Skip to content

Commit 0744d49

Browse files
hchandelsvs-quic
andauthored
[RISCV] Add Qualcomm uC Xqcilb (Long Branch) extension (llvm#131996)
This extension adds two long branch instructions. The current spec can be found at: https://github.com/quic/riscv-unified-db/releases/tag/Xqci-0.7.0 This patch adds assembler only support. Co-authored-by: Sudharsan Veeravalli <[email protected]>
1 parent 460c0f5 commit 0744d49

File tree

12 files changed

+133
-8
lines changed

12 files changed

+133
-8
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@
205205
// CHECK-NEXT: xqcics 0.2 'Xqcics' (Qualcomm uC Conditional Select Extension)
206206
// CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension)
207207
// CHECK-NEXT: xqciint 0.4 'Xqciint' (Qualcomm uC Interrupts Extension)
208+
// CHECK-NEXT: xqcilb 0.2 'Xqcilb' (Qualcomm uC Long Branch Extension)
208209
// CHECK-NEXT: xqcili 0.2 'Xqcili' (Qualcomm uC Load Large Immediate Extension)
209210
// CHECK-NEXT: xqcilia 0.2 'Xqcilia' (Qualcomm uC Large Immediate Arithmetic Extension)
210211
// CHECK-NEXT: xqcilo 0.2 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)

llvm/docs/RISCVUsage.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,9 @@ The current vendor extensions supported are:
461461
``experimental-Xqciint``
462462
LLVM implements `version 0.4 of the Qualcomm uC Interrupts extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm. All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
463463

464+
``experimental-Xqcilb``
465+
LLVM implements `version 0.2 of the Qualcomm uC Long Branch extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm. All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
466+
464467
``experimental-Xqcili``
465468
LLVM implements `version 0.2 of the Qualcomm uC Load Large Immediate extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm. All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
466469

llvm/docs/ReleaseNotes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ Changes to the PowerPC Backend
114114
Changes to the RISC-V Backend
115115
-----------------------------
116116

117+
* Adds experimental assembler support for the Qualcomm uC 'Xqcilb` (Long Branch)
118+
extension.
117119
* Adds experimental assembler support for the Qualcomm uC 'Xqcili` (Load Large Immediate)
118120
extension.
119121
* Adds experimental assembler support for the Qualcomm uC 'Xqcilia` (Large Immediate Arithmetic)

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,17 @@ struct RISCVOperand final : public MCParsedAsmOperand {
11441144
VK == RISCVMCExpr::VK_None;
11451145
}
11461146

1147+
bool isSImm32Lsb0() const {
1148+
if (!isImm())
1149+
return false;
1150+
RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_None;
1151+
int64_t Imm;
1152+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
1153+
return IsConstantImm &&
1154+
isShiftedInt<31, 1>(fixImmediateForRV32(Imm, isRV64Imm())) &&
1155+
VK == RISCVMCExpr::VK_None;
1156+
}
1157+
11471158
/// getStartLoc - Gets location of the first token of this operand
11481159
SMLoc getStartLoc() const override { return StartLoc; }
11491160
/// getEndLoc - Gets location of the last token of this operand
@@ -1777,6 +1788,11 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
17771788
return generateImmOutOfRangeError(Operands, ErrorInfo,
17781789
std::numeric_limits<int32_t>::min(),
17791790
std::numeric_limits<uint32_t>::max());
1791+
case Match_InvalidSImm32Lsb0:
1792+
return generateImmOutOfRangeError(
1793+
Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1794+
std::numeric_limits<int32_t>::max() - 1,
1795+
"operand must be a multiple of 2 bytes in the range ");
17801796
case Match_InvalidRnumArg: {
17811797
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
17821798
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -667,10 +667,10 @@ static constexpr FeatureBitset XqciFeatureGroup = {
667667
RISCV::FeatureVendorXqcibi, RISCV::FeatureVendorXqcibm,
668668
RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm,
669669
RISCV::FeatureVendorXqcics, RISCV::FeatureVendorXqcicsr,
670-
RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqcili,
671-
RISCV::FeatureVendorXqcilia, RISCV::FeatureVendorXqcilo,
672-
RISCV::FeatureVendorXqcilsm, RISCV::FeatureVendorXqcisim,
673-
RISCV::FeatureVendorXqcisls,
670+
RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqcilb,
671+
RISCV::FeatureVendorXqcili, RISCV::FeatureVendorXqcilia,
672+
RISCV::FeatureVendorXqcilo, RISCV::FeatureVendorXqcilsm,
673+
RISCV::FeatureVendorXqcisim, RISCV::FeatureVendorXqcisls,
674674
};
675675

676676
static constexpr FeatureBitset XSfVectorGroup = {

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,6 +1374,14 @@ def HasVendorXqciint
13741374
AssemblerPredicate<(all_of FeatureVendorXqciint),
13751375
"'Xqciint' (Qualcomm uC Interrupts Extension)">;
13761376

1377+
def FeatureVendorXqcilb
1378+
: RISCVExperimentalExtension<0, 2, "Qualcomm uC Long Branch Extension",
1379+
[FeatureStdExtZca]>;
1380+
1381+
def HasVendorXqcilb : Predicate<"Subtarget->hasVendorXqcilb()">,
1382+
AssemblerPredicate<(all_of FeatureVendorXqcilb),
1383+
"'Xqcilb' (Qualcomm uC Long Branch Extension)">;
1384+
13771385
def FeatureVendorXqcili
13781386
: RISCVExperimentalExtension<0, 2, "Qualcomm uC Load Large Immediate Extension",
13791387
[FeatureStdExtZca]>;

llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,21 @@ def simm32 : RISCVOp<XLenVT> {
9696
}];
9797
}
9898

99+
// A 32-bit signed immediate where the least significant bit is zero.
100+
def simm32_lsb0 : Operand<OtherVT> {
101+
let ParserMatchClass = SImmAsmOperand<32, "Lsb0">;
102+
let PrintMethod = "printBranchOperand";
103+
let EncoderMethod = "getImmOpValueAsr1";
104+
let DecoderMethod = "decodeSImmOperandAndLsl1<32>";
105+
let MCOperandPredicate = [{
106+
int64_t Imm;
107+
if (!MCOp.evaluateAsConstantImm(Imm))
108+
return false;
109+
return isShiftedInt<31, 1>(Imm);
110+
}];
111+
let OperandType = "OPERAND_PCREL";
112+
}
113+
99114
//===----------------------------------------------------------------------===//
100115
// Instruction Formats
101116
//===----------------------------------------------------------------------===//
@@ -413,6 +428,24 @@ class QCIRVInstEI<bits<3> funct3, bits<2> funct2, string opcodestr>
413428
(ins GPRNoX0:$rs1, simm26:$imm), opcodestr,
414429
"$rd, $rs1, $imm">;
415430

431+
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
432+
class QCIRVInst48EJ<bits<2> func2, string opcodestr>
433+
: RVInst48<(outs), (ins simm32_lsb0:$imm31),
434+
opcodestr, "$imm31", [], InstFormatOther> {
435+
bits<31> imm31;
436+
437+
let Inst{47-32} = imm31{30-15};
438+
let Inst{31} = imm31{11};
439+
let Inst{30-25} = imm31{9-4};
440+
let Inst{24-20} = 0b00000;
441+
let Inst{19-17} = imm31{14-12};
442+
let Inst{16-15} = func2;
443+
let Inst{14-12} = 0b100;
444+
let Inst{11-8} = imm31{3-0};
445+
let Inst{7} = imm31{10};
446+
let Inst{6-0} = 0b0011111;
447+
}
448+
416449
//===----------------------------------------------------------------------===//
417450
// Instructions
418451
//===----------------------------------------------------------------------===//
@@ -677,6 +710,13 @@ let Predicates = [HasVendorXqcilo, IsRV32] in {
677710
def QC_E_SW : QCIRVInstESStore<0b110, 0b11, "qc.e.sw">;
678711
} // Predicates = [HasVendorXqcilo, IsRV32]
679712

713+
let Predicates = [HasVendorXqcilb, IsRV32] in {
714+
let isCall = 1, Defs = [X1] in
715+
def QC_E_JAL : QCIRVInst48EJ<0b01, "qc.e.jal">;
716+
let isBranch = 1, isTerminator = 1, isBarrier = 1 in
717+
def QC_E_J : QCIRVInst48EJ<0b00, "qc.e.j">;
718+
} // Predicates = [HasVendorXqcilb, IsRV32]
719+
680720
let Predicates = [HasVendorXqcili, IsRV32] in {
681721
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
682722
def QC_LI : RVInstU<OPC_OP_IMM_32, (outs GPRNoX0:$rd), (ins simm20:$imm20),

llvm/lib/TargetParser/RISCVISAInfo.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -744,9 +744,10 @@ Error RISCVISAInfo::checkDependency() {
744744
bool HasXqccmp = Exts.count("xqccmp") != 0;
745745

746746
static constexpr StringLiteral XqciExts[] = {
747-
{"xqcia"}, {"xqciac"}, {"xqcibi"}, {"xqcibm"}, {"xqcicli"},
748-
{"xqcicm"}, {"xqcics"}, {"xqcicsr"}, {"xqciint"}, {"xqcili"},
749-
{"xqcilia"}, {"xqcilo"}, {"xqcilsm"}, {"xqcisim"}, {"xqcisls"}};
747+
{"xqcia"}, {"xqciac"}, {"xqcibi"}, {"xqcibm"},
748+
{"xqcicli"}, {"xqcicm"}, {"xqcics"}, {"xqcicsr"},
749+
{"xqciint"}, {"xqcilb"}, {"xqcili"}, {"xqcilia"},
750+
{"xqcilo"}, {"xqcilsm"}, {"xqcisim"}, {"xqcisls"}};
750751
static constexpr StringLiteral ZcdOverlaps[] = {
751752
{"zcmt"}, {"zcmp"}, {"xqccmp"}, {"xqciac"}, {"xqcicm"}};
752753

llvm/test/CodeGen/RISCV/attributes.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcics %s -o - | FileCheck --check-prefix=RV32XQCICS %s
9292
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %s
9393
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqciint %s -o - | FileCheck --check-prefix=RV32XQCIINT %s
94+
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilb %s -o - | FileCheck --check-prefix=RV32XQCILB %s
9495
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcili %s -o - | FileCheck --check-prefix=RV32XQCILI %s
9596
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilia %s -o - | FileCheck --check-prefix=RV32XQCILIA %s
9697
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilo %s -o - | FileCheck --check-prefix=RV32XQCILO %s
@@ -418,6 +419,7 @@
418419
; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
419420
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
420421
; RV32XQCIINT: .attribute 5, "rv32i2p1_zca1p0_xqciint0p4"
422+
; RV32XQCILB: .attribute 5, "rv32i2p1_zca1p0_xqcilb0p2"
421423
; RV32XQCILI: .attribute 5, "rv32i2p1_zca1p0_xqcili0p2"
422424
; RV32XQCILIA: .attribute 5, "rv32i2p1_zca1p0_xqcilia0p2"
423425
; RV32XQCILO: .attribute 5, "rv32i2p1_zca1p0_xqcilo0p2"

llvm/test/MC/RISCV/xqcilb-invalid.s

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Xqcilb - Qualcomm uC Long Branch Extension
2+
# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcilb < %s 2>&1 \
3+
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
4+
# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcilb < %s 2>&1 \
5+
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s
6+
7+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
8+
qc.e.j
9+
10+
# CHECK-PLUS: :[[@LINE+1]]:9: error: operand must be a multiple of 2 bytes in the range [-2147483648, 2147483646]
11+
qc.e.j -2147483649
12+
13+
# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilb' (Qualcomm uC Long Branch Extension)
14+
qc.e.j -2147483648
15+
16+
17+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
18+
qc.e.jal
19+
20+
# CHECK-PLUS: :[[@LINE+1]]:10: error: operand must be a multiple of 2 bytes in the range [-2147483648, 2147483646]
21+
qc.e.jal 2147483649
22+
23+
# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilb' (Qualcomm uC Long Branch Extension)
24+
qc.e.jal 2147483640

llvm/test/MC/RISCV/xqcilb-valid.s

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Xqcilb - Qualcomm uC Long Branch Extension
2+
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilb -riscv-no-aliases -show-encoding \
3+
# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
4+
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilb < %s \
5+
# RUN: | llvm-objdump --mattr=+experimental-xqcilb -M no-aliases --no-print-imm-hex -d - \
6+
# RUN: | FileCheck -check-prefix=CHECK-OBJ %s
7+
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilb -show-encoding \
8+
# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
9+
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilb < %s \
10+
# RUN: | llvm-objdump --mattr=+experimental-xqcilb --no-print-imm-hex -d - \
11+
# RUN: | FileCheck -check-prefix=CHECK-OBJ %s
12+
13+
# CHECK-INST: qc.e.j -2147483648
14+
# CHECK-OBJ: qc.e.j 0x80000000
15+
# CHECK-ENC: encoding: [0x1f,0x40,0x00,0x00,0x00,0x80]
16+
qc.e.j -2147483648
17+
18+
# CHECK-INST: qc.e.jal 2147483640
19+
# CHECK-OBJ: qc.e.jal 0x7ffffffe
20+
# CHECK-ENC: encoding: [0x9f,0xcc,0x0e,0xfe,0xff,0x7f]
21+
qc.e.jal 2147483640
22+
23+
# CHECK-INST: qc.e.jal -116
24+
# CHECK-OBJ: qc.e.jal 0xffffff98
25+
# CHECK-ENC: encoding: [0x9f,0xc6,0x0e,0xf8,0xff,0xff]
26+
qc.e.jal 0xffffff8c

llvm/unittests/TargetParser/RISCVISAInfoTest.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,8 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
663663
"rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcicm0p2",
664664
"rv64i_xqcics0p2", "rv64i_xqcicli0p2", "rv64i_xqciint0p4",
665665
"rv64i_xqcilo0p2", "rv64i_xqcilia0p2", "rv64i_xqcibm0p4",
666-
"rv64i_xqcibi0p2", "rv64i_xqcili0p2", "rv64i_xqcisim0p2"}) {
666+
"rv64i_xqcibi0p2", "rv64i_xqcili0p2", "rv64i_xqcisim0p2",
667+
"rv64i_xqcilb0p2"}) {
667668
EXPECT_THAT(
668669
toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
669670
::testing::EndsWith(" is only supported for 'rv32'"));
@@ -1150,6 +1151,7 @@ Experimental extensions
11501151
xqcics 0.2
11511152
xqcicsr 0.2
11521153
xqciint 0.4
1154+
xqcilb 0.2
11531155
xqcili 0.2
11541156
xqcilia 0.2
11551157
xqcilo 0.2

0 commit comments

Comments
 (0)