diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -273,3 +273,6 @@ ``XCVmac`` LLVM implements `version 1.3.1 of the Core-V Multiply-Accumulate (MAC) custom instructions specification `_ by Core-V. All instructions are prefixed with `cv.mac.` as described in the specification. These instructions are only available for riscv32 at this time. + +``XCVbi`` + LLVM implements `version 1.3.1 of the Core-V immediate branching (MAC) custom instructions specification `_ by Core-V. All instructions are prefixed with `cv.` as described in the specification. These instructions are only available for riscv32 at this time. diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -563,6 +563,9 @@ "CORE-V Bit Manipulation custom opcode table"); TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmac, DecoderTableXCVmac32, "CORE-V MAC custom opcode table"); + TRY_TO_DECODE_FEATURE( + RISCV::FeatureVendorXCVbi, DecoderTableXCVbi32, + "CORE-V Immediate Branching extensions custom opcode table"); TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table"); return MCDisassembler::Fail; diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -767,6 +767,13 @@ AssemblerPredicate<(all_of FeatureVendorXCVmac), "'XCVmac' (Multiply-Accumulate)">; +def FeatureVendorXCVbi + : SubtargetFeature<"xcvbi", "HasVendorXCVbi", "true", + "'XCVbi' (Immediate Branching)">; +def HasVendorXCVbi : Predicate<"Subtarget->hasVendorXCVbi()">, + AssemblerPredicate<(all_of FeatureVendorXCVbi), + "'XCVbi' (Immediate Branching)">; + //===----------------------------------------------------------------------===// // LLVM specific features and extensions //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td @@ -180,3 +180,22 @@ def : InstAlias<"cv.mulu $rd1, $rs1, $rs2", (CV_MULUN GPR:$rd1, GPR:$rs1, GPR:$rs2, 0)>; def : InstAlias<"cv.mulhhu $rd1, $rs1, $rs2", (CV_MULHHUN GPR:$rd1, GPR:$rs1, GPR:$rs2, 0)>; } // Predicates = [HasVendorXCVmac, IsRV32] + +class RVInstImmBranch funct3, dag outs, dag ins, + string opcodestr, string argstr> + : RVInstB { + bits<5> imm5; + let rs2 = imm5; + let DecoderNamespace = "XCVbi"; +} + +let Predicates = [HasVendorXCVbi, IsRV32], hasSideEffects = 0, mayLoad = 0, + mayStore = 0, isBranch = 1, isTerminator = 1 in { + // Immediate branching operations + def CV_BEQIMM : RVInstImmBranch<0b110, (outs), + (ins GPR:$rs1, simm5:$imm5, simm13_lsb0:$imm12), + "cv.beqimm", "$rs1, $imm5, $imm12">, Sched<[]>; + def CV_BNEIMM : RVInstImmBranch<0b111, (outs), + (ins GPR:$rs1, simm5:$imm5, simm13_lsb0:$imm12), + "cv.bneimm", "$rs1, $imm5, $imm12">, Sched<[]>; +} diff --git a/llvm/test/MC/RISCV/corev/XCVbi-invalid.s b/llvm/test/MC/RISCV/corev/XCVbi-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/corev/XCVbi-invalid.s @@ -0,0 +1,58 @@ +# RUN: not llvm-mc -triple=riscv32 --mattr=+xcvbi %s 2>&1 \ +# RUN: | FileCheck %s --check-prefixes=CHECK-ERROR + +//===----------------------------------------------------------------------===// +// cv.beqimm +//===----------------------------------------------------------------------===// + +cv.beqimm 0, 0, 0 +# CHECK-ERROR: invalid operand for instruction + +cv.beqimm t0, t1, 0 +# CHECK-ERROR: immediate must be an integer in the range [-16, 15] + +cv.beqimm t0, 0, t1 +# CHECK-ERROR: immediate must be a multiple of 2 bytes in the range [-4096, 4094] + +cv.beqimm t0, 16, 0 +# CHECK-ERROR: immediate must be an integer in the range [-16, 15] + +cv.beqimm t0, -17, 0 +# CHECK-ERROR: immediate must be an integer in the range [-16, 15] + +cv.beqimm t0, 0, 1 +# CHECK-ERROR: immediate must be a multiple of 2 bytes in the range [-4096, 4094] + +cv.beqimm t0, 0, 4096 +# CHECK-ERROR: immediate must be a multiple of 2 bytes in the range [-4096, 4094] + +cv.beqimm t0, 0, -4098 +# CHECK-ERROR: immediate must be a multiple of 2 bytes in the range [-4096, 4094] + +//===----------------------------------------------------------------------===// +// cv.bneimm +//===----------------------------------------------------------------------===// + +cv.bneimm 0, 0, 0 +# CHECK-ERROR: invalid operand for instruction + +cv.bneimm t0, t1, 0 +# CHECK-ERROR: immediate must be an integer in the range [-16, 15] + +cv.bneimm t0, 0, t1 +# CHECK-ERROR: immediate must be a multiple of 2 bytes in the range [-4096, 4094] + +cv.bneimm t0, 16, 0 +# CHECK-ERROR: immediate must be an integer in the range [-16, 15] + +cv.bneimm t0, -17, 0 +# CHECK-ERROR: immediate must be an integer in the range [-16, 15] + +cv.bneimm t0, 0, 1 +# CHECK-ERROR: immediate must be a multiple of 2 bytes in the range [-4096, 4094] + +cv.bneimm t0, 0, 4096 +# CHECK-ERROR: immediate must be a multiple of 2 bytes in the range [-4096, 4094] + +cv.bneimm t0, 0, -4098 +# CHECK-ERROR: immediate must be a multiple of 2 bytes in the range [-4096, 4094] \ No newline at end of file diff --git a/llvm/test/MC/RISCV/corev/XCVbi.s b/llvm/test/MC/RISCV/corev/XCVbi.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/corev/XCVbi.s @@ -0,0 +1,40 @@ +# RUN: llvm-mc -triple=riscv32 --mattr=+xcvbi -show-encoding %s \ +# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INSTR + +//===----------------------------------------------------------------------===// +// cv.beqimm +//===----------------------------------------------------------------------===// + +label1: + +cv.beqimm t0, 0, 0 +# CHECK-INSTR: cv.beqimm t0, 0, 0 +# CHECK-ENCODING: [0x0b,0xe0,0x02,0x00] + +cv.beqimm a0, 5, 42 +# CHECK-INSTR: cv.beqimm a0, 5, 42 +# CHECK-ENCODING: [0x0b,0x65,0x55,0x02] + +cv.beqimm a0, -5, label1 +# CHECK-INSTR: cv.beqimm a0, -5, label1 +# CHECK-ENCODING: [0x0b'A',0x60'A',0xb5'A',0x01'A'] +# CHECK-ENCODING: fixup A - offset: 0, value: label1, kind: fixup_riscv_branch + +//===----------------------------------------------------------------------===// +// cv.bneimm +//===----------------------------------------------------------------------===// + +label2: + +cv.bneimm t0, 0, 0 +# CHECK-INSTR: cv.bneimm t0, 0, 0 +# CHECK-ENCODING: [0x0b,0xf0,0x02,0x00] + +cv.bneimm a0, 5, 42 +# CHECK-INSTR: cv.bneimm a0, 5, 42 +# CHECK-ENCODING: [0x0b,0x75,0x55,0x02] + +cv.bneimm a0, -5, label2 +# CHECK-INSTR: cv.bneimm a0, -5, label2 +# CHECK-ENCODING: [0x0b'A',0x70'A',0xb5'A',0x01'A'] +# CHECK-ENCODING: fixup A - offset: 0, value: label2, kind: fixup_riscv_branch