target-tricore: add RR_DIV and RR_DIV_U instructions of the v1.6 ISA
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> Reviewed-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
parent
0e045f43c4
commit
9371557115
@ -113,6 +113,8 @@ DEF_HELPER_3(dvinit_h_131, i64, env, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(dvadj, TCG_CALL_NO_RWG_SE, i64, i64, i32)
|
||||
DEF_HELPER_FLAGS_2(dvstep, TCG_CALL_NO_RWG_SE, i64, i64, i32)
|
||||
DEF_HELPER_FLAGS_2(dvstep_u, TCG_CALL_NO_RWG_SE, i64, i64, i32)
|
||||
DEF_HELPER_3(divide, i64, env, i32, i32)
|
||||
DEF_HELPER_3(divide_u, i64, env, i32, i32)
|
||||
/* mulh */
|
||||
DEF_HELPER_FLAGS_5(mul_h, TCG_CALL_NO_RWG_SE, i64, i32, i32, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_5(mulm_h, TCG_CALL_NO_RWG_SE, i64, i32, i32, i32, i32, i32)
|
||||
|
@ -2094,6 +2094,55 @@ uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2)
|
||||
return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
|
||||
}
|
||||
|
||||
uint64_t helper_divide(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
|
||||
{
|
||||
int32_t quotient, remainder;
|
||||
int32_t dividend = (int32_t)r1;
|
||||
int32_t divisor = (int32_t)r2;
|
||||
|
||||
if (divisor == 0) {
|
||||
if (dividend >= 0) {
|
||||
quotient = 0x7fffffff;
|
||||
remainder = 0;
|
||||
} else {
|
||||
quotient = 0x80000000;
|
||||
remainder = 0;
|
||||
}
|
||||
env->PSW_USB_V = (1 << 31);
|
||||
} else if ((divisor == 0xffffffff) && (dividend == 0x80000000)) {
|
||||
quotient = 0x7fffffff;
|
||||
remainder = 0;
|
||||
env->PSW_USB_V = (1 << 31);
|
||||
} else {
|
||||
remainder = dividend % divisor;
|
||||
quotient = (dividend - remainder)/divisor;
|
||||
env->PSW_USB_V = 0;
|
||||
}
|
||||
env->PSW_USB_SV |= env->PSW_USB_V;
|
||||
env->PSW_USB_AV = 0;
|
||||
return ((uint64_t)remainder << 32) | (uint32_t)quotient;
|
||||
}
|
||||
|
||||
uint64_t helper_divide_u(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
|
||||
{
|
||||
uint32_t quotient, remainder;
|
||||
uint32_t dividend = r1;
|
||||
uint32_t divisor = r2;
|
||||
|
||||
if (divisor == 0) {
|
||||
quotient = 0xffffffff;
|
||||
remainder = 0;
|
||||
env->PSW_USB_V = (1 << 31);
|
||||
} else {
|
||||
remainder = dividend % divisor;
|
||||
quotient = (dividend - remainder)/divisor;
|
||||
env->PSW_USB_V = 0;
|
||||
}
|
||||
env->PSW_USB_SV |= env->PSW_USB_V;
|
||||
env->PSW_USB_AV = 0;
|
||||
return ((uint64_t)remainder << 32) | quotient;
|
||||
}
|
||||
|
||||
uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
|
||||
uint32_t arg10, uint32_t arg11, uint32_t n)
|
||||
{
|
||||
|
@ -201,6 +201,15 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
|
||||
tcg_temp_free_i64(arg1); \
|
||||
} while (0)
|
||||
|
||||
#define GEN_HELPER_RR(name, rl, rh, arg1, arg2) do { \
|
||||
TCGv_i64 ret = tcg_temp_new_i64(); \
|
||||
\
|
||||
gen_helper_##name(ret, cpu_env, arg1, arg2); \
|
||||
tcg_gen_extr_i64_i32(rl, rh, ret); \
|
||||
\
|
||||
tcg_temp_free_i64(ret); \
|
||||
} while (0)
|
||||
|
||||
#define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF))
|
||||
#define EA_B_ABSOLUT(con) (((offset & 0xf00000) << 8) | \
|
||||
((offset & 0x0fffff) << 1))
|
||||
@ -6494,6 +6503,18 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
|
||||
gen_helper_crc32(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||
} /* TODO: else raise illegal opcode trap */
|
||||
break;
|
||||
case OPC2_32_RR_DIV:
|
||||
if (tricore_feature(env, TRICORE_FEATURE_16)) {
|
||||
GEN_HELPER_RR(divide, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
|
||||
cpu_gpr_d[r2]);
|
||||
} /* TODO: else raise illegal opcode trap */
|
||||
break;
|
||||
case OPC2_32_RR_DIV_U:
|
||||
if (tricore_feature(env, TRICORE_FEATURE_16)) {
|
||||
GEN_HELPER_RR(divide_u, cpu_gpr_d[r3], cpu_gpr_d[r3+1],
|
||||
cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||
} /* TODO: else raise illegal opcode trap */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1124,6 +1124,8 @@ enum {
|
||||
OPC2_32_RR_PARITY = 0x02,
|
||||
OPC2_32_RR_UNPACK = 0x08,
|
||||
OPC2_32_RR_CRC32 = 0x03,
|
||||
OPC2_32_RR_DIV = 0x20,
|
||||
OPC2_32_RR_DIV_U = 0x21,
|
||||
};
|
||||
/* OPCM_32_RR_IDIRECT */
|
||||
enum {
|
||||
|
Loading…
Reference in New Issue
Block a user