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## 27## Helpers for gen_analyze_func 28## 29def is_predicated(tag): 30 return "A_CONDEXEC" in hex_common.attribdict[tag] 31 32 33def analyze_opn_old(f, tag, regtype, regid, regno): 34 regN = f"{regtype}{regid}N" 35 predicated = "true" if is_predicated(tag) else "false" 36 if regtype == "R": 37 if regid in {"ss", "tt"}: 38 f.write(f" const int {regN} = insn->regno[{regno}];\n") 39 f.write(f" ctx_log_reg_read_pair(ctx, {regN});\n") 40 elif regid in {"dd", "ee", "xx", "yy"}: 41 f.write(f" const int {regN} = insn->regno[{regno}];\n") 42 f.write(f" ctx_log_reg_write_pair(ctx, {regN}, {predicated});\n") 43 elif regid in {"s", "t", "u", "v"}: 44 f.write(f" const int {regN} = insn->regno[{regno}];\n") 45 f.write(f" ctx_log_reg_read(ctx, {regN});\n") 46 elif regid in {"d", "e", "x", "y"}: 47 f.write(f" const int {regN} = insn->regno[{regno}];\n") 48 f.write(f" ctx_log_reg_write(ctx, {regN}, {predicated});\n") 49 else: 50 hex_common.bad_register(regtype, regid) 51 elif regtype == "P": 52 if regid in {"s", "t", "u", "v"}: 53 f.write(f" const int {regN} = insn->regno[{regno}];\n") 54 f.write(f" ctx_log_pred_read(ctx, {regN});\n") 55 elif regid in {"d", "e", "x"}: 56 f.write(f" const int {regN} = insn->regno[{regno}];\n") 57 f.write(f" ctx_log_pred_write(ctx, {regN});\n") 58 else: 59 hex_common.bad_register(regtype, regid) 60 elif regtype == "C": 61 if regid == "ss": 62 f.write( 63 f" const int {regN} = insn->regno[{regno}] " 64 "+ HEX_REG_SA0;\n" 65 ) 66 f.write(f" ctx_log_reg_read_pair(ctx, {regN});\n") 67 elif regid == "dd": 68 f.write(f" const int {regN} = insn->regno[{regno}] " "+ HEX_REG_SA0;\n") 69 f.write(f" ctx_log_reg_write_pair(ctx, {regN}, {predicated});\n") 70 elif regid == "s": 71 f.write( 72 f" const int {regN} = insn->regno[{regno}] " 73 "+ HEX_REG_SA0;\n" 74 ) 75 f.write(f" ctx_log_reg_read(ctx, {regN});\n") 76 elif regid == "d": 77 f.write(f" const int {regN} = insn->regno[{regno}] " "+ HEX_REG_SA0;\n") 78 f.write(f" ctx_log_reg_write(ctx, {regN}, {predicated});\n") 79 else: 80 hex_common.bad_register(regtype, regid) 81 elif regtype == "M": 82 if regid == "u": 83 f.write(f" const int {regN} = insn->regno[{regno}];\n") 84 f.write(f" ctx_log_reg_read(ctx, {regN});\n") 85 else: 86 hex_common.bad_register(regtype, regid) 87 elif regtype == "V": 88 newv = "EXT_DFL" 89 if hex_common.is_new_result(tag): 90 newv = "EXT_NEW" 91 elif hex_common.is_tmp_result(tag): 92 newv = "EXT_TMP" 93 if regid in {"dd", "xx"}: 94 f.write(f" const int {regN} = insn->regno[{regno}];\n") 95 f.write( 96 f" ctx_log_vreg_write_pair(ctx, {regN}, {newv}, " f"{predicated});\n" 97 ) 98 elif regid in {"uu", "vv"}: 99 f.write(f" const int {regN} = insn->regno[{regno}];\n") 100 f.write(f" ctx_log_vreg_read_pair(ctx, {regN});\n") 101 elif regid in {"s", "u", "v", "w"}: 102 f.write(f" const int {regN} = insn->regno[{regno}];\n") 103 f.write(f" ctx_log_vreg_read(ctx, {regN});\n") 104 elif regid in {"d", "x", "y"}: 105 f.write(f" const int {regN} = insn->regno[{regno}];\n") 106 f.write(f" ctx_log_vreg_write(ctx, {regN}, {newv}, " f"{predicated});\n") 107 else: 108 hex_common.bad_register(regtype, regid) 109 elif regtype == "Q": 110 if regid in {"d", "e", "x"}: 111 f.write(f" const int {regN} = insn->regno[{regno}];\n") 112 f.write(f" ctx_log_qreg_write(ctx, {regN});\n") 113 elif regid in {"s", "t", "u", "v"}: 114 f.write(f" const int {regN} = insn->regno[{regno}];\n") 115 f.write(f" ctx_log_qreg_read(ctx, {regN});\n") 116 else: 117 hex_common.bad_register(regtype, regid) 118 elif regtype == "G": 119 if regid in {"dd"}: 120 f.write(f"// const int {regN} = insn->regno[{regno}];\n") 121 elif regid in {"d"}: 122 f.write(f"// const int {regN} = insn->regno[{regno}];\n") 123 elif regid in {"ss"}: 124 f.write(f"// const int {regN} = insn->regno[{regno}];\n") 125 elif regid in {"s"}: 126 f.write(f"// const int {regN} = insn->regno[{regno}];\n") 127 else: 128 hex_common.bad_register(regtype, regid) 129 elif regtype == "S": 130 if regid in {"dd"}: 131 f.write(f"// const int {regN} = insn->regno[{regno}];\n") 132 elif regid in {"d"}: 133 f.write(f"// const int {regN} = insn->regno[{regno}];\n") 134 elif regid in {"ss"}: 135 f.write(f"// const int {regN} = insn->regno[{regno}];\n") 136 elif regid in {"s"}: 137 f.write(f"// const int {regN} = insn->regno[{regno}];\n") 138 else: 139 hex_common.bad_register(regtype, regid) 140 else: 141 hex_common.bad_register(regtype, regid) 142 143 144def analyze_opn_new(f, tag, regtype, regid, regno): 145 regN = f"{regtype}{regid}N" 146 if regtype == "N": 147 if regid in {"s", "t"}: 148 f.write(f" const int {regN} = insn->regno[{regno}];\n") 149 f.write(f" ctx_log_reg_read(ctx, {regN});\n") 150 else: 151 hex_common.bad_register(regtype, regid) 152 elif regtype == "P": 153 if regid in {"t", "u", "v"}: 154 f.write(f" const int {regN} = insn->regno[{regno}];\n") 155 f.write(f" ctx_log_pred_read(ctx, {regN});\n") 156 else: 157 hex_common.bad_register(regtype, regid) 158 elif regtype == "O": 159 if regid == "s": 160 f.write(f" const int {regN} = insn->regno[{regno}];\n") 161 f.write(f" ctx_log_vreg_read(ctx, {regN});\n") 162 else: 163 hex_common.bad_register(regtype, regid) 164 else: 165 hex_common.bad_register(regtype, regid) 166 167 168def analyze_opn(f, tag, regtype, regid, i): 169 if hex_common.is_pair(regid): 170 analyze_opn_old(f, tag, regtype, regid, i) 171 elif hex_common.is_single(regid): 172 if hex_common.is_old_val(regtype, regid, tag): 173 analyze_opn_old(f, tag, regtype, regid, i) 174 elif hex_common.is_new_val(regtype, regid, tag): 175 analyze_opn_new(f, tag, regtype, regid, i) 176 else: 177 hex_common.bad_register(regtype, regid) 178 else: 179 hex_common.bad_register(regtype, regid) 180 181 182## 183## Generate the code to analyze the instruction 184## For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;} 185## We produce: 186## static void analyze_A2_add(DisasContext *ctx) 187## { 188## Insn *insn G_GNUC_UNUSED = ctx->insn; 189## const int RdN = insn->regno[0]; 190## ctx_log_reg_write(ctx, RdN, false); 191## const int RsN = insn->regno[1]; 192## ctx_log_reg_read(ctx, RsN); 193## const int RtN = insn->regno[2]; 194## ctx_log_reg_read(ctx, RtN); 195## } 196## 197def gen_analyze_func(f, tag, regs, imms): 198 f.write(f"static void analyze_{tag}(DisasContext *ctx)\n") 199 f.write("{\n") 200 201 f.write(" Insn *insn G_GNUC_UNUSED = ctx->insn;\n") 202 203 i = 0 204 ## Analyze all the registers 205 for regtype, regid in regs: 206 analyze_opn(f, tag, regtype, regid, i) 207 i += 1 208 209 has_generated_helper = not hex_common.skip_qemu_helper( 210 tag 211 ) and not hex_common.is_idef_parser_enabled(tag) 212 213 ## Mark HVX instructions with generated helpers 214 if (has_generated_helper and 215 "A_CVI" in hex_common.attribdict[tag]): 216 f.write(" ctx->has_hvx_helper = true;\n") 217 218 f.write("}\n\n") 219 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 251 252if __name__ == "__main__": 253 main() 254