Skip to content

Commit fb1cd01

Browse files
committed
[RISCV][MC] Add support for Q extension
1 parent 4c9ffb7 commit fb1cd01

26 files changed

+611
-30
lines changed

clang/test/Driver/print-supported-extensions-riscv.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
// CHECK-NEXT: a 2.1 'A' (Atomic Instructions)
1111
// CHECK-NEXT: f 2.2 'F' (Single-Precision Floating-Point)
1212
// CHECK-NEXT: d 2.2 'D' (Double-Precision Floating-Point)
13+
// CHECK-NEXT: q 2.2 'Q' (Quad-Precision Floating-Point)
1314
// CHECK-NEXT: c 2.0 'C' (Compressed Instructions)
1415
// CHECK-NEXT: b 1.0 'B' (the collection of the Zba, Zbb, Zbs extensions)
1516
// CHECK-NEXT: v 1.0 'V' (Vector Extension for Application Processors)

clang/test/Driver/riscv-arch.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
// RUN: -fsyntax-only 2>&1 | FileCheck %s
1111
// RUN: %clang --target=riscv32-unknown-elf -march=rv32imafd -### %s \
1212
// RUN: -fsyntax-only 2>&1 | FileCheck %s
13+
// RUN: %clang --target=riscv32-unknown-elf -march=rv32imafdq -### %s \
14+
// RUN: -fsyntax-only 2>&1 | FileCheck %s
1315

1416
// RUN: %clang --target=riscv32-unknown-elf -march=rv32ic -### %s \
1517
// RUN: -fsyntax-only 2>&1 | FileCheck %s
@@ -21,20 +23,26 @@
2123
// RUN: -fsyntax-only 2>&1 | FileCheck %s
2224
// RUN: %clang --target=riscv32-unknown-elf -march=rv32imafdc -### %s \
2325
// RUN: -fsyntax-only 2>&1 | FileCheck %s
26+
// RUN: %clang --target=riscv32-unknown-elf -march=rv32imafdqc -### %s \
27+
// RUN: -fsyntax-only 2>&1 | FileCheck %s
2428

2529
// RUN: %clang --target=riscv32-unknown-elf -march=rv32ia -### %s \
2630
// RUN: -fsyntax-only 2>&1 | FileCheck %s
2731
// RUN: %clang --target=riscv32-unknown-elf -march=rv32iaf -### %s \
2832
// RUN: -fsyntax-only 2>&1 | FileCheck %s
2933
// RUN: %clang --target=riscv32-unknown-elf -march=rv32iafd -### %s \
3034
// RUN: -fsyntax-only 2>&1 | FileCheck %s
35+
// RUN: %clang --target=riscv32-unknown-elf -march=rv32iafdq -### %s \
36+
// RUN: -fsyntax-only 2>&1 | FileCheck %s
3137

3238
// RUN: %clang --target=riscv32-unknown-elf -march=rv32iac -### %s \
3339
// RUN: -fsyntax-only 2>&1 | FileCheck %s
3440
// RUN: %clang --target=riscv32-unknown-elf -march=rv32iafc -### %s \
3541
// RUN: -fsyntax-only 2>&1 | FileCheck %s
3642
// RUN: %clang --target=riscv32-unknown-elf -march=rv32iafdc -### %s \
3743
// RUN: -fsyntax-only 2>&1 | FileCheck %s
44+
// RUN: %clang --target=riscv32-unknown-elf -march=rv32iafdqc -### %s \
45+
// RUN: -fsyntax-only 2>&1 | FileCheck %s
3846

3947
// RUN: %clang --target=riscv32-unknown-elf -march=rv32g -### %s \
4048
// RUN: -fsyntax-only 2>&1 | FileCheck %s
@@ -80,6 +88,8 @@
8088
// RUN: -fsyntax-only 2>&1 | FileCheck %s
8189
// RUN: %clang --target=riscv64-unknown-elf -march=rv64imafd -### %s \
8290
// RUN: -fsyntax-only 2>&1 | FileCheck %s
91+
// RUN: %clang --target=riscv64-unknown-elf -march=rv64imafdq -### %s \
92+
// RUN: -fsyntax-only 2>&1 | FileCheck %s
8393

8494
// RUN: %clang --target=riscv64-unknown-elf -march=rv64ic -### %s \
8595
// RUN: -fsyntax-only 2>&1 | FileCheck %s
@@ -91,20 +101,26 @@
91101
// RUN: -fsyntax-only 2>&1 | FileCheck %s
92102
// RUN: %clang --target=riscv64-unknown-elf -march=rv64imafdc -### %s \
93103
// RUN: -fsyntax-only 2>&1 | FileCheck %s
104+
// RUN: %clang --target=riscv64-unknown-elf -march=rv64imafdqc -### %s \
105+
// RUN: -fsyntax-only 2>&1 | FileCheck %s
94106

95107
// RUN: %clang --target=riscv64-unknown-elf -march=rv64ia -### %s \
96108
// RUN: -fsyntax-only 2>&1 | FileCheck %s
97109
// RUN: %clang --target=riscv64-unknown-elf -march=rv64iaf -### %s \
98110
// RUN: -fsyntax-only 2>&1 | FileCheck %s
99111
// RUN: %clang --target=riscv64-unknown-elf -march=rv64iafd -### %s \
100112
// RUN: -fsyntax-only 2>&1 | FileCheck %s
113+
// RUN: %clang --target=riscv64-unknown-elf -march=rv64iafdq -### %s \
114+
// RUN: -fsyntax-only 2>&1 | FileCheck %s
101115

102116
// RUN: %clang --target=riscv64-unknown-elf -march=rv64iac -### %s \
103117
// RUN: -fsyntax-only 2>&1 | FileCheck %s
104118
// RUN: %clang --target=riscv64-unknown-elf -march=rv64iafc -### %s \
105119
// RUN: -fsyntax-only 2>&1 | FileCheck %s
106120
// RUN: %clang --target=riscv64-unknown-elf -march=rv64iafdc -### %s \
107121
// RUN: -fsyntax-only 2>&1 | FileCheck %s
122+
// RUN: %clang --target=riscv64-unknown-elf -march=rv64iafdqc -### %s \
123+
// RUN: -fsyntax-only 2>&1 | FileCheck %s
108124

109125
// RUN: %clang --target=riscv64-unknown-elf -march=rv64g -### %s \
110126
// RUN: -fsyntax-only 2>&1 | FileCheck %s
@@ -211,11 +227,6 @@
211227
// RV32-LETTER: error: invalid arch name 'rv32q',
212228
// RV32-LETTER: first letter after 'rv32' should be 'e', 'i' or 'g'
213229

214-
// RUN: not %clang --target=riscv32-unknown-elf -march=rv32imcq -### %s \
215-
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-ORDER %s
216-
// RV32-ORDER: error: invalid arch name 'rv32imcq',
217-
// RV32-ORDER: unsupported standard user-level extension 'q'
218-
219230
// RUN: not %clang --target=riscv32-unknown-elf -march=rv32izvl64b -### %s \
220231
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-ZVL64B-ER %s
221232
// RV32-ZVL64B-ER: error: invalid arch name 'rv32izvl64b',
@@ -226,11 +237,6 @@
226237
// RV32-STD-INVAL: error: invalid arch name 'rv32imw',
227238
// RV32-STD-INVAL: invalid standard user-level extension 'w'
228239

229-
// RUN: not %clang --target=riscv32-unknown-elf -march=rv32imqc -### %s \
230-
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-STD %s
231-
// RV32-STD: error: invalid arch name 'rv32imqc',
232-
// RV32-STD: unsupported standard user-level extension 'q'
233-
234240
// RUN: not %clang --target=riscv32-unknown-elf -march=rv32xabc -### %s \
235241
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32X %s
236242
// RV32X: error: invalid arch name 'rv32xabc',

