riscv-opcodes/go_utils.py
Mark Ryan 3c73392134
Add CSR encodings for Go and remove call to Go fmt (#329)
* Don't run go fmt error in go_utils.py

go_utils.py currently runs go fmt to pretty print the generated
inst.go file. Unfortunately, this call to go fmt always fails as
inst.go contains an internal import and go fmt is being run out of
tree. Here we remove the code that attempts to format inst.go
resulting in a clean run of go_utils.py without any errors. The
generated file, inst.go, can be formatted when it's copied into the
Go source tree, prior to its submission to the Golang project.

* Add CSR support to go_utils.py

go_utils.py now generates a Go map that maps CSR numbers to CSR
names. The resulting map is written into inst.go for use by the
Go assembler.
2025-01-09 14:50:24 -08:00

65 lines
1.5 KiB
Python

import logging
import pprint
import sys
from constants import csrs
from shared_utils import InstrDict, signed
pp = pprint.PrettyPrinter(indent=2)
logging.basicConfig(level=logging.INFO, format="%(levelname)s:: %(message)s")
def make_go(instr_dict: InstrDict):
args = " ".join(sys.argv)
prelude = f"""// Code generated by {args}; DO NOT EDIT."""
prelude += """
package riscv
import "cmd/internal/obj"
type inst struct {
opcode uint32
funct3 uint32
rs1 uint32
rs2 uint32
csr int64
funct7 uint32
}
func encode(a obj.As) *inst {
switch a {
"""
csrs_map_str = """ }
return nil
}
var csrs = map[uint16]string {
"""
endoffile = """}
"""
instr_str = ""
for i in instr_dict:
enc_match = int(instr_dict[i]["match"], 0)
opcode = (enc_match >> 0) & ((1 << 7) - 1)
funct3 = (enc_match >> 12) & ((1 << 3) - 1)
rs1 = (enc_match >> 15) & ((1 << 5) - 1)
rs2 = (enc_match >> 20) & ((1 << 5) - 1)
csr = (enc_match >> 20) & ((1 << 12) - 1)
funct7 = (enc_match >> 25) & ((1 << 7) - 1)
instr_str += f""" case A{i.upper().replace("_","")}:
return &inst{{ {hex(opcode)}, {hex(funct3)}, {hex(rs1)}, {hex(rs2)}, {signed(csr,12)}, {hex(funct7)} }}
"""
for num, name in sorted(csrs, key=lambda row: row[0]):
csrs_map_str += f'{hex(num)} : "{name.upper()}",\n'
with open("inst.go", "w", encoding="utf-8") as file:
file.write(prelude)
file.write(instr_str)
file.write(csrs_map_str)
file.write(endoffile)