/*
 * Optimizations for Tiny Code Generator for QEMU
 *
 * Copyright (c) 2010 Samsung Electronics.
 * Contributed by Kirill Batuzov <batuzovk@ispras.ru>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "config.h"

#include <stdlib.h>
#include <stdio.h>

#include "qemu-common.h"
#include "tcg-op.h"

#define CASE_OP_32_64(x)                        \
        glue(glue(case INDEX_op_, x), _i32):    \
        glue(glue(case INDEX_op_, x), _i64)

typedef enum {
    TCG_TEMP_UNDEF = 0,
    TCG_TEMP_CONST,
    TCG_TEMP_COPY,
} tcg_temp_state;

struct tcg_temp_info {
    tcg_temp_state state;
    uint16_t prev_copy;
    uint16_t next_copy;
    tcg_target_ulong val;
    tcg_target_ulong mask;
};

static struct tcg_temp_info temps[TCG_MAX_TEMPS];

/* Reset TEMP's state to TCG_TEMP_UNDEF.  If TEMP only had one copy, remove
   the copy flag from the left temp.  */
static void reset_temp(TCGArg temp)
{
    if (temps[temp].state == TCG_TEMP_COPY) {
        if (temps[temp].prev_copy == temps[temp].next_copy) {
            temps[temps[temp].next_copy].state = TCG_TEMP_UNDEF;
        } else {
            temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy;
            temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy;
        }
    }
    temps[temp].state = TCG_TEMP_UNDEF;
    temps[temp].mask = -1;
}

/* Reset all temporaries, given that there are NB_TEMPS of them.  */
static void reset_all_temps(int nb_temps)
{
    int i;
    for (i = 0; i < nb_temps; i++) {
        temps[i].state = TCG_TEMP_UNDEF;
        temps[i].mask = -1;
    }
}

static int op_bits(TCGOpcode op)
{
    const TCGOpDef *def = &tcg_op_defs[op];
    return def->flags & TCG_OPF_64BIT ? 64 : 32;
}

static TCGOpcode op_to_movi(TCGOpcode op)
{
    switch (op_bits(op)) {
    case 32:
        return INDEX_op_movi_i32;
    case 64:
        return INDEX_op_movi_i64;
    default:
        fprintf(stderr, "op_to_movi: unexpected return value of "
                "function op_bits.\n");
        tcg_abort();
    }
}

static TCGArg find_better_copy(TCGContext *s, TCGArg temp)
{
    TCGArg i;

    /* If this is already a global, we can't do better. */
    if (temp < s->nb_globals) {
        return temp;
    }

    /* Search for a global first. */
    for (i = temps[temp].next_copy ; i != temp ; i = temps[i].next_copy) {
        if (i < s->nb_globals) {
            return i;
        }
    }

    /* If it is a temp, search for a temp local. */
    if (!s->temps[temp].temp_local) {
        for (i = temps[temp].next_copy ; i != temp ; i = temps[i].next_copy) {
            if (s->temps[i].temp_local) {
                return i;
            }
        }
    }

    /* Failure to find a better representation, return the same temp. */
    return temp;
}

static bool temps_are_copies(TCGArg arg1, TCGArg arg2)
{
    TCGArg i;

    if (arg1 == arg2) {
        return true;
    }

    if (temps[arg1].state != TCG_TEMP_COPY
        || temps[arg2].state != TCG_TEMP_COPY) {
        return false;
    }

    for (i = temps[arg1].next_copy ; i != arg1 ; i = temps[i].next_copy) {
        if (i == arg2) {
            return true;
        }
    }

    return false;
}

static void tcg_opt_gen_mov(TCGContext *s, TCGArg *gen_args,
                            TCGArg dst, TCGArg src)
{
    reset_temp(dst);
    temps[dst].mask = temps[src].mask;
    assert(temps[src].state != TCG_TEMP_CONST);

    if (s->temps[src].type == s->temps[dst].type) {
        if (temps[src].state != TCG_TEMP_COPY) {
            temps[src].state = TCG_TEMP_COPY;
            temps[src].next_copy = src;
            temps[src].prev_copy = src;
        }
        temps[dst].state = TCG_TEMP_COPY;
        temps[dst].next_copy = temps[src].next_copy;
        temps[dst].prev_copy = src;
        temps[temps[dst].next_copy].prev_copy = dst;
        temps[src].next_copy = dst;
    }

    gen_args[0] = dst;
    gen_args[1] = src;
}

static void tcg_opt_gen_movi(TCGArg *gen_args, TCGArg dst, TCGArg val)
{
    reset_temp(dst);
    temps[dst].state = TCG_TEMP_CONST;
    temps[dst].val = val;
    temps[dst].mask = val;
    gen_args[0] = dst;
    gen_args[1] = val;
}

static TCGOpcode op_to_mov(TCGOpcode op)
{
    switch (op_bits(op)) {
    case 32:
        return INDEX_op_mov_i32;
    case 64:
        return INDEX_op_mov_i64;
    default:
        fprintf(stderr, "op_to_mov: unexpected return value of "
                "function op_bits.\n");
        tcg_abort();
    }
}

