diff options
Diffstat (limited to 'llvm/lib/Target/ARM')
4 files changed, 35 insertions, 8 deletions
| diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 3e68a0b865a..bc711dc35f0 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -4444,6 +4444,12 @@ bool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,          ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||          ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))        return Error(Loc, "immediate shift value out of range"); +    // If <ShiftTy> #0, turn it into a no_shift. +    if (Imm == 0) +      St = ARM_AM::lsl; +    // For consistency, treat lsr #32 and asr #32 as having immediate value 0. +    if (Imm == 32) +      Imm = 0;      Amount = Imm;    } diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 57642e1924e..bf0dabb4a0f 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -1523,6 +1523,8 @@ DecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn,          return MCDisassembler::Fail;      }      unsigned amt = fieldFromInstruction(Insn, 7, 5); +    if (Opc == ARM_AM::ror && amt == 0) +      Opc = ARM_AM::rrx;      unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode);      Inst.addOperand(MCOperand::CreateImm(imm)); @@ -1564,6 +1566,9 @@ static DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Val,        break;    } +  if (ShOp == ARM_AM::ror && imm == 0) +    ShOp = ARM_AM::rrx; +    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))      return MCDisassembler::Fail;    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) diff --git a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index 8b9109ec986..60f92f82d40 100644 --- a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -29,11 +29,27 @@ using namespace llvm;  ///  /// getSORegOffset returns an integer from 0-31, representing '32' as 0.  static unsigned translateShiftImm(unsigned imm) { +  // lsr #32 and asr #32 exist, but should be encoded as a 0. +  assert((imm & ~0x1f) == 0 && "Invalid shift encoding"); +    if (imm == 0)      return 32;    return imm;  } +/// Prints the shift value with an immediate value. +static void printRegImmShift(raw_ostream &O, ARM_AM::ShiftOpc ShOpc, +                          unsigned ShImm) { +  if (ShOpc == ARM_AM::no_shift || (ShOpc == ARM_AM::lsl && !ShImm)) +    return; +  O << ", "; + +  assert (!(ShOpc == ARM_AM::ror && !ShImm) && "Cannot have ror #0"); +  O << getShiftOpcStr(ShOpc); + +  if (ShOpc != ARM_AM::rrx) +    O << " #" << translateShiftImm(ShImm); +}  ARMInstPrinter::ARMInstPrinter(const MCAsmInfo &MAI,                                 const MCInstrInfo &MII, @@ -319,10 +335,8 @@ void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,      << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))      << getRegisterName(MO2.getReg()); -  if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) -    O << ", " -    << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) -    << " #" << ShImm; +  printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO3.getImm()), +                   ARM_AM::getAM2Offset(MO3.getImm()));    O << "]";  } @@ -403,10 +417,8 @@ void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,    O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))      << getRegisterName(MO1.getReg()); -  if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm())) -    O << ", " -    << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm())) -    << " #" << ShImm; +  printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO2.getImm()), +                   ARM_AM::getAM2Offset(MO2.getImm()));  }  //===--------------------------------------------------------------------===// diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index dde72853540..d0e127a8f33 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp @@ -934,6 +934,10 @@ getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,    ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());    unsigned SBits = getShiftOp(ShOp); +  // While "lsr #32" and "asr #32" exist, they are encoded with a 0 in the shift +  // amount. However, it would be an easy mistake to make so check here. +  assert((ShImm & ~0x1f) == 0 && "Out of range shift amount"); +    // {16-13} = Rn    // {12}    = isAdd    // {11-0}  = shifter | 

