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 extract_tr glue(extract, TCG_TARGET_REG_BITS) 31 #define sextract_tr glue(sextract, TCG_TARGET_REG_BITS) 32 33 /* 34 * Enable TCI assertions only when debugging TCG (and without NDEBUG defined). 35 * Without assertions, the interpreter runs much faster. 36 */ 37 #if defined(CONFIG_DEBUG_TCG) 38 # define tci_assert(cond) assert(cond) 39 #else 40 # define tci_assert(cond) ((void)(cond)) 41 #endif 42 43 __thread uintptr_t tci_tb_ptr; 44 45 static void tci_write_reg64(tcg_target_ulong *regs, uint32_t high_index, 46 uint32_t low_index, uint64_t value) 47 { 48 regs[low_index] = (uint32_t)value; 49 regs[high_index] = value >> 32; 50 } 51 52 /* Create a 64 bit value from two 32 bit values. */ 53 static uint64_t tci_uint64(uint32_t high, uint32_t low) 54 { 55 return ((uint64_t)high << 32) + low; 56 } 57 58 /* 59 * Load sets of arguments all at once. The naming convention is: 60 * tci_args_<arguments> 61 * where arguments is a sequence of 62 * 63 * b = immediate (bit position) 64 * c = condition (TCGCond) 65 * i = immediate (uint32_t) 66 * I = immediate (tcg_target_ulong) 67 * l = label or pointer 68 * m = immediate (MemOpIdx) 69 * n = immediate (call return length) 70 * r = register 71 * s = signed ldst offset 72 */ 73 74 static void tci_args_l(uint32_t insn, const void *tb_ptr, void **l0) 75 { 76 int diff = sextract32(insn, 12, 20); 77 *l0 = diff ? (void *)tb_ptr + diff : NULL; 78 } 79 80 static void tci_args_r(uint32_t insn, TCGReg *r0) 81 { 82 *r0 = extract32(insn, 8, 4); 83 } 84 85 static void tci_args_nl(uint32_t insn, const void *tb_ptr, 86 uint8_t *n0, void **l1) 87 { 88 *n0 = extract32(insn, 8, 4); 89 *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr; 90 } 91 92 static void tci_args_rl(uint32_t insn, const void *tb_ptr, 93 TCGReg *r0, void **l1) 94 { 95 *r0 = extract32(insn, 8, 4); 96 *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr; 97 } 98 99 static void tci_args_rr(uint32_t insn, TCGReg *r0, TCGReg *r1) 100 { 101 *r0 = extract32(insn, 8, 4); 102 *r1 = extract32(insn, 12, 4); 103 } 104 105 static void tci_args_ri(uint32_t insn, TCGReg *r0, tcg_target_ulong *i1) 106 { 107 *r0 = extract32(insn, 8, 4); 108 *i1 = sextract32(insn, 12, 20); 109 } 110 111 static void tci_args_rrm(uint32_t insn, TCGReg *r0, 112 TCGReg *r1, MemOpIdx *m2) 113 { 114 *r0 = extract32(insn, 8, 4); 115 *r1 = extract32(insn, 12, 4); 116 *m2 = extract32(insn, 16, 16); 117 } 118 119 static void tci_args_rrr(uint32_t insn, TCGReg *r0, TCGReg *r1, TCGReg *r2) 120 { 121 *r0 = extract32(insn, 8, 4); 122 *r1 = extract32(insn, 12, 4); 123 *r2 = extract32(insn, 16, 4); 124 } 125 126 static void tci_args_rrs(uint32_t insn, TCGReg *r0, TCGReg *r1, int32_t *i2) 127 { 128 *r0 = extract32(insn, 8, 4); 129 *r1 = extract32(insn, 12, 4); 130 *i2 = sextract32(insn, 16, 16); 131 } 132 133 static void tci_args_rrbb(uint32_t insn, TCGReg *r0, TCGReg *r1, 134 uint8_t *i2, uint8_t *i3) 135 { 136 *r0 = extract32(insn, 8, 4); 137 *r1 = extract32(insn, 12, 4); 138 *i2 = extract32(insn, 16, 6); 139 *i3 = extract32(insn, 22, 6); 140 } 141 142 static void tci_args_rrrc(uint32_t insn, 143 TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3) 144 { 145 *r0 = extract32(insn, 8, 4); 146 *r1 = extract32(insn, 12, 4); 147 *r2 = extract32(insn, 16, 4); 148 *c3 = extract32(insn, 20, 4); 149 } 150 151 static void tci_args_rrrbb(uint32_t insn, TCGReg *r0, TCGReg *r1, 152 TCGReg *r2, uint8_t *i3, uint8_t *i4) 153 { 154 *r0 = extract32(insn, 8, 4); 155 *r1 = extract32(insn, 12, 4); 156 *r2 = extract32(insn, 16, 4); 157 *i3 = extract32(insn, 20, 6); 158 *i4 = extract32(insn, 26, 6); 159 } 160 161 static void tci_args_rrrr(uint32_t insn, 162 TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3) 163 { 164 *r0 = extract32(insn, 8, 4); 165 *r1 = extract32(insn, 12, 4); 166 *r2 = extract32(insn, 16, 4); 167 *r3 = extract32(insn, 20, 4); 168 } 169 170 static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1, 171 TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5) 172 { 173 *r0 = extract32(insn, 8, 4); 174 *r1 = extract32(insn, 12, 4); 175 *r2 = extract32(insn, 16, 4); 176 *r3 = extract32(insn, 20, 4); 177 *r4 = extract32(insn, 24, 4); 178 *c5 = extract32(insn, 28, 4); 179 } 180 181 static void tci_args_rrrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1, 182 TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGReg *r5) 183 { 184 *r0 = extract32(insn, 8, 4); 185 *r1 = extract32(insn, 12, 4); 186 *r2 = extract32(insn, 16, 4); 187 *r3 = extract32(insn, 20, 4); 188 *r4 = extract32(insn, 24, 4); 189 *r5 = extract32(insn, 28, 4); 190 } 191 192 static bool tci_compare32(uint32_t u0, uint32_t u1, TCGCond condition) 193 { 194 bool result = false; 195 int32_t i0 = u0; 196 int32_t i1 = u1; 197 switch (condition) { 198 case TCG_COND_EQ: 199 result = (u0 == u1); 200 break; 201 case TCG_COND_NE: 202 result = (u0 != u1); 203 break; 204 case TCG_COND_LT: 205 result = (i0 < i1); 206 break; 207 case TCG_COND_GE: 208 result = (i0 >= i1); 209 break; 210 case TCG_COND_LE: 211 result = (i0 <= i1); 212 break; 213 case TCG_COND_GT: 214 result = (i0 > i1); 215 break; 216 case TCG_COND_LTU: 217 result = (u0 < u1); 218 break; 219 case TCG_COND_GEU: 220 result = (u0 >= u1); 221 break; 222 case TCG_COND_LEU: 223 result = (u0 <= u1); 224 break; 225 case TCG_COND_GTU: 226 result = (u0 > u1); 227 break; 228 case TCG_COND_TSTEQ: 229 result = (u0 & u1) == 0; 230 break; 231 case TCG_COND_TSTNE: 232 result = (u0 & u1) != 0; 233 break; 234 default: 235 g_assert_not_reached(); 236 } 237 return result; 238 } 239 240 static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition) 241 { 242 bool result = false; 243 int64_t i0 = u0; 244 int64_t i1 = u1; 245 switch (condition) { 246 case TCG_COND_EQ: 247 result = (u0 == u1); 248 break; 249 case TCG_COND_NE: 250 result = (u0 != u1); 251 break; 252 case TCG_COND_LT: 253 result = (i0 < i1); 254 break; 255 case TCG_COND_GE: 256 result = (i0 >= i1); 257 break; 258 case TCG_COND_LE: 259 result = (i0 <= i1); 260 break; 261 case TCG_COND_GT: 262 result = (i0 > i1); 263 break; 264 case TCG_COND_LTU: 265 result = (u0 < u1); 266 break; 267 case TCG_COND_GEU: 268 result = (u0 >= u1); 269 break; 270 case TCG_COND_LEU: 271 result = (u0 <= u1); 272 break; 273 case TCG_COND_GTU: 274 result = (u0 > u1); 275 break; 276 case TCG_COND_TSTEQ: 277 result = (u0 & u1) == 0; 278 break; 279 case TCG_COND_TSTNE: 280 result = (u0 & u1) != 0; 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 #if TCG_TARGET_REG_BITS == 32 444 case INDEX_op_setcond2_i32: 445 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition); 446 T1 = tci_uint64(regs[r2], regs[r1]); 447 T2 = tci_uint64(regs[r4], regs[r3]); 448 regs[r0] = tci_compare64(T1, T2, condition); 449 break; 450 #elif TCG_TARGET_REG_BITS == 64 451 case INDEX_op_setcond: 452 tci_args_rrrc(insn, &r0, &r1, &r2, &condition); 453 regs[r0] = tci_compare64(regs[r1], regs[r2], condition); 454 break; 455 case INDEX_op_movcond: 456 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition); 457 tmp32 = tci_compare64(regs[r1], regs[r2], condition); 458 regs[r0] = regs[tmp32 ? r3 : r4]; 459 break; 460 #endif 461 case INDEX_op_mov: 462 tci_args_rr(insn, &r0, &r1); 463 regs[r0] = regs[r1]; 464 break; 465 case INDEX_op_tci_movi: 466 tci_args_ri(insn, &r0, &t1); 467 regs[r0] = t1; 468 break; 469 case INDEX_op_tci_movl: 470 tci_args_rl(insn, tb_ptr, &r0, &ptr); 471 regs[r0] = *(tcg_target_ulong *)ptr; 472 break; 473 474 /* Load/store operations (32 bit). */ 475 476 CASE_32_64(ld8u) 477 tci_args_rrs(insn, &r0, &r1, &ofs); 478 ptr = (void *)(regs[r1] + ofs); 479 regs[r0] = *(uint8_t *)ptr; 480 break; 481 CASE_32_64(ld8s) 482 tci_args_rrs(insn, &r0, &r1, &ofs); 483 ptr = (void *)(regs[r1] + ofs); 484 regs[r0] = *(int8_t *)ptr; 485 break; 486 CASE_32_64(ld16u) 487 tci_args_rrs(insn, &r0, &r1, &ofs); 488 ptr = (void *)(regs[r1] + ofs); 489 regs[r0] = *(uint16_t *)ptr; 490 break; 491 CASE_32_64(ld16s) 492 tci_args_rrs(insn, &r0, &r1, &ofs); 493 ptr = (void *)(regs[r1] + ofs); 494 regs[r0] = *(int16_t *)ptr; 495 break; 496 case INDEX_op_ld_i32: 497 CASE_64(ld32u) 498 tci_args_rrs(insn, &r0, &r1, &ofs); 499 ptr = (void *)(regs[r1] + ofs); 500 regs[r0] = *(uint32_t *)ptr; 501 break; 502 CASE_32_64(st8) 503 tci_args_rrs(insn, &r0, &r1, &ofs); 504 ptr = (void *)(regs[r1] + ofs); 505 *(uint8_t *)ptr = regs[r0]; 506 break; 507 CASE_32_64(st16) 508 tci_args_rrs(insn, &r0, &r1, &ofs); 509 ptr = (void *)(regs[r1] + ofs); 510 *(uint16_t *)ptr = regs[r0]; 511 break; 512 case INDEX_op_st_i32: 513 CASE_64(st32) 514 tci_args_rrs(insn, &r0, &r1, &ofs); 515 ptr = (void *)(regs[r1] + ofs); 516 *(uint32_t *)ptr = regs[r0]; 517 break; 518 519 /* Arithmetic operations (mixed 32/64 bit). */ 520 521 case INDEX_op_add: 522 tci_args_rrr(insn, &r0, &r1, &r2); 523 regs[r0] = regs[r1] + regs[r2]; 524 break; 525 case INDEX_op_sub: 526 tci_args_rrr(insn, &r0, &r1, &r2); 527 regs[r0] = regs[r1] - regs[r2]; 528 break; 529 case INDEX_op_mul: 530 tci_args_rrr(insn, &r0, &r1, &r2); 531 regs[r0] = regs[r1] * regs[r2]; 532 break; 533 case INDEX_op_and: 534 tci_args_rrr(insn, &r0, &r1, &r2); 535 regs[r0] = regs[r1] & regs[r2]; 536 break; 537 case INDEX_op_or: 538 tci_args_rrr(insn, &r0, &r1, &r2); 539 regs[r0] = regs[r1] | regs[r2]; 540 break; 541 case INDEX_op_xor: 542 tci_args_rrr(insn, &r0, &r1, &r2); 543 regs[r0] = regs[r1] ^ regs[r2]; 544 break; 545 case INDEX_op_andc: 546 tci_args_rrr(insn, &r0, &r1, &r2); 547 regs[r0] = regs[r1] & ~regs[r2]; 548 break; 549 case INDEX_op_orc: 550 tci_args_rrr(insn, &r0, &r1, &r2); 551 regs[r0] = regs[r1] | ~regs[r2]; 552 break; 553 case INDEX_op_eqv: 554 tci_args_rrr(insn, &r0, &r1, &r2); 555 regs[r0] = ~(regs[r1] ^ regs[r2]); 556 break; 557 case INDEX_op_nand: 558 tci_args_rrr(insn, &r0, &r1, &r2); 559 regs[r0] = ~(regs[r1] & regs[r2]); 560 break; 561 case INDEX_op_nor: 562 tci_args_rrr(insn, &r0, &r1, &r2); 563 regs[r0] = ~(regs[r1] | regs[r2]); 564 break; 565 case INDEX_op_neg: 566 tci_args_rr(insn, &r0, &r1); 567 regs[r0] = -regs[r1]; 568 break; 569 case INDEX_op_not: 570 tci_args_rr(insn, &r0, &r1); 571 regs[r0] = ~regs[r1]; 572 break; 573 case INDEX_op_ctpop: 574 tci_args_rr(insn, &r0, &r1); 575 regs[r0] = ctpop_tr(regs[r1]); 576 break; 577 case INDEX_op_muls2: 578 tci_args_rrrr(insn, &r0, &r1, &r2, &r3); 579 #if TCG_TARGET_REG_BITS == 32 580 tmp64 = (int64_t)(int32_t)regs[r2] * (int32_t)regs[r3]; 581 tci_write_reg64(regs, r1, r0, tmp64); 582 #else 583 muls64(®s[r0], ®s[r1], regs[r2], regs[r3]); 584 #endif 585 break; 586 case INDEX_op_mulu2: 587 tci_args_rrrr(insn, &r0, &r1, &r2, &r3); 588 #if TCG_TARGET_REG_BITS == 32 589 tmp64 = (uint64_t)(uint32_t)regs[r2] * (uint32_t)regs[r3]; 590 tci_write_reg64(regs, r1, r0, tmp64); 591 #else 592 mulu64(®s[r0], ®s[r1], regs[r2], regs[r3]); 593 #endif 594 break; 595 596 /* Arithmetic operations (32 bit). */ 597 598 case INDEX_op_tci_divs32: 599 tci_args_rrr(insn, &r0, &r1, &r2); 600 regs[r0] = (int32_t)regs[r1] / (int32_t)regs[r2]; 601 break; 602 case INDEX_op_tci_divu32: 603 tci_args_rrr(insn, &r0, &r1, &r2); 604 regs[r0] = (uint32_t)regs[r1] / (uint32_t)regs[r2]; 605 break; 606 case INDEX_op_tci_rems32: 607 tci_args_rrr(insn, &r0, &r1, &r2); 608 regs[r0] = (int32_t)regs[r1] % (int32_t)regs[r2]; 609 break; 610 case INDEX_op_tci_remu32: 611 tci_args_rrr(insn, &r0, &r1, &r2); 612 regs[r0] = (uint32_t)regs[r1] % (uint32_t)regs[r2]; 613 break; 614 case INDEX_op_tci_clz32: 615 tci_args_rrr(insn, &r0, &r1, &r2); 616 tmp32 = regs[r1]; 617 regs[r0] = tmp32 ? clz32(tmp32) : regs[r2]; 618 break; 619 case INDEX_op_tci_ctz32: 620 tci_args_rrr(insn, &r0, &r1, &r2); 621 tmp32 = regs[r1]; 622 regs[r0] = tmp32 ? ctz32(tmp32) : regs[r2]; 623 break; 624 case INDEX_op_tci_setcond32: 625 tci_args_rrrc(insn, &r0, &r1, &r2, &condition); 626 regs[r0] = tci_compare32(regs[r1], regs[r2], condition); 627 break; 628 case INDEX_op_tci_movcond32: 629 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition); 630 tmp32 = tci_compare32(regs[r1], regs[r2], condition); 631 regs[r0] = regs[tmp32 ? r3 : r4]; 632 break; 633 634 /* Shift/rotate operations. */ 635 636 case INDEX_op_shl: 637 tci_args_rrr(insn, &r0, &r1, &r2); 638 regs[r0] = regs[r1] << (regs[r2] % TCG_TARGET_REG_BITS); 639 break; 640 case INDEX_op_shr: 641 tci_args_rrr(insn, &r0, &r1, &r2); 642 regs[r0] = regs[r1] >> (regs[r2] % TCG_TARGET_REG_BITS); 643 break; 644 case INDEX_op_sar: 645 tci_args_rrr(insn, &r0, &r1, &r2); 646 regs[r0] = ((tcg_target_long)regs[r1] 647 >> (regs[r2] % TCG_TARGET_REG_BITS)); 648 break; 649 case INDEX_op_tci_rotl32: 650 tci_args_rrr(insn, &r0, &r1, &r2); 651 regs[r0] = rol32(regs[r1], regs[r2] & 31); 652 break; 653 case INDEX_op_tci_rotr32: 654 tci_args_rrr(insn, &r0, &r1, &r2); 655 regs[r0] = ror32(regs[r1], regs[r2] & 31); 656 break; 657 case INDEX_op_deposit_i32: 658 tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len); 659 regs[r0] = deposit32(regs[r1], pos, len, regs[r2]); 660 break; 661 case INDEX_op_extract: 662 tci_args_rrbb(insn, &r0, &r1, &pos, &len); 663 regs[r0] = extract_tr(regs[r1], pos, len); 664 break; 665 case INDEX_op_sextract: 666 tci_args_rrbb(insn, &r0, &r1, &pos, &len); 667 regs[r0] = sextract_tr(regs[r1], pos, len); 668 break; 669 case INDEX_op_brcond: 670 tci_args_rl(insn, tb_ptr, &r0, &ptr); 671 if (regs[r0]) { 672 tb_ptr = ptr; 673 } 674 break; 675 #if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_add2_i32 676 case INDEX_op_add2_i32: 677 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5); 678 T1 = tci_uint64(regs[r3], regs[r2]); 679 T2 = tci_uint64(regs[r5], regs[r4]); 680 tci_write_reg64(regs, r1, r0, T1 + T2); 681 break; 682 #endif 683 #if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_sub2_i32 684 case INDEX_op_sub2_i32: 685 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5); 686 T1 = tci_uint64(regs[r3], regs[r2]); 687 T2 = tci_uint64(regs[r5], regs[r4]); 688 tci_write_reg64(regs, r1, r0, T1 - T2); 689 break; 690 #endif 691 case INDEX_op_bswap16: 692 tci_args_rr(insn, &r0, &r1); 693 regs[r0] = bswap16(regs[r1]); 694 break; 695 case INDEX_op_bswap32: 696 tci_args_rr(insn, &r0, &r1); 697 regs[r0] = bswap32(regs[r1]); 698 break; 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_add2_i64 745 case INDEX_op_add2_i64: 746 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5); 747 T1 = regs[r2] + regs[r4]; 748 T2 = regs[r3] + regs[r5] + (T1 < regs[r2]); 749 regs[r0] = T1; 750 regs[r1] = T2; 751 break; 752 #endif 753 #if TCG_TARGET_HAS_add2_i64 754 case INDEX_op_sub2_i64: 755 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5); 756 T1 = regs[r2] - regs[r4]; 757 T2 = regs[r3] - regs[r5] - (regs[r2] < regs[r4]); 758 regs[r0] = T1; 759 regs[r1] = T2; 760 break; 761 #endif 762 763 /* Shift/rotate operations (64 bit). */ 764 765 case INDEX_op_rotl: 766 tci_args_rrr(insn, &r0, &r1, &r2); 767 regs[r0] = rol64(regs[r1], regs[r2] & 63); 768 break; 769 case INDEX_op_rotr: 770 tci_args_rrr(insn, &r0, &r1, &r2); 771 regs[r0] = ror64(regs[r1], regs[r2] & 63); 772 break; 773 case INDEX_op_deposit_i64: 774 tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len); 775 regs[r0] = deposit64(regs[r1], pos, len, regs[r2]); 776 break; 777 case INDEX_op_ext_i32_i64: 778 tci_args_rr(insn, &r0, &r1); 779 regs[r0] = (int32_t)regs[r1]; 780 break; 781 case INDEX_op_extu_i32_i64: 782 tci_args_rr(insn, &r0, &r1); 783 regs[r0] = (uint32_t)regs[r1]; 784 break; 785 case INDEX_op_bswap64: 786 tci_args_rr(insn, &r0, &r1); 787 regs[r0] = bswap64(regs[r1]); 788 break; 789 #endif /* TCG_TARGET_REG_BITS == 64 */ 790 791 /* QEMU specific operations. */ 792 793 case INDEX_op_exit_tb: 794 tci_args_l(insn, tb_ptr, &ptr); 795 return (uintptr_t)ptr; 796 797 case INDEX_op_goto_tb: 798 tci_args_l(insn, tb_ptr, &ptr); 799 tb_ptr = *(void **)ptr; 800 break; 801 802 case INDEX_op_goto_ptr: 803 tci_args_r(insn, &r0); 804 ptr = (void *)regs[r0]; 805 if (!ptr) { 806 return 0; 807 } 808 tb_ptr = ptr; 809 break; 810 811 case INDEX_op_qemu_ld_i32: 812 tci_args_rrm(insn, &r0, &r1, &oi); 813 taddr = regs[r1]; 814 regs[r0] = tci_qemu_ld(env, taddr, oi, tb_ptr); 815 break; 816 817 case INDEX_op_qemu_ld_i64: 818 if (TCG_TARGET_REG_BITS == 64) { 819 tci_args_rrm(insn, &r0, &r1, &oi); 820 taddr = regs[r1]; 821 } else { 822 tci_args_rrrr(insn, &r0, &r1, &r2, &r3); 823 taddr = regs[r2]; 824 oi = regs[r3]; 825 } 826 tmp64 = tci_qemu_ld(env, taddr, oi, tb_ptr); 827 if (TCG_TARGET_REG_BITS == 32) { 828 tci_write_reg64(regs, r1, r0, tmp64); 829 } else { 830 regs[r0] = tmp64; 831 } 832 break; 833 834 case INDEX_op_qemu_st_i32: 835 tci_args_rrm(insn, &r0, &r1, &oi); 836 taddr = regs[r1]; 837 tci_qemu_st(env, taddr, regs[r0], oi, tb_ptr); 838 break; 839 840 case INDEX_op_qemu_st_i64: 841 if (TCG_TARGET_REG_BITS == 64) { 842 tci_args_rrm(insn, &r0, &r1, &oi); 843 tmp64 = regs[r0]; 844 taddr = regs[r1]; 845 } else { 846 tci_args_rrrr(insn, &r0, &r1, &r2, &r3); 847 tmp64 = tci_uint64(regs[r1], regs[r0]); 848 taddr = regs[r2]; 849 oi = regs[r3]; 850 } 851 tci_qemu_st(env, taddr, tmp64, oi, tb_ptr); 852 break; 853 854 case INDEX_op_mb: 855 /* Ensure ordering for all kinds */ 856 smp_mb(); 857 break; 858 default: 859 g_assert_not_reached(); 860 } 861 } 862 } 863 864 /* 865 * Disassembler that matches the interpreter 866 */ 867 868 static const char *str_r(TCGReg r) 869 { 870 static const char regs[TCG_TARGET_NB_REGS][4] = { 871 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 872 "r8", "r9", "r10", "r11", "r12", "r13", "env", "sp" 873 }; 874 875 QEMU_BUILD_BUG_ON(TCG_AREG0 != TCG_REG_R14); 876 QEMU_BUILD_BUG_ON(TCG_REG_CALL_STACK != TCG_REG_R15); 877 878 assert((unsigned)r < TCG_TARGET_NB_REGS); 879 return regs[r]; 880 } 881 882 static const char *str_c(TCGCond c) 883 { 884 static const char cond[16][8] = { 885 [TCG_COND_NEVER] = "never", 886 [TCG_COND_ALWAYS] = "always", 887 [TCG_COND_EQ] = "eq", 888 [TCG_COND_NE] = "ne", 889 [TCG_COND_LT] = "lt", 890 [TCG_COND_GE] = "ge", 891 [TCG_COND_LE] = "le", 892 [TCG_COND_GT] = "gt", 893 [TCG_COND_LTU] = "ltu", 894 [TCG_COND_GEU] = "geu", 895 [TCG_COND_LEU] = "leu", 896 [TCG_COND_GTU] = "gtu", 897 [TCG_COND_TSTEQ] = "tsteq", 898 [TCG_COND_TSTNE] = "tstne", 899 }; 900 901 assert((unsigned)c < ARRAY_SIZE(cond)); 902 assert(cond[c][0] != 0); 903 return cond[c]; 904 } 905 906 /* Disassemble TCI bytecode. */ 907 int print_insn_tci(bfd_vma addr, disassemble_info *info) 908 { 909 const uint32_t *tb_ptr = (const void *)(uintptr_t)addr; 910 const TCGOpDef *def; 911 const char *op_name; 912 uint32_t insn; 913 TCGOpcode op; 914 TCGReg r0, r1, r2, r3, r4, r5; 915 tcg_target_ulong i1; 916 int32_t s2; 917 TCGCond c; 918 MemOpIdx oi; 919 uint8_t pos, len; 920 void *ptr; 921 922 /* TCI is always the host, so we don't need to load indirect. */ 923 insn = *tb_ptr++; 924 925 info->fprintf_func(info->stream, "%08x ", insn); 926 927 op = extract32(insn, 0, 8); 928 def = &tcg_op_defs[op]; 929 op_name = def->name; 930 931 switch (op) { 932 case INDEX_op_br: 933 case INDEX_op_exit_tb: 934 case INDEX_op_goto_tb: 935 tci_args_l(insn, tb_ptr, &ptr); 936 info->fprintf_func(info->stream, "%-12s %p", op_name, ptr); 937 break; 938 939 case INDEX_op_goto_ptr: 940 tci_args_r(insn, &r0); 941 info->fprintf_func(info->stream, "%-12s %s", op_name, str_r(r0)); 942 break; 943 944 case INDEX_op_call: 945 tci_args_nl(insn, tb_ptr, &len, &ptr); 946 info->fprintf_func(info->stream, "%-12s %d, %p", op_name, len, ptr); 947 break; 948 949 case INDEX_op_brcond: 950 tci_args_rl(insn, tb_ptr, &r0, &ptr); 951 info->fprintf_func(info->stream, "%-12s %s, 0, ne, %p", 952 op_name, str_r(r0), ptr); 953 break; 954 955 case INDEX_op_setcond: 956 case INDEX_op_tci_setcond32: 957 tci_args_rrrc(insn, &r0, &r1, &r2, &c); 958 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s", 959 op_name, str_r(r0), str_r(r1), str_r(r2), str_c(c)); 960 break; 961 962 case INDEX_op_tci_movi: 963 tci_args_ri(insn, &r0, &i1); 964 info->fprintf_func(info->stream, "%-12s %s, 0x%" TCG_PRIlx, 965 op_name, str_r(r0), i1); 966 break; 967 968 case INDEX_op_tci_movl: 969 tci_args_rl(insn, tb_ptr, &r0, &ptr); 970 info->fprintf_func(info->stream, "%-12s %s, %p", 971 op_name, str_r(r0), ptr); 972 break; 973 974 case INDEX_op_ld8u_i32: 975 case INDEX_op_ld8u_i64: 976 case INDEX_op_ld8s_i32: 977 case INDEX_op_ld8s_i64: 978 case INDEX_op_ld16u_i32: 979 case INDEX_op_ld16u_i64: 980 case INDEX_op_ld16s_i32: 981 case INDEX_op_ld16s_i64: 982 case INDEX_op_ld32u_i64: 983 case INDEX_op_ld32s_i64: 984 case INDEX_op_ld_i32: 985 case INDEX_op_ld_i64: 986 case INDEX_op_st8_i32: 987 case INDEX_op_st8_i64: 988 case INDEX_op_st16_i32: 989 case INDEX_op_st16_i64: 990 case INDEX_op_st32_i64: 991 case INDEX_op_st_i32: 992 case INDEX_op_st_i64: 993 tci_args_rrs(insn, &r0, &r1, &s2); 994 info->fprintf_func(info->stream, "%-12s %s, %s, %d", 995 op_name, str_r(r0), str_r(r1), s2); 996 break; 997 998 case INDEX_op_bswap16: 999 case INDEX_op_bswap32: 1000 case INDEX_op_ctpop: 1001 case INDEX_op_mov: 1002 case INDEX_op_neg: 1003 case INDEX_op_not: 1004 case INDEX_op_ext_i32_i64: 1005 case INDEX_op_extu_i32_i64: 1006 case INDEX_op_bswap64: 1007 tci_args_rr(insn, &r0, &r1); 1008 info->fprintf_func(info->stream, "%-12s %s, %s", 1009 op_name, str_r(r0), str_r(r1)); 1010 break; 1011 1012 case INDEX_op_add: 1013 case INDEX_op_and: 1014 case INDEX_op_andc: 1015 case INDEX_op_clz: 1016 case INDEX_op_ctz: 1017 case INDEX_op_divs: 1018 case INDEX_op_divu: 1019 case INDEX_op_eqv: 1020 case INDEX_op_mul: 1021 case INDEX_op_nand: 1022 case INDEX_op_nor: 1023 case INDEX_op_or: 1024 case INDEX_op_orc: 1025 case INDEX_op_rems: 1026 case INDEX_op_remu: 1027 case INDEX_op_rotl: 1028 case INDEX_op_rotr: 1029 case INDEX_op_sar: 1030 case INDEX_op_shl: 1031 case INDEX_op_shr: 1032 case INDEX_op_sub: 1033 case INDEX_op_xor: 1034 case INDEX_op_tci_ctz32: 1035 case INDEX_op_tci_clz32: 1036 case INDEX_op_tci_divs32: 1037 case INDEX_op_tci_divu32: 1038 case INDEX_op_tci_rems32: 1039 case INDEX_op_tci_remu32: 1040 case INDEX_op_tci_rotl32: 1041 case INDEX_op_tci_rotr32: 1042 tci_args_rrr(insn, &r0, &r1, &r2); 1043 info->fprintf_func(info->stream, "%-12s %s, %s, %s", 1044 op_name, str_r(r0), str_r(r1), str_r(r2)); 1045 break; 1046 1047 case INDEX_op_deposit_i32: 1048 case INDEX_op_deposit_i64: 1049 tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len); 1050 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %d, %d", 1051 op_name, str_r(r0), str_r(r1), str_r(r2), pos, len); 1052 break; 1053 1054 case INDEX_op_extract: 1055 case INDEX_op_sextract: 1056 tci_args_rrbb(insn, &r0, &r1, &pos, &len); 1057 info->fprintf_func(info->stream, "%-12s %s,%s,%d,%d", 1058 op_name, str_r(r0), str_r(r1), pos, len); 1059 break; 1060 1061 case INDEX_op_tci_movcond32: 1062 case INDEX_op_movcond: 1063 case INDEX_op_setcond2_i32: 1064 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &c); 1065 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s", 1066 op_name, str_r(r0), str_r(r1), str_r(r2), 1067 str_r(r3), str_r(r4), str_c(c)); 1068 break; 1069 1070 case INDEX_op_muls2: 1071 case INDEX_op_mulu2: 1072 tci_args_rrrr(insn, &r0, &r1, &r2, &r3); 1073 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s", 1074 op_name, str_r(r0), str_r(r1), 1075 str_r(r2), str_r(r3)); 1076 break; 1077 1078 case INDEX_op_add2_i32: 1079 case INDEX_op_add2_i64: 1080 case INDEX_op_sub2_i32: 1081 case INDEX_op_sub2_i64: 1082 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5); 1083 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s", 1084 op_name, str_r(r0), str_r(r1), str_r(r2), 1085 str_r(r3), str_r(r4), str_r(r5)); 1086 break; 1087 1088 case INDEX_op_qemu_ld_i64: 1089 case INDEX_op_qemu_st_i64: 1090 if (TCG_TARGET_REG_BITS == 32) { 1091 tci_args_rrrr(insn, &r0, &r1, &r2, &r3); 1092 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s", 1093 op_name, str_r(r0), str_r(r1), 1094 str_r(r2), str_r(r3)); 1095 break; 1096 } 1097 /* fall through */ 1098 case INDEX_op_qemu_ld_i32: 1099 case INDEX_op_qemu_st_i32: 1100 tci_args_rrm(insn, &r0, &r1, &oi); 1101 info->fprintf_func(info->stream, "%-12s %s, %s, %x", 1102 op_name, str_r(r0), str_r(r1), oi); 1103 break; 1104 1105 case 0: 1106 /* tcg_out_nop_fill uses zeros */ 1107 if (insn == 0) { 1108 info->fprintf_func(info->stream, "align"); 1109 break; 1110 } 1111 /* fall through */ 1112 1113 default: 1114 info->fprintf_func(info->stream, "illegal opcode %d", op); 1115 break; 1116 } 1117 1118 return sizeof(insn); 1119 } 1120