[llvm-commits] [llvm] r128585 - in /llvm/trunk: lib/Target/ARM/ARMBaseInfo.h lib/Target/ARM/ARMBaseInstrInfo.h lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp lib/Target/ARM/InstPrinter/A

Nick Lewycky nlewycky at google.com
Wed Mar 30 17:38:29 PDT 2011


On 30 March 2011 16:32, Bruno Cardoso Lopes <bruno.cardoso at gmail.com> wrote:

> Author: bruno
> Date: Wed Mar 30 18:32:32 2011
> New Revision: 128585
>
> URL: http://llvm.org/viewvc/llvm-project?rev=128585&view=rev
> Log:
> - Implement asm parsing support for LDRT, LDRBT, STRT, STRBT and
>  {STR,LDC}{2}_PRE.
> - Fixed the encoding in some places.
> - Some of those instructions were using am2offset and now use addrmode2.
> Codegen isn't affected, instructions which use SelectAddrMode2Offset were
> not
> touched.
> - Teach printAddrMode2Operand to check by the addressing mode which index
> mode to print.
> - This is a work in progress, more work to come. The idea is to change
> places
> which use am2offset to use addrmode2 instead, as to unify assembly parser.
> - Add testcases for assembly parser
>
> Added:
>    llvm/trunk/test/MC/ARM/arm_addrmode2.s
> Modified:
>    llvm/trunk/lib/Target/ARM/ARMBaseInfo.h
>    llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h
>    llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
>    llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
>    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
>    llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
>    llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
>
> Modified: llvm/trunk/lib/Target/ARM/ARMBaseInfo.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInfo.h?rev=128585&r1=128584&r2=128585&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMBaseInfo.h (original)
> +++ llvm/trunk/lib/Target/ARM/ARMBaseInfo.h Wed Mar 30 18:32:32 2011
> @@ -200,6 +200,51 @@
>  }
>
>  namespace ARMII {
> +
> +  /// ARM Addressing Modes
> +  enum AddrMode {
> +    AddrModeNone    = 0,
> +    AddrMode1       = 1,
> +    AddrMode2       = 2,
> +    AddrMode3       = 3,
> +    AddrMode4       = 4,
> +    AddrMode5       = 5,
> +    AddrMode6       = 6,
> +    AddrModeT1_1    = 7,
> +    AddrModeT1_2    = 8,
> +    AddrModeT1_4    = 9,
> +    AddrModeT1_s    = 10, // i8 * 4 for pc and sp relative data
> +    AddrModeT2_i12  = 11,
> +    AddrModeT2_i8   = 12,
> +    AddrModeT2_so   = 13,
> +    AddrModeT2_pc   = 14, // +/- i12 for pc relative data
> +    AddrModeT2_i8s4 = 15, // i8 * 4
> +    AddrMode_i12    = 16
> +  };
> +
> +  inline static const char *AddrModeToString(AddrMode addrmode) {
> +    switch (addrmode) {
> +    default: llvm_unreachable("Unknown memory operation");
> +    case AddrModeNone:    return "AddrModeNone";
> +    case AddrMode1:       return "AddrMode1";
> +    case AddrMode2:       return "AddrMode2";
> +    case AddrMode3:       return "AddrMode3";
> +    case AddrMode4:       return "AddrMode4";
> +    case AddrMode5:       return "AddrMode5";
> +    case AddrMode6:       return "AddrMode6";
> +    case AddrModeT1_1:    return "AddrModeT1_1";
> +    case AddrModeT1_2:    return "AddrModeT1_2";
> +    case AddrModeT1_4:    return "AddrModeT1_4";
> +    case AddrModeT1_s:    return "AddrModeT1_s";
> +    case AddrModeT2_i12:  return "AddrModeT2_i12";
> +    case AddrModeT2_i8:   return "AddrModeT2_i8";
> +    case AddrModeT2_so:   return "AddrModeT2_so";
> +    case AddrModeT2_pc:   return "AddrModeT2_pc";
> +    case AddrModeT2_i8s4: return "AddrModeT2_i8s4";
> +    case AddrMode_i12:    return "AddrMode_i12";
> +    }
> +  }
> +
>   /// Target Operand Flag enum.
>   enum TOF {
>
> //===------------------------------------------------------------------===//
>
> Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=128585&r1=128584&r2=128585&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original)
> +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Wed Mar 30 18:32:32 2011
> @@ -34,25 +34,7 @@
>
>
> //===------------------------------------------------------------------===//
>     // This four-bit field describes the addressing mode used.
> -
> -    AddrModeMask  = 0x1f,
> -    AddrModeNone    = 0,
> -    AddrMode1       = 1,
> -    AddrMode2       = 2,
> -    AddrMode3       = 3,
> -    AddrMode4       = 4,
> -    AddrMode5       = 5,
> -    AddrMode6       = 6,
> -    AddrModeT1_1    = 7,
> -    AddrModeT1_2    = 8,
> -    AddrModeT1_4    = 9,
> -    AddrModeT1_s    = 10, // i8 * 4 for pc and sp relative data
> -    AddrModeT2_i12  = 11,
> -    AddrModeT2_i8   = 12,
> -    AddrModeT2_so   = 13,
> -    AddrModeT2_pc   = 14, // +/- i12 for pc relative data
> -    AddrModeT2_i8s4 = 15, // i8 * 4
> -    AddrMode_i12    = 16,
> +    AddrModeMask  = 0x1f, // The AddrMode enums are declared in
> ARMBaseInfo.h
>
>     // Size* - Flags to keep track of the size of an instruction.
>     SizeShift     = 5,
>
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=128585&r1=128584&r2=128585&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Wed Mar 30 18:32:32 2011
> @@ -515,15 +515,15 @@
>   : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
>                pattern> {
>   // AM2 store w/ two operands: (GPR, am2offset)
> +  // {17-14}  Rn
>   // {13}     1 == Rm, 0 == imm12
>   // {12}     isAdd
>   // {11-0}   imm12/Rm
> -  bits<14> offset;
> -  bits<4> Rn;
> -  let Inst{25} = offset{13};
> -  let Inst{23} = offset{12};
> -  let Inst{19-16} = Rn;
> -  let Inst{11-0} = offset{11-0};
> +  bits<18> addr;
> +  let Inst{25} = addr{13};
> +  let Inst{23} = addr{12};
> +  let Inst{19-16} = addr{17-14};
> +  let Inst{11-0} = addr{11-0};
>  }
>
>  // addrmode3 instructions
>
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128585&r1=128584&r2=128585&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Wed Mar 30 18:32:32 2011
> @@ -498,6 +498,12 @@
>   let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
>  }
>
> +def MemMode2AsmOperand : AsmOperandClass {
> +  let Name = "MemMode2";
> +  let SuperClasses = [];
> +  let ParserMethod = "tryParseMemMode2Operand";
> +}
> +
>  // addrmode2 := reg +/- imm12
>  //           := reg +/- reg shop imm
>  //
> @@ -505,6 +511,7 @@
>                 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
>   let EncoderMethod = "getAddrMode2OpValue";
>   let PrintMethod = "printAddrMode2Operand";
> +  let ParserMatchClass = MemMode2AsmOperand;
>   let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
>  }
>
> @@ -1656,6 +1663,7 @@
>     let Inst{23} = addr{12};
>     let Inst{19-16} = addr{17-14};
>     let Inst{11-0} = addr{11-0};
> +    let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
>   }
>   def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
>                       (ins GPR:$Rn, am2offset:$offset),
> @@ -1714,17 +1722,35 @@
>
>  // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
>  let mayLoad = 1, neverHasSideEffects = 1 in {
> -def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
> -                   (ins GPR:$base, am2offset:$offset), IndexModePost,
> -                   LdFrm, IIC_iLoad_ru,
> -                   "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb",
> []> {
> +def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb),
> +                   (ins addrmode2:$addr), IndexModePost, LdFrm,
> IIC_iLoad_ru,
> +                   "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
> +  // {17-14}  Rn
> +  // {13}     1 == Rm, 0 == imm12
> +  // {12}     isAdd
> +  // {11-0}   imm12/Rm
> +  bits<18> addr;
> +  let Inst{25} = addr{13};
> +  let Inst{23} = addr{12};
>   let Inst{21} = 1; // overwrite
> -}
> -def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
> -                  (ins GPR:$base, am2offset:$offset), IndexModePost,
> -                  LdFrm, IIC_iLoad_bh_ru,
> -                  "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb",
> []> {
> +  let Inst{19-16} = addr{17-14};
> +  let Inst{11-0} = addr{11-0};
> +  let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
> +}
> +def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb),
> +                  (ins addrmode2:$addr), IndexModePost, LdFrm,
> IIC_iLoad_bh_ru,
> +                  "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
> +  // {17-14}  Rn
> +  // {13}     1 == Rm, 0 == imm12
> +  // {12}     isAdd
> +  // {11-0}   imm12/Rm
> +  bits<18> addr;
> +  let Inst{25} = addr{13};
> +  let Inst{23} = addr{12};
>   let Inst{21} = 1; // overwrite
> +  let Inst{19-16} = addr{17-14};
> +  let Inst{11-0} = addr{11-0};
> +  let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
>  }
>  def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
>                  (ins GPR:$base, am3offset:$offset), IndexModePost,
> @@ -1818,20 +1844,20 @@
>
>  // STRT, STRBT, and STRHT are for disassembly only.
>
> -def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb),
> -                    (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
> +def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt,
> addrmode2:$addr),
>                     IndexModePost, StFrm, IIC_iStore_ru,
> -                    "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
> +                    "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
>                     [/* For disassembly only; pattern left blank */]> {
>   let Inst{21} = 1; // overwrite
> +  let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
>  }
>
> -def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb),
> -                     (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
> +def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt,
> addrmode2:$addr),
>                      IndexModePost, StFrm, IIC_iStore_bh_ru,
> -                     "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
> +                     "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
>                      [/* For disassembly only; pattern left blank */]> {
>   let Inst{21} = 1; // overwrite
> +  let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
>  }
>
>  def STRHT: AI3sthpo<(outs GPR:$base_wb),
> @@ -3391,8 +3417,9 @@
>   let Inst{23-20} = opc1;
>  }
>
> -class ACI<dag oops, dag iops, string opc, string asm>
> -  : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm,
> NoItinerary,
> +class ACI<dag oops, dag iops, string opc, string asm,
> +          IndexMode im = IndexModeNone>
> +  : I<oops, iops, AddrModeNone, Size4Bytes, im, BrFrm, NoItinerary,
>       opc, asm, "", [/* For disassembly only; pattern left blank */]> {
>   let Inst{27-25} = 0b110;
>  }
> @@ -3411,7 +3438,7 @@
>
>   def _PRE : ACI<(outs),
>       (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
> -      opc, "\tp$cop, cr$CRd, $addr!"> {
> +      opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> {
>     let Inst{31-28} = op31_28;
>     let Inst{24} = 1; // P = 1
>     let Inst{21} = 1; // W = 1
> @@ -3452,7 +3479,7 @@
>
>   def L_PRE : ACI<(outs),
>       (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
> -      !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
> +      !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> {
>     let Inst{31-28} = op31_28;
>     let Inst{24} = 1; // P = 1
>     let Inst{21} = 1; // W = 1
>
> Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=128585&r1=128584&r2=128585&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Wed Mar 30
> 18:32:32 2011
> @@ -48,7 +48,8 @@
>   bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*>
> &);
>   bool TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
>   bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
> -  bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
> +  bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &,
> +                   ARMII::AddrMode AddrMode);
>   bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef
> Mnemonic);
>   bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
>   const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
> @@ -95,6 +96,14 @@
>     SmallVectorImpl<MCParsedAsmOperand*>&);
>   OperandMatchResultTy tryParseMSRMaskOperand(
>     SmallVectorImpl<MCParsedAsmOperand*>&);
> +  OperandMatchResultTy tryParseMemMode2Operand(
> +    SmallVectorImpl<MCParsedAsmOperand*>&);
> +
> +  // Asm Match Converter Methods
> +  bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
> +                                  const
> SmallVectorImpl<MCParsedAsmOperand*> &);
> +  bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
> +                                  const
> SmallVectorImpl<MCParsedAsmOperand*> &);
>
>  public:
>   ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM)
> @@ -172,6 +181,7 @@
>
>     /// Combined record for all forms of ARM address expressions.
>     struct {
> +      ARMII::AddrMode AddrMode;
>       unsigned BaseRegNum;
>       union {
>         unsigned RegNum;     ///< Offset register num, when OffsetIsReg.
> @@ -293,7 +303,9 @@
>
>   /// @name Memory Operand Accessors
>   /// @{
> -
> +  ARMII::AddrMode getMemAddrMode() const {
> +    return Mem.AddrMode;
> +  }
>   unsigned getMemBaseRegNum() const {
>     return Mem.BaseRegNum;
>   }
> @@ -338,6 +350,27 @@
>   bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
>   bool isMemory() const { return Kind == Memory; }
>   bool isShifter() const { return Kind == Shifter; }
> +  bool isMemMode2() const {
> +    if (getMemAddrMode() != ARMII::AddrMode2)
> +      return false;
> +
> +    if (getMemOffsetIsReg())
> +      return true;
> +
> +    if (getMemNegative() &&
> +        !(getMemPostindexed() || getMemPreindexed()))
> +      return false;
> +
> +    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
> +    if (!CE) return false;
> +    int64_t Value = CE->getValue();
> +
> +    // The offset must be in the range 0-4095 (imm12).
> +    if (Value > 4095 || Value < -4095)
> +      return false;
> +
> +    return true;
> +  }
>   bool isMemMode5() const {
>     if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() ||
>         getMemNegative())
> @@ -465,6 +498,46 @@
>            "No offset operand support in mode 7");
>   }
>
> +  void addMemMode2Operands(MCInst &Inst, unsigned N) const {
> +    assert(isMemMode2() && "Invalid mode or number of operands!");
> +    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
> +
> +    if (getMemOffsetIsReg()) {
> +      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
> +
> +      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub :
> ARM_AM::add;
> +      ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift;
> +      int64_t ShiftAmount = 0;
> +
> +      if (getMemOffsetRegShifted()) {
> +        ShOpc = getMemShiftType();
> +        const MCConstantExpr *CE =
> +                   dyn_cast<MCConstantExpr>(getMemShiftAmount());
> +        ShiftAmount = CE->getValue();
> +      }
> +
> +      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc,
> ShiftAmount,
> +                                           ShOpc)));
> +      return;
> +    }
> +
> +    // Create a operand placeholder to always yield the same number of
> operands.
> +    Inst.addOperand(MCOperand::CreateReg(0));
> +
> +    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
> +    // the difference?
> +    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
> +    assert(CE && "Non-constant mode 2 offset operand!");
> +    int64_t Offset = CE->getValue();
> +
> +    if (Offset >= 0)
> +      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add,
> +                                           Offset, ARM_AM::no_shift)));
> +    else
> +      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub,
> +                                           -Offset, ARM_AM::no_shift)));
> +  }
> +
>   void addMemMode5Operands(MCInst &Inst, unsigned N) const {
>     assert(N == 2 && isMemMode5() && "Invalid number of operands!");
>
> @@ -599,9 +672,9 @@
>     return Op;
>   }
>
> -  static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg,
> -                               const MCExpr *Offset, int OffsetRegNum,
> -                               bool OffsetRegShifted,
> +  static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned
> BaseRegNum,
> +                               bool OffsetIsReg, const MCExpr *Offset,
> +                               int OffsetRegNum, bool OffsetRegShifted,
>                                enum ARM_AM::ShiftOpc ShiftType,
>                                const MCExpr *ShiftAmount, bool Preindexed,
>                                bool Postindexed, bool Negative, bool
> Writeback,
> @@ -618,6 +691,7 @@
>            "Cannot have expression offset and register offset!");
>
>     ARMOperand *Op = new ARMOperand(Memory);
> +    Op->Mem.AddrMode = AddrMode;
>     Op->Mem.BaseRegNum = BaseRegNum;
>     Op->Mem.OffsetIsReg = OffsetIsReg;
>     if (OffsetIsReg)
> @@ -689,7 +763,8 @@
>     break;
>   case Memory:
>     OS << "<memory "
> -       << "base:" << getMemBaseRegNum();
> +       << "am:" << ARMII::AddrModeToString(getMemAddrMode())
> +       << " base:" << getMemBaseRegNum();
>     if (getMemOffsetIsReg()) {
>       OS << " offset:<register " << getMemOffsetRegNum();
>       if (getMemOffsetRegShifted()) {
> @@ -1132,13 +1207,57 @@
>   return MatchOperand_Success;
>  }
>
> +/// tryParseMemMode2Operand - Try to parse memory addressing mode 2
> operand.
> +ARMAsmParser::OperandMatchResultTy ARMAsmParser::
> +tryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
> +  SMLoc S = Parser.getTok().getLoc();
> +  const AsmToken &Tok = Parser.getTok();
> +  assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\"");
> +
> +  if (ParseMemory(Operands, ARMII::AddrMode2))
> +    return MatchOperand_NoMatch;
> +
> +  return MatchOperand_Success;
> +}
> +
> +/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
> +/// Needed here because the Asm Gen Matcher can't handle properly tied
> operands
> +/// when they refer multiple MIOperands inside a single one.
> +bool ARMAsmParser::
> +CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
> +                         const SmallVectorImpl<MCParsedAsmOperand*>
> &Operands) {
> +  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
> +
> +  // Create a writeback register dummy placeholder.
> +  Inst.addOperand(MCOperand::CreateImm(0));
> +
> +  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
> +  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
> +  return true;
> +}
> +
> +/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
> +/// Needed here because the Asm Gen Matcher can't handle properly tied
> operands
> +/// when they refer multiple MIOperands inside a single one.
> +bool ARMAsmParser::
> +CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
> +                         const SmallVectorImpl<MCParsedAsmOperand*>
> &Operands) {
> +  // Create a writeback register dummy placeholder.
> +  Inst.addOperand(MCOperand::CreateImm(0));
> +  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
> +  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
> +  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
> +  return true;
> +}
> +
>  /// Parse an ARM memory expression, return false if successful else return
> true
>  /// or an error.  The first token must be a '[' when called.
>  ///
>  /// TODO Only preindexing and postindexing addressing are started,
> unindexed
>  /// with option, etc are still to do.
>  bool ARMAsmParser::
> -ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
> +ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
> +            ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
>   SMLoc S, E;
>   assert(Parser.getTok().is(AsmToken::LBrac) &&
>          "Token is not a Left Bracket");
> @@ -1231,11 +1350,10 @@
>       Offset = MCConstantExpr::Create(0, getContext());
>   }
>
> -  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg,
> Offset,
> -                                           OffsetRegNum, OffsetRegShifted,
> -                                           ShiftType, ShiftAmount,
> Preindexed,
> -                                           Postindexed, Negative,
> Writeback,
> -                                           S, E));
> +  Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum,
> OffsetIsReg,
> +                                     Offset, OffsetRegNum,
> OffsetRegShifted,
> +                                     ShiftType, ShiftAmount, Preindexed,
> +                                     Postindexed, Negative, Writeback, S,
> E));
>   if (WBOp)
>     Operands.push_back(WBOp);
>
>
> Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=128585&r1=128584&r2=128585&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Wed Mar 30
> 18:32:32 2011
> @@ -14,6 +14,7 @@
>  #define DEBUG_TYPE "asm-printer"
>  #include "ARMBaseInfo.h"
>  #include "ARMInstPrinter.h"
> +#include "ARMInstrInfo.h"
>

