import csv
import re
import os
overlapping_extensions = {
"rv_zcmt": {"rv_c_d"},
"rv_zcmp": {"rv_c_d"},
"rv_c": {"rv_zcmop"},
}
overlapping_instructions = {
"c_addi": {"c_nop"},
"c_lui": {"c_addi16sp"},
"c_mv": {"c_jr"},
"c_jalr": {"c_ebreak"},
"c_add": {"c_ebreak", "c_jalr"},
}
isa_regex = re.compile(
"^RV(32|64|128)[IE]+[ABCDEFGHJKLMNPQSTUVX]*(Zicsr|Zifencei|Zihintpause|Zam|Ztso|Zkne|Zknd|Zknh|Zkse|Zksh|Zkg|Zkb|Zkr|Zks|Zkn|Zba|Zbc|Zbb|Zbp|Zbr|Zbm|Zbs|Zbe|Zbf|Zbt|Zmmul|Zbpbo|Zca|Zcf|Zcd|Zcb|Zcmp|Zcmt){,1}(_Zicsr){,1}(_Zifencei){,1}(_Zihintpause){,1}(_Zmmul){,1}(_Zam){,1}(_Zba){,1}(_Zbb){,1}(_Zbc){,1}(_Zbe){,1}(_Zbf){,1}(_Zbm){,1}(_Zbp){,1}(_Zbpbo){,1}(_Zbr){,1}(_Zbs){,1}(_Zbt){,1}(_Zkb){,1}(_Zkg){,1}(_Zkr){,1}(_Zks){,1}(_Zkn){,1}(_Zknd){,1}(_Zkne){,1}(_Zknh){,1}(_Zkse){,1}(_Zksh){,1}(_Ztso){,1}(_Zca){,1}(_Zcf){,1}(_Zcd){,1}(_Zcb){,1}(_Zcmp){,1}(_Zcmt){,1}$"
)
# regex to find <msb>..<lsb>=<val> patterns in instruction
fixed_ranges = re.compile(
"\s*(?P<msb>\d+.?)\.\.(?P<lsb>\d+.?)\s*=\s*(?P<val>\d[\w]*)[\s$]*", re.M
)
# regex to find <lsb>=<val> patterns in instructions
# single_fixed = re.compile('\s+(?P<lsb>\d+)=(?P<value>[\w\d]*)[\s$]*', re.M)
single_fixed = re.compile("(?:^|[\s])(?P<lsb>\d+)=(?P<value>[\w]*)((?=\s|$))", re.M)
# regex to find the overloading condition variable
var_regex = re.compile("(?P<var>[a-zA-Z][\w\d]*)\s*=\s*.*?[\s$]*", re.M)
# regex for pseudo op instructions returns the dependent filename, dependent
# instruction, the pseudo op name and the encoding string
pseudo_regex = re.compile(
"^\$pseudo_op\s+(?P<filename>rv[\d]*_[\w].*)::\s*(?P<orig_inst>.*?)\s+(?P<pseudo_inst>.*?)\s+(?P<overload>.*)$",
re.M,
)
imported_regex = re.compile(
"^\s*\$import\s*(?P<extension>.*)\s*::\s*(?P<instruction>.*)", re.M
)
def read_csv(filename):
"""
Reads a CSV file and returns a list of tuples.
Each tuple contains an integer value (from the first column) and a string (from the second column).
Args:
filename (str): The name of the CSV file to read.
Returns:
list of tuple: A list of (int, str) tuples extracted from the CSV file.
"""
with open(filename) as f:
csv_reader = csv.reader(f, skipinitialspace=True)
return [(int(row[0], 0), row[1]) for row in csv_reader]
RISCV_OPCODES = os.environ["RISCV_OPCODES"]
causes = read_csv(RISCV_OPCODES + "/causes.csv")
csrs = read_csv(RISCV_OPCODES + "/csrs.csv")
csrs32 = read_csv(RISCV_OPCODES + "/csrs32.csv")
# Load the argument lookup table (arg_lut) from a CSV file, mapping argument names to their bit positions
arg_lut = {
row[0]: (int(row[1]), int(row[2]))
for row in csv.reader(open(RISCV_OPCODES + "/arg_lut.csv"), skipinitialspace=True)
}
# for mop
arg_lut["mop_r_t_30"] = (30, 30)
arg_lut["mop_r_t_27_26"] = (27, 26)
arg_lut["mop_r_t_21_20"] = (21, 20)
arg_lut["mop_rr_t_30"] = (30, 30)
arg_lut["mop_rr_t_27_26"] = (27, 26)
arg_lut["c_mop_t"] = (10, 8)
# dictionary containing the mapping of the argument to the what the fields in
# the latex table should be
latex_mapping = {}
latex_mapping["imm12"] = "imm[11:0]"
latex_mapping["rs1"] = "rs1"
latex_mapping["rs2"] = "rs2"
latex_mapping["rd"] = "rd"
latex_mapping["imm20"] = "imm[31:12]"
latex_mapping["bimm12hi"] = "imm[12$\\vert$10:5]"
latex_mapping["bimm12lo"] = "imm[4:1$\\vert$11]"
latex_mapping["imm12hi"] = "imm[11:5]"
latex_mapping["imm12lo"] = "imm[4:0]"
latex_mapping["jimm20"] = "imm[20$\\vert$10:1$\\vert$11$\\vert$19:12]"
latex_mapping["zimm"] = "uimm"
latex_mapping["shamtw"] = "shamt"
latex_mapping["shamtd"] = "shamt"
latex_mapping["shamtq"] = "shamt"
latex_mapping["rd_p"] = "rd\\,$'$"
latex_mapping["rs1_p"] = "rs1\\,$'$"
latex_mapping["rs2_p"] = "rs2\\,$'$"
latex_mapping["rd_rs1_n0"] = "rd/rs$\\neq$0"
latex_mapping["rd_rs1_p"] = "rs1\\,$'$/rs2\\,$'$"
latex_mapping["c_rs2"] = "rs2"
latex_mapping["c_rs2_n0"] = "rs2$\\neq$0"
latex_mapping["rd_n0"] = "rd$\\neq$0"
latex_mapping["rs1_n0"] = "rs1$\\neq$0"
latex_mapping["c_rs1_n0"] = "rs1$\\neq$0"
latex_mapping["rd_rs1"] = "rd/rs1"
latex_mapping["zimm6hi"] = "uimm[5]"
latex_mapping["zimm6lo"] = "uimm[4:0]"
latex_mapping["c_nzuimm10"] = "nzuimm[5:4$\\vert$9:6$\\vert$2$\\vert$3]"
latex_mapping["c_uimm7lo"] = "uimm[2$\\vert$6]"
latex_mapping["c_uimm7hi"] = "uimm[5:3]"
latex_mapping["c_uimm8lo"] = "uimm[7:6]"
latex_mapping["c_uimm8hi"] = "uimm[5:3]"
latex_mapping["c_uimm9lo"] = "uimm[7:6]"
latex_mapping["c_uimm9hi"] = "uimm[5:4$\\vert$8]"
latex_mapping["c_nzimm6lo"] = "nzimm[4:0]"
latex_mapping["c_nzimm6hi"] = "nzimm[5]"
latex_mapping["c_imm6lo"] = "imm[4:0]"
latex_mapping["c_imm6hi"] = "imm[5]"
latex_mapping["c_nzimm10hi"] = "nzimm[9]"
latex_mapping["c_nzimm10lo"] = "nzimm[4$\\vert$6$\\vert$8:7$\\vert$5]"
latex_mapping["c_nzimm18hi"] = "nzimm[17]"
latex_mapping["c_nzimm18lo"] = "nzimm[16:12]"
latex_mapping["c_imm12"] = (
"imm[11$\\vert$4$\\vert$9:8$\\vert$10$\\vert$6$\\vert$7$\\vert$3:1$\\vert$5]"
)
latex_mapping["c_bimm9lo"] = "imm[7:6$\\vert$2:1$\\vert$5]"
latex_mapping["c_bimm9hi"] = "imm[8$\\vert$4:3]"
latex_mapping["c_nzuimm5"] = "nzuimm[4:0]"
latex_mapping["c_nzuimm6lo"] = "nzuimm[4:0]"
latex_mapping["c_nzuimm6hi"] = "nzuimm[5]"
latex_mapping["c_uimm8splo"] = "uimm[4:2$\\vert$7:6]"
latex_mapping["c_uimm8sphi"] = "uimm[5]"
latex_mapping["c_uimm8sp_s"] = "uimm[5:2$\\vert$7:6]"
latex_mapping["c_uimm10splo"] = "uimm[4$\\vert$9:6]"
latex_mapping["c_uimm10sphi"] = "uimm[5]"
latex_mapping["c_uimm9splo"] = "uimm[4:3$\\vert$8:6]"
latex_mapping["c_uimm9sphi"] = "uimm[5]"
latex_mapping["c_uimm10sp_s"] = "uimm[5:4$\\vert$9:6]"
latex_mapping["c_uimm9sp_s"] = "uimm[5:3$\\vert$8:6]"
# created a dummy instruction-dictionary like dictionary for all the instruction
# types so that the same logic can be used to create their tables
latex_inst_type = {}
latex_inst_type["R-type"] = {}
latex_inst_type["R-type"]["variable_fields"] = [
"opcode",
"rd",
"funct3",
"rs1",
"rs2",
"funct7",
]
latex_inst_type["R4-type"] = {}
latex_inst_type["R4-type"]["variable_fields"] = [
"opcode",
"rd",
"funct3",
"rs1",
"rs2",
"funct2",
"rs3",
]
latex_inst_type["I-type"] = {}
latex_inst_type["I-type"]["variable_fields"] = [
"opcode",
"rd",
"funct3",
"rs1",
"imm12",
]
latex_inst_type["S-type"] = {}
latex_inst_type["S-type"]["variable_fields"] = [
"opcode",
"imm12lo",
"funct3",
"rs1",
"rs2",
"imm12hi",
]
latex_inst_type["B-type"] = {}
latex_inst_type["B-type"]["variable_fields"] = [
"opcode",
"bimm12lo",
"funct3",
"rs1",
"rs2",
"bimm12hi",
]
latex_inst_type["U-type"] = {}
latex_inst_type["U-type"]["variable_fields"] = ["opcode", "rd", "imm20"]
latex_inst_type["J-type"] = {}
latex_inst_type["J-type"]["variable_fields"] = ["opcode", "rd", "jimm20"]
latex_fixed_fields = []
latex_fixed_fields.append((31, 25))
latex_fixed_fields.append((24, 20))
latex_fixed_fields.append((19, 15))
latex_fixed_fields.append((14, 12))
latex_fixed_fields.append((11, 7))
latex_fixed_fields.append((6, 0))
# Pseudo-ops present in the generated encodings.
# By default pseudo-ops are not listed as they are considered aliases
# of their base instruction.
emitted_pseudo_ops = [
"pause",
"prefetch_i",
"prefetch_r",
"prefetch_w",
"rstsa16",
"rstsa32",
"srli32_u",
"slli_rv32",
"srai_rv32",
"srli_rv32",
"umax32",
"c_mop_1",
"c_sspush_x1",
"c_mop_3",
"c_mop_5",
"c_sspopchk_x5",
"c_mop_7",
"c_mop_9",
"c_mop_11",
"c_mop_13",
"c_mop_15",
"mop_r_0",
"mop_r_1",
"mop_r_2",
"mop_r_3",
"mop_r_4",
"mop_r_5",
"mop_r_6",
"mop_r_7",
"mop_r_8",
"mop_r_9",
"mop_r_10",
"mop_r_11",
"mop_r_12",
"mop_r_13",
"mop_r_14",
"mop_r_15",
"mop_r_16",
"mop_r_17",
"mop_r_18",
"mop_r_19",
"mop_r_20",
"mop_r_21",
"mop_r_22",
"mop_r_23",
"mop_r_24",
"mop_r_25",
"mop_r_26",
"mop_r_27",
"mop_r_28",
"sspopchk_x1",
"sspopchk_x5",
"ssrdp",
"mop_r_29",
"mop_r_30",
"mop_r_31",
"mop_r_32",
"mop_rr_0",
"mop_rr_1",
"mop_rr_2",
"mop_rr_3",
"mop_rr_4",
"mop_rr_5",
"mop_rr_6",
"mop_rr_7",
"sspush_x1",
"sspush_x5",
"lpad",
"bclri.rv32",
"bexti.rv32",
"binvi.rv32",
"bseti.rv32",
"zext.h.rv32",
"rev8.h.rv32",
"rori.rv32",
]