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 /* define it to use liveness analysis (better code) */ 26 #define USE_TCG_OPTIMIZATIONS 27 28 #include "qemu/osdep.h" 29 30 /* Define to jump the ELF file used to communicate with GDB. */ 31 #undef DEBUG_JIT 32 33 #include "qemu/cutils.h" 34 #include "qemu/host-utils.h" 35 #include "qemu/timer.h" 36 37 /* Note: the long term plan is to reduce the dependencies on the QEMU 38 CPU definitions. Currently they are used for qemu_ld/st 39 instructions */ 40 #define NO_CPU_IO_DEFS 41 #include "cpu.h" 42 43 #include "exec/cpu-common.h" 44 #include "exec/exec-all.h" 45 46 #include "tcg-op.h" 47 48 #if UINTPTR_MAX == UINT32_MAX 49 # define ELF_CLASS ELFCLASS32 50 #else 51 # define ELF_CLASS ELFCLASS64 52 #endif 53 #ifdef HOST_WORDS_BIGENDIAN 54 # define ELF_DATA ELFDATA2MSB 55 #else 56 # define ELF_DATA ELFDATA2LSB 57 #endif 58 59 #include "elf.h" 60 #include "exec/log.h" 61 62 /* Forward declarations for functions declared in tcg-target.inc.c and 63 used here. */ 64 static void tcg_target_init(TCGContext *s); 65 static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode); 66 static void tcg_target_qemu_prologue(TCGContext *s); 67 static void patch_reloc(tcg_insn_unit *code_ptr, int type, 68 intptr_t value, intptr_t addend); 69 70 /* The CIE and FDE header definitions will be common to all hosts. */ 71 typedef struct { 72 uint32_t len __attribute__((aligned((sizeof(void *))))); 73 uint32_t id; 74 uint8_t version; 75 char augmentation[1]; 76 uint8_t code_align; 77 uint8_t data_align; 78 uint8_t return_column; 79 } DebugFrameCIE; 80 81 typedef struct QEMU_PACKED { 82 uint32_t len __attribute__((aligned((sizeof(void *))))); 83 uint32_t cie_offset; 84 uintptr_t func_start; 85 uintptr_t func_len; 86 } DebugFrameFDEHeader; 87 88 typedef struct QEMU_PACKED { 89 DebugFrameCIE cie; 90 DebugFrameFDEHeader fde; 91 } DebugFrameHeader; 92 93 static void tcg_register_jit_int(void *buf, size_t size, 94 const void *debug_frame, 95 size_t debug_frame_size) 96 __attribute__((unused)); 97 98 /* Forward declarations for functions declared and used in tcg-target.inc.c. */ 99 static const char *target_parse_constraint(TCGArgConstraint *ct, 100 const char *ct_str, TCGType type); 101 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1, 102 intptr_t arg2); 103 static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); 104 static void tcg_out_movi(TCGContext *s, TCGType type, 105 TCGReg ret, tcg_target_long arg); 106 static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, 107 const int *const_args); 108 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, 109 intptr_t arg2); 110 static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val, 111 TCGReg base, intptr_t ofs); 112 static void tcg_out_call(TCGContext *s, tcg_insn_unit *target); 113 static int tcg_target_const_match(tcg_target_long val, TCGType type, 114 const TCGArgConstraint *arg_ct); 115 #ifdef TCG_TARGET_NEED_LDST_LABELS 116 static bool tcg_out_ldst_finalize(TCGContext *s); 117 #endif 118 119 #define TCG_HIGHWATER 1024 120 121 static TCGRegSet tcg_target_available_regs[2]; 122 static TCGRegSet tcg_target_call_clobber_regs; 123 124 #if TCG_TARGET_INSN_UNIT_SIZE == 1 125 static __attribute__((unused)) inline void tcg_out8(TCGContext *s, uint8_t v) 126 { 127 *s->code_ptr++ = v; 128 } 129 130 static __attribute__((unused)) inline void tcg_patch8(tcg_insn_unit *p, 131 uint8_t v) 132 { 133 *p = v; 134 } 135 #endif 136 137 #if TCG_TARGET_INSN_UNIT_SIZE <= 2 138 static __attribute__((unused)) inline void tcg_out16(TCGContext *s, uint16_t v) 139 { 140 if (TCG_TARGET_INSN_UNIT_SIZE == 2) { 141 *s->code_ptr++ = v; 142 } else { 143 tcg_insn_unit *p = s->code_ptr; 144 memcpy(p, &v, sizeof(v)); 145 s->code_ptr = p + (2 / TCG_TARGET_INSN_UNIT_SIZE); 146 } 147 } 148 149 static __attribute__((unused)) inline void tcg_patch16(tcg_insn_unit *p, 150 uint16_t v) 151 { 152 if (TCG_TARGET_INSN_UNIT_SIZE == 2) { 153 *p = v; 154 } else { 155 memcpy(p, &v, sizeof(v)); 156 } 157 } 158 #endif 159 160 #if TCG_TARGET_INSN_UNIT_SIZE <= 4 161 static __attribute__((unused)) inline void tcg_out32(TCGContext *s, uint32_t v) 162 { 163 if (TCG_TARGET_INSN_UNIT_SIZE == 4) { 164 *s->code_ptr++ = v; 165 } else { 166 tcg_insn_unit *p = s->code_ptr; 167 memcpy(p, &v, sizeof(v)); 168 s->code_ptr = p + (4 / TCG_TARGET_INSN_UNIT_SIZE); 169 } 170 } 171 172 static __attribute__((unused)) inline void tcg_patch32(tcg_insn_unit *p, 173 uint32_t v) 174 { 175 if (TCG_TARGET_INSN_UNIT_SIZE == 4) { 176 *p = v; 177 } else { 178 memcpy(p, &v, sizeof(v)); 179 } 180 } 181 #endif 182 183 #if TCG_TARGET_INSN_UNIT_SIZE <= 8 184 static __attribute__((unused)) inline void tcg_out64(TCGContext *s, uint64_t v) 185 { 186 if (TCG_TARGET_INSN_UNIT_SIZE == 8) { 187 *s->code_ptr++ = v; 188 } else { 189 tcg_insn_unit *p = s->code_ptr; 190 memcpy(p, &v, sizeof(v)); 191 s->code_ptr = p + (8 / TCG_TARGET_INSN_UNIT_SIZE); 192 } 193 } 194 195 static __attribute__((unused)) inline void tcg_patch64(tcg_insn_unit *p, 196 uint64_t v) 197 { 198 if (TCG_TARGET_INSN_UNIT_SIZE == 8) { 199 *p = v; 200 } else { 201 memcpy(p, &v, sizeof(v)); 202 } 203 } 204 #endif 205 206 /* label relocation processing */ 207 208 static void tcg_out_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type, 209 TCGLabel *l, intptr_t addend) 210 { 211 TCGRelocation *r; 212 213 if (l->has_value) { 214 /* FIXME: This may break relocations on RISC targets that 215 modify instruction fields in place. The caller may not have 216 written the initial value. */ 217 patch_reloc(code_ptr, type, l->u.value, addend); 218 } else { 219 /* add a new relocation entry */ 220 r = tcg_malloc(sizeof(TCGRelocation)); 221 r->type = type; 222 r->ptr = code_ptr; 223 r->addend = addend; 224 r->next = l->u.first_reloc; 225 l->u.first_reloc = r; 226 } 227 } 228 229 static void tcg_out_label(TCGContext *s, TCGLabel *l, tcg_insn_unit *ptr) 230 { 231 intptr_t value = (intptr_t)ptr; 232 TCGRelocation *r; 233 234 tcg_debug_assert(!l->has_value); 235 236 for (r = l->u.first_reloc; r != NULL; r = r->next) { 237 patch_reloc(r->ptr, r->type, value, r->addend); 238 } 239 240 l->has_value = 1; 241 l->u.value_ptr = ptr; 242 } 243 244 TCGLabel *gen_new_label(void) 245 { 246 TCGContext *s = &tcg_ctx; 247 TCGLabel *l = tcg_malloc(sizeof(TCGLabel)); 248 249 *l = (TCGLabel){ 250 .id = s->nb_labels++ 251 }; 252 253 return l; 254 } 255 256 #include "tcg-target.inc.c" 257 258 /* pool based memory allocation */ 259 void *tcg_malloc_internal(TCGContext *s, int size) 260 { 261 TCGPool *p; 262 int pool_size; 263 264 if (size > TCG_POOL_CHUNK_SIZE) { 265 /* big malloc: insert a new pool (XXX: could optimize) */ 266 p = g_malloc(sizeof(TCGPool) + size); 267 p->size = size; 268 p->next = s->pool_first_large; 269 s->pool_first_large = p; 270 return p->data; 271 } else { 272 p = s->pool_current; 273 if (!p) { 274 p = s->pool_first; 275 if (!p) 276 goto new_pool; 277 } else { 278 if (!p->next) { 279 new_pool: 280 pool_size = TCG_POOL_CHUNK_SIZE; 281 p = g_malloc(sizeof(TCGPool) + pool_size); 282 p->size = pool_size; 283 p->next = NULL; 284 if (s->pool_current) 285 s->pool_current->next = p; 286 else 287 s->pool_first = p; 288 } else { 289 p = p->next; 290 } 291 } 292 } 293 s->pool_current = p; 294 s->pool_cur = p->data + size; 295 s->pool_end = p->data + p->size; 296 return p->data; 297 } 298 299 void tcg_pool_reset(TCGContext *s) 300 { 301 TCGPool *p, *t; 302 for (p = s->pool_first_large; p; p = t) { 303 t = p->next; 304 g_free(p); 305 } 306 s->pool_first_large = NULL; 307 s->pool_cur = s->pool_end = NULL; 308 s->pool_current = NULL; 309 } 310 311 typedef struct TCGHelperInfo { 312 void *func; 313 const char *name; 314 unsigned flags; 315 unsigned sizemask; 316 } TCGHelperInfo; 317 318 #include "exec/helper-proto.h" 319 320 static const TCGHelperInfo all_helpers[] = { 321 #include "exec/helper-tcg.h" 322 }; 323 static GHashTable *helper_table; 324 325 static int indirect_reg_alloc_order[ARRAY_SIZE(tcg_target_reg_alloc_order)]; 326 static void process_op_defs(TCGContext *s); 327 328 void tcg_context_init(TCGContext *s) 329 { 330 int op, total_args, n, i; 331 TCGOpDef *def; 332 TCGArgConstraint *args_ct; 333 int *sorted_args; 334 335 memset(s, 0, sizeof(*s)); 336 s->nb_globals = 0; 337 338 /* Count total number of arguments and allocate the corresponding 339 space */ 340 total_args = 0; 341 for(op = 0; op < NB_OPS; op++) { 342 def = &tcg_op_defs[op]; 343 n = def->nb_iargs + def->nb_oargs; 344 total_args += n; 345 } 346 347 args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args); 348 sorted_args = g_malloc(sizeof(int) * total_args); 349 350 for(op = 0; op < NB_OPS; op++) { 351 def = &tcg_op_defs[op]; 352 def->args_ct = args_ct; 353 def->sorted_args = sorted_args; 354 n = def->nb_iargs + def->nb_oargs; 355 sorted_args += n; 356 args_ct += n; 357 } 358 359 /* Register helpers. */ 360 /* Use g_direct_hash/equal for direct pointer comparisons on func. */ 361 helper_table = g_hash_table_new(NULL, NULL); 362 363 for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) { 364 g_hash_table_insert(helper_table, (gpointer)all_helpers[i].func, 365 (gpointer)&all_helpers[i]); 366 } 367 368 tcg_target_init(s); 369 process_op_defs(s); 370 371 /* Reverse the order of the saved registers, assuming they're all at 372 the start of tcg_target_reg_alloc_order. */ 373 for (n = 0; n < ARRAY_SIZE(tcg_target_reg_alloc_order); ++n) { 374 int r = tcg_target_reg_alloc_order[n]; 375 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, r)) { 376 break; 377 } 378 } 379 for (i = 0; i < n; ++i) { 380 indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[n - 1 - i]; 381 } 382 for (; i < ARRAY_SIZE(tcg_target_reg_alloc_order); ++i) { 383 indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[i]; 384 } 385 } 386 387 /* 388 * Allocate TBs right before their corresponding translated code, making 389 * sure that TBs and code are on different cache lines. 390 */ 391 TranslationBlock *tcg_tb_alloc(TCGContext *s) 392 { 393 uintptr_t align = qemu_icache_linesize; 394 TranslationBlock *tb; 395 void *next; 396 397 tb = (void *)ROUND_UP((uintptr_t)s->code_gen_ptr, align); 398 next = (void *)ROUND_UP((uintptr_t)(tb + 1), align); 399 400 if (unlikely(next > s->code_gen_highwater)) { 401 return NULL; 402 } 403 s->code_gen_ptr = next; 404 s->data_gen_ptr = NULL; 405 return tb; 406 } 407 408 void tcg_prologue_init(TCGContext *s) 409 { 410 size_t prologue_size, total_size; 411 void *buf0, *buf1; 412 413 /* Put the prologue at the beginning of code_gen_buffer. */ 414 buf0 = s->code_gen_buffer; 415 s->code_ptr = buf0; 416 s->code_buf = buf0; 417 s->code_gen_prologue = buf0; 418 419 /* Generate the prologue. */ 420 tcg_target_qemu_prologue(s); 421 buf1 = s->code_ptr; 422 flush_icache_range((uintptr_t)buf0, (uintptr_t)buf1); 423 424 /* Deduct the prologue from the buffer. */ 425 prologue_size = tcg_current_code_size(s); 426 s->code_gen_ptr = buf1; 427 s->code_gen_buffer = buf1; 428 s->code_buf = buf1; 429 total_size = s->code_gen_buffer_size - prologue_size; 430 s->code_gen_buffer_size = total_size; 431 432 /* Compute a high-water mark, at which we voluntarily flush the buffer 433 and start over. The size here is arbitrary, significantly larger 434 than we expect the code generation for any one opcode to require. */ 435 s->code_gen_highwater = s->code_gen_buffer + (total_size - TCG_HIGHWATER); 436 437 tcg_register_jit(s->code_gen_buffer, total_size); 438 439 #ifdef DEBUG_DISAS 440 if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) { 441 qemu_log_lock(); 442 qemu_log("PROLOGUE: [size=%zu]\n", prologue_size); 443 log_disas(buf0, prologue_size); 444 qemu_log("\n"); 445 qemu_log_flush(); 446 qemu_log_unlock(); 447 } 448 #endif 449 450 /* Assert that goto_ptr is implemented completely. */ 451 if (TCG_TARGET_HAS_goto_ptr) { 452 tcg_debug_assert(s->code_gen_epilogue != NULL); 453 } 454 } 455 456 void tcg_func_start(TCGContext *s) 457 { 458 tcg_pool_reset(s); 459 s->nb_temps = s->nb_globals; 460 461 /* No temps have been previously allocated for size or locality. */ 462 memset(s->free_temps, 0, sizeof(s->free_temps)); 463 464 s->nb_labels = 0; 465 s->current_frame_offset = s->frame_start; 466 467 #ifdef CONFIG_DEBUG_TCG 468 s->goto_tb_issue_mask = 0; 469 #endif 470 471 s->gen_op_buf[0].next = 1; 472 s->gen_op_buf[0].prev = 0; 473 s->gen_next_op_idx = 1; 474 } 475 476 static inline TCGTemp *tcg_temp_alloc(TCGContext *s) 477 { 478 int n = s->nb_temps++; 479 tcg_debug_assert(n < TCG_MAX_TEMPS); 480 return memset(&s->temps[n], 0, sizeof(TCGTemp)); 481 } 482 483 static inline TCGTemp *tcg_global_alloc(TCGContext *s) 484 { 485 TCGTemp *ts; 486 487 tcg_debug_assert(s->nb_globals == s->nb_temps); 488 s->nb_globals++; 489 ts = tcg_temp_alloc(s); 490 ts->temp_global = 1; 491 492 return ts; 493 } 494 495 static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type, 496 TCGReg reg, const char *name) 497 { 498 TCGTemp *ts; 499 500 if (TCG_TARGET_REG_BITS == 32 && type != TCG_TYPE_I32) { 501 tcg_abort(); 502 } 503 504 ts = tcg_global_alloc(s); 505 ts->base_type = type; 506 ts->type = type; 507 ts->fixed_reg = 1; 508 ts->reg = reg; 509 ts->name = name; 510 tcg_regset_set_reg(s->reserved_regs, reg); 511 512 return ts; 513 } 514 515 void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size) 516 { 517 s->frame_start = start; 518 s->frame_end = start + size; 519 s->frame_temp 520 = tcg_global_reg_new_internal(s, TCG_TYPE_PTR, reg, "_frame"); 521 } 522 523 TCGv_i32 tcg_global_reg_new_i32(TCGReg reg, const char *name) 524 { 525 TCGContext *s = &tcg_ctx; 526 TCGTemp *t; 527 528 if (tcg_regset_test_reg(s->reserved_regs, reg)) { 529 tcg_abort(); 530 } 531 t = tcg_global_reg_new_internal(s, TCG_TYPE_I32, reg, name); 532 return temp_tcgv_i32(t); 533 } 534 535 TCGv_i64 tcg_global_reg_new_i64(TCGReg reg, const char *name) 536 { 537 TCGContext *s = &tcg_ctx; 538 TCGTemp *t; 539 540 if (tcg_regset_test_reg(s->reserved_regs, reg)) { 541 tcg_abort(); 542 } 543 t = tcg_global_reg_new_internal(s, TCG_TYPE_I64, reg, name); 544 return temp_tcgv_i64(t); 545 } 546 547 TCGTemp *tcg_global_mem_new_internal(TCGType type, TCGv_ptr base, 548 intptr_t offset, const char *name) 549 { 550 TCGContext *s = &tcg_ctx; 551 TCGTemp *base_ts = tcgv_ptr_temp(base); 552 TCGTemp *ts = tcg_global_alloc(s); 553 int indirect_reg = 0, bigendian = 0; 554 #ifdef HOST_WORDS_BIGENDIAN 555 bigendian = 1; 556 #endif 557 558 if (!base_ts->fixed_reg) { 559 /* We do not support double-indirect registers. */ 560 tcg_debug_assert(!base_ts->indirect_reg); 561 base_ts->indirect_base = 1; 562 s->nb_indirects += (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64 563 ? 2 : 1); 564 indirect_reg = 1; 565 } 566 567 if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) { 568 TCGTemp *ts2 = tcg_global_alloc(s); 569 char buf[64]; 570 571 ts->base_type = TCG_TYPE_I64; 572 ts->type = TCG_TYPE_I32; 573 ts->indirect_reg = indirect_reg; 574 ts->mem_allocated = 1; 575 ts->mem_base = base_ts; 576 ts->mem_offset = offset + bigendian * 4; 577 pstrcpy(buf, sizeof(buf), name); 578 pstrcat(buf, sizeof(buf), "_0"); 579 ts->name = strdup(buf); 580 581 tcg_debug_assert(ts2 == ts + 1); 582 ts2->base_type = TCG_TYPE_I64; 583 ts2->type = TCG_TYPE_I32; 584 ts2->indirect_reg = indirect_reg; 585 ts2->mem_allocated = 1; 586 ts2->mem_base = base_ts; 587 ts2->mem_offset = offset + (1 - bigendian) * 4; 588 pstrcpy(buf, sizeof(buf), name); 589 pstrcat(buf, sizeof(buf), "_1"); 590 ts2->name = strdup(buf); 591 } else { 592 ts->base_type = type; 593 ts->type = type; 594 ts->indirect_reg = indirect_reg; 595 ts->mem_allocated = 1; 596 ts->mem_base = base_ts; 597 ts->mem_offset = offset; 598 ts->name = name; 599 } 600 return ts; 601 } 602 603 static TCGTemp *tcg_temp_new_internal(TCGType type, int temp_local) 604 { 605 TCGContext *s = &tcg_ctx; 606 TCGTemp *ts; 607 int idx, k; 608 609 k = type + (temp_local ? TCG_TYPE_COUNT : 0); 610 idx = find_first_bit(s->free_temps[k].l, TCG_MAX_TEMPS); 611 if (idx < TCG_MAX_TEMPS) { 612 /* There is already an available temp with the right type. */ 613 clear_bit(idx, s->free_temps[k].l); 614 615 ts = &s->temps[idx]; 616 ts->temp_allocated = 1; 617 tcg_debug_assert(ts->base_type == type); 618 tcg_debug_assert(ts->temp_local == temp_local); 619 } else { 620 ts = tcg_temp_alloc(s); 621 if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) { 622 TCGTemp *ts2 = tcg_temp_alloc(s); 623 624 ts->base_type = type; 625 ts->type = TCG_TYPE_I32; 626 ts->temp_allocated = 1; 627 ts->temp_local = temp_local; 628 629 tcg_debug_assert(ts2 == ts + 1); 630 ts2->base_type = TCG_TYPE_I64; 631 ts2->type = TCG_TYPE_I32; 632 ts2->temp_allocated = 1; 633 ts2->temp_local = temp_local; 634 } else { 635 ts->base_type = type; 636 ts->type = type; 637 ts->temp_allocated = 1; 638 ts->temp_local = temp_local; 639 } 640 } 641 642 #if defined(CONFIG_DEBUG_TCG) 643 s->temps_in_use++; 644 #endif 645 return ts; 646 } 647 648 TCGv_i32 tcg_temp_new_internal_i32(int temp_local) 649 { 650 TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, temp_local); 651 return temp_tcgv_i32(t); 652 } 653 654 TCGv_i64 tcg_temp_new_internal_i64(int temp_local) 655 { 656 TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, temp_local); 657 return temp_tcgv_i64(t); 658 } 659 660 static void tcg_temp_free_internal(TCGTemp *ts) 661 { 662 TCGContext *s = &tcg_ctx; 663 int k, idx; 664 665 #if defined(CONFIG_DEBUG_TCG) 666 s->temps_in_use--; 667 if (s->temps_in_use < 0) { 668 fprintf(stderr, "More temporaries freed than allocated!\n"); 669 } 670 #endif 671 672 tcg_debug_assert(ts->temp_global == 0); 673 tcg_debug_assert(ts->temp_allocated != 0); 674 ts->temp_allocated = 0; 675 676 idx = temp_idx(ts); 677 k = ts->base_type + (ts->temp_local ? TCG_TYPE_COUNT : 0); 678 set_bit(idx, s->free_temps[k].l); 679 } 680 681 void tcg_temp_free_i32(TCGv_i32 arg) 682 { 683 tcg_temp_free_internal(tcgv_i32_temp(arg)); 684 } 685 686 void tcg_temp_free_i64(TCGv_i64 arg) 687 { 688 tcg_temp_free_internal(tcgv_i64_temp(arg)); 689 } 690 691 TCGv_i32 tcg_const_i32(int32_t val) 692 { 693 TCGv_i32 t0; 694 t0 = tcg_temp_new_i32(); 695 tcg_gen_movi_i32(t0, val); 696 return t0; 697 } 698 699 TCGv_i64 tcg_const_i64(int64_t val) 700 { 701 TCGv_i64 t0; 702 t0 = tcg_temp_new_i64(); 703 tcg_gen_movi_i64(t0, val); 704 return t0; 705 } 706 707 TCGv_i32 tcg_const_local_i32(int32_t val) 708 { 709 TCGv_i32 t0; 710 t0 = tcg_temp_local_new_i32(); 711 tcg_gen_movi_i32(t0, val); 712 return t0; 713 } 714 715 TCGv_i64 tcg_const_local_i64(int64_t val) 716 { 717 TCGv_i64 t0; 718 t0 = tcg_temp_local_new_i64(); 719 tcg_gen_movi_i64(t0, val); 720 return t0; 721 } 722 723 #if defined(CONFIG_DEBUG_TCG) 724 void tcg_clear_temp_count(void) 725 { 726 TCGContext *s = &tcg_ctx; 727 s->temps_in_use = 0; 728 } 729 730 int tcg_check_temp_count(void) 731 { 732 TCGContext *s = &tcg_ctx; 733 if (s->temps_in_use) { 734 /* Clear the count so that we don't give another 735 * warning immediately next time around. 736 */ 737 s->temps_in_use = 0; 738 return 1; 739 } 740 return 0; 741 } 742 #endif 743 744 /* Return true if OP may appear in the opcode stream. 745 Test the runtime variable that controls each opcode. */ 746 bool tcg_op_supported(TCGOpcode op) 747 { 748 switch (op) { 749 case INDEX_op_discard: 750 case INDEX_op_set_label: 751 case INDEX_op_call: 752 case INDEX_op_br: 753 case INDEX_op_mb: 754 case INDEX_op_insn_start: 755 case INDEX_op_exit_tb: 756 case INDEX_op_goto_tb: 757 case INDEX_op_qemu_ld_i32: 758 case INDEX_op_qemu_st_i32: 759 case INDEX_op_qemu_ld_i64: 760 case INDEX_op_qemu_st_i64: 761 return true; 762 763 case INDEX_op_goto_ptr: 764 return TCG_TARGET_HAS_goto_ptr; 765 766 case INDEX_op_mov_i32: 767 case INDEX_op_movi_i32: 768 case INDEX_op_setcond_i32: 769 case INDEX_op_brcond_i32: 770 case INDEX_op_ld8u_i32: 771 case INDEX_op_ld8s_i32: 772 case INDEX_op_ld16u_i32: 773 case INDEX_op_ld16s_i32: 774 case INDEX_op_ld_i32: 775 case INDEX_op_st8_i32: 776 case INDEX_op_st16_i32: 777 case INDEX_op_st_i32: 778 case INDEX_op_add_i32: 779 case INDEX_op_sub_i32: 780 case INDEX_op_mul_i32: 781 case INDEX_op_and_i32: 782 case INDEX_op_or_i32: 783 case INDEX_op_xor_i32: 784 case INDEX_op_shl_i32: 785 case INDEX_op_shr_i32: 786 case INDEX_op_sar_i32: 787 return true; 788 789 case INDEX_op_movcond_i32: 790 return TCG_TARGET_HAS_movcond_i32; 791 case INDEX_op_div_i32: 792 case INDEX_op_divu_i32: 793 return TCG_TARGET_HAS_div_i32; 794 case INDEX_op_rem_i32: 795 case INDEX_op_remu_i32: 796 return TCG_TARGET_HAS_rem_i32; 797 case INDEX_op_div2_i32: 798 case INDEX_op_divu2_i32: 799 return TCG_TARGET_HAS_div2_i32; 800 case INDEX_op_rotl_i32: 801 case INDEX_op_rotr_i32: 802 return TCG_TARGET_HAS_rot_i32; 803 case INDEX_op_deposit_i32: 804 return TCG_TARGET_HAS_deposit_i32; 805 case INDEX_op_extract_i32: 806 return TCG_TARGET_HAS_extract_i32; 807 case INDEX_op_sextract_i32: 808 return TCG_TARGET_HAS_sextract_i32; 809 case INDEX_op_add2_i32: 810 return TCG_TARGET_HAS_add2_i32; 811 case INDEX_op_sub2_i32: 812 return TCG_TARGET_HAS_sub2_i32; 813 case INDEX_op_mulu2_i32: 814 return TCG_TARGET_HAS_mulu2_i32; 815 case INDEX_op_muls2_i32: 816 return TCG_TARGET_HAS_muls2_i32; 817 case INDEX_op_muluh_i32: 818 return TCG_TARGET_HAS_muluh_i32; 819 case INDEX_op_mulsh_i32: 820 return TCG_TARGET_HAS_mulsh_i32; 821 case INDEX_op_ext8s_i32: 822 return TCG_TARGET_HAS_ext8s_i32; 823 case INDEX_op_ext16s_i32: 824 return TCG_TARGET_HAS_ext16s_i32; 825 case INDEX_op_ext8u_i32: 826 return TCG_TARGET_HAS_ext8u_i32; 827 case INDEX_op_ext16u_i32: 828 return TCG_TARGET_HAS_ext16u_i32; 829 case INDEX_op_bswap16_i32: 830 return TCG_TARGET_HAS_bswap16_i32; 831 case INDEX_op_bswap32_i32: 832 return TCG_TARGET_HAS_bswap32_i32; 833 case INDEX_op_not_i32: 834 return TCG_TARGET_HAS_not_i32; 835 case INDEX_op_neg_i32: 836 return TCG_TARGET_HAS_neg_i32; 837 case INDEX_op_andc_i32: 838 return TCG_TARGET_HAS_andc_i32; 839 case INDEX_op_orc_i32: 840 return TCG_TARGET_HAS_orc_i32; 841 case INDEX_op_eqv_i32: 842 return TCG_TARGET_HAS_eqv_i32; 843 case INDEX_op_nand_i32: 844 return TCG_TARGET_HAS_nand_i32; 845 case INDEX_op_nor_i32: 846 return TCG_TARGET_HAS_nor_i32; 847 case INDEX_op_clz_i32: 848 return TCG_TARGET_HAS_clz_i32; 849 case INDEX_op_ctz_i32: 850 return TCG_TARGET_HAS_ctz_i32; 851 case INDEX_op_ctpop_i32: 852 return TCG_TARGET_HAS_ctpop_i32; 853 854 case INDEX_op_brcond2_i32: 855 case INDEX_op_setcond2_i32: 856 return TCG_TARGET_REG_BITS == 32; 857 858 case INDEX_op_mov_i64: 859 case INDEX_op_movi_i64: 860 case INDEX_op_setcond_i64: 861 case INDEX_op_brcond_i64: 862 case INDEX_op_ld8u_i64: 863 case INDEX_op_ld8s_i64: 864 case INDEX_op_ld16u_i64: 865 case INDEX_op_ld16s_i64: 866 case INDEX_op_ld32u_i64: 867 case INDEX_op_ld32s_i64: 868 case INDEX_op_ld_i64: 869 case INDEX_op_st8_i64: 870 case INDEX_op_st16_i64: 871 case INDEX_op_st32_i64: 872 case INDEX_op_st_i64: 873 case INDEX_op_add_i64: 874 case INDEX_op_sub_i64: 875 case INDEX_op_mul_i64: 876 case INDEX_op_and_i64: 877 case INDEX_op_or_i64: 878 case INDEX_op_xor_i64: 879 case INDEX_op_shl_i64: 880 case INDEX_op_shr_i64: 881 case INDEX_op_sar_i64: 882 case INDEX_op_ext_i32_i64: 883 case INDEX_op_extu_i32_i64: 884 return TCG_TARGET_REG_BITS == 64; 885 886 case INDEX_op_movcond_i64: 887 return TCG_TARGET_HAS_movcond_i64; 888 case INDEX_op_div_i64: 889 case INDEX_op_divu_i64: 890 return TCG_TARGET_HAS_div_i64; 891 case INDEX_op_rem_i64: 892 case INDEX_op_remu_i64: 893 return TCG_TARGET_HAS_rem_i64; 894 case INDEX_op_div2_i64: 895 case INDEX_op_divu2_i64: 896 return TCG_TARGET_HAS_div2_i64; 897 case INDEX_op_rotl_i64: 898 case INDEX_op_rotr_i64: 899 return TCG_TARGET_HAS_rot_i64; 900 case INDEX_op_deposit_i64: 901 return TCG_TARGET_HAS_deposit_i64; 902 case INDEX_op_extract_i64: 903 return TCG_TARGET_HAS_extract_i64; 904 case INDEX_op_sextract_i64: 905 return TCG_TARGET_HAS_sextract_i64; 906 case INDEX_op_extrl_i64_i32: 907 return TCG_TARGET_HAS_extrl_i64_i32; 908 case INDEX_op_extrh_i64_i32: 909 return TCG_TARGET_HAS_extrh_i64_i32; 910 case INDEX_op_ext8s_i64: 911 return TCG_TARGET_HAS_ext8s_i64; 912 case INDEX_op_ext16s_i64: 913 return TCG_TARGET_HAS_ext16s_i64; 914 case INDEX_op_ext32s_i64: 915 return TCG_TARGET_HAS_ext32s_i64; 916 case INDEX_op_ext8u_i64: 917 return TCG_TARGET_HAS_ext8u_i64; 918 case INDEX_op_ext16u_i64: 919 return TCG_TARGET_HAS_ext16u_i64; 920 case INDEX_op_ext32u_i64: 921 return TCG_TARGET_HAS_ext32u_i64; 922 case INDEX_op_bswap16_i64: 923 return TCG_TARGET_HAS_bswap16_i64; 924 case INDEX_op_bswap32_i64: 925 return TCG_TARGET_HAS_bswap32_i64; 926 case INDEX_op_bswap64_i64: 927 return TCG_TARGET_HAS_bswap64_i64; 928 case INDEX_op_not_i64: 929 return TCG_TARGET_HAS_not_i64; 930 case INDEX_op_neg_i64: 931 return TCG_TARGET_HAS_neg_i64; 932 case INDEX_op_andc_i64: 933 return TCG_TARGET_HAS_andc_i64; 934 case INDEX_op_orc_i64: 935 return TCG_TARGET_HAS_orc_i64; 936 case INDEX_op_eqv_i64: 937 return TCG_TARGET_HAS_eqv_i64; 938 case INDEX_op_nand_i64: 939 return TCG_TARGET_HAS_nand_i64; 940 case INDEX_op_nor_i64: 941 return TCG_TARGET_HAS_nor_i64; 942 case INDEX_op_clz_i64: 943 return TCG_TARGET_HAS_clz_i64; 944 case INDEX_op_ctz_i64: 945 return TCG_TARGET_HAS_ctz_i64; 946 case INDEX_op_ctpop_i64: 947 return TCG_TARGET_HAS_ctpop_i64; 948 case INDEX_op_add2_i64: 949 return TCG_TARGET_HAS_add2_i64; 950 case INDEX_op_sub2_i64: 951 return TCG_TARGET_HAS_sub2_i64; 952 case INDEX_op_mulu2_i64: 953 return TCG_TARGET_HAS_mulu2_i64; 954 case INDEX_op_muls2_i64: 955 return TCG_TARGET_HAS_muls2_i64; 956 case INDEX_op_muluh_i64: 957 return TCG_TARGET_HAS_muluh_i64; 958 case INDEX_op_mulsh_i64: 959 return TCG_TARGET_HAS_mulsh_i64; 960 961 case NB_OPS: 962 break; 963 } 964 g_assert_not_reached(); 965 } 966 967 /* Note: we convert the 64 bit args to 32 bit and do some alignment 968 and endian swap. Maybe it would be better to do the alignment 969 and endian swap in tcg_reg_alloc_call(). */ 970 void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args) 971 { 972 TCGContext *s = &tcg_ctx; 973 int i, real_args, nb_rets, pi; 974 unsigned sizemask, flags; 975 TCGHelperInfo *info; 976 TCGOp *op; 977 978 info = g_hash_table_lookup(helper_table, (gpointer)func); 979 flags = info->flags; 980 sizemask = info->sizemask; 981 982 #if defined(__sparc__) && !defined(__arch64__) \ 983 && !defined(CONFIG_TCG_INTERPRETER) 984 /* We have 64-bit values in one register, but need to pass as two 985 separate parameters. Split them. */ 986 int orig_sizemask = sizemask; 987 int orig_nargs = nargs; 988 TCGv_i64 retl, reth; 989 TCGTemp *split_args[MAX_OPC_PARAM]; 990 991 TCGV_UNUSED_I64(retl); 992 TCGV_UNUSED_I64(reth); 993 if (sizemask != 0) { 994 for (i = real_args = 0; i < nargs; ++i) { 995 int is_64bit = sizemask & (1 << (i+1)*2); 996 if (is_64bit) { 997 TCGv_i64 orig = temp_tcgv_i64(args[i]); 998 TCGv_i32 h = tcg_temp_new_i32(); 999 TCGv_i32 l = tcg_temp_new_i32(); 1000 tcg_gen_extr_i64_i32(l, h, orig); 1001 split_args[real_args++] = tcgv_i32_temp(h); 1002 split_args[real_args++] = tcgv_i32_temp(l); 1003 } else { 1004 split_args[real_args++] = args[i]; 1005 } 1006 } 1007 nargs = real_args; 1008 args = split_args; 1009 sizemask = 0; 1010 } 1011 #elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64 1012 for (i = 0; i < nargs; ++i) { 1013 int is_64bit = sizemask & (1 << (i+1)*2); 1014 int is_signed = sizemask & (2 << (i+1)*2); 1015 if (!is_64bit) { 1016 TCGv_i64 temp = tcg_temp_new_i64(); 1017 TCGv_i64 orig = temp_tcgv_i64(args[i]); 1018 if (is_signed) { 1019 tcg_gen_ext32s_i64(temp, orig); 1020 } else { 1021 tcg_gen_ext32u_i64(temp, orig); 1022 } 1023 args[i] = tcgv_i64_temp(temp); 1024 } 1025 } 1026 #endif /* TCG_TARGET_EXTEND_ARGS */ 1027 1028 i = s->gen_next_op_idx; 1029 tcg_debug_assert(i < OPC_BUF_SIZE); 1030 s->gen_op_buf[0].prev = i; 1031 s->gen_next_op_idx = i + 1; 1032 op = &s->gen_op_buf[i]; 1033 1034 /* Set links for sequential allocation during translation. */ 1035 memset(op, 0, offsetof(TCGOp, args)); 1036 op->opc = INDEX_op_call; 1037 op->prev = i - 1; 1038 op->next = i + 1; 1039 1040 pi = 0; 1041 if (ret != NULL) { 1042 #if defined(__sparc__) && !defined(__arch64__) \ 1043 && !defined(CONFIG_TCG_INTERPRETER) 1044 if (orig_sizemask & 1) { 1045 /* The 32-bit ABI is going to return the 64-bit value in 1046 the %o0/%o1 register pair. Prepare for this by using 1047 two return temporaries, and reassemble below. */ 1048 retl = tcg_temp_new_i64(); 1049 reth = tcg_temp_new_i64(); 1050 op->args[pi++] = tcgv_i64_arg(reth); 1051 op->args[pi++] = tcgv_i64_arg(retl); 1052 nb_rets = 2; 1053 } else { 1054 op->args[pi++] = temp_arg(ret); 1055 nb_rets = 1; 1056 } 1057 #else 1058 if (TCG_TARGET_REG_BITS < 64 && (sizemask & 1)) { 1059 #ifdef HOST_WORDS_BIGENDIAN 1060 op->args[pi++] = temp_arg(ret + 1); 1061 op->args[pi++] = temp_arg(ret); 1062 #else 1063 op->args[pi++] = temp_arg(ret); 1064 op->args[pi++] = temp_arg(ret + 1); 1065 #endif 1066 nb_rets = 2; 1067 } else { 1068 op->args[pi++] = temp_arg(ret); 1069 nb_rets = 1; 1070 } 1071 #endif 1072 } else { 1073 nb_rets = 0; 1074 } 1075 op->callo = nb_rets; 1076 1077 real_args = 0; 1078 for (i = 0; i < nargs; i++) { 1079 int is_64bit = sizemask & (1 << (i+1)*2); 1080 if (TCG_TARGET_REG_BITS < 64 && is_64bit) { 1081 #ifdef TCG_TARGET_CALL_ALIGN_ARGS 1082 /* some targets want aligned 64 bit args */ 1083 if (real_args & 1) { 1084 op->args[pi++] = TCG_CALL_DUMMY_ARG; 1085 real_args++; 1086 } 1087 #endif 1088 /* If stack grows up, then we will be placing successive 1089 arguments at lower addresses, which means we need to 1090 reverse the order compared to how we would normally 1091 treat either big or little-endian. For those arguments 1092 that will wind up in registers, this still works for 1093 HPPA (the only current STACK_GROWSUP target) since the 1094 argument registers are *also* allocated in decreasing 1095 order. If another such target is added, this logic may 1096 have to get more complicated to differentiate between 1097 stack arguments and register arguments. */ 1098 #if defined(HOST_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP) 1099 op->args[pi++] = temp_arg(args[i] + 1); 1100 op->args[pi++] = temp_arg(args[i]); 1101 #else 1102 op->args[pi++] = temp_arg(args[i]); 1103 op->args[pi++] = temp_arg(args[i] + 1); 1104 #endif 1105 real_args += 2; 1106 continue; 1107 } 1108 1109 op->args[pi++] = temp_arg(args[i]); 1110 real_args++; 1111 } 1112 op->args[pi++] = (uintptr_t)func; 1113 op->args[pi++] = flags; 1114 op->calli = real_args; 1115 1116 /* Make sure the fields didn't overflow. */ 1117 tcg_debug_assert(op->calli == real_args); 1118 tcg_debug_assert(pi <= ARRAY_SIZE(op->args)); 1119 1120 #if defined(__sparc__) && !defined(__arch64__) \ 1121 && !defined(CONFIG_TCG_INTERPRETER) 1122 /* Free all of the parts we allocated above. */ 1123 for (i = real_args = 0; i < orig_nargs; ++i) { 1124 int is_64bit = orig_sizemask & (1 << (i+1)*2); 1125 if (is_64bit) { 1126 tcg_temp_free_internal(args[real_args++]); 1127 tcg_temp_free_internal(args[real_args++]); 1128 } else { 1129 real_args++; 1130 } 1131 } 1132 if (orig_sizemask & 1) { 1133 /* The 32-bit ABI returned two 32-bit pieces. Re-assemble them. 1134 Note that describing these as TCGv_i64 eliminates an unnecessary 1135 zero-extension that tcg_gen_concat_i32_i64 would create. */ 1136 tcg_gen_concat32_i64(temp_tcgv_i64(ret), retl, reth); 1137 tcg_temp_free_i64(retl); 1138 tcg_temp_free_i64(reth); 1139 } 1140 #elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64 1141 for (i = 0; i < nargs; ++i) { 1142 int is_64bit = sizemask & (1 << (i+1)*2); 1143 if (!is_64bit) { 1144 tcg_temp_free_internal(args[i]); 1145 } 1146 } 1147 #endif /* TCG_TARGET_EXTEND_ARGS */ 1148 } 1149 1150 static void tcg_reg_alloc_start(TCGContext *s) 1151 { 1152 int i, n; 1153 TCGTemp *ts; 1154 1155 for (i = 0, n = s->nb_globals; i < n; i++) { 1156 ts = &s->temps[i]; 1157 ts->val_type = (ts->fixed_reg ? TEMP_VAL_REG : TEMP_VAL_MEM); 1158 } 1159 for (n = s->nb_temps; i < n; i++) { 1160 ts = &s->temps[i]; 1161 ts->val_type = (ts->temp_local ? TEMP_VAL_MEM : TEMP_VAL_DEAD); 1162 ts->mem_allocated = 0; 1163 ts->fixed_reg = 0; 1164 } 1165 1166 memset(s->reg_to_temp, 0, sizeof(s->reg_to_temp)); 1167 } 1168 1169 static char *tcg_get_arg_str_ptr(TCGContext *s, char *buf, int buf_size, 1170 TCGTemp *ts) 1171 { 1172 int idx = temp_idx(ts); 1173 1174 if (ts->temp_global) { 1175 pstrcpy(buf, buf_size, ts->name); 1176 } else if (ts->temp_local) { 1177 snprintf(buf, buf_size, "loc%d", idx - s->nb_globals); 1178 } else { 1179 snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals); 1180 } 1181 return buf; 1182 } 1183 1184 static char *tcg_get_arg_str(TCGContext *s, char *buf, 1185 int buf_size, TCGArg arg) 1186 { 1187 return tcg_get_arg_str_ptr(s, buf, buf_size, arg_temp(arg)); 1188 } 1189 1190 /* Find helper name. */ 1191 static inline const char *tcg_find_helper(TCGContext *s, uintptr_t val) 1192 { 1193 const char *ret = NULL; 1194 if (helper_table) { 1195 TCGHelperInfo *info = g_hash_table_lookup(helper_table, (gpointer)val); 1196 if (info) { 1197 ret = info->name; 1198 } 1199 } 1200 return ret; 1201 } 1202 1203 static const char * const cond_name[] = 1204 { 1205 [TCG_COND_NEVER] = "never", 1206 [TCG_COND_ALWAYS] = "always", 1207 [TCG_COND_EQ] = "eq", 1208 [TCG_COND_NE] = "ne", 1209 [TCG_COND_LT] = "lt", 1210 [TCG_COND_GE] = "ge", 1211 [TCG_COND_LE] = "le", 1212 [TCG_COND_GT] = "gt", 1213 [TCG_COND_LTU] = "ltu", 1214 [TCG_COND_GEU] = "geu", 1215 [TCG_COND_LEU] = "leu", 1216 [TCG_COND_GTU] = "gtu" 1217 }; 1218 1219 static const char * const ldst_name[] = 1220 { 1221 [MO_UB] = "ub", 1222 [MO_SB] = "sb", 1223 [MO_LEUW] = "leuw", 1224 [MO_LESW] = "lesw", 1225 [MO_LEUL] = "leul", 1226 [MO_LESL] = "lesl", 1227 [MO_LEQ] = "leq", 1228 [MO_BEUW] = "beuw", 1229 [MO_BESW] = "besw", 1230 [MO_BEUL] = "beul", 1231 [MO_BESL] = "besl", 1232 [MO_BEQ] = "beq", 1233 }; 1234 1235 static const char * const alignment_name[(MO_AMASK >> MO_ASHIFT) + 1] = { 1236 #ifdef ALIGNED_ONLY 1237 [MO_UNALN >> MO_ASHIFT] = "un+", 1238 [MO_ALIGN >> MO_ASHIFT] = "", 1239 #else 1240 [MO_UNALN >> MO_ASHIFT] = "", 1241 [MO_ALIGN >> MO_ASHIFT] = "al+", 1242 #endif 1243 [MO_ALIGN_2 >> MO_ASHIFT] = "al2+", 1244 [MO_ALIGN_4 >> MO_ASHIFT] = "al4+", 1245 [MO_ALIGN_8 >> MO_ASHIFT] = "al8+", 1246 [MO_ALIGN_16 >> MO_ASHIFT] = "al16+", 1247 [MO_ALIGN_32 >> MO_ASHIFT] = "al32+", 1248 [MO_ALIGN_64 >> MO_ASHIFT] = "al64+", 1249 }; 1250 1251 void tcg_dump_ops(TCGContext *s) 1252 { 1253 char buf[128]; 1254 TCGOp *op; 1255 int oi; 1256 1257 for (oi = s->gen_op_buf[0].next; oi != 0; oi = op->next) { 1258 int i, k, nb_oargs, nb_iargs, nb_cargs; 1259 const TCGOpDef *def; 1260 TCGOpcode c; 1261 int col = 0; 1262 1263 op = &s->gen_op_buf[oi]; 1264 c = op->opc; 1265 def = &tcg_op_defs[c]; 1266 1267 if (c == INDEX_op_insn_start) { 1268 col += qemu_log("%s ----", oi != s->gen_op_buf[0].next ? "\n" : ""); 1269 1270 for (i = 0; i < TARGET_INSN_START_WORDS; ++i) { 1271 target_ulong a; 1272 #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS 1273 a = deposit64(op->args[i * 2], 32, 32, op->args[i * 2 + 1]); 1274 #else 1275 a = op->args[i]; 1276 #endif 1277 col += qemu_log(" " TARGET_FMT_lx, a); 1278 } 1279 } else if (c == INDEX_op_call) { 1280 /* variable number of arguments */ 1281 nb_oargs = op->callo; 1282 nb_iargs = op->calli; 1283 nb_cargs = def->nb_cargs; 1284 1285 /* function name, flags, out args */ 1286 col += qemu_log(" %s %s,$0x%" TCG_PRIlx ",$%d", def->name, 1287 tcg_find_helper(s, op->args[nb_oargs + nb_iargs]), 1288 op->args[nb_oargs + nb_iargs + 1], nb_oargs); 1289 for (i = 0; i < nb_oargs; i++) { 1290 col += qemu_log(",%s", tcg_get_arg_str(s, buf, sizeof(buf), 1291 op->args[i])); 1292 } 1293 for (i = 0; i < nb_iargs; i++) { 1294 TCGArg arg = op->args[nb_oargs + i]; 1295 const char *t = "<dummy>"; 1296 if (arg != TCG_CALL_DUMMY_ARG) { 1297 t = tcg_get_arg_str(s, buf, sizeof(buf), arg); 1298 } 1299 col += qemu_log(",%s", t); 1300 } 1301 } else { 1302 col += qemu_log(" %s ", def->name); 1303 1304 nb_oargs = def->nb_oargs; 1305 nb_iargs = def->nb_iargs; 1306 nb_cargs = def->nb_cargs; 1307 1308 k = 0; 1309 for (i = 0; i < nb_oargs; i++) { 1310 if (k != 0) { 1311 col += qemu_log(","); 1312 } 1313 col += qemu_log("%s", tcg_get_arg_str(s, buf, sizeof(buf), 1314 op->args[k++])); 1315 } 1316 for (i = 0; i < nb_iargs; i++) { 1317 if (k != 0) { 1318 col += qemu_log(","); 1319 } 1320 col += qemu_log("%s", tcg_get_arg_str(s, buf, sizeof(buf), 1321 op->args[k++])); 1322 } 1323 switch (c) { 1324 case INDEX_op_brcond_i32: 1325 case INDEX_op_setcond_i32: 1326 case INDEX_op_movcond_i32: 1327 case INDEX_op_brcond2_i32: 1328 case INDEX_op_setcond2_i32: 1329 case INDEX_op_brcond_i64: 1330 case INDEX_op_setcond_i64: 1331 case INDEX_op_movcond_i64: 1332 if (op->args[k] < ARRAY_SIZE(cond_name) 1333 && cond_name[op->args[k]]) { 1334 col += qemu_log(",%s", cond_name[op->args[k++]]); 1335 } else { 1336 col += qemu_log(",$0x%" TCG_PRIlx, op->args[k++]); 1337 } 1338 i = 1; 1339 break; 1340 case INDEX_op_qemu_ld_i32: 1341 case INDEX_op_qemu_st_i32: 1342 case INDEX_op_qemu_ld_i64: 1343 case INDEX_op_qemu_st_i64: 1344 { 1345 TCGMemOpIdx oi = op->args[k++]; 1346 TCGMemOp op = get_memop(oi); 1347 unsigned ix = get_mmuidx(oi); 1348 1349 if (op & ~(MO_AMASK | MO_BSWAP | MO_SSIZE)) { 1350 col += qemu_log(",$0x%x,%u", op, ix); 1351 } else { 1352 const char *s_al, *s_op; 1353 s_al = alignment_name[(op & MO_AMASK) >> MO_ASHIFT]; 1354 s_op = ldst_name[op & (MO_BSWAP | MO_SSIZE)]; 1355 col += qemu_log(",%s%s,%u", s_al, s_op, ix); 1356 } 1357 i = 1; 1358 } 1359 break; 1360 default: 1361 i = 0; 1362 break; 1363 } 1364 switch (c) { 1365 case INDEX_op_set_label: 1366 case INDEX_op_br: 1367 case INDEX_op_brcond_i32: 1368 case INDEX_op_brcond_i64: 1369 case INDEX_op_brcond2_i32: 1370 col += qemu_log("%s$L%d", k ? "," : "", 1371 arg_label(op->args[k])->id); 1372 i++, k++; 1373 break; 1374 default: 1375 break; 1376 } 1377 for (; i < nb_cargs; i++, k++) { 1378 col += qemu_log("%s$0x%" TCG_PRIlx, k ? "," : "", op->args[k]); 1379 } 1380 } 1381 if (op->life) { 1382 unsigned life = op->life; 1383 1384 for (; col < 48; ++col) { 1385 putc(' ', qemu_logfile); 1386 } 1387 1388 if (life & (SYNC_ARG * 3)) { 1389 qemu_log(" sync:"); 1390 for (i = 0; i < 2; ++i) { 1391 if (life & (SYNC_ARG << i)) { 1392 qemu_log(" %d", i); 1393 } 1394 } 1395 } 1396 life /= DEAD_ARG; 1397 if (life) { 1398 qemu_log(" dead:"); 1399 for (i = 0; life; ++i, life >>= 1) { 1400 if (life & 1) { 1401 qemu_log(" %d", i); 1402 } 1403 } 1404 } 1405 } 1406 qemu_log("\n"); 1407 } 1408 } 1409 1410 /* we give more priority to constraints with less registers */ 1411 static int get_constraint_priority(const TCGOpDef *def, int k) 1412 { 1413 const TCGArgConstraint *arg_ct; 1414 1415 int i, n; 1416 arg_ct = &def->args_ct[k]; 1417 if (arg_ct->ct & TCG_CT_ALIAS) { 1418 /* an alias is equivalent to a single register */ 1419 n = 1; 1420 } else { 1421 if (!(arg_ct->ct & TCG_CT_REG)) 1422 return 0; 1423 n = 0; 1424 for(i = 0; i < TCG_TARGET_NB_REGS; i++) { 1425 if (tcg_regset_test_reg(arg_ct->u.regs, i)) 1426 n++; 1427 } 1428 } 1429 return TCG_TARGET_NB_REGS - n + 1; 1430 } 1431 1432 /* sort from highest priority to lowest */ 1433 static void sort_constraints(TCGOpDef *def, int start, int n) 1434 { 1435 int i, j, p1, p2, tmp; 1436 1437 for(i = 0; i < n; i++) 1438 def->sorted_args[start + i] = start + i; 1439 if (n <= 1) 1440 return; 1441 for(i = 0; i < n - 1; i++) { 1442 for(j = i + 1; j < n; j++) { 1443 p1 = get_constraint_priority(def, def->sorted_args[start + i]); 1444 p2 = get_constraint_priority(def, def->sorted_args[start + j]); 1445 if (p1 < p2) { 1446 tmp = def->sorted_args[start + i]; 1447 def->sorted_args[start + i] = def->sorted_args[start + j]; 1448 def->sorted_args[start + j] = tmp; 1449 } 1450 } 1451 } 1452 } 1453 1454 static void process_op_defs(TCGContext *s) 1455 { 1456 TCGOpcode op; 1457 1458 for (op = 0; op < NB_OPS; op++) { 1459 TCGOpDef *def = &tcg_op_defs[op]; 1460 const TCGTargetOpDef *tdefs; 1461 TCGType type; 1462 int i, nb_args; 1463 1464 if (def->flags & TCG_OPF_NOT_PRESENT) { 1465 continue; 1466 } 1467 1468 nb_args = def->nb_iargs + def->nb_oargs; 1469 if (nb_args == 0) { 1470 continue; 1471 } 1472 1473 tdefs = tcg_target_op_def(op); 1474 /* Missing TCGTargetOpDef entry. */ 1475 tcg_debug_assert(tdefs != NULL); 1476 1477 type = (def->flags & TCG_OPF_64BIT ? TCG_TYPE_I64 : TCG_TYPE_I32); 1478 for (i = 0; i < nb_args; i++) { 1479 const char *ct_str = tdefs->args_ct_str[i]; 1480 /* Incomplete TCGTargetOpDef entry. */ 1481 tcg_debug_assert(ct_str != NULL); 1482 1483 def->args_ct[i].u.regs = 0; 1484 def->args_ct[i].ct = 0; 1485 while (*ct_str != '\0') { 1486 switch(*ct_str) { 1487 case '0' ... '9': 1488 { 1489 int oarg = *ct_str - '0'; 1490 tcg_debug_assert(ct_str == tdefs->args_ct_str[i]); 1491 tcg_debug_assert(oarg < def->nb_oargs); 1492 tcg_debug_assert(def->args_ct[oarg].ct & TCG_CT_REG); 1493 /* TCG_CT_ALIAS is for the output arguments. 1494 The input is tagged with TCG_CT_IALIAS. */ 1495 def->args_ct[i] = def->args_ct[oarg]; 1496 def->args_ct[oarg].ct |= TCG_CT_ALIAS; 1497 def->args_ct[oarg].alias_index = i; 1498 def->args_ct[i].ct |= TCG_CT_IALIAS; 1499 def->args_ct[i].alias_index = oarg; 1500 } 1501 ct_str++; 1502 break; 1503 case '&': 1504 def->args_ct[i].ct |= TCG_CT_NEWREG; 1505 ct_str++; 1506 break; 1507 case 'i': 1508 def->args_ct[i].ct |= TCG_CT_CONST; 1509 ct_str++; 1510 break; 1511 default: 1512 ct_str = target_parse_constraint(&def->args_ct[i], 1513 ct_str, type); 1514 /* Typo in TCGTargetOpDef constraint. */ 1515 tcg_debug_assert(ct_str != NULL); 1516 } 1517 } 1518 } 1519 1520 /* TCGTargetOpDef entry with too much information? */ 1521 tcg_debug_assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL); 1522 1523 /* sort the constraints (XXX: this is just an heuristic) */ 1524 sort_constraints(def, 0, def->nb_oargs); 1525 sort_constraints(def, def->nb_oargs, def->nb_iargs); 1526 } 1527 } 1528 1529 void tcg_op_remove(TCGContext *s, TCGOp *op) 1530 { 1531 int next = op->next; 1532 int prev = op->prev; 1533 1534 /* We should never attempt to remove the list terminator. */ 1535 tcg_debug_assert(op != &s->gen_op_buf[0]); 1536 1537 s->gen_op_buf[next].prev = prev; 1538 s->gen_op_buf[prev].next = next; 1539 1540 memset(op, 0, sizeof(*op)); 1541 1542 #ifdef CONFIG_PROFILER 1543 s->del_op_count++; 1544 #endif 1545 } 1546 1547 TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *old_op, 1548 TCGOpcode opc, int nargs) 1549 { 1550 int oi = s->gen_next_op_idx; 1551 int prev = old_op->prev; 1552 int next = old_op - s->gen_op_buf; 1553 TCGOp *new_op; 1554 1555 tcg_debug_assert(oi < OPC_BUF_SIZE); 1556 s->gen_next_op_idx = oi + 1; 1557 1558 new_op = &s->gen_op_buf[oi]; 1559 *new_op = (TCGOp){ 1560 .opc = opc, 1561 .prev = prev, 1562 .next = next 1563 }; 1564 s->gen_op_buf[prev].next = oi; 1565 old_op->prev = oi; 1566 1567 return new_op; 1568 } 1569 1570 TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *old_op, 1571 TCGOpcode opc, int nargs) 1572 { 1573 int oi = s->gen_next_op_idx; 1574 int prev = old_op - s->gen_op_buf; 1575 int next = old_op->next; 1576 TCGOp *new_op; 1577 1578 tcg_debug_assert(oi < OPC_BUF_SIZE); 1579 s->gen_next_op_idx = oi + 1; 1580 1581 new_op = &s->gen_op_buf[oi]; 1582 *new_op = (TCGOp){ 1583 .opc = opc, 1584 .prev = prev, 1585 .next = next 1586 }; 1587 s->gen_op_buf[next].prev = oi; 1588 old_op->next = oi; 1589 1590 return new_op; 1591 } 1592 1593 #define TS_DEAD 1 1594 #define TS_MEM 2 1595 1596 #define IS_DEAD_ARG(n) (arg_life & (DEAD_ARG << (n))) 1597 #define NEED_SYNC_ARG(n) (arg_life & (SYNC_ARG << (n))) 1598 1599 /* liveness analysis: end of function: all temps are dead, and globals 1600 should be in memory. */ 1601 static void tcg_la_func_end(TCGContext *s) 1602 { 1603 int ng = s->nb_globals; 1604 int nt = s->nb_temps; 1605 int i; 1606 1607 for (i = 0; i < ng; ++i) { 1608 s->temps[i].state = TS_DEAD | TS_MEM; 1609 } 1610 for (i = ng; i < nt; ++i) { 1611 s->temps[i].state = TS_DEAD; 1612 } 1613 } 1614 1615 /* liveness analysis: end of basic block: all temps are dead, globals 1616 and local temps should be in memory. */ 1617 static void tcg_la_bb_end(TCGContext *s) 1618 { 1619 int ng = s->nb_globals; 1620 int nt = s->nb_temps; 1621 int i; 1622 1623 for (i = 0; i < ng; ++i) { 1624 s->temps[i].state = TS_DEAD | TS_MEM; 1625 } 1626 for (i = ng; i < nt; ++i) { 1627 s->temps[i].state = (s->temps[i].temp_local 1628 ? TS_DEAD | TS_MEM 1629 : TS_DEAD); 1630 } 1631 } 1632 1633 /* Liveness analysis : update the opc_arg_life array to tell if a 1634 given input arguments is dead. Instructions updating dead 1635 temporaries are removed. */ 1636 static void liveness_pass_1(TCGContext *s) 1637 { 1638 int nb_globals = s->nb_globals; 1639 int oi, oi_prev; 1640 1641 tcg_la_func_end(s); 1642 1643 for (oi = s->gen_op_buf[0].prev; oi != 0; oi = oi_prev) { 1644 int i, nb_iargs, nb_oargs; 1645 TCGOpcode opc_new, opc_new2; 1646 bool have_opc_new2; 1647 TCGLifeData arg_life = 0; 1648 TCGTemp *arg_ts; 1649 1650 TCGOp * const op = &s->gen_op_buf[oi]; 1651 TCGOpcode opc = op->opc; 1652 const TCGOpDef *def = &tcg_op_defs[opc]; 1653 1654 oi_prev = op->prev; 1655 1656 switch (opc) { 1657 case INDEX_op_call: 1658 { 1659 int call_flags; 1660 1661 nb_oargs = op->callo; 1662 nb_iargs = op->calli; 1663 call_flags = op->args[nb_oargs + nb_iargs + 1]; 1664 1665 /* pure functions can be removed if their result is unused */ 1666 if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) { 1667 for (i = 0; i < nb_oargs; i++) { 1668 arg_ts = arg_temp(op->args[i]); 1669 if (arg_ts->state != TS_DEAD) { 1670 goto do_not_remove_call; 1671 } 1672 } 1673 goto do_remove; 1674 } else { 1675 do_not_remove_call: 1676 1677 /* output args are dead */ 1678 for (i = 0; i < nb_oargs; i++) { 1679 arg_ts = arg_temp(op->args[i]); 1680 if (arg_ts->state & TS_DEAD) { 1681 arg_life |= DEAD_ARG << i; 1682 } 1683 if (arg_ts->state & TS_MEM) { 1684 arg_life |= SYNC_ARG << i; 1685 } 1686 arg_ts->state = TS_DEAD; 1687 } 1688 1689 if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS | 1690 TCG_CALL_NO_READ_GLOBALS))) { 1691 /* globals should go back to memory */ 1692 for (i = 0; i < nb_globals; i++) { 1693 s->temps[i].state = TS_DEAD | TS_MEM; 1694 } 1695 } else if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) { 1696 /* globals should be synced to memory */ 1697 for (i = 0; i < nb_globals; i++) { 1698 s->temps[i].state |= TS_MEM; 1699 } 1700 } 1701 1702 /* record arguments that die in this helper */ 1703 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) { 1704 arg_ts = arg_temp(op->args[i]); 1705 if (arg_ts && arg_ts->state & TS_DEAD) { 1706 arg_life |= DEAD_ARG << i; 1707 } 1708 } 1709 /* input arguments are live for preceding opcodes */ 1710 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) { 1711 arg_ts = arg_temp(op->args[i]); 1712 if (arg_ts) { 1713 arg_ts->state &= ~TS_DEAD; 1714 } 1715 } 1716 } 1717 } 1718 break; 1719 case INDEX_op_insn_start: 1720 break; 1721 case INDEX_op_discard: 1722 /* mark the temporary as dead */ 1723 arg_temp(op->args[0])->state = TS_DEAD; 1724 break; 1725 1726 case INDEX_op_add2_i32: 1727 opc_new = INDEX_op_add_i32; 1728 goto do_addsub2; 1729 case INDEX_op_sub2_i32: 1730 opc_new = INDEX_op_sub_i32; 1731 goto do_addsub2; 1732 case INDEX_op_add2_i64: 1733 opc_new = INDEX_op_add_i64; 1734 goto do_addsub2; 1735 case INDEX_op_sub2_i64: 1736 opc_new = INDEX_op_sub_i64; 1737 do_addsub2: 1738 nb_iargs = 4; 1739 nb_oargs = 2; 1740 /* Test if the high part of the operation is dead, but not 1741 the low part. The result can be optimized to a simple 1742 add or sub. This happens often for x86_64 guest when the 1743 cpu mode is set to 32 bit. */ 1744 if (arg_temp(op->args[1])->state == TS_DEAD) { 1745 if (arg_temp(op->args[0])->state == TS_DEAD) { 1746 goto do_remove; 1747 } 1748 /* Replace the opcode and adjust the args in place, 1749 leaving 3 unused args at the end. */ 1750 op->opc = opc = opc_new; 1751 op->args[1] = op->args[2]; 1752 op->args[2] = op->args[4]; 1753 /* Fall through and mark the single-word operation live. */ 1754 nb_iargs = 2; 1755 nb_oargs = 1; 1756 } 1757 goto do_not_remove; 1758 1759 case INDEX_op_mulu2_i32: 1760 opc_new = INDEX_op_mul_i32; 1761 opc_new2 = INDEX_op_muluh_i32; 1762 have_opc_new2 = TCG_TARGET_HAS_muluh_i32; 1763 goto do_mul2; 1764 case INDEX_op_muls2_i32: 1765 opc_new = INDEX_op_mul_i32; 1766 opc_new2 = INDEX_op_mulsh_i32; 1767 have_opc_new2 = TCG_TARGET_HAS_mulsh_i32; 1768 goto do_mul2; 1769 case INDEX_op_mulu2_i64: 1770 opc_new = INDEX_op_mul_i64; 1771 opc_new2 = INDEX_op_muluh_i64; 1772 have_opc_new2 = TCG_TARGET_HAS_muluh_i64; 1773 goto do_mul2; 1774 case INDEX_op_muls2_i64: 1775 opc_new = INDEX_op_mul_i64; 1776 opc_new2 = INDEX_op_mulsh_i64; 1777 have_opc_new2 = TCG_TARGET_HAS_mulsh_i64; 1778 goto do_mul2; 1779 do_mul2: 1780 nb_iargs = 2; 1781 nb_oargs = 2; 1782 if (arg_temp(op->args[1])->state == TS_DEAD) { 1783 if (arg_temp(op->args[0])->state == TS_DEAD) { 1784 /* Both parts of the operation are dead. */ 1785 goto do_remove; 1786 } 1787 /* The high part of the operation is dead; generate the low. */ 1788 op->opc = opc = opc_new; 1789 op->args[1] = op->args[2]; 1790 op->args[2] = op->args[3]; 1791 } else if (arg_temp(op->args[0])->state == TS_DEAD && have_opc_new2) { 1792 /* The low part of the operation is dead; generate the high. */ 1793 op->opc = opc = opc_new2; 1794 op->args[0] = op->args[1]; 1795 op->args[1] = op->args[2]; 1796 op->args[2] = op->args[3]; 1797 } else { 1798 goto do_not_remove; 1799 } 1800 /* Mark the single-word operation live. */ 1801 nb_oargs = 1; 1802 goto do_not_remove; 1803 1804 default: 1805 /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */ 1806 nb_iargs = def->nb_iargs; 1807 nb_oargs = def->nb_oargs; 1808 1809 /* Test if the operation can be removed because all 1810 its outputs are dead. We assume that nb_oargs == 0 1811 implies side effects */ 1812 if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) { 1813 for (i = 0; i < nb_oargs; i++) { 1814 if (arg_temp(op->args[i])->state != TS_DEAD) { 1815 goto do_not_remove; 1816 } 1817 } 1818 do_remove: 1819 tcg_op_remove(s, op); 1820 } else { 1821 do_not_remove: 1822 /* output args are dead */ 1823 for (i = 0; i < nb_oargs; i++) { 1824 arg_ts = arg_temp(op->args[i]); 1825 if (arg_ts->state & TS_DEAD) { 1826 arg_life |= DEAD_ARG << i; 1827 } 1828 if (arg_ts->state & TS_MEM) { 1829 arg_life |= SYNC_ARG << i; 1830 } 1831 arg_ts->state = TS_DEAD; 1832 } 1833 1834 /* if end of basic block, update */ 1835 if (def->flags & TCG_OPF_BB_END) { 1836 tcg_la_bb_end(s); 1837 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) { 1838 /* globals should be synced to memory */ 1839 for (i = 0; i < nb_globals; i++) { 1840 s->temps[i].state |= TS_MEM; 1841 } 1842 } 1843 1844 /* record arguments that die in this opcode */ 1845 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) { 1846 arg_ts = arg_temp(op->args[i]); 1847 if (arg_ts->state & TS_DEAD) { 1848 arg_life |= DEAD_ARG << i; 1849 } 1850 } 1851 /* input arguments are live for preceding opcodes */ 1852 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) { 1853 arg_temp(op->args[i])->state &= ~TS_DEAD; 1854 } 1855 } 1856 break; 1857 } 1858 op->life = arg_life; 1859 } 1860 } 1861 1862 /* Liveness analysis: Convert indirect regs to direct temporaries. */ 1863 static bool liveness_pass_2(TCGContext *s) 1864 { 1865 int nb_globals = s->nb_globals; 1866 int nb_temps, i, oi, oi_next; 1867 bool changes = false; 1868 1869 /* Create a temporary for each indirect global. */ 1870 for (i = 0; i < nb_globals; ++i) { 1871 TCGTemp *its = &s->temps[i]; 1872 if (its->indirect_reg) { 1873 TCGTemp *dts = tcg_temp_alloc(s); 1874 dts->type = its->type; 1875 dts->base_type = its->base_type; 1876 its->state_ptr = dts; 1877 } else { 1878 its->state_ptr = NULL; 1879 } 1880 /* All globals begin dead. */ 1881 its->state = TS_DEAD; 1882 } 1883 for (nb_temps = s->nb_temps; i < nb_temps; ++i) { 1884 TCGTemp *its = &s->temps[i]; 1885 its->state_ptr = NULL; 1886 its->state = TS_DEAD; 1887 } 1888 1889 for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) { 1890 TCGOp *op = &s->gen_op_buf[oi]; 1891 TCGOpcode opc = op->opc; 1892 const TCGOpDef *def = &tcg_op_defs[opc]; 1893 TCGLifeData arg_life = op->life; 1894 int nb_iargs, nb_oargs, call_flags; 1895 TCGTemp *arg_ts, *dir_ts; 1896 1897 oi_next = op->next; 1898 1899 if (opc == INDEX_op_call) { 1900 nb_oargs = op->callo; 1901 nb_iargs = op->calli; 1902 call_flags = op->args[nb_oargs + nb_iargs + 1]; 1903 } else { 1904 nb_iargs = def->nb_iargs; 1905 nb_oargs = def->nb_oargs; 1906 1907 /* Set flags similar to how calls require. */ 1908 if (def->flags & TCG_OPF_BB_END) { 1909 /* Like writing globals: save_globals */ 1910 call_flags = 0; 1911 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) { 1912 /* Like reading globals: sync_globals */ 1913 call_flags = TCG_CALL_NO_WRITE_GLOBALS; 1914 } else { 1915 /* No effect on globals. */ 1916 call_flags = (TCG_CALL_NO_READ_GLOBALS | 1917 TCG_CALL_NO_WRITE_GLOBALS); 1918 } 1919 } 1920 1921 /* Make sure that input arguments are available. */ 1922 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) { 1923 arg_ts = arg_temp(op->args[i]); 1924 if (arg_ts) { 1925 dir_ts = arg_ts->state_ptr; 1926 if (dir_ts && arg_ts->state == TS_DEAD) { 1927 TCGOpcode lopc = (arg_ts->type == TCG_TYPE_I32 1928 ? INDEX_op_ld_i32 1929 : INDEX_op_ld_i64); 1930 TCGOp *lop = tcg_op_insert_before(s, op, lopc, 3); 1931 1932 lop->args[0] = temp_arg(dir_ts); 1933 lop->args[1] = temp_arg(arg_ts->mem_base); 1934 lop->args[2] = arg_ts->mem_offset; 1935 1936 /* Loaded, but synced with memory. */ 1937 arg_ts->state = TS_MEM; 1938 } 1939 } 1940 } 1941 1942 /* Perform input replacement, and mark inputs that became dead. 1943 No action is required except keeping temp_state up to date 1944 so that we reload when needed. */ 1945 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) { 1946 arg_ts = arg_temp(op->args[i]); 1947 if (arg_ts) { 1948 dir_ts = arg_ts->state_ptr; 1949 if (dir_ts) { 1950 op->args[i] = temp_arg(dir_ts); 1951 changes = true; 1952 if (IS_DEAD_ARG(i)) { 1953 arg_ts->state = TS_DEAD; 1954 } 1955 } 1956 } 1957 } 1958 1959 /* Liveness analysis should ensure that the following are 1960 all correct, for call sites and basic block end points. */ 1961 if (call_flags & TCG_CALL_NO_READ_GLOBALS) { 1962 /* Nothing to do */ 1963 } else if (call_flags & TCG_CALL_NO_WRITE_GLOBALS) { 1964 for (i = 0; i < nb_globals; ++i) { 1965 /* Liveness should see that globals are synced back, 1966 that is, either TS_DEAD or TS_MEM. */ 1967 arg_ts = &s->temps[i]; 1968 tcg_debug_assert(arg_ts->state_ptr == 0 1969 || arg_ts->state != 0); 1970 } 1971 } else { 1972 for (i = 0; i < nb_globals; ++i) { 1973 /* Liveness should see that globals are saved back, 1974 that is, TS_DEAD, waiting to be reloaded. */ 1975 arg_ts = &s->temps[i]; 1976 tcg_debug_assert(arg_ts->state_ptr == 0 1977 || arg_ts->state == TS_DEAD); 1978 } 1979 } 1980 1981 /* Outputs become available. */ 1982 for (i = 0; i < nb_oargs; i++) { 1983 arg_ts = arg_temp(op->args[i]); 1984 dir_ts = arg_ts->state_ptr; 1985 if (!dir_ts) { 1986 continue; 1987 } 1988 op->args[i] = temp_arg(dir_ts); 1989 changes = true; 1990 1991 /* The output is now live and modified. */ 1992 arg_ts->state = 0; 1993 1994 /* Sync outputs upon their last write. */ 1995 if (NEED_SYNC_ARG(i)) { 1996 TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32 1997 ? INDEX_op_st_i32 1998 : INDEX_op_st_i64); 1999 TCGOp *sop = tcg_op_insert_after(s, op, sopc, 3); 2000 2001 sop->args[0] = temp_arg(dir_ts); 2002 sop->args[1] = temp_arg(arg_ts->mem_base); 2003 sop->args[2] = arg_ts->mem_offset; 2004 2005 arg_ts->state = TS_MEM; 2006 } 2007 /* Drop outputs that are dead. */ 2008 if (IS_DEAD_ARG(i)) { 2009 arg_ts->state = TS_DEAD; 2010 } 2011 } 2012 } 2013 2014 return changes; 2015 } 2016 2017 #ifdef CONFIG_DEBUG_TCG 2018 static void dump_regs(TCGContext *s) 2019 { 2020 TCGTemp *ts; 2021 int i; 2022 char buf[64]; 2023 2024 for(i = 0; i < s->nb_temps; i++) { 2025 ts = &s->temps[i]; 2026 printf(" %10s: ", tcg_get_arg_str_ptr(s, buf, sizeof(buf), ts)); 2027 switch(ts->val_type) { 2028 case TEMP_VAL_REG: 2029 printf("%s", tcg_target_reg_names[ts->reg]); 2030 break; 2031 case TEMP_VAL_MEM: 2032 printf("%d(%s)", (int)ts->mem_offset, 2033 tcg_target_reg_names[ts->mem_base->reg]); 2034 break; 2035 case TEMP_VAL_CONST: 2036 printf("$0x%" TCG_PRIlx, ts->val); 2037 break; 2038 case TEMP_VAL_DEAD: 2039 printf("D"); 2040 break; 2041 default: 2042 printf("???"); 2043 break; 2044 } 2045 printf("\n"); 2046 } 2047 2048 for(i = 0; i < TCG_TARGET_NB_REGS; i++) { 2049 if (s->reg_to_temp[i] != NULL) { 2050 printf("%s: %s\n", 2051 tcg_target_reg_names[i], 2052 tcg_get_arg_str_ptr(s, buf, sizeof(buf), s->reg_to_temp[i])); 2053 } 2054 } 2055 } 2056 2057 static void check_regs(TCGContext *s) 2058 { 2059 int reg; 2060 int k; 2061 TCGTemp *ts; 2062 char buf[64]; 2063 2064 for (reg = 0; reg < TCG_TARGET_NB_REGS; reg++) { 2065 ts = s->reg_to_temp[reg]; 2066 if (ts != NULL) { 2067 if (ts->val_type != TEMP_VAL_REG || ts->reg != reg) { 2068 printf("Inconsistency for register %s:\n", 2069 tcg_target_reg_names[reg]); 2070 goto fail; 2071 } 2072 } 2073 } 2074 for (k = 0; k < s->nb_temps; k++) { 2075 ts = &s->temps[k]; 2076 if (ts->val_type == TEMP_VAL_REG && !ts->fixed_reg 2077 && s->reg_to_temp[ts->reg] != ts) { 2078 printf("Inconsistency for temp %s:\n", 2079 tcg_get_arg_str_ptr(s, buf, sizeof(buf), ts)); 2080 fail: 2081 printf("reg state:\n"); 2082 dump_regs(s); 2083 tcg_abort(); 2084 } 2085 } 2086 } 2087 #endif 2088 2089 static void temp_allocate_frame(TCGContext *s, TCGTemp *ts) 2090 { 2091 #if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64) 2092 /* Sparc64 stack is accessed with offset of 2047 */ 2093 s->current_frame_offset = (s->current_frame_offset + 2094 (tcg_target_long)sizeof(tcg_target_long) - 1) & 2095 ~(sizeof(tcg_target_long) - 1); 2096 #endif 2097 if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) > 2098 s->frame_end) { 2099 tcg_abort(); 2100 } 2101 ts->mem_offset = s->current_frame_offset; 2102 ts->mem_base = s->frame_temp; 2103 ts->mem_allocated = 1; 2104 s->current_frame_offset += sizeof(tcg_target_long); 2105 } 2106 2107 static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet); 2108 2109 /* Mark a temporary as free or dead. If 'free_or_dead' is negative, 2110 mark it free; otherwise mark it dead. */ 2111 static void temp_free_or_dead(TCGContext *s, TCGTemp *ts, int free_or_dead) 2112 { 2113 if (ts->fixed_reg) { 2114 return; 2115 } 2116 if (ts->val_type == TEMP_VAL_REG) { 2117 s->reg_to_temp[ts->reg] = NULL; 2118 } 2119 ts->val_type = (free_or_dead < 0 2120 || ts->temp_local 2121 || ts->temp_global 2122 ? TEMP_VAL_MEM : TEMP_VAL_DEAD); 2123 } 2124 2125 /* Mark a temporary as dead. */ 2126 static inline void temp_dead(TCGContext *s, TCGTemp *ts) 2127 { 2128 temp_free_or_dead(s, ts, 1); 2129 } 2130 2131 /* Sync a temporary to memory. 'allocated_regs' is used in case a temporary 2132 registers needs to be allocated to store a constant. If 'free_or_dead' 2133 is non-zero, subsequently release the temporary; if it is positive, the 2134 temp is dead; if it is negative, the temp is free. */ 2135 static void temp_sync(TCGContext *s, TCGTemp *ts, 2136 TCGRegSet allocated_regs, int free_or_dead) 2137 { 2138 if (ts->fixed_reg) { 2139 return; 2140 } 2141 if (!ts->mem_coherent) { 2142 if (!ts->mem_allocated) { 2143 temp_allocate_frame(s, ts); 2144 } 2145 switch (ts->val_type) { 2146 case TEMP_VAL_CONST: 2147 /* If we're going to free the temp immediately, then we won't 2148 require it later in a register, so attempt to store the 2149 constant to memory directly. */ 2150 if (free_or_dead 2151 && tcg_out_sti(s, ts->type, ts->val, 2152 ts->mem_base->reg, ts->mem_offset)) { 2153 break; 2154 } 2155 temp_load(s, ts, tcg_target_available_regs[ts->type], 2156 allocated_regs); 2157 /* fallthrough */ 2158 2159 case TEMP_VAL_REG: 2160 tcg_out_st(s, ts->type, ts->reg, 2161 ts->mem_base->reg, ts->mem_offset); 2162 break; 2163 2164 case TEMP_VAL_MEM: 2165 break; 2166 2167 case TEMP_VAL_DEAD: 2168 default: 2169 tcg_abort(); 2170 } 2171 ts->mem_coherent = 1; 2172 } 2173 if (free_or_dead) { 2174 temp_free_or_dead(s, ts, free_or_dead); 2175 } 2176 } 2177 2178 /* free register 'reg' by spilling the corresponding temporary if necessary */ 2179 static void tcg_reg_free(TCGContext *s, TCGReg reg, TCGRegSet allocated_regs) 2180 { 2181 TCGTemp *ts = s->reg_to_temp[reg]; 2182 if (ts != NULL) { 2183 temp_sync(s, ts, allocated_regs, -1); 2184 } 2185 } 2186 2187 /* Allocate a register belonging to reg1 & ~reg2 */ 2188 static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet desired_regs, 2189 TCGRegSet allocated_regs, bool rev) 2190 { 2191 int i, n = ARRAY_SIZE(tcg_target_reg_alloc_order); 2192 const int *order; 2193 TCGReg reg; 2194 TCGRegSet reg_ct; 2195 2196 reg_ct = desired_regs & ~allocated_regs; 2197 order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order; 2198 2199 /* first try free registers */ 2200 for(i = 0; i < n; i++) { 2201 reg = order[i]; 2202 if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == NULL) 2203 return reg; 2204 } 2205 2206 /* XXX: do better spill choice */ 2207 for(i = 0; i < n; i++) { 2208 reg = order[i]; 2209 if (tcg_regset_test_reg(reg_ct, reg)) { 2210 tcg_reg_free(s, reg, allocated_regs); 2211 return reg; 2212 } 2213 } 2214 2215 tcg_abort(); 2216 } 2217 2218 /* Make sure the temporary is in a register. If needed, allocate the register 2219 from DESIRED while avoiding ALLOCATED. */ 2220 static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs, 2221 TCGRegSet allocated_regs) 2222 { 2223 TCGReg reg; 2224 2225 switch (ts->val_type) { 2226 case TEMP_VAL_REG: 2227 return; 2228 case TEMP_VAL_CONST: 2229 reg = tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirect_base); 2230 tcg_out_movi(s, ts->type, reg, ts->val); 2231 ts->mem_coherent = 0; 2232 break; 2233 case TEMP_VAL_MEM: 2234 reg = tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirect_base); 2235 tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset); 2236 ts->mem_coherent = 1; 2237 break; 2238 case TEMP_VAL_DEAD: 2239 default: 2240 tcg_abort(); 2241 } 2242 ts->reg = reg; 2243 ts->val_type = TEMP_VAL_REG; 2244 s->reg_to_temp[reg] = ts; 2245 } 2246 2247 /* Save a temporary to memory. 'allocated_regs' is used in case a 2248 temporary registers needs to be allocated to store a constant. */ 2249 static void temp_save(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs) 2250 { 2251 /* The liveness analysis already ensures that globals are back 2252 in memory. Keep an tcg_debug_assert for safety. */ 2253 tcg_debug_assert(ts->val_type == TEMP_VAL_MEM || ts->fixed_reg); 2254 } 2255 2256 /* save globals to their canonical location and assume they can be 2257 modified be the following code. 'allocated_regs' is used in case a 2258 temporary registers needs to be allocated to store a constant. */ 2259 static void save_globals(TCGContext *s, TCGRegSet allocated_regs) 2260 { 2261 int i, n; 2262 2263 for (i = 0, n = s->nb_globals; i < n; i++) { 2264 temp_save(s, &s->temps[i], allocated_regs); 2265 } 2266 } 2267 2268 /* sync globals to their canonical location and assume they can be 2269 read by the following code. 'allocated_regs' is used in case a 2270 temporary registers needs to be allocated to store a constant. */ 2271 static void sync_globals(TCGContext *s, TCGRegSet allocated_regs) 2272 { 2273 int i, n; 2274 2275 for (i = 0, n = s->nb_globals; i < n; i++) { 2276 TCGTemp *ts = &s->temps[i]; 2277 tcg_debug_assert(ts->val_type != TEMP_VAL_REG 2278 || ts->fixed_reg 2279 || ts->mem_coherent); 2280 } 2281 } 2282 2283 /* at the end of a basic block, we assume all temporaries are dead and 2284 all globals are stored at their canonical location. */ 2285 static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs) 2286 { 2287 int i; 2288 2289 for (i = s->nb_globals; i < s->nb_temps; i++) { 2290 TCGTemp *ts = &s->temps[i]; 2291 if (ts->temp_local) { 2292 temp_save(s, ts, allocated_regs); 2293 } else { 2294 /* The liveness analysis already ensures that temps are dead. 2295 Keep an tcg_debug_assert for safety. */ 2296 tcg_debug_assert(ts->val_type == TEMP_VAL_DEAD); 2297 } 2298 } 2299 2300 save_globals(s, allocated_regs); 2301 } 2302 2303 static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp *ots, 2304 tcg_target_ulong val, TCGLifeData arg_life) 2305 { 2306 if (ots->fixed_reg) { 2307 /* For fixed registers, we do not do any constant propagation. */ 2308 tcg_out_movi(s, ots->type, ots->reg, val); 2309 return; 2310 } 2311 2312 /* The movi is not explicitly generated here. */ 2313 if (ots->val_type == TEMP_VAL_REG) { 2314 s->reg_to_temp[ots->reg] = NULL; 2315 } 2316 ots->val_type = TEMP_VAL_CONST; 2317 ots->val = val; 2318 ots->mem_coherent = 0; 2319 if (NEED_SYNC_ARG(0)) { 2320 temp_sync(s, ots, s->reserved_regs, IS_DEAD_ARG(0)); 2321 } else if (IS_DEAD_ARG(0)) { 2322 temp_dead(s, ots); 2323 } 2324 } 2325 2326 static void tcg_reg_alloc_movi(TCGContext *s, const TCGOp *op) 2327 { 2328 TCGTemp *ots = arg_temp(op->args[0]); 2329 tcg_target_ulong val = op->args[1]; 2330 2331 tcg_reg_alloc_do_movi(s, ots, val, op->life); 2332 } 2333 2334 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op) 2335 { 2336 const TCGLifeData arg_life = op->life; 2337 TCGRegSet allocated_regs; 2338 TCGTemp *ts, *ots; 2339 TCGType otype, itype; 2340 2341 allocated_regs = s->reserved_regs; 2342 ots = arg_temp(op->args[0]); 2343 ts = arg_temp(op->args[1]); 2344 2345 /* Note that otype != itype for no-op truncation. */ 2346 otype = ots->type; 2347 itype = ts->type; 2348 2349 if (ts->val_type == TEMP_VAL_CONST) { 2350 /* propagate constant or generate sti */ 2351 tcg_target_ulong val = ts->val; 2352 if (IS_DEAD_ARG(1)) { 2353 temp_dead(s, ts); 2354 } 2355 tcg_reg_alloc_do_movi(s, ots, val, arg_life); 2356 return; 2357 } 2358 2359 /* If the source value is in memory we're going to be forced 2360 to have it in a register in order to perform the copy. Copy 2361 the SOURCE value into its own register first, that way we 2362 don't have to reload SOURCE the next time it is used. */ 2363 if (ts->val_type == TEMP_VAL_MEM) { 2364 temp_load(s, ts, tcg_target_available_regs[itype], allocated_regs); 2365 } 2366 2367 tcg_debug_assert(ts->val_type == TEMP_VAL_REG); 2368 if (IS_DEAD_ARG(0) && !ots->fixed_reg) { 2369 /* mov to a non-saved dead register makes no sense (even with 2370 liveness analysis disabled). */ 2371 tcg_debug_assert(NEED_SYNC_ARG(0)); 2372 if (!ots->mem_allocated) { 2373 temp_allocate_frame(s, ots); 2374 } 2375 tcg_out_st(s, otype, ts->reg, ots->mem_base->reg, ots->mem_offset); 2376 if (IS_DEAD_ARG(1)) { 2377 temp_dead(s, ts); 2378 } 2379 temp_dead(s, ots); 2380 } else { 2381 if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) { 2382 /* the mov can be suppressed */ 2383 if (ots->val_type == TEMP_VAL_REG) { 2384 s->reg_to_temp[ots->reg] = NULL; 2385 } 2386 ots->reg = ts->reg; 2387 temp_dead(s, ts); 2388 } else { 2389 if (ots->val_type != TEMP_VAL_REG) { 2390 /* When allocating a new register, make sure to not spill the 2391 input one. */ 2392 tcg_regset_set_reg(allocated_regs, ts->reg); 2393 ots->reg = tcg_reg_alloc(s, tcg_target_available_regs[otype], 2394 allocated_regs, ots->indirect_base); 2395 } 2396 tcg_out_mov(s, otype, ots->reg, ts->reg); 2397 } 2398 ots->val_type = TEMP_VAL_REG; 2399 ots->mem_coherent = 0; 2400 s->reg_to_temp[ots->reg] = ots; 2401 if (NEED_SYNC_ARG(0)) { 2402 temp_sync(s, ots, allocated_regs, 0); 2403 } 2404 } 2405 } 2406 2407 static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op) 2408 { 2409 const TCGLifeData arg_life = op->life; 2410 const TCGOpDef * const def = &tcg_op_defs[op->opc]; 2411 TCGRegSet i_allocated_regs; 2412 TCGRegSet o_allocated_regs; 2413 int i, k, nb_iargs, nb_oargs; 2414 TCGReg reg; 2415 TCGArg arg; 2416 const TCGArgConstraint *arg_ct; 2417 TCGTemp *ts; 2418 TCGArg new_args[TCG_MAX_OP_ARGS]; 2419 int const_args[TCG_MAX_OP_ARGS]; 2420 2421 nb_oargs = def->nb_oargs; 2422 nb_iargs = def->nb_iargs; 2423 2424 /* copy constants */ 2425 memcpy(new_args + nb_oargs + nb_iargs, 2426 op->args + nb_oargs + nb_iargs, 2427 sizeof(TCGArg) * def->nb_cargs); 2428 2429 i_allocated_regs = s->reserved_regs; 2430 o_allocated_regs = s->reserved_regs; 2431 2432 /* satisfy input constraints */ 2433 for (k = 0; k < nb_iargs; k++) { 2434 i = def->sorted_args[nb_oargs + k]; 2435 arg = op->args[i]; 2436 arg_ct = &def->args_ct[i]; 2437 ts = arg_temp(arg); 2438 2439 if (ts->val_type == TEMP_VAL_CONST 2440 && tcg_target_const_match(ts->val, ts->type, arg_ct)) { 2441 /* constant is OK for instruction */ 2442 const_args[i] = 1; 2443 new_args[i] = ts->val; 2444 goto iarg_end; 2445 } 2446 2447 temp_load(s, ts, arg_ct->u.regs, i_allocated_regs); 2448 2449 if (arg_ct->ct & TCG_CT_IALIAS) { 2450 if (ts->fixed_reg) { 2451 /* if fixed register, we must allocate a new register 2452 if the alias is not the same register */ 2453 if (arg != op->args[arg_ct->alias_index]) 2454 goto allocate_in_reg; 2455 } else { 2456 /* if the input is aliased to an output and if it is 2457 not dead after the instruction, we must allocate 2458 a new register and move it */ 2459 if (!IS_DEAD_ARG(i)) { 2460 goto allocate_in_reg; 2461 } 2462 /* check if the current register has already been allocated 2463 for another input aliased to an output */ 2464 int k2, i2; 2465 for (k2 = 0 ; k2 < k ; k2++) { 2466 i2 = def->sorted_args[nb_oargs + k2]; 2467 if ((def->args_ct[i2].ct & TCG_CT_IALIAS) && 2468 (new_args[i2] == ts->reg)) { 2469 goto allocate_in_reg; 2470 } 2471 } 2472 } 2473 } 2474 reg = ts->reg; 2475 if (tcg_regset_test_reg(arg_ct->u.regs, reg)) { 2476 /* nothing to do : the constraint is satisfied */ 2477 } else { 2478 allocate_in_reg: 2479 /* allocate a new register matching the constraint 2480 and move the temporary register into it */ 2481 reg = tcg_reg_alloc(s, arg_ct->u.regs, i_allocated_regs, 2482 ts->indirect_base); 2483 tcg_out_mov(s, ts->type, reg, ts->reg); 2484 } 2485 new_args[i] = reg; 2486 const_args[i] = 0; 2487 tcg_regset_set_reg(i_allocated_regs, reg); 2488 iarg_end: ; 2489 } 2490 2491 /* mark dead temporaries and free the associated registers */ 2492 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) { 2493 if (IS_DEAD_ARG(i)) { 2494 temp_dead(s, arg_temp(op->args[i])); 2495 } 2496 } 2497 2498 if (def->flags & TCG_OPF_BB_END) { 2499 tcg_reg_alloc_bb_end(s, i_allocated_regs); 2500 } else { 2501 if (def->flags & TCG_OPF_CALL_CLOBBER) { 2502 /* XXX: permit generic clobber register list ? */ 2503 for (i = 0; i < TCG_TARGET_NB_REGS; i++) { 2504 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) { 2505 tcg_reg_free(s, i, i_allocated_regs); 2506 } 2507 } 2508 } 2509 if (def->flags & TCG_OPF_SIDE_EFFECTS) { 2510 /* sync globals if the op has side effects and might trigger 2511 an exception. */ 2512 sync_globals(s, i_allocated_regs); 2513 } 2514 2515 /* satisfy the output constraints */ 2516 for(k = 0; k < nb_oargs; k++) { 2517 i = def->sorted_args[k]; 2518 arg = op->args[i]; 2519 arg_ct = &def->args_ct[i]; 2520 ts = arg_temp(arg); 2521 if ((arg_ct->ct & TCG_CT_ALIAS) 2522 && !const_args[arg_ct->alias_index]) { 2523 reg = new_args[arg_ct->alias_index]; 2524 } else if (arg_ct->ct & TCG_CT_NEWREG) { 2525 reg = tcg_reg_alloc(s, arg_ct->u.regs, 2526 i_allocated_regs | o_allocated_regs, 2527 ts->indirect_base); 2528 } else { 2529 /* if fixed register, we try to use it */ 2530 reg = ts->reg; 2531 if (ts->fixed_reg && 2532 tcg_regset_test_reg(arg_ct->u.regs, reg)) { 2533 goto oarg_end; 2534 } 2535 reg = tcg_reg_alloc(s, arg_ct->u.regs, o_allocated_regs, 2536 ts->indirect_base); 2537 } 2538 tcg_regset_set_reg(o_allocated_regs, reg); 2539 /* if a fixed register is used, then a move will be done afterwards */ 2540 if (!ts->fixed_reg) { 2541 if (ts->val_type == TEMP_VAL_REG) { 2542 s->reg_to_temp[ts->reg] = NULL; 2543 } 2544 ts->val_type = TEMP_VAL_REG; 2545 ts->reg = reg; 2546 /* temp value is modified, so the value kept in memory is 2547 potentially not the same */ 2548 ts->mem_coherent = 0; 2549 s->reg_to_temp[reg] = ts; 2550 } 2551 oarg_end: 2552 new_args[i] = reg; 2553 } 2554 } 2555 2556 /* emit instruction */ 2557 tcg_out_op(s, op->opc, new_args, const_args); 2558 2559 /* move the outputs in the correct register if needed */ 2560 for(i = 0; i < nb_oargs; i++) { 2561 ts = arg_temp(op->args[i]); 2562 reg = new_args[i]; 2563 if (ts->fixed_reg && ts->reg != reg) { 2564 tcg_out_mov(s, ts->type, ts->reg, reg); 2565 } 2566 if (NEED_SYNC_ARG(i)) { 2567 temp_sync(s, ts, o_allocated_regs, IS_DEAD_ARG(i)); 2568 } else if (IS_DEAD_ARG(i)) { 2569 temp_dead(s, ts); 2570 } 2571 } 2572 } 2573 2574 #ifdef TCG_TARGET_STACK_GROWSUP 2575 #define STACK_DIR(x) (-(x)) 2576 #else 2577 #define STACK_DIR(x) (x) 2578 #endif 2579 2580 static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op) 2581 { 2582 const int nb_oargs = op->callo; 2583 const int nb_iargs = op->calli; 2584 const TCGLifeData arg_life = op->life; 2585 int flags, nb_regs, i; 2586 TCGReg reg; 2587 TCGArg arg; 2588 TCGTemp *ts; 2589 intptr_t stack_offset; 2590 size_t call_stack_size; 2591 tcg_insn_unit *func_addr; 2592 int allocate_args; 2593 TCGRegSet allocated_regs; 2594 2595 func_addr = (tcg_insn_unit *)(intptr_t)op->args[nb_oargs + nb_iargs]; 2596 flags = op->args[nb_oargs + nb_iargs + 1]; 2597 2598 nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs); 2599 if (nb_regs > nb_iargs) { 2600 nb_regs = nb_iargs; 2601 } 2602 2603 /* assign stack slots first */ 2604 call_stack_size = (nb_iargs - nb_regs) * sizeof(tcg_target_long); 2605 call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & 2606 ~(TCG_TARGET_STACK_ALIGN - 1); 2607 allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE); 2608 if (allocate_args) { 2609 /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed, 2610 preallocate call stack */ 2611 tcg_abort(); 2612 } 2613 2614 stack_offset = TCG_TARGET_CALL_STACK_OFFSET; 2615 for (i = nb_regs; i < nb_iargs; i++) { 2616 arg = op->args[nb_oargs + i]; 2617 #ifdef TCG_TARGET_STACK_GROWSUP 2618 stack_offset -= sizeof(tcg_target_long); 2619 #endif 2620 if (arg != TCG_CALL_DUMMY_ARG) { 2621 ts = arg_temp(arg); 2622 temp_load(s, ts, tcg_target_available_regs[ts->type], 2623 s->reserved_regs); 2624 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset); 2625 } 2626 #ifndef TCG_TARGET_STACK_GROWSUP 2627 stack_offset += sizeof(tcg_target_long); 2628 #endif 2629 } 2630 2631 /* assign input registers */ 2632 allocated_regs = s->reserved_regs; 2633 for (i = 0; i < nb_regs; i++) { 2634 arg = op->args[nb_oargs + i]; 2635 if (arg != TCG_CALL_DUMMY_ARG) { 2636 ts = arg_temp(arg); 2637 reg = tcg_target_call_iarg_regs[i]; 2638 tcg_reg_free(s, reg, allocated_regs); 2639 2640 if (ts->val_type == TEMP_VAL_REG) { 2641 if (ts->reg != reg) { 2642 tcg_out_mov(s, ts->type, reg, ts->reg); 2643 } 2644 } else { 2645 TCGRegSet arg_set = 0; 2646 2647 tcg_regset_set_reg(arg_set, reg); 2648 temp_load(s, ts, arg_set, allocated_regs); 2649 } 2650 2651 tcg_regset_set_reg(allocated_regs, reg); 2652 } 2653 } 2654 2655 /* mark dead temporaries and free the associated registers */ 2656 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) { 2657 if (IS_DEAD_ARG(i)) { 2658 temp_dead(s, arg_temp(op->args[i])); 2659 } 2660 } 2661 2662 /* clobber call registers */ 2663 for (i = 0; i < TCG_TARGET_NB_REGS; i++) { 2664 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) { 2665 tcg_reg_free(s, i, allocated_regs); 2666 } 2667 } 2668 2669 /* Save globals if they might be written by the helper, sync them if 2670 they might be read. */ 2671 if (flags & TCG_CALL_NO_READ_GLOBALS) { 2672 /* Nothing to do */ 2673 } else if (flags & TCG_CALL_NO_WRITE_GLOBALS) { 2674 sync_globals(s, allocated_regs); 2675 } else { 2676 save_globals(s, allocated_regs); 2677 } 2678 2679 tcg_out_call(s, func_addr); 2680 2681 /* assign output registers and emit moves if needed */ 2682 for(i = 0; i < nb_oargs; i++) { 2683 arg = op->args[i]; 2684 ts = arg_temp(arg); 2685 reg = tcg_target_call_oarg_regs[i]; 2686 tcg_debug_assert(s->reg_to_temp[reg] == NULL); 2687 2688 if (ts->fixed_reg) { 2689 if (ts->reg != reg) { 2690 tcg_out_mov(s, ts->type, ts->reg, reg); 2691 } 2692 } else { 2693 if (ts->val_type == TEMP_VAL_REG) { 2694 s->reg_to_temp[ts->reg] = NULL; 2695 } 2696 ts->val_type = TEMP_VAL_REG; 2697 ts->reg = reg; 2698 ts->mem_coherent = 0; 2699 s->reg_to_temp[reg] = ts; 2700 if (NEED_SYNC_ARG(i)) { 2701 temp_sync(s, ts, allocated_regs, IS_DEAD_ARG(i)); 2702 } else if (IS_DEAD_ARG(i)) { 2703 temp_dead(s, ts); 2704 } 2705 } 2706 } 2707 } 2708 2709 #ifdef CONFIG_PROFILER 2710 2711 static int64_t tcg_table_op_count[NB_OPS]; 2712 2713 void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf) 2714 { 2715 int i; 2716 2717 for (i = 0; i < NB_OPS; i++) { 2718 cpu_fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, 2719 tcg_table_op_count[i]); 2720 } 2721 } 2722 #else 2723 void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf) 2724 { 2725 cpu_fprintf(f, "[TCG profiler not compiled]\n"); 2726 } 2727 #endif 2728 2729 2730 int tcg_gen_code(TCGContext *s, TranslationBlock *tb) 2731 { 2732 int i, oi, oi_next, num_insns; 2733 2734 #ifdef CONFIG_PROFILER 2735 { 2736 int n; 2737 2738 n = s->gen_op_buf[0].prev + 1; 2739 s->op_count += n; 2740 if (n > s->op_count_max) { 2741 s->op_count_max = n; 2742 } 2743 2744 n = s->nb_temps; 2745 s->temp_count += n; 2746 if (n > s->temp_count_max) { 2747 s->temp_count_max = n; 2748 } 2749 } 2750 #endif 2751 2752 #ifdef DEBUG_DISAS 2753 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP) 2754 && qemu_log_in_addr_range(tb->pc))) { 2755 qemu_log_lock(); 2756 qemu_log("OP:\n"); 2757 tcg_dump_ops(s); 2758 qemu_log("\n"); 2759 qemu_log_unlock(); 2760 } 2761 #endif 2762 2763 #ifdef CONFIG_PROFILER 2764 s->opt_time -= profile_getclock(); 2765 #endif 2766 2767 #ifdef USE_TCG_OPTIMIZATIONS 2768 tcg_optimize(s); 2769 #endif 2770 2771 #ifdef CONFIG_PROFILER 2772 s->opt_time += profile_getclock(); 2773 s->la_time -= profile_getclock(); 2774 #endif 2775 2776 liveness_pass_1(s); 2777 2778 if (s->nb_indirects > 0) { 2779 #ifdef DEBUG_DISAS 2780 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_IND) 2781 && qemu_log_in_addr_range(tb->pc))) { 2782 qemu_log_lock(); 2783 qemu_log("OP before indirect lowering:\n"); 2784 tcg_dump_ops(s); 2785 qemu_log("\n"); 2786 qemu_log_unlock(); 2787 } 2788 #endif 2789 /* Replace indirect temps with direct temps. */ 2790 if (liveness_pass_2(s)) { 2791 /* If changes were made, re-run liveness. */ 2792 liveness_pass_1(s); 2793 } 2794 } 2795 2796 #ifdef CONFIG_PROFILER 2797 s->la_time += profile_getclock(); 2798 #endif 2799 2800 #ifdef DEBUG_DISAS 2801 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT) 2802 && qemu_log_in_addr_range(tb->pc))) { 2803 qemu_log_lock(); 2804 qemu_log("OP after optimization and liveness analysis:\n"); 2805 tcg_dump_ops(s); 2806 qemu_log("\n"); 2807 qemu_log_unlock(); 2808 } 2809 #endif 2810 2811 tcg_reg_alloc_start(s); 2812 2813 s->code_buf = tb->tc.ptr; 2814 s->code_ptr = tb->tc.ptr; 2815 2816 #ifdef TCG_TARGET_NEED_LDST_LABELS 2817 s->ldst_labels = NULL; 2818 #endif 2819 #ifdef TCG_TARGET_NEED_POOL_LABELS 2820 s->pool_labels = NULL; 2821 #endif 2822 2823 num_insns = -1; 2824 for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) { 2825 TCGOp * const op = &s->gen_op_buf[oi]; 2826 TCGOpcode opc = op->opc; 2827 2828 oi_next = op->next; 2829 #ifdef CONFIG_PROFILER 2830 tcg_table_op_count[opc]++; 2831 #endif 2832 2833 switch (opc) { 2834 case INDEX_op_mov_i32: 2835 case INDEX_op_mov_i64: 2836 tcg_reg_alloc_mov(s, op); 2837 break; 2838 case INDEX_op_movi_i32: 2839 case INDEX_op_movi_i64: 2840 tcg_reg_alloc_movi(s, op); 2841 break; 2842 case INDEX_op_insn_start: 2843 if (num_insns >= 0) { 2844 s->gen_insn_end_off[num_insns] = tcg_current_code_size(s); 2845 } 2846 num_insns++; 2847 for (i = 0; i < TARGET_INSN_START_WORDS; ++i) { 2848 target_ulong a; 2849 #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS 2850 a = deposit64(op->args[i * 2], 32, 32, op->args[i * 2 + 1]); 2851 #else 2852 a = op->args[i]; 2853 #endif 2854 s->gen_insn_data[num_insns][i] = a; 2855 } 2856 break; 2857 case INDEX_op_discard: 2858 temp_dead(s, arg_temp(op->args[0])); 2859 break; 2860 case INDEX_op_set_label: 2861 tcg_reg_alloc_bb_end(s, s->reserved_regs); 2862 tcg_out_label(s, arg_label(op->args[0]), s->code_ptr); 2863 break; 2864 case INDEX_op_call: 2865 tcg_reg_alloc_call(s, op); 2866 break; 2867 default: 2868 /* Sanity check that we've not introduced any unhandled opcodes. */ 2869 tcg_debug_assert(tcg_op_supported(opc)); 2870 /* Note: in order to speed up the code, it would be much 2871 faster to have specialized register allocator functions for 2872 some common argument patterns */ 2873 tcg_reg_alloc_op(s, op); 2874 break; 2875 } 2876 #ifdef CONFIG_DEBUG_TCG 2877 check_regs(s); 2878 #endif 2879 /* Test for (pending) buffer overflow. The assumption is that any 2880 one operation beginning below the high water mark cannot overrun 2881 the buffer completely. Thus we can test for overflow after 2882 generating code without having to check during generation. */ 2883 if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) { 2884 return -1; 2885 } 2886 } 2887 tcg_debug_assert(num_insns >= 0); 2888 s->gen_insn_end_off[num_insns] = tcg_current_code_size(s); 2889 2890 /* Generate TB finalization at the end of block */ 2891 #ifdef TCG_TARGET_NEED_LDST_LABELS 2892 if (!tcg_out_ldst_finalize(s)) { 2893 return -1; 2894 } 2895 #endif 2896 #ifdef TCG_TARGET_NEED_POOL_LABELS 2897 if (!tcg_out_pool_finalize(s)) { 2898 return -1; 2899 } 2900 #endif 2901 2902 /* flush instruction cache */ 2903 flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr); 2904 2905 return tcg_current_code_size(s); 2906 } 2907 2908 #ifdef CONFIG_PROFILER 2909 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf) 2910 { 2911 TCGContext *s = &tcg_ctx; 2912 int64_t tb_count = s->tb_count; 2913 int64_t tb_div_count = tb_count ? tb_count : 1; 2914 int64_t tot = s->interm_time + s->code_time; 2915 2916 cpu_fprintf(f, "JIT cycles %" PRId64 " (%0.3f s at 2.4 GHz)\n", 2917 tot, tot / 2.4e9); 2918 cpu_fprintf(f, "translated TBs %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n", 2919 tb_count, s->tb_count1 - tb_count, 2920 (double)(s->tb_count1 - s->tb_count) 2921 / (s->tb_count1 ? s->tb_count1 : 1) * 100.0); 2922 cpu_fprintf(f, "avg ops/TB %0.1f max=%d\n", 2923 (double)s->op_count / tb_div_count, s->op_count_max); 2924 cpu_fprintf(f, "deleted ops/TB %0.2f\n", 2925 (double)s->del_op_count / tb_div_count); 2926 cpu_fprintf(f, "avg temps/TB %0.2f max=%d\n", 2927 (double)s->temp_count / tb_div_count, s->temp_count_max); 2928 cpu_fprintf(f, "avg host code/TB %0.1f\n", 2929 (double)s->code_out_len / tb_div_count); 2930 cpu_fprintf(f, "avg search data/TB %0.1f\n", 2931 (double)s->search_out_len / tb_div_count); 2932 2933 cpu_fprintf(f, "cycles/op %0.1f\n", 2934 s->op_count ? (double)tot / s->op_count : 0); 2935 cpu_fprintf(f, "cycles/in byte %0.1f\n", 2936 s->code_in_len ? (double)tot / s->code_in_len : 0); 2937 cpu_fprintf(f, "cycles/out byte %0.1f\n", 2938 s->code_out_len ? (double)tot / s->code_out_len : 0); 2939 cpu_fprintf(f, "cycles/search byte %0.1f\n", 2940 s->search_out_len ? (double)tot / s->search_out_len : 0); 2941 if (tot == 0) { 2942 tot = 1; 2943 } 2944 cpu_fprintf(f, " gen_interm time %0.1f%%\n", 2945 (double)s->interm_time / tot * 100.0); 2946 cpu_fprintf(f, " gen_code time %0.1f%%\n", 2947 (double)s->code_time / tot * 100.0); 2948 cpu_fprintf(f, "optim./code time %0.1f%%\n", 2949 (double)s->opt_time / (s->code_time ? s->code_time : 1) 2950 * 100.0); 2951 cpu_fprintf(f, "liveness/code time %0.1f%%\n", 2952 (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0); 2953 cpu_fprintf(f, "cpu_restore count %" PRId64 "\n", 2954 s->restore_count); 2955 cpu_fprintf(f, " avg cycles %0.1f\n", 2956 s->restore_count ? (double)s->restore_time / s->restore_count : 0); 2957 } 2958 #else 2959 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf) 2960 { 2961 cpu_fprintf(f, "[TCG profiler not compiled]\n"); 2962 } 2963 #endif 2964 2965 #ifdef ELF_HOST_MACHINE 2966 /* In order to use this feature, the backend needs to do three things: 2967 2968 (1) Define ELF_HOST_MACHINE to indicate both what value to 2969 put into the ELF image and to indicate support for the feature. 2970 2971 (2) Define tcg_register_jit. This should create a buffer containing 2972 the contents of a .debug_frame section that describes the post- 2973 prologue unwind info for the tcg machine. 2974 2975 (3) Call tcg_register_jit_int, with the constructed .debug_frame. 2976 */ 2977 2978 /* Begin GDB interface. THE FOLLOWING MUST MATCH GDB DOCS. */ 2979 typedef enum { 2980 JIT_NOACTION = 0, 2981 JIT_REGISTER_FN, 2982 JIT_UNREGISTER_FN 2983 } jit_actions_t; 2984 2985 struct jit_code_entry { 2986 struct jit_code_entry *next_entry; 2987 struct jit_code_entry *prev_entry; 2988 const void *symfile_addr; 2989 uint64_t symfile_size; 2990 }; 2991 2992 struct jit_descriptor { 2993 uint32_t version; 2994 uint32_t action_flag; 2995 struct jit_code_entry *relevant_entry; 2996 struct jit_code_entry *first_entry; 2997 }; 2998 2999 void __jit_debug_register_code(void) __attribute__((noinline)); 3000 void __jit_debug_register_code(void) 3001 { 3002 asm(""); 3003 } 3004 3005 /* Must statically initialize the version, because GDB may check 3006 the version before we can set it. */ 3007 struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 }; 3008 3009 /* End GDB interface. */ 3010 3011 static int find_string(const char *strtab, const char *str) 3012 { 3013 const char *p = strtab + 1; 3014 3015 while (1) { 3016 if (strcmp(p, str) == 0) { 3017 return p - strtab; 3018 } 3019 p += strlen(p) + 1; 3020 } 3021 } 3022 3023 static void tcg_register_jit_int(void *buf_ptr, size_t buf_size, 3024 const void *debug_frame, 3025 size_t debug_frame_size) 3026 { 3027 struct __attribute__((packed)) DebugInfo { 3028 uint32_t len; 3029 uint16_t version; 3030 uint32_t abbrev; 3031 uint8_t ptr_size; 3032 uint8_t cu_die; 3033 uint16_t cu_lang; 3034 uintptr_t cu_low_pc; 3035 uintptr_t cu_high_pc; 3036 uint8_t fn_die; 3037 char fn_name[16]; 3038 uintptr_t fn_low_pc; 3039 uintptr_t fn_high_pc; 3040 uint8_t cu_eoc; 3041 }; 3042 3043 struct ElfImage { 3044 ElfW(Ehdr) ehdr; 3045 ElfW(Phdr) phdr; 3046 ElfW(Shdr) shdr[7]; 3047 ElfW(Sym) sym[2]; 3048 struct DebugInfo di; 3049 uint8_t da[24]; 3050 char str[80]; 3051 }; 3052 3053 struct ElfImage *img; 3054 3055 static const struct ElfImage img_template = { 3056 .ehdr = { 3057 .e_ident[EI_MAG0] = ELFMAG0, 3058 .e_ident[EI_MAG1] = ELFMAG1, 3059 .e_ident[EI_MAG2] = ELFMAG2, 3060 .e_ident[EI_MAG3] = ELFMAG3, 3061 .e_ident[EI_CLASS] = ELF_CLASS, 3062 .e_ident[EI_DATA] = ELF_DATA, 3063 .e_ident[EI_VERSION] = EV_CURRENT, 3064 .e_type = ET_EXEC, 3065 .e_machine = ELF_HOST_MACHINE, 3066 .e_version = EV_CURRENT, 3067 .e_phoff = offsetof(struct ElfImage, phdr), 3068 .e_shoff = offsetof(struct ElfImage, shdr), 3069 .e_ehsize = sizeof(ElfW(Shdr)), 3070 .e_phentsize = sizeof(ElfW(Phdr)), 3071 .e_phnum = 1, 3072 .e_shentsize = sizeof(ElfW(Shdr)), 3073 .e_shnum = ARRAY_SIZE(img->shdr), 3074 .e_shstrndx = ARRAY_SIZE(img->shdr) - 1, 3075 #ifdef ELF_HOST_FLAGS 3076 .e_flags = ELF_HOST_FLAGS, 3077 #endif 3078 #ifdef ELF_OSABI 3079 .e_ident[EI_OSABI] = ELF_OSABI, 3080 #endif 3081 }, 3082 .phdr = { 3083 .p_type = PT_LOAD, 3084 .p_flags = PF_X, 3085 }, 3086 .shdr = { 3087 [0] = { .sh_type = SHT_NULL }, 3088 /* Trick: The contents of code_gen_buffer are not present in 3089 this fake ELF file; that got allocated elsewhere. Therefore 3090 we mark .text as SHT_NOBITS (similar to .bss) so that readers 3091 will not look for contents. We can record any address. */ 3092 [1] = { /* .text */ 3093 .sh_type = SHT_NOBITS, 3094 .sh_flags = SHF_EXECINSTR | SHF_ALLOC, 3095 }, 3096 [2] = { /* .debug_info */ 3097 .sh_type = SHT_PROGBITS, 3098 .sh_offset = offsetof(struct ElfImage, di), 3099 .sh_size = sizeof(struct DebugInfo), 3100 }, 3101 [3] = { /* .debug_abbrev */ 3102 .sh_type = SHT_PROGBITS, 3103 .sh_offset = offsetof(struct ElfImage, da), 3104 .sh_size = sizeof(img->da), 3105 }, 3106 [4] = { /* .debug_frame */ 3107 .sh_type = SHT_PROGBITS, 3108 .sh_offset = sizeof(struct ElfImage), 3109 }, 3110 [5] = { /* .symtab */ 3111 .sh_type = SHT_SYMTAB, 3112 .sh_offset = offsetof(struct ElfImage, sym), 3113 .sh_size = sizeof(img->sym), 3114 .sh_info = 1, 3115 .sh_link = ARRAY_SIZE(img->shdr) - 1, 3116 .sh_entsize = sizeof(ElfW(Sym)), 3117 }, 3118 [6] = { /* .strtab */ 3119 .sh_type = SHT_STRTAB, 3120 .sh_offset = offsetof(struct ElfImage, str), 3121 .sh_size = sizeof(img->str), 3122 } 3123 }, 3124 .sym = { 3125 [1] = { /* code_gen_buffer */ 3126 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC), 3127 .st_shndx = 1, 3128 } 3129 }, 3130 .di = { 3131 .len = sizeof(struct DebugInfo) - 4, 3132 .version = 2, 3133 .ptr_size = sizeof(void *), 3134 .cu_die = 1, 3135 .cu_lang = 0x8001, /* DW_LANG_Mips_Assembler */ 3136 .fn_die = 2, 3137 .fn_name = "code_gen_buffer" 3138 }, 3139 .da = { 3140 1, /* abbrev number (the cu) */ 3141 0x11, 1, /* DW_TAG_compile_unit, has children */ 3142 0x13, 0x5, /* DW_AT_language, DW_FORM_data2 */ 3143 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */ 3144 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */ 3145 0, 0, /* end of abbrev */ 3146 2, /* abbrev number (the fn) */ 3147 0x2e, 0, /* DW_TAG_subprogram, no children */ 3148 0x3, 0x8, /* DW_AT_name, DW_FORM_string */ 3149 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */ 3150 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */ 3151 0, 0, /* end of abbrev */ 3152 0 /* no more abbrev */ 3153 }, 3154 .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0" 3155 ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer", 3156 }; 3157 3158 /* We only need a single jit entry; statically allocate it. */ 3159 static struct jit_code_entry one_entry; 3160 3161 uintptr_t buf = (uintptr_t)buf_ptr; 3162 size_t img_size = sizeof(struct ElfImage) + debug_frame_size; 3163 DebugFrameHeader *dfh; 3164 3165 img = g_malloc(img_size); 3166 *img = img_template; 3167 3168 img->phdr.p_vaddr = buf; 3169 img->phdr.p_paddr = buf; 3170 img->phdr.p_memsz = buf_size; 3171 3172 img->shdr[1].sh_name = find_string(img->str, ".text"); 3173 img->shdr[1].sh_addr = buf; 3174 img->shdr[1].sh_size = buf_size; 3175 3176 img->shdr[2].sh_name = find_string(img->str, ".debug_info"); 3177 img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev"); 3178 3179 img->shdr[4].sh_name = find_string(img->str, ".debug_frame"); 3180 img->shdr[4].sh_size = debug_frame_size; 3181 3182 img->shdr[5].sh_name = find_string(img->str, ".symtab"); 3183 img->shdr[6].sh_name = find_string(img->str, ".strtab"); 3184 3185 img->sym[1].st_name = find_string(img->str, "code_gen_buffer"); 3186 img->sym[1].st_value = buf; 3187 img->sym[1].st_size = buf_size; 3188 3189 img->di.cu_low_pc = buf; 3190 img->di.cu_high_pc = buf + buf_size; 3191 img->di.fn_low_pc = buf; 3192 img->di.fn_high_pc = buf + buf_size; 3193 3194 dfh = (DebugFrameHeader *)(img + 1); 3195 memcpy(dfh, debug_frame, debug_frame_size); 3196 dfh->fde.func_start = buf; 3197 dfh->fde.func_len = buf_size; 3198 3199 #ifdef DEBUG_JIT 3200 /* Enable this block to be able to debug the ELF image file creation. 3201 One can use readelf, objdump, or other inspection utilities. */ 3202 { 3203 FILE *f = fopen("/tmp/qemu.jit", "w+b"); 3204 if (f) { 3205 if (fwrite(img, img_size, 1, f) != img_size) { 3206 /* Avoid stupid unused return value warning for fwrite. */ 3207 } 3208 fclose(f); 3209 } 3210 } 3211 #endif 3212 3213 one_entry.symfile_addr = img; 3214 one_entry.symfile_size = img_size; 3215 3216 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN; 3217 __jit_debug_descriptor.relevant_entry = &one_entry; 3218 __jit_debug_descriptor.first_entry = &one_entry; 3219 __jit_debug_register_code(); 3220 } 3221 #else 3222 /* No support for the feature. Provide the entry point expected by exec.c, 3223 and implement the internal function we declared earlier. */ 3224 3225 static void tcg_register_jit_int(void *buf, size_t size, 3226 const void *debug_frame, 3227 size_t debug_frame_size) 3228 { 3229 } 3230 3231 void tcg_register_jit(void *buf, size_t buf_size) 3232 { 3233 } 3234 #endif /* ELF_HOST_MACHINE */ 3235