[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