Changeset 37689 in vbox for trunk/src/recompiler/tcg/tcg.c
- Timestamp:
- Jun 29, 2011 4:01:23 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/recompiler/tcg/tcg.c
r37676 r37689 28 28 #include "config.h" 29 29 30 #if ndef CONFIG_DEBUG_TCG30 #if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG) 31 31 /* define it to suppress various consistency checks (faster) */ 32 32 #define NDEBUG … … 53 53 #include "cache-utils.h" 54 54 #include "host-utils.h" 55 #include "qemu-timer.h" 55 56 56 57 /* Note: the long term plan is to reduce the dependancies on the QEMU … … 72 73 * Liveness analysis doesn't work well with 32-bit hosts and 64-bit targets, 73 74 * second element of the register pair to store 64-bit value is considered 74 * dead, it seems. 75 * @todo: fix it in compiler 76 */ 75 * dead, it seems. */ 76 /** @todo re-test this */ 77 77 # if defined(TARGET_X86_64) && (TCG_TARGET_REG_BITS == 32) 78 78 # undef USE_LIVENESS_ANALYSIS … … 80 80 #endif /* VBOX */ 81 81 82 static void tcg_target_init(TCGContext *s); 83 static void tcg_target_qemu_prologue(TCGContext *s); 82 84 static void patch_reloc(uint8_t *code_ptr, int type, 83 85 tcg_target_long value, tcg_target_long addend); 84 86 85 87 static TCGOpDef tcg_op_defs[] = { 86 #define DEF(s, n, copy_size) { #s, 0, 0, n, n, 0, copy_size }, 87 #ifndef VBOX 88 #define DEF2(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags, 0 }, 89 #else /* VBOX */ 90 # define DEF2(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags, 0, 0, 0 }, 91 #endif /* VBOX */ 88 #define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags }, 92 89 #include "tcg-opc.h" 93 90 #undef DEF 94 #undef DEF295 91 }; 96 92 … … 121 117 /* label relocation processing */ 122 118 123 void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,124 int label_index, long addend)119 static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type, 120 int label_index, long addend) 125 121 { 126 122 TCGLabel *l; … … 261 257 262 258 tcg_target_init(s); 263 259 } 260 261 void tcg_prologue_init(TCGContext *s) 262 { 264 263 /* init global prologue and epilogue */ 265 264 s->code_buf = code_gen_prologue; … … 575 574 int sizemask, TCGArg ret, int nargs, TCGArg *args) 576 575 { 576 #ifdef TCG_TARGET_I386 577 577 int call_type; 578 #endif 578 579 int i; 579 580 int real_args; 580 581 int nb_rets; 581 582 TCGArg *nparam; 583 584 #if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64 585 for (i = 0; i < nargs; ++i) { 586 int is_64bit = sizemask & (1 << (i+1)*2); 587 int is_signed = sizemask & (2 << (i+1)*2); 588 if (!is_64bit) { 589 TCGv_i64 temp = tcg_temp_new_i64(); 590 TCGv_i64 orig = MAKE_TCGV_I64(args[i]); 591 if (is_signed) { 592 tcg_gen_ext32s_i64(temp, orig); 593 } else { 594 tcg_gen_ext32u_i64(temp, orig); 595 } 596 args[i] = GET_TCGV_I64(temp); 597 } 598 } 599 #endif /* TCG_TARGET_EXTEND_ARGS */ 600 582 601 *gen_opc_ptr++ = INDEX_op_call; 583 602 nparam = gen_opparam_ptr++; 603 #ifdef TCG_TARGET_I386 584 604 call_type = (flags & TCG_CALL_TYPE_MASK); 605 #endif 585 606 if (ret != TCG_CALL_DUMMY_ARG) { 586 607 #if TCG_TARGET_REG_BITS < 64 … … 606 627 for (i = 0; i < nargs; i++) { 607 628 #if TCG_TARGET_REG_BITS < 64 608 if (sizemask & (2 << i)) { 629 int is_64bit = sizemask & (1 << (i+1)*2); 630 if (is_64bit) { 609 631 #ifdef TCG_TARGET_I386 610 632 /* REGPARM case: if the third parameter is 64 bit, it is … … 622 644 } 623 645 #endif 624 #ifdef TCG_TARGET_WORDS_BIGENDIAN 646 /* If stack grows up, then we will be placing successive 647 arguments at lower addresses, which means we need to 648 reverse the order compared to how we would normally 649 treat either big or little-endian. For those arguments 650 that will wind up in registers, this still works for 651 HPPA (the only current STACK_GROWSUP target) since the 652 argument registers are *also* allocated in decreasing 653 order. If another such target is added, this logic may 654 have to get more complicated to differentiate between 655 stack arguments and register arguments. */ 656 #if defined(TCG_TARGET_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP) 625 657 *gen_opparam_ptr++ = args[i] + 1; 626 658 *gen_opparam_ptr++ = args[i]; … … 630 662 #endif 631 663 real_args += 2; 632 } else633 #endif 634 { 635 *gen_opparam_ptr++ = args[i]; 636 real_args++;637 }664 continue; 665 } 666 #endif /* TCG_TARGET_REG_BITS < 64 */ 667 668 *gen_opparam_ptr++ = args[i]; 669 real_args++; 638 670 } 639 671 *gen_opparam_ptr++ = GET_TCGV_PTR(func); … … 645 677 /* total parameters, needed to go backward in the instruction stream */ 646 678 *gen_opparam_ptr++ = 1 + nb_rets + real_args + 3; 679 680 #if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64 681 for (i = 0; i < nargs; ++i) { 682 int is_64bit = sizemask & (1 << (i+1)*2); 683 if (!is_64bit) { 684 TCGv_i64 temp = MAKE_TCGV_I64(args[i]); 685 tcg_temp_free_i64(temp); 686 } 687 } 688 #endif /* TCG_TARGET_EXTEND_ARGS */ 647 689 } 648 690 … … 696 738 #endif 697 739 740 698 741 static void tcg_reg_alloc_start(TCGContext *s) 699 742 { … … 813 856 const TCGArg *args; 814 857 TCGArg arg; 815 int c, i, k, nb_oargs, nb_iargs, nb_cargs, first_insn; 858 TCGOpcode c; 859 int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn; 816 860 const TCGOpDef *def; 817 861 char buf[128]; … … 919 963 tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++])); 920 964 } 921 if (c == INDEX_op_brcond_i32 965 switch (c) { 966 case INDEX_op_brcond_i32: 922 967 #if TCG_TARGET_REG_BITS == 32 923 || c == INDEX_op_brcond2_i32968 case INDEX_op_brcond2_i32: 924 969 #elif TCG_TARGET_REG_BITS == 64 925 || c == INDEX_op_brcond_i64 926 #endif 927 ) { 970 case INDEX_op_brcond_i64: 971 #endif 972 case INDEX_op_setcond_i32: 973 #if TCG_TARGET_REG_BITS == 32 974 case INDEX_op_setcond2_i32: 975 #elif TCG_TARGET_REG_BITS == 64 976 case INDEX_op_setcond_i64: 977 #endif 928 978 if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) 929 979 fprintf(outfile, ",%s", cond_name[args[k++]]); … … 931 981 fprintf(outfile, ",$0x%" TCG_PRIlx, args[k++]); 932 982 i = 1; 933 }934 else983 break; 984 default: 935 985 i = 0; 986 break; 987 } 936 988 for(; i < nb_cargs; i++) { 937 989 if (k != 0) … … 992 1044 void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs) 993 1045 { 994 intop;1046 TCGOpcode op; 995 1047 TCGOpDef *def; 996 1048 const char *ct_str; … … 998 1050 999 1051 for(;;) { 1000 if (tdefs->op < 0)1052 if (tdefs->op == (TCGOpcode)-1) 1001 1053 break; 1002 1054 op = tdefs->op; 1003 1055 assert(op >= 0 && op < NB_OPS); 1004 1056 def = &tcg_op_defs[op]; 1057 #if defined(CONFIG_DEBUG_TCG) 1058 /* Duplicate entry in op definitions? */ 1059 assert(!def->used); 1060 def->used = 1; 1061 #endif 1005 1062 nb_args = def->nb_iargs + def->nb_oargs; 1006 1063 for(i = 0; i < nb_args; i++) { 1007 1064 ct_str = tdefs->args_ct_str[i]; 1065 /* Incomplete TCGTargetOpDef entry? */ 1066 assert(ct_str != NULL); 1008 1067 tcg_regset_clear(def->args_ct[i].u.regs); 1009 1068 def->args_ct[i].ct = 0; … … 1033 1092 fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n", 1034 1093 ct_str, i, def->name); 1035 #ifdef VBOX1036 tcg_exit(1);1037 #else1038 1094 exit(1); 1039 #endif1040 1095 } 1041 1096 } … … 1043 1098 } 1044 1099 } 1100 1101 /* TCGTargetOpDef entry with too much information? */ 1102 assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL); 1045 1103 1046 1104 /* sort the constraints (XXX: this is just an heuristic) */ … … 1061 1119 } 1062 1120 1121 #if defined(CONFIG_DEBUG_TCG) 1122 i = 0; 1123 for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) { 1124 if (op < INDEX_op_call || op == INDEX_op_debug_insn_start) { 1125 /* Wrong entry in op definitions? */ 1126 if (tcg_op_defs[op].used) { 1127 fprintf(stderr, "Invalid op definition for %s\n", 1128 tcg_op_defs[op].name); 1129 i = 1; 1130 } 1131 } else { 1132 /* Missing entry in op definitions? */ 1133 if (!tcg_op_defs[op].used) { 1134 fprintf(stderr, "Missing op definition for %s\n", 1135 tcg_op_defs[op].name); 1136 i = 1; 1137 } 1138 } 1139 } 1140 if (i == 1) { 1141 tcg_abort(); 1142 } 1143 #endif 1063 1144 } 1064 1145 … … 1111 1192 static void tcg_liveness_analysis(TCGContext *s) 1112 1193 { 1113 int i, op_index, op, nb_args, nb_iargs, nb_oargs, arg, nb_ops; 1194 int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops; 1195 TCGOpcode op; 1114 1196 TCGArg *args; 1115 1197 const TCGOpDef *def; … … 1259 1341 #else 1260 1342 /* dummy liveness analysis */ 1261 void tcg_liveness_analysis(TCGContext *s)1343 static void tcg_liveness_analysis(TCGContext *s) 1262 1344 { 1263 1345 int nb_ops; … … 1350 1432 if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end) 1351 1433 #else 1352 if (( unsigned)s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)1434 if ((tcg_target_long)s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end) 1353 1435 #endif 1354 1436 tcg_abort(); … … 1524 1606 } 1525 1607 if (ts->reg != reg) { 1526 tcg_out_mov(s, reg, ts->reg);1608 tcg_out_mov(s, ots->type, reg, ts->reg); 1527 1609 } 1528 1610 } … … 1556 1638 1557 1639 static void tcg_reg_alloc_op(TCGContext *s, 1558 const TCGOpDef *def, intopc,1640 const TCGOpDef *def, TCGOpcode opc, 1559 1641 const TCGArg *args, 1560 1642 unsigned int dead_iargs) … … 1629 1711 and move the temporary register into it */ 1630 1712 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); 1631 tcg_out_mov(s, reg, ts->reg);1713 tcg_out_mov(s, ts->type, reg, ts->reg); 1632 1714 } 1633 1715 new_args[i] = reg; … … 1711 1793 reg = new_args[i]; 1712 1794 if (ts->fixed_reg && ts->reg != reg) { 1713 tcg_out_mov(s, ts-> reg, reg);1795 tcg_out_mov(s, ts->type, ts->reg, reg); 1714 1796 } 1715 1797 } … … 1723 1805 1724 1806 static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, 1725 intopc, const TCGArg *args,1807 TCGOpcode opc, const TCGArg *args, 1726 1808 unsigned int dead_iargs) 1727 1809 { … … 1797 1879 if (ts->val_type == TEMP_VAL_REG) { 1798 1880 if (ts->reg != reg) { 1799 tcg_out_mov(s, reg, ts->reg);1881 tcg_out_mov(s, ts->type, reg, ts->reg); 1800 1882 } 1801 1883 } else if (ts->val_type == TEMP_VAL_MEM) { … … 1826 1908 if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) { 1827 1909 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); 1828 tcg_out_mov(s, reg, ts->reg);1910 tcg_out_mov(s, ts->type, reg, ts->reg); 1829 1911 } 1830 1912 func_arg = reg; … … 1885 1967 if (ts->fixed_reg) { 1886 1968 if (ts->reg != reg) { 1887 tcg_out_mov(s, ts-> reg, reg);1969 tcg_out_mov(s, ts->type, ts->reg, reg); 1888 1970 } 1889 1971 } else { … … 1920 2002 long search_pc) 1921 2003 { 1922 int opc, op_index; 2004 TCGOpcode opc; 2005 int op_index; 1923 2006 const TCGOpDef *def; 1924 2007 unsigned int dead_iargs;
Note:
See TracChangeset
for help on using the changeset viewer.