- if (temps[args[2]].state == TCG_TEMP_CONST
- && temps[args[2]].val == 0) {
- 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;
+ 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):
+ case INDEX_op_setcond2_i32:
+ mask = 1;
+ break;
+
+ CASE_OP_32_64(movcond):
+ mask = temps[args[3]].mask | temps[args[4]].mask;
+ break;
+
+ CASE_OP_32_64(ld8u):
+ mask = 0xff;
+ break;
+ CASE_OP_32_64(ld16u):
+ mask = 0xffff;
+ break;
+ case INDEX_op_ld32u_i64:
+ 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;