-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Currently we do not support instruction’s behavior which contains functions calls (except raise). As functions are often helpful for reducing code duplications and creating more readable code, I want to provide 2 solutions to eliminate this limitation:
- A) via inlining
It should be straightforward to inline simple function behavior into the instruction behavior using a Seal5 transform (and constant folding). This way we can use functions for writing cleaner code while the pattern extraction does not need to know about the functions at all.
- B) via attributes hinting to relevant llvmir func
If the function behavior is “equivalent” to a LLVM-IR builtins function, we may want to use attributes to indicate this. Ideally the CoreDSL2LLVM parser would insert a call to these LLVM function instead of using the CoreDSL data flow. The main challenge here is probably how to define the mapping of argument between the functions.
Example with Rotate-Left operation used by SHA256 instructions:
CoreDSL2 does not support bit rotation operations, hence we need to build them using shifts and bitwise or symbols.
Without functions the function behavior will look messed up (it’s hard to identify that we are dealing with rotations here)
SHA256SUM0 {
// opcode: custom-0
encoding: 7'b0000110 :: 5'b00000 :: rs1[4:0] :: 3'b000 :: rd[4:0] :: 7'b0001011;
assembly: {"oa.sha256sum0", "{name(rd)}, {name(rs1)}"};
behavior: {
if (rd != 0) {
X[rd] = ((X[rs1] >> 2) | (X[rs1] << 30)) ^ ((X[rs1] >> 13) | (X[rs1] << 19)) ^ ((X[rs1] >> 22) | (X[rs1] << 10));
}
}
}
We can greatly improve the readability by introducing a function:
functions {
unsigned<32> rotr32(unsigned<32> x, unsigned<32> n) {
return (x >> n) | (x << (32 - n));
}
...
SHA256SUM0 {
// opcode: custom-0
encoding: 7'b0000110 :: 5'b00000 :: rs1[4:0] :: 3'b000 :: rd[4:0] :: 7'b0001011;
assembly: {"oa.sha256sum0", "{name(rd)}, {name(rs1)}"};
behavior: {
if (rd != 0) {
X[rd] = rotr32(X[rs1], 2) ^ rotr32(X[rs1], 13) ^ rotr32(X[rs1], 22);
}
}
}
In this case we can make use of the following relation:
rotr32(x, n) -> @llvm.fshr.i32(i32 %x, i32 %x, i32 %n)
An annotation via Attributes might look as follows:
unsigned<32> rotr32(unsigned<32> x, unsigned<32> n) [[llvm_op=llvm.fshr.i32]] {
return (x >> n) | (x << (32 - n));
}