1 /* 2 * Tiny Code Interpreter for QEMU 3 * 4 * Copyright (c) 2009, 2011, 2016 Stefan Weil 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 20 #include "qemu/osdep.h" 21 #include "tcg/tcg.h" 22 #include "tcg/tcg-ldst.h" 23 #include <ffi.h> 24 25 26 /* 27 * Enable TCI assertions only when debugging TCG (and without NDEBUG defined). 28 * Without assertions, the interpreter runs much faster. 29 */ 30 #if defined(CONFIG_DEBUG_TCG) 31 # define tci_assert(cond) assert(cond) 32 #else 33 # define tci_assert(cond) ((void)(cond)) 34 #endif 35 36 __thread uintptr_t tci_tb_ptr; 37 38 static void tci_write_reg64(tcg_target_ulong *regs, uint32_t high_index, 39 uint32_t low_index, uint64_t value) 40 { 41 regs[low_index] = (uint32_t)value; 42 regs[high_index] = value >> 32; 43 } 44 45 /* Create a 64 bit value from two 32 bit values. */ 46 static uint64_t tci_uint64(uint32_t high, uint32_t low) 47 { 48 return ((uint64_t)high << 32) + low; 49 } 50 51 /* 52 * Load sets of arguments all at once. The naming convention is: 53 * tci_args_<arguments> 54 * where arguments is a sequence of 55 * 56 * b = immediate (bit position) 57 * c = condition (TCGCond) 58 * i = immediate (uint32_t) 59 * I = immediate (tcg_target_ulong) 60 * l = label or pointer 61 * m = immediate (MemOpIdx) 62 * n = immediate (call return length) 63 * r = register 64 * s = signed ldst offset 65 */ 66 67 static void tci_args_l(uint32_t insn, const void *tb_ptr, void **l0) 68 { 69 int diff = sextract32(insn, 12, 20); 70 *l0 = diff ? (void *)tb_ptr + diff : NULL; 71 } 72 73 static void tci_args_r(uint32_t insn, TCGReg *r0) 74 { 75 *r0 = extract32(insn, 8, 4); 76 } 77 78 static void tci_args_nl(uint32_t insn, const void *tb_ptr, 79 uint8_t *n0, void **l1) 80 { 81 *n0 = extract32(insn, 8, 4); 82 *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr; 83 } 84 85 static void tci_args_rl(uint32_t insn, const void *tb_ptr, 86 TCGReg *r0, void **l1) 87 { 88 *r0 = extract32(insn, 8, 4); 89 *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr; 90 } 91 92 static void tci_args_rr(uint32_t insn, TCGReg *r0, TCGReg *r1) 93 { 94 *r0 = extract32(insn, 8, 4); 95 *r1 = extract32(insn, 12, 4); 96 } 97 98 static void tci_args_ri(uint32_t insn, TCGReg *r0, tcg_target_ulong *i1) 99 { 100 *r0 = extract32(insn, 8, 4); 101 *i1 = sextract32(insn, 12, 20); 102 } 103 104 static void tci_args_rrm(uint32_t insn, TCGReg *r0, 105 TCGReg *r1, MemOpIdx *m2) 106 { 107 *r0 = extract32(insn, 8, 4); 108 *r1 = extract32(insn, 12, 4); 109 *m2 = extract32(insn, 20, 12); 110 } 111 112 static void tci_args_rrr(uint32_t insn, TCGReg *r0, TCGReg *r1, TCGReg *r2) 113 { 114 *r0 = extract32(insn, 8, 4); 115 *r1 = extract32(insn, 12, 4); 116 *r2 = extract32(insn, 16, 4); 117 } 118 119 static void tci_args_rrs(uint32_t insn, TCGReg *r0, TCGReg *r1, int32_t *i2) 120 { 121 *r0 = extract32(insn, 8, 4); 122 *r1 = extract32(insn, 12, 4); 123 *i2 = sextract32(insn, 16, 16); 124 } 125 126 static void tci_args_rrbb(uint32_t insn, TCGReg *r0, TCGReg *r1, 127 uint8_t *i2, uint8_t *i3) 128 { 129 *r0 = extract32(insn, 8, 4); 130 *r1 = extract32(insn, 12, 4); 131 *i2 = extract32(insn, 16, 6); 132 *i3 = extract32(insn, 22, 6); 133 } 134 135 static void tci_args_rrrc(uint32_t insn, 136 TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3) 137 { 138 *r0 = extract32(insn, 8, 4); 139 *r1 = extract32(insn, 12, 4); 140 *r2 = extract32(insn, 16, 4); 141 *c3 = extract32(insn, 20, 4); 142 } 143 144 static void tci_args_rrrm(uint32_t insn, 145 TCGReg *r0, TCGReg *r1, TCGReg *r2, MemOpIdx *m3) 146 { 147 *r0 = extract32(insn, 8, 4); 148 *r1 = extract32(insn, 12, 4); 149 *r2 = extract32(insn, 16, 4); 150 *m3 = extract32(insn, 20, 12); 151 } 152 153 static void tci_args_rrrbb(uint32_t insn, TCGReg *r0, TCGReg *r1, 154 TCGReg *r2, uint8_t *i3, uint8_t *i4) 155 { 156 *r0 = extract32(insn, 8, 4); 157 *r1 = extract32(insn, 12, 4); 158 *r2 = extract32(insn, 16, 4); 159 *i3 = extract32(insn, 20, 6); 160 *i4 = extract32(insn, 26, 6); 161 } 162 163 static void tci_args_rrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1, 164 TCGReg *r2, TCGReg *r3, TCGReg *r4) 165 { 166 *r0 = extract32(insn, 8, 4); 167 *r1 = extract32(insn, 12, 4); 168 *r2 = extract32(insn, 16, 4); 169 *r3 = extract32(insn, 20, 4); 170 *r4 = extract32(insn, 24, 4); 171 } 172 173 static void tci_args_rrrr(uint32_t insn, 174 TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3) 175 { 176 *r0 = extract32(insn, 8, 4); 177 *r1 = extract32(insn, 12, 4); 178 *r2 = extract32(insn, 16, 4); 179 *r3 = extract32(insn, 20, 4); 180 } 181 182 static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1, 183 TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5) 184 { 185 *r0 = extract32(insn, 8, 4); 186 *r1 = extract32(insn, 12, 4); 187 *r2 = extract32(insn, 16, 4); 188 *r3 = extract32(insn, 20, 4); 189 *r4 = extract32(insn, 24, 4); 190 *c5 = extract32(insn, 28, 4); 191 } 192 193 static void tci_args_rrrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1, 194 TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGReg *r5) 195 { 196 *r0 = extract32(insn, 8, 4); 197 *r1 = extract32(insn, 12, 4); 198 *r2 = extract32(insn, 16, 4); 199 *r3 = extract32(insn, 20, 4); 200 *r4 = extract32(insn, 24, 4); 201 *r5 = extract32(insn, 28, 4); 202 } 203 204 static bool tci_compare32(uint32_t u0, uint32_t u1, TCGCond condition) 205 { 206 bool result = false; 207 int32_t i0 = u0; 208 int32_t i1 = u1; 209 switch (condition) { 210 case TCG_COND_EQ: 211 result = (u0 == u1); 212 break; 213 case TCG_COND_NE: 214 result = (u0 != u1); 215 break; 216 case TCG_COND_LT: 217 result = (i0 < i1); 218 break; 219 case TCG_COND_GE: 220 result = (i0 >= i1); 221 break; 222 case TCG_COND_LE: 223 result = (i0 <= i1); 224 break; 225 case TCG_COND_GT: 226 result = (i0 > i1); 227 break; 228 case TCG_COND_LTU: 229 result = (u0 < u1); 230 break; 231 case TCG_COND_GEU: 232 result = (u0 >= u1); 233 break; 234 case TCG_COND_LEU: 235 result = (u0 <= u1); 236 break; 237 case TCG_COND_GTU: 238 result = (u0 > u1); 239 break; 240 default: 241 g_assert_not_reached(); 242 } 243 return result; 244 } 245 246 static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition) 247 { 248 bool result = false; 249 int64_t i0 = u0; 250 int64_t i1 = u1; 251 switch (condition) { 252 case TCG_COND_EQ: 253 result = (u0 == u1); 254 break; 255 case TCG_COND_NE: 256 result = (u0 != u1); 257 break; 258 case TCG_COND_LT: 259 result = (i0 < i1); 260 break; 261 case TCG_COND_GE: 262 result = (i0 >= i1); 263 break; 264 case TCG_COND_LE: 265 result = (i0 <= i1); 266 break; 267 case TCG_COND_GT: 268 result = (i0 > i1); 269 break; 270 case TCG_COND_LTU: 271 result = (u0 < u1); 272 break; 273 case TCG_COND_GEU: 274 result = (u0 >= u1); 275 break; 276 case TCG_COND_LEU: 277 result = (u0 <= u1); 278 break; 279 case TCG_COND_GTU: 280 result = (u0 > u1); 281 break; 282 default: 283 g_assert_not_reached(); 284 } 285 return result; 286 } 287 288 static uint64_t tci_qemu_ld(CPUArchState *env, uint64_t taddr, 289 MemOpIdx oi, const void *tb_ptr) 290 { 291 MemOp mop = get_memop(oi); 292 uintptr_t ra = (uintptr_t)tb_ptr; 293 294 switch (mop & MO_SSIZE) { 295 case MO_UB: 296 return helper_ldub_mmu(env, taddr, oi, ra); 297 case MO_SB: 298 return helper_ldsb_mmu(env, taddr, oi, ra); 299 case MO_UW: 300 return helper_lduw_mmu(env, taddr, oi, ra); 301 case MO_SW: 302 return helper_ldsw_mmu(env, taddr, oi, ra); 303 case MO_UL: 304 return helper_ldul_mmu(env, taddr, oi, ra); 305 case MO_SL: 306 return helper_ldsl_mmu(env, taddr, oi, ra); 307 case MO_UQ: 308 return helper_ldq_mmu(env, taddr, oi, ra); 309 default: 310 g_assert_not_reached(); 311 } 312 } 313 314 static void tci_qemu_st(CPUArchState *env, uint64_t taddr, uint64_t val, 315 MemOpIdx oi, const void *tb_ptr) 316 { 317 MemOp mop = get_memop(oi); 318 uintptr_t ra = (uintptr_t)tb_ptr; 319 320 switch (mop & MO_SIZE) { 321 case MO_UB: 322 helper_stb_mmu(env, taddr, val, oi, ra); 323 break; 324 case MO_UW: 325 helper_stw_mmu(env, taddr, val, oi, ra); 326 break; 327 case MO_UL: 328 helper_stl_mmu(env, taddr, val, oi, ra); 329 break; 330 case MO_UQ: 331 helper_stq_mmu(env, taddr, val, oi, ra); 332 break; 333 default: 334 g_assert_not_reached(); 335 } 336 } 337 338 #if TCG_TARGET_REG_BITS == 64 339 # define CASE_32_64(x) \ 340 case glue(glue(INDEX_op_, x), _i64): \ 341 case glue(glue(INDEX_op_, x), _i32): 342 # define CASE_64(x) \ 343 case glue(glue(INDEX_op_, x), _i64): 344 #else 345 # define CASE_32_64(x) \ 346 case glue(glue(INDEX_op_, x), _i32): 347 # define CASE_64(x) 348 #endif 349 350 /* Interpret pseudo code in tb. */ 351 /* 352 * Disable CFI checks. 353 * One possible operation in the pseudo code is a call to binary code. 354 * Therefore, disable CFI checks in the interpreter function 355 */ 356 uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env, 357 const void *v_tb_ptr) 358 { 359 const uint32_t *tb_ptr = v_tb_ptr; 360 tcg_target_ulong regs[TCG_TARGET_NB_REGS]; 361 uint64_t stack[(TCG_STATIC_CALL_ARGS_SIZE + TCG_STATIC_FRAME_SIZE) 362 / sizeof(uint64_t)]; 363 364 regs[TCG_AREG0] = (tcg_target_ulong)env; 365 regs[TCG_REG_CALL_STACK] = (uintptr_t)stack; 366 tci_assert(tb_ptr); 367 368 for (;;) { 369 uint32_t insn; 370 TCGOpcode opc; 371 TCGReg r0, r1, r2, r3, r4, r5; 372 tcg_target_ulong t1; 373 TCGCond condition; 374 uint8_t pos, len; 375 uint32_t tmp32; 376 uint64_t tmp64, taddr; 377 uint64_t T1, T2; 378 MemOpIdx oi; 379 int32_t ofs; 380 void *ptr; 381 382 insn = *tb_ptr++; 383 opc = extract32(insn, 0, 8); 384 385 switch (opc) { 386 case INDEX_op_call: 387 { 388 void *call_slots[MAX_CALL_IARGS]; 389 ffi_cif *cif; 390 void *func; 391 unsigned i, s, n; 392 393 tci_args_nl(insn, tb_ptr, &len, &ptr); 394 func = ((void **)ptr)[0]; 395 cif = ((void **)ptr)[1]; 396 397 n = cif->nargs; 398 for (i = s = 0; i < n; ++i) { 399 ffi_type *t = cif->arg_types[i]; 400 call_slots[i] = &stack[s]; 401 s += DIV_ROUND_UP(t->size, 8); 402 } 403 404 /* Helper functions may need to access the "return address" */ 405 tci_tb_ptr = (uintptr_t)tb_ptr; 406 ffi_call(cif, func, stack, call_slots); 407 } 408 409 switch (len) { 410 case 0: /* void */ 411 break; 412 case 1: /* uint32_t */ 413 /* 414 * The result winds up "left-aligned" in the stack[0] slot. 415 * Note that libffi has an odd special case in that it will 416 * always widen an integral result to ffi_arg. 417 */ 418 if (sizeof(ffi_arg) == 8) { 419 regs[TCG_REG_R0] = (uint32_t)stack[0]; 420 } else { 421 regs[TCG_REG_R0] = *(uint32_t *)stack; 422 } 423 break; 424 case 2: /* uint64_t */ 425 /* 426 * For TCG_TARGET_REG_BITS == 32, the register pair 427 * must stay in host memory order. 428 */ 429 memcpy(®s[TCG_REG_R0], stack, 8); 430 break; 431 case 3: /* Int128 */ 432 memcpy(®s[TCG_REG_R0], stack, 16); 433 break; 434 default: 435 g_assert_not_reached(); 436 } 437 break; 438 439 case INDEX_op_br: 440 tci_args_l(insn, tb_ptr, &ptr); 441 tb_ptr = ptr; 442 continue; 443 case INDEX_op_setcond_i32: 444 tci_args_rrrc(insn, &r0, &r1, &r2, &condition); 445 regs[r0] = tci_compare32(regs[r1], regs[r2], condition); 446 break; 447 case INDEX_op_movcond_i32: 448 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition); 449 tmp32 = tci_compare32(regs[r1], regs[r2], condition); 450 regs[r0] = regs[tmp32 ? r3 : r4]; 451 break; 452 #if TCG_TARGET_REG_BITS == 32 453 case INDEX_op_setcond2_i32: 454 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition); 455 T1 = tci_uint64(regs[r2], regs[r1]); 456 T2 = tci_uint64(regs[r4], regs[r3]); 457 regs[r0] = tci_compare64(T1, T2, condition); 458 break; 459 #elif TCG_TARGET_REG_BITS == 64 460 case INDEX_op_setcond_i64: 461 tci_args_rrrc(insn, &r0, &r1, &r2, &condition); 462 regs[r0] = tci_compare64(regs[r1], regs[r2], condition); 463 break; 464 case INDEX_op_movcond_i64: 465 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition); 466 tmp32 = tci_compare64(regs[r1], regs[r2], condition); 467 regs[r0] = regs[tmp32 ? r3 : r4]; 468 break; 469 #endif 470 CASE_32_64(mov) 471 tci_args_rr(insn, &r0, &r1); 472 regs[r0] = regs[r1]; 473 break; 474 case INDEX_op_tci_movi: 475 tci_args_ri(insn, &r0, &t1); 476 regs[r0] = t1; 477 break; 478 case INDEX_op_tci_movl: 479 tci_args_rl(insn, tb_ptr, &r0, &ptr); 480 regs[r0] = *(tcg_target_ulong *)ptr; 481 break; 482 483 /* Load/store operations (32 bit). */ 484 485 CASE_32_64(ld8u) 486 tci_args_rrs(insn, &r0, &r1, &ofs); 487 ptr = (void *)(regs[r1] + ofs); 488 regs[r0] = *(uint8_t *)ptr; 489 break; 490 CASE_32_64(ld8s) 491 tci_args_rrs(insn, &r0, &r1, &ofs); 492 ptr = (void *)(regs[r1] + ofs); 493 regs[r0] = *(int8_t *)ptr; 494 break; 495 CASE_32_64(ld16u) 496 tci_args_rrs(insn, &r0, &r1, &ofs); 497 ptr = (void *)(regs[r1] + ofs); 498 regs[r0] = *(uint16_t *)ptr; 499 break; 500 CASE_32_64(ld16s) 501 tci_args_rrs(insn, &r0, &r1, &ofs); 502 ptr = (void *)(regs[r1] + ofs); 503 regs[r0] = *(int16_t *)ptr; 504 break; 505 case INDEX_op_ld_i32: 506 CASE_64(ld32u) 507 tci_args_rrs(insn, &r0, &r1, &ofs); 508 ptr = (void *)(regs[r1] + ofs); 509 regs[r0] = *(uint32_t *)ptr; 510 break; 511 CASE_32_64(st8) 512 tci_args_rrs(insn, &r0, &r1, &ofs); 513 ptr = (void *)(regs[r1] + ofs); 514 *(uint8_t *)ptr = regs[r0]; 515 break; 516 CASE_32_64(st16) 517 tci_args_rrs(insn, &r0, &r1, &ofs); 518 ptr = (void *)(regs[r1] + ofs); 519 *(uint16_t *)ptr = regs[r0]; 520 break; 521 case INDEX_op_st_i32: 522 CASE_64(st32) 523 tci_args_rrs(insn, &r0, &r1, &ofs); 524 ptr = (void *)(regs[r1] + ofs); 525 *(uint32_t *)ptr = regs[r0]; 526 break; 527 528 /* Arithmetic operations (mixed 32/64 bit). */ 529 530 CASE_32_64(add) 531 tci_args_rrr(insn, &r0, &r1, &r2); 532 regs[r0] = regs[r1] + regs[r2]; 533 break; 534 CASE_32_64(sub) 535 tci_args_rrr(insn, &r0, &r1, &r2); 536 regs[r0] = regs[r1] - regs[r2]; 537 break; 538 CASE_32_64(mul) 539 tci_args_rrr(insn, &r0, &r1, &r2); 540 regs[r0] = regs[r1] * regs[r2]; 541 break; 542 CASE_32_64(and) 543 tci_args_rrr(insn, &r0, &r1, &r2); 544 regs[r0] = regs[r1] & regs[r2]; 545 break; 546 CASE_32_64(or) 547 tci_args_rrr(insn, &r0, &r1, &r2); 548 regs[r0] = regs[r1] | regs[r2]; 549 break; 550 CASE_32_64(xor) 551 tci_args_rrr(insn, &r0, &r1, &r2); 552 regs[r0] = regs[r1] ^ regs[r2]; 553 break; 554 #if TCG_TARGET_HAS_andc_i32 || TCG_TARGET_HAS_andc_i64 555 CASE_32_64(andc) 556 tci_args_rrr(insn, &r0, &r1, &r2); 557 regs[r0] = regs[r1] & ~regs[r2]; 558 break; 559 #endif 560 #if TCG_TARGET_HAS_orc_i32 || TCG_TARGET_HAS_orc_i64 561 CASE_32_64(orc) 562 tci_args_rrr(insn, &r0, &r1, &r2); 563 regs[r0] = regs[r1] | ~regs[r2]; 564 break; 565 #endif 566 #if TCG_TARGET_HAS_eqv_i32 || TCG_TARGET_HAS_eqv_i64 567 CASE_32_64(eqv) 568 tci_args_rrr(insn, &r0, &r1, &r2); 569 regs[r0] = ~(regs[r1] ^ regs[r2]); 570 break; 571 #endif 572 #if TCG_TARGET_HAS_nand_i32 || TCG_TARGET_HAS_nand_i64 573 CASE_32_64(nand) 574 tci_args_rrr(insn, &r0, &r1, &r2); 575 regs[r0] = ~(regs[r1] & regs[r2]); 576 break; 577 #endif 578 #if TCG_TARGET_HAS_nor_i32 || TCG_TARGET_HAS_nor_i64 579 CASE_32_64(nor) 580 tci_args_rrr(insn, &r0, &r1, &r2); 581 regs[r0] = ~(regs[r1] | regs[r2]); 582 break; 583 #endif 584 585 /* Arithmetic operations (32 bit). */ 586 587 case INDEX_op_div_i32: 588 tci_args_rrr(insn, &r0, &r1, &r2); 589 regs[r0] = (int32_t)regs[r1] / (int32_t)regs[r2]; 590 break; 591 case INDEX_op_divu_i32: 592 tci_args_rrr(insn, &r0, &r1, &r2); 593 regs[r0] = (uint32_t)regs[r1] / (uint32_t)regs[r2]; 594 break; 595 case INDEX_op_rem_i32: 596 tci_args_rrr(insn, &r0, &r1, &r2); 597 regs[r0] = (int32_t)regs[r1] % (int32_t)regs[r2]; 598 break; 599 case INDEX_op_remu_i32: 600 tci_args_rrr(insn, &r0, &r1, &r2); 601 regs[r0] = (uint32_t)regs[r1] % (uint32_t)regs[r2]; 602 break; 603 #if TCG_TARGET_HAS_clz_i32 604 case INDEX_op_clz_i32: 605 tci_args_rrr(insn, &r0, &r1, &r2); 606 tmp32 = regs[r1]; 607 regs[r0] = tmp32 ? clz32(tmp32) : regs[r2]; 608 break; 609 #endif 610 #if TCG_TARGET_HAS_ctz_i32 611 case INDEX_op_ctz_i32: 612 tci_args_rrr(insn, &r0, &r1, &r2); 613 tmp32 = regs[r1]; 614 regs[r0] = tmp32 ? ctz32(tmp32) : regs[r2]; 615 break; 616 #endif 617 #if TCG_TARGET_HAS_ctpop_i32 618 case INDEX_op_ctpop_i32: 619 tci_args_rr(insn, &r0, &r1); 620 regs[r0] = ctpop32(regs[r1]); 621 break; 622 #endif 623 624 /* Shift/rotate operations (32 bit). */ 625 626 case INDEX_op_shl_i32: 627 tci_args_rrr(insn, &r0, &r1, &r2); 628 regs[r0] = (uint32_t)regs[r1] << (regs[r2] & 31); 629 break; 630 case INDEX_op_shr_i32: 631 tci_args_rrr(insn, &r0, &r1, &r2); 632 regs[r0] = (uint32_t)regs[r1] >> (regs[r2] & 31); 633 break; 634 case INDEX_op_sar_i32: 635 tci_args_rrr(insn, &r0, &r1, &r2); 636 regs[r0] = (int32_t)regs[r1] >> (regs[r2] & 31); 637 break; 638 #if TCG_TARGET_HAS_rot_i32 639 case INDEX_op_rotl_i32: 640 tci_args_rrr(insn, &r0, &r1, &r2); 641 regs[r0] = rol32(regs[r1], regs[r2] & 31); 642 break; 643 case INDEX_op_rotr_i32: 644 tci_args_rrr(insn, &r0, &r1, &r2); 645 regs[r0] = ror32(regs[r1], regs[r2] & 31); 646 break; 647 #endif 648 #if TCG_TARGET_HAS_deposit_i32 649 case INDEX_op_deposit_i32: 650 tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len); 651 regs[r0] = deposit32(regs[r1], pos, len, regs[r2]); 652 break; 653 #endif 654 #if TCG_TARGET_HAS_extract_i32 655 case INDEX_op_extract_i32: 656 tci_args_rrbb(insn, &r0, &r1, &pos, &len); 657 regs[r0] = extract32(regs[r1], pos, len); 658 break; 659 #endif 660 #if TCG_TARGET_HAS_sextract_i32 661 case INDEX_op_sextract_i32: 662 tci_args_rrbb(insn, &r0, &r1, &pos, &len); 663 regs[r0] = sextract32(regs[r1], pos, len); 664 break; 665 #endif 666 case INDEX_op_brcond_i32: 667 tci_args_rl(insn, tb_ptr, &r0, &ptr); 668 if ((uint32_t)regs[r0]) { 669 tb_ptr = ptr; 670 } 671 break; 672 #if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_add2_i32 673 case INDEX_op_add2_i32: 674 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5); 675 T1 = tci_uint64(regs[r3], regs[r2]); 676 T2 = tci_uint64(regs[r5], regs[r4]); 677 tci_write_reg64(regs, r1, r0, T1 + T2); 678 break; 679 #endif 680 #if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_sub2_i32 681 case INDEX_op_sub2_i32: 682 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5); 683 T1 = tci_uint64(regs[r3], regs[r2]); 684 T2 = tci_uint64(regs[r5], regs[r4]); 685 tci_write_reg64(regs, r1, r0, T1 - T2); 686 break; 687 #endif 688 #if TCG_TARGET_HAS_mulu2_i32 689 case INDEX_op_mulu2_i32: 690 tci_args_rrrr(insn, &r0, &r1, &r2, &r3); 691 tmp64 = (uint64_t)(uint32_t)regs[r2] * (uint32_t)regs[r3]; 692 tci_write_reg64(regs, r1, r0, tmp64); 693 break; 694 #endif 695 #if TCG_TARGET_HAS_muls2_i32 696 case INDEX_op_muls2_i32: 697 tci_args_rrrr(insn, &r0, &r1, &r2, &r3); 698 tmp64 = (int64_t)(int32_t)regs[r2] * (int32_t)regs[r3]; 699 tci_write_reg64(regs, r1, r0, tmp64); 700 break; 701 #endif 702 #if TCG_TARGET_HAS_ext8s_i32 || TCG_TARGET_HAS_ext8s_i64 703 CASE_32_64(ext8s) 704 tci_args_rr(insn, &r0, &r1); 705 regs[r0] = (int8_t)regs[r1]; 706 break; 707 #endif 708 #if TCG_TARGET_HAS_ext16s_i32 || TCG_TARGET_HAS_ext16s_i64 || \ 709 TCG_TARGET_HAS_bswap16_i32 || TCG_TARGET_HAS_bswap16_i64 710 CASE_32_64(ext16s) 711 tci_args_rr(insn, &r0, &r1); 712 regs[r0] = (int16_t)regs[r1]; 713 break; 714 #endif 715 #if TCG_TARGET_HAS_ext8u_i32 || TCG_TARGET_HAS_ext8u_i64 716 CASE_32_64(ext8u) 717 tci_args_rr(insn, &r0, &r1); 718 regs[r0] = (uint8_t)regs[r1]; 719 break; 720 #endif 721 #if TCG_TARGET_HAS_ext16u_i32 || TCG_TARGET_HAS_ext16u_i64 722 CASE_32_64(ext16u) 723 tci_args_rr(insn, &r0, &r1); 724 regs[r0] = (uint16_t)regs[r1]; 725 break; 726 #endif 727 #if TCG_TARGET_HAS_bswap16_i32 || TCG_TARGET_HAS_bswap16_i64 728 CASE_32_64(bswap16) 729 tci_args_rr(insn, &r0, &r1); 730 regs[r0] = bswap16(regs[r1]); 731 break; 732 #endif 733 #if TCG_TARGET_HAS_bswap32_i32 || TCG_TARGET_HAS_bswap32_i64 734 CASE_32_64(bswap32) 735 tci_args_rr(insn, &r0, &r1); 736 regs[r0] = bswap32(regs[r1]); 737 break; 738 #endif 739 #if TCG_TARGET_HAS_not_i32 || TCG_TARGET_HAS_not_i64 740 CASE_32_64(not) 741 tci_args_rr(insn, &r0, &r1); 742 regs[r0] = ~regs[r1]; 743 break; 744 #endif 745 #if TCG_TARGET_HAS_neg_i32 || TCG_TARGET_HAS_neg_i64 746 CASE_32_64(neg) 747 tci_args_rr(insn, &r0, &r1); 748 regs[r0] = -regs[r1]; 749 break; 750 #endif 751 #if TCG_TARGET_REG_BITS == 64 752 /* Load/store operations (64 bit). */ 753 754 case INDEX_op_ld32s_i64: 755 tci_args_rrs(insn, &r0, &r1, &ofs); 756 ptr = (void *)(regs[r1] + ofs); 757 regs[r0] = *(int32_t *)ptr; 758 break; 759 case INDEX_op_ld_i64: 760 tci_args_rrs(insn, &r0, &r1, &ofs); 761 ptr = (void *)(regs[r1] + ofs); 762 regs[r0] = *(uint64_t *)ptr; 763 break; 764 case INDEX_op_st_i64: 765 tci_args_rrs(insn, &r0, &r1, &ofs); 766 ptr = (void *)(regs[r1] + ofs); 767 *(uint64_t *)ptr = regs[r0]; 768 break; 769 770 /* Arithmetic operations (64 bit). */ 771 772 case INDEX_op_div_i64: 773 tci_args_rrr(insn, &r0, &r1, &r2); 774 regs[r0] = (int64_t)regs[r1] / (int64_t)regs[r2]; 775 break; 776 case INDEX_op_divu_i64: 777 tci_args_rrr(insn, &r0, &r1, &r2); 778 regs[r0] = (uint64_t)regs[r1] / (uint64_t)regs[r2]; 779 break; 780 case INDEX_op_rem_i64: 781 tci_args_rrr(insn, &r0, &r1, &r2); 782 regs[r0] = (int64_t)regs[r1] % (int64_t)regs[r2]; 783 break; 784 case INDEX_op_remu_i64: 785 tci_args_rrr(insn, &r0, &r1, &r2); 786 regs[r0] = (uint64_t)regs[r1] % (uint64_t)regs[r2]; 787 break; 788 #if TCG_TARGET_HAS_clz_i64 789 case INDEX_op_clz_i64: 790 tci_args_rrr(insn, &r0, &r1, &r2); 791 regs[r0] = regs[r1] ? clz64(regs[r1]) : regs[r2]; 792 break; 793 #endif 794 #if TCG_TARGET_HAS_ctz_i64 795 case INDEX_op_ctz_i64: 796 tci_args_rrr(insn, &r0, &r1, &r2); 797 regs[r0] = regs[r1] ? ctz64(regs[r1]) : regs[r2]; 798 break; 799 #endif 800 #if TCG_TARGET_HAS_ctpop_i64 801 case INDEX_op_ctpop_i64: 802 tci_args_rr(insn, &r0, &r1); 803 regs[r0] = ctpop64(regs[r1]); 804 break; 805 #endif 806 #if TCG_TARGET_HAS_mulu2_i64 807 case INDEX_op_mulu2_i64: 808 tci_args_rrrr(insn, &r0, &r1, &r2, &r3); 809 mulu64(®s[r0], ®s[r1], regs[r2], regs[r3]); 810 break; 811 #endif 812 #if TCG_TARGET_HAS_muls2_i64 813 case INDEX_op_muls2_i64: 814 tci_args_rrrr(insn, &r0, &r1, &r2, &r3); 815 muls64(®s[r0], ®s[r1], regs[r2], regs[r3]); 816 break; 817 #endif 818 #if TCG_TARGET_HAS_add2_i64 819 case INDEX_op_add2_i64: 820 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5); 821 T1 = regs[r2] + regs[r4]; 822 T2 = regs[r3] + regs[r5] + (T1 < regs[r2]); 823 regs[r0] = T1; 824 regs[r1] = T2; 825 break; 826 #endif 827 #if TCG_TARGET_HAS_add2_i64 828 case INDEX_op_sub2_i64: 829 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5); 830 T1 = regs[r2] - regs[r4]; 831 T2 = regs[r3] - regs[r5] - (regs[r2] < regs[r4]); 832 regs[r0] = T1; 833 regs[r1] = T2; 834 break; 835 #endif 836 837 /* Shift/rotate operations (64 bit). */ 838 839 case INDEX_op_shl_i64: 840 tci_args_rrr(insn, &r0, &r1, &r2); 841 regs[r0] = regs[r1] << (regs[r2] & 63); 842 break; 843 case INDEX_op_shr_i64: 844 tci_args_rrr(insn, &r0, &r1, &r2); 845 regs[r0] = regs[r1] >> (regs[r2] & 63); 846 break; 847 case INDEX_op_sar_i64: 848 tci_args_rrr(insn, &r0, &r1, &r2); 849 regs[r0] = (int64_t)regs[r1] >> (regs[r2] & 63); 850 break; 851 #if TCG_TARGET_HAS_rot_i64 852 case INDEX_op_rotl_i64: 853 tci_args_rrr(insn, &r0, &r1, &r2); 854 regs[r0] = rol64(regs[r1], regs[r2] & 63); 855 break; 856 case INDEX_op_rotr_i64: 857 tci_args_rrr(insn, &r0, &r1, &r2); 858 regs[r0] = ror64(regs[r1], regs[r2] & 63); 859 break; 860 #endif 861 #if TCG_TARGET_HAS_deposit_i64 862 case INDEX_op_deposit_i64: 863 tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len); 864 regs[r0] = deposit64(regs[r1], pos, len, regs[r2]); 865 break; 866 #endif 867 #if TCG_TARGET_HAS_extract_i64 868 case INDEX_op_extract_i64: 869 tci_args_rrbb(insn, &r0, &r1, &pos, &len); 870 regs[r0] = extract64(regs[r1], pos, len); 871 break; 872 #endif 873 #if TCG_TARGET_HAS_sextract_i64 874 case INDEX_op_sextract_i64: 875 tci_args_rrbb(insn, &r0, &r1, &pos, &len); 876 regs[r0] = sextract64(regs[r1], pos, len); 877 break; 878 #endif 879 case INDEX_op_brcond_i64: 880 tci_args_rl(insn, tb_ptr, &r0, &ptr); 881 if (regs[r0]) { 882 tb_ptr = ptr; 883 } 884 break; 885 case INDEX_op_ext32s_i64: 886 case INDEX_op_ext_i32_i64: 887 tci_args_rr(insn, &r0, &r1); 888 regs[r0] = (int32_t)regs[r1]; 889 break; 890 case INDEX_op_ext32u_i64: 891 case INDEX_op_extu_i32_i64: 892 tci_args_rr(insn, &r0, &r1); 893 regs[r0] = (uint32_t)regs[r1]; 894 break; 895 #if TCG_TARGET_HAS_bswap64_i64 896 case INDEX_op_bswap64_i64: 897 tci_args_rr(insn, &r0, &r1); 898 regs[r0] = bswap64(regs[r1]); 899 break; 900 #endif 901 #endif /* TCG_TARGET_REG_BITS == 64 */ 902 903 /* QEMU specific operations. */ 904 905 case INDEX_op_exit_tb: 906 tci_args_l(insn, tb_ptr, &ptr); 907 return (uintptr_t)ptr; 908 909 case INDEX_op_goto_tb: 910 tci_args_l(insn, tb_ptr, &ptr); 911 tb_ptr = *(void **)ptr; 912 break; 913 914 case INDEX_op_goto_ptr: 915 tci_args_r(insn, &r0); 916 ptr = (void *)regs[r0]; 917 if (!ptr) { 918 return 0; 919 } 920 tb_ptr = ptr; 921 break; 922 923 case INDEX_op_qemu_ld_a32_i32: 924 tci_args_rrm(insn, &r0, &r1, &oi); 925 taddr = (uint32_t)regs[r1]; 926 goto do_ld_i32; 927 case INDEX_op_qemu_ld_a64_i32: 928 if (TCG_TARGET_REG_BITS == 64) { 929 tci_args_rrm(insn, &r0, &r1, &oi); 930 taddr = regs[r1]; 931 } else { 932 tci_args_rrrm(insn, &r0, &r1, &r2, &oi); 933 taddr = tci_uint64(regs[r2], regs[r1]); 934 } 935 do_ld_i32: 936 regs[r0] = tci_qemu_ld(env, taddr, oi, tb_ptr); 937 break; 938 939 case INDEX_op_qemu_ld_a32_i64: 940 if (TCG_TARGET_REG_BITS == 64) { 941 tci_args_rrm(insn, &r0, &r1, &oi); 942 taddr = (uint32_t)regs[r1]; 943 } else { 944 tci_args_rrrm(insn, &r0, &r1, &r2, &oi); 945 taddr = (uint32_t)regs[r2]; 946 } 947 goto do_ld_i64; 948 case INDEX_op_qemu_ld_a64_i64: 949 if (TCG_TARGET_REG_BITS == 64) { 950 tci_args_rrm(insn, &r0, &r1, &oi); 951 taddr = regs[r1]; 952 } else { 953 tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4); 954 taddr = tci_uint64(regs[r3], regs[r2]); 955 oi = regs[r4]; 956 } 957 do_ld_i64: 958 tmp64 = tci_qemu_ld(env, taddr, oi, tb_ptr); 959 if (TCG_TARGET_REG_BITS == 32) { 960 tci_write_reg64(regs, r1, r0, tmp64); 961 } else { 962 regs[r0] = tmp64; 963 } 964 break; 965 966 case INDEX_op_qemu_st_a32_i32: 967 tci_args_rrm(insn, &r0, &r1, &oi); 968 taddr = (uint32_t)regs[r1]; 969 goto do_st_i32; 970 case INDEX_op_qemu_st_a64_i32: 971 if (TCG_TARGET_REG_BITS == 64) { 972 tci_args_rrm(insn, &r0, &r1, &oi); 973 taddr = regs[r1]; 974 } else { 975 tci_args_rrrm(insn, &r0, &r1, &r2, &oi); 976 taddr = tci_uint64(regs[r2], regs[r1]); 977 } 978 do_st_i32: 979 tci_qemu_st(env, taddr, regs[r0], oi, tb_ptr); 980 break; 981 982 case INDEX_op_qemu_st_a32_i64: 983 if (TCG_TARGET_REG_BITS == 64) { 984 tci_args_rrm(insn, &r0, &r1, &oi); 985 tmp64 = regs[r0]; 986 taddr = (uint32_t)regs[r1]; 987 } else { 988 tci_args_rrrm(insn, &r0, &r1, &r2, &oi); 989 tmp64 = tci_uint64(regs[r1], regs[r0]); 990 taddr = (uint32_t)regs[r2]; 991 } 992 goto do_st_i64; 993 case INDEX_op_qemu_st_a64_i64: 994 if (TCG_TARGET_REG_BITS == 64) { 995 tci_args_rrm(insn, &r0, &r1, &oi); 996 tmp64 = regs[r0]; 997 taddr = regs[r1]; 998 } else { 999 tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4); 1000 tmp64 = tci_uint64(regs[r1], regs[r0]); 1001 taddr = tci_uint64(regs[r3], regs[r2]); 1002 oi = regs[r4]; 1003 } 1004 do_st_i64: 1005 tci_qemu_st(env, taddr, tmp64, oi, tb_ptr); 1006 break; 1007 1008 case INDEX_op_mb: 1009 /* Ensure ordering for all kinds */ 1010 smp_mb(); 1011 break; 1012 default: 1013 g_assert_not_reached(); 1014 } 1015 } 1016 } 1017 1018 /* 1019 * Disassembler that matches the interpreter 1020 */ 1021 1022 static const char *str_r(TCGReg r) 1023 { 1024 static const char regs[TCG_TARGET_NB_REGS][4] = { 1025 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1026 "r8", "r9", "r10", "r11", "r12", "r13", "env", "sp" 1027 }; 1028 1029 QEMU_BUILD_BUG_ON(TCG_AREG0 != TCG_REG_R14); 1030 QEMU_BUILD_BUG_ON(TCG_REG_CALL_STACK != TCG_REG_R15); 1031 1032 assert((unsigned)r < TCG_TARGET_NB_REGS); 1033 return regs[r]; 1034 } 1035 1036 static const char *str_c(TCGCond c) 1037 { 1038 static const char cond[16][8] = { 1039 [TCG_COND_NEVER] = "never", 1040 [TCG_COND_ALWAYS] = "always", 1041 [TCG_COND_EQ] = "eq", 1042 [TCG_COND_NE] = "ne", 1043 [TCG_COND_LT] = "lt", 1044 [TCG_COND_GE] = "ge", 1045 [TCG_COND_LE] = "le", 1046 [TCG_COND_GT] = "gt", 1047 [TCG_COND_LTU] = "ltu", 1048 [TCG_COND_GEU] = "geu", 1049 [TCG_COND_LEU] = "leu", 1050 [TCG_COND_GTU] = "gtu", 1051 }; 1052 1053 assert((unsigned)c < ARRAY_SIZE(cond)); 1054 assert(cond[c][0] != 0); 1055 return cond[c]; 1056 } 1057 1058 /* Disassemble TCI bytecode. */ 1059 int print_insn_tci(bfd_vma addr, disassemble_info *info) 1060 { 1061 const uint32_t *tb_ptr = (const void *)(uintptr_t)addr; 1062 const TCGOpDef *def; 1063 const char *op_name; 1064 uint32_t insn; 1065 TCGOpcode op; 1066 TCGReg r0, r1, r2, r3, r4, r5; 1067 tcg_target_ulong i1; 1068 int32_t s2; 1069 TCGCond c; 1070 MemOpIdx oi; 1071 uint8_t pos, len; 1072 void *ptr; 1073 1074 /* TCI is always the host, so we don't need to load indirect. */ 1075 insn = *tb_ptr++; 1076 1077 info->fprintf_func(info->stream, "%08x ", insn); 1078 1079 op = extract32(insn, 0, 8); 1080 def = &tcg_op_defs[op]; 1081 op_name = def->name; 1082 1083 switch (op) { 1084 case INDEX_op_br: 1085 case INDEX_op_exit_tb: 1086 case INDEX_op_goto_tb: 1087 tci_args_l(insn, tb_ptr, &ptr); 1088 info->fprintf_func(info->stream, "%-12s %p", op_name, ptr); 1089 break; 1090 1091 case INDEX_op_goto_ptr: 1092 tci_args_r(insn, &r0); 1093 info->fprintf_func(info->stream, "%-12s %s", op_name, str_r(r0)); 1094 break; 1095 1096 case INDEX_op_call: 1097 tci_args_nl(insn, tb_ptr, &len, &ptr); 1098 info->fprintf_func(info->stream, "%-12s %d, %p", op_name, len, ptr); 1099 break; 1100 1101 case INDEX_op_brcond_i32: 1102 case INDEX_op_brcond_i64: 1103 tci_args_rl(insn, tb_ptr, &r0, &ptr); 1104 info->fprintf_func(info->stream, "%-12s %s, 0, ne, %p", 1105 op_name, str_r(r0), ptr); 1106 break; 1107 1108 case INDEX_op_setcond_i32: 1109 case INDEX_op_setcond_i64: 1110 tci_args_rrrc(insn, &r0, &r1, &r2, &c); 1111 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s", 1112 op_name, str_r(r0), str_r(r1), str_r(r2), str_c(c)); 1113 break; 1114 1115 case INDEX_op_tci_movi: 1116 tci_args_ri(insn, &r0, &i1); 1117 info->fprintf_func(info->stream, "%-12s %s, 0x%" TCG_PRIlx, 1118 op_name, str_r(r0), i1); 1119 break; 1120 1121 case INDEX_op_tci_movl: 1122 tci_args_rl(insn, tb_ptr, &r0, &ptr); 1123 info->fprintf_func(info->stream, "%-12s %s, %p", 1124 op_name, str_r(r0), ptr); 1125 break; 1126 1127 case INDEX_op_ld8u_i32: 1128 case INDEX_op_ld8u_i64: 1129 case INDEX_op_ld8s_i32: 1130 case INDEX_op_ld8s_i64: 1131 case INDEX_op_ld16u_i32: 1132 case INDEX_op_ld16u_i64: 1133 case INDEX_op_ld16s_i32: 1134 case INDEX_op_ld16s_i64: 1135 case INDEX_op_ld32u_i64: 1136 case INDEX_op_ld32s_i64: 1137 case INDEX_op_ld_i32: 1138 case INDEX_op_ld_i64: 1139 case INDEX_op_st8_i32: 1140 case INDEX_op_st8_i64: 1141 case INDEX_op_st16_i32: 1142 case INDEX_op_st16_i64: 1143 case INDEX_op_st32_i64: 1144 case INDEX_op_st_i32: 1145 case INDEX_op_st_i64: 1146 tci_args_rrs(insn, &r0, &r1, &s2); 1147 info->fprintf_func(info->stream, "%-12s %s, %s, %d", 1148 op_name, str_r(r0), str_r(r1), s2); 1149 break; 1150 1151 case INDEX_op_mov_i32: 1152 case INDEX_op_mov_i64: 1153 case INDEX_op_ext8s_i32: 1154 case INDEX_op_ext8s_i64: 1155 case INDEX_op_ext8u_i32: 1156 case INDEX_op_ext8u_i64: 1157 case INDEX_op_ext16s_i32: 1158 case INDEX_op_ext16s_i64: 1159 case INDEX_op_ext16u_i32: 1160 case INDEX_op_ext32s_i64: 1161 case INDEX_op_ext32u_i64: 1162 case INDEX_op_ext_i32_i64: 1163 case INDEX_op_extu_i32_i64: 1164 case INDEX_op_bswap16_i32: 1165 case INDEX_op_bswap16_i64: 1166 case INDEX_op_bswap32_i32: 1167 case INDEX_op_bswap32_i64: 1168 case INDEX_op_bswap64_i64: 1169 case INDEX_op_not_i32: 1170 case INDEX_op_not_i64: 1171 case INDEX_op_neg_i32: 1172 case INDEX_op_neg_i64: 1173 case INDEX_op_ctpop_i32: 1174 case INDEX_op_ctpop_i64: 1175 tci_args_rr(insn, &r0, &r1); 1176 info->fprintf_func(info->stream, "%-12s %s, %s", 1177 op_name, str_r(r0), str_r(r1)); 1178 break; 1179 1180 case INDEX_op_add_i32: 1181 case INDEX_op_add_i64: 1182 case INDEX_op_sub_i32: 1183 case INDEX_op_sub_i64: 1184 case INDEX_op_mul_i32: 1185 case INDEX_op_mul_i64: 1186 case INDEX_op_and_i32: 1187 case INDEX_op_and_i64: 1188 case INDEX_op_or_i32: 1189 case INDEX_op_or_i64: 1190 case INDEX_op_xor_i32: 1191 case INDEX_op_xor_i64: 1192 case INDEX_op_andc_i32: 1193 case INDEX_op_andc_i64: 1194 case INDEX_op_orc_i32: 1195 case INDEX_op_orc_i64: 1196 case INDEX_op_eqv_i32: 1197 case INDEX_op_eqv_i64: 1198 case INDEX_op_nand_i32: 1199 case INDEX_op_nand_i64: 1200 case INDEX_op_nor_i32: 1201 case INDEX_op_nor_i64: 1202 case INDEX_op_div_i32: 1203 case INDEX_op_div_i64: 1204 case INDEX_op_rem_i32: 1205 case INDEX_op_rem_i64: 1206 case INDEX_op_divu_i32: 1207 case INDEX_op_divu_i64: 1208 case INDEX_op_remu_i32: 1209 case INDEX_op_remu_i64: 1210 case INDEX_op_shl_i32: 1211 case INDEX_op_shl_i64: 1212 case INDEX_op_shr_i32: 1213 case INDEX_op_shr_i64: 1214 case INDEX_op_sar_i32: 1215 case INDEX_op_sar_i64: 1216 case INDEX_op_rotl_i32: 1217 case INDEX_op_rotl_i64: 1218 case INDEX_op_rotr_i32: 1219 case INDEX_op_rotr_i64: 1220 case INDEX_op_clz_i32: 1221 case INDEX_op_clz_i64: 1222 case INDEX_op_ctz_i32: 1223 case INDEX_op_ctz_i64: 1224 tci_args_rrr(insn, &r0, &r1, &r2); 1225 info->fprintf_func(info->stream, "%-12s %s, %s, %s", 1226 op_name, str_r(r0), str_r(r1), str_r(r2)); 1227 break; 1228 1229 case INDEX_op_deposit_i32: 1230 case INDEX_op_deposit_i64: 1231 tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len); 1232 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %d, %d", 1233 op_name, str_r(r0), str_r(r1), str_r(r2), pos, len); 1234 break; 1235 1236 case INDEX_op_extract_i32: 1237 case INDEX_op_extract_i64: 1238 case INDEX_op_sextract_i32: 1239 case INDEX_op_sextract_i64: 1240 tci_args_rrbb(insn, &r0, &r1, &pos, &len); 1241 info->fprintf_func(info->stream, "%-12s %s,%s,%d,%d", 1242 op_name, str_r(r0), str_r(r1), pos, len); 1243 break; 1244 1245 case INDEX_op_movcond_i32: 1246 case INDEX_op_movcond_i64: 1247 case INDEX_op_setcond2_i32: 1248 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &c); 1249 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s", 1250 op_name, str_r(r0), str_r(r1), str_r(r2), 1251 str_r(r3), str_r(r4), str_c(c)); 1252 break; 1253 1254 case INDEX_op_mulu2_i32: 1255 case INDEX_op_mulu2_i64: 1256 case INDEX_op_muls2_i32: 1257 case INDEX_op_muls2_i64: 1258 tci_args_rrrr(insn, &r0, &r1, &r2, &r3); 1259 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s", 1260 op_name, str_r(r0), str_r(r1), 1261 str_r(r2), str_r(r3)); 1262 break; 1263 1264 case INDEX_op_add2_i32: 1265 case INDEX_op_add2_i64: 1266 case INDEX_op_sub2_i32: 1267 case INDEX_op_sub2_i64: 1268 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5); 1269 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s", 1270 op_name, str_r(r0), str_r(r1), str_r(r2), 1271 str_r(r3), str_r(r4), str_r(r5)); 1272 break; 1273 1274 case INDEX_op_qemu_ld_a32_i32: 1275 case INDEX_op_qemu_st_a32_i32: 1276 len = 1 + 1; 1277 goto do_qemu_ldst; 1278 case INDEX_op_qemu_ld_a32_i64: 1279 case INDEX_op_qemu_st_a32_i64: 1280 case INDEX_op_qemu_ld_a64_i32: 1281 case INDEX_op_qemu_st_a64_i32: 1282 len = 1 + DIV_ROUND_UP(64, TCG_TARGET_REG_BITS); 1283 goto do_qemu_ldst; 1284 case INDEX_op_qemu_ld_a64_i64: 1285 case INDEX_op_qemu_st_a64_i64: 1286 len = 2 * DIV_ROUND_UP(64, TCG_TARGET_REG_BITS); 1287 goto do_qemu_ldst; 1288 do_qemu_ldst: 1289 switch (len) { 1290 case 2: 1291 tci_args_rrm(insn, &r0, &r1, &oi); 1292 info->fprintf_func(info->stream, "%-12s %s, %s, %x", 1293 op_name, str_r(r0), str_r(r1), oi); 1294 break; 1295 case 3: 1296 tci_args_rrrm(insn, &r0, &r1, &r2, &oi); 1297 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %x", 1298 op_name, str_r(r0), str_r(r1), str_r(r2), oi); 1299 break; 1300 case 4: 1301 tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4); 1302 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s", 1303 op_name, str_r(r0), str_r(r1), 1304 str_r(r2), str_r(r3), str_r(r4)); 1305 break; 1306 default: 1307 g_assert_not_reached(); 1308 } 1309 break; 1310 1311 case 0: 1312 /* tcg_out_nop_fill uses zeros */ 1313 if (insn == 0) { 1314 info->fprintf_func(info->stream, "align"); 1315 break; 1316 } 1317 /* fall through */ 1318 1319 default: 1320 info->fprintf_func(info->stream, "illegal opcode %d", op); 1321 break; 1322 } 1323 1324 return sizeof(insn); 1325 } 1326