Statistics
| Branch: | Revision:

root / tcg / optimize.c @ fedc0da2

History | View | Annotate | Download (21.2 kB)

1 8f2e8c07 Kirill Batuzov
/*
2 8f2e8c07 Kirill Batuzov
 * Optimizations for Tiny Code Generator for QEMU
3 8f2e8c07 Kirill Batuzov
 *
4 8f2e8c07 Kirill Batuzov
 * Copyright (c) 2010 Samsung Electronics.
5 8f2e8c07 Kirill Batuzov
 * Contributed by Kirill Batuzov <batuzovk@ispras.ru>
6 8f2e8c07 Kirill Batuzov
 *
7 8f2e8c07 Kirill Batuzov
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 8f2e8c07 Kirill Batuzov
 * of this software and associated documentation files (the "Software"), to deal
9 8f2e8c07 Kirill Batuzov
 * in the Software without restriction, including without limitation the rights
10 8f2e8c07 Kirill Batuzov
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 8f2e8c07 Kirill Batuzov
 * copies of the Software, and to permit persons to whom the Software is
12 8f2e8c07 Kirill Batuzov
 * furnished to do so, subject to the following conditions:
13 8f2e8c07 Kirill Batuzov
 *
14 8f2e8c07 Kirill Batuzov
 * The above copyright notice and this permission notice shall be included in
15 8f2e8c07 Kirill Batuzov
 * all copies or substantial portions of the Software.
16 8f2e8c07 Kirill Batuzov
 *
17 8f2e8c07 Kirill Batuzov
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 8f2e8c07 Kirill Batuzov
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 8f2e8c07 Kirill Batuzov
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 8f2e8c07 Kirill Batuzov
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 8f2e8c07 Kirill Batuzov
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 8f2e8c07 Kirill Batuzov
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 8f2e8c07 Kirill Batuzov
 * THE SOFTWARE.
24 8f2e8c07 Kirill Batuzov
 */
25 8f2e8c07 Kirill Batuzov
26 8f2e8c07 Kirill Batuzov
#include "config.h"
27 8f2e8c07 Kirill Batuzov
28 8f2e8c07 Kirill Batuzov
#include <stdlib.h>
29 8f2e8c07 Kirill Batuzov
#include <stdio.h>
30 8f2e8c07 Kirill Batuzov
31 8f2e8c07 Kirill Batuzov
#include "qemu-common.h"
32 8f2e8c07 Kirill Batuzov
#include "tcg-op.h"
33 8f2e8c07 Kirill Batuzov
34 8f2e8c07 Kirill Batuzov
#define CASE_OP_32_64(x)                        \
35 8f2e8c07 Kirill Batuzov
        glue(glue(case INDEX_op_, x), _i32):    \
36 8f2e8c07 Kirill Batuzov
        glue(glue(case INDEX_op_, x), _i64)
37 8f2e8c07 Kirill Batuzov
38 22613af4 Kirill Batuzov
typedef enum {
39 22613af4 Kirill Batuzov
    TCG_TEMP_UNDEF = 0,
40 22613af4 Kirill Batuzov
    TCG_TEMP_CONST,
41 22613af4 Kirill Batuzov
    TCG_TEMP_COPY,
42 22613af4 Kirill Batuzov
    TCG_TEMP_HAS_COPY,
43 22613af4 Kirill Batuzov
    TCG_TEMP_ANY
44 22613af4 Kirill Batuzov
} tcg_temp_state;
45 22613af4 Kirill Batuzov
46 22613af4 Kirill Batuzov
struct tcg_temp_info {
47 22613af4 Kirill Batuzov
    tcg_temp_state state;
48 22613af4 Kirill Batuzov
    uint16_t prev_copy;
49 22613af4 Kirill Batuzov
    uint16_t next_copy;
50 22613af4 Kirill Batuzov
    tcg_target_ulong val;
51 22613af4 Kirill Batuzov
};
52 22613af4 Kirill Batuzov
53 22613af4 Kirill Batuzov
static struct tcg_temp_info temps[TCG_MAX_TEMPS];
54 22613af4 Kirill Batuzov
55 22613af4 Kirill Batuzov
/* Reset TEMP's state to TCG_TEMP_ANY.  If TEMP was a representative of some
56 22613af4 Kirill Batuzov
   class of equivalent temp's, a new representative should be chosen in this
57 22613af4 Kirill Batuzov
   class. */
58 22613af4 Kirill Batuzov
static void reset_temp(TCGArg temp, int nb_temps, int nb_globals)
59 22613af4 Kirill Batuzov
{
60 22613af4 Kirill Batuzov
    int i;
61 22613af4 Kirill Batuzov
    TCGArg new_base = (TCGArg)-1;
62 22613af4 Kirill Batuzov
    if (temps[temp].state == TCG_TEMP_HAS_COPY) {
63 22613af4 Kirill Batuzov
        for (i = temps[temp].next_copy; i != temp; i = temps[i].next_copy) {
64 22613af4 Kirill Batuzov
            if (i >= nb_globals) {
65 22613af4 Kirill Batuzov
                temps[i].state = TCG_TEMP_HAS_COPY;
66 22613af4 Kirill Batuzov
                new_base = i;
67 22613af4 Kirill Batuzov
                break;
68 22613af4 Kirill Batuzov
            }
69 22613af4 Kirill Batuzov
        }
70 22613af4 Kirill Batuzov
        for (i = temps[temp].next_copy; i != temp; i = temps[i].next_copy) {
71 22613af4 Kirill Batuzov
            if (new_base == (TCGArg)-1) {
72 22613af4 Kirill Batuzov
                temps[i].state = TCG_TEMP_ANY;
73 22613af4 Kirill Batuzov
            } else {
74 22613af4 Kirill Batuzov
                temps[i].val = new_base;
75 22613af4 Kirill Batuzov
            }
76 22613af4 Kirill Batuzov
        }
77 22613af4 Kirill Batuzov
        temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy;
78 22613af4 Kirill Batuzov
        temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy;
79 22613af4 Kirill Batuzov
    } else if (temps[temp].state == TCG_TEMP_COPY) {
80 22613af4 Kirill Batuzov
        temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy;
81 22613af4 Kirill Batuzov
        temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy;
82 22613af4 Kirill Batuzov
        new_base = temps[temp].val;
83 22613af4 Kirill Batuzov
    }
84 22613af4 Kirill Batuzov
    temps[temp].state = TCG_TEMP_ANY;
85 22613af4 Kirill Batuzov
    if (new_base != (TCGArg)-1 && temps[new_base].next_copy == new_base) {
86 22613af4 Kirill Batuzov
        temps[new_base].state = TCG_TEMP_ANY;
87 22613af4 Kirill Batuzov
    }
88 22613af4 Kirill Batuzov
}
89 22613af4 Kirill Batuzov
90 fe0de7aa Blue Swirl
static int op_bits(TCGOpcode op)
91 22613af4 Kirill Batuzov
{
92 8399ad59 Richard Henderson
    const TCGOpDef *def = &tcg_op_defs[op];
93 8399ad59 Richard Henderson
    return def->flags & TCG_OPF_64BIT ? 64 : 32;
94 22613af4 Kirill Batuzov
}
95 22613af4 Kirill Batuzov
96 fe0de7aa Blue Swirl
static TCGOpcode op_to_movi(TCGOpcode op)
97 22613af4 Kirill Batuzov
{
98 22613af4 Kirill Batuzov
    switch (op_bits(op)) {
99 22613af4 Kirill Batuzov
    case 32:
100 22613af4 Kirill Batuzov
        return INDEX_op_movi_i32;
101 22613af4 Kirill Batuzov
    case 64:
102 22613af4 Kirill Batuzov
        return INDEX_op_movi_i64;
103 22613af4 Kirill Batuzov
    default:
104 22613af4 Kirill Batuzov
        fprintf(stderr, "op_to_movi: unexpected return value of "
105 22613af4 Kirill Batuzov
                "function op_bits.\n");
106 22613af4 Kirill Batuzov
        tcg_abort();
107 22613af4 Kirill Batuzov
    }
108 22613af4 Kirill Batuzov
}
109 22613af4 Kirill Batuzov
110 e31b0a7c Blue Swirl
static void tcg_opt_gen_mov(TCGContext *s, TCGArg *gen_args, TCGArg dst,
111 e31b0a7c Blue Swirl
                            TCGArg src, int nb_temps, int nb_globals)
