Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pseudoinstructions #6

Open
ThinkOpenly opened this issue Jan 12, 2024 · 3 comments
Open

Add pseudoinstructions #6

ThinkOpenly opened this issue Jan 12, 2024 · 3 comments

Comments

@ThinkOpenly
Copy link
Owner

No description provided.

@jriyyya
Copy link

jriyyya commented Jan 19, 2024

Hi @ThinkOpenly, I wanted to know how this can be done. Is this about creating like a models/riscv_insts_pseudo.sail with definitions for the pseudoinstructions which RISCV might have or is this similar to adding mere definitions in a pre existing file.
Can you please elaborate and guide me to understanding this issue .

@ThinkOpenly
Copy link
Owner Author

ThinkOpenly commented May 8, 2024

I completely missed this comment until now. Apologies.

It would be nice to have the pseudoinstructions close to where the actual instructions are defined. So, I'm thinking in the same file as the respective instruction. Implementation is an open question. Off the top of my head, I can see another scattered mapping, much like the scattered mapping assembly and associated mapping clause assembly instances for each instruction (or instruction group). A simple string <-> string mapping would suffice for most pseudoinstructions, maybe with some convention to be able to match operands. Something like:

mapping clause pseudo = "mv %rd,%rs" <-> "addi %rd,%rs,0"

[Edit]: Thinking a bit more, these strings should probably make use of the conventions of the assembly clauses and include the use of spc() and sep():

mapping clause pseudo = "mv" @ spc() @ "%rd" @ sep() @ "%rs"
    <-> "addi" @ spc() @ "%rd" @ sep() @ "%rs" @ sep() @ "0"

Unfortunately, there are a lot of odd cases where the mapping from instruction to pseudoinstruction is not straightforward (from RISC-V Unprivileged ISA V20191213, table 25.2):

pseudoinstruction Base Instruction(s) Meaning
la rd, symbol (non-PIC ) auipc rd, delta[31 : 12] + delta[11]
addi rd, rd, delta[11:0]
Load absolute address,
where delta = symbol − pc
la rd, symbol (PIC ) auipc rd, delta[31 : 12] + delta[11]
l{w|d} rd, rd, delta[11:0]
Load absolute address,
where delta = GOT[symbol] − pc

The lack of a 1:1 mapping from instruction to pseudoinstruction makes for another question: to which instruction should the pseudoinstruction be associated? Maybe the association isn't terribly important, and the pseudoinstructions should just go where they best match functionally.

@ThinkOpenly
Copy link
Owner Author

A simple string <-> string mapping would suffice for most pseudoinstructions

Sail doesn't support string <-> string mappings.

64 |mapping s2s : string <-> string = { "a" <-> "b" }
   |              ^---------------^
   | Well-formedness check failed for type
   | 
   | 64 |mapping s2s : string <-> string = { "a" <-> "b" }
   |    |              ^---------------^
   |    | Bidirectional types cannot be the same on both sides

I may have found a decent approach. Using an example from the (relatively new) RISC-V Instruction Set Manual Volume I:

zext.w rd, rs1 → add.uw rd, rs1, zero

The basic "4 stanzas" are necessary and reasonably straightforward, and they redirect to the base instruction's implementation where appropriate:

union clause ast = ZEXTW : (regidx, regidx)
mapping clause encdec = ZEXTW(rs1, rd) if extension("Zba") & sizeof(xlen) == 64
  <-> encdec(ZBA_RTYPEUW(reg_name("zero"), rs1, rd, RISCV_ADDUW)) if extension("Zba") & sizeof(xlen) == 64
mapping clause assembly = ZEXTW(rs1, rd)
  <-> "zext.w" ^ spc() ^ reg_name(rd) ^ sep() ^ reg_name(rs1)
function clause execute (ZEXTW(rs1, rd)) = execute(ZBA_RTYPEUW(reg_name("zero"), rs1, rd, RISCV_ADDUW))

I also thought adding another scattered mapping would make it much easier to associate the pseudoinstruction with its base instruction, and make it very obvious that this was a pseudoinstruction:

val pseudo_of : ast <-> string
scattered mapping pseudo_of
mapping clause pseudo_of = ZEXTW(rs1, rd) <-> "add.uw" ^ spc() ^ reg_name(rd) ^ sep() ^ reg_name(rs1) ^ sep() ^ "zero"
end pseudo_of

Without this, we'd need to deconstruct whatever is in the execute expression, or maybe find the associated assembly clause, assuming one exists, while making a fair number of assumptions about the syntax of the execute expression.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants