1/* 2 * Tiny Code Generator for QEMU 3 * 4 * Copyright (c) 2009, 2011 Stefan Weil 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25#include "../tcg-pool.c.inc" 26 27static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op) 28{ 29 switch (op) { 30 case INDEX_op_goto_ptr: 31 return C_O0_I1(r); 32 33 case INDEX_op_ld8u_i32: 34 case INDEX_op_ld8s_i32: 35 case INDEX_op_ld16u_i32: 36 case INDEX_op_ld16s_i32: 37 case INDEX_op_ld_i32: 38 case INDEX_op_ld8u_i64: 39 case INDEX_op_ld8s_i64: 40 case INDEX_op_ld16u_i64: 41 case INDEX_op_ld16s_i64: 42 case INDEX_op_ld32u_i64: 43 case INDEX_op_ld32s_i64: 44 case INDEX_op_ld_i64: 45 case INDEX_op_not_i32: 46 case INDEX_op_not_i64: 47 case INDEX_op_neg_i32: 48 case INDEX_op_neg_i64: 49 case INDEX_op_ext8s_i32: 50 case INDEX_op_ext8s_i64: 51 case INDEX_op_ext16s_i32: 52 case INDEX_op_ext16s_i64: 53 case INDEX_op_ext8u_i32: 54 case INDEX_op_ext8u_i64: 55 case INDEX_op_ext16u_i32: 56 case INDEX_op_ext16u_i64: 57 case INDEX_op_ext32s_i64: 58 case INDEX_op_ext32u_i64: 59 case INDEX_op_ext_i32_i64: 60 case INDEX_op_extu_i32_i64: 61 case INDEX_op_bswap16_i32: 62 case INDEX_op_bswap16_i64: 63 case INDEX_op_bswap32_i32: 64 case INDEX_op_bswap32_i64: 65 case INDEX_op_bswap64_i64: 66 case INDEX_op_extract_i32: 67 case INDEX_op_extract_i64: 68 case INDEX_op_sextract_i32: 69 case INDEX_op_sextract_i64: 70 case INDEX_op_ctpop_i32: 71 case INDEX_op_ctpop_i64: 72 return C_O1_I1(r, r); 73 74 case INDEX_op_st8_i32: 75 case INDEX_op_st16_i32: 76 case INDEX_op_st_i32: 77 case INDEX_op_st8_i64: 78 case INDEX_op_st16_i64: 79 case INDEX_op_st32_i64: 80 case INDEX_op_st_i64: 81 return C_O0_I2(r, r); 82 83 case INDEX_op_div_i32: 84 case INDEX_op_div_i64: 85 case INDEX_op_divu_i32: 86 case INDEX_op_divu_i64: 87 case INDEX_op_rem_i32: 88 case INDEX_op_rem_i64: 89 case INDEX_op_remu_i32: 90 case INDEX_op_remu_i64: 91 case INDEX_op_add_i32: 92 case INDEX_op_add_i64: 93 case INDEX_op_sub_i32: 94 case INDEX_op_sub_i64: 95 case INDEX_op_mul_i32: 96 case INDEX_op_mul_i64: 97 case INDEX_op_and_i32: 98 case INDEX_op_and_i64: 99 case INDEX_op_andc_i32: 100 case INDEX_op_andc_i64: 101 case INDEX_op_eqv_i32: 102 case INDEX_op_eqv_i64: 103 case INDEX_op_nand_i32: 104 case INDEX_op_nand_i64: 105 case INDEX_op_nor_i32: 106 case INDEX_op_nor_i64: 107 case INDEX_op_or_i32: 108 case INDEX_op_or_i64: 109 case INDEX_op_orc_i32: 110 case INDEX_op_orc_i64: 111 case INDEX_op_xor_i32: 112 case INDEX_op_xor_i64: 113 case INDEX_op_shl_i32: 114 case INDEX_op_shl_i64: 115 case INDEX_op_shr_i32: 116 case INDEX_op_shr_i64: 117 case INDEX_op_sar_i32: 118 case INDEX_op_sar_i64: 119 case INDEX_op_rotl_i32: 120 case INDEX_op_rotl_i64: 121 case INDEX_op_rotr_i32: 122 case INDEX_op_rotr_i64: 123 case INDEX_op_setcond_i32: 124 case INDEX_op_setcond_i64: 125 case INDEX_op_deposit_i32: 126 case INDEX_op_deposit_i64: 127 case INDEX_op_clz_i32: 128 case INDEX_op_clz_i64: 129 case INDEX_op_ctz_i32: 130 case INDEX_op_ctz_i64: 131 return C_O1_I2(r, r, r); 132 133 case INDEX_op_brcond_i32: 134 case INDEX_op_brcond_i64: 135 return C_O0_I2(r, r); 136 137 case INDEX_op_add2_i32: 138 case INDEX_op_add2_i64: 139 case INDEX_op_sub2_i32: 140 case INDEX_op_sub2_i64: 141 return C_O2_I4(r, r, r, r, r, r); 142 143#if TCG_TARGET_REG_BITS == 32 144 case INDEX_op_brcond2_i32: 145 return C_O0_I4(r, r, r, r); 146#endif 147 148 case INDEX_op_mulu2_i32: 149 case INDEX_op_mulu2_i64: 150 case INDEX_op_muls2_i32: 151 case INDEX_op_muls2_i64: 152 return C_O2_I2(r, r, r, r); 153 154 case INDEX_op_movcond_i32: 155 case INDEX_op_movcond_i64: 156 case INDEX_op_setcond2_i32: 157 return C_O1_I4(r, r, r, r, r); 158 159 case INDEX_op_qemu_ld_i32: 160 return (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS 161 ? C_O1_I1(r, r) 162 : C_O1_I2(r, r, r)); 163 case INDEX_op_qemu_ld_i64: 164 return (TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) 165 : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? C_O2_I1(r, r, r) 166 : C_O2_I2(r, r, r, r)); 167 case INDEX_op_qemu_st_i32: 168 return (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS 169 ? C_O0_I2(r, r) 170 : C_O0_I3(r, r, r)); 171 case INDEX_op_qemu_st_i64: 172 return (TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) 173 : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? C_O0_I3(r, r, r) 174 : C_O0_I4(r, r, r, r)); 175 176 default: 177 g_assert_not_reached(); 178 } 179} 180 181static const int tcg_target_reg_alloc_order[] = { 182 TCG_REG_R2, 183 TCG_REG_R3, 184 TCG_REG_R4, 185 TCG_REG_R5, 186 TCG_REG_R6, 187 TCG_REG_R7, 188 TCG_REG_R8, 189 TCG_REG_R9, 190 TCG_REG_R10, 191 TCG_REG_R11, 192 TCG_REG_R12, 193 TCG_REG_R13, 194 TCG_REG_R14, 195 TCG_REG_R15, 196 TCG_REG_R1, 197 TCG_REG_R0, 198}; 199 200#if MAX_OPC_PARAM_IARGS != 7 201# error Fix needed, number of supported input arguments changed! 202#endif 203 204/* No call arguments via registers. All will be stored on the "stack". */ 205static const int tcg_target_call_iarg_regs[] = { }; 206 207static const int tcg_target_call_oarg_regs[] = { 208 TCG_REG_R0, 209#if TCG_TARGET_REG_BITS == 32 210 TCG_REG_R1 211#endif 212}; 213 214#ifdef CONFIG_DEBUG_TCG 215static const char *const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { 216 "r00", 217 "r01", 218 "r02", 219 "r03", 220 "r04", 221 "r05", 222 "r06", 223 "r07", 224 "r08", 225 "r09", 226 "r10", 227 "r11", 228 "r12", 229 "r13", 230 "r14", 231 "r15", 232}; 233#endif 234 235static bool patch_reloc(tcg_insn_unit *code_ptr, int type, 236 intptr_t value, intptr_t addend) 237{ 238 intptr_t diff = value - (intptr_t)(code_ptr + 1); 239 240 tcg_debug_assert(addend == 0); 241 tcg_debug_assert(type == 20); 242 243 if (diff == sextract32(diff, 0, type)) { 244 tcg_patch32(code_ptr, deposit32(*code_ptr, 32 - type, type, diff)); 245 return true; 246 } 247 return false; 248} 249 250static void stack_bounds_check(TCGReg base, target_long offset) 251{ 252 if (base == TCG_REG_CALL_STACK) { 253 tcg_debug_assert(offset >= 0); 254 tcg_debug_assert(offset < (TCG_STATIC_CALL_ARGS_SIZE + 255 TCG_STATIC_FRAME_SIZE)); 256 } 257} 258 259static void tcg_out_op_l(TCGContext *s, TCGOpcode op, TCGLabel *l0) 260{ 261 tcg_insn_unit insn = 0; 262 263 tcg_out_reloc(s, s->code_ptr, 20, l0, 0); 264 insn = deposit32(insn, 0, 8, op); 265 tcg_out32(s, insn); 266} 267 268static void tcg_out_op_p(TCGContext *s, TCGOpcode op, void *p0) 269{ 270 tcg_insn_unit insn = 0; 271 intptr_t diff; 272 273 /* Special case for exit_tb: map null -> 0. */ 274 if (p0 == NULL) { 275 diff = 0; 276 } else { 277 diff = p0 - (void *)(s->code_ptr + 1); 278 tcg_debug_assert(diff != 0); 279 if (diff != sextract32(diff, 0, 20)) { 280 tcg_raise_tb_overflow(s); 281 } 282 } 283 insn = deposit32(insn, 0, 8, op); 284 insn = deposit32(insn, 12, 20, diff); 285 tcg_out32(s, insn); 286} 287 288static void tcg_out_op_r(TCGContext *s, TCGOpcode op, TCGReg r0) 289{ 290 tcg_insn_unit insn = 0; 291 292 insn = deposit32(insn, 0, 8, op); 293 insn = deposit32(insn, 8, 4, r0); 294 tcg_out32(s, insn); 295} 296 297static void tcg_out_op_v(TCGContext *s, TCGOpcode op) 298{ 299 tcg_out32(s, (uint8_t)op); 300} 301 302static void tcg_out_op_ri(TCGContext *s, TCGOpcode op, TCGReg r0, int32_t i1) 303{ 304 tcg_insn_unit insn = 0; 305 306 tcg_debug_assert(i1 == sextract32(i1, 0, 20)); 307 insn = deposit32(insn, 0, 8, op); 308 insn = deposit32(insn, 8, 4, r0); 309 insn = deposit32(insn, 12, 20, i1); 310 tcg_out32(s, insn); 311} 312 313static void tcg_out_op_rl(TCGContext *s, TCGOpcode op, TCGReg r0, TCGLabel *l1) 314{ 315 tcg_insn_unit insn = 0; 316 317 tcg_out_reloc(s, s->code_ptr, 20, l1, 0); 318 insn = deposit32(insn, 0, 8, op); 319 insn = deposit32(insn, 8, 4, r0); 320 tcg_out32(s, insn); 321} 322 323static void tcg_out_op_rr(TCGContext *s, TCGOpcode op, TCGReg r0, TCGReg r1) 324{ 325 tcg_insn_unit insn = 0; 326 327 insn = deposit32(insn, 0, 8, op); 328 insn = deposit32(insn, 8, 4, r0); 329 insn = deposit32(insn, 12, 4, r1); 330 tcg_out32(s, insn); 331} 332 333static void tcg_out_op_rrm(TCGContext *s, TCGOpcode op, 334 TCGReg r0, TCGReg r1, TCGArg m2) 335{ 336 tcg_insn_unit insn = 0; 337 338 tcg_debug_assert(m2 == extract32(m2, 0, 12)); 339 insn = deposit32(insn, 0, 8, op); 340 insn = deposit32(insn, 8, 4, r0); 341 insn = deposit32(insn, 12, 4, r1); 342 insn = deposit32(insn, 20, 12, m2); 343 tcg_out32(s, insn); 344} 345 346static void tcg_out_op_rrr(TCGContext *s, TCGOpcode op, 347 TCGReg r0, TCGReg r1, TCGReg r2) 348{ 349 tcg_insn_unit insn = 0; 350 351 insn = deposit32(insn, 0, 8, op); 352 insn = deposit32(insn, 8, 4, r0); 353 insn = deposit32(insn, 12, 4, r1); 354 insn = deposit32(insn, 16, 4, r2); 355 tcg_out32(s, insn); 356} 357 358static void tcg_out_op_rrs(TCGContext *s, TCGOpcode op, 359 TCGReg r0, TCGReg r1, intptr_t i2) 360{ 361 tcg_insn_unit insn = 0; 362 363 tcg_debug_assert(i2 == sextract32(i2, 0, 16)); 364 insn = deposit32(insn, 0, 8, op); 365 insn = deposit32(insn, 8, 4, r0); 366 insn = deposit32(insn, 12, 4, r1); 367 insn = deposit32(insn, 16, 16, i2); 368 tcg_out32(s, insn); 369} 370 371static void tcg_out_op_rrbb(TCGContext *s, TCGOpcode op, TCGReg r0, 372 TCGReg r1, uint8_t b2, uint8_t b3) 373{ 374 tcg_insn_unit insn = 0; 375 376 tcg_debug_assert(b2 == extract32(b2, 0, 6)); 377 tcg_debug_assert(b3 == extract32(b3, 0, 6)); 378 insn = deposit32(insn, 0, 8, op); 379 insn = deposit32(insn, 8, 4, r0); 380 insn = deposit32(insn, 12, 4, r1); 381 insn = deposit32(insn, 16, 6, b2); 382 insn = deposit32(insn, 22, 6, b3); 383 tcg_out32(s, insn); 384} 385 386static void tcg_out_op_rrrc(TCGContext *s, TCGOpcode op, 387 TCGReg r0, TCGReg r1, TCGReg r2, TCGCond c3) 388{ 389 tcg_insn_unit insn = 0; 390 391 insn = deposit32(insn, 0, 8, op); 392 insn = deposit32(insn, 8, 4, r0); 393 insn = deposit32(insn, 12, 4, r1); 394 insn = deposit32(insn, 16, 4, r2); 395 insn = deposit32(insn, 20, 4, c3); 396 tcg_out32(s, insn); 397} 398 399static void tcg_out_op_rrrm(TCGContext *s, TCGOpcode op, 400 TCGReg r0, TCGReg r1, TCGReg r2, TCGArg m3) 401{ 402 tcg_insn_unit insn = 0; 403 404 tcg_debug_assert(m3 == extract32(m3, 0, 12)); 405 insn = deposit32(insn, 0, 8, op); 406 insn = deposit32(insn, 8, 4, r0); 407 insn = deposit32(insn, 12, 4, r1); 408 insn = deposit32(insn, 16, 4, r2); 409 insn = deposit32(insn, 20, 12, m3); 410 tcg_out32(s, insn); 411} 412 413static void tcg_out_op_rrrbb(TCGContext *s, TCGOpcode op, TCGReg r0, 414 TCGReg r1, TCGReg r2, uint8_t b3, uint8_t b4) 415{ 416 tcg_insn_unit insn = 0; 417 418 tcg_debug_assert(b3 == extract32(b3, 0, 6)); 419 tcg_debug_assert(b4 == extract32(b4, 0, 6)); 420 insn = deposit32(insn, 0, 8, op); 421 insn = deposit32(insn, 8, 4, r0); 422 insn = deposit32(insn, 12, 4, r1); 423 insn = deposit32(insn, 16, 4, r2); 424 insn = deposit32(insn, 20, 6, b3); 425 insn = deposit32(insn, 26, 6, b4); 426 tcg_out32(s, insn); 427} 428 429static void tcg_out_op_rrrrr(TCGContext *s, TCGOpcode op, TCGReg r0, 430 TCGReg r1, TCGReg r2, TCGReg r3, TCGReg r4) 431{ 432 tcg_insn_unit insn = 0; 433 434 insn = deposit32(insn, 0, 8, op); 435 insn = deposit32(insn, 8, 4, r0); 436 insn = deposit32(insn, 12, 4, r1); 437 insn = deposit32(insn, 16, 4, r2); 438 insn = deposit32(insn, 20, 4, r3); 439 insn = deposit32(insn, 24, 4, r4); 440 tcg_out32(s, insn); 441} 442 443static void tcg_out_op_rrrr(TCGContext *s, TCGOpcode op, 444 TCGReg r0, TCGReg r1, TCGReg r2, TCGReg r3) 445{ 446 tcg_insn_unit insn = 0; 447 448 insn = deposit32(insn, 0, 8, op); 449 insn = deposit32(insn, 8, 4, r0); 450 insn = deposit32(insn, 12, 4, r1); 451 insn = deposit32(insn, 16, 4, r2); 452 insn = deposit32(insn, 20, 4, r3); 453 tcg_out32(s, insn); 454} 455 456static void tcg_out_op_rrrrrc(TCGContext *s, TCGOpcode op, 457 TCGReg r0, TCGReg r1, TCGReg r2, 458 TCGReg r3, TCGReg r4, TCGCond c5) 459{ 460 tcg_insn_unit insn = 0; 461 462 insn = deposit32(insn, 0, 8, op); 463 insn = deposit32(insn, 8, 4, r0); 464 insn = deposit32(insn, 12, 4, r1); 465 insn = deposit32(insn, 16, 4, r2); 466 insn = deposit32(insn, 20, 4, r3); 467 insn = deposit32(insn, 24, 4, r4); 468 insn = deposit32(insn, 28, 4, c5); 469 tcg_out32(s, insn); 470} 471 472static void tcg_out_op_rrrrrr(TCGContext *s, TCGOpcode op, 473 TCGReg r0, TCGReg r1, TCGReg r2, 474 TCGReg r3, TCGReg r4, TCGReg r5) 475{ 476 tcg_insn_unit insn = 0; 477 478 insn = deposit32(insn, 0, 8, op); 479 insn = deposit32(insn, 8, 4, r0); 480 insn = deposit32(insn, 12, 4, r1); 481 insn = deposit32(insn, 16, 4, r2); 482 insn = deposit32(insn, 20, 4, r3); 483 insn = deposit32(insn, 24, 4, r4); 484 insn = deposit32(insn, 28, 4, r5); 485 tcg_out32(s, insn); 486} 487 488static void tcg_out_ldst(TCGContext *s, TCGOpcode op, TCGReg val, 489 TCGReg base, intptr_t offset) 490{ 491 stack_bounds_check(base, offset); 492 if (offset != sextract32(offset, 0, 16)) { 493 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP, offset); 494 tcg_out_op_rrr(s, (TCG_TARGET_REG_BITS == 32 495 ? INDEX_op_add_i32 : INDEX_op_add_i64), 496 TCG_REG_TMP, TCG_REG_TMP, base); 497 base = TCG_REG_TMP; 498 offset = 0; 499 } 500 tcg_out_op_rrs(s, op, val, base, offset); 501} 502 503static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg val, TCGReg base, 504 intptr_t offset) 505{ 506 switch (type) { 507 case TCG_TYPE_I32: 508 tcg_out_ldst(s, INDEX_op_ld_i32, val, base, offset); 509 break; 510#if TCG_TARGET_REG_BITS == 64 511 case TCG_TYPE_I64: 512 tcg_out_ldst(s, INDEX_op_ld_i64, val, base, offset); 513 break; 514#endif 515 default: 516 g_assert_not_reached(); 517 } 518} 519 520static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) 521{ 522 switch (type) { 523 case TCG_TYPE_I32: 524 tcg_out_op_rr(s, INDEX_op_mov_i32, ret, arg); 525 break; 526#if TCG_TARGET_REG_BITS == 64 527 case TCG_TYPE_I64: 528 tcg_out_op_rr(s, INDEX_op_mov_i64, ret, arg); 529 break; 530#endif 531 default: 532 g_assert_not_reached(); 533 } 534 return true; 535} 536 537static void tcg_out_movi(TCGContext *s, TCGType type, 538 TCGReg ret, tcg_target_long arg) 539{ 540 switch (type) { 541 case TCG_TYPE_I32: 542#if TCG_TARGET_REG_BITS == 64 543 arg = (int32_t)arg; 544 /* fall through */ 545 case TCG_TYPE_I64: 546#endif 547 break; 548 default: 549 g_assert_not_reached(); 550 } 551 552 if (arg == sextract32(arg, 0, 20)) { 553 tcg_out_op_ri(s, INDEX_op_tci_movi, ret, arg); 554 } else { 555 tcg_insn_unit insn = 0; 556 557 new_pool_label(s, arg, 20, s->code_ptr, 0); 558 insn = deposit32(insn, 0, 8, INDEX_op_tci_movl); 559 insn = deposit32(insn, 8, 4, ret); 560 tcg_out32(s, insn); 561 } 562} 563 564static void tcg_out_call(TCGContext *s, const tcg_insn_unit *func, 565 ffi_cif *cif) 566{ 567 tcg_insn_unit insn = 0; 568 uint8_t which; 569 570 if (cif->rtype == &ffi_type_void) { 571 which = 0; 572 } else if (cif->rtype->size == 4) { 573 which = 1; 574 } else { 575 tcg_debug_assert(cif->rtype->size == 8); 576 which = 2; 577 } 578 new_pool_l2(s, 20, s->code_ptr, 0, (uintptr_t)func, (uintptr_t)cif); 579 insn = deposit32(insn, 0, 8, INDEX_op_call); 580 insn = deposit32(insn, 8, 4, which); 581 tcg_out32(s, insn); 582} 583 584#if TCG_TARGET_REG_BITS == 64 585# define CASE_32_64(x) \ 586 case glue(glue(INDEX_op_, x), _i64): \ 587 case glue(glue(INDEX_op_, x), _i32): 588# define CASE_64(x) \ 589 case glue(glue(INDEX_op_, x), _i64): 590#else 591# define CASE_32_64(x) \ 592 case glue(glue(INDEX_op_, x), _i32): 593# define CASE_64(x) 594#endif 595 596static void tcg_out_op(TCGContext *s, TCGOpcode opc, 597 const TCGArg args[TCG_MAX_OP_ARGS], 598 const int const_args[TCG_MAX_OP_ARGS]) 599{ 600 TCGOpcode exts; 601 602 switch (opc) { 603 case INDEX_op_exit_tb: 604 tcg_out_op_p(s, opc, (void *)args[0]); 605 break; 606 607 case INDEX_op_goto_tb: 608 tcg_debug_assert(s->tb_jmp_insn_offset == 0); 609 /* indirect jump method. */ 610 tcg_out_op_p(s, opc, s->tb_jmp_target_addr + args[0]); 611 set_jmp_reset_offset(s, args[0]); 612 break; 613 614 case INDEX_op_goto_ptr: 615 tcg_out_op_r(s, opc, args[0]); 616 break; 617 618 case INDEX_op_br: 619 tcg_out_op_l(s, opc, arg_label(args[0])); 620 break; 621 622 CASE_32_64(setcond) 623 tcg_out_op_rrrc(s, opc, args[0], args[1], args[2], args[3]); 624 break; 625 626 CASE_32_64(movcond) 627 case INDEX_op_setcond2_i32: 628 tcg_out_op_rrrrrc(s, opc, args[0], args[1], args[2], 629 args[3], args[4], args[5]); 630 break; 631 632 CASE_32_64(ld8u) 633 CASE_32_64(ld8s) 634 CASE_32_64(ld16u) 635 CASE_32_64(ld16s) 636 case INDEX_op_ld_i32: 637 CASE_64(ld32u) 638 CASE_64(ld32s) 639 CASE_64(ld) 640 CASE_32_64(st8) 641 CASE_32_64(st16) 642 case INDEX_op_st_i32: 643 CASE_64(st32) 644 CASE_64(st) 645 tcg_out_ldst(s, opc, args[0], args[1], args[2]); 646 break; 647 648 CASE_32_64(add) 649 CASE_32_64(sub) 650 CASE_32_64(mul) 651 CASE_32_64(and) 652 CASE_32_64(or) 653 CASE_32_64(xor) 654 CASE_32_64(andc) /* Optional (TCG_TARGET_HAS_andc_*). */ 655 CASE_32_64(orc) /* Optional (TCG_TARGET_HAS_orc_*). */ 656 CASE_32_64(eqv) /* Optional (TCG_TARGET_HAS_eqv_*). */ 657 CASE_32_64(nand) /* Optional (TCG_TARGET_HAS_nand_*). */ 658 CASE_32_64(nor) /* Optional (TCG_TARGET_HAS_nor_*). */ 659 CASE_32_64(shl) 660 CASE_32_64(shr) 661 CASE_32_64(sar) 662 CASE_32_64(rotl) /* Optional (TCG_TARGET_HAS_rot_*). */ 663 CASE_32_64(rotr) /* Optional (TCG_TARGET_HAS_rot_*). */ 664 CASE_32_64(div) /* Optional (TCG_TARGET_HAS_div_*). */ 665 CASE_32_64(divu) /* Optional (TCG_TARGET_HAS_div_*). */ 666 CASE_32_64(rem) /* Optional (TCG_TARGET_HAS_div_*). */ 667 CASE_32_64(remu) /* Optional (TCG_TARGET_HAS_div_*). */ 668 CASE_32_64(clz) /* Optional (TCG_TARGET_HAS_clz_*). */ 669 CASE_32_64(ctz) /* Optional (TCG_TARGET_HAS_ctz_*). */ 670 tcg_out_op_rrr(s, opc, args[0], args[1], args[2]); 671 break; 672 673 CASE_32_64(deposit) /* Optional (TCG_TARGET_HAS_deposit_*). */ 674 { 675 TCGArg pos = args[3], len = args[4]; 676 TCGArg max = opc == INDEX_op_deposit_i32 ? 32 : 64; 677 678 tcg_debug_assert(pos < max); 679 tcg_debug_assert(pos + len <= max); 680 681 tcg_out_op_rrrbb(s, opc, args[0], args[1], args[2], pos, len); 682 } 683 break; 684 685 CASE_32_64(extract) /* Optional (TCG_TARGET_HAS_extract_*). */ 686 CASE_32_64(sextract) /* Optional (TCG_TARGET_HAS_sextract_*). */ 687 { 688 TCGArg pos = args[2], len = args[3]; 689 TCGArg max = tcg_op_defs[opc].flags & TCG_OPF_64BIT ? 64 : 32; 690 691 tcg_debug_assert(pos < max); 692 tcg_debug_assert(pos + len <= max); 693 694 tcg_out_op_rrbb(s, opc, args[0], args[1], pos, len); 695 } 696 break; 697 698 CASE_32_64(brcond) 699 tcg_out_op_rrrc(s, (opc == INDEX_op_brcond_i32 700 ? INDEX_op_setcond_i32 : INDEX_op_setcond_i64), 701 TCG_REG_TMP, args[0], args[1], args[2]); 702 tcg_out_op_rl(s, opc, TCG_REG_TMP, arg_label(args[3])); 703 break; 704 705 CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */ 706 CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */ 707 CASE_32_64(ext8s) /* Optional (TCG_TARGET_HAS_ext8s_*). */ 708 CASE_32_64(ext8u) /* Optional (TCG_TARGET_HAS_ext8u_*). */ 709 CASE_32_64(ext16s) /* Optional (TCG_TARGET_HAS_ext16s_*). */ 710 CASE_32_64(ext16u) /* Optional (TCG_TARGET_HAS_ext16u_*). */ 711 CASE_64(ext32s) /* Optional (TCG_TARGET_HAS_ext32s_i64). */ 712 CASE_64(ext32u) /* Optional (TCG_TARGET_HAS_ext32u_i64). */ 713 CASE_64(ext_i32) 714 CASE_64(extu_i32) 715 CASE_32_64(ctpop) /* Optional (TCG_TARGET_HAS_ctpop_*). */ 716 case INDEX_op_bswap32_i32: /* Optional (TCG_TARGET_HAS_bswap32_i32). */ 717 case INDEX_op_bswap64_i64: /* Optional (TCG_TARGET_HAS_bswap64_i64). */ 718 tcg_out_op_rr(s, opc, args[0], args[1]); 719 break; 720 721 case INDEX_op_bswap16_i32: /* Optional (TCG_TARGET_HAS_bswap16_i32). */ 722 exts = INDEX_op_ext16s_i32; 723 goto do_bswap; 724 case INDEX_op_bswap16_i64: /* Optional (TCG_TARGET_HAS_bswap16_i64). */ 725 exts = INDEX_op_ext16s_i64; 726 goto do_bswap; 727 case INDEX_op_bswap32_i64: /* Optional (TCG_TARGET_HAS_bswap32_i64). */ 728 exts = INDEX_op_ext32s_i64; 729 do_bswap: 730 /* The base tci bswaps zero-extend, and ignore high bits. */ 731 tcg_out_op_rr(s, opc, args[0], args[1]); 732 if (args[2] & TCG_BSWAP_OS) { 733 tcg_out_op_rr(s, exts, args[0], args[0]); 734 } 735 break; 736 737 CASE_32_64(add2) 738 CASE_32_64(sub2) 739 tcg_out_op_rrrrrr(s, opc, args[0], args[1], args[2], 740 args[3], args[4], args[5]); 741 break; 742 743#if TCG_TARGET_REG_BITS == 32 744 case INDEX_op_brcond2_i32: 745 tcg_out_op_rrrrrc(s, INDEX_op_setcond2_i32, TCG_REG_TMP, 746 args[0], args[1], args[2], args[3], args[4]); 747 tcg_out_op_rl(s, INDEX_op_brcond_i32, TCG_REG_TMP, arg_label(args[5])); 748 break; 749#endif 750 751 CASE_32_64(mulu2) 752 CASE_32_64(muls2) 753 tcg_out_op_rrrr(s, opc, args[0], args[1], args[2], args[3]); 754 break; 755 756 case INDEX_op_qemu_ld_i32: 757 case INDEX_op_qemu_st_i32: 758 if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) { 759 tcg_out_op_rrm(s, opc, args[0], args[1], args[2]); 760 } else { 761 tcg_out_op_rrrm(s, opc, args[0], args[1], args[2], args[3]); 762 } 763 break; 764 765 case INDEX_op_qemu_ld_i64: 766 case INDEX_op_qemu_st_i64: 767 if (TCG_TARGET_REG_BITS == 64) { 768 tcg_out_op_rrm(s, opc, args[0], args[1], args[2]); 769 } else if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) { 770 tcg_out_op_rrrm(s, opc, args[0], args[1], args[2], args[3]); 771 } else { 772 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP, args[4]); 773 tcg_out_op_rrrrr(s, opc, args[0], args[1], 774 args[2], args[3], TCG_REG_TMP); 775 } 776 break; 777 778 case INDEX_op_mb: 779 tcg_out_op_v(s, opc); 780 break; 781 782 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */ 783 case INDEX_op_mov_i64: 784 case INDEX_op_call: /* Always emitted via tcg_out_call. */ 785 default: 786 tcg_abort(); 787 } 788} 789 790static void tcg_out_st(TCGContext *s, TCGType type, TCGReg val, TCGReg base, 791 intptr_t offset) 792{ 793 switch (type) { 794 case TCG_TYPE_I32: 795 tcg_out_ldst(s, INDEX_op_st_i32, val, base, offset); 796 break; 797#if TCG_TARGET_REG_BITS == 64 798 case TCG_TYPE_I64: 799 tcg_out_ldst(s, INDEX_op_st_i64, val, base, offset); 800 break; 801#endif 802 default: 803 g_assert_not_reached(); 804 } 805} 806 807static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val, 808 TCGReg base, intptr_t ofs) 809{ 810 return false; 811} 812 813/* Test if a constant matches the constraint. */ 814static bool tcg_target_const_match(int64_t val, TCGType type, int ct) 815{ 816 return ct & TCG_CT_CONST; 817} 818 819static void tcg_out_nop_fill(tcg_insn_unit *p, int count) 820{ 821 memset(p, 0, sizeof(*p) * count); 822} 823 824static void tcg_target_init(TCGContext *s) 825{ 826 /* The current code uses uint8_t for tcg operations. */ 827 tcg_debug_assert(tcg_op_defs_max <= UINT8_MAX); 828 829 /* Registers available for 32 bit operations. */ 830 tcg_target_available_regs[TCG_TYPE_I32] = BIT(TCG_TARGET_NB_REGS) - 1; 831 /* Registers available for 64 bit operations. */ 832 tcg_target_available_regs[TCG_TYPE_I64] = BIT(TCG_TARGET_NB_REGS) - 1; 833 /* 834 * The interpreter "registers" are in the local stack frame and 835 * cannot be clobbered by the called helper functions. However, 836 * the interpreter assumes a 64-bit return value and assigns to 837 * the return value registers. 838 */ 839 tcg_target_call_clobber_regs = 840 MAKE_64BIT_MASK(TCG_REG_R0, 64 / TCG_TARGET_REG_BITS); 841 842 s->reserved_regs = 0; 843 tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP); 844 tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK); 845 846 /* The call arguments come first, followed by the temp storage. */ 847 tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE, 848 TCG_STATIC_FRAME_SIZE); 849} 850 851/* Generate global QEMU prologue and epilogue code. */ 852static inline void tcg_target_qemu_prologue(TCGContext *s) 853{ 854} 855