Commit 85342a76 by Karl Schimpf

Fix emission of move immediate for ARM integrated assembler.

parent 28b71be4
...@@ -71,7 +71,8 @@ void Assembler::Emit(int32_t value) { ...@@ -71,7 +71,8 @@ void Assembler::Emit(int32_t value) {
buffer_.Emit<int32_t>(value); buffer_.Emit<int32_t>(value);
} }
#if 0
// Moved to class AssemblerARM32.
void Assembler::EmitType01(Condition cond, void Assembler::EmitType01(Condition cond,
int type, int type,
Opcode opcode, Opcode opcode,
...@@ -90,7 +91,7 @@ void Assembler::EmitType01(Condition cond, ...@@ -90,7 +91,7 @@ void Assembler::EmitType01(Condition cond,
o.encoding(); o.encoding();
Emit(encoding); Emit(encoding);
} }
#endif
void Assembler::EmitType5(Condition cond, int32_t offset, bool link) { void Assembler::EmitType5(Condition cond, int32_t offset, bool link) {
ASSERT(cond != kNoCondition); ASSERT(cond != kNoCondition);
...@@ -277,10 +278,13 @@ void Assembler::orrs(Register rd, Register rn, Operand o, Condition cond) { ...@@ -277,10 +278,13 @@ void Assembler::orrs(Register rd, Register rn, Operand o, Condition cond) {
} }
#if 0
// Moved to AssemblerARM32::mov(..FlexImm..)
// TODO(kschimpf) other forms of move.
void Assembler::mov(Register rd, Operand o, Condition cond) { void Assembler::mov(Register rd, Operand o, Condition cond) {
EmitType01(cond, o.type(), MOV, 0, R0, rd, o); EmitType01(cond, o.type(), MOV, 0, R0, rd, o);
} }
#endif
void Assembler::movs(Register rd, Operand o, Condition cond) { void Assembler::movs(Register rd, Operand o, Condition cond) {
EmitType01(cond, o.type(), MOV, 1, R0, rd, o); EmitType01(cond, o.type(), MOV, 1, R0, rd, o);
......
...@@ -28,7 +28,7 @@ class RuntimeEntry; ...@@ -28,7 +28,7 @@ class RuntimeEntry;
class StubEntry; class StubEntry;
#if 0 #if 0
// Moved to: ARM32::AssemblerARM32. // Moved to: ARM32::AssemblerARM32 as needed
// Instruction encoding bits. // Instruction encoding bits.
enum { enum {
H = 1 << 5, // halfword (or byte) H = 1 << 5, // halfword (or byte)
...@@ -139,12 +139,15 @@ class Operand : public ValueObject { ...@@ -139,12 +139,15 @@ class Operand : public ValueObject {
encoding_ = immediate; encoding_ = immediate;
} }
#if 0
// Moved to AssemblerARM32::encodeImm12FromFlexImm.
// Data-processing operands - Rotated immediate. // Data-processing operands - Rotated immediate.
Operand(uint32_t rotate, uint32_t immed8) { Operand(uint32_t rotate, uint32_t immed8) {
ASSERT((rotate < (1 << kRotateBits)) && (immed8 < (1 << kImmed8Bits))); ASSERT((rotate < (1 << kRotateBits)) && (immed8 < (1 << kImmed8Bits)));
type_ = 1; type_ = 1;
encoding_ = (rotate << kRotateShift) | (immed8 << kImmed8Shift); encoding_ = (rotate << kRotateShift) | (immed8 << kImmed8Shift);
} }
#endif
// Data-processing operands - Register. // Data-processing operands - Register.
explicit Operand(Register rm) { explicit Operand(Register rm) {
...@@ -465,7 +468,11 @@ class Assembler : public ValueObject { ...@@ -465,7 +468,11 @@ class Assembler : public ValueObject {
void orr(Register rd, Register rn, Operand o, Condition cond = AL); void orr(Register rd, Register rn, Operand o, Condition cond = AL);
void orrs(Register rd, Register rn, Operand o, Condition cond = AL); void orrs(Register rd, Register rn, Operand o, Condition cond = AL);
#if 0
// Moved to IceAssemblerARM32::mov(..FlexImm..)
// TODO(kschimpf) other forms of move.
void mov(Register rd, Operand o, Condition cond = AL); void mov(Register rd, Operand o, Condition cond = AL);
#endif
void movs(Register rd, Operand o, Condition cond = AL); void movs(Register rd, Operand o, Condition cond = AL);
void bic(Register rd, Register rn, Operand o, Condition cond = AL); void bic(Register rd, Register rn, Operand o, Condition cond = AL);
...@@ -1084,6 +1091,8 @@ class Assembler : public ValueObject { ...@@ -1084,6 +1091,8 @@ class Assembler : public ValueObject {
bool is_unique, bool is_unique,
Register pp); Register pp);
#if 0
// Moved to class AssemblerARM32.
void EmitType01(Condition cond, void EmitType01(Condition cond,
int type, int type,
Opcode opcode, Opcode opcode,
...@@ -1091,6 +1100,7 @@ class Assembler : public ValueObject { ...@@ -1091,6 +1100,7 @@ class Assembler : public ValueObject {
Register rn, Register rn,
Register rd, Register rd,
Operand o); Operand o);
#endif
void EmitType5(Condition cond, int32_t offset, bool link); void EmitType5(Condition cond, int32_t offset, bool link);
......
...@@ -24,6 +24,65 @@ ...@@ -24,6 +24,65 @@
namespace Ice { namespace Ice {
// The following define individual bits.
static constexpr uint32_t B0 = 1;
static constexpr uint32_t B2 = 1 << 2;
static constexpr uint32_t B3 = 1 << 3;
static constexpr uint32_t B4 = 1 << 4;
static constexpr uint32_t B5 = 1 << 5;
static constexpr uint32_t B6 = 1 << 6;
static constexpr uint32_t B21 = 1 << 21;
static constexpr uint32_t B24 = 1 << 24;
// Constants used for the decoding or encoding of the individual fields of
// instructions. Based on ARM section A5.1.
static constexpr uint32_t kConditionShift = 28;
static constexpr uint32_t kOpcodeShift = 21;
static constexpr uint32_t kRdShift = 12;
static constexpr uint32_t kRmShift = 0;
static constexpr uint32_t kRnShift = 16;
static constexpr uint32_t kSShift = 20;
static constexpr uint32_t kTypeShift = 25;
// Immediate instruction fields encoding.
static constexpr uint32_t kImmed8Bits = 8;
static constexpr uint32_t kImmed8Shift = 0;
static constexpr uint32_t kRotateBits = 4;
static constexpr uint32_t kRotateShift = 8;
// Types of instructions.
static constexpr uint32_t kInstTypeImmediate = 1;
inline uint32_t encodeBool(bool b) { return b ? 1 : 0; }
inline uint32_t encodeGPRRegister(RegARM32::GPRRegister Rn) {
return static_cast<uint32_t>(Rn);
}
inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) {
return R != RegARM32::Encoded_Not_GPR;
}
inline bool isGPRRegisterDefined(uint32_t R) {
return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR);
}
inline bool isConditionDefined(CondARM32::Cond Cond) {
return Cond != CondARM32::kNone;
}
inline uint32_t encodeCondition(CondARM32::Cond Cond) {
return static_cast<uint32_t>(Cond);
}
// Converts rotated immediate into imm12.
inline uint32_t encodeImm12FromFlexImm(const OperandARM32FlexImm &FlexImm) {
uint32_t Immed8 = FlexImm.getImm();
uint32_t Rotate = FlexImm.getRotateAmt();
assert((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits)));
return (Rotate << kRotateShift) | (Immed8 << kImmed8Shift);
}
Label *ARM32::AssemblerARM32::getOrCreateLabel(SizeT Number, Label *ARM32::AssemblerARM32::getOrCreateLabel(SizeT Number,
LabelVector &Labels) { LabelVector &Labels) {
Label *L = nullptr; Label *L = nullptr;
...@@ -56,20 +115,47 @@ void ARM32::AssemblerARM32::bind(Label *label) { ...@@ -56,20 +115,47 @@ void ARM32::AssemblerARM32::bind(Label *label) {
label->bindTo(bound); label->bindTo(bound);
} }
void ARM32::AssemblerARM32::emitType01(CondARM32::Cond Cond, uint32_t Type,
uint32_t Opcode, bool SetCc, uint32_t Rn,
uint32_t Rd, uint32_t Imm12) {
assert(isGPRRegisterDefined(Rd));
assert(Cond != CondARM32::kNone);
uint32_t Encoding = encodeCondition(Cond) << kConditionShift |
(Type << kTypeShift) | (Opcode << kOpcodeShift) |
(encodeBool(SetCc) << kSShift) | (Rn << kRnShift) |
(Rd << kRdShift) | Imm12;
emitInst(Encoding);
}
void ARM32::AssemblerARM32::bkpt(uint16_t imm16) { void ARM32::AssemblerARM32::bkpt(uint16_t imm16) {
AssemblerBuffer::EnsureCapacity ensured(&Buffer); AssemblerBuffer::EnsureCapacity ensured(&Buffer);
emitInt32(BkptEncoding(imm16)); uint32_t Encoding = (CondARM32::AL << kConditionShift) | B24 | B21 |
((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf);
emitInst(Encoding);
} }
void ARM32::AssemblerARM32::bx(RegARM32::GPRRegister rm, CondARM32::Cond cond) { void ARM32::AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) {
// cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond. // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond.
assert(rm != RegARM32::Encoded_Not_GPR); // (ARM section A8.8.27, encoding A1).
assert(cond != CondARM32::kNone); assert(isGPRRegisterDefined(Rm));
assert(isConditionDefined(Cond));
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | B21 |
(0xfff << 8) | B4 | (encodeGPRRegister(Rm) << kRmShift);
emitInst(Encoding);
}
void ARM32::AssemblerARM32::mov(RegARM32::GPRRegister Rd,
const OperandARM32FlexImm &FlexImm,
CondARM32::Cond Cond) {
// cccc0011101s0000ddddiiiiiiiiiiii (ARM section A8.8.102, encoding A1)
assert(isConditionDefined(Cond));
AssemblerBuffer::EnsureCapacity ensured(&Buffer); AssemblerBuffer::EnsureCapacity ensured(&Buffer);
int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B24 | bool SetCc = false; // Note: We don't use movs in this assembler.
B21 | (0xfff << 8) | B4 | uint32_t Rn = 0;
(static_cast<int32_t>(rm) << kRmShift); uint32_t Mov = B3 | B2 | B0; // 1101.
emitInt32(encoding); emitType01(Cond, kInstTypeImmediate, Mov, SetCc, Rn, encodeGPRRegister(Rd),
encodeImm12FromFlexImm(FlexImm));
} }
} // end of namespace Ice } // end of namespace Ice
...@@ -18,6 +18,10 @@ ...@@ -18,6 +18,10 @@
/// \file /// \file
/// This file implements the Assembler class for ARM32. /// This file implements the Assembler class for ARM32.
/// ///
/// Note: All references to ARM "section" documentation refers to the "ARM
/// Architecture Reference Manual, ARMv7-A and ARMv7-R edition". See:
/// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406c
///
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef SUBZERO_SRC_ICEASSEMBLERARM32_H #ifndef SUBZERO_SRC_ICEASSEMBLERARM32_H
...@@ -27,6 +31,7 @@ ...@@ -27,6 +31,7 @@
#include "IceConditionCodesARM32.h" #include "IceConditionCodesARM32.h"
#include "IceDefs.h" #include "IceDefs.h"
#include "IceFixups.h" #include "IceFixups.h"
#include "IceInstARM32.h"
#include "IceRegistersARM32.h" #include "IceRegistersARM32.h"
#include "IceTargetLowering.h" #include "IceTargetLowering.h"
...@@ -74,8 +79,8 @@ public: ...@@ -74,8 +79,8 @@ public:
} }
Ice::Label *getCfgNodeLabel(SizeT NodeNumber) override { Ice::Label *getCfgNodeLabel(SizeT NodeNumber) override {
(void)NodeNumber; assert(NodeNumber < CfgNodeLabels.size());
llvm_unreachable("Not yet implemented."); return CfgNodeLabels[NodeNumber];
} }
void bindCfgNodeLabel(SizeT NodeNumber) override { void bindCfgNodeLabel(SizeT NodeNumber) override {
...@@ -90,145 +95,18 @@ public: ...@@ -90,145 +95,18 @@ public:
} }
void bind(Label *label); void bind(Label *label);
void bkpt(uint16_t imm16); void bkpt(uint16_t Imm16);
void mov(RegARM32::GPRRegister Rd, const OperandARM32FlexImm &FlexImm,
CondARM32::Cond Cond);
void bx(RegARM32::GPRRegister rm, CondARM32::Cond cond = CondARM32::AL); void bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond = CondARM32::AL);
static bool classof(const Assembler *Asm) { static bool classof(const Assembler *Asm) {
return Asm->getKind() == Asm_ARM32; return Asm->getKind() == Asm_ARM32;
} }
private: private:
// Instruction encoding bits.
// halfword (or byte)
static constexpr uint32_t H = 1 << 5;
// load (or store)
static constexpr uint32_t L = 1 << 20;
// set condition code (or leave unchanged)
static constexpr uint32_t S = 1 << 20;
// writeback base register (or leave unchanged)
static constexpr uint32_t W = 1 << 21;
// accumulate in multiply instruction (or not)
static constexpr uint32_t A = 1 << 21;
// unsigned byte (or word)
static constexpr uint32_t B = 1 << 22;
// high/lo bit of start of s/d register range
static constexpr uint32_t D = 1 << 22;
// long (or short)
static constexpr uint32_t N = 1 << 22;
// positive (or negative) offset/index
static constexpr uint32_t U = 1 << 23;
// offset/pre-indexed addressing (or post-indexed addressing)
static constexpr uint32_t P = 1 << 24;
// immediate shifter operand (or not)
static constexpr uint32_t I = 1 << 25;
// The following define individual bits.
static constexpr uint32_t B0 = 1;
static constexpr uint32_t B1 = 1 << 1;
static constexpr uint32_t B2 = 1 << 2;
static constexpr uint32_t B3 = 1 << 3;
static constexpr uint32_t B4 = 1 << 4;
static constexpr uint32_t B5 = 1 << 5;
static constexpr uint32_t B6 = 1 << 6;
static constexpr uint32_t B7 = 1 << 7;
static constexpr uint32_t B8 = 1 << 8;
static constexpr uint32_t B9 = 1 << 9;
static constexpr uint32_t B10 = 1 << 10;
static constexpr uint32_t B11 = 1 << 11;
static constexpr uint32_t B12 = 1 << 12;
static constexpr uint32_t B16 = 1 << 16;
static constexpr uint32_t B17 = 1 << 17;
static constexpr uint32_t B18 = 1 << 18;
static constexpr uint32_t B19 = 1 << 19;
static constexpr uint32_t B20 = 1 << 20;
static constexpr uint32_t B21 = 1 << 21;
static constexpr uint32_t B22 = 1 << 22;
static constexpr uint32_t B23 = 1 << 23;
static constexpr uint32_t B24 = 1 << 24;
static constexpr uint32_t B25 = 1 << 25;
static constexpr uint32_t B26 = 1 << 26;
static constexpr uint32_t B27 = 1 << 27;
// Constants used for the decoding or encoding of the individual fields of
// instructions. Based on section A5.1 from the "ARM Architecture Reference
// Manual, ARMv7-A and ARMv7-R edition". See:
// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406c
static constexpr uint32_t kConditionShift = 28;
static constexpr uint32_t kConditionBits = 4;
static constexpr uint32_t kTypeShift = 25;
static constexpr uint32_t kTypeBits = 3;
static constexpr uint32_t kLinkShift = 24;
static constexpr uint32_t kLinkBits = 1;
static constexpr uint32_t kUShift = 23;
static constexpr uint32_t kUBits = 1;
static constexpr uint32_t kOpcodeShift = 21;
static constexpr uint32_t kOpcodeBits = 4;
static constexpr uint32_t kSShift = 20;
static constexpr uint32_t kSBits = 1;
static constexpr uint32_t kRnShift = 16;
static constexpr uint32_t kRnBits = 4;
static constexpr uint32_t kRdShift = 12;
static constexpr uint32_t kRdBits = 4;
static constexpr uint32_t kRsShift = 8;
static constexpr uint32_t kRsBits = 4;
static constexpr uint32_t kRmShift = 0;
static constexpr uint32_t kRmBits = 4;
// Immediate instruction fields encoding.
static constexpr uint32_t kRotateShift = 8;
static constexpr uint32_t kRotateBits = 4;
static constexpr uint32_t kImmed8Shift = 0;
static constexpr uint32_t kImmed8Bits = 8;
// Shift instruction register fields encodings.
static constexpr uint32_t kShiftImmShift = 7;
static constexpr uint32_t kShiftRegisterShift = 8;
static constexpr uint32_t kShiftImmBits = 5;
static constexpr uint32_t kShiftShift = 5;
static constexpr uint32_t kShiftBits = 2;
// Load/store instruction offset field encoding.
static constexpr uint32_t kOffset12Shift = 0;
static constexpr uint32_t kOffset12Bits = 12;
static constexpr uint32_t kOffset12Mask = 0x00000fff;
// Mul instruction register field encodings.
static constexpr uint32_t kMulRdShift = 16;
static constexpr uint32_t kMulRdBits = 4;
static constexpr uint32_t kMulRnShift = 12;
static constexpr uint32_t kMulRnBits = 4;
// Div instruction register field encodings.
static constexpr uint32_t kDivRdShift = 16;
static constexpr uint32_t kDivRdBits = 4;
static constexpr uint32_t kDivRmShift = 8;
static constexpr uint32_t kDivRmBints = 4;
static constexpr uint32_t kDivRnShift = 0;
static constexpr uint32_t kDivRnBits = 4;
// ldrex/strex register field encodings.
static constexpr uint32_t kLdExRnShift = 16;
static constexpr uint32_t kLdExRtShift = 12;
static constexpr uint32_t kStrExRnShift = 16;
static constexpr uint32_t kStrExRdShift = 12;
static constexpr uint32_t kStrExRtShift = 0;
// MRC instruction offset field encoding.
static constexpr uint32_t kCRmShift = 0;
static constexpr uint32_t kCRmBits = 4;
static constexpr uint32_t kOpc2Shift = 5;
static constexpr uint32_t kOpc2Bits = 3;
static constexpr uint32_t kCoprocShift = 8;
static constexpr uint32_t kCoprocBits = 4;
static constexpr uint32_t kCRnShift = 16;
static constexpr uint32_t kCRnBits = 4;
static constexpr uint32_t kOpc1Shift = 21;
static constexpr uint32_t kOpc1Bits = 3;
static constexpr uint32_t kBranchOffsetMask = 0x00ffffff;
// A vector of pool-allocated x86 labels for CFG nodes. // A vector of pool-allocated x86 labels for CFG nodes.
using LabelVector = std::vector<Label *>; using LabelVector = std::vector<Label *>;
LabelVector CfgNodeLabels; LabelVector CfgNodeLabels;
...@@ -238,14 +116,12 @@ private: ...@@ -238,14 +116,12 @@ private:
return getOrCreateLabel(NodeNumber, CfgNodeLabels); return getOrCreateLabel(NodeNumber, CfgNodeLabels);
} }
void emitInt32(int32_t Value) { Buffer.emit<int32_t>(Value); } void emitInst(uint32_t Value) { Buffer.emit<uint32_t>(Value); }
static int32_t BkptEncoding(uint16_t imm16) { // Pattern cccctttoooosnnnnddddiiiiiiiiiiii where cccc=Cond, ttt=Type,
// bkpt requires that the cond field is AL. // oooo=Opcode, nnnn=Rn, dddd=Rd, iiiiiiiiiiii=imm12 (See ARM section A5.2.3).
// cccc00010010iiiiiiiiiiii0111iiii where cccc=AL and i in imm16 void emitType01(CondARM32::Cond Cond, uint32_t Type, uint32_t Opcode,
return (CondARM32::AL << kConditionShift) | B24 | B21 | bool SetCc, uint32_t Rn, uint32_t Rd, uint32_t imm12);
((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf);
}
}; };
} // end of namespace ARM32 } // end of namespace ARM32
......
...@@ -592,6 +592,29 @@ void InstARM32Mov::emitSingleDestSingleSource(const Cfg *Func) const { ...@@ -592,6 +592,29 @@ void InstARM32Mov::emitSingleDestSingleSource(const Cfg *Func) const {
} }
} }
void InstARM32Mov::emitIASSingleDestSingleSource(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Variable *Dest = getDest();
Operand *Src0 = getSrc(0);
// Note: Loop is used so that we can short circuit using break.
do {
if (Dest->hasReg()) {
Type DestTy = Dest->getType();
const bool DestIsVector = isVectorType(DestTy);
const bool DestIsScalarFP = isScalarFloatingType(DestTy);
const bool CoreVFPMove = isMoveBetweenCoreAndVFPRegisters(Dest, Src0);
if (DestIsVector || DestIsScalarFP || CoreVFPMove)
break;
if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Src0)) {
Asm->mov(static_cast<RegARM32::GPRRegister>(Dest->getRegNum()),
*FlexImm, getPredicate());
return;
}
}
} while (0);
llvm_unreachable("not yet implemented");
}
void InstARM32Mov::emit(const Cfg *Func) const { void InstARM32Mov::emit(const Cfg *Func) const {
if (!BuildDefs::dump()) if (!BuildDefs::dump())
return; return;
...@@ -612,7 +635,13 @@ void InstARM32Mov::emit(const Cfg *Func) const { ...@@ -612,7 +635,13 @@ void InstARM32Mov::emit(const Cfg *Func) const {
void InstARM32Mov::emitIAS(const Cfg *Func) const { void InstARM32Mov::emitIAS(const Cfg *Func) const {
assert(getSrcSize() == 1); assert(getSrcSize() == 1);
(void)Func; (void)Func;
llvm_unreachable("Not yet implemented"); assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type.");
if (isMultiDest())
llvm_unreachable("Not yet implemented");
if (isMultiSource())
llvm_unreachable("Not yet implemented");
// Must be single source/dest.
emitIASSingleDestSingleSource(Func);
} }
void InstARM32Mov::dump(const Cfg *Func) const { void InstARM32Mov::dump(const Cfg *Func) const {
......
...@@ -1175,6 +1175,8 @@ private: ...@@ -1175,6 +1175,8 @@ private:
void emitSingleDestMultiSource(const Cfg *Func) const; void emitSingleDestMultiSource(const Cfg *Func) const;
void emitSingleDestSingleSource(const Cfg *Func) const; void emitSingleDestSingleSource(const Cfg *Func) const;
void emitIASSingleDestSingleSource(const Cfg *Func) const;
Variable *DestHi = nullptr; Variable *DestHi = nullptr;
}; };
......
; Show that we know how to translate move (immediate) ARM instruction.
; RUN: %p2i --filetype=asm -i %s --target=arm32 \
; RUN: | FileCheck %s --check-prefix=ASM
; RUN: %p2i --filetype=iasm -i %s --target=arm32 \
; RUN: | FileCheck %s --check-prefix=IASM
define internal i32 @Imm1() {
ret i32 1
}
; ASM-LABEL: Imm1:
; ASM: mov r0, #1
; IASM-LABEL: Imm1:
; IASM: .byte 0x1
; IASM: .byte 0x0
; IASM: .byte 0xa0
; IASM: .byte 0xe3
define internal i32 @rotateFImmAA() {
; immediate = 0x000002a8 = b 0000 0000 0000 0000 0000 0010 1010 1000
ret i32 680
}
; ASM-LABEL: rotateFImmAA:
; ASM: mov r0, #680
; IASM-LABEL: rotateFImmAA:
; IASM: .byte 0xaa
; IASM: .byte 0xf
; IASM: .byte 0xa0
; IASM: .byte 0xe3
define internal i32 @rotateEImmAA() {
; immediate = 0x00000aa0 = b 0000 0000 0000 0000 0000 1010 1010 0000
ret i32 2720
}
; ASM-LABEL: rotateEImmAA:
; ASM: mov r0, #2720
; IASM-LABEL: rotateEImmAA:
; IASM: .byte 0xaa
; IASM: .byte 0xe
; IASM: .byte 0xa0
; IASM: .byte 0xe3
define internal i32 @rotateDImmAA() {
; immediate = 0x00002a80 = b 0000 0000 0000 0000 0010 1010 1000 0000
ret i32 10880
}
; ASM-LABEL: rotateDImmAA:
; ASM: mov r0, #10880
; IASM-LABEL: rotateDImmAA:
; IASM: .byte 0xaa
; IASM: .byte 0xd
; IASM: .byte 0xa0
; IASM: .byte 0xe3
define internal i32 @rotateCImmAA() {
; immediate = 0x0000aa00 = b 0000 0000 0000 0000 1010 1010 0000 0000
ret i32 43520
}
; ASM-LABEL: rotateCImmAA:
; ASM: mov r0, #43520
; IASM-LABEL: rotateCImmAA:
; IASM: .byte 0xaa
; IASM: .byte 0xc
; IASM: .byte 0xa0
; IASM: .byte 0xe3
define internal i32 @rotateBImmAA() {
; immediate = 0x0002a800 = b 0000 0000 0000 0010 1010 1000 0000 0000
ret i32 174080
}
; ASM-LABEL: rotateBImmAA:
; ASM: mov r0, #174080
; IASM-LABEL: rotateBImmAA:
; IASM: .byte 0xaa
; IASM: .byte 0xb
; IASM: .byte 0xa0
; IASM: .byte 0xe3
define internal i32 @rotateAImmAA() {
; immediate = 0x000aa000 = b 0000 0000 0000 1010 1010 0000 0000 0000
ret i32 696320
}
; ASM-LABEL: rotateAImmAA:
; ASM: mov r0, #696320
; IASM-LABEL: rotateAImmAA:
; IASM: .byte 0xaa
; IASM: .byte 0xa
; IASM: .byte 0xa0
; IASM: .byte 0xe3
define internal i32 @rotate9ImmAA() {
; immediate = 0x002a8000 = b 0000 0000 0010 1010 1000 0000 0000 0000
ret i32 2785280
}
; ASM-LABEL: rotate9ImmAA:
; ASM: mov r0, #2785280
; IASM-LABEL: rotate9ImmAA:
; IASM: .byte 0xaa
; IASM: .byte 0x9
; IASM: .byte 0xa0
; IASM: .byte 0xe3
define internal i32 @rotate8ImmAA() {
; immediate = 0x00aa0000 = b 0000 0000 1010 1010 0000 0000 0000 0000
ret i32 11141120
}
; ASM-LABEL: rotate8ImmAA:
; ASM: mov r0, #11141120
; IASM-LABEL: rotate8ImmAA:
; IASM: .byte 0xaa
; IASM: .byte 0x8
; IASM: .byte 0xa0
; IASM: .byte 0xe3
define internal i32 @rotate7ImmAA() {
; immediate = 0x02a80000 = b 0000 0010 1010 1000 0000 0000 0000 0000
ret i32 44564480
}
; ASM-LABEL: rotate7ImmAA:
; ASM: mov r0, #44564480
; IASM-LABEL: rotate7ImmAA:
; IASM: .byte 0xaa
; IASM: .byte 0x7
; IASM: .byte 0xa0
; IASM: .byte 0xe3
define internal i32 @rotate6ImmAA() {
; immediate = 0x0aa00000 = b 0000 1010 1010 0000 0000 0000 0000 0000
ret i32 178257920
}
; ASM-LABEL: rotate6ImmAA:
; ASM: mov r0, #178257920
; IASM-LABEL: rotate6ImmAA:
; IASM: .byte 0xaa
; IASM: .byte 0x6
; IASM: .byte 0xa0
; IASM: .byte 0xe3
define internal i32 @rotate5ImmAA() {
; immediate = 0x2a800000 = b 0010 1010 1000 0000 0000 0000 0000 0000
ret i32 713031680
}
; ASM-LABEL: rotate5ImmAA:
; ASM: mov r0, #713031680
; IASM-LABEL: rotate5ImmAA:
; IASM: .byte 0xaa
; IASM: .byte 0x5
; IASM: .byte 0xa0
; IASM: .byte 0xe3
define internal i32 @rotate4ImmAA() {
; immediate = 0xaa000000 = b 1010 1010 0000 0000 0000 0000 0000 0000
ret i32 2852126720
}
; ASM-LABEL: rotate4ImmAA:
; ASM: mov r0, #2852126720
; IASM-LABEL: rotate4ImmAA:
; IASM: .byte 0xaa
; IASM: .byte 0x4
; IASM: .byte 0xa0
; IASM: .byte 0xe3
define internal i32 @rotate3ImmAA() {
; immediate = 0xa8000002 = b 1010 1000 0000 0000 0000 0000 0000 0010
ret i32 2818572290
}
; ASM-LABEL: rotate3ImmAA:
; ASM: mov r0, #2818572290
; IASM-LABEL: rotate3ImmAA:
; IASM: .byte 0xaa
; IASM: .byte 0x3
; IASM: .byte 0xa0
; IASM: .byte 0xe3
define internal i32 @rotate2ImmAA() {
; immediate = 0xa000000a = b 1010 0000 0000 0000 0000 0000 0000 1010
ret i32 2684354570
}
; ASM-LABEL: rotate2ImmAA:
; ASM: mov r0, #2684354570
; IASM-LABEL: rotate2ImmAA:
; IASM: .byte 0xaa
; IASM: .byte 0x2
; IASM: .byte 0xa0
; IASM: .byte 0xe3
define internal i32 @rotate1ImmAA() {
; immediate = 0x8000002a = b 1000 1000 0000 0000 0000 0000 0010 1010
ret i32 2147483690
}
; ASM-LABEL: rotate1ImmAA:
; ASM: mov r0, #2147483690
; IASM-LABEL: rotate1ImmAA:
; IASM: .byte 0xaa
; IASM: .byte 0x1
; IASM: .byte 0xa0
; IASM: .byte 0xe3
define internal i32 @rotate0ImmAA() {
; immediate = 0x000000aa = b 0000 0000 0000 0000 0000 0000 1010 1010
ret i32 170
}
; ASM-LABEL: rotate0ImmAA:
; ASM: mov r0, #170
; IASM-LABEL: rotate0ImmAA:
; IASM: .byte 0xaa
; IASM: .byte 0x0
; IASM: .byte 0xa0
; IASM: .byte 0xe3
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment