diff options
Diffstat (limited to 'src/core/arm')
| -rw-r--r-- | src/core/arm/disassembler/arm_disasm.cpp | 2 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom.cpp | 2 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 39 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_thumb.cpp | 102 | ||||
| -rw-r--r-- | src/core/arm/interpreter/arminit.cpp | 1 | ||||
| -rw-r--r-- | src/core/arm/interpreter/armsupp.cpp | 2 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/arm_regformat.h | 2 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/armdefs.h | 34 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/armemu.h | 47 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfp.cpp | 4 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfp.h | 1 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfp_helper.h | 4 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfpinstr.cpp | 18 |
13 files changed, 140 insertions, 118 deletions
diff --git a/src/core/arm/disassembler/arm_disasm.cpp b/src/core/arm/disassembler/arm_disasm.cpp index 913dc1454..f6d44d85a 100644 --- a/src/core/arm/disassembler/arm_disasm.cpp +++ b/src/core/arm/disassembler/arm_disasm.cpp @@ -813,7 +813,7 @@ Opcode ARM_Disasm::Decode11(uint32_t insn) { // SWI return OP_SWI; } - + uint8_t bit4 = (insn >> 4) & 0x1; uint8_t cpnum = (insn >> 8) & 0xf; diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index 0072ae533..529c4ac70 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp @@ -6,7 +6,7 @@ #include "common/make_unique.h" -#include "core/arm/skyeye_common/armemu.h" +#include "core/arm/skyeye_common/armdefs.h" #include "core/arm/skyeye_common/vfp/vfp.h" #include "core/arm/dyncom/arm_dyncom.h" diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index e4b5486e0..b00eb49a9 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp @@ -134,7 +134,7 @@ static unsigned int DPO(Immediate)(ARMul_State* cpu, unsigned int sht_oper) { unsigned int immed_8 = BITS(sht_oper, 0, 7); unsigned int rotate_imm = BITS(sht_oper, 8, 11); unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2); - if (rotate_imm == 0) + if (rotate_imm == 0) cpu->shifter_carry_out = cpu->CFlag; else cpu->shifter_carry_out = BIT(shifter_operand, 31); @@ -521,7 +521,7 @@ static void MLnS(ImmediateOffset)(ARMul_State* cpu, unsigned int inst, unsigned addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8; else addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8; - + virt_addr = addr; } @@ -550,7 +550,7 @@ static void MLnS(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst, unsig if (U_BIT) addr = rn + offset_8; - else + else addr = rn - offset_8; virt_addr = addr; @@ -1306,8 +1306,8 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index) inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); inst_cream->shtop_func = get_shtop(inst); - - if (inst_cream->Rd == 15) + + if (inst_cream->Rd == 15) inst_base->br = INDIRECT_BRANCH; return inst_base; @@ -1350,7 +1350,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index) inst_cream->shifter_operand = BITS(inst, 0, 11); inst_cream->shtop_func = get_shtop(inst); - if (inst_cream->Rd == 15) + if (inst_cream->Rd == 15) inst_base->br = INDIRECT_BRANCH; return inst_base; } @@ -3269,7 +3269,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(yield)(unsigned int inst, int index) #define VFP_INTERPRETER_STRUCT #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" #undef VFP_INTERPRETER_STRUCT - + #define VFP_INTERPRETER_TRANS #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" #undef VFP_INTERPRETER_TRANS @@ -3478,9 +3478,9 @@ const transop_fp_t arm_instruction_trans[] = { INTERPRETER_TRANSLATE(bbl), // All the thumb instructions should be placed the end of table - INTERPRETER_TRANSLATE(b_2_thumb), - INTERPRETER_TRANSLATE(b_cond_thumb), - INTERPRETER_TRANSLATE(bl_1_thumb), + INTERPRETER_TRANSLATE(b_2_thumb), + INTERPRETER_TRANSLATE(b_cond_thumb), + INTERPRETER_TRANSLATE(bl_1_thumb), INTERPRETER_TRANSLATE(bl_2_thumb), INTERPRETER_TRANSLATE(blx_1_thumb) }; @@ -3564,17 +3564,13 @@ static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) { unsigned int inst, inst_size = 4; int idx; int ret = NON_BRANCH; - int thumb = 0; int size = 0; // instruction size of basic block bb_start = top; - if (cpu->TFlag) - thumb = THUMB; - u32 phys_addr = addr; u32 pc_start = cpu->Reg[15]; - while(ret == NON_BRANCH) { + while (ret == NON_BRANCH) { inst = Memory::Read32(phys_addr & 0xFFFFFFFC); size++; @@ -3890,7 +3886,6 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE) #define PC (cpu->Reg[15]) - #define CHECK_EXT_INT if (!cpu->NirqSig && !(cpu->Cpsr & 0x80)) goto END; // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback // to a clunky switch statement. @@ -4343,7 +4338,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { } } if (BIT(inst, 13)) { - if (cpu->Mode == USER32MODE) + if (cpu->Mode == USER32MODE) cpu->Reg[13] = ReadMemory32(cpu, addr); else cpu->Reg_usr[0] = ReadMemory32(cpu, addr); @@ -4351,7 +4346,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { addr += 4; } if (BIT(inst, 14)) { - if (cpu->Mode == USER32MODE) + if (cpu->Mode == USER32MODE) cpu->Reg[14] = ReadMemory32(cpu, addr); else cpu->Reg_usr[1] = ReadMemory32(cpu, addr); @@ -5153,7 +5148,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { REV16_INST: REVSH_INST: { - + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { rev_inst* const inst_cream = (rev_inst*)inst_base->component; @@ -5726,7 +5721,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { if (do_swap) rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16)); - + const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF); const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF); s64 result; @@ -6588,7 +6583,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { { u32 lo_val = 0; u32 hi_val = 0; - + // UHADD16 if (op2 == 0x00) { lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF); @@ -6777,7 +6772,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { u16 lo_val = 0; u16 hi_val = 0; - + // UQADD16 if (op2 == 0x00) { lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF); diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp index 08b5c0b77..3e79c44c0 100644 --- a/src/core/arm/dyncom/arm_dyncom_thumb.cpp +++ b/src/core/arm/dyncom/arm_dyncom_thumb.cpp @@ -184,38 +184,27 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { case 9: // LDR Rd,[PC,#imm8] *ainstr = 0xE59F0000 // base | ((tinstr & 0x0700) << (12 - 8)) // Rd - |((tinstr & 0x00FF) << (2 - 0)); // off8 + |((tinstr & 0x00FF) << (2 - 0)); // off8 break; case 10: case 11: - // TODO: Format 7 and Format 8 perform the same ARM encoding, so the following could be - // merged into a single subset, saving on the following boolean: - - if ((tinstr & (1 << 9)) == 0) { - static const ARMword subset[4] = { - 0xE7800000, // STR Rd,[Rb,Ro] - 0xE7C00000, // STRB Rd,[Rb,Ro] - 0xE7900000, // LDR Rd,[Rb,Ro] - 0xE7D00000 // LDRB Rd,[Rb,Ro] - }; - - *ainstr = subset[(tinstr & 0x0C00) >> 10] // base - |((tinstr & 0x0007) << (12 - 0)) // Rd - |((tinstr & 0x0038) << (16 - 3)) // Rb - |((tinstr & 0x01C0) >> 6); // Ro - - } else { - static const ARMword subset[4] = { + { + static const ARMword subset[8] = { + 0xE7800000, // STR Rd,[Rb,Ro] 0xE18000B0, // STRH Rd,[Rb,Ro] + 0xE7C00000, // STRB Rd,[Rb,Ro] 0xE19000D0, // LDRSB Rd,[Rb,Ro] + 0xE7900000, // LDR Rd,[Rb,Ro] 0xE19000B0, // LDRH Rd,[Rb,Ro] + 0xE7D00000, // LDRB Rd,[Rb,Ro] 0xE19000F0 // LDRSH Rd,[Rb,Ro] }; - *ainstr = subset[(tinstr & 0x0C00) >> 10] // base - |((tinstr & 0x0007) << (12 - 0)) // Rd - |((tinstr & 0x0038) << (16 - 3)) // Rb - |((tinstr & 0x01C0) >> 6); // Ro + + *ainstr = subset[(tinstr & 0xE00) >> 9] // base + |((tinstr & 0x0007) << (12 - 0)) // Rd + |((tinstr & 0x0038) << (16 - 3)) // Rb + |((tinstr & 0x01C0) >> 6); // Ro } break; @@ -285,9 +274,46 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { ? 0xE24DDF00 // SUB : 0xE28DDF00) // ADD |(tinstr & 0x007F); // off7 - } else if ((tinstr & 0x0F00) == 0x0e00) - *ainstr = 0xEF000000 | 0x180000; // base | BKPT mask - else { + } else if ((tinstr & 0x0F00) == 0x0e00) { + // BKPT + *ainstr = 0xEF000000 // base + | BITS(tinstr, 0, 3) // imm4 field; + | (BITS(tinstr, 4, 7) << 8); // beginning 4 bits of imm12 + } else if ((tinstr & 0x0F00) == 0x0200) { + static const ARMword subset[4] = { + 0xE6BF0070, // SXTH + 0xE6AF0070, // SXTB + 0xE6FF0070, // UXTH + 0xE6EF0070, // UXTB + }; + + *ainstr = subset[BITS(tinstr, 6, 7)] // base + | (BITS(tinstr, 0, 2) << 12) // Rd + | BITS(tinstr, 3, 5); // Rm + } else if ((tinstr & 0x0F00) == 0x600) { + if (BIT(tinstr, 5) == 0) { + // SETEND + *ainstr = 0xF1010000 // base + | (BIT(tinstr, 3) << 9); // endian specifier + } else { + // CPS + *ainstr = 0xF1080000 // base + | (BIT(tinstr, 0) << 6) // fiq bit + | (BIT(tinstr, 1) << 7) // irq bit + | (BIT(tinstr, 2) << 8) // abort bit + | (BIT(tinstr, 4) << 18); // enable bit + } + } else if ((tinstr & 0x0F00) == 0x0a00) { + static const ARMword subset[3] = { + 0xE6BF0F30, // REV + 0xE6BF0FB0, // REV16 + 0xE6FF0FB0, // REVSH + }; + + *ainstr = subset[BITS(tinstr, 6, 7)] // base + | (BITS(tinstr, 0, 2) << 12) // Rd + | BITS(tinstr, 3, 5); // Rm + } else { static const ARMword subset[4] = { 0xE92D0000, // STMDB sp!,{rlist} 0xE92D4000, // STMDB sp!,{rlist,lr} @@ -301,11 +327,25 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { case 24: // STMIA case 25: // LDMIA - *ainstr = ((tinstr & (1 << 11)) // base - ? 0xE8B00000 // LDMIA - : 0xE8A00000) // STMIA - |((tinstr & 0x0700) << (16 - 8)) // Rb - |(tinstr & 0x00FF); // mask8 + if (tinstr & (1 << 11)) + { + unsigned int base = 0xE8900000; + unsigned int rn = BITS(tinstr, 8, 10); + + // Writeback + if ((tinstr & (1 << rn)) == 0) + base |= (1 << 21); + + *ainstr = base // base (LDMIA) + | (rn << 16) // Rn + | (tinstr & 0x00FF); // Register list + } + else + { + *ainstr = 0xE8A00000 // base (STMIA) + | (BITS(tinstr, 8, 10) << 16) // Rn + | (tinstr & 0x00FF); // Register list + } break; case 26: // Bcc diff --git a/src/core/arm/interpreter/arminit.cpp b/src/core/arm/interpreter/arminit.cpp index 680a94a39..4f7a48fab 100644 --- a/src/core/arm/interpreter/arminit.cpp +++ b/src/core/arm/interpreter/arminit.cpp @@ -17,7 +17,6 @@ #include <cstring> #include "core/arm/skyeye_common/armdefs.h" -#include "core/arm/skyeye_common/armemu.h" #include "core/arm/skyeye_common/vfp/vfp.h" /***************************************************************************\ diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp index 1b078dc71..83f7f3e2c 100644 --- a/src/core/arm/interpreter/armsupp.cpp +++ b/src/core/arm/interpreter/armsupp.cpp @@ -628,7 +628,7 @@ void WriteCP15Register(ARMul_State* cpu, u32 value, u32 crn, u32 opcode_1, u32 c cpu->CP15[CP15_DATA_SYNC_BARRIER] = value; else if (opcode_2 == 5) cpu->CP15[CP15_DATA_MEMORY_BARRIER] = value; - + } else if (crn == 13 && opcode_1 == 0 && crm == 0 && opcode_2 == 2) { diff --git a/src/core/arm/skyeye_common/arm_regformat.h b/src/core/arm/skyeye_common/arm_regformat.h index 6c89774eb..a92effbb4 100644 --- a/src/core/arm/skyeye_common/arm_regformat.h +++ b/src/core/arm/skyeye_common/arm_regformat.h @@ -59,6 +59,8 @@ enum { VFP_FPSID, VFP_FPSCR, VFP_FPEXC, + VFP_MVFR0, + VFP_MVFR1, // Not an actual register. // All VFP system registers should be defined above this. diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h index 470f9508d..d2c901100 100644 --- a/src/core/arm/skyeye_common/armdefs.h +++ b/src/core/arm/skyeye_common/armdefs.h @@ -1,16 +1,16 @@ /* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator. Copyright (C) 1994 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. */ @@ -262,6 +262,34 @@ enum ConditionCode { NV = 15, }; +// Flags for use with the APSR. +enum : u32 { + NBIT = (1U << 31U), + ZBIT = (1 << 30), + CBIT = (1 << 29), + VBIT = (1 << 28), + QBIT = (1 << 27), + JBIT = (1 << 24), + EBIT = (1 << 9), + ABIT = (1 << 8), + IBIT = (1 << 7), + FBIT = (1 << 6), + TBIT = (1 << 5), + + // Masks for groups of bits in the APSR. + MODEBITS = 0x1F, + INTBITS = 0x1C0, +}; + +// Values for Emulate. +enum { + STOP = 0, // Stop + CHANGEMODE = 1, // Change mode + ONCE = 2, // Execute just one iteration + RUN = 3 // Continuous execution +}; + + extern bool AddOverflow(ARMword, ARMword, ARMword); extern bool SubOverflow(ARMword, ARMword, ARMword); diff --git a/src/core/arm/skyeye_common/armemu.h b/src/core/arm/skyeye_common/armemu.h deleted file mode 100644 index 7e0965052..000000000 --- a/src/core/arm/skyeye_common/armemu.h +++ /dev/null @@ -1,47 +0,0 @@ -/* armemu.h -- ARMulator emulation macros: ARM6 Instruction Emulator. - Copyright (C) 1994 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. */ - -#pragma once - -#include "core/arm/skyeye_common/armdefs.h" - -// Flags for use with the APSR. -enum : u32 { - NBIT = (1U << 31U), - ZBIT = (1 << 30), - CBIT = (1 << 29), - VBIT = (1 << 28), - QBIT = (1 << 27), - JBIT = (1 << 24), - EBIT = (1 << 9), - ABIT = (1 << 8), - IBIT = (1 << 7), - FBIT = (1 << 6), - TBIT = (1 << 5), - - // Masks for groups of bits in the APSR. - MODEBITS = 0x1F, - INTBITS = 0x1C0, -}; - -// Values for Emulate. -enum { - STOP = 0, // Stop - CHANGEMODE = 1, // Change mode - ONCE = 2, // Execute just one interation - RUN = 3 // Continuous execution -}; diff --git a/src/core/arm/skyeye_common/vfp/vfp.cpp b/src/core/arm/skyeye_common/vfp/vfp.cpp index b88d47750..571d6c2f2 100644 --- a/src/core/arm/skyeye_common/vfp/vfp.cpp +++ b/src/core/arm/skyeye_common/vfp/vfp.cpp @@ -33,6 +33,10 @@ unsigned VFPInit(ARMul_State* state) state->VFP[VFP_FPEXC] = 0; state->VFP[VFP_FPSCR] = 0; + // ARM11 MPCore feature register values. + state->VFP[VFP_MVFR0] = 0x11111111; + state->VFP[VFP_MVFR1] = 0; + return 0; } diff --git a/src/core/arm/skyeye_common/vfp/vfp.h b/src/core/arm/skyeye_common/vfp/vfp.h index 727350f14..acefae9bb 100644 --- a/src/core/arm/skyeye_common/vfp/vfp.h +++ b/src/core/arm/skyeye_common/vfp/vfp.h @@ -22,7 +22,6 @@ #include "core/arm/skyeye_common/vfp/vfp_helper.h" /* for references to cdp SoftFloat functions */ -#define VFP_DEBUG_UNIMPLEMENTED(x) LOG_ERROR(Core_ARM11, "in func %s, " #x " unimplemented\n", __FUNCTION__); exit(-1); #define VFP_DEBUG_UNTESTED(x) LOG_TRACE(Core_ARM11, "in func %s, " #x " untested\n", __FUNCTION__); #define CHECK_VFP_ENABLED #define CHECK_VFP_CDP_RET vfp_raise_exceptions(cpu, ret, inst_cream->instr, cpu->VFP[VFP_FPSCR]); diff --git a/src/core/arm/skyeye_common/vfp/vfp_helper.h b/src/core/arm/skyeye_common/vfp/vfp_helper.h index ccc0212ab..2007d6dc4 100644 --- a/src/core/arm/skyeye_common/vfp/vfp_helper.h +++ b/src/core/arm/skyeye_common/vfp/vfp_helper.h @@ -18,10 +18,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* +/* * The following code is derivative from Linux Android kernel vfp * floating point support. - * + * * Copyright (C) 2004 ARM Limited. * Written by Deep Blue Solutions Limited. * diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp index 3ed918a93..67fe63aa4 100644 --- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp @@ -1068,10 +1068,12 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrc)(unsigned int inst, int index) #ifdef VFP_INTERPRETER_IMPL VMOVBRC_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - VFP_DEBUG_UNIMPLEMENTED(VMOVBRC); + vmovbrc_inst* const inst_cream = (vmovbrc_inst*)inst_base->component; + + cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index] = cpu->Reg[inst_cream->t]; } cpu->Reg[15] += GET_INST_SIZE(cpu); INC_PC(sizeof(vmovbrc_inst)); @@ -1139,12 +1141,10 @@ VMRS_INST: cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_FPSID]; break; case 6: - /* MVFR1, VFPv3 only ? */ - LOG_TRACE(Core_ARM11, "\tr%d <= MVFR1 unimplemented\n", inst_cream->Rt); + cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_MVFR1]; break; case 7: - /* MVFR0, VFPv3 only? */ - LOG_TRACE(Core_ARM11, "\tr%d <= MVFR0 unimplemented\n", inst_cream->Rt); + cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_MVFR0]; break; case 8: cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_FPEXC]; @@ -1195,10 +1195,12 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbcr)(unsigned int inst, int index) #ifdef VFP_INTERPRETER_IMPL VMOVBCR_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - VFP_DEBUG_UNIMPLEMENTED(VMOVBCR); + vmovbcr_inst* const inst_cream = (vmovbcr_inst*) inst_base->component; + + cpu->Reg[inst_cream->t] = cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index]; } cpu->Reg[15] += GET_INST_SIZE(cpu); INC_PC(sizeof(vmovbcr_inst)); |
