259 |
259 |
s->frame_reg = reg;
|
260 |
260 |
}
|
261 |
261 |
|
262 |
|
void tcg_set_macro_func(TCGContext *s, TCGMacroFunc *func)
|
263 |
|
{
|
264 |
|
s->macro_func = func;
|
265 |
|
}
|
266 |
|
|
267 |
262 |
void tcg_func_start(TCGContext *s)
|
268 |
263 |
{
|
269 |
264 |
int i;
|
... | ... | |
1120 |
1115 |
/* mark the temporary as dead */
|
1121 |
1116 |
dead_temps[args[0]] = 1;
|
1122 |
1117 |
break;
|
1123 |
|
case INDEX_op_macro_2:
|
1124 |
|
{
|
1125 |
|
int dead_args[2], macro_id;
|
1126 |
|
int saved_op_index, saved_arg_index;
|
1127 |
|
int macro_op_index, macro_arg_index;
|
1128 |
|
int macro_end_op_index, macro_end_arg_index;
|
1129 |
|
int last_nb_temps;
|
1130 |
|
|
1131 |
|
nb_args = 3;
|
1132 |
|
args -= nb_args;
|
1133 |
|
dead_args[0] = dead_temps[args[0]];
|
1134 |
|
dead_args[1] = dead_temps[args[1]];
|
1135 |
|
macro_id = args[2];
|
1136 |
|
|
1137 |
|
/* call the macro function which generate code
|
1138 |
|
depending on the live outputs */
|
1139 |
|
saved_op_index = op_index;
|
1140 |
|
saved_arg_index = args - gen_opparam_buf;
|
1141 |
|
|
1142 |
|
/* add a macro start instruction */
|
1143 |
|
*gen_opc_ptr++ = INDEX_op_macro_start;
|
1144 |
|
*gen_opparam_ptr++ = saved_op_index;
|
1145 |
|
*gen_opparam_ptr++ = saved_arg_index;
|
1146 |
|
|
1147 |
|
macro_op_index = gen_opc_ptr - gen_opc_buf;
|
1148 |
|
macro_arg_index = gen_opparam_ptr - gen_opparam_buf;
|
1149 |
|
|
1150 |
|
last_nb_temps = s->nb_temps;
|
1151 |
|
|
1152 |
|
s->macro_func(s, macro_id, dead_args);
|
1153 |
|
|
1154 |
|
/* realloc temp info (XXX: make it faster) */
|
1155 |
|
if (s->nb_temps > last_nb_temps) {
|
1156 |
|
uint8_t *new_dead_temps;
|
1157 |
|
|
1158 |
|
new_dead_temps = tcg_malloc(s->nb_temps);
|
1159 |
|
memcpy(new_dead_temps, dead_temps, last_nb_temps);
|
1160 |
|
memset(new_dead_temps + last_nb_temps, 1,
|
1161 |
|
s->nb_temps - last_nb_temps);
|
1162 |
|
dead_temps = new_dead_temps;
|
1163 |
|
}
|
1164 |
|
|
1165 |
|
macro_end_op_index = gen_opc_ptr - gen_opc_buf;
|
1166 |
|
macro_end_arg_index = gen_opparam_ptr - gen_opparam_buf;
|
1167 |
|
|
1168 |
|
/* end of macro: add a goto to the next instruction */
|
1169 |
|
*gen_opc_ptr++ = INDEX_op_macro_end;
|
1170 |
|
*gen_opparam_ptr++ = op_index + 1;
|
1171 |
|
*gen_opparam_ptr++ = saved_arg_index + nb_args;
|
1172 |
|
|
1173 |
|
/* modify the macro operation to be a macro_goto */
|
1174 |
|
gen_opc_buf[op_index] = INDEX_op_macro_goto;
|
1175 |
|
args[0] = macro_op_index;
|
1176 |
|
args[1] = macro_arg_index;
|
1177 |
|
args[2] = 0; /* dummy third arg to match the
|
1178 |
|
macro parameters */
|
1179 |
|
|
1180 |
|
/* set the next instruction to the end of the macro */
|
1181 |
|
op_index = macro_end_op_index;
|
1182 |
|
args = macro_end_arg_index + gen_opparam_buf;
|
1183 |
|
}
|
1184 |
|
break;
|
1185 |
|
case INDEX_op_macro_start:
|
1186 |
|
args -= 2;
|
1187 |
|
op_index = args[0];
|
1188 |
|
args = gen_opparam_buf + args[1];
|
1189 |
|
break;
|
1190 |
|
case INDEX_op_macro_goto:
|
1191 |
|
case INDEX_op_macro_end:
|
1192 |
|
tcg_abort(); /* should never happen in liveness analysis */
|
1193 |
1118 |
case INDEX_op_end:
|
1194 |
1119 |
break;
|
1195 |
1120 |
/* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
|
... | ... | |
1916 |
1841 |
static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
|
1917 |
1842 |
long search_pc)
|
1918 |
1843 |
{
|
1919 |
|
int opc, op_index, macro_op_index;
|
|
1844 |
int opc, op_index;
|
1920 |
1845 |
const TCGOpDef *def;
|
1921 |
1846 |
unsigned int dead_iargs;
|
1922 |
1847 |
const TCGArg *args;
|
... | ... | |
1950 |
1875 |
s->code_buf = gen_code_buf;
|
1951 |
1876 |
s->code_ptr = gen_code_buf;
|
1952 |
1877 |
|
1953 |
|
macro_op_index = -1;
|
1954 |
1878 |
args = gen_opparam_buf;
|
1955 |
1879 |
op_index = 0;
|
1956 |
1880 |
|
... | ... | |
2002 |
1926 |
}
|
2003 |
1927 |
}
|
2004 |
1928 |
break;
|
2005 |
|
case INDEX_op_macro_goto:
|
2006 |
|
macro_op_index = op_index; /* only used for exceptions */
|
2007 |
|
op_index = args[0] - 1;
|
2008 |
|
args = gen_opparam_buf + args[1];
|
2009 |
|
goto next;
|
2010 |
|
case INDEX_op_macro_end:
|
2011 |
|
macro_op_index = -1; /* only used for exceptions */
|
2012 |
|
op_index = args[0] - 1;
|
2013 |
|
args = gen_opparam_buf + args[1];
|
2014 |
|
goto next;
|
2015 |
|
case INDEX_op_macro_start:
|
2016 |
|
/* must never happen here */
|
2017 |
|
tcg_abort();
|
2018 |
1929 |
case INDEX_op_set_label:
|
2019 |
1930 |
tcg_reg_alloc_bb_end(s, s->reserved_regs);
|
2020 |
1931 |
tcg_out_label(s, args[0], (long)s->code_ptr);
|
... | ... | |
2052 |
1963 |
args += def->nb_args;
|
2053 |
1964 |
next: ;
|
2054 |
1965 |
if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
|
2055 |
|
if (macro_op_index >= 0)
|
2056 |
|
return macro_op_index;
|
2057 |
|
else
|
2058 |
|
return op_index;
|
|
1966 |
return op_index;
|
2059 |
1967 |
}
|
2060 |
1968 |
op_index++;
|
2061 |
1969 |
#ifndef NDEBUG
|