mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
target-tricore: Add instructions of RCR opcode format
Add instructions of RCR opcode format. Add helper for madd32/64_ssov and madd32/64_suov. Add helper for msub32/64_ssov and msub32/64_suov. Add microcode generator function madd/msub for 32bit and 64bit, which calculate a mul and a add/sub. OPC2_32_RCR_MSUB_U_32 -> OPC2_32_RCR_MSUB_U_32. Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> Reviewed-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
@@ -24,6 +24,14 @@ DEF_HELPER_3(mul_ssov, i32, env, i32, i32)
|
||||
DEF_HELPER_3(mul_suov, i32, env, i32, i32)
|
||||
DEF_HELPER_3(sha_ssov, i32, env, i32, i32)
|
||||
DEF_HELPER_3(absdif_ssov, i32, env, i32, i32)
|
||||
DEF_HELPER_4(madd32_ssov, i32, env, i32, i32, i32)
|
||||
DEF_HELPER_4(madd32_suov, i32, env, i32, i32, i32)
|
||||
DEF_HELPER_4(madd64_ssov, i64, env, i32, i64, i32)
|
||||
DEF_HELPER_4(madd64_suov, i64, env, i32, i64, i32)
|
||||
DEF_HELPER_4(msub32_ssov, i32, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msub32_suov, i32, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msub64_ssov, i64, env, i32, i64, i32)
|
||||
DEF_HELPER_4(msub64_suov, i64, env, i32, i64, i32)
|
||||
/* CSA */
|
||||
DEF_HELPER_2(call, void, env, i32)
|
||||
DEF_HELPER_1(ret, void, env)
|
||||
|
||||
@@ -198,6 +198,174 @@ target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
|
||||
SSOV(env, ret, result, 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
|
||||
target_ulong r2, target_ulong r3)
|
||||
{
|
||||
target_ulong ret;
|
||||
int64_t t1 = sextract64(r1, 0, 32);
|
||||
int64_t t2 = sextract64(r2, 0, 32);
|
||||
int64_t t3 = sextract64(r3, 0, 32);
|
||||
int64_t result;
|
||||
|
||||
result = t2 + (t1 * t3);
|
||||
SSOV(env, ret, result, 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
|
||||
target_ulong r2, target_ulong r3)
|
||||
{
|
||||
target_ulong ret;
|
||||
uint64_t t1 = extract64(r1, 0, 32);
|
||||
uint64_t t2 = extract64(r2, 0, 32);
|
||||
uint64_t t3 = extract64(r3, 0, 32);
|
||||
int64_t result;
|
||||
|
||||
result = t2 + (t1 * t3);
|
||||
SUOV(env, ret, result, 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
|
||||
uint64_t r2, target_ulong r3)
|
||||
{
|
||||
uint64_t ret, ovf;
|
||||
int64_t t1 = sextract64(r1, 0, 32);
|
||||
int64_t t3 = sextract64(r3, 0, 32);
|
||||
int64_t mul;
|
||||
|
||||
mul = t1 * t3;
|
||||
ret = mul + r2;
|
||||
ovf = (ret ^ mul) & ~(mul ^ r2);
|
||||
|
||||
if ((int64_t)ovf < 0) {
|
||||
env->PSW_USB_V = (1 << 31);
|
||||
env->PSW_USB_SV = (1 << 31);
|
||||
/* ext_ret > MAX_INT */
|
||||
if (mul >= 0) {
|
||||
ret = INT64_MAX;
|
||||
/* ext_ret < MIN_INT */
|
||||
} else {
|
||||
ret = INT64_MIN;
|
||||
}
|
||||
} else {
|
||||
env->PSW_USB_V = 0;
|
||||
}
|
||||
t1 = ret >> 32;
|
||||
env->PSW_USB_AV = t1 ^ t1 * 2u;
|
||||
env->PSW_USB_SAV |= env->PSW_USB_AV;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
|
||||
uint64_t r2, target_ulong r3)
|
||||
{
|
||||
uint64_t ret, mul;
|
||||
uint64_t t1 = extract64(r1, 0, 32);
|
||||
uint64_t t3 = extract64(r3, 0, 32);
|
||||
|
||||
mul = t1 * t3;
|
||||
ret = mul + r2;
|
||||
|
||||
if (ret < r2) {
|
||||
env->PSW_USB_V = (1 << 31);
|
||||
env->PSW_USB_SV = (1 << 31);
|
||||
/* saturate */
|
||||
ret = UINT64_MAX;
|
||||
} else {
|
||||
env->PSW_USB_V = 0;
|
||||
}
|
||||
t1 = ret >> 32;
|
||||
env->PSW_USB_AV = t1 ^ t1 * 2u;
|
||||
env->PSW_USB_SAV |= env->PSW_USB_AV;
|
||||
return ret;
|
||||
}
|
||||
|
||||
target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
|
||||
target_ulong r2, target_ulong r3)
|
||||
{
|
||||
target_ulong ret;
|
||||
int64_t t1 = sextract64(r1, 0, 32);
|
||||
int64_t t2 = sextract64(r2, 0, 32);
|
||||
int64_t t3 = sextract64(r3, 0, 32);
|
||||
int64_t result;
|
||||
|
||||
result = t2 - (t1 * t3);
|
||||
SSOV(env, ret, result, 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
|
||||
target_ulong r2, target_ulong r3)
|
||||
{
|
||||
target_ulong ret;
|
||||
int64_t t1 = extract64(r1, 0, 32);
|
||||
int64_t t2 = extract64(r2, 0, 32);
|
||||
int64_t t3 = extract64(r3, 0, 32);
|
||||
int64_t result;
|
||||
|
||||
result = t2 - (t1 * t3);
|
||||
SUOV(env, ret, result, 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
|
||||
uint64_t r2, target_ulong r3)
|
||||
{
|
||||
uint64_t ret, ovf;
|
||||
int64_t t1 = sextract64(r1, 0, 32);
|
||||
int64_t t3 = sextract64(r3, 0, 32);
|
||||
int64_t mul;
|
||||
|
||||
mul = t1 * t3;
|
||||
ret = r2 - mul;
|
||||
ovf = (ret ^ r2) & (mul ^ r2);
|
||||
|
||||
if ((int64_t)ovf < 0) {
|
||||
env->PSW_USB_V = (1 << 31);
|
||||
env->PSW_USB_SV = (1 << 31);
|
||||
/* ext_ret > MAX_INT */
|
||||
if (mul < 0) {
|
||||
ret = INT64_MAX;
|
||||
/* ext_ret < MIN_INT */
|
||||
} else {
|
||||
ret = INT64_MIN;
|
||||
}
|
||||
} else {
|
||||
env->PSW_USB_V = 0;
|
||||
}
|
||||
t1 = ret >> 32;
|
||||
env->PSW_USB_AV = t1 ^ t1 * 2u;
|
||||
env->PSW_USB_SAV |= env->PSW_USB_AV;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
|
||||
uint64_t r2, target_ulong r3)
|
||||
{
|
||||
uint64_t ret, mul;
|
||||
uint64_t t1 = extract64(r1, 0, 32);
|
||||
uint64_t t3 = extract64(r3, 0, 32);
|
||||
|
||||
mul = t1 * t3;
|
||||
ret = r2 - mul;
|
||||
|
||||
if (ret > r2) {
|
||||
env->PSW_USB_V = (1 << 31);
|
||||
env->PSW_USB_SV = (1 << 31);
|
||||
/* saturate */
|
||||
ret = 0;
|
||||
} else {
|
||||
env->PSW_USB_V = 0;
|
||||
}
|
||||
t1 = ret >> 32;
|
||||
env->PSW_USB_AV = t1 ^ t1 * 2u;
|
||||
env->PSW_USB_SAV |= env->PSW_USB_AV;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* context save area (CSA) related helpers */
|
||||
|
||||
static int cdc_increment(target_ulong *psw)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -169,6 +169,7 @@
|
||||
#define MASK_OP_RCR_S3(op) MASK_BITS_SHIFT(op, 24, 27)
|
||||
#define MASK_OP_RCR_OP2(op) MASK_BITS_SHIFT(op, 21, 23)
|
||||
#define MASK_OP_RCR_CONST9(op) MASK_BITS_SHIFT(op, 12, 20)
|
||||
#define MASK_OP_RCR_CONST9_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 20)
|
||||
#define MASK_OP_RCR_S1(op) MASK_OP_META_S1(op)
|
||||
|
||||
/* RCRR Format */
|
||||
@@ -945,7 +946,7 @@ enum {
|
||||
OPC2_32_RCR_MSUB_64 = 0x03,
|
||||
OPC2_32_RCR_MSUBS_32 = 0x05,
|
||||
OPC2_32_RCR_MSUBS_64 = 0x07,
|
||||
OPC2_32_RCR_MSUB_U_32 = 0x02,
|
||||
OPC2_32_RCR_MSUB_U_64 = 0x02,
|
||||
OPC2_32_RCR_MSUBS_U_32 = 0x04,
|
||||
OPC2_32_RCR_MSUBS_U_64 = 0x06,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user