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 ..= patterns in instruction fixed_ranges = re.compile( "\s*(?P\d+.?)\.\.(?P\d+.?)\s*=\s*(?P\d[\w]*)[\s$]*", re.M ) # regex to find = patterns in instructions # single_fixed = re.compile('\s+(?P\d+)=(?P[\w\d]*)[\s$]*', re.M) single_fixed = re.compile("(?:^|[\s])(?P\d+)=(?P[\w]*)((?=\s|$))", re.M) # regex to find the overloading condition variable var_regex = re.compile("(?P[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+(?Prv[\d]*_[\w].*)::\s*(?P.*?)\s+(?P.*?)\s+(?P.*)$", re.M, ) imported_regex = re.compile( "^\s*\$import\s*(?P.*)\s*::\s*(?P.*)", 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", ]