Chromium Code Reviews| Index: src/IceAssemblerARM32.cpp |
| diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp |
| index 598146cad583fc35862d02a422d3b52661307295..7f7140e3a493151f3ca95b47f1e28f15224dd77b 100644 |
| --- a/src/IceAssemblerARM32.cpp |
| +++ b/src/IceAssemblerARM32.cpp |
| @@ -27,66 +27,77 @@ |
| namespace { |
| using namespace Ice; |
| +using namespace Ice::ARM32; |
| // 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 B21 = 1 << 21; |
| -static constexpr uint32_t B24 = 1 << 24; |
| +static constexpr InstValueType B0 = 1; |
| +static constexpr InstValueType B1 = 1 << 1; |
| +static constexpr InstValueType B2 = 1 << 2; |
| +static constexpr InstValueType B3 = 1 << 3; |
| +static constexpr InstValueType B4 = 1 << 4; |
| +static constexpr InstValueType B5 = 1 << 5; |
| +static constexpr InstValueType B6 = 1 << 6; |
| +static constexpr InstValueType B21 = 1 << 21; |
| +static constexpr InstValueType 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 L = 1 << 20; // load (or store) |
| -static constexpr uint32_t W = 1 << 21; // writeback base register (or leave |
| - // unchanged) |
| -static constexpr uint32_t B = 1 << 22; // unsigned byte (or word) |
| -static constexpr uint32_t U = 1 << 23; // positive (or negative) offset/index |
| -static constexpr uint32_t P = 1 << 24; // offset/pre-indexed addressing (or |
| - // post-indexed addressing) |
| - |
| -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; |
| +static constexpr InstValueType L = 1 << 20; // load (or store) |
| +static constexpr InstValueType W = 1 << 21; // writeback base register |
| + // (or leave unchanged) |
| +static constexpr InstValueType B = 1 << 22; // unsigned byte (or word) |
| +static constexpr InstValueType U = 1 << 23; // positive (or negative) |
| + // offset/index |
| +static constexpr InstValueType P = 1 << 24; // offset/pre-indexed |
| + // addressing (or |
| + // post-indexed addressing) |
| + |
| +static constexpr InstValueType kConditionShift = 28; |
| +static constexpr InstValueType kLinkShift = 24; |
| +static constexpr InstValueType kOpcodeShift = 21; |
| +static constexpr InstValueType kRdShift = 12; |
| +static constexpr InstValueType kRmShift = 0; |
| +static constexpr InstValueType kRnShift = 16; |
| +static constexpr InstValueType kSShift = 20; |
| +static constexpr InstValueType 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; |
| +static constexpr InstValueType kImmed8Bits = 8; |
| +static constexpr InstValueType kImmed8Shift = 0; |
| +static constexpr InstValueType kRotateBits = 4; |
| +static constexpr InstValueType kRotateShift = 8; |
| // Shift instruction register fields encodings. |
| -static constexpr uint32_t kShiftImmShift = 7; |
| -static constexpr uint32_t kShiftImmBits = 5; |
| -static constexpr uint32_t kShiftShift = 5; |
| +static constexpr InstValueType kShiftImmShift = 7; |
| +static constexpr InstValueType kShiftImmBits = 5; |
| +static constexpr InstValueType kShiftShift = 5; |
| -static constexpr uint32_t kImmed12Bits = 12; |
| -static constexpr uint32_t kImm12Shift = 0; |
| +static constexpr InstValueType kImmed12Bits = 12; |
| +static constexpr InstValueType kImm12Shift = 0; |
| // Type of instruction encoding (bits 25-27). See ARM section A5.1 |
| -static constexpr uint32_t kInstTypeDataRegister = 0; // i.e. 000 |
| -static constexpr uint32_t kInstTypeDataImmediate = 1; // i.e. 001 |
| -static constexpr uint32_t kInstTypeMemImmediate = 2; // i.e. 010 |
| +static constexpr InstValueType kInstTypeDataRegister = 0; // i.e. 000 |
| +static constexpr InstValueType kInstTypeDataImmediate = 1; // i.e. 001 |
| +static constexpr InstValueType kInstTypeMemImmediate = 2; // i.e. 010 |
| -inline uint32_t encodeBool(bool b) { return b ? 1 : 0; } |
| +// Offset modifier to current PC for next instruction. The offset is off by 8 |
| +// due to the way the ARM CPUs read PC. |
| +static constexpr InstOffsetType kPCReadOffset = 8; |
| -inline uint32_t encodeGPRRegister(RegARM32::GPRRegister Rn) { |
| - return static_cast<uint32_t>(Rn); |
| +// Mask to pull out PC offset from branch (b) instruction. |
| +static constexpr InstOffsetType kBranchOffsetMask = 0x00ffffff; |
| + |
| +inline InstValueType encodeBool(bool b) { return b ? 1 : 0; } |
| + |
| +inline InstValueType encodeGPRRegister(RegARM32::GPRRegister Rn) { |
| + return static_cast<InstValueType>(Rn); |
| } |
| inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) { |
| return R != RegARM32::Encoded_Not_GPR; |
| } |
| -inline bool isGPRRegisterDefined(uint32_t R) { |
| +inline bool isGPRRegisterDefined(InstValueType R) { |
| return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR); |
| } |
| @@ -94,11 +105,11 @@ inline bool isConditionDefined(CondARM32::Cond Cond) { |
| return Cond != CondARM32::kNone; |
| } |
| -inline uint32_t encodeCondition(CondARM32::Cond Cond) { |
| - return static_cast<uint32_t>(Cond); |
| +inline InstValueType encodeCondition(CondARM32::Cond Cond) { |
| + return static_cast<InstValueType>(Cond); |
| } |
| -uint32_t encodeShift(OperandARM32::ShiftKind Shift) { |
| +InstValueType encodeShift(OperandARM32::ShiftKind Shift) { |
| // Follows encoding in ARM section A8.4.1 "Constant shifts". |
| switch (Shift) { |
| case OperandARM32::kNoShift: |
| @@ -115,17 +126,19 @@ uint32_t encodeShift(OperandARM32::ShiftKind Shift) { |
| } |
| // Returns the bits in the corresponding masked value. |
| -inline uint32_t mask(uint32_t Value, uint32_t Shift, uint32_t Bits) { |
| +inline InstValueType mask(InstValueType Value, InstValueType Shift, |
| + InstValueType Bits) { |
| return (Value >> Shift) & ((1 << Bits) - 1); |
| } |
| // Extract out a Bit in Value. |
| -inline bool isBitSet(uint32_t Bit, uint32_t Value) { |
| +inline bool isBitSet(InstValueType Bit, InstValueType Value) { |
| return (Value & Bit) == Bit; |
| } |
| // Returns the GPR register at given Shift in Value. |
| -inline RegARM32::GPRRegister getGPRReg(uint32_t Shift, uint32_t Value) { |
| +inline RegARM32::GPRRegister getGPRReg(InstValueType Shift, |
| + InstValueType Value) { |
| return static_cast<RegARM32::GPRRegister>((Value >> Shift) & 0xF); |
| } |
| @@ -147,35 +160,35 @@ enum DecodedResult { |
| // Encodes iiiiitt0mmmm for data-processing (2nd) operands where iiiii=Imm5, |
| // tt=Shift, and mmmm=Rm. |
| -uint32_t encodeShiftRotateImm5(uint32_t Rm, OperandARM32::ShiftKind Shift, |
| - uint32_t imm5) { |
| +InstValueType encodeShiftRotateImm5(InstValueType Rm, |
| + OperandARM32::ShiftKind Shift, |
| + InstValueType imm5) { |
| (void)kShiftImmBits; |
| assert(imm5 < (1 << kShiftImmBits)); |
| return (imm5 << kShiftImmShift) | (encodeShift(Shift) << kShiftShift) | Rm; |
| } |
| -DecodedResult decodeOperand(const Operand *Opnd, uint32_t &Value) { |
| +DecodedResult decodeOperand(const Operand *Opnd, InstValueType &Value) { |
| if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { |
| if (Var->hasReg()) { |
| Value = Var->getRegNum(); |
| return DecodedAsRegister; |
| } |
| } else if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) { |
| - const uint32_t Immed8 = FlexImm->getImm(); |
| - const uint32_t Rotate = FlexImm->getRotateAmt(); |
| - assert((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits))); |
| - // TODO(kschimpf): Remove void casts when MINIMAL build allows. |
| - (void)kRotateBits; |
| - (void)kImmed8Bits; |
| + const InstValueType Immed8 = FlexImm->getImm(); |
| + const InstValueType Rotate = FlexImm->getRotateAmt(); |
| + if (!((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits)))) |
| + return CantDecode; |
| Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift); |
| return DecodedAsRotatedImm8; |
| } |
| return CantDecode; |
| } |
| -uint32_t decodeImmRegOffset(RegARM32::GPRRegister Reg, int32_t Offset, |
| - OperandARM32Mem::AddrMode Mode) { |
| - uint32_t Value = Mode | (encodeGPRRegister(Reg) << kRnShift); |
| +InstValueType decodeImmRegOffset(RegARM32::GPRRegister Reg, |
| + InstOffsetType Offset, |
| + OperandARM32Mem::AddrMode Mode) { |
| + InstValueType Value = Mode | (encodeGPRRegister(Reg) << kRnShift); |
| if (Offset < 0) { |
| Value = (Value ^ U) | -Offset; // Flip U to adjust sign. |
| } else { |
| @@ -186,12 +199,12 @@ uint32_t decodeImmRegOffset(RegARM32::GPRRegister Reg, int32_t Offset, |
| // Decodes memory address Opnd, and encodes that information into Value, |
| // based on how ARM represents the address. Returns how the value was encoded. |
| -DecodedResult decodeAddress(const Operand *Opnd, uint32_t &Value) { |
| +DecodedResult decodeAddress(const Operand *Opnd, InstValueType &Value) { |
| if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { |
| // Should be a stack variable, with an offset. |
| if (Var->hasReg()) |
| return CantDecode; |
| - const int32_t Offset = Var->getStackOffset(); |
| + const InstOffsetType Offset = Var->getStackOffset(); |
| if (!Utils::IsAbsoluteUint(12, Offset)) |
| return CantDecode; |
| Value = decodeImmRegOffset(RegARM32::Encoded_Reg_sp, Offset, |
| @@ -204,8 +217,9 @@ DecodedResult decodeAddress(const Operand *Opnd, uint32_t &Value) { |
| } // end of anonymous namespace |
| namespace Ice { |
| +namespace ARM32 { |
| -void ARM32::AssemblerARM32::bindCfgNodeLabel(const CfgNode *Node) { |
| +void AssemblerARM32::bindCfgNodeLabel(const CfgNode *Node) { |
| if (BuildDefs::dump() && !Ctx->getFlags().getDisableHybridAssembly()) { |
| // Generate label name so that branches can find it. |
| constexpr SizeT InstSize = 0; |
| @@ -217,8 +231,7 @@ void ARM32::AssemblerARM32::bindCfgNodeLabel(const CfgNode *Node) { |
| this->bind(L); |
| } |
| -Label *ARM32::AssemblerARM32::getOrCreateLabel(SizeT Number, |
| - LabelVector &Labels) { |
| +Label *AssemblerARM32::getOrCreateLabel(SizeT Number, LabelVector &Labels) { |
| Label *L = nullptr; |
| if (Number == Labels.size()) { |
| L = new (this->allocate<Label>()) Label(); |
| @@ -236,21 +249,40 @@ Label *ARM32::AssemblerARM32::getOrCreateLabel(SizeT Number, |
| return L; |
| } |
| -void ARM32::AssemblerARM32::bind(Label *label) { |
| - intptr_t bound = Buffer.size(); |
| - assert(!label->isBound()); // Labels can only be bound once. |
| - while (label->isLinked()) { |
| - intptr_t position = label->getLinkPosition(); |
| - intptr_t next = Buffer.load<int32_t>(position); |
| - Buffer.store<int32_t>(position, bound - (position + 4)); |
| - label->setPosition(next); |
| +InstValueType AssemblerARM32::encodeBranchOffset(InstOffsetType Offset, |
| + InstValueType Inst) { |
| + // TODO(kschimpf): Decide if we need to handle far jumps (ignoring for now). |
|
Jim Stichnoth
2015/10/23 21:32:07
For this TODO and the related one below, this is a
Karl
2015/10/26 18:32:43
Added function canEncodeBranchOffset to do check.
|
| + // Adjust offset to the way ARM CPUs read PC. |
| + Offset -= kPCReadOffset; |
| + |
| + // Properly preserve only the bits supported in the instruction. |
| + Offset >>= 2; |
| + Offset &= kBranchOffsetMask; |
| + return (Inst & ~kBranchOffsetMask) | Offset; |
| +} |
| + |
| +InstOffsetType AssemblerARM32::decodeBranchOffset(InstValueType Inst) { |
| + // Sign-extend, left-shift by 2, and adjust to the way ARM CPUs read PC. |
| + InstOffsetType Offset = |
| + static_cast<InstOffsetType>((Inst & kBranchOffsetMask) << 8); |
| + return (Offset >> 6) + kPCReadOffset; |
| +} |
| + |
| +void AssemblerARM32::bind(Label *L) { |
| + // TODO(kschimpf): Decide if we need to handle far jumps (ignoring for now). |
| + InstOffsetType BoundPc = Buffer.size(); |
| + assert(!L->isBound()); // Labels can only be bound once. |
| + while (L->isLinked()) { |
| + InstOffsetType Position = L->getLinkPosition(); |
| + InstOffsetType Dest = BoundPc - Position; |
| + InstValueType Inst = Buffer.load<InstValueType>(Position); |
| + Buffer.store<InstValueType>(Position, encodeBranchOffset(Dest, Inst)); |
| + L->setPosition(decodeBranchOffset(Inst)); |
| } |
| - // TODO(kschimpf) Decide if we have near jumps. |
| - label->bindTo(bound); |
| + L->bindTo(BoundPc); |
| } |
| -void ARM32::AssemblerARM32::emitTextInst(const std::string &Text, |
| - SizeT InstSize) { |
| +void AssemblerARM32::emitTextInst(const std::string &Text, SizeT InstSize) { |
| AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| AssemblerFixup *F = createTextFixup(Text, InstSize); |
| emitFixup(F); |
| @@ -258,44 +290,73 @@ void ARM32::AssemblerARM32::emitTextInst(const std::string &Text, |
| Buffer.emit<char>(0); |
| } |
| -void ARM32::AssemblerARM32::emitType01(CondARM32::Cond Cond, uint32_t Type, |
| - uint32_t Opcode, bool SetCc, uint32_t Rn, |
| - uint32_t Rd, uint32_t Imm12) { |
| +void AssemblerARM32::emitType01(CondARM32::Cond Cond, InstValueType Type, |
| + InstValueType Opcode, bool SetCc, |
| + InstValueType Rn, InstValueType Rd, |
| + InstValueType Imm12) { |
| assert(isGPRRegisterDefined(Rd)); |
| // TODO(kschimpf): Remove void cast when MINIMAL build allows. |
| (void)isGPRRegisterDefined(Rd); |
| assert(Cond != CondARM32::kNone); |
| AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| - const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | |
| - (Type << kTypeShift) | (Opcode << kOpcodeShift) | |
| - (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | |
| - (Rd << kRdShift) | Imm12; |
| + const InstValueType Encoding = |
| + (encodeCondition(Cond) << kConditionShift) | (Type << kTypeShift) | |
| + (Opcode << kOpcodeShift) | (encodeBool(SetCc) << kSShift) | |
| + (Rn << kRnShift) | (Rd << kRdShift) | Imm12; |
| emitInst(Encoding); |
| } |
| -void ARM32::AssemblerARM32::emitMemOp(CondARM32::Cond Cond, uint32_t InstType, |
| - bool IsLoad, bool IsByte, uint32_t Rt, |
| - uint32_t Address) { |
| +void AssemblerARM32::emitType05(CondARM32::Cond Cond, InstOffsetType Offset, |
| + bool Link) { |
| + // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and |
| + // iiiiiiiiiiiiiiiiiiiiiiii= |
| + // EncodedBranchOffset(cccc101l000000000000000000000000, Offset); |
| + if (!isConditionDefined(Cond)) |
| + return setNeedsTextFixup(); |
| + AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| + InstValueType Encoding = static_cast<int32_t>(Cond) << kConditionShift | |
| + 5 << kTypeShift | (Link ? 1 : 0) << kLinkShift; |
| + Encoding = encodeBranchOffset(Offset, Encoding); |
| + emitInst(Encoding); |
| +} |
| + |
| +void AssemblerARM32::emitBranch(Label *L, CondARM32::Cond Cond, bool Link) { |
| + // TODO(kschimpf): Is there a way to verify that near jump applies? |
| + if (L->isBound()) { |
| + const int32_t Dest = L->getPosition() - Buffer.size(); |
| + emitType05(Cond, Dest, Link); |
| + return; |
| + } |
| + const InstOffsetType Position = Buffer.size(); |
| + // Use the offset field of the branch instruction for linking the sites. |
| + emitType05(Cond, L->getEncodedPosition(), Link); |
| + if (!needsTextFixup()) |
| + L->linkTo(Position); |
| +} |
| + |
| +void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, InstValueType InstType, |
| + bool IsLoad, bool IsByte, InstValueType Rt, |
| + InstValueType Address) { |
| assert(isGPRRegisterDefined(Rt)); |
| assert(Cond != CondARM32::kNone); |
| AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| - const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | |
| - (InstType << kTypeShift) | (IsLoad ? L : 0) | |
| - (IsByte ? B : 0) | (Rt << kRdShift) | Address; |
| + const InstValueType Encoding = (encodeCondition(Cond) << kConditionShift) | |
| + (InstType << kTypeShift) | (IsLoad ? L : 0) | |
| + (IsByte ? B : 0) | (Rt << kRdShift) | Address; |
| emitInst(Encoding); |
| } |
| -void ARM32::AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn, |
| - const Operand *OpSrc1, bool SetFlags, |
| - CondARM32::Cond Cond) { |
| - uint32_t Rd; |
| +void AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn, |
| + const Operand *OpSrc1, bool SetFlags, |
| + CondARM32::Cond Cond) { |
| + InstValueType Rd; |
| if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
| return setNeedsTextFixup(); |
| - uint32_t Rn; |
| + InstValueType Rn; |
| if (decodeOperand(OpRn, Rn) != DecodedAsRegister) |
| return setNeedsTextFixup(); |
| - constexpr uint32_t Add = B2; // 0100 |
| - uint32_t Src1Value; |
| + constexpr InstValueType Add = B2; // 0100 |
| + InstValueType Src1Value; |
| // TODO(kschimpf) Other possible decodings of add. |
| switch (decodeOperand(OpSrc1, Src1Value)) { |
| default: |
| @@ -332,18 +393,23 @@ void ARM32::AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn, |
| }; |
| } |
| -void ARM32::AssemblerARM32::bkpt(uint16_t Imm16) { |
| +void AssemblerARM32::b(Label *L, CondARM32::Cond Cond) { |
| + emitBranch(L, Cond, false); |
| +} |
| + |
| +void AssemblerARM32::bkpt(uint16_t Imm16) { |
| // BKPT - ARM section A*.8.24 - encoding A1: |
| // bkpt #<Imm16> |
| // |
| // cccc00010010iiiiiiiiiiii0111iiii where cccc=AL and iiiiiiiiiiiiiiii=Imm16 |
| AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| - const uint32_t Encoding = (CondARM32::AL << kConditionShift) | B24 | B21 | |
| - ((Imm16 >> 4) << 8) | B6 | B5 | B4 | (Imm16 & 0xf); |
| + const InstValueType 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 AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) { |
| // BX - ARM section A8.8.27, encoding A1: |
| // bx<c> <Rm> |
| // |
| @@ -351,18 +417,18 @@ void ARM32::AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) { |
| if (!(isGPRRegisterDefined(Rm) && isConditionDefined(Cond))) |
| return setNeedsTextFixup(); |
| AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| - const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | |
| - B21 | (0xfff << 8) | B4 | |
| - (encodeGPRRegister(Rm) << kRmShift); |
| + const InstValueType Encoding = (encodeCondition(Cond) << kConditionShift) | |
| + B24 | B21 | (0xfff << 8) | B4 | |
| + (encodeGPRRegister(Rm) << kRmShift); |
| emitInst(Encoding); |
| } |
| -void ARM32::AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, |
| - CondARM32::Cond Cond) { |
| - uint32_t Rt; |
| +void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, |
| + CondARM32::Cond Cond) { |
| + InstValueType Rt; |
| if (decodeOperand(OpRt, Rt) != DecodedAsRegister) |
| return setNeedsTextFixup(); |
| - uint32_t Address; |
| + InstValueType Address; |
| if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset) |
| return setNeedsTextFixup(); |
| // LDR (immediate) - ARM section A8.8.63, encoding A1: |
| @@ -393,12 +459,12 @@ void ARM32::AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, |
| emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); |
| } |
| -void ARM32::AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc, |
| - CondARM32::Cond Cond) { |
| - uint32_t Rd; |
| +void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc, |
| + CondARM32::Cond Cond) { |
| + InstValueType Rd; |
| if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
| return setNeedsTextFixup(); |
| - uint32_t Src; |
| + InstValueType Src; |
| // TODO(kschimpf) Handle other forms of mov. |
| if (decodeOperand(OpSrc, Src) != DecodedAsRotatedImm8) |
| return setNeedsTextFixup(); |
| @@ -412,17 +478,17 @@ void ARM32::AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc, |
| if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) |
| // Conditions of rule violated. |
| return setNeedsTextFixup(); |
| - constexpr uint32_t Rn = 0; |
| - constexpr uint32_t Mov = B3 | B2 | B0; // 1101. |
| + constexpr InstValueType Rn = 0; |
| + constexpr InstValueType Mov = B3 | B2 | B0; // 1101. |
| emitType01(Cond, kInstTypeDataImmediate, Mov, SetFlags, Rn, Rd, Src); |
| } |
| -void ARM32::AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, |
| - CondARM32::Cond Cond) { |
| - uint32_t Rt; |
| +void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, |
| + CondARM32::Cond Cond) { |
| + InstValueType Rt; |
| if (decodeOperand(OpRt, Rt) != DecodedAsRegister) |
| return setNeedsTextFixup(); |
| - uint32_t Address; |
| + InstValueType Address; |
| if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset) |
| return setNeedsTextFixup(); |
| // STR (immediate) - ARM section A8.8.204, encoding A1: |
| @@ -453,17 +519,17 @@ void ARM32::AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, |
| emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); |
| } |
| -void ARM32::AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, |
| - const Operand *OpSrc1, bool SetFlags, |
| - CondARM32::Cond Cond) { |
| - uint32_t Rd; |
| +void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, |
| + const Operand *OpSrc1, bool SetFlags, |
| + CondARM32::Cond Cond) { |
| + InstValueType Rd; |
| if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
| return setNeedsTextFixup(); |
| - uint32_t Rn; |
| + InstValueType Rn; |
| if (decodeOperand(OpRn, Rn) != DecodedAsRegister) |
| return setNeedsTextFixup(); |
| - constexpr uint32_t Sub = B1; // 0010 |
| - uint32_t Src1Value; |
| + constexpr InstValueType Sub = B1; // 0010 |
| + InstValueType Src1Value; |
| // TODO(kschimpf) Other possible decodings of sub. |
| switch (decodeOperand(OpSrc1, Src1Value)) { |
| default: |
| @@ -500,4 +566,5 @@ void ARM32::AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, |
| } |
| } |
| +} // end of namespace ARM32 |
| } // end of namespace Ice |