Skip to content

Commit

Permalink
[RISCV] Fix hwlp instructions (plctlab#26)
Browse files Browse the repository at this point in the history
Updated hwlp instructions for CV32E40P from version 1 to version 2 according to the documentation.

Co-authored-by: Qihan Cai <[email protected]>
  • Loading branch information
realqhc and Qihan Cai authored Mar 3, 2023
1 parent b18cb93 commit 4eec1f1
Show file tree
Hide file tree
Showing 26 changed files with 164 additions and 95 deletions.
3 changes: 2 additions & 1 deletion llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1325,7 +1325,8 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
}
case Match_InvalidCVUImm1: {
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 1);
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 1,
"loop ID must be an integer in the range");
}
case Match_InvalidCVUImm5: {
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 2,
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Target/RISCV/RISCV.td
Original file line number Diff line number Diff line change
Expand Up @@ -417,10 +417,10 @@ def Feature32Bit
//
// CORE-V Hardware Loop Extension
def FeatureExtXCoreVHwlp
: SubtargetFeature<"xcorevhwlp", "HasExtXCoreVHwlp", "true",
: SubtargetFeature<"xcorevhwlp", "HasExtXcvHwlp", "true",
"'Xcorevhwlp' (Hardware Loop)">;
def HasExtXCoreVHwlp
: Predicate<"Subtarget->hasExtXCoreVHwlp()">,
def HasExtXcvHwlp
: Predicate<"Subtarget->hasExtXcvHwlp()">,
AssemblerPredicate<(any_of FeatureExtXCoreVHwlp),
"'Xcorevhwlp' (Hardware Loop)">;
// CORE-V Multiply-Accumulate Extension
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/RISCVCoreVHwlpBlocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ namespace {
char RISCVCoreVHwlpBlocks::ID = 0;

bool RISCVCoreVHwlpBlocks::runOnMachineFunction(MachineFunction &MF) {
if (!MF.getSubtarget<RISCVSubtarget>().hasExtXCoreVHwlp()) {
if (!MF.getSubtarget<RISCVSubtarget>().hasExtXcvHwlp()) {
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/RISCVExpandCoreVHwlpPseudoInsts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ namespace {
char RISCVExpandCoreVHwlpPseudo::ID = 0;

bool RISCVExpandCoreVHwlpPseudo::runOnMachineFunction(MachineFunction &MF) {
if (!MF.getSubtarget<RISCVSubtarget>().hasExtXCoreVHwlp()) {
if (!MF.getSubtarget<RISCVSubtarget>().hasExtXcvHwlp()) {
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setIndexedStoreAction(ISD::POST_INC, MVT::i32, Legal);
}

if (Subtarget.hasExtXCoreVHwlp()) {
if (Subtarget.hasExtXcvHwlp()) {
setTargetDAGCombine(ISD::BR);
// The default legalizer can't promote this to i32, so we do it manually
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i1, Custom);
Expand Down
36 changes: 18 additions & 18 deletions llvm/lib/Target/RISCV/RISCVInstrFormatsCOREV.td
Original file line number Diff line number Diff line change
Expand Up @@ -12,58 +12,58 @@
//
//===----------------------------------------------------------------------===//

class RVInstHwlp_i<bits<3> funct3, dag ins, string opcodestr, string argstr>
class RVInstHwlp_i<bits<4> rd, dag ins, string opcodestr, string argstr>
: RVInst<(outs), ins, opcodestr, argstr, [], InstFormatCVHwlp> {
bits<12> imm12;
bits<1> imm1;

let Inst{31-20} = imm12;
let Inst{19-15} = 0b00000;
let Inst{14-12} = funct3;
let Inst{11-8} = 0b0000;
let Inst{19-15} = 0b00000; // rs1
let Inst{14-12} = 0b100; // funct3
let Inst{11-8} = rd;
let Inst{7} = imm1;
let Opcode = OPC_CUSTOM3.Value;
let Opcode = OPC_CUSTOM1.Value;
}

class RVInstHwlp_r<bits<3> funct3, dag ins, string opcodestr, string argstr>
class RVInstHwlp_r<bits<4> rd, dag ins, string opcodestr, string argstr>
: RVInst<(outs), ins, opcodestr, argstr, [], InstFormatCVHwlp> {
bits<5> rs1;
bits<1> imm1;

let Inst{31-20} = 0;
let Inst{31-20} = 0; // imm12
let Inst{19-15} = rs1;
let Inst{14-12} = funct3;
let Inst{11-8} = 0b0000;
let Inst{14-12} = 0b100; // funct3
let Inst{11-8} = rd;
let Inst{7} = imm1;
let Opcode = OPC_CUSTOM3.Value;
let Opcode = OPC_CUSTOM1.Value;
}

class RVInstHwlp_ri<bits<3> funct3, dag ins, string opcodestr, string argstr>
class RVInstHwlp_ri<bits<4> rd, dag ins, string opcodestr, string argstr>
: RVInst<(outs), ins, opcodestr, argstr, [], InstFormatCVHwlp> {
bits<12> imm12;
bits<5> rs1;
bits<1> imm1;

let Inst{31-20} = imm12;
let Inst{19-15} = rs1;
let Inst{14-12} = funct3;
let Inst{11-8} = 0b0000;
let Inst{14-12} = 0b100; // funct3
let Inst{11-8} = rd;
let Inst{7} = imm1;
let Opcode = OPC_CUSTOM3.Value;
let Opcode = OPC_CUSTOM1.Value;
}

class RVInstHwlp_ii<bits<3> funct3, dag ins, string opcodestr, string argstr>
class RVInstHwlp_ii<bits<4> rd, dag ins, string opcodestr, string argstr>
: RVInst<(outs), ins, opcodestr, argstr, [], InstFormatCVHwlp> {
bits<12> imm12;
bits<5> imm5;
bits<1> imm1;

let Inst{31-20} = imm12;
let Inst{19-15} = imm5;
let Inst{14-12} = funct3;
let Inst{11-8} = 0b0000;
let Inst{14-12} = 0b100; // funct3
let Inst{11-8} = rd;
let Inst{7} = imm1;
let Opcode = OPC_CUSTOM3.Value;
let Opcode = OPC_CUSTOM1.Value;
}

class RVInstMac<bits<7> funct7, bits<3> funct3, dag outs, dag ins,
Expand Down
30 changes: 18 additions & 12 deletions llvm/lib/Target/RISCV/RISCVInstrInfoCOREV.td
Original file line number Diff line number Diff line change
Expand Up @@ -74,26 +74,32 @@ def cv_uimm12 : Operand<XLenVT>,
// CORE-V specific instructions
//===----------------------------------------------------------------------===//

let Predicates = [HasExtXCoreVHwlp], hasSideEffects = 1, mayLoad = 0, mayStore = 0 in {
def CV_STARTI : RVInstHwlp_i<0b000, (ins cv_uimm1:$imm1, cv_uimm12:$imm12),
let Predicates = [HasExtXcvHwlp], hasSideEffects = 1, mayLoad = 0, mayStore = 0 in {
def CV_STARTI : RVInstHwlp_i<0b0000, (ins cv_uimm1:$imm1, cv_uimm12:$imm12),
"cv.starti", "$imm1, $imm12">,
Sched<[]>;
def CV_ENDI : RVInstHwlp_i<0b001, (ins cv_uimm1:$imm1, cv_uimm12:$imm12),
def CV_START : RVInstHwlp_r<0b0001, (ins cv_uimm1:$imm1, GPR:$rs1),
"cv.start", "$imm1, $rs1">,
Sched<[]>;
def CV_ENDI : RVInstHwlp_i<0b0010, (ins cv_uimm1:$imm1, cv_uimm12:$imm12),
"cv.endi", "$imm1, $imm12">,
Sched<[]>;
def CV_COUNT : RVInstHwlp_r<0b010, (ins cv_uimm1:$imm1, GPR:$rs1),
"cv.count", "$imm1, $rs1">,
Sched<[]>;
def CV_COUNTI : RVInstHwlp_i<0b011, (ins cv_uimm1:$imm1, uimm12:$imm12),
def CV_END : RVInstHwlp_r<0b0011, (ins cv_uimm1:$imm1, GPR:$rs1),
"cv.end", "$imm1, $rs1">,
Sched<[]>;
def CV_COUNTI : RVInstHwlp_i<0b0100, (ins cv_uimm1:$imm1, uimm12:$imm12),
"cv.counti", "$imm1, $imm12">,
Sched<[]>;
def CV_SETUP : RVInstHwlp_ri<0b100, (ins cv_uimm1:$imm1, GPR:$rs1, cv_uimm12:$imm12),
"cv.setup", "$imm1, $rs1, $imm12">,
def CV_COUNT : RVInstHwlp_r<0b0101, (ins cv_uimm1:$imm1, GPR:$rs1),
"cv.count", "$imm1, $rs1">,
Sched<[]>;
def CV_SETUPI : RVInstHwlp_ii<0b101, (ins cv_uimm1:$imm1, uimm12:$imm12, cv_uimm5:$imm5),
def CV_SETUPI : RVInstHwlp_ii<0b0110, (ins cv_uimm1:$imm1, uimm12:$imm12, cv_uimm5:$imm5),
"cv.setupi", "$imm1, $imm12, $imm5">,
Sched<[]>;
} // Predicates = [HasExtXCoreVHwlp], hasSideEffects = 1, mayLoad = 0, mayStore = 0
def CV_SETUP : RVInstHwlp_ri<0b0111, (ins cv_uimm1:$imm1, GPR:$rs1, cv_uimm12:$imm12),
"cv.setup", "$imm1, $rs1, $imm12">,
Sched<[]>;
} // Predicates = [HasExtXcvHwlp], hasSideEffects = 1, mayLoad = 0, mayStore = 0

let Predicates = [HasExtXCoreVMac], hasSideEffects = 0, mayLoad = 0, mayStore = 0, Constraints = "$rd = $rd_wb" in {
// 32x32 bit macs
Expand Down Expand Up @@ -778,7 +784,7 @@ let Predicates = [HasExtXCoreVMem] in {
// Pseudo instructions and patterns for hardware loop generation
//===----------------------------------------------------------------------===//

let Predicates = [HasExtXCoreVHwlp], isNotDuplicable = 1,
let Predicates = [HasExtXcvHwlp], isNotDuplicable = 1,
hasSideEffects = 1, mayLoad = 1, mayStore = 1 in {

// RISCVInstrInfo assumes 3 operands for conditional branch instructions,
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/RISCV/RISCVSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
bool HasStdExtZvlsseg = false;
bool HasStdExtZvamo = false;
bool HasExtXCoreV = false;
bool HasExtXCoreVHwlp = false;
bool HasExtXcvHwlp = false;
bool HasExtXCoreVMac = false;
bool HasExtXCoreVAlu = false;
bool HasExtXCoreVMem = false;
Expand Down Expand Up @@ -202,7 +202,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
bool hasStdExtZvlsseg() const { return HasStdExtZvlsseg; }
bool hasStdExtZvamo() const { return HasStdExtZvamo; }
bool hasExtXCoreV() const { return HasExtXCoreV; }
bool hasExtXCoreVHwlp() const { return HasExtXCoreVHwlp; }
bool hasExtXcvHwlp() const { return HasExtXcvHwlp; }
bool hasExtXCoreVMac() const { return HasExtXCoreVMac; }
bool hasExtXCoreVAlu() const { return HasExtXCoreVAlu; }
bool hasExtXCoreVMem() const { return HasExtXCoreVMem; }
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1016,7 +1016,7 @@ bool RISCVTTIImpl::isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
AssumptionCache &AC,
TargetLibraryInfo *LibInfo,
HardwareLoopInfo &HWLoopInfo) {
if (!ST->hasExtXCoreVHwlp())
if (!ST->hasExtXcvHwlp())
return false;

// Hardware loops need exactly one latch and exiting block and they need to be
Expand Down
12 changes: 6 additions & 6 deletions llvm/test/MC/RISCV/corev/hwlp-all-extensions.s
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@

cv.starti 0, 0
# CHECK-INSTR: cv.starti 0, 0
# CHECK-ENCODING: [0x7b,0x00,0x00,0x00]
# CHECK-ENCODING: [0x2b,0x40,0x00,0x00]

cv.endi 0, 0
# CHECK-INSTR: cv.endi 0, 0
# CHECK-ENCODING: [0x7b,0x10,0x00,0x00]
# CHECK-ENCODING: [0x2b,0x42,0x00,0x00]

cv.count 0, zero
# CHECK-INSTR: cv.count 0, zero
# CHECK-ENCODING: [0x7b,0x20,0x00,0x00]
# CHECK-ENCODING: [0x2b,0x45,0x00,0x00]

cv.counti 0, 0
# CHECK-INSTR: cv.counti 0, 0
# CHECK-ENCODING: [0x7b,0x30,0x00,0x00]
# CHECK-ENCODING: [0x2b,0x44,0x00,0x00]

cv.setup 0, zero, 0
# CHECK-INSTR: cv.setup 0, zero, 0
# CHECK-ENCODING: [0x7b,0x40,0x00,0x00]
# CHECK-ENCODING: [0x2b,0x47,0x00,0x00]

cv.setupi 0, 0, 0
# CHECK-INSTR: cv.setupi 0, 0, 0
# CHECK-ENCODING: [0x7b,0x50,0x00,0x00]
# CHECK-ENCODING: [0x2b,0x46,0x00,0x00]
4 changes: 2 additions & 2 deletions llvm/test/MC/RISCV/corev/hwlp/count-invalid.s
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
# RUN: | FileCheck %s --check-prefixes=CHECK-ERROR

cv.count 2, 0
# CHECK-ERROR: immediate must be an integer in the range [0, 1]
# CHECK-ERROR: loop ID must be an integer in the range [0, 1]

cv.count -1, 0
# CHECK-ERROR: immediate must be an integer in the range [0, 1]
# CHECK-ERROR: loop ID must be an integer in the range [0, 1]

cv.count 1, 10
# CHECK-ERROR: invalid operand for instruction
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/MC/RISCV/corev/hwlp/count.s
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

cv.count 1, s2
# CHECK-INSTR: cv.count 1, s2
# CHECK-ENCODING: [0xfb,0x20,0x09,0x00]
# CHECK-ENCODING: [0xab,0x45,0x09,0x00]

cv.count 0, s4
# CHECK-INSTR: cv.count 0, s4
# CHECK-ENCODING: [0x7b,0x20,0x0a,0x00]
# CHECK-ENCODING: [0x2b,0x45,0x0a,0x00]

cv.count 0, zero
# CHECK-INSTR: cv.count 0, zero
# CHECK-ENCODING: [0x7b,0x20,0x00,0x00]
# CHECK-ENCODING: [0x2b,0x45,0x00,0x00]
8 changes: 4 additions & 4 deletions llvm/test/MC/RISCV/corev/hwlp/counti-invalid.s
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ cv.counti 0, -7
# CHECK-ERROR: immediate must be an integer in the range [0, 4095]

cv.counti 2, 0
# CHECK-ERROR: immediate must be an integer in the range [0, 1]
# CHECK-ERROR: loop ID must be an integer in the range [0, 1]

cv.counti -1, 0
# CHECK-ERROR: immediate must be an integer in the range [0, 1]
# CHECK-ERROR: loop ID must be an integer in the range [0, 1]

cv.counti s2, 0
# CHECK-ERROR: immediate must be an integer in the range [0, 1]
# CHECK-ERROR: loop ID must be an integer in the range [0, 1]

cv.counti 0, s2
# CHECK-ERROR: immediate must be an integer in the range [0, 4095]

cv.counti 2
# CHECK-ERROR: immediate must be an integer in the range [0, 1]
# CHECK-ERROR: loop ID must be an integer in the range [0, 1]

cv.counti 1
# CHECK-ERROR: too few operands for instruction
Expand Down
10 changes: 5 additions & 5 deletions llvm/test/MC/RISCV/corev/hwlp/counti.s
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@

cv.counti 1, 4095
# CHECK-INSTR: cv.counti 1, 4095
# CHECK-ENCODING: [0xfb,0x30,0xf0,0xff]
# CHECK-ENCODING: [0xab,0x44,0xf0,0xff]

cv.counti 1, 1932
# CHECK-INSTR: cv.counti 1, 1932
# CHECK-ENCODING: [0xfb,0x30,0xc0,0x78]
# CHECK-ENCODING: [0xab,0x44,0xc0,0x78]

cv.counti 1, 0
# CHECK-INSTR: cv.counti 1, 0
# CHECK-ENCODING: [0xfb,0x30,0x00,0x00]
# CHECK-ENCODING: [0xab,0x44,0x00,0x00]

cv.counti 0, 1000
# CHECK-INSTR: cv.counti 0, 1000
# CHECK-ENCODING: [0x7b,0x30,0x80,0x3e]
# CHECK-ENCODING: [0x2b,0x44,0x80,0x3e]

cv.counti 0, 0x401
# CHECK-INSTR: cv.counti 0, 1025
# CHECK-ENCODING: [0x7b,0x30,0x10,0x40]
# CHECK-ENCODING: [0x2b,0x44,0x10,0x40]
17 changes: 17 additions & 0 deletions llvm/test/MC/RISCV/corev/hwlp/end-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# RUN: not llvm-mc -triple=riscv32 --mattr=+xcorevhwlp %s 2>&1 \
# RUN: | FileCheck %s --check-prefixes=CHECK-ERROR

cv.end 2, 0
# CHECK-ERROR: loop ID must be an integer in the range [0, 1]

cv.end -1, 0
# CHECK-ERROR: loop ID must be an integer in the range [0, 1]

cv.end 1, 10
# CHECK-ERROR: invalid operand for instruction

cv.end 1
# CHECK-ERROR: too few operands for instruction

cv.end 1, s2, 0
# CHECK-ERROR: invalid operand for instruction
14 changes: 14 additions & 0 deletions llvm/test/MC/RISCV/corev/hwlp/end.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# RUN: llvm-mc -triple=riscv32 --mattr=+xcorevhwlp -show-encoding %s \
# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INSTR

cv.end 0, t0
# CHECK-INSTR: cv.end 0, t0
# CHECK-ENCODING: [0x2b,0xc3,0x02,0x00]

cv.end 1, s4
# CHECK-INSTR: cv.end 1, s4
# CHECK-ENCODING: [0xab,0x43,0x0a,0x00]

cv.end 0, zero
# CHECK-INSTR: cv.end 0, zero
# CHECK-ENCODING: [0x2b,0x43,0x00,0x00]
8 changes: 4 additions & 4 deletions llvm/test/MC/RISCV/corev/hwlp/endi-invalid.s
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ cv.endi 0, -7
# CHECK-ERROR: immediate must be an even integer in the range [0, 4094]

cv.endi 2, 0
# CHECK-ERROR: immediate must be an integer in the range [0, 1]
# CHECK-ERROR: loop ID must be an integer in the range [0, 1]

cv.endi -1, 0
# CHECK-ERROR: immediate must be an integer in the range [0, 1]
# CHECK-ERROR: loop ID must be an integer in the range [0, 1]

cv.endi s2, 0
# CHECK-ERROR: immediate must be an integer in the range [0, 1]
# CHECK-ERROR: loop ID must be an integer in the range [0, 1]

cv.endi 0, s2
# CHECK-ERROR: immediate must be an even integer in the range [0, 4094]

cv.endi 2
# CHECK-ERROR: immediate must be an integer in the range [0, 1]
# CHECK-ERROR: loop ID must be an integer in the range [0, 1]

cv.endi 1
# CHECK-ERROR: too few operands for instruction
Expand Down
Loading

0 comments on commit 4eec1f1

Please sign in to comment.