#!/usr/bin/env python3 ## ## Copyright (c) 2024 Taylor Simpson ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, see . ## import io import re import sys import textwrap import iset import hex_common encs = { tag: "".join(reversed(iset.iset[tag]["enc"].replace(" ", ""))) for tag in iset.tags if iset.iset[tag]["enc"] != "MISSING ENCODING" } regre = re.compile(r"((? 1: raise Exception(f"{tag} has split register field!") reg_enc_field = reg_enc_fields[0] if 2 ** len(reg_enc_field) != reg_num_choices: raise Exception(f"{tag} has incorrect register field width!") f.write(f"%{tag}_{reg_type}{reg_id}\t" f"{enc.index(reg_enc_field)}:{len(reg_enc_field)}") if (reg_type in num_registers and reg_num_choices != num_registers[reg_type]): f.write(f"\t!function=decode_mapped_reg_{reg_mapping}") f.write("\n") # Write the field definitions for the immediates for imm in imms: immno = 1 if imm[0].isupper() else 0 imm_type = imm[0] imm_width = int(imm[1]) imm_letter = "i" if imm_type.islower() else "I" fields = [] sign_mark = "s" if imm_type.lower() in "sr" else "" for m in reversed(list(re.finditer(imm_letter + "+", enc))): fields.append(f"{m.start()}:{sign_mark}{m.end() - m.start()}") sign_mark = "" field_str = " ".join(fields) f.write(f"%{tag}_{imm_type}{imm_letter}\t{field_str}\n") ## Handle instructions with unused encoding letters ## Change the unused letters to ignored if tag in tags_with_unused_d_encoding: enc_str = enc_str.replace("d", "-") if tag in tags_with_unused_t_encoding: enc_str = enc_str.replace("t", "-") # Replace the operand letters with . for x in operand_letters: enc_str = enc_str.replace(x, ".") # Write the instruction format f.write(f"@{tag}\t{enc_str}") for reg in regs: reg_type = reg[0] reg_id = reg[1] f.write(f" {reg_type}{reg_id}=%{tag}_{reg_type}{reg_id}") for imm in imms: imm_type = imm[0] imm_letter = "i" if imm_type.islower() else "I" f.write(f" {imm_type}{imm_letter}=%{tag}_{imm_type}{imm_letter}") if not is_subinsn: f.write(" %PP") f.write("\n") # Replace the 0s and 1s with . enc_str = enc_str.replace("0", ".").replace("1", ".") # Write the instruction pattern f.write(f"{tag}\t{enc_str} @{tag}\n") if __name__ == "__main__": hex_common.read_semantics_file(sys.argv[1]) class_to_decode = sys.argv[2] with open(sys.argv[3], "w") as f: gen_decodetree_file(f, class_to_decode)