def AddrModeT1_2 : AddrMode<8>;
def AddrModeT1_4 : AddrMode<9>;
def AddrModeT1_s : AddrMode<10>;
-def AddrModeT2_i12: AddrMode<12>;
+def AddrModeT2_i12: AddrMode<11>;
def AddrModeT2_i8 : AddrMode<12>;
def AddrModeT2_so : AddrMode<13>;
def AddrModeT2_pc : AddrMode<14>;
//===----------------------------------------------------------------------===//
+// ARM special operands.
+//
+
+// ARM Predicate operand. Default to 14 = always (AL). Second part is CC
+// register whose default is 0 (no register).
+def pred : PredicateOperand<OtherVT, (ops i32imm, CCR),
+ (ops (i32 14), (i32 zero_reg))> {
+ let PrintMethod = "printPredicateOperand";
+}
+
+// Conditional code result for instructions whose 's' bit is set, e.g. subs.
+def cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 zero_reg))> {
+ let PrintMethod = "printSBitModifierOperand";
+}
+
+// Same as cc_out except it defaults to setting CPSR.
+def s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> {
+ let PrintMethod = "printSBitModifierOperand";
+}
+
+//===----------------------------------------------------------------------===//
+
// ARM Instruction templates.
//
let Inst{20} = 1; // L bit
let Inst{21} = 0; // W bit
let Inst{24} = 1; // P bit
+ let Inst{27-25} = 0b000;
}
class AXI3ldh<dag oops, dag iops, Format f, string asm,
list<dag> pattern>
let Inst{20} = 1; // L bit
let Inst{21} = 0; // W bit
let Inst{24} = 1; // P bit
+ let Inst{27-25} = 0b000;
}
class AXI3ldsh<dag oops, dag iops, Format f, string asm,
list<dag> pattern>
let Inst{20} = 1; // L bit
let Inst{21} = 0; // W bit
let Inst{24} = 1; // P bit
+ let Inst{27-25} = 0b000;
}
class AXI3ldsb<dag oops, dag iops, Format f, string asm,
list<dag> pattern>
let Inst{20} = 0; // L bit
let Inst{21} = 0; // W bit
let Inst{24} = 1; // P bit
+ let Inst{27-25} = 0b000;
}
// stores
let Inst{20} = 0; // L bit
let Inst{21} = 0; // W bit
let Inst{24} = 1; // P bit
+ let Inst{27-25} = 0b000;
}
class AXI3sth<dag oops, dag iops, Format f, string asm,
list<dag> pattern>
let Inst{20} = 0; // L bit
let Inst{21} = 0; // W bit
let Inst{24} = 1; // P bit
+ let Inst{27-25} = 0b000;
}
// Pre-indexed loads
let Inst{20} = 1; // L bit
let Inst{21} = 1; // W bit
let Inst{24} = 1; // P bit
+ let Inst{27-25} = 0b000;
}
class AI3ldshpr<dag oops, dag iops, Format f, string opc,
string asm, string cstr, list<dag> pattern>
let Inst{20} = 1; // L bit
let Inst{21} = 1; // W bit
let Inst{24} = 1; // P bit
+ let Inst{27-25} = 0b000;
}
class AI3ldsbpr<dag oops, dag iops, Format f, string opc,
string asm, string cstr, list<dag> pattern>
let Inst{20} = 1; // L bit
let Inst{21} = 1; // W bit
let Inst{24} = 1; // P bit
+ let Inst{27-25} = 0b000;
}
// Pre-indexed stores
let Inst{20} = 0; // L bit
let Inst{21} = 1; // W bit
let Inst{24} = 1; // P bit
+ let Inst{27-25} = 0b000;
}
// Post-indexed loads
let Inst{20} = 1; // L bit
let Inst{21} = 1; // W bit
let Inst{24} = 0; // P bit
+ let Inst{27-25} = 0b000;
}
class AI3ldshpo<dag oops, dag iops, Format f, string opc,
string asm, string cstr, list<dag> pattern>
let Inst{20} = 1; // L bit
let Inst{21} = 1; // W bit
let Inst{24} = 0; // P bit
+ let Inst{27-25} = 0b000;
}
class AI3ldsbpo<dag oops, dag iops, Format f, string opc,
string asm, string cstr, list<dag> pattern>
let Inst{20} = 1; // L bit
let Inst{21} = 1; // W bit
let Inst{24} = 0; // P bit
+ let Inst{27-25} = 0b000;
}
// Post-indexed stores
let Inst{20} = 0; // L bit
let Inst{21} = 1; // W bit
let Inst{24} = 0; // P bit
+ let Inst{27-25} = 0b000;
}
// TI - Thumb instruction.
-class ThumbI<dag outs, dag ins, AddrMode am, SizeFlagVal sz,
+class ThumbI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
string asm, string cstr, list<dag> pattern>
: InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
- let OutOperandList = outs;
- let InOperandList = ins;
+ let OutOperandList = oops;
+ let InOperandList = iops;
let AsmString = asm;
let Pattern = pattern;
list<Predicate> Predicates = [IsThumb];
}
-class TI<dag outs, dag ins, string asm, list<dag> pattern>
- : ThumbI<outs, ins, AddrModeNone, Size2Bytes, asm, "", pattern>;
+class TI<dag oops, dag iops, string asm, list<dag> pattern>
+ : ThumbI<oops, iops, AddrModeNone, Size2Bytes, asm, "", pattern>;
-// BL, BLX(1) are translated by assembler into two instructions
-class TIx2<dag outs, dag ins, string asm, list<dag> pattern>
- : ThumbI<outs, ins, AddrModeNone, Size4Bytes, asm, "", pattern>;
+// Two-address instructions
+class TIt<dag oops, dag iops, string asm, list<dag> pattern>
+ : ThumbI<oops, iops, AddrModeNone, Size2Bytes, asm, "$lhs = $dst", pattern>;
-// BR_JT instructions
-class TJTI<dag outs, dag ins, string asm, list<dag> pattern>
- : ThumbI<outs, ins, AddrModeNone, SizeSpecial, asm, "", pattern>;
+// tBL, tBX instructions
+class TIx2<dag oops, dag iops, string asm, list<dag> pattern>
+ : ThumbI<oops, iops, AddrModeNone, Size4Bytes, asm, "", pattern>;
-// TPat - Same as Pat<>, but requires that the compiler be in Thumb mode.
-class TPat<dag pattern, dag result> : Pat<pattern, result> {
- list<Predicate> Predicates = [IsThumb];
-}
-
-class Tv5Pat<dag pattern, dag result> : Pat<pattern, result> {
- list<Predicate> Predicates = [IsThumb, HasV5T];
-}
+// BR_JT instructions
+class TJTI<dag oops, dag iops, string asm, list<dag> pattern>
+ : ThumbI<oops, iops, AddrModeNone, SizeSpecial, asm, "", pattern>;
// Thumb1 only
-class Thumb1I<dag outs, dag ins, AddrMode am, SizeFlagVal sz,
+class Thumb1I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
string asm, string cstr, list<dag> pattern>
: InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
- let OutOperandList = outs;
- let InOperandList = ins;
+ let OutOperandList = oops;
+ let InOperandList = iops;
let AsmString = asm;
let Pattern = pattern;
list<Predicate> Predicates = [IsThumb1Only];
}
-class T1I<dag outs, dag ins, string asm, list<dag> pattern>
- : Thumb1I<outs, ins, AddrModeNone, Size2Bytes, asm, "", pattern>;
-class T1I1<dag outs, dag ins, string asm, list<dag> pattern>
- : Thumb1I<outs, ins, AddrModeT1_1, Size2Bytes, asm, "", pattern>;
-class T1I2<dag outs, dag ins, string asm, list<dag> pattern>
- : Thumb1I<outs, ins, AddrModeT1_2, Size2Bytes, asm, "", pattern>;
-class T1I4<dag outs, dag ins, string asm, list<dag> pattern>
- : Thumb1I<outs, ins, AddrModeT1_4, Size2Bytes, asm, "", pattern>;
-class T1Is<dag outs, dag ins, string asm, list<dag> pattern>
- : Thumb1I<outs, ins, AddrModeT1_s, Size2Bytes, asm, "", pattern>;
-class T1Ix2<dag outs, dag ins, string asm, list<dag> pattern>
- : Thumb1I<outs, ins, AddrModeNone, Size4Bytes, asm, "", pattern>;
-class T1JTI<dag outs, dag ins, string asm, list<dag> pattern>
- : Thumb1I<outs, ins, AddrModeNone, SizeSpecial, asm, "", pattern>;
+class T1I<dag oops, dag iops, string asm, list<dag> pattern>
+ : Thumb1I<oops, iops, AddrModeNone, Size2Bytes, asm, "", pattern>;
+class T1Ix2<dag oops, dag iops, string asm, list<dag> pattern>
+ : Thumb1I<oops, iops, AddrModeNone, Size4Bytes, asm, "", pattern>;
+class T1JTI<dag oops, dag iops, string asm, list<dag> pattern>
+ : Thumb1I<oops, iops, AddrModeNone, SizeSpecial, asm, "", pattern>;
// Two-address instructions
-class T1It<dag outs, dag ins, string asm, list<dag> pattern>
- : Thumb1I<outs, ins, AddrModeNone, Size2Bytes, asm, "$lhs = $dst", pattern>;
+class T1It<dag oops, dag iops, string asm, list<dag> pattern>
+ : Thumb1I<oops, iops, AddrModeNone, Size2Bytes, asm, "$lhs = $dst", pattern>;
-class T1Pat<dag pattern, dag result> : Pat<pattern, result> {
+// Thumb1 instruction that can either be predicated or set CPSR.
+class Thumb1sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
+ string opc, string asm, string cstr, list<dag> pattern>
+ : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
+ let OutOperandList = !con(oops, (ops s_cc_out:$s));
+ let InOperandList = !con(iops, (ops pred:$p));
+ let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm));
+ let Pattern = pattern;
+ list<Predicate> Predicates = [IsThumb1Only];
+}
+
+class T1sI<dag oops, dag iops, string opc, string asm, list<dag> pattern>
+ : Thumb1sI<oops, iops, AddrModeNone, Size2Bytes, opc, asm, "", pattern>;
+
+// Two-address instructions
+class T1sIt<dag oops, dag iops, string opc, string asm, list<dag> pattern>
+ : Thumb1sI<oops, iops, AddrModeNone, Size2Bytes, opc, asm,
+ "$lhs = $dst", pattern>;
+
+// Thumb1 instruction that can be predicated.
+class Thumb1pI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
+ string opc, string asm, string cstr, list<dag> pattern>
+ : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
+ let OutOperandList = oops;
+ let InOperandList = !con(iops, (ops pred:$p));
+ let AsmString = !strconcat(opc, !strconcat("${p}", asm));
+ let Pattern = pattern;
list<Predicate> Predicates = [IsThumb1Only];
}
+class T1pI<dag oops, dag iops, string opc, string asm, list<dag> pattern>
+ : Thumb1pI<oops, iops, AddrModeNone, Size2Bytes, opc, asm, "", pattern>;
+
+// Two-address instructions
+class T1pIt<dag oops, dag iops, string opc, string asm, list<dag> pattern>
+ : Thumb1pI<oops, iops, AddrModeNone, Size2Bytes, opc, asm,
+ "$lhs = $dst", pattern>;
+
+class T1pI1<dag oops, dag iops, string opc, string asm, list<dag> pattern>
+ : Thumb1pI<oops, iops, AddrModeT1_1, Size2Bytes, opc, asm, "", pattern>;
+class T1pI2<dag oops, dag iops, string opc, string asm, list<dag> pattern>
+ : Thumb1pI<oops, iops, AddrModeT1_2, Size2Bytes, opc, asm, "", pattern>;
+class T1pI4<dag oops, dag iops, string opc, string asm, list<dag> pattern>
+ : Thumb1pI<oops, iops, AddrModeT1_4, Size2Bytes, opc, asm, "", pattern>;
+class T1pIs<dag oops, dag iops, string opc, string asm, list<dag> pattern>
+ : Thumb1pI<oops, iops, AddrModeT1_s, Size2Bytes, opc, asm, "", pattern>;
+
// Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable.
class Thumb2I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
string opc, string asm, string cstr, list<dag> pattern>
list<Predicate> Predicates = [IsThumb2];
}
+// Tv5Pat - Same as Pat<>, but requires V5T Thumb mode.
+class Tv5Pat<dag pattern, dag result> : Pat<pattern, result> {
+ list<Predicate> Predicates = [IsThumb1Only, HasV5T];
+}
+
+// T1Pat - Same as Pat<>, but requires that the compiler be in Thumb1 mode.
+class T1Pat<dag pattern, dag result> : Pat<pattern, result> {
+ list<Predicate> Predicates = [IsThumb1Only];
+}
// T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
class T2Pat<dag pattern, dag result> : Pat<pattern, result> {
// ARM VFP Instruction templates.
//
+// Almost all VFP instructions are predicable.
+class VFPI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
+ IndexMode im, Format f, string opc, string asm, string cstr,
+ list<dag> pattern>
+ : InstARM<am, sz, im, f, cstr> {
+ let OutOperandList = oops;
+ let InOperandList = !con(iops, (ops pred:$p));
+ let AsmString = !strconcat(opc, !strconcat("${p}", asm));
+ let Pattern = pattern;
+ list<Predicate> Predicates = [HasVFP2];
+}
+
+// Special cases
+class VFPXI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
+ IndexMode im, Format f, string asm, string cstr, list<dag> pattern>
+ : InstARM<am, sz, im, f, cstr> {
+ let OutOperandList = oops;
+ let InOperandList = iops;
+ let AsmString = asm;
+ let Pattern = pattern;
+ list<Predicate> Predicates = [HasVFP2];
+}
+
+class VFPAI<dag oops, dag iops, Format f, string opc,
+ string asm, list<dag> pattern>
+ : VFPI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, opc,
+ asm, "", pattern>;
+
// ARM VFP addrmode5 loads and stores
class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
string opc, string asm, list<dag> pattern>
- : I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
+ : VFPI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
VFPLdStFrm, opc, asm, "", pattern> {
// TODO: Mark the instructions with the appropriate subtarget info.
let Inst{27-24} = opcod1;
class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
string opc, string asm, list<dag> pattern>
- : I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
+ : VFPI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
VFPLdStFrm, opc, asm, "", pattern> {
// TODO: Mark the instructions with the appropriate subtarget info.
let Inst{27-24} = opcod1;
// Load / store multiple
class AXSI5<dag oops, dag iops, string asm, list<dag> pattern>
- : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
+ : VFPXI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
VFPLdStMulFrm, asm, "", pattern> {
// TODO: Mark the instructions with the appropriate subtarget info.
let Inst{27-25} = 0b110;
}
class AXDI5<dag oops, dag iops, string asm, list<dag> pattern>
- : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
+ : VFPXI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
VFPLdStMulFrm, asm, "", pattern> {
// TODO: Mark the instructions with the appropriate subtarget info.
let Inst{27-25} = 0b110;
// Double precision, unary
class ADuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
string opc, string asm, list<dag> pattern>
- : AI<oops, iops, VFPUnaryFrm, opc, asm, pattern> {
+ : VFPAI<oops, iops, VFPUnaryFrm, opc, asm, pattern> {
let Inst{27-20} = opcod1;
let Inst{19-16} = opcod2;
let Inst{11-8} = 0b1011;
// Double precision, binary
class ADbI<bits<8> opcod, dag oops, dag iops, string opc,
string asm, list<dag> pattern>
- : AI<oops, iops, VFPBinaryFrm, opc, asm, pattern> {
+ : VFPAI<oops, iops, VFPBinaryFrm, opc, asm, pattern> {
let Inst{27-20} = opcod;
let Inst{11-8} = 0b1011;
}
// Single precision, unary
class ASuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
string opc, string asm, list<dag> pattern>
- : AI<oops, iops, VFPUnaryFrm, opc, asm, pattern> {
+ : VFPAI<oops, iops, VFPUnaryFrm, opc, asm, pattern> {
// Bits 22 (D bit) and 5 (M bit) will be changed during instruction encoding.
let Inst{27-20} = opcod1;
let Inst{19-16} = opcod2;
let Inst{7-4} = opcod3;
}
+// Single precision, unary if no NEON
+// Same as ASuI except not available if NEON is enabled
+class ASuIn<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
+ string opc, string asm, list<dag> pattern>
+ : ASuI<opcod1, opcod2, opcod2, oops, iops, opc, asm, pattern> {
+ list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
+}
+
// Single precision, binary
class ASbI<bits<8> opcod, dag oops, dag iops, string opc,
string asm, list<dag> pattern>
- : AI<oops, iops, VFPBinaryFrm, opc, asm, pattern> {
+ : VFPAI<oops, iops, VFPBinaryFrm, opc, asm, pattern> {
// Bit 22 (D bit) can be changed during instruction encoding.
let Inst{27-20} = opcod;
let Inst{11-8} = 0b1010;
}
+// Single precision, binary if no NEON
+// Same as ASbI except not available if NEON is enabled
+class ASbIn<bits<8> opcod, dag oops, dag iops, string opc,
+ string asm, list<dag> pattern>
+ : ASbI<opcod, oops, iops, opc, asm, pattern> {
+ list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
+}
+
// VFP conversion instructions
class AVConv1I<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3,
dag oops, dag iops, string opc, string asm, list<dag> pattern>
- : AI<oops, iops, VFPConv1Frm, opc, asm, pattern> {
+ : VFPAI<oops, iops, VFPConv1Frm, opc, asm, pattern> {
let Inst{27-20} = opcod1;
let Inst{19-16} = opcod2;
let Inst{11-8} = opcod3;
class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f,
string opc, string asm, list<dag> pattern>
- : AI<oops, iops, f, opc, asm, pattern> {
+ : VFPAI<oops, iops, f, opc, asm, pattern> {
let Inst{27-20} = opcod1;
let Inst{11-8} = opcod2;
let Inst{4} = 1;
class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
dag oops, dag iops, string opc, string asm, list<dag> pattern>
: NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONDupFrm, opc, asm, pattern>;
+
+// NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON
+// for single-precision FP.
+class NEONFPPat<dag pattern, dag result> : Pat<pattern, result> {
+ list<Predicate> Predicates = [HasNEON,UseNEONForFP];
+}