2013-04-17 22:43:11 -04:00
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
2009-07-06 02:10:26 +00:00
// Additional copyrights go to Duddie (c) 2005 (duddie@walla.com)
2014-02-17 05:18:15 -05:00
# include "Common/Common.h"
2009-07-06 02:10:26 +00:00
2014-02-19 13:09:14 -05:00
# include "Core/DSP/DSPEmitter.h"
2014-02-17 05:18:15 -05:00
# include "Core/DSP/DSPInterpreter.h"
# include "Core/DSP/DSPIntExtOps.h"
# include "Core/DSP/DSPTables.h"
2009-07-06 02:10:26 +00:00
2010-03-24 05:05:25 +00:00
void nop ( const UDSPInstruction opc )
2009-07-06 02:10:26 +00:00
{
// The real nop is 0. Anything else is bad.
2013-04-16 23:14:36 -04:00
if ( opc )
{
2011-03-22 20:32:17 +00:00
ERROR_LOG ( DSPLLE , " LLE: Unrecognized opcode 0x%04x " , opc ) ;
}
2009-07-06 02:10:26 +00:00
}
2013-10-29 01:23:17 -04:00
2009-07-06 02:10:26 +00:00
const DSPOPCTemplate opcodes [ ] =
{
2014-02-16 18:29:53 +01:00
// # of parameters----+ {type, size, loc, lshift, mask} branch reads PC // instruction approximation
// name opcode mask interpreter function JIT function size-V V param 1 param 2 param 3 extendable uncond. updates SR
{ " NOP " , 0x0000 , 0xfffc , nop , & DSPEmitter : : nop , 1 , 0 , { } , false , false , false , false , false } , // no operation
{ " DAR " , 0x0004 , 0xfffc , DSPInterpreter : : dar , & DSPEmitter : : dar , 1 , 1 , { { P_REG , 1 , 0 , 0 , 0x0003 } } , false , false , false , false , false } , // $arD--
{ " IAR " , 0x0008 , 0xfffc , DSPInterpreter : : iar , & DSPEmitter : : iar , 1 , 1 , { { P_REG , 1 , 0 , 0 , 0x0003 } } , false , false , false , false , false } , // $arD++
{ " SUBARN " , 0x000c , 0xfffc , DSPInterpreter : : subarn , & DSPEmitter : : subarn , 1 , 1 , { { P_REG , 1 , 0 , 0 , 0x0003 } } , false , false , false , false , false } , // $arD -= $ixS
{ " ADDARN " , 0x0010 , 0xfff0 , DSPInterpreter : : addarn , & DSPEmitter : : addarn , 1 , 2 , { { P_REG , 1 , 0 , 0 , 0x0003 } , { P_REG04 , 1 , 0 , 2 , 0x000c } } , false , false , false , false , false } , // $arD += $ixS
{ " HALT " , 0x0021 , 0xffff , DSPInterpreter : : halt , & DSPEmitter : : halt , 1 , 0 , { } , false , true , true , false , false } , // halt until reset
{ " RETGE " , 0x02d0 , 0xffff , DSPInterpreter : : ret , & DSPEmitter : : ret , 1 , 0 , { } , false , true , false , true , false } , // return if greater or equal
{ " RETL " , 0x02d1 , 0xffff , DSPInterpreter : : ret , & DSPEmitter : : ret , 1 , 0 , { } , false , true , false , true , false } , // return if less
{ " RETG " , 0x02d2 , 0xffff , DSPInterpreter : : ret , & DSPEmitter : : ret , 1 , 0 , { } , false , true , false , true , false } , // return if greater
{ " RETLE " , 0x02d3 , 0xffff , DSPInterpreter : : ret , & DSPEmitter : : ret , 1 , 0 , { } , false , true , false , true , false } , // return if less or equal
{ " RETNZ " , 0x02d4 , 0xffff , DSPInterpreter : : ret , & DSPEmitter : : ret , 1 , 0 , { } , false , true , false , true , false } , // return if not zero
{ " RETZ " , 0x02d5 , 0xffff , DSPInterpreter : : ret , & DSPEmitter : : ret , 1 , 0 , { } , false , true , false , true , false } , // return if zero
{ " RETNC " , 0x02d6 , 0xffff , DSPInterpreter : : ret , & DSPEmitter : : ret , 1 , 0 , { } , false , true , false , true , false } , // return if not carry
{ " RETC " , 0x02d7 , 0xffff , DSPInterpreter : : ret , & DSPEmitter : : ret , 1 , 0 , { } , false , true , false , true , false } , // return if carry
{ " RETx8 " , 0x02d8 , 0xffff , DSPInterpreter : : ret , & DSPEmitter : : ret , 1 , 0 , { } , false , true , false , true , false } , // return if TODO
{ " RETx9 " , 0x02d9 , 0xffff , DSPInterpreter : : ret , & DSPEmitter : : ret , 1 , 0 , { } , false , true , false , true , false } , // return if TODO
{ " RETxA " , 0x02da , 0xffff , DSPInterpreter : : ret , & DSPEmitter : : ret , 1 , 0 , { } , false , true , false , true , false } , // return if TODO
{ " RETxB " , 0x02db , 0xffff , DSPInterpreter : : ret , & DSPEmitter : : ret , 1 , 0 , { } , false , true , false , true , false } , // return if TODO
{ " RETLNZ " , 0x02dc , 0xffff , DSPInterpreter : : ret , & DSPEmitter : : ret , 1 , 0 , { } , false , true , false , true , false } , // return if logic not zero
{ " RETLZ " , 0x02dd , 0xffff , DSPInterpreter : : ret , & DSPEmitter : : ret , 1 , 0 , { } , false , true , false , true , false } , // return if logic zero
{ " RETO " , 0x02de , 0xffff , DSPInterpreter : : ret , & DSPEmitter : : ret , 1 , 0 , { } , false , true , false , true , false } , // return if overflow
{ " RET " , 0x02df , 0xffff , DSPInterpreter : : ret , & DSPEmitter : : ret , 1 , 0 , { } , false , true , true , false , false } , // unconditional return
{ " RTI " , 0x02ff , 0xffff , DSPInterpreter : : rti , & DSPEmitter : : rti , 1 , 0 , { } , false , true , true , false , false } , // return from interrupt
{ " CALLGE " , 0x02b0 , 0xffff , DSPInterpreter : : call , & DSPEmitter : : call , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // call if greater or equal
{ " CALLL " , 0x02b1 , 0xffff , DSPInterpreter : : call , & DSPEmitter : : call , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // call if less
{ " CALLG " , 0x02b2 , 0xffff , DSPInterpreter : : call , & DSPEmitter : : call , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // call if greater
{ " CALLLE " , 0x02b3 , 0xffff , DSPInterpreter : : call , & DSPEmitter : : call , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // call if less or equal
{ " CALLNZ " , 0x02b4 , 0xffff , DSPInterpreter : : call , & DSPEmitter : : call , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // call if not zero
{ " CALLZ " , 0x02b5 , 0xffff , DSPInterpreter : : call , & DSPEmitter : : call , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // call if zero
{ " CALLNC " , 0x02b6 , 0xffff , DSPInterpreter : : call , & DSPEmitter : : call , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // call if not carry
{ " CALLC " , 0x02b7 , 0xffff , DSPInterpreter : : call , & DSPEmitter : : call , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // call if carry
{ " CALLx8 " , 0x02b8 , 0xffff , DSPInterpreter : : call , & DSPEmitter : : call , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // call if TODO
{ " CALLx9 " , 0x02b9 , 0xffff , DSPInterpreter : : call , & DSPEmitter : : call , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // call if TODO
{ " CALLxA " , 0x02ba , 0xffff , DSPInterpreter : : call , & DSPEmitter : : call , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // call if TODO
{ " CALLxB " , 0x02bb , 0xffff , DSPInterpreter : : call , & DSPEmitter : : call , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // call if TODO
{ " CALLLNZ " , 0x02bc , 0xffff , DSPInterpreter : : call , & DSPEmitter : : call , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // call if logic not zero
{ " CALLLZ " , 0x02bd , 0xffff , DSPInterpreter : : call , & DSPEmitter : : call , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // call if logic zero
{ " CALLO " , 0x02be , 0xffff , DSPInterpreter : : call , & DSPEmitter : : call , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // call if overflow
{ " CALL " , 0x02bf , 0xffff , DSPInterpreter : : call , & DSPEmitter : : call , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , true , true , false } , // unconditional call
{ " IFGE " , 0x0270 , 0xffff , DSPInterpreter : : ifcc , & DSPEmitter : : ifcc , 1 , 0 , { } , false , true , false , true , false } , // if greater or equal
{ " IFL " , 0x0271 , 0xffff , DSPInterpreter : : ifcc , & DSPEmitter : : ifcc , 1 , 0 , { } , false , true , false , true , false } , // if less
{ " IFG " , 0x0272 , 0xffff , DSPInterpreter : : ifcc , & DSPEmitter : : ifcc , 1 , 0 , { } , false , true , false , true , false } , // if greater
{ " IFLE " , 0x0273 , 0xffff , DSPInterpreter : : ifcc , & DSPEmitter : : ifcc , 1 , 0 , { } , false , true , false , true , false } , // if less or equal
{ " IFNZ " , 0x0274 , 0xffff , DSPInterpreter : : ifcc , & DSPEmitter : : ifcc , 1 , 0 , { } , false , true , false , true , false } , // if not zero
{ " IFZ " , 0x0275 , 0xffff , DSPInterpreter : : ifcc , & DSPEmitter : : ifcc , 1 , 0 , { } , false , true , false , true , false } , // if zero
{ " IFNC " , 0x0276 , 0xffff , DSPInterpreter : : ifcc , & DSPEmitter : : ifcc , 1 , 0 , { } , false , true , false , true , false } , // if not carry
{ " IFC " , 0x0277 , 0xffff , DSPInterpreter : : ifcc , & DSPEmitter : : ifcc , 1 , 0 , { } , false , true , false , true , false } , // if carry
{ " IFx8 " , 0x0278 , 0xffff , DSPInterpreter : : ifcc , & DSPEmitter : : ifcc , 1 , 0 , { } , false , true , false , true , false } , // if TODO
{ " IFx9 " , 0x0279 , 0xffff , DSPInterpreter : : ifcc , & DSPEmitter : : ifcc , 1 , 0 , { } , false , true , false , true , false } , // if TODO
{ " IFxA " , 0x027a , 0xffff , DSPInterpreter : : ifcc , & DSPEmitter : : ifcc , 1 , 0 , { } , false , true , false , true , false } , // if TODO
{ " IFxB " , 0x027b , 0xffff , DSPInterpreter : : ifcc , & DSPEmitter : : ifcc , 1 , 0 , { } , false , true , false , true , false } , // if TODO
{ " IFLNZ " , 0x027c , 0xffff , DSPInterpreter : : ifcc , & DSPEmitter : : ifcc , 1 , 0 , { } , false , true , false , true , false } , // if logic not zero
{ " IFLZ " , 0x027d , 0xffff , DSPInterpreter : : ifcc , & DSPEmitter : : ifcc , 1 , 0 , { } , false , true , false , true , false } , // if logic zero
{ " IFO " , 0x027e , 0xffff , DSPInterpreter : : ifcc , & DSPEmitter : : ifcc , 1 , 0 , { } , false , true , false , true , false } , // if overflow
{ " IF " , 0x027f , 0xffff , DSPInterpreter : : ifcc , & DSPEmitter : : ifcc , 1 , 0 , { } , false , true , true , true , false } , // what is this, I don't even...
{ " JGE " , 0x0290 , 0xffff , DSPInterpreter : : jcc , & DSPEmitter : : jcc , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // jump if greater or equal
{ " JL " , 0x0291 , 0xffff , DSPInterpreter : : jcc , & DSPEmitter : : jcc , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // jump if less
{ " JG " , 0x0292 , 0xffff , DSPInterpreter : : jcc , & DSPEmitter : : jcc , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // jump if greater
{ " JLE " , 0x0293 , 0xffff , DSPInterpreter : : jcc , & DSPEmitter : : jcc , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // jump if less or equal
{ " JNZ " , 0x0294 , 0xffff , DSPInterpreter : : jcc , & DSPEmitter : : jcc , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // jump if not zero
{ " JZ " , 0x0295 , 0xffff , DSPInterpreter : : jcc , & DSPEmitter : : jcc , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // jump if zero
{ " JNC " , 0x0296 , 0xffff , DSPInterpreter : : jcc , & DSPEmitter : : jcc , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // jump if not carry
{ " JC " , 0x0297 , 0xffff , DSPInterpreter : : jcc , & DSPEmitter : : jcc , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // jump if carry
{ " JMPx8 " , 0x0298 , 0xffff , DSPInterpreter : : jcc , & DSPEmitter : : jcc , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // jump if TODO
{ " JMPx9 " , 0x0299 , 0xffff , DSPInterpreter : : jcc , & DSPEmitter : : jcc , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // jump if TODO
{ " JMPxA " , 0x029a , 0xffff , DSPInterpreter : : jcc , & DSPEmitter : : jcc , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // jump if TODO
{ " JMPxB " , 0x029b , 0xffff , DSPInterpreter : : jcc , & DSPEmitter : : jcc , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // jump if TODO
{ " JLNZ " , 0x029c , 0xffff , DSPInterpreter : : jcc , & DSPEmitter : : jcc , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // jump if logic not zero
{ " JLZ " , 0x029d , 0xffff , DSPInterpreter : : jcc , & DSPEmitter : : jcc , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // jump if logic zero
{ " JO " , 0x029e , 0xffff , DSPInterpreter : : jcc , & DSPEmitter : : jcc , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , false , true , false } , // jump if overflow
{ " JMP " , 0x029f , 0xffff , DSPInterpreter : : jcc , & DSPEmitter : : jcc , 2 , 1 , { { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , true , true , false } , // unconditional jump
{ " JRGE " , 0x1700 , 0xff1f , DSPInterpreter : : jmprcc , & DSPEmitter : : jmprcc , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , false , false } , // jump to $R if greater or equal
{ " JRL " , 0x1701 , 0xff1f , DSPInterpreter : : jmprcc , & DSPEmitter : : jmprcc , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , false , false } , // jump to $R if less
{ " JRG " , 0x1702 , 0xff1f , DSPInterpreter : : jmprcc , & DSPEmitter : : jmprcc , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , false , false } , // jump to $R if greater
{ " JRLE " , 0x1703 , 0xff1f , DSPInterpreter : : jmprcc , & DSPEmitter : : jmprcc , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , false , false } , // jump to $R if less or equal
{ " JRNZ " , 0x1704 , 0xff1f , DSPInterpreter : : jmprcc , & DSPEmitter : : jmprcc , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , false , false } , // jump to $R if not zero
{ " JRZ " , 0x1705 , 0xff1f , DSPInterpreter : : jmprcc , & DSPEmitter : : jmprcc , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , false , false } , // jump to $R if zero
{ " JRNC " , 0x1706 , 0xff1f , DSPInterpreter : : jmprcc , & DSPEmitter : : jmprcc , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , false , false } , // jump to $R if not carry
{ " JRC " , 0x1707 , 0xff1f , DSPInterpreter : : jmprcc , & DSPEmitter : : jmprcc , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , false , false } , // jump to $R if carry
{ " JMPRx8 " , 0x1708 , 0xff1f , DSPInterpreter : : jmprcc , & DSPEmitter : : jmprcc , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , false , false } , // jump to $R if TODO
{ " JMPRx9 " , 0x1709 , 0xff1f , DSPInterpreter : : jmprcc , & DSPEmitter : : jmprcc , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , false , false } , // jump to $R if TODO
{ " JMPRxA " , 0x170a , 0xff1f , DSPInterpreter : : jmprcc , & DSPEmitter : : jmprcc , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , false , false } , // jump to $R if TODO
{ " JMPRxB " , 0x170b , 0xff1f , DSPInterpreter : : jmprcc , & DSPEmitter : : jmprcc , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , false , false } , // jump to $R if TODO
{ " JRLNZ " , 0x170c , 0xff1f , DSPInterpreter : : jmprcc , & DSPEmitter : : jmprcc , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , false , false } , // jump to $R if logic not zero
{ " JRLZ " , 0x170d , 0xff1f , DSPInterpreter : : jmprcc , & DSPEmitter : : jmprcc , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , false , false } , // jump to $R if logic zero
{ " JRO " , 0x170e , 0xff1f , DSPInterpreter : : jmprcc , & DSPEmitter : : jmprcc , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , false , false } , // jump to $R if overflow
{ " JMPR " , 0x170f , 0xff1f , DSPInterpreter : : jmprcc , & DSPEmitter : : jmprcc , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , true , false , false } , // jump to $R
{ " CALLRGE " , 0x1710 , 0xff1f , DSPInterpreter : : callr , & DSPEmitter : : callr , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , true , false } , // call $R if greater or equal
{ " CALLRL " , 0x1711 , 0xff1f , DSPInterpreter : : callr , & DSPEmitter : : callr , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , true , false } , // call $R if less
{ " CALLRG " , 0x1712 , 0xff1f , DSPInterpreter : : callr , & DSPEmitter : : callr , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , true , false } , // call $R if greater
{ " CALLRLE " , 0x1713 , 0xff1f , DSPInterpreter : : callr , & DSPEmitter : : callr , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , true , false } , // call $R if less or equal
{ " CALLRNZ " , 0x1714 , 0xff1f , DSPInterpreter : : callr , & DSPEmitter : : callr , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , true , false } , // call $R if not zero
{ " CALLRZ " , 0x1715 , 0xff1f , DSPInterpreter : : callr , & DSPEmitter : : callr , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , true , false } , // call $R if zero
{ " CALLRNC " , 0x1716 , 0xff1f , DSPInterpreter : : callr , & DSPEmitter : : callr , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , true , false } , // call $R if not carry
{ " CALLRC " , 0x1717 , 0xff1f , DSPInterpreter : : callr , & DSPEmitter : : callr , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , true , false } , // call $R if carry
{ " CALLRx8 " , 0x1718 , 0xff1f , DSPInterpreter : : callr , & DSPEmitter : : callr , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , true , false } , // call $R if TODO
{ " CALLRx9 " , 0x1719 , 0xff1f , DSPInterpreter : : callr , & DSPEmitter : : callr , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , true , false } , // call $R if TODO
{ " CALLRxA " , 0x171a , 0xff1f , DSPInterpreter : : callr , & DSPEmitter : : callr , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , true , false } , // call $R if TODO
{ " CALLRxB " , 0x171b , 0xff1f , DSPInterpreter : : callr , & DSPEmitter : : callr , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , true , false } , // call $R if TODO
{ " CALLRLNZ " , 0x171c , 0xff1f , DSPInterpreter : : callr , & DSPEmitter : : callr , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , true , false } , // call $R if logic not zero
{ " CALLRLZ " , 0x171d , 0xff1f , DSPInterpreter : : callr , & DSPEmitter : : callr , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , true , false } , // call $R if logic zero
{ " CALLRO " , 0x171e , 0xff1f , DSPInterpreter : : callr , & DSPEmitter : : callr , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , false , true , false } , // call $R if overflow
{ " CALLR " , 0x171f , 0xff1f , DSPInterpreter : : callr , & DSPEmitter : : callr , 1 , 1 , { { P_REG , 1 , 0 , 5 , 0x00e0 } } , false , true , true , true , false } , // call $R
{ " SBCLR " , 0x1200 , 0xff00 , DSPInterpreter : : sbclr , & DSPEmitter : : sbclr , 1 , 1 , { { P_IMM , 1 , 0 , 0 , 0x0007 } } , false , false , false , false , false } , // $sr &= ~(I + 6)
{ " SBSET " , 0x1300 , 0xff00 , DSPInterpreter : : sbset , & DSPEmitter : : sbset , 1 , 1 , { { P_IMM , 1 , 0 , 0 , 0x0007 } } , false , false , false , false , false } , // $sr |= (I + 6)
{ " LSL " , 0x1400 , 0xfec0 , DSPInterpreter : : lsl , & DSPEmitter : : lsl , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_IMM , 1 , 0 , 0 , 0x003f } } , false , false , false , false , true } , // $acR <<= I
{ " LSR " , 0x1440 , 0xfec0 , DSPInterpreter : : lsr , & DSPEmitter : : lsr , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_IMM , 1 , 0 , 0 , 0x003f } } , false , false , false , false , true } , // $acR >>= I (shifting in zeros)
{ " ASL " , 0x1480 , 0xfec0 , DSPInterpreter : : asl , & DSPEmitter : : asl , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_IMM , 1 , 0 , 0 , 0x003f } } , false , false , false , false , true } , // $acR <<= I
{ " ASR " , 0x14c0 , 0xfec0 , DSPInterpreter : : asr , & DSPEmitter : : asr , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_IMM , 1 , 0 , 0 , 0x003f } } , false , false , false , false , true } , // $acR >>= I (shifting in sign bits)
// these two were discovered by ector
{ " LSRN " , 0x02ca , 0xffff , DSPInterpreter : : lsrn , & DSPEmitter : : lsrn , 1 , 0 , { } , false , false , false , false , true } , // $ac0 >>=/<<= $ac1.m[0-6]
{ " ASRN " , 0x02cb , 0xffff , DSPInterpreter : : asrn , & DSPEmitter : : asrn , 1 , 0 , { } , false , false , false , false , true } , // $ac0 >>=/<<= $ac1.m[0-6] (arithmetic)
{ " LRI " , 0x0080 , 0xffe0 , DSPInterpreter : : lri , & DSPEmitter : : lri , 2 , 2 , { { P_REG , 1 , 0 , 0 , 0x001f } , { P_IMM , 2 , 1 , 0 , 0xffff } } , false , false , false , true , false } , // $D = I
{ " LR " , 0x00c0 , 0xffe0 , DSPInterpreter : : lr , & DSPEmitter : : lr , 2 , 2 , { { P_REG , 1 , 0 , 0 , 0x001f } , { P_MEM , 2 , 1 , 0 , 0xffff } } , false , false , false , true , false } , // $D = MEM[M]
{ " SR " , 0x00e0 , 0xffe0 , DSPInterpreter : : sr , & DSPEmitter : : sr , 2 , 2 , { { P_MEM , 2 , 1 , 0 , 0xffff } , { P_REG , 1 , 0 , 0 , 0x001f } } , false , false , false , true , false } , // MEM[M] = $S
{ " MRR " , 0x1c00 , 0xfc00 , DSPInterpreter : : mrr , & DSPEmitter : : mrr , 1 , 2 , { { P_REG , 1 , 0 , 5 , 0x03e0 } , { P_REG , 1 , 0 , 0 , 0x001f } } , false , false , false , false , false } , // $D = $S
{ " SI " , 0x1600 , 0xff00 , DSPInterpreter : : si , & DSPEmitter : : si , 2 , 2 , { { P_MEM , 1 , 0 , 0 , 0x00ff } , { P_IMM , 2 , 1 , 0 , 0xffff } } , false , false , false , true , false } , // MEM[M] = I
{ " ADDIS " , 0x0400 , 0xfe00 , DSPInterpreter : : addis , & DSPEmitter : : addis , 1 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_IMM , 1 , 0 , 0 , 0x00ff } } , false , false , false , false , true } , // $acD.hm += I
{ " CMPIS " , 0x0600 , 0xfe00 , DSPInterpreter : : cmpis , & DSPEmitter : : cmpis , 1 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_IMM , 1 , 0 , 0 , 0x00ff } } , false , false , false , false , true } , // FLAGS($acD - I)
{ " LRIS " , 0x0800 , 0xf800 , DSPInterpreter : : lris , & DSPEmitter : : lris , 1 , 2 , { { P_REG18 , 1 , 0 , 8 , 0x0700 } , { P_IMM , 1 , 0 , 0 , 0x00ff } } , false , false , false , false , true } , // $(D+24) = I
{ " ADDI " , 0x0200 , 0xfeff , DSPInterpreter : : addi , & DSPEmitter : : addi , 2 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_IMM , 2 , 1 , 0 , 0xffff } } , false , false , false , true , true } , // $acD.hm += I
{ " XORI " , 0x0220 , 0xfeff , DSPInterpreter : : xori , & DSPEmitter : : xori , 2 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_IMM , 2 , 1 , 0 , 0xffff } } , false , false , false , true , true } , // $acD.m ^= I
{ " ANDI " , 0x0240 , 0xfeff , DSPInterpreter : : andi , & DSPEmitter : : andi , 2 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_IMM , 2 , 1 , 0 , 0xffff } } , false , false , false , true , true } , // $acD.m &= I
{ " ORI " , 0x0260 , 0xfeff , DSPInterpreter : : ori , & DSPEmitter : : ori , 2 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_IMM , 2 , 1 , 0 , 0xffff } } , false , false , false , true , true } , // $acD.m |= I
{ " CMPI " , 0x0280 , 0xfeff , DSPInterpreter : : cmpi , & DSPEmitter : : cmpi , 2 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_IMM , 2 , 1 , 0 , 0xffff } } , false , false , false , true , true } , // FLAGS(($acD.hm - I) | $acD.l)
{ " ANDF " , 0x02a0 , 0xfeff , DSPInterpreter : : andf , & DSPEmitter : : andf , 2 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_IMM , 2 , 1 , 0 , 0xffff } } , false , false , false , true , true } , // $sr.LZ = ($acD.m & I) == 0 ? 1 : 0
{ " ANDCF " , 0x02c0 , 0xfeff , DSPInterpreter : : andcf , & DSPEmitter : : andcf , 2 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_IMM , 2 , 1 , 0 , 0xffff } } , false , false , false , true , true } , // $sr.LZ = ($acD.m & I) == I ? 1 : 0
{ " ILRR " , 0x0210 , 0xfefc , DSPInterpreter : : ilrr , & DSPEmitter : : ilrr , 1 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_PRG , 1 , 0 , 0 , 0x0003 } } , false , false , false , false , false } , // $acD.m = IMEM[$arS]
{ " ILRRD " , 0x0214 , 0xfefc , DSPInterpreter : : ilrrd , & DSPEmitter : : ilrrd , 1 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_PRG , 1 , 0 , 0 , 0x0003 } } , false , false , false , false , false } , // $acD.m = IMEM[$arS--]
{ " ILRRI " , 0x0218 , 0xfefc , DSPInterpreter : : ilrri , & DSPEmitter : : ilrri , 1 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_PRG , 1 , 0 , 0 , 0x0003 } } , false , false , false , false , false } , // $acD.m = IMEM[$arS++]
{ " ILRRN " , 0x021c , 0xfefc , DSPInterpreter : : ilrrn , & DSPEmitter : : ilrrn , 1 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_PRG , 1 , 0 , 0 , 0x0003 } } , false , false , false , false , false } , // $acD.m = IMEM[$arS]; $arS += $ixS
2009-07-06 02:10:26 +00:00
2010-03-24 05:05:25 +00:00
// LOOPS
2014-02-16 18:29:53 +01:00
{ " LOOP " , 0x0040 , 0xffe0 , DSPInterpreter : : loop , & DSPEmitter : : loop , 1 , 1 , { { P_REG , 1 , 0 , 0 , 0x001f } } , false , true , true , true , false } , // run next instruction $R times
{ " BLOOP " , 0x0060 , 0xffe0 , DSPInterpreter : : bloop , & DSPEmitter : : bloop , 2 , 2 , { { P_REG , 1 , 0 , 0 , 0x001f } , { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , true , true , false } , // COMEFROM addr $R times
{ " LOOPI " , 0x1000 , 0xff00 , DSPInterpreter : : loopi , & DSPEmitter : : loopi , 1 , 1 , { { P_IMM , 1 , 0 , 0 , 0x00ff } } , false , true , true , true , false } , // run next instruction I times
{ " BLOOPI " , 0x1100 , 0xff00 , DSPInterpreter : : bloopi , & DSPEmitter : : bloopi , 2 , 2 , { { P_IMM , 1 , 0 , 0 , 0x00ff } , { P_ADDR_I , 2 , 1 , 0 , 0xffff } } , false , true , true , true , false } , // COMEFROM addr I times
2009-07-06 02:10:26 +00:00
2010-03-24 05:05:25 +00:00
// load and store value pointed by indexing reg and increment; LRR/SRR variants
2014-02-16 18:29:53 +01:00
{ " LRR " , 0x1800 , 0xff80 , DSPInterpreter : : lrr , & DSPEmitter : : lrr , 1 , 2 , { { P_REG , 1 , 0 , 0 , 0x001f } , { P_PRG , 1 , 0 , 5 , 0x0060 } } , false , false , false , false , false } , // $D = MEM[$arS]
{ " LRRD " , 0x1880 , 0xff80 , DSPInterpreter : : lrrd , & DSPEmitter : : lrrd , 1 , 2 , { { P_REG , 1 , 0 , 0 , 0x001f } , { P_PRG , 1 , 0 , 5 , 0x0060 } } , false , false , false , false , false } , // $D = MEM[$arS--]
{ " LRRI " , 0x1900 , 0xff80 , DSPInterpreter : : lrri , & DSPEmitter : : lrri , 1 , 2 , { { P_REG , 1 , 0 , 0 , 0x001f } , { P_PRG , 1 , 0 , 5 , 0x0060 } } , false , false , false , false , false } , // $D = MEM[$arS++]
{ " LRRN " , 0x1980 , 0xff80 , DSPInterpreter : : lrrn , & DSPEmitter : : lrrn , 1 , 2 , { { P_REG , 1 , 0 , 0 , 0x001f } , { P_PRG , 1 , 0 , 5 , 0x0060 } } , false , false , false , false , false } , // $D = MEM[$arS]; $arS += $ixS
2009-07-06 02:10:26 +00:00
2014-02-16 18:29:53 +01:00
{ " SRR " , 0x1a00 , 0xff80 , DSPInterpreter : : srr , & DSPEmitter : : srr , 1 , 2 , { { P_PRG , 1 , 0 , 5 , 0x0060 } , { P_REG , 1 , 0 , 0 , 0x001f } } , false , false , false , false , false } , // MEM[$arD] = $S
{ " SRRD " , 0x1a80 , 0xff80 , DSPInterpreter : : srrd , & DSPEmitter : : srrd , 1 , 2 , { { P_PRG , 1 , 0 , 5 , 0x0060 } , { P_REG , 1 , 0 , 0 , 0x001f } } , false , false , false , false , false } , // MEM[$arD--] = $S
{ " SRRI " , 0x1b00 , 0xff80 , DSPInterpreter : : srri , & DSPEmitter : : srri , 1 , 2 , { { P_PRG , 1 , 0 , 5 , 0x0060 } , { P_REG , 1 , 0 , 0 , 0x001f } } , false , false , false , false , false } , // MEM[$arD++] = $S
{ " SRRN " , 0x1b80 , 0xff80 , DSPInterpreter : : srrn , & DSPEmitter : : srrn , 1 , 2 , { { P_PRG , 1 , 0 , 5 , 0x0060 } , { P_REG , 1 , 0 , 0 , 0x001f } } , false , false , false , false , false } , // MEM[$arD] = $S; $arD += $ixD
2009-07-06 02:10:26 +00:00
2009-11-14 17:45:35 +00:00
//2
2014-02-16 18:29:53 +01:00
{ " LRS " , 0x2000 , 0xf800 , DSPInterpreter : : lrs , & DSPEmitter : : lrs , 1 , 2 , { { P_REG18 , 1 , 0 , 8 , 0x0700 } , { P_MEM , 1 , 0 , 0 , 0x00ff } } , false , false , false , false , false } , // $(D+24) = MEM[($cr[0-7] << 8) | I]
{ " SRS " , 0x2800 , 0xf800 , DSPInterpreter : : srs , & DSPEmitter : : srs , 1 , 2 , { { P_MEM , 1 , 0 , 0 , 0x00ff } , { P_REG18 , 1 , 0 , 8 , 0x0700 } } , false , false , false , false , false } , // MEM[($cr[0-7] << 8) | I] = $(S+24)
2009-11-14 17:45:35 +00:00
2009-11-04 12:49:26 +00:00
// opcodes that can be extended
//3 - main opcode defined by 9 bits, extension defined by last 7 bits!!
2014-02-16 18:29:53 +01:00
{ " XORR " , 0x3000 , 0xfc80 , DSPInterpreter : : xorr , & DSPEmitter : : xorr , 1 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_REG1A , 1 , 0 , 9 , 0x0200 } } , true , false , false , false , true } , // $acD.m ^= $axS.h
{ " ANDR " , 0x3400 , 0xfc80 , DSPInterpreter : : andr , & DSPEmitter : : andr , 1 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_REG1A , 1 , 0 , 9 , 0x0200 } } , true , false , false , false , true } , // $acD.m &= $axS.h
{ " ORR " , 0x3800 , 0xfc80 , DSPInterpreter : : orr , & DSPEmitter : : orr , 1 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_REG1A , 1 , 0 , 9 , 0x0200 } } , true , false , false , false , true } , // $acD.m |= $axS.h
{ " ANDC " , 0x3c00 , 0xfe80 , DSPInterpreter : : andc , & DSPEmitter : : andc , 1 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_ACCM_D , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD.m &= $ac(1-D).m
{ " ORC " , 0x3e00 , 0xfe80 , DSPInterpreter : : orc , & DSPEmitter : : orc , 1 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_ACCM_D , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD.m |= $ac(1-D).m
{ " XORC " , 0x3080 , 0xfe80 , DSPInterpreter : : xorc , & DSPEmitter : : xorc , 1 , 2 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } , { P_ACCM_D , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD.m ^= $ac(1-D).m
{ " NOT " , 0x3280 , 0xfe80 , DSPInterpreter : : notc , & DSPEmitter : : notc , 1 , 1 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD.m = ~$acD.m
{ " LSRNRX " , 0x3480 , 0xfc80 , DSPInterpreter : : lsrnrx , & DSPEmitter : : lsrnrx , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_REG1A , 1 , 0 , 9 , 0x0200 } } , true , false , false , false , true } , // $acD >>=/<<= $axS.h[0-6]
{ " ASRNRX " , 0x3880 , 0xfc80 , DSPInterpreter : : asrnrx , & DSPEmitter : : asrnrx , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_REG1A , 1 , 0 , 9 , 0x0200 } } , true , false , false , false , true } , // $acD >>=/<<= $axS.h[0-6] (arithmetic)
{ " LSRNR " , 0x3c80 , 0xfe80 , DSPInterpreter : : lsrnr , & DSPEmitter : : lsrnr , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_ACCM_D , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD >>=/<<= $ac(1-D).m[0-6]
{ " ASRNR " , 0x3e80 , 0xfe80 , DSPInterpreter : : asrnr , & DSPEmitter : : asrnr , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_ACCM_D , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD >>=/<<= $ac(1-D).m[0-6] (arithmetic)
2009-11-04 12:49:26 +00:00
//4
2014-02-16 18:29:53 +01:00
{ " ADDR " , 0x4000 , 0xf800 , DSPInterpreter : : addr , & DSPEmitter : : addr , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_REG18 , 1 , 0 , 9 , 0x0600 } } , true , false , false , false , true } , // $acD += $(S+24)
{ " ADDAX " , 0x4800 , 0xfc00 , DSPInterpreter : : addax , & DSPEmitter : : addax , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_AX , 1 , 0 , 9 , 0x0200 } } , true , false , false , false , true } , // $acD += $axS
{ " ADD " , 0x4c00 , 0xfe00 , DSPInterpreter : : add , & DSPEmitter : : add , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_ACC_D , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD += $ac(1-D)
{ " ADDP " , 0x4e00 , 0xfe00 , DSPInterpreter : : addp , & DSPEmitter : : addp , 1 , 1 , { { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD += $prod
2009-11-04 12:49:26 +00:00
//5
2014-02-16 18:29:53 +01:00
{ " SUBR " , 0x5000 , 0xf800 , DSPInterpreter : : subr , & DSPEmitter : : subr , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_REG18 , 1 , 0 , 9 , 0x0600 } } , true , false , false , false , true } , // $acD -= $(S+24)
{ " SUBAX " , 0x5800 , 0xfc00 , DSPInterpreter : : subax , & DSPEmitter : : subax , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_AX , 1 , 0 , 9 , 0x0200 } } , true , false , false , false , true } , // $acD -= $axS
{ " SUB " , 0x5c00 , 0xfe00 , DSPInterpreter : : sub , & DSPEmitter : : sub , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_ACC_D , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD -= $ac(1-D)
{ " SUBP " , 0x5e00 , 0xfe00 , DSPInterpreter : : subp , & DSPEmitter : : subp , 1 , 1 , { { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD -= $prod
2009-07-06 02:10:26 +00:00
2009-11-04 12:49:26 +00:00
//6
2014-02-16 18:29:53 +01:00
{ " MOVR " , 0x6000 , 0xf800 , DSPInterpreter : : movr , & DSPEmitter : : movr , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_REG18 , 1 , 0 , 9 , 0x0600 } } , true , false , false , false , true } , // $acD.hm = $(S+24); $acD.l = 0
{ " MOVAX " , 0x6800 , 0xfc00 , DSPInterpreter : : movax , & DSPEmitter : : movax , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_AX , 1 , 0 , 9 , 0x0200 } } , true , false , false , false , true } , // $acD = $axS
{ " MOV " , 0x6c00 , 0xfe00 , DSPInterpreter : : mov , & DSPEmitter : : mov , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_ACC_D , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD = $ax(1-D)
{ " MOVP " , 0x6e00 , 0xfe00 , DSPInterpreter : : movp , & DSPEmitter : : movp , 1 , 1 , { { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD = $prod
2009-07-06 02:10:26 +00:00
2009-11-04 12:49:26 +00:00
//7
2014-02-16 18:29:53 +01:00
{ " ADDAXL " , 0x7000 , 0xfc00 , DSPInterpreter : : addaxl , & DSPEmitter : : addaxl , 1 , 2 , { { P_ACC , 1 , 0 , 8 , 0x0100 } , { P_REG18 , 1 , 0 , 9 , 0x0200 } } , true , false , false , false , true } , // $acD += $axS.l
{ " INCM " , 0x7400 , 0xfe00 , DSPInterpreter : : incm , & DSPEmitter : : incm , 1 , 1 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acsD++
{ " INC " , 0x7600 , 0xfe00 , DSPInterpreter : : inc , & DSPEmitter : : inc , 1 , 1 , { { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD++
{ " DECM " , 0x7800 , 0xfe00 , DSPInterpreter : : decm , & DSPEmitter : : decm , 1 , 1 , { { P_ACCM , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acsD--
{ " DEC " , 0x7a00 , 0xfe00 , DSPInterpreter : : dec , & DSPEmitter : : dec , 1 , 1 , { { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD--
{ " NEG " , 0x7c00 , 0xfe00 , DSPInterpreter : : neg , & DSPEmitter : : neg , 1 , 1 , { { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD = -$acD
{ " MOVNP " , 0x7e00 , 0xfe00 , DSPInterpreter : : movnp , & DSPEmitter : : movnp , 1 , 1 , { { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD = -$prod
2009-07-06 02:10:26 +00:00
2009-11-04 12:49:26 +00:00
//8
2014-02-16 18:29:53 +01:00
{ " NX " , 0x8000 , 0xf700 , DSPInterpreter : : nx , & DSPEmitter : : nx , 1 , 0 , { } , true , false , false , false , false } , // extendable nop
{ " CLR " , 0x8100 , 0xf700 , DSPInterpreter : : clr , & DSPEmitter : : clr , 1 , 1 , { { P_ACC , 1 , 0 , 11 , 0x0800 } } , true , false , false , false , true } , // $acD = 0
{ " CMP " , 0x8200 , 0xff00 , DSPInterpreter : : cmp , & DSPEmitter : : cmp , 1 , 0 , { } , true , false , false , false , true } , // FLAGS($ac0 - $ac1)
{ " MULAXH " , 0x8300 , 0xff00 , DSPInterpreter : : mulaxh , & DSPEmitter : : mulaxh , 1 , 0 , { } , true , false , false , false , true } , // $prod = $ax0.h * $ax0.h
{ " CLRP " , 0x8400 , 0xff00 , DSPInterpreter : : clrp , & DSPEmitter : : clrp , 1 , 0 , { } , true , false , false , false , true } , // $prod = 0
{ " TSTPROD " , 0x8500 , 0xff00 , DSPInterpreter : : tstprod , & DSPEmitter : : tstprod , 1 , 0 , { } , true , false , false , false , true } , // FLAGS($prod)
{ " TSTAXH " , 0x8600 , 0xfe00 , DSPInterpreter : : tstaxh , & DSPEmitter : : tstaxh , 1 , 1 , { { P_REG1A , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // FLAGS($axR.h)
{ " M2 " , 0x8a00 , 0xff00 , DSPInterpreter : : srbith , & DSPEmitter : : srbith , 1 , 0 , { } , true , false , false , false , false } , // enable "$prod *= 2" after every multiplication
{ " M0 " , 0x8b00 , 0xff00 , DSPInterpreter : : srbith , & DSPEmitter : : srbith , 1 , 0 , { } , true , false , false , false , false } , // disable "$prod *= 2" after every multiplication
{ " CLR15 " , 0x8c00 , 0xff00 , DSPInterpreter : : srbith , & DSPEmitter : : srbith , 1 , 0 , { } , true , false , false , false , false } , // set normal multiplication
{ " SET15 " , 0x8d00 , 0xff00 , DSPInterpreter : : srbith , & DSPEmitter : : srbith , 1 , 0 , { } , true , false , false , false , false } , // set unsigned multiplication in MUL
{ " SET16 " , 0x8e00 , 0xff00 , DSPInterpreter : : srbith , & DSPEmitter : : srbith , 1 , 0 , { } , true , false , false , false , false } , // set 16 bit sign extension width
{ " SET40 " , 0x8f00 , 0xff00 , DSPInterpreter : : srbith , & DSPEmitter : : srbith , 1 , 0 , { } , true , false , false , false , false } , // set 40 bit sign extension width
2009-07-31 15:21:35 +00:00
2009-11-04 12:49:26 +00:00
//9
2014-02-16 18:29:53 +01:00
{ " MUL " , 0x9000 , 0xf700 , DSPInterpreter : : mul , & DSPEmitter : : mul , 1 , 2 , { { P_REG18 , 1 , 0 , 11 , 0x0800 } , { P_REG1A , 1 , 0 , 11 , 0x0800 } } , true , false , false , false , true } , // $prod = $axS.l * $axS.h
{ " ASR16 " , 0x9100 , 0xf700 , DSPInterpreter : : asr16 , & DSPEmitter : : asr16 , 1 , 1 , { { P_ACC , 1 , 0 , 11 , 0x0800 } } , true , false , false , false , true } , // $acD >>= 16 (shifting in sign bits)
{ " MULMVZ " , 0x9200 , 0xf600 , DSPInterpreter : : mulmvz , & DSPEmitter : : mulmvz , 1 , 3 , { { P_REG18 , 1 , 0 , 11 , 0x0800 } , { P_REG1A , 1 , 0 , 11 , 0x0800 } , { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acR.hm = $prod.hm; $acR.l = 0; $prod = $axS.l * $axS.h
{ " MULAC " , 0x9400 , 0xf600 , DSPInterpreter : : mulac , & DSPEmitter : : mulac , 1 , 3 , { { P_REG18 , 1 , 0 , 11 , 0x0800 } , { P_REG1A , 1 , 0 , 11 , 0x0800 } , { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acR += $prod; $prod = $axS.l * $axS.h
{ " MULMV " , 0x9600 , 0xf600 , DSPInterpreter : : mulmv , & DSPEmitter : : mulmv , 1 , 3 , { { P_REG18 , 1 , 0 , 11 , 0x0800 } , { P_REG1A , 1 , 0 , 11 , 0x0800 } , { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acR = $prod; $prod = $axS.l * $axS.h
2010-10-14 13:17:38 +00:00
2010-03-19 21:53:41 +00:00
//a-b
2014-02-16 18:29:53 +01:00
{ " MULX " , 0xa000 , 0xe700 , DSPInterpreter : : mulx , & DSPEmitter : : mulx , 1 , 2 , { { P_REGM18 , 1 , 0 , 11 , 0x1000 } , { P_REGM19 , 1 , 0 , 10 , 0x0800 } } , true , false , false , false , true } , // $prod = $ax0.S * $ax1.T
{ " ABS " , 0xa100 , 0xf700 , DSPInterpreter : : abs , & DSPEmitter : : abs , 1 , 1 , { { P_ACC , 1 , 0 , 11 , 0x0800 } } , true , false , false , false , true } , // $acD = abs($acD)
{ " MULXMVZ " , 0xa200 , 0xe600 , DSPInterpreter : : mulxmvz , & DSPEmitter : : mulxmvz , 1 , 3 , { { P_REGM18 , 1 , 0 , 11 , 0x1000 } , { P_REGM19 , 1 , 0 , 10 , 0x0800 } , { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acR.hm = $prod.hm; $acR.l = 0; $prod = $ax0.S * $ax1.T
{ " MULXAC " , 0xa400 , 0xe600 , DSPInterpreter : : mulxac , & DSPEmitter : : mulxac , 1 , 3 , { { P_REGM18 , 1 , 0 , 11 , 0x1000 } , { P_REGM19 , 1 , 0 , 10 , 0x0800 } , { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acR += $prod; $prod = $ax0.S * $ax1.T
{ " MULXMV " , 0xa600 , 0xe600 , DSPInterpreter : : mulxmv , & DSPEmitter : : mulxmv , 1 , 3 , { { P_REGM18 , 1 , 0 , 11 , 0x1000 } , { P_REGM19 , 1 , 0 , 10 , 0x0800 } , { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acR = $prod; $prod = $ax0.S * $ax1.T
{ " TST " , 0xb100 , 0xf700 , DSPInterpreter : : tst , & DSPEmitter : : tst , 1 , 1 , { { P_ACC , 1 , 0 , 11 , 0x0800 } } , true , false , false , false , true } , // FLAGS($acR)
2009-07-31 15:21:35 +00:00
2009-11-04 12:49:26 +00:00
//c-d
2014-02-16 18:29:53 +01:00
{ " MULC " , 0xc000 , 0xe700 , DSPInterpreter : : mulc , & DSPEmitter : : mulc , 1 , 2 , { { P_ACCM , 1 , 0 , 12 , 0x1000 } , { P_REG1A , 1 , 0 , 11 , 0x0800 } } , true , false , false , false , true } , // $prod = $acS.m * $axS.h
{ " CMPAR " , 0xc100 , 0xe700 , DSPInterpreter : : cmpar , & DSPEmitter : : cmpar , 1 , 2 , { { P_ACC , 1 , 0 , 12 , 0x1000 } , { P_REG1A , 1 , 0 , 11 , 0x0800 } } , true , false , false , false , true } , // FLAGS($acS - axR.h)
{ " MULCMVZ " , 0xc200 , 0xe600 , DSPInterpreter : : mulcmvz , & DSPEmitter : : mulcmvz , 1 , 3 , { { P_ACCM , 1 , 0 , 12 , 0x1000 } , { P_REG1A , 1 , 0 , 11 , 0x0800 } , { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acR.hm, $acR.l, $prod = $prod.hm, 0, $acS.m * $axS.h
{ " MULCAC " , 0xc400 , 0xe600 , DSPInterpreter : : mulcac , & DSPEmitter : : mulcac , 1 , 3 , { { P_ACCM , 1 , 0 , 12 , 0x1000 } , { P_REG1A , 1 , 0 , 11 , 0x0800 } , { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acR, $prod = $acR + $prod, $acS.m * $axS.h
{ " MULCMV " , 0xc600 , 0xe600 , DSPInterpreter : : mulcmv , & DSPEmitter : : mulcmv , 1 , 3 , { { P_ACCM , 1 , 0 , 12 , 0x1000 } , { P_REG1A , 1 , 0 , 11 , 0x0800 } , { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acR, $prod = $prod, $acS.m * $axS.h
2009-07-31 15:21:35 +00:00
2009-11-04 12:49:26 +00:00
//e
2014-02-16 18:29:53 +01:00
{ " MADDX " , 0xe000 , 0xfc00 , DSPInterpreter : : maddx , & DSPEmitter : : maddx , 1 , 2 , { { P_REGM18 , 1 , 0 , 8 , 0x0200 } , { P_REGM19 , 1 , 0 , 7 , 0x0100 } } , true , false , false , false , true } , // $prod += $ax0.S * $ax1.T
{ " MSUBX " , 0xe400 , 0xfc00 , DSPInterpreter : : msubx , & DSPEmitter : : msubx , 1 , 2 , { { P_REGM18 , 1 , 0 , 8 , 0x0200 } , { P_REGM19 , 1 , 0 , 7 , 0x0100 } } , true , false , false , false , true } , // $prod -= $ax0.S * $ax1.T
{ " MADDC " , 0xe800 , 0xfc00 , DSPInterpreter : : maddc , & DSPEmitter : : maddc , 1 , 2 , { { P_ACCM , 1 , 0 , 9 , 0x0200 } , { P_REG19 , 1 , 0 , 7 , 0x0100 } } , true , false , false , false , true } , // $prod += $acS.m * $axT.h
{ " MSUBC " , 0xec00 , 0xfc00 , DSPInterpreter : : msubc , & DSPEmitter : : msubc , 1 , 2 , { { P_ACCM , 1 , 0 , 9 , 0x0200 } , { P_REG19 , 1 , 0 , 7 , 0x0100 } } , true , false , false , false , true } , // $prod -= $acS.m * $axT.h
2009-11-04 12:49:26 +00:00
//f
2014-02-16 18:29:53 +01:00
{ " LSL16 " , 0xf000 , 0xfe00 , DSPInterpreter : : lsl16 , & DSPEmitter : : lsl16 , 1 , 1 , { { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acR <<= 16
{ " MADD " , 0xf200 , 0xfe00 , DSPInterpreter : : madd , & DSPEmitter : : madd , 1 , 2 , { { P_REG18 , 1 , 0 , 8 , 0x0100 } , { P_REG1A , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $prod += $axS.l * $axS.h
{ " LSR16 " , 0xf400 , 0xfe00 , DSPInterpreter : : lsr16 , & DSPEmitter : : lsr16 , 1 , 1 , { { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acR >>= 16
{ " MSUB " , 0xf600 , 0xfe00 , DSPInterpreter : : msub , & DSPEmitter : : msub , 1 , 2 , { { P_REG18 , 1 , 0 , 8 , 0x0100 } , { P_REG1A , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $prod -= $axS.l * $axS.h
{ " ADDPAXZ " , 0xf800 , 0xfc00 , DSPInterpreter : : addpaxz , & DSPEmitter : : addpaxz , 1 , 2 , { { P_ACC , 1 , 0 , 9 , 0x0200 } , { P_AX , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD.hm = $prod.hm + $ax.h; $acD.l = 0
{ " CLRL " , 0xfc00 , 0xfe00 , DSPInterpreter : : clrl , & DSPEmitter : : clrl , 1 , 1 , { { P_ACCL , 1 , 0 , 11 , 0x0800 } } , true , false , false , false , true } , // $acR.l = 0
{ " MOVPZ " , 0xfe00 , 0xfe00 , DSPInterpreter : : movpz , & DSPEmitter : : movpz , 1 , 1 , { { P_ACC , 1 , 0 , 8 , 0x0100 } } , true , false , false , false , true } , // $acD.hm = $prod.hm; $acD.l = 0
2009-07-06 02:10:26 +00:00
} ;
2013-10-29 01:23:17 -04:00
const DSPOPCTemplate cw =
2014-03-09 21:14:26 +01:00
{ " CW " , 0x0000 , 0x0000 , nop , nullptr , 1 , 1 , { { P_VAL , 2 , 0 , 0 , 0xffff } } , false , false , false , false , false } ;
2009-07-06 02:10:26 +00:00
2010-05-23 08:41:58 +00:00
// extended opcodes
2009-07-06 02:10:26 +00:00
const DSPOPCTemplate opcodes_ext [ ] =
2009-07-24 16:04:29 +00:00
{
2014-02-16 18:29:53 +01:00
{ " XXX " , 0x0000 , 0x00fc , DSPInterpreter : : Ext : : nop , & DSPEmitter : : nop , 1 , 1 , { { P_VAL , 1 , 0 , 0 , 0x00ff } } , false , false , false , false , false } , // no operation
{ " DR " , 0x0004 , 0x00fc , DSPInterpreter : : Ext : : dr , & DSPEmitter : : dr , 1 , 1 , { { P_REG , 1 , 0 , 0 , 0x0003 } } , false , false , false , false , false } , // $arR--
{ " IR " , 0x0008 , 0x00fc , DSPInterpreter : : Ext : : ir , & DSPEmitter : : ir , 1 , 1 , { { P_REG , 1 , 0 , 0 , 0x0003 } } , false , false , false , false , false } , // $arR++
{ " NR " , 0x000c , 0x00fc , DSPInterpreter : : Ext : : nr , & DSPEmitter : : nr , 1 , 1 , { { P_REG , 1 , 0 , 0 , 0x0003 } } , false , false , false , false , false } , // $arR += $ixR
{ " MV " , 0x0010 , 0x00f0 , DSPInterpreter : : Ext : : mv , & DSPEmitter : : mv , 1 , 2 , { { P_REG18 , 1 , 0 , 2 , 0x000c } , { P_REG1C , 1 , 0 , 0 , 0x0003 } } , false , false , false , false , false } , // $(D+24) = $(S+28)
{ " S " , 0x0020 , 0x00e4 , DSPInterpreter : : Ext : : s , & DSPEmitter : : s , 1 , 2 , { { P_PRG , 1 , 0 , 0 , 0x0003 } , { P_REG1C , 1 , 0 , 3 , 0x0018 } } , false , false , false , false , false } , // MEM[$D++] = $(S+28)
{ " SN " , 0x0024 , 0x00e4 , DSPInterpreter : : Ext : : sn , & DSPEmitter : : sn , 1 , 2 , { { P_PRG , 1 , 0 , 0 , 0x0003 } , { P_REG1C , 1 , 0 , 3 , 0x0018 } } , false , false , false , false , false } , // MEM[$D] = $(D+28); $D += $(D+4)
{ " L " , 0x0040 , 0x00c4 , DSPInterpreter : : Ext : : l , & DSPEmitter : : l , 1 , 2 , { { P_REG18 , 1 , 0 , 3 , 0x0038 } , { P_PRG , 1 , 0 , 0 , 0x0003 } } , false , false , false , false , false } , // $(D+24) = MEM[$S++]
{ " LN " , 0x0044 , 0x00c4 , DSPInterpreter : : Ext : : ln , & DSPEmitter : : ln , 1 , 2 , { { P_REG18 , 1 , 0 , 3 , 0x0038 } , { P_PRG , 1 , 0 , 0 , 0x0003 } } , false , false , false , false , false } , // $(D+24) = MEM[$S]; $S += $(S+4)
{ " LS " , 0x0080 , 0x00ce , DSPInterpreter : : Ext : : ls , & DSPEmitter : : ls , 1 , 2 , { { P_REG18 , 1 , 0 , 4 , 0x0030 } , { P_ACCM , 1 , 0 , 0 , 0x0001 } } , false , false , false , false , false } , // $(D+24) = MEM[$ar0++]; MEM[$ar3++] = $acS.m
{ " SL " , 0x0082 , 0x00ce , DSPInterpreter : : Ext : : sl , & DSPEmitter : : sl , 1 , 2 , { { P_ACCM , 1 , 0 , 0 , 0x0001 } , { P_REG18 , 1 , 0 , 4 , 0x0030 } } , false , false , false , false , false } , // MEM[$ar0++] = $acS.m; $(D+24) = MEM[$ar3++]
{ " LSN " , 0x0084 , 0x00ce , DSPInterpreter : : Ext : : lsn , & DSPEmitter : : lsn , 1 , 2 , { { P_REG18 , 1 , 0 , 4 , 0x0030 } , { P_ACCM , 1 , 0 , 0 , 0x0001 } } , false , false , false , false , false } , // $(D+24) = MEM[$ar0]; MEM[$ar3++] = $acS.m; $ar0 += $ix0
{ " SLN " , 0x0086 , 0x00ce , DSPInterpreter : : Ext : : sln , & DSPEmitter : : sln , 1 , 2 , { { P_ACCM , 1 , 0 , 0 , 0x0001 } , { P_REG18 , 1 , 0 , 4 , 0x0030 } } , false , false , false , false , false } , // MEM[$ar0] = $acS.m; $(D+24) = MEM[$ar3++]; $ar0 += $ix0
{ " LSM " , 0x0088 , 0x00ce , DSPInterpreter : : Ext : : lsm , & DSPEmitter : : lsm , 1 , 2 , { { P_REG18 , 1 , 0 , 4 , 0x0030 } , { P_ACCM , 1 , 0 , 0 , 0x0001 } } , false , false , false , false , false } , // $(D+24) = MEM[$ar0++]; MEM[$ar3] = $acS.m; $ar3 += $ix3
{ " SLM " , 0x008a , 0x00ce , DSPInterpreter : : Ext : : slm , & DSPEmitter : : slm , 1 , 2 , { { P_ACCM , 1 , 0 , 0 , 0x0001 } , { P_REG18 , 1 , 0 , 4 , 0x0030 } } , false , false , false , false , false } , // MEM[$ar0++] = $acS.m; $(D+24) = MEM[$ar3]; $ar3 += $ix3
{ " LSNM " , 0x008c , 0x00ce , DSPInterpreter : : Ext : : lsnm , & DSPEmitter : : lsnm , 1 , 2 , { { P_REG18 , 1 , 0 , 4 , 0x0030 } , { P_ACCM , 1 , 0 , 0 , 0x0001 } } , false , false , false , false , false } , // $(D+24) = MEM[$ar0]; MEM[$ar3] = $acS.m; $ar0 += $ix0; $ar3 += $ix3
{ " SLNM " , 0x008e , 0x00ce , DSPInterpreter : : Ext : : slnm , & DSPEmitter : : slnm , 1 , 2 , { { P_ACCM , 1 , 0 , 0 , 0x0001 } , { P_REG18 , 1 , 0 , 4 , 0x0030 } } , false , false , false , false , false } , // MEM[$ar0] = $acS.m; $(D+24) = MEM[$ar3]; $ar0 += $ix0; $ar3 += $ix3
{ " LDAX " , 0x00c3 , 0x00cf , DSPInterpreter : : Ext : : ldax , & DSPEmitter : : ldax , 1 , 2 , { { P_AX , 1 , 0 , 4 , 0x0010 } , { P_PRG , 1 , 0 , 5 , 0x0020 } } , false , false , false , false , false } , // $axR.h = MEM[$arS++]; $axR.l = MEM[$ar3++]
{ " LDAXN " , 0x00c7 , 0x00cf , DSPInterpreter : : Ext : : ldaxn , & DSPEmitter : : ldaxn , 1 , 2 , { { P_AX , 1 , 0 , 4 , 0x0010 } , { P_PRG , 1 , 0 , 5 , 0x0020 } } , false , false , false , false , false } , // $axR.h = MEM[$arS]; $axR.l = MEM[$ar3++]; $arS += $ixS
{ " LDAXM " , 0x00cb , 0x00cf , DSPInterpreter : : Ext : : ldaxm , & DSPEmitter : : ldaxm , 1 , 2 , { { P_AX , 1 , 0 , 4 , 0x0010 } , { P_PRG , 1 , 0 , 5 , 0x0020 } } , false , false , false , false , false } , // $axR.h = MEM[$arS++]; $axR.l = MEM[$ar3]; $ar3 += $ix3
{ " LDAXNM " , 0x00cf , 0x00cf , DSPInterpreter : : Ext : : ldaxnm , & DSPEmitter : : ldaxnm , 1 , 2 , { { P_AX , 1 , 0 , 4 , 0x0010 } , { P_PRG , 1 , 0 , 5 , 0x0020 } } , false , false , false , false , false } , // $axR.h = MEM[$arS]; $axR.l = MEM[$ar3]; $arS += $ixS; $ar3 += $ix3
{ " LD " , 0x00c0 , 0x00cc , DSPInterpreter : : Ext : : ld , & DSPEmitter : : ld , 1 , 3 , { { P_REGM18 , 1 , 0 , 4 , 0x0020 } , { P_REGM19 , 1 , 0 , 3 , 0x0010 } , { P_PRG , 1 , 0 , 0 , 0x0003 } } , false , false , false , false , false } , // $ax0.D = MEM[$arS++]; $ax1.R = MEM[$ar3++]
{ " LDN " , 0x00c4 , 0x00cc , DSPInterpreter : : Ext : : ldn , & DSPEmitter : : ldn , 1 , 3 , { { P_REGM18 , 1 , 0 , 4 , 0x0020 } , { P_REGM19 , 1 , 0 , 3 , 0x0010 } , { P_PRG , 1 , 0 , 0 , 0x0003 } } , false , false , false , false , false } , // $ax0.D = MEM[$arS]; $ax1.R = MEM[$ar3++]; $arS += $ixS
{ " LDM " , 0x00c8 , 0x00cc , DSPInterpreter : : Ext : : ldm , & DSPEmitter : : ldm , 1 , 3 , { { P_REGM18 , 1 , 0 , 4 , 0x0020 } , { P_REGM19 , 1 , 0 , 3 , 0x0010 } , { P_PRG , 1 , 0 , 0 , 0x0003 } } , false , false , false , false , false } , // $ax0.D = MEM[$arS++]; $ax1.R = MEM[$ar3]; $ar3 += $ix3
{ " LDNM " , 0x00cc , 0x00cc , DSPInterpreter : : Ext : : ldnm , & DSPEmitter : : ldnm , 1 , 3 , { { P_REGM18 , 1 , 0 , 4 , 0x0020 } , { P_REGM19 , 1 , 0 , 3 , 0x0010 } , { P_PRG , 1 , 0 , 0 , 0x0003 } } , false , false , false , false , false } , // $ax0.D = MEM[$arS]; $ax1.R = MEM[$ar3]; $arS += $ixS; $ar3 += $ix3
2009-07-06 02:10:26 +00:00
} ;
const int opcodes_size = sizeof ( opcodes ) / sizeof ( DSPOPCTemplate ) ;
const int opcodes_ext_size = sizeof ( opcodes_ext ) / sizeof ( DSPOPCTemplate ) ;
const pdlabel_t pdlabels [ ] =
{
{ 0xffa0 , " COEF_A1_0 " , " COEF_A1_0 " , } ,
{ 0xffa1 , " COEF_A2_0 " , " COEF_A2_0 " , } ,
{ 0xffa2 , " COEF_A1_1 " , " COEF_A1_1 " , } ,
{ 0xffa3 , " COEF_A2_1 " , " COEF_A2_1 " , } ,
{ 0xffa4 , " COEF_A1_2 " , " COEF_A1_2 " , } ,
{ 0xffa5 , " COEF_A2_2 " , " COEF_A2_2 " , } ,
{ 0xffa6 , " COEF_A1_3 " , " COEF_A1_3 " , } ,
{ 0xffa7 , " COEF_A2_3 " , " COEF_A2_3 " , } ,
{ 0xffa8 , " COEF_A1_4 " , " COEF_A1_4 " , } ,
{ 0xffa9 , " COEF_A2_4 " , " COEF_A2_4 " , } ,
{ 0xffaa , " COEF_A1_5 " , " COEF_A1_5 " , } ,
{ 0xffab , " COEF_A2_5 " , " COEF_A2_5 " , } ,
{ 0xffac , " COEF_A1_6 " , " COEF_A1_6 " , } ,
{ 0xffad , " COEF_A2_6 " , " COEF_A2_6 " , } ,
{ 0xffae , " COEF_A1_7 " , " COEF_A1_7 " , } ,
{ 0xffaf , " COEF_A2_7 " , " COEF_A2_7 " , } ,
2014-03-09 21:14:26 +01:00
{ 0xffb0 , " 0xffb0 " , nullptr , } ,
{ 0xffb1 , " 0xffb1 " , nullptr , } ,
{ 0xffb2 , " 0xffb2 " , nullptr , } ,
{ 0xffb3 , " 0xffb3 " , nullptr , } ,
{ 0xffb4 , " 0xffb4 " , nullptr , } ,
{ 0xffb5 , " 0xffb5 " , nullptr , } ,
{ 0xffb6 , " 0xffb6 " , nullptr , } ,
{ 0xffb7 , " 0xffb7 " , nullptr , } ,
{ 0xffb8 , " 0xffb8 " , nullptr , } ,
{ 0xffb9 , " 0xffb9 " , nullptr , } ,
{ 0xffba , " 0xffba " , nullptr , } ,
{ 0xffbb , " 0xffbb " , nullptr , } ,
{ 0xffbc , " 0xffbc " , nullptr , } ,
{ 0xffbd , " 0xffbd " , nullptr , } ,
{ 0xffbe , " 0xffbe " , nullptr , } ,
{ 0xffbf , " 0xffbf " , nullptr , } ,
{ 0xffc0 , " 0xffc0 " , nullptr , } ,
{ 0xffc1 , " 0xffc1 " , nullptr , } ,
{ 0xffc2 , " 0xffc2 " , nullptr , } ,
{ 0xffc3 , " 0xffc3 " , nullptr , } ,
{ 0xffc4 , " 0xffc4 " , nullptr , } ,
{ 0xffc5 , " 0xffc5 " , nullptr , } ,
{ 0xffc6 , " 0xffc6 " , nullptr , } ,
{ 0xffc7 , " 0xffc7 " , nullptr , } ,
{ 0xffc8 , " 0xffc8 " , nullptr , } ,
2009-07-06 02:10:26 +00:00
{ 0xffc9 , " DSCR " , " DSP DMA Control Reg " , } ,
2014-03-09 21:14:26 +01:00
{ 0xffca , " 0xffca " , nullptr , } ,
2009-07-06 02:10:26 +00:00
{ 0xffcb , " DSBL " , " DSP DMA Block Length " , } ,
2014-03-09 21:14:26 +01:00
{ 0xffcc , " 0xffcc " , nullptr , } ,
2009-07-06 02:10:26 +00:00
{ 0xffcd , " DSPA " , " DSP DMA DMEM Address " , } ,
{ 0xffce , " DSMAH " , " DSP DMA Mem Address H " , } ,
{ 0xffcf , " DSMAL " , " DSP DMA Mem Address L " , } ,
2014-03-09 21:14:26 +01:00
{ 0xffd0 , " 0xffd0 " , nullptr , } ,
2009-07-06 02:10:26 +00:00
{ 0xffd1 , " SampleFormat " , " SampleFormat " , } ,
2014-03-09 21:14:26 +01:00
{ 0xffd2 , " 0xffd2 " , nullptr , } ,
2009-07-06 02:10:26 +00:00
{ 0xffd3 , " UnkZelda " , " Unk Zelda reads/writes from/to it " , } ,
{ 0xffd4 , " ACSAH " , " Accelerator start address H " , } ,
{ 0xffd5 , " ACSAL " , " Accelerator start address L " , } ,
{ 0xffd6 , " ACEAH " , " Accelerator end address H " , } ,
{ 0xffd7 , " ACEAL " , " Accelerator end address L " , } ,
{ 0xffd8 , " ACCAH " , " Accelerator current address H " , } ,
{ 0xffd9 , " ACCAL " , " Accelerator current address L " , } ,
{ 0xffda , " pred_scale " , " pred_scale " , } ,
{ 0xffdb , " yn1 " , " yn1 " , } ,
{ 0xffdc , " yn2 " , " yn2 " , } ,
{ 0xffdd , " ARAM " , " Direct Read from ARAM (uses ADPCM) " , } ,
{ 0xffde , " GAIN " , " Gain " , } ,
2014-03-09 21:14:26 +01:00
{ 0xffdf , " 0xffdf " , nullptr , } ,
{ 0xffe0 , " 0xffe0 " , nullptr , } ,
{ 0xffe1 , " 0xffe1 " , nullptr , } ,
{ 0xffe2 , " 0xffe2 " , nullptr , } ,
{ 0xffe3 , " 0xffe3 " , nullptr , } ,
{ 0xffe4 , " 0xffe4 " , nullptr , } ,
{ 0xffe5 , " 0xffe5 " , nullptr , } ,
{ 0xffe6 , " 0xffe6 " , nullptr , } ,
{ 0xffe7 , " 0xffe7 " , nullptr , } ,
{ 0xffe8 , " 0xffe8 " , nullptr , } ,
{ 0xffe9 , " 0xffe9 " , nullptr , } ,
{ 0xffea , " 0xffea " , nullptr , } ,
{ 0xffeb , " 0xffeb " , nullptr , } ,
{ 0xffec , " 0xffec " , nullptr , } ,
{ 0xffed , " 0xffed " , nullptr , } ,
{ 0xffee , " 0xffee " , nullptr , } ,
2009-07-06 02:10:26 +00:00
{ 0xffef , " AMDM " , " ARAM DMA Request Mask " , } ,
2014-03-09 21:14:26 +01:00
{ 0xfff0 , " 0xfff0 " , nullptr , } ,
{ 0xfff1 , " 0xfff1 " , nullptr , } ,
{ 0xfff2 , " 0xfff2 " , nullptr , } ,
{ 0xfff3 , " 0xfff3 " , nullptr , } ,
{ 0xfff4 , " 0xfff4 " , nullptr , } ,
{ 0xfff5 , " 0xfff5 " , nullptr , } ,
{ 0xfff6 , " 0xfff6 " , nullptr , } ,
{ 0xfff7 , " 0xfff7 " , nullptr , } ,
{ 0xfff8 , " 0xfff8 " , nullptr , } ,
{ 0xfff9 , " 0xfff9 " , nullptr , } ,
{ 0xfffa , " 0xfffa " , nullptr , } ,
2009-07-06 02:10:26 +00:00
{ 0xfffb , " DIRQ " , " DSP IRQ Request " , } ,
{ 0xfffc , " DMBH " , " DSP Mailbox H " , } ,
{ 0xfffd , " DMBL " , " DSP Mailbox L " , } ,
{ 0xfffe , " CMBH " , " CPU Mailbox H " , } ,
{ 0xffff , " CMBL " , " CPU Mailbox L " , } ,
} ;
const u32 pdlabels_size = sizeof ( pdlabels ) / sizeof ( pdlabel_t ) ;
const pdlabel_t regnames [ ] =
{
{ 0x00 , " AR0 " , " Addr Reg 00 " , } ,
{ 0x01 , " AR1 " , " Addr Reg 01 " , } ,
{ 0x02 , " AR2 " , " Addr Reg 02 " , } ,
{ 0x03 , " AR3 " , " Addr Reg 03 " , } ,
{ 0x04 , " IX0 " , " Index Reg 0 " , } ,
{ 0x05 , " IX1 " , " Index Reg 1 " , } ,
{ 0x06 , " IX2 " , " Index Reg 2 " , } ,
{ 0x07 , " IX3 " , " Index Reg 3 " , } ,
{ 0x08 , " WR0 " , " Wrapping Register 0 " , } ,
{ 0x09 , " WR1 " , " Wrapping Register 1 " , } ,
{ 0x0a , " WR2 " , " Wrapping Register 2 " , } ,
{ 0x0b , " WR3 " , " Wrapping Register 3 " , } ,
{ 0x0c , " ST0 " , " Call stack " , } ,
{ 0x0d , " ST1 " , " Data stack " , } ,
{ 0x0e , " ST2 " , " Loop addr stack " , } ,
{ 0x0f , " ST3 " , " Loop counter " , } ,
{ 0x10 , " AC0.H " , " Accu High 0 " , } ,
{ 0x11 , " AC1.H " , " Accu High 1 " , } ,
{ 0x12 , " CR " , " Config Register " , } ,
{ 0x13 , " SR " , " Special Register " , } ,
{ 0x14 , " PROD.L " , " Prod L " , } ,
{ 0x15 , " PROD.M1 " , " Prod M1 " , } ,
{ 0x16 , " PROD.H " , " Prod H " , } ,
{ 0x17 , " PROD.M2 " , " Prod M2 " , } ,
{ 0x18 , " AX0.L " , " Extra Accu L 0 " , } ,
{ 0x19 , " AX1.L " , " Extra Accu L 1 " , } ,
{ 0x1a , " AX0.H " , " Extra Accu H 0 " , } ,
{ 0x1b , " AX1.H " , " Extra Accu H 1 " , } ,
{ 0x1c , " AC0.L " , " Accu Low 0 " , } ,
{ 0x1d , " AC1.L " , " Accu Low 1 " , } ,
{ 0x1e , " AC0.M " , " Accu Mid 0 " , } ,
{ 0x1f , " AC1.M " , " Accu Mid 1 " , } ,
// To resolve combined register names.
{ 0x20 , " ACC0 " , " Accu Full 0 " , } ,
{ 0x21 , " ACC1 " , " Accu Full 1 " , } ,
{ 0x22 , " AX0 " , " Extra Accu 0 " , } ,
{ 0x23 , " AX1 " , " Extra Accu 1 " , } ,
} ;
2010-03-29 01:18:05 +00:00
const DSPOPCTemplate * opTable [ OPTABLE_SIZE ] ;
const DSPOPCTemplate * extOpTable [ EXT_OPTABLE_SIZE ] ;
2009-08-19 21:37:24 +00:00
u16 writeBackLog [ WRITEBACKLOGSIZE ] ;
int writeBackLogIdx [ WRITEBACKLOGSIZE ] ;
2009-07-06 02:10:26 +00:00
const char * pdname ( u16 val )
{
static char tmpstr [ 12 ] ; // nasty
2014-03-03 06:25:15 +01:00
for ( const pdlabel_t & pdlabel : pdlabels )
2009-07-06 02:10:26 +00:00
{
2013-10-29 01:09:01 -04:00
if ( pdlabel . addr = = val )
return pdlabel . name ;
2009-07-06 02:10:26 +00:00
}
sprintf ( tmpstr , " 0x%04x " , val ) ;
return tmpstr ;
}
const char * pdregname ( int val )
{
return regnames [ val ] . name ;
}
const char * pdregnamelong ( int val )
{
return regnames [ val ] . description ;
}
const DSPOPCTemplate * GetOpTemplate ( const UDSPInstruction & inst )
{
2010-03-29 01:18:05 +00:00
return opTable [ inst ] ;
2009-07-06 02:10:26 +00:00
}
// This function could use the above GetOpTemplate, but then we'd lose the
// nice property that it catches colliding op masks.
void InitInstructionTable ( )
{
2009-07-24 16:04:29 +00:00
// ext op table
Core/DSP: Split extended opcode 0xc0/mask 0xc0 to account for 0xc3/mask 0xc3 variant
In assembly, these are 'ld $ax0.d,$ax1.r,@$arS with their n,m and nm variants,
which have been special cased for S==3. The regular 'ld can be decomposed
into lrri $ax0.d,@$arS and lrri $ax1.r,@$ar3, while the S==3 case decomposes
to lrri $axR.h,@$arD and lrri $axR.l,@$ar3. The latter variant will be
disassembled to 'ldax $axR,@$arD after this change. The assembler recognizes
both the new 'ldax variant and the old 'ld with @$ar3 but the disassembler
only outputs 'ldax. Besides the readability, this allows for more correct
register use analysis(when it's done).
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7413 8ced0084-cf51-0410-be5f-012b33b47a6e
2011-03-25 22:28:18 +00:00
for ( int i = 0 ; i < EXT_OPTABLE_SIZE ; i + + )
2013-10-29 01:09:01 -04:00
{
2010-03-29 01:18:05 +00:00
extOpTable [ i ] = & cw ;
2009-07-24 16:04:29 +00:00
2014-03-03 06:25:15 +01:00
for ( const DSPOPCTemplate & ext : opcodes_ext )
2009-07-24 16:04:29 +00:00
{
2013-10-29 01:09:01 -04:00
u16 mask = ext . opcode_mask ;
if ( ( mask & i ) = = ext . opcode )
2009-07-24 16:04:29 +00:00
{
Core/DSP: Split extended opcode 0xc0/mask 0xc0 to account for 0xc3/mask 0xc3 variant
In assembly, these are 'ld $ax0.d,$ax1.r,@$arS with their n,m and nm variants,
which have been special cased for S==3. The regular 'ld can be decomposed
into lrri $ax0.d,@$arS and lrri $ax1.r,@$ar3, while the S==3 case decomposes
to lrri $axR.h,@$arD and lrri $axR.l,@$ar3. The latter variant will be
disassembled to 'ldax $axR,@$arD after this change. The assembler recognizes
both the new 'ldax variant and the old 'ld with @$ar3 but the disassembler
only outputs 'ldax. Besides the readability, this allows for more correct
register use analysis(when it's done).
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7413 8ced0084-cf51-0410-be5f-012b33b47a6e
2011-03-25 22:28:18 +00:00
if ( extOpTable [ i ] = = & cw )
2014-03-03 06:25:15 +01:00
{
2013-10-29 01:09:01 -04:00
extOpTable [ i ] = & ext ;
2014-03-03 06:25:15 +01:00
}
2009-07-24 16:04:29 +00:00
else
Core/DSP: Split extended opcode 0xc0/mask 0xc0 to account for 0xc3/mask 0xc3 variant
In assembly, these are 'ld $ax0.d,$ax1.r,@$arS with their n,m and nm variants,
which have been special cased for S==3. The regular 'ld can be decomposed
into lrri $ax0.d,@$arS and lrri $ax1.r,@$ar3, while the S==3 case decomposes
to lrri $axR.h,@$arD and lrri $axR.l,@$ar3. The latter variant will be
disassembled to 'ldax $axR,@$arD after this change. The assembler recognizes
both the new 'ldax variant and the old 'ld with @$ar3 but the disassembler
only outputs 'ldax. Besides the readability, this allows for more correct
register use analysis(when it's done).
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7413 8ced0084-cf51-0410-be5f-012b33b47a6e
2011-03-25 22:28:18 +00:00
{
//if the entry already in the table
//is a strict subset, allow it
2013-10-29 01:09:01 -04:00
if ( ( extOpTable [ i ] - > opcode_mask | ext . opcode_mask ) ! = extOpTable [ i ] - > opcode_mask )
2014-03-03 06:25:15 +01:00
{
2013-10-29 01:09:01 -04:00
ERROR_LOG ( DSPLLE , " opcode ext table place %d already in use by %s when inserting %s " , i , extOpTable [ i ] - > name , ext . name ) ;
2014-03-03 06:25:15 +01:00
}
Core/DSP: Split extended opcode 0xc0/mask 0xc0 to account for 0xc3/mask 0xc3 variant
In assembly, these are 'ld $ax0.d,$ax1.r,@$arS with their n,m and nm variants,
which have been special cased for S==3. The regular 'ld can be decomposed
into lrri $ax0.d,@$arS and lrri $ax1.r,@$ar3, while the S==3 case decomposes
to lrri $axR.h,@$arD and lrri $axR.l,@$ar3. The latter variant will be
disassembled to 'ldax $axR,@$arD after this change. The assembler recognizes
both the new 'ldax variant and the old 'ld with @$ar3 but the disassembler
only outputs 'ldax. Besides the readability, this allows for more correct
register use analysis(when it's done).
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7413 8ced0084-cf51-0410-be5f-012b33b47a6e
2011-03-25 22:28:18 +00:00
}
2009-07-24 16:04:29 +00:00
}
Core/DSP: Split extended opcode 0xc0/mask 0xc0 to account for 0xc3/mask 0xc3 variant
In assembly, these are 'ld $ax0.d,$ax1.r,@$arS with their n,m and nm variants,
which have been special cased for S==3. The regular 'ld can be decomposed
into lrri $ax0.d,@$arS and lrri $ax1.r,@$ar3, while the S==3 case decomposes
to lrri $axR.h,@$arD and lrri $axR.l,@$ar3. The latter variant will be
disassembled to 'ldax $axR,@$arD after this change. The assembler recognizes
both the new 'ldax variant and the old 'ld with @$ar3 but the disassembler
only outputs 'ldax. Besides the readability, this allows for more correct
register use analysis(when it's done).
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7413 8ced0084-cf51-0410-be5f-012b33b47a6e
2011-03-25 22:28:18 +00:00
}
2009-07-24 16:04:29 +00:00
}
2009-07-25 20:12:38 +00:00
2009-07-24 16:04:29 +00:00
// op table
2014-03-03 06:25:15 +01:00
for ( const DSPOPCTemplate * & opcode : opTable )
{
opcode = & cw ;
}
2013-10-29 01:09:01 -04:00
2009-07-06 02:10:26 +00:00
for ( int i = 0 ; i < OPTABLE_SIZE ; i + + )
{
2014-03-03 06:25:15 +01:00
for ( const DSPOPCTemplate & opcode : opcodes )
2009-07-06 02:10:26 +00:00
{
2013-10-29 01:09:01 -04:00
u16 mask = opcode . opcode_mask ;
if ( ( mask & i ) = = opcode . opcode )
2009-07-06 02:10:26 +00:00
{
2010-03-29 01:18:05 +00:00
if ( opTable [ i ] = = & cw )
2013-10-29 01:09:01 -04:00
opTable [ i ] = & opcode ;
2009-07-06 02:10:26 +00:00
else
2013-10-29 01:23:17 -04:00
ERROR_LOG ( DSPLLE , " opcode table place %d already in use for %s " , i , opcode . name ) ;
2009-07-06 02:10:26 +00:00
}
}
}
2009-08-19 21:37:24 +00:00
2014-03-03 06:25:15 +01:00
for ( int & elem : writeBackLogIdx )
{
elem = - 1 ;
}
2013-04-16 23:14:36 -04:00
}