Skip to content

Commit fa402ab

Browse files
committed
[RISCV] Add Support of RISCV Zibimm Experimental Extension
1 parent 6684a59 commit fa402ab

18 files changed

+552
-6
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@
183183
// CHECK-EMPTY:
184184
// CHECK-NEXT: Experimental extensions
185185
// CHECK-NEXT: p 0.14 'P' ('Base P' (Packed SIMD))
186+
// CHECK-NEXT: zibimm 0.1 'Zibimm' (Branch with Immediate)
186187
// CHECK-NEXT: zicfilp 1.0 'Zicfilp' (Landing pad)
187188
// CHECK-NEXT: zicfiss 1.0 'Zicfiss' (Shadow stack)
188189
// CHECK-NEXT: zalasr 0.1 'Zalasr' (Load-Acquire and Store-Release Instructions)

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
// CHECK-NOT: __riscv_zfinx {{.*$}}
119119
// CHECK-NOT: __riscv_zhinx {{.*$}}
120120
// CHECK-NOT: __riscv_zhinxmin {{.*$}}
121+
// CHECK-NOT: __riscv_zibimm {{.*$}}
121122
// CHECK-NOT: __riscv_zic64b {{.*$}}
122123
// CHECK-NOT: __riscv_zicbom {{.*$}}
123124
// CHECK-NOT: __riscv_zicbop {{.*$}}
@@ -998,6 +999,14 @@
998999
// RUN: -o - | FileCheck --check-prefix=CHECK-ZHINXMIN-EXT %s
9991000
// CHECK-ZHINXMIN-EXT: __riscv_zhinxmin 1000000{{$}}
10001001

1002+
// RUN: %clang --target=riscv32 -menable-experimental-extensions \
1003+
// RUN: -march=rv32i_zibimm0p1 -E -dM %s \
1004+
// RUN: -o - | FileCheck --check-prefix=CHECK-ZIBIMM-EXT %s
1005+
// RUN: %clang --target=riscv64 -menable-experimental-extensions \
1006+
// RUN: -march=rv64i_zibimm0p1 -E -dM %s \
1007+
// RUN: -o - | FileCheck --check-prefix=CHECK-ZIBIMM-EXT %s
1008+
// CHECK-ZIBIMM-EXT: __riscv_zibimm
1009+
10011010
// RUN: %clang --target=riscv32-unknown-linux-gnu \
10021011
// RUN: -march=rv32izic64b -E -dM %s \
10031012
// RUN: -o - | FileCheck --check-prefix=CHECK-ZIC64B-EXT %s

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,17 @@ struct RISCVOperand final : public MCParsedAsmOperand {
735735
VK == RISCVMCExpr::VK_RISCV_None;
736736
}
737737

738+
bool isUImm5Zibimm() const {
739+
if (!isImm())
740+
return false;
741+
int64_t Imm;
742+
RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
743+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
744+
Imm = fixImmediateForRV32(Imm, isRV64Imm());
745+
return IsConstantImm && ((isUInt<5>(Imm) && Imm != 0) || Imm == -1) &&
746+
VK == RISCVMCExpr::VK_RISCV_None;
747+
}
748+
738749
bool isUImm5GT3() const {
739750
if (!isImm())
740751
return false;
@@ -1550,6 +1561,10 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
15501561
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
15511562
case Match_InvalidUImm5NonZero:
15521563
return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1564+
case Match_InvalidUImm5Zibimm:
1565+
return generateImmOutOfRangeError(
1566+
Operands, ErrorInfo, -1, (1 << 5) - 1,
1567+
"immediate must be non-zero in the range");
15531568
case Match_InvalidUImm5GT3:
15541569
return generateImmOutOfRangeError(Operands, ErrorInfo, 4, (1 << 5) - 1);
15551570
case Match_InvalidUImm6:

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,18 @@ static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
350350
return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
351351
}
352352