112 22613af4 Kirill Batuzov
{
113 22613af4 Kirill Batuzov
        reset_temp(dst, nb_temps, nb_globals);
114 22613af4 Kirill Batuzov
        assert(temps[src].state != TCG_TEMP_COPY);
115 e31b0a7c Blue Swirl
        /* Don't try to copy if one of temps is a global or either one
116 e31b0a7c Blue Swirl
           is local and another is register */
117 e31b0a7c Blue Swirl
        if (src >= nb_globals && dst >= nb_globals &&
118 e31b0a7c Blue Swirl
            tcg_arg_is_local(s, src) == tcg_arg_is_local(s, dst)) {
119 22613af4 Kirill Batuzov
            assert(temps[src].state != TCG_TEMP_CONST);
120 22613af4 Kirill Batuzov
            if (temps[src].state != TCG_TEMP_HAS_COPY) {
121 22613af4 Kirill Batuzov
                temps[src].state = TCG_TEMP_HAS_COPY;
122 22613af4 Kirill Batuzov
                temps[src].next_copy = src;
123 22613af4 Kirill Batuzov
                temps[src].prev_copy = src;
124 22613af4 Kirill Batuzov
            }
125 22613af4 Kirill Batuzov
            temps[dst].state = TCG_TEMP_COPY;
126 22613af4 Kirill Batuzov
            temps[dst].val = src;
127 22613af4 Kirill Batuzov
            temps[dst].next_copy = temps[src].next_copy;
128 22613af4 Kirill Batuzov
            temps[dst].prev_copy = src;
129 22613af4 Kirill Batuzov
            temps[temps[dst].next_copy].prev_copy = dst;
130 22613af4 Kirill Batuzov
            temps[src].next_copy = dst;
131 22613af4 Kirill Batuzov
        }
132 22613af4 Kirill Batuzov
        gen_args[0] = dst;
133 22613af4 Kirill Batuzov
        gen_args[1] = src;
134 22613af4 Kirill Batuzov
}
135 22613af4 Kirill Batuzov
136 22613af4 Kirill Batuzov
static void tcg_opt_gen_movi(TCGArg *gen_args, TCGArg dst, TCGArg val,
137 22613af4 Kirill Batuzov
                             int nb_temps, int nb_globals)
