llvm-6502/lib/Target/AArch64/AArch64InstrFormats.td
Jiangning Liu 477fc628b3 Initial support for Neon scalar instructions.
Patch by Ana Pazos.

1.Added support for v1ix and v1fx types.
2.Added Scalar Pairwise Reduce instructions.
3.Added initial implementation of Scalar Arithmetic instructions.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191263 91177308-0d34-0410-b5e6-96231b3b80d8
2013-09-24 02:47:27 +00:00

1151 lines
32 KiB
TableGen

//===- 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 3 vector registers with different vector type
class NeonI_3VDiff<bit q, bit u, bits<2> size, bits<4> 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-12} = opcode;
let Inst{11} = 0b0;
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<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
}
// Format AdvSIMD 2 vector 1 immediate shift
class NeonI_2VShiftImm<bit q, bit u, bits<5> opcode,
dag outs, dag ins, string asmstr,
list<dag> patterns, InstrItinClass itin>
: A64InstRdn<outs, ins, asmstr, patterns, itin> {
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<bit q, bit op, bits<4> imm4,
dag outs, dag ins, string asmstr,
list<dag> patterns, InstrItinClass itin>
: A64InstRdn<outs, ins, asmstr, patterns, itin>
{
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<bit q, bit op,
dag outs, dag ins, string asmstr,
list<dag> patterns, InstrItinClass itin>
: A64InstRdn<outs, ins, asmstr, patterns, itin>
{
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<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} = 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
}
}