aboutsummaryrefslogtreecommitdiff
path: root/src/core/arm
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/arm')
-rw-r--r--src/core/arm/disassembler/arm_disasm.cpp2
-rw-r--r--src/core/arm/dyncom/arm_dyncom.cpp2
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp39
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.cpp102
-rw-r--r--src/core/arm/interpreter/arminit.cpp1
-rw-r--r--src/core/arm/interpreter/armsupp.cpp2
-rw-r--r--src/core/arm/skyeye_common/arm_regformat.h2
-rw-r--r--src/core/arm/skyeye_common/armdefs.h34
-rw-r--r--src/core/arm/skyeye_common/armemu.h47
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp.cpp4
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp.h1
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp_helper.h4
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpinstr.cpp18
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));