clang/test/Preprocessor/riscv-target-features.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
// CHECK-NOT: __riscv_m {{.*$}}
2121
// CHECK-NOT: __riscv_mul {{.*$}}
2222
// CHECK-NOT: __riscv_muldiv {{.*$}}
23+
// CHECK-NOT: __riscv_q {{.*$}}
2324
// CHECK-NOT: __riscv_sha {{.*$}}
2425
// CHECK-NOT: __riscv_shcounterenw {{.*$}}
2526
// CHECK-NOT: __riscv_shgatpa {{.*$}}
@@ -334,6 +335,17 @@
334335
// CHECK-M-EXT: __riscv_mul 1
335336
// CHECK-M-EXT: __riscv_muldiv 1
336337

338+
// RUN: %clang --target=riscv32-unknown-linux-gnu \
339+
// RUN: -march=rv32ifdq -E -dM %s \
340+
// RUN: -o - | FileCheck --check-prefix=CHECK-Q-EXT %s
341+
// RUN: %clang --target=riscv64-unknown-linux-gnu \
342+
// RUN: -march=rv64ifdq -E -dM %s \
343+
// RUN: -o - | FileCheck --check-prefix=CHECK-Q-EXT %s
344+
// CHECK-Q-EXT: __riscv_fdiv 1
345+
// CHECK-Q-EXT: __riscv_flen 128
346+
// CHECK-Q-EXT: __riscv_fsqrt 1
347+
// CHECK-Q-EXT: __riscv_q 2002000{{$}}
348+
337349
// RUN: %clang --target=riscv32-unknown-linux-gnu \
338350
// RUN: -march=rv32isha -E -dM %s \
339351
// RUN: -o - | FileCheck --check-prefix=CHECK-SHCOUNTERENW-EXT %s

llvm/docs/RISCVUsage.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ on support follow.
119119
``E`` Supported (`See note <#riscv-rve-note>`__)
120120
``H`` Assembly Support
121121
``M`` Supported
122+
``Q`` Assembly Support
122123
``Sha`` Supported
123124
``Shcounterenw`` Assembly Support (`See note <#riscv-profiles-extensions-note>`__)
124125
``Shgatpa`` Assembly Support (`See note <#riscv-profiles-extensions-note>`__)

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,11 @@ static MCRegister convertFPR64ToFPR32(MCRegister Reg) {
12721272
return Reg - RISCV::F0_D + RISCV::F0_F;
12731273
}
12741274

1275+
static MCRegister convertFPR64ToFPR128(MCRegister Reg) {
1276+
assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register");
1277+
return Reg - RISCV::F0_D + RISCV::F0_Q;
1278+
}
1279+
12751280
static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg,
12761281
unsigned Kind) {
12771282
unsigned RegClassID;
@@ -1300,6 +1305,10 @@ unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
13001305
RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(Reg);
13011306
bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(Reg);
13021307

1308+
if (IsRegFPR64 && Kind == MCK_FPR128) {
1309+
Op.Reg.RegNum = convertFPR64ToFPR128(Reg);
1310+
return Match_Success;
1311+
}
13031312
// As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
13041313
// register from FPR64 to FPR32 or FPR64C to FPR32C if necessary.
13051314
if ((IsRegFPR64 && Kind == MCK_FPR32) ||
@@ -1663,13 +1672,16 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
16631672
// rejected.
16641673
MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name) const {
16651674
MCRegister Reg = MatchRegisterName(Name);
1666-
// The 16-/32- and 64-bit FPRs have the same asm name. Check that the initial
1667-
// match always matches the 64-bit variant, and not the 16/32-bit one.
1675+
// The 16-/32-/128- and 64-bit FPRs have the same asm name. Check
1676+
// that the initial match always matches the 64-bit variant, and
1677+
// not the 16/32/128-bit one.
16681678
assert(!(Reg >= RISCV::F0_H && Reg <= RISCV::F31_H));
16691679
assert(!(Reg >= RISCV::F0_F && Reg <= RISCV::F31_F));
1680+
assert(!(Reg >= RISCV::F0_Q && Reg <= RISCV::F31_Q));
16701681
// The default FPR register class is based on the tablegen enum ordering.
16711682
static_assert(RISCV::F0_D < RISCV::F0_H, "FPR matching must be updated");
16721683
static_assert(RISCV::F0_D < RISCV::F0_F, "FPR matching must be updated");
1684+
static_assert(RISCV::F0_D < RISCV::F0_Q, "FPR matching must be updated");
16731685
if (!Reg)
16741686
Reg = MatchRegisterAltName(Name);
16751687
if (isRVE() && Reg >= RISCV::X16 && Reg <= RISCV::X31)
@@ -3848,6 +3860,9 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
38483860
case RISCV::PseudoFLD:
38493861
emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true);
38503862
return false;
3863+
case RISCV::PseudoFLQ:
3864+
emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out, /*HasTmpReg=*/true);
3865+
return false;
38513866
case RISCV::PseudoSB:
38523867
case RISCV::PseudoQC_E_SB:
38533868
emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true);
@@ -3875,6 +3890,9 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
38753890
case RISCV::PseudoFSD:
38763891
emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true);
38773892
return false;
3893+
case RISCV::PseudoFSQ:
3894+
emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out, /*HasTmpReg=*/true);
3895+
return false;
38783896
case RISCV::PseudoAddTPRel:
38793897
if (checkPseudoAddTPRel(Inst, Operands))
38803898
return true;

llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,17 @@ static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint32_t RegNo,
177177
return MCDisassembler::Success;
178178
}
179179

180+
static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, uint32_t RegNo,
181+
uint64_t Address,
182+
const MCDisassembler *Decoder) {
183+
if (RegNo >= 32)
184+
return MCDisassembler::Fail;
185+
186+
MCRegister Reg = RISCV::F0_Q + RegNo;
187+
Inst.addOperand(MCOperand::createReg(Reg));
188+
return MCDisassembler::Success;
189+
}
190+
180191
static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint32_t RegNo,
181192
uint64_t Address,
182193
const MCDisassembler *Decoder) {

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,13 @@ def HasStdExtD : Predicate<"Subtarget->hasStdExtD()">,
291291
AssemblerPredicate<(all_of FeatureStdExtD),
292292
"'D' (Double-Precision Floating-Point)">;
293293

294+
def FeatureStdExtQ
295+
: RISCVExtension<2, 2, "Quad-Precision Floating-Point", [FeatureStdExtD]>,
296+
RISCVExtensionBitmask<0, 16>;
297+
def HasStdExtQ : Predicate<"Subtarget->hasStdExtQ()">,
298+
AssemblerPredicate<(all_of FeatureStdExtQ),
299+
"'Q' (Quad-Precision Floating-Point)">;
300+
294301
def FeatureStdExtZfhmin
295302
: RISCVExtension<1, 0, "Half-Precision Floating-Point Minimal",
296303
[FeatureStdExtF]>,

llvm/lib/Target/RISCV/RISCVInstrInfo.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,13 @@ void RISCVInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
599599
return;
600600
}
601601

602+
if (RISCV::FPR128RegClass.contains(DstReg, SrcReg)) {
603+
BuildMI(MBB, MBBI, DL, get(RISCV::FSGNJ_Q), DstReg)
604+
.addReg(SrcReg, getKillRegState(KillSrc))
605+
.addReg(SrcReg, getKillRegState(KillSrc));
606+
return;
607+
}
608+
602609
if (RISCV::FPR32RegClass.contains(DstReg) &&
603610
RISCV::GPRRegClass.contains(SrcReg)) {
604611
BuildMI(MBB, MBBI, DL, get(RISCV::FMV_W_X), DstReg)
@@ -674,6 +681,9 @@ void RISCVInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
674681
} else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
675682
Opcode = RISCV::FSD;
676683
IsScalableVector = false;
684+
} else if (RISCV::FPR128RegClass.hasSubClassEq(RC)) {
685+
Opcode = RISCV::FSQ;
686+
IsScalableVector = false;
677687
} else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
678688
Opcode = RISCV::VS1R_V;
679689
} else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
@@ -766,6 +776,9 @@ void RISCVInstrInfo::loadRegFromStackSlot(
766776
} else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
767777
Opcode = RISCV::FLD;
768778
IsScalableVector = false;
779+
} else if (RISCV::FPR128RegClass.hasSubClassEq(RC)) {
780+
Opcode = RISCV::FLQ;
781+
IsScalableVector = false;
769782
} else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
770783
Opcode = RISCV::VL1RE8_V;
771784
} else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2213,6 +2213,7 @@ include "RISCVInstrInfoZalasr.td"
22132213
// Scalar FP
22142214
include "RISCVInstrInfoF.td"
22152215
include "RISCVInstrInfoD.td"
2216+
include "RISCVInstrInfoQ.td"
22162217
include "RISCVInstrInfoZfh.td"
22172218
include "RISCVInstrInfoZfbfmin.td"
22182219
include "RISCVInstrInfoZfa.td"

