llvm.org GIT mirror llvm / b5523ce
Add AArch32 DCPS{1,2,3} and HLT instructions. These were pretty straightforward instructions, with some assembly support required for HLT. The ARM assembler is keen to split the instruction mnemonic into a (non-existent) 'H' instruction with the LT condition code. An exception for HLT is needed. HLT follows the same rules as BKPT when in IT blocks, so the special BKPT hadling code has been adapted to handle HLT also. Regression tests added including diagnostic tests for out of range immediates and illegal condition codes, as well as negative tests for pre-ARMv8. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190053 91177308-0d34-0410-b5e6-96231b3b80d8 Richard Barton 6 years ago
10 changed file(s) with 166 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
17531753 let Inst{3-0} = val{3-0};
17541754 let Inst{19-8} = val{15-4};
17551755 let Inst{27-20} = 0b00010010;
1756 let Inst{31-28} = 0xe; // AL
1757 let Inst{7-4} = 0b0111;
1758 }
1759
1760 def HLT : AInoP<(outs), (ins imm0_65535:$val), MiscFrm, NoItinerary,
1761 "hlt", "\t$val", []>, Requires<[IsARM, HasV8]> {
1762 bits<16> val;
1763 let Inst{3-0} = val{3-0};
1764 let Inst{19-8} = val{15-4};
1765 let Inst{27-20} = 0b00010000;
17561766 let Inst{31-28} = 0xe; // AL
17571767 let Inst{7-4} = 0b0111;
17581768 }
297297 // A8.6.22
298298 bits<8> val;
299299 let Inst{7-0} = val;
300 }
301
302 def tHLT : T1I<(outs), (ins imm0_63:$val), NoItinerary, "hlt\t$val",
303 []>, T1Encoding<0b101110>, Requires<[IsThumb, HasV8]> {
304 let Inst{9-6} = 0b1010;
305 bits<6> val;
306 let Inst{5-0} = val;
300307 }
301308
302309 def tSETEND : T1I<(outs), (ins setend_op:$end), NoItinerary, "setend\t$end",
36433643 bits<4> opt;
36443644 let Inst{19-16} = opt;
36453645 }
3646
3647 class T2DCPS opt, string opc>
3648 : T2I<(outs), (ins), NoItinerary, opc, "", []>, Requires<[IsThumb2, HasV8]> {
3649 let Inst{31-27} = 0b11110;
3650 let Inst{26-20} = 0b1111000;
3651 let Inst{19-16} = 0b1111;
3652 let Inst{15-12} = 0b1000;
3653 let Inst{11-2} = 0b0000000000;
3654 let Inst{1-0} = opt;
3655 }
3656
3657 def t2DCPS1 : T2DCPS<0b01, "dcps1">;
3658 def t2DCPS2 : T2DCPS<0b10, "dcps2">;
3659 def t2DCPS3 : T2DCPS<0b11, "dcps3">;
36463660
36473661 class T2SRS Op, bit W, dag oops, dag iops, InstrItinClass itin,
36483662 string opc, string asm, list pattern>
46864686 Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" ||
46874687 Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" ||
46884688 Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" ||
4689 Mnemonic == "vaclt" || Mnemonic == "vacle" ||
4689 Mnemonic == "vaclt" || Mnemonic == "vacle" || Mnemonic == "hlt" ||
46904690 Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" ||
46914691 Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" ||
46924692 Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal" ||
47924792
47934793 if (Mnemonic == "bkpt" || Mnemonic == "cbnz" || Mnemonic == "setend" ||
47944794 Mnemonic == "cps" || Mnemonic == "it" || Mnemonic == "cbz" ||
4795 Mnemonic == "trap" || Mnemonic == "setend" ||
4795 Mnemonic == "trap" || Mnemonic == "hlt" ||
47964796 Mnemonic.startswith("cps") || Mnemonic.startswith("vsel") ||
47974797 Mnemonic == "vmaxnm" || Mnemonic == "vminnm" || Mnemonic == "vcvta" ||
47984798 Mnemonic == "vcvtn" || Mnemonic == "vcvtp" || Mnemonic == "vcvtm" ||
52965296 return ARMInsts[Opcode];
52975297 }
52985298
5299 // Return true if instruction has the interesting property of being
5300 // allowed in IT blocks, but not being predicable.
5301 static bool instIsBreakpoint(const MCInst &Inst) {
5302 return Inst.getOpcode() == ARM::tBKPT ||
5303 Inst.getOpcode() == ARM::BKPT ||
5304 Inst.getOpcode() == ARM::tHLT ||
5305 Inst.getOpcode() == ARM::HLT;
5306
5307 }
5308
52995309 // FIXME: We would really like to be able to tablegen'erate this.
53005310 bool ARMAsmParser::
53015311 validateInstruction(MCInst &Inst,
53045314 SMLoc Loc = Operands[0]->getStartLoc();
53055315
53065316 // Check the IT block state first.
5307 // NOTE: BKPT instruction has the interesting property of being
5308 // allowed in IT blocks, but not being predicable. It just always
5309 // executes.
5310 if (inITBlock() && Inst.getOpcode() != ARM::tBKPT &&
5311 Inst.getOpcode() != ARM::BKPT) {
5317 // NOTE: BKPT and HLT instructions have the interesting property of being
5318 // allowed in IT blocks, but not being predicable. They just always
5319 // execute.
5320 if (inITBlock() && !instIsBreakpoint(Inst)) {
53125321 unsigned bit = 1;
53135322 if (ITState.FirstCond)
53145323 ITState.FirstCond = false;
0 @ New ARMv8 A32 encodings
1
2 @ RUN: llvm-mc -triple armv8 -show-encoding < %s | FileCheck %s --check-prefix=CHECK-V8
3 @ RUN: not llvm-mc -triple armv7 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-V7
4
5 @ HLT
6 hlt #0
7 hlt #65535
8 @ CHECK-V8: hlt #0 @ encoding: [0x70,0x00,0x00,0xe1]
9 @ CHECK-V8: hlt #65535 @ encoding: [0x7f,0xff,0x0f,0xe1]
10 @ CHECK-V7: error: instruction requires: armv8
11 @ CHECK-V7: error: instruction requires: armv8
12
13 @ AL condition code allowable
14 hltal #0
15 @ CHECK-V8: hlt #0 @ encoding: [0x70,0x00,0x00,0xe1]
16 @ CHECK-V7: error: instruction requires: armv8
0 @ New ARMv8 T32 encodings
1
2 @ RUN: llvm-mc -triple thumbv8 -show-encoding < %s | FileCheck %s --check-prefix=CHECK-V8
3 @ RUN: not llvm-mc -triple thumbv7 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-V7
4
5 @ HLT
6 hlt #0
7 hlt #63
8 @ CHECK-V8: hlt #0 @ encoding: [0x80,0xba]
9 @ CHECK-V8: hlt #63 @ encoding: [0xbf,0xba]
10 @ CHECK-V7: error: instruction requires: armv8
11 @ CHECK-V7: error: instruction requires: armv8
12
13 @ In IT block
14 it pl
15 hlt #24
16
17 @ CHECK-V8: it pl @ encoding: [0x58,0xbf]
18 @ CHECK-V8: hlt #24 @ encoding: [0x98,0xba]
19 @ CHECK-V7: error: instruction requires: armv8
20
21 @ Can accept AL condition code
22 hltal #24
23 @ CHECK-V8: hlt #24 @ encoding: [0x98,0xba]
24 @ CHECK-V7: error: instruction requires: armv8
25
26 @ DCPS{1,2,3}
27 dcps1
28 dcps2
29 dcps3
30 @ CHECK-V8: dcps1 @ encoding: [0x8f,0xf7,0x01,0x80]
31 @ CHECK-V8: dcps2 @ encoding: [0x8f,0xf7,0x02,0x80]
32 @ CHECK-V8: dcps3 @ encoding: [0x8f,0xf7,0x03,0x80]
33 @ CHECK-V7: error: instruction requires: armv8
34 @ CHECK-V7: error: instruction requires: armv8
35 @ CHECK-V7: error: instruction requires: armv8
0 @ RUN: not llvm-mc -triple=armv7-apple-darwin < %s 2> %t
11 @ RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s
2 @ RUN: not llvm-mc -triple=armv8 < %s 2> %t
3 @ RUN: FileCheck --check-prefix=CHECK-ERRORS-V8 < %t %s
24
35 @ Check for various assembly diagnostic messages on invalid input.
46
9193 bkpt #65536
9294
9395 @ CHECK-ERRORS: error: invalid operand for instruction
96
97 @ Out of range immediates for v8 HLT instruction.
98 hlt #65536
99 hlt #-1
100 @CHECK-ERRORS-V8: error: invalid operand for instruction
101 @CHECK-ERRORS-V8: hlt #65536
102 @CHECK-ERRORS-V8: ^
103 @CHECK-ERRORS-V8: error: invalid operand for instruction
104 @CHECK-ERRORS-V8: hlt #-1
105 @CHECK-ERRORS-V8: ^
106
107 @ Illegal condition code for v8 HLT instruction.
108 hlteq #2
109 hltlt #23
110 @CHECK-ERRORS-V8: error: instruction 'hlt' is not predicable, but condition code specified
111 @CHECK-ERRORS-V8: hlteq #2
112 @CHECK-ERRORS-V8: ^
113 @CHECK-ERRORS-V8: error: instruction 'hlt' is not predicable, but condition code specified
114 @CHECK-ERRORS-V8: hltlt #23
115 @CHECK-ERRORS-V8: ^
94116
95117 @ Out of range 4 and 3 bit immediates on CDP[2]
96118
11 @ RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s
22 @ RUN: not llvm-mc -triple=thumbv5-apple-darwin < %s 2> %t
33 @ RUN: FileCheck --check-prefix=CHECK-ERRORS-V5 < %t %s
4 @ RUN: not llvm-mc -triple=thumbv8 < %s 2> %t
5 @ RUN: FileCheck --check-prefix=CHECK-ERRORS-V8 < %t %s
46
57 @ Check for various assembly diagnostic messages on invalid input.
68
3638 error: invalid operand for instruction
3739 bkpt #-1
3840 ^
41
42 @ Out of range immediates for v8 HLT instruction.
43 hlt #64
44 hlt #-1
45 @CHECK-ERRORS: error: instruction requires: armv8 arm-mode
46 @CHECK-ERRORS: hlt #64
47 @CHECK-ERRORS: ^
48 @CHECK-ERRORS-V8: error: instruction requires: arm-mode
49 @CHECK-ERRORS-V8: hlt #64
50 @CHECK-ERRORS-V8: ^
51 @CHECK-ERRORS: error: invalid operand for instruction
52 @CHECK-ERRORS: hlt #-1
53 @CHECK-ERRORS: ^
3954
4055 @ Invalid writeback and register lists for LDM
4156 ldm r2!, {r5, r8}
0 # RUN: llvm-mc -disassemble -triple armv8 -show-encoding < %s | FileCheck %s
1
2 # New v8 ARM instructions
3
4 # HLT
5
6 0x70 0x00 0x00 0xe1
7 # CHECK: hlt #0
8
9 0x7f 0xff 0x0f 0xe1
10 # CHECK: hlt #65535
0 # RUN: llvm-mc -disassemble -triple thumbv8 -show-encoding < %s | FileCheck %s
1
2 0x80 0xba
3 # CHECK: hlt #0
4
5 0xbf 0xba
6 # CHECK: hlt #63
7
8 # DCPS{1,2,3}
9
10 0x8f 0xf7 0x01 0x80
11 # CHECK: dcps1
12
13 0x8f 0xf7 0x02 0x80
14 # CHECK: dcps2
15
16 0x8f 0xf7 0x03 0x80
17 # CHECK: dcps3