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);\n" % (regN)) 114 elif (regid in {"s", "t", "u", "v"}): 115 f.write("// const int %s = insn->regno[%d];\n" % \ 116 (regN, regno)) 117 else: 118 print("Bad register parse: ", regtype, regid) 119 elif (regtype == "G"): 120 if (regid in {"dd"}): 121 f.write("// const int %s = insn->regno[%d];\n" % \ 122 (regN, regno)) 123 elif (regid in {"d"}): 124 f.write("// const int %s = insn->regno[%d];\n" % \ 125 (regN, regno)) 126 elif (regid in {"ss"}): 127 f.write("// const int %s = insn->regno[%d];\n" % \ 128 (regN, regno)) 129 elif (regid in {"s"}): 130 f.write("// const int %s = insn->regno[%d];\n" % \ 131 (regN, regno)) 132 else: 133 print("Bad register parse: ", regtype, regid) 134 elif (regtype == "S"): 135 if (regid in {"dd"}): 136 f.write("// const int %s = insn->regno[%d];\n" % \ 137 (regN, regno)) 138 elif (regid in {"d"}): 139 f.write("// const int %s = insn->regno[%d];\n" % \ 140 (regN, regno)) 141 elif (regid in {"ss"}): 142 f.write("// const int %s = insn->regno[%d];\n" % \ 143 (regN, regno)) 144 elif (regid in {"s"}): 145 f.write("// const int %s = insn->regno[%d];\n" % \ 146 (regN, regno)) 147 else: 148 print("Bad register parse: ", regtype, regid) 149 else: 150 print("Bad register parse: ", regtype, regid) 151 152def analyze_opn_new(f, tag, regtype, regid, regno): 153 regN = "%s%sN" % (regtype, regid) 154 if (regtype == "N"): 155 if (regid in {"s", "t"}): 156 f.write("// const int %s = insn->regno[%d];\n" % \ 157 (regN, regno)) 158 else: 159 print("Bad register parse: ", regtype, regid) 160 elif (regtype == "P"): 161 if (regid in {"t", "u", "v"}): 162 f.write("// const int %s = insn->regno[%d];\n" % \ 163 (regN, regno)) 164 else: 165 print("Bad register parse: ", regtype, regid) 166 elif (regtype == "O"): 167 if (regid == "s"): 168 f.write("// const int %s = insn->regno[%d];\n" % \ 169 (regN, regno)) 170 else: 171 print("Bad register parse: ", regtype, regid) 172 else: 173 print("Bad register parse: ", regtype, regid) 174 175def analyze_opn(f, tag, regtype, regid, toss, numregs, i): 176 if (hex_common.is_pair(regid)): 177 analyze_opn_old(f, tag, regtype, regid, i) 178 elif (hex_common.is_single(regid)): 179 if hex_common.is_old_val(regtype, regid, tag): 180 analyze_opn_old(f,tag, regtype, regid, i) 181 elif hex_common.is_new_val(regtype, regid, tag): 182 analyze_opn_new(f, tag, regtype, regid, i) 183 else: 184 print("Bad register parse: ", regtype, regid, toss, numregs) 185 else: 186 print("Bad register parse: ", regtype, regid, toss, numregs) 187 188## 189## Generate the code to analyze the instruction 190## For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;} 191## We produce: 192## static void analyze_A2_add(DisasContext *ctx) 193## { 194## Insn *insn G_GNUC_UNUSED = ctx->insn; 195## const int RdN = insn->regno[0]; 196## ctx_log_reg_write(ctx, RdN, false); 197## // const int RsN = insn->regno[1]; 198## // const int RtN = insn->regno[2]; 199## } 200## 201def gen_analyze_func(f, tag, regs, imms): 202 f.write("static void analyze_%s(DisasContext *ctx)\n" %tag) 203 f.write('{\n') 204 205 f.write(" Insn *insn G_GNUC_UNUSED = ctx->insn;\n") 206 207 i=0 208 ## Analyze all the registers 209 for regtype, regid, toss, numregs in regs: 210 analyze_opn(f, tag, regtype, regid, toss, numregs, i) 211 i += 1 212 213 has_generated_helper = (not hex_common.skip_qemu_helper(tag) and 214 not hex_common.is_idef_parser_enabled(tag)) 215 if (has_generated_helper and 216 'A_SCALAR_LOAD' in hex_common.attribdict[tag]): 217 f.write(" ctx->need_pkt_has_store_s1 = true;\n") 218 219 f.write("}\n\n") 220 221def main(): 222 hex_common.read_semantics_file(sys.argv[1]) 223 hex_common.read_attribs_file(sys.argv[2]) 224 hex_common.read_overrides_file(sys.argv[3]) 225 hex_common.read_overrides_file(sys.argv[4]) 226 ## Whether or not idef-parser is enabled is 227 ## determined by the number of arguments to 228 ## this script: 229 ## 230 ## 5 args. -> not enabled, 231 ## 6 args. -> idef-parser enabled. 232 ## 233 ## The 6:th arg. then holds a list of the successfully 234 ## parsed instructions. 235 is_idef_parser_enabled = len(sys.argv) > 6 236 if is_idef_parser_enabled: 237 hex_common.read_idef_parser_enabled_file(sys.argv[5]) 238 hex_common.calculate_attribs() 239 tagregs = hex_common.get_tagregs() 240 tagimms = hex_common.get_tagimms() 241 242 with open(sys.argv[-1], 'w') as f: 243 f.write("#ifndef HEXAGON_TCG_FUNCS_H\n") 244 f.write("#define HEXAGON_TCG_FUNCS_H\n\n") 245 246 for tag in hex_common.tags: 247 gen_analyze_func(f, tag, tagregs[tag], tagimms[tag]) 248 249 f.write("#endif /* HEXAGON_TCG_FUNCS_H */\n") 250 251if __name__ == "__main__": 252 main() 253