llvm/lib/Target/RISCV/RISCVInstrInfoD.td

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,12 @@ def FPR64IN32X : RegisterOperand<GPRPair> {
5858
let ParserMatchClass = GPRPairAsFPR;
5959
}
6060

61-
def DExt : ExtInfo<"", "", [HasStdExtD], f64, FPR64, FPR32, FPR64, ?>;
61+
def DExt : ExtInfo<"", "", [HasStdExtD], f64, FPR64, FPR32, FPR64, ?, ?>;
6262

6363
def ZdinxExt : ExtInfo<"_INX", "Zfinx", [HasStdExtZdinx, IsRV64],
64-
f64, FPR64INX, FPR32INX, FPR64INX, ?>;
64+
f64, FPR64INX, FPR32INX, FPR64INX, ?, ?>;
6565
def Zdinx32Ext : ExtInfo<"_IN32X", "ZdinxRV32Only", [HasStdExtZdinx, IsRV32],
66-
f64, FPR64IN32X, FPR32INX, FPR64IN32X, ?>;
66+
f64, FPR64IN32X, FPR32INX, FPR64IN32X, ?, ?>;
6767

6868
defvar DExts = [DExt, ZdinxExt, Zdinx32Ext];
6969
defvar DExtsRV64 = [DExt, ZdinxExt];

llvm/lib/Target/RISCV/RISCVInstrInfoF.td

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,20 +131,22 @@ def FPR32INX : RegisterOperand<GPRF32> {
131131
// The DAGOperand can be unset if the predicates are not enough to define it.
132132
class ExtInfo<string suffix, string space, list<Predicate> predicates,
133133
ValueType primaryvt, DAGOperand primaryty, DAGOperand f32ty,
134-
DAGOperand f64ty, DAGOperand f16ty> {
134+
DAGOperand f64ty, DAGOperand f16ty, DAGOperand f128ty> {
135135
list<Predicate> Predicates = predicates;
136136
string Suffix = suffix;
137137
string Space = space;
138138
DAGOperand PrimaryTy = primaryty;
139139
DAGOperand F16Ty = f16ty;
140140
DAGOperand F32Ty = f32ty;
141141
DAGOperand F64Ty = f64ty;
142+
DAGOperand F128Ty = f128ty;
142143
ValueType PrimaryVT = primaryvt;
143144
}
144145

145-
def FExt : ExtInfo<"", "", [HasStdExtF], f32, FPR32, FPR32, ?, ?>;
146+
def FExt : ExtInfo<"", "", [HasStdExtF], f32, FPR32, FPR32, ?, ?, ?>;
146147

147-
def ZfinxExt : ExtInfo<"_INX", "Zfinx", [HasStdExtZfinx], f32, FPR32INX, FPR32INX, ?, ?>;
148+
def ZfinxExt : ExtInfo<"_INX", "Zfinx", [HasStdExtZfinx], f32, FPR32INX,
149+
FPR32INX, ?, ?, ?>;
148150

149151
defvar FExts = [FExt, ZfinxExt];
150152

0 commit comments

Comments
 (0)