| Index: src/IceAssemblerARM32.cpp
|
| diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp
|
| index ab22450f04ba482c6e3ffa71b8c4a647c93dbb43..16f1e4a1223a7ecf88244942989bb7c3772e46ea 100644
|
| --- a/src/IceAssemblerARM32.cpp
|
| +++ b/src/IceAssemblerARM32.cpp
|
| @@ -24,6 +24,65 @@
|
|
|
| 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,
|
| LabelVector &Labels) {
|
| Label *L = nullptr;
|
| @@ -56,20 +115,47 @@ void ARM32::AssemblerARM32::bind(Label *label) {
|
| 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) {
|
| 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.
|
| - assert(rm != RegARM32::Encoded_Not_GPR);
|
| - assert(cond != CondARM32::kNone);
|
| + // (ARM section A8.8.27, encoding A1).
|
| + 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);
|
| - int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B24 |
|
| - B21 | (0xfff << 8) | B4 |
|
| - (static_cast<int32_t>(rm) << kRmShift);
|
| - emitInt32(encoding);
|
| + bool SetCc = false; // Note: We don't use movs in this assembler.
|
| + uint32_t Rn = 0;
|
| + uint32_t Mov = B3 | B2 | B0; // 1101.
|
| + emitType01(Cond, kInstTypeImmediate, Mov, SetCc, Rn, encodeGPRRegister(Rd),
|
| + encodeImm12FromFlexImm(FlexImm));
|
| }
|
|
|
| } // end of namespace Ice
|
|
|