Revision b314f270

b/tcg/tcg-op.h
1396 1396
#endif
1397 1397

  
1398 1398
/***************************************/
1399
static inline void tcg_gen_macro_2(TCGv ret0, TCGv ret1, int macro_id)
1400
{
1401
    tcg_gen_op3i(INDEX_op_macro_2, ret0, ret1, macro_id);
1402
}
1403

  
1404
/***************************************/
1405 1399
/* QEMU specific operations. Their type depend on the QEMU CPU
1406 1400
   type. */
1407 1401
#ifndef TARGET_LONG_BITS
b/tcg/tcg-opc.h
36 36
DEF2(nop2, 0, 0, 2, 0)
37 37
DEF2(nop3, 0, 0, 3, 0)
38 38
DEF2(nopn, 0, 0, 1, 0) /* variable number of parameters */
39
/* macro handling */
40
DEF2(macro_2, 2, 0, 1, 0)
41
DEF2(macro_start, 0, 0, 2, 0)
42
DEF2(macro_end, 0, 0, 2, 0)
43
DEF2(macro_goto, 0, 0, 3, 0)
44 39

  
45 40
DEF2(discard, 1, 0, 0, 0)
46 41

  
b/tcg/tcg.c
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
b/tcg/tcg.h
205 205

  
206 206
typedef struct TCGContext TCGContext;
207 207

  
208
typedef void TCGMacroFunc(TCGContext *s, int macro_id, const int *dead_args);
209

  
210 208
struct TCGContext {
211 209
    uint8_t *pool_cur, *pool_end;
212 210
    TCGPool *pool_first, *pool_current;
......
240 238
    uint8_t *code_ptr;
241 239
    TCGTemp static_temps[TCG_MAX_TEMPS];
242 240

  
243
    TCGMacroFunc *macro_func;
244 241
    TCGHelperInfo *helpers;
245 242
    int nb_helpers;
246 243
    int allocated_helpers;
......
301 298

  
302 299
void tcg_set_frame(TCGContext *s, int reg,
303 300
                   tcg_target_long start, tcg_target_long size);
304
void tcg_set_macro_func(TCGContext *s, TCGMacroFunc *func);
305 301
TCGv tcg_global_reg_new(TCGType type, int reg, const char *name);
306 302
TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2, 
307 303
                              const char *name);

Also available in: Unified diff