138 22613af4 Kirill Batuzov
{
139 22613af4 Kirill Batuzov
        reset_temp(dst, nb_temps, nb_globals);
140 22613af4 Kirill Batuzov
        temps[dst].state = TCG_TEMP_CONST;
141 22613af4 Kirill Batuzov
        temps[dst].val = val;
142 22613af4 Kirill Batuzov
        gen_args[0] = dst;
143 22613af4 Kirill Batuzov
        gen_args[1] = val;
144 22613af4 Kirill Batuzov
}
145 22613af4 Kirill Batuzov
146 fe0de7aa Blue Swirl
static TCGOpcode op_to_mov(TCGOpcode op)
147 53108fb5 Kirill Batuzov
{
148 53108fb5 Kirill Batuzov
    switch (op_bits(op)) {
149 53108fb5 Kirill Batuzov
    case 32:
150 53108fb5 Kirill Batuzov
        return INDEX_op_mov_i32;
151 53108fb5 Kirill Batuzov
    case 64:
152 53108fb5 Kirill Batuzov
        return INDEX_op_mov_i64;
153 53108fb5 Kirill Batuzov
    default:
154 53108fb5 Kirill Batuzov
        fprintf(stderr, "op_to_mov: unexpected return value of "
155 53108fb5 Kirill Batuzov
                "function op_bits.\n");
156 53108fb5 Kirill Batuzov
        tcg_abort();
157 53108fb5 Kirill Batuzov
    }
158 53108fb5 Kirill Batuzov
}
159 53108fb5 Kirill Batuzov
160 fe0de7aa Blue Swirl
static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y)
161 53108fb5 Kirill Batuzov
{
162 53108fb5 Kirill Batuzov
    switch (op) {
163 53108fb5 Kirill Batuzov
    CASE_OP_32_64(add):
164 53108fb5 Kirill Batuzov
        return x + y;
165 53108fb5 Kirill Batuzov
166 53108fb5 Kirill Batuzov
    CASE_OP_32_64(sub):
167 53108fb5 Kirill Batuzov
        return x - y;
168 53108fb5 Kirill Batuzov
169 53108fb5 Kirill Batuzov
    CASE_OP_32_64(mul):
170 53108fb5 Kirill Batuzov
        return x * y;
171 53108fb5 Kirill Batuzov
172 9a81090b Kirill Batuzov
    CASE_OP_32_64(and):
173 9a81090b Kirill Batuzov
        return x & y;
174 9a81090b Kirill Batuzov
175 9a81090b Kirill Batuzov
    CASE_OP_32_64(or):
176 9a81090b Kirill Batuzov
        return x | y;
177 9a81090b Kirill Batuzov
178 9a81090b Kirill Batuzov
    CASE_OP_32_64(xor):
179 9a81090b Kirill Batuzov
        return x ^ y;
180 9a81090b Kirill Batuzov
181 55c0975c Kirill Batuzov
    case INDEX_op_shl_i32:
182 55c0975c Kirill Batuzov
        return (uint32_t)x << (uint32_t)y;
183 55c0975c Kirill Batuzov
184 55c0975c Kirill Batuzov
    case INDEX_op_shl_i64:
185 55c0975c Kirill Batuzov
        return (uint64_t)x << (uint64_t)y;
186 55c0975c Kirill Batuzov
187 55c0975c Kirill Batuzov
    case INDEX_op_shr_i32:
188 55c0975c Kirill Batuzov
        return (uint32_t)x >> (uint32_t)y;
189 55c0975c Kirill Batuzov
190 55c0975c Kirill Batuzov
    case INDEX_op_shr_i64:
191 55c0975c Kirill Batuzov
        return (uint64_t)x >> (uint64_t)y;
192 55c0975c Kirill Batuzov
193 55c0975c Kirill Batuzov
    case INDEX_op_sar_i32:
194 55c0975c Kirill Batuzov
        return (int32_t)x >> (int32_t)y;
195 55c0975c Kirill Batuzov
196 55c0975c Kirill Batuzov
    case INDEX_op_sar_i64:
197 55c0975c Kirill Batuzov
        return (int64_t)x >> (int64_t)y;
198 55c0975c Kirill Batuzov
199 55c0975c Kirill Batuzov
    case INDEX_op_rotr_i32:
200 25c4d9cc Richard Henderson
        x = ((uint32_t)x << (32 - y)) | ((uint32_t)x >> y);
201 55c0975c Kirill Batuzov
        return x;
202 55c0975c Kirill Batuzov
203 55c0975c Kirill Batuzov
    case INDEX_op_rotr_i64:
204 25c4d9cc Richard Henderson
        x = ((uint64_t)x << (64 - y)) | ((uint64_t)x >> y);
205 55c0975c Kirill Batuzov
        return x;
206 55c0975c Kirill Batuzov
207 55c0975c Kirill Batuzov
    case INDEX_op_rotl_i32:
208 25c4d9cc Richard Henderson
        x = ((uint32_t)x << y) | ((uint32_t)x >> (32 - y));
209 55c0975c Kirill Batuzov
        return x;
210 55c0975c Kirill Batuzov
211 55c0975c Kirill Batuzov
    case INDEX_op_rotl_i64:
212 25c4d9cc Richard Henderson
        x = ((uint64_t)x << y) | ((uint64_t)x >> (64 - y));
213 55c0975c Kirill Batuzov
        return x;
214 25c4d9cc Richard Henderson
215 25c4d9cc Richard Henderson
    CASE_OP_32_64(not):
216 a640f031 Kirill Batuzov
        return ~x;
217 25c4d9cc Richard Henderson
218 cb25c80a Richard Henderson
    CASE_OP_32_64(neg):
219 cb25c80a Richard Henderson
        return -x;
220 cb25c80a Richard Henderson
221 cb25c80a Richard Henderson
    CASE_OP_32_64(andc):
222 cb25c80a Richard Henderson
        return x & ~y;
223 cb25c80a Richard Henderson
224 cb25c80a Richard Henderson
    CASE_OP_32_64(orc):
225 cb25c80a Richard Henderson
        return x | ~y;
226 cb25c80a Richard Henderson
227 cb25c80a Richard Henderson
    CASE_OP_32_64(eqv):
228 cb25c80a Richard Henderson
        return ~(x ^ y);
229 cb25c80a Richard Henderson
230 cb25c80a Richard Henderson
    CASE_OP_32_64(nand):
231 cb25c80a Richard Henderson
        return ~(x & y);
232 cb25c80a Richard Henderson
233 cb25c80a Richard Henderson
    CASE_OP_32_64(nor):
234 cb25c80a Richard Henderson
        return ~(x | y);
235 cb25c80a Richard Henderson
236 25c4d9cc Richard Henderson
    CASE_OP_32_64(ext8s):
237 a640f031 Kirill Batuzov
        return (int8_t)x;
238 25c4d9cc Richard Henderson
239 25c4d9cc Richard Henderson
    CASE_OP_32_64(ext16s):
240 a640f031 Kirill Batuzov
        return (int16_t)x;
241 25c4d9cc Richard Henderson
242 25c4d9cc Richard Henderson
    CASE_OP_32_64(ext8u):
243 a640f031 Kirill Batuzov
        return (uint8_t)x;
244 25c4d9cc Richard Henderson
245 25c4d9cc Richard Henderson
    CASE_OP_32_64(ext16u):
246 a640f031 Kirill Batuzov
        return (uint16_t)x;
247 a640f031 Kirill Batuzov
248 a640f031 Kirill Batuzov
    case INDEX_op_ext32s_i64:
249 a640f031 Kirill Batuzov
        return (int32_t)x;
250 a640f031 Kirill Batuzov
251 a640f031 Kirill Batuzov
    case INDEX_op_ext32u_i64:
252 a640f031 Kirill Batuzov
        return (uint32_t)x;
253 a640f031 Kirill Batuzov
254 53108fb5 Kirill Batuzov
    default:
255 53108fb5 Kirill Batuzov
        fprintf(stderr,
256 53108fb5 Kirill Batuzov
                "Unrecognized operation %d in do_constant_folding.\n", op);
257 53108fb5 Kirill Batuzov
        tcg_abort();
258 53108fb5 Kirill Batuzov
    }
259 53108fb5 Kirill Batuzov
}
260 53108fb5 Kirill Batuzov
261 fe0de7aa Blue Swirl
static TCGArg do_constant_folding(TCGOpcode op, TCGArg x, TCGArg y)
262 53108fb5 Kirill Batuzov
{
263 53108fb5 Kirill Batuzov
    TCGArg res = do_constant_folding_2(op, x, y);
264 53108fb5 Kirill Batuzov
    if (op_bits(op) == 32) {
265 53108fb5 Kirill Batuzov
        res &= 0xffffffff;
266 53108fb5 Kirill Batuzov
    }
267 53108fb5 Kirill Batuzov
    return res;
268 53108fb5 Kirill Batuzov
}
269 53108fb5 Kirill Batuzov
270 f8dd19e5 Aurelien Jarno
static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x,
271 f8dd19e5 Aurelien Jarno
                                       TCGArg y, TCGCond c)
