Revision 53108fb5

b/tcg/optimize.c
96 96
{
97 97
    switch (op) {
98 98
    case INDEX_op_mov_i32:
99
    case INDEX_op_add_i32:
100
    case INDEX_op_sub_i32:
101
    case INDEX_op_mul_i32:
99 102
        return 32;
100 103
#if TCG_TARGET_REG_BITS == 64
101 104
    case INDEX_op_mov_i64:
105
    case INDEX_op_add_i64:
106
    case INDEX_op_sub_i64:
107
    case INDEX_op_mul_i64:
102 108
        return 64;
103 109
#endif
104 110
    default:
......
156 162
        gen_args[1] = val;
157 163
}
158 164

  
165
static int op_to_mov(int op)
166
{
167
    switch (op_bits(op)) {
168
    case 32:
169
        return INDEX_op_mov_i32;
170
#if TCG_TARGET_REG_BITS == 64
171
    case 64:
172
        return INDEX_op_mov_i64;
173
#endif
174
    default:
175
        fprintf(stderr, "op_to_mov: unexpected return value of "
176
                "function op_bits.\n");
177
        tcg_abort();
178
    }
179
}
180

  
181
static TCGArg do_constant_folding_2(int op, TCGArg x, TCGArg y)
182
{
183
    switch (op) {
184
    CASE_OP_32_64(add):
185
        return x + y;
186

  
187
    CASE_OP_32_64(sub):
188
        return x - y;
189

  
190
    CASE_OP_32_64(mul):
191
        return x * y;
192

  
193
    default:
194
        fprintf(stderr,
195
                "Unrecognized operation %d in do_constant_folding.\n", op);
196
        tcg_abort();
197
    }
198
}
199

  
200
static TCGArg do_constant_folding(int op, TCGArg x, TCGArg y)
201
{
202
    TCGArg res = do_constant_folding_2(op, x, y);
203
#if TCG_TARGET_REG_BITS == 64
204
    if (op_bits(op) == 32) {
205
        res &= 0xffffffff;
206
    }
207
#endif
208
    return res;
209
}
210

  
159 211
/* Propagate constants and copies, fold constant expressions. */
160 212
static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
161 213
                                    TCGArg *args, TCGOpDef *tcg_op_defs)
......
163 215
    int i, nb_ops, op_index, op, nb_temps, nb_globals, nb_call_args;
164 216
    const TCGOpDef *def;
165 217
    TCGArg *gen_args;
218
    TCGArg tmp;
166 219
    /* Array VALS has an element for each temp.
167 220
       If this temp holds a constant then its value is kept in VALS' element.
168 221
       If this temp is a copy of other ones then this equivalence class'
......
189 242
            }
190 243
        }
191 244

  
245
        /* For commutative operations make constant second argument */
246
        switch (op) {
247
        CASE_OP_32_64(add):
248
        CASE_OP_32_64(mul):
249
            if (temps[args[1]].state == TCG_TEMP_CONST) {
250
                tmp = args[1];
251
                args[1] = args[2];
252
                args[2] = tmp;
253
            }
254
            break;
255
        default:
256
            break;
257
        }
258

  
259
        /* Simplify expression if possible. */
260
        switch (op) {
261
        CASE_OP_32_64(add):
262
        CASE_OP_32_64(sub):
263
            if (temps[args[1]].state == TCG_TEMP_CONST) {
264
                /* Proceed with possible constant folding. */
265
                break;
266
            }
267
            if (temps[args[2]].state == TCG_TEMP_CONST
268
                && temps[args[2]].val == 0) {
269
                if ((temps[args[0]].state == TCG_TEMP_COPY
270
                    && temps[args[0]].val == args[1])
271
                    || args[0] == args[1]) {
272
                    args += 3;
273
                    gen_opc_buf[op_index] = INDEX_op_nop;
274
                } else {
275
                    gen_opc_buf[op_index] = op_to_mov(op);
276
                    tcg_opt_gen_mov(gen_args, args[0], args[1],
277
                                    nb_temps, nb_globals);
278
                    gen_args += 2;
279
                    args += 3;
280
                }
281
                continue;
282
            }
283
            break;
284
        CASE_OP_32_64(mul):
285
            if ((temps[args[2]].state == TCG_TEMP_CONST
286
                && temps[args[2]].val == 0)) {
287
                gen_opc_buf[op_index] = op_to_movi(op);
288
                tcg_opt_gen_movi(gen_args, args[0], 0, nb_temps, nb_globals);
289
                args += 3;
290
                gen_args += 2;
291
                continue;
292
            }
293
            break;
294
        }
295

  
192 296
        /* Propagate constants through copy operations and do constant
193 297
           folding.  Constants will be substituted to arguments by register
194 298
           allocator where needed and possible.  Also detect copies. */
......
219 323
            gen_args += 2;
220 324
            args += 2;
221 325
            break;
326
        CASE_OP_32_64(add):
327
        CASE_OP_32_64(sub):
328
        CASE_OP_32_64(mul):
329
            if (temps[args[1]].state == TCG_TEMP_CONST
330
                && temps[args[2]].state == TCG_TEMP_CONST) {
331
                gen_opc_buf[op_index] = op_to_movi(op);
332
                tmp = do_constant_folding(op, temps[args[1]].val,
333
                                          temps[args[2]].val);
334
                tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
335
                gen_args += 2;
336
                args += 3;
337
                break;
338
            } else {
339
                reset_temp(args[0], nb_temps, nb_globals);
340
                gen_args[0] = args[0];
341
                gen_args[1] = args[1];
342
                gen_args[2] = args[2];
343
                gen_args += 3;
344
                args += 3;
345
                break;
346
            }
222 347
        case INDEX_op_call:
223 348
            nb_call_args = (args[0] >> 16) + (args[0] & 0xffff);
224 349
            if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) {

Also available in: Unified diff