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