aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/ARM/ARMAddressingModes.h
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-06-23 17:48:47 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-06-23 17:48:47 +0000
commitf49810c7e60807c43a68ab02c936a4ee77a4d2cf (patch)
treebe9a566fb443c19412217da5a94e7ffd5cc00223 /lib/Target/ARM/ARMAddressingModes.h
parent5a9c0eeaf23a498de19c805395cc0e2762dbf3d3 (diff)
Initial Thumb2 support. Majority of the work is done by David Goodwin. There are
also some contribution from Jim Grosbach, Bob Wilson, and Evan Cheng. I've done my best to consolidate the patches with those that were done by Viktor Kutuzov and Anton Korzh from Access Softek, Inc. Let me know if missed anything. I've completely reorganized the thumb2 td file, made more extensive uses of multiclass, etc. Test cases will be contributed later after I re-organize what's in svn first. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73965 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMAddressingModes.h')
-rw-r--r--lib/Target/ARM/ARMAddressingModes.h110
1 files changed, 110 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMAddressingModes.h b/lib/Target/ARM/ARMAddressingModes.h
index 6d9b9ee880..005eb7a10f 100644
--- a/lib/Target/ARM/ARMAddressingModes.h
+++ b/lib/Target/ARM/ARMAddressingModes.h
@@ -248,12 +248,122 @@ namespace ARM_AM {
return V == 0;
}
+ /// getThumbImm16ValShift - Try to handle Imm with a 16-bit immediate followed
+ /// by a left shift. Returns the shift amount to use.
+ static inline unsigned getThumbImm16ValShift(unsigned Imm) {
+ // 16-bit (or less) immediates are trivially immediate operand with a shift
+ // of zero.
+ if ((Imm & ~65535U) == 0) return 0;
+
+ // Use CTZ to compute the shift amount.
+ return CountTrailingZeros_32(Imm);
+ }
+
+ /// isThumbImm16ShiftedVal - Return true if the specified value can be
+ /// obtained by left shifting a 16-bit immediate.
+ static inline bool isThumbImm16ShiftedVal(unsigned V) {
+ // If this can be handled with
+ V = (~65535U << getThumbImm16ValShift(V)) & V;
+ return V == 0;
+ }
+
/// getThumbImmNonShiftedVal - If V is a value that satisfies
/// isThumbImmShiftedVal, return the non-shiftd value.
static inline unsigned getThumbImmNonShiftedVal(unsigned V) {
return V >> getThumbImmValShift(V);
}
+ /// getT2SOImmValDecode - Given a 12-bit encoded Thumb-2 modified immediate,
+ /// return the corresponding 32-bit immediate value.
+ /// See ARM Reference Manual A6.3.2.
+ static inline unsigned getT2SOImmValDecode(unsigned Imm) {
+ unsigned Base = Imm & 0xff;
+ switch ((Imm >> 8) & 0xf) {
+ case 0:
+ return Base;
+ case 1:
+ return Base | (Base << 16);
+ case 2:
+ return (Base << 8) | (Base << 24);
+ case 3:
+ return Base | (Base << 8) | (Base << 16) | (Base << 24);
+ default:
+ break;
+ }
+
+ // shifted immediate
+ unsigned RotAmount = ((Imm >> 7) & 0x1f) - 8;
+ return (Base | 0x80) << (24 - RotAmount);
+ }
+
+ /// getT2SOImmValSplat - Return the 12-bit encoded representation
+ /// if the specified value can be obtained by splatting the low 8 bits
+ /// into every other byte or every byte of a 32-bit value. i.e.,
+ /// 00000000 00000000 00000000 abcdefgh control = 0
+ /// 00000000 abcdefgh 00000000 abcdefgh control = 1
+ /// abcdefgh 00000000 abcdefgh 00000000 control = 2
+ /// abcdefgh abcdefgh abcdefgh abcdefgh control = 3
+ /// Return -1 if none of the above apply.
+ /// See ARM Reference Manual A6.3.2.
+ static inline int getT2SOImmValSplat (unsigned V) {
+ unsigned u, Vs, Imm;
+ // control = 0
+ if ((V & 0xffffff00) == 0)
+ return V;
+
+ // If the value is zeroes in the first byte, just shift those off
+ Vs = ((V & 0xff) == 0) ? V >> 8 : V;
+ // Any passing value only has 8 bits of payload, splatted across the word
+ Imm = Vs & 0xff;
+ // Likewise, any passing values have the payload splatted into the 3rd byte
+ u = Imm | (Imm << 16);
+
+ // control = 1 or 2
+ if (Vs == u)
+ return (((Vs == V) ? 1 : 2) << 8) | Imm;
+
+ // control = 3
+ if (Vs == (u | (u << 8)))
+ return (3 << 8) | Imm;
+
+ return -1;
+ }
+
+ /// getT2SOImmValRotate - Return the 12-bit encoded representation if the
+ /// specified value is a rotated 8-bit value. Return -1 if no rotation
+ /// encoding is possible.
+ /// See ARM Reference Manual A6.3.2.
+ static inline int getT2SOImmValRotate (unsigned V) {
+ unsigned RotAmt = CountLeadingZeros_32(V);
+ if (RotAmt >= 24)
+ return -1;
+
+ // If 'Arg' can be handled with a single shifter_op return the value.
+ if ((rotr32(0xff000000U, RotAmt) & V) == V)
+ return (rotr32(V, 24 - RotAmt) & 0x7f) | ((RotAmt + 8) << 7);
+
+ return -1;
+ }
+
+ /// getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit
+ /// into a Thumb-2 shifter_operand immediate operand, return the 12-bit
+ /// encoding for it. If not, return -1.
+ /// See ARM Reference Manual A6.3.2.
+ static inline int getT2SOImmVal(unsigned Arg) {
+ // If 'Arg' is an 8-bit splat, then get the encoded value.
+ int Splat = getT2SOImmValSplat(Arg);
+ if (Splat != -1)
+ return Splat;
+
+ // If 'Arg' can be handled with a single shifter_op return the value.
+ int Rot = getT2SOImmValRotate(Arg);
+ if (Rot != -1)
+ return Rot;
+
+ return -1;
+ }
+
+
//===--------------------------------------------------------------------===//
// Addressing Mode #2
//===--------------------------------------------------------------------===//