1#!/usr/bin/env python3 2 3## 4## Copyright(c) 2019-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_tcg_func 28## 29def gen_decl_ea_tcg(f, tag): 30 f.write(" TCGv EA G_GNUC_UNUSED = tcg_temp_new();\n") 31 32 33def genptr_decl_pair_writable(f, tag, regtype, regid, regno): 34 regN = f"{regtype}{regid}N" 35 if regtype == "R": 36 f.write(f" const int {regN} = insn->regno[{regno}];\n") 37 elif regtype == "C": 38 f.write(f" const int {regN} = insn->regno[{regno}] + HEX_REG_SA0;\n") 39 else: 40 print("Bad register parse: ", regtype, regid) 41 f.write(f" TCGv_i64 {regtype}{regid}V = " f"get_result_gpr_pair(ctx, {regN});\n") 42 43 44def genptr_decl_writable(f, tag, regtype, regid, regno): 45 regN = f"{regtype}{regid}N" 46 if regtype == "R": 47 f.write(f" const int {regN} = insn->regno[{regno}];\n") 48 f.write(f" TCGv {regtype}{regid}V = get_result_gpr(ctx, {regN});\n") 49 elif regtype == "C": 50 f.write(f" const int {regN} = insn->regno[{regno}] + HEX_REG_SA0;\n") 51 f.write(f" TCGv {regtype}{regid}V = get_result_gpr(ctx, {regN});\n") 52 elif regtype == "P": 53 f.write(f" const int {regN} = insn->regno[{regno}];\n") 54 f.write(f" TCGv {regtype}{regid}V = tcg_temp_new();\n") 55 else: 56 print("Bad register parse: ", regtype, regid) 57 58 59def genptr_decl(f, tag, regtype, regid, regno): 60 regN = f"{regtype}{regid}N" 61 if regtype == "R": 62 if regid in {"ss", "tt"}: 63 f.write(f" TCGv_i64 {regtype}{regid}V = tcg_temp_new_i64();\n") 64 f.write(f" const int {regN} = insn->regno[{regno}];\n") 65 elif regid in {"dd", "ee", "xx", "yy"}: 66 genptr_decl_pair_writable(f, tag, regtype, regid, regno) 67 elif regid in {"s", "t", "u", "v"}: 68 f.write( 69 f" TCGv {regtype}{regid}V = " f"hex_gpr[insn->regno[{regno}]];\n" 70 ) 71 elif regid in {"d", "e", "x", "y"}: 72 genptr_decl_writable(f, tag, regtype, regid, regno) 73 else: 74 print("Bad register parse: ", regtype, regid) 75 elif regtype == "P": 76 if regid in {"s", "t", "u", "v"}: 77 f.write( 78 f" TCGv {regtype}{regid}V = " f"hex_pred[insn->regno[{regno}]];\n" 79 ) 80 elif regid in {"d", "e", "x"}: 81 genptr_decl_writable(f, tag, regtype, regid, regno) 82 else: 83 print("Bad register parse: ", regtype, regid) 84 elif regtype == "C": 85 if regid == "ss": 86 f.write(f" TCGv_i64 {regtype}{regid}V = " f"tcg_temp_new_i64();\n") 87 f.write(f" const int {regN} = insn->regno[{regno}] + " "HEX_REG_SA0;\n") 88 elif regid == "dd": 89 genptr_decl_pair_writable(f, tag, regtype, regid, regno) 90 elif regid == "s": 91 f.write(f" TCGv {regtype}{regid}V = tcg_temp_new();\n") 92 f.write( 93 f" const int {regtype}{regid}N = insn->regno[{regno}] + " 94 "HEX_REG_SA0;\n" 95 ) 96 elif regid == "d": 97 genptr_decl_writable(f, tag, regtype, regid, regno) 98 else: 99 print("Bad register parse: ", regtype, regid) 100 elif regtype == "M": 101 if regid == "u": 102 f.write(f" const int {regtype}{regid}N = " f"insn->regno[{regno}];\n") 103 f.write( 104 f" TCGv {regtype}{regid}V = hex_gpr[{regtype}{regid}N + " 105 "HEX_REG_M0];\n" 106 ) 107 else: 108 print("Bad register parse: ", regtype, regid) 109 elif regtype == "V": 110 if regid in {"dd"}: 111 f.write(f" const int {regtype}{regid}N = " f"insn->regno[{regno}];\n") 112 f.write(f" const intptr_t {regtype}{regid}V_off =\n") 113 if hex_common.is_tmp_result(tag): 114 f.write( 115 f" ctx_tmp_vreg_off(ctx, {regtype}{regid}N, 2, " "true);\n" 116 ) 117 else: 118 f.write(f" ctx_future_vreg_off(ctx, {regtype}{regid}N,") 119 f.write(" 2, true);\n") 120 if not hex_common.skip_qemu_helper(tag): 121 f.write(f" TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n") 122 f.write( 123 f" tcg_gen_addi_ptr({regtype}{regid}V, cpu_env, " 124 f"{regtype}{regid}V_off);\n" 125 ) 126 elif regid in {"uu", "vv", "xx"}: 127 f.write(f" const int {regtype}{regid}N = " f"insn->regno[{regno}];\n") 128 f.write(f" const intptr_t {regtype}{regid}V_off =\n") 129 f.write(f" offsetof(CPUHexagonState, {regtype}{regid}V);\n") 130 if not hex_common.skip_qemu_helper(tag): 131 f.write(f" TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n") 132 f.write( 133 f" tcg_gen_addi_ptr({regtype}{regid}V, cpu_env, " 134 f"{regtype}{regid}V_off);\n" 135 ) 136 elif regid in {"s", "u", "v", "w"}: 137 f.write(f" const int {regtype}{regid}N = " f"insn->regno[{regno}];\n") 138 f.write(f" const intptr_t {regtype}{regid}V_off =\n") 139 f.write(f" vreg_src_off(ctx, {regtype}{regid}N);\n") 140 if not hex_common.skip_qemu_helper(tag): 141 f.write(f" TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n") 142 elif regid in {"d", "x", "y"}: 143 f.write(f" const int {regtype}{regid}N = " f"insn->regno[{regno}];\n") 144 f.write(f" const intptr_t {regtype}{regid}V_off =\n") 145 if regid == "y": 146 f.write(" offsetof(CPUHexagonState, vtmp);\n") 147 elif hex_common.is_tmp_result(tag): 148 f.write( 149 f" ctx_tmp_vreg_off(ctx, {regtype}{regid}N, 1, " "true);\n" 150 ) 151 else: 152 f.write(f" ctx_future_vreg_off(ctx, {regtype}{regid}N,") 153 f.write(" 1, true);\n") 154 155 if not hex_common.skip_qemu_helper(tag): 156 f.write(f" TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n") 157 f.write( 158 f" tcg_gen_addi_ptr({regtype}{regid}V, cpu_env, " 159 f"{regtype}{regid}V_off);\n" 160 ) 161 else: 162 print("Bad register parse: ", regtype, regid) 163 elif regtype == "Q": 164 if regid in {"d", "e", "x"}: 165 f.write(f" const int {regtype}{regid}N = " f"insn->regno[{regno}];\n") 166 f.write(f" const intptr_t {regtype}{regid}V_off =\n") 167 f.write(f" get_result_qreg(ctx, {regtype}{regid}N);\n") 168 if not hex_common.skip_qemu_helper(tag): 169 f.write(f" TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n") 170 f.write( 171 f" tcg_gen_addi_ptr({regtype}{regid}V, cpu_env, " 172 f"{regtype}{regid}V_off);\n" 173 ) 174 elif regid in {"s", "t", "u", "v"}: 175 f.write(f" const int {regtype}{regid}N = " f"insn->regno[{regno}];\n") 176 f.write(f" const intptr_t {regtype}{regid}V_off =\n") 177 f.write( 178 f" offsetof(CPUHexagonState, " f"QRegs[{regtype}{regid}N]);\n" 179 ) 180 if not hex_common.skip_qemu_helper(tag): 181 f.write(f" TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n") 182 else: 183 print("Bad register parse: ", regtype, regid) 184 else: 185 print("Bad register parse: ", regtype, regid) 186 187 188def genptr_decl_new(f, tag, regtype, regid, regno): 189 if regtype == "N": 190 if regid in {"s", "t"}: 191 f.write( 192 f" TCGv {regtype}{regid}N = " 193 f"hex_new_value[insn->regno[{regno}]];\n" 194 ) 195 else: 196 print("Bad register parse: ", regtype, regid) 197 elif regtype == "P": 198 if regid in {"t", "u", "v"}: 199 f.write( 200 f" TCGv {regtype}{regid}N = " 201 f"hex_new_pred_value[insn->regno[{regno}]];\n" 202 ) 203 else: 204 print("Bad register parse: ", regtype, regid) 205 elif regtype == "O": 206 if regid == "s": 207 f.write( 208 f" const intptr_t {regtype}{regid}N_num = " 209 f"insn->regno[{regno}];\n" 210 ) 211 if hex_common.skip_qemu_helper(tag): 212 f.write(f" const intptr_t {regtype}{regid}N_off =\n") 213 f.write(" ctx_future_vreg_off(ctx, " f"{regtype}{regid}N_num,") 214 f.write(" 1, true);\n") 215 else: 216 f.write( 217 f" TCGv {regtype}{regid}N = " 218 f"tcg_constant_tl({regtype}{regid}N_num);\n" 219 ) 220 else: 221 print("Bad register parse: ", regtype, regid) 222 else: 223 print("Bad register parse: ", regtype, regid) 224 225 226def genptr_decl_opn(f, tag, regtype, regid, toss, numregs, i): 227 if hex_common.is_pair(regid): 228 genptr_decl(f, tag, regtype, regid, i) 229 elif hex_common.is_single(regid): 230 if hex_common.is_old_val(regtype, regid, tag): 231 genptr_decl(f, tag, regtype, regid, i) 232 elif hex_common.is_new_val(regtype, regid, tag): 233 genptr_decl_new(f, tag, regtype, regid, i) 234 else: 235 print("Bad register parse: ", regtype, regid, toss, numregs) 236 else: 237 print("Bad register parse: ", regtype, regid, toss, numregs) 238 239 240def genptr_decl_imm(f, immlett): 241 if immlett.isupper(): 242 i = 1 243 else: 244 i = 0 245 f.write(f" int {hex_common.imm_name(immlett)} = insn->immed[{i}];\n") 246 247 248def genptr_src_read(f, tag, regtype, regid): 249 if regtype == "R": 250 if regid in {"ss", "tt", "xx", "yy"}: 251 f.write( 252 f" tcg_gen_concat_i32_i64({regtype}{regid}V, " 253 f"hex_gpr[{regtype}{regid}N],\n" 254 ) 255 f.write( 256 f" hex_gpr[{regtype}" 257 f"{regid}N + 1]);\n" 258 ) 259 elif regid in {"x", "y"}: 260 ## For read/write registers, we need to get the original value into 261 ## the result TCGv. For conditional instructions, this is done in 262 ## gen_start_packet. For unconditional instructions, we do it here. 263 if "A_CONDEXEC" not in hex_common.attribdict[tag]: 264 f.write( 265 f" tcg_gen_mov_tl({regtype}{regid}V, " 266 f"hex_gpr[{regtype}{regid}N]);\n" 267 ) 268 elif regid not in {"s", "t", "u", "v"}: 269 print("Bad register parse: ", regtype, regid) 270 elif regtype == "P": 271 if regid == "x": 272 f.write( 273 f" tcg_gen_mov_tl({regtype}{regid}V, " 274 f"hex_pred[{regtype}{regid}N]);\n" 275 ) 276 elif regid not in {"s", "t", "u", "v"}: 277 print("Bad register parse: ", regtype, regid) 278 elif regtype == "C": 279 if regid == "ss": 280 f.write( 281 f" gen_read_ctrl_reg_pair(ctx, {regtype}{regid}N, " 282 f"{regtype}{regid}V);\n" 283 ) 284 elif regid == "s": 285 f.write( 286 f" gen_read_ctrl_reg(ctx, {regtype}{regid}N, " 287 f"{regtype}{regid}V);\n" 288 ) 289 else: 290 print("Bad register parse: ", regtype, regid) 291 elif regtype == "M": 292 if regid != "u": 293 print("Bad register parse: ", regtype, regid) 294 elif regtype == "V": 295 if regid in {"uu", "vv", "xx"}: 296 f.write(f" tcg_gen_gvec_mov(MO_64, {regtype}{regid}V_off,\n") 297 f.write(f" vreg_src_off(ctx, {regtype}{regid}N),\n") 298 f.write(" sizeof(MMVector), sizeof(MMVector));\n") 299 f.write(" tcg_gen_gvec_mov(MO_64,\n") 300 f.write(f" {regtype}{regid}V_off + sizeof(MMVector),\n") 301 f.write(f" vreg_src_off(ctx, {regtype}{regid}N ^ 1),\n") 302 f.write(" sizeof(MMVector), sizeof(MMVector));\n") 303 elif regid in {"s", "u", "v", "w"}: 304 if not hex_common.skip_qemu_helper(tag): 305 f.write( 306 f" tcg_gen_addi_ptr({regtype}{regid}V, cpu_env, " 307 f"{regtype}{regid}V_off);\n" 308 ) 309 elif regid in {"x", "y"}: 310 f.write(f" tcg_gen_gvec_mov(MO_64, {regtype}{regid}V_off,\n") 311 f.write(f" vreg_src_off(ctx, {regtype}{regid}N),\n") 312 f.write(" sizeof(MMVector), sizeof(MMVector));\n") 313 else: 314 print("Bad register parse: ", regtype, regid) 315 elif regtype == "Q": 316 if regid in {"s", "t", "u", "v"}: 317 if not hex_common.skip_qemu_helper(tag): 318 f.write( 319 f" tcg_gen_addi_ptr({regtype}{regid}V, cpu_env, " 320 f"{regtype}{regid}V_off);\n" 321 ) 322 elif regid in {"x"}: 323 f.write(f" tcg_gen_gvec_mov(MO_64, {regtype}{regid}V_off,\n") 324 f.write( 325 f" offsetof(CPUHexagonState, " f"QRegs[{regtype}{regid}N]),\n" 326 ) 327 f.write(" sizeof(MMQReg), sizeof(MMQReg));\n") 328 else: 329 print("Bad register parse: ", regtype, regid) 330 else: 331 print("Bad register parse: ", regtype, regid) 332 333 334def genptr_src_read_new(f, regtype, regid): 335 if regtype == "N": 336 if regid not in {"s", "t"}: 337 print("Bad register parse: ", regtype, regid) 338 elif regtype == "P": 339 if regid not in {"t", "u", "v"}: 340 print("Bad register parse: ", regtype, regid) 341 elif regtype == "O": 342 if regid != "s": 343 print("Bad register parse: ", regtype, regid) 344 else: 345 print("Bad register parse: ", regtype, regid) 346 347 348def genptr_src_read_opn(f, regtype, regid, tag): 349 if hex_common.is_pair(regid): 350 genptr_src_read(f, tag, regtype, regid) 351 elif hex_common.is_single(regid): 352 if hex_common.is_old_val(regtype, regid, tag): 353 genptr_src_read(f, tag, regtype, regid) 354 elif hex_common.is_new_val(regtype, regid, tag): 355 genptr_src_read_new(f, regtype, regid) 356 else: 357 print("Bad register parse: ", regtype, regid, toss, numregs) 358 else: 359 print("Bad register parse: ", regtype, regid, toss, numregs) 360 361 362def gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i): 363 if i > 0: 364 f.write(", ") 365 if hex_common.is_pair(regid): 366 f.write(f"{regtype}{regid}V") 367 elif hex_common.is_single(regid): 368 if hex_common.is_old_val(regtype, regid, tag): 369 f.write(f"{regtype}{regid}V") 370 elif hex_common.is_new_val(regtype, regid, tag): 371 f.write(f"{regtype}{regid}N") 372 else: 373 print("Bad register parse: ", regtype, regid, toss, numregs) 374 else: 375 print("Bad register parse: ", regtype, regid, toss, numregs) 376 377 378def gen_helper_decl_imm(f, immlett): 379 f.write( 380 f" TCGv tcgv_{hex_common.imm_name(immlett)} = " 381 f"tcg_constant_tl({hex_common.imm_name(immlett)});\n" 382 ) 383 384 385def gen_helper_call_imm(f, immlett): 386 f.write(f", tcgv_{hex_common.imm_name(immlett)}") 387 388 389def genptr_dst_write_pair(f, tag, regtype, regid): 390 f.write(f" gen_log_reg_write_pair({regtype}{regid}N, " f"{regtype}{regid}V);\n") 391 392 393def genptr_dst_write(f, tag, regtype, regid): 394 if regtype == "R": 395 if regid in {"dd", "xx", "yy"}: 396 genptr_dst_write_pair(f, tag, regtype, regid) 397 elif regid in {"d", "e", "x", "y"}: 398 f.write( 399 f" gen_log_reg_write({regtype}{regid}N, " f"{regtype}{regid}V);\n" 400 ) 401 else: 402 print("Bad register parse: ", regtype, regid) 403 elif regtype == "P": 404 if regid in {"d", "e", "x"}: 405 f.write( 406 f" gen_log_pred_write(ctx, {regtype}{regid}N, " 407 f"{regtype}{regid}V);\n" 408 ) 409 else: 410 print("Bad register parse: ", regtype, regid) 411 elif regtype == "C": 412 if regid == "dd": 413 f.write( 414 f" gen_write_ctrl_reg_pair(ctx, {regtype}{regid}N, " 415 f"{regtype}{regid}V);\n" 416 ) 417 elif regid == "d": 418 f.write( 419 f" gen_write_ctrl_reg(ctx, {regtype}{regid}N, " 420 f"{regtype}{regid}V);\n" 421 ) 422 else: 423 print("Bad register parse: ", regtype, regid) 424 else: 425 print("Bad register parse: ", regtype, regid) 426 427 428def genptr_dst_write_ext(f, tag, regtype, regid, newv="EXT_DFL"): 429 if regtype == "V": 430 if regid in {"xx"}: 431 f.write( 432 f" gen_log_vreg_write_pair(ctx, {regtype}{regid}V_off, " 433 f"{regtype}{regid}N, {newv});\n" 434 ) 435 elif regid in {"y"}: 436 f.write( 437 f" gen_log_vreg_write(ctx, {regtype}{regid}V_off, " 438 f"{regtype}{regid}N, {newv});\n" 439 ) 440 elif regid not in {"dd", "d", "x"}: 441 print("Bad register parse: ", regtype, regid) 442 elif regtype == "Q": 443 if regid not in {"d", "e", "x"}: 444 print("Bad register parse: ", regtype, regid) 445 else: 446 print("Bad register parse: ", regtype, regid) 447 448 449def genptr_dst_write_opn(f, regtype, regid, tag): 450 if hex_common.is_pair(regid): 451 if hex_common.is_hvx_reg(regtype): 452 if hex_common.is_tmp_result(tag): 453 genptr_dst_write_ext(f, tag, regtype, regid, "EXT_TMP") 454 else: 455 genptr_dst_write_ext(f, tag, regtype, regid) 456 else: 457 genptr_dst_write(f, tag, regtype, regid) 458 elif hex_common.is_single(regid): 459 if hex_common.is_hvx_reg(regtype): 460 if hex_common.is_new_result(tag): 461 genptr_dst_write_ext(f, tag, regtype, regid, "EXT_NEW") 462 elif hex_common.is_tmp_result(tag): 463 genptr_dst_write_ext(f, tag, regtype, regid, "EXT_TMP") 464 else: 465 genptr_dst_write_ext(f, tag, regtype, regid, "EXT_DFL") 466 else: 467 genptr_dst_write(f, tag, regtype, regid) 468 else: 469 print("Bad register parse: ", regtype, regid, toss, numregs) 470 471 472## 473## Generate the TCG code to call the helper 474## For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;} 475## We produce: 476## static void generate_A2_add(DisasContext *ctx) 477## { 478## Insn *insn __attribute__((unused)) = ctx->insn; 479## const int RdN = insn->regno[0]; 480## TCGv RdV = get_result_gpr(ctx, RdN); 481## TCGv RsV = hex_gpr[insn->regno[1]]; 482## TCGv RtV = hex_gpr[insn->regno[2]]; 483## <GEN> 484## gen_log_reg_write(RdN, RdV); 485## } 486## 487## where <GEN> depends on hex_common.skip_qemu_helper(tag) 488## if hex_common.skip_qemu_helper(tag) is True 489## <GEN> is fGEN_TCG_A2_add({ RdV=RsV+RtV;}); 490## if hex_common.skip_qemu_helper(tag) is False 491## <GEN> is gen_helper_A2_add(RdV, cpu_env, RsV, RtV); 492## 493def gen_tcg_func(f, tag, regs, imms): 494 f.write(f"static void generate_{tag}(DisasContext *ctx)\n") 495 f.write("{\n") 496 497 f.write(" Insn *insn __attribute__((unused)) = ctx->insn;\n") 498 499 if hex_common.need_ea(tag): 500 gen_decl_ea_tcg(f, tag) 501 i = 0 502 ## Declare all the operands (regs and immediates) 503 for regtype, regid, toss, numregs in regs: 504 genptr_decl_opn(f, tag, regtype, regid, toss, numregs, i) 505 i += 1 506 for immlett, bits, immshift in imms: 507 genptr_decl_imm(f, immlett) 508 509 if "A_PRIV" in hex_common.attribdict[tag]: 510 f.write(" fCHECKFORPRIV();\n") 511 if "A_GUEST" in hex_common.attribdict[tag]: 512 f.write(" fCHECKFORGUEST();\n") 513 514 ## Read all the inputs 515 for regtype, regid, toss, numregs in regs: 516 if hex_common.is_read(regid): 517 genptr_src_read_opn(f, regtype, regid, tag) 518 519 if hex_common.is_idef_parser_enabled(tag): 520 declared = [] 521 ## Handle registers 522 for regtype, regid, toss, numregs in regs: 523 if hex_common.is_pair(regid) or ( 524 hex_common.is_single(regid) 525 and hex_common.is_old_val(regtype, regid, tag) 526 ): 527 declared.append(f"{regtype}{regid}V") 528 if regtype == "M": 529 declared.append(f"{regtype}{regid}N") 530 elif hex_common.is_new_val(regtype, regid, tag): 531 declared.append(f"{regtype}{regid}N") 532 else: 533 print("Bad register parse: ", regtype, regid, toss, numregs) 534 535 ## Handle immediates 536 for immlett, bits, immshift in imms: 537 declared.append(hex_common.imm_name(immlett)) 538 539 arguments = ", ".join(["ctx", "ctx->insn", "ctx->pkt"] + declared) 540 f.write(f" emit_{tag}({arguments});\n") 541 542 elif hex_common.skip_qemu_helper(tag): 543 f.write(f" fGEN_TCG_{tag}({hex_common.semdict[tag]});\n") 544 else: 545 ## Generate the call to the helper 546 for immlett, bits, immshift in imms: 547 gen_helper_decl_imm(f, immlett) 548 if hex_common.need_pkt_has_multi_cof(tag): 549 f.write(" TCGv pkt_has_multi_cof = ") 550 f.write("tcg_constant_tl(ctx->pkt->pkt_has_multi_cof);\n") 551 if hex_common.need_part1(tag): 552 f.write(" TCGv part1 = tcg_constant_tl(insn->part1);\n") 553 if hex_common.need_slot(tag): 554 f.write(" TCGv slot = tcg_constant_tl(insn->slot);\n") 555 if hex_common.need_PC(tag): 556 f.write(" TCGv PC = tcg_constant_tl(ctx->pkt->pc);\n") 557 if hex_common.helper_needs_next_PC(tag): 558 f.write(" TCGv next_PC = tcg_constant_tl(ctx->next_PC);\n") 559 f.write(f" gen_helper_{tag}(") 560 i = 0 561 ## If there is a scalar result, it is the return type 562 for regtype, regid, toss, numregs in regs: 563 if hex_common.is_written(regid): 564 if hex_common.is_hvx_reg(regtype): 565 continue 566 gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i) 567 i += 1 568 if i > 0: 569 f.write(", ") 570 f.write("cpu_env") 571 i = 1 572 ## For conditional instructions, we pass in the destination register 573 if "A_CONDEXEC" in hex_common.attribdict[tag]: 574 for regtype, regid, toss, numregs in regs: 575 if hex_common.is_writeonly(regid) and not hex_common.is_hvx_reg( 576 regtype 577 ): 578 gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i) 579 i += 1 580 for regtype, regid, toss, numregs in regs: 581 if hex_common.is_written(regid): 582 if not hex_common.is_hvx_reg(regtype): 583 continue 584 gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i) 585 i += 1 586 for regtype, regid, toss, numregs in regs: 587 if hex_common.is_read(regid): 588 if hex_common.is_hvx_reg(regtype) and hex_common.is_readwrite(regid): 589 continue 590 gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i) 591 i += 1 592 for immlett, bits, immshift in imms: 593 gen_helper_call_imm(f, immlett) 594 595 if hex_common.need_pkt_has_multi_cof(tag): 596 f.write(", pkt_has_multi_cof") 597 if hex_common.need_PC(tag): 598 f.write(", PC") 599 if hex_common.helper_needs_next_PC(tag): 600 f.write(", next_PC") 601 if hex_common.need_slot(tag): 602 f.write(", slot") 603 if hex_common.need_part1(tag): 604 f.write(", part1") 605 f.write(");\n") 606 607 ## Write all the outputs 608 for regtype, regid, toss, numregs in regs: 609 if hex_common.is_written(regid): 610 genptr_dst_write_opn(f, regtype, regid, tag) 611 612 f.write("}\n\n") 613 614 615def gen_def_tcg_func(f, tag, tagregs, tagimms): 616 regs = tagregs[tag] 617 imms = tagimms[tag] 618 619 gen_tcg_func(f, tag, regs, imms) 620 621 622def main(): 623 hex_common.read_semantics_file(sys.argv[1]) 624 hex_common.read_attribs_file(sys.argv[2]) 625 hex_common.read_overrides_file(sys.argv[3]) 626 hex_common.read_overrides_file(sys.argv[4]) 627 hex_common.calculate_attribs() 628 ## Whether or not idef-parser is enabled is 629 ## determined by the number of arguments to 630 ## this script: 631 ## 632 ## 5 args. -> not enabled, 633 ## 6 args. -> idef-parser enabled. 634 ## 635 ## The 6:th arg. then holds a list of the successfully 636 ## parsed instructions. 637 is_idef_parser_enabled = len(sys.argv) > 6 638 if is_idef_parser_enabled: 639 hex_common.read_idef_parser_enabled_file(sys.argv[5]) 640 tagregs = hex_common.get_tagregs() 641 tagimms = hex_common.get_tagimms() 642 643 output_file = sys.argv[-1] 644 with open(output_file, "w") as f: 645 f.write("#ifndef HEXAGON_TCG_FUNCS_H\n") 646 f.write("#define HEXAGON_TCG_FUNCS_H\n\n") 647 if is_idef_parser_enabled: 648 f.write('#include "idef-generated-emitter.h.inc"\n\n') 649 650 for tag in hex_common.tags: 651 ## Skip the priv instructions 652 if "A_PRIV" in hex_common.attribdict[tag]: 653 continue 654 ## Skip the guest instructions 655 if "A_GUEST" in hex_common.attribdict[tag]: 656 continue 657 ## Skip the diag instructions 658 if tag == "Y6_diag": 659 continue 660 if tag == "Y6_diag0": 661 continue 662 if tag == "Y6_diag1": 663 continue 664 665 gen_def_tcg_func(f, tag, tagregs, tagimms) 666 667 f.write("#endif /* HEXAGON_TCG_FUNCS_H */\n") 668 669 670if __name__ == "__main__": 671 main() 672