diff options
Diffstat (limited to 'target-mips/op_helper.c')
-rw-r--r-- | target-mips/op_helper.c | 1292 |
1 files changed, 823 insertions, 469 deletions
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index eae5b7489..008fb2c0b 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -89,25 +89,25 @@ target_ulong do_dclz (target_ulong t0) /* 64 bits arithmetic for 32 bits hosts */ static always_inline uint64_t get_HILO (void) { - return ((uint64_t)(env->HI[env->current_tc][0]) << 32) | (uint32_t)env->LO[env->current_tc][0]; + return ((uint64_t)(env->active_tc.HI[0]) << 32) | (uint32_t)env->active_tc.LO[0]; } static always_inline void set_HILO (uint64_t HILO) { - env->LO[env->current_tc][0] = (int32_t)HILO; - env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); + env->active_tc.LO[0] = (int32_t)HILO; + env->active_tc.HI[0] = (int32_t)(HILO >> 32); } static always_inline void set_HIT0_LO (target_ulong t0, uint64_t HILO) { - env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF); - t0 = env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); + env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF); + t0 = env->active_tc.HI[0] = (int32_t)(HILO >> 32); } static always_inline void set_HI_LOT0 (target_ulong t0, uint64_t HILO) { - t0 = env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF); - env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); + t0 = env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF); + env->active_tc.HI[0] = (int32_t)(HILO >> 32); } #if TARGET_LONG_BITS > HOST_LONG_BITS @@ -246,12 +246,12 @@ target_ulong do_mulshiu (target_ulong t0, target_ulong t1) #ifdef TARGET_MIPS64 void do_dmult (target_ulong t0, target_ulong t1) { - muls64(&(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), t0, t1); + muls64(&(env->active_tc.LO[0]), &(env->active_tc.HI[0]), t0, t1); } void do_dmultu (target_ulong t0, target_ulong t1) { - mulu64(&(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), t0, t1); + mulu64(&(env->active_tc.LO[0]), &(env->active_tc.HI[0]), t0, t1); } #endif @@ -672,86 +672,107 @@ target_ulong do_mfc0_random (void) target_ulong do_mfc0_tcstatus (void) { - return env->CP0_TCStatus[env->current_tc]; + return env->active_tc.CP0_TCStatus; } target_ulong do_mftc0_tcstatus(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - return env->CP0_TCStatus[other_tc]; + if (other_tc == env->current_tc) + return env->active_tc.CP0_TCStatus; + else + return env->tcs[other_tc].CP0_TCStatus; } target_ulong do_mfc0_tcbind (void) { - return env->CP0_TCBind[env->current_tc]; + return env->active_tc.CP0_TCBind; } target_ulong do_mftc0_tcbind(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - return env->CP0_TCBind[other_tc]; + if (other_tc == env->current_tc) + return env->active_tc.CP0_TCBind; + else + return env->tcs[other_tc].CP0_TCBind; } target_ulong do_mfc0_tcrestart (void) { - return env->PC[env->current_tc]; + return env->active_tc.PC; } target_ulong do_mftc0_tcrestart(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - return env->PC[other_tc]; + if (other_tc == env->current_tc) + return env->active_tc.PC; + else + return env->tcs[other_tc].PC; } target_ulong do_mfc0_tchalt (void) { - return env->CP0_TCHalt[env->current_tc]; + return env->active_tc.CP0_TCHalt; } target_ulong do_mftc0_tchalt(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - return env->CP0_TCHalt[other_tc]; + if (other_tc == env->current_tc) + return env->active_tc.CP0_TCHalt; + else + return env->tcs[other_tc].CP0_TCHalt; } target_ulong do_mfc0_tccontext (void) { - return env->CP0_TCContext[env->current_tc]; + return env->active_tc.CP0_TCContext; } target_ulong do_mftc0_tccontext(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - return env->CP0_TCContext[other_tc]; + if (other_tc == env->current_tc) + return env->active_tc.CP0_TCContext; + else + return env->tcs[other_tc].CP0_TCContext; } target_ulong do_mfc0_tcschedule (void) { - return env->CP0_TCSchedule[env->current_tc]; + return env->active_tc.CP0_TCSchedule; } target_ulong do_mftc0_tcschedule(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - return env->CP0_TCSchedule[other_tc]; + if (other_tc == env->current_tc) + return env->active_tc.CP0_TCSchedule; + else + return env->tcs[other_tc].CP0_TCSchedule; } target_ulong do_mfc0_tcschefback (void) { - return env->CP0_TCScheFBack[env->current_tc]; + return env->active_tc.CP0_TCScheFBack; } target_ulong do_mftc0_tcschefback(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - return env->CP0_TCScheFBack[other_tc]; + if (other_tc == env->current_tc) + return env->active_tc.CP0_TCScheFBack; + else + return env->tcs[other_tc].CP0_TCScheFBack; } target_ulong do_mfc0_count (void) @@ -762,15 +783,26 @@ target_ulong do_mfc0_count (void) target_ulong do_mftc0_entryhi(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + int32_t tcstatus; + + if (other_tc == env->current_tc) + tcstatus = env->active_tc.CP0_TCStatus; + else + tcstatus = env->tcs[other_tc].CP0_TCStatus; - return (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff); + return (env->CP0_EntryHi & ~0xff) | (tcstatus & 0xff); } target_ulong do_mftc0_status(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - uint32_t tcstatus = env->CP0_TCStatus[other_tc]; target_ulong t0; + int32_t tcstatus; + + if (other_tc == env->current_tc) + tcstatus = env->active_tc.CP0_TCStatus; + else + tcstatus = env->tcs[other_tc].CP0_TCStatus; t0 = env->CP0_Status & ~0xf1000018; t0 |= tcstatus & (0xf << CP0TCSt_TCU0); @@ -807,37 +839,42 @@ target_ulong do_mfc0_debug (void) target_ulong do_mftc0_debug(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + int32_t tcstatus; + + if (other_tc == env->current_tc) + tcstatus = env->active_tc.CP0_Debug_tcstatus; + else + tcstatus = env->tcs[other_tc].CP0_Debug_tcstatus; /* XXX: Might be wrong, check with EJTAG spec. */ return (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) | - (env->CP0_Debug_tcstatus[other_tc] & - ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))); + (tcstatus & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))); } #if defined(TARGET_MIPS64) target_ulong do_dmfc0_tcrestart (void) { - return env->PC[env->current_tc]; + return env->active_tc.PC; } target_ulong do_dmfc0_tchalt (void) { - return env->CP0_TCHalt[env->current_tc]; + return env->active_tc.CP0_TCHalt; } target_ulong do_dmfc0_tccontext (void) { - return env->CP0_TCContext[env->current_tc]; + return env->active_tc.CP0_TCContext; } target_ulong do_dmfc0_tcschedule (void) { - return env->CP0_TCSchedule[env->current_tc]; + return env->active_tc.CP0_TCSchedule; } target_ulong do_dmfc0_tcschefback (void) { - return env->CP0_TCScheFBack[env->current_tc]; + return env->active_tc.CP0_TCScheFBack; } target_ulong do_dmfc0_lladdr (void) @@ -955,11 +992,11 @@ void do_mtc0_tcstatus (target_ulong t0) uint32_t mask = env->CP0_TCStatus_rw_bitmask; uint32_t newval; - newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (t0 & mask); + newval = (env->active_tc.CP0_TCStatus & ~mask) | (t0 & mask); // TODO: Sync with CP0_Status. - env->CP0_TCStatus[env->current_tc] = newval; + env->active_tc.CP0_TCStatus = newval; } void do_mttc0_tcstatus (target_ulong t0) @@ -968,7 +1005,10 @@ void do_mttc0_tcstatus (target_ulong t0) // TODO: Sync with CP0_Status. - env->CP0_TCStatus[other_tc] = t0; + if (other_tc == env->current_tc) + env->active_tc.CP0_TCStatus = t0; + else + env->tcs[other_tc].CP0_TCStatus = t0; } void do_mtc0_tcbind (target_ulong t0) @@ -978,8 +1018,8 @@ void do_mtc0_tcbind (target_ulong t0) if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) mask |= (1 << CP0TCBd_CurVPE); - newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (t0 & mask); - env->CP0_TCBind[env->current_tc] = newval; + newval = (env->active_tc.CP0_TCBind & ~mask) | (t0 & mask); + env->active_tc.CP0_TCBind = newval; } void do_mttc0_tcbind (target_ulong t0) @@ -990,14 +1030,19 @@ void do_mttc0_tcbind (target_ulong t0) if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) mask |= (1 << CP0TCBd_CurVPE); - newval = (env->CP0_TCBind[other_tc] & ~mask) | (t0 & mask); - env->CP0_TCBind[other_tc] = newval; + if (other_tc == env->current_tc) { + newval = (env->active_tc.CP0_TCBind & ~mask) | (t0 & mask); + env->active_tc.CP0_TCBind = newval; + } else { + newval = (env->tcs[other_tc].CP0_TCBind & ~mask) | (t0 & mask); + env->tcs[other_tc].CP0_TCBind = newval; + } } void do_mtc0_tcrestart (target_ulong t0) { - env->PC[env->current_tc] = t0; - env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS); + env->active_tc.PC = t0; + env->active_tc.CP0_TCStatus &= ~(1 << CP0TCSt_TDS); env->CP0_LLAddr = 0ULL; /* MIPS16 not implemented. */ } @@ -1006,15 +1051,22 @@ void do_mttc0_tcrestart (target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - env->PC[other_tc] = t0; - env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS); - env->CP0_LLAddr = 0ULL; - /* MIPS16 not implemented. */ + if (other_tc == env->current_tc) { + env->active_tc.PC = t0; + env->active_tc.CP0_TCStatus &= ~(1 << CP0TCSt_TDS); + env->CP0_LLAddr = 0ULL; + /* MIPS16 not implemented. */ + } else { + env->tcs[other_tc].PC = t0; + env->tcs[other_tc].CP0_TCStatus &= ~(1 << CP0TCSt_TDS); + env->CP0_LLAddr = 0ULL; + /* MIPS16 not implemented. */ + } } void do_mtc0_tchalt (target_ulong t0) { - env->CP0_TCHalt[env->current_tc] = t0 & 0x1; + env->active_tc.CP0_TCHalt = t0 & 0x1; // TODO: Halt TC / Restart (if allocated+active) TC. } @@ -1025,43 +1077,55 @@ void do_mttc0_tchalt (target_ulong t0) // TODO: Halt TC / Restart (if allocated+active) TC. - env->CP0_TCHalt[other_tc] = t0; + if (other_tc == env->current_tc) + env->active_tc.CP0_TCHalt = t0; + else + env->tcs[other_tc].CP0_TCHalt = t0; } void do_mtc0_tccontext (target_ulong t0) { - env->CP0_TCContext[env->current_tc] = t0; + env->active_tc.CP0_TCContext = t0; } void do_mttc0_tccontext (target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - env->CP0_TCContext[other_tc] = t0; + if (other_tc == env->current_tc) + env->active_tc.CP0_TCContext = t0; + else + env->tcs[other_tc].CP0_TCContext = t0; } void do_mtc0_tcschedule (target_ulong t0) { - env->CP0_TCSchedule[env->current_tc] = t0; + env->active_tc.CP0_TCSchedule = t0; } void do_mttc0_tcschedule (target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - env->CP0_TCSchedule[other_tc] = t0; + if (other_tc == env->current_tc) + env->active_tc.CP0_TCSchedule = t0; + else + env->tcs[other_tc].CP0_TCSchedule = t0; } void do_mtc0_tcschefback (target_ulong t0) { - env->CP0_TCScheFBack[env->current_tc] = t0; + env->active_tc.CP0_TCScheFBack = t0; } void do_mttc0_tcschefback (target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - env->CP0_TCScheFBack[other_tc] = t0; + if (other_tc == env->current_tc) + env->active_tc.CP0_TCScheFBack = t0; + else + env->tcs[other_tc].CP0_TCScheFBack = t0; } void do_mtc0_entrylo1 (target_ulong t0) @@ -1142,8 +1206,8 @@ void do_mtc0_entryhi (target_ulong t0) old = env->CP0_EntryHi; env->CP0_EntryHi = val; if (env->CP0_Config3 & (1 << CP0C3_MT)) { - uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff; - env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff); + uint32_t tcst = env->active_tc.CP0_TCStatus & ~0xff; + env->active_tc.CP0_TCStatus = tcst | (val & 0xff); } /* If the ASID changes, flush qemu's TLB. */ if ((old & 0xFF) != (val & 0xFF)) @@ -1153,9 +1217,16 @@ void do_mtc0_entryhi (target_ulong t0) void do_mttc0_entryhi(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + int32_t tcstatus; env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (t0 & ~0xff); - env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (t0 & 0xff); + if (other_tc == env->current_tc) { + tcstatus = (env->active_tc.CP0_TCStatus & ~0xff) | (t0 & 0xff); + env->active_tc.CP0_TCStatus = tcstatus; + } else { + tcstatus = (env->tcs[other_tc].CP0_TCStatus & ~0xff) | (t0 & 0xff); + env->tcs[other_tc].CP0_TCStatus = tcstatus; + } } void do_mtc0_compare (target_ulong t0) @@ -1180,13 +1251,16 @@ void do_mtc0_status (target_ulong t0) void do_mttc0_status(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - uint32_t tcstatus = env->CP0_TCStatus[other_tc]; + int32_t tcstatus = env->tcs[other_tc].CP0_TCStatus; env->CP0_Status = t0 & ~0xf1000018; tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (t0 & (0xf << CP0St_CU0)); tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((t0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX)); tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((t0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU)); - env->CP0_TCStatus[other_tc] = tcstatus; + if (other_tc == env->current_tc) + env->active_tc.CP0_TCStatus = tcstatus; + else + env->tcs[other_tc].CP0_TCStatus = tcstatus; } void do_mtc0_intctl (target_ulong t0) @@ -1279,9 +1353,13 @@ void do_mtc0_debug (target_ulong t0) void do_mttc0_debug(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + uint32_t val = t0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)); /* XXX: Might be wrong, check with EJTAG spec. */ - env->CP0_Debug_tcstatus[other_tc] = t0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)); + if (other_tc == env->current_tc) + env->active_tc.CP0_Debug_tcstatus = val; + else + env->tcs[other_tc].CP0_Debug_tcstatus = val; env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) | (t0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))); } @@ -1336,70 +1414,100 @@ target_ulong do_mftgpr(target_ulong t0, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - return env->gpr[other_tc][sel]; + if (other_tc == env->current_tc) + return env->active_tc.gpr[sel]; + else + return env->tcs[other_tc].gpr[sel]; } target_ulong do_mftlo(target_ulong t0, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - return env->LO[other_tc][sel]; + if (other_tc == env->current_tc) + return env->active_tc.LO[sel]; + else + return env->tcs[other_tc].LO[sel]; } target_ulong do_mfthi(target_ulong t0, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - return env->HI[other_tc][sel]; + if (other_tc == env->current_tc) + return env->active_tc.HI[sel]; + else + return env->tcs[other_tc].HI[sel]; } target_ulong do_mftacx(target_ulong t0, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - return env->ACX[other_tc][sel]; + if (other_tc == env->current_tc) + return env->active_tc.ACX[sel]; + else + return env->tcs[other_tc].ACX[sel]; } target_ulong do_mftdsp(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - return env->DSPControl[other_tc]; + if (other_tc == env->current_tc) + return env->active_tc.DSPControl; + else + return env->tcs[other_tc].DSPControl; } void do_mttgpr(target_ulong t0, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - env->gpr[other_tc][sel] = t0; + if (other_tc == env->current_tc) + env->active_tc.gpr[sel] = t0; + else + env->tcs[other_tc].gpr[sel] = t0; } void do_mttlo(target_ulong t0, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - env->LO[other_tc][sel] = t0; + if (other_tc == env->current_tc) + env->active_tc.LO[sel] = t0; + else + env->tcs[other_tc].LO[sel] = t0; } void do_mtthi(target_ulong t0, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - env->HI[other_tc][sel] = t0; + if (other_tc == env->current_tc) + env->active_tc.HI[sel] = t0; + else + env->tcs[other_tc].HI[sel] = t0; } void do_mttacx(target_ulong t0, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - env->ACX[other_tc][sel] = t0; + if (other_tc == env->current_tc) + env->active_tc.ACX[sel] = t0; + else + env->tcs[other_tc].ACX[sel] = t0; } void do_mttdsp(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - env->DSPControl[other_tc] = t0; + if (other_tc == env->current_tc) + env->active_tc.DSPControl = t0; + else + env->tcs[other_tc].DSPControl = t0; } /* MIPS MT functions */ @@ -1452,7 +1560,7 @@ target_ulong do_yield(target_ulong t0) /* No scheduling policy implemented. */ if (t0 != -2) { if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) && - env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) { + env->active_tc.CP0_TCStatus & (1 << CP0TCSt_DT)) { env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT); env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT; do_raise_exception(EXCP_THREAD); @@ -1638,18 +1746,20 @@ void r4k_do_tlbr (void) #endif /* !CONFIG_USER_ONLY */ /* Specials */ -target_ulong do_di (target_ulong t0) +target_ulong do_di (void) { - t0 = env->CP0_Status; + target_ulong t0 = env->CP0_Status; + env->CP0_Status = t0 & ~(1 << CP0St_IE); cpu_mips_update_irq(env); return t0; } -target_ulong do_ei (target_ulong t0) +target_ulong do_ei (void) { - t0 = env->CP0_Status; + target_ulong t0 = env->CP0_Status; + env->CP0_Status = t0 | (1 << CP0St_IE); cpu_mips_update_irq(env); @@ -1659,7 +1769,7 @@ target_ulong do_ei (target_ulong t0) void debug_pre_eret (void) { fprintf(logfile, "ERET: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx, - env->PC[env->current_tc], env->CP0_EPC); + env->active_tc.PC, env->CP0_EPC); if (env->CP0_Status & (1 << CP0St_ERL)) fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC); if (env->hflags & MIPS_HFLAG_DM) @@ -1670,7 +1780,7 @@ void debug_pre_eret (void) void debug_post_eret (void) { fprintf(logfile, " => PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx, - env->PC[env->current_tc], env->CP0_EPC); + env->active_tc.PC, env->CP0_EPC); if (env->CP0_Status & (1 << CP0St_ERL)) fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC); if (env->hflags & MIPS_HFLAG_DM) @@ -1688,10 +1798,10 @@ void do_eret (void) if (loglevel & CPU_LOG_EXEC) debug_pre_eret(); if (env->CP0_Status & (1 << CP0St_ERL)) { - env->PC[env->current_tc] = env->CP0_ErrorEPC; + env->active_tc.PC = env->CP0_ErrorEPC; env->CP0_Status &= ~(1 << CP0St_ERL); } else { - env->PC[env->current_tc] = env->CP0_EPC; + env->active_tc.PC = env->CP0_EPC; env->CP0_Status &= ~(1 << CP0St_EXL); } compute_hflags(env); @@ -1704,7 +1814,7 @@ void do_deret (void) { if (loglevel & CPU_LOG_EXEC) debug_pre_eret(); - env->PC[env->current_tc] = env->CP0_DEPC; + env->active_tc.PC = env->CP0_DEPC; env->hflags &= MIPS_HFLAG_DM; compute_hflags(env); if (loglevel & CPU_LOG_EXEC) @@ -1712,52 +1822,52 @@ void do_deret (void) env->CP0_LLAddr = 1; } -target_ulong do_rdhwr_cpunum(target_ulong t0) +target_ulong do_rdhwr_cpunum(void) { if ((env->hflags & MIPS_HFLAG_CP0) || (env->CP0_HWREna & (1 << 0))) - t0 = env->CP0_EBase & 0x3ff; + return env->CP0_EBase & 0x3ff; else do_raise_exception(EXCP_RI); - return t0; + return 0; } -target_ulong do_rdhwr_synci_step(target_ulong t0) +target_ulong do_rdhwr_synci_step(void) { if ((env->hflags & MIPS_HFLAG_CP0) || (env->CP0_HWREna & (1 << 1))) - t0 = env->SYNCI_Step; + return env->SYNCI_Step; else do_raise_exception(EXCP_RI); - return t0; + return 0; } -target_ulong do_rdhwr_cc(target_ulong t0) +target_ulong do_rdhwr_cc(void) { if ((env->hflags & MIPS_HFLAG_CP0) || (env->CP0_HWREna & (1 << 2))) - t0 = env->CP0_Count; + return env->CP0_Count; else do_raise_exception(EXCP_RI); - return t0; + return 0; } -target_ulong do_rdhwr_ccres(target_ulong t0) +target_ulong do_rdhwr_ccres(void) { if ((env->hflags & MIPS_HFLAG_CP0) || (env->CP0_HWREna & (1 << 3))) - t0 = env->CCRes; + return env->CCRes; else do_raise_exception(EXCP_RI); - return t0; + return 0; } /* Bitfield operations. */ -target_ulong do_ext(target_ulong t0, target_ulong t1, uint32_t pos, uint32_t size) +target_ulong do_ext(target_ulong t1, uint32_t pos, uint32_t size) { return (int32_t)((t1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0)); } @@ -1769,13 +1879,13 @@ target_ulong do_ins(target_ulong t0, target_ulong t1, uint32_t pos, uint32_t siz return (int32_t)((t0 & ~mask) | ((t1 << pos) & mask)); } -target_ulong do_wsbh(target_ulong t0, target_ulong t1) +target_ulong do_wsbh(target_ulong t1) { return (int32_t)(((t1 << 8) & ~0x00FF00FF) | ((t1 >> 8) & 0x00FF00FF)); } #if defined(TARGET_MIPS64) -target_ulong do_dext(target_ulong t0, target_ulong t1, uint32_t pos, uint32_t size) +target_ulong do_dext(target_ulong t1, uint32_t pos, uint32_t size) { return (t1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL); } @@ -1787,12 +1897,12 @@ target_ulong do_dins(target_ulong t0, target_ulong t1, uint32_t pos, uint32_t si return (t0 & ~mask) | ((t1 << pos) & mask); } -target_ulong do_dsbh(target_ulong t0, target_ulong t1) +target_ulong do_dsbh(target_ulong t1) { return ((t1 << 8) & ~0x00FF00FF00FF00FFULL) | ((t1 >> 8) & 0x00FF00FF00FF00FFULL); } -target_ulong do_dshd(target_ulong t0, target_ulong t1) +target_ulong do_dshd(target_ulong t1) { t1 = ((t1 << 16) & ~0x0000FFFF0000FFFFULL) | ((t1 >> 16) & 0x0000FFFF0000FFFFULL); return (t1 << 32) | (t1 >> 32); @@ -1804,21 +1914,21 @@ void do_pmon (int function) function /= 2; switch (function) { case 2: /* TODO: char inbyte(int waitflag); */ - if (env->gpr[env->current_tc][4] == 0) - env->gpr[env->current_tc][2] = -1; + if (env->active_tc.gpr[4] == 0) + env->active_tc.gpr[2] = -1; /* Fall through */ case 11: /* TODO: char inbyte (void); */ - env->gpr[env->current_tc][2] = -1; + env->active_tc.gpr[2] = -1; break; case 3: case 12: - printf("%c", (char)(env->gpr[env->current_tc][4] & 0xFF)); + printf("%c", (char)(env->active_tc.gpr[4] & 0xFF)); break; case 17: break; case 158: { - unsigned char *fmt = (void *)(unsigned long)env->gpr[env->current_tc][4]; + unsigned char *fmt = (void *)(unsigned long)env->active_tc.gpr[4]; printf("%s", fmt); } break; @@ -2011,380 +2121,555 @@ static always_inline void update_fcr31(void) "d" suffix, 32bit integer "w", 64bit integer "l", paired single "ps", paired single lower "pl", paired single upper "pu". */ -#define FLOAT_OP(name, p) void do_float_##name##_##p(void) - /* unary operations, modifying fp status */ -#define FLOAT_UNOP(name) \ -FLOAT_OP(name, d) \ -{ \ - FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \ -} \ -FLOAT_OP(name, s) \ -{ \ - FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \ -} -FLOAT_UNOP(sqrt) -#undef FLOAT_UNOP +uint64_t do_float_sqrt_d(uint64_t fdt0) +{ + return float64_sqrt(fdt0, &env->fpu->fp_status); +} + +uint32_t do_float_sqrt_s(uint32_t fst0) +{ + return float32_sqrt(fst0, &env->fpu->fp_status); +} -FLOAT_OP(cvtd, s) +uint64_t do_float_cvtd_s(uint32_t fst0) { + uint64_t fdt2; + set_float_exception_flags(0, &env->fpu->fp_status); - FDT2 = float32_to_float64(FST0, &env->fpu->fp_status); + fdt2 = float32_to_float64(fst0, &env->fpu->fp_status); update_fcr31(); + return fdt2; } -FLOAT_OP(cvtd, w) + +uint64_t do_float_cvtd_w(uint32_t wt0) { + uint64_t fdt2; + set_float_exception_flags(0, &env->fpu->fp_status); - FDT2 = int32_to_float64(WT0, &env->fpu->fp_status); + fdt2 = int32_to_float64(wt0, &env->fpu->fp_status); update_fcr31(); + return fdt2; } -FLOAT_OP(cvtd, l) + +uint64_t do_float_cvtd_l(uint64_t dt0) { + uint64_t fdt2; + set_float_exception_flags(0, &env->fpu->fp_status); - FDT2 = int64_to_float64(DT0, &env->fpu->fp_status); + fdt2 = int64_to_float64(dt0, &env->fpu->fp_status); update_fcr31(); + return fdt2; } -FLOAT_OP(cvtl, d) + +uint64_t do_float_cvtl_d(uint64_t fdt0) { + uint64_t dt2; + set_float_exception_flags(0, &env->fpu->fp_status); - DT2 = float64_to_int64(FDT0, &env->fpu->fp_status); + dt2 = float64_to_int64(fdt0, &env->fpu->fp_status); update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - DT2 = FLOAT_SNAN64; + dt2 = FLOAT_SNAN64; + return dt2; } -FLOAT_OP(cvtl, s) + +uint64_t do_float_cvtl_s(uint32_t fst0) { + uint64_t dt2; + set_float_exception_flags(0, &env->fpu->fp_status); - DT2 = float32_to_int64(FST0, &env->fpu->fp_status); + dt2 = float32_to_int64(fst0, &env->fpu->fp_status); update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - DT2 = FLOAT_SNAN64; + dt2 = FLOAT_SNAN64; + return dt2; } -FLOAT_OP(cvtps, pw) +uint64_t do_float_cvtps_pw(uint64_t dt0) { + uint32_t fst2; + uint32_t fsth2; + set_float_exception_flags(0, &env->fpu->fp_status); - FST2 = int32_to_float32(WT0, &env->fpu->fp_status); - FSTH2 = int32_to_float32(WTH0, &env->fpu->fp_status); + fst2 = int32_to_float32(dt0 & 0XFFFFFFFF, &env->fpu->fp_status); + fsth2 = int32_to_float32(dt0 >> 32, &env->fpu->fp_status); update_fcr31(); + return ((uint64_t)fsth2 << 32) | fst2; } -FLOAT_OP(cvtpw, ps) + +uint64_t do_float_cvtpw_ps(uint64_t fdt0) { + uint32_t wt2; + uint32_t wth2; + set_float_exception_flags(0, &env->fpu->fp_status); - WT2 = float32_to_int32(FST0, &env->fpu->fp_status); - WTH2 = float32_to_int32(FSTH0, &env->fpu->fp_status); + wt2 = float32_to_int32(fdt0 & 0XFFFFFFFF, &env->fpu->fp_status); + wth2 = float32_to_int32(fdt0 >> 32, &env->fpu->fp_status); update_fcr31(); - if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - WT2 = FLOAT_SNAN32; + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) { + wt2 = FLOAT_SNAN32; + wth2 = FLOAT_SNAN32; + } + return ((uint64_t)wth2 << 32) | wt2; } -FLOAT_OP(cvts, d) + +uint32_t do_float_cvts_d(uint64_t fdt0) { + uint32_t fst2; + set_float_exception_flags(0, &env->fpu->fp_status); - FST2 = float64_to_float32(FDT0, &env->fpu->fp_status); + fst2 = float64_to_float32(fdt0, &env->fpu->fp_status); update_fcr31(); + return fst2; } -FLOAT_OP(cvts, w) + +uint32_t do_float_cvts_w(uint32_t wt0) { + uint32_t fst2; + set_float_exception_flags(0, &env->fpu->fp_status); - FST2 = int32_to_float32(WT0, &env->fpu->fp_status); + fst2 = int32_to_float32(wt0, &env->fpu->fp_status); update_fcr31(); + return fst2; } -FLOAT_OP(cvts, l) + +uint32_t do_float_cvts_l(uint64_t dt0) { + uint32_t fst2; + set_float_exception_flags(0, &env->fpu->fp_status); - FST2 = int64_to_float32(DT0, &env->fpu->fp_status); + fst2 = int64_to_float32(dt0, &env->fpu->fp_status); update_fcr31(); + return fst2; } -FLOAT_OP(cvts, pl) + +uint32_t do_float_cvts_pl(uint32_t wt0) { + uint32_t wt2; + set_float_exception_flags(0, &env->fpu->fp_status); - WT2 = WT0; + wt2 = wt0; update_fcr31(); + return wt2; } -FLOAT_OP(cvts, pu) + +uint32_t do_float_cvts_pu(uint32_t wth0) { + uint32_t wt2; + set_float_exception_flags(0, &env->fpu->fp_status); - WT2 = WTH0; + wt2 = wth0; update_fcr31(); + return wt2; } -FLOAT_OP(cvtw, s) + +uint32_t do_float_cvtw_s(uint32_t fst0) { + uint32_t wt2; + set_float_exception_flags(0, &env->fpu->fp_status); - WT2 = float32_to_int32(FST0, &env->fpu->fp_status); + wt2 = float32_to_int32(fst0, &env->fpu->fp_status); update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - WT2 = FLOAT_SNAN32; + wt2 = FLOAT_SNAN32; + return wt2; } -FLOAT_OP(cvtw, d) + +uint32_t do_float_cvtw_d(uint64_t fdt0) { + uint32_t wt2; + set_float_exception_flags(0, &env->fpu->fp_status); - WT2 = float64_to_int32(FDT0, &env->fpu->fp_status); + wt2 = float64_to_int32(fdt0, &env->fpu->fp_status); update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - WT2 = FLOAT_SNAN32; + wt2 = FLOAT_SNAN32; + return wt2; } -FLOAT_OP(roundl, d) +uint64_t do_float_roundl_d(uint64_t fdt0) { + uint64_t dt2; + set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status); - DT2 = float64_to_int64(FDT0, &env->fpu->fp_status); + dt2 = float64_to_int64(fdt0, &env->fpu->fp_status); RESTORE_ROUNDING_MODE; update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - DT2 = FLOAT_SNAN64; + dt2 = FLOAT_SNAN64; + return dt2; } -FLOAT_OP(roundl, s) + +uint64_t do_float_roundl_s(uint32_t fst0) { + uint64_t dt2; + set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status); - DT2 = float32_to_int64(FST0, &env->fpu->fp_status); + dt2 = float32_to_int64(fst0, &env->fpu->fp_status); RESTORE_ROUNDING_MODE; update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - DT2 = FLOAT_SNAN64; + dt2 = FLOAT_SNAN64; + return dt2; } -FLOAT_OP(roundw, d) + +uint32_t do_float_roundw_d(uint64_t fdt0) { + uint32_t wt2; + set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status); - WT2 = float64_to_int32(FDT0, &env->fpu->fp_status); + wt2 = float64_to_int32(fdt0, &env->fpu->fp_status); RESTORE_ROUNDING_MODE; update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - WT2 = FLOAT_SNAN32; + wt2 = FLOAT_SNAN32; + return wt2; } -FLOAT_OP(roundw, s) + +uint32_t do_float_roundw_s(uint32_t fst0) { + uint32_t wt2; + set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status); - WT2 = float32_to_int32(FST0, &env->fpu->fp_status); + wt2 = float32_to_int32(fst0, &env->fpu->fp_status); RESTORE_ROUNDING_MODE; update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - WT2 = FLOAT_SNAN32; + wt2 = FLOAT_SNAN32; + return wt2; } -FLOAT_OP(truncl, d) +uint64_t do_float_truncl_d(uint64_t fdt0) { - DT2 = float64_to_int64_round_to_zero(FDT0, &env->fpu->fp_status); + uint64_t dt2; + + dt2 = float64_to_int64_round_to_zero(fdt0, &env->fpu->fp_status); update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - DT2 = FLOAT_SNAN64; + dt2 = FLOAT_SNAN64; + return dt2; } -FLOAT_OP(truncl, s) + +uint64_t do_float_truncl_s(uint32_t fst0) { - DT2 = float32_to_int64_round_to_zero(FST0, &env->fpu->fp_status); + uint64_t dt2; + + dt2 = float32_to_int64_round_to_zero(fst0, &env->fpu->fp_status); update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - DT2 = FLOAT_SNAN64; + dt2 = FLOAT_SNAN64; + return dt2; } -FLOAT_OP(truncw, d) + +uint32_t do_float_truncw_d(uint64_t fdt0) { - WT2 = float64_to_int32_round_to_zero(FDT0, &env->fpu->fp_status); + uint32_t wt2; + + wt2 = float64_to_int32_round_to_zero(fdt0, &env->fpu->fp_status); update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - WT2 = FLOAT_SNAN32; + wt2 = FLOAT_SNAN32; + return wt2; } -FLOAT_OP(truncw, s) + +uint32_t do_float_truncw_s(uint32_t fst0) { - WT2 = float32_to_int32_round_to_zero(FST0, &env->fpu->fp_status); + uint32_t wt2; + + wt2 = float32_to_int32_round_to_zero(fst0, &env->fpu->fp_status); update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - WT2 = FLOAT_SNAN32; + wt2 = FLOAT_SNAN32; + return wt2; } -FLOAT_OP(ceill, d) +uint64_t do_float_ceill_d(uint64_t fdt0) { + uint64_t dt2; + set_float_rounding_mode(float_round_up, &env->fpu->fp_status); - DT2 = float64_to_int64(FDT0, &env->fpu->fp_status); + dt2 = float64_to_int64(fdt0, &env->fpu->fp_status); RESTORE_ROUNDING_MODE; update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - DT2 = FLOAT_SNAN64; + dt2 = FLOAT_SNAN64; + return dt2; } -FLOAT_OP(ceill, s) + +uint64_t do_float_ceill_s(uint32_t fst0) { + uint64_t dt2; + set_float_rounding_mode(float_round_up, &env->fpu->fp_status); - DT2 = float32_to_int64(FST0, &env->fpu->fp_status); + dt2 = float32_to_int64(fst0, &env->fpu->fp_status); RESTORE_ROUNDING_MODE; update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - DT2 = FLOAT_SNAN64; + dt2 = FLOAT_SNAN64; + return dt2; } -FLOAT_OP(ceilw, d) + +uint32_t do_float_ceilw_d(uint64_t fdt0) { + uint32_t wt2; + set_float_rounding_mode(float_round_up, &env->fpu->fp_status); - WT2 = float64_to_int32(FDT0, &env->fpu->fp_status); + wt2 = float64_to_int32(fdt0, &env->fpu->fp_status); RESTORE_ROUNDING_MODE; update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - WT2 = FLOAT_SNAN32; + wt2 = FLOAT_SNAN32; + return wt2; } -FLOAT_OP(ceilw, s) + +uint32_t do_float_ceilw_s(uint32_t fst0) { + uint32_t wt2; + set_float_rounding_mode(float_round_up, &env->fpu->fp_status); - WT2 = float32_to_int32(FST0, &env->fpu->fp_status); + wt2 = float32_to_int32(fst0, &env->fpu->fp_status); RESTORE_ROUNDING_MODE; update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - WT2 = FLOAT_SNAN32; + wt2 = FLOAT_SNAN32; + return wt2; } -FLOAT_OP(floorl, d) +uint64_t do_float_floorl_d(uint64_t fdt0) { + uint64_t dt2; + set_float_rounding_mode(float_round_down, &env->fpu->fp_status); - DT2 = float64_to_int64(FDT0, &env->fpu->fp_status); + dt2 = float64_to_int64(fdt0, &env->fpu->fp_status); RESTORE_ROUNDING_MODE; update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - DT2 = FLOAT_SNAN64; + dt2 = FLOAT_SNAN64; + return dt2; } -FLOAT_OP(floorl, s) + +uint64_t do_float_floorl_s(uint32_t fst0) { + uint64_t dt2; + set_float_rounding_mode(float_round_down, &env->fpu->fp_status); - DT2 = float32_to_int64(FST0, &env->fpu->fp_status); + dt2 = float32_to_int64(fst0, &env->fpu->fp_status); RESTORE_ROUNDING_MODE; update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - DT2 = FLOAT_SNAN64; + dt2 = FLOAT_SNAN64; + return dt2; } -FLOAT_OP(floorw, d) + +uint32_t do_float_floorw_d(uint64_t fdt0) { + uint32_t wt2; + set_float_rounding_mode(float_round_down, &env->fpu->fp_status); - WT2 = float64_to_int32(FDT0, &env->fpu->fp_status); + wt2 = float64_to_int32(fdt0, &env->fpu->fp_status); RESTORE_ROUNDING_MODE; update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - WT2 = FLOAT_SNAN32; + wt2 = FLOAT_SNAN32; + return wt2; } -FLOAT_OP(floorw, s) + +uint32_t do_float_floorw_s(uint32_t fst0) { + uint32_t wt2; + set_float_rounding_mode(float_round_down, &env->fpu->fp_status); - WT2 = float32_to_int32(FST0, &env->fpu->fp_status); + wt2 = float32_to_int32(fst0, &env->fpu->fp_status); RESTORE_ROUNDING_MODE; update_fcr31(); if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) - WT2 = FLOAT_SNAN32; + wt2 = FLOAT_SNAN32; + return wt2; } /* unary operations, not modifying fp status */ -#define FLOAT_UNOP(name) \ -FLOAT_OP(name, d) \ -{ \ - FDT2 = float64_ ## name(FDT0); \ -} \ -FLOAT_OP(name, s) \ -{ \ - FST2 = float32_ ## name(FST0); \ -} \ -FLOAT_OP(name, ps) \ -{ \ - FST2 = float32_ ## name(FST0); \ - FSTH2 = float32_ ## name(FSTH0); \ +#define FLOAT_UNOP(name) \ +uint64_t do_float_ ## name ## _d(uint64_t fdt0) \ +{ \ + return float64_ ## name(fdt0); \ +} \ +uint32_t do_float_ ## name ## _s(uint32_t fst0) \ +{ \ + return float32_ ## name(fst0); \ +} \ +uint64_t do_float_ ## name ## _ps(uint64_t fdt0) \ +{ \ + uint32_t wt0; \ + uint32_t wth0; \ + \ + wt0 = float32_ ## name(fdt0 & 0XFFFFFFFF); \ + wth0 = float32_ ## name(fdt0 >> 32); \ + return ((uint64_t)wth0 << 32) | wt0; \ } FLOAT_UNOP(abs) FLOAT_UNOP(chs) #undef FLOAT_UNOP /* MIPS specific unary operations */ -FLOAT_OP(recip, d) +uint64_t do_float_recip_d(uint64_t fdt0) { + uint64_t fdt2; + set_float_exception_flags(0, &env->fpu->fp_status); - FDT2 = float64_div(FLOAT_ONE64, FDT0, &env->fpu->fp_status); + fdt2 = float64_div(FLOAT_ONE64, fdt0, &env->fpu->fp_status); update_fcr31(); + return fdt2; } -FLOAT_OP(recip, s) + +uint32_t do_float_recip_s(uint32_t fst0) { + uint32_t fst2; + set_float_exception_flags(0, &env->fpu->fp_status); - FST2 = float32_div(FLOAT_ONE32, FST0, &env->fpu->fp_status); + fst2 = float32_div(FLOAT_ONE32, fst0, &env->fpu->fp_status); update_fcr31(); + return fst2; } -FLOAT_OP(rsqrt, d) +uint64_t do_float_rsqrt_d(uint64_t fdt0) { + uint64_t fdt2; + set_float_exception_flags(0, &env->fpu->fp_status); - FDT2 = float64_sqrt(FDT0, &env->fpu->fp_status); - FDT2 = float64_div(FLOAT_ONE64, FDT2, &env->fpu->fp_status); + fdt2 = float64_sqrt(fdt0, &env->fpu->fp_status); + fdt2 = float64_div(FLOAT_ONE64, fdt2, &env->fpu->fp_status); update_fcr31(); + return fdt2; } -FLOAT_OP(rsqrt, s) + +uint32_t do_float_rsqrt_s(uint32_t fst0) { + uint32_t fst2; + set_float_exception_flags(0, &env->fpu->fp_status); - FST2 = float32_sqrt(FST0, &env->fpu->fp_status); - FST2 = float32_div(FLOAT_ONE32, FST2, &env->fpu->fp_status); + fst2 = float32_sqrt(fst0, &env->fpu->fp_status); + fst2 = float32_div(FLOAT_ONE32, fst2, &env->fpu->fp_status); update_fcr31(); + return fst2; } -FLOAT_OP(recip1, d) +uint64_t do_float_recip1_d(uint64_t fdt0) { + uint64_t fdt2; + set_float_exception_flags(0, &env->fpu->fp_status); - FDT2 = float64_div(FLOAT_ONE64, FDT0, &env->fpu->fp_status); + fdt2 = float64_div(FLOAT_ONE64, fdt0, &env->fpu->fp_status); update_fcr31(); + return fdt2; } -FLOAT_OP(recip1, s) + +uint32_t do_float_recip1_s(uint32_t fst0) { + uint32_t fst2; + set_float_exception_flags(0, &env->fpu->fp_status); - FST2 = float32_div(FLOAT_ONE32, FST0, &env->fpu->fp_status); + fst2 = float32_div(FLOAT_ONE32, fst0, &env->fpu->fp_status); update_fcr31(); + return fst2; } -FLOAT_OP(recip1, ps) + +uint64_t do_float_recip1_ps(uint64_t fdt0) { + uint32_t fst2; + uint32_t fsth2; + set_float_exception_flags(0, &env->fpu->fp_status); - FST2 = float32_div(FLOAT_ONE32, FST0, &env->fpu->fp_status); - FSTH2 = float32_div(FLOAT_ONE32, FSTH0, &env->fpu->fp_status); + fst2 = float32_div(FLOAT_ONE32, fdt0 & 0XFFFFFFFF, &env->fpu->fp_status); + fsth2 = float32_div(FLOAT_ONE32, fdt0 >> 32, &env->fpu->fp_status); update_fcr31(); + return ((uint64_t)fsth2 << 32) | fst2; } -FLOAT_OP(rsqrt1, d) +uint64_t do_float_rsqrt1_d(uint64_t fdt0) { + uint64_t fdt2; + set_float_exception_flags(0, &env->fpu->fp_status); - FDT2 = float64_sqrt(FDT0, &env->fpu->fp_status); - FDT2 = float64_div(FLOAT_ONE64, FDT2, &env->fpu->fp_status); + fdt2 = float64_sqrt(fdt0, &env->fpu->fp_status); + fdt2 = float64_div(FLOAT_ONE64, fdt2, &env->fpu->fp_status); update_fcr31(); + return fdt2; } -FLOAT_OP(rsqrt1, s) + +uint32_t do_float_rsqrt1_s(uint32_t fst0) { + uint32_t fst2; + set_float_exception_flags(0, &env->fpu->fp_status); - FST2 = float32_sqrt(FST0, &env->fpu->fp_status); - FST2 = float32_div(FLOAT_ONE32, FST2, &env->fpu->fp_status); + fst2 = float32_sqrt(fst0, &env->fpu->fp_status); + fst2 = float32_div(FLOAT_ONE32, fst2, &env->fpu->fp_status); update_fcr31(); + return fst2; } -FLOAT_OP(rsqrt1, ps) + +uint64_t do_float_rsqrt1_ps(uint64_t fdt0) { + uint32_t fst2; + uint32_t fsth2; + set_float_exception_flags(0, &env->fpu->fp_status); - FST2 = float32_sqrt(FST0, &env->fpu->fp_status); - FSTH2 = float32_sqrt(FSTH0, &env->fpu->fp_status); - FST2 = float32_div(FLOAT_ONE32, FST2, &env->fpu->fp_status); - FSTH2 = float32_div(FLOAT_ONE32, FSTH2, &env->fpu->fp_status); + fst2 = float32_sqrt(fdt0 & 0XFFFFFFFF, &env->fpu->fp_status); + fsth2 = float32_sqrt(fdt0 >> 32, &env->fpu->fp_status); + fst2 = float32_div(FLOAT_ONE32, fst2, &env->fpu->fp_status); + fsth2 = float32_div(FLOAT_ONE32, fsth2, &env->fpu->fp_status); update_fcr31(); + return ((uint64_t)fsth2 << 32) | fst2; } +#define FLOAT_OP(name, p) void do_float_##name##_##p(void) + /* binary operations */ -#define FLOAT_BINOP(name) \ -FLOAT_OP(name, d) \ -{ \ +#define FLOAT_BINOP(name) \ +uint64_t do_float_ ## name ## _d(uint64_t fdt0, uint64_t fdt1) \ +{ \ + uint64_t dt2; \ + \ set_float_exception_flags(0, &env->fpu->fp_status); \ - FDT2 = float64_ ## name (FDT0, FDT1, &env->fpu->fp_status); \ + dt2 = float64_ ## name (fdt0, fdt1, &env->fpu->fp_status); \ update_fcr31(); \ if (GET_FP_CAUSE(env->fpu->fcr31) & FP_INVALID) \ - DT2 = FLOAT_QNAN64; \ -} \ -FLOAT_OP(name, s) \ -{ \ + dt2 = FLOAT_QNAN64; \ + return dt2; \ +} \ + \ +uint32_t do_float_ ## name ## _s(uint32_t fst0, uint32_t fst1) \ +{ \ + uint32_t wt2; \ + \ set_float_exception_flags(0, &env->fpu->fp_status); \ - FST2 = float32_ ## name (FST0, FST1, &env->fpu->fp_status); \ + wt2 = float32_ ## name (fst0, fst1, &env->fpu->fp_status); \ update_fcr31(); \ if (GET_FP_CAUSE(env->fpu->fcr31) & FP_INVALID) \ - WT2 = FLOAT_QNAN32; \ -} \ -FLOAT_OP(name, ps) \ -{ \ + wt2 = FLOAT_QNAN32; \ + return wt2; \ +} \ + \ +uint64_t do_float_ ## name ## _ps(uint64_t fdt0, uint64_t fdt1) \ +{ \ + uint32_t fst0 = fdt0 & 0XFFFFFFFF; \ + uint32_t fsth0 = fdt0 >> 32; \ + uint32_t fst1 = fdt1 & 0XFFFFFFFF; \ + uint32_t fsth1 = fdt1 >> 32; \ + uint32_t wt2; \ + uint32_t wth2; \ + \ set_float_exception_flags(0, &env->fpu->fp_status); \ - FST2 = float32_ ## name (FST0, FST1, &env->fpu->fp_status); \ - FSTH2 = float32_ ## name (FSTH0, FSTH1, &env->fpu->fp_status); \ - update_fcr31(); \ + wt2 = float32_ ## name (fst0, fst1, &env->fpu->fp_status); \ + wth2 = float32_ ## name (fsth0, fsth1, &env->fpu->fp_status); \ + update_fcr31(); \ if (GET_FP_CAUSE(env->fpu->fcr31) & FP_INVALID) { \ - WT2 = FLOAT_QNAN32; \ - WTH2 = FLOAT_QNAN32; \ - } \ + wt2 = FLOAT_QNAN32; \ + wth2 = FLOAT_QNAN32; \ + } \ + return ((uint64_t)wth2 << 32) | wt2; \ } + FLOAT_BINOP(add) FLOAT_BINOP(sub) FLOAT_BINOP(mul) @@ -2392,146 +2677,210 @@ FLOAT_BINOP(div) #undef FLOAT_BINOP /* ternary operations */ -#define FLOAT_TERNOP(name1, name2) \ -FLOAT_OP(name1 ## name2, d) \ -{ \ - FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \ - FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \ -} \ -FLOAT_OP(name1 ## name2, s) \ -{ \ - FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ - FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ -} \ -FLOAT_OP(name1 ## name2, ps) \ -{ \ - FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ - FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \ - FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ - FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \ +#define FLOAT_TERNOP(name1, name2) \ +uint64_t do_float_ ## name1 ## name2 ## _d(uint64_t fdt0, uint64_t fdt1, \ + uint64_t fdt2) \ +{ \ + fdt0 = float64_ ## name1 (fdt0, fdt1, &env->fpu->fp_status); \ + return float64_ ## name2 (fdt0, fdt2, &env->fpu->fp_status); \ +} \ + \ +uint32_t do_float_ ## name1 ## name2 ## _s(uint32_t fst0, uint32_t fst1, \ + uint32_t fst2) \ +{ \ + fst0 = float32_ ## name1 (fst0, fst1, &env->fpu->fp_status); \ + return float32_ ## name2 (fst0, fst2, &env->fpu->fp_status); \ +} \ + \ +uint64_t do_float_ ## name1 ## name2 ## _ps(uint64_t fdt0, uint64_t fdt1, \ + uint64_t fdt2) \ +{ \ + uint32_t fst0 = fdt0 & 0XFFFFFFFF; \ + uint32_t fsth0 = fdt0 >> 32; \ + uint32_t fst1 = fdt1 & 0XFFFFFFFF; \ + uint32_t fsth1 = fdt1 >> 32; \ + uint32_t fst2 = fdt2 & 0XFFFFFFFF; \ + uint32_t fsth2 = fdt2 >> 32; \ + \ + fst0 = float32_ ## name1 (fst0, fst1, &env->fpu->fp_status); \ + fsth0 = float32_ ## name1 (fsth0, fsth1, &env->fpu->fp_status); \ + fst2 = float32_ ## name2 (fst0, fst2, &env->fpu->fp_status); \ + fsth2 = float32_ ## name2 (fsth0, fsth2, &env->fpu->fp_status); \ + return ((uint64_t)fsth2 << 32) | fst2; \ } + FLOAT_TERNOP(mul, add) FLOAT_TERNOP(mul, sub) #undef FLOAT_TERNOP /* negated ternary operations */ -#define FLOAT_NTERNOP(name1, name2) \ -FLOAT_OP(n ## name1 ## name2, d) \ -{ \ - FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \ - FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \ - FDT2 = float64_chs(FDT2); \ -} \ -FLOAT_OP(n ## name1 ## name2, s) \ -{ \ - FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ - FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ - FST2 = float32_chs(FST2); \ -} \ -FLOAT_OP(n ## name1 ## name2, ps) \ -{ \ - FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ - FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \ - FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ - FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \ - FST2 = float32_chs(FST2); \ - FSTH2 = float32_chs(FSTH2); \ +#define FLOAT_NTERNOP(name1, name2) \ +uint64_t do_float_n ## name1 ## name2 ## _d(uint64_t fdt0, uint64_t fdt1, \ + uint64_t fdt2) \ +{ \ + fdt0 = float64_ ## name1 (fdt0, fdt1, &env->fpu->fp_status); \ + fdt2 = float64_ ## name2 (fdt0, fdt2, &env->fpu->fp_status); \ + return float64_chs(fdt2); \ +} \ + \ +uint32_t do_float_n ## name1 ## name2 ## _s(uint32_t fst0, uint32_t fst1, \ + uint32_t fst2) \ +{ \ + fst0 = float32_ ## name1 (fst0, fst1, &env->fpu->fp_status); \ + fst2 = float32_ ## name2 (fst0, fst2, &env->fpu->fp_status); \ + return float32_chs(fst2); \ +} \ + \ +uint64_t do_float_n ## name1 ## name2 ## _ps(uint64_t fdt0, uint64_t fdt1,\ + uint64_t fdt2) \ +{ \ + uint32_t fst0 = fdt0 & 0XFFFFFFFF; \ + uint32_t fsth0 = fdt0 >> 32; \ + uint32_t fst1 = fdt1 & 0XFFFFFFFF; \ + uint32_t fsth1 = fdt1 >> 32; \ + uint32_t fst2 = fdt2 & 0XFFFFFFFF; \ + uint32_t fsth2 = fdt2 >> 32; \ + \ + fst0 = float32_ ## name1 (fst0, fst1, &env->fpu->fp_status); \ + fsth0 = float32_ ## name1 (fsth0, fsth1, &env->fpu->fp_status); \ + fst2 = float32_ ## name2 (fst0, fst2, &env->fpu->fp_status); \ + fsth2 = float32_ ## name2 (fsth0, fsth2, &env->fpu->fp_status); \ + fst2 = float32_chs(fst2); \ + fsth2 = float32_chs(fsth2); \ + return ((uint64_t)fsth2 << 32) | fst2; \ } + FLOAT_NTERNOP(mul, add) FLOAT_NTERNOP(mul, sub) #undef FLOAT_NTERNOP /* MIPS specific binary operations */ -FLOAT_OP(recip2, d) +uint64_t do_float_recip2_d(uint64_t fdt0, uint64_t fdt2) { set_float_exception_flags(0, &env->fpu->fp_status); - FDT2 = float64_mul(FDT0, FDT2, &env->fpu->fp_status); - FDT2 = float64_chs(float64_sub(FDT2, FLOAT_ONE64, &env->fpu->fp_status)); + fdt2 = float64_mul(fdt0, fdt2, &env->fpu->fp_status); + fdt2 = float64_chs(float64_sub(fdt2, FLOAT_ONE64, &env->fpu->fp_status)); update_fcr31(); + return fdt2; } -FLOAT_OP(recip2, s) + +uint32_t do_float_recip2_s(uint32_t fst0, uint32_t fst2) { set_float_exception_flags(0, &env->fpu->fp_status); - FST2 = float32_mul(FST0, FST2, &env->fpu->fp_status); - FST2 = float32_chs(float32_sub(FST2, FLOAT_ONE32, &env->fpu->fp_status)); + fst2 = float32_mul(fst0, fst2, &env->fpu->fp_status); + fst2 = float32_chs(float32_sub(fst2, FLOAT_ONE32, &env->fpu->fp_status)); update_fcr31(); + return fst2; } -FLOAT_OP(recip2, ps) + +uint64_t do_float_recip2_ps(uint64_t fdt0, uint64_t fdt2) { + uint32_t fst0 = fdt0 & 0XFFFFFFFF; + uint32_t fsth0 = fdt0 >> 32; + uint32_t fst2 = fdt2 & 0XFFFFFFFF; + uint32_t fsth2 = fdt2 >> 32; + set_float_exception_flags(0, &env->fpu->fp_status); - FST2 = float32_mul(FST0, FST2, &env->fpu->fp_status); - FSTH2 = float32_mul(FSTH0, FSTH2, &env->fpu->fp_status); - FST2 = float32_chs(float32_sub(FST2, FLOAT_ONE32, &env->fpu->fp_status)); - FSTH2 = float32_chs(float32_sub(FSTH2, FLOAT_ONE32, &env->fpu->fp_status)); + fst2 = float32_mul(fst0, fst2, &env->fpu->fp_status); + fsth2 = float32_mul(fsth0, fsth2, &env->fpu->fp_status); + fst2 = float32_chs(float32_sub(fst2, FLOAT_ONE32, &env->fpu->fp_status)); + fsth2 = float32_chs(float32_sub(fsth2, FLOAT_ONE32, &env->fpu->fp_status)); update_fcr31(); + return ((uint64_t)fsth2 << 32) | fst2; } -FLOAT_OP(rsqrt2, d) +uint64_t do_float_rsqrt2_d(uint64_t fdt0, uint64_t fdt2) { set_float_exception_flags(0, &env->fpu->fp_status); - FDT2 = float64_mul(FDT0, FDT2, &env->fpu->fp_status); - FDT2 = float64_sub(FDT2, FLOAT_ONE64, &env->fpu->fp_status); - FDT2 = float64_chs(float64_div(FDT2, FLOAT_TWO64, &env->fpu->fp_status)); + fdt2 = float64_mul(fdt0, fdt2, &env->fpu->fp_status); + fdt2 = float64_sub(fdt2, FLOAT_ONE64, &env->fpu->fp_status); + fdt2 = float64_chs(float64_div(fdt2, FLOAT_TWO64, &env->fpu->fp_status)); update_fcr31(); + return fdt2; } -FLOAT_OP(rsqrt2, s) + +uint32_t do_float_rsqrt2_s(uint32_t fst0, uint32_t fst2) { set_float_exception_flags(0, &env->fpu->fp_status); - FST2 = float32_mul(FST0, FST2, &env->fpu->fp_status); - FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fpu->fp_status); - FST2 = float32_chs(float32_div(FST2, FLOAT_TWO32, &env->fpu->fp_status)); + fst2 = float32_mul(fst0, fst2, &env->fpu->fp_status); + fst2 = float32_sub(fst2, FLOAT_ONE32, &env->fpu->fp_status); + fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32, &env->fpu->fp_status)); update_fcr31(); + return fst2; } -FLOAT_OP(rsqrt2, ps) + +uint64_t do_float_rsqrt2_ps(uint64_t fdt0, uint64_t fdt2) { + uint32_t fst0 = fdt0 & 0XFFFFFFFF; + uint32_t fsth0 = fdt0 >> 32; + uint32_t fst2 = fdt2 & 0XFFFFFFFF; + uint32_t fsth2 = fdt2 >> 32; + set_float_exception_flags(0, &env->fpu->fp_status); - FST2 = float32_mul(FST0, FST2, &env->fpu->fp_status); - FSTH2 = float32_mul(FSTH0, FSTH2, &env->fpu->fp_status); - FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fpu->fp_status); - FSTH2 = float32_sub(FSTH2, FLOAT_ONE32, &env->fpu->fp_status); - FST2 = float32_chs(float32_div(FST2, FLOAT_TWO32, &env->fpu->fp_status)); - FSTH2 = float32_chs(float32_div(FSTH2, FLOAT_TWO32, &env->fpu->fp_status)); + fst2 = float32_mul(fst0, fst2, &env->fpu->fp_status); + fsth2 = float32_mul(fsth0, fsth2, &env->fpu->fp_status); + fst2 = float32_sub(fst2, FLOAT_ONE32, &env->fpu->fp_status); + fsth2 = float32_sub(fsth2, FLOAT_ONE32, &env->fpu->fp_status); + fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32, &env->fpu->fp_status)); + fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32, &env->fpu->fp_status)); update_fcr31(); + return ((uint64_t)fsth2 << 32) | fst2; } -FLOAT_OP(addr, ps) +uint64_t do_float_addr_ps(uint64_t fdt0, uint64_t fdt1) { + uint32_t fst0 = fdt0 & 0XFFFFFFFF; + uint32_t fsth0 = fdt0 >> 32; + uint32_t fst1 = fdt1 & 0XFFFFFFFF; + uint32_t fsth1 = fdt1 >> 32; + uint32_t fst2; + uint32_t fsth2; + set_float_exception_flags(0, &env->fpu->fp_status); - FST2 = float32_add (FST0, FSTH0, &env->fpu->fp_status); - FSTH2 = float32_add (FST1, FSTH1, &env->fpu->fp_status); + fst2 = float32_add (fst0, fsth0, &env->fpu->fp_status); + fsth2 = float32_add (fst1, fsth1, &env->fpu->fp_status); update_fcr31(); + return ((uint64_t)fsth2 << 32) | fst2; } -FLOAT_OP(mulr, ps) +uint64_t do_float_mulr_ps(uint64_t fdt0, uint64_t fdt1) { + uint32_t fst0 = fdt0 & 0XFFFFFFFF; + uint32_t fsth0 = fdt0 >> 32; + uint32_t fst1 = fdt1 & 0XFFFFFFFF; + uint32_t fsth1 = fdt1 >> 32; + uint32_t fst2; + uint32_t fsth2; + set_float_exception_flags(0, &env->fpu->fp_status); - FST2 = float32_mul (FST0, FSTH0, &env->fpu->fp_status); - FSTH2 = float32_mul (FST1, FSTH1, &env->fpu->fp_status); + fst2 = float32_mul (fst0, fsth0, &env->fpu->fp_status); + fsth2 = float32_mul (fst1, fsth1, &env->fpu->fp_status); update_fcr31(); + return ((uint64_t)fsth2 << 32) | fst2; } /* compare operations */ -#define FOP_COND_D(op, cond) \ -void do_cmp_d_ ## op (long cc) \ -{ \ - int c = cond; \ - update_fcr31(); \ - if (c) \ - SET_FP_COND(cc, env->fpu); \ - else \ - CLEAR_FP_COND(cc, env->fpu); \ -} \ -void do_cmpabs_d_ ## op (long cc) \ -{ \ - int c; \ - FDT0 = float64_abs(FDT0); \ - FDT1 = float64_abs(FDT1); \ - c = cond; \ - update_fcr31(); \ - if (c) \ - SET_FP_COND(cc, env->fpu); \ - else \ - CLEAR_FP_COND(cc, env->fpu); \ +#define FOP_COND_D(op, cond) \ +void do_cmp_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \ +{ \ + int c = cond; \ + update_fcr31(); \ + if (c) \ + SET_FP_COND(cc, env->fpu); \ + else \ + CLEAR_FP_COND(cc, env->fpu); \ +} \ +void do_cmpabs_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \ +{ \ + int c; \ + fdt0 = float64_abs(fdt0); \ + fdt1 = float64_abs(fdt1); \ + c = cond; \ + update_fcr31(); \ + if (c) \ + SET_FP_COND(cc, env->fpu); \ + else \ + CLEAR_FP_COND(cc, env->fpu); \ } int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM) @@ -2550,46 +2899,46 @@ int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM) /* NOTE: the comma operator will make "cond" to eval to false, * but float*_is_unordered() is still called. */ -FOP_COND_D(f, (float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status), 0)) -FOP_COND_D(un, float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status)) -FOP_COND_D(eq, !float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) && float64_eq(FDT0, FDT1, &env->fpu->fp_status)) -FOP_COND_D(ueq, float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) || float64_eq(FDT0, FDT1, &env->fpu->fp_status)) -FOP_COND_D(olt, !float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) && float64_lt(FDT0, FDT1, &env->fpu->fp_status)) -FOP_COND_D(ult, float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) || float64_lt(FDT0, FDT1, &env->fpu->fp_status)) -FOP_COND_D(ole, !float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) && float64_le(FDT0, FDT1, &env->fpu->fp_status)) -FOP_COND_D(ule, float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) || float64_le(FDT0, FDT1, &env->fpu->fp_status)) +FOP_COND_D(f, (float64_is_unordered(0, fdt1, fdt0, &env->fpu->fp_status), 0)) +FOP_COND_D(un, float64_is_unordered(0, fdt1, fdt0, &env->fpu->fp_status)) +FOP_COND_D(eq, !float64_is_unordered(0, fdt1, fdt0, &env->fpu->fp_status) && float64_eq(fdt0, fdt1, &env->fpu->fp_status)) +FOP_COND_D(ueq, float64_is_unordered(0, fdt1, fdt0, &env->fpu->fp_status) || float64_eq(fdt0, fdt1, &env->fpu->fp_status)) +FOP_COND_D(olt, !float64_is_unordered(0, fdt1, fdt0, &env->fpu->fp_status) && float64_lt(fdt0, fdt1, &env->fpu->fp_status)) +FOP_COND_D(ult, float64_is_unordered(0, fdt1, fdt0, &env->fpu->fp_status) || float64_lt(fdt0, fdt1, &env->fpu->fp_status)) +FOP_COND_D(ole, !float64_is_unordered(0, fdt1, fdt0, &env->fpu->fp_status) && float64_le(fdt0, fdt1, &env->fpu->fp_status)) +FOP_COND_D(ule, float64_is_unordered(0, fdt1, fdt0, &env->fpu->fp_status) || float64_le(fdt0, fdt1, &env->fpu->fp_status)) /* NOTE: the comma operator will make "cond" to eval to false, * but float*_is_unordered() is still called. */ -FOP_COND_D(sf, (float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status), 0)) -FOP_COND_D(ngle,float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status)) -FOP_COND_D(seq, !float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) && float64_eq(FDT0, FDT1, &env->fpu->fp_status)) -FOP_COND_D(ngl, float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) || float64_eq(FDT0, FDT1, &env->fpu->fp_status)) -FOP_COND_D(lt, !float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) && float64_lt(FDT0, FDT1, &env->fpu->fp_status)) -FOP_COND_D(nge, float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) || float64_lt(FDT0, FDT1, &env->fpu->fp_status)) -FOP_COND_D(le, !float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) && float64_le(FDT0, FDT1, &env->fpu->fp_status)) -FOP_COND_D(ngt, float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) || float64_le(FDT0, FDT1, &env->fpu->fp_status)) - -#define FOP_COND_S(op, cond) \ -void do_cmp_s_ ## op (long cc) \ -{ \ - int c = cond; \ - update_fcr31(); \ - if (c) \ - SET_FP_COND(cc, env->fpu); \ - else \ - CLEAR_FP_COND(cc, env->fpu); \ -} \ -void do_cmpabs_s_ ## op (long cc) \ -{ \ - int c; \ - FST0 = float32_abs(FST0); \ - FST1 = float32_abs(FST1); \ - c = cond; \ - update_fcr31(); \ - if (c) \ - SET_FP_COND(cc, env->fpu); \ - else \ - CLEAR_FP_COND(cc, env->fpu); \ +FOP_COND_D(sf, (float64_is_unordered(1, fdt1, fdt0, &env->fpu->fp_status), 0)) +FOP_COND_D(ngle,float64_is_unordered(1, fdt1, fdt0, &env->fpu->fp_status)) +FOP_COND_D(seq, !float64_is_unordered(1, fdt1, fdt0, &env->fpu->fp_status) && float64_eq(fdt0, fdt1, &env->fpu->fp_status)) +FOP_COND_D(ngl, float64_is_unordered(1, fdt1, fdt0, &env->fpu->fp_status) || float64_eq(fdt0, fdt1, &env->fpu->fp_status)) +FOP_COND_D(lt, !float64_is_unordered(1, fdt1, fdt0, &env->fpu->fp_status) && float64_lt(fdt0, fdt1, &env->fpu->fp_status)) +FOP_COND_D(nge, float64_is_unordered(1, fdt1, fdt0, &env->fpu->fp_status) || float64_lt(fdt0, fdt1, &env->fpu->fp_status)) +FOP_COND_D(le, !float64_is_unordered(1, fdt1, fdt0, &env->fpu->fp_status) && float64_le(fdt0, fdt1, &env->fpu->fp_status)) +FOP_COND_D(ngt, float64_is_unordered(1, fdt1, fdt0, &env->fpu->fp_status) || float64_le(fdt0, fdt1, &env->fpu->fp_status)) + +#define FOP_COND_S(op, cond) \ +void do_cmp_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \ +{ \ + int c = cond; \ + update_fcr31(); \ + if (c) \ + SET_FP_COND(cc, env->fpu); \ + else \ + CLEAR_FP_COND(cc, env->fpu); \ +} \ +void do_cmpabs_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \ +{ \ + int c; \ + fst0 = float32_abs(fst0); \ + fst1 = float32_abs(fst1); \ + c = cond; \ + update_fcr31(); \ + if (c) \ + SET_FP_COND(cc, env->fpu); \ + else \ + CLEAR_FP_COND(cc, env->fpu); \ } flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM) @@ -2608,93 +2957,98 @@ flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM) /* NOTE: the comma operator will make "cond" to eval to false, * but float*_is_unordered() is still called. */ -FOP_COND_S(f, (float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status), 0)) -FOP_COND_S(un, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status)) -FOP_COND_S(eq, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_eq(FST0, FST1, &env->fpu->fp_status)) -FOP_COND_S(ueq, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_eq(FST0, FST1, &env->fpu->fp_status)) -FOP_COND_S(olt, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_lt(FST0, FST1, &env->fpu->fp_status)) -FOP_COND_S(ult, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_lt(FST0, FST1, &env->fpu->fp_status)) -FOP_COND_S(ole, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_le(FST0, FST1, &env->fpu->fp_status)) -FOP_COND_S(ule, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_le(FST0, FST1, &env->fpu->fp_status)) +FOP_COND_S(f, (float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status), 0)) +FOP_COND_S(un, float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status)) +FOP_COND_S(eq, !float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status) && float32_eq(fst0, fst1, &env->fpu->fp_status)) +FOP_COND_S(ueq, float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status) || float32_eq(fst0, fst1, &env->fpu->fp_status)) +FOP_COND_S(olt, !float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status) && float32_lt(fst0, fst1, &env->fpu->fp_status)) +FOP_COND_S(ult, float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status) || float32_lt(fst0, fst1, &env->fpu->fp_status)) +FOP_COND_S(ole, !float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status) && float32_le(fst0, fst1, &env->fpu->fp_status)) +FOP_COND_S(ule, float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status) || float32_le(fst0, fst1, &env->fpu->fp_status)) /* NOTE: the comma operator will make "cond" to eval to false, * but float*_is_unordered() is still called. */ -FOP_COND_S(sf, (float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status), 0)) -FOP_COND_S(ngle,float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status)) -FOP_COND_S(seq, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_eq(FST0, FST1, &env->fpu->fp_status)) -FOP_COND_S(ngl, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_eq(FST0, FST1, &env->fpu->fp_status)) -FOP_COND_S(lt, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_lt(FST0, FST1, &env->fpu->fp_status)) -FOP_COND_S(nge, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_lt(FST0, FST1, &env->fpu->fp_status)) -FOP_COND_S(le, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_le(FST0, FST1, &env->fpu->fp_status)) -FOP_COND_S(ngt, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_le(FST0, FST1, &env->fpu->fp_status)) - -#define FOP_COND_PS(op, condl, condh) \ -void do_cmp_ps_ ## op (long cc) \ -{ \ - int cl = condl; \ - int ch = condh; \ - update_fcr31(); \ - if (cl) \ - SET_FP_COND(cc, env->fpu); \ - else \ - CLEAR_FP_COND(cc, env->fpu); \ - if (ch) \ - SET_FP_COND(cc + 1, env->fpu); \ - else \ - CLEAR_FP_COND(cc + 1, env->fpu); \ -} \ -void do_cmpabs_ps_ ## op (long cc) \ -{ \ - int cl, ch; \ - FST0 = float32_abs(FST0); \ - FSTH0 = float32_abs(FSTH0); \ - FST1 = float32_abs(FST1); \ - FSTH1 = float32_abs(FSTH1); \ - cl = condl; \ - ch = condh; \ - update_fcr31(); \ - if (cl) \ - SET_FP_COND(cc, env->fpu); \ - else \ - CLEAR_FP_COND(cc, env->fpu); \ - if (ch) \ - SET_FP_COND(cc + 1, env->fpu); \ - else \ - CLEAR_FP_COND(cc + 1, env->fpu); \ +FOP_COND_S(sf, (float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status), 0)) +FOP_COND_S(ngle,float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status)) +FOP_COND_S(seq, !float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status) && float32_eq(fst0, fst1, &env->fpu->fp_status)) +FOP_COND_S(ngl, float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status) || float32_eq(fst0, fst1, &env->fpu->fp_status)) +FOP_COND_S(lt, !float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status) && float32_lt(fst0, fst1, &env->fpu->fp_status)) +FOP_COND_S(nge, float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status) || float32_lt(fst0, fst1, &env->fpu->fp_status)) +FOP_COND_S(le, !float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status) && float32_le(fst0, fst1, &env->fpu->fp_status)) +FOP_COND_S(ngt, float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status) || float32_le(fst0, fst1, &env->fpu->fp_status)) + +#define FOP_COND_PS(op, condl, condh) \ +void do_cmp_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \ +{ \ + uint32_t fst0 = float32_abs(fdt0 & 0XFFFFFFFF); \ + uint32_t fsth0 = float32_abs(fdt0 >> 32); \ + uint32_t fst1 = float32_abs(fdt1 & 0XFFFFFFFF); \ + uint32_t fsth1 = float32_abs(fdt1 >> 32); \ + int cl = condl; \ + int ch = condh; \ + \ + update_fcr31(); \ + if (cl) \ + SET_FP_COND(cc, env->fpu); \ + else \ + CLEAR_FP_COND(cc, env->fpu); \ + if (ch) \ + SET_FP_COND(cc + 1, env->fpu); \ + else \ + CLEAR_FP_COND(cc + 1, env->fpu); \ +} \ +void do_cmpabs_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \ +{ \ + uint32_t fst0 = float32_abs(fdt0 & 0XFFFFFFFF); \ + uint32_t fsth0 = float32_abs(fdt0 >> 32); \ + uint32_t fst1 = float32_abs(fdt1 & 0XFFFFFFFF); \ + uint32_t fsth1 = float32_abs(fdt1 >> 32); \ + int cl = condl; \ + int ch = condh; \ + \ + update_fcr31(); \ + if (cl) \ + SET_FP_COND(cc, env->fpu); \ + else \ + CLEAR_FP_COND(cc, env->fpu); \ + if (ch) \ + SET_FP_COND(cc + 1, env->fpu); \ + else \ + CLEAR_FP_COND(cc + 1, env->fpu); \ } /* NOTE: the comma operator will make "cond" to eval to false, * but float*_is_unordered() is still called. */ -FOP_COND_PS(f, (float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status), 0), - (float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status), 0)) -FOP_COND_PS(un, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status), - float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status)) -FOP_COND_PS(eq, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_eq(FST0, FST1, &env->fpu->fp_status), - !float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) && float32_eq(FSTH0, FSTH1, &env->fpu->fp_status)) -FOP_COND_PS(ueq, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_eq(FST0, FST1, &env->fpu->fp_status), - float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) || float32_eq(FSTH0, FSTH1, &env->fpu->fp_status)) -FOP_COND_PS(olt, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_lt(FST0, FST1, &env->fpu->fp_status), - !float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) && float32_lt(FSTH0, FSTH1, &env->fpu->fp_status)) -FOP_COND_PS(ult, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_lt(FST0, FST1, &env->fpu->fp_status), - float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) || float32_lt(FSTH0, FSTH1, &env->fpu->fp_status)) -FOP_COND_PS(ole, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_le(FST0, FST1, &env->fpu->fp_status), - !float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) && float32_le(FSTH0, FSTH1, &env->fpu->fp_status)) -FOP_COND_PS(ule, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_le(FST0, FST1, &env->fpu->fp_status), - float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) || float32_le(FSTH0, FSTH1, &env->fpu->fp_status)) +FOP_COND_PS(f, (float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status), 0), + (float32_is_unordered(0, fsth1, fsth0, &env->fpu->fp_status), 0)) +FOP_COND_PS(un, float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status), + float32_is_unordered(0, fsth1, fsth0, &env->fpu->fp_status)) +FOP_COND_PS(eq, !float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status) && float32_eq(fst0, fst1, &env->fpu->fp_status), + !float32_is_unordered(0, fsth1, fsth0, &env->fpu->fp_status) && float32_eq(fsth0, fsth1, &env->fpu->fp_status)) +FOP_COND_PS(ueq, float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status) || float32_eq(fst0, fst1, &env->fpu->fp_status), + float32_is_unordered(0, fsth1, fsth0, &env->fpu->fp_status) || float32_eq(fsth0, fsth1, &env->fpu->fp_status)) +FOP_COND_PS(olt, !float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status) && float32_lt(fst0, fst1, &env->fpu->fp_status), + !float32_is_unordered(0, fsth1, fsth0, &env->fpu->fp_status) && float32_lt(fsth0, fsth1, &env->fpu->fp_status)) +FOP_COND_PS(ult, float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status) || float32_lt(fst0, fst1, &env->fpu->fp_status), + float32_is_unordered(0, fsth1, fsth0, &env->fpu->fp_status) || float32_lt(fsth0, fsth1, &env->fpu->fp_status)) +FOP_COND_PS(ole, !float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status) && float32_le(fst0, fst1, &env->fpu->fp_status), + !float32_is_unordered(0, fsth1, fsth0, &env->fpu->fp_status) && float32_le(fsth0, fsth1, &env->fpu->fp_status)) +FOP_COND_PS(ule, float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status) || float32_le(fst0, fst1, &env->fpu->fp_status), + float32_is_unordered(0, fsth1, fsth0, &env->fpu->fp_status) || float32_le(fsth0, fsth1, &env->fpu->fp_status)) /* NOTE: the comma operator will make "cond" to eval to false, * but float*_is_unordered() is still called. */ -FOP_COND_PS(sf, (float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status), 0), - (float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status), 0)) -FOP_COND_PS(ngle,float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status), - float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status)) -FOP_COND_PS(seq, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_eq(FST0, FST1, &env->fpu->fp_status), - !float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) && float32_eq(FSTH0, FSTH1, &env->fpu->fp_status)) -FOP_COND_PS(ngl, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_eq(FST0, FST1, &env->fpu->fp_status), - float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) || float32_eq(FSTH0, FSTH1, &env->fpu->fp_status)) -FOP_COND_PS(lt, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_lt(FST0, FST1, &env->fpu->fp_status), - !float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) && float32_lt(FSTH0, FSTH1, &env->fpu->fp_status)) -FOP_COND_PS(nge, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_lt(FST0, FST1, &env->fpu->fp_status), - float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) || float32_lt(FSTH0, FSTH1, &env->fpu->fp_status)) -FOP_COND_PS(le, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_le(FST0, FST1, &env->fpu->fp_status), - !float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) && float32_le(FSTH0, FSTH1, &env->fpu->fp_status)) -FOP_COND_PS(ngt, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_le(FST0, FST1, &env->fpu->fp_status), - float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) || float32_le(FSTH0, FSTH1, &env->fpu->fp_status)) +FOP_COND_PS(sf, (float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status), 0), + (float32_is_unordered(1, fsth1, fsth0, &env->fpu->fp_status), 0)) +FOP_COND_PS(ngle,float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status), + float32_is_unordered(1, fsth1, fsth0, &env->fpu->fp_status)) +FOP_COND_PS(seq, !float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status) && float32_eq(fst0, fst1, &env->fpu->fp_status), + !float32_is_unordered(1, fsth1, fsth0, &env->fpu->fp_status) && float32_eq(fsth0, fsth1, &env->fpu->fp_status)) +FOP_COND_PS(ngl, float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status) || float32_eq(fst0, fst1, &env->fpu->fp_status), + float32_is_unordered(1, fsth1, fsth0, &env->fpu->fp_status) || float32_eq(fsth0, fsth1, &env->fpu->fp_status)) +FOP_COND_PS(lt, !float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status) && float32_lt(fst0, fst1, &env->fpu->fp_status), + !float32_is_unordered(1, fsth1, fsth0, &env->fpu->fp_status) && float32_lt(fsth0, fsth1, &env->fpu->fp_status)) +FOP_COND_PS(nge, float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status) || float32_lt(fst0, fst1, &env->fpu->fp_status), + float32_is_unordered(1, fsth1, fsth0, &env->fpu->fp_status) || float32_lt(fsth0, fsth1, &env->fpu->fp_status)) +FOP_COND_PS(le, !float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status) && float32_le(fst0, fst1, &env->fpu->fp_status), + !float32_is_unordered(1, fsth1, fsth0, &env->fpu->fp_status) && float32_le(fsth0, fsth1, &env->fpu->fp_status)) +FOP_COND_PS(ngt, float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status) || float32_le(fst0, fst1, &env->fpu->fp_status), + float32_is_unordered(1, fsth1, fsth0, &env->fpu->fp_status) || float32_le(fsth0, fsth1, &env->fpu->fp_status)) |