llvm.org GIT mirror llvm / 505f3cd
Add asm parsing support w/ testcases for strex/ldrex family of instructions git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128236 91177308-0d34-0410-b5e6-96231b3b80d8 Bruno Cardoso Lopes 9 years ago
11 changed file(s) with 156 addition(s) and 61 deletion(s). Raw diff Collapse all Expand all
3434 kOperandTypeARMAddrMode5,
3535 kOperandTypeARMAddrMode6,
3636 kOperandTypeARMAddrMode6Offset,
37 kOperandTypeARMAddrMode7,
3738 kOperandTypeARMAddrModePC,
3839 kOperandTypeARMRegisterList,
3940 kOperandTypeARMTBAddrMode,
5051 kOperandTypeThumb2AddrModeImm12,
5152 kOperandTypeThumb2AddrModeSoReg,
5253 kOperandTypeThumb2AddrModeImm8s4,
53 kOperandTypeThumb2AddrModeImm8s4Offset
54 kOperandTypeThumb2AddrModeImm8s4Offset,
55 kOperandTypeThumb2AddrModeReg
5456 };
5557
5658 enum OperandFlags {
7272 case kOperandTypeThumb2AddrModeImm8Offset:
7373 case kOperandTypeARMTBAddrMode:
7474 case kOperandTypeThumb2AddrModeImm8s4Offset:
75 case kOperandTypeARMAddrMode7:
76 case kOperandTypeThumb2AddrModeReg:
7577 numMCOperands = 1;
7678 break;
7779 case kOperandTypeThumb2SoReg:
255257 case kOperandTypeARMAddrMode4:
256258 case kOperandTypeARMAddrMode5:
257259 case kOperandTypeARMAddrMode6:
260 case kOperandTypeARMAddrMode7:
258261 case kOperandTypeARMAddrModePC:
259262 case kOperandTypeARMBranchTarget:
260263 case kOperandTypeThumbAddrModeS1:
268271 case kOperandTypeThumb2AddrModeImm12:
269272 case kOperandTypeThumb2AddrModeSoReg:
270273 case kOperandTypeThumb2AddrModeImm8s4:
274 case kOperandTypeThumb2AddrModeReg:
271275 return 1;
272276 }
273277 }
433433 opc, asm, "", pattern> {
434434 bits<4> Rd;
435435 bits<4> Rt;
436 bits<4> Rn;
436 bits<4> addr;
437437 let Inst{27-23} = 0b00011;
438438 let Inst{22-21} = opcod;
439439 let Inst{20} = 0;
440 let Inst{19-16} = Rn;
440 let Inst{19-16} = addr;
441441 let Inst{15-12} = Rd;
442442 let Inst{11-4} = 0b11111001;
443443 let Inst{3-0} = Rt;
587587 ComplexPattern {
588588 let PrintMethod = "printAddrModePCOperand";
589589 let MIOperandInfo = (ops GPR, i32imm);
590 }
591
592 def MemMode7AsmOperand : AsmOperandClass {
593 let Name = "MemMode7";
594 let SuperClasses = [];
595 }
596
597 // addrmode7 := reg
598 // Used by load/store exclusive instructions. Useful to enable right assembly
599 // parsing and printing. Not used for any codegen matching.
600 //
601 def addrmode7 : Operand {
602 let PrintMethod = "printAddrMode7Operand";
603 let MIOperandInfo = (ops GPR);
604 let ParserMatchClass = MemMode7AsmOperand;
590605 }
591606
592607 def nohash_imm : Operand {
32933308 }
32943309
32953310 let mayLoad = 1 in {
3296 def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3297 "ldrexb", "\t$Rt, [$Rn]",
3298 []>;
3299 def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3300 "ldrexh", "\t$Rt, [$Rn]",
3301 []>;
3302 def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
3303 "ldrex", "\t$Rt, [$Rn]",
3304 []>;
3305 def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn),
3306 NoItinerary,
3307 "ldrexd", "\t$Rt, $Rt2, [$Rn]",
3308 []>;
3311 def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins addrmode7:$addr), NoItinerary,
3312 "ldrexb", "\t$Rt, $addr", []>;
3313 def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins addrmode7:$addr), NoItinerary,
3314 "ldrexh", "\t$Rt, $addr", []>;
3315 def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins addrmode7:$addr), NoItinerary,
3316 "ldrex", "\t$Rt, $addr", []>;
3317 def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins addrmode7:$addr),
3318 NoItinerary, "ldrexd", "\t$Rt, $Rt2, $addr", []>;
33093319 }
33103320
33113321 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
3312 def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$src, GPR:$Rn),
3313 NoItinerary,
3314 "strexb", "\t$Rd, $src, [$Rn]",
3315 []>;
3316 def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3317 NoItinerary,
3318 "strexh", "\t$Rd, $Rt, [$Rn]",
3319 []>;
3320 def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
3321 NoItinerary,
3322 "strex", "\t$Rd, $Rt, [$Rn]",
3323 []>;
3322 def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$Rt, addrmode7:$addr),
3323 NoItinerary, "strexb", "\t$Rd, $Rt, $addr", []>;
3324 def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, addrmode7:$addr),
3325 NoItinerary, "strexh", "\t$Rd, $Rt, $addr", []>;
3326 def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, addrmode7:$addr),
3327 NoItinerary, "strex", "\t$Rd, $Rt, $addr", []>;
33243328 def STREXD : AIstrex<0b01, (outs GPR:$Rd),
3325 (ins GPR:$Rt, GPR:$Rt2, GPR:$Rn),
3326 NoItinerary,
3327 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]",
3328 []>;
3329 (ins GPR:$Rt, GPR:$Rt2, addrmode7:$addr),
3330 NoItinerary, "strexd", "\t$Rd, $Rt, $Rt2, $addr", []>;
33293331 }
33303332
33313333 // Clear-Exclusive is for disassembly only.
144144 let ParserMatchClass = MemMode5AsmOperand;
145145 }
146146
147 // t2addrmode_reg := reg
148 // Used by load/store exclusive instructions. Useful to enable right assembly
149 // parsing and printing. Not used for any codegen matching.
150 //
151 def t2addrmode_reg : Operand {
152 let PrintMethod = "printAddrMode7Operand";
153 let MIOperandInfo = (ops tGPR);
154 let ParserMatchClass = MemMode7AsmOperand;
155 }
147156
148157 //===----------------------------------------------------------------------===//
149158 // Multiclass helpers...
28202829 let Inst{5-4} = opcod;
28212830 let Inst{3-0} = 0b1111;
28222831
2823 bits<4> Rn;
2832 bits<4> addr;
28242833 bits<4> Rt;
2825 let Inst{19-16} = Rn;
2834 let Inst{19-16} = addr;
28262835 let Inst{15-12} = Rt;
28272836 }
28282837 class T2I_strex opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
28362845 let Inst{5-4} = opcod;
28372846
28382847 bits<4> Rd;
2839 bits<4> Rn;
2848 bits<4> addr;
28402849 bits<4> Rt;
2841 let Inst{11-8} = Rd;
2842 let Inst{19-16} = Rn;
2850 let Inst{3-0} = Rd;
2851 let Inst{19-16} = addr;
28432852 let Inst{15-12} = Rt;
28442853 }
28452854
28462855 let mayLoad = 1 in {
2847 def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
2848 Size4Bytes, NoItinerary, "ldrexb", "\t$Rt, [$Rn]",
2856 def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$Rt), (ins t2addrmode_reg:$addr), AddrModeNone,
2857 Size4Bytes, NoItinerary, "ldrexb", "\t$Rt, $addr",
28492858 "", []>;
2850 def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
2851 Size4Bytes, NoItinerary, "ldrexh", "\t$Rt, [$Rn]",
2859 def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$Rt), (ins t2addrmode_reg:$addr), AddrModeNone,
2860 Size4Bytes, NoItinerary, "ldrexh", "\t$Rt, $addr",
28522861 "", []>;
2853 def t2LDREX : Thumb2I<(outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
2862 def t2LDREX : Thumb2I<(outs rGPR:$Rt), (ins t2addrmode_reg:$addr), AddrModeNone,
28542863 Size4Bytes, NoItinerary,
2855 "ldrex", "\t$Rt, [$Rn]", "",
2864 "ldrex", "\t$Rt, $addr", "",
28562865 []> {
28572866 let Inst{31-27} = 0b11101;
28582867 let Inst{26-20} = 0b0000101;
28592868 let Inst{11-8} = 0b1111;
28602869 let Inst{7-0} = 0b00000000; // imm8 = 0
28612870
2862 bits<4> Rn;
28632871 bits<4> Rt;
2864 let Inst{19-16} = Rn;
2872 bits<4> addr;
2873 let Inst{19-16} = addr;
28652874 let Inst{15-12} = Rt;
28662875 }
2867 def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$Rt, rGPR:$Rt2), (ins rGPR:$Rn),
2876 def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$Rt, rGPR:$Rt2), (ins t2addrmode_reg:$addr),
28682877 AddrModeNone, Size4Bytes, NoItinerary,
2869 "ldrexd", "\t$Rt, $Rt2, [$Rn]", "",
2878 "ldrexd", "\t$Rt, $Rt2, $addr", "",
28702879 [], {?, ?, ?, ?}> {
28712880 bits<4> Rt2;
28722881 let Inst{11-8} = Rt2;
28742883 }
28752884
28762885 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
2877 def t2STREXB : T2I_strex<0b00, (outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
2878 AddrModeNone, Size4Bytes, NoItinerary,
2879 "strexb", "\t$Rd, $Rt, [$Rn]", "", []>;
2880 def t2STREXH : T2I_strex<0b01, (outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
2881 AddrModeNone, Size4Bytes, NoItinerary,
2882 "strexh", "\t$Rd, $Rt, [$Rn]", "", []>;
2883 def t2STREX : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
2884 AddrModeNone, Size4Bytes, NoItinerary,
2885 "strex", "\t$Rd, $Rt, [$Rn]", "",
2886 []> {
2886 def t2STREXB : T2I_strex<0b00, (outs rGPR:$Rd), (ins rGPR:$Rt, t2addrmode_reg:$addr),
2887 AddrModeNone, Size4Bytes, NoItinerary,
2888 "strexb", "\t$Rd, $Rt, $addr", "", []>;
2889 def t2STREXH : T2I_strex<0b01, (outs rGPR:$Rd), (ins rGPR:$Rt, t2addrmode_reg:$addr),
2890 AddrModeNone, Size4Bytes, NoItinerary,
2891 "strexh", "\t$Rd, $Rt, $addr", "", []>;
2892 def t2STREX : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, t2addrmode_reg:$addr),
2893 AddrModeNone, Size4Bytes, NoItinerary,
2894 "strex", "\t$Rd, $Rt, $addr", "",
2895 []> {
28872896 let Inst{31-27} = 0b11101;
28882897 let Inst{26-20} = 0b0000100;
28892898 let Inst{7-0} = 0b00000000; // imm8 = 0
28902899
28912900 bits<4> Rd;
2892 bits<4> Rn;
2901 bits<4> addr;
28932902 bits<4> Rt;
28942903 let Inst{11-8} = Rd;
2895 let Inst{19-16} = Rn;
2904 let Inst{19-16} = addr;
28962905 let Inst{15-12} = Rt;
28972906 }
28982907 def t2STREXD : T2I_strex<0b11, (outs rGPR:$Rd),
2899 (ins rGPR:$Rt, rGPR:$Rt2, rGPR:$Rn),
2908 (ins rGPR:$Rt, rGPR:$Rt2, t2addrmode_reg:$addr),
29002909 AddrModeNone, Size4Bytes, NoItinerary,
2901 "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]", "", [],
2910 "strexd", "\t$Rd, $Rt, $Rt2, $addr", "", [],
29022911 {?, ?, ?, ?}> {
29032912 bits<4> Rt2;
29042913 let Inst{11-8} = Rt2;
349349 int64_t Value = CE->getValue();
350350 return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
351351 }
352 bool isMemMode7() const {
353 if (!isMemory() ||
354 getMemPreindexed() ||
355 getMemPostindexed() ||
356 getMemOffsetIsReg() ||
357 getMemNegative() ||
358 getMemWriteback())
359 return false;
360
361 const MCConstantExpr *CE = dyn_cast(getMemOffset());
362 if (!CE) return false;
363
364 if (CE->getValue())
365 return false;
366
367 return true;
368 }
352369 bool isMemModeRegThumb() const {
353370 if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback())
354371 return false;
435452 void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
436453 assert(N == 1 && "Invalid number of operands!");
437454 Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
455 }
456
457 void addMemMode7Operands(MCInst &Inst, unsigned N) const {
458 assert(N == 1 && isMemMode7() && "Invalid number of operands!");
459 Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
460
461 const MCConstantExpr *CE = dyn_cast(getMemOffset());
462 assert((CE || CE->getValue() == 0) &&
463 "No offset operand support in mode 7");
438464 }
439465
440466 void addMemMode5Operands(MCInst &Inst, unsigned N) const {
314314 O << ", :" << (MO2.getImm() << 3);
315315 }
316316 O << "]";
317 }
318
319 void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum,
320 raw_ostream &O) {
321 const MCOperand &MO1 = MI->getOperand(OpNum);
322 O << "[" << getRegisterName(MO1.getReg()) << "]";
317323 }
318324
319325 void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI,
5050 void printLdStmModeOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
5151 void printAddrMode5Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
5252 void printAddrMode6Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
53 void printAddrMode7Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
5354 void printAddrMode6OffsetOperand(const MCInst *MI, unsigned OpNum,
5455 raw_ostream &O);
5556
283283
284284 @ CHECK: add r1, r2, r3, lsl r4 @ encoding: [0x13,0x14,0x82,0xe0]
285285 add r1, r2, r3, lsl r4
286
287 @ CHECK: strexb r0, r1, [r2] @ encoding: [0x91,0x0f,0xc2,0xe1]
288 strexb r0, r1, [r2]
289
290 @ CHECK: strexh r0, r1, [r2] @ encoding: [0x91,0x0f,0xe2,0xe1]
291 strexh r0, r1, [r2]
292
293 @ CHECK: strex r0, r1, [r2] @ encoding: [0x91,0x0f,0x82,0xe1]
294 strex r0, r1, [r2]
295
296 @ CHECK: strexd r0, r2, r3, [r1] @ encoding: [0x92,0x0f,0xa1,0xe1]
297 strexd r0, r2, r3, [r1]
298
299 @ CHECK: ldrexb r0, [r0] @ encoding: [0x9f,0x0f,0xd0,0xe1]
300 ldrexb r0, [r0]
301
302 @ CHECK: ldrexh r0, [r0] @ encoding: [0x9f,0x0f,0xf0,0xe1]
303 ldrexh r0, [r0]
304
305 @ CHECK: ldrex r0, [r0] @ encoding: [0x9f,0x0f,0x90,0xe1]
306 ldrex r0, [r0]
307
308 @ CHECK: ldrexd r0, r1, [r0] @ encoding: [0x9f,0x0f,0xb0,0xe1]
309 ldrexd r0, r1, [r0]
310
283283 @ CHECK: msr cpsr_fsxc, r0 @ encoding: [0x80,0xf3,0x00,0x8f]
284284 msr cpsr_fsxc, r0
285285
286 @ CHECK: strexb r0, r1, [r2] @ encoding: [0xc2,0xe8,0x40,0x1f]
287 strexb r0, r1, [r2]
288 @ CHECK: strexh r0, r1, [r2] @ encoding: [0xc2,0xe8,0x50,0x1f]
289 strexh r0, r1, [r2]
290 @ CHECK: strex r0, r1, [r2] @ encoding: [0x42,0xe8,0x00,0x10]
291 strex r0, r1, [r2]
292 @ CHECK: strexd r0, r2, r3, [r1] @ encoding: [0xc1,0xe8,0x70,0x23]
293 strexd r0, r2, r3, [r1]
294 @ CHECK: ldrexb r0, [r0] @ encoding: [0xd0,0xe8,0x4f,0x0f]
295 ldrexb r0, [r0]
296 @ CHECK: ldrexh r0, [r0] @ encoding: [0xd0,0xe8,0x5f,0x0f]
297 ldrexh r0, [r0]
298 @ CHECK: ldrex r0, [r0] @ encoding: [0x50,0xe8,0x00,0x0f]
299 ldrex r0, [r0]
300 @ CHECK: ldrexd r0, r1, [r0] @ encoding: [0xd0,0xe8,0x7f,0x01]
301 ldrexd r0, r1, [r0]
636636 MISC("am6offset", "kOperandTypeARMAddrMode6Offset"); // R, I, I
637637 MISC("addrmode6dup", "kOperandTypeARMAddrMode6"); // R, R, I, I
638638 MISC("addrmodepc", "kOperandTypeARMAddrModePC"); // R, I
639 MISC("addrmode7", "kOperandTypeARMAddrMode7"); // R
639640 MISC("reglist", "kOperandTypeARMRegisterList"); // I, R, ...
640641 MISC("dpr_reglist", "kOperandTypeARMDPRRegisterList"); // I, R, ...
641642 MISC("spr_reglist", "kOperandTypeARMSPRRegisterList"); // I, R, ...
642643 MISC("it_mask", "kOperandTypeThumbITMask"); // I
644 MISC("t2addrmode_reg", "kOperandTypeThumb2AddrModeReg"); // R
643645 MISC("t2addrmode_imm8", "kOperandTypeThumb2AddrModeImm8"); // R, I
644646 MISC("t2am_imm8_offset", "kOperandTypeThumb2AddrModeImm8Offset");//I
645647 MISC("t2addrmode_imm12", "kOperandTypeThumb2AddrModeImm12"); // R, I
857859 operandTypes.addEntry("kOperandTypeARMAddrMode5");
858860 operandTypes.addEntry("kOperandTypeARMAddrMode6");
859861 operandTypes.addEntry("kOperandTypeARMAddrMode6Offset");
862 operandTypes.addEntry("kOperandTypeARMAddrMode7");
860863 operandTypes.addEntry("kOperandTypeARMAddrModePC");
861864 operandTypes.addEntry("kOperandTypeARMRegisterList");
862865 operandTypes.addEntry("kOperandTypeARMDPRRegisterList");
868871 operandTypes.addEntry("kOperandTypeThumbAddrModeRR");
869872 operandTypes.addEntry("kOperandTypeThumbAddrModeSP");
870873 operandTypes.addEntry("kOperandTypeThumbAddrModePC");
874 operandTypes.addEntry("kOperandTypeThumb2AddrModeReg");
871875 operandTypes.addEntry("kOperandTypeThumb2SoReg");
872876 operandTypes.addEntry("kOperandTypeThumb2SoImm");
873877 operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8");