//===- 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 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 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 patterns> : PseudoInst { let Size = 4; } // As above, this will be a single A64 instruction, but we can actually give the // expansion in TableGen. class A64PseudoExpand patterns, dag Result> : A64PseudoInst, PseudoInstExpansion; // First, some common cross-hierarchy register formats. class A64InstRd patterns, InstrItinClass itin> : A64Inst { bits<5> Rd; let Inst{4-0} = Rd; } class A64InstRt patterns, InstrItinClass itin> : A64Inst { bits<5> Rt; let Inst{4-0} = Rt; } class A64InstRdn patterns, InstrItinClass itin> : A64InstRd { // Inherit rdt bits<5> Rn; let Inst{9-5} = Rn; } class A64InstRtn patterns, InstrItinClass itin> : A64InstRt { // Inherit rdt bits<5> Rn; let Inst{9-5} = Rn; } // Instructions taking Rt,Rt2,Rn class A64InstRtt2n patterns, InstrItinClass itin> : A64InstRtn { bits<5> Rt2; let Inst{14-10} = Rt2; } class A64InstRdnm patterns, InstrItinClass itin> : A64InstRdn { bits<5> Rm; let Inst{20-16} = Rm; } class A64InstRtnm patterns, InstrItinClass itin> : A64InstRtn { bits<5> Rm; let Inst{20-16} = Rm; } //===----------------------------------------------------------------------===// // // Actual A64 Instruction Formats // // Format for Add-subtract (extended register) instructions. class A64I_addsubext opt, bits<3> option, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { 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 shift, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdn { 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 shift, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { 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 opcode2, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { 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 opc, bit n, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdn { 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 patterns, InstrItinClass itin> : A64InstRt { 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 patterns, InstrItinClass itin> : A64Inst { 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 patterns, InstrItinClass itin> : A64Inst { 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 patterns, InstrItinClass itin> : A64Inst { 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 op2, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { 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 opcode2, bits<6> opcode, string asmstr, dag outs, dag ins, list patterns, InstrItinClass itin> : A64InstRdn { 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 opcode, bit S, string asmstr, dag outs, dag ins, list patterns, InstrItinClass itin> : A64InstRdnm { 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 opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { 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 opc, bits<3> op2, bits<2> ll, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64Inst { 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 op, bit n, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { 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 } let Predicates = [HasFPARMv8] in { // Format for floating-point compare instructions. class A64I_fpcmp type, bits<2> op, bits<5> opcode2, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64Inst { 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 type, bit op, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdn { 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 type, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { 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 type, bits<6> opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdn { 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 type, bits<4> opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { 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 type, bit o1, bit o0, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { 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 type, bits<2> mode, bits<3> opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdn { 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 type, bits<2> rmode, bits<3> opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdn { 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 type, bits<5> imm5, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRd { 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 opc, bit v, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRt { 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 size, bit o2, bit L, bit o1, bit o0, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRtn { 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 size, bit o2, bit L, bit o1, bit o0, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin>: A64I_LDSTex_tn{ bits<5> Rt2; let Inst{14-10} = Rt2; } class A64I_LDSTex_stn size, bit o2, bit L, bit o1, bit o0, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin>: A64I_LDSTex_tn{ bits<5> Rs; let Inst{20-16} = Rs; } class A64I_LDSTex_stt2n size, bit o2, bit L, bit o1, bit o0, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin>: A64I_LDSTex_stn{ bits<5> Rt2; let Inst{14-10} = Rt2; } // Format for load-store register (immediate post-indexed) instructions class A64I_LSpostind size, bit v, bits<2> opc, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRtn { 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 size, bit v, bits<2> opc, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRtn { 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 size, bit v, bits<2> opc, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRtn { 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 size, bit v, bits<2> opc, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRtn { 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 size, bit v, bits<2> opc, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRtn { 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 size, bit v, bits<2> opc, bit optionlo, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRtn { 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 opc, bit v, bit l, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRtt2n { 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 opc, bit v, bit l, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRtt2n { 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 opc, bit v, bit l, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRtt2n { 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 opc, bit v, bit l, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRtt2n { 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 opc, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdn { 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 opc, bits<2> shift, bit N, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { 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 opc, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRd { 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 patterns, InstrItinClass itin> : A64InstRd { 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 patterns, InstrItinClass itin> : A64Inst { 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 patterns, InstrItinClass itin> : A64Inst { // 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 patterns, InstrItinClass itin> : A64InstRt { // 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 opc, bits<5> op2, bits<6> op3, bits<5> op4, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64Inst { // 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 : InstAlias { } // Format AdvSIMD bitwise extract class NeonI_BitExtract op2, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { let Inst{31} = 0b0; let Inst{30} = q; let Inst{29-24} = 0b101110; let Inst{23-22} = op2; let Inst{21} = 0b0; // Inherit Rm in 20-16 let Inst{15} = 0b0; // imm4 in 14-11 let Inst{10} = 0b0; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD perm class NeonI_Perm size, bits<3> opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { let Inst{31} = 0b0; let Inst{30} = q; let Inst{29-24} = 0b001110; let Inst{23-22} = size; let Inst{21} = 0b0; // Inherit Rm in 20-16 let Inst{15} = 0b0; let Inst{14-12} = opcode; let Inst{11-10} = 0b10; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD table lookup class NeonI_TBL op2, bits<2> len, bit op, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { let Inst{31} = 0b0; let Inst{30} = q; let Inst{29-24} = 0b001110; let Inst{23-22} = op2; let Inst{21} = 0b0; // Inherit Rm in 20-16 let Inst{15} = 0b0; let Inst{14-13} = len; let Inst{12} = op; let Inst{11-10} = 0b00; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD 3 vector registers with same vector type class NeonI_3VSame size, bits<5> opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { 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 3 vector registers with different vector type class NeonI_3VDiff size, bits<4> opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { 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-12} = opcode; let Inst{11} = 0b0; let Inst{10} = 0b0; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD two registers and an element class NeonI_2VElem size, bits<4> opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { let Inst{31} = 0b0; let Inst{30} = q; let Inst{29} = u; let Inst{28-24} = 0b01111; let Inst{23-22} = size; // l in Inst{21} // m in Inst{20} // Inherit Rm in 19-16 let Inst{15-12} = opcode; // h in Inst{11} let Inst{10} = 0b0; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD 1 vector register with modified immediate class NeonI_1VModImm patterns, InstrItinClass itin> : A64InstRd { 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 size, bits<5> opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { 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 size, bits<5> opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdn { 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 } // Format AdvSIMD 2 vector 1 immediate shift class NeonI_2VShiftImm opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdn { bits<7> Imm; let Inst{31} = 0b0; let Inst{30} = q; let Inst{29} = u; let Inst{28-23} = 0b011110; let Inst{22-16} = Imm; let Inst{15-11} = opcode; let Inst{10} = 0b1; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD duplicate and insert class NeonI_copy imm4, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdn { bits<5> Imm5; let Inst{31} = 0b0; let Inst{30} = q; let Inst{29} = op; let Inst{28-21} = 0b01110000; let Inst{20-16} = Imm5; let Inst{15} = 0b0; let Inst{14-11} = imm4; let Inst{10} = 0b1; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD insert from element to vector class NeonI_insert patterns, InstrItinClass itin> : A64InstRdn { bits<5> Imm5; bits<4> Imm4; let Inst{31} = 0b0; let Inst{30} = q; let Inst{29} = op; let Inst{28-21} = 0b01110000; let Inst{20-16} = Imm5; let Inst{15} = 0b0; let Inst{14-11} = Imm4; let Inst{10} = 0b1; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD scalar pairwise class NeonI_ScalarPair size, bits<5> opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdn { 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-17} = 0b11000; let Inst{16-12} = opcode; let Inst{11-10} = 0b10; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD 2 vector across lanes class NeonI_2VAcross size, bits<5> opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdn { 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} = 0b11000; let Inst{16-12} = opcode; let Inst{11-10} = 0b10; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD scalar two registers miscellaneous class NeonI_Scalar2SameMisc size, bits<5> opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdn { 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-17} = 0b10000; let Inst{16-12} = opcode; let Inst{11-10} = 0b10; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD vector load/store multiple N-element structure class NeonI_LdStMult opcode, bits<2> size, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRtn { let Inst{31} = 0b0; let Inst{30} = q; let Inst{29-23} = 0b0011000; let Inst{22} = l; let Inst{21-16} = 0b000000; let Inst{15-12} = opcode; let Inst{11-10} = size; // Inherit Rn in 9-5 // Inherit Rt in 4-0 } // Format AdvSIMD vector load/store multiple N-element structure (post-index) class NeonI_LdStMult_Post opcode, bits<2> size, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRtnm { let Inst{31} = 0b0; let Inst{30} = q; let Inst{29-23} = 0b0011001; let Inst{22} = l; let Inst{21} = 0b0; // Inherit Rm in 20-16 let Inst{15-12} = opcode; let Inst{11-10} = size; // Inherit Rn in 9-5 // Inherit Rt in 4-0 } // Format AdvSIMD vector load Single N-element structure to all lanes class NeonI_LdOne_Dup opcode, bits<2> size, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRtn { let Inst{31} = 0b0; let Inst{30} = q; let Inst{29-23} = 0b0011010; let Inst{22} = 0b1; let Inst{21} = r; let Inst{20-16} = 0b00000; let Inst{15-13} = opcode; let Inst{12} = 0b0; let Inst{11-10} = size; // Inherit Rn in 9-5 // Inherit Rt in 4-0 } // Format AdvSIMD vector load/store Single N-element structure to/from one lane class NeonI_LdStOne_Lane op2_1, bit op0, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRtn { bits<4> lane; let Inst{31} = 0b0; let Inst{29-23} = 0b0011010; let Inst{22} = l; let Inst{21} = r; let Inst{20-16} = 0b00000; let Inst{15-14} = op2_1; let Inst{13} = op0; // Inherit Rn in 9-5 // Inherit Rt in 4-0 } // Format AdvSIMD post-index vector load Single N-element structure to all lanes class NeonI_LdOne_Dup_Post opcode, bits<2> size, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRtnm { let Inst{31} = 0b0; let Inst{30} = q; let Inst{29-23} = 0b0011011; let Inst{22} = 0b1; let Inst{21} = r; // Inherit Rm in 20-16 let Inst{15-13} = opcode; let Inst{12} = 0b0; let Inst{11-10} = size; // Inherit Rn in 9-5 // Inherit Rt in 4-0 } // Format AdvSIMD post-index vector load/store Single N-element structure // to/from one lane class NeonI_LdStOne_Lane_Post op2_1, bit op0, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRtnm { bits<4> lane; let Inst{31} = 0b0; let Inst{29-23} = 0b0011011; let Inst{22} = l; let Inst{21} = r; // Inherit Rm in 20-16 let Inst{15-14} = op2_1; let Inst{13} = op0; // Inherit Rn in 9-5 // Inherit Rt in 4-0 } // Format AdvSIMD 3 scalar registers with different type class NeonI_Scalar3Diff size, bits<4> opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { let Inst{31-30} = 0b01; 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-12} = opcode; let Inst{11-10} = 0b00; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD scalar shift by immediate class NeonI_ScalarShiftImm opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdn { bits<4> Imm4; bits<3> Imm3; let Inst{31-30} = 0b01; let Inst{29} = u; let Inst{28-23} = 0b111110; let Inst{22-19} = Imm4; let Inst{18-16} = Imm3; let Inst{15-11} = opcode; let Inst{10} = 0b1; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD crypto AES class NeonI_Crypto_AES size, bits<5> opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdn { let Inst{31-24} = 0b01001110; let Inst{23-22} = size; let Inst{21-17} = 0b10100; let Inst{16-12} = opcode; let Inst{11-10} = 0b10; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD crypto SHA class NeonI_Crypto_SHA size, bits<5> opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdn { let Inst{31-24} = 0b01011110; let Inst{23-22} = size; let Inst{21-17} = 0b10100; let Inst{16-12} = opcode; let Inst{11-10} = 0b10; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD crypto 3V SHA class NeonI_Crypto_3VSHA size, bits<3> opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { let Inst{31-24} = 0b01011110; let Inst{23-22} = size; let Inst{21} = 0b0; // Inherit Rm in 20-16 let Inst{15} = 0b0; let Inst{14-12} = opcode; let Inst{11-10} = 0b00; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD scalar x indexed element class NeonI_ScalarXIndexedElem opcode, dag outs, dag ins, string asmstr, list patterns, InstrItinClass itin> : A64InstRdnm { let Inst{31} = 0b0; let Inst{30} = 0b1; let Inst{29} = u; let Inst{28-24} = 0b11111; let Inst{23} = szhi; let Inst{22} = szlo; // l in Inst{21} // m in Instr{20} // Inherit Rm in 19-16 let Inst{15-12} = opcode; // h in Inst{11} let Inst{10} = 0b0; // Inherit Rn in 9-5 // Inherit Rd in 4-0 } // Format AdvSIMD scalar copy - insert from element to scalar class NeonI_ScalarCopy patterns, InstrItinClass itin> : NeonI_copy<0b1, 0b0, 0b0000, outs, ins, asmstr, patterns, itin> { let Inst{28} = 0b1; } }