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