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; 4922613af4SKirill Batuzov }; 5022613af4SKirill Batuzov 5122613af4SKirill Batuzov static struct tcg_temp_info temps[TCG_MAX_TEMPS]; 5222613af4SKirill Batuzov 53e590d4e6SAurelien Jarno /* Reset TEMP's state to TCG_TEMP_UNDEF. If TEMP only had one copy, remove 54e590d4e6SAurelien Jarno the copy flag from the left temp. */ 55e590d4e6SAurelien Jarno static void reset_temp(TCGArg temp) 5622613af4SKirill Batuzov { 57e590d4e6SAurelien Jarno if (temps[temp].state == TCG_TEMP_COPY) { 58e590d4e6SAurelien Jarno if (temps[temp].prev_copy == temps[temp].next_copy) { 59e590d4e6SAurelien Jarno temps[temps[temp].next_copy].state = TCG_TEMP_UNDEF; 6022613af4SKirill Batuzov } else { 6122613af4SKirill Batuzov temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy; 6222613af4SKirill Batuzov temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy; 63e590d4e6SAurelien Jarno } 6422613af4SKirill Batuzov } 6548b56ce1SAurelien Jarno temps[temp].state = TCG_TEMP_UNDEF; 6622613af4SKirill Batuzov } 6722613af4SKirill Batuzov 68fe0de7aaSBlue Swirl static int op_bits(TCGOpcode op) 6922613af4SKirill Batuzov { 708399ad59SRichard Henderson const TCGOpDef *def = &tcg_op_defs[op]; 718399ad59SRichard Henderson return def->flags & TCG_OPF_64BIT ? 64 : 32; 7222613af4SKirill Batuzov } 7322613af4SKirill Batuzov 74fe0de7aaSBlue Swirl static TCGOpcode op_to_movi(TCGOpcode op) 7522613af4SKirill Batuzov { 7622613af4SKirill Batuzov switch (op_bits(op)) { 7722613af4SKirill Batuzov case 32: 7822613af4SKirill Batuzov return INDEX_op_movi_i32; 7922613af4SKirill Batuzov case 64: 8022613af4SKirill Batuzov return INDEX_op_movi_i64; 8122613af4SKirill Batuzov default: 8222613af4SKirill Batuzov fprintf(stderr, "op_to_movi: unexpected return value of " 8322613af4SKirill Batuzov "function op_bits.\n"); 8422613af4SKirill Batuzov tcg_abort(); 8522613af4SKirill Batuzov } 8622613af4SKirill Batuzov } 8722613af4SKirill Batuzov 88e590d4e6SAurelien Jarno static TCGArg find_better_copy(TCGContext *s, TCGArg temp) 89e590d4e6SAurelien Jarno { 90e590d4e6SAurelien Jarno TCGArg i; 91e590d4e6SAurelien Jarno 92e590d4e6SAurelien Jarno /* If this is already a global, we can't do better. */ 93e590d4e6SAurelien Jarno if (temp < s->nb_globals) { 94e590d4e6SAurelien Jarno return temp; 95e590d4e6SAurelien Jarno } 96e590d4e6SAurelien Jarno 97e590d4e6SAurelien Jarno /* Search for a global first. */ 98e590d4e6SAurelien Jarno for (i = temps[temp].next_copy ; i != temp ; i = temps[i].next_copy) { 99e590d4e6SAurelien Jarno if (i < s->nb_globals) { 100e590d4e6SAurelien Jarno return i; 101e590d4e6SAurelien Jarno } 102e590d4e6SAurelien Jarno } 103e590d4e6SAurelien Jarno 104e590d4e6SAurelien Jarno /* If it is a temp, search for a temp local. */ 105e590d4e6SAurelien Jarno if (!s->temps[temp].temp_local) { 106e590d4e6SAurelien Jarno for (i = temps[temp].next_copy ; i != temp ; i = temps[i].next_copy) { 107e590d4e6SAurelien Jarno if (s->temps[i].temp_local) { 108e590d4e6SAurelien Jarno return i; 109e590d4e6SAurelien Jarno } 110e590d4e6SAurelien Jarno } 111e590d4e6SAurelien Jarno } 112e590d4e6SAurelien Jarno 113e590d4e6SAurelien Jarno /* Failure to find a better representation, return the same temp. */ 114e590d4e6SAurelien Jarno return temp; 115e590d4e6SAurelien Jarno } 116e590d4e6SAurelien Jarno 117e590d4e6SAurelien Jarno static bool temps_are_copies(TCGArg arg1, TCGArg arg2) 118e590d4e6SAurelien Jarno { 119e590d4e6SAurelien Jarno TCGArg i; 120e590d4e6SAurelien Jarno 121e590d4e6SAurelien Jarno if (arg1 == arg2) { 122e590d4e6SAurelien Jarno return true; 123e590d4e6SAurelien Jarno } 124e590d4e6SAurelien Jarno 125e590d4e6SAurelien Jarno if (temps[arg1].state != TCG_TEMP_COPY 126e590d4e6SAurelien Jarno || temps[arg2].state != TCG_TEMP_COPY) { 127e590d4e6SAurelien Jarno return false; 128e590d4e6SAurelien Jarno } 129e590d4e6SAurelien Jarno 130e590d4e6SAurelien Jarno for (i = temps[arg1].next_copy ; i != arg1 ; i = temps[i].next_copy) { 131e590d4e6SAurelien Jarno if (i == arg2) { 132e590d4e6SAurelien Jarno return true; 133e590d4e6SAurelien Jarno } 134e590d4e6SAurelien Jarno } 135e590d4e6SAurelien Jarno 136e590d4e6SAurelien Jarno return false; 137e590d4e6SAurelien Jarno } 138e590d4e6SAurelien Jarno 139b80bb016SAurelien Jarno static void tcg_opt_gen_mov(TCGContext *s, TCGArg *gen_args, 140b80bb016SAurelien Jarno TCGArg dst, TCGArg src) 14122613af4SKirill Batuzov { 142e590d4e6SAurelien Jarno reset_temp(dst); 14322613af4SKirill Batuzov assert(temps[src].state != TCG_TEMP_CONST); 144e590d4e6SAurelien Jarno 145e590d4e6SAurelien Jarno if (s->temps[src].type == s->temps[dst].type) { 146e590d4e6SAurelien Jarno if (temps[src].state != TCG_TEMP_COPY) { 147e590d4e6SAurelien Jarno temps[src].state = TCG_TEMP_COPY; 14822613af4SKirill Batuzov temps[src].next_copy = src; 14922613af4SKirill Batuzov temps[src].prev_copy = src; 15022613af4SKirill Batuzov } 15122613af4SKirill Batuzov temps[dst].state = TCG_TEMP_COPY; 15222613af4SKirill Batuzov temps[dst].next_copy = temps[src].next_copy; 15322613af4SKirill Batuzov temps[dst].prev_copy = src; 15422613af4SKirill Batuzov temps[temps[dst].next_copy].prev_copy = dst; 15522613af4SKirill Batuzov temps[src].next_copy = dst; 15622613af4SKirill Batuzov } 157e590d4e6SAurelien Jarno 15822613af4SKirill Batuzov gen_args[0] = dst; 15922613af4SKirill Batuzov gen_args[1] = src; 16022613af4SKirill Batuzov } 16122613af4SKirill Batuzov 162e590d4e6SAurelien Jarno static void tcg_opt_gen_movi(TCGArg *gen_args, TCGArg dst, TCGArg val) 16322613af4SKirill Batuzov { 164e590d4e6SAurelien Jarno reset_temp(dst); 16522613af4SKirill Batuzov temps[dst].state = TCG_TEMP_CONST; 16622613af4SKirill Batuzov temps[dst].val = val; 16722613af4SKirill Batuzov gen_args[0] = dst; 16822613af4SKirill Batuzov gen_args[1] = val; 16922613af4SKirill Batuzov } 17022613af4SKirill Batuzov 171fe0de7aaSBlue Swirl static TCGOpcode op_to_mov(TCGOpcode op) 17253108fb5SKirill Batuzov { 17353108fb5SKirill Batuzov switch (op_bits(op)) { 17453108fb5SKirill Batuzov case 32: 17553108fb5SKirill Batuzov return INDEX_op_mov_i32; 17653108fb5SKirill Batuzov case 64: 17753108fb5SKirill Batuzov return INDEX_op_mov_i64; 17853108fb5SKirill Batuzov default: 17953108fb5SKirill Batuzov fprintf(stderr, "op_to_mov: unexpected return value of " 18053108fb5SKirill Batuzov "function op_bits.\n"); 18153108fb5SKirill Batuzov tcg_abort(); 18253108fb5SKirill Batuzov } 18353108fb5SKirill Batuzov } 18453108fb5SKirill Batuzov 185fe0de7aaSBlue Swirl static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y) 18653108fb5SKirill Batuzov { 18753108fb5SKirill Batuzov switch (op) { 18853108fb5SKirill Batuzov CASE_OP_32_64(add): 18953108fb5SKirill Batuzov return x + y; 19053108fb5SKirill Batuzov 19153108fb5SKirill Batuzov CASE_OP_32_64(sub): 19253108fb5SKirill Batuzov return x - y; 19353108fb5SKirill Batuzov 19453108fb5SKirill Batuzov CASE_OP_32_64(mul): 19553108fb5SKirill Batuzov return x * y; 19653108fb5SKirill Batuzov 1979a81090bSKirill Batuzov CASE_OP_32_64(and): 1989a81090bSKirill Batuzov return x & y; 1999a81090bSKirill Batuzov 2009a81090bSKirill Batuzov CASE_OP_32_64(or): 2019a81090bSKirill Batuzov return x | y; 2029a81090bSKirill Batuzov 2039a81090bSKirill Batuzov CASE_OP_32_64(xor): 2049a81090bSKirill Batuzov return x ^ y; 2059a81090bSKirill Batuzov 20655c0975cSKirill Batuzov case INDEX_op_shl_i32: 20755c0975cSKirill Batuzov return (uint32_t)x << (uint32_t)y; 20855c0975cSKirill Batuzov 20955c0975cSKirill Batuzov case INDEX_op_shl_i64: 21055c0975cSKirill Batuzov return (uint64_t)x << (uint64_t)y; 21155c0975cSKirill Batuzov 21255c0975cSKirill Batuzov case INDEX_op_shr_i32: 21355c0975cSKirill Batuzov return (uint32_t)x >> (uint32_t)y; 21455c0975cSKirill Batuzov 21555c0975cSKirill Batuzov case INDEX_op_shr_i64: 21655c0975cSKirill Batuzov return (uint64_t)x >> (uint64_t)y; 21755c0975cSKirill Batuzov 21855c0975cSKirill Batuzov case INDEX_op_sar_i32: 21955c0975cSKirill Batuzov return (int32_t)x >> (int32_t)y; 22055c0975cSKirill Batuzov 22155c0975cSKirill Batuzov case INDEX_op_sar_i64: 22255c0975cSKirill Batuzov return (int64_t)x >> (int64_t)y; 22355c0975cSKirill Batuzov 22455c0975cSKirill Batuzov case INDEX_op_rotr_i32: 22525c4d9ccSRichard Henderson x = ((uint32_t)x << (32 - y)) | ((uint32_t)x >> y); 22655c0975cSKirill Batuzov return x; 22755c0975cSKirill Batuzov 22855c0975cSKirill Batuzov case INDEX_op_rotr_i64: 22925c4d9ccSRichard Henderson x = ((uint64_t)x << (64 - y)) | ((uint64_t)x >> y); 23055c0975cSKirill Batuzov return x; 23155c0975cSKirill Batuzov 23255c0975cSKirill Batuzov case INDEX_op_rotl_i32: 23325c4d9ccSRichard Henderson x = ((uint32_t)x << y) | ((uint32_t)x >> (32 - y)); 23455c0975cSKirill Batuzov return x; 23555c0975cSKirill Batuzov 23655c0975cSKirill Batuzov case INDEX_op_rotl_i64: 23725c4d9ccSRichard Henderson x = ((uint64_t)x << y) | ((uint64_t)x >> (64 - y)); 23855c0975cSKirill Batuzov return x; 23955c0975cSKirill Batuzov 24025c4d9ccSRichard Henderson CASE_OP_32_64(not): 241a640f031SKirill Batuzov return ~x; 242a640f031SKirill Batuzov 243cb25c80aSRichard Henderson CASE_OP_32_64(neg): 244cb25c80aSRichard Henderson return -x; 245cb25c80aSRichard Henderson 246cb25c80aSRichard Henderson CASE_OP_32_64(andc): 247cb25c80aSRichard Henderson return x & ~y; 248cb25c80aSRichard Henderson 249cb25c80aSRichard Henderson CASE_OP_32_64(orc): 250cb25c80aSRichard Henderson return x | ~y; 251cb25c80aSRichard Henderson 252cb25c80aSRichard Henderson CASE_OP_32_64(eqv): 253cb25c80aSRichard Henderson return ~(x ^ y); 254cb25c80aSRichard Henderson 255cb25c80aSRichard Henderson CASE_OP_32_64(nand): 256cb25c80aSRichard Henderson return ~(x & y); 257cb25c80aSRichard Henderson 258cb25c80aSRichard Henderson CASE_OP_32_64(nor): 259cb25c80aSRichard Henderson return ~(x | y); 260cb25c80aSRichard Henderson 26125c4d9ccSRichard Henderson CASE_OP_32_64(ext8s): 262a640f031SKirill Batuzov return (int8_t)x; 263a640f031SKirill Batuzov 26425c4d9ccSRichard Henderson CASE_OP_32_64(ext16s): 265a640f031SKirill Batuzov return (int16_t)x; 266a640f031SKirill Batuzov 26725c4d9ccSRichard Henderson CASE_OP_32_64(ext8u): 268a640f031SKirill Batuzov return (uint8_t)x; 269a640f031SKirill Batuzov 27025c4d9ccSRichard Henderson CASE_OP_32_64(ext16u): 271a640f031SKirill Batuzov return (uint16_t)x; 272a640f031SKirill Batuzov 273a640f031SKirill Batuzov case INDEX_op_ext32s_i64: 274a640f031SKirill Batuzov return (int32_t)x; 275a640f031SKirill Batuzov 276a640f031SKirill Batuzov case INDEX_op_ext32u_i64: 277a640f031SKirill Batuzov return (uint32_t)x; 278a640f031SKirill Batuzov 27953108fb5SKirill Batuzov default: 28053108fb5SKirill Batuzov fprintf(stderr, 28153108fb5SKirill Batuzov "Unrecognized operation %d in do_constant_folding.\n", op); 28253108fb5SKirill Batuzov tcg_abort(); 28353108fb5SKirill Batuzov } 28453108fb5SKirill Batuzov } 28553108fb5SKirill Batuzov 286fe0de7aaSBlue Swirl static TCGArg do_constant_folding(TCGOpcode op, TCGArg x, TCGArg y) 28753108fb5SKirill Batuzov { 28853108fb5SKirill Batuzov TCGArg res = do_constant_folding_2(op, x, y); 28953108fb5SKirill Batuzov if (op_bits(op) == 32) { 29053108fb5SKirill Batuzov res &= 0xffffffff; 29153108fb5SKirill Batuzov } 29253108fb5SKirill Batuzov return res; 29353108fb5SKirill Batuzov } 29453108fb5SKirill Batuzov 295f8dd19e5SAurelien Jarno static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x, 296f8dd19e5SAurelien Jarno TCGArg y, TCGCond c) 297f8dd19e5SAurelien Jarno { 298f8dd19e5SAurelien Jarno switch (op_bits(op)) { 299f8dd19e5SAurelien Jarno case 32: 300f8dd19e5SAurelien Jarno switch (c) { 301f8dd19e5SAurelien Jarno case TCG_COND_EQ: 302f8dd19e5SAurelien Jarno return (uint32_t)x == (uint32_t)y; 303f8dd19e5SAurelien Jarno case TCG_COND_NE: 304f8dd19e5SAurelien Jarno return (uint32_t)x != (uint32_t)y; 305f8dd19e5SAurelien Jarno case TCG_COND_LT: 306f8dd19e5SAurelien Jarno return (int32_t)x < (int32_t)y; 307f8dd19e5SAurelien Jarno case TCG_COND_GE: 308f8dd19e5SAurelien Jarno return (int32_t)x >= (int32_t)y; 309f8dd19e5SAurelien Jarno case TCG_COND_LE: 310f8dd19e5SAurelien Jarno return (int32_t)x <= (int32_t)y; 311f8dd19e5SAurelien Jarno case TCG_COND_GT: 312f8dd19e5SAurelien Jarno return (int32_t)x > (int32_t)y; 313f8dd19e5SAurelien Jarno case TCG_COND_LTU: 314f8dd19e5SAurelien Jarno return (uint32_t)x < (uint32_t)y; 315f8dd19e5SAurelien Jarno case TCG_COND_GEU: 316f8dd19e5SAurelien Jarno return (uint32_t)x >= (uint32_t)y; 317f8dd19e5SAurelien Jarno case TCG_COND_LEU: 318f8dd19e5SAurelien Jarno return (uint32_t)x <= (uint32_t)y; 319f8dd19e5SAurelien Jarno case TCG_COND_GTU: 320f8dd19e5SAurelien Jarno return (uint32_t)x > (uint32_t)y; 321f8dd19e5SAurelien Jarno } 322f8dd19e5SAurelien Jarno break; 323f8dd19e5SAurelien Jarno case 64: 324f8dd19e5SAurelien Jarno switch (c) { 325f8dd19e5SAurelien Jarno case TCG_COND_EQ: 326f8dd19e5SAurelien Jarno return (uint64_t)x == (uint64_t)y; 327f8dd19e5SAurelien Jarno case TCG_COND_NE: 328f8dd19e5SAurelien Jarno return (uint64_t)x != (uint64_t)y; 329f8dd19e5SAurelien Jarno case TCG_COND_LT: 330f8dd19e5SAurelien Jarno return (int64_t)x < (int64_t)y; 331f8dd19e5SAurelien Jarno case TCG_COND_GE: 332f8dd19e5SAurelien Jarno return (int64_t)x >= (int64_t)y; 333f8dd19e5SAurelien Jarno case TCG_COND_LE: 334f8dd19e5SAurelien Jarno return (int64_t)x <= (int64_t)y; 335f8dd19e5SAurelien Jarno case TCG_COND_GT: 336f8dd19e5SAurelien Jarno return (int64_t)x > (int64_t)y; 337f8dd19e5SAurelien Jarno case TCG_COND_LTU: 338f8dd19e5SAurelien Jarno return (uint64_t)x < (uint64_t)y; 339f8dd19e5SAurelien Jarno case TCG_COND_GEU: 340f8dd19e5SAurelien Jarno return (uint64_t)x >= (uint64_t)y; 341f8dd19e5SAurelien Jarno case TCG_COND_LEU: 342f8dd19e5SAurelien Jarno return (uint64_t)x <= (uint64_t)y; 343f8dd19e5SAurelien Jarno case TCG_COND_GTU: 344f8dd19e5SAurelien Jarno return (uint64_t)x > (uint64_t)y; 345f8dd19e5SAurelien Jarno } 346f8dd19e5SAurelien Jarno break; 347f8dd19e5SAurelien Jarno } 348f8dd19e5SAurelien Jarno 349f8dd19e5SAurelien Jarno fprintf(stderr, 350f8dd19e5SAurelien Jarno "Unrecognized bitness %d or condition %d in " 351f8dd19e5SAurelien Jarno "do_constant_folding_cond.\n", op_bits(op), c); 352f8dd19e5SAurelien Jarno tcg_abort(); 353f8dd19e5SAurelien Jarno } 354f8dd19e5SAurelien Jarno 35522613af4SKirill Batuzov /* Propagate constants and copies, fold constant expressions. */ 3568f2e8c07SKirill Batuzov static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, 3578f2e8c07SKirill Batuzov TCGArg *args, TCGOpDef *tcg_op_defs) 3588f2e8c07SKirill Batuzov { 359fe0de7aaSBlue Swirl int i, nb_ops, op_index, nb_temps, nb_globals, nb_call_args; 360fe0de7aaSBlue Swirl TCGOpcode op; 3618f2e8c07SKirill Batuzov const TCGOpDef *def; 3628f2e8c07SKirill Batuzov TCGArg *gen_args; 36353108fb5SKirill Batuzov TCGArg tmp; 3645d8f5363SRichard Henderson TCGCond cond; 3655d8f5363SRichard Henderson 36622613af4SKirill Batuzov /* Array VALS has an element for each temp. 36722613af4SKirill Batuzov If this temp holds a constant then its value is kept in VALS' element. 368e590d4e6SAurelien Jarno If this temp is a copy of other ones then the other copies are 369e590d4e6SAurelien Jarno available through the doubly linked circular list. */ 3708f2e8c07SKirill Batuzov 3718f2e8c07SKirill Batuzov nb_temps = s->nb_temps; 3728f2e8c07SKirill Batuzov nb_globals = s->nb_globals; 37322613af4SKirill Batuzov memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info)); 3748f2e8c07SKirill Batuzov 3758f2e8c07SKirill Batuzov nb_ops = tcg_opc_ptr - gen_opc_buf; 3768f2e8c07SKirill Batuzov gen_args = args; 3778f2e8c07SKirill Batuzov for (op_index = 0; op_index < nb_ops; op_index++) { 3788f2e8c07SKirill Batuzov op = gen_opc_buf[op_index]; 3798f2e8c07SKirill Batuzov def = &tcg_op_defs[op]; 38022613af4SKirill Batuzov /* Do copy propagation */ 3811ff8c541SAurelien Jarno if (op == INDEX_op_call) { 3821ff8c541SAurelien Jarno int nb_oargs = args[0] >> 16; 3831ff8c541SAurelien Jarno int nb_iargs = args[0] & 0xffff; 3841ff8c541SAurelien Jarno for (i = nb_oargs + 1; i < nb_oargs + nb_iargs + 1; i++) { 3851ff8c541SAurelien Jarno if (temps[args[i]].state == TCG_TEMP_COPY) { 3861ff8c541SAurelien Jarno args[i] = find_better_copy(s, args[i]); 3871ff8c541SAurelien Jarno } 3881ff8c541SAurelien Jarno } 3891ff8c541SAurelien Jarno } else { 39022613af4SKirill Batuzov for (i = def->nb_oargs; i < def->nb_oargs + def->nb_iargs; i++) { 39122613af4SKirill Batuzov if (temps[args[i]].state == TCG_TEMP_COPY) { 392e590d4e6SAurelien Jarno args[i] = find_better_copy(s, args[i]); 39322613af4SKirill Batuzov } 39422613af4SKirill Batuzov } 39522613af4SKirill Batuzov } 39622613af4SKirill Batuzov 39753108fb5SKirill Batuzov /* For commutative operations make constant second argument */ 39853108fb5SKirill Batuzov switch (op) { 39953108fb5SKirill Batuzov CASE_OP_32_64(add): 40053108fb5SKirill Batuzov CASE_OP_32_64(mul): 4019a81090bSKirill Batuzov CASE_OP_32_64(and): 4029a81090bSKirill Batuzov CASE_OP_32_64(or): 4039a81090bSKirill Batuzov CASE_OP_32_64(xor): 404cb25c80aSRichard Henderson CASE_OP_32_64(eqv): 405cb25c80aSRichard Henderson CASE_OP_32_64(nand): 406cb25c80aSRichard Henderson CASE_OP_32_64(nor): 40753108fb5SKirill Batuzov if (temps[args[1]].state == TCG_TEMP_CONST) { 40853108fb5SKirill Batuzov tmp = args[1]; 40953108fb5SKirill Batuzov args[1] = args[2]; 41053108fb5SKirill Batuzov args[2] = tmp; 41153108fb5SKirill Batuzov } 41253108fb5SKirill Batuzov break; 41365a7cce1SAurelien Jarno CASE_OP_32_64(brcond): 41465a7cce1SAurelien Jarno if (temps[args[0]].state == TCG_TEMP_CONST 41565a7cce1SAurelien Jarno && temps[args[1]].state != TCG_TEMP_CONST) { 41665a7cce1SAurelien Jarno tmp = args[0]; 41765a7cce1SAurelien Jarno args[0] = args[1]; 41865a7cce1SAurelien Jarno args[1] = tmp; 41965a7cce1SAurelien Jarno args[2] = tcg_swap_cond(args[2]); 42065a7cce1SAurelien Jarno } 42165a7cce1SAurelien Jarno break; 42265a7cce1SAurelien Jarno CASE_OP_32_64(setcond): 42365a7cce1SAurelien Jarno if (temps[args[1]].state == TCG_TEMP_CONST 42465a7cce1SAurelien Jarno && temps[args[2]].state != TCG_TEMP_CONST) { 42565a7cce1SAurelien Jarno tmp = args[1]; 42665a7cce1SAurelien Jarno args[1] = args[2]; 42765a7cce1SAurelien Jarno args[2] = tmp; 42865a7cce1SAurelien Jarno args[3] = tcg_swap_cond(args[3]); 42965a7cce1SAurelien Jarno } 43065a7cce1SAurelien Jarno break; 431fa01a208SRichard Henderson CASE_OP_32_64(movcond): 4325d8f5363SRichard Henderson cond = args[5]; 433fa01a208SRichard Henderson if (temps[args[1]].state == TCG_TEMP_CONST 434fa01a208SRichard Henderson && temps[args[2]].state != TCG_TEMP_CONST) { 435fa01a208SRichard Henderson tmp = args[1]; 436fa01a208SRichard Henderson args[1] = args[2]; 437fa01a208SRichard Henderson args[2] = tmp; 4385d8f5363SRichard Henderson cond = tcg_swap_cond(cond); 439fa01a208SRichard Henderson } 4405d8f5363SRichard Henderson /* For movcond, we canonicalize the "false" input reg to match 4415d8f5363SRichard Henderson the destination reg so that the tcg backend can implement 4425d8f5363SRichard Henderson a "move if true" operation. */ 4435d8f5363SRichard Henderson if (args[0] == args[3]) { 4445d8f5363SRichard Henderson tmp = args[3]; 4455d8f5363SRichard Henderson args[3] = args[4]; 4465d8f5363SRichard Henderson args[4] = tmp; 4475d8f5363SRichard Henderson cond = tcg_invert_cond(cond); 4485d8f5363SRichard Henderson } 4495d8f5363SRichard Henderson args[5] = cond; 45053108fb5SKirill Batuzov default: 45153108fb5SKirill Batuzov break; 45253108fb5SKirill Batuzov } 45353108fb5SKirill Batuzov 45401ee5282SAurelien Jarno /* Simplify expressions for "shift/rot r, 0, a => movi r, 0" */ 45501ee5282SAurelien Jarno switch (op) { 45601ee5282SAurelien Jarno CASE_OP_32_64(shl): 45701ee5282SAurelien Jarno CASE_OP_32_64(shr): 45801ee5282SAurelien Jarno CASE_OP_32_64(sar): 45901ee5282SAurelien Jarno CASE_OP_32_64(rotl): 46001ee5282SAurelien Jarno CASE_OP_32_64(rotr): 46101ee5282SAurelien Jarno if (temps[args[1]].state == TCG_TEMP_CONST 46201ee5282SAurelien Jarno && temps[args[1]].val == 0) { 46301ee5282SAurelien Jarno gen_opc_buf[op_index] = op_to_movi(op); 464e590d4e6SAurelien Jarno tcg_opt_gen_movi(gen_args, args[0], 0); 46501ee5282SAurelien Jarno args += 3; 46601ee5282SAurelien Jarno gen_args += 2; 46701ee5282SAurelien Jarno continue; 46801ee5282SAurelien Jarno } 46901ee5282SAurelien Jarno break; 47001ee5282SAurelien Jarno default: 47101ee5282SAurelien Jarno break; 47201ee5282SAurelien Jarno } 47301ee5282SAurelien Jarno 47456e49438SAurelien Jarno /* Simplify expression for "op r, a, 0 => mov r, a" cases */ 47553108fb5SKirill Batuzov switch (op) { 47653108fb5SKirill Batuzov CASE_OP_32_64(add): 47753108fb5SKirill Batuzov CASE_OP_32_64(sub): 47855c0975cSKirill Batuzov CASE_OP_32_64(shl): 47955c0975cSKirill Batuzov CASE_OP_32_64(shr): 48055c0975cSKirill Batuzov CASE_OP_32_64(sar): 48125c4d9ccSRichard Henderson CASE_OP_32_64(rotl): 48225c4d9ccSRichard Henderson CASE_OP_32_64(rotr): 48338ee188bSAurelien Jarno CASE_OP_32_64(or): 48438ee188bSAurelien Jarno CASE_OP_32_64(xor): 48553108fb5SKirill Batuzov if (temps[args[1]].state == TCG_TEMP_CONST) { 48653108fb5SKirill Batuzov /* Proceed with possible constant folding. */ 48753108fb5SKirill Batuzov break; 48853108fb5SKirill Batuzov } 48953108fb5SKirill Batuzov if (temps[args[2]].state == TCG_TEMP_CONST 49053108fb5SKirill Batuzov && temps[args[2]].val == 0) { 491e590d4e6SAurelien Jarno if (temps_are_copies(args[0], args[1])) { 49253108fb5SKirill Batuzov gen_opc_buf[op_index] = INDEX_op_nop; 49353108fb5SKirill Batuzov } else { 49453108fb5SKirill Batuzov gen_opc_buf[op_index] = op_to_mov(op); 495b80bb016SAurelien Jarno tcg_opt_gen_mov(s, gen_args, args[0], args[1]); 49653108fb5SKirill Batuzov gen_args += 2; 49753108fb5SKirill Batuzov } 498fedc0da2SAurelien Jarno args += 3; 49953108fb5SKirill Batuzov continue; 50053108fb5SKirill Batuzov } 50153108fb5SKirill Batuzov break; 50256e49438SAurelien Jarno default: 50356e49438SAurelien Jarno break; 50456e49438SAurelien Jarno } 50556e49438SAurelien Jarno 50656e49438SAurelien Jarno /* Simplify expression for "op r, a, 0 => movi r, 0" cases */ 50756e49438SAurelien Jarno switch (op) { 50861251c0cSAurelien Jarno CASE_OP_32_64(and): 50953108fb5SKirill Batuzov CASE_OP_32_64(mul): 51053108fb5SKirill Batuzov if ((temps[args[2]].state == TCG_TEMP_CONST 51153108fb5SKirill Batuzov && temps[args[2]].val == 0)) { 51253108fb5SKirill Batuzov gen_opc_buf[op_index] = op_to_movi(op); 513e590d4e6SAurelien Jarno tcg_opt_gen_movi(gen_args, args[0], 0); 51453108fb5SKirill Batuzov args += 3; 51553108fb5SKirill Batuzov gen_args += 2; 51653108fb5SKirill Batuzov continue; 51753108fb5SKirill Batuzov } 51853108fb5SKirill Batuzov break; 51956e49438SAurelien Jarno default: 52056e49438SAurelien Jarno break; 52156e49438SAurelien Jarno } 52256e49438SAurelien Jarno 52356e49438SAurelien Jarno /* Simplify expression for "op r, a, a => mov r, a" cases */ 52456e49438SAurelien Jarno switch (op) { 5259a81090bSKirill Batuzov CASE_OP_32_64(or): 5269a81090bSKirill Batuzov CASE_OP_32_64(and): 5270aba1c73SAurelien Jarno if (temps_are_copies(args[1], args[2])) { 528e590d4e6SAurelien Jarno if (temps_are_copies(args[0], args[1])) { 5299a81090bSKirill Batuzov gen_opc_buf[op_index] = INDEX_op_nop; 5309a81090bSKirill Batuzov } else { 5319a81090bSKirill Batuzov gen_opc_buf[op_index] = op_to_mov(op); 532b80bb016SAurelien Jarno tcg_opt_gen_mov(s, gen_args, args[0], args[1]); 5339a81090bSKirill Batuzov gen_args += 2; 5349a81090bSKirill Batuzov } 535fedc0da2SAurelien Jarno args += 3; 5369a81090bSKirill Batuzov continue; 5379a81090bSKirill Batuzov } 5389a81090bSKirill Batuzov break; 539fe0de7aaSBlue Swirl default: 540fe0de7aaSBlue Swirl break; 54153108fb5SKirill Batuzov } 54253108fb5SKirill Batuzov 543*3c94193eSAurelien Jarno /* Simplify expression for "op r, a, a => movi r, 0" cases */ 544*3c94193eSAurelien Jarno switch (op) { 545*3c94193eSAurelien Jarno CASE_OP_32_64(sub): 546*3c94193eSAurelien Jarno CASE_OP_32_64(xor): 547*3c94193eSAurelien Jarno if (temps_are_copies(args[1], args[2])) { 548*3c94193eSAurelien Jarno gen_opc_buf[op_index] = op_to_movi(op); 549*3c94193eSAurelien Jarno tcg_opt_gen_movi(gen_args, args[0], 0); 550*3c94193eSAurelien Jarno gen_args += 2; 551*3c94193eSAurelien Jarno args += 3; 552*3c94193eSAurelien Jarno continue; 553*3c94193eSAurelien Jarno } 554*3c94193eSAurelien Jarno break; 555*3c94193eSAurelien Jarno default: 556*3c94193eSAurelien Jarno break; 557*3c94193eSAurelien Jarno } 558*3c94193eSAurelien Jarno 55922613af4SKirill Batuzov /* Propagate constants through copy operations and do constant 56022613af4SKirill Batuzov folding. Constants will be substituted to arguments by register 56122613af4SKirill Batuzov allocator where needed and possible. Also detect copies. */ 5628f2e8c07SKirill Batuzov switch (op) { 56322613af4SKirill Batuzov CASE_OP_32_64(mov): 564e590d4e6SAurelien Jarno if (temps_are_copies(args[0], args[1])) { 56522613af4SKirill Batuzov args += 2; 56622613af4SKirill Batuzov gen_opc_buf[op_index] = INDEX_op_nop; 56722613af4SKirill Batuzov break; 56822613af4SKirill Batuzov } 56922613af4SKirill Batuzov if (temps[args[1]].state != TCG_TEMP_CONST) { 570b80bb016SAurelien Jarno tcg_opt_gen_mov(s, gen_args, args[0], args[1]); 57122613af4SKirill Batuzov gen_args += 2; 57222613af4SKirill Batuzov args += 2; 57322613af4SKirill Batuzov break; 57422613af4SKirill Batuzov } 57522613af4SKirill Batuzov /* Source argument is constant. Rewrite the operation and 57622613af4SKirill Batuzov let movi case handle it. */ 57722613af4SKirill Batuzov op = op_to_movi(op); 57822613af4SKirill Batuzov gen_opc_buf[op_index] = op; 57922613af4SKirill Batuzov args[1] = temps[args[1]].val; 58022613af4SKirill Batuzov /* fallthrough */ 58122613af4SKirill Batuzov CASE_OP_32_64(movi): 582e590d4e6SAurelien Jarno tcg_opt_gen_movi(gen_args, args[0], args[1]); 58322613af4SKirill Batuzov gen_args += 2; 58422613af4SKirill Batuzov args += 2; 58522613af4SKirill Batuzov break; 586a640f031SKirill Batuzov CASE_OP_32_64(not): 587cb25c80aSRichard Henderson CASE_OP_32_64(neg): 58825c4d9ccSRichard Henderson CASE_OP_32_64(ext8s): 58925c4d9ccSRichard Henderson CASE_OP_32_64(ext8u): 59025c4d9ccSRichard Henderson CASE_OP_32_64(ext16s): 59125c4d9ccSRichard Henderson CASE_OP_32_64(ext16u): 592a640f031SKirill Batuzov case INDEX_op_ext32s_i64: 593a640f031SKirill Batuzov case INDEX_op_ext32u_i64: 594a640f031SKirill Batuzov if (temps[args[1]].state == TCG_TEMP_CONST) { 595a640f031SKirill Batuzov gen_opc_buf[op_index] = op_to_movi(op); 596a640f031SKirill Batuzov tmp = do_constant_folding(op, temps[args[1]].val, 0); 597e590d4e6SAurelien Jarno tcg_opt_gen_movi(gen_args, args[0], tmp); 598a640f031SKirill Batuzov } else { 599e590d4e6SAurelien Jarno reset_temp(args[0]); 600a640f031SKirill Batuzov gen_args[0] = args[0]; 601a640f031SKirill Batuzov gen_args[1] = args[1]; 602fedc0da2SAurelien Jarno } 603a640f031SKirill Batuzov gen_args += 2; 604a640f031SKirill Batuzov args += 2; 605a640f031SKirill Batuzov break; 60653108fb5SKirill Batuzov CASE_OP_32_64(add): 60753108fb5SKirill Batuzov CASE_OP_32_64(sub): 60853108fb5SKirill Batuzov CASE_OP_32_64(mul): 6099a81090bSKirill Batuzov CASE_OP_32_64(or): 6109a81090bSKirill Batuzov CASE_OP_32_64(and): 6119a81090bSKirill Batuzov CASE_OP_32_64(xor): 61255c0975cSKirill Batuzov CASE_OP_32_64(shl): 61355c0975cSKirill Batuzov CASE_OP_32_64(shr): 61455c0975cSKirill Batuzov CASE_OP_32_64(sar): 61525c4d9ccSRichard Henderson CASE_OP_32_64(rotl): 61625c4d9ccSRichard Henderson CASE_OP_32_64(rotr): 617cb25c80aSRichard Henderson CASE_OP_32_64(andc): 618cb25c80aSRichard Henderson CASE_OP_32_64(orc): 619cb25c80aSRichard Henderson CASE_OP_32_64(eqv): 620cb25c80aSRichard Henderson CASE_OP_32_64(nand): 621cb25c80aSRichard Henderson CASE_OP_32_64(nor): 62253108fb5SKirill Batuzov if (temps[args[1]].state == TCG_TEMP_CONST 62353108fb5SKirill Batuzov && temps[args[2]].state == TCG_TEMP_CONST) { 62453108fb5SKirill Batuzov gen_opc_buf[op_index] = op_to_movi(op); 62553108fb5SKirill Batuzov tmp = do_constant_folding(op, temps[args[1]].val, 62653108fb5SKirill Batuzov temps[args[2]].val); 627e590d4e6SAurelien Jarno tcg_opt_gen_movi(gen_args, args[0], tmp); 62853108fb5SKirill Batuzov gen_args += 2; 62953108fb5SKirill Batuzov } else { 630e590d4e6SAurelien Jarno reset_temp(args[0]); 63153108fb5SKirill Batuzov gen_args[0] = args[0]; 63253108fb5SKirill Batuzov gen_args[1] = args[1]; 63353108fb5SKirill Batuzov gen_args[2] = args[2]; 63453108fb5SKirill Batuzov gen_args += 3; 635fedc0da2SAurelien Jarno } 63653108fb5SKirill Batuzov args += 3; 63753108fb5SKirill Batuzov break; 638f8dd19e5SAurelien Jarno CASE_OP_32_64(setcond): 639f8dd19e5SAurelien Jarno if (temps[args[1]].state == TCG_TEMP_CONST 640f8dd19e5SAurelien Jarno && temps[args[2]].state == TCG_TEMP_CONST) { 641f8dd19e5SAurelien Jarno gen_opc_buf[op_index] = op_to_movi(op); 642f8dd19e5SAurelien Jarno tmp = do_constant_folding_cond(op, temps[args[1]].val, 643f8dd19e5SAurelien Jarno temps[args[2]].val, args[3]); 644e590d4e6SAurelien Jarno tcg_opt_gen_movi(gen_args, args[0], tmp); 645f8dd19e5SAurelien Jarno gen_args += 2; 646f8dd19e5SAurelien Jarno } else { 647e590d4e6SAurelien Jarno reset_temp(args[0]); 648f8dd19e5SAurelien Jarno gen_args[0] = args[0]; 649f8dd19e5SAurelien Jarno gen_args[1] = args[1]; 650f8dd19e5SAurelien Jarno gen_args[2] = args[2]; 651f8dd19e5SAurelien Jarno gen_args[3] = args[3]; 652f8dd19e5SAurelien Jarno gen_args += 4; 653fedc0da2SAurelien Jarno } 654f8dd19e5SAurelien Jarno args += 4; 655f8dd19e5SAurelien Jarno break; 656fbeaa26cSAurelien Jarno CASE_OP_32_64(brcond): 657fbeaa26cSAurelien Jarno if (temps[args[0]].state == TCG_TEMP_CONST 658fbeaa26cSAurelien Jarno && temps[args[1]].state == TCG_TEMP_CONST) { 659fbeaa26cSAurelien Jarno if (do_constant_folding_cond(op, temps[args[0]].val, 660fbeaa26cSAurelien Jarno temps[args[1]].val, args[2])) { 661fbeaa26cSAurelien Jarno memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info)); 662fbeaa26cSAurelien Jarno gen_opc_buf[op_index] = INDEX_op_br; 663fbeaa26cSAurelien Jarno gen_args[0] = args[3]; 664fbeaa26cSAurelien Jarno gen_args += 1; 665fbeaa26cSAurelien Jarno } else { 666fbeaa26cSAurelien Jarno gen_opc_buf[op_index] = INDEX_op_nop; 667fbeaa26cSAurelien Jarno } 668fbeaa26cSAurelien Jarno } else { 669fbeaa26cSAurelien Jarno memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info)); 670e590d4e6SAurelien Jarno reset_temp(args[0]); 671fbeaa26cSAurelien Jarno gen_args[0] = args[0]; 672fbeaa26cSAurelien Jarno gen_args[1] = args[1]; 673fbeaa26cSAurelien Jarno gen_args[2] = args[2]; 674fbeaa26cSAurelien Jarno gen_args[3] = args[3]; 675fbeaa26cSAurelien Jarno gen_args += 4; 676fedc0da2SAurelien Jarno } 677fbeaa26cSAurelien Jarno args += 4; 678fbeaa26cSAurelien Jarno break; 679fa01a208SRichard Henderson CASE_OP_32_64(movcond): 680fa01a208SRichard Henderson if (temps[args[1]].state == TCG_TEMP_CONST 681fa01a208SRichard Henderson && temps[args[2]].state == TCG_TEMP_CONST) { 682fa01a208SRichard Henderson tmp = do_constant_folding_cond(op, temps[args[1]].val, 683fa01a208SRichard Henderson temps[args[2]].val, args[5]); 684e590d4e6SAurelien Jarno if (temps_are_copies(args[0], args[4-tmp])) { 685fa01a208SRichard Henderson gen_opc_buf[op_index] = INDEX_op_nop; 686fa01a208SRichard Henderson } else if (temps[args[4-tmp]].state == TCG_TEMP_CONST) { 687fa01a208SRichard Henderson gen_opc_buf[op_index] = op_to_movi(op); 688e590d4e6SAurelien Jarno tcg_opt_gen_movi(gen_args, args[0], temps[args[4-tmp]].val); 689fa01a208SRichard Henderson gen_args += 2; 690fa01a208SRichard Henderson } else { 691fa01a208SRichard Henderson gen_opc_buf[op_index] = op_to_mov(op); 692e590d4e6SAurelien Jarno tcg_opt_gen_mov(s, gen_args, args[0], args[4-tmp]); 693fa01a208SRichard Henderson gen_args += 2; 694fa01a208SRichard Henderson } 695fa01a208SRichard Henderson } else { 696e590d4e6SAurelien Jarno reset_temp(args[0]); 697fa01a208SRichard Henderson gen_args[0] = args[0]; 698fa01a208SRichard Henderson gen_args[1] = args[1]; 699fa01a208SRichard Henderson gen_args[2] = args[2]; 700fa01a208SRichard Henderson gen_args[3] = args[3]; 701fa01a208SRichard Henderson gen_args[4] = args[4]; 702fa01a208SRichard Henderson gen_args[5] = args[5]; 703fa01a208SRichard Henderson gen_args += 6; 704fa01a208SRichard Henderson } 705fa01a208SRichard Henderson args += 6; 706fa01a208SRichard Henderson break; 7078f2e8c07SKirill Batuzov case INDEX_op_call: 70822613af4SKirill Batuzov nb_call_args = (args[0] >> 16) + (args[0] & 0xffff); 70922613af4SKirill Batuzov if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) { 71022613af4SKirill Batuzov for (i = 0; i < nb_globals; i++) { 711e590d4e6SAurelien Jarno reset_temp(i); 71222613af4SKirill Batuzov } 71322613af4SKirill Batuzov } 71422613af4SKirill Batuzov for (i = 0; i < (args[0] >> 16); i++) { 715e590d4e6SAurelien Jarno reset_temp(args[i + 1]); 71622613af4SKirill Batuzov } 71722613af4SKirill Batuzov i = nb_call_args + 3; 7188f2e8c07SKirill Batuzov while (i) { 7198f2e8c07SKirill Batuzov *gen_args = *args; 7208f2e8c07SKirill Batuzov args++; 7218f2e8c07SKirill Batuzov gen_args++; 7228f2e8c07SKirill Batuzov i--; 7238f2e8c07SKirill Batuzov } 7248f2e8c07SKirill Batuzov break; 7258f2e8c07SKirill Batuzov default: 72622613af4SKirill Batuzov /* Default case: we do know nothing about operation so no 727a2550660SAurelien Jarno propagation is done. We trash everything if the operation 728a2550660SAurelien Jarno is the end of a basic block, otherwise we only trash the 729a2550660SAurelien Jarno output args. */ 730a2550660SAurelien Jarno if (def->flags & TCG_OPF_BB_END) { 731a2550660SAurelien Jarno memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info)); 732a2550660SAurelien Jarno } else { 73322613af4SKirill Batuzov for (i = 0; i < def->nb_oargs; i++) { 734e590d4e6SAurelien Jarno reset_temp(args[i]); 73522613af4SKirill Batuzov } 736a2550660SAurelien Jarno } 7378f2e8c07SKirill Batuzov for (i = 0; i < def->nb_args; i++) { 7388f2e8c07SKirill Batuzov gen_args[i] = args[i]; 7398f2e8c07SKirill Batuzov } 7408f2e8c07SKirill Batuzov args += def->nb_args; 7418f2e8c07SKirill Batuzov gen_args += def->nb_args; 7428f2e8c07SKirill Batuzov break; 7438f2e8c07SKirill Batuzov } 7448f2e8c07SKirill Batuzov } 7458f2e8c07SKirill Batuzov 7468f2e8c07SKirill Batuzov return gen_args; 7478f2e8c07SKirill Batuzov } 7488f2e8c07SKirill Batuzov 7498f2e8c07SKirill Batuzov TCGArg *tcg_optimize(TCGContext *s, uint16_t *tcg_opc_ptr, 7508f2e8c07SKirill Batuzov TCGArg *args, TCGOpDef *tcg_op_defs) 7518f2e8c07SKirill Batuzov { 7528f2e8c07SKirill Batuzov TCGArg *res; 7538f2e8c07SKirill Batuzov res = tcg_constant_folding(s, tcg_opc_ptr, args, tcg_op_defs); 7548f2e8c07SKirill Batuzov return res; 7558f2e8c07SKirill Batuzov } 756