[llvm] r320023 - [RISCV] MC layer support for the standard RV32D instruction set extension
Alex Bradbury via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 7 02:46:24 PST 2017
Author: asb
Date: Thu Dec 7 02:46:23 2017
New Revision: 320023
URL: http://llvm.org/viewvc/llvm-project?rev=320023&view=rev
Log:
[RISCV] MC layer support for the standard RV32D instruction set extension
As the FPR32 and FPR64 registers have the same names, use
validateTargetOperandClass in RISCVAsmParser to coerce a parsed FPR32 to an
FPR64 when necessary. The rest of this patch is very similar to the RV32F
patch.
Differential Revision: https://reviews.llvm.org/D39895
Added:
llvm/trunk/lib/Target/RISCV/RISCVInstrInfoD.td
llvm/trunk/test/MC/RISCV/rv32d-invalid.s
llvm/trunk/test/MC/RISCV/rv32d-valid.s
Modified:
llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
llvm/trunk/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
llvm/trunk/lib/Target/RISCV/RISCV.td
llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td
llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.td
llvm/trunk/lib/Target/RISCV/RISCVSubtarget.h
llvm/trunk/test/MC/RISCV/rv32f-invalid.s
Modified: llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp?rev=320023&r1=320022&r2=320023&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp Thu Dec 7 02:46:23 2017
@@ -32,6 +32,9 @@ struct RISCVOperand;
class RISCVAsmParser : public MCTargetAsmParser {
SMLoc getLoc() const { return getParser().getTok().getLoc(); }
+ unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
+ unsigned Kind) override;
+
bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
int Lower, int Upper, Twine Msg);
@@ -381,6 +384,67 @@ public:
#define GET_MATCHER_IMPLEMENTATION
#include "RISCVGenAsmMatcher.inc"
+// Return the matching FPR64 register for the given FPR32.
+// FIXME: Ideally this function could be removed in favour of using
+// information from TableGen.
+unsigned convertFPR32ToFPR64(unsigned Reg) {
+ switch (Reg) {
+ default:
+ llvm_unreachable("Not a recognised FPR32 register");
+ case RISCV::F0_32: return RISCV::F0_64;
+ case RISCV::F1_32: return RISCV::F1_64;
+ case RISCV::F2_32: return RISCV::F2_64;
+ case RISCV::F3_32: return RISCV::F3_64;
+ case RISCV::F4_32: return RISCV::F4_64;
+ case RISCV::F5_32: return RISCV::F5_64;
+ case RISCV::F6_32: return RISCV::F6_64;
+ case RISCV::F7_32: return RISCV::F7_64;
+ case RISCV::F8_32: return RISCV::F8_64;
+ case RISCV::F9_32: return RISCV::F9_64;
+ case RISCV::F10_32: return RISCV::F10_64;
+ case RISCV::F11_32: return RISCV::F11_64;
+ case RISCV::F12_32: return RISCV::F12_64;
+ case RISCV::F13_32: return RISCV::F13_64;
+ case RISCV::F14_32: return RISCV::F14_64;
+ case RISCV::F15_32: return RISCV::F15_64;
+ case RISCV::F16_32: return RISCV::F16_64;
+ case RISCV::F17_32: return RISCV::F17_64;
+ case RISCV::F18_32: return RISCV::F18_64;
+ case RISCV::F19_32: return RISCV::F19_64;
+ case RISCV::F20_32: return RISCV::F20_64;
+ case RISCV::F21_32: return RISCV::F21_64;
+ case RISCV::F22_32: return RISCV::F22_64;
+ case RISCV::F23_32: return RISCV::F23_64;
+ case RISCV::F24_32: return RISCV::F24_64;
+ case RISCV::F25_32: return RISCV::F25_64;
+ case RISCV::F26_32: return RISCV::F26_64;
+ case RISCV::F27_32: return RISCV::F27_64;
+ case RISCV::F28_32: return RISCV::F28_64;
+ case RISCV::F29_32: return RISCV::F29_64;
+ case RISCV::F30_32: return RISCV::F30_64;
+ case RISCV::F31_32: return RISCV::F31_64;
+ }
+}
+
+unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
+ unsigned Kind) {
+ RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp);
+ if (!Op.isReg())
+ return Match_InvalidOperand;
+
+ unsigned Reg = Op.getReg();
+ bool IsRegFPR32 =
+ RISCVMCRegisterClasses[RISCV::FPR32RegClassID].contains(Reg);
+
+ // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
+ // register from FPR32 to FPR64 if necessary.
+ if (IsRegFPR32 && Kind == MCK_FPR64) {
+ Op.Reg.RegNum = convertFPR32ToFPR64(Reg);
+ return Match_Success;
+ }
+ return Match_InvalidOperand;
+}
+
bool RISCVAsmParser::generateImmOutOfRangeError(
OperandVector &Operands, uint64_t ErrorInfo, int Lower, int Upper,
Twine Msg = "immediate must be an integer in the range") {
Modified: llvm/trunk/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp?rev=320023&r1=320022&r2=320023&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp Thu Dec 7 02:46:23 2017
@@ -105,6 +105,31 @@ static DecodeStatus DecodeFPR32RegisterC
return MCDisassembler::Success;
}
+static const unsigned FPR64DecoderTable[] = {
+ RISCV::F0_64, RISCV::F1_64, RISCV::F2_64, RISCV::F3_64,
+ RISCV::F4_64, RISCV::F5_64, RISCV::F6_64, RISCV::F7_64,
+ RISCV::F8_64, RISCV::F9_64, RISCV::F10_64, RISCV::F11_64,
+ RISCV::F12_64, RISCV::F13_64, RISCV::F14_64, RISCV::F15_64,
+ RISCV::F16_64, RISCV::F17_64, RISCV::F18_64, RISCV::F19_64,
+ RISCV::F20_64, RISCV::F21_64, RISCV::F22_64, RISCV::F23_64,
+ RISCV::F24_64, RISCV::F25_64, RISCV::F26_64, RISCV::F27_64,
+ RISCV::F28_64, RISCV::F29_64, RISCV::F30_64, RISCV::F31_64
+};
+
+static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ if (RegNo > sizeof(FPR64DecoderTable))
+ return MCDisassembler::Fail;
+
+ // We must define our own mapping from RegNo to register identifier.
+ // Accessing index RegNo in the register class will work in the case that
+ // registers were added in ascending order, but not in general.
+ unsigned Reg = FPR64DecoderTable[RegNo];
+ Inst.addOperand(MCOperand::createReg(Reg));
+ return MCDisassembler::Success;
+}
+
template <unsigned N>
static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
int64_t Address, const void *Decoder) {
Modified: llvm/trunk/lib/Target/RISCV/RISCV.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCV.td?rev=320023&r1=320022&r2=320023&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCV.td (original)
+++ llvm/trunk/lib/Target/RISCV/RISCV.td Thu Dec 7 02:46:23 2017
@@ -31,6 +31,13 @@ def FeatureStdExtF
def HasStdExtF : Predicate<"Subtarget->hasStdExtF()">,
AssemblerPredicate<"FeatureStdExtF">;
+def FeatureStdExtD
+ : SubtargetFeature<"d", "HasStdExtD", "true",
+ "'D' (Double-Precision Floating-Point)",
+ [FeatureStdExtF]>;
+def HasStdExtD : Predicate<"Subtarget->hasStdExtD()">,
+ AssemblerPredicate<"FeatureStdExtD">;
+
def Feature64Bit
: SubtargetFeature<"64bit", "HasRV64", "true", "Implements RV64">;
@@ -63,6 +70,7 @@ def RISCVInstrInfo : InstrInfo {
def RISCVAsmParser : AsmParser {
let ShouldEmitMatchRegisterAltName = 1;
+ let AllowDuplicateRegisterNames = 1;
}
def RISCV : Target {
Modified: llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td?rev=320023&r1=320022&r2=320023&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td Thu Dec 7 02:46:23 2017
@@ -442,3 +442,4 @@ def ADJCALLSTACKUP : Pseudo<(outs), (i
include "RISCVInstrInfoM.td"
include "RISCVInstrInfoA.td"
include "RISCVInstrInfoF.td"
+include "RISCVInstrInfoD.td"
Added: llvm/trunk/lib/Target/RISCV/RISCVInstrInfoD.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVInstrInfoD.td?rev=320023&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVInstrInfoD.td (added)
+++ llvm/trunk/lib/Target/RISCV/RISCVInstrInfoD.td Thu Dec 7 02:46:23 2017
@@ -0,0 +1,131 @@
+//===-- RISCVInstrInfoD.td - RISC-V 'D' instructions -------*- 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 the RISC-V instructions from the standard 'D',
+// Double-Precision Floating-Point instruction set extension.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Instruction Class Templates
+//===----------------------------------------------------------------------===//
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class FPFMAD_rrr_frm<RISCVOpcode opcode, string opcodestr>
+ : RVInstR4<0b01, opcode, (outs FPR64:$rd),
+ (ins FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, frmarg:$funct3),
+ opcodestr, "$rd, $rs1, $rs2, $rs3, $funct3">;
+
+class FPFMADDynFrmAlias<FPFMAD_rrr_frm Inst, string OpcodeStr>
+ : InstAlias<OpcodeStr#" $rd, $rs1, $rs2, $rs3",
+ (Inst FPR64:$rd, FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>;
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class FPALUD_rr<bits<7> funct7, bits<3> funct3, string opcodestr>
+ : RVInstR<funct7, funct3, OPC_OP_FP, (outs FPR64:$rd),
+ (ins FPR64:$rs1, FPR64:$rs2), opcodestr, "$rd, $rs1, $rs2">;
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class FPALUD_rr_frm<bits<7> funct7, string opcodestr>
+ : RVInstRFrm<funct7, OPC_OP_FP, (outs FPR64:$rd),
+ (ins FPR64:$rs1, FPR64:$rs2, frmarg:$funct3), opcodestr,
+ "$rd, $rs1, $rs2, $funct3">;
+
+class FPALUDDynFrmAlias<FPALUD_rr_frm Inst, string OpcodeStr>
+ : InstAlias<OpcodeStr#" $rd, $rs1, $rs2",
+ (Inst FPR64:$rd, FPR64:$rs1, FPR64:$rs2, 0b111)>;
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class FPCmpD_rr<bits<3> funct3, string opcodestr>
+ : RVInstR<0b1010001, funct3, OPC_OP_FP, (outs GPR:$rd),
+ (ins FPR64:$rs1, FPR64:$rs2), opcodestr, "$rd, $rs1, $rs2">;
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasStdExtD] in {
+
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+def FLD : RVInstI<0b011, OPC_LOAD_FP, (outs FPR64:$rd),
+ (ins GPR:$rs1, simm12:$imm12),
+ "fld", "$rd, ${imm12}(${rs1})">;
+
+// Operands for stores are in the order srcreg, base, offset rather than
+// reflecting the order these fields are specified in the instruction
+// encoding.
+let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
+def FSD : RVInstS<0b011, OPC_STORE_FP, (outs),
+ (ins FPR64:$rs2, GPR:$rs1, simm12:$imm12),
+ "fsd", "$rs2, ${imm12}(${rs1})">;
+
+def FMADD_D : FPFMAD_rrr_frm<OPC_MADD, "fmadd.d">;
+def : FPFMADDynFrmAlias<FMADD_D, "fmadd.d">;
+def FMSUB_D : FPFMAD_rrr_frm<OPC_MSUB, "fmsub.d">;
+def : FPFMADDynFrmAlias<FMSUB_D, "fmsub.d">;
+def FNMSUB_D : FPFMAD_rrr_frm<OPC_NMSUB, "fnmsub.d">;
+def : FPFMADDynFrmAlias<FNMSUB_D, "fnmsub.d">;
+def FNMADD_D : FPFMAD_rrr_frm<OPC_NMADD, "fnmadd.d">;
+def : FPFMADDynFrmAlias<FNMADD_D, "fnmadd.d">;
+
+def FADD_D : FPALUD_rr_frm<0b0000001, "fadd.d">;
+def : FPALUDDynFrmAlias<FADD_D, "fadd.d">;
+def FSUB_D : FPALUD_rr_frm<0b0000101, "fsub.d">;
+def : FPALUDDynFrmAlias<FSUB_D, "fsub.d">;
+def FMUL_D : FPALUD_rr_frm<0b0001001, "fmul.d">;
+def : FPALUDDynFrmAlias<FMUL_D, "fmul.d">;
+def FDIV_D : FPALUD_rr_frm<0b0001101, "fdiv.d">;
+def : FPALUDDynFrmAlias<FDIV_D, "fdiv.d">;
+
+def FSQRT_D : FPUnaryOp_r_frm<0b0101101, FPR64, FPR64, "fsqrt.d"> {
+ let rs2 = 0b00000;
+}
+def : FPUnaryOpDynFrmAlias<FSQRT_D, "fsqrt.d", FPR64, FPR64>;
+
+def FSGNJ_D : FPALUD_rr<0b0010001, 0b000, "fsgnj.d">;
+def FSGNJN_D : FPALUD_rr<0b0010001, 0b001, "fsgnjn.d">;
+def FSGNJX_D : FPALUD_rr<0b0010001, 0b010, "fsgnjx.d">;
+def FMIN_D : FPALUD_rr<0b0010101, 0b000, "fmin.d">;
+def FMAX_D : FPALUD_rr<0b0010101, 0b001, "fmax.d">;
+
+def FCVT_S_D : FPUnaryOp_r_frm<0b0100000, FPR32, FPR64, "fcvt.s.d"> {
+ let rs2 = 0b00001;
+}
+def : FPUnaryOpDynFrmAlias<FCVT_S_D, "fcvt.s.d", FPR32, FPR64>;
+
+def FCVT_D_S : FPUnaryOp_r<0b0100001, 0b000, FPR64, FPR32, "fcvt.d.s"> {
+ let rs2 = 0b00000;
+}
+
+def FEQ_D : FPCmpD_rr<0b010, "feq.d">;
+def FLT_D : FPCmpD_rr<0b001, "flt.d">;
+def FLE_D : FPCmpD_rr<0b000, "fle.d">;
+
+def FCLASS_D : FPUnaryOp_r<0b1110001, 0b001, GPR, FPR64, "fclass.d"> {
+ let rs2 = 0b00000;
+}
+
+def FCVT_W_D : FPUnaryOp_r_frm<0b1100001, GPR, FPR64, "fcvt.w.d"> {
+ let rs2 = 0b00000;
+}
+def : FPUnaryOpDynFrmAlias<FCVT_W_D, "fcvt.w.d", GPR, FPR64>;
+
+def FCVT_WU_D : FPUnaryOp_r_frm<0b1100001, GPR, FPR64, "fcvt.wu.d"> {
+ let rs2 = 0b00001;
+}
+def : FPUnaryOpDynFrmAlias<FCVT_WU_D, "fcvt.wu.d", GPR, FPR64>;
+
+def FCVT_D_W : FPUnaryOp_r<0b1101001, 0b000, FPR64, GPR, "fcvt.d.w"> {
+ let rs2 = 0b00000;
+}
+
+def FCVT_D_WU : FPUnaryOp_r<0b1101001, 0b000, FPR64, GPR, "fcvt.d.wu"> {
+ let rs2 = 0b00001;
+}
+} // Predicates = [HasStdExtD]
Modified: llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.td?rev=320023&r1=320022&r2=320023&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.td (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.td Thu Dec 7 02:46:23 2017
@@ -22,6 +22,18 @@ class RISCVReg32<bits<5> Enc, string n,
let AltNames = alt;
}
+// Because RISCVReg64 register have AsmName and AltNames that alias with their
+// 32-bit sub-register, RISCVAsmParser will need to coerce a register number
+// from a RISCVReg32 to the equivalent RISCVReg64 when appropriate.
+def sub_32 : SubRegIndex<32>;
+class RISCVReg64<RISCVReg32 subreg> : Register<""> {
+ let HWEncoding{4-0} = subreg.HWEncoding{4-0};
+ let SubRegs = [subreg];
+ let SubRegIndices = [sub_32];
+ let AsmName = subreg.AsmName;
+ let AltNames = subreg.AltNames;
+}
+
def ABIRegAltName : RegAltNameIndex;
} // Namespace = "RISCV"
@@ -113,6 +125,11 @@ let RegAltNameIndices = [ABIRegAltName]
def F29_32 : RISCVReg32<29,"f29", ["ft9"]>, DwarfRegNum<[61]>;
def F30_32 : RISCVReg32<30,"f30", ["ft10"]>, DwarfRegNum<[62]>;
def F31_32 : RISCVReg32<31,"f31", ["ft11"]>, DwarfRegNum<[63]>;
+
+ foreach Index = 0-31 in {
+ def F#Index#_64 : RISCVReg64<!cast<RISCVReg32>("F"#Index#"_32")>,
+ DwarfRegNum<[!add(Index, 32)]>;
+ }
}
// The order of registers represents the preferred allocation sequence,
@@ -124,3 +141,13 @@ def FPR32 : RegisterClass<"RISCV", [f32]
(sequence "F%u_32", 8, 9),
(sequence "F%u_32", 18, 27)
)>;
+
+// The order of registers represents the preferred allocation sequence,
+// meaning caller-save regs are listed before callee-save.
+def FPR64 : RegisterClass<"RISCV", [f64], 64, (add
+ (sequence "F%u_64", 0, 7),
+ (sequence "F%u_64", 10, 17),
+ (sequence "F%u_64", 28, 31),
+ (sequence "F%u_64", 8, 9),
+ (sequence "F%u_64", 18, 27)
+)>;
Modified: llvm/trunk/lib/Target/RISCV/RISCVSubtarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVSubtarget.h?rev=320023&r1=320022&r2=320023&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVSubtarget.h (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVSubtarget.h Thu Dec 7 02:46:23 2017
@@ -33,6 +33,7 @@ class RISCVSubtarget : public RISCVGenSu
bool HasStdExtM = false;
bool HasStdExtA = false;
bool HasStdExtF = false;
+ bool HasStdExtD = false;
bool HasRV64 = false;
unsigned XLen = 32;
MVT XLenVT = MVT::i32;
@@ -72,6 +73,7 @@ public:
bool hasStdExtM() const { return HasStdExtM; }
bool hasStdExtA() const { return HasStdExtA; }
bool hasStdExtF() const { return HasStdExtF; }
+ bool hasStdExtD() const { return HasStdExtD; }
bool is64Bit() const { return HasRV64; }
MVT getXLenVT() const { return XLenVT; }
unsigned getXLen() const { return XLen; }
Added: llvm/trunk/test/MC/RISCV/rv32d-invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv32d-invalid.s?rev=320023&view=auto
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv32d-invalid.s (added)
+++ llvm/trunk/test/MC/RISCV/rv32d-invalid.s Thu Dec 7 02:46:23 2017
@@ -0,0 +1,21 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+d < %s 2>&1 | FileCheck %s
+
+# Out of range immediates
+## simm12
+fld ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-2048, 2047]
+fsd ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-2048, 2047]
+
+# Memory operand not formatted correctly
+fld ft1, a0, -200 # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-2048, 2047]
+fsd ft2, a1, 100 # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-2048, 2047]
+
+# Invalid register names
+fld ft15, 100(a0) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction
+fld ft1, 100(a10) # CHECK: :[[@LINE]]:14: error: expected register
+fsgnjn.d fa100, fa2, fa3 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction
+
+# Integer registers where FP regs are expected
+fadd.d a2, a1, a0 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
+
+# FP registers where integer regs are expected
+fcvt.wu.d ft2, a1 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction
Added: llvm/trunk/test/MC/RISCV/rv32d-valid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv32d-valid.s?rev=320023&view=auto
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv32d-valid.s (added)
+++ llvm/trunk/test/MC/RISCV/rv32d-valid.s Thu Dec 7 02:46:23 2017
@@ -0,0 +1,159 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+d -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+d -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+d < %s \
+# RUN: | llvm-objdump -mattr=+d -d - | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+d < %s \
+# RUN: | llvm-objdump -mattr=+d -d - | FileCheck -check-prefix=CHECK-INST %s
+
+# Support for the 'D' extension implies support for 'F'
+# CHECK-INST: fadd.s fs10, fs11, ft8
+# CHECK: encoding: [0x53,0xfd,0xcd,0x01]
+fadd.s f26, f27, f28
+
+# CHECK-INST: fld ft0, 12(a0)
+# CHECK: encoding: [0x07,0x30,0xc5,0x00]
+fld f0, 12(a0)
+# CHECK-INST: fld ft1, 4(ra)
+# CHECK: encoding: [0x87,0xb0,0x40,0x00]
+fld f1, +4(ra)
+# CHECK-INST: fld ft2, -2048(a3)
+# CHECK: encoding: [0x07,0xb1,0x06,0x80]
+fld f2, -2048(x13)
+# CHECK-INST: fld ft3, -2048(s1)
+# CHECK: encoding: [0x87,0xb1,0x04,0x80]
+fld f3, %lo(2048)(s1)
+# CHECK-INST: fld ft4, 2047(s2)
+# CHECK: encoding: [0x07,0x32,0xf9,0x7f]
+fld f4, 2047(s2)
+# CHECK-INST: fld ft5, 0(s3)
+# CHECK: encoding: [0x87,0xb2,0x09,0x00]
+fld f5, 0(s3)
+
+# CHECK-INST: fsd ft6, 2047(s4)
+# CHECK: encoding: [0xa7,0x3f,0x6a,0x7e]
+fsd f6, 2047(s4)
+# CHECK-INST: fsd ft7, -2048(s5)
+# CHECK: encoding: [0x27,0xb0,0x7a,0x80]
+fsd f7, -2048(s5)
+# CHECK-INST: fsd fs0, -2048(s6)
+# CHECK: encoding: [0x27,0x30,0x8b,0x80]
+fsd f8, %lo(2048)(s6)
+# CHECK-INST: fsd fs1, 999(s7)
+# CHECK: encoding: [0xa7,0xb3,0x9b,0x3e]
+fsd f9, 999(s7)
+
+# CHECK-INST: fmadd.d fa0, fa1, fa2, fa3
+# CHECK: encoding: [0x43,0xf5,0xc5,0x6a]
+fmadd.d f10, f11, f12, f13
+# CHECK-INST: fmsub.d fa4, fa5, fa6, fa7
+# CHECK: encoding: [0x47,0xf7,0x07,0x8b]
+fmsub.d f14, f15, f16, f17
+# CHECK-INST: fnmsub.d fs2, fs3, fs4, fs5
+# CHECK: encoding: [0x4b,0xf9,0x49,0xab]
+fnmsub.d f18, f19, f20, f21
+# CHECK-INST: fnmadd.d fs6, fs7, fs8, fs9
+# CHECK: encoding: [0x4f,0xfb,0x8b,0xcb]
+fnmadd.d f22, f23, f24, f25
+
+# CHECK-INST: fadd.d fs10, fs11, ft8
+# CHECK: encoding: [0x53,0xfd,0xcd,0x03]
+fadd.d f26, f27, f28
+# CHECK-INST: fsub.d ft9, ft10, ft11
+# CHECK: encoding: [0xd3,0x7e,0xff,0x0b]
+fsub.d f29, f30, f31
+# CHECK-INST: fmul.d ft0, ft1, ft2
+# CHECK: encoding: [0x53,0xf0,0x20,0x12]
+fmul.d ft0, ft1, ft2
+# CHECK-INST: fdiv.d ft3, ft4, ft5
+# CHECK: encoding: [0xd3,0x71,0x52,0x1a]
+fdiv.d ft3, ft4, ft5
+# CHECK-INST: fsqrt.d ft6, ft7
+# CHECK: encoding: [0x53,0xf3,0x03,0x5a]
+fsqrt.d ft6, ft7
+# CHECK-INST: fsgnj.d fs1, fa0, fa1
+# CHECK: encoding: [0xd3,0x04,0xb5,0x22]
+fsgnj.d fs1, fa0, fa1
+# CHECK-INST: fsgnjn.d fa1, fa3, fa4
+# CHECK: encoding: [0xd3,0x95,0xe6,0x22]
+fsgnjn.d fa1, fa3, fa4
+# CHECK-INST: fsgnjx.d fa3, fa2, fa1
+# CHECK: encoding: [0xd3,0x26,0xb6,0x22]
+fsgnjx.d fa3, fa2, fa1
+# CHECK-INST: fmin.d fa5, fa6, fa7
+# CHECK: encoding: [0xd3,0x07,0x18,0x2b]
+fmin.d fa5, fa6, fa7
+# CHECK-INST: fmax.d fs2, fs3, fs4
+# CHECK: encoding: [0x53,0x99,0x49,0x2b]
+fmax.d fs2, fs3, fs4
+
+# CHECK-INST: fcvt.s.d fs5, fs6
+# CHECK: encoding: [0xd3,0x7a,0x1b,0x40]
+fcvt.s.d fs5, fs6
+# CHECK-INST: fcvt.d.s fs7, fs8
+# CHECK: encoding: [0xd3,0x0b,0x0c,0x42]
+fcvt.d.s fs7, fs8
+# CHECK-INST: feq.d a1, fs8, fs9
+# CHECK: encoding: [0xd3,0x25,0x9c,0xa3]
+feq.d a1, fs8, fs9
+# CHECK-INST: flt.d a2, fs10, fs11
+# CHECK: encoding: [0x53,0x16,0xbd,0xa3]
+flt.d a2, fs10, fs11
+# CHECK-INST: fle.d a3, ft8, ft9
+# CHECK: encoding: [0xd3,0x06,0xde,0xa3]
+fle.d a3, ft8, ft9
+# CHECK-INST: fclass.d a3, ft10
+# CHECK: encoding: [0xd3,0x16,0x0f,0xe2]
+fclass.d a3, ft10
+
+# CHECK-INST: fcvt.w.d a4, ft11
+# CHECK: encoding: [0x53,0xf7,0x0f,0xc2]
+fcvt.w.d a4, ft11
+# CHECK-INST: fcvt.d.w ft0, a5
+# CHECK: encoding: [0x53,0x80,0x07,0xd2]
+fcvt.d.w ft0, a5
+# CHECK-INST: fcvt.d.wu ft1, a6
+# CHECK: encoding: [0xd3,0x00,0x18,0xd2]
+fcvt.d.wu ft1, a6
+
+# Rounding modes
+
+# CHECK-INST: fmadd.d fa0, fa1, fa2, fa3, rne
+# CHECK: encoding: [0x43,0x85,0xc5,0x6a]
+fmadd.d f10, f11, f12, f13, rne
+# CHECK-INST: fmsub.d fa4, fa5, fa6, fa7, rtz
+# CHECK: encoding: [0x47,0x97,0x07,0x8b]
+fmsub.d f14, f15, f16, f17, rtz
+# CHECK-INST: fnmsub.d fs2, fs3, fs4, fs5, rdn
+# CHECK: encoding: [0x4b,0xa9,0x49,0xab]
+fnmsub.d f18, f19, f20, f21, rdn
+# CHECK-INST: fnmadd.d fs6, fs7, fs8, fs9, rup
+# CHECK: encoding: [0x4f,0xbb,0x8b,0xcb]
+fnmadd.d f22, f23, f24, f25, rup
+
+# CHECK-INST: fadd.d fs10, fs11, ft8, rmm
+# CHECK: encoding: [0x53,0xcd,0xcd,0x03]
+fadd.d f26, f27, f28, rmm
+# CHECK-INST: fsub.d ft9, ft10, ft11
+# CHECK: encoding: [0xd3,0x7e,0xff,0x0b]
+fsub.d f29, f30, f31, dyn
+# CHECK-INST: fmul.d ft0, ft1, ft2, rne
+# CHECK: encoding: [0x53,0x80,0x20,0x12]
+fmul.d ft0, ft1, ft2, rne
+# CHECK-INST: fdiv.d ft3, ft4, ft5, rtz
+# CHECK: encoding: [0xd3,0x11,0x52,0x1a]
+fdiv.d ft3, ft4, ft5, rtz
+
+# CHECK-INST: fsqrt.d ft6, ft7, rdn
+# CHECK: encoding: [0x53,0xa3,0x03,0x5a]
+fsqrt.d ft6, ft7, rdn
+# CHECK-INST: fcvt.s.d fs5, fs6, rup
+# CHECK: encoding: [0xd3,0x3a,0x1b,0x40]
+fcvt.s.d fs5, fs6, rup
+# CHECK-INST: fcvt.w.d a4, ft11, rmm
+# CHECK: encoding: [0x53,0xc7,0x0f,0xc2]
+fcvt.w.d a4, ft11, rmm
+# CHECK-INST: fcvt.wu.d a5, ft10
+# CHECK: encoding: [0xd3,0x77,0x1f,0xc2]
+fcvt.wu.d a5, ft10, dyn
Modified: llvm/trunk/test/MC/RISCV/rv32f-invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv32f-invalid.s?rev=320023&r1=320022&r2=320023&view=diff
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv32f-invalid.s (original)
+++ llvm/trunk/test/MC/RISCV/rv32f-invalid.s Thu Dec 7 02:46:23 2017
@@ -27,3 +27,6 @@ fmadd.s f10, f11, f12, ree # CHECK: :[[@
fmadd.s f10, f11, f12, f13, ree # CHECK: :[[@LINE]]:29: error: operand must be a valid floating point rounding mode mnemonic
fmsub.s f14, f15, f16, f17, 0 # CHECK: :[[@LINE]]:29: error: operand must be a valid floating point rounding mode mnemonic
fnmsub.s f18, f19, f20, f21, 0b111 # CHECK: :[[@LINE]]:30: error: operand must be a valid floating point rounding mode mnemonic
+
+# Using 'D' instructions for an 'F'-only target
+fadd.d ft0, ft1, ft2 # CHECK: :[[@LINE]]:1: error: instruction use requires an option to be enabled
More information about the llvm-commits
mailing list