LEFT | RIGHT |
1 //===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===// | 1 //===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file describes the ARM instructions in TableGen format. | 10 // This file describes the ARM instructions in TableGen format. |
(...skipping 15 matching lines...) Expand all Loading... |
26 def SDT_ARMCMov : SDTypeProfile<1, 3, | 26 def SDT_ARMCMov : SDTypeProfile<1, 3, |
27 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, | 27 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, |
28 SDTCisVT<3, i32>]>; | 28 SDTCisVT<3, i32>]>; |
29 | 29 |
30 def SDT_ARMBrcond : SDTypeProfile<0, 2, | 30 def SDT_ARMBrcond : SDTypeProfile<0, 2, |
31 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>; | 31 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>; |
32 | 32 |
33 def SDT_ARMBrJT : SDTypeProfile<0, 3, | 33 def SDT_ARMBrJT : SDTypeProfile<0, 3, |
34 [SDTCisPtrTy<0>, SDTCisVT<1, i32>, | 34 [SDTCisPtrTy<0>, SDTCisVT<1, i32>, |
35 SDTCisVT<2, i32>]>; | 35 SDTCisVT<2, i32>]>; |
| 36 |
| 37 def SDT_ARMBr2JT : SDTypeProfile<0, 4, |
| 38 [SDTCisPtrTy<0>, SDTCisVT<1, i32>, |
| 39 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; |
36 | 40 |
37 def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; | 41 def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; |
38 | 42 |
39 def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, | 43 def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, |
40 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>; | 44 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>; |
41 | 45 |
42 def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; | 46 def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; |
43 def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>; | 47 def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>; |
44 | 48 |
45 // Node definitions. | 49 // Node definitions. |
(...skipping 17 matching lines...) Expand all Loading... |
63 | 67 |
64 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov, | 68 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov, |
65 [SDNPInFlag]>; | 69 [SDNPInFlag]>; |
66 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov, | 70 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov, |
67 [SDNPInFlag]>; | 71 [SDNPInFlag]>; |
68 | 72 |
69 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond, | 73 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond, |
70 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; | 74 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; |
71 | 75 |
72 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT, | 76 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT, |
| 77 [SDNPHasChain]>; |
| 78 def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT, |
73 [SDNPHasChain]>; | 79 [SDNPHasChain]>; |
74 | 80 |
75 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp, | 81 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp, |
76 [SDNPOutFlag]>; | 82 [SDNPOutFlag]>; |
77 | 83 |
78 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp, | 84 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp, |
79 [SDNPOutFlag,SDNPCommutative]>; | 85 [SDNPOutFlag,SDNPCommutative]>; |
80 | 86 |
81 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>; | 87 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>; |
82 | 88 |
83 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>; | 89 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>; |
84 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>; | 90 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>; |
85 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>; | 91 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>; |
86 | 92 |
87 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>; | 93 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>; |
88 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>; | 94 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>; |
89 | 95 |
90 //===----------------------------------------------------------------------===// | 96 //===----------------------------------------------------------------------===// |
91 // ARM Instruction Predicate Definitions. | 97 // ARM Instruction Predicate Definitions. |
92 // | 98 // |
93 def HasV5T : Predicate<"Subtarget->hasV5TOps()">; | 99 def HasV5T : Predicate<"Subtarget->hasV5TOps()">; |
94 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">; | 100 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">; |
95 def HasV6 : Predicate<"Subtarget->hasV6Ops()">; | 101 def HasV6 : Predicate<"Subtarget->hasV6Ops()">; |
96 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">; | 102 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">; |
97 def HasV7 : Predicate<"Subtarget->hasV7Ops()">; | 103 def HasV7 : Predicate<"Subtarget->hasV7Ops()">; |
98 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">; | 104 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">; |
99 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">; | 105 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">; |
100 def HasNEON : Predicate<"Subtarget->hasNEON()">; | 106 def HasNEON : Predicate<"Subtarget->hasNEON()">; |
| 107 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">; |
| 108 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">; |
101 def IsThumb : Predicate<"Subtarget->isThumb()">; | 109 def IsThumb : Predicate<"Subtarget->isThumb()">; |
102 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">; | 110 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">; |
103 def IsThumb2 : Predicate<"Subtarget->isThumb2()">; | 111 def IsThumb2 : Predicate<"Subtarget->isThumb2()">; |
104 def IsARM : Predicate<"!Subtarget->isThumb()">; | 112 def IsARM : Predicate<"!Subtarget->isThumb()">; |
105 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">; | 113 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">; |
106 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">; | 114 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">; |
107 def CarryDefIsUnused : Predicate<"!N.getNode()->hasAnyUseOfValue(1)">; | 115 def CarryDefIsUnused : Predicate<"!N.getNode()->hasAnyUseOfValue(1)">; |
108 def CarryDefIsUsed : Predicate<"N.getNode()->hasAnyUseOfValue(1)">; | 116 def CarryDefIsUsed : Predicate<"N.getNode()->hasAnyUseOfValue(1)">; |
109 | 117 |
110 //===----------------------------------------------------------------------===// | 118 //===----------------------------------------------------------------------===// |
(...skipping 28 matching lines...) Expand all Loading... |
139 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15]. | 147 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15]. |
140 def imm1_15 : PatLeaf<(i32 imm), [{ | 148 def imm1_15 : PatLeaf<(i32 imm), [{ |
141 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16; | 149 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16; |
142 }]>; | 150 }]>; |
143 | 151 |
144 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31]. | 152 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31]. |
145 def imm16_31 : PatLeaf<(i32 imm), [{ | 153 def imm16_31 : PatLeaf<(i32 imm), [{ |
146 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32; | 154 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32; |
147 }]>; | 155 }]>; |
148 | 156 |
149 def so_imm_neg : | 157 def so_imm_neg : |
150 PatLeaf<(imm), [{ | 158 PatLeaf<(imm), [{ |
151 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1; | 159 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1; |
152 }], so_imm_neg_XFORM>; | 160 }], so_imm_neg_XFORM>; |
153 | 161 |
154 def so_imm_not : | 162 def so_imm_not : |
155 PatLeaf<(imm), [{ | 163 PatLeaf<(imm), [{ |
156 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1; | 164 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1; |
157 }], so_imm_not_XFORM>; | 165 }], so_imm_not_XFORM>; |
158 | 166 |
159 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits. | 167 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits. |
160 def sext_16_node : PatLeaf<(i32 GPR:$a), [{ | 168 def sext_16_node : PatLeaf<(i32 GPR:$a), [{ |
161 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17; | 169 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17; |
162 }]>; | 170 }]>; |
163 | 171 |
164 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield | 172 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield |
165 /// e.g., 0xf000ffff | 173 /// e.g., 0xf000ffff |
166 def bf_inv_mask_imm : Operand<i32>, | 174 def bf_inv_mask_imm : Operand<i32>, |
167 PatLeaf<(imm), [{ | 175 PatLeaf<(imm), [{ |
168 uint32_t v = (uint32_t)N->getZExtValue(); | 176 uint32_t v = (uint32_t)N->getZExtValue(); |
169 if (v == 0xffffffff) | 177 if (v == 0xffffffff) |
170 return 0; | 178 return 0; |
171 // there can be 1's on either or both "outsides", all the "inside" | 179 // there can be 1's on either or both "outsides", all the "inside" |
172 // bits must be 0's | 180 // bits must be 0's |
173 unsigned int lsb = 0, msb = 31; | 181 unsigned int lsb = 0, msb = 31; |
174 while (v & (1 << msb)) --msb; | 182 while (v & (1 << msb)) --msb; |
175 while (v & (1 << lsb)) ++lsb; | 183 while (v & (1 << lsb)) ++lsb; |
176 for (unsigned int i = lsb; i <= msb; ++i) { | 184 for (unsigned int i = lsb; i <= msb; ++i) { |
177 if (v & (1 << i)) | 185 if (v & (1 << i)) |
(...skipping 19 matching lines...) Expand all Loading... |
197 let PrintMethod = "printRegisterList"; | 205 let PrintMethod = "printRegisterList"; |
198 } | 206 } |
199 | 207 |
200 // An operand for the CONSTPOOL_ENTRY pseudo-instruction. | 208 // An operand for the CONSTPOOL_ENTRY pseudo-instruction. |
201 def cpinst_operand : Operand<i32> { | 209 def cpinst_operand : Operand<i32> { |
202 let PrintMethod = "printCPInstOperand"; | 210 let PrintMethod = "printCPInstOperand"; |
203 } | 211 } |
204 | 212 |
205 def jtblock_operand : Operand<i32> { | 213 def jtblock_operand : Operand<i32> { |
206 let PrintMethod = "printJTBlockOperand"; | 214 let PrintMethod = "printJTBlockOperand"; |
| 215 } |
| 216 def jt2block_operand : Operand<i32> { |
| 217 let PrintMethod = "printJT2BlockOperand"; |
207 } | 218 } |
208 | 219 |
209 // Local PC labels. | 220 // Local PC labels. |
210 def pclabel : Operand<i32> { | 221 def pclabel : Operand<i32> { |
211 let PrintMethod = "printPCLabel"; | 222 let PrintMethod = "printPCLabel"; |
212 } | 223 } |
213 | 224 |
214 // shifter_operand operands: so_reg and so_imm. | 225 // shifter_operand operands: so_reg and so_imm. |
215 def so_reg : Operand<i32>, // reg reg imm | 226 def so_reg : Operand<i32>, // reg reg imm |
216 ComplexPattern<i32, 3, "SelectShifterOperandReg", | 227 ComplexPattern<i32, 3, "SelectShifterOperandReg", |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx, | 503 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx, |
493 i32imm:$size), | 504 i32imm:$size), |
494 "${instid:label} ${cpidx:cpentry}", []>; | 505 "${instid:label} ${cpidx:cpentry}", []>; |
495 | 506 |
496 let Defs = [SP], Uses = [SP] in { | 507 let Defs = [SP], Uses = [SP] in { |
497 def ADJCALLSTACKUP : | 508 def ADJCALLSTACKUP : |
498 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), | 509 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), |
499 "@ ADJCALLSTACKUP $amt1", | 510 "@ ADJCALLSTACKUP $amt1", |
500 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>; | 511 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>; |
501 | 512 |
502 def ADJCALLSTACKDOWN : | 513 def ADJCALLSTACKDOWN : |
503 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), | 514 PseudoInst<(outs), (ins i32imm:$amt, pred:$p), |
504 "@ ADJCALLSTACKDOWN $amt", | 515 "@ ADJCALLSTACKDOWN $amt", |
505 [(ARMcallseq_start timm:$amt)]>; | 516 [(ARMcallseq_start timm:$amt)]>; |
506 } | 517 } |
507 | 518 |
508 def DWARF_LOC : | 519 def DWARF_LOC : |
509 PseudoInst<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file), | 520 PseudoInst<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file), |
510 ".loc $file, $line, $col", | 521 ".loc $file, $line, $col", |
511 [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>; | 522 [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>; |
512 | 523 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), | 562 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), |
552 Pseudo, "${addr:label}:\n\tstr${p}b $src, $addr", | 563 Pseudo, "${addr:label}:\n\tstr${p}b $src, $addr", |
553 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>; | 564 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>; |
554 } | 565 } |
555 } // isNotDuplicable = 1 | 566 } // isNotDuplicable = 1 |
556 | 567 |
557 | 568 |
558 // LEApcrel - Load a pc-relative address into a register without offending the | 569 // LEApcrel - Load a pc-relative address into a register without offending the |
559 // assembler. | 570 // assembler. |
560 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p), Pseudo, | 571 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p), Pseudo, |
561 !strconcat(!strconcat(".set PCRELV${:uid}, ($label-(", | 572 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(", |
562 "${:private}PCRELL${:uid}+8))\n"), | 573 "${:private}PCRELL${:uid}+8))\n"), |
563 !strconcat("${:private}PCRELL${:uid}:\n\t", | 574 !strconcat("${:private}PCRELL${:uid}:\n\t", |
564 "add$p $dst, pc, #PCRELV${:uid}")), | 575 "add$p $dst, pc, #${:private}PCRELV${:uid}")), |
565 []>; | 576 []>; |
566 | 577 |
567 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst), | 578 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst), |
568 (ins i32imm:$label, i32imm:$id, pred:$p), | 579 (ins i32imm:$label, i32imm:$id, pred:$p), |
569 Pseudo, | 580 Pseudo, |
570 !strconcat(!strconcat(".set PCRELV${:uid}, (${label}_${id:no_hash}-(", | 581 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, " |
571 "${:private}PCRELL${:uid}+8))\n"), | 582 "(${label}_${id:no_hash}-(", |
572 !strconcat("${:private}PCRELL${:uid}:\n\t", | 583 "${:private}PCRELL${:uid}+8))\n"), |
573 "add$p $dst, pc, #PCRELV${:uid}")), | 584 !strconcat("${:private}PCRELL${:uid}:\n\t", |
| 585 "add$p $dst, pc, #${:private}PCRELV${:uid}")), |
574 []> { | 586 []> { |
575 let Inst{25} = 1; | 587 let Inst{25} = 1; |
576 } | 588 } |
577 | 589 |
578 //===----------------------------------------------------------------------===// | 590 //===----------------------------------------------------------------------===// |
579 // Control Flow Instructions. | 591 // Control Flow Instructions. |
580 // | 592 // |
581 | 593 |
582 let isReturn = 1, isTerminator = 1 in | 594 let isReturn = 1, isTerminator = 1 in |
583 def BX_RET : AI<(outs), (ins), BrMiscFrm, "bx", " lr", [(ARMretflag)]> { | 595 def BX_RET : AI<(outs), (ins), BrMiscFrm, "bx", " lr", [(ARMretflag)]> { |
584 let Inst{7-4} = 0b0001; | 596 let Inst{7-4} = 0b0001; |
585 let Inst{19-8} = 0b111111111111; | 597 let Inst{19-8} = 0b111111111111; |
586 let Inst{27-20} = 0b00010010; | 598 let Inst{27-20} = 0b00010010; |
587 } | 599 } |
588 | 600 |
589 // Indirect branches | 601 // Indirect branches (e.g. for jump tables) |
590 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { | 602 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { |
591 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, "bx $dst", | 603 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, "bx $dst", |
592 [(brind GPR:$dst)]> { | 604 [(brind GPR:$dst)]> { |
593 let Inst{7-4} = 0b0001; | 605 let Inst{7-4} = 0b0001; |
594 let Inst{19-8} = 0b111111111111; | 606 let Inst{19-8} = 0b111111111111; |
595 let Inst{27-20} = 0b00010010; | 607 let Inst{27-20} = 0b00010010; |
596 } | 608 } |
597 } | 609 } |
598 | 610 |
599 // FIXME: remove when we have a way to marking a MI with these properties. | 611 // FIXME: remove when we have a way to marking a MI with these properties. |
600 // FIXME: $dst1 should be a def. But the extra ops must be in the end of the | 612 // FIXME: $dst1 should be a def. But the extra ops must be in the end of the |
601 // operand list. | 613 // operand list. |
602 // FIXME: Should pc be an implicit operand like PICADD, etc? | 614 // FIXME: Should pc be an implicit operand like PICADD, etc? |
603 let isReturn = 1, isTerminator = 1, mayLoad = 1 in | 615 let isReturn = 1, isTerminator = 1, mayLoad = 1 in |
604 def LDM_RET : AXI4ld<(outs), | 616 def LDM_RET : AXI4ld<(outs), |
605 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops), | 617 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops), |
606 LdStMulFrm, "ldm${p}${addr:submode} $addr, $dst1", | 618 LdStMulFrm, "ldm${p}${addr:submode} $addr, $dst1", |
607 []>; | 619 []>; |
608 | 620 |
609 // On non-Darwin platforms R9 is callee-saved. | 621 // On non-Darwin platforms R9 is callee-saved. |
610 let isCall = 1, Itinerary = IIC_Br, | 622 let isCall = 1, Itinerary = IIC_Br, |
611 Defs = [R0, R1, R2, R3, R12, LR, | 623 Defs = [R0, R1, R2, R3, R12, LR, |
612 D0, D1, D2, D3, D4, D5, D6, D7, CPSR] in { | 624 D0, D1, D2, D3, D4, D5, D6, D7, |
| 625 D16, D17, D18, D19, D20, D21, D22, D23, |
| 626 D24, D25, D26, D27, D28, D29, D30, D31, CPSR] in { |
613 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops), | 627 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops), |
614 "bl ${func:call}", | 628 "bl ${func:call}", |
615 [(ARMcall tglobaladdr:$func)]>, Requires<[IsNotDarwin]>; | 629 [(ARMcall tglobaladdr:$func)]>, |
| 630 Requires<[IsARM, IsNotDarwin]>; |
616 | 631 |
617 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops), | 632 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops), |
618 "bl", " ${func:call}", | 633 "bl", " ${func:call}", |
619 [(ARMcall_pred tglobaladdr:$func)]>, Requires<[IsNotDarwin]>; | 634 [(ARMcall_pred tglobaladdr:$func)]>, |
| 635 Requires<[IsARM, IsNotDarwin]>; |
620 | 636 |
621 // ARMv5T and above | 637 // ARMv5T and above |
622 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm, | 638 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm, |
623 "blx $func", | 639 "blx $func", |
624 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsNotDarwin]> { | 640 [(ARMcall GPR:$func)]>, |
| 641 Requires<[IsARM, HasV5T, IsNotDarwin]> { |
625 let Inst{7-4} = 0b0011; | 642 let Inst{7-4} = 0b0011; |
626 let Inst{19-8} = 0b111111111111; | 643 let Inst{19-8} = 0b111111111111; |
627 let Inst{27-20} = 0b00010010; | 644 let Inst{27-20} = 0b00010010; |
628 } | 645 } |
629 | 646 |
630 // ARMv4T | 647 // ARMv4T |
631 def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops), | 648 def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops), |
632 "mov lr, pc\n\tbx $func", | 649 "mov lr, pc\n\tbx $func", |
633 [(ARMcall_nolink GPR:$func)]>, Requires<[IsNotDarwin]> { | 650 [(ARMcall_nolink GPR:$func)]>, |
| 651 Requires<[IsARM, IsNotDarwin]> { |
634 let Inst{7-4} = 0b0001; | 652 let Inst{7-4} = 0b0001; |
635 let Inst{19-8} = 0b111111111111; | 653 let Inst{19-8} = 0b111111111111; |
636 let Inst{27-20} = 0b00010010; | 654 let Inst{27-20} = 0b00010010; |
637 } | 655 } |
638 } | 656 } |
639 | 657 |
640 // On Darwin R9 is call-clobbered. | 658 // On Darwin R9 is call-clobbered. |
641 let isCall = 1, Itinerary = IIC_Br, | 659 let isCall = 1, Itinerary = IIC_Br, |
642 Defs = [R0, R1, R2, R3, R9, R12, LR, | 660 Defs = [R0, R1, R2, R3, R9, R12, LR, |
643 D0, D1, D2, D3, D4, D5, D6, D7, CPSR] in { | 661 D0, D1, D2, D3, D4, D5, D6, D7, |
| 662 D16, D17, D18, D19, D20, D21, D22, D23, |
| 663 D24, D25, D26, D27, D28, D29, D30, D31, CPSR] in { |
644 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops), | 664 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops), |
645 "bl ${func:call}", | 665 "bl ${func:call}", |
646 [(ARMcall tglobaladdr:$func)]>, Requires<[IsDarwin]>; | 666 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]>; |
647 | 667 |
648 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops), | 668 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops), |
649 "bl", " ${func:call}", | 669 "bl", " ${func:call}", |
650 [(ARMcall_pred tglobaladdr:$func)]>, Requires<[IsDarwin]>; | 670 [(ARMcall_pred tglobaladdr:$func)]>, |
| 671 Requires<[IsARM, IsDarwin]>; |
651 | 672 |
652 // ARMv5T and above | 673 // ARMv5T and above |
653 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm, | 674 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm, |
654 "blx $func", | 675 "blx $func", |
655 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> { | 676 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> { |
656 let Inst{7-4} = 0b0011; | 677 let Inst{7-4} = 0b0011; |
657 let Inst{19-8} = 0b111111111111; | 678 let Inst{19-8} = 0b111111111111; |
658 let Inst{27-20} = 0b00010010; | 679 let Inst{27-20} = 0b00010010; |
659 } | 680 } |
660 | 681 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
700 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt, | 721 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt, |
701 imm:$id)]> { | 722 imm:$id)]> { |
702 let Inst{20} = 0; // S bit | 723 let Inst{20} = 0; // S bit |
703 let Inst{24-21} = 0b0100; | 724 let Inst{24-21} = 0b0100; |
704 let Inst{27-25} = 0b000; | 725 let Inst{27-25} = 0b000; |
705 } | 726 } |
706 } // isNotDuplicable = 1, isIndirectBranch = 1 | 727 } // isNotDuplicable = 1, isIndirectBranch = 1 |
707 } // isBarrier = 1 | 728 } // isBarrier = 1 |
708 | 729 |
709 // FIXME: should be able to write a pattern for ARMBrcond, but can't use | 730 // FIXME: should be able to write a pattern for ARMBrcond, but can't use |
710 // a two-value operand where a dag node expects two operands. :( | 731 // a two-value operand where a dag node expects two operands. :( |
711 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target), | 732 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target), |
712 "b", " $target", | 733 "b", " $target", |
713 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>; | 734 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>; |
714 } | 735 } |
715 | 736 |
716 //===----------------------------------------------------------------------===// | 737 //===----------------------------------------------------------------------===// |
717 // Load / store Instructions. | 738 // Load / store Instructions. |
718 // | 739 // |
719 | 740 |
720 // Load | 741 // Load |
721 let canFoldAsLoad = 1 in | 742 let canFoldAsLoad = 1 in |
722 def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, | 743 def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, |
723 "ldr", " $dst, $addr", | 744 "ldr", " $dst, $addr", |
724 [(set GPR:$dst, (load addrmode2:$addr))]>; | 745 [(set GPR:$dst, (load addrmode2:$addr))]>; |
725 | 746 |
726 // Special LDR for loads from non-pc-relative constpools. | 747 // Special LDR for loads from non-pc-relative constpools. |
727 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in | 748 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in |
728 def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, | 749 def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, |
729 "ldr", " $dst, $addr", []>; | 750 "ldr", " $dst, $addr", []>; |
730 | 751 |
731 // Loads with zero extension | 752 // Loads with zero extension |
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1344 | 1365 |
1345 def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm), | 1366 def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm), |
1346 (CMNri GPR:$src, so_imm_neg:$imm)>; | 1367 (CMNri GPR:$src, so_imm_neg:$imm)>; |
1347 | 1368 |
1348 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm), | 1369 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm), |
1349 (CMNri GPR:$src, so_imm_neg:$imm)>; | 1370 (CMNri GPR:$src, so_imm_neg:$imm)>; |
1350 | 1371 |
1351 | 1372 |
1352 // Conditional moves | 1373 // Conditional moves |
1353 // FIXME: should be able to write a pattern for ARMcmov, but can't use | 1374 // FIXME: should be able to write a pattern for ARMcmov, but can't use |
1354 // a two-value operand where a dag node expects two operands. :( | 1375 // a two-value operand where a dag node expects two operands. :( |
1355 def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm, | 1376 def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm, |
1356 "mov", " $dst, $true", | 1377 "mov", " $dst, $true", |
1357 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>, | 1378 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>, |
1358 RegConstraint<"$false = $dst">, UnaryDP; | 1379 RegConstraint<"$false = $dst">, UnaryDP; |
1359 | 1380 |
1360 def MOVCCs : AI1<0b1101, (outs GPR:$dst), | 1381 def MOVCCs : AI1<0b1101, (outs GPR:$dst), |
1361 (ins GPR:$false, so_reg:$true), DPSoRegFrm, | 1382 (ins GPR:$false, so_reg:$true), DPSoRegFrm, |
1362 "mov", " $dst, $true", | 1383 "mov", " $dst, $true", |
1363 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>, | 1384 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>, |
1364 RegConstraint<"$false = $dst">, UnaryDP; | 1385 RegConstraint<"$false = $dst">, UnaryDP; |
(...skipping 12 matching lines...) Expand all Loading... |
1377 // __aeabi_read_tp preserves the registers r1-r3. | 1398 // __aeabi_read_tp preserves the registers r1-r3. |
1378 let isCall = 1, | 1399 let isCall = 1, |
1379 Defs = [R0, R12, LR, CPSR] in { | 1400 Defs = [R0, R12, LR, CPSR] in { |
1380 def TPsoft : ABXI<0b1011, (outs), (ins), | 1401 def TPsoft : ABXI<0b1011, (outs), (ins), |
1381 "bl __aeabi_read_tp", | 1402 "bl __aeabi_read_tp", |
1382 [(set R0, ARMthread_pointer)]>; | 1403 [(set R0, ARMthread_pointer)]>; |
1383 } | 1404 } |
1384 | 1405 |
1385 //===----------------------------------------------------------------------===// | 1406 //===----------------------------------------------------------------------===// |
1386 // SJLJ Exception handling intrinsics | 1407 // SJLJ Exception handling intrinsics |
1387 // eh_sjlj_setjmp() is a three instruction sequence to store the return | 1408 // eh_sjlj_setjmp() is a three instruction sequence to store the return |
1388 // address and save #0 in R0 for the non-longjmp case. | 1409 // address and save #0 in R0 for the non-longjmp case. |
1389 // Since by its nature we may be coming from some other function to get | 1410 // Since by its nature we may be coming from some other function to get |
1390 // here, and we're using the stack frame for the containing function to | 1411 // here, and we're using the stack frame for the containing function to |
1391 // save/restore registers, we can't keep anything live in regs across | 1412 // save/restore registers, we can't keep anything live in regs across |
1392 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon | 1413 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon |
1393 // when we get here from a longjmp(). We force everthing out of registers | 1414 // when we get here from a longjmp(). We force everthing out of registers |
1394 // except for our own input by listing the relevant registers in Defs. By | 1415 // except for our own input by listing the relevant registers in Defs. By |
1395 // doing so, we also cause the prologue/epilogue code to actively preserve | 1416 // doing so, we also cause the prologue/epilogue code to actively preserve |
1396 // all of the callee-saved resgisters, which is exactly what we want. | 1417 // all of the callee-saved resgisters, which is exactly what we want. |
1397 let Defs = | 1418 let Defs = |
1398 [ R0, R1, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, | 1419 [ R0, R1, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, |
1399 D0, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15 ] in { | 1420 D0, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, |
| 1421 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, |
| 1422 D31 ] in { |
1400 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src), | 1423 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src), |
1401 AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, | 1424 AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, |
1402 "add r0, pc, #4\n\t" | 1425 "add r0, pc, #4\n\t" |
1403 "str r0, [$src, #+4]\n\t" | 1426 "str r0, [$src, #+4]\n\t" |
1404 "mov r0, #0 @ eh_setjmp", "", | 1427 "mov r0, #0 @ eh_setjmp", "", |
1405 [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>; | 1428 [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>; |
1406 } | 1429 } |
1407 | 1430 |
1408 //===----------------------------------------------------------------------===// | 1431 //===----------------------------------------------------------------------===// |
1409 // Non-Instruction Patterns | 1432 // Non-Instruction Patterns |
(...skipping 18 matching lines...) Expand all Loading... |
1428 (so_imm2part_2 imm:$RHS))>; | 1451 (so_imm2part_2 imm:$RHS))>; |
1429 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS), | 1452 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS), |
1430 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)), | 1453 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)), |
1431 (so_imm2part_2 imm:$RHS))>; | 1454 (so_imm2part_2 imm:$RHS))>; |
1432 | 1455 |
1433 // TODO: add,sub,and, 3-instr forms? | 1456 // TODO: add,sub,and, 3-instr forms? |
1434 | 1457 |
1435 | 1458 |
1436 // Direct calls | 1459 // Direct calls |
1437 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>, | 1460 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>, |
1438 Requires<[IsNotDarwin]>; | 1461 Requires<[IsARM, IsNotDarwin]>; |
1439 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>, | 1462 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>, |
1440 Requires<[IsDarwin]>; | 1463 Requires<[IsARM, IsDarwin]>; |
1441 | 1464 |
1442 // zextload i1 -> zextload i8 | 1465 // zextload i1 -> zextload i8 |
1443 def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>; | 1466 def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>; |
1444 | 1467 |
1445 // extload -> zextload | 1468 // extload -> zextload |
1446 def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>; | 1469 def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>; |
1447 def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>; | 1470 def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>; |
1448 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>; | 1471 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>; |
1449 | 1472 |
1450 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>; | 1473 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1517 // Floating Point Support | 1540 // Floating Point Support |
1518 // | 1541 // |
1519 | 1542 |
1520 include "ARMInstrVFP.td" | 1543 include "ARMInstrVFP.td" |
1521 | 1544 |
1522 //===----------------------------------------------------------------------===// | 1545 //===----------------------------------------------------------------------===// |
1523 // Advanced SIMD (NEON) Support | 1546 // Advanced SIMD (NEON) Support |
1524 // | 1547 // |
1525 | 1548 |
1526 include "ARMInstrNEON.td" | 1549 include "ARMInstrNEON.td" |
LEFT | RIGHT |