llvm.org GIT mirror llvm / b41aaab
Revert r128632 again, until I figure out what break the tests git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128635 91177308-0d34-0410-b5e6-96231b3b80d8 Bruno Cardoso Lopes 9 years ago
10 changed file(s) with 89 addition(s) and 362 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. The
411 // forth operand 16-17 encodes the index mode.
410 // in bit 12, the immediate in bits 0-11, and the shift op in 13-15.
412411 //
413412 // If this addressing mode is a frame index (before prolog/epilog insertion
414413 // and code rewriting), this operand will have the form: FI#, reg0,
415414 // with no shift amount for the frame offset.
416415 //
417 static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO,
418 unsigned IdxMode = 0) {
416 static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO) {
419417 assert(Imm12 < (1 << 12) && "Imm too large!");
420418 bool isSub = Opc == sub;
421 return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ;
419 return Imm12 | ((int)isSub << 12) | (SO << 13);
422420 }
423421 static inline unsigned getAM2Offset(unsigned AM2Opc) {
424422 return AM2Opc & ((1 << 12)-1);
427425 return ((AM2Opc >> 12) & 1) ? sub : add;
428426 }
429427 static inline ShiftOpc getAM2ShiftOpc(unsigned AM2Opc) {
430 return (ShiftOpc)((AM2Opc >> 13) & 7);
431 }
432 static inline unsigned getAM2IdxMode(unsigned AM2Opc) {
433 return (AM2Opc >> 16);
428 return (ShiftOpc)(AM2Opc >> 13);
434429 }
435430
436431
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
255202 /// Target Operand Flag enum.
256203 enum TOF {
257204 //===------------------------------------------------------------------===//
3333
3434 //===------------------------------------------------------------------===//
3535 // This four-bit field describes the addressing mode used.
36 AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h
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,
3755
3856 // Size* - Flags to keep track of the size of an instruction.
3957 SizeShift = 5,
4563
4664 // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
4765 // and store ops only. Generic "updating" flag is used for ld/st multiple.
48 // The index mode enums are declared in ARMBaseInfo.h
4966 IndexModeShift = 8,
5067 IndexModeMask = 3 << IndexModeShift,
68 IndexModePre = 1,
69 IndexModePost = 2,
70 IndexModeUpd = 3,
5171
5272 //===------------------------------------------------------------------===//
5373 // Instruction encoding formats.
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
518517 // {13} 1 == Rm, 0 == imm12
519518 // {12} isAdd
520519 // {11-0} imm12/Rm
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};
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};
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
506500 // addrmode2 := reg +/- imm12
507501 // := reg +/- reg shop imm
508502 //
510504 ComplexPattern {
511505 let EncoderMethod = "getAddrMode2OpValue";
512506 let PrintMethod = "printAddrMode2Operand";
513 let ParserMatchClass = MemMode2AsmOperand;
514507 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
515508 }
516509
16621655 let Inst{23} = addr{12};
16631656 let Inst{19-16} = addr{17-14};
16641657 let Inst{11-0} = addr{11-0};
1665 let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
16661658 }
16671659 def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1668 (ins addrmode2:$addr), IndexModePost, LdFrm, itin,
1669 opc, "\t$Rt, $addr", "$addr.base = $Rn_wb", []> {
1670 // {17-14} Rn
1660 (ins GPR:$Rn, am2offset:$offset),
1661 IndexModePost, LdFrm, itin,
1662 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
16711663 // {13} 1 == Rm, 0 == imm12
16721664 // {12} isAdd
16731665 // {11-0} imm12/Rm
1674 bits<18> addr;
1675 let Inst{25} = addr{13};
1676 let Inst{23} = addr{12};
1677 let Inst{19-16} = addr{17-14};
1678 let Inst{11-0} = addr{11-0};
1679 let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
1666 bits<14> offset;
1667 bits<4> Rn;
1668 let Inst{25} = offset{13};
1669 let Inst{23} = offset{12};
1670 let Inst{19-16} = Rn;
1671 let Inst{11-0} = offset{11-0};
16801672 }
16811673 }
16821674
17211713
17221714 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
17231715 let mayLoad = 1, neverHasSideEffects = 1 in {
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};
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", []> {
17341720 let Inst{21} = 1; // overwrite
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};
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", []> {
17491726 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";
17531727 }
17541728 def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
17551729 (ins GPR:$base, am3offset:$offset), IndexModePost,
18431817
18441818 // STRT, STRBT, and STRHT are for disassembly only.
18451819
1846 def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr),
1820 def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb),
1821 (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
18471822 IndexModePost, StFrm, IIC_iStore_ru,
1848 "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
1823 "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
18491824 [/* For disassembly only; pattern left blank */]> {
18501825 let Inst{21} = 1; // overwrite
1851 let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
1852 }
1853
1854 def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr),
1826 }
1827
1828 def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb),
1829 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
18551830 IndexModePost, StFrm, IIC_iStore_bh_ru,
1856 "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
1831 "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
18571832 [/* For disassembly only; pattern left blank */]> {
18581833 let Inst{21} = 1; // overwrite
1859 let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
18601834 }
18611835
18621836 def STRHT: AI3sthpo<(outs GPR:$base_wb),
34163390 let Inst{23-20} = opc1;
34173391 }
34183392
3419 class ACI
3420 IndexMode im = IndexModeNone>
3421 : I
3393 class ACI
3394 : I
34223395 opc, asm, "", [/* For disassembly only; pattern left blank */]> {
34233396 let Inst{27-25} = 0b110;
34243397 }
34373410
34383411 def _PRE : ACI<(outs),
34393412 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3440 opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> {
3413 opc, "\tp$cop, cr$CRd, $addr!"> {
34413414 let Inst{31-28} = op31_28;
34423415 let Inst{24} = 1; // P = 1
34433416 let Inst{21} = 1; // W = 1
34463419 }
34473420
34483421 def _POST : ACI<(outs),
3449 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3450 opc, "\tp$cop, cr$CRd, $addr", IndexModePost> {
3422 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3423 opc, "\tp$cop, cr$CRd, [$base], $offset"> {
34513424 let Inst{31-28} = op31_28;
34523425 let Inst{24} = 0; // P = 0
34533426 let Inst{21} = 1; // W = 1
34783451
34793452 def L_PRE : ACI<(outs),
34803453 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3481 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> {
3454 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
34823455 let Inst{31-28} = op31_28;
34833456 let Inst{24} = 1; // P = 1
34843457 let Inst{21} = 1; // W = 1
34873460 }
34883461
34893462 def L_POST : ACI<(outs),
3490 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
3491 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr", IndexModePost> {
3463 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
3464 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
34923465 let Inst{31-28} = op31_28;
34933466 let Inst{24} = 0; // P = 0
34943467 let Inst{21} = 1; // W = 1
4747 bool TryParseRegisterWithWriteBack(SmallVectorImpl &);
4848 bool TryParseShiftRegister(SmallVectorImpl &);
4949 bool ParseRegisterList(SmallVectorImpl &);
50 bool ParseMemory(SmallVectorImpl &,
51 ARMII::AddrMode AddrMode);
50 bool ParseMemory(SmallVectorImpl &);
5251 bool ParseOperand(SmallVectorImpl &, StringRef Mnemonic);
5352 bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
5453 const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
9594 SmallVectorImpl&);
9695 OperandMatchResultTy tryParseMSRMaskOperand(
9796 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 &);
10697
10798 public:
10899 ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM)
180171
181172 /// Combined record for all forms of ARM address expressions.
182173 struct {
183 ARMII::AddrMode AddrMode;
184174 unsigned BaseRegNum;
185175 union {
186176 unsigned RegNum; ///< Offset register num, when OffsetIsReg.
302292
303293 /// @name Memory Operand Accessors
304294 /// @{
305 ARMII::AddrMode getMemAddrMode() const {
306 return Mem.AddrMode;
307 }
295
308296 unsigned getMemBaseRegNum() const {
309297 return Mem.BaseRegNum;
310298 }
349337 bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
350338 bool isMemory() const { return Kind == Memory; }
351339 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 }
373340 bool isMemMode5() const {
374341 if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() ||
375342 getMemNegative())
495462 (void)CE;
496463 assert((CE || CE->getValue() == 0) &&
497464 "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)));
539465 }
540466
541467 void addMemMode5Operands(MCInst &Inst, unsigned N) const {
672598 return Op;
673599 }
674600
675 static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum,
676 bool OffsetIsReg, const MCExpr *Offset,
677 int OffsetRegNum, bool OffsetRegShifted,
601 static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg,
602 const MCExpr *Offset, int OffsetRegNum,
603 bool OffsetRegShifted,
678604 enum ARM_AM::ShiftOpc ShiftType,
679605 const MCExpr *ShiftAmount, bool Preindexed,
680606 bool Postindexed, bool Negative, bool Writeback,
691617 "Cannot have expression offset and register offset!");
692618
693619 ARMOperand *Op = new ARMOperand(Memory);
694 Op->Mem.AddrMode = AddrMode;
695620 Op->Mem.BaseRegNum = BaseRegNum;
696621 Op->Mem.OffsetIsReg = OffsetIsReg;
697622 if (OffsetIsReg)
763688 break;
764689 case Memory:
765690 OS << "
766 << "am:" << ARMII::AddrModeToString(getMemAddrMode())
767 << " base:" << getMemBaseRegNum();
691 << "base:" << getMemBaseRegNum();
768692 if (getMemOffsetIsReg()) {
769693 OS << " offset:
770694 if (getMemOffsetRegShifted()) {
12071131 return MatchOperand_Success;
12081132 }
12091133
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
12531134 /// Parse an ARM memory expression, return false if successful else return true
12541135 /// or an error. The first token must be a '[' when called.
12551136 ///
12561137 /// TODO Only preindexing and postindexing addressing are started, unindexed
12571138 /// with option, etc are still to do.
12581139 bool ARMAsmParser::
1259 ParseMemory(SmallVectorImpl &Operands,
1260 ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
1140 ParseMemory(SmallVectorImpl &Operands) {
12611141 SMLoc S, E;
12621142 assert(Parser.getTok().is(AsmToken::LBrac) &&
12631143 "Token is not a Left Bracket");
13151195 ExclaimTok.getLoc());
13161196 Writeback = true;
13171197 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;
13211198 }
13221199 } else {
13231200 // The "[Rn" we have so far was not followed by a comma.
13531230 Offset = MCConstantExpr::Create(0, getContext());
13541231 }
13551232
1356 Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg,
1357 Offset, OffsetRegNum, OffsetRegShifted,
1358 ShiftType, ShiftAmount, Preindexed,
1359 Postindexed, Negative, Writeback, S, E));
1233 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset,
1234 OffsetRegNum, OffsetRegShifted,
1235 ShiftType, ShiftAmount, Preindexed,
1236 Postindexed, Negative, Writeback,
1237 S, E));
13601238 if (WBOp)
13611239 Operands.push_back(WBOp);
13621240
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;
648645 unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, slice(insn, 7, 0) << 2,
649 ARM_AM::no_shift, IndexMode);
646 ARM_AM::no_shift);
650647 MI.addOperand(MCOperand::CreateImm(Offset));
651648 OpIdx = 5;
652649 } else {
10751072 return false;
10761073
10771074 ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
1078 unsigned IndexMode =
1079 (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
10801075 if (getIBit(insn) == 0) {
10811076 // For pre- and post-indexed case, add a reg0 operand (Addressing Mode #2).
10821077 // Otherwise, skip the reg operand since for addrmode_imm12, Rn has already
10881083
10891084 // Disassemble the 12-bit immediate offset.
10901085 unsigned Imm12 = slice(insn, 11, 0);
1091 unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift,
1092 IndexMode);
1086 unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift);
10931087 MI.addOperand(MCOperand::CreateImm(Offset));
10941088 OpIdx += 1;
10951089 } else {
11041098 // A8.4.1. Possible rrx or shift amount of 32...
11051099 getImmShiftSE(ShOp, ShImm);
11061100 MI.addOperand(MCOperand::CreateImm(
1107 ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp, IndexMode)));
1101 ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp)));
11081102 OpIdx += 2;
11091103 }
11101104
180180 }
181181 }
182182
183 void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
184 raw_ostream &O) {
183
184 void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
185 raw_ostream &O) {
185186 const MCOperand &MO1 = MI->getOperand(Op);
186187 const MCOperand &MO2 = MI->getOperand(Op+1);
187188 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 }
188194
189195 O << "[" << getRegisterName(MO1.getReg());
190196
206212 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
207213 << " #" << ShImm;
208214 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);
253215 }
254216
255217 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
4544 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);
4945 void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum,
5046 raw_ostream &O);
5147 void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
None @ 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 @ CHECK: ldr r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0x90,0xe6]
16 @ CHECK: ldrb r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xd0,0xe6]
17 ldrt r1, [r0], r2
18 ldrt r1, [r0], r2, lsr #3
19 ldrt r1, [r0], #4
20 ldrbt r1, [r0], r2
21 ldrbt r1, [r0], r2, lsr #3
22 ldrbt r1, [r0], #4
23 strt r1, [r0], r2
24 strt r1, [r0], r2, lsr #3
25 strt r1, [r0], #4
26 strbt r1, [r0], r2
27 strbt r1, [r0], r2, lsr #3
28 strbt r1, [r0], #4
29 ldr r1, [r0], r2, lsr #3
30 ldrb r1, [r0], r2, lsr #3
31
32 @ Pre-indexed
33 @ CHECK: ldr r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xb0,0xe7]
34 @ CHECK: ldrb r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xf0,0xe7]
35 ldr r1, [r0, r2, lsr #3]!
36 ldrb r1, [r0, r2, lsr #3]!
37