def AdrpOperand : AsmOperandClass {
let Name = "AdrpLabel";
let ParserMethod = "tryParseAdrpLabel";
+ let DiagnosticType = "InvalidLabel";
}
def adrplabel : Operand<i64> {
let EncoderMethod = "getAdrLabelOpValue";
def AdrOperand : AsmOperandClass {
let Name = "AdrLabel";
let ParserMethod = "tryParseAdrLabel";
+ let DiagnosticType = "InvalidLabel";
}
def adrlabel : Operand<i64> {
let EncoderMethod = "getAdrLabelOpValue";
def fixedpoint32 : Operand<i32> {
let EncoderMethod = "getFixedPointScaleOpValue";
- let DecoderMethod = "DecodeFixedPointScaleImm";
+ let DecoderMethod = "DecodeFixedPointScaleImm32";
let ParserMatchClass = Imm1_32Operand;
}
def fixedpoint64 : Operand<i64> {
let EncoderMethod = "getFixedPointScaleOpValue";
- let DecoderMethod = "DecodeFixedPointScaleImm";
+ let DecoderMethod = "DecodeFixedPointScaleImm64";
let ParserMatchClass = Imm1_64Operand;
}
let ParserMatchClass = Imm0_127Operand;
}
+// NOTE: These imm0_N operands have to be of type i64 because i64 is the size
+// for all shift-amounts.
+
// imm0_63 predicate - True if the immediate is in the range [0,63]
-// NOTE: This has to be of type i64 because i64 is the shift-amount-size
-// for X registers.
def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
return ((uint64_t)Imm) < 64;
}]> {
let ParserMatchClass = Imm0_63Operand;
}
-// imm0_31x predicate - True if the immediate is in the range [0,31]
-// NOTE: This has to be of type i64 because i64 is the shift-amount-size
-// for X registers.
-def imm0_31x : Operand<i64>, ImmLeaf<i64, [{
- return ((uint64_t)Imm) < 32;
-}]> {
- let ParserMatchClass = Imm0_31Operand;
-}
-
-// imm0_15x predicate - True if the immediate is in the range [0,15]
-def imm0_15x : Operand<i64>, ImmLeaf<i64, [{
- return ((uint64_t)Imm) < 16;
-}]> {
- let ParserMatchClass = Imm0_15Operand;
-}
-
-// imm0_7x predicate - True if the immediate is in the range [0,7]
-def imm0_7x : Operand<i64>, ImmLeaf<i64, [{
- return ((uint64_t)Imm) < 8;
-}]> {
- let ParserMatchClass = Imm0_7Operand;
-}
-
// imm0_31 predicate - True if the immediate is in the range [0,31]
-// NOTE: This has to be of type i32 because i32 is the shift-amount-size
-// for W registers.
-def imm0_31 : Operand<i32>, ImmLeaf<i32, [{
- return ((uint32_t)Imm) < 32;
+def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
+ return ((uint64_t)Imm) < 32;
}]> {
let ParserMatchClass = Imm0_31Operand;
}
// imm0_15 predicate - True if the immediate is in the range [0,15]
-def imm0_15 : Operand<i32>, ImmLeaf<i32, [{
- return ((uint32_t)Imm) < 16;
+def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
+ return ((uint64_t)Imm) < 16;
}]> {
let ParserMatchClass = Imm0_15Operand;
}
// imm0_7 predicate - True if the immediate is in the range [0,7]
-def imm0_7 : Operand<i32>, ImmLeaf<i32, [{
- return ((uint32_t)Imm) < 8;
+def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
+ return ((uint64_t)Imm) < 8;
}]> {
let ParserMatchClass = Imm0_7Operand;
}
//---
-// Sytem management
+// System management
//---
// Base encoding for system instruction operands.
let Inst{7-5} = opc;
}
-// MRS/MSR system instructions.
-def SystemRegisterOperand : AsmOperandClass {
- let Name = "SystemRegister";
- let ParserMethod = "tryParseSystemRegister";
+// MRS/MSR system instructions. These have different operand classes because
+// a different subset of registers can be accessed through each instruction.
+def MRSSystemRegisterOperand : AsmOperandClass {
+ let Name = "MRSSystemRegister";
+ let ParserMethod = "tryParseSysReg";
}
// concatenation of 1, op0, op1, CRn, CRm, op2. 16-bit immediate.
-def sysreg_op : Operand<i32> {
- let ParserMatchClass = SystemRegisterOperand;
- let DecoderMethod = "DecodeSystemRegister";
- let PrintMethod = "printSystemRegister";
+def mrs_sysreg_op : Operand<i32> {
+ let ParserMatchClass = MRSSystemRegisterOperand;
+ let DecoderMethod = "DecodeMRSSystemRegister";
+ let PrintMethod = "printMRSSystemRegister";
+}
+
+def MSRSystemRegisterOperand : AsmOperandClass {
+ let Name = "MSRSystemRegister";
+ let ParserMethod = "tryParseSysReg";
+}
+def msr_sysreg_op : Operand<i32> {
+ let ParserMatchClass = MSRSystemRegisterOperand;
+ let DecoderMethod = "DecodeMSRSystemRegister";
+ let PrintMethod = "printMSRSystemRegister";
}
-class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins sysreg_op:$systemreg),
+class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
"mrs", "\t$Rt, $systemreg"> {
bits<15> systemreg;
let Inst{20} = 1;
// FIXME: Some of these def CPSR, others don't. Best way to model that?
// Explicitly modeling each of the system register as a register class
// would do it, but feels like overkill at this point.
-class MSRI : RtSystemI<0, (outs), (ins sysreg_op:$systemreg, GPR64:$Rt),
+class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
"msr", "\t$systemreg, $Rt"> {
bits<15> systemreg;
let Inst{20} = 1;
def SystemCPSRFieldOperand : AsmOperandClass {
let Name = "SystemCPSRField";
- let ParserMethod = "tryParseCPSRField";
+ let ParserMethod = "tryParseSysReg";
}
def cpsrfield_op : Operand<i32> {
let ParserMatchClass = SystemCPSRFieldOperand;
let ParserMatchClass = SysCRAsmOperand;
}
-class SystemI<bit L, string asm>
- : SimpleSystemI<L,
- (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
- asm, "\t$op1, $Cn, $Cm, $op2">,
- Sched<[WriteSys]> {
- bits<3> op1;
- bits<4> Cn;
- bits<4> Cm;
- bits<3> op2;
- let Inst{20-19} = 0b01;
- let Inst{18-16} = op1;
- let Inst{15-12} = Cn;
- let Inst{11-8} = Cm;
- let Inst{7-5} = op2;
-}
-
class SystemXtI<bit L, string asm>
: RtSystemI<L, (outs),
(ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
}
}
-class BaseShift<bits<2> shift_type, RegisterClass regtype,
- string asm, SDNode OpNode>
+class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
+ SDPatternOperator OpNode = null_frag>
: BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
Sched<[WriteIS]> {
let Inst{11-10} = shift_type;
}
multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
- def Wr : BaseShift<shift_type, GPR32, asm, OpNode> {
+ def Wr : BaseShift<shift_type, GPR32, asm> {
let Inst{31} = 0;
}
def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
let Inst{31} = 1;
}
+
+ def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
+ (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
+ (EXTRACT_SUBREG i64:$Rm, sub_32))>;
+
+ def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
+ (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
+
+ def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
+ (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
+
+ def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
+ (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
}
class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
let Inst{31-24} = 0b10011011;
let Inst{23-21} = opc;
let Inst{20-16} = Rm;
- let Inst{15-10} = 0b011111;
+ let Inst{15} = 0;
let Inst{9-5} = Rn;
let Inst{4-0} = Rd;
+
+ // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
+ // (i.e. all bits 1) but is ignored by the processor.
+ let PostEncoderMethod = "fixMulHigh";
}
class MulAccumWAlias<string asm, Instruction inst>
// Extract
//---
def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
- SDTCisSameAs<0, 3>]>;
+ SDTCisPtrTy<3>]>;
def ARM64Extr : SDNode<"ARM64ISD::EXTR", SDTA64EXTR>;
class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
(ARM64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
let Inst{31} = 0;
let Inst{22} = 0;
+ // imm<5> must be zero.
+ let imm{5} = 0;
}
def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
[(set GPR64:$Rd,
def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
let Inst{31} = 0;
let Inst{22} = 0;
+ // imms<5> and immr<5> must be zero, else ReservedValue().
+ let Inst{21} = 0;
+ let Inst{15} = 0;
}
def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
let Inst{31} = 1;
def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
let Inst{31} = 0;
let Inst{22} = 0;
+ // imms<5> and immr<5> must be zero, else ReservedValue().
+ let Inst{21} = 0;
+ let Inst{15} = 0;
}
def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
let Inst{31} = 1;
let ParserMatchClass = MemoryUnscaledOperand;
let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
}
+class am_unscaled_wb_operand : Operand<i64> {
+ let PrintMethod = "printAMUnscaledWB";
+ let ParserMatchClass = MemoryUnscaledOperand;
+ let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
+}
def am_unscaled : am_unscaled_operand;
+def am_unscaled_wb: am_unscaled_wb_operand;
def am_unscaled8 : am_unscaled_operand,
ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
def am_unscaled16 : am_unscaled_operand,
string asm>
: BaseLoadStorePreIdx<sz, V, opc,
(outs regtype:$Rt/*, GPR64sp:$wback*/),
- (ins am_unscaled:$addr), asm, ""/*"$addr.base = $wback"*/>,
+ (ins am_unscaled_wb:$addr), asm, ""/*"$addr.base = $wback"*/>,
Sched<[WriteLD, WriteAdr]>;
let mayStore = 1, mayLoad = 0 in
string asm>
: BaseLoadStorePreIdx<sz, V, opc,
(outs/* GPR64sp:$wback*/),
- (ins regtype:$Rt, am_unscaled:$addr),
+ (ins regtype:$Rt, am_unscaled_wb:$addr),
asm, ""/*"$addr.base = $wback"*/>,
Sched<[WriteAdr, WriteST]>;
} // hasSideEffects = 0
let ParserMatchClass = MemoryIndexed32SImm7;
let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
}
+def am_indexed32simm7_wb : Operand<i32> { // ComplexPattern<...>
+ let PrintMethod = "printAMIndexed32WB";
+ let ParserMatchClass = MemoryIndexed32SImm7;
+ let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
+}
def MemoryIndexed64SImm7 : AsmOperandClass {
let Name = "MemoryIndexed64SImm7";
let ParserMatchClass = MemoryIndexed64SImm7;
let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
}
+def am_indexed64simm7_wb : Operand<i32> { // ComplexPattern<...>
+ let PrintMethod = "printAMIndexed64WB";
+ let ParserMatchClass = MemoryIndexed64SImm7;
+ let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
+}
def MemoryIndexed128SImm7 : AsmOperandClass {
let Name = "MemoryIndexed128SImm7";
let ParserMatchClass = MemoryIndexed128SImm7;
let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
}
+def am_indexed128simm7_wb : Operand<i32> { // ComplexPattern<...>
+ let PrintMethod = "printAMIndexed128WB";
+ let ParserMatchClass = MemoryIndexed128SImm7;
+ let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
+}
class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
string asm>
// True exclusive operations write to and/or read from the system's exclusive
// monitors, which as far as a compiler is concerned can be modelled as a
// random shared memory address. Hence LoadExclusive mayStore.
+//
+// Since these instructions have the undefined register bits set to 1 in
+// their canonical form, we need a post encoder method to set those bits
+// to 1 when encoding these instructions. We do this using the
+// fixLoadStoreExclusive function. This function has template parameters:
+//
+// fixLoadStoreExclusive<int hasRs, int hasRt2>
+//
+// hasRs indicates that the instruction uses the Rs field, so we won't set
+// it to 1 (and the same for Rt2). We don't need template parameters for
+// the other register fields since Rt and Rn are always used.
+//
let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
dag oops, dag iops, string asm, string operands>
: BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
bits<5> reg;
bits<5> base;
- let Inst{20-16} = 0b11111;
- let Inst{14-10} = 0b11111;
let Inst{9-5} = base;
let Inst{4-0} = reg;
+
+ let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
}
// Simple load acquires don't set the exclusive monitor
bits<5> dst1;
bits<5> dst2;
bits<5> base;
- let Inst{20-16} = 0b11111;
let Inst{14-10} = dst2;
let Inst{9-5} = base;
let Inst{4-0} = dst1;
+
+ let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
}
// Simple store release operations do not check the exclusive monitor.
bits<5> reg;
bits<5> base;
let Inst{20-16} = status;
- let Inst{14-10} = 0b11111;
let Inst{9-5} = base;
let Inst{4-0} = reg;
let Constraints = "@earlyclobber $Ws";
+ let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
}
class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
Sched<[WriteFCvt]> {
bits<5> Rd;
bits<5> Rn;
- let Inst{30} = 0;
+ let Inst{30-29} = 0b00;
let Inst{28-24} = 0b11110;
let Inst{23-22} = type;
let Inst{21} = 1;
bits<5> Rd;
bits<5> Rn;
bits<6> scale;
- let Inst{30} = 0;
+ let Inst{30-29} = 0b00;
let Inst{28-24} = 0b11110;
let Inst{23-22} = type;
let Inst{21} = 0;
let Inst{4-0} = Rd;
}
-multiclass FPToInteger<bits<2> rmode, bits<3> opcode, string asm, SDPatternOperator OpN> {
+multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
+ SDPatternOperator OpN> {
// Unscaled single-precision to 32-bit
def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
[(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
[(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
let Inst{31} = 1; // 64-bit GPR flag
}
+}
+multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
+ SDPatternOperator OpN> {
// Scaled single-precision to 32-bit
def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
fixedpoint32, asm> {
let Inst{31} = 0; // 32-bit GPR flag
+ let scale{5} = 1;
}
// Scaled single-precision to 64-bit
def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
fixedpoint32, asm> {
let Inst{31} = 0; // 32-bit GPR flag
+ let scale{5} = 1;
}
// Scaled double-precision to 64-bit
def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint32, asm> {
let Inst{31} = 0; // 32-bit GPR flag
let Inst{22} = 0; // 32-bit FPR flag
+ let scale{5} = 1;
}
def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint32, asm> {
let Inst{31} = 0; // 32-bit GPR flag
let Inst{22} = 1; // 64-bit FPR flag
+ let scale{5} = 1;
}
def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint64, asm> {
let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
- RegisterClass srcType, RegisterOperand dstType, string asm>
- : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd[1], $Rn", "", []>,
+ RegisterClass srcType, RegisterOperand dstType, string asm,
+ string kind>
+ : I<(outs dstType:$Rd), (ins srcType:$Rn), asm,
+ "{\t$Rd"#kind#"[1], $Rn|"#kind#"\t$Rd[1], $Rn}", "", []>,
Sched<[WriteFCopy]> {
bits<5> Rd;
bits<5> Rn;
let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
- RegisterOperand srcType, RegisterClass dstType, string asm>
- : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn[1]", "", []>,
+ RegisterOperand srcType, RegisterClass dstType, string asm,
+ string kind>
+ : I<(outs dstType:$Rd), (ins srcType:$Rn), asm,
+ "{\t$Rd, $Rn"#kind#"[1]|"#kind#"\t$Rd, $Rn[1]}", "", []>,
Sched<[WriteFCopy]> {
bits<5> Rd;
bits<5> Rn;
}
def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
- asm#".d"> {
+ asm, ".d"> {
let Inst{31} = 1;
let Inst{22} = 0;
}
def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
- asm#".d"> {
+ asm, ".d"> {
let Inst{31} = 1;
let Inst{22} = 0;
}
-
- def : InstAlias<asm#"$Vd.d[1], $Rn",
- (!cast<Instruction>(NAME#XDHighr) V128:$Vd, GPR64:$Rn), 0>;
- def : InstAlias<asm#"$Rd, $Vn.d[1]",
- (!cast<Instruction>(NAME#DXHighr) GPR64:$Rd, V128:$Vn), 0>;
}
//---
let Inst{31-23} = 0b000111100;
let Inst{21} = 1;
- let Inst{20-16} = 0b00000;
let Inst{15-10} = 0b001000;
let Inst{9-5} = Rn;
let Inst{4} = signalAllNans;
let Inst{3-0} = 0b1000;
+
+ // Rm should be 0b00000 canonically, but we need to accept any value.
+ let PostEncoderMethod = "fixOneOperandFPComparison";
}
let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
multiclass SIMDBitwiseExtract<string asm> {
- def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b">;
+ def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
+ let imm{3} = 0;
+ }
def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
}
SDPatternOperator OpNode = null_frag> {
def v1i64 : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
[(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
+
+ def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
+ (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
}
multiclass SIMDTwoScalarSD<bit U, bit S, bits<5> opc, string asm> {
(!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
}
-let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
Intrinsic OpNode> {
- def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
- [(set (v1i64 FPR64:$dst),
- (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn)))]>;
- def v1i32 : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR32, asm, []>;
- def v1i16 : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR16, asm, []>;
- def v1i8 : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
+ let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
+ def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
+ [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
+ def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
+ [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
+ def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
+ def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
+ }
+
+ def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
+ (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
}
SDPatternOperator OpNode> {
def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
FPR64, FPR64, vecshiftR64, asm,
- [(set (v1i64 FPR64:$Rd),
- (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
+ [(set (i64 FPR64:$Rd),
+ (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
let Inst{21-16} = imm{5-0};
}
+
+ def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
+ (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
}
-let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
SDPatternOperator OpNode = null_frag> {
def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
FPR64, FPR64, vecshiftR64, asm,
- [(set (v1i64 FPR64:$dst),
- (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
- (i32 vecshiftR64:$imm)))]> {
+ [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
+ (i32 vecshiftR64:$imm)))]> {
let Inst{21-16} = imm{5-0};
}
+
+ def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
+ (i32 vecshiftR64:$imm))),
+ (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
+ vecshiftR64:$imm)>;
}
multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
}
let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
- RegisterOperand listtype,
- RegisterOperand GPR64pi> {
+ RegisterOperand listtype, RegisterOperand GPR64pi> {
def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
(outs listtype:$dst),
(ins listtype:$Vt, VectorIndexD:$idx,
}
let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
- RegisterOperand listtype, list<dag> pattern,
- RegisterOperand GPR64pi> {
+ RegisterOperand listtype, RegisterOperand GPR64pi> {
def i8 : SIMDLdStSingleB<0, R, opcode, asm,
(outs), (ins listtype:$Vt, VectorIndexB:$idx,
- am_simdnoindex:$vaddr),
- pattern>;
+ am_simdnoindex:$vaddr), []>;
def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
(outs), (ins listtype:$Vt, VectorIndexB:$idx,
}
let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
- RegisterOperand listtype, list<dag> pattern,
- RegisterOperand GPR64pi> {
+ RegisterOperand listtype, RegisterOperand GPR64pi> {
def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
(outs), (ins listtype:$Vt, VectorIndexH:$idx,
- am_simdnoindex:$vaddr),
- pattern>;
+ am_simdnoindex:$vaddr), []>;
def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
(outs), (ins listtype:$Vt, VectorIndexH:$idx,
}
let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
- RegisterOperand listtype, list<dag> pattern,
- RegisterOperand GPR64pi> {
+ RegisterOperand listtype, RegisterOperand GPR64pi> {
def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
(outs), (ins listtype:$Vt, VectorIndexS:$idx,
- am_simdnoindex:$vaddr),
- pattern>;
+ am_simdnoindex:$vaddr), []>;
def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
(outs), (ins listtype:$Vt, VectorIndexS:$idx,
}
let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
- RegisterOperand listtype, list<dag> pattern,
- RegisterOperand GPR64pi> {
+ RegisterOperand listtype, RegisterOperand GPR64pi> {
def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
(outs), (ins listtype:$Vt, VectorIndexD:$idx,
- am_simdnoindex:$vaddr), pattern>;
+ am_simdnoindex:$vaddr), []>;
def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
(outs), (ins listtype:$Vt, VectorIndexD:$idx,
def : TokenAlias<".8H", ".8h">;
def : TokenAlias<".4S", ".4s">;
def : TokenAlias<".2D", ".2d">;
+def : TokenAlias<".1Q", ".1q">;
def : TokenAlias<".B", ".b">;
def : TokenAlias<".H", ".h">;
def : TokenAlias<".S", ".s">;
def : TokenAlias<".D", ".d">;
+def : TokenAlias<".Q", ".q">;