target-alpha: Move integer overflow helpers to int_helper.c.
Signed-off-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
		
							parent
							
								
									a44a27775a
								
							
						
					
					
						commit
						2958620f67
					
				| 
						 | 
					@ -3,12 +3,12 @@
 | 
				
			||||||
DEF_HELPER_3(excp, void, env, int, int)
 | 
					DEF_HELPER_3(excp, void, env, int, int)
 | 
				
			||||||
DEF_HELPER_FLAGS_0(load_pcc, TCG_CALL_CONST | TCG_CALL_PURE, i64)
 | 
					DEF_HELPER_FLAGS_0(load_pcc, TCG_CALL_CONST | TCG_CALL_PURE, i64)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF_HELPER_2(addqv, i64, i64, i64)
 | 
					DEF_HELPER_3(addqv, i64, env, i64, i64)
 | 
				
			||||||
DEF_HELPER_2(addlv, i64, i64, i64)
 | 
					DEF_HELPER_3(addlv, i64, env, i64, i64)
 | 
				
			||||||
DEF_HELPER_2(subqv, i64, i64, i64)
 | 
					DEF_HELPER_3(subqv, i64, env, i64, i64)
 | 
				
			||||||
DEF_HELPER_2(sublv, i64, i64, i64)
 | 
					DEF_HELPER_3(sublv, i64, env, i64, i64)
 | 
				
			||||||
DEF_HELPER_2(mullv, i64, i64, i64)
 | 
					DEF_HELPER_3(mullv, i64, env, i64, i64)
 | 
				
			||||||
DEF_HELPER_2(mulqv, i64, i64, i64)
 | 
					DEF_HELPER_3(mulqv, i64, env, i64, i64)
 | 
				
			||||||
