summaryrefslogtreecommitdiff
path: root/Source/Core/DSPCore
diff options
context:
space:
mode:
authormylek4 <mylek4@gmail.com>2010-12-30 15:36:28 +0000
committermylek4 <mylek4@gmail.com>2010-12-30 15:36:28 +0000
commit6cf9b3688df632328b1fa223b9ade8d869cfade9 (patch)
treebd16054d5370afa7d71c04997a128b17c28d268d /Source/Core/DSPCore
parent2c4f9825ca54d730cbeb2d860092b0d8aaae6bca (diff)
LLE Int: (addr add/sub/inc/dec)
Adjusted the code work without ToMask. This code should be functionally identical for all inputs to the previous code. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6691 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/DSPCore')
-rw-r--r--Source/Core/DSPCore/Src/DSPIntUtil.h91
1 files changed, 55 insertions, 36 deletions
diff --git a/Source/Core/DSPCore/Src/DSPIntUtil.h b/Source/Core/DSPCore/Src/DSPIntUtil.h
index 7f3f520341..f73288f60b 100644
--- a/Source/Core/DSPCore/Src/DSPIntUtil.h
+++ b/Source/Core/DSPCore/Src/DSPIntUtil.h
@@ -52,55 +52,74 @@ inline bool dsp_SR_is_flag_set(int flag)
// --- AR increments, decrements
// ---------------------------------------------------------------------------------------
-// NextPowerOf2()-1
-inline u16 ToMask(u16 a)
+inline u16 dsp_increase_addr_reg(u16 reg, s16 _ix)
{
- a = a | (a >> 8);
- a = a | (a >> 4);
- a = a | (a >> 2);
- return a | (a >> 1);
+ u32 ar = g_dsp.r.ar[reg];
+ u32 wr = g_dsp.r.wr[reg];
+ s32 ix = _ix;
+
+ u32 mx = (wr | 1) << 1;
+ u32 nar = ar + ix;
+ u32 dar = (nar ^ ar ^ ix) & mx;
+
+ if (ix >= 0)
+ {
+ if (dar > wr) //overflow
+ nar -= wr + 1;
+ }
+ else
+ {
+ if ((((nar + wr + 1) ^ nar) & dar) <= wr) //underflow or below min for mask
+ nar += wr + 1;
+ }
+ return nar;
}
-inline u16 dsp_increase_addr_reg(u16 reg, s16 ix)
+inline u16 dsp_decrease_addr_reg(u16 reg, s16 _ix)
{
- u16 ar = g_dsp.r.ar[reg];
- u16 wr = g_dsp.r.wr[reg];
- u16 m = ToMask(wr) | 1;
- u16 nar = ar+ix;
- if (ix >= 0) {
- if((ar&m) + (int)(ix&m) -(int)m-1 >= 0)
- nar -= wr+1;
- } else {
- if((ar&m) + (int)(ix&m) -(int)m-1 < m-wr)
- nar += wr+1;
- }
- return nar;
-}
+ u32 ar = g_dsp.r.ar[reg];
+ u32 wr = g_dsp.r.wr[reg];
+ s32 ix = _ix;
-inline u16 dsp_decrease_addr_reg(u16 reg, s16 ix)
-{
- u16 ar = g_dsp.r.ar[reg];
- u16 wr = g_dsp.r.wr[reg];
- u16 m = ToMask(wr) | 1;
- u16 nar = ar-ix;
- if ((u16)ix > 0x8000) { // equiv: ix < 0 && ix != -0x8000
- if((ar&m) - (int)(ix&m) >= 0)
- nar -= wr+1;
- } else {
- if((ar&m) - (int)(ix&m) < m-wr)
- nar += wr+1;
- }
- return nar;
+ u32 mx = (wr | 1) << 1;
+ u32 nar = ar - ix;
+ u32 dar = (nar ^ ar ^ ~ix) & mx;
+
+ if ((u32)ix > 0xFFFF8000) //(ix < 0 && ix != -0x8000)
+ {
+ if (dar > wr) //overflow
+ nar -= wr + 1;
+ }
+ else
+ {
+ if ((((nar + wr + 1) ^ nar) & dar) <= wr) //underflow or below min for mask
+ nar += wr + 1;
+ }
+ return nar;
}
inline u16 dsp_increment_addr_reg(u16 reg)
{
- return dsp_increase_addr_reg(reg, 1);
+ u32 ar = g_dsp.r.ar[reg];
+ u32 wr = g_dsp.r.wr[reg];
+
+ u32 nar = ar + 1;
+
+ if (((nar ^ ar) & ((wr | 1) << 1)) > wr)
+ nar -= wr + 1;
+ return nar;
}
inline u16 dsp_decrement_addr_reg(u16 reg)
{
- return dsp_decrease_addr_reg(reg, 1);
+ u32 ar = g_dsp.r.ar[reg];
+ u32 wr = g_dsp.r.wr[reg];
+
+ u32 nar = ar + wr;
+
+ if (((nar ^ ar) & ((wr | 1) << 1)) > wr)
+ nar -= wr + 1;
+ return nar;
}