static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y)
{
    uint64_t l64, h64;

    switch (op) {
    CASE_OP_32_64(add):
        return x + y;

    CASE_OP_32_64(sub):
        return x - y;

    CASE_OP_32_64(mul):
        return x * y;

    CASE_OP_32_64(and):
        return x & y;

    CASE_OP_32_64(or):
        return x | y;

    CASE_OP_32_64(xor):
        return x ^ y;

    case INDEX_op_shl_i32:
        return (uint32_t)x << (y & 31);

    case INDEX_op_shl_i64:
        return (uint64_t)x << (y & 63);

    case INDEX_op_shr_i32:
        return (uint32_t)x >> (y & 31);

    case INDEX_op_trunc_shr_i32:
    case INDEX_op_shr_i64:
        return (uint64_t)x >> (y & 63);

    case INDEX_op_sar_i32:
        return (int32_t)x >> (y & 31);

    case INDEX_op_sar_i64:
        return (int64_t)x >> (y & 63);

    case INDEX_op_rotr_i32:
        return ror32(x, y & 31);

    case INDEX_op_rotr_i64:
        return ror64(x, y & 63);

    case INDEX_op_rotl_i32:
        return rol32(x, y & 31);

    case INDEX_op_rotl_i64:
        return rol64(x, y & 63);

    CASE_OP_32_64(not):
        return ~x;

    CASE_OP_32_64(neg):
        return -x;

    CASE_OP_32_64(andc):
        return x & ~y;

    CASE_OP_32_64(orc):
        return x | ~y;

    CASE_OP_32_64(eqv):
        return ~(x ^ y);

    CASE_OP_32_64(nand):
        return ~(x & y);

    CASE_OP_32_64(nor):
        return ~(x | y);

    CASE_OP_32_64(ext8s):
        return (int8_t)x;

    CASE_OP_32_64(ext16s):
        return (int16_t)x;

    CASE_OP_32_64(ext8u):
        return (uint8_t)x;

    CASE_OP_32_64(ext16u):
        return (uint16_t)x;

    case INDEX_op_ext32s_i64:
        return (int32_t)x;

    case INDEX_op_ext32u_i64:
        return (uint32_t)x;

    case INDEX_op_muluh_i32:
        return ((uint64_t)(uint32_t)x * (uint32_t)y) >> 32;
    case INDEX_op_mulsh_i32:
        return ((int64_t)(int32_t)x * (int32_t)y) >> 32;

    case INDEX_op_muluh_i64:
        mulu64(&l64, &h64, x, y);
        return h64;
    case INDEX_op_mulsh_i64:
        muls64(&l64, &h64, x, y);
        return h64;

    case INDEX_op_div_i32:
        /* Avoid crashing on divide by zero, otherwise undefined.  */
        return (int32_t)x / ((int32_t)y ? : 1);
    case INDEX_op_divu_i32:
        return (uint32_t)x / ((uint32_t)y ? : 1);
    case INDEX_op_div_i64:
        return (int64_t)x / ((int64_t)y ? : 1);
    case INDEX_op_divu_i64:
        return (uint64_t)x / ((uint64_t)y ? : 1);

    case INDEX_op_rem_i32:
        return (int32_t)x % ((int32_t)y ? : 1);
    case INDEX_op_remu_i32:
        return (uint32_t)x % ((uint32_t)y ? : 1);
    case INDEX_op_rem_i64:
        return (int64_t)x % ((int64_t)y ? : 1);
    case INDEX_op_remu_i64:
        return (uint64_t)x % ((uint64_t)y ? : 1);

    default:
        fprintf(stderr,
                "Unrecognized operation %d in do_constant_folding.\n", op);
        tcg_abort();
    }
}

static TCGArg do_constant_folding(TCGOpcode op, TCGArg x, TCGArg y)
{
    TCGArg res = do_constant_folding_2(op, x, y);
    if (op_bits(op) == 32) {
        res &= 0xffffffff;
    }
    return res;
}

static bool do_constant_folding_cond_32(uint32_t x, uint32_t y, TCGCond c)
{
    switch (c) {
    case TCG_COND_EQ:
        return x == y;
    case TCG_COND_NE:
        return x != y;
    case TCG_COND_LT:
        return (int32_t)x < (int32_t)y;
    case TCG_COND_GE:
        return (int32_t)x >= (int32_t)y;
    case TCG_COND_LE:
        return (int32_t)x <= (int32_t)y;
    case TCG_COND_GT:
        return (int32_t)x > (int32_t)y;
    case TCG_COND_LTU:
        return x < y;
    case TCG_COND_GEU:
        return x >= y;
    case TCG_COND_LEU:
        return x <= y;
    case TCG_COND_GTU:
        return x > y;
    default:
        tcg_abort();
    }
}

static bool do_constant_folding_cond_64(uint64_t x, uint64_t y, TCGCond c)
{
    switch (c) {
    case TCG_COND_EQ:
        return x == y;
    case TCG_COND_NE:
        return x != y;
    case TCG_COND_LT:
        return (int64_t)x < (int64_t)y;
    case TCG_COND_GE:
        return (int64_t)x >= (int64_t)y;
    case TCG_COND_LE:
        return (int64_t)x <= (int64_t)y;
    case TCG_COND_GT:
        return (int64_t)x > (int64_t)y;
    case TCG_COND_LTU:
        return x < y;
    case TCG_COND_GEU:
        return x >= y;
    case TCG_COND_LEU:
        return x <= y;
    case TCG_COND_GTU:
        return x > y;
    default:
        tcg_abort();
    }
}

