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_LIVENESS_ANALYSIS 27 #define USE_TCG_OPTIMIZATIONS 28 29 #include "config.h" 30 31 /* Define to jump the ELF file used to communicate with GDB. */ 32 #undef DEBUG_JIT 33 34 #if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG) 35 /* define it to suppress various consistency checks (faster) */ 36 #define NDEBUG 37 #endif 38 39 #include "qemu-common.h" 40 #include "qemu/host-utils.h" 41 #include "qemu/timer.h" 42 43 /* Note: the long term plan is to reduce the dependencies on the QEMU 44 CPU definitions. Currently they are used for qemu_ld/st 45 instructions */ 46 #define NO_CPU_IO_DEFS 47 #include "cpu.h" 48 49 #include "tcg-op.h" 50 51 #if UINTPTR_MAX == UINT32_MAX 52 # define ELF_CLASS ELFCLASS32 53 #else 54 # define ELF_CLASS ELFCLASS64 55 #endif 56 #ifdef HOST_WORDS_BIGENDIAN 57 # define ELF_DATA ELFDATA2MSB 58 #else 59 # define ELF_DATA ELFDATA2LSB 60 #endif 61 62 #include "elf.h" 63 64 /* Forward declarations for functions declared in tcg-target.c and used here. */ 65 static void tcg_target_init(TCGContext *s); 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.c. */ 99 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str); 100 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1, 101 intptr_t arg2); 102 static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); 103 static void tcg_out_movi(TCGContext *s, TCGType type, 104 TCGReg ret, tcg_target_long arg); 105 static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, 106 const int *const_args); 107 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, 108 intptr_t arg2); 109 static void tcg_out_call(TCGContext *s, tcg_insn_unit *target); 110 static int tcg_target_const_match(tcg_target_long val, TCGType type, 111 const TCGArgConstraint *arg_ct); 112 static void tcg_out_tb_init(TCGContext *s); 113 static void tcg_out_tb_finalize(TCGContext *s); 114 115 116 TCGOpDef tcg_op_defs[] = { 117 #define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags }, 118 #include "tcg-opc.h" 119 #undef DEF 120 }; 121 const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs); 122 123 static TCGRegSet tcg_target_available_regs[2]; 124 static TCGRegSet tcg_target_call_clobber_regs; 125 126 #if TCG_TARGET_INSN_UNIT_SIZE == 1 127 static __attribute__((unused)) inline void tcg_out8(TCGContext *s, uint8_t v) 128 { 129 *s->code_ptr++ = v; 130 } 131 132 static __attribute__((unused)) inline void tcg_patch8(tcg_insn_unit *p, 133 uint8_t v) 134 { 135 *p = v; 136 } 137 #endif 138 139 #if TCG_TARGET_INSN_UNIT_SIZE <= 2 140 static __attribute__((unused)) inline void tcg_out16(TCGContext *s, uint16_t v) 141 { 142 if (TCG_TARGET_INSN_UNIT_SIZE == 2) { 143 *s->code_ptr++ = v; 144 } else { 145 tcg_insn_unit *p = s->code_ptr; 146 memcpy(p, &v, sizeof(v)); 147 s->code_ptr = p + (2 / TCG_TARGET_INSN_UNIT_SIZE); 148 } 149 } 150 151 static __attribute__((unused)) inline void tcg_patch16(tcg_insn_unit *p, 152 uint16_t v) 153 { 154 if (TCG_TARGET_INSN_UNIT_SIZE == 2) { 155 *p = v; 156 } else { 157 memcpy(p, &v, sizeof(v)); 158 } 159 } 160 #endif 161 162 #if TCG_TARGET_INSN_UNIT_SIZE <= 4 163 static __attribute__((unused)) inline void tcg_out32(TCGContext *s, uint32_t v) 164 { 165 if (TCG_TARGET_INSN_UNIT_SIZE == 4) { 166 *s->code_ptr++ = v; 167 } else { 168 tcg_insn_unit *p = s->code_ptr; 169 memcpy(p, &v, sizeof(v)); 170 s->code_ptr = p + (4 / TCG_TARGET_INSN_UNIT_SIZE); 171 } 172 } 173 174 static __attribute__((unused)) inline void tcg_patch32(tcg_insn_unit *p, 175 uint32_t v) 176 { 177 if (TCG_TARGET_INSN_UNIT_SIZE == 4) { 178 *p = v; 179 } else { 180 memcpy(p, &v, sizeof(v)); 181 } 182 } 183 #endif 184 185 #if TCG_TARGET_INSN_UNIT_SIZE <= 8 186 static __attribute__((unused)) inline void tcg_out64(TCGContext *s, uint64_t v) 187 { 188 if (TCG_TARGET_INSN_UNIT_SIZE == 8) { 189 *s->code_ptr++ = v; 190 } else { 191 tcg_insn_unit *p = s->code_ptr; 192 memcpy(p, &v, sizeof(v)); 193 s->code_ptr = p + (8 / TCG_TARGET_INSN_UNIT_SIZE); 194 } 195 } 196 197 static __attribute__((unused)) inline void tcg_patch64(tcg_insn_unit *p, 198 uint64_t v) 199 { 200 if (TCG_TARGET_INSN_UNIT_SIZE == 8) { 201 *p = v; 202 } else { 203 memcpy(p, &v, sizeof(v)); 204 } 205 } 206 #endif 207 208 /* label relocation processing */ 209 210 static void tcg_out_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type, 211 int label_index, intptr_t addend) 212 { 213 TCGLabel *l; 214 TCGRelocation *r; 215 216 l = &s->labels[label_index]; 217 if (l->has_value) { 218 /* FIXME: This may break relocations on RISC targets that 219 modify instruction fields in place. The caller may not have 220 written the initial value. */ 221 patch_reloc(code_ptr, type, l->u.value, addend); 222 } else { 223 /* add a new relocation entry */ 224 r = tcg_malloc(sizeof(TCGRelocation)); 225 r->type = type; 226 r->ptr = code_ptr; 227 r->addend = addend; 228 r->next = l->u.first_reloc; 229 l->u.first_reloc = r; 230 } 231 } 232 233 static void tcg_out_label(TCGContext *s, int label_index, tcg_insn_unit *ptr) 234 { 235 TCGLabel *l = &s->labels[label_index]; 236 intptr_t value = (intptr_t)ptr; 237 TCGRelocation *r; 238 239 assert(!l->has_value); 240 241 for (r = l->u.first_reloc; r != NULL; r = r->next) { 242 patch_reloc(r->ptr, r->type, value, r->addend); 243 } 244 245 l->has_value = 1; 246 l->u.value_ptr = ptr; 247 } 248 249 int gen_new_label(void) 250 { 251 TCGContext *s = &tcg_ctx; 252 int idx; 253 TCGLabel *l; 254 255 if (s->nb_labels >= TCG_MAX_LABELS) 256 tcg_abort(); 257 idx = s->nb_labels++; 258 l = &s->labels[idx]; 259 l->has_value = 0; 260 l->u.first_reloc = NULL; 261 return idx; 262 } 263 264 #include "tcg-target.c" 265 266 /* pool based memory allocation */ 267 void *tcg_malloc_internal(TCGContext *s, int size) 268 { 269 TCGPool *p; 270 int pool_size; 271 272 if (size > TCG_POOL_CHUNK_SIZE) { 273 /* big malloc: insert a new pool (XXX: could optimize) */ 274 p = g_malloc(sizeof(TCGPool) + size); 275 p->size = size; 276 p->next = s->pool_first_large; 277 s->pool_first_large = p; 278 return p->data; 279 } else { 280 p = s->pool_current; 281 if (!p) { 282 p = s->pool_first; 283 if (!p) 284 goto new_pool; 285 } else { 286 if (!p->next) { 287 new_pool: 288 pool_size = TCG_POOL_CHUNK_SIZE; 289 p = g_malloc(sizeof(TCGPool) + pool_size); 290 p->size = pool_size; 291 p->next = NULL; 292 if (s->pool_current) 293 s->pool_current->next = p; 294 else 295 s->pool_first = p; 296 } else { 297 p = p->next; 298 } 299 } 300 } 301 s->pool_current = p; 302 s->pool_cur = p->data + size; 303 s->pool_end = p->data + p->size; 304 return p->data; 305 } 306 307 void tcg_pool_reset(TCGContext *s) 308 { 309 TCGPool *p, *t; 310 for (p = s->pool_first_large; p; p = t) { 311 t = p->next; 312 g_free(p); 313 } 314 s->pool_first_large = NULL; 315 s->pool_cur = s->pool_end = NULL; 316 s->pool_current = NULL; 317 } 318 319 typedef struct TCGHelperInfo { 320 void *func; 321 const char *name; 322 unsigned flags; 323 unsigned sizemask; 324 } TCGHelperInfo; 325 326 #include "exec/helper-proto.h" 327 328 static const TCGHelperInfo all_helpers[] = { 329 #include "exec/helper-tcg.h" 330 }; 331 332 void tcg_context_init(TCGContext *s) 333 { 334 int op, total_args, n, i; 335 TCGOpDef *def; 336 TCGArgConstraint *args_ct; 337 int *sorted_args; 338 GHashTable *helper_table; 339 340 memset(s, 0, sizeof(*s)); 341 s->nb_globals = 0; 342 343 /* Count total number of arguments and allocate the corresponding 344 space */ 345 total_args = 0; 346 for(op = 0; op < NB_OPS; op++) { 347 def = &tcg_op_defs[op]; 348 n = def->nb_iargs + def->nb_oargs; 349 total_args += n; 350 } 351 352 args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args); 353 sorted_args = g_malloc(sizeof(int) * total_args); 354 355 for(op = 0; op < NB_OPS; op++) { 356 def = &tcg_op_defs[op]; 357 def->args_ct = args_ct; 358 def->sorted_args = sorted_args; 359 n = def->nb_iargs + def->nb_oargs; 360 sorted_args += n; 361 args_ct += n; 362 } 363 364 /* Register helpers. */ 365 /* Use g_direct_hash/equal for direct pointer comparisons on func. */ 366 s->helpers = helper_table = g_hash_table_new(NULL, NULL); 367 368 for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) { 369 g_hash_table_insert(helper_table, (gpointer)all_helpers[i].func, 370 (gpointer)&all_helpers[i]); 371 } 372 373 tcg_target_init(s); 374 } 375 376 void tcg_prologue_init(TCGContext *s) 377 { 378 /* init global prologue and epilogue */ 379 s->code_buf = s->code_gen_prologue; 380 s->code_ptr = s->code_buf; 381 tcg_target_qemu_prologue(s); 382 flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr); 383 384 #ifdef DEBUG_DISAS 385 if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) { 386 size_t size = tcg_current_code_size(s); 387 qemu_log("PROLOGUE: [size=%zu]\n", size); 388 log_disas(s->code_buf, size); 389 qemu_log("\n"); 390 qemu_log_flush(); 391 } 392 #endif 393 } 394 395 void tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size) 396 { 397 s->frame_start = start; 398 s->frame_end = start + size; 399 s->frame_reg = reg; 400 } 401 402 void tcg_func_start(TCGContext *s) 403 { 404 tcg_pool_reset(s); 405 s->nb_temps = s->nb_globals; 406 407 /* No temps have been previously allocated for size or locality. */ 408 memset(s->free_temps, 0, sizeof(s->free_temps)); 409 410 s->nb_labels = 0; 411 s->current_frame_offset = s->frame_start; 412 413 #ifdef CONFIG_DEBUG_TCG 414 s->goto_tb_issue_mask = 0; 415 #endif 416 417 s->gen_first_op_idx = 0; 418 s->gen_last_op_idx = -1; 419 s->gen_next_op_idx = 0; 420 s->gen_next_parm_idx = 0; 421 422 s->be = tcg_malloc(sizeof(TCGBackendData)); 423 } 424 425 static inline void tcg_temp_alloc(TCGContext *s, int n) 426 { 427 if (n > TCG_MAX_TEMPS) 428 tcg_abort(); 429 } 430 431 static inline int tcg_global_reg_new_internal(TCGType type, int reg, 432 const char *name) 433 { 434 TCGContext *s = &tcg_ctx; 435 TCGTemp *ts; 436 int idx; 437 438 #if TCG_TARGET_REG_BITS == 32 439 if (type != TCG_TYPE_I32) 440 tcg_abort(); 441 #endif 442 if (tcg_regset_test_reg(s->reserved_regs, reg)) 443 tcg_abort(); 444 idx = s->nb_globals; 445 tcg_temp_alloc(s, s->nb_globals + 1); 446 ts = &s->temps[s->nb_globals]; 447 ts->base_type = type; 448 ts->type = type; 449 ts->fixed_reg = 1; 450 ts->reg = reg; 451 ts->name = name; 452 s->nb_globals++; 453 tcg_regset_set_reg(s->reserved_regs, reg); 454 return idx; 455 } 456 457 TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name) 458 { 459 int idx; 460 461 idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name); 462 return MAKE_TCGV_I32(idx); 463 } 464 465 TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name) 466 { 467 int idx; 468 469 idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name); 470 return MAKE_TCGV_I64(idx); 471 } 472 473 static inline int tcg_global_mem_new_internal(TCGType type, int reg, 474 intptr_t offset, 475 const char *name) 476 { 477 TCGContext *s = &tcg_ctx; 478 TCGTemp *ts; 479 int idx; 480 481 idx = s->nb_globals; 482 #if TCG_TARGET_REG_BITS == 32 483 if (type == TCG_TYPE_I64) { 484 char buf[64]; 485 tcg_temp_alloc(s, s->nb_globals + 2); 486 ts = &s->temps[s->nb_globals]; 487 ts->base_type = type; 488 ts->type = TCG_TYPE_I32; 489 ts->fixed_reg = 0; 490 ts->mem_allocated = 1; 491 ts->mem_reg = reg; 492 #ifdef HOST_WORDS_BIGENDIAN 493 ts->mem_offset = offset + 4; 494 #else 495 ts->mem_offset = offset; 496 #endif 497 pstrcpy(buf, sizeof(buf), name); 498 pstrcat(buf, sizeof(buf), "_0"); 499 ts->name = strdup(buf); 500 ts++; 501 502 ts->base_type = type; 503 ts->type = TCG_TYPE_I32; 504 ts->fixed_reg = 0; 505 ts->mem_allocated = 1; 506 ts->mem_reg = reg; 507 #ifdef HOST_WORDS_BIGENDIAN 508 ts->mem_offset = offset; 509 #else 510 ts->mem_offset = offset + 4; 511 #endif 512 pstrcpy(buf, sizeof(buf), name); 513 pstrcat(buf, sizeof(buf), "_1"); 514 ts->name = strdup(buf); 515 516 s->nb_globals += 2; 517 } else 518 #endif 519 { 520 tcg_temp_alloc(s, s->nb_globals + 1); 521 ts = &s->temps[s->nb_globals]; 522 ts->base_type = type; 523 ts->type = type; 524 ts->fixed_reg = 0; 525 ts->mem_allocated = 1; 526 ts->mem_reg = reg; 527 ts->mem_offset = offset; 528 ts->name = name; 529 s->nb_globals++; 530 } 531 return idx; 532 } 533 534 TCGv_i32 tcg_global_mem_new_i32(int reg, intptr_t offset, const char *name) 535 { 536 int idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name); 537 return MAKE_TCGV_I32(idx); 538 } 539 540 TCGv_i64 tcg_global_mem_new_i64(int reg, intptr_t offset, const char *name) 541 { 542 int idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name); 543 return MAKE_TCGV_I64(idx); 544 } 545 546 static inline int tcg_temp_new_internal(TCGType type, int temp_local) 547 { 548 TCGContext *s = &tcg_ctx; 549 TCGTemp *ts; 550 int idx, k; 551 552 k = type + (temp_local ? TCG_TYPE_COUNT : 0); 553 idx = find_first_bit(s->free_temps[k].l, TCG_MAX_TEMPS); 554 if (idx < TCG_MAX_TEMPS) { 555 /* There is already an available temp with the right type. */ 556 clear_bit(idx, s->free_temps[k].l); 557 558 ts = &s->temps[idx]; 559 ts->temp_allocated = 1; 560 assert(ts->base_type == type); 561 assert(ts->temp_local == temp_local); 562 } else { 563 idx = s->nb_temps; 564 #if TCG_TARGET_REG_BITS == 32 565 if (type == TCG_TYPE_I64) { 566 tcg_temp_alloc(s, s->nb_temps + 2); 567 ts = &s->temps[s->nb_temps]; 568 ts->base_type = type; 569 ts->type = TCG_TYPE_I32; 570 ts->temp_allocated = 1; 571 ts->temp_local = temp_local; 572 ts->name = NULL; 573 ts++; 574 ts->base_type = type; 575 ts->type = TCG_TYPE_I32; 576 ts->temp_allocated = 1; 577 ts->temp_local = temp_local; 578 ts->name = NULL; 579 s->nb_temps += 2; 580 } else 581 #endif 582 { 583 tcg_temp_alloc(s, s->nb_temps + 1); 584 ts = &s->temps[s->nb_temps]; 585 ts->base_type = type; 586 ts->type = type; 587 ts->temp_allocated = 1; 588 ts->temp_local = temp_local; 589 ts->name = NULL; 590 s->nb_temps++; 591 } 592 } 593 594 #if defined(CONFIG_DEBUG_TCG) 595 s->temps_in_use++; 596 #endif 597 return idx; 598 } 599 600 TCGv_i32 tcg_temp_new_internal_i32(int temp_local) 601 { 602 int idx; 603 604 idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local); 605 return MAKE_TCGV_I32(idx); 606 } 607 608 TCGv_i64 tcg_temp_new_internal_i64(int temp_local) 609 { 610 int idx; 611 612 idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local); 613 return MAKE_TCGV_I64(idx); 614 } 615 616 static void tcg_temp_free_internal(int idx) 617 { 618 TCGContext *s = &tcg_ctx; 619 TCGTemp *ts; 620 int k; 621 622 #if defined(CONFIG_DEBUG_TCG) 623 s->temps_in_use--; 624 if (s->temps_in_use < 0) { 625 fprintf(stderr, "More temporaries freed than allocated!\n"); 626 } 627 #endif 628 629 assert(idx >= s->nb_globals && idx < s->nb_temps); 630 ts = &s->temps[idx]; 631 assert(ts->temp_allocated != 0); 632 ts->temp_allocated = 0; 633 634 k = ts->base_type + (ts->temp_local ? TCG_TYPE_COUNT : 0); 635 set_bit(idx, s->free_temps[k].l); 636 } 637 638 void tcg_temp_free_i32(TCGv_i32 arg) 639 { 640 tcg_temp_free_internal(GET_TCGV_I32(arg)); 641 } 642 643 void tcg_temp_free_i64(TCGv_i64 arg) 644 { 645 tcg_temp_free_internal(GET_TCGV_I64(arg)); 646 } 647 648 TCGv_i32 tcg_const_i32(int32_t val) 649 { 650 TCGv_i32 t0; 651 t0 = tcg_temp_new_i32(); 652 tcg_gen_movi_i32(t0, val); 653 return t0; 654 } 655 656 TCGv_i64 tcg_const_i64(int64_t val) 657 { 658 TCGv_i64 t0; 659 t0 = tcg_temp_new_i64(); 660 tcg_gen_movi_i64(t0, val); 661 return t0; 662 } 663 664 TCGv_i32 tcg_const_local_i32(int32_t val) 665 { 666 TCGv_i32 t0; 667 t0 = tcg_temp_local_new_i32(); 668 tcg_gen_movi_i32(t0, val); 669 return t0; 670 } 671 672 TCGv_i64 tcg_const_local_i64(int64_t val) 673 { 674 TCGv_i64 t0; 675 t0 = tcg_temp_local_new_i64(); 676 tcg_gen_movi_i64(t0, val); 677 return t0; 678 } 679 680 #if defined(CONFIG_DEBUG_TCG) 681 void tcg_clear_temp_count(void) 682 { 683 TCGContext *s = &tcg_ctx; 684 s->temps_in_use = 0; 685 } 686 687 int tcg_check_temp_count(void) 688 { 689 TCGContext *s = &tcg_ctx; 690 if (s->temps_in_use) { 691 /* Clear the count so that we don't give another 692 * warning immediately next time around. 693 */ 694 s->temps_in_use = 0; 695 return 1; 696 } 697 return 0; 698 } 699 #endif 700 701 /* Note: we convert the 64 bit args to 32 bit and do some alignment 702 and endian swap. Maybe it would be better to do the alignment 703 and endian swap in tcg_reg_alloc_call(). */ 704 void tcg_gen_callN(TCGContext *s, void *func, TCGArg ret, 705 int nargs, TCGArg *args) 706 { 707 int i, real_args, nb_rets, pi, pi_first; 708 unsigned sizemask, flags; 709 TCGHelperInfo *info; 710 711 info = g_hash_table_lookup(s->helpers, (gpointer)func); 712 flags = info->flags; 713 sizemask = info->sizemask; 714 715 #if defined(__sparc__) && !defined(__arch64__) \ 716 && !defined(CONFIG_TCG_INTERPRETER) 717 /* We have 64-bit values in one register, but need to pass as two 718 separate parameters. Split them. */ 719 int orig_sizemask = sizemask; 720 int orig_nargs = nargs; 721 TCGv_i64 retl, reth; 722 723 TCGV_UNUSED_I64(retl); 724 TCGV_UNUSED_I64(reth); 725 if (sizemask != 0) { 726 TCGArg *split_args = __builtin_alloca(sizeof(TCGArg) * nargs * 2); 727 for (i = real_args = 0; i < nargs; ++i) { 728 int is_64bit = sizemask & (1 << (i+1)*2); 729 if (is_64bit) { 730 TCGv_i64 orig = MAKE_TCGV_I64(args[i]); 731 TCGv_i32 h = tcg_temp_new_i32(); 732 TCGv_i32 l = tcg_temp_new_i32(); 733 tcg_gen_extr_i64_i32(l, h, orig); 734 split_args[real_args++] = GET_TCGV_I32(h); 735 split_args[real_args++] = GET_TCGV_I32(l); 736 } else { 737 split_args[real_args++] = args[i]; 738 } 739 } 740 nargs = real_args; 741 args = split_args; 742 sizemask = 0; 743 } 744 #elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64 745 for (i = 0; i < nargs; ++i) { 746 int is_64bit = sizemask & (1 << (i+1)*2); 747 int is_signed = sizemask & (2 << (i+1)*2); 748 if (!is_64bit) { 749 TCGv_i64 temp = tcg_temp_new_i64(); 750 TCGv_i64 orig = MAKE_TCGV_I64(args[i]); 751 if (is_signed) { 752 tcg_gen_ext32s_i64(temp, orig); 753 } else { 754 tcg_gen_ext32u_i64(temp, orig); 755 } 756 args[i] = GET_TCGV_I64(temp); 757 } 758 } 759 #endif /* TCG_TARGET_EXTEND_ARGS */ 760 761 pi_first = pi = s->gen_next_parm_idx; 762 if (ret != TCG_CALL_DUMMY_ARG) { 763 #if defined(__sparc__) && !defined(__arch64__) \ 764 && !defined(CONFIG_TCG_INTERPRETER) 765 if (orig_sizemask & 1) { 766 /* The 32-bit ABI is going to return the 64-bit value in 767 the %o0/%o1 register pair. Prepare for this by using 768 two return temporaries, and reassemble below. */ 769 retl = tcg_temp_new_i64(); 770 reth = tcg_temp_new_i64(); 771 s->gen_opparam_buf[pi++] = GET_TCGV_I64(reth); 772 s->gen_opparam_buf[pi++] = GET_TCGV_I64(retl); 773 nb_rets = 2; 774 } else { 775 s->gen_opparam_buf[pi++] = ret; 776 nb_rets = 1; 777 } 778 #else 779 if (TCG_TARGET_REG_BITS < 64 && (sizemask & 1)) { 780 #ifdef HOST_WORDS_BIGENDIAN 781 s->gen_opparam_buf[pi++] = ret + 1; 782 s->gen_opparam_buf[pi++] = ret; 783 #else 784 s->gen_opparam_buf[pi++] = ret; 785 s->gen_opparam_buf[pi++] = ret + 1; 786 #endif 787 nb_rets = 2; 788 } else { 789 s->gen_opparam_buf[pi++] = ret; 790 nb_rets = 1; 791 } 792 #endif 793 } else { 794 nb_rets = 0; 795 } 796 real_args = 0; 797 for (i = 0; i < nargs; i++) { 798 int is_64bit = sizemask & (1 << (i+1)*2); 799 if (TCG_TARGET_REG_BITS < 64 && is_64bit) { 800 #ifdef TCG_TARGET_CALL_ALIGN_ARGS 801 /* some targets want aligned 64 bit args */ 802 if (real_args & 1) { 803 s->gen_opparam_buf[pi++] = TCG_CALL_DUMMY_ARG; 804 real_args++; 805 } 806 #endif 807 /* If stack grows up, then we will be placing successive 808 arguments at lower addresses, which means we need to 809 reverse the order compared to how we would normally 810 treat either big or little-endian. For those arguments 811 that will wind up in registers, this still works for 812 HPPA (the only current STACK_GROWSUP target) since the 813 argument registers are *also* allocated in decreasing 814 order. If another such target is added, this logic may 815 have to get more complicated to differentiate between 816 stack arguments and register arguments. */ 817 #if defined(HOST_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP) 818 s->gen_opparam_buf[pi++] = args[i] + 1; 819 s->gen_opparam_buf[pi++] = args[i]; 820 #else 821 s->gen_opparam_buf[pi++] = args[i]; 822 s->gen_opparam_buf[pi++] = args[i] + 1; 823 #endif 824 real_args += 2; 825 continue; 826 } 827 828 s->gen_opparam_buf[pi++] = args[i]; 829 real_args++; 830 } 831 s->gen_opparam_buf[pi++] = (uintptr_t)func; 832 s->gen_opparam_buf[pi++] = flags; 833 834 i = s->gen_next_op_idx; 835 tcg_debug_assert(i < OPC_BUF_SIZE); 836 tcg_debug_assert(pi <= OPPARAM_BUF_SIZE); 837 838 /* Set links for sequential allocation during translation. */ 839 s->gen_op_buf[i] = (TCGOp){ 840 .opc = INDEX_op_call, 841 .callo = nb_rets, 842 .calli = real_args, 843 .args = pi_first, 844 .prev = i - 1, 845 .next = i + 1 846 }; 847 848 /* Make sure the calli field didn't overflow. */ 849 tcg_debug_assert(s->gen_op_buf[i].calli == real_args); 850 851 s->gen_last_op_idx = i; 852 s->gen_next_op_idx = i + 1; 853 s->gen_next_parm_idx = pi; 854 855 #if defined(__sparc__) && !defined(__arch64__) \ 856 && !defined(CONFIG_TCG_INTERPRETER) 857 /* Free all of the parts we allocated above. */ 858 for (i = real_args = 0; i < orig_nargs; ++i) { 859 int is_64bit = orig_sizemask & (1 << (i+1)*2); 860 if (is_64bit) { 861 TCGv_i32 h = MAKE_TCGV_I32(args[real_args++]); 862 TCGv_i32 l = MAKE_TCGV_I32(args[real_args++]); 863 tcg_temp_free_i32(h); 864 tcg_temp_free_i32(l); 865 } else { 866 real_args++; 867 } 868 } 869 if (orig_sizemask & 1) { 870 /* The 32-bit ABI returned two 32-bit pieces. Re-assemble them. 871 Note that describing these as TCGv_i64 eliminates an unnecessary 872 zero-extension that tcg_gen_concat_i32_i64 would create. */ 873 tcg_gen_concat32_i64(MAKE_TCGV_I64(ret), retl, reth); 874 tcg_temp_free_i64(retl); 875 tcg_temp_free_i64(reth); 876 } 877 #elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64 878 for (i = 0; i < nargs; ++i) { 879 int is_64bit = sizemask & (1 << (i+1)*2); 880 if (!is_64bit) { 881 TCGv_i64 temp = MAKE_TCGV_I64(args[i]); 882 tcg_temp_free_i64(temp); 883 } 884 } 885 #endif /* TCG_TARGET_EXTEND_ARGS */ 886 } 887 888 static void tcg_reg_alloc_start(TCGContext *s) 889 { 890 int i; 891 TCGTemp *ts; 892 for(i = 0; i < s->nb_globals; i++) { 893 ts = &s->temps[i]; 894 if (ts->fixed_reg) { 895 ts->val_type = TEMP_VAL_REG; 896 } else { 897 ts->val_type = TEMP_VAL_MEM; 898 } 899 } 900 for(i = s->nb_globals; i < s->nb_temps; i++) { 901 ts = &s->temps[i]; 902 if (ts->temp_local) { 903 ts->val_type = TEMP_VAL_MEM; 904 } else { 905 ts->val_type = TEMP_VAL_DEAD; 906 } 907 ts->mem_allocated = 0; 908 ts->fixed_reg = 0; 909 } 910 for(i = 0; i < TCG_TARGET_NB_REGS; i++) { 911 s->reg_to_temp[i] = -1; 912 } 913 } 914 915 static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size, 916 int idx) 917 { 918 TCGTemp *ts; 919 920 assert(idx >= 0 && idx < s->nb_temps); 921 ts = &s->temps[idx]; 922 if (idx < s->nb_globals) { 923 pstrcpy(buf, buf_size, ts->name); 924 } else { 925 if (ts->temp_local) 926 snprintf(buf, buf_size, "loc%d", idx - s->nb_globals); 927 else 928 snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals); 929 } 930 return buf; 931 } 932 933 char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg) 934 { 935 return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg)); 936 } 937 938 char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg) 939 { 940 return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg)); 941 } 942 943 /* Find helper name. */ 944 static inline const char *tcg_find_helper(TCGContext *s, uintptr_t val) 945 { 946 const char *ret = NULL; 947 if (s->helpers) { 948 TCGHelperInfo *info = g_hash_table_lookup(s->helpers, (gpointer)val); 949 if (info) { 950 ret = info->name; 951 } 952 } 953 return ret; 954 } 955 956 static const char * const cond_name[] = 957 { 958 [TCG_COND_NEVER] = "never", 959 [TCG_COND_ALWAYS] = "always", 960 [TCG_COND_EQ] = "eq", 961 [TCG_COND_NE] = "ne", 962 [TCG_COND_LT] = "lt", 963 [TCG_COND_GE] = "ge", 964 [TCG_COND_LE] = "le", 965 [TCG_COND_GT] = "gt", 966 [TCG_COND_LTU] = "ltu", 967 [TCG_COND_GEU] = "geu", 968 [TCG_COND_LEU] = "leu", 969 [TCG_COND_GTU] = "gtu" 970 }; 971 972 static const char * const ldst_name[] = 973 { 974 [MO_UB] = "ub", 975 [MO_SB] = "sb", 976 [MO_LEUW] = "leuw", 977 [MO_LESW] = "lesw", 978 [MO_LEUL] = "leul", 979 [MO_LESL] = "lesl", 980 [MO_LEQ] = "leq", 981 [MO_BEUW] = "beuw", 982 [MO_BESW] = "besw", 983 [MO_BEUL] = "beul", 984 [MO_BESL] = "besl", 985 [MO_BEQ] = "beq", 986 }; 987 988 void tcg_dump_ops(TCGContext *s) 989 { 990 char buf[128]; 991 TCGOp *op; 992 int oi; 993 994 for (oi = s->gen_first_op_idx; oi >= 0; oi = op->next) { 995 int i, k, nb_oargs, nb_iargs, nb_cargs; 996 const TCGOpDef *def; 997 const TCGArg *args; 998 TCGOpcode c; 999 1000 op = &s->gen_op_buf[oi]; 1001 c = op->opc; 1002 def = &tcg_op_defs[c]; 1003 args = &s->gen_opparam_buf[op->args]; 1004 1005 if (c == INDEX_op_debug_insn_start) { 1006 uint64_t pc; 1007 #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS 1008 pc = ((uint64_t)args[1] << 32) | args[0]; 1009 #else 1010 pc = args[0]; 1011 #endif 1012 if (oi != s->gen_first_op_idx) { 1013 qemu_log("\n"); 1014 } 1015 qemu_log(" ---- 0x%" PRIx64, pc); 1016 } else if (c == INDEX_op_call) { 1017 /* variable number of arguments */ 1018 nb_oargs = op->callo; 1019 nb_iargs = op->calli; 1020 nb_cargs = def->nb_cargs; 1021 1022 /* function name, flags, out args */ 1023 qemu_log(" %s %s,$0x%" TCG_PRIlx ",$%d", def->name, 1024 tcg_find_helper(s, args[nb_oargs + nb_iargs]), 1025 args[nb_oargs + nb_iargs + 1], nb_oargs); 1026 for (i = 0; i < nb_oargs; i++) { 1027 qemu_log(",%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), 1028 args[i])); 1029 } 1030 for (i = 0; i < nb_iargs; i++) { 1031 TCGArg arg = args[nb_oargs + i]; 1032 const char *t = "<dummy>"; 1033 if (arg != TCG_CALL_DUMMY_ARG) { 1034 t = tcg_get_arg_str_idx(s, buf, sizeof(buf), arg); 1035 } 1036 qemu_log(",%s", t); 1037 } 1038 } else { 1039 qemu_log(" %s ", def->name); 1040 1041 nb_oargs = def->nb_oargs; 1042 nb_iargs = def->nb_iargs; 1043 nb_cargs = def->nb_cargs; 1044 1045 k = 0; 1046 for (i = 0; i < nb_oargs; i++) { 1047 if (k != 0) { 1048 qemu_log(","); 1049 } 1050 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), 1051 args[k++])); 1052 } 1053 for (i = 0; i < nb_iargs; i++) { 1054 if (k != 0) { 1055 qemu_log(","); 1056 } 1057 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), 1058 args[k++])); 1059 } 1060 switch (c) { 1061 case INDEX_op_brcond_i32: 1062 case INDEX_op_setcond_i32: 1063 case INDEX_op_movcond_i32: 1064 case INDEX_op_brcond2_i32: 1065 case INDEX_op_setcond2_i32: 1066 case INDEX_op_brcond_i64: 1067 case INDEX_op_setcond_i64: 1068 case INDEX_op_movcond_i64: 1069 if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) { 1070 qemu_log(",%s", cond_name[args[k++]]); 1071 } else { 1072 qemu_log(",$0x%" TCG_PRIlx, args[k++]); 1073 } 1074 i = 1; 1075 break; 1076 case INDEX_op_qemu_ld_i32: 1077 case INDEX_op_qemu_st_i32: 1078 case INDEX_op_qemu_ld_i64: 1079 case INDEX_op_qemu_st_i64: 1080 if (args[k] < ARRAY_SIZE(ldst_name) && ldst_name[args[k]]) { 1081 qemu_log(",%s", ldst_name[args[k++]]); 1082 } else { 1083 qemu_log(",$0x%" TCG_PRIlx, args[k++]); 1084 } 1085 i = 1; 1086 break; 1087 default: 1088 i = 0; 1089 break; 1090 } 1091 for (; i < nb_cargs; i++) { 1092 if (k != 0) { 1093 qemu_log(","); 1094 } 1095 qemu_log("$0x%" TCG_PRIlx, args[k++]); 1096 } 1097 } 1098 qemu_log("\n"); 1099 } 1100 } 1101 1102 /* we give more priority to constraints with less registers */ 1103 static int get_constraint_priority(const TCGOpDef *def, int k) 1104 { 1105 const TCGArgConstraint *arg_ct; 1106 1107 int i, n; 1108 arg_ct = &def->args_ct[k]; 1109 if (arg_ct->ct & TCG_CT_ALIAS) { 1110 /* an alias is equivalent to a single register */ 1111 n = 1; 1112 } else { 1113 if (!(arg_ct->ct & TCG_CT_REG)) 1114 return 0; 1115 n = 0; 1116 for(i = 0; i < TCG_TARGET_NB_REGS; i++) { 1117 if (tcg_regset_test_reg(arg_ct->u.regs, i)) 1118 n++; 1119 } 1120 } 1121 return TCG_TARGET_NB_REGS - n + 1; 1122 } 1123 1124 /* sort from highest priority to lowest */ 1125 static void sort_constraints(TCGOpDef *def, int start, int n) 1126 { 1127 int i, j, p1, p2, tmp; 1128 1129 for(i = 0; i < n; i++) 1130 def->sorted_args[start + i] = start + i; 1131 if (n <= 1) 1132 return; 1133 for(i = 0; i < n - 1; i++) { 1134 for(j = i + 1; j < n; j++) { 1135 p1 = get_constraint_priority(def, def->sorted_args[start + i]); 1136 p2 = get_constraint_priority(def, def->sorted_args[start + j]); 1137 if (p1 < p2) { 1138 tmp = def->sorted_args[start + i]; 1139 def->sorted_args[start + i] = def->sorted_args[start + j]; 1140 def->sorted_args[start + j] = tmp; 1141 } 1142 } 1143 } 1144 } 1145 1146 void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs) 1147 { 1148 TCGOpcode op; 1149 TCGOpDef *def; 1150 const char *ct_str; 1151 int i, nb_args; 1152 1153 for(;;) { 1154 if (tdefs->op == (TCGOpcode)-1) 1155 break; 1156 op = tdefs->op; 1157 assert((unsigned)op < NB_OPS); 1158 def = &tcg_op_defs[op]; 1159 #if defined(CONFIG_DEBUG_TCG) 1160 /* Duplicate entry in op definitions? */ 1161 assert(!def->used); 1162 def->used = 1; 1163 #endif 1164 nb_args = def->nb_iargs + def->nb_oargs; 1165 for(i = 0; i < nb_args; i++) { 1166 ct_str = tdefs->args_ct_str[i]; 1167 /* Incomplete TCGTargetOpDef entry? */ 1168 assert(ct_str != NULL); 1169 tcg_regset_clear(def->args_ct[i].u.regs); 1170 def->args_ct[i].ct = 0; 1171 if (ct_str[0] >= '0' && ct_str[0] <= '9') { 1172 int oarg; 1173 oarg = ct_str[0] - '0'; 1174 assert(oarg < def->nb_oargs); 1175 assert(def->args_ct[oarg].ct & TCG_CT_REG); 1176 /* TCG_CT_ALIAS is for the output arguments. The input 1177 argument is tagged with TCG_CT_IALIAS. */ 1178 def->args_ct[i] = def->args_ct[oarg]; 1179 def->args_ct[oarg].ct = TCG_CT_ALIAS; 1180 def->args_ct[oarg].alias_index = i; 1181 def->args_ct[i].ct |= TCG_CT_IALIAS; 1182 def->args_ct[i].alias_index = oarg; 1183 } else { 1184 for(;;) { 1185 if (*ct_str == '\0') 1186 break; 1187 switch(*ct_str) { 1188 case 'i': 1189 def->args_ct[i].ct |= TCG_CT_CONST; 1190 ct_str++; 1191 break; 1192 default: 1193 if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) { 1194 fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n", 1195 ct_str, i, def->name); 1196 exit(1); 1197 } 1198 } 1199 } 1200 } 1201 } 1202 1203 /* TCGTargetOpDef entry with too much information? */ 1204 assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL); 1205 1206 /* sort the constraints (XXX: this is just an heuristic) */ 1207 sort_constraints(def, 0, def->nb_oargs); 1208 sort_constraints(def, def->nb_oargs, def->nb_iargs); 1209 1210 #if 0 1211 { 1212 int i; 1213 1214 printf("%s: sorted=", def->name); 1215 for(i = 0; i < def->nb_oargs + def->nb_iargs; i++) 1216 printf(" %d", def->sorted_args[i]); 1217 printf("\n"); 1218 } 1219 #endif 1220 tdefs++; 1221 } 1222 1223 #if defined(CONFIG_DEBUG_TCG) 1224 i = 0; 1225 for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) { 1226 const TCGOpDef *def = &tcg_op_defs[op]; 1227 if (def->flags & TCG_OPF_NOT_PRESENT) { 1228 /* Wrong entry in op definitions? */ 1229 if (def->used) { 1230 fprintf(stderr, "Invalid op definition for %s\n", def->name); 1231 i = 1; 1232 } 1233 } else { 1234 /* Missing entry in op definitions? */ 1235 if (!def->used) { 1236 fprintf(stderr, "Missing op definition for %s\n", def->name); 1237 i = 1; 1238 } 1239 } 1240 } 1241 if (i == 1) { 1242 tcg_abort(); 1243 } 1244 #endif 1245 } 1246 1247 void tcg_op_remove(TCGContext *s, TCGOp *op) 1248 { 1249 int next = op->next; 1250 int prev = op->prev; 1251 1252 if (next >= 0) { 1253 s->gen_op_buf[next].prev = prev; 1254 } else { 1255 s->gen_last_op_idx = prev; 1256 } 1257 if (prev >= 0) { 1258 s->gen_op_buf[prev].next = next; 1259 } else { 1260 s->gen_first_op_idx = next; 1261 } 1262 1263 memset(op, -1, sizeof(*op)); 1264 1265 #ifdef CONFIG_PROFILER 1266 s->del_op_count++; 1267 #endif 1268 } 1269 1270 #ifdef USE_LIVENESS_ANALYSIS 1271 /* liveness analysis: end of function: all temps are dead, and globals 1272 should be in memory. */ 1273 static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps, 1274 uint8_t *mem_temps) 1275 { 1276 memset(dead_temps, 1, s->nb_temps); 1277 memset(mem_temps, 1, s->nb_globals); 1278 memset(mem_temps + s->nb_globals, 0, s->nb_temps - s->nb_globals); 1279 } 1280 1281 /* liveness analysis: end of basic block: all temps are dead, globals 1282 and local temps should be in memory. */ 1283 static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps, 1284 uint8_t *mem_temps) 1285 { 1286 int i; 1287 1288 memset(dead_temps, 1, s->nb_temps); 1289 memset(mem_temps, 1, s->nb_globals); 1290 for(i = s->nb_globals; i < s->nb_temps; i++) { 1291 mem_temps[i] = s->temps[i].temp_local; 1292 } 1293 } 1294 1295 /* Liveness analysis : update the opc_dead_args array to tell if a 1296 given input arguments is dead. Instructions updating dead 1297 temporaries are removed. */ 1298 static void tcg_liveness_analysis(TCGContext *s) 1299 { 1300 uint8_t *dead_temps, *mem_temps; 1301 int oi, oi_prev, nb_ops; 1302 1303 nb_ops = s->gen_next_op_idx; 1304 s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t)); 1305 s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t)); 1306 1307 dead_temps = tcg_malloc(s->nb_temps); 1308 mem_temps = tcg_malloc(s->nb_temps); 1309 tcg_la_func_end(s, dead_temps, mem_temps); 1310 1311 for (oi = s->gen_last_op_idx; oi >= 0; oi = oi_prev) { 1312 int i, nb_iargs, nb_oargs; 1313 TCGOpcode opc_new, opc_new2; 1314 bool have_opc_new2; 1315 uint16_t dead_args; 1316 uint8_t sync_args; 1317 TCGArg arg; 1318 1319 TCGOp * const op = &s->gen_op_buf[oi]; 1320 TCGArg * const args = &s->gen_opparam_buf[op->args]; 1321 TCGOpcode opc = op->opc; 1322 const TCGOpDef *def = &tcg_op_defs[opc]; 1323 1324 oi_prev = op->prev; 1325 1326 switch (opc) { 1327 case INDEX_op_call: 1328 { 1329 int call_flags; 1330 1331 nb_oargs = op->callo; 1332 nb_iargs = op->calli; 1333 call_flags = args[nb_oargs + nb_iargs + 1]; 1334 1335 /* pure functions can be removed if their result is unused */ 1336 if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) { 1337 for (i = 0; i < nb_oargs; i++) { 1338 arg = args[i]; 1339 if (!dead_temps[arg] || mem_temps[arg]) { 1340 goto do_not_remove_call; 1341 } 1342 } 1343 goto do_remove; 1344 } else { 1345 do_not_remove_call: 1346 1347 /* output args are dead */ 1348 dead_args = 0; 1349 sync_args = 0; 1350 for (i = 0; i < nb_oargs; i++) { 1351 arg = args[i]; 1352 if (dead_temps[arg]) { 1353 dead_args |= (1 << i); 1354 } 1355 if (mem_temps[arg]) { 1356 sync_args |= (1 << i); 1357 } 1358 dead_temps[arg] = 1; 1359 mem_temps[arg] = 0; 1360 } 1361 1362 if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) { 1363 /* globals should be synced to memory */ 1364 memset(mem_temps, 1, s->nb_globals); 1365 } 1366 if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS | 1367 TCG_CALL_NO_READ_GLOBALS))) { 1368 /* globals should go back to memory */ 1369 memset(dead_temps, 1, s->nb_globals); 1370 } 1371 1372 /* input args are live */ 1373 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) { 1374 arg = args[i]; 1375 if (arg != TCG_CALL_DUMMY_ARG) { 1376 if (dead_temps[arg]) { 1377 dead_args |= (1 << i); 1378 } 1379 dead_temps[arg] = 0; 1380 } 1381 } 1382 s->op_dead_args[oi] = dead_args; 1383 s->op_sync_args[oi] = sync_args; 1384 } 1385 } 1386 break; 1387 case INDEX_op_debug_insn_start: 1388 break; 1389 case INDEX_op_discard: 1390 /* mark the temporary as dead */ 1391 dead_temps[args[0]] = 1; 1392 mem_temps[args[0]] = 0; 1393 break; 1394 1395 case INDEX_op_add2_i32: 1396 opc_new = INDEX_op_add_i32; 1397 goto do_addsub2; 1398 case INDEX_op_sub2_i32: 1399 opc_new = INDEX_op_sub_i32; 1400 goto do_addsub2; 1401 case INDEX_op_add2_i64: 1402 opc_new = INDEX_op_add_i64; 1403 goto do_addsub2; 1404 case INDEX_op_sub2_i64: 1405 opc_new = INDEX_op_sub_i64; 1406 do_addsub2: 1407 nb_iargs = 4; 1408 nb_oargs = 2; 1409 /* Test if the high part of the operation is dead, but not 1410 the low part. The result can be optimized to a simple 1411 add or sub. This happens often for x86_64 guest when the 1412 cpu mode is set to 32 bit. */ 1413 if (dead_temps[args[1]] && !mem_temps[args[1]]) { 1414 if (dead_temps[args[0]] && !mem_temps[args[0]]) { 1415 goto do_remove; 1416 } 1417 /* Replace the opcode and adjust the args in place, 1418 leaving 3 unused args at the end. */ 1419 op->opc = opc = opc_new; 1420 args[1] = args[2]; 1421 args[2] = args[4]; 1422 /* Fall through and mark the single-word operation live. */ 1423 nb_iargs = 2; 1424 nb_oargs = 1; 1425 } 1426 goto do_not_remove; 1427 1428 case INDEX_op_mulu2_i32: 1429 opc_new = INDEX_op_mul_i32; 1430 opc_new2 = INDEX_op_muluh_i32; 1431 have_opc_new2 = TCG_TARGET_HAS_muluh_i32; 1432 goto do_mul2; 1433 case INDEX_op_muls2_i32: 1434 opc_new = INDEX_op_mul_i32; 1435 opc_new2 = INDEX_op_mulsh_i32; 1436 have_opc_new2 = TCG_TARGET_HAS_mulsh_i32; 1437 goto do_mul2; 1438 case INDEX_op_mulu2_i64: 1439 opc_new = INDEX_op_mul_i64; 1440 opc_new2 = INDEX_op_muluh_i64; 1441 have_opc_new2 = TCG_TARGET_HAS_muluh_i64; 1442 goto do_mul2; 1443 case INDEX_op_muls2_i64: 1444 opc_new = INDEX_op_mul_i64; 1445 opc_new2 = INDEX_op_mulsh_i64; 1446 have_opc_new2 = TCG_TARGET_HAS_mulsh_i64; 1447 goto do_mul2; 1448 do_mul2: 1449 nb_iargs = 2; 1450 nb_oargs = 2; 1451 if (dead_temps[args[1]] && !mem_temps[args[1]]) { 1452 if (dead_temps[args[0]] && !mem_temps[args[0]]) { 1453 /* Both parts of the operation are dead. */ 1454 goto do_remove; 1455 } 1456 /* The high part of the operation is dead; generate the low. */ 1457 op->opc = opc = opc_new; 1458 args[1] = args[2]; 1459 args[2] = args[3]; 1460 } else if (have_opc_new2 && dead_temps[args[0]] 1461 && !mem_temps[args[0]]) { 1462 /* The low part of the operation is dead; generate the high. */ 1463 op->opc = opc = opc_new2; 1464 args[0] = args[1]; 1465 args[1] = args[2]; 1466 args[2] = args[3]; 1467 } else { 1468 goto do_not_remove; 1469 } 1470 /* Mark the single-word operation live. */ 1471 nb_oargs = 1; 1472 goto do_not_remove; 1473 1474 default: 1475 /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */ 1476 nb_iargs = def->nb_iargs; 1477 nb_oargs = def->nb_oargs; 1478 1479 /* Test if the operation can be removed because all 1480 its outputs are dead. We assume that nb_oargs == 0 1481 implies side effects */ 1482 if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) { 1483 for (i = 0; i < nb_oargs; i++) { 1484 arg = args[i]; 1485 if (!dead_temps[arg] || mem_temps[arg]) { 1486 goto do_not_remove; 1487 } 1488 } 1489 do_remove: 1490 tcg_op_remove(s, op); 1491 } else { 1492 do_not_remove: 1493 /* output args are dead */ 1494 dead_args = 0; 1495 sync_args = 0; 1496 for (i = 0; i < nb_oargs; i++) { 1497 arg = args[i]; 1498 if (dead_temps[arg]) { 1499 dead_args |= (1 << i); 1500 } 1501 if (mem_temps[arg]) { 1502 sync_args |= (1 << i); 1503 } 1504 dead_temps[arg] = 1; 1505 mem_temps[arg] = 0; 1506 } 1507 1508 /* if end of basic block, update */ 1509 if (def->flags & TCG_OPF_BB_END) { 1510 tcg_la_bb_end(s, dead_temps, mem_temps); 1511 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) { 1512 /* globals should be synced to memory */ 1513 memset(mem_temps, 1, s->nb_globals); 1514 } 1515 1516 /* input args are live */ 1517 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) { 1518 arg = args[i]; 1519 if (dead_temps[arg]) { 1520 dead_args |= (1 << i); 1521 } 1522 dead_temps[arg] = 0; 1523 } 1524 s->op_dead_args[oi] = dead_args; 1525 s->op_sync_args[oi] = sync_args; 1526 } 1527 break; 1528 } 1529 } 1530 } 1531 #else 1532 /* dummy liveness analysis */ 1533 static void tcg_liveness_analysis(TCGContext *s) 1534 { 1535 int nb_ops; 1536 nb_ops = s->gen_opc_ptr - s->gen_opc_buf; 1537 1538 s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t)); 1539 memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t)); 1540 s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t)); 1541 memset(s->op_sync_args, 0, nb_ops * sizeof(uint8_t)); 1542 } 1543 #endif 1544 1545 #ifndef NDEBUG 1546 static void dump_regs(TCGContext *s) 1547 { 1548 TCGTemp *ts; 1549 int i; 1550 char buf[64]; 1551 1552 for(i = 0; i < s->nb_temps; i++) { 1553 ts = &s->temps[i]; 1554 printf(" %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i)); 1555 switch(ts->val_type) { 1556 case TEMP_VAL_REG: 1557 printf("%s", tcg_target_reg_names[ts->reg]); 1558 break; 1559 case TEMP_VAL_MEM: 1560 printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]); 1561 break; 1562 case TEMP_VAL_CONST: 1563 printf("$0x%" TCG_PRIlx, ts->val); 1564 break; 1565 case TEMP_VAL_DEAD: 1566 printf("D"); 1567 break; 1568 default: 1569 printf("???"); 1570 break; 1571 } 1572 printf("\n"); 1573 } 1574 1575 for(i = 0; i < TCG_TARGET_NB_REGS; i++) { 1576 if (s->reg_to_temp[i] >= 0) { 1577 printf("%s: %s\n", 1578 tcg_target_reg_names[i], 1579 tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i])); 1580 } 1581 } 1582 } 1583 1584 static void check_regs(TCGContext *s) 1585 { 1586 int reg, k; 1587 TCGTemp *ts; 1588 char buf[64]; 1589 1590 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) { 1591 k = s->reg_to_temp[reg]; 1592 if (k >= 0) { 1593 ts = &s->temps[k]; 1594 if (ts->val_type != TEMP_VAL_REG || 1595 ts->reg != reg) { 1596 printf("Inconsistency for register %s:\n", 1597 tcg_target_reg_names[reg]); 1598 goto fail; 1599 } 1600 } 1601 } 1602 for(k = 0; k < s->nb_temps; k++) { 1603 ts = &s->temps[k]; 1604 if (ts->val_type == TEMP_VAL_REG && 1605 !ts->fixed_reg && 1606 s->reg_to_temp[ts->reg] != k) { 1607 printf("Inconsistency for temp %s:\n", 1608 tcg_get_arg_str_idx(s, buf, sizeof(buf), k)); 1609 fail: 1610 printf("reg state:\n"); 1611 dump_regs(s); 1612 tcg_abort(); 1613 } 1614 } 1615 } 1616 #endif 1617 1618 static void temp_allocate_frame(TCGContext *s, int temp) 1619 { 1620 TCGTemp *ts; 1621 ts = &s->temps[temp]; 1622 #if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64) 1623 /* Sparc64 stack is accessed with offset of 2047 */ 1624 s->current_frame_offset = (s->current_frame_offset + 1625 (tcg_target_long)sizeof(tcg_target_long) - 1) & 1626 ~(sizeof(tcg_target_long) - 1); 1627 #endif 1628 if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) > 1629 s->frame_end) { 1630 tcg_abort(); 1631 } 1632 ts->mem_offset = s->current_frame_offset; 1633 ts->mem_reg = s->frame_reg; 1634 ts->mem_allocated = 1; 1635 s->current_frame_offset += sizeof(tcg_target_long); 1636 } 1637 1638 /* sync register 'reg' by saving it to the corresponding temporary */ 1639 static inline void tcg_reg_sync(TCGContext *s, int reg) 1640 { 1641 TCGTemp *ts; 1642 int temp; 1643 1644 temp = s->reg_to_temp[reg]; 1645 ts = &s->temps[temp]; 1646 assert(ts->val_type == TEMP_VAL_REG); 1647 if (!ts->mem_coherent && !ts->fixed_reg) { 1648 if (!ts->mem_allocated) { 1649 temp_allocate_frame(s, temp); 1650 } 1651 tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset); 1652 } 1653 ts->mem_coherent = 1; 1654 } 1655 1656 /* free register 'reg' by spilling the corresponding temporary if necessary */ 1657 static void tcg_reg_free(TCGContext *s, int reg) 1658 { 1659 int temp; 1660 1661 temp = s->reg_to_temp[reg]; 1662 if (temp != -1) { 1663 tcg_reg_sync(s, reg); 1664 s->temps[temp].val_type = TEMP_VAL_MEM; 1665 s->reg_to_temp[reg] = -1; 1666 } 1667 } 1668 1669 /* Allocate a register belonging to reg1 & ~reg2 */ 1670 static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2) 1671 { 1672 int i, reg; 1673 TCGRegSet reg_ct; 1674 1675 tcg_regset_andnot(reg_ct, reg1, reg2); 1676 1677 /* first try free registers */ 1678 for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) { 1679 reg = tcg_target_reg_alloc_order[i]; 1680 if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1) 1681 return reg; 1682 } 1683 1684 /* XXX: do better spill choice */ 1685 for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) { 1686 reg = tcg_target_reg_alloc_order[i]; 1687 if (tcg_regset_test_reg(reg_ct, reg)) { 1688 tcg_reg_free(s, reg); 1689 return reg; 1690 } 1691 } 1692 1693 tcg_abort(); 1694 } 1695 1696 /* mark a temporary as dead. */ 1697 static inline void temp_dead(TCGContext *s, int temp) 1698 { 1699 TCGTemp *ts; 1700 1701 ts = &s->temps[temp]; 1702 if (!ts->fixed_reg) { 1703 if (ts->val_type == TEMP_VAL_REG) { 1704 s->reg_to_temp[ts->reg] = -1; 1705 } 1706 if (temp < s->nb_globals || ts->temp_local) { 1707 ts->val_type = TEMP_VAL_MEM; 1708 } else { 1709 ts->val_type = TEMP_VAL_DEAD; 1710 } 1711 } 1712 } 1713 1714 /* sync a temporary to memory. 'allocated_regs' is used in case a 1715 temporary registers needs to be allocated to store a constant. */ 1716 static inline void temp_sync(TCGContext *s, int temp, TCGRegSet allocated_regs) 1717 { 1718 TCGTemp *ts; 1719 1720 ts = &s->temps[temp]; 1721 if (!ts->fixed_reg) { 1722 switch(ts->val_type) { 1723 case TEMP_VAL_CONST: 1724 ts->reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 1725 allocated_regs); 1726 ts->val_type = TEMP_VAL_REG; 1727 s->reg_to_temp[ts->reg] = temp; 1728 ts->mem_coherent = 0; 1729 tcg_out_movi(s, ts->type, ts->reg, ts->val); 1730 /* fallthrough*/ 1731 case TEMP_VAL_REG: 1732 tcg_reg_sync(s, ts->reg); 1733 break; 1734 case TEMP_VAL_DEAD: 1735 case TEMP_VAL_MEM: 1736 break; 1737 default: 1738 tcg_abort(); 1739 } 1740 } 1741 } 1742 1743 /* save a temporary to memory. 'allocated_regs' is used in case a 1744 temporary registers needs to be allocated to store a constant. */ 1745 static inline void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs) 1746 { 1747 #ifdef USE_LIVENESS_ANALYSIS 1748 /* The liveness analysis already ensures that globals are back 1749 in memory. Keep an assert for safety. */ 1750 assert(s->temps[temp].val_type == TEMP_VAL_MEM || s->temps[temp].fixed_reg); 1751 #else 1752 temp_sync(s, temp, allocated_regs); 1753 temp_dead(s, temp); 1754 #endif 1755 } 1756 1757 /* save globals to their canonical location and assume they can be 1758 modified be the following code. 'allocated_regs' is used in case a 1759 temporary registers needs to be allocated to store a constant. */ 1760 static void save_globals(TCGContext *s, TCGRegSet allocated_regs) 1761 { 1762 int i; 1763 1764 for(i = 0; i < s->nb_globals; i++) { 1765 temp_save(s, i, allocated_regs); 1766 } 1767 } 1768 1769 /* sync globals to their canonical location and assume they can be 1770 read by the following code. 'allocated_regs' is used in case a 1771 temporary registers needs to be allocated to store a constant. */ 1772 static void sync_globals(TCGContext *s, TCGRegSet allocated_regs) 1773 { 1774 int i; 1775 1776 for (i = 0; i < s->nb_globals; i++) { 1777 #ifdef USE_LIVENESS_ANALYSIS 1778 assert(s->temps[i].val_type != TEMP_VAL_REG || s->temps[i].fixed_reg || 1779 s->temps[i].mem_coherent); 1780 #else 1781 temp_sync(s, i, allocated_regs); 1782 #endif 1783 } 1784 } 1785 1786 /* at the end of a basic block, we assume all temporaries are dead and 1787 all globals are stored at their canonical location. */ 1788 static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs) 1789 { 1790 TCGTemp *ts; 1791 int i; 1792 1793 for(i = s->nb_globals; i < s->nb_temps; i++) { 1794 ts = &s->temps[i]; 1795 if (ts->temp_local) { 1796 temp_save(s, i, allocated_regs); 1797 } else { 1798 #ifdef USE_LIVENESS_ANALYSIS 1799 /* The liveness analysis already ensures that temps are dead. 1800 Keep an assert for safety. */ 1801 assert(ts->val_type == TEMP_VAL_DEAD); 1802 #else 1803 temp_dead(s, i); 1804 #endif 1805 } 1806 } 1807 1808 save_globals(s, allocated_regs); 1809 } 1810 1811 #define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1) 1812 #define NEED_SYNC_ARG(n) ((sync_args >> (n)) & 1) 1813 1814 static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args, 1815 uint16_t dead_args, uint8_t sync_args) 1816 { 1817 TCGTemp *ots; 1818 tcg_target_ulong val; 1819 1820 ots = &s->temps[args[0]]; 1821 val = args[1]; 1822 1823 if (ots->fixed_reg) { 1824 /* for fixed registers, we do not do any constant 1825 propagation */ 1826 tcg_out_movi(s, ots->type, ots->reg, val); 1827 } else { 1828 /* The movi is not explicitly generated here */ 1829 if (ots->val_type == TEMP_VAL_REG) 1830 s->reg_to_temp[ots->reg] = -1; 1831 ots->val_type = TEMP_VAL_CONST; 1832 ots->val = val; 1833 } 1834 if (NEED_SYNC_ARG(0)) { 1835 temp_sync(s, args[0], s->reserved_regs); 1836 } 1837 if (IS_DEAD_ARG(0)) { 1838 temp_dead(s, args[0]); 1839 } 1840 } 1841 1842 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, 1843 const TCGArg *args, uint16_t dead_args, 1844 uint8_t sync_args) 1845 { 1846 TCGRegSet allocated_regs; 1847 TCGTemp *ts, *ots; 1848 TCGType otype, itype; 1849 1850 tcg_regset_set(allocated_regs, s->reserved_regs); 1851 ots = &s->temps[args[0]]; 1852 ts = &s->temps[args[1]]; 1853 1854 /* Note that otype != itype for no-op truncation. */ 1855 otype = ots->type; 1856 itype = ts->type; 1857 1858 /* If the source value is not in a register, and we're going to be 1859 forced to have it in a register in order to perform the copy, 1860 then copy the SOURCE value into its own register first. That way 1861 we don't have to reload SOURCE the next time it is used. */ 1862 if (((NEED_SYNC_ARG(0) || ots->fixed_reg) && ts->val_type != TEMP_VAL_REG) 1863 || ts->val_type == TEMP_VAL_MEM) { 1864 ts->reg = tcg_reg_alloc(s, tcg_target_available_regs[itype], 1865 allocated_regs); 1866 if (ts->val_type == TEMP_VAL_MEM) { 1867 tcg_out_ld(s, itype, ts->reg, ts->mem_reg, ts->mem_offset); 1868 ts->mem_coherent = 1; 1869 } else if (ts->val_type == TEMP_VAL_CONST) { 1870 tcg_out_movi(s, itype, ts->reg, ts->val); 1871 } 1872 s->reg_to_temp[ts->reg] = args[1]; 1873 ts->val_type = TEMP_VAL_REG; 1874 } 1875 1876 if (IS_DEAD_ARG(0) && !ots->fixed_reg) { 1877 /* mov to a non-saved dead register makes no sense (even with 1878 liveness analysis disabled). */ 1879 assert(NEED_SYNC_ARG(0)); 1880 /* The code above should have moved the temp to a register. */ 1881 assert(ts->val_type == TEMP_VAL_REG); 1882 if (!ots->mem_allocated) { 1883 temp_allocate_frame(s, args[0]); 1884 } 1885 tcg_out_st(s, otype, ts->reg, ots->mem_reg, ots->mem_offset); 1886 if (IS_DEAD_ARG(1)) { 1887 temp_dead(s, args[1]); 1888 } 1889 temp_dead(s, args[0]); 1890 } else if (ts->val_type == TEMP_VAL_CONST) { 1891 /* propagate constant */ 1892 if (ots->val_type == TEMP_VAL_REG) { 1893 s->reg_to_temp[ots->reg] = -1; 1894 } 1895 ots->val_type = TEMP_VAL_CONST; 1896 ots->val = ts->val; 1897 } else { 1898 /* The code in the first if block should have moved the 1899 temp to a register. */ 1900 assert(ts->val_type == TEMP_VAL_REG); 1901 if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) { 1902 /* the mov can be suppressed */ 1903 if (ots->val_type == TEMP_VAL_REG) { 1904 s->reg_to_temp[ots->reg] = -1; 1905 } 1906 ots->reg = ts->reg; 1907 temp_dead(s, args[1]); 1908 } else { 1909 if (ots->val_type != TEMP_VAL_REG) { 1910 /* When allocating a new register, make sure to not spill the 1911 input one. */ 1912 tcg_regset_set_reg(allocated_regs, ts->reg); 1913 ots->reg = tcg_reg_alloc(s, tcg_target_available_regs[otype], 1914 allocated_regs); 1915 } 1916 tcg_out_mov(s, otype, ots->reg, ts->reg); 1917 } 1918 ots->val_type = TEMP_VAL_REG; 1919 ots->mem_coherent = 0; 1920 s->reg_to_temp[ots->reg] = args[0]; 1921 if (NEED_SYNC_ARG(0)) { 1922 tcg_reg_sync(s, ots->reg); 1923 } 1924 } 1925 } 1926 1927 static void tcg_reg_alloc_op(TCGContext *s, 1928 const TCGOpDef *def, TCGOpcode opc, 1929 const TCGArg *args, uint16_t dead_args, 1930 uint8_t sync_args) 1931 { 1932 TCGRegSet allocated_regs; 1933 int i, k, nb_iargs, nb_oargs, reg; 1934 TCGArg arg; 1935 const TCGArgConstraint *arg_ct; 1936 TCGTemp *ts; 1937 TCGArg new_args[TCG_MAX_OP_ARGS]; 1938 int const_args[TCG_MAX_OP_ARGS]; 1939 1940 nb_oargs = def->nb_oargs; 1941 nb_iargs = def->nb_iargs; 1942 1943 /* copy constants */ 1944 memcpy(new_args + nb_oargs + nb_iargs, 1945 args + nb_oargs + nb_iargs, 1946 sizeof(TCGArg) * def->nb_cargs); 1947 1948 /* satisfy input constraints */ 1949 tcg_regset_set(allocated_regs, s->reserved_regs); 1950 for(k = 0; k < nb_iargs; k++) { 1951 i = def->sorted_args[nb_oargs + k]; 1952 arg = args[i]; 1953 arg_ct = &def->args_ct[i]; 1954 ts = &s->temps[arg]; 1955 if (ts->val_type == TEMP_VAL_MEM) { 1956 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); 1957 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset); 1958 ts->val_type = TEMP_VAL_REG; 1959 ts->reg = reg; 1960 ts->mem_coherent = 1; 1961 s->reg_to_temp[reg] = arg; 1962 } else if (ts->val_type == TEMP_VAL_CONST) { 1963 if (tcg_target_const_match(ts->val, ts->type, arg_ct)) { 1964 /* constant is OK for instruction */ 1965 const_args[i] = 1; 1966 new_args[i] = ts->val; 1967 goto iarg_end; 1968 } else { 1969 /* need to move to a register */ 1970 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); 1971 tcg_out_movi(s, ts->type, reg, ts->val); 1972 ts->val_type = TEMP_VAL_REG; 1973 ts->reg = reg; 1974 ts->mem_coherent = 0; 1975 s->reg_to_temp[reg] = arg; 1976 } 1977 } 1978 assert(ts->val_type == TEMP_VAL_REG); 1979 if (arg_ct->ct & TCG_CT_IALIAS) { 1980 if (ts->fixed_reg) { 1981 /* if fixed register, we must allocate a new register 1982 if the alias is not the same register */ 1983 if (arg != args[arg_ct->alias_index]) 1984 goto allocate_in_reg; 1985 } else { 1986 /* if the input is aliased to an output and if it is 1987 not dead after the instruction, we must allocate 1988 a new register and move it */ 1989 if (!IS_DEAD_ARG(i)) { 1990 goto allocate_in_reg; 1991 } 1992 } 1993 } 1994 reg = ts->reg; 1995 if (tcg_regset_test_reg(arg_ct->u.regs, reg)) { 1996 /* nothing to do : the constraint is satisfied */ 1997 } else { 1998 allocate_in_reg: 1999 /* allocate a new register matching the constraint 2000 and move the temporary register into it */ 2001 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); 2002 tcg_out_mov(s, ts->type, reg, ts->reg); 2003 } 2004 new_args[i] = reg; 2005 const_args[i] = 0; 2006 tcg_regset_set_reg(allocated_regs, reg); 2007 iarg_end: ; 2008 } 2009 2010 /* mark dead temporaries and free the associated registers */ 2011 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) { 2012 if (IS_DEAD_ARG(i)) { 2013 temp_dead(s, args[i]); 2014 } 2015 } 2016 2017 if (def->flags & TCG_OPF_BB_END) { 2018 tcg_reg_alloc_bb_end(s, allocated_regs); 2019 } else { 2020 if (def->flags & TCG_OPF_CALL_CLOBBER) { 2021 /* XXX: permit generic clobber register list ? */ 2022 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) { 2023 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) { 2024 tcg_reg_free(s, reg); 2025 } 2026 } 2027 } 2028 if (def->flags & TCG_OPF_SIDE_EFFECTS) { 2029 /* sync globals if the op has side effects and might trigger 2030 an exception. */ 2031 sync_globals(s, allocated_regs); 2032 } 2033 2034 /* satisfy the output constraints */ 2035 tcg_regset_set(allocated_regs, s->reserved_regs); 2036 for(k = 0; k < nb_oargs; k++) { 2037 i = def->sorted_args[k]; 2038 arg = args[i]; 2039 arg_ct = &def->args_ct[i]; 2040 ts = &s->temps[arg]; 2041 if (arg_ct->ct & TCG_CT_ALIAS) { 2042 reg = new_args[arg_ct->alias_index]; 2043 } else { 2044 /* if fixed register, we try to use it */ 2045 reg = ts->reg; 2046 if (ts->fixed_reg && 2047 tcg_regset_test_reg(arg_ct->u.regs, reg)) { 2048 goto oarg_end; 2049 } 2050 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); 2051 } 2052 tcg_regset_set_reg(allocated_regs, reg); 2053 /* if a fixed register is used, then a move will be done afterwards */ 2054 if (!ts->fixed_reg) { 2055 if (ts->val_type == TEMP_VAL_REG) { 2056 s->reg_to_temp[ts->reg] = -1; 2057 } 2058 ts->val_type = TEMP_VAL_REG; 2059 ts->reg = reg; 2060 /* temp value is modified, so the value kept in memory is 2061 potentially not the same */ 2062 ts->mem_coherent = 0; 2063 s->reg_to_temp[reg] = arg; 2064 } 2065 oarg_end: 2066 new_args[i] = reg; 2067 } 2068 } 2069 2070 /* emit instruction */ 2071 tcg_out_op(s, opc, new_args, const_args); 2072 2073 /* move the outputs in the correct register if needed */ 2074 for(i = 0; i < nb_oargs; i++) { 2075 ts = &s->temps[args[i]]; 2076 reg = new_args[i]; 2077 if (ts->fixed_reg && ts->reg != reg) { 2078 tcg_out_mov(s, ts->type, ts->reg, reg); 2079 } 2080 if (NEED_SYNC_ARG(i)) { 2081 tcg_reg_sync(s, reg); 2082 } 2083 if (IS_DEAD_ARG(i)) { 2084 temp_dead(s, args[i]); 2085 } 2086 } 2087 } 2088 2089 #ifdef TCG_TARGET_STACK_GROWSUP 2090 #define STACK_DIR(x) (-(x)) 2091 #else 2092 #define STACK_DIR(x) (x) 2093 #endif 2094 2095 static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs, 2096 const TCGArg * const args, uint16_t dead_args, 2097 uint8_t sync_args) 2098 { 2099 int flags, nb_regs, i, reg; 2100 TCGArg arg; 2101 TCGTemp *ts; 2102 intptr_t stack_offset; 2103 size_t call_stack_size; 2104 tcg_insn_unit *func_addr; 2105 int allocate_args; 2106 TCGRegSet allocated_regs; 2107 2108 func_addr = (tcg_insn_unit *)(intptr_t)args[nb_oargs + nb_iargs]; 2109 flags = args[nb_oargs + nb_iargs + 1]; 2110 2111 nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs); 2112 if (nb_regs > nb_iargs) { 2113 nb_regs = nb_iargs; 2114 } 2115 2116 /* assign stack slots first */ 2117 call_stack_size = (nb_iargs - nb_regs) * sizeof(tcg_target_long); 2118 call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & 2119 ~(TCG_TARGET_STACK_ALIGN - 1); 2120 allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE); 2121 if (allocate_args) { 2122 /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed, 2123 preallocate call stack */ 2124 tcg_abort(); 2125 } 2126 2127 stack_offset = TCG_TARGET_CALL_STACK_OFFSET; 2128 for(i = nb_regs; i < nb_iargs; i++) { 2129 arg = args[nb_oargs + i]; 2130 #ifdef TCG_TARGET_STACK_GROWSUP 2131 stack_offset -= sizeof(tcg_target_long); 2132 #endif 2133 if (arg != TCG_CALL_DUMMY_ARG) { 2134 ts = &s->temps[arg]; 2135 if (ts->val_type == TEMP_VAL_REG) { 2136 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset); 2137 } else if (ts->val_type == TEMP_VAL_MEM) { 2138 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 2139 s->reserved_regs); 2140 /* XXX: not correct if reading values from the stack */ 2141 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset); 2142 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset); 2143 } else if (ts->val_type == TEMP_VAL_CONST) { 2144 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 2145 s->reserved_regs); 2146 /* XXX: sign extend may be needed on some targets */ 2147 tcg_out_movi(s, ts->type, reg, ts->val); 2148 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset); 2149 } else { 2150 tcg_abort(); 2151 } 2152 } 2153 #ifndef TCG_TARGET_STACK_GROWSUP 2154 stack_offset += sizeof(tcg_target_long); 2155 #endif 2156 } 2157 2158 /* assign input registers */ 2159 tcg_regset_set(allocated_regs, s->reserved_regs); 2160 for(i = 0; i < nb_regs; i++) { 2161 arg = args[nb_oargs + i]; 2162 if (arg != TCG_CALL_DUMMY_ARG) { 2163 ts = &s->temps[arg]; 2164 reg = tcg_target_call_iarg_regs[i]; 2165 tcg_reg_free(s, reg); 2166 if (ts->val_type == TEMP_VAL_REG) { 2167 if (ts->reg != reg) { 2168 tcg_out_mov(s, ts->type, reg, ts->reg); 2169 } 2170 } else if (ts->val_type == TEMP_VAL_MEM) { 2171 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset); 2172 } else if (ts->val_type == TEMP_VAL_CONST) { 2173 /* XXX: sign extend ? */ 2174 tcg_out_movi(s, ts->type, reg, ts->val); 2175 } else { 2176 tcg_abort(); 2177 } 2178 tcg_regset_set_reg(allocated_regs, reg); 2179 } 2180 } 2181 2182 /* mark dead temporaries and free the associated registers */ 2183 for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) { 2184 if (IS_DEAD_ARG(i)) { 2185 temp_dead(s, args[i]); 2186 } 2187 } 2188 2189 /* clobber call registers */ 2190 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) { 2191 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) { 2192 tcg_reg_free(s, reg); 2193 } 2194 } 2195 2196 /* Save globals if they might be written by the helper, sync them if 2197 they might be read. */ 2198 if (flags & TCG_CALL_NO_READ_GLOBALS) { 2199 /* Nothing to do */ 2200 } else if (flags & TCG_CALL_NO_WRITE_GLOBALS) { 2201 sync_globals(s, allocated_regs); 2202 } else { 2203 save_globals(s, allocated_regs); 2204 } 2205 2206 tcg_out_call(s, func_addr); 2207 2208 /* assign output registers and emit moves if needed */ 2209 for(i = 0; i < nb_oargs; i++) { 2210 arg = args[i]; 2211 ts = &s->temps[arg]; 2212 reg = tcg_target_call_oarg_regs[i]; 2213 assert(s->reg_to_temp[reg] == -1); 2214 2215 if (ts->fixed_reg) { 2216 if (ts->reg != reg) { 2217 tcg_out_mov(s, ts->type, ts->reg, reg); 2218 } 2219 } else { 2220 if (ts->val_type == TEMP_VAL_REG) { 2221 s->reg_to_temp[ts->reg] = -1; 2222 } 2223 ts->val_type = TEMP_VAL_REG; 2224 ts->reg = reg; 2225 ts->mem_coherent = 0; 2226 s->reg_to_temp[reg] = arg; 2227 if (NEED_SYNC_ARG(i)) { 2228 tcg_reg_sync(s, reg); 2229 } 2230 if (IS_DEAD_ARG(i)) { 2231 temp_dead(s, args[i]); 2232 } 2233 } 2234 } 2235 } 2236 2237 #ifdef CONFIG_PROFILER 2238 2239 static int64_t tcg_table_op_count[NB_OPS]; 2240 2241 void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf) 2242 { 2243 int i; 2244 2245 for (i = 0; i < NB_OPS; i++) { 2246 cpu_fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, 2247 tcg_table_op_count[i]); 2248 } 2249 } 2250 #else 2251 void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf) 2252 { 2253 cpu_fprintf(f, "[TCG profiler not compiled]\n"); 2254 } 2255 #endif 2256 2257 2258 static inline int tcg_gen_code_common(TCGContext *s, 2259 tcg_insn_unit *gen_code_buf, 2260 long search_pc) 2261 { 2262 int oi, oi_next; 2263 2264 #ifdef DEBUG_DISAS 2265 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) { 2266 qemu_log("OP:\n"); 2267 tcg_dump_ops(s); 2268 qemu_log("\n"); 2269 } 2270 #endif 2271 2272 #ifdef CONFIG_PROFILER 2273 s->opt_time -= profile_getclock(); 2274 #endif 2275 2276 #ifdef USE_TCG_OPTIMIZATIONS 2277 tcg_optimize(s); 2278 #endif 2279 2280 #ifdef CONFIG_PROFILER 2281 s->opt_time += profile_getclock(); 2282 s->la_time -= profile_getclock(); 2283 #endif 2284 2285 tcg_liveness_analysis(s); 2286 2287 #ifdef CONFIG_PROFILER 2288 s->la_time += profile_getclock(); 2289 #endif 2290 2291 #ifdef DEBUG_DISAS 2292 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) { 2293 qemu_log("OP after optimization and liveness analysis:\n"); 2294 tcg_dump_ops(s); 2295 qemu_log("\n"); 2296 } 2297 #endif 2298 2299 tcg_reg_alloc_start(s); 2300 2301 s->code_buf = gen_code_buf; 2302 s->code_ptr = gen_code_buf; 2303 2304 tcg_out_tb_init(s); 2305 2306 for (oi = s->gen_first_op_idx; oi >= 0; oi = oi_next) { 2307 TCGOp * const op = &s->gen_op_buf[oi]; 2308 TCGArg * const args = &s->gen_opparam_buf[op->args]; 2309 TCGOpcode opc = op->opc; 2310 const TCGOpDef *def = &tcg_op_defs[opc]; 2311 uint16_t dead_args = s->op_dead_args[oi]; 2312 uint8_t sync_args = s->op_sync_args[oi]; 2313 2314 oi_next = op->next; 2315 #ifdef CONFIG_PROFILER 2316 tcg_table_op_count[opc]++; 2317 #endif 2318 2319 switch (opc) { 2320 case INDEX_op_mov_i32: 2321 case INDEX_op_mov_i64: 2322 tcg_reg_alloc_mov(s, def, args, dead_args, sync_args); 2323 break; 2324 case INDEX_op_movi_i32: 2325 case INDEX_op_movi_i64: 2326 tcg_reg_alloc_movi(s, args, dead_args, sync_args); 2327 break; 2328 case INDEX_op_debug_insn_start: 2329 break; 2330 case INDEX_op_discard: 2331 temp_dead(s, args[0]); 2332 break; 2333 case INDEX_op_set_label: 2334 tcg_reg_alloc_bb_end(s, s->reserved_regs); 2335 tcg_out_label(s, args[0], s->code_ptr); 2336 break; 2337 case INDEX_op_call: 2338 tcg_reg_alloc_call(s, op->callo, op->calli, args, 2339 dead_args, sync_args); 2340 break; 2341 default: 2342 /* Sanity check that we've not introduced any unhandled opcodes. */ 2343 if (def->flags & TCG_OPF_NOT_PRESENT) { 2344 tcg_abort(); 2345 } 2346 /* Note: in order to speed up the code, it would be much 2347 faster to have specialized register allocator functions for 2348 some common argument patterns */ 2349 tcg_reg_alloc_op(s, def, opc, args, dead_args, sync_args); 2350 break; 2351 } 2352 if (search_pc >= 0 && search_pc < tcg_current_code_size(s)) { 2353 return oi; 2354 } 2355 #ifndef NDEBUG 2356 check_regs(s); 2357 #endif 2358 } 2359 2360 /* Generate TB finalization at the end of block */ 2361 tcg_out_tb_finalize(s); 2362 return -1; 2363 } 2364 2365 int tcg_gen_code(TCGContext *s, tcg_insn_unit *gen_code_buf) 2366 { 2367 #ifdef CONFIG_PROFILER 2368 { 2369 int n; 2370 2371 n = s->gen_last_op_idx + 1; 2372 s->op_count += n; 2373 if (n > s->op_count_max) { 2374 s->op_count_max = n; 2375 } 2376 2377 n = s->nb_temps; 2378 s->temp_count += n; 2379 if (n > s->temp_count_max) { 2380 s->temp_count_max = n; 2381 } 2382 } 2383 #endif 2384 2385 tcg_gen_code_common(s, gen_code_buf, -1); 2386 2387 /* flush instruction cache */ 2388 flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr); 2389 2390 return tcg_current_code_size(s); 2391 } 2392 2393 /* Return the index of the micro operation such as the pc after is < 2394 offset bytes from the start of the TB. The contents of gen_code_buf must 2395 not be changed, though writing the same values is ok. 2396 Return -1 if not found. */ 2397 int tcg_gen_code_search_pc(TCGContext *s, tcg_insn_unit *gen_code_buf, 2398 long offset) 2399 { 2400 return tcg_gen_code_common(s, gen_code_buf, offset); 2401 } 2402 2403 #ifdef CONFIG_PROFILER 2404 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf) 2405 { 2406 TCGContext *s = &tcg_ctx; 2407 int64_t tot; 2408 2409 tot = s->interm_time + s->code_time; 2410 cpu_fprintf(f, "JIT cycles %" PRId64 " (%0.3f s at 2.4 GHz)\n", 2411 tot, tot / 2.4e9); 2412 cpu_fprintf(f, "translated TBs %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n", 2413 s->tb_count, 2414 s->tb_count1 - s->tb_count, 2415 s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0); 2416 cpu_fprintf(f, "avg ops/TB %0.1f max=%d\n", 2417 s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max); 2418 cpu_fprintf(f, "deleted ops/TB %0.2f\n", 2419 s->tb_count ? 2420 (double)s->del_op_count / s->tb_count : 0); 2421 cpu_fprintf(f, "avg temps/TB %0.2f max=%d\n", 2422 s->tb_count ? 2423 (double)s->temp_count / s->tb_count : 0, 2424 s->temp_count_max); 2425 2426 cpu_fprintf(f, "cycles/op %0.1f\n", 2427 s->op_count ? (double)tot / s->op_count : 0); 2428 cpu_fprintf(f, "cycles/in byte %0.1f\n", 2429 s->code_in_len ? (double)tot / s->code_in_len : 0); 2430 cpu_fprintf(f, "cycles/out byte %0.1f\n", 2431 s->code_out_len ? (double)tot / s->code_out_len : 0); 2432 if (tot == 0) 2433 tot = 1; 2434 cpu_fprintf(f, " gen_interm time %0.1f%%\n", 2435 (double)s->interm_time / tot * 100.0); 2436 cpu_fprintf(f, " gen_code time %0.1f%%\n", 2437 (double)s->code_time / tot * 100.0); 2438 cpu_fprintf(f, "optim./code time %0.1f%%\n", 2439 (double)s->opt_time / (s->code_time ? s->code_time : 1) 2440 * 100.0); 2441 cpu_fprintf(f, "liveness/code time %0.1f%%\n", 2442 (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0); 2443 cpu_fprintf(f, "cpu_restore count %" PRId64 "\n", 2444 s->restore_count); 2445 cpu_fprintf(f, " avg cycles %0.1f\n", 2446 s->restore_count ? (double)s->restore_time / s->restore_count : 0); 2447 } 2448 #else 2449 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf) 2450 { 2451 cpu_fprintf(f, "[TCG profiler not compiled]\n"); 2452 } 2453 #endif 2454 2455 #ifdef ELF_HOST_MACHINE 2456 /* In order to use this feature, the backend needs to do three things: 2457 2458 (1) Define ELF_HOST_MACHINE to indicate both what value to 2459 put into the ELF image and to indicate support for the feature. 2460 2461 (2) Define tcg_register_jit. This should create a buffer containing 2462 the contents of a .debug_frame section that describes the post- 2463 prologue unwind info for the tcg machine. 2464 2465 (3) Call tcg_register_jit_int, with the constructed .debug_frame. 2466 */ 2467 2468 /* Begin GDB interface. THE FOLLOWING MUST MATCH GDB DOCS. */ 2469 typedef enum { 2470 JIT_NOACTION = 0, 2471 JIT_REGISTER_FN, 2472 JIT_UNREGISTER_FN 2473 } jit_actions_t; 2474 2475 struct jit_code_entry { 2476 struct jit_code_entry *next_entry; 2477 struct jit_code_entry *prev_entry; 2478 const void *symfile_addr; 2479 uint64_t symfile_size; 2480 }; 2481 2482 struct jit_descriptor { 2483 uint32_t version; 2484 uint32_t action_flag; 2485 struct jit_code_entry *relevant_entry; 2486 struct jit_code_entry *first_entry; 2487 }; 2488 2489 void __jit_debug_register_code(void) __attribute__((noinline)); 2490 void __jit_debug_register_code(void) 2491 { 2492 asm(""); 2493 } 2494 2495 /* Must statically initialize the version, because GDB may check 2496 the version before we can set it. */ 2497 struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 }; 2498 2499 /* End GDB interface. */ 2500 2501 static int find_string(const char *strtab, const char *str) 2502 { 2503 const char *p = strtab + 1; 2504 2505 while (1) { 2506 if (strcmp(p, str) == 0) { 2507 return p - strtab; 2508 } 2509 p += strlen(p) + 1; 2510 } 2511 } 2512 2513 static void tcg_register_jit_int(void *buf_ptr, size_t buf_size, 2514 const void *debug_frame, 2515 size_t debug_frame_size) 2516 { 2517 struct __attribute__((packed)) DebugInfo { 2518 uint32_t len; 2519 uint16_t version; 2520 uint32_t abbrev; 2521 uint8_t ptr_size; 2522 uint8_t cu_die; 2523 uint16_t cu_lang; 2524 uintptr_t cu_low_pc; 2525 uintptr_t cu_high_pc; 2526 uint8_t fn_die; 2527 char fn_name[16]; 2528 uintptr_t fn_low_pc; 2529 uintptr_t fn_high_pc; 2530 uint8_t cu_eoc; 2531 }; 2532 2533 struct ElfImage { 2534 ElfW(Ehdr) ehdr; 2535 ElfW(Phdr) phdr; 2536 ElfW(Shdr) shdr[7]; 2537 ElfW(Sym) sym[2]; 2538 struct DebugInfo di; 2539 uint8_t da[24]; 2540 char str[80]; 2541 }; 2542 2543 struct ElfImage *img; 2544 2545 static const struct ElfImage img_template = { 2546 .ehdr = { 2547 .e_ident[EI_MAG0] = ELFMAG0, 2548 .e_ident[EI_MAG1] = ELFMAG1, 2549 .e_ident[EI_MAG2] = ELFMAG2, 2550 .e_ident[EI_MAG3] = ELFMAG3, 2551 .e_ident[EI_CLASS] = ELF_CLASS, 2552 .e_ident[EI_DATA] = ELF_DATA, 2553 .e_ident[EI_VERSION] = EV_CURRENT, 2554 .e_type = ET_EXEC, 2555 .e_machine = ELF_HOST_MACHINE, 2556 .e_version = EV_CURRENT, 2557 .e_phoff = offsetof(struct ElfImage, phdr), 2558 .e_shoff = offsetof(struct ElfImage, shdr), 2559 .e_ehsize = sizeof(ElfW(Shdr)), 2560 .e_phentsize = sizeof(ElfW(Phdr)), 2561 .e_phnum = 1, 2562 .e_shentsize = sizeof(ElfW(Shdr)), 2563 .e_shnum = ARRAY_SIZE(img->shdr), 2564 .e_shstrndx = ARRAY_SIZE(img->shdr) - 1, 2565 #ifdef ELF_HOST_FLAGS 2566 .e_flags = ELF_HOST_FLAGS, 2567 #endif 2568 #ifdef ELF_OSABI 2569 .e_ident[EI_OSABI] = ELF_OSABI, 2570 #endif 2571 }, 2572 .phdr = { 2573 .p_type = PT_LOAD, 2574 .p_flags = PF_X, 2575 }, 2576 .shdr = { 2577 [0] = { .sh_type = SHT_NULL }, 2578 /* Trick: The contents of code_gen_buffer are not present in 2579 this fake ELF file; that got allocated elsewhere. Therefore 2580 we mark .text as SHT_NOBITS (similar to .bss) so that readers 2581 will not look for contents. We can record any address. */ 2582 [1] = { /* .text */ 2583 .sh_type = SHT_NOBITS, 2584 .sh_flags = SHF_EXECINSTR | SHF_ALLOC, 2585 }, 2586 [2] = { /* .debug_info */ 2587 .sh_type = SHT_PROGBITS, 2588 .sh_offset = offsetof(struct ElfImage, di), 2589 .sh_size = sizeof(struct DebugInfo), 2590 }, 2591 [3] = { /* .debug_abbrev */ 2592 .sh_type = SHT_PROGBITS, 2593 .sh_offset = offsetof(struct ElfImage, da), 2594 .sh_size = sizeof(img->da), 2595 }, 2596 [4] = { /* .debug_frame */ 2597 .sh_type = SHT_PROGBITS, 2598 .sh_offset = sizeof(struct ElfImage), 2599 }, 2600 [5] = { /* .symtab */ 2601 .sh_type = SHT_SYMTAB, 2602 .sh_offset = offsetof(struct ElfImage, sym), 2603 .sh_size = sizeof(img->sym), 2604 .sh_info = 1, 2605 .sh_link = ARRAY_SIZE(img->shdr) - 1, 2606 .sh_entsize = sizeof(ElfW(Sym)), 2607 }, 2608 [6] = { /* .strtab */ 2609 .sh_type = SHT_STRTAB, 2610 .sh_offset = offsetof(struct ElfImage, str), 2611 .sh_size = sizeof(img->str), 2612 } 2613 }, 2614 .sym = { 2615 [1] = { /* code_gen_buffer */ 2616 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC), 2617 .st_shndx = 1, 2618 } 2619 }, 2620 .di = { 2621 .len = sizeof(struct DebugInfo) - 4, 2622 .version = 2, 2623 .ptr_size = sizeof(void *), 2624 .cu_die = 1, 2625 .cu_lang = 0x8001, /* DW_LANG_Mips_Assembler */ 2626 .fn_die = 2, 2627 .fn_name = "code_gen_buffer" 2628 }, 2629 .da = { 2630 1, /* abbrev number (the cu) */ 2631 0x11, 1, /* DW_TAG_compile_unit, has children */ 2632 0x13, 0x5, /* DW_AT_language, DW_FORM_data2 */ 2633 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */ 2634 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */ 2635 0, 0, /* end of abbrev */ 2636 2, /* abbrev number (the fn) */ 2637 0x2e, 0, /* DW_TAG_subprogram, no children */ 2638 0x3, 0x8, /* DW_AT_name, DW_FORM_string */ 2639 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */ 2640 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */ 2641 0, 0, /* end of abbrev */ 2642 0 /* no more abbrev */ 2643 }, 2644 .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0" 2645 ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer", 2646 }; 2647 2648 /* We only need a single jit entry; statically allocate it. */ 2649 static struct jit_code_entry one_entry; 2650 2651 uintptr_t buf = (uintptr_t)buf_ptr; 2652 size_t img_size = sizeof(struct ElfImage) + debug_frame_size; 2653 DebugFrameHeader *dfh; 2654 2655 img = g_malloc(img_size); 2656 *img = img_template; 2657 2658 img->phdr.p_vaddr = buf; 2659 img->phdr.p_paddr = buf; 2660 img->phdr.p_memsz = buf_size; 2661 2662 img->shdr[1].sh_name = find_string(img->str, ".text"); 2663 img->shdr[1].sh_addr = buf; 2664 img->shdr[1].sh_size = buf_size; 2665 2666 img->shdr[2].sh_name = find_string(img->str, ".debug_info"); 2667 img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev"); 2668 2669 img->shdr[4].sh_name = find_string(img->str, ".debug_frame"); 2670 img->shdr[4].sh_size = debug_frame_size; 2671 2672 img->shdr[5].sh_name = find_string(img->str, ".symtab"); 2673 img->shdr[6].sh_name = find_string(img->str, ".strtab"); 2674 2675 img->sym[1].st_name = find_string(img->str, "code_gen_buffer"); 2676 img->sym[1].st_value = buf; 2677 img->sym[1].st_size = buf_size; 2678 2679 img->di.cu_low_pc = buf; 2680 img->di.cu_high_pc = buf + buf_size; 2681 img->di.fn_low_pc = buf; 2682 img->di.fn_high_pc = buf + buf_size; 2683 2684 dfh = (DebugFrameHeader *)(img + 1); 2685 memcpy(dfh, debug_frame, debug_frame_size); 2686 dfh->fde.func_start = buf; 2687 dfh->fde.func_len = buf_size; 2688 2689 #ifdef DEBUG_JIT 2690 /* Enable this block to be able to debug the ELF image file creation. 2691 One can use readelf, objdump, or other inspection utilities. */ 2692 { 2693 FILE *f = fopen("/tmp/qemu.jit", "w+b"); 2694 if (f) { 2695 if (fwrite(img, img_size, 1, f) != img_size) { 2696 /* Avoid stupid unused return value warning for fwrite. */ 2697 } 2698 fclose(f); 2699 } 2700 } 2701 #endif 2702 2703 one_entry.symfile_addr = img; 2704 one_entry.symfile_size = img_size; 2705 2706 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN; 2707 __jit_debug_descriptor.relevant_entry = &one_entry; 2708 __jit_debug_descriptor.first_entry = &one_entry; 2709 __jit_debug_register_code(); 2710 } 2711 #else 2712 /* No support for the feature. Provide the entry point expected by exec.c, 2713 and implement the internal function we declared earlier. */ 2714 2715 static void tcg_register_jit_int(void *buf, size_t size, 2716 const void *debug_frame, 2717 size_t debug_frame_size) 2718 { 2719 } 2720 2721 void tcg_register_jit(void *buf, size_t buf_size) 2722 { 2723 } 2724 #endif /* ELF_HOST_MACHINE */ 2725