add = '+', sub = '-'
};
+ static inline const char *getAddrOpcStr(AddrOpc Op) {
+ return Op == sub ? "-" : "";
+ }
+
static inline const char *getShiftOpcStr(ShiftOpc Op) {
switch (Op) {
default: assert(0 && "Unknown shift opc!");
if ((rotr32(Imm, RotAmt) & ~255U) == 0)
return (32-RotAmt)&31; // HW rotates right, not left.
- // For values like 0xF000000F, we should skip the first run of ones, then
+ // For values like 0xF000000F, we should ignore the low 6 bits, then
// retry the hunt.
- if (Imm & 1) {
- unsigned TrailingOnes = CountTrailingZeros_32(~Imm);
- if (TrailingOnes != 32) { // Avoid overflow on 0xFFFFFFFF
- // Restart the search for a high-order bit after the initial seconds of
- // ones.
- unsigned TZ2 = CountTrailingZeros_32(Imm & ~((1 << TrailingOnes)-1));
-
- // Rotate amount must be even.
- unsigned RotAmt2 = TZ2 & ~1;
-
- // If this fits, use it.
- if (RotAmt2 != 32 && (rotr32(Imm, RotAmt2) & ~255U) == 0)
- return (32-RotAmt2)&31; // HW rotates right, not left.
- }
+ if (Imm & 63U) {
+ unsigned TZ2 = CountTrailingZeros_32(Imm & ~63U);
+ unsigned RotAmt2 = TZ2 & ~1;
+ if ((rotr32(Imm, RotAmt2) & ~255U) == 0)
+ return (32-RotAmt2)&31; // HW rotates right, not left.
}
// Otherwise, we have no way to cover this span of bits with a single
//
// This is used for NEON load / store instructions.
//
- // addrmode6 := reg with optional writeback and alignment
+ // addrmode6 := reg with optional alignment
//
- // This is stored in four operands [regaddr, regupdate, opc, align]. The
- // first is the address register. The second register holds the value of
- // a post-access increment for writeback or reg0 if no writeback or if the
- // writeback increment is the size of the memory access. The third
- // operand encodes whether there is writeback to the address register. The
- // fourth operand is the value of the alignment specifier to use or zero if
- // no explicit alignment.
-
- static inline unsigned getAM6Opc(bool WB = false) {
- return (int)WB;
- }
-
- static inline bool getAM6WBFlag(unsigned Mode) {
- return Mode & 1;
- }
+ // This is stored in two operands [regaddr, align]. The first is the
+ // address register. The second operand is the value of the alignment
+ // specifier to use or zero if no explicit alignment.
+ // Valid alignments are: 0, 8, 16, and 32 bytes, depending on the specific
+ // instruction.
} // end namespace ARM_AM
} // end namespace llvm