353+
template <unsigned N>
354+
static DecodeStatus decodeUImmZibimmOperand(MCInst &Inst, uint32_t Imm,
355+
int64_t Address,
356+
const MCDisassembler *Decoder) {
357+
assert(isUInt<N>(Imm) && "Invalid immediate");
358+
if (Imm)
359+
Inst.addOperand(MCOperand::createImm(Imm));
360+
else
361+
Inst.addOperand(MCOperand::createImm(-1));
362+
return MCDisassembler::Success;
363+
}
364+
353365
static DecodeStatus
354366
decodeUImmLog2XLenNonZeroOperand(MCInst &Inst, uint32_t Imm, int64_t Address,
355367
const MCDisassembler *Decoder) {

llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,7 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
789789
RISCVCC::CondCode CC;
790790
getOperandsForBranch(MI.getOperand(0).getReg(), CC, LHS, RHS, *MRI);
791791

792-
auto Bcc = MIB.buildInstr(RISCVCC::getBrCond(CC), {}, {LHS, RHS})
792+
auto Bcc = MIB.buildInstr(RISCVCC::getBrCond(STI, CC), {}, {LHS, RHS})
793793
.addMBB(MI.getOperand(1).getMBB());
794794
MI.eraseFromParent();
795795
return constrainSelectedInstRegOperands(*Bcc, TII, TRI, RBI);

llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ enum OperandType : unsigned {
302302
OPERAND_UIMM4,
303303
OPERAND_UIMM5,
304304
OPERAND_UIMM5_NONZERO,
305+
OPERAND_UIMM5_ZIBIMM,
305306
OPERAND_UIMM5_GT3,
306307
OPERAND_UIMM5_LSB0,
307308
OPERAND_UIMM6,

llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ class RISCVMCCodeEmitter : public MCCodeEmitter {
8484
SmallVectorImpl<MCFixup> &Fixups,
8585
const MCSubtargetInfo &STI) const;
8686

87+
uint64_t getImmOpValueZibimm(const MCInst &MI, unsigned OpNo,
88+
SmallVectorImpl<MCFixup> &Fixups,
89+
const MCSubtargetInfo &STI) const;
90+
8791
uint64_t getImmOpValue(const MCInst &MI, unsigned OpNo,
8892
SmallVectorImpl<MCFixup> &Fixups,
8993
const MCSubtargetInfo &STI) const;
@@ -400,6 +404,22 @@ RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo,
400404
return getImmOpValue(MI, OpNo, Fixups, STI);
401405
}
402406

407+
uint64_t
408+
RISCVMCCodeEmitter::getImmOpValueZibimm(const MCInst &MI, unsigned OpNo,
409+
SmallVectorImpl<MCFixup> &Fixups,
410+
const MCSubtargetInfo &STI) const {
411+
const MCOperand &MO = MI.getOperand(OpNo);
412+
413+
if (MO.isImm()) {
414+
uint64_t Res = MO.getImm();
415+
if (Res >= 1 && Res <= 31)
416+
return Res;
417+
if (Res == (uint64_t)-1)
418+
return 0;
419+
}
420+
return getImmOpValue(MI, OpNo, Fixups, STI);
421+
}
422+
403423
uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
404424
SmallVectorImpl<MCFixup> &Fixups,
405425
const MCSubtargetInfo &STI) const {

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@ def FeatureStdExtI
7777
def FeatureStdExtE
7878
: RISCVExtension<2, 0, "Embedded Instruction Set with 16 GPRs">;
7979

80+
def FeatureStdExtZibimm
81+
: RISCVExperimentalExtension<0, 1, "'Zibimm' (Branch with Immediate)">;
82+
def HasStdExtZibimm : Predicate<"Subtarget->hasStdExtZibimm()">,
83+
AssemblerPredicate<(all_of FeatureStdExtZibimm),
84+
"'Zibimm' (Branch with Immediate)">;
85+
8086
def FeatureStdExtZic64b
8187
: RISCVExtension<1, 0, "Cache Block Size Is 64 Bytes">;
8288

llvm/lib/Target/RISCV/RISCVInstrFormats.td

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,22 @@ class RVInstB<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins,
489489
let Inst{6-0} = opcode.Value;
490490
}
491491

492+
class RVInstBIMM<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins,
493+
string opcodestr, string argstr>
494+
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatB> {
495+
bits<12> imm12;
496+
bits<5> cimm;
497+
bits<5> rs1;
498+
let Inst{31} = imm12{11};
499+
let Inst{30-25} = imm12{9-4};
500+
let Inst{24-20} = cimm;
501+
let Inst{19-15} = rs1;
502+
let Inst{14-12} = funct3;
503+
let Inst{11-8} = imm12{3-0};
504+
let Inst{7} = imm12{10};
505+
let Inst{6-0} = opcode.Value;
506+
}
507+
492508
class RVInstU<RISCVOpcode opcode, dag outs, dag ins, string opcodestr,
493509
string argstr>
494510
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatU> {

llvm/lib/Target/RISCV/RISCVInstrInfo.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,10 @@ static RISCVCC::CondCode getCondFromBranchOpc(unsigned Opc) {
923923
return RISCVCC::COND_EQ;
924924
case RISCV::CV_BNEIMM:
925925
return RISCVCC::COND_NE;
926+
case RISCV::BEQI:
927+
return RISCVCC::COND_EQ;
928+
case RISCV::BNEI:
929+
return RISCVCC::COND_NE;
926930
case RISCV::BEQ:
927931
return RISCVCC::COND_EQ;
928932
case RISCV::BNE:
@@ -953,14 +957,21 @@ static void parseCondBranch(MachineInstr &LastInst, MachineBasicBlock *&Target,
953957
Cond.push_back(LastInst.getOperand(1));
954958
}
955959

956-
unsigned RISCVCC::getBrCond(RISCVCC::CondCode CC, bool Imm) {
960+
unsigned RISCVCC::getBrCond(const RISCVSubtarget &STI, RISCVCC::CondCode CC,
961+
bool Imm) {
957962
switch (CC) {
958963
default:
959964
llvm_unreachable("Unknown condition code!");
960965
case RISCVCC::COND_EQ:
961-
return Imm ? RISCV::CV_BEQIMM : RISCV::BEQ;
966+
return Imm ? (STI.hasStdExtZibimm()
967+
? RISCV::BEQI
968+
: (STI.hasVendorXCVbi() ? RISCV::CV_BEQIMM : RISCV::BEQ))
969+
: RISCV::BEQ;
962970
case RISCVCC::COND_NE:
963-
return Imm ? RISCV::CV_BNEIMM : RISCV::BNE;
971+
return Imm ? (STI.hasStdExtZibimm()
972+
? RISCV::BNEI
973+
: (STI.hasVendorXCVbi() ? RISCV::CV_BNEIMM : RISCV::BNE))
974+
: RISCV::BNE;
964975
case RISCVCC::COND_LT:
965976
return RISCV::BLT;
966977
case RISCVCC::COND_GE:
@@ -974,7 +985,7 @@ unsigned RISCVCC::getBrCond(RISCVCC::CondCode CC, bool Imm) {
974985

975986
const MCInstrDesc &RISCVInstrInfo::getBrCond(RISCVCC::CondCode CC,
976987
bool Imm) const {
977-
return get(RISCVCC::getBrCond(CC, Imm));
988+
return get(RISCVCC::getBrCond(STI, CC, Imm));
978989
}
979990

980991
RISCVCC::CondCode RISCVCC::getOppositeBranchCondition(RISCVCC::CondCode CC) {
@@ -1350,6 +1361,8 @@ bool RISCVInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
13501361
case RISCV::BGE:
13511362
case RISCV::BLTU:
13521363
case RISCV::BGEU:
1364+
case RISCV::BEQI:
1365+
case RISCV::BNEI:
13531366
case RISCV::CV_BEQIMM:
13541367
case RISCV::CV_BNEIMM:
13551368
return isIntN(13, BrOffset);
@@ -2490,6 +2503,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
24902503
case RISCVOp::OPERAND_UIMM2_LSB0:
24912504
Ok = isShiftedUInt<1, 1>(Imm);
24922505
break;
2506+
case RISCVOp::OPERAND_UIMM5_ZIBIMM:
2507+
Ok = (isUInt<5>(Imm) && Imm != 0) || Imm == -1;
2508+
break;
24932509
case RISCVOp::OPERAND_UIMM5_LSB0:
24942510
Ok = isShiftedUInt<4, 1>(Imm);
24952511
break;

0 commit comments

Comments
 (0)