target-i386: Add CC_OP_CLR
Special case xor with self. We need not even store the known zero into cc_src. Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
		
							parent
							
								
									321c535105
								
							
						
					
					
						commit
						436ff2d227
					
				@ -102,6 +102,8 @@ target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    case CC_OP_EFLAGS:
 | 
					    case CC_OP_EFLAGS:
 | 
				
			||||||
        return src1;
 | 
					        return src1;
 | 
				
			||||||
 | 
					    case CC_OP_CLR:
 | 
				
			||||||
 | 
					        return CC_Z;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case CC_OP_MULB:
 | 
					    case CC_OP_MULB:
 | 
				
			||||||
        return compute_all_mulb(dst, src1);
 | 
					        return compute_all_mulb(dst, src1);
 | 
				
			||||||
@ -228,6 +230,7 @@ target_ulong helper_cc_compute_c(target_ulong dst, target_ulong src1,
 | 
				
			|||||||
    case CC_OP_LOGICW:
 | 
					    case CC_OP_LOGICW:
 | 
				
			||||||
    case CC_OP_LOGICL:
 | 
					    case CC_OP_LOGICL:
 | 
				
			||||||
    case CC_OP_LOGICQ:
 | 
					    case CC_OP_LOGICQ:
 | 
				
			||||||
 | 
					    case CC_OP_CLR:
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case CC_OP_EFLAGS:
 | 
					    case CC_OP_EFLAGS:
 | 
				
			||||||
 | 
				
			|||||||
@ -645,6 +645,8 @@ typedef enum {
 | 
				
			|||||||
    CC_OP_ADOX, /* CC_DST = O, CC_SRC = rest.  */
 | 
					    CC_OP_ADOX, /* CC_DST = O, CC_SRC = rest.  */
 | 
				
			||||||
    CC_OP_ADCOX, /* CC_DST = C, CC_SRC2 = O, CC_SRC = rest.  */
 | 
					    CC_OP_ADCOX, /* CC_DST = C, CC_SRC2 = O, CC_SRC = rest.  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CC_OP_CLR, /* Z set, all other flags clear.  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CC_OP_NB,
 | 
					    CC_OP_NB,
 | 
				
			||||||
} CCOp;
 | 
					} CCOp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -117,6 +117,8 @@ static const char *cc_op_str[CC_OP_NB] = {
 | 
				
			|||||||
    "ADCX",
 | 
					    "ADCX",
 | 
				
			||||||
    "ADOX",
 | 
					    "ADOX",
 | 
				
			||||||
    "ADCOX",
 | 
					    "ADCOX",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "CLR",
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
 | 
				
			|||||||
@ -213,6 +213,7 @@ static const uint8_t cc_op_live[CC_OP_NB] = {
 | 
				
			|||||||
    [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC,
 | 
					    [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC,
 | 
				
			||||||
    [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2,
 | 
					    [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2,
 | 
				
			||||||
    [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
 | 
					    [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
 | 
				
			||||||
 | 
					    [CC_OP_CLR] = 0,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void set_cc_op(DisasContext *s, CCOp op)
 | 
					static void set_cc_op(DisasContext *s, CCOp op)
 | 
				
			||||||
@ -906,6 +907,11 @@ static void gen_compute_eflags(DisasContext *s)
 | 
				
			|||||||
    if (s->cc_op == CC_OP_EFLAGS) {
 | 
					    if (s->cc_op == CC_OP_EFLAGS) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (s->cc_op == CC_OP_CLR) {
 | 
				
			||||||
 | 
					        tcg_gen_movi_tl(cpu_cc_src, CC_Z);
 | 
				
			||||||
 | 
					        set_cc_op(s, CC_OP_EFLAGS);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    TCGV_UNUSED(zero);
 | 
					    TCGV_UNUSED(zero);
 | 
				
			||||||
    dst = cpu_cc_dst;
 | 
					    dst = cpu_cc_dst;
 | 
				
			||||||
@ -974,6 +980,7 @@ static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
 | 
				
			|||||||
                             .reg2 = t1, .mask = -1, .use_reg2 = true };
 | 
					                             .reg2 = t1, .mask = -1, .use_reg2 = true };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case CC_OP_LOGICB ... CC_OP_LOGICQ:
 | 
					    case CC_OP_LOGICB ... CC_OP_LOGICQ:
 | 
				
			||||||
 | 
					    case CC_OP_CLR:
 | 
				
			||||||
        return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
 | 
					        return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case CC_OP_INCB ... CC_OP_INCQ:
 | 
					    case CC_OP_INCB ... CC_OP_INCQ:
 | 
				
			||||||
@ -1040,6 +1047,8 @@ static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
 | 
				
			|||||||
    case CC_OP_ADCOX:
 | 
					    case CC_OP_ADCOX:
 | 
				
			||||||
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
 | 
					        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
 | 
				
			||||||
                             .mask = CC_S };
 | 
					                             .mask = CC_S };
 | 
				
			||||||
 | 
					    case CC_OP_CLR:
 | 
				
			||||||
 | 
					        return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            int size = (s->cc_op - CC_OP_ADDB) & 3;
 | 
					            int size = (s->cc_op - CC_OP_ADDB) & 3;
 | 
				
			||||||
@ -1057,7 +1066,8 @@ static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
 | 
				
			|||||||
    case CC_OP_ADCOX:
 | 
					    case CC_OP_ADCOX:
 | 
				
			||||||
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2,
 | 
					        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2,
 | 
				
			||||||
                             .mask = -1, .no_setcond = true };
 | 
					                             .mask = -1, .no_setcond = true };
 | 
				
			||||||
 | 
					    case CC_OP_CLR:
 | 
				
			||||||
 | 
					        return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        gen_compute_eflags(s);
 | 
					        gen_compute_eflags(s);
 | 
				
			||||||
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
 | 
					        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
 | 
				
			||||||
@ -1078,6 +1088,8 @@ static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
 | 
				
			|||||||
    case CC_OP_ADCOX:
 | 
					    case CC_OP_ADCOX:
 | 
				
			||||||
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
 | 
					        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
 | 
				
			||||||
                             .mask = CC_Z };
 | 
					                             .mask = CC_Z };
 | 
				
			||||||
 | 
					    case CC_OP_CLR:
 | 
				
			||||||
 | 
					        return (CCPrepare) { .cond = TCG_COND_ALWAYS, .mask = -1 };
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            int size = (s->cc_op - CC_OP_ADDB) & 3;
 | 
					            int size = (s->cc_op - CC_OP_ADDB) & 3;
 | 
				
			||||||
@ -4890,10 +4902,9 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
 | 
				
			|||||||
                } else if (op == OP_XORL && rm == reg) {
 | 
					                } else if (op == OP_XORL && rm == reg) {
 | 
				
			||||||
                xor_zero:
 | 
					                xor_zero:
 | 
				
			||||||
                    /* xor reg, reg optimisation */
 | 
					                    /* xor reg, reg optimisation */
 | 
				
			||||||
 | 
					                    set_cc_op(s, CC_OP_CLR);
 | 
				
			||||||
                    gen_op_movl_T0_0();
 | 
					                    gen_op_movl_T0_0();
 | 
				
			||||||
                    set_cc_op(s, CC_OP_LOGICB + ot);
 | 
					 | 
				
			||||||
                    gen_op_mov_reg_T0(ot, reg);
 | 
					                    gen_op_mov_reg_T0(ot, reg);
 | 
				
			||||||
                    gen_op_update1_cc();
 | 
					 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    opreg = rm;
 | 
					                    opreg = rm;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user