Statistics
| Branch: | Revision:

root / tcg / optimize.c @ e590d4e6

History | View | Annotate | Download (22.4 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_state;
43 22613af4 Kirill Batuzov
44 22613af4 Kirill Batuzov
struct tcg_temp_info {
45 22613af4 Kirill Batuzov
    tcg_temp_state state;
46 22613af4 Kirill Batuzov
    uint16_t prev_copy;
47 22613af4 Kirill Batuzov
    uint16_t next_copy;
48 22613af4 Kirill Batuzov
    tcg_target_ulong val;
49 22613af4 Kirill Batuzov
};
50 22613af4 Kirill Batuzov
51 22613af4 Kirill Batuzov
static struct tcg_temp_info temps[TCG_MAX_TEMPS];
52 22613af4 Kirill Batuzov
53 e590d4e6 Aurelien Jarno
/* Reset TEMP's state to TCG_TEMP_UNDEF.  If TEMP only had one copy, remove
54 e590d4e6 Aurelien Jarno
   the copy flag from the left temp.  */
55 e590d4e6 Aurelien Jarno
static void reset_temp(TCGArg temp)
56 22613af4 Kirill Batuzov
{
57 e590d4e6 Aurelien Jarno
    if (temps[temp].state == TCG_TEMP_COPY) {
58 e590d4e6 Aurelien Jarno
        if (temps[temp].prev_copy == temps[temp].next_copy) {
59 e590d4e6 Aurelien Jarno
            temps[temps[temp].next_copy].state = TCG_TEMP_UNDEF;
60 e590d4e6 Aurelien Jarno
        } else {
61 e590d4e6 Aurelien Jarno
            temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy;
62 e590d4e6 Aurelien Jarno
            temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy;
63 22613af4 Kirill Batuzov
        }
64 22613af4 Kirill Batuzov
    }
65 48b56ce1 Aurelien Jarno
    temps[temp].state = TCG_TEMP_UNDEF;
66 22613af4 Kirill Batuzov
}
67 22613af4 Kirill Batuzov
68 fe0de7aa Blue Swirl
static int op_bits(TCGOpcode op)
69 22613af4 Kirill Batuzov
{
70 8399ad59 Richard Henderson
    const TCGOpDef *def = &tcg_op_defs[op];
71 8399ad59 Richard Henderson
    return def->flags & TCG_OPF_64BIT ? 64 : 32;
72 22613af4 Kirill Batuzov
}
73 22613af4 Kirill Batuzov
74 fe0de7aa Blue Swirl
static TCGOpcode op_to_movi(TCGOpcode op)
75 22613af4 Kirill Batuzov
{
76 22613af4 Kirill Batuzov
    switch (op_bits(op)) {
77 22613af4 Kirill Batuzov
    case 32:
78 22613af4 Kirill Batuzov
        return INDEX_op_movi_i32;
79 22613af4 Kirill Batuzov
    case 64:
80 22613af4 Kirill Batuzov
        return INDEX_op_movi_i64;
81 22613af4 Kirill Batuzov
    default:
82 22613af4 Kirill Batuzov
        fprintf(stderr, "op_to_movi: unexpected return value of "
83 22613af4 Kirill Batuzov
                "function op_bits.\n");
84 22613af4 Kirill Batuzov
        tcg_abort();
85 22613af4 Kirill Batuzov
    }
86 22613af4 Kirill Batuzov
}
87 22613af4 Kirill Batuzov
88 e590d4e6 Aurelien Jarno
static TCGArg find_better_copy(TCGContext *s, TCGArg temp)
89 e590d4e6 Aurelien Jarno
{
90 e590d4e6 Aurelien Jarno
    TCGArg i;
91 e590d4e6 Aurelien Jarno
92 e590d4e6 Aurelien Jarno
    /* If this is already a global, we can't do better. */
93 e590d4e6 Aurelien Jarno
    if (temp < s->nb_globals) {
94 e590d4e6 Aurelien Jarno
        return temp;
95 e590d4e6 Aurelien Jarno
    }
96 e590d4e6 Aurelien Jarno
97 e590d4e6 Aurelien Jarno
    /* Search for a global first. */
98 e590d4e6 Aurelien Jarno
    for (i = temps[temp].next_copy ; i != temp ; i = temps[i].next_copy) {
99 e590d4e6 Aurelien Jarno
        if (i < s->nb_globals) {
100 e590d4e6 Aurelien Jarno
            return i;
101 e590d4e6 Aurelien Jarno
        }
102 e590d4e6 Aurelien Jarno
    }
103 e590d4e6 Aurelien Jarno
104 e590d4e6 Aurelien Jarno
    /* If it is a temp, search for a temp local. */
105 e590d4e6 Aurelien Jarno
    if (!s->temps[temp].temp_local) {
106 e590d4e6 Aurelien Jarno
        for (i = temps[temp].next_copy ; i != temp ; i = temps[i].next_copy) {
107 e590d4e6 Aurelien Jarno
            if (s->temps[i].temp_local) {
108 e590d4e6 Aurelien Jarno
                return i;
109 e590d4e6 Aurelien Jarno
            }
110 e590d4e6 Aurelien Jarno
        }
111 e590d4e6 Aurelien Jarno
    }
112 e590d4e6 Aurelien Jarno
113 e590d4e6 Aurelien Jarno
    /* Failure to find a better representation, return the same temp. */
114 e590d4e6 Aurelien Jarno
    return temp;
115 e590d4e6 Aurelien Jarno
}
116 e590d4e6 Aurelien Jarno
117 e590d4e6 Aurelien Jarno
static bool temps_are_copies(TCGArg arg1, TCGArg arg2)
118 e590d4e6 Aurelien Jarno
{
119 e590d4e6 Aurelien Jarno
    TCGArg i;
120 e590d4e6 Aurelien Jarno
121 e590d4e6 Aurelien Jarno
    if (arg1 == arg2) {
122 e590d4e6 Aurelien Jarno
        return true;
123 e590d4e6 Aurelien Jarno
    }
124 e590d4e6 Aurelien Jarno
125 e590d4e6 Aurelien Jarno
    if (temps[arg1].state != TCG_TEMP_COPY
126 e590d4e6 Aurelien Jarno
        || temps[arg2].state != TCG_TEMP_COPY) {
127 e590d4e6 Aurelien Jarno
        return false;
128 e590d4e6 Aurelien Jarno
    }
129 e590d4e6 Aurelien Jarno
130 e590d4e6 Aurelien Jarno
    for (i = temps[arg1].next_copy ; i != arg1 ; i = temps[i].next_copy) {
131 e590d4e6 Aurelien Jarno
        if (i == arg2) {
132 e590d4e6 Aurelien Jarno
            return true;
133 e590d4e6 Aurelien Jarno
        }
134 e590d4e6 Aurelien Jarno
    }
135 e590d4e6 Aurelien Jarno
136 e590d4e6 Aurelien Jarno
    return false;
137 e590d4e6 Aurelien Jarno
}
138 e590d4e6 Aurelien Jarno
139 b80bb016 Aurelien Jarno
static void tcg_opt_gen_mov(TCGContext *s, TCGArg *gen_args,
140 b80bb016 Aurelien Jarno
                            TCGArg dst, TCGArg src)
141 22613af4 Kirill Batuzov
{
142 e590d4e6 Aurelien Jarno
        reset_temp(dst);
143 e590d4e6 Aurelien Jarno
        assert(temps[src].state != TCG_TEMP_CONST);
144 e590d4e6 Aurelien Jarno
145 e590d4e6 Aurelien Jarno
        if (s->temps[src].type == s->temps[dst].type) {
146 e590d4e6 Aurelien Jarno
            if (temps[src].state != TCG_TEMP_COPY) {
147 e590d4e6 Aurelien Jarno
                temps[src].state = TCG_TEMP_COPY;
148 22613af4 Kirill Batuzov
                temps[src].next_copy = src;
149 22613af4 Kirill Batuzov
                temps[src].prev_copy = src;
150 22613af4 Kirill Batuzov
            }
151 22613af4 Kirill Batuzov
            temps[dst].state = TCG_TEMP_COPY;
152 22613af4 Kirill Batuzov
            temps[dst].next_copy = temps[src].next_copy;
153 22613af4 Kirill Batuzov
            temps[dst].prev_copy = src;
154 22613af4 Kirill Batuzov
            temps[temps[dst].next_copy].prev_copy = dst;
155 22613af4 Kirill Batuzov
            temps[src].next_copy = dst;
156 22613af4 Kirill Batuzov
        }
157 e590d4e6 Aurelien Jarno
158 22613af4 Kirill Batuzov
        gen_args[0] = dst;
159 22613af4 Kirill Batuzov
        gen_args[1] = src;
160 22613af4 Kirill Batuzov
}
161 22613af4 Kirill Batuzov
162 e590d4e6 Aurelien Jarno
static void tcg_opt_gen_movi(TCGArg *gen_args, TCGArg dst, TCGArg val)
163 22613af4 Kirill Batuzov
{
164 e590d4e6 Aurelien Jarno
        reset_temp(dst);
165 22613af4 Kirill Batuzov
        temps[dst].state = TCG_TEMP_CONST;
166 22613af4 Kirill Batuzov
        temps[dst].val = val;
167 22613af4 Kirill Batuzov
        gen_args[0] = dst;
168 22613af4 Kirill Batuzov
        gen_args[1] = val;
169 22613af4 Kirill Batuzov
}
170 22613af4 Kirill Batuzov
171 fe0de7aa Blue Swirl
static TCGOpcode op_to_mov(TCGOpcode op)
172 53108fb5 Kirill Batuzov
{
173 53108fb5 Kirill Batuzov
    switch (op_bits(op)) {
174 53108fb5 Kirill Batuzov
    case 32:
175 53108fb5 Kirill Batuzov
        return INDEX_op_mov_i32;
176 53108fb5 Kirill Batuzov
    case 64:
177 53108fb5 Kirill Batuzov
        return INDEX_op_mov_i64;
178 53108fb5 Kirill Batuzov
    default:
179 53108fb5 Kirill Batuzov
        fprintf(stderr, "op_to_mov: unexpected return value of "
180 53108fb5 Kirill Batuzov
                "function op_bits.\n");
181 53108fb5 Kirill Batuzov
        tcg_abort();
182 53108fb5 Kirill Batuzov
    }
183 53108fb5 Kirill Batuzov
}
184 53108fb5 Kirill Batuzov
185 fe0de7aa Blue Swirl
static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y)
186 53108fb5 Kirill Batuzov
{
187 53108fb5 Kirill Batuzov
    switch (op) {
188 53108fb5 Kirill Batuzov
    CASE_OP_32_64(add):
189 53108fb5 Kirill Batuzov
        return x + y;
190 53108fb5 Kirill Batuzov
191 53108fb5 Kirill Batuzov
    CASE_OP_32_64(sub):
192 53108fb5 Kirill Batuzov
        return x - y;
193 53108fb5 Kirill Batuzov
194 53108fb5 Kirill Batuzov
    CASE_OP_32_64(mul):
195 53108fb5 Kirill Batuzov
        return x * y;
196 53108fb5 Kirill Batuzov
197 9a81090b Kirill Batuzov
    CASE_OP_32_64(and):
198 9a81090b Kirill Batuzov
        return x & y;
199 9a81090b Kirill Batuzov
200 9a81090b Kirill Batuzov
    CASE_OP_32_64(or):
201 9a81090b Kirill Batuzov
        return x | y;
202 9a81090b Kirill Batuzov
203 9a81090b Kirill Batuzov
    CASE_OP_32_64(xor):
204 9a81090b Kirill Batuzov
        return x ^ y;
205 9a81090b Kirill Batuzov
206 55c0975c Kirill Batuzov
    case INDEX_op_shl_i32:
207 55c0975c Kirill Batuzov
        return (uint32_t)x << (uint32_t)y;
208 55c0975c Kirill Batuzov
209 55c0975c Kirill Batuzov
    case INDEX_op_shl_i64:
210 55c0975c Kirill Batuzov
        return (uint64_t)x << (uint64_t)y;
211 55c0975c Kirill Batuzov
212 55c0975c Kirill Batuzov
    case INDEX_op_shr_i32:
213 55c0975c Kirill Batuzov
        return (uint32_t)x >> (uint32_t)y;
214 55c0975c Kirill Batuzov
215 55c0975c Kirill Batuzov
    case INDEX_op_shr_i64:
216 55c0975c Kirill Batuzov
        return (uint64_t)x >> (uint64_t)y;
217 55c0975c Kirill Batuzov
218 55c0975c Kirill Batuzov
    case INDEX_op_sar_i32:
219 55c0975c Kirill Batuzov
        return (int32_t)x >> (int32_t)y;
220 55c0975c Kirill Batuzov
221 55c0975c Kirill Batuzov
    case INDEX_op_sar_i64:
222 55c0975c Kirill Batuzov
        return (int64_t)x >> (int64_t)y;
223 55c0975c Kirill Batuzov
224 55c0975c Kirill Batuzov
    case INDEX_op_rotr_i32:
225 25c4d9cc Richard Henderson
        x = ((uint32_t)x << (32 - y)) | ((uint32_t)x >> y);
226 55c0975c Kirill Batuzov
        return x;
227 55c0975c Kirill Batuzov
228 55c0975c Kirill Batuzov
    case INDEX_op_rotr_i64:
229 25c4d9cc Richard Henderson
        x = ((uint64_t)x << (64 - y)) | ((uint64_t)x >> y);
230 55c0975c Kirill Batuzov
        return x;
231 55c0975c Kirill Batuzov
232 55c0975c Kirill Batuzov
    case INDEX_op_rotl_i32:
233 25c4d9cc Richard Henderson
        x = ((uint32_t)x << y) | ((uint32_t)x >> (32 - y));
234 55c0975c Kirill Batuzov
        return x;
235 55c0975c Kirill Batuzov
236 55c0975c Kirill Batuzov
    case INDEX_op_rotl_i64:
237 25c4d9cc Richard Henderson
        x = ((uint64_t)x << y) | ((uint64_t)x >> (64 - y));
238 55c0975c Kirill Batuzov
        return x;
239 25c4d9cc Richard Henderson
240 25c4d9cc Richard Henderson
    CASE_OP_32_64(not):
241 a640f031 Kirill Batuzov
        return ~x;
242 25c4d9cc Richard Henderson
243 cb25c80a Richard Henderson
    CASE_OP_32_64(neg):
244 cb25c80a Richard Henderson
        return -x;
245 cb25c80a Richard Henderson
246 cb25c80a Richard Henderson
    CASE_OP_32_64(andc):
247 cb25c80a Richard Henderson
        return x & ~y;
248 cb25c80a Richard Henderson
249 cb25c80a Richard Henderson
    CASE_OP_32_64(orc):
250 cb25c80a Richard Henderson
        return x | ~y;
251 cb25c80a Richard Henderson
252 cb25c80a Richard Henderson
    CASE_OP_32_64(eqv):
253 cb25c80a Richard Henderson
        return ~(x ^ y);
254 cb25c80a Richard Henderson
255 cb25c80a Richard Henderson
    CASE_OP_32_64(nand):
256 cb25c80a Richard Henderson
        return ~(x & y);
257 cb25c80a Richard Henderson
258 cb25c80a Richard Henderson
    CASE_OP_32_64(nor):
259 cb25c80a Richard Henderson
        return ~(x | y);
260 cb25c80a Richard Henderson
261 25c4d9cc Richard Henderson
    CASE_OP_32_64(ext8s):
262 a640f031 Kirill Batuzov
        return (int8_t)x;
263 25c4d9cc Richard Henderson
264 25c4d9cc Richard Henderson
    CASE_OP_32_64(ext16s):
265 a640f031 Kirill Batuzov
        return (int16_t)x;
266 25c4d9cc Richard Henderson
267 25c4d9cc Richard Henderson
    CASE_OP_32_64(ext8u):
268 a640f031 Kirill Batuzov
        return (uint8_t)x;
269 25c4d9cc Richard Henderson
270 25c4d9cc Richard Henderson
    CASE_OP_32_64(ext16u):
271 a640f031 Kirill Batuzov
        return (uint16_t)x;
272 a640f031 Kirill Batuzov
273 a640f031 Kirill Batuzov
    case INDEX_op_ext32s_i64:
274 a640f031 Kirill Batuzov
        return (int32_t)x;
275 a640f031 Kirill Batuzov
276 a640f031 Kirill Batuzov
    case INDEX_op_ext32u_i64:
277 a640f031 Kirill Batuzov
        return (uint32_t)x;
278 a640f031 Kirill Batuzov
279 53108fb5 Kirill Batuzov
    default:
280 53108fb5 Kirill Batuzov
        fprintf(stderr,
281 53108fb5 Kirill Batuzov
                "Unrecognized operation %d in do_constant_folding.\n", op);
282 53108fb5 Kirill Batuzov
        tcg_abort();
283 53108fb5 Kirill Batuzov
    }
284 53108fb5 Kirill Batuzov
}
285 53108fb5 Kirill Batuzov
286 fe0de7aa Blue Swirl
static TCGArg do_constant_folding(TCGOpcode op, TCGArg x, TCGArg y)
287 53108fb5 Kirill Batuzov
{
288 53108fb5 Kirill Batuzov
    TCGArg res = do_constant_folding_2(op, x, y);
289 53108fb5 Kirill Batuzov
    if (op_bits(op) == 32) {
290 53108fb5 Kirill Batuzov
        res &= 0xffffffff;
291 53108fb5 Kirill Batuzov
    }
292 53108fb5 Kirill Batuzov
    return res;
293 53108fb5 Kirill Batuzov
}
294 53108fb5 Kirill Batuzov
295 f8dd19e5 Aurelien Jarno
static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x,
296 f8dd19e5 Aurelien Jarno
                                       TCGArg y, TCGCond c)
297 f8dd19e5 Aurelien Jarno
{
298 f8dd19e5 Aurelien Jarno
    switch (op_bits(op)) {
299 f8dd19e5 Aurelien Jarno
    case 32:
300 f8dd19e5 Aurelien Jarno
        switch (c) {
301 f8dd19e5 Aurelien Jarno
        case TCG_COND_EQ:
302 f8dd19e5 Aurelien Jarno
            return (uint32_t)x == (uint32_t)y;
303 f8dd19e5 Aurelien Jarno
        case TCG_COND_NE:
304 f8dd19e5 Aurelien Jarno
            return (uint32_t)x != (uint32_t)y;
305 f8dd19e5 Aurelien Jarno
        case TCG_COND_LT:
306 f8dd19e5 Aurelien Jarno
            return (int32_t)x < (int32_t)y;
307 f8dd19e5 Aurelien Jarno
        case TCG_COND_GE:
308 f8dd19e5 Aurelien Jarno
            return (int32_t)x >= (int32_t)y;
309 f8dd19e5 Aurelien Jarno
        case TCG_COND_LE:
310 f8dd19e5 Aurelien Jarno
            return (int32_t)x <= (int32_t)y;
311 f8dd19e5 Aurelien Jarno
        case TCG_COND_GT:
312 f8dd19e5 Aurelien Jarno
            return (int32_t)x > (int32_t)y;
313 f8dd19e5 Aurelien Jarno
        case TCG_COND_LTU:
314 f8dd19e5 Aurelien Jarno
            return (uint32_t)x < (uint32_t)y;
315 f8dd19e5 Aurelien Jarno
        case TCG_COND_GEU:
316 f8dd19e5 Aurelien Jarno
            return (uint32_t)x >= (uint32_t)y;
317 f8dd19e5 Aurelien Jarno
        case TCG_COND_LEU:
318 f8dd19e5 Aurelien Jarno
            return (uint32_t)x <= (uint32_t)y;
319 f8dd19e5 Aurelien Jarno
        case TCG_COND_GTU:
320 f8dd19e5 Aurelien Jarno
            return (uint32_t)x > (uint32_t)y;
321 f8dd19e5 Aurelien Jarno
        }
322 f8dd19e5 Aurelien Jarno
        break;
323 f8dd19e5 Aurelien Jarno
    case 64:
324 f8dd19e5 Aurelien Jarno
        switch (c) {
325 f8dd19e5 Aurelien Jarno
        case TCG_COND_EQ:
326 f8dd19e5 Aurelien Jarno
            return (uint64_t)x == (uint64_t)y;
327 f8dd19e5 Aurelien Jarno
        case TCG_COND_NE:
328 f8dd19e5 Aurelien Jarno
            return (uint64_t)x != (uint64_t)y;
329 f8dd19e5 Aurelien Jarno
        case TCG_COND_LT:
330 f8dd19e5 Aurelien Jarno
            return (int64_t)x < (int64_t)y;
331 f8dd19e5 Aurelien Jarno
        case TCG_COND_GE:
332 f8dd19e5 Aurelien Jarno
            return (int64_t)x >= (int64_t)y;
333 f8dd19e5 Aurelien Jarno
        case TCG_COND_LE:
334 f8dd19e5 Aurelien Jarno
            return (int64_t)x <= (int64_t)y;
335 f8dd19e5 Aurelien Jarno
        case TCG_COND_GT:
336 f8dd19e5 Aurelien Jarno
            return (int64_t)x > (int64_t)y;
337 f8dd19e5 Aurelien Jarno
        case TCG_COND_LTU:
338 f8dd19e5 Aurelien Jarno
            return (uint64_t)x < (uint64_t)y;
339 f8dd19e5 Aurelien Jarno
        case TCG_COND_GEU:
340 f8dd19e5 Aurelien Jarno
            return (uint64_t)x >= (uint64_t)y;
341 f8dd19e5 Aurelien Jarno
        case TCG_COND_LEU:
342 f8dd19e5 Aurelien Jarno
            return (uint64_t)x <= (uint64_t)y;
343 f8dd19e5 Aurelien Jarno
        case TCG_COND_GTU:
344 f8dd19e5 Aurelien Jarno
            return (uint64_t)x > (uint64_t)y;
345 f8dd19e5 Aurelien Jarno
        }
346 f8dd19e5 Aurelien Jarno
        break;
347 f8dd19e5 Aurelien Jarno
    }
348 f8dd19e5 Aurelien Jarno
349 f8dd19e5 Aurelien Jarno
    fprintf(stderr,
350 f8dd19e5 Aurelien Jarno
            "Unrecognized bitness %d or condition %d in "
351 f8dd19e5 Aurelien Jarno
            "do_constant_folding_cond.\n", op_bits(op), c);
352 f8dd19e5 Aurelien Jarno
    tcg_abort();
353 f8dd19e5 Aurelien Jarno
}
354 f8dd19e5 Aurelien Jarno
355 22613af4 Kirill Batuzov
/* Propagate constants and copies, fold constant expressions. */
356 8f2e8c07 Kirill Batuzov
static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
357 8f2e8c07 Kirill Batuzov
                                    TCGArg *args, TCGOpDef *tcg_op_defs)
358 8f2e8c07 Kirill Batuzov
{
359 fe0de7aa Blue Swirl
    int i, nb_ops, op_index, nb_temps, nb_globals, nb_call_args;
360 fe0de7aa Blue Swirl
    TCGOpcode op;
361 8f2e8c07 Kirill Batuzov
    const TCGOpDef *def;
362 8f2e8c07 Kirill Batuzov
    TCGArg *gen_args;
363 53108fb5 Kirill Batuzov
    TCGArg tmp;
364 5d8f5363 Richard Henderson
    TCGCond cond;
365 5d8f5363 Richard Henderson
366 22613af4 Kirill Batuzov
    /* Array VALS has an element for each temp.
367 22613af4 Kirill Batuzov
       If this temp holds a constant then its value is kept in VALS' element.
368 e590d4e6 Aurelien Jarno
       If this temp is a copy of other ones then the other copies are
369 e590d4e6 Aurelien Jarno
       available through the doubly linked circular list. */
370 8f2e8c07 Kirill Batuzov
371 8f2e8c07 Kirill Batuzov
    nb_temps = s->nb_temps;
372 8f2e8c07 Kirill Batuzov
    nb_globals = s->nb_globals;
373 22613af4 Kirill Batuzov
    memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
374 8f2e8c07 Kirill Batuzov
375 8f2e8c07 Kirill Batuzov
    nb_ops = tcg_opc_ptr - gen_opc_buf;
376 8f2e8c07 Kirill Batuzov
    gen_args = args;
377 8f2e8c07 Kirill Batuzov
    for (op_index = 0; op_index < nb_ops; op_index++) {
378 8f2e8c07 Kirill Batuzov
        op = gen_opc_buf[op_index];
379 8f2e8c07 Kirill Batuzov
        def = &tcg_op_defs[op];
380 22613af4 Kirill Batuzov
        /* Do copy propagation */
381 22613af4 Kirill Batuzov
        if (!(def->flags & (TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS))) {
382 22613af4 Kirill Batuzov
            assert(op != INDEX_op_call);
383 22613af4 Kirill Batuzov
            for (i = def->nb_oargs; i < def->nb_oargs + def->nb_iargs; i++) {
384 22613af4 Kirill Batuzov
                if (temps[args[i]].state == TCG_TEMP_COPY) {
385 e590d4e6 Aurelien Jarno
                    args[i] = find_better_copy(s, args[i]);
386 22613af4 Kirill Batuzov
                }
387 22613af4 Kirill Batuzov
            }
388 22613af4 Kirill Batuzov
        }
389 22613af4 Kirill Batuzov
390 53108fb5 Kirill Batuzov
        /* For commutative operations make constant second argument */
391 53108fb5 Kirill Batuzov
        switch (op) {
392 53108fb5 Kirill Batuzov
        CASE_OP_32_64(add):
393 53108fb5 Kirill Batuzov
        CASE_OP_32_64(mul):
394 9a81090b Kirill Batuzov
        CASE_OP_32_64(and):
395 9a81090b Kirill Batuzov
        CASE_OP_32_64(or):
396 9a81090b Kirill Batuzov
        CASE_OP_32_64(xor):
397 cb25c80a Richard Henderson
        CASE_OP_32_64(eqv):
398 cb25c80a Richard Henderson
        CASE_OP_32_64(nand):
399 cb25c80a Richard Henderson
        CASE_OP_32_64(nor):
400 53108fb5 Kirill Batuzov
            if (temps[args[1]].state == TCG_TEMP_CONST) {
401 53108fb5 Kirill Batuzov
                tmp = args[1];
402 53108fb5 Kirill Batuzov
                args[1] = args[2];
403 53108fb5 Kirill Batuzov
                args[2] = tmp;
404 53108fb5 Kirill Batuzov
            }
405 53108fb5 Kirill Batuzov
            break;
406 65a7cce1 Aurelien Jarno
        CASE_OP_32_64(brcond):
407 65a7cce1 Aurelien Jarno
            if (temps[args[0]].state == TCG_TEMP_CONST
408 65a7cce1 Aurelien Jarno
                && temps[args[1]].state != TCG_TEMP_CONST) {
409 65a7cce1 Aurelien Jarno
                tmp = args[0];
410 65a7cce1 Aurelien Jarno
                args[0] = args[1];
411 65a7cce1 Aurelien Jarno
                args[1] = tmp;
412 65a7cce1 Aurelien Jarno
                args[2] = tcg_swap_cond(args[2]);
413 65a7cce1 Aurelien Jarno
            }
414 65a7cce1 Aurelien Jarno
            break;
415 65a7cce1 Aurelien Jarno
        CASE_OP_32_64(setcond):
416 65a7cce1 Aurelien Jarno
            if (temps[args[1]].state == TCG_TEMP_CONST
417 65a7cce1 Aurelien Jarno
                && temps[args[2]].state != TCG_TEMP_CONST) {
418 65a7cce1 Aurelien Jarno
                tmp = args[1];
419 65a7cce1 Aurelien Jarno
                args[1] = args[2];
420 65a7cce1 Aurelien Jarno
                args[2] = tmp;
421 65a7cce1 Aurelien Jarno
                args[3] = tcg_swap_cond(args[3]);
422 65a7cce1 Aurelien Jarno
            }
423 65a7cce1 Aurelien Jarno
            break;
424 fa01a208 Richard Henderson
        CASE_OP_32_64(movcond):
425 5d8f5363 Richard Henderson
            cond = args[5];
426 fa01a208 Richard Henderson
            if (temps[args[1]].state == TCG_TEMP_CONST
427 fa01a208 Richard Henderson
                && temps[args[2]].state != TCG_TEMP_CONST) {
428 fa01a208 Richard Henderson
                tmp = args[1];
429 fa01a208 Richard Henderson
                args[1] = args[2];
430 fa01a208 Richard Henderson
                args[2] = tmp;
431 5d8f5363 Richard Henderson
                cond = tcg_swap_cond(cond);
432 5d8f5363 Richard Henderson
            }
433 5d8f5363 Richard Henderson
            /* For movcond, we canonicalize the "false" input reg to match
434 5d8f5363 Richard Henderson
               the destination reg so that the tcg backend can implement
435 5d8f5363 Richard Henderson
               a "move if true" operation.  */
436 5d8f5363 Richard Henderson
            if (args[0] == args[3]) {
437 5d8f5363 Richard Henderson
                tmp = args[3];
438 5d8f5363 Richard Henderson
                args[3] = args[4];
439 5d8f5363 Richard Henderson
                args[4] = tmp;
440 5d8f5363 Richard Henderson
                cond = tcg_invert_cond(cond);
441 fa01a208 Richard Henderson
            }
442 5d8f5363 Richard Henderson
            args[5] = cond;
443 53108fb5 Kirill Batuzov
        default:
444 53108fb5 Kirill Batuzov
            break;
445 53108fb5 Kirill Batuzov
        }
446 53108fb5 Kirill Batuzov
447 01ee5282 Aurelien Jarno
        /* Simplify expressions for "shift/rot r, 0, a => movi r, 0" */
448 01ee5282 Aurelien Jarno
        switch (op) {
449 01ee5282 Aurelien Jarno
        CASE_OP_32_64(shl):
450 01ee5282 Aurelien Jarno
        CASE_OP_32_64(shr):
451 01ee5282 Aurelien Jarno
        CASE_OP_32_64(sar):
452 01ee5282 Aurelien Jarno
        CASE_OP_32_64(rotl):
453 01ee5282 Aurelien Jarno
        CASE_OP_32_64(rotr):
454 01ee5282 Aurelien Jarno
            if (temps[args[1]].state == TCG_TEMP_CONST
455 01ee5282 Aurelien Jarno
                && temps[args[1]].val == 0) {
456 01ee5282 Aurelien Jarno
                gen_opc_buf[op_index] = op_to_movi(op);
457 e590d4e6 Aurelien Jarno
                tcg_opt_gen_movi(gen_args, args[0], 0);
458 01ee5282 Aurelien Jarno
                args += 3;
459 01ee5282 Aurelien Jarno
                gen_args += 2;
460 01ee5282 Aurelien Jarno
                continue;
461 01ee5282 Aurelien Jarno
            }
462 01ee5282 Aurelien Jarno
            break;
463 01ee5282 Aurelien Jarno
        default:
464 01ee5282 Aurelien Jarno
            break;
465 01ee5282 Aurelien Jarno
        }
466 01ee5282 Aurelien Jarno
467 56e49438 Aurelien Jarno
        /* Simplify expression for "op r, a, 0 => mov r, a" cases */
468 53108fb5 Kirill Batuzov
        switch (op) {
469 53108fb5 Kirill Batuzov
        CASE_OP_32_64(add):
470 53108fb5 Kirill Batuzov
        CASE_OP_32_64(sub):
471 55c0975c Kirill Batuzov
        CASE_OP_32_64(shl):
472 55c0975c Kirill Batuzov
        CASE_OP_32_64(shr):
473 55c0975c Kirill Batuzov
        CASE_OP_32_64(sar):
474 25c4d9cc Richard Henderson
        CASE_OP_32_64(rotl):
475 25c4d9cc Richard Henderson
        CASE_OP_32_64(rotr):
476 38ee188b Aurelien Jarno
        CASE_OP_32_64(or):
477 38ee188b Aurelien Jarno
        CASE_OP_32_64(xor):
478 53108fb5 Kirill Batuzov
            if (temps[args[1]].state == TCG_TEMP_CONST) {
479 53108fb5 Kirill Batuzov
                /* Proceed with possible constant folding. */
480 53108fb5 Kirill Batuzov
                break;
481 53108fb5 Kirill Batuzov
            }
482 53108fb5 Kirill Batuzov
            if (temps[args[2]].state == TCG_TEMP_CONST
483 53108fb5 Kirill Batuzov
                && temps[args[2]].val == 0) {
484 e590d4e6 Aurelien Jarno
                if (temps_are_copies(args[0], args[1])) {
485 53108fb5 Kirill Batuzov
                    gen_opc_buf[op_index] = INDEX_op_nop;
486 53108fb5 Kirill Batuzov
                } else {
487 53108fb5 Kirill Batuzov
                    gen_opc_buf[op_index] = op_to_mov(op);
488 b80bb016 Aurelien Jarno
                    tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
489 53108fb5 Kirill Batuzov
                    gen_args += 2;
490 53108fb5 Kirill Batuzov
                }
491 fedc0da2 Aurelien Jarno
                args += 3;
492 53108fb5 Kirill Batuzov
                continue;
493 53108fb5 Kirill Batuzov
            }
494 53108fb5 Kirill Batuzov
            break;
495 56e49438 Aurelien Jarno
        default:
496 56e49438 Aurelien Jarno
            break;
497 56e49438 Aurelien Jarno
        }
498 56e49438 Aurelien Jarno
499 56e49438 Aurelien Jarno
        /* Simplify expression for "op r, a, 0 => movi r, 0" cases */
500 56e49438 Aurelien Jarno
        switch (op) {
501 61251c0c Aurelien Jarno
        CASE_OP_32_64(and):
502 53108fb5 Kirill Batuzov
        CASE_OP_32_64(mul):
503 53108fb5 Kirill Batuzov
            if ((temps[args[2]].state == TCG_TEMP_CONST
504 53108fb5 Kirill Batuzov
                && temps[args[2]].val == 0)) {
505 53108fb5 Kirill Batuzov
                gen_opc_buf[op_index] = op_to_movi(op);
506 e590d4e6 Aurelien Jarno
                tcg_opt_gen_movi(gen_args, args[0], 0);
507 53108fb5 Kirill Batuzov
                args += 3;
508 53108fb5 Kirill Batuzov
                gen_args += 2;
509 53108fb5 Kirill Batuzov
                continue;
510 53108fb5 Kirill Batuzov
            }
511 53108fb5 Kirill Batuzov
            break;
512 56e49438 Aurelien Jarno
        default:
513 56e49438 Aurelien Jarno
            break;
514 56e49438 Aurelien Jarno
        }
515 56e49438 Aurelien Jarno
516 56e49438 Aurelien Jarno
        /* Simplify expression for "op r, a, a => mov r, a" cases */
517 56e49438 Aurelien Jarno
        switch (op) {
518 9a81090b Kirill Batuzov
        CASE_OP_32_64(or):
519 9a81090b Kirill Batuzov
        CASE_OP_32_64(and):
520 9a81090b Kirill Batuzov
            if (args[1] == args[2]) {
521 e590d4e6 Aurelien Jarno
                if (temps_are_copies(args[0], args[1])) {
522 9a81090b Kirill Batuzov
                    gen_opc_buf[op_index] = INDEX_op_nop;
523 9a81090b Kirill Batuzov
                } else {
524 9a81090b Kirill Batuzov
                    gen_opc_buf[op_index] = op_to_mov(op);
525 b80bb016 Aurelien Jarno
                    tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
526 9a81090b Kirill Batuzov
                    gen_args += 2;
527 9a81090b Kirill Batuzov
                }
528 fedc0da2 Aurelien Jarno
                args += 3;
529 9a81090b Kirill Batuzov
                continue;
530 9a81090b Kirill Batuzov
            }
531 9a81090b Kirill Batuzov
            break;
532 fe0de7aa Blue Swirl
        default:
533 fe0de7aa Blue Swirl
            break;
534 53108fb5 Kirill Batuzov
        }
535 53108fb5 Kirill Batuzov
536 22613af4 Kirill Batuzov
        /* Propagate constants through copy operations and do constant
537 22613af4 Kirill Batuzov
           folding.  Constants will be substituted to arguments by register
538 22613af4 Kirill Batuzov
           allocator where needed and possible.  Also detect copies. */
539 8f2e8c07 Kirill Batuzov
        switch (op) {
540 22613af4 Kirill Batuzov
        CASE_OP_32_64(mov):
541 e590d4e6 Aurelien Jarno
            if (temps_are_copies(args[0], args[1])) {
542 22613af4 Kirill Batuzov
                args += 2;
543 22613af4 Kirill Batuzov
                gen_opc_buf[op_index] = INDEX_op_nop;
544 22613af4 Kirill Batuzov
                break;
545 22613af4 Kirill Batuzov
            }
546 22613af4 Kirill Batuzov
            if (temps[args[1]].state != TCG_TEMP_CONST) {
547 b80bb016 Aurelien Jarno
                tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
548 22613af4 Kirill Batuzov
                gen_args += 2;
549 22613af4 Kirill Batuzov
                args += 2;
550 22613af4 Kirill Batuzov
                break;
551 22613af4 Kirill Batuzov
            }
552 22613af4 Kirill Batuzov
            /* Source argument is constant.  Rewrite the operation and
553 22613af4 Kirill Batuzov
               let movi case handle it. */
554 22613af4 Kirill Batuzov
            op = op_to_movi(op);
555 22613af4 Kirill Batuzov
            gen_opc_buf[op_index] = op;
556 22613af4 Kirill Batuzov
            args[1] = temps[args[1]].val;
557 22613af4 Kirill Batuzov
            /* fallthrough */
558 22613af4 Kirill Batuzov
        CASE_OP_32_64(movi):
559 e590d4e6 Aurelien Jarno
            tcg_opt_gen_movi(gen_args, args[0], args[1]);
560 22613af4 Kirill Batuzov
            gen_args += 2;
561 22613af4 Kirill Batuzov
            args += 2;
562 22613af4 Kirill Batuzov
            break;
563 a640f031 Kirill Batuzov
        CASE_OP_32_64(not):
564 cb25c80a Richard Henderson
        CASE_OP_32_64(neg):
565 25c4d9cc Richard Henderson
        CASE_OP_32_64(ext8s):
566 25c4d9cc Richard Henderson
        CASE_OP_32_64(ext8u):
567 25c4d9cc Richard Henderson
        CASE_OP_32_64(ext16s):
568 25c4d9cc Richard Henderson
        CASE_OP_32_64(ext16u):
569 a640f031 Kirill Batuzov
        case INDEX_op_ext32s_i64:
570 a640f031 Kirill Batuzov
        case INDEX_op_ext32u_i64:
571 a640f031 Kirill Batuzov
            if (temps[args[1]].state == TCG_TEMP_CONST) {
572 a640f031 Kirill Batuzov
                gen_opc_buf[op_index] = op_to_movi(op);
573 a640f031 Kirill Batuzov
                tmp = do_constant_folding(op, temps[args[1]].val, 0);
574 e590d4e6 Aurelien Jarno
                tcg_opt_gen_movi(gen_args, args[0], tmp);
575 a640f031 Kirill Batuzov
            } else {
576 e590d4e6 Aurelien Jarno
                reset_temp(args[0]);
577 a640f031 Kirill Batuzov
                gen_args[0] = args[0];
578 a640f031 Kirill Batuzov
                gen_args[1] = args[1];
579 a640f031 Kirill Batuzov
            }
580 fedc0da2 Aurelien Jarno
            gen_args += 2;
581 fedc0da2 Aurelien Jarno
            args += 2;
582 fedc0da2 Aurelien Jarno
            break;
583 53108fb5 Kirill Batuzov
        CASE_OP_32_64(add):
584 53108fb5 Kirill Batuzov
        CASE_OP_32_64(sub):
585 53108fb5 Kirill Batuzov
        CASE_OP_32_64(mul):
586 9a81090b Kirill Batuzov
        CASE_OP_32_64(or):
587 9a81090b Kirill Batuzov
        CASE_OP_32_64(and):
588 9a81090b Kirill Batuzov
        CASE_OP_32_64(xor):
589 55c0975c Kirill Batuzov
        CASE_OP_32_64(shl):
590 55c0975c Kirill Batuzov
        CASE_OP_32_64(shr):
591 55c0975c Kirill Batuzov
        CASE_OP_32_64(sar):
592 25c4d9cc Richard Henderson
        CASE_OP_32_64(rotl):
593 25c4d9cc Richard Henderson
        CASE_OP_32_64(rotr):
594 cb25c80a Richard Henderson
        CASE_OP_32_64(andc):
595 cb25c80a Richard Henderson
        CASE_OP_32_64(orc):
596 cb25c80a Richard Henderson
        CASE_OP_32_64(eqv):
597 cb25c80a Richard Henderson
        CASE_OP_32_64(nand):
598 cb25c80a Richard Henderson
        CASE_OP_32_64(nor):
599 53108fb5 Kirill Batuzov
            if (temps[args[1]].state == TCG_TEMP_CONST
600 53108fb5 Kirill Batuzov
                && temps[args[2]].state == TCG_TEMP_CONST) {
601 53108fb5 Kirill Batuzov
                gen_opc_buf[op_index] = op_to_movi(op);
602 53108fb5 Kirill Batuzov
                tmp = do_constant_folding(op, temps[args[1]].val,
603 53108fb5 Kirill Batuzov
                                          temps[args[2]].val);
604 e590d4e6 Aurelien Jarno
                tcg_opt_gen_movi(gen_args, args[0], tmp);
605 53108fb5 Kirill Batuzov
                gen_args += 2;
606 53108fb5 Kirill Batuzov
            } else {
607 e590d4e6 Aurelien Jarno
                reset_temp(args[0]);
608 53108fb5 Kirill Batuzov
                gen_args[0] = args[0];
609 53108fb5 Kirill Batuzov
                gen_args[1] = args[1];
610 53108fb5 Kirill Batuzov
                gen_args[2] = args[2];
611 53108fb5 Kirill Batuzov
                gen_args += 3;
612 53108fb5 Kirill Batuzov
            }
613 fedc0da2 Aurelien Jarno
            args += 3;
614 fedc0da2 Aurelien Jarno
            break;
615 f8dd19e5 Aurelien Jarno
        CASE_OP_32_64(setcond):
616 f8dd19e5 Aurelien Jarno
            if (temps[args[1]].state == TCG_TEMP_CONST
617 f8dd19e5 Aurelien Jarno
                && temps[args[2]].state == TCG_TEMP_CONST) {
618 f8dd19e5 Aurelien Jarno
                gen_opc_buf[op_index] = op_to_movi(op);
619 f8dd19e5 Aurelien Jarno
                tmp = do_constant_folding_cond(op, temps[args[1]].val,
620 f8dd19e5 Aurelien Jarno
                                               temps[args[2]].val, args[3]);
621 e590d4e6 Aurelien Jarno
                tcg_opt_gen_movi(gen_args, args[0], tmp);
622 f8dd19e5 Aurelien Jarno
                gen_args += 2;
623 f8dd19e5 Aurelien Jarno
            } else {
624 e590d4e6 Aurelien Jarno
                reset_temp(args[0]);
625 f8dd19e5 Aurelien Jarno
                gen_args[0] = args[0];
626 f8dd19e5 Aurelien Jarno
                gen_args[1] = args[1];
627 f8dd19e5 Aurelien Jarno
                gen_args[2] = args[2];
628 f8dd19e5 Aurelien Jarno
                gen_args[3] = args[3];
629 f8dd19e5 Aurelien Jarno
                gen_args += 4;
630 f8dd19e5 Aurelien Jarno
            }
631 fedc0da2 Aurelien Jarno
            args += 4;
632 fedc0da2 Aurelien Jarno
            break;
633 fbeaa26c Aurelien Jarno
        CASE_OP_32_64(brcond):
634 fbeaa26c Aurelien Jarno
            if (temps[args[0]].state == TCG_TEMP_CONST
635 fbeaa26c Aurelien Jarno
                && temps[args[1]].state == TCG_TEMP_CONST) {
636 fbeaa26c Aurelien Jarno
                if (do_constant_folding_cond(op, temps[args[0]].val,
637 fbeaa26c Aurelien Jarno
                                             temps[args[1]].val, args[2])) {
638 fbeaa26c Aurelien Jarno
                    memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
639 fbeaa26c Aurelien Jarno
                    gen_opc_buf[op_index] = INDEX_op_br;
640 fbeaa26c Aurelien Jarno
                    gen_args[0] = args[3];
641 fbeaa26c Aurelien Jarno
                    gen_args += 1;
642 fbeaa26c Aurelien Jarno
                } else {
643 fbeaa26c Aurelien Jarno
                    gen_opc_buf[op_index] = INDEX_op_nop;
644 fbeaa26c Aurelien Jarno
                }
645 fbeaa26c Aurelien Jarno
            } else {
646 fbeaa26c Aurelien Jarno
                memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
647 e590d4e6 Aurelien Jarno
                reset_temp(args[0]);
648 fbeaa26c Aurelien Jarno
                gen_args[0] = args[0];
649 fbeaa26c Aurelien Jarno
                gen_args[1] = args[1];
650 fbeaa26c Aurelien Jarno
                gen_args[2] = args[2];
651 fbeaa26c Aurelien Jarno
                gen_args[3] = args[3];
652 fbeaa26c Aurelien Jarno
                gen_args += 4;
653 fbeaa26c Aurelien Jarno
            }
654 fedc0da2 Aurelien Jarno
            args += 4;
655 fedc0da2 Aurelien Jarno
            break;
656 fa01a208 Richard Henderson
        CASE_OP_32_64(movcond):
657 fa01a208 Richard Henderson
            if (temps[args[1]].state == TCG_TEMP_CONST
658 fa01a208 Richard Henderson
                && temps[args[2]].state == TCG_TEMP_CONST) {
659 fa01a208 Richard Henderson
                tmp = do_constant_folding_cond(op, temps[args[1]].val,
660 fa01a208 Richard Henderson
                                               temps[args[2]].val, args[5]);
661 e590d4e6 Aurelien Jarno
                if (temps_are_copies(args[0], args[4-tmp])) {
662 fa01a208 Richard Henderson
                    gen_opc_buf[op_index] = INDEX_op_nop;
663 fa01a208 Richard Henderson
                } else if (temps[args[4-tmp]].state == TCG_TEMP_CONST) {
664 fa01a208 Richard Henderson
                    gen_opc_buf[op_index] = op_to_movi(op);
665 e590d4e6 Aurelien Jarno
                    tcg_opt_gen_movi(gen_args, args[0], temps[args[4-tmp]].val);
666 fa01a208 Richard Henderson
                    gen_args += 2;
667 fa01a208 Richard Henderson
                } else {
668 fa01a208 Richard Henderson
                    gen_opc_buf[op_index] = op_to_mov(op);
669 e590d4e6 Aurelien Jarno
                    tcg_opt_gen_mov(s, gen_args, args[0], args[4-tmp]);
670 fa01a208 Richard Henderson
                    gen_args += 2;
671 fa01a208 Richard Henderson
                }
672 fa01a208 Richard Henderson
            } else {
673 e590d4e6 Aurelien Jarno
                reset_temp(args[0]);
674 fa01a208 Richard Henderson
                gen_args[0] = args[0];
675 fa01a208 Richard Henderson
                gen_args[1] = args[1];
676 fa01a208 Richard Henderson
                gen_args[2] = args[2];
677 fa01a208 Richard Henderson
                gen_args[3] = args[3];
678 fa01a208 Richard Henderson
                gen_args[4] = args[4];
679 fa01a208 Richard Henderson
                gen_args[5] = args[5];
680 fa01a208 Richard Henderson
                gen_args += 6;
681 fa01a208 Richard Henderson
            }
682 fa01a208 Richard Henderson
            args += 6;
683 fa01a208 Richard Henderson
            break;
684 8f2e8c07 Kirill Batuzov
        case INDEX_op_call:
685 22613af4 Kirill Batuzov
            nb_call_args = (args[0] >> 16) + (args[0] & 0xffff);
686 22613af4 Kirill Batuzov
            if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) {
687 22613af4 Kirill Batuzov
                for (i = 0; i < nb_globals; i++) {
688 e590d4e6 Aurelien Jarno
                    reset_temp(i);
689 22613af4 Kirill Batuzov
                }
690 22613af4 Kirill Batuzov
            }
691 22613af4 Kirill Batuzov
            for (i = 0; i < (args[0] >> 16); i++) {
692 e590d4e6 Aurelien Jarno
                reset_temp(args[i + 1]);
693 22613af4 Kirill Batuzov
            }
694 22613af4 Kirill Batuzov
            i = nb_call_args + 3;
695 8f2e8c07 Kirill Batuzov
            while (i) {
696 8f2e8c07 Kirill Batuzov
                *gen_args = *args;
697 8f2e8c07 Kirill Batuzov
                args++;
698 8f2e8c07 Kirill Batuzov
                gen_args++;
699 8f2e8c07 Kirill Batuzov
                i--;
700 8f2e8c07 Kirill Batuzov
            }
701 8f2e8c07 Kirill Batuzov
            break;
702 8f2e8c07 Kirill Batuzov
        default:
703 22613af4 Kirill Batuzov
            /* Default case: we do know nothing about operation so no
704 a2550660 Aurelien Jarno
               propagation is done.  We trash everything if the operation
705 a2550660 Aurelien Jarno
               is the end of a basic block, otherwise we only trash the
706 a2550660 Aurelien Jarno
               output args.  */
707 a2550660 Aurelien Jarno
            if (def->flags & TCG_OPF_BB_END) {
708 a2550660 Aurelien Jarno
                memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
709 a2550660 Aurelien Jarno
            } else {
710 a2550660 Aurelien Jarno
                for (i = 0; i < def->nb_oargs; i++) {
711 e590d4e6 Aurelien Jarno
                    reset_temp(args[i]);
712 a2550660 Aurelien Jarno
                }
713 22613af4 Kirill Batuzov
            }
714 8f2e8c07 Kirill Batuzov
            for (i = 0; i < def->nb_args; i++) {
715 8f2e8c07 Kirill Batuzov
                gen_args[i] = args[i];
716 8f2e8c07 Kirill Batuzov
            }
717 8f2e8c07 Kirill Batuzov
            args += def->nb_args;
718 8f2e8c07 Kirill Batuzov
            gen_args += def->nb_args;
719 8f2e8c07 Kirill Batuzov
            break;
720 8f2e8c07 Kirill Batuzov
        }
721 8f2e8c07 Kirill Batuzov
    }
722 8f2e8c07 Kirill Batuzov
723 8f2e8c07 Kirill Batuzov
    return gen_args;
724 8f2e8c07 Kirill Batuzov
}
725 8f2e8c07 Kirill Batuzov
726 8f2e8c07 Kirill Batuzov
TCGArg *tcg_optimize(TCGContext *s, uint16_t *tcg_opc_ptr,
727 8f2e8c07 Kirill Batuzov
        TCGArg *args, TCGOpDef *tcg_op_defs)
728 8f2e8c07 Kirill Batuzov
{
729 8f2e8c07 Kirill Batuzov
    TCGArg *res;
730 8f2e8c07 Kirill Batuzov
    res = tcg_constant_folding(s, tcg_opc_ptr, args, tcg_op_defs);
731 8f2e8c07 Kirill Batuzov
    return res;
732 8f2e8c07 Kirill Batuzov
}