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