llvm.org GIT mirror llvm / ae08554
Apply again changes to support ARM memory asm parsing. I removed all LDR/STR changes and left them to a future patch. Passing all checks now. - Implement asm parsing support for LDRT, LDRBT, STRT, STRBT and fix the encoding wherever is possible. - Add a new encoding bit to describe the index mode used and teach printAddrMode2Operand to check by the addressing mode which index mode to print. - Testcases git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128689 91177308-0d34-0410-b5e6-96231b3b80d8 Bruno Cardoso Lopes 9 years ago
10 changed file(s) with 365 addition(s) and 78 deletion(s). Raw diff Collapse all Expand all
407407 //
408408 // The first operand is always a Reg. The second operand is a reg if in
409409 // reg/reg form, otherwise it's reg#0. The third field encodes the operation
410 // in bit 12, the immediate in bits 0-11, and the shift op in 13-15.
410 // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The
411 // forth operand 16-17 encodes the index mode.
411412 //
412413 // If this addressing mode is a frame index (before prolog/epilog insertion
413414 // and code rewriting), this operand will have the form: FI#, reg0,
414415 // with no shift amount for the frame offset.
415416 //
416 static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO) {
417 static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO,
418 unsigned IdxMode = 0) {
417419 assert(Imm12 < (1 << 12) && "Imm too large!");
418420 bool isSub = Opc == sub;
419 return Imm12 | ((int)isSub << 12) | (SO << 13);
421 return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ;
420422 }
421423 static inline unsigned getAM2Offset(unsigned AM2Opc) {
422424 return AM2Opc & ((1 << 12)-1);
425427 return ((AM2Opc >> 12) & 1) ? sub : add;
426428 }
427429 static inline ShiftOpc getAM2ShiftOpc(unsigned AM2Opc) {
428 return (ShiftOpc)(AM2Opc >> 13);
430 return (ShiftOpc)((AM2Opc >> 13) & 7);
431 }
432 static inline unsigned getAM2IdxMode(unsigned AM2Opc) {
433 return (AM2Opc >> 16);
429434 }
430435
431436
199199 }
200200
201201 namespace ARMII {
202
203 /// ARM Index Modes
204 enum IndexMode {
205 IndexModeNone = 0,
206 IndexModePre = 1,
207 IndexModePost = 2,
208 IndexModeUpd = 3
209 };
210
211 /// ARM Addressing Modes
212 enum AddrMode {
213 AddrModeNone = 0,
214 AddrMode1 = 1,
215 AddrMode2 = 2,
216 AddrMode3 = 3,
217 AddrMode4 = 4,
218 AddrMode5 = 5,
219 AddrMode6 = 6,
220 AddrModeT1_1 = 7,
221 AddrModeT1_2 = 8,
222 AddrModeT1_4 = 9,
223 AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data
224 AddrModeT2_i12 = 11,
225 AddrModeT2_i8 = 12,
226 AddrModeT2_so = 13,
227 AddrModeT2_pc = 14, // +/- i12 for pc relative data
228 AddrModeT2_i8s4 = 15, // i8 * 4
229 AddrMode_i12 = 16
230 };
231
232 inline static const char *AddrModeToString(AddrMode addrmode) {
233 switch (addrmode) {
234 default: llvm_unreachable("Unknown memory operation");
235 case AddrModeNone: return "AddrModeNone";
236 case AddrMode1: return "AddrMode1";
237 case AddrMode2: return "AddrMode2";
238 case AddrMode3: return "AddrMode3";
239 case AddrMode4: return "AddrMode4";
240 case AddrMode5: return "AddrMode5";
241 case AddrMode6: return "AddrMode6";
242 case AddrModeT1_1: return "AddrModeT1_1";
243 case AddrModeT1_2: return "AddrModeT1_2";
244 case AddrModeT1_4: return "AddrModeT1_4";
245 case AddrModeT1_s: return "AddrModeT1_s";
246 case AddrModeT2_i12: return "AddrModeT2_i12";
247 case AddrModeT2_i8: return "AddrModeT2_i8";
248 case AddrModeT2_so: return "AddrModeT2_so";
249 case AddrModeT2_pc: return "AddrModeT2_pc";
250 case AddrModeT2_i8s4: return "AddrModeT2_i8s4";
251 case AddrMode_i12: return "AddrMode_i12";
252 }
253 }
254
202255 /// Target Operand Flag enum.
203256 enum TOF {
204257 //===------------------------------------------------------------------===//
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,
6345
6446 // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
6547 // and store ops only. Generic "updating" flag is used for ld/st multiple.
48 // The index mode enums are declared in ARMBaseInfo.h
6649 IndexModeShift = 8,
6750 IndexModeMask = 3 << IndexModeShift,
68 IndexModePre = 1,
69 IndexModePost = 2,
70 IndexModeUpd = 3,
7151
7252 //===------------------------------------------------------------------===//
7353 // Instruction encoding formats.
523523 let Inst{23} = offset{12};
524524 let Inst{19-16} = Rn;
525525 let Inst{11-0} = offset{11-0};
526 }
527 // FIXME: Merge with the above class when addrmode2 gets used for STR, STRB
528 // but for now use this class for STRT and STRBT.
529 class AI2stridxT
530 IndexMode im, Format f, InstrItinClass itin, string opc,
531 string asm, string cstr, list pattern>
532 : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
533 pattern> {
534 // AM2 store w/ two operands: (GPR, am2offset)
535 // {17-14} Rn
536 // {13} 1 == Rm, 0 == imm12
537 // {12} isAdd
538 // {11-0} imm12/Rm
539 bits<18> addr;
540 let Inst{25} = addr{13};
541 let Inst{23} = addr{12};
542 let Inst{19-16} = addr{17-14};
543 let Inst{11-0} = addr{11-0};
526544 }
527545
528546 // 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
16671674 let Inst{23} = addr{12};
16681675 let Inst{19-16} = addr{17-14};
16691676 let Inst{11-0} = addr{11-0};
1677 let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
16701678 }
16711679 def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
16721680 (ins GPR:$Rn, am2offset:$offset),
17251733
17261734 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
17271735 let mayLoad = 1, neverHasSideEffects = 1 in {
1728 def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
1729 (ins GPR:$base, am2offset:$offset), IndexModePost,
1730 LdFrm, IIC_iLoad_ru,
1731 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1736 def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb),
1737 (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru,
1738 "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
1739 // {17-14} Rn
1740 // {13} 1 == Rm, 0 == imm12
1741 // {12} isAdd
1742 // {11-0} imm12/Rm
1743 bits<18> addr;
1744 let Inst{25} = addr{13};
1745 let Inst{23} = addr{12};
17321746 let Inst{21} = 1; // overwrite
1733 }
1734 def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
1735 (ins GPR:$base, am2offset:$offset), IndexModePost,
1736 LdFrm, IIC_iLoad_bh_ru,
1737 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
1747 let Inst{19-16} = addr{17-14};
1748 let Inst{11-0} = addr{11-0};
1749 let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
1750 }
1751 def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb),
1752 (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_bh_ru,
1753 "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
1754 // {17-14} Rn
1755 // {13} 1 == Rm, 0 == imm12
1756 // {12} isAdd
1757 // {11-0} imm12/Rm
1758 bits<18> addr;
1759 let Inst{25} = addr{13};
1760 let Inst{23} = addr{12};
17381761 let Inst{21} = 1; // overwrite
1762 let Inst{19-16} = addr{17-14};
1763 let Inst{11-0} = addr{11-0};
1764 let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
17391765 }
17401766 def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
17411767 (ins GPR:$base, am3offset:$offset), IndexModePost,
18291855
18301856 // STRT, STRBT, and STRHT are for disassembly only.
18311857
1832 def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1833 (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
1834 IndexModePost, StFrm, IIC_iStore_ru,
1835 "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1836 [/* For disassembly only; pattern left blank */]> {
1837 let Inst{21} = 1; // overwrite
1838 }
1839
1840 def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb),
1841 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
1842 IndexModePost, StFrm, IIC_iStore_bh_ru,
1843 "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
1858 def STRT : AI2stridxT<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr),
1859 IndexModePost, StFrm, IIC_iStore_ru,
1860 "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
18441861 [/* For disassembly only; pattern left blank */]> {
18451862 let Inst{21} = 1; // overwrite
1863 let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
1864 }
1865
1866 def STRBT : AI2stridxT<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr),
1867 IndexModePost, StFrm, IIC_iStore_bh_ru,
1868 "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
1869 [/* For disassembly only; pattern left blank */]> {
1870 let Inst{21} = 1; // overwrite
1871 let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
18461872 }
18471873
18481874 def STRHT: AI3sthpo<(outs GPR:$base_wb),
34023428 let Inst{23-20} = opc1;
34033429 }
34043430
3405 class ACI
3406 : I,
3431 class ACI,
3432 IndexMode im = IndexModeNone>
3433 : I
34073434 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
34083435 let Inst{27-25} = 0b110;
34093436 }
34223449
34233450 def _PRE : ACI<(outs),
34243451 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3425 opc, "\tp$cop, cr$CRd, $addr!"> {
3452 opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> {
34263453 let Inst{31-28} = op31_28;
34273454 let Inst{24} = 1; // P = 1
34283455 let Inst{21} = 1; // W = 1
34313458 }
34323459
34333460 def _POST : ACI<(outs),
3434 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3435 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
3461 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3462 opc, "\tp$cop, cr$CRd, $addr", IndexModePost> {
34363463 let Inst{31-28} = op31_28;
34373464 let Inst{24} = 0; // P = 0
34383465 let Inst{21} = 1; // W = 1
34633490
34643491 def L_PRE : ACI<(outs),
34653492 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3466 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
3493 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> {
34673494 let Inst{31-28} = op31_28;
34683495 let Inst{24} = 1; // P = 1
34693496 let Inst{21} = 1; // W = 1
34723499 }
34733500
34743501 def L_POST : ACI<(outs),
3475 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3476 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
3502 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3503 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr", IndexModePost> {
34773504 let Inst{31-28} = op31_28;
34783505 let Inst{24} = 0; // P = 0
34793506 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 unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
504
505 if (getMemOffsetIsReg()) {
506 Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
507
508 ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
509 ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift;
510 int64_t ShiftAmount = 0;
511
512 if (getMemOffsetRegShifted()) {
513 ShOpc = getMemShiftType();
514 const MCConstantExpr *CE =
515 dyn_cast(getMemShiftAmount());
516 ShiftAmount = CE->getValue();
517 }
518
519 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount,
520 ShOpc, IdxMode)));
521 return;
522 }
523
524 // Create a operand placeholder to always yield the same number of operands.
525 Inst.addOperand(MCOperand::CreateReg(0));
526
527 // FIXME: #-0 is encoded differently than #0. Does the parser preserve
528 // the difference?
529 const MCConstantExpr *CE = dyn_cast(getMemOffset());
530 assert(CE && "Non-constant mode 2 offset operand!");
531 int64_t Offset = CE->getValue();
532
533 if (Offset >= 0)
534 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add,
535 Offset, ARM_AM::no_shift, IdxMode)));
536 else
537 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub,
538 -Offset, ARM_AM::no_shift, IdxMode)));
465539 }
466540
467541 void addMemMode5Operands(MCInst &Inst, unsigned N) const {
598672 return Op;
599673 }
600674
601 static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg,
602 const MCExpr *Offset, int OffsetRegNum,
603 bool OffsetRegShifted,
675 static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum,
676 bool OffsetIsReg, const MCExpr *Offset,
677 int OffsetRegNum, bool OffsetRegShifted,
604678 enum ARM_AM::ShiftOpc ShiftType,
605679 const MCExpr *ShiftAmount, bool Preindexed,
606680 bool Postindexed, bool Negative, bool Writeback,
617691 "Cannot have expression offset and register offset!");
618692
619693 ARMOperand *Op = new ARMOperand(Memory);
694 Op->Mem.AddrMode = AddrMode;
620695 Op->Mem.BaseRegNum = BaseRegNum;
621696 Op->Mem.OffsetIsReg = OffsetIsReg;
622697 if (OffsetIsReg)
688763 break;
689764 case Memory:
690765 OS << "
691 << "base:" << getMemBaseRegNum();
766 << "am:" << ARMII::AddrModeToString(getMemAddrMode())
767 << " base:" << getMemBaseRegNum();
692768 if (getMemOffsetIsReg()) {
693769 OS << " offset:
694770 if (getMemOffsetRegShifted()) {
11311207 return MatchOperand_Success;
11321208 }
11331209
1210 /// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand.
1211 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1212 tryParseMemMode2Operand(SmallVectorImpl &Operands) {
1213 SMLoc S = Parser.getTok().getLoc();
1214 const AsmToken &Tok = Parser.getTok();
1215 assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\"");
1216
1217 if (ParseMemory(Operands, ARMII::AddrMode2))
1218 return MatchOperand_NoMatch;
1219
1220 return MatchOperand_Success;
1221 }
1222
1223 /// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1224 /// Needed here because the Asm Gen Matcher can't handle properly tied operands
1225 /// when they refer multiple MIOperands inside a single one.
1226 bool ARMAsmParser::
1227 CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1228 const SmallVectorImpl &Operands) {
1229 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1230
1231 // Create a writeback register dummy placeholder.
1232 Inst.addOperand(MCOperand::CreateImm(0));
1233
1234 ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1235 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1236 return true;
1237 }
1238
1239 /// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1240 /// Needed here because the Asm Gen Matcher can't handle properly tied operands
1241 /// when they refer multiple MIOperands inside a single one.
1242 bool ARMAsmParser::
1243 CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1244 const SmallVectorImpl &Operands) {
1245 // Create a writeback register dummy placeholder.
1246 Inst.addOperand(MCOperand::CreateImm(0));
1247 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1248 ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1249 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1250 return true;
1251 }
1252
11341253 /// Parse an ARM memory expression, return false if successful else return true
11351254 /// or an error. The first token must be a '[' when called.
11361255 ///
11371256 /// TODO Only preindexing and postindexing addressing are started, unindexed
11381257 /// with option, etc are still to do.
11391258 bool ARMAsmParser::
1140 ParseMemory(SmallVectorImpl &Operands) {
1259 ParseMemory(SmallVectorImpl &Operands,
1260 ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
11411261 SMLoc S, E;
11421262 assert(Parser.getTok().is(AsmToken::LBrac) &&
11431263 "Token is not a Left Bracket");
11951315 ExclaimTok.getLoc());
11961316 Writeback = true;
11971317 Parser.Lex(); // Eat exclaim token
1318 } else { // In addressing mode 2, pre-indexed mode always end with "!"
1319 if (AddrMode == ARMII::AddrMode2)
1320 Preindexed = false;
11981321 }
11991322 } else {
12001323 // The "[Rn" we have so far was not followed by a comma.
12301353 Offset = MCConstantExpr::Create(0, getContext());
12311354 }
12321355
1233 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset,
1234 OffsetRegNum, OffsetRegShifted,
1235 ShiftType, ShiftAmount, Preindexed,
1236 Postindexed, Negative, Writeback,
1237 S, E));
1356 Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg,
1357 Offset, OffsetRegNum, OffsetRegShifted,
1358 ShiftType, ShiftAmount, Preindexed,
1359 Postindexed, Negative, Writeback, S, E));
12381360 if (WBOp)
12391361 Operands.push_back(WBOp);
12401362
642642 if (PW) {
643643 MI.addOperand(MCOperand::CreateReg(0));
644644 ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
645 const TargetInstrDesc &TID = ARMInsts[Opcode];
646 unsigned IndexMode =
647 (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
645648 unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, slice(insn, 7, 0) << 2,
646 ARM_AM::no_shift);
649 ARM_AM::no_shift, IndexMode);
647650 MI.addOperand(MCOperand::CreateImm(Offset));
648651 OpIdx = 5;
649652 } else {
10831086 return false;
10841087
10851088 ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
1089 unsigned IndexMode =
1090 (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
10861091 if (getIBit(insn) == 0) {
10871092 // For pre- and post-indexed case, add a reg0 operand (Addressing Mode #2).
10881093 // Otherwise, skip the reg operand since for addrmode_imm12, Rn has already
10941099
10951100 // Disassemble the 12-bit immediate offset.
10961101 unsigned Imm12 = slice(insn, 11, 0);
1097 unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift);
1102 unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift,
1103 IndexMode);
10981104 MI.addOperand(MCOperand::CreateImm(Offset));
10991105 OpIdx += 1;
11001106 } else {
11091115 // A8.4.1. Possible rrx or shift amount of 32...
11101116 getImmShiftSE(ShOp, ShImm);
11111117 MI.addOperand(MCOperand::CreateImm(
1112 ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp)));
1118 ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp, IndexMode)));
11131119 OpIdx += 2;
11141120 }
11151121
180180 }
181181 }
182182
183
184 void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
185 raw_ostream &O) {
183 void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
184 raw_ostream &O) {
186185 const MCOperand &MO1 = MI->getOperand(Op);
187186 const MCOperand &MO2 = MI->getOperand(Op+1);
188187 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 }
194188
195189 O << "[" << getRegisterName(MO1.getReg());
196190
212206 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
213207 << " #" << ShImm;
214208 O << "]";
209 }
210
211 void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op,
212 raw_ostream &O) {
213 const MCOperand &MO1 = MI->getOperand(Op);
214 const MCOperand &MO2 = MI->getOperand(Op+1);
215 const MCOperand &MO3 = MI->getOperand(Op+2);
216
217 O << "[" << getRegisterName(MO1.getReg()) << "], ";
218
219 if (!MO2.getReg()) {
220 unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm());
221 O << '#'
222 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
223 << ImmOffs;
224 return;
225 }
226
227 O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
228 << getRegisterName(MO2.getReg());
229
230 if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
231 O << ", "
232 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
233 << " #" << ShImm;
234 }
235
236 void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
237 raw_ostream &O) {
238 const MCOperand &MO1 = MI->getOperand(Op);
239
240 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
241 printOperand(MI, Op, O);
242 return;
243 }
244
245 const MCOperand &MO3 = MI->getOperand(Op+2);
246 unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm());
247
248 if (IdxMode == ARMII::IndexModePost) {
249 printAM2PostIndexOp(MI, Op, O);
250 return;
251 }
252 printAM2PreOrOffsetIndexOp(MI, Op, O);
215253 }
216254
217255 void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
4141 void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
4242
4343 void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
44
4445 void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
46 void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O);
47 void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum,
48 raw_ostream &O);
4549 void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum,
4650 raw_ostream &O);
4751 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