//===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tablegen -*-=// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // This file describes AArch64 instruction formats, down to the level of the // instruction's overall class. //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// // A64 Instruction Format Definitions. //===----------------------------------------------------------------------===// // A64 is currently the only instruction set supported by the AArch64 // architecture. class A64Inst<dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : Instruction { // All A64 instructions are 32-bit. This field will be filled in // gradually going down the hierarchy. field bits<32> Inst; field bits<32> Unpredictable = 0; // SoftFail is the generic name for this field, but we alias it so // as to make it more obvious what it means in ARM-land. field bits<32> SoftFail = Unpredictable; // LLVM-level model of the AArch64/A64 distinction. let Namespace = "AArch64"; let DecoderNamespace = "A64"; let Size = 4; // Set the templated fields let OutOperandList = outs; let InOperandList = ins; let AsmString = asmstr; let Pattern = patterns; let Itinerary = itin; } class PseudoInst<dag outs, dag ins, list<dag> patterns> : Instruction { let Namespace = "AArch64"; let OutOperandList = outs; let InOperandList= ins; let Pattern = patterns; let isCodeGenOnly = 1; let isPseudo = 1; } // Represents a pseudo-instruction that represents a single A64 instruction for // whatever reason, the eventual result will be a 32-bit real instruction. class A64PseudoInst<dag outs, dag ins, list<dag> patterns> : PseudoInst<outs, ins, patterns> { let Size = 4; } // As above, this will be a single A64 instruction, but we can actually give the // expansion in TableGen. class A64PseudoExpand<dag outs, dag ins, list<dag> patterns, dag Result> : A64PseudoInst<outs, ins, patterns>, PseudoInstExpansion<Result>; // First, some common cross-hierarchy register formats. class A64InstRd<dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64Inst<outs, ins, asmstr, patterns, itin> { bits<5> Rd; let Inst{4-0} = Rd; } class A64InstRt<dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64Inst<outs, ins, asmstr, patterns, itin> { bits<5> Rt; let Inst{4-0} = Rt; } class A64InstRdn<dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRd<outs, ins, asmstr, patterns, itin> { // Inherit rdt bits<5> Rn; let Inst{9-5} = Rn; } class A64InstRtn<dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRt<outs, ins, asmstr, patterns, itin> { // Inherit rdt bits<5> Rn; let Inst{9-5} = Rn; } // Instructions taking Rt,Rt2,Rn class A64InstRtt2n<dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRtn<outs, ins, asmstr, patterns, itin> { bits<5> Rt2; let Inst{14-10} = Rt2; } class A64InstRdnm<dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdn<outs, ins, asmstr, patterns, itin> { bits<5> Rm; let Inst{20-16} = Rm; } //===----------------------------------------------------------------------===// // // Actual A64 Instruction Formats // // Format for Add-subtract (extended register) instructions. class A64I_addsubext<bit sf, bit op, bit S, bits<2> opt, bits<3> option, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdnm<outs, ins, asmstr, patterns, itin> { bits<3> Imm3; let Inst{31} = sf; let Inst{30} = op; let Inst{29} = S; let Inst{28-24} = 0b01011; let Inst{23-22} = opt; let Inst{21} = 0b1; // Rm inherited in 20-16 let Inst{15-13} = option; let Inst{12-10} = Imm3; // Rn inherited in 9-5 // Rd inherited in 4-0 } // Format for Add-subtract (immediate) instructions. class A64I_addsubimm<bit sf, bit op, bit S, bits<2> shift, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdn<outs, ins, asmstr, patterns, itin> { bits<12> Imm12; let Inst{31} = sf; let Inst{30} = op; let Inst{29} = S; let Inst{28-24} = 0b10001; let Inst{23-22} = shift; let Inst{21-10} = Imm12; } // Format for Add-subtract (shifted register) instructions. class A64I_addsubshift<bit sf, bit op, bit S, bits<2> shift, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdnm<outs, ins, asmstr, patterns, itin> { bits<6> Imm6; let Inst{31} = sf; let Inst{30} = op; let Inst{29} = S; let Inst{28-24} = 0b01011; let Inst{23-22} = shift; let Inst{21} = 0b0; // Rm inherited in 20-16 let Inst{15-10} = Imm6; // Rn inherited in 9-5 // Rd inherited in 4-0 } // Format for Add-subtract (with carry) instructions. class A64I_addsubcarry<bit sf, bit op, bit S, bits<6> opcode2, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdnm<outs, ins, asmstr, patterns, itin> { let Inst{31} = sf; let Inst{30} = op; let Inst{29} = S; let Inst{28-21} = 0b11010000; // Rm inherited in 20-16 let Inst{15-10} = opcode2; // Rn inherited in 9-5 // Rd inherited in 4-0 } // Format for Bitfield instructions class A64I_bitfield<bit sf, bits<2> opc, bit n, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdn<outs, ins, asmstr, patterns, itin> { bits<6> ImmR; bits<6> ImmS; let Inst{31} = sf; let Inst{30-29} = opc; let Inst{28-23} = 0b100110; let Inst{22} = n; let Inst{21-16} = ImmR; let Inst{15-10} = ImmS; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format for compare and branch (immediate) instructions. class A64I_cmpbr<bit sf, bit op, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRt<outs, ins, asmstr, patterns, itin> { bits<19> Label; let Inst{31} = sf; let Inst{30-25} = 0b011010; let Inst{24} = op; let Inst{23-5} = Label; // Inherit Rt in 4-0 } // Format for conditional branch (immediate) instructions. class A64I_condbr<bit o1, bit o0, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64Inst<outs, ins, asmstr, patterns, itin> { bits<19> Label; bits<4> Cond; let Inst{31-25} = 0b0101010; let Inst{24} = o1; let Inst{23-5} = Label; let Inst{4} = o0; let Inst{3-0} = Cond; } // Format for conditional compare (immediate) instructions. class A64I_condcmpimm<bit sf, bit op, bit o2, bit o3, bit s, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64Inst<outs, ins, asmstr, patterns, itin> { bits<5> Rn; bits<5> UImm5; bits<4> NZCVImm; bits<4> Cond; let Inst{31} = sf; let Inst{30} = op; let Inst{29} = s; let Inst{28-21} = 0b11010010; let Inst{20-16} = UImm5; let Inst{15-12} = Cond; let Inst{11} = 0b1; let Inst{10} = o2; let Inst{9-5} = Rn; let Inst{4} = o3; let Inst{3-0} = NZCVImm; } // Format for conditional compare (register) instructions. class A64I_condcmpreg<bit sf, bit op, bit o2, bit o3, bit s, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64Inst<outs, ins, asmstr, patterns, itin> { bits<5> Rn; bits<5> Rm; bits<4> NZCVImm; bits<4> Cond; let Inst{31} = sf; let Inst{30} = op; let Inst{29} = s; let Inst{28-21} = 0b11010010; let Inst{20-16} = Rm; let Inst{15-12} = Cond; let Inst{11} = 0b0; let Inst{10} = o2; let Inst{9-5} = Rn; let Inst{4} = o3; let Inst{3-0} = NZCVImm; } // Format for conditional select instructions. class A64I_condsel<bit sf, bit op, bit s, bits<2> op2, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdnm<outs, ins, asmstr, patterns, itin> { bits<4> Cond; let Inst{31} = sf; let Inst{30} = op; let Inst{29} = s; let Inst{28-21} = 0b11010100; // Inherit Rm in 20-16 let Inst{15-12} = Cond; let Inst{11-10} = op2; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format for data processing (1 source) instructions class A64I_dp_1src<bit sf, bit S, bits<5> opcode2, bits<6> opcode, string asmstr, dag outs, dag ins, list<dag> patterns, InstrItinClass itin> : A64InstRdn<outs, ins, asmstr, patterns, itin> { let Inst{31} = sf; let Inst{30} = 0b1; let Inst{29} = S; let Inst{28-21} = 0b11010110; let Inst{20-16} = opcode2; let Inst{15-10} = opcode; } // Format for data processing (2 source) instructions class A64I_dp_2src<bit sf, bits<6> opcode, bit S, string asmstr, dag outs, dag ins, list<dag> patterns, InstrItinClass itin> : A64InstRdnm<outs, ins, asmstr, patterns, itin> { let Inst{31} = sf; let Inst{30} = 0b0; let Inst{29} = S; let Inst{28-21} = 0b11010110; let Inst{15-10} = opcode; } // Format for data-processing (3 source) instructions class A64I_dp3<bit sf, bits<6> opcode, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdnm<outs, ins, asmstr, patterns, itin> { bits<5> Ra; let Inst{31} = sf; let Inst{30-29} = opcode{5-4}; let Inst{28-24} = 0b11011; let Inst{23-21} = opcode{3-1}; // Inherits Rm in 20-16 let Inst{15} = opcode{0}; let Inst{14-10} = Ra; // Inherits Rn in 9-5 // Inherits Rd in 4-0 } // Format for exception generation instructions class A64I_exception<bits<3> opc, bits<3> op2, bits<2> ll, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64Inst<outs, ins, asmstr, patterns, itin> { bits<16> UImm16; let Inst{31-24} = 0b11010100; let Inst{23-21} = opc; let Inst{20-5} = UImm16; let Inst{4-2} = op2; let Inst{1-0} = ll; } // Format for extract (immediate) instructions class A64I_extract<bit sf, bits<3> op, bit n, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdnm<outs, ins, asmstr, patterns, itin> { bits<6> LSB; let Inst{31} = sf; let Inst{30-29} = op{2-1}; let Inst{28-23} = 0b100111; let Inst{22} = n; let Inst{21} = op{0}; // Inherits Rm in bits 20-16 let Inst{15-10} = LSB; // Inherits Rn in 9-5 // Inherits Rd in 4-0 } // Format for floating-point compare instructions. class A64I_fpcmp<bit m, bit s, bits<2> type, bits<2> op, bits<5> opcode2, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64Inst<outs, ins, asmstr, patterns, itin> { bits<5> Rn; bits<5> Rm; let Inst{31} = m; let Inst{30} = 0b0; let Inst{29} = s; let Inst{28-24} = 0b11110; let Inst{23-22} = type; let Inst{21} = 0b1; let Inst{20-16} = Rm; let Inst{15-14} = op; let Inst{13-10} = 0b1000; let Inst{9-5} = Rn; let Inst{4-0} = opcode2; } // Format for floating-point conditional compare instructions. class A64I_fpccmp<bit m, bit s, bits<2> type, bit op, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdn<outs, ins, asmstr, patterns, itin> { bits<5> Rn; bits<5> Rm; bits<4> NZCVImm; bits<4> Cond; let Inst{31} = m; let Inst{30} = 0b0; let Inst{29} = s; let Inst{28-24} = 0b11110; let Inst{23-22} = type; let Inst{21} = 0b1; let Inst{20-16} = Rm; let Inst{15-12} = Cond; let Inst{11-10} = 0b01; let Inst{9-5} = Rn; let Inst{4} = op; let Inst{3-0} = NZCVImm; } // Format for floating-point conditional select instructions. class A64I_fpcondsel<bit m, bit s, bits<2> type, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdnm<outs, ins, asmstr, patterns, itin> { bits<4> Cond; let Inst{31} = m; let Inst{30} = 0b0; let Inst{29} = s; let Inst{28-24} = 0b11110; let Inst{23-22} = type; let Inst{21} = 0b1; // Inherit Rm in 20-16 let Inst{15-12} = Cond; let Inst{11-10} = 0b11; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format for floating-point data-processing (1 source) instructions. class A64I_fpdp1<bit m, bit s, bits<2> type, bits<6> opcode, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdn<outs, ins, asmstr, patterns, itin> { let Inst{31} = m; let Inst{30} = 0b0; let Inst{29} = s; let Inst{28-24} = 0b11110; let Inst{23-22} = type; let Inst{21} = 0b1; let Inst{20-15} = opcode; let Inst{14-10} = 0b10000; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format for floating-point data-processing (2 sources) instructions. class A64I_fpdp2<bit m, bit s, bits<2> type, bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdnm<outs, ins, asmstr, patterns, itin> { let Inst{31} = m; let Inst{30} = 0b0; let Inst{29} = s; let Inst{28-24} = 0b11110; let Inst{23-22} = type; let Inst{21} = 0b1; // Inherit Rm in 20-16 let Inst{15-12} = opcode; let Inst{11-10} = 0b10; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format for floating-point data-processing (3 sources) instructions. class A64I_fpdp3<bit m, bit s, bits<2> type, bit o1, bit o0, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdnm<outs, ins, asmstr, patterns, itin> { bits<5> Ra; let Inst{31} = m; let Inst{30} = 0b0; let Inst{29} = s; let Inst{28-24} = 0b11111; let Inst{23-22} = type; let Inst{21} = o1; // Inherit Rm in 20-16 let Inst{15} = o0; let Inst{14-10} = Ra; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format for floating-point <-> fixed-point conversion instructions. class A64I_fpfixed<bit sf, bit s, bits<2> type, bits<2> mode, bits<3> opcode, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdn<outs, ins, asmstr, patterns, itin> { bits<6> Scale; let Inst{31} = sf; let Inst{30} = 0b0; let Inst{29} = s; let Inst{28-24} = 0b11110; let Inst{23-22} = type; let Inst{21} = 0b0; let Inst{20-19} = mode; let Inst{18-16} = opcode; let Inst{15-10} = Scale; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format for floating-point <-> integer conversion instructions. class A64I_fpint<bit sf, bit s, bits<2> type, bits<2> rmode, bits<3> opcode, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdn<outs, ins, asmstr, patterns, itin> { let Inst{31} = sf; let Inst{30} = 0b0; let Inst{29} = s; let Inst{28-24} = 0b11110; let Inst{23-22} = type; let Inst{21} = 0b1; let Inst{20-19} = rmode; let Inst{18-16} = opcode; let Inst{15-10} = 0b000000; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format for floating-point immediate instructions. class A64I_fpimm<bit m, bit s, bits<2> type, bits<5> imm5, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRd<outs, ins, asmstr, patterns, itin> { bits<8> Imm8; let Inst{31} = m; let Inst{30} = 0b0; let Inst{29} = s; let Inst{28-24} = 0b11110; let Inst{23-22} = type; let Inst{21} = 0b1; let Inst{20-13} = Imm8; let Inst{12-10} = 0b100; let Inst{9-5} = imm5; // Inherit Rd in 4-0 } // Format for load-register (literal) instructions. class A64I_LDRlit<bits<2> opc, bit v, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRt<outs, ins, asmstr, patterns, itin> { bits<19> Imm19; let Inst{31-30} = opc; let Inst{29-27} = 0b011; let Inst{26} = v; let Inst{25-24} = 0b00; let Inst{23-5} = Imm19; // Inherit Rt in 4-0 } // Format for load-store exclusive instructions. class A64I_LDSTex_tn<bits<2> size, bit o2, bit L, bit o1, bit o0, dag outs, dag ins, string asmstr, list <dag> patterns, InstrItinClass itin> : A64InstRtn<outs, ins, asmstr, patterns, itin> { let Inst{31-30} = size; let Inst{29-24} = 0b001000; let Inst{23} = o2; let Inst{22} = L; let Inst{21} = o1; let Inst{15} = o0; } class A64I_LDSTex_tt2n<bits<2> size, bit o2, bit L, bit o1, bit o0, dag outs, dag ins, string asmstr, list <dag> patterns, InstrItinClass itin>: A64I_LDSTex_tn<size, o2, L, o1, o0, outs, ins, asmstr, patterns, itin>{ bits<5> Rt2; let Inst{14-10} = Rt2; } class A64I_LDSTex_stn<bits<2> size, bit o2, bit L, bit o1, bit o0, dag outs, dag ins, string asmstr, list <dag> patterns, InstrItinClass itin>: A64I_LDSTex_tn<size, o2, L, o1, o0, outs, ins, asmstr, patterns, itin>{ bits<5> Rs; let Inst{20-16} = Rs; } class A64I_LDSTex_stt2n<bits<2> size, bit o2, bit L, bit o1, bit o0, dag outs, dag ins, string asmstr, list <dag> patterns, InstrItinClass itin>: A64I_LDSTex_stn<size, o2, L, o1, o0, outs, ins, asmstr, patterns, itin>{ bits<5> Rt2; let Inst{14-10} = Rt2; } // Format for load-store register (immediate post-indexed) instructions class A64I_LSpostind<bits<2> size, bit v, bits<2> opc, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRtn<outs, ins, asmstr, patterns, itin> { bits<9> SImm9; let Inst{31-30} = size; let Inst{29-27} = 0b111; let Inst{26} = v; let Inst{25-24} = 0b00; let Inst{23-22} = opc; let Inst{21} = 0b0; let Inst{20-12} = SImm9; let Inst{11-10} = 0b01; // Inherit Rn in 9-5 // Inherit Rt in 4-0 } // Format for load-store register (immediate pre-indexed) instructions class A64I_LSpreind<bits<2> size, bit v, bits<2> opc, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRtn<outs, ins, asmstr, patterns, itin> { bits<9> SImm9; let Inst{31-30} = size; let Inst{29-27} = 0b111; let Inst{26} = v; let Inst{25-24} = 0b00; let Inst{23-22} = opc; let Inst{21} = 0b0; let Inst{20-12} = SImm9; let Inst{11-10} = 0b11; // Inherit Rn in 9-5 // Inherit Rt in 4-0 } // Format for load-store register (unprivileged) instructions class A64I_LSunpriv<bits<2> size, bit v, bits<2> opc, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRtn<outs, ins, asmstr, patterns, itin> { bits<9> SImm9; let Inst{31-30} = size; let Inst{29-27} = 0b111; let Inst{26} = v; let Inst{25-24} = 0b00; let Inst{23-22} = opc; let Inst{21} = 0b0; let Inst{20-12} = SImm9; let Inst{11-10} = 0b10; // Inherit Rn in 9-5 // Inherit Rt in 4-0 } // Format for load-store (unscaled immediate) instructions. class A64I_LSunalimm<bits<2> size, bit v, bits<2> opc, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRtn<outs, ins, asmstr, patterns, itin> { bits<9> SImm9; let Inst{31-30} = size; let Inst{29-27} = 0b111; let Inst{26} = v; let Inst{25-24} = 0b00; let Inst{23-22} = opc; let Inst{21} = 0b0; let Inst{20-12} = SImm9; let Inst{11-10} = 0b00; // Inherit Rn in 9-5 // Inherit Rt in 4-0 } // Format for load-store (unsigned immediate) instructions. class A64I_LSunsigimm<bits<2> size, bit v, bits<2> opc, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRtn<outs, ins, asmstr, patterns, itin> { bits<12> UImm12; let Inst{31-30} = size; let Inst{29-27} = 0b111; let Inst{26} = v; let Inst{25-24} = 0b01; let Inst{23-22} = opc; let Inst{21-10} = UImm12; } // Format for load-store register (register offset) instructions. class A64I_LSregoff<bits<2> size, bit v, bits<2> opc, bit optionlo, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRtn<outs, ins, asmstr, patterns, itin> { bits<5> Rm; // Complex operand selection needed for these instructions, so they // need an "addr" field for encoding/decoding to be generated. bits<3> Ext; // OptionHi = Ext{2-1} // S = Ext{0} let Inst{31-30} = size; let Inst{29-27} = 0b111; let Inst{26} = v; let Inst{25-24} = 0b00; let Inst{23-22} = opc; let Inst{21} = 0b1; let Inst{20-16} = Rm; let Inst{15-14} = Ext{2-1}; let Inst{13} = optionlo; let Inst{12} = Ext{0}; let Inst{11-10} = 0b10; // Inherits Rn in 9-5 // Inherits Rt in 4-0 let AddedComplexity = 50; } // Format for Load-store register pair (offset) instructions class A64I_LSPoffset<bits<2> opc, bit v, bit l, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRtt2n<outs, ins, asmstr, patterns, itin> { bits<7> SImm7; let Inst{31-30} = opc; let Inst{29-27} = 0b101; let Inst{26} = v; let Inst{25-23} = 0b010; let Inst{22} = l; let Inst{21-15} = SImm7; // Inherit Rt2 in 14-10 // Inherit Rn in 9-5 // Inherit Rt in 4-0 } // Format for Load-store register pair (post-indexed) instructions class A64I_LSPpostind<bits<2> opc, bit v, bit l, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRtt2n<outs, ins, asmstr, patterns, itin> { bits<7> SImm7; let Inst{31-30} = opc; let Inst{29-27} = 0b101; let Inst{26} = v; let Inst{25-23} = 0b001; let Inst{22} = l; let Inst{21-15} = SImm7; // Inherit Rt2 in 14-10 // Inherit Rn in 9-5 // Inherit Rt in 4-0 } // Format for Load-store register pair (pre-indexed) instructions class A64I_LSPpreind<bits<2> opc, bit v, bit l, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRtt2n<outs, ins, asmstr, patterns, itin> { bits<7> SImm7; let Inst{31-30} = opc; let Inst{29-27} = 0b101; let Inst{26} = v; let Inst{25-23} = 0b011; let Inst{22} = l; let Inst{21-15} = SImm7; // Inherit Rt2 in 14-10 // Inherit Rn in 9-5 // Inherit Rt in 4-0 } // Format for Load-store non-temporal register pair (offset) instructions class A64I_LSPnontemp<bits<2> opc, bit v, bit l, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRtt2n<outs, ins, asmstr, patterns, itin> { bits<7> SImm7; let Inst{31-30} = opc; let Inst{29-27} = 0b101; let Inst{26} = v; let Inst{25-23} = 0b000; let Inst{22} = l; let Inst{21-15} = SImm7; // Inherit Rt2 in 14-10 // Inherit Rn in 9-5 // Inherit Rt in 4-0 } // Format for Logical (immediate) instructions class A64I_logicalimm<bit sf, bits<2> opc, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdn<outs, ins, asmstr, patterns, itin> { bit N; bits<6> ImmR; bits<6> ImmS; // N, ImmR and ImmS have no separate existence in any assembly syntax (or for // selection), so we'll combine them into a single field here. bits<13> Imm; // N = Imm{12}; // ImmR = Imm{11-6}; // ImmS = Imm{5-0}; let Inst{31} = sf; let Inst{30-29} = opc; let Inst{28-23} = 0b100100; let Inst{22} = Imm{12}; let Inst{21-16} = Imm{11-6}; let Inst{15-10} = Imm{5-0}; // Rn inherited in 9-5 // Rd inherited in 4-0 } // Format for Logical (shifted register) instructions class A64I_logicalshift<bit sf, bits<2> opc, bits<2> shift, bit N, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdnm<outs, ins, asmstr, patterns, itin> { bits<6> Imm6; let Inst{31} = sf; let Inst{30-29} = opc; let Inst{28-24} = 0b01010; let Inst{23-22} = shift; let Inst{21} = N; // Rm inherited let Inst{15-10} = Imm6; // Rn inherited // Rd inherited } // Format for Move wide (immediate) class A64I_movw<bit sf, bits<2> opc, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRd<outs, ins, asmstr, patterns, itin> { bits<16> UImm16; bits<2> Shift; // Called "hw" officially let Inst{31} = sf; let Inst{30-29} = opc; let Inst{28-23} = 0b100101; let Inst{22-21} = Shift; let Inst{20-5} = UImm16; // Inherits Rd in 4-0 } // Format for PC-relative addressing instructions, ADR and ADRP. class A64I_PCADR<bit op, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRd<outs, ins, asmstr, patterns, itin> { bits<21> Label; let Inst{31} = op; let Inst{30-29} = Label{1-0}; let Inst{28-24} = 0b10000; let Inst{23-5} = Label{20-2}; } // Format for system instructions class A64I_system<bit l, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64Inst<outs, ins, asmstr, patterns, itin> { bits<2> Op0; bits<3> Op1; bits<4> CRn; bits<4> CRm; bits<3> Op2; bits<5> Rt; let Inst{31-22} = 0b1101010100; let Inst{21} = l; let Inst{20-19} = Op0; let Inst{18-16} = Op1; let Inst{15-12} = CRn; let Inst{11-8} = CRm; let Inst{7-5} = Op2; let Inst{4-0} = Rt; // These instructions can do horrible things. let hasSideEffects = 1; } // Format for unconditional branch (immediate) instructions class A64I_Bimm<bit op, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64Inst<outs, ins, asmstr, patterns, itin> { // Doubly special in not even sharing register fields with other // instructions, so we create our own Rn here. bits<26> Label; let Inst{31} = op; let Inst{30-26} = 0b00101; let Inst{25-0} = Label; } // Format for Test & branch (immediate) instructions class A64I_TBimm<bit op, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRt<outs, ins, asmstr, patterns, itin> { // Doubly special in not even sharing register fields with other // instructions, so we create our own Rn here. bits<6> Imm; bits<14> Label; let Inst{31} = Imm{5}; let Inst{30-25} = 0b011011; let Inst{24} = op; let Inst{23-19} = Imm{4-0}; let Inst{18-5} = Label; // Inherit Rt in 4-0 } // Format for Unconditional branch (register) instructions, including // RET. Shares no fields with instructions further up the hierarchy // so top-level. class A64I_Breg<bits<4> opc, bits<5> op2, bits<6> op3, bits<5> op4, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64Inst<outs, ins, asmstr, patterns, itin> { // Doubly special in not even sharing register fields with other // instructions, so we create our own Rn here. bits<5> Rn; let Inst{31-25} = 0b1101011; let Inst{24-21} = opc; let Inst{20-16} = op2; let Inst{15-10} = op3; let Inst{9-5} = Rn; let Inst{4-0} = op4; } //===----------------------------------------------------------------------===// // // Neon Instruction Format Definitions. // let Predicates = [HasNEON] in { class NeonInstAlias<string Asm, dag Result, bit Emit = 0b1> : InstAlias<Asm, Result, Emit> { } // Format AdvSIMD 3 vector registers with same vector type class NeonI_3VSame<bit q, bit u, bits<2> size, bits<5> opcode, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdnm<outs, ins, asmstr, patterns, itin> { let Inst{31} = 0b0; let Inst{30} = q; let Inst{29} = u; let Inst{28-24} = 0b01110; let Inst{23-22} = size; let Inst{21} = 0b1; // Inherit Rm in 20-16 let Inst{15-11} = opcode; let Inst{10} = 0b1; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD 1 vector register with modified immediate class NeonI_1VModImm<bit q, bit op, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRd<outs,ins, asmstr, patterns, itin> { bits<8> Imm; bits<4> cmode; let Inst{31} = 0b0; let Inst{30} = q; let Inst{29} = op; let Inst{28-19} = 0b0111100000; let Inst{15-12} = cmode; let Inst{11} = 0b0; // o2 let Inst{10} = 1; // Inherit Rd in 4-0 let Inst{18-16} = Imm{7-5}; // imm a:b:c let Inst{9-5} = Imm{4-0}; // imm d:e:f:g:h } // Format AdvSIMD 3 scalar registers with same type class NeonI_Scalar3Same<bit u, bits<2> size, bits<5> opcode, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdnm<outs, ins, asmstr, patterns, itin> { let Inst{31} = 0b0; let Inst{30} = 0b1; let Inst{29} = u; let Inst{28-24} = 0b11110; let Inst{23-22} = size; let Inst{21} = 0b1; // Inherit Rm in 20-16 let Inst{15-11} = opcode; let Inst{10} = 0b1; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD 2 vector registers miscellaneous class NeonI_2VMisc<bit q, bit u, bits<2> size, bits<5> opcode, dag outs, dag ins, string asmstr, list<dag> patterns, InstrItinClass itin> : A64InstRdn<outs, ins, asmstr, patterns, itin> { let Inst{31} = 0b0; let Inst{30} = q; let Inst{29} = u; let Inst{28-24} = 0b01110; let Inst{23-22} = size; let Inst{21-17} = 0b10000; let Inst{16-12} = opcode; let Inst{11-10} = 0b10; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } }