Skip to content

Instantly share code, notes, and snippets.

@Keksgesicht
Created August 27, 2025 22:31
Show Gist options
  • Save Keksgesicht/75b03b1bd70b10a69f0105fda4b10d11 to your computer and use it in GitHub Desktop.
Save Keksgesicht/75b03b1bd70b10a69f0105fda4b10d11 to your computer and use it in GitHub Desktop.
LLVM patching approach
// RUN: %llvmbuildpath/bin/clang --sysroot=%libcpath --target="riscv32-none-elf" -menable-experimental-extensions -mabi="ilp32" -march="rv32imxsimple0p1" -O3 -S -o - %s | FileCheck %s
// CHECK: main:
// CHECK-DAG: SIMPLE.mac [[RD1:[as][0-9]+]], [[RS1:[as][0-9]+]], [[RS2:[as][0-9]+]]
// CHECK: call printf
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
time_t t;
srand((unsigned) time(&t));
int a[] = {rand(), rand(), rand(), rand()};
int b[] = {rand(), rand(), rand(), rand()};
int c = rand();
c = a[0] * b[0] + c;
c = a[1] * b[1] + c;
c = a[2] * b[2] + c;
c = a[3] * b[3] + c;
printf("%d", c);
return 0;
}
// RUN: %llvmbuildpath/bin/clang --sysroot=%libcpath --target="riscv32-none-elf" -menable-experimental-extensions -mabi="ilp32" -march="rv32imxsimple0p1" -O3 -S -o - %s | FileCheck %s
// CHECK: main:
// CHECK-DAG: SIMPLE.mac [[RD1:a[0-9]+]], [[RS1:a[0-9]+]], [[RS2:a[0-9]+]]
// CHECK-DAG: SIMPLE.mac [[RD2:a[0-9]+]], [[RS3:a[0-9]+]], [[RD1]]
// CHECK-DAG: SIMPLE.mac [[RD3:a[0-9]+]], [[RS4:a[0-9]+]], [[RD2]]
// CHECK-DAG: SIMPLE.mac [[RD4:a[0-9]+]], [[RS5:a[0-9]+]], [[RD3]]
// CHECK: call printf
#include <stdio.h>
int main() {
int a[] = {27, 23, 13, 5};
int b[] = {42, 47, 64, 69};
int c = 5;
#ifdef __riscv_simple
c = __builtin_riscv_simple_mac(a[0], b[0], c);
c = __builtin_riscv_simple_mac(a[1], b[1], c);
c = __builtin_riscv_simple_mac(a[2], b[2], c);
c = __builtin_riscv_simple_mac(a[3], b[3], c);
printf("%d", c);
#endif
return 0;
}
InstructionSet Simple {
architectural_state {
register unsigned<32> X[32] [[is_main_reg]];
}
instructions {
mac {
encoding: 7'd0 :: rs2[4:0] :: rs1[4:0] :: 3'b000 :: rd[4:0] :: 7'b0101011;
behavior: {
signed<32> ACC = (signed<32>)(X[rs1] * X[rs2] + X[rd]);
X[rd] = (unsigned<32>) ACC;
}
}
}
}
diff --git a/clang/include/clang/Basic/BuiltinsRISCV.td b/clang/include/clang/Basic/BuiltinsRISCV.td
index 3263603a8..afb7b407e 100644
--- a/clang/include/clang/Basic/BuiltinsRISCV.td
+++ b/clang/include/clang/Basic/BuiltinsRISCV.td
@@ -151,3 +151,11 @@ def ntl_store : RISCVBuiltin<"void(...)">;
// XCV extensions.
//===----------------------------------------------------------------------===//
include "clang/Basic/BuiltinsRISCVXCV.td"
+
+//===------------------------------------------------===//
+// SIMPLE extension.
+//===------------------------------------------------===//
+let Attributes = [NoThrow, Const], Features = "experimental-xsimple" in {
+def simple_mac : RISCVBuiltin<"int(int, int, int)">;
+} // Features = "simple"
+
diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp
index 61b8ae9d0..82e8a4293 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -187,6 +187,9 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
if (ISAInfo->hasExtension("zmmul"))
Builder.defineMacro("__riscv_mul");
+ if (ISAInfo->hasExtension("xsimple"))
+ Builder.defineMacro("__riscv_simple");
+
if (ISAInfo->hasExtension("m")) {
Builder.defineMacro("__riscv_div");
Builder.defineMacro("__riscv_muldiv");
diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td
index 99cb557d9..8a5461c26 100644
--- a/llvm/include/llvm/IR/IntrinsicsRISCV.td
+++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td
@@ -1883,3 +1883,19 @@ let TargetPrefix = "riscv" in {
include "llvm/IR/IntrinsicsRISCVXTHead.td"
include "llvm/IR/IntrinsicsRISCVXsf.td"
include "llvm/IR/IntrinsicsRISCVXCV.td"
+
+let TargetPrefix = "riscv" in {
+
+ multiclass SIMPLEIntrinsic<list<LLVMType> ret_types,
+ list<LLVMType> param_types,
+ list<IntrinsicProperty> intr_properties> {
+ def "int_riscv_simple_" # NAME
+ : ClangBuiltin<"__builtin_riscv_simple_" # NAME>,
+ Intrinsic<ret_types,param_types,intr_properties>;
+ }
+
+ defm mac : SIMPLEIntrinsic<[llvm_i32_ty],
+ [llvm_i32_ty,llvm_i32_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+
+} // TargetPrefix = "riscv"
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index f050977c5..11045603b 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1471,3 +1471,13 @@ def FeatureTaggedGlobals : SubtargetFeature<"tagged-globals",
"AllowTaggedGlobals",
"true", "Use an instruction sequence for taking the address of a global "
"that allows a memory tag in the upper address bits">;
+
+//===--------------------------------------------------===//
+// Custom ISA extensions created written in CoreDSL
+//===--------------------------------------------------===//
+def FeatureVendorXSIMPLE
+ : RISCVExperimentalExtension<0, 1, "SIMPLE (non-standard extension)", []>;
+def HasVendorXSIMPLE : Predicate<"Subtarget->hasVendorXSIMPLE()">,
+ AssemblerPredicate<(all_of FeatureVendorXSIMPLE),
+ "SIMPLE Instruction Set">;
+
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index fec10864f..f8aa58c31 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2144,3 +2144,38 @@ include "RISCVInstrInfoXMips.td"
//===----------------------------------------------------------------------===//
include "RISCVInstrGISel.td"
+
+//===----------------------------------------------------===//
+// Define new ISAX instructions.
+//===----------------------------------------------------===//
+
+let Predicates = [HasVendorXSIMPLE] in {
+
+ def RV_SIMPLE_mac_Inst
+ : RVInst<(outs GPR:$rddst),
+ (ins GPR:$rd, GPR:$rs1, GPR:$rs2),
+ "SIMPLE.mac", "$rd, $rs1, $rs2",
+ [(set GPR:$rddst, (int_riscv_simple_mac GPR:$rd, GPR:$rs1, GPR:$rs2))],
+ InstFormatR>,
+ Sched<[]> {
+
+ let hasSideEffects = 0;
+ let mayLoad = 0;
+ let mayStore = 0;
+ let Constraints = "$rddst = $rd";
+
+ bits<5> rd;
+ bits<5> rs1;
+ bits<5> rs2;
+
+ let Inst{6-0} = 0b0101011;
+ let Inst{11-7} = rd;
+ let Inst{14-12} = 0b000;
+ let Inst{19-15} = rs1;
+ let Inst{24-20} = rs2;
+ let Inst{31-25} = 0b0000000;
+ }
+
+ def : Pat<(i32 (add (i32 (mul GPR:$rs1, GPR:$rs2)), GPR:$rd)),
+ (RV_SIMPLE_mac_Inst GPR:$rd, GPR:$rs1, GPR:$rs2)>;
+} // Predicates = [HasVendorXSIMPLE]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment