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