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