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