summaryrefslogtreecommitdiff
path: root/Source/Core/DSPCore
diff options
context:
space:
mode:
authorSoren Jorvang <soren.jorvang@gmail.com>2010-12-19 16:03:39 +0000
committerSoren Jorvang <soren.jorvang@gmail.com>2010-12-19 16:03:39 +0000
commit38a46ddf9443c4144cd176ea2fc8b7ae7e385fa0 (patch)
tree7d0c3ba7dc967dee5884bcfe2847abfbb1162d57 /Source/Core/DSPCore
parentc68ae8e91e6e15ad89552975bf7664c39f314958 (diff)
Avoid shadowing variables.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6613 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/DSPCore')
-rw-r--r--Source/Core/DSPCore/Src/Jit/DSPJitArithmetic.cpp2302
-rw-r--r--Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp572
-rw-r--r--Source/Core/DSPCore/Src/Jit/DSPJitLoadStore.cpp734
-rw-r--r--Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp30
4 files changed, 1820 insertions, 1818 deletions
diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitArithmetic.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitArithmetic.cpp
index 54924be7e6..3278f6f26e 100644
--- a/Source/Core/DSPCore/Src/Jit/DSPJitArithmetic.cpp
+++ b/Source/Core/DSPCore/Src/Jit/DSPJitArithmetic.cpp
@@ -1,1151 +1,1151 @@
-// Copyright (C) 2003 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-// Additional copyrights go to Duddie and Tratax (c) 2004
-
-#include "../DSPIntCCUtil.h"
-#include "../DSPIntUtil.h"
-#include "../DSPEmitter.h"
-#include "x64Emitter.h"
-#include "ABI.h"
-using namespace Gen;
-
-// CLR $acR
-// 1000 r001 xxxx xxxx
-// Clears accumulator $acR
-//
-// flags out: --10 0100
-//void DSPEmitter::clr(const UDSPInstruction opc)
-//{
-// u8 reg = (opc >> 11) & 0x1;
-
-// dsp_set_long_acc(reg, 0);
-// Update_SR_Register64(0);
-// zeroWriteBackLog();
-//}
-
-// CLRL $acR.l
-// 1111 110r xxxx xxxx
-// Clears (and rounds!) $acR.l - low 16 bits of accumulator $acR.
-//
-// flags out: --xx xx00
-//void DSPEmitter::clrl(const UDSPInstruction opc)
-//{
-// u8 reg = (opc >> 8) & 0x1;
-// s64 acc = dsp_round_long_acc(dsp_get_long_acc(reg));
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(reg, acc);
-// Update_SR_Register64(acc);
-//}
-
-//----
-
-// ANDCF $acD.m, #I
-// 0000 001r 1100 0000
-// iiii iiii iiii iiii
-// Set logic zero (LZ) flag in status register $sr if result of logic AND of
-// accumulator mid part $acD.m with immediate value I is equal I.
-//
-// flags out: -x-- ----
-//void DSPEmitter::andcf(const UDSPInstruction opc)
-//{
-// u8 reg = (opc >> 8) & 0x1;
-
-// u16 imm = dsp_fetch_code();
-// u16 val = dsp_get_acc_m(reg);
-// Update_SR_LZ(((val & imm) == imm) ? true : false);
-//}
-
-// ANDF $acD.m, #I
-// 0000 001r 1010 0000
-// iiii iiii iiii iiii
-// Set logic zero (LZ) flag in status register $sr if result of logical AND
-// operation of accumulator mid part $acD.m with immediate value I is equal
-// immediate value 0.
-//
-// flags out: -x-- ----
-//void DSPEmitter::andf(const UDSPInstruction opc)
-//{
-// u8 reg = (opc >> 8) & 0x1;
-
-// u16 imm = dsp_fetch_code();
-// u16 val = dsp_get_acc_m(reg);
-// Update_SR_LZ(((val & imm) == 0) ? true : false);
-//}
-
-//----
-
-// TST
-// 1011 r001 xxxx xxxx
-// Test accumulator %acR.
-//
-// flags out: --xx xx00
-//void DSPEmitter::tst(const UDSPInstruction opc)
-//{
-// u8 reg = (opc >> 11) & 0x1;
-
-// s64 acc = dsp_get_long_acc(reg);
-// Update_SR_Register64(acc);
-// zeroWriteBackLog();
-//}
-
-// TSTAXH $axR.h
-// 1000 011r xxxx xxxx
-// Test high part of secondary accumulator $axR.h.
-//
-// flags out: --x0 xx00
-//void DSPEmitter::tstaxh(const UDSPInstruction opc)
-//{
-// u8 reg = (opc >> 8) & 0x1;
-
-// s16 val = dsp_get_ax_h(reg);
-// Update_SR_Register16(val);
-// zeroWriteBackLog();
-//}
-
-//----
-
-// CMP
-// 1000 0010 xxxx xxxx
-// Compares accumulator $ac0 with accumulator $ac1.
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::cmp(const UDSPInstruction opc)
-//{
-// s64 acc0 = dsp_get_long_acc(0);
-// s64 acc1 = dsp_get_long_acc(1);
-// s64 res = dsp_convert_long_acc(acc0 - acc1);
-//
-// Update_SR_Register64(res, isCarry2(acc0, res), isOverflow(acc0, -acc1, res)); // CF -> influence on ABS/0xa100
-// zeroWriteBackLog();
-//}
-
-// CMPAR $acS axR.h
-// 1100 0001 xxxx xxxx
-// Compares accumulator $acS with accumulator axR.h.
-// Not described by Duddie's doc - at least not as a separate instruction.
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::cmpar(const UDSPInstruction opc)
-//{
-// u8 rreg = ((opc >> 12) & 0x1) + DSP_REG_AXH0;
-// u8 sreg = (opc >> 11) & 0x1;
-
-// s64 sr = dsp_get_long_acc(sreg);
-// s64 rr = (s16)g_dsp.r[rreg];
-// rr <<= 16;
-// s64 res = dsp_convert_long_acc(sr - rr);
-//
-// Update_SR_Register64(res, isCarry2(sr, res), isOverflow(sr, -rr, res));
-// zeroWriteBackLog();
-//}
-
-// CMPI $amD, #I
-// 0000 001r 1000 0000
-// iiii iiii iiii iiii
-// Compares mid accumulator $acD.hm ($amD) with sign extended immediate value I.
-// Although flags are being set regarding whole accumulator register.
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::cmpi(const UDSPInstruction opc)
-//{
-// u8 reg = (opc >> 8) & 0x1;
-
-// s64 val = dsp_get_long_acc(reg);
-// s64 imm = (s64)(s16)dsp_fetch_code() << 16; // Immediate is considered to be at M level in the 40-bit accumulator.
-// s64 res = dsp_convert_long_acc(val - imm);
-
-// Update_SR_Register64(res, isCarry2(val, res), isOverflow(val, -imm, res));
-//}
-
-// CMPIS $acD, #I
-// 0000 011d iiii iiii
-// Compares accumulator with short immediate. Comaprison is executed
-// by subtracting short immediate (8bit sign extended) from mid accumulator
-// $acD.hm and computing flags based on whole accumulator $acD.
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::cmpis(const UDSPInstruction opc)
-//{
-// u8 areg = (opc >> 8) & 0x1;
-
-// s64 acc = dsp_get_long_acc(areg);
-// s64 val = (s8)opc;
-// val <<= 16;
-// s64 res = dsp_convert_long_acc(acc - val);
-
-// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -val, res));
-//}
-
-//----
-
-// XORR $acD.m, $axS.h
-// 0011 00sd 0xxx xxxx
-// Logic XOR (exclusive or) middle part of accumulator $acD.m with
-// high part of secondary accumulator $axS.h.
-// x = extension (7 bits!!)
-//
-// flags out: --xx xx00
-//void DSPEmitter::xorr(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-// u8 sreg = (opc >> 9) & 0x1;
-// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] ^ g_dsp.r[DSP_REG_AXH0 + sreg];
-//
-// zeroWriteBackLogPreserveAcc(dreg);
-
-// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
-// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
-//}
-
-// ANDR $acD.m, $axS.h
-// 0011 01sd 0xxx xxxx
-// Logic AND middle part of accumulator $acD.m with high part of
-// secondary accumulator $axS.h.
-// x = extension (7 bits!!)
-//
-// flags out: --xx xx00
-//void DSPEmitter::andr(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-// u8 sreg = (opc >> 9) & 0x1;
-// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] & g_dsp.r[DSP_REG_AXH0 + sreg];
-//
-// zeroWriteBackLogPreserveAcc(dreg);
-
-// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
-// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
-//}
-
-// ORR $acD.m, $axS.h
-// 0011 10sd 0xxx xxxx
-// Logic OR middle part of accumulator $acD.m with high part of
-// secondary accumulator $axS.h.
-// x = extension (7 bits!!)
-//
-// flags out: --xx xx00
-//void DSPEmitter::orr(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-// u8 sreg = (opc >> 9) & 0x1;
-// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] | g_dsp.r[DSP_REG_AXH0 + sreg];
-//
-// zeroWriteBackLogPreserveAcc(dreg);
-
-// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
-// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
-//}
-
-// ANDC $acD.m, $ac(1-D).m
-// 0011 110d 0xxx xxxx
-// Logic AND middle part of accumulator $acD.m with middle part of
-// accumulator $ac(1-D).m
-// x = extension (7 bits!!)
-//
-// flags out: --xx xx00
-//void DSPEmitter::andc(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] & g_dsp.r[DSP_REG_ACM0 + (1 - dreg)];
-//
-// zeroWriteBackLogPreserveAcc(dreg);
-
-// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
-// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
-//}
-
-// ORC $acD.m, $ac(1-D).m
-// 0011 111d 0xxx xxxx
-// Logic OR middle part of accumulator $acD.m with middle part of
-// accumulator $ac(1-D).m.
-// x = extension (7 bits!!)
-//
-// flags out: --xx xx00
-//void DSPEmitter::orc(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] | g_dsp.r[DSP_REG_ACM0 + (1 - dreg)];
-//
-// zeroWriteBackLogPreserveAcc(dreg);
-
-// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
-// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
-//}
-
-// XORC $acD.m
-// 0011 000d 1xxx xxxx
-// Logic XOR (exclusive or) middle part of accumulator $acD.m with $ac(1-D).m
-// x = extension (7 bits!!)
-//
-// flags out: --xx xx00
-//void DSPEmitter::xorc(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] ^ g_dsp.r[DSP_REG_ACM0 + (1 - dreg)];
-
-// zeroWriteBackLogPreserveAcc(dreg);
-
-// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
-// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
-//}
-
-// NOT $acD.m
-// 0011 001d 1xxx xxxx
-// Invert all bits in dest reg, aka xor with 0xffff
-// x = extension (7 bits!!)
-//
-// flags out: --xx xx00
-//void DSPEmitter::notc(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] ^ 0xffff;
-
-// zeroWriteBackLogPreserveAcc(dreg);
-
-// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
-// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
-//}
-
-// XORI $acD.m, #I
-// 0000 001r 0010 0000
-// iiii iiii iiii iiii
-// Logic exclusive or (XOR) of accumulator mid part $acD.m with
-// immediate value I.
-//
-// flags out: --xx xx00
-//void DSPEmitter::xori(const UDSPInstruction opc)
-//{
-// u8 reg = (opc >> 8) & 0x1;
-// u16 imm = dsp_fetch_code();
-// g_dsp.r[DSP_REG_ACM0 + reg] ^= imm;
-
-// Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isOverS32(dsp_get_long_acc(reg)));
-//}
-
-// ANDI $acD.m, #I
-// 0000 001r 0100 0000
-// iiii iiii iiii iiii
-// Logic AND of accumulator mid part $acD.m with immediate value I.
-//
-// flags out: --xx xx00
-//void DSPEmitter::andi(const UDSPInstruction opc)
-//{
-// u8 reg = (opc >> 8) & 0x1;
-// u16 imm = dsp_fetch_code();
-// g_dsp.r[DSP_REG_ACM0 + reg] &= imm;
-
-// Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isOverS32(dsp_get_long_acc(reg)));
-//}
-
-// ORI $acD.m, #I
-// 0000 001r 0110 0000
-// iiii iiii iiii iiii
-// Logic OR of accumulator mid part $acD.m with immediate value I.
-//
-// flags out: --xx xx00
-//void DSPEmitter::ori(const UDSPInstruction opc)
-//{
-// u8 reg = (opc >> 8) & 0x1;
-// u16 imm = dsp_fetch_code();
-// g_dsp.r[DSP_REG_ACM0 + reg] |= imm;
-
-// Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isOverS32(dsp_get_long_acc(reg)));
-//}
-
-//----
-
-// ADDR $acD.M, $axS.L
-// 0100 0ssd xxxx xxxx
-// Adds register $axS.L to accumulator $acD.M register.
-//
-// flags out: x-xx xxxx
-void DSPEmitter::addr(const UDSPInstruction opc)
-{
-#ifdef _M_X64
- u8 dreg = (opc >> 8) & 0x1;
- u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
-
- MOV(64, R(R11), ImmPtr(&g_dsp.r));
-// s64 acc = dsp_get_long_acc(dreg);
- get_long_acc(dreg);
- PUSH(64, R(RAX));
-// s64 ax = (s16)g_dsp.r[sreg];
- MOVSX(64, 16, RDX, MDisp(R11, sreg * 2));
-// ax <<= 16;
- SHL(64, R(RDX), Imm8(16));
-// s64 res = acc + ax;
- ADD(64, R(RAX), R(RDX));
-// dsp_set_long_acc(dreg, res);
- set_long_acc(dreg);
-// Update_SR_Register64(res, isCarry(acc, res), isOverflow(acc, ax, res));
- XOR(8, R(RSI), R(RSI));
- POP(64, R(RCX));
- CMP(64, R(RCX), R(RAX));
-
- // Carry = (acc>res)
- FixupBranch noCarry = J_CC(CC_G);
- OR(8, R(RSI), Imm8(1));
- SetJumpTarget(noCarry);
-
- // Overflow = ((acc ^ res) & (ax ^ res)) < 0
- XOR(64, R(RCX), R(RAX));
- XOR(64, R(RDX), R(RAX));
- AND(64, R(RCX), R(RDX));
- CMP(64, R(RCX), Imm8(0));
- FixupBranch noOverflow = J_CC(CC_L);
- OR(8, R(RSI), Imm8(2));
- SetJumpTarget(noOverflow);
-
- Update_SR_Register64();
-#else
- Default(opc);
-#endif
-}
-
-// ADDAX $acD, $axS
-// 0100 10sd xxxx xxxx
-// Adds secondary accumulator $axS to accumulator register $acD.
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::addax(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-// u8 sreg = (opc >> 9) & 0x1;
-
-// s64 acc = dsp_get_long_acc(dreg);
-// s64 ax = dsp_get_long_acx(sreg);
-// s64 res = acc + ax;
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, res);
-// res = dsp_get_long_acc(dreg);
-// Update_SR_Register64(res, isCarry(acc, res), isOverflow(acc, ax, res));
-//}
-
-// ADD $acD, $ac(1-D)
-// 0100 110d xxxx xxxx
-// Adds accumulator $ac(1-D) to accumulator register $acD.
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::add(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-
-// s64 acc0 = dsp_get_long_acc(dreg);
-// s64 acc1 = dsp_get_long_acc(1 - dreg);
-// s64 res = acc0 + acc1;
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, res);
-// res = dsp_get_long_acc(dreg);
-// Update_SR_Register64(res, isCarry(acc0, res), isOverflow(acc0, acc1, res));
-//}
-
-// ADDP $acD
-// 0100 111d xxxx xxxx
-// Adds product register to accumulator register.
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::addp(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-
-// s64 acc = dsp_get_long_acc(dreg);
-// s64 prod = dsp_get_long_prod();
-// s64 res = acc + prod;
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, res);
-// res = dsp_get_long_acc(dreg);
-// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, prod, res));
-//}
-
-// ADDAXL $acD, $axS.l
-// 0111 00sd xxxx xxxx
-// Adds secondary accumulator $axS.l to accumulator register $acD.
-// should be unsigned values!!
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::addaxl(const UDSPInstruction opc)
-//{
-// u8 sreg = (opc >> 9) & 0x1;
-// u8 dreg = (opc >> 8) & 0x1;
-
-// u64 acc = dsp_get_long_acc(dreg);
-// u16 acx = (u16)dsp_get_ax_l(sreg);
-
-// u64 res = acc + acx;
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, (s64)res);
-// res = dsp_get_long_acc(dreg);
-// Update_SR_Register64((s64)res, isCarry(acc, res), isOverflow((s64)acc, (s64)acx, (s64)res));
-//}
-
-// ADDI $amR, #I
-// 0000 001r 0000 0000
-// iiii iiii iiii iiii
-// Adds immediate (16-bit sign extended) to mid accumulator $acD.hm.
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::addi(const UDSPInstruction opc)
-//{
-// u8 areg = (opc >> 8) & 0x1;
-
-// s64 acc = dsp_get_long_acc(areg);
-// s64 imm = (s16)dsp_fetch_code();
-// imm <<= 16;
-// s64 res = acc + imm;
-
-// dsp_set_long_acc(areg, res);
-// res = dsp_get_long_acc(areg);
-// Update_SR_Register64(res, isCarry(acc, res), isOverflow(acc, imm, res));
-//}
-
-// ADDIS $acD, #I
-// 0000 010d iiii iiii
-// Adds short immediate (8-bit sign extended) to mid accumulator $acD.hm.
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::addis(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-
-// s64 acc = dsp_get_long_acc(dreg);
-// s64 imm = (s8)(u8)opc;
-// imm <<= 16;
-// s64 res = acc + imm;
-
-// dsp_set_long_acc(dreg, res);
-// res = dsp_get_long_acc(dreg);
-// Update_SR_Register64(res, isCarry(acc, res), isOverflow(acc, imm, res));
-//}
-
-// INCM $acsD
-// 0111 010d xxxx xxxx
-// Increment 24-bit mid-accumulator $acsD.
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::incm(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-
-// s64 sub = 0x10000;
-// s64 acc = dsp_get_long_acc(dreg);
-// s64 res = acc + sub;
-
-// zeroWriteBackLog();
-//
-// dsp_set_long_acc(dreg, res);
-// res = dsp_get_long_acc(dreg);
-// Update_SR_Register64(res, isCarry(acc, res), isOverflow(acc, sub, res));
-//}
-
-// INC $acD
-// 0111 011d xxxx xxxx
-// Increment accumulator $acD.
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::inc(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-
-// s64 acc = dsp_get_long_acc(dreg);
-// s64 res = acc + 1;
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, res);
-// res = dsp_get_long_acc(dreg);
-// Update_SR_Register64(res, isCarry(acc, res), isOverflow(acc, 1, res));
-//}
-
-//----
-
-// SUBR $acD.M, $axS.L
-// 0101 0ssd xxxx xxxx
-// Subtracts register $axS.L from accumulator $acD.M register.
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::subr(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-// u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
-
-// s64 acc = dsp_get_long_acc(dreg);
-// s64 ax = (s16)g_dsp.r[sreg];
-// ax <<= 16;
-// s64 res = acc - ax;
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, res);
-// res = dsp_get_long_acc(dreg);
-// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -ax, res));
-//}
-
-// SUBAX $acD, $axS
-// 0101 10sd xxxx xxxx
-// Subtracts secondary accumulator $axS from accumulator register $acD.
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::subax(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-// u8 sreg = (opc >> 9) & 0x1;
-
-// s64 acc = dsp_get_long_acc(dreg);
-// s64 acx = dsp_get_long_acx(sreg);
-// s64 res = acc - acx;
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, res);
-// res = dsp_get_long_acc(dreg);
-// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -acx, res));
-//}
-
-// SUB $acD, $ac(1-D)
-// 0101 110d xxxx xxxx
-// Subtracts accumulator $ac(1-D) from accumulator register $acD.
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::sub(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-
-// s64 acc1 = dsp_get_long_acc(dreg);
-// s64 acc2 = dsp_get_long_acc(1 - dreg);
-// s64 res = acc1 - acc2;
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, res);
-// res = dsp_get_long_acc(dreg);
-// Update_SR_Register64(res, isCarry2(acc1, res), isOverflow(acc1, -acc2, res));
-//}
-
-// SUBP $acD
-// 0101 111d xxxx xxxx
-// Subtracts product register from accumulator register.
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::subp(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-
-// s64 acc = dsp_get_long_acc(dreg);
-// s64 prod = dsp_get_long_prod();
-// s64 res = acc - prod;
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, res);
-// res = dsp_get_long_acc(dreg);
-// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -prod, res));
-//}
-
-// DECM $acsD
-// 0111 100d xxxx xxxx
-// Decrement 24-bit mid-accumulator $acsD.
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::decm(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x01;
-
-// s64 sub = 0x10000;
-// s64 acc = dsp_get_long_acc(dreg);
-// s64 res = acc - sub;
-
-// zeroWriteBackLog();
-//
-// dsp_set_long_acc(dreg, res);
-// res = dsp_get_long_acc(dreg);
-// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -sub, res));
-//}
-
-// DEC $acD
-// 0111 101d xxxx xxxx
-// Decrement accumulator $acD.
-//
-// flags out: x-xx xxxx
-//void DSPEmitter::dec(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x01;
-
-// s64 acc = dsp_get_long_acc(dreg);
-// s64 res = acc - 1;
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, res);
-// res = dsp_get_long_acc(dreg);
-// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -1, res));
-//}
-
-//----
-
-// NEG $acD
-// 0111 110d xxxx xxxx
-// Negate accumulator $acD.
-//
-// flags out: --xx xx00
-//void DSPEmitter::neg(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-//
-// s64 acc = dsp_get_long_acc(dreg);
-// acc = 0 - acc;
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, acc);
-// Update_SR_Register64(dsp_get_long_acc(dreg));
-//}
-
-// ABS $acD
-// 1010 d001 xxxx xxxx
-// absolute value of $acD
-//
-// flags out: --xx xx00
-//void DSPEmitter::abs(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 11) & 0x1;
-
-// s64 acc = dsp_get_long_acc(dreg);
-
-// if (acc < 0)
-// acc = 0 - acc;
-//
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, acc);
-// Update_SR_Register64(dsp_get_long_acc(dreg));
-//}
-//----
-
-// MOVR $acD, $axS.R
-// 0110 0srd xxxx xxxx
-// Moves register $axS.R (sign extended) to middle accumulator $acD.hm.
-// Sets $acD.l to 0.
-// TODO: Check what happens to acD.h.
-//
-// flags out: --xx xx00
-//void DSPEmitter::movr(const UDSPInstruction opc)
-//{
-// u8 areg = (opc >> 8) & 0x1;
-// u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
-//
-// s64 acc = (s16)g_dsp.r[sreg];
-// acc <<= 16;
-// acc &= ~0xffff;
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(areg, acc);
-// Update_SR_Register64(acc);
-//}
-
-// MOVAX $acD, $axS
-// 0110 10sd xxxx xxxx
-// Moves secondary accumulator $axS to accumulator $axD.
-//
-// flags out: --xx xx00
-//void DSPEmitter::movax(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-// u8 sreg = (opc >> 9) & 0x1;
-
-// s64 acx = dsp_get_long_acx(sreg);
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, acx);
-// Update_SR_Register64(acx);
-//}
-
-// MOV $acD, $ac(1-D)
-// 0110 110d xxxx xxxx
-// Moves accumulator $ax(1-D) to accumulator $axD.
-//
-// flags out: --x0 xx00
-//void DSPEmitter::mov(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-// u64 acc = dsp_get_long_acc(1 - dreg);
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, acc);
-// Update_SR_Register64(acc);
-//}
-
-//----
-
-// LSL16 $acR
-// 1111 000r xxxx xxxx
-// Logically shifts left accumulator $acR by 16.
-//
-// flags out: --xx xx00
-void DSPEmitter::lsl16(const UDSPInstruction opc)
-{
-#ifdef _M_X64
- u8 areg = (opc >> 8) & 0x1;
-// s64 acc = dsp_get_long_acc(areg);
- get_long_acc(areg);
-// acc <<= 16;
- SHL(64, R(RAX), Imm8(16));
-// dsp_set_long_acc(areg, acc);
- set_long_acc(areg);
-// Update_SR_Register64(dsp_get_long_acc(areg));
- Update_SR_Register64();
-#else
- Default(opc);
-#endif
-}
-
-// LSR16 $acR
-// 1111 010r xxxx xxxx
-// Logically shifts right accumulator $acR by 16.
-//
-// flags out: --xx xx00
-//void DSPEmitter::lsr16(const UDSPInstruction opc)
-//{
-// u8 areg = (opc >> 8) & 0x1;
-
-// u64 acc = dsp_get_long_acc(areg);
-// acc &= 0x000000FFFFFFFFFFULL; // Lop off the extraneous sign extension our 64-bit fake accum causes
-// acc >>= 16;
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(areg, (s64)acc);
-// Update_SR_Register64(dsp_get_long_acc(areg));
-//}
-
-// ASR16 $acR
-// 1001 r001 xxxx xxxx
-// Arithmetically shifts right accumulator $acR by 16.
-//
-// flags out: --xx xx00
-//void DSPEmitter::asr16(const UDSPInstruction opc)
-//{
-// u8 areg = (opc >> 11) & 0x1;
-
-// s64 acc = dsp_get_long_acc(areg);
-// acc >>= 16;
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(areg, acc);
-// Update_SR_Register64(dsp_get_long_acc(areg));
-//}
-
-// LSL $acR, #I
-// 0001 010r 00ii iiii
-// Logically shifts left accumulator $acR by number specified by value I.
-//
-// flags out: --xx xx00
-void DSPEmitter::lsl(const UDSPInstruction opc)
-{
-#ifdef _M_X64
- u8 rreg = (opc >> 8) & 0x01;
- u16 shift = opc & 0x3f;
-// u64 acc = dsp_get_long_acc(rreg);
- get_long_acc(rreg);
-
-// acc <<= shift;
- SHL(64, R(RAX), Imm8(shift));
-
-// dsp_set_long_acc(rreg, acc);
- set_long_acc(rreg);
-// Update_SR_Register64(dsp_get_long_acc(rreg));
- Update_SR_Register64();
-#else
- Default(opc);
-#endif
-}
-
-// LSR $acR, #I
-// 0001 010r 01ii iiii
-// Logically shifts right accumulator $acR by number specified by value
-// calculated by negating sign extended bits 0-6.
-//
-// flags out: --xx xx00
-//void DSPEmitter::lsr(const UDSPInstruction opc)
-//{
-// u8 rreg = (opc >> 8) & 0x01;
-// u16 shift;
-// u64 acc = dsp_get_long_acc(rreg);
-// acc &= 0x000000FFFFFFFFFFULL; // Lop off the extraneous sign extension our 64-bit fake accum causes
-
-// if ((opc & 0x3f) == 0)
-// shift = 0;
-// else
-// shift = 0x40 - (opc & 0x3f);
-
-// acc >>= shift;
-//
-// dsp_set_long_acc(rreg, (s64)acc);
-// Update_SR_Register64(dsp_get_long_acc(rreg));
-//}
-
-// ASL $acR, #I
-// 0001 010r 10ii iiii
-// Logically shifts left accumulator $acR by number specified by value I.
-//
-// flags out: --xx xx00
-//void DSPEmitter::asl(const UDSPInstruction opc)
-//{
-// u8 rreg = (opc >> 8) & 0x01;
-// u16 shift = opc & 0x3f;
-// u64 acc = dsp_get_long_acc(rreg);
-
-// acc <<= shift;
-//
-// dsp_set_long_acc(rreg, acc);
-// Update_SR_Register64(dsp_get_long_acc(rreg));
-//}
-
-// ASR $acR, #I
-// 0001 010r 11ii iiii
-// Arithmetically shifts right accumulator $acR by number specified by
-// value calculated by negating sign extended bits 0-6.
-//
-// flags out: --xx xx00
-//void DSPEmitter::asr(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x01;
-// u16 shift;
-
-// if ((opc & 0x3f) == 0)
-// shift = 0;
-// else
-// shift = 0x40 - (opc & 0x3f);
-
-// // arithmetic shift
-// s64 acc = dsp_get_long_acc(dreg);
-// acc >>= shift;
-
-// dsp_set_long_acc(dreg, acc);
-// Update_SR_Register64(dsp_get_long_acc(dreg));
-//}
-
-// LSRN (fixed parameters)
-// 0000 0010 1100 1010
-// Logically shifts right accumulator $ACC0 by lower 7-bit (signed) value in $AC1.M
-// (if value negative, becomes left shift).
-//
-// flags out: --xx xx00
-//void DSPEmitter::lsrn(const UDSPInstruction opc)
-//{
-// s16 shift;
-// u16 accm = (u16)dsp_get_acc_m(1);
-// u64 acc = dsp_get_long_acc(0);
-// acc &= 0x000000FFFFFFFFFFULL;
-
-// if ((accm & 0x3f) == 0)
-// shift = 0;
-// else if (accm & 0x40)
-// shift = -0x40 + (accm & 0x3f);
-// else
-// shift = accm & 0x3f;
-
-// if (shift > 0) {
-// acc >>= shift;
-// } else if (shift < 0) {
-// acc <<= -shift;
-// }
-
-// dsp_set_long_acc(0, (s64)acc);
-// Update_SR_Register64(dsp_get_long_acc(0));
-//}
-
-// ASRN (fixed parameters)
-// 0000 0010 1100 1011
-// Arithmetically shifts right accumulator $ACC0 by lower 7-bit (signed) value in $AC1.M
-// (if value negative, becomes left shift).
-//
-// flags out: --xx xx00
-//void DSPEmitter::asrn(const UDSPInstruction opc)
-//{
-// s16 shift;
-// u16 accm = (u16)dsp_get_acc_m(1);
-// s64 acc = dsp_get_long_acc(0);
-
-// if ((accm & 0x3f) == 0)
-// shift = 0;
-// else if (accm & 0x40)
-// shift = -0x40 + (accm & 0x3f);
-// else
-// shift = accm & 0x3f;
-
-// if (shift > 0) {
-// acc >>= shift;
-// } else if (shift < 0) {
-// acc <<= -shift;
-// }
-
-// dsp_set_long_acc(0, acc);
-// Update_SR_Register64(dsp_get_long_acc(0));
-//}
-
-// LSRNRX $acD, $axS.h
-// 0011 01sd 1xxx xxxx
-// Logically shifts left/right accumulator $ACC[D] by lower 7-bit (signed) value in $AX[S].H
-// x = extension (7 bits!!)
-//
-// flags out: --xx xx00
-//void DSPEmitter::lsrnrx(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-// u8 sreg = (opc >> 9) & 0x1;
-
-// s16 shift;
-// u16 axh = g_dsp.r[DSP_REG_AXH0 + sreg];
-// u64 acc = dsp_get_long_acc(dreg);
-// acc &= 0x000000FFFFFFFFFFULL;
-
-// if ((axh & 0x3f) == 0)
-// shift = 0;
-// else if (axh & 0x40)
-// shift = -0x40 + (axh & 0x3f);
-// else
-// shift = axh & 0x3f;
-
-// if (shift > 0) {
-// acc <<= shift;
-// } else if (shift < 0) {
-// acc >>= -shift;
-// }
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, (s64)acc);
-// Update_SR_Register64(dsp_get_long_acc(dreg));
-//}
-
-// ASRNRX $acD, $axS.h
-// 0011 10sd 1xxx xxxx
-// Arithmetically shifts left/right accumulator $ACC[D] by lower 7-bit (signed) value in $AX[S].H
-// x = extension (7 bits!!)
-//
-// flags out: --xx xx00
-//void DSPEmitter::asrnrx(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-// u8 sreg = (opc >> 9) & 0x1;
-
-// s16 shift;
-// u16 axh = g_dsp.r[DSP_REG_AXH0 + sreg];
-// s64 acc = dsp_get_long_acc(dreg);
-
-// if ((axh & 0x3f) == 0)
-// shift = 0;
-// else if (axh & 0x40)
-// shift = -0x40 + (axh & 0x3f);
-// else
-// shift = axh & 0x3f;
-
-// if (shift > 0) {
-// acc <<= shift;
-// } else if (shift < 0) {
-// acc >>= -shift;
-// }
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, acc);
-// Update_SR_Register64(dsp_get_long_acc(dreg));
-//}
-
-// LSRNR $acD
-// 0011 110d 1xxx xxxx
-// Logically shifts left/right accumulator $ACC[D] by lower 7-bit (signed) value in $AC[1-D].M
-// x = extension (7 bits!!)
-//
-// flags out: --xx xx00
-//void DSPEmitter::lsrnr(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-
-// s16 shift;
-// u16 accm = (u16)dsp_get_acc_m(1 - dreg);
-// u64 acc = dsp_get_long_acc(dreg);
-// acc &= 0x000000FFFFFFFFFFULL;
-
-// if ((accm & 0x3f) == 0)
-// shift = 0;
-// else if (accm & 0x40)
-// shift = -0x40 + (accm & 0x3f);
-// else
-// shift = accm & 0x3f;
-
-// if (shift > 0)
-// acc <<= shift;
-// else if (shift < 0)
-// acc >>= -shift;
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, (s64)acc);
-// Update_SR_Register64(dsp_get_long_acc(dreg));
-//}
-
-// ASRNR $acD
-// 0011 111d 1xxx xxxx
-// Arithmeticaly shift left/right accumulator $ACC[D] by lower 7-bit (signed) value in $AC[1-D].M
-// x = extension (7 bits!!)
-//
-// flags out: --xx xx00
-//void DSPEmitter::asrnr(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 8) & 0x1;
-
-// s16 shift;
-// u16 accm = (u16)dsp_get_acc_m(1 - dreg);
-// s64 acc = dsp_get_long_acc(dreg);
-
-// if ((accm & 0x3f) == 0)
-// shift = 0;
-// else if (accm & 0x40)
-// shift = -0x40 + (accm & 0x3f);
-// else
-// shift = accm & 0x3f;
-
-// if (shift > 0)
-// acc <<= shift;
-// else if (shift < 0)
-// acc >>= -shift;
-
-// zeroWriteBackLog();
-
-// dsp_set_long_acc(dreg, acc);
-// Update_SR_Register64(dsp_get_long_acc(dreg));
-//}
-
-
-//} // namespace
-
-//
+// Copyright (C) 2003 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Additional copyrights go to Duddie and Tratax (c) 2004
+
+#include "../DSPIntCCUtil.h"
+#include "../DSPIntUtil.h"
+#include "../DSPEmitter.h"
+#include "x64Emitter.h"
+#include "ABI.h"
+using namespace Gen;
+
+// CLR $acR
+// 1000 r001 xxxx xxxx
+// Clears accumulator $acR
+//
+// flags out: --10 0100
+//void DSPEmitter::clr(const UDSPInstruction opc)
+//{
+// u8 reg = (opc >> 11) & 0x1;
+
+// dsp_set_long_acc(reg, 0);
+// Update_SR_Register64(0);
+// zeroWriteBackLog();
+//}
+
+// CLRL $acR.l
+// 1111 110r xxxx xxxx
+// Clears (and rounds!) $acR.l - low 16 bits of accumulator $acR.
+//
+// flags out: --xx xx00
+//void DSPEmitter::clrl(const UDSPInstruction opc)
+//{
+// u8 reg = (opc >> 8) & 0x1;
+// s64 acc = dsp_round_long_acc(dsp_get_long_acc(reg));
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(reg, acc);
+// Update_SR_Register64(acc);
+//}
+
+//----
+
+// ANDCF $acD.m, #I
+// 0000 001r 1100 0000
+// iiii iiii iiii iiii
+// Set logic zero (LZ) flag in status register $sr if result of logic AND of
+// accumulator mid part $acD.m with immediate value I is equal I.
+//
+// flags out: -x-- ----
+//void DSPEmitter::andcf(const UDSPInstruction opc)
+//{
+// u8 reg = (opc >> 8) & 0x1;
+
+// u16 imm = dsp_fetch_code();
+// u16 val = dsp_get_acc_m(reg);
+// Update_SR_LZ(((val & imm) == imm) ? true : false);
+//}
+
+// ANDF $acD.m, #I
+// 0000 001r 1010 0000
+// iiii iiii iiii iiii
+// Set logic zero (LZ) flag in status register $sr if result of logical AND
+// operation of accumulator mid part $acD.m with immediate value I is equal
+// immediate value 0.
+//
+// flags out: -x-- ----
+//void DSPEmitter::andf(const UDSPInstruction opc)
+//{
+// u8 reg = (opc >> 8) & 0x1;
+
+// u16 imm = dsp_fetch_code();
+// u16 val = dsp_get_acc_m(reg);
+// Update_SR_LZ(((val & imm) == 0) ? true : false);
+//}
+
+//----
+
+// TST
+// 1011 r001 xxxx xxxx
+// Test accumulator %acR.
+//
+// flags out: --xx xx00
+//void DSPEmitter::tst(const UDSPInstruction opc)
+//{
+// u8 reg = (opc >> 11) & 0x1;
+
+// s64 acc = dsp_get_long_acc(reg);
+// Update_SR_Register64(acc);
+// zeroWriteBackLog();
+//}
+
+// TSTAXH $axR.h
+// 1000 011r xxxx xxxx
+// Test high part of secondary accumulator $axR.h.
+//
+// flags out: --x0 xx00
+//void DSPEmitter::tstaxh(const UDSPInstruction opc)
+//{
+// u8 reg = (opc >> 8) & 0x1;
+
+// s16 val = dsp_get_ax_h(reg);
+// Update_SR_Register16(val);
+// zeroWriteBackLog();
+//}
+
+//----
+
+// CMP
+// 1000 0010 xxxx xxxx
+// Compares accumulator $ac0 with accumulator $ac1.
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::cmp(const UDSPInstruction opc)
+//{
+// s64 acc0 = dsp_get_long_acc(0);
+// s64 acc1 = dsp_get_long_acc(1);
+// s64 res = dsp_convert_long_acc(acc0 - acc1);
+//
+// Update_SR_Register64(res, isCarry2(acc0, res), isOverflow(acc0, -acc1, res)); // CF -> influence on ABS/0xa100
+// zeroWriteBackLog();
+//}
+
+// CMPAR $acS axR.h
+// 1100 0001 xxxx xxxx
+// Compares accumulator $acS with accumulator axR.h.
+// Not described by Duddie's doc - at least not as a separate instruction.
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::cmpar(const UDSPInstruction opc)
+//{
+// u8 rreg = ((opc >> 12) & 0x1) + DSP_REG_AXH0;
+// u8 sreg = (opc >> 11) & 0x1;
+
+// s64 sr = dsp_get_long_acc(sreg);
+// s64 rr = (s16)g_dsp.r[rreg];
+// rr <<= 16;
+// s64 res = dsp_convert_long_acc(sr - rr);
+//
+// Update_SR_Register64(res, isCarry2(sr, res), isOverflow(sr, -rr, res));
+// zeroWriteBackLog();
+//}
+
+// CMPI $amD, #I
+// 0000 001r 1000 0000
+// iiii iiii iiii iiii
+// Compares mid accumulator $acD.hm ($amD) with sign extended immediate value I.
+// Although flags are being set regarding whole accumulator register.
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::cmpi(const UDSPInstruction opc)
+//{
+// u8 reg = (opc >> 8) & 0x1;
+
+// s64 val = dsp_get_long_acc(reg);
+// s64 imm = (s64)(s16)dsp_fetch_code() << 16; // Immediate is considered to be at M level in the 40-bit accumulator.
+// s64 res = dsp_convert_long_acc(val - imm);
+
+// Update_SR_Register64(res, isCarry2(val, res), isOverflow(val, -imm, res));
+//}
+
+// CMPIS $acD, #I
+// 0000 011d iiii iiii
+// Compares accumulator with short immediate. Comaprison is executed
+// by subtracting short immediate (8bit sign extended) from mid accumulator
+// $acD.hm and computing flags based on whole accumulator $acD.
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::cmpis(const UDSPInstruction opc)
+//{
+// u8 areg = (opc >> 8) & 0x1;
+
+// s64 acc = dsp_get_long_acc(areg);
+// s64 val = (s8)opc;
+// val <<= 16;
+// s64 res = dsp_convert_long_acc(acc - val);
+
+// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -val, res));
+//}
+
+//----
+
+// XORR $acD.m, $axS.h
+// 0011 00sd 0xxx xxxx
+// Logic XOR (exclusive or) middle part of accumulator $acD.m with
+// high part of secondary accumulator $axS.h.
+// x = extension (7 bits!!)
+//
+// flags out: --xx xx00
+//void DSPEmitter::xorr(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+// u8 sreg = (opc >> 9) & 0x1;
+// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] ^ g_dsp.r[DSP_REG_AXH0 + sreg];
+//
+// zeroWriteBackLogPreserveAcc(dreg);
+
+// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
+// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
+//}
+
+// ANDR $acD.m, $axS.h
+// 0011 01sd 0xxx xxxx
+// Logic AND middle part of accumulator $acD.m with high part of
+// secondary accumulator $axS.h.
+// x = extension (7 bits!!)
+//
+// flags out: --xx xx00
+//void DSPEmitter::andr(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+// u8 sreg = (opc >> 9) & 0x1;
+// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] & g_dsp.r[DSP_REG_AXH0 + sreg];
+//
+// zeroWriteBackLogPreserveAcc(dreg);
+
+// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
+// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
+//}
+
+// ORR $acD.m, $axS.h
+// 0011 10sd 0xxx xxxx
+// Logic OR middle part of accumulator $acD.m with high part of
+// secondary accumulator $axS.h.
+// x = extension (7 bits!!)
+//
+// flags out: --xx xx00
+//void DSPEmitter::orr(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+// u8 sreg = (opc >> 9) & 0x1;
+// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] | g_dsp.r[DSP_REG_AXH0 + sreg];
+//
+// zeroWriteBackLogPreserveAcc(dreg);
+
+// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
+// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
+//}
+
+// ANDC $acD.m, $ac(1-D).m
+// 0011 110d 0xxx xxxx
+// Logic AND middle part of accumulator $acD.m with middle part of
+// accumulator $ac(1-D).m
+// x = extension (7 bits!!)
+//
+// flags out: --xx xx00
+//void DSPEmitter::andc(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] & g_dsp.r[DSP_REG_ACM0 + (1 - dreg)];
+//
+// zeroWriteBackLogPreserveAcc(dreg);
+
+// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
+// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
+//}
+
+// ORC $acD.m, $ac(1-D).m
+// 0011 111d 0xxx xxxx
+// Logic OR middle part of accumulator $acD.m with middle part of
+// accumulator $ac(1-D).m.
+// x = extension (7 bits!!)
+//
+// flags out: --xx xx00
+//void DSPEmitter::orc(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] | g_dsp.r[DSP_REG_ACM0 + (1 - dreg)];
+//
+// zeroWriteBackLogPreserveAcc(dreg);
+
+// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
+// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
+//}
+
+// XORC $acD.m
+// 0011 000d 1xxx xxxx
+// Logic XOR (exclusive or) middle part of accumulator $acD.m with $ac(1-D).m
+// x = extension (7 bits!!)
+//
+// flags out: --xx xx00
+//void DSPEmitter::xorc(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] ^ g_dsp.r[DSP_REG_ACM0 + (1 - dreg)];
+
+// zeroWriteBackLogPreserveAcc(dreg);
+
+// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
+// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
+//}
+
+// NOT $acD.m
+// 0011 001d 1xxx xxxx
+// Invert all bits in dest reg, aka xor with 0xffff
+// x = extension (7 bits!!)
+//
+// flags out: --xx xx00
+//void DSPEmitter::notc(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] ^ 0xffff;
+
+// zeroWriteBackLogPreserveAcc(dreg);
+
+// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
+// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
+//}
+
+// XORI $acD.m, #I
+// 0000 001r 0010 0000
+// iiii iiii iiii iiii
+// Logic exclusive or (XOR) of accumulator mid part $acD.m with
+// immediate value I.
+//
+// flags out: --xx xx00
+//void DSPEmitter::xori(const UDSPInstruction opc)
+//{
+// u8 reg = (opc >> 8) & 0x1;
+// u16 imm = dsp_fetch_code();
+// g_dsp.r[DSP_REG_ACM0 + reg] ^= imm;
+
+// Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isOverS32(dsp_get_long_acc(reg)));
+//}
+
+// ANDI $acD.m, #I
+// 0000 001r 0100 0000
+// iiii iiii iiii iiii
+// Logic AND of accumulator mid part $acD.m with immediate value I.
+//
+// flags out: --xx xx00
+//void DSPEmitter::andi(const UDSPInstruction opc)
+//{
+// u8 reg = (opc >> 8) & 0x1;
+// u16 imm = dsp_fetch_code();
+// g_dsp.r[DSP_REG_ACM0 + reg] &= imm;
+
+// Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isOverS32(dsp_get_long_acc(reg)));
+//}
+
+// ORI $acD.m, #I
+// 0000 001r 0110 0000
+// iiii iiii iiii iiii
+// Logic OR of accumulator mid part $acD.m with immediate value I.
+//
+// flags out: --xx xx00
+//void DSPEmitter::ori(const UDSPInstruction opc)
+//{
+// u8 reg = (opc >> 8) & 0x1;
+// u16 imm = dsp_fetch_code();
+// g_dsp.r[DSP_REG_ACM0 + reg] |= imm;
+
+// Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isOverS32(dsp_get_long_acc(reg)));
+//}
+
+//----
+
+// ADDR $acD.M, $axS.L
+// 0100 0ssd xxxx xxxx
+// Adds register $axS.L to accumulator $acD.M register.
+//
+// flags out: x-xx xxxx
+void DSPEmitter::addr(const UDSPInstruction opc)
+{
+#ifdef _M_X64
+ u8 dreg = (opc >> 8) & 0x1;
+ u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
+
+ MOV(64, R(R11), ImmPtr(&g_dsp.r));
+// s64 acc = dsp_get_long_acc(dreg);
+ get_long_acc(dreg);
+ PUSH(64, R(RAX));
+// s64 ax = (s16)g_dsp.r[sreg];
+ MOVSX(64, 16, RDX, MDisp(R11, sreg * 2));
+// ax <<= 16;
+ SHL(64, R(RDX), Imm8(16));
+// s64 res = acc + ax;
+ ADD(64, R(RAX), R(RDX));
+// dsp_set_long_acc(dreg, res);
+ set_long_acc(dreg);
+// Update_SR_Register64(res, isCarry(acc, res), isOverflow(acc, ax, res));
+ XOR(8, R(RSI), R(RSI));
+ POP(64, R(RCX));
+ CMP(64, R(RCX), R(RAX));
+
+ // Carry = (acc>res)
+ FixupBranch noCarry = J_CC(CC_G);
+ OR(8, R(RSI), Imm8(1));
+ SetJumpTarget(noCarry);
+
+ // Overflow = ((acc ^ res) & (ax ^ res)) < 0
+ XOR(64, R(RCX), R(RAX));
+ XOR(64, R(RDX), R(RAX));
+ AND(64, R(RCX), R(RDX));
+ CMP(64, R(RCX), Imm8(0));
+ FixupBranch noOverflow = J_CC(CC_L);
+ OR(8, R(RSI), Imm8(2));
+ SetJumpTarget(noOverflow);
+
+ Update_SR_Register64();
+#else
+ Default(opc);
+#endif
+}
+
+// ADDAX $acD, $axS
+// 0100 10sd xxxx xxxx
+// Adds secondary accumulator $axS to accumulator register $acD.
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::addax(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+// u8 sreg = (opc >> 9) & 0x1;
+
+// s64 acc = dsp_get_long_acc(dreg);
+// s64 ax = dsp_get_long_acx(sreg);
+// s64 res = acc + ax;
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, res);
+// res = dsp_get_long_acc(dreg);
+// Update_SR_Register64(res, isCarry(acc, res), isOverflow(acc, ax, res));
+//}
+
+// ADD $acD, $ac(1-D)
+// 0100 110d xxxx xxxx
+// Adds accumulator $ac(1-D) to accumulator register $acD.
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::add(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+
+// s64 acc0 = dsp_get_long_acc(dreg);
+// s64 acc1 = dsp_get_long_acc(1 - dreg);
+// s64 res = acc0 + acc1;
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, res);
+// res = dsp_get_long_acc(dreg);
+// Update_SR_Register64(res, isCarry(acc0, res), isOverflow(acc0, acc1, res));
+//}
+
+// ADDP $acD
+// 0100 111d xxxx xxxx
+// Adds product register to accumulator register.
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::addp(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+
+// s64 acc = dsp_get_long_acc(dreg);
+// s64 prod = dsp_get_long_prod();
+// s64 res = acc + prod;
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, res);
+// res = dsp_get_long_acc(dreg);
+// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, prod, res));
+//}
+
+// ADDAXL $acD, $axS.l
+// 0111 00sd xxxx xxxx
+// Adds secondary accumulator $axS.l to accumulator register $acD.
+// should be unsigned values!!
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::addaxl(const UDSPInstruction opc)
+//{
+// u8 sreg = (opc >> 9) & 0x1;
+// u8 dreg = (opc >> 8) & 0x1;
+
+// u64 acc = dsp_get_long_acc(dreg);
+// u16 acx = (u16)dsp_get_ax_l(sreg);
+
+// u64 res = acc + acx;
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, (s64)res);
+// res = dsp_get_long_acc(dreg);
+// Update_SR_Register64((s64)res, isCarry(acc, res), isOverflow((s64)acc, (s64)acx, (s64)res));
+//}
+
+// ADDI $amR, #I
+// 0000 001r 0000 0000
+// iiii iiii iiii iiii
+// Adds immediate (16-bit sign extended) to mid accumulator $acD.hm.
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::addi(const UDSPInstruction opc)
+//{
+// u8 areg = (opc >> 8) & 0x1;
+
+// s64 acc = dsp_get_long_acc(areg);
+// s64 imm = (s16)dsp_fetch_code();
+// imm <<= 16;
+// s64 res = acc + imm;
+
+// dsp_set_long_acc(areg, res);
+// res = dsp_get_long_acc(areg);
+// Update_SR_Register64(res, isCarry(acc, res), isOverflow(acc, imm, res));
+//}
+
+// ADDIS $acD, #I
+// 0000 010d iiii iiii
+// Adds short immediate (8-bit sign extended) to mid accumulator $acD.hm.
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::addis(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+
+// s64 acc = dsp_get_long_acc(dreg);
+// s64 imm = (s8)(u8)opc;
+// imm <<= 16;
+// s64 res = acc + imm;
+
+// dsp_set_long_acc(dreg, res);
+// res = dsp_get_long_acc(dreg);
+// Update_SR_Register64(res, isCarry(acc, res), isOverflow(acc, imm, res));
+//}
+
+// INCM $acsD
+// 0111 010d xxxx xxxx
+// Increment 24-bit mid-accumulator $acsD.
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::incm(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+
+// s64 sub = 0x10000;
+// s64 acc = dsp_get_long_acc(dreg);
+// s64 res = acc + sub;
+
+// zeroWriteBackLog();
+//
+// dsp_set_long_acc(dreg, res);
+// res = dsp_get_long_acc(dreg);
+// Update_SR_Register64(res, isCarry(acc, res), isOverflow(acc, sub, res));
+//}
+
+// INC $acD
+// 0111 011d xxxx xxxx
+// Increment accumulator $acD.
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::inc(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+
+// s64 acc = dsp_get_long_acc(dreg);
+// s64 res = acc + 1;
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, res);
+// res = dsp_get_long_acc(dreg);
+// Update_SR_Register64(res, isCarry(acc, res), isOverflow(acc, 1, res));
+//}
+
+//----
+
+// SUBR $acD.M, $axS.L
+// 0101 0ssd xxxx xxxx
+// Subtracts register $axS.L from accumulator $acD.M register.
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::subr(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+// u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
+
+// s64 acc = dsp_get_long_acc(dreg);
+// s64 ax = (s16)g_dsp.r[sreg];
+// ax <<= 16;
+// s64 res = acc - ax;
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, res);
+// res = dsp_get_long_acc(dreg);
+// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -ax, res));
+//}
+
+// SUBAX $acD, $axS
+// 0101 10sd xxxx xxxx
+// Subtracts secondary accumulator $axS from accumulator register $acD.
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::subax(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+// u8 sreg = (opc >> 9) & 0x1;
+
+// s64 acc = dsp_get_long_acc(dreg);
+// s64 acx = dsp_get_long_acx(sreg);
+// s64 res = acc - acx;
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, res);
+// res = dsp_get_long_acc(dreg);
+// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -acx, res));
+//}
+
+// SUB $acD, $ac(1-D)
+// 0101 110d xxxx xxxx
+// Subtracts accumulator $ac(1-D) from accumulator register $acD.
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::sub(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+
+// s64 acc1 = dsp_get_long_acc(dreg);
+// s64 acc2 = dsp_get_long_acc(1 - dreg);
+// s64 res = acc1 - acc2;
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, res);
+// res = dsp_get_long_acc(dreg);
+// Update_SR_Register64(res, isCarry2(acc1, res), isOverflow(acc1, -acc2, res));
+//}
+
+// SUBP $acD
+// 0101 111d xxxx xxxx
+// Subtracts product register from accumulator register.
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::subp(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+
+// s64 acc = dsp_get_long_acc(dreg);
+// s64 prod = dsp_get_long_prod();
+// s64 res = acc - prod;
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, res);
+// res = dsp_get_long_acc(dreg);
+// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -prod, res));
+//}
+
+// DECM $acsD
+// 0111 100d xxxx xxxx
+// Decrement 24-bit mid-accumulator $acsD.
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::decm(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x01;
+
+// s64 sub = 0x10000;
+// s64 acc = dsp_get_long_acc(dreg);
+// s64 res = acc - sub;
+
+// zeroWriteBackLog();
+//
+// dsp_set_long_acc(dreg, res);
+// res = dsp_get_long_acc(dreg);
+// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -sub, res));
+//}
+
+// DEC $acD
+// 0111 101d xxxx xxxx
+// Decrement accumulator $acD.
+//
+// flags out: x-xx xxxx
+//void DSPEmitter::dec(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x01;
+
+// s64 acc = dsp_get_long_acc(dreg);
+// s64 res = acc - 1;
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, res);
+// res = dsp_get_long_acc(dreg);
+// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -1, res));
+//}
+
+//----
+
+// NEG $acD
+// 0111 110d xxxx xxxx
+// Negate accumulator $acD.
+//
+// flags out: --xx xx00
+//void DSPEmitter::neg(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+//
+// s64 acc = dsp_get_long_acc(dreg);
+// acc = 0 - acc;
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, acc);
+// Update_SR_Register64(dsp_get_long_acc(dreg));
+//}
+
+// ABS $acD
+// 1010 d001 xxxx xxxx
+// absolute value of $acD
+//
+// flags out: --xx xx00
+//void DSPEmitter::abs(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 11) & 0x1;
+
+// s64 acc = dsp_get_long_acc(dreg);
+
+// if (acc < 0)
+// acc = 0 - acc;
+//
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, acc);
+// Update_SR_Register64(dsp_get_long_acc(dreg));
+//}
+//----
+
+// MOVR $acD, $axS.R
+// 0110 0srd xxxx xxxx
+// Moves register $axS.R (sign extended) to middle accumulator $acD.hm.
+// Sets $acD.l to 0.
+// TODO: Check what happens to acD.h.
+//
+// flags out: --xx xx00
+//void DSPEmitter::movr(const UDSPInstruction opc)
+//{
+// u8 areg = (opc >> 8) & 0x1;
+// u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
+//
+// s64 acc = (s16)g_dsp.r[sreg];
+// acc <<= 16;
+// acc &= ~0xffff;
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(areg, acc);
+// Update_SR_Register64(acc);
+//}
+
+// MOVAX $acD, $axS
+// 0110 10sd xxxx xxxx
+// Moves secondary accumulator $axS to accumulator $axD.
+//
+// flags out: --xx xx00
+//void DSPEmitter::movax(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+// u8 sreg = (opc >> 9) & 0x1;
+
+// s64 acx = dsp_get_long_acx(sreg);
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, acx);
+// Update_SR_Register64(acx);
+//}
+
+// MOV $acD, $ac(1-D)
+// 0110 110d xxxx xxxx
+// Moves accumulator $ax(1-D) to accumulator $axD.
+//
+// flags out: --x0 xx00
+//void DSPEmitter::mov(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+// u64 acc = dsp_get_long_acc(1 - dreg);
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, acc);
+// Update_SR_Register64(acc);
+//}
+
+//----
+
+// LSL16 $acR
+// 1111 000r xxxx xxxx
+// Logically shifts left accumulator $acR by 16.
+//
+// flags out: --xx xx00
+void DSPEmitter::lsl16(const UDSPInstruction opc)
+{
+#ifdef _M_X64
+ u8 areg = (opc >> 8) & 0x1;
+// s64 acc = dsp_get_long_acc(areg);
+ get_long_acc(areg);
+// acc <<= 16;
+ SHL(64, R(RAX), Imm8(16));
+// dsp_set_long_acc(areg, acc);
+ set_long_acc(areg);
+// Update_SR_Register64(dsp_get_long_acc(areg));
+ Update_SR_Register64();
+#else
+ Default(opc);
+#endif
+}
+
+// LSR16 $acR
+// 1111 010r xxxx xxxx
+// Logically shifts right accumulator $acR by 16.
+//
+// flags out: --xx xx00
+//void DSPEmitter::lsr16(const UDSPInstruction opc)
+//{
+// u8 areg = (opc >> 8) & 0x1;
+
+// u64 acc = dsp_get_long_acc(areg);
+// acc &= 0x000000FFFFFFFFFFULL; // Lop off the extraneous sign extension our 64-bit fake accum causes
+// acc >>= 16;
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(areg, (s64)acc);
+// Update_SR_Register64(dsp_get_long_acc(areg));
+//}
+
+// ASR16 $acR
+// 1001 r001 xxxx xxxx
+// Arithmetically shifts right accumulator $acR by 16.
+//
+// flags out: --xx xx00
+//void DSPEmitter::asr16(const UDSPInstruction opc)
+//{
+// u8 areg = (opc >> 11) & 0x1;
+
+// s64 acc = dsp_get_long_acc(areg);
+// acc >>= 16;
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(areg, acc);
+// Update_SR_Register64(dsp_get_long_acc(areg));
+//}
+
+// LSL $acR, #I
+// 0001 010r 00ii iiii
+// Logically shifts left accumulator $acR by number specified by value I.
+//
+// flags out: --xx xx00
+void DSPEmitter::lsl(const UDSPInstruction opc)
+{
+#ifdef _M_X64
+ u8 rreg = (opc >> 8) & 0x01;
+ u16 shift = opc & 0x3f;
+// u64 acc = dsp_get_long_acc(rreg);
+ get_long_acc(rreg);
+
+// acc <<= shift;
+ SHL(64, R(RAX), Imm8(shift));
+
+// dsp_set_long_acc(rreg, acc);
+ set_long_acc(rreg);
+// Update_SR_Register64(dsp_get_long_acc(rreg));
+ Update_SR_Register64();
+#else
+ Default(opc);
+#endif
+}
+
+// LSR $acR, #I
+// 0001 010r 01ii iiii
+// Logically shifts right accumulator $acR by number specified by value
+// calculated by negating sign extended bits 0-6.
+//
+// flags out: --xx xx00
+//void DSPEmitter::lsr(const UDSPInstruction opc)
+//{
+// u8 rreg = (opc >> 8) & 0x01;
+// u16 shift;
+// u64 acc = dsp_get_long_acc(rreg);
+// acc &= 0x000000FFFFFFFFFFULL; // Lop off the extraneous sign extension our 64-bit fake accum causes
+
+// if ((opc & 0x3f) == 0)
+// shift = 0;
+// else
+// shift = 0x40 - (opc & 0x3f);
+
+// acc >>= shift;
+//
+// dsp_set_long_acc(rreg, (s64)acc);
+// Update_SR_Register64(dsp_get_long_acc(rreg));
+//}
+
+// ASL $acR, #I
+// 0001 010r 10ii iiii
+// Logically shifts left accumulator $acR by number specified by value I.
+//
+// flags out: --xx xx00
+//void DSPEmitter::asl(const UDSPInstruction opc)
+//{
+// u8 rreg = (opc >> 8) & 0x01;
+// u16 shift = opc & 0x3f;
+// u64 acc = dsp_get_long_acc(rreg);
+
+// acc <<= shift;
+//
+// dsp_set_long_acc(rreg, acc);
+// Update_SR_Register64(dsp_get_long_acc(rreg));
+//}
+
+// ASR $acR, #I
+// 0001 010r 11ii iiii
+// Arithmetically shifts right accumulator $acR by number specified by
+// value calculated by negating sign extended bits 0-6.
+//
+// flags out: --xx xx00
+//void DSPEmitter::asr(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x01;
+// u16 shift;
+
+// if ((opc & 0x3f) == 0)
+// shift = 0;
+// else
+// shift = 0x40 - (opc & 0x3f);
+
+// // arithmetic shift
+// s64 acc = dsp_get_long_acc(dreg);
+// acc >>= shift;
+
+// dsp_set_long_acc(dreg, acc);
+// Update_SR_Register64(dsp_get_long_acc(dreg));
+//}
+
+// LSRN (fixed parameters)
+// 0000 0010 1100 1010
+// Logically shifts right accumulator $ACC0 by lower 7-bit (signed) value in $AC1.M
+// (if value negative, becomes left shift).
+//
+// flags out: --xx xx00
+//void DSPEmitter::lsrn(const UDSPInstruction opc)
+//{
+// s16 shift;
+// u16 accm = (u16)dsp_get_acc_m(1);
+// u64 acc = dsp_get_long_acc(0);
+// acc &= 0x000000FFFFFFFFFFULL;
+
+// if ((accm & 0x3f) == 0)
+// shift = 0;
+// else if (accm & 0x40)
+// shift = -0x40 + (accm & 0x3f);
+// else
+// shift = accm & 0x3f;
+
+// if (shift > 0) {
+// acc >>= shift;
+// } else if (shift < 0) {
+// acc <<= -shift;
+// }
+
+// dsp_set_long_acc(0, (s64)acc);
+// Update_SR_Register64(dsp_get_long_acc(0));
+//}
+
+// ASRN (fixed parameters)
+// 0000 0010 1100 1011
+// Arithmetically shifts right accumulator $ACC0 by lower 7-bit (signed) value in $AC1.M
+// (if value negative, becomes left shift).
+//
+// flags out: --xx xx00
+//void DSPEmitter::asrn(const UDSPInstruction opc)
+//{
+// s16 shift;
+// u16 accm = (u16)dsp_get_acc_m(1);
+// s64 acc = dsp_get_long_acc(0);
+
+// if ((accm & 0x3f) == 0)
+// shift = 0;
+// else if (accm & 0x40)
+// shift = -0x40 + (accm & 0x3f);
+// else
+// shift = accm & 0x3f;
+
+// if (shift > 0) {
+// acc >>= shift;
+// } else if (shift < 0) {
+// acc <<= -shift;
+// }
+
+// dsp_set_long_acc(0, acc);
+// Update_SR_Register64(dsp_get_long_acc(0));
+//}
+
+// LSRNRX $acD, $axS.h
+// 0011 01sd 1xxx xxxx
+// Logically shifts left/right accumulator $ACC[D] by lower 7-bit (signed) value in $AX[S].H
+// x = extension (7 bits!!)
+//
+// flags out: --xx xx00
+//void DSPEmitter::lsrnrx(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+// u8 sreg = (opc >> 9) & 0x1;
+
+// s16 shift;
+// u16 axh = g_dsp.r[DSP_REG_AXH0 + sreg];
+// u64 acc = dsp_get_long_acc(dreg);
+// acc &= 0x000000FFFFFFFFFFULL;
+
+// if ((axh & 0x3f) == 0)
+// shift = 0;
+// else if (axh & 0x40)
+// shift = -0x40 + (axh & 0x3f);
+// else
+// shift = axh & 0x3f;
+
+// if (shift > 0) {
+// acc <<= shift;
+// } else if (shift < 0) {
+// acc >>= -shift;
+// }
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, (s64)acc);
+// Update_SR_Register64(dsp_get_long_acc(dreg));
+//}
+
+// ASRNRX $acD, $axS.h
+// 0011 10sd 1xxx xxxx
+// Arithmetically shifts left/right accumulator $ACC[D] by lower 7-bit (signed) value in $AX[S].H
+// x = extension (7 bits!!)
+//
+// flags out: --xx xx00
+//void DSPEmitter::asrnrx(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+// u8 sreg = (opc >> 9) & 0x1;
+
+// s16 shift;
+// u16 axh = g_dsp.r[DSP_REG_AXH0 + sreg];
+// s64 acc = dsp_get_long_acc(dreg);
+
+// if ((axh & 0x3f) == 0)
+// shift = 0;
+// else if (axh & 0x40)
+// shift = -0x40 + (axh & 0x3f);
+// else
+// shift = axh & 0x3f;
+
+// if (shift > 0) {
+// acc <<= shift;
+// } else if (shift < 0) {
+// acc >>= -shift;
+// }
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, acc);
+// Update_SR_Register64(dsp_get_long_acc(dreg));
+//}
+
+// LSRNR $acD
+// 0011 110d 1xxx xxxx
+// Logically shifts left/right accumulator $ACC[D] by lower 7-bit (signed) value in $AC[1-D].M
+// x = extension (7 bits!!)
+//
+// flags out: --xx xx00
+//void DSPEmitter::lsrnr(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+
+// s16 shift;
+// u16 accm = (u16)dsp_get_acc_m(1 - dreg);
+// u64 acc = dsp_get_long_acc(dreg);
+// acc &= 0x000000FFFFFFFFFFULL;
+
+// if ((accm & 0x3f) == 0)
+// shift = 0;
+// else if (accm & 0x40)
+// shift = -0x40 + (accm & 0x3f);
+// else
+// shift = accm & 0x3f;
+
+// if (shift > 0)
+// acc <<= shift;
+// else if (shift < 0)
+// acc >>= -shift;
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, (s64)acc);
+// Update_SR_Register64(dsp_get_long_acc(dreg));
+//}
+
+// ASRNR $acD
+// 0011 111d 1xxx xxxx
+// Arithmeticaly shift left/right accumulator $ACC[D] by lower 7-bit (signed) value in $AC[1-D].M
+// x = extension (7 bits!!)
+//
+// flags out: --xx xx00
+//void DSPEmitter::asrnr(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 8) & 0x1;
+
+// s16 shift;
+// u16 accm = (u16)dsp_get_acc_m(1 - dreg);
+// s64 acc = dsp_get_long_acc(dreg);
+
+// if ((accm & 0x3f) == 0)
+// shift = 0;
+// else if (accm & 0x40)
+// shift = -0x40 + (accm & 0x3f);
+// else
+// shift = accm & 0x3f;
+
+// if (shift > 0)
+// acc <<= shift;
+// else if (shift < 0)
+// acc >>= -shift;
+
+// zeroWriteBackLog();
+
+// dsp_set_long_acc(dreg, acc);
+// Update_SR_Register64(dsp_get_long_acc(dreg));
+//}
+
+
+//} // namespace
+
+//
diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp
index 04769bfef3..77afef2566 100644
--- a/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp
+++ b/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp
@@ -1,286 +1,286 @@
-// Copyright (C) 2010 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-#include "../DSPMemoryMap.h"
-#include "../DSPEmitter.h"
-#include "../DSPStacks.h"
-#include "x64Emitter.h"
-#include "ABI.h"
-
-using namespace Gen;
-
-const int GetCodeSize(void(*jitCode)(const UDSPInstruction, DSPEmitter&), const UDSPInstruction opc, DSPEmitter &emitter)
-{
- u16 pc = g_dsp.pc;
- const u8* ptr = emitter.GetCodePtr();
- jitCode(opc, emitter);
- //emitter.JMP(emitter.GetCodePtr());
- int size = (int)(emitter.GetCodePtr() - ptr);
- emitter.SetCodePtr((u8*)ptr);
- g_dsp.pc = pc;
- return size;
-}
-
-const u8* CheckCondition(DSPEmitter& emitter, u8 cond, u8 skipCodeSize)
-{
- if (cond == 0xf) // Always true.
- return NULL;
- //emitter.INT3();
- FixupBranch skipCode2;
-#ifdef _M_IX86 // All32
- emitter.MOV(16, R(EAX), M(&g_dsp.r[DSP_REG_SR]));
-#else
- emitter.MOV(64, R(RAX), ImmPtr(&g_dsp.r[DSP_REG_SR]));
- emitter.MOV(16, R(EAX), MatR(RAX));
-#endif
- switch(cond)
- {
- case 0x0: // GE - Greater Equal
- case 0x1: // L - Less
- case 0x2: // G - Greater
- case 0x3: // LE - Less Equal
- emitter.MOV(16, R(EDX), R(EAX));
- emitter.SHR(16, R(EDX), Imm8(3)); //SR_SIGN flag
- emitter.NOT(16, R(EDX));
- emitter.SHR(16, R(EAX), Imm8(1)); //SR_OVERFLOW flag
- emitter.NOT(16, R(EAX));
- emitter.XOR(16, R(EAX), R(EDX));
- emitter.TEST(16, R(EAX), Imm16(1));
- if (cond < 0x2)
- break;
-
- //LE: problem in here, half the tests fail
- skipCode2 = emitter.J_CC(CC_NE);
- //skipCode2 = emitter.J_CC((CCFlags)(CC_NE - (cond & 1)));
-#ifdef _M_IX86 // All32
- emitter.MOV(16, R(EAX), M(&g_dsp.r[DSP_REG_SR]));
-#else
- emitter.MOV(64, R(RAX), ImmPtr(&g_dsp.r[DSP_REG_SR]));
- emitter.MOV(16, R(EAX), MatR(RAX));
-#endif
- emitter.TEST(16, R(EAX), Imm16(SR_ARITH_ZERO));
- break;
- case 0x4: // NZ - Not Zero
- case 0x5: // Z - Zero
- emitter.TEST(16, R(EAX), Imm16(SR_ARITH_ZERO));
- break;
- case 0x6: // NC - Not carry
- case 0x7: // C - Carry
- emitter.TEST(16, R(EAX), Imm16(SR_CARRY));
- break;
- case 0x8: // ? - Not over s32
- case 0x9: // ? - Over s32
- emitter.TEST(16, R(EAX), Imm16(SR_OVER_S32));
- break;
- case 0xa: // ?
- case 0xb: // ?
- {
- //full of fail, both
- emitter.TEST(16, R(EAX), Imm16(SR_OVER_S32 | SR_TOP2BITS));
- FixupBranch skipArithZero = emitter.J_CC(CC_E);
- emitter.TEST(16, R(EAX), Imm16(SR_ARITH_ZERO));
- FixupBranch setZero = emitter.J_CC(CC_NE);
-
- emitter.MOV(16, R(EAX), Imm16(1));
- FixupBranch toEnd = emitter.J();
-
- emitter.SetJumpTarget(skipArithZero);
- emitter.SetJumpTarget(setZero);
- emitter.XOR(16, R(EAX), R(EAX));
- emitter.SetJumpTarget(toEnd);
- emitter.SETcc(CC_E, R(EAX));
- emitter.TEST(8, R(EAX), R(EAX));
- break;
- //emitter.TEST(16, R(EAX), Imm16(SR_OVER_S32 | SR_TOP2BITS));
- //skipCode2 = emitter.J_CC((CCFlags)(CC_E + (cond & 1)));
- //emitter.TEST(16, R(EAX), Imm16(SR_ARITH_ZERO));
- //break;
- }
- case 0xc: // LNZ - Logic Not Zero
- case 0xd: // LZ - Logic Zero
- emitter.TEST(16, R(EAX), Imm16(SR_LOGIC_ZERO));
- break;
- case 0xe: // 0 - Overflow
- emitter.TEST(16, R(EAX), Imm16(SR_OVERFLOW));
- break;
- }
- FixupBranch skipCode = cond == 0xe ? emitter.J_CC(CC_E) : emitter.J_CC((CCFlags)(CC_NE - (cond & 1)));
- const u8* res = emitter.GetCodePtr();
- emitter.NOP(skipCodeSize);
- emitter.SetJumpTarget(skipCode);
- if ((cond | 1) == 0x3) // || (cond | 1) == 0xb)
- emitter.SetJumpTarget(skipCode2);
- return res;
-}
-
-template <void(*jitCode)(const UDSPInstruction, DSPEmitter&)>
-void ReJitConditional(const UDSPInstruction opc, DSPEmitter& emitter)
-{
- static const int codeSize = GetCodeSize(jitCode, opc, emitter);
- //emitter.INT3();
- const u8* codePtr = CheckCondition(emitter, opc & 0xf, codeSize);
- //const u8* afterSkip = emitter.GetCodePtr();
- if (codePtr != NULL)
- emitter.SetCodePtr((u8*)codePtr);
- jitCode(opc, emitter);
- //if (codePtr != NULL)
- //{
- // emitter.JMP(afterSkip + 4 + sizeof(void*));
- // emitter.SetCodePtr((u8*)afterSkip);
- // emitter.ADD(16, M(&g_dsp.pc), Imm8(1)); //4 bytes + pointer
- //}
-}
-
-void r_jcc(const UDSPInstruction opc, DSPEmitter& emitter)
-{
- u16 dest = dsp_imem_read(emitter.compilePC + 1);
-#ifdef _M_IX86 // All32
- emitter.MOV(16, M(&(g_dsp.pc)), Imm16(dest));
-
- // Jump directly to the called block if it has already been compiled.
- // TODO: Subtract cycles from cyclesLeft
- if (emitter.blockLinks[dest])
- {
- emitter.JMPptr(M(&emitter.blockLinks[dest]));
- }
-#else
- emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
- emitter.MOV(16, MatR(RAX), Imm16(dest));
-
- // Jump directly to the next block if it has already been compiled.
- // TODO: Subtract cycles from cyclesLeft
- if (emitter.blockLinks[dest])
- {
- emitter.MOV(64, R(RAX), ImmPtr((void *)(emitter.blockLinks[dest])));
- emitter.JMPptr(R(RAX));
- emitter.ClearCallFlag();
- }
-#endif
-}
-// Generic jmp implementation
-// Jcc addressA
-// 0000 0010 1001 cccc
-// aaaa aaaa aaaa aaaa
-// Jump to addressA if condition cc has been met. Set program counter to
-// address represented by value that follows this "jmp" instruction.
-void DSPEmitter::jcc(const UDSPInstruction opc)
-{
- // Disabled as jcc has issues in games
- Default(opc); return;
-#if 0
-#ifdef _M_IX86 // All32
- MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 1));
-#else
- MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
- MOV(16, MDisp(RAX,0), Imm16(compilePC + 1));
-#endif
- ReJitConditional<r_jcc>(opc, *this);
-#endif
-}
-
-void r_jmprcc(const UDSPInstruction opc, DSPEmitter& emitter)
-{
- u8 reg = (opc >> 5) & 0x7;
- //reg can only be DSP_REG_ARx and DSP_REG_IXx now,
- //no need to handle DSP_REG_STx.
-#ifdef _M_IX86 // All32
- emitter.MOV(16, R(EAX), M(&g_dsp.r[reg]));
- emitter.MOV(16, M(&g_dsp.pc), R(EAX));
-#else
- emitter.MOV(64, R(RSI), ImmPtr(&g_dsp.r[reg]));
- emitter.MOV(16, R(RSI), MatR(RSI));
- emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
- emitter.MOV(16, MatR(RAX), R(RSI));
-#endif
-}
-// Generic jmpr implementation
-// JMPcc $R
-// 0001 0111 rrr0 cccc
-// Jump to address; set program counter to a value from register $R.
-void DSPEmitter::jmprcc(const UDSPInstruction opc)
-{
- ReJitConditional<r_jmprcc>(opc, *this);
-}
-
-void r_call(const UDSPInstruction opc, DSPEmitter& emitter)
-{
- u16 dest = dsp_imem_read(emitter.compilePC + 1);
- emitter.ABI_CallFunctionCC16((void *)dsp_reg_store_stack, DSP_STACK_C, emitter.compilePC + 2);
-#ifdef _M_IX86 // All32
- emitter.MOV(16, M(&(g_dsp.pc)), Imm16(dest));
-
- // Jump directly to the called block if it has already been compiled.
- // TODO: Subtract cycles from cyclesLeft
- if (emitter.blockLinks[dest])
- {
- emitter.JMPptr(M(&emitter.blockLinks[dest]));
- }
-#else
- emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
- emitter.MOV(16, MDisp(RAX,0), Imm16(dest));
-
- // Jump directly to the called block if it has already been compiled.
- // TODO: Subtract cycles from cyclesLeft
- if (emitter.blockLinks[dest])
- {
- emitter.MOV(64, R(RAX), ImmPtr((void *)(emitter.blockLinks[dest])));
- emitter.JMPptr(R(RAX));
- emitter.ClearCallFlag();
- }
-#endif
-}
-// Generic call implementation
-// CALLcc addressA
-// 0000 0010 1011 cccc
-// aaaa aaaa aaaa aaaa
-// Call function if condition cc has been met. Push program counter of
-// instruction following "call" to $st0. Set program counter to address
-// represented by value that follows this "call" instruction.
-void DSPEmitter::call(const UDSPInstruction opc)
-{
-#ifdef _M_IX86 // All32
- MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 1));
-#else
- MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
- MOV(16, MDisp(RAX,0), Imm16(compilePC + 1));
-#endif
- ReJitConditional<r_call>(opc, *this);
-}
-
-void r_callr(const UDSPInstruction opc, DSPEmitter& emitter)
-{
- u8 reg = (opc >> 5) & 0x7;
- emitter.ABI_CallFunctionCC16((void *)dsp_reg_store_stack, DSP_STACK_C, emitter.compilePC + 1);
-#ifdef _M_IX86 // All32
- emitter.MOV(16, R(EAX), M(&g_dsp.r[reg]));
- emitter.MOV(16, M(&g_dsp.pc), R(EAX));
-#else
- emitter.MOV(64, R(RSI), ImmPtr(&g_dsp.r[reg]));
- emitter.MOV(16, R(RSI), MatR(RSI));
- emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
- emitter.MOV(16, MDisp(RAX,0), R(RSI));
-#endif
-}
-// Generic callr implementation
-// CALLRcc $R
-// 0001 0111 rrr1 cccc
-// Call function if condition cc has been met. Push program counter of
-// instruction following "call" to call stack $st0. Set program counter to
-// register $R.
-void DSPEmitter::callr(const UDSPInstruction opc)
-{
- ReJitConditional<r_callr>(opc, *this);
-}
+// Copyright (C) 2010 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+#include "../DSPMemoryMap.h"
+#include "../DSPEmitter.h"
+#include "../DSPStacks.h"
+#include "x64Emitter.h"
+#include "ABI.h"
+
+using namespace Gen;
+
+const int GetCodeSize(void(*jitCode)(const UDSPInstruction, DSPEmitter&), const UDSPInstruction opc, DSPEmitter &emitter)
+{
+ u16 pc = g_dsp.pc;
+ const u8* ptr = emitter.GetCodePtr();
+ jitCode(opc, emitter);
+ //emitter.JMP(emitter.GetCodePtr());
+ int size = (int)(emitter.GetCodePtr() - ptr);
+ emitter.SetCodePtr((u8*)ptr);
+ g_dsp.pc = pc;
+ return size;
+}
+
+const u8* CheckCondition(DSPEmitter& emitter, u8 cond, u8 skipCodeSize)
+{
+ if (cond == 0xf) // Always true.
+ return NULL;
+ //emitter.INT3();
+ FixupBranch skipCode2;
+#ifdef _M_IX86 // All32
+ emitter.MOV(16, R(EAX), M(&g_dsp.r[DSP_REG_SR]));
+#else
+ emitter.MOV(64, R(RAX), ImmPtr(&g_dsp.r[DSP_REG_SR]));
+ emitter.MOV(16, R(EAX), MatR(RAX));
+#endif
+ switch(cond)
+ {
+ case 0x0: // GE - Greater Equal
+ case 0x1: // L - Less
+ case 0x2: // G - Greater
+ case 0x3: // LE - Less Equal
+ emitter.MOV(16, R(EDX), R(EAX));
+ emitter.SHR(16, R(EDX), Imm8(3)); //SR_SIGN flag
+ emitter.NOT(16, R(EDX));
+ emitter.SHR(16, R(EAX), Imm8(1)); //SR_OVERFLOW flag
+ emitter.NOT(16, R(EAX));
+ emitter.XOR(16, R(EAX), R(EDX));
+ emitter.TEST(16, R(EAX), Imm16(1));
+ if (cond < 0x2)
+ break;
+
+ //LE: problem in here, half the tests fail
+ skipCode2 = emitter.J_CC(CC_NE);
+ //skipCode2 = emitter.J_CC((CCFlags)(CC_NE - (cond & 1)));
+#ifdef _M_IX86 // All32
+ emitter.MOV(16, R(EAX), M(&g_dsp.r[DSP_REG_SR]));
+#else
+ emitter.MOV(64, R(RAX), ImmPtr(&g_dsp.r[DSP_REG_SR]));
+ emitter.MOV(16, R(EAX), MatR(RAX));
+#endif
+ emitter.TEST(16, R(EAX), Imm16(SR_ARITH_ZERO));
+ break;
+ case 0x4: // NZ - Not Zero
+ case 0x5: // Z - Zero
+ emitter.TEST(16, R(EAX), Imm16(SR_ARITH_ZERO));
+ break;
+ case 0x6: // NC - Not carry
+ case 0x7: // C - Carry
+ emitter.TEST(16, R(EAX), Imm16(SR_CARRY));
+ break;
+ case 0x8: // ? - Not over s32
+ case 0x9: // ? - Over s32
+ emitter.TEST(16, R(EAX), Imm16(SR_OVER_S32));
+ break;
+ case 0xa: // ?
+ case 0xb: // ?
+ {
+ //full of fail, both
+ emitter.TEST(16, R(EAX), Imm16(SR_OVER_S32 | SR_TOP2BITS));
+ FixupBranch skipArithZero = emitter.J_CC(CC_E);
+ emitter.TEST(16, R(EAX), Imm16(SR_ARITH_ZERO));
+ FixupBranch setZero = emitter.J_CC(CC_NE);
+
+ emitter.MOV(16, R(EAX), Imm16(1));
+ FixupBranch toEnd = emitter.J();
+
+ emitter.SetJumpTarget(skipArithZero);
+ emitter.SetJumpTarget(setZero);
+ emitter.XOR(16, R(EAX), R(EAX));
+ emitter.SetJumpTarget(toEnd);
+ emitter.SETcc(CC_E, R(EAX));
+ emitter.TEST(8, R(EAX), R(EAX));
+ break;
+ //emitter.TEST(16, R(EAX), Imm16(SR_OVER_S32 | SR_TOP2BITS));
+ //skipCode2 = emitter.J_CC((CCFlags)(CC_E + (cond & 1)));
+ //emitter.TEST(16, R(EAX), Imm16(SR_ARITH_ZERO));
+ //break;
+ }
+ case 0xc: // LNZ - Logic Not Zero
+ case 0xd: // LZ - Logic Zero
+ emitter.TEST(16, R(EAX), Imm16(SR_LOGIC_ZERO));
+ break;
+ case 0xe: // 0 - Overflow
+ emitter.TEST(16, R(EAX), Imm16(SR_OVERFLOW));
+ break;
+ }
+ FixupBranch skipCode = cond == 0xe ? emitter.J_CC(CC_E) : emitter.J_CC((CCFlags)(CC_NE - (cond & 1)));
+ const u8* res = emitter.GetCodePtr();
+ emitter.NOP(skipCodeSize);
+ emitter.SetJumpTarget(skipCode);
+ if ((cond | 1) == 0x3) // || (cond | 1) == 0xb)
+ emitter.SetJumpTarget(skipCode2);
+ return res;
+}
+
+template <void(*jitCode)(const UDSPInstruction, DSPEmitter&)>
+void ReJitConditional(const UDSPInstruction opc, DSPEmitter& emitter)
+{
+ static const int codeSize = GetCodeSize(jitCode, opc, emitter);
+ //emitter.INT3();
+ const u8* codePtr = CheckCondition(emitter, opc & 0xf, codeSize);
+ //const u8* afterSkip = emitter.GetCodePtr();
+ if (codePtr != NULL)
+ emitter.SetCodePtr((u8*)codePtr);
+ jitCode(opc, emitter);
+ //if (codePtr != NULL)
+ //{
+ // emitter.JMP(afterSkip + 4 + sizeof(void*));
+ // emitter.SetCodePtr((u8*)afterSkip);
+ // emitter.ADD(16, M(&g_dsp.pc), Imm8(1)); //4 bytes + pointer
+ //}
+}
+
+void r_jcc(const UDSPInstruction opc, DSPEmitter& emitter)
+{
+ u16 dest = dsp_imem_read(emitter.compilePC + 1);
+#ifdef _M_IX86 // All32
+ emitter.MOV(16, M(&(g_dsp.pc)), Imm16(dest));
+
+ // Jump directly to the called block if it has already been compiled.
+ // TODO: Subtract cycles from cyclesLeft
+ if (emitter.blockLinks[dest])
+ {
+ emitter.JMPptr(M(&emitter.blockLinks[dest]));
+ }
+#else
+ emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
+ emitter.MOV(16, MatR(RAX), Imm16(dest));
+
+ // Jump directly to the next block if it has already been compiled.
+ // TODO: Subtract cycles from cyclesLeft
+ if (emitter.blockLinks[dest])
+ {
+ emitter.MOV(64, R(RAX), ImmPtr((void *)(emitter.blockLinks[dest])));
+ emitter.JMPptr(R(RAX));
+ emitter.ClearCallFlag();
+ }
+#endif
+}
+// Generic jmp implementation
+// Jcc addressA
+// 0000 0010 1001 cccc
+// aaaa aaaa aaaa aaaa
+// Jump to addressA if condition cc has been met. Set program counter to
+// address represented by value that follows this "jmp" instruction.
+void DSPEmitter::jcc(const UDSPInstruction opc)
+{
+ // Disabled as jcc has issues in games
+ Default(opc); return;
+#if 0
+#ifdef _M_IX86 // All32
+ MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 1));
+#else
+ MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
+ MOV(16, MDisp(RAX,0), Imm16(compilePC + 1));
+#endif
+ ReJitConditional<r_jcc>(opc, *this);
+#endif
+}
+
+void r_jmprcc(const UDSPInstruction opc, DSPEmitter& emitter)
+{
+ u8 reg = (opc >> 5) & 0x7;
+ //reg can only be DSP_REG_ARx and DSP_REG_IXx now,
+ //no need to handle DSP_REG_STx.
+#ifdef _M_IX86 // All32
+ emitter.MOV(16, R(EAX), M(&g_dsp.r[reg]));
+ emitter.MOV(16, M(&g_dsp.pc), R(EAX));
+#else
+ emitter.MOV(64, R(RSI), ImmPtr(&g_dsp.r[reg]));
+ emitter.MOV(16, R(RSI), MatR(RSI));
+ emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
+ emitter.MOV(16, MatR(RAX), R(RSI));
+#endif
+}
+// Generic jmpr implementation
+// JMPcc $R
+// 0001 0111 rrr0 cccc
+// Jump to address; set program counter to a value from register $R.
+void DSPEmitter::jmprcc(const UDSPInstruction opc)
+{
+ ReJitConditional<r_jmprcc>(opc, *this);
+}
+
+void r_call(const UDSPInstruction opc, DSPEmitter& emitter)
+{
+ u16 dest = dsp_imem_read(emitter.compilePC + 1);
+ emitter.ABI_CallFunctionCC16((void *)dsp_reg_store_stack, DSP_STACK_C, emitter.compilePC + 2);
+#ifdef _M_IX86 // All32
+ emitter.MOV(16, M(&(g_dsp.pc)), Imm16(dest));
+
+ // Jump directly to the called block if it has already been compiled.
+ // TODO: Subtract cycles from cyclesLeft
+ if (emitter.blockLinks[dest])
+ {
+ emitter.JMPptr(M(&emitter.blockLinks[dest]));
+ }
+#else
+ emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
+ emitter.MOV(16, MDisp(RAX,0), Imm16(dest));
+
+ // Jump directly to the called block if it has already been compiled.
+ // TODO: Subtract cycles from cyclesLeft
+ if (emitter.blockLinks[dest])
+ {
+ emitter.MOV(64, R(RAX), ImmPtr((void *)(emitter.blockLinks[dest])));
+ emitter.JMPptr(R(RAX));
+ emitter.ClearCallFlag();
+ }
+#endif
+}
+// Generic call implementation
+// CALLcc addressA
+// 0000 0010 1011 cccc
+// aaaa aaaa aaaa aaaa
+// Call function if condition cc has been met. Push program counter of
+// instruction following "call" to $st0. Set program counter to address
+// represented by value that follows this "call" instruction.
+void DSPEmitter::call(const UDSPInstruction opc)
+{
+#ifdef _M_IX86 // All32
+ MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 1));
+#else
+ MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
+ MOV(16, MDisp(RAX,0), Imm16(compilePC + 1));
+#endif
+ ReJitConditional<r_call>(opc, *this);
+}
+
+void r_callr(const UDSPInstruction opc, DSPEmitter& emitter)
+{
+ u8 reg = (opc >> 5) & 0x7;
+ emitter.ABI_CallFunctionCC16((void *)dsp_reg_store_stack, DSP_STACK_C, emitter.compilePC + 1);
+#ifdef _M_IX86 // All32
+ emitter.MOV(16, R(EAX), M(&g_dsp.r[reg]));
+ emitter.MOV(16, M(&g_dsp.pc), R(EAX));
+#else
+ emitter.MOV(64, R(RSI), ImmPtr(&g_dsp.r[reg]));
+ emitter.MOV(16, R(RSI), MatR(RSI));
+ emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
+ emitter.MOV(16, MDisp(RAX,0), R(RSI));
+#endif
+}
+// Generic callr implementation
+// CALLRcc $R
+// 0001 0111 rrr1 cccc
+// Call function if condition cc has been met. Push program counter of
+// instruction following "call" to call stack $st0. Set program counter to
+// register $R.
+void DSPEmitter::callr(const UDSPInstruction opc)
+{
+ ReJitConditional<r_callr>(opc, *this);
+}
diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitLoadStore.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitLoadStore.cpp
index c98c5c067c..a488cd2a1d 100644
--- a/Source/Core/DSPCore/Src/Jit/DSPJitLoadStore.cpp
+++ b/Source/Core/DSPCore/Src/Jit/DSPJitLoadStore.cpp
@@ -1,367 +1,367 @@
-// Copyright (C) 2003 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-// Additional copyrights go to Duddie and Tratax (c) 2004
-
-#include "../DSPIntCCUtil.h"
-#include "../DSPIntUtil.h"
-#include "../DSPEmitter.h"
-#include "x64Emitter.h"
-#include "ABI.h"
-using namespace Gen;
-
-// SRS @M, $(0x18+S)
-// 0010 1sss mmmm mmmm
-// Move value from register $(0x18+D) to data memory pointed by address
-// CR[0-7] | M. That is, the upper 8 bits of the address are the
-// bottom 8 bits from CR, and the lower 8 bits are from the 8-bit immediate.
-// Note: pc+=2 in duddie's doc seems wrong
-void DSPEmitter::srs(const UDSPInstruction opc)
-{
- u8 reg = ((opc >> 8) & 0x7) + 0x18;
- //u16 addr = (g_dsp.r[DSP_REG_CR] << 8) | (opc & 0xFF);
-#ifdef _M_IX86 // All32
- MOVZX(32, 16, ECX, M(&g_dsp.r[reg]));
- MOVZX(32, 8, EAX, M(&g_dsp.r[DSP_REG_CR]));
-#else
- MOV(64, R(R11), ImmPtr(g_dsp.r));
- MOVZX(64, 16, RCX, MDisp(R11,reg*2));
- MOVZX(64, 8, RAX, MDisp(R11,DSP_REG_CR*2));
-#endif
- SHL(16, R(EAX), Imm8(8));
- OR(8, R(EAX), Imm8(opc & 0xFF));
- dmem_write();
-}
-
-// LRS $(0x18+D), @M
-// 0010 0ddd mmmm mmmm
-// Move value from data memory pointed by address CR[0-7] | M to register
-// $(0x18+D). That is, the upper 8 bits of the address are the bottom 8 bits
-// from CR, and the lower 8 bits are from the 8-bit immediate.
-void DSPEmitter::lrs(const UDSPInstruction opc)
-{
- u8 reg = ((opc >> 8) & 0x7) + 0x18;
- //u16 addr = (g_dsp.r[DSP_REG_CR] << 8) | (opc & 0xFF);
-#ifdef _M_IX86 // All32
- MOVZX(32, 8, ECX, M(&g_dsp.r[DSP_REG_CR]));
- SHL(16, R(ECX), Imm8(8));
- OR(8, R(ECX), Imm8(opc & 0xFF));
- dmem_read();
- MOV(16, M(&g_dsp.r[reg]), R(EAX));
-#else
- MOV(64, R(R11), ImmPtr(g_dsp.r));
- MOVZX(64, 8, RCX, MDisp(R11,DSP_REG_CR*2));
- SHL(16, R(ECX), Imm8(8));
- OR(8, R(ECX), Imm8(opc & 0xFF));
- dmem_read();
- MOV(64, R(R11), ImmPtr(g_dsp.r));
- MOV(16, MDisp(R11,reg*2), R(RAX));
-#endif
- dsp_conditional_extend_accum(reg);
-}
-
-// LR $D, @M
-// 0000 0000 110d dddd
-// mmmm mmmm mmmm mmmm
-// Move value from data memory pointed by address M to register $D.
-// FIXME: Perform additional operation depending on destination register.
-void DSPEmitter::lr(const UDSPInstruction opc)
-{
- int reg = opc & DSP_REG_MASK;
- u16 addr = dsp_imem_read(compilePC + 1);
- dmem_read_imm(addr);
- dsp_op_write_reg(reg, EAX);
- dsp_conditional_extend_accum(reg);
-}
-
-// SR @M, $S
-// 0000 0000 111s ssss
-// mmmm mmmm mmmm mmmm
-// Store value from register $S to a memory pointed by address M.
-// FIXME: Perform additional operation depending on destination register.
-void DSPEmitter::sr(const UDSPInstruction opc)
-{
- u8 reg = opc & DSP_REG_MASK;
- u16 addr = dsp_imem_read(compilePC + 1);
- dsp_op_read_reg(reg, ECX);
- dmem_write_imm(addr);
-}
-
-// SI @M, #I
-// 0001 0110 mmmm mmmm
-// iiii iiii iiii iiii
-// Store 16-bit immediate value I to a memory location pointed by address
-// M (M is 8-bit value sign extended).
-void DSPEmitter::si(const UDSPInstruction opc)
-{
- u16 addr = (s8)opc;
- u16 imm = dsp_imem_read(compilePC + 1);
- MOV(32, R(ECX), Imm32((u32)imm));
- dmem_write_imm(addr);
-}
-
-// LRR $D, @$S
-// 0001 1000 0ssd dddd
-// Move value from data memory pointed by addressing register $S to register $D.
-// FIXME: Perform additional operation depending on destination register.
-void DSPEmitter::lrr(const UDSPInstruction opc)
-{
- u8 sreg = (opc >> 5) & 0x3;
- u8 dreg = opc & 0x1f;
-
- dsp_op_read_reg(sreg, ECX);
-#ifdef _M_IX86 // All32
- MOVZX(32, 16, ECX, R(ECX));
-#else
- MOVZX(64, 16, ECX, R(ECX));
-#endif
- dmem_read();
- dsp_op_write_reg(dreg, EAX);
- dsp_conditional_extend_accum(dreg);
-}
-
-// LRRD $D, @$S
-// 0001 1000 1ssd dddd
-// Move value from data memory pointed by addressing register $S toregister $D.
-// Decrement register $S.
-// FIXME: Perform additional operation depending on destination register.
-void DSPEmitter::lrrd(const UDSPInstruction opc)
-{
- u8 sreg = (opc >> 5) & 0x3;
- u8 dreg = opc & 0x1f;
-
- dsp_op_read_reg(sreg, ECX);
-#ifdef _M_IX86 // All32
- MOVZX(32, 16, ECX, R(ECX));
-#else
- MOVZX(64, 16, ECX, R(ECX));
-#endif
- dmem_read();
- dsp_op_write_reg(dreg, EAX);
- dsp_conditional_extend_accum(dreg);
- decrement_addr_reg(sreg);
-}
-
-// LRRI $D, @$S
-// 0001 1001 0ssd dddd
-// Move value from data memory pointed by addressing register $S to register $D.
-// Increment register $S.
-// FIXME: Perform additional operation depending on destination register.
-void DSPEmitter::lrri(const UDSPInstruction opc)
-{
- u8 sreg = (opc >> 5) & 0x3;
- u8 dreg = opc & 0x1f;
-
- dsp_op_read_reg(sreg, ECX);
-#ifdef _M_IX86 // All32
- MOVZX(32, 16, ECX, R(ECX));
-#else
- MOVZX(64, 16, ECX, R(ECX));
-#endif
- dmem_read();
- dsp_op_write_reg(dreg, EAX);
- dsp_conditional_extend_accum(dreg);
- increment_addr_reg(sreg);
-}
-
-// LRRN $D, @$S
-// 0001 1001 1ssd dddd
-// Move value from data memory pointed by addressing register $S to register $D.
-// Add indexing register $(0x4+S) to register $S.
-// FIXME: Perform additional operation depending on destination register.
-//void DSPEmitter::lrrn(const UDSPInstruction opc)
-//{
-// u8 sreg = (opc >> 5) & 0x3;
-// u8 dreg = opc & 0x1f;
-
-// u16 val = dsp_dmem_read(dsp_op_read_reg(sreg));
-// dsp_op_write_reg(dreg, val);
-// dsp_conditional_extend_accum(dreg);
-// g_dsp.r[sreg] = dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
-//}
-
-// SRR @$D, $S
-// 0001 1010 0dds ssss
-// Store value from source register $S to a memory location pointed by
-// addressing register $D.
-// FIXME: Perform additional operation depending on source register.
-void DSPEmitter::srr(const UDSPInstruction opc)
-{
- u8 dreg = (opc >> 5) & 0x3;
- u8 sreg = opc & 0x1f;
-
- dsp_op_read_reg(sreg, ECX);
-#ifdef _M_IX86 // All32
- MOVZX(32, 16, EAX, M(&g_dsp.r[dreg]));
-#else
- MOV(64, R(R11), ImmPtr(g_dsp.r));
- MOVZX(64, 16, RAX, MDisp(R11,dreg*2));
-#endif
- dmem_write();
-}
-
-// SRRD @$D, $S
-// 0001 1010 1dds ssss
-// Store value from source register $S to a memory location pointed by
-// addressing register $D. Decrement register $D.
-// FIXME: Perform additional operation depending on source register.
-void DSPEmitter::srrd(const UDSPInstruction opc)
-{
- u8 dreg = (opc >> 5) & 0x3;
- u8 sreg = opc & 0x1f;
-
- dsp_op_read_reg(sreg, ECX);
-#ifdef _M_IX86 // All32
- MOVZX(32, 16, EAX, M(&g_dsp.r[dreg]));
-#else
- MOV(64, R(R11), ImmPtr(g_dsp.r));
- MOVZX(64, 16, RAX, MDisp(R11,dreg*2));
-#endif
- dmem_write();
- decrement_addr_reg(dreg);
-}
-
-// SRRI @$D, $S
-// 0001 1011 0dds ssss
-// Store value from source register $S to a memory location pointed by
-// addressing register $D. Increment register $D.
-// FIXME: Perform additional operation depending on source register.
-void DSPEmitter::srri(const UDSPInstruction opc)
-{
- u8 dreg = (opc >> 5) & 0x3;
- u8 sreg = opc & 0x1f;
-
- dsp_op_read_reg(sreg, ECX);
-#ifdef _M_IX86 // All32
- MOVZX(32, 16, EAX, M(&g_dsp.r[dreg]));
-#else
- MOV(64, R(R11), ImmPtr(g_dsp.r));
- MOVZX(64, 16, RAX, MDisp(R11,dreg*2));
-#endif
- dmem_write();
- increment_addr_reg(dreg);
-}
-
-// SRRN @$D, $S
-// 0001 1011 1dds ssss
-// Store value from source register $S to a memory location pointed by
-// addressing register $D. Add DSP_REG_IX0 register to register $D.
-// FIXME: Perform additional operation depending on source register.
-//void DSPEmitter::srrn(const UDSPInstruction opc)
-//{
-// u8 dreg = (opc >> 5) & 0x3;
-// u8 sreg = opc & 0x1f;
-
-// u16 val = dsp_op_read_reg(sreg);
-// dsp_dmem_write(g_dsp.r[dreg], val);
-// g_dsp.r[dreg] = dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]);
-//}
-
-// ILRR $acD.m, @$arS
-// 0000 001d 0001 00ss
-// Move value from instruction memory pointed by addressing register
-// $arS to mid accumulator register $acD.m.
-void DSPEmitter::ilrr(const UDSPInstruction opc)
-{
- u16 reg = opc & 0x3;
- u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
-
-#ifdef _M_IX86 // All32
- MOVZX(32, 16, ECX, M(&g_dsp.r[reg]));
-#else
- MOV(64, R(R11), ImmPtr(g_dsp.r));
- MOVZX(64, 16, RCX, MDisp(R11,reg*2));
-#endif
- imem_read();
-#ifdef _M_IX86 // All32
- MOV(16, M(&g_dsp.r[dreg]), R(EAX));
-#else
- MOV(64, R(R11), ImmPtr(g_dsp.r));
- MOV(16, MDisp(R11,dreg*2), R(RAX));
-#endif
- dsp_conditional_extend_accum(dreg);
-}
-
-// ILRRD $acD.m, @$arS
-// 0000 001d 0001 01ss
-// Move value from instruction memory pointed by addressing register
-// $arS to mid accumulator register $acD.m. Decrement addressing register $arS.
-void DSPEmitter::ilrrd(const UDSPInstruction opc)
-{
- u16 reg = opc & 0x3;
- u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
-
-#ifdef _M_IX86 // All32
- MOVZX(32, 16, ECX, M(&g_dsp.r[reg]));
-#else
- MOV(64, R(R11), ImmPtr(g_dsp.r));
- MOVZX(64, 16, RCX, MDisp(R11,reg*2));
-#endif
- imem_read();
-#ifdef _M_IX86 // All32
- MOV(16, M(&g_dsp.r[dreg]), R(EAX));
-#else
- MOV(64, R(R11), ImmPtr(g_dsp.r));
- MOV(16, MDisp(R11,dreg*2), R(RAX));
-#endif
- dsp_conditional_extend_accum(dreg);
- dsp_decrement_addr_reg(reg);
-}
-
-// ILRRI $acD.m, @$S
-// 0000 001d 0001 10ss
-// Move value from instruction memory pointed by addressing register
-// $arS to mid accumulator register $acD.m. Increment addressing register $arS.
-void DSPEmitter::ilrri(const UDSPInstruction opc)
-{
- u16 reg = opc & 0x3;
- u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
-
-#ifdef _M_IX86 // All32
- MOVZX(32, 16, ECX, M(&g_dsp.r[reg]));
-#else
- MOV(64, R(R11), ImmPtr(g_dsp.r));
- MOVZX(64, 16, RCX, MDisp(R11,reg*2));
-#endif
- imem_read();
-#ifdef _M_IX86 // All32
- MOV(16, M(&g_dsp.r[dreg]), R(EAX));
-#else
- MOV(64, R(R11), ImmPtr(g_dsp.r));
- MOV(16, MDisp(R11,dreg*2), R(RAX));
-#endif
- dsp_conditional_extend_accum(dreg);
- dsp_increment_addr_reg(reg);
-}
-
-// ILRRN $acD.m, @$arS
-// 0000 001d 0001 11ss
-// Move value from instruction memory pointed by addressing register
-// $arS to mid accumulator register $acD.m. Add corresponding indexing
-// register $ixS to addressing register $arS.
-//void DSPEmitter::ilrrn(const UDSPInstruction opc)
-//{
-// u16 reg = opc & 0x3;
-// u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
-
-// g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
-// dsp_conditional_extend_accum(dreg);
-// g_dsp.r[reg] = dsp_increase_addr_reg(reg, (s16)g_dsp.r[DSP_REG_IX0 + reg]);
-//}
-
-//} // namespace
-// \ No newline at end of file
+// Copyright (C) 2003 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Additional copyrights go to Duddie and Tratax (c) 2004
+
+#include "../DSPIntCCUtil.h"
+#include "../DSPIntUtil.h"
+#include "../DSPEmitter.h"
+#include "x64Emitter.h"
+#include "ABI.h"
+using namespace Gen;
+
+// SRS @M, $(0x18+S)
+// 0010 1sss mmmm mmmm
+// Move value from register $(0x18+D) to data memory pointed by address
+// CR[0-7] | M. That is, the upper 8 bits of the address are the
+// bottom 8 bits from CR, and the lower 8 bits are from the 8-bit immediate.
+// Note: pc+=2 in duddie's doc seems wrong
+void DSPEmitter::srs(const UDSPInstruction opc)
+{
+ u8 reg = ((opc >> 8) & 0x7) + 0x18;
+ //u16 addr = (g_dsp.r[DSP_REG_CR] << 8) | (opc & 0xFF);
+#ifdef _M_IX86 // All32
+ MOVZX(32, 16, ECX, M(&g_dsp.r[reg]));
+ MOVZX(32, 8, EAX, M(&g_dsp.r[DSP_REG_CR]));
+#else
+ MOV(64, R(R11), ImmPtr(g_dsp.r));
+ MOVZX(64, 16, RCX, MDisp(R11,reg*2));
+ MOVZX(64, 8, RAX, MDisp(R11,DSP_REG_CR*2));
+#endif
+ SHL(16, R(EAX), Imm8(8));
+ OR(8, R(EAX), Imm8(opc & 0xFF));
+ dmem_write();
+}
+
+// LRS $(0x18+D), @M
+// 0010 0ddd mmmm mmmm
+// Move value from data memory pointed by address CR[0-7] | M to register
+// $(0x18+D). That is, the upper 8 bits of the address are the bottom 8 bits
+// from CR, and the lower 8 bits are from the 8-bit immediate.
+void DSPEmitter::lrs(const UDSPInstruction opc)
+{
+ u8 reg = ((opc >> 8) & 0x7) + 0x18;
+ //u16 addr = (g_dsp.r[DSP_REG_CR] << 8) | (opc & 0xFF);
+#ifdef _M_IX86 // All32
+ MOVZX(32, 8, ECX, M(&g_dsp.r[DSP_REG_CR]));
+ SHL(16, R(ECX), Imm8(8));
+ OR(8, R(ECX), Imm8(opc & 0xFF));
+ dmem_read();
+ MOV(16, M(&g_dsp.r[reg]), R(EAX));
+#else
+ MOV(64, R(R11), ImmPtr(g_dsp.r));
+ MOVZX(64, 8, RCX, MDisp(R11,DSP_REG_CR*2));
+ SHL(16, R(ECX), Imm8(8));
+ OR(8, R(ECX), Imm8(opc & 0xFF));
+ dmem_read();
+ MOV(64, R(R11), ImmPtr(g_dsp.r));
+ MOV(16, MDisp(R11,reg*2), R(RAX));
+#endif
+ dsp_conditional_extend_accum(reg);
+}
+
+// LR $D, @M
+// 0000 0000 110d dddd
+// mmmm mmmm mmmm mmmm
+// Move value from data memory pointed by address M to register $D.
+// FIXME: Perform additional operation depending on destination register.
+void DSPEmitter::lr(const UDSPInstruction opc)
+{
+ int reg = opc & DSP_REG_MASK;
+ u16 address = dsp_imem_read(compilePC + 1);
+ dmem_read_imm(address);
+ dsp_op_write_reg(reg, EAX);
+ dsp_conditional_extend_accum(reg);
+}
+
+// SR @M, $S
+// 0000 0000 111s ssss
+// mmmm mmmm mmmm mmmm
+// Store value from register $S to a memory pointed by address M.
+// FIXME: Perform additional operation depending on destination register.
+void DSPEmitter::sr(const UDSPInstruction opc)
+{
+ u8 reg = opc & DSP_REG_MASK;
+ u16 address = dsp_imem_read(compilePC + 1);
+ dsp_op_read_reg(reg, ECX);
+ dmem_write_imm(address);
+}
+
+// SI @M, #I
+// 0001 0110 mmmm mmmm
+// iiii iiii iiii iiii
+// Store 16-bit immediate value I to a memory location pointed by address
+// M (M is 8-bit value sign extended).
+void DSPEmitter::si(const UDSPInstruction opc)
+{
+ u16 address = (s8)opc;
+ u16 imm = dsp_imem_read(compilePC + 1);
+ MOV(32, R(ECX), Imm32((u32)imm));
+ dmem_write_imm(address);
+}
+
+// LRR $D, @$S
+// 0001 1000 0ssd dddd
+// Move value from data memory pointed by addressing register $S to register $D.
+// FIXME: Perform additional operation depending on destination register.
+void DSPEmitter::lrr(const UDSPInstruction opc)
+{
+ u8 sreg = (opc >> 5) & 0x3;
+ u8 dreg = opc & 0x1f;
+
+ dsp_op_read_reg(sreg, ECX);
+#ifdef _M_IX86 // All32
+ MOVZX(32, 16, ECX, R(ECX));
+#else
+ MOVZX(64, 16, ECX, R(ECX));
+#endif
+ dmem_read();
+ dsp_op_write_reg(dreg, EAX);
+ dsp_conditional_extend_accum(dreg);
+}
+
+// LRRD $D, @$S
+// 0001 1000 1ssd dddd
+// Move value from data memory pointed by addressing register $S toregister $D.
+// Decrement register $S.
+// FIXME: Perform additional operation depending on destination register.
+void DSPEmitter::lrrd(const UDSPInstruction opc)
+{
+ u8 sreg = (opc >> 5) & 0x3;
+ u8 dreg = opc & 0x1f;
+
+ dsp_op_read_reg(sreg, ECX);
+#ifdef _M_IX86 // All32
+ MOVZX(32, 16, ECX, R(ECX));
+#else
+ MOVZX(64, 16, ECX, R(ECX));
+#endif
+ dmem_read();
+ dsp_op_write_reg(dreg, EAX);
+ dsp_conditional_extend_accum(dreg);
+ decrement_addr_reg(sreg);
+}
+
+// LRRI $D, @$S
+// 0001 1001 0ssd dddd
+// Move value from data memory pointed by addressing register $S to register $D.
+// Increment register $S.
+// FIXME: Perform additional operation depending on destination register.
+void DSPEmitter::lrri(const UDSPInstruction opc)
+{
+ u8 sreg = (opc >> 5) & 0x3;
+ u8 dreg = opc & 0x1f;
+
+ dsp_op_read_reg(sreg, ECX);
+#ifdef _M_IX86 // All32
+ MOVZX(32, 16, ECX, R(ECX));
+#else
+ MOVZX(64, 16, ECX, R(ECX));
+#endif
+ dmem_read();
+ dsp_op_write_reg(dreg, EAX);
+ dsp_conditional_extend_accum(dreg);
+ increment_addr_reg(sreg);
+}
+
+// LRRN $D, @$S
+// 0001 1001 1ssd dddd
+// Move value from data memory pointed by addressing register $S to register $D.
+// Add indexing register $(0x4+S) to register $S.
+// FIXME: Perform additional operation depending on destination register.
+//void DSPEmitter::lrrn(const UDSPInstruction opc)
+//{
+// u8 sreg = (opc >> 5) & 0x3;
+// u8 dreg = opc & 0x1f;
+
+// u16 val = dsp_dmem_read(dsp_op_read_reg(sreg));
+// dsp_op_write_reg(dreg, val);
+// dsp_conditional_extend_accum(dreg);
+// g_dsp.r[sreg] = dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
+//}
+
+// SRR @$D, $S
+// 0001 1010 0dds ssss
+// Store value from source register $S to a memory location pointed by
+// addressing register $D.
+// FIXME: Perform additional operation depending on source register.
+void DSPEmitter::srr(const UDSPInstruction opc)
+{
+ u8 dreg = (opc >> 5) & 0x3;
+ u8 sreg = opc & 0x1f;
+
+ dsp_op_read_reg(sreg, ECX);
+#ifdef _M_IX86 // All32
+ MOVZX(32, 16, EAX, M(&g_dsp.r[dreg]));
+#else
+ MOV(64, R(R11), ImmPtr(g_dsp.r));
+ MOVZX(64, 16, RAX, MDisp(R11,dreg*2));
+#endif
+ dmem_write();
+}
+
+// SRRD @$D, $S
+// 0001 1010 1dds ssss
+// Store value from source register $S to a memory location pointed by
+// addressing register $D. Decrement register $D.
+// FIXME: Perform additional operation depending on source register.
+void DSPEmitter::srrd(const UDSPInstruction opc)
+{
+ u8 dreg = (opc >> 5) & 0x3;
+ u8 sreg = opc & 0x1f;
+
+ dsp_op_read_reg(sreg, ECX);
+#ifdef _M_IX86 // All32
+ MOVZX(32, 16, EAX, M(&g_dsp.r[dreg]));
+#else
+ MOV(64, R(R11), ImmPtr(g_dsp.r));
+ MOVZX(64, 16, RAX, MDisp(R11,dreg*2));
+#endif
+ dmem_write();
+ decrement_addr_reg(dreg);
+}
+
+// SRRI @$D, $S
+// 0001 1011 0dds ssss
+// Store value from source register $S to a memory location pointed by
+// addressing register $D. Increment register $D.
+// FIXME: Perform additional operation depending on source register.
+void DSPEmitter::srri(const UDSPInstruction opc)
+{
+ u8 dreg = (opc >> 5) & 0x3;
+ u8 sreg = opc & 0x1f;
+
+ dsp_op_read_reg(sreg, ECX);
+#ifdef _M_IX86 // All32
+ MOVZX(32, 16, EAX, M(&g_dsp.r[dreg]));
+#else
+ MOV(64, R(R11), ImmPtr(g_dsp.r));
+ MOVZX(64, 16, RAX, MDisp(R11,dreg*2));
+#endif
+ dmem_write();
+ increment_addr_reg(dreg);
+}
+
+// SRRN @$D, $S
+// 0001 1011 1dds ssss
+// Store value from source register $S to a memory location pointed by
+// addressing register $D. Add DSP_REG_IX0 register to register $D.
+// FIXME: Perform additional operation depending on source register.
+//void DSPEmitter::srrn(const UDSPInstruction opc)
+//{
+// u8 dreg = (opc >> 5) & 0x3;
+// u8 sreg = opc & 0x1f;
+
+// u16 val = dsp_op_read_reg(sreg);
+// dsp_dmem_write(g_dsp.r[dreg], val);
+// g_dsp.r[dreg] = dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]);
+//}
+
+// ILRR $acD.m, @$arS
+// 0000 001d 0001 00ss
+// Move value from instruction memory pointed by addressing register
+// $arS to mid accumulator register $acD.m.
+void DSPEmitter::ilrr(const UDSPInstruction opc)
+{
+ u16 reg = opc & 0x3;
+ u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
+
+#ifdef _M_IX86 // All32
+ MOVZX(32, 16, ECX, M(&g_dsp.r[reg]));
+#else
+ MOV(64, R(R11), ImmPtr(g_dsp.r));
+ MOVZX(64, 16, RCX, MDisp(R11,reg*2));
+#endif
+ imem_read();
+#ifdef _M_IX86 // All32
+ MOV(16, M(&g_dsp.r[dreg]), R(EAX));
+#else
+ MOV(64, R(R11), ImmPtr(g_dsp.r));
+ MOV(16, MDisp(R11,dreg*2), R(RAX));
+#endif
+ dsp_conditional_extend_accum(dreg);
+}
+
+// ILRRD $acD.m, @$arS
+// 0000 001d 0001 01ss
+// Move value from instruction memory pointed by addressing register
+// $arS to mid accumulator register $acD.m. Decrement addressing register $arS.
+void DSPEmitter::ilrrd(const UDSPInstruction opc)
+{
+ u16 reg = opc & 0x3;
+ u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
+
+#ifdef _M_IX86 // All32
+ MOVZX(32, 16, ECX, M(&g_dsp.r[reg]));
+#else
+ MOV(64, R(R11), ImmPtr(g_dsp.r));
+ MOVZX(64, 16, RCX, MDisp(R11,reg*2));
+#endif
+ imem_read();
+#ifdef _M_IX86 // All32
+ MOV(16, M(&g_dsp.r[dreg]), R(EAX));
+#else
+ MOV(64, R(R11), ImmPtr(g_dsp.r));
+ MOV(16, MDisp(R11,dreg*2), R(RAX));
+#endif
+ dsp_conditional_extend_accum(dreg);
+ dsp_decrement_addr_reg(reg);
+}
+
+// ILRRI $acD.m, @$S
+// 0000 001d 0001 10ss
+// Move value from instruction memory pointed by addressing register
+// $arS to mid accumulator register $acD.m. Increment addressing register $arS.
+void DSPEmitter::ilrri(const UDSPInstruction opc)
+{
+ u16 reg = opc & 0x3;
+ u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
+
+#ifdef _M_IX86 // All32
+ MOVZX(32, 16, ECX, M(&g_dsp.r[reg]));
+#else
+ MOV(64, R(R11), ImmPtr(g_dsp.r));
+ MOVZX(64, 16, RCX, MDisp(R11,reg*2));
+#endif
+ imem_read();
+#ifdef _M_IX86 // All32
+ MOV(16, M(&g_dsp.r[dreg]), R(EAX));
+#else
+ MOV(64, R(R11), ImmPtr(g_dsp.r));
+ MOV(16, MDisp(R11,dreg*2), R(RAX));
+#endif
+ dsp_conditional_extend_accum(dreg);
+ dsp_increment_addr_reg(reg);
+}
+
+// ILRRN $acD.m, @$arS
+// 0000 001d 0001 11ss
+// Move value from instruction memory pointed by addressing register
+// $arS to mid accumulator register $acD.m. Add corresponding indexing
+// register $ixS to addressing register $arS.
+//void DSPEmitter::ilrrn(const UDSPInstruction opc)
+//{
+// u16 reg = opc & 0x3;
+// u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
+
+// g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
+// dsp_conditional_extend_accum(dreg);
+// g_dsp.r[reg] = dsp_increase_addr_reg(reg, (s16)g_dsp.r[DSP_REG_IX0 + reg]);
+//}
+
+//} // namespace
+//
diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp
index 3d0cb8d38f..08b3ea5062 100644
--- a/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp
+++ b/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp
@@ -333,26 +333,27 @@ void DSPEmitter::dmem_write()
}
// ECX - value
-void DSPEmitter::dmem_write_imm(u16 addr)
+void DSPEmitter::dmem_write_imm(u16 address)
{
- switch (addr >> 12)
+ switch (address >> 12)
{
case 0x0: // 0xxx DRAM
#ifdef _M_IX86 // All32
- MOV(16, M(&g_dsp.dram[addr & DSP_DRAM_MASK]), R(ECX));
+ MOV(16, M(&g_dsp.dram[address & DSP_DRAM_MASK]), R(ECX));
#else
MOV(64, R(RDX), ImmPtr(g_dsp.dram));
- MOV(16, MDisp(RDX,(addr & DSP_DRAM_MASK)*2), R(ECX));
+ MOV(16, MDisp(RDX,(address & DSP_DRAM_MASK)*2), R(ECX));
#endif
break;
case 0xf: // Fxxx HW regs
- MOV(16, R(EAX), Imm16(addr));
+ MOV(16, R(EAX), Imm16(address));
ABI_CallFunctionRR((void *)gdsp_ifx_write, EAX, ECX);
break;
default: // Unmapped/non-existing memory
- ERROR_LOG(DSPLLE, "%04x DSP ERROR: Write to UNKNOWN (%04x) memory", g_dsp.pc, addr);
+ ERROR_LOG(DSPLLE, "%04x DSP ERROR: Write to UNKNOWN (%04x) memory",
+ g_dsp.pc, address);
break;
}
}
@@ -431,34 +432,35 @@ void DSPEmitter::dmem_read()
SetJumpTarget(end2);
}
-void DSPEmitter::dmem_read_imm(u16 addr)
+void DSPEmitter::dmem_read_imm(u16 address)
{
- switch (addr >> 12)
+ switch (address >> 12)
{
case 0x0: // 0xxx DRAM
#ifdef _M_IX86 // All32
- MOV(16, R(EAX), M(&g_dsp.dram[addr & DSP_DRAM_MASK]));
+ MOV(16, R(EAX), M(&g_dsp.dram[address & DSP_DRAM_MASK]));
#else
MOV(64, R(RDX), ImmPtr(g_dsp.dram));
- MOV(16, R(EAX), MDisp(RDX,(addr & DSP_DRAM_MASK)*2));
+ MOV(16, R(EAX), MDisp(RDX,(address & DSP_DRAM_MASK)*2));
#endif
break;
case 0x1: // 1xxx COEF
#ifdef _M_IX86 // All32
- MOV(16, R(EAX), Imm16(g_dsp.coef[addr & DSP_COEF_MASK]));
+ MOV(16, R(EAX), Imm16(g_dsp.coef[address & DSP_COEF_MASK]));
#else
MOV(64, R(RDX), ImmPtr(g_dsp.coef));
- MOV(16, R(EAX), MDisp(RDX,(addr & DSP_COEF_MASK)*2));
+ MOV(16, R(EAX), MDisp(RDX,(address & DSP_COEF_MASK)*2));
#endif
break;
case 0xf: // Fxxx HW regs
- ABI_CallFunctionC16((void *)gdsp_ifx_read, addr);
+ ABI_CallFunctionC16((void *)gdsp_ifx_read, address);
break;
default: // Unmapped/non-existing memory
- ERROR_LOG(DSPLLE, "%04x DSP ERROR: Read from UNKNOWN (%04x) memory", g_dsp.pc, addr);
+ ERROR_LOG(DSPLLE, "%04x DSP ERROR: Read from UNKNOWN (%04x) memory",
+ g_dsp.pc, address);
}
}