diff options
Diffstat (limited to 'target-tricore/op_helper.c')
-rw-r--r-- | target-tricore/op_helper.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c index 7aa1f8e40e..10ed541dfd 100644 --- a/target-tricore/op_helper.c +++ b/target-tricore/op_helper.c @@ -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) { |