static bool do_constant_folding_cond_eq(TCGCond c)
{
    switch (c) {
    case TCG_COND_GT:
    case TCG_COND_LTU:
    case TCG_COND_LT:
    case TCG_COND_GTU:
    case TCG_COND_NE:
        return 0;
    case TCG_COND_GE:
    case TCG_COND_GEU:
    case TCG_COND_LE:
    case TCG_COND_LEU:
    case TCG_COND_EQ:
        return 1;
    default:
        tcg_abort();
    }
}

/* Return 2 if the condition can't be simplified, and the result
   of the condition (0 or 1) if it can */
static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x,
                                       TCGArg y, TCGCond c)
{
    if (temps[x].state == TCG_TEMP_CONST && temps[y].state == TCG_TEMP_CONST) {
        switch (op_bits(op)) {
        case 32:
            return do_constant_folding_cond_32(temps[x].val, temps[y].val, c);
        case 64:
            return do_constant_folding_cond_64(temps[x].val, temps[y].val, c);
        default:
            tcg_abort();
        }
    } else if (temps_are_copies(x, y)) {
        return do_constant_folding_cond_eq(c);
    } else if (temps[y].state == TCG_TEMP_CONST && temps[y].val == 0) {
        switch (c) {
        case TCG_COND_LTU:
            return 0;
        case TCG_COND_GEU:
            return 1;
        default:
            return 2;
        }
    } else {
        return 2;
    }
}

/* Return 2 if the condition can't be simplified, and the result
   of the condition (0 or 1) if it can */
static TCGArg do_constant_folding_cond2(TCGArg *p1, TCGArg *p2, TCGCond c)
{
    TCGArg al = p1[0], ah = p1[1];
    TCGArg bl = p2[0], bh = p2[1];

    if (temps[bl].state == TCG_TEMP_CONST
        && temps[bh].state == TCG_TEMP_CONST) {
        uint64_t b = ((uint64_t)temps[bh].val << 32) | (uint32_t)temps[bl].val;

        if (temps[al].state == TCG_TEMP_CONST
            && temps[ah].state == TCG_TEMP_CONST) {
            uint64_t a;
            a = ((uint64_t)temps[ah].val << 32) | (uint32_t)temps[al].val;
            return do_constant_folding_cond_64(a, b, c);
        }
        if (b == 0) {
            switch (c) {
            case TCG_COND_LTU:
                return 0;
            case TCG_COND_GEU:
                return 1;
            default:
                break;
            }
        }
    }
    if (temps_are_copies(al, bl) && temps_are_copies(ah, bh)) {
        return do_constant_folding_cond_eq(c);
    }
    return 2;
}

static bool swap_commutative(TCGArg dest, TCGArg *p1, TCGArg *p2)
{
    TCGArg a1 = *p1, a2 = *p2;
    int sum = 0;
    sum += temps[a1].state == TCG_TEMP_CONST;
    sum -= temps[a2].state == TCG_TEMP_CONST;

    /* Prefer the constant in second argument, and then the form
       op a, a, b, which is better handled on non-RISC hosts. */
    if (sum > 0 || (sum == 0 && dest == a2)) {
        *p1 = a2;
        *p2 = a1;
        return true;
    }
    return false;
}

static bool swap_commutative2(TCGArg *p1, TCGArg *p2)
{
    int sum = 0;
    sum += temps[p1[0]].state == TCG_TEMP_CONST;
    sum += temps[p1[1]].state == TCG_TEMP_CONST;
    sum -= temps[p2[0]].state == TCG_TEMP_CONST;
    sum -= temps[p2[1]].state == TCG_TEMP_CONST;
    if (sum > 0) {
        TCGArg t;
        t = p1[0], p1[0] = p2[0], p2[0] = t;
        t = p1[1], p1[1] = p2[1], p2[1] = t;
        return true;
    }
    return false;
}

