xref: /openbmc/qemu/tcg/optimize.c (revision 48b56ce1)
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,
42*48b56ce1SAurelien Jarno     TCG_TEMP_HAS_COPY
4322613af4SKirill Batuzov } tcg_temp_state;
4422613af4SKirill Batuzov 
4522613af4SKirill Batuzov struct tcg_temp_info {
4622613af4SKirill Batuzov     tcg_temp_state state;
4722613af4SKirill Batuzov     uint16_t prev_copy;
4822613af4SKirill Batuzov     uint16_t next_copy;
4922613af4SKirill Batuzov     tcg_target_ulong val;
5022613af4SKirill Batuzov };
5122613af4SKirill Batuzov 
5222613af4SKirill Batuzov static struct tcg_temp_info temps[TCG_MAX_TEMPS];
5322613af4SKirill Batuzov 
54*48b56ce1SAurelien Jarno /* Reset TEMP's state to TCG_TEMP_UNDEF.  If TEMP was a representative of some
5522613af4SKirill Batuzov    class of equivalent temp's, a new representative should be chosen in this
5622613af4SKirill Batuzov    class. */
5722613af4SKirill Batuzov static void reset_temp(TCGArg temp, int nb_temps, int nb_globals)
5822613af4SKirill Batuzov {
5922613af4SKirill Batuzov     int i;
6022613af4SKirill Batuzov     TCGArg new_base = (TCGArg)-1;
6122613af4SKirill Batuzov     if (temps[temp].state == TCG_TEMP_HAS_COPY) {
6222613af4SKirill Batuzov         for (i = temps[temp].next_copy; i != temp; i = temps[i].next_copy) {
6322613af4SKirill Batuzov             if (i >= nb_globals) {
6422613af4SKirill Batuzov                 temps[i].state = TCG_TEMP_HAS_COPY;
6522613af4SKirill Batuzov                 new_base = i;
6622613af4SKirill Batuzov                 break;
6722613af4SKirill Batuzov             }
6822613af4SKirill Batuzov         }
6922613af4SKirill Batuzov         for (i = temps[temp].next_copy; i != temp; i = temps[i].next_copy) {
7022613af4SKirill Batuzov             if (new_base == (TCGArg)-1) {
71*48b56ce1SAurelien Jarno                 temps[i].state = TCG_TEMP_UNDEF;
7222613af4SKirill Batuzov             } else {
7322613af4SKirill Batuzov                 temps[i].val = new_base;
7422613af4SKirill Batuzov             }
7522613af4SKirill Batuzov         }
7622613af4SKirill Batuzov         temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy;
7722613af4SKirill Batuzov         temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy;
7822613af4SKirill Batuzov     } else if (temps[temp].state == TCG_TEMP_COPY) {
7922613af4SKirill Batuzov         temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy;
8022613af4SKirill Batuzov         temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy;
8122613af4SKirill Batuzov         new_base = temps[temp].val;
8222613af4SKirill Batuzov     }
83*48b56ce1SAurelien Jarno     temps[temp].state = TCG_TEMP_UNDEF;
8422613af4SKirill Batuzov     if (new_base != (TCGArg)-1 && temps[new_base].next_copy == new_base) {
85*48b56ce1SAurelien Jarno         temps[new_base].state = TCG_TEMP_UNDEF;
8622613af4SKirill Batuzov     }
8722613af4SKirill Batuzov }
8822613af4SKirill Batuzov 
89fe0de7aaSBlue Swirl static int op_bits(TCGOpcode op)
9022613af4SKirill Batuzov {
918399ad59SRichard Henderson     const TCGOpDef *def = &tcg_op_defs[op];
928399ad59SRichard Henderson     return def->flags & TCG_OPF_64BIT ? 64 : 32;
9322613af4SKirill Batuzov }
9422613af4SKirill Batuzov 
95fe0de7aaSBlue Swirl static TCGOpcode op_to_movi(TCGOpcode op)
9622613af4SKirill Batuzov {
9722613af4SKirill Batuzov     switch (op_bits(op)) {
9822613af4SKirill Batuzov     case 32:
9922613af4SKirill Batuzov         return INDEX_op_movi_i32;
10022613af4SKirill Batuzov     case 64:
10122613af4SKirill Batuzov         return INDEX_op_movi_i64;
10222613af4SKirill Batuzov     default:
10322613af4SKirill Batuzov         fprintf(stderr, "op_to_movi: unexpected return value of "
10422613af4SKirill Batuzov                 "function op_bits.\n");
10522613af4SKirill Batuzov         tcg_abort();
10622613af4SKirill Batuzov     }
10722613af4SKirill Batuzov }
10822613af4SKirill Batuzov 
109d104bebdSAurelien Jarno static void tcg_opt_gen_mov(TCGArg *gen_args, TCGArg dst, TCGArg src,
110d104bebdSAurelien Jarno                             int nb_temps, int nb_globals)
11122613af4SKirill Batuzov {
11222613af4SKirill Batuzov         reset_temp(dst, nb_temps, nb_globals);
11322613af4SKirill Batuzov         assert(temps[src].state != TCG_TEMP_COPY);
114d104bebdSAurelien Jarno         if (src >= nb_globals) {
11522613af4SKirill Batuzov             assert(temps[src].state != TCG_TEMP_CONST);
11622613af4SKirill Batuzov             if (temps[src].state != TCG_TEMP_HAS_COPY) {
11722613af4SKirill Batuzov                 temps[src].state = TCG_TEMP_HAS_COPY;
11822613af4SKirill Batuzov                 temps[src].next_copy = src;
11922613af4SKirill Batuzov                 temps[src].prev_copy = src;
12022613af4SKirill Batuzov             }
12122613af4SKirill Batuzov             temps[dst].state = TCG_TEMP_COPY;
12222613af4SKirill Batuzov             temps[dst].val = src;
12322613af4SKirill Batuzov             temps[dst].next_copy = temps[src].next_copy;
12422613af4SKirill Batuzov             temps[dst].prev_copy = src;
12522613af4SKirill Batuzov             temps[temps[dst].next_copy].prev_copy = dst;
12622613af4SKirill Batuzov             temps[src].next_copy = dst;
12722613af4SKirill Batuzov         }
12822613af4SKirill Batuzov         gen_args[0] = dst;
12922613af4SKirill Batuzov         gen_args[1] = src;
13022613af4SKirill Batuzov }
13122613af4SKirill Batuzov 
13222613af4SKirill Batuzov static void tcg_opt_gen_movi(TCGArg *gen_args, TCGArg dst, TCGArg val,
13322613af4SKirill Batuzov                              int nb_temps, int nb_globals)
13422613af4SKirill Batuzov {
13522613af4SKirill Batuzov         reset_temp(dst, nb_temps, nb_globals);
13622613af4SKirill Batuzov         temps[dst].state = TCG_TEMP_CONST;
13722613af4SKirill Batuzov         temps[dst].val = val;
13822613af4SKirill Batuzov         gen_args[0] = dst;
13922613af4SKirill Batuzov         gen_args[1] = val;
14022613af4SKirill Batuzov }
14122613af4SKirill Batuzov 
142fe0de7aaSBlue Swirl static TCGOpcode op_to_mov(TCGOpcode op)
14353108fb5SKirill Batuzov {
14453108fb5SKirill Batuzov     switch (op_bits(op)) {
14553108fb5SKirill Batuzov     case 32:
14653108fb5SKirill Batuzov         return INDEX_op_mov_i32;
14753108fb5SKirill Batuzov     case 64:
14853108fb5SKirill Batuzov         return INDEX_op_mov_i64;
14953108fb5SKirill Batuzov     default:
15053108fb5SKirill Batuzov         fprintf(stderr, "op_to_mov: unexpected return value of "
15153108fb5SKirill Batuzov                 "function op_bits.\n");
15253108fb5SKirill Batuzov         tcg_abort();
15353108fb5SKirill Batuzov     }
15453108fb5SKirill Batuzov }
15553108fb5SKirill Batuzov 
156fe0de7aaSBlue Swirl static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y)
15753108fb5SKirill Batuzov {
15853108fb5SKirill Batuzov     switch (op) {
15953108fb5SKirill Batuzov     CASE_OP_32_64(add):
16053108fb5SKirill Batuzov         return x + y;
16153108fb5SKirill Batuzov 
16253108fb5SKirill Batuzov     CASE_OP_32_64(sub):
16353108fb5SKirill Batuzov         return x - y;
16453108fb5SKirill Batuzov 
16553108fb5SKirill Batuzov     CASE_OP_32_64(mul):
16653108fb5SKirill Batuzov         return x * y;
16753108fb5SKirill Batuzov 
1689a81090bSKirill Batuzov     CASE_OP_32_64(and):
1699a81090bSKirill Batuzov         return x & y;
1709a81090bSKirill Batuzov 
1719a81090bSKirill Batuzov     CASE_OP_32_64(or):
1729a81090bSKirill Batuzov         return x | y;
1739a81090bSKirill Batuzov 
1749a81090bSKirill Batuzov     CASE_OP_32_64(xor):
1759a81090bSKirill Batuzov         return x ^ y;
1769a81090bSKirill Batuzov 
17755c0975cSKirill Batuzov     case INDEX_op_shl_i32:
17855c0975cSKirill Batuzov         return (uint32_t)x << (uint32_t)y;
17955c0975cSKirill Batuzov 
18055c0975cSKirill Batuzov     case INDEX_op_shl_i64:
18155c0975cSKirill Batuzov         return (uint64_t)x << (uint64_t)y;
18255c0975cSKirill Batuzov 
18355c0975cSKirill Batuzov     case INDEX_op_shr_i32:
18455c0975cSKirill Batuzov         return (uint32_t)x >> (uint32_t)y;
18555c0975cSKirill Batuzov 
18655c0975cSKirill Batuzov     case INDEX_op_shr_i64:
18755c0975cSKirill Batuzov         return (uint64_t)x >> (uint64_t)y;
18855c0975cSKirill Batuzov 
18955c0975cSKirill Batuzov     case INDEX_op_sar_i32:
19055c0975cSKirill Batuzov         return (int32_t)x >> (int32_t)y;
19155c0975cSKirill Batuzov 
19255c0975cSKirill Batuzov     case INDEX_op_sar_i64:
19355c0975cSKirill Batuzov         return (int64_t)x >> (int64_t)y;
19455c0975cSKirill Batuzov 
19555c0975cSKirill Batuzov     case INDEX_op_rotr_i32:
19625c4d9ccSRichard Henderson         x = ((uint32_t)x << (32 - y)) | ((uint32_t)x >> y);
19755c0975cSKirill Batuzov         return x;
19855c0975cSKirill Batuzov 
19955c0975cSKirill Batuzov     case INDEX_op_rotr_i64:
20025c4d9ccSRichard Henderson         x = ((uint64_t)x << (64 - y)) | ((uint64_t)x >> y);
20155c0975cSKirill Batuzov         return x;
20255c0975cSKirill Batuzov 
20355c0975cSKirill Batuzov     case INDEX_op_rotl_i32:
20425c4d9ccSRichard Henderson         x = ((uint32_t)x << y) | ((uint32_t)x >> (32 - y));
20555c0975cSKirill Batuzov         return x;
20655c0975cSKirill Batuzov 
20755c0975cSKirill Batuzov     case INDEX_op_rotl_i64:
20825c4d9ccSRichard Henderson         x = ((uint64_t)x << y) | ((uint64_t)x >> (64 - y));
20955c0975cSKirill Batuzov         return x;
21055c0975cSKirill Batuzov 
21125c4d9ccSRichard Henderson     CASE_OP_32_64(not):
212a640f031SKirill Batuzov         return ~x;
213a640f031SKirill Batuzov 
214cb25c80aSRichard Henderson     CASE_OP_32_64(neg):
215cb25c80aSRichard Henderson         return -x;
216cb25c80aSRichard Henderson 
217cb25c80aSRichard Henderson     CASE_OP_32_64(andc):
218cb25c80aSRichard Henderson         return x & ~y;
219cb25c80aSRichard Henderson 
220cb25c80aSRichard Henderson     CASE_OP_32_64(orc):
221cb25c80aSRichard Henderson         return x | ~y;
222cb25c80aSRichard Henderson 
223cb25c80aSRichard Henderson     CASE_OP_32_64(eqv):
224cb25c80aSRichard Henderson         return ~(x ^ y);
225cb25c80aSRichard Henderson 
226cb25c80aSRichard Henderson     CASE_OP_32_64(nand):
227cb25c80aSRichard Henderson         return ~(x & y);
228cb25c80aSRichard Henderson 
229cb25c80aSRichard Henderson     CASE_OP_32_64(nor):
230cb25c80aSRichard Henderson         return ~(x | y);
231cb25c80aSRichard Henderson 
23225c4d9ccSRichard Henderson     CASE_OP_32_64(ext8s):
233a640f031SKirill Batuzov         return (int8_t)x;
234a640f031SKirill Batuzov 
23525c4d9ccSRichard Henderson     CASE_OP_32_64(ext16s):
236a640f031SKirill Batuzov         return (int16_t)x;
237a640f031SKirill Batuzov 
23825c4d9ccSRichard Henderson     CASE_OP_32_64(ext8u):
239a640f031SKirill Batuzov         return (uint8_t)x;
240a640f031SKirill Batuzov 
24125c4d9ccSRichard Henderson     CASE_OP_32_64(ext16u):
242a640f031SKirill Batuzov         return (uint16_t)x;
243a640f031SKirill Batuzov 
244a640f031SKirill Batuzov     case INDEX_op_ext32s_i64:
245a640f031SKirill Batuzov         return (int32_t)x;
246a640f031SKirill Batuzov 
247a640f031SKirill Batuzov     case INDEX_op_ext32u_i64:
248a640f031SKirill Batuzov         return (uint32_t)x;
249a640f031SKirill Batuzov 
25053108fb5SKirill Batuzov     default:
25153108fb5SKirill Batuzov         fprintf(stderr,
25253108fb5SKirill Batuzov                 "Unrecognized operation %d in do_constant_folding.\n", op);
25353108fb5SKirill Batuzov         tcg_abort();
25453108fb5SKirill Batuzov     }
25553108fb5SKirill Batuzov }
25653108fb5SKirill Batuzov 
257fe0de7aaSBlue Swirl static TCGArg do_constant_folding(TCGOpcode op, TCGArg x, TCGArg y)
25853108fb5SKirill Batuzov {
25953108fb5SKirill Batuzov     TCGArg res = do_constant_folding_2(op, x, y);
26053108fb5SKirill Batuzov     if (op_bits(op) == 32) {
26153108fb5SKirill Batuzov         res &= 0xffffffff;
26253108fb5SKirill Batuzov     }
26353108fb5SKirill Batuzov     return res;
26453108fb5SKirill Batuzov }
26553108fb5SKirill Batuzov 
266f8dd19e5SAurelien Jarno static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x,
267f8dd19e5SAurelien Jarno                                        TCGArg y, TCGCond c)
268f8dd19e5SAurelien Jarno {
269f8dd19e5SAurelien Jarno     switch (op_bits(op)) {
270f8dd19e5SAurelien Jarno     case 32:
271f8dd19e5SAurelien Jarno         switch (c) {
272f8dd19e5SAurelien Jarno         case TCG_COND_EQ:
273f8dd19e5SAurelien Jarno             return (uint32_t)x == (uint32_t)y;
274f8dd19e5SAurelien Jarno         case TCG_COND_NE:
275f8dd19e5SAurelien Jarno             return (uint32_t)x != (uint32_t)y;
276f8dd19e5SAurelien Jarno         case TCG_COND_LT:
277f8dd19e5SAurelien Jarno             return (int32_t)x < (int32_t)y;
278f8dd19e5SAurelien Jarno         case TCG_COND_GE:
279f8dd19e5SAurelien Jarno             return (int32_t)x >= (int32_t)y;
280f8dd19e5SAurelien Jarno         case TCG_COND_LE:
281f8dd19e5SAurelien Jarno             return (int32_t)x <= (int32_t)y;
282f8dd19e5SAurelien Jarno         case TCG_COND_GT:
283f8dd19e5SAurelien Jarno             return (int32_t)x > (int32_t)y;
284f8dd19e5SAurelien Jarno         case TCG_COND_LTU:
285f8dd19e5SAurelien Jarno             return (uint32_t)x < (uint32_t)y;
286f8dd19e5SAurelien Jarno         case TCG_COND_GEU:
287f8dd19e5SAurelien Jarno             return (uint32_t)x >= (uint32_t)y;
288f8dd19e5SAurelien Jarno         case TCG_COND_LEU:
289f8dd19e5SAurelien Jarno             return (uint32_t)x <= (uint32_t)y;
290f8dd19e5SAurelien Jarno         case TCG_COND_GTU:
291f8dd19e5SAurelien Jarno             return (uint32_t)x > (uint32_t)y;
292f8dd19e5SAurelien Jarno         }
293f8dd19e5SAurelien Jarno         break;
294f8dd19e5SAurelien Jarno     case 64:
295f8dd19e5SAurelien Jarno         switch (c) {
296f8dd19e5SAurelien Jarno         case TCG_COND_EQ:
297f8dd19e5SAurelien Jarno             return (uint64_t)x == (uint64_t)y;
298f8dd19e5SAurelien Jarno         case TCG_COND_NE:
299f8dd19e5SAurelien Jarno             return (uint64_t)x != (uint64_t)y;
300f8dd19e5SAurelien Jarno         case TCG_COND_LT:
301f8dd19e5SAurelien Jarno             return (int64_t)x < (int64_t)y;
302f8dd19e5SAurelien Jarno         case TCG_COND_GE:
303f8dd19e5SAurelien Jarno             return (int64_t)x >= (int64_t)y;
304f8dd19e5SAurelien Jarno         case TCG_COND_LE:
305f8dd19e5SAurelien Jarno             return (int64_t)x <= (int64_t)y;
306f8dd19e5SAurelien Jarno         case TCG_COND_GT:
307f8dd19e5SAurelien Jarno             return (int64_t)x > (int64_t)y;
308f8dd19e5SAurelien Jarno         case TCG_COND_LTU:
309f8dd19e5SAurelien Jarno             return (uint64_t)x < (uint64_t)y;
310f8dd19e5SAurelien Jarno         case TCG_COND_GEU:
311f8dd19e5SAurelien Jarno             return (uint64_t)x >= (uint64_t)y;
312f8dd19e5SAurelien Jarno         case TCG_COND_LEU:
313f8dd19e5SAurelien Jarno             return (uint64_t)x <= (uint64_t)y;
314f8dd19e5SAurelien Jarno         case TCG_COND_GTU:
315f8dd19e5SAurelien Jarno             return (uint64_t)x > (uint64_t)y;
316f8dd19e5SAurelien Jarno         }
317f8dd19e5SAurelien Jarno         break;
318f8dd19e5SAurelien Jarno     }
319f8dd19e5SAurelien Jarno 
320f8dd19e5SAurelien Jarno     fprintf(stderr,
321f8dd19e5SAurelien Jarno             "Unrecognized bitness %d or condition %d in "
322f8dd19e5SAurelien Jarno             "do_constant_folding_cond.\n", op_bits(op), c);
323f8dd19e5SAurelien Jarno     tcg_abort();
324f8dd19e5SAurelien Jarno }
325f8dd19e5SAurelien Jarno 
326f8dd19e5SAurelien Jarno 
32722613af4SKirill Batuzov /* Propagate constants and copies, fold constant expressions. */
3288f2e8c07SKirill Batuzov static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
3298f2e8c07SKirill Batuzov                                     TCGArg *args, TCGOpDef *tcg_op_defs)
3308f2e8c07SKirill Batuzov {
331fe0de7aaSBlue Swirl     int i, nb_ops, op_index, nb_temps, nb_globals, nb_call_args;
332fe0de7aaSBlue Swirl     TCGOpcode op;
3338f2e8c07SKirill Batuzov     const TCGOpDef *def;
3348f2e8c07SKirill Batuzov     TCGArg *gen_args;
33553108fb5SKirill Batuzov     TCGArg tmp;
3365d8f5363SRichard Henderson     TCGCond cond;
3375d8f5363SRichard Henderson 
33822613af4SKirill Batuzov     /* Array VALS has an element for each temp.
33922613af4SKirill Batuzov        If this temp holds a constant then its value is kept in VALS' element.
34022613af4SKirill Batuzov        If this temp is a copy of other ones then this equivalence class'
34122613af4SKirill Batuzov        representative is kept in VALS' element.
34222613af4SKirill Batuzov        If this temp is neither copy nor constant then corresponding VALS'
34322613af4SKirill Batuzov        element is unused. */
3448f2e8c07SKirill Batuzov 
3458f2e8c07SKirill Batuzov     nb_temps = s->nb_temps;
3468f2e8c07SKirill Batuzov     nb_globals = s->nb_globals;
34722613af4SKirill Batuzov     memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
3488f2e8c07SKirill Batuzov 
3498f2e8c07SKirill Batuzov     nb_ops = tcg_opc_ptr - gen_opc_buf;
3508f2e8c07SKirill Batuzov     gen_args = args;
3518f2e8c07SKirill Batuzov     for (op_index = 0; op_index < nb_ops; op_index++) {
3528f2e8c07SKirill Batuzov         op = gen_opc_buf[op_index];
3538f2e8c07SKirill Batuzov         def = &tcg_op_defs[op];
35422613af4SKirill Batuzov         /* Do copy propagation */
35522613af4SKirill Batuzov         if (!(def->flags & (TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS))) {
35622613af4SKirill Batuzov             assert(op != INDEX_op_call);
35722613af4SKirill Batuzov             for (i = def->nb_oargs; i < def->nb_oargs + def->nb_iargs; i++) {
35822613af4SKirill Batuzov                 if (temps[args[i]].state == TCG_TEMP_COPY) {
35922613af4SKirill Batuzov                     args[i] = temps[args[i]].val;
36022613af4SKirill Batuzov                 }
36122613af4SKirill Batuzov             }
36222613af4SKirill Batuzov         }
36322613af4SKirill Batuzov 
36453108fb5SKirill Batuzov         /* For commutative operations make constant second argument */
36553108fb5SKirill Batuzov         switch (op) {
36653108fb5SKirill Batuzov         CASE_OP_32_64(add):
36753108fb5SKirill Batuzov         CASE_OP_32_64(mul):
3689a81090bSKirill Batuzov         CASE_OP_32_64(and):
3699a81090bSKirill Batuzov         CASE_OP_32_64(or):
3709a81090bSKirill Batuzov         CASE_OP_32_64(xor):
371cb25c80aSRichard Henderson         CASE_OP_32_64(eqv):
372cb25c80aSRichard Henderson         CASE_OP_32_64(nand):
373cb25c80aSRichard Henderson         CASE_OP_32_64(nor):
37453108fb5SKirill Batuzov             if (temps[args[1]].state == TCG_TEMP_CONST) {
37553108fb5SKirill Batuzov                 tmp = args[1];
37653108fb5SKirill Batuzov                 args[1] = args[2];
37753108fb5SKirill Batuzov                 args[2] = tmp;
37853108fb5SKirill Batuzov             }
37953108fb5SKirill Batuzov             break;
38065a7cce1SAurelien Jarno         CASE_OP_32_64(brcond):
38165a7cce1SAurelien Jarno             if (temps[args[0]].state == TCG_TEMP_CONST
38265a7cce1SAurelien Jarno                 && temps[args[1]].state != TCG_TEMP_CONST) {
38365a7cce1SAurelien Jarno                 tmp = args[0];
38465a7cce1SAurelien Jarno                 args[0] = args[1];
38565a7cce1SAurelien Jarno                 args[1] = tmp;
38665a7cce1SAurelien Jarno                 args[2] = tcg_swap_cond(args[2]);
38765a7cce1SAurelien Jarno             }
38865a7cce1SAurelien Jarno             break;
38965a7cce1SAurelien Jarno         CASE_OP_32_64(setcond):
39065a7cce1SAurelien Jarno             if (temps[args[1]].state == TCG_TEMP_CONST
39165a7cce1SAurelien Jarno                 && temps[args[2]].state != TCG_TEMP_CONST) {
39265a7cce1SAurelien Jarno                 tmp = args[1];
39365a7cce1SAurelien Jarno                 args[1] = args[2];
39465a7cce1SAurelien Jarno                 args[2] = tmp;
39565a7cce1SAurelien Jarno                 args[3] = tcg_swap_cond(args[3]);
39665a7cce1SAurelien Jarno             }
39765a7cce1SAurelien Jarno             break;
398fa01a208SRichard Henderson         CASE_OP_32_64(movcond):
3995d8f5363SRichard Henderson             cond = args[5];
400fa01a208SRichard Henderson             if (temps[args[1]].state == TCG_TEMP_CONST
401fa01a208SRichard Henderson                 && temps[args[2]].state != TCG_TEMP_CONST) {
402fa01a208SRichard Henderson                 tmp = args[1];
403fa01a208SRichard Henderson                 args[1] = args[2];
404fa01a208SRichard Henderson                 args[2] = tmp;
4055d8f5363SRichard Henderson                 cond = tcg_swap_cond(cond);
406fa01a208SRichard Henderson             }
4075d8f5363SRichard Henderson             /* For movcond, we canonicalize the "false" input reg to match
4085d8f5363SRichard Henderson                the destination reg so that the tcg backend can implement
4095d8f5363SRichard Henderson                a "move if true" operation.  */
4105d8f5363SRichard Henderson             if (args[0] == args[3]) {
4115d8f5363SRichard Henderson                 tmp = args[3];
4125d8f5363SRichard Henderson                 args[3] = args[4];
4135d8f5363SRichard Henderson                 args[4] = tmp;
4145d8f5363SRichard Henderson                 cond = tcg_invert_cond(cond);
4155d8f5363SRichard Henderson             }
4165d8f5363SRichard Henderson             args[5] = cond;
41753108fb5SKirill Batuzov         default:
41853108fb5SKirill Batuzov             break;
41953108fb5SKirill Batuzov         }
42053108fb5SKirill Batuzov 
42101ee5282SAurelien Jarno         /* Simplify expressions for "shift/rot r, 0, a => movi r, 0" */
42201ee5282SAurelien Jarno         switch (op) {
42301ee5282SAurelien Jarno         CASE_OP_32_64(shl):
42401ee5282SAurelien Jarno         CASE_OP_32_64(shr):
42501ee5282SAurelien Jarno         CASE_OP_32_64(sar):
42601ee5282SAurelien Jarno         CASE_OP_32_64(rotl):
42701ee5282SAurelien Jarno         CASE_OP_32_64(rotr):
42801ee5282SAurelien Jarno             if (temps[args[1]].state == TCG_TEMP_CONST
42901ee5282SAurelien Jarno                 && temps[args[1]].val == 0) {
43001ee5282SAurelien Jarno                 gen_opc_buf[op_index] = op_to_movi(op);
43101ee5282SAurelien Jarno                 tcg_opt_gen_movi(gen_args, args[0], 0, nb_temps, nb_globals);
43201ee5282SAurelien Jarno                 args += 3;
43301ee5282SAurelien Jarno                 gen_args += 2;
43401ee5282SAurelien Jarno                 continue;
43501ee5282SAurelien Jarno             }
43601ee5282SAurelien Jarno             break;
43701ee5282SAurelien Jarno         default:
43801ee5282SAurelien Jarno             break;
43901ee5282SAurelien Jarno         }
44001ee5282SAurelien Jarno 
44156e49438SAurelien Jarno         /* Simplify expression for "op r, a, 0 => mov r, a" cases */
44253108fb5SKirill Batuzov         switch (op) {
44353108fb5SKirill Batuzov         CASE_OP_32_64(add):
44453108fb5SKirill Batuzov         CASE_OP_32_64(sub):
44555c0975cSKirill Batuzov         CASE_OP_32_64(shl):
44655c0975cSKirill Batuzov         CASE_OP_32_64(shr):
44755c0975cSKirill Batuzov         CASE_OP_32_64(sar):
44825c4d9ccSRichard Henderson         CASE_OP_32_64(rotl):
44925c4d9ccSRichard Henderson         CASE_OP_32_64(rotr):
45038ee188bSAurelien Jarno         CASE_OP_32_64(or):
45138ee188bSAurelien Jarno         CASE_OP_32_64(xor):
45253108fb5SKirill Batuzov             if (temps[args[1]].state == TCG_TEMP_CONST) {
45353108fb5SKirill Batuzov                 /* Proceed with possible constant folding. */
45453108fb5SKirill Batuzov                 break;
45553108fb5SKirill Batuzov             }
45653108fb5SKirill Batuzov             if (temps[args[2]].state == TCG_TEMP_CONST
45753108fb5SKirill Batuzov                 && temps[args[2]].val == 0) {
45853108fb5SKirill Batuzov                 if ((temps[args[0]].state == TCG_TEMP_COPY
45953108fb5SKirill Batuzov                     && temps[args[0]].val == args[1])
46053108fb5SKirill Batuzov                     || args[0] == args[1]) {
46153108fb5SKirill Batuzov                     gen_opc_buf[op_index] = INDEX_op_nop;
46253108fb5SKirill Batuzov                 } else {
46353108fb5SKirill Batuzov                     gen_opc_buf[op_index] = op_to_mov(op);
464d104bebdSAurelien Jarno                     tcg_opt_gen_mov(gen_args, args[0], args[1],
46553108fb5SKirill Batuzov                                     nb_temps, nb_globals);
46653108fb5SKirill Batuzov                     gen_args += 2;
46753108fb5SKirill Batuzov                 }
468fedc0da2SAurelien Jarno                 args += 3;
46953108fb5SKirill Batuzov                 continue;
47053108fb5SKirill Batuzov             }
47153108fb5SKirill Batuzov             break;
47256e49438SAurelien Jarno         default:
47356e49438SAurelien Jarno             break;
47456e49438SAurelien Jarno         }
47556e49438SAurelien Jarno 
47656e49438SAurelien Jarno         /* Simplify expression for "op r, a, 0 => movi r, 0" cases */
47756e49438SAurelien Jarno         switch (op) {
47861251c0cSAurelien Jarno         CASE_OP_32_64(and):
47953108fb5SKirill Batuzov         CASE_OP_32_64(mul):
48053108fb5SKirill Batuzov             if ((temps[args[2]].state == TCG_TEMP_CONST
48153108fb5SKirill Batuzov                 && temps[args[2]].val == 0)) {
48253108fb5SKirill Batuzov                 gen_opc_buf[op_index] = op_to_movi(op);
48353108fb5SKirill Batuzov                 tcg_opt_gen_movi(gen_args, args[0], 0, nb_temps, nb_globals);
48453108fb5SKirill Batuzov                 args += 3;
48553108fb5SKirill Batuzov                 gen_args += 2;
48653108fb5SKirill Batuzov                 continue;
48753108fb5SKirill Batuzov             }
48853108fb5SKirill Batuzov             break;
48956e49438SAurelien Jarno         default:
49056e49438SAurelien Jarno             break;
49156e49438SAurelien Jarno         }
49256e49438SAurelien Jarno 
49356e49438SAurelien Jarno         /* Simplify expression for "op r, a, a => mov r, a" cases */
49456e49438SAurelien Jarno         switch (op) {
4959a81090bSKirill Batuzov         CASE_OP_32_64(or):
4969a81090bSKirill Batuzov         CASE_OP_32_64(and):
4979a81090bSKirill Batuzov             if (args[1] == args[2]) {
4989a81090bSKirill Batuzov                 if (args[1] == args[0]) {
4999a81090bSKirill Batuzov                     gen_opc_buf[op_index] = INDEX_op_nop;
5009a81090bSKirill Batuzov                 } else {
5019a81090bSKirill Batuzov                     gen_opc_buf[op_index] = op_to_mov(op);
502d104bebdSAurelien Jarno                     tcg_opt_gen_mov(gen_args, args[0], args[1], nb_temps,
5039a81090bSKirill Batuzov                                     nb_globals);
5049a81090bSKirill Batuzov                     gen_args += 2;
5059a81090bSKirill Batuzov                 }
506fedc0da2SAurelien Jarno                 args += 3;
5079a81090bSKirill Batuzov                 continue;
5089a81090bSKirill Batuzov             }
5099a81090bSKirill Batuzov             break;
510fe0de7aaSBlue Swirl         default:
511fe0de7aaSBlue Swirl             break;
51253108fb5SKirill Batuzov         }
51353108fb5SKirill Batuzov 
51422613af4SKirill Batuzov         /* Propagate constants through copy operations and do constant
51522613af4SKirill Batuzov            folding.  Constants will be substituted to arguments by register
51622613af4SKirill Batuzov            allocator where needed and possible.  Also detect copies. */
5178f2e8c07SKirill Batuzov         switch (op) {
51822613af4SKirill Batuzov         CASE_OP_32_64(mov):
51922613af4SKirill Batuzov             if ((temps[args[1]].state == TCG_TEMP_COPY
52022613af4SKirill Batuzov                 && temps[args[1]].val == args[0])
52122613af4SKirill Batuzov                 || args[0] == args[1]) {
52222613af4SKirill Batuzov                 args += 2;
52322613af4SKirill Batuzov                 gen_opc_buf[op_index] = INDEX_op_nop;
52422613af4SKirill Batuzov                 break;
52522613af4SKirill Batuzov             }
52622613af4SKirill Batuzov             if (temps[args[1]].state != TCG_TEMP_CONST) {
527d104bebdSAurelien Jarno                 tcg_opt_gen_mov(gen_args, args[0], args[1],
52822613af4SKirill Batuzov                                 nb_temps, nb_globals);
52922613af4SKirill Batuzov                 gen_args += 2;
53022613af4SKirill Batuzov                 args += 2;
53122613af4SKirill Batuzov                 break;
53222613af4SKirill Batuzov             }
53322613af4SKirill Batuzov             /* Source argument is constant.  Rewrite the operation and
53422613af4SKirill Batuzov                let movi case handle it. */
53522613af4SKirill Batuzov             op = op_to_movi(op);
53622613af4SKirill Batuzov             gen_opc_buf[op_index] = op;
53722613af4SKirill Batuzov             args[1] = temps[args[1]].val;
53822613af4SKirill Batuzov             /* fallthrough */
53922613af4SKirill Batuzov         CASE_OP_32_64(movi):
54022613af4SKirill Batuzov             tcg_opt_gen_movi(gen_args, args[0], args[1], nb_temps, nb_globals);
54122613af4SKirill Batuzov             gen_args += 2;
54222613af4SKirill Batuzov             args += 2;
54322613af4SKirill Batuzov             break;
544a640f031SKirill Batuzov         CASE_OP_32_64(not):
545cb25c80aSRichard Henderson         CASE_OP_32_64(neg):
54625c4d9ccSRichard Henderson         CASE_OP_32_64(ext8s):
54725c4d9ccSRichard Henderson         CASE_OP_32_64(ext8u):
54825c4d9ccSRichard Henderson         CASE_OP_32_64(ext16s):
54925c4d9ccSRichard Henderson         CASE_OP_32_64(ext16u):
550a640f031SKirill Batuzov         case INDEX_op_ext32s_i64:
551a640f031SKirill Batuzov         case INDEX_op_ext32u_i64:
552a640f031SKirill Batuzov             if (temps[args[1]].state == TCG_TEMP_CONST) {
553a640f031SKirill Batuzov                 gen_opc_buf[op_index] = op_to_movi(op);
554a640f031SKirill Batuzov                 tmp = do_constant_folding(op, temps[args[1]].val, 0);
555a640f031SKirill Batuzov                 tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
556a640f031SKirill Batuzov             } else {
557a640f031SKirill Batuzov                 reset_temp(args[0], nb_temps, nb_globals);
558a640f031SKirill Batuzov                 gen_args[0] = args[0];
559a640f031SKirill Batuzov                 gen_args[1] = args[1];
560fedc0da2SAurelien Jarno             }
561a640f031SKirill Batuzov             gen_args += 2;
562a640f031SKirill Batuzov             args += 2;
563a640f031SKirill Batuzov             break;
56453108fb5SKirill Batuzov         CASE_OP_32_64(add):
56553108fb5SKirill Batuzov         CASE_OP_32_64(sub):
56653108fb5SKirill Batuzov         CASE_OP_32_64(mul):
5679a81090bSKirill Batuzov         CASE_OP_32_64(or):
5689a81090bSKirill Batuzov         CASE_OP_32_64(and):
5699a81090bSKirill Batuzov         CASE_OP_32_64(xor):
57055c0975cSKirill Batuzov         CASE_OP_32_64(shl):
57155c0975cSKirill Batuzov         CASE_OP_32_64(shr):
57255c0975cSKirill Batuzov         CASE_OP_32_64(sar):
57325c4d9ccSRichard Henderson         CASE_OP_32_64(rotl):
57425c4d9ccSRichard Henderson         CASE_OP_32_64(rotr):
575cb25c80aSRichard Henderson         CASE_OP_32_64(andc):
576cb25c80aSRichard Henderson         CASE_OP_32_64(orc):
577cb25c80aSRichard Henderson         CASE_OP_32_64(eqv):
578cb25c80aSRichard Henderson         CASE_OP_32_64(nand):
579cb25c80aSRichard Henderson         CASE_OP_32_64(nor):
58053108fb5SKirill Batuzov             if (temps[args[1]].state == TCG_TEMP_CONST
58153108fb5SKirill Batuzov                 && temps[args[2]].state == TCG_TEMP_CONST) {
58253108fb5SKirill Batuzov                 gen_opc_buf[op_index] = op_to_movi(op);
58353108fb5SKirill Batuzov                 tmp = do_constant_folding(op, temps[args[1]].val,
58453108fb5SKirill Batuzov                                           temps[args[2]].val);
58553108fb5SKirill Batuzov                 tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
58653108fb5SKirill Batuzov                 gen_args += 2;
58753108fb5SKirill Batuzov             } else {
58853108fb5SKirill Batuzov                 reset_temp(args[0], nb_temps, nb_globals);
58953108fb5SKirill Batuzov                 gen_args[0] = args[0];
59053108fb5SKirill Batuzov                 gen_args[1] = args[1];
59153108fb5SKirill Batuzov                 gen_args[2] = args[2];
59253108fb5SKirill Batuzov                 gen_args += 3;
593fedc0da2SAurelien Jarno             }
59453108fb5SKirill Batuzov             args += 3;
59553108fb5SKirill Batuzov             break;
596f8dd19e5SAurelien Jarno         CASE_OP_32_64(setcond):
597f8dd19e5SAurelien Jarno             if (temps[args[1]].state == TCG_TEMP_CONST
598f8dd19e5SAurelien Jarno                 && temps[args[2]].state == TCG_TEMP_CONST) {
599f8dd19e5SAurelien Jarno                 gen_opc_buf[op_index] = op_to_movi(op);
600f8dd19e5SAurelien Jarno                 tmp = do_constant_folding_cond(op, temps[args[1]].val,
601f8dd19e5SAurelien Jarno                                                temps[args[2]].val, args[3]);
602f8dd19e5SAurelien Jarno                 tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
603f8dd19e5SAurelien Jarno                 gen_args += 2;
604f8dd19e5SAurelien Jarno             } else {
605f8dd19e5SAurelien Jarno                 reset_temp(args[0], nb_temps, nb_globals);
606f8dd19e5SAurelien Jarno                 gen_args[0] = args[0];
607f8dd19e5SAurelien Jarno                 gen_args[1] = args[1];
608f8dd19e5SAurelien Jarno                 gen_args[2] = args[2];
609f8dd19e5SAurelien Jarno                 gen_args[3] = args[3];
610f8dd19e5SAurelien Jarno                 gen_args += 4;
611fedc0da2SAurelien Jarno             }
612f8dd19e5SAurelien Jarno             args += 4;
613f8dd19e5SAurelien Jarno             break;
614fbeaa26cSAurelien Jarno         CASE_OP_32_64(brcond):
615fbeaa26cSAurelien Jarno             if (temps[args[0]].state == TCG_TEMP_CONST
616fbeaa26cSAurelien Jarno                 && temps[args[1]].state == TCG_TEMP_CONST) {
617fbeaa26cSAurelien Jarno                 if (do_constant_folding_cond(op, temps[args[0]].val,
618fbeaa26cSAurelien Jarno                                              temps[args[1]].val, args[2])) {
619fbeaa26cSAurelien Jarno                     memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
620fbeaa26cSAurelien Jarno                     gen_opc_buf[op_index] = INDEX_op_br;
621fbeaa26cSAurelien Jarno                     gen_args[0] = args[3];
622fbeaa26cSAurelien Jarno                     gen_args += 1;
623fbeaa26cSAurelien Jarno                 } else {
624fbeaa26cSAurelien Jarno                     gen_opc_buf[op_index] = INDEX_op_nop;
625fbeaa26cSAurelien Jarno                 }
626fbeaa26cSAurelien Jarno             } else {
627fbeaa26cSAurelien Jarno                 memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
628fbeaa26cSAurelien Jarno                 reset_temp(args[0], nb_temps, nb_globals);
629fbeaa26cSAurelien Jarno                 gen_args[0] = args[0];
630fbeaa26cSAurelien Jarno                 gen_args[1] = args[1];
631fbeaa26cSAurelien Jarno                 gen_args[2] = args[2];
632fbeaa26cSAurelien Jarno                 gen_args[3] = args[3];
633fbeaa26cSAurelien Jarno                 gen_args += 4;
634fedc0da2SAurelien Jarno             }
635fbeaa26cSAurelien Jarno             args += 4;
636fbeaa26cSAurelien Jarno             break;
637fa01a208SRichard Henderson         CASE_OP_32_64(movcond):
638fa01a208SRichard Henderson             if (temps[args[1]].state == TCG_TEMP_CONST
639fa01a208SRichard Henderson                 && temps[args[2]].state == TCG_TEMP_CONST) {
640fa01a208SRichard Henderson                 tmp = do_constant_folding_cond(op, temps[args[1]].val,
641fa01a208SRichard Henderson                                                temps[args[2]].val, args[5]);
642fa01a208SRichard Henderson                 if (args[0] == args[4-tmp]
643fa01a208SRichard Henderson                     || (temps[args[4-tmp]].state == TCG_TEMP_COPY
644fa01a208SRichard Henderson                         && temps[args[4-tmp]].val == args[0])) {
645fa01a208SRichard Henderson                     gen_opc_buf[op_index] = INDEX_op_nop;
646fa01a208SRichard Henderson                 } else if (temps[args[4-tmp]].state == TCG_TEMP_CONST) {
647fa01a208SRichard Henderson                     gen_opc_buf[op_index] = op_to_movi(op);
648fa01a208SRichard Henderson                     tcg_opt_gen_movi(gen_args, args[0], temps[args[4-tmp]].val,
649fa01a208SRichard Henderson                                      nb_temps, nb_globals);
650fa01a208SRichard Henderson                     gen_args += 2;
651fa01a208SRichard Henderson                 } else {
652fa01a208SRichard Henderson                     gen_opc_buf[op_index] = op_to_mov(op);
653fa01a208SRichard Henderson                     tcg_opt_gen_mov(gen_args, args[0], args[4-tmp],
654fa01a208SRichard Henderson                                     nb_temps, nb_globals);
655fa01a208SRichard Henderson                     gen_args += 2;
656fa01a208SRichard Henderson                 }
657fa01a208SRichard Henderson             } else {
658fa01a208SRichard Henderson                 reset_temp(args[0], nb_temps, nb_globals);
659fa01a208SRichard Henderson                 gen_args[0] = args[0];
660fa01a208SRichard Henderson                 gen_args[1] = args[1];
661fa01a208SRichard Henderson                 gen_args[2] = args[2];
662fa01a208SRichard Henderson                 gen_args[3] = args[3];
663fa01a208SRichard Henderson                 gen_args[4] = args[4];
664fa01a208SRichard Henderson                 gen_args[5] = args[5];
665fa01a208SRichard Henderson                 gen_args += 6;
666fa01a208SRichard Henderson             }
667fa01a208SRichard Henderson             args += 6;
668fa01a208SRichard Henderson             break;
6698f2e8c07SKirill Batuzov         case INDEX_op_call:
67022613af4SKirill Batuzov             nb_call_args = (args[0] >> 16) + (args[0] & 0xffff);
67122613af4SKirill Batuzov             if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) {
67222613af4SKirill Batuzov                 for (i = 0; i < nb_globals; i++) {
67322613af4SKirill Batuzov                     reset_temp(i, nb_temps, nb_globals);
67422613af4SKirill Batuzov                 }
67522613af4SKirill Batuzov             }
67622613af4SKirill Batuzov             for (i = 0; i < (args[0] >> 16); i++) {
67722613af4SKirill Batuzov                 reset_temp(args[i + 1], nb_temps, nb_globals);
67822613af4SKirill Batuzov             }
67922613af4SKirill Batuzov             i = nb_call_args + 3;
6808f2e8c07SKirill Batuzov             while (i) {
6818f2e8c07SKirill Batuzov                 *gen_args = *args;
6828f2e8c07SKirill Batuzov                 args++;
6838f2e8c07SKirill Batuzov                 gen_args++;
6848f2e8c07SKirill Batuzov                 i--;
6858f2e8c07SKirill Batuzov             }
6868f2e8c07SKirill Batuzov             break;
6878f2e8c07SKirill Batuzov         default:
68822613af4SKirill Batuzov             /* Default case: we do know nothing about operation so no
689a2550660SAurelien Jarno                propagation is done.  We trash everything if the operation
690a2550660SAurelien Jarno                is the end of a basic block, otherwise we only trash the
691a2550660SAurelien Jarno                output args.  */
692a2550660SAurelien Jarno             if (def->flags & TCG_OPF_BB_END) {
693a2550660SAurelien Jarno                 memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
694a2550660SAurelien Jarno             } else {
69522613af4SKirill Batuzov                 for (i = 0; i < def->nb_oargs; i++) {
69622613af4SKirill Batuzov                     reset_temp(args[i], nb_temps, nb_globals);
69722613af4SKirill Batuzov                 }
698a2550660SAurelien Jarno             }
6998f2e8c07SKirill Batuzov             for (i = 0; i < def->nb_args; i++) {
7008f2e8c07SKirill Batuzov                 gen_args[i] = args[i];
7018f2e8c07SKirill Batuzov             }
7028f2e8c07SKirill Batuzov             args += def->nb_args;
7038f2e8c07SKirill Batuzov             gen_args += def->nb_args;
7048f2e8c07SKirill Batuzov             break;
7058f2e8c07SKirill Batuzov         }
7068f2e8c07SKirill Batuzov     }
7078f2e8c07SKirill Batuzov 
7088f2e8c07SKirill Batuzov     return gen_args;
7098f2e8c07SKirill Batuzov }
7108f2e8c07SKirill Batuzov 
7118f2e8c07SKirill Batuzov TCGArg *tcg_optimize(TCGContext *s, uint16_t *tcg_opc_ptr,
7128f2e8c07SKirill Batuzov         TCGArg *args, TCGOpDef *tcg_op_defs)
7138f2e8c07SKirill Batuzov {
7148f2e8c07SKirill Batuzov     TCGArg *res;
7158f2e8c07SKirill Batuzov     res = tcg_constant_folding(s, tcg_opc_ptr, args, tcg_op_defs);
7168f2e8c07SKirill Batuzov     return res;
7178f2e8c07SKirill Batuzov }
718