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

Unified Diff: src/IceAssemblerARM32.cpp

Issue 1630863002: Clean up register+immediate addresses in ARM. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. Created 4 years, 11 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceAssemblerARM32.cpp
diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp
index c4d5ad680c99e3cd19eb5d1e991a6f9423a2b2db..0132d709a20e992cf05c4d3d69d975105ba7c44f 100644
--- a/src/IceAssemblerARM32.cpp
+++ b/src/IceAssemblerARM32.cpp
@@ -175,22 +175,6 @@ RegARM32::GPRRegister getGPRReg(IValueT Shift, IValueT Value) {
return decodeGPRRegister((Value >> Shift) & 0xF);
}
-// Defines alternate layouts of instruction operands, should the (common)
-// default pattern not be used.
-enum OpEncoding {
- // No alternate layout specified.
- DefaultOpEncoding,
- // Alternate encoding for ImmRegOffset, where the offset is divided by 4
- // before encoding.
- ImmRegOffsetDiv4,
- // Alternate encoding 3 for memory operands (like in strb, strh, ldrb, and
- // ldrh.
- OpEncoding3,
- // Alternate encoding for memory operands for ldrex and strex, which only
- // actually expect a register.
- OpEncodingMemEx
-};
-
IValueT getEncodedGPRegNum(const Variable *Var) {
assert(Var->hasReg());
int32_t Reg = Var->getRegNum();
@@ -215,6 +199,23 @@ IValueT getYInRegYXXXX(IValueT RegYXXXX) { return RegYXXXX >> 4; }
IValueT getXXXXInRegYXXXX(IValueT RegYXXXX) { return RegYXXXX & 0x0f; }
+// Defines layouts of an operand representing a (register) memory address,
+// possibly modified by an immediate value.
+enum EncodedImmAddress {
+ // Address modified by a rotated immediate 8-bit value.
+ RotatedImm8Address,
+ // Alternate encoding for RotatedImm8Address, where the offset is divided by 4
Jim Stichnoth 2016/01/25 20:37:50 Optional: Consider adding a blank line after each
Karl 2016/01/25 23:59:16 Added blank lines. Did same for following enum Enc
+ // before encoding.
+ RotatedImm8Div4Address,
+ // Address modified by an immediate 12-bit value.
+ Imm12Address,
+ // Alternate encoding 3, for an address modified by a rotated immediate 8-bit
+ // value.
+ RotatedImm8Enc3Address,
+ // Encoding where no immediate offset is used.
+ NoImmOffsetAddress
+};
+
// The way an operand is encoded into a sequence of bits in functions
// encodeOperand and encodeAddress below.
enum EncodedOperand {
@@ -226,24 +227,29 @@ enum EncodedOperand {
// value.
EncodedAsRotatedImm8,
// EncodedAsImmRegOffset is a memory operand that can take three forms, based
- // on OpEncoding:
+ // on type EncodedImmAddress:
//
- // ***** DefaultOpEncoding *****
+ // ***** RotatedImm8Address *****
//
// Value=0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn,
// p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to
// Rn should be used, and iiiiiiiiiiii defines the rotated Imm8 value.
//
- // ***** OpEncoding3 *****
+ // ***** RotatedImm8Div4Address *****
//
// Value=00000000pu0w0nnnn0000iiii0000jjjj where nnnn=Rn, iiiijjjj=Imm8, p=1
// if pre-indexed addressing, u=1 if offset positive, and w=1 if writeback to
// Rn.
//
- // ***** OpEncodingMemEx *****
+ // ***** Imm12Address *****
//
- // Value=00000000U000nnnn00000000xxxxxxxx where nnnn=Rn, xxxxxxxx=abs(Offset),
- // and U=1 Offset>=0.
+ // Value=0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn,
+ // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to
+ // Rn should be used, and iiiiiiiiiiii defines the immediate 12-bit value.
+ //
+ // ***** NoImmOffsetAddress *****
+ //
+ // Value=000000001000nnnn0000000000000000 where nnnn=Rn.
EncodedAsImmRegOffset,
// Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn,
// mmmm is the index register Rm, iiiii is the shift amount, ss is the shift
@@ -356,14 +362,16 @@ EncodedOperand encodeOperand(const Operand *Opnd, IValueT &Value,
return CantEncode;
}
-IValueT encodeImmRegOffset(IValueT Reg, IOffsetT Offset,
- OperandARM32Mem::AddrMode Mode,
- IValueT OffsetShift = 0) {
+inline IValueT encodeImmRegOffset(IValueT Reg, IOffsetT Offset,
Jim Stichnoth 2016/01/25 20:37:50 Why inline here? This seems inconsistent with the
Karl 2016/01/25 23:59:16 Removed.
+ OperandARM32Mem::AddrMode Mode,
+ IOffsetT MaxOffset, IValueT OffsetShift) {
IValueT Value = Mode | (Reg << kRnShift);
if (Offset < 0) {
Offset = -Offset;
Value ^= U; // Flip U to adjust sign.
}
+ assert(Offset <= MaxOffset);
+ (void)MaxOffset;
return Value | (Offset >> OffsetShift);
}
@@ -380,23 +388,33 @@ IValueT encodeImmRegOffsetEnc3(IValueT Rn, IOffsetT Imm8,
return Value;
}
-IValueT encodeImmRegOffset(OpEncoding AddressEncoding, IValueT Reg,
+IValueT encodeImmRegOffset(EncodedImmAddress ImmEncoding, IValueT Reg,
IOffsetT Offset, OperandARM32Mem::AddrMode Mode) {
- switch (AddressEncoding) {
- case DefaultOpEncoding:
- return encodeImmRegOffset(Reg, Offset, Mode);
- case ImmRegOffsetDiv4: {
+ switch (ImmEncoding) {
+ case RotatedImm8Address: {
+ constexpr IOffsetT MaxOffset = (1 << 8) - 1;
+ constexpr IValueT NoRightShift = 0;
+ return encodeImmRegOffset(Reg, Offset, Mode, MaxOffset, NoRightShift);
+ }
+ case RotatedImm8Div4Address: {
assert((Offset & 0x3) == 0);
+ constexpr IOffsetT MaxOffset = (1 << 8) - 1;
constexpr IValueT RightShift2 = 2;
- return encodeImmRegOffset(Reg, Offset, Mode, RightShift2);
+ return encodeImmRegOffset(Reg, Offset, Mode, MaxOffset, RightShift2);
+ }
+ case Imm12Address: {
+ constexpr IOffsetT MaxOffset = (1 << 12) - 1;
+ constexpr IValueT NoRightShift = 0;
+ return encodeImmRegOffset(Reg, Offset, Mode, MaxOffset, NoRightShift);
}
- case OpEncoding3:
+ case RotatedImm8Enc3Address:
return encodeImmRegOffsetEnc3(Reg, Offset, Mode);
- case OpEncodingMemEx:
+ case NoImmOffsetAddress: {
assert(Offset == 0);
assert(Mode == OperandARM32Mem::Offset);
return Reg << kRnShift;
}
+ }
llvm_unreachable("(silence g++ warning)");
}
@@ -404,7 +422,7 @@ IValueT encodeImmRegOffset(OpEncoding AddressEncoding, IValueT Reg,
// on how ARM represents the address. Returns how the value was encoded.
EncodedOperand encodeAddress(const Operand *Opnd, IValueT &Value,
const AssemblerARM32::TargetInfo &TInfo,
- OpEncoding AddressEncoding = DefaultOpEncoding) {
+ EncodedImmAddress ImmEncoding) {
Value = 0; // Make sure initialized.
if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
// Should be a stack variable, with an offset.
@@ -416,7 +434,7 @@ EncodedOperand encodeAddress(const Operand *Opnd, IValueT &Value,
int32_t BaseRegNum = Var->getBaseRegNum();
if (BaseRegNum == Variable::NoRegister)
BaseRegNum = TInfo.FrameOrStackReg;
- Value = encodeImmRegOffset(AddressEncoding, BaseRegNum, Offset,
+ Value = encodeImmRegOffset(ImmEncoding, BaseRegNum, Offset,
OperandARM32Mem::Offset);
return EncodedAsImmRegOffset;
}
@@ -436,7 +454,7 @@ EncodedOperand encodeAddress(const Operand *Opnd, IValueT &Value,
}
// Encoded as immediate register offset.
ConstantInteger32 *Offset = Mem->getOffset();
- Value = encodeImmRegOffset(AddressEncoding, Rn, Offset->getValue(),
+ Value = encodeImmRegOffset(ImmEncoding, Rn, Offset->getValue(),
Mem->getAddrMode());
return EncodedAsImmRegOffset;
}
@@ -802,7 +820,7 @@ void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, bool IsLoad, bool IsByte,
IValueT Rt, const Operand *OpAddress,
const TargetInfo &TInfo, const char *InstName) {
IValueT Address;
- switch (encodeAddress(OpAddress, Address, TInfo)) {
+ switch (encodeAddress(OpAddress, Address, TInfo, Imm12Address)) {
default:
llvm::report_fatal_error(std::string(InstName) +
": Memory address not understood");
@@ -860,7 +878,7 @@ void AssemblerARM32::emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode,
const TargetInfo &TInfo,
const char *InstName) {
IValueT Address;
- switch (encodeAddress(OpAddress, Address, TInfo, OpEncoding3)) {
+ switch (encodeAddress(OpAddress, Address, TInfo, RotatedImm8Enc3Address)) {
default:
llvm::report_fatal_error(std::string(InstName) +
": Memory address not understood");
@@ -1356,7 +1374,7 @@ void AssemblerARM32::emitMemExOp(CondARM32::Cond Cond, Type Ty, bool IsLoad,
MemExOpcode |= B1;
}
IValueT AddressRn;
- if (encodeAddress(OpAddress, AddressRn, TInfo, OpEncodingMemEx) !=
+ if (encodeAddress(OpAddress, AddressRn, TInfo, NoImmOffsetAddress) !=
EncodedAsImmRegOffset)
llvm::report_fatal_error(std::string(InstName) +
": Can't extract Rn from address");
@@ -1730,8 +1748,11 @@ void AssemblerARM32::pop(const Variable *OpRt, CondARM32::Cond Cond) {
// Same as load instruction.
constexpr bool IsLoad = true;
constexpr bool IsByte = false;
- IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize,
- OperandARM32Mem::PostIndex);
+ constexpr IOffsetT MaxOffset = (1 << 8) - 1;
+ constexpr IValueT NoShiftRight = 0;
+ IValueT Address =
+ encodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize,
+ OperandARM32Mem::PostIndex, MaxOffset, NoShiftRight);
emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
}
@@ -1756,8 +1777,11 @@ void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) {
// Same as store instruction.
constexpr bool isLoad = false;
constexpr bool isByte = false;
- IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize,
- OperandARM32Mem::PreIndex);
+ constexpr IOffsetT MaxOffset = (1 << 8) - 1;
+ constexpr IValueT NoShiftRight = 0;
+ IValueT Address =
+ encodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize,
+ OperandARM32Mem::PreIndex, MaxOffset, NoShiftRight);
emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address);
}
@@ -2322,7 +2346,7 @@ void AssemblerARM32::vldrd(const Operand *OpDd, const Operand *OpAddress,
assert(CondARM32::isDefined(Cond));
IValueT Address;
EncodedOperand AddressEncoding =
- encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4);
+ encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address);
(void)AddressEncoding;
assert(AddressEncoding == EncodedAsImmRegOffset);
IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 | B8 |
@@ -2344,7 +2368,7 @@ void AssemblerARM32::vldrs(const Operand *OpSd, const Operand *OpAddress,
assert(CondARM32::isDefined(Cond));
IValueT Address;
EncodedOperand AddressEncoding =
- encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4);
+ encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address);
(void)AddressEncoding;
assert(AddressEncoding == EncodedAsImmRegOffset);
IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 |
@@ -2429,7 +2453,7 @@ void AssemblerARM32::vstrd(const Operand *OpDd, const Operand *OpAddress,
assert(CondARM32::isDefined(Cond));
IValueT Address;
IValueT AddressEncoding =
- encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4);
+ encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address);
(void)AddressEncoding;
assert(AddressEncoding == EncodedAsImmRegOffset);
IValueT Encoding = B27 | B26 | B24 | B11 | B9 | B8 |
@@ -2451,7 +2475,7 @@ void AssemblerARM32::vstrs(const Operand *OpSd, const Operand *OpAddress,
assert(CondARM32::isDefined(Cond));
IValueT Address;
IValueT AddressEncoding =
- encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4);
+ encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address);
(void)AddressEncoding;
assert(AddressEncoding == EncodedAsImmRegOffset);
IValueT Encoding =
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698