/* Propagate constants and copies, fold constant expressions. */
static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
                                    TCGArg *args, TCGOpDef *tcg_op_defs)
{
    int nb_ops, op_index, nb_temps, nb_globals;
    TCGArg *gen_args;

    /* Array VALS has an element for each temp.
       If this temp holds a constant then its value is kept in VALS' element.
       If this temp is a copy of other ones then the other copies are
       available through the doubly linked circular list. */

    nb_temps = s->nb_temps;
    nb_globals = s->nb_globals;
    reset_all_temps(nb_temps);

    nb_ops = tcg_opc_ptr - s->gen_opc_buf;
    gen_args = args;
    for (op_index = 0; op_index < nb_ops; op_index++) {
        TCGOpcode op = s->gen_opc_buf[op_index];
        const TCGOpDef *def = &tcg_op_defs[op];
        tcg_target_ulong mask, affected;
        int nb_oargs, nb_iargs, nb_args, i;
        TCGArg tmp;

        if (op == INDEX_op_call) {
            *gen_args++ = tmp = *args++;
            nb_oargs = tmp >> 16;
            nb_iargs = tmp & 0xffff;
            nb_args = nb_oargs + nb_iargs + def->nb_cargs;
        } else {
            nb_oargs = def->nb_oargs;
            nb_iargs = def->nb_iargs;
            nb_args = def->nb_args;
        }

        /* Do copy propagation */
        for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
            if (temps[args[i]].state == TCG_TEMP_COPY) {
                args[i] = find_better_copy(s, args[i]);
            }
        }

        /* For commutative operations make constant second argument */
        switch (op) {
        CASE_OP_32_64(add):
        CASE_OP_32_64(mul):
        CASE_OP_32_64(and):
        CASE_OP_32_64(or):
        CASE_OP_32_64(xor):
        CASE_OP_32_64(eqv):
        CASE_OP_32_64(nand):
        CASE_OP_32_64(nor):
        CASE_OP_32_64(muluh):
        CASE_OP_32_64(mulsh):
            swap_commutative(args[0], &args[1], &args[2]);
            break;
        CASE_OP_32_64(brcond):
            if (swap_commutative(-1, &args[0], &args[1])) {
                args[2] = tcg_swap_cond(args[2]);
            }
            break;
        CASE_OP_32_64(setcond):
            if (swap_commutative(args[0], &args[1], &args[2])) {
                args[3] = tcg_swap_cond(args[3]);
            }
            break;
        CASE_OP_32_64(movcond):
            if (swap_commutative(-1, &args[1], &args[2])) {
                args[5] = tcg_swap_cond(args[5]);
            }
            /* For movcond, we canonicalize the "false" input reg to match
               the destination reg so that the tcg backend can implement
               a "move if true" operation.  */
            if (swap_commutative(args[0], &args[4], &args[3])) {
                args[5] = tcg_invert_cond(args[5]);
            }
            break;
        CASE_OP_32_64(add2):
            swap_commutative(args[0], &args[2], &args[4]);
            swap_commutative(args[1], &args[3], &args[5]);
            break;
        CASE_OP_32_64(mulu2):
        CASE_OP_32_64(muls2):
            swap_commutative(args[0], &args[2], &args[3]);
            break;
        case INDEX_op_brcond2_i32:
            if (swap_commutative2(&args[0], &args[2])) {
                args[4] = tcg_swap_cond(args[4]);
            }
            break;
        case INDEX_op_setcond2_i32:
            if (swap_commutative2(&args[1], &args[3])) {
                args[5] = tcg_swap_cond(args[5]);
            }
            break;
        default:
            break;
        }

        /* Simplify expressions for "shift/rot r, 0, a => movi r, 0",
           and "sub r, 0, a => neg r, a" case.  */
        switch (op) {
        CASE_OP_32_64(shl):
        CASE_OP_32_64(shr):
        CASE_OP_32_64(sar):
        CASE_OP_32_64(rotl):
        CASE_OP_32_64(rotr):
            if (temps[args[1]].state == TCG_TEMP_CONST
                && temps[args[1]].val == 0) {
                s->gen_opc_buf[op_index] = op_to_movi(op);
                tcg_opt_gen_movi(gen_args, args[0], 0);
                args += 3;
                gen_args += 2;
                continue;
            }
            break;
        CASE_OP_32_64(sub):
            {
                TCGOpcode neg_op;
                bool have_neg;

                if (temps[args[2]].state == TCG_TEMP_CONST) {
                    /* Proceed with possible constant folding. */
                    break;
                }
                if (op == INDEX_op_sub_i32) {
                    neg_op = INDEX_op_neg_i32;
                    have_neg = TCG_TARGET_HAS_neg_i32;
                } else {
                    neg_op = INDEX_op_neg_i64;
                    have_neg = TCG_TARGET_HAS_neg_i64;
                }
                if (!have_neg) {
                    break;
                }
                if (temps[args[1]].state == TCG_TEMP_CONST
                    && temps[args[1]].val == 0) {
                    s->gen_opc_buf[op_index] = neg_op;
                    reset_temp(args[0]);
                    gen_args[0] = args[0];
                    gen_args[1] = args[2];
                    args += 3;
                    gen_args += 2;
                    continue;
                }
            }
            break;
        CASE_OP_32_64(xor):
        CASE_OP_32_64(nand):
            if (temps[args[1]].state != TCG_TEMP_CONST
                && temps[args[2]].state == TCG_TEMP_CONST
                && temps[args[2]].val == -1) {
                i = 1;
                goto try_not;
            }
            break;
        CASE_OP_32_64(nor):
            if (temps[args[1]].state != TCG_TEMP_CONST
                && temps[args[2]].state == TCG_TEMP_CONST
                && temps[args[2]].val == 0) {
                i = 1;
                goto try_not;
            }
            break;
        CASE_OP_32_64(andc):
            if (temps[args[2]].state != TCG_TEMP_CONST
                && temps[args[1]].state == TCG_TEMP_CONST
                && temps[args[1]].val == -1) {
                i = 2;
                goto try_not;
            }
            break;
        CASE_OP_32_64(orc):
        CASE_OP_32_64(eqv):
            if (temps[args[2]].state != TCG_TEMP_CONST
                && temps[args[1]].state == TCG_TEMP_CONST
                && temps[args[1]].val == 0) {
                i = 2;
                goto try_not;
            }
            break;
        try_not:
            {
                TCGOpcode not_op;
                bool have_not;

                if (def->flags & TCG_OPF_64BIT) {
                    not_op = INDEX_op_not_i64;
                    have_not = TCG_TARGET_HAS_not_i64;
                } else {
                    not_op = INDEX_op_not_i32;
                    have_not = TCG_TARGET_HAS_not_i32;
                }
                if (!have_not) {
                    break;
                }
                s->gen_opc_buf[op_index] = not_op;
                reset_temp(args[0]);
                gen_args[0] = args[0];
                gen_args[1] = args[i];
                args += 3;
                gen_args += 2;
                continue;
            }
        default:
            break;
        }

        /* Simplify expression for "op r, a, const => mov r, a" cases */
        switch (op) {
        CASE_OP_32_64(add):
        CASE_OP_32_64(sub):
        CASE_OP_32_64(shl):
        CASE_OP_32_64(shr):
        CASE_OP_32_64(sar):
        CASE_OP_32_64(rotl):
        CASE_OP_32_64(rotr):
        CASE_OP_32_64(or):
        CASE_OP_32_64(xor):
        CASE_OP_32_64(andc):
            if (temps[args[1]].state != TCG_TEMP_CONST
                && temps[args[2]].state == TCG_TEMP_CONST
                && temps[args[2]].val == 0) {
                goto do_mov3;
            }
            break;
        CASE_OP_32_64(and):
        CASE_OP_32_64(orc):
        CASE_OP_32_64(eqv):
            if (temps[args[1]].state != TCG_TEMP_CONST
                && temps[args[2]].state == TCG_TEMP_CONST
                && temps[args[2]].val == -1) {
                goto do_mov3;
            }
            break;
        do_mov3:
            if (temps_are_copies(args[0], args[1])) {
                s->gen_opc_buf[op_index] = INDEX_op_nop;
            } else {
                s->gen_opc_buf[op_index] = op_to_mov(op);
                tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
                gen_args += 2;
            }
            args += 3;
            continue;
        default:
            break;
        }

        /* Simplify using known-zero bits. Currently only ops with a single
           output argument is supported. */
        mask = -1;
        affected = -1;
        switch (op) {
        CASE_OP_32_64(ext8s):
            if ((temps[args[1]].mask & 0x80) != 0) {
                break;
            }
        CASE_OP_32_64(ext8u):
            mask = 0xff;
            goto and_const;
        CASE_OP_32_64(ext16s):
            if ((temps[args[1]].mask & 0x8000) != 0) {
                break;
            }
        CASE_OP_32_64(ext16u):
            mask = 0xffff;
            goto and_const;
        case INDEX_op_ext32s_i64:
            if ((temps[args[1]].mask & 0x80000000) != 0) {
                break;
            }
        case INDEX_op_ext32u_i64:
            mask = 0xffffffffU;
            goto and_const;

        CASE_OP_32_64(and):
            mask = temps[args[2]].mask;
            if (temps[args[2]].state == TCG_TEMP_CONST) {
        and_const:
                affected = temps[args[1]].mask & ~mask;
            }
            mask = temps[args[1]].mask & mask;
            break;

        CASE_OP_32_64(andc):
            /* Known-zeros does not imply known-ones.  Therefore unless
               args[2] is constant, we can't infer anything from it.  */
            if (temps[args[2]].state == TCG_TEMP_CONST) {
                mask = ~temps[args[2]].mask;
                goto and_const;
            }
            /* But we certainly know nothing outside args[1] may be set. */
            mask = temps[args[1]].mask;
            break;

        case INDEX_op_sar_i32:
            if (temps[args[2]].state == TCG_TEMP_CONST) {
                tmp = temps[args[2]].val & 31;
                mask = (int32_t)temps[args[1]].mask >> tmp;
            }
            break;
        case INDEX_op_sar_i64:
            if (temps[args[2]].state == TCG_TEMP_CONST) {
                tmp = temps[args[2]].val & 63;
                mask = (int64_t)temps[args[1]].mask >> tmp;
            }
            break;

        case INDEX_op_shr_i32:
            if (temps[args[2]].state == TCG_TEMP_CONST) {
                tmp = temps[args[2]].val & 31;
                mask = (uint32_t)temps[args[1]].mask >> tmp;
            }
            break;
        case INDEX_op_shr_i64:
            if (temps[args[2]].state == TCG_TEMP_CONST) {
                tmp = temps[args[2]].val & 63;
                mask = (uint64_t)temps[args[1]].mask >> tmp;
            }
            break;

        case INDEX_op_trunc_shr_i32:
            mask = (uint64_t)temps[args[1]].mask >> args[2];
            break;

        CASE_OP_32_64(shl):
            if (temps[args[2]].state == TCG_TEMP_CONST) {
                tmp = temps[args[2]].val & (TCG_TARGET_REG_BITS - 1);
                mask = temps[args[1]].mask << tmp;
            }
            break;

        CASE_OP_32_64(neg):
            /* Set to 1 all bits to the left of the rightmost.  */
            mask = -(temps[args[1]].mask & -temps[args[1]].mask);
            break;

        CASE_OP_32_64(deposit):
            mask = deposit64(temps[args[1]].mask, args[3], args[4],
                             temps[args[2]].mask);
            break;

        CASE_OP_32_64(or):
        CASE_OP_32_64(xor):
            mask = temps[args[1]].mask | temps[args[2]].mask;
            break;

        CASE_OP_32_64(setcond):
            mask = 1;
            break;

        CASE_OP_32_64(movcond):
            mask = temps[args[3]].mask | temps[args[4]].mask;
            break;

        CASE_OP_32_64(ld8u):
        case INDEX_op_qemu_ld8u:
            mask = 0xff;
            break;
        CASE_OP_32_64(ld16u):
        case INDEX_op_qemu_ld16u:
            mask = 0xffff;
            break;
        case INDEX_op_ld32u_i64:
#if TCG_TARGET_REG_BITS == 64
        case INDEX_op_qemu_ld32u:
#endif
            mask = 0xffffffffu;
            break;

        CASE_OP_32_64(qemu_ld):
            {
                TCGMemOp mop = args[nb_oargs + nb_iargs];
                if (!(mop & MO_SIGN)) {
                    mask = (2ULL << ((8 << (mop & MO_SIZE)) - 1)) - 1;
                }
            }
            break;

        default:
            break;
        }

        /* 32-bit ops (non 64-bit ops and non load/store ops) generate 32-bit
           results */
        if (!(def->flags & (TCG_OPF_CALL_CLOBBER | TCG_OPF_64BIT))) {
            mask &= 0xffffffffu;
        }

        if (mask == 0) {
            assert(nb_oargs == 1);
            s->gen_opc_buf[op_index] = op_to_movi(op);
            tcg_opt_gen_movi(gen_args, args[0], 0);
            args += nb_args;
            gen_args += 2;
            continue;
        }
        if (affected == 0) {
            assert(nb_oargs == 1);
            if (temps_are_copies(args[0], args[1])) {
                s->gen_opc_buf[op_index] = INDEX_op_nop;
            } else if (temps[args[1]].state != TCG_TEMP_CONST) {
                s->gen_opc_buf[op_index] = op_to_mov(op);
                tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
                gen_args += 2;
            } else {
                s->gen_opc_buf[op_index] = op_to_movi(op);
                tcg_opt_gen_movi(gen_args, args[0], temps[args[1]].val);
                gen_args += 2;
            }
            args += nb_args;
            continue;
        }

        /* Simplify expression for "op r, a, 0 => movi r, 0" cases */
        switch (op) {
        CASE_OP_32_64(and):
        CASE_OP_32_64(mul):
        CASE_OP_32_64(muluh):
        CASE_OP_32_64(mulsh):
            if ((temps[args[2]].state == TCG_TEMP_CONST
                && temps[args[2]].val == 0)) {
                s->gen_opc_buf[op_index] = op_to_movi(op);
                tcg_opt_gen_movi(gen_args, args[0], 0);
                args += 3;
                gen_args += 2;
                continue;
            }
            break;
        default:
            break;
        }

        /* Simplify expression for "op r, a, a => mov r, a" cases */
        switch (op) {
        CASE_OP_32_64(or):
        CASE_OP_32_64(and):
            if (temps_are_copies(args[1], args[2])) {
                if (temps_are_copies(args[0], args[1])) {
                    s->gen_opc_buf[op_index] = INDEX_op_nop;
                } else {
                    s->gen_opc_buf[op_index] = op_to_mov(op);
                    tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
                    gen_args += 2;
                }
                args += 3;
                continue;
            }
            break;
        default:
            break;
        }

        /* Simplify expression for "op r, a, a => movi r, 0" cases */
        switch (op) {
        CASE_OP_32_64(andc):
        CASE_OP_32_64(sub):
        CASE_OP_32_64(xor):
            if (temps_are_copies(args[1], args[2])) {
                s->gen_opc_buf[op_index] = op_to_movi(op);
                tcg_opt_gen_movi(gen_args, args[0], 0);
                gen_args += 2;
                args += 3;
                continue;
            }
            break;
        default:
            break;
        }

        /* Propagate constants through copy operations and do constant
           folding.  Constants will be substituted to arguments by register
           allocator where needed and possible.  Also detect copies. */
        switch (op) {
        CASE_OP_32_64(mov):
            if (temps_are_copies(args[0], args[1])) {
                args += 2;
                s->gen_opc_buf[op_index] = INDEX_op_nop;
                break;
            }
            if (temps[args[1]].state != TCG_TEMP_CONST) {
                tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
                gen_args += 2;
                args += 2;
                break;
            }
            /* Source argument is constant.  Rewrite the operation and
               let movi case handle it. */
            op = op_to_movi(op);
            s->gen_opc_buf[op_index] = op;
            args[1] = temps[args[1]].val;
            /* fallthrough */
        CASE_OP_32_64(movi):
            tcg_opt_gen_movi(gen_args, args[0], args[1]);
            gen_args += 2;
            args += 2;
            break;

        CASE_OP_32_64(not):
        CASE_OP_32_64(neg):
        CASE_OP_32_64(ext8s):
        CASE_OP_32_64(ext8u):
        CASE_OP_32_64(ext16s):
        CASE_OP_32_64(ext16u):
        case INDEX_op_ext32s_i64:
        case INDEX_op_ext32u_i64:
            if (temps[args[1]].state == TCG_TEMP_CONST) {
                s->gen_opc_buf[op_index] = op_to_movi(op);
                tmp = do_constant_folding(op, temps[args[1]].val, 0);
                tcg_opt_gen_movi(gen_args, args[0], tmp);
                gen_args += 2;
                args += 2;
                break;
            }
            goto do_default;

        case INDEX_op_trunc_shr_i32:
            if (temps[args[1]].state == TCG_TEMP_CONST) {
                s->gen_opc_buf[op_index] = op_to_movi(op);
                tmp = do_constant_folding(op, temps[args[1]].val, args[2]);
                tcg_opt_gen_movi(gen_args, args[0], tmp);
                gen_args += 2;
                args += 3;
                break;
            }
            goto do_default;

        CASE_OP_32_64(add):
        CASE_OP_32_64(sub):
        CASE_OP_32_64(mul):
        CASE_OP_32_64(or):
        CASE_OP_32_64(and):
        CASE_OP_32_64(xor):
        CASE_OP_32_64(shl):
        CASE_OP_32_64(shr):
        CASE_OP_32_64(sar):
        CASE_OP_32_64(rotl):
        CASE_OP_32_64(rotr):
        CASE_OP_32_64(andc):
        CASE_OP_32_64(orc):
        CASE_OP_32_64(eqv):
        CASE_OP_32_64(nand):
        CASE_OP_32_64(nor):
        CASE_OP_32_64(muluh):
        CASE_OP_32_64(mulsh):
        CASE_OP_32_64(div):
        CASE_OP_32_64(divu):
        CASE_OP_32_64(rem):
        CASE_OP_32_64(remu):
            if (temps[args[1]].state == TCG_TEMP_CONST
                && temps[args[2]].state == TCG_TEMP_CONST) {
                s->gen_opc_buf[op_index] = op_to_movi(op);
                tmp = do_constant_folding(op, temps[args[1]].val,
                                          temps[args[2]].val);
                tcg_opt_gen_movi(gen_args, args[0], tmp);
                gen_args += 2;
                args += 3;
                break;
            }
            goto do_default;

        CASE_OP_32_64(deposit):
            if (temps[args[1]].state == TCG_TEMP_CONST
                && temps[args[2]].state == TCG_TEMP_CONST) {
                s->gen_opc_buf[op_index] = op_to_movi(op);
                tmp = deposit64(temps[args[1]].val, args[3], args[4],
                                temps[args[2]].val);
                tcg_opt_gen_movi(gen_args, args[0], tmp);
                gen_args += 2;
                args += 5;
                break;
            }
            goto do_default;

        CASE_OP_32_64(setcond):
            tmp = do_constant_folding_cond(op, args[1], args[2], args[3]);
            if (tmp != 2) {
                s->gen_opc_buf[op_index] = op_to_movi(op);
                tcg_opt_gen_movi(gen_args, args[0], tmp);
                gen_args += 2;
                args += 4;
                break;
            }
            goto do_default;

        CASE_OP_32_64(brcond):
            tmp = do_constant_folding_cond(op, args[0], args[1], args[2]);
            if (tmp != 2) {
                if (tmp) {
                    reset_all_temps(nb_temps);
                    s->gen_opc_buf[op_index] = INDEX_op_br;
                    gen_args[0] = args[3];
                    gen_args += 1;
                } else {
                    s->gen_opc_buf[op_index] = INDEX_op_nop;
                }
                args += 4;
                break;
            }
            goto do_default;

        CASE_OP_32_64(movcond):
            tmp = do_constant_folding_cond(op, args[1], args[2], args[5]);
            if (tmp != 2) {
                if (temps_are_copies(args[0], args[4-tmp])) {
                    s->gen_opc_buf[op_index] = INDEX_op_nop;
                } else if (temps[args[4-tmp]].state == TCG_TEMP_CONST) {
                    s->gen_opc_buf[op_index] = op_to_movi(op);
                    tcg_opt_gen_movi(gen_args, args[0], temps[args[4-tmp]].val);
                    gen_args += 2;
                } else {
                    s->gen_opc_buf[op_index] = op_to_mov(op);
                    tcg_opt_gen_mov(s, gen_args, args[0], args[4-tmp]);
                    gen_args += 2;
                }
                args += 6;
                break;
            }
            goto do_default;

        case INDEX_op_add2_i32:
        case INDEX_op_sub2_i32:
            if (temps[args[2]].state == TCG_TEMP_CONST
                && temps[args[3]].state == TCG_TEMP_CONST
                && temps[args[4]].state == TCG_TEMP_CONST
                && temps[args[5]].state == TCG_TEMP_CONST) {
                uint32_t al = temps[args[2]].val;
                uint32_t ah = temps[args[3]].val;
                uint32_t bl = temps[args[4]].val;
                uint32_t bh = temps[args[5]].val;
                uint64_t a = ((uint64_t)ah << 32) | al;
                uint64_t b = ((uint64_t)bh << 32) | bl;
                TCGArg rl, rh;

                if (op == INDEX_op_add2_i32) {
                    a += b;
                } else {
                    a -= b;
                }

                /* We emit the extra nop when we emit the add2/sub2.  */
                assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);

                rl = args[0];
                rh = args[1];
                s->gen_opc_buf[op_index] = INDEX_op_movi_i32;
                s->gen_opc_buf[++op_index] = INDEX_op_movi_i32;
                tcg_opt_gen_movi(&gen_args[0], rl, (uint32_t)a);
                tcg_opt_gen_movi(&gen_args[2], rh, (uint32_t)(a >> 32));
                gen_args += 4;
                args += 6;
                break;
            }
            goto do_default;

        case INDEX_op_mulu2_i32:
            if (temps[args[2]].state == TCG_TEMP_CONST
                && temps[args[3]].state == TCG_TEMP_CONST) {
                uint32_t a = temps[args[2]].val;
                uint32_t b = temps[args[3]].val;
                uint64_t r = (uint64_t)a * b;
                TCGArg rl, rh;

                /* We emit the extra nop when we emit the mulu2.  */
                assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);

                rl = args[0];
                rh = args[1];
                s->gen_opc_buf[op_index] = INDEX_op_movi_i32;
                s->gen_opc_buf[++op_index] = INDEX_op_movi_i32;
                tcg_opt_gen_movi(&gen_args[0], rl, (uint32_t)r);
                tcg_opt_gen_movi(&gen_args[2], rh, (uint32_t)(r >> 32));
                gen_args += 4;
                args += 4;
                break;
            }
            goto do_default;

        case INDEX_op_brcond2_i32:
            tmp = do_constant_folding_cond2(&args[0], &args[2], args[4]);
            if (tmp != 2) {
                if (tmp) {
                    reset_all_temps(nb_temps);
                    s->gen_opc_buf[op_index] = INDEX_op_br;
                    gen_args[0] = args[5];
                    gen_args += 1;
                } else {
                    s->gen_opc_buf[op_index] = INDEX_op_nop;
                }
            } else if ((args[4] == TCG_COND_LT || args[4] == TCG_COND_GE)
                       && temps[args[2]].state == TCG_TEMP_CONST
                       && temps[args[3]].state == TCG_TEMP_CONST
                       && temps[args[2]].val == 0
                       && temps[args[3]].val == 0) {
                /* Simplify LT/GE comparisons vs zero to a single compare
                   vs the high word of the input.  */
                reset_all_temps(nb_temps);
                s->gen_opc_buf[op_index] = INDEX_op_brcond_i32;
                gen_args[0] = args[1];
                gen_args[1] = args[3];
                gen_args[2] = args[4];
                gen_args[3] = args[5];
                gen_args += 4;
            } else {
                goto do_default;
            }
            args += 6;
            break;

        case INDEX_op_setcond2_i32:
            tmp = do_constant_folding_cond2(&args[1], &args[3], args[5]);
            if (tmp != 2) {
                s->gen_opc_buf[op_index] = INDEX_op_movi_i32;
                tcg_opt_gen_movi(gen_args, args[0], tmp);
                gen_args += 2;
            } else if ((args[5] == TCG_COND_LT || args[5] == TCG_COND_GE)
                       && temps[args[3]].state == TCG_TEMP_CONST
                       && temps[args[4]].state == TCG_TEMP_CONST
                       && temps[args[3]].val == 0
                       && temps[args[4]].val == 0) {
                /* Simplify LT/GE comparisons vs zero to a single compare
                   vs the high word of the input.  */
                s->gen_opc_buf[op_index] = INDEX_op_setcond_i32;
                reset_temp(args[0]);
                gen_args[0] = args[0];
                gen_args[1] = args[2];
                gen_args[2] = args[4];
                gen_args[3] = args[5];
                gen_args += 4;
            } else {
                goto do_default;
            }
            args += 6;
            break;

        case INDEX_op_call:
            if (!(args[nb_oargs + nb_iargs + 1]
                  & (TCG_CALL_NO_READ_GLOBALS | TCG_CALL_NO_WRITE_GLOBALS))) {
                for (i = 0; i < nb_globals; i++) {
                    reset_temp(i);
                }
            }
            goto do_reset_output;

        default:
        do_default:
            /* Default case: we know nothing about operation (or were unable
               to compute the operation result) so no propagation is done.
               We trash everything if the operation is the end of a basic
               block, otherwise we only trash the output args.  "mask" is
               the non-zero bits mask for the first output arg.  */
            if (def->flags & TCG_OPF_BB_END) {
                reset_all_temps(nb_temps);
            } else {
        do_reset_output:
                for (i = 0; i < nb_oargs; i++) {
                    reset_temp(args[i]);
                    /* Save the corresponding known-zero bits mask for the
                       first output argument (only one supported so far). */
                    if (i == 0) {
                        temps[args[i]].mask = mask;
                    }
                }
            }
            for (i = 0; i < nb_args; i++) {
                gen_args[i] = args[i];
            }
            args += nb_args;
            gen_args += nb_args;
            break;
        }
    }

    return gen_args;
}

TCGArg *tcg_optimize(TCGContext *s, uint16_t *tcg_opc_ptr,
        TCGArg *args, TCGOpDef *tcg_op_defs)
{
    TCGArg *res;
    res = tcg_constant_folding(s, tcg_opc_ptr, args, tcg_op_defs);
    return res;
}
