mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 05:32:25 +00:00
2d9f3bf9f9
Only one instruction pair needed changing: SMULH & UMULH. The previous code worked, but MC was doing extra work treating Ra as a valid operand (which then got completely overwritten in MCCodeEmitter). No behaviour change, so no tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203772 91177308-0d34-0410-b5e6-96231b3b80d8
1488 lines
42 KiB
TableGen
1488 lines
42 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;
|
|
}
|
|
|
|
class A64InstRtnm<dag outs, dag ins, string asmstr,
|
|
list<dag> patterns, InstrItinClass itin>
|
|
: A64InstRtn<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> {
|
|
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};
|
|
// {14-10} mostly Ra, but unspecified for SMULH/UMULH
|
|
// 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
|
|
}
|
|
|
|
let Predicates = [HasFPARMv8] in {
|
|
|
|
// 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 bitwise extract
|
|
class NeonI_BitExtract<bit q, bits<2> op2,
|
|
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-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<bit q, bits<2> size, bits<3> 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-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<bit q, bits<2> op2, bits<2> len, bit op,
|
|
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-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<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 two registers and an element
|
|
class NeonI_2VElem<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} = 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<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
|
|
}
|
|
|
|
// Format AdvSIMD 2 vector across lanes
|
|
class NeonI_2VAcross<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} = 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<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} = 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<bit q, bit l, bits<4> opcode, bits<2> size,
|
|
dag outs, dag ins, string asmstr,
|
|
list<dag> patterns, InstrItinClass itin>
|
|
: A64InstRtn<outs, ins, asmstr, patterns, itin>
|
|
{
|
|
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<bit q, bit l, bits<4> opcode, bits<2> size,
|
|
dag outs, dag ins, string asmstr,
|
|
list<dag> patterns, InstrItinClass itin>
|
|
: A64InstRtnm<outs, ins, asmstr, patterns, itin>
|
|
{
|
|
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<bit q, bit r, bits<3> opcode, bits<2> size, dag outs,
|
|
dag ins, string asmstr, list<dag> patterns,
|
|
InstrItinClass itin>
|
|
: A64InstRtn<outs, ins, asmstr, patterns, itin>
|
|
{
|
|
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<bit l, bit r, bits<2> op2_1, bit op0, dag outs,
|
|
dag ins, string asmstr,
|
|
list<dag> patterns, InstrItinClass itin>
|
|
: A64InstRtn<outs, ins, asmstr, patterns, itin>
|
|
{
|
|
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<bit q, bit r, bits<3> opcode, bits<2> size, dag outs,
|
|
dag ins, string asmstr, list<dag> patterns,
|
|
InstrItinClass itin>
|
|
: A64InstRtnm<outs, ins, asmstr, patterns, itin>
|
|
{
|
|
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<bit l, bit r, bits<2> op2_1, bit op0, dag outs,
|
|
dag ins, string asmstr,
|
|
list<dag> patterns, InstrItinClass itin>
|
|
: A64InstRtnm<outs, ins, asmstr, patterns, itin>
|
|
{
|
|
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<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-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<bit u, bits<5> opcode,
|
|
dag outs, dag ins, string asmstr,
|
|
list<dag> patterns, InstrItinClass itin>
|
|
: A64InstRdn<outs, ins, asmstr, patterns, itin> {
|
|
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<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-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<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-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<bits<2> size, bits<3> opcode,
|
|
dag outs, dag ins, string asmstr,
|
|
list<dag> patterns, InstrItinClass itin>
|
|
: A64InstRdnm<outs, ins, asmstr, patterns, itin> {
|
|
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<bit u, bit szhi, bit szlo,
|
|
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} = 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<dag outs, dag ins, string asmstr,
|
|
list<dag> patterns, InstrItinClass itin>
|
|
: NeonI_copy<0b1, 0b0, 0b0000, outs, ins, asmstr, patterns, itin> {
|
|
let Inst{28} = 0b1;
|
|
}
|
|
}
|
|
|