llvm.org GIT mirror llvm / 40829ed
- 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128585 91177308-0d34-0410-b5e6-96231b3b80d8 Bruno Cardoso Lopes 9 years ago
8 changed file(s) with 321 addition(s) and 68 deletion(s). Raw diff Collapse all Expand all
199199 }
200200
201201 namespace ARMII {
202
203 /// ARM Addressing Modes
204 enum AddrMode {
205 AddrModeNone = 0,
206 AddrMode1 = 1,
207 AddrMode2 = 2,
208 AddrMode3 = 3,
209 AddrMode4 = 4,
210 AddrMode5 = 5,
211 AddrMode6 = 6,
212 AddrModeT1_1 = 7,
213 AddrModeT1_2 = 8,
214 AddrModeT1_4 = 9,
215 AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data
216 AddrModeT2_i12 = 11,
217 AddrModeT2_i8 = 12,
218 AddrModeT2_so = 13,
219 AddrModeT2_pc = 14, // +/- i12 for pc relative data
220 AddrModeT2_i8s4 = 15, // i8 * 4
221 AddrMode_i12 = 16
222 };
223
224 inline static const char *AddrModeToString(AddrMode addrmode) {
225 switch (addrmode) {
226 default: llvm_unreachable("Unknown memory operation");
227 case AddrModeNone: return "AddrModeNone";
228 case AddrMode1: return "AddrMode1";
229 case AddrMode2: return "AddrMode2";
230 case AddrMode3: return "AddrMode3";
231 case AddrMode4: return "AddrMode4";
232 case AddrMode5: return "AddrMode5";
233 case AddrMode6: return "AddrMode6";
234 case AddrModeT1_1: return "AddrModeT1_1";
235 case AddrModeT1_2: return "AddrModeT1_2";
236 case AddrModeT1_4: return "AddrModeT1_4";
237 case AddrModeT1_s: return "AddrModeT1_s";
238 case AddrModeT2_i12: return "AddrModeT2_i12";
239 case AddrModeT2_i8: return "AddrModeT2_i8";
240 case AddrModeT2_so: return "AddrModeT2_so";
241 case AddrModeT2_pc: return "AddrModeT2_pc";
242 case AddrModeT2_i8s4: return "AddrModeT2_i8s4";
243 case AddrMode_i12: return "AddrMode_i12";
244 }
245 }
246
202247 /// Target Operand Flag enum.
203248 enum TOF {
204249 //===------------------------------------------------------------------===//
3333
3434 //===------------------------------------------------------------------===//
3535 // This four-bit field describes the addressing mode used.
36
37 AddrModeMask = 0x1f,
38 AddrModeNone = 0,
39 AddrMode1 = 1,
40 AddrMode2 = 2,
41 AddrMode3 = 3,
42 AddrMode4 = 4,
43 AddrMode5 = 5,
44 AddrMode6 = 6,
45 AddrModeT1_1 = 7,
46 AddrModeT1_2 = 8,
47 AddrModeT1_4 = 9,
48 AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data
49 AddrModeT2_i12 = 11,
50 AddrModeT2_i8 = 12,
51 AddrModeT2_so = 13,
52 AddrModeT2_pc = 14, // +/- i12 for pc relative data
53 AddrModeT2_i8s4 = 15, // i8 * 4
54 AddrMode_i12 = 16,
36 AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h
5537
5638 // Size* - Flags to keep track of the size of an instruction.
5739 SizeShift = 5,
514514 : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
515515 pattern> {
516516 // AM2 store w/ two operands: (GPR, am2offset)
517 // {17-14} Rn
517518 // {13} 1 == Rm, 0 == imm12
518519 // {12} isAdd
519520 // {11-0} imm12/Rm
520 bits<14> offset;
521 bits<4> Rn;
522 let Inst{25} = offset{13};
523 let Inst{23} = offset{12};
524 let Inst{19-16} = Rn;
525 let Inst{11-0} = offset{11-0};
521 bits<18> addr;
522 let Inst{25} = addr{13};
523 let Inst{23} = addr{12};
524 let Inst{19-16} = addr{17-14};
525 let Inst{11-0} = addr{11-0};
526526 }
527527
528528 // addrmode3 instructions
497497 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
498498 }
499499
500 def MemMode2AsmOperand : AsmOperandClass {
501 let Name = "MemMode2";
502 let SuperClasses = [];
503 let ParserMethod = "tryParseMemMode2Operand";
504 }
505
500506 // addrmode2 := reg +/- imm12
501507 // := reg +/- reg shop imm
502508 //
504510 ComplexPattern {
505511 let EncoderMethod = "getAddrMode2OpValue";
506512 let PrintMethod = "printAddrMode2Operand";
513 let ParserMatchClass = MemMode2AsmOperand;
507514 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
508515 }
509516
16551662 let Inst{23} = addr{12};
16561663 let Inst{19-16} = addr{17-14};
16571664 let Inst{11-0} = addr{11-0};
1665 let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
16581666 }
16591667 def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
16601668 (ins GPR:$Rn, am2offset:$offset),
17131721
17141722 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
17151723 let mayLoad = 1, neverHasSideEffects = 1 in {
1716 def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
1717 (ins GPR:$base, am2offset:$offset), IndexModePost,
1718 LdFrm, IIC_iLoad_ru,
1719 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1724 def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb),
1725 (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru,
1726 "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
1727 // {17-14} Rn
1728 // {13} 1 == Rm, 0 == imm12
1729 // {12} isAdd
1730 // {11-0} imm12/Rm
1731 bits<18> addr;
1732 let Inst{25} = addr{13};
1733 let Inst{23} = addr{12};
17201734 let Inst{21} = 1; // overwrite
1721 }
1722 def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1723 (ins GPR:$base, am2offset:$offset), IndexModePost,
1724 LdFrm, IIC_iLoad_bh_ru,
1725 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1735 let Inst{19-16} = addr{17-14};
1736 let Inst{11-0} = addr{11-0};
1737 let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
1738 }
1739 def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb),
1740 (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_bh_ru,
1741 "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
1742 // {17-14} Rn
1743 // {13} 1 == Rm, 0 == imm12
1744 // {12} isAdd
1745 // {11-0} imm12/Rm
1746 bits<18> addr;
1747 let Inst{25} = addr{13};
1748 let Inst{23} = addr{12};
17261749 let Inst{21} = 1; // overwrite
1750 let Inst{19-16} = addr{17-14};
1751 let Inst{11-0} = addr{11-0};
1752 let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
17271753 }
17281754 def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
17291755 (ins GPR:$base, am3offset:$offset), IndexModePost,
18171843
18181844 // STRT, STRBT, and STRHT are for disassembly only.
18191845
1820 def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1821 (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
1846 def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr),
18221847 IndexModePost, StFrm, IIC_iStore_ru,
1823 "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1848 "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
18241849 [/* For disassembly only; pattern left blank */]> {
18251850 let Inst{21} = 1; // overwrite
1826 }
1827
1828 def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb),
1829 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1851 let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
1852 }
1853
1854 def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr),
18301855 IndexModePost, StFrm, IIC_iStore_bh_ru,
1831 "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1856 "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
18321857 [/* For disassembly only; pattern left blank */]> {
18331858 let Inst{21} = 1; // overwrite
1859 let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
18341860 }
18351861
18361862 def STRHT: AI3sthpo<(outs GPR:$base_wb),
33903416 let Inst{23-20} = opc1;
33913417 }
33923418
3393 class ACI
3394 : I,
3419 class ACI,
3420 IndexMode im = IndexModeNone>
3421 : I
33953422 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
33963423 let Inst{27-25} = 0b110;
33973424 }
34103437
34113438 def _PRE : ACI<(outs),
34123439 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3413 opc, "\tp$cop, cr$CRd, $addr!"> {
3440 opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> {
34143441 let Inst{31-28} = op31_28;
34153442 let Inst{24} = 1; // P = 1
34163443 let Inst{21} = 1; // W = 1
34513478
34523479 def L_PRE : ACI<(outs),
34533480 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3454 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3481 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> {
34553482 let Inst{31-28} = op31_28;
34563483 let Inst{24} = 1; // P = 1
34573484 let Inst{21} = 1; // W = 1
4747 bool TryParseRegisterWithWriteBack(SmallVectorImpl &);
4848 bool TryParseShiftRegister(SmallVectorImpl &);
4949 bool ParseRegisterList(SmallVectorImpl &);
50 bool ParseMemory(SmallVectorImpl &);
50 bool ParseMemory(SmallVectorImpl &,
51 ARMII::AddrMode AddrMode);
5152 bool ParseOperand(SmallVectorImpl &, StringRef Mnemonic);
5253 bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
5354 const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
9495 SmallVectorImpl&);
9596 OperandMatchResultTy tryParseMSRMaskOperand(
9697 SmallVectorImpl&);
98 OperandMatchResultTy tryParseMemMode2Operand(
99 SmallVectorImpl&);
100
101 // Asm Match Converter Methods
102 bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
103 const SmallVectorImpl &);
104 bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
105 const SmallVectorImpl &);
97106
98107 public:
99108 ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM)
171180
172181 /// Combined record for all forms of ARM address expressions.
173182 struct {
183 ARMII::AddrMode AddrMode;
174184 unsigned BaseRegNum;
175185 union {
176186 unsigned RegNum; ///< Offset register num, when OffsetIsReg.
292302
293303 /// @name Memory Operand Accessors
294304 /// @{
295
305 ARMII::AddrMode getMemAddrMode() const {
306 return Mem.AddrMode;
307 }
296308 unsigned getMemBaseRegNum() const {
297309 return Mem.BaseRegNum;
298310 }
337349 bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
338350 bool isMemory() const { return Kind == Memory; }
339351 bool isShifter() const { return Kind == Shifter; }
352 bool isMemMode2() const {
353 if (getMemAddrMode() != ARMII::AddrMode2)
354 return false;
355
356 if (getMemOffsetIsReg())
357 return true;
358
359 if (getMemNegative() &&
360 !(getMemPostindexed() || getMemPreindexed()))
361 return false;
362
363 const MCConstantExpr *CE = dyn_cast(getMemOffset());
364 if (!CE) return false;
365 int64_t Value = CE->getValue();
366
367 // The offset must be in the range 0-4095 (imm12).
368 if (Value > 4095 || Value < -4095)
369 return false;
370
371 return true;
372 }
340373 bool isMemMode5() const {
341374 if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() ||
342375 getMemNegative())
462495 (void)CE;
463496 assert((CE || CE->getValue() == 0) &&
464497 "No offset operand support in mode 7");
498 }
499
500 void addMemMode2Operands(MCInst &Inst, unsigned N) const {
501 assert(isMemMode2() && "Invalid mode or number of operands!");
502 Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
503
504 if (getMemOffsetIsReg()) {
505 Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
506
507 ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
508 ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift;
509 int64_t ShiftAmount = 0;
510
511 if (getMemOffsetRegShifted()) {
512 ShOpc = getMemShiftType();
513 const MCConstantExpr *CE =
514 dyn_cast(getMemShiftAmount());
515 ShiftAmount = CE->getValue();
516 }
517
518 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount,
519 ShOpc)));
520 return;
521 }
522
523 // Create a operand placeholder to always yield the same number of operands.
524 Inst.addOperand(MCOperand::CreateReg(0));
525
526 // FIXME: #-0 is encoded differently than #0. Does the parser preserve
527 // the difference?
528 const MCConstantExpr *CE = dyn_cast(getMemOffset());
529 assert(CE && "Non-constant mode 2 offset operand!");
530 int64_t Offset = CE->getValue();
531
532 if (Offset >= 0)
533 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add,
534 Offset, ARM_AM::no_shift)));
535 else
536 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub,
537 -Offset, ARM_AM::no_shift)));
465538 }
466539
467540 void addMemMode5Operands(MCInst &Inst, unsigned N) const {
598671 return Op;
599672 }
600673
601 static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg,
602 const MCExpr *Offset, int OffsetRegNum,
603 bool OffsetRegShifted,
674 static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum,
675 bool OffsetIsReg, const MCExpr *Offset,
676 int OffsetRegNum, bool OffsetRegShifted,
604677 enum ARM_AM::ShiftOpc ShiftType,
605678 const MCExpr *ShiftAmount, bool Preindexed,
606679 bool Postindexed, bool Negative, bool Writeback,
617690 "Cannot have expression offset and register offset!");
618691
619692 ARMOperand *Op = new ARMOperand(Memory);
693 Op->Mem.AddrMode = AddrMode;
620694 Op->Mem.BaseRegNum = BaseRegNum;
621695 Op->Mem.OffsetIsReg = OffsetIsReg;
622696 if (OffsetIsReg)
688762 break;
689763 case Memory:
690764 OS << "
691 << "base:" << getMemBaseRegNum();
765 << "am:" << ARMII::AddrModeToString(getMemAddrMode())
766 << " base:" << getMemBaseRegNum();
692767 if (getMemOffsetIsReg()) {
693768 OS << " offset:
694769 if (getMemOffsetRegShifted()) {
11311206 return MatchOperand_Success;
11321207 }
11331208
1209 /// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand.
1210 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1211 tryParseMemMode2Operand(SmallVectorImpl &Operands) {
1212 SMLoc S = Parser.getTok().getLoc();
1213 const AsmToken &Tok = Parser.getTok();
1214 assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\"");
1215
1216 if (ParseMemory(Operands, ARMII::AddrMode2))
1217 return MatchOperand_NoMatch;
1218
1219 return MatchOperand_Success;
1220 }
1221
1222 /// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1223 /// Needed here because the Asm Gen Matcher can't handle properly tied operands
1224 /// when they refer multiple MIOperands inside a single one.
1225 bool ARMAsmParser::
1226 CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1227 const SmallVectorImpl &Operands) {
1228 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1229
1230 // Create a writeback register dummy placeholder.
1231 Inst.addOperand(MCOperand::CreateImm(0));
1232
1233 ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1234 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1235 return true;
1236 }
1237
1238 /// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1239 /// Needed here because the Asm Gen Matcher can't handle properly tied operands
1240 /// when they refer multiple MIOperands inside a single one.
1241 bool ARMAsmParser::
1242 CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1243 const SmallVectorImpl &Operands) {
1244 // Create a writeback register dummy placeholder.
1245 Inst.addOperand(MCOperand::CreateImm(0));
1246 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1247 ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1248 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1249 return true;
1250 }
1251
11341252 /// Parse an ARM memory expression, return false if successful else return true
11351253 /// or an error. The first token must be a '[' when called.
11361254 ///
11371255 /// TODO Only preindexing and postindexing addressing are started, unindexed
11381256 /// with option, etc are still to do.
11391257 bool ARMAsmParser::
1140 ParseMemory(SmallVectorImpl &Operands) {
1258 ParseMemory(SmallVectorImpl &Operands,
1259 ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
11411260 SMLoc S, E;
11421261 assert(Parser.getTok().is(AsmToken::LBrac) &&
11431262 "Token is not a Left Bracket");
12301349 Offset = MCConstantExpr::Create(0, getContext());
12311350 }
12321351
1233 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset,
1234 OffsetRegNum, OffsetRegShifted,
1235 ShiftType, ShiftAmount, Preindexed,
1236 Postindexed, Negative, Writeback,
1237 S, E));
1352 Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg,
1353 Offset, OffsetRegNum, OffsetRegShifted,
1354 ShiftType, ShiftAmount, Preindexed,
1355 Postindexed, Negative, Writeback, S, E));
12381356 if (WBOp)
12391357 Operands.push_back(WBOp);
12401358
1313 #define DEBUG_TYPE "asm-printer"
1414 #include "ARMBaseInfo.h"
1515 #include "ARMInstPrinter.h"
16 #include "ARMInstrInfo.h"
1617 #include "ARMAddressingModes.h"
1718 #include "llvm/MC/MCInst.h"
1819 #include "llvm/MC/MCAsmInfo.h"
180181 }
181182 }
182183
183
184 void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
185 raw_ostream &O) {
184 void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
185 raw_ostream &O) {
186186 const MCOperand &MO1 = MI->getOperand(Op);
187187 const MCOperand &MO2 = MI->getOperand(Op+1);
188188 const MCOperand &MO3 = MI->getOperand(Op+2);
189
190 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
191 printOperand(MI, Op, O);
192 return;
193 }
194189
195190 O << "[" << getRegisterName(MO1.getReg());
196191
212207 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
213208 << " #" << ShImm;
214209 O << "]";
210 }
211
212 void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op,
213 raw_ostream &O) {
214 const MCOperand &MO1 = MI->getOperand(Op);
215 const MCOperand &MO2 = MI->getOperand(Op+1);
216 const MCOperand &MO3 = MI->getOperand(Op+2);
217
218 O << "[" << getRegisterName(MO1.getReg()) << "], ";
219
220 if (!MO2.getReg()) {
221 unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm());
222 O << '#'
223 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
224 << ImmOffs;
225 return;
226 }
227
228 O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
229 << getRegisterName(MO2.getReg());
230
231 if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
232 O << ", "
233 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
234 << " #" << ShImm;
235 }
236
237 void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
238 raw_ostream &O) {
239 const MCOperand &MO1 = MI->getOperand(Op);
240
241 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
242 printOperand(MI, Op, O);
243 return;
244 }
245
246 unsigned Opcode = MI->getOpcode();
247 const TargetInstrDesc &Desc = TM.getInstrInfo()->get(Opcode);
248 uint64_t TSFlags = Desc.TSFlags;
249 unsigned IdxMode = (TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
250
251 if (IdxMode == ARMII::IndexModePost) {
252 printAM2PostIndexOp(MI, Op, O);
253 return;
254 }
255 printAM2PreOrOffsetIndexOp(MI, Op, O);
215256 }
216257
217258 void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
2121 class TargetMachine;
2222
2323 class ARMInstPrinter : public MCInstPrinter {
24 private:
25 TargetMachine &TM;
2426 public:
25 ARMInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI)
26 : MCInstPrinter(MAI) {}
27 ARMInstPrinter(TargetMachine &_TM, const MCAsmInfo &MAI)
28 : MCInstPrinter(MAI), TM(_TM) {}
2729
2830 virtual void printInst(const MCInst *MI, raw_ostream &O);
2931 virtual StringRef getOpcodeName(unsigned Opcode) const;
4143 void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
4244
4345 void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
46
4447 void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
48 void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O);
49 void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum,
50 raw_ostream &O);
4551 void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum,
4652 raw_ostream &O);
4753 void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
0 @ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding %s | FileCheck %s
1
2 @ Post-indexed
3 @ CHECK: ldrt r1, [r0], r2 @ encoding: [0x02,0x10,0xb0,0xe6]
4 @ CHECK: ldrt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xb0,0xe6]
5 @ CHECK: ldrt r1, [r0], #4 @ encoding: [0x04,0x10,0xb0,0xe4]
6 @ CHECK: ldrbt r1, [r0], r2 @ encoding: [0x02,0x10,0xf0,0xe6]
7 @ CHECK: ldrbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xf0,0xe6]
8 @ CHECK: ldrbt r1, [r0], #4 @ encoding: [0x04,0x10,0xf0,0xe4]
9 @ CHECK: strt r1, [r0], r2 @ encoding: [0x02,0x10,0xa0,0xe6]
10 @ CHECK: strt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xa0,0xe6]
11 @ CHECK: strt r1, [r0], #4 @ encoding: [0x04,0x10,0xa0,0xe4]
12 @ CHECK: strbt r1, [r0], r2 @ encoding: [0x02,0x10,0xe0,0xe6]
13 @ CHECK: strbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xe0,0xe6]
14 @ CHECK: strbt r1, [r0], #4 @ encoding: [0x04,0x10,0xe0,0xe4]
15 ldrt r1, [r0], r2
16 ldrt r1, [r0], r2, lsr #3
17 ldrt r1, [r0], #4
18 ldrbt r1, [r0], r2
19 ldrbt r1, [r0], r2, lsr #3
20 ldrbt r1, [r0], #4
21 strt r1, [r0], r2
22 strt r1, [r0], r2, lsr #3
23 strt r1, [r0], #4
24 strbt r1, [r0], r2
25 strbt r1, [r0], r2, lsr #3
26 strbt r1, [r0], #4
27
28 @ Pre-indexed
29 @ CHECK: ldr r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xb0,0xe7]
30 @ CHECK: ldrb r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xf0,0xe7]
31 ldr r1, [r0, r2, lsr #3]!
32 ldrb r1, [r0, r2, lsr #3]!
33