xref: /openbmc/qemu/tcg/optimize.c (revision 3a9d8b17)
18f2e8c07SKirill Batuzov /*
28f2e8c07SKirill Batuzov  * Optimizations for Tiny Code Generator for QEMU
38f2e8c07SKirill Batuzov  *
48f2e8c07SKirill Batuzov  * Copyright (c) 2010 Samsung Electronics.
58f2e8c07SKirill Batuzov  * Contributed by Kirill Batuzov <batuzovk@ispras.ru>
68f2e8c07SKirill Batuzov  *
78f2e8c07SKirill Batuzov  * Permission is hereby granted, free of charge, to any person obtaining a copy
88f2e8c07SKirill Batuzov  * of this software and associated documentation files (the "Software"), to deal
98f2e8c07SKirill Batuzov  * in the Software without restriction, including without limitation the rights
108f2e8c07SKirill Batuzov  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
118f2e8c07SKirill Batuzov  * copies of the Software, and to permit persons to whom the Software is
128f2e8c07SKirill Batuzov  * furnished to do so, subject to the following conditions:
138f2e8c07SKirill Batuzov  *
148f2e8c07SKirill Batuzov  * The above copyright notice and this permission notice shall be included in
158f2e8c07SKirill Batuzov  * all copies or substantial portions of the Software.
168f2e8c07SKirill Batuzov  *
178f2e8c07SKirill Batuzov  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
188f2e8c07SKirill Batuzov  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
198f2e8c07SKirill Batuzov  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
208f2e8c07SKirill Batuzov  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
218f2e8c07SKirill Batuzov  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
228f2e8c07SKirill Batuzov  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
238f2e8c07SKirill Batuzov  * THE SOFTWARE.
248f2e8c07SKirill Batuzov  */
258f2e8c07SKirill Batuzov 
268f2e8c07SKirill Batuzov #include "config.h"
278f2e8c07SKirill Batuzov 
288f2e8c07SKirill Batuzov #include <stdlib.h>
298f2e8c07SKirill Batuzov #include <stdio.h>
308f2e8c07SKirill Batuzov 
318f2e8c07SKirill Batuzov #include "qemu-common.h"
328f2e8c07SKirill Batuzov #include "tcg-op.h"
338f2e8c07SKirill Batuzov 
348f2e8c07SKirill Batuzov #define CASE_OP_32_64(x)                        \
358f2e8c07SKirill Batuzov         glue(glue(case INDEX_op_, x), _i32):    \
368f2e8c07SKirill Batuzov         glue(glue(case INDEX_op_, x), _i64)
378f2e8c07SKirill Batuzov 
3822613af4SKirill Batuzov typedef enum {
3922613af4SKirill Batuzov     TCG_TEMP_UNDEF = 0,
4022613af4SKirill Batuzov     TCG_TEMP_CONST,
4122613af4SKirill Batuzov     TCG_TEMP_COPY,
4222613af4SKirill Batuzov } tcg_temp_state;
4322613af4SKirill Batuzov 
4422613af4SKirill Batuzov struct tcg_temp_info {
4522613af4SKirill Batuzov     tcg_temp_state state;
4622613af4SKirill Batuzov     uint16_t prev_copy;
4722613af4SKirill Batuzov     uint16_t next_copy;
4822613af4SKirill Batuzov     tcg_target_ulong val;
49*3a9d8b17SPaolo Bonzini     tcg_target_ulong mask;
5022613af4SKirill Batuzov };
5122613af4SKirill Batuzov 
5222613af4SKirill Batuzov static struct tcg_temp_info temps[TCG_MAX_TEMPS];
5322613af4SKirill Batuzov 
54e590d4e6SAurelien Jarno /* Reset TEMP's state to TCG_TEMP_UNDEF.  If TEMP only had one copy, remove
55e590d4e6SAurelien Jarno    the copy flag from the left temp.  */
56e590d4e6SAurelien Jarno static void reset_temp(TCGArg temp)
5722613af4SKirill Batuzov {
58e590d4e6SAurelien Jarno     if (temps[temp].state == TCG_TEMP_COPY) {
59e590d4e6SAurelien Jarno         if (temps[temp].prev_copy == temps[temp].next_copy) {
60e590d4e6SAurelien Jarno             temps[temps[temp].next_copy].state = TCG_TEMP_UNDEF;
6122613af4SKirill Batuzov         } else {
6222613af4SKirill Batuzov             temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy;
6322613af4SKirill Batuzov             temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy;
64e590d4e6SAurelien Jarno         }
6522613af4SKirill Batuzov     }
6648b56ce1SAurelien Jarno     temps[temp].state = TCG_TEMP_UNDEF;
67*3a9d8b17SPaolo Bonzini     temps[temp].mask = -1;
6822613af4SKirill Batuzov }
6922613af4SKirill Batuzov 
70d193a14aSPaolo Bonzini /* Reset all temporaries, given that there are NB_TEMPS of them.  */
71d193a14aSPaolo Bonzini static void reset_all_temps(int nb_temps)
72d193a14aSPaolo Bonzini {
73d193a14aSPaolo Bonzini     int i;
74d193a14aSPaolo Bonzini     for (i = 0; i < nb_temps; i++) {
75d193a14aSPaolo Bonzini         temps[i].state = TCG_TEMP_UNDEF;
76*3a9d8b17SPaolo Bonzini         temps[i].mask = -1;
77d193a14aSPaolo Bonzini     }
78d193a14aSPaolo Bonzini }
79d193a14aSPaolo Bonzini 
80fe0de7aaSBlue Swirl static int op_bits(TCGOpcode op)
8122613af4SKirill Batuzov {
828399ad59SRichard Henderson     const TCGOpDef *def = &tcg_op_defs[op];
838399ad59SRichard Henderson     return def->flags & TCG_OPF_64BIT ? 64 : 32;
8422613af4SKirill Batuzov }
8522613af4SKirill Batuzov 
86fe0de7aaSBlue Swirl static TCGOpcode op_to_movi(TCGOpcode op)
8722613af4SKirill Batuzov {
8822613af4SKirill Batuzov     switch (op_bits(op)) {
8922613af4SKirill Batuzov     case 32:
9022613af4SKirill Batuzov         return INDEX_op_movi_i32;
9122613af4SKirill Batuzov     case 64:
9222613af4SKirill Batuzov         return INDEX_op_movi_i64;
9322613af4SKirill Batuzov     default:
9422613af4SKirill Batuzov         fprintf(stderr, "op_to_movi: unexpected return value of "
9522613af4SKirill Batuzov                 "function op_bits.\n");
9622613af4SKirill Batuzov         tcg_abort();
9722613af4SKirill Batuzov     }
9822613af4SKirill Batuzov }
9922613af4SKirill Batuzov 
100e590d4e6SAurelien Jarno static TCGArg find_better_copy(TCGContext *s, TCGArg temp)
101e590d4e6SAurelien Jarno {
102e590d4e6SAurelien Jarno     TCGArg i;
103e590d4e6SAurelien Jarno 
104e590d4e6SAurelien Jarno     /* If this is already a global, we can't do better. */
105e590d4e6SAurelien Jarno     if (temp < s->nb_globals) {
106e590d4e6SAurelien Jarno         return temp;
107e590d4e6SAurelien Jarno     }
108e590d4e6SAurelien Jarno 
109e590d4e6SAurelien Jarno     /* Search for a global first. */
110e590d4e6SAurelien Jarno     for (i = temps[temp].next_copy ; i != temp ; i = temps[i].next_copy) {
111e590d4e6SAurelien Jarno         if (i < s->nb_globals) {
112e590d4e6SAurelien Jarno             return i;
113e590d4e6SAurelien Jarno         }
114e590d4e6SAurelien Jarno     }
115e590d4e6SAurelien Jarno 
116e590d4e6SAurelien Jarno     /* If it is a temp, search for a temp local. */
117e590d4e6SAurelien Jarno     if (!s->temps[temp].temp_local) {
118e590d4e6SAurelien Jarno         for (i = temps[temp].next_copy ; i != temp ; i = temps[i].next_copy) {
119e590d4e6SAurelien Jarno             if (s->temps[i].temp_local) {
120e590d4e6SAurelien Jarno                 return i;
121e590d4e6SAurelien Jarno             }
122e590d4e6SAurelien Jarno         }
123e590d4e6SAurelien Jarno     }
124e590d4e6SAurelien Jarno 
125e590d4e6SAurelien Jarno     /* Failure to find a better representation, return the same temp. */
126e590d4e6SAurelien Jarno     return temp;
127e590d4e6SAurelien Jarno }
128e590d4e6SAurelien Jarno 
129e590d4e6SAurelien Jarno static bool temps_are_copies(TCGArg arg1, TCGArg arg2)
130e590d4e6SAurelien Jarno {
131e590d4e6SAurelien Jarno     TCGArg i;
132e590d4e6SAurelien Jarno 
133e590d4e6SAurelien Jarno     if (arg1 == arg2) {
134e590d4e6SAurelien Jarno         return true;
135e590d4e6SAurelien Jarno     }
136e590d4e6SAurelien Jarno 
137e590d4e6SAurelien Jarno     if (temps[arg1].state != TCG_TEMP_COPY
138e590d4e6SAurelien Jarno         || temps[arg2].state != TCG_TEMP_COPY) {
139e590d4e6SAurelien Jarno         return false;
140e590d4e6SAurelien Jarno     }
141e590d4e6SAurelien Jarno 
142e590d4e6SAurelien Jarno     for (i = temps[arg1].next_copy ; i != arg1 ; i = temps[i].next_copy) {
143e590d4e6SAurelien Jarno         if (i == arg2) {
144e590d4e6SAurelien Jarno             return true;
145e590d4e6SAurelien Jarno         }
146e590d4e6SAurelien Jarno     }
147e590d4e6SAurelien Jarno 
148e590d4e6SAurelien Jarno     return false;
149e590d4e6SAurelien Jarno }
150e590d4e6SAurelien Jarno 
151b80bb016SAurelien Jarno static void tcg_opt_gen_mov(TCGContext *s, TCGArg *gen_args,
152b80bb016SAurelien Jarno                             TCGArg dst, TCGArg src)
15322613af4SKirill Batuzov {
154e590d4e6SAurelien Jarno     reset_temp(dst);
155*3a9d8b17SPaolo Bonzini     temps[dst].mask = temps[src].mask;
15622613af4SKirill Batuzov     assert(temps[src].state != TCG_TEMP_CONST);
157e590d4e6SAurelien Jarno 
158e590d4e6SAurelien Jarno     if (s->temps[src].type == s->temps[dst].type) {
159e590d4e6SAurelien Jarno         if (temps[src].state != TCG_TEMP_COPY) {
160e590d4e6SAurelien Jarno             temps[src].state = TCG_TEMP_COPY;
16122613af4SKirill Batuzov             temps[src].next_copy = src;
16222613af4SKirill Batuzov             temps[src].prev_copy = src;
16322613af4SKirill Batuzov         }
16422613af4SKirill Batuzov         temps[dst].state = TCG_TEMP_COPY;
16522613af4SKirill Batuzov         temps[dst].next_copy = temps[src].next_copy;
16622613af4SKirill Batuzov         temps[dst].prev_copy = src;
16722613af4SKirill Batuzov         temps[temps[dst].next_copy].prev_copy = dst;
16822613af4SKirill Batuzov         temps[src].next_copy = dst;
16922613af4SKirill Batuzov     }
170e590d4e6SAurelien Jarno 
17122613af4SKirill Batuzov     gen_args[0] = dst;
17222613af4SKirill Batuzov     gen_args[1] = src;
17322613af4SKirill Batuzov }
17422613af4SKirill Batuzov 
175e590d4e6SAurelien Jarno static void tcg_opt_gen_movi(TCGArg *gen_args, TCGArg dst, TCGArg val)
17622613af4SKirill Batuzov {
177e590d4e6SAurelien Jarno     reset_temp(dst);
17822613af4SKirill Batuzov     temps[dst].state = TCG_TEMP_CONST;
17922613af4SKirill Batuzov     temps[dst].val = val;
180*3a9d8b17SPaolo Bonzini     temps[dst].mask = val;
18122613af4SKirill Batuzov     gen_args[0] = dst;
18222613af4SKirill Batuzov     gen_args[1] = val;
18322613af4SKirill Batuzov }
18422613af4SKirill Batuzov 
185fe0de7aaSBlue Swirl static TCGOpcode op_to_mov(TCGOpcode op)
18653108fb5SKirill Batuzov {
18753108fb5SKirill Batuzov     switch (op_bits(op)) {
18853108fb5SKirill Batuzov     case 32:
18953108fb5SKirill Batuzov         return INDEX_op_mov_i32;
19053108fb5SKirill Batuzov     case 64:
19153108fb5SKirill Batuzov         return INDEX_op_mov_i64;
19253108fb5SKirill Batuzov     default:
19353108fb5SKirill Batuzov         fprintf(stderr, "op_to_mov: unexpected return value of "
19453108fb5SKirill Batuzov                 "function op_bits.\n");
19553108fb5SKirill Batuzov         tcg_abort();
19653108fb5SKirill Batuzov     }
19753108fb5SKirill Batuzov }
19853108fb5SKirill Batuzov 
199fe0de7aaSBlue Swirl static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y)
20053108fb5SKirill Batuzov {
20153108fb5SKirill Batuzov     switch (op) {
20253108fb5SKirill Batuzov     CASE_OP_32_64(add):
20353108fb5SKirill Batuzov         return x + y;
20453108fb5SKirill Batuzov 
20553108fb5SKirill Batuzov     CASE_OP_32_64(sub):
20653108fb5SKirill Batuzov         return x - y;
20753108fb5SKirill Batuzov 
20853108fb5SKirill Batuzov     CASE_OP_32_64(mul):
20953108fb5SKirill Batuzov         return x * y;
21053108fb5SKirill Batuzov 
2119a81090bSKirill Batuzov     CASE_OP_32_64(and):
2129a81090bSKirill Batuzov         return x & y;
2139a81090bSKirill Batuzov 
2149a81090bSKirill Batuzov     CASE_OP_32_64(or):
2159a81090bSKirill Batuzov         return x | y;
2169a81090bSKirill Batuzov 
2179a81090bSKirill Batuzov     CASE_OP_32_64(xor):
2189a81090bSKirill Batuzov         return x ^ y;
2199a81090bSKirill Batuzov 
22055c0975cSKirill Batuzov     case INDEX_op_shl_i32:
22155c0975cSKirill Batuzov         return (uint32_t)x << (uint32_t)y;
22255c0975cSKirill Batuzov 
22355c0975cSKirill Batuzov     case INDEX_op_shl_i64:
22455c0975cSKirill Batuzov         return (uint64_t)x << (uint64_t)y;
22555c0975cSKirill Batuzov 
22655c0975cSKirill Batuzov     case INDEX_op_shr_i32:
22755c0975cSKirill Batuzov         return (uint32_t)x >> (uint32_t)y;
22855c0975cSKirill Batuzov 
22955c0975cSKirill Batuzov     case INDEX_op_shr_i64:
23055c0975cSKirill Batuzov         return (uint64_t)x >> (uint64_t)y;
23155c0975cSKirill Batuzov 
23255c0975cSKirill Batuzov     case INDEX_op_sar_i32:
23355c0975cSKirill Batuzov         return (int32_t)x >> (int32_t)y;
23455c0975cSKirill Batuzov 
23555c0975cSKirill Batuzov     case INDEX_op_sar_i64:
23655c0975cSKirill Batuzov         return (int64_t)x >> (int64_t)y;
23755c0975cSKirill Batuzov 
23855c0975cSKirill Batuzov     case INDEX_op_rotr_i32:
23925c4d9ccSRichard Henderson         x = ((uint32_t)x << (32 - y)) | ((uint32_t)x >> y);
24055c0975cSKirill Batuzov         return x;
24155c0975cSKirill Batuzov 
24255c0975cSKirill Batuzov     case INDEX_op_rotr_i64:
24325c4d9ccSRichard Henderson         x = ((uint64_t)x << (64 - y)) | ((uint64_t)x >> y);
24455c0975cSKirill Batuzov         return x;
24555c0975cSKirill Batuzov 
24655c0975cSKirill Batuzov     case INDEX_op_rotl_i32:
24725c4d9ccSRichard Henderson         x = ((uint32_t)x << y) | ((uint32_t)x >> (32 - y));
24855c0975cSKirill Batuzov         return x;
24955c0975cSKirill Batuzov 
25055c0975cSKirill Batuzov     case INDEX_op_rotl_i64:
25125c4d9ccSRichard Henderson         x = ((uint64_t)x << y) | ((uint64_t)x >> (64 - y));
25255c0975cSKirill Batuzov         return x;
25355c0975cSKirill Batuzov 
25425c4d9ccSRichard Henderson     CASE_OP_32_64(not):
255a640f031SKirill Batuzov         return ~x;
256a640f031SKirill Batuzov 
257cb25c80aSRichard Henderson     CASE_OP_32_64(neg):
258cb25c80aSRichard Henderson         return -x;
259cb25c80aSRichard Henderson 
260cb25c80aSRichard Henderson     CASE_OP_32_64(andc):
261cb25c80aSRichard Henderson         return x & ~y;
262cb25c80aSRichard Henderson 
263cb25c80aSRichard Henderson     CASE_OP_32_64(orc):
264cb25c80aSRichard Henderson         return x | ~y;
265cb25c80aSRichard Henderson 
266cb25c80aSRichard Henderson     CASE_OP_32_64(eqv):
267cb25c80aSRichard Henderson         return ~(x ^ y);
268cb25c80aSRichard Henderson 
269cb25c80aSRichard Henderson     CASE_OP_32_64(nand):
270cb25c80aSRichard Henderson         return ~(x & y);
271cb25c80aSRichard Henderson 
272cb25c80aSRichard Henderson     CASE_OP_32_64(nor):
273cb25c80aSRichard Henderson         return ~(x | y);
274cb25c80aSRichard Henderson 
27525c4d9ccSRichard Henderson     CASE_OP_32_64(ext8s):
276a640f031SKirill Batuzov         return (int8_t)x;
277a640f031SKirill Batuzov 
27825c4d9ccSRichard Henderson     CASE_OP_32_64(ext16s):
279a640f031SKirill Batuzov         return (int16_t)x;
280a640f031SKirill Batuzov 
28125c4d9ccSRichard Henderson     CASE_OP_32_64(ext8u):
282a640f031SKirill Batuzov         return (uint8_t)x;
283a640f031SKirill Batuzov 
28425c4d9ccSRichard Henderson     CASE_OP_32_64(ext16u):
285a640f031SKirill Batuzov         return (uint16_t)x;
286a640f031SKirill Batuzov 
287a640f031SKirill Batuzov     case INDEX_op_ext32s_i64:
288a640f031SKirill Batuzov         return (int32_t)x;
289a640f031SKirill Batuzov 
290a640f031SKirill Batuzov     case INDEX_op_ext32u_i64:
291a640f031SKirill Batuzov         return (uint32_t)x;
292a640f031SKirill Batuzov 
29353108fb5SKirill Batuzov     default:
29453108fb5SKirill Batuzov         fprintf(stderr,
29553108fb5SKirill Batuzov                 "Unrecognized operation %d in do_constant_folding.\n", op);
29653108fb5SKirill Batuzov         tcg_abort();
29753108fb5SKirill Batuzov     }
29853108fb5SKirill Batuzov }
29953108fb5SKirill Batuzov 
300fe0de7aaSBlue Swirl static TCGArg do_constant_folding(TCGOpcode op, TCGArg x, TCGArg y)
30153108fb5SKirill Batuzov {
30253108fb5SKirill Batuzov     TCGArg res = do_constant_folding_2(op, x, y);
30353108fb5SKirill Batuzov     if (op_bits(op) == 32) {
30453108fb5SKirill Batuzov         res &= 0xffffffff;
30553108fb5SKirill Batuzov     }
30653108fb5SKirill Batuzov     return res;
30753108fb5SKirill Batuzov }
30853108fb5SKirill Batuzov 
3099519da7eSRichard Henderson static bool do_constant_folding_cond_32(uint32_t x, uint32_t y, TCGCond c)
310f8dd19e5SAurelien Jarno {
311f8dd19e5SAurelien Jarno     switch (c) {
312f8dd19e5SAurelien Jarno     case TCG_COND_EQ:
3139519da7eSRichard Henderson         return x == y;
314f8dd19e5SAurelien Jarno     case TCG_COND_NE:
3159519da7eSRichard Henderson         return x != y;
316f8dd19e5SAurelien Jarno     case TCG_COND_LT:
3179519da7eSRichard Henderson         return (int32_t)x < (int32_t)y;
318f8dd19e5SAurelien Jarno     case TCG_COND_GE:
3199519da7eSRichard Henderson         return (int32_t)x >= (int32_t)y;
320f8dd19e5SAurelien Jarno     case TCG_COND_LE:
3219519da7eSRichard Henderson         return (int32_t)x <= (int32_t)y;
322f8dd19e5SAurelien Jarno     case TCG_COND_GT:
3239519da7eSRichard Henderson         return (int32_t)x > (int32_t)y;
324f8dd19e5SAurelien Jarno     case TCG_COND_LTU:
3259519da7eSRichard Henderson         return x < y;
326f8dd19e5SAurelien Jarno     case TCG_COND_GEU:
3279519da7eSRichard Henderson         return x >= y;
328f8dd19e5SAurelien Jarno     case TCG_COND_LEU:
3299519da7eSRichard Henderson         return x <= y;
330f8dd19e5SAurelien Jarno     case TCG_COND_GTU:
3319519da7eSRichard Henderson         return x > y;
3320aed257fSRichard Henderson     default:
3339519da7eSRichard Henderson         tcg_abort();
334f8dd19e5SAurelien Jarno     }
3359519da7eSRichard Henderson }
3369519da7eSRichard Henderson 
3379519da7eSRichard Henderson static bool do_constant_folding_cond_64(uint64_t x, uint64_t y, TCGCond c)
3389519da7eSRichard Henderson {
339f8dd19e5SAurelien Jarno     switch (c) {
340f8dd19e5SAurelien Jarno     case TCG_COND_EQ:
3419519da7eSRichard Henderson         return x == y;
342f8dd19e5SAurelien Jarno     case TCG_COND_NE:
3439519da7eSRichard Henderson         return x != y;
344f8dd19e5SAurelien Jarno     case TCG_COND_LT:
3459519da7eSRichard Henderson         return (int64_t)x < (int64_t)y;
346f8dd19e5SAurelien Jarno     case TCG_COND_GE:
3479519da7eSRichard Henderson         return (int64_t)x >= (int64_t)y;
348f8dd19e5SAurelien Jarno     case TCG_COND_LE:
3499519da7eSRichard Henderson         return (int64_t)x <= (int64_t)y;
350f8dd19e5SAurelien Jarno     case TCG_COND_GT:
3519519da7eSRichard Henderson         return (int64_t)x > (int64_t)y;
352f8dd19e5SAurelien Jarno     case TCG_COND_LTU:
3539519da7eSRichard Henderson         return x < y;
354f8dd19e5SAurelien Jarno     case TCG_COND_GEU:
3559519da7eSRichard Henderson         return x >= y;
356f8dd19e5SAurelien Jarno     case TCG_COND_LEU:
3579519da7eSRichard Henderson         return x <= y;
358f8dd19e5SAurelien Jarno     case TCG_COND_GTU:
3599519da7eSRichard Henderson         return x > y;
3600aed257fSRichard Henderson     default:
3619519da7eSRichard Henderson         tcg_abort();
362f8dd19e5SAurelien Jarno     }
363f8dd19e5SAurelien Jarno }
3649519da7eSRichard Henderson 
3659519da7eSRichard Henderson static bool do_constant_folding_cond_eq(TCGCond c)
3669519da7eSRichard Henderson {
367b336ceb6SAurelien Jarno     switch (c) {
368b336ceb6SAurelien Jarno     case TCG_COND_GT:
369b336ceb6SAurelien Jarno     case TCG_COND_LTU:
370b336ceb6SAurelien Jarno     case TCG_COND_LT:
371b336ceb6SAurelien Jarno     case TCG_COND_GTU:
372b336ceb6SAurelien Jarno     case TCG_COND_NE:
373b336ceb6SAurelien Jarno         return 0;
374b336ceb6SAurelien Jarno     case TCG_COND_GE:
375b336ceb6SAurelien Jarno     case TCG_COND_GEU:
376b336ceb6SAurelien Jarno     case TCG_COND_LE:
377b336ceb6SAurelien Jarno     case TCG_COND_LEU:
378b336ceb6SAurelien Jarno     case TCG_COND_EQ:
379b336ceb6SAurelien Jarno         return 1;
3800aed257fSRichard Henderson     default:
3819519da7eSRichard Henderson         tcg_abort();
382b336ceb6SAurelien Jarno     }
3839519da7eSRichard Henderson }
3849519da7eSRichard Henderson 
3859519da7eSRichard Henderson /* Return 2 if the condition can't be simplified, and the result
3869519da7eSRichard Henderson    of the condition (0 or 1) if it can */
3879519da7eSRichard Henderson static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x,
3889519da7eSRichard Henderson                                        TCGArg y, TCGCond c)
3899519da7eSRichard Henderson {
3909519da7eSRichard Henderson     if (temps[x].state == TCG_TEMP_CONST && temps[y].state == TCG_TEMP_CONST) {
3919519da7eSRichard Henderson         switch (op_bits(op)) {
3929519da7eSRichard Henderson         case 32:
3939519da7eSRichard Henderson             return do_constant_folding_cond_32(temps[x].val, temps[y].val, c);
3949519da7eSRichard Henderson         case 64:
3959519da7eSRichard Henderson             return do_constant_folding_cond_64(temps[x].val, temps[y].val, c);
3969519da7eSRichard Henderson         default:
3979519da7eSRichard Henderson             tcg_abort();
3989519da7eSRichard Henderson         }
3999519da7eSRichard Henderson     } else if (temps_are_copies(x, y)) {
4009519da7eSRichard Henderson         return do_constant_folding_cond_eq(c);
401b336ceb6SAurelien Jarno     } else if (temps[y].state == TCG_TEMP_CONST && temps[y].val == 0) {
402b336ceb6SAurelien Jarno         switch (c) {
403b336ceb6SAurelien Jarno         case TCG_COND_LTU:
404b336ceb6SAurelien Jarno             return 0;
405b336ceb6SAurelien Jarno         case TCG_COND_GEU:
406b336ceb6SAurelien Jarno             return 1;
407b336ceb6SAurelien Jarno         default:
408b336ceb6SAurelien Jarno             return 2;
409b336ceb6SAurelien Jarno         }
410b336ceb6SAurelien Jarno     } else {
411b336ceb6SAurelien Jarno         return 2;
412b336ceb6SAurelien Jarno     }
413f8dd19e5SAurelien Jarno }
414f8dd19e5SAurelien Jarno 
4156c4382f8SRichard Henderson /* Return 2 if the condition can't be simplified, and the result
4166c4382f8SRichard Henderson    of the condition (0 or 1) if it can */
4176c4382f8SRichard Henderson static TCGArg do_constant_folding_cond2(TCGArg *p1, TCGArg *p2, TCGCond c)
4186c4382f8SRichard Henderson {
4196c4382f8SRichard Henderson     TCGArg al = p1[0], ah = p1[1];
4206c4382f8SRichard Henderson     TCGArg bl = p2[0], bh = p2[1];
4216c4382f8SRichard Henderson 
4226c4382f8SRichard Henderson     if (temps[bl].state == TCG_TEMP_CONST
4236c4382f8SRichard Henderson         && temps[bh].state == TCG_TEMP_CONST) {
4246c4382f8SRichard Henderson         uint64_t b = ((uint64_t)temps[bh].val << 32) | (uint32_t)temps[bl].val;
4256c4382f8SRichard Henderson 
4266c4382f8SRichard Henderson         if (temps[al].state == TCG_TEMP_CONST
4276c4382f8SRichard Henderson             && temps[ah].state == TCG_TEMP_CONST) {
4286c4382f8SRichard Henderson             uint64_t a;
4296c4382f8SRichard Henderson             a = ((uint64_t)temps[ah].val << 32) | (uint32_t)temps[al].val;
4306c4382f8SRichard Henderson             return do_constant_folding_cond_64(a, b, c);
4316c4382f8SRichard Henderson         }
4326c4382f8SRichard Henderson         if (b == 0) {
4336c4382f8SRichard Henderson             switch (c) {
4346c4382f8SRichard Henderson             case TCG_COND_LTU:
4356c4382f8SRichard Henderson                 return 0;
4366c4382f8SRichard Henderson             case TCG_COND_GEU:
4376c4382f8SRichard Henderson                 return 1;
4386c4382f8SRichard Henderson             default:
4396c4382f8SRichard Henderson                 break;
4406c4382f8SRichard Henderson             }
4416c4382f8SRichard Henderson         }
4426c4382f8SRichard Henderson     }
4436c4382f8SRichard Henderson     if (temps_are_copies(al, bl) && temps_are_copies(ah, bh)) {
4446c4382f8SRichard Henderson         return do_constant_folding_cond_eq(c);
4456c4382f8SRichard Henderson     }
4466c4382f8SRichard Henderson     return 2;
4476c4382f8SRichard Henderson }
4486c4382f8SRichard Henderson 
44924c9ae4eSRichard Henderson static bool swap_commutative(TCGArg dest, TCGArg *p1, TCGArg *p2)
45024c9ae4eSRichard Henderson {
45124c9ae4eSRichard Henderson     TCGArg a1 = *p1, a2 = *p2;
45224c9ae4eSRichard Henderson     int sum = 0;
45324c9ae4eSRichard Henderson     sum += temps[a1].state == TCG_TEMP_CONST;
45424c9ae4eSRichard Henderson     sum -= temps[a2].state == TCG_TEMP_CONST;
45524c9ae4eSRichard Henderson 
45624c9ae4eSRichard Henderson     /* Prefer the constant in second argument, and then the form
45724c9ae4eSRichard Henderson        op a, a, b, which is better handled on non-RISC hosts. */
45824c9ae4eSRichard Henderson     if (sum > 0 || (sum == 0 && dest == a2)) {
45924c9ae4eSRichard Henderson         *p1 = a2;
46024c9ae4eSRichard Henderson         *p2 = a1;
46124c9ae4eSRichard Henderson         return true;
46224c9ae4eSRichard Henderson     }
46324c9ae4eSRichard Henderson     return false;
46424c9ae4eSRichard Henderson }
46524c9ae4eSRichard Henderson 
4660bfcb865SRichard Henderson static bool swap_commutative2(TCGArg *p1, TCGArg *p2)
4670bfcb865SRichard Henderson {
4680bfcb865SRichard Henderson     int sum = 0;
4690bfcb865SRichard Henderson     sum += temps[p1[0]].state == TCG_TEMP_CONST;
4700bfcb865SRichard Henderson     sum += temps[p1[1]].state == TCG_TEMP_CONST;
4710bfcb865SRichard Henderson     sum -= temps[p2[0]].state == TCG_TEMP_CONST;
4720bfcb865SRichard Henderson     sum -= temps[p2[1]].state == TCG_TEMP_CONST;
4730bfcb865SRichard Henderson     if (sum > 0) {
4740bfcb865SRichard Henderson         TCGArg t;
4750bfcb865SRichard Henderson         t = p1[0], p1[0] = p2[0], p2[0] = t;
4760bfcb865SRichard Henderson         t = p1[1], p1[1] = p2[1], p2[1] = t;
4770bfcb865SRichard Henderson         return true;
4780bfcb865SRichard Henderson     }
4790bfcb865SRichard Henderson     return false;
4800bfcb865SRichard Henderson }
4810bfcb865SRichard Henderson 
48222613af4SKirill Batuzov /* Propagate constants and copies, fold constant expressions. */
4838f2e8c07SKirill Batuzov static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
4848f2e8c07SKirill Batuzov                                     TCGArg *args, TCGOpDef *tcg_op_defs)
4858f2e8c07SKirill Batuzov {
486fe0de7aaSBlue Swirl     int i, nb_ops, op_index, nb_temps, nb_globals, nb_call_args;
487*3a9d8b17SPaolo Bonzini     tcg_target_ulong mask;
488fe0de7aaSBlue Swirl     TCGOpcode op;
4898f2e8c07SKirill Batuzov     const TCGOpDef *def;
4908f2e8c07SKirill Batuzov     TCGArg *gen_args;
49153108fb5SKirill Batuzov     TCGArg tmp;
4925d8f5363SRichard Henderson 
49322613af4SKirill Batuzov     /* Array VALS has an element for each temp.
49422613af4SKirill Batuzov        If this temp holds a constant then its value is kept in VALS' element.
495e590d4e6SAurelien Jarno        If this temp is a copy of other ones then the other copies are
496e590d4e6SAurelien Jarno        available through the doubly linked circular list. */
4978f2e8c07SKirill Batuzov 
4988f2e8c07SKirill Batuzov     nb_temps = s->nb_temps;
4998f2e8c07SKirill Batuzov     nb_globals = s->nb_globals;
500d193a14aSPaolo Bonzini     reset_all_temps(nb_temps);
5018f2e8c07SKirill Batuzov 
50292414b31SEvgeny Voevodin     nb_ops = tcg_opc_ptr - s->gen_opc_buf;
5038f2e8c07SKirill Batuzov     gen_args = args;
5048f2e8c07SKirill Batuzov     for (op_index = 0; op_index < nb_ops; op_index++) {
50592414b31SEvgeny Voevodin         op = s->gen_opc_buf[op_index];
5068f2e8c07SKirill Batuzov         def = &tcg_op_defs[op];
50722613af4SKirill Batuzov         /* Do copy propagation */
5081ff8c541SAurelien Jarno         if (op == INDEX_op_call) {
5091ff8c541SAurelien Jarno             int nb_oargs = args[0] >> 16;
5101ff8c541SAurelien Jarno             int nb_iargs = args[0] & 0xffff;
5111ff8c541SAurelien Jarno             for (i = nb_oargs + 1; i < nb_oargs + nb_iargs + 1; i++) {
5121ff8c541SAurelien Jarno                 if (temps[args[i]].state == TCG_TEMP_COPY) {
5131ff8c541SAurelien Jarno                     args[i] = find_better_copy(s, args[i]);
5141ff8c541SAurelien Jarno                 }
5151ff8c541SAurelien Jarno             }
5161ff8c541SAurelien Jarno         } else {
51722613af4SKirill Batuzov             for (i = def->nb_oargs; i < def->nb_oargs + def->nb_iargs; i++) {
51822613af4SKirill Batuzov                 if (temps[args[i]].state == TCG_TEMP_COPY) {
519e590d4e6SAurelien Jarno                     args[i] = find_better_copy(s, args[i]);
52022613af4SKirill Batuzov                 }
52122613af4SKirill Batuzov             }
52222613af4SKirill Batuzov         }
52322613af4SKirill Batuzov 
52453108fb5SKirill Batuzov         /* For commutative operations make constant second argument */
52553108fb5SKirill Batuzov         switch (op) {
52653108fb5SKirill Batuzov         CASE_OP_32_64(add):
52753108fb5SKirill Batuzov         CASE_OP_32_64(mul):
5289a81090bSKirill Batuzov         CASE_OP_32_64(and):
5299a81090bSKirill Batuzov         CASE_OP_32_64(or):
5309a81090bSKirill Batuzov         CASE_OP_32_64(xor):
531cb25c80aSRichard Henderson         CASE_OP_32_64(eqv):
532cb25c80aSRichard Henderson         CASE_OP_32_64(nand):
533cb25c80aSRichard Henderson         CASE_OP_32_64(nor):
53424c9ae4eSRichard Henderson             swap_commutative(args[0], &args[1], &args[2]);
53553108fb5SKirill Batuzov             break;
53665a7cce1SAurelien Jarno         CASE_OP_32_64(brcond):
53724c9ae4eSRichard Henderson             if (swap_commutative(-1, &args[0], &args[1])) {
53865a7cce1SAurelien Jarno                 args[2] = tcg_swap_cond(args[2]);
53965a7cce1SAurelien Jarno             }
54065a7cce1SAurelien Jarno             break;
54165a7cce1SAurelien Jarno         CASE_OP_32_64(setcond):
54224c9ae4eSRichard Henderson             if (swap_commutative(args[0], &args[1], &args[2])) {
54365a7cce1SAurelien Jarno                 args[3] = tcg_swap_cond(args[3]);
54465a7cce1SAurelien Jarno             }
54565a7cce1SAurelien Jarno             break;
546fa01a208SRichard Henderson         CASE_OP_32_64(movcond):
54724c9ae4eSRichard Henderson             if (swap_commutative(-1, &args[1], &args[2])) {
54824c9ae4eSRichard Henderson                 args[5] = tcg_swap_cond(args[5]);
549fa01a208SRichard Henderson             }
5505d8f5363SRichard Henderson             /* For movcond, we canonicalize the "false" input reg to match
5515d8f5363SRichard Henderson                the destination reg so that the tcg backend can implement
5525d8f5363SRichard Henderson                a "move if true" operation.  */
55324c9ae4eSRichard Henderson             if (swap_commutative(args[0], &args[4], &args[3])) {
55424c9ae4eSRichard Henderson                 args[5] = tcg_invert_cond(args[5]);
5555d8f5363SRichard Henderson             }
5561e484e61SRichard Henderson             break;
5571e484e61SRichard Henderson         case INDEX_op_add2_i32:
5581e484e61SRichard Henderson             swap_commutative(args[0], &args[2], &args[4]);
5591e484e61SRichard Henderson             swap_commutative(args[1], &args[3], &args[5]);
5601e484e61SRichard Henderson             break;
5611414968aSRichard Henderson         case INDEX_op_mulu2_i32:
5621414968aSRichard Henderson             swap_commutative(args[0], &args[2], &args[3]);
5631414968aSRichard Henderson             break;
5640bfcb865SRichard Henderson         case INDEX_op_brcond2_i32:
5650bfcb865SRichard Henderson             if (swap_commutative2(&args[0], &args[2])) {
5660bfcb865SRichard Henderson                 args[4] = tcg_swap_cond(args[4]);
5670bfcb865SRichard Henderson             }
5680bfcb865SRichard Henderson             break;
5690bfcb865SRichard Henderson         case INDEX_op_setcond2_i32:
5700bfcb865SRichard Henderson             if (swap_commutative2(&args[1], &args[3])) {
5710bfcb865SRichard Henderson                 args[5] = tcg_swap_cond(args[5]);
5720bfcb865SRichard Henderson             }
5730bfcb865SRichard Henderson             break;
57453108fb5SKirill Batuzov         default:
57553108fb5SKirill Batuzov             break;
57653108fb5SKirill Batuzov         }
57753108fb5SKirill Batuzov 
57801ee5282SAurelien Jarno         /* Simplify expressions for "shift/rot r, 0, a => movi r, 0" */
57901ee5282SAurelien Jarno         switch (op) {
58001ee5282SAurelien Jarno         CASE_OP_32_64(shl):
58101ee5282SAurelien Jarno         CASE_OP_32_64(shr):
58201ee5282SAurelien Jarno         CASE_OP_32_64(sar):
58301ee5282SAurelien Jarno         CASE_OP_32_64(rotl):
58401ee5282SAurelien Jarno         CASE_OP_32_64(rotr):
58501ee5282SAurelien Jarno             if (temps[args[1]].state == TCG_TEMP_CONST
58601ee5282SAurelien Jarno                 && temps[args[1]].val == 0) {
58792414b31SEvgeny Voevodin                 s->gen_opc_buf[op_index] = op_to_movi(op);
588e590d4e6SAurelien Jarno                 tcg_opt_gen_movi(gen_args, args[0], 0);
58901ee5282SAurelien Jarno                 args += 3;
59001ee5282SAurelien Jarno                 gen_args += 2;
59101ee5282SAurelien Jarno                 continue;
59201ee5282SAurelien Jarno             }
59301ee5282SAurelien Jarno             break;
59401ee5282SAurelien Jarno         default:
59501ee5282SAurelien Jarno             break;
59601ee5282SAurelien Jarno         }
59701ee5282SAurelien Jarno 
59856e49438SAurelien Jarno         /* Simplify expression for "op r, a, 0 => mov r, a" cases */
59953108fb5SKirill Batuzov         switch (op) {
60053108fb5SKirill Batuzov         CASE_OP_32_64(add):
60153108fb5SKirill Batuzov         CASE_OP_32_64(sub):
60255c0975cSKirill Batuzov         CASE_OP_32_64(shl):
60355c0975cSKirill Batuzov         CASE_OP_32_64(shr):
60455c0975cSKirill Batuzov         CASE_OP_32_64(sar):
60525c4d9ccSRichard Henderson         CASE_OP_32_64(rotl):
60625c4d9ccSRichard Henderson         CASE_OP_32_64(rotr):
60738ee188bSAurelien Jarno         CASE_OP_32_64(or):
60838ee188bSAurelien Jarno         CASE_OP_32_64(xor):
60953108fb5SKirill Batuzov             if (temps[args[1]].state == TCG_TEMP_CONST) {
61053108fb5SKirill Batuzov                 /* Proceed with possible constant folding. */
61153108fb5SKirill Batuzov                 break;
61253108fb5SKirill Batuzov             }
61353108fb5SKirill Batuzov             if (temps[args[2]].state == TCG_TEMP_CONST
61453108fb5SKirill Batuzov                 && temps[args[2]].val == 0) {
615e590d4e6SAurelien Jarno                 if (temps_are_copies(args[0], args[1])) {
61692414b31SEvgeny Voevodin                     s->gen_opc_buf[op_index] = INDEX_op_nop;
61753108fb5SKirill Batuzov                 } else {
61892414b31SEvgeny Voevodin                     s->gen_opc_buf[op_index] = op_to_mov(op);
619b80bb016SAurelien Jarno                     tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
62053108fb5SKirill Batuzov                     gen_args += 2;
62153108fb5SKirill Batuzov                 }
622fedc0da2SAurelien Jarno                 args += 3;
62353108fb5SKirill Batuzov                 continue;
62453108fb5SKirill Batuzov             }
62553108fb5SKirill Batuzov             break;
62656e49438SAurelien Jarno         default:
62756e49438SAurelien Jarno             break;
62856e49438SAurelien Jarno         }
62956e49438SAurelien Jarno 
630*3a9d8b17SPaolo Bonzini         /* Simplify using known-zero bits */
631*3a9d8b17SPaolo Bonzini         mask = -1;
632*3a9d8b17SPaolo Bonzini         switch (op) {
633*3a9d8b17SPaolo Bonzini         CASE_OP_32_64(ext8s):
634*3a9d8b17SPaolo Bonzini             if ((temps[args[1]].mask & 0x80) != 0) {
635*3a9d8b17SPaolo Bonzini                 break;
636*3a9d8b17SPaolo Bonzini             }
637*3a9d8b17SPaolo Bonzini         CASE_OP_32_64(ext8u):
638*3a9d8b17SPaolo Bonzini             mask = 0xff;
639*3a9d8b17SPaolo Bonzini             goto and_const;
640*3a9d8b17SPaolo Bonzini         CASE_OP_32_64(ext16s):
641*3a9d8b17SPaolo Bonzini             if ((temps[args[1]].mask & 0x8000) != 0) {
642*3a9d8b17SPaolo Bonzini                 break;
643*3a9d8b17SPaolo Bonzini             }
644*3a9d8b17SPaolo Bonzini         CASE_OP_32_64(ext16u):
645*3a9d8b17SPaolo Bonzini             mask = 0xffff;
646*3a9d8b17SPaolo Bonzini             goto and_const;
647*3a9d8b17SPaolo Bonzini         case INDEX_op_ext32s_i64:
648*3a9d8b17SPaolo Bonzini             if ((temps[args[1]].mask & 0x80000000) != 0) {
649*3a9d8b17SPaolo Bonzini                 break;
650*3a9d8b17SPaolo Bonzini             }
651*3a9d8b17SPaolo Bonzini         case INDEX_op_ext32u_i64:
652*3a9d8b17SPaolo Bonzini             mask = 0xffffffffU;
653*3a9d8b17SPaolo Bonzini             goto and_const;
654*3a9d8b17SPaolo Bonzini 
655*3a9d8b17SPaolo Bonzini         CASE_OP_32_64(and):
656*3a9d8b17SPaolo Bonzini             mask = temps[args[2]].mask;
657*3a9d8b17SPaolo Bonzini             if (temps[args[2]].state == TCG_TEMP_CONST) {
658*3a9d8b17SPaolo Bonzini         and_const:
659*3a9d8b17SPaolo Bonzini                 ;
660*3a9d8b17SPaolo Bonzini             }
661*3a9d8b17SPaolo Bonzini             mask = temps[args[1]].mask & mask;
662*3a9d8b17SPaolo Bonzini             break;
663*3a9d8b17SPaolo Bonzini 
664*3a9d8b17SPaolo Bonzini         CASE_OP_32_64(sar):
665*3a9d8b17SPaolo Bonzini             if (temps[args[2]].state == TCG_TEMP_CONST) {
666*3a9d8b17SPaolo Bonzini                 mask = ((tcg_target_long)temps[args[1]].mask
667*3a9d8b17SPaolo Bonzini                         >> temps[args[2]].val);
668*3a9d8b17SPaolo Bonzini             }
669*3a9d8b17SPaolo Bonzini             break;
670*3a9d8b17SPaolo Bonzini 
671*3a9d8b17SPaolo Bonzini         CASE_OP_32_64(shr):
672*3a9d8b17SPaolo Bonzini             if (temps[args[2]].state == TCG_TEMP_CONST) {
673*3a9d8b17SPaolo Bonzini                 mask = temps[args[1]].mask >> temps[args[2]].val;
674*3a9d8b17SPaolo Bonzini             }
675*3a9d8b17SPaolo Bonzini             break;
676*3a9d8b17SPaolo Bonzini 
677*3a9d8b17SPaolo Bonzini         CASE_OP_32_64(shl):
678*3a9d8b17SPaolo Bonzini             if (temps[args[2]].state == TCG_TEMP_CONST) {
679*3a9d8b17SPaolo Bonzini                 mask = temps[args[1]].mask << temps[args[2]].val;
680*3a9d8b17SPaolo Bonzini             }
681*3a9d8b17SPaolo Bonzini             break;
682*3a9d8b17SPaolo Bonzini 
683*3a9d8b17SPaolo Bonzini         CASE_OP_32_64(neg):
684*3a9d8b17SPaolo Bonzini             /* Set to 1 all bits to the left of the rightmost.  */
685*3a9d8b17SPaolo Bonzini             mask = -(temps[args[1]].mask & -temps[args[1]].mask);
686*3a9d8b17SPaolo Bonzini             break;
687*3a9d8b17SPaolo Bonzini 
688*3a9d8b17SPaolo Bonzini         CASE_OP_32_64(deposit):
689*3a9d8b17SPaolo Bonzini             tmp = ((1ull << args[4]) - 1);
690*3a9d8b17SPaolo Bonzini             mask = ((temps[args[1]].mask & ~(tmp << args[3]))
691*3a9d8b17SPaolo Bonzini                     | ((temps[args[2]].mask & tmp) << args[3]));
692*3a9d8b17SPaolo Bonzini             break;
693*3a9d8b17SPaolo Bonzini 
694*3a9d8b17SPaolo Bonzini         CASE_OP_32_64(or):
695*3a9d8b17SPaolo Bonzini         CASE_OP_32_64(xor):
696*3a9d8b17SPaolo Bonzini             mask = temps[args[1]].mask | temps[args[2]].mask;
697*3a9d8b17SPaolo Bonzini             break;
698*3a9d8b17SPaolo Bonzini 
699*3a9d8b17SPaolo Bonzini         CASE_OP_32_64(setcond):
700*3a9d8b17SPaolo Bonzini             mask = 1;
701*3a9d8b17SPaolo Bonzini             break;
702*3a9d8b17SPaolo Bonzini 
703*3a9d8b17SPaolo Bonzini         CASE_OP_32_64(movcond):
704*3a9d8b17SPaolo Bonzini             mask = temps[args[3]].mask | temps[args[4]].mask;
705*3a9d8b17SPaolo Bonzini             break;
706*3a9d8b17SPaolo Bonzini 
707*3a9d8b17SPaolo Bonzini         default:
708*3a9d8b17SPaolo Bonzini             break;
709*3a9d8b17SPaolo Bonzini         }
710*3a9d8b17SPaolo Bonzini 
71156e49438SAurelien Jarno         /* Simplify expression for "op r, a, 0 => movi r, 0" cases */
71256e49438SAurelien Jarno         switch (op) {
71361251c0cSAurelien Jarno         CASE_OP_32_64(and):
71453108fb5SKirill Batuzov         CASE_OP_32_64(mul):
71553108fb5SKirill Batuzov             if ((temps[args[2]].state == TCG_TEMP_CONST
71653108fb5SKirill Batuzov                 && temps[args[2]].val == 0)) {
71792414b31SEvgeny Voevodin                 s->gen_opc_buf[op_index] = op_to_movi(op);
718e590d4e6SAurelien Jarno                 tcg_opt_gen_movi(gen_args, args[0], 0);
71953108fb5SKirill Batuzov                 args += 3;
72053108fb5SKirill Batuzov                 gen_args += 2;
72153108fb5SKirill Batuzov                 continue;
72253108fb5SKirill Batuzov             }
72353108fb5SKirill Batuzov             break;
72456e49438SAurelien Jarno         default:
72556e49438SAurelien Jarno             break;
72656e49438SAurelien Jarno         }
72756e49438SAurelien Jarno 
72856e49438SAurelien Jarno         /* Simplify expression for "op r, a, a => mov r, a" cases */
72956e49438SAurelien Jarno         switch (op) {
7309a81090bSKirill Batuzov         CASE_OP_32_64(or):
7319a81090bSKirill Batuzov         CASE_OP_32_64(and):
7320aba1c73SAurelien Jarno             if (temps_are_copies(args[1], args[2])) {
733e590d4e6SAurelien Jarno                 if (temps_are_copies(args[0], args[1])) {
73492414b31SEvgeny Voevodin                     s->gen_opc_buf[op_index] = INDEX_op_nop;
7359a81090bSKirill Batuzov                 } else {
73692414b31SEvgeny Voevodin                     s->gen_opc_buf[op_index] = op_to_mov(op);
737b80bb016SAurelien Jarno                     tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
7389a81090bSKirill Batuzov                     gen_args += 2;
7399a81090bSKirill Batuzov                 }
740fedc0da2SAurelien Jarno                 args += 3;
7419a81090bSKirill Batuzov                 continue;
7429a81090bSKirill Batuzov             }
7439a81090bSKirill Batuzov             break;
744fe0de7aaSBlue Swirl         default:
745fe0de7aaSBlue Swirl             break;
74653108fb5SKirill Batuzov         }
74753108fb5SKirill Batuzov 
7483c94193eSAurelien Jarno         /* Simplify expression for "op r, a, a => movi r, 0" cases */
7493c94193eSAurelien Jarno         switch (op) {
7503c94193eSAurelien Jarno         CASE_OP_32_64(sub):
7513c94193eSAurelien Jarno         CASE_OP_32_64(xor):
7523c94193eSAurelien Jarno             if (temps_are_copies(args[1], args[2])) {
75392414b31SEvgeny Voevodin                 s->gen_opc_buf[op_index] = op_to_movi(op);
7543c94193eSAurelien Jarno                 tcg_opt_gen_movi(gen_args, args[0], 0);
7553c94193eSAurelien Jarno                 gen_args += 2;
7563c94193eSAurelien Jarno                 args += 3;
7573c94193eSAurelien Jarno                 continue;
7583c94193eSAurelien Jarno             }
7593c94193eSAurelien Jarno             break;
7603c94193eSAurelien Jarno         default:
7613c94193eSAurelien Jarno             break;
7623c94193eSAurelien Jarno         }
7633c94193eSAurelien Jarno 
76422613af4SKirill Batuzov         /* Propagate constants through copy operations and do constant
76522613af4SKirill Batuzov            folding.  Constants will be substituted to arguments by register
76622613af4SKirill Batuzov            allocator where needed and possible.  Also detect copies. */
7678f2e8c07SKirill Batuzov         switch (op) {
76822613af4SKirill Batuzov         CASE_OP_32_64(mov):
769e590d4e6SAurelien Jarno             if (temps_are_copies(args[0], args[1])) {
77022613af4SKirill Batuzov                 args += 2;
77192414b31SEvgeny Voevodin                 s->gen_opc_buf[op_index] = INDEX_op_nop;
77222613af4SKirill Batuzov                 break;
77322613af4SKirill Batuzov             }
77422613af4SKirill Batuzov             if (temps[args[1]].state != TCG_TEMP_CONST) {
775b80bb016SAurelien Jarno                 tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
77622613af4SKirill Batuzov                 gen_args += 2;
77722613af4SKirill Batuzov                 args += 2;
77822613af4SKirill Batuzov                 break;
77922613af4SKirill Batuzov             }
78022613af4SKirill Batuzov             /* Source argument is constant.  Rewrite the operation and
78122613af4SKirill Batuzov                let movi case handle it. */
78222613af4SKirill Batuzov             op = op_to_movi(op);
78392414b31SEvgeny Voevodin             s->gen_opc_buf[op_index] = op;
78422613af4SKirill Batuzov             args[1] = temps[args[1]].val;
78522613af4SKirill Batuzov             /* fallthrough */
78622613af4SKirill Batuzov         CASE_OP_32_64(movi):
787e590d4e6SAurelien Jarno             tcg_opt_gen_movi(gen_args, args[0], args[1]);
78822613af4SKirill Batuzov             gen_args += 2;
78922613af4SKirill Batuzov             args += 2;
79022613af4SKirill Batuzov             break;
7916e14e91bSRichard Henderson 
792a640f031SKirill Batuzov         CASE_OP_32_64(not):
793cb25c80aSRichard Henderson         CASE_OP_32_64(neg):
79425c4d9ccSRichard Henderson         CASE_OP_32_64(ext8s):
79525c4d9ccSRichard Henderson         CASE_OP_32_64(ext8u):
79625c4d9ccSRichard Henderson         CASE_OP_32_64(ext16s):
79725c4d9ccSRichard Henderson         CASE_OP_32_64(ext16u):
798a640f031SKirill Batuzov         case INDEX_op_ext32s_i64:
799a640f031SKirill Batuzov         case INDEX_op_ext32u_i64:
800a640f031SKirill Batuzov             if (temps[args[1]].state == TCG_TEMP_CONST) {
80192414b31SEvgeny Voevodin                 s->gen_opc_buf[op_index] = op_to_movi(op);
802a640f031SKirill Batuzov                 tmp = do_constant_folding(op, temps[args[1]].val, 0);
803e590d4e6SAurelien Jarno                 tcg_opt_gen_movi(gen_args, args[0], tmp);
804a640f031SKirill Batuzov                 gen_args += 2;
805a640f031SKirill Batuzov                 args += 2;
806a640f031SKirill Batuzov                 break;
8076e14e91bSRichard Henderson             }
8086e14e91bSRichard Henderson             goto do_default;
8096e14e91bSRichard Henderson 
81053108fb5SKirill Batuzov         CASE_OP_32_64(add):
81153108fb5SKirill Batuzov         CASE_OP_32_64(sub):
81253108fb5SKirill Batuzov         CASE_OP_32_64(mul):
8139a81090bSKirill Batuzov         CASE_OP_32_64(or):
8149a81090bSKirill Batuzov         CASE_OP_32_64(and):
8159a81090bSKirill Batuzov         CASE_OP_32_64(xor):
81655c0975cSKirill Batuzov         CASE_OP_32_64(shl):
81755c0975cSKirill Batuzov         CASE_OP_32_64(shr):
81855c0975cSKirill Batuzov         CASE_OP_32_64(sar):
81925c4d9ccSRichard Henderson         CASE_OP_32_64(rotl):
82025c4d9ccSRichard Henderson         CASE_OP_32_64(rotr):
821cb25c80aSRichard Henderson         CASE_OP_32_64(andc):
822cb25c80aSRichard Henderson         CASE_OP_32_64(orc):
823cb25c80aSRichard Henderson         CASE_OP_32_64(eqv):
824cb25c80aSRichard Henderson         CASE_OP_32_64(nand):
825cb25c80aSRichard Henderson         CASE_OP_32_64(nor):
82653108fb5SKirill Batuzov             if (temps[args[1]].state == TCG_TEMP_CONST
82753108fb5SKirill Batuzov                 && temps[args[2]].state == TCG_TEMP_CONST) {
82892414b31SEvgeny Voevodin                 s->gen_opc_buf[op_index] = op_to_movi(op);
82953108fb5SKirill Batuzov                 tmp = do_constant_folding(op, temps[args[1]].val,
83053108fb5SKirill Batuzov                                           temps[args[2]].val);
831e590d4e6SAurelien Jarno                 tcg_opt_gen_movi(gen_args, args[0], tmp);
83253108fb5SKirill Batuzov                 gen_args += 2;
83353108fb5SKirill Batuzov                 args += 3;
83453108fb5SKirill Batuzov                 break;
8356e14e91bSRichard Henderson             }
8366e14e91bSRichard Henderson             goto do_default;
8376e14e91bSRichard Henderson 
8387ef55fc9SAurelien Jarno         CASE_OP_32_64(deposit):
8397ef55fc9SAurelien Jarno             if (temps[args[1]].state == TCG_TEMP_CONST
8407ef55fc9SAurelien Jarno                 && temps[args[2]].state == TCG_TEMP_CONST) {
84192414b31SEvgeny Voevodin                 s->gen_opc_buf[op_index] = op_to_movi(op);
8427ef55fc9SAurelien Jarno                 tmp = ((1ull << args[4]) - 1);
8437ef55fc9SAurelien Jarno                 tmp = (temps[args[1]].val & ~(tmp << args[3]))
8447ef55fc9SAurelien Jarno                       | ((temps[args[2]].val & tmp) << args[3]);
8457ef55fc9SAurelien Jarno                 tcg_opt_gen_movi(gen_args, args[0], tmp);
8467ef55fc9SAurelien Jarno                 gen_args += 2;
8477ef55fc9SAurelien Jarno                 args += 5;
8487ef55fc9SAurelien Jarno                 break;
8496e14e91bSRichard Henderson             }
8506e14e91bSRichard Henderson             goto do_default;
8516e14e91bSRichard Henderson 
852f8dd19e5SAurelien Jarno         CASE_OP_32_64(setcond):
853b336ceb6SAurelien Jarno             tmp = do_constant_folding_cond(op, args[1], args[2], args[3]);
854b336ceb6SAurelien Jarno             if (tmp != 2) {
85592414b31SEvgeny Voevodin                 s->gen_opc_buf[op_index] = op_to_movi(op);
856e590d4e6SAurelien Jarno                 tcg_opt_gen_movi(gen_args, args[0], tmp);
857f8dd19e5SAurelien Jarno                 gen_args += 2;
858f8dd19e5SAurelien Jarno                 args += 4;
859f8dd19e5SAurelien Jarno                 break;
8606e14e91bSRichard Henderson             }
8616e14e91bSRichard Henderson             goto do_default;
8626e14e91bSRichard Henderson 
863fbeaa26cSAurelien Jarno         CASE_OP_32_64(brcond):
864b336ceb6SAurelien Jarno             tmp = do_constant_folding_cond(op, args[0], args[1], args[2]);
865b336ceb6SAurelien Jarno             if (tmp != 2) {
866b336ceb6SAurelien Jarno                 if (tmp) {
867d193a14aSPaolo Bonzini                     reset_all_temps(nb_temps);
86892414b31SEvgeny Voevodin                     s->gen_opc_buf[op_index] = INDEX_op_br;
869fbeaa26cSAurelien Jarno                     gen_args[0] = args[3];
870fbeaa26cSAurelien Jarno                     gen_args += 1;
871fbeaa26cSAurelien Jarno                 } else {
87292414b31SEvgeny Voevodin                     s->gen_opc_buf[op_index] = INDEX_op_nop;
873fbeaa26cSAurelien Jarno                 }
874fbeaa26cSAurelien Jarno                 args += 4;
875fbeaa26cSAurelien Jarno                 break;
8766e14e91bSRichard Henderson             }
8776e14e91bSRichard Henderson             goto do_default;
8786e14e91bSRichard Henderson 
879fa01a208SRichard Henderson         CASE_OP_32_64(movcond):
880b336ceb6SAurelien Jarno             tmp = do_constant_folding_cond(op, args[1], args[2], args[5]);
881b336ceb6SAurelien Jarno             if (tmp != 2) {
882e590d4e6SAurelien Jarno                 if (temps_are_copies(args[0], args[4-tmp])) {
88392414b31SEvgeny Voevodin                     s->gen_opc_buf[op_index] = INDEX_op_nop;
884fa01a208SRichard Henderson                 } else if (temps[args[4-tmp]].state == TCG_TEMP_CONST) {
88592414b31SEvgeny Voevodin                     s->gen_opc_buf[op_index] = op_to_movi(op);
886e590d4e6SAurelien Jarno                     tcg_opt_gen_movi(gen_args, args[0], temps[args[4-tmp]].val);
887fa01a208SRichard Henderson                     gen_args += 2;
888fa01a208SRichard Henderson                 } else {
88992414b31SEvgeny Voevodin                     s->gen_opc_buf[op_index] = op_to_mov(op);
890e590d4e6SAurelien Jarno                     tcg_opt_gen_mov(s, gen_args, args[0], args[4-tmp]);
891fa01a208SRichard Henderson                     gen_args += 2;
892fa01a208SRichard Henderson                 }
893fa01a208SRichard Henderson                 args += 6;
894fa01a208SRichard Henderson                 break;
8956e14e91bSRichard Henderson             }
8966e14e91bSRichard Henderson             goto do_default;
8976e14e91bSRichard Henderson 
898212c328dSRichard Henderson         case INDEX_op_add2_i32:
899212c328dSRichard Henderson         case INDEX_op_sub2_i32:
900212c328dSRichard Henderson             if (temps[args[2]].state == TCG_TEMP_CONST
901212c328dSRichard Henderson                 && temps[args[3]].state == TCG_TEMP_CONST
902212c328dSRichard Henderson                 && temps[args[4]].state == TCG_TEMP_CONST
903212c328dSRichard Henderson                 && temps[args[5]].state == TCG_TEMP_CONST) {
904212c328dSRichard Henderson                 uint32_t al = temps[args[2]].val;
905212c328dSRichard Henderson                 uint32_t ah = temps[args[3]].val;
906212c328dSRichard Henderson                 uint32_t bl = temps[args[4]].val;
907212c328dSRichard Henderson                 uint32_t bh = temps[args[5]].val;
908212c328dSRichard Henderson                 uint64_t a = ((uint64_t)ah << 32) | al;
909212c328dSRichard Henderson                 uint64_t b = ((uint64_t)bh << 32) | bl;
910212c328dSRichard Henderson                 TCGArg rl, rh;
911212c328dSRichard Henderson 
912212c328dSRichard Henderson                 if (op == INDEX_op_add2_i32) {
913212c328dSRichard Henderson                     a += b;
914212c328dSRichard Henderson                 } else {
915212c328dSRichard Henderson                     a -= b;
916212c328dSRichard Henderson                 }
917212c328dSRichard Henderson 
918212c328dSRichard Henderson                 /* We emit the extra nop when we emit the add2/sub2.  */
91992414b31SEvgeny Voevodin                 assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
920212c328dSRichard Henderson 
921212c328dSRichard Henderson                 rl = args[0];
922212c328dSRichard Henderson                 rh = args[1];
92392414b31SEvgeny Voevodin                 s->gen_opc_buf[op_index] = INDEX_op_movi_i32;
92492414b31SEvgeny Voevodin                 s->gen_opc_buf[++op_index] = INDEX_op_movi_i32;
925212c328dSRichard Henderson                 tcg_opt_gen_movi(&gen_args[0], rl, (uint32_t)a);
926212c328dSRichard Henderson                 tcg_opt_gen_movi(&gen_args[2], rh, (uint32_t)(a >> 32));
927212c328dSRichard Henderson                 gen_args += 4;
928212c328dSRichard Henderson                 args += 6;
929212c328dSRichard Henderson                 break;
930212c328dSRichard Henderson             }
931212c328dSRichard Henderson             goto do_default;
932212c328dSRichard Henderson 
9331414968aSRichard Henderson         case INDEX_op_mulu2_i32:
9341414968aSRichard Henderson             if (temps[args[2]].state == TCG_TEMP_CONST
9351414968aSRichard Henderson                 && temps[args[3]].state == TCG_TEMP_CONST) {
9361414968aSRichard Henderson                 uint32_t a = temps[args[2]].val;
9371414968aSRichard Henderson                 uint32_t b = temps[args[3]].val;
9381414968aSRichard Henderson                 uint64_t r = (uint64_t)a * b;
9391414968aSRichard Henderson                 TCGArg rl, rh;
9401414968aSRichard Henderson 
9411414968aSRichard Henderson                 /* We emit the extra nop when we emit the mulu2.  */
94292414b31SEvgeny Voevodin                 assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
9431414968aSRichard Henderson 
9441414968aSRichard Henderson                 rl = args[0];
9451414968aSRichard Henderson                 rh = args[1];
94692414b31SEvgeny Voevodin                 s->gen_opc_buf[op_index] = INDEX_op_movi_i32;
94792414b31SEvgeny Voevodin                 s->gen_opc_buf[++op_index] = INDEX_op_movi_i32;
9481414968aSRichard Henderson                 tcg_opt_gen_movi(&gen_args[0], rl, (uint32_t)r);
9491414968aSRichard Henderson                 tcg_opt_gen_movi(&gen_args[2], rh, (uint32_t)(r >> 32));
9501414968aSRichard Henderson                 gen_args += 4;
9511414968aSRichard Henderson                 args += 4;
9521414968aSRichard Henderson                 break;
9531414968aSRichard Henderson             }
9541414968aSRichard Henderson             goto do_default;
9551414968aSRichard Henderson 
956bc1473efSRichard Henderson         case INDEX_op_brcond2_i32:
9576c4382f8SRichard Henderson             tmp = do_constant_folding_cond2(&args[0], &args[2], args[4]);
9586c4382f8SRichard Henderson             if (tmp != 2) {
9596c4382f8SRichard Henderson                 if (tmp) {
960d193a14aSPaolo Bonzini                     reset_all_temps(nb_temps);
96192414b31SEvgeny Voevodin                     s->gen_opc_buf[op_index] = INDEX_op_br;
9626c4382f8SRichard Henderson                     gen_args[0] = args[5];
9636c4382f8SRichard Henderson                     gen_args += 1;
9646c4382f8SRichard Henderson                 } else {
96592414b31SEvgeny Voevodin                     s->gen_opc_buf[op_index] = INDEX_op_nop;
9666c4382f8SRichard Henderson                 }
9676c4382f8SRichard Henderson             } else if ((args[4] == TCG_COND_LT || args[4] == TCG_COND_GE)
968bc1473efSRichard Henderson                        && temps[args[2]].state == TCG_TEMP_CONST
969bc1473efSRichard Henderson                        && temps[args[3]].state == TCG_TEMP_CONST
970bc1473efSRichard Henderson                        && temps[args[2]].val == 0
971bc1473efSRichard Henderson                        && temps[args[3]].val == 0) {
9726c4382f8SRichard Henderson                 /* Simplify LT/GE comparisons vs zero to a single compare
9736c4382f8SRichard Henderson                    vs the high word of the input.  */
974d193a14aSPaolo Bonzini                 reset_all_temps(nb_temps);
97592414b31SEvgeny Voevodin                 s->gen_opc_buf[op_index] = INDEX_op_brcond_i32;
976bc1473efSRichard Henderson                 gen_args[0] = args[1];
977bc1473efSRichard Henderson                 gen_args[1] = args[3];
978bc1473efSRichard Henderson                 gen_args[2] = args[4];
979bc1473efSRichard Henderson                 gen_args[3] = args[5];
980bc1473efSRichard Henderson                 gen_args += 4;
9816c4382f8SRichard Henderson             } else {
982bc1473efSRichard Henderson                 goto do_default;
9836c4382f8SRichard Henderson             }
9846c4382f8SRichard Henderson             args += 6;
9856c4382f8SRichard Henderson             break;
986bc1473efSRichard Henderson 
987bc1473efSRichard Henderson         case INDEX_op_setcond2_i32:
9886c4382f8SRichard Henderson             tmp = do_constant_folding_cond2(&args[1], &args[3], args[5]);
9896c4382f8SRichard Henderson             if (tmp != 2) {
99092414b31SEvgeny Voevodin                 s->gen_opc_buf[op_index] = INDEX_op_movi_i32;
9916c4382f8SRichard Henderson                 tcg_opt_gen_movi(gen_args, args[0], tmp);
9926c4382f8SRichard Henderson                 gen_args += 2;
9936c4382f8SRichard Henderson             } else if ((args[5] == TCG_COND_LT || args[5] == TCG_COND_GE)
994bc1473efSRichard Henderson                        && temps[args[3]].state == TCG_TEMP_CONST
995bc1473efSRichard Henderson                        && temps[args[4]].state == TCG_TEMP_CONST
996bc1473efSRichard Henderson                        && temps[args[3]].val == 0
997bc1473efSRichard Henderson                        && temps[args[4]].val == 0) {
9986c4382f8SRichard Henderson                 /* Simplify LT/GE comparisons vs zero to a single compare
9996c4382f8SRichard Henderson                    vs the high word of the input.  */
100092414b31SEvgeny Voevodin                 s->gen_opc_buf[op_index] = INDEX_op_setcond_i32;
1001bc1473efSRichard Henderson                 gen_args[0] = args[0];
1002bc1473efSRichard Henderson                 gen_args[1] = args[2];
1003bc1473efSRichard Henderson                 gen_args[2] = args[4];
1004bc1473efSRichard Henderson                 gen_args[3] = args[5];
1005bc1473efSRichard Henderson                 gen_args += 4;
10066c4382f8SRichard Henderson             } else {
10076c4382f8SRichard Henderson                 goto do_default;
10086c4382f8SRichard Henderson             }
1009bc1473efSRichard Henderson             args += 6;
1010bc1473efSRichard Henderson             break;
1011bc1473efSRichard Henderson 
10128f2e8c07SKirill Batuzov         case INDEX_op_call:
101322613af4SKirill Batuzov             nb_call_args = (args[0] >> 16) + (args[0] & 0xffff);
101478505279SAurelien Jarno             if (!(args[nb_call_args + 1] & (TCG_CALL_NO_READ_GLOBALS |
101578505279SAurelien Jarno                                             TCG_CALL_NO_WRITE_GLOBALS))) {
101622613af4SKirill Batuzov                 for (i = 0; i < nb_globals; i++) {
1017e590d4e6SAurelien Jarno                     reset_temp(i);
101822613af4SKirill Batuzov                 }
101922613af4SKirill Batuzov             }
102022613af4SKirill Batuzov             for (i = 0; i < (args[0] >> 16); i++) {
1021e590d4e6SAurelien Jarno                 reset_temp(args[i + 1]);
102222613af4SKirill Batuzov             }
102322613af4SKirill Batuzov             i = nb_call_args + 3;
10248f2e8c07SKirill Batuzov             while (i) {
10258f2e8c07SKirill Batuzov                 *gen_args = *args;
10268f2e8c07SKirill Batuzov                 args++;
10278f2e8c07SKirill Batuzov                 gen_args++;
10288f2e8c07SKirill Batuzov                 i--;
10298f2e8c07SKirill Batuzov             }
10308f2e8c07SKirill Batuzov             break;
10316e14e91bSRichard Henderson 
10328f2e8c07SKirill Batuzov         default:
10336e14e91bSRichard Henderson         do_default:
10346e14e91bSRichard Henderson             /* Default case: we know nothing about operation (or were unable
10356e14e91bSRichard Henderson                to compute the operation result) so no propagation is done.
10366e14e91bSRichard Henderson                We trash everything if the operation is the end of a basic
1037*3a9d8b17SPaolo Bonzini                block, otherwise we only trash the output args.  "mask" is
1038*3a9d8b17SPaolo Bonzini                the non-zero bits mask for the first output arg.  */
1039a2550660SAurelien Jarno             if (def->flags & TCG_OPF_BB_END) {
1040d193a14aSPaolo Bonzini                 reset_all_temps(nb_temps);
1041a2550660SAurelien Jarno             } else {
104222613af4SKirill Batuzov                 for (i = 0; i < def->nb_oargs; i++) {
1043e590d4e6SAurelien Jarno                     reset_temp(args[i]);
104422613af4SKirill Batuzov                 }
1045a2550660SAurelien Jarno             }
10468f2e8c07SKirill Batuzov             for (i = 0; i < def->nb_args; i++) {
10478f2e8c07SKirill Batuzov                 gen_args[i] = args[i];
10488f2e8c07SKirill Batuzov             }
10498f2e8c07SKirill Batuzov             args += def->nb_args;
10508f2e8c07SKirill Batuzov             gen_args += def->nb_args;
10518f2e8c07SKirill Batuzov             break;
10528f2e8c07SKirill Batuzov         }
10538f2e8c07SKirill Batuzov     }
10548f2e8c07SKirill Batuzov 
10558f2e8c07SKirill Batuzov     return gen_args;
10568f2e8c07SKirill Batuzov }
10578f2e8c07SKirill Batuzov 
10588f2e8c07SKirill Batuzov TCGArg *tcg_optimize(TCGContext *s, uint16_t *tcg_opc_ptr,
10598f2e8c07SKirill Batuzov         TCGArg *args, TCGOpDef *tcg_op_defs)
10608f2e8c07SKirill Batuzov {
10618f2e8c07SKirill Batuzov     TCGArg *res;
10628f2e8c07SKirill Batuzov     res = tcg_constant_folding(s, tcg_opc_ptr, args, tcg_op_defs);
10638f2e8c07SKirill Batuzov     return res;
10648f2e8c07SKirill Batuzov }
1065