No, you can not do this. This will transitively
#include ARMGenRegisterInfo.h.inc which declares "extern QQQQPRClass
QQQQPRRegClass;". That causes ARMInstPrinter to have a dependency on
ARMCodeGen, causing a cycle.

We'll probably revert this patch shortly. Please re-commit once you fix
this!

Nick


>  #include "ARMAddressingModes.h"
>  #include "llvm/MC/MCInst.h"
>  #include "llvm/MC/MCAsmInfo.h"
> @@ -181,18 +182,12 @@
>   }
>  }
>
> -
> -void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
> -                                           raw_ostream &O) {
> +void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned
> Op,
> +                                                raw_ostream &O) {
>   const MCOperand &MO1 = MI->getOperand(Op);
>   const MCOperand &MO2 = MI->getOperand(Op+1);
>   const MCOperand &MO3 = MI->getOperand(Op+2);
>
> -  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
> -    printOperand(MI, Op, O);
> -    return;
> -  }
> -
>   O << "[" << getRegisterName(MO1.getReg());
>
>   if (!MO2.getReg()) {
> @@ -215,6 +210,52 @@
>   O << "]";
>  }
>
> +void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op,
> +                                         raw_ostream &O) {
> +  const MCOperand &MO1 = MI->getOperand(Op);
> +  const MCOperand &MO2 = MI->getOperand(Op+1);
> +  const MCOperand &MO3 = MI->getOperand(Op+2);
> +
> +  O << "[" << getRegisterName(MO1.getReg()) << "], ";
> +
> +  if (!MO2.getReg()) {
> +    unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm());
> +    O << '#'
> +      << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
> +      << ImmOffs;
> +    return;
> +  }
> +
> +  O << 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;
> +}
> +
> +void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
> +                                           raw_ostream &O) {
> +  const MCOperand &MO1 = MI->getOperand(Op);
> +
> +  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
> +    printOperand(MI, Op, O);
> +    return;
> +  }
> +
> +  unsigned Opcode = MI->getOpcode();
> +  const TargetInstrDesc &Desc = TM.getInstrInfo()->get(Opcode);
> +  uint64_t TSFlags = Desc.TSFlags;
> +  unsigned IdxMode = (TSFlags & ARMII::IndexModeMask) >>
> ARMII::IndexModeShift;
> +
> +  if (IdxMode == ARMII::IndexModePost) {
> +    printAM2PostIndexOp(MI, Op, O);
> +    return;
> +  }
> +  printAM2PreOrOffsetIndexOp(MI, Op, O);
> +}
> +
>  void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
>                                                  unsigned OpNum,
>                                                  raw_ostream &O) {
>
> Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h?rev=128585&r1=128584&r2=128585&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h (original)
> +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Wed Mar 30
> 18:32:32 2011
> @@ -22,9 +22,11 @@
>  class TargetMachine;
>
>  class ARMInstPrinter : public MCInstPrinter {
> +private:
> +  TargetMachine &TM;
>  public:
> -  ARMInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI)
> -    : MCInstPrinter(MAI) {}
> +  ARMInstPrinter(TargetMachine &_TM, const MCAsmInfo &MAI)
> +    : MCInstPrinter(MAI), TM(_TM) {}
>
>   virtual void printInst(const MCInst *MI, raw_ostream &O);
>   virtual StringRef getOpcodeName(unsigned Opcode) const;
> @@ -42,7 +44,11 @@
>   void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
>
>   void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
> +
>   void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream
> &O);
> +  void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream
> &O);
> +  void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum,
> +                                  raw_ostream &O);
>   void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum,
>                                    raw_ostream &O);
>   void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream
> &O);
>
> Added: llvm/trunk/test/MC/ARM/arm_addrmode2.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_addrmode2.s?rev=128585&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/ARM/arm_addrmode2.s (added)
> +++ llvm/trunk/test/MC/ARM/arm_addrmode2.s Wed Mar 30 18:32:32 2011
> @@ -0,0 +1,34 @@
> +@ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding
> %s | FileCheck %s
> +
> +@ Post-indexed
> +@ CHECK: ldrt  r1, [r0], r2 @ encoding: [0x02,0x10,0xb0,0xe6]
> +@ CHECK: ldrt  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xb0,0xe6]
> +@ CHECK: ldrt  r1, [r0], #4 @ encoding: [0x04,0x10,0xb0,0xe4]
> +@ CHECK: ldrbt  r1, [r0], r2 @ encoding: [0x02,0x10,0xf0,0xe6]
> +@ CHECK: ldrbt  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xf0,0xe6]
> +@ CHECK: ldrbt  r1, [r0], #4 @ encoding: [0x04,0x10,0xf0,0xe4]
> +@ CHECK: strt  r1, [r0], r2 @ encoding: [0x02,0x10,0xa0,0xe6]
> +@ CHECK: strt  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xa0,0xe6]
> +@ CHECK: strt  r1, [r0], #4 @ encoding: [0x04,0x10,0xa0,0xe4]
> +@ CHECK: strbt  r1, [r0], r2 @ encoding: [0x02,0x10,0xe0,0xe6]
> +@ CHECK: strbt  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xe0,0xe6]
> +@ CHECK: strbt  r1, [r0], #4 @ encoding: [0x04,0x10,0xe0,0xe4]
> +        ldrt  r1, [r0], r2
> +        ldrt  r1, [r0], r2, lsr #3
> +        ldrt  r1, [r0], #4
> +        ldrbt  r1, [r0], r2
> +        ldrbt  r1, [r0], r2, lsr #3
> +        ldrbt  r1, [r0], #4
> +        strt  r1, [r0], r2
> +        strt  r1, [r0], r2, lsr #3
> +        strt  r1, [r0], #4
> +        strbt  r1, [r0], r2
> +        strbt  r1, [r0], r2, lsr #3
> +        strbt  r1, [r0], #4
> +
> +@ Pre-indexed
> +@ CHECK: ldr  r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xb0,0xe7]
> +@ CHECK: ldrb  r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xf0,0xe7]
> +        ldr  r1, [r0, r2, lsr #3]!
> +        ldrb  r1, [r0, r2, lsr #3]!
> +
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20110330/832248a2/attachment.html>


More information about the llvm-commits mailing list