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 hex_common.bad_register(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 hex_common.bad_register(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 hex_common.bad_register(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 hex_common.bad_register(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 hex_common.bad_register(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 hex_common.bad_register(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 hex_common.bad_register(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 hex_common.bad_register(regtype, regid) 184 else: 185 hex_common.bad_register(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"get_result_gpr(ctx, insn->regno[{regno}]);\n" 194 ) 195 else: 196 hex_common.bad_register(regtype, regid) 197 elif regtype == "P": 198 if regid in {"t", "u", "v"}: 199 f.write( 200 f" TCGv {regtype}{regid}N = " 201 f"ctx->new_pred_value[insn->regno[{regno}]];\n" 202 ) 203 else: 204 hex_common.bad_register(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 hex_common.bad_register(regtype, regid) 222 else: 223 hex_common.bad_register(regtype, regid) 224 225 226def genptr_decl_opn(f, tag, regtype, regid, 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 hex_common.bad_register(regtype, regid) 236 else: 237 hex_common.bad_register(regtype, regid) 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 hex_common.bad_register(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 hex_common.bad_register(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 hex_common.bad_register(regtype, regid) 291 elif regtype == "M": 292 if regid != "u": 293 hex_common.bad_register(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 hex_common.bad_register(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 hex_common.bad_register(regtype, regid) 330 else: 331 hex_common.bad_register(regtype, regid) 332 333 334def genptr_src_read_new(f, regtype, regid): 335 if regtype == "N": 336 if regid not in {"s", "t"}: 337 hex_common.bad_register(regtype, regid) 338 elif regtype == "P": 339 if regid not in {"t", "u", "v"}: 340 hex_common.bad_register(regtype, regid) 341 elif regtype == "O": 342 if regid != "s": 343 hex_common.bad_register(regtype, regid) 344 else: 345 hex_common.bad_register(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 hex_common.bad_register(regtype, regid) 358 else: 359 hex_common.bad_register(regtype, regid) 360 361 362def gen_helper_call_opn(f, tag, regtype, regid, 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 hex_common.bad_register(regtype, regid) 374 else: 375 hex_common.bad_register(regtype, regid) 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(ctx, {regtype}{regid}N, " 391 f"{regtype}{regid}V);\n") 392 393 394def genptr_dst_write(f, tag, regtype, regid): 395 if regtype == "R": 396 if regid in {"dd", "xx", "yy"}: 397 genptr_dst_write_pair(f, tag, regtype, regid) 398 elif regid in {"d", "e", "x", "y"}: 399 f.write( 400 f" gen_log_reg_write(ctx, {regtype}{regid}N, " 401 f"{regtype}{regid}V);\n" 402 ) 403 else: 404 hex_common.bad_register(regtype, regid) 405 elif regtype == "P": 406 if regid in {"d", "e", "x"}: 407 f.write( 408 f" gen_log_pred_write(ctx, {regtype}{regid}N, " 409 f"{regtype}{regid}V);\n" 410 ) 411 else: 412 hex_common.bad_register(regtype, regid) 413 elif regtype == "C": 414 if regid == "dd": 415 f.write( 416 f" gen_write_ctrl_reg_pair(ctx, {regtype}{regid}N, " 417 f"{regtype}{regid}V);\n" 418 ) 419 elif regid == "d": 420 f.write( 421 f" gen_write_ctrl_reg(ctx, {regtype}{regid}N, " 422 f"{regtype}{regid}V);\n" 423 ) 424 else: 425 hex_common.bad_register(regtype, regid) 426 else: 427 hex_common.bad_register(regtype, regid) 428 429 430def genptr_dst_write_ext(f, tag, regtype, regid, newv="EXT_DFL"): 431 if regtype == "V": 432 if regid in {"xx"}: 433 f.write( 434 f" gen_log_vreg_write_pair(ctx, {regtype}{regid}V_off, " 435 f"{regtype}{regid}N, {newv});\n" 436 ) 437 elif regid in {"y"}: 438 f.write( 439 f" gen_log_vreg_write(ctx, {regtype}{regid}V_off, " 440 f"{regtype}{regid}N, {newv});\n" 441 ) 442 elif regid not in {"dd", "d", "x"}: 443 hex_common.bad_register(regtype, regid) 444 elif regtype == "Q": 445 if regid not in {"d", "e", "x"}: 446 hex_common.bad_register(regtype, regid) 447 else: 448 hex_common.bad_register(regtype, regid) 449 450 451def genptr_dst_write_opn(f, regtype, regid, tag): 452 if hex_common.is_pair(regid): 453 if hex_common.is_hvx_reg(regtype): 454 if hex_common.is_tmp_result(tag): 455 genptr_dst_write_ext(f, tag, regtype, regid, "EXT_TMP") 456 else: 457 genptr_dst_write_ext(f, tag, regtype, regid) 458 else: 459 genptr_dst_write(f, tag, regtype, regid) 460 elif hex_common.is_single(regid): 461 if hex_common.is_hvx_reg(regtype): 462 if hex_common.is_new_result(tag): 463 genptr_dst_write_ext(f, tag, regtype, regid, "EXT_NEW") 464 elif hex_common.is_tmp_result(tag): 465 genptr_dst_write_ext(f, tag, regtype, regid, "EXT_TMP") 466 else: 467 genptr_dst_write_ext(f, tag, regtype, regid, "EXT_DFL") 468 else: 469 genptr_dst_write(f, tag, regtype, regid) 470 else: 471 hex_common.bad_register(regtype, regid) 472 473 474## 475## Generate the TCG code to call the helper 476## For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;} 477## We produce: 478## static void generate_A2_add(DisasContext *ctx) 479## { 480## Insn *insn __attribute__((unused)) = ctx->insn; 481## const int RdN = insn->regno[0]; 482## TCGv RdV = get_result_gpr(ctx, RdN); 483## TCGv RsV = hex_gpr[insn->regno[1]]; 484## TCGv RtV = hex_gpr[insn->regno[2]]; 485## <GEN> 486## gen_log_reg_write(ctx, RdN, RdV); 487## } 488## 489## where <GEN> depends on hex_common.skip_qemu_helper(tag) 490## if hex_common.skip_qemu_helper(tag) is True 491## <GEN> is fGEN_TCG_A2_add({ RdV=RsV+RtV;}); 492## if hex_common.skip_qemu_helper(tag) is False 493## <GEN> is gen_helper_A2_add(RdV, cpu_env, RsV, RtV); 494## 495def gen_tcg_func(f, tag, regs, imms): 496 f.write(f"static void generate_{tag}(DisasContext *ctx)\n") 497 f.write("{\n") 498 499 f.write(" Insn *insn __attribute__((unused)) = ctx->insn;\n") 500 501 if hex_common.need_ea(tag): 502 gen_decl_ea_tcg(f, tag) 503 i = 0 504 ## Declare all the operands (regs and immediates) 505 for regtype, regid in regs: 506 genptr_decl_opn(f, tag, regtype, regid, i) 507 i += 1 508 for immlett, bits, immshift in imms: 509 genptr_decl_imm(f, immlett) 510 511 if "A_PRIV" in hex_common.attribdict[tag]: 512 f.write(" fCHECKFORPRIV();\n") 513 if "A_GUEST" in hex_common.attribdict[tag]: 514 f.write(" fCHECKFORGUEST();\n") 515 516 ## Read all the inputs 517 for regtype, regid in regs: 518 if hex_common.is_read(regid): 519 genptr_src_read_opn(f, regtype, regid, tag) 520 521 if hex_common.is_idef_parser_enabled(tag): 522 declared = [] 523 ## Handle registers 524 for regtype, regid in regs: 525 if hex_common.is_pair(regid) or ( 526 hex_common.is_single(regid) 527 and hex_common.is_old_val(regtype, regid, tag) 528 ): 529 declared.append(f"{regtype}{regid}V") 530 if regtype == "M": 531 declared.append(f"{regtype}{regid}N") 532 elif hex_common.is_new_val(regtype, regid, tag): 533 declared.append(f"{regtype}{regid}N") 534 else: 535 hex_common.bad_register(regtype, regid) 536 537 ## Handle immediates 538 for immlett, bits, immshift in imms: 539 declared.append(hex_common.imm_name(immlett)) 540 541 arguments = ", ".join(["ctx", "ctx->insn", "ctx->pkt"] + declared) 542 f.write(f" emit_{tag}({arguments});\n") 543 544 elif hex_common.skip_qemu_helper(tag): 545 f.write(f" fGEN_TCG_{tag}({hex_common.semdict[tag]});\n") 546 else: 547 ## Generate the call to the helper 548 for immlett, bits, immshift in imms: 549 gen_helper_decl_imm(f, immlett) 550 if hex_common.need_pkt_has_multi_cof(tag): 551 f.write(" TCGv pkt_has_multi_cof = ") 552 f.write("tcg_constant_tl(ctx->pkt->pkt_has_multi_cof);\n") 553 if hex_common.need_pkt_need_commit(tag): 554 f.write(" TCGv pkt_need_commit = ") 555 f.write("tcg_constant_tl(ctx->need_commit);\n") 556 if hex_common.need_part1(tag): 557 f.write(" TCGv part1 = tcg_constant_tl(insn->part1);\n") 558 if hex_common.need_slot(tag): 559 f.write(" TCGv slotval = gen_slotval(ctx);\n") 560 if hex_common.need_PC(tag): 561 f.write(" TCGv PC = tcg_constant_tl(ctx->pkt->pc);\n") 562 if hex_common.helper_needs_next_PC(tag): 563 f.write(" TCGv next_PC = tcg_constant_tl(ctx->next_PC);\n") 564 f.write(f" gen_helper_{tag}(") 565 i = 0 566 ## If there is a scalar result, it is the return type 567 for regtype, regid in regs: 568 if hex_common.is_written(regid): 569 if hex_common.is_hvx_reg(regtype): 570 continue 571 gen_helper_call_opn(f, tag, regtype, regid, i) 572 i += 1 573 if i > 0: 574 f.write(", ") 575 f.write("cpu_env") 576 i = 1 577 ## For conditional instructions, we pass in the destination register 578 if "A_CONDEXEC" in hex_common.attribdict[tag]: 579 for regtype, regid in regs: 580 if hex_common.is_writeonly(regid) and not hex_common.is_hvx_reg( 581 regtype 582 ): 583 gen_helper_call_opn(f, tag, regtype, regid, i) 584 i += 1 585 for regtype, regid in regs: 586 if hex_common.is_written(regid): 587 if not hex_common.is_hvx_reg(regtype): 588 continue 589 gen_helper_call_opn(f, tag, regtype, regid, i) 590 i += 1 591 for regtype, regid in regs: 592 if hex_common.is_read(regid): 593 if hex_common.is_hvx_reg(regtype) and hex_common.is_readwrite(regid): 594 continue 595 gen_helper_call_opn(f, tag, regtype, regid, i) 596 i += 1 597 for immlett, bits, immshift in imms: 598 gen_helper_call_imm(f, immlett) 599 600 if hex_common.need_pkt_has_multi_cof(tag): 601 f.write(", pkt_has_multi_cof") 602 if hex_common.need_pkt_need_commit(tag): 603 f.write(", pkt_need_commit") 604 if hex_common.need_PC(tag): 605 f.write(", PC") 606 if hex_common.helper_needs_next_PC(tag): 607 f.write(", next_PC") 608 if hex_common.need_slot(tag): 609 f.write(", slotval") 610 if hex_common.need_part1(tag): 611 f.write(", part1") 612 f.write(");\n") 613 614 ## Write all the outputs 615 for regtype, regid in regs: 616 if hex_common.is_written(regid): 617 genptr_dst_write_opn(f, regtype, regid, tag) 618 619 f.write("}\n\n") 620 621 622def gen_def_tcg_func(f, tag, tagregs, tagimms): 623 regs = tagregs[tag] 624 imms = tagimms[tag] 625 626 gen_tcg_func(f, tag, regs, imms) 627 628 629def main(): 630 hex_common.read_semantics_file(sys.argv[1]) 631 hex_common.read_attribs_file(sys.argv[2]) 632 hex_common.read_overrides_file(sys.argv[3]) 633 hex_common.read_overrides_file(sys.argv[4]) 634 hex_common.calculate_attribs() 635 ## Whether or not idef-parser is enabled is 636 ## determined by the number of arguments to 637 ## this script: 638 ## 639 ## 5 args. -> not enabled, 640 ## 6 args. -> idef-parser enabled. 641 ## 642 ## The 6:th arg. then holds a list of the successfully 643 ## parsed instructions. 644 is_idef_parser_enabled = len(sys.argv) > 6 645 if is_idef_parser_enabled: 646 hex_common.read_idef_parser_enabled_file(sys.argv[5]) 647 tagregs = hex_common.get_tagregs() 648 tagimms = hex_common.get_tagimms() 649 650 output_file = sys.argv[-1] 651 with open(output_file, "w") as f: 652 f.write("#ifndef HEXAGON_TCG_FUNCS_H\n") 653 f.write("#define HEXAGON_TCG_FUNCS_H\n\n") 654 if is_idef_parser_enabled: 655 f.write('#include "idef-generated-emitter.h.inc"\n\n') 656 657 for tag in hex_common.tags: 658 ## Skip the priv instructions 659 if "A_PRIV" in hex_common.attribdict[tag]: 660 continue 661 ## Skip the guest instructions 662 if "A_GUEST" in hex_common.attribdict[tag]: 663 continue 664 ## Skip the diag instructions 665 if tag == "Y6_diag": 666 continue 667 if tag == "Y6_diag0": 668 continue 669 if tag == "Y6_diag1": 670 continue 671 672 gen_def_tcg_func(f, tag, tagregs, tagimms) 673 674 f.write("#endif /* HEXAGON_TCG_FUNCS_H */\n") 675 676 677if __name__ == "__main__": 678 main() 679