DEF_HELPER_FLAGS_2(umulh, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
 | 
					DEF_HELPER_FLAGS_2(umulh, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF_HELPER_FLAGS_1(ctpop, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
 | 
					DEF_HELPER_FLAGS_1(ctpop, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -255,3 +255,65 @@ uint64_t helper_unpkbw(uint64_t op1)
 | 
				
			||||||
            | ((op1 & 0xff0000) << 16)
 | 
					            | ((op1 & 0xff0000) << 16)
 | 
				
			||||||
            | ((op1 & 0xff000000) << 24));
 | 
					            | ((op1 & 0xff000000) << 24));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint64_t helper_addqv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint64_t tmp = op1;
 | 
				
			||||||
 | 
					    op1 += op2;
 | 
				
			||||||
 | 
					    if (unlikely((tmp ^ op2 ^ (-1ULL)) & (tmp ^ op1) & (1ULL << 63))) {
 | 
				
			||||||
 | 
					        arith_excp(env, GETPC(), EXC_M_IOV, 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return op1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint64_t helper_addlv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint64_t tmp = op1;
 | 
				
			||||||
 | 
					    op1 = (uint32_t)(op1 + op2);
 | 
				
			||||||
 | 
					    if (unlikely((tmp ^ op2 ^ (-1UL)) & (tmp ^ op1) & (1UL << 31))) {
 | 
				
			||||||
 | 
					        arith_excp(env, GETPC(), EXC_M_IOV, 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return op1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint64_t helper_subqv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint64_t res;
 | 
				
			||||||
 | 
					    res = op1 - op2;
 | 
				
			||||||
 | 
					    if (unlikely((op1 ^ op2) & (res ^ op1) & (1ULL << 63))) {
 | 
				
			||||||
 | 
					        arith_excp(env, GETPC(), EXC_M_IOV, 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint64_t helper_sublv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t res;
 | 
				
			||||||
 | 
					    res = op1 - op2;
 | 
				
			||||||
 | 
					    if (unlikely((op1 ^ op2) & (res ^ op1) & (1UL << 31))) {
 | 
				
			||||||
 | 
					        arith_excp(env, GETPC(), EXC_M_IOV, 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint64_t helper_mullv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int64_t res = (int64_t)op1 * (int64_t)op2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (unlikely((int32_t)res != res)) {
 | 
				
			||||||
 | 
					        arith_excp(env, GETPC(), EXC_M_IOV, 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return (int64_t)((int32_t)res);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint64_t helper_mulqv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint64_t tl, th;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    muls64(&tl, &th, op1, op2);
 | 
				
			||||||
 | 
					    /* If th != 0 && th != -1, then we had an overflow */
 | 
				
			||||||
 | 
					    if (unlikely((th + 1) > 1)) {
 | 
				
			||||||
 | 
					        arith_excp(env, GETPC(), EXC_M_IOV, 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return tl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,68 +43,6 @@ uint64_t helper_load_pcc (void)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint64_t helper_addqv (uint64_t op1, uint64_t op2)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    uint64_t tmp = op1;
 | 
					 | 
				
			||||||
    op1 += op2;
 | 
					 | 
				
			||||||
    if (unlikely((tmp ^ op2 ^ (-1ULL)) & (tmp ^ op1) & (1ULL << 63))) {
 | 
					 | 
				
			||||||
        arith_excp(env, GETPC(), EXC_M_IOV, 0);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return op1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint64_t helper_addlv (uint64_t op1, uint64_t op2)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    uint64_t tmp = op1;
 | 
					 | 
				
			||||||
    op1 = (uint32_t)(op1 + op2);
 | 
					 | 
				
			||||||
    if (unlikely((tmp ^ op2 ^ (-1UL)) & (tmp ^ op1) & (1UL << 31))) {
 | 
					 | 
				
			||||||
        arith_excp(env, GETPC(), EXC_M_IOV, 0);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return op1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint64_t helper_subqv (uint64_t op1, uint64_t op2)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    uint64_t res;
 | 
					 | 
				
			||||||
    res = op1 - op2;
 | 
					 | 
				
			||||||
    if (unlikely((op1 ^ op2) & (res ^ op1) & (1ULL << 63))) {
 | 
					 | 
				
			||||||
        arith_excp(env, GETPC(), EXC_M_IOV, 0);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return res;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint64_t helper_sublv (uint64_t op1, uint64_t op2)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    uint32_t res;
 | 
					 | 
				
			||||||
    res = op1 - op2;
 | 
					 | 
				
			||||||
    if (unlikely((op1 ^ op2) & (res ^ op1) & (1UL << 31))) {
 | 
					 | 
				
			||||||
        arith_excp(env, GETPC(), EXC_M_IOV, 0);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return res;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint64_t helper_mullv (uint64_t op1, uint64_t op2)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int64_t res = (int64_t)op1 * (int64_t)op2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (unlikely((int32_t)res != res)) {
 | 
					 | 
				
			||||||
        arith_excp(env, GETPC(), EXC_M_IOV, 0);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return (int64_t)((int32_t)res);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint64_t helper_mulqv (uint64_t op1, uint64_t op2)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    uint64_t tl, th;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    muls64(&tl, &th, op1, op2);
 | 
					 | 
				
			||||||
    /* If th != 0 && th != -1, then we had an overflow */
 | 
					 | 
				
			||||||
    if (unlikely((th + 1) > 1)) {
 | 
					 | 
				
			||||||
        arith_excp(env, GETPC(), EXC_M_IOV, 0);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return tl;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* PALcode support special instructions */
 | 
					/* PALcode support special instructions */
 | 
				
			||||||
#if !defined (CONFIG_USER_ONLY)
 | 
					#if !defined (CONFIG_USER_ONLY)
 | 
				
			||||||
void helper_hw_ret (uint64_t a)
 | 
					void helper_hw_ret (uint64_t a)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1392,14 +1392,8 @@ static inline void glue(gen_, name)(int ra, int rb, int rc, int islit,\
 | 
				
			||||||
        tcg_temp_free(tmp1);                                          \
 | 
					        tcg_temp_free(tmp1);                                          \
 | 
				
			||||||
    }                                                                 \
 | 
					    }                                                                 \
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
ARITH3(cmpbge)
 | 
					 | 
				
			||||||
ARITH3(addlv)
 | 
					 | 
				
			||||||
ARITH3(sublv)
 | 
					 | 
				
			||||||
ARITH3(addqv)
 | 
					 | 
				
			||||||
ARITH3(subqv)
 | 
					 | 
				
			||||||
ARITH3(umulh)
 | 
					ARITH3(umulh)
 | 
				
			||||||
ARITH3(mullv)
 | 
					ARITH3(cmpbge)
 | 
				
			||||||
ARITH3(mulqv)
 | 
					 | 
				
			||||||
ARITH3(minub8)
 | 
					ARITH3(minub8)
 | 
				
			||||||
ARITH3(minsb8)
 | 
					ARITH3(minsb8)
 | 
				
			||||||
ARITH3(minuw4)
 | 
					ARITH3(minuw4)
 | 
				
			||||||
| 
						 | 
					@ -1410,6 +1404,43 @@ ARITH3(maxuw4)
 | 
				
			||||||
ARITH3(maxsw4)
 | 
					ARITH3(maxsw4)
 | 
				
			||||||
ARITH3(perr)
 | 
					ARITH3(perr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Code to call arith3 helpers */
 | 
				
			||||||
 | 
					#define ARITH3_EX(name)                                                 \
 | 
				
			||||||
 | 
					    static inline void glue(gen_, name)(int ra, int rb, int rc,         \
 | 
				
			||||||
 | 
					                                        int islit, uint8_t lit)         \
 | 
				
			||||||
 | 
					    {                                                                   \
 | 
				
			||||||
 | 
					        if (unlikely(rc == 31)) {                                       \
 | 
				
			||||||
 | 
					            return;                                                     \
 | 
				
			||||||
 | 
					        }                                                               \
 | 
				
			||||||
 | 
					        if (ra != 31) {                                                 \
 | 
				
			||||||
 | 
					            if (islit) {                                                \
 | 
				
			||||||
 | 
					                TCGv tmp = tcg_const_i64(lit);                          \
 | 
				
			||||||
 | 
					                gen_helper_ ## name(cpu_ir[rc], cpu_env,                \
 | 
				
			||||||
 | 
					                                    cpu_ir[ra], tmp);                   \
 | 
				
			||||||
 | 
					                tcg_temp_free(tmp);                                     \
 | 
				
			||||||
 | 
					            } else {                                                    \
 | 
				
			||||||
 | 
					                gen_helper_ ## name(cpu_ir[rc], cpu_env,                \
 | 
				
			||||||
 | 
					                                    cpu_ir[ra], cpu_ir[rb]);            \
 | 
				
			||||||
 | 
					            }                                                           \
 | 
				
			||||||
 | 
					        } else {                                                        \
 | 
				
			||||||
 | 
					            TCGv tmp1 = tcg_const_i64(0);                               \
 | 
				
			||||||
 | 
					            if (islit) {                                                \
 | 
				
			||||||
 | 
					                TCGv tmp2 = tcg_const_i64(lit);                         \
 | 
				
			||||||
 | 
					                gen_helper_ ## name(cpu_ir[rc], cpu_env, tmp1, tmp2);   \
 | 
				
			||||||
 | 
					                tcg_temp_free(tmp2);                                    \
 | 
				
			||||||
 | 
					            } else {                                                    \
 | 
				
			||||||
 | 
					                gen_helper_ ## name(cpu_ir[rc], cpu_env, tmp1, cpu_ir[rb]); \
 | 
				
			||||||
 | 
					            }                                                           \
 | 
				
			||||||
 | 
					            tcg_temp_free(tmp1);                                        \
 | 
				
			||||||
 | 
					        }                                                               \
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					ARITH3_EX(addlv)
 | 
				
			||||||
 | 
					ARITH3_EX(sublv)
 | 
				
			||||||
 | 
					ARITH3_EX(addqv)
 | 
				
			||||||
 | 
					ARITH3_EX(subqv)
 | 
				
			||||||
 | 
					ARITH3_EX(mullv)
 | 
				
			||||||
 | 
					ARITH3_EX(mulqv)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MVIOP2(name)                                    \
 | 
					#define MVIOP2(name)                                    \
 | 
				
			||||||
static inline void glue(gen_, name)(int rb, int rc)     \
 | 
					static inline void glue(gen_, name)(int rb, int rc)     \
 | 
				
			||||||
{                                                       \
 | 
					{                                                       \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue