Statistics
| Branch: | Revision:

root / tcg / optimize.c @ d73685e3

History | View | Annotate | Download (25.1 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 b336ceb6 Aurelien Jarno
/* Return 2 if the condition can't be simplified, and the result
296 b336ceb6 Aurelien Jarno
   of the condition (0 or 1) if it can */
297 f8dd19e5 Aurelien Jarno
static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x,
298 f8dd19e5 Aurelien Jarno
                                       TCGArg y, TCGCond c)
299 f8dd19e5 Aurelien Jarno
{
300 b336ceb6 Aurelien Jarno
    if (temps[x].state == TCG_TEMP_CONST && temps[y].state == TCG_TEMP_CONST) {
301 b336ceb6 Aurelien Jarno
        switch (op_bits(op)) {
302 b336ceb6 Aurelien Jarno
        case 32:
303 b336ceb6 Aurelien Jarno
            switch (c) {
304 b336ceb6 Aurelien Jarno
            case TCG_COND_EQ:
305 b336ceb6 Aurelien Jarno
                return (uint32_t)temps[x].val == (uint32_t)temps[y].val;
306 b336ceb6 Aurelien Jarno
            case TCG_COND_NE:
307 b336ceb6 Aurelien Jarno
                return (uint32_t)temps[x].val != (uint32_t)temps[y].val;
308 b336ceb6 Aurelien Jarno
            case TCG_COND_LT:
309 b336ceb6 Aurelien Jarno
                return (int32_t)temps[x].val < (int32_t)temps[y].val;
310 b336ceb6 Aurelien Jarno
            case TCG_COND_GE:
311 b336ceb6 Aurelien Jarno
                return (int32_t)temps[x].val >= (int32_t)temps[y].val;
312 b336ceb6 Aurelien Jarno
            case TCG_COND_LE:
313 b336ceb6 Aurelien Jarno
                return (int32_t)temps[x].val <= (int32_t)temps[y].val;
314 b336ceb6 Aurelien Jarno
            case TCG_COND_GT:
315 b336ceb6 Aurelien Jarno
                return (int32_t)temps[x].val > (int32_t)temps[y].val;
316 b336ceb6 Aurelien Jarno
            case TCG_COND_LTU:
317 b336ceb6 Aurelien Jarno
                return (uint32_t)temps[x].val < (uint32_t)temps[y].val;
318 b336ceb6 Aurelien Jarno
            case TCG_COND_GEU:
319 b336ceb6 Aurelien Jarno
                return (uint32_t)temps[x].val >= (uint32_t)temps[y].val;
320 b336ceb6 Aurelien Jarno
            case TCG_COND_LEU:
321 b336ceb6 Aurelien Jarno
                return (uint32_t)temps[x].val <= (uint32_t)temps[y].val;
322 b336ceb6 Aurelien Jarno
            case TCG_COND_GTU:
323 b336ceb6 Aurelien Jarno
                return (uint32_t)temps[x].val > (uint32_t)temps[y].val;
324 b336ceb6 Aurelien Jarno
            }
325 b336ceb6 Aurelien Jarno
            break;
326 b336ceb6 Aurelien Jarno
        case 64:
327 b336ceb6 Aurelien Jarno
            switch (c) {
328 b336ceb6 Aurelien Jarno
            case TCG_COND_EQ:
329 b336ceb6 Aurelien Jarno
                return (uint64_t)temps[x].val == (uint64_t)temps[y].val;
330 b336ceb6 Aurelien Jarno
            case TCG_COND_NE:
331 b336ceb6 Aurelien Jarno
                return (uint64_t)temps[x].val != (uint64_t)temps[y].val;
332 b336ceb6 Aurelien Jarno
            case TCG_COND_LT:
333 b336ceb6 Aurelien Jarno
                return (int64_t)temps[x].val < (int64_t)temps[y].val;
334 b336ceb6 Aurelien Jarno
            case TCG_COND_GE:
335 b336ceb6 Aurelien Jarno
                return (int64_t)temps[x].val >= (int64_t)temps[y].val;
336 b336ceb6 Aurelien Jarno
            case TCG_COND_LE:
337 b336ceb6 Aurelien Jarno
                return (int64_t)temps[x].val <= (int64_t)temps[y].val;
338 b336ceb6 Aurelien Jarno
            case TCG_COND_GT:
339 b336ceb6 Aurelien Jarno
                return (int64_t)temps[x].val > (int64_t)temps[y].val;
340 b336ceb6 Aurelien Jarno
            case TCG_COND_LTU:
341 b336ceb6 Aurelien Jarno
                return (uint64_t)temps[x].val < (uint64_t)temps[y].val;
342 b336ceb6 Aurelien Jarno
            case TCG_COND_GEU:
343 b336ceb6 Aurelien Jarno
                return (uint64_t)temps[x].val >= (uint64_t)temps[y].val;
344 b336ceb6 Aurelien Jarno
            case TCG_COND_LEU:
345 b336ceb6 Aurelien Jarno
                return (uint64_t)temps[x].val <= (uint64_t)temps[y].val;
346 b336ceb6 Aurelien Jarno
            case TCG_COND_GTU:
347 b336ceb6 Aurelien Jarno
                return (uint64_t)temps[x].val > (uint64_t)temps[y].val;
348 b336ceb6 Aurelien Jarno
            }
349 b336ceb6 Aurelien Jarno
            break;
350 b336ceb6 Aurelien Jarno
        }
351 b336ceb6 Aurelien Jarno
    } else if (temps_are_copies(x, y)) {
352 f8dd19e5 Aurelien Jarno
        switch (c) {
353 f8dd19e5 Aurelien Jarno
        case TCG_COND_GT:
354 f8dd19e5 Aurelien Jarno
        case TCG_COND_LTU:
355 b336ceb6 Aurelien Jarno
        case TCG_COND_LT:
356 f8dd19e5 Aurelien Jarno
        case TCG_COND_GTU:
357 f8dd19e5 Aurelien Jarno
        case TCG_COND_NE:
358 b336ceb6 Aurelien Jarno
            return 0;
359 f8dd19e5 Aurelien Jarno
        case TCG_COND_GE:
360 b336ceb6 Aurelien Jarno
        case TCG_COND_GEU:
361 f8dd19e5 Aurelien Jarno
        case TCG_COND_LE:
362 b336ceb6 Aurelien Jarno
        case TCG_COND_LEU:
363 b336ceb6 Aurelien Jarno
        case TCG_COND_EQ:
364 b336ceb6 Aurelien Jarno
            return 1;
365 b336ceb6 Aurelien Jarno
        }
366 b336ceb6 Aurelien Jarno
    } else if (temps[y].state == TCG_TEMP_CONST && temps[y].val == 0) {
367 b336ceb6 Aurelien Jarno
        switch (c) {
368 f8dd19e5 Aurelien Jarno
        case TCG_COND_LTU:
369 b336ceb6 Aurelien Jarno
            return 0;
370 f8dd19e5 Aurelien Jarno
        case TCG_COND_GEU:
371 b336ceb6 Aurelien Jarno
            return 1;
372 b336ceb6 Aurelien Jarno
        default:
373 b336ceb6 Aurelien Jarno
            return 2;
374 f8dd19e5 Aurelien Jarno
        }
375 b336ceb6 Aurelien Jarno
    } else {
376 b336ceb6 Aurelien Jarno
        return 2;
377 f8dd19e5 Aurelien Jarno
    }
378 f8dd19e5 Aurelien Jarno
379 f8dd19e5 Aurelien Jarno
    fprintf(stderr,
380 f8dd19e5 Aurelien Jarno
            "Unrecognized bitness %d or condition %d in "
381 f8dd19e5 Aurelien Jarno
            "do_constant_folding_cond.\n", op_bits(op), c);
382 f8dd19e5 Aurelien Jarno
    tcg_abort();
383 f8dd19e5 Aurelien Jarno
}
384 f8dd19e5 Aurelien Jarno
385 22613af4 Kirill Batuzov
/* Propagate constants and copies, fold constant expressions. */
386 8f2e8c07 Kirill Batuzov
static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
387 8f2e8c07 Kirill Batuzov
                                    TCGArg *args, TCGOpDef *tcg_op_defs)
388 8f2e8c07 Kirill Batuzov
{
389 fe0de7aa Blue Swirl
    int i, nb_ops, op_index, nb_temps, nb_globals, nb_call_args;
390 fe0de7aa Blue Swirl
    TCGOpcode op;
391 8f2e8c07 Kirill Batuzov
    const TCGOpDef *def;
392 8f2e8c07 Kirill Batuzov
    TCGArg *gen_args;
393 53108fb5 Kirill Batuzov
    TCGArg tmp;
394 5d8f5363 Richard Henderson
    TCGCond cond;
395 5d8f5363 Richard Henderson
396 22613af4 Kirill Batuzov
    /* Array VALS has an element for each temp.
397 22613af4 Kirill Batuzov
       If this temp holds a constant then its value is kept in VALS' element.
398 e590d4e6 Aurelien Jarno
       If this temp is a copy of other ones then the other copies are
399 e590d4e6 Aurelien Jarno
       available through the doubly linked circular list. */
400 8f2e8c07 Kirill Batuzov
401 8f2e8c07 Kirill Batuzov
    nb_temps = s->nb_temps;
402 8f2e8c07 Kirill Batuzov
    nb_globals = s->nb_globals;
403 22613af4 Kirill Batuzov
    memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
404 8f2e8c07 Kirill Batuzov
405 8f2e8c07 Kirill Batuzov
    nb_ops = tcg_opc_ptr - gen_opc_buf;
406 8f2e8c07 Kirill Batuzov
    gen_args = args;
407 8f2e8c07 Kirill Batuzov
    for (op_index = 0; op_index < nb_ops; op_index++) {
408 8f2e8c07 Kirill Batuzov
        op = gen_opc_buf[op_index];
409 8f2e8c07 Kirill Batuzov
        def = &tcg_op_defs[op];
410 22613af4 Kirill Batuzov
        /* Do copy propagation */
411 1ff8c541 Aurelien Jarno
        if (op == INDEX_op_call) {
412 1ff8c541 Aurelien Jarno
            int nb_oargs = args[0] >> 16;
413 1ff8c541 Aurelien Jarno
            int nb_iargs = args[0] & 0xffff;
414 1ff8c541 Aurelien Jarno
            for (i = nb_oargs + 1; i < nb_oargs + nb_iargs + 1; i++) {
415 1ff8c541 Aurelien Jarno
                if (temps[args[i]].state == TCG_TEMP_COPY) {
416 1ff8c541 Aurelien Jarno
                    args[i] = find_better_copy(s, args[i]);
417 1ff8c541 Aurelien Jarno
                }
418 1ff8c541 Aurelien Jarno
            }
419 1ff8c541 Aurelien Jarno
        } else {
420 22613af4 Kirill Batuzov
            for (i = def->nb_oargs; i < def->nb_oargs + def->nb_iargs; i++) {
421 22613af4 Kirill Batuzov
                if (temps[args[i]].state == TCG_TEMP_COPY) {
422 e590d4e6 Aurelien Jarno
                    args[i] = find_better_copy(s, args[i]);
423 22613af4 Kirill Batuzov
                }
424 22613af4 Kirill Batuzov
            }
425 22613af4 Kirill Batuzov
        }
426 22613af4 Kirill Batuzov
427 53108fb5 Kirill Batuzov
        /* For commutative operations make constant second argument */
428 53108fb5 Kirill Batuzov
        switch (op) {
429 53108fb5 Kirill Batuzov
        CASE_OP_32_64(add):
430 53108fb5 Kirill Batuzov
        CASE_OP_32_64(mul):
431 9a81090b Kirill Batuzov
        CASE_OP_32_64(and):
432 9a81090b Kirill Batuzov
        CASE_OP_32_64(or):
433 9a81090b Kirill Batuzov
        CASE_OP_32_64(xor):
434 cb25c80a Richard Henderson
        CASE_OP_32_64(eqv):
435 cb25c80a Richard Henderson
        CASE_OP_32_64(nand):
436 cb25c80a Richard Henderson
        CASE_OP_32_64(nor):
437 c2b0e2fe Aurelien Jarno
            /* Prefer the constant in second argument, and then the form
438 c2b0e2fe Aurelien Jarno
               op a, a, b, which is better handled on non-RISC hosts. */
439 c2b0e2fe Aurelien Jarno
            if (temps[args[1]].state == TCG_TEMP_CONST || (args[0] == args[2]
440 c2b0e2fe Aurelien Jarno
                && temps[args[2]].state != TCG_TEMP_CONST)) {
441 53108fb5 Kirill Batuzov
                tmp = args[1];
442 53108fb5 Kirill Batuzov
                args[1] = args[2];
443 53108fb5 Kirill Batuzov
                args[2] = tmp;
444 53108fb5 Kirill Batuzov
            }
445 53108fb5 Kirill Batuzov
            break;
446 65a7cce1 Aurelien Jarno
        CASE_OP_32_64(brcond):
447 65a7cce1 Aurelien Jarno
            if (temps[args[0]].state == TCG_TEMP_CONST
448 65a7cce1 Aurelien Jarno
                && temps[args[1]].state != TCG_TEMP_CONST) {
449 65a7cce1 Aurelien Jarno
                tmp = args[0];
450 65a7cce1 Aurelien Jarno
                args[0] = args[1];
451 65a7cce1 Aurelien Jarno
                args[1] = tmp;
452 65a7cce1 Aurelien Jarno
                args[2] = tcg_swap_cond(args[2]);
453 65a7cce1 Aurelien Jarno
            }
454 65a7cce1 Aurelien Jarno
            break;
455 65a7cce1 Aurelien Jarno
        CASE_OP_32_64(setcond):
456 65a7cce1 Aurelien Jarno
            if (temps[args[1]].state == TCG_TEMP_CONST
457 65a7cce1 Aurelien Jarno
                && temps[args[2]].state != TCG_TEMP_CONST) {
458 65a7cce1 Aurelien Jarno
                tmp = args[1];
459 65a7cce1 Aurelien Jarno
                args[1] = args[2];
460 65a7cce1 Aurelien Jarno
                args[2] = tmp;
461 65a7cce1 Aurelien Jarno
                args[3] = tcg_swap_cond(args[3]);
462 65a7cce1 Aurelien Jarno
            }
463 65a7cce1 Aurelien Jarno
            break;
464 fa01a208 Richard Henderson
        CASE_OP_32_64(movcond):
465 5d8f5363 Richard Henderson
            cond = args[5];
466 fa01a208 Richard Henderson
            if (temps[args[1]].state == TCG_TEMP_CONST
467 fa01a208 Richard Henderson
                && temps[args[2]].state != TCG_TEMP_CONST) {
468 fa01a208 Richard Henderson
                tmp = args[1];
469 fa01a208 Richard Henderson
                args[1] = args[2];
470 fa01a208 Richard Henderson
                args[2] = tmp;
471 5d8f5363 Richard Henderson
                cond = tcg_swap_cond(cond);
472 5d8f5363 Richard Henderson
            }
473 5d8f5363 Richard Henderson
            /* For movcond, we canonicalize the "false" input reg to match
474 5d8f5363 Richard Henderson
               the destination reg so that the tcg backend can implement
475 5d8f5363 Richard Henderson
               a "move if true" operation.  */
476 5d8f5363 Richard Henderson
            if (args[0] == args[3]) {
477 5d8f5363 Richard Henderson
                tmp = args[3];
478 5d8f5363 Richard Henderson
                args[3] = args[4];
479 5d8f5363 Richard Henderson
                args[4] = tmp;
480 5d8f5363 Richard Henderson
                cond = tcg_invert_cond(cond);
481 fa01a208 Richard Henderson
            }
482 5d8f5363 Richard Henderson
            args[5] = cond;
483 53108fb5 Kirill Batuzov
        default:
484 53108fb5 Kirill Batuzov
            break;
485 53108fb5 Kirill Batuzov
        }
486 53108fb5 Kirill Batuzov
487 01ee5282 Aurelien Jarno
        /* Simplify expressions for "shift/rot r, 0, a => movi r, 0" */
488 01ee5282 Aurelien Jarno
        switch (op) {
489 01ee5282 Aurelien Jarno
        CASE_OP_32_64(shl):
490 01ee5282 Aurelien Jarno
        CASE_OP_32_64(shr):
491 01ee5282 Aurelien Jarno
        CASE_OP_32_64(sar):
492 01ee5282 Aurelien Jarno
        CASE_OP_32_64(rotl):
493 01ee5282 Aurelien Jarno
        CASE_OP_32_64(rotr):
494 01ee5282 Aurelien Jarno
            if (temps[args[1]].state == TCG_TEMP_CONST
495 01ee5282 Aurelien Jarno
                && temps[args[1]].val == 0) {
496 01ee5282 Aurelien Jarno
                gen_opc_buf[op_index] = op_to_movi(op);
497 e590d4e6 Aurelien Jarno
                tcg_opt_gen_movi(gen_args, args[0], 0);
498 01ee5282 Aurelien Jarno
                args += 3;
499 01ee5282 Aurelien Jarno
                gen_args += 2;
500 01ee5282 Aurelien Jarno
                continue;
501 01ee5282 Aurelien Jarno
            }
502 01ee5282 Aurelien Jarno
            break;
503 01ee5282 Aurelien Jarno
        default:
504 01ee5282 Aurelien Jarno
            break;
505 01ee5282 Aurelien Jarno
        }
506 01ee5282 Aurelien Jarno
507 56e49438 Aurelien Jarno
        /* Simplify expression for "op r, a, 0 => mov r, a" cases */
508 53108fb5 Kirill Batuzov
        switch (op) {
509 53108fb5 Kirill Batuzov
        CASE_OP_32_64(add):
510 53108fb5 Kirill Batuzov
        CASE_OP_32_64(sub):
511 55c0975c Kirill Batuzov
        CASE_OP_32_64(shl):
512 55c0975c Kirill Batuzov
        CASE_OP_32_64(shr):
513 55c0975c Kirill Batuzov
        CASE_OP_32_64(sar):
514 25c4d9cc Richard Henderson
        CASE_OP_32_64(rotl):
515 25c4d9cc Richard Henderson
        CASE_OP_32_64(rotr):
516 38ee188b Aurelien Jarno
        CASE_OP_32_64(or):
517 38ee188b Aurelien Jarno
        CASE_OP_32_64(xor):
518 53108fb5 Kirill Batuzov
            if (temps[args[1]].state == TCG_TEMP_CONST) {
519 53108fb5 Kirill Batuzov
                /* Proceed with possible constant folding. */
520 53108fb5 Kirill Batuzov
                break;
521 53108fb5 Kirill Batuzov
            }
522 53108fb5 Kirill Batuzov
            if (temps[args[2]].state == TCG_TEMP_CONST
523 53108fb5 Kirill Batuzov
                && temps[args[2]].val == 0) {
524 e590d4e6 Aurelien Jarno
                if (temps_are_copies(args[0], args[1])) {
525 53108fb5 Kirill Batuzov
                    gen_opc_buf[op_index] = INDEX_op_nop;
526 53108fb5 Kirill Batuzov
                } else {
527 53108fb5 Kirill Batuzov
                    gen_opc_buf[op_index] = op_to_mov(op);
528 b80bb016 Aurelien Jarno
                    tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
529 53108fb5 Kirill Batuzov
                    gen_args += 2;
530 53108fb5 Kirill Batuzov
                }
531 fedc0da2 Aurelien Jarno
                args += 3;
532 53108fb5 Kirill Batuzov
                continue;
533 53108fb5 Kirill Batuzov
            }
534 53108fb5 Kirill Batuzov
            break;
535 56e49438 Aurelien Jarno
        default:
536 56e49438 Aurelien Jarno
            break;
537 56e49438 Aurelien Jarno
        }
538 56e49438 Aurelien Jarno
539 56e49438 Aurelien Jarno
        /* Simplify expression for "op r, a, 0 => movi r, 0" cases */
540 56e49438 Aurelien Jarno
        switch (op) {
541 61251c0c Aurelien Jarno
        CASE_OP_32_64(and):
542 53108fb5 Kirill Batuzov
        CASE_OP_32_64(mul):
543 53108fb5 Kirill Batuzov
            if ((temps[args[2]].state == TCG_TEMP_CONST
544 53108fb5 Kirill Batuzov
                && temps[args[2]].val == 0)) {
545 53108fb5 Kirill Batuzov
                gen_opc_buf[op_index] = op_to_movi(op);
546 e590d4e6 Aurelien Jarno
                tcg_opt_gen_movi(gen_args, args[0], 0);
547 53108fb5 Kirill Batuzov
                args += 3;
548 53108fb5 Kirill Batuzov
                gen_args += 2;
549 53108fb5 Kirill Batuzov
                continue;
550 53108fb5 Kirill Batuzov
            }
551 53108fb5 Kirill Batuzov
            break;
552 56e49438 Aurelien Jarno
        default:
553 56e49438 Aurelien Jarno
            break;
554 56e49438 Aurelien Jarno
        }
555 56e49438 Aurelien Jarno
556 56e49438 Aurelien Jarno
        /* Simplify expression for "op r, a, a => mov r, a" cases */
557 56e49438 Aurelien Jarno
        switch (op) {
558 9a81090b Kirill Batuzov
        CASE_OP_32_64(or):
559 9a81090b Kirill Batuzov
        CASE_OP_32_64(and):
560 0aba1c73 Aurelien Jarno
            if (temps_are_copies(args[1], args[2])) {
561 e590d4e6 Aurelien Jarno
                if (temps_are_copies(args[0], args[1])) {
562 9a81090b Kirill Batuzov
                    gen_opc_buf[op_index] = INDEX_op_nop;
563 9a81090b Kirill Batuzov
                } else {
564 9a81090b Kirill Batuzov
                    gen_opc_buf[op_index] = op_to_mov(op);
565 b80bb016 Aurelien Jarno
                    tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
566 9a81090b Kirill Batuzov
                    gen_args += 2;
567 9a81090b Kirill Batuzov
                }
568 fedc0da2 Aurelien Jarno
                args += 3;
569 9a81090b Kirill Batuzov
                continue;
570 9a81090b Kirill Batuzov
            }
571 9a81090b Kirill Batuzov
            break;
572 fe0de7aa Blue Swirl
        default:
573 fe0de7aa Blue Swirl
            break;
574 53108fb5 Kirill Batuzov
        }
575 53108fb5 Kirill Batuzov
576 3c94193e Aurelien Jarno
        /* Simplify expression for "op r, a, a => movi r, 0" cases */
577 3c94193e Aurelien Jarno
        switch (op) {
578 3c94193e Aurelien Jarno
        CASE_OP_32_64(sub):
579 3c94193e Aurelien Jarno
        CASE_OP_32_64(xor):
580 3c94193e Aurelien Jarno
            if (temps_are_copies(args[1], args[2])) {
581 3c94193e Aurelien Jarno
                gen_opc_buf[op_index] = op_to_movi(op);
582 3c94193e Aurelien Jarno
                tcg_opt_gen_movi(gen_args, args[0], 0);
583 3c94193e Aurelien Jarno
                gen_args += 2;
584 3c94193e Aurelien Jarno
                args += 3;
585 3c94193e Aurelien Jarno
                continue;
586 3c94193e Aurelien Jarno
            }
587 3c94193e Aurelien Jarno
            break;
588 3c94193e Aurelien Jarno
        default:
589 3c94193e Aurelien Jarno
            break;
590 3c94193e Aurelien Jarno
        }
591 3c94193e Aurelien Jarno
592 22613af4 Kirill Batuzov
        /* Propagate constants through copy operations and do constant
593 22613af4 Kirill Batuzov
           folding.  Constants will be substituted to arguments by register
594 22613af4 Kirill Batuzov
           allocator where needed and possible.  Also detect copies. */
595 8f2e8c07 Kirill Batuzov
        switch (op) {
596 22613af4 Kirill Batuzov
        CASE_OP_32_64(mov):
597 e590d4e6 Aurelien Jarno
            if (temps_are_copies(args[0], args[1])) {
598 22613af4 Kirill Batuzov
                args += 2;
599 22613af4 Kirill Batuzov
                gen_opc_buf[op_index] = INDEX_op_nop;
600 22613af4 Kirill Batuzov
                break;
601 22613af4 Kirill Batuzov
            }
602 22613af4 Kirill Batuzov
            if (temps[args[1]].state != TCG_TEMP_CONST) {
603 b80bb016 Aurelien Jarno
                tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
604 22613af4 Kirill Batuzov
                gen_args += 2;
605 22613af4 Kirill Batuzov
                args += 2;
606 22613af4 Kirill Batuzov
                break;
607 22613af4 Kirill Batuzov
            }
608 22613af4 Kirill Batuzov
            /* Source argument is constant.  Rewrite the operation and
609 22613af4 Kirill Batuzov
               let movi case handle it. */
610 22613af4 Kirill Batuzov
            op = op_to_movi(op);
611 22613af4 Kirill Batuzov
            gen_opc_buf[op_index] = op;
612 22613af4 Kirill Batuzov
            args[1] = temps[args[1]].val;
613 22613af4 Kirill Batuzov
            /* fallthrough */
614 22613af4 Kirill Batuzov
        CASE_OP_32_64(movi):
615 e590d4e6 Aurelien Jarno
            tcg_opt_gen_movi(gen_args, args[0], args[1]);
616 22613af4 Kirill Batuzov
            gen_args += 2;
617 22613af4 Kirill Batuzov
            args += 2;
618 22613af4 Kirill Batuzov
            break;
619 a640f031 Kirill Batuzov
        CASE_OP_32_64(not):
620 cb25c80a Richard Henderson
        CASE_OP_32_64(neg):
621 25c4d9cc Richard Henderson
        CASE_OP_32_64(ext8s):
622 25c4d9cc Richard Henderson
        CASE_OP_32_64(ext8u):
623 25c4d9cc Richard Henderson
        CASE_OP_32_64(ext16s):
624 25c4d9cc Richard Henderson
        CASE_OP_32_64(ext16u):
625 a640f031 Kirill Batuzov
        case INDEX_op_ext32s_i64:
626 a640f031 Kirill Batuzov
        case INDEX_op_ext32u_i64:
627 a640f031 Kirill Batuzov
            if (temps[args[1]].state == TCG_TEMP_CONST) {
628 a640f031 Kirill Batuzov
                gen_opc_buf[op_index] = op_to_movi(op);
629 a640f031 Kirill Batuzov
                tmp = do_constant_folding(op, temps[args[1]].val, 0);
630 e590d4e6 Aurelien Jarno
                tcg_opt_gen_movi(gen_args, args[0], tmp);
631 a640f031 Kirill Batuzov
            } else {
632 e590d4e6 Aurelien Jarno
                reset_temp(args[0]);
633 a640f031 Kirill Batuzov
                gen_args[0] = args[0];
634 a640f031 Kirill Batuzov
                gen_args[1] = args[1];
635 a640f031 Kirill Batuzov
            }
636 fedc0da2 Aurelien Jarno
            gen_args += 2;
637 fedc0da2 Aurelien Jarno
            args += 2;
638 fedc0da2 Aurelien Jarno
            break;
639 53108fb5 Kirill Batuzov
        CASE_OP_32_64(add):
640 53108fb5 Kirill Batuzov
        CASE_OP_32_64(sub):
641 53108fb5 Kirill Batuzov
        CASE_OP_32_64(mul):
642 9a81090b Kirill Batuzov
        CASE_OP_32_64(or):
643 9a81090b Kirill Batuzov
        CASE_OP_32_64(and):
644 9a81090b Kirill Batuzov
        CASE_OP_32_64(xor):
645 55c0975c Kirill Batuzov
        CASE_OP_32_64(shl):
646 55c0975c Kirill Batuzov
        CASE_OP_32_64(shr):
647 55c0975c Kirill Batuzov
        CASE_OP_32_64(sar):
648 25c4d9cc Richard Henderson
        CASE_OP_32_64(rotl):
649 25c4d9cc Richard Henderson
        CASE_OP_32_64(rotr):
650 cb25c80a Richard Henderson
        CASE_OP_32_64(andc):
651 cb25c80a Richard Henderson
        CASE_OP_32_64(orc):
652 cb25c80a Richard Henderson
        CASE_OP_32_64(eqv):
653 cb25c80a Richard Henderson
        CASE_OP_32_64(nand):
654 cb25c80a Richard Henderson
        CASE_OP_32_64(nor):
655 53108fb5 Kirill Batuzov
            if (temps[args[1]].state == TCG_TEMP_CONST
656 53108fb5 Kirill Batuzov
                && temps[args[2]].state == TCG_TEMP_CONST) {
657 53108fb5 Kirill Batuzov
                gen_opc_buf[op_index] = op_to_movi(op);
658 53108fb5 Kirill Batuzov
                tmp = do_constant_folding(op, temps[args[1]].val,
659 53108fb5 Kirill Batuzov
                                          temps[args[2]].val);
660 e590d4e6 Aurelien Jarno
                tcg_opt_gen_movi(gen_args, args[0], tmp);
661 53108fb5 Kirill Batuzov
                gen_args += 2;
662 53108fb5 Kirill Batuzov
            } else {
663 e590d4e6 Aurelien Jarno
                reset_temp(args[0]);
664 53108fb5 Kirill Batuzov
                gen_args[0] = args[0];
665 53108fb5 Kirill Batuzov
                gen_args[1] = args[1];
666 53108fb5 Kirill Batuzov
                gen_args[2] = args[2];
667 53108fb5 Kirill Batuzov
                gen_args += 3;
668 53108fb5 Kirill Batuzov
            }
669 fedc0da2 Aurelien Jarno
            args += 3;
670 fedc0da2 Aurelien Jarno
            break;
671 7ef55fc9 Aurelien Jarno
        CASE_OP_32_64(deposit):
672 7ef55fc9 Aurelien Jarno
            if (temps[args[1]].state == TCG_TEMP_CONST
673 7ef55fc9 Aurelien Jarno
                && temps[args[2]].state == TCG_TEMP_CONST) {
674 7ef55fc9 Aurelien Jarno
                gen_opc_buf[op_index] = op_to_movi(op);
675 7ef55fc9 Aurelien Jarno
                tmp = ((1ull << args[4]) - 1);
676 7ef55fc9 Aurelien Jarno
                tmp = (temps[args[1]].val & ~(tmp << args[3]))
677 7ef55fc9 Aurelien Jarno
                      | ((temps[args[2]].val & tmp) << args[3]);
678 7ef55fc9 Aurelien Jarno
                tcg_opt_gen_movi(gen_args, args[0], tmp);
679 7ef55fc9 Aurelien Jarno
                gen_args += 2;
680 7ef55fc9 Aurelien Jarno
            } else {
681 7ef55fc9 Aurelien Jarno
                reset_temp(args[0]);
682 7ef55fc9 Aurelien Jarno
                gen_args[0] = args[0];
683 7ef55fc9 Aurelien Jarno
                gen_args[1] = args[1];
684 7ef55fc9 Aurelien Jarno
                gen_args[2] = args[2];
685 7ef55fc9 Aurelien Jarno
                gen_args[3] = args[3];
686 7ef55fc9 Aurelien Jarno
                gen_args[4] = args[4];
687 7ef55fc9 Aurelien Jarno
                gen_args += 5;
688 7ef55fc9 Aurelien Jarno
            }
689 7ef55fc9 Aurelien Jarno
            args += 5;
690 7ef55fc9 Aurelien Jarno
            break;
691 f8dd19e5 Aurelien Jarno
        CASE_OP_32_64(setcond):
692 b336ceb6 Aurelien Jarno
            tmp = do_constant_folding_cond(op, args[1], args[2], args[3]);
693 b336ceb6 Aurelien Jarno
            if (tmp != 2) {
694 f8dd19e5 Aurelien Jarno
                gen_opc_buf[op_index] = op_to_movi(op);
695 e590d4e6 Aurelien Jarno
                tcg_opt_gen_movi(gen_args, args[0], tmp);
696 f8dd19e5 Aurelien Jarno
                gen_args += 2;
697 f8dd19e5 Aurelien Jarno
            } else {
698 e590d4e6 Aurelien Jarno
                reset_temp(args[0]);
699 f8dd19e5 Aurelien Jarno
                gen_args[0] = args[0];
700 f8dd19e5 Aurelien Jarno
                gen_args[1] = args[1];
701 f8dd19e5 Aurelien Jarno
                gen_args[2] = args[2];
702 f8dd19e5 Aurelien Jarno
                gen_args[3] = args[3];
703 f8dd19e5 Aurelien Jarno
                gen_args += 4;
704 f8dd19e5 Aurelien Jarno
            }
705 fedc0da2 Aurelien Jarno
            args += 4;
706 fedc0da2 Aurelien Jarno
            break;
707 fbeaa26c Aurelien Jarno
        CASE_OP_32_64(brcond):
708 b336ceb6 Aurelien Jarno
            tmp = do_constant_folding_cond(op, args[0], args[1], args[2]);
709 b336ceb6 Aurelien Jarno
            if (tmp != 2) {
710 b336ceb6 Aurelien Jarno
                if (tmp) {
711 fbeaa26c Aurelien Jarno
                    memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
712 fbeaa26c Aurelien Jarno
                    gen_opc_buf[op_index] = INDEX_op_br;
713 fbeaa26c Aurelien Jarno
                    gen_args[0] = args[3];
714 fbeaa26c Aurelien Jarno
                    gen_args += 1;
715 fbeaa26c Aurelien Jarno
                } else {
716 fbeaa26c Aurelien Jarno
                    gen_opc_buf[op_index] = INDEX_op_nop;
717 fbeaa26c Aurelien Jarno
                }
718 fbeaa26c Aurelien Jarno
            } else {
719 fbeaa26c Aurelien Jarno
                memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
720 e590d4e6 Aurelien Jarno
                reset_temp(args[0]);
721 fbeaa26c Aurelien Jarno
                gen_args[0] = args[0];
722 fbeaa26c Aurelien Jarno
                gen_args[1] = args[1];
723 fbeaa26c Aurelien Jarno
                gen_args[2] = args[2];
724 fbeaa26c Aurelien Jarno
                gen_args[3] = args[3];
725 fbeaa26c Aurelien Jarno
                gen_args += 4;
726 fbeaa26c Aurelien Jarno
            }
727 fedc0da2 Aurelien Jarno
            args += 4;
728 fedc0da2 Aurelien Jarno
            break;
729 fa01a208 Richard Henderson
        CASE_OP_32_64(movcond):
730 b336ceb6 Aurelien Jarno
            tmp = do_constant_folding_cond(op, args[1], args[2], args[5]);
731 b336ceb6 Aurelien Jarno
            if (tmp != 2) {
732 e590d4e6 Aurelien Jarno
                if (temps_are_copies(args[0], args[4-tmp])) {
733 fa01a208 Richard Henderson
                    gen_opc_buf[op_index] = INDEX_op_nop;
734 fa01a208 Richard Henderson
                } else if (temps[args[4-tmp]].state == TCG_TEMP_CONST) {
735 fa01a208 Richard Henderson
                    gen_opc_buf[op_index] = op_to_movi(op);
736 e590d4e6 Aurelien Jarno
                    tcg_opt_gen_movi(gen_args, args[0], temps[args[4-tmp]].val);
737 fa01a208 Richard Henderson
                    gen_args += 2;
738 fa01a208 Richard Henderson
                } else {
739 fa01a208 Richard Henderson
                    gen_opc_buf[op_index] = op_to_mov(op);
740 e590d4e6 Aurelien Jarno
                    tcg_opt_gen_mov(s, gen_args, args[0], args[4-tmp]);
741 fa01a208 Richard Henderson
                    gen_args += 2;
742 fa01a208 Richard Henderson
                }
743 fa01a208 Richard Henderson
            } else {
744 e590d4e6 Aurelien Jarno
                reset_temp(args[0]);
745 fa01a208 Richard Henderson
                gen_args[0] = args[0];
746 fa01a208 Richard Henderson
                gen_args[1] = args[1];
747 fa01a208 Richard Henderson
                gen_args[2] = args[2];
748 fa01a208 Richard Henderson
                gen_args[3] = args[3];
749 fa01a208 Richard Henderson
                gen_args[4] = args[4];
750 fa01a208 Richard Henderson
                gen_args[5] = args[5];
751 fa01a208 Richard Henderson
                gen_args += 6;
752 fa01a208 Richard Henderson
            }
753 fa01a208 Richard Henderson
            args += 6;
754 fa01a208 Richard Henderson
            break;
755 8f2e8c07 Kirill Batuzov
        case INDEX_op_call:
756 22613af4 Kirill Batuzov
            nb_call_args = (args[0] >> 16) + (args[0] & 0xffff);
757 22613af4 Kirill Batuzov
            if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) {
758 22613af4 Kirill Batuzov
                for (i = 0; i < nb_globals; i++) {
759 e590d4e6 Aurelien Jarno
                    reset_temp(i);
760 22613af4 Kirill Batuzov
                }
761 22613af4 Kirill Batuzov
            }
762 22613af4 Kirill Batuzov
            for (i = 0; i < (args[0] >> 16); i++) {
763 e590d4e6 Aurelien Jarno
                reset_temp(args[i + 1]);
764 22613af4 Kirill Batuzov
            }
765 22613af4 Kirill Batuzov
            i = nb_call_args + 3;
766 8f2e8c07 Kirill Batuzov
            while (i) {
767 8f2e8c07 Kirill Batuzov
                *gen_args = *args;
768 8f2e8c07 Kirill Batuzov
                args++;
769 8f2e8c07 Kirill Batuzov
                gen_args++;
770 8f2e8c07 Kirill Batuzov
                i--;
771 8f2e8c07 Kirill Batuzov
            }
772 8f2e8c07 Kirill Batuzov
            break;
773 8f2e8c07 Kirill Batuzov
        default:
774 22613af4 Kirill Batuzov
            /* Default case: we do know nothing about operation so no
775 a2550660 Aurelien Jarno
               propagation is done.  We trash everything if the operation
776 a2550660 Aurelien Jarno
               is the end of a basic block, otherwise we only trash the
777 a2550660 Aurelien Jarno
               output args.  */
778 a2550660 Aurelien Jarno
            if (def->flags & TCG_OPF_BB_END) {
779 a2550660 Aurelien Jarno
                memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
780 a2550660 Aurelien Jarno
            } else {
781 a2550660 Aurelien Jarno
                for (i = 0; i < def->nb_oargs; i++) {
782 e590d4e6 Aurelien Jarno
                    reset_temp(args[i]);
783 a2550660 Aurelien Jarno
                }
784 22613af4 Kirill Batuzov
            }
785 8f2e8c07 Kirill Batuzov
            for (i = 0; i < def->nb_args; i++) {
786 8f2e8c07 Kirill Batuzov
                gen_args[i] = args[i];
787 8f2e8c07 Kirill Batuzov
            }
788 8f2e8c07 Kirill Batuzov
            args += def->nb_args;
789 8f2e8c07 Kirill Batuzov
            gen_args += def->nb_args;
790 8f2e8c07 Kirill Batuzov
            break;
791 8f2e8c07 Kirill Batuzov
        }
792 8f2e8c07 Kirill Batuzov
    }
793 8f2e8c07 Kirill Batuzov
794 8f2e8c07 Kirill Batuzov
    return gen_args;
795 8f2e8c07 Kirill Batuzov
}
796 8f2e8c07 Kirill Batuzov
797 8f2e8c07 Kirill Batuzov
TCGArg *tcg_optimize(TCGContext *s, uint16_t *tcg_opc_ptr,
798 8f2e8c07 Kirill Batuzov
        TCGArg *args, TCGOpDef *tcg_op_defs)
799 8f2e8c07 Kirill Batuzov
{
800 8f2e8c07 Kirill Batuzov
    TCGArg *res;
801 8f2e8c07 Kirill Batuzov
    res = tcg_constant_folding(s, tcg_opc_ptr, args, tcg_op_defs);
802 8f2e8c07 Kirill Batuzov
    return res;
803 8f2e8c07 Kirill Batuzov
}