[clang] [llvm] [RISCV][MC] Add support for Q extension (PR #139369)
via llvm-commits
llvm-commits at lists.llvm.org
Sat May 10 03:10:32 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mc
@llvm/pr-subscribers-clang
Author: Iris Shi (el-ev)
<details>
<summary>Changes</summary>
Closes #<!-- -->130217.
https://github.com/riscv/riscv-isa-manual/blob/main/src/q-st-ext.adoc
---
Patch is 62.40 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/139369.diff
35 Files Affected:
- (modified) clang/test/Driver/print-supported-extensions-riscv.c (+1)
- (modified) clang/test/Driver/riscv-arch.c (+16-10)
- (modified) clang/test/Preprocessor/riscv-target-features.c (+12)
- (modified) llvm/docs/RISCVUsage.rst (+1)
- (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+9)
- (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+11)
- (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+7)
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.td (+1)
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoD.td (+4-4)
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoF.td (+5-3)
- (added) llvm/lib/Target/RISCV/RISCVInstrInfoQ.td (+168)
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td (+29-27)
- (modified) llvm/lib/Target/RISCV/RISCVRegisterInfo.td (+18)
- (modified) llvm/lib/Target/RISCV/RISCVSchedGenericOOO.td (+1)
- (modified) llvm/lib/Target/RISCV/RISCVSchedMIPSP8700.td (+1)
- (modified) llvm/lib/Target/RISCV/RISCVSchedRocket.td (+1)
- (modified) llvm/lib/Target/RISCV/RISCVSchedSiFive7.td (+1)
- (modified) llvm/lib/Target/RISCV/RISCVSchedSiFiveP400.td (+1)
- (modified) llvm/lib/Target/RISCV/RISCVSchedSiFiveP500.td (+1)
- (modified) llvm/lib/Target/RISCV/RISCVSchedSiFiveP600.td (+1)
- (modified) llvm/lib/Target/RISCV/RISCVSchedSpacemitX60.td (+1)
- (modified) llvm/lib/Target/RISCV/RISCVSchedSyntacoreSCR345.td (+3-3)
- (modified) llvm/lib/Target/RISCV/RISCVSchedSyntacoreSCR7.td (+1)
- (modified) llvm/lib/Target/RISCV/RISCVSchedTTAscalonD8.td (+1)
- (modified) llvm/lib/Target/RISCV/RISCVSchedXiangShanNanHu.td (+1)
- (modified) llvm/lib/Target/RISCV/RISCVSchedule.td (+126-43)
- (modified) llvm/lib/Target/RISCV/RISCVSubtarget.h (+3)
- (modified) llvm/lib/TargetParser/RISCVISAInfo.cpp (+3-2)
- (modified) llvm/test/CodeGen/RISCV/attributes.ll (+4)
- (modified) llvm/test/CodeGen/RISCV/features-info.ll (+1)
- (added) llvm/test/MC/RISCV/rv32q-invalid.s (+21)
- (added) llvm/test/MC/RISCV/rv64q-invalid.s (+9)
- (added) llvm/test/MC/RISCV/rv64q-valid.s (+43)
- (added) llvm/test/MC/RISCV/rvq-valid.s (+184)
- (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+1)
``````````diff
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index b10850aadddc3..cbadb86f006f4 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -10,6 +10,7 @@
// CHECK-NEXT: a 2.1 'A' (Atomic Instructions)
// CHECK-NEXT: f 2.2 'F' (Single-Precision Floating-Point)
// CHECK-NEXT: d 2.2 'D' (Double-Precision Floating-Point)
+// CHECK-NEXT: q 2.2 'Q' (Quad-Precision Floating-Point)
// CHECK-NEXT: c 2.0 'C' (Compressed Instructions)
// CHECK-NEXT: b 1.0 'B' (the collection of the Zba, Zbb, Zbs extensions)
// CHECK-NEXT: v 1.0 'V' (Vector Extension for Application Processors)
diff --git a/clang/test/Driver/riscv-arch.c b/clang/test/Driver/riscv-arch.c
index 018fa25218ea6..32e7c0d44b243 100644
--- a/clang/test/Driver/riscv-arch.c
+++ b/clang/test/Driver/riscv-arch.c
@@ -10,6 +10,8 @@
// RUN: -fsyntax-only 2>&1 | FileCheck %s
// RUN: %clang --target=riscv32-unknown-elf -march=rv32imafd -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang --target=riscv32-unknown-elf -march=rv32imafdq -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s
// RUN: %clang --target=riscv32-unknown-elf -march=rv32ic -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck %s
@@ -21,6 +23,8 @@
// RUN: -fsyntax-only 2>&1 | FileCheck %s
// RUN: %clang --target=riscv32-unknown-elf -march=rv32imafdc -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang --target=riscv32-unknown-elf -march=rv32imafdqc -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s
// RUN: %clang --target=riscv32-unknown-elf -march=rv32ia -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck %s
@@ -28,6 +32,8 @@
// RUN: -fsyntax-only 2>&1 | FileCheck %s
// RUN: %clang --target=riscv32-unknown-elf -march=rv32iafd -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang --target=riscv32-unknown-elf -march=rv32iafdq -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s
// RUN: %clang --target=riscv32-unknown-elf -march=rv32iac -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck %s
@@ -35,6 +41,8 @@
// RUN: -fsyntax-only 2>&1 | FileCheck %s
// RUN: %clang --target=riscv32-unknown-elf -march=rv32iafdc -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang --target=riscv32-unknown-elf -march=rv32iafdqc -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s
// RUN: %clang --target=riscv32-unknown-elf -march=rv32g -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck %s
@@ -80,6 +88,8 @@
// RUN: -fsyntax-only 2>&1 | FileCheck %s
// RUN: %clang --target=riscv64-unknown-elf -march=rv64imafd -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang --target=riscv32-unknown-elf -march=rv64imafdq -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s
// RUN: %clang --target=riscv64-unknown-elf -march=rv64ic -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck %s
@@ -91,6 +101,8 @@
// RUN: -fsyntax-only 2>&1 | FileCheck %s
// RUN: %clang --target=riscv64-unknown-elf -march=rv64imafdc -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang --target=riscv32-unknown-elf -march=rv64imafdqc -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s
// RUN: %clang --target=riscv64-unknown-elf -march=rv64ia -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck %s
@@ -98,6 +110,8 @@
// RUN: -fsyntax-only 2>&1 | FileCheck %s
// RUN: %clang --target=riscv64-unknown-elf -march=rv64iafd -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang --target=riscv64-unknown-elf -march=rv64iafdq -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s
// RUN: %clang --target=riscv64-unknown-elf -march=rv64iac -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck %s
@@ -105,6 +119,8 @@
// RUN: -fsyntax-only 2>&1 | FileCheck %s
// RUN: %clang --target=riscv64-unknown-elf -march=rv64iafdc -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang --target=riscv64-unknown-elf -march=rv64iafdqc -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s
// RUN: %clang --target=riscv64-unknown-elf -march=rv64g -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck %s
@@ -211,11 +227,6 @@
// RV32-LETTER: error: invalid arch name 'rv32q',
// RV32-LETTER: first letter after 'rv32' should be 'e', 'i' or 'g'
-// RUN: not %clang --target=riscv32-unknown-elf -march=rv32imcq -### %s \
-// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-ORDER %s
-// RV32-ORDER: error: invalid arch name 'rv32imcq',
-// RV32-ORDER: unsupported standard user-level extension 'q'
-
// RUN: not %clang --target=riscv32-unknown-elf -march=rv32izvl64b -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-ZVL64B-ER %s
// RV32-ZVL64B-ER: error: invalid arch name 'rv32izvl64b',
@@ -226,11 +237,6 @@
// RV32-STD-INVAL: error: invalid arch name 'rv32imw',
// RV32-STD-INVAL: invalid standard user-level extension 'w'
-// RUN: not %clang --target=riscv32-unknown-elf -march=rv32imqc -### %s \
-// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-STD %s
-// RV32-STD: error: invalid arch name 'rv32imqc',
-// RV32-STD: unsupported standard user-level extension 'q'
-
// RUN: not %clang --target=riscv32-unknown-elf -march=rv32xabc -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32X %s
// RV32X: error: invalid arch name 'rv32xabc',
diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c
index 25f15cc5283f9..e3b456e0245f7 100644
--- a/clang/test/Preprocessor/riscv-target-features.c
+++ b/clang/test/Preprocessor/riscv-target-features.c
@@ -20,6 +20,7 @@
// CHECK-NOT: __riscv_m {{.*$}}
// CHECK-NOT: __riscv_mul {{.*$}}
// CHECK-NOT: __riscv_muldiv {{.*$}}
+// CHECK-NOT: __riscv_q {{.*$}}
// CHECK-NOT: __riscv_sha {{.*$}}
// CHECK-NOT: __riscv_shcounterenw {{.*$}}
// CHECK-NOT: __riscv_shgatpa {{.*$}}
@@ -334,6 +335,17 @@
// CHECK-M-EXT: __riscv_mul 1
// CHECK-M-EXT: __riscv_muldiv 1
+// RUN: %clang --target=riscv32-unknown-linux-gnu \
+// RUN: -march=rv32ifdq -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-Q-EXT %s
+// RUN: %clang --target=riscv64-unknown-linux-gnu \
+// RUN: -march=rv64ifdq -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-Q-EXT %s
+// CHECK-Q-EXT: __riscv_fdiv 1
+// CHECK-Q-EXT: __riscv_flen 128
+// CHECK-Q-EXT: __riscv_fsqrt 1
+// CHECK-Q-EXT: __riscv_q 2002000{{$}}
+
// RUN: %clang --target=riscv32-unknown-linux-gnu \
// RUN: -march=rv32isha -E -dM %s \
// RUN: -o - | FileCheck --check-prefix=CHECK-SHCOUNTERENW-EXT %s
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 4b98f58304f13..8aec0f80cf0ed 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -119,6 +119,7 @@ on support follow.
``E`` Supported (`See note <#riscv-rve-note>`__)
``H`` Assembly Support
``M`` Supported
+ ``Q`` Assembly Support
``Sha`` Supported
``Shcounterenw`` Assembly Support (`See note <#riscv-profiles-extensions-note>`__)
``Shgatpa`` Assembly Support (`See note <#riscv-profiles-extensions-note>`__)
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 9bc4734815364..442b3c32c779d 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -1272,6 +1272,11 @@ static MCRegister convertFPR64ToFPR32(MCRegister Reg) {
return Reg - RISCV::F0_D + RISCV::F0_F;
}
+static MCRegister convertFPR64ToFPR128(MCRegister Reg) {
+ assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register");
+ return Reg - RISCV::F0_D + RISCV::F0_Q;
+}
+
static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg,
unsigned Kind) {
unsigned RegClassID;
@@ -1300,6 +1305,10 @@ unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(Reg);
bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(Reg);
+ if (IsRegFPR64 && Kind == MCK_FPR128) {
+ Op.Reg.RegNum = convertFPR64ToFPR128(Reg);
+ return Match_Success;
+ }
// As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
// register from FPR64 to FPR32 or FPR64C to FPR32C if necessary.
if ((IsRegFPR64 && Kind == MCK_FPR32) ||
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 8f1b790826b24..5eb60070f391f 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -177,6 +177,17 @@ static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint32_t RegNo,
return MCDisassembler::Success;
}
+static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, uint32_t RegNo,
+ uint64_t Address,
+ const MCDisassembler *Decoder) {
+ if (RegNo >= 32)
+ return MCDisassembler::Fail;
+
+ MCRegister Reg = RISCV::F0_Q + RegNo;
+ Inst.addOperand(MCOperand::createReg(Reg));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
const MCDisassembler *Decoder) {
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 18d341aa5b5ca..c26f5aae7ab26 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -291,6 +291,13 @@ def HasStdExtD : Predicate<"Subtarget->hasStdExtD()">,
AssemblerPredicate<(all_of FeatureStdExtD),
"'D' (Double-Precision Floating-Point)">;
+def FeatureStdExtQ
+ : RISCVExtension<2, 2, "Quad-Precision Floating-Point", [FeatureStdExtD]>,
+ RISCVExtensionBitmask<0, 16>;
+def HasStdExtQ : Predicate<"Subtarget->hasStdExtQ()">,
+ AssemblerPredicate<(all_of FeatureStdExtQ),
+ "'Q' (Quad-Precision Floating-Point)">;
+
def FeatureStdExtZfhmin
: RISCVExtension<1, 0, "Half-Precision Floating-Point Minimal",
[FeatureStdExtF]>,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index e9bdeb88e4ca8..3f6931b584c16 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2213,6 +2213,7 @@ include "RISCVInstrInfoZalasr.td"
// Scalar FP
include "RISCVInstrInfoF.td"
include "RISCVInstrInfoD.td"
+include "RISCVInstrInfoQ.td"
include "RISCVInstrInfoZfh.td"
include "RISCVInstrInfoZfbfmin.td"
include "RISCVInstrInfoZfa.td"
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
index 0c584daf45b14..efe73b87c7ed9 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
@@ -58,12 +58,12 @@ def FPR64IN32X : RegisterOperand<GPRPair> {
let ParserMatchClass = GPRPairAsFPR;
}
-def DExt : ExtInfo<"", "", [HasStdExtD], f64, FPR64, FPR32, FPR64, ?>;
+def DExt : ExtInfo<"", "", [HasStdExtD], f64, FPR64, FPR32, FPR64, ?, ?>;
-def ZdinxExt : ExtInfo<"_INX", "Zfinx", [HasStdExtZdinx, IsRV64],
- f64, FPR64INX, FPR32INX, FPR64INX, ?>;
+def ZdinxExt : ExtInfo<"_INX", "Zfinx", [HasStdExtZdinx, IsRV64], f64, FPR64INX,
+ FPR32INX, FPR64INX, ?, ?>;
def Zdinx32Ext : ExtInfo<"_IN32X", "ZdinxRV32Only", [HasStdExtZdinx, IsRV32],
- f64, FPR64IN32X, FPR32INX, FPR64IN32X, ?>;
+ f64, FPR64IN32X, FPR32INX, FPR64IN32X, ?, ?>;
defvar DExts = [DExt, ZdinxExt, Zdinx32Ext];
defvar DExtsRV64 = [DExt, ZdinxExt];
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
index 360191f03ddf7..6f672a93f5b7c 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
@@ -131,7 +131,7 @@ def FPR32INX : RegisterOperand<GPRF32> {
// The DAGOperand can be unset if the predicates are not enough to define it.
class ExtInfo<string suffix, string space, list<Predicate> predicates,
ValueType primaryvt, DAGOperand primaryty, DAGOperand f32ty,
- DAGOperand f64ty, DAGOperand f16ty> {
+ DAGOperand f64ty, DAGOperand f16ty, DAGOperand f128ty> {
list<Predicate> Predicates = predicates;
string Suffix = suffix;
string Space = space;
@@ -139,12 +139,14 @@ class ExtInfo<string suffix, string space, list<Predicate> predicates,
DAGOperand F16Ty = f16ty;
DAGOperand F32Ty = f32ty;
DAGOperand F64Ty = f64ty;
+ DAGOperand F128Ty = f128ty;
ValueType PrimaryVT = primaryvt;
}
-def FExt : ExtInfo<"", "", [HasStdExtF], f32, FPR32, FPR32, ?, ?>;
+def FExt : ExtInfo<"", "", [HasStdExtF], f32, FPR32, FPR32, ?, ?, ?>;
-def ZfinxExt : ExtInfo<"_INX", "Zfinx", [HasStdExtZfinx], f32, FPR32INX, FPR32INX, ?, ?>;
+def ZfinxExt : ExtInfo<"_INX", "Zfinx", [HasStdExtZfinx], f32, FPR32INX,
+ FPR32INX, ?, ?, ?>;
defvar FExts = [FExt, ZfinxExt];
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoQ.td b/llvm/lib/Target/RISCV/RISCVInstrInfoQ.td
new file mode 100644
index 0000000000000..40f1e473d3b2a
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoQ.td
@@ -0,0 +1,168 @@
+//===-- RISCVInstrInfoF.td - RISC-V 'Q' instructions -------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the RISC-V instructions from the standard 'Q',
+// Quad-Precision Floating-Point instruction set extension.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Operand and SDNode transformation definitions.
+//===----------------------------------------------------------------------===//
+
+def QExt : ExtInfo<"", "", [HasStdExtQ], f128, FPR128, FPR32, FPR64, ?, FPR128>;
+
+defvar QExts = [QExt];
+defvar QExtsRV64 = [QExt];
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasStdExtQ] in {
+ def FLQ : FPLoad_r<0b100, "flq", FPR128, WriteFLD128>;
+
+ // Operands for stores are in the order srcreg, base, offset rather than
+ // reflecting the order these fields are specified in the instruction
+ // encoding.
+ def FSQ : FPStore_r<0b100, "fsq", FPR128, WriteFST128>;
+}
+
+foreach Ext = QExts in {
+ let SchedRW = [WriteFMA128, ReadFMA128, ReadFMA128, ReadFMA128Addend] in {
+ defm FMADD_Q : FPFMA_rrr_frm_m<OPC_MADD, 0b11, "fmadd.q", Ext>;
+ defm FMSUB_Q : FPFMA_rrr_frm_m<OPC_MSUB, 0b11, "fmsub.q", Ext>;
+ defm FNMSUB_Q : FPFMA_rrr_frm_m<OPC_NMSUB, 0b11, "fnmsub.q", Ext>;
+ defm FNMADD_Q : FPFMA_rrr_frm_m<OPC_NMADD, 0b11, "fnmadd.q", Ext>;
+ }
+
+ let SchedRW = [WriteFAdd128, ReadFAdd128, ReadFAdd128] in {
+ defm FADD_Q : FPALU_rr_frm_m<0b0000011, "fadd.q", Ext>;
+ defm FSUB_Q : FPALU_rr_frm_m<0b0000111, "fsub.q", Ext>;
+ }
+
+ let SchedRW = [WriteFMul128, ReadFMul128, ReadFMul128] in defm FMUL_Q
+ : FPALU_rr_frm_m<0b0001011, "fmul.q", Ext>;
+
+ let SchedRW = [WriteFDiv128, ReadFDiv128, ReadFDiv128] in defm FDIV_Q
+ : FPALU_rr_frm_m<0b0001111, "fdiv.q", Ext>;
+
+ defm FSQRT_Q : FPUnaryOp_r_frm_m<0b0101111, 0b00000, Ext, Ext.PrimaryTy,
+ Ext.PrimaryTy, "fsqrt.q">,
+ Sched<[WriteFSqrt128, ReadFSqrt128]>;
+
+ let SchedRW = [WriteFSGNJ128, ReadFSGNJ128, ReadFSGNJ128],
+ mayRaiseFPException = 0 in {
+ defm FSGNJ_Q : FPALU_rr_m<0b0010011, 0b000, "fsgnj.q", Ext>;
+ defm FSGNJN_Q : FPALU_rr_m<0b0010011, 0b001, "fsgnjn.q", Ext>;
+ defm FSGNJX_Q : FPALU_rr_m<0b0010011, 0b010, "fsgnjx.q", Ext>;
+ }
+
+ let SchedRW = [WriteFMinMax128, ReadFMinMax128, ReadFMinMax128] in {
+ defm FMIN_Q : FPALU_rr_m<0b0010111, 0b000, "fmin.q", Ext, Commutable = 1>;
+ defm FMAX_Q : FPALU_rr_m<0b0010111, 0b001, "fmax.q", Ext, Commutable = 1>;
+ }
+
+ defm FCVT_S_Q : FPUnaryOp_r_frm_m<0b0100000, 0b00011, Ext, Ext.F32Ty,
+ Ext.PrimaryTy, "fcvt.s.q">,
+ Sched<[WriteFCvtF128ToF32, ReadFCvtF128ToF32]>;
+
+ defm FCVT_Q_S : FPUnaryOp_r_frmlegacy_m<0b0100011, 0b00000, Ext,
+ Ext.PrimaryTy, Ext.F32Ty, "fcvt.q.s">,
+ Sched<[WriteFCvtF32ToF128, ReadFCvtF32ToF128]>;
+
+ defm FCVT_D_Q : FPUnaryOp_r_frm_m<0b0100001, 0b00011, Ext, Ext.F64Ty,
+ Ext.PrimaryTy, "fcvt.d.q">,
+ Sched<[WriteFCvtF128ToF64, ReadFCvtF128ToF64]>;
+
+ defm FCVT_Q_D : FPUnaryOp_r_frmlegacy_m<0b0100011, 0b00001, Ext,
+ Ext.PrimaryTy, Ext.F64Ty, "fcvt.q.d">,
+ Sched<[WriteFCvtF64ToF128, ReadFCvtF64ToF128]>;
+
+ let SchedRW = [WriteFCmp128, ReadFCmp128, ReadFCmp128] in {
+ defm FEQ_Q : FPCmp_rr_m<0b1010011, 0b010, "feq.q", Ext, Commutable = 1>;
+ defm FLT_Q : FPCmp_rr_m<0b1010011, 0b001, "flt.q", Ext>;
+ defm FLE_Q : FPCmp_rr_m<0b1010011, 0b000, "fle.q", Ext>;
+ }
+
+ let mayRaiseFPException =
+ 0 in defm FCLASS_Q : FPUnaryOp_r_m<0b1110011, 0b00000, 0b001, Ext, GPR,
+ Ext.PrimaryTy, "fclass.q">,
+ Sched<[WriteFClass128, ReadFClass128]>;
+
+ let IsSignExtendingOpW =
+ 1 in defm FCVT_W_Q : FPUnaryOp_r_frm_m<0b1100011, 0b00000, Ext, GPR,
+ Ext.PrimaryTy, "fcvt.w.q">,
+ Sched<[WriteFCvtF128ToI32, ReadFCvtF128ToI32]>;
+
+ let IsSignExtendingOpW =
+ 1 in defm FCVT_WU_Q : FPUnaryOp_r_frm_m<0b1100011, 0b00001, Ext, GPR,
+ Ext.PrimaryTy, "fcvt.wu.q">,
+ Sched<[WriteFCvtF128ToI32, ReadFCvtF128ToI32]>;
+
+ let mayRaiseFPException =
+ 0 in defm FCVT_Q_W : FPUnaryOp_r_frm_m<0b1101011, 0b00000, Ext,
+ Ext.PrimaryTy, GPR, "fcvt.q.w">,
+ Sched<[WriteFCvtI32ToF128, ReadFCvtI32ToF128]>;
+
+ let mayRaiseFPException =
+ 0 in defm FCVT_Q_WU : FPUnaryOp_r_frm_m<0b1101011, 0b00001, Ext,
+ Ext.PrimaryTy, GPR, "fcvt.q.wu">,
+ Sched<[WriteFCvtI32ToF128, ReadFCvtI32ToF128]>;
+
+} // foreach Ext = QExts
+
+foreach Ext = QExtsRV64 in {
+ defm FCVT_L_Q : FPUnaryOp_r_frm_m<0b1100011, 0b00010, Ext, GPR, Ext.PrimaryTy,
+ "fcvt.l.q", [IsRV64]>,
+ Sched<[WriteFCvtF128ToI64, ReadFCvtF128ToI64]>;
+
+ defm FCVT_LU_Q : FPUnaryOp_r_frm_m<0b1100011, 0b00011, Ext, GPR,
+ Ext.PrimaryTy, "fcvt.lu.q", [IsRV64]>,
+ Sched<[WriteFCvtF128ToI64, ReadFCvtF128ToI64]>;
+
+ let mayRaiseFPException = 0 in defm FCVT_Q_L
+ : FPUnaryOp_r_frm_m<0b1101011, 0b00010, Ext, Ext.PrimaryTy, GPR,
+ "fcvt.q.l", [IsRV64]>,
+ Sched<[WriteFCvtI64ToF128, ReadFCvtI64ToF128]>;
+
+ let mayRaiseFPException = 0 in defm FCVT_Q_LU
+ : FPUnaryOp_r_frm_m<0b1101011, 0b00011, Ext, Ext.PrimaryTy, GPR,
+ "fcvt.q.lu", [IsRV64]>,
+ Sched<[WriteFCvtI64ToF128, ReadFCvtI64ToF128]>;
+} // foreach Ext = QExtsRV64
+
+//===----------------------------------------------------------------------===//
+// Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasStdExtQ] in {
+ def : InstAlias<"flq $rd,...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/139369
More information about the llvm-commits
mailing list