リビジョン | 40ae5c62ebaaf7d9d3b93b88c2d32bf6342f7889 (tree) |
---|---|
日時 | 2016-02-09 08:45:34 |
作者 | Richard Henderson <rth@twid...> |
コミッター | Richard Henderson |
tcg: Introduce temp_load
Unify all of the places that realize a temporary into a register.
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
@@ -1707,6 +1707,35 @@ static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2) | ||
1707 | 1707 | tcg_abort(); |
1708 | 1708 | } |
1709 | 1709 | |
1710 | +/* Make sure the temporary is in a register. If needed, allocate the register | |
1711 | + from DESIRED while avoiding ALLOCATED. */ | |
1712 | +static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs, | |
1713 | + TCGRegSet allocated_regs) | |
1714 | +{ | |
1715 | + TCGReg reg; | |
1716 | + | |
1717 | + switch (ts->val_type) { | |
1718 | + case TEMP_VAL_REG: | |
1719 | + return; | |
1720 | + case TEMP_VAL_CONST: | |
1721 | + reg = tcg_reg_alloc(s, desired_regs, allocated_regs); | |
1722 | + tcg_out_movi(s, ts->type, reg, ts->val); | |
1723 | + ts->mem_coherent = 0; | |
1724 | + break; | |
1725 | + case TEMP_VAL_MEM: | |
1726 | + reg = tcg_reg_alloc(s, desired_regs, allocated_regs); | |
1727 | + tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset); | |
1728 | + ts->mem_coherent = 1; | |
1729 | + break; | |
1730 | + case TEMP_VAL_DEAD: | |
1731 | + default: | |
1732 | + tcg_abort(); | |
1733 | + } | |
1734 | + ts->reg = reg; | |
1735 | + ts->val_type = TEMP_VAL_REG; | |
1736 | + s->reg_to_temp[reg] = ts; | |
1737 | +} | |
1738 | + | |
1710 | 1739 | /* mark a temporary as dead. */ |
1711 | 1740 | static inline void temp_dead(TCGContext *s, TCGTemp *ts) |
1712 | 1741 | { |
@@ -1729,13 +1758,8 @@ static void temp_sync(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs) | ||
1729 | 1758 | } |
1730 | 1759 | switch (ts->val_type) { |
1731 | 1760 | case TEMP_VAL_CONST: |
1732 | - ts->reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], | |
1733 | - allocated_regs); | |
1734 | - ts->val_type = TEMP_VAL_REG; | |
1735 | - s->reg_to_temp[ts->reg] = ts; | |
1736 | - ts->mem_coherent = 0; | |
1737 | - tcg_out_movi(s, ts->type, ts->reg, ts->val); | |
1738 | - /* fallthrough*/ | |
1761 | + temp_load(s, ts, tcg_target_available_regs[ts->type], allocated_regs); | |
1762 | + /* fallthrough */ | |
1739 | 1763 | case TEMP_VAL_REG: |
1740 | 1764 | tcg_reg_sync(s, ts->reg); |
1741 | 1765 | break; |
@@ -1871,17 +1895,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, | ||
1871 | 1895 | we don't have to reload SOURCE the next time it is used. */ |
1872 | 1896 | if (((NEED_SYNC_ARG(0) || ots->fixed_reg) && ts->val_type != TEMP_VAL_REG) |
1873 | 1897 | || ts->val_type == TEMP_VAL_MEM) { |
1874 | - ts->reg = tcg_reg_alloc(s, tcg_target_available_regs[itype], | |
1875 | - allocated_regs); | |
1876 | - if (ts->val_type == TEMP_VAL_MEM) { | |
1877 | - tcg_out_ld(s, itype, ts->reg, ts->mem_base->reg, ts->mem_offset); | |
1878 | - ts->mem_coherent = 1; | |
1879 | - } else if (ts->val_type == TEMP_VAL_CONST) { | |
1880 | - tcg_out_movi(s, itype, ts->reg, ts->val); | |
1881 | - ts->mem_coherent = 0; | |
1882 | - } | |
1883 | - s->reg_to_temp[ts->reg] = ts; | |
1884 | - ts->val_type = TEMP_VAL_REG; | |
1898 | + temp_load(s, ts, tcg_target_available_regs[itype], allocated_regs); | |
1885 | 1899 | } |
1886 | 1900 | |
1887 | 1901 | if (IS_DEAD_ARG(0) && !ots->fixed_reg) { |
@@ -1967,30 +1981,17 @@ static void tcg_reg_alloc_op(TCGContext *s, | ||
1967 | 1981 | arg = args[i]; |
1968 | 1982 | arg_ct = &def->args_ct[i]; |
1969 | 1983 | ts = &s->temps[arg]; |
1970 | - if (ts->val_type == TEMP_VAL_MEM) { | |
1971 | - reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); | |
1972 | - tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset); | |
1973 | - ts->val_type = TEMP_VAL_REG; | |
1974 | - ts->reg = reg; | |
1975 | - ts->mem_coherent = 1; | |
1976 | - s->reg_to_temp[reg] = ts; | |
1977 | - } else if (ts->val_type == TEMP_VAL_CONST) { | |
1978 | - if (tcg_target_const_match(ts->val, ts->type, arg_ct)) { | |
1979 | - /* constant is OK for instruction */ | |
1980 | - const_args[i] = 1; | |
1981 | - new_args[i] = ts->val; | |
1982 | - goto iarg_end; | |
1983 | - } else { | |
1984 | - /* need to move to a register */ | |
1985 | - reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); | |
1986 | - tcg_out_movi(s, ts->type, reg, ts->val); | |
1987 | - ts->val_type = TEMP_VAL_REG; | |
1988 | - ts->reg = reg; | |
1989 | - ts->mem_coherent = 0; | |
1990 | - s->reg_to_temp[reg] = ts; | |
1991 | - } | |
1984 | + | |
1985 | + if (ts->val_type == TEMP_VAL_CONST | |
1986 | + && tcg_target_const_match(ts->val, ts->type, arg_ct)) { | |
1987 | + /* constant is OK for instruction */ | |
1988 | + const_args[i] = 1; | |
1989 | + new_args[i] = ts->val; | |
1990 | + goto iarg_end; | |
1992 | 1991 | } |
1993 | - assert(ts->val_type == TEMP_VAL_REG); | |
1992 | + | |
1993 | + temp_load(s, ts, arg_ct->u.regs, allocated_regs); | |
1994 | + | |
1994 | 1995 | if (arg_ct->ct & TCG_CT_IALIAS) { |
1995 | 1996 | if (ts->fixed_reg) { |
1996 | 1997 | /* if fixed register, we must allocate a new register |
@@ -2158,23 +2159,9 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs, | ||
2158 | 2159 | #endif |
2159 | 2160 | if (arg != TCG_CALL_DUMMY_ARG) { |
2160 | 2161 | ts = &s->temps[arg]; |
2161 | - if (ts->val_type == TEMP_VAL_REG) { | |
2162 | - tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset); | |
2163 | - } else if (ts->val_type == TEMP_VAL_MEM) { | |
2164 | - reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], | |
2165 | - s->reserved_regs); | |
2166 | - /* XXX: not correct if reading values from the stack */ | |
2167 | - tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset); | |
2168 | - tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset); | |
2169 | - } else if (ts->val_type == TEMP_VAL_CONST) { | |
2170 | - reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], | |
2171 | - s->reserved_regs); | |
2172 | - /* XXX: sign extend may be needed on some targets */ | |
2173 | - tcg_out_movi(s, ts->type, reg, ts->val); | |
2174 | - tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset); | |
2175 | - } else { | |
2176 | - tcg_abort(); | |
2177 | - } | |
2162 | + temp_load(s, ts, tcg_target_available_regs[ts->type], | |
2163 | + s->reserved_regs); | |
2164 | + tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset); | |
2178 | 2165 | } |
2179 | 2166 | #ifndef TCG_TARGET_STACK_GROWSUP |
2180 | 2167 | stack_offset += sizeof(tcg_target_long); |
@@ -2189,18 +2176,19 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs, | ||
2189 | 2176 | ts = &s->temps[arg]; |
2190 | 2177 | reg = tcg_target_call_iarg_regs[i]; |
2191 | 2178 | tcg_reg_free(s, reg); |
2179 | + | |
2192 | 2180 | if (ts->val_type == TEMP_VAL_REG) { |
2193 | 2181 | if (ts->reg != reg) { |
2194 | 2182 | tcg_out_mov(s, ts->type, reg, ts->reg); |
2195 | 2183 | } |
2196 | - } else if (ts->val_type == TEMP_VAL_MEM) { | |
2197 | - tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset); | |
2198 | - } else if (ts->val_type == TEMP_VAL_CONST) { | |
2199 | - /* XXX: sign extend ? */ | |
2200 | - tcg_out_movi(s, ts->type, reg, ts->val); | |
2201 | 2184 | } else { |
2202 | - tcg_abort(); | |
2185 | + TCGRegSet arg_set; | |
2186 | + | |
2187 | + tcg_regset_clear(arg_set); | |
2188 | + tcg_regset_set_reg(arg_set, reg); | |
2189 | + temp_load(s, ts, arg_set, allocated_regs); | |
2203 | 2190 | } |
2191 | + | |
2204 | 2192 | tcg_regset_set_reg(allocated_regs, reg); |
2205 | 2193 | } |
2206 | 2194 | } |