Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Unified Diff: src/IceAssemblerARM32.cpp

Issue 1418313003: Handle branch relative to pc in ARM integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix issues in patch set 2. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/IceAssemblerARM32.cpp
diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp
index 598146cad583fc35862d02a422d3b52661307295..7f5998c67beef270a36c72baab16a7db87c7cbe7 100644
--- a/src/IceAssemblerARM32.cpp
+++ b/src/IceAssemblerARM32.cpp
@@ -27,66 +27,78 @@
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 IValueT B0 = 1;
+static constexpr IValueT B1 = 1 << 1;
+static constexpr IValueT B2 = 1 << 2;
+static constexpr IValueT B3 = 1 << 3;
+static constexpr IValueT B4 = 1 << 4;
+static constexpr IValueT B5 = 1 << 5;
+static constexpr IValueT B6 = 1 << 6;
+static constexpr IValueT B21 = 1 << 21;
+static constexpr IValueT 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 IValueT L = 1 << 20; // load (or store)
+static constexpr IValueT W = 1 << 21; // writeback base register
+ // (or leave unchanged)
+static constexpr IValueT B = 1 << 22; // unsigned byte (or word)
+static constexpr IValueT U = 1 << 23; // positive (or negative)
+ // offset/index
+static constexpr IValueT P = 1 << 24; // offset/pre-indexed
+ // addressing (or
+ // post-indexed addressing)
+
+static constexpr IValueT kConditionShift = 28;
+static constexpr IValueT kLinkShift = 24;
+static constexpr IValueT kOpcodeShift = 21;
+static constexpr IValueT kRdShift = 12;
+static constexpr IValueT kRmShift = 0;
+static constexpr IValueT kRnShift = 16;
+static constexpr IValueT kSShift = 20;
+static constexpr IValueT 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 IValueT kImmed8Bits = 8;
+static constexpr IValueT kImmed8Shift = 0;
+static constexpr IValueT kRotateBits = 4;
+static constexpr IValueT 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 IValueT kShiftImmShift = 7;
+static constexpr IValueT kShiftImmBits = 5;
+static constexpr IValueT kShiftShift = 5;
-static constexpr uint32_t kImmed12Bits = 12;
-static constexpr uint32_t kImm12Shift = 0;
+static constexpr IValueT kImmed12Bits = 12;
+static constexpr IValueT 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 IValueT kInstTypeDataRegister = 0; // i.e. 000
+static constexpr IValueT kInstTypeDataImmediate = 1; // i.e. 001
+static constexpr IValueT 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 IOffsetT 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 int kBranchOffsetBits = 24;
+static constexpr IOffsetT kBranchOffsetMask = 0x00ffffff;
+
+inline IValueT encodeBool(bool b) { return b ? 1 : 0; }
Jim Stichnoth 2015/10/26 22:59:08 Probably want B instead of b
Karl 2015/10/27 14:28:27 Done.
+
+inline IValueT encodeGPRRegister(RegARM32::GPRRegister Rn) {
+ return static_cast<IValueT>(Rn);
}
inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) {
return R != RegARM32::Encoded_Not_GPR;
}
-inline bool isGPRRegisterDefined(uint32_t R) {
+inline bool isGPRRegisterDefined(IValueT R) {
return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR);
}
@@ -94,11 +106,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 IValueT encodeCondition(CondARM32::Cond Cond) {
+ return static_cast<IValueT>(Cond);
}
-uint32_t encodeShift(OperandARM32::ShiftKind Shift) {
+IValueT encodeShift(OperandARM32::ShiftKind Shift) {
// Follows encoding in ARM section A8.4.1 "Constant shifts".
switch (Shift) {
case OperandARM32::kNoShift:
@@ -115,17 +127,17 @@ 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 IValueT mask(IValueT Value, IValueT Shift, IValueT 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(IValueT Bit, IValueT 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(IValueT Shift, IValueT Value) {
return static_cast<RegARM32::GPRRegister>((Value >> Shift) & 0xF);
}
@@ -147,35 +159,33 @@ 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) {
+IValueT encodeShiftRotateImm5(IValueT Rm, OperandARM32::ShiftKind Shift,
+ IValueT 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, IValueT &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 IValueT Immed8 = FlexImm->getImm();
+ const IValueT 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);
+IValueT decodeImmRegOffset(RegARM32::GPRRegister Reg, IOffsetT Offset,
+ OperandARM32Mem::AddrMode Mode) {
+ IValueT Value = Mode | (encodeGPRRegister(Reg) << kRnShift);
if (Offset < 0) {
Value = (Value ^ U) | -Offset; // Flip U to adjust sign.
} else {
@@ -186,12 +196,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, IValueT &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 IOffsetT Offset = Var->getStackOffset();
if (!Utils::IsAbsoluteUint(12, Offset))
return CantDecode;
Value = decodeImmRegOffset(RegARM32::Encoded_Reg_sp, Offset,
@@ -201,11 +211,18 @@ DecodedResult decodeAddress(const Operand *Opnd, uint32_t &Value) {
return CantDecode;
}
+// Checks that Offset can fit in imm24 constant of branch (b) instruction.
+bool canEncodeBranchOffset(IOffsetT Offset) {
+ return Utils::IsAligned(Offset, 4) &&
+ Utils::IsInt(kBranchOffsetBits, Offset >> 2);
+}
+
} // 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 +234,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 +252,41 @@ 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);
+IValueT AssemblerARM32::encodeBranchOffset(IOffsetT Offset, IValueT Inst) {
+ // Adjust offset to the way ARM CPUs read PC.
+ Offset -= kPCReadOffset;
+
+ bool isGoodOffset = canEncodeBranchOffset(Offset);
Jim Stichnoth 2015/10/26 22:59:08 IsGoodOffset
Karl 2015/10/27 14:28:27 Done.
+ assert(isGoodOffset);
+ // Note: Following cast is for MINIMAL build.
+ (void)isGoodOffset;
+
+ // Properly preserve only the bits supported in the instruction.
+ Offset >>= 2;
+ Offset &= kBranchOffsetMask;
+ return (Inst & ~kBranchOffsetMask) | Offset;
+}
+
+IOffsetT AssemblerARM32::decodeBranchOffset(IValueT Inst) {
+ // Sign-extend, left-shift by 2, and adjust to the way ARM CPUs read PC.
+ IOffsetT Offset = static_cast<IOffsetT>((Inst & kBranchOffsetMask) << 8);
+ return (Offset >> 6) + kPCReadOffset;
+}
+
+void AssemblerARM32::bind(Label *L) {
+ IOffsetT BoundPc = Buffer.size();
+ assert(!L->isBound()); // Labels can only be bound once.
+ while (L->isLinked()) {
+ IOffsetT Position = L->getLinkPosition();
+ IOffsetT Dest = BoundPc - Position;
+ IValueT Inst = Buffer.load<IValueT>(Position);
+ Buffer.store<IValueT>(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 +294,72 @@ 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, IValueT Type,
+ IValueT Opcode, bool SetCc, IValueT Rn,
+ IValueT Rd, IValueT 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 IValueT 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, IOffsetT Offset,
+ bool Link) {
+ // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and
+ // iiiiiiiiiiiiiiiiiiiiiiii=
+ // EncodedBranchOffset(cccc101l000000000000000000000000, Offset);
+ if (!isConditionDefined(Cond))
+ return setNeedsTextFixup();
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ IValueT 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): Handle far jumps.
+ if (L->isBound()) {
+ const int32_t Dest = L->getPosition() - Buffer.size();
+ emitType05(Cond, Dest, Link);
+ return;
+ }
+ const IOffsetT 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, IValueT InstType,
+ bool IsLoad, bool IsByte, IValueT Rt,
+ IValueT 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 IValueT 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) {
+ IValueT Rd;
if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
return setNeedsTextFixup();
- uint32_t Rn;
+ IValueT Rn;
if (decodeOperand(OpRn, Rn) != DecodedAsRegister)
return setNeedsTextFixup();
- constexpr uint32_t Add = B2; // 0100
- uint32_t Src1Value;
+ constexpr IValueT Add = B2; // 0100
+ IValueT Src1Value;
// TODO(kschimpf) Other possible decodings of add.
switch (decodeOperand(OpSrc1, Src1Value)) {
default:
@@ -332,18 +396,22 @@ 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 IValueT 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 +419,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 IValueT 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) {
+ IValueT Rt;
if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
return setNeedsTextFixup();
- uint32_t Address;
+ IValueT Address;
if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset)
return setNeedsTextFixup();
// LDR (immediate) - ARM section A8.8.63, encoding A1:
@@ -393,12 +461,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) {
+ IValueT Rd;
if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
return setNeedsTextFixup();
- uint32_t Src;
+ IValueT Src;
// TODO(kschimpf) Handle other forms of mov.
if (decodeOperand(OpSrc, Src) != DecodedAsRotatedImm8)
return setNeedsTextFixup();
@@ -412,17 +480,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 IValueT Rn = 0;
+ constexpr IValueT 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) {
+ IValueT Rt;
if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
return setNeedsTextFixup();
- uint32_t Address;
+ IValueT Address;
if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset)
return setNeedsTextFixup();
// STR (immediate) - ARM section A8.8.204, encoding A1:
@@ -453,17 +521,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) {
+ IValueT Rd;
if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
return setNeedsTextFixup();
- uint32_t Rn;
+ IValueT Rn;
if (decodeOperand(OpRn, Rn) != DecodedAsRegister)
return setNeedsTextFixup();
- constexpr uint32_t Sub = B1; // 0010
- uint32_t Src1Value;
+ constexpr IValueT Sub = B1; // 0010
+ IValueT Src1Value;
// TODO(kschimpf) Other possible decodings of sub.
switch (decodeOperand(OpSrc1, Src1Value)) {
default:
@@ -500,4 +568,5 @@ void ARM32::AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn,
}
}
+} // end of namespace ARM32
} // end of namespace Ice
« src/IceAssemblerARM32.h ('K') | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698