1 /* 2 * Tiny Code Generator for QEMU 3 * 4 * Copyright (c) 2008 Fabrice Bellard 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 "qemu/osdep.h" 26 27 /* Define to jump the ELF file used to communicate with GDB. */ 28 #undef DEBUG_JIT 29 30 #include "qemu/error-report.h" 31 #include "qemu/cutils.h" 32 #include "qemu/host-utils.h" 33 #include "qemu/qemu-print.h" 34 #include "qemu/cacheflush.h" 35 #include "qemu/cacheinfo.h" 36 #include "qemu/timer.h" 37 #include "exec/target_page.h" 38 #include "exec/translation-block.h" 39 #include "exec/tlb-common.h" 40 #include "tcg/startup.h" 41 #include "tcg/tcg-op-common.h" 42 43 #if UINTPTR_MAX == UINT32_MAX 44 # define ELF_CLASS ELFCLASS32 45 #else 46 # define ELF_CLASS ELFCLASS64 47 #endif 48 #if HOST_BIG_ENDIAN 49 # define ELF_DATA ELFDATA2MSB 50 #else 51 # define ELF_DATA ELFDATA2LSB 52 #endif 53 54 #include "elf.h" 55 #include "exec/log.h" 56 #include "tcg/tcg-ldst.h" 57 #include "tcg/tcg-temp-internal.h" 58 #include "tcg-internal.h" 59 #include "tcg/perf.h" 60 #include "tcg-has.h" 61 #ifdef CONFIG_USER_ONLY 62 #include "user/guest-base.h" 63 #endif 64 65 /* Forward declarations for functions declared in tcg-target.c.inc and 66 used here. */ 67 static void tcg_target_init(TCGContext *s); 68 static void tcg_target_qemu_prologue(TCGContext *s); 69 static bool patch_reloc(tcg_insn_unit *code_ptr, int type, 70 intptr_t value, intptr_t addend); 71 static void tcg_out_nop_fill(tcg_insn_unit *p, int count); 72 73 typedef struct TCGLabelQemuLdst TCGLabelQemuLdst; 74 static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l); 75 static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l); 76 77 /* The CIE and FDE header definitions will be common to all hosts. */ 78 typedef struct { 79 uint32_t len __attribute__((aligned((sizeof(void *))))); 80 uint32_t id; 81 uint8_t version; 82 char augmentation[1]; 83 uint8_t code_align; 84 uint8_t data_align; 85 uint8_t return_column; 86 } DebugFrameCIE; 87 88 typedef struct QEMU_PACKED { 89 uint32_t len __attribute__((aligned((sizeof(void *))))); 90 uint32_t cie_offset; 91 uintptr_t func_start; 92 uintptr_t func_len; 93 } DebugFrameFDEHeader; 94 95 typedef struct QEMU_PACKED { 96 DebugFrameCIE cie; 97 DebugFrameFDEHeader fde; 98 } DebugFrameHeader; 99 100 struct TCGLabelQemuLdst { 101 bool is_ld; /* qemu_ld: true, qemu_st: false */ 102 MemOpIdx oi; 103 TCGType type; /* result type of a load */ 104 TCGReg addr_reg; /* reg index for guest virtual addr */ 105 TCGReg datalo_reg; /* reg index for low word to be loaded or stored */ 106 TCGReg datahi_reg; /* reg index for high word to be loaded or stored */ 107 const tcg_insn_unit *raddr; /* addr of the next IR of qemu_ld/st IR */ 108 tcg_insn_unit *label_ptr[2]; /* label pointers to be updated */ 109 QSIMPLEQ_ENTRY(TCGLabelQemuLdst) next; 110 }; 111 112 static void tcg_register_jit_int(const void *buf, size_t size, 113 const void *debug_frame, 114 size_t debug_frame_size) 115 __attribute__((unused)); 116 117 /* Forward declarations for functions declared and used in tcg-target.c.inc. */ 118 static void tcg_out_tb_start(TCGContext *s); 119 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1, 120 intptr_t arg2); 121 static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); 122 static void tcg_out_movi(TCGContext *s, TCGType type, 123 TCGReg ret, tcg_target_long arg); 124 static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); 125 static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); 126 static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg); 127 static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg); 128 static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg); 129 static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg); 130 static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg); 131 static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg); 132 static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg ret, TCGReg arg); 133 static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long); 134 static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2); 135 static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg); 136 static void tcg_out_goto_tb(TCGContext *s, int which); 137 static void tcg_out_goto_ptr(TCGContext *s, TCGReg dest); 138 static void tcg_out_mb(TCGContext *s, unsigned bar); 139 static void tcg_out_br(TCGContext *s, TCGLabel *l); 140 static void tcg_out_set_carry(TCGContext *s); 141 static void tcg_out_set_borrow(TCGContext *s); 142 #if TCG_TARGET_MAYBE_vec 143 static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece, 144 TCGReg dst, TCGReg src); 145 static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece, 146 TCGReg dst, TCGReg base, intptr_t offset); 147 static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece, 148 TCGReg dst, int64_t arg); 149 static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, 150 unsigned vecl, unsigned vece, 151 const TCGArg args[TCG_MAX_OP_ARGS], 152 const int const_args[TCG_MAX_OP_ARGS]); 153 #else 154 static inline bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece, 155 TCGReg dst, TCGReg src) 156 { 157 g_assert_not_reached(); 158 } 159 static inline bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece, 160 TCGReg dst, TCGReg base, intptr_t offset) 161 { 162 g_assert_not_reached(); 163 } 164 static inline void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece, 165 TCGReg dst, int64_t arg) 166 { 167 g_assert_not_reached(); 168 } 169 static inline void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, 170 unsigned vecl, unsigned vece, 171 const TCGArg args[TCG_MAX_OP_ARGS], 172 const int const_args[TCG_MAX_OP_ARGS]) 173 { 174 g_assert_not_reached(); 175 } 176 int tcg_can_emit_vec_op(TCGOpcode o, TCGType t, unsigned ve) 177 { 178 return 0; 179 } 180 #endif 181 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, 182 intptr_t arg2); 183 static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val, 184 TCGReg base, intptr_t ofs); 185 static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target, 186 const TCGHelperInfo *info); 187 static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot); 188 static bool tcg_target_const_match(int64_t val, int ct, 189 TCGType type, TCGCond cond, int vece); 190 191 #ifndef CONFIG_USER_ONLY 192 #define guest_base ({ qemu_build_not_reached(); (uintptr_t)0; }) 193 #endif 194 195 typedef struct TCGLdstHelperParam { 196 TCGReg (*ra_gen)(TCGContext *s, const TCGLabelQemuLdst *l, int arg_reg); 197 unsigned ntmp; 198 int tmp[3]; 199 } TCGLdstHelperParam; 200 201 static void tcg_out_ld_helper_args(TCGContext *s, const TCGLabelQemuLdst *l, 202 const TCGLdstHelperParam *p) 203 __attribute__((unused)); 204 static void tcg_out_ld_helper_ret(TCGContext *s, const TCGLabelQemuLdst *l, 205 bool load_sign, const TCGLdstHelperParam *p) 206 __attribute__((unused)); 207 static void tcg_out_st_helper_args(TCGContext *s, const TCGLabelQemuLdst *l, 208 const TCGLdstHelperParam *p) 209 __attribute__((unused)); 210 211 static void * const qemu_ld_helpers[MO_SSIZE + 1] __attribute__((unused)) = { 212 [MO_UB] = helper_ldub_mmu, 213 [MO_SB] = helper_ldsb_mmu, 214 [MO_UW] = helper_lduw_mmu, 215 [MO_SW] = helper_ldsw_mmu, 216 [MO_UL] = helper_ldul_mmu, 217 [MO_UQ] = helper_ldq_mmu, 218 #if TCG_TARGET_REG_BITS == 64 219 [MO_SL] = helper_ldsl_mmu, 220 [MO_128] = helper_ld16_mmu, 221 #endif 222 }; 223 224 static void * const qemu_st_helpers[MO_SIZE + 1] __attribute__((unused)) = { 225 [MO_8] = helper_stb_mmu, 226 [MO_16] = helper_stw_mmu, 227 [MO_32] = helper_stl_mmu, 228 [MO_64] = helper_stq_mmu, 229 #if TCG_TARGET_REG_BITS == 64 230 [MO_128] = helper_st16_mmu, 231 #endif 232 }; 233 234 typedef struct { 235 MemOp atom; /* lg2 bits of atomicity required */ 236 MemOp align; /* lg2 bits of alignment to use */ 237 } TCGAtomAlign; 238 239 static TCGAtomAlign atom_and_align_for_opc(TCGContext *s, MemOp opc, 240 MemOp host_atom, bool allow_two_ops) 241 __attribute__((unused)); 242 243 #ifdef CONFIG_USER_ONLY 244 bool tcg_use_softmmu; 245 #endif 246 247 TCGContext tcg_init_ctx; 248 __thread TCGContext *tcg_ctx; 249 250 TCGContext **tcg_ctxs; 251 unsigned int tcg_cur_ctxs; 252 unsigned int tcg_max_ctxs; 253 TCGv_env tcg_env; 254 const void *tcg_code_gen_epilogue; 255 uintptr_t tcg_splitwx_diff; 256 257 #ifndef CONFIG_TCG_INTERPRETER 258 tcg_prologue_fn *tcg_qemu_tb_exec; 259 #endif 260 261 static TCGRegSet tcg_target_available_regs[TCG_TYPE_COUNT]; 262 static TCGRegSet tcg_target_call_clobber_regs; 263 264 #if TCG_TARGET_INSN_UNIT_SIZE == 1 265 static __attribute__((unused)) inline void tcg_out8(TCGContext *s, uint8_t v) 266 { 267 *s->code_ptr++ = v; 268 } 269 270 static __attribute__((unused)) inline void tcg_patch8(tcg_insn_unit *p, 271 uint8_t v) 272 { 273 *p = v; 274 } 275 #endif 276 277 #if TCG_TARGET_INSN_UNIT_SIZE <= 2 278 static __attribute__((unused)) inline void tcg_out16(TCGContext *s, uint16_t v) 279 { 280 if (TCG_TARGET_INSN_UNIT_SIZE == 2) { 281 *s->code_ptr++ = v; 282 } else { 283 tcg_insn_unit *p = s->code_ptr; 284 memcpy(p, &v, sizeof(v)); 285 s->code_ptr = p + (2 / TCG_TARGET_INSN_UNIT_SIZE); 286 } 287 } 288 289 static __attribute__((unused)) inline void tcg_patch16(tcg_insn_unit *p, 290 uint16_t v) 291 { 292 if (TCG_TARGET_INSN_UNIT_SIZE == 2) { 293 *p = v; 294 } else { 295 memcpy(p, &v, sizeof(v)); 296 } 297 } 298 #endif 299 300 #if TCG_TARGET_INSN_UNIT_SIZE <= 4 301 static __attribute__((unused)) inline void tcg_out32(TCGContext *s, uint32_t v) 302 { 303 if (TCG_TARGET_INSN_UNIT_SIZE == 4) { 304 *s->code_ptr++ = v; 305 } else { 306 tcg_insn_unit *p = s->code_ptr; 307 memcpy(p, &v, sizeof(v)); 308 s->code_ptr = p + (4 / TCG_TARGET_INSN_UNIT_SIZE); 309 } 310 } 311 312 static __attribute__((unused)) inline void tcg_patch32(tcg_insn_unit *p, 313 uint32_t v) 314 { 315 if (TCG_TARGET_INSN_UNIT_SIZE == 4) { 316 *p = v; 317 } else { 318 memcpy(p, &v, sizeof(v)); 319 } 320 } 321 #endif 322 323 #if TCG_TARGET_INSN_UNIT_SIZE <= 8 324 static __attribute__((unused)) inline void tcg_out64(TCGContext *s, uint64_t v) 325 { 326 if (TCG_TARGET_INSN_UNIT_SIZE == 8) { 327 *s->code_ptr++ = v; 328 } else { 329 tcg_insn_unit *p = s->code_ptr; 330 memcpy(p, &v, sizeof(v)); 331 s->code_ptr = p + (8 / TCG_TARGET_INSN_UNIT_SIZE); 332 } 333 } 334 335 static __attribute__((unused)) inline void tcg_patch64(tcg_insn_unit *p, 336 uint64_t v) 337 { 338 if (TCG_TARGET_INSN_UNIT_SIZE == 8) { 339 *p = v; 340 } else { 341 memcpy(p, &v, sizeof(v)); 342 } 343 } 344 #endif 345 346 /* label relocation processing */ 347 348 static void tcg_out_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type, 349 TCGLabel *l, intptr_t addend) 350 { 351 TCGRelocation *r = tcg_malloc(sizeof(TCGRelocation)); 352 353 r->type = type; 354 r->ptr = code_ptr; 355 r->addend = addend; 356 QSIMPLEQ_INSERT_TAIL(&l->relocs, r, next); 357 } 358 359 static void tcg_out_label(TCGContext *s, TCGLabel *l) 360 { 361 tcg_debug_assert(!l->has_value); 362 l->has_value = 1; 363 l->u.value_ptr = tcg_splitwx_to_rx(s->code_ptr); 364 } 365 366 TCGLabel *gen_new_label(void) 367 { 368 TCGContext *s = tcg_ctx; 369 TCGLabel *l = tcg_malloc(sizeof(TCGLabel)); 370 371 memset(l, 0, sizeof(TCGLabel)); 372 l->id = s->nb_labels++; 373 QSIMPLEQ_INIT(&l->branches); 374 QSIMPLEQ_INIT(&l->relocs); 375 376 QSIMPLEQ_INSERT_TAIL(&s->labels, l, next); 377 378 return l; 379 } 380 381 static bool tcg_resolve_relocs(TCGContext *s) 382 { 383 TCGLabel *l; 384 385 QSIMPLEQ_FOREACH(l, &s->labels, next) { 386 TCGRelocation *r; 387 uintptr_t value = l->u.value; 388 389 QSIMPLEQ_FOREACH(r, &l->relocs, next) { 390 if (!patch_reloc(r->ptr, r->type, value, r->addend)) { 391 return false; 392 } 393 } 394 } 395 return true; 396 } 397 398 static void set_jmp_reset_offset(TCGContext *s, int which) 399 { 400 /* 401 * We will check for overflow at the end of the opcode loop in 402 * tcg_gen_code, where we bound tcg_current_code_size to UINT16_MAX. 403 */ 404 s->gen_tb->jmp_reset_offset[which] = tcg_current_code_size(s); 405 } 406 407 static void G_GNUC_UNUSED set_jmp_insn_offset(TCGContext *s, int which) 408 { 409 /* 410 * We will check for overflow at the end of the opcode loop in 411 * tcg_gen_code, where we bound tcg_current_code_size to UINT16_MAX. 412 */ 413 s->gen_tb->jmp_insn_offset[which] = tcg_current_code_size(s); 414 } 415 416 static uintptr_t G_GNUC_UNUSED get_jmp_target_addr(TCGContext *s, int which) 417 { 418 /* 419 * Return the read-execute version of the pointer, for the benefit 420 * of any pc-relative addressing mode. 421 */ 422 return (uintptr_t)tcg_splitwx_to_rx(&s->gen_tb->jmp_target_addr[which]); 423 } 424 425 static int __attribute__((unused)) 426 tlb_mask_table_ofs(TCGContext *s, int which) 427 { 428 return (offsetof(CPUNegativeOffsetState, tlb.f[which]) - 429 sizeof(CPUNegativeOffsetState)); 430 } 431 432 /* Signal overflow, starting over with fewer guest insns. */ 433 static G_NORETURN 434 void tcg_raise_tb_overflow(TCGContext *s) 435 { 436 siglongjmp(s->jmp_trans, -2); 437 } 438 439 /* 440 * Used by tcg_out_movext{1,2} to hold the arguments for tcg_out_movext. 441 * By the time we arrive at tcg_out_movext1, @dst is always a TCGReg. 442 * 443 * However, tcg_out_helper_load_slots reuses this field to hold an 444 * argument slot number (which may designate a argument register or an 445 * argument stack slot), converting to TCGReg once all arguments that 446 * are destined for the stack are processed. 447 */ 448 typedef struct TCGMovExtend { 449 unsigned dst; 450 TCGReg src; 451 TCGType dst_type; 452 TCGType src_type; 453 MemOp src_ext; 454 } TCGMovExtend; 455 456 /** 457 * tcg_out_movext -- move and extend 458 * @s: tcg context 459 * @dst_type: integral type for destination 460 * @dst: destination register 461 * @src_type: integral type for source 462 * @src_ext: extension to apply to source 463 * @src: source register 464 * 465 * Move or extend @src into @dst, depending on @src_ext and the types. 466 */ 467 static void tcg_out_movext(TCGContext *s, TCGType dst_type, TCGReg dst, 468 TCGType src_type, MemOp src_ext, TCGReg src) 469 { 470 switch (src_ext) { 471 case MO_UB: 472 tcg_out_ext8u(s, dst, src); 473 break; 474 case MO_SB: 475 tcg_out_ext8s(s, dst_type, dst, src); 476 break; 477 case MO_UW: 478 tcg_out_ext16u(s, dst, src); 479 break; 480 case MO_SW: 481 tcg_out_ext16s(s, dst_type, dst, src); 482 break; 483 case MO_UL: 484 case MO_SL: 485 if (dst_type == TCG_TYPE_I32) { 486 if (src_type == TCG_TYPE_I32) { 487 tcg_out_mov(s, TCG_TYPE_I32, dst, src); 488 } else { 489 tcg_out_extrl_i64_i32(s, dst, src); 490 } 491 } else if (src_type == TCG_TYPE_I32) { 492 if (src_ext & MO_SIGN) { 493 tcg_out_exts_i32_i64(s, dst, src); 494 } else { 495 tcg_out_extu_i32_i64(s, dst, src); 496 } 497 } else { 498 if (src_ext & MO_SIGN) { 499 tcg_out_ext32s(s, dst, src); 500 } else { 501 tcg_out_ext32u(s, dst, src); 502 } 503 } 504 break; 505 case MO_UQ: 506 tcg_debug_assert(TCG_TARGET_REG_BITS == 64); 507 if (dst_type == TCG_TYPE_I32) { 508 tcg_out_extrl_i64_i32(s, dst, src); 509 } else { 510 tcg_out_mov(s, TCG_TYPE_I64, dst, src); 511 } 512 break; 513 default: 514 g_assert_not_reached(); 515 } 516 } 517 518 /* Minor variations on a theme, using a structure. */ 519 static void tcg_out_movext1_new_src(TCGContext *s, const TCGMovExtend *i, 520 TCGReg src) 521 { 522 tcg_out_movext(s, i->dst_type, i->dst, i->src_type, i->src_ext, src); 523 } 524 525 static void tcg_out_movext1(TCGContext *s, const TCGMovExtend *i) 526 { 527 tcg_out_movext1_new_src(s, i, i->src); 528 } 529 530 /** 531 * tcg_out_movext2 -- move and extend two pair 532 * @s: tcg context 533 * @i1: first move description 534 * @i2: second move description 535 * @scratch: temporary register, or -1 for none 536 * 537 * As tcg_out_movext, for both @i1 and @i2, caring for overlap 538 * between the sources and destinations. 539 */ 540 541 static void tcg_out_movext2(TCGContext *s, const TCGMovExtend *i1, 542 const TCGMovExtend *i2, int scratch) 543 { 544 TCGReg src1 = i1->src; 545 TCGReg src2 = i2->src; 546 547 if (i1->dst != src2) { 548 tcg_out_movext1(s, i1); 549 tcg_out_movext1(s, i2); 550 return; 551 } 552 if (i2->dst == src1) { 553 TCGType src1_type = i1->src_type; 554 TCGType src2_type = i2->src_type; 555 556 if (tcg_out_xchg(s, MAX(src1_type, src2_type), src1, src2)) { 557 /* The data is now in the correct registers, now extend. */ 558 src1 = i2->src; 559 src2 = i1->src; 560 } else { 561 tcg_debug_assert(scratch >= 0); 562 tcg_out_mov(s, src1_type, scratch, src1); 563 src1 = scratch; 564 } 565 } 566 tcg_out_movext1_new_src(s, i2, src2); 567 tcg_out_movext1_new_src(s, i1, src1); 568 } 569 570 /** 571 * tcg_out_movext3 -- move and extend three pair 572 * @s: tcg context 573 * @i1: first move description 574 * @i2: second move description 575 * @i3: third move description 576 * @scratch: temporary register, or -1 for none 577 * 578 * As tcg_out_movext, for all of @i1, @i2 and @i3, caring for overlap 579 * between the sources and destinations. 580 */ 581 582 static void tcg_out_movext3(TCGContext *s, const TCGMovExtend *i1, 583 const TCGMovExtend *i2, const TCGMovExtend *i3, 584 int scratch) 585 { 586 TCGReg src1 = i1->src; 587 TCGReg src2 = i2->src; 588 TCGReg src3 = i3->src; 589 590 if (i1->dst != src2 && i1->dst != src3) { 591 tcg_out_movext1(s, i1); 592 tcg_out_movext2(s, i2, i3, scratch); 593 return; 594 } 595 if (i2->dst != src1 && i2->dst != src3) { 596 tcg_out_movext1(s, i2); 597 tcg_out_movext2(s, i1, i3, scratch); 598 return; 599 } 600 if (i3->dst != src1 && i3->dst != src2) { 601 tcg_out_movext1(s, i3); 602 tcg_out_movext2(s, i1, i2, scratch); 603 return; 604 } 605 606 /* 607 * There is a cycle. Since there are only 3 nodes, the cycle is 608 * either "clockwise" or "anti-clockwise", and can be solved with 609 * a single scratch or two xchg. 610 */ 611 if (i1->dst == src2 && i2->dst == src3 && i3->dst == src1) { 612 /* "Clockwise" */ 613 if (tcg_out_xchg(s, MAX(i1->src_type, i2->src_type), src1, src2)) { 614 tcg_out_xchg(s, MAX(i2->src_type, i3->src_type), src2, src3); 615 /* The data is now in the correct registers, now extend. */ 616 tcg_out_movext1_new_src(s, i1, i1->dst); 617 tcg_out_movext1_new_src(s, i2, i2->dst); 618 tcg_out_movext1_new_src(s, i3, i3->dst); 619 } else { 620 tcg_debug_assert(scratch >= 0); 621 tcg_out_mov(s, i1->src_type, scratch, src1); 622 tcg_out_movext1(s, i3); 623 tcg_out_movext1(s, i2); 624 tcg_out_movext1_new_src(s, i1, scratch); 625 } 626 } else if (i1->dst == src3 && i2->dst == src1 && i3->dst == src2) { 627 /* "Anti-clockwise" */ 628 if (tcg_out_xchg(s, MAX(i2->src_type, i3->src_type), src2, src3)) { 629 tcg_out_xchg(s, MAX(i1->src_type, i2->src_type), src1, src2); 630 /* The data is now in the correct registers, now extend. */ 631 tcg_out_movext1_new_src(s, i1, i1->dst); 632 tcg_out_movext1_new_src(s, i2, i2->dst); 633 tcg_out_movext1_new_src(s, i3, i3->dst); 634 } else { 635 tcg_debug_assert(scratch >= 0); 636 tcg_out_mov(s, i1->src_type, scratch, src1); 637 tcg_out_movext1(s, i2); 638 tcg_out_movext1(s, i3); 639 tcg_out_movext1_new_src(s, i1, scratch); 640 } 641 } else { 642 g_assert_not_reached(); 643 } 644 } 645 646 /* 647 * Allocate a new TCGLabelQemuLdst entry. 648 */ 649 650 __attribute__((unused)) 651 static TCGLabelQemuLdst *new_ldst_label(TCGContext *s) 652 { 653 TCGLabelQemuLdst *l = tcg_malloc(sizeof(*l)); 654 655 memset(l, 0, sizeof(*l)); 656 QSIMPLEQ_INSERT_TAIL(&s->ldst_labels, l, next); 657 658 return l; 659 } 660 661 /* 662 * Allocate new constant pool entries. 663 */ 664 665 typedef struct TCGLabelPoolData { 666 struct TCGLabelPoolData *next; 667 tcg_insn_unit *label; 668 intptr_t addend; 669 int rtype; 670 unsigned nlong; 671 tcg_target_ulong data[]; 672 } TCGLabelPoolData; 673 674 static TCGLabelPoolData *new_pool_alloc(TCGContext *s, int nlong, int rtype, 675 tcg_insn_unit *label, intptr_t addend) 676 { 677 TCGLabelPoolData *n = tcg_malloc(sizeof(TCGLabelPoolData) 678 + sizeof(tcg_target_ulong) * nlong); 679 680 n->label = label; 681 n->addend = addend; 682 n->rtype = rtype; 683 n->nlong = nlong; 684 return n; 685 } 686 687 static void new_pool_insert(TCGContext *s, TCGLabelPoolData *n) 688 { 689 TCGLabelPoolData *i, **pp; 690 int nlong = n->nlong; 691 692 /* Insertion sort on the pool. */ 693 for (pp = &s->pool_labels; (i = *pp) != NULL; pp = &i->next) { 694 if (nlong > i->nlong) { 695 break; 696 } 697 if (nlong < i->nlong) { 698 continue; 699 } 700 if (memcmp(n->data, i->data, sizeof(tcg_target_ulong) * nlong) >= 0) { 701 break; 702 } 703 } 704 n->next = *pp; 705 *pp = n; 706 } 707 708 /* The "usual" for generic integer code. */ 709 __attribute__((unused)) 710 static void new_pool_label(TCGContext *s, tcg_target_ulong d, int rtype, 711 tcg_insn_unit *label, intptr_t addend) 712 { 713 TCGLabelPoolData *n = new_pool_alloc(s, 1, rtype, label, addend); 714 n->data[0] = d; 715 new_pool_insert(s, n); 716 } 717 718 /* For v64 or v128, depending on the host. */ 719 __attribute__((unused)) 720 static void new_pool_l2(TCGContext *s, int rtype, tcg_insn_unit *label, 721 intptr_t addend, tcg_target_ulong d0, 722 tcg_target_ulong d1) 723 { 724 TCGLabelPoolData *n = new_pool_alloc(s, 2, rtype, label, addend); 725 n->data[0] = d0; 726 n->data[1] = d1; 727 new_pool_insert(s, n); 728 } 729 730 /* For v128 or v256, depending on the host. */ 731 __attribute__((unused)) 732 static void new_pool_l4(TCGContext *s, int rtype, tcg_insn_unit *label, 733 intptr_t addend, tcg_target_ulong d0, 734 tcg_target_ulong d1, tcg_target_ulong d2, 735 tcg_target_ulong d3) 736 { 737 TCGLabelPoolData *n = new_pool_alloc(s, 4, rtype, label, addend); 738 n->data[0] = d0; 739 n->data[1] = d1; 740 n->data[2] = d2; 741 n->data[3] = d3; 742 new_pool_insert(s, n); 743 } 744 745 /* For v256, for 32-bit host. */ 746 __attribute__((unused)) 747 static void new_pool_l8(TCGContext *s, int rtype, tcg_insn_unit *label, 748 intptr_t addend, tcg_target_ulong d0, 749 tcg_target_ulong d1, tcg_target_ulong d2, 750 tcg_target_ulong d3, tcg_target_ulong d4, 751 tcg_target_ulong d5, tcg_target_ulong d6, 752 tcg_target_ulong d7) 753 { 754 TCGLabelPoolData *n = new_pool_alloc(s, 8, rtype, label, addend); 755 n->data[0] = d0; 756 n->data[1] = d1; 757 n->data[2] = d2; 758 n->data[3] = d3; 759 n->data[4] = d4; 760 n->data[5] = d5; 761 n->data[6] = d6; 762 n->data[7] = d7; 763 new_pool_insert(s, n); 764 } 765 766 /* 767 * Generate TB finalization at the end of block 768 */ 769 770 static int tcg_out_ldst_finalize(TCGContext *s) 771 { 772 TCGLabelQemuLdst *lb; 773 774 /* qemu_ld/st slow paths */ 775 QSIMPLEQ_FOREACH(lb, &s->ldst_labels, next) { 776 if (lb->is_ld 777 ? !tcg_out_qemu_ld_slow_path(s, lb) 778 : !tcg_out_qemu_st_slow_path(s, lb)) { 779 return -2; 780 } 781 782 /* 783 * Test for (pending) buffer overflow. The assumption is that any 784 * one operation beginning below the high water mark cannot overrun 785 * the buffer completely. Thus we can test for overflow after 786 * generating code without having to check during generation. 787 */ 788 if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) { 789 return -1; 790 } 791 } 792 return 0; 793 } 794 795 static int tcg_out_pool_finalize(TCGContext *s) 796 { 797 TCGLabelPoolData *p = s->pool_labels; 798 TCGLabelPoolData *l = NULL; 799 void *a; 800 801 if (p == NULL) { 802 return 0; 803 } 804 805 /* 806 * ??? Round up to qemu_icache_linesize, but then do not round 807 * again when allocating the next TranslationBlock structure. 808 */ 809 a = (void *)ROUND_UP((uintptr_t)s->code_ptr, 810 sizeof(tcg_target_ulong) * p->nlong); 811 tcg_out_nop_fill(s->code_ptr, (tcg_insn_unit *)a - s->code_ptr); 812 s->data_gen_ptr = a; 813 814 for (; p != NULL; p = p->next) { 815 size_t size = sizeof(tcg_target_ulong) * p->nlong; 816 uintptr_t value; 817 818 if (!l || l->nlong != p->nlong || memcmp(l->data, p->data, size)) { 819 if (unlikely(a > s->code_gen_highwater)) { 820 return -1; 821 } 822 memcpy(a, p->data, size); 823 a += size; 824 l = p; 825 } 826 827 value = (uintptr_t)tcg_splitwx_to_rx(a) - size; 828 if (!patch_reloc(p->label, p->rtype, value, p->addend)) { 829 return -2; 830 } 831 } 832 833 s->code_ptr = a; 834 return 0; 835 } 836 837 #define C_PFX1(P, A) P##A 838 #define C_PFX2(P, A, B) P##A##_##B 839 #define C_PFX3(P, A, B, C) P##A##_##B##_##C 840 #define C_PFX4(P, A, B, C, D) P##A##_##B##_##C##_##D 841 #define C_PFX5(P, A, B, C, D, E) P##A##_##B##_##C##_##D##_##E 842 #define C_PFX6(P, A, B, C, D, E, F) P##A##_##B##_##C##_##D##_##E##_##F 843 844 /* Define an enumeration for the various combinations. */ 845 846 #define C_O0_I1(I1) C_PFX1(c_o0_i1_, I1), 847 #define C_O0_I2(I1, I2) C_PFX2(c_o0_i2_, I1, I2), 848 #define C_O0_I3(I1, I2, I3) C_PFX3(c_o0_i3_, I1, I2, I3), 849 #define C_O0_I4(I1, I2, I3, I4) C_PFX4(c_o0_i4_, I1, I2, I3, I4), 850 851 #define C_O1_I1(O1, I1) C_PFX2(c_o1_i1_, O1, I1), 852 #define C_O1_I2(O1, I1, I2) C_PFX3(c_o1_i2_, O1, I1, I2), 853 #define C_O1_I3(O1, I1, I2, I3) C_PFX4(c_o1_i3_, O1, I1, I2, I3), 854 #define C_O1_I4(O1, I1, I2, I3, I4) C_PFX5(c_o1_i4_, O1, I1, I2, I3, I4), 855 856 #define C_N1_I2(O1, I1, I2) C_PFX3(c_n1_i2_, O1, I1, I2), 857 #define C_N1O1_I1(O1, O2, I1) C_PFX3(c_n1o1_i1_, O1, O2, I1), 858 #define C_N2_I1(O1, O2, I1) C_PFX3(c_n2_i1_, O1, O2, I1), 859 860 #define C_O2_I1(O1, O2, I1) C_PFX3(c_o2_i1_, O1, O2, I1), 861 #define C_O2_I2(O1, O2, I1, I2) C_PFX4(c_o2_i2_, O1, O2, I1, I2), 862 #define C_O2_I3(O1, O2, I1, I2, I3) C_PFX5(c_o2_i3_, O1, O2, I1, I2, I3), 863 #define C_O2_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_o2_i4_, O1, O2, I1, I2, I3, I4), 864 #define C_N1_O1_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_n1_o1_i4_, O1, O2, I1, I2, I3, I4), 865 866 typedef enum { 867 C_Dynamic = -2, 868 C_NotImplemented = -1, 869 #include "tcg-target-con-set.h" 870 } TCGConstraintSetIndex; 871 872 static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode, TCGType, unsigned); 873 874 #undef C_O0_I1 875 #undef C_O0_I2 876 #undef C_O0_I3 877 #undef C_O0_I4 878 #undef C_O1_I1 879 #undef C_O1_I2 880 #undef C_O1_I3 881 #undef C_O1_I4 882 #undef C_N1_I2 883 #undef C_N1O1_I1 884 #undef C_N2_I1 885 #undef C_O2_I1 886 #undef C_O2_I2 887 #undef C_O2_I3 888 #undef C_O2_I4 889 #undef C_N1_O1_I4 890 891 /* Put all of the constraint sets into an array, indexed by the enum. */ 892 893 typedef struct TCGConstraintSet { 894 uint8_t nb_oargs, nb_iargs; 895 const char *args_ct_str[TCG_MAX_OP_ARGS]; 896 } TCGConstraintSet; 897 898 #define C_O0_I1(I1) { 0, 1, { #I1 } }, 899 #define C_O0_I2(I1, I2) { 0, 2, { #I1, #I2 } }, 900 #define C_O0_I3(I1, I2, I3) { 0, 3, { #I1, #I2, #I3 } }, 901 #define C_O0_I4(I1, I2, I3, I4) { 0, 4, { #I1, #I2, #I3, #I4 } }, 902 903 #define C_O1_I1(O1, I1) { 1, 1, { #O1, #I1 } }, 904 #define C_O1_I2(O1, I1, I2) { 1, 2, { #O1, #I1, #I2 } }, 905 #define C_O1_I3(O1, I1, I2, I3) { 1, 3, { #O1, #I1, #I2, #I3 } }, 906 #define C_O1_I4(O1, I1, I2, I3, I4) { 1, 4, { #O1, #I1, #I2, #I3, #I4 } }, 907 908 #define C_N1_I2(O1, I1, I2) { 1, 2, { "&" #O1, #I1, #I2 } }, 909 #define C_N1O1_I1(O1, O2, I1) { 2, 1, { "&" #O1, #O2, #I1 } }, 910 #define C_N2_I1(O1, O2, I1) { 2, 1, { "&" #O1, "&" #O2, #I1 } }, 911 912 #define C_O2_I1(O1, O2, I1) { 2, 1, { #O1, #O2, #I1 } }, 913 #define C_O2_I2(O1, O2, I1, I2) { 2, 2, { #O1, #O2, #I1, #I2 } }, 914 #define C_O2_I3(O1, O2, I1, I2, I3) { 2, 3, { #O1, #O2, #I1, #I2, #I3 } }, 915 #define C_O2_I4(O1, O2, I1, I2, I3, I4) { 2, 4, { #O1, #O2, #I1, #I2, #I3, #I4 } }, 916 #define C_N1_O1_I4(O1, O2, I1, I2, I3, I4) { 2, 4, { "&" #O1, #O2, #I1, #I2, #I3, #I4 } }, 917 918 static const TCGConstraintSet constraint_sets[] = { 919 #include "tcg-target-con-set.h" 920 }; 921 922 #undef C_O0_I1 923 #undef C_O0_I2 924 #undef C_O0_I3 925 #undef C_O0_I4 926 #undef C_O1_I1 927 #undef C_O1_I2 928 #undef C_O1_I3 929 #undef C_O1_I4 930 #undef C_N1_I2 931 #undef C_N1O1_I1 932 #undef C_N2_I1 933 #undef C_O2_I1 934 #undef C_O2_I2 935 #undef C_O2_I3 936 #undef C_O2_I4 937 #undef C_N1_O1_I4 938 939 /* Expand the enumerator to be returned from tcg_target_op_def(). */ 940 941 #define C_O0_I1(I1) C_PFX1(c_o0_i1_, I1) 942 #define C_O0_I2(I1, I2) C_PFX2(c_o0_i2_, I1, I2) 943 #define C_O0_I3(I1, I2, I3) C_PFX3(c_o0_i3_, I1, I2, I3) 944 #define C_O0_I4(I1, I2, I3, I4) C_PFX4(c_o0_i4_, I1, I2, I3, I4) 945 946 #define C_O1_I1(O1, I1) C_PFX2(c_o1_i1_, O1, I1) 947 #define C_O1_I2(O1, I1, I2) C_PFX3(c_o1_i2_, O1, I1, I2) 948 #define C_O1_I3(O1, I1, I2, I3) C_PFX4(c_o1_i3_, O1, I1, I2, I3) 949 #define C_O1_I4(O1, I1, I2, I3, I4) C_PFX5(c_o1_i4_, O1, I1, I2, I3, I4) 950 951 #define C_N1_I2(O1, I1, I2) C_PFX3(c_n1_i2_, O1, I1, I2) 952 #define C_N1O1_I1(O1, O2, I1) C_PFX3(c_n1o1_i1_, O1, O2, I1) 953 #define C_N2_I1(O1, O2, I1) C_PFX3(c_n2_i1_, O1, O2, I1) 954 955 #define C_O2_I1(O1, O2, I1) C_PFX3(c_o2_i1_, O1, O2, I1) 956 #define C_O2_I2(O1, O2, I1, I2) C_PFX4(c_o2_i2_, O1, O2, I1, I2) 957 #define C_O2_I3(O1, O2, I1, I2, I3) C_PFX5(c_o2_i3_, O1, O2, I1, I2, I3) 958 #define C_O2_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_o2_i4_, O1, O2, I1, I2, I3, I4) 959 #define C_N1_O1_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_n1_o1_i4_, O1, O2, I1, I2, I3, I4) 960 961 /* 962 * TCGOutOp is the base class for a set of structures that describe how 963 * to generate code for a given TCGOpcode. 964 * 965 * @static_constraint: 966 * C_NotImplemented: The TCGOpcode is not supported by the backend. 967 * C_Dynamic: Use @dynamic_constraint to select a constraint set 968 * based on any of @type, @flags, or host isa. 969 * Otherwise: The register allocation constrains for the TCGOpcode. 970 * 971 * Subclasses of TCGOutOp will define a set of output routines that may 972 * be used. Such routines will often be selected by the set of registers 973 * and constants that come out of register allocation. The set of 974 * routines that are provided will guide the set of constraints that are 975 * legal. In particular, assume that tcg_optimize() has done its job in 976 * swapping commutative operands and folding operations for which all 977 * operands are constant. 978 */ 979 typedef struct TCGOutOp { 980 TCGConstraintSetIndex static_constraint; 981 TCGConstraintSetIndex (*dynamic_constraint)(TCGType type, unsigned flags); 982 } TCGOutOp; 983 984 typedef struct TCGOutOpAddSubCarry { 985 TCGOutOp base; 986 void (*out_rrr)(TCGContext *s, TCGType type, 987 TCGReg a0, TCGReg a1, TCGReg a2); 988 void (*out_rri)(TCGContext *s, TCGType type, 989 TCGReg a0, TCGReg a1, tcg_target_long a2); 990 void (*out_rir)(TCGContext *s, TCGType type, 991 TCGReg a0, tcg_target_long a1, TCGReg a2); 992 void (*out_rii)(TCGContext *s, TCGType type, 993 TCGReg a0, tcg_target_long a1, tcg_target_long a2); 994 } TCGOutOpAddSubCarry; 995 996 typedef struct TCGOutOpBinary { 997 TCGOutOp base; 998 void (*out_rrr)(TCGContext *s, TCGType type, 999 TCGReg a0, TCGReg a1, TCGReg a2); 1000 void (*out_rri)(TCGContext *s, TCGType type, 1001 TCGReg a0, TCGReg a1, tcg_target_long a2); 1002 } TCGOutOpBinary; 1003 1004 typedef struct TCGOutOpBrcond { 1005 TCGOutOp base; 1006 void (*out_rr)(TCGContext *s, TCGType type, TCGCond cond, 1007 TCGReg a1, TCGReg a2, TCGLabel *label); 1008 void (*out_ri)(TCGContext *s, TCGType type, TCGCond cond, 1009 TCGReg a1, tcg_target_long a2, TCGLabel *label); 1010 } TCGOutOpBrcond; 1011 1012 typedef struct TCGOutOpBrcond2 { 1013 TCGOutOp base; 1014 void (*out)(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah, 1015 TCGArg bl, bool const_bl, 1016 TCGArg bh, bool const_bh, TCGLabel *l); 1017 } TCGOutOpBrcond2; 1018 1019 typedef struct TCGOutOpBswap { 1020 TCGOutOp base; 1021 void (*out_rr)(TCGContext *s, TCGType type, 1022 TCGReg a0, TCGReg a1, unsigned flags); 1023 } TCGOutOpBswap; 1024 1025 typedef struct TCGOutOpDeposit { 1026 TCGOutOp base; 1027 void (*out_rrr)(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1, 1028 TCGReg a2, unsigned ofs, unsigned len); 1029 void (*out_rri)(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1, 1030 tcg_target_long a2, unsigned ofs, unsigned len); 1031 void (*out_rzr)(TCGContext *s, TCGType type, TCGReg a0, 1032 TCGReg a2, unsigned ofs, unsigned len); 1033 } TCGOutOpDeposit; 1034 1035 typedef struct TCGOutOpDivRem { 1036 TCGOutOp base; 1037 void (*out_rr01r)(TCGContext *s, TCGType type, 1038 TCGReg a0, TCGReg a1, TCGReg a4); 1039 } TCGOutOpDivRem; 1040 1041 typedef struct TCGOutOpExtract { 1042 TCGOutOp base; 1043 void (*out_rr)(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1, 1044 unsigned ofs, unsigned len); 1045 } TCGOutOpExtract; 1046 1047 typedef struct TCGOutOpExtract2 { 1048 TCGOutOp base; 1049 void (*out_rrr)(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1, 1050 TCGReg a2, unsigned shr); 1051 } TCGOutOpExtract2; 1052 1053 typedef struct TCGOutOpLoad { 1054 TCGOutOp base; 1055 void (*out)(TCGContext *s, TCGType type, TCGReg dest, 1056 TCGReg base, intptr_t offset); 1057 } TCGOutOpLoad; 1058 1059 typedef struct TCGOutOpMovcond { 1060 TCGOutOp base; 1061 void (*out)(TCGContext *s, TCGType type, TCGCond cond, 1062 TCGReg ret, TCGReg c1, TCGArg c2, bool const_c2, 1063 TCGArg vt, bool const_vt, TCGArg vf, bool consf_vf); 1064 } TCGOutOpMovcond; 1065 1066 typedef struct TCGOutOpMul2 { 1067 TCGOutOp base; 1068 void (*out_rrrr)(TCGContext *s, TCGType type, 1069 TCGReg a0, TCGReg a1, TCGReg a2, TCGReg a3); 1070 } TCGOutOpMul2; 1071 1072 typedef struct TCGOutOpQemuLdSt { 1073 TCGOutOp base; 1074 void (*out)(TCGContext *s, TCGType type, TCGReg dest, 1075 TCGReg addr, MemOpIdx oi); 1076 } TCGOutOpQemuLdSt; 1077 1078 typedef struct TCGOutOpQemuLdSt2 { 1079 TCGOutOp base; 1080 void (*out)(TCGContext *s, TCGType type, TCGReg dlo, TCGReg dhi, 1081 TCGReg addr, MemOpIdx oi); 1082 } TCGOutOpQemuLdSt2; 1083 1084 typedef struct TCGOutOpUnary { 1085 TCGOutOp base; 1086 void (*out_rr)(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1); 1087 } TCGOutOpUnary; 1088 1089 typedef struct TCGOutOpSetcond { 1090 TCGOutOp base; 1091 void (*out_rrr)(TCGContext *s, TCGType type, TCGCond cond, 1092 TCGReg ret, TCGReg a1, TCGReg a2); 1093 void (*out_rri)(TCGContext *s, TCGType type, TCGCond cond, 1094 TCGReg ret, TCGReg a1, tcg_target_long a2); 1095 } TCGOutOpSetcond; 1096 1097 typedef struct TCGOutOpSetcond2 { 1098 TCGOutOp base; 1099 void (*out)(TCGContext *s, TCGCond cond, TCGReg ret, TCGReg al, TCGReg ah, 1100 TCGArg bl, bool const_bl, TCGArg bh, bool const_bh); 1101 } TCGOutOpSetcond2; 1102 1103 typedef struct TCGOutOpStore { 1104 TCGOutOp base; 1105 void (*out_r)(TCGContext *s, TCGType type, TCGReg data, 1106 TCGReg base, intptr_t offset); 1107 void (*out_i)(TCGContext *s, TCGType type, tcg_target_long data, 1108 TCGReg base, intptr_t offset); 1109 } TCGOutOpStore; 1110 1111 typedef struct TCGOutOpSubtract { 1112 TCGOutOp base; 1113 void (*out_rrr)(TCGContext *s, TCGType type, 1114 TCGReg a0, TCGReg a1, TCGReg a2); 1115 void (*out_rir)(TCGContext *s, TCGType type, 1116 TCGReg a0, tcg_target_long a1, TCGReg a2); 1117 } TCGOutOpSubtract; 1118 1119 #include "tcg-target.c.inc" 1120 1121 #ifndef CONFIG_TCG_INTERPRETER 1122 /* Validate CPUTLBDescFast placement. */ 1123 QEMU_BUILD_BUG_ON((int)(offsetof(CPUNegativeOffsetState, tlb.f[0]) - 1124 sizeof(CPUNegativeOffsetState)) 1125 < MIN_TLB_MASK_TABLE_OFS); 1126 #endif 1127 1128 #if TCG_TARGET_REG_BITS == 64 1129 /* 1130 * We require these functions for slow-path function calls. 1131 * Adapt them generically for opcode output. 1132 */ 1133 1134 static void tgen_exts_i32_i64(TCGContext *s, TCGType t, TCGReg a0, TCGReg a1) 1135 { 1136 tcg_out_exts_i32_i64(s, a0, a1); 1137 } 1138 1139 static const TCGOutOpUnary outop_exts_i32_i64 = { 1140 .base.static_constraint = C_O1_I1(r, r), 1141 .out_rr = tgen_exts_i32_i64, 1142 }; 1143 1144 static void tgen_extu_i32_i64(TCGContext *s, TCGType t, TCGReg a0, TCGReg a1) 1145 { 1146 tcg_out_extu_i32_i64(s, a0, a1); 1147 } 1148 1149 static const TCGOutOpUnary outop_extu_i32_i64 = { 1150 .base.static_constraint = C_O1_I1(r, r), 1151 .out_rr = tgen_extu_i32_i64, 1152 }; 1153 1154 static void tgen_extrl_i64_i32(TCGContext *s, TCGType t, TCGReg a0, TCGReg a1) 1155 { 1156 tcg_out_extrl_i64_i32(s, a0, a1); 1157 } 1158 1159 static const TCGOutOpUnary outop_extrl_i64_i32 = { 1160 .base.static_constraint = C_O1_I1(r, r), 1161 .out_rr = TCG_TARGET_HAS_extr_i64_i32 ? tgen_extrl_i64_i32 : NULL, 1162 }; 1163 #endif 1164 1165 static const TCGOutOp outop_goto_ptr = { 1166 .static_constraint = C_O0_I1(r), 1167 }; 1168 1169 static const TCGOutOpLoad outop_ld = { 1170 .base.static_constraint = C_O1_I1(r, r), 1171 .out = tcg_out_ld, 1172 }; 1173 1174 /* 1175 * Register V as the TCGOutOp for O. 1176 * This verifies that V is of type T, otherwise give a nice compiler error. 1177 * This prevents trivial mistakes within each arch/tcg-target.c.inc. 1178 */ 1179 #define OUTOP(O, T, V) [O] = _Generic(V, T: &V.base) 1180 1181 /* Register allocation descriptions for every TCGOpcode. */ 1182 static const TCGOutOp * const all_outop[NB_OPS] = { 1183 OUTOP(INDEX_op_add, TCGOutOpBinary, outop_add), 1184 OUTOP(INDEX_op_addci, TCGOutOpAddSubCarry, outop_addci), 1185 OUTOP(INDEX_op_addcio, TCGOutOpBinary, outop_addcio), 1186 OUTOP(INDEX_op_addco, TCGOutOpBinary, outop_addco), 1187 /* addc1o is implemented with set_carry + addcio */ 1188 OUTOP(INDEX_op_addc1o, TCGOutOpBinary, outop_addcio), 1189 OUTOP(INDEX_op_and, TCGOutOpBinary, outop_and), 1190 OUTOP(INDEX_op_andc, TCGOutOpBinary, outop_andc), 1191 OUTOP(INDEX_op_brcond, TCGOutOpBrcond, outop_brcond), 1192 OUTOP(INDEX_op_bswap16, TCGOutOpBswap, outop_bswap16), 1193 OUTOP(INDEX_op_bswap32, TCGOutOpBswap, outop_bswap32), 1194 OUTOP(INDEX_op_clz, TCGOutOpBinary, outop_clz), 1195 OUTOP(INDEX_op_ctpop, TCGOutOpUnary, outop_ctpop), 1196 OUTOP(INDEX_op_ctz, TCGOutOpBinary, outop_ctz), 1197 OUTOP(INDEX_op_deposit, TCGOutOpDeposit, outop_deposit), 1198 OUTOP(INDEX_op_divs, TCGOutOpBinary, outop_divs), 1199 OUTOP(INDEX_op_divu, TCGOutOpBinary, outop_divu), 1200 OUTOP(INDEX_op_divs2, TCGOutOpDivRem, outop_divs2), 1201 OUTOP(INDEX_op_divu2, TCGOutOpDivRem, outop_divu2), 1202 OUTOP(INDEX_op_eqv, TCGOutOpBinary, outop_eqv), 1203 OUTOP(INDEX_op_extract, TCGOutOpExtract, outop_extract), 1204 OUTOP(INDEX_op_extract2, TCGOutOpExtract2, outop_extract2), 1205 OUTOP(INDEX_op_ld8u, TCGOutOpLoad, outop_ld8u), 1206 OUTOP(INDEX_op_ld8s, TCGOutOpLoad, outop_ld8s), 1207 OUTOP(INDEX_op_ld16u, TCGOutOpLoad, outop_ld16u), 1208 OUTOP(INDEX_op_ld16s, TCGOutOpLoad, outop_ld16s), 1209 OUTOP(INDEX_op_ld, TCGOutOpLoad, outop_ld), 1210 OUTOP(INDEX_op_movcond, TCGOutOpMovcond, outop_movcond), 1211 OUTOP(INDEX_op_mul, TCGOutOpBinary, outop_mul), 1212 OUTOP(INDEX_op_muls2, TCGOutOpMul2, outop_muls2), 1213 OUTOP(INDEX_op_mulsh, TCGOutOpBinary, outop_mulsh), 1214 OUTOP(INDEX_op_mulu2, TCGOutOpMul2, outop_mulu2), 1215 OUTOP(INDEX_op_muluh, TCGOutOpBinary, outop_muluh), 1216 OUTOP(INDEX_op_nand, TCGOutOpBinary, outop_nand), 1217 OUTOP(INDEX_op_neg, TCGOutOpUnary, outop_neg), 1218 OUTOP(INDEX_op_negsetcond, TCGOutOpSetcond, outop_negsetcond), 1219 OUTOP(INDEX_op_nor, TCGOutOpBinary, outop_nor), 1220 OUTOP(INDEX_op_not, TCGOutOpUnary, outop_not), 1221 OUTOP(INDEX_op_or, TCGOutOpBinary, outop_or), 1222 OUTOP(INDEX_op_orc, TCGOutOpBinary, outop_orc), 1223 OUTOP(INDEX_op_qemu_ld, TCGOutOpQemuLdSt, outop_qemu_ld), 1224 OUTOP(INDEX_op_qemu_ld2, TCGOutOpQemuLdSt2, outop_qemu_ld2), 1225 OUTOP(INDEX_op_qemu_st, TCGOutOpQemuLdSt, outop_qemu_st), 1226 OUTOP(INDEX_op_qemu_st2, TCGOutOpQemuLdSt2, outop_qemu_st2), 1227 OUTOP(INDEX_op_rems, TCGOutOpBinary, outop_rems), 1228 OUTOP(INDEX_op_remu, TCGOutOpBinary, outop_remu), 1229 OUTOP(INDEX_op_rotl, TCGOutOpBinary, outop_rotl), 1230 OUTOP(INDEX_op_rotr, TCGOutOpBinary, outop_rotr), 1231 OUTOP(INDEX_op_sar, TCGOutOpBinary, outop_sar), 1232 OUTOP(INDEX_op_setcond, TCGOutOpSetcond, outop_setcond), 1233 OUTOP(INDEX_op_sextract, TCGOutOpExtract, outop_sextract), 1234 OUTOP(INDEX_op_shl, TCGOutOpBinary, outop_shl), 1235 OUTOP(INDEX_op_shr, TCGOutOpBinary, outop_shr), 1236 OUTOP(INDEX_op_st, TCGOutOpStore, outop_st), 1237 OUTOP(INDEX_op_st8, TCGOutOpStore, outop_st8), 1238 OUTOP(INDEX_op_st16, TCGOutOpStore, outop_st16), 1239 OUTOP(INDEX_op_sub, TCGOutOpSubtract, outop_sub), 1240 OUTOP(INDEX_op_subbi, TCGOutOpAddSubCarry, outop_subbi), 1241 OUTOP(INDEX_op_subbio, TCGOutOpAddSubCarry, outop_subbio), 1242 OUTOP(INDEX_op_subbo, TCGOutOpAddSubCarry, outop_subbo), 1243 /* subb1o is implemented with set_borrow + subbio */ 1244 OUTOP(INDEX_op_subb1o, TCGOutOpAddSubCarry, outop_subbio), 1245 OUTOP(INDEX_op_xor, TCGOutOpBinary, outop_xor), 1246 1247 [INDEX_op_goto_ptr] = &outop_goto_ptr, 1248 1249 #if TCG_TARGET_REG_BITS == 32 1250 OUTOP(INDEX_op_brcond2_i32, TCGOutOpBrcond2, outop_brcond2), 1251 OUTOP(INDEX_op_setcond2_i32, TCGOutOpSetcond2, outop_setcond2), 1252 #else 1253 OUTOP(INDEX_op_bswap64, TCGOutOpUnary, outop_bswap64), 1254 OUTOP(INDEX_op_ext_i32_i64, TCGOutOpUnary, outop_exts_i32_i64), 1255 OUTOP(INDEX_op_extu_i32_i64, TCGOutOpUnary, outop_extu_i32_i64), 1256 OUTOP(INDEX_op_extrl_i64_i32, TCGOutOpUnary, outop_extrl_i64_i32), 1257 OUTOP(INDEX_op_extrh_i64_i32, TCGOutOpUnary, outop_extrh_i64_i32), 1258 OUTOP(INDEX_op_ld32u, TCGOutOpLoad, outop_ld32u), 1259 OUTOP(INDEX_op_ld32s, TCGOutOpLoad, outop_ld32s), 1260 OUTOP(INDEX_op_st32, TCGOutOpStore, outop_st), 1261 #endif 1262 }; 1263 1264 #undef OUTOP 1265 1266 /* 1267 * All TCG threads except the parent (i.e. the one that called tcg_context_init 1268 * and registered the target's TCG globals) must register with this function 1269 * before initiating translation. 1270 * 1271 * In user-mode we just point tcg_ctx to tcg_init_ctx. See the documentation 1272 * of tcg_region_init() for the reasoning behind this. 1273 * 1274 * In system-mode each caller registers its context in tcg_ctxs[]. Note that in 1275 * system-mode tcg_ctxs[] does not track tcg_ctx_init, since the initial context 1276 * is not used anymore for translation once this function is called. 1277 * 1278 * Not tracking tcg_init_ctx in tcg_ctxs[] in system-mode keeps code that 1279 * iterates over the array (e.g. tcg_code_size() the same for both system/user 1280 * modes. 1281 */ 1282 #ifdef CONFIG_USER_ONLY 1283 void tcg_register_thread(void) 1284 { 1285 tcg_ctx = &tcg_init_ctx; 1286 } 1287 #else 1288 void tcg_register_thread(void) 1289 { 1290 TCGContext *s = g_malloc(sizeof(*s)); 1291 unsigned int i, n; 1292 1293 *s = tcg_init_ctx; 1294 1295 /* Relink mem_base. */ 1296 for (i = 0, n = tcg_init_ctx.nb_globals; i < n; ++i) { 1297 if (tcg_init_ctx.temps[i].mem_base) { 1298 ptrdiff_t b = tcg_init_ctx.temps[i].mem_base - tcg_init_ctx.temps; 1299 tcg_debug_assert(b >= 0 && b < n); 1300 s->temps[i].mem_base = &s->temps[b]; 1301 } 1302 } 1303 1304 /* Claim an entry in tcg_ctxs */ 1305 n = qatomic_fetch_inc(&tcg_cur_ctxs); 1306 g_assert(n < tcg_max_ctxs); 1307 qatomic_set(&tcg_ctxs[n], s); 1308 1309 if (n > 0) { 1310 tcg_region_initial_alloc(s); 1311 } 1312 1313 tcg_ctx = s; 1314 } 1315 #endif /* !CONFIG_USER_ONLY */ 1316 1317 /* pool based memory allocation */ 1318 void *tcg_malloc_internal(TCGContext *s, int size) 1319 { 1320 TCGPool *p; 1321 int pool_size; 1322 1323 if (size > TCG_POOL_CHUNK_SIZE) { 1324 /* big malloc: insert a new pool (XXX: could optimize) */ 1325 p = g_malloc(sizeof(TCGPool) + size); 1326 p->size = size; 1327 p->next = s->pool_first_large; 1328 s->pool_first_large = p; 1329 return p->data; 1330 } else { 1331 p = s->pool_current; 1332 if (!p) { 1333 p = s->pool_first; 1334 if (!p) { 1335 goto new_pool; 1336 } 1337 } else { 1338 if (!p->next) { 1339 new_pool: 1340 pool_size = TCG_POOL_CHUNK_SIZE; 1341 p = g_malloc(sizeof(TCGPool) + pool_size); 1342 p->size = pool_size; 1343 p->next = NULL; 1344 if (s->pool_current) { 1345 s->pool_current->next = p; 1346 } else { 1347 s->pool_first = p; 1348 } 1349 } else { 1350 p = p->next; 1351 } 1352 } 1353 } 1354 s->pool_current = p; 1355 s->pool_cur = (uintptr_t)p->data + size; 1356 s->pool_end = (uintptr_t)p->data + p->size; 1357 return p->data; 1358 } 1359 1360 void tcg_pool_reset(TCGContext *s) 1361 { 1362 TCGPool *p, *t; 1363 for (p = s->pool_first_large; p; p = t) { 1364 t = p->next; 1365 g_free(p); 1366 } 1367 s->pool_first_large = NULL; 1368 s->pool_cur = s->pool_end = 0; 1369 s->pool_current = NULL; 1370 } 1371 1372 /* 1373 * Create TCGHelperInfo structures for "tcg/tcg-ldst.h" functions, 1374 * akin to what "exec/helper-tcg.h" does with DEF_HELPER_FLAGS_N. 1375 * We only use these for layout in tcg_out_ld_helper_ret and 1376 * tcg_out_st_helper_args, and share them between several of 1377 * the helpers, with the end result that it's easier to build manually. 1378 */ 1379 1380 #if TCG_TARGET_REG_BITS == 32 1381 # define dh_typecode_ttl dh_typecode_i32 1382 #else 1383 # define dh_typecode_ttl dh_typecode_i64 1384 #endif 1385 1386 static TCGHelperInfo info_helper_ld32_mmu = { 1387 .flags = TCG_CALL_NO_WG, 1388 .typemask = dh_typemask(ttl, 0) /* return tcg_target_ulong */ 1389 | dh_typemask(env, 1) 1390 | dh_typemask(i64, 2) /* uint64_t addr */ 1391 | dh_typemask(i32, 3) /* unsigned oi */ 1392 | dh_typemask(ptr, 4) /* uintptr_t ra */ 1393 }; 1394 1395 static TCGHelperInfo info_helper_ld64_mmu = { 1396 .flags = TCG_CALL_NO_WG, 1397 .typemask = dh_typemask(i64, 0) /* return uint64_t */ 1398 | dh_typemask(env, 1) 1399 | dh_typemask(i64, 2) /* uint64_t addr */ 1400 | dh_typemask(i32, 3) /* unsigned oi */ 1401 | dh_typemask(ptr, 4) /* uintptr_t ra */ 1402 }; 1403 1404 static TCGHelperInfo info_helper_ld128_mmu = { 1405 .flags = TCG_CALL_NO_WG, 1406 .typemask = dh_typemask(i128, 0) /* return Int128 */ 1407 | dh_typemask(env, 1) 1408 | dh_typemask(i64, 2) /* uint64_t addr */ 1409 | dh_typemask(i32, 3) /* unsigned oi */ 1410 | dh_typemask(ptr, 4) /* uintptr_t ra */ 1411 }; 1412 1413 static TCGHelperInfo info_helper_st32_mmu = { 1414 .flags = TCG_CALL_NO_WG, 1415 .typemask = dh_typemask(void, 0) 1416 | dh_typemask(env, 1) 1417 | dh_typemask(i64, 2) /* uint64_t addr */ 1418 | dh_typemask(i32, 3) /* uint32_t data */ 1419 | dh_typemask(i32, 4) /* unsigned oi */ 1420 | dh_typemask(ptr, 5) /* uintptr_t ra */ 1421 }; 1422 1423 static TCGHelperInfo info_helper_st64_mmu = { 1424 .flags = TCG_CALL_NO_WG, 1425 .typemask = dh_typemask(void, 0) 1426 | dh_typemask(env, 1) 1427 | dh_typemask(i64, 2) /* uint64_t addr */ 1428 | dh_typemask(i64, 3) /* uint64_t data */ 1429 | dh_typemask(i32, 4) /* unsigned oi */ 1430 | dh_typemask(ptr, 5) /* uintptr_t ra */ 1431 }; 1432 1433 static TCGHelperInfo info_helper_st128_mmu = { 1434 .flags = TCG_CALL_NO_WG, 1435 .typemask = dh_typemask(void, 0) 1436 | dh_typemask(env, 1) 1437 | dh_typemask(i64, 2) /* uint64_t addr */ 1438 | dh_typemask(i128, 3) /* Int128 data */ 1439 | dh_typemask(i32, 4) /* unsigned oi */ 1440 | dh_typemask(ptr, 5) /* uintptr_t ra */ 1441 }; 1442 1443 #ifdef CONFIG_TCG_INTERPRETER 1444 static ffi_type *typecode_to_ffi(int argmask) 1445 { 1446 /* 1447 * libffi does not support __int128_t, so we have forced Int128 1448 * to use the structure definition instead of the builtin type. 1449 */ 1450 static ffi_type *ffi_type_i128_elements[3] = { 1451 &ffi_type_uint64, 1452 &ffi_type_uint64, 1453 NULL 1454 }; 1455 static ffi_type ffi_type_i128 = { 1456 .size = 16, 1457 .alignment = __alignof__(Int128), 1458 .type = FFI_TYPE_STRUCT, 1459 .elements = ffi_type_i128_elements, 1460 }; 1461 1462 switch (argmask) { 1463 case dh_typecode_void: 1464 return &ffi_type_void; 1465 case dh_typecode_i32: 1466 return &ffi_type_uint32; 1467 case dh_typecode_s32: 1468 return &ffi_type_sint32; 1469 case dh_typecode_i64: 1470 return &ffi_type_uint64; 1471 case dh_typecode_s64: 1472 return &ffi_type_sint64; 1473 case dh_typecode_ptr: 1474 return &ffi_type_pointer; 1475 case dh_typecode_i128: 1476 return &ffi_type_i128; 1477 } 1478 g_assert_not_reached(); 1479 } 1480 1481 static ffi_cif *init_ffi_layout(TCGHelperInfo *info) 1482 { 1483 unsigned typemask = info->typemask; 1484 struct { 1485 ffi_cif cif; 1486 ffi_type *args[]; 1487 } *ca; 1488 ffi_status status; 1489 int nargs; 1490 1491 /* Ignoring the return type, find the last non-zero field. */ 1492 nargs = 32 - clz32(typemask >> 3); 1493 nargs = DIV_ROUND_UP(nargs, 3); 1494 assert(nargs <= MAX_CALL_IARGS); 1495 1496 ca = g_malloc0(sizeof(*ca) + nargs * sizeof(ffi_type *)); 1497 ca->cif.rtype = typecode_to_ffi(typemask & 7); 1498 ca->cif.nargs = nargs; 1499 1500 if (nargs != 0) { 1501 ca->cif.arg_types = ca->args; 1502 for (int j = 0; j < nargs; ++j) { 1503 int typecode = extract32(typemask, (j + 1) * 3, 3); 1504 ca->args[j] = typecode_to_ffi(typecode); 1505 } 1506 } 1507 1508 status = ffi_prep_cif(&ca->cif, FFI_DEFAULT_ABI, nargs, 1509 ca->cif.rtype, ca->cif.arg_types); 1510 assert(status == FFI_OK); 1511 1512 return &ca->cif; 1513 } 1514 1515 #define HELPER_INFO_INIT(I) (&(I)->cif) 1516 #define HELPER_INFO_INIT_VAL(I) init_ffi_layout(I) 1517 #else 1518 #define HELPER_INFO_INIT(I) (&(I)->init) 1519 #define HELPER_INFO_INIT_VAL(I) 1 1520 #endif /* CONFIG_TCG_INTERPRETER */ 1521 1522 static inline bool arg_slot_reg_p(unsigned arg_slot) 1523 { 1524 /* 1525 * Split the sizeof away from the comparison to avoid Werror from 1526 * "unsigned < 0 is always false", when iarg_regs is empty. 1527 */ 1528 unsigned nreg = ARRAY_SIZE(tcg_target_call_iarg_regs); 1529 return arg_slot < nreg; 1530 } 1531 1532 static inline int arg_slot_stk_ofs(unsigned arg_slot) 1533 { 1534 unsigned max = TCG_STATIC_CALL_ARGS_SIZE / sizeof(tcg_target_long); 1535 unsigned stk_slot = arg_slot - ARRAY_SIZE(tcg_target_call_iarg_regs); 1536 1537 tcg_debug_assert(stk_slot < max); 1538 return TCG_TARGET_CALL_STACK_OFFSET + stk_slot * sizeof(tcg_target_long); 1539 } 1540 1541 typedef struct TCGCumulativeArgs { 1542 int arg_idx; /* tcg_gen_callN args[] */ 1543 int info_in_idx; /* TCGHelperInfo in[] */ 1544 int arg_slot; /* regs+stack slot */ 1545 int ref_slot; /* stack slots for references */ 1546 } TCGCumulativeArgs; 1547 1548 static void layout_arg_even(TCGCumulativeArgs *cum) 1549 { 1550 cum->arg_slot += cum->arg_slot & 1; 1551 } 1552 1553 static void layout_arg_1(TCGCumulativeArgs *cum, TCGHelperInfo *info, 1554 TCGCallArgumentKind kind) 1555 { 1556 TCGCallArgumentLoc *loc = &info->in[cum->info_in_idx]; 1557 1558 *loc = (TCGCallArgumentLoc){ 1559 .kind = kind, 1560 .arg_idx = cum->arg_idx, 1561 .arg_slot = cum->arg_slot, 1562 }; 1563 cum->info_in_idx++; 1564 cum->arg_slot++; 1565 } 1566 1567 static void layout_arg_normal_n(TCGCumulativeArgs *cum, 1568 TCGHelperInfo *info, int n) 1569 { 1570 TCGCallArgumentLoc *loc = &info->in[cum->info_in_idx]; 1571 1572 for (int i = 0; i < n; ++i) { 1573 /* Layout all using the same arg_idx, adjusting the subindex. */ 1574 loc[i] = (TCGCallArgumentLoc){ 1575 .kind = TCG_CALL_ARG_NORMAL, 1576 .arg_idx = cum->arg_idx, 1577 .tmp_subindex = i, 1578 .arg_slot = cum->arg_slot + i, 1579 }; 1580 } 1581 cum->info_in_idx += n; 1582 cum->arg_slot += n; 1583 } 1584 1585 static void layout_arg_by_ref(TCGCumulativeArgs *cum, TCGHelperInfo *info) 1586 { 1587 TCGCallArgumentLoc *loc = &info->in[cum->info_in_idx]; 1588 int n = 128 / TCG_TARGET_REG_BITS; 1589 1590 /* The first subindex carries the pointer. */ 1591 layout_arg_1(cum, info, TCG_CALL_ARG_BY_REF); 1592 1593 /* 1594 * The callee is allowed to clobber memory associated with 1595 * structure pass by-reference. Therefore we must make copies. 1596 * Allocate space from "ref_slot", which will be adjusted to 1597 * follow the parameters on the stack. 1598 */ 1599 loc[0].ref_slot = cum->ref_slot; 1600 1601 /* 1602 * Subsequent words also go into the reference slot, but 1603 * do not accumulate into the regular arguments. 1604 */ 1605 for (int i = 1; i < n; ++i) { 1606 loc[i] = (TCGCallArgumentLoc){ 1607 .kind = TCG_CALL_ARG_BY_REF_N, 1608 .arg_idx = cum->arg_idx, 1609 .tmp_subindex = i, 1610 .ref_slot = cum->ref_slot + i, 1611 }; 1612 } 1613 cum->info_in_idx += n - 1; /* i=0 accounted for in layout_arg_1 */ 1614 cum->ref_slot += n; 1615 } 1616 1617 static void init_call_layout(TCGHelperInfo *info) 1618 { 1619 int max_reg_slots = ARRAY_SIZE(tcg_target_call_iarg_regs); 1620 int max_stk_slots = TCG_STATIC_CALL_ARGS_SIZE / sizeof(tcg_target_long); 1621 unsigned typemask = info->typemask; 1622 unsigned typecode; 1623 TCGCumulativeArgs cum = { }; 1624 1625 /* 1626 * Parse and place any function return value. 1627 */ 1628 typecode = typemask & 7; 1629 switch (typecode) { 1630 case dh_typecode_void: 1631 info->nr_out = 0; 1632 break; 1633 case dh_typecode_i32: 1634 case dh_typecode_s32: 1635 case dh_typecode_ptr: 1636 info->nr_out = 1; 1637 info->out_kind = TCG_CALL_RET_NORMAL; 1638 break; 1639 case dh_typecode_i64: 1640 case dh_typecode_s64: 1641 info->nr_out = 64 / TCG_TARGET_REG_BITS; 1642 info->out_kind = TCG_CALL_RET_NORMAL; 1643 /* Query the last register now to trigger any assert early. */ 1644 tcg_target_call_oarg_reg(info->out_kind, info->nr_out - 1); 1645 break; 1646 case dh_typecode_i128: 1647 info->nr_out = 128 / TCG_TARGET_REG_BITS; 1648 info->out_kind = TCG_TARGET_CALL_RET_I128; 1649 switch (TCG_TARGET_CALL_RET_I128) { 1650 case TCG_CALL_RET_NORMAL: 1651 /* Query the last register now to trigger any assert early. */ 1652 tcg_target_call_oarg_reg(info->out_kind, info->nr_out - 1); 1653 break; 1654 case TCG_CALL_RET_BY_VEC: 1655 /* Query the single register now to trigger any assert early. */ 1656 tcg_target_call_oarg_reg(TCG_CALL_RET_BY_VEC, 0); 1657 break; 1658 case TCG_CALL_RET_BY_REF: 1659 /* 1660 * Allocate the first argument to the output. 1661 * We don't need to store this anywhere, just make it 1662 * unavailable for use in the input loop below. 1663 */ 1664 cum.arg_slot = 1; 1665 break; 1666 default: 1667 qemu_build_not_reached(); 1668 } 1669 break; 1670 default: 1671 g_assert_not_reached(); 1672 } 1673 1674 /* 1675 * Parse and place function arguments. 1676 */ 1677 for (typemask >>= 3; typemask; typemask >>= 3, cum.arg_idx++) { 1678 TCGCallArgumentKind kind; 1679 TCGType type; 1680 1681 typecode = typemask & 7; 1682 switch (typecode) { 1683 case dh_typecode_i32: 1684 case dh_typecode_s32: 1685 type = TCG_TYPE_I32; 1686 break; 1687 case dh_typecode_i64: 1688 case dh_typecode_s64: 1689 type = TCG_TYPE_I64; 1690 break; 1691 case dh_typecode_ptr: 1692 type = TCG_TYPE_PTR; 1693 break; 1694 case dh_typecode_i128: 1695 type = TCG_TYPE_I128; 1696 break; 1697 default: 1698 g_assert_not_reached(); 1699 } 1700 1701 switch (type) { 1702 case TCG_TYPE_I32: 1703 switch (TCG_TARGET_CALL_ARG_I32) { 1704 case TCG_CALL_ARG_EVEN: 1705 layout_arg_even(&cum); 1706 /* fall through */ 1707 case TCG_CALL_ARG_NORMAL: 1708 layout_arg_1(&cum, info, TCG_CALL_ARG_NORMAL); 1709 break; 1710 case TCG_CALL_ARG_EXTEND: 1711 kind = TCG_CALL_ARG_EXTEND_U + (typecode & 1); 1712 layout_arg_1(&cum, info, kind); 1713 break; 1714 default: 1715 qemu_build_not_reached(); 1716 } 1717 break; 1718 1719 case TCG_TYPE_I64: 1720 switch (TCG_TARGET_CALL_ARG_I64) { 1721 case TCG_CALL_ARG_EVEN: 1722 layout_arg_even(&cum); 1723 /* fall through */ 1724 case TCG_CALL_ARG_NORMAL: 1725 if (TCG_TARGET_REG_BITS == 32) { 1726 layout_arg_normal_n(&cum, info, 2); 1727 } else { 1728 layout_arg_1(&cum, info, TCG_CALL_ARG_NORMAL); 1729 } 1730 break; 1731 default: 1732 qemu_build_not_reached(); 1733 } 1734 break; 1735 1736 case TCG_TYPE_I128: 1737 switch (TCG_TARGET_CALL_ARG_I128) { 1738 case TCG_CALL_ARG_EVEN: 1739 layout_arg_even(&cum); 1740 /* fall through */ 1741 case TCG_CALL_ARG_NORMAL: 1742 layout_arg_normal_n(&cum, info, 128 / TCG_TARGET_REG_BITS); 1743 break; 1744 case TCG_CALL_ARG_BY_REF: 1745 layout_arg_by_ref(&cum, info); 1746 break; 1747 default: 1748 qemu_build_not_reached(); 1749 } 1750 break; 1751 1752 default: 1753 g_assert_not_reached(); 1754 } 1755 } 1756 info->nr_in = cum.info_in_idx; 1757 1758 /* Validate that we didn't overrun the input array. */ 1759 assert(cum.info_in_idx <= ARRAY_SIZE(info->in)); 1760 /* Validate the backend has enough argument space. */ 1761 assert(cum.arg_slot <= max_reg_slots + max_stk_slots); 1762 1763 /* 1764 * Relocate the "ref_slot" area to the end of the parameters. 1765 * Minimizing this stack offset helps code size for x86, 1766 * which has a signed 8-bit offset encoding. 1767 */ 1768 if (cum.ref_slot != 0) { 1769 int ref_base = 0; 1770 1771 if (cum.arg_slot > max_reg_slots) { 1772 int align = __alignof(Int128) / sizeof(tcg_target_long); 1773 1774 ref_base = cum.arg_slot - max_reg_slots; 1775 if (align > 1) { 1776 ref_base = ROUND_UP(ref_base, align); 1777 } 1778 } 1779 assert(ref_base + cum.ref_slot <= max_stk_slots); 1780 ref_base += max_reg_slots; 1781 1782 if (ref_base != 0) { 1783 for (int i = cum.info_in_idx - 1; i >= 0; --i) { 1784 TCGCallArgumentLoc *loc = &info->in[i]; 1785 switch (loc->kind) { 1786 case TCG_CALL_ARG_BY_REF: 1787 case TCG_CALL_ARG_BY_REF_N: 1788 loc->ref_slot += ref_base; 1789 break; 1790 default: 1791 break; 1792 } 1793 } 1794 } 1795 } 1796 } 1797 1798 static int indirect_reg_alloc_order[ARRAY_SIZE(tcg_target_reg_alloc_order)]; 1799 static void process_constraint_sets(void); 1800 static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type, 1801 TCGReg reg, const char *name); 1802 1803 static void tcg_context_init(unsigned max_threads) 1804 { 1805 TCGContext *s = &tcg_init_ctx; 1806 int n, i; 1807 TCGTemp *ts; 1808 1809 memset(s, 0, sizeof(*s)); 1810 s->nb_globals = 0; 1811 1812 init_call_layout(&info_helper_ld32_mmu); 1813 init_call_layout(&info_helper_ld64_mmu); 1814 init_call_layout(&info_helper_ld128_mmu); 1815 init_call_layout(&info_helper_st32_mmu); 1816 init_call_layout(&info_helper_st64_mmu); 1817 init_call_layout(&info_helper_st128_mmu); 1818 1819 tcg_target_init(s); 1820 process_constraint_sets(); 1821 1822 /* Reverse the order of the saved registers, assuming they're all at 1823 the start of tcg_target_reg_alloc_order. */ 1824 for (n = 0; n < ARRAY_SIZE(tcg_target_reg_alloc_order); ++n) { 1825 int r = tcg_target_reg_alloc_order[n]; 1826 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, r)) { 1827 break; 1828 } 1829 } 1830 for (i = 0; i < n; ++i) { 1831 indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[n - 1 - i]; 1832 } 1833 for (; i < ARRAY_SIZE(tcg_target_reg_alloc_order); ++i) { 1834 indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[i]; 1835 } 1836 1837 tcg_ctx = s; 1838 /* 1839 * In user-mode we simply share the init context among threads, since we 1840 * use a single region. See the documentation tcg_region_init() for the 1841 * reasoning behind this. 1842 * In system-mode we will have at most max_threads TCG threads. 1843 */ 1844 #ifdef CONFIG_USER_ONLY 1845 tcg_ctxs = &tcg_ctx; 1846 tcg_cur_ctxs = 1; 1847 tcg_max_ctxs = 1; 1848 #else 1849 tcg_max_ctxs = max_threads; 1850 tcg_ctxs = g_new0(TCGContext *, max_threads); 1851 #endif 1852 1853 tcg_debug_assert(!tcg_regset_test_reg(s->reserved_regs, TCG_AREG0)); 1854 ts = tcg_global_reg_new_internal(s, TCG_TYPE_PTR, TCG_AREG0, "env"); 1855 tcg_env = temp_tcgv_ptr(ts); 1856 } 1857 1858 void tcg_init(size_t tb_size, int splitwx, unsigned max_threads) 1859 { 1860 tcg_context_init(max_threads); 1861 tcg_region_init(tb_size, splitwx, max_threads); 1862 } 1863 1864 /* 1865 * Allocate TBs right before their corresponding translated code, making 1866 * sure that TBs and code are on different cache lines. 1867 */ 1868 TranslationBlock *tcg_tb_alloc(TCGContext *s) 1869 { 1870 uintptr_t align = qemu_icache_linesize; 1871 TranslationBlock *tb; 1872 void *next; 1873 1874 retry: 1875 tb = (void *)ROUND_UP((uintptr_t)s->code_gen_ptr, align); 1876 next = (void *)ROUND_UP((uintptr_t)(tb + 1), align); 1877 1878 if (unlikely(next > s->code_gen_highwater)) { 1879 if (tcg_region_alloc(s)) { 1880 return NULL; 1881 } 1882 goto retry; 1883 } 1884 qatomic_set(&s->code_gen_ptr, next); 1885 return tb; 1886 } 1887 1888 void tcg_prologue_init(void) 1889 { 1890 TCGContext *s = tcg_ctx; 1891 size_t prologue_size; 1892 1893 s->code_ptr = s->code_gen_ptr; 1894 s->code_buf = s->code_gen_ptr; 1895 s->data_gen_ptr = NULL; 1896 1897 #ifndef CONFIG_TCG_INTERPRETER 1898 tcg_qemu_tb_exec = (tcg_prologue_fn *)tcg_splitwx_to_rx(s->code_ptr); 1899 #endif 1900 1901 s->pool_labels = NULL; 1902 1903 qemu_thread_jit_write(); 1904 /* Generate the prologue. */ 1905 tcg_target_qemu_prologue(s); 1906 1907 /* Allow the prologue to put e.g. guest_base into a pool entry. */ 1908 { 1909 int result = tcg_out_pool_finalize(s); 1910 tcg_debug_assert(result == 0); 1911 } 1912 1913 prologue_size = tcg_current_code_size(s); 1914 perf_report_prologue(s->code_gen_ptr, prologue_size); 1915 1916 #ifndef CONFIG_TCG_INTERPRETER 1917 flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(s->code_buf), 1918 (uintptr_t)s->code_buf, prologue_size); 1919 #endif 1920 1921 if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) { 1922 FILE *logfile = qemu_log_trylock(); 1923 if (logfile) { 1924 fprintf(logfile, "PROLOGUE: [size=%zu]\n", prologue_size); 1925 if (s->data_gen_ptr) { 1926 size_t code_size = s->data_gen_ptr - s->code_gen_ptr; 1927 size_t data_size = prologue_size - code_size; 1928 size_t i; 1929 1930 disas(logfile, s->code_gen_ptr, code_size); 1931 1932 for (i = 0; i < data_size; i += sizeof(tcg_target_ulong)) { 1933 if (sizeof(tcg_target_ulong) == 8) { 1934 fprintf(logfile, 1935 "0x%08" PRIxPTR ": .quad 0x%016" PRIx64 "\n", 1936 (uintptr_t)s->data_gen_ptr + i, 1937 *(uint64_t *)(s->data_gen_ptr + i)); 1938 } else { 1939 fprintf(logfile, 1940 "0x%08" PRIxPTR ": .long 0x%08x\n", 1941 (uintptr_t)s->data_gen_ptr + i, 1942 *(uint32_t *)(s->data_gen_ptr + i)); 1943 } 1944 } 1945 } else { 1946 disas(logfile, s->code_gen_ptr, prologue_size); 1947 } 1948 fprintf(logfile, "\n"); 1949 qemu_log_unlock(logfile); 1950 } 1951 } 1952 1953 #ifndef CONFIG_TCG_INTERPRETER 1954 /* 1955 * Assert that goto_ptr is implemented completely, setting an epilogue. 1956 * For tci, we use NULL as the signal to return from the interpreter, 1957 * so skip this check. 1958 */ 1959 tcg_debug_assert(tcg_code_gen_epilogue != NULL); 1960 #endif 1961 1962 tcg_region_prologue_set(s); 1963 } 1964 1965 void tcg_func_start(TCGContext *s) 1966 { 1967 tcg_pool_reset(s); 1968 s->nb_temps = s->nb_globals; 1969 1970 /* No temps have been previously allocated for size or locality. */ 1971 tcg_temp_ebb_reset_freed(s); 1972 1973 /* No constant temps have been previously allocated. */ 1974 for (int i = 0; i < TCG_TYPE_COUNT; ++i) { 1975 if (s->const_table[i]) { 1976 g_hash_table_remove_all(s->const_table[i]); 1977 } 1978 } 1979 1980 s->nb_ops = 0; 1981 s->nb_labels = 0; 1982 s->current_frame_offset = s->frame_start; 1983 1984 #ifdef CONFIG_DEBUG_TCG 1985 s->goto_tb_issue_mask = 0; 1986 #endif 1987 1988 QTAILQ_INIT(&s->ops); 1989 QTAILQ_INIT(&s->free_ops); 1990 s->emit_before_op = NULL; 1991 QSIMPLEQ_INIT(&s->labels); 1992 1993 tcg_debug_assert(s->addr_type <= TCG_TYPE_REG); 1994 } 1995 1996 static TCGTemp *tcg_temp_alloc(TCGContext *s) 1997 { 1998 int n = s->nb_temps++; 1999 2000 if (n >= TCG_MAX_TEMPS) { 2001 tcg_raise_tb_overflow(s); 2002 } 2003 return memset(&s->temps[n], 0, sizeof(TCGTemp)); 2004 } 2005 2006 static TCGTemp *tcg_global_alloc(TCGContext *s) 2007 { 2008 TCGTemp *ts; 2009 2010 tcg_debug_assert(s->nb_globals == s->nb_temps); 2011 tcg_debug_assert(s->nb_globals < TCG_MAX_TEMPS); 2012 s->nb_globals++; 2013 ts = tcg_temp_alloc(s); 2014 ts->kind = TEMP_GLOBAL; 2015 2016 return ts; 2017 } 2018 2019 static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type, 2020 TCGReg reg, const char *name) 2021 { 2022 TCGTemp *ts; 2023 2024 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32); 2025 2026 ts = tcg_global_alloc(s); 2027 ts->base_type = type; 2028 ts->type = type; 2029 ts->kind = TEMP_FIXED; 2030 ts->reg = reg; 2031 ts->name = name; 2032 tcg_regset_set_reg(s->reserved_regs, reg); 2033 2034 return ts; 2035 } 2036 2037 void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size) 2038 { 2039 s->frame_start = start; 2040 s->frame_end = start + size; 2041 s->frame_temp 2042 = tcg_global_reg_new_internal(s, TCG_TYPE_PTR, reg, "_frame"); 2043 } 2044 2045 static TCGTemp *tcg_global_mem_new_internal(TCGv_ptr base, intptr_t offset, 2046 const char *name, TCGType type) 2047 { 2048 TCGContext *s = tcg_ctx; 2049 TCGTemp *base_ts = tcgv_ptr_temp(base); 2050 TCGTemp *ts = tcg_global_alloc(s); 2051 int indirect_reg = 0; 2052 2053 switch (base_ts->kind) { 2054 case TEMP_FIXED: 2055 break; 2056 case TEMP_GLOBAL: 2057 /* We do not support double-indirect registers. */ 2058 tcg_debug_assert(!base_ts->indirect_reg); 2059 base_ts->indirect_base = 1; 2060 s->nb_indirects += (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64 2061 ? 2 : 1); 2062 indirect_reg = 1; 2063 break; 2064 default: 2065 g_assert_not_reached(); 2066 } 2067 2068 if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) { 2069 TCGTemp *ts2 = tcg_global_alloc(s); 2070 char buf[64]; 2071 2072 ts->base_type = TCG_TYPE_I64; 2073 ts->type = TCG_TYPE_I32; 2074 ts->indirect_reg = indirect_reg; 2075 ts->mem_allocated = 1; 2076 ts->mem_base = base_ts; 2077 ts->mem_offset = offset; 2078 pstrcpy(buf, sizeof(buf), name); 2079 pstrcat(buf, sizeof(buf), "_0"); 2080 ts->name = strdup(buf); 2081 2082 tcg_debug_assert(ts2 == ts + 1); 2083 ts2->base_type = TCG_TYPE_I64; 2084 ts2->type = TCG_TYPE_I32; 2085 ts2->indirect_reg = indirect_reg; 2086 ts2->mem_allocated = 1; 2087 ts2->mem_base = base_ts; 2088 ts2->mem_offset = offset + 4; 2089 ts2->temp_subindex = 1; 2090 pstrcpy(buf, sizeof(buf), name); 2091 pstrcat(buf, sizeof(buf), "_1"); 2092 ts2->name = strdup(buf); 2093 } else { 2094 ts->base_type = type; 2095 ts->type = type; 2096 ts->indirect_reg = indirect_reg; 2097 ts->mem_allocated = 1; 2098 ts->mem_base = base_ts; 2099 ts->mem_offset = offset; 2100 ts->name = name; 2101 } 2102 return ts; 2103 } 2104 2105 TCGv_i32 tcg_global_mem_new_i32(TCGv_ptr reg, intptr_t off, const char *name) 2106 { 2107 TCGTemp *ts = tcg_global_mem_new_internal(reg, off, name, TCG_TYPE_I32); 2108 return temp_tcgv_i32(ts); 2109 } 2110 2111 TCGv_i64 tcg_global_mem_new_i64(TCGv_ptr reg, intptr_t off, const char *name) 2112 { 2113 TCGTemp *ts = tcg_global_mem_new_internal(reg, off, name, TCG_TYPE_I64); 2114 return temp_tcgv_i64(ts); 2115 } 2116 2117 TCGv_ptr tcg_global_mem_new_ptr(TCGv_ptr reg, intptr_t off, const char *name) 2118 { 2119 TCGTemp *ts = tcg_global_mem_new_internal(reg, off, name, TCG_TYPE_PTR); 2120 return temp_tcgv_ptr(ts); 2121 } 2122 2123 TCGTemp *tcg_temp_new_internal(TCGType type, TCGTempKind kind) 2124 { 2125 TCGContext *s = tcg_ctx; 2126 TCGTemp *ts; 2127 int n; 2128 2129 if (kind == TEMP_EBB) { 2130 int idx = find_first_bit(s->free_temps[type].l, TCG_MAX_TEMPS); 2131 2132 if (idx < TCG_MAX_TEMPS) { 2133 /* There is already an available temp with the right type. */ 2134 clear_bit(idx, s->free_temps[type].l); 2135 2136 ts = &s->temps[idx]; 2137 ts->temp_allocated = 1; 2138 tcg_debug_assert(ts->base_type == type); 2139 tcg_debug_assert(ts->kind == kind); 2140 return ts; 2141 } 2142 } else { 2143 tcg_debug_assert(kind == TEMP_TB); 2144 } 2145 2146 switch (type) { 2147 case TCG_TYPE_I32: 2148 case TCG_TYPE_V64: 2149 case TCG_TYPE_V128: 2150 case TCG_TYPE_V256: 2151 n = 1; 2152 break; 2153 case TCG_TYPE_I64: 2154 n = 64 / TCG_TARGET_REG_BITS; 2155 break; 2156 case TCG_TYPE_I128: 2157 n = 128 / TCG_TARGET_REG_BITS; 2158 break; 2159 default: 2160 g_assert_not_reached(); 2161 } 2162 2163 ts = tcg_temp_alloc(s); 2164 ts->base_type = type; 2165 ts->temp_allocated = 1; 2166 ts->kind = kind; 2167 2168 if (n == 1) { 2169 ts->type = type; 2170 } else { 2171 ts->type = TCG_TYPE_REG; 2172 2173 for (int i = 1; i < n; ++i) { 2174 TCGTemp *ts2 = tcg_temp_alloc(s); 2175 2176 tcg_debug_assert(ts2 == ts + i); 2177 ts2->base_type = type; 2178 ts2->type = TCG_TYPE_REG; 2179 ts2->temp_allocated = 1; 2180 ts2->temp_subindex = i; 2181 ts2->kind = kind; 2182 } 2183 } 2184 return ts; 2185 } 2186 2187 TCGv_i32 tcg_temp_new_i32(void) 2188 { 2189 return temp_tcgv_i32(tcg_temp_new_internal(TCG_TYPE_I32, TEMP_TB)); 2190 } 2191 2192 TCGv_i32 tcg_temp_ebb_new_i32(void) 2193 { 2194 return temp_tcgv_i32(tcg_temp_new_internal(TCG_TYPE_I32, TEMP_EBB)); 2195 } 2196 2197 TCGv_i64 tcg_temp_new_i64(void) 2198 { 2199 return temp_tcgv_i64(tcg_temp_new_internal(TCG_TYPE_I64, TEMP_TB)); 2200 } 2201 2202 TCGv_i64 tcg_temp_ebb_new_i64(void) 2203 { 2204 return temp_tcgv_i64(tcg_temp_new_internal(TCG_TYPE_I64, TEMP_EBB)); 2205 } 2206 2207 TCGv_ptr tcg_temp_new_ptr(void) 2208 { 2209 return temp_tcgv_ptr(tcg_temp_new_internal(TCG_TYPE_PTR, TEMP_TB)); 2210 } 2211 2212 TCGv_ptr tcg_temp_ebb_new_ptr(void) 2213 { 2214 return temp_tcgv_ptr(tcg_temp_new_internal(TCG_TYPE_PTR, TEMP_EBB)); 2215 } 2216 2217 TCGv_i128 tcg_temp_new_i128(void) 2218 { 2219 return temp_tcgv_i128(tcg_temp_new_internal(TCG_TYPE_I128, TEMP_TB)); 2220 } 2221 2222 TCGv_i128 tcg_temp_ebb_new_i128(void) 2223 { 2224 return temp_tcgv_i128(tcg_temp_new_internal(TCG_TYPE_I128, TEMP_EBB)); 2225 } 2226 2227 TCGv_vec tcg_temp_new_vec(TCGType type) 2228 { 2229 TCGTemp *t; 2230 2231 #ifdef CONFIG_DEBUG_TCG 2232 switch (type) { 2233 case TCG_TYPE_V64: 2234 assert(TCG_TARGET_HAS_v64); 2235 break; 2236 case TCG_TYPE_V128: 2237 assert(TCG_TARGET_HAS_v128); 2238 break; 2239 case TCG_TYPE_V256: 2240 assert(TCG_TARGET_HAS_v256); 2241 break; 2242 default: 2243 g_assert_not_reached(); 2244 } 2245 #endif 2246 2247 t = tcg_temp_new_internal(type, TEMP_EBB); 2248 return temp_tcgv_vec(t); 2249 } 2250 2251 /* Create a new temp of the same type as an existing temp. */ 2252 TCGv_vec tcg_temp_new_vec_matching(TCGv_vec match) 2253 { 2254 TCGTemp *t = tcgv_vec_temp(match); 2255 2256 tcg_debug_assert(t->temp_allocated != 0); 2257 2258 t = tcg_temp_new_internal(t->base_type, TEMP_EBB); 2259 return temp_tcgv_vec(t); 2260 } 2261 2262 void tcg_temp_free_internal(TCGTemp *ts) 2263 { 2264 TCGContext *s = tcg_ctx; 2265 2266 switch (ts->kind) { 2267 case TEMP_CONST: 2268 case TEMP_TB: 2269 /* Silently ignore free. */ 2270 break; 2271 case TEMP_EBB: 2272 tcg_debug_assert(ts->temp_allocated != 0); 2273 ts->temp_allocated = 0; 2274 set_bit(temp_idx(ts), s->free_temps[ts->base_type].l); 2275 break; 2276 default: 2277 /* It never made sense to free TEMP_FIXED or TEMP_GLOBAL. */ 2278 g_assert_not_reached(); 2279 } 2280 } 2281 2282 void tcg_temp_free_i32(TCGv_i32 arg) 2283 { 2284 tcg_temp_free_internal(tcgv_i32_temp(arg)); 2285 } 2286 2287 void tcg_temp_free_i64(TCGv_i64 arg) 2288 { 2289 tcg_temp_free_internal(tcgv_i64_temp(arg)); 2290 } 2291 2292 void tcg_temp_free_i128(TCGv_i128 arg) 2293 { 2294 tcg_temp_free_internal(tcgv_i128_temp(arg)); 2295 } 2296 2297 void tcg_temp_free_ptr(TCGv_ptr arg) 2298 { 2299 tcg_temp_free_internal(tcgv_ptr_temp(arg)); 2300 } 2301 2302 void tcg_temp_free_vec(TCGv_vec arg) 2303 { 2304 tcg_temp_free_internal(tcgv_vec_temp(arg)); 2305 } 2306 2307 TCGTemp *tcg_constant_internal(TCGType type, int64_t val) 2308 { 2309 TCGContext *s = tcg_ctx; 2310 GHashTable *h = s->const_table[type]; 2311 TCGTemp *ts; 2312 2313 if (h == NULL) { 2314 h = g_hash_table_new(g_int64_hash, g_int64_equal); 2315 s->const_table[type] = h; 2316 } 2317 2318 ts = g_hash_table_lookup(h, &val); 2319 if (ts == NULL) { 2320 int64_t *val_ptr; 2321 2322 ts = tcg_temp_alloc(s); 2323 2324 if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) { 2325 TCGTemp *ts2 = tcg_temp_alloc(s); 2326 2327 tcg_debug_assert(ts2 == ts + 1); 2328 2329 ts->base_type = TCG_TYPE_I64; 2330 ts->type = TCG_TYPE_I32; 2331 ts->kind = TEMP_CONST; 2332 ts->temp_allocated = 1; 2333 2334 ts2->base_type = TCG_TYPE_I64; 2335 ts2->type = TCG_TYPE_I32; 2336 ts2->kind = TEMP_CONST; 2337 ts2->temp_allocated = 1; 2338 ts2->temp_subindex = 1; 2339 2340 /* 2341 * Retain the full value of the 64-bit constant in the low 2342 * part, so that the hash table works. Actual uses will 2343 * truncate the value to the low part. 2344 */ 2345 ts[HOST_BIG_ENDIAN].val = val; 2346 ts[!HOST_BIG_ENDIAN].val = val >> 32; 2347 val_ptr = &ts[HOST_BIG_ENDIAN].val; 2348 } else { 2349 ts->base_type = type; 2350 ts->type = type; 2351 ts->kind = TEMP_CONST; 2352 ts->temp_allocated = 1; 2353 ts->val = val; 2354 val_ptr = &ts->val; 2355 } 2356 g_hash_table_insert(h, val_ptr, ts); 2357 } 2358 2359 return ts; 2360 } 2361 2362 TCGv_i32 tcg_constant_i32(int32_t val) 2363 { 2364 return temp_tcgv_i32(tcg_constant_internal(TCG_TYPE_I32, val)); 2365 } 2366 2367 TCGv_i64 tcg_constant_i64(int64_t val) 2368 { 2369 return temp_tcgv_i64(tcg_constant_internal(TCG_TYPE_I64, val)); 2370 } 2371 2372 TCGv_vaddr tcg_constant_vaddr(uintptr_t val) 2373 { 2374 return temp_tcgv_vaddr(tcg_constant_internal(TCG_TYPE_PTR, val)); 2375 } 2376 2377 TCGv_ptr tcg_constant_ptr_int(intptr_t val) 2378 { 2379 return temp_tcgv_ptr(tcg_constant_internal(TCG_TYPE_PTR, val)); 2380 } 2381 2382 TCGv_vec tcg_constant_vec(TCGType type, unsigned vece, int64_t val) 2383 { 2384 val = dup_const(vece, val); 2385 return temp_tcgv_vec(tcg_constant_internal(type, val)); 2386 } 2387 2388 TCGv_vec tcg_constant_vec_matching(TCGv_vec match, unsigned vece, int64_t val) 2389 { 2390 TCGTemp *t = tcgv_vec_temp(match); 2391 2392 tcg_debug_assert(t->temp_allocated != 0); 2393 return tcg_constant_vec(t->base_type, vece, val); 2394 } 2395 2396 #ifdef CONFIG_DEBUG_TCG 2397 size_t temp_idx(TCGTemp *ts) 2398 { 2399 ptrdiff_t n = ts - tcg_ctx->temps; 2400 assert(n >= 0 && n < tcg_ctx->nb_temps); 2401 return n; 2402 } 2403 2404 TCGTemp *tcgv_i32_temp(TCGv_i32 v) 2405 { 2406 uintptr_t o = (uintptr_t)v - offsetof(TCGContext, temps); 2407 2408 assert(o < sizeof(TCGTemp) * tcg_ctx->nb_temps); 2409 assert(o % sizeof(TCGTemp) == 0); 2410 2411 return (void *)tcg_ctx + (uintptr_t)v; 2412 } 2413 #endif /* CONFIG_DEBUG_TCG */ 2414 2415 /* 2416 * Return true if OP may appear in the opcode stream with TYPE. 2417 * Test the runtime variable that controls each opcode. 2418 */ 2419 bool tcg_op_supported(TCGOpcode op, TCGType type, unsigned flags) 2420 { 2421 bool has_type; 2422 2423 switch (type) { 2424 case TCG_TYPE_I32: 2425 has_type = true; 2426 break; 2427 case TCG_TYPE_I64: 2428 has_type = TCG_TARGET_REG_BITS == 64; 2429 break; 2430 case TCG_TYPE_V64: 2431 has_type = TCG_TARGET_HAS_v64; 2432 break; 2433 case TCG_TYPE_V128: 2434 has_type = TCG_TARGET_HAS_v128; 2435 break; 2436 case TCG_TYPE_V256: 2437 has_type = TCG_TARGET_HAS_v256; 2438 break; 2439 default: 2440 has_type = false; 2441 break; 2442 } 2443 2444 switch (op) { 2445 case INDEX_op_discard: 2446 case INDEX_op_set_label: 2447 case INDEX_op_call: 2448 case INDEX_op_br: 2449 case INDEX_op_mb: 2450 case INDEX_op_insn_start: 2451 case INDEX_op_exit_tb: 2452 case INDEX_op_goto_tb: 2453 case INDEX_op_goto_ptr: 2454 return true; 2455 2456 case INDEX_op_qemu_ld: 2457 case INDEX_op_qemu_st: 2458 tcg_debug_assert(type <= TCG_TYPE_REG); 2459 return true; 2460 2461 case INDEX_op_qemu_ld2: 2462 case INDEX_op_qemu_st2: 2463 if (TCG_TARGET_REG_BITS == 32) { 2464 tcg_debug_assert(type == TCG_TYPE_I64); 2465 return true; 2466 } 2467 tcg_debug_assert(type == TCG_TYPE_I128); 2468 goto do_lookup; 2469 2470 case INDEX_op_add: 2471 case INDEX_op_and: 2472 case INDEX_op_brcond: 2473 case INDEX_op_deposit: 2474 case INDEX_op_extract: 2475 case INDEX_op_ld8u: 2476 case INDEX_op_ld8s: 2477 case INDEX_op_ld16u: 2478 case INDEX_op_ld16s: 2479 case INDEX_op_ld: 2480 case INDEX_op_mov: 2481 case INDEX_op_movcond: 2482 case INDEX_op_negsetcond: 2483 case INDEX_op_or: 2484 case INDEX_op_setcond: 2485 case INDEX_op_sextract: 2486 case INDEX_op_st8: 2487 case INDEX_op_st16: 2488 case INDEX_op_st: 2489 case INDEX_op_xor: 2490 return has_type; 2491 2492 case INDEX_op_brcond2_i32: 2493 case INDEX_op_setcond2_i32: 2494 return TCG_TARGET_REG_BITS == 32; 2495 2496 case INDEX_op_ld32u: 2497 case INDEX_op_ld32s: 2498 case INDEX_op_st32: 2499 case INDEX_op_ext_i32_i64: 2500 case INDEX_op_extu_i32_i64: 2501 case INDEX_op_extrl_i64_i32: 2502 case INDEX_op_extrh_i64_i32: 2503 return TCG_TARGET_REG_BITS == 64; 2504 2505 case INDEX_op_mov_vec: 2506 case INDEX_op_dup_vec: 2507 case INDEX_op_dupm_vec: 2508 case INDEX_op_ld_vec: 2509 case INDEX_op_st_vec: 2510 case INDEX_op_add_vec: 2511 case INDEX_op_sub_vec: 2512 case INDEX_op_and_vec: 2513 case INDEX_op_or_vec: 2514 case INDEX_op_xor_vec: 2515 case INDEX_op_cmp_vec: 2516 return has_type; 2517 case INDEX_op_dup2_vec: 2518 return has_type && TCG_TARGET_REG_BITS == 32; 2519 case INDEX_op_not_vec: 2520 return has_type && TCG_TARGET_HAS_not_vec; 2521 case INDEX_op_neg_vec: 2522 return has_type && TCG_TARGET_HAS_neg_vec; 2523 case INDEX_op_abs_vec: 2524 return has_type && TCG_TARGET_HAS_abs_vec; 2525 case INDEX_op_andc_vec: 2526 return has_type && TCG_TARGET_HAS_andc_vec; 2527 case INDEX_op_orc_vec: 2528 return has_type && TCG_TARGET_HAS_orc_vec; 2529 case INDEX_op_nand_vec: 2530 return has_type && TCG_TARGET_HAS_nand_vec; 2531 case INDEX_op_nor_vec: 2532 return has_type && TCG_TARGET_HAS_nor_vec; 2533 case INDEX_op_eqv_vec: 2534 return has_type && TCG_TARGET_HAS_eqv_vec; 2535 case INDEX_op_mul_vec: 2536 return has_type && TCG_TARGET_HAS_mul_vec; 2537 case INDEX_op_shli_vec: 2538 case INDEX_op_shri_vec: 2539 case INDEX_op_sari_vec: 2540 return has_type && TCG_TARGET_HAS_shi_vec; 2541 case INDEX_op_shls_vec: 2542 case INDEX_op_shrs_vec: 2543 case INDEX_op_sars_vec: 2544 return has_type && TCG_TARGET_HAS_shs_vec; 2545 case INDEX_op_shlv_vec: 2546 case INDEX_op_shrv_vec: 2547 case INDEX_op_sarv_vec: 2548 return has_type && TCG_TARGET_HAS_shv_vec; 2549 case INDEX_op_rotli_vec: 2550 return has_type && TCG_TARGET_HAS_roti_vec; 2551 case INDEX_op_rotls_vec: 2552 return has_type && TCG_TARGET_HAS_rots_vec; 2553 case INDEX_op_rotlv_vec: 2554 case INDEX_op_rotrv_vec: 2555 return has_type && TCG_TARGET_HAS_rotv_vec; 2556 case INDEX_op_ssadd_vec: 2557 case INDEX_op_usadd_vec: 2558 case INDEX_op_sssub_vec: 2559 case INDEX_op_ussub_vec: 2560 return has_type && TCG_TARGET_HAS_sat_vec; 2561 case INDEX_op_smin_vec: 2562 case INDEX_op_umin_vec: 2563 case INDEX_op_smax_vec: 2564 case INDEX_op_umax_vec: 2565 return has_type && TCG_TARGET_HAS_minmax_vec; 2566 case INDEX_op_bitsel_vec: 2567 return has_type && TCG_TARGET_HAS_bitsel_vec; 2568 case INDEX_op_cmpsel_vec: 2569 return has_type && TCG_TARGET_HAS_cmpsel_vec; 2570 2571 default: 2572 if (op < INDEX_op_last_generic) { 2573 const TCGOutOp *outop; 2574 TCGConstraintSetIndex con_set; 2575 2576 if (!has_type) { 2577 return false; 2578 } 2579 2580 do_lookup: 2581 outop = all_outop[op]; 2582 tcg_debug_assert(outop != NULL); 2583 2584 con_set = outop->static_constraint; 2585 if (con_set == C_Dynamic) { 2586 con_set = outop->dynamic_constraint(type, flags); 2587 } 2588 if (con_set >= 0) { 2589 return true; 2590 } 2591 tcg_debug_assert(con_set == C_NotImplemented); 2592 return false; 2593 } 2594 tcg_debug_assert(op < NB_OPS); 2595 return true; 2596 2597 case INDEX_op_last_generic: 2598 g_assert_not_reached(); 2599 } 2600 } 2601 2602 bool tcg_op_deposit_valid(TCGType type, unsigned ofs, unsigned len) 2603 { 2604 unsigned width; 2605 2606 tcg_debug_assert(type == TCG_TYPE_I32 || type == TCG_TYPE_I64); 2607 width = (type == TCG_TYPE_I32 ? 32 : 64); 2608 2609 tcg_debug_assert(ofs < width); 2610 tcg_debug_assert(len > 0); 2611 tcg_debug_assert(len <= width - ofs); 2612 2613 return TCG_TARGET_deposit_valid(type, ofs, len); 2614 } 2615 2616 static TCGOp *tcg_op_alloc(TCGOpcode opc, unsigned nargs); 2617 2618 static void tcg_gen_callN(void *func, TCGHelperInfo *info, 2619 TCGTemp *ret, TCGTemp **args) 2620 { 2621 TCGv_i64 extend_free[MAX_CALL_IARGS]; 2622 int n_extend = 0; 2623 TCGOp *op; 2624 int i, n, pi = 0, total_args; 2625 2626 if (unlikely(g_once_init_enter(HELPER_INFO_INIT(info)))) { 2627 init_call_layout(info); 2628 g_once_init_leave(HELPER_INFO_INIT(info), HELPER_INFO_INIT_VAL(info)); 2629 } 2630 2631 total_args = info->nr_out + info->nr_in + 2; 2632 op = tcg_op_alloc(INDEX_op_call, total_args); 2633 2634 #ifdef CONFIG_PLUGIN 2635 /* Flag helpers that may affect guest state */ 2636 if (tcg_ctx->plugin_insn && !(info->flags & TCG_CALL_NO_SIDE_EFFECTS)) { 2637 tcg_ctx->plugin_insn->calls_helpers = true; 2638 } 2639 #endif 2640 2641 TCGOP_CALLO(op) = n = info->nr_out; 2642 switch (n) { 2643 case 0: 2644 tcg_debug_assert(ret == NULL); 2645 break; 2646 case 1: 2647 tcg_debug_assert(ret != NULL); 2648 op->args[pi++] = temp_arg(ret); 2649 break; 2650 case 2: 2651 case 4: 2652 tcg_debug_assert(ret != NULL); 2653 tcg_debug_assert(ret->base_type == ret->type + ctz32(n)); 2654 tcg_debug_assert(ret->temp_subindex == 0); 2655 for (i = 0; i < n; ++i) { 2656 op->args[pi++] = temp_arg(ret + i); 2657 } 2658 break; 2659 default: 2660 g_assert_not_reached(); 2661 } 2662 2663 TCGOP_CALLI(op) = n = info->nr_in; 2664 for (i = 0; i < n; i++) { 2665 const TCGCallArgumentLoc *loc = &info->in[i]; 2666 TCGTemp *ts = args[loc->arg_idx] + loc->tmp_subindex; 2667 2668 switch (loc->kind) { 2669 case TCG_CALL_ARG_NORMAL: 2670 case TCG_CALL_ARG_BY_REF: 2671 case TCG_CALL_ARG_BY_REF_N: 2672 op->args[pi++] = temp_arg(ts); 2673 break; 2674 2675 case TCG_CALL_ARG_EXTEND_U: 2676 case TCG_CALL_ARG_EXTEND_S: 2677 { 2678 TCGv_i64 temp = tcg_temp_ebb_new_i64(); 2679 TCGv_i32 orig = temp_tcgv_i32(ts); 2680 2681 if (loc->kind == TCG_CALL_ARG_EXTEND_S) { 2682 tcg_gen_ext_i32_i64(temp, orig); 2683 } else { 2684 tcg_gen_extu_i32_i64(temp, orig); 2685 } 2686 op->args[pi++] = tcgv_i64_arg(temp); 2687 extend_free[n_extend++] = temp; 2688 } 2689 break; 2690 2691 default: 2692 g_assert_not_reached(); 2693 } 2694 } 2695 op->args[pi++] = (uintptr_t)func; 2696 op->args[pi++] = (uintptr_t)info; 2697 tcg_debug_assert(pi == total_args); 2698 2699 if (tcg_ctx->emit_before_op) { 2700 QTAILQ_INSERT_BEFORE(tcg_ctx->emit_before_op, op, link); 2701 } else { 2702 QTAILQ_INSERT_TAIL(&tcg_ctx->ops, op, link); 2703 } 2704 2705 tcg_debug_assert(n_extend < ARRAY_SIZE(extend_free)); 2706 for (i = 0; i < n_extend; ++i) { 2707 tcg_temp_free_i64(extend_free[i]); 2708 } 2709 } 2710 2711 void tcg_gen_call0(void *func, TCGHelperInfo *info, TCGTemp *ret) 2712 { 2713 tcg_gen_callN(func, info, ret, NULL); 2714 } 2715 2716 void tcg_gen_call1(void *func, TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1) 2717 { 2718 tcg_gen_callN(func, info, ret, &t1); 2719 } 2720 2721 void tcg_gen_call2(void *func, TCGHelperInfo *info, TCGTemp *ret, 2722 TCGTemp *t1, TCGTemp *t2) 2723 { 2724 TCGTemp *args[2] = { t1, t2 }; 2725 tcg_gen_callN(func, info, ret, args); 2726 } 2727 2728 void tcg_gen_call3(void *func, TCGHelperInfo *info, TCGTemp *ret, 2729 TCGTemp *t1, TCGTemp *t2, TCGTemp *t3) 2730 { 2731 TCGTemp *args[3] = { t1, t2, t3 }; 2732 tcg_gen_callN(func, info, ret, args); 2733 } 2734 2735 void tcg_gen_call4(void *func, TCGHelperInfo *info, TCGTemp *ret, 2736 TCGTemp *t1, TCGTemp *t2, TCGTemp *t3, TCGTemp *t4) 2737 { 2738 TCGTemp *args[4] = { t1, t2, t3, t4 }; 2739 tcg_gen_callN(func, info, ret, args); 2740 } 2741 2742 void tcg_gen_call5(void *func, TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1, 2743 TCGTemp *t2, TCGTemp *t3, TCGTemp *t4, TCGTemp *t5) 2744 { 2745 TCGTemp *args[5] = { t1, t2, t3, t4, t5 }; 2746 tcg_gen_callN(func, info, ret, args); 2747 } 2748 2749 void tcg_gen_call6(void *func, TCGHelperInfo *info, TCGTemp *ret, 2750 TCGTemp *t1, TCGTemp *t2, TCGTemp *t3, 2751 TCGTemp *t4, TCGTemp *t5, TCGTemp *t6) 2752 { 2753 TCGTemp *args[6] = { t1, t2, t3, t4, t5, t6 }; 2754 tcg_gen_callN(func, info, ret, args); 2755 } 2756 2757 void tcg_gen_call7(void *func, TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1, 2758 TCGTemp *t2, TCGTemp *t3, TCGTemp *t4, 2759 TCGTemp *t5, TCGTemp *t6, TCGTemp *t7) 2760 { 2761 TCGTemp *args[7] = { t1, t2, t3, t4, t5, t6, t7 }; 2762 tcg_gen_callN(func, info, ret, args); 2763 } 2764 2765 static void tcg_reg_alloc_start(TCGContext *s) 2766 { 2767 int i, n; 2768 2769 for (i = 0, n = s->nb_temps; i < n; i++) { 2770 TCGTemp *ts = &s->temps[i]; 2771 TCGTempVal val = TEMP_VAL_MEM; 2772 2773 switch (ts->kind) { 2774 case TEMP_CONST: 2775 val = TEMP_VAL_CONST; 2776 break; 2777 case TEMP_FIXED: 2778 val = TEMP_VAL_REG; 2779 break; 2780 case TEMP_GLOBAL: 2781 break; 2782 case TEMP_EBB: 2783 val = TEMP_VAL_DEAD; 2784 /* fall through */ 2785 case TEMP_TB: 2786 ts->mem_allocated = 0; 2787 break; 2788 default: 2789 g_assert_not_reached(); 2790 } 2791 ts->val_type = val; 2792 } 2793 2794 memset(s->reg_to_temp, 0, sizeof(s->reg_to_temp)); 2795 } 2796 2797 static char *tcg_get_arg_str_ptr(TCGContext *s, char *buf, int buf_size, 2798 TCGTemp *ts) 2799 { 2800 int idx = temp_idx(ts); 2801 2802 switch (ts->kind) { 2803 case TEMP_FIXED: 2804 case TEMP_GLOBAL: 2805 pstrcpy(buf, buf_size, ts->name); 2806 break; 2807 case TEMP_TB: 2808 snprintf(buf, buf_size, "loc%d", idx - s->nb_globals); 2809 break; 2810 case TEMP_EBB: 2811 snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals); 2812 break; 2813 case TEMP_CONST: 2814 switch (ts->type) { 2815 case TCG_TYPE_I32: 2816 snprintf(buf, buf_size, "$0x%x", (int32_t)ts->val); 2817 break; 2818 #if TCG_TARGET_REG_BITS > 32 2819 case TCG_TYPE_I64: 2820 snprintf(buf, buf_size, "$0x%" PRIx64, ts->val); 2821 break; 2822 #endif 2823 case TCG_TYPE_V64: 2824 case TCG_TYPE_V128: 2825 case TCG_TYPE_V256: 2826 snprintf(buf, buf_size, "v%d$0x%" PRIx64, 2827 64 << (ts->type - TCG_TYPE_V64), ts->val); 2828 break; 2829 default: 2830 g_assert_not_reached(); 2831 } 2832 break; 2833 } 2834 return buf; 2835 } 2836 2837 static char *tcg_get_arg_str(TCGContext *s, char *buf, 2838 int buf_size, TCGArg arg) 2839 { 2840 return tcg_get_arg_str_ptr(s, buf, buf_size, arg_temp(arg)); 2841 } 2842 2843 static const char * const cond_name[] = 2844 { 2845 [TCG_COND_NEVER] = "never", 2846 [TCG_COND_ALWAYS] = "always", 2847 [TCG_COND_EQ] = "eq", 2848 [TCG_COND_NE] = "ne", 2849 [TCG_COND_LT] = "lt", 2850 [TCG_COND_GE] = "ge", 2851 [TCG_COND_LE] = "le", 2852 [TCG_COND_GT] = "gt", 2853 [TCG_COND_LTU] = "ltu", 2854 [TCG_COND_GEU] = "geu", 2855 [TCG_COND_LEU] = "leu", 2856 [TCG_COND_GTU] = "gtu", 2857 [TCG_COND_TSTEQ] = "tsteq", 2858 [TCG_COND_TSTNE] = "tstne", 2859 }; 2860 2861 static const char * const ldst_name[(MO_BSWAP | MO_SSIZE) + 1] = 2862 { 2863 [MO_UB] = "ub", 2864 [MO_SB] = "sb", 2865 [MO_LEUW] = "leuw", 2866 [MO_LESW] = "lesw", 2867 [MO_LEUL] = "leul", 2868 [MO_LESL] = "lesl", 2869 [MO_LEUQ] = "leq", 2870 [MO_BEUW] = "beuw", 2871 [MO_BESW] = "besw", 2872 [MO_BEUL] = "beul", 2873 [MO_BESL] = "besl", 2874 [MO_BEUQ] = "beq", 2875 [MO_128 + MO_BE] = "beo", 2876 [MO_128 + MO_LE] = "leo", 2877 }; 2878 2879 static const char * const alignment_name[(MO_AMASK >> MO_ASHIFT) + 1] = { 2880 [MO_UNALN >> MO_ASHIFT] = "un+", 2881 [MO_ALIGN >> MO_ASHIFT] = "al+", 2882 [MO_ALIGN_2 >> MO_ASHIFT] = "al2+", 2883 [MO_ALIGN_4 >> MO_ASHIFT] = "al4+", 2884 [MO_ALIGN_8 >> MO_ASHIFT] = "al8+", 2885 [MO_ALIGN_16 >> MO_ASHIFT] = "al16+", 2886 [MO_ALIGN_32 >> MO_ASHIFT] = "al32+", 2887 [MO_ALIGN_64 >> MO_ASHIFT] = "al64+", 2888 }; 2889 2890 static const char * const atom_name[(MO_ATOM_MASK >> MO_ATOM_SHIFT) + 1] = { 2891 [MO_ATOM_IFALIGN >> MO_ATOM_SHIFT] = "", 2892 [MO_ATOM_IFALIGN_PAIR >> MO_ATOM_SHIFT] = "pair+", 2893 [MO_ATOM_WITHIN16 >> MO_ATOM_SHIFT] = "w16+", 2894 [MO_ATOM_WITHIN16_PAIR >> MO_ATOM_SHIFT] = "w16p+", 2895 [MO_ATOM_SUBALIGN >> MO_ATOM_SHIFT] = "sub+", 2896 [MO_ATOM_NONE >> MO_ATOM_SHIFT] = "noat+", 2897 }; 2898 2899 static const char bswap_flag_name[][6] = { 2900 [TCG_BSWAP_IZ] = "iz", 2901 [TCG_BSWAP_OZ] = "oz", 2902 [TCG_BSWAP_OS] = "os", 2903 [TCG_BSWAP_IZ | TCG_BSWAP_OZ] = "iz,oz", 2904 [TCG_BSWAP_IZ | TCG_BSWAP_OS] = "iz,os", 2905 }; 2906 2907 #ifdef CONFIG_PLUGIN 2908 static const char * const plugin_from_name[] = { 2909 "from-tb", 2910 "from-insn", 2911 "after-insn", 2912 "after-tb", 2913 }; 2914 #endif 2915 2916 static inline bool tcg_regset_single(TCGRegSet d) 2917 { 2918 return (d & (d - 1)) == 0; 2919 } 2920 2921 static inline TCGReg tcg_regset_first(TCGRegSet d) 2922 { 2923 if (TCG_TARGET_NB_REGS <= 32) { 2924 return ctz32(d); 2925 } else { 2926 return ctz64(d); 2927 } 2928 } 2929 2930 /* Return only the number of characters output -- no error return. */ 2931 #define ne_fprintf(...) \ 2932 ({ int ret_ = fprintf(__VA_ARGS__); ret_ >= 0 ? ret_ : 0; }) 2933 2934 void tcg_dump_ops(TCGContext *s, FILE *f, bool have_prefs) 2935 { 2936 char buf[128]; 2937 TCGOp *op; 2938 2939 QTAILQ_FOREACH(op, &s->ops, link) { 2940 int i, k, nb_oargs, nb_iargs, nb_cargs; 2941 const TCGOpDef *def; 2942 TCGOpcode c; 2943 int col = 0; 2944 2945 c = op->opc; 2946 def = &tcg_op_defs[c]; 2947 2948 if (c == INDEX_op_insn_start) { 2949 nb_oargs = 0; 2950 col += ne_fprintf(f, "\n ----"); 2951 2952 for (i = 0, k = INSN_START_WORDS; i < k; ++i) { 2953 col += ne_fprintf(f, " %016" PRIx64, 2954 tcg_get_insn_start_param(op, i)); 2955 } 2956 } else if (c == INDEX_op_call) { 2957 const TCGHelperInfo *info = tcg_call_info(op); 2958 void *func = tcg_call_func(op); 2959 2960 /* variable number of arguments */ 2961 nb_oargs = TCGOP_CALLO(op); 2962 nb_iargs = TCGOP_CALLI(op); 2963 nb_cargs = def->nb_cargs; 2964 2965 col += ne_fprintf(f, " %s ", def->name); 2966 2967 /* 2968 * Print the function name from TCGHelperInfo, if available. 2969 * Note that plugins have a template function for the info, 2970 * but the actual function pointer comes from the plugin. 2971 */ 2972 if (func == info->func) { 2973 col += ne_fprintf(f, "%s", info->name); 2974 } else { 2975 col += ne_fprintf(f, "plugin(%p)", func); 2976 } 2977 2978 col += ne_fprintf(f, ",$0x%x,$%d", info->flags, nb_oargs); 2979 for (i = 0; i < nb_oargs; i++) { 2980 col += ne_fprintf(f, ",%s", tcg_get_arg_str(s, buf, sizeof(buf), 2981 op->args[i])); 2982 } 2983 for (i = 0; i < nb_iargs; i++) { 2984 TCGArg arg = op->args[nb_oargs + i]; 2985 const char *t = tcg_get_arg_str(s, buf, sizeof(buf), arg); 2986 col += ne_fprintf(f, ",%s", t); 2987 } 2988 } else { 2989 if (def->flags & TCG_OPF_INT) { 2990 col += ne_fprintf(f, " %s_i%d ", 2991 def->name, 2992 8 * tcg_type_size(TCGOP_TYPE(op))); 2993 } else if (def->flags & TCG_OPF_VECTOR) { 2994 col += ne_fprintf(f, "%s v%d,e%d,", 2995 def->name, 2996 8 * tcg_type_size(TCGOP_TYPE(op)), 2997 8 << TCGOP_VECE(op)); 2998 } else { 2999 col += ne_fprintf(f, " %s ", def->name); 3000 } 3001 3002 nb_oargs = def->nb_oargs; 3003 nb_iargs = def->nb_iargs; 3004 nb_cargs = def->nb_cargs; 3005 3006 k = 0; 3007 for (i = 0; i < nb_oargs; i++) { 3008 const char *sep = k ? "," : ""; 3009 col += ne_fprintf(f, "%s%s", sep, 3010 tcg_get_arg_str(s, buf, sizeof(buf), 3011 op->args[k++])); 3012 } 3013 for (i = 0; i < nb_iargs; i++) { 3014 const char *sep = k ? "," : ""; 3015 col += ne_fprintf(f, "%s%s", sep, 3016 tcg_get_arg_str(s, buf, sizeof(buf), 3017 op->args[k++])); 3018 } 3019 switch (c) { 3020 case INDEX_op_brcond: 3021 case INDEX_op_setcond: 3022 case INDEX_op_negsetcond: 3023 case INDEX_op_movcond: 3024 case INDEX_op_brcond2_i32: 3025 case INDEX_op_setcond2_i32: 3026 case INDEX_op_cmp_vec: 3027 case INDEX_op_cmpsel_vec: 3028 if (op->args[k] < ARRAY_SIZE(cond_name) 3029 && cond_name[op->args[k]]) { 3030 col += ne_fprintf(f, ",%s", cond_name[op->args[k++]]); 3031 } else { 3032 col += ne_fprintf(f, ",$0x%" TCG_PRIlx, op->args[k++]); 3033 } 3034 i = 1; 3035 break; 3036 case INDEX_op_qemu_ld: 3037 case INDEX_op_qemu_st: 3038 case INDEX_op_qemu_ld2: 3039 case INDEX_op_qemu_st2: 3040 { 3041 const char *s_al, *s_op, *s_at; 3042 MemOpIdx oi = op->args[k++]; 3043 MemOp mop = get_memop(oi); 3044 unsigned ix = get_mmuidx(oi); 3045 3046 s_al = alignment_name[(mop & MO_AMASK) >> MO_ASHIFT]; 3047 s_op = ldst_name[mop & (MO_BSWAP | MO_SSIZE)]; 3048 s_at = atom_name[(mop & MO_ATOM_MASK) >> MO_ATOM_SHIFT]; 3049 mop &= ~(MO_AMASK | MO_BSWAP | MO_SSIZE | MO_ATOM_MASK); 3050 3051 /* If all fields are accounted for, print symbolically. */ 3052 if (!mop && s_al && s_op && s_at) { 3053 col += ne_fprintf(f, ",%s%s%s,%u", 3054 s_at, s_al, s_op, ix); 3055 } else { 3056 mop = get_memop(oi); 3057 col += ne_fprintf(f, ",$0x%x,%u", mop, ix); 3058 } 3059 i = 1; 3060 } 3061 break; 3062 case INDEX_op_bswap16: 3063 case INDEX_op_bswap32: 3064 case INDEX_op_bswap64: 3065 { 3066 TCGArg flags = op->args[k]; 3067 const char *name = NULL; 3068 3069 if (flags < ARRAY_SIZE(bswap_flag_name)) { 3070 name = bswap_flag_name[flags]; 3071 } 3072 if (name) { 3073 col += ne_fprintf(f, ",%s", name); 3074 } else { 3075 col += ne_fprintf(f, ",$0x%" TCG_PRIlx, flags); 3076 } 3077 i = k = 1; 3078 } 3079 break; 3080 #ifdef CONFIG_PLUGIN 3081 case INDEX_op_plugin_cb: 3082 { 3083 TCGArg from = op->args[k++]; 3084 const char *name = NULL; 3085 3086 if (from < ARRAY_SIZE(plugin_from_name)) { 3087 name = plugin_from_name[from]; 3088 } 3089 if (name) { 3090 col += ne_fprintf(f, "%s", name); 3091 } else { 3092 col += ne_fprintf(f, "$0x%" TCG_PRIlx, from); 3093 } 3094 i = 1; 3095 } 3096 break; 3097 #endif 3098 default: 3099 i = 0; 3100 break; 3101 } 3102 switch (c) { 3103 case INDEX_op_set_label: 3104 case INDEX_op_br: 3105 case INDEX_op_brcond: 3106 case INDEX_op_brcond2_i32: 3107 col += ne_fprintf(f, "%s$L%d", k ? "," : "", 3108 arg_label(op->args[k])->id); 3109 i++, k++; 3110 break; 3111 case INDEX_op_mb: 3112 { 3113 TCGBar membar = op->args[k]; 3114 const char *b_op, *m_op; 3115 3116 switch (membar & TCG_BAR_SC) { 3117 case 0: 3118 b_op = "none"; 3119 break; 3120 case TCG_BAR_LDAQ: 3121 b_op = "acq"; 3122 break; 3123 case TCG_BAR_STRL: 3124 b_op = "rel"; 3125 break; 3126 case TCG_BAR_SC: 3127 b_op = "seq"; 3128 break; 3129 default: 3130 g_assert_not_reached(); 3131 } 3132 3133 switch (membar & TCG_MO_ALL) { 3134 case 0: 3135 m_op = "none"; 3136 break; 3137 case TCG_MO_LD_LD: 3138 m_op = "rr"; 3139 break; 3140 case TCG_MO_LD_ST: 3141 m_op = "rw"; 3142 break; 3143 case TCG_MO_ST_LD: 3144 m_op = "wr"; 3145 break; 3146 case TCG_MO_ST_ST: 3147 m_op = "ww"; 3148 break; 3149 case TCG_MO_LD_LD | TCG_MO_LD_ST: 3150 m_op = "rr+rw"; 3151 break; 3152 case TCG_MO_LD_LD | TCG_MO_ST_LD: 3153 m_op = "rr+wr"; 3154 break; 3155 case TCG_MO_LD_LD | TCG_MO_ST_ST: 3156 m_op = "rr+ww"; 3157 break; 3158 case TCG_MO_LD_ST | TCG_MO_ST_LD: 3159 m_op = "rw+wr"; 3160 break; 3161 case TCG_MO_LD_ST | TCG_MO_ST_ST: 3162 m_op = "rw+ww"; 3163 break; 3164 case TCG_MO_ST_LD | TCG_MO_ST_ST: 3165 m_op = "wr+ww"; 3166 break; 3167 case TCG_MO_LD_LD | TCG_MO_LD_ST | TCG_MO_ST_LD: 3168 m_op = "rr+rw+wr"; 3169 break; 3170 case TCG_MO_LD_LD | TCG_MO_LD_ST | TCG_MO_ST_ST: 3171 m_op = "rr+rw+ww"; 3172 break; 3173 case TCG_MO_LD_LD | TCG_MO_ST_LD | TCG_MO_ST_ST: 3174 m_op = "rr+wr+ww"; 3175 break; 3176 case TCG_MO_LD_ST | TCG_MO_ST_LD | TCG_MO_ST_ST: 3177 m_op = "rw+wr+ww"; 3178 break; 3179 case TCG_MO_ALL: 3180 m_op = "all"; 3181 break; 3182 default: 3183 g_assert_not_reached(); 3184 } 3185 3186 col += ne_fprintf(f, "%s%s:%s", (k ? "," : ""), b_op, m_op); 3187 i++, k++; 3188 } 3189 break; 3190 default: 3191 break; 3192 } 3193 for (; i < nb_cargs; i++, k++) { 3194 col += ne_fprintf(f, "%s$0x%" TCG_PRIlx, k ? "," : "", 3195 op->args[k]); 3196 } 3197 } 3198 3199 if (have_prefs || op->life) { 3200 for (; col < 40; ++col) { 3201 putc(' ', f); 3202 } 3203 } 3204 3205 if (op->life) { 3206 unsigned life = op->life; 3207 3208 if (life & (SYNC_ARG * 3)) { 3209 ne_fprintf(f, " sync:"); 3210 for (i = 0; i < 2; ++i) { 3211 if (life & (SYNC_ARG << i)) { 3212 ne_fprintf(f, " %d", i); 3213 } 3214 } 3215 } 3216 life /= DEAD_ARG; 3217 if (life) { 3218 ne_fprintf(f, " dead:"); 3219 for (i = 0; life; ++i, life >>= 1) { 3220 if (life & 1) { 3221 ne_fprintf(f, " %d", i); 3222 } 3223 } 3224 } 3225 } 3226 3227 if (have_prefs) { 3228 for (i = 0; i < nb_oargs; ++i) { 3229 TCGRegSet set = output_pref(op, i); 3230 3231 if (i == 0) { 3232 ne_fprintf(f, " pref="); 3233 } else { 3234 ne_fprintf(f, ","); 3235 } 3236 if (set == 0) { 3237 ne_fprintf(f, "none"); 3238 } else if (set == MAKE_64BIT_MASK(0, TCG_TARGET_NB_REGS)) { 3239 ne_fprintf(f, "all"); 3240 #ifdef CONFIG_DEBUG_TCG 3241 } else if (tcg_regset_single(set)) { 3242 TCGReg reg = tcg_regset_first(set); 3243 ne_fprintf(f, "%s", tcg_target_reg_names[reg]); 3244 #endif 3245 } else if (TCG_TARGET_NB_REGS <= 32) { 3246 ne_fprintf(f, "0x%x", (uint32_t)set); 3247 } else { 3248 ne_fprintf(f, "0x%" PRIx64, (uint64_t)set); 3249 } 3250 } 3251 } 3252 3253 putc('\n', f); 3254 } 3255 } 3256 3257 /* we give more priority to constraints with less registers */ 3258 static int get_constraint_priority(const TCGArgConstraint *arg_ct, int k) 3259 { 3260 int n; 3261 3262 arg_ct += k; 3263 n = ctpop64(arg_ct->regs); 3264 3265 /* 3266 * Sort constraints of a single register first, which includes output 3267 * aliases (which must exactly match the input already allocated). 3268 */ 3269 if (n == 1 || arg_ct->oalias) { 3270 return INT_MAX; 3271 } 3272 3273 /* 3274 * Sort register pairs next, first then second immediately after. 3275 * Arbitrarily sort multiple pairs by the index of the first reg; 3276 * there shouldn't be many pairs. 3277 */ 3278 switch (arg_ct->pair) { 3279 case 1: 3280 case 3: 3281 return (k + 1) * 2; 3282 case 2: 3283 return (arg_ct->pair_index + 1) * 2 - 1; 3284 } 3285 3286 /* Finally, sort by decreasing register count. */ 3287 assert(n > 1); 3288 return -n; 3289 } 3290 3291 /* sort from highest priority to lowest */ 3292 static void sort_constraints(TCGArgConstraint *a, int start, int n) 3293 { 3294 int i, j; 3295 3296 for (i = 0; i < n; i++) { 3297 a[start + i].sort_index = start + i; 3298 } 3299 if (n <= 1) { 3300 return; 3301 } 3302 for (i = 0; i < n - 1; i++) { 3303 for (j = i + 1; j < n; j++) { 3304 int p1 = get_constraint_priority(a, a[start + i].sort_index); 3305 int p2 = get_constraint_priority(a, a[start + j].sort_index); 3306 if (p1 < p2) { 3307 int tmp = a[start + i].sort_index; 3308 a[start + i].sort_index = a[start + j].sort_index; 3309 a[start + j].sort_index = tmp; 3310 } 3311 } 3312 } 3313 } 3314 3315 static const TCGArgConstraint empty_cts[TCG_MAX_OP_ARGS]; 3316 static TCGArgConstraint all_cts[ARRAY_SIZE(constraint_sets)][TCG_MAX_OP_ARGS]; 3317 3318 static void process_constraint_sets(void) 3319 { 3320 for (size_t c = 0; c < ARRAY_SIZE(constraint_sets); ++c) { 3321 const TCGConstraintSet *tdefs = &constraint_sets[c]; 3322 TCGArgConstraint *args_ct = all_cts[c]; 3323 int nb_oargs = tdefs->nb_oargs; 3324 int nb_iargs = tdefs->nb_iargs; 3325 int nb_args = nb_oargs + nb_iargs; 3326 bool saw_alias_pair = false; 3327 3328 for (int i = 0; i < nb_args; i++) { 3329 const char *ct_str = tdefs->args_ct_str[i]; 3330 bool input_p = i >= nb_oargs; 3331 int o; 3332 3333 switch (*ct_str) { 3334 case '0' ... '9': 3335 o = *ct_str - '0'; 3336 tcg_debug_assert(input_p); 3337 tcg_debug_assert(o < nb_oargs); 3338 tcg_debug_assert(args_ct[o].regs != 0); 3339 tcg_debug_assert(!args_ct[o].oalias); 3340 args_ct[i] = args_ct[o]; 3341 /* The output sets oalias. */ 3342 args_ct[o].oalias = 1; 3343 args_ct[o].alias_index = i; 3344 /* The input sets ialias. */ 3345 args_ct[i].ialias = 1; 3346 args_ct[i].alias_index = o; 3347 if (args_ct[i].pair) { 3348 saw_alias_pair = true; 3349 } 3350 tcg_debug_assert(ct_str[1] == '\0'); 3351 continue; 3352 3353 case '&': 3354 tcg_debug_assert(!input_p); 3355 args_ct[i].newreg = true; 3356 ct_str++; 3357 break; 3358 3359 case 'p': /* plus */ 3360 /* Allocate to the register after the previous. */ 3361 tcg_debug_assert(i > (input_p ? nb_oargs : 0)); 3362 o = i - 1; 3363 tcg_debug_assert(!args_ct[o].pair); 3364 tcg_debug_assert(!args_ct[o].ct); 3365 args_ct[i] = (TCGArgConstraint){ 3366 .pair = 2, 3367 .pair_index = o, 3368 .regs = args_ct[o].regs << 1, 3369 .newreg = args_ct[o].newreg, 3370 }; 3371 args_ct[o].pair = 1; 3372 args_ct[o].pair_index = i; 3373 tcg_debug_assert(ct_str[1] == '\0'); 3374 continue; 3375 3376 case 'm': /* minus */ 3377 /* Allocate to the register before the previous. */ 3378 tcg_debug_assert(i > (input_p ? nb_oargs : 0)); 3379 o = i - 1; 3380 tcg_debug_assert(!args_ct[o].pair); 3381 tcg_debug_assert(!args_ct[o].ct); 3382 args_ct[i] = (TCGArgConstraint){ 3383 .pair = 1, 3384 .pair_index = o, 3385 .regs = args_ct[o].regs >> 1, 3386 .newreg = args_ct[o].newreg, 3387 }; 3388 args_ct[o].pair = 2; 3389 args_ct[o].pair_index = i; 3390 tcg_debug_assert(ct_str[1] == '\0'); 3391 continue; 3392 } 3393 3394 do { 3395 switch (*ct_str) { 3396 case 'i': 3397 args_ct[i].ct |= TCG_CT_CONST; 3398 break; 3399 #ifdef TCG_REG_ZERO 3400 case 'z': 3401 args_ct[i].ct |= TCG_CT_REG_ZERO; 3402 break; 3403 #endif 3404 3405 /* Include all of the target-specific constraints. */ 3406 3407 #undef CONST 3408 #define CONST(CASE, MASK) \ 3409 case CASE: args_ct[i].ct |= MASK; break; 3410 #define REGS(CASE, MASK) \ 3411 case CASE: args_ct[i].regs |= MASK; break; 3412 3413 #include "tcg-target-con-str.h" 3414 3415 #undef REGS 3416 #undef CONST 3417 default: 3418 case '0' ... '9': 3419 case '&': 3420 case 'p': 3421 case 'm': 3422 /* Typo in TCGConstraintSet constraint. */ 3423 g_assert_not_reached(); 3424 } 3425 } while (*++ct_str != '\0'); 3426 } 3427 3428 /* 3429 * Fix up output pairs that are aliased with inputs. 3430 * When we created the alias, we copied pair from the output. 3431 * There are three cases: 3432 * (1a) Pairs of inputs alias pairs of outputs. 3433 * (1b) One input aliases the first of a pair of outputs. 3434 * (2) One input aliases the second of a pair of outputs. 3435 * 3436 * Case 1a is handled by making sure that the pair_index'es are 3437 * properly updated so that they appear the same as a pair of inputs. 3438 * 3439 * Case 1b is handled by setting the pair_index of the input to 3440 * itself, simply so it doesn't point to an unrelated argument. 3441 * Since we don't encounter the "second" during the input allocation 3442 * phase, nothing happens with the second half of the input pair. 3443 * 3444 * Case 2 is handled by setting the second input to pair=3, the 3445 * first output to pair=3, and the pair_index'es to match. 3446 */ 3447 if (saw_alias_pair) { 3448 for (int i = nb_oargs; i < nb_args; i++) { 3449 int o, o2, i2; 3450 3451 /* 3452 * Since [0-9pm] must be alone in the constraint string, 3453 * the only way they can both be set is if the pair comes 3454 * from the output alias. 3455 */ 3456 if (!args_ct[i].ialias) { 3457 continue; 3458 } 3459 switch (args_ct[i].pair) { 3460 case 0: 3461 break; 3462 case 1: 3463 o = args_ct[i].alias_index; 3464 o2 = args_ct[o].pair_index; 3465 tcg_debug_assert(args_ct[o].pair == 1); 3466 tcg_debug_assert(args_ct[o2].pair == 2); 3467 if (args_ct[o2].oalias) { 3468 /* Case 1a */ 3469 i2 = args_ct[o2].alias_index; 3470 tcg_debug_assert(args_ct[i2].pair == 2); 3471 args_ct[i2].pair_index = i; 3472 args_ct[i].pair_index = i2; 3473 } else { 3474 /* Case 1b */ 3475 args_ct[i].pair_index = i; 3476 } 3477 break; 3478 case 2: 3479 o = args_ct[i].alias_index; 3480 o2 = args_ct[o].pair_index; 3481 tcg_debug_assert(args_ct[o].pair == 2); 3482 tcg_debug_assert(args_ct[o2].pair == 1); 3483 if (args_ct[o2].oalias) { 3484 /* Case 1a */ 3485 i2 = args_ct[o2].alias_index; 3486 tcg_debug_assert(args_ct[i2].pair == 1); 3487 args_ct[i2].pair_index = i; 3488 args_ct[i].pair_index = i2; 3489 } else { 3490 /* Case 2 */ 3491 args_ct[i].pair = 3; 3492 args_ct[o2].pair = 3; 3493 args_ct[i].pair_index = o2; 3494 args_ct[o2].pair_index = i; 3495 } 3496 break; 3497 default: 3498 g_assert_not_reached(); 3499 } 3500 } 3501 } 3502 3503 /* sort the constraints (XXX: this is just an heuristic) */ 3504 sort_constraints(args_ct, 0, nb_oargs); 3505 sort_constraints(args_ct, nb_oargs, nb_iargs); 3506 } 3507 } 3508 3509 static const TCGArgConstraint *opcode_args_ct(const TCGOp *op) 3510 { 3511 TCGOpcode opc = op->opc; 3512 TCGType type = TCGOP_TYPE(op); 3513 unsigned flags = TCGOP_FLAGS(op); 3514 const TCGOpDef *def = &tcg_op_defs[opc]; 3515 const TCGOutOp *outop = all_outop[opc]; 3516 TCGConstraintSetIndex con_set; 3517 3518 if (def->flags & TCG_OPF_NOT_PRESENT) { 3519 return empty_cts; 3520 } 3521 3522 if (outop) { 3523 con_set = outop->static_constraint; 3524 if (con_set == C_Dynamic) { 3525 con_set = outop->dynamic_constraint(type, flags); 3526 } 3527 } else { 3528 con_set = tcg_target_op_def(opc, type, flags); 3529 } 3530 tcg_debug_assert(con_set >= 0); 3531 tcg_debug_assert(con_set < ARRAY_SIZE(constraint_sets)); 3532 3533 /* The constraint arguments must match TCGOpcode arguments. */ 3534 tcg_debug_assert(constraint_sets[con_set].nb_oargs == def->nb_oargs); 3535 tcg_debug_assert(constraint_sets[con_set].nb_iargs == def->nb_iargs); 3536 3537 return all_cts[con_set]; 3538 } 3539 3540 static void remove_label_use(TCGOp *op, int idx) 3541 { 3542 TCGLabel *label = arg_label(op->args[idx]); 3543 TCGLabelUse *use; 3544 3545 QSIMPLEQ_FOREACH(use, &label->branches, next) { 3546 if (use->op == op) { 3547 QSIMPLEQ_REMOVE(&label->branches, use, TCGLabelUse, next); 3548 return; 3549 } 3550 } 3551 g_assert_not_reached(); 3552 } 3553 3554 void tcg_op_remove(TCGContext *s, TCGOp *op) 3555 { 3556 switch (op->opc) { 3557 case INDEX_op_br: 3558 remove_label_use(op, 0); 3559 break; 3560 case INDEX_op_brcond: 3561 remove_label_use(op, 3); 3562 break; 3563 case INDEX_op_brcond2_i32: 3564 remove_label_use(op, 5); 3565 break; 3566 default: 3567 break; 3568 } 3569 3570 QTAILQ_REMOVE(&s->ops, op, link); 3571 QTAILQ_INSERT_TAIL(&s->free_ops, op, link); 3572 s->nb_ops--; 3573 } 3574 3575 void tcg_remove_ops_after(TCGOp *op) 3576 { 3577 TCGContext *s = tcg_ctx; 3578 3579 while (true) { 3580 TCGOp *last = tcg_last_op(); 3581 if (last == op) { 3582 return; 3583 } 3584 tcg_op_remove(s, last); 3585 } 3586 } 3587 3588 static TCGOp *tcg_op_alloc(TCGOpcode opc, unsigned nargs) 3589 { 3590 TCGContext *s = tcg_ctx; 3591 TCGOp *op = NULL; 3592 3593 if (unlikely(!QTAILQ_EMPTY(&s->free_ops))) { 3594 QTAILQ_FOREACH(op, &s->free_ops, link) { 3595 if (nargs <= op->nargs) { 3596 QTAILQ_REMOVE(&s->free_ops, op, link); 3597 nargs = op->nargs; 3598 goto found; 3599 } 3600 } 3601 } 3602 3603 /* Most opcodes have 3 or 4 operands: reduce fragmentation. */ 3604 nargs = MAX(4, nargs); 3605 op = tcg_malloc(sizeof(TCGOp) + sizeof(TCGArg) * nargs); 3606 3607 found: 3608 memset(op, 0, offsetof(TCGOp, link)); 3609 op->opc = opc; 3610 op->nargs = nargs; 3611 3612 /* Check for bitfield overflow. */ 3613 tcg_debug_assert(op->nargs == nargs); 3614 3615 s->nb_ops++; 3616 return op; 3617 } 3618 3619 TCGOp *tcg_emit_op(TCGOpcode opc, unsigned nargs) 3620 { 3621 TCGOp *op = tcg_op_alloc(opc, nargs); 3622 3623 if (tcg_ctx->emit_before_op) { 3624 QTAILQ_INSERT_BEFORE(tcg_ctx->emit_before_op, op, link); 3625 } else { 3626 QTAILQ_INSERT_TAIL(&tcg_ctx->ops, op, link); 3627 } 3628 return op; 3629 } 3630 3631 TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *old_op, 3632 TCGOpcode opc, TCGType type, unsigned nargs) 3633 { 3634 TCGOp *new_op = tcg_op_alloc(opc, nargs); 3635 3636 TCGOP_TYPE(new_op) = type; 3637 QTAILQ_INSERT_BEFORE(old_op, new_op, link); 3638 return new_op; 3639 } 3640 3641 TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *old_op, 3642 TCGOpcode opc, TCGType type, unsigned nargs) 3643 { 3644 TCGOp *new_op = tcg_op_alloc(opc, nargs); 3645 3646 TCGOP_TYPE(new_op) = type; 3647 QTAILQ_INSERT_AFTER(&s->ops, old_op, new_op, link); 3648 return new_op; 3649 } 3650 3651 static void move_label_uses(TCGLabel *to, TCGLabel *from) 3652 { 3653 TCGLabelUse *u; 3654 3655 QSIMPLEQ_FOREACH(u, &from->branches, next) { 3656 TCGOp *op = u->op; 3657 switch (op->opc) { 3658 case INDEX_op_br: 3659 op->args[0] = label_arg(to); 3660 break; 3661 case INDEX_op_brcond: 3662 op->args[3] = label_arg(to); 3663 break; 3664 case INDEX_op_brcond2_i32: 3665 op->args[5] = label_arg(to); 3666 break; 3667 default: 3668 g_assert_not_reached(); 3669 } 3670 } 3671 3672 QSIMPLEQ_CONCAT(&to->branches, &from->branches); 3673 } 3674 3675 /* Reachable analysis : remove unreachable code. */ 3676 static void __attribute__((noinline)) 3677 reachable_code_pass(TCGContext *s) 3678 { 3679 TCGOp *op, *op_next, *op_prev; 3680 bool dead = false; 3681 3682 QTAILQ_FOREACH_SAFE(op, &s->ops, link, op_next) { 3683 bool remove = dead; 3684 TCGLabel *label; 3685 3686 switch (op->opc) { 3687 case INDEX_op_set_label: 3688 label = arg_label(op->args[0]); 3689 3690 /* 3691 * Note that the first op in the TB is always a load, 3692 * so there is always something before a label. 3693 */ 3694 op_prev = QTAILQ_PREV(op, link); 3695 3696 /* 3697 * If we find two sequential labels, move all branches to 3698 * reference the second label and remove the first label. 3699 * Do this before branch to next optimization, so that the 3700 * middle label is out of the way. 3701 */ 3702 if (op_prev->opc == INDEX_op_set_label) { 3703 move_label_uses(label, arg_label(op_prev->args[0])); 3704 tcg_op_remove(s, op_prev); 3705 op_prev = QTAILQ_PREV(op, link); 3706 } 3707 3708 /* 3709 * Optimization can fold conditional branches to unconditional. 3710 * If we find a label which is preceded by an unconditional 3711 * branch to next, remove the branch. We couldn't do this when 3712 * processing the branch because any dead code between the branch 3713 * and label had not yet been removed. 3714 */ 3715 if (op_prev->opc == INDEX_op_br && 3716 label == arg_label(op_prev->args[0])) { 3717 tcg_op_remove(s, op_prev); 3718 /* Fall through means insns become live again. */ 3719 dead = false; 3720 } 3721 3722 if (QSIMPLEQ_EMPTY(&label->branches)) { 3723 /* 3724 * While there is an occasional backward branch, virtually 3725 * all branches generated by the translators are forward. 3726 * Which means that generally we will have already removed 3727 * all references to the label that will be, and there is 3728 * little to be gained by iterating. 3729 */ 3730 remove = true; 3731 } else { 3732 /* Once we see a label, insns become live again. */ 3733 dead = false; 3734 remove = false; 3735 } 3736 break; 3737 3738 case INDEX_op_br: 3739 case INDEX_op_exit_tb: 3740 case INDEX_op_goto_ptr: 3741 /* Unconditional branches; everything following is dead. */ 3742 dead = true; 3743 break; 3744 3745 case INDEX_op_call: 3746 /* Notice noreturn helper calls, raising exceptions. */ 3747 if (tcg_call_flags(op) & TCG_CALL_NO_RETURN) { 3748 dead = true; 3749 } 3750 break; 3751 3752 case INDEX_op_insn_start: 3753 /* Never remove -- we need to keep these for unwind. */ 3754 remove = false; 3755 break; 3756 3757 default: 3758 break; 3759 } 3760 3761 if (remove) { 3762 tcg_op_remove(s, op); 3763 } 3764 } 3765 } 3766 3767 #define TS_DEAD 1 3768 #define TS_MEM 2 3769 3770 #define IS_DEAD_ARG(n) (arg_life & (DEAD_ARG << (n))) 3771 #define NEED_SYNC_ARG(n) (arg_life & (SYNC_ARG << (n))) 3772 3773 /* For liveness_pass_1, the register preferences for a given temp. */ 3774 static inline TCGRegSet *la_temp_pref(TCGTemp *ts) 3775 { 3776 return ts->state_ptr; 3777 } 3778 3779 /* For liveness_pass_1, reset the preferences for a given temp to the 3780 * maximal regset for its type. 3781 */ 3782 static inline void la_reset_pref(TCGTemp *ts) 3783 { 3784 *la_temp_pref(ts) 3785 = (ts->state == TS_DEAD ? 0 : tcg_target_available_regs[ts->type]); 3786 } 3787 3788 /* liveness analysis: end of function: all temps are dead, and globals 3789 should be in memory. */ 3790 static void la_func_end(TCGContext *s, int ng, int nt) 3791 { 3792 int i; 3793 3794 for (i = 0; i < ng; ++i) { 3795 s->temps[i].state = TS_DEAD | TS_MEM; 3796 la_reset_pref(&s->temps[i]); 3797 } 3798 for (i = ng; i < nt; ++i) { 3799 s->temps[i].state = TS_DEAD; 3800 la_reset_pref(&s->temps[i]); 3801 } 3802 } 3803 3804 /* liveness analysis: end of basic block: all temps are dead, globals 3805 and local temps should be in memory. */ 3806 static void la_bb_end(TCGContext *s, int ng, int nt) 3807 { 3808 int i; 3809 3810 for (i = 0; i < nt; ++i) { 3811 TCGTemp *ts = &s->temps[i]; 3812 int state; 3813 3814 switch (ts->kind) { 3815 case TEMP_FIXED: 3816 case TEMP_GLOBAL: 3817 case TEMP_TB: 3818 state = TS_DEAD | TS_MEM; 3819 break; 3820 case TEMP_EBB: 3821 case TEMP_CONST: 3822 state = TS_DEAD; 3823 break; 3824 default: 3825 g_assert_not_reached(); 3826 } 3827 ts->state = state; 3828 la_reset_pref(ts); 3829 } 3830 } 3831 3832 /* liveness analysis: sync globals back to memory. */ 3833 static void la_global_sync(TCGContext *s, int ng) 3834 { 3835 int i; 3836 3837 for (i = 0; i < ng; ++i) { 3838 int state = s->temps[i].state; 3839 s->temps[i].state = state | TS_MEM; 3840 if (state == TS_DEAD) { 3841 /* If the global was previously dead, reset prefs. */ 3842 la_reset_pref(&s->temps[i]); 3843 } 3844 } 3845 } 3846 3847 /* 3848 * liveness analysis: conditional branch: all temps are dead unless 3849 * explicitly live-across-conditional-branch, globals and local temps 3850 * should be synced. 3851 */ 3852 static void la_bb_sync(TCGContext *s, int ng, int nt) 3853 { 3854 la_global_sync(s, ng); 3855 3856 for (int i = ng; i < nt; ++i) { 3857 TCGTemp *ts = &s->temps[i]; 3858 int state; 3859 3860 switch (ts->kind) { 3861 case TEMP_TB: 3862 state = ts->state; 3863 ts->state = state | TS_MEM; 3864 if (state != TS_DEAD) { 3865 continue; 3866 } 3867 break; 3868 case TEMP_EBB: 3869 case TEMP_CONST: 3870 continue; 3871 default: 3872 g_assert_not_reached(); 3873 } 3874 la_reset_pref(&s->temps[i]); 3875 } 3876 } 3877 3878 /* liveness analysis: sync globals back to memory and kill. */ 3879 static void la_global_kill(TCGContext *s, int ng) 3880 { 3881 int i; 3882 3883 for (i = 0; i < ng; i++) { 3884 s->temps[i].state = TS_DEAD | TS_MEM; 3885 la_reset_pref(&s->temps[i]); 3886 } 3887 } 3888 3889 /* liveness analysis: note live globals crossing calls. */ 3890 static void la_cross_call(TCGContext *s, int nt) 3891 { 3892 TCGRegSet mask = ~tcg_target_call_clobber_regs; 3893 int i; 3894 3895 for (i = 0; i < nt; i++) { 3896 TCGTemp *ts = &s->temps[i]; 3897 if (!(ts->state & TS_DEAD)) { 3898 TCGRegSet *pset = la_temp_pref(ts); 3899 TCGRegSet set = *pset; 3900 3901 set &= mask; 3902 /* If the combination is not possible, restart. */ 3903 if (set == 0) { 3904 set = tcg_target_available_regs[ts->type] & mask; 3905 } 3906 *pset = set; 3907 } 3908 } 3909 } 3910 3911 /* 3912 * Liveness analysis: Verify the lifetime of TEMP_TB, and reduce 3913 * to TEMP_EBB, if possible. 3914 */ 3915 static void __attribute__((noinline)) 3916 liveness_pass_0(TCGContext *s) 3917 { 3918 void * const multiple_ebb = (void *)(uintptr_t)-1; 3919 int nb_temps = s->nb_temps; 3920 TCGOp *op, *ebb; 3921 3922 for (int i = s->nb_globals; i < nb_temps; ++i) { 3923 s->temps[i].state_ptr = NULL; 3924 } 3925 3926 /* 3927 * Represent each EBB by the op at which it begins. In the case of 3928 * the first EBB, this is the first op, otherwise it is a label. 3929 * Collect the uses of each TEMP_TB: NULL for unused, EBB for use 3930 * within a single EBB, else MULTIPLE_EBB. 3931 */ 3932 ebb = QTAILQ_FIRST(&s->ops); 3933 QTAILQ_FOREACH(op, &s->ops, link) { 3934 const TCGOpDef *def; 3935 int nb_oargs, nb_iargs; 3936 3937 switch (op->opc) { 3938 case INDEX_op_set_label: 3939 ebb = op; 3940 continue; 3941 case INDEX_op_discard: 3942 continue; 3943 case INDEX_op_call: 3944 nb_oargs = TCGOP_CALLO(op); 3945 nb_iargs = TCGOP_CALLI(op); 3946 break; 3947 default: 3948 def = &tcg_op_defs[op->opc]; 3949 nb_oargs = def->nb_oargs; 3950 nb_iargs = def->nb_iargs; 3951 break; 3952 } 3953 3954 for (int i = 0; i < nb_oargs + nb_iargs; ++i) { 3955 TCGTemp *ts = arg_temp(op->args[i]); 3956 3957 if (ts->kind != TEMP_TB) { 3958 continue; 3959 } 3960 if (ts->state_ptr == NULL) { 3961 ts->state_ptr = ebb; 3962 } else if (ts->state_ptr != ebb) { 3963 ts->state_ptr = multiple_ebb; 3964 } 3965 } 3966 } 3967 3968 /* 3969 * For TEMP_TB that turned out not to be used beyond one EBB, 3970 * reduce the liveness to TEMP_EBB. 3971 */ 3972 for (int i = s->nb_globals; i < nb_temps; ++i) { 3973 TCGTemp *ts = &s->temps[i]; 3974 if (ts->kind == TEMP_TB && ts->state_ptr != multiple_ebb) { 3975 ts->kind = TEMP_EBB; 3976 } 3977 } 3978 } 3979 3980 static void assert_carry_dead(TCGContext *s) 3981 { 3982 /* 3983 * Carry operations can be separated by a few insns like mov, 3984 * load or store, but they should always be "close", and 3985 * carry-out operations should always be paired with carry-in. 3986 * At various boundaries, carry must have been consumed. 3987 */ 3988 tcg_debug_assert(!s->carry_live); 3989 } 3990 3991 /* Liveness analysis : update the opc_arg_life array to tell if a 3992 given input arguments is dead. Instructions updating dead 3993 temporaries are removed. */ 3994 static void __attribute__((noinline)) 3995 liveness_pass_1(TCGContext *s) 3996 { 3997 int nb_globals = s->nb_globals; 3998 int nb_temps = s->nb_temps; 3999 TCGOp *op, *op_prev; 4000 TCGRegSet *prefs; 4001 4002 prefs = tcg_malloc(sizeof(TCGRegSet) * nb_temps); 4003 for (int i = 0; i < nb_temps; ++i) { 4004 s->temps[i].state_ptr = prefs + i; 4005 } 4006 4007 /* ??? Should be redundant with the exit_tb that ends the TB. */ 4008 la_func_end(s, nb_globals, nb_temps); 4009 4010 s->carry_live = false; 4011 QTAILQ_FOREACH_REVERSE_SAFE(op, &s->ops, link, op_prev) { 4012 int nb_iargs, nb_oargs; 4013 TCGOpcode opc_new, opc_new2; 4014 TCGLifeData arg_life = 0; 4015 TCGTemp *ts; 4016 TCGOpcode opc = op->opc; 4017 const TCGOpDef *def; 4018 const TCGArgConstraint *args_ct; 4019 4020 switch (opc) { 4021 case INDEX_op_call: 4022 assert_carry_dead(s); 4023 { 4024 const TCGHelperInfo *info = tcg_call_info(op); 4025 int call_flags = tcg_call_flags(op); 4026 4027 nb_oargs = TCGOP_CALLO(op); 4028 nb_iargs = TCGOP_CALLI(op); 4029 4030 /* pure functions can be removed if their result is unused */ 4031 if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) { 4032 for (int i = 0; i < nb_oargs; i++) { 4033 ts = arg_temp(op->args[i]); 4034 if (ts->state != TS_DEAD) { 4035 goto do_not_remove_call; 4036 } 4037 } 4038 goto do_remove; 4039 } 4040 do_not_remove_call: 4041 4042 /* Output args are dead. */ 4043 for (int i = 0; i < nb_oargs; i++) { 4044 ts = arg_temp(op->args[i]); 4045 if (ts->state & TS_DEAD) { 4046 arg_life |= DEAD_ARG << i; 4047 } 4048 if (ts->state & TS_MEM) { 4049 arg_life |= SYNC_ARG << i; 4050 } 4051 ts->state = TS_DEAD; 4052 la_reset_pref(ts); 4053 } 4054 4055 /* Not used -- it will be tcg_target_call_oarg_reg(). */ 4056 memset(op->output_pref, 0, sizeof(op->output_pref)); 4057 4058 if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS | 4059 TCG_CALL_NO_READ_GLOBALS))) { 4060 la_global_kill(s, nb_globals); 4061 } else if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) { 4062 la_global_sync(s, nb_globals); 4063 } 4064 4065 /* Record arguments that die in this helper. */ 4066 for (int i = nb_oargs; i < nb_iargs + nb_oargs; i++) { 4067 ts = arg_temp(op->args[i]); 4068 if (ts->state & TS_DEAD) { 4069 arg_life |= DEAD_ARG << i; 4070 } 4071 } 4072 4073 /* For all live registers, remove call-clobbered prefs. */ 4074 la_cross_call(s, nb_temps); 4075 4076 /* 4077 * Input arguments are live for preceding opcodes. 4078 * 4079 * For those arguments that die, and will be allocated in 4080 * registers, clear the register set for that arg, to be 4081 * filled in below. For args that will be on the stack, 4082 * reset to any available reg. Process arguments in reverse 4083 * order so that if a temp is used more than once, the stack 4084 * reset to max happens before the register reset to 0. 4085 */ 4086 for (int i = nb_iargs - 1; i >= 0; i--) { 4087 const TCGCallArgumentLoc *loc = &info->in[i]; 4088 ts = arg_temp(op->args[nb_oargs + i]); 4089 4090 if (ts->state & TS_DEAD) { 4091 switch (loc->kind) { 4092 case TCG_CALL_ARG_NORMAL: 4093 case TCG_CALL_ARG_EXTEND_U: 4094 case TCG_CALL_ARG_EXTEND_S: 4095 if (arg_slot_reg_p(loc->arg_slot)) { 4096 *la_temp_pref(ts) = 0; 4097 break; 4098 } 4099 /* fall through */ 4100 default: 4101 *la_temp_pref(ts) = 4102 tcg_target_available_regs[ts->type]; 4103 break; 4104 } 4105 ts->state &= ~TS_DEAD; 4106 } 4107 } 4108 4109 /* 4110 * For each input argument, add its input register to prefs. 4111 * If a temp is used once, this produces a single set bit; 4112 * if a temp is used multiple times, this produces a set. 4113 */ 4114 for (int i = 0; i < nb_iargs; i++) { 4115 const TCGCallArgumentLoc *loc = &info->in[i]; 4116 ts = arg_temp(op->args[nb_oargs + i]); 4117 4118 switch (loc->kind) { 4119 case TCG_CALL_ARG_NORMAL: 4120 case TCG_CALL_ARG_EXTEND_U: 4121 case TCG_CALL_ARG_EXTEND_S: 4122 if (arg_slot_reg_p(loc->arg_slot)) { 4123 tcg_regset_set_reg(*la_temp_pref(ts), 4124 tcg_target_call_iarg_regs[loc->arg_slot]); 4125 } 4126 break; 4127 default: 4128 break; 4129 } 4130 } 4131 } 4132 break; 4133 case INDEX_op_insn_start: 4134 assert_carry_dead(s); 4135 break; 4136 case INDEX_op_discard: 4137 /* mark the temporary as dead */ 4138 ts = arg_temp(op->args[0]); 4139 ts->state = TS_DEAD; 4140 la_reset_pref(ts); 4141 break; 4142 4143 case INDEX_op_muls2: 4144 opc_new = INDEX_op_mul; 4145 opc_new2 = INDEX_op_mulsh; 4146 goto do_mul2; 4147 case INDEX_op_mulu2: 4148 opc_new = INDEX_op_mul; 4149 opc_new2 = INDEX_op_muluh; 4150 do_mul2: 4151 assert_carry_dead(s); 4152 if (arg_temp(op->args[1])->state == TS_DEAD) { 4153 if (arg_temp(op->args[0])->state == TS_DEAD) { 4154 /* Both parts of the operation are dead. */ 4155 goto do_remove; 4156 } 4157 /* The high part of the operation is dead; generate the low. */ 4158 op->opc = opc = opc_new; 4159 op->args[1] = op->args[2]; 4160 op->args[2] = op->args[3]; 4161 } else if (arg_temp(op->args[0])->state == TS_DEAD && 4162 tcg_op_supported(opc_new2, TCGOP_TYPE(op), 0)) { 4163 /* The low part of the operation is dead; generate the high. */ 4164 op->opc = opc = opc_new2; 4165 op->args[0] = op->args[1]; 4166 op->args[1] = op->args[2]; 4167 op->args[2] = op->args[3]; 4168 } else { 4169 goto do_not_remove; 4170 } 4171 /* Mark the single-word operation live. */ 4172 goto do_not_remove; 4173 4174 case INDEX_op_addco: 4175 if (s->carry_live) { 4176 goto do_not_remove; 4177 } 4178 op->opc = opc = INDEX_op_add; 4179 goto do_default; 4180 4181 case INDEX_op_addcio: 4182 if (s->carry_live) { 4183 goto do_not_remove; 4184 } 4185 op->opc = opc = INDEX_op_addci; 4186 goto do_default; 4187 4188 case INDEX_op_subbo: 4189 if (s->carry_live) { 4190 goto do_not_remove; 4191 } 4192 /* Lower to sub, but this may also require canonicalization. */ 4193 op->opc = opc = INDEX_op_sub; 4194 ts = arg_temp(op->args[2]); 4195 if (ts->kind == TEMP_CONST) { 4196 ts = tcg_constant_internal(ts->type, -ts->val); 4197 if (ts->state_ptr == NULL) { 4198 tcg_debug_assert(temp_idx(ts) == nb_temps); 4199 nb_temps++; 4200 ts->state_ptr = tcg_malloc(sizeof(TCGRegSet)); 4201 ts->state = TS_DEAD; 4202 la_reset_pref(ts); 4203 } 4204 op->args[2] = temp_arg(ts); 4205 op->opc = opc = INDEX_op_add; 4206 } 4207 goto do_default; 4208 4209 case INDEX_op_subbio: 4210 if (s->carry_live) { 4211 goto do_not_remove; 4212 } 4213 op->opc = opc = INDEX_op_subbi; 4214 goto do_default; 4215 4216 case INDEX_op_addc1o: 4217 if (s->carry_live) { 4218 goto do_not_remove; 4219 } 4220 /* Lower to add, add +1. */ 4221 op_prev = tcg_op_insert_before(s, op, INDEX_op_add, 4222 TCGOP_TYPE(op), 3); 4223 op_prev->args[0] = op->args[0]; 4224 op_prev->args[1] = op->args[1]; 4225 op_prev->args[2] = op->args[2]; 4226 op->opc = opc = INDEX_op_add; 4227 op->args[1] = op->args[0]; 4228 ts = arg_temp(op->args[0]); 4229 ts = tcg_constant_internal(ts->type, 1); 4230 op->args[2] = temp_arg(ts); 4231 goto do_default; 4232 4233 case INDEX_op_subb1o: 4234 if (s->carry_live) { 4235 goto do_not_remove; 4236 } 4237 /* Lower to sub, add -1. */ 4238 op_prev = tcg_op_insert_before(s, op, INDEX_op_sub, 4239 TCGOP_TYPE(op), 3); 4240 op_prev->args[0] = op->args[0]; 4241 op_prev->args[1] = op->args[1]; 4242 op_prev->args[2] = op->args[2]; 4243 op->opc = opc = INDEX_op_add; 4244 op->args[1] = op->args[0]; 4245 ts = arg_temp(op->args[0]); 4246 ts = tcg_constant_internal(ts->type, -1); 4247 op->args[2] = temp_arg(ts); 4248 goto do_default; 4249 4250 default: 4251 do_default: 4252 /* 4253 * Test if the operation can be removed because all 4254 * its outputs are dead. We assume that nb_oargs == 0 4255 * implies side effects. 4256 */ 4257 def = &tcg_op_defs[opc]; 4258 if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && def->nb_oargs != 0) { 4259 for (int i = def->nb_oargs - 1; i >= 0; i--) { 4260 if (arg_temp(op->args[i])->state != TS_DEAD) { 4261 goto do_not_remove; 4262 } 4263 } 4264 goto do_remove; 4265 } 4266 goto do_not_remove; 4267 4268 do_remove: 4269 tcg_op_remove(s, op); 4270 break; 4271 4272 do_not_remove: 4273 def = &tcg_op_defs[opc]; 4274 nb_iargs = def->nb_iargs; 4275 nb_oargs = def->nb_oargs; 4276 4277 for (int i = 0; i < nb_oargs; i++) { 4278 ts = arg_temp(op->args[i]); 4279 4280 /* Remember the preference of the uses that followed. */ 4281 if (i < ARRAY_SIZE(op->output_pref)) { 4282 op->output_pref[i] = *la_temp_pref(ts); 4283 } 4284 4285 /* Output args are dead. */ 4286 if (ts->state & TS_DEAD) { 4287 arg_life |= DEAD_ARG << i; 4288 } 4289 if (ts->state & TS_MEM) { 4290 arg_life |= SYNC_ARG << i; 4291 } 4292 ts->state = TS_DEAD; 4293 la_reset_pref(ts); 4294 } 4295 4296 /* If end of basic block, update. */ 4297 if (def->flags & TCG_OPF_BB_EXIT) { 4298 assert_carry_dead(s); 4299 la_func_end(s, nb_globals, nb_temps); 4300 } else if (def->flags & TCG_OPF_COND_BRANCH) { 4301 assert_carry_dead(s); 4302 la_bb_sync(s, nb_globals, nb_temps); 4303 } else if (def->flags & TCG_OPF_BB_END) { 4304 assert_carry_dead(s); 4305 la_bb_end(s, nb_globals, nb_temps); 4306 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) { 4307 assert_carry_dead(s); 4308 la_global_sync(s, nb_globals); 4309 if (def->flags & TCG_OPF_CALL_CLOBBER) { 4310 la_cross_call(s, nb_temps); 4311 } 4312 } 4313 4314 /* Record arguments that die in this opcode. */ 4315 for (int i = nb_oargs; i < nb_oargs + nb_iargs; i++) { 4316 ts = arg_temp(op->args[i]); 4317 if (ts->state & TS_DEAD) { 4318 arg_life |= DEAD_ARG << i; 4319 } 4320 } 4321 if (def->flags & TCG_OPF_CARRY_OUT) { 4322 s->carry_live = false; 4323 } 4324 4325 /* Input arguments are live for preceding opcodes. */ 4326 for (int i = nb_oargs; i < nb_oargs + nb_iargs; i++) { 4327 ts = arg_temp(op->args[i]); 4328 if (ts->state & TS_DEAD) { 4329 /* For operands that were dead, initially allow 4330 all regs for the type. */ 4331 *la_temp_pref(ts) = tcg_target_available_regs[ts->type]; 4332 ts->state &= ~TS_DEAD; 4333 } 4334 } 4335 if (def->flags & TCG_OPF_CARRY_IN) { 4336 s->carry_live = true; 4337 } 4338 4339 /* Incorporate constraints for this operand. */ 4340 switch (opc) { 4341 case INDEX_op_mov: 4342 /* Note that these are TCG_OPF_NOT_PRESENT and do not 4343 have proper constraints. That said, special case 4344 moves to propagate preferences backward. */ 4345 if (IS_DEAD_ARG(1)) { 4346 *la_temp_pref(arg_temp(op->args[0])) 4347 = *la_temp_pref(arg_temp(op->args[1])); 4348 } 4349 break; 4350 4351 default: 4352 args_ct = opcode_args_ct(op); 4353 for (int i = nb_oargs; i < nb_oargs + nb_iargs; i++) { 4354 const TCGArgConstraint *ct = &args_ct[i]; 4355 TCGRegSet set, *pset; 4356 4357 ts = arg_temp(op->args[i]); 4358 pset = la_temp_pref(ts); 4359 set = *pset; 4360 4361 set &= ct->regs; 4362 if (ct->ialias) { 4363 set &= output_pref(op, ct->alias_index); 4364 } 4365 /* If the combination is not possible, restart. */ 4366 if (set == 0) { 4367 set = ct->regs; 4368 } 4369 *pset = set; 4370 } 4371 break; 4372 } 4373 break; 4374 } 4375 op->life = arg_life; 4376 } 4377 assert_carry_dead(s); 4378 } 4379 4380 /* Liveness analysis: Convert indirect regs to direct temporaries. */ 4381 static bool __attribute__((noinline)) 4382 liveness_pass_2(TCGContext *s) 4383 { 4384 int nb_globals = s->nb_globals; 4385 int nb_temps, i; 4386 bool changes = false; 4387 TCGOp *op, *op_next; 4388 4389 /* Create a temporary for each indirect global. */ 4390 for (i = 0; i < nb_globals; ++i) { 4391 TCGTemp *its = &s->temps[i]; 4392 if (its->indirect_reg) { 4393 TCGTemp *dts = tcg_temp_alloc(s); 4394 dts->type = its->type; 4395 dts->base_type = its->base_type; 4396 dts->temp_subindex = its->temp_subindex; 4397 dts->kind = TEMP_EBB; 4398 its->state_ptr = dts; 4399 } else { 4400 its->state_ptr = NULL; 4401 } 4402 /* All globals begin dead. */ 4403 its->state = TS_DEAD; 4404 } 4405 for (nb_temps = s->nb_temps; i < nb_temps; ++i) { 4406 TCGTemp *its = &s->temps[i]; 4407 its->state_ptr = NULL; 4408 its->state = TS_DEAD; 4409 } 4410 4411 QTAILQ_FOREACH_SAFE(op, &s->ops, link, op_next) { 4412 TCGOpcode opc = op->opc; 4413 const TCGOpDef *def = &tcg_op_defs[opc]; 4414 TCGLifeData arg_life = op->life; 4415 int nb_iargs, nb_oargs, call_flags; 4416 TCGTemp *arg_ts, *dir_ts; 4417 4418 if (opc == INDEX_op_call) { 4419 nb_oargs = TCGOP_CALLO(op); 4420 nb_iargs = TCGOP_CALLI(op); 4421 call_flags = tcg_call_flags(op); 4422 } else { 4423 nb_iargs = def->nb_iargs; 4424 nb_oargs = def->nb_oargs; 4425 4426 /* Set flags similar to how calls require. */ 4427 if (def->flags & TCG_OPF_COND_BRANCH) { 4428 /* Like reading globals: sync_globals */ 4429 call_flags = TCG_CALL_NO_WRITE_GLOBALS; 4430 } else if (def->flags & TCG_OPF_BB_END) { 4431 /* Like writing globals: save_globals */ 4432 call_flags = 0; 4433 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) { 4434 /* Like reading globals: sync_globals */ 4435 call_flags = TCG_CALL_NO_WRITE_GLOBALS; 4436 } else { 4437 /* No effect on globals. */ 4438 call_flags = (TCG_CALL_NO_READ_GLOBALS | 4439 TCG_CALL_NO_WRITE_GLOBALS); 4440 } 4441 } 4442 4443 /* Make sure that input arguments are available. */ 4444 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) { 4445 arg_ts = arg_temp(op->args[i]); 4446 dir_ts = arg_ts->state_ptr; 4447 if (dir_ts && arg_ts->state == TS_DEAD) { 4448 TCGOp *lop = tcg_op_insert_before(s, op, INDEX_op_ld, 4449 arg_ts->type, 3); 4450 4451 lop->args[0] = temp_arg(dir_ts); 4452 lop->args[1] = temp_arg(arg_ts->mem_base); 4453 lop->args[2] = arg_ts->mem_offset; 4454 4455 /* Loaded, but synced with memory. */ 4456 arg_ts->state = TS_MEM; 4457 } 4458 } 4459 4460 /* Perform input replacement, and mark inputs that became dead. 4461 No action is required except keeping temp_state up to date 4462 so that we reload when needed. */ 4463 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) { 4464 arg_ts = arg_temp(op->args[i]); 4465 dir_ts = arg_ts->state_ptr; 4466 if (dir_ts) { 4467 op->args[i] = temp_arg(dir_ts); 4468 changes = true; 4469 if (IS_DEAD_ARG(i)) { 4470 arg_ts->state = TS_DEAD; 4471 } 4472 } 4473 } 4474 4475 /* Liveness analysis should ensure that the following are 4476 all correct, for call sites and basic block end points. */ 4477 if (call_flags & TCG_CALL_NO_READ_GLOBALS) { 4478 /* Nothing to do */ 4479 } else if (call_flags & TCG_CALL_NO_WRITE_GLOBALS) { 4480 for (i = 0; i < nb_globals; ++i) { 4481 /* Liveness should see that globals are synced back, 4482 that is, either TS_DEAD or TS_MEM. */ 4483 arg_ts = &s->temps[i]; 4484 tcg_debug_assert(arg_ts->state_ptr == 0 4485 || arg_ts->state != 0); 4486 } 4487 } else { 4488 for (i = 0; i < nb_globals; ++i) { 4489 /* Liveness should see that globals are saved back, 4490 that is, TS_DEAD, waiting to be reloaded. */ 4491 arg_ts = &s->temps[i]; 4492 tcg_debug_assert(arg_ts->state_ptr == 0 4493 || arg_ts->state == TS_DEAD); 4494 } 4495 } 4496 4497 /* Outputs become available. */ 4498 if (opc == INDEX_op_mov) { 4499 arg_ts = arg_temp(op->args[0]); 4500 dir_ts = arg_ts->state_ptr; 4501 if (dir_ts) { 4502 op->args[0] = temp_arg(dir_ts); 4503 changes = true; 4504 4505 /* The output is now live and modified. */ 4506 arg_ts->state = 0; 4507 4508 if (NEED_SYNC_ARG(0)) { 4509 TCGOp *sop = tcg_op_insert_after(s, op, INDEX_op_st, 4510 arg_ts->type, 3); 4511 TCGTemp *out_ts = dir_ts; 4512 4513 if (IS_DEAD_ARG(0)) { 4514 out_ts = arg_temp(op->args[1]); 4515 arg_ts->state = TS_DEAD; 4516 tcg_op_remove(s, op); 4517 } else { 4518 arg_ts->state = TS_MEM; 4519 } 4520 4521 sop->args[0] = temp_arg(out_ts); 4522 sop->args[1] = temp_arg(arg_ts->mem_base); 4523 sop->args[2] = arg_ts->mem_offset; 4524 } else { 4525 tcg_debug_assert(!IS_DEAD_ARG(0)); 4526 } 4527 } 4528 } else { 4529 for (i = 0; i < nb_oargs; i++) { 4530 arg_ts = arg_temp(op->args[i]); 4531 dir_ts = arg_ts->state_ptr; 4532 if (!dir_ts) { 4533 continue; 4534 } 4535 op->args[i] = temp_arg(dir_ts); 4536 changes = true; 4537 4538 /* The output is now live and modified. */ 4539 arg_ts->state = 0; 4540 4541 /* Sync outputs upon their last write. */ 4542 if (NEED_SYNC_ARG(i)) { 4543 TCGOp *sop = tcg_op_insert_after(s, op, INDEX_op_st, 4544 arg_ts->type, 3); 4545 4546 sop->args[0] = temp_arg(dir_ts); 4547 sop->args[1] = temp_arg(arg_ts->mem_base); 4548 sop->args[2] = arg_ts->mem_offset; 4549 4550 arg_ts->state = TS_MEM; 4551 } 4552 /* Drop outputs that are dead. */ 4553 if (IS_DEAD_ARG(i)) { 4554 arg_ts->state = TS_DEAD; 4555 } 4556 } 4557 } 4558 } 4559 4560 return changes; 4561 } 4562 4563 static void temp_allocate_frame(TCGContext *s, TCGTemp *ts) 4564 { 4565 intptr_t off; 4566 int size, align; 4567 4568 /* When allocating an object, look at the full type. */ 4569 size = tcg_type_size(ts->base_type); 4570 switch (ts->base_type) { 4571 case TCG_TYPE_I32: 4572 align = 4; 4573 break; 4574 case TCG_TYPE_I64: 4575 case TCG_TYPE_V64: 4576 align = 8; 4577 break; 4578 case TCG_TYPE_I128: 4579 case TCG_TYPE_V128: 4580 case TCG_TYPE_V256: 4581 /* 4582 * Note that we do not require aligned storage for V256, 4583 * and that we provide alignment for I128 to match V128, 4584 * even if that's above what the host ABI requires. 4585 */ 4586 align = 16; 4587 break; 4588 default: 4589 g_assert_not_reached(); 4590 } 4591 4592 /* 4593 * Assume the stack is sufficiently aligned. 4594 * This affects e.g. ARM NEON, where we have 8 byte stack alignment 4595 * and do not require 16 byte vector alignment. This seems slightly 4596 * easier than fully parameterizing the above switch statement. 4597 */ 4598 align = MIN(TCG_TARGET_STACK_ALIGN, align); 4599 off = ROUND_UP(s->current_frame_offset, align); 4600 4601 /* If we've exhausted the stack frame, restart with a smaller TB. */ 4602 if (off + size > s->frame_end) { 4603 tcg_raise_tb_overflow(s); 4604 } 4605 s->current_frame_offset = off + size; 4606 #if defined(__sparc__) 4607 off += TCG_TARGET_STACK_BIAS; 4608 #endif 4609 4610 /* If the object was subdivided, assign memory to all the parts. */ 4611 if (ts->base_type != ts->type) { 4612 int part_size = tcg_type_size(ts->type); 4613 int part_count = size / part_size; 4614 4615 /* 4616 * Each part is allocated sequentially in tcg_temp_new_internal. 4617 * Jump back to the first part by subtracting the current index. 4618 */ 4619 ts -= ts->temp_subindex; 4620 for (int i = 0; i < part_count; ++i) { 4621 ts[i].mem_offset = off + i * part_size; 4622 ts[i].mem_base = s->frame_temp; 4623 ts[i].mem_allocated = 1; 4624 } 4625 } else { 4626 ts->mem_offset = off; 4627 ts->mem_base = s->frame_temp; 4628 ts->mem_allocated = 1; 4629 } 4630 } 4631 4632 /* Assign @reg to @ts, and update reg_to_temp[]. */ 4633 static void set_temp_val_reg(TCGContext *s, TCGTemp *ts, TCGReg reg) 4634 { 4635 if (ts->val_type == TEMP_VAL_REG) { 4636 TCGReg old = ts->reg; 4637 tcg_debug_assert(s->reg_to_temp[old] == ts); 4638 if (old == reg) { 4639 return; 4640 } 4641 s->reg_to_temp[old] = NULL; 4642 } 4643 tcg_debug_assert(s->reg_to_temp[reg] == NULL); 4644 s->reg_to_temp[reg] = ts; 4645 ts->val_type = TEMP_VAL_REG; 4646 ts->reg = reg; 4647 } 4648 4649 /* Assign a non-register value type to @ts, and update reg_to_temp[]. */ 4650 static void set_temp_val_nonreg(TCGContext *s, TCGTemp *ts, TCGTempVal type) 4651 { 4652 tcg_debug_assert(type != TEMP_VAL_REG); 4653 if (ts->val_type == TEMP_VAL_REG) { 4654 TCGReg reg = ts->reg; 4655 tcg_debug_assert(s->reg_to_temp[reg] == ts); 4656 s->reg_to_temp[reg] = NULL; 4657 } 4658 ts->val_type = type; 4659 } 4660 4661 static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet, TCGRegSet); 4662 4663 /* Mark a temporary as free or dead. If 'free_or_dead' is negative, 4664 mark it free; otherwise mark it dead. */ 4665 static void temp_free_or_dead(TCGContext *s, TCGTemp *ts, int free_or_dead) 4666 { 4667 TCGTempVal new_type; 4668 4669 switch (ts->kind) { 4670 case TEMP_FIXED: 4671 return; 4672 case TEMP_GLOBAL: 4673 case TEMP_TB: 4674 new_type = TEMP_VAL_MEM; 4675 break; 4676 case TEMP_EBB: 4677 new_type = free_or_dead < 0 ? TEMP_VAL_MEM : TEMP_VAL_DEAD; 4678 break; 4679 case TEMP_CONST: 4680 new_type = TEMP_VAL_CONST; 4681 break; 4682 default: 4683 g_assert_not_reached(); 4684 } 4685 set_temp_val_nonreg(s, ts, new_type); 4686 } 4687 4688 /* Mark a temporary as dead. */ 4689 static inline void temp_dead(TCGContext *s, TCGTemp *ts) 4690 { 4691 temp_free_or_dead(s, ts, 1); 4692 } 4693 4694 /* Sync a temporary to memory. 'allocated_regs' is used in case a temporary 4695 registers needs to be allocated to store a constant. If 'free_or_dead' 4696 is non-zero, subsequently release the temporary; if it is positive, the 4697 temp is dead; if it is negative, the temp is free. */ 4698 static void temp_sync(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs, 4699 TCGRegSet preferred_regs, int free_or_dead) 4700 { 4701 if (!temp_readonly(ts) && !ts->mem_coherent) { 4702 if (!ts->mem_allocated) { 4703 temp_allocate_frame(s, ts); 4704 } 4705 switch (ts->val_type) { 4706 case TEMP_VAL_CONST: 4707 /* If we're going to free the temp immediately, then we won't 4708 require it later in a register, so attempt to store the 4709 constant to memory directly. */ 4710 if (free_or_dead 4711 && tcg_out_sti(s, ts->type, ts->val, 4712 ts->mem_base->reg, ts->mem_offset)) { 4713 break; 4714 } 4715 temp_load(s, ts, tcg_target_available_regs[ts->type], 4716 allocated_regs, preferred_regs); 4717 /* fallthrough */ 4718 4719 case TEMP_VAL_REG: 4720 tcg_out_st(s, ts->type, ts->reg, 4721 ts->mem_base->reg, ts->mem_offset); 4722 break; 4723 4724 case TEMP_VAL_MEM: 4725 break; 4726 4727 case TEMP_VAL_DEAD: 4728 default: 4729 g_assert_not_reached(); 4730 } 4731 ts->mem_coherent = 1; 4732 } 4733 if (free_or_dead) { 4734 temp_free_or_dead(s, ts, free_or_dead); 4735 } 4736 } 4737 4738 /* free register 'reg' by spilling the corresponding temporary if necessary */ 4739 static void tcg_reg_free(TCGContext *s, TCGReg reg, TCGRegSet allocated_regs) 4740 { 4741 TCGTemp *ts = s->reg_to_temp[reg]; 4742 if (ts != NULL) { 4743 temp_sync(s, ts, allocated_regs, 0, -1); 4744 } 4745 } 4746 4747 /** 4748 * tcg_reg_alloc: 4749 * @required_regs: Set of registers in which we must allocate. 4750 * @allocated_regs: Set of registers which must be avoided. 4751 * @preferred_regs: Set of registers we should prefer. 4752 * @rev: True if we search the registers in "indirect" order. 4753 * 4754 * The allocated register must be in @required_regs & ~@allocated_regs, 4755 * but if we can put it in @preferred_regs we may save a move later. 4756 */ 4757 static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet required_regs, 4758 TCGRegSet allocated_regs, 4759 TCGRegSet preferred_regs, bool rev) 4760 { 4761 int i, j, f, n = ARRAY_SIZE(tcg_target_reg_alloc_order); 4762 TCGRegSet reg_ct[2]; 4763 const int *order; 4764 4765 reg_ct[1] = required_regs & ~allocated_regs; 4766 tcg_debug_assert(reg_ct[1] != 0); 4767 reg_ct[0] = reg_ct[1] & preferred_regs; 4768 4769 /* Skip the preferred_regs option if it cannot be satisfied, 4770 or if the preference made no difference. */ 4771 f = reg_ct[0] == 0 || reg_ct[0] == reg_ct[1]; 4772 4773 order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order; 4774 4775 /* Try free registers, preferences first. */ 4776 for (j = f; j < 2; j++) { 4777 TCGRegSet set = reg_ct[j]; 4778 4779 if (tcg_regset_single(set)) { 4780 /* One register in the set. */ 4781 TCGReg reg = tcg_regset_first(set); 4782 if (s->reg_to_temp[reg] == NULL) { 4783 return reg; 4784 } 4785 } else { 4786 for (i = 0; i < n; i++) { 4787 TCGReg reg = order[i]; 4788 if (s->reg_to_temp[reg] == NULL && 4789 tcg_regset_test_reg(set, reg)) { 4790 return reg; 4791 } 4792 } 4793 } 4794 } 4795 4796 /* We must spill something. */ 4797 for (j = f; j < 2; j++) { 4798 TCGRegSet set = reg_ct[j]; 4799 4800 if (tcg_regset_single(set)) { 4801 /* One register in the set. */ 4802 TCGReg reg = tcg_regset_first(set); 4803 tcg_reg_free(s, reg, allocated_regs); 4804 return reg; 4805 } else { 4806 for (i = 0; i < n; i++) { 4807 TCGReg reg = order[i]; 4808 if (tcg_regset_test_reg(set, reg)) { 4809 tcg_reg_free(s, reg, allocated_regs); 4810 return reg; 4811 } 4812 } 4813 } 4814 } 4815 4816 g_assert_not_reached(); 4817 } 4818 4819 static TCGReg tcg_reg_alloc_pair(TCGContext *s, TCGRegSet required_regs, 4820 TCGRegSet allocated_regs, 4821 TCGRegSet preferred_regs, bool rev) 4822 { 4823 int i, j, k, fmin, n = ARRAY_SIZE(tcg_target_reg_alloc_order); 4824 TCGRegSet reg_ct[2]; 4825 const int *order; 4826 4827 /* Ensure that if I is not in allocated_regs, I+1 is not either. */ 4828 reg_ct[1] = required_regs & ~(allocated_regs | (allocated_regs >> 1)); 4829 tcg_debug_assert(reg_ct[1] != 0); 4830 reg_ct[0] = reg_ct[1] & preferred_regs; 4831 4832 order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order; 4833 4834 /* 4835 * Skip the preferred_regs option if it cannot be satisfied, 4836 * or if the preference made no difference. 4837 */ 4838 k = reg_ct[0] == 0 || reg_ct[0] == reg_ct[1]; 4839 4840 /* 4841 * Minimize the number of flushes by looking for 2 free registers first, 4842 * then a single flush, then two flushes. 4843 */ 4844 for (fmin = 2; fmin >= 0; fmin--) { 4845 for (j = k; j < 2; j++) { 4846 TCGRegSet set = reg_ct[j]; 4847 4848 for (i = 0; i < n; i++) { 4849 TCGReg reg = order[i]; 4850 4851 if (tcg_regset_test_reg(set, reg)) { 4852 int f = !s->reg_to_temp[reg] + !s->reg_to_temp[reg + 1]; 4853 if (f >= fmin) { 4854 tcg_reg_free(s, reg, allocated_regs); 4855 tcg_reg_free(s, reg + 1, allocated_regs); 4856 return reg; 4857 } 4858 } 4859 } 4860 } 4861 } 4862 g_assert_not_reached(); 4863 } 4864 4865 /* Make sure the temporary is in a register. If needed, allocate the register 4866 from DESIRED while avoiding ALLOCATED. */ 4867 static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs, 4868 TCGRegSet allocated_regs, TCGRegSet preferred_regs) 4869 { 4870 TCGReg reg; 4871 4872 switch (ts->val_type) { 4873 case TEMP_VAL_REG: 4874 return; 4875 case TEMP_VAL_CONST: 4876 reg = tcg_reg_alloc(s, desired_regs, allocated_regs, 4877 preferred_regs, ts->indirect_base); 4878 if (ts->type <= TCG_TYPE_I64) { 4879 tcg_out_movi(s, ts->type, reg, ts->val); 4880 } else { 4881 uint64_t val = ts->val; 4882 MemOp vece = MO_64; 4883 4884 /* 4885 * Find the minimal vector element that matches the constant. 4886 * The targets will, in general, have to do this search anyway, 4887 * do this generically. 4888 */ 4889 if (val == dup_const(MO_8, val)) { 4890 vece = MO_8; 4891 } else if (val == dup_const(MO_16, val)) { 4892 vece = MO_16; 4893 } else if (val == dup_const(MO_32, val)) { 4894 vece = MO_32; 4895 } 4896 4897 tcg_out_dupi_vec(s, ts->type, vece, reg, ts->val); 4898 } 4899 ts->mem_coherent = 0; 4900 break; 4901 case TEMP_VAL_MEM: 4902 if (!ts->mem_allocated) { 4903 temp_allocate_frame(s, ts); 4904 } 4905 reg = tcg_reg_alloc(s, desired_regs, allocated_regs, 4906 preferred_regs, ts->indirect_base); 4907 tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset); 4908 ts->mem_coherent = 1; 4909 break; 4910 case TEMP_VAL_DEAD: 4911 default: 4912 g_assert_not_reached(); 4913 } 4914 set_temp_val_reg(s, ts, reg); 4915 } 4916 4917 /* Save a temporary to memory. 'allocated_regs' is used in case a 4918 temporary registers needs to be allocated to store a constant. */ 4919 static void temp_save(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs) 4920 { 4921 /* The liveness analysis already ensures that globals are back 4922 in memory. Keep an tcg_debug_assert for safety. */ 4923 tcg_debug_assert(ts->val_type == TEMP_VAL_MEM || temp_readonly(ts)); 4924 } 4925 4926 /* save globals to their canonical location and assume they can be 4927 modified be the following code. 'allocated_regs' is used in case a 4928 temporary registers needs to be allocated to store a constant. */ 4929 static void save_globals(TCGContext *s, TCGRegSet allocated_regs) 4930 { 4931 int i, n; 4932 4933 for (i = 0, n = s->nb_globals; i < n; i++) { 4934 temp_save(s, &s->temps[i], allocated_regs); 4935 } 4936 } 4937 4938 /* sync globals to their canonical location and assume they can be 4939 read by the following code. 'allocated_regs' is used in case a 4940 temporary registers needs to be allocated to store a constant. */ 4941 static void sync_globals(TCGContext *s, TCGRegSet allocated_regs) 4942 { 4943 int i, n; 4944 4945 for (i = 0, n = s->nb_globals; i < n; i++) { 4946 TCGTemp *ts = &s->temps[i]; 4947 tcg_debug_assert(ts->val_type != TEMP_VAL_REG 4948 || ts->kind == TEMP_FIXED 4949 || ts->mem_coherent); 4950 } 4951 } 4952 4953 /* at the end of a basic block, we assume all temporaries are dead and 4954 all globals are stored at their canonical location. */ 4955 static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs) 4956 { 4957 assert_carry_dead(s); 4958 for (int i = s->nb_globals; i < s->nb_temps; i++) { 4959 TCGTemp *ts = &s->temps[i]; 4960 4961 switch (ts->kind) { 4962 case TEMP_TB: 4963 temp_save(s, ts, allocated_regs); 4964 break; 4965 case TEMP_EBB: 4966 /* The liveness analysis already ensures that temps are dead. 4967 Keep an tcg_debug_assert for safety. */ 4968 tcg_debug_assert(ts->val_type == TEMP_VAL_DEAD); 4969 break; 4970 case TEMP_CONST: 4971 /* Similarly, we should have freed any allocated register. */ 4972 tcg_debug_assert(ts->val_type == TEMP_VAL_CONST); 4973 break; 4974 default: 4975 g_assert_not_reached(); 4976 } 4977 } 4978 4979 save_globals(s, allocated_regs); 4980 } 4981 4982 /* 4983 * At a conditional branch, we assume all temporaries are dead unless 4984 * explicitly live-across-conditional-branch; all globals and local 4985 * temps are synced to their location. 4986 */ 4987 static void tcg_reg_alloc_cbranch(TCGContext *s, TCGRegSet allocated_regs) 4988 { 4989 assert_carry_dead(s); 4990 sync_globals(s, allocated_regs); 4991 4992 for (int i = s->nb_globals; i < s->nb_temps; i++) { 4993 TCGTemp *ts = &s->temps[i]; 4994 /* 4995 * The liveness analysis already ensures that temps are dead. 4996 * Keep tcg_debug_asserts for safety. 4997 */ 4998 switch (ts->kind) { 4999 case TEMP_TB: 5000 tcg_debug_assert(ts->val_type != TEMP_VAL_REG || ts->mem_coherent); 5001 break; 5002 case TEMP_EBB: 5003 case TEMP_CONST: 5004 break; 5005 default: 5006 g_assert_not_reached(); 5007 } 5008 } 5009 } 5010 5011 /* 5012 * Specialized code generation for INDEX_op_mov_* with a constant. 5013 */ 5014 static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp *ots, 5015 tcg_target_ulong val, TCGLifeData arg_life, 5016 TCGRegSet preferred_regs) 5017 { 5018 /* ENV should not be modified. */ 5019 tcg_debug_assert(!temp_readonly(ots)); 5020 5021 /* The movi is not explicitly generated here. */ 5022 set_temp_val_nonreg(s, ots, TEMP_VAL_CONST); 5023 ots->val = val; 5024 ots->mem_coherent = 0; 5025 if (NEED_SYNC_ARG(0)) { 5026 temp_sync(s, ots, s->reserved_regs, preferred_regs, IS_DEAD_ARG(0)); 5027 } else if (IS_DEAD_ARG(0)) { 5028 temp_dead(s, ots); 5029 } 5030 } 5031 5032 /* 5033 * Specialized code generation for INDEX_op_mov_*. 5034 */ 5035 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op) 5036 { 5037 const TCGLifeData arg_life = op->life; 5038 TCGRegSet allocated_regs, preferred_regs; 5039 TCGTemp *ts, *ots; 5040 TCGType otype, itype; 5041 TCGReg oreg, ireg; 5042 5043 allocated_regs = s->reserved_regs; 5044 preferred_regs = output_pref(op, 0); 5045 ots = arg_temp(op->args[0]); 5046 ts = arg_temp(op->args[1]); 5047 5048 /* ENV should not be modified. */ 5049 tcg_debug_assert(!temp_readonly(ots)); 5050 5051 /* Note that otype != itype for no-op truncation. */ 5052 otype = ots->type; 5053 itype = ts->type; 5054 5055 if (ts->val_type == TEMP_VAL_CONST) { 5056 /* propagate constant or generate sti */ 5057 tcg_target_ulong val = ts->val; 5058 if (IS_DEAD_ARG(1)) { 5059 temp_dead(s, ts); 5060 } 5061 tcg_reg_alloc_do_movi(s, ots, val, arg_life, preferred_regs); 5062 return; 5063 } 5064 5065 /* If the source value is in memory we're going to be forced 5066 to have it in a register in order to perform the copy. Copy 5067 the SOURCE value into its own register first, that way we 5068 don't have to reload SOURCE the next time it is used. */ 5069 if (ts->val_type == TEMP_VAL_MEM) { 5070 temp_load(s, ts, tcg_target_available_regs[itype], 5071 allocated_regs, preferred_regs); 5072 } 5073 tcg_debug_assert(ts->val_type == TEMP_VAL_REG); 5074 ireg = ts->reg; 5075 5076 if (IS_DEAD_ARG(0)) { 5077 /* mov to a non-saved dead register makes no sense (even with 5078 liveness analysis disabled). */ 5079 tcg_debug_assert(NEED_SYNC_ARG(0)); 5080 if (!ots->mem_allocated) { 5081 temp_allocate_frame(s, ots); 5082 } 5083 tcg_out_st(s, otype, ireg, ots->mem_base->reg, ots->mem_offset); 5084 if (IS_DEAD_ARG(1)) { 5085 temp_dead(s, ts); 5086 } 5087 temp_dead(s, ots); 5088 return; 5089 } 5090 5091 if (IS_DEAD_ARG(1) && ts->kind != TEMP_FIXED) { 5092 /* 5093 * The mov can be suppressed. Kill input first, so that it 5094 * is unlinked from reg_to_temp, then set the output to the 5095 * reg that we saved from the input. 5096 */ 5097 temp_dead(s, ts); 5098 oreg = ireg; 5099 } else { 5100 if (ots->val_type == TEMP_VAL_REG) { 5101 oreg = ots->reg; 5102 } else { 5103 /* Make sure to not spill the input register during allocation. */ 5104 oreg = tcg_reg_alloc(s, tcg_target_available_regs[otype], 5105 allocated_regs | ((TCGRegSet)1 << ireg), 5106 preferred_regs, ots->indirect_base); 5107 } 5108 if (!tcg_out_mov(s, otype, oreg, ireg)) { 5109 /* 5110 * Cross register class move not supported. 5111 * Store the source register into the destination slot 5112 * and leave the destination temp as TEMP_VAL_MEM. 5113 */ 5114 assert(!temp_readonly(ots)); 5115 if (!ts->mem_allocated) { 5116 temp_allocate_frame(s, ots); 5117 } 5118 tcg_out_st(s, ts->type, ireg, ots->mem_base->reg, ots->mem_offset); 5119 set_temp_val_nonreg(s, ts, TEMP_VAL_MEM); 5120 ots->mem_coherent = 1; 5121 return; 5122 } 5123 } 5124 set_temp_val_reg(s, ots, oreg); 5125 ots->mem_coherent = 0; 5126 5127 if (NEED_SYNC_ARG(0)) { 5128 temp_sync(s, ots, allocated_regs, 0, 0); 5129 } 5130 } 5131 5132 /* 5133 * Specialized code generation for INDEX_op_dup_vec. 5134 */ 5135 static void tcg_reg_alloc_dup(TCGContext *s, const TCGOp *op) 5136 { 5137 const TCGLifeData arg_life = op->life; 5138 TCGRegSet dup_out_regs, dup_in_regs; 5139 const TCGArgConstraint *dup_args_ct; 5140 TCGTemp *its, *ots; 5141 TCGType itype, vtype; 5142 unsigned vece; 5143 int lowpart_ofs; 5144 bool ok; 5145 5146 ots = arg_temp(op->args[0]); 5147 its = arg_temp(op->args[1]); 5148 5149 /* ENV should not be modified. */ 5150 tcg_debug_assert(!temp_readonly(ots)); 5151 5152 itype = its->type; 5153 vece = TCGOP_VECE(op); 5154 vtype = TCGOP_TYPE(op); 5155 5156 if (its->val_type == TEMP_VAL_CONST) { 5157 /* Propagate constant via movi -> dupi. */ 5158 tcg_target_ulong val = dup_const(vece, its->val); 5159 if (IS_DEAD_ARG(1)) { 5160 temp_dead(s, its); 5161 } 5162 tcg_reg_alloc_do_movi(s, ots, val, arg_life, output_pref(op, 0)); 5163 return; 5164 } 5165 5166 dup_args_ct = opcode_args_ct(op); 5167 dup_out_regs = dup_args_ct[0].regs; 5168 dup_in_regs = dup_args_ct[1].regs; 5169 5170 /* Allocate the output register now. */ 5171 if (ots->val_type != TEMP_VAL_REG) { 5172 TCGRegSet allocated_regs = s->reserved_regs; 5173 TCGReg oreg; 5174 5175 if (!IS_DEAD_ARG(1) && its->val_type == TEMP_VAL_REG) { 5176 /* Make sure to not spill the input register. */ 5177 tcg_regset_set_reg(allocated_regs, its->reg); 5178 } 5179 oreg = tcg_reg_alloc(s, dup_out_regs, allocated_regs, 5180 output_pref(op, 0), ots->indirect_base); 5181 set_temp_val_reg(s, ots, oreg); 5182 } 5183 5184 switch (its->val_type) { 5185 case TEMP_VAL_REG: 5186 /* 5187 * The dup constriaints must be broad, covering all possible VECE. 5188 * However, tcg_op_dup_vec() gets to see the VECE and we allow it 5189 * to fail, indicating that extra moves are required for that case. 5190 */ 5191 if (tcg_regset_test_reg(dup_in_regs, its->reg)) { 5192 if (tcg_out_dup_vec(s, vtype, vece, ots->reg, its->reg)) { 5193 goto done; 5194 } 5195 /* Try again from memory or a vector input register. */ 5196 } 5197 if (!its->mem_coherent) { 5198 /* 5199 * The input register is not synced, and so an extra store 5200 * would be required to use memory. Attempt an integer-vector 5201 * register move first. We do not have a TCGRegSet for this. 5202 */ 5203 if (tcg_out_mov(s, itype, ots->reg, its->reg)) { 5204 break; 5205 } 5206 /* Sync the temp back to its slot and load from there. */ 5207 temp_sync(s, its, s->reserved_regs, 0, 0); 5208 } 5209 /* fall through */ 5210 5211 case TEMP_VAL_MEM: 5212 lowpart_ofs = 0; 5213 if (HOST_BIG_ENDIAN) { 5214 lowpart_ofs = tcg_type_size(itype) - (1 << vece); 5215 } 5216 if (tcg_out_dupm_vec(s, vtype, vece, ots->reg, its->mem_base->reg, 5217 its->mem_offset + lowpart_ofs)) { 5218 goto done; 5219 } 5220 /* Load the input into the destination vector register. */ 5221 tcg_out_ld(s, itype, ots->reg, its->mem_base->reg, its->mem_offset); 5222 break; 5223 5224 default: 5225 g_assert_not_reached(); 5226 } 5227 5228 /* We now have a vector input register, so dup must succeed. */ 5229 ok = tcg_out_dup_vec(s, vtype, vece, ots->reg, ots->reg); 5230 tcg_debug_assert(ok); 5231 5232 done: 5233 ots->mem_coherent = 0; 5234 if (IS_DEAD_ARG(1)) { 5235 temp_dead(s, its); 5236 } 5237 if (NEED_SYNC_ARG(0)) { 5238 temp_sync(s, ots, s->reserved_regs, 0, 0); 5239 } 5240 if (IS_DEAD_ARG(0)) { 5241 temp_dead(s, ots); 5242 } 5243 } 5244 5245 static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op) 5246 { 5247 const TCGLifeData arg_life = op->life; 5248 const TCGOpDef * const def = &tcg_op_defs[op->opc]; 5249 TCGRegSet i_allocated_regs; 5250 TCGRegSet o_allocated_regs; 5251 int i, k, nb_iargs, nb_oargs; 5252 TCGReg reg; 5253 TCGArg arg; 5254 const TCGArgConstraint *args_ct; 5255 const TCGArgConstraint *arg_ct; 5256 TCGTemp *ts; 5257 TCGArg new_args[TCG_MAX_OP_ARGS]; 5258 int const_args[TCG_MAX_OP_ARGS]; 5259 TCGCond op_cond; 5260 5261 if (def->flags & TCG_OPF_CARRY_IN) { 5262 tcg_debug_assert(s->carry_live); 5263 } 5264 5265 nb_oargs = def->nb_oargs; 5266 nb_iargs = def->nb_iargs; 5267 5268 /* copy constants */ 5269 memcpy(new_args + nb_oargs + nb_iargs, 5270 op->args + nb_oargs + nb_iargs, 5271 sizeof(TCGArg) * def->nb_cargs); 5272 5273 i_allocated_regs = s->reserved_regs; 5274 o_allocated_regs = s->reserved_regs; 5275 5276 switch (op->opc) { 5277 case INDEX_op_brcond: 5278 op_cond = op->args[2]; 5279 break; 5280 case INDEX_op_setcond: 5281 case INDEX_op_negsetcond: 5282 case INDEX_op_cmp_vec: 5283 op_cond = op->args[3]; 5284 break; 5285 case INDEX_op_brcond2_i32: 5286 op_cond = op->args[4]; 5287 break; 5288 case INDEX_op_movcond: 5289 case INDEX_op_setcond2_i32: 5290 case INDEX_op_cmpsel_vec: 5291 op_cond = op->args[5]; 5292 break; 5293 default: 5294 /* No condition within opcode. */ 5295 op_cond = TCG_COND_ALWAYS; 5296 break; 5297 } 5298 5299 args_ct = opcode_args_ct(op); 5300 5301 /* satisfy input constraints */ 5302 for (k = 0; k < nb_iargs; k++) { 5303 TCGRegSet i_preferred_regs, i_required_regs; 5304 bool allocate_new_reg, copyto_new_reg; 5305 TCGTemp *ts2; 5306 int i1, i2; 5307 5308 i = args_ct[nb_oargs + k].sort_index; 5309 arg = op->args[i]; 5310 arg_ct = &args_ct[i]; 5311 ts = arg_temp(arg); 5312 5313 if (ts->val_type == TEMP_VAL_CONST) { 5314 #ifdef TCG_REG_ZERO 5315 if (ts->val == 0 && (arg_ct->ct & TCG_CT_REG_ZERO)) { 5316 /* Hardware zero register: indicate register via non-const. */ 5317 const_args[i] = 0; 5318 new_args[i] = TCG_REG_ZERO; 5319 continue; 5320 } 5321 #endif 5322 5323 if (tcg_target_const_match(ts->val, arg_ct->ct, ts->type, 5324 op_cond, TCGOP_VECE(op))) { 5325 /* constant is OK for instruction */ 5326 const_args[i] = 1; 5327 new_args[i] = ts->val; 5328 continue; 5329 } 5330 } 5331 5332 reg = ts->reg; 5333 i_preferred_regs = 0; 5334 i_required_regs = arg_ct->regs; 5335 allocate_new_reg = false; 5336 copyto_new_reg = false; 5337 5338 switch (arg_ct->pair) { 5339 case 0: /* not paired */ 5340 if (arg_ct->ialias) { 5341 i_preferred_regs = output_pref(op, arg_ct->alias_index); 5342 5343 /* 5344 * If the input is readonly, then it cannot also be an 5345 * output and aliased to itself. If the input is not 5346 * dead after the instruction, we must allocate a new 5347 * register and move it. 5348 */ 5349 if (temp_readonly(ts) || !IS_DEAD_ARG(i) 5350 || args_ct[arg_ct->alias_index].newreg) { 5351 allocate_new_reg = true; 5352 } else if (ts->val_type == TEMP_VAL_REG) { 5353 /* 5354 * Check if the current register has already been 5355 * allocated for another input. 5356 */ 5357 allocate_new_reg = 5358 tcg_regset_test_reg(i_allocated_regs, reg); 5359 } 5360 } 5361 if (!allocate_new_reg) { 5362 temp_load(s, ts, i_required_regs, i_allocated_regs, 5363 i_preferred_regs); 5364 reg = ts->reg; 5365 allocate_new_reg = !tcg_regset_test_reg(i_required_regs, reg); 5366 } 5367 if (allocate_new_reg) { 5368 /* 5369 * Allocate a new register matching the constraint 5370 * and move the temporary register into it. 5371 */ 5372 temp_load(s, ts, tcg_target_available_regs[ts->type], 5373 i_allocated_regs, 0); 5374 reg = tcg_reg_alloc(s, i_required_regs, i_allocated_regs, 5375 i_preferred_regs, ts->indirect_base); 5376 copyto_new_reg = true; 5377 } 5378 break; 5379 5380 case 1: 5381 /* First of an input pair; if i1 == i2, the second is an output. */ 5382 i1 = i; 5383 i2 = arg_ct->pair_index; 5384 ts2 = i1 != i2 ? arg_temp(op->args[i2]) : NULL; 5385 5386 /* 5387 * It is easier to default to allocating a new pair 5388 * and to identify a few cases where it's not required. 5389 */ 5390 if (arg_ct->ialias) { 5391 i_preferred_regs = output_pref(op, arg_ct->alias_index); 5392 if (IS_DEAD_ARG(i1) && 5393 IS_DEAD_ARG(i2) && 5394 !temp_readonly(ts) && 5395 ts->val_type == TEMP_VAL_REG && 5396 ts->reg < TCG_TARGET_NB_REGS - 1 && 5397 tcg_regset_test_reg(i_required_regs, reg) && 5398 !tcg_regset_test_reg(i_allocated_regs, reg) && 5399 !tcg_regset_test_reg(i_allocated_regs, reg + 1) && 5400 (ts2 5401 ? ts2->val_type == TEMP_VAL_REG && 5402 ts2->reg == reg + 1 && 5403 !temp_readonly(ts2) 5404 : s->reg_to_temp[reg + 1] == NULL)) { 5405 break; 5406 } 5407 } else { 5408 /* Without aliasing, the pair must also be an input. */ 5409 tcg_debug_assert(ts2); 5410 if (ts->val_type == TEMP_VAL_REG && 5411 ts2->val_type == TEMP_VAL_REG && 5412 ts2->reg == reg + 1 && 5413 tcg_regset_test_reg(i_required_regs, reg)) { 5414 break; 5415 } 5416 } 5417 reg = tcg_reg_alloc_pair(s, i_required_regs, i_allocated_regs, 5418 0, ts->indirect_base); 5419 goto do_pair; 5420 5421 case 2: /* pair second */ 5422 reg = new_args[arg_ct->pair_index] + 1; 5423 goto do_pair; 5424 5425 case 3: /* ialias with second output, no first input */ 5426 tcg_debug_assert(arg_ct->ialias); 5427 i_preferred_regs = output_pref(op, arg_ct->alias_index); 5428 5429 if (IS_DEAD_ARG(i) && 5430 !temp_readonly(ts) && 5431 ts->val_type == TEMP_VAL_REG && 5432 reg > 0 && 5433 s->reg_to_temp[reg - 1] == NULL && 5434 tcg_regset_test_reg(i_required_regs, reg) && 5435 !tcg_regset_test_reg(i_allocated_regs, reg) && 5436 !tcg_regset_test_reg(i_allocated_regs, reg - 1)) { 5437 tcg_regset_set_reg(i_allocated_regs, reg - 1); 5438 break; 5439 } 5440 reg = tcg_reg_alloc_pair(s, i_required_regs >> 1, 5441 i_allocated_regs, 0, 5442 ts->indirect_base); 5443 tcg_regset_set_reg(i_allocated_regs, reg); 5444 reg += 1; 5445 goto do_pair; 5446 5447 do_pair: 5448 /* 5449 * If an aliased input is not dead after the instruction, 5450 * we must allocate a new register and move it. 5451 */ 5452 if (arg_ct->ialias && (!IS_DEAD_ARG(i) || temp_readonly(ts))) { 5453 TCGRegSet t_allocated_regs = i_allocated_regs; 5454 5455 /* 5456 * Because of the alias, and the continued life, make sure 5457 * that the temp is somewhere *other* than the reg pair, 5458 * and we get a copy in reg. 5459 */ 5460 tcg_regset_set_reg(t_allocated_regs, reg); 5461 tcg_regset_set_reg(t_allocated_regs, reg + 1); 5462 if (ts->val_type == TEMP_VAL_REG && ts->reg == reg) { 5463 /* If ts was already in reg, copy it somewhere else. */ 5464 TCGReg nr; 5465 bool ok; 5466 5467 tcg_debug_assert(ts->kind != TEMP_FIXED); 5468 nr = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 5469 t_allocated_regs, 0, ts->indirect_base); 5470 ok = tcg_out_mov(s, ts->type, nr, reg); 5471 tcg_debug_assert(ok); 5472 5473 set_temp_val_reg(s, ts, nr); 5474 } else { 5475 temp_load(s, ts, tcg_target_available_regs[ts->type], 5476 t_allocated_regs, 0); 5477 copyto_new_reg = true; 5478 } 5479 } else { 5480 /* Preferably allocate to reg, otherwise copy. */ 5481 i_required_regs = (TCGRegSet)1 << reg; 5482 temp_load(s, ts, i_required_regs, i_allocated_regs, 5483 i_preferred_regs); 5484 copyto_new_reg = ts->reg != reg; 5485 } 5486 break; 5487 5488 default: 5489 g_assert_not_reached(); 5490 } 5491 5492 if (copyto_new_reg) { 5493 if (!tcg_out_mov(s, ts->type, reg, ts->reg)) { 5494 /* 5495 * Cross register class move not supported. Sync the 5496 * temp back to its slot and load from there. 5497 */ 5498 temp_sync(s, ts, i_allocated_regs, 0, 0); 5499 tcg_out_ld(s, ts->type, reg, 5500 ts->mem_base->reg, ts->mem_offset); 5501 } 5502 } 5503 new_args[i] = reg; 5504 const_args[i] = 0; 5505 tcg_regset_set_reg(i_allocated_regs, reg); 5506 } 5507 5508 /* mark dead temporaries and free the associated registers */ 5509 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) { 5510 if (IS_DEAD_ARG(i)) { 5511 temp_dead(s, arg_temp(op->args[i])); 5512 } 5513 } 5514 5515 if (def->flags & TCG_OPF_COND_BRANCH) { 5516 tcg_reg_alloc_cbranch(s, i_allocated_regs); 5517 } else if (def->flags & TCG_OPF_BB_END) { 5518 tcg_reg_alloc_bb_end(s, i_allocated_regs); 5519 } else { 5520 if (def->flags & TCG_OPF_CALL_CLOBBER) { 5521 assert_carry_dead(s); 5522 /* XXX: permit generic clobber register list ? */ 5523 for (i = 0; i < TCG_TARGET_NB_REGS; i++) { 5524 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) { 5525 tcg_reg_free(s, i, i_allocated_regs); 5526 } 5527 } 5528 } 5529 if (def->flags & TCG_OPF_SIDE_EFFECTS) { 5530 /* sync globals if the op has side effects and might trigger 5531 an exception. */ 5532 sync_globals(s, i_allocated_regs); 5533 } 5534 5535 /* satisfy the output constraints */ 5536 for (k = 0; k < nb_oargs; k++) { 5537 i = args_ct[k].sort_index; 5538 arg = op->args[i]; 5539 arg_ct = &args_ct[i]; 5540 ts = arg_temp(arg); 5541 5542 /* ENV should not be modified. */ 5543 tcg_debug_assert(!temp_readonly(ts)); 5544 5545 switch (arg_ct->pair) { 5546 case 0: /* not paired */ 5547 if (arg_ct->oalias && !const_args[arg_ct->alias_index]) { 5548 reg = new_args[arg_ct->alias_index]; 5549 } else if (arg_ct->newreg) { 5550 reg = tcg_reg_alloc(s, arg_ct->regs, 5551 i_allocated_regs | o_allocated_regs, 5552 output_pref(op, k), ts->indirect_base); 5553 } else { 5554 reg = tcg_reg_alloc(s, arg_ct->regs, o_allocated_regs, 5555 output_pref(op, k), ts->indirect_base); 5556 } 5557 break; 5558 5559 case 1: /* first of pair */ 5560 if (arg_ct->oalias) { 5561 reg = new_args[arg_ct->alias_index]; 5562 } else if (arg_ct->newreg) { 5563 reg = tcg_reg_alloc_pair(s, arg_ct->regs, 5564 i_allocated_regs | o_allocated_regs, 5565 output_pref(op, k), 5566 ts->indirect_base); 5567 } else { 5568 reg = tcg_reg_alloc_pair(s, arg_ct->regs, o_allocated_regs, 5569 output_pref(op, k), 5570 ts->indirect_base); 5571 } 5572 break; 5573 5574 case 2: /* second of pair */ 5575 if (arg_ct->oalias) { 5576 reg = new_args[arg_ct->alias_index]; 5577 } else { 5578 reg = new_args[arg_ct->pair_index] + 1; 5579 } 5580 break; 5581 5582 case 3: /* first of pair, aliasing with a second input */ 5583 tcg_debug_assert(!arg_ct->newreg); 5584 reg = new_args[arg_ct->pair_index] - 1; 5585 break; 5586 5587 default: 5588 g_assert_not_reached(); 5589 } 5590 tcg_regset_set_reg(o_allocated_regs, reg); 5591 set_temp_val_reg(s, ts, reg); 5592 ts->mem_coherent = 0; 5593 new_args[i] = reg; 5594 } 5595 } 5596 5597 /* emit instruction */ 5598 TCGType type = TCGOP_TYPE(op); 5599 switch (op->opc) { 5600 case INDEX_op_addc1o: 5601 tcg_out_set_carry(s); 5602 /* fall through */ 5603 case INDEX_op_add: 5604 case INDEX_op_addcio: 5605 case INDEX_op_addco: 5606 case INDEX_op_and: 5607 case INDEX_op_andc: 5608 case INDEX_op_clz: 5609 case INDEX_op_ctz: 5610 case INDEX_op_divs: 5611 case INDEX_op_divu: 5612 case INDEX_op_eqv: 5613 case INDEX_op_mul: 5614 case INDEX_op_mulsh: 5615 case INDEX_op_muluh: 5616 case INDEX_op_nand: 5617 case INDEX_op_nor: 5618 case INDEX_op_or: 5619 case INDEX_op_orc: 5620 case INDEX_op_rems: 5621 case INDEX_op_remu: 5622 case INDEX_op_rotl: 5623 case INDEX_op_rotr: 5624 case INDEX_op_sar: 5625 case INDEX_op_shl: 5626 case INDEX_op_shr: 5627 case INDEX_op_xor: 5628 { 5629 const TCGOutOpBinary *out = 5630 container_of(all_outop[op->opc], TCGOutOpBinary, base); 5631 5632 /* Constants should never appear in the first source operand. */ 5633 tcg_debug_assert(!const_args[1]); 5634 if (const_args[2]) { 5635 out->out_rri(s, type, new_args[0], new_args[1], new_args[2]); 5636 } else { 5637 out->out_rrr(s, type, new_args[0], new_args[1], new_args[2]); 5638 } 5639 } 5640 break; 5641 5642 case INDEX_op_sub: 5643 { 5644 const TCGOutOpSubtract *out = &outop_sub; 5645 5646 /* 5647 * Constants should never appear in the second source operand. 5648 * These are folded to add with negative constant. 5649 */ 5650 tcg_debug_assert(!const_args[2]); 5651 if (const_args[1]) { 5652 out->out_rir(s, type, new_args[0], new_args[1], new_args[2]); 5653 } else { 5654 out->out_rrr(s, type, new_args[0], new_args[1], new_args[2]); 5655 } 5656 } 5657 break; 5658 5659 case INDEX_op_subb1o: 5660 tcg_out_set_borrow(s); 5661 /* fall through */ 5662 case INDEX_op_addci: 5663 case INDEX_op_subbi: 5664 case INDEX_op_subbio: 5665 case INDEX_op_subbo: 5666 { 5667 const TCGOutOpAddSubCarry *out = 5668 container_of(all_outop[op->opc], TCGOutOpAddSubCarry, base); 5669 5670 if (const_args[2]) { 5671 if (const_args[1]) { 5672 out->out_rii(s, type, new_args[0], 5673 new_args[1], new_args[2]); 5674 } else { 5675 out->out_rri(s, type, new_args[0], 5676 new_args[1], new_args[2]); 5677 } 5678 } else if (const_args[1]) { 5679 out->out_rir(s, type, new_args[0], new_args[1], new_args[2]); 5680 } else { 5681 out->out_rrr(s, type, new_args[0], new_args[1], new_args[2]); 5682 } 5683 } 5684 break; 5685 5686 case INDEX_op_bswap64: 5687 case INDEX_op_ext_i32_i64: 5688 case INDEX_op_extu_i32_i64: 5689 case INDEX_op_extrl_i64_i32: 5690 case INDEX_op_extrh_i64_i32: 5691 assert(TCG_TARGET_REG_BITS == 64); 5692 /* fall through */ 5693 case INDEX_op_ctpop: 5694 case INDEX_op_neg: 5695 case INDEX_op_not: 5696 { 5697 const TCGOutOpUnary *out = 5698 container_of(all_outop[op->opc], TCGOutOpUnary, base); 5699 5700 /* Constants should have been folded. */ 5701 tcg_debug_assert(!const_args[1]); 5702 out->out_rr(s, type, new_args[0], new_args[1]); 5703 } 5704 break; 5705 5706 case INDEX_op_bswap16: 5707 case INDEX_op_bswap32: 5708 { 5709 const TCGOutOpBswap *out = 5710 container_of(all_outop[op->opc], TCGOutOpBswap, base); 5711 5712 tcg_debug_assert(!const_args[1]); 5713 out->out_rr(s, type, new_args[0], new_args[1], new_args[2]); 5714 } 5715 break; 5716 5717 case INDEX_op_deposit: 5718 { 5719 const TCGOutOpDeposit *out = &outop_deposit; 5720 5721 if (const_args[2]) { 5722 tcg_debug_assert(!const_args[1]); 5723 out->out_rri(s, type, new_args[0], new_args[1], 5724 new_args[2], new_args[3], new_args[4]); 5725 } else if (const_args[1]) { 5726 tcg_debug_assert(new_args[1] == 0); 5727 tcg_debug_assert(!const_args[2]); 5728 out->out_rzr(s, type, new_args[0], new_args[2], 5729 new_args[3], new_args[4]); 5730 } else { 5731 out->out_rrr(s, type, new_args[0], new_args[1], 5732 new_args[2], new_args[3], new_args[4]); 5733 } 5734 } 5735 break; 5736 5737 case INDEX_op_divs2: 5738 case INDEX_op_divu2: 5739 { 5740 const TCGOutOpDivRem *out = 5741 container_of(all_outop[op->opc], TCGOutOpDivRem, base); 5742 5743 /* Only used by x86 and s390x, which use matching constraints. */ 5744 tcg_debug_assert(new_args[0] == new_args[2]); 5745 tcg_debug_assert(new_args[1] == new_args[3]); 5746 tcg_debug_assert(!const_args[4]); 5747 out->out_rr01r(s, type, new_args[0], new_args[1], new_args[4]); 5748 } 5749 break; 5750 5751 case INDEX_op_extract: 5752 case INDEX_op_sextract: 5753 { 5754 const TCGOutOpExtract *out = 5755 container_of(all_outop[op->opc], TCGOutOpExtract, base); 5756 5757 tcg_debug_assert(!const_args[1]); 5758 out->out_rr(s, type, new_args[0], new_args[1], 5759 new_args[2], new_args[3]); 5760 } 5761 break; 5762 5763 case INDEX_op_extract2: 5764 { 5765 const TCGOutOpExtract2 *out = &outop_extract2; 5766 5767 tcg_debug_assert(!const_args[1]); 5768 tcg_debug_assert(!const_args[2]); 5769 out->out_rrr(s, type, new_args[0], new_args[1], 5770 new_args[2], new_args[3]); 5771 } 5772 break; 5773 5774 case INDEX_op_ld8u: 5775 case INDEX_op_ld8s: 5776 case INDEX_op_ld16u: 5777 case INDEX_op_ld16s: 5778 case INDEX_op_ld32u: 5779 case INDEX_op_ld32s: 5780 case INDEX_op_ld: 5781 { 5782 const TCGOutOpLoad *out = 5783 container_of(all_outop[op->opc], TCGOutOpLoad, base); 5784 5785 tcg_debug_assert(!const_args[1]); 5786 out->out(s, type, new_args[0], new_args[1], new_args[2]); 5787 } 5788 break; 5789 5790 case INDEX_op_muls2: 5791 case INDEX_op_mulu2: 5792 { 5793 const TCGOutOpMul2 *out = 5794 container_of(all_outop[op->opc], TCGOutOpMul2, base); 5795 5796 tcg_debug_assert(!const_args[2]); 5797 tcg_debug_assert(!const_args[3]); 5798 out->out_rrrr(s, type, new_args[0], new_args[1], 5799 new_args[2], new_args[3]); 5800 } 5801 break; 5802 5803 case INDEX_op_st32: 5804 /* Use tcg_op_st w/ I32. */ 5805 type = TCG_TYPE_I32; 5806 /* fall through */ 5807 case INDEX_op_st: 5808 case INDEX_op_st8: 5809 case INDEX_op_st16: 5810 { 5811 const TCGOutOpStore *out = 5812 container_of(all_outop[op->opc], TCGOutOpStore, base); 5813 5814 if (const_args[0]) { 5815 out->out_i(s, type, new_args[0], new_args[1], new_args[2]); 5816 } else { 5817 out->out_r(s, type, new_args[0], new_args[1], new_args[2]); 5818 } 5819 } 5820 break; 5821 5822 case INDEX_op_qemu_ld: 5823 case INDEX_op_qemu_st: 5824 { 5825 const TCGOutOpQemuLdSt *out = 5826 container_of(all_outop[op->opc], TCGOutOpQemuLdSt, base); 5827 5828 out->out(s, type, new_args[0], new_args[1], new_args[2]); 5829 } 5830 break; 5831 5832 case INDEX_op_qemu_ld2: 5833 case INDEX_op_qemu_st2: 5834 { 5835 const TCGOutOpQemuLdSt2 *out = 5836 container_of(all_outop[op->opc], TCGOutOpQemuLdSt2, base); 5837 5838 out->out(s, type, new_args[0], new_args[1], 5839 new_args[2], new_args[3]); 5840 } 5841 break; 5842 5843 case INDEX_op_brcond: 5844 { 5845 const TCGOutOpBrcond *out = &outop_brcond; 5846 TCGCond cond = new_args[2]; 5847 TCGLabel *label = arg_label(new_args[3]); 5848 5849 tcg_debug_assert(!const_args[0]); 5850 if (const_args[1]) { 5851 out->out_ri(s, type, cond, new_args[0], new_args[1], label); 5852 } else { 5853 out->out_rr(s, type, cond, new_args[0], new_args[1], label); 5854 } 5855 } 5856 break; 5857 5858 case INDEX_op_movcond: 5859 { 5860 const TCGOutOpMovcond *out = &outop_movcond; 5861 TCGCond cond = new_args[5]; 5862 5863 tcg_debug_assert(!const_args[1]); 5864 out->out(s, type, cond, new_args[0], 5865 new_args[1], new_args[2], const_args[2], 5866 new_args[3], const_args[3], 5867 new_args[4], const_args[4]); 5868 } 5869 break; 5870 5871 case INDEX_op_setcond: 5872 case INDEX_op_negsetcond: 5873 { 5874 const TCGOutOpSetcond *out = 5875 container_of(all_outop[op->opc], TCGOutOpSetcond, base); 5876 TCGCond cond = new_args[3]; 5877 5878 tcg_debug_assert(!const_args[1]); 5879 if (const_args[2]) { 5880 out->out_rri(s, type, cond, 5881 new_args[0], new_args[1], new_args[2]); 5882 } else { 5883 out->out_rrr(s, type, cond, 5884 new_args[0], new_args[1], new_args[2]); 5885 } 5886 } 5887 break; 5888 5889 #if TCG_TARGET_REG_BITS == 32 5890 case INDEX_op_brcond2_i32: 5891 { 5892 const TCGOutOpBrcond2 *out = &outop_brcond2; 5893 TCGCond cond = new_args[4]; 5894 TCGLabel *label = arg_label(new_args[5]); 5895 5896 tcg_debug_assert(!const_args[0]); 5897 tcg_debug_assert(!const_args[1]); 5898 out->out(s, cond, new_args[0], new_args[1], 5899 new_args[2], const_args[2], 5900 new_args[3], const_args[3], label); 5901 } 5902 break; 5903 case INDEX_op_setcond2_i32: 5904 { 5905 const TCGOutOpSetcond2 *out = &outop_setcond2; 5906 TCGCond cond = new_args[5]; 5907 5908 tcg_debug_assert(!const_args[1]); 5909 tcg_debug_assert(!const_args[2]); 5910 out->out(s, cond, new_args[0], new_args[1], new_args[2], 5911 new_args[3], const_args[3], new_args[4], const_args[4]); 5912 } 5913 break; 5914 #else 5915 case INDEX_op_brcond2_i32: 5916 case INDEX_op_setcond2_i32: 5917 g_assert_not_reached(); 5918 #endif 5919 5920 case INDEX_op_goto_ptr: 5921 tcg_debug_assert(!const_args[0]); 5922 tcg_out_goto_ptr(s, new_args[0]); 5923 break; 5924 5925 default: 5926 tcg_debug_assert(def->flags & TCG_OPF_VECTOR); 5927 tcg_out_vec_op(s, op->opc, type - TCG_TYPE_V64, 5928 TCGOP_VECE(op), new_args, const_args); 5929 break; 5930 } 5931 5932 if (def->flags & TCG_OPF_CARRY_IN) { 5933 s->carry_live = false; 5934 } 5935 if (def->flags & TCG_OPF_CARRY_OUT) { 5936 s->carry_live = true; 5937 } 5938 5939 /* move the outputs in the correct register if needed */ 5940 for(i = 0; i < nb_oargs; i++) { 5941 ts = arg_temp(op->args[i]); 5942 5943 /* ENV should not be modified. */ 5944 tcg_debug_assert(!temp_readonly(ts)); 5945 5946 if (NEED_SYNC_ARG(i)) { 5947 temp_sync(s, ts, o_allocated_regs, 0, IS_DEAD_ARG(i)); 5948 } else if (IS_DEAD_ARG(i)) { 5949 temp_dead(s, ts); 5950 } 5951 } 5952 } 5953 5954 static bool tcg_reg_alloc_dup2(TCGContext *s, const TCGOp *op) 5955 { 5956 const TCGLifeData arg_life = op->life; 5957 TCGTemp *ots, *itsl, *itsh; 5958 TCGType vtype = TCGOP_TYPE(op); 5959 5960 /* This opcode is only valid for 32-bit hosts, for 64-bit elements. */ 5961 tcg_debug_assert(TCG_TARGET_REG_BITS == 32); 5962 tcg_debug_assert(TCGOP_VECE(op) == MO_64); 5963 5964 ots = arg_temp(op->args[0]); 5965 itsl = arg_temp(op->args[1]); 5966 itsh = arg_temp(op->args[2]); 5967 5968 /* ENV should not be modified. */ 5969 tcg_debug_assert(!temp_readonly(ots)); 5970 5971 /* Allocate the output register now. */ 5972 if (ots->val_type != TEMP_VAL_REG) { 5973 TCGRegSet allocated_regs = s->reserved_regs; 5974 TCGRegSet dup_out_regs = opcode_args_ct(op)[0].regs; 5975 TCGReg oreg; 5976 5977 /* Make sure to not spill the input registers. */ 5978 if (!IS_DEAD_ARG(1) && itsl->val_type == TEMP_VAL_REG) { 5979 tcg_regset_set_reg(allocated_regs, itsl->reg); 5980 } 5981 if (!IS_DEAD_ARG(2) && itsh->val_type == TEMP_VAL_REG) { 5982 tcg_regset_set_reg(allocated_regs, itsh->reg); 5983 } 5984 5985 oreg = tcg_reg_alloc(s, dup_out_regs, allocated_regs, 5986 output_pref(op, 0), ots->indirect_base); 5987 set_temp_val_reg(s, ots, oreg); 5988 } 5989 5990 /* Promote dup2 of immediates to dupi_vec. */ 5991 if (itsl->val_type == TEMP_VAL_CONST && itsh->val_type == TEMP_VAL_CONST) { 5992 uint64_t val = deposit64(itsl->val, 32, 32, itsh->val); 5993 MemOp vece = MO_64; 5994 5995 if (val == dup_const(MO_8, val)) { 5996 vece = MO_8; 5997 } else if (val == dup_const(MO_16, val)) { 5998 vece = MO_16; 5999 } else if (val == dup_const(MO_32, val)) { 6000 vece = MO_32; 6001 } 6002 6003 tcg_out_dupi_vec(s, vtype, vece, ots->reg, val); 6004 goto done; 6005 } 6006 6007 /* If the two inputs form one 64-bit value, try dupm_vec. */ 6008 if (itsl->temp_subindex == HOST_BIG_ENDIAN && 6009 itsh->temp_subindex == !HOST_BIG_ENDIAN && 6010 itsl == itsh + (HOST_BIG_ENDIAN ? 1 : -1)) { 6011 TCGTemp *its = itsl - HOST_BIG_ENDIAN; 6012 6013 temp_sync(s, its + 0, s->reserved_regs, 0, 0); 6014 temp_sync(s, its + 1, s->reserved_regs, 0, 0); 6015 6016 if (tcg_out_dupm_vec(s, vtype, MO_64, ots->reg, 6017 its->mem_base->reg, its->mem_offset)) { 6018 goto done; 6019 } 6020 } 6021 6022 /* Fall back to generic expansion. */ 6023 return false; 6024 6025 done: 6026 ots->mem_coherent = 0; 6027 if (IS_DEAD_ARG(1)) { 6028 temp_dead(s, itsl); 6029 } 6030 if (IS_DEAD_ARG(2)) { 6031 temp_dead(s, itsh); 6032 } 6033 if (NEED_SYNC_ARG(0)) { 6034 temp_sync(s, ots, s->reserved_regs, 0, IS_DEAD_ARG(0)); 6035 } else if (IS_DEAD_ARG(0)) { 6036 temp_dead(s, ots); 6037 } 6038 return true; 6039 } 6040 6041 static void load_arg_reg(TCGContext *s, TCGReg reg, TCGTemp *ts, 6042 TCGRegSet allocated_regs) 6043 { 6044 if (ts->val_type == TEMP_VAL_REG) { 6045 if (ts->reg != reg) { 6046 tcg_reg_free(s, reg, allocated_regs); 6047 if (!tcg_out_mov(s, ts->type, reg, ts->reg)) { 6048 /* 6049 * Cross register class move not supported. Sync the 6050 * temp back to its slot and load from there. 6051 */ 6052 temp_sync(s, ts, allocated_regs, 0, 0); 6053 tcg_out_ld(s, ts->type, reg, 6054 ts->mem_base->reg, ts->mem_offset); 6055 } 6056 } 6057 } else { 6058 TCGRegSet arg_set = 0; 6059 6060 tcg_reg_free(s, reg, allocated_regs); 6061 tcg_regset_set_reg(arg_set, reg); 6062 temp_load(s, ts, arg_set, allocated_regs, 0); 6063 } 6064 } 6065 6066 static void load_arg_stk(TCGContext *s, unsigned arg_slot, TCGTemp *ts, 6067 TCGRegSet allocated_regs) 6068 { 6069 /* 6070 * When the destination is on the stack, load up the temp and store. 6071 * If there are many call-saved registers, the temp might live to 6072 * see another use; otherwise it'll be discarded. 6073 */ 6074 temp_load(s, ts, tcg_target_available_regs[ts->type], allocated_regs, 0); 6075 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, 6076 arg_slot_stk_ofs(arg_slot)); 6077 } 6078 6079 static void load_arg_normal(TCGContext *s, const TCGCallArgumentLoc *l, 6080 TCGTemp *ts, TCGRegSet *allocated_regs) 6081 { 6082 if (arg_slot_reg_p(l->arg_slot)) { 6083 TCGReg reg = tcg_target_call_iarg_regs[l->arg_slot]; 6084 load_arg_reg(s, reg, ts, *allocated_regs); 6085 tcg_regset_set_reg(*allocated_regs, reg); 6086 } else { 6087 load_arg_stk(s, l->arg_slot, ts, *allocated_regs); 6088 } 6089 } 6090 6091 static void load_arg_ref(TCGContext *s, unsigned arg_slot, TCGReg ref_base, 6092 intptr_t ref_off, TCGRegSet *allocated_regs) 6093 { 6094 TCGReg reg; 6095 6096 if (arg_slot_reg_p(arg_slot)) { 6097 reg = tcg_target_call_iarg_regs[arg_slot]; 6098 tcg_reg_free(s, reg, *allocated_regs); 6099 tcg_out_addi_ptr(s, reg, ref_base, ref_off); 6100 tcg_regset_set_reg(*allocated_regs, reg); 6101 } else { 6102 reg = tcg_reg_alloc(s, tcg_target_available_regs[TCG_TYPE_PTR], 6103 *allocated_regs, 0, false); 6104 tcg_out_addi_ptr(s, reg, ref_base, ref_off); 6105 tcg_out_st(s, TCG_TYPE_PTR, reg, TCG_REG_CALL_STACK, 6106 arg_slot_stk_ofs(arg_slot)); 6107 } 6108 } 6109 6110 static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op) 6111 { 6112 const int nb_oargs = TCGOP_CALLO(op); 6113 const int nb_iargs = TCGOP_CALLI(op); 6114 const TCGLifeData arg_life = op->life; 6115 const TCGHelperInfo *info = tcg_call_info(op); 6116 TCGRegSet allocated_regs = s->reserved_regs; 6117 int i; 6118 6119 /* 6120 * Move inputs into place in reverse order, 6121 * so that we place stacked arguments first. 6122 */ 6123 for (i = nb_iargs - 1; i >= 0; --i) { 6124 const TCGCallArgumentLoc *loc = &info->in[i]; 6125 TCGTemp *ts = arg_temp(op->args[nb_oargs + i]); 6126 6127 switch (loc->kind) { 6128 case TCG_CALL_ARG_NORMAL: 6129 case TCG_CALL_ARG_EXTEND_U: 6130 case TCG_CALL_ARG_EXTEND_S: 6131 load_arg_normal(s, loc, ts, &allocated_regs); 6132 break; 6133 case TCG_CALL_ARG_BY_REF: 6134 load_arg_stk(s, loc->ref_slot, ts, allocated_regs); 6135 load_arg_ref(s, loc->arg_slot, TCG_REG_CALL_STACK, 6136 arg_slot_stk_ofs(loc->ref_slot), 6137 &allocated_regs); 6138 break; 6139 case TCG_CALL_ARG_BY_REF_N: 6140 load_arg_stk(s, loc->ref_slot, ts, allocated_regs); 6141 break; 6142 default: 6143 g_assert_not_reached(); 6144 } 6145 } 6146 6147 /* Mark dead temporaries and free the associated registers. */ 6148 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) { 6149 if (IS_DEAD_ARG(i)) { 6150 temp_dead(s, arg_temp(op->args[i])); 6151 } 6152 } 6153 6154 /* Clobber call registers. */ 6155 for (i = 0; i < TCG_TARGET_NB_REGS; i++) { 6156 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) { 6157 tcg_reg_free(s, i, allocated_regs); 6158 } 6159 } 6160 6161 /* 6162 * Save globals if they might be written by the helper, 6163 * sync them if they might be read. 6164 */ 6165 if (info->flags & TCG_CALL_NO_READ_GLOBALS) { 6166 /* Nothing to do */ 6167 } else if (info->flags & TCG_CALL_NO_WRITE_GLOBALS) { 6168 sync_globals(s, allocated_regs); 6169 } else { 6170 save_globals(s, allocated_regs); 6171 } 6172 6173 /* 6174 * If the ABI passes a pointer to the returned struct as the first 6175 * argument, load that now. Pass a pointer to the output home slot. 6176 */ 6177 if (info->out_kind == TCG_CALL_RET_BY_REF) { 6178 TCGTemp *ts = arg_temp(op->args[0]); 6179 6180 if (!ts->mem_allocated) { 6181 temp_allocate_frame(s, ts); 6182 } 6183 load_arg_ref(s, 0, ts->mem_base->reg, ts->mem_offset, &allocated_regs); 6184 } 6185 6186 tcg_out_call(s, tcg_call_func(op), info); 6187 6188 /* Assign output registers and emit moves if needed. */ 6189 switch (info->out_kind) { 6190 case TCG_CALL_RET_NORMAL: 6191 for (i = 0; i < nb_oargs; i++) { 6192 TCGTemp *ts = arg_temp(op->args[i]); 6193 TCGReg reg = tcg_target_call_oarg_reg(TCG_CALL_RET_NORMAL, i); 6194 6195 /* ENV should not be modified. */ 6196 tcg_debug_assert(!temp_readonly(ts)); 6197 6198 set_temp_val_reg(s, ts, reg); 6199 ts->mem_coherent = 0; 6200 } 6201 break; 6202 6203 case TCG_CALL_RET_BY_VEC: 6204 { 6205 TCGTemp *ts = arg_temp(op->args[0]); 6206 6207 tcg_debug_assert(ts->base_type == TCG_TYPE_I128); 6208 tcg_debug_assert(ts->temp_subindex == 0); 6209 if (!ts->mem_allocated) { 6210 temp_allocate_frame(s, ts); 6211 } 6212 tcg_out_st(s, TCG_TYPE_V128, 6213 tcg_target_call_oarg_reg(TCG_CALL_RET_BY_VEC, 0), 6214 ts->mem_base->reg, ts->mem_offset); 6215 } 6216 /* fall through to mark all parts in memory */ 6217 6218 case TCG_CALL_RET_BY_REF: 6219 /* The callee has performed a write through the reference. */ 6220 for (i = 0; i < nb_oargs; i++) { 6221 TCGTemp *ts = arg_temp(op->args[i]); 6222 ts->val_type = TEMP_VAL_MEM; 6223 } 6224 break; 6225 6226 default: 6227 g_assert_not_reached(); 6228 } 6229 6230 /* Flush or discard output registers as needed. */ 6231 for (i = 0; i < nb_oargs; i++) { 6232 TCGTemp *ts = arg_temp(op->args[i]); 6233 if (NEED_SYNC_ARG(i)) { 6234 temp_sync(s, ts, s->reserved_regs, 0, IS_DEAD_ARG(i)); 6235 } else if (IS_DEAD_ARG(i)) { 6236 temp_dead(s, ts); 6237 } 6238 } 6239 } 6240 6241 /** 6242 * atom_and_align_for_opc: 6243 * @s: tcg context 6244 * @opc: memory operation code 6245 * @host_atom: MO_ATOM_{IFALIGN,WITHIN16,SUBALIGN} for host operations 6246 * @allow_two_ops: true if we are prepared to issue two operations 6247 * 6248 * Return the alignment and atomicity to use for the inline fast path 6249 * for the given memory operation. The alignment may be larger than 6250 * that specified in @opc, and the correct alignment will be diagnosed 6251 * by the slow path helper. 6252 * 6253 * If @allow_two_ops, the host is prepared to test for 2x alignment, 6254 * and issue two loads or stores for subalignment. 6255 */ 6256 static TCGAtomAlign atom_and_align_for_opc(TCGContext *s, MemOp opc, 6257 MemOp host_atom, bool allow_two_ops) 6258 { 6259 MemOp align = memop_alignment_bits(opc); 6260 MemOp size = opc & MO_SIZE; 6261 MemOp half = size ? size - 1 : 0; 6262 MemOp atom = opc & MO_ATOM_MASK; 6263 MemOp atmax; 6264 6265 switch (atom) { 6266 case MO_ATOM_NONE: 6267 /* The operation requires no specific atomicity. */ 6268 atmax = MO_8; 6269 break; 6270 6271 case MO_ATOM_IFALIGN: 6272 atmax = size; 6273 break; 6274 6275 case MO_ATOM_IFALIGN_PAIR: 6276 atmax = half; 6277 break; 6278 6279 case MO_ATOM_WITHIN16: 6280 atmax = size; 6281 if (size == MO_128) { 6282 /* Misalignment implies !within16, and therefore no atomicity. */ 6283 } else if (host_atom != MO_ATOM_WITHIN16) { 6284 /* The host does not implement within16, so require alignment. */ 6285 align = MAX(align, size); 6286 } 6287 break; 6288 6289 case MO_ATOM_WITHIN16_PAIR: 6290 atmax = size; 6291 /* 6292 * Misalignment implies !within16, and therefore half atomicity. 6293 * Any host prepared for two operations can implement this with 6294 * half alignment. 6295 */ 6296 if (host_atom != MO_ATOM_WITHIN16 && allow_two_ops) { 6297 align = MAX(align, half); 6298 } 6299 break; 6300 6301 case MO_ATOM_SUBALIGN: 6302 atmax = size; 6303 if (host_atom != MO_ATOM_SUBALIGN) { 6304 /* If unaligned but not odd, there are subobjects up to half. */ 6305 if (allow_two_ops) { 6306 align = MAX(align, half); 6307 } else { 6308 align = MAX(align, size); 6309 } 6310 } 6311 break; 6312 6313 default: 6314 g_assert_not_reached(); 6315 } 6316 6317 return (TCGAtomAlign){ .atom = atmax, .align = align }; 6318 } 6319 6320 /* 6321 * Similarly for qemu_ld/st slow path helpers. 6322 * We must re-implement tcg_gen_callN and tcg_reg_alloc_call simultaneously, 6323 * using only the provided backend tcg_out_* functions. 6324 */ 6325 6326 static int tcg_out_helper_stk_ofs(TCGType type, unsigned slot) 6327 { 6328 int ofs = arg_slot_stk_ofs(slot); 6329 6330 /* 6331 * Each stack slot is TCG_TARGET_LONG_BITS. If the host does not 6332 * require extension to uint64_t, adjust the address for uint32_t. 6333 */ 6334 if (HOST_BIG_ENDIAN && 6335 TCG_TARGET_REG_BITS == 64 && 6336 type == TCG_TYPE_I32) { 6337 ofs += 4; 6338 } 6339 return ofs; 6340 } 6341 6342 static void tcg_out_helper_load_slots(TCGContext *s, 6343 unsigned nmov, TCGMovExtend *mov, 6344 const TCGLdstHelperParam *parm) 6345 { 6346 unsigned i; 6347 TCGReg dst3; 6348 6349 /* 6350 * Start from the end, storing to the stack first. 6351 * This frees those registers, so we need not consider overlap. 6352 */ 6353 for (i = nmov; i-- > 0; ) { 6354 unsigned slot = mov[i].dst; 6355 6356 if (arg_slot_reg_p(slot)) { 6357 goto found_reg; 6358 } 6359 6360 TCGReg src = mov[i].src; 6361 TCGType dst_type = mov[i].dst_type; 6362 MemOp dst_mo = dst_type == TCG_TYPE_I32 ? MO_32 : MO_64; 6363 6364 /* The argument is going onto the stack; extend into scratch. */ 6365 if ((mov[i].src_ext & MO_SIZE) != dst_mo) { 6366 tcg_debug_assert(parm->ntmp != 0); 6367 mov[i].dst = src = parm->tmp[0]; 6368 tcg_out_movext1(s, &mov[i]); 6369 } 6370 6371 tcg_out_st(s, dst_type, src, TCG_REG_CALL_STACK, 6372 tcg_out_helper_stk_ofs(dst_type, slot)); 6373 } 6374 return; 6375 6376 found_reg: 6377 /* 6378 * The remaining arguments are in registers. 6379 * Convert slot numbers to argument registers. 6380 */ 6381 nmov = i + 1; 6382 for (i = 0; i < nmov; ++i) { 6383 mov[i].dst = tcg_target_call_iarg_regs[mov[i].dst]; 6384 } 6385 6386 switch (nmov) { 6387 case 4: 6388 /* The backend must have provided enough temps for the worst case. */ 6389 tcg_debug_assert(parm->ntmp >= 2); 6390 6391 dst3 = mov[3].dst; 6392 for (unsigned j = 0; j < 3; ++j) { 6393 if (dst3 == mov[j].src) { 6394 /* 6395 * Conflict. Copy the source to a temporary, perform the 6396 * remaining moves, then the extension from our scratch 6397 * on the way out. 6398 */ 6399 TCGReg scratch = parm->tmp[1]; 6400 6401 tcg_out_mov(s, mov[3].src_type, scratch, mov[3].src); 6402 tcg_out_movext3(s, mov, mov + 1, mov + 2, parm->tmp[0]); 6403 tcg_out_movext1_new_src(s, &mov[3], scratch); 6404 break; 6405 } 6406 } 6407 6408 /* No conflicts: perform this move and continue. */ 6409 tcg_out_movext1(s, &mov[3]); 6410 /* fall through */ 6411 6412 case 3: 6413 tcg_out_movext3(s, mov, mov + 1, mov + 2, 6414 parm->ntmp ? parm->tmp[0] : -1); 6415 break; 6416 case 2: 6417 tcg_out_movext2(s, mov, mov + 1, 6418 parm->ntmp ? parm->tmp[0] : -1); 6419 break; 6420 case 1: 6421 tcg_out_movext1(s, mov); 6422 break; 6423 default: 6424 g_assert_not_reached(); 6425 } 6426 } 6427 6428 static void tcg_out_helper_load_imm(TCGContext *s, unsigned slot, 6429 TCGType type, tcg_target_long imm, 6430 const TCGLdstHelperParam *parm) 6431 { 6432 if (arg_slot_reg_p(slot)) { 6433 tcg_out_movi(s, type, tcg_target_call_iarg_regs[slot], imm); 6434 } else { 6435 int ofs = tcg_out_helper_stk_ofs(type, slot); 6436 if (!tcg_out_sti(s, type, imm, TCG_REG_CALL_STACK, ofs)) { 6437 tcg_debug_assert(parm->ntmp != 0); 6438 tcg_out_movi(s, type, parm->tmp[0], imm); 6439 tcg_out_st(s, type, parm->tmp[0], TCG_REG_CALL_STACK, ofs); 6440 } 6441 } 6442 } 6443 6444 static void tcg_out_helper_load_common_args(TCGContext *s, 6445 const TCGLabelQemuLdst *ldst, 6446 const TCGLdstHelperParam *parm, 6447 const TCGHelperInfo *info, 6448 unsigned next_arg) 6449 { 6450 TCGMovExtend ptr_mov = { 6451 .dst_type = TCG_TYPE_PTR, 6452 .src_type = TCG_TYPE_PTR, 6453 .src_ext = sizeof(void *) == 4 ? MO_32 : MO_64 6454 }; 6455 const TCGCallArgumentLoc *loc = &info->in[0]; 6456 TCGType type; 6457 unsigned slot; 6458 tcg_target_ulong imm; 6459 6460 /* 6461 * Handle env, which is always first. 6462 */ 6463 ptr_mov.dst = loc->arg_slot; 6464 ptr_mov.src = TCG_AREG0; 6465 tcg_out_helper_load_slots(s, 1, &ptr_mov, parm); 6466 6467 /* 6468 * Handle oi. 6469 */ 6470 imm = ldst->oi; 6471 loc = &info->in[next_arg]; 6472 type = TCG_TYPE_I32; 6473 switch (loc->kind) { 6474 case TCG_CALL_ARG_NORMAL: 6475 break; 6476 case TCG_CALL_ARG_EXTEND_U: 6477 case TCG_CALL_ARG_EXTEND_S: 6478 /* No extension required for MemOpIdx. */ 6479 tcg_debug_assert(imm <= INT32_MAX); 6480 type = TCG_TYPE_REG; 6481 break; 6482 default: 6483 g_assert_not_reached(); 6484 } 6485 tcg_out_helper_load_imm(s, loc->arg_slot, type, imm, parm); 6486 next_arg++; 6487 6488 /* 6489 * Handle ra. 6490 */ 6491 loc = &info->in[next_arg]; 6492 slot = loc->arg_slot; 6493 if (parm->ra_gen) { 6494 int arg_reg = -1; 6495 TCGReg ra_reg; 6496 6497 if (arg_slot_reg_p(slot)) { 6498 arg_reg = tcg_target_call_iarg_regs[slot]; 6499 } 6500 ra_reg = parm->ra_gen(s, ldst, arg_reg); 6501 6502 ptr_mov.dst = slot; 6503 ptr_mov.src = ra_reg; 6504 tcg_out_helper_load_slots(s, 1, &ptr_mov, parm); 6505 } else { 6506 imm = (uintptr_t)ldst->raddr; 6507 tcg_out_helper_load_imm(s, slot, TCG_TYPE_PTR, imm, parm); 6508 } 6509 } 6510 6511 static unsigned tcg_out_helper_add_mov(TCGMovExtend *mov, 6512 const TCGCallArgumentLoc *loc, 6513 TCGType dst_type, TCGType src_type, 6514 TCGReg lo, TCGReg hi) 6515 { 6516 MemOp reg_mo; 6517 6518 if (dst_type <= TCG_TYPE_REG) { 6519 MemOp src_ext; 6520 6521 switch (loc->kind) { 6522 case TCG_CALL_ARG_NORMAL: 6523 src_ext = src_type == TCG_TYPE_I32 ? MO_32 : MO_64; 6524 break; 6525 case TCG_CALL_ARG_EXTEND_U: 6526 dst_type = TCG_TYPE_REG; 6527 src_ext = MO_UL; 6528 break; 6529 case TCG_CALL_ARG_EXTEND_S: 6530 dst_type = TCG_TYPE_REG; 6531 src_ext = MO_SL; 6532 break; 6533 default: 6534 g_assert_not_reached(); 6535 } 6536 6537 mov[0].dst = loc->arg_slot; 6538 mov[0].dst_type = dst_type; 6539 mov[0].src = lo; 6540 mov[0].src_type = src_type; 6541 mov[0].src_ext = src_ext; 6542 return 1; 6543 } 6544 6545 if (TCG_TARGET_REG_BITS == 32) { 6546 assert(dst_type == TCG_TYPE_I64); 6547 reg_mo = MO_32; 6548 } else { 6549 assert(dst_type == TCG_TYPE_I128); 6550 reg_mo = MO_64; 6551 } 6552 6553 mov[0].dst = loc[HOST_BIG_ENDIAN].arg_slot; 6554 mov[0].src = lo; 6555 mov[0].dst_type = TCG_TYPE_REG; 6556 mov[0].src_type = TCG_TYPE_REG; 6557 mov[0].src_ext = reg_mo; 6558 6559 mov[1].dst = loc[!HOST_BIG_ENDIAN].arg_slot; 6560 mov[1].src = hi; 6561 mov[1].dst_type = TCG_TYPE_REG; 6562 mov[1].src_type = TCG_TYPE_REG; 6563 mov[1].src_ext = reg_mo; 6564 6565 return 2; 6566 } 6567 6568 static void tcg_out_ld_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst, 6569 const TCGLdstHelperParam *parm) 6570 { 6571 const TCGHelperInfo *info; 6572 const TCGCallArgumentLoc *loc; 6573 TCGMovExtend mov[2]; 6574 unsigned next_arg, nmov; 6575 MemOp mop = get_memop(ldst->oi); 6576 6577 switch (mop & MO_SIZE) { 6578 case MO_8: 6579 case MO_16: 6580 case MO_32: 6581 info = &info_helper_ld32_mmu; 6582 break; 6583 case MO_64: 6584 info = &info_helper_ld64_mmu; 6585 break; 6586 case MO_128: 6587 info = &info_helper_ld128_mmu; 6588 break; 6589 default: 6590 g_assert_not_reached(); 6591 } 6592 6593 /* Defer env argument. */ 6594 next_arg = 1; 6595 6596 loc = &info->in[next_arg]; 6597 if (TCG_TARGET_REG_BITS == 32 && s->addr_type == TCG_TYPE_I32) { 6598 /* 6599 * 32-bit host with 32-bit guest: zero-extend the guest address 6600 * to 64-bits for the helper by storing the low part, then 6601 * load a zero for the high part. 6602 */ 6603 tcg_out_helper_add_mov(mov, loc + HOST_BIG_ENDIAN, 6604 TCG_TYPE_I32, TCG_TYPE_I32, 6605 ldst->addr_reg, -1); 6606 tcg_out_helper_load_slots(s, 1, mov, parm); 6607 6608 tcg_out_helper_load_imm(s, loc[!HOST_BIG_ENDIAN].arg_slot, 6609 TCG_TYPE_I32, 0, parm); 6610 next_arg += 2; 6611 } else { 6612 nmov = tcg_out_helper_add_mov(mov, loc, TCG_TYPE_I64, s->addr_type, 6613 ldst->addr_reg, -1); 6614 tcg_out_helper_load_slots(s, nmov, mov, parm); 6615 next_arg += nmov; 6616 } 6617 6618 switch (info->out_kind) { 6619 case TCG_CALL_RET_NORMAL: 6620 case TCG_CALL_RET_BY_VEC: 6621 break; 6622 case TCG_CALL_RET_BY_REF: 6623 /* 6624 * The return reference is in the first argument slot. 6625 * We need memory in which to return: re-use the top of stack. 6626 */ 6627 { 6628 int ofs_slot0 = TCG_TARGET_CALL_STACK_OFFSET; 6629 6630 if (arg_slot_reg_p(0)) { 6631 tcg_out_addi_ptr(s, tcg_target_call_iarg_regs[0], 6632 TCG_REG_CALL_STACK, ofs_slot0); 6633 } else { 6634 tcg_debug_assert(parm->ntmp != 0); 6635 tcg_out_addi_ptr(s, parm->tmp[0], 6636 TCG_REG_CALL_STACK, ofs_slot0); 6637 tcg_out_st(s, TCG_TYPE_PTR, parm->tmp[0], 6638 TCG_REG_CALL_STACK, ofs_slot0); 6639 } 6640 } 6641 break; 6642 default: 6643 g_assert_not_reached(); 6644 } 6645 6646 tcg_out_helper_load_common_args(s, ldst, parm, info, next_arg); 6647 } 6648 6649 static void tcg_out_ld_helper_ret(TCGContext *s, const TCGLabelQemuLdst *ldst, 6650 bool load_sign, 6651 const TCGLdstHelperParam *parm) 6652 { 6653 MemOp mop = get_memop(ldst->oi); 6654 TCGMovExtend mov[2]; 6655 int ofs_slot0; 6656 6657 switch (ldst->type) { 6658 case TCG_TYPE_I64: 6659 if (TCG_TARGET_REG_BITS == 32) { 6660 break; 6661 } 6662 /* fall through */ 6663 6664 case TCG_TYPE_I32: 6665 mov[0].dst = ldst->datalo_reg; 6666 mov[0].src = tcg_target_call_oarg_reg(TCG_CALL_RET_NORMAL, 0); 6667 mov[0].dst_type = ldst->type; 6668 mov[0].src_type = TCG_TYPE_REG; 6669 6670 /* 6671 * If load_sign, then we allowed the helper to perform the 6672 * appropriate sign extension to tcg_target_ulong, and all 6673 * we need now is a plain move. 6674 * 6675 * If they do not, then we expect the relevant extension 6676 * instruction to be no more expensive than a move, and 6677 * we thus save the icache etc by only using one of two 6678 * helper functions. 6679 */ 6680 if (load_sign || !(mop & MO_SIGN)) { 6681 if (TCG_TARGET_REG_BITS == 32 || ldst->type == TCG_TYPE_I32) { 6682 mov[0].src_ext = MO_32; 6683 } else { 6684 mov[0].src_ext = MO_64; 6685 } 6686 } else { 6687 mov[0].src_ext = mop & MO_SSIZE; 6688 } 6689 tcg_out_movext1(s, mov); 6690 return; 6691 6692 case TCG_TYPE_I128: 6693 tcg_debug_assert(TCG_TARGET_REG_BITS == 64); 6694 ofs_slot0 = TCG_TARGET_CALL_STACK_OFFSET; 6695 switch (TCG_TARGET_CALL_RET_I128) { 6696 case TCG_CALL_RET_NORMAL: 6697 break; 6698 case TCG_CALL_RET_BY_VEC: 6699 tcg_out_st(s, TCG_TYPE_V128, 6700 tcg_target_call_oarg_reg(TCG_CALL_RET_BY_VEC, 0), 6701 TCG_REG_CALL_STACK, ofs_slot0); 6702 /* fall through */ 6703 case TCG_CALL_RET_BY_REF: 6704 tcg_out_ld(s, TCG_TYPE_I64, ldst->datalo_reg, 6705 TCG_REG_CALL_STACK, ofs_slot0 + 8 * HOST_BIG_ENDIAN); 6706 tcg_out_ld(s, TCG_TYPE_I64, ldst->datahi_reg, 6707 TCG_REG_CALL_STACK, ofs_slot0 + 8 * !HOST_BIG_ENDIAN); 6708 return; 6709 default: 6710 g_assert_not_reached(); 6711 } 6712 break; 6713 6714 default: 6715 g_assert_not_reached(); 6716 } 6717 6718 mov[0].dst = ldst->datalo_reg; 6719 mov[0].src = 6720 tcg_target_call_oarg_reg(TCG_CALL_RET_NORMAL, HOST_BIG_ENDIAN); 6721 mov[0].dst_type = TCG_TYPE_REG; 6722 mov[0].src_type = TCG_TYPE_REG; 6723 mov[0].src_ext = TCG_TARGET_REG_BITS == 32 ? MO_32 : MO_64; 6724 6725 mov[1].dst = ldst->datahi_reg; 6726 mov[1].src = 6727 tcg_target_call_oarg_reg(TCG_CALL_RET_NORMAL, !HOST_BIG_ENDIAN); 6728 mov[1].dst_type = TCG_TYPE_REG; 6729 mov[1].src_type = TCG_TYPE_REG; 6730 mov[1].src_ext = TCG_TARGET_REG_BITS == 32 ? MO_32 : MO_64; 6731 6732 tcg_out_movext2(s, mov, mov + 1, parm->ntmp ? parm->tmp[0] : -1); 6733 } 6734 6735 static void tcg_out_st_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst, 6736 const TCGLdstHelperParam *parm) 6737 { 6738 const TCGHelperInfo *info; 6739 const TCGCallArgumentLoc *loc; 6740 TCGMovExtend mov[4]; 6741 TCGType data_type; 6742 unsigned next_arg, nmov, n; 6743 MemOp mop = get_memop(ldst->oi); 6744 6745 switch (mop & MO_SIZE) { 6746 case MO_8: 6747 case MO_16: 6748 case MO_32: 6749 info = &info_helper_st32_mmu; 6750 data_type = TCG_TYPE_I32; 6751 break; 6752 case MO_64: 6753 info = &info_helper_st64_mmu; 6754 data_type = TCG_TYPE_I64; 6755 break; 6756 case MO_128: 6757 info = &info_helper_st128_mmu; 6758 data_type = TCG_TYPE_I128; 6759 break; 6760 default: 6761 g_assert_not_reached(); 6762 } 6763 6764 /* Defer env argument. */ 6765 next_arg = 1; 6766 nmov = 0; 6767 6768 /* Handle addr argument. */ 6769 loc = &info->in[next_arg]; 6770 tcg_debug_assert(s->addr_type <= TCG_TYPE_REG); 6771 if (TCG_TARGET_REG_BITS == 32) { 6772 /* 6773 * 32-bit host (and thus 32-bit guest): zero-extend the guest address 6774 * to 64-bits for the helper by storing the low part. Later, 6775 * after we have processed the register inputs, we will load a 6776 * zero for the high part. 6777 */ 6778 tcg_out_helper_add_mov(mov, loc + HOST_BIG_ENDIAN, 6779 TCG_TYPE_I32, TCG_TYPE_I32, 6780 ldst->addr_reg, -1); 6781 next_arg += 2; 6782 nmov += 1; 6783 } else { 6784 n = tcg_out_helper_add_mov(mov, loc, TCG_TYPE_I64, s->addr_type, 6785 ldst->addr_reg, -1); 6786 next_arg += n; 6787 nmov += n; 6788 } 6789 6790 /* Handle data argument. */ 6791 loc = &info->in[next_arg]; 6792 switch (loc->kind) { 6793 case TCG_CALL_ARG_NORMAL: 6794 case TCG_CALL_ARG_EXTEND_U: 6795 case TCG_CALL_ARG_EXTEND_S: 6796 n = tcg_out_helper_add_mov(mov + nmov, loc, data_type, ldst->type, 6797 ldst->datalo_reg, ldst->datahi_reg); 6798 next_arg += n; 6799 nmov += n; 6800 tcg_out_helper_load_slots(s, nmov, mov, parm); 6801 break; 6802 6803 case TCG_CALL_ARG_BY_REF: 6804 tcg_debug_assert(TCG_TARGET_REG_BITS == 64); 6805 tcg_debug_assert(data_type == TCG_TYPE_I128); 6806 tcg_out_st(s, TCG_TYPE_I64, 6807 HOST_BIG_ENDIAN ? ldst->datahi_reg : ldst->datalo_reg, 6808 TCG_REG_CALL_STACK, arg_slot_stk_ofs(loc[0].ref_slot)); 6809 tcg_out_st(s, TCG_TYPE_I64, 6810 HOST_BIG_ENDIAN ? ldst->datalo_reg : ldst->datahi_reg, 6811 TCG_REG_CALL_STACK, arg_slot_stk_ofs(loc[1].ref_slot)); 6812 6813 tcg_out_helper_load_slots(s, nmov, mov, parm); 6814 6815 if (arg_slot_reg_p(loc->arg_slot)) { 6816 tcg_out_addi_ptr(s, tcg_target_call_iarg_regs[loc->arg_slot], 6817 TCG_REG_CALL_STACK, 6818 arg_slot_stk_ofs(loc->ref_slot)); 6819 } else { 6820 tcg_debug_assert(parm->ntmp != 0); 6821 tcg_out_addi_ptr(s, parm->tmp[0], TCG_REG_CALL_STACK, 6822 arg_slot_stk_ofs(loc->ref_slot)); 6823 tcg_out_st(s, TCG_TYPE_PTR, parm->tmp[0], 6824 TCG_REG_CALL_STACK, arg_slot_stk_ofs(loc->arg_slot)); 6825 } 6826 next_arg += 2; 6827 break; 6828 6829 default: 6830 g_assert_not_reached(); 6831 } 6832 6833 if (TCG_TARGET_REG_BITS == 32) { 6834 /* Zero extend the address by loading a zero for the high part. */ 6835 loc = &info->in[1 + !HOST_BIG_ENDIAN]; 6836 tcg_out_helper_load_imm(s, loc->arg_slot, TCG_TYPE_I32, 0, parm); 6837 } 6838 6839 tcg_out_helper_load_common_args(s, ldst, parm, info, next_arg); 6840 } 6841 6842 int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start) 6843 { 6844 int i, num_insns; 6845 TCGOp *op; 6846 6847 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP) 6848 && qemu_log_in_addr_range(pc_start))) { 6849 FILE *logfile = qemu_log_trylock(); 6850 if (logfile) { 6851 fprintf(logfile, "OP:\n"); 6852 tcg_dump_ops(s, logfile, false); 6853 fprintf(logfile, "\n"); 6854 qemu_log_unlock(logfile); 6855 } 6856 } 6857 6858 #ifdef CONFIG_DEBUG_TCG 6859 /* Ensure all labels referenced have been emitted. */ 6860 { 6861 TCGLabel *l; 6862 bool error = false; 6863 6864 QSIMPLEQ_FOREACH(l, &s->labels, next) { 6865 if (unlikely(!l->present) && !QSIMPLEQ_EMPTY(&l->branches)) { 6866 qemu_log_mask(CPU_LOG_TB_OP, 6867 "$L%d referenced but not present.\n", l->id); 6868 error = true; 6869 } 6870 } 6871 assert(!error); 6872 } 6873 #endif 6874 6875 /* Do not reuse any EBB that may be allocated within the TB. */ 6876 tcg_temp_ebb_reset_freed(s); 6877 6878 tcg_optimize(s); 6879 6880 reachable_code_pass(s); 6881 liveness_pass_0(s); 6882 liveness_pass_1(s); 6883 6884 if (s->nb_indirects > 0) { 6885 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_IND) 6886 && qemu_log_in_addr_range(pc_start))) { 6887 FILE *logfile = qemu_log_trylock(); 6888 if (logfile) { 6889 fprintf(logfile, "OP before indirect lowering:\n"); 6890 tcg_dump_ops(s, logfile, false); 6891 fprintf(logfile, "\n"); 6892 qemu_log_unlock(logfile); 6893 } 6894 } 6895 6896 /* Replace indirect temps with direct temps. */ 6897 if (liveness_pass_2(s)) { 6898 /* If changes were made, re-run liveness. */ 6899 liveness_pass_1(s); 6900 } 6901 } 6902 6903 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT) 6904 && qemu_log_in_addr_range(pc_start))) { 6905 FILE *logfile = qemu_log_trylock(); 6906 if (logfile) { 6907 fprintf(logfile, "OP after optimization and liveness analysis:\n"); 6908 tcg_dump_ops(s, logfile, true); 6909 fprintf(logfile, "\n"); 6910 qemu_log_unlock(logfile); 6911 } 6912 } 6913 6914 /* Initialize goto_tb jump offsets. */ 6915 tb->jmp_reset_offset[0] = TB_JMP_OFFSET_INVALID; 6916 tb->jmp_reset_offset[1] = TB_JMP_OFFSET_INVALID; 6917 tb->jmp_insn_offset[0] = TB_JMP_OFFSET_INVALID; 6918 tb->jmp_insn_offset[1] = TB_JMP_OFFSET_INVALID; 6919 6920 tcg_reg_alloc_start(s); 6921 6922 /* 6923 * Reset the buffer pointers when restarting after overflow. 6924 * TODO: Move this into translate-all.c with the rest of the 6925 * buffer management. Having only this done here is confusing. 6926 */ 6927 s->code_buf = tcg_splitwx_to_rw(tb->tc.ptr); 6928 s->code_ptr = s->code_buf; 6929 s->data_gen_ptr = NULL; 6930 6931 QSIMPLEQ_INIT(&s->ldst_labels); 6932 s->pool_labels = NULL; 6933 6934 s->gen_insn_data = 6935 tcg_malloc(sizeof(uint64_t) * s->gen_tb->icount * INSN_START_WORDS); 6936 6937 tcg_out_tb_start(s); 6938 6939 num_insns = -1; 6940 s->carry_live = false; 6941 QTAILQ_FOREACH(op, &s->ops, link) { 6942 TCGOpcode opc = op->opc; 6943 6944 switch (opc) { 6945 case INDEX_op_extrl_i64_i32: 6946 assert(TCG_TARGET_REG_BITS == 64); 6947 /* 6948 * If TCG_TYPE_I32 is represented in some canonical form, 6949 * e.g. zero or sign-extended, then emit as a unary op. 6950 * Otherwise we can treat this as a plain move. 6951 * If the output dies, treat this as a plain move, because 6952 * this will be implemented with a store. 6953 */ 6954 if (TCG_TARGET_HAS_extr_i64_i32) { 6955 TCGLifeData arg_life = op->life; 6956 if (!IS_DEAD_ARG(0)) { 6957 goto do_default; 6958 } 6959 } 6960 /* fall through */ 6961 case INDEX_op_mov: 6962 case INDEX_op_mov_vec: 6963 tcg_reg_alloc_mov(s, op); 6964 break; 6965 case INDEX_op_dup_vec: 6966 tcg_reg_alloc_dup(s, op); 6967 break; 6968 case INDEX_op_insn_start: 6969 assert_carry_dead(s); 6970 if (num_insns >= 0) { 6971 size_t off = tcg_current_code_size(s); 6972 s->gen_insn_end_off[num_insns] = off; 6973 /* Assert that we do not overflow our stored offset. */ 6974 assert(s->gen_insn_end_off[num_insns] == off); 6975 } 6976 num_insns++; 6977 for (i = 0; i < INSN_START_WORDS; ++i) { 6978 s->gen_insn_data[num_insns * INSN_START_WORDS + i] = 6979 tcg_get_insn_start_param(op, i); 6980 } 6981 break; 6982 case INDEX_op_discard: 6983 temp_dead(s, arg_temp(op->args[0])); 6984 break; 6985 case INDEX_op_set_label: 6986 tcg_reg_alloc_bb_end(s, s->reserved_regs); 6987 tcg_out_label(s, arg_label(op->args[0])); 6988 break; 6989 case INDEX_op_call: 6990 assert_carry_dead(s); 6991 tcg_reg_alloc_call(s, op); 6992 break; 6993 case INDEX_op_exit_tb: 6994 tcg_out_exit_tb(s, op->args[0]); 6995 break; 6996 case INDEX_op_goto_tb: 6997 tcg_out_goto_tb(s, op->args[0]); 6998 break; 6999 case INDEX_op_br: 7000 tcg_out_br(s, arg_label(op->args[0])); 7001 break; 7002 case INDEX_op_mb: 7003 tcg_out_mb(s, op->args[0]); 7004 break; 7005 case INDEX_op_dup2_vec: 7006 if (tcg_reg_alloc_dup2(s, op)) { 7007 break; 7008 } 7009 /* fall through */ 7010 default: 7011 do_default: 7012 /* Sanity check that we've not introduced any unhandled opcodes. */ 7013 tcg_debug_assert(tcg_op_supported(opc, TCGOP_TYPE(op), 7014 TCGOP_FLAGS(op))); 7015 /* Note: in order to speed up the code, it would be much 7016 faster to have specialized register allocator functions for 7017 some common argument patterns */ 7018 tcg_reg_alloc_op(s, op); 7019 break; 7020 } 7021 /* Test for (pending) buffer overflow. The assumption is that any 7022 one operation beginning below the high water mark cannot overrun 7023 the buffer completely. Thus we can test for overflow after 7024 generating code without having to check during generation. */ 7025 if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) { 7026 return -1; 7027 } 7028 /* Test for TB overflow, as seen by gen_insn_end_off. */ 7029 if (unlikely(tcg_current_code_size(s) > UINT16_MAX)) { 7030 return -2; 7031 } 7032 } 7033 assert_carry_dead(s); 7034 7035 tcg_debug_assert(num_insns + 1 == s->gen_tb->icount); 7036 s->gen_insn_end_off[num_insns] = tcg_current_code_size(s); 7037 7038 /* Generate TB finalization at the end of block */ 7039 i = tcg_out_ldst_finalize(s); 7040 if (i < 0) { 7041 return i; 7042 } 7043 i = tcg_out_pool_finalize(s); 7044 if (i < 0) { 7045 return i; 7046 } 7047 if (!tcg_resolve_relocs(s)) { 7048 return -2; 7049 } 7050 7051 #ifndef CONFIG_TCG_INTERPRETER 7052 /* flush instruction cache */ 7053 flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(s->code_buf), 7054 (uintptr_t)s->code_buf, 7055 tcg_ptr_byte_diff(s->code_ptr, s->code_buf)); 7056 #endif 7057 7058 return tcg_current_code_size(s); 7059 } 7060 7061 #ifdef ELF_HOST_MACHINE 7062 /* In order to use this feature, the backend needs to do three things: 7063 7064 (1) Define ELF_HOST_MACHINE to indicate both what value to 7065 put into the ELF image and to indicate support for the feature. 7066 7067 (2) Define tcg_register_jit. This should create a buffer containing 7068 the contents of a .debug_frame section that describes the post- 7069 prologue unwind info for the tcg machine. 7070 7071 (3) Call tcg_register_jit_int, with the constructed .debug_frame. 7072 */ 7073 7074 /* Begin GDB interface. THE FOLLOWING MUST MATCH GDB DOCS. */ 7075 typedef enum { 7076 JIT_NOACTION = 0, 7077 JIT_REGISTER_FN, 7078 JIT_UNREGISTER_FN 7079 } jit_actions_t; 7080 7081 struct jit_code_entry { 7082 struct jit_code_entry *next_entry; 7083 struct jit_code_entry *prev_entry; 7084 const void *symfile_addr; 7085 uint64_t symfile_size; 7086 }; 7087 7088 struct jit_descriptor { 7089 uint32_t version; 7090 uint32_t action_flag; 7091 struct jit_code_entry *relevant_entry; 7092 struct jit_code_entry *first_entry; 7093 }; 7094 7095 void __jit_debug_register_code(void) __attribute__((noinline)); 7096 void __jit_debug_register_code(void) 7097 { 7098 asm(""); 7099 } 7100 7101 /* Must statically initialize the version, because GDB may check 7102 the version before we can set it. */ 7103 struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 }; 7104 7105 /* End GDB interface. */ 7106 7107 static int find_string(const char *strtab, const char *str) 7108 { 7109 const char *p = strtab + 1; 7110 7111 while (1) { 7112 if (strcmp(p, str) == 0) { 7113 return p - strtab; 7114 } 7115 p += strlen(p) + 1; 7116 } 7117 } 7118 7119 static void tcg_register_jit_int(const void *buf_ptr, size_t buf_size, 7120 const void *debug_frame, 7121 size_t debug_frame_size) 7122 { 7123 struct __attribute__((packed)) DebugInfo { 7124 uint32_t len; 7125 uint16_t version; 7126 uint32_t abbrev; 7127 uint8_t ptr_size; 7128 uint8_t cu_die; 7129 uint16_t cu_lang; 7130 uintptr_t cu_low_pc; 7131 uintptr_t cu_high_pc; 7132 uint8_t fn_die; 7133 char fn_name[16]; 7134 uintptr_t fn_low_pc; 7135 uintptr_t fn_high_pc; 7136 uint8_t cu_eoc; 7137 }; 7138 7139 struct ElfImage { 7140 ElfW(Ehdr) ehdr; 7141 ElfW(Phdr) phdr; 7142 ElfW(Shdr) shdr[7]; 7143 ElfW(Sym) sym[2]; 7144 struct DebugInfo di; 7145 uint8_t da[24]; 7146 char str[80]; 7147 }; 7148 7149 struct ElfImage *img; 7150 7151 static const struct ElfImage img_template = { 7152 .ehdr = { 7153 .e_ident[EI_MAG0] = ELFMAG0, 7154 .e_ident[EI_MAG1] = ELFMAG1, 7155 .e_ident[EI_MAG2] = ELFMAG2, 7156 .e_ident[EI_MAG3] = ELFMAG3, 7157 .e_ident[EI_CLASS] = ELF_CLASS, 7158 .e_ident[EI_DATA] = ELF_DATA, 7159 .e_ident[EI_VERSION] = EV_CURRENT, 7160 .e_type = ET_EXEC, 7161 .e_machine = ELF_HOST_MACHINE, 7162 .e_version = EV_CURRENT, 7163 .e_phoff = offsetof(struct ElfImage, phdr), 7164 .e_shoff = offsetof(struct ElfImage, shdr), 7165 .e_ehsize = sizeof(ElfW(Shdr)), 7166 .e_phentsize = sizeof(ElfW(Phdr)), 7167 .e_phnum = 1, 7168 .e_shentsize = sizeof(ElfW(Shdr)), 7169 .e_shnum = ARRAY_SIZE(img->shdr), 7170 .e_shstrndx = ARRAY_SIZE(img->shdr) - 1, 7171 #ifdef ELF_HOST_FLAGS 7172 .e_flags = ELF_HOST_FLAGS, 7173 #endif 7174 #ifdef ELF_OSABI 7175 .e_ident[EI_OSABI] = ELF_OSABI, 7176 #endif 7177 }, 7178 .phdr = { 7179 .p_type = PT_LOAD, 7180 .p_flags = PF_X, 7181 }, 7182 .shdr = { 7183 [0] = { .sh_type = SHT_NULL }, 7184 /* Trick: The contents of code_gen_buffer are not present in 7185 this fake ELF file; that got allocated elsewhere. Therefore 7186 we mark .text as SHT_NOBITS (similar to .bss) so that readers 7187 will not look for contents. We can record any address. */ 7188 [1] = { /* .text */ 7189 .sh_type = SHT_NOBITS, 7190 .sh_flags = SHF_EXECINSTR | SHF_ALLOC, 7191 }, 7192 [2] = { /* .debug_info */ 7193 .sh_type = SHT_PROGBITS, 7194 .sh_offset = offsetof(struct ElfImage, di), 7195 .sh_size = sizeof(struct DebugInfo), 7196 }, 7197 [3] = { /* .debug_abbrev */ 7198 .sh_type = SHT_PROGBITS, 7199 .sh_offset = offsetof(struct ElfImage, da), 7200 .sh_size = sizeof(img->da), 7201 }, 7202 [4] = { /* .debug_frame */ 7203 .sh_type = SHT_PROGBITS, 7204 .sh_offset = sizeof(struct ElfImage), 7205 }, 7206 [5] = { /* .symtab */ 7207 .sh_type = SHT_SYMTAB, 7208 .sh_offset = offsetof(struct ElfImage, sym), 7209 .sh_size = sizeof(img->sym), 7210 .sh_info = 1, 7211 .sh_link = ARRAY_SIZE(img->shdr) - 1, 7212 .sh_entsize = sizeof(ElfW(Sym)), 7213 }, 7214 [6] = { /* .strtab */ 7215 .sh_type = SHT_STRTAB, 7216 .sh_offset = offsetof(struct ElfImage, str), 7217 .sh_size = sizeof(img->str), 7218 } 7219 }, 7220 .sym = { 7221 [1] = { /* code_gen_buffer */ 7222 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC), 7223 .st_shndx = 1, 7224 } 7225 }, 7226 .di = { 7227 .len = sizeof(struct DebugInfo) - 4, 7228 .version = 2, 7229 .ptr_size = sizeof(void *), 7230 .cu_die = 1, 7231 .cu_lang = 0x8001, /* DW_LANG_Mips_Assembler */ 7232 .fn_die = 2, 7233 .fn_name = "code_gen_buffer" 7234 }, 7235 .da = { 7236 1, /* abbrev number (the cu) */ 7237 0x11, 1, /* DW_TAG_compile_unit, has children */ 7238 0x13, 0x5, /* DW_AT_language, DW_FORM_data2 */ 7239 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */ 7240 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */ 7241 0, 0, /* end of abbrev */ 7242 2, /* abbrev number (the fn) */ 7243 0x2e, 0, /* DW_TAG_subprogram, no children */ 7244 0x3, 0x8, /* DW_AT_name, DW_FORM_string */ 7245 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */ 7246 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */ 7247 0, 0, /* end of abbrev */ 7248 0 /* no more abbrev */ 7249 }, 7250 .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0" 7251 ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer", 7252 }; 7253 7254 /* We only need a single jit entry; statically allocate it. */ 7255 static struct jit_code_entry one_entry; 7256 7257 uintptr_t buf = (uintptr_t)buf_ptr; 7258 size_t img_size = sizeof(struct ElfImage) + debug_frame_size; 7259 DebugFrameHeader *dfh; 7260 7261 img = g_malloc(img_size); 7262 *img = img_template; 7263 7264 img->phdr.p_vaddr = buf; 7265 img->phdr.p_paddr = buf; 7266 img->phdr.p_memsz = buf_size; 7267 7268 img->shdr[1].sh_name = find_string(img->str, ".text"); 7269 img->shdr[1].sh_addr = buf; 7270 img->shdr[1].sh_size = buf_size; 7271 7272 img->shdr[2].sh_name = find_string(img->str, ".debug_info"); 7273 img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev"); 7274 7275 img->shdr[4].sh_name = find_string(img->str, ".debug_frame"); 7276 img->shdr[4].sh_size = debug_frame_size; 7277 7278 img->shdr[5].sh_name = find_string(img->str, ".symtab"); 7279 img->shdr[6].sh_name = find_string(img->str, ".strtab"); 7280 7281 img->sym[1].st_name = find_string(img->str, "code_gen_buffer"); 7282 img->sym[1].st_value = buf; 7283 img->sym[1].st_size = buf_size; 7284 7285 img->di.cu_low_pc = buf; 7286 img->di.cu_high_pc = buf + buf_size; 7287 img->di.fn_low_pc = buf; 7288 img->di.fn_high_pc = buf + buf_size; 7289 7290 dfh = (DebugFrameHeader *)(img + 1); 7291 memcpy(dfh, debug_frame, debug_frame_size); 7292 dfh->fde.func_start = buf; 7293 dfh->fde.func_len = buf_size; 7294 7295 #ifdef DEBUG_JIT 7296 /* Enable this block to be able to debug the ELF image file creation. 7297 One can use readelf, objdump, or other inspection utilities. */ 7298 { 7299 g_autofree char *jit = g_strdup_printf("%s/qemu.jit", g_get_tmp_dir()); 7300 FILE *f = fopen(jit, "w+b"); 7301 if (f) { 7302 if (fwrite(img, img_size, 1, f) != img_size) { 7303 /* Avoid stupid unused return value warning for fwrite. */ 7304 } 7305 fclose(f); 7306 } 7307 } 7308 #endif 7309 7310 one_entry.symfile_addr = img; 7311 one_entry.symfile_size = img_size; 7312 7313 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN; 7314 __jit_debug_descriptor.relevant_entry = &one_entry; 7315 __jit_debug_descriptor.first_entry = &one_entry; 7316 __jit_debug_register_code(); 7317 } 7318 #else 7319 /* No support for the feature. Provide the entry point expected by exec.c, 7320 and implement the internal function we declared earlier. */ 7321 7322 static void tcg_register_jit_int(const void *buf, size_t size, 7323 const void *debug_frame, 7324 size_t debug_frame_size) 7325 { 7326 } 7327 7328 void tcg_register_jit(const void *buf, size_t buf_size) 7329 { 7330 } 7331 #endif /* ELF_HOST_MACHINE */ 7332 7333 #if !TCG_TARGET_MAYBE_vec 7334 void tcg_expand_vec_op(TCGOpcode o, TCGType t, unsigned e, TCGArg a0, ...) 7335 { 7336 g_assert_not_reached(); 7337 } 7338 #endif 7339