mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	Merge pull request #703 from lioncash/cruft
dyncom: Remove unused/unnecessary VFP cruft
This commit is contained in:
		
						commit
						a698e15c5d
					
				@ -6,7 +6,6 @@ set(SRCS
 | 
			
		||||
            arm/dyncom/arm_dyncom_interpreter.cpp
 | 
			
		||||
            arm/dyncom/arm_dyncom_run.cpp
 | 
			
		||||
            arm/dyncom/arm_dyncom_thumb.cpp
 | 
			
		||||
            arm/interpreter/armcopro.cpp
 | 
			
		||||
            arm/interpreter/arminit.cpp
 | 
			
		||||
            arm/interpreter/armsupp.cpp
 | 
			
		||||
            arm/skyeye_common/vfp/vfp.cpp
 | 
			
		||||
 | 
			
		||||
@ -1,142 +0,0 @@
 | 
			
		||||
/*  armcopro.c -- co-processor interface:  ARM6 Instruction Emulator.
 | 
			
		||||
    Copyright (C) 1994, 2000 Advanced RISC Machines Ltd.
 | 
			
		||||
 
 | 
			
		||||
    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; either version 2 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 
 | 
			
		||||
    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 for more details.
 | 
			
		||||
 
 | 
			
		||||
    You should have received a copy of the GNU General Public License
 | 
			
		||||
    along with this program; if not, write to the Free Software
 | 
			
		||||
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 | 
			
		||||
 | 
			
		||||
#include "core/arm/skyeye_common/armdefs.h"
 | 
			
		||||
#include "core/arm/skyeye_common/armemu.h"
 | 
			
		||||
#include "core/arm/skyeye_common/vfp/vfp.h"
 | 
			
		||||
 | 
			
		||||
// Dummy Co-processors.
 | 
			
		||||
 | 
			
		||||
static unsigned int NoCoPro3R(ARMul_State* state, unsigned int a, ARMword b)
 | 
			
		||||
{
 | 
			
		||||
    return ARMul_CANT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static unsigned int NoCoPro4R(ARMul_State* state, unsigned int a, ARMword b, ARMword c)
 | 
			
		||||
{
 | 
			
		||||
    return ARMul_CANT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static unsigned int NoCoPro4W(ARMul_State* state, unsigned int a, ARMword b, ARMword* c)
 | 
			
		||||
{
 | 
			
		||||
    return ARMul_CANT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static unsigned int NoCoPro5R(ARMul_State* state, unsigned int a, ARMword b, ARMword c, ARMword d)
 | 
			
		||||
{
 | 
			
		||||
    return ARMul_CANT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static unsigned int NoCoPro5W(ARMul_State* state, unsigned int a, ARMword b, ARMword* c, ARMword* d)
 | 
			
		||||
{
 | 
			
		||||
    return ARMul_CANT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Install co-processor instruction handlers in this routine.
 | 
			
		||||
void ARMul_CoProInit(ARMul_State* state)
 | 
			
		||||
{
 | 
			
		||||
    // Initialise tham all first.
 | 
			
		||||
    for (unsigned int i = 0; i < 16; i++)
 | 
			
		||||
        ARMul_CoProDetach(state, i);
 | 
			
		||||
 | 
			
		||||
    // Install CoPro Instruction handlers here.
 | 
			
		||||
    // The format is:
 | 
			
		||||
    // ARMul_CoProAttach (state, CP Number, Init routine, Exit routine
 | 
			
		||||
    // LDC routine, STC routine, MRC routine, MCR routine,
 | 
			
		||||
    // CDP routine, Read Reg routine, Write Reg routine).
 | 
			
		||||
    if (state->is_v6) {
 | 
			
		||||
        ARMul_CoProAttach(state, 10, VFPInit, NULL, VFPLDC, VFPSTC,
 | 
			
		||||
            VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL);
 | 
			
		||||
        ARMul_CoProAttach(state, 11, VFPInit, NULL, VFPLDC, VFPSTC,
 | 
			
		||||
            VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
        /*ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL,
 | 
			
		||||
        MMUMRC, MMUMCR, NULL, NULL, NULL, NULL, NULL);*/
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // No handlers below here.
 | 
			
		||||
 | 
			
		||||
    // Call all the initialisation routines.
 | 
			
		||||
    for (unsigned int i = 0; i < 16; i++) {
 | 
			
		||||
        if (state->CPInit[i])
 | 
			
		||||
            (state->CPInit[i]) (state);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Install co-processor finalisation routines in this routine.
 | 
			
		||||
void ARMul_CoProExit(ARMul_State * state)
 | 
			
		||||
{
 | 
			
		||||
    for (unsigned int i = 0; i < 16; i++)
 | 
			
		||||
        if (state->CPExit[i])
 | 
			
		||||
            (state->CPExit[i]) (state);
 | 
			
		||||
 | 
			
		||||
    // Detach all handlers.
 | 
			
		||||
    for (unsigned int i = 0; i < 16; i++)
 | 
			
		||||
        ARMul_CoProDetach(state, i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Routines to hook Co-processors into ARMulator.
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_CoProAttach(ARMul_State* state,
 | 
			
		||||
unsigned number,
 | 
			
		||||
ARMul_CPInits* init,
 | 
			
		||||
ARMul_CPExits* exit,
 | 
			
		||||
ARMul_LDCs* ldc,
 | 
			
		||||
ARMul_STCs* stc,
 | 
			
		||||
ARMul_MRCs* mrc,
 | 
			
		||||
ARMul_MCRs* mcr,
 | 
			
		||||
ARMul_MRRCs* mrrc,
 | 
			
		||||
ARMul_MCRRs* mcrr,
 | 
			
		||||
ARMul_CDPs* cdp,
 | 
			
		||||
ARMul_CPReads* read, ARMul_CPWrites* write)
 | 
			
		||||
{
 | 
			
		||||
    if (init != NULL)
 | 
			
		||||
        state->CPInit[number] = init;
 | 
			
		||||
    if (exit != NULL)
 | 
			
		||||
        state->CPExit[number] = exit;
 | 
			
		||||
    if (ldc != NULL)
 | 
			
		||||
        state->LDC[number] = ldc;
 | 
			
		||||
    if (stc != NULL)
 | 
			
		||||
        state->STC[number] = stc;
 | 
			
		||||
    if (mrc != NULL)
 | 
			
		||||
        state->MRC[number] = mrc;
 | 
			
		||||
    if (mcr != NULL)
 | 
			
		||||
        state->MCR[number] = mcr;
 | 
			
		||||
    if (mrrc != NULL)
 | 
			
		||||
        state->MRRC[number] = mrrc;
 | 
			
		||||
    if (mcrr != NULL)
 | 
			
		||||
        state->MCRR[number] = mcrr;
 | 
			
		||||
    if (cdp != NULL)
 | 
			
		||||
        state->CDP[number] = cdp;
 | 
			
		||||
    if (read != NULL)
 | 
			
		||||
        state->CPRead[number] = read;
 | 
			
		||||
    if (write != NULL)
 | 
			
		||||
        state->CPWrite[number] = write;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ARMul_CoProDetach(ARMul_State* state, unsigned number)
 | 
			
		||||
{
 | 
			
		||||
    ARMul_CoProAttach(state, number, NULL, NULL,
 | 
			
		||||
        NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R,
 | 
			
		||||
        NoCoPro5W, NoCoPro5R, NoCoPro3R, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
    state->CPInit[number] = NULL;
 | 
			
		||||
    state->CPExit[number] = NULL;
 | 
			
		||||
    state->CPRead[number] = NULL;
 | 
			
		||||
    state->CPWrite[number] = NULL;
 | 
			
		||||
}
 | 
			
		||||
@ -19,6 +19,7 @@
 | 
			
		||||
#include "core/mem_map.h"
 | 
			
		||||
#include "core/arm/skyeye_common/armdefs.h"
 | 
			
		||||
#include "core/arm/skyeye_common/armemu.h"
 | 
			
		||||
#include "core/arm/skyeye_common/vfp/vfp.h"
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*            Returns a new instantiation of the ARMulator's state           *
 | 
			
		||||
@ -56,15 +57,11 @@ ARMul_State* ARMul_NewState(ARMul_State* state)
 | 
			
		||||
 | 
			
		||||
void ARMul_SelectProcessor(ARMul_State* state, unsigned properties)
 | 
			
		||||
{
 | 
			
		||||
    state->is_v4     = (properties & (ARM_v4_Prop | ARM_v5_Prop)) != 0;
 | 
			
		||||
    state->is_v5     = (properties & ARM_v5_Prop) != 0;
 | 
			
		||||
    state->is_v5e    = (properties & ARM_v5e_Prop) != 0;
 | 
			
		||||
    state->is_v6     = (properties & ARM_v6_Prop) != 0;
 | 
			
		||||
    state->is_v7     = (properties & ARM_v7_Prop) != 0;
 | 
			
		||||
 | 
			
		||||
    // Only initialse the coprocessor support once we
 | 
			
		||||
    // know what kind of chip we are dealing with.
 | 
			
		||||
    ARMul_CoProInit(state);
 | 
			
		||||
    state->is_v4  = (properties & (ARM_v4_Prop | ARM_v5_Prop)) != 0;
 | 
			
		||||
    state->is_v5  = (properties & ARM_v5_Prop) != 0;
 | 
			
		||||
    state->is_v5e = (properties & ARM_v5e_Prop) != 0;
 | 
			
		||||
    state->is_v6  = (properties & ARM_v6_Prop) != 0;
 | 
			
		||||
    state->is_v7  = (properties & ARM_v7_Prop) != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Resets certain MPCore CP15 values to their ARM-defined reset values.
 | 
			
		||||
@ -130,6 +127,8 @@ static void ResetMPCoreCP15Registers(ARMul_State* cpu)
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
void ARMul_Reset(ARMul_State* state)
 | 
			
		||||
{
 | 
			
		||||
    VFPInit(state);
 | 
			
		||||
 | 
			
		||||
    state->NextInstr = 0;
 | 
			
		||||
 | 
			
		||||
    state->Reg[15] = 0;
 | 
			
		||||
 | 
			
		||||
@ -55,18 +55,6 @@ typedef u16 ARMhword;  // must be 16 bits wide
 | 
			
		||||
typedef u8 ARMbyte;    // must be 8 bits wide
 | 
			
		||||
typedef struct ARMul_State ARMul_State;
 | 
			
		||||
 | 
			
		||||
typedef unsigned ARMul_CPInits(ARMul_State* state);
 | 
			
		||||
typedef unsigned ARMul_CPExits(ARMul_State* state);
 | 
			
		||||
typedef unsigned ARMul_LDCs(ARMul_State* state, unsigned type, ARMword instr, ARMword value);
 | 
			
		||||
typedef unsigned ARMul_STCs(ARMul_State* state, unsigned type, ARMword instr, ARMword* value);
 | 
			
		||||
typedef unsigned ARMul_MRCs(ARMul_State* state, unsigned type, ARMword instr, ARMword* value);
 | 
			
		||||
typedef unsigned ARMul_MCRs(ARMul_State* state, unsigned type, ARMword instr, ARMword value);
 | 
			
		||||
typedef unsigned ARMul_MRRCs(ARMul_State* state, unsigned type, ARMword instr, ARMword* value1, ARMword* value2);
 | 
			
		||||
typedef unsigned ARMul_MCRRs(ARMul_State* state, unsigned type, ARMword instr, ARMword value1, ARMword value2);
 | 
			
		||||
typedef unsigned ARMul_CDPs(ARMul_State* state, unsigned type, ARMword instr);
 | 
			
		||||
typedef unsigned ARMul_CPReads(ARMul_State* state, unsigned reg, ARMword* value);
 | 
			
		||||
typedef unsigned ARMul_CPWrites(ARMul_State* state, unsigned reg, ARMword value);
 | 
			
		||||
 | 
			
		||||
#define VFP_REG_NUM 64
 | 
			
		||||
struct ARMul_State
 | 
			
		||||
{
 | 
			
		||||
@ -117,20 +105,6 @@ struct ARMul_State
 | 
			
		||||
    unsigned NextInstr;
 | 
			
		||||
    unsigned VectorCatch;                   // Caught exception mask
 | 
			
		||||
 | 
			
		||||
    ARMul_CPInits* CPInit[16];              // Coprocessor initialisers
 | 
			
		||||
    ARMul_CPExits* CPExit[16];              // Coprocessor finalisers
 | 
			
		||||
    ARMul_LDCs* LDC[16];                    // LDC instruction
 | 
			
		||||
    ARMul_STCs* STC[16];                    // STC instruction
 | 
			
		||||
    ARMul_MRCs* MRC[16];                    // MRC instruction
 | 
			
		||||
    ARMul_MCRs* MCR[16];                    // MCR instruction
 | 
			
		||||
    ARMul_MRRCs* MRRC[16];                  // MRRC instruction
 | 
			
		||||
    ARMul_MCRRs* MCRR[16];                  // MCRR instruction
 | 
			
		||||
    ARMul_CDPs* CDP[16];                    // CDP instruction
 | 
			
		||||
    ARMul_CPReads* CPRead[16];              // Read CP register
 | 
			
		||||
    ARMul_CPWrites* CPWrite[16];            // Write CP register
 | 
			
		||||
    unsigned char* CPData[16];              // Coprocessor data
 | 
			
		||||
    unsigned char const* CPRegWords[16];    // Map of coprocessor register sizes
 | 
			
		||||
 | 
			
		||||
    unsigned NresetSig;                     // Reset the processor
 | 
			
		||||
    unsigned NfiqSig;
 | 
			
		||||
    unsigned NirqSig;
 | 
			
		||||
 | 
			
		||||
@ -57,12 +57,3 @@ enum {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define FLUSHPIPE state->NextInstr |= PRIMEPIPE
 | 
			
		||||
 | 
			
		||||
// Coprocessor support functions.
 | 
			
		||||
extern void ARMul_CoProInit(ARMul_State*);
 | 
			
		||||
extern void ARMul_CoProExit(ARMul_State*);
 | 
			
		||||
extern void ARMul_CoProAttach(ARMul_State*, unsigned, ARMul_CPInits*,
 | 
			
		||||
                              ARMul_CPExits*, ARMul_LDCs*, ARMul_STCs*,
 | 
			
		||||
                              ARMul_MRCs*, ARMul_MCRs*, ARMul_MRRCs*, ARMul_MCRRs*,
 | 
			
		||||
                              ARMul_CDPs*, ARMul_CPReads*, ARMul_CPWrites*);
 | 
			
		||||
extern void ARMul_CoProDetach(ARMul_State*, unsigned);
 | 
			
		||||
 | 
			
		||||
@ -37,296 +37,18 @@ unsigned VFPInit(ARMul_State* state)
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned VFPMRC(ARMul_State* state, unsigned type, u32 instr, u32* value)
 | 
			
		||||
void VMSR(ARMul_State* state, ARMword reg, ARMword Rt)
 | 
			
		||||
{
 | 
			
		||||
    /* MRC<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
 | 
			
		||||
    int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
 | 
			
		||||
    int OPC_1 = BITS(instr, 21, 23);
 | 
			
		||||
    int Rt = BITS(instr, 12, 15);
 | 
			
		||||
    int CRn = BITS(instr, 16, 19);
 | 
			
		||||
    int CRm = BITS(instr, 0, 3);
 | 
			
		||||
    int OPC_2 = BITS(instr, 5, 7);
 | 
			
		||||
 | 
			
		||||
    /* TODO check access permission */
 | 
			
		||||
 | 
			
		||||
    /* CRn/opc1 CRm/opc2 */
 | 
			
		||||
 | 
			
		||||
    if (CoProc == 10 || CoProc == 11)
 | 
			
		||||
    if (reg == 1)
 | 
			
		||||
    {
 | 
			
		||||
        if (OPC_1 == 0x0 && CRm == 0 && (OPC_2 & 0x3) == 0)
 | 
			
		||||
        {
 | 
			
		||||
            /* VMOV r to s */
 | 
			
		||||
            /* Transfering Rt is not mandatory, as the value of interest is pointed by value */
 | 
			
		||||
            VMOVBRS(state, BIT(instr, 20), Rt, BIT(instr, 7)|CRn<<1, value);
 | 
			
		||||
            return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (OPC_1 == 0x7 && CRm == 0 && OPC_2 == 0)
 | 
			
		||||
        {
 | 
			
		||||
            VMRS(state, CRn, Rt, value);
 | 
			
		||||
            return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
        state->VFP[VFP_FPSCR] = state->Reg[Rt];
 | 
			
		||||
    }
 | 
			
		||||
    LOG_WARNING(Core_ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n",
 | 
			
		||||
          instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2);
 | 
			
		||||
 | 
			
		||||
    return ARMul_CANT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned VFPMCR(ARMul_State* state, unsigned type, u32 instr, u32 value)
 | 
			
		||||
{
 | 
			
		||||
    /* MCR<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
 | 
			
		||||
    int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
 | 
			
		||||
    int OPC_1 = BITS(instr, 21, 23);
 | 
			
		||||
    int Rt = BITS(instr, 12, 15);
 | 
			
		||||
    int CRn = BITS(instr, 16, 19);
 | 
			
		||||
    int CRm = BITS(instr, 0, 3);
 | 
			
		||||
    int OPC_2 = BITS(instr, 5, 7);
 | 
			
		||||
 | 
			
		||||
    /* TODO check access permission */
 | 
			
		||||
 | 
			
		||||
    /* CRn/opc1 CRm/opc2 */
 | 
			
		||||
    if (CoProc == 10 || CoProc == 11)
 | 
			
		||||
    else if (reg == 8)
 | 
			
		||||
    {
 | 
			
		||||
        if (OPC_1 == 0x0 && CRm == 0 && (OPC_2 & 0x3) == 0)
 | 
			
		||||
        {
 | 
			
		||||
            /* VMOV s to r */
 | 
			
		||||
            /* Transfering Rt is not mandatory, as the value of interest is pointed by value */
 | 
			
		||||
            VMOVBRS(state, BIT(instr, 20), Rt, BIT(instr, 7)|CRn<<1, &value);
 | 
			
		||||
            return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (OPC_1 == 0x7 && CRm == 0 && OPC_2 == 0)
 | 
			
		||||
        {
 | 
			
		||||
            VMSR(state, CRn, Rt);
 | 
			
		||||
            return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ((OPC_1 & 0x4) == 0 && CoProc == 11 && CRm == 0)
 | 
			
		||||
        {
 | 
			
		||||
            VFP_DEBUG_UNIMPLEMENTED(VMOVBRC);
 | 
			
		||||
            return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (CoProc == 11 && CRm == 0)
 | 
			
		||||
        {
 | 
			
		||||
            VFP_DEBUG_UNIMPLEMENTED(VMOVBCR);
 | 
			
		||||
            return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
        state->VFP[VFP_FPEXC] = state->Reg[Rt];
 | 
			
		||||
    }
 | 
			
		||||
    LOG_WARNING(Core_ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n",
 | 
			
		||||
          instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2);
 | 
			
		||||
 | 
			
		||||
    return ARMul_CANT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned VFPMRRC(ARMul_State* state, unsigned type, u32 instr, u32* value1, u32* value2)
 | 
			
		||||
{
 | 
			
		||||
    /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
 | 
			
		||||
    int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
 | 
			
		||||
    int OPC_1 = BITS(instr, 4, 7);
 | 
			
		||||
    int Rt = BITS(instr, 12, 15);
 | 
			
		||||
    int Rt2 = BITS(instr, 16, 19);
 | 
			
		||||
    int CRm = BITS(instr, 0, 3);
 | 
			
		||||
 | 
			
		||||
    if (CoProc == 10 || CoProc == 11)
 | 
			
		||||
    {
 | 
			
		||||
        if (CoProc == 10 && (OPC_1 & 0xD) == 1)
 | 
			
		||||
        {
 | 
			
		||||
            VMOVBRRSS(state, BIT(instr, 20), Rt, Rt2, BIT(instr, 5)<<4|CRm, value1, value2);
 | 
			
		||||
            return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (CoProc == 11 && (OPC_1 & 0xD) == 1)
 | 
			
		||||
        {
 | 
			
		||||
            /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */
 | 
			
		||||
            VMOVBRRD(state, BIT(instr, 20), Rt, Rt2, BIT(instr, 5)<<4|CRm, value1, value2);
 | 
			
		||||
            return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    LOG_WARNING(Core_ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",
 | 
			
		||||
          instr, CoProc, OPC_1, Rt, Rt2, CRm);
 | 
			
		||||
 | 
			
		||||
    return ARMul_CANT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned VFPMCRR(ARMul_State* state, unsigned type, u32 instr, u32 value1, u32 value2)
 | 
			
		||||
{
 | 
			
		||||
    /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
 | 
			
		||||
    int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
 | 
			
		||||
    int OPC_1 = BITS(instr, 4, 7);
 | 
			
		||||
    int Rt = BITS(instr, 12, 15);
 | 
			
		||||
    int Rt2 = BITS(instr, 16, 19);
 | 
			
		||||
    int CRm = BITS(instr, 0, 3);
 | 
			
		||||
 | 
			
		||||
    /* TODO check access permission */
 | 
			
		||||
 | 
			
		||||
    /* CRn/opc1 CRm/opc2 */
 | 
			
		||||
 | 
			
		||||
    if (CoProc == 11 || CoProc == 10)
 | 
			
		||||
    {
 | 
			
		||||
        if (CoProc == 10 && (OPC_1 & 0xD) == 1)
 | 
			
		||||
        {
 | 
			
		||||
            VMOVBRRSS(state, BIT(instr, 20), Rt, Rt2, BIT(instr, 5)<<4|CRm, &value1, &value2);
 | 
			
		||||
            return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (CoProc == 11 && (OPC_1 & 0xD) == 1)
 | 
			
		||||
        {
 | 
			
		||||
            /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */
 | 
			
		||||
            VMOVBRRD(state, BIT(instr, 20), Rt, Rt2, BIT(instr, 5)<<4|CRm, &value1, &value2);
 | 
			
		||||
            return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    LOG_WARNING(Core_ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",
 | 
			
		||||
          instr, CoProc, OPC_1, Rt, Rt2, CRm);
 | 
			
		||||
 | 
			
		||||
    return ARMul_CANT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned VFPSTC(ARMul_State* state, unsigned type, u32 instr, u32 * value)
 | 
			
		||||
{
 | 
			
		||||
    /* STC{L}<c> <coproc>,<CRd>,[<Rn>],<option> */
 | 
			
		||||
    int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
 | 
			
		||||
    int CRd = BITS(instr, 12, 15);
 | 
			
		||||
    int Rn = BITS(instr, 16, 19);
 | 
			
		||||
    int imm8 = BITS(instr, 0, 7);
 | 
			
		||||
    int P = BIT(instr, 24);
 | 
			
		||||
    int U = BIT(instr, 23);
 | 
			
		||||
    int D = BIT(instr, 22);
 | 
			
		||||
    int W = BIT(instr, 21);
 | 
			
		||||
 | 
			
		||||
    /* TODO check access permission */
 | 
			
		||||
 | 
			
		||||
    /* VSTM */
 | 
			
		||||
    if ( (P|U|D|W) == 0 ) {
 | 
			
		||||
        LOG_ERROR(Core_ARM11, "In %s, UNDEFINED\n", __FUNCTION__);
 | 
			
		||||
        exit(-1);
 | 
			
		||||
    }
 | 
			
		||||
    if (CoProc == 10 || CoProc == 11) {
 | 
			
		||||
#if 1
 | 
			
		||||
        if (P == 0 && U == 0 && W == 0) {
 | 
			
		||||
            LOG_ERROR(Core_ARM11, "VSTM Related encodings\n");
 | 
			
		||||
            exit(-1);
 | 
			
		||||
        }
 | 
			
		||||
        if (P == U && W == 1) {
 | 
			
		||||
            LOG_ERROR(Core_ARM11, "UNDEFINED\n");
 | 
			
		||||
            exit(-1);
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        if (P == 1 && W == 0)
 | 
			
		||||
        {
 | 
			
		||||
            return VSTR(state, type, instr, value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (P == 1 && U == 0 && W == 1 && Rn == 0xD)
 | 
			
		||||
        {
 | 
			
		||||
            return VPUSH(state, type, instr, value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return VSTM(state, type, instr, value);
 | 
			
		||||
    }
 | 
			
		||||
    LOG_WARNING(Core_ARM11, "Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n",
 | 
			
		||||
          instr, CoProc, CRd, Rn, imm8, P, U, D, W);
 | 
			
		||||
 | 
			
		||||
    return ARMul_CANT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned VFPLDC(ARMul_State* state, unsigned type, u32 instr, u32 value)
 | 
			
		||||
{
 | 
			
		||||
    /* LDC{L}<c> <coproc>,<CRd>,[<Rn>] */
 | 
			
		||||
    int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
 | 
			
		||||
    int CRd = BITS(instr, 12, 15);
 | 
			
		||||
    int Rn = BITS(instr, 16, 19);
 | 
			
		||||
    int imm8 = BITS(instr, 0, 7);
 | 
			
		||||
    int P = BIT(instr, 24);
 | 
			
		||||
    int U = BIT(instr, 23);
 | 
			
		||||
    int D = BIT(instr, 22);
 | 
			
		||||
    int W = BIT(instr, 21);
 | 
			
		||||
 | 
			
		||||
    /* TODO check access permission */
 | 
			
		||||
 | 
			
		||||
    if ( (P|U|D|W) == 0 ) {
 | 
			
		||||
        LOG_ERROR(Core_ARM11, "In %s, UNDEFINED\n", __FUNCTION__);
 | 
			
		||||
        exit(-1);
 | 
			
		||||
    }
 | 
			
		||||
    if (CoProc == 10 || CoProc == 11)
 | 
			
		||||
    {
 | 
			
		||||
        if (P == 1 && W == 0)
 | 
			
		||||
        {
 | 
			
		||||
            return VLDR(state, type, instr, value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (P == 0 && U == 1 && W == 1 && Rn == 0xD)
 | 
			
		||||
        {
 | 
			
		||||
            return VPOP(state, type, instr, value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return VLDM(state, type, instr, value);
 | 
			
		||||
    }
 | 
			
		||||
    LOG_WARNING(Core_ARM11, "Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n",
 | 
			
		||||
          instr, CoProc, CRd, Rn, imm8, P, U, D, W);
 | 
			
		||||
 | 
			
		||||
    return ARMul_CANT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned VFPCDP(ARMul_State* state, unsigned type, u32 instr)
 | 
			
		||||
{
 | 
			
		||||
    /* CDP<c> <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> */
 | 
			
		||||
    int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
 | 
			
		||||
    int OPC_1 = BITS(instr, 20, 23);
 | 
			
		||||
    int CRd = BITS(instr, 12, 15);
 | 
			
		||||
    int CRn = BITS(instr, 16, 19);
 | 
			
		||||
    int CRm = BITS(instr, 0, 3);
 | 
			
		||||
    int OPC_2 = BITS(instr, 5, 7);
 | 
			
		||||
 | 
			
		||||
    /* TODO check access permission */
 | 
			
		||||
 | 
			
		||||
    /* CRn/opc1 CRm/opc2 */
 | 
			
		||||
 | 
			
		||||
    if (CoProc == 10 || CoProc == 11)
 | 
			
		||||
    {
 | 
			
		||||
        if ((OPC_1 & 0xB) == 0xB && BITS(instr, 4, 7) == 0)
 | 
			
		||||
        {
 | 
			
		||||
            unsigned int single = BIT(instr, 8) == 0;
 | 
			
		||||
            unsigned int d      = (single ? BITS(instr, 12,15)<<1 | BIT(instr, 22) : BITS(instr, 12,15) | BIT(instr, 22)<<4);
 | 
			
		||||
            unsigned int imm;
 | 
			
		||||
            instr = BITS(instr, 16, 19) << 4 | BITS(instr, 0, 3); // FIXME dirty workaround to get a correct imm
 | 
			
		||||
 | 
			
		||||
            if (single)
 | 
			
		||||
                imm = BIT(instr, 7)<<31 | (BIT(instr, 6)==0)<<30 | (BIT(instr, 6) ? 0x1f : 0)<<25 | BITS(instr, 0, 5)<<19;
 | 
			
		||||
            else
 | 
			
		||||
                imm = BIT(instr, 7)<<31 | (BIT(instr, 6)==0)<<30 | (BIT(instr, 6) ? 0xff : 0)<<22 | BITS(instr, 0, 5)<<16;
 | 
			
		||||
 | 
			
		||||
            VMOVI(state, single, d, imm);
 | 
			
		||||
            return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x6) == 0x2)
 | 
			
		||||
        {
 | 
			
		||||
            unsigned int single = BIT(instr, 8) == 0;
 | 
			
		||||
            unsigned int d      = (single ? BITS(instr, 12,15)<<1 | BIT(instr, 22) : BITS(instr, 12,15) | BIT(instr, 22)<<4);
 | 
			
		||||
            unsigned int m      = (single ? BITS(instr,  0, 3)<<1 | BIT(instr,  5) : BITS(instr,  0, 3) | BIT(instr, 5)<<4);
 | 
			
		||||
            VMOVR(state, single, d, m);
 | 
			
		||||
            return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int exceptions = 0;
 | 
			
		||||
        if (CoProc == 10)
 | 
			
		||||
            exceptions = vfp_single_cpdo(state, instr, state->VFP[VFP_FPSCR]);
 | 
			
		||||
        else
 | 
			
		||||
            exceptions = vfp_double_cpdo(state, instr, state->VFP[VFP_FPSCR]);
 | 
			
		||||
 | 
			
		||||
        vfp_raise_exceptions(state, exceptions, instr, state->VFP[VFP_FPSCR]);
 | 
			
		||||
 | 
			
		||||
        return ARMul_DONE;
 | 
			
		||||
    }
 | 
			
		||||
    LOG_WARNING(Core_ARM11, "Can't identify %x\n", instr);
 | 
			
		||||
    return ARMul_CANT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------- MRC ------------ */
 | 
			
		||||
void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* value)
 | 
			
		||||
{
 | 
			
		||||
    if (to_arm)
 | 
			
		||||
@ -338,43 +60,7 @@ void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword*
 | 
			
		||||
        state->ExtReg[n] = *value;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
void VMRS(ARMul_State* state, ARMword reg, ARMword Rt, ARMword* value)
 | 
			
		||||
{
 | 
			
		||||
    if (reg == 1)
 | 
			
		||||
    {
 | 
			
		||||
        if (Rt != 15)
 | 
			
		||||
        {
 | 
			
		||||
            *value = state->VFP[VFP_FPSCR];
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            *value = state->VFP[VFP_FPSCR] ;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        switch (reg)
 | 
			
		||||
        {
 | 
			
		||||
            case 0:
 | 
			
		||||
                *value = state->VFP[VFP_FPSID];
 | 
			
		||||
                break;
 | 
			
		||||
            case 6:
 | 
			
		||||
                /* MVFR1, VFPv3 only ? */
 | 
			
		||||
                LOG_TRACE(Core_ARM11, "\tr%d <= MVFR1 unimplemented\n", Rt);
 | 
			
		||||
                break;
 | 
			
		||||
            case 7:
 | 
			
		||||
                /* MVFR0, VFPv3 only? */
 | 
			
		||||
                LOG_TRACE(Core_ARM11, "\tr%d <= MVFR0 unimplemented\n", Rt);
 | 
			
		||||
                break;
 | 
			
		||||
            case 8:
 | 
			
		||||
                *value = state->VFP[VFP_FPEXC];
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                LOG_TRACE(Core_ARM11, "\tSUBARCHITECTURE DEFINED\n");
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2)
 | 
			
		||||
{
 | 
			
		||||
    if (to_arm)
 | 
			
		||||
@ -402,301 +88,6 @@ void VMOVBRRSS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMwor
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------- MCR ------------ */
 | 
			
		||||
void VMSR(ARMul_State* state, ARMword reg, ARMword Rt)
 | 
			
		||||
{
 | 
			
		||||
    if (reg == 1)
 | 
			
		||||
    {
 | 
			
		||||
        state->VFP[VFP_FPSCR] = state->Reg[Rt];
 | 
			
		||||
    }
 | 
			
		||||
    else if (reg == 8)
 | 
			
		||||
    {
 | 
			
		||||
        state->VFP[VFP_FPEXC] = state->Reg[Rt];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Memory operation are not inlined, as old Interpreter and Fast interpreter
 | 
			
		||||
   don't have the same memory operation interface.
 | 
			
		||||
   Old interpreter framework does one access to coprocessor per data, and
 | 
			
		||||
   handles already data write, as well as address computation,
 | 
			
		||||
   which is not the case for Fast interpreter. Therefore, implementation
 | 
			
		||||
   of vfp instructions in old interpreter and fast interpreter are separate. */
 | 
			
		||||
 | 
			
		||||
/* ----------- STC ------------ */
 | 
			
		||||
int VSTR(ARMul_State* state, int type, ARMword instr, ARMword* value)
 | 
			
		||||
{
 | 
			
		||||
    static int i = 0;
 | 
			
		||||
    static int single_reg, add, d, n, imm32, regs;
 | 
			
		||||
    if (type == ARMul_FIRST)
 | 
			
		||||
    {
 | 
			
		||||
        single_reg = BIT(instr, 8) == 0; // Double precision
 | 
			
		||||
        add = BIT(instr, 23);
 | 
			
		||||
        imm32 = BITS(instr, 0,7)<<2; // may not be used
 | 
			
		||||
        d = single_reg ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); /* Base register */
 | 
			
		||||
        n = BITS(instr, 16, 19); // destination register
 | 
			
		||||
 | 
			
		||||
        i = 0;
 | 
			
		||||
        regs = 1;
 | 
			
		||||
 | 
			
		||||
        return ARMul_DONE;
 | 
			
		||||
    }
 | 
			
		||||
    else if (type == ARMul_DATA)
 | 
			
		||||
    {
 | 
			
		||||
        if (single_reg)
 | 
			
		||||
        {
 | 
			
		||||
            *value = state->ExtReg[d+i];
 | 
			
		||||
            i++;
 | 
			
		||||
            if (i < regs)
 | 
			
		||||
                return ARMul_INC;
 | 
			
		||||
            else
 | 
			
		||||
                return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            /* FIXME Careful of endianness, may need to rework this */
 | 
			
		||||
            *value = state->ExtReg[d*2+i];
 | 
			
		||||
            i++;
 | 
			
		||||
            if (i < regs*2)
 | 
			
		||||
                return ARMul_INC;
 | 
			
		||||
            else
 | 
			
		||||
                return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
int VPUSH(ARMul_State* state, int type, ARMword instr, ARMword* value)
 | 
			
		||||
{
 | 
			
		||||
    static int i = 0;
 | 
			
		||||
    static int single_regs, d, imm32, regs;
 | 
			
		||||
    if (type == ARMul_FIRST)
 | 
			
		||||
    {
 | 
			
		||||
        single_regs = BIT(instr, 8) == 0; // Single precision
 | 
			
		||||
        d = single_regs ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register
 | 
			
		||||
        imm32 = BITS(instr, 0,7)<<2; // may not be used
 | 
			
		||||
        regs = single_regs ? BITS(instr, 0, 7) : BITS(instr, 1, 7); // FSTMX if regs is odd
 | 
			
		||||
 | 
			
		||||
        state->Reg[R13] = state->Reg[R13] - imm32;
 | 
			
		||||
 | 
			
		||||
        i = 0;
 | 
			
		||||
 | 
			
		||||
        return ARMul_DONE;
 | 
			
		||||
    }
 | 
			
		||||
    else if (type == ARMul_DATA)
 | 
			
		||||
    {
 | 
			
		||||
        if (single_regs)
 | 
			
		||||
        {
 | 
			
		||||
            *value = state->ExtReg[d + i];
 | 
			
		||||
            i++;
 | 
			
		||||
            if (i < regs)
 | 
			
		||||
                return ARMul_INC;
 | 
			
		||||
            else
 | 
			
		||||
                return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            /* FIXME Careful of endianness, may need to rework this */
 | 
			
		||||
            *value = state->ExtReg[d*2 + i];
 | 
			
		||||
            i++;
 | 
			
		||||
            if (i < regs*2)
 | 
			
		||||
                return ARMul_INC;
 | 
			
		||||
            else
 | 
			
		||||
                return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
int VSTM(ARMul_State* state, int type, ARMword instr, ARMword* value)
 | 
			
		||||
{
 | 
			
		||||
    static int i = 0;
 | 
			
		||||
    static int single_regs, add, wback, d, n, imm32, regs;
 | 
			
		||||
    if (type == ARMul_FIRST)
 | 
			
		||||
    {
 | 
			
		||||
        single_regs = BIT(instr, 8) == 0; // Single precision
 | 
			
		||||
        add = BIT(instr, 23);
 | 
			
		||||
        wback = BIT(instr, 21); // write-back
 | 
			
		||||
        d = single_regs ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register
 | 
			
		||||
        n = BITS(instr, 16, 19); // destination register
 | 
			
		||||
        imm32 = BITS(instr, 0,7) * 4; // may not be used
 | 
			
		||||
        regs = single_regs ? BITS(instr, 0, 7) : BITS(instr, 0, 7)>>1; // FSTMX if regs is odd
 | 
			
		||||
 | 
			
		||||
        if (wback) {
 | 
			
		||||
            state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        i = 0;
 | 
			
		||||
 | 
			
		||||
        return ARMul_DONE;
 | 
			
		||||
    }
 | 
			
		||||
    else if (type == ARMul_DATA)
 | 
			
		||||
    {
 | 
			
		||||
        if (single_regs)
 | 
			
		||||
        {
 | 
			
		||||
            *value = state->ExtReg[d + i];
 | 
			
		||||
            i++;
 | 
			
		||||
            if (i < regs)
 | 
			
		||||
                return ARMul_INC;
 | 
			
		||||
            else
 | 
			
		||||
                return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            /* FIXME Careful of endianness, may need to rework this */
 | 
			
		||||
            *value = state->ExtReg[d*2 + i];
 | 
			
		||||
            i++;
 | 
			
		||||
            if (i < regs*2)
 | 
			
		||||
                return ARMul_INC;
 | 
			
		||||
            else
 | 
			
		||||
                return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------- LDC ------------ */
 | 
			
		||||
int VPOP(ARMul_State* state, int type, ARMword instr, ARMword value)
 | 
			
		||||
{
 | 
			
		||||
    static int i = 0;
 | 
			
		||||
    static int single_regs, d, imm32, regs;
 | 
			
		||||
    if (type == ARMul_FIRST)
 | 
			
		||||
    {
 | 
			
		||||
        single_regs = BIT(instr, 8) == 0; // Single precision
 | 
			
		||||
        d = single_regs ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register
 | 
			
		||||
        imm32 = BITS(instr, 0, 7)<<2; // may not be used
 | 
			
		||||
        regs = single_regs ? BITS(instr, 0, 7) : BITS(instr, 1, 7); // FLDMX if regs is odd
 | 
			
		||||
 | 
			
		||||
        state->Reg[R13] = state->Reg[R13] + imm32;
 | 
			
		||||
 | 
			
		||||
        i = 0;
 | 
			
		||||
 | 
			
		||||
        return ARMul_DONE;
 | 
			
		||||
    }
 | 
			
		||||
    else if (type == ARMul_TRANSFER)
 | 
			
		||||
    {
 | 
			
		||||
        return ARMul_DONE;
 | 
			
		||||
    }
 | 
			
		||||
    else if (type == ARMul_DATA)
 | 
			
		||||
    {
 | 
			
		||||
        if (single_regs)
 | 
			
		||||
        {
 | 
			
		||||
            state->ExtReg[d + i] = value;
 | 
			
		||||
            i++;
 | 
			
		||||
            if (i < regs)
 | 
			
		||||
                return ARMul_INC;
 | 
			
		||||
            else
 | 
			
		||||
                return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            /* FIXME Careful of endianness, may need to rework this */
 | 
			
		||||
            state->ExtReg[d*2 + i] = value;
 | 
			
		||||
            i++;
 | 
			
		||||
            if (i < regs*2)
 | 
			
		||||
                return ARMul_INC;
 | 
			
		||||
            else
 | 
			
		||||
                return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
int VLDR(ARMul_State* state, int type, ARMword instr, ARMword value)
 | 
			
		||||
{
 | 
			
		||||
    static int i = 0;
 | 
			
		||||
    static int single_reg, add, d, n, imm32, regs;
 | 
			
		||||
    if (type == ARMul_FIRST)
 | 
			
		||||
    {
 | 
			
		||||
        single_reg = BIT(instr, 8) == 0; // Double precision
 | 
			
		||||
        add = BIT(instr, 23);
 | 
			
		||||
        imm32 = BITS(instr, 0, 7)<<2; // may not be used
 | 
			
		||||
        d = single_reg ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register
 | 
			
		||||
        n = BITS(instr, 16, 19); // destination register
 | 
			
		||||
 | 
			
		||||
        i = 0;
 | 
			
		||||
        regs = 1;
 | 
			
		||||
 | 
			
		||||
        return ARMul_DONE;
 | 
			
		||||
    }
 | 
			
		||||
    else if (type == ARMul_TRANSFER)
 | 
			
		||||
    {
 | 
			
		||||
        return ARMul_DONE;
 | 
			
		||||
    }
 | 
			
		||||
    else if (type == ARMul_DATA)
 | 
			
		||||
    {
 | 
			
		||||
        if (single_reg)
 | 
			
		||||
        {
 | 
			
		||||
            state->ExtReg[d+i] = value;
 | 
			
		||||
            i++;
 | 
			
		||||
            if (i < regs)
 | 
			
		||||
                return ARMul_INC;
 | 
			
		||||
            else
 | 
			
		||||
                return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            /* FIXME Careful of endianness, may need to rework this */
 | 
			
		||||
            state->ExtReg[d*2+i] = value;
 | 
			
		||||
            i++;
 | 
			
		||||
            if (i < regs*2)
 | 
			
		||||
                return ARMul_INC;
 | 
			
		||||
            else
 | 
			
		||||
                return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
int VLDM(ARMul_State* state, int type, ARMword instr, ARMword value)
 | 
			
		||||
{
 | 
			
		||||
    static int i = 0;
 | 
			
		||||
    static int single_regs, add, wback, d, n, imm32, regs;
 | 
			
		||||
    if (type == ARMul_FIRST)
 | 
			
		||||
    {
 | 
			
		||||
        single_regs = BIT(instr, 8) == 0; // Single precision
 | 
			
		||||
        add = BIT(instr, 23);
 | 
			
		||||
        wback = BIT(instr, 21); // write-back
 | 
			
		||||
        d = single_regs ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register
 | 
			
		||||
        n = BITS(instr, 16, 19); // destination register
 | 
			
		||||
        imm32 = BITS(instr, 0, 7) * 4; // may not be used
 | 
			
		||||
        regs = single_regs ? BITS(instr, 0, 7) : BITS(instr, 0, 7)>>1; // FLDMX if regs is odd
 | 
			
		||||
 | 
			
		||||
        if (wback) {
 | 
			
		||||
            state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        i = 0;
 | 
			
		||||
 | 
			
		||||
        return ARMul_DONE;
 | 
			
		||||
    }
 | 
			
		||||
    else if (type == ARMul_DATA)
 | 
			
		||||
    {
 | 
			
		||||
        if (single_regs)
 | 
			
		||||
        {
 | 
			
		||||
            state->ExtReg[d + i] = value;
 | 
			
		||||
            i++;
 | 
			
		||||
            if (i < regs)
 | 
			
		||||
                return ARMul_INC;
 | 
			
		||||
            else
 | 
			
		||||
                return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            /* FIXME Careful of endianness, may need to rework this */
 | 
			
		||||
            state->ExtReg[d*2 + i] = value;
 | 
			
		||||
            i++;
 | 
			
		||||
            if (i < regs*2)
 | 
			
		||||
                return ARMul_INC;
 | 
			
		||||
            else
 | 
			
		||||
                return ARMul_DONE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------- CDP ------------ */
 | 
			
		||||
void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm)
 | 
			
		||||
{
 | 
			
		||||
    if (single)
 | 
			
		||||
 | 
			
		||||
@ -28,13 +28,6 @@
 | 
			
		||||
#define CHECK_VFP_CDP_RET vfp_raise_exceptions(cpu, ret, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
 | 
			
		||||
 | 
			
		||||
unsigned VFPInit(ARMul_State* state);
 | 
			
		||||
unsigned VFPMRC(ARMul_State* state, unsigned type, ARMword instr, ARMword* value);
 | 
			
		||||
unsigned VFPMCR(ARMul_State* state, unsigned type, ARMword instr, ARMword value);
 | 
			
		||||
unsigned VFPMRRC(ARMul_State* state, unsigned type, ARMword instr, ARMword* value1, ARMword* value2);
 | 
			
		||||
unsigned VFPMCRR(ARMul_State* state, unsigned type, ARMword instr, ARMword value1, ARMword value2);
 | 
			
		||||
unsigned VFPSTC(ARMul_State* state, unsigned type, ARMword instr, ARMword* value);
 | 
			
		||||
unsigned VFPLDC(ARMul_State* state, unsigned type, ARMword instr, ARMword value);
 | 
			
		||||
unsigned VFPCDP(ARMul_State* state, unsigned type, ARMword instr);
 | 
			
		||||
 | 
			
		||||
s32 vfp_get_float(ARMul_State* state, u32 reg);
 | 
			
		||||
void vfp_put_float(ARMul_State* state, s32 val, u32 reg);
 | 
			
		||||
@ -44,23 +37,10 @@ void vfp_raise_exceptions(ARMul_State* state, u32 exceptions, u32 inst, u32 fpsc
 | 
			
		||||
u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr);
 | 
			
		||||
u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr);
 | 
			
		||||
 | 
			
		||||
// MRC
 | 
			
		||||
void VMRS(ARMul_State* state, ARMword reg, ARMword Rt, ARMword* value);
 | 
			
		||||
void VMSR(ARMul_State* state, ARMword reg, ARMword Rt);
 | 
			
		||||
void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* value);
 | 
			
		||||
void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2);
 | 
			
		||||
void VMOVBRRSS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2);
 | 
			
		||||
void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm);
 | 
			
		||||
void VMOVR(ARMul_State* state, ARMword single, ARMword d, ARMword imm);
 | 
			
		||||
 | 
			
		||||
// MCR
 | 
			
		||||
void VMSR(ARMul_State* state, ARMword reg, ARMword Rt);
 | 
			
		||||
 | 
			
		||||
// STC
 | 
			
		||||
int VSTM(ARMul_State* state, int type, ARMword instr, ARMword* value);
 | 
			
		||||
int VPUSH(ARMul_State* state, int type, ARMword instr, ARMword* value);
 | 
			
		||||
int VSTR(ARMul_State* state, int type, ARMword instr, ARMword* value);
 | 
			
		||||
 | 
			
		||||
// LDC
 | 
			
		||||
int VLDM(ARMul_State* state, int type, ARMword instr, ARMword value);
 | 
			
		||||
int VPOP(ARMul_State* state, int type, ARMword instr, ARMword value);
 | 
			
		||||
int VLDR(ARMul_State* state, int type, ARMword instr, ARMword value);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user