Skip to content

Support functions #24

@PhilippvK

Description

@PhilippvK

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));
      }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions