1#!/usr/bin/env python3 2 3## 4## Copyright(c) 2022-2023 Qualcomm Innovation Center, Inc. All Rights Reserved. 5## 6## This program is free software; you can redistribute it and/or modify 7## it under the terms of the GNU General Public License as published by 8## the Free Software Foundation; either version 2 of the License, or 9## (at your option) any later version. 10## 11## This program is distributed in the hope that it will be useful, 12## but WITHOUT ANY WARRANTY; without even the implied warranty of 13## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14## GNU General Public License for more details. 15## 16## You should have received a copy of the GNU General Public License 17## along with this program; if not, see <http://www.gnu.org/licenses/>. 18## 19 20import sys 21import re 22import string 23import hex_common 24 25## 26## Helpers for gen_analyze_func 27## 28def is_predicated(tag): 29 return 'A_CONDEXEC' in hex_common.attribdict[tag] 30 31def analyze_opn_old(f, tag, regtype, regid, regno): 32 regN = "%s%sN" % (regtype, regid) 33 predicated = "true" if is_predicated(tag) else "false" 34 if (regtype == "R"): 35 if (regid in {"ss", "tt"}): 36 f.write("// const int %s = insn->regno[%d];\n" % \ 37 (regN, regno)) 38 elif (regid in {"dd", "ee", "xx", "yy"}): 39 f.write(" const int %s = insn->regno[%d];\n" % (regN, regno)) 40 f.write(" ctx_log_reg_write_pair(ctx, %s, %s);\n" % \ 41 (regN, predicated)) 42 elif (regid in {"s", "t", "u", "v"}): 43 f.write("// const int %s = insn->regno[%d];\n" % \ 44 (regN, regno)) 45 elif (regid in {"d", "e", "x", "y"}): 46 f.write(" const int %s = insn->regno[%d];\n" % (regN, regno)) 47 f.write(" ctx_log_reg_write(ctx, %s, %s);\n" % \ 48 (regN, predicated)) 49 else: 50 print("Bad register parse: ", regtype, regid) 51 elif (regtype == "P"): 52 if (regid in {"s", "t", "u", "v"}): 53 f.write("// const int %s = insn->regno[%d];\n" % \ 54 (regN, regno)) 55 elif (regid in {"d", "e", "x"}): 56 f.write(" const int %s = insn->regno[%d];\n" % (regN, regno)) 57 f.write(" ctx_log_pred_write(ctx, %s);\n" % (regN)) 58 else: 59 print("Bad register parse: ", regtype, regid) 60 elif (regtype == "C"): 61 if (regid == "ss"): 62 f.write("// const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \ 63 (regN, regno)) 64 elif (regid == "dd"): 65 f.write(" const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \ 66 (regN, regno)) 67 f.write(" ctx_log_reg_write_pair(ctx, %s, %s);\n" % \ 68 (regN, predicated)) 69 elif (regid == "s"): 70 f.write("// const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \ 71 (regN, regno)) 72 elif (regid == "d"): 73 f.write(" const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \ 74 (regN, regno)) 75 f.write(" ctx_log_reg_write(ctx, %s, %s);\n" % \ 76 (regN, predicated)) 77 else: 78 print("Bad register parse: ", regtype, regid) 79 elif (regtype == "M"): 80 if (regid == "u"): 81 f.write("// const int %s = insn->regno[%d];\n"% \ 82 (regN, regno)) 83 else: 84 print("Bad register parse: ", regtype, regid) 85 elif (regtype == "V"): 86 newv = "EXT_DFL" 87 if (hex_common.is_new_result(tag)): 88 newv = "EXT_NEW" 89 elif (hex_common.is_tmp_result(tag)): 90 newv = "EXT_TMP" 91 if (regid in {"dd", "xx"}): 92 f.write(" const int %s = insn->regno[%d];\n" %\ 93 (regN, regno)) 94 f.write(" ctx_log_vreg_write_pair(ctx, %s, %s, %s);\n" % \ 95 (regN, newv, predicated)) 96 elif (regid in {"uu", "vv"}): 97 f.write("// const int %s = insn->regno[%d];\n" % \ 98 (regN, regno)) 99 elif (regid in {"s", "u", "v", "w"}): 100 f.write("// const int %s = insn->regno[%d];\n" % \ 101 (regN, regno)) 102 elif (regid in {"d", "x", "y"}): 103 f.write(" const int %s = insn->regno[%d];\n" % \ 104 (regN, regno)) 105 f.write(" ctx_log_vreg_write(ctx, %s, %s, %s);\n" % \ 106 (regN, newv, predicated)) 107 else: 108 print("Bad register parse: ", regtype, regid) 109 elif (regtype == "Q"): 110 if (regid in {"d", "e", "x"}): 111 f.write(" const int %s = insn->regno[%d];\n" % \ 112 (regN, regno)) 113 f.write(" ctx_log_qreg_write(ctx, %s, %s);\n" % \ 114 (regN, predicated)) 115 elif (regid in {"s", "t", "u", "v"}): 116 f.write("// const int %s = insn->regno[%d];\n" % \ 117 (regN, regno)) 118 else: 119 print("Bad register parse: ", regtype, regid) 120 elif (regtype == "G"): 121 if (regid in {"dd"}): 122 f.write("// const int %s = insn->regno[%d];\n" % \ 123 (regN, regno)) 124 elif (regid in {"d"}): 125 f.write("// const int %s = insn->regno[%d];\n" % \ 126 (regN, regno)) 127 elif (regid in {"ss"}): 128 f.write("// const int %s = insn->regno[%d];\n" % \ 129 (regN, regno)) 130 elif (regid in {"s"}): 131 f.write("// const int %s = insn->regno[%d];\n" % \ 132 (regN, regno)) 133 else: 134 print("Bad register parse: ", regtype, regid) 135 elif (regtype == "S"): 136 if (regid in {"dd"}): 137 f.write("// const int %s = insn->regno[%d];\n" % \ 138 (regN, regno)) 139 elif (regid in {"d"}): 140 f.write("// const int %s = insn->regno[%d];\n" % \ 141 (regN, regno)) 142 elif (regid in {"ss"}): 143 f.write("// const int %s = insn->regno[%d];\n" % \ 144 (regN, regno)) 145 elif (regid in {"s"}): 146 f.write("// const int %s = insn->regno[%d];\n" % \ 147 (regN, regno)) 148 else: 149 print("Bad register parse: ", regtype, regid) 150 else: 151 print("Bad register parse: ", regtype, regid) 152 153def analyze_opn_new(f, tag, regtype, regid, regno): 154 regN = "%s%sN" % (regtype, regid) 155 if (regtype == "N"): 156 if (regid in {"s", "t"}): 157 f.write("// const int %s = insn->regno[%d];\n" % \ 158 (regN, regno)) 159 else: 160 print("Bad register parse: ", regtype, regid) 161 elif (regtype == "P"): 162 if (regid in {"t", "u", "v"}): 163 f.write("// const int %s = insn->regno[%d];\n" % \ 164 (regN, regno)) 165 else: 166 print("Bad register parse: ", regtype, regid) 167 elif (regtype == "O"): 168 if (regid == "s"): 169 f.write("// const int %s = insn->regno[%d];\n" % \ 170 (regN, regno)) 171 else: 172 print("Bad register parse: ", regtype, regid) 173 else: 174 print("Bad register parse: ", regtype, regid) 175 176def analyze_opn(f, tag, regtype, regid, toss, numregs, i): 177 if (hex_common.is_pair(regid)): 178 analyze_opn_old(f, tag, regtype, regid, i) 179 elif (hex_common.is_single(regid)): 180 if hex_common.is_old_val(regtype, regid, tag): 181 analyze_opn_old(f,tag, regtype, regid, i) 182 elif hex_common.is_new_val(regtype, regid, tag): 183 analyze_opn_new(f, tag, regtype, regid, i) 184 else: 185 print("Bad register parse: ", regtype, regid, toss, numregs) 186 else: 187 print("Bad register parse: ", regtype, regid, toss, numregs) 188 189## 190## Generate the code to analyze the instruction 191## For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;} 192## We produce: 193## static void analyze_A2_add(DisasContext *ctx) 194## { 195## Insn *insn G_GNUC_UNUSED = ctx->insn; 196## const int RdN = insn->regno[0]; 197## ctx_log_reg_write(ctx, RdN, false); 198## // const int RsN = insn->regno[1]; 199## // const int RtN = insn->regno[2]; 200## } 201## 202def gen_analyze_func(f, tag, regs, imms): 203 f.write("static void analyze_%s(DisasContext *ctx)\n" %tag) 204 f.write('{\n') 205 206 f.write(" Insn *insn G_GNUC_UNUSED = ctx->insn;\n") 207 208 i=0 209 ## Analyze all the registers 210 for regtype, regid, toss, numregs in regs: 211 analyze_opn(f, tag, regtype, regid, toss, numregs, i) 212 i += 1 213 214 has_generated_helper = (not hex_common.skip_qemu_helper(tag) and 215 not hex_common.is_idef_parser_enabled(tag)) 216 if (has_generated_helper and 217 'A_SCALAR_LOAD' in hex_common.attribdict[tag]): 218 f.write(" ctx->need_pkt_has_store_s1 = true;\n") 219 220 f.write("}\n\n") 221 222def main(): 223 hex_common.read_semantics_file(sys.argv[1]) 224 hex_common.read_attribs_file(sys.argv[2]) 225 hex_common.read_overrides_file(sys.argv[3]) 226 hex_common.read_overrides_file(sys.argv[4]) 227 ## Whether or not idef-parser is enabled is 228 ## determined by the number of arguments to 229 ## this script: 230 ## 231 ## 5 args. -> not enabled, 232 ## 6 args. -> idef-parser enabled. 233 ## 234 ## The 6:th arg. then holds a list of the successfully 235 ## parsed instructions. 236 is_idef_parser_enabled = len(sys.argv) > 6 237 if is_idef_parser_enabled: 238 hex_common.read_idef_parser_enabled_file(sys.argv[5]) 239 hex_common.calculate_attribs() 240 tagregs = hex_common.get_tagregs() 241 tagimms = hex_common.get_tagimms() 242 243 with open(sys.argv[-1], 'w') as f: 244 f.write("#ifndef HEXAGON_TCG_FUNCS_H\n") 245 f.write("#define HEXAGON_TCG_FUNCS_H\n\n") 246 247 for tag in hex_common.tags: 248 gen_analyze_func(f, tag, tagregs[tag], tagimms[tag]) 249 250 f.write("#endif /* HEXAGON_TCG_FUNCS_H */\n") 251 252if __name__ == "__main__": 253 main() 254