272 f8dd19e5 Aurelien Jarno
{
273 f8dd19e5 Aurelien Jarno
    switch (op_bits(op)) {
274 f8dd19e5 Aurelien Jarno
    case 32:
275 f8dd19e5 Aurelien Jarno
        switch (c) {
276 f8dd19e5 Aurelien Jarno
        case TCG_COND_EQ:
277 f8dd19e5 Aurelien Jarno
            return (uint32_t)x == (uint32_t)y;
278 f8dd19e5 Aurelien Jarno
        case TCG_COND_NE:
279 f8dd19e5 Aurelien Jarno
            return (uint32_t)x != (uint32_t)y;
280 f8dd19e5 Aurelien Jarno
        case TCG_COND_LT:
281 f8dd19e5 Aurelien Jarno
            return (int32_t)x < (int32_t)y;
282 f8dd19e5 Aurelien Jarno
        case TCG_COND_GE:
283 f8dd19e5 Aurelien Jarno
            return (int32_t)x >= (int32_t)y;
284 f8dd19e5 Aurelien Jarno
        case TCG_COND_LE:
285 f8dd19e5 Aurelien Jarno
            return (int32_t)x <= (int32_t)y;
286 f8dd19e5 Aurelien Jarno
        case TCG_COND_GT:
287 f8dd19e5 Aurelien Jarno
            return (int32_t)x > (int32_t)y;
288 f8dd19e5 Aurelien Jarno
        case TCG_COND_LTU:
289 f8dd19e5 Aurelien Jarno
            return (uint32_t)x < (uint32_t)y;
290 f8dd19e5 Aurelien Jarno
        case TCG_COND_GEU:
291 f8dd19e5 Aurelien Jarno
            return (uint32_t)x >= (uint32_t)y;
292 f8dd19e5 Aurelien Jarno
        case TCG_COND_LEU:
293 f8dd19e5 Aurelien Jarno
            return (uint32_t)x <= (uint32_t)y;
294 f8dd19e5 Aurelien Jarno
        case TCG_COND_GTU:
295 f8dd19e5 Aurelien Jarno
            return (uint32_t)x > (uint32_t)y;
296 f8dd19e5 Aurelien Jarno
        }
297 f8dd19e5 Aurelien Jarno
        break;
298 f8dd19e5 Aurelien Jarno
    case 64:
299 f8dd19e5 Aurelien Jarno
        switch (c) {
300 f8dd19e5 Aurelien Jarno
        case TCG_COND_EQ:
301 f8dd19e5 Aurelien Jarno
            return (uint64_t)x == (uint64_t)y;
302 f8dd19e5 Aurelien Jarno
        case TCG_COND_NE:
303 f8dd19e5 Aurelien Jarno
            return (uint64_t)x != (uint64_t)y;
304 f8dd19e5 Aurelien Jarno
        case TCG_COND_LT:
305 f8dd19e5 Aurelien Jarno
            return (int64_t)x < (int64_t)y;
306 f8dd19e5 Aurelien Jarno
        case TCG_COND_GE:
307 f8dd19e5 Aurelien Jarno
            return (int64_t)x >= (int64_t)y;
308 f8dd19e5 Aurelien Jarno
        case TCG_COND_LE:
309 f8dd19e5 Aurelien Jarno
            return (int64_t)x <= (int64_t)y;
310 f8dd19e5 Aurelien Jarno
        case TCG_COND_GT:
311 f8dd19e5 Aurelien Jarno
            return (int64_t)x > (int64_t)y;
312 f8dd19e5 Aurelien Jarno
        case TCG_COND_LTU:
313 f8dd19e5 Aurelien Jarno
            return (uint64_t)x < (uint64_t)y;
314 f8dd19e5 Aurelien Jarno
        case TCG_COND_GEU:
315 f8dd19e5 Aurelien Jarno
            return (uint64_t)x >= (uint64_t)y;
316 f8dd19e5 Aurelien Jarno
        case TCG_COND_LEU:
317 f8dd19e5 Aurelien Jarno
            return (uint64_t)x <= (uint64_t)y;
318 f8dd19e5 Aurelien Jarno
        case TCG_COND_GTU:
319 f8dd19e5 Aurelien Jarno
            return (uint64_t)x > (uint64_t)y;
320 f8dd19e5 Aurelien Jarno
        }
321 f8dd19e5 Aurelien Jarno
        break;
322 f8dd19e5 Aurelien Jarno
    }
323 f8dd19e5 Aurelien Jarno
324 f8dd19e5 Aurelien Jarno
    fprintf(stderr,
325 f8dd19e5 Aurelien Jarno
            "Unrecognized bitness %d or condition %d in "
326 f8dd19e5 Aurelien Jarno
            "do_constant_folding_cond.\n", op_bits(op), c);
327 f8dd19e5 Aurelien Jarno
    tcg_abort();
328 f8dd19e5 Aurelien Jarno
}
329 f8dd19e5 Aurelien Jarno
330 f8dd19e5 Aurelien Jarno
331 22613af4 Kirill Batuzov
/* Propagate constants and copies, fold constant expressions. */
332 8f2e8c07 Kirill Batuzov
static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
333 8f2e8c07 Kirill Batuzov
                                    TCGArg *args, TCGOpDef *tcg_op_defs)
334 8f2e8c07 Kirill Batuzov
{
335 fe0de7aa Blue Swirl
    int i, nb_ops, op_index, nb_temps, nb_globals, nb_call_args;
336 fe0de7aa Blue Swirl
    TCGOpcode op;
337 8f2e8c07 Kirill Batuzov
    const TCGOpDef *def;
338 8f2e8c07 Kirill Batuzov
    TCGArg *gen_args;
339 53108fb5 Kirill Batuzov
    TCGArg tmp;
340 22613af4 Kirill Batuzov
    /* Array VALS has an element for each temp.
341 22613af4 Kirill Batuzov
       If this temp holds a constant then its value is kept in VALS' element.
342 22613af4 Kirill Batuzov
       If this temp is a copy of other ones then this equivalence class'
343 22613af4 Kirill Batuzov
       representative is kept in VALS' element.
344 22613af4 Kirill Batuzov
       If this temp is neither copy nor constant then corresponding VALS'
345 22613af4 Kirill Batuzov
       element is unused. */
346 8f2e8c07 Kirill Batuzov
347 8f2e8c07 Kirill Batuzov
    nb_temps = s->nb_temps;
348 8f2e8c07 Kirill Batuzov
    nb_globals = s->nb_globals;
349 22613af4 Kirill Batuzov
    memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
350 8f2e8c07 Kirill Batuzov
351 8f2e8c07 Kirill Batuzov
    nb_ops = tcg_opc_ptr - gen_opc_buf;
352 8f2e8c07 Kirill Batuzov
    gen_args = args;
353 8f2e8c07 Kirill Batuzov
    for (op_index = 0; op_index < nb_ops; op_index++) {
354 8f2e8c07 Kirill Batuzov
        op = gen_opc_buf[op_index];
355 8f2e8c07 Kirill Batuzov
        def = &tcg_op_defs[op];
356 22613af4 Kirill Batuzov
        /* Do copy propagation */
357 22613af4 Kirill Batuzov
        if (!(def->flags & (TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS))) {
358 22613af4 Kirill Batuzov
            assert(op != INDEX_op_call);
359 22613af4 Kirill Batuzov
            for (i = def->nb_oargs; i < def->nb_oargs + def->nb_iargs; i++) {
360 22613af4 Kirill Batuzov
                if (temps[args[i]].state == TCG_TEMP_COPY) {
361 22613af4 Kirill Batuzov
                    args[i] = temps[args[i]].val;
362 22613af4 Kirill Batuzov
                }
363 22613af4 Kirill Batuzov
            }
364 22613af4 Kirill Batuzov
        }
365 22613af4 Kirill Batuzov
366 53108fb5 Kirill Batuzov
        /* For commutative operations make constant second argument */
367 53108fb5 Kirill Batuzov
        switch (op) {
368 53108fb5 Kirill Batuzov
        CASE_OP_32_64(add):
369 53108fb5 Kirill Batuzov
        CASE_OP_32_64(mul):
370 9a81090b Kirill Batuzov
        CASE_OP_32_64(and):
371 9a81090b Kirill Batuzov
        CASE_OP_32_64(or):
372 9a81090b Kirill Batuzov
        CASE_OP_32_64(xor):
373 cb25c80a Richard Henderson
        CASE_OP_32_64(eqv):
374 cb25c80a Richard Henderson
        CASE_OP_32_64(nand):
375 cb25c80a Richard Henderson
        CASE_OP_32_64(nor):
376 53108fb5 Kirill Batuzov
            if (temps[args[1]].state == TCG_TEMP_CONST) {
377 53108fb5 Kirill Batuzov
                tmp = args[1];
378 53108fb5 Kirill Batuzov
                args[1] = args[2];
379 53108fb5 Kirill Batuzov
                args[2] = tmp;
380 53108fb5 Kirill Batuzov
            }
381 53108fb5 Kirill Batuzov
            break;
382 65a7cce1 Aurelien Jarno
        CASE_OP_32_64(brcond):
383 65a7cce1 Aurelien Jarno
            if (temps[args[0]].state == TCG_TEMP_CONST
384 65a7cce1 Aurelien Jarno
                && temps[args[1]].state != TCG_TEMP_CONST) {
385 65a7cce1 Aurelien Jarno
                tmp = args[0];
386 65a7cce1 Aurelien Jarno
                args[0] = args[1];
387 65a7cce1 Aurelien Jarno
                args[1] = tmp;
388 65a7cce1 Aurelien Jarno
                args[2] = tcg_swap_cond(args[2]);
389 65a7cce1 Aurelien Jarno
            }
390 65a7cce1 Aurelien Jarno
            break;
391 65a7cce1 Aurelien Jarno
        CASE_OP_32_64(setcond):
392 65a7cce1 Aurelien Jarno
            if (temps[args[1]].state == TCG_TEMP_CONST
393 65a7cce1 Aurelien Jarno
                && temps[args[2]].state != TCG_TEMP_CONST) {
394 65a7cce1 Aurelien Jarno
                tmp = args[1];
395 65a7cce1 Aurelien Jarno
                args[1] = args[2];
396 65a7cce1 Aurelien Jarno
                args[2] = tmp;
397 65a7cce1 Aurelien Jarno
                args[3] = tcg_swap_cond(args[3]);
398 65a7cce1 Aurelien Jarno
            }
399 65a7cce1 Aurelien Jarno
            break;
400 53108fb5 Kirill Batuzov
        default:
401 53108fb5 Kirill Batuzov
            break;
402 53108fb5 Kirill Batuzov
        }
403 53108fb5 Kirill Batuzov
404 01ee5282 Aurelien Jarno
        /* Simplify expressions for "shift/rot r, 0, a => movi r, 0" */
405 01ee5282 Aurelien Jarno
        switch (op) {
406 01ee5282 Aurelien Jarno
        CASE_OP_32_64(shl):
407 01ee5282 Aurelien Jarno
        CASE_OP_32_64(shr):
408 01ee5282 Aurelien Jarno
        CASE_OP_32_64(sar):
409 01ee5282 Aurelien Jarno
        CASE_OP_32_64(rotl):
410 01ee5282 Aurelien Jarno
        CASE_OP_32_64(rotr):
411 01ee5282 Aurelien Jarno
            if (temps[args[1]].state == TCG_TEMP_CONST
412 01ee5282 Aurelien Jarno
                && temps[args[1]].val == 0) {
413 01ee5282 Aurelien Jarno
                gen_opc_buf[op_index] = op_to_movi(op);
414 01ee5282 Aurelien Jarno
                tcg_opt_gen_movi(gen_args, args[0], 0, nb_temps, nb_globals);
415 01ee5282 Aurelien Jarno
                args += 3;
416 01ee5282 Aurelien Jarno
                gen_args += 2;
417 01ee5282 Aurelien Jarno
                continue;
418 01ee5282 Aurelien Jarno
            }
419 01ee5282 Aurelien Jarno
            break;
420 01ee5282 Aurelien Jarno
        default:
421 01ee5282 Aurelien Jarno
            break;
422 01ee5282 Aurelien Jarno
        }
423 01ee5282 Aurelien Jarno
424 56e49438 Aurelien Jarno
        /* Simplify expression for "op r, a, 0 => mov r, a" cases */
425 53108fb5 Kirill Batuzov
        switch (op) {
426 53108fb5 Kirill Batuzov
        CASE_OP_32_64(add):
427 53108fb5 Kirill Batuzov
        CASE_OP_32_64(sub):
428 55c0975c Kirill Batuzov
        CASE_OP_32_64(shl):
429 55c0975c Kirill Batuzov
        CASE_OP_32_64(shr):
430 55c0975c Kirill Batuzov
        CASE_OP_32_64(sar):
431 25c4d9cc Richard Henderson
        CASE_OP_32_64(rotl):
432 25c4d9cc Richard Henderson
        CASE_OP_32_64(rotr):
433 38ee188b Aurelien Jarno
        CASE_OP_32_64(or):
434 38ee188b Aurelien Jarno
        CASE_OP_32_64(xor):
435 53108fb5 Kirill Batuzov
            if (temps[args[1]].state == TCG_TEMP_CONST) {
436 53108fb5 Kirill Batuzov
                /* Proceed with possible constant folding. */
437 53108fb5 Kirill Batuzov
                break;
438 53108fb5 Kirill Batuzov
            }
439 53108fb5 Kirill Batuzov
            if (temps[args[2]].state == TCG_TEMP_CONST
440 53108fb5 Kirill Batuzov
                && temps[args[2]].val == 0) {
441 53108fb5 Kirill Batuzov
                if ((temps[args[0]].state == TCG_TEMP_COPY
442 53108fb5 Kirill Batuzov
                    && temps[args[0]].val == args[1])
443 53108fb5 Kirill Batuzov
                    || args[0] == args[1]) {
444 53108fb5 Kirill Batuzov
                    gen_opc_buf[op_index] = INDEX_op_nop;
445 53108fb5 Kirill Batuzov
                } else {
446 53108fb5 Kirill Batuzov
                    gen_opc_buf[op_index] = op_to_mov(op);
447 e31b0a7c Blue Swirl
                    tcg_opt_gen_mov(s, gen_args, args[0], args[1],
448 53108fb5 Kirill Batuzov
                                    nb_temps, nb_globals);
449 53108fb5 Kirill Batuzov
                    gen_args += 2;
450 53108fb5 Kirill Batuzov
                }
451 fedc0da2 Aurelien Jarno
                args += 3;
452 53108fb5 Kirill Batuzov
                continue;
453 53108fb5 Kirill Batuzov
            }
454 53108fb5 Kirill Batuzov
            break;
455 56e49438 Aurelien Jarno
        default:
456 56e49438 Aurelien Jarno
            break;
457 56e49438 Aurelien Jarno
        }
458 56e49438 Aurelien Jarno
459 56e49438 Aurelien Jarno
        /* Simplify expression for "op r, a, 0 => movi r, 0" cases */
460 56e49438 Aurelien Jarno
        switch (op) {
461 61251c0c Aurelien Jarno
        CASE_OP_32_64(and):
462 53108fb5 Kirill Batuzov
        CASE_OP_32_64(mul):
463 53108fb5 Kirill Batuzov
            if ((temps[args[2]].state == TCG_TEMP_CONST
464 53108fb5 Kirill Batuzov
                && temps[args[2]].val == 0)) {
465 53108fb5 Kirill Batuzov
                gen_opc_buf[op_index] = op_to_movi(op);
466 53108fb5 Kirill Batuzov
                tcg_opt_gen_movi(gen_args, args[0], 0, nb_temps, nb_globals);
467 53108fb5 Kirill Batuzov
                args += 3;
468 53108fb5 Kirill Batuzov
                gen_args += 2;
469 53108fb5 Kirill Batuzov
                continue;
470 53108fb5 Kirill Batuzov
            }
471 53108fb5 Kirill Batuzov
            break;
472 56e49438 Aurelien Jarno
        default:
473 56e49438 Aurelien Jarno
            break;
474 56e49438 Aurelien Jarno
        }
475 56e49438 Aurelien Jarno
476 56e49438 Aurelien Jarno
        /* Simplify expression for "op r, a, a => mov r, a" cases */
477 56e49438 Aurelien Jarno
        switch (op) {
478 9a81090b Kirill Batuzov
        CASE_OP_32_64(or):
479 9a81090b Kirill Batuzov
        CASE_OP_32_64(and):
480 9a81090b Kirill Batuzov
            if (args[1] == args[2]) {
481 9a81090b Kirill Batuzov
                if (args[1] == args[0]) {
482 9a81090b Kirill Batuzov
                    gen_opc_buf[op_index] = INDEX_op_nop;
483 9a81090b Kirill Batuzov
                } else {
484 9a81090b Kirill Batuzov
                    gen_opc_buf[op_index] = op_to_mov(op);
485 e31b0a7c Blue Swirl
                    tcg_opt_gen_mov(s, gen_args, args[0], args[1], nb_temps,
486 9a81090b Kirill Batuzov
                                    nb_globals);
487 9a81090b Kirill Batuzov
                    gen_args += 2;
488 9a81090b Kirill Batuzov
                }
489 fedc0da2 Aurelien Jarno
                args += 3;
490 9a81090b Kirill Batuzov
                continue;
491 9a81090b Kirill Batuzov
            }
492 9a81090b Kirill Batuzov
            break;
493 fe0de7aa Blue Swirl
        default:
494 fe0de7aa Blue Swirl
            break;
495 53108fb5 Kirill Batuzov
        }
496 53108fb5 Kirill Batuzov
497 22613af4 Kirill Batuzov
        /* Propagate constants through copy operations and do constant
498 22613af4 Kirill Batuzov
           folding.  Constants will be substituted to arguments by register
499 22613af4 Kirill Batuzov
           allocator where needed and possible.  Also detect copies. */
500 8f2e8c07 Kirill Batuzov
        switch (op) {
501 22613af4 Kirill Batuzov
        CASE_OP_32_64(mov):
502 22613af4 Kirill Batuzov
            if ((temps[args[1]].state == TCG_TEMP_COPY
503 22613af4 Kirill Batuzov
                && temps[args[1]].val == args[0])
504 22613af4 Kirill Batuzov
                || args[0] == args[1]) {
505 22613af4 Kirill Batuzov
                args += 2;
506 22613af4 Kirill Batuzov
                gen_opc_buf[op_index] = INDEX_op_nop;
507 22613af4 Kirill Batuzov
                break;
508 22613af4 Kirill Batuzov
            }
509 22613af4 Kirill Batuzov
            if (temps[args[1]].state != TCG_TEMP_CONST) {
510 e31b0a7c Blue Swirl
                tcg_opt_gen_mov(s, gen_args, args[0], args[1],
511 22613af4 Kirill Batuzov
                                nb_temps, nb_globals);
512 22613af4 Kirill Batuzov
                gen_args += 2;
513 22613af4 Kirill Batuzov
                args += 2;
514 22613af4 Kirill Batuzov
                break;
515 22613af4 Kirill Batuzov
            }
516 22613af4 Kirill Batuzov
            /* Source argument is constant.  Rewrite the operation and
517 22613af4 Kirill Batuzov
               let movi case handle it. */
518 22613af4 Kirill Batuzov
            op = op_to_movi(op);
519 22613af4 Kirill Batuzov
            gen_opc_buf[op_index] = op;
520 22613af4 Kirill Batuzov
            args[1] = temps[args[1]].val;
521 22613af4 Kirill Batuzov
            /* fallthrough */
522 22613af4 Kirill Batuzov
        CASE_OP_32_64(movi):
523 22613af4 Kirill Batuzov
            tcg_opt_gen_movi(gen_args, args[0], args[1], nb_temps, nb_globals);
524 22613af4 Kirill Batuzov
            gen_args += 2;
525 22613af4 Kirill Batuzov
            args += 2;
526 22613af4 Kirill Batuzov
            break;
527 a640f031 Kirill Batuzov
        CASE_OP_32_64(not):
528 cb25c80a Richard Henderson
        CASE_OP_32_64(neg):
529 25c4d9cc Richard Henderson
        CASE_OP_32_64(ext8s):
530 25c4d9cc Richard Henderson
        CASE_OP_32_64(ext8u):
531 25c4d9cc Richard Henderson
        CASE_OP_32_64(ext16s):
532 25c4d9cc Richard Henderson
        CASE_OP_32_64(ext16u):
533 a640f031 Kirill Batuzov
        case INDEX_op_ext32s_i64:
534 a640f031 Kirill Batuzov
        case INDEX_op_ext32u_i64:
535 a640f031 Kirill Batuzov
            if (temps[args[1]].state == TCG_TEMP_CONST) {
536 a640f031 Kirill Batuzov
                gen_opc_buf[op_index] = op_to_movi(op);
537 a640f031 Kirill Batuzov
                tmp = do_constant_folding(op, temps[args[1]].val, 0);
538 a640f031 Kirill Batuzov
                tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
539 a640f031 Kirill Batuzov
            } else {
540 a640f031 Kirill Batuzov
                reset_temp(args[0], nb_temps, nb_globals);
541 a640f031 Kirill Batuzov
                gen_args[0] = args[0];
542 a640f031 Kirill Batuzov
                gen_args[1] = args[1];
543 a640f031 Kirill Batuzov
            }
544 fedc0da2 Aurelien Jarno
            gen_args += 2;
545 fedc0da2 Aurelien Jarno
            args += 2;
546 fedc0da2 Aurelien Jarno
            break;
547 53108fb5 Kirill Batuzov
        CASE_OP_32_64(add):
548 53108fb5 Kirill Batuzov
        CASE_OP_32_64(sub):
549 53108fb5 Kirill Batuzov
        CASE_OP_32_64(mul):
550 9a81090b Kirill Batuzov
        CASE_OP_32_64(or):
551 9a81090b Kirill Batuzov
        CASE_OP_32_64(and):
552 9a81090b Kirill Batuzov
        CASE_OP_32_64(xor):
553 55c0975c Kirill Batuzov
        CASE_OP_32_64(shl):
554 55c0975c Kirill Batuzov
        CASE_OP_32_64(shr):
555 55c0975c Kirill Batuzov
        CASE_OP_32_64(sar):
556 25c4d9cc Richard Henderson
        CASE_OP_32_64(rotl):
557 25c4d9cc Richard Henderson
        CASE_OP_32_64(rotr):
558 cb25c80a Richard Henderson
        CASE_OP_32_64(andc):
559 cb25c80a Richard Henderson
        CASE_OP_32_64(orc):
560 cb25c80a Richard Henderson
        CASE_OP_32_64(eqv):
561 cb25c80a Richard Henderson
        CASE_OP_32_64(nand):
562 cb25c80a Richard Henderson
        CASE_OP_32_64(nor):
563 53108fb5 Kirill Batuzov
            if (temps[args[1]].state == TCG_TEMP_CONST
564 53108fb5 Kirill Batuzov
                && temps[args[2]].state == TCG_TEMP_CONST) {
565 53108fb5 Kirill Batuzov
                gen_opc_buf[op_index] = op_to_movi(op);
566 53108fb5 Kirill Batuzov
                tmp = do_constant_folding(op, temps[args[1]].val,
567 53108fb5 Kirill Batuzov
                                          temps[args[2]].val);
568 53108fb5 Kirill Batuzov
                tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
569 53108fb5 Kirill Batuzov
                gen_args += 2;
570 53108fb5 Kirill Batuzov
            } else {
571 53108fb5 Kirill Batuzov
                reset_temp(args[0], nb_temps, nb_globals);
572 53108fb5 Kirill Batuzov
                gen_args[0] = args[0];
573 53108fb5 Kirill Batuzov
                gen_args[1] = args[1];
574 53108fb5 Kirill Batuzov
                gen_args[2] = args[2];
575 53108fb5 Kirill Batuzov
                gen_args += 3;
576 53108fb5 Kirill Batuzov
            }
577 fedc0da2 Aurelien Jarno
            args += 3;
578 fedc0da2 Aurelien Jarno
            break;
579 f8dd19e5 Aurelien Jarno
        CASE_OP_32_64(setcond):
580 f8dd19e5 Aurelien Jarno
            if (temps[args[1]].state == TCG_TEMP_CONST
581 f8dd19e5 Aurelien Jarno
                && temps[args[2]].state == TCG_TEMP_CONST) {
582 f8dd19e5 Aurelien Jarno
                gen_opc_buf[op_index] = op_to_movi(op);
583 f8dd19e5 Aurelien Jarno
                tmp = do_constant_folding_cond(op, temps[args[1]].val,
584 f8dd19e5 Aurelien Jarno
                                               temps[args[2]].val, args[3]);
585 f8dd19e5 Aurelien Jarno
                tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
586 f8dd19e5 Aurelien Jarno
                gen_args += 2;
587 f8dd19e5 Aurelien Jarno
            } else {
588 f8dd19e5 Aurelien Jarno
                reset_temp(args[0], nb_temps, nb_globals);
589 f8dd19e5 Aurelien Jarno
                gen_args[0] = args[0];
590 f8dd19e5 Aurelien Jarno
                gen_args[1] = args[1];
591 f8dd19e5 Aurelien Jarno
                gen_args[2] = args[2];
592 f8dd19e5 Aurelien Jarno
                gen_args[3] = args[3];
593 f8dd19e5 Aurelien Jarno
                gen_args += 4;
594 f8dd19e5 Aurelien Jarno
            }
595 fedc0da2 Aurelien Jarno
            args += 4;
596 fedc0da2 Aurelien Jarno
            break;
597 fbeaa26c Aurelien Jarno
        CASE_OP_32_64(brcond):
598 fbeaa26c Aurelien Jarno
            if (temps[args[0]].state == TCG_TEMP_CONST
599 fbeaa26c Aurelien Jarno
                && temps[args[1]].state == TCG_TEMP_CONST) {
600 fbeaa26c Aurelien Jarno
                if (do_constant_folding_cond(op, temps[args[0]].val,
601 fbeaa26c Aurelien Jarno
                                             temps[args[1]].val, args[2])) {
602 fbeaa26c Aurelien Jarno
                    memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
603 fbeaa26c Aurelien Jarno
                    gen_opc_buf[op_index] = INDEX_op_br;
604 fbeaa26c Aurelien Jarno
                    gen_args[0] = args[3];
605 fbeaa26c Aurelien Jarno
                    gen_args += 1;
606 fbeaa26c Aurelien Jarno
                } else {
607 fbeaa26c Aurelien Jarno
                    gen_opc_buf[op_index] = INDEX_op_nop;
608 fbeaa26c Aurelien Jarno
                }
609 fbeaa26c Aurelien Jarno
            } else {
610 fbeaa26c Aurelien Jarno
                memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
611 fbeaa26c Aurelien Jarno
                reset_temp(args[0], nb_temps, nb_globals);
612 fbeaa26c Aurelien Jarno
                gen_args[0] = args[0];
613 fbeaa26c Aurelien Jarno
                gen_args[1] = args[1];
614 fbeaa26c Aurelien Jarno
                gen_args[2] = args[2];
615 fbeaa26c Aurelien Jarno
                gen_args[3] = args[3];
616 fbeaa26c Aurelien Jarno
                gen_args += 4;
617 fbeaa26c Aurelien Jarno
            }
618 fedc0da2 Aurelien Jarno
            args += 4;
619 fedc0da2 Aurelien Jarno
            break;
620 8f2e8c07 Kirill Batuzov
        case INDEX_op_call:
621 22613af4 Kirill Batuzov
            nb_call_args = (args[0] >> 16) + (args[0] & 0xffff);
622 22613af4 Kirill Batuzov
            if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) {
623 22613af4 Kirill Batuzov
                for (i = 0; i < nb_globals; i++) {
624 22613af4 Kirill Batuzov
                    reset_temp(i, nb_temps, nb_globals);
625 22613af4 Kirill Batuzov
                }
626 22613af4 Kirill Batuzov
            }
627 22613af4 Kirill Batuzov
            for (i = 0; i < (args[0] >> 16); i++) {
628 22613af4 Kirill Batuzov
                reset_temp(args[i + 1], nb_temps, nb_globals);
629 22613af4 Kirill Batuzov
            }
630 22613af4 Kirill Batuzov
            i = nb_call_args + 3;
631 8f2e8c07 Kirill Batuzov
            while (i) {
632 8f2e8c07 Kirill Batuzov
                *gen_args = *args;
633 8f2e8c07 Kirill Batuzov
                args++;
634 8f2e8c07 Kirill Batuzov
                gen_args++;
635 8f2e8c07 Kirill Batuzov
                i--;
636 8f2e8c07 Kirill Batuzov
            }
637 8f2e8c07 Kirill Batuzov
            break;
638 8f2e8c07 Kirill Batuzov
        case INDEX_op_set_label:
639 8f2e8c07 Kirill Batuzov
        case INDEX_op_jmp:
640 8f2e8c07 Kirill Batuzov
        case INDEX_op_br:
641 22613af4 Kirill Batuzov
            memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
642 8f2e8c07 Kirill Batuzov
            for (i = 0; i < def->nb_args; i++) {
643 8f2e8c07 Kirill Batuzov
                *gen_args = *args;
644 8f2e8c07 Kirill Batuzov
                args++;
645 8f2e8c07 Kirill Batuzov
                gen_args++;
646 8f2e8c07 Kirill Batuzov
            }
647 8f2e8c07 Kirill Batuzov
            break;
648 8f2e8c07 Kirill Batuzov
        default:
649 22613af4 Kirill Batuzov
            /* Default case: we do know nothing about operation so no
650 22613af4 Kirill Batuzov
               propagation is done.  We only trash output args.  */
651 22613af4 Kirill Batuzov
            for (i = 0; i < def->nb_oargs; i++) {
652 22613af4 Kirill Batuzov
                reset_temp(args[i], nb_temps, nb_globals);
653 22613af4 Kirill Batuzov
            }
654 8f2e8c07 Kirill Batuzov
            for (i = 0; i < def->nb_args; i++) {
655 8f2e8c07 Kirill Batuzov
                gen_args[i] = args[i];
656 8f2e8c07 Kirill Batuzov
            }
657 8f2e8c07 Kirill Batuzov
            args += def->nb_args;
658 8f2e8c07 Kirill Batuzov
            gen_args += def->nb_args;
659 8f2e8c07 Kirill Batuzov
            break;
660 8f2e8c07 Kirill Batuzov
        }
661 8f2e8c07 Kirill Batuzov
    }
662 8f2e8c07 Kirill Batuzov
663 8f2e8c07 Kirill Batuzov
    return gen_args;
664 8f2e8c07 Kirill Batuzov
}
665 8f2e8c07 Kirill Batuzov
666 8f2e8c07 Kirill Batuzov
TCGArg *tcg_optimize(TCGContext *s, uint16_t *tcg_opc_ptr,
667 8f2e8c07 Kirill Batuzov
        TCGArg *args, TCGOpDef *tcg_op_defs)
668 8f2e8c07 Kirill Batuzov
{
669 8f2e8c07 Kirill Batuzov
    TCGArg *res;
670 8f2e8c07 Kirill Batuzov
    res = tcg_constant_folding(s, tcg_opc_ptr, args, tcg_op_defs);
671 8f2e8c07 Kirill Batuzov
    return res;
672 8f2e8c07 Kirill Batuzov
}