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