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