summaryrefslogtreecommitdiff
path: root/src/core/arm
diff options
context:
space:
mode:
authorGravatar darkf2014-12-29 19:47:41 -0800
committerGravatar darkf2014-12-29 19:47:41 -0800
commit8ba9ac0f74abb0408a26207a76a0c1808bad8de0 (patch)
treef1c7c3393fa726435b5b90bf335567c93e528ef1 /src/core/arm
parentAdd comment regarding __WIN32__ in SkyEye code (diff)
parentMerge pull request #367 from bunnei/usat_ssat (diff)
downloadyuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar.gz
yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar.xz
yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.zip
Fix merge conflicts
Diffstat (limited to 'src/core/arm')
-rw-r--r--src/core/arm/arm_interface.h8
-rw-r--r--src/core/arm/disassembler/load_symbol_map.cpp2
-rw-r--r--src/core/arm/disassembler/load_symbol_map.h2
-rw-r--r--src/core/arm/dyncom/arm_dyncom.cpp51
-rw-r--r--src/core/arm/dyncom/arm_dyncom.h16
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.cpp817
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.h2
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp11064
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.h2
-rw-r--r--src/core/arm/dyncom/arm_dyncom_run.cpp46
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.cpp863
-rw-r--r--src/core/arm/interpreter/arm_interpreter.cpp53
-rw-r--r--src/core/arm/interpreter/arm_interpreter.h8
-rw-r--r--src/core/arm/interpreter/armemu.cpp1412
-rw-r--r--src/core/arm/interpreter/armsupp.cpp166
-rw-r--r--src/core/arm/interpreter/thumbemu.cpp2
-rw-r--r--src/core/arm/skyeye_common/armdefs.h491
-rw-r--r--src/core/arm/skyeye_common/armemu.h12
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp.cpp663
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp.h6
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpinstr.cpp1957
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpsingle.cpp14
22 files changed, 8501 insertions, 9156 deletions
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index 3ae528562..3b7209418 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -1,5 +1,5 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once 5#pragma once
@@ -78,6 +78,12 @@ public:
78 virtual u64 GetTicks() const = 0; 78 virtual u64 GetTicks() const = 0;
79 79
80 /** 80 /**
81 * Advance the CPU core by the specified number of ticks (e.g. to simulate CPU execution time)
82 * @param ticks Number of ticks to advance the CPU core
83 */
84 virtual void AddTicks(u64 ticks) = 0;
85
86 /**
81 * Saves the current CPU context 87 * Saves the current CPU context
82 * @param ctx Thread context to save 88 * @param ctx Thread context to save
83 */ 89 */
diff --git a/src/core/arm/disassembler/load_symbol_map.cpp b/src/core/arm/disassembler/load_symbol_map.cpp
index 55278474b..13d26d170 100644
--- a/src/core/arm/disassembler/load_symbol_map.cpp
+++ b/src/core/arm/disassembler/load_symbol_map.cpp
@@ -1,5 +1,5 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <string> 5#include <string>
diff --git a/src/core/arm/disassembler/load_symbol_map.h b/src/core/arm/disassembler/load_symbol_map.h
index 837cca99b..d28c551c3 100644
--- a/src/core/arm/disassembler/load_symbol_map.h
+++ b/src/core/arm/disassembler/load_symbol_map.h
@@ -1,5 +1,5 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once 5#pragma once
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp
index 6c8ea211e..a838fd25a 100644
--- a/src/core/arm/dyncom/arm_dyncom.cpp
+++ b/src/core/arm/dyncom/arm_dyncom.cpp
@@ -1,5 +1,5 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/arm/skyeye_common/armcpu.h" 5#include "core/arm/skyeye_common/armcpu.h"
@@ -47,68 +47,38 @@ ARM_DynCom::ARM_DynCom() : ticks(0) {
47ARM_DynCom::~ARM_DynCom() { 47ARM_DynCom::~ARM_DynCom() {
48} 48}
49 49
50/**
51 * Set the Program Counter to an address
52 * @param addr Address to set PC to
53 */
54void ARM_DynCom::SetPC(u32 pc) { 50void ARM_DynCom::SetPC(u32 pc) {
55 state->pc = state->Reg[15] = pc; 51 state->pc = state->Reg[15] = pc;
56} 52}
57 53
58/*
59 * Get the current Program Counter
60 * @return Returns current PC
61 */
62u32 ARM_DynCom::GetPC() const { 54u32 ARM_DynCom::GetPC() const {
63 return state->Reg[15]; 55 return state->Reg[15];
64} 56}
65 57
66/**
67 * Get an ARM register
68 * @param index Register index (0-15)
69 * @return Returns the value in the register
70 */
71u32 ARM_DynCom::GetReg(int index) const { 58u32 ARM_DynCom::GetReg(int index) const {
72 return state->Reg[index]; 59 return state->Reg[index];
73} 60}
74 61
75/**
76 * Set an ARM register
77 * @param index Register index (0-15)
78 * @param value Value to set register to
79 */
80void ARM_DynCom::SetReg(int index, u32 value) { 62void ARM_DynCom::SetReg(int index, u32 value) {
81 state->Reg[index] = value; 63 state->Reg[index] = value;
82} 64}
83 65
84/**
85 * Get the current CPSR register
86 * @return Returns the value of the CPSR register
87 */
88u32 ARM_DynCom::GetCPSR() const { 66u32 ARM_DynCom::GetCPSR() const {
89 return state->Cpsr; 67 return state->Cpsr;
90} 68}
91 69
92/**
93 * Set the current CPSR register
94 * @param cpsr Value to set CPSR to
95 */
96void ARM_DynCom::SetCPSR(u32 cpsr) { 70void ARM_DynCom::SetCPSR(u32 cpsr) {
97 state->Cpsr = cpsr; 71 state->Cpsr = cpsr;
98} 72}
99 73
100/**
101 * Returns the number of clock ticks since the last reset
102 * @return Returns number of clock ticks
103 */
104u64 ARM_DynCom::GetTicks() const { 74u64 ARM_DynCom::GetTicks() const {
105 return ticks; 75 return ticks;
106} 76}
107 77
108/** 78void ARM_DynCom::AddTicks(u64 ticks) {
109 * Executes the given number of instructions 79 this->ticks += ticks;
110 * @param num_instructions Number of instructions to executes 80}
111 */ 81
112void ARM_DynCom::ExecuteInstructions(int num_instructions) { 82void ARM_DynCom::ExecuteInstructions(int num_instructions) {
113 state->NumInstrsToExecute = num_instructions; 83 state->NumInstrsToExecute = num_instructions;
114 84
@@ -118,11 +88,6 @@ void ARM_DynCom::ExecuteInstructions(int num_instructions) {
118 ticks += InterpreterMainLoop(state.get()); 88 ticks += InterpreterMainLoop(state.get());
119} 89}
120 90
121/**
122 * Saves the current CPU context
123 * @param ctx Thread context to save
124 * @todo Do we need to save Reg[15] and NextInstr?
125 */
126void ARM_DynCom::SaveContext(ThreadContext& ctx) { 91void ARM_DynCom::SaveContext(ThreadContext& ctx) {
127 memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers)); 92 memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers));
128 memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers)); 93 memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers));
@@ -139,11 +104,6 @@ void ARM_DynCom::SaveContext(ThreadContext& ctx) {
139 ctx.mode = state->NextInstr; 104 ctx.mode = state->NextInstr;
140} 105}
141 106
142/**
143 * Loads a CPU context
144 * @param ctx Thread context to load
145 * @param Do we need to load Reg[15] and NextInstr?
146 */
147void ARM_DynCom::LoadContext(const ThreadContext& ctx) { 107void ARM_DynCom::LoadContext(const ThreadContext& ctx) {
148 memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers)); 108 memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers));
149 memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers)); 109 memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
@@ -160,7 +120,6 @@ void ARM_DynCom::LoadContext(const ThreadContext& ctx) {
160 state->NextInstr = ctx.mode; 120 state->NextInstr = ctx.mode;
161} 121}
162 122
163/// Prepare core for thread reschedule (if needed to correctly handle state)
164void ARM_DynCom::PrepareReschedule() { 123void ARM_DynCom::PrepareReschedule() {
165 state->NumInstrsToExecute = 0; 124 state->NumInstrsToExecute = 0;
166} 125}
diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h
index 51eea41ed..7284dcd07 100644
--- a/src/core/arm/dyncom/arm_dyncom.h
+++ b/src/core/arm/dyncom/arm_dyncom.h
@@ -1,5 +1,5 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once 5#pragma once
@@ -27,14 +27,14 @@ public:
27 * Get the current Program Counter 27 * Get the current Program Counter
28 * @return Returns current PC 28 * @return Returns current PC
29 */ 29 */
30 u32 GetPC() const; 30 u32 GetPC() const override;
31 31
32 /** 32 /**
33 * Get an ARM register 33 * Get an ARM register
34 * @param index Register index (0-15) 34 * @param index Register index (0-15)
35 * @return Returns the value in the register 35 * @return Returns the value in the register
36 */ 36 */
37 u32 GetReg(int index) const; 37 u32 GetReg(int index) const override;
38 38
39 /** 39 /**
40 * Set an ARM register 40 * Set an ARM register
@@ -47,7 +47,7 @@ public:
47 * Get the current CPSR register 47 * Get the current CPSR register
48 * @return Returns the value of the CPSR register 48 * @return Returns the value of the CPSR register
49 */ 49 */
50 u32 GetCPSR() const; 50 u32 GetCPSR() const override;
51 51
52 /** 52 /**
53 * Set the current CPSR register 53 * Set the current CPSR register
@@ -59,7 +59,13 @@ public:
59 * Returns the number of clock ticks since the last reset 59 * Returns the number of clock ticks since the last reset
60 * @return Returns number of clock ticks 60 * @return Returns number of clock ticks
61 */ 61 */
62 u64 GetTicks() const; 62 u64 GetTicks() const override;
63
64 /**
65 * Advance the CPU core by the specified number of ticks (e.g. to simulate CPU execution time)
66 * @param ticks Number of ticks to advance the CPU core
67 */
68 void AddTicks(u64 ticks) override;
63 69
64 /** 70 /**
65 * Saves the current CPU context 71 * Saves the current CPU context
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp
index 5d174a08f..333b40f54 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp
@@ -1,402 +1,443 @@
1/* Copyright (C) 1// Copyright 2012 Michael Kang, 2014 Citra Emulator Project
2* 2012 - Michael.Kang blackfin.kang@gmail.com 2// Licensed under GPLv2 or any later version
3* This program is free software; you can redistribute it and/or 3// Refer to the license.txt file included.
4* modify it under the terms of the GNU General Public License
5* as published by the Free Software Foundation; either version 2
6* of the License, or (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18/**
19* @file arm_dyncom_dec.cpp
20* @brief Some common utility for arm decoder
21* @author Michael.Kang blackfin.kang@gmail.com
22* @version 7849
23* @date 2012-03-15
24*/
25 4
26#include "core/arm/skyeye_common/arm_regformat.h" 5#include "core/arm/skyeye_common/arm_regformat.h"
27#include "core/arm/skyeye_common/armdefs.h" 6#include "core/arm/skyeye_common/armdefs.h"
28#include "core/arm/dyncom/arm_dyncom_dec.h" 7#include "core/arm/dyncom/arm_dyncom_dec.h"
29 8
30const ISEITEM arm_instruction[] = { 9const ISEITEM arm_instruction[] = {
31 #define VFP_DECODE 10 { "vmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0 },
32 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 11 { "vmls", 7, ARMVFP2, 28, 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0 },
33 #undef VFP_DECODE 12 { "vnmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0 },
34 {"srs" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d, 8, 11, 0x00000005}, 13 { "vnmla", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 },
35 {"rfe" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001, 8, 11, 0x0000000a}, 14 { "vnmls", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 },
36 {"bkpt" , 2 , 3 , 20, 31, 0x00000e12, 4, 7, 0x00000007}, 15 { "vnmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 },
37 {"blx" , 1 , 3 , 25, 31, 0x0000007d}, 16 { "vmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 },
38 {"cps" , 3 , 6 , 20, 31, 0x00000f10, 16, 16, 0x00000000, 5, 5, 0x00000000}, 17 { "vadd", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 },
39 {"pld" , 4 , 4 , 26, 31, 0x0000003d, 24, 24, 0x00000001, 20, 22, 0x00000005, 12, 15, 0x0000000f}, 18 { "vsub", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 },
40 {"setend" , 2 , 6 , 16, 31, 0x0000f101, 4, 7, 0x00000000}, 19 { "vdiv", 5, ARMVFP2, 23, 27, 0x1D, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 },
41 {"clrex" , 1 , 6 , 0, 31, 0xf57ff01f}, 20 { "vmov(i)", 4, ARMVFP3, 23, 27, 0x1D, 20, 21, 0x3, 9, 11, 0x5, 4, 7, 0 },
42 {"rev16" , 2 , 6 , 16, 27, 0x000006bf, 4, 11, 0x000000fb}, 21 { "vmov(r)", 5, ARMVFP3, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 1, 4, 4, 0 },
43 {"usad8" , 3 , 6 , 20, 27, 0x00000078, 12, 15, 0x0000000f, 4, 7, 0x00000001}, 22 { "vabs", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 },
44 {"sxtb" , 2 , 6 , 16, 27, 0x000006af, 4, 7, 0x00000007}, 23 { "vneg", 5, ARMVFP2, 23, 27, 0x1D, 17, 21, 0x18, 9, 11, 0x5, 6, 7, 1, 4, 4, 0 },
45 {"uxtb" , 2 , 6 , 16, 27, 0x000006ef, 4, 7, 0x00000007}, 24 { "vsqrt", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x31, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 },
46 {"sxth" , 2 , 6 , 16, 27, 0x000006bf, 4, 7, 0x00000007}, 25 { "vcmp", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x34, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 },
47 {"sxtb16" , 2 , 6 , 16, 27, 0x0000068f, 4, 7, 0x00000007}, 26 { "vcmp2", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x35, 9, 11, 0x5, 0, 6, 0x40 },
48 {"uxth" , 2 , 6 , 16, 27, 0x000006ff, 4, 7, 0x00000007}, 27 { "vcvt(bds)", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x37, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 },
49 {"uxtb16" , 2 , 6 , 16, 27, 0x000006cf, 4, 7, 0x00000007}, 28 { "vcvt(bff)", 6, ARMVFP3, 23, 27, 0x1D, 19, 21, 0x7, 17, 17, 0x1, 9, 11, 5, 6, 6, 1 },
50 {"cpy" , 2 , 6 , 20, 27, 0x0000001a, 4, 11, 0x00000000}, 29 { "vcvt(bfi)", 5, ARMVFP2, 23, 27, 0x1D, 19, 21, 0x7, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 },
51 {"uxtab" , 2 , 6 , 20, 27, 0x0000006e, 4, 9, 0x00000007}, 30 { "vmovbrs", 3, ARMVFP2, 21, 27, 0x70, 8, 11, 0xA, 0, 6, 0x10 },
52 {"ssub8" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x0000000f}, 31 { "vmsr", 2, ARMVFP2, 20, 27, 0xEE, 0, 11, 0xA10 },
53 {"shsub8" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x0000000f}, 32 { "vmovbrc", 4, ARMVFP2, 23, 27, 0x1C, 20, 20, 0x0, 8, 11, 0xB, 0, 4, 0x10 },
54 {"ssubaddx" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000005}, 33 { "vmrs", 2, ARMVFP2, 20, 27, 0xEF, 0, 11, 0xA10 },
55 {"strex" , 2 , 6 , 20, 27, 0x00000018, 4, 7, 0x00000009}, 34 { "vmovbcr", 4, ARMVFP2, 24, 27, 0xE, 20, 20, 1, 8, 11, 0xB, 0, 4, 0x10 },
56 {"strexb" , 2 , 7 , 20, 27, 0x0000001c, 4, 7, 0x00000009}, 35 { "vmovbrrss", 3, ARMVFP2, 21, 27, 0x62, 8, 11, 0xA, 4, 4, 1 },
57 {"swp" , 2 , 0 , 20, 27, 0x00000010, 4, 7, 0x00000009}, 36 { "vmovbrrd", 3, ARMVFP2, 21, 27, 0x62, 6, 11, 0x2C, 4, 4, 1 },
58 {"swpb" , 2 , 0 , 20, 27, 0x00000014, 4, 7, 0x00000009}, 37 { "vstr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 0, 9, 11, 5 },
59 {"ssub16" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000007}, 38 { "vpush", 3, ARMVFP2, 23, 27, 0x1A, 16, 21, 0x2D, 9, 11, 5 },
60 {"ssat16" , 2 , 6 , 20, 27, 0x0000006a, 4, 7, 0x00000003}, 39 { "vstm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 0, 9, 11, 5 },
61 {"shsubaddx" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000005}, 40 { "vpop", 3, ARMVFP2, 23, 27, 0x19, 16, 21, 0x3D, 9, 11, 5 },
62 {"qsubaddx" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000005}, 41 { "vldr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 1, 9, 11, 5 },
63 {"shaddsubx" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000003}, 42 { "vldm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 1, 9, 11, 5 },
64 {"shadd8" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000009}, 43
65 {"shadd16" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000001}, 44 { "srs", 4, 6, 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d, 8, 11, 0x00000005 },
66 {"sel" , 2 , 6 , 20, 27, 0x00000068, 4, 7, 0x0000000b}, 45 { "rfe", 4, 6, 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001, 8, 11, 0x0000000a },
67 {"saddsubx" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000003}, 46 { "bkpt", 2, 3, 20, 31, 0x00000e12, 4, 7, 0x00000007 },
68 {"sadd8" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000009}, 47 { "blx", 1, 3, 25, 31, 0x0000007d },
69 {"sadd16" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000001}, 48 { "cps", 3, 6, 20, 31, 0x00000f10, 16, 16, 0x00000000, 5, 5, 0x00000000 },
70 {"shsub16" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000007}, 49 { "pld", 4, 4, 26, 31, 0x0000003d, 24, 24, 0x00000001, 20, 22, 0x00000005, 12, 15, 0x0000000f },
71 {"umaal" , 2 , 6 , 20, 27, 0x00000004, 4, 7, 0x00000009}, 50 { "setend", 2, 6, 16, 31, 0x0000f101, 4, 7, 0x00000000 },
72 {"uxtab16" , 2 , 6 , 20, 27, 0x0000006c, 4, 7, 0x00000007}, 51 { "clrex", 1, 6, 0, 31, 0xf57ff01f },
73 {"usubaddx" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000005}, 52 { "rev16", 2, 6, 16, 27, 0x000006bf, 4, 11, 0x000000fb },
74 {"usub8" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x0000000f}, 53 { "usad8", 3, 6, 20, 27, 0x00000078, 12, 15, 0x0000000f, 4, 7, 0x00000001 },
75 {"usub16" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000007}, 54 { "sxtb", 2, 6, 16, 27, 0x000006af, 4, 7, 0x00000007 },
76 {"usat16" , 2 , 6 , 20, 27, 0x0000006e, 4, 7, 0x00000003}, 55 { "uxtb", 2, 6, 16, 27, 0x000006ef, 4, 7, 0x00000007 },
77 {"usada8" , 2 , 6 , 20, 27, 0x00000078, 4, 7, 0x00000001}, 56 { "sxth", 2, 6, 16, 27, 0x000006bf, 4, 7, 0x00000007 },
78 {"uqsubaddx" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000005}, 57 { "sxtb16", 2, 6, 16, 27, 0x0000068f, 4, 7, 0x00000007 },
79 {"uqsub8" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x0000000f}, 58 { "uxth", 2, 6, 16, 27, 0x000006ff, 4, 7, 0x00000007 },
80 {"uqsub16" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000007}, 59 { "uxtb16", 2, 6, 16, 27, 0x000006cf, 4, 7, 0x00000007 },
81 {"uqaddsubx" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000003}, 60 { "cpy", 2, 6, 20, 27, 0x0000001a, 4, 11, 0x00000000 },
82 {"uqadd8" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000009}, 61 { "uxtab", 2, 6, 20, 27, 0x0000006e, 4, 9, 0x00000007 },
83 {"uqadd16" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000001}, 62 { "ssub8", 2, 6, 20, 27, 0x00000061, 4, 7, 0x0000000f },
84 {"sxtab" , 2 , 6 , 20, 27, 0x0000006a, 4, 7, 0x00000007}, 63 { "shsub8", 2, 6, 20, 27, 0x00000063, 4, 7, 0x0000000f },
85 {"uhsubaddx" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000005}, 64 { "ssubaddx", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000005 },
86 {"uhsub8" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x0000000f}, 65 { "strex", 2, 6, 20, 27, 0x00000018, 4, 7, 0x00000009 },
87 {"uhsub16" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000007}, 66 { "strexb", 2, 7, 20, 27, 0x0000001c, 4, 7, 0x00000009 },
88 {"uhaddsubx" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000003}, 67 { "swp", 2, 0, 20, 27, 0x00000010, 4, 7, 0x00000009 },
89 {"uhadd8" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000009}, 68 { "swpb", 2, 0, 20, 27, 0x00000014, 4, 7, 0x00000009 },
90 {"uhadd16" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000001}, 69 { "ssub16", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000007 },
91 {"uaddsubx" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000003}, 70 { "ssat16", 2, 6, 20, 27, 0x0000006a, 4, 7, 0x00000003 },
92 {"uadd8" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000009}, 71 { "shsubaddx", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000005 },
93 {"uadd16" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000001}, 72 { "qsubaddx", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000005 },
94 {"sxtah" , 2 , 6 , 20, 27, 0x0000006b, 4, 7, 0x00000007}, 73 { "shaddsubx", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000003 },
95 {"sxtab16" , 2 , 6 , 20, 27, 0x00000068, 4, 7, 0x00000007}, 74 { "shadd8", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000009 },
96 {"qadd8" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000009}, 75 { "shadd16", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000001 },
97 {"bxj" , 2 , 5 , 20, 27, 0x00000012, 4, 7, 0x00000002}, 76 { "sel", 2, 6, 20, 27, 0x00000068, 4, 7, 0x0000000b },
98 {"clz" , 2 , 3 , 20, 27, 0x00000016, 4, 7, 0x00000001}, 77 { "saddsubx", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000003 },
99 {"uxtah" , 2 , 6 , 20, 27, 0x0000006f, 4, 7, 0x00000007}, 78 { "sadd8", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000009 },
100 {"bx" , 2 , 2 , 20, 27, 0x00000012, 4, 7, 0x00000001}, 79 { "sadd16", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000001 },
101 {"rev" , 2 , 6 , 20, 27, 0x0000006b, 4, 7, 0x00000003}, 80 { "shsub16", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000007 },
102 {"blx" , 2 , 3 , 20, 27, 0x00000012, 4, 7, 0x00000003}, 81 { "umaal", 2, 6, 20, 27, 0x00000004, 4, 7, 0x00000009 },
103 {"revsh" , 2 , 6 , 20, 27, 0x0000006f, 4, 7, 0x0000000b}, 82 { "uxtab16", 2, 6, 20, 27, 0x0000006c, 4, 7, 0x00000007 },
104 {"qadd" , 2 , 4 , 20, 27, 0x00000010, 4, 7, 0x00000005}, 83 { "usubaddx", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000005 },
105 {"qadd16" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000001}, 84 { "usub8", 2, 6, 20, 27, 0x00000065, 4, 7, 0x0000000f },
106 {"qaddsubx" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000003}, 85 { "usub16", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000007 },
107 {"ldrex" , 2 , 0 , 20, 27, 0x00000019, 4, 7, 0x00000009}, 86 { "usat16", 2, 6, 20, 27, 0x0000006e, 4, 7, 0x00000003 },
108 {"qdadd" , 2 , 4 , 20, 27, 0x00000014, 4, 7, 0x00000005}, 87 { "usada8", 2, 6, 20, 27, 0x00000078, 4, 7, 0x00000001 },
109 {"qdsub" , 2 , 4 , 20, 27, 0x00000016, 4, 7, 0x00000005}, 88 { "uqsubaddx", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000005 },
110 {"qsub" , 2 , 4 , 20, 27, 0x00000012, 4, 7, 0x00000005}, 89 { "uqsub8", 2, 6, 20, 27, 0x00000066, 4, 7, 0x0000000f },
111 {"ldrexb" , 2 , 7 , 20, 27, 0x0000001d, 4, 7, 0x00000009}, 90 { "uqsub16", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000007 },
112 {"qsub8" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x0000000f}, 91 { "uqaddsubx", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000003 },
113 {"qsub16" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000007}, 92 { "uqadd8", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000009 },
114 {"smuad" , 4 , 6 , 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001}, 93 { "uqadd16", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000001 },
115 {"smmul" , 4 , 6 , 20, 27, 0x00000075, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001}, 94 { "sxtab", 2, 6, 20, 27, 0x0000006a, 4, 7, 0x00000007 },
116 {"smusd" , 4 , 6 , 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000001, 4, 4, 0x00000001}, 95 { "uhsubaddx", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000005 },
117 {"smlsd" , 3 , 6 , 20, 27, 0x00000070, 6, 7, 0x00000001, 4, 4, 0x00000001}, 96 { "uhsub8", 2, 6, 20, 27, 0x00000067, 4, 7, 0x0000000f },
118 {"smlsld" , 3 , 6 , 20, 27, 0x00000074, 6, 7, 0x00000001, 4, 4, 0x00000001}, 97 { "uhsub16", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000007 },
119 {"smmla" , 3 , 6 , 20, 27, 0x00000075, 6, 7, 0x00000000, 4, 4, 0x00000001}, 98 { "uhaddsubx", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000003 },
120 {"smmls" , 3 , 6 , 20, 27, 0x00000075, 6, 7, 0x00000003, 4, 4, 0x00000001}, 99 { "uhadd8", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000009 },
121 {"smlald" , 3 , 6 , 20, 27, 0x00000074, 6, 7, 0x00000000, 4, 4, 0x00000001}, 100 { "uhadd16", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000001 },
122 {"smlad" , 3 , 6 , 20, 27, 0x00000070, 6, 7, 0x00000000, 4, 4, 0x00000001}, 101 { "uaddsubx", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000003 },
123 {"smlaw" , 3 , 4 , 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000000}, 102 { "uadd8", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000009 },
124 {"smulw" , 3 , 4 , 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000002}, 103 { "uadd16", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000001 },
125 {"pkhtb" , 2 , 6 , 20, 27, 0x00000068, 4, 6, 0x00000005}, 104 { "sxtah", 2, 6, 20, 27, 0x0000006b, 4, 7, 0x00000007 },
126 {"pkhbt" , 2 , 6 , 20, 27, 0x00000068, 4, 6, 0x00000001}, 105 { "sxtab16", 2, 6, 20, 27, 0x00000068, 4, 7, 0x00000007 },
127 {"smul" , 3 , 4 , 20, 27, 0x00000016, 7, 7, 0x00000001, 4, 4, 0x00000000}, 106 { "qadd8", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000009 },
128 {"smlalxy" , 3 , 4 , 20, 27, 0x00000014, 7, 7, 0x00000001, 4, 4, 0x00000000}, 107 { "bxj", 2, 5, 20, 27, 0x00000012, 4, 7, 0x00000002 },
129// {"smlal" , 2 , 4 , 21, 27, 0x00000007, 4, 7, 0x00000009}, 108 { "clz", 2, 3, 20, 27, 0x00000016, 4, 7, 0x00000001 },
130 {"smla" , 3 , 4 , 20, 27, 0x00000010, 7, 7, 0x00000001, 4, 4, 0x00000000}, 109 { "uxtah", 2, 6, 20, 27, 0x0000006f, 4, 7, 0x00000007 },
131 {"mcrr" , 1 , 6 , 20, 27, 0x000000c4}, 110 { "bx", 2, 2, 20, 27, 0x00000012, 4, 7, 0x00000001 },
132 {"mrrc" , 1 , 6 , 20, 27, 0x000000c5}, 111 { "rev", 2, 6, 20, 27, 0x0000006b, 4, 7, 0x00000003 },
133 {"cmp" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000015}, 112 { "blx", 2, 3, 20, 27, 0x00000012, 4, 7, 0x00000003 },
134 {"tst" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000011}, 113 { "revsh", 2, 6, 20, 27, 0x0000006f, 4, 7, 0x0000000b },
135 {"teq" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000013}, 114 { "qadd", 2, 4, 20, 27, 0x00000010, 4, 7, 0x00000005 },
136 {"cmn" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000017}, 115 { "qadd16", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000001 },
137 {"smull" , 2 , 0 , 21, 27, 0x00000006, 4, 7, 0x00000009}, 116 { "qaddsubx", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000003 },
138 {"umull" , 2 , 0 , 21, 27, 0x00000004, 4, 7, 0x00000009}, 117 { "ldrex", 2, 0, 20, 27, 0x00000019, 4, 7, 0x00000009 },
139 {"umlal" , 2 , 0 , 21, 27, 0x00000005, 4, 7, 0x00000009}, 118 { "qdadd", 2, 4, 20, 27, 0x00000014, 4, 7, 0x00000005 },
140 {"smlal" , 2 , 0 , 21, 27, 0x00000007, 4, 7, 0x00000009}, 119 { "qdsub", 2, 4, 20, 27, 0x00000016, 4, 7, 0x00000005 },
141 {"mul" , 2 , 0 , 21, 27, 0x00000000, 4, 7, 0x00000009}, 120 { "qsub", 2, 4, 20, 27, 0x00000012, 4, 7, 0x00000005 },
142 {"mla" , 2 , 0 , 21, 27, 0x00000001, 4, 7, 0x00000009}, 121 { "ldrexb", 2, 7, 20, 27, 0x0000001d, 4, 7, 0x00000009 },
143 {"ssat" , 2 , 6 , 21, 27, 0x00000035, 4, 5, 0x00000001}, 122 { "qsub8", 2, 6, 20, 27, 0x00000062, 4, 7, 0x0000000f },
144 {"usat" , 2 , 6 , 21, 27, 0x00000037, 4, 5, 0x00000001}, 123 { "qsub16", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000007 },
145 {"mrs" , 4 , 0 , 23, 27, 0x00000002, 20, 21, 0x00000000, 16, 19, 0x0000000f, 0, 11, 0x00000000}, 124 { "smuad", 4, 6, 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001 },
146 {"msr" , 3 , 0 , 23, 27, 0x00000002, 20, 21, 0x00000002, 4, 7, 0x00000000}, 125 { "smmul", 4, 6, 20, 27, 0x00000075, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001 },
147 {"and" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000000}, 126 { "smusd", 4, 6, 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000001, 4, 4, 0x00000001 },
148 {"bic" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000e}, 127 { "smlsd", 3, 6, 20, 27, 0x00000070, 6, 7, 0x00000001, 4, 4, 0x00000001 },
149 {"ldm" , 3 , 0 , 25, 27, 0x00000004, 20, 22, 0x00000005, 15, 15, 0x00000000}, 128 { "smlsld", 3, 6, 20, 27, 0x00000074, 6, 7, 0x00000001, 4, 4, 0x00000001 },
150 {"eor" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000001}, 129 { "smmla", 3, 6, 20, 27, 0x00000075, 6, 7, 0x00000000, 4, 4, 0x00000001 },
151 {"add" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000004}, 130 { "smmls", 3, 6, 20, 27, 0x00000075, 6, 7, 0x00000003, 4, 4, 0x00000001 },
152 {"rsb" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000003}, 131 { "smlald", 3, 6, 20, 27, 0x00000074, 6, 7, 0x00000000, 4, 4, 0x00000001 },
153 {"rsc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000007}, 132 { "smlad", 3, 6, 20, 27, 0x00000070, 6, 7, 0x00000000, 4, 4, 0x00000001 },
154 {"sbc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000006}, 133 { "smlaw", 3, 4, 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000000 },
155 {"adc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000005}, 134 { "smulw", 3, 4, 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000002 },
156 {"sub" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000002}, 135 { "pkhtb", 2, 6, 20, 27, 0x00000068, 4, 6, 0x00000005 },
157 {"orr" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000c}, 136 { "pkhbt", 2, 6, 20, 27, 0x00000068, 4, 6, 0x00000001 },
158 {"mvn" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000f}, 137 { "smul", 3, 4, 20, 27, 0x00000016, 7, 7, 0x00000001, 4, 4, 0x00000000 },
159 {"mov" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000d}, 138 { "smlalxy", 3, 4, 20, 27, 0x00000014, 7, 7, 0x00000001, 4, 4, 0x00000000 },
160 {"stm" , 2 , 0 , 25, 27, 0x00000004, 20, 22, 0x00000004}, 139 // {"smlal" , 2 , 4 , 21, 27, 0x00000007, 4, 7, 0x00000009},
161 {"ldm" , 4 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000001, 20, 20, 0x00000001, 15, 15, 0x00000001}, 140 { "smla", 3, 4, 20, 27, 0x00000010, 7, 7, 0x00000001, 4, 4, 0x00000000 },
162 {"ldrsh" , 3 , 2 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000f}, 141 { "mcrr", 1, 6, 20, 27, 0x000000c4 },
163 {"stm" , 3 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000000}, 142 { "mrrc", 1, 6, 20, 27, 0x000000c5 },
164 {"ldm" , 3 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000001}, 143 { "cmp", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000015 },
165 {"ldrsb" , 3 , 2 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000d}, 144 { "tst", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000011 },
166 {"strd" , 3 , 4 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000f}, 145 { "teq", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000013 },
167 {"ldrh" , 3 , 0 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000b}, 146 { "cmn", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000017 },
168 {"strh" , 3 , 0 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000b}, 147 { "smull", 2, 0, 21, 27, 0x00000006, 4, 7, 0x00000009 },
169 {"ldrd" , 3 , 4 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000d}, 148 { "umull", 2, 0, 21, 27, 0x00000004, 4, 7, 0x00000009 },
170 {"strt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000002}, 149 { "umlal", 2, 0, 21, 27, 0x00000005, 4, 7, 0x00000009 },
171 {"strbt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000006}, 150 { "smlal", 2, 0, 21, 27, 0x00000007, 4, 7, 0x00000009 },
172 {"ldrbt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000007}, 151 { "mul", 2, 0, 21, 27, 0x00000000, 4, 7, 0x00000009 },
173 {"ldrt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000003}, 152 { "mla", 2, 0, 21, 27, 0x00000001, 4, 7, 0x00000009 },
174 {"mrc" , 3 , 6 , 24, 27, 0x0000000e, 20, 20, 0x00000001, 4, 4, 0x00000001}, 153 { "ssat", 2, 6, 21, 27, 0x00000035, 4, 5, 0x00000001 },
175 {"mcr" , 3 , 0 , 24, 27, 0x0000000e, 20, 20, 0x00000000, 4, 4, 0x00000001}, 154 { "usat", 2, 6, 21, 27, 0x00000037, 4, 5, 0x00000001 },
176 {"msr" , 2 , 0 , 23, 27, 0x00000006, 20, 21, 0x00000002}, 155 { "mrs", 4, 0, 23, 27, 0x00000002, 20, 21, 0x00000000, 16, 19, 0x0000000f, 0, 11, 0x00000000 },
177 {"ldrb" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000001}, 156 { "msr", 3, 0, 23, 27, 0x00000002, 20, 21, 0x00000002, 4, 7, 0x00000000 },
178 {"strb" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000000}, 157 { "and", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000000 },
179 {"ldr" , 4 , 0 , 28, 31, 0x0000000e, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001}, 158 { "bic", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000e },
180 {"ldrcond" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001}, 159 { "ldm", 3, 0, 25, 27, 0x00000004, 20, 22, 0x00000005, 15, 15, 0x00000000 },
181 {"str" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000000}, 160 { "eor", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000001 },
182 {"cdp" , 2 , 0 , 24, 27, 0x0000000e, 4, 4, 0x00000000}, 161 { "add", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000004 },
183 {"stc" , 2 , 0 , 25, 27, 0x00000006, 20, 20, 0x00000000}, 162 { "rsb", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000003 },
184 {"ldc" , 2 , 0 , 25, 27, 0x00000006, 20, 20, 0x00000001}, 163 { "rsc", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000007 },
185 {"swi" , 1 , 0 , 24, 27, 0x0000000f}, 164 { "sbc", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000006 },
186 {"bbl" , 1 , 0 , 25, 27, 0x00000005}, 165 { "adc", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000005 },
166 { "sub", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000002 },
167 { "orr", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000c },
168 { "mvn", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000f },
169 { "mov", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000d },
170 { "stm", 2, 0, 25, 27, 0x00000004, 20, 22, 0x00000004 },
171 { "ldm", 4, 0, 25, 27, 0x00000004, 22, 22, 0x00000001, 20, 20, 0x00000001, 15, 15, 0x00000001 },
172 { "ldrsh", 3, 2, 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000f },
173 { "stm", 3, 0, 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000000 },
174 { "ldm", 3, 0, 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000001 },
175 { "ldrsb", 3, 2, 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000d },
176 { "strd", 3, 4, 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000f },
177 { "ldrh", 3, 0, 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000b },
178 { "strh", 3, 0, 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000b },
179 { "ldrd", 3, 4, 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000d },
180 { "strt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000002 },
181 { "strbt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000006 },
182 { "ldrbt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000007 },
183 { "ldrt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000003 },
184 { "mrc", 3, 6, 24, 27, 0x0000000e, 20, 20, 0x00000001, 4, 4, 0x00000001 },
185 { "mcr", 3, 0, 24, 27, 0x0000000e, 20, 20, 0x00000000, 4, 4, 0x00000001 },
186 { "msr", 2, 0, 23, 27, 0x00000006, 20, 21, 0x00000002 },
187 { "ldrb", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000001 },
188 { "strb", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000000 },
189 { "ldr", 4, 0, 28, 31, 0x0000000e, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001 },
190 { "ldrcond", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001 },
191 { "str", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000000 },
192 { "cdp", 2, 0, 24, 27, 0x0000000e, 4, 4, 0x00000000 },
193 { "stc", 2, 0, 25, 27, 0x00000006, 20, 20, 0x00000000 },
194 { "ldc", 2, 0, 25, 27, 0x00000006, 20, 20, 0x00000001 },
195 { "swi", 1, 0, 24, 27, 0x0000000f },
196 { "bbl", 1, 0, 25, 27, 0x00000005 },
187}; 197};
188 198
189const ISEITEM arm_exclusion_code[] = { 199const ISEITEM arm_exclusion_code[] = {
190 #define VFP_DECODE_EXCLUSION 200 { "vmla", 0, ARMVFP2, 0 },
191 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 201 { "vmls", 0, ARMVFP2, 0 },
192 #undef VFP_DECODE_EXCLUSION 202 { "vnmla", 0, ARMVFP2, 0 },
193 {"srs" , 0 , 6 , 0}, 203 { "vnmla", 0, ARMVFP2, 0 },
194 {"rfe" , 0 , 6 , 0}, 204 { "vnmls", 0, ARMVFP2, 0 },
195 {"bkpt" , 0 , 3 , 0}, 205 { "vnmul", 0, ARMVFP2, 0 },
196 {"blx" , 0 , 3 , 0}, 206 { "vmul", 0, ARMVFP2, 0 },
197 {"cps" , 0 , 6 , 0}, 207 { "vadd", 0, ARMVFP2, 0 },
198 {"pld" , 0 , 4 , 0}, 208 { "vsub", 0, ARMVFP2, 0 },
199 {"setend" , 0 , 6 , 0}, 209 { "vdiv", 0, ARMVFP2, 0 },
200 {"clrex" , 0 , 6 , 0}, 210 { "vmov(i)", 0, ARMVFP3, 0 },
201 {"rev16" , 0 , 6 , 0}, 211 { "vmov(r)", 0, ARMVFP3, 0 },
202 {"usad8" , 0 , 6 , 0}, 212 { "vabs", 0, ARMVFP2, 0 },
203 {"sxtb" , 0 , 6 , 0}, 213 { "vneg", 0, ARMVFP2, 0 },
204 {"uxtb" , 0 , 6 , 0}, 214 { "vsqrt", 0, ARMVFP2, 0 },
205 {"sxth" , 0 , 6 , 0}, 215 { "vcmp", 0, ARMVFP2, 0 },
206 {"sxtb16" , 0 , 6 , 0}, 216 { "vcmp2", 0, ARMVFP2, 0 },
207 {"uxth" , 0 , 6 , 0}, 217 { "vcvt(bff)", 0, ARMVFP3, 4, 4, 1 },
208 {"uxtb16" , 0 , 6 , 0}, 218 { "vcvt(bds)", 0, ARMVFP2, 0 },
209 {"cpy" , 0 , 6 , 0}, 219 { "vcvt(bfi)", 0, ARMVFP2, 0 },
210 {"uxtab" , 0 , 6 , 0}, 220 { "vmovbrs", 0, ARMVFP2, 0 },
211 {"ssub8" , 0 , 6 , 0}, 221 { "vmsr", 0, ARMVFP2, 0 },
212 {"shsub8" , 0 , 6 , 0}, 222 { "vmovbrc", 0, ARMVFP2, 0 },
213 {"ssubaddx" , 0 , 6 , 0}, 223 { "vmrs", 0, ARMVFP2, 0 },
214 {"strex" , 0 , 6 , 0}, 224 { "vmovbcr", 0, ARMVFP2, 0 },
215 {"strexb" , 0 , 7 , 0}, 225 { "vmovbrrss", 0, ARMVFP2, 0 },
216 {"swp" , 0 , 0 , 0}, 226 { "vmovbrrd", 0, ARMVFP2, 0 },
217 {"swpb" , 0 , 0 , 0}, 227 { "vstr", 0, ARMVFP2, 0 },
218 {"ssub16" , 0 , 6 , 0}, 228 { "vpush", 0, ARMVFP2, 0 },
219 {"ssat16" , 0 , 6 , 0}, 229 { "vstm", 0, ARMVFP2, 0 },
220 {"shsubaddx" , 0 , 6 , 0}, 230 { "vpop", 0, ARMVFP2, 0 },
221 {"qsubaddx" , 0 , 6 , 0}, 231 { "vldr", 0, ARMVFP2, 0 },
222 {"shaddsubx" , 0 , 6 , 0}, 232 { "vldm", 0, ARMVFP2, 0 },
223 {"shadd8" , 0 , 6 , 0}, 233
224 {"shadd16" , 0 , 6 , 0}, 234 { "srs", 0, 6, 0 },
225 {"sel" , 0 , 6 , 0}, 235 { "rfe", 0, 6, 0 },
226 {"saddsubx" , 0 , 6 , 0}, 236 { "bkpt", 0, 3, 0 },
227 {"sadd8" , 0 , 6 , 0}, 237 { "blx", 0, 3, 0 },
228 {"sadd16" , 0 , 6 , 0}, 238 { "cps", 0, 6, 0 },
229 {"shsub16" , 0 , 6 , 0}, 239 { "pld", 0, 4, 0 },
230 {"umaal" , 0 , 6 , 0}, 240 { "setend", 0, 6, 0 },
231 {"uxtab16" , 0 , 6 , 0}, 241 { "clrex", 0, 6, 0 },
232 {"usubaddx" , 0 , 6 , 0}, 242 { "rev16", 0, 6, 0 },
233 {"usub8" , 0 , 6 , 0}, 243 { "usad8", 0, 6, 0 },
234 {"usub16" , 0 , 6 , 0}, 244 { "sxtb", 0, 6, 0 },
235 {"usat16" , 0 , 6 , 0}, 245 { "uxtb", 0, 6, 0 },
236 {"usada8" , 0 , 6 , 0}, 246 { "sxth", 0, 6, 0 },
237 {"uqsubaddx" , 0 , 6 , 0}, 247 { "sxtb16", 0, 6, 0 },
238 {"uqsub8" , 0 , 6 , 0}, 248 { "uxth", 0, 6, 0 },
239 {"uqsub16" , 0 , 6 , 0}, 249 { "uxtb16", 0, 6, 0 },
240 {"uqaddsubx" , 0 , 6 , 0}, 250 { "cpy", 0, 6, 0 },
241 {"uqadd8" , 0 , 6 , 0}, 251 { "uxtab", 0, 6, 0 },
242 {"uqadd16" , 0 , 6 , 0}, 252 { "ssub8", 0, 6, 0 },
243 {"sxtab" , 0 , 6 , 0}, 253 { "shsub8", 0, 6, 0 },
244 {"uhsubaddx" , 0 , 6 , 0}, 254 { "ssubaddx", 0, 6, 0 },
245 {"uhsub8" , 0 , 6 , 0}, 255 { "strex", 0, 6, 0 },
246 {"uhsub16" , 0 , 6 , 0}, 256 { "strexb", 0, 7, 0 },
247 {"uhaddsubx" , 0 , 6 , 0}, 257 { "swp", 0, 0, 0 },
248 {"uhadd8" , 0 , 6 , 0}, 258 { "swpb", 0, 0, 0 },
249 {"uhadd16" , 0 , 6 , 0}, 259 { "ssub16", 0, 6, 0 },
250 {"uaddsubx" , 0 , 6 , 0}, 260 { "ssat16", 0, 6, 0 },
251 {"uadd8" , 0 , 6 , 0}, 261 { "shsubaddx", 0, 6, 0 },
252 {"uadd16" , 0 , 6 , 0}, 262 { "qsubaddx", 0, 6, 0 },
253 {"sxtah" , 0 , 6 , 0}, 263 { "shaddsubx", 0, 6, 0 },
254 {"sxtab16" , 0 , 6 , 0}, 264 { "shadd8", 0, 6, 0 },
255 {"qadd8" , 0 , 6 , 0}, 265 { "shadd16", 0, 6, 0 },
256 {"bxj" , 0 , 5 , 0}, 266 { "sel", 0, 6, 0 },
257 {"clz" , 0 , 3 , 0}, 267 { "saddsubx", 0, 6, 0 },
258 {"uxtah" , 0 , 6 , 0}, 268 { "sadd8", 0, 6, 0 },
259 {"bx" , 0 , 2 , 0}, 269 { "sadd16", 0, 6, 0 },
260 {"rev" , 0 , 6 , 0}, 270 { "shsub16", 0, 6, 0 },
261 {"blx" , 0 , 3 , 0}, 271 { "umaal", 0, 6, 0 },
262 {"revsh" , 0 , 6 , 0}, 272 { "uxtab16", 0, 6, 0 },
263 {"qadd" , 0 , 4 , 0}, 273 { "usubaddx", 0, 6, 0 },
264 {"qadd16" , 0 , 6 , 0}, 274 { "usub8", 0, 6, 0 },
265 {"qaddsubx" , 0 , 6 , 0}, 275 { "usub16", 0, 6, 0 },
266 {"ldrex" , 0 , 0 , 0}, 276 { "usat16", 0, 6, 0 },
267 {"qdadd" , 0 , 4 , 0}, 277 { "usada8", 0, 6, 0 },
268 {"qdsub" , 0 , 4 , 0}, 278 { "uqsubaddx", 0, 6, 0 },
269 {"qsub" , 0 , 4 , 0}, 279 { "uqsub8", 0, 6, 0 },
270 {"ldrexb" , 0 , 7 , 0}, 280 { "uqsub16", 0, 6, 0 },
271 {"qsub8" , 0 , 6 , 0}, 281 { "uqaddsubx", 0, 6, 0 },
272 {"qsub16" , 0 , 6 , 0}, 282 { "uqadd8", 0, 6, 0 },
273 {"smuad" , 0 , 6 , 0}, 283 { "uqadd16", 0, 6, 0 },
274 {"smmul" , 0 , 6 , 0}, 284 { "sxtab", 0, 6, 0 },
275 {"smusd" , 0 , 6 , 0}, 285 { "uhsubaddx", 0, 6, 0 },
276 {"smlsd" , 0 , 6 , 0}, 286 { "uhsub8", 0, 6, 0 },
277 {"smlsld" , 0 , 6 , 0}, 287 { "uhsub16", 0, 6, 0 },
278 {"smmla" , 0 , 6 , 0}, 288 { "uhaddsubx", 0, 6, 0 },
279 {"smmls" , 0 , 6 , 0}, 289 { "uhadd8", 0, 6, 0 },
280 {"smlald" , 0 , 6 , 0}, 290 { "uhadd16", 0, 6, 0 },
281 {"smlad" , 0 , 6 , 0}, 291 { "uaddsubx", 0, 6, 0 },
282 {"smlaw" , 0 , 4 , 0}, 292 { "uadd8", 0, 6, 0 },
283 {"smulw" , 0 , 4 , 0}, 293 { "uadd16", 0, 6, 0 },
284 {"pkhtb" , 0 , 6 , 0}, 294 { "sxtah", 0, 6, 0 },
285 {"pkhbt" , 0 , 6 , 0}, 295 { "sxtab16", 0, 6, 0 },
286 {"smul" , 0 , 4 , 0}, 296 { "qadd8", 0, 6, 0 },
287 {"smlal" , 0 , 4 , 0}, 297 { "bxj", 0, 5, 0 },
288 {"smla" , 0 , 4 , 0}, 298 { "clz", 0, 3, 0 },
289 {"mcrr" , 0 , 6 , 0}, 299 { "uxtah", 0, 6, 0 },
290 {"mrrc" , 0 , 6 , 0}, 300 { "bx", 0, 2, 0 },
291 {"cmp" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, 301 { "rev", 0, 6, 0 },
292 {"tst" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, 302 { "blx", 0, 3, 0 },
293 {"teq" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, 303 { "revsh", 0, 6, 0 },
294 {"cmn" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, 304 { "qadd", 0, 4, 0 },
295 {"smull" , 0 , 0 , 0}, 305 { "qadd16", 0, 6, 0 },
296 {"umull" , 0 , 0 , 0}, 306 { "qaddsubx", 0, 6, 0 },
297 {"umlal" , 0 , 0 , 0}, 307 { "ldrex", 0, 0, 0 },
298 {"smlal" , 0 , 0 , 0}, 308 { "qdadd", 0, 4, 0 },
299 {"mul" , 0 , 0 , 0}, 309 { "qdsub", 0, 4, 0 },
300 {"mla" , 0 , 0 , 0}, 310 { "qsub", 0, 4, 0 },
301 {"ssat" , 0 , 6 , 0}, 311 { "ldrexb", 0, 7, 0 },
302 {"usat" , 0 , 6 , 0}, 312 { "qsub8", 0, 6, 0 },
303 {"mrs" , 0 , 0 , 0}, 313 { "qsub16", 0, 6, 0 },
304 {"msr" , 0 , 0 , 0}, 314 { "smuad", 0, 6, 0 },
305 {"and" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, 315 { "smmul", 0, 6, 0 },
306 {"bic" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, 316 { "smusd", 0, 6, 0 },
307 {"ldm" , 0 , 0 , 0}, 317 { "smlsd", 0, 6, 0 },
308 {"eor" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, 318 { "smlsld", 0, 6, 0 },
309 {"add" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, 319 { "smmla", 0, 6, 0 },
310 {"rsb" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, 320 { "smmls", 0, 6, 0 },
311 {"rsc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, 321 { "smlald", 0, 6, 0 },
312 {"sbc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, 322 { "smlad", 0, 6, 0 },
313 {"adc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, 323 { "smlaw", 0, 4, 0 },
314 {"sub" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, 324 { "smulw", 0, 4, 0 },
315 {"orr" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, 325 { "pkhtb", 0, 6, 0 },
316 {"mvn" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, 326 { "pkhbt", 0, 6, 0 },
317 {"mov" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, 327 { "smul", 0, 4, 0 },
318 {"stm" , 0 , 0 , 0}, 328 { "smlal", 0, 4, 0 },
319 {"ldm" , 0 , 0 , 0}, 329 { "smla", 0, 4, 0 },
320 {"ldrsh" , 0 , 2 , 0}, 330 { "mcrr", 0, 6, 0 },
321 {"stm" , 0 , 0 , 0}, 331 { "mrrc", 0, 6, 0 },
322 {"ldm" , 0 , 0 , 0}, 332 { "cmp", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
323 {"ldrsb" , 0 , 2 , 0}, 333 { "tst", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
324 {"strd" , 0 , 4 , 0}, 334 { "teq", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
325 {"ldrh" , 0 , 0 , 0}, 335 { "cmn", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
326 {"strh" , 0 , 0 , 0}, 336 { "smull", 0, 0, 0 },
327 {"ldrd" , 0 , 4 , 0}, 337 { "umull", 0, 0, 0 },
328 {"strt" , 0 , 0 , 0}, 338 { "umlal", 0, 0, 0 },
329 {"strbt" , 0 , 0 , 0}, 339 { "smlal", 0, 0, 0 },
330 {"ldrbt" , 0 , 0 , 0}, 340 { "mul", 0, 0, 0 },
331 {"ldrt" , 0 , 0 , 0}, 341 { "mla", 0, 0, 0 },
332 {"mrc" , 0 , 6 , 0}, 342 { "ssat", 0, 6, 0 },
333 {"mcr" , 0 , 0 , 0}, 343 { "usat", 0, 6, 0 },
334 {"msr" , 0 , 0 , 0}, 344 { "mrs", 0, 0, 0 },
335 {"ldrb" , 0 , 0 , 0}, 345 { "msr", 0, 0, 0 },
336 {"strb" , 0 , 0 , 0}, 346 { "and", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
337 {"ldr" , 0 , 0 , 0}, 347 { "bic", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
338 {"ldrcond" , 1 , 0 , 28, 31, 0x0000000e}, 348 { "ldm", 0, 0, 0 },
339 {"str" , 0 , 0 , 0}, 349 { "eor", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
340 {"cdp" , 0 , 0 , 0}, 350 { "add", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
341 {"stc" , 0 , 0 , 0}, 351 { "rsb", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
342 {"ldc" , 0 , 0 , 0}, 352 { "rsc", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
343 {"swi" , 0 , 0 , 0}, 353 { "sbc", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
344 {"bbl" , 0 , 0 , 0}, 354 { "adc", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
345 {"bl_1_thumb", 0, INVALID, 0},/* should be table[-4] */ 355 { "sub", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
346 {"bl_2_thumb", 0, INVALID, 0}, /* should be located at the end of the table[-3] */ 356 { "orr", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
347 {"blx_1_thumb", 0, INVALID, 0}, /* should be located at table[-2] */ 357 { "mvn", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
348 {"invalid", 0, INVALID, 0} 358 { "mov", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
359 { "stm", 0, 0, 0 },
360 { "ldm", 0, 0, 0 },
361 { "ldrsh", 0, 2, 0 },
362 { "stm", 0, 0, 0 },
363 { "ldm", 0, 0, 0 },
364 { "ldrsb", 0, 2, 0 },
365 { "strd", 0, 4, 0 },
366 { "ldrh", 0, 0, 0 },
367 { "strh", 0, 0, 0 },
368 { "ldrd", 0, 4, 0 },
369 { "strt", 0, 0, 0 },
370 { "strbt", 0, 0, 0 },
371 { "ldrbt", 0, 0, 0 },
372 { "ldrt", 0, 0, 0 },
373 { "mrc", 0, 6, 0 },
374 { "mcr", 0, 0, 0 },
375 { "msr", 0, 0, 0 },
376 { "ldrb", 0, 0, 0 },
377 { "strb", 0, 0, 0 },
378 { "ldr", 0, 0, 0 },
379 { "ldrcond", 1, 0, 28, 31, 0x0000000e },
380 { "str", 0, 0, 0 },
381 { "cdp", 0, 0, 0 },
382 { "stc", 0, 0, 0 },
383 { "ldc", 0, 0, 0 },
384 { "swi", 0, 0, 0 },
385 { "bbl", 0, 0, 0 },
386 { "bl_1_thumb", 0, INVALID, 0 }, // Should be table[-4]
387 { "bl_2_thumb", 0, INVALID, 0 }, // Should be located at the end of the table[-3]
388 { "blx_1_thumb", 0, INVALID, 0 }, // Should be located at table[-2]
389 { "invalid", 0, INVALID, 0 }
349}; 390};
350 391
351int decode_arm_instr(uint32_t instr, int32_t *idx) 392int decode_arm_instr(uint32_t instr, int32_t *idx) {
352{ 393 int n = 0;
353 int n = 0; 394 int base = 0;
354 int base = 0; 395 int ret = DECODE_FAILURE;
355 int ret = DECODE_FAILURE; 396 int i = 0;
356 int i = 0; 397 int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM);
357 int instr_slots = sizeof(arm_instruction)/sizeof(ISEITEM); 398 for (i = 0; i < instr_slots; i++) {
358 for (i = 0; i < instr_slots; i++) 399 n = arm_instruction[i].attribute_value;
359 { 400 base = 0;
360// ret = DECODE_SUCCESS;
361 n = arm_instruction[i].attribute_value;
362 base = 0;
363 while (n) {
364 if (arm_instruction[i].content[base + 1] == 31 && arm_instruction[i].content[base] == 0) {
365 /* clrex */
366 if (instr != arm_instruction[i].content[base + 2]) {
367 break;
368 }
369 } else if (BITS(arm_instruction[i].content[base], arm_instruction[i].content[base + 1]) != arm_instruction[i].content[base + 2]) {
370 break;
371 }
372 base += 3;
373 n --;
374 }
375 //All conditions is satisfied.
376 if (n == 0)
377 ret = DECODE_SUCCESS;
378 401
379 if (ret == DECODE_SUCCESS) { 402 while (n) {
380 n = arm_exclusion_code[i].attribute_value; 403 if (arm_instruction[i].content[base + 1] == 31 && arm_instruction[i].content[base] == 0) {
381 if (n != 0) { 404 // clrex
382 base = 0; 405 if (instr != arm_instruction[i].content[base + 2]) {
383 while (n) { 406 break;
384 if (BITS(arm_exclusion_code[i].content[base], arm_exclusion_code[i].content[base + 1]) != arm_exclusion_code[i].content[base + 2]) { 407 }
385 break; } 408 } else if (BITS(arm_instruction[i].content[base], arm_instruction[i].content[base + 1]) != arm_instruction[i].content[base + 2]) {
386 base += 3; 409 break;
387 n --; 410 }
388 } 411 base += 3;
389 //All conditions is satisfied. 412 n--;
390 if (n == 0) 413 }
391 ret = DECODE_FAILURE;
392 }
393 }
394 414
395 if (ret == DECODE_SUCCESS) { 415 // All conditions is satisfied.
396 *idx = i; 416 if (n == 0)
397 return ret; 417 ret = DECODE_SUCCESS;
398 }
399 }
400 return ret;
401}
402 418
419 if (ret == DECODE_SUCCESS) {
420 n = arm_exclusion_code[i].attribute_value;
421 if (n != 0) {
422 base = 0;
423 while (n) {
424 if (BITS(arm_exclusion_code[i].content[base], arm_exclusion_code[i].content[base + 1]) != arm_exclusion_code[i].content[base + 2]) {
425 break;
426 }
427 base += 3;
428 n--;
429 }
430
431 // All conditions is satisfied.
432 if (n == 0)
433 ret = DECODE_FAILURE;
434 }
435 }
436
437 if (ret == DECODE_SUCCESS) {
438 *idx = i;
439 return ret;
440 }
441 }
442 return ret;
443}
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.h b/src/core/arm/dyncom/arm_dyncom_dec.h
index 19d94f369..70eb96e93 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.h
+++ b/src/core/arm/dyncom/arm_dyncom_dec.h
@@ -56,8 +56,6 @@
56#define RN ((instr >> 16) & 0xF) 56#define RN ((instr >> 16) & 0xF)
57/*xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 */ 57/*xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 */
58#define RM (instr & 0xF) 58#define RM (instr & 0xF)
59#define BIT(n) ((instr >> (n)) & 1)
60#define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1))
61 59
62/* CP15 registers */ 60/* CP15 registers */
63#define OPCODE_1 BITS(21, 23) 61#define OPCODE_1 BITS(21, 23)
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 37925e8a8..53da7ca9c 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -1,32 +1,11 @@
1/* Copyright (C) 1// Copyright 2012 Michael Kang, 2014 Citra Emulator Project
2* 2012 - Michael.Kang blackfin.kang@gmail.com 2// Licensed under GPLv2 or any later version
3* This program is free software; you can redistribute it and/or 3// Refer to the license.txt file included.
4* modify it under the terms of the GNU General Public License
5* as published by the Free Software Foundation; either version 2
6* of the License, or (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18/**
19* @file arm_dyncom_interpreter.cpp
20* @brief The fast interpreter for arm
21* @author Michael.Kang blackfin.kang@gmail.com
22* @version 7849
23* @date 2012-03-15
24*/
25 4
26#define CITRA_IGNORE_EXIT(x) 5#define CITRA_IGNORE_EXIT(x)
27 6
28#include <algorithm> 7#include <algorithm>
29#include <map> 8#include <unordered_map>
30#include <stdio.h> 9#include <stdio.h>
31#include <assert.h> 10#include <assert.h>
32#include <cstdio> 11#include <cstdio>
@@ -47,10 +26,6 @@ using namespace std;
47#include "arm_dyncom_thumb.h" 26#include "arm_dyncom_thumb.h"
48#include "arm_dyncom_run.h" 27#include "arm_dyncom_run.h"
49#include "core/arm/skyeye_common/vfp/vfp.h" 28#include "core/arm/skyeye_common/vfp/vfp.h"
50/* shenoubang 2012-6-14 */
51#ifdef __WIN32__
52#include "bank_defs.h"
53#endif
54 29
55#include "core/mem_map.h" 30#include "core/mem_map.h"
56#include "core/hle/hle.h" 31#include "core/hle/hle.h"
@@ -66,327 +41,243 @@ enum {
66 THUMB = (1 << 7) 41 THUMB = (1 << 7)
67}; 42};
68 43
69#define USER_MODE_OPT 1 44#define USER_MODE_OPT 1
70#define HYBRID_MODE 0 // Enable for JIT mode 45#define HYBRID_MODE 0 // Enable for JIT mode
71 46
72#define THRESHOLD 1000 47#define THRESHOLD 1000
73#define DURATION 500 48#define DURATION 500
74//#define PRINT_PROFILE_INFO
75 49
76#define CHECK_RS if(RS == 15) rs += 8 50#define CHECK_RS if(RS == 15) rs += 8
77#define CHECK_RM if(RM == 15) rm += 8 51#define CHECK_RM if(RM == 15) rm += 8
78 52
79//#define BITS(s, a, b) (((s) >> (a)) & ((1 << (1 + (b) - (a))) - 1))
80#undef BITS 53#undef BITS
81#define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1)) 54#define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1))
82#define BIT(s, n) ((s >> (n)) & 1) 55#define BIT(s, n) ((s >> (n)) & 1)
83#define RM BITS(sht_oper, 0, 3) 56#define RM BITS(sht_oper, 0, 3)
84#define RS BITS(sht_oper, 8, 11) 57#define RS BITS(sht_oper, 8, 11)
85 58
86#define glue(x, y) x ## y 59#define glue(x, y) x ## y
87#define DPO(s) glue(DataProcessingOperands, s) 60#define DPO(s) glue(DataProcessingOperands, s)
88#define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i)) 61#define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i))
89#define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i)) 62#define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i))
90#define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32) 63#define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32)
91#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32) 64#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32)
92 65
93//#define rotr(x,n) ((((x)>>(n))&((1<<(sizeof(x) * 8)-1))|(x<<(sizeof(x)*8-n))))
94//#define rotl(x,n) ((((x)<<(n))&(-(1<<(n))))|(((x)>>(sizeof(x)*8-n))&((1<<(n))-1)))
95#define rotr(x,n) ( (x >> n) | ((x & ((1 << (n + 1)) - 1)) << (32 - n)) ) 66#define rotr(x,n) ( (x >> n) | ((x & ((1 << (n + 1)) - 1)) << (32 - n)) )
96 67
97extern void switch_mode(arm_core_t *core, uint32_t mode); 68extern void switch_mode(arm_core_t *core, uint32_t mode);
98//extern bool InAPrivilegedMode(arm_core_t *core);
99 69
100typedef arm_core_t arm_processor; 70typedef arm_core_t arm_processor;
101typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper); 71typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper);
102 72
103/* exclusive memory access */ 73// Exclusive memory access
104static int exclusive_detect(ARMul_State* state, ARMword addr){ 74static int exclusive_detect(ARMul_State* state, ARMword addr){
105 int i; 75 if(state->exclusive_tag == addr)
106 #if 0 76 return 0;
107 for(i = 0; i < 128; i++){ 77 else
108 if(state->exclusive_tag_array[i] == addr) 78 return -1;
109 return 0;
110 }
111 #endif
112 if(state->exclusive_tag == addr)
113 return 0;
114 else
115 return -1;
116} 79}
117 80
118static void add_exclusive_addr(ARMul_State* state, ARMword addr){ 81static void add_exclusive_addr(ARMul_State* state, ARMword addr){
119 int i; 82 state->exclusive_tag = addr;
120 #if 0 83 return;
121 for(i = 0; i < 128; i++){
122 if(state->exclusive_tag_array[i] == 0xffffffff){
123 state->exclusive_tag_array[i] = addr;
124 //DEBUG_LOG(ARM11, "In %s, add addr 0x%x\n", __func__, addr);
125 return;
126 }
127 }
128 DEBUG_LOG(ARM11, "In %s ,can not monitor the addr, out of array\n", __FUNCTION__);
129 #endif
130 state->exclusive_tag = addr;
131 return;
132} 84}
133 85
134static void remove_exclusive(ARMul_State* state, ARMword addr){ 86static void remove_exclusive(ARMul_State* state, ARMword addr){
135 #if 0 87 state->exclusive_tag = 0xFFFFFFFF;
136 int i; 88}
137 for(i = 0; i < 128; i++){ 89
138 if(state->exclusive_tag_array[i] == addr){ 90
139 state->exclusive_tag_array[i] = 0xffffffff; 91unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) {
140 //DEBUG_LOG(ARM11, "In %s, remove addr 0x%x\n", __func__, addr); 92 unsigned int immed_8 = BITS(sht_oper, 0, 7);
141 return; 93 unsigned int rotate_imm = BITS(sht_oper, 8, 11);
142 } 94 unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2);
143 } 95 if (rotate_imm == 0)
144 #endif 96 cpu->shifter_carry_out = cpu->CFlag;
145 state->exclusive_tag = 0xFFFFFFFF; 97 else
146} 98 cpu->shifter_carry_out = BIT(shifter_operand, 31);
147 99 return shifter_operand;
148 100}
149unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) 101
150{ 102unsigned int DPO(Register)(arm_processor *cpu, unsigned int sht_oper) {
151// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); 103 unsigned int rm = CHECK_READ_REG15(cpu, RM);
152 unsigned int immed_8 = BITS(sht_oper, 0, 7); 104 unsigned int shifter_operand = rm;
153 unsigned int rotate_imm = BITS(sht_oper, 8, 11); 105 cpu->shifter_carry_out = cpu->CFlag;
154// DEBUG_LOG(ARM11, "immed_8 is %x\n", immed_8); 106 return shifter_operand;
155// DEBUG_LOG(ARM11, "rotate_imm is %x\n", rotate_imm); 107}
156 unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2);//ROTATE_RIGHT_32(immed_8, rotate_imm * 2); 108
157// DEBUG_LOG(ARM11, "shifter_operand : %x\n", shifter_operand); 109unsigned int DPO(LogicalShiftLeftByImmediate)(arm_processor *cpu, unsigned int sht_oper) {
158 /* set c flag */ 110 int shift_imm = BITS(sht_oper, 7, 11);
159 if (rotate_imm == 0) 111 unsigned int rm = CHECK_READ_REG15(cpu, RM);
160 cpu->shifter_carry_out = cpu->CFlag; 112 unsigned int shifter_operand;
161 else 113 if (shift_imm == 0) {
162 cpu->shifter_carry_out = BIT(shifter_operand, 31); 114 shifter_operand = rm;
163 return shifter_operand; 115 cpu->shifter_carry_out = cpu->CFlag;
164} 116 } else {
165 117 shifter_operand = rm << shift_imm;
166unsigned int DPO(Register)(arm_processor *cpu, unsigned int sht_oper) 118 cpu->shifter_carry_out = BIT(rm, 32 - shift_imm);
167{ 119 }
168// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); 120 return shifter_operand;
169 unsigned int rm = CHECK_READ_REG15(cpu, RM); 121}
170 //if (RM == 15) rm += 8; 122
171 unsigned int shifter_operand = rm; 123unsigned int DPO(LogicalShiftLeftByRegister)(arm_processor *cpu, unsigned int sht_oper) {
172 cpu->shifter_carry_out = cpu->CFlag; 124 int shifter_operand;
173 return shifter_operand; 125 unsigned int rm = CHECK_READ_REG15(cpu, RM);
126 unsigned int rs = CHECK_READ_REG15(cpu, RS);
127 if (BITS(rs, 0, 7) == 0) {
128 shifter_operand = rm;
129 cpu->shifter_carry_out = cpu->CFlag;
130 } else if (BITS(rs, 0, 7) < 32) {
131 shifter_operand = rm << BITS(rs, 0, 7);
132 cpu->shifter_carry_out = BIT(rm, 32 - BITS(rs, 0, 7));
133 } else if (BITS(rs, 0, 7) == 32) {
134 shifter_operand = 0;
135 cpu->shifter_carry_out = BIT(rm, 0);
136 } else {
137 shifter_operand = 0;
138 cpu->shifter_carry_out = 0;
139 }
140 return shifter_operand;
141}
142
143unsigned int DPO(LogicalShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) {
144 unsigned int rm = CHECK_READ_REG15(cpu, RM);
145 unsigned int shifter_operand;
146 int shift_imm = BITS(sht_oper, 7, 11);
147 if (shift_imm == 0) {
148 shifter_operand = 0;
149 cpu->shifter_carry_out = BIT(rm, 31);
150 } else {
151 shifter_operand = rm >> shift_imm;
152 cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
153 }
154 return shifter_operand;
155}
156
157unsigned int DPO(LogicalShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper) {
158 unsigned int rs = CHECK_READ_REG15(cpu, RS);
159 unsigned int rm = CHECK_READ_REG15(cpu, RM);
160 unsigned int shifter_operand;
161 if (BITS(rs, 0, 7) == 0) {
162 shifter_operand = rm;
163 cpu->shifter_carry_out = cpu->CFlag;
164 } else if (BITS(rs, 0, 7) < 32) {
165 shifter_operand = rm >> BITS(rs, 0, 7);
166 cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
167 } else if (BITS(rs, 0, 7) == 32) {
168 shifter_operand = 0;
169 cpu->shifter_carry_out = BIT(rm, 31);
170 } else {
171 shifter_operand = 0;
172 cpu->shifter_carry_out = 0;
173 }
174 return shifter_operand;
175}
176
177unsigned int DPO(ArithmeticShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) {
178 unsigned int rm = CHECK_READ_REG15(cpu, RM);
179 unsigned int shifter_operand;
180 int shift_imm = BITS(sht_oper, 7, 11);
181 if (shift_imm == 0) {
182 if (BIT(rm, 31)) {
183 shifter_operand = 0;
184 cpu->shifter_carry_out = BIT(rm, 31);
185 } else {
186 shifter_operand = 0xFFFFFFFF;
187 cpu->shifter_carry_out = BIT(rm, 31);
188 }
189 } else {
190 shifter_operand = static_cast<int>(rm) >> shift_imm;
191 cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
192 }
193 return shifter_operand;
194}
195
196unsigned int DPO(ArithmeticShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper) {
197 unsigned int rs = CHECK_READ_REG15(cpu, RS);
198 unsigned int rm = CHECK_READ_REG15(cpu, RM);
199 unsigned int shifter_operand;
200 if (BITS(rs, 0, 7) == 0) {
201 shifter_operand = rm;
202 cpu->shifter_carry_out = cpu->CFlag;
203 } else if (BITS(rs, 0, 7) < 32) {
204 shifter_operand = static_cast<int>(rm) >> BITS(rs, 0, 7);
205 cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
206 } else {
207 if (BIT(rm, 31) == 0)
208 shifter_operand = 0;
209 else
210 shifter_operand = 0xffffffff;
211 cpu->shifter_carry_out = BIT(rm, 31);
212 }
213 return shifter_operand;
214}
215
216unsigned int DPO(RotateRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) {
217 unsigned int shifter_operand;
218 unsigned int rm = CHECK_READ_REG15(cpu, RM);
219 int shift_imm = BITS(sht_oper, 7, 11);
220 if (shift_imm == 0) {
221 shifter_operand = (cpu->CFlag << 31) | (rm >> 1);
222 cpu->shifter_carry_out = BIT(rm, 0);
223 } else {
224 shifter_operand = ROTATE_RIGHT_32(rm, shift_imm);
225 cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
226 }
227 return shifter_operand;
228}
229
230unsigned int DPO(RotateRightByRegister)(arm_processor *cpu, unsigned int sht_oper) {
231 unsigned int rm = CHECK_READ_REG15(cpu, RM);
232 unsigned int rs = CHECK_READ_REG15(cpu, RS);
233 unsigned int shifter_operand;
234 if (BITS(rs, 0, 7) == 0) {
235 shifter_operand = rm;
236 cpu->shifter_carry_out = cpu->CFlag;
237 } else if (BITS(rs, 0, 4) == 0) {
238 shifter_operand = rm;
239 cpu->shifter_carry_out = BIT(rm, 31);
240 } else {
241 shifter_operand = ROTATE_RIGHT_32(rm, BITS(rs, 0, 4));
242 cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 4) - 1);
243 }
244 return shifter_operand;
174} 245}
175 246
176unsigned int DPO(LogicalShiftLeftByImmediate)(arm_processor *cpu, unsigned int sht_oper)
177{
178// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
179 int shift_imm = BITS(sht_oper, 7, 11);
180 unsigned int rm = CHECK_READ_REG15(cpu, RM);
181 //if (RM == 15) rm += 8;
182 unsigned int shifter_operand;
183 if (shift_imm == 0) {
184 shifter_operand = rm;
185 cpu->shifter_carry_out = cpu->CFlag;
186 } else {
187 shifter_operand = rm << shift_imm;
188 cpu->shifter_carry_out = BIT(rm, 32 - shift_imm);
189 }
190 return shifter_operand;
191}
192
193unsigned int DPO(LogicalShiftLeftByRegister)(arm_processor *cpu, unsigned int sht_oper)
194{
195// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
196 int shifter_operand;
197 unsigned int rm = CHECK_READ_REG15(cpu, RM);
198 unsigned int rs = CHECK_READ_REG15(cpu, RS);
199 //if (RM == 15) rm += 8;
200 //if (RS == 15) rs += 8;
201 if (BITS(rs, 0, 7) == 0) {
202 shifter_operand = rm;
203 cpu->shifter_carry_out = cpu->CFlag;
204 } else if (BITS(rs, 0, 7) < 32) {
205 shifter_operand = rm << BITS(rs, 0, 7);
206 cpu->shifter_carry_out = BIT(rm, 32 - BITS(rs, 0, 7));
207 } else if (BITS(rs, 0, 7) == 32) {
208 shifter_operand = 0;
209 cpu->shifter_carry_out = BIT(rm, 0);
210 } else {
211 shifter_operand = 0;
212 cpu->shifter_carry_out = 0;
213 }
214 return shifter_operand;
215}
216
217unsigned int DPO(LogicalShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper)
218{
219// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
220 //unsigned int rm = cpu->Reg[RM];
221 unsigned int rm = CHECK_READ_REG15(cpu, RM);
222 //if (RM == 15) rm += 8;
223 unsigned int shifter_operand;
224 int shift_imm = BITS(sht_oper, 7, 11);
225 if (shift_imm == 0) {
226 shifter_operand = 0;
227 cpu->shifter_carry_out = BIT(rm, 31);
228 } else {
229 shifter_operand = rm >> shift_imm;
230 cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
231 }
232 return shifter_operand;
233}
234
235unsigned int DPO(LogicalShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper)
236{
237// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
238 unsigned int rs = CHECK_READ_REG15(cpu, RS);
239 unsigned int rm = CHECK_READ_REG15(cpu, RM);
240 //if (RS == 15) rs += 8;
241 //if (RM == 15) rm += 8;
242 unsigned int shifter_operand;
243 if (BITS(rs, 0, 7) == 0) {
244 shifter_operand = rm;
245 cpu->shifter_carry_out = cpu->CFlag;
246 } else if (BITS(rs, 0, 7) < 32) {
247 shifter_operand = rm >> BITS(rs, 0, 7);
248 cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
249 } else if (BITS(rs, 0, 7) == 32) {
250 shifter_operand = 0;
251 cpu->shifter_carry_out = BIT(rm, 31);
252 } else {
253 shifter_operand = 0;
254 cpu->shifter_carry_out = 0;
255 }
256 return shifter_operand;
257}
258
259unsigned int DPO(ArithmeticShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper)
260{
261// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
262 //unsigned int rm = cpu->Reg[RM];
263 unsigned int rm = CHECK_READ_REG15(cpu, RM);
264 //if (RM == 15) rm += 8;
265 unsigned int shifter_operand;
266 int shift_imm = BITS(sht_oper, 7, 11);
267 if (shift_imm == 0) {
268 if (BIT(rm, 31)) {
269 shifter_operand = 0;
270 cpu->shifter_carry_out = BIT(rm, 31);
271 } else {
272 shifter_operand = 0xFFFFFFFF;
273 cpu->shifter_carry_out = BIT(rm, 31);
274 }
275 } else {
276 shifter_operand = static_cast<int>(rm) >> shift_imm;
277 cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
278 }
279 return shifter_operand;
280}
281
282unsigned int DPO(ArithmeticShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper)
283{
284// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
285 //unsigned int rs = cpu->Reg[RS];
286 unsigned int rs = CHECK_READ_REG15(cpu, RS);
287 //unsigned int rm = cpu->Reg[RM];
288 unsigned int rm = CHECK_READ_REG15(cpu, RM);
289 //if (RS == 15) rs += 8;
290 //if (RM == 15) rm += 8;
291 unsigned int shifter_operand;
292 if (BITS(rs, 0, 7) == 0) {
293 shifter_operand = rm;
294 cpu->shifter_carry_out = cpu->CFlag;
295 } else if (BITS(rs, 0, 7) < 32) {
296 shifter_operand = static_cast<int>(rm) >> BITS(rs, 0, 7);
297 cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
298 } else {
299 if (BIT(rm, 31) == 0) {
300 shifter_operand = 0;
301 } else
302 shifter_operand = 0xffffffff;
303 cpu->shifter_carry_out = BIT(rm, 31);
304 }
305 return shifter_operand;
306}
307
308unsigned int DPO(RotateRightByImmediate)(arm_processor *cpu, unsigned int sht_oper)
309{
310// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
311 unsigned int shifter_operand;
312 //unsigned int rm = cpu->Reg[RM];
313 unsigned int rm = CHECK_READ_REG15(cpu, RM);
314 //if (RM == 15) rm += 8;
315 int shift_imm = BITS(sht_oper, 7, 11);
316 if (shift_imm == 0) {
317 shifter_operand = (cpu->CFlag << 31) |
318 (rm >> 1);
319 cpu->shifter_carry_out = BIT(rm, 0);
320 } else {
321 shifter_operand = ROTATE_RIGHT_32(rm, shift_imm);
322 cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
323 }
324 return shifter_operand;
325}
326
327unsigned int DPO(RotateRightByRegister)(arm_processor *cpu, unsigned int sht_oper)
328{
329// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
330 unsigned int rm = CHECK_READ_REG15(cpu, RM);
331 //if (RM == 15) rm += 8;
332 unsigned int rs = CHECK_READ_REG15(cpu, RS);
333 //if (RS == 15) rs += 8;
334 unsigned int shifter_operand;
335 if (BITS(rs, 0, 7) == 0) {
336 shifter_operand = rm;
337 cpu->shifter_carry_out = cpu->CFlag;
338 } else if (BITS(rs, 0, 4) == 0) {
339 shifter_operand = rm;
340 cpu->shifter_carry_out = BIT(rm, 31);
341 } else {
342 shifter_operand = ROTATE_RIGHT_32(rm, BITS(rs, 0, 4));
343 cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 4) - 1);
344 }
345 #if 0
346 if (cpu->icounter >= 20371544) {
347 DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
348 DEBUG_LOG(ARM11, "RM:%d\nRS:%d\n", RM, RS);
349 DEBUG_LOG(ARM11, "rm:0x%08x\nrs:0x%08x\n", cpu->Reg[RM], cpu->Reg[RS]);
350 }
351 #endif
352 return shifter_operand;
353}
354
355//typedef unsigned int (*get_addr_fp_t)(arm_processor *cpu);
356typedef struct _MiscImmeData { 247typedef struct _MiscImmeData {
357 unsigned int U; 248 unsigned int U;
358 unsigned int Rn; 249 unsigned int Rn;
359 unsigned int offset_8; 250 unsigned int offset_8;
360} MiscLSData; 251} MiscLSData;
361 252
362typedef struct _MiscRegData { 253typedef struct _MiscRegData {
363 unsigned int U; 254 unsigned int U;
364 unsigned int Rn; 255 unsigned int Rn;
365 unsigned int Rm; 256 unsigned int Rm;
366} MiscRegData; 257} MiscRegData;
367 258
368typedef struct _MiscImmePreIdx { 259typedef struct _MiscImmePreIdx {
369 unsigned int offset_8; 260 unsigned int offset_8;
370 unsigned int U; 261 unsigned int U;
371 unsigned int Rn; 262 unsigned int Rn;
372} MiscImmePreIdx; 263} MiscImmePreIdx;
373 264
374typedef struct _MiscRegPreIdx { 265typedef struct _MiscRegPreIdx {
375 unsigned int U; 266 unsigned int U;
376 unsigned int Rn; 267 unsigned int Rn;
377 unsigned int Rm; 268 unsigned int Rm;
378} MiscRegPreIdx; 269} MiscRegPreIdx;
379 270
380typedef struct _MiscImmePstIdx { 271typedef struct _MiscImmePstIdx {
381 unsigned int offset_8; 272 unsigned int offset_8;
382 unsigned int U; 273 unsigned int U;
383 unsigned int Rn; 274 unsigned int Rn;
384} MIscImmePstIdx; 275} MIscImmePstIdx;
385 276
386typedef struct _MiscRegPstIdx { 277typedef struct _MiscRegPstIdx {
387 unsigned int Rn; 278 unsigned int Rn;
388 unsigned int Rm; 279 unsigned int Rm;
389 unsigned int U; 280 unsigned int U;
390} MiscRegPstIdx; 281} MiscRegPstIdx;
391 282
392typedef struct _LSWordorUnsignedByte { 283typedef struct _LSWordorUnsignedByte {
@@ -394,40 +285,38 @@ typedef struct _LSWordorUnsignedByte {
394 285
395#if USER_MODE_OPT 286#if USER_MODE_OPT
396static inline fault_t interpreter_read_memory(addr_t virt_addr, addr_t phys_addr, uint32_t &value, uint32_t size){ 287static inline fault_t interpreter_read_memory(addr_t virt_addr, addr_t phys_addr, uint32_t &value, uint32_t size){
397 switch(size) { 288 switch(size) {
398 case 8: 289 case 8:
399 value = Memory::Read8(virt_addr); 290 value = Memory::Read8(virt_addr);
400 break; 291 break;
401 case 16: 292 case 16:
402 value = Memory::Read16(virt_addr); 293 value = Memory::Read16(virt_addr);
403 break; 294 break;
404 case 32: 295 case 32:
405 value = Memory::Read32(virt_addr); 296 value = Memory::Read32(virt_addr);
406 break; 297 break;
407 } 298 }
408 return NO_FAULT; 299 return NO_FAULT;
409} 300}
410 301
411//static inline void interpreter_write_memory(void *mem_ptr, uint32_t offset, uint32_t value, int size) 302static inline fault_t interpreter_write_memory(addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size) {
412static inline fault_t interpreter_write_memory(addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size) 303 switch(size) {
413{ 304 case 8:
414 switch(size) {
415 case 8:
416 Memory::Write8(virt_addr, value & 0xff); 305 Memory::Write8(virt_addr, value & 0xff);
417 break; 306 break;
418 case 16: 307 case 16:
419 Memory::Write16(virt_addr, value & 0xffff); 308 Memory::Write16(virt_addr, value & 0xffff);
420 break; 309 break;
421 case 32: 310 case 32:
422 Memory::Write32(virt_addr, value); 311 Memory::Write32(virt_addr, value);
423 break; 312 break;
424 } 313 }
425 return NO_FAULT; 314 return NO_FAULT;
426} 315}
427 316
428static inline fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_addr, uint32_t rw){ 317static inline fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_addr, uint32_t rw) {
429 *phys_addr = virt_addr; 318 *phys_addr = virt_addr;
430 return NO_FAULT; 319 return NO_FAULT;
431} 320}
432 321
433#else 322#else
@@ -440,738 +329,679 @@ fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_
440typedef fault_t (*get_addr_fp_t)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw); 329typedef fault_t (*get_addr_fp_t)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw);
441 330
442typedef struct _ldst_inst { 331typedef struct _ldst_inst {
443 unsigned int inst; 332 unsigned int inst;
444 get_addr_fp_t get_addr; 333 get_addr_fp_t get_addr;
445} ldst_inst; 334} ldst_inst;
446#define DEBUG_MSG DEBUG_LOG(ARM11, "in %s %d\n", __FUNCTION__, __LINE__); \ 335#define DEBUG_MSG LOG_DEBUG(Core_ARM11, "inst is %x", inst); CITRA_IGNORE_EXIT(0)
447 DEBUG_LOG(ARM11, "inst is %x\n", inst); \
448 CITRA_IGNORE_EXIT(0)
449 336
450int CondPassed(arm_processor *cpu, unsigned int cond); 337int CondPassed(arm_processor *cpu, unsigned int cond);
451#define LnSWoUB(s) glue(LnSWoUB, s) 338#define LnSWoUB(s) glue(LnSWoUB, s)
452#define MLnS(s) glue(MLnS, s) 339#define MLnS(s) glue(MLnS, s)
453#define LdnStM(s) glue(LdnStM, s) 340#define LdnStM(s) glue(LdnStM, s)
454 341
455#define W_BIT BIT(inst, 21) 342#define W_BIT BIT(inst, 21)
456#define U_BIT BIT(inst, 23) 343#define U_BIT BIT(inst, 23)
457#define I_BIT BIT(inst, 25) 344#define I_BIT BIT(inst, 25)
458#define P_BIT BIT(inst, 24) 345#define P_BIT BIT(inst, 24)
459#define OFFSET_12 BITS(inst, 0, 11) 346#define OFFSET_12 BITS(inst, 0, 11)
460fault_t LnSWoUB(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) 347fault_t LnSWoUB(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
461{ 348 unsigned int Rn = BITS(inst, 16, 19);
462 unsigned int Rn = BITS(inst, 16, 19); 349 unsigned int addr;
463 unsigned int addr; 350 fault_t fault;
464 fault_t fault; 351 if (U_BIT) {
465 if (U_BIT) { 352 addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
466 addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; 353 } else {
467 } else { 354 addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
468 addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; 355 }
469 } 356 virt_addr = addr;
470 //if (Rn == 15) rn += 8; 357 fault = check_address_validity(cpu, addr, &phys_addr, rw);
471 virt_addr = addr; 358 return fault;
472 fault = check_address_validity(cpu, addr, &phys_addr, rw); 359}
473 return fault; 360
474// return addr; 361fault_t LnSWoUB(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
475} 362 fault_t fault;
476 363 unsigned int Rn = BITS(inst, 16, 19);
477fault_t LnSWoUB(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) 364 unsigned int Rm = BITS(inst, 0, 3);
478{ 365 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
479 fault_t fault; 366 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
480 unsigned int Rn = BITS(inst, 16, 19); 367 unsigned int addr;
481 unsigned int Rm = BITS(inst, 0, 3); 368 if (U_BIT) {
482 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); 369 addr = rn + rm;
483 //if (Rn == 15) rn += 8; 370 } else {
484 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); 371 addr = rn - rm;
485 //if (Rm == 15) rm += 8; 372 }
486 unsigned int addr; 373 virt_addr = addr;
487 if (U_BIT) { 374 fault = check_address_validity(cpu, addr, &phys_addr, rw);
488 addr = rn + rm; 375 return fault;
489 } else { 376}
490 addr = rn - rm; 377
491 } 378fault_t LnSWoUB(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
492 virt_addr = addr; 379 fault_t fault;
493 fault = check_address_validity(cpu, addr, &phys_addr, rw); 380 unsigned int Rn = BITS(inst, 16, 19);
494 return fault; 381 unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn);
495} 382
496 383 virt_addr = addr;
497fault_t LnSWoUB(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) 384 fault = check_address_validity(cpu, addr, &phys_addr, rw);
498{ 385 if (fault) return fault;
499 fault_t fault; 386
500 unsigned int Rn = BITS(inst, 16, 19); 387 if (U_BIT) {
501 unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn); 388 cpu->Reg[Rn] += OFFSET_12;
502 //if (Rn == 15) addr += 8; 389 } else {
390 cpu->Reg[Rn] -= OFFSET_12;
391 }
392 return fault;
393}
503 394
504 virt_addr = addr; 395fault_t LnSWoUB(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
505 fault = check_address_validity(cpu, addr, &phys_addr, rw); 396 fault_t fault;
506 if (fault) return fault; 397 unsigned int Rn = BITS(inst, 16, 19);
398 unsigned int addr;
399 if (U_BIT) {
400 addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
401 } else {
402 addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
403 }
404
405 virt_addr = addr;
406 fault = check_address_validity(cpu, addr, &phys_addr, rw);
407 if (fault) return fault;
507 408
508 if (U_BIT) { 409 if (CondPassed(cpu, BITS(inst, 28, 31))) {
509 cpu->Reg[Rn] += OFFSET_12; 410 cpu->Reg[Rn] = addr;
510 } else { 411 }
511 cpu->Reg[Rn] -= OFFSET_12; 412 return fault;
512 } 413}
513 return fault; 414
415fault_t MLnS(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
416 fault_t fault;
417 unsigned int addr;
418 unsigned int Rn = BITS(inst, 16, 19);
419 unsigned int Rm = BITS(inst, 0, 3);
420 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
421 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
422
423 if (U_BIT) {
424 addr = rn + rm;
425 } else
426 addr = rn - rm;
427 if(BIT(inst, 20)){ // L BIT
428 }
429 if(BIT(inst, 6)){ // Sign Bit
430 }
431 if(BIT(inst, 5)){ // Half Bit
432 }
433
434 virt_addr = addr;
435 fault = check_address_validity(cpu, addr, &phys_addr, rw);
436 if (fault) return fault;
437
438 if (CondPassed(cpu, BITS(inst, 28, 31))) {
439 cpu->Reg[Rn] = addr;
440 }
441 return fault;
442}
443
444fault_t LnSWoUB(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
445 fault_t fault;
446 unsigned int Rn = BITS(inst, 16, 19);
447 unsigned int Rm = BITS(inst, 0, 3);
448 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
449 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
450 unsigned int addr;
451 if (U_BIT) {
452 addr = rn + rm;
453 } else {
454 addr = rn - rm;
455 }
456 virt_addr = addr;
457 fault = check_address_validity(cpu, addr, &phys_addr, rw);
458 if(fault)
459 return fault;
460 if (CondPassed(cpu, BITS(inst, 28, 31))) {
461 cpu->Reg[Rn] = addr;
462 }
463 return fault;
464}
465fault_t LnSWoUB(ScaledRegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
466 fault_t fault;
467 unsigned int shift = BITS(inst, 5, 6);
468 unsigned int shift_imm = BITS(inst, 7, 11);
469 unsigned int Rn = BITS(inst, 16, 19);
470 unsigned int Rm = BITS(inst, 0, 3);
471 unsigned int index;
472 unsigned int addr;
473
474 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
475 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
476
477 switch (shift) {
478 case 0:
479 index = rm << shift_imm;
480 break;
481 case 1:
482 if (shift_imm == 0) {
483 index = 0;
484 } else {
485 index = rm >> shift_imm;
486 }
487 break;
488 case 2:
489 DEBUG_MSG;
490 break;
491 case 3:
492 DEBUG_MSG;
493 break;
494 }
495 if (U_BIT) {
496 addr = rn + index;
497 } else
498 addr = rn - index;
499 virt_addr = addr;
500 fault = check_address_validity(cpu, addr, &phys_addr, rw);
501 if(fault)
502 return fault;
503 if (CondPassed(cpu, BITS(inst, 28, 31))) {
504 cpu->Reg[Rn] = addr;
505 }
506
507 return fault;
508}
509
510fault_t LnSWoUB(ScaledRegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
511 fault_t fault;
512 unsigned int shift = BITS(inst, 5, 6);
513 unsigned int shift_imm = BITS(inst, 7, 11);
514 unsigned int Rn = BITS(inst, 16, 19);
515 unsigned int Rm = BITS(inst, 0, 3);
516 unsigned int index;
517 unsigned int addr;
518
519 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
520 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
521 addr = rn;
522 switch (shift) {
523 case 0:
524 index = rm << shift_imm;
525 break;
526 case 1:
527 if (shift_imm == 0) {
528 index = 0;
529 } else {
530 index = rm >> shift_imm;
531 }
532 break;
533 case 2:
534 DEBUG_MSG;
535 break;
536 case 3:
537 DEBUG_MSG;
538 break;
539 }
540 virt_addr = addr;
541 fault = check_address_validity(cpu, addr, &phys_addr, rw);
542 if(fault)
543 return fault;
544 if (CondPassed(cpu, BITS(inst, 28, 31))) {
545 if (U_BIT)
546 cpu->Reg[Rn] += index;
547 else
548 cpu->Reg[Rn] -= index;
549 }
550
551 return fault;
514} 552}
515 553
516fault_t LnSWoUB(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) 554fault_t LnSWoUB(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
517{ 555 fault_t fault;
518 fault_t fault; 556 unsigned int Rn = BITS(inst, 16, 19);
519 unsigned int Rn = BITS(inst, 16, 19); 557 unsigned int Rm = BITS(inst, 0, 3);
520 unsigned int addr; 558 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
521 if (U_BIT) { 559 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
522 addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; 560
523 } else { 561 unsigned int addr = rn;
524 addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; 562 virt_addr = addr;
525 } 563 fault = check_address_validity(cpu, addr, &phys_addr, rw);
526 #if 0 564 if (fault) return fault;
527 if (Rn == 15) { 565
528 addr += 8; 566 if (CondPassed(cpu, BITS(inst, 28, 31))) {
529 } 567 if (U_BIT) {
530 #endif 568 cpu->Reg[Rn] += rm;
531 569 } else {
532 virt_addr = addr; 570 cpu->Reg[Rn] -= rm;
533 fault = check_address_validity(cpu, addr, &phys_addr, rw); 571 }
534 if (fault) return fault; 572 }
535 573 return fault;
536 if (CondPassed(cpu, BITS(inst, 28, 31))) { 574}
537 cpu->Reg[Rn] = addr; 575
538 } 576fault_t MLnS(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
539 return fault; 577 fault_t fault;
540} 578 unsigned int immedL = BITS(inst, 0, 3);
541 579 unsigned int immedH = BITS(inst, 8, 11);
542fault_t MLnS(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) 580
543{ 581 unsigned int Rn = BITS(inst, 16, 19);
544 fault_t fault; 582 unsigned int addr;
545 unsigned int addr; 583
546 unsigned int Rn = BITS(inst, 16, 19); 584 unsigned int offset_8 = (immedH << 4) | immedL;
547 unsigned int Rm = BITS(inst, 0, 3); 585 if (U_BIT) {
548 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); 586 addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8;
549 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); 587 } else
550 //if (Rn == 15) rn += 8; 588 addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8;
551 //if (Rm == 15) rm += 8; 589
552 if (U_BIT) { 590 virt_addr = addr;
553 addr = rn + rm; 591 fault = check_address_validity(cpu, addr, &phys_addr, rw);
554 } else 592 return fault;
555 addr = rn - rm; 593}
556 if(BIT(inst, 20)){ /* L BIT */ 594
557 } 595fault_t MLnS(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
558 if(BIT(inst, 6)){ /* Sign Bit */ 596 fault_t fault;
559 } 597 unsigned int addr;
560 if(BIT(inst, 5)){ /* Half Bit */ 598 unsigned int Rn = BITS(inst, 16, 19);
561 } 599 unsigned int Rm = BITS(inst, 0, 3);
562 600 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
563 virt_addr = addr; 601 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
564 fault = check_address_validity(cpu, addr, &phys_addr, rw); 602 if (U_BIT) {
565 if (fault) return fault; 603 addr = rn + rm;
566 604 } else
567 if (CondPassed(cpu, BITS(inst, 28, 31))) { 605 addr = rn - rm;
568 cpu->Reg[Rn] = addr; 606 if(BIT(inst, 20)){ // L BIT
569 } 607 }
570 return fault; 608 if(BIT(inst, 6)){ // Sign Bit
571} 609 }
572 610 if(BIT(inst, 5)){ // Half Bit
573fault_t LnSWoUB(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) 611 }
574{ 612 virt_addr = addr;
575 fault_t fault; 613 fault = check_address_validity(cpu, addr, &phys_addr, rw);
576 unsigned int Rn = BITS(inst, 16, 19); 614 return fault;
577 unsigned int Rm = BITS(inst, 0, 3); 615}
578 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); 616
579 //if (Rn == 15) rn += 8; 617fault_t MLnS(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
580 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); 618 fault_t fault;
581 //if (Rm == 15) rm += 8; 619 unsigned int Rn = BITS(inst, 16, 19);
582 unsigned int addr; 620 unsigned int immedH = BITS(inst, 8, 11);
583 if (U_BIT) { 621 unsigned int immedL = BITS(inst, 0, 3);
584 addr = rn + rm; 622 unsigned int addr;
585 } else { 623 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
586 addr = rn - rm; 624 unsigned int offset_8 = (immedH << 4) | immedL;
587 } 625
588 virt_addr = addr; 626 if (U_BIT) {
589 fault = check_address_validity(cpu, addr, &phys_addr, rw); 627 addr = rn + offset_8;
590 if(fault) 628 } else
591 return fault; 629 addr = rn - offset_8;
592 if (CondPassed(cpu, BITS(inst, 28, 31))) { 630
593 cpu->Reg[Rn] = addr; 631 virt_addr = addr;
594 } 632 fault = check_address_validity(cpu, addr, &phys_addr, rw);
595 return fault; 633 if (fault) return fault;
596} 634
597fault_t LnSWoUB(ScaledRegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) 635 if (CondPassed(cpu, BITS(inst, 28, 31))) {
598{ 636 cpu->Reg[Rn] = addr;
599 fault_t fault; 637 }
600 unsigned int shift = BITS(inst, 5, 6); 638 return fault;
601 unsigned int shift_imm = BITS(inst, 7, 11); 639}
602 unsigned int Rn = BITS(inst, 16, 19); 640
603 unsigned int Rm = BITS(inst, 0, 3); 641fault_t MLnS(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
604 unsigned int index; 642 fault_t fault;
605 unsigned int addr; 643 unsigned int Rn = BITS(inst, 16, 19);
606 644 unsigned int immedH = BITS(inst, 8, 11);
607 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); 645 unsigned int immedL = BITS(inst, 0, 3);
608 //if (Rm == 15) rm += 8; 646 unsigned int addr;
609 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); 647 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
610 //if (Rn == 15) rn += 8; 648 addr = rn;
611 switch (shift) { 649
612 case 0: 650 virt_addr = addr;
613 //DEBUG_MSG; 651 fault = check_address_validity(cpu, addr, &phys_addr, rw);
614 index = rm << shift_imm; 652 if (fault) return fault;
615 break; 653
616 case 1: 654 if (CondPassed(cpu, BITS(inst, 28, 31))) {
617// DEBUG_MSG; 655 unsigned int offset_8 = (immedH << 4) | immedL;
618 if (shift_imm == 0) { 656 if (U_BIT) {
619 index = 0; 657 rn += offset_8;
620 } else { 658 } else {
621 index = rm >> shift_imm; 659 rn -= offset_8;
622 } 660 }
623 break; 661 cpu->Reg[Rn] = rn;
624 case 2: 662 }
625 DEBUG_MSG; 663
626 break; 664 return fault;
627 case 3: 665}
628 DEBUG_MSG; 666fault_t MLnS(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
629 break; 667 fault_t fault;
630 } 668 unsigned int Rn = BITS(inst, 16, 19);
631 if (U_BIT) { 669 unsigned int Rm = BITS(inst, 0, 3);
632 addr = rn + index; 670 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
633 } else 671 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
634 addr = rn - index; 672 unsigned int addr = rn;
635 virt_addr = addr; 673
636 fault = check_address_validity(cpu, addr, &phys_addr, rw); 674 virt_addr = addr;
637 if(fault) 675 fault = check_address_validity(cpu, addr, &phys_addr, rw);
638 return fault; 676 if (fault) return fault;
639 if (CondPassed(cpu, BITS(inst, 28, 31))) { 677
640 cpu->Reg[Rn] = addr; 678 if (CondPassed(cpu, BITS(inst, 28, 31))) {
641 } 679 if (U_BIT) {
642 680 cpu->Reg[Rn] += rm;
643 return fault; 681 } else {
644} 682 cpu->Reg[Rn] -= rm;
645 683 }
646fault_t LnSWoUB(ScaledRegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) 684 }
647{ 685 return fault;
648 fault_t fault; 686}
649 unsigned int shift = BITS(inst, 5, 6); 687
650 unsigned int shift_imm = BITS(inst, 7, 11); 688fault_t LdnStM(DecrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
651 unsigned int Rn = BITS(inst, 16, 19); 689 fault_t fault;
652 unsigned int Rm = BITS(inst, 0, 3); 690 unsigned int Rn = BITS(inst, 16, 19);
653 unsigned int index; 691 unsigned int i = BITS(inst, 0, 15);
654 unsigned int addr; 692 int count = 0;
655 693 while(i) {
656 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); 694 if(i & 1) count ++;
657 //if (Rm == 15) rm += 8; 695 i = i >> 1;
658 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); 696 }
659 //if (Rn == 15) rn += 8; 697 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
660 addr = rn; 698 unsigned int start_addr = rn - count * 4;
661 switch (shift) { 699 unsigned int end_addr = rn - 4;
662 case 0: 700
663 //DEBUG_MSG; 701 fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
664 index = rm << shift_imm; 702 virt_addr = end_addr;
665 break; 703 if (fault) return fault;
666 case 1: 704
667// DEBUG_MSG; 705 fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
668 if (shift_imm == 0) { 706 virt_addr = start_addr;
669 index = 0; 707 if (fault) return fault;
670 } else { 708
671 index = rm >> shift_imm; 709 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
672 } 710 cpu->Reg[Rn] -= count * 4;
673 break; 711 }
674 case 2: 712
675 DEBUG_MSG; 713 return fault;
676 break; 714}
677 case 3: 715
678 DEBUG_MSG; 716fault_t LdnStM(IncrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
679 break; 717 fault_t fault;
680 } 718 unsigned int Rn = BITS(inst, 16, 19);
681 virt_addr = addr; 719 unsigned int i = BITS(inst, 0, 15);
682 fault = check_address_validity(cpu, addr, &phys_addr, rw); 720 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
683 if(fault) 721 int count = 0;
684 return fault; 722 while(i) {
685 if (CondPassed(cpu, BITS(inst, 28, 31))) { 723 if(i & 1) count ++;
686 if (U_BIT) 724 i = i >> 1;
687 cpu->Reg[Rn] += index; 725 }
688 else 726
689 cpu->Reg[Rn] -= index; 727 unsigned int start_addr = rn + 4;
690 } 728 unsigned int end_addr = rn + count * 4;
691 729
692 return fault; 730 fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
693} 731 virt_addr = end_addr;
694 732 if (fault) return fault;
695fault_t LnSWoUB(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) 733
696{ 734 fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
697 fault_t fault; 735 virt_addr = start_addr;
698 unsigned int Rn = BITS(inst, 16, 19); 736 if (fault) return fault;
699 unsigned int Rm = BITS(inst, 0, 3); 737
700 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); 738 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
701 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); 739 cpu->Reg[Rn] += count * 4;
702 740 }
703 unsigned int addr = rn; 741 return fault;
704 virt_addr = addr; 742}
705 fault = check_address_validity(cpu, addr, &phys_addr, rw); 743
706 if (fault) return fault; 744fault_t LdnStM(IncrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
707 745 fault_t fault;
708 if (CondPassed(cpu, BITS(inst, 28, 31))) { 746 unsigned int Rn = BITS(inst, 16, 19);
709 if (U_BIT) { 747 unsigned int i = BITS(inst, 0, 15);
710 cpu->Reg[Rn] += rm; 748 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
711 } else { 749 int count = 0;
712 cpu->Reg[Rn] -= rm; 750 while(i) {
713 } 751 if(i & 1) count ++;
714 } 752 i = i >> 1;
715 return fault; 753 }
716} 754 unsigned int start_addr = rn;
717 755 unsigned int end_addr = rn + count * 4 - 4;
718fault_t MLnS(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) 756
719{ 757 fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
720 fault_t fault; 758 virt_addr = end_addr;
721 unsigned int immedL = BITS(inst, 0, 3); 759 if (fault) return fault;
722 unsigned int immedH = BITS(inst, 8, 11); 760
723 761 fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
724 unsigned int Rn = BITS(inst, 16, 19); 762 virt_addr = start_addr;
725 unsigned int addr; 763 if (fault) return fault;
726 764
727 unsigned int offset_8 = (immedH << 4) | immedL; 765 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
728 if (U_BIT) { 766 cpu->Reg[Rn] += count * 4;
729 addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8; 767 }
730 } else 768 return fault;
731 addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8; 769}
732 #if 0 770
733 if (Rn == 15) { 771fault_t LdnStM(DecrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
734 addr += 8; 772 fault_t fault;
735 } 773 unsigned int Rn = BITS(inst, 16, 19);
736 #endif 774 unsigned int i = BITS(inst, 0, 15);
737 virt_addr = addr; 775 int count = 0;
738 fault = check_address_validity(cpu, addr, &phys_addr, rw); 776 while(i) {
739 return fault; 777 if(i & 1) count ++;
740} 778 i = i >> 1;
741 779 }
742fault_t MLnS(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) 780 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
743{ 781 unsigned int start_addr = rn - count * 4 + 4;
744 fault_t fault; 782 unsigned int end_addr = rn;
745 unsigned int addr; 783
746 unsigned int Rn = BITS(inst, 16, 19); 784 fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
747 unsigned int Rm = BITS(inst, 0, 3); 785 virt_addr = end_addr;
748 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); 786 if (fault) return fault;
749 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); 787
750 //if (Rn == 15) rn += 8; 788 fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
751 //if (Rm == 15) rm += 8; 789 if (fault) return fault;
752 if (U_BIT) { 790 virt_addr = start_addr;
753 addr = rn + rm; 791
754 } else 792 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
755 addr = rn - rm; 793 cpu->Reg[Rn] -= count * 4;
756 if(BIT(inst, 20)){ /* L BIT */ 794 }
757 } 795 return fault;
758 if(BIT(inst, 6)){ /* Sign Bit */ 796}
759 } 797
760 if(BIT(inst, 5)){ /* Half Bit */ 798fault_t LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
761 } 799 fault_t fault;
762 virt_addr = addr; 800 unsigned int shift = BITS(inst, 5, 6);
763 fault = check_address_validity(cpu, addr, &phys_addr, rw); 801 unsigned int shift_imm = BITS(inst, 7, 11);
764 return fault; 802 unsigned int Rn = BITS(inst, 16, 19);
765} 803 unsigned int Rm = BITS(inst, 0, 3);
766 804 unsigned int index;
767fault_t MLnS(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) 805 unsigned int addr;
768{ 806
769 fault_t fault; 807 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
770 unsigned int Rn = BITS(inst, 16, 19); 808 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
771 unsigned int immedH = BITS(inst, 8, 11); 809 switch (shift) {
772 unsigned int immedL = BITS(inst, 0, 3); 810 case 0:
773 unsigned int addr; 811 index = rm << shift_imm;
774 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); 812 break;
775 //if (Rn == 15) rn += 8; 813 case 1:
776 814 if (shift_imm == 0) {
777// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); 815 index = 0;
778 unsigned int offset_8 = (immedH << 4) | immedL; 816 } else {
779 if (U_BIT) { 817 index = rm >> shift_imm;
780 addr = rn + offset_8; 818 }
781 } else 819 break;
782 addr = rn - offset_8; 820 case 2:
783 821 if (shift_imm == 0){ // ASR #32
784 virt_addr = addr; 822 if (rm >> 31)
785 fault = check_address_validity(cpu, addr, &phys_addr, rw); 823 index = 0xFFFFFFFF;
786 if (fault) return fault; 824 else
787 825 index = 0;
788 if (CondPassed(cpu, BITS(inst, 28, 31))) { 826 }
789 cpu->Reg[Rn] = addr; 827 else {
790 } 828 index = static_cast<int>(rm) >> shift_imm;
791 return fault; 829 }
792} 830 break;
793 831 case 3:
794fault_t MLnS(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) 832 DEBUG_MSG;
795{ 833 break;
796 fault_t fault; 834 }
797 unsigned int Rn = BITS(inst, 16, 19); 835 if (U_BIT) {
798 unsigned int immedH = BITS(inst, 8, 11); 836 addr = rn + index;
799 unsigned int immedL = BITS(inst, 0, 3); 837 } else
800 unsigned int addr; 838 addr = rn - index;
801 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); 839
802 addr = rn; 840 virt_addr = addr;
803 841 fault = check_address_validity(cpu, addr, &phys_addr, rw);
804 virt_addr = addr; 842
805 fault = check_address_validity(cpu, addr, &phys_addr, rw); 843 return fault;
806 if (fault) return fault; 844}
807 845
808 if (CondPassed(cpu, BITS(inst, 28, 31))) { 846#define ISNEG(n) (n < 0)
809 unsigned int offset_8 = (immedH << 4) | immedL; 847#define ISPOS(n) (n >= 0)
810 if (U_BIT) {
811 rn += offset_8;
812 } else {
813 rn -= offset_8;
814 }
815 cpu->Reg[Rn] = rn;
816 }
817
818 return fault;
819}
820fault_t MLnS(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
821{
822 fault_t fault;
823 unsigned int Rn = BITS(inst, 16, 19);
824 unsigned int Rm = BITS(inst, 0, 3);
825 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
826 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
827
828 unsigned int addr = rn;
829 virt_addr = addr;
830 fault = check_address_validity(cpu, addr, &phys_addr, rw);
831 if (fault) return fault;
832
833 if (CondPassed(cpu, BITS(inst, 28, 31))) {
834 if (U_BIT) {
835 cpu->Reg[Rn] += rm;
836 } else {
837 cpu->Reg[Rn] -= rm;
838 }
839 }
840 return fault;
841}
842
843fault_t LdnStM(DecrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
844{
845 fault_t fault;
846 unsigned int Rn = BITS(inst, 16, 19);
847 unsigned int i = BITS(inst, 0, 15);
848 int count = 0;
849 while(i) {
850 if(i & 1) count ++;
851 i = i >> 1;
852 }
853 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
854 //if (Rn == 15) rn += 8;
855 unsigned int start_addr = rn - count * 4;
856 unsigned int end_addr = rn - 4;
857
858 fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
859 virt_addr = end_addr;
860 if (fault) return fault;
861
862 fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
863 virt_addr = start_addr;
864 if (fault) return fault;
865
866 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
867 cpu->Reg[Rn] -= count * 4;
868 }
869
870 return fault;
871}
872
873fault_t LdnStM(IncrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
874{
875 fault_t fault;
876 unsigned int Rn = BITS(inst, 16, 19);
877 unsigned int i = BITS(inst, 0, 15);
878 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
879 //if (Rn == 15) rn += 8;
880 int count = 0;
881 while(i) {
882 if(i & 1) count ++;
883 i = i >> 1;
884 }
885
886 unsigned int start_addr = rn + 4;
887 unsigned int end_addr = rn + count * 4;
888
889 fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
890 virt_addr = end_addr;
891 if (fault) return fault;
892
893 fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
894 virt_addr = start_addr;
895 if (fault) return fault;
896
897 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
898 cpu->Reg[Rn] += count * 4;
899 }
900 return fault;
901}
902
903fault_t LdnStM(IncrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
904{
905 fault_t fault;
906 unsigned int Rn = BITS(inst, 16, 19);
907 unsigned int i = BITS(inst, 0, 15);
908 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
909 int count = 0;
910 while(i) {
911 if(i & 1) count ++;
912 i = i >> 1;
913 }
914 //if (Rn == 15) rn += 8;
915 unsigned int start_addr = rn;
916 unsigned int end_addr = rn + count * 4 - 4;
917
918 fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
919 virt_addr = end_addr;
920 if (fault) return fault;
921
922 fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
923 virt_addr = start_addr;
924 if (fault) return fault;
925
926 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
927 cpu->Reg[Rn] += count * 4;
928 }
929 return fault;
930}
931
932fault_t LdnStM(DecrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
933{
934 fault_t fault;
935 unsigned int Rn = BITS(inst, 16, 19);
936 unsigned int i = BITS(inst, 0, 15);
937 int count = 0;
938 while(i) {
939 if(i & 1) count ++;
940 i = i >> 1;
941 }
942 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
943 //if (Rn == 15) rn += 8;
944 unsigned int start_addr = rn - count * 4 + 4;
945 unsigned int end_addr = rn;
946
947 fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
948 virt_addr = end_addr;
949 if (fault) return fault;
950
951 fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
952 if (fault) return fault;
953 virt_addr = start_addr;
954
955 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
956 cpu->Reg[Rn] -= count * 4;
957 }
958 return fault;
959}
960
961fault_t LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
962{
963 fault_t fault;
964 unsigned int shift = BITS(inst, 5, 6);
965 unsigned int shift_imm = BITS(inst, 7, 11);
966 unsigned int Rn = BITS(inst, 16, 19);
967 unsigned int Rm = BITS(inst, 0, 3);
968 unsigned int index;
969 unsigned int addr;
970
971 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
972 //if (Rm == 15) rm += 8;
973 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
974 //if (Rn == 15) rn += 8;
975 switch (shift) {
976 case 0:
977 //DEBUG_MSG;
978 index = rm << shift_imm;
979 break;
980 case 1:
981// DEBUG_MSG;
982 if (shift_imm == 0) {
983 index = 0;
984 } else {
985 index = rm >> shift_imm;
986 }
987 break;
988 case 2:
989 if (shift_imm == 0){ /* ASR #32 */
990 if (rm >> 31)
991 index = 0xFFFFFFFF;
992 else
993 index = 0;
994 }
995 else {
996 index = static_cast<int>(rm) >> shift_imm;
997 }
998 break;
999 case 3:
1000 DEBUG_MSG;
1001 break;
1002 }
1003 if (U_BIT) {
1004 addr = rn + index;
1005 } else
1006 addr = rn - index;
1007 virt_addr = addr;
1008 fault = check_address_validity(cpu, addr, &phys_addr, rw);
1009 return fault;
1010}
1011
1012#define ISNEG(n) (n < 0)
1013#define ISPOS(n) (n >= 0)
1014
1015//enum {
1016// COND = (1 << 0),
1017// NON_BRANCH = (1 << 1),
1018// DIRECT_BRANCH = (1 << 2),
1019// INDIRECT_BRANCH = (1 << 3),
1020// CALL = (1 << 4),
1021// RET = (1 << 5),
1022// END_OF_PAGE = (1 << 6),
1023// THUMB = (1 << 7)
1024//};
1025 848
1026typedef struct _arm_inst { 849typedef struct _arm_inst {
1027 unsigned int idx; 850 unsigned int idx;
1028 unsigned int cond; 851 unsigned int cond;
1029 int br; 852 int br;
1030 int load_r15; 853 int load_r15;
1031 char component[0]; 854 char component[0];
1032} arm_inst; 855} arm_inst;
1033 856
857typedef struct generic_arm_inst {
858 u32 Ra;
859 u32 Rm;
860 u32 Rn;
861 u32 Rd;
862 u8 op1;
863 u8 op2;
864} generic_arm_inst;
865
1034typedef struct _adc_inst { 866typedef struct _adc_inst {
1035 unsigned int I; 867 unsigned int I;
1036 unsigned int S; 868 unsigned int S;
1037 unsigned int Rn; 869 unsigned int Rn;
1038 unsigned int Rd; 870 unsigned int Rd;
1039 unsigned int shifter_operand; 871 unsigned int shifter_operand;
1040 shtop_fp_t shtop_func; 872 shtop_fp_t shtop_func;
1041} adc_inst; 873} adc_inst;
1042 874
1043typedef struct _add_inst { 875typedef struct _add_inst {
1044 unsigned int I; 876 unsigned int I;
1045 unsigned int S; 877 unsigned int S;
1046 unsigned int Rn; 878 unsigned int Rn;
1047 unsigned int Rd; 879 unsigned int Rd;
1048 unsigned int shifter_operand; 880 unsigned int shifter_operand;
1049 shtop_fp_t shtop_func; 881 shtop_fp_t shtop_func;
1050} add_inst; 882} add_inst;
1051 883
1052typedef struct _orr_inst { 884typedef struct _orr_inst {
1053 unsigned int I; 885 unsigned int I;
1054 unsigned int S; 886 unsigned int S;
1055 unsigned int Rn; 887 unsigned int Rn;
1056 unsigned int Rd; 888 unsigned int Rd;
1057 unsigned int shifter_operand; 889 unsigned int shifter_operand;
1058 shtop_fp_t shtop_func; 890 shtop_fp_t shtop_func;
1059} orr_inst; 891} orr_inst;
1060 892
1061typedef struct _and_inst { 893typedef struct _and_inst {
1062 unsigned int I; 894 unsigned int I;
1063 unsigned int S; 895 unsigned int S;
1064 unsigned int Rn; 896 unsigned int Rn;
1065 unsigned int Rd; 897 unsigned int Rd;
1066 unsigned int shifter_operand; 898 unsigned int shifter_operand;
1067 shtop_fp_t shtop_func; 899 shtop_fp_t shtop_func;
1068} and_inst; 900} and_inst;
1069 901
1070typedef struct _eor_inst { 902typedef struct _eor_inst {
1071 unsigned int I; 903 unsigned int I;
1072 unsigned int S; 904 unsigned int S;
1073 unsigned int Rn; 905 unsigned int Rn;
1074 unsigned int Rd; 906 unsigned int Rd;
1075 unsigned int shifter_operand; 907 unsigned int shifter_operand;
1076 shtop_fp_t shtop_func; 908 shtop_fp_t shtop_func;
1077} eor_inst; 909} eor_inst;
1078 910
1079typedef struct _bbl_inst { 911typedef struct _bbl_inst {
1080 unsigned int L; 912 unsigned int L;
1081 int signed_immed_24; 913 int signed_immed_24;
1082 unsigned int next_addr; 914 unsigned int next_addr;
1083 unsigned int jmp_addr; 915 unsigned int jmp_addr;
1084} bbl_inst; 916} bbl_inst;
1085 917
1086typedef struct _bx_inst { 918typedef struct _bx_inst {
1087 unsigned int Rm; 919 unsigned int Rm;
1088} bx_inst; 920} bx_inst;
1089 921
1090typedef struct _blx_inst { 922typedef struct _blx_inst {
1091 union { 923 union {
1092 int32_t signed_immed_24; 924 int32_t signed_immed_24;
1093 uint32_t Rm; 925 uint32_t Rm;
1094 } val; 926 } val;
1095 unsigned int inst; 927 unsigned int inst;
1096} blx_inst; 928} blx_inst;
1097 929
1098typedef struct _clz_inst { 930typedef struct _clz_inst {
1099 unsigned int Rm; 931 unsigned int Rm;
1100 unsigned int Rd; 932 unsigned int Rd;
1101} clz_inst; 933} clz_inst;
1102 934
1103typedef struct _cps_inst { 935typedef struct _cps_inst {
1104 unsigned int imod0; 936 unsigned int imod0;
1105 unsigned int imod1; 937 unsigned int imod1;
1106 unsigned int mmod; 938 unsigned int mmod;
1107 unsigned int A, I, F; 939 unsigned int A, I, F;
1108 unsigned int mode; 940 unsigned int mode;
1109} cps_inst; 941} cps_inst;
1110 942
1111typedef struct _clrex_inst { 943typedef struct _clrex_inst {
1112} clrex_inst; 944} clrex_inst;
1113 945
1114typedef struct _cpy_inst { 946typedef struct _cpy_inst {
1115 unsigned int Rm; 947 unsigned int Rm;
1116 unsigned int Rd; 948 unsigned int Rd;
1117} cpy_inst; 949} cpy_inst;
1118 950
1119typedef struct _bic_inst { 951typedef struct _bic_inst {
1120 unsigned int I; 952 unsigned int I;
1121 unsigned int S; 953 unsigned int S;
1122 unsigned int Rn; 954 unsigned int Rn;
1123 unsigned int Rd; 955 unsigned int Rd;
1124 unsigned int shifter_operand; 956 unsigned int shifter_operand;
1125 shtop_fp_t shtop_func; 957 shtop_fp_t shtop_func;
1126} bic_inst; 958} bic_inst;
1127 959
1128typedef struct _sub_inst { 960typedef struct _sub_inst {
1129 unsigned int I; 961 unsigned int I;
1130 unsigned int S; 962 unsigned int S;
1131 unsigned int Rn; 963 unsigned int Rn;
1132 unsigned int Rd; 964 unsigned int Rd;
1133 unsigned int shifter_operand; 965 unsigned int shifter_operand;
1134 shtop_fp_t shtop_func; 966 shtop_fp_t shtop_func;
1135} sub_inst; 967} sub_inst;
1136 968
1137typedef struct _tst_inst { 969typedef struct _tst_inst {
1138 unsigned int I; 970 unsigned int I;
1139 unsigned int S; 971 unsigned int S;
1140 unsigned int Rn; 972 unsigned int Rn;
1141 unsigned int Rd; 973 unsigned int Rd;
1142 unsigned int shifter_operand; 974 unsigned int shifter_operand;
1143 shtop_fp_t shtop_func; 975 shtop_fp_t shtop_func;
1144} tst_inst; 976} tst_inst;
1145 977
1146typedef struct _cmn_inst { 978typedef struct _cmn_inst {
1147 unsigned int I; 979 unsigned int I;
1148 //unsigned int S; 980 unsigned int Rn;
1149 unsigned int Rn; 981 unsigned int shifter_operand;
1150 //unsigned int Rd; 982 shtop_fp_t shtop_func;
1151 unsigned int shifter_operand;
1152 shtop_fp_t shtop_func;
1153} cmn_inst; 983} cmn_inst;
1154 984
1155typedef struct _teq_inst { 985typedef struct _teq_inst {
1156 unsigned int I; 986 unsigned int I;
1157 unsigned int Rn; 987 unsigned int Rn;
1158 unsigned int shifter_operand; 988 unsigned int shifter_operand;
1159 shtop_fp_t shtop_func; 989 shtop_fp_t shtop_func;
1160} teq_inst; 990} teq_inst;
1161 991
1162typedef struct _stm_inst { 992typedef struct _stm_inst {
1163 unsigned int inst; 993 unsigned int inst;
1164} stm_inst; 994} stm_inst;
1165 995
1166struct bkpt_inst { 996struct bkpt_inst {
1167}; 997};
1168 998
1169struct blx1_inst { 999struct blx1_inst {
1170 unsigned int addr; 1000 unsigned int addr;
1171}; 1001};
1172 1002
1173struct blx2_inst { 1003struct blx2_inst {
1174 unsigned int Rm; 1004 unsigned int Rm;
1175}; 1005};
1176 1006
1177typedef struct _stc_inst { 1007typedef struct _stc_inst {
@@ -1181,1965 +1011,2188 @@ typedef struct _ldc_inst {
1181} ldc_inst; 1011} ldc_inst;
1182 1012
1183typedef struct _swi_inst { 1013typedef struct _swi_inst {
1184 unsigned int num; 1014 unsigned int num;
1185} swi_inst; 1015} swi_inst;
1186 1016
1187typedef struct _cmp_inst { 1017typedef struct _cmp_inst {
1188 unsigned int I; 1018 unsigned int I;
1189 unsigned int Rn; 1019 unsigned int Rn;
1190 unsigned int shifter_operand; 1020 unsigned int shifter_operand;
1191 shtop_fp_t shtop_func; 1021 shtop_fp_t shtop_func;
1192} cmp_inst; 1022} cmp_inst;
1193 1023
1194typedef struct _mov_inst { 1024typedef struct _mov_inst {
1195 unsigned int I; 1025 unsigned int I;
1196 unsigned int S; 1026 unsigned int S;
1197 unsigned int Rd; 1027 unsigned int Rd;
1198 unsigned int shifter_operand; 1028 unsigned int shifter_operand;
1199 shtop_fp_t shtop_func; 1029 shtop_fp_t shtop_func;
1200} mov_inst; 1030} mov_inst;
1201 1031
1202typedef struct _mvn_inst { 1032typedef struct _mvn_inst {
1203 unsigned int I; 1033 unsigned int I;
1204 unsigned int S; 1034 unsigned int S;
1205 unsigned int Rd; 1035 unsigned int Rd;
1206 unsigned int shifter_operand; 1036 unsigned int shifter_operand;
1207 shtop_fp_t shtop_func; 1037 shtop_fp_t shtop_func;
1208} mvn_inst; 1038} mvn_inst;
1209 1039
1210typedef struct _rev_inst { 1040typedef struct _rev_inst {
1211 unsigned int Rd; 1041 unsigned int Rd;
1212 unsigned int Rm; 1042 unsigned int Rm;
1213} rev_inst; 1043} rev_inst;
1214 1044
1215typedef struct _rsb_inst { 1045typedef struct _rsb_inst {
1216 unsigned int I; 1046 unsigned int I;
1217 unsigned int S; 1047 unsigned int S;
1218 unsigned int Rn; 1048 unsigned int Rn;
1219 unsigned int Rd; 1049 unsigned int Rd;
1220 unsigned int shifter_operand; 1050 unsigned int shifter_operand;
1221 shtop_fp_t shtop_func; 1051 shtop_fp_t shtop_func;
1222} rsb_inst; 1052} rsb_inst;
1223 1053
1224typedef struct _rsc_inst { 1054typedef struct _rsc_inst {
1225 unsigned int I; 1055 unsigned int I;
1226 unsigned int S; 1056 unsigned int S;
1227 unsigned int Rn; 1057 unsigned int Rn;
1228 unsigned int Rd; 1058 unsigned int Rd;
1229 unsigned int shifter_operand; 1059 unsigned int shifter_operand;
1230 shtop_fp_t shtop_func; 1060 shtop_fp_t shtop_func;
1231} rsc_inst; 1061} rsc_inst;
1232 1062
1233typedef struct _sbc_inst { 1063typedef struct _sbc_inst {
1234 unsigned int I; 1064 unsigned int I;
1235 unsigned int S; 1065 unsigned int S;
1236 unsigned int Rn; 1066 unsigned int Rn;
1237 unsigned int Rd; 1067 unsigned int Rd;
1238 unsigned int shifter_operand; 1068 unsigned int shifter_operand;
1239 shtop_fp_t shtop_func; 1069 shtop_fp_t shtop_func;
1240} sbc_inst; 1070} sbc_inst;
1241 1071
1242typedef struct _mul_inst { 1072typedef struct _mul_inst {
1243 unsigned int S; 1073 unsigned int S;
1244 unsigned int Rd; 1074 unsigned int Rd;
1245 unsigned int Rs; 1075 unsigned int Rs;
1246 unsigned int Rm; 1076 unsigned int Rm;
1247} mul_inst; 1077} mul_inst;
1248 1078
1249typedef struct _smul_inst { 1079typedef struct _smul_inst {
1250 unsigned int Rd; 1080 unsigned int Rd;
1251 unsigned int Rs; 1081 unsigned int Rs;
1252 unsigned int Rm; 1082 unsigned int Rm;
1253 unsigned int x; 1083 unsigned int x;
1254 unsigned int y; 1084 unsigned int y;
1255} smul_inst; 1085} smul_inst;
1256 1086
1257typedef struct _umull_inst { 1087typedef struct _umull_inst {
1258 unsigned int S; 1088 unsigned int S;
1259 unsigned int RdHi; 1089 unsigned int RdHi;
1260 unsigned int RdLo; 1090 unsigned int RdLo;
1261 unsigned int Rs; 1091 unsigned int Rs;
1262 unsigned int Rm; 1092 unsigned int Rm;
1263} umull_inst; 1093} umull_inst;
1264typedef struct _smlad_inst { 1094typedef struct _smlad_inst {
1265 unsigned int m; 1095 unsigned int m;
1266 unsigned int Rm; 1096 unsigned int Rm;
1267 unsigned int Rd; 1097 unsigned int Rd;
1268 unsigned int Ra; 1098 unsigned int Ra;
1269 unsigned int Rn; 1099 unsigned int Rn;
1270} smlad_inst; 1100} smlad_inst;
1271 1101
1272typedef struct _smla_inst { 1102typedef struct _smla_inst {
1273 unsigned int x; 1103 unsigned int x;
1274 unsigned int y; 1104 unsigned int y;
1275 unsigned int Rm; 1105 unsigned int Rm;
1276 unsigned int Rd; 1106 unsigned int Rd;
1277 unsigned int Rs; 1107 unsigned int Rs;
1278 unsigned int Rn; 1108 unsigned int Rn;
1279} smla_inst; 1109} smla_inst;
1280 1110
1111typedef struct ssat_inst {
1112 unsigned int Rn;
1113 unsigned int Rd;
1114 unsigned int imm5;
1115 unsigned int sat_imm;
1116 unsigned int shift_type;
1117} ssat_inst;
1118
1119typedef struct umaal_inst {
1120 unsigned int Rn;
1121 unsigned int Rm;
1122 unsigned int RdHi;
1123 unsigned int RdLo;
1124} umaal_inst;
1125
1281typedef struct _umlal_inst { 1126typedef struct _umlal_inst {
1282 unsigned int S; 1127 unsigned int S;
1283 unsigned int Rm; 1128 unsigned int Rm;
1284 unsigned int Rs; 1129 unsigned int Rs;
1285 unsigned int RdHi; 1130 unsigned int RdHi;
1286 unsigned int RdLo; 1131 unsigned int RdLo;
1287} umlal_inst; 1132} umlal_inst;
1288 1133
1289typedef struct _smlal_inst { 1134typedef struct _smlal_inst {
1290 unsigned int S; 1135 unsigned int S;
1291 unsigned int Rm; 1136 unsigned int Rm;
1292 unsigned int Rs; 1137 unsigned int Rs;
1293 unsigned int RdHi; 1138 unsigned int RdHi;
1294 unsigned int RdLo; 1139 unsigned int RdLo;
1295} smlal_inst; 1140} smlal_inst;
1296 1141
1297typedef struct _mla_inst { 1142typedef struct _mla_inst {
1298 unsigned int S; 1143 unsigned int S;
1299 unsigned int Rn; 1144 unsigned int Rn;
1300 unsigned int Rd; 1145 unsigned int Rd;
1301 unsigned int Rs; 1146 unsigned int Rs;
1302 unsigned int Rm; 1147 unsigned int Rm;
1303} mla_inst; 1148} mla_inst;
1304 1149
1305typedef struct _mrc_inst { 1150typedef struct _mrc_inst {
1306 unsigned int opcode_1; 1151 unsigned int opcode_1;
1307 unsigned int opcode_2; 1152 unsigned int opcode_2;
1308 unsigned int cp_num; 1153 unsigned int cp_num;
1309 unsigned int crn; 1154 unsigned int crn;
1310 unsigned int crm; 1155 unsigned int crm;
1311 unsigned int Rd; 1156 unsigned int Rd;
1312 unsigned int inst; 1157 unsigned int inst;
1313} mrc_inst; 1158} mrc_inst;
1314 1159
1315typedef struct _mcr_inst { 1160typedef struct _mcr_inst {
1316 unsigned int opcode_1; 1161 unsigned int opcode_1;
1317 unsigned int opcode_2; 1162 unsigned int opcode_2;
1318 unsigned int cp_num; 1163 unsigned int cp_num;
1319 unsigned int crn; 1164 unsigned int crn;
1320 unsigned int crm; 1165 unsigned int crm;
1321 unsigned int Rd; 1166 unsigned int Rd;
1322 unsigned int inst; 1167 unsigned int inst;
1323} mcr_inst; 1168} mcr_inst;
1324 1169
1325typedef struct _mrs_inst { 1170typedef struct _mrs_inst {
1326 unsigned int R; 1171 unsigned int R;
1327 unsigned int Rd; 1172 unsigned int Rd;
1328} mrs_inst; 1173} mrs_inst;
1329 1174
1330typedef struct _msr_inst { 1175typedef struct _msr_inst {
1331 unsigned int field_mask; 1176 unsigned int field_mask;
1332 unsigned int R; 1177 unsigned int R;
1333 unsigned int inst; 1178 unsigned int inst;
1334} msr_inst; 1179} msr_inst;
1335 1180
1336typedef struct _pld_inst { 1181typedef struct _pld_inst {
1337} pld_inst; 1182} pld_inst;
1338 1183
1339typedef struct _sxtb_inst { 1184typedef struct _sxtb_inst {
1340 unsigned int Rd; 1185 unsigned int Rd;
1341 unsigned int Rm; 1186 unsigned int Rm;
1342 unsigned int rotate; 1187 unsigned int rotate;
1343} sxtb_inst; 1188} sxtb_inst;
1344 1189
1345typedef struct _sxtab_inst { 1190typedef struct _sxtab_inst {
1346 unsigned int Rd; 1191 unsigned int Rd;
1347 unsigned int Rn; 1192 unsigned int Rn;
1348 unsigned int Rm; 1193 unsigned int Rm;
1349 unsigned rotate; 1194 unsigned rotate;
1350} sxtab_inst; 1195} sxtab_inst;
1351 1196
1352typedef struct _sxtah_inst { 1197typedef struct _sxtah_inst {
1353 unsigned int Rd; 1198 unsigned int Rd;
1354 unsigned int Rn; 1199 unsigned int Rn;
1355 unsigned int Rm; 1200 unsigned int Rm;
1356 unsigned int rotate; 1201 unsigned int rotate;
1357} sxtah_inst; 1202} sxtah_inst;
1358 1203
1359typedef struct _sxth_inst { 1204typedef struct _sxth_inst {
1360 unsigned int Rd; 1205 unsigned int Rd;
1361 unsigned int Rm; 1206 unsigned int Rm;
1362 unsigned int rotate; 1207 unsigned int rotate;
1363} sxth_inst; 1208} sxth_inst;
1364 1209
1365typedef struct _uxtab_inst { 1210typedef struct _uxtab_inst {
1366 unsigned int Rn; 1211 unsigned int Rn;
1367 unsigned int Rd; 1212 unsigned int Rd;
1368 unsigned int rotate; 1213 unsigned int rotate;
1369 unsigned int Rm; 1214 unsigned int Rm;
1370} uxtab_inst; 1215} uxtab_inst;
1371 1216
1372typedef struct _uxtah_inst { 1217typedef struct _uxtah_inst {
1373 unsigned int Rn; 1218 unsigned int Rn;
1374 unsigned int Rd; 1219 unsigned int Rd;
1375 unsigned int rotate; 1220 unsigned int rotate;
1376 unsigned int Rm; 1221 unsigned int Rm;
1377} uxtah_inst; 1222} uxtah_inst;
1378 1223
1379typedef struct _uxth_inst { 1224typedef struct _uxth_inst {
1380 unsigned int Rd; 1225 unsigned int Rd;
1381 unsigned int Rm; 1226 unsigned int Rm;
1382 unsigned int rotate; 1227 unsigned int rotate;
1383} uxth_inst; 1228} uxth_inst;
1384 1229
1385typedef struct _cdp_inst { 1230typedef struct _cdp_inst {
1386 unsigned int opcode_1; 1231 unsigned int opcode_1;
1387 unsigned int CRn; 1232 unsigned int CRn;
1388 unsigned int CRd; 1233 unsigned int CRd;
1389 unsigned int cp_num; 1234 unsigned int cp_num;
1390 unsigned int opcode_2; 1235 unsigned int opcode_2;
1391 unsigned int CRm; 1236 unsigned int CRm;
1392 uint32 inst; 1237 uint32 inst;
1393}cdp_inst; 1238}cdp_inst;
1394 1239
1395typedef struct _uxtb_inst { 1240typedef struct _uxtb_inst {
1396 unsigned int Rd; 1241 unsigned int Rd;
1397 unsigned int Rm; 1242 unsigned int Rm;
1398 unsigned int rotate; 1243 unsigned int rotate;
1399} uxtb_inst; 1244} uxtb_inst;
1400 1245
1401typedef struct _swp_inst { 1246typedef struct _swp_inst {
1402 unsigned int Rn; 1247 unsigned int Rn;
1403 unsigned int Rd; 1248 unsigned int Rd;
1404 unsigned int Rm; 1249 unsigned int Rm;
1405} swp_inst; 1250} swp_inst;
1406 1251
1407typedef struct _b_2_thumb { 1252typedef struct _b_2_thumb {
1408 unsigned int imm; 1253 unsigned int imm;
1409}b_2_thumb; 1254}b_2_thumb;
1410typedef struct _b_cond_thumb { 1255typedef struct _b_cond_thumb {
1411 unsigned int imm; 1256 unsigned int imm;
1412 unsigned int cond; 1257 unsigned int cond;
1413}b_cond_thumb; 1258}b_cond_thumb;
1414 1259
1415typedef struct _bl_1_thumb { 1260typedef struct _bl_1_thumb {
1416 unsigned int imm; 1261 unsigned int imm;
1417}bl_1_thumb; 1262}bl_1_thumb;
1418typedef struct _bl_2_thumb { 1263typedef struct _bl_2_thumb {
1419 unsigned int imm; 1264 unsigned int imm;
1420}bl_2_thumb; 1265}bl_2_thumb;
1421typedef struct _blx_1_thumb { 1266typedef struct _blx_1_thumb {
1422 unsigned int imm; 1267 unsigned int imm;
1423 unsigned int instr; 1268 unsigned int instr;
1424}blx_1_thumb; 1269}blx_1_thumb;
1425 1270
1271typedef struct _pkh_inst {
1272 u32 Rm;
1273 u32 Rn;
1274 u32 Rd;
1275 u8 imm;
1276} pkh_inst;
1277
1426typedef arm_inst * ARM_INST_PTR; 1278typedef arm_inst * ARM_INST_PTR;
1427 1279
1428#define CACHE_BUFFER_SIZE (64 * 1024 * 2000) 1280#define CACHE_BUFFER_SIZE (64 * 1024 * 2000)
1429char inst_buf[CACHE_BUFFER_SIZE]; 1281char inst_buf[CACHE_BUFFER_SIZE];
1430int top = 0; 1282int top = 0;
1431inline void *AllocBuffer(unsigned int size) 1283inline void *AllocBuffer(unsigned int size) {
1432{ 1284 int start = top;
1433 int start = top; 1285 top += size;
1434 top += size; 1286 if (top > CACHE_BUFFER_SIZE) {
1435 if (top > CACHE_BUFFER_SIZE) { 1287 LOG_ERROR(Core_ARM11, "inst_buf is full");
1436 DEBUG_LOG(ARM11, "inst_buf is full\n"); 1288 CITRA_IGNORE_EXIT(-1);
1437 CITRA_IGNORE_EXIT(-1); 1289 }
1438 } 1290 return (void *)&inst_buf[start];
1439 return (void *)&inst_buf[start]; 1291}
1440} 1292
1441 1293int CondPassed(arm_processor *cpu, unsigned int cond) {
1442int CondPassed(arm_processor *cpu, unsigned int cond) 1294 #define NFLAG cpu->NFlag
1443{ 1295 #define ZFLAG cpu->ZFlag
1444 #define NFLAG cpu->NFlag 1296 #define CFLAG cpu->CFlag
1445 #define ZFLAG cpu->ZFlag 1297 #define VFLAG cpu->VFlag
1446 #define CFLAG cpu->CFlag 1298
1447 #define VFLAG cpu->VFlag 1299 int temp;
1448 int temp; 1300
1449 switch (cond) { 1301 switch (cond) {
1450 case 0x0: 1302 case 0x0:
1451 temp = ZFLAG; 1303 temp = ZFLAG;
1452 break; 1304 break;
1453 case 0x1: /* NE */ 1305 case 0x1: // NE
1454 temp = !ZFLAG; 1306 temp = !ZFLAG;
1455 break; 1307 break;
1456 case 0x6: /* VS */ 1308 case 0x6: // VS
1457 temp = VFLAG; 1309 temp = VFLAG;
1458 break; 1310 break;
1459 case 0x7: /* VC */ 1311 case 0x7: // VC
1460 temp = !VFLAG; 1312 temp = !VFLAG;
1461 break; 1313 break;
1462 case 0x4: /* MI */ 1314 case 0x4: // MI
1463 temp = NFLAG; 1315 temp = NFLAG;
1464 break; 1316 break;
1465 case 0x5: /* PL */ 1317 case 0x5: // PL
1466 temp = !NFLAG; 1318 temp = !NFLAG;
1467 break; 1319 break;
1468 case 0x2: /* CS */ 1320 case 0x2: // CS
1469 temp = CFLAG; 1321 temp = CFLAG;
1470 break; 1322 break;
1471 case 0x3: /* CC */ 1323 case 0x3: // CC
1472 temp = !CFLAG; 1324 temp = !CFLAG;
1473 break; 1325 break;
1474 case 0x8: /* HI */ 1326 case 0x8: // HI
1475 temp = (CFLAG && !ZFLAG); 1327 temp = (CFLAG && !ZFLAG);
1476 break; 1328 break;
1477 case 0x9: /* LS */ 1329 case 0x9: // LS
1478 temp = (!CFLAG || ZFLAG); 1330 temp = (!CFLAG || ZFLAG);
1479 break; 1331 break;
1480 case 0xa: /* GE */ 1332 case 0xa: // GE
1481 temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG)); 1333 temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
1482 break; 1334 break;
1483 case 0xb: /* LT */ 1335 case 0xb: // LT
1484 temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)); 1336 temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
1485 break; 1337 break;
1486 case 0xc: /* GT */ 1338 case 0xc: // GT
1487 temp = ((!NFLAG && !VFLAG && !ZFLAG) 1339 temp = ((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG));
1488 || (NFLAG && VFLAG && !ZFLAG)); 1340 break;
1489 break; 1341 case 0xd: // LE
1490 case 0xd: /* LE */ 1342 temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
1491 temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) 1343 break;
1492 || ZFLAG; 1344 case 0xe: // AL
1493 break; 1345 temp = 1;
1494 case 0xe: /* AL */ 1346 break;
1495 temp = 1; 1347 case 0xf:
1496 break; 1348 temp = 1;
1497 case 0xf: 1349 break;
1498// DEBUG_LOG(ARM11, "inst is %x\n"); 1350 }
1499// DEBUG_LOG(ARM11, "icounter is %lld\n", cpu->icounter); 1351 return temp;
1500// CITRA_IGNORE_EXIT(-1);
1501 temp = 1;
1502 break;
1503 }
1504 return temp;
1505} 1352}
1506 1353
1507enum DECODE_STATUS { 1354enum DECODE_STATUS {
1508 DECODE_SUCCESS, 1355 DECODE_SUCCESS,
1509 DECODE_FAILURE 1356 DECODE_FAILURE
1510}; 1357};
1511 1358
1512int decode_arm_instr(uint32_t instr, int32_t *idx); 1359int decode_arm_instr(uint32_t instr, int32_t *idx);
1513 1360
1514shtop_fp_t get_shtop(unsigned int inst) 1361shtop_fp_t get_shtop(unsigned int inst) {
1515{ 1362 if (BIT(inst, 25)) {
1516 if (BIT(inst, 25)) { 1363 return DPO(Immediate);
1517 return DPO(Immediate); 1364 } else if (BITS(inst, 4, 11) == 0) {
1518 } else if (BITS(inst, 4, 11) == 0) { 1365 return DPO(Register);
1519 return DPO(Register); 1366 } else if (BITS(inst, 4, 6) == 0) {
1520 } else if (BITS(inst, 4, 6) == 0) { 1367 return DPO(LogicalShiftLeftByImmediate);
1521 return DPO(LogicalShiftLeftByImmediate); 1368 } else if (BITS(inst, 4, 7) == 1) {
1522 } else if (BITS(inst, 4, 7) == 1) { 1369 return DPO(LogicalShiftLeftByRegister);
1523 return DPO(LogicalShiftLeftByRegister); 1370 } else if (BITS(inst, 4, 6) == 2) {
1524 } else if (BITS(inst, 4, 6) == 2) { 1371 return DPO(LogicalShiftRightByImmediate);
1525 return DPO(LogicalShiftRightByImmediate); 1372 } else if (BITS(inst, 4, 7) == 3) {
1526 } else if (BITS(inst, 4, 7) == 3) { 1373 return DPO(LogicalShiftRightByRegister);
1527 return DPO(LogicalShiftRightByRegister); 1374 } else if (BITS(inst, 4, 6) == 4) {
1528 } else if (BITS(inst, 4, 6) == 4) { 1375 return DPO(ArithmeticShiftRightByImmediate);
1529 return DPO(ArithmeticShiftRightByImmediate); 1376 } else if (BITS(inst, 4, 7) == 5) {
1530 } else if (BITS(inst, 4, 7) == 5) { 1377 return DPO(ArithmeticShiftRightByRegister);
1531 return DPO(ArithmeticShiftRightByRegister); 1378 } else if (BITS(inst, 4, 6) == 6) {
1532 } else if (BITS(inst, 4, 6) == 6) { 1379 return DPO(RotateRightByImmediate);
1533 return DPO(RotateRightByImmediate); 1380 } else if (BITS(inst, 4, 7) == 7) {
1534 } else if (BITS(inst, 4, 7) == 7) { 1381 return DPO(RotateRightByRegister);
1535 return DPO(RotateRightByRegister); 1382 }
1536 } 1383 return nullptr;
1537 return NULL; 1384}
1538} 1385
1539 1386get_addr_fp_t get_calc_addr_op(unsigned int inst) {
1540get_addr_fp_t get_calc_addr_op(unsigned int inst) 1387 if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) {
1541{ 1388 return LnSWoUB(ImmediateOffset);
1542 /* 1 */ 1389 } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
1543 if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) { 1390 return LnSWoUB(RegisterOffset);
1544// DEBUG_LOG(ARM11, "line is %d", __LINE__); 1391 } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
1545 return LnSWoUB(ImmediateOffset); 1392 return LnSWoUB(ScaledRegisterOffset);
1546 } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) { 1393 } else if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 1) {
1547// DEBUG_MSG; 1394 return LnSWoUB(ImmediatePreIndexed);
1548// DEBUG_LOG(ARM11, "line is %d", __LINE__); 1395 } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BITS(inst, 4, 11) == 0) {
1549 return LnSWoUB(RegisterOffset); 1396 return LnSWoUB(RegisterPreIndexed);
1550 } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) { 1397 } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BIT(inst, 4) == 0) {
1551// DEBUG_MSG; 1398 return LnSWoUB(ScaledRegisterPreIndexed);
1552// DEBUG_LOG(ARM11, "line is %d", __LINE__); 1399 } else if (BITS(inst, 24, 27) == 4 && BIT(inst, 21) == 0) {
1553 return LnSWoUB(ScaledRegisterOffset); 1400 return LnSWoUB(ImmediatePostIndexed);
1554 } else if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 1) { 1401 } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
1555// DEBUG_LOG(ARM11, "line is %d", __LINE__); 1402 return LnSWoUB(RegisterPostIndexed);
1556 return LnSWoUB(ImmediatePreIndexed); 1403 } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
1557 } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BITS(inst, 4, 11) == 0) { 1404 return LnSWoUB(ScaledRegisterPostIndexed);
1558 return LnSWoUB(RegisterPreIndexed); 1405 } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1559 } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BIT(inst, 4) == 0) { 1406 return MLnS(ImmediateOffset);
1560 return LnSWoUB(ScaledRegisterPreIndexed); 1407 } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1561 } else if (BITS(inst, 24, 27) == 4 && BIT(inst, 21) == 0) { 1408 return MLnS(RegisterOffset);
1562 return LnSWoUB(ImmediatePostIndexed); 1409 } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1563 } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) { 1410 return MLnS(ImmediatePreIndexed);
1564// DEBUG_MSG; 1411 } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1565 return LnSWoUB(RegisterPostIndexed); 1412 return MLnS(RegisterPreIndexed);
1566 } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) { 1413 } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1567 return LnSWoUB(ScaledRegisterPostIndexed); 1414 return MLnS(ImmediatePostIndexed);
1568// DEBUG_MSG; 1415 } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1569 } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { 1416 return MLnS(RegisterPostIndexed);
1570 /* 2 */ 1417 } else if (BITS(inst, 23, 27) == 0x11) {
1571// DEBUG_LOG(ARM11, "line is %d", __LINE__); 1418 return LdnStM(IncrementAfter);
1572 return MLnS(ImmediateOffset); 1419 } else if (BITS(inst, 23, 27) == 0x13) {
1573// DEBUG_MSG; 1420 return LdnStM(IncrementBefore);
1574 } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { 1421 } else if (BITS(inst, 23, 27) == 0x10) {
1575// DEBUG_LOG(ARM11, "line is %d\n", __LINE__); 1422 return LdnStM(DecrementAfter);
1576 return MLnS(RegisterOffset); 1423 } else if (BITS(inst, 23, 27) == 0x12) {
1577// DEBUG_MSG; 1424 return LdnStM(DecrementBefore);
1578 } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { 1425 }
1579// DEBUG_LOG(ARM11, "line is %d\n", __LINE__); 1426 return nullptr;
1580 return MLnS(ImmediatePreIndexed);
1581// DEBUG_MSG;
1582 } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1583 return MLnS(RegisterPreIndexed);
1584 } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1585// DEBUG_MSG;
1586 return MLnS(ImmediatePostIndexed);
1587 } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1588 //DEBUG_MSG;
1589 return MLnS(RegisterPostIndexed);
1590 } else if (BITS(inst, 23, 27) == 0x11) {
1591 /* 3 */
1592// DEBUG_MSG;
1593// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1594 return LdnStM(IncrementAfter);
1595 } else if (BITS(inst, 23, 27) == 0x13) {
1596// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1597 return LdnStM(IncrementBefore);
1598// DEBUG_MSG;
1599 } else if (BITS(inst, 23, 27) == 0x10) {
1600// DEBUG_MSG;
1601// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1602 return LdnStM(DecrementAfter);
1603 } else if (BITS(inst, 23, 27) == 0x12) {
1604// DEBUG_MSG;
1605// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1606 return LdnStM(DecrementBefore);
1607 }
1608 #if 0
1609 DEBUG_LOG(ARM11, "In %s Unknown addressing mode\n", __FUNCTION__);
1610 DEBUG_LOG(ARM11, "inst:%x\n", inst);
1611 CITRA_IGNORE_EXIT(-1);
1612 #endif
1613 return NULL;
1614} 1427}
1615 1428
1616#define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s) 1429#define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s)
1617 1430
1618#define CHECK_RN (inst_cream->Rn == 15) 1431#define CHECK_RN (inst_cream->Rn == 15)
1619#define CHECK_RM (inst_cream->Rm == 15) 1432#define CHECK_RM (inst_cream->Rm == 15)
1620#define CHECK_RS (inst_cream->Rs == 15) 1433#define CHECK_RS (inst_cream->Rs == 15)
1621 1434
1435#define UNIMPLEMENTED_INSTRUCTION(mnemonic) \
1436 LOG_ERROR(Core_ARM11, "unimplemented instruction: %s", mnemonic); \
1437 CITRA_IGNORE_EXIT(-1); \
1438 return nullptr;
1622 1439
1623ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index) 1440ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index)
1624{ 1441{
1625 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst)); 1442 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst));
1626 adc_inst *inst_cream = (adc_inst *)inst_base->component; 1443 adc_inst *inst_cream = (adc_inst *)inst_base->component;
1627 1444
1628 inst_base->cond = BITS(inst, 28, 31); 1445 inst_base->cond = BITS(inst, 28, 31);
1629 inst_base->idx = index; 1446 inst_base->idx = index;
1630 inst_base->br = NON_BRANCH; 1447 inst_base->br = NON_BRANCH;
1631 inst_base->load_r15 = 0; 1448 inst_base->load_r15 = 0;
1632 1449
1633 inst_cream->I = BIT(inst, 25); 1450 inst_cream->I = BIT(inst, 25);
1634 inst_cream->S = BIT(inst, 20); 1451 inst_cream->S = BIT(inst, 20);
1635 inst_cream->Rn = BITS(inst, 16, 19); 1452 inst_cream->Rn = BITS(inst, 16, 19);
1636 inst_cream->Rd = BITS(inst, 12, 15); 1453 inst_cream->Rd = BITS(inst, 12, 15);
1637 if (CHECK_RN) 1454 if (CHECK_RN)
1638 inst_base->load_r15 = 1; 1455 inst_base->load_r15 = 1;
1639 inst_cream->shifter_operand = BITS(inst, 0, 11); 1456 inst_cream->shifter_operand = BITS(inst, 0, 11);
1640 inst_cream->shtop_func = get_shtop(inst); 1457 inst_cream->shtop_func = get_shtop(inst);
1641 if (inst_cream->Rd == 15) { 1458 if (inst_cream->Rd == 15) {
1642 inst_base->br = INDIRECT_BRANCH; 1459 inst_base->br = INDIRECT_BRANCH;
1643 } 1460 }
1644 return inst_base; 1461 return inst_base;
1645} 1462}
1646ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index) 1463ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index)
1647{ 1464{
1648 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst)); 1465 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst));
1649 add_inst *inst_cream = (add_inst *)inst_base->component; 1466 add_inst *inst_cream = (add_inst *)inst_base->component;
1650 1467
1651 inst_base->cond = BITS(inst, 28, 31); 1468 inst_base->cond = BITS(inst, 28, 31);
1652 inst_base->idx = index; 1469 inst_base->idx = index;
1653 inst_base->br = NON_BRANCH; 1470 inst_base->br = NON_BRANCH;
1654 inst_base->load_r15 = 0; 1471 inst_base->load_r15 = 0;
1655 1472
1656 inst_cream->I = BIT(inst, 25); 1473 inst_cream->I = BIT(inst, 25);
1657 inst_cream->S = BIT(inst, 20); 1474 inst_cream->S = BIT(inst, 20);
1658 inst_cream->Rn = BITS(inst, 16, 19); 1475 inst_cream->Rn = BITS(inst, 16, 19);
1659 inst_cream->Rd = BITS(inst, 12, 15); 1476 inst_cream->Rd = BITS(inst, 12, 15);
1660 if (CHECK_RN) 1477 if (CHECK_RN)
1661 inst_base->load_r15 = 1; 1478 inst_base->load_r15 = 1;
1662 inst_cream->shifter_operand = BITS(inst, 0, 11); 1479 inst_cream->shifter_operand = BITS(inst, 0, 11);
1663 inst_cream->shtop_func = get_shtop(inst); 1480 inst_cream->shtop_func = get_shtop(inst);
1664 if (inst_cream->Rd == 15) { 1481 if (inst_cream->Rd == 15) {
1665 inst_base->br = INDIRECT_BRANCH; 1482 inst_base->br = INDIRECT_BRANCH;
1666 } 1483 }
1667 return inst_base; 1484 return inst_base;
1668} 1485}
1669ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index) 1486ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index)
1670{ 1487{
1671 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst)); 1488 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst));
1672 and_inst *inst_cream = (and_inst *)inst_base->component; 1489 and_inst *inst_cream = (and_inst *)inst_base->component;
1673 1490
1674 inst_base->cond = BITS(inst, 28, 31); 1491 inst_base->cond = BITS(inst, 28, 31);
1675 inst_base->idx = index; 1492 inst_base->idx = index;
1676 inst_base->br = NON_BRANCH; 1493 inst_base->br = NON_BRANCH;
1677 inst_base->load_r15 = 0; 1494 inst_base->load_r15 = 0;
1678 1495
1679 inst_cream->I = BIT(inst, 25); 1496 inst_cream->I = BIT(inst, 25);
1680 inst_cream->S = BIT(inst, 20); 1497 inst_cream->S = BIT(inst, 20);
1681 inst_cream->Rn = BITS(inst, 16, 19); 1498 inst_cream->Rn = BITS(inst, 16, 19);
1682 inst_cream->Rd = BITS(inst, 12, 15); 1499 inst_cream->Rd = BITS(inst, 12, 15);
1683 if (CHECK_RN) 1500 if (CHECK_RN)
1684 inst_base->load_r15 = 1; 1501 inst_base->load_r15 = 1;
1685 inst_cream->shifter_operand = BITS(inst, 0, 11); 1502 inst_cream->shifter_operand = BITS(inst, 0, 11);
1686 inst_cream->shtop_func = get_shtop(inst); 1503 inst_cream->shtop_func = get_shtop(inst);
1687 if (inst_cream->Rd == 15) 1504 if (inst_cream->Rd == 15)
1688 inst_base->br = INDIRECT_BRANCH; 1505 inst_base->br = INDIRECT_BRANCH;
1689 return inst_base; 1506 return inst_base;
1690} 1507}
1691ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index) 1508ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index)
1692{ 1509{
1693 #define POSBRANCH ((inst & 0x7fffff) << 2) 1510 #define POSBRANCH ((inst & 0x7fffff) << 2)
1694 #define NEGBRANCH ((0xff000000 |(inst & 0xffffff)) << 2) 1511 #define NEGBRANCH ((0xff000000 |(inst & 0xffffff)) << 2)
1695 1512
1696 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst)); 1513 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst));
1697 bbl_inst *inst_cream = (bbl_inst *)inst_base->component; 1514 bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
1698 1515
1699 inst_base->cond = BITS(inst, 28, 31); 1516 inst_base->cond = BITS(inst, 28, 31);
1700 inst_base->idx = index; 1517 inst_base->idx = index;
1701 inst_base->br = DIRECT_BRANCH; 1518 inst_base->br = DIRECT_BRANCH;
1702 1519
1703 if (BIT(inst, 24)) 1520 if (BIT(inst, 24))
1704 inst_base->br = CALL; 1521 inst_base->br = CALL;
1705 if (BITS(inst, 28, 31) <= 0xe) 1522 if (BITS(inst, 28, 31) <= 0xe)
1706 inst_base->br |= COND; 1523 inst_base->br |= COND;
1707 1524
1708 inst_cream->L = BIT(inst, 24); 1525 inst_cream->L = BIT(inst, 24);
1709 inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH; 1526 inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH;
1710 1527
1711 return inst_base; 1528 return inst_base;
1712} 1529}
1713ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index) 1530ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index)
1714{ 1531{
1715 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst)); 1532 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst));
1716 bic_inst *inst_cream = (bic_inst *)inst_base->component; 1533 bic_inst *inst_cream = (bic_inst *)inst_base->component;
1717 1534
1718 inst_base->cond = BITS(inst, 28, 31); 1535 inst_base->cond = BITS(inst, 28, 31);
1719 inst_base->idx = index; 1536 inst_base->idx = index;
1720 inst_base->br = NON_BRANCH; 1537 inst_base->br = NON_BRANCH;
1721 inst_base->load_r15 = 0; 1538 inst_base->load_r15 = 0;
1722 1539
1723 inst_cream->I = BIT(inst, 25); 1540 inst_cream->I = BIT(inst, 25);
1724 inst_cream->S = BIT(inst, 20); 1541 inst_cream->S = BIT(inst, 20);
1725 inst_cream->Rn = BITS(inst, 16, 19); 1542 inst_cream->Rn = BITS(inst, 16, 19);
1726 inst_cream->Rd = BITS(inst, 12, 15); 1543 inst_cream->Rd = BITS(inst, 12, 15);
1727 if (CHECK_RN) 1544 if (CHECK_RN)
1728 inst_base->load_r15 = 1; 1545 inst_base->load_r15 = 1;
1729 inst_cream->shifter_operand = BITS(inst, 0, 11); 1546 inst_cream->shifter_operand = BITS(inst, 0, 11);
1730 inst_cream->shtop_func = get_shtop(inst); 1547 inst_cream->shtop_func = get_shtop(inst);
1731 1548
1732 if (inst_cream->Rd == 15) 1549 if (inst_cream->Rd == 15)
1733 inst_base->br = INDIRECT_BRANCH; 1550 inst_base->br = INDIRECT_BRANCH;
1734 return inst_base; 1551 return inst_base;
1735} 1552}
1736ARM_INST_PTR INTERPRETER_TRANSLATE(bkpt)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 1553ARM_INST_PTR INTERPRETER_TRANSLATE(bkpt)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("BKPT"); }
1737ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index) 1554ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index)
1738{ 1555{
1739 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst)); 1556 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst));
1740 blx_inst *inst_cream = (blx_inst *)inst_base->component; 1557 blx_inst *inst_cream = (blx_inst *)inst_base->component;
1741 1558
1742 inst_base->cond = BITS(inst, 28, 31); 1559 inst_base->cond = BITS(inst, 28, 31);
1743 inst_base->idx = index; 1560 inst_base->idx = index;
1744 inst_base->br = INDIRECT_BRANCH; 1561 inst_base->br = INDIRECT_BRANCH;
1745 1562
1746 inst_cream->inst = inst; 1563 inst_cream->inst = inst;
1747 if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { 1564 if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
1748 inst_cream->val.Rm = BITS(inst, 0, 3); 1565 inst_cream->val.Rm = BITS(inst, 0, 3);
1749 } else { 1566 } else {
1750 inst_cream->val.signed_immed_24 = BITS(inst, 0, 23); 1567 inst_cream->val.signed_immed_24 = BITS(inst, 0, 23);
1751 //DEBUG_LOG(ARM11, " blx inst is %x\n", inst); 1568 }
1752 //CITRA_IGNORE_EXIT(-1);
1753// DEBUG_MSG;
1754 }
1755 1569
1756 return inst_base; 1570 return inst_base;
1757} 1571}
1758ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index) 1572ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index)
1759{ 1573{
1760 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst)); 1574 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst));
1761 bx_inst *inst_cream = (bx_inst *)inst_base->component; 1575 bx_inst *inst_cream = (bx_inst *)inst_base->component;
1762 1576
1763 inst_base->cond = BITS(inst, 28, 31); 1577 inst_base->cond = BITS(inst, 28, 31);
1764 inst_base->idx = index; 1578 inst_base->idx = index;
1765 inst_base->br = INDIRECT_BRANCH; 1579 inst_base->br = INDIRECT_BRANCH;
1766 1580
1767 inst_cream->Rm = BITS(inst, 0, 3); 1581 inst_cream->Rm = BITS(inst, 0, 3);
1768 1582
1769 return inst_base; 1583 return inst_base;
1770} 1584}
1771ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 1585ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("BXJ"); }
1772ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){ 1586ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){
1773 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst)); 1587 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst));
1774 cdp_inst *inst_cream = (cdp_inst *)inst_base->component; 1588 cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
1775 inst_base->cond = BITS(inst, 28, 31); 1589 inst_base->cond = BITS(inst, 28, 31);
1776 inst_base->idx = index; 1590 inst_base->idx = index;
1777 inst_base->br = NON_BRANCH; 1591 inst_base->br = NON_BRANCH;
1778 inst_base->load_r15 = 0; 1592 inst_base->load_r15 = 0;
1779 1593
1780 inst_cream->CRm = BITS(inst, 0, 3); 1594 inst_cream->CRm = BITS(inst, 0, 3);
1781 inst_cream->CRd = BITS(inst, 12, 15); 1595 inst_cream->CRd = BITS(inst, 12, 15);
1782 inst_cream->CRn = BITS(inst, 16, 19); 1596 inst_cream->CRn = BITS(inst, 16, 19);
1783 inst_cream->cp_num = BITS(inst, 8, 11); 1597 inst_cream->cp_num = BITS(inst, 8, 11);
1784 inst_cream->opcode_2 = BITS(inst, 5, 7); 1598 inst_cream->opcode_2 = BITS(inst, 5, 7);
1785 inst_cream->opcode_1 = BITS(inst, 20, 23); 1599 inst_cream->opcode_1 = BITS(inst, 20, 23);
1786 inst_cream->inst = inst; 1600 inst_cream->inst = inst;
1787 1601
1788 DEBUG_LOG(ARM11, "in func %s inst %x index %x\n", __FUNCTION__, inst, index); 1602 LOG_TRACE(Core_ARM11, "inst %x index %x", inst, index);
1789 return inst_base; 1603 return inst_base;
1790} 1604}
1791ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index) 1605ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index)
1792{ 1606{
1793 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst)); 1607 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst));
1794 inst_base->cond = BITS(inst, 28, 31); 1608 inst_base->cond = BITS(inst, 28, 31);
1795 inst_base->idx = index; 1609 inst_base->idx = index;
1796 inst_base->br = NON_BRANCH; 1610 inst_base->br = NON_BRANCH;
1797 1611
1798 return inst_base; 1612 return inst_base;
1799} 1613}
1800ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index) 1614ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index)
1801{ 1615{
1802 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst)); 1616 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst));
1803 clz_inst *inst_cream = (clz_inst *)inst_base->component; 1617 clz_inst *inst_cream = (clz_inst *)inst_base->component;
1804 1618
1805 inst_base->cond = BITS(inst, 28, 31); 1619 inst_base->cond = BITS(inst, 28, 31);
1806 inst_base->idx = index; 1620 inst_base->idx = index;
1807 inst_base->br = NON_BRANCH; 1621 inst_base->br = NON_BRANCH;
1808 inst_base->load_r15 = 0; 1622 inst_base->load_r15 = 0;
1809 1623
1810 inst_cream->Rm = BITS(inst, 0, 3); 1624 inst_cream->Rm = BITS(inst, 0, 3);
1811 inst_cream->Rd = BITS(inst, 12, 15); 1625 inst_cream->Rd = BITS(inst, 12, 15);
1812 if (CHECK_RM) 1626 if (CHECK_RM)
1813 inst_base->load_r15 = 1; 1627 inst_base->load_r15 = 1;
1814 1628
1815 return inst_base; 1629 return inst_base;
1816} 1630}
1817ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index) 1631ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index)
1818{ 1632{
1819 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst)); 1633 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst));
1820 cmn_inst *inst_cream = (cmn_inst *)inst_base->component; 1634 cmn_inst *inst_cream = (cmn_inst *)inst_base->component;
1821 1635
1822 inst_base->cond = BITS(inst, 28, 31); 1636 inst_base->cond = BITS(inst, 28, 31);
1823 inst_base->idx = index; 1637 inst_base->idx = index;
1824 inst_base->br = NON_BRANCH; 1638 inst_base->br = NON_BRANCH;
1825 inst_base->load_r15 = 0; 1639 inst_base->load_r15 = 0;
1826 1640
1827 inst_cream->I = BIT(inst, 25); 1641 inst_cream->I = BIT(inst, 25);
1828 //inst_cream->S = BIT(inst, 20); 1642 //inst_cream->S = BIT(inst, 20);
1829 inst_cream->Rn = BITS(inst, 16, 19); 1643 inst_cream->Rn = BITS(inst, 16, 19);
1830 //inst_cream->Rd = BITS(inst, 12, 15); 1644 //inst_cream->Rd = BITS(inst, 12, 15);
1831 if (CHECK_RN) 1645 if (CHECK_RN)
1832 inst_base->load_r15 = 1; 1646 inst_base->load_r15 = 1;
1833 inst_cream->shifter_operand = BITS(inst, 0, 11); 1647 inst_cream->shifter_operand = BITS(inst, 0, 11);
1834 inst_cream->shtop_func = get_shtop(inst); 1648 inst_cream->shtop_func = get_shtop(inst);
1835 return inst_base; 1649 return inst_base;
1836} 1650}
1837ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index) 1651ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index)
1838{ 1652{
1839 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst)); 1653 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst));
1840 cmp_inst *inst_cream = (cmp_inst *)inst_base->component; 1654 cmp_inst *inst_cream = (cmp_inst *)inst_base->component;
1841 1655
1842 inst_base->cond = BITS(inst, 28, 31); 1656 inst_base->cond = BITS(inst, 28, 31);
1843 inst_base->idx = index; 1657 inst_base->idx = index;
1844 inst_base->br = NON_BRANCH; 1658 inst_base->br = NON_BRANCH;
1845 inst_base->load_r15 = 0; 1659 inst_base->load_r15 = 0;
1846 1660
1847 inst_cream->I = BIT(inst, 25); 1661 inst_cream->I = BIT(inst, 25);
1848 inst_cream->Rn = BITS(inst, 16, 19); 1662 inst_cream->Rn = BITS(inst, 16, 19);
1849 if (CHECK_RN) 1663 if (CHECK_RN)
1850 inst_base->load_r15 = 1; 1664 inst_base->load_r15 = 1;
1851 inst_cream->shifter_operand = BITS(inst, 0, 11); 1665 inst_cream->shifter_operand = BITS(inst, 0, 11);
1852 inst_cream->shtop_func = get_shtop(inst); 1666 inst_cream->shtop_func = get_shtop(inst);
1853 return inst_base; 1667 return inst_base;
1854} 1668}
1855ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index) 1669ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index)
1856{ 1670{
1857 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst)); 1671 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst));
1858 cps_inst *inst_cream = (cps_inst *)inst_base->component; 1672 cps_inst *inst_cream = (cps_inst *)inst_base->component;
1859 1673
1860 inst_base->cond = BITS(inst, 28, 31); 1674 inst_base->cond = BITS(inst, 28, 31);
1861 inst_base->idx = index; 1675 inst_base->idx = index;
1862 inst_base->br = NON_BRANCH; 1676 inst_base->br = NON_BRANCH;
1863 1677
1864 inst_cream->imod0 = BIT(inst, 18); 1678 inst_cream->imod0 = BIT(inst, 18);
1865 inst_cream->imod1 = BIT(inst, 19); 1679 inst_cream->imod1 = BIT(inst, 19);
1866 inst_cream->mmod = BIT(inst, 17); 1680 inst_cream->mmod = BIT(inst, 17);
1867 inst_cream->A = BIT(inst, 8); 1681 inst_cream->A = BIT(inst, 8);
1868 inst_cream->I = BIT(inst, 7); 1682 inst_cream->I = BIT(inst, 7);
1869 inst_cream->F = BIT(inst, 6); 1683 inst_cream->F = BIT(inst, 6);
1870 inst_cream->mode = BITS(inst, 0, 4); 1684 inst_cream->mode = BITS(inst, 0, 4);
1871 1685
1872 return inst_base; 1686 return inst_base;
1873} 1687}
1874ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index) 1688ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index)
1875{ 1689{
1876 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); 1690 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
1877 mov_inst *inst_cream = (mov_inst *)inst_base->component; 1691 mov_inst *inst_cream = (mov_inst *)inst_base->component;
1878 1692
1879 inst_base->cond = BITS(inst, 28, 31); 1693 inst_base->cond = BITS(inst, 28, 31);
1880 inst_base->idx = index; 1694 inst_base->idx = index;
1881 inst_base->br = NON_BRANCH; 1695 inst_base->br = NON_BRANCH;
1882 1696
1883 inst_cream->I = BIT(inst, 25); 1697 inst_cream->I = BIT(inst, 25);
1884 inst_cream->S = BIT(inst, 20); 1698 inst_cream->S = BIT(inst, 20);
1885 inst_cream->Rd = BITS(inst, 12, 15); 1699 inst_cream->Rd = BITS(inst, 12, 15);
1886 inst_cream->shifter_operand = BITS(inst, 0, 11); 1700 inst_cream->shifter_operand = BITS(inst, 0, 11);
1887 inst_cream->shtop_func = get_shtop(inst); 1701 inst_cream->shtop_func = get_shtop(inst);
1888 1702
1889 if (inst_cream->Rd == 15) { 1703 if (inst_cream->Rd == 15) {
1890 inst_base->br = INDIRECT_BRANCH; 1704 inst_base->br = INDIRECT_BRANCH;
1891 } 1705 }
1892 return inst_base; 1706 return inst_base;
1893} 1707}
1894ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index) 1708ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index)
1895{ 1709{
1896 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst)); 1710 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst));
1897 eor_inst *inst_cream = (eor_inst *)inst_base->component; 1711 eor_inst *inst_cream = (eor_inst *)inst_base->component;
1898 1712
1899 inst_base->cond = BITS(inst, 28, 31); 1713 inst_base->cond = BITS(inst, 28, 31);
1900 inst_base->idx = index; 1714 inst_base->idx = index;
1901 inst_base->br = NON_BRANCH; 1715 inst_base->br = NON_BRANCH;
1902 inst_base->load_r15 = 0; 1716 inst_base->load_r15 = 0;
1903 1717
1904 inst_cream->I = BIT(inst, 25); 1718 inst_cream->I = BIT(inst, 25);
1905 inst_cream->S = BIT(inst, 20); 1719 inst_cream->S = BIT(inst, 20);
1906 inst_cream->Rn = BITS(inst, 16, 19); 1720 inst_cream->Rn = BITS(inst, 16, 19);
1907 inst_cream->Rd = BITS(inst, 12, 15); 1721 inst_cream->Rd = BITS(inst, 12, 15);
1908 if (CHECK_RN) 1722 if (CHECK_RN)
1909 inst_base->load_r15 = 1; 1723 inst_base->load_r15 = 1;
1910 inst_cream->shifter_operand = BITS(inst, 0, 11); 1724 inst_cream->shifter_operand = BITS(inst, 0, 11);
1911 inst_cream->shtop_func = get_shtop(inst); 1725 inst_cream->shtop_func = get_shtop(inst);
1912 if (inst_cream->Rd == 15) { 1726 if (inst_cream->Rd == 15) {
1913 inst_base->br = INDIRECT_BRANCH; 1727 inst_base->br = INDIRECT_BRANCH;
1914 } 1728 }
1915 return inst_base; 1729 return inst_base;
1916} 1730}
1917ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index) 1731ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index)
1918{ 1732{
1919 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst)); 1733 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst));
1920 inst_base->cond = BITS(inst, 28, 31); 1734 inst_base->cond = BITS(inst, 28, 31);
1921 inst_base->idx = index; 1735 inst_base->idx = index;
1922 inst_base->br = NON_BRANCH; 1736 inst_base->br = NON_BRANCH;
1923 1737
1924 return inst_base; 1738 return inst_base;
1925} 1739}
1926ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index) 1740ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index)
1927{ 1741{
1928 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 1742 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
1929 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 1743 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
1930 1744
1931 inst_base->cond = BITS(inst, 28, 31); 1745 inst_base->cond = BITS(inst, 28, 31);
1932 inst_base->idx = index; 1746 inst_base->idx = index;
1933 inst_base->br = NON_BRANCH; 1747 inst_base->br = NON_BRANCH;
1934 1748
1935 inst_cream->inst = inst; 1749 inst_cream->inst = inst;
1936 inst_cream->get_addr = get_calc_addr_op(inst); 1750 inst_cream->get_addr = get_calc_addr_op(inst);
1937 1751
1938 if (BIT(inst, 15)) { 1752 if (BIT(inst, 15)) {
1939 inst_base->br = INDIRECT_BRANCH; 1753 inst_base->br = INDIRECT_BRANCH;
1940 } 1754 }
1941 return inst_base; 1755 return inst_base;
1942} 1756}
1943ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index) 1757ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index)
1944{ 1758{
1945 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); 1759 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
1946 sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; 1760 sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
1947 1761
1948 inst_base->cond = BITS(inst, 28, 31); 1762 inst_base->cond = BITS(inst, 28, 31);
1949 inst_base->idx = index; 1763 inst_base->idx = index;
1950 inst_base->br = NON_BRANCH; 1764 inst_base->br = NON_BRANCH;
1951 inst_base->load_r15 = 0; 1765 inst_base->load_r15 = 0;
1952 1766
1953 inst_cream->Rd = BITS(inst, 12, 15); 1767 inst_cream->Rd = BITS(inst, 12, 15);
1954 inst_cream->Rm = BITS(inst, 0, 3); 1768 inst_cream->Rm = BITS(inst, 0, 3);
1955 inst_cream->rotate = BITS(inst, 10, 11); 1769 inst_cream->rotate = BITS(inst, 10, 11);
1956 if (CHECK_RM) 1770 if (CHECK_RM)
1957 inst_base->load_r15 = 1; 1771 inst_base->load_r15 = 1;
1958 1772
1959 return inst_base; 1773 return inst_base;
1960} 1774}
1961ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index) 1775ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index)
1962{ 1776{
1963 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 1777 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
1964 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 1778 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
1965 1779
1966 inst_base->cond = BITS(inst, 28, 31); 1780 inst_base->cond = BITS(inst, 28, 31);
1967 inst_base->idx = index; 1781 inst_base->idx = index;
1968 inst_base->br = NON_BRANCH; 1782 inst_base->br = NON_BRANCH;
1969 inst_base->load_r15 = 0; 1783 inst_base->load_r15 = 0;
1970 1784
1971 inst_cream->inst = inst; 1785 inst_cream->inst = inst;
1972 inst_cream->get_addr = get_calc_addr_op(inst); 1786 inst_cream->get_addr = get_calc_addr_op(inst);
1973 1787
1974 if (BITS(inst, 12, 15) == 15) { 1788 if (BITS(inst, 12, 15) == 15) {
1975 inst_base->br = INDIRECT_BRANCH; 1789 inst_base->br = INDIRECT_BRANCH;
1976 } 1790 }
1977 return inst_base; 1791 return inst_base;
1978} 1792}
1979 1793
1980ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index) 1794ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index)
1981{ 1795{
1982 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 1796 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
1983 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 1797 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
1984 1798
1985 inst_base->cond = BITS(inst, 28, 31); 1799 inst_base->cond = BITS(inst, 28, 31);
1986 inst_base->idx = index; 1800 inst_base->idx = index;
1987 inst_base->br = NON_BRANCH; 1801 inst_base->br = NON_BRANCH;
1988 inst_base->load_r15 = 0; 1802 inst_base->load_r15 = 0;
1989 1803
1990 inst_cream->inst = inst; 1804 inst_cream->inst = inst;
1991 inst_cream->get_addr = get_calc_addr_op(inst); 1805 inst_cream->get_addr = get_calc_addr_op(inst);
1992 1806
1993 if (BITS(inst, 12, 15) == 15) { 1807 if (BITS(inst, 12, 15) == 15) {
1994 inst_base->br = INDIRECT_BRANCH; 1808 inst_base->br = INDIRECT_BRANCH;
1995 } 1809 }
1996 return inst_base; 1810 return inst_base;
1997} 1811}
1998 1812
1999ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index) 1813ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index)
2000{ 1814{
2001 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); 1815 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
2002 uxth_inst *inst_cream = (uxth_inst *)inst_base->component; 1816 uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
2003 1817
2004 inst_base->cond = BITS(inst, 28, 31); 1818 inst_base->cond = BITS(inst, 28, 31);
2005 inst_base->idx = index; 1819 inst_base->idx = index;
2006 inst_base->br = NON_BRANCH; 1820 inst_base->br = NON_BRANCH;
2007 inst_base->load_r15 = 0; 1821 inst_base->load_r15 = 0;
2008 1822
2009 inst_cream->Rd = BITS(inst, 12, 15); 1823 inst_cream->Rd = BITS(inst, 12, 15);
2010 inst_cream->rotate = BITS(inst, 10, 11); 1824 inst_cream->rotate = BITS(inst, 10, 11);
2011 inst_cream->Rm = BITS(inst, 0, 3); 1825 inst_cream->Rm = BITS(inst, 0, 3);
2012 if (CHECK_RM) 1826 if (CHECK_RM)
2013 inst_base->load_r15 = 1; 1827 inst_base->load_r15 = 1;
2014 1828
2015 return inst_base; 1829 return inst_base;
2016} 1830}
2017ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index) 1831ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index)
2018{ 1832{
2019 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst)); 1833 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst));
2020 uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component; 1834 uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component;
2021 1835
2022 inst_base->cond = BITS(inst, 28, 31); 1836 inst_base->cond = BITS(inst, 28, 31);
2023 inst_base->idx = index; 1837 inst_base->idx = index;
2024 inst_base->br = NON_BRANCH; 1838 inst_base->br = NON_BRANCH;
2025 inst_base->load_r15 = 0; 1839 inst_base->load_r15 = 0;
2026 1840
2027 inst_cream->Rn = BITS(inst, 16, 19); 1841 inst_cream->Rn = BITS(inst, 16, 19);
2028 inst_cream->Rd = BITS(inst, 12, 15); 1842 inst_cream->Rd = BITS(inst, 12, 15);
2029 inst_cream->rotate = BITS(inst, 10, 11); 1843 inst_cream->rotate = BITS(inst, 10, 11);
2030 inst_cream->Rm = BITS(inst, 0, 3); 1844 inst_cream->Rm = BITS(inst, 0, 3);
2031 if (CHECK_RM || CHECK_RN) 1845 if (CHECK_RM || CHECK_RN)
2032 inst_base->load_r15 = 1; 1846 inst_base->load_r15 = 1;
2033 1847
2034 return inst_base; 1848 return inst_base;
2035} 1849}
2036ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index) 1850ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index)
2037{ 1851{
2038 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 1852 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2039 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 1853 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2040 1854
2041 inst_base->cond = BITS(inst, 28, 31); 1855 inst_base->cond = BITS(inst, 28, 31);
2042 inst_base->idx = index; 1856 inst_base->idx = index;
2043 inst_base->br = NON_BRANCH; 1857 inst_base->br = NON_BRANCH;
2044 1858
2045 inst_cream->inst = inst; 1859 inst_cream->inst = inst;
2046 inst_cream->get_addr = get_calc_addr_op(inst); 1860 inst_cream->get_addr = get_calc_addr_op(inst);
2047 1861
2048 if (BITS(inst, 12, 15) == 15) { 1862 if (BITS(inst, 12, 15) == 15) {
2049 inst_base->br = INDIRECT_BRANCH; 1863 inst_base->br = INDIRECT_BRANCH;
2050 } 1864 }
2051 return inst_base; 1865 return inst_base;
2052} 1866}
2053ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index) 1867ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index)
2054{ 1868{
2055 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 1869 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2056 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 1870 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2057 1871
2058 inst_base->cond = BITS(inst, 28, 31); 1872 inst_base->cond = BITS(inst, 28, 31);
2059 inst_base->idx = index; 1873 inst_base->idx = index;
2060 inst_base->br = NON_BRANCH; 1874 inst_base->br = NON_BRANCH;
2061 1875
2062 inst_cream->inst = inst; 1876 inst_cream->inst = inst;
2063 if (I_BIT == 0) { 1877 if (I_BIT == 0) {
2064 inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); 1878 inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
2065 } else { 1879 } else {
2066 DEBUG_MSG; 1880 DEBUG_MSG;
2067 } 1881 }
2068 #if 0 1882 #if 0
2069 inst_cream->get_addr = get_calc_addr_op(inst); 1883 inst_cream->get_addr = get_calc_addr_op(inst);
2070 if(inst == 0x54f13001) { 1884 if(inst == 0x54f13001) {
2071 DEBUG_LOG(ARM11, "get_calc_addr_op:%llx\n", inst_cream->get_addr); 1885 DEBUG_LOG(ARM11, "get_calc_addr_op:%llx\n", inst_cream->get_addr);
2072 } 1886 }
2073 #endif 1887 #endif
2074 1888
2075 if (BITS(inst, 12, 15) == 15) { 1889 if (BITS(inst, 12, 15) == 15) {
2076 inst_base->br = INDIRECT_BRANCH; 1890 inst_base->br = INDIRECT_BRANCH;
2077 } 1891 }
2078 return inst_base; 1892 return inst_base;
2079} 1893}
2080ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index) 1894ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index)
2081{ 1895{
2082 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 1896 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2083 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 1897 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2084 1898
2085 inst_base->cond = BITS(inst, 28, 31); 1899 inst_base->cond = BITS(inst, 28, 31);
2086 inst_base->idx = index; 1900 inst_base->idx = index;
2087 inst_base->br = NON_BRANCH; 1901 inst_base->br = NON_BRANCH;
2088 1902
2089 inst_cream->inst = inst; 1903 inst_cream->inst = inst;
2090 inst_cream->get_addr = get_calc_addr_op(inst); 1904 inst_cream->get_addr = get_calc_addr_op(inst);
2091 1905
2092 return inst_base; 1906 return inst_base;
2093} 1907}
2094 1908
2095ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index) 1909ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index)
2096{ 1910{
2097 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 1911 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2098 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 1912 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2099 1913
2100 inst_base->cond = BITS(inst, 28, 31); 1914 inst_base->cond = BITS(inst, 28, 31);
2101 inst_base->idx = index; 1915 inst_base->idx = index;
2102 inst_base->br = NON_BRANCH; 1916 inst_base->br = NON_BRANCH;
2103 1917
2104 inst_cream->inst = inst; 1918 inst_cream->inst = inst;
2105 //inst_cream->get_addr = get_calc_addr_op(inst); 1919 //inst_cream->get_addr = get_calc_addr_op(inst);
2106 1920
2107 if (BITS(inst, 12, 15) == 15) { 1921 if (BITS(inst, 12, 15) == 15) {
2108 inst_base->br = INDIRECT_BRANCH; 1922 inst_base->br = INDIRECT_BRANCH;
2109 } 1923 }
2110 return inst_base; 1924 return inst_base;
2111} 1925}
2112ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index) 1926ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index)
2113{ 1927{
2114 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 1928 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2115 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 1929 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2116 1930
2117 inst_base->cond = BITS(inst, 28, 31); 1931 inst_base->cond = BITS(inst, 28, 31);
2118 inst_base->idx = index; 1932 inst_base->idx = index;
2119 inst_base->br = NON_BRANCH; 1933 inst_base->br = NON_BRANCH;
2120 1934
2121 inst_cream->inst = inst; 1935 inst_cream->inst = inst;
2122 inst_cream->get_addr = get_calc_addr_op(inst); 1936 inst_cream->get_addr = get_calc_addr_op(inst);
2123 1937
2124 if (BITS(inst, 12, 15) == 15) { 1938 if (BITS(inst, 12, 15) == 15) {
2125 inst_base->br = INDIRECT_BRANCH; 1939 inst_base->br = INDIRECT_BRANCH;
2126 } 1940 }
2127 return inst_base; 1941 return inst_base;
2128} 1942}
2129ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index) 1943ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index)
2130{ 1944{
2131 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 1945 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2132 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 1946 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2133 1947
2134 inst_base->cond = BITS(inst, 28, 31); 1948 inst_base->cond = BITS(inst, 28, 31);
2135 inst_base->idx = index; 1949 inst_base->idx = index;
2136 inst_base->br = NON_BRANCH; 1950 inst_base->br = NON_BRANCH;
2137 1951
2138 inst_cream->inst = inst; 1952 inst_cream->inst = inst;
2139 inst_cream->get_addr = get_calc_addr_op(inst); 1953 inst_cream->get_addr = get_calc_addr_op(inst);
2140 1954
2141 if (BITS(inst, 12, 15) == 15) { 1955 if (BITS(inst, 12, 15) == 15) {
2142 inst_base->br = INDIRECT_BRANCH; 1956 inst_base->br = INDIRECT_BRANCH;
2143 } 1957 }
2144 return inst_base; 1958 return inst_base;
2145} 1959}
2146ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index) 1960ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index)
2147{ 1961{
2148 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 1962 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2149 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 1963 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2150 1964
2151 inst_base->cond = BITS(inst, 28, 31); 1965 inst_base->cond = BITS(inst, 28, 31);
2152 inst_base->idx = index; 1966 inst_base->idx = index;
2153 inst_base->br = NON_BRANCH; 1967 inst_base->br = NON_BRANCH;
2154 1968
2155 inst_cream->inst = inst; 1969 inst_cream->inst = inst;
2156 inst_cream->get_addr = get_calc_addr_op(inst); 1970 inst_cream->get_addr = get_calc_addr_op(inst);
2157 1971
2158 if (BITS(inst, 12, 15) == 15) { 1972 if (BITS(inst, 12, 15) == 15) {
2159 inst_base->br = INDIRECT_BRANCH; 1973 inst_base->br = INDIRECT_BRANCH;
2160 } 1974 }
2161 return inst_base; 1975 return inst_base;
2162} 1976}
2163ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index) 1977ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index)
2164{ 1978{
2165 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 1979 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2166 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 1980 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2167 1981
2168 inst_base->cond = BITS(inst, 28, 31); 1982 inst_base->cond = BITS(inst, 28, 31);
2169 inst_base->idx = index; 1983 inst_base->idx = index;
2170 inst_base->br = NON_BRANCH; 1984 inst_base->br = NON_BRANCH;
2171 1985
2172 inst_cream->inst = inst; 1986 inst_cream->inst = inst;
2173 inst_cream->get_addr = get_calc_addr_op(inst); 1987 inst_cream->get_addr = get_calc_addr_op(inst);
2174 1988
2175 if (BITS(inst, 12, 15) == 15) { 1989 if (BITS(inst, 12, 15) == 15) {
2176 inst_base->br = INDIRECT_BRANCH; 1990 inst_base->br = INDIRECT_BRANCH;
2177 } 1991 }
2178 return inst_base; 1992 return inst_base;
2179} 1993}
2180ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index) 1994ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index)
2181{ 1995{
2182 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 1996 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2183 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 1997 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2184 1998
2185 inst_base->cond = BITS(inst, 28, 31); 1999 inst_base->cond = BITS(inst, 28, 31);
2186 inst_base->idx = index; 2000 inst_base->idx = index;
2187 inst_base->br = NON_BRANCH; 2001 inst_base->br = NON_BRANCH;
2188 2002
2189 inst_cream->inst = inst; 2003 inst_cream->inst = inst;
2190 if (I_BIT == 0) { 2004 if (I_BIT == 0) {
2191 inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); 2005 inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
2192 } else { 2006 } else {
2193 DEBUG_MSG; 2007 DEBUG_MSG;
2194 } 2008 }
2195 2009
2196 if (BITS(inst, 12, 15) == 15) { 2010 if (BITS(inst, 12, 15) == 15) {
2197 inst_base->br = INDIRECT_BRANCH; 2011 inst_base->br = INDIRECT_BRANCH;
2198 } 2012 }
2199 return inst_base; 2013 return inst_base;
2200} 2014}
2201ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index) 2015ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index)
2202{ 2016{
2203 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst)); 2017 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst));
2204 mcr_inst *inst_cream = (mcr_inst *)inst_base->component; 2018 mcr_inst *inst_cream = (mcr_inst *)inst_base->component;
2205 inst_base->cond = BITS(inst, 28, 31); 2019 inst_base->cond = BITS(inst, 28, 31);
2206 inst_base->idx = index; 2020 inst_base->idx = index;
2207 inst_base->br = NON_BRANCH; 2021 inst_base->br = NON_BRANCH;
2208 2022
2209 inst_cream->crn = BITS(inst, 16, 19); 2023 inst_cream->crn = BITS(inst, 16, 19);
2210 inst_cream->crm = BITS(inst, 0, 3); 2024 inst_cream->crm = BITS(inst, 0, 3);
2211 inst_cream->opcode_1 = BITS(inst, 21, 23); 2025 inst_cream->opcode_1 = BITS(inst, 21, 23);
2212 inst_cream->opcode_2 = BITS(inst, 5, 7); 2026 inst_cream->opcode_2 = BITS(inst, 5, 7);
2213 inst_cream->Rd = BITS(inst, 12, 15); 2027 inst_cream->Rd = BITS(inst, 12, 15);
2214 inst_cream->cp_num = BITS(inst, 8, 11); 2028 inst_cream->cp_num = BITS(inst, 8, 11);
2215 inst_cream->inst = inst; 2029 inst_cream->inst = inst;
2216 return inst_base; 2030 return inst_base;
2217} 2031}
2218ARM_INST_PTR INTERPRETER_TRANSLATE(mcrr)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2032ARM_INST_PTR INTERPRETER_TRANSLATE(mcrr)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("MCRR"); }
2219ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index) 2033ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index)
2220{ 2034{
2221 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst)); 2035 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst));
2222 mla_inst *inst_cream = (mla_inst *)inst_base->component; 2036 mla_inst *inst_cream = (mla_inst *)inst_base->component;
2223 2037
2224 inst_base->cond = BITS(inst, 28, 31); 2038 inst_base->cond = BITS(inst, 28, 31);
2225 inst_base->idx = index; 2039 inst_base->idx = index;
2226 inst_base->br = NON_BRANCH; 2040 inst_base->br = NON_BRANCH;
2227 inst_base->load_r15 = 0; 2041 inst_base->load_r15 = 0;
2228 2042
2229 inst_cream->S = BIT(inst, 20); 2043 inst_cream->S = BIT(inst, 20);
2230 inst_cream->Rn = BITS(inst, 12, 15); 2044 inst_cream->Rn = BITS(inst, 12, 15);
2231 inst_cream->Rd = BITS(inst, 16, 19); 2045 inst_cream->Rd = BITS(inst, 16, 19);
2232 inst_cream->Rs = BITS(inst, 8, 11); 2046 inst_cream->Rs = BITS(inst, 8, 11);
2233 inst_cream->Rm = BITS(inst, 0, 3); 2047 inst_cream->Rm = BITS(inst, 0, 3);
2234 2048
2235 if (CHECK_RM || CHECK_RN || CHECK_RS) 2049 if (CHECK_RM || CHECK_RN || CHECK_RS)
2236 inst_base->load_r15 = 1; 2050 inst_base->load_r15 = 1;
2237 2051
2238 return inst_base; 2052 return inst_base;
2239} 2053}
2240ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index) 2054ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index)
2241{ 2055{
2242 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); 2056 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
2243 mov_inst *inst_cream = (mov_inst *)inst_base->component; 2057 mov_inst *inst_cream = (mov_inst *)inst_base->component;
2244 2058
2245 inst_base->cond = BITS(inst, 28, 31); 2059 inst_base->cond = BITS(inst, 28, 31);
2246 inst_base->idx = index; 2060 inst_base->idx = index;
2247 inst_base->br = NON_BRANCH; 2061 inst_base->br = NON_BRANCH;
2248 2062
2249 inst_cream->I = BIT(inst, 25); 2063 inst_cream->I = BIT(inst, 25);
2250 inst_cream->S = BIT(inst, 20); 2064 inst_cream->S = BIT(inst, 20);
2251 inst_cream->Rd = BITS(inst, 12, 15); 2065 inst_cream->Rd = BITS(inst, 12, 15);
2252 inst_cream->shifter_operand = BITS(inst, 0, 11); 2066 inst_cream->shifter_operand = BITS(inst, 0, 11);
2253 inst_cream->shtop_func = get_shtop(inst); 2067 inst_cream->shtop_func = get_shtop(inst);
2254 2068
2255 if (inst_cream->Rd == 15) { 2069 if (inst_cream->Rd == 15) {
2256 inst_base->br = INDIRECT_BRANCH; 2070 inst_base->br = INDIRECT_BRANCH;
2257 } 2071 }
2258 return inst_base; 2072 return inst_base;
2259} 2073}
2260ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index) 2074ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index)
2261{ 2075{
2262 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst)); 2076 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst));
2263 mrc_inst *inst_cream = (mrc_inst *)inst_base->component; 2077 mrc_inst *inst_cream = (mrc_inst *)inst_base->component;
2264 inst_base->cond = BITS(inst, 28, 31); 2078 inst_base->cond = BITS(inst, 28, 31);
2265 inst_base->idx = index; 2079 inst_base->idx = index;
2266 inst_base->br = NON_BRANCH; 2080 inst_base->br = NON_BRANCH;
2267 2081
2268 inst_cream->crn = BITS(inst, 16, 19); 2082 inst_cream->crn = BITS(inst, 16, 19);
2269 inst_cream->crm = BITS(inst, 0, 3); 2083 inst_cream->crm = BITS(inst, 0, 3);
2270 inst_cream->opcode_1 = BITS(inst, 21, 23); 2084 inst_cream->opcode_1 = BITS(inst, 21, 23);
2271 inst_cream->opcode_2 = BITS(inst, 5, 7); 2085 inst_cream->opcode_2 = BITS(inst, 5, 7);
2272 inst_cream->Rd = BITS(inst, 12, 15); 2086 inst_cream->Rd = BITS(inst, 12, 15);
2273 inst_cream->cp_num = BITS(inst, 8, 11); 2087 inst_cream->cp_num = BITS(inst, 8, 11);
2274 inst_cream->inst = inst; 2088 inst_cream->inst = inst;
2275 return inst_base; 2089 return inst_base;
2276} 2090}
2277ARM_INST_PTR INTERPRETER_TRANSLATE(mrrc)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2091ARM_INST_PTR INTERPRETER_TRANSLATE(mrrc)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("MRRC"); }
2278ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index) 2092ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index)
2279{ 2093{
2280 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst)); 2094 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst));
2281 mrs_inst *inst_cream = (mrs_inst *)inst_base->component; 2095 mrs_inst *inst_cream = (mrs_inst *)inst_base->component;
2282 2096
2283 inst_base->cond = BITS(inst, 28, 31); 2097 inst_base->cond = BITS(inst, 28, 31);
2284 inst_base->idx = index; 2098 inst_base->idx = index;
2285 inst_base->br = NON_BRANCH; 2099 inst_base->br = NON_BRANCH;
2286 2100
2287 inst_cream->Rd = BITS(inst, 12, 15); 2101 inst_cream->Rd = BITS(inst, 12, 15);
2288 inst_cream->R = BIT(inst, 22); 2102 inst_cream->R = BIT(inst, 22);
2289 2103
2290 return inst_base; 2104 return inst_base;
2291} 2105}
2292ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index) 2106ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index)
2293{ 2107{
2294 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst)); 2108 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst));
2295 msr_inst *inst_cream = (msr_inst *)inst_base->component; 2109 msr_inst *inst_cream = (msr_inst *)inst_base->component;
2296 2110
2297 inst_base->cond = BITS(inst, 28, 31); 2111 inst_base->cond = BITS(inst, 28, 31);
2298 inst_base->idx = index; 2112 inst_base->idx = index;
2299 inst_base->br = NON_BRANCH; 2113 inst_base->br = NON_BRANCH;
2300 2114
2301 inst_cream->field_mask = BITS(inst, 16, 19); 2115 inst_cream->field_mask = BITS(inst, 16, 19);
2302 inst_cream->R = BIT(inst, 22); 2116 inst_cream->R = BIT(inst, 22);
2303 inst_cream->inst = inst; 2117 inst_cream->inst = inst;
2304 2118
2305 return inst_base; 2119 return inst_base;
2306} 2120}
2307ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index) 2121ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index)
2308{ 2122{
2309 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst)); 2123 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst));
2310 mul_inst *inst_cream = (mul_inst *)inst_base->component; 2124 mul_inst *inst_cream = (mul_inst *)inst_base->component;
2311 2125
2312 inst_base->cond = BITS(inst, 28, 31); 2126 inst_base->cond = BITS(inst, 28, 31);
2313 inst_base->idx = index; 2127 inst_base->idx = index;
2314 inst_base->br = NON_BRANCH; 2128 inst_base->br = NON_BRANCH;
2315 inst_base->load_r15 = 0; 2129 inst_base->load_r15 = 0;
2316 2130
2317 inst_cream->S = BIT(inst, 20); 2131 inst_cream->S = BIT(inst, 20);
2318 inst_cream->Rm = BITS(inst, 0, 3); 2132 inst_cream->Rm = BITS(inst, 0, 3);
2319 inst_cream->Rs = BITS(inst, 8, 11); 2133 inst_cream->Rs = BITS(inst, 8, 11);
2320 inst_cream->Rd = BITS(inst, 16, 19); 2134 inst_cream->Rd = BITS(inst, 16, 19);
2321 2135
2322 if (CHECK_RM || CHECK_RS) 2136 if (CHECK_RM || CHECK_RS)
2323 inst_base->load_r15 = 1; 2137 inst_base->load_r15 = 1;
2324 return inst_base; 2138 return inst_base;
2325} 2139}
2326ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index) 2140ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index)
2327{ 2141{
2328 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst)); 2142 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst));
2329 mvn_inst *inst_cream = (mvn_inst *)inst_base->component; 2143 mvn_inst *inst_cream = (mvn_inst *)inst_base->component;
2330 2144
2331 inst_base->cond = BITS(inst, 28, 31); 2145 inst_base->cond = BITS(inst, 28, 31);
2332 inst_base->idx = index; 2146 inst_base->idx = index;
2333 inst_base->br = NON_BRANCH; 2147 inst_base->br = NON_BRANCH;
2334 2148
2335 inst_cream->I = BIT(inst, 25); 2149 inst_cream->I = BIT(inst, 25);
2336 inst_cream->S = BIT(inst, 20); 2150 inst_cream->S = BIT(inst, 20);
2337 inst_cream->Rd = BITS(inst, 12, 15); 2151 inst_cream->Rd = BITS(inst, 12, 15);
2338 inst_cream->shifter_operand = BITS(inst, 0, 11); 2152 inst_cream->shifter_operand = BITS(inst, 0, 11);
2339 inst_cream->shtop_func = get_shtop(inst); 2153 inst_cream->shtop_func = get_shtop(inst);
2340 2154
2341 if (inst_cream->Rd == 15) { 2155 if (inst_cream->Rd == 15) {
2342 inst_base->br = INDIRECT_BRANCH; 2156 inst_base->br = INDIRECT_BRANCH;
2343 } 2157 }
2344 return inst_base; 2158 return inst_base;
2345 2159
2346} 2160}
2347ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index) 2161ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index)
2348{ 2162{
2349 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst)); 2163 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst));
2350 orr_inst *inst_cream = (orr_inst *)inst_base->component; 2164 orr_inst *inst_cream = (orr_inst *)inst_base->component;
2351 2165
2352 inst_base->cond = BITS(inst, 28, 31); 2166 inst_base->cond = BITS(inst, 28, 31);
2353 inst_base->idx = index; 2167 inst_base->idx = index;
2354 inst_base->br = NON_BRANCH; 2168 inst_base->br = NON_BRANCH;
2355 inst_base->load_r15 = 0; 2169 inst_base->load_r15 = 0;
2356 2170
2357 inst_cream->I = BIT(inst, 25); 2171 inst_cream->I = BIT(inst, 25);
2358 inst_cream->S = BIT(inst, 20); 2172 inst_cream->S = BIT(inst, 20);
2359 inst_cream->Rd = BITS(inst, 12, 15); 2173 inst_cream->Rd = BITS(inst, 12, 15);
2360 inst_cream->Rn = BITS(inst, 16, 19); 2174 inst_cream->Rn = BITS(inst, 16, 19);
2361 inst_cream->shifter_operand = BITS(inst, 0, 11); 2175 inst_cream->shifter_operand = BITS(inst, 0, 11);
2362 inst_cream->shtop_func = get_shtop(inst); 2176 inst_cream->shtop_func = get_shtop(inst);
2363 2177
2364 if (CHECK_RN) 2178 if (CHECK_RN)
2365 inst_base->load_r15 = 1; 2179 inst_base->load_r15 = 1;
2366 if (inst_cream->Rd == 15) { 2180 if (inst_cream->Rd == 15) {
2367 inst_base->br = INDIRECT_BRANCH; 2181 inst_base->br = INDIRECT_BRANCH;
2368 } 2182 }
2369 return inst_base; 2183 return inst_base;
2370} 2184}
2371ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2185
2372ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2186ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index)
2187{
2188 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst));
2189 pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
2190
2191 inst_base->cond = BITS(inst, 28, 31);
2192 inst_base->idx = index;
2193 inst_base->br = NON_BRANCH;
2194 inst_base->load_r15 = 0;
2195
2196 inst_cream->Rd = BITS(inst, 12, 15);
2197 inst_cream->Rn = BITS(inst, 16, 19);
2198 inst_cream->Rm = BITS(inst, 0, 3);
2199 inst_cream->imm = BITS(inst, 7, 11);
2200
2201 return inst_base;
2202}
2203
2204ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index)
2205{
2206 return INTERPRETER_TRANSLATE(pkhbt)(inst, index);
2207}
2208
2373ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index) 2209ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index)
2374{ 2210{
2375 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst)); 2211 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst));
2376 2212
2377 inst_base->cond = BITS(inst, 28, 31); 2213 inst_base->cond = BITS(inst, 28, 31);
2378 inst_base->idx = index; 2214 inst_base->idx = index;
2379 inst_base->br = NON_BRANCH; 2215 inst_base->br = NON_BRANCH;
2380 inst_base->load_r15 = 0; 2216 inst_base->load_r15 = 0;
2381 2217
2382 return inst_base; 2218 return inst_base;
2383} 2219}
2384ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2220ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD"); }
2385ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2221ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index)
2386ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2222{
2387ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2223 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
2388ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2224 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
2389ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2225
2390ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2226 inst_base->cond = BITS(inst, 28, 31);
2391ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2227 inst_base->idx = index;
2392ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2228 inst_base->br = NON_BRANCH;
2393ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2229 inst_base->load_r15 = 0;
2230
2231 inst_cream->Rm = BITS(inst, 0, 3);
2232 inst_cream->Rn = BITS(inst, 16, 19);
2233 inst_cream->Rd = BITS(inst, 12, 15);
2234 inst_cream->op1 = BITS(inst, 20, 21);
2235 inst_cream->op2 = BITS(inst, 5, 7);
2236
2237 return inst_base;
2238}
2239ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index)
2240{
2241 return INTERPRETER_TRANSLATE(qadd8)(inst, index);
2242}
2243ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index)
2244{
2245 return INTERPRETER_TRANSLATE(qadd8)(inst, index);
2246}
2247ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDADD"); }
2248ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDSUB"); }
2249ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB"); }
2250ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index)
2251{
2252 return INTERPRETER_TRANSLATE(qadd8)(inst, index);
2253}
2254ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index)
2255{
2256 return INTERPRETER_TRANSLATE(qadd8)(inst, index);
2257}
2258ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index)
2259{
2260 return INTERPRETER_TRANSLATE(qadd8)(inst, index);
2261}
2394ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index) 2262ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index)
2395{ 2263{
2396 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); 2264 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
2397 rev_inst *inst_cream = (rev_inst *)inst_base->component; 2265 rev_inst *inst_cream = (rev_inst *)inst_base->component;
2398 2266
2399 inst_base->cond = BITS(inst, 28, 31); 2267 inst_base->cond = BITS(inst, 28, 31);
2400 inst_base->idx = index; 2268 inst_base->idx = index;
2401 inst_base->br = NON_BRANCH; 2269 inst_base->br = NON_BRANCH;
2402 inst_base->load_r15 = 0; 2270 inst_base->load_r15 = 0;
2403 2271
2404 inst_cream->Rm = BITS(inst, 0, 3); 2272 inst_cream->Rm = BITS(inst, 0, 3);
2405 inst_cream->Rd = BITS(inst, 12, 15); 2273 inst_cream->Rd = BITS(inst, 12, 15);
2406 2274
2407 return inst_base; 2275 return inst_base;
2408} 2276}
2409ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index){ 2277ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index){
2410 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); 2278 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
2411 rev_inst *inst_cream = (rev_inst *)inst_base->component; 2279 rev_inst *inst_cream = (rev_inst *)inst_base->component;
2412 2280
2413 inst_base->cond = BITS(inst, 28, 31); 2281 inst_base->cond = BITS(inst, 28, 31);
2414 inst_base->idx = index; 2282 inst_base->idx = index;
2415 inst_base->br = NON_BRANCH; 2283 inst_base->br = NON_BRANCH;
2416 inst_base->load_r15 = 0; 2284 inst_base->load_r15 = 0;
2417 2285
2418 inst_cream->Rm = BITS(inst, 0, 3); 2286 inst_cream->Rm = BITS(inst, 0, 3);
2419 inst_cream->Rd = BITS(inst, 12, 15); 2287 inst_cream->Rd = BITS(inst, 12, 15);
2420 2288
2421 return inst_base; 2289 return inst_base;
2422} 2290}
2423ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2291ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("REVSH"); }
2424ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2292ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("RFE"); }
2425ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index) 2293ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index)
2426{ 2294{
2427 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst)); 2295 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst));
2428 rsb_inst *inst_cream = (rsb_inst *)inst_base->component; 2296 rsb_inst *inst_cream = (rsb_inst *)inst_base->component;
2429 2297
2430 inst_base->cond = BITS(inst, 28, 31); 2298 inst_base->cond = BITS(inst, 28, 31);
2431 inst_base->idx = index; 2299 inst_base->idx = index;
2432 inst_base->br = NON_BRANCH; 2300 inst_base->br = NON_BRANCH;
2433 inst_base->load_r15 = 0; 2301 inst_base->load_r15 = 0;
2434 2302
2435 inst_cream->I = BIT(inst, 25); 2303 inst_cream->I = BIT(inst, 25);
2436 inst_cream->S = BIT(inst, 20); 2304 inst_cream->S = BIT(inst, 20);
2437 inst_cream->Rn = BITS(inst, 16, 19); 2305 inst_cream->Rn = BITS(inst, 16, 19);
2438 inst_cream->Rd = BITS(inst, 12, 15); 2306 inst_cream->Rd = BITS(inst, 12, 15);
2439 inst_cream->shifter_operand = BITS(inst, 0, 11); 2307 inst_cream->shifter_operand = BITS(inst, 0, 11);
2440 inst_cream->shtop_func = get_shtop(inst); 2308 inst_cream->shtop_func = get_shtop(inst);
2441 if (CHECK_RN) 2309 if (CHECK_RN)
2442 inst_base->load_r15 = 1; 2310 inst_base->load_r15 = 1;
2443 2311
2444 if (inst_cream->Rd == 15) { 2312 if (inst_cream->Rd == 15) {
2445 inst_base->br = INDIRECT_BRANCH; 2313 inst_base->br = INDIRECT_BRANCH;
2446 } 2314 }
2447 return inst_base; 2315 return inst_base;
2448} 2316}
2449ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index) 2317ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index)
2450{ 2318{
2451 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst)); 2319 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst));
2452 rsc_inst *inst_cream = (rsc_inst *)inst_base->component; 2320 rsc_inst *inst_cream = (rsc_inst *)inst_base->component;
2453 2321
2454 inst_base->cond = BITS(inst, 28, 31); 2322 inst_base->cond = BITS(inst, 28, 31);
2455 inst_base->idx = index; 2323 inst_base->idx = index;
2456 inst_base->br = NON_BRANCH; 2324 inst_base->br = NON_BRANCH;
2457 inst_base->load_r15 = 0; 2325 inst_base->load_r15 = 0;
2458 2326
2459 inst_cream->I = BIT(inst, 25); 2327 inst_cream->I = BIT(inst, 25);
2460 inst_cream->S = BIT(inst, 20); 2328 inst_cream->S = BIT(inst, 20);
2461 inst_cream->Rn = BITS(inst, 16, 19); 2329 inst_cream->Rn = BITS(inst, 16, 19);
2462 inst_cream->Rd = BITS(inst, 12, 15); 2330 inst_cream->Rd = BITS(inst, 12, 15);
2463 inst_cream->shifter_operand = BITS(inst, 0, 11); 2331 inst_cream->shifter_operand = BITS(inst, 0, 11);
2464 inst_cream->shtop_func = get_shtop(inst); 2332 inst_cream->shtop_func = get_shtop(inst);
2465 if (CHECK_RN) 2333 if (CHECK_RN)
2466 inst_base->load_r15 = 1; 2334 inst_base->load_r15 = 1;
2467 2335
2468 if (inst_cream->Rd == 15) { 2336 if (inst_cream->Rd == 15) {
2469 inst_base->br = INDIRECT_BRANCH; 2337 inst_base->br = INDIRECT_BRANCH;
2470 } 2338 }
2471 return inst_base; 2339 return inst_base;
2472} 2340}
2473ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2341ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SADD8"); }
2474ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2342ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index)
2475ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2343{
2344 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
2345 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
2346
2347 inst_base->cond = BITS(inst, 28, 31);
2348 inst_base->idx = index;
2349 inst_base->br = NON_BRANCH;
2350 inst_base->load_r15 = 0;
2351
2352 inst_cream->Rm = BITS(inst, 0, 3);
2353 inst_cream->Rn = BITS(inst, 16, 19);
2354 inst_cream->Rd = BITS(inst, 12, 15);
2355 inst_cream->op1 = BITS(inst, 20, 21);
2356 inst_cream->op2 = BITS(inst, 5, 7);
2357
2358 return inst_base;
2359}
2360ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index)
2361{
2362 return INTERPRETER_TRANSLATE(sadd16)(inst, index);
2363}
2476ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index) 2364ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index)
2477{ 2365{
2478 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst)); 2366 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst));
2479 sbc_inst *inst_cream = (sbc_inst *)inst_base->component; 2367 sbc_inst *inst_cream = (sbc_inst *)inst_base->component;
2480 2368
2481 inst_base->cond = BITS(inst, 28, 31); 2369 inst_base->cond = BITS(inst, 28, 31);
2482 inst_base->idx = index; 2370 inst_base->idx = index;
2483 inst_base->br = NON_BRANCH; 2371 inst_base->br = NON_BRANCH;
2484 inst_base->load_r15 = 0; 2372 inst_base->load_r15 = 0;
2485 2373
2486 inst_cream->I = BIT(inst, 25); 2374 inst_cream->I = BIT(inst, 25);
2487 inst_cream->S = BIT(inst, 20); 2375 inst_cream->S = BIT(inst, 20);
2488 inst_cream->Rn = BITS(inst, 16, 19); 2376 inst_cream->Rn = BITS(inst, 16, 19);
2489 inst_cream->Rd = BITS(inst, 12, 15); 2377 inst_cream->Rd = BITS(inst, 12, 15);
2490 inst_cream->shifter_operand = BITS(inst, 0, 11); 2378 inst_cream->shifter_operand = BITS(inst, 0, 11);
2491 inst_cream->shtop_func = get_shtop(inst); 2379 inst_cream->shtop_func = get_shtop(inst);
2492 if (CHECK_RN) 2380 if (CHECK_RN)
2493 inst_base->load_r15 = 1; 2381 inst_base->load_r15 = 1;
2494 2382
2495 if (inst_cream->Rd == 15) { 2383 if (inst_cream->Rd == 15) {
2496 inst_base->br = INDIRECT_BRANCH; 2384 inst_base->br = INDIRECT_BRANCH;
2497 } 2385 }
2498 return inst_base; 2386 return inst_base;
2499} 2387}
2500ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2388ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index)
2501ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2389{
2502ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2390 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
2503ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2391 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
2504ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2392
2505ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2393 inst_base->cond = BITS(inst, 28, 31);
2506ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2394 inst_base->idx = index;
2507ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2395 inst_base->br = NON_BRANCH;
2396 inst_base->load_r15 = 0;
2397
2398 inst_cream->Rm = BITS(inst, 0, 3);
2399 inst_cream->Rn = BITS(inst, 16, 19);
2400 inst_cream->Rd = BITS(inst, 12, 15);
2401 inst_cream->op1 = BITS(inst, 20, 22);
2402 inst_cream->op2 = BITS(inst, 5, 7);
2403
2404 return inst_base;
2405}
2406ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SETEND"); }
2407ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADD16"); }
2408ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADD8"); }
2409ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADDSUBX"); }
2410ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUB16"); }
2411ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUB8"); }
2412ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUBADDX"); }
2508ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index) 2413ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index)
2509{ 2414{
2510 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst)); 2415 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst));
2511 smla_inst *inst_cream = (smla_inst *)inst_base->component; 2416 smla_inst *inst_cream = (smla_inst *)inst_base->component;
2512 2417
2513 inst_base->cond = BITS(inst, 28, 31); 2418 inst_base->cond = BITS(inst, 28, 31);
2514 inst_base->idx = index; 2419 inst_base->idx = index;
2515 inst_base->br = NON_BRANCH; 2420 inst_base->br = NON_BRANCH;
2516 inst_base->load_r15 = 0; 2421 inst_base->load_r15 = 0;
2517 2422
2518 inst_cream->x = BIT(inst, 5); 2423 inst_cream->x = BIT(inst, 5);
2519 inst_cream->y = BIT(inst, 6); 2424 inst_cream->y = BIT(inst, 6);
2520 inst_cream->Rm = BITS(inst, 0, 3); 2425 inst_cream->Rm = BITS(inst, 0, 3);
2521 inst_cream->Rs = BITS(inst, 8, 11); 2426 inst_cream->Rs = BITS(inst, 8, 11);
2522 inst_cream->Rd = BITS(inst, 16, 19); 2427 inst_cream->Rd = BITS(inst, 16, 19);
2523 inst_cream->Rn = BITS(inst, 12, 15); 2428 inst_cream->Rn = BITS(inst, 12, 15);
2524 2429
2525 return inst_base; 2430 return inst_base;
2526} 2431}
2527ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index){ 2432ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index){
2528 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); 2433 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
2529 smlad_inst *inst_cream = (smlad_inst *)inst_base->component; 2434 smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
2530 2435
2531 inst_base->cond = BITS(inst, 28, 31); 2436 inst_base->cond = BITS(inst, 28, 31);
2532 inst_base->idx = index; 2437 inst_base->idx = index;
2533 inst_base->br = NON_BRANCH; 2438 inst_base->br = NON_BRANCH;
2534 inst_base->load_r15 = 0; 2439 inst_base->load_r15 = 0;
2535 2440
2536 inst_cream->m = BIT(inst, 4); 2441 inst_cream->m = BIT(inst, 4);
2537 inst_cream->Rn = BITS(inst, 0, 3); 2442 inst_cream->Rn = BITS(inst, 0, 3);
2538 inst_cream->Rm = BITS(inst, 8, 11); 2443 inst_cream->Rm = BITS(inst, 8, 11);
2539 inst_cream->Rd = BITS(inst, 16, 19); 2444 inst_cream->Rd = BITS(inst, 16, 19);
2540 inst_cream->Ra = BITS(inst, 12, 15); 2445 inst_cream->Ra = BITS(inst, 12, 15);
2541 2446
2542 if (CHECK_RM ) 2447 if (CHECK_RM )
2543 inst_base->load_r15 = 1; 2448 inst_base->load_r15 = 1;
2544 return inst_base; 2449 return inst_base;
2545} 2450}
2546ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index) 2451ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index)
2547{ 2452{
2548 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); 2453 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
2549 umlal_inst *inst_cream = (umlal_inst *)inst_base->component; 2454 umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
2550 2455
2551 inst_base->cond = BITS(inst, 28, 31); 2456 inst_base->cond = BITS(inst, 28, 31);
2552 inst_base->idx = index; 2457 inst_base->idx = index;
2553 inst_base->br = NON_BRANCH; 2458 inst_base->br = NON_BRANCH;
2554 inst_base->load_r15 = 0; 2459 inst_base->load_r15 = 0;
2555 2460
2556 inst_cream->S = BIT(inst, 20); 2461 inst_cream->S = BIT(inst, 20);
2557 inst_cream->Rm = BITS(inst, 0, 3); 2462 inst_cream->Rm = BITS(inst, 0, 3);
2558 inst_cream->Rs = BITS(inst, 8, 11); 2463 inst_cream->Rs = BITS(inst, 8, 11);
2559 inst_cream->RdHi = BITS(inst, 16, 19); 2464 inst_cream->RdHi = BITS(inst, 16, 19);
2560 inst_cream->RdLo = BITS(inst, 12, 15); 2465 inst_cream->RdLo = BITS(inst, 12, 15);
2561 2466
2562 if (CHECK_RM || CHECK_RS) 2467 if (CHECK_RM || CHECK_RS)
2563 inst_base->load_r15 = 1; 2468 inst_base->load_r15 = 1;
2564 return inst_base; 2469 return inst_base;
2565} 2470}
2566ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2471ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALXY"); }
2567ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2472ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALD"); }
2568ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2473ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLAW"); }
2569ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2474ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLSD"); }
2570ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2475ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLSLD"); }
2571ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2476ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMMLA"); }
2572ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2477ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMMLS"); }
2573ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2478ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMMUL"); }
2574ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2479ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUAD"); }
2575ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index) 2480ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index)
2576{ 2481{
2577 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst)); 2482 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst));
2578 smul_inst *inst_cream = (smul_inst *)inst_base->component; 2483 smul_inst *inst_cream = (smul_inst *)inst_base->component;
2579 2484
2580 inst_base->cond = BITS(inst, 28, 31); 2485 inst_base->cond = BITS(inst, 28, 31);
2581 inst_base->idx = index; 2486 inst_base->idx = index;
2582 inst_base->br = NON_BRANCH; 2487 inst_base->br = NON_BRANCH;
2583 inst_base->load_r15 = 0; 2488 inst_base->load_r15 = 0;
2584 2489
2585 inst_cream->Rd = BITS(inst, 16, 19); 2490 inst_cream->Rd = BITS(inst, 16, 19);
2586 inst_cream->Rs = BITS(inst, 8, 11); 2491 inst_cream->Rs = BITS(inst, 8, 11);
2587 inst_cream->Rm = BITS(inst, 0, 3); 2492 inst_cream->Rm = BITS(inst, 0, 3);
2588 2493
2589 inst_cream->x = BIT(inst, 5); 2494 inst_cream->x = BIT(inst, 5);
2590 inst_cream->y = BIT(inst, 6); 2495 inst_cream->y = BIT(inst, 6);
2591 2496
2592 if (CHECK_RM || CHECK_RS) 2497 if (CHECK_RM || CHECK_RS)
2593 inst_base->load_r15 = 1; 2498 inst_base->load_r15 = 1;
2594 return inst_base; 2499 return inst_base;
2595 2500
2596} 2501}
2597ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index) 2502ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index)
2598{ 2503{
2599 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); 2504 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
2600 umull_inst *inst_cream = (umull_inst *)inst_base->component; 2505 umull_inst *inst_cream = (umull_inst *)inst_base->component;
2601 2506
2602 inst_base->cond = BITS(inst, 28, 31); 2507 inst_base->cond = BITS(inst, 28, 31);
2603 inst_base->idx = index; 2508 inst_base->idx = index;
2604 inst_base->br = NON_BRANCH; 2509 inst_base->br = NON_BRANCH;
2605 inst_base->load_r15 = 0; 2510 inst_base->load_r15 = 0;
2606 2511
2607 inst_cream->S = BIT(inst, 20); 2512 inst_cream->S = BIT(inst, 20);
2608 inst_cream->Rm = BITS(inst, 0, 3); 2513 inst_cream->Rm = BITS(inst, 0, 3);
2609 inst_cream->Rs = BITS(inst, 8, 11); 2514 inst_cream->Rs = BITS(inst, 8, 11);
2610 inst_cream->RdHi = BITS(inst, 16, 19); 2515 inst_cream->RdHi = BITS(inst, 16, 19);
2611 inst_cream->RdLo = BITS(inst, 12, 15); 2516 inst_cream->RdLo = BITS(inst, 12, 15);
2612 2517
2613 if (CHECK_RM || CHECK_RS) 2518 if (CHECK_RM || CHECK_RS)
2614 inst_base->load_r15 = 1; 2519 inst_base->load_r15 = 1;
2615 return inst_base; 2520 return inst_base;
2616} 2521}
2617 2522
2618ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index) 2523ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index)
2619{ 2524{
2620 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); 2525 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
2621 smlad_inst *inst_cream = (smlad_inst *)inst_base->component; 2526 smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
2622 2527
2623 inst_base->cond = BITS(inst, 28, 31); 2528 inst_base->cond = BITS(inst, 28, 31);
2624 inst_base->idx = index; 2529 inst_base->idx = index;
2625 inst_base->br = NON_BRANCH; 2530 inst_base->br = NON_BRANCH;
2626 inst_base->load_r15 = 0; 2531 inst_base->load_r15 = 0;
2627 2532
2628 inst_cream->m = BIT(inst, 6); 2533 inst_cream->m = BIT(inst, 6);
2629 inst_cream->Rm = BITS(inst, 8, 11); 2534 inst_cream->Rm = BITS(inst, 8, 11);
2630 inst_cream->Rn = BITS(inst, 0, 3); 2535 inst_cream->Rn = BITS(inst, 0, 3);
2631 inst_cream->Rd = BITS(inst, 16, 19); 2536 inst_cream->Rd = BITS(inst, 16, 19);
2632 2537
2633 if (CHECK_RM || CHECK_RN) 2538 if (CHECK_RM || CHECK_RN)
2634 inst_base->load_r15 = 1; 2539 inst_base->load_r15 = 1;
2635 return inst_base; 2540 return inst_base;
2636} 2541}
2637ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2542ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUSD"); }
2638ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2543ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SRS"); }
2639ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2544ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index)
2640ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2545{
2641ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2546 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ssat_inst));
2642ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2547 ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
2643ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2548
2549 inst_base->cond = BITS(inst, 28, 31);
2550 inst_base->idx = index;
2551 inst_base->br = NON_BRANCH;
2552 inst_base->load_r15 = 0;
2553
2554 inst_cream->Rn = BITS(inst, 0, 3);
2555 inst_cream->Rd = BITS(inst, 12, 15);
2556 inst_cream->imm5 = BITS(inst, 7, 11);
2557 inst_cream->sat_imm = BITS(inst, 16, 20);
2558 inst_cream->shift_type = BIT(inst, 6);
2559
2560 return inst_base;
2561}
2562ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSAT16"); }
2563ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSUB8"); }
2564ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index)
2565{
2566 return INTERPRETER_TRANSLATE(sadd16)(inst, index);
2567}
2568ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index)
2569{
2570 return INTERPRETER_TRANSLATE(sadd16)(inst, index);
2571}
2644ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index) 2572ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index)
2645{ 2573{
2646 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst)); 2574 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst));
2647 inst_base->cond = BITS(inst, 28, 31); 2575 inst_base->cond = BITS(inst, 28, 31);
2648 inst_base->idx = index; 2576 inst_base->idx = index;
2649 inst_base->br = NON_BRANCH; 2577 inst_base->br = NON_BRANCH;
2650 2578
2651 return inst_base; 2579 return inst_base;
2652} 2580}
2653ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(unsigned int inst, int index) 2581ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(unsigned int inst, int index)
2654{ 2582{
2655 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 2583 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2656 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 2584 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2657 2585
2658 inst_base->cond = BITS(inst, 28, 31); 2586 inst_base->cond = BITS(inst, 28, 31);
2659 inst_base->idx = index; 2587 inst_base->idx = index;
2660 inst_base->br = NON_BRANCH; 2588 inst_base->br = NON_BRANCH;
2661 2589
2662 inst_cream->inst = inst; 2590 inst_cream->inst = inst;
2663 inst_cream->get_addr = get_calc_addr_op(inst); 2591 inst_cream->get_addr = get_calc_addr_op(inst);
2664 return inst_base; 2592 return inst_base;
2665} 2593}
2666ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index) 2594ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index)
2667{ 2595{
2668 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); 2596 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
2669 sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; 2597 sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
2670 2598
2671 inst_base->cond = BITS(inst, 28, 31); 2599 inst_base->cond = BITS(inst, 28, 31);
2672 inst_base->idx = index; 2600 inst_base->idx = index;
2673 inst_base->br = NON_BRANCH; 2601 inst_base->br = NON_BRANCH;
2674 inst_base->load_r15 = 0; 2602 inst_base->load_r15 = 0;
2675 2603
2676 inst_cream->Rd = BITS(inst, 12, 15); 2604 inst_cream->Rd = BITS(inst, 12, 15);
2677 inst_cream->Rm = BITS(inst, 0, 3); 2605 inst_cream->Rm = BITS(inst, 0, 3);
2678 inst_cream->rotate = BITS(inst, 10, 11); 2606 inst_cream->rotate = BITS(inst, 10, 11);
2679 2607
2680 if (CHECK_RM) 2608 if (CHECK_RM)
2681 inst_base->load_r15 = 1; 2609 inst_base->load_r15 = 1;
2682 return inst_base; 2610 return inst_base;
2683} 2611}
2684ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index) 2612ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index)
2685{ 2613{
2686 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 2614 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2687 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 2615 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2688 2616
2689 inst_base->cond = BITS(inst, 28, 31); 2617 inst_base->cond = BITS(inst, 28, 31);
2690 inst_base->idx = index; 2618 inst_base->idx = index;
2691 inst_base->br = NON_BRANCH; 2619 inst_base->br = NON_BRANCH;
2692 2620
2693 inst_cream->inst = inst; 2621 inst_cream->inst = inst;
2694 inst_cream->get_addr = get_calc_addr_op(inst); 2622 inst_cream->get_addr = get_calc_addr_op(inst);
2695 2623
2696 if (BITS(inst, 12, 15) == 15) { 2624 if (BITS(inst, 12, 15) == 15) {
2697 inst_base->br = INDIRECT_BRANCH; 2625 inst_base->br = INDIRECT_BRANCH;
2698 } 2626 }
2699 return inst_base; 2627 return inst_base;
2700} 2628}
2701ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index) 2629ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index)
2702{ 2630{
2703 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); 2631 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
2704 uxth_inst *inst_cream = (uxth_inst *)inst_base->component; 2632 uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
2705 2633
2706 inst_base->cond = BITS(inst, 28, 31); 2634 inst_base->cond = BITS(inst, 28, 31);
2707 inst_base->idx = index; 2635 inst_base->idx = index;
2708 inst_base->br = NON_BRANCH; 2636 inst_base->br = NON_BRANCH;
2709 inst_base->load_r15 = 0; 2637 inst_base->load_r15 = 0;
2710 2638
2711 inst_cream->Rd = BITS(inst, 12, 15); 2639 inst_cream->Rd = BITS(inst, 12, 15);
2712 inst_cream->rotate = BITS(inst, 10, 11); 2640 inst_cream->rotate = BITS(inst, 10, 11);
2713 inst_cream->Rm = BITS(inst, 0, 3); 2641 inst_cream->Rm = BITS(inst, 0, 3);
2714 2642
2715 if (CHECK_RM) 2643 if (CHECK_RM)
2716 inst_base->load_r15 = 1; 2644 inst_base->load_r15 = 1;
2717 return inst_base; 2645 return inst_base;
2718} 2646}
2719ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index) 2647ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index)
2720{ 2648{
2721 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst)); 2649 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
2722 uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component; 2650 uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component;
2723 2651
2724 inst_base->cond = BITS(inst, 28, 31); 2652 inst_base->cond = BITS(inst, 28, 31);
2725 inst_base->idx = index; 2653 inst_base->idx = index;
2726 inst_base->br = NON_BRANCH; 2654 inst_base->br = NON_BRANCH;
2727 inst_base->load_r15 = 0; 2655 inst_base->load_r15 = 0;
2728 2656
2729 inst_cream->Rd = BITS(inst, 12, 15); 2657 inst_cream->Rd = BITS(inst, 12, 15);
2730 inst_cream->rotate = BITS(inst, 10, 11); 2658 inst_cream->rotate = BITS(inst, 10, 11);
2731 inst_cream->Rm = BITS(inst, 0, 3); 2659 inst_cream->Rm = BITS(inst, 0, 3);
2732 inst_cream->Rn = BITS(inst, 16, 19); 2660 inst_cream->Rn = BITS(inst, 16, 19);
2733 2661
2734 return inst_base; 2662 return inst_base;
2735} 2663}
2736ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index) 2664ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index)
2737{ 2665{
2738 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 2666 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2739 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 2667 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2740 2668
2741 inst_base->cond = BITS(inst, 28, 31); 2669 inst_base->cond = BITS(inst, 28, 31);
2742 inst_base->idx = index; 2670 inst_base->idx = index;
2743 inst_base->br = NON_BRANCH; 2671 inst_base->br = NON_BRANCH;
2744 2672
2745 inst_cream->inst = inst; 2673 inst_cream->inst = inst;
2746 inst_cream->get_addr = get_calc_addr_op(inst); 2674 inst_cream->get_addr = get_calc_addr_op(inst);
2747 2675
2748 if (BITS(inst, 12, 15) == 15) { 2676 if (BITS(inst, 12, 15) == 15) {
2749 inst_base->br = INDIRECT_BRANCH; 2677 inst_base->br = INDIRECT_BRANCH;
2750 } 2678 }
2751 return inst_base; 2679 return inst_base;
2752} 2680}
2753ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index) 2681ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index)
2754{ 2682{
2755 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 2683 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2756 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 2684 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2757 2685
2758 inst_base->cond = BITS(inst, 28, 31); 2686 inst_base->cond = BITS(inst, 28, 31);
2759 inst_base->idx = index; 2687 inst_base->idx = index;
2760 inst_base->br = NON_BRANCH; 2688 inst_base->br = NON_BRANCH;
2761 2689
2762 inst_cream->inst = inst; 2690 inst_cream->inst = inst;
2763// inst_cream->get_addr = get_calc_addr_op(inst); 2691// inst_cream->get_addr = get_calc_addr_op(inst);
2764 if (I_BIT == 0) { 2692 if (I_BIT == 0) {
2765 inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); 2693 inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
2766 } else { 2694 } else {
2767 DEBUG_MSG; 2695 DEBUG_MSG;
2768 } 2696 }
2769 2697
2770 if (BITS(inst, 12, 15) == 15) { 2698 if (BITS(inst, 12, 15) == 15) {
2771 inst_base->br = INDIRECT_BRANCH; 2699 inst_base->br = INDIRECT_BRANCH;
2772 } 2700 }
2773 return inst_base; 2701 return inst_base;
2774} 2702}
2775ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){ 2703ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){
2776 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 2704 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2777 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 2705 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2778 2706
2779 inst_base->cond = BITS(inst, 28, 31); 2707 inst_base->cond = BITS(inst, 28, 31);
2780 inst_base->idx = index; 2708 inst_base->idx = index;
2781 inst_base->br = NON_BRANCH; 2709 inst_base->br = NON_BRANCH;
2782 2710
2783 inst_cream->inst = inst; 2711 inst_cream->inst = inst;
2784 inst_cream->get_addr = get_calc_addr_op(inst); 2712 inst_cream->get_addr = get_calc_addr_op(inst);
2785 2713
2786 if (BITS(inst, 12, 15) == 15) { 2714 if (BITS(inst, 12, 15) == 15) {
2787 inst_base->br = INDIRECT_BRANCH; 2715 inst_base->br = INDIRECT_BRANCH;
2788 } 2716 }
2789 return inst_base; 2717 return inst_base;
2790} 2718}
2791ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index) 2719ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index)
2792{ 2720{
2793 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 2721 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2794 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 2722 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2795 2723
2796 inst_base->cond = BITS(inst, 28, 31); 2724 inst_base->cond = BITS(inst, 28, 31);
2797 inst_base->idx = index; 2725 inst_base->idx = index;
2798 inst_base->br = NON_BRANCH; 2726 inst_base->br = NON_BRANCH;
2799 2727
2800 inst_cream->inst = inst; 2728 inst_cream->inst = inst;
2801 inst_cream->get_addr = get_calc_addr_op(inst); 2729 inst_cream->get_addr = get_calc_addr_op(inst);
2802 2730
2803 if (BITS(inst, 12, 15) == 15) { 2731 if (BITS(inst, 12, 15) == 15) {
2804 inst_base->br = INDIRECT_BRANCH; 2732 inst_base->br = INDIRECT_BRANCH;
2805 } 2733 }
2806 return inst_base; 2734 return inst_base;
2807} 2735}
2808ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index) 2736ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index)
2809{ 2737{
2810 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 2738 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2811 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 2739 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2812 2740
2813 inst_base->cond = BITS(inst, 28, 31); 2741 inst_base->cond = BITS(inst, 28, 31);
2814 inst_base->idx = index; 2742 inst_base->idx = index;
2815 inst_base->br = NON_BRANCH; 2743 inst_base->br = NON_BRANCH;
2816 2744
2817 inst_cream->inst = inst; 2745 inst_cream->inst = inst;
2818 inst_cream->get_addr = get_calc_addr_op(inst); 2746 inst_cream->get_addr = get_calc_addr_op(inst);
2819 2747
2820 if (BITS(inst, 12, 15) == 15) { 2748 if (BITS(inst, 12, 15) == 15) {
2821 inst_base->br = INDIRECT_BRANCH; 2749 inst_base->br = INDIRECT_BRANCH;
2822 } 2750 }
2823 return inst_base; 2751 return inst_base;
2824} 2752}
2825ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index) 2753ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index)
2826{ 2754{
2827 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 2755 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2828 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 2756 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2829 2757
2830 inst_base->cond = BITS(inst, 28, 31); 2758 inst_base->cond = BITS(inst, 28, 31);
2831 inst_base->idx = index; 2759 inst_base->idx = index;
2832 inst_base->br = NON_BRANCH; 2760 inst_base->br = NON_BRANCH;
2833 2761
2834 inst_cream->inst = inst; 2762 inst_cream->inst = inst;
2835 inst_cream->get_addr = get_calc_addr_op(inst); 2763 inst_cream->get_addr = get_calc_addr_op(inst);
2836 2764
2837 if (BITS(inst, 12, 15) == 15) { 2765 if (BITS(inst, 12, 15) == 15) {
2838 inst_base->br = INDIRECT_BRANCH; 2766 inst_base->br = INDIRECT_BRANCH;
2839 } 2767 }
2840 return inst_base; 2768 return inst_base;
2841} 2769}
2842ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index) 2770ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index)
2843{ 2771{
2844 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 2772 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2845 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 2773 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2846 2774
2847 inst_base->cond = BITS(inst, 28, 31); 2775 inst_base->cond = BITS(inst, 28, 31);
2848 inst_base->idx = index; 2776 inst_base->idx = index;
2849 inst_base->br = NON_BRANCH; 2777 inst_base->br = NON_BRANCH;
2850 2778
2851 inst_cream->inst = inst; 2779 inst_cream->inst = inst;
2852 if (I_BIT == 0) { 2780 if (I_BIT == 0) {
2853 inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); 2781 inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
2854 } else { 2782 } else {
2855 DEBUG_MSG; 2783 DEBUG_MSG;
2856 } 2784 }
2857 2785
2858 if (BITS(inst, 12, 15) == 15) { 2786 if (BITS(inst, 12, 15) == 15) {
2859 inst_base->br = INDIRECT_BRANCH; 2787 inst_base->br = INDIRECT_BRANCH;
2860 } 2788 }
2861 return inst_base; 2789 return inst_base;
2862} 2790}
2863ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index) 2791ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index)
2864{ 2792{
2865 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst)); 2793 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst));
2866 sub_inst *inst_cream = (sub_inst *)inst_base->component; 2794 sub_inst *inst_cream = (sub_inst *)inst_base->component;
2867 2795
2868 inst_base->cond = BITS(inst, 28, 31); 2796 inst_base->cond = BITS(inst, 28, 31);
2869 inst_base->idx = index; 2797 inst_base->idx = index;
2870 inst_base->br = NON_BRANCH; 2798 inst_base->br = NON_BRANCH;
2871 inst_base->load_r15 = 0; 2799 inst_base->load_r15 = 0;
2872 2800
2873 inst_cream->I = BIT(inst, 25); 2801 inst_cream->I = BIT(inst, 25);
2874 inst_cream->S = BIT(inst, 20); 2802 inst_cream->S = BIT(inst, 20);
2875 inst_cream->Rn = BITS(inst, 16, 19); 2803 inst_cream->Rn = BITS(inst, 16, 19);
2876 inst_cream->Rd = BITS(inst, 12, 15); 2804 inst_cream->Rd = BITS(inst, 12, 15);
2877 inst_cream->shifter_operand = BITS(inst, 0, 11); 2805 inst_cream->shifter_operand = BITS(inst, 0, 11);
2878 inst_cream->shtop_func = get_shtop(inst); 2806 inst_cream->shtop_func = get_shtop(inst);
2879 if (inst_cream->Rd == 15) { 2807 if (inst_cream->Rd == 15) {
2880 inst_base->br = INDIRECT_BRANCH; 2808 inst_base->br = INDIRECT_BRANCH;
2881 } 2809 }
2882 if (CHECK_RN) 2810 if (CHECK_RN)
2883 inst_base->load_r15 = 1; 2811 inst_base->load_r15 = 1;
2884 2812
2885 return inst_base; 2813 return inst_base;
2886} 2814}
2887ARM_INST_PTR INTERPRETER_TRANSLATE(swi)(unsigned int inst, int index) 2815ARM_INST_PTR INTERPRETER_TRANSLATE(swi)(unsigned int inst, int index)
2888{ 2816{
2889 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst)); 2817 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst));
2890 swi_inst *inst_cream = (swi_inst *)inst_base->component; 2818 swi_inst *inst_cream = (swi_inst *)inst_base->component;
2891 2819
2892 inst_base->cond = BITS(inst, 28, 31); 2820 inst_base->cond = BITS(inst, 28, 31);
2893 inst_base->idx = index; 2821 inst_base->idx = index;
2894 inst_base->br = NON_BRANCH; 2822 inst_base->br = NON_BRANCH;
2895 2823
2896 inst_cream->num = BITS(inst, 0, 23); 2824 inst_cream->num = BITS(inst, 0, 23);
2897 return inst_base; 2825 return inst_base;
2898} 2826}
2899ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index) 2827ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index)
2900{ 2828{
2901 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); 2829 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
2902 swp_inst *inst_cream = (swp_inst *)inst_base->component; 2830 swp_inst *inst_cream = (swp_inst *)inst_base->component;
2903 2831
2904 inst_base->cond = BITS(inst, 28, 31); 2832 inst_base->cond = BITS(inst, 28, 31);
2905 inst_base->idx = index; 2833 inst_base->idx = index;
2906 inst_base->br = NON_BRANCH; 2834 inst_base->br = NON_BRANCH;
2907 2835
2908 inst_cream->Rn = BITS(inst, 16, 19); 2836 inst_cream->Rn = BITS(inst, 16, 19);
2909 inst_cream->Rd = BITS(inst, 12, 15); 2837 inst_cream->Rd = BITS(inst, 12, 15);
2910 inst_cream->Rm = BITS(inst, 0, 3); 2838 inst_cream->Rm = BITS(inst, 0, 3);
2911 2839
2912 if (inst_cream->Rd == 15) { 2840 if (inst_cream->Rd == 15) {
2913 inst_base->br = INDIRECT_BRANCH; 2841 inst_base->br = INDIRECT_BRANCH;
2914 } 2842 }
2915 return inst_base; 2843 return inst_base;
2916} 2844}
2917ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){ 2845ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){
2918 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); 2846 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
2919 swp_inst *inst_cream = (swp_inst *)inst_base->component; 2847 swp_inst *inst_cream = (swp_inst *)inst_base->component;
2920 2848
2921 inst_base->cond = BITS(inst, 28, 31); 2849 inst_base->cond = BITS(inst, 28, 31);
2922 inst_base->idx = index; 2850 inst_base->idx = index;
2923 inst_base->br = NON_BRANCH; 2851 inst_base->br = NON_BRANCH;
2924 2852
2925 inst_cream->Rn = BITS(inst, 16, 19); 2853 inst_cream->Rn = BITS(inst, 16, 19);
2926 inst_cream->Rd = BITS(inst, 12, 15); 2854 inst_cream->Rd = BITS(inst, 12, 15);
2927 inst_cream->Rm = BITS(inst, 0, 3); 2855 inst_cream->Rm = BITS(inst, 0, 3);
2928 2856
2929 if (inst_cream->Rd == 15) { 2857 if (inst_cream->Rd == 15) {
2930 inst_base->br = INDIRECT_BRANCH; 2858 inst_base->br = INDIRECT_BRANCH;
2931 } 2859 }
2932 return inst_base; 2860 return inst_base;
2933} 2861}
2934ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){ 2862ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){
2935 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst)); 2863 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst));
2936 sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component; 2864 sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component;
2937 2865
2938 inst_base->cond = BITS(inst, 28, 31); 2866 inst_base->cond = BITS(inst, 28, 31);
2939 inst_base->idx = index; 2867 inst_base->idx = index;
2940 inst_base->br = NON_BRANCH; 2868 inst_base->br = NON_BRANCH;
2941 inst_base->load_r15 = 0; 2869 inst_base->load_r15 = 0;
2942 2870
2943 inst_cream->Rd = BITS(inst, 12, 15); 2871 inst_cream->Rd = BITS(inst, 12, 15);
2944 inst_cream->rotate = BITS(inst, 10, 11); 2872 inst_cream->rotate = BITS(inst, 10, 11);
2945 inst_cream->Rm = BITS(inst, 0, 3); 2873 inst_cream->Rm = BITS(inst, 0, 3);
2946 inst_cream->Rn = BITS(inst, 16, 19); 2874 inst_cream->Rn = BITS(inst, 16, 19);
2947 2875
2948 return inst_base; 2876 return inst_base;
2949} 2877}
2950ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2878ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SXTAB16"); }
2951ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index){ 2879ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index){
2952 DEBUG_LOG(ARM11, "in func %s, SXTAH untested\n", __func__); 2880 LOG_WARNING(Core_ARM11, "SXTAH untested");
2953 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst)); 2881 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst));
2954 sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component; 2882 sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
2955 2883
2956 inst_base->cond = BITS(inst, 28, 31); 2884 inst_base->cond = BITS(inst, 28, 31);
2957 inst_base->idx = index; 2885 inst_base->idx = index;
2958 inst_base->br = NON_BRANCH; 2886 inst_base->br = NON_BRANCH;
2959 inst_base->load_r15 = 0; 2887 inst_base->load_r15 = 0;
2960 2888
2961 inst_cream->Rd = BITS(inst, 12, 15); 2889 inst_cream->Rd = BITS(inst, 12, 15);
2962 inst_cream->rotate = BITS(inst, 10, 11); 2890 inst_cream->rotate = BITS(inst, 10, 11);
2963 inst_cream->Rm = BITS(inst, 0, 3); 2891 inst_cream->Rm = BITS(inst, 0, 3);
2964 inst_cream->Rn = BITS(inst, 16, 19); 2892 inst_cream->Rn = BITS(inst, 16, 19);
2965 2893
2966 return inst_base; 2894 return inst_base;
2967} 2895}
2968ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2896ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SXTB16"); }
2969ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index) 2897ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index)
2970{ 2898{
2971 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst)); 2899 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst));
2972 teq_inst *inst_cream = (teq_inst *)inst_base->component; 2900 teq_inst *inst_cream = (teq_inst *)inst_base->component;
2973 2901
2974 inst_base->cond = BITS(inst, 28, 31); 2902 inst_base->cond = BITS(inst, 28, 31);
2975 inst_base->idx = index; 2903 inst_base->idx = index;
2976 inst_base->br = NON_BRANCH; 2904 inst_base->br = NON_BRANCH;
2977 inst_base->load_r15 = 0; 2905 inst_base->load_r15 = 0;
2978 2906
2979 inst_cream->I = BIT(inst, 25); 2907 inst_cream->I = BIT(inst, 25);
2980 inst_cream->Rn = BITS(inst, 16, 19); 2908 inst_cream->Rn = BITS(inst, 16, 19);
2981 inst_cream->shifter_operand = BITS(inst, 0, 11); 2909 inst_cream->shifter_operand = BITS(inst, 0, 11);
2982 inst_cream->shtop_func = get_shtop(inst); 2910 inst_cream->shtop_func = get_shtop(inst);
2983 2911
2984 if (CHECK_RN) 2912 if (CHECK_RN)
2985 inst_base->load_r15 = 1; 2913 inst_base->load_r15 = 1;
2986 return inst_base; 2914 return inst_base;
2987} 2915}
2988ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index) 2916ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index)
2989{ 2917{
2990 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst)); 2918 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst));
2991 tst_inst *inst_cream = (tst_inst *)inst_base->component; 2919 tst_inst *inst_cream = (tst_inst *)inst_base->component;
2992 2920
2993 inst_base->cond = BITS(inst, 28, 31); 2921 inst_base->cond = BITS(inst, 28, 31);
2994 inst_base->idx = index; 2922 inst_base->idx = index;
2995 inst_base->br = NON_BRANCH; 2923 inst_base->br = NON_BRANCH;
2996 inst_base->load_r15 = 0; 2924 inst_base->load_r15 = 0;
2997 2925
2998 inst_cream->I = BIT(inst, 25); 2926 inst_cream->I = BIT(inst, 25);
2999 inst_cream->S = BIT(inst, 20); 2927 inst_cream->S = BIT(inst, 20);
3000 inst_cream->Rn = BITS(inst, 16, 19); 2928 inst_cream->Rn = BITS(inst, 16, 19);
3001 inst_cream->Rd = BITS(inst, 12, 15); 2929 inst_cream->Rd = BITS(inst, 12, 15);
3002 inst_cream->shifter_operand = BITS(inst, 0, 11); 2930 inst_cream->shifter_operand = BITS(inst, 0, 11);
3003 inst_cream->shtop_func = get_shtop(inst); 2931 inst_cream->shtop_func = get_shtop(inst);
3004 if (inst_cream->Rd == 15) { 2932 if (inst_cream->Rd == 15) {
3005 inst_base->br = INDIRECT_BRANCH; 2933 inst_base->br = INDIRECT_BRANCH;
3006 } 2934 }
3007 2935
3008 if (CHECK_RN) 2936 if (CHECK_RN)
3009 inst_base->load_r15 = 1; 2937 inst_base->load_r15 = 1;
3010 return inst_base; 2938 return inst_base;
3011} 2939}
3012ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2940ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD8"); }
3013ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2941ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); }
3014ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2942ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADDSUBX"); }
3015ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2943ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index)
3016ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2944{
3017ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2945 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
3018ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2946 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
3019ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2947
3020ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2948 inst_base->cond = BITS(inst, 28, 31);
3021ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 2949 inst_base->idx = index;
2950 inst_base->br = NON_BRANCH;
2951 inst_base->load_r15 = 0;
2952
2953 inst_cream->op1 = BITS(inst, 20, 21);
2954 inst_cream->op2 = BITS(inst, 5, 7);
2955 inst_cream->Rm = BITS(inst, 0, 3);
2956 inst_cream->Rn = BITS(inst, 16, 19);
2957 inst_cream->Rd = BITS(inst, 12, 15);
2958
2959 return inst_base;
2960}
2961ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index)
2962{
2963 return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
2964}
2965ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index)
2966{
2967 return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
2968}
2969ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index)
2970{
2971 return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
2972}
2973ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index)
2974{
2975 return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
2976}
2977ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index)
2978{
2979 return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
2980}
2981ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index)
2982{
2983 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umaal_inst));
2984 umaal_inst* const inst_cream = (umaal_inst*)inst_base->component;
2985
2986 inst_base->cond = BITS(inst, 28, 31);
2987 inst_base->idx = index;
2988 inst_base->br = NON_BRANCH;
2989 inst_base->load_r15 = 0;
2990
2991 inst_cream->Rm = BITS(inst, 8, 11);
2992 inst_cream->Rn = BITS(inst, 0, 3);
2993 inst_cream->RdLo = BITS(inst, 12, 15);
2994 inst_cream->RdHi = BITS(inst, 16, 19);
2995
2996 if (CHECK_RM || CHECK_RN)
2997 inst_base->load_r15 = 1;
2998
2999 return inst_base;
3000}
3022ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index) 3001ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index)
3023{ 3002{
3024 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); 3003 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
3025 umlal_inst *inst_cream = (umlal_inst *)inst_base->component; 3004 umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
3005
3006 inst_base->cond = BITS(inst, 28, 31);
3007 inst_base->idx = index;
3008 inst_base->br = NON_BRANCH;
3009 inst_base->load_r15 = 0;
3026 3010
3027 inst_base->cond = BITS(inst, 28, 31); 3011 inst_cream->S = BIT(inst, 20);
3028 inst_base->idx = index; 3012 inst_cream->Rm = BITS(inst, 0, 3);
3029 inst_base->br = NON_BRANCH; 3013 inst_cream->Rs = BITS(inst, 8, 11);
3030 inst_base->load_r15 = 0; 3014 inst_cream->RdHi = BITS(inst, 16, 19);
3015 inst_cream->RdLo = BITS(inst, 12, 15);
3031 3016
3032 inst_cream->S = BIT(inst, 20); 3017 if (CHECK_RM || CHECK_RS)
3033 inst_cream->Rm = BITS(inst, 0, 3); 3018 inst_base->load_r15 = 1;
3034 inst_cream->Rs = BITS(inst, 8, 11);
3035 inst_cream->RdHi = BITS(inst, 16, 19);
3036 inst_cream->RdLo = BITS(inst, 12, 15);
3037 3019
3038 if (CHECK_RM || CHECK_RS) 3020 return inst_base;
3039 inst_base->load_r15 = 1;
3040 return inst_base;
3041} 3021}
3042ARM_INST_PTR INTERPRETER_TRANSLATE(umull)(unsigned int inst, int index) 3022ARM_INST_PTR INTERPRETER_TRANSLATE(umull)(unsigned int inst, int index)
3043{ 3023{
3044 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); 3024 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
3045 umull_inst *inst_cream = (umull_inst *)inst_base->component; 3025 umull_inst *inst_cream = (umull_inst *)inst_base->component;
3046 3026
3047 inst_base->cond = BITS(inst, 28, 31); 3027 inst_base->cond = BITS(inst, 28, 31);
3048 inst_base->idx = index; 3028 inst_base->idx = index;
3049 inst_base->br = NON_BRANCH; 3029 inst_base->br = NON_BRANCH;
3050 inst_base->load_r15 = 0; 3030 inst_base->load_r15 = 0;
3051 3031
3052 inst_cream->S = BIT(inst, 20); 3032 inst_cream->S = BIT(inst, 20);
3053 inst_cream->Rm = BITS(inst, 0, 3); 3033 inst_cream->Rm = BITS(inst, 0, 3);
3054 inst_cream->Rs = BITS(inst, 8, 11); 3034 inst_cream->Rs = BITS(inst, 8, 11);
3055 inst_cream->RdHi = BITS(inst, 16, 19); 3035 inst_cream->RdHi = BITS(inst, 16, 19);
3056 inst_cream->RdLo = BITS(inst, 12, 15); 3036 inst_cream->RdLo = BITS(inst, 12, 15);
3057 3037
3058 if (CHECK_RM || CHECK_RS) 3038 if (CHECK_RM || CHECK_RS)
3059 inst_base->load_r15 = 1; 3039 inst_base->load_r15 = 1;
3060 return inst_base; 3040 return inst_base;
3061} 3041}
3062 3042
3063ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index) 3043ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index)
3064{ 3044{
3065 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb)); 3045 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb));
3066 b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component; 3046 b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component;
3067 3047
3068 inst_cream->imm =((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0); 3048 inst_cream->imm = ((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0);
3069 //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm); 3049
3070 inst_base->idx = index; 3050 inst_base->idx = index;
3071 inst_base->br = DIRECT_BRANCH; 3051 inst_base->br = DIRECT_BRANCH;
3072 return inst_base; 3052
3053 return inst_base;
3073} 3054}
3074 3055
3075ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index) 3056ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index)
3076{ 3057{
3077 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb)); 3058 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb));
3078 b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component; 3059 b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component;
3079 3060
3080 inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0)); 3061 inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0));
3081 inst_cream->cond = ((tinst >> 8) & 0xf); 3062 inst_cream->cond = ((tinst >> 8) & 0xf);
3082 //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x, cond=0x%x\n", __FUNCTION__, tinst, inst_cream->imm, inst_cream->cond); 3063 inst_base->idx = index;
3083 inst_base->idx = index; 3064 inst_base->br = DIRECT_BRANCH;
3084 inst_base->br = DIRECT_BRANCH; 3065
3085 return inst_base; 3066 return inst_base;
3086} 3067}
3087 3068
3088ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index) 3069ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index)
3089{ 3070{
3090 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb)); 3071 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb));
3091 bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component; 3072 bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component;
3092 3073
3093 inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0)); 3074 inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0));
3094 //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm);
3095 3075
3096 inst_base->idx = index; 3076 inst_base->idx = index;
3097 inst_base->br = NON_BRANCH; 3077 inst_base->br = NON_BRANCH;
3098 return inst_base; 3078 return inst_base;
3099} 3079}
3100ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index) 3080ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index)
3101{ 3081{
3102 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb)); 3082 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb));
3103 bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component; 3083 bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component;
3084
3085 inst_cream->imm = (tinst & 0x07FF) << 1;
3104 3086
3105 inst_cream->imm = (tinst & 0x07FF) << 1; 3087 inst_base->idx = index;
3106 //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm); 3088 inst_base->br = DIRECT_BRANCH;
3107 inst_base->idx = index; 3089 return inst_base;
3108 inst_base->br = DIRECT_BRANCH;
3109 return inst_base;
3110} 3090}
3111ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index) 3091ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index)
3112{ 3092{
3113 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb)); 3093 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb));
3114 blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component; 3094 blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
3115 3095
3116 inst_cream->imm = (tinst & 0x07FF) << 1; 3096 inst_cream->imm = (tinst & 0x07FF) << 1;
3117 //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm); 3097 inst_cream->instr = tinst;
3118 inst_cream->instr = tinst; 3098
3119 inst_base->idx = index; 3099 inst_base->idx = index;
3120 inst_base->br = DIRECT_BRANCH; 3100 inst_base->br = DIRECT_BRANCH;
3121 return inst_base; 3101 return inst_base;
3122} 3102}
3123 3103
3124ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 3104ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index)
3125ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 3105{
3126ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 3106 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
3127ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 3107 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
3128ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 3108
3129ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 3109 inst_base->cond = BITS(inst, 28, 31);
3130ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 3110 inst_base->idx = index;
3131ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 3111 inst_base->br = NON_BRANCH;
3132ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 3112 inst_base->load_r15 = 0;
3133ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 3113
3134ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 3114 inst_cream->Rm = BITS(inst, 0, 3);
3135ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 3115 inst_cream->Rn = BITS(inst, 16, 19);
3136ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 3116 inst_cream->Rd = BITS(inst, 12, 15);
3137ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 3117 inst_cream->op1 = BITS(inst, 20, 21);
3138ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} 3118 inst_cream->op2 = BITS(inst, 5, 7);
3119
3120 return inst_base;
3121}
3122ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index)
3123{
3124 return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
3125}
3126ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index)
3127{
3128 return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
3129}
3130ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index)
3131{
3132 return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
3133}
3134ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index)
3135{
3136 return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
3137}
3138ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index)
3139{
3140 return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
3141}
3142ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index)
3143{
3144 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
3145 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
3139 3146
3147 inst_base->cond = BITS(inst, 28, 31);
3148 inst_base->idx = index;
3149 inst_base->br = NON_BRANCH;
3150 inst_base->load_r15 = 0;
3140 3151
3152 inst_cream->op1 = BITS(inst, 20, 24);
3153 inst_cream->op2 = BITS(inst, 5, 7);
3154 inst_cream->Rm = BITS(inst, 8, 11);
3155 inst_cream->Rn = BITS(inst, 0, 3);
3156 inst_cream->Ra = BITS(inst, 12, 15);
3141 3157
3142/* Floating point VFPv3 structures and instructions */ 3158 return inst_base;
3159}
3160ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index)
3161{
3162 return INTERPRETER_TRANSLATE(usada8)(inst, index);
3163}
3164ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index)
3165{
3166 return INTERPRETER_TRANSLATE(ssat)(inst, index);
3167}
3168ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT16"); }
3169ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB16"); }
3170ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB8"); }
3171ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUBADDX"); }
3172
3173ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index)
3174{
3175 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
3176 uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component;
3177
3178 inst_base->cond = BITS(inst, 28, 31);
3179 inst_base->idx = index;
3180 inst_base->br = NON_BRANCH;
3181 inst_base->load_r15 = 0;
3182
3183 inst_cream->Rm = BITS(inst, 0, 3);
3184 inst_cream->Rn = BITS(inst, 16, 19);
3185 inst_cream->Rd = BITS(inst, 12, 15);
3186 inst_cream->rotate = BITS(inst, 10, 11);
3187
3188 return inst_base;
3189}
3190ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index)
3191{
3192 return INTERPRETER_TRANSLATE(uxtab16)(inst, index);
3193}
3194
3195// Floating point VFPv3 structures and instructions
3143 3196
3144#define VFP_INTERPRETER_STRUCT 3197#define VFP_INTERPRETER_STRUCT
3145#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 3198#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
@@ -3149,324 +3202,288 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index){DEBUG_L
3149#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 3202#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
3150#undef VFP_INTERPRETER_TRANS 3203#undef VFP_INTERPRETER_TRANS
3151 3204
3152
3153
3154typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int); 3205typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int);
3155 3206
3156const transop_fp_t arm_instruction_trans[] = { 3207const transop_fp_t arm_instruction_trans[] = {
3157 #define VFP_INTERPRETER_TABLE 3208 INTERPRETER_TRANSLATE(vmla),
3158 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 3209 INTERPRETER_TRANSLATE(vmls),
3159 #undef VFP_INTERPRETER_TABLE 3210 INTERPRETER_TRANSLATE(vnmla),
3160 INTERPRETER_TRANSLATE(srs), 3211 INTERPRETER_TRANSLATE(vnmla),
3161 INTERPRETER_TRANSLATE(rfe), 3212 INTERPRETER_TRANSLATE(vnmls),
3162 INTERPRETER_TRANSLATE(bkpt), 3213 INTERPRETER_TRANSLATE(vnmul),
3163 INTERPRETER_TRANSLATE(blx), 3214 INTERPRETER_TRANSLATE(vmul),
3164 INTERPRETER_TRANSLATE(cps), 3215 INTERPRETER_TRANSLATE(vadd),
3165 INTERPRETER_TRANSLATE(pld), 3216 INTERPRETER_TRANSLATE(vsub),
3166 INTERPRETER_TRANSLATE(setend), 3217 INTERPRETER_TRANSLATE(vdiv),
3167 INTERPRETER_TRANSLATE(clrex), 3218 INTERPRETER_TRANSLATE(vmovi),
3168 INTERPRETER_TRANSLATE(rev16), 3219 INTERPRETER_TRANSLATE(vmovr),
3169 INTERPRETER_TRANSLATE(usad8), 3220 INTERPRETER_TRANSLATE(vabs),
3170 INTERPRETER_TRANSLATE(sxtb), 3221 INTERPRETER_TRANSLATE(vneg),
3171 INTERPRETER_TRANSLATE(uxtb), 3222 INTERPRETER_TRANSLATE(vsqrt),
3172 INTERPRETER_TRANSLATE(sxth), 3223 INTERPRETER_TRANSLATE(vcmp),
3173 INTERPRETER_TRANSLATE(sxtb16), 3224 INTERPRETER_TRANSLATE(vcmp2),
3174 INTERPRETER_TRANSLATE(uxth), 3225 INTERPRETER_TRANSLATE(vcvtbds),
3175 INTERPRETER_TRANSLATE(uxtb16), 3226 INTERPRETER_TRANSLATE(vcvtbff),
3176 INTERPRETER_TRANSLATE(cpy), 3227 INTERPRETER_TRANSLATE(vcvtbfi),
3177 INTERPRETER_TRANSLATE(uxtab), 3228 INTERPRETER_TRANSLATE(vmovbrs),
3178 INTERPRETER_TRANSLATE(ssub8), 3229 INTERPRETER_TRANSLATE(vmsr),
3179 INTERPRETER_TRANSLATE(shsub8), 3230 INTERPRETER_TRANSLATE(vmovbrc),
3180 INTERPRETER_TRANSLATE(ssubaddx), 3231 INTERPRETER_TRANSLATE(vmrs),
3181 INTERPRETER_TRANSLATE(strex), 3232 INTERPRETER_TRANSLATE(vmovbcr),
3182 INTERPRETER_TRANSLATE(strexb), 3233 INTERPRETER_TRANSLATE(vmovbrrss),
3183 INTERPRETER_TRANSLATE(swp), 3234 INTERPRETER_TRANSLATE(vmovbrrd),
3184 INTERPRETER_TRANSLATE(swpb), 3235 INTERPRETER_TRANSLATE(vstr),
3185 INTERPRETER_TRANSLATE(ssub16), 3236 INTERPRETER_TRANSLATE(vpush),
3186 INTERPRETER_TRANSLATE(ssat16), 3237 INTERPRETER_TRANSLATE(vstm),
3187 INTERPRETER_TRANSLATE(shsubaddx), 3238 INTERPRETER_TRANSLATE(vpop),
3188 INTERPRETER_TRANSLATE(qsubaddx), 3239 INTERPRETER_TRANSLATE(vldr),
3189 INTERPRETER_TRANSLATE(shaddsubx), 3240 INTERPRETER_TRANSLATE(vldm),
3190 INTERPRETER_TRANSLATE(shadd8), 3241
3191 INTERPRETER_TRANSLATE(shadd16), 3242 INTERPRETER_TRANSLATE(srs),
3192 INTERPRETER_TRANSLATE(sel), 3243 INTERPRETER_TRANSLATE(rfe),
3193 INTERPRETER_TRANSLATE(saddsubx), 3244 INTERPRETER_TRANSLATE(bkpt),
3194 INTERPRETER_TRANSLATE(sadd8), 3245 INTERPRETER_TRANSLATE(blx),
3195 INTERPRETER_TRANSLATE(sadd16), 3246 INTERPRETER_TRANSLATE(cps),
3196 INTERPRETER_TRANSLATE(shsub16), 3247 INTERPRETER_TRANSLATE(pld),
3197 INTERPRETER_TRANSLATE(umaal), 3248 INTERPRETER_TRANSLATE(setend),
3198 INTERPRETER_TRANSLATE(uxtab16), 3249 INTERPRETER_TRANSLATE(clrex),
3199 INTERPRETER_TRANSLATE(usubaddx), 3250 INTERPRETER_TRANSLATE(rev16),
3200 INTERPRETER_TRANSLATE(usub8), 3251 INTERPRETER_TRANSLATE(usad8),
3201 INTERPRETER_TRANSLATE(usub16), 3252 INTERPRETER_TRANSLATE(sxtb),
3202 INTERPRETER_TRANSLATE(usat16), 3253 INTERPRETER_TRANSLATE(uxtb),
3203 INTERPRETER_TRANSLATE(usada8), 3254 INTERPRETER_TRANSLATE(sxth),
3204 INTERPRETER_TRANSLATE(uqsubaddx), 3255 INTERPRETER_TRANSLATE(sxtb16),
3205 INTERPRETER_TRANSLATE(uqsub8), 3256 INTERPRETER_TRANSLATE(uxth),
3206 INTERPRETER_TRANSLATE(uqsub16), 3257 INTERPRETER_TRANSLATE(uxtb16),
3207 INTERPRETER_TRANSLATE(uqaddsubx), 3258 INTERPRETER_TRANSLATE(cpy),
3208 INTERPRETER_TRANSLATE(uqadd8), 3259 INTERPRETER_TRANSLATE(uxtab),
3209 INTERPRETER_TRANSLATE(uqadd16), 3260 INTERPRETER_TRANSLATE(ssub8),
3210 INTERPRETER_TRANSLATE(sxtab), 3261 INTERPRETER_TRANSLATE(shsub8),
3211 INTERPRETER_TRANSLATE(uhsubaddx), 3262 INTERPRETER_TRANSLATE(ssubaddx),
3212 INTERPRETER_TRANSLATE(uhsub8), 3263 INTERPRETER_TRANSLATE(strex),
3213 INTERPRETER_TRANSLATE(uhsub16), 3264 INTERPRETER_TRANSLATE(strexb),
3214 INTERPRETER_TRANSLATE(uhaddsubx), 3265 INTERPRETER_TRANSLATE(swp),
3215 INTERPRETER_TRANSLATE(uhadd8), 3266 INTERPRETER_TRANSLATE(swpb),
3216 INTERPRETER_TRANSLATE(uhadd16), 3267 INTERPRETER_TRANSLATE(ssub16),
3217 INTERPRETER_TRANSLATE(uaddsubx), 3268 INTERPRETER_TRANSLATE(ssat16),
3218 INTERPRETER_TRANSLATE(uadd8), 3269 INTERPRETER_TRANSLATE(shsubaddx),
3219 INTERPRETER_TRANSLATE(uadd16), 3270 INTERPRETER_TRANSLATE(qsubaddx),
3220 INTERPRETER_TRANSLATE(sxtah), 3271 INTERPRETER_TRANSLATE(shaddsubx),
3221 INTERPRETER_TRANSLATE(sxtab16), 3272 INTERPRETER_TRANSLATE(shadd8),
3222 INTERPRETER_TRANSLATE(qadd8), 3273 INTERPRETER_TRANSLATE(shadd16),
3223 INTERPRETER_TRANSLATE(bxj), 3274 INTERPRETER_TRANSLATE(sel),
3224 INTERPRETER_TRANSLATE(clz), 3275 INTERPRETER_TRANSLATE(saddsubx),
3225 INTERPRETER_TRANSLATE(uxtah), 3276 INTERPRETER_TRANSLATE(sadd8),
3226 INTERPRETER_TRANSLATE(bx), 3277 INTERPRETER_TRANSLATE(sadd16),
3227 INTERPRETER_TRANSLATE(rev), 3278 INTERPRETER_TRANSLATE(shsub16),
3228 INTERPRETER_TRANSLATE(blx), 3279 INTERPRETER_TRANSLATE(umaal),
3229 INTERPRETER_TRANSLATE(revsh), 3280 INTERPRETER_TRANSLATE(uxtab16),
3230 INTERPRETER_TRANSLATE(qadd), 3281 INTERPRETER_TRANSLATE(usubaddx),
3231 INTERPRETER_TRANSLATE(qadd16), 3282 INTERPRETER_TRANSLATE(usub8),
3232 INTERPRETER_TRANSLATE(qaddsubx), 3283 INTERPRETER_TRANSLATE(usub16),
3233 INTERPRETER_TRANSLATE(ldrex), 3284 INTERPRETER_TRANSLATE(usat16),
3234 INTERPRETER_TRANSLATE(qdadd), 3285 INTERPRETER_TRANSLATE(usada8),
3235 INTERPRETER_TRANSLATE(qdsub), 3286 INTERPRETER_TRANSLATE(uqsubaddx),
3236 INTERPRETER_TRANSLATE(qsub), 3287 INTERPRETER_TRANSLATE(uqsub8),
3237 INTERPRETER_TRANSLATE(ldrexb), 3288 INTERPRETER_TRANSLATE(uqsub16),
3238 INTERPRETER_TRANSLATE(qsub8), 3289 INTERPRETER_TRANSLATE(uqaddsubx),
3239 INTERPRETER_TRANSLATE(qsub16), 3290 INTERPRETER_TRANSLATE(uqadd8),
3240 INTERPRETER_TRANSLATE(smuad), 3291 INTERPRETER_TRANSLATE(uqadd16),
3241 INTERPRETER_TRANSLATE(smmul), 3292 INTERPRETER_TRANSLATE(sxtab),
3242 INTERPRETER_TRANSLATE(smusd), 3293 INTERPRETER_TRANSLATE(uhsubaddx),
3243 INTERPRETER_TRANSLATE(smlsd), 3294 INTERPRETER_TRANSLATE(uhsub8),
3244 INTERPRETER_TRANSLATE(smlsld), 3295 INTERPRETER_TRANSLATE(uhsub16),
3245 INTERPRETER_TRANSLATE(smmla), 3296 INTERPRETER_TRANSLATE(uhaddsubx),
3246 INTERPRETER_TRANSLATE(smmls), 3297 INTERPRETER_TRANSLATE(uhadd8),
3247 INTERPRETER_TRANSLATE(smlald), 3298 INTERPRETER_TRANSLATE(uhadd16),
3248 INTERPRETER_TRANSLATE(smlad), 3299 INTERPRETER_TRANSLATE(uaddsubx),
3249 INTERPRETER_TRANSLATE(smlaw), 3300 INTERPRETER_TRANSLATE(uadd8),
3250 INTERPRETER_TRANSLATE(smulw), 3301 INTERPRETER_TRANSLATE(uadd16),
3251 INTERPRETER_TRANSLATE(pkhtb), 3302 INTERPRETER_TRANSLATE(sxtah),
3252 INTERPRETER_TRANSLATE(pkhbt), 3303 INTERPRETER_TRANSLATE(sxtab16),
3253 INTERPRETER_TRANSLATE(smul), 3304 INTERPRETER_TRANSLATE(qadd8),
3254 INTERPRETER_TRANSLATE(smlalxy), 3305 INTERPRETER_TRANSLATE(bxj),
3255 INTERPRETER_TRANSLATE(smla), 3306 INTERPRETER_TRANSLATE(clz),
3256 INTERPRETER_TRANSLATE(mcrr), 3307 INTERPRETER_TRANSLATE(uxtah),
3257 INTERPRETER_TRANSLATE(mrrc), 3308 INTERPRETER_TRANSLATE(bx),
3258 INTERPRETER_TRANSLATE(cmp), 3309 INTERPRETER_TRANSLATE(rev),
3259 INTERPRETER_TRANSLATE(tst), 3310 INTERPRETER_TRANSLATE(blx),
3260 INTERPRETER_TRANSLATE(teq), 3311 INTERPRETER_TRANSLATE(revsh),
3261 INTERPRETER_TRANSLATE(cmn), 3312 INTERPRETER_TRANSLATE(qadd),
3262 INTERPRETER_TRANSLATE(smull), 3313 INTERPRETER_TRANSLATE(qadd16),
3263 INTERPRETER_TRANSLATE(umull), 3314 INTERPRETER_TRANSLATE(qaddsubx),
3264 INTERPRETER_TRANSLATE(umlal), 3315 INTERPRETER_TRANSLATE(ldrex),
3265 INTERPRETER_TRANSLATE(smlal), 3316 INTERPRETER_TRANSLATE(qdadd),
3266 INTERPRETER_TRANSLATE(mul), 3317 INTERPRETER_TRANSLATE(qdsub),
3267 INTERPRETER_TRANSLATE(mla), 3318 INTERPRETER_TRANSLATE(qsub),
3268 INTERPRETER_TRANSLATE(ssat), 3319 INTERPRETER_TRANSLATE(ldrexb),
3269 INTERPRETER_TRANSLATE(usat), 3320 INTERPRETER_TRANSLATE(qsub8),
3270 INTERPRETER_TRANSLATE(mrs), 3321 INTERPRETER_TRANSLATE(qsub16),
3271 INTERPRETER_TRANSLATE(msr), 3322 INTERPRETER_TRANSLATE(smuad),
3272 INTERPRETER_TRANSLATE(and), 3323 INTERPRETER_TRANSLATE(smmul),
3273 INTERPRETER_TRANSLATE(bic), 3324 INTERPRETER_TRANSLATE(smusd),
3274 INTERPRETER_TRANSLATE(ldm), 3325 INTERPRETER_TRANSLATE(smlsd),
3275 INTERPRETER_TRANSLATE(eor), 3326 INTERPRETER_TRANSLATE(smlsld),
3276 INTERPRETER_TRANSLATE(add), 3327 INTERPRETER_TRANSLATE(smmla),
3277 INTERPRETER_TRANSLATE(rsb), 3328 INTERPRETER_TRANSLATE(smmls),
3278 INTERPRETER_TRANSLATE(rsc), 3329 INTERPRETER_TRANSLATE(smlald),
3279 INTERPRETER_TRANSLATE(sbc), 3330 INTERPRETER_TRANSLATE(smlad),
3280 INTERPRETER_TRANSLATE(adc), 3331 INTERPRETER_TRANSLATE(smlaw),
3281 INTERPRETER_TRANSLATE(sub), 3332 INTERPRETER_TRANSLATE(smulw),
3282 INTERPRETER_TRANSLATE(orr), 3333 INTERPRETER_TRANSLATE(pkhtb),
3283 INTERPRETER_TRANSLATE(mvn), 3334 INTERPRETER_TRANSLATE(pkhbt),
3284 INTERPRETER_TRANSLATE(mov), 3335 INTERPRETER_TRANSLATE(smul),
3285 INTERPRETER_TRANSLATE(stm), 3336 INTERPRETER_TRANSLATE(smlalxy),
3286 INTERPRETER_TRANSLATE(ldm), 3337 INTERPRETER_TRANSLATE(smla),
3287 INTERPRETER_TRANSLATE(ldrsh), 3338 INTERPRETER_TRANSLATE(mcrr),
3288 INTERPRETER_TRANSLATE(stm), 3339 INTERPRETER_TRANSLATE(mrrc),
3289 INTERPRETER_TRANSLATE(ldm), 3340 INTERPRETER_TRANSLATE(cmp),
3290 INTERPRETER_TRANSLATE(ldrsb), 3341 INTERPRETER_TRANSLATE(tst),
3291 INTERPRETER_TRANSLATE(strd), 3342 INTERPRETER_TRANSLATE(teq),
3292 INTERPRETER_TRANSLATE(ldrh), 3343 INTERPRETER_TRANSLATE(cmn),
3293 INTERPRETER_TRANSLATE(strh), 3344 INTERPRETER_TRANSLATE(smull),
3294 INTERPRETER_TRANSLATE(ldrd), 3345 INTERPRETER_TRANSLATE(umull),
3295 INTERPRETER_TRANSLATE(strt), 3346 INTERPRETER_TRANSLATE(umlal),
3296 INTERPRETER_TRANSLATE(strbt), 3347 INTERPRETER_TRANSLATE(smlal),
3297 INTERPRETER_TRANSLATE(ldrbt), 3348 INTERPRETER_TRANSLATE(mul),
3298 INTERPRETER_TRANSLATE(ldrt), 3349 INTERPRETER_TRANSLATE(mla),
3299 INTERPRETER_TRANSLATE(mrc), 3350 INTERPRETER_TRANSLATE(ssat),
3300 INTERPRETER_TRANSLATE(mcr), 3351 INTERPRETER_TRANSLATE(usat),
3301 INTERPRETER_TRANSLATE(msr), 3352 INTERPRETER_TRANSLATE(mrs),
3302 INTERPRETER_TRANSLATE(ldrb), 3353 INTERPRETER_TRANSLATE(msr),
3303 INTERPRETER_TRANSLATE(strb), 3354 INTERPRETER_TRANSLATE(and),
3304 INTERPRETER_TRANSLATE(ldr), 3355 INTERPRETER_TRANSLATE(bic),
3305 INTERPRETER_TRANSLATE(ldrcond), 3356 INTERPRETER_TRANSLATE(ldm),
3306 INTERPRETER_TRANSLATE(str), 3357 INTERPRETER_TRANSLATE(eor),
3307 INTERPRETER_TRANSLATE(cdp), 3358 INTERPRETER_TRANSLATE(add),
3308 INTERPRETER_TRANSLATE(stc), 3359 INTERPRETER_TRANSLATE(rsb),
3309 INTERPRETER_TRANSLATE(ldc), 3360 INTERPRETER_TRANSLATE(rsc),
3310 INTERPRETER_TRANSLATE(swi), 3361 INTERPRETER_TRANSLATE(sbc),
3311 INTERPRETER_TRANSLATE(bbl), 3362 INTERPRETER_TRANSLATE(adc),
3312 /* All the thumb instructions should be placed the end of table */ 3363 INTERPRETER_TRANSLATE(sub),
3313 INTERPRETER_TRANSLATE(b_2_thumb), 3364 INTERPRETER_TRANSLATE(orr),
3314 INTERPRETER_TRANSLATE(b_cond_thumb), 3365 INTERPRETER_TRANSLATE(mvn),
3315 INTERPRETER_TRANSLATE(bl_1_thumb), 3366 INTERPRETER_TRANSLATE(mov),
3316 INTERPRETER_TRANSLATE(bl_2_thumb), 3367 INTERPRETER_TRANSLATE(stm),
3317 INTERPRETER_TRANSLATE(blx_1_thumb) 3368 INTERPRETER_TRANSLATE(ldm),
3369 INTERPRETER_TRANSLATE(ldrsh),
3370 INTERPRETER_TRANSLATE(stm),
3371 INTERPRETER_TRANSLATE(ldm),
3372 INTERPRETER_TRANSLATE(ldrsb),
3373 INTERPRETER_TRANSLATE(strd),
3374 INTERPRETER_TRANSLATE(ldrh),
3375 INTERPRETER_TRANSLATE(strh),
3376 INTERPRETER_TRANSLATE(ldrd),
3377 INTERPRETER_TRANSLATE(strt),
3378 INTERPRETER_TRANSLATE(strbt),
3379 INTERPRETER_TRANSLATE(ldrbt),
3380 INTERPRETER_TRANSLATE(ldrt),
3381 INTERPRETER_TRANSLATE(mrc),
3382 INTERPRETER_TRANSLATE(mcr),
3383 INTERPRETER_TRANSLATE(msr),
3384 INTERPRETER_TRANSLATE(ldrb),
3385 INTERPRETER_TRANSLATE(strb),
3386 INTERPRETER_TRANSLATE(ldr),
3387 INTERPRETER_TRANSLATE(ldrcond),
3388 INTERPRETER_TRANSLATE(str),
3389 INTERPRETER_TRANSLATE(cdp),
3390 INTERPRETER_TRANSLATE(stc),
3391 INTERPRETER_TRANSLATE(ldc),
3392 INTERPRETER_TRANSLATE(swi),
3393 INTERPRETER_TRANSLATE(bbl),
3394 // All the thumb instructions should be placed the end of table
3395 INTERPRETER_TRANSLATE(b_2_thumb),
3396 INTERPRETER_TRANSLATE(b_cond_thumb),
3397 INTERPRETER_TRANSLATE(bl_1_thumb),
3398 INTERPRETER_TRANSLATE(bl_2_thumb),
3399 INTERPRETER_TRANSLATE(blx_1_thumb)
3318}; 3400};
3319 3401
3320typedef map<unsigned int, int> bb_map; 3402typedef std::unordered_map<u32, int> bb_map;
3321bb_map CreamCache[65536]; 3403bb_map CreamCache;
3322bb_map ProfileCache[65536];
3323
3324//#define USE_DUMMY_CACHE
3325 3404
3326#ifdef USE_DUMMY_CACHE 3405void insert_bb(unsigned int addr, int start) {
3327unsigned int DummyCache[0x100000]; 3406 CreamCache[addr] = start;
3328#endif
3329
3330#define HASH(x) ((x + (x << 3) + (x >> 6)) % 65536)
3331void insert_bb(unsigned int addr, int start)
3332{
3333#ifdef USE_DUMMY_CACHE
3334 DummyCache[addr] = start;
3335#else
3336// CreamCache[addr] = start;
3337 CreamCache[HASH(addr)][addr] = start;
3338#endif
3339} 3407}
3340 3408
3341#define TRANS_THRESHOLD 65000 3409#define TRANS_THRESHOLD 65000
3342int find_bb(unsigned int addr, int &start) 3410int find_bb(unsigned int addr, int &start) {
3343{ 3411 int ret = -1;
3344 int ret = -1; 3412 bb_map::const_iterator it = CreamCache.find(addr);
3345#ifdef USE_DUMMY_CACHE 3413 if (it != CreamCache.end()) {
3346 start = DummyCache[addr]; 3414 start = static_cast<int>(it->second);
3347 if (start) { 3415 ret = 0;
3348 ret = 0; 3416 } else {
3349 } else 3417 ret = -1;
3350 ret = -1; 3418 }
3351#else 3419 return ret;
3352 bb_map::const_iterator it = CreamCache[HASH(addr)].find(addr);
3353 if (it != CreamCache[HASH(addr)].end()) {
3354 start = static_cast<int>(it->second);
3355 ret = 0;
3356#if HYBRID_MODE
3357#if PROFILE
3358#else
3359 /* increase the bb counter */
3360 if(get_bb_prof(cpu, addr, 1) == TRANS_THRESHOLD){
3361 push_to_compiled(cpu, addr);
3362 }
3363#endif
3364#endif
3365 } else {
3366 ret = -1;
3367 }
3368#endif
3369 return ret;
3370} 3420}
3371 3421
3372
3373enum { 3422enum {
3374 FETCH_SUCCESS, 3423 FETCH_SUCCESS,
3375 FETCH_FAILURE 3424 FETCH_FAILURE
3376}; 3425};
3426
3377static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr, uint32_t *arm_inst, uint32_t* inst_size, ARM_INST_PTR* ptr_inst_base){ 3427static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr, uint32_t *arm_inst, uint32_t* inst_size, ARM_INST_PTR* ptr_inst_base){
3378 /* Check if in Thumb mode. */ 3428 // Check if in Thumb mode
3379 tdstate ret; 3429 tdstate ret = thumb_translate (addr, inst, arm_inst, inst_size);
3380 ret = thumb_translate (addr, inst, arm_inst, inst_size); 3430 if(ret == t_branch){
3381 if(ret == t_branch){ 3431 // TODO: FIXME, endian should be judged
3382 /* FIXME, endian should be judged */ 3432 uint32 tinstr;
3383 uint32 tinstr; 3433 if((addr & 0x3) != 0)
3384 if((addr & 0x3) != 0) 3434 tinstr = inst >> 16;
3385 tinstr = inst >> 16; 3435 else
3386 else 3436 tinstr = inst & 0xFFFF;
3387 tinstr = inst & 0xFFFF; 3437
3388 3438 int inst_index;
3389 //tinstr = inst & 0xFFFF; 3439 int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
3390 int inst_index; 3440
3391 /* table_length */ 3441 switch((tinstr & 0xF800) >> 11){
3392 int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t); 3442 case 26:
3393 3443 case 27:
3394 switch((tinstr & 0xF800) >> 11){ 3444 if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){
3395 /* we will translate the thumb instruction directly here */ 3445 uint32 cond = (tinstr & 0x0F00) >> 8;
3396 /* we will translate the thumb instruction directly here */ 3446 inst_index = table_length - 4;
3397 case 26: 3447 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3398 case 27: 3448 } else {
3399 if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){ 3449 LOG_ERROR(Core_ARM11, "thumb decoder error");
3400 uint32 cond = (tinstr & 0x0F00) >> 8; 3450 }
3401 inst_index = table_length - 4; 3451 break;
3402 //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d\n", __FUNCTION__, tinstr, inst_index); 3452 case 28:
3403 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); 3453 // Branch 2, unconditional branch
3404 } 3454 inst_index = table_length - 5;
3405 else{ 3455 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3406 /* something wrong */ 3456 break;
3407 DEBUG_LOG(ARM11, "In %s, thumb decoder error\n", __FUNCTION__); 3457
3408 } 3458 case 8:
3409 break; 3459 case 29:
3410 case 28: 3460 // For BLX 1 thumb instruction
3411 /* Branch 2, unconditional branch */ 3461 inst_index = table_length - 1;
3412 inst_index = table_length - 5; 3462 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3413 //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d\n", __FUNCTION__, tinstr, inst_index); 3463 break;
3414 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); 3464 case 30:
3415 break; 3465 // For BL 1 thumb instruction
3416 3466 inst_index = table_length - 3;
3417 case 8: 3467 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3418 case 29: 3468 break;
3419 /* For BLX 1 thumb instruction*/ 3469 case 31:
3420 inst_index = table_length - 1; 3470 // For BL 2 thumb instruction
3421 //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d, pc=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc); 3471 inst_index = table_length - 2;
3422 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); 3472 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3423 break; 3473 break;
3424 case 30: 3474 default:
3425 /* For BL 1 thumb instruction*/ 3475 ret = t_undefined;
3426 inst_index = table_length - 3; 3476 break;
3427 //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, bl 1 thumb index=%d, pc=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc); 3477 }
3428 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); 3478 }
3429 break; 3479 return ret;
3430 case 31:
3431 /* For BL 2 thumb instruction*/
3432 inst_index = table_length - 2;
3433 //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, bl 2 thumb index=%d, px=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc);
3434 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3435 break;
3436 default:
3437 ret = t_undefined;
3438 break;
3439 }
3440 }
3441 return ret;
3442}
3443
3444#if 0
3445int FetchInst(cpu_t *core, unsigned int &inst)
3446{
3447 //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t");
3448 arm_processor *cpu = (arm_processor *)(core->cpu_data->obj);
3449// fault_t fault = interpreter_read_memory(cpu->translate_pc, inst, 32);
3450 fault_t fault = interpreter_fetch(core, cpu->translate_pc, inst, 32);
3451 if (!core->is_user_mode) {
3452 if (fault) {
3453 cpu->abortSig = true;
3454 cpu->Aborted = ARMul_PrefetchAbortV;
3455 cpu->AbortAddr = cpu->translate_pc;
3456 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
3457 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->translate_pc;
3458 return FETCH_FAILURE;
3459 }
3460 }
3461 return FETCH_SUCCESS;
3462} 3480}
3463#endif
3464 3481
3465unsigned int *InstLength; 3482unsigned int *InstLength;
3466 3483
3467enum { 3484enum {
3468 KEEP_GOING, 3485 KEEP_GOING,
3469 FETCH_EXCEPTION 3486 FETCH_EXCEPTION
3470}; 3487};
3471 3488
3472typedef struct instruction_set_encoding_item ISEITEM; 3489typedef struct instruction_set_encoding_item ISEITEM;
@@ -3475,289 +3492,148 @@ extern const ISEITEM arm_instruction[];
3475 3492
3476vector<uint64_t> code_page_set; 3493vector<uint64_t> code_page_set;
3477 3494
3478void flush_bb(uint32_t addr) 3495void flush_bb(uint32_t addr) {
3479{ 3496 bb_map::iterator it;
3480 bb_map::iterator it; 3497 uint32_t start;
3481 uint32_t start; 3498
3482 3499 addr &= 0xfffff000;
3483 addr &= 0xfffff000; 3500 for (it = CreamCache.begin(); it != CreamCache.end(); ) {
3484 for (int i = 0; i < 65536; i ++) { 3501 start = static_cast<uint32_t>(it->first);
3485 for (it = CreamCache[i].begin(); it != CreamCache[i].end(); ) { 3502 start &= 0xfffff000;
3486 start = static_cast<uint32_t>(it->first); 3503 if (start == addr) {
3487 //start = (start >> 12) << 12; 3504 CreamCache.erase(it++);
3488 start &= 0xfffff000; 3505 } else
3489 if (start == addr) { 3506 ++it;
3490 //DEBUG_LOG(ARM11, "[ERASE][0x%08x]\n", static_cast<int>(it->first)); 3507 }
3491 CreamCache[i].erase(it ++); 3508}
3492 } else
3493 ++it;
3494 }
3495 }
3496
3497 for (int i = 0; i < 65536; i ++) {
3498 for (it = ProfileCache[i].begin(); it != ProfileCache[i].end(); ) {
3499 start = static_cast<uint32_t>(it->first);
3500 //start = (start >> 12) << 12;
3501 start &= 0xfffff000;
3502 if (start == addr) {
3503 //DEBUG_LOG(ARM11, "[ERASE][0x%08x]\n", static_cast<int>(it->first));
3504 ProfileCache[i].erase(it ++);
3505 } else
3506 ++it;
3507 }
3508 }
3509
3510 //DEBUG_LOG(ARM11, "flush bb @ %x\n", addr);
3511}
3512
3513//static uint32_t get_bank_addr(void *addr)
3514//{
3515// uint64_t address = (uint64_t)addr;
3516// uint64_t bank0 = get_dma_addr(BANK0_START);
3517// if ((address >= bank0) && (address < (bank0 + BANK0_SIZE))) {
3518// //DEBUG_LOG(ARM11, "1.addr is %llx\n", addr);
3519// return ((uint64_t)addr - bank0) + BANK0_START;
3520// }
3521// return 0;
3522//}
3523
3524/* shenoubang add win32 2012-6-12 */
3525//#ifndef __WIN32__
3526//static void flush_code_cache(int signal_number, siginfo_t *si, void *unused)
3527//{
3528// DEBUG_LOG(ARM11, "in %s, addr=0x%llx\n", __FUNCTION__, si->si_addr);
3529// uint64_t addr = (uint64_t)si->si_addr;
3530// addr = (addr >> 12) << 12;
3531// skyeye_backtrace();
3532// #if 0
3533// if (addr == 0) {
3534// return;
3535// }
3536// const vector<uint64_t>::iterator it = find(code_page_set.begin(),
3537// code_page_set.end(),
3538// (uint64_t)addr);
3539// if (it != code_page_set.end()) {
3540// code_page_set.erase(it);
3541// }
3542// mprotect((void *)addr, 4096, PROT_READ | PROT_WRITE);
3543// //DEBUG_LOG(ARM11, "[flush][ADDR:0x%08llx]\n", addr);
3544// uint32_t phys_addr = get_bank_addr((void *)addr);
3545//// DEBUG_LOG(ARM11, "[PHYSICAL][ADDR:0x%08llx]\n", phys_addr);
3546// flush_bb(phys_addr);
3547// flush_bb(phys_addr + 4096);
3548//#if HYBRID_MODE
3549// /* flush the translated BB of dyncom */
3550// clear_translated_cache(phys_addr);
3551//#endif
3552// #endif
3553//}
3554//#endif /* shenoubang */
3555
3556//void protect_code_page(uint32_t addr)
3557//{
3558// void *mem_ptr = (void *)get_dma_addr(addr);
3559// mem_ptr = (void *)((long long int)mem_ptr & 0xfffffffffffff000LL);
3560//
3561// const vector<uint64_t>::iterator it = find(code_page_set.begin(),
3562// code_page_set.end(),
3563// (uint64_t)mem_ptr);
3564// if (it != code_page_set.end()) {
3565// return;
3566// }
3567// //DEBUG_LOG(ARM11, "[mprotect][ADDR:0x%08llx]\n", mem_ptr);
3568// /* shenoubang add win32 2012-6-12 */
3569//#ifndef __WIN32__
3570// struct sigaction sa;
3571//
3572// memset(&sa, 0, sizeof(sa));
3573// sa.sa_flags = SA_RESTART | SA_SIGINFO;
3574// sa.sa_sigaction = &flush_code_cache;
3575// sigaction(SIGSEGV, &sa, NULL);
3576//
3577// //mprotect(mem_ptr, 4096, PROT_READ);
3578//
3579// code_page_set.push_back((uint64_t)mem_ptr);
3580//#endif /* shenoubang */
3581//}
3582
3583
3584
3585int InterpreterTranslate(arm_processor *cpu, int &bb_start, addr_t addr)
3586{
3587 /* Decode instruction, get index */
3588 /* Allocate memory and init InsCream */
3589 /* Go on next, until terminal instruction */
3590 /* Save start addr of basicblock in CreamCache */
3591 //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t");
3592 //arm_processor *cpu = (arm_processor *)(core->cpu_data->obj);
3593 ARM_INST_PTR inst_base = NULL;
3594 unsigned int inst, inst_size = 4;
3595 int idx;
3596 int ret = NON_BRANCH;
3597 int thumb = 0;
3598 /* instruction size of basic block */
3599 int size = 0;
3600 /* (R15 - 8) ? */
3601 //cpu->translate_pc = cpu->Reg[15];
3602 bb_start = top;
3603
3604 if (cpu->TFlag)
3605 thumb = THUMB;
3606
3607 addr_t phys_addr;
3608 addr_t pc_start;
3609 fault_t fault = NO_FAULT;
3610 //fault = check_address_validity(cpu, addr, &phys_addr, 1, INSN_TLB);
3611 fault = check_address_validity(cpu, addr, &phys_addr, 1);
3612 if(fault != NO_FAULT){
3613 cpu->abortSig = true;
3614 cpu->Aborted = ARMul_PrefetchAbortV;
3615 cpu->AbortAddr = addr;
3616 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
3617 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr;
3618 return FETCH_EXCEPTION;
3619 }
3620 pc_start = phys_addr;
3621 //phys_addr = get_dma_addr(phys_addr);
3622 while(ret == NON_BRANCH) {
3623 /* shenoubang add win32 2012-6-14 */
3624#ifdef __WIN32__
3625 mem_bank_t* bank;
3626 if (bank = bank_ptr(addr)) {
3627 bank->bank_read(32, phys_addr, &inst);
3628 }
3629 else {
3630 DEBUG_LOG(ARM11, "SKYEYE: Read physical addr 0x%x error!!\n", phys_addr);
3631 return FETCH_FAILURE;
3632 }
3633#else
3634 inst = Memory::Read32(phys_addr & 0xFFFFFFFC);//*(uint32_t *)(phys_addr & 0xFFFFFFFC);
3635#endif
3636 //or_tag(core, phys_addr, TAG_FAST_INTERP);
3637
3638 /*if (ret == FETCH_FAILURE) {
3639 return FETCH_EXCEPTION;
3640 }*/
3641
3642 size ++;
3643 /* If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction */
3644 if (cpu->TFlag){
3645 //if(cpu->Cpsr & (1 << THUMB_BIT)){
3646 uint32_t arm_inst;
3647 tdstate state;
3648 state = decode_thumb_instr(cpu, inst, phys_addr, &arm_inst, &inst_size, &inst_base);
3649 //or_tag(core, phys_addr, TAG_THUMB);
3650 //DEBUG_LOG(ARM11, "In thumb state, arm_inst=0x%x, inst_size=0x%x, pc=0x%x\n", arm_inst, inst_size, cpu->translate_pc);
3651 /* we have translated the branch instruction of thumb in thumb decoder */
3652 if(state == t_branch){
3653 goto translated;
3654 }
3655 inst = arm_inst;
3656 }
3657
3658 ret = decode_arm_instr(inst, &idx);
3659 if (ret == DECODE_FAILURE) {
3660 DEBUG_LOG(ARM11, "[info] : Decode failure.\tPC : [0x%x]\tInstruction : [%x]\n", phys_addr, inst);
3661 DEBUG_LOG(ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x\n", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]);
3662 CITRA_IGNORE_EXIT(-1);
3663 }
3664// DEBUG_LOG(ARM11, "PC : [0x%x] INST : %s\n", cpu->translate_pc, arm_instruction[idx].name);
3665 inst_base = arm_instruction_trans[idx](inst, idx);
3666// DEBUG_LOG(ARM11, "translated @ %x INST : %x\n", cpu->translate_pc, inst);
3667// DEBUG_LOG(ARM11, "inst size is %d\n", InstLength[idx]);
3668translated:
3669 phys_addr += inst_size;
3670 3509
3671 if ((phys_addr & 0xfff) == 0) { 3510int InterpreterTranslate(arm_processor *cpu, int &bb_start, addr_t addr) {
3672 inst_base->br = END_OF_PAGE; 3511 // Decode instruction, get index
3673 } 3512 // Allocate memory and init InsCream
3674 ret = inst_base->br; 3513 // Go on next, until terminal instruction
3675 }; 3514 // Save start addr of basicblock in CreamCache
3515 ARM_INST_PTR inst_base = nullptr;
3516 unsigned int inst, inst_size = 4;
3517 int idx;
3518 int ret = NON_BRANCH;
3519 int thumb = 0;
3520 int size = 0; // instruction size of basic block
3521 bb_start = top;
3522
3523 if (cpu->TFlag)
3524 thumb = THUMB;
3525
3526 addr_t phys_addr;
3527 addr_t pc_start;
3528 fault_t fault = NO_FAULT;
3529 fault = check_address_validity(cpu, addr, &phys_addr, 1);
3530 if(fault != NO_FAULT){
3531 cpu->abortSig = true;
3532 cpu->Aborted = ARMul_PrefetchAbortV;
3533 cpu->AbortAddr = addr;
3534 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
3535 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr;
3536 return FETCH_EXCEPTION;
3537 }
3676 3538
3677 //DEBUG_LOG(ARM11, "In %s,insert_bb pc=0x%x, TFlag=0x%x\n", __FUNCTION__, pc_start, cpu->TFlag); 3539 pc_start = phys_addr;
3678 insert_bb(pc_start, bb_start);
3679 return KEEP_GOING;
3680}
3681 3540
3682#define LOG_IN_CLR skyeye_printf_in_color 3541 while(ret == NON_BRANCH) {
3542 inst = Memory::Read32(phys_addr & 0xFFFFFFFC);//*(uint32_t *)(phys_addr & 0xFFFFFFFC);
3683 3543
3684int cmp(const void *x, const void *y) 3544 size ++;
3685{ 3545 // If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction
3686 return *(unsigned long long int*)x - *(unsigned long long int *)y; 3546 if (cpu->TFlag) {
3547 uint32_t arm_inst;
3548 tdstate state;
3549 state = decode_thumb_instr(cpu, inst, phys_addr, &arm_inst, &inst_size, &inst_base);
3550 // We have translated the branch instruction of thumb in thumb decoder
3551 if(state == t_branch){
3552 goto translated;
3553 }
3554 inst = arm_inst;
3555 }
3556
3557 ret = decode_arm_instr(inst, &idx);
3558 if (ret == DECODE_FAILURE) {
3559 LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : [%x]", phys_addr, inst);
3560 LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]);
3561 CITRA_IGNORE_EXIT(-1);
3562 }
3563 inst_base = arm_instruction_trans[idx](inst, idx);
3564translated:
3565 phys_addr += inst_size;
3566
3567 if ((phys_addr & 0xfff) == 0) {
3568 inst_base->br = END_OF_PAGE;
3569 }
3570 ret = inst_base->br;
3571 };
3572 insert_bb(pc_start, bb_start);
3573 return KEEP_GOING;
3574}
3575
3576#define LOG_IN_CLR skyeye_printf_in_color
3577
3578int cmp(const void *x, const void *y) {
3579 return *(unsigned long long int*)x - *(unsigned long long int *)y;
3580}
3581
3582void InterpreterInitInstLength(unsigned long long int *ptr, size_t size) {
3583 int array_size = size / sizeof(void *);
3584 unsigned long long int *InstLabel = new unsigned long long int[array_size];
3585 memcpy(InstLabel, ptr, size);
3586 qsort(InstLabel, array_size, sizeof(void *), cmp);
3587 InstLength = new unsigned int[array_size - 4];
3588 for (int i = 0; i < array_size - 4; i ++) {
3589 for (int j = 0; j < array_size; j ++) {
3590 if (ptr[i] == InstLabel[j]) {
3591 InstLength[i] = InstLabel[j + 1] - InstLabel[j];
3592 break;
3593 }
3594 }
3595 }
3596 for (int i = 0; i < array_size - 4; i ++)
3597 LOG_DEBUG(Core_ARM11, "[%d]:%d", i, InstLength[i]);
3687} 3598}
3688 3599
3689void InterpreterInitInstLength(unsigned long long int *ptr, size_t size) 3600int clz(unsigned int x) {
3690{ 3601 int n;
3691 int array_size = size / sizeof(void *); 3602 if (x == 0) return (32);
3692 unsigned long long int *InstLabel = new unsigned long long int[array_size]; 3603 n = 1;
3693 memcpy(InstLabel, ptr, size); 3604 if ((x >> 16) == 0) { n = n + 16; x = x << 16;}
3694 qsort(InstLabel, array_size, sizeof(void *), cmp); 3605 if ((x >> 24) == 0) { n = n + 8; x = x << 8;}
3695 InstLength = new unsigned int[array_size - 4]; 3606 if ((x >> 28) == 0) { n = n + 4; x = x << 4;}
3696 for (int i = 0; i < array_size - 4; i ++) { 3607 if ((x >> 30) == 0) { n = n + 2; x = x << 2;}
3697 for (int j = 0; j < array_size; j ++) { 3608 n = n - (x >> 31);
3698 if (ptr[i] == InstLabel[j]) { 3609 return n;
3699 InstLength[i] = InstLabel[j + 1] - InstLabel[j];
3700 break;
3701 }
3702 }
3703 }
3704 for (int i = 0; i < array_size - 4; i ++)
3705 DEBUG_LOG(ARM11, "[%d]:%d\n", i, InstLength[i]);
3706}
3707
3708int clz(unsigned int x)
3709{
3710 int n;
3711 if (x == 0) return (32);
3712 n = 1;
3713 if ((x >> 16) == 0) { n = n + 16; x = x << 16;}
3714 if ((x >> 24) == 0) { n = n + 8; x = x << 8;}
3715 if ((x >> 28) == 0) { n = n + 4; x = x << 4;}
3716 if ((x >> 30) == 0) { n = n + 2; x = x << 2;}
3717 n = n - (x >> 31);
3718 return n;
3719} 3610}
3720 3611
3721unsigned arm_dyncom_SWI (ARMul_State * state, ARMword number); 3612unsigned arm_dyncom_SWI (ARMul_State * state, ARMword number);
3722 3613
3723static bool InAPrivilegedMode(arm_core_t *core) 3614static bool InAPrivilegedMode(arm_core_t *core) {
3724{ 3615 return (core->Mode != USER32MODE);
3725 return (core->Mode != USER32MODE);
3726} 3616}
3727 3617
3728/* r15 = r15 + 8 */ 3618unsigned InterpreterMainLoop(ARMul_State* state) {
3729unsigned InterpreterMainLoop(ARMul_State* state) 3619 #define CRn inst_cream->crn
3730{ 3620 #define OPCODE_2 inst_cream->opcode_2
3731 #define CRn inst_cream->crn 3621 #define CRm inst_cream->crm
3732 #define OPCODE_2 inst_cream->opcode_2 3622 #define CP15_REG(n) cpu->CP15[CP15(n)]
3733 #define CRm inst_cream->crm 3623 #define RD cpu->Reg[inst_cream->Rd]
3734 #define CP15_REG(n) cpu->CP15[CP15(n)] 3624 #define RN cpu->Reg[inst_cream->Rn]
3735 #define RD cpu->Reg[inst_cream->Rd] 3625 #define RM cpu->Reg[inst_cream->Rm]
3736 #define RN cpu->Reg[inst_cream->Rn] 3626 #define RS cpu->Reg[inst_cream->Rs]
3737 #define RM cpu->Reg[inst_cream->Rm] 3627 #define RDHI cpu->Reg[inst_cream->RdHi]
3738 #define RS cpu->Reg[inst_cream->Rs] 3628 #define RDLO cpu->Reg[inst_cream->RdLo]
3739 #define RDHI cpu->Reg[inst_cream->RdHi] 3629 #define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4)
3740 #define RDLO cpu->Reg[inst_cream->RdLo] 3630 #define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24)
3741 #define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4) 3631 #define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand)
3742 #define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24) 3632
3743 #define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand) 3633 #define FETCH_INST if (inst_base->br != NON_BRANCH) goto DISPATCH; \
3744 3634 inst_base = (arm_inst *)&inst_buf[ptr]
3745 #if ENABLE_ICOUNTER 3635
3746 #define INC_ICOUNTER cpu->icounter++; \ 3636 #define INC_PC(l) ptr += sizeof(arm_inst) + l
3747 if(cpu->Reg[15] > 0xc0000000) \
3748 cpu->kernel_icounter++;
3749 //if (debug_function(core)) \
3750 if (core->check_int_flag) \
3751 goto END
3752 //DEBUG_LOG(ARM11, "icounter is %llx line is %d pc is %x\n", cpu->icounter, __LINE__, cpu->Reg[15])
3753 #else
3754 #define INC_ICOUNTER ;
3755 #endif
3756
3757 #define FETCH_INST if (inst_base->br != NON_BRANCH) \
3758 goto DISPATCH; \
3759 inst_base = (arm_inst *)&inst_buf[ptr]
3760#define INC_PC(l) ptr += sizeof(arm_inst) + l
3761 3637
3762// GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a 3638// GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a
3763// clunky switch statement. 3639// clunky switch statement.
@@ -3898,7 +3774,7 @@ unsigned InterpreterMainLoop(ARMul_State* state)
3898 case 124: goto PKHTB_INST; \ 3774 case 124: goto PKHTB_INST; \
3899 case 125: goto PKHBT_INST; \ 3775 case 125: goto PKHBT_INST; \
3900 case 126: goto SMUL_INST; \ 3776 case 126: goto SMUL_INST; \
3901 case 127: goto SMLAL_INST; \ 3777 case 127: goto SMLALXY_INST; \
3902 case 128: goto SMLA_INST; \ 3778 case 128: goto SMLA_INST; \
3903 case 129: goto MCRR_INST; \ 3779 case 129: goto MCRR_INST; \
3904 case 130: goto MRRC_INST; \ 3780 case 130: goto MRRC_INST; \
@@ -3967,2606 +3843,2586 @@ unsigned InterpreterMainLoop(ARMul_State* state)
3967 } 3843 }
3968#endif 3844#endif
3969 3845
3970 #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0) 3846 #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0)
3971 #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1) 3847 #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1)
3972// #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((ISNEG(lop) && ISPOS(rop)) || \ 3848
3973 (ISNEG(lop) && ISPOS(dst)) || \ 3849 #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((dst < lop) || (dst < rop)))
3974 (ISPOS(rop) && ISPOS(dst)))) 3850 #define UPDATE_CFLAG_CARRY_FROM_ADD(lop, rop, flag) (cpu->CFlag = (((uint64_t) lop + (uint64_t) rop + (uint64_t) flag) > 0xffffffff) )
3975 #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((dst < lop) || (dst < rop))) 3851 #define UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(lop, rop, flag) (cpu->CFlag = ((uint64_t) lop >= ((uint64_t) rop + (uint64_t) flag)))
3976 #define UPDATE_CFLAG_CARRY_FROM_ADD(lop, rop, flag) (cpu->CFlag = (((uint64_t) lop + (uint64_t) rop + (uint64_t) flag) > 0xffffffff) ) 3852 #define UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop) (cpu->CFlag = (lop >= rop))
3977 #define UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(lop, rop, flag) (cpu->CFlag = ((uint64_t) lop >= ((uint64_t) rop + (uint64_t) flag))) 3853 #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) (cpu->CFlag = !(dst < lop))
3978 #define UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop) (cpu->CFlag = (lop >= rop)) 3854 #define UPDATE_CFLAG_WITH_SC (cpu->CFlag = cpu->shifter_carry_out)
3979 #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) (cpu->CFlag = !(dst < lop)) 3855
3980 #define UPDATE_CFLAG_WITH_SC cpu->CFlag = cpu->shifter_carry_out 3856 #define UPDATE_VFLAG(dst, lop, rop) (cpu->VFlag = (((lop < 0) && (rop < 0) && (dst >= 0)) || \
3981// #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || \ 3857 ((lop >= 0) && (rop) >= 0 && (dst < 0))))
3982 (ISNEG(lop) && ISPOS(dst)) || \ 3858 #define UPDATE_VFLAG_WITH_NOT(dst, lop, rop) (cpu->VFlag = !(((lop < 0) && (rop < 0) && (dst >= 0)) || \
3983 (ISPOS(rop) && ISPOS(dst))) 3859 ((lop >= 0) && (rop) >= 0 && (dst < 0))))
3984 #define UPDATE_VFLAG(dst, lop, rop) (cpu->VFlag = (((lop < 0) && (rop < 0) && (dst >= 0)) || \ 3860 #define UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop) (cpu->VFlag = (((lop ^ rop) & (lop ^ dst)) >> 31))
3985 ((lop >= 0) && (rop) >= 0 && (dst < 0)))) 3861
3986 #define UPDATE_VFLAG_WITH_NOT(dst, lop, rop) (cpu->VFlag = !(((lop < 0) && (rop < 0) && (dst >= 0)) || \ 3862 #define SAVE_NZCVT cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \
3987 ((lop >= 0) && (rop) >= 0 && (dst < 0)))) 3863 (cpu->NFlag << 31) | \
3988 #define UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop) (cpu->VFlag = (((lop ^ rop) & (lop ^ dst)) >> 31)) 3864 (cpu->ZFlag << 30) | \
3989 3865 (cpu->CFlag << 29) | \
3990 #define SAVE_NZCVT cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \ 3866 (cpu->VFlag << 28) | \
3991 (cpu->NFlag << 31) | \ 3867 (cpu->TFlag << 5)
3992 (cpu->ZFlag << 30) | \ 3868 #define LOAD_NZCVT cpu->NFlag = (cpu->Cpsr >> 31); \
3993 (cpu->CFlag << 29) | \ 3869 cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \
3994 (cpu->VFlag << 28) | \ 3870 cpu->CFlag = (cpu->Cpsr >> 29) & 1; \
3995 (cpu->TFlag << 5) 3871 cpu->VFlag = (cpu->Cpsr >> 28) & 1; \
3996 #define LOAD_NZCVT cpu->NFlag = (cpu->Cpsr >> 31); \ 3872 cpu->TFlag = (cpu->Cpsr >> 5) & 1;
3997 cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \ 3873
3998 cpu->CFlag = (cpu->Cpsr >> 29) & 1; \ 3874 #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE)
3999 cpu->VFlag = (cpu->Cpsr >> 28) & 1; \ 3875 #define PC (cpu->Reg[15])
4000 cpu->TFlag = (cpu->Cpsr >> 5) & 1; 3876 #define CHECK_EXT_INT if (!cpu->NirqSig && !(cpu->Cpsr & 0x80)) goto END;
4001 3877
4002 #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE) 3878 arm_processor *cpu = state;
4003 #define PC (cpu->Reg[15])
4004 #define CHECK_EXT_INT if (!cpu->NirqSig) { \
4005 if (!(cpu->Cpsr & 0x80)) { \
4006 goto END; \
4007 } \
4008 }
4009
4010
4011
4012 //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t");
4013 arm_processor *cpu = state; //(arm_processor *)(core->cpu_data->obj);
4014 3879
4015 // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback 3880 // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback
4016 // to a clunky switch statement. 3881 // to a clunky switch statement.
4017#if defined __GNUC__ || defined __clang__ 3882#if defined __GNUC__ || defined __clang__
4018 void *InstLabel[] = { 3883 void *InstLabel[] = {
4019 #define VFP_INTERPRETER_LABEL 3884 &&VMLA_INST, &&VMLS_INST, &&VNMLA_INST, &&VNMLA_INST, &&VNMLS_INST, &&VNMUL_INST, &&VMUL_INST, &&VADD_INST, &&VSUB_INST,
4020 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 3885 &&VDIV_INST, &&VMOVI_INST, &&VMOVR_INST, &&VABS_INST, &&VNEG_INST, &&VSQRT_INST, &&VCMP_INST, &&VCMP2_INST, &&VCVTBDS_INST,
4021 #undef VFP_INTERPRETER_LABEL 3886 &&VCVTBFF_INST, &&VCVTBFI_INST, &&VMOVBRS_INST, &&VMSR_INST, &&VMOVBRC_INST, &&VMRS_INST, &&VMOVBCR_INST, &&VMOVBRRSS_INST,
4022 &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST, 3887 &&VMOVBRRD_INST, &&VSTR_INST, &&VPUSH_INST, &&VSTM_INST, &&VPOP_INST, &&VLDR_INST, &&VLDM_INST,
4023 &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST, 3888
4024 &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST, 3889 &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST,
4025 &&SHADD8_INST,&&SHADD16_INST,&&SEL_INST,&&SADDSUBX_INST,&&SADD8_INST,&&SADD16_INST,&&SHSUB16_INST,&&UMAAL_INST,&&UXTAB16_INST, 3890 &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST,
4026 &&USUBADDX_INST,&&USUB8_INST,&&USUB16_INST,&&USAT16_INST,&&USADA8_INST,&&UQSUBADDX_INST,&&UQSUB8_INST,&&UQSUB16_INST, 3891 &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST,
4027 &&UQADDSUBX_INST,&&UQADD8_INST,&&UQADD16_INST,&&SXTAB_INST,&&UHSUBADDX_INST,&&UHSUB8_INST,&&UHSUB16_INST,&&UHADDSUBX_INST,&&UHADD8_INST, 3892 &&SHADD8_INST,&&SHADD16_INST,&&SEL_INST,&&SADDSUBX_INST,&&SADD8_INST,&&SADD16_INST,&&SHSUB16_INST,&&UMAAL_INST,&&UXTAB16_INST,
4028 &&UHADD16_INST,&&UADDSUBX_INST,&&UADD8_INST,&&UADD16_INST,&&SXTAH_INST,&&SXTAB16_INST,&&QADD8_INST,&&BXJ_INST,&&CLZ_INST,&&UXTAH_INST, 3893 &&USUBADDX_INST,&&USUB8_INST,&&USUB16_INST,&&USAT16_INST,&&USADA8_INST,&&UQSUBADDX_INST,&&UQSUB8_INST,&&UQSUB16_INST,
4029 &&BX_INST,&&REV_INST,&&BLX_INST,&&REVSH_INST,&&QADD_INST,&&QADD16_INST,&&QADDSUBX_INST,&&LDREX_INST,&&QDADD_INST,&&QDSUB_INST, 3894 &&UQADDSUBX_INST,&&UQADD8_INST,&&UQADD16_INST,&&SXTAB_INST,&&UHSUBADDX_INST,&&UHSUB8_INST,&&UHSUB16_INST,&&UHADDSUBX_INST,&&UHADD8_INST,
4030 &&QSUB_INST,&&LDREXB_INST,&&QSUB8_INST,&&QSUB16_INST,&&SMUAD_INST,&&SMMUL_INST,&&SMUSD_INST,&&SMLSD_INST,&&SMLSLD_INST,&&SMMLA_INST, 3895 &&UHADD16_INST,&&UADDSUBX_INST,&&UADD8_INST,&&UADD16_INST,&&SXTAH_INST,&&SXTAB16_INST,&&QADD8_INST,&&BXJ_INST,&&CLZ_INST,&&UXTAH_INST,
4031 &&SMMLS_INST,&&SMLALD_INST,&&SMLAD_INST,&&SMLAW_INST,&&SMULW_INST,&&PKHTB_INST,&&PKHBT_INST,&&SMUL_INST,&&SMLAL_INST,&&SMLA_INST, 3896 &&BX_INST,&&REV_INST,&&BLX_INST,&&REVSH_INST,&&QADD_INST,&&QADD16_INST,&&QADDSUBX_INST,&&LDREX_INST,&&QDADD_INST,&&QDSUB_INST,
4032 &&MCRR_INST,&&MRRC_INST,&&CMP_INST,&&TST_INST,&&TEQ_INST,&&CMN_INST,&&SMULL_INST,&&UMULL_INST,&&UMLAL_INST,&&SMLAL_INST,&&MUL_INST, 3897 &&QSUB_INST,&&LDREXB_INST,&&QSUB8_INST,&&QSUB16_INST,&&SMUAD_INST,&&SMMUL_INST,&&SMUSD_INST,&&SMLSD_INST,&&SMLSLD_INST,&&SMMLA_INST,
4033 &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST, 3898 &&SMMLS_INST,&&SMLALD_INST,&&SMLAD_INST,&&SMLAW_INST,&&SMULW_INST,&&PKHTB_INST,&&PKHBT_INST,&&SMUL_INST,&&SMLALXY_INST,&&SMLA_INST,
4034 &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST, 3899 &&MCRR_INST,&&MRRC_INST,&&CMP_INST,&&TST_INST,&&TEQ_INST,&&CMN_INST,&&SMULL_INST,&&UMULL_INST,&&UMLAL_INST,&&SMLAL_INST,&&MUL_INST,
4035 &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST, 3900 &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST,
4036 &&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST,&&SWI_INST,&&BBL_INST,&&B_2_THUMB, &&B_COND_THUMB, 3901 &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST,
4037 &&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,&&INIT_INST_LENGTH,&&END 3902 &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST,
4038 }; 3903 &&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST,&&SWI_INST,&&BBL_INST,&&B_2_THUMB, &&B_COND_THUMB,
4039#endif 3904 &&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,&&INIT_INST_LENGTH,&&END
4040 arm_inst * inst_base; 3905 };
4041 unsigned int lop, rop, dst;
4042 unsigned int addr;
4043 unsigned int phys_addr;
4044 unsigned int last_pc = 0;
4045 unsigned int num_instrs = 0;
4046 fault_t fault;
4047 static unsigned int last_physical_base = 0, last_logical_base = 0;
4048 int ptr;
4049 bool single_step = (cpu->NumInstrsToExecute == 1);
4050
4051 LOAD_NZCVT;
4052 DISPATCH:
4053 {
4054 if (!cpu->NirqSig) {
4055 if (!(cpu->Cpsr & 0x80)) {
4056 goto END;
4057 }
4058 }
4059
4060 if (cpu->TFlag) {
4061 cpu->Reg[15] &= 0xfffffffe;
4062 } else
4063 cpu->Reg[15] &= 0xfffffffc;
4064#if PROFILE
4065 /* check next instruction address is valid. */
4066 last_pc = cpu->Reg[15];
4067#endif 3906#endif
4068#if USER_MODE_OPT 3907 arm_inst * inst_base;
4069 phys_addr = cpu->Reg[15]; 3908 unsigned int lop, rop, dst;
4070#else 3909 unsigned int addr;
4071 { 3910 unsigned int phys_addr;
4072 if (last_logical_base == (cpu->Reg[15] & 0xfffff000)) 3911 unsigned int last_pc = 0;
4073 phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff); 3912 unsigned int num_instrs = 0;
4074 else { 3913 fault_t fault;
4075 /* check next instruction address is valid. */ 3914 static unsigned int last_physical_base = 0, last_logical_base = 0;
4076 fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB); 3915 int ptr;
4077 if (fault) { 3916 bool single_step = (cpu->NumInstrsToExecute == 1);
4078 cpu->abortSig = true; 3917
4079 cpu->Aborted = ARMul_PrefetchAbortV; 3918 LOAD_NZCVT;
4080 cpu->AbortAddr = cpu->Reg[15]; 3919 DISPATCH:
4081 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; 3920 {
4082 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15]; 3921 if (!cpu->NirqSig) {
4083 goto END; 3922 if (!(cpu->Cpsr & 0x80)) {
4084 } 3923 goto END;
4085 last_logical_base = cpu->Reg[15] & 0xfffff000; 3924 }
4086 last_physical_base = phys_addr & 0xfffff000; 3925 }
4087 } 3926
4088 } 3927 if (cpu->TFlag)
4089#if HYBRID_MODE 3928 cpu->Reg[15] &= 0xfffffffe;
4090 /* check if the native code of dyncom is available */ 3929 else
4091 //fast_map hash_map = core->dyncom_engine->fmap; 3930 cpu->Reg[15] &= 0xfffffffc;
4092 //void * pfunc = NULL; 3931
4093 //PFUNC(phys_addr); 3932 phys_addr = cpu->Reg[15];
4094 //if(pfunc){ 3933
4095 if(is_translated_entry(core, phys_addr)){ 3934 if (find_bb(phys_addr, ptr) == -1)
4096 int rc = JIT_RETURN_NOERR;
4097 //DEBUG_LOG(ARM11, "enter jit icounter is %lld, pc=0x%x\n", core->icounter, cpu->Reg[15]);
4098 SAVE_NZCVT;
4099// resume_timing();
4100 rc = cpu_run(core);
4101 LOAD_NZCVT;
4102 //DEBUG_LOG(ARM11, "out of jit ret is %d icounter is %lld, pc=0x%x\n", rc, core->icounter, cpu->Reg[15]);
4103 if((rc == JIT_RETURN_FUNCNOTFOUND) || (rc == JIT_RETURN_FUNC_BLANK)){
4104 /* keep the tflag same with the bit in CPSR */
4105 //cpu->TFlag = cpu->Cpsr & (1 << THUMB_BIT);
4106 //cpu->TFlag = cpu->Cpsr & (1 << 5);
4107 //switch_mode(cpu, cpu->Cpsr & 0x1f);
4108 //DEBUG_LOG(ARM11, "FUNCTION not found , pc=0x%x\n", cpu->Reg[15]);
4109 fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB);
4110 if (fault) {
4111 cpu->abortSig = true;
4112 cpu->Aborted = ARMul_PrefetchAbortV;
4113 cpu->AbortAddr = cpu->Reg[15];
4114 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
4115 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15];
4116 goto END;
4117 }
4118 last_logical_base = cpu->Reg[15] & 0xfffff000;
4119 last_physical_base = phys_addr & 0xfffff000;
4120 core->current_page_phys = last_physical_base;
4121 core->current_page_effec = last_logical_base;
4122 //push_to_compiled(core, phys_addr);
4123 }
4124 else{
4125 if((cpu->CP15[CP15(CP15_TLB_FAULT_STATUS)] & 0xf0)){
4126 //DEBUG_LOG(ARM11, "\n\n###############In %s, fsr=0x%x, fault_addr=0x%x, pc=0x%x\n\n", __FUNCTION__, cpu->CP15[CP15(CP15_FAULT_STATUS)], cpu->CP15[CP15(CP15_FAULT_ADDRESS)], cpu->Reg[15]);
4127 //core->Reg[15] -= get_instr_size(cpu_dyncom);
4128 fill_tlb(cpu);
4129 goto END;
4130 }
4131 if (cpu->syscallSig) {
4132 goto END;
4133 }
4134 if (cpu->abortSig) {
4135 cpu->CP15[CP15_TLB_FAULT_STATUS - CP15_BASE] &= 0xFFFFFFF0;
4136 goto END;
4137 }
4138 if (!cpu->NirqSig) {
4139 if (!(cpu->Cpsr & 0x80)) {
4140 goto END;
4141 }
4142 }
4143
4144 /* if regular trap */
4145 cpu->Reg[15] += GET_INST_SIZE(cpu);
4146 /*uint32_t mode = cpu->Cpsr & 0x1f;
4147 if ((mode != cpu->Mode) && (!is_user_mode(core))) {
4148 switch_mode(cpu, mode);
4149 return 1;
4150 }*/
4151
4152 goto END;
4153 }
4154 //phys_addr = cpu->Reg[15];
4155 }
4156 else{
4157 if (last_logical_base == (cpu->Reg[15] & 0xfffff000))
4158 phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff);
4159 else {
4160 /* check next instruction address is valid. */
4161 fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB);
4162 if (fault) {
4163 cpu->abortSig = true;
4164 cpu->Aborted = ARMul_PrefetchAbortV;
4165 cpu->AbortAddr = cpu->Reg[15];
4166 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
4167 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15];
4168 goto END;
4169 }
4170 last_logical_base = cpu->Reg[15] & 0xfffff000;
4171 last_physical_base = phys_addr & 0xfffff000;
4172 }
4173 }
4174#endif /* #if HYBRID_MODE */
4175#endif /* #if USER_MODE_OPT */
4176 if (true){//if(is_fast_interp_code(core, phys_addr)){
4177 if (find_bb(phys_addr, ptr) == -1)
4178 if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
4179 goto END;
4180 }
4181 else{
4182 if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION) 3935 if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
4183 goto END; 3936 goto END;
4184 } 3937
4185#if PROFILE 3938 inst_base = (arm_inst *)&inst_buf[ptr];
4186 resume_timing(); 3939 GOTO_NEXT_INST;
4187#endif 3940 }
4188 inst_base = (arm_inst *)&inst_buf[ptr]; 3941 ADC_INST:
4189 GOTO_NEXT_INST; 3942 {
4190 } 3943 adc_inst *inst_cream = (adc_inst *)inst_base->component;
4191 ADC_INST: 3944 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4192 { 3945 lop = RN;
4193 INC_ICOUNTER; 3946 unsigned int sht_op = SHIFTER_OPERAND;
4194 adc_inst *inst_cream = (adc_inst *)inst_base->component; 3947 rop = SHIFTER_OPERAND + cpu->CFlag;
4195 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 3948 RD = dst = lop + rop;
4196 lop = RN; 3949 if (inst_cream->S && (inst_cream->Rd == 15)) {
4197 unsigned int sht_op = SHIFTER_OPERAND; 3950 if (CurrentModeHasSPSR) {
4198 rop = SHIFTER_OPERAND + cpu->CFlag; 3951 cpu->Cpsr = cpu->Spsr_copy;
4199 RD = dst = lop + rop; 3952 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
4200 if (inst_cream->S && (inst_cream->Rd == 15)) { 3953 LOAD_NZCVT;
4201 /* cpsr = spsr */ 3954 }
4202 if (CurrentModeHasSPSR) { 3955 } else if (inst_cream->S) {
4203 cpu->Cpsr = cpu->Spsr_copy; 3956 UPDATE_NFLAG(dst);
4204 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 3957 UPDATE_ZFLAG(dst);
4205 LOAD_NZCVT; 3958 UPDATE_CFLAG_CARRY_FROM_ADD(lop, sht_op, cpu->CFlag);
4206 } 3959 UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4207 } else if (inst_cream->S) { 3960 }
4208 UPDATE_NFLAG(dst); 3961 if (inst_cream->Rd == 15) {
4209 UPDATE_ZFLAG(dst); 3962 INC_PC(sizeof(adc_inst));
4210 UPDATE_CFLAG_CARRY_FROM_ADD(lop, sht_op, cpu->CFlag); 3963 goto DISPATCH;
4211 UPDATE_VFLAG((int)dst, (int)lop, (int)rop); 3964 }
4212 } 3965 }
4213 if (inst_cream->Rd == 15) { 3966 cpu->Reg[15] += GET_INST_SIZE(cpu);
4214 INC_PC(sizeof(adc_inst)); 3967 INC_PC(sizeof(adc_inst));
4215 goto DISPATCH; 3968 FETCH_INST;
4216 } 3969 GOTO_NEXT_INST;
4217 } 3970 }
4218 cpu->Reg[15] += GET_INST_SIZE(cpu); 3971 ADD_INST:
4219 INC_PC(sizeof(adc_inst)); 3972 {
4220 FETCH_INST; 3973 add_inst *inst_cream = (add_inst *)inst_base->component;
4221 GOTO_NEXT_INST; 3974 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4222 } 3975 lop = RN;
4223 ADD_INST: 3976 if (inst_cream->Rn == 15) {
4224 { 3977 lop += 2 * GET_INST_SIZE(cpu);
4225 INC_ICOUNTER; 3978 }
4226 add_inst *inst_cream = (add_inst *)inst_base->component; 3979 rop = SHIFTER_OPERAND;
4227 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 3980 RD = dst = lop + rop;
4228 lop = RN; 3981 if (inst_cream->S && (inst_cream->Rd == 15)) {
4229 if (inst_cream->Rn == 15) { 3982 if (CurrentModeHasSPSR) {
4230 lop += 2 * GET_INST_SIZE(cpu); 3983 cpu->Cpsr = cpu->Spsr_copy;
4231 } 3984 switch_mode(cpu, cpu->Cpsr & 0x1f);
4232 rop = SHIFTER_OPERAND; 3985 LOAD_NZCVT;
4233 RD = dst = lop + rop; 3986 }
4234 if (inst_cream->S && (inst_cream->Rd == 15)) { 3987 } else if (inst_cream->S) {
4235 /* cpsr = spsr*/ 3988 UPDATE_NFLAG(dst);
4236 if (CurrentModeHasSPSR) { 3989 UPDATE_ZFLAG(dst);
4237 cpu->Cpsr = cpu->Spsr_copy; 3990 UPDATE_CFLAG(dst, lop, rop);
4238 switch_mode(cpu, cpu->Cpsr & 0x1f); 3991 UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4239 LOAD_NZCVT; 3992 }
4240 } 3993 if (inst_cream->Rd == 15) {
4241 } else if (inst_cream->S) { 3994 INC_PC(sizeof(add_inst));
4242 UPDATE_NFLAG(dst); 3995 goto DISPATCH;
4243 UPDATE_ZFLAG(dst); 3996 }
4244 UPDATE_CFLAG(dst, lop, rop); 3997 }
4245 UPDATE_VFLAG((int)dst, (int)lop, (int)rop); 3998 cpu->Reg[15] += GET_INST_SIZE(cpu);
4246 } 3999 INC_PC(sizeof(add_inst));
4247 if (inst_cream->Rd == 15) { 4000 FETCH_INST;
4248 INC_PC(sizeof(add_inst)); 4001 GOTO_NEXT_INST;
4249 goto DISPATCH; 4002 }
4250 } 4003 AND_INST:
4251 } 4004 {
4252 cpu->Reg[15] += GET_INST_SIZE(cpu); 4005 and_inst *inst_cream = (and_inst *)inst_base->component;
4253 INC_PC(sizeof(add_inst)); 4006 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4254 FETCH_INST; 4007 lop = RN;
4255 GOTO_NEXT_INST; 4008 rop = SHIFTER_OPERAND;
4256 } 4009 RD = dst = lop & rop;
4257 AND_INST: 4010 if (inst_cream->S && (inst_cream->Rd == 15)) {
4258 { 4011 if (CurrentModeHasSPSR) {
4259 INC_ICOUNTER; 4012 cpu->Cpsr = cpu->Spsr_copy;
4260 and_inst *inst_cream = (and_inst *)inst_base->component; 4013 switch_mode(cpu, cpu->Cpsr & 0x1f);
4261 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4014 LOAD_NZCVT;
4262 lop = RN; 4015 }
4263 rop = SHIFTER_OPERAND; 4016 } else if (inst_cream->S) {
4264 RD = dst = lop & rop; 4017 UPDATE_NFLAG(dst);
4265 if (inst_cream->S && (inst_cream->Rd == 15)) { 4018 UPDATE_ZFLAG(dst);
4266 /* cpsr = spsr*/ 4019 UPDATE_CFLAG_WITH_SC;
4267 if (CurrentModeHasSPSR) { 4020 }
4268 cpu->Cpsr = cpu->Spsr_copy; 4021 if (inst_cream->Rd == 15) {
4269 switch_mode(cpu, cpu->Cpsr & 0x1f); 4022 INC_PC(sizeof(and_inst));
4270 LOAD_NZCVT; 4023 goto DISPATCH;
4271 } 4024 }
4272 } else if (inst_cream->S) { 4025 }
4273 UPDATE_NFLAG(dst); 4026 cpu->Reg[15] += GET_INST_SIZE(cpu);
4274 UPDATE_ZFLAG(dst); 4027 INC_PC(sizeof(and_inst));
4275 UPDATE_CFLAG_WITH_SC; 4028 FETCH_INST;
4276 //UPDATE_VFLAG((int)dst, (int)lop, (int)rop); 4029 GOTO_NEXT_INST;
4277 } 4030 }
4278 if (inst_cream->Rd == 15) { 4031 BBL_INST:
4279 INC_PC(sizeof(and_inst)); 4032 {
4280 goto DISPATCH; 4033 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4281 } 4034 bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
4282 } 4035 if (inst_cream->L) {
4283 cpu->Reg[15] += GET_INST_SIZE(cpu); 4036 LINK_RTN_ADDR;
4284 INC_PC(sizeof(and_inst)); 4037 }
4285 FETCH_INST; 4038 SET_PC;
4286 GOTO_NEXT_INST; 4039 INC_PC(sizeof(bbl_inst));
4287 } 4040 goto DISPATCH;
4288 BBL_INST: 4041 }
4289 { 4042 cpu->Reg[15] += GET_INST_SIZE(cpu);
4290 INC_ICOUNTER; 4043 INC_PC(sizeof(bbl_inst));
4291 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4044 goto DISPATCH;
4292 bbl_inst *inst_cream = (bbl_inst *)inst_base->component; 4045 }
4293 if (inst_cream->L) { 4046 BIC_INST:
4294 LINK_RTN_ADDR; 4047 {
4295 } 4048 bic_inst *inst_cream = (bic_inst *)inst_base->component;
4296 SET_PC; 4049 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4297 INC_PC(sizeof(bbl_inst)); 4050 lop = RN;
4298 goto DISPATCH; 4051 if (inst_cream->Rn == 15) {
4299 } 4052 lop += 2 * GET_INST_SIZE(cpu);
4300 cpu->Reg[15] += GET_INST_SIZE(cpu); 4053 }
4301 INC_PC(sizeof(bbl_inst)); 4054 rop = SHIFTER_OPERAND;
4302 goto DISPATCH; 4055 RD = dst = lop & (~rop);
4303 } 4056 if ((inst_cream->S) && (inst_cream->Rd == 15)) {
4304 BIC_INST: 4057 if (CurrentModeHasSPSR) {
4305 { 4058 cpu->Cpsr = cpu->Spsr_copy;
4306 INC_ICOUNTER; 4059 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
4307 bic_inst *inst_cream = (bic_inst *)inst_base->component; 4060 LOAD_NZCVT;
4308 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4061 }
4309 lop = RN; 4062 } else if (inst_cream->S) {
4310 if (inst_cream->Rn == 15) { 4063 UPDATE_NFLAG(dst);
4311 lop += 2 * GET_INST_SIZE(cpu); 4064 UPDATE_ZFLAG(dst);
4312 } 4065 UPDATE_CFLAG_WITH_SC;
4313 rop = SHIFTER_OPERAND; 4066 }
4314// RD = dst = lop & (rop ^ 0xffffffff); 4067 if (inst_cream->Rd == 15) {
4315 RD = dst = lop & (~rop); 4068 INC_PC(sizeof(bic_inst));
4316 if ((inst_cream->S) && (inst_cream->Rd == 15)) { 4069 goto DISPATCH;
4317 /* cpsr = spsr */ 4070 }
4318 if (CurrentModeHasSPSR) { 4071 }
4319 cpu->Cpsr = cpu->Spsr_copy; 4072 cpu->Reg[15] += GET_INST_SIZE(cpu);
4320 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 4073 INC_PC(sizeof(bic_inst));
4321 LOAD_NZCVT; 4074 FETCH_INST;
4322 } 4075 GOTO_NEXT_INST;
4323 } else if (inst_cream->S) { 4076 }
4324 UPDATE_NFLAG(dst); 4077 BKPT_INST:
4325 UPDATE_ZFLAG(dst); 4078 BLX_INST:
4326 UPDATE_CFLAG_WITH_SC; 4079 {
4327 } 4080 blx_inst *inst_cream = (blx_inst *)inst_base->component;
4328 if (inst_cream->Rd == 15) { 4081 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4329 INC_PC(sizeof(bic_inst)); 4082 unsigned int inst = inst_cream->inst;
4330 goto DISPATCH; 4083 if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
4331 } 4084 cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
4332 } 4085 if(cpu->TFlag)
4333 cpu->Reg[15] += GET_INST_SIZE(cpu); 4086 cpu->Reg[14] |= 0x1;
4334 INC_PC(sizeof(bic_inst)); 4087 cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe;
4335 FETCH_INST; 4088 cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1;
4336 GOTO_NEXT_INST; 4089 } else {
4337 } 4090 cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
4338 BKPT_INST: 4091 cpu->TFlag = 0x1;
4339 BLX_INST: 4092 int signed_int = inst_cream->val.signed_immed_24;
4340 { 4093 signed_int = (signed_int) & 0x800000 ? (0x3F000000 | signed_int) : signed_int;
4341 INC_ICOUNTER; 4094 signed_int = signed_int << 2;
4342 blx_inst *inst_cream = (blx_inst *)inst_base->component; 4095 cpu->Reg[15] = cpu->Reg[15] + 8 + signed_int + (BIT(inst, 24) << 1);
4343 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4096 }
4344 unsigned int inst = inst_cream->inst; 4097 INC_PC(sizeof(blx_inst));
4345 if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { 4098 goto DISPATCH;
4346 //LINK_RTN_ADDR; 4099 }
4347 cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); 4100 cpu->Reg[15] += GET_INST_SIZE(cpu);
4348 if(cpu->TFlag) 4101 INC_PC(sizeof(blx_inst));
4349 cpu->Reg[14] |= 0x1; 4102 goto DISPATCH;
4350 cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe; 4103 }
4351 cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1; 4104 BX_INST:
4352 //cpu->Reg[15] = cpu->Reg[BITS(inst, 0, 3)] & 0xfffffffe; 4105 {
4353 //cpu->TFlag = cpu->Reg[BITS(inst, 0, 3)] & 0x1; 4106 bx_inst *inst_cream = (bx_inst *)inst_base->component;
4354 } else { 4107 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4355 cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); 4108 if (inst_cream->Rm == 15)
4356 cpu->TFlag = 0x1; 4109 LOG_WARNING(Core_ARM11, "BX at pc %x: use of Rm = R15 is discouraged", cpu->Reg[15]);
4357 int signed_int = inst_cream->val.signed_immed_24; 4110 cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1;
4358 signed_int = (signed_int) & 0x800000 ? (0x3F000000 | signed_int) : signed_int; 4111 cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe;
4359 signed_int = signed_int << 2; 4112 INC_PC(sizeof(bx_inst));
4360 // cpu->Reg[15] = cpu->Reg[15] + 2 * GET_INST_SIZE(cpu) 4113 goto DISPATCH;
4361 cpu->Reg[15] = cpu->Reg[15] + 8 4114 }
4362 + signed_int + (BIT(inst, 24) << 1); 4115 cpu->Reg[15] += GET_INST_SIZE(cpu);
4363 //DEBUG_MSG; 4116 INC_PC(sizeof(bx_inst));
4364 } 4117 goto DISPATCH;
4365 INC_PC(sizeof(blx_inst)); 4118 }
4366 goto DISPATCH; 4119 BXJ_INST:
4367 } 4120 CDP_INST:
4368 cpu->Reg[15] += GET_INST_SIZE(cpu); 4121 {
4369// INC_PC(sizeof(bx_inst)); 4122 cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
4370 INC_PC(sizeof(blx_inst)); 4123 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4371 goto DISPATCH; 4124 // Undefined instruction here
4372 } 4125 cpu->NumInstrsToExecute = 0;
4373 BX_INST: 4126 return num_instrs;
4374 { 4127 }
4375 INC_ICOUNTER; 4128 cpu->Reg[15] += GET_INST_SIZE(cpu);
4376 bx_inst *inst_cream = (bx_inst *)inst_base->component; 4129 INC_PC(sizeof(cdp_inst));
4377 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4130 FETCH_INST;
4378 if (inst_cream->Rm == 15) 4131 GOTO_NEXT_INST;
4379 DEBUG_LOG(ARM11, "In %s, BX at pc %x: use of Rm = R15 is discouraged\n", __FUNCTION__, cpu->Reg[15]); 4132 }
4380 cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1; 4133
4381 cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe; 4134 CLREX_INST:
4382// cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1; 4135 {
4383 INC_PC(sizeof(bx_inst)); 4136 remove_exclusive(cpu, 0);
4384 goto DISPATCH; 4137 cpu->exclusive_state = 0;
4385 } 4138
4386 cpu->Reg[15] += GET_INST_SIZE(cpu); 4139 cpu->Reg[15] += GET_INST_SIZE(cpu);
4387// INC_PC(sizeof(bx_inst)); 4140 INC_PC(sizeof(clrex_inst));
4388 INC_PC(sizeof(bx_inst)); 4141 FETCH_INST;
4389 goto DISPATCH; 4142 GOTO_NEXT_INST;
4390 } 4143 }
4391 BXJ_INST: 4144 CLZ_INST:
4392 CDP_INST: 4145 {
4393 { 4146 clz_inst *inst_cream = (clz_inst *)inst_base->component;
4394 INC_ICOUNTER; 4147 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4395 cdp_inst *inst_cream = (cdp_inst *)inst_base->component; 4148 RD = clz(RM);
4396 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4149 }
4397 /* FIXME, check if cp access allowed */ 4150 cpu->Reg[15] += GET_INST_SIZE(cpu);
4398 #define CP_ACCESS_ALLOW 0 4151 INC_PC(sizeof(clz_inst));
4399 if(CP_ACCESS_ALLOW){ 4152 FETCH_INST;
4400 /* undefined instruction here */ 4153 GOTO_NEXT_INST;
4401 cpu->NumInstrsToExecute = 0; 4154 }
4402 return num_instrs; 4155 CMN_INST:
4403 } 4156 {
4404 ERROR_LOG(ARM11, "CDP insn inst=0x%x, pc=0x%x\n", inst_cream->inst, cpu->Reg[15]); 4157 cmn_inst *inst_cream = (cmn_inst *)inst_base->component;
4405 unsigned cpab = (cpu->CDP[inst_cream->cp_num]) (cpu, ARMul_FIRST, inst_cream->inst); 4158 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4406 if(cpab != ARMul_DONE){ 4159 lop = RN;
4407 ERROR_LOG(ARM11, "CDP insn wrong, inst=0x%x, cp_num=0x%x\n", inst_cream->inst, inst_cream->cp_num); 4160 rop = SHIFTER_OPERAND;
4408 //CITRA_IGNORE_EXIT(-1); 4161 dst = lop + rop;
4409 } 4162 UPDATE_NFLAG(dst);
4410 } 4163 UPDATE_ZFLAG(dst);
4411 cpu->Reg[15] += GET_INST_SIZE(cpu); 4164 UPDATE_CFLAG(dst, lop, rop);
4412 INC_PC(sizeof(cdp_inst)); 4165 UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4413 FETCH_INST; 4166 }
4414 GOTO_NEXT_INST; 4167 cpu->Reg[15] += GET_INST_SIZE(cpu);
4415 } 4168 INC_PC(sizeof(cmn_inst));
4416 4169 FETCH_INST;
4417 CLREX_INST: 4170 GOTO_NEXT_INST;
4418 { 4171 }
4419 INC_ICOUNTER; 4172 CMP_INST:
4420 remove_exclusive(cpu, 0); 4173 {
4421 cpu->exclusive_state = 0; 4174 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4422 4175 cmp_inst *inst_cream = (cmp_inst *)inst_base->component;
4423 cpu->Reg[15] += GET_INST_SIZE(cpu); 4176 lop = RN;
4424 INC_PC(sizeof(clrex_inst)); 4177 if (inst_cream->Rn == 15) {
4425 FETCH_INST; 4178 lop += 2 * GET_INST_SIZE(cpu);
4426 GOTO_NEXT_INST; 4179 }
4427 } 4180 rop = SHIFTER_OPERAND;
4428 CLZ_INST: 4181 dst = lop - rop;
4429 { 4182
4430 INC_ICOUNTER; 4183 UPDATE_NFLAG(dst);
4431 clz_inst *inst_cream = (clz_inst *)inst_base->component; 4184 UPDATE_ZFLAG(dst);
4432 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4185 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
4433 RD = clz(RM); 4186 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
4434 } 4187 }
4435 cpu->Reg[15] += GET_INST_SIZE(cpu); 4188 cpu->Reg[15] += GET_INST_SIZE(cpu);
4436 INC_PC(sizeof(clz_inst)); 4189 INC_PC(sizeof(cmp_inst));
4437 FETCH_INST; 4190 FETCH_INST;
4438 GOTO_NEXT_INST; 4191 GOTO_NEXT_INST;
4439 } 4192 }
4440 CMN_INST: 4193 CPS_INST:
4441 { 4194 {
4442 INC_ICOUNTER; 4195 cps_inst *inst_cream = (cps_inst *)inst_base->component;
4443 cmn_inst *inst_cream = (cmn_inst *)inst_base->component; 4196 uint32_t aif_val = 0;
4444 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4197 uint32_t aif_mask = 0;
4445// DEBUG_LOG(ARM11, "RN is %x\n", RN); 4198 if (InAPrivilegedMode(cpu)) {
4446 lop = RN; 4199 if (inst_cream->imod1) {
4447 rop = SHIFTER_OPERAND; 4200 if (inst_cream->A) {
4448 dst = lop + rop; 4201 aif_val |= (inst_cream->imod0 << 8);
4449 UPDATE_NFLAG(dst); 4202 aif_mask |= 1 << 8;
4450 UPDATE_ZFLAG(dst); 4203 }
4451 UPDATE_CFLAG(dst, lop, rop); 4204 if (inst_cream->I) {
4452 UPDATE_VFLAG((int)dst, (int)lop, (int)rop); 4205 aif_val |= (inst_cream->imod0 << 7);
4453 } 4206 aif_mask |= 1 << 7;
4454 cpu->Reg[15] += GET_INST_SIZE(cpu); 4207 }
4455 INC_PC(sizeof(cmn_inst)); 4208 if (inst_cream->F) {
4456 FETCH_INST; 4209 aif_val |= (inst_cream->imod0 << 6);
4457 GOTO_NEXT_INST; 4210 aif_mask |= 1 << 6;
4458 } 4211 }
4459 CMP_INST: 4212 aif_mask = ~aif_mask;
4460 { 4213 cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val;
4461// DEBUG_LOG(ARM11, "cmp inst\n"); 4214 }
4462// DEBUG_LOG(ARM11, "pc: %x\n", cpu->Reg[15]); 4215 if (inst_cream->mmod) {
4463 INC_ICOUNTER; 4216 cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode;
4464 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4217 switch_mode(cpu, inst_cream->mode);
4465// DEBUG_LOG(ARM11, "r0 is %x\n", cpu->Reg[0]); 4218 }
4466 cmp_inst *inst_cream = (cmp_inst *)inst_base->component; 4219 }
4467 lop = RN; 4220 cpu->Reg[15] += GET_INST_SIZE(cpu);
4468 if (inst_cream->Rn == 15) { 4221 INC_PC(sizeof(cps_inst));
4469 lop += 2 * GET_INST_SIZE(cpu); 4222 FETCH_INST;
4470 } 4223 GOTO_NEXT_INST;
4471 rop = SHIFTER_OPERAND; 4224 }
4472 dst = lop - rop; 4225 CPY_INST:
4473 4226 {
4474 UPDATE_NFLAG(dst); 4227 mov_inst *inst_cream = (mov_inst *)inst_base->component;
4475 UPDATE_ZFLAG(dst); 4228 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4476// UPDATE_CFLAG(dst, lop, rop); 4229 RD = SHIFTER_OPERAND;
4477 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); 4230 if ((inst_cream->Rd == 15)) {
4478// UPDATE_VFLAG((int)dst, (int)lop, (int)rop); 4231 INC_PC(sizeof(mov_inst));
4479 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); 4232 goto DISPATCH;
4480// UPDATE_VFLAG_WITH_NOT(dst, lop, rop); 4233 }
4481 } 4234 }
4482 cpu->Reg[15] += GET_INST_SIZE(cpu); 4235 cpu->Reg[15] += GET_INST_SIZE(cpu);
4483 INC_PC(sizeof(cmp_inst)); 4236 INC_PC(sizeof(mov_inst));
4484 FETCH_INST; 4237 FETCH_INST;
4485 GOTO_NEXT_INST; 4238 GOTO_NEXT_INST;
4486 } 4239 }
4487 CPS_INST: 4240 EOR_INST:
4488 { 4241 {
4489 INC_ICOUNTER; 4242 eor_inst *inst_cream = (eor_inst *)inst_base->component;
4490 cps_inst *inst_cream = (cps_inst *)inst_base->component; 4243 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4491 uint32_t aif_val = 0; 4244 lop = RN;
4492 uint32_t aif_mask = 0; 4245 if (inst_cream->Rn == 15) {
4493 if (InAPrivilegedMode(cpu)) { 4246 lop += 2 * GET_INST_SIZE(cpu);
4494 /* isInAPrivilegedMode */ 4247 }
4495 if (inst_cream->imod1) { 4248 rop = SHIFTER_OPERAND;
4496 if (inst_cream->A) { 4249 RD = dst = lop ^ rop;
4497 aif_val |= (inst_cream->imod0 << 8); 4250 if (inst_cream->S && (inst_cream->Rd == 15)) {
4498 aif_mask |= 1 << 8; 4251 if (CurrentModeHasSPSR) {
4499 } 4252 cpu->Cpsr = cpu->Spsr_copy;
4500 if (inst_cream->I) { 4253 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
4501 aif_val |= (inst_cream->imod0 << 7); 4254 LOAD_NZCVT;
4502 aif_mask |= 1 << 7; 4255 }
4503 } 4256 } else if (inst_cream->S) {
4504 if (inst_cream->F) { 4257 UPDATE_NFLAG(dst);
4505 aif_val |= (inst_cream->imod0 << 6); 4258 UPDATE_ZFLAG(dst);
4506 aif_mask |= 1 << 6; 4259 UPDATE_CFLAG_WITH_SC;
4507 } 4260 }
4508 aif_mask = ~aif_mask; 4261 if (inst_cream->Rd == 15) {
4509 cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val; 4262 INC_PC(sizeof(eor_inst));
4510 } 4263 goto DISPATCH;
4511 if (inst_cream->mmod) { 4264 }
4512 cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode; 4265 }
4513 switch_mode(cpu, inst_cream->mode); 4266 cpu->Reg[15] += GET_INST_SIZE(cpu);
4514 } 4267 INC_PC(sizeof(eor_inst));
4515 } 4268 FETCH_INST;
4516 cpu->Reg[15] += GET_INST_SIZE(cpu); 4269 GOTO_NEXT_INST;
4517 INC_PC(sizeof(cps_inst)); 4270 }
4518 FETCH_INST; 4271 LDC_INST:
4519 GOTO_NEXT_INST; 4272 {
4520 } 4273 // Instruction not implemented
4521 CPY_INST: 4274 //LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
4522 { 4275 cpu->Reg[15] += GET_INST_SIZE(cpu);
4523 INC_ICOUNTER; 4276 INC_PC(sizeof(ldc_inst));
4524 mov_inst *inst_cream = (mov_inst *)inst_base->component; 4277 FETCH_INST;
4525// cpy_inst *inst_cream = (cpy_inst *)inst_base->component; 4278 GOTO_NEXT_INST;
4526 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4279 }
4527 RD = SHIFTER_OPERAND; 4280 LDM_INST:
4528// RD = RM; 4281 {
4529 if ((inst_cream->Rd == 15)) { 4282 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4530 INC_PC(sizeof(mov_inst)); 4283 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4531 goto DISPATCH; 4284 int i;
4532 } 4285 unsigned int ret;
4533 } 4286 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4534// DEBUG_LOG(ARM11, "cpy inst %x\n", cpu->Reg[15]); 4287 if (fault) {
4535 cpu->Reg[15] += GET_INST_SIZE(cpu); 4288 goto MMU_EXCEPTION;
4536 INC_PC(sizeof(mov_inst)); 4289 }
4537 FETCH_INST; 4290 unsigned int inst = inst_cream->inst;
4538 GOTO_NEXT_INST; 4291 if (BIT(inst, 22) && !BIT(inst, 15)) {
4539 } 4292 for (i = 0; i < 13; i++) {
4540 EOR_INST: 4293 if(BIT(inst, i)){
4541 { 4294 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4542 INC_ICOUNTER; 4295 cpu->Reg[i] = ret;
4543 eor_inst *inst_cream = (eor_inst *)inst_base->component; 4296 addr += 4;
4544 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4297 if ((addr & 0xfff) == 0) {
4545 lop = RN; 4298 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4546 if (inst_cream->Rn == 15) { 4299 } else {
4547 lop += 2 * GET_INST_SIZE(cpu); 4300 phys_addr += 4;
4548 } 4301 }
4549 rop = SHIFTER_OPERAND; 4302 }
4550 RD = dst = lop ^ rop; 4303 }
4551 if (inst_cream->S && (inst_cream->Rd == 15)) { 4304 if (BIT(inst, 13)) {
4552 /* cpsr = spsr*/ 4305 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4553 if (CurrentModeHasSPSR) { 4306
4554 cpu->Cpsr = cpu->Spsr_copy; 4307 if (cpu->Mode == USER32MODE)
4555 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 4308 cpu->Reg[13] = ret;
4556 LOAD_NZCVT; 4309 else
4557 } 4310 cpu->Reg_usr[0] = ret;
4558 } else if (inst_cream->S) { 4311 addr += 4;
4559 UPDATE_NFLAG(dst); 4312 if ((addr & 0xfff) == 0) {
4560 UPDATE_ZFLAG(dst); 4313 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4561 UPDATE_CFLAG_WITH_SC; 4314 } else {
4562// UPDATE_CFLAG(dst, lop, rop); 4315 phys_addr += 4;
4563// UPDATE_VFLAG((int)dst, (int)lop, (int)rop); 4316 }
4564 } 4317 }
4565 if (inst_cream->Rd == 15) { 4318 if (BIT(inst, 14)) {
4566 INC_PC(sizeof(eor_inst)); 4319 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4567 goto DISPATCH; 4320
4568 } 4321 if (cpu->Mode == USER32MODE)
4569 } 4322 cpu->Reg[14] = ret;
4570 cpu->Reg[15] += GET_INST_SIZE(cpu); 4323 else
4571 INC_PC(sizeof(eor_inst)); 4324 cpu->Reg_usr[1] = ret;
4572 FETCH_INST; 4325 }
4573 GOTO_NEXT_INST; 4326 } else if (!BIT(inst, 22)) {
4574 } 4327 for( i = 0; i < 16; i ++ ){
4575 LDC_INST: 4328 if(BIT(inst, i)){
4576 { 4329 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4577 INC_ICOUNTER; 4330 if (fault) goto MMU_EXCEPTION;
4578 /* NOT IMPL */ 4331
4579 cpu->Reg[15] += GET_INST_SIZE(cpu); 4332 // For armv5t, should enter thumb when bits[0] is non-zero.
4580 INC_PC(sizeof(ldc_inst)); 4333 if(i == 15){
4581 FETCH_INST; 4334 cpu->TFlag = ret & 0x1;
4582 GOTO_NEXT_INST; 4335 ret &= 0xFFFFFFFE;
4583 }
4584 LDM_INST:
4585 {
4586 INC_ICOUNTER;
4587 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4588 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4589 int i;
4590 unsigned int ret;
4591 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4592 if (fault) {
4593 goto MMU_EXCEPTION;
4594 }
4595 unsigned int inst = inst_cream->inst;
4596 if (BIT(inst, 22) && !BIT(inst, 15)) {
4597// DEBUG_MSG;
4598 #if 1
4599 /* LDM (2) user */
4600 for (i = 0; i < 13; i++) {
4601 if(BIT(inst, i)){
4602 #if 0
4603 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4604 if (fault) {
4605 goto MMU_EXCEPTION;
4606 }
4607 #endif
4608 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4609 //if (fault) goto MMU_EXCEPTION;
4610 cpu->Reg[i] = ret;
4611 addr += 4;
4612 if ((addr & 0xfff) == 0) {
4613 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4614 } else {
4615 phys_addr += 4;
4616 }
4617 }
4618 }
4619 if (BIT(inst, 13)) {
4620 #if 0
4621 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4622 if (fault) {
4623 goto MMU_EXCEPTION;
4624 }
4625 #endif
4626 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4627 //if (fault) goto MMU_EXCEPTION;
4628 if (cpu->Mode == USER32MODE)
4629 cpu->Reg[13] = ret;
4630 else
4631 cpu->Reg_usr[0] = ret;
4632 addr += 4;
4633 if ((addr & 0xfff) == 0) {
4634 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4635 } else {
4636 phys_addr += 4;
4637 }
4638 }
4639 if (BIT(inst, 14)) {
4640 #if 0
4641 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4642 if (fault) {
4643 goto MMU_EXCEPTION;
4644 }
4645 #endif
4646 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4647 //if (fault) goto MMU_EXCEPTION;
4648 if (cpu->Mode == USER32MODE)
4649 cpu->Reg[14] = ret;
4650 else
4651 cpu->Reg_usr[1] = ret;
4652 }
4653 #endif
4654 } else if (!BIT(inst, 22)) {
4655 for( i = 0; i < 16; i ++ ){
4656 if(BIT(inst, i)){
4657 //bus_read(32, addr, &ret);
4658 #if 0
4659 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4660 if (fault) {
4661 goto MMU_EXCEPTION;
4662 }
4663 #endif
4664 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4665 if (fault) goto MMU_EXCEPTION;
4666 /* For armv5t, should enter thumb when bits[0] is non-zero. */
4667 if(i == 15){
4668 cpu->TFlag = ret & 0x1;
4669 ret &= 0xFFFFFFFE;
4670 //DEBUG_LOG(ARM11, "In %s, TFlag ret=0x%x\n", __FUNCTION__, ret);
4671 }
4672
4673 cpu->Reg[i] = ret;
4674 addr += 4;
4675 if ((addr & 0xfff) == 0) {
4676 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4677 } else {
4678 phys_addr += 4;
4679 }
4680 }
4681 }
4682 } else if (BIT(inst, 22) && BIT(inst, 15)) {
4683 for( i = 0; i < 15; i ++ ){
4684 if(BIT(inst, i)){
4685 #if 0
4686 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4687 if (fault) {
4688 goto MMU_EXCEPTION;
4689 }
4690 #endif
4691 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4692 //if (fault) goto MMU_EXCEPTION;
4693 cpu->Reg[i] = ret;
4694 addr += 4;
4695 if ((addr & 0xfff) == 0) {
4696 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4697 } else {
4698 phys_addr += 4;
4699 }
4700 }
4701 }
4702
4703 if (CurrentModeHasSPSR) {
4704 cpu->Cpsr = cpu->Spsr_copy;
4705 switch_mode(cpu, cpu->Cpsr & 0x1f);
4706 LOAD_NZCVT;
4707 }
4708 #if 0
4709 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4710 if (fault) {
4711 goto MMU_EXCEPTION;
4712 }
4713 #endif
4714 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4715 if (fault) {
4716 goto MMU_EXCEPTION;
4717 }
4718 cpu->Reg[15] = ret;
4719 #if 0
4720 addr += 4;
4721 phys_addr += 4;
4722 #endif
4723 }
4724 if (BIT(inst, 15)) {
4725 INC_PC(sizeof(ldst_inst));
4726 goto DISPATCH;
4727 }
4728 }
4729 cpu->Reg[15] += GET_INST_SIZE(cpu);
4730 INC_PC(sizeof(ldst_inst));
4731 FETCH_INST;
4732 GOTO_NEXT_INST;
4733 }
4734 SXTH_INST:
4735 {
4736 INC_ICOUNTER;
4737 sxth_inst *inst_cream = (sxth_inst *)inst_base->component;
4738 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4739 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
4740 if (BIT(operand2, 15)) {
4741 operand2 |= 0xffff0000;
4742 } else {
4743 operand2 &= 0xffff;
4744 }
4745 RD = operand2;
4746 }
4747 cpu->Reg[15] += GET_INST_SIZE(cpu);
4748 INC_PC(sizeof(sxth_inst));
4749 FETCH_INST;
4750 GOTO_NEXT_INST;
4751 }
4752 LDR_INST:
4753 {
4754 INC_ICOUNTER;
4755 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4756 //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4757 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4758 if (fault) goto MMU_EXCEPTION;
4759 unsigned int value;
4760 //bus_read(32, addr, &value);
4761 fault = interpreter_read_memory(addr, phys_addr, value, 32);
4762 if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
4763 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4764 else {
4765 value = ROTATE_RIGHT_32(value,(8*(addr&0x3)));
4766 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4767 }
4768 if (BITS(inst_cream->inst, 12, 15) == 15) {
4769 /* For armv5t, should enter thumb when bits[0] is non-zero. */
4770 cpu->TFlag = value & 0x1;
4771 cpu->Reg[15] &= 0xFFFFFFFE;
4772 INC_PC(sizeof(ldst_inst));
4773 goto DISPATCH;
4774 }
4775 //}
4776 cpu->Reg[15] += GET_INST_SIZE(cpu);
4777 INC_PC(sizeof(ldst_inst));
4778 FETCH_INST;
4779 GOTO_NEXT_INST;
4780 }
4781 LDRCOND_INST:
4782 {
4783 INC_ICOUNTER;
4784 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4785 if (CondPassed(cpu, inst_base->cond)) {
4786 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4787 if (fault) goto MMU_EXCEPTION;
4788 unsigned int value;
4789 //bus_read(32, addr, &value);
4790 fault = interpreter_read_memory(addr, phys_addr, value, 32);
4791 if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
4792 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4793 else {
4794 value = ROTATE_RIGHT_32(value,(8*(addr&0x3)));
4795 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4796 } 4336 }
4797 4337
4798 if (BITS(inst_cream->inst, 12, 15) == 15) { 4338 cpu->Reg[i] = ret;
4799 /* For armv5t, should enter thumb when bits[0] is non-zero. */ 4339 addr += 4;
4800 cpu->TFlag = value & 0x1; 4340 if ((addr & 0xfff) == 0) {
4801 cpu->Reg[15] &= 0xFFFFFFFE; 4341 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4802 INC_PC(sizeof(ldst_inst)); 4342 } else {
4803 goto DISPATCH; 4343 phys_addr += 4;
4804 } 4344 }
4805 } 4345 }
4806 cpu->Reg[15] += GET_INST_SIZE(cpu); 4346 }
4807 INC_PC(sizeof(ldst_inst)); 4347 } else if (BIT(inst, 22) && BIT(inst, 15)) {
4808 FETCH_INST; 4348 for( i = 0; i < 15; i ++ ){
4809 GOTO_NEXT_INST; 4349 if(BIT(inst, i)){
4810 } 4350 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4811 UXTH_INST: 4351 cpu->Reg[i] = ret;
4812 { 4352 addr += 4;
4813 INC_ICOUNTER; 4353 if ((addr & 0xfff) == 0) {
4814 uxth_inst *inst_cream = (uxth_inst *)inst_base->component; 4354 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4815 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4355 } else {
4816 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) 4356 phys_addr += 4;
4817 & 0xffff; 4357 }
4818 RD = operand2; 4358 }
4819 } 4359 }
4820 cpu->Reg[15] += GET_INST_SIZE(cpu); 4360
4821 INC_PC(sizeof(uxth_inst)); 4361 if (CurrentModeHasSPSR) {
4822 FETCH_INST; 4362 cpu->Cpsr = cpu->Spsr_copy;
4823 GOTO_NEXT_INST; 4363 switch_mode(cpu, cpu->Cpsr & 0x1f);
4824 } 4364 LOAD_NZCVT;
4825 UXTAH_INST: 4365 }
4826 { 4366
4827 INC_ICOUNTER; 4367 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4828 uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component; 4368 if (fault) {
4829 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4369 goto MMU_EXCEPTION;
4830 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) 4370 }
4831 & 0xffff; 4371 cpu->Reg[15] = ret;
4832 RD = RN + operand2; 4372 }
4833 if (inst_cream->Rn == 15 || inst_cream->Rm == 15) { 4373 if (BIT(inst, 15)) {
4834 DEBUG_LOG(ARM11, "in line %d\n", __LINE__); 4374 INC_PC(sizeof(ldst_inst));
4835 CITRA_IGNORE_EXIT(-1); 4375 goto DISPATCH;
4836 } 4376 }
4837 } 4377 }
4838 cpu->Reg[15] += GET_INST_SIZE(cpu); 4378 cpu->Reg[15] += GET_INST_SIZE(cpu);
4839 INC_PC(sizeof(uxtah_inst)); 4379 INC_PC(sizeof(ldst_inst));
4840 FETCH_INST; 4380 FETCH_INST;
4841 GOTO_NEXT_INST; 4381 GOTO_NEXT_INST;
4842 } 4382 }
4843 LDRB_INST: 4383 SXTH_INST:
4844 { 4384 {
4845 INC_ICOUNTER; 4385 sxth_inst *inst_cream = (sxth_inst *)inst_base->component;
4846 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 4386 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4847 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4387 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
4848 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); 4388 if (BIT(operand2, 15)) {
4849 if (fault) goto MMU_EXCEPTION; 4389 operand2 |= 0xffff0000;
4850 unsigned int value; 4390 } else {
4851 fault = interpreter_read_memory(addr, phys_addr, value, 8); 4391 operand2 &= 0xffff;
4852 if (fault) goto MMU_EXCEPTION; 4392 }
4853 //bus_read(8, addr, &value); 4393 RD = operand2;
4854 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4394 }
4855 if (BITS(inst_cream->inst, 12, 15) == 15) { 4395 cpu->Reg[15] += GET_INST_SIZE(cpu);
4856 INC_PC(sizeof(ldst_inst)); 4396 INC_PC(sizeof(sxth_inst));
4857 goto DISPATCH; 4397 FETCH_INST;
4858 } 4398 GOTO_NEXT_INST;
4859 } 4399 }
4860 cpu->Reg[15] += GET_INST_SIZE(cpu); 4400 LDR_INST:
4861 INC_PC(sizeof(ldst_inst)); 4401 {
4862 FETCH_INST; 4402 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4863 GOTO_NEXT_INST; 4403 //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4864 } 4404 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4865 LDRBT_INST: 4405 if (fault) goto MMU_EXCEPTION;
4866 { 4406 unsigned int value;
4867 INC_ICOUNTER; 4407 fault = interpreter_read_memory(addr, phys_addr, value, 32);
4868 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 4408 if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
4869 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4409 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4870 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); 4410 else {
4871 if (fault) goto MMU_EXCEPTION; 4411 value = ROTATE_RIGHT_32(value,(8*(addr&0x3)));
4872 unsigned int value; 4412 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4873 fault = interpreter_read_memory(addr, phys_addr, value, 8); 4413 }
4874 if (fault) goto MMU_EXCEPTION; 4414 if (BITS(inst_cream->inst, 12, 15) == 15) {
4875 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4415 // For armv5t, should enter thumb when bits[0] is non-zero.
4876 if (BITS(inst_cream->inst, 12, 15) == 15) { 4416 cpu->TFlag = value & 0x1;
4877 INC_PC(sizeof(ldst_inst)); 4417 cpu->Reg[15] &= 0xFFFFFFFE;
4878 goto DISPATCH; 4418 INC_PC(sizeof(ldst_inst));
4879 } 4419 goto DISPATCH;
4880 } 4420 }
4881 cpu->Reg[15] += GET_INST_SIZE(cpu); 4421 //}
4882 INC_PC(sizeof(ldst_inst)); 4422 cpu->Reg[15] += GET_INST_SIZE(cpu);
4883 FETCH_INST; 4423 INC_PC(sizeof(ldst_inst));
4884 GOTO_NEXT_INST; 4424 FETCH_INST;
4885 } 4425 GOTO_NEXT_INST;
4886 LDRD_INST: 4426 }
4887 { 4427 LDRCOND_INST:
4888 INC_ICOUNTER; 4428 {
4889 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 4429 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4890 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4430 if (CondPassed(cpu, inst_base->cond)) {
4891 /* Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0) */ 4431 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4892 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); 4432 if (fault) goto MMU_EXCEPTION;
4893 if (fault) goto MMU_EXCEPTION; 4433 unsigned int value;
4894 uint32_t rear_phys_addr; 4434 fault = interpreter_read_memory(addr, phys_addr, value, 32);
4895 fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 1); 4435 if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
4896 if(fault){ 4436 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4897 ERROR_LOG(ARM11, "mmu fault , should rollback the above get_addr\n"); 4437 else {
4898 CITRA_IGNORE_EXIT(-1); 4438 value = ROTATE_RIGHT_32(value,(8*(addr&0x3)));
4899 goto MMU_EXCEPTION; 4439 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4900 } 4440 }
4901 unsigned int value; 4441
4902 fault = interpreter_read_memory(addr, phys_addr, value, 32); 4442 if (BITS(inst_cream->inst, 12, 15) == 15) {
4903 if (fault) goto MMU_EXCEPTION; 4443 // For armv5t, should enter thumb when bits[0] is non-zero.
4904 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4444 cpu->TFlag = value & 0x1;
4905 fault = interpreter_read_memory(addr + 4, rear_phys_addr, value, 32); 4445 cpu->Reg[15] &= 0xFFFFFFFE;
4906 if (fault) goto MMU_EXCEPTION; 4446 INC_PC(sizeof(ldst_inst));
4907 cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = value; 4447 goto DISPATCH;
4908 /* No dispatch since this operation should not modify R15 */ 4448 }
4909 } 4449 }
4910 cpu->Reg[15] += 4; 4450 cpu->Reg[15] += GET_INST_SIZE(cpu);
4911 INC_PC(sizeof(ldst_inst)); 4451 INC_PC(sizeof(ldst_inst));
4912 FETCH_INST; 4452 FETCH_INST;
4913 GOTO_NEXT_INST; 4453 GOTO_NEXT_INST;
4914 } 4454 }
4915 4455 UXTH_INST:
4916 LDREX_INST: 4456 {
4917 { 4457 uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
4918 INC_ICOUNTER; 4458 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4919 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 4459 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
4920 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4460 & 0xffff;
4921 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; 4461 RD = operand2;
4922 fault = check_address_validity(cpu, addr, &phys_addr, 1); 4462 }
4923 if (fault) goto MMU_EXCEPTION; 4463 cpu->Reg[15] += GET_INST_SIZE(cpu);
4924 unsigned int value; 4464 INC_PC(sizeof(uxth_inst));
4925 fault = interpreter_read_memory(addr, phys_addr, value, 32); 4465 FETCH_INST;
4926 if (fault) goto MMU_EXCEPTION; 4466 GOTO_NEXT_INST;
4927 4467 }
4928 add_exclusive_addr(cpu, phys_addr); 4468 UXTAH_INST:
4929 cpu->exclusive_state = 1; 4469 {
4930 4470 uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component;
4931 //bus_read(32, addr, &value); 4471 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4932 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4472 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
4933 if (BITS(inst_cream->inst, 12, 15) == 15) { 4473 & 0xffff;
4934 INC_PC(sizeof(ldst_inst)); 4474 RD = RN + operand2;
4935 goto DISPATCH; 4475 if (inst_cream->Rn == 15 || inst_cream->Rm == 15) {
4936 } 4476 LOG_ERROR(Core_ARM11, "invalid operands for UXTAH");
4937 } 4477 CITRA_IGNORE_EXIT(-1);
4938 cpu->Reg[15] += GET_INST_SIZE(cpu); 4478 }
4939 INC_PC(sizeof(ldst_inst)); 4479 }
4940 FETCH_INST; 4480 cpu->Reg[15] += GET_INST_SIZE(cpu);
4941 GOTO_NEXT_INST; 4481 INC_PC(sizeof(uxtah_inst));
4942 } 4482 FETCH_INST;
4943 LDREXB_INST: 4483 GOTO_NEXT_INST;
4944 { 4484 }
4945 INC_ICOUNTER; 4485 LDRB_INST:
4946 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 4486 {
4947 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4487 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4948 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; 4488 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4949 fault = check_address_validity(cpu, addr, &phys_addr, 1); 4489 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4950 if (fault) goto MMU_EXCEPTION; 4490 if (fault) goto MMU_EXCEPTION;
4951 unsigned int value; 4491 unsigned int value;
4952 fault = interpreter_read_memory(addr, phys_addr, value, 8); 4492 fault = interpreter_read_memory(addr, phys_addr, value, 8);
4953 if (fault) goto MMU_EXCEPTION; 4493 if (fault) goto MMU_EXCEPTION;
4954 4494 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4955 add_exclusive_addr(cpu, phys_addr); 4495 if (BITS(inst_cream->inst, 12, 15) == 15) {
4956 cpu->exclusive_state = 1; 4496 INC_PC(sizeof(ldst_inst));
4957 4497 goto DISPATCH;
4958 //bus_read(8, addr, &value); 4498 }
4959 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4499 }
4960 if (BITS(inst_cream->inst, 12, 15) == 15) { 4500 cpu->Reg[15] += GET_INST_SIZE(cpu);
4961 INC_PC(sizeof(ldst_inst)); 4501 INC_PC(sizeof(ldst_inst));
4962 goto DISPATCH; 4502 FETCH_INST;
4963 } 4503 GOTO_NEXT_INST;
4964 } 4504 }
4965 cpu->Reg[15] += GET_INST_SIZE(cpu); 4505 LDRBT_INST:
4966 INC_PC(sizeof(ldst_inst)); 4506 {
4967 FETCH_INST; 4507 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4968 GOTO_NEXT_INST; 4508 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4969 } 4509 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4970 LDRH_INST: 4510 if (fault) goto MMU_EXCEPTION;
4971 { 4511 unsigned int value;
4972 INC_ICOUNTER; 4512 fault = interpreter_read_memory(addr, phys_addr, value, 8);
4973 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 4513 if (fault) goto MMU_EXCEPTION;
4974 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4514 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4975 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); 4515 if (BITS(inst_cream->inst, 12, 15) == 15) {
4976 if (fault) goto MMU_EXCEPTION; 4516 INC_PC(sizeof(ldst_inst));
4977 unsigned int value = 0; 4517 goto DISPATCH;
4978 fault = interpreter_read_memory(addr, phys_addr, value, 16); 4518 }
4979// fault = interpreter_read_memory(addr, value, 32); 4519 }
4980 if (fault) goto MMU_EXCEPTION; 4520 cpu->Reg[15] += GET_INST_SIZE(cpu);
4981 //if (value == 0xffff && cpu->icounter > 190000000 && cpu->icounter < 210000000) { 4521 INC_PC(sizeof(ldst_inst));
4982 // value = 0xffffffff; 4522 FETCH_INST;
4983 //} 4523 GOTO_NEXT_INST;
4984 //bus_read(16, addr, &value); 4524 }
4985// cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value & 0xffff; 4525 LDRD_INST:
4986 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4526 {
4987 if (BITS(inst_cream->inst, 12, 15) == 15) { 4527 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4988 INC_PC(sizeof(ldst_inst)); 4528 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4989 goto DISPATCH; 4529 // Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0)
4990 } 4530 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4991 } 4531 if (fault) goto MMU_EXCEPTION;
4992 cpu->Reg[15] += GET_INST_SIZE(cpu); 4532 uint32_t rear_phys_addr;
4993 INC_PC(sizeof(ldst_inst)); 4533 fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 1);
4994 FETCH_INST; 4534 if(fault){
4995 GOTO_NEXT_INST; 4535 LOG_ERROR(Core_ARM11, "MMU fault , should rollback the above get_addr\n");
4996 } 4536 CITRA_IGNORE_EXIT(-1);
4997 LDRSB_INST: 4537 goto MMU_EXCEPTION;
4998 { 4538 }
4999 INC_ICOUNTER; 4539 unsigned int value;
5000 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 4540 fault = interpreter_read_memory(addr, phys_addr, value, 32);
5001 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4541 if (fault) goto MMU_EXCEPTION;
5002 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); 4542 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5003 if (fault) goto MMU_EXCEPTION; 4543 fault = interpreter_read_memory(addr + 4, rear_phys_addr, value, 32);
5004 unsigned int value; 4544 if (fault) goto MMU_EXCEPTION;
5005// DEBUG_LOG(ARM11, "ldrsb addr is %x\n", addr); 4545 cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = value;
5006 fault = interpreter_read_memory(addr, phys_addr, value, 8); 4546
5007 if (fault) goto MMU_EXCEPTION; 4547 // No dispatch since this operation should not modify R15
5008 //bus_read(8, addr, &value); 4548 }
5009 if (BIT(value, 7)) { 4549 cpu->Reg[15] += 4;
5010 value |= 0xffffff00; 4550 INC_PC(sizeof(ldst_inst));
5011 } 4551 FETCH_INST;
5012 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4552 GOTO_NEXT_INST;
5013 if (BITS(inst_cream->inst, 12, 15) == 15) { 4553 }
5014 INC_PC(sizeof(ldst_inst)); 4554
5015 goto DISPATCH; 4555 LDREX_INST:
5016 } 4556 {
5017 } 4557 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5018 cpu->Reg[15] += GET_INST_SIZE(cpu); 4558 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5019 INC_PC(sizeof(ldst_inst)); 4559 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
5020 FETCH_INST; 4560 fault = check_address_validity(cpu, addr, &phys_addr, 1);
5021 GOTO_NEXT_INST; 4561 if (fault) goto MMU_EXCEPTION;
5022 } 4562 unsigned int value;
5023 LDRSH_INST: 4563 fault = interpreter_read_memory(addr, phys_addr, value, 32);
5024 { 4564 if (fault) goto MMU_EXCEPTION;
5025 INC_ICOUNTER; 4565
5026 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 4566 add_exclusive_addr(cpu, phys_addr);
5027 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4567 cpu->exclusive_state = 1;
5028 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); 4568
5029 if (fault) goto MMU_EXCEPTION; 4569 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5030 unsigned int value; 4570 if (BITS(inst_cream->inst, 12, 15) == 15) {
5031 fault = interpreter_read_memory(addr, phys_addr, value, 16); 4571 INC_PC(sizeof(ldst_inst));
5032 if (fault) goto MMU_EXCEPTION; 4572 goto DISPATCH;
5033 //bus_read(16, addr, &value); 4573 }
5034 if (BIT(value, 15)) { 4574 }
5035 value |= 0xffff0000; 4575 cpu->Reg[15] += GET_INST_SIZE(cpu);
5036 } 4576 INC_PC(sizeof(ldst_inst));
5037 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4577 FETCH_INST;
5038 if (BITS(inst_cream->inst, 12, 15) == 15) { 4578 GOTO_NEXT_INST;
5039 INC_PC(sizeof(ldst_inst)); 4579 }
5040 goto DISPATCH; 4580 LDREXB_INST:
5041 } 4581 {
5042 } 4582 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5043 cpu->Reg[15] += GET_INST_SIZE(cpu); 4583 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5044 INC_PC(sizeof(ldst_inst)); 4584 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
5045 FETCH_INST; 4585 fault = check_address_validity(cpu, addr, &phys_addr, 1);
5046 GOTO_NEXT_INST; 4586 if (fault) goto MMU_EXCEPTION;
5047 } 4587 unsigned int value;
5048 LDRT_INST: 4588 fault = interpreter_read_memory(addr, phys_addr, value, 8);
5049 { 4589 if (fault) goto MMU_EXCEPTION;
5050 INC_ICOUNTER; 4590
5051 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 4591 add_exclusive_addr(cpu, phys_addr);
5052 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4592 cpu->exclusive_state = 1;
5053 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); 4593
5054 if (fault) goto MMU_EXCEPTION; 4594 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5055 unsigned int value; 4595 if (BITS(inst_cream->inst, 12, 15) == 15) {
5056 fault = interpreter_read_memory(addr, phys_addr, value, 32); 4596 INC_PC(sizeof(ldst_inst));
5057 if (fault) goto MMU_EXCEPTION; 4597 goto DISPATCH;
5058 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4598 }
5059 4599 }
5060 if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) 4600 cpu->Reg[15] += GET_INST_SIZE(cpu);
5061 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4601 INC_PC(sizeof(ldst_inst));
5062 else 4602 FETCH_INST;
5063 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ROTATE_RIGHT_32(value,(8*(addr&0x3))) ; 4603 GOTO_NEXT_INST;
5064 4604 }
5065 if (BITS(inst_cream->inst, 12, 15) == 15) { 4605 LDRH_INST:
5066 INC_PC(sizeof(ldst_inst)); 4606 {
5067 goto DISPATCH; 4607 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5068 } 4608 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5069 } 4609 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
5070 cpu->Reg[15] += GET_INST_SIZE(cpu); 4610 if (fault) goto MMU_EXCEPTION;
5071 INC_PC(sizeof(ldst_inst)); 4611 unsigned int value = 0;
5072 FETCH_INST; 4612 fault = interpreter_read_memory(addr, phys_addr, value, 16);
5073 GOTO_NEXT_INST; 4613 if (fault) goto MMU_EXCEPTION;
5074 } 4614 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5075 MCR_INST: 4615 if (BITS(inst_cream->inst, 12, 15) == 15) {
5076 { 4616 INC_PC(sizeof(ldst_inst));
5077 INC_ICOUNTER; 4617 goto DISPATCH;
5078 /* NOT IMPL */ 4618 }
5079 mcr_inst *inst_cream = (mcr_inst *)inst_base->component; 4619 }
5080 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4620 cpu->Reg[15] += GET_INST_SIZE(cpu);
5081 unsigned int inst = inst_cream->inst; 4621 INC_PC(sizeof(ldst_inst));
5082 if (inst_cream->Rd == 15) { 4622 FETCH_INST;
5083 DEBUG_MSG; 4623 GOTO_NEXT_INST;
5084 } else { 4624 }
5085 if (inst_cream->cp_num == 15) { 4625 LDRSB_INST:
5086 if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) { 4626 {
5087 //LET(RD, CONST(0x0007b000)); 4627 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5088 //LET(RD, CONST(0x410FB760)); 4628 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5089 //LET(CP15_MAIN_ID, R(RD)); 4629 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
5090 CP15_REG(CP15_MAIN_ID) = RD; 4630 if (fault) goto MMU_EXCEPTION;
5091 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) { 4631 unsigned int value;
5092 //LET(RD, R(CP15_CONTROL)); 4632 fault = interpreter_read_memory(addr, phys_addr, value, 8);
5093 CP15_REG(CP15_AUXILIARY_CONTROL) = RD; 4633 if (fault) goto MMU_EXCEPTION;
5094 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) { 4634 if (BIT(value, 7)) {
5095 //LET(RD, R(CP15_CONTROL)); 4635 value |= 0xffffff00;
5096 CP15_REG(CP15_COPROCESSOR_ACCESS_CONTROL) = RD; 4636 }
5097 } else if(CRn == 1 && CRm == 0 && OPCODE_2 == 0) { 4637 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5098 //LET(CP15_CONTROL, R(RD)); 4638 if (BITS(inst_cream->inst, 12, 15) == 15) {
5099 CP15_REG(CP15_CONTROL) = RD; 4639 INC_PC(sizeof(ldst_inst));
5100 } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) { 4640 goto DISPATCH;
5101 //LET(CP15_DOMAIN_ACCESS_CONTROL, R(RD)); 4641 }
5102 CP15_REG(CP15_DOMAIN_ACCESS_CONTROL) = RD; 4642 }
5103 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) { 4643 cpu->Reg[15] += GET_INST_SIZE(cpu);
5104 //LET(CP15_TRANSLATION_BASE_TABLE_0, R(RD)); 4644 INC_PC(sizeof(ldst_inst));
5105 CP15_REG(CP15_TRANSLATION_BASE_TABLE_0) = RD; 4645 FETCH_INST;
5106 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 1) { 4646 GOTO_NEXT_INST;
5107 //LET(CP15_TRANSLATION_BASE_TABLE_1, R(RD)); 4647 }
5108 CP15_REG(CP15_TRANSLATION_BASE_TABLE_1) = RD; 4648 LDRSH_INST:
5109 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 2) { 4649 {
5110 //LET(CP15_TRANSLATION_BASE_CONTROL, R(RD)); 4650 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5111 CP15_REG(CP15_TRANSLATION_BASE_CONTROL) = RD; 4651 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5112 } else if(CRn == MMU_CACHE_OPS){ 4652 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
5113 //SKYEYE_WARNING("cache operation have not implemented.\n"); 4653 if (fault) goto MMU_EXCEPTION;
5114 } else if(CRn == MMU_TLB_OPS){ 4654 unsigned int value;
5115 switch (CRm) { 4655 fault = interpreter_read_memory(addr, phys_addr, value, 16);
5116 case 5: /* ITLB */ 4656 if (fault) goto MMU_EXCEPTION;
5117 switch(OPCODE_2){ 4657 if (BIT(value, 15)) {
5118 case 0: /* invalidate all */ 4658 value |= 0xffff0000;
5119 //invalidate_all_tlb(state); 4659 }
5120 DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate all\n"); 4660 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5121 //remove_tlb(INSN_TLB); 4661 if (BITS(inst_cream->inst, 12, 15) == 15) {
5122 //erase_all(core, INSN_TLB); 4662 INC_PC(sizeof(ldst_inst));
5123 break; 4663 goto DISPATCH;
5124 case 1: /* invalidate by MVA */ 4664 }
5125 //invalidate_by_mva(state, value); 4665 }
5126 //DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by mva\n"); 4666 cpu->Reg[15] += GET_INST_SIZE(cpu);
5127 //remove_tlb_by_mva(RD, INSN_TLB); 4667 INC_PC(sizeof(ldst_inst));
5128 //erase_by_mva(core, RD, INSN_TLB); 4668 FETCH_INST;
5129 break; 4669 GOTO_NEXT_INST;
5130 case 2: /* invalidate by asid */ 4670 }
5131 //invalidate_by_asid(state, value); 4671 LDRT_INST:
5132 //DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by asid\n"); 4672 {
5133 //erase_by_asid(core, RD, INSN_TLB); 4673 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5134 break; 4674 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5135 default: 4675 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
5136 break; 4676 if (fault) goto MMU_EXCEPTION;
5137 } 4677 unsigned int value;
5138 4678 fault = interpreter_read_memory(addr, phys_addr, value, 32);
5139 break; 4679 if (fault) goto MMU_EXCEPTION;
5140 case 6: /* DTLB */ 4680 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5141 switch(OPCODE_2){ 4681
5142 case 0: /* invalidate all */ 4682 if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
5143 //invalidate_all_tlb(state); 4683 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5144 //remove_tlb(DATA_TLB); 4684 else
5145 //erase_all(core, DATA_TLB); 4685 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ROTATE_RIGHT_32(value,(8*(addr&0x3))) ;
5146 DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate all\n"); 4686
5147 break; 4687 if (BITS(inst_cream->inst, 12, 15) == 15) {
5148 case 1: /* invalidate by MVA */ 4688 INC_PC(sizeof(ldst_inst));
5149 //invalidate_by_mva(state, value); 4689 goto DISPATCH;
5150 //remove_tlb_by_mva(RD, DATA_TLB); 4690 }
5151 //erase_by_mva(core, RD, DATA_TLB); 4691 }
5152 //DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by mva\n"); 4692 cpu->Reg[15] += GET_INST_SIZE(cpu);
5153 break; 4693 INC_PC(sizeof(ldst_inst));
5154 case 2: /* invalidate by asid */ 4694 FETCH_INST;
5155 //invalidate_by_asid(state, value); 4695 GOTO_NEXT_INST;
5156 //remove_tlb_by_asid(RD, DATA_TLB); 4696 }
5157 //erase_by_asid(core, RD, DATA_TLB); 4697 MCR_INST:
5158 //DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by asid\n"); 4698 {
5159 break; 4699 mcr_inst *inst_cream = (mcr_inst *)inst_base->component;
5160 default: 4700 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5161 break; 4701 unsigned int inst = inst_cream->inst;
5162 } 4702 if (inst_cream->Rd == 15) {
5163 break; 4703 DEBUG_MSG;
5164 case 7: /* UNIFILED TLB */ 4704 } else {
5165 switch(OPCODE_2){ 4705 if (inst_cream->cp_num == 15) {
5166 case 0: /* invalidate all */ 4706 if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) {
5167 //invalidate_all_tlb(state); 4707 CP15_REG(CP15_MAIN_ID) = RD;
5168 //erase_all(core, INSN_TLB); 4708 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) {
5169 //erase_all(core, DATA_TLB); 4709 CP15_REG(CP15_AUXILIARY_CONTROL) = RD;
5170 //remove_tlb(DATA_TLB); 4710 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) {
5171 //remove_tlb(INSN_TLB); 4711 CP15_REG(CP15_COPROCESSOR_ACCESS_CONTROL) = RD;
5172 //DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate all\n"); 4712 } else if(CRn == 1 && CRm == 0 && OPCODE_2 == 0) {
5173 break; 4713 CP15_REG(CP15_CONTROL) = RD;
5174 case 1: /* invalidate by MVA */ 4714 } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) {
5175 //invalidate_by_mva(state, value); 4715 CP15_REG(CP15_DOMAIN_ACCESS_CONTROL) = RD;
5176 //erase_by_mva(core, RD, DATA_TLB); 4716 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) {
5177 //erase_by_mva(core, RD, INSN_TLB); 4717 CP15_REG(CP15_TRANSLATION_BASE_TABLE_0) = RD;
5178 DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate by mva\n"); 4718 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 1) {
5179 break; 4719 CP15_REG(CP15_TRANSLATION_BASE_TABLE_1) = RD;
5180 case 2: /* invalidate by asid */ 4720 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 2) {
5181 //invalidate_by_asid(state, value); 4721 CP15_REG(CP15_TRANSLATION_BASE_CONTROL) = RD;
5182 //erase_by_asid(core, RD, DATA_TLB); 4722 } else if(CRn == MMU_CACHE_OPS){
5183 //erase_by_asid(core, RD, INSN_TLB); 4723 //LOG_WARNING(Core_ARM11, "cache operations have not implemented.");
5184 DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate by asid\n"); 4724 } else if(CRn == MMU_TLB_OPS){
5185 break; 4725 switch (CRm) {
5186 default: 4726 case 5: // ITLB
5187 break; 4727 switch(OPCODE_2) {
5188 } 4728 case 0: // Invalidate all
5189 break; 4729 LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate all");
5190 default: 4730 break;
5191 break; 4731 case 1: // Invalidate by MVA
5192 } 4732 LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate by mva");
5193 } else if(CRn == MMU_PID){ 4733 break;
5194 if(OPCODE_2 == 0) 4734 case 2: // Invalidate by asid
5195 CP15_REG(CP15_PID) = RD; 4735 LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate by asid");
5196 else if(OPCODE_2 == 1) 4736 break;
5197 CP15_REG(CP15_CONTEXT_ID) = RD; 4737 default:
5198 else if(OPCODE_2 == 3){ 4738 break;
5199 CP15_REG(CP15_THREAD_URO) = RD; 4739 }
5200 } 4740
5201 else{ 4741 break;
5202 printf ("mmu_mcr wrote UNKNOWN - reg %d\n", CRn); 4742 case 6: // DTLB
5203 } 4743 switch(OPCODE_2){
5204 4744 case 0: // Invalidate all
5205 } else { 4745 LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate all");
5206 DEBUG_LOG(ARM11, "mcr is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2); 4746 break;
5207 } 4747 case 1: // Invalidate by MVA
5208 } 4748 LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate by mva");
5209 } 4749 break;
5210 } 4750 case 2: // Invalidate by asid
5211 cpu->Reg[15] += GET_INST_SIZE(cpu); 4751 LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate by asid");
5212 INC_PC(sizeof(mcr_inst)); 4752 break;
5213 FETCH_INST; 4753 default:
5214 GOTO_NEXT_INST; 4754 break;
5215 } 4755 }
5216 MCRR_INST: 4756 break;
5217 MLA_INST: 4757 case 7: // UNIFILED TLB
5218 { 4758 switch(OPCODE_2){
5219 INC_ICOUNTER; 4759 case 0: // invalidate all
5220 mla_inst *inst_cream = (mla_inst *)inst_base->component; 4760 LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate all");
5221 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4761 break;
5222 uint64_t rm = RM; 4762 case 1: // Invalidate by MVA
5223 uint64_t rs = RS; 4763 LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate by mva");
5224 uint64_t rn = RN; 4764 break;
5225 if (inst_cream->Rm == 15 || inst_cream->Rs == 15 || inst_cream->Rn == 15) { 4765 case 2: // Invalidate by asid
5226 DEBUG_LOG(ARM11, "in __line__\n", __LINE__); 4766 LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate by asid");
5227 CITRA_IGNORE_EXIT(-1); 4767 break;
5228 } 4768 default:
5229// RD = dst = RM * RS + RN; 4769 break;
5230 RD = dst = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff); 4770 }
5231 if (inst_cream->S) { 4771 break;
5232 UPDATE_NFLAG(dst); 4772 default:
5233 UPDATE_ZFLAG(dst); 4773 break;
5234 } 4774 }
5235 if (inst_cream->Rd == 15) { 4775 } else if(CRn == MMU_PID) {
5236 INC_PC(sizeof(mla_inst)); 4776 if(OPCODE_2 == 0)
5237 goto DISPATCH; 4777 CP15_REG(CP15_PID) = RD;
5238 } 4778 else if(OPCODE_2 == 1)
5239 } 4779 CP15_REG(CP15_CONTEXT_ID) = RD;
5240 cpu->Reg[15] += GET_INST_SIZE(cpu); 4780 else if(OPCODE_2 == 3) {
5241 INC_PC(sizeof(mla_inst)); 4781 CP15_REG(CP15_THREAD_URO) = RD;
5242 FETCH_INST; 4782 } else {
5243 GOTO_NEXT_INST; 4783 LOG_ERROR(Core_ARM11, "mmu_mcr wrote UNKNOWN - reg %d", CRn);
5244 } 4784 }
5245 MOV_INST: 4785 } else {
5246 { 4786 LOG_ERROR(Core_ARM11, "mcr CRn=%d, CRm=%d OP2=%d is not implemented", CRn, CRm, OPCODE_2);
5247// DEBUG_LOG(ARM11, "mov inst\n"); 4787 }
5248// DEBUG_LOG(ARM11, "pc: %x\n", cpu->Reg[15]); 4788 }
5249// debug_function(cpu); 4789 }
5250// cpu->icount ++; 4790 }
5251 INC_ICOUNTER; 4791 cpu->Reg[15] += GET_INST_SIZE(cpu);
5252 mov_inst *inst_cream = (mov_inst *)inst_base->component; 4792 INC_PC(sizeof(mcr_inst));
5253 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4793 FETCH_INST;
5254 RD = dst = SHIFTER_OPERAND; 4794 GOTO_NEXT_INST;
5255 if (inst_cream->S && (inst_cream->Rd == 15)) { 4795 }
5256 /* cpsr = spsr */ 4796 MCRR_INST:
5257 if (CurrentModeHasSPSR) { 4797 MLA_INST:
5258 cpu->Cpsr = cpu->Spsr_copy; 4798 {
5259 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 4799 mla_inst *inst_cream = (mla_inst *)inst_base->component;
5260 LOAD_NZCVT; 4800 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5261 } 4801 uint64_t rm = RM;
5262 } else if (inst_cream->S) { 4802 uint64_t rs = RS;
5263 UPDATE_NFLAG(dst); 4803 uint64_t rn = RN;
5264 UPDATE_ZFLAG(dst); 4804 if (inst_cream->Rm == 15 || inst_cream->Rs == 15 || inst_cream->Rn == 15) {
5265 UPDATE_CFLAG_WITH_SC; 4805 LOG_ERROR(Core_ARM11, "invalid operands for MLA");
5266 } 4806 CITRA_IGNORE_EXIT(-1);
5267 if (inst_cream->Rd == 15) { 4807 }
5268 INC_PC(sizeof(mov_inst)); 4808 RD = dst = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff);
5269 goto DISPATCH; 4809 if (inst_cream->S) {
5270 } 4810 UPDATE_NFLAG(dst);
5271// return; 4811 UPDATE_ZFLAG(dst);
5272 } 4812 }
5273 cpu->Reg[15] += GET_INST_SIZE(cpu); 4813 if (inst_cream->Rd == 15) {
5274 INC_PC(sizeof(mov_inst)); 4814 INC_PC(sizeof(mla_inst));
5275 FETCH_INST; 4815 goto DISPATCH;
5276 GOTO_NEXT_INST; 4816 }
5277 } 4817 }
5278 MRC_INST: 4818 cpu->Reg[15] += GET_INST_SIZE(cpu);
5279 { 4819 INC_PC(sizeof(mla_inst));
5280 INC_ICOUNTER; 4820 FETCH_INST;
5281 /* NOT IMPL */ 4821 GOTO_NEXT_INST;
5282 mrc_inst *inst_cream = (mrc_inst *)inst_base->component; 4822 }
5283 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4823 MOV_INST:
5284 unsigned int inst = inst_cream->inst; 4824 {
5285 if (inst_cream->Rd == 15) { 4825 mov_inst *inst_cream = (mov_inst *)inst_base->component;
5286 DEBUG_MSG; 4826 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5287 } 4827 RD = dst = SHIFTER_OPERAND;
5288 if (inst_cream->inst == 0xeef04a10) { 4828 if (inst_cream->S && (inst_cream->Rd == 15)) {
5289 /* undefined instruction fmrx */ 4829 if (CurrentModeHasSPSR) {
5290 RD = 0x20000000; 4830 cpu->Cpsr = cpu->Spsr_copy;
5291 CITRA_IGNORE_EXIT(-1); 4831 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5292 goto END; 4832 LOAD_NZCVT;
5293 } else { 4833 }
5294 if (inst_cream->cp_num == 15) { 4834 } else if (inst_cream->S) {
5295 if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) { 4835 UPDATE_NFLAG(dst);
5296 //LET(RD, CONST(0x0007b000)); 4836 UPDATE_ZFLAG(dst);
5297 //LET(RD, CONST(0x410FB760)); 4837 UPDATE_CFLAG_WITH_SC;
5298 //LET(RD, R(CP15_MAIN_ID)); 4838 }
5299 RD = cpu->CP15[CP15(CP15_MAIN_ID)]; 4839 if (inst_cream->Rd == 15) {
5300 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 0) { 4840 INC_PC(sizeof(mov_inst));
5301 //LET(RD, R(CP15_CONTROL)); 4841 goto DISPATCH;
5302 RD = cpu->CP15[CP15(CP15_CONTROL)]; 4842 }
5303 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) { 4843 }
5304 //LET(RD, R(CP15_CONTROL)); 4844 cpu->Reg[15] += GET_INST_SIZE(cpu);
5305 RD = cpu->CP15[CP15(CP15_AUXILIARY_CONTROL)]; 4845 INC_PC(sizeof(mov_inst));
5306 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) { 4846 FETCH_INST;
5307 //LET(RD, R(CP15_CONTROL)); 4847 GOTO_NEXT_INST;
5308 RD = cpu->CP15[CP15(CP15_COPROCESSOR_ACCESS_CONTROL)]; 4848 }
5309 } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) { 4849 MRC_INST:
5310 //LET(RD, R(CP15_DOMAIN_ACCESS_CONTROL)); 4850 {
5311 RD = cpu->CP15[CP15(CP15_DOMAIN_ACCESS_CONTROL)]; 4851 mrc_inst *inst_cream = (mrc_inst *)inst_base->component;
5312 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) { 4852 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5313 //LET(RD, R(CP15_TRANSLATION_BASE_TABLE_0)); 4853 unsigned int inst = inst_cream->inst;
5314 RD = cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_0)]; 4854 if (inst_cream->Rd == 15) {
5315 } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 0) { 4855 DEBUG_MSG;
5316 //LET(RD, R(CP15_FAULT_STATUS)); 4856 }
5317 RD = cpu->CP15[CP15(CP15_FAULT_STATUS)]; 4857 if (inst_cream->inst == 0xeef04a10) {
5318 } else if (CRn == 6 && CRm == 0 && OPCODE_2 == 0) { 4858 // Undefined instruction fmrx
5319 //LET(RD, R(CP15_FAULT_ADDRESS)); 4859 RD = 0x20000000;
5320 RD = cpu->CP15[CP15(CP15_FAULT_ADDRESS)]; 4860 CITRA_IGNORE_EXIT(-1);
5321 } else if (CRn == 0 && CRm == 0 && OPCODE_2 == 1) { 4861 goto END;
5322 //LET(RD, R(CP15_CACHE_TYPE)); 4862 } else {
5323 RD = cpu->CP15[CP15(CP15_CACHE_TYPE)]; 4863 if (inst_cream->cp_num == 15) {
5324 } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 1) { 4864 if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) {
5325 //LET(RD, R(CP15_INSTR_FAULT_STATUS)); 4865 RD = cpu->CP15[CP15(CP15_MAIN_ID)];
5326 RD = cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)]; 4866 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 0) {
5327 } else if (CRn == 13) { 4867 RD = cpu->CP15[CP15(CP15_CONTROL)];
5328 if(OPCODE_2 == 0) 4868 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) {
5329 RD = CP15_REG(CP15_PID); 4869 RD = cpu->CP15[CP15(CP15_AUXILIARY_CONTROL)];
5330 else if(OPCODE_2 == 1) 4870 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) {
5331 RD = CP15_REG(CP15_CONTEXT_ID); 4871 RD = cpu->CP15[CP15(CP15_COPROCESSOR_ACCESS_CONTROL)];
5332 else if(OPCODE_2 == 3){ 4872 } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) {
5333 RD = Memory::KERNEL_MEMORY_VADDR; 4873 RD = cpu->CP15[CP15(CP15_DOMAIN_ACCESS_CONTROL)];
5334 } 4874 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) {
5335 else{ 4875 RD = cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_0)];
5336 printf ("mmu_mrr wrote UNKNOWN - reg %d\n", CRn); 4876 } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 0) {
5337 } 4877 RD = cpu->CP15[CP15(CP15_FAULT_STATUS)];
5338 } 4878 } else if (CRn == 6 && CRm == 0 && OPCODE_2 == 0) {
5339 else { 4879 RD = cpu->CP15[CP15(CP15_FAULT_ADDRESS)];
5340 DEBUG_LOG(ARM11, "mrc is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2); 4880 } else if (CRn == 0 && CRm == 0 && OPCODE_2 == 1) {
5341 } 4881 RD = cpu->CP15[CP15(CP15_CACHE_TYPE)];
5342 } 4882 } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 1) {
5343 //DEBUG_LOG(ARM11, "mrc is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2); 4883 RD = cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)];
5344 } 4884 } else if (CRn == 13) {
5345 } 4885 if(OPCODE_2 == 0)
5346 cpu->Reg[15] += GET_INST_SIZE(cpu); 4886 RD = CP15_REG(CP15_PID);
5347 INC_PC(sizeof(mrc_inst)); 4887 else if(OPCODE_2 == 1)
5348 FETCH_INST; 4888 RD = CP15_REG(CP15_CONTEXT_ID);
5349 GOTO_NEXT_INST; 4889 else if(OPCODE_2 == 3) {
5350 } 4890 RD = Memory::KERNEL_MEMORY_VADDR;
5351 MRRC_INST: 4891 } else {
5352 MRS_INST: 4892 LOG_ERROR(Core_ARM11, "mmu_mrr wrote UNKNOWN - reg %d", CRn);
5353 { 4893 }
5354 INC_ICOUNTER; 4894 } else {
5355 mrs_inst *inst_cream = (mrs_inst *)inst_base->component; 4895 LOG_ERROR(Core_ARM11, "mrc CRn=%d, CRm=%d, OP2=%d is not implemented", CRn, CRm, OPCODE_2);
5356 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4896 }
5357 if (inst_cream->R) { 4897 }
5358 RD = cpu->Spsr_copy; 4898 }
5359 } else { 4899 }
5360 SAVE_NZCVT; 4900 cpu->Reg[15] += GET_INST_SIZE(cpu);
5361 RD = cpu->Cpsr; 4901 INC_PC(sizeof(mrc_inst));
5362 } 4902 FETCH_INST;
5363 } 4903 GOTO_NEXT_INST;
5364 cpu->Reg[15] += GET_INST_SIZE(cpu); 4904 }
5365 INC_PC(sizeof(mrs_inst)); 4905 MRRC_INST:
5366 FETCH_INST; 4906 MRS_INST:
5367 GOTO_NEXT_INST; 4907 {
5368 } 4908 mrs_inst *inst_cream = (mrs_inst *)inst_base->component;
5369 MSR_INST: 4909 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5370 { 4910 if (inst_cream->R) {
5371 INC_ICOUNTER; 4911 RD = cpu->Spsr_copy;
5372 msr_inst *inst_cream = (msr_inst *)inst_base->component; 4912 } else {
5373 const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020; 4913 SAVE_NZCVT;
5374 unsigned int inst = inst_cream->inst; 4914 RD = cpu->Cpsr;
5375 unsigned int operand; 4915 }
5376 4916 }
5377 if (BIT(inst, 25)) { 4917 cpu->Reg[15] += GET_INST_SIZE(cpu);
5378 int rot_imm = BITS(inst, 8, 11) * 2; 4918 INC_PC(sizeof(mrs_inst));
5379 //operand = ROTL(CONST(BITS(0, 7)), CONST(32 - rot_imm)); 4919 FETCH_INST;
5380 operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm); 4920 GOTO_NEXT_INST;
5381 } else { 4921 }
5382 //operand = R(RM); 4922 MSR_INST:
5383 operand = cpu->Reg[BITS(inst, 0, 3)]; 4923 {
5384 } 4924 msr_inst *inst_cream = (msr_inst *)inst_base->component;
5385 uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0) 4925 const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020;
5386 | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0); 4926 unsigned int inst = inst_cream->inst;
5387 uint32_t mask; 4927 unsigned int operand;
5388 if (!inst_cream->R) { 4928
5389 if (InAPrivilegedMode(cpu)) { 4929 if (BIT(inst, 25)) {
5390 if ((operand & StateMask) != 0) { 4930 int rot_imm = BITS(inst, 8, 11) * 2;
5391 /* UNPREDICTABLE */ 4931 operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm);
5392 DEBUG_MSG; 4932 } else {
5393 } else 4933 operand = cpu->Reg[BITS(inst, 0, 3)];
5394 mask = byte_mask & (UserMask | PrivMask); 4934 }
5395 } else { 4935 uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0)
5396 mask = byte_mask & UserMask; 4936 | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0);
5397 } 4937 uint32_t mask;
5398 //LET(CPSR_REG, OR(AND(R(CPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask)))); 4938 if (!inst_cream->R) {
5399 SAVE_NZCVT; 4939 if (InAPrivilegedMode(cpu)) {
5400 4940 if ((operand & StateMask) != 0) {
5401 cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask); 4941 /// UNPREDICTABLE
5402 switch_mode(cpu, cpu->Cpsr & 0x1f); 4942 DEBUG_MSG;
5403 LOAD_NZCVT; 4943 } else
5404 } else { 4944 mask = byte_mask & (UserMask | PrivMask);
5405 if (CurrentModeHasSPSR) { 4945 } else {
5406 mask = byte_mask & (UserMask | PrivMask | StateMask); 4946 mask = byte_mask & UserMask;
5407 //LET(SPSR_REG, OR(AND(R(SPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask)))); 4947 }
5408 cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask); 4948 SAVE_NZCVT;
5409 } 4949
5410 } 4950 cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask);
5411 cpu->Reg[15] += GET_INST_SIZE(cpu); 4951 switch_mode(cpu, cpu->Cpsr & 0x1f);
5412 INC_PC(sizeof(msr_inst)); 4952 LOAD_NZCVT;
5413 FETCH_INST; 4953 } else {
5414 GOTO_NEXT_INST; 4954 if (CurrentModeHasSPSR) {
5415 } 4955 mask = byte_mask & (UserMask | PrivMask | StateMask);
5416 MUL_INST: 4956 cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask);
5417 { 4957 }
5418 INC_ICOUNTER; 4958 }
5419 mul_inst *inst_cream = (mul_inst *)inst_base->component; 4959 cpu->Reg[15] += GET_INST_SIZE(cpu);
5420 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4960 INC_PC(sizeof(msr_inst));
5421// RD = dst = SHIFTER_OPERAND; 4961 FETCH_INST;
5422 uint64_t rm = RM; 4962 GOTO_NEXT_INST;
5423 uint64_t rs = RS; 4963 }
5424 RD = dst = static_cast<uint32_t>((rm * rs) & 0xffffffff); 4964 MUL_INST:
5425 if (inst_cream->S) { 4965 {
5426 UPDATE_NFLAG(dst); 4966 mul_inst *inst_cream = (mul_inst *)inst_base->component;
5427 UPDATE_ZFLAG(dst); 4967 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5428 } 4968 uint64_t rm = RM;
5429 if (inst_cream->Rd == 15) { 4969 uint64_t rs = RS;
5430 INC_PC(sizeof(mul_inst)); 4970 RD = dst = static_cast<uint32_t>((rm * rs) & 0xffffffff);
5431 goto DISPATCH; 4971 if (inst_cream->S) {
5432 } 4972 UPDATE_NFLAG(dst);
5433 } 4973 UPDATE_ZFLAG(dst);
5434 cpu->Reg[15] += GET_INST_SIZE(cpu); 4974 }
5435 INC_PC(sizeof(mul_inst)); 4975 if (inst_cream->Rd == 15) {
5436 FETCH_INST; 4976 INC_PC(sizeof(mul_inst));
5437 GOTO_NEXT_INST; 4977 goto DISPATCH;
5438 } 4978 }
5439 MVN_INST: 4979 }
5440 { 4980 cpu->Reg[15] += GET_INST_SIZE(cpu);
5441 INC_ICOUNTER; 4981 INC_PC(sizeof(mul_inst));
5442 mvn_inst *inst_cream = (mvn_inst *)inst_base->component; 4982 FETCH_INST;
5443 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4983 GOTO_NEXT_INST;
5444// RD = dst = (SHIFTER_OPERAND ^ 0xffffffff); 4984 }
5445 RD = dst = ~SHIFTER_OPERAND; 4985 MVN_INST:
5446 if (inst_cream->S && (inst_cream->Rd == 15)) { 4986 {
5447 /* cpsr = spsr */ 4987 mvn_inst *inst_cream = (mvn_inst *)inst_base->component;
5448 if (CurrentModeHasSPSR) { 4988 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5449 cpu->Cpsr = cpu->Spsr_copy; 4989 RD = dst = ~SHIFTER_OPERAND;
5450 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 4990 if (inst_cream->S && (inst_cream->Rd == 15)) {
5451 LOAD_NZCVT; 4991 if (CurrentModeHasSPSR) {
5452 } 4992 cpu->Cpsr = cpu->Spsr_copy;
5453 } else if (inst_cream->S) { 4993 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5454 UPDATE_NFLAG(dst); 4994 LOAD_NZCVT;
5455 UPDATE_ZFLAG(dst); 4995 }
5456 UPDATE_CFLAG_WITH_SC; 4996 } else if (inst_cream->S) {
5457 } 4997 UPDATE_NFLAG(dst);
5458 if (inst_cream->Rd == 15) { 4998 UPDATE_ZFLAG(dst);
5459 INC_PC(sizeof(mvn_inst)); 4999 UPDATE_CFLAG_WITH_SC;
5460 goto DISPATCH; 5000 }
5461 } 5001 if (inst_cream->Rd == 15) {
5462 } 5002 INC_PC(sizeof(mvn_inst));
5463 cpu->Reg[15] += GET_INST_SIZE(cpu); 5003 goto DISPATCH;
5464 INC_PC(sizeof(mvn_inst)); 5004 }
5465 FETCH_INST; 5005 }
5466 GOTO_NEXT_INST; 5006 cpu->Reg[15] += GET_INST_SIZE(cpu);
5467 } 5007 INC_PC(sizeof(mvn_inst));
5468 ORR_INST: 5008 FETCH_INST;
5469 { 5009 GOTO_NEXT_INST;
5470 INC_ICOUNTER; 5010 }
5471 orr_inst *inst_cream = (orr_inst *)inst_base->component; 5011 ORR_INST:
5472 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5012 {
5473 lop = RN; 5013 orr_inst *inst_cream = (orr_inst *)inst_base->component;
5474 rop = SHIFTER_OPERAND; 5014 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5475// DEBUG_LOG(ARM11, "lop is %x, rop is %x, r2 is %x, r3 is %x\n", lop, rop, cpu->Reg[2], cpu->Reg[3]); 5015 lop = RN;
5476 RD = dst = lop | rop; 5016 rop = SHIFTER_OPERAND;
5477 if (inst_cream->S && (inst_cream->Rd == 15)) { 5017 RD = dst = lop | rop;
5478 /* cpsr = spsr*/ 5018 if (inst_cream->S && (inst_cream->Rd == 15)) {
5479 if (CurrentModeHasSPSR) { 5019 if (CurrentModeHasSPSR) {
5480 cpu->Cpsr = cpu->Spsr_copy; 5020 cpu->Cpsr = cpu->Spsr_copy;
5481 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 5021 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5482 LOAD_NZCVT; 5022 LOAD_NZCVT;
5483 } 5023 }
5484 } else if (inst_cream->S) { 5024 } else if (inst_cream->S) {
5485 UPDATE_NFLAG(dst); 5025 UPDATE_NFLAG(dst);
5486 UPDATE_ZFLAG(dst); 5026 UPDATE_ZFLAG(dst);
5487 UPDATE_CFLAG_WITH_SC; 5027 UPDATE_CFLAG_WITH_SC;
5488// UPDATE_CFLAG(dst, lop, rop); 5028 }
5489 } 5029 if (inst_cream->Rd == 15) {
5490 if (inst_cream->Rd == 15) { 5030 INC_PC(sizeof(orr_inst));
5491 INC_PC(sizeof(orr_inst)); 5031 goto DISPATCH;
5492 goto DISPATCH; 5032 }
5493 } 5033 }
5494 } 5034 cpu->Reg[15] += GET_INST_SIZE(cpu);
5495 cpu->Reg[15] += GET_INST_SIZE(cpu); 5035 INC_PC(sizeof(orr_inst));
5496 INC_PC(sizeof(orr_inst)); 5036 FETCH_INST;
5497 FETCH_INST; 5037 GOTO_NEXT_INST;
5498 GOTO_NEXT_INST; 5038 }
5499 } 5039
5500 PKHBT_INST: 5040 PKHBT_INST:
5501 PKHTB_INST: 5041 {
5502 PLD_INST: 5042 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5503 { 5043 pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
5504 INC_ICOUNTER; 5044 RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000);
5505 /* NOT IMPL */ 5045 }
5506 cpu->Reg[15] += GET_INST_SIZE(cpu); 5046 cpu->Reg[15] += GET_INST_SIZE(cpu);
5507 INC_PC(sizeof(stc_inst)); 5047 INC_PC(sizeof(pkh_inst));
5508 FETCH_INST; 5048 FETCH_INST;
5509 GOTO_NEXT_INST; 5049 GOTO_NEXT_INST;
5510 } 5050 }
5511 QADD_INST: 5051
5512 QADD16_INST: 5052 PKHTB_INST:
5513 QADD8_INST: 5053 {
5514 QADDSUBX_INST: 5054 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5515 QDADD_INST: 5055 pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
5516 QDSUB_INST: 5056 int shift_imm = inst_cream->imm ? inst_cream->imm : 31;
5517 QSUB_INST: 5057 RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000);
5518 QSUB16_INST: 5058 }
5519 QSUB8_INST: 5059 cpu->Reg[15] += GET_INST_SIZE(cpu);
5520 QSUBADDX_INST: 5060 INC_PC(sizeof(pkh_inst));
5521 REV_INST: 5061 FETCH_INST;
5522 { 5062 GOTO_NEXT_INST;
5523 INC_ICOUNTER; 5063 }
5524 rev_inst *inst_cream = (rev_inst *)inst_base->component; 5064
5525 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5065 PLD_INST:
5526 RD = ((RM & 0xff) << 24) | 5066 {
5527 (((RM >> 8) & 0xff) << 16) | 5067 // Instruction not implemented
5528 (((RM >> 16) & 0xff) << 8) | 5068 //LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
5529 ((RM >> 24) & 0xff); 5069 cpu->Reg[15] += GET_INST_SIZE(cpu);
5530 if (inst_cream->Rm == 15) { 5070 INC_PC(sizeof(stc_inst));
5531 DEBUG_LOG(ARM11, "in line %d\n", __LINE__); 5071 FETCH_INST;
5532 CITRA_IGNORE_EXIT(-1); 5072 GOTO_NEXT_INST;
5533 } 5073 }
5534 } 5074
5535 cpu->Reg[15] += GET_INST_SIZE(cpu); 5075 QADD_INST:
5536 INC_PC(sizeof(rev_inst)); 5076 QADD8_INST:
5537 FETCH_INST; 5077 QADD16_INST:
5538 GOTO_NEXT_INST; 5078 QADDSUBX_INST:
5539 } 5079 QSUB8_INST:
5540 REV16_INST: 5080 QSUB16_INST:
5541 { 5081 QSUBADDX_INST:
5542 INC_ICOUNTER; 5082 {
5543 rev_inst *inst_cream = (rev_inst *)inst_base->component; 5083 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5544 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5084 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
5545 RD = (BITS(RM, 0, 7) << 8) | 5085 const u16 rm_lo = (RM & 0xFFFF);
5546 BITS(RM, 8, 15) | 5086 const u16 rm_hi = ((RM >> 16) & 0xFFFF);
5547 (BITS(RM, 16, 23) << 24) | 5087 const u16 rn_lo = (RN & 0xFFFF);
5548 (BITS(RM, 24, 31) << 16); 5088 const u16 rn_hi = ((RN >> 16) & 0xFFFF);
5549 } 5089 const u8 op2 = inst_cream->op2;
5550 cpu->Reg[15] += GET_INST_SIZE(cpu); 5090
5551 INC_PC(sizeof(rev_inst)); 5091 u16 lo_result = 0;
5552 FETCH_INST; 5092 u16 hi_result = 0;
5553 GOTO_NEXT_INST; 5093
5554 } 5094 // QADD16
5555 REVSH_INST: 5095 if (op2 == 0x00) {
5556 RFE_INST: 5096 lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo);
5557 RSB_INST: 5097 hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi);
5558 { 5098 }
5559 INC_ICOUNTER; 5099 // QASX
5560 rsb_inst *inst_cream = (rsb_inst *)inst_base->component; 5100 else if (op2 == 0x01) {
5561 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5101 lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi);
5562 rop = RN; 5102 hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo);
5563 lop = SHIFTER_OPERAND; 5103 }
5564 if (inst_cream->Rn == 15) { 5104 // QSAX
5565 rop += 2 * GET_INST_SIZE(cpu);; 5105 else if (op2 == 0x02) {
5566 } 5106 lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi);
5567 RD = dst = lop - rop; 5107 hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo);
5568 if (inst_cream->S && (inst_cream->Rd == 15)) { 5108 }
5569 /* cpsr = spsr */ 5109 // QSUB16
5570 if (CurrentModeHasSPSR) { 5110 else if (op2 == 0x03) {
5571 cpu->Cpsr = cpu->Spsr_copy; 5111 lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo);
5572 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 5112 hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi);
5573 LOAD_NZCVT; 5113 }
5574 } 5114 // QADD8
5575 } else if (inst_cream->S) { 5115 else if (op2 == 0x04) {
5576 UPDATE_NFLAG(dst); 5116 lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) |
5577 UPDATE_ZFLAG(dst); 5117 ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8;
5578 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); 5118 hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) |
5579// UPDATE_VFLAG((int)dst, (int)lop, (int)rop); 5119 ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8;
5580 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); 5120 }
5581 } 5121 // QSUB8
5582 if (inst_cream->Rd == 15) { 5122 else if (op2 == 0x07) {
5583 INC_PC(sizeof(rsb_inst)); 5123 lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) |
5584 goto DISPATCH; 5124 ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8;
5585 } 5125 hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) |
5586 } 5126 ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8;
5587 cpu->Reg[15] += GET_INST_SIZE(cpu); 5127 }
5588 INC_PC(sizeof(rsb_inst)); 5128
5589 FETCH_INST; 5129 RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
5590 GOTO_NEXT_INST; 5130 }
5591 } 5131
5592 RSC_INST: 5132 cpu->Reg[15] += GET_INST_SIZE(cpu);
5593 { 5133 INC_PC(sizeof(generic_arm_inst));
5594 INC_ICOUNTER; 5134 FETCH_INST;
5595 rsc_inst *inst_cream = (rsc_inst *)inst_base->component; 5135 GOTO_NEXT_INST;
5596 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5136 }
5597 //lop = RN + !cpu->CFlag; 5137
5598 //rop = SHIFTER_OPERAND; 5138 QDADD_INST:
5599 //RD = dst = rop - lop; 5139 QDSUB_INST:
5600 lop = RN; 5140 QSUB_INST:
5601 rop = SHIFTER_OPERAND; 5141 REV_INST:
5602 RD = dst = rop - lop - !cpu->CFlag; 5142 {
5603 if (inst_cream->S && (inst_cream->Rd == 15)) { 5143 rev_inst *inst_cream = (rev_inst *)inst_base->component;
5604 /* cpsr = spsr */ 5144 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5605 if (CurrentModeHasSPSR) { 5145 RD = ((RM & 0xff) << 24) |
5606 cpu->Cpsr = cpu->Spsr_copy; 5146 (((RM >> 8) & 0xff) << 16) |
5607 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 5147 (((RM >> 16) & 0xff) << 8) |
5608 LOAD_NZCVT; 5148 ((RM >> 24) & 0xff);
5609 } 5149 if (inst_cream->Rm == 15) {
5610 } else if (inst_cream->S) { 5150 LOG_ERROR(Core_ARM11, "invalid operand for REV");
5611 UPDATE_NFLAG(dst); 5151 CITRA_IGNORE_EXIT(-1);
5612 UPDATE_ZFLAG(dst); 5152 }
5613// UPDATE_CFLAG(dst, lop, rop); 5153 }
5614// UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop); 5154 cpu->Reg[15] += GET_INST_SIZE(cpu);
5615 UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(rop, lop, !cpu->CFlag); 5155 INC_PC(sizeof(rev_inst));
5616// cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst))); 5156 FETCH_INST;
5617 UPDATE_VFLAG_OVERFLOW_FROM((int)dst, (int)rop, (int)lop); 5157 GOTO_NEXT_INST;
5618 } 5158 }
5619 if (inst_cream->Rd == 15) { 5159 REV16_INST:
5620 INC_PC(sizeof(rsc_inst)); 5160 {
5621 goto DISPATCH; 5161 rev_inst *inst_cream = (rev_inst *)inst_base->component;
5622 } 5162 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5623 } 5163 RD = (BITS(RM, 0, 7) << 8) |
5624 cpu->Reg[15] += GET_INST_SIZE(cpu); 5164 BITS(RM, 8, 15) |
5625 INC_PC(sizeof(rsc_inst)); 5165 (BITS(RM, 16, 23) << 24) |
5626 FETCH_INST; 5166 (BITS(RM, 24, 31) << 16);
5627 GOTO_NEXT_INST; 5167 }
5628 } 5168 cpu->Reg[15] += GET_INST_SIZE(cpu);
5629 SADD16_INST: 5169 INC_PC(sizeof(rev_inst));
5630 SADD8_INST: 5170 FETCH_INST;
5631 SADDSUBX_INST: 5171 GOTO_NEXT_INST;
5632 SBC_INST: 5172 }
5633 { 5173 REVSH_INST:
5634 INC_ICOUNTER; 5174 RFE_INST:
5635 sbc_inst *inst_cream = (sbc_inst *)inst_base->component; 5175 RSB_INST:
5636 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5176 {
5637 lop = SHIFTER_OPERAND + !cpu->CFlag; 5177 rsb_inst *inst_cream = (rsb_inst *)inst_base->component;
5638 rop = RN; 5178 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5639 RD = dst = rop - lop; 5179 rop = RN;
5640 if (inst_cream->S && (inst_cream->Rd == 15)) { 5180 lop = SHIFTER_OPERAND;
5641 /* cpsr = spsr */ 5181 if (inst_cream->Rn == 15) {
5642 if (CurrentModeHasSPSR) { 5182 rop += 2 * GET_INST_SIZE(cpu);;
5643 cpu->Cpsr = cpu->Spsr_copy; 5183 }
5644 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 5184 RD = dst = lop - rop;
5645 LOAD_NZCVT; 5185 if (inst_cream->S && (inst_cream->Rd == 15)) {
5646 } 5186 if (CurrentModeHasSPSR) {
5647 } else if (inst_cream->S) { 5187 cpu->Cpsr = cpu->Spsr_copy;
5648 UPDATE_NFLAG(dst); 5188 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5649 UPDATE_ZFLAG(dst); 5189 LOAD_NZCVT;
5650// UPDATE_CFLAG(dst, lop, rop); 5190 }
5651 //UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop); 5191 } else if (inst_cream->S) {
5652 //rop = rop - !cpu->CFlag; 5192 UPDATE_NFLAG(dst);
5653 if(rop >= !cpu->CFlag) 5193 UPDATE_ZFLAG(dst);
5654 UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND); 5194 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
5655 else 5195 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
5656 UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag); 5196 }
5657// cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst))); 5197 if (inst_cream->Rd == 15) {
5658 UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop); 5198 INC_PC(sizeof(rsb_inst));
5659 } 5199 goto DISPATCH;
5660 if (inst_cream->Rd == 15) { 5200 }
5661 INC_PC(sizeof(sbc_inst)); 5201 }
5662 goto DISPATCH; 5202 cpu->Reg[15] += GET_INST_SIZE(cpu);
5663 } 5203 INC_PC(sizeof(rsb_inst));
5664 } 5204 FETCH_INST;
5665 cpu->Reg[15] += GET_INST_SIZE(cpu); 5205 GOTO_NEXT_INST;
5666 INC_PC(sizeof(sbc_inst)); 5206 }
5667 FETCH_INST; 5207 RSC_INST:
5668 GOTO_NEXT_INST; 5208 {
5669 } 5209 rsc_inst *inst_cream = (rsc_inst *)inst_base->component;
5670 SEL_INST: 5210 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5671 SETEND_INST: 5211 lop = RN;
5672 SHADD16_INST: 5212 rop = SHIFTER_OPERAND;
5673 SHADD8_INST: 5213 RD = dst = rop - lop - !cpu->CFlag;
5674 SHADDSUBX_INST: 5214 if (inst_cream->S && (inst_cream->Rd == 15)) {
5675 SHSUB16_INST: 5215 if (CurrentModeHasSPSR) {
5676 SHSUB8_INST: 5216 cpu->Cpsr = cpu->Spsr_copy;
5677 SHSUBADDX_INST: 5217 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5678 SMLA_INST: 5218 LOAD_NZCVT;
5679 { 5219 }
5680 INC_ICOUNTER; 5220 } else if (inst_cream->S) {
5681 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5221 UPDATE_NFLAG(dst);
5682 smla_inst *inst_cream = (smla_inst *)inst_base->component; 5222 UPDATE_ZFLAG(dst);
5683 int32_t operand1, operand2; 5223 UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(rop, lop, !cpu->CFlag);
5684 if (inst_cream->x == 0) 5224 UPDATE_VFLAG_OVERFLOW_FROM((int)dst, (int)rop, (int)lop);
5685 operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); 5225 }
5686 else 5226 if (inst_cream->Rd == 15) {
5687 operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); 5227 INC_PC(sizeof(rsc_inst));
5688 5228 goto DISPATCH;
5689 if (inst_cream->y == 0) 5229 }
5690 operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); 5230 }
5691 else 5231 cpu->Reg[15] += GET_INST_SIZE(cpu);
5692 operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); 5232 INC_PC(sizeof(rsc_inst));
5693 RD = operand1 * operand2 + RN; 5233 FETCH_INST;
5694 //FIXME: UPDATE Q FLAGS 5234 GOTO_NEXT_INST;
5695 } 5235 }
5696 cpu->Reg[15] += GET_INST_SIZE(cpu); 5236
5697 INC_PC(sizeof(smla_inst)); 5237 SADD8_INST:
5698 FETCH_INST; 5238 SADD16_INST:
5699 GOTO_NEXT_INST; 5239 SADDSUBX_INST:
5700 } 5240 SSUBADDX_INST:
5701 SMLAD_INST: 5241 SSUB16_INST:
5702 { 5242 {
5703 INC_ICOUNTER; 5243 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5704 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5244 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
5705 smlad_inst *inst_cream = (smlad_inst *)inst_base->component; 5245
5706 long long int rm = cpu->Reg[inst_cream->Rm]; 5246 const s16 rn_lo = (RN & 0xFFFF);
5707 long long int rn = cpu->Reg[inst_cream->Rn]; 5247 const s16 rn_hi = ((RN >> 16) & 0xFFFF);
5708 long long int ra = cpu->Reg[inst_cream->Ra]; 5248 const s16 rm_lo = (RM & 0xFFFF);
5709 /* see SMUAD */ 5249 const s16 rm_hi = ((RM >> 16) & 0xFFFF);
5710 if(inst_cream->Ra == 15) 5250
5711 CITRA_IGNORE_EXIT(-1); 5251 s32 lo_result = 0;
5712 int operand2 = (inst_cream->m)? ROTATE_RIGHT_32(rm, 16):rm; 5252 s32 hi_result = 0;
5713 5253
5714 int half_rn, half_operand2; 5254 // SADD16
5715 half_rn = rn & 0xFFFF; 5255 if (inst_cream->op2 == 0x00) {
5716 half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; 5256 lo_result = (rn_lo + rm_lo);
5717 5257 hi_result = (rn_hi + rm_hi);
5718 half_operand2 = operand2 & 0xFFFF; 5258 }
5719 half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; 5259 // SASX
5720 5260 else if (inst_cream->op2 == 0x01) {
5721 long long int product1 = half_rn * half_operand2; 5261 lo_result = (rn_lo - rm_hi);
5722 5262 hi_result = (rn_hi + rm_lo);
5723 half_rn = (rn & 0xFFFF0000) >> 16; 5263 }
5724 half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; 5264 // SSAX
5725 5265 else if (inst_cream->op2 == 0x02) {
5726 half_operand2 = (operand2 & 0xFFFF0000) >> 16; 5266 lo_result = (rn_lo + rm_hi);
5727 half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; 5267 hi_result = (rn_hi - rm_lo);
5728 5268 }
5729 long long int product2 = half_rn * half_operand2; 5269 // SSUB16
5730 5270 else if (inst_cream->op2 == 0x03) {
5731 long long int signed_ra = (ra & 0x80000000)? (0xFFFFFFFF00000000LL) | ra : ra; 5271 lo_result = (rn_lo - rm_lo);
5732 long long int result = product1 + product2 + signed_ra; 5272 hi_result = (rn_hi - rm_hi);
5733 cpu->Reg[inst_cream->Rd] = result & 0xFFFFFFFF; 5273 }
5734 /* FIXME , should check Signed overflow */ 5274
5735 } 5275 RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
5736 cpu->Reg[15] += GET_INST_SIZE(cpu); 5276
5737 INC_PC(sizeof(umlal_inst)); 5277 if (lo_result >= 0) {
5738 FETCH_INST; 5278 cpu->Cpsr |= (1 << 16);
5739 GOTO_NEXT_INST; 5279 cpu->Cpsr |= (1 << 17);
5740 } 5280 } else {
5741 5281 cpu->Cpsr &= ~(1 << 16);
5742 SMLAL_INST: 5282 cpu->Cpsr &= ~(1 << 17);
5743 { 5283 }
5744 INC_ICOUNTER; 5284
5745 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5285 if (hi_result >= 0) {
5746 umlal_inst *inst_cream = (umlal_inst *)inst_base->component; 5286 cpu->Cpsr |= (1 << 18);
5747 long long int rm = RM; 5287 cpu->Cpsr |= (1 << 19);
5748 long long int rs = RS; 5288 } else {
5749 if (BIT(rm, 31)) { 5289 cpu->Cpsr &= ~(1 << 18);
5750 rm |= 0xffffffff00000000LL; 5290 cpu->Cpsr &= ~(1 << 19);
5751 } 5291 }
5752 if (BIT(rs, 31)) { 5292 }
5753 rs |= 0xffffffff00000000LL; 5293
5754 } 5294 cpu->Reg[15] += GET_INST_SIZE(cpu);
5755 long long int rst = rm * rs; 5295 INC_PC(sizeof(generic_arm_inst));
5756 long long int rdhi32 = RDHI; 5296 FETCH_INST;
5757 long long int hilo = (rdhi32 << 32) + RDLO; 5297 GOTO_NEXT_INST;
5758 rst += hilo; 5298 }
5759 RDLO = BITS(rst, 0, 31); 5299
5760 RDHI = BITS(rst, 32, 63); 5300 SBC_INST:
5761 if (inst_cream->S) { 5301 {
5762 cpu->NFlag = BIT(RDHI, 31); 5302 sbc_inst *inst_cream = (sbc_inst *)inst_base->component;
5763 cpu->ZFlag = (RDHI == 0 && RDLO == 0); 5303 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5764 } 5304 lop = SHIFTER_OPERAND + !cpu->CFlag;
5765 } 5305 rop = RN;
5766 cpu->Reg[15] += GET_INST_SIZE(cpu); 5306 RD = dst = rop - lop;
5767 INC_PC(sizeof(umlal_inst)); 5307 if (inst_cream->S && (inst_cream->Rd == 15)) {
5768 FETCH_INST; 5308 if (CurrentModeHasSPSR) {
5769 GOTO_NEXT_INST; 5309 cpu->Cpsr = cpu->Spsr_copy;
5770 } 5310 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5771 SMLALXY_INST: 5311 LOAD_NZCVT;
5772 SMLALD_INST: 5312 }
5773 SMLAW_INST: 5313 } else if (inst_cream->S) {
5774 SMLSD_INST: 5314 UPDATE_NFLAG(dst);
5775 SMLSLD_INST: 5315 UPDATE_ZFLAG(dst);
5776 SMMLA_INST: 5316
5777 SMMLS_INST: 5317 if(rop >= !cpu->CFlag)
5778 SMMUL_INST: 5318 UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND);
5779 SMUAD_INST: 5319 else
5780 SMUL_INST: 5320 UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag);
5781 { 5321
5782 INC_ICOUNTER; 5322 UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop);
5783 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5323 }
5784 smul_inst *inst_cream = (smul_inst *)inst_base->component; 5324 if (inst_cream->Rd == 15) {
5785 uint32_t operand1, operand2; 5325 INC_PC(sizeof(sbc_inst));
5786 if (inst_cream->x == 0) 5326 goto DISPATCH;
5787 operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); 5327 }
5788 else 5328 }
5789 operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); 5329 cpu->Reg[15] += GET_INST_SIZE(cpu);
5790 5330 INC_PC(sizeof(sbc_inst));
5791 if (inst_cream->y == 0) 5331 FETCH_INST;
5792 operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); 5332 GOTO_NEXT_INST;
5793 else 5333 }
5794 operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); 5334
5795 RD = operand1 * operand2; 5335 SEL_INST:
5796 } 5336 {
5797 cpu->Reg[15] += GET_INST_SIZE(cpu); 5337 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5798 INC_PC(sizeof(smul_inst)); 5338 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
5799 FETCH_INST; 5339
5800 GOTO_NEXT_INST; 5340 const u32 to = RM;
5801 } 5341 const u32 from = RN;
5802 SMULL_INST: 5342 const u32 cpsr = cpu->Cpsr;
5803 { 5343
5804 INC_ICOUNTER; 5344 u32 result;
5805 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5345 if (cpsr & (1 << 16))
5806 umull_inst *inst_cream = (umull_inst *)inst_base->component; 5346 result = from & 0xff;
5807// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst); 5347 else
5808 int64_t rm = RM; 5348 result = to & 0xff;
5809 int64_t rs = RS; 5349
5810 if (BIT(rm, 31)) { 5350 if (cpsr & (1 << 17))
5811 rm |= 0xffffffff00000000LL; 5351 result |= from & 0x0000ff00;
5812 } 5352 else
5813 if (BIT(rs, 31)) { 5353 result |= to & 0x0000ff00;
5814 rs |= 0xffffffff00000000LL; 5354
5815 } 5355 if (cpsr & (1 << 18))
5816 int64_t rst = rm * rs; 5356 result |= from & 0x00ff0000;
5817 RDHI = BITS(rst, 32, 63); 5357 else
5818 RDLO = BITS(rst, 0, 31); 5358 result |= to & 0x00ff0000;
5819 5359
5820 5360 if (cpsr & (1 << 19))
5821 if (inst_cream->S) { 5361 result |= from & 0xff000000;
5822 cpu->NFlag = BIT(RDHI, 31); 5362 else
5823 cpu->ZFlag = (RDHI == 0 && RDLO == 0); 5363 result |= to & 0xff000000;
5824 } 5364
5825 } 5365 RD = result;
5826 cpu->Reg[15] += GET_INST_SIZE(cpu); 5366 }
5827 INC_PC(sizeof(umull_inst)); 5367
5828 FETCH_INST; 5368 cpu->Reg[15] += GET_INST_SIZE(cpu);
5829 GOTO_NEXT_INST; 5369 INC_PC(sizeof(generic_arm_inst));
5830 } 5370 FETCH_INST;
5831 SMULW_INST: 5371 GOTO_NEXT_INST;
5832 INC_ICOUNTER; 5372 }
5833 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5373
5834 smlad_inst *inst_cream = (smlad_inst *)inst_base->component; 5374 SETEND_INST:
5835// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst); 5375 SHADD16_INST:
5836 int64_t rm = RM; 5376 SHADD8_INST:
5837 int64_t rn = RN; 5377 SHADDSUBX_INST:
5838 if (inst_cream->m) 5378 SHSUB16_INST:
5839 rm = BITS(rm,16 , 31); 5379 SHSUB8_INST:
5840 else 5380 SHSUBADDX_INST:
5841 rm = BITS(rm,0 , 15); 5381 SMLA_INST:
5842 int64_t rst = rm * rn; 5382 {
5843 RD = BITS(rst, 16, 47); 5383 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5844 } 5384 smla_inst *inst_cream = (smla_inst *)inst_base->component;
5845 cpu->Reg[15] += GET_INST_SIZE(cpu); 5385 int32_t operand1, operand2;
5846 INC_PC(sizeof(smlad_inst)); 5386 if (inst_cream->x == 0)
5847 FETCH_INST; 5387 operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
5848 GOTO_NEXT_INST; 5388 else
5849 5389 operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
5850 SMUSD_INST: 5390
5851 SRS_INST: 5391 if (inst_cream->y == 0)
5852 SSAT_INST: 5392 operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
5853 SSAT16_INST: 5393 else
5854 SSUB16_INST: 5394 operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
5855 SSUB8_INST: 5395 RD = operand1 * operand2 + RN;
5856 SSUBADDX_INST: 5396
5857 STC_INST: 5397 // TODO: FIXME: UPDATE Q FLAGS
5858 { 5398 }
5859 INC_ICOUNTER; 5399 cpu->Reg[15] += GET_INST_SIZE(cpu);
5860 /* NOT IMPL */ 5400 INC_PC(sizeof(smla_inst));
5861 cpu->Reg[15] += GET_INST_SIZE(cpu); 5401 FETCH_INST;
5862 INC_PC(sizeof(stc_inst)); 5402 GOTO_NEXT_INST;
5863 FETCH_INST; 5403 }
5864 GOTO_NEXT_INST; 5404 SMLAD_INST:
5865 } 5405 {
5866 STM_INST: 5406 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5867 { 5407 smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
5868 INC_ICOUNTER; 5408 long long int rm = cpu->Reg[inst_cream->Rm];
5869 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 5409 long long int rn = cpu->Reg[inst_cream->Rn];
5870 unsigned int inst = inst_cream->inst; 5410 long long int ra = cpu->Reg[inst_cream->Ra];
5871 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5411
5872 int i; 5412 // See SMUAD
5873 unsigned int Rn = BITS(inst, 16, 19); 5413 if(inst_cream->Ra == 15)
5874 unsigned int old_RN = cpu->Reg[Rn]; 5414 CITRA_IGNORE_EXIT(-1);
5875 5415 int operand2 = (inst_cream->m)? ROTATE_RIGHT_32(rm, 16):rm;
5876 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); 5416 int half_rn, half_operand2;
5877 if (fault) goto MMU_EXCEPTION; 5417
5878 if (BIT(inst_cream->inst, 22) == 1) { 5418 half_rn = rn & 0xFFFF;
5879// DEBUG_MSG; 5419 half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn;
5880 #if 1 5420
5881 for (i = 0; i < 13; i++) { 5421 half_operand2 = operand2 & 0xFFFF;
5882 if(BIT(inst_cream->inst, i)){ 5422 half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2;
5883 fault = check_address_validity(cpu, addr, &phys_addr, 0); 5423
5884 if (fault) { 5424 long long int product1 = half_rn * half_operand2;
5885 goto MMU_EXCEPTION; 5425
5886 } 5426 half_rn = (rn & 0xFFFF0000) >> 16;
5887 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); 5427 half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn;
5888 if (fault) goto MMU_EXCEPTION; 5428
5889 addr += 4; 5429 half_operand2 = (operand2 & 0xFFFF0000) >> 16;
5890 phys_addr += 4; 5430 half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2;
5891 } 5431
5892 } 5432 long long int product2 = half_rn * half_operand2;
5893 if (BIT(inst_cream->inst, 13)) { 5433
5894 if (cpu->Mode == USER32MODE) { 5434 long long int signed_ra = (ra & 0x80000000)? (0xFFFFFFFF00000000LL) | ra : ra;
5895 fault = check_address_validity(cpu, addr, &phys_addr, 0); 5435 long long int result = product1 + product2 + signed_ra;
5896 if (fault) { 5436 cpu->Reg[inst_cream->Rd] = result & 0xFFFFFFFF;
5897 goto MMU_EXCEPTION; 5437
5898 } 5438 // TODO: FIXME should check Signed overflow
5899 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); 5439 }
5900 if (fault) goto MMU_EXCEPTION; 5440 cpu->Reg[15] += GET_INST_SIZE(cpu);
5901 addr += 4; 5441 INC_PC(sizeof(umlal_inst));
5902 phys_addr += 4; 5442 FETCH_INST;
5903 } else { 5443 GOTO_NEXT_INST;
5904 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[0], 32); 5444 }
5905 if (fault) goto MMU_EXCEPTION; 5445
5906 addr += 4; 5446 SMLAL_INST:
5907 phys_addr += 4; 5447 {
5908 } 5448 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5909 } 5449 umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
5910 if (BIT(inst_cream->inst, 14)) { 5450 long long int rm = RM;
5911 if (cpu->Mode == USER32MODE) { 5451 long long int rs = RS;
5912 fault = check_address_validity(cpu, addr, &phys_addr, 0); 5452 if (BIT(rm, 31)) {
5913 if (fault) { 5453 rm |= 0xffffffff00000000LL;
5914 goto MMU_EXCEPTION; 5454 }
5915 } 5455 if (BIT(rs, 31)) {
5916 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); 5456 rs |= 0xffffffff00000000LL;
5917 if (fault) goto MMU_EXCEPTION; 5457 }
5918 addr += 4; 5458 long long int rst = rm * rs;
5919 phys_addr += 4; 5459 long long int rdhi32 = RDHI;
5920 } else { 5460 long long int hilo = (rdhi32 << 32) + RDLO;
5921 fault = check_address_validity(cpu, addr, &phys_addr, 0); 5461 rst += hilo;
5922 if (fault) { 5462 RDLO = BITS(rst, 0, 31);
5923 goto MMU_EXCEPTION; 5463 RDHI = BITS(rst, 32, 63);
5924 } 5464 if (inst_cream->S) {
5925 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[1], 32); 5465 cpu->NFlag = BIT(RDHI, 31);
5926 if (fault) goto MMU_EXCEPTION; 5466 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
5927 addr += 4; 5467 }
5928 phys_addr += 4; 5468 }
5929 } 5469 cpu->Reg[15] += GET_INST_SIZE(cpu);
5930 } 5470 INC_PC(sizeof(umlal_inst));
5931 if (BIT(inst_cream->inst, 15)) { 5471 FETCH_INST;
5932 fault = check_address_validity(cpu, addr, &phys_addr, 0); 5472 GOTO_NEXT_INST;
5933 if (fault) { 5473 }
5934 goto MMU_EXCEPTION; 5474 SMLALXY_INST:
5935 } 5475 SMLALD_INST:
5936 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32); 5476 SMLAW_INST:
5937 if (fault) goto MMU_EXCEPTION; 5477 SMLSD_INST:
5938 } 5478 SMLSLD_INST:
5939 #endif 5479 SMMLA_INST:
5940 } else { 5480 SMMLS_INST:
5941 for( i = 0; i < 15; i ++ ){ 5481 SMMUL_INST:
5942 if(BIT(inst_cream->inst, i)){ 5482 SMUAD_INST:
5943 //arch_write_memory(cpu, bb, Addr, R(i), 32); 5483 SMUL_INST:
5944 //bus_write(32, addr, cpu->Reg[i]); 5484 {
5945 fault = check_address_validity(cpu, addr, &phys_addr, 0); 5485 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5946 if (fault) { 5486 smul_inst *inst_cream = (smul_inst *)inst_base->component;
5947 goto MMU_EXCEPTION; 5487 uint32_t operand1, operand2;
5948 } 5488 if (inst_cream->x == 0)
5949 if(i == Rn) 5489 operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
5950 fault = interpreter_write_memory(addr, phys_addr, old_RN, 32); 5490 else
5951 else 5491 operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
5952 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); 5492
5953 if (fault) goto MMU_EXCEPTION; 5493 if (inst_cream->y == 0)
5954 addr += 4; 5494 operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
5955 phys_addr += 4; 5495 else
5956 //Addr = ADD(Addr, CONST(4)); 5496 operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
5957 } 5497 RD = operand1 * operand2;
5958 } 5498 }
5959 5499 cpu->Reg[15] += GET_INST_SIZE(cpu);
5960 /* check pc reg*/ 5500 INC_PC(sizeof(smul_inst));
5961 if(BIT(inst_cream->inst, i)){ 5501 FETCH_INST;
5962 //arch_write_memory(cpu, bb, Addr, STOREM_CHECK_PC, 32); 5502 GOTO_NEXT_INST;
5963 //bus_write(32, addr, cpu->Reg[i] + 8); 5503 }
5964 fault = check_address_validity(cpu, addr, &phys_addr, 0); 5504 SMULL_INST:
5965 if (fault) { 5505 {
5966 goto MMU_EXCEPTION; 5506 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5967 } 5507 umull_inst *inst_cream = (umull_inst *)inst_base->component;
5968 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32); 5508 int64_t rm = RM;
5969 if (fault) goto MMU_EXCEPTION; 5509 int64_t rs = RS;
5970 } 5510 if (BIT(rm, 31)) {
5971 } 5511 rm |= 0xffffffff00000000LL;
5972 } 5512 }
5973 cpu->Reg[15] += GET_INST_SIZE(cpu); 5513 if (BIT(rs, 31)) {
5974 INC_PC(sizeof(ldst_inst)); 5514 rs |= 0xffffffff00000000LL;
5975 FETCH_INST; 5515 }
5976 GOTO_NEXT_INST; 5516 int64_t rst = rm * rs;
5977 } 5517 RDHI = BITS(rst, 32, 63);
5978 SXTB_INST: 5518 RDLO = BITS(rst, 0, 31);
5979 { 5519
5980 INC_ICOUNTER; 5520 if (inst_cream->S) {
5981 sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; 5521 cpu->NFlag = BIT(RDHI, 31);
5982 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5522 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
5983 if (inst_cream->Rm == 15) { 5523 }
5984 DEBUG_LOG(ARM11, "line is %d\n", __LINE__); 5524 }
5985 CITRA_IGNORE_EXIT(-1); 5525 cpu->Reg[15] += GET_INST_SIZE(cpu);
5986 } 5526 INC_PC(sizeof(umull_inst));
5987 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); 5527 FETCH_INST;
5988 if (BIT(operand2, 7)) { 5528 GOTO_NEXT_INST;
5989 operand2 |= 0xffffff00; 5529 }
5990 } else 5530
5991 operand2 &= 0xff; 5531 SMULW_INST:
5992 RD = operand2; 5532 {
5993 } 5533 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5994 cpu->Reg[15] += GET_INST_SIZE(cpu); 5534 smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
5995 INC_PC(sizeof(sxtb_inst)); 5535 int64_t rm = RM;
5996 FETCH_INST; 5536 int64_t rn = RN;
5997 GOTO_NEXT_INST; 5537 if (inst_cream->m)
5998 } 5538 rm = BITS(rm, 16, 31);
5999 STR_INST: 5539 else
6000 { 5540 rm = BITS(rm, 0, 15);
6001 INC_ICOUNTER; 5541 int64_t rst = rm * rn;
6002 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 5542 RD = BITS(rst, 16, 47);
6003 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5543 }
6004 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); 5544 cpu->Reg[15] += GET_INST_SIZE(cpu);
6005 if (fault) goto MMU_EXCEPTION; 5545 INC_PC(sizeof(smlad_inst));
6006 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; 5546 FETCH_INST;
6007 //bus_write(32, addr, value); 5547 GOTO_NEXT_INST;
6008 fault = interpreter_write_memory(addr, phys_addr, value, 32); 5548 }
6009 if (fault) goto MMU_EXCEPTION; 5549
6010 } 5550 SMUSD_INST:
6011 cpu->Reg[15] += GET_INST_SIZE(cpu); 5551 SRS_INST:
6012 INC_PC(sizeof(ldst_inst)); 5552 SSAT_INST:
6013 FETCH_INST; 5553 {
6014 GOTO_NEXT_INST; 5554 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
6015 } 5555 ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
6016 UXTB_INST: 5556
6017 { 5557 u8 shift_type = inst_cream->shift_type;
6018 INC_ICOUNTER; 5558 u8 shift_amount = inst_cream->imm5;
6019 uxtb_inst *inst_cream = (uxtb_inst *)inst_base->component; 5559 u32 rn_val = RN;
6020 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5560
6021 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) 5561 // 32-bit ASR is encoded as an amount of 0.
6022 & 0xff; 5562 if (shift_type == 1 && shift_amount == 0)
6023 RD = operand2; 5563 shift_amount = 31;
6024 } 5564
6025 cpu->Reg[15] += GET_INST_SIZE(cpu); 5565 if (shift_type == 0)
6026 INC_PC(sizeof(uxtb_inst)); 5566 rn_val <<= shift_amount;
6027 FETCH_INST; 5567 else if (shift_type == 1)
6028 GOTO_NEXT_INST; 5568 rn_val = ((s32)rn_val >> shift_amount);
6029 } 5569
6030 UXTAB_INST: 5570 bool saturated = false;
6031 { 5571 rn_val = ARMul_SignedSatQ(rn_val, inst_cream->sat_imm, &saturated);
6032 INC_ICOUNTER; 5572
6033 uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component; 5573 if (saturated)
6034 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5574 cpu->Cpsr |= (1 << 27);
6035 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) 5575
6036 & 0xff; 5576 RD = rn_val;
6037 RD = RN + operand2; 5577 }
6038 } 5578
6039 cpu->Reg[15] += GET_INST_SIZE(cpu); 5579 cpu->Reg[15] += GET_INST_SIZE(cpu);
6040 INC_PC(sizeof(uxtab_inst)); 5580 INC_PC(sizeof(ssat_inst));
6041 FETCH_INST; 5581 FETCH_INST;
6042 GOTO_NEXT_INST; 5582 GOTO_NEXT_INST;
6043 } 5583 }
6044 STRB_INST: 5584
6045 { 5585 SSAT16_INST:
6046 INC_ICOUNTER; 5586 SSUB8_INST:
6047 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 5587 STC_INST:
6048 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5588 {
6049 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); 5589 // Instruction not implemented
6050 if (fault) goto MMU_EXCEPTION; 5590 //LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
6051 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; 5591 cpu->Reg[15] += GET_INST_SIZE(cpu);
6052 //bus_write(8, addr, value); 5592 INC_PC(sizeof(stc_inst));
6053 fault = interpreter_write_memory(addr, phys_addr, value, 8); 5593 FETCH_INST;
6054 if (fault) goto MMU_EXCEPTION; 5594 GOTO_NEXT_INST;
6055 } 5595 }
6056 cpu->Reg[15] += GET_INST_SIZE(cpu); 5596 STM_INST:
6057 INC_PC(sizeof(ldst_inst)); 5597 {
6058 FETCH_INST; 5598 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6059 GOTO_NEXT_INST; 5599 unsigned int inst = inst_cream->inst;
6060 } 5600 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6061 STRBT_INST: 5601 int i;
6062 { 5602 unsigned int Rn = BITS(inst, 16, 19);
6063 INC_ICOUNTER; 5603 unsigned int old_RN = cpu->Reg[Rn];
6064 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 5604
6065 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5605 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6066 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); 5606 if (fault) goto MMU_EXCEPTION;
6067 if (fault) goto MMU_EXCEPTION; 5607 if (BIT(inst_cream->inst, 22) == 1) {
6068 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; 5608 for (i = 0; i < 13; i++) {
6069 //bus_write(8, addr, value); 5609 if(BIT(inst_cream->inst, i)){
6070 fault = interpreter_write_memory(addr, phys_addr, value, 8); 5610 fault = check_address_validity(cpu, addr, &phys_addr, 0);
6071 if (fault) goto MMU_EXCEPTION; 5611 if (fault) goto MMU_EXCEPTION;
6072 } 5612 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
6073 cpu->Reg[15] += GET_INST_SIZE(cpu); 5613 if (fault) goto MMU_EXCEPTION;
6074 //if (BITS(inst_cream->inst, 12, 15) == 15) 5614 addr += 4;
6075 // goto DISPATCH; 5615 phys_addr += 4;
6076 INC_PC(sizeof(ldst_inst)); 5616 }
6077 FETCH_INST; 5617 }
6078 GOTO_NEXT_INST; 5618 if (BIT(inst_cream->inst, 13)) {
6079 } 5619 if (cpu->Mode == USER32MODE) {
6080 STRD_INST: 5620 fault = check_address_validity(cpu, addr, &phys_addr, 0);
6081 { 5621 if (fault) goto MMU_EXCEPTION;
6082 INC_ICOUNTER; 5622 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
6083 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 5623 if (fault) goto MMU_EXCEPTION;
6084 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5624 addr += 4;
6085 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); 5625 phys_addr += 4;
6086 if (fault) goto MMU_EXCEPTION; 5626 } else {
6087 uint32_t rear_phys_addr; 5627 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[0], 32);
6088 fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 0); 5628 if (fault) goto MMU_EXCEPTION;
5629 addr += 4;
5630 phys_addr += 4;
5631 }
5632 }
5633 if (BIT(inst_cream->inst, 14)) {
5634 if (cpu->Mode == USER32MODE) {
5635 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5636 if (fault) goto MMU_EXCEPTION;
5637 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
5638 if (fault) goto MMU_EXCEPTION;
5639 addr += 4;
5640 phys_addr += 4;
5641 } else {
5642 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5643 if (fault) goto MMU_EXCEPTION;
5644 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[1], 32);
5645 if (fault) goto MMU_EXCEPTION;
5646 addr += 4;
5647 phys_addr += 4;
5648 }
5649 }
5650 if (BIT(inst_cream->inst, 15)) {
5651 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5652 if (fault) goto MMU_EXCEPTION;
5653 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32);
5654 if (fault) goto MMU_EXCEPTION;
5655 }
5656 } else {
5657 for( i = 0; i < 15; i ++ ) {
5658 if(BIT(inst_cream->inst, i)) {
5659 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5660 if (fault) goto MMU_EXCEPTION;
5661 if(i == Rn)
5662 fault = interpreter_write_memory(addr, phys_addr, old_RN, 32);
5663 else
5664 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
5665 if (fault) goto MMU_EXCEPTION;
5666 addr += 4;
5667 phys_addr += 4;
5668 }
5669 }
5670
5671 // Check PC reg
5672 if(BIT(inst_cream->inst, i)) {
5673 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5674 if (fault) goto MMU_EXCEPTION;
5675 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32);
5676 if (fault) goto MMU_EXCEPTION;
5677 }
5678 }
5679 }
5680 cpu->Reg[15] += GET_INST_SIZE(cpu);
5681 INC_PC(sizeof(ldst_inst));
5682 FETCH_INST;
5683 GOTO_NEXT_INST;
5684 }
5685 SXTB_INST:
5686 {
5687 sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
5688 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5689 if (inst_cream->Rm == 15) {
5690 LOG_ERROR(Core_ARM11, "invalid operand for SXTB");
5691 CITRA_IGNORE_EXIT(-1);
5692 }
5693 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
5694 if (BIT(operand2, 7)) {
5695 operand2 |= 0xffffff00;
5696 } else
5697 operand2 &= 0xff;
5698 RD = operand2;
5699 }
5700 cpu->Reg[15] += GET_INST_SIZE(cpu);
5701 INC_PC(sizeof(sxtb_inst));
5702 FETCH_INST;
5703 GOTO_NEXT_INST;
5704 }
5705 STR_INST:
5706 {
5707 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5708 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5709 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
5710 if (fault) goto MMU_EXCEPTION;
5711 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
5712 fault = interpreter_write_memory(addr, phys_addr, value, 32);
5713 if (fault) goto MMU_EXCEPTION;
5714 }
5715 cpu->Reg[15] += GET_INST_SIZE(cpu);
5716 INC_PC(sizeof(ldst_inst));
5717 FETCH_INST;
5718 GOTO_NEXT_INST;
5719 }
5720 UXTB_INST:
5721 {
5722 uxtb_inst *inst_cream = (uxtb_inst *)inst_base->component;
5723 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5724 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
5725 & 0xff;
5726 RD = operand2;
5727 }
5728 cpu->Reg[15] += GET_INST_SIZE(cpu);
5729 INC_PC(sizeof(uxtb_inst));
5730 FETCH_INST;
5731 GOTO_NEXT_INST;
5732 }
5733 UXTAB_INST:
5734 {
5735 uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component;
5736 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5737 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
5738 & 0xff;
5739 RD = RN + operand2;
5740 }
5741 cpu->Reg[15] += GET_INST_SIZE(cpu);
5742 INC_PC(sizeof(uxtab_inst));
5743 FETCH_INST;
5744 GOTO_NEXT_INST;
5745 }
5746 STRB_INST:
5747 {
5748 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5749 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5750 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
5751 if (fault) goto MMU_EXCEPTION;
5752 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
5753 fault = interpreter_write_memory(addr, phys_addr, value, 8);
5754 if (fault) goto MMU_EXCEPTION;
5755 }
5756 cpu->Reg[15] += GET_INST_SIZE(cpu);
5757 INC_PC(sizeof(ldst_inst));
5758 FETCH_INST;
5759 GOTO_NEXT_INST;
5760 }
5761 STRBT_INST:
5762 {
5763 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5764 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5765 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
5766 if (fault) goto MMU_EXCEPTION;
5767 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
5768 fault = interpreter_write_memory(addr, phys_addr, value, 8);
5769 if (fault) goto MMU_EXCEPTION;
5770 }
5771 cpu->Reg[15] += GET_INST_SIZE(cpu);
5772 INC_PC(sizeof(ldst_inst));
5773 FETCH_INST;
5774 GOTO_NEXT_INST;
5775 }
5776 STRD_INST:
5777 {
5778 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5779 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5780 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
5781 if (fault) goto MMU_EXCEPTION;
5782 uint32_t rear_phys_addr;
5783 fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 0);
6089 if (fault){ 5784 if (fault){
6090 ERROR_LOG(ARM11, "mmu fault , should rollback the above get_addr\n"); 5785 LOG_ERROR(Core_ARM11, "MMU fault , should rollback the above get_addr");
6091 CITRA_IGNORE_EXIT(-1); 5786 CITRA_IGNORE_EXIT(-1);
6092 goto MMU_EXCEPTION; 5787 goto MMU_EXCEPTION;
6093 } 5788 }
6094 5789
6095 //fault = inst_cream->get_addr(cpu, inst_cream->inst, addr + 4, phys_addr + 4, 0); 5790 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
6096 //if (fault) goto MMU_EXCEPTION; 5791 fault = interpreter_write_memory(addr, phys_addr, value, 32);
6097 5792 if (fault) goto MMU_EXCEPTION;
6098 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; 5793 value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1];
6099 //bus_write(32, addr, value); 5794 fault = interpreter_write_memory(addr + 4, rear_phys_addr, value, 32);
6100 fault = interpreter_write_memory(addr, phys_addr, value, 32); 5795 if (fault) goto MMU_EXCEPTION;
6101 if (fault) goto MMU_EXCEPTION; 5796 }
6102 value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]; 5797 cpu->Reg[15] += GET_INST_SIZE(cpu);
6103 //bus_write(32, addr, value); 5798 INC_PC(sizeof(ldst_inst));
6104 fault = interpreter_write_memory(addr + 4, rear_phys_addr, value, 32); 5799 FETCH_INST;
6105 if (fault) goto MMU_EXCEPTION; 5800 GOTO_NEXT_INST;
6106 } 5801 }
6107 cpu->Reg[15] += GET_INST_SIZE(cpu); 5802 STREX_INST:
6108 INC_PC(sizeof(ldst_inst)); 5803 {
6109 FETCH_INST; 5804 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6110 GOTO_NEXT_INST; 5805 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6111 } 5806 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
6112 STREX_INST: 5807 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)];
6113 { 5808 fault = check_address_validity(cpu, addr, &phys_addr, 0);
6114 INC_ICOUNTER; 5809 if (fault) goto MMU_EXCEPTION;
6115 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 5810
6116 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5811 int dest_reg = BITS(inst_cream->inst, 12, 15);
6117 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; 5812 if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){
6118 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)]; 5813 remove_exclusive(cpu, phys_addr);
6119 fault = check_address_validity(cpu, addr, &phys_addr, 0); 5814 cpu->Reg[dest_reg] = 0;
6120 if (fault) goto MMU_EXCEPTION; 5815 cpu->exclusive_state = 0;
6121 5816
6122 int dest_reg = BITS(inst_cream->inst, 12, 15); 5817 fault = interpreter_write_memory(addr, phys_addr, value, 32);
6123 if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){ 5818 if (fault) goto MMU_EXCEPTION;
6124 remove_exclusive(cpu, phys_addr); 5819 } else {
6125 cpu->Reg[dest_reg] = 0; 5820 // Failed to write due to mutex access
6126 cpu->exclusive_state = 0; 5821 cpu->Reg[dest_reg] = 1;
6127 5822 }
6128 // bus_write(32, addr, value); 5823 }
6129 fault = interpreter_write_memory(addr, phys_addr, value, 32); 5824 cpu->Reg[15] += GET_INST_SIZE(cpu);
6130 if (fault) goto MMU_EXCEPTION; 5825 INC_PC(sizeof(ldst_inst));
6131 } 5826 FETCH_INST;
6132 else{ 5827 GOTO_NEXT_INST;
6133 /* Failed to write due to mutex access */ 5828 }
6134 cpu->Reg[dest_reg] = 1; 5829 STREXB_INST:
6135 } 5830 {
6136 } 5831 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6137 cpu->Reg[15] += GET_INST_SIZE(cpu); 5832 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6138 INC_PC(sizeof(ldst_inst)); 5833 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
6139 FETCH_INST; 5834 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff;
6140 GOTO_NEXT_INST; 5835 fault = check_address_validity(cpu, addr, &phys_addr, 0);
6141 } 5836 if (fault) goto MMU_EXCEPTION;
6142 STREXB_INST: 5837 int dest_reg = BITS(inst_cream->inst, 12, 15);
6143 { 5838 if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){
6144 INC_ICOUNTER; 5839 remove_exclusive(cpu, phys_addr);
6145 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 5840 cpu->Reg[dest_reg] = 0;
6146 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5841 cpu->exclusive_state = 0;
6147 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; 5842 fault = interpreter_write_memory(addr, phys_addr, value, 8);
6148 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff; 5843 if (fault) goto MMU_EXCEPTION;
6149 fault = check_address_validity(cpu, addr, &phys_addr, 0); 5844 } else {
6150 if (fault) goto MMU_EXCEPTION; 5845 cpu->Reg[dest_reg] = 1;
6151 //bus_write(8, addr, value); 5846 }
6152 int dest_reg = BITS(inst_cream->inst, 12, 15); 5847 }
6153 if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){ 5848 cpu->Reg[15] += GET_INST_SIZE(cpu);
6154 remove_exclusive(cpu, phys_addr); 5849 INC_PC(sizeof(ldst_inst));
6155 cpu->Reg[dest_reg] = 0; 5850 FETCH_INST;
6156 cpu->exclusive_state = 0; 5851 GOTO_NEXT_INST;
6157 fault = interpreter_write_memory(addr, phys_addr, value, 8); 5852 }
6158 if (fault) goto MMU_EXCEPTION; 5853 STRH_INST:
6159 5854 {
6160 } 5855 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6161 else{ 5856 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6162 cpu->Reg[dest_reg] = 1; 5857 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6163 } 5858 if (fault) goto MMU_EXCEPTION;
6164 } 5859 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff;
6165 cpu->Reg[15] += GET_INST_SIZE(cpu); 5860 fault = interpreter_write_memory(addr, phys_addr, value, 16);
6166 INC_PC(sizeof(ldst_inst)); 5861 if (fault) goto MMU_EXCEPTION;
6167 FETCH_INST; 5862 }
6168 GOTO_NEXT_INST; 5863 cpu->Reg[15] += GET_INST_SIZE(cpu);
6169 } 5864 INC_PC(sizeof(ldst_inst));
6170 STRH_INST: 5865 FETCH_INST;
6171 { 5866 GOTO_NEXT_INST;
6172 INC_ICOUNTER; 5867 }
6173 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 5868 STRT_INST:
6174 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5869 {
6175 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); 5870 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6176 if (fault) goto MMU_EXCEPTION; 5871 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6177 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff; 5872 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6178 //bus_write(16, addr, value); 5873 if (fault) goto MMU_EXCEPTION;
6179 fault = interpreter_write_memory(addr, phys_addr, value, 16); 5874 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
6180 if (fault) goto MMU_EXCEPTION; 5875 fault = interpreter_write_memory(addr, phys_addr, value, 32);
6181 } 5876 if (fault) goto MMU_EXCEPTION;
6182 cpu->Reg[15] += GET_INST_SIZE(cpu); 5877 }
6183 //if (BITS(inst_cream->inst, 12, 15) == 15) 5878 cpu->Reg[15] += GET_INST_SIZE(cpu);
6184 // goto DISPATCH; 5879 INC_PC(sizeof(ldst_inst));
6185 INC_PC(sizeof(ldst_inst)); 5880 FETCH_INST;
6186 FETCH_INST; 5881 GOTO_NEXT_INST;
6187 GOTO_NEXT_INST; 5882 }
6188 } 5883 SUB_INST:
6189 STRT_INST: 5884 {
6190 { 5885 sub_inst *inst_cream = (sub_inst *)inst_base->component;
6191 INC_ICOUNTER; 5886 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6192 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 5887 lop = RN;
6193 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5888 if (inst_cream->Rn == 15) {
6194 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); 5889 lop += 8;
6195 if (fault) goto MMU_EXCEPTION; 5890 }
6196 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; 5891 rop = SHIFTER_OPERAND;
6197 //bus_write(16, addr, value); 5892 RD = dst = lop - rop;
6198 fault = interpreter_write_memory(addr, phys_addr, value, 32); 5893 if (inst_cream->S && (inst_cream->Rd == 15)) {
6199 if (fault) goto MMU_EXCEPTION; 5894 if (CurrentModeHasSPSR) {
6200 } 5895 cpu->Cpsr = cpu->Spsr_copy;
6201 cpu->Reg[15] += GET_INST_SIZE(cpu); 5896 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
6202 INC_PC(sizeof(ldst_inst)); 5897 LOAD_NZCVT;
6203 FETCH_INST; 5898 }
6204 GOTO_NEXT_INST; 5899 } else if (inst_cream->S) {
6205 } 5900 UPDATE_NFLAG(dst);
6206 SUB_INST: 5901 UPDATE_ZFLAG(dst);
6207 { 5902 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
6208 INC_ICOUNTER; 5903 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
6209 sub_inst *inst_cream = (sub_inst *)inst_base->component; 5904 }
6210 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5905 if (inst_cream->Rd == 15) {
6211 lop = RN; 5906 INC_PC(sizeof(sub_inst));
6212 if (inst_cream->Rn == 15) { 5907 goto DISPATCH;
6213 lop += 8; 5908 }
6214 } 5909 }
6215 rop = SHIFTER_OPERAND; 5910 cpu->Reg[15] += GET_INST_SIZE(cpu);
6216 RD = dst = lop - rop; 5911 INC_PC(sizeof(sub_inst));
6217 if (inst_cream->S && (inst_cream->Rd == 15)) { 5912 FETCH_INST;
6218 /* cpsr = spsr */ 5913 GOTO_NEXT_INST;
6219 if (CurrentModeHasSPSR) { 5914 }
6220 cpu->Cpsr = cpu->Spsr_copy; 5915 SWI_INST:
6221 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 5916 {
6222 LOAD_NZCVT; 5917 swi_inst *inst_cream = (swi_inst *)inst_base->component;
6223 } 5918
6224 } else if (inst_cream->S) { 5919 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond))
6225 UPDATE_NFLAG(dst); 5920 HLE::CallSVC(Memory::Read32(cpu->Reg[15]));
6226 UPDATE_ZFLAG(dst); 5921
6227// UPDATE_CFLAG(dst, lop, rop); 5922 cpu->Reg[15] += GET_INST_SIZE(cpu);
6228 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); 5923 INC_PC(sizeof(swi_inst));
6229 // UPDATE_VFLAG((int)dst, (int)lop, (int)rop); 5924 FETCH_INST;
6230 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); 5925 GOTO_NEXT_INST;
6231 } 5926 }
6232 if (inst_cream->Rd == 15) { 5927 SWP_INST:
6233 INC_PC(sizeof(sub_inst)); 5928 {
6234 goto DISPATCH; 5929 swp_inst *inst_cream = (swp_inst *)inst_base->component;
6235 } 5930 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6236 } 5931 addr = RN;
6237 cpu->Reg[15] += GET_INST_SIZE(cpu); 5932 fault = check_address_validity(cpu, addr, &phys_addr, 1);
6238 INC_PC(sizeof(sub_inst)); 5933 if (fault) goto MMU_EXCEPTION;
6239 FETCH_INST; 5934 unsigned int value;
6240 GOTO_NEXT_INST; 5935 fault = interpreter_read_memory(addr, phys_addr, value, 32);
6241 } 5936 if (fault) goto MMU_EXCEPTION;
6242 SWI_INST: 5937 fault = interpreter_write_memory(addr, phys_addr, RM, 32);
6243 { 5938 if (fault) goto MMU_EXCEPTION;
6244 INC_ICOUNTER; 5939
6245 swi_inst *inst_cream = (swi_inst *)inst_base->component; 5940 assert((phys_addr & 0x3) == 0);
6246 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5941 RD = value;
6247 if (true){ //if (core->is_user_mode) { --> Citra only emulates user mode 5942 }
6248 //arm_dyncom_SWI(cpu, inst_cream->num); 5943 cpu->Reg[15] += GET_INST_SIZE(cpu);
6249 HLE::CallSVC(Memory::Read32(cpu->Reg[15])); 5944 INC_PC(sizeof(swp_inst));
6250 } else { 5945 FETCH_INST;
6251 cpu->syscallSig = 1; 5946 GOTO_NEXT_INST;
6252 goto END; 5947 }
6253 } 5948 SWPB_INST:
6254 } 5949 {
6255 cpu->Reg[15] += GET_INST_SIZE(cpu); 5950 swp_inst *inst_cream = (swp_inst *)inst_base->component;
6256 INC_PC(sizeof(swi_inst)); 5951 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6257 FETCH_INST; 5952 addr = RN;
6258 GOTO_NEXT_INST; 5953 fault = check_address_validity(cpu, addr, &phys_addr, 1);
6259 } 5954 if (fault) goto MMU_EXCEPTION;
6260 SWP_INST: 5955 unsigned int value;
6261 { 5956 fault = interpreter_read_memory(addr, phys_addr, value, 8);
6262 INC_ICOUNTER; 5957 if (fault) goto MMU_EXCEPTION;
6263 swp_inst *inst_cream = (swp_inst *)inst_base->component; 5958 fault = interpreter_write_memory(addr, phys_addr, (RM & 0xFF), 8);
6264 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5959 if (fault) goto MMU_EXCEPTION;
6265 addr = RN; 5960 }
6266 fault = check_address_validity(cpu, addr, &phys_addr, 1); 5961 cpu->Reg[15] += GET_INST_SIZE(cpu);
6267 if (fault) goto MMU_EXCEPTION; 5962 INC_PC(sizeof(swp_inst));
6268 unsigned int value; 5963 FETCH_INST;
6269 fault = interpreter_read_memory(addr, phys_addr, value, 32); 5964 GOTO_NEXT_INST;
6270 if (fault) goto MMU_EXCEPTION; 5965 }
6271 fault = interpreter_write_memory(addr, phys_addr, RM, 32); 5966 SXTAB_INST:
6272 if (fault) goto MMU_EXCEPTION; 5967 {
6273 5968 sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component;
6274 /* ROR(data, 8*UInt(address<1:0>)); */ 5969 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6275 assert((phys_addr & 0x3) == 0); 5970 // R15 should be check
6276 RD = value; 5971 if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){
6277 } 5972 CITRA_IGNORE_EXIT(-1);
6278 cpu->Reg[15] += GET_INST_SIZE(cpu); 5973 }
6279 INC_PC(sizeof(swp_inst)); 5974 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
6280 FETCH_INST; 5975
6281 GOTO_NEXT_INST; 5976 // Sign extend for byte
6282 } 5977 operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2;
6283 SWPB_INST: 5978 RD = RN + operand2;
6284 { 5979 }
6285 INC_ICOUNTER; 5980 cpu->Reg[15] += GET_INST_SIZE(cpu);
6286 swp_inst *inst_cream = (swp_inst *)inst_base->component; 5981 INC_PC(sizeof(uxtab_inst));
6287 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5982 FETCH_INST;
6288 addr = RN; 5983 GOTO_NEXT_INST;
6289 fault = check_address_validity(cpu, addr, &phys_addr, 1); 5984 }
6290 if (fault) goto MMU_EXCEPTION; 5985 SXTAB16_INST:
6291 unsigned int value; 5986 SXTAH_INST:
6292 fault = interpreter_read_memory(addr, phys_addr, value, 8); 5987 {
6293 if (fault) goto MMU_EXCEPTION; 5988 sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
6294 fault = interpreter_write_memory(addr, phys_addr, (RM & 0xFF), 8); 5989 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6295 if (fault) goto MMU_EXCEPTION; 5990 // R15 should be check
6296 5991 if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15) {
6297 /* FIXME */ 5992 CITRA_IGNORE_EXIT(-1);
6298 #if 0 5993 }
6299 if Shared(address) then 5994 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
6300 /* ARMv6 */ 5995 // Sign extend for half
6301 physical_address = TLB(address) 5996 operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2;
6302 ClearExclusiveByAddress(physical_address,processor_id,1) 5997 RD = RN + operand2;
6303 /* See Summary of operation on page A2-49 */ 5998 }
6304 #endif 5999 cpu->Reg[15] += GET_INST_SIZE(cpu);
6305 } 6000 INC_PC(sizeof(sxtah_inst));
6306 cpu->Reg[15] += GET_INST_SIZE(cpu); 6001 FETCH_INST;
6307 INC_PC(sizeof(swp_inst)); 6002 GOTO_NEXT_INST;
6308 FETCH_INST; 6003 }
6309 GOTO_NEXT_INST; 6004 SXTB16_INST:
6310 } 6005 TEQ_INST:
6311 SXTAB_INST: 6006 {
6312 { 6007 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6313 INC_ICOUNTER; 6008 teq_inst *inst_cream = (teq_inst *)inst_base->component;
6314 sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component; 6009 lop = RN;
6315 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 6010
6316 /* R15 should be check */ 6011 if (inst_cream->Rn == 15)
6317 if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){ 6012 lop += GET_INST_SIZE(cpu) * 2;
6318 CITRA_IGNORE_EXIT(-1); 6013
6319 } 6014 rop = SHIFTER_OPERAND;
6320 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) 6015 dst = lop ^ rop;
6321 & 0xff; 6016
6322 /* sign extend for byte */ 6017 UPDATE_NFLAG(dst);
6323 operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2; 6018 UPDATE_ZFLAG(dst);
6324 RD = RN + operand2; 6019 UPDATE_CFLAG_WITH_SC;
6325 } 6020 }
6326 cpu->Reg[15] += GET_INST_SIZE(cpu); 6021 cpu->Reg[15] += GET_INST_SIZE(cpu);
6327 INC_PC(sizeof(uxtab_inst)); 6022 INC_PC(sizeof(teq_inst));
6328 FETCH_INST; 6023 FETCH_INST;
6329 GOTO_NEXT_INST; 6024 GOTO_NEXT_INST;
6330 } 6025 }
6331 SXTAB16_INST: 6026 TST_INST:
6332 SXTAH_INST: 6027 {
6333 { 6028 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6334 INC_ICOUNTER; 6029 tst_inst *inst_cream = (tst_inst *)inst_base->component;
6335 sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component; 6030 lop = RN;
6336 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 6031
6337 /* R15 should be check */ 6032 if (inst_cream->Rn == 15)
6338 if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){ 6033 lop += GET_INST_SIZE(cpu) * 2;
6339 CITRA_IGNORE_EXIT(-1); 6034
6340 } 6035 rop = SHIFTER_OPERAND;
6341 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; 6036 dst = lop & rop;
6342 /* sign extend for half */ 6037
6343 operand2 = (0x8000 & operand2)? (0xFFFF0000 | operand2):operand2; 6038 UPDATE_NFLAG(dst);
6344 RD = RN + operand2; 6039 UPDATE_ZFLAG(dst);
6345 } 6040 UPDATE_CFLAG_WITH_SC;
6346 cpu->Reg[15] += GET_INST_SIZE(cpu); 6041 }
6347 INC_PC(sizeof(sxtah_inst)); 6042 cpu->Reg[15] += GET_INST_SIZE(cpu);
6348 FETCH_INST; 6043 INC_PC(sizeof(tst_inst));
6349 GOTO_NEXT_INST; 6044 FETCH_INST;
6350 } 6045 GOTO_NEXT_INST;
6351 SXTB16_INST: 6046 }
6352 TEQ_INST: 6047 UADD8_INST:
6353 { 6048 UADD16_INST:
6354 INC_ICOUNTER; 6049 UADDSUBX_INST:
6355 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 6050
6356 teq_inst *inst_cream = (teq_inst *)inst_base->component; 6051 UHADD8_INST:
6357 lop = RN; 6052 UHADD16_INST:
6358 if (inst_cream->Rn == 15) 6053 UHADDSUBX_INST:
6359 lop += GET_INST_SIZE(cpu) * 2; 6054 UHSUBADDX_INST:
6360 6055 UHSUB8_INST:
6361 rop = SHIFTER_OPERAND; 6056 UHSUB16_INST:
6362 dst = lop ^ rop; 6057 {
6363 6058 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
6364 UPDATE_NFLAG(dst); 6059 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
6365 UPDATE_ZFLAG(dst); 6060 const u32 rm_val = RM;
6366 UPDATE_CFLAG_WITH_SC; 6061 const u32 rn_val = RN;
6367 } 6062 const u8 op2 = inst_cream->op2;
6368 cpu->Reg[15] += GET_INST_SIZE(cpu); 6063
6369 INC_PC(sizeof(teq_inst)); 6064 if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03)
6370 FETCH_INST; 6065 {
6371 GOTO_NEXT_INST; 6066 u32 lo_val = 0;
6372 } 6067 u32 hi_val = 0;
6373 TST_INST: 6068
6374 { 6069 // UHADD16
6375 INC_ICOUNTER; 6070 if (op2 == 0x00) {
6376 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 6071 lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
6377 tst_inst *inst_cream = (tst_inst *)inst_base->component; 6072 hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
6378 lop = RN; 6073 }
6379 if (inst_cream->Rn == 15) 6074 // UHASX
6380 lop += GET_INST_SIZE(cpu) * 2; 6075 else if (op2 == 0x01) {
6381 rop = SHIFTER_OPERAND; 6076 lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
6382 dst = lop & rop; 6077 hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
6383 6078 }
6384 UPDATE_NFLAG(dst); 6079 // UHSAX
6385 UPDATE_ZFLAG(dst); 6080 else if (op2 == 0x02) {
6386 UPDATE_CFLAG_WITH_SC; 6081 lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
6387 } 6082 hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
6388 cpu->Reg[15] += GET_INST_SIZE(cpu); 6083 }
6389 INC_PC(sizeof(tst_inst)); 6084 // UHSUB16
6390 FETCH_INST; 6085 else if (op2 == 0x03) {
6391 GOTO_NEXT_INST; 6086 lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
6392 } 6087 hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
6393 UADD16_INST: 6088 }
6394 UADD8_INST: 6089
6395 UADDSUBX_INST: 6090 lo_val >>= 1;
6396 UHADD16_INST: 6091 hi_val >>= 1;
6397 UHADD8_INST: 6092
6398 UHADDSUBX_INST: 6093 RD = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16);
6399 UHSUB16_INST: 6094 }
6400 UHSUB8_INST: 6095 else if (op2 == 0x04 || op2 == 0x07) {
6401 UHSUBADDX_INST: 6096 u32 sum1;
6402 UMAAL_INST: 6097 u32 sum2;
6403 UMLAL_INST: 6098 u32 sum3;
6404 { 6099 u32 sum4;
6405 INC_ICOUNTER; 6100
6406 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 6101 // UHADD8
6407 umlal_inst *inst_cream = (umlal_inst *)inst_base->component; 6102 if (op2 == 0x04) {
6408 unsigned long long int rm = RM; 6103 sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
6409 unsigned long long int rs = RS; 6104 sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
6410 unsigned long long int rst = rm * rs; 6105 sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
6411 unsigned long long int add = ((unsigned long long) RDHI)<<32; 6106 sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
6412 add += RDLO; 6107 }
6413 //DEBUG_LOG(ARM11, "rm[%llx] * rs[%llx] = rst[%llx] | add[%llx]\n", RM, RS, rst, add); 6108 // UHSUB8
6414 rst += add; 6109 else {
6415 RDLO = BITS(rst, 0, 31); 6110 sum1 = (rn_val & 0xFF) - (rm_val & 0xFF);
6416 RDHI = BITS(rst, 32, 63); 6111 sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
6417 6112 sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
6418 if (inst_cream->S) 6113 sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
6419 { 6114 }
6420 cpu->NFlag = BIT(RDHI, 31); 6115
6421 cpu->ZFlag = (RDHI == 0 && RDLO == 0); 6116 sum1 >>= 1;
6422 } 6117 sum2 >>= 1;
6423 } 6118 sum3 >>= 1;
6424 cpu->Reg[15] += GET_INST_SIZE(cpu); 6119 sum4 >>= 1;
6425 INC_PC(sizeof(umlal_inst)); 6120
6426 FETCH_INST; 6121 RD = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24);
6427 GOTO_NEXT_INST; 6122 }
6428 } 6123 }
6429 UMULL_INST: 6124
6430 { 6125 cpu->Reg[15] += GET_INST_SIZE(cpu);
6431 INC_ICOUNTER; 6126 INC_PC(sizeof(generic_arm_inst));
6432 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 6127 FETCH_INST;
6433 umull_inst *inst_cream = (umull_inst *)inst_base->component; 6128 GOTO_NEXT_INST;
6434 unsigned long long int rm = RM; 6129 }
6435 unsigned long long int rs = RS; 6130
6436 unsigned long long int rst = rm * rs; 6131 UMAAL_INST:
6437// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst); 6132 {
6438 RDHI = BITS(rst, 32, 63); 6133 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
6439 RDLO = BITS(rst, 0, 31); 6134 umaal_inst* const inst_cream = (umaal_inst*)inst_base->component;
6440 6135 const u32 rm = RM;
6441 if (inst_cream->S) { 6136 const u32 rn = RN;
6442 cpu->NFlag = BIT(RDHI, 31); 6137 const u32 rd_lo = RDLO;
6443 cpu->ZFlag = (RDHI == 0 && RDLO == 0); 6138 const u32 rd_hi = RDHI;
6444 } 6139 const u64 result = (rm * rn) + rd_lo + rd_hi;
6445 } 6140
6446 cpu->Reg[15] += GET_INST_SIZE(cpu); 6141 RDLO = (result & 0xFFFFFFFF);
6447 INC_PC(sizeof(umull_inst)); 6142 RDHI = ((result >> 32) & 0xFFFFFFFF);
6448 FETCH_INST; 6143 }
6449 GOTO_NEXT_INST; 6144 cpu->Reg[15] += GET_INST_SIZE(cpu);
6450 } 6145 INC_PC(sizeof(umaal_inst));
6451 B_2_THUMB: 6146 FETCH_INST;
6452 { 6147 GOTO_NEXT_INST;
6453 INC_ICOUNTER; 6148 }
6454 b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component; 6149 UMLAL_INST:
6455 cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; 6150 {
6456 //DEBUG_LOG(ARM11, " BL_1_THUMB: imm=0x%x, r14=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]); 6151 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6457 INC_PC(sizeof(b_2_thumb)); 6152 umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
6458 goto DISPATCH; 6153 unsigned long long int rm = RM;
6459 } 6154 unsigned long long int rs = RS;
6460 B_COND_THUMB: 6155 unsigned long long int rst = rm * rs;
6461 { 6156 unsigned long long int add = ((unsigned long long) RDHI)<<32;
6462 INC_ICOUNTER; 6157 add += RDLO;
6463 b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component; 6158 rst += add;
6464 if(CondPassed(cpu, inst_cream->cond)) 6159 RDLO = BITS(rst, 0, 31);
6465 cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; 6160 RDHI = BITS(rst, 32, 63);
6466 else 6161
6467 cpu->Reg[15] += 2; 6162 if (inst_cream->S) {
6468 //DEBUG_LOG(ARM11, " B_COND_THUMB: imm=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[15]); 6163 cpu->NFlag = BIT(RDHI, 31);
6469 INC_PC(sizeof(b_cond_thumb)); 6164 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
6470 goto DISPATCH; 6165 }
6471 } 6166 }
6472 BL_1_THUMB: 6167 cpu->Reg[15] += GET_INST_SIZE(cpu);
6473 { 6168 INC_PC(sizeof(umlal_inst));
6474 INC_ICOUNTER; 6169 FETCH_INST;
6475 bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component; 6170 GOTO_NEXT_INST;
6476 cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm; 6171 }
6477 //cpu->Reg[15] += 2; 6172 UMULL_INST:
6478 //DEBUG_LOG(ARM11, " BL_1_THUMB: imm=0x%x, r14=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]); 6173 {
6479 6174 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6480 cpu->Reg[15] += GET_INST_SIZE(cpu); 6175 umull_inst *inst_cream = (umull_inst *)inst_base->component;
6481 INC_PC(sizeof(bl_1_thumb)); 6176 unsigned long long int rm = RM;
6482 FETCH_INST; 6177 unsigned long long int rs = RS;
6483 GOTO_NEXT_INST; 6178 unsigned long long int rst = rm * rs;
6484 6179 RDHI = BITS(rst, 32, 63);
6485 } 6180 RDLO = BITS(rst, 0, 31);
6486 BL_2_THUMB: 6181
6487 { 6182 if (inst_cream->S) {
6488 INC_ICOUNTER; 6183 cpu->NFlag = BIT(RDHI, 31);
6489 bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component; 6184 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
6490 int tmp = ((cpu->Reg[15] + 2) | 1); 6185 }
6491 cpu->Reg[15] = 6186 }
6492 (cpu->Reg[14] + inst_cream->imm); 6187 cpu->Reg[15] += GET_INST_SIZE(cpu);
6493 cpu->Reg[14] = tmp; 6188 INC_PC(sizeof(umull_inst));
6494 //DEBUG_LOG(ARM11, " BL_2_THUMB: imm=0x%x, r14=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]); 6189 FETCH_INST;
6495 INC_PC(sizeof(bl_2_thumb)); 6190 GOTO_NEXT_INST;
6496 goto DISPATCH; 6191 }
6497 } 6192 B_2_THUMB:
6498 BLX_1_THUMB: 6193 {
6499 { 6194 b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component;
6500 /* BLX 1 for armv5t and above */ 6195 cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
6501 INC_ICOUNTER; 6196 INC_PC(sizeof(b_2_thumb));
6502 uint32 tmp = cpu->Reg[15]; 6197 goto DISPATCH;
6503 blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component; 6198 }
6504 cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC; 6199 B_COND_THUMB:
6505 //DEBUG_LOG(ARM11, "In BLX_1_THUMB, BLX(1),imm=0x%x,r14=0x%x, instr=0x%x\n", inst_cream->imm, cpu->Reg[14], inst_cream->instr); 6200 {
6506 cpu->Reg[14] = ((tmp + 2) | 1); 6201 b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component;
6507 //(state->Reg[14] + ((tinstr & 0x07FF) << 1)) & 0xFFFFFFFC; 6202
6508 /* switch to arm state from thumb state */ 6203 if(CondPassed(cpu, inst_cream->cond))
6509 cpu->TFlag = 0; 6204 cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
6510 //DEBUG_LOG(ARM11, "In BLX_1_THUMB, BLX(1),imm=0x%x,r14=0x%x, r15=0x%x, \n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]); 6205 else
6511 INC_PC(sizeof(blx_1_thumb)); 6206 cpu->Reg[15] += 2;
6512 goto DISPATCH; 6207
6513 } 6208 INC_PC(sizeof(b_cond_thumb));
6514 6209 goto DISPATCH;
6515 UQADD16_INST: 6210 }
6516 UQADD8_INST: 6211 BL_1_THUMB:
6517 UQADDSUBX_INST: 6212 {
6518 UQSUB16_INST: 6213 bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component;
6519 UQSUB8_INST: 6214 cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm;
6520 UQSUBADDX_INST: 6215 cpu->Reg[15] += GET_INST_SIZE(cpu);
6521 USAD8_INST: 6216 INC_PC(sizeof(bl_1_thumb));
6522 USADA8_INST: 6217 FETCH_INST;
6523 USAT_INST: 6218 GOTO_NEXT_INST;
6524 USAT16_INST: 6219 }
6525 USUB16_INST: 6220 BL_2_THUMB:
6526 USUB8_INST: 6221 {
6527 USUBADDX_INST: 6222 bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component;
6528 UXTAB16_INST: 6223 int tmp = ((cpu->Reg[15] + 2) | 1);
6529 UXTB16_INST: 6224 cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm);
6530 #define VFP_INTERPRETER_IMPL 6225 cpu->Reg[14] = tmp;
6531 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 6226 INC_PC(sizeof(bl_2_thumb));
6532 #undef VFP_INTERPRETER_IMPL 6227 goto DISPATCH;
6533 MMU_EXCEPTION: 6228 }
6534 { 6229 BLX_1_THUMB:
6535 SAVE_NZCVT; 6230 {
6536 cpu->abortSig = true; 6231 // BLX 1 for armv5t and above
6537 cpu->Aborted = ARMul_DataAbortV; 6232 uint32 tmp = cpu->Reg[15];
6538 cpu->AbortAddr = addr; 6233 blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
6539 cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff; 6234 cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC;
6540 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; 6235 cpu->Reg[14] = ((tmp + 2) | 1);
6541 cpu->NumInstrsToExecute = 0; 6236 cpu->TFlag = 0;
6542 return num_instrs; 6237 INC_PC(sizeof(blx_1_thumb));
6543 } 6238 goto DISPATCH;
6544 END: 6239 }
6545 { 6240
6546 SAVE_NZCVT; 6241 UQADD8_INST:
6547 cpu->NumInstrsToExecute = 0; 6242 UQADD16_INST:
6548 return num_instrs; 6243 UQADDSUBX_INST:
6549 } 6244 UQSUB8_INST:
6550 INIT_INST_LENGTH: 6245 UQSUB16_INST:
6551 { 6246 UQSUBADDX_INST:
6552#if 0 6247 {
6553 DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel)); 6248 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
6554 for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++) 6249 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
6555 DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]); 6250
6556 DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel)); 6251 const u8 op2 = inst_cream->op2;
6557#endif 6252 const u32 rm_val = RM;
6253 const u32 rn_val = RN;
6254
6255 u16 lo_val = 0;
6256 u16 hi_val = 0;
6257
6258 // UQADD16
6259 if (op2 == 0x00) {
6260 lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF);
6261 hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
6262 }
6263 // UQASX
6264 else if (op2 == 0x01) {
6265 lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
6266 hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
6267 }
6268 // UQSAX
6269 else if (op2 == 0x02) {
6270 lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
6271 hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
6272 }
6273 // UQSUB16
6274 else if (op2 == 0x03) {
6275 lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF);
6276 hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
6277 }
6278 // UQADD8
6279 else if (op2 == 0x04) {
6280 lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) |
6281 ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8;
6282 hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) |
6283 ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8;
6284 }
6285 // UQSUB8
6286 else {
6287 lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) |
6288 ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8;
6289 hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) |
6290 ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8;
6291 }
6292
6293 RD = ((lo_val & 0xFFFF) | hi_val << 16);
6294 }
6295
6296 cpu->Reg[15] += GET_INST_SIZE(cpu);
6297 INC_PC(sizeof(generic_arm_inst));
6298 FETCH_INST;
6299 GOTO_NEXT_INST;
6300 }
6301
6302 USAD8_INST:
6303 USADA8_INST:
6304 {
6305 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
6306 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
6307
6308 const u8 ra_idx = inst_cream->Ra;
6309 const u32 rm_val = RM;
6310 const u32 rn_val = RN;
6311
6312 const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF);
6313 const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF);
6314 const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF);
6315 const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF);
6316
6317 u32 finalDif = (diff1 + diff2 + diff3 + diff4);
6318
6319 // Op is USADA8 if true.
6320 if (ra_idx != 15)
6321 finalDif += cpu->Reg[ra_idx];
6322
6323 RD = finalDif;
6324 }
6325
6326 cpu->Reg[15] += GET_INST_SIZE(cpu);
6327 INC_PC(sizeof(generic_arm_inst));
6328 FETCH_INST;
6329 GOTO_NEXT_INST;
6330 }
6331
6332 USAT_INST:
6333 {
6334 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
6335 ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
6336
6337 u8 shift_type = inst_cream->shift_type;
6338 u8 shift_amount = inst_cream->imm5;
6339 u32 rn_val = RN;
6340
6341 // 32-bit ASR is encoded as an amount of 0.
6342 if (shift_type == 1 && shift_amount == 0)
6343 shift_amount = 31;
6344
6345 if (shift_type == 0)
6346 rn_val <<= shift_amount;
6347 else if (shift_type == 1)
6348 rn_val = ((s32)rn_val >> shift_amount);
6349
6350 bool saturated = false;
6351 rn_val = ARMul_UnsignedSatQ(rn_val, inst_cream->sat_imm, &saturated);
6352
6353 if (saturated)
6354 cpu->Cpsr |= (1 << 27);
6355
6356 RD = rn_val;
6357 }
6358
6359 cpu->Reg[15] += GET_INST_SIZE(cpu);
6360 INC_PC(sizeof(ssat_inst));
6361 FETCH_INST;
6362 GOTO_NEXT_INST;
6363 }
6364
6365 USAT16_INST:
6366 USUB16_INST:
6367 USUB8_INST:
6368 USUBADDX_INST:
6369 UXTAB16_INST:
6370 UXTB16_INST:
6371 {
6372 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
6373 uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component;
6374
6375 const u8 rn_idx = inst_cream->Rn;
6376 const u32 rm_val = RM;
6377 const u32 rotation = inst_cream->rotate * 8;
6378 const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
6379
6380 // UXTB16, otherwise UXTAB16
6381 if (rn_idx == 15) {
6382 RD = rotated_rm & 0x00FF00FF;
6383 } else {
6384 const u32 rn_val = RN;
6385 const u8 lo_rotated = (rotated_rm & 0xFF);
6386 const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated;
6387 const u8 hi_rotated = (rotated_rm >> 16) & 0xFF;
6388 const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated;
6389
6390 RD = ((hi_result << 16) | (lo_result & 0xFFFF));
6391 }
6392 }
6393
6394 cpu->Reg[15] += GET_INST_SIZE(cpu);
6395 INC_PC(sizeof(uxtab_inst));
6396 FETCH_INST;
6397 GOTO_NEXT_INST;
6398 }
6399
6400 #define VFP_INTERPRETER_IMPL
6401 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
6402 #undef VFP_INTERPRETER_IMPL
6403 MMU_EXCEPTION:
6404 {
6405 SAVE_NZCVT;
6406 cpu->abortSig = true;
6407 cpu->Aborted = ARMul_DataAbortV;
6408 cpu->AbortAddr = addr;
6409 cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff;
6410 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr;
6411 cpu->NumInstrsToExecute = 0;
6412 return num_instrs;
6413 }
6414 END:
6415 {
6416 SAVE_NZCVT;
6417 cpu->NumInstrsToExecute = 0;
6418 return num_instrs;
6419 }
6420 INIT_INST_LENGTH:
6421 {
6558#if defined __GNUC__ || defined __clang__ 6422#if defined __GNUC__ || defined __clang__
6559 InterpreterInitInstLength((unsigned long long int *)InstLabel, sizeof(InstLabel)); 6423 InterpreterInitInstLength((unsigned long long int *)InstLabel, sizeof(InstLabel));
6560#endif 6424#endif
6561#if 0 6425 cpu->NumInstrsToExecute = 0;
6562 for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++) 6426 return num_instrs;
6563 DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]); 6427 }
6564 DEBUG_LOG(ARM11, "%llx\n", InstEndLabel[1]);
6565 DEBUG_LOG(ARM11, "%llx\n", InstLabel[1]);
6566 DEBUG_LOG(ARM11, "%lld\n", (char *)InstEndLabel[1] - (char *)InstLabel[1]);
6567#endif
6568 cpu->NumInstrsToExecute = 0;
6569 return num_instrs;
6570 }
6571} 6428}
6572
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.h b/src/core/arm/dyncom/arm_dyncom_interpreter.h
index 3a2462f55..4791ea25f 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.h
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.h
@@ -1,5 +1,5 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once 5#pragma once
diff --git a/src/core/arm/dyncom/arm_dyncom_run.cpp b/src/core/arm/dyncom/arm_dyncom_run.cpp
index a2026cbf3..d457d0ac5 100644
--- a/src/core/arm/dyncom/arm_dyncom_run.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_run.cpp
@@ -1,42 +1,15 @@
1/* Copyright (C) 1// Copyright 2012 Michael Kang, 2014 Citra Emulator Project
2* 2011 - Michael.Kang blackfin.kang@gmail.com 2// Licensed under GPLv2 or any later version
3* This program is free software; you can redistribute it and/or 3// Refer to the license.txt file included.
4* modify it under the terms of the GNU General Public License
5* as published by the Free Software Foundation; either version 2
6* of the License, or (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18/**
19* @file arm_dyncom_run.cpp
20* @brief The dyncom run implementation for arm
21* @author Michael.Kang blackfin.kang@gmail.com
22* @version 78.77
23* @date 2011-11-20
24*/
25 4
26#include <assert.h> 5#include <assert.h>
27 6
28#include "core/arm/skyeye_common/armdefs.h" 7#include "core/arm/skyeye_common/armdefs.h"
29 8
30void switch_mode(arm_core_t *core, uint32_t mode) 9void switch_mode(arm_core_t *core, uint32_t mode) {
31{ 10 if (core->Mode == mode)
32 uint32_t tmp1, tmp2;
33 if (core->Mode == mode) {
34 //Mode not changed.
35 //printf("mode not changed\n");
36 return; 11 return;
37 } 12
38 //printf("%d --->>> %d\n", core->Mode, mode);
39 //printf("In %s, Cpsr=0x%x, R15=0x%x, last_pc=0x%x, cpsr=0x%x, spsr_copy=0x%x, icounter=%lld\n", __FUNCTION__, core->Cpsr, core->Reg[15], core->last_pc, core->Cpsr, core->Spsr_copy, core->icounter);
40 if (mode != USERBANK) { 13 if (mode != USERBANK) {
41 switch (core->Mode) { 14 switch (core->Mode) {
42 case USER32MODE: 15 case USER32MODE:
@@ -110,11 +83,8 @@ void switch_mode(arm_core_t *core, uint32_t mode)
110 83
111 } 84 }
112 core->Mode = mode; 85 core->Mode = mode;
113 //printf("In %si end, Cpsr=0x%x, R15=0x%x, last_pc=0x%x, cpsr=0x%x, spsr_copy=0x%x, icounter=%lld\n", __FUNCTION__, core->Cpsr, core->Reg[15], core->last_pc, core->Cpsr, core->Spsr_copy, core->icounter); 86 } else {
114 //printf("\n--------------------------------------\n"); 87 LOG_CRITICAL(Core_ARM11, "user mode");
115 }
116 else {
117 printf("user mode\n");
118 exit(-2); 88 exit(-2);
119 } 89 }
120} 90}
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
index e10f2f9ee..de70ca8ae 100644
--- a/src/core/arm/dyncom/arm_dyncom_thumb.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
@@ -1,35 +1,13 @@
1/* Copyright (C) 1// Copyright 2012 Michael Kang, 2014 Citra Emulator Project
2* 2011 - Michael.Kang blackfin.kang@gmail.com 2// Licensed under GPLv2 or any later version
3* This program is free software; you can redistribute it and/or 3// Refer to the license.txt file included.
4* modify it under the terms of the GNU General Public License 4
5* as published by the Free Software Foundation; either version 2 5// We can provide simple Thumb simulation by decoding the Thumb instruction into its corresponding
6* of the License, or (at your option) any later version. 6// ARM instruction, and using the existing ARM simulator.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18/**
19* @file arm_dyncom_thumb.c
20* @brief The thumb dynamic interpreter
21* @author Michael.Kang blackfin.kang@gmail.com
22* @version 78.77
23* @date 2011-11-07
24*/
25
26/* We can provide simple Thumb simulation by decoding the Thumb
27instruction into its corresponding ARM instruction, and using the
28existing ARM simulator. */
29 7
30#include "core/arm/skyeye_common/skyeye_defs.h" 8#include "core/arm/skyeye_common/skyeye_defs.h"
31 9
32#ifndef MODET /* required for the Thumb instruction support */ 10#ifndef MODET // Required for the Thumb instruction support
33#if 1 11#if 1
34#error "MODET needs to be defined for the Thumb world to work" 12#error "MODET needs to be defined for the Thumb world to work"
35#else 13#else
@@ -40,482 +18,359 @@ existing ARM simulator. */
40#include "core/arm/skyeye_common/armos.h" 18#include "core/arm/skyeye_common/armos.h"
41#include "core/arm/dyncom/arm_dyncom_thumb.h" 19#include "core/arm/dyncom/arm_dyncom_thumb.h"
42 20
43/* Decode a 16bit Thumb instruction. The instruction is in the low 21// Decode a 16bit Thumb instruction. The instruction is in the low 16-bits of the tinstr field,
44 16-bits of the tinstr field, with the following Thumb instruction 22// with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions
45 held in the high 16-bits. Passing in two Thumb instructions allows 23// allows easier simulation of the special dual BL instruction.
46 easier simulation of the special dual BL instruction. */
47 24
48tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size) 25tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size) {
49{
50 tdstate valid = t_uninitialized; 26 tdstate valid = t_uninitialized;
51 ARMword next_instr; 27 ARMword tinstr;
52 ARMword tinstr; 28 tinstr = instr;
53 tinstr = instr; 29
54 /* The endian should be judge here */ 30 // The endian should be judge here
55 #if 0 31 if((addr & 0x3) != 0)
56 if (state->bigendSig) { 32 tinstr = instr >> 16;
57 next_instr = tinstr & 0xFFFF; 33 else
58 tinstr >>= 16; 34 tinstr &= 0xFFFF;
59 } 35
60 else { 36 *ainstr = 0xDEADC0DE; // Debugging to catch non updates
61 next_instr = tinstr >> 16; 37
62 tinstr &= 0xFFFF; 38 switch ((tinstr & 0xF800) >> 11) {
63 } 39 case 0: // LSL
64 #endif 40 case 1: // LSR
65 if((addr & 0x3) != 0) 41 case 2: // ASR
66 tinstr = instr >> 16; 42 *ainstr = 0xE1B00000 // base opcode
67 else 43 | ((tinstr & 0x1800) >> (11 - 5)) // shift type
68 tinstr &= 0xFFFF; 44 |((tinstr & 0x07C0) << (7 - 6)) // imm5
69 45 |((tinstr & 0x0038) >> 3) // Rs
70 //printf("In %s, instr=0x%x, tinstr=0x%x, r15=0x%x\n", __FUNCTION__, instr, tinstr, cpu->translate_pc); 46 |((tinstr & 0x0007) << 12); // Rd
71#if 1 /* debugging to catch non updates */ 47 break;
72 *ainstr = 0xDEADC0DE; 48
73#endif 49 case 3: // ADD/SUB
50 {
51 ARMword subset[4] = {
52 0xE0900000, // ADDS Rd,Rs,Rn
53 0xE0500000, // SUBS Rd,Rs,Rn
54 0xE2900000, // ADDS Rd,Rs,#imm3
55 0xE2500000 // SUBS Rd,Rs,#imm3
56 };
57 // It is quicker indexing into a table, than performing switch or conditionals:
58 *ainstr = subset[(tinstr & 0x0600) >> 9] // base opcode
59 |((tinstr & 0x01C0) >> 6) // Rn or imm3
60 |((tinstr & 0x0038) << (16 - 3)) // Rs
61 |((tinstr & 0x0007) << (12 - 0)); // Rd
62 }
63 break;
64
65 case 4: // MOV
66 case 5: // CMP
67 case 6: // ADD
68 case 7: // SUB
69 {
70 ARMword subset[4] = {
71 0xE3B00000, // MOVS Rd,#imm8
72 0xE3500000, // CMP Rd,#imm8
73 0xE2900000, // ADDS Rd,Rd,#imm8
74 0xE2500000, // SUBS Rd,Rd,#imm8
75 };
76
77 *ainstr = subset[(tinstr & 0x1800) >> 11] // base opcode
78 |((tinstr & 0x00FF) >> 0) // imm8
79 |((tinstr & 0x0700) << (16 - 8)) // Rn
80 |((tinstr & 0x0700) << (12 - 8)); // Rd
81 }
82 break;
83
84 case 8: // Arithmetic and high register transfers
85
86 // TODO: Since the subsets for both Format 4 and Format 5 instructions are made up of
87 // different ARM encodings, we could save the following conditional, and just have one
88 // large subset
89
90 if ((tinstr & (1 << 10)) == 0) {
91 enum otype {
92 t_norm,
93 t_shift,
94 t_neg,
95 t_mul
96 };
97
98 struct {
99 ARMword opcode;
100 otype type;
101 } subset[16] = {
102 { 0xE0100000, t_norm }, // ANDS Rd,Rd,Rs
103 { 0xE0300000, t_norm }, // EORS Rd,Rd,Rs
104 { 0xE1B00010, t_shift }, // MOVS Rd,Rd,LSL Rs
105 { 0xE1B00030, t_shift }, // MOVS Rd,Rd,LSR Rs
106 { 0xE1B00050, t_shift }, // MOVS Rd,Rd,ASR Rs
107 { 0xE0B00000, t_norm }, // ADCS Rd,Rd,Rs
108 { 0xE0D00000, t_norm }, // SBCS Rd,Rd,Rs
109 { 0xE1B00070, t_shift }, // MOVS Rd,Rd,ROR Rs
110 { 0xE1100000, t_norm }, // TST Rd,Rs
111 { 0xE2700000, t_neg }, // RSBS Rd,Rs,#0
112 { 0xE1500000, t_norm }, // CMP Rd,Rs
113 { 0xE1700000, t_norm }, // CMN Rd,Rs
114 { 0xE1900000, t_norm }, // ORRS Rd,Rd,Rs
115 { 0xE0100090, t_mul }, // MULS Rd,Rd,Rs
116 { 0xE1D00000, t_norm }, // BICS Rd,Rd,Rs
117 { 0xE1F00000, t_norm } // MVNS Rd,Rs
118 };
119
120 *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; // base
121
122 switch (subset[(tinstr & 0x03C0) >> 6].type) {
123 case t_norm:
124 *ainstr |= ((tinstr & 0x0007) << 16) // Rn
125 |((tinstr & 0x0007) << 12) // Rd
126 |((tinstr & 0x0038) >> 3); // Rs
127 break;
128 case t_shift:
129 *ainstr |= ((tinstr & 0x0007) << 12) // Rd
130 |((tinstr & 0x0007) >> 0) // Rm
131 |((tinstr & 0x0038) << (8 - 3)); // Rs
132 break;
133 case t_neg:
134 *ainstr |= ((tinstr & 0x0007) << 12) // Rd
135 |((tinstr & 0x0038) << (16 - 3)); // Rn
136 break;
137 case t_mul:
138 *ainstr |= ((tinstr & 0x0007) << 16) // Rd
139 |((tinstr & 0x0007) << 8) // Rs
140 |((tinstr & 0x0038) >> 3); // Rm
141 break;
142 }
143 } else {
144 ARMword Rd = ((tinstr & 0x0007) >> 0);
145 ARMword Rs = ((tinstr & 0x0038) >> 3);
146
147 if (tinstr & (1 << 7))
148 Rd += 8;
149 if (tinstr & (1 << 6))
150 Rs += 8;
151
152 switch ((tinstr & 0x03C0) >> 6) {
153 case 0x1: // ADD Rd,Rd,Hs
154 case 0x2: // ADD Hd,Hd,Rs
155 case 0x3: // ADD Hd,Hd,Hs
156 *ainstr = 0xE0800000 // base
157 | (Rd << 16) // Rn
158 |(Rd << 12) // Rd
159 |(Rs << 0); // Rm
160 break;
161 case 0x5: // CMP Rd,Hs
162 case 0x6: // CMP Hd,Rs
163 case 0x7: // CMP Hd,Hs
164 *ainstr = 0xE1500000 // base
165 | (Rd << 16) // Rn
166 |(Rd << 12) // Rd
167 |(Rs << 0); // Rm
168 break;
169 case 0x9: // MOV Rd,Hs
170 case 0xA: // MOV Hd,Rs
171 case 0xB: // MOV Hd,Hs
172 *ainstr = 0xE1A00000 // base
173 | (Rd << 16) // Rn
174 |(Rd << 12) // Rd
175 |(Rs << 0); // Rm
176 break;
177 case 0xC: // BX Rs
178 case 0xD: // BX Hs
179 *ainstr = 0xE12FFF10 // base
180 | ((tinstr & 0x0078) >> 3); // Rd
181 break;
182 case 0x0: // UNDEFINED
183 case 0x4: // UNDEFINED
184 case 0x8: // UNDEFINED
185 valid = t_undefined;
186 break;
187 case 0xE: // BLX
188 case 0xF: // BLX
189 *ainstr = 0xE1200030 // base
190 | (Rs << 0); // Rm
191 break;
192 }
193 }
194 break;
195
196 case 9: // LDR Rd,[PC,#imm8]
197 *ainstr = 0xE59F0000 // base
198 | ((tinstr & 0x0700) << (12 - 8)) // Rd
199 |((tinstr & 0x00FF) << (2 - 0)); // off8
200 break;
201
202 case 10:
203 case 11:
204 // TODO: Format 7 and Format 8 perform the same ARM encoding, so the following could be
205 // merged into a single subset, saving on the following boolean:
206
207 if ((tinstr & (1 << 9)) == 0) {
208 ARMword subset[4] = {
209 0xE7800000, // STR Rd,[Rb,Ro]
210 0xE7C00000, // STRB Rd,[Rb,Ro]
211 0xE7900000, // LDR Rd,[Rb,Ro]
212 0xE7D00000 // LDRB Rd,[Rb,Ro]
213 };
214
215 *ainstr = subset[(tinstr & 0x0C00) >> 10] // base
216 |((tinstr & 0x0007) << (12 - 0)) // Rd
217 |((tinstr & 0x0038) << (16 - 3)) // Rb
218 |((tinstr & 0x01C0) >> 6); // Ro
219
220 } else {
221 ARMword subset[4] = {
222 0xE18000B0, // STRH Rd,[Rb,Ro]
223 0xE19000D0, // LDRSB Rd,[Rb,Ro]
224 0xE19000B0, // LDRH Rd,[Rb,Ro]
225 0xE19000F0 // LDRSH Rd,[Rb,Ro]
226 };
227 *ainstr = subset[(tinstr & 0x0C00) >> 10] // base
228 |((tinstr & 0x0007) << (12 - 0)) // Rd
229 |((tinstr & 0x0038) << (16 - 3)) // Rb
230 |((tinstr & 0x01C0) >> 6); // Ro
231 }
232 break;
233
234 case 12: // STR Rd,[Rb,#imm5]
235 case 13: // LDR Rd,[Rb,#imm5]
236 case 14: // STRB Rd,[Rb,#imm5]
237 case 15: // LDRB Rd,[Rb,#imm5]
238 {
239 ARMword subset[4] = {
240 0xE5800000, // STR Rd,[Rb,#imm5]
241 0xE5900000, // LDR Rd,[Rb,#imm5]
242 0xE5C00000, // STRB Rd,[Rb,#imm5]
243 0xE5D00000 // LDRB Rd,[Rb,#imm5]
244 };
245 // The offset range defends on whether we are transferring a byte or word value:
246 *ainstr = subset[(tinstr & 0x1800) >> 11] // base
247 |((tinstr & 0x0007) << (12 - 0)) // Rd
248 |((tinstr & 0x0038) << (16 - 3)) // Rb
249 |((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); // off5
250 }
251 break;
252
253 case 16: // STRH Rd,[Rb,#imm5]
254 case 17: // LDRH Rd,[Rb,#imm5]
255 *ainstr = ((tinstr & (1 << 11)) // base
256 ? 0xE1D000B0 // LDRH
257 : 0xE1C000B0) // STRH
258 |((tinstr & 0x0007) << (12 - 0)) // Rd
259 |((tinstr & 0x0038) << (16 - 3)) // Rb
260 |((tinstr & 0x01C0) >> (6 - 1)) // off5, low nibble
261 |((tinstr & 0x0600) >> (9 - 8)); // off5, high nibble
262 break;
263
264 case 18: // STR Rd,[SP,#imm8]
265 case 19: // LDR Rd,[SP,#imm8]
266 *ainstr = ((tinstr & (1 << 11)) // base
267 ? 0xE59D0000 // LDR
268 : 0xE58D0000) // STR
269 |((tinstr & 0x0700) << (12 - 8)) // Rd
270 |((tinstr & 0x00FF) << 2); // off8
271 break;
272
273 case 20: // ADD Rd,PC,#imm8
274 case 21: // ADD Rd,SP,#imm8
275
276 if ((tinstr & (1 << 11)) == 0) {
277
278 // NOTE: The PC value used here should by word aligned. We encode shift-left-by-2 in the
279 // rotate immediate field, so no shift of off8 is needed.
280
281 *ainstr = 0xE28F0F00 // base
282 | ((tinstr & 0x0700) << (12 - 8)) // Rd
283 |(tinstr & 0x00FF); // off8
284 } else {
285 // We encode shift-left-by-2 in the rotate immediate field, so no shift of off8 is needed.
286 *ainstr = 0xE28D0F00 // base
287 | ((tinstr & 0x0700) << (12 - 8)) // Rd
288 |(tinstr & 0x00FF); // off8
289 }
290 break;
291
292 case 22:
293 case 23:
294 if ((tinstr & 0x0F00) == 0x0000) {
295 // NOTE: The instruction contains a shift left of 2 equivalent (implemented as ROR #30):
296 *ainstr = ((tinstr & (1 << 7)) // base
297 ? 0xE24DDF00 // SUB
298 : 0xE28DDF00) // ADD
299 |(tinstr & 0x007F); // off7
300 } else if ((tinstr & 0x0F00) == 0x0e00)
301 *ainstr = 0xEF000000 | SWI_Breakpoint;
302 else {
303 ARMword subset[4] = {
304 0xE92D0000, // STMDB sp!,{rlist}
305 0xE92D4000, // STMDB sp!,{rlist,lr}
306 0xE8BD0000, // LDMIA sp!,{rlist}
307 0xE8BD8000 // LDMIA sp!,{rlist,pc}
308 };
309 *ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)] // base
310 |(tinstr & 0x00FF); // mask8
311 }
312 break;
313
314 case 24: // STMIA
315 case 25: // LDMIA
316 *ainstr = ((tinstr & (1 << 11)) // base
317 ? 0xE8B00000 // LDMIA
318 : 0xE8A00000) // STMIA
319 |((tinstr & 0x0700) << (16 - 8)) // Rb
320 |(tinstr & 0x00FF); // mask8
321 break;
322
323 case 26: // Bcc
324 case 27: // Bcc/SWI
325 if ((tinstr & 0x0F00) == 0x0F00) {
326 // Format 17 : SWI
327 *ainstr = 0xEF000000;
328 // Breakpoint must be handled specially.
329 if ((tinstr & 0x00FF) == 0x18)
330 *ainstr |= ((tinstr & 0x00FF) << 16);
331 // New breakpoint value. See gdb/arm-tdep.c
332 else if ((tinstr & 0x00FF) == 0xFE)
333 *ainstr |= SWI_Breakpoint;
334 else
335 *ainstr |= (tinstr & 0x00FF);
336 } else if ((tinstr & 0x0F00) != 0x0E00)
337 valid = t_branch;
338 else // UNDEFINED : cc=1110(AL) uses different format
339 valid = t_undefined;
340
341 break;
342
343 case 28: // B
344 valid = t_branch;
345 break;
346
347 case 29:
348 if(tinstr & 0x1)
349 valid = t_undefined;
350 else
351 valid = t_branch;
352 break;
353
354 case 30: // BL instruction 1
355
356 // There is no single ARM instruction equivalent for this Thumb instruction. To keep the
357 // simulation simple (from the user perspective) we check if the following instruction is
358 // the second half of this BL, and if it is we simulate it immediately
359
360 valid = t_branch;
361 break;
362
363 case 31: // BL instruction 2
364
365 // There is no single ARM instruction equivalent for this instruction. Also, it should only
366 // ever be matched with the fmt19 "BL instruction 1" instruction. However, we do allow the
367 // simulation of it on its own, with undefined results if r14 is not suitably initialised.
368
369 valid = t_branch;
370 break;
371 }
372
373 *inst_size = 2;
74 374
75 switch ((tinstr & 0xF800) >> 11) { 375 return valid;
76 case 0: /* LSL */
77 case 1: /* LSR */
78 case 2: /* ASR */
79 /* Format 1 */
80 *ainstr = 0xE1B00000 /* base opcode */
81 | ((tinstr & 0x1800) >> (11 - 5)) /* shift type */
82 |((tinstr & 0x07C0) << (7 - 6)) /* imm5 */
83 |((tinstr & 0x0038) >> 3) /* Rs */
84 |((tinstr & 0x0007) << 12); /* Rd */
85 break;
86 case 3: /* ADD/SUB */
87 /* Format 2 */
88 {
89 ARMword subset[4] = {
90 0xE0900000, /* ADDS Rd,Rs,Rn */
91 0xE0500000, /* SUBS Rd,Rs,Rn */
92 0xE2900000, /* ADDS Rd,Rs,#imm3 */
93 0xE2500000 /* SUBS Rd,Rs,#imm3 */
94 };
95 /* It is quicker indexing into a table, than performing switch
96 or conditionals: */
97 *ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */
98 |((tinstr & 0x01C0) >> 6) /* Rn or imm3 */
99 |((tinstr & 0x0038) << (16 - 3)) /* Rs */
100 |((tinstr & 0x0007) << (12 - 0)); /* Rd */
101 }
102 break;
103 case 4: /* MOV */
104 case 5: /* CMP */
105 case 6: /* ADD */
106 case 7: /* SUB */
107 /* Format 3 */
108 {
109 ARMword subset[4] = {
110 0xE3B00000, /* MOVS Rd,#imm8 */
111 0xE3500000, /* CMP Rd,#imm8 */
112 0xE2900000, /* ADDS Rd,Rd,#imm8 */
113 0xE2500000, /* SUBS Rd,Rd,#imm8 */
114 };
115 *ainstr = subset[(tinstr & 0x1800) >> 11] /* base opcode */
116 |((tinstr & 0x00FF) >> 0) /* imm8 */
117 |((tinstr & 0x0700) << (16 - 8)) /* Rn */
118 |((tinstr & 0x0700) << (12 - 8)); /* Rd */
119 }
120 break;
121 case 8: /* Arithmetic and high register transfers */
122 /* TODO: Since the subsets for both Format 4 and Format 5
123 instructions are made up of different ARM encodings, we could
124 save the following conditional, and just have one large
125 subset. */
126 if ((tinstr & (1 << 10)) == 0) {
127 typedef enum
128 { t_norm, t_shift, t_neg, t_mul }otype_t;
129
130 /* Format 4 */
131 struct
132 {
133 ARMword opcode;
134 otype_t otype;
135 }
136 subset[16] = {
137 {
138 0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */
139 {
140 0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */
141 {
142 0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */
143 {
144 0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */
145 {
146 0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */
147 {
148 0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */
149 {
150 0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */
151 {
152 0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */
153 {
154 0xE1100000, t_norm}, /* TST Rd,Rs */
155 {
156 0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */
157 {
158 0xE1500000, t_norm}, /* CMP Rd,Rs */
159 {
160 0xE1700000, t_norm}, /* CMN Rd,Rs */
161 {
162 0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */
163 {
164 0xE0100090, t_mul}, /* MULS Rd,Rd,Rs */
165 {
166 0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */
167 {
168 0xE1F00000, t_norm} /* MVNS Rd,Rs */
169 };
170 *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
171 switch (subset[(tinstr & 0x03C0) >> 6].otype) {
172 case t_norm:
173 *ainstr |= ((tinstr & 0x0007) << 16) /* Rn */
174 |((tinstr & 0x0007) << 12) /* Rd */
175 |((tinstr & 0x0038) >> 3); /* Rs */
176 break;
177 case t_shift:
178 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
179 |((tinstr & 0x0007) >> 0) /* Rm */
180 |((tinstr & 0x0038) << (8 - 3)); /* Rs */
181 break;
182 case t_neg:
183 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
184 |((tinstr & 0x0038) << (16 - 3)); /* Rn */
185 break;
186 case t_mul:
187 *ainstr |= ((tinstr & 0x0007) << 16) /* Rd */
188 |((tinstr & 0x0007) << 8) /* Rs */
189 |((tinstr & 0x0038) >> 3); /* Rm */
190 break;
191 }
192 }
193 else {
194 /* Format 5 */
195 ARMword Rd = ((tinstr & 0x0007) >> 0);
196 ARMword Rs = ((tinstr & 0x0038) >> 3);
197 if (tinstr & (1 << 7))
198 Rd += 8;
199 if (tinstr & (1 << 6))
200 Rs += 8;
201 switch ((tinstr & 0x03C0) >> 6) {
202 case 0x1: /* ADD Rd,Rd,Hs */
203 case 0x2: /* ADD Hd,Hd,Rs */
204 case 0x3: /* ADD Hd,Hd,Hs */
205 *ainstr = 0xE0800000 /* base */
206 | (Rd << 16) /* Rn */
207 |(Rd << 12) /* Rd */
208 |(Rs << 0); /* Rm */
209 break;
210 case 0x5: /* CMP Rd,Hs */
211 case 0x6: /* CMP Hd,Rs */
212 case 0x7: /* CMP Hd,Hs */
213 *ainstr = 0xE1500000 /* base */
214 | (Rd << 16) /* Rn */
215 |(Rd << 12) /* Rd */
216 |(Rs << 0); /* Rm */
217 break;
218 case 0x9: /* MOV Rd,Hs */
219 case 0xA: /* MOV Hd,Rs */
220 case 0xB: /* MOV Hd,Hs */
221 *ainstr = 0xE1A00000 /* base */
222 | (Rd << 16) /* Rn */
223 |(Rd << 12) /* Rd */
224 |(Rs << 0); /* Rm */
225 break;
226 case 0xC: /* BX Rs */
227 case 0xD: /* BX Hs */
228 *ainstr = 0xE12FFF10 /* base */
229 | ((tinstr & 0x0078) >> 3); /* Rd */
230 break;
231 case 0x0: /* UNDEFINED */
232 case 0x4: /* UNDEFINED */
233 case 0x8: /* UNDEFINED */
234 valid = t_undefined;
235 break;
236 case 0xE: /* BLX */
237 case 0xF: /* BLX */
238
239 //if (state->is_v5) {
240 if(1){
241 //valid = t_branch;
242 #if 1
243 *ainstr = 0xE1200030 /* base */
244 |(Rs << 0); /* Rm */
245 #endif
246 } else {
247 valid = t_undefined;
248 }
249 break;
250 }
251 }
252 break;
253 case 9: /* LDR Rd,[PC,#imm8] */
254 /* Format 6 */
255 *ainstr = 0xE59F0000 /* base */
256 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
257 |((tinstr & 0x00FF) << (2 - 0)); /* off8 */
258 break;
259 case 10:
260 case 11:
261 /* TODO: Format 7 and Format 8 perform the same ARM encoding, so
262 the following could be merged into a single subset, saving on
263 the following boolean: */
264 if ((tinstr & (1 << 9)) == 0) {
265 /* Format 7 */
266 ARMword subset[4] = {
267 0xE7800000, /* STR Rd,[Rb,Ro] */
268 0xE7C00000, /* STRB Rd,[Rb,Ro] */
269 0xE7900000, /* LDR Rd,[Rb,Ro] */
270 0xE7D00000 /* LDRB Rd,[Rb,Ro] */
271 };
272 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
273 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
274 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
275 |((tinstr & 0x01C0) >> 6); /* Ro */
276 }
277 else {
278 /* Format 8 */
279 ARMword subset[4] = {
280 0xE18000B0, /* STRH Rd,[Rb,Ro] */
281 0xE19000D0, /* LDRSB Rd,[Rb,Ro] */
282 0xE19000B0, /* LDRH Rd,[Rb,Ro] */
283 0xE19000F0 /* LDRSH Rd,[Rb,Ro] */
284 };
285 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
286 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
287 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
288 |((tinstr & 0x01C0) >> 6); /* Ro */
289 }
290 break;
291 case 12: /* STR Rd,[Rb,#imm5] */
292 case 13: /* LDR Rd,[Rb,#imm5] */
293 case 14: /* STRB Rd,[Rb,#imm5] */
294 case 15: /* LDRB Rd,[Rb,#imm5] */
295 /* Format 9 */
296 {
297 ARMword subset[4] = {
298 0xE5800000, /* STR Rd,[Rb,#imm5] */
299 0xE5900000, /* LDR Rd,[Rb,#imm5] */
300 0xE5C00000, /* STRB Rd,[Rb,#imm5] */
301 0xE5D00000 /* LDRB Rd,[Rb,#imm5] */
302 };
303 /* The offset range defends on whether we are transferring a
304 byte or word value: */
305 *ainstr = subset[(tinstr & 0x1800) >> 11] /* base */
306 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
307 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
308 |((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */
309 }
310 break;
311 case 16: /* STRH Rd,[Rb,#imm5] */
312 case 17: /* LDRH Rd,[Rb,#imm5] */
313 /* Format 10 */
314 *ainstr = ((tinstr & (1 << 11)) /* base */
315 ? 0xE1D000B0 /* LDRH */
316 : 0xE1C000B0) /* STRH */
317 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
318 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
319 |((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */
320 |((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */
321 break;
322 case 18: /* STR Rd,[SP,#imm8] */
323 case 19: /* LDR Rd,[SP,#imm8] */
324 /* Format 11 */
325 *ainstr = ((tinstr & (1 << 11)) /* base */
326 ? 0xE59D0000 /* LDR */
327 : 0xE58D0000) /* STR */
328 |((tinstr & 0x0700) << (12 - 8)) /* Rd */
329 |((tinstr & 0x00FF) << 2); /* off8 */
330 break;
331 case 20: /* ADD Rd,PC,#imm8 */
332 case 21: /* ADD Rd,SP,#imm8 */
333 /* Format 12 */
334 if ((tinstr & (1 << 11)) == 0) {
335 /* NOTE: The PC value used here should by word aligned */
336 /* We encode shift-left-by-2 in the rotate immediate field,
337 so no shift of off8 is needed. */
338 *ainstr = 0xE28F0F00 /* base */
339 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
340 |(tinstr & 0x00FF); /* off8 */
341 }
342 else {
343 /* We encode shift-left-by-2 in the rotate immediate field,
344 so no shift of off8 is needed. */
345 *ainstr = 0xE28D0F00 /* base */
346 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
347 |(tinstr & 0x00FF); /* off8 */
348 }
349 break;
350 case 22:
351 case 23:
352 if ((tinstr & 0x0F00) == 0x0000) {
353 /* Format 13 */
354 /* NOTE: The instruction contains a shift left of 2
355 equivalent (implemented as ROR #30): */
356 *ainstr = ((tinstr & (1 << 7)) /* base */
357 ? 0xE24DDF00 /* SUB */
358 : 0xE28DDF00) /* ADD */
359 |(tinstr & 0x007F); /* off7 */
360 }
361 else if ((tinstr & 0x0F00) == 0x0e00)
362 *ainstr = 0xEF000000 | SWI_Breakpoint;
363 else {
364 /* Format 14 */
365 ARMword subset[4] = {
366 0xE92D0000, /* STMDB sp!,{rlist} */
367 0xE92D4000, /* STMDB sp!,{rlist,lr} */
368 0xE8BD0000, /* LDMIA sp!,{rlist} */
369 0xE8BD8000 /* LDMIA sp!,{rlist,pc} */
370 };
371 *ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)] /* base */
372 |(tinstr & 0x00FF); /* mask8 */
373 }
374 break;
375 case 24: /* STMIA */
376 case 25: /* LDMIA */
377 /* Format 15 */
378 *ainstr = ((tinstr & (1 << 11)) /* base */
379 ? 0xE8B00000 /* LDMIA */
380 : 0xE8A00000) /* STMIA */
381 |((tinstr & 0x0700) << (16 - 8)) /* Rb */
382 |(tinstr & 0x00FF); /* mask8 */
383 break;
384 case 26: /* Bcc */
385 case 27: /* Bcc/SWI */
386 if ((tinstr & 0x0F00) == 0x0F00) {
387 #if 0
388 if (tinstr == (ARMul_ABORTWORD & 0xffff) &&
389 state->AbortAddr == pc) {
390 *ainstr = ARMul_ABORTWORD;
391 break;
392 }
393 #endif
394 /* Format 17 : SWI */
395 *ainstr = 0xEF000000;
396 /* Breakpoint must be handled specially. */
397 if ((tinstr & 0x00FF) == 0x18)
398 *ainstr |= ((tinstr & 0x00FF) << 16);
399 /* New breakpoint value. See gdb/arm-tdep.c */
400 else if ((tinstr & 0x00FF) == 0xFE)
401 *ainstr |= SWI_Breakpoint;
402 else
403 *ainstr |= (tinstr & 0x00FF);
404 }
405 else if ((tinstr & 0x0F00) != 0x0E00) {
406 /* Format 16 */
407 #if 0
408 int doit = FALSE;
409 /* TODO: Since we are doing a switch here, we could just add
410 the SWI and undefined instruction checks into this
411 switch to same on a couple of conditionals: */
412 switch ((tinstr & 0x0F00) >> 8) {
413 case EQ:
414 doit = ZFLAG;
415 break;
416 case NE:
417 doit = !ZFLAG;
418 break;
419 case VS:
420 doit = VFLAG;
421 break;
422 case VC:
423 doit = !VFLAG;
424 break;
425 case MI:
426 doit = NFLAG;
427 break;
428 case PL:
429 doit = !NFLAG;
430 break;
431 case CS:
432 doit = CFLAG;
433 break;
434 case CC:
435 doit = !CFLAG;
436 break;
437 case HI:
438 doit = (CFLAG && !ZFLAG);
439 break;
440 case LS:
441 doit = (!CFLAG || ZFLAG);
442 break;
443 case GE:
444 doit = ((!NFLAG && !VFLAG)
445 || (NFLAG && VFLAG));
446 break;
447 case LT:
448 doit = ((NFLAG && !VFLAG)
449 || (!NFLAG && VFLAG));
450 break;
451 case GT:
452 doit = ((!NFLAG && !VFLAG && !ZFLAG)
453 || (NFLAG && VFLAG && !ZFLAG));
454 break;
455 case LE:
456 doit = ((NFLAG && !VFLAG)
457 || (!NFLAG && VFLAG)) || ZFLAG;
458 break;
459 }
460 if (doit) {
461 state->Reg[15] = (pc + 4
462 + (((tinstr & 0x7F) << 1)
463 | ((tinstr & (1 << 7)) ?
464 0xFFFFFF00 : 0)));
465 FLUSHPIPE;
466 }
467 #endif
468 valid = t_branch;
469 }
470 else /* UNDEFINED : cc=1110(AL) uses different format */
471 valid = t_undefined;
472 break;
473 case 28: /* B */
474 /* Format 18 */
475 #if 0
476 state->Reg[15] = (pc + 4 + (((tinstr & 0x3FF) << 1)
477 | ((tinstr & (1 << 10)) ?
478 0xFFFFF800 : 0)));
479 #endif
480 //FLUSHPIPE;
481 valid = t_branch;
482 break;
483 case 29:
484 if(tinstr & 0x1)
485 valid = t_undefined;
486 else{
487 /* BLX 1 for armv5t and above */
488 //printf("In %s, After BLX(1),LR=0x%x,PC=0x%x, offset=0x%x\n", __FUNCTION__, state->Reg[14], state->Reg[15], (tinstr &0x7FF) << 1);
489 valid = t_branch;
490 }
491 break;
492 case 30: /* BL instruction 1 */
493 /* Format 19 */
494 /* There is no single ARM instruction equivalent for this Thumb
495 instruction. To keep the simulation simple (from the user
496 perspective) we check if the following instruction is the
497 second half of this BL, and if it is we simulate it
498 immediately. */
499 valid = t_branch;
500 break;
501 case 31: /* BL instruction 2 */
502 /* Format 19 */
503 /* There is no single ARM instruction equivalent for this
504 instruction. Also, it should only ever be matched with the
505 fmt19 "BL instruction 1" instruction. However, we do allow
506 the simulation of it on its own, with undefined results if
507 r14 is not suitably initialised. */
508 {
509 #if 0
510 ARMword tmp = (pc + 2);
511 state->Reg[15] =
512 (state->Reg[14] + ((tinstr & 0x07FF) << 1));
513 state->Reg[14] = (tmp | 1);
514 #endif
515 valid = t_branch;
516 }
517 break;
518 }
519 *inst_size = 2;
520 return valid;
521} 376}
diff --git a/src/core/arm/interpreter/arm_interpreter.cpp b/src/core/arm/interpreter/arm_interpreter.cpp
index e2aa5ce92..80ebc359e 100644
--- a/src/core/arm/interpreter/arm_interpreter.cpp
+++ b/src/core/arm/interpreter/arm_interpreter.cpp
@@ -1,5 +1,5 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/arm/interpreter/arm_interpreter.h" 5#include "core/arm/interpreter/arm_interpreter.h"
@@ -38,78 +38,43 @@ ARM_Interpreter::~ARM_Interpreter() {
38 delete state; 38 delete state;
39} 39}
40 40
41/**
42 * Set the Program Counter to an address
43 * @param addr Address to set PC to
44 */
45void ARM_Interpreter::SetPC(u32 pc) { 41void ARM_Interpreter::SetPC(u32 pc) {
46 state->pc = state->Reg[15] = pc; 42 state->pc = state->Reg[15] = pc;
47} 43}
48 44
49/*
50 * Get the current Program Counter
51 * @return Returns current PC
52 */
53u32 ARM_Interpreter::GetPC() const { 45u32 ARM_Interpreter::GetPC() const {
54 return state->pc; 46 return state->pc;
55} 47}
56 48
57/**
58 * Get an ARM register
59 * @param index Register index (0-15)
60 * @return Returns the value in the register
61 */
62u32 ARM_Interpreter::GetReg(int index) const { 49u32 ARM_Interpreter::GetReg(int index) const {
63 return state->Reg[index]; 50 return state->Reg[index];
64} 51}
65 52
66/**
67 * Set an ARM register
68 * @param index Register index (0-15)
69 * @param value Value to set register to
70 */
71void ARM_Interpreter::SetReg(int index, u32 value) { 53void ARM_Interpreter::SetReg(int index, u32 value) {
72 state->Reg[index] = value; 54 state->Reg[index] = value;
73} 55}
74 56
75/**
76 * Get the current CPSR register
77 * @return Returns the value of the CPSR register
78 */
79u32 ARM_Interpreter::GetCPSR() const { 57u32 ARM_Interpreter::GetCPSR() const {
80 return state->Cpsr; 58 return state->Cpsr;
81} 59}
82 60
83/**
84 * Set the current CPSR register
85 * @param cpsr Value to set CPSR to
86 */
87void ARM_Interpreter::SetCPSR(u32 cpsr) { 61void ARM_Interpreter::SetCPSR(u32 cpsr) {
88 state->Cpsr = cpsr; 62 state->Cpsr = cpsr;
89} 63}
90 64
91/**
92 * Returns the number of clock ticks since the last reset
93 * @return Returns number of clock ticks
94 */
95u64 ARM_Interpreter::GetTicks() const { 65u64 ARM_Interpreter::GetTicks() const {
96 return ARMul_Time(state); 66 return state->NumInstrs;
67}
68
69void ARM_Interpreter::AddTicks(u64 ticks) {
70 state->NumInstrs += ticks;
97} 71}
98 72
99/**
100 * Executes the given number of instructions
101 * @param num_instructions Number of instructions to executes
102 */
103void ARM_Interpreter::ExecuteInstructions(int num_instructions) { 73void ARM_Interpreter::ExecuteInstructions(int num_instructions) {
104 state->NumInstrsToExecute = num_instructions - 1; 74 state->NumInstrsToExecute = num_instructions - 1;
105 ARMul_Emulate32(state); 75 ARMul_Emulate32(state);
106} 76}
107 77
108/**
109 * Saves the current CPU context
110 * @param ctx Thread context to save
111 * @todo Do we need to save Reg[15] and NextInstr?
112 */
113void ARM_Interpreter::SaveContext(ThreadContext& ctx) { 78void ARM_Interpreter::SaveContext(ThreadContext& ctx) {
114 memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers)); 79 memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers));
115 memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers)); 80 memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers));
@@ -126,11 +91,6 @@ void ARM_Interpreter::SaveContext(ThreadContext& ctx) {
126 ctx.mode = state->NextInstr; 91 ctx.mode = state->NextInstr;
127} 92}
128 93
129/**
130 * Loads a CPU context
131 * @param ctx Thread context to load
132 * @param Do we need to load Reg[15] and NextInstr?
133 */
134void ARM_Interpreter::LoadContext(const ThreadContext& ctx) { 94void ARM_Interpreter::LoadContext(const ThreadContext& ctx) {
135 memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers)); 95 memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers));
136 memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers)); 96 memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
@@ -147,7 +107,6 @@ void ARM_Interpreter::LoadContext(const ThreadContext& ctx) {
147 state->NextInstr = ctx.mode; 107 state->NextInstr = ctx.mode;
148} 108}
149 109
150/// Prepare core for thread reschedule (if needed to correctly handle state)
151void ARM_Interpreter::PrepareReschedule() { 110void ARM_Interpreter::PrepareReschedule() {
152 state->NumInstrsToExecute = 0; 111 state->NumInstrsToExecute = 0;
153} 112}
diff --git a/src/core/arm/interpreter/arm_interpreter.h b/src/core/arm/interpreter/arm_interpreter.h
index ed53d997c..019dad5df 100644
--- a/src/core/arm/interpreter/arm_interpreter.h
+++ b/src/core/arm/interpreter/arm_interpreter.h
@@ -1,5 +1,5 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once 5#pragma once
@@ -61,6 +61,12 @@ public:
61 u64 GetTicks() const override; 61 u64 GetTicks() const override;
62 62
63 /** 63 /**
64 * Advance the CPU core by the specified number of ticks (e.g. to simulate CPU execution time)
65 * @param ticks Number of ticks to advance the CPU core
66 */
67 void AddTicks(u64 ticks) override;
68
69 /**
64 * Saves the current CPU context 70 * Saves the current CPU context
65 * @param ctx Thread context to save 71 * @param ctx Thread context to save
66 */ 72 */
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index 73223874e..b9c2aa6c2 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -949,7 +949,7 @@ ARMul_Emulate26 (ARMul_State * state)
949 //printf("t decode %04lx -> %08lx\n", instr & 0xffff, armOp); 949 //printf("t decode %04lx -> %08lx\n", instr & 0xffff, armOp);
950 950
951 if (armOp == 0xDEADC0DE) { 951 if (armOp == 0xDEADC0DE) {
952 DEBUG("Failed to decode thumb opcode %04X at %08X\n", instr, pc); 952 LOG_ERROR(Core_ARM11, "Failed to decode thumb opcode %04X at %08X", instr, pc);
953 } 953 }
954 954
955 instr = armOp; 955 instr = armOp;
@@ -1166,7 +1166,7 @@ mainswitch:
1166 else if ((((int)BITS(21, 27)) == 0x3e) && ((int)BITS(4, 6) == 0x1)) { 1166 else if ((((int)BITS(21, 27)) == 0x3e) && ((int)BITS(4, 6) == 0x1)) {
1167 //(ARMword)(instr<<(31-(n))) >> ((31-(n))+(m)) 1167 //(ARMword)(instr<<(31-(n))) >> ((31-(n))+(m))
1168 unsigned msb ,tmp_rn, tmp_rd, dst; 1168 unsigned msb ,tmp_rn, tmp_rd, dst;
1169 msb = tmp_rd = tmp_rn = dst = 0; 1169 tmp_rd = tmp_rn = dst = 0;
1170 Rd = BITS(12, 15); 1170 Rd = BITS(12, 15);
1171 Rn = BITS(0, 3); 1171 Rn = BITS(0, 3);
1172 lsb = BITS(7, 11); 1172 lsb = BITS(7, 11);
@@ -1356,7 +1356,13 @@ mainswitch:
1356 } 1356 }
1357 break; 1357 break;
1358 1358
1359 case 0x04: /* SUB reg */ 1359 case 0x04: /* SUB reg */
1360 // Signifies UMAAL
1361 if (state->is_v6 && BITS(4, 7) == 0x09) {
1362 if (handle_v6_insn(state, instr))
1363 break;
1364 }
1365
1360#ifdef MODET 1366#ifdef MODET
1361 if (BITS (4, 7) == 0xB) { 1367 if (BITS (4, 7) == 0xB) {
1362 /* STRH immediate offset, no write-back, down, post indexed. */ 1368 /* STRH immediate offset, no write-back, down, post indexed. */
@@ -1664,7 +1670,7 @@ mainswitch:
1664 op1 *= op2; 1670 op1 *= op2;
1665 //printf("SMLA_INST:BB,op1=0x%x, op2=0x%x. Rn=0x%x\n", op1, op2, Rn); 1671 //printf("SMLA_INST:BB,op1=0x%x, op2=0x%x. Rn=0x%x\n", op1, op2, Rn);
1666 if (AddOverflow(op1, Rn, op1 + Rn)) 1672 if (AddOverflow(op1, Rn, op1 + Rn))
1667 SETS; 1673 SETQ;
1668 state->Reg[BITS (16, 19)] = op1 + Rn; 1674 state->Reg[BITS (16, 19)] = op1 + Rn;
1669 break; 1675 break;
1670 } 1676 }
@@ -1676,7 +1682,7 @@ mainswitch:
1676 ARMword result = op1 + op2; 1682 ARMword result = op1 + op2;
1677 if (AddOverflow(op1, op2, result)) { 1683 if (AddOverflow(op1, op2, result)) {
1678 result = POS (result) ? 0x80000000 : 0x7fffffff; 1684 result = POS (result) ? 0x80000000 : 0x7fffffff;
1679 SETS; 1685 SETQ;
1680 } 1686 }
1681 state->Reg[BITS (12, 15)] = result; 1687 state->Reg[BITS (12, 15)] = result;
1682 break; 1688 break;
@@ -1718,7 +1724,7 @@ mainswitch:
1718 TAKEABORT; 1724 TAKEABORT;
1719 } else if ((BITS (0, 11) == 0) && (LHSReg == 15)) { /* MRS CPSR */ 1725 } else if ((BITS (0, 11) == 0) && (LHSReg == 15)) { /* MRS CPSR */
1720 UNDEF_MRSPC; 1726 UNDEF_MRSPC;
1721 DEST = ECC | EINT | EMODE; 1727 DEST = ARMul_GetCPSR(state);
1722 } else { 1728 } else {
1723 UNDEF_Test; 1729 UNDEF_Test;
1724 } 1730 }
@@ -1737,7 +1743,7 @@ mainswitch:
1737 //chy 2006-02-15 if in user mode, can not set cpsr 0:23 1743 //chy 2006-02-15 if in user mode, can not set cpsr 0:23
1738 //from p165 of ARMARM book 1744 //from p165 of ARMARM book
1739 state->Cpsr = GETSPSR (state->Bank); 1745 state->Cpsr = GETSPSR (state->Bank);
1740 //ARMul_CPSRAltered (state); 1746 ARMul_CPSRAltered (state);
1741#else 1747#else
1742 rhs = DPRegRHS; 1748 rhs = DPRegRHS;
1743 temp = LHS & rhs; 1749 temp = LHS & rhs;
@@ -1789,7 +1795,7 @@ mainswitch:
1789 ARMword Rn = state->Reg[BITS(12, 15)]; 1795 ARMword Rn = state->Reg[BITS(12, 15)];
1790 1796
1791 if (AddOverflow((ARMword)result, Rn, (ARMword)(result + Rn))) 1797 if (AddOverflow((ARMword)result, Rn, (ARMword)(result + Rn)))
1792 SETS; 1798 SETQ;
1793 result += Rn; 1799 result += Rn;
1794 } 1800 }
1795 state->Reg[BITS (16, 19)] = (ARMword)result; 1801 state->Reg[BITS (16, 19)] = (ARMword)result;
@@ -1805,7 +1811,7 @@ mainswitch:
1805 if (SubOverflow 1811 if (SubOverflow
1806 (op1, op2, result)) { 1812 (op1, op2, result)) {
1807 result = POS (result) ? 0x80000000 : 0x7fffffff; 1813 result = POS (result) ? 0x80000000 : 0x7fffffff;
1808 SETS; 1814 SETQ;
1809 } 1815 }
1810 1816
1811 state->Reg[BITS (12, 15)] = result; 1817 state->Reg[BITS (12, 15)] = result;
@@ -1877,7 +1883,7 @@ mainswitch:
1877 /* TEQP reg */ 1883 /* TEQP reg */
1878#ifdef MODE32 1884#ifdef MODE32
1879 state->Cpsr = GETSPSR (state->Bank); 1885 state->Cpsr = GETSPSR (state->Bank);
1880 //ARMul_CPSRAltered (state); 1886 ARMul_CPSRAltered (state);
1881#else 1887#else
1882 rhs = DPRegRHS; 1888 rhs = DPRegRHS;
1883 temp = LHS ^ rhs; 1889 temp = LHS ^ rhs;
@@ -1928,13 +1934,13 @@ mainswitch:
1928 1934
1929 if (AddOverflow 1935 if (AddOverflow
1930 (op2, op2, op2d)) { 1936 (op2, op2, op2d)) {
1931 SETS; 1937 SETQ;
1932 op2d = POS (op2d) ? 0x80000000 : 0x7fffffff; 1938 op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
1933 } 1939 }
1934 1940
1935 result = op1 + op2d; 1941 result = op1 + op2d;
1936 if (AddOverflow(op1, op2d, result)) { 1942 if (AddOverflow(op1, op2d, result)) {
1937 SETS; 1943 SETQ;
1938 result = POS (result) ? 0x80000000 : 0x7fffffff; 1944 result = POS (result) ? 0x80000000 : 0x7fffffff;
1939 } 1945 }
1940 1946
@@ -1993,7 +1999,7 @@ mainswitch:
1993 /* CMPP reg. */ 1999 /* CMPP reg. */
1994#ifdef MODE32 2000#ifdef MODE32
1995 state->Cpsr = GETSPSR (state->Bank); 2001 state->Cpsr = GETSPSR (state->Bank);
1996 //ARMul_CPSRAltered (state); 2002 ARMul_CPSRAltered (state);
1997#else 2003#else
1998 rhs = DPRegRHS; 2004 rhs = DPRegRHS;
1999 temp = LHS - rhs; 2005 temp = LHS - rhs;
@@ -2047,13 +2053,13 @@ mainswitch:
2047 ARMword result; 2053 ARMword result;
2048 2054
2049 if (AddOverflow(op2, op2, op2d)) { 2055 if (AddOverflow(op2, op2, op2d)) {
2050 SETS; 2056 SETQ;
2051 op2d = POS (op2d) ? 0x80000000 : 0x7fffffff; 2057 op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
2052 } 2058 }
2053 2059
2054 result = op1 - op2d; 2060 result = op1 - op2d;
2055 if (SubOverflow(op1, op2d, result)) { 2061 if (SubOverflow(op1, op2d, result)) {
2056 SETS; 2062 SETQ;
2057 result = POS (result) ? 0x80000000 : 0x7fffffff; 2063 result = POS (result) ? 0x80000000 : 0x7fffffff;
2058 } 2064 }
2059 2065
@@ -2112,7 +2118,7 @@ mainswitch:
2112 if (DESTReg == 15) { 2118 if (DESTReg == 15) {
2113#ifdef MODE32 2119#ifdef MODE32
2114 state->Cpsr = GETSPSR (state->Bank); 2120 state->Cpsr = GETSPSR (state->Bank);
2115 //ARMul_CPSRAltered (state); 2121 ARMul_CPSRAltered (state);
2116#else 2122#else
2117 rhs = DPRegRHS; 2123 rhs = DPRegRHS;
2118 temp = LHS + rhs; 2124 temp = LHS + rhs;
@@ -2200,17 +2206,57 @@ mainswitch:
2200 Handle_Store_Double (state, instr); 2206 Handle_Store_Double (state, instr);
2201 break; 2207 break;
2202 } 2208 }
2209 if (BITS(4, 11) == 0xF9) { //strexd
2210 u32 l = LHSReg;
2211
2212 bool enter = false;
2213
2214 if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr)&&
2215 state->currentexvald == (u32)ARMul_ReadWord(state, state->currentexaddr + 4))
2216 enter = true;
2217
2218
2219 //todo bug this and STREXD and LDREXD http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360e/CHDGJGGC.html
2220
2221
2222 if (enter) {
2223 ARMul_StoreWordN(state, LHS, state->Reg[RHSReg]);
2224 ARMul_StoreWordN(state,LHS + 4 , state->Reg[RHSReg + 1]);
2225 state->Reg[DESTReg] = 0;
2226 } else {
2227 state->Reg[DESTReg] = 1;
2228 }
2229
2230 break;
2231 }
2203#endif 2232#endif
2204 dest = DPRegRHS; 2233 dest = DPRegRHS;
2205 WRITEDEST (dest); 2234 WRITEDEST (dest);
2206 break; 2235 break;
2207 2236
2208 case 0x1b: /* MOVS reg */ 2237 case 0x1B: /* MOVS reg */
2209#ifdef MODET 2238#ifdef MODET
2239 /* ldrexd ichfly */
2240 if (BITS(0, 11) == 0xF9F) { //strexd
2241 lhs = LHS;
2242
2243 state->currentexaddr = lhs;
2244 state->currentexval = (u32)ARMul_ReadWord(state, lhs);
2245 state->currentexvald = (u32)ARMul_ReadWord(state, lhs + 4);
2246
2247 state->Reg[DESTReg] = ARMul_LoadWordN(state, lhs);
2248 state->Reg[DESTReg] = ARMul_LoadWordN(state, lhs + 4);
2249 break;
2250 }
2251
2210 if ((BITS (4, 11) & 0xF9) == 0x9) 2252 if ((BITS (4, 11) & 0xF9) == 0x9)
2211 /* LDR register offset, write-back, up, pre indexed. */ 2253 /* LDR register offset, write-back, up, pre indexed. */
2212 LHPREUPWB (); 2254 LHPREUPWB ();
2213 /* Continue with remaining instruction decoding. */ 2255 /* Continue with remaining instruction decoding. */
2256
2257
2258
2259
2214#endif 2260#endif
2215 dest = DPSRegRHS; 2261 dest = DPSRegRHS;
2216 WRITESDEST (dest); 2262 WRITESDEST (dest);
@@ -2297,12 +2343,12 @@ mainswitch:
2297 if (state->currentexval == (u32)ARMul_LoadHalfWord(state, state->currentexaddr))enter = true; 2343 if (state->currentexval == (u32)ARMul_LoadHalfWord(state, state->currentexaddr))enter = true;
2298 2344
2299 2345
2300 ARMul_StoreHalfWord(state, lhs, RHS);
2301 //StoreWord(state, lhs, RHS) 2346 //StoreWord(state, lhs, RHS)
2302 if (state->Aborted) { 2347 if (state->Aborted) {
2303 TAKEABORT; 2348 TAKEABORT;
2304 } 2349 }
2305 if (enter) { 2350 if (enter) {
2351 ARMul_StoreHalfWord(state, lhs, RHS);
2306 state->Reg[DESTReg] = 0; 2352 state->Reg[DESTReg] = 0;
2307 } else { 2353 } else {
2308 state->Reg[DESTReg] = 1; 2354 state->Reg[DESTReg] = 1;
@@ -2520,7 +2566,7 @@ mainswitch:
2520 /* TSTP immed. */ 2566 /* TSTP immed. */
2521#ifdef MODE32 2567#ifdef MODE32
2522 state->Cpsr = GETSPSR (state->Bank); 2568 state->Cpsr = GETSPSR (state->Bank);
2523 //ARMul_CPSRAltered (state); 2569 ARMul_CPSRAltered (state);
2524#else 2570#else
2525 temp = LHS & DPImmRHS; 2571 temp = LHS & DPImmRHS;
2526 SETR15PSR (temp); 2572 SETR15PSR (temp);
@@ -2547,7 +2593,7 @@ mainswitch:
2547 /* TEQP immed. */ 2593 /* TEQP immed. */
2548#ifdef MODE32 2594#ifdef MODE32
2549 state->Cpsr = GETSPSR (state->Bank); 2595 state->Cpsr = GETSPSR (state->Bank);
2550 //ARMul_CPSRAltered (state); 2596 ARMul_CPSRAltered (state);
2551#else 2597#else
2552 temp = LHS ^ DPImmRHS; 2598 temp = LHS ^ DPImmRHS;
2553 SETR15PSR (temp); 2599 SETR15PSR (temp);
@@ -2568,7 +2614,7 @@ mainswitch:
2568 /* CMPP immed. */ 2614 /* CMPP immed. */
2569#ifdef MODE32 2615#ifdef MODE32
2570 state->Cpsr = GETSPSR (state->Bank); 2616 state->Cpsr = GETSPSR (state->Bank);
2571 //ARMul_CPSRAltered (state); 2617 ARMul_CPSRAltered (state);
2572#else 2618#else
2573 temp = LHS - DPImmRHS; 2619 temp = LHS - DPImmRHS;
2574 SETR15PSR (temp); 2620 SETR15PSR (temp);
@@ -2604,7 +2650,7 @@ mainswitch:
2604 /* CMNP immed. */ 2650 /* CMNP immed. */
2605#ifdef MODE32 2651#ifdef MODE32
2606 state->Cpsr = GETSPSR (state->Bank); 2652 state->Cpsr = GETSPSR (state->Bank);
2607 //ARMul_CPSRAltered (state); 2653 ARMul_CPSRAltered (state);
2608#else 2654#else
2609 temp = LHS + DPImmRHS; 2655 temp = LHS + DPImmRHS;
2610 SETR15PSR (temp); 2656 SETR15PSR (temp);
@@ -3054,27 +3100,21 @@ mainswitch:
3054 break; 3100 break;
3055 3101
3056 case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */ 3102 case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */
3057 //ichfly PKHBT PKHTB todo check this 3103 if ((instr & 0x70) == 0x10) { //pkhbt
3058 if ((instr & 0x70) == 0x10) //pkhbt
3059 {
3060 u8 idest = BITS(12, 15); 3104 u8 idest = BITS(12, 15);
3061 u8 rfis = BITS(16, 19); 3105 u8 rfis = BITS(16, 19);
3062 u8 rlast = BITS(0, 3); 3106 u8 rlast = BITS(0, 3);
3063 u8 ishi = BITS(7,11); 3107 u8 ishi = BITS(7,11);
3064 state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000); 3108 state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000);
3065 break; 3109 break;
3066 } 3110 } else if ((instr & 0x70) == 0x50) { //pkhtb
3067 else if ((instr & 0x70) == 0x50)//pkhtb 3111 u8 rd_idx = BITS(12, 15);
3068 { 3112 u8 rn_idx = BITS(16, 19);
3069 u8 idest = BITS(12, 15); 3113 u8 rm_idx = BITS(0, 3);
3070 u8 rfis = BITS(16, 19); 3114 u8 imm5 = BITS(7, 11) ? BITS(7, 11) : 31;
3071 u8 rlast = BITS(0, 3); 3115 state->Reg[rd_idx] = ((static_cast<s32>(state->Reg[rm_idx]) >> imm5) & 0xFFFF) | ((state->Reg[rn_idx]) & 0xFFFF0000);
3072 u8 ishi = BITS(7, 11);
3073 if (ishi == 0)ishi = 0x20;
3074 state->Reg[idest] = (((int)(state->Reg[rlast]) >> (int)(ishi))& 0xFFFF) | ((state->Reg[rfis]) & 0xFFFF0000);
3075 break; 3116 break;
3076 } 3117 } else if (BIT (4)) {
3077 else if (BIT (4)) {
3078#ifdef MODE32 3118#ifdef MODE32
3079 if (state->is_v6 3119 if (state->is_v6
3080 && handle_v6_insn (state, instr)) 3120 && handle_v6_insn (state, instr))
@@ -3437,7 +3477,7 @@ mainswitch:
3437 3477
3438 case 0x7f: /* Load Byte, WriteBack, Pre Inc, Reg. */ 3478 case 0x7f: /* Load Byte, WriteBack, Pre Inc, Reg. */
3439 if (BIT (4)) { 3479 if (BIT (4)) {
3440 DEBUG("got unhandled special breakpoint\n"); 3480 LOG_DEBUG(Core_ARM11, "got unhandled special breakpoint");
3441 return 1; 3481 return 1;
3442 } 3482 }
3443 UNDEF_LSRBaseEQOffWb; 3483 UNDEF_LSRBaseEQOffWb;
@@ -3686,13 +3726,11 @@ mainswitch:
3686 3726
3687 /* Co-Processor Data Transfers. */ 3727 /* Co-Processor Data Transfers. */
3688 case 0xc4: 3728 case 0xc4:
3689 if ((instr & 0x0FF00FF0) == 0xC400B10) //vmov BIT(0-3), BIT(12-15), BIT(16-20), vmov d0, r0, r0 3729 if ((instr & 0x0FF00FF0) == 0xC400B10) { //vmov BIT(0-3), BIT(12-15), BIT(16-20), vmov d0, r0, r0
3690 {
3691 state->ExtReg[BITS(0, 3) << 1] = state->Reg[BITS(12, 15)]; 3730 state->ExtReg[BITS(0, 3) << 1] = state->Reg[BITS(12, 15)];
3692 state->ExtReg[(BITS(0, 3) << 1) + 1] = state->Reg[BITS(16, 20)]; 3731 state->ExtReg[(BITS(0, 3) << 1) + 1] = state->Reg[BITS(16, 20)];
3693 break; 3732 break;
3694 } 3733 } else if (state->is_v5) {
3695 else if (state->is_v5) {
3696 /* Reading from R15 is UNPREDICTABLE. */ 3734 /* Reading from R15 is UNPREDICTABLE. */
3697 if (BITS (12, 15) == 15 || BITS (16, 19) == 15) 3735 if (BITS (12, 15) == 15 || BITS (16, 19) == 15)
3698 ARMul_UndefInstr (state, instr); 3736 ARMul_UndefInstr (state, instr);
@@ -3712,22 +3750,18 @@ mainswitch:
3712 break; 3750 break;
3713 3751
3714 case 0xc5: 3752 case 0xc5:
3715 if ((instr & 0x00000FF0) == 0xB10) //vmov BIT(12-15), BIT(16-20), BIT(0-3) vmov r0, r0, d0 3753 if ((instr & 0x00000FF0) == 0xB10) { //vmov BIT(12-15), BIT(16-20), BIT(0-3) vmov r0, r0, d0
3716 {
3717 state->Reg[BITS(12, 15)] = state->ExtReg[BITS(0, 3) << 1]; 3754 state->Reg[BITS(12, 15)] = state->ExtReg[BITS(0, 3) << 1];
3718 state->Reg[BITS(16, 19)] = state->ExtReg[(BITS(0, 3) << 1) + 1]; 3755 state->Reg[BITS(16, 19)] = state->ExtReg[(BITS(0, 3) << 1) + 1];
3719 break; 3756 break;
3720 } 3757 } else if (state->is_v5) {
3721 else if (state->is_v5) {
3722 /* Writes to R15 are UNPREDICATABLE. */ 3758 /* Writes to R15 are UNPREDICATABLE. */
3723 if (DESTReg == 15 || LHSReg == 15) 3759 if (DESTReg == 15 || LHSReg == 15)
3724 ARMul_UndefInstr (state, instr); 3760 ARMul_UndefInstr (state, instr);
3725 /* Is access to the coprocessor allowed ? */ 3761 /* Is access to the coprocessor allowed ? */
3726 else if (!CP_ACCESS_ALLOWED(state, CPNum)) 3762 else if (!CP_ACCESS_ALLOWED(state, CPNum)) {
3727 {
3728 ARMul_UndefInstr(state, instr); 3763 ARMul_UndefInstr(state, instr);
3729 } 3764 } else {
3730 else {
3731 /* MRRC, ARMv5TE and up */ 3765 /* MRRC, ARMv5TE and up */
3732 ARMul_MRRC (state, instr, &DEST, &(state->Reg[LHSReg])); 3766 ARMul_MRRC (state, instr, &DEST, &(state->Reg[LHSReg]));
3733 break; 3767 break;
@@ -4565,7 +4599,7 @@ out:
4565#ifdef MODE32 4599#ifdef MODE32
4566 if (state->Bank > 0) { 4600 if (state->Bank > 0) {
4567 state->Cpsr = state->Spsr[state->Bank]; 4601 state->Cpsr = state->Spsr[state->Bank];
4568 //ARMul_CPSRAltered (state); 4602 ARMul_CPSRAltered (state);
4569 } 4603 }
4570#ifdef MODET 4604#ifdef MODET
4571 if (TFLAG) 4605 if (TFLAG)
@@ -5256,7 +5290,7 @@ L_ldm_s_makeabort:
5256 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode 5290 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
5257 if (state->Mode != USER26MODE && state->Mode != USER32MODE ) { 5291 if (state->Mode != USER26MODE && state->Mode != USER32MODE ) {
5258 state->Cpsr = GETSPSR (state->Bank); 5292 state->Cpsr = GETSPSR (state->Bank);
5259 //ARMul_CPSRAltered (state); 5293 ARMul_CPSRAltered (state);
5260 } 5294 }
5261 5295
5262 WriteR15 (state, PC); 5296 WriteR15 (state, PC);
@@ -5639,37 +5673,29 @@ L_stm_s_takeabort:
5639 /* Attempt to emulate an ARMv6 instruction. 5673 /* Attempt to emulate an ARMv6 instruction.
5640 Returns non-zero upon success. */ 5674 Returns non-zero upon success. */
5641 5675
5642 static int 5676 static int handle_v6_insn(ARMul_State* state, ARMword instr) {
5643 handle_v6_insn (ARMul_State * state, ARMword instr) { 5677 switch (BITS(20, 27)) {
5644 switch (BITS (20, 27)) {
5645 //ichfly
5646 case 0x66: //UQSUB8
5647 if ((instr & 0x0FF00FF0) == 0x06600FF0) {
5648 u32 rd = (instr >> 12) & 0xF;
5649 u32 rm = (instr >> 16) & 0xF;
5650 u32 rn = (instr >> 0) & 0xF;
5651 u32 subfrom = state->Reg[rm];
5652 u32 tosub = state->Reg[rn];
5653
5654 u8 b1 = (u8)((u8)(subfrom)-(u8)(tosub));
5655 if (b1 > (u8)(subfrom)) b1 = 0;
5656 u8 b2 = (u8)((u8)(subfrom >> 8) - (u8)(tosub >> 8));
5657 if (b2 > (u8)(subfrom >> 8)) b2 = 0;
5658 u8 b3 = (u8)((u8)(subfrom >> 16) - (u8)(tosub >> 16));
5659 if (b3 > (u8)(subfrom >> 16)) b3 = 0;
5660 u8 b4 = (u8)((u8)(subfrom >> 24) - (u8)(tosub >> 24));
5661 if (b4 > (u8)(subfrom >> 24)) b4 = 0;
5662 state->Reg[rd] = (u32)(b1 | b2 << 8 | b3 << 16 | b4 << 24);
5663 return 1;
5664 } else {
5665 printf("UQSUB8 decoding fail %08X",instr);
5666 }
5667#if 0
5668 case 0x03: 5678 case 0x03:
5669 printf ("Unhandled v6 insn: ldr\n"); 5679 printf ("Unhandled v6 insn: ldr\n");
5670 break; 5680 break;
5671 case 0x04: 5681 case 0x04: // UMAAL
5672 printf ("Unhandled v6 insn: umaal\n"); 5682 {
5683 const u8 rm_idx = BITS(8, 11);
5684 const u8 rn_idx = BITS(0, 3);
5685 const u8 rd_lo_idx = BITS(12, 15);
5686 const u8 rd_hi_idx = BITS(16, 19);
5687
5688 const u32 rm_val = state->Reg[rm_idx];
5689 const u32 rn_val = state->Reg[rn_idx];
5690 const u32 rd_lo_val = state->Reg[rd_lo_idx];
5691 const u32 rd_hi_val = state->Reg[rd_hi_idx];
5692
5693 const u64 result = (rn_val * rm_val) + rd_lo_val + rd_hi_val;
5694
5695 state->Reg[rd_lo_idx] = (result & 0xFFFFFFFF);
5696 state->Reg[rd_hi_idx] = ((result >> 32) & 0xFFFFFFFF);
5697 return 1;
5698 }
5673 break; 5699 break;
5674 case 0x06: 5700 case 0x06:
5675 printf ("Unhandled v6 insn: mls/str\n"); 5701 printf ("Unhandled v6 insn: mls/str\n");
@@ -5678,9 +5704,43 @@ L_stm_s_takeabort:
5678 printf ("Unhandled v6 insn: smi\n"); 5704 printf ("Unhandled v6 insn: smi\n");
5679 break; 5705 break;
5680 case 0x18: 5706 case 0x18:
5707 if (BITS(4, 7) == 0x9) {
5708 /* strex */
5709 u32 l = LHSReg;
5710 u32 r = RHSReg;
5711 u32 lhs = LHS;
5712
5713 bool enter = false;
5714
5715 if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr))enter = true;
5716 //StoreWord(state, lhs, RHS)
5717 if (state->Aborted) {
5718 TAKEABORT;
5719 }
5720
5721 if (enter) {
5722 ARMul_StoreWordS(state, lhs, RHS);
5723 state->Reg[DESTReg] = 0;
5724 }
5725 else {
5726 state->Reg[DESTReg] = 1;
5727 }
5728
5729 return 1;
5730 }
5681 printf ("Unhandled v6 insn: strex\n"); 5731 printf ("Unhandled v6 insn: strex\n");
5682 break; 5732 break;
5683 case 0x19: 5733 case 0x19:
5734 /* ldrex */
5735 if (BITS(4, 7) == 0x9) {
5736 u32 lhs = LHS;
5737
5738 state->currentexaddr = lhs;
5739 state->currentexval = ARMul_ReadWord(state, lhs);
5740
5741 LoadWord(state, instr, lhs);
5742 return 1;
5743 }
5684 printf ("Unhandled v6 insn: ldrex\n"); 5744 printf ("Unhandled v6 insn: ldrex\n");
5685 break; 5745 break;
5686 case 0x1a: 5746 case 0x1a:
@@ -5690,9 +5750,52 @@ L_stm_s_takeabort:
5690 printf ("Unhandled v6 insn: ldrexd\n"); 5750 printf ("Unhandled v6 insn: ldrexd\n");
5691 break; 5751 break;
5692 case 0x1c: 5752 case 0x1c:
5753 if (BITS(4, 7) == 0x9) {
5754 /* strexb */
5755 u32 lhs = LHS;
5756
5757 bool enter = false;
5758
5759 if (state->currentexval == (u32)ARMul_ReadByte(state, state->currentexaddr))enter = true;
5760
5761 BUSUSEDINCPCN;
5762 if (state->Aborted) {
5763 TAKEABORT;
5764 }
5765
5766
5767 if (enter) {
5768 ARMul_StoreByte(state, lhs, RHS);
5769 state->Reg[DESTReg] = 0;
5770 }
5771 else {
5772 state->Reg[DESTReg] = 1;
5773 }
5774
5775 //printf("In %s, strexb not implemented\n", __FUNCTION__);
5776 UNDEF_LSRBPC;
5777 /* WRITESDEST (dest); */
5778 return 1;
5779 }
5693 printf ("Unhandled v6 insn: strexb\n"); 5780 printf ("Unhandled v6 insn: strexb\n");
5694 break; 5781 break;
5695 case 0x1d: 5782 case 0x1d:
5783 if ((BITS(4, 7)) == 0x9) {
5784 /* ldrexb */
5785 u32 lhs = LHS;
5786 LoadByte(state, instr, lhs, LUNSIGNED);
5787
5788 state->currentexaddr = lhs;
5789 state->currentexval = (u32)ARMul_ReadByte(state, lhs);
5790
5791 //state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]);
5792 //printf("ldrexb\n");
5793 //printf("instr is %x rm is %d\n", instr, BITS(16, 19));
5794 //exit(-1);
5795
5796 //printf("In %s, ldrexb not implemented\n", __FUNCTION__);
5797 return 1;
5798 }
5696 printf ("Unhandled v6 insn: ldrexb\n"); 5799 printf ("Unhandled v6 insn: ldrexb\n");
5697 break; 5800 break;
5698 case 0x1e: 5801 case 0x1e:
@@ -5713,510 +5816,801 @@ L_stm_s_takeabort:
5713 case 0x3f: 5816 case 0x3f:
5714 printf ("Unhandled v6 insn: rbit\n"); 5817 printf ("Unhandled v6 insn: rbit\n");
5715 break; 5818 break;
5716#endif 5819 case 0x61: // SADD16, SASX, SSAX, and SSUB16
5717 case 0x61: 5820 if ((instr & 0xFF0) == 0xf10 || (instr & 0xFF0) == 0xf30 ||
5718 if ((instr & 0xFF0) == 0xf70)//ssub16 5821 (instr & 0xFF0) == 0xf50 || (instr & 0xFF0) == 0xf70)
5719 {
5720 u8 tar = BITS(12, 15);
5721 u8 src1 = BITS(16, 19);
5722 u8 src2 = BITS(0, 3);
5723 s16 a1 = (state->Reg[src1] & 0xFFFF);
5724 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5725 s16 b1 = (state->Reg[src2] & 0xFFFF);
5726 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
5727 state->Reg[tar] = (a1 - a2)&0xFFFF | (((b1 - b2)&0xFFFF)<< 0x10);
5728 return 1;
5729 }
5730 else if ((instr & 0xFF0) == 0xf10)//sadd16
5731 { 5822 {
5732 u8 tar = BITS(12, 15); 5823 const u8 rd_idx = BITS(12, 15);
5733 u8 src1 = BITS(16, 19); 5824 const u8 rm_idx = BITS(0, 3);
5734 u8 src2 = BITS(0, 3); 5825 const u8 rn_idx = BITS(16, 19);
5735 s16 a1 = (state->Reg[src1] & 0xFFFF); 5826 const s16 rn_lo = (state->Reg[rn_idx] & 0xFFFF);
5736 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 5827 const s16 rn_hi = ((state->Reg[rn_idx] >> 16) & 0xFFFF);
5737 s16 b1 = (state->Reg[src2] & 0xFFFF); 5828 const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
5738 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); 5829 const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF);
5739 state->Reg[tar] = (a1 + a2)&0xFFFF | (((b1 + b2)&0xFFFF)<< 0x10); 5830
5831 s32 lo_result;
5832 s32 hi_result;
5833
5834 // SADD16
5835 if ((instr & 0xFF0) == 0xf10) {
5836 lo_result = (rn_lo + rm_lo);
5837 hi_result = (rn_hi + rm_hi);
5838 }
5839 // SASX
5840 else if ((instr & 0xFF0) == 0xf30) {
5841 lo_result = (rn_lo - rm_hi);
5842 hi_result = (rn_hi + rm_lo);
5843 }
5844 // SSAX
5845 else if ((instr & 0xFF0) == 0xf50) {
5846 lo_result = (rn_lo + rm_hi);
5847 hi_result = (rn_hi - rm_lo);
5848 }
5849 // SSUB16
5850 else {
5851 lo_result = (rn_lo - rm_lo);
5852 hi_result = (rn_hi - rm_hi);
5853 }
5854
5855 state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
5856
5857 if (lo_result >= 0) {
5858 state->GEFlag |= (1 << 16);
5859 state->GEFlag |= (1 << 17);
5860 } else {
5861 state->GEFlag &= ~(1 << 16);
5862 state->GEFlag &= ~(1 << 17);
5863 }
5864
5865 if (hi_result >= 0) {
5866 state->GEFlag |= (1 << 18);
5867 state->GEFlag |= (1 << 19);
5868 } else {
5869 state->GEFlag &= ~(1 << 18);
5870 state->GEFlag &= ~(1 << 19);
5871 }
5872
5740 return 1; 5873 return 1;
5741 } 5874 }
5742 else if ((instr & 0xFF0) == 0xf50)//ssax 5875 // SADD8/SSUB8
5876 else if ((instr & 0xFF0) == 0xf90 || (instr & 0xFF0) == 0xff0)
5743 { 5877 {
5744 u8 tar = BITS(12, 15); 5878 const u8 rd_idx = BITS(12, 15);
5745 u8 src1 = BITS(16, 19); 5879 const u8 rm_idx = BITS(0, 3);
5746 u8 src2 = BITS(0, 3); 5880 const u8 rn_idx = BITS(16, 19);
5747 s16 a1 = (state->Reg[src1] & 0xFFFF); 5881 const u32 rm_val = state->Reg[rm_idx];
5748 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 5882 const u32 rn_val = state->Reg[rn_idx];
5749 s16 b1 = (state->Reg[src2] & 0xFFFF); 5883
5750 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); 5884 u8 lo_val1;
5751 state->Reg[tar] = (a1 - b2) & 0xFFFF | (((a2 + b1) & 0xFFFF) << 0x10); 5885 u8 lo_val2;
5886 u8 hi_val1;
5887 u8 hi_val2;
5888
5889 // SADD8
5890 if ((instr & 0xFF0) == 0xf90) {
5891 lo_val1 = (u8)((rn_val & 0xFF) + (rm_val & 0xFF));
5892 lo_val2 = (u8)(((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF));
5893 hi_val1 = (u8)(((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF));
5894 hi_val2 = (u8)(((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF));
5895
5896 if (lo_val1 & 0x80)
5897 state->GEFlag |= (1 << 16);
5898 else
5899 state->GEFlag &= ~(1 << 16);
5900
5901 if (lo_val2 & 0x80)
5902 state->GEFlag |= (1 << 17);
5903 else
5904 state->GEFlag &= ~(1 << 17);
5905
5906 if (hi_val1 & 0x80)
5907 state->GEFlag |= (1 << 18);
5908 else
5909 state->GEFlag &= ~(1 << 18);
5910
5911 if (hi_val2 & 0x80)
5912 state->GEFlag |= (1 << 19);
5913 else
5914 state->GEFlag &= ~(1 << 19);
5915 }
5916 // SSUB8
5917 else {
5918 lo_val1 = (u8)((rn_val & 0xFF) - (rm_val & 0xFF));
5919 lo_val2 = (u8)(((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF));
5920 hi_val1 = (u8)(((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF));
5921 hi_val2 = (u8)(((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF));
5922
5923 if (!(lo_val1 & 0x80))
5924 state->GEFlag |= (1 << 16);
5925 else
5926 state->GEFlag &= ~(1 << 16);
5927
5928 if (!(lo_val2 & 0x80))
5929 state->GEFlag |= (1 << 17);
5930 else
5931 state->GEFlag &= ~(1 << 17);
5932
5933 if (!(hi_val1 & 0x80))
5934 state->GEFlag |= (1 << 18);
5935 else
5936 state->GEFlag &= ~(1 << 18);
5937
5938 if (!(hi_val2 & 0x80))
5939 state->GEFlag |= (1 << 19);
5940 else
5941 state->GEFlag &= ~(1 << 19);
5942 }
5943
5944 state->Reg[rd_idx] = (lo_val1 | lo_val2 << 8 | hi_val1 << 16 | hi_val2 << 24);
5752 return 1; 5945 return 1;
5753 } 5946 }
5754 else if ((instr & 0xFF0) == 0xf30)//sasx 5947 else {
5755 { 5948 printf("Unhandled v6 insn: %08x", instr);
5756 u8 tar = BITS(12, 15);
5757 u8 src1 = BITS(16, 19);
5758 u8 src2 = BITS(0, 3);
5759 s16 a1 = (state->Reg[src1] & 0xFFFF);
5760 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5761 s16 b1 = (state->Reg[src2] & 0xFFFF);
5762 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
5763 state->Reg[tar] = (a2 - b1) & 0xFFFF | (((a2 + b1) & 0xFFFF) << 0x10);
5764 return 1;
5765 } 5949 }
5766 else printf ("Unhandled v6 insn: sadd/ssub\n");
5767 break; 5950 break;
5768 case 0x62: 5951 case 0x62: // QADD16, QASX, QSAX, QSUB16, QADD8, and QSUB8
5769 if ((instr & 0xFF0) == 0xf70)//QSUB16
5770 { 5952 {
5771 u8 tar = BITS(12, 15); 5953 const u8 op2 = BITS(5, 7);
5772 u8 src1 = BITS(16, 19); 5954
5773 u8 src2 = BITS(0, 3); 5955 const u8 rd_idx = BITS(12, 15);
5774 s16 a1 = (state->Reg[src1] & 0xFFFF); 5956 const u8 rn_idx = BITS(16, 19);
5775 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 5957 const u8 rm_idx = BITS(0, 3);
5776 s16 b1 = (state->Reg[src2] & 0xFFFF); 5958 const u16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
5777 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); 5959 const u16 rm_hi = ((state->Reg[rm_idx] >> 0x10) & 0xFFFF);
5778 s32 res1 = (a1 - b1); 5960 const u16 rn_lo = (state->Reg[rn_idx] & 0xFFFF);
5779 s32 res2 = (a2 - b2); 5961 const u16 rn_hi = ((state->Reg[rn_idx] >> 0x10) & 0xFFFF);
5780 if (res1 > 0x7FFF) res1 = 0x7FFF; 5962
5781 if (res2 > 0x7FFF) res2 = 0x7FFF; 5963 u16 lo_result = 0;
5782 if (res1 < 0x7FFF) res1 = -0x8000; 5964 u16 hi_result = 0;
5783 if (res2 < 0x7FFF) res2 = -0x8000; 5965
5784 state->Reg[tar] = (res1 & 0xFFFF) | ((res2 & 0xFFFF) << 0x10); 5966 // QADD16
5785 return 1; 5967 if (op2 == 0x00) {
5786 } 5968 lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo);
5787 else if ((instr & 0xFF0) == 0xf10)//QADD16 5969 hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi);
5788 { 5970 }
5789 u8 tar = BITS(12, 15); 5971 // QASX
5790 u8 src1 = BITS(16, 19); 5972 else if (op2 == 0x01) {
5791 u8 src2 = BITS(0, 3); 5973 lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi);
5792 s16 a1 = (state->Reg[src1] & 0xFFFF); 5974 hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo);
5793 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 5975 }
5794 s16 b1 = (state->Reg[src2] & 0xFFFF); 5976 // QSAX
5795 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); 5977 else if (op2 == 0x02) {
5796 s32 res1 = (a1 + b1); 5978 lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi);
5797 s32 res2 = (a2 + b2); 5979 hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo);
5798 if (res1 > 0x7FFF) res1 = 0x7FFF; 5980 }
5799 if (res2 > 0x7FFF) res2 = 0x7FFF; 5981 // QSUB16
5800 if (res1 < 0x7FFF) res1 = -0x8000; 5982 else if (op2 == 0x03) {
5801 if (res2 < 0x7FFF) res2 = -0x8000; 5983 lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo);
5802 state->Reg[tar] = ((res1) & 0xFFFF) | (((res2) & 0xFFFF) << 0x10); 5984 hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi);
5985 }
5986 // QADD8
5987 else if (op2 == 0x04) {
5988 lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) |
5989 ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8;
5990 hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) |
5991 ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8;
5992 }
5993 // QSUB8
5994 else if (op2 == 0x07) {
5995 lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) |
5996 ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8;
5997 hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) |
5998 ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8;
5999 }
6000
6001 state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
5803 return 1; 6002 return 1;
5804 } 6003 }
5805 else printf ("Unhandled v6 insn: qadd/qsub\n");
5806 break; 6004 break;
5807#if 0
5808 case 0x63: 6005 case 0x63:
5809 printf ("Unhandled v6 insn: shadd/shsub\n"); 6006 printf ("Unhandled v6 insn: shadd/shsub\n");
5810 break; 6007 break;
5811 case 0x65: 6008 case 0x65:
5812 printf ("Unhandled v6 insn: uadd/usub\n"); 6009 {
5813 break; 6010 u32 rd = (instr >> 12) & 0xF;
5814 case 0x66: 6011 u32 rn = (instr >> 16) & 0xF;
5815 printf ("Unhandled v6 insn: uqadd/uqsub\n"); 6012 u32 rm = (instr >> 0) & 0xF;
5816 break; 6013 u32 from = state->Reg[rn];
5817 case 0x67: 6014 u32 to = state->Reg[rm];
5818 printf ("Unhandled v6 insn: uhadd/uhsub\n"); 6015
5819 break; 6016 if ((instr & 0xFF0) == 0xF10 || (instr & 0xFF0) == 0xF70) { // UADD16/USUB16
5820 case 0x68: 6017 u32 h1, h2;
5821 printf ("Unhandled v6 insn: pkh/sxtab/selsxtb\n"); 6018 state->Cpsr &= 0xfff0ffff;
5822 break; 6019 if ((instr & 0x0F0) == 0x070) { // USUB16
5823#endif 6020 h1 = ((u16)from - (u16)to);
5824 case 0x6c: 6021 h2 = ((u16)(from >> 16) - (u16)(to >> 16));
5825 if ((instr & 0xf03f0) == 0xf0070) //uxtb16 6022
5826 { 6023 if (!(h1 & 0xffff0000))
5827 u8 src1 = BITS(0, 3); 6024 state->GEFlag |= (3 << 16);
5828 u8 tar = BITS(12, 15); 6025 else
5829 u32 base = state->Reg[src1]; 6026 state->GEFlag &= ~(3 << 16);
5830 u32 shamt = BITS(9,10)* 8;
5831 u32 in = ((base << (32 - shamt)) | (base >> shamt));
5832 state->Reg[tar] = in & 0x00FF00FF;
5833 return 1;
5834 }
5835 else
5836 printf ("Unhandled v6 insn: uxtb16/uxtab16\n");
5837 break;
5838 case 0x70:
5839 if ((instr & 0xf0d0) == 0xf010)//smuad //ichfly
5840 {
5841 u8 tar = BITS(16, 19);
5842 u8 src1 = BITS(0, 3);
5843 u8 src2 = BITS(8, 11);
5844 u8 swap = BIT(5);
5845 s16 a1 = (state->Reg[src1] & 0xFFFF);
5846 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5847 s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF);
5848 s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF);
5849 state->Reg[tar] = a1*a2 + b1*b2;
5850 return 1;
5851 6027
5852 } 6028 if (!(h2 & 0xffff0000))
5853 else if ((instr & 0xf0d0) == 0xf050)//smusd 6029 state->GEFlag |= (3 << 18);
5854 { 6030 else
5855 u8 tar = BITS(16, 19); 6031 state->GEFlag &= ~(3 << 18);
5856 u8 src1 = BITS(0, 3); 6032 }
5857 u8 src2 = BITS(8, 11); 6033 else { // UADD16
5858 u8 swap = BIT(5); 6034 h1 = ((u16)from + (u16)to);
5859 s16 a1 = (state->Reg[src1] & 0xFFFF); 6035 h2 = ((u16)(from >> 16) + (u16)(to >> 16));
5860 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 6036
5861 s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF); 6037 if (h1 & 0xffff0000)
5862 s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF); 6038 state->GEFlag |= (3 << 16);
5863 state->Reg[tar] = a1*a2 - b1*b2; 6039 else
5864 return 1; 6040 state->GEFlag &= ~(3 << 16);
5865 } 6041
5866 else if ((instr & 0xd0) == 0x10)//smlad 6042 if (h2 & 0xffff0000)
5867 { 6043 state->GEFlag |= (3 << 18);
5868 u8 tar = BITS(16, 19); 6044 else
5869 u8 src1 = BITS(0, 3); 6045 state->GEFlag &= ~(3 << 18);
5870 u8 src2 = BITS(8, 11); 6046 }
5871 u8 src3 = BITS(12, 15); 6047
5872 u8 swap = BIT(5); 6048 state->Reg[rd] = (u32)((h1 & 0xffff) | ((h2 & 0xffff) << 16));
5873
5874 u32 a3 = state->Reg[src3];
5875
5876 s16 a1 = (state->Reg[src1] & 0xFFFF);
5877 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5878 s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF);
5879 s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF);
5880 state->Reg[tar] = a1*a2 + b1*b2 + a3;
5881 return 1; 6049 return 1;
5882 } 6050 }
5883 else printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n"); 6051 else
5884 break; 6052 if ((instr & 0xFF0) == 0xF90 || (instr & 0xFF0) == 0xFF0) { // UADD8/USUB8
5885 case 0x74: 6053 u32 b1, b2, b3, b4;
5886 printf ("Unhandled v6 insn: smlald/smlsld\n"); 6054 state->Cpsr &= 0xfff0ffff;
5887 break; 6055 if ((instr & 0x0F0) == 0x0F0) { // USUB8
5888 case 0x75: 6056 b1 = ((u8)from - (u8)to);
5889 printf ("Unhandled v6 insn: smmla/smmls/smmul\n"); 6057 b2 = ((u8)(from >> 8) - (u8)(to >> 8));
5890 break; 6058 b3 = ((u8)(from >> 16) - (u8)(to >> 16));
5891 case 0x78: 6059 b4 = ((u8)(from >> 24) - (u8)(to >> 24));
5892 printf ("Unhandled v6 insn: usad/usada8\n"); 6060
5893 break; 6061 if (!(b1 & 0xffffff00))
5894#if 0 6062 state->GEFlag |= (1 << 16);
5895 case 0x7a: 6063 else
5896 printf ("Unhandled v6 insn: usbfx\n"); 6064 state->GEFlag &= ~(1 << 16);
5897 break;
5898 case 0x7c:
5899 printf ("Unhandled v6 insn: bfc/bfi\n");
5900 break;
5901#endif
5902 6065
6066 if (!(b2 & 0xffffff00))
6067 state->GEFlag |= (1 << 17);
6068 else
6069 state->GEFlag &= ~(1 << 17);
5903 6070
5904 /* add new instr for arm v6. */ 6071 if (!(b3 & 0xffffff00))
5905 ARMword lhs, temp; 6072 state->GEFlag |= (1 << 18);
5906 case 0x18: { /* ORR reg */ 6073 else
5907 /* dyf add armv6 instr strex 2010.9.17 */ 6074 state->GEFlag &= ~(1 << 18);
5908 if (BITS (4, 7) == 0x9) {
5909 u32 l = LHSReg;
5910 u32 r = RHSReg;
5911 lhs = LHS;
5912 6075
5913 bool enter = false; 6076 if (!(b4 & 0xffffff00))
6077 state->GEFlag |= (1 << 19);
6078 else
6079 state->GEFlag &= ~(1 << 19);
6080 }
6081 else { // UADD8
6082 b1 = ((u8)from + (u8)to);
6083 b2 = ((u8)(from >> 8) + (u8)(to >> 8));
6084 b3 = ((u8)(from >> 16) + (u8)(to >> 16));
6085 b4 = ((u8)(from >> 24) + (u8)(to >> 24));
5914 6086
5915 if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr))enter = true; 6087 if (b1 & 0xffffff00)
5916 ARMul_StoreWordS(state, lhs, RHS); 6088 state->GEFlag |= (1 << 16);
5917 //StoreWord(state, lhs, RHS) 6089 else
5918 if (state->Aborted) { 6090 state->GEFlag &= ~(1 << 16);
5919 TAKEABORT;
5920 }
5921 6091
5922 if (enter) { 6092 if (b2 & 0xffffff00)
5923 state->Reg[DESTReg] = 0; 6093 state->GEFlag |= (1 << 17);
5924 } else { 6094 else
5925 state->Reg[DESTReg] = 1; 6095 state->GEFlag &= ~(1 << 17);
5926 }
5927 6096
5928 return 1; 6097 if (b3 & 0xffffff00)
5929 } 6098 state->GEFlag |= (1 << 18);
5930 break; 6099 else
5931 } 6100 state->GEFlag &= ~(1 << 18);
5932 6101
5933 case 0x19: { /* orrs reg */ 6102 if (b4 & 0xffffff00)
5934 /* dyf add armv6 instr ldrex */ 6103 state->GEFlag |= (1 << 19);
5935 if (BITS (4, 7) == 0x9) { 6104 else
5936 lhs = LHS; 6105 state->GEFlag &= ~(1 << 19);
6106 }
5937 6107
5938 state->currentexaddr = lhs; 6108 state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24);
5939 state->currentexval = ARMul_ReadWord(state, lhs); 6109 return 1;
6110 }
6111 }
6112 printf("Unhandled v6 insn: uasx/usax\n");
6113 break;
6114 case 0x66: // UQADD16, UQASX, UQSAX, UQSUB16, UQADD8, and UQSUB8
6115 {
6116 const u8 rd_idx = BITS(12, 15);
6117 const u8 rm_idx = BITS(0, 3);
6118 const u8 rn_idx = BITS(16, 19);
6119 const u8 op2 = BITS(5, 7);
6120 const u32 rm_val = state->Reg[rm_idx];
6121 const u32 rn_val = state->Reg[rn_idx];
6122
6123 u16 lo_val = 0;
6124 u16 hi_val = 0;
6125
6126 // UQADD16
6127 if (op2 == 0x00) {
6128 lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF);
6129 hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
6130 }
6131 // UQASX
6132 else if (op2 == 0x01) {
6133 lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
6134 hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
6135 }
6136 // UQSAX
6137 else if (op2 == 0x02) {
6138 lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
6139 hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
6140 }
6141 // UQSUB16
6142 else if (op2 == 0x03) {
6143 lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF);
6144 hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
6145 }
6146 // UQADD8
6147 else if (op2 == 0x04) {
6148 lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) |
6149 ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8;
6150 hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) |
6151 ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8;
6152 }
6153 // UQSUB8
6154 else {
6155 lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) |
6156 ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8;
6157 hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) |
6158 ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8;
6159 }
5940 6160
5941 LoadWord (state, instr, lhs); 6161 state->Reg[rd_idx] = ((lo_val & 0xFFFF) | hi_val << 16);
5942 return 1; 6162 return 1;
5943 } 6163 }
5944 break; 6164 break;
5945 } 6165 case 0x67: // UHADD16, UHASX, UHSAX, UHSUB16, UHADD8, and UHSUB8.
6166 {
6167 const u8 op2 = BITS(5, 7);
5946 6168
5947 case 0x1c: { /* BIC reg */ 6169 const u8 rm_idx = BITS(0, 3);
5948 /* dyf add for STREXB */ 6170 const u8 rn_idx = BITS(16, 19);
5949 if (BITS (4, 7) == 0x9) { 6171 const u8 rd_idx = BITS(12, 15);
5950 lhs = LHS;
5951 6172
5952 bool enter = false; 6173 const u32 rm_val = state->Reg[rm_idx];
6174 const u32 rn_val = state->Reg[rn_idx];
5953 6175
5954 if (state->currentexval == (u32)ARMul_ReadByte(state, state->currentexaddr))enter = true; 6176 if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03)
6177 {
6178 u32 lo_val = 0;
6179 u32 hi_val = 0;
5955 6180
5956 ARMul_StoreByte (state, lhs, RHS); 6181 // UHADD16
5957 BUSUSEDINCPCN; 6182 if (op2 == 0x00) {
5958 if (state->Aborted) { 6183 lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
5959 TAKEABORT; 6184 hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
5960 } 6185 }
6186 // UHASX
6187 else if (op2 == 0x01) {
6188 lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
6189 hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
6190 }
6191 // UHSAX
6192 else if (op2 == 0x02) {
6193 lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
6194 hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
6195 }
6196 // UHSUB16
6197 else if (op2 == 0x03) {
6198 lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
6199 hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
6200 }
5961 6201
6202 lo_val >>= 1;
6203 hi_val >>= 1;
5962 6204
5963 if (enter) { 6205 state->Reg[rd_idx] = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16);
5964 state->Reg[DESTReg] = 0; 6206 return 1;
5965 } else { 6207 }
5966 state->Reg[DESTReg] = 1; 6208 else if (op2 == 0x04 || op2 == 0x07) {
6209 u32 sum1;
6210 u32 sum2;
6211 u32 sum3;
6212 u32 sum4;
6213
6214 // UHADD8
6215 if (op2 == 0x04) {
6216 sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
6217 sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
6218 sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
6219 sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
6220 }
6221 // UHSUB8
6222 else {
6223 sum1 = (rn_val & 0xFF) - (rm_val & 0xFF);
6224 sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
6225 sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
6226 sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
6227 }
6228
6229 sum1 >>= 1;
6230 sum2 >>= 1;
6231 sum3 >>= 1;
6232 sum4 >>= 1;
6233
6234 state->Reg[rd_idx] = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24);
6235 return 1;
5967 } 6236 }
5968
5969 //printf("In %s, strexb not implemented\n", __FUNCTION__);
5970 UNDEF_LSRBPC;
5971 /* WRITESDEST (dest); */
5972 return 1;
5973 } 6237 }
5974 break; 6238 break;
6239 case 0x68:
6240 {
6241 u32 rd = (instr >> 12) & 0xF;
6242 u32 rn = (instr >> 16) & 0xF;
6243 u32 rm = (instr >> 0) & 0xF;
6244 u32 from = state->Reg[rn];
6245 u32 to = state->Reg[rm];
6246 u32 cpsr = ARMul_GetCPSR(state);
6247 if ((instr & 0xFF0) == 0xFB0) { // SEL
6248 u32 result;
6249 if (cpsr & (1 << 16))
6250 result = from & 0xff;
6251 else
6252 result = to & 0xff;
6253 if (cpsr & (1 << 17))
6254 result |= from & 0x0000ff00;
6255 else
6256 result |= to & 0x0000ff00;
6257 if (cpsr & (1 << 18))
6258 result |= from & 0x00ff0000;
6259 else
6260 result |= to & 0x00ff0000;
6261 if (cpsr & (1 << 19))
6262 result |= from & 0xff000000;
6263 else
6264 result |= to & 0xff000000;
6265 state->Reg[rd] = result;
6266 return 1;
6267 }
5975 } 6268 }
6269 printf("Unhandled v6 insn: pkh/sxtab/selsxtb\n");
6270 break;
6271
6272 case 0x6a: // SSAT, SSAT16, SXTB, and SXTAB
6273 {
6274 const u8 op2 = BITS(5, 7);
6275
6276 // SSAT16
6277 if (op2 == 0x01) {
6278 const u8 rd_idx = BITS(12, 15);
6279 const u8 rn_idx = BITS(0, 3);
6280 const u8 num_bits = BITS(16, 19) + 1;
6281 const s16 min = -(0x8000 >> (16 - num_bits));
6282 const s16 max = (0x7FFF >> (16 - num_bits));
6283 s16 rn_lo = (state->Reg[rn_idx]);
6284 s16 rn_hi = (state->Reg[rn_idx] >> 16);
6285
6286 if (rn_lo > max) {
6287 rn_lo = max;
6288 SETQ;
6289 } else if (rn_lo < min) {
6290 rn_lo = min;
6291 SETQ;
6292 }
6293
6294 if (rn_hi > max) {
6295 rn_hi = max;
6296 SETQ;
6297 } else if (rn_hi < min) {
6298 rn_hi = min;
6299 SETQ;
6300 }
6301
6302 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi & 0xFFFF) << 16);
6303 return 1;
6304 }
6305 else if (op2 == 0x03) {
6306 const u8 rotation = BITS(10, 11) * 8;
6307 u32 rm = ((state->Reg[BITS(0, 3)] >> rotation) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotation)) & 0xFF) & 0xFF);
6308 if (rm & 0x80)
6309 rm |= 0xffffff00;
6310
6311 // SXTB, otherwise SXTAB
6312 if (BITS(16, 19) == 0xf)
6313 state->Reg[BITS(12, 15)] = rm;
6314 else
6315 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
6316
6317 return 1;
6318 }
6319 else {
6320 printf("Unimplemented op: SSAT");
6321 }
6322 }
6323 break;
6324
6325 case 0x6b: // REV, REV16, SXTH, and SXTAH
6326 {
6327 const u8 op2 = BITS(5, 7);
6328
6329 // REV
6330 if (op2 == 0x01) {
6331 DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24);
6332 return 1;
6333 }
6334 // REV16
6335 else if (op2 == 0x05) {
6336 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8);
6337 return 1;
6338 }
6339 else if (op2 == 0x03) {
6340 const u8 rotate = BITS(10, 11) * 8;
6341
6342 u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF);
6343 if (rm & 0x8000)
6344 rm |= 0xffff0000;
6345
6346 // SXTH, otherwise SXTAH
6347 if (BITS(16, 19) == 15)
6348 state->Reg[BITS(12, 15)] = rm;
6349 else
6350 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
6351
6352 return 1;
6353 }
6354 }
6355 break;
6356
6357 case 0x6c: // UXTB16 and UXTAB16
6358 {
6359 const u8 rm_idx = BITS(0, 3);
6360 const u8 rn_idx = BITS(16, 19);
6361 const u8 rd_idx = BITS(12, 15);
6362 const u32 rm_val = state->Reg[rm_idx];
6363 const u32 rn_val = state->Reg[rn_idx];
6364 const u32 rotation = BITS(10, 11) * 8;
6365 const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
6366
6367 // UXTB16
6368 if ((instr & 0xf03f0) == 0xf0070) {
6369 state->Reg[rd_idx] = rotated_rm & 0x00FF00FF;
6370 }
6371 else { // UXTAB16
6372 const u8 lo_rotated = (rotated_rm & 0xFF);
6373 const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated;
6374
6375 const u8 hi_rotated = (rotated_rm >> 16) & 0xFF;
6376 const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated;
6377
6378 state->Reg[rd_idx] = ((hi_result << 16) | (lo_result & 0xFFFF));
6379 }
6380
6381 return 1;
6382 }
6383 break;
6384 case 0x6e: // USAT, USAT16, UXTB, and UXTAB
6385 {
6386 const u8 op2 = BITS(5, 7);
6387
6388 // USAT16
6389 if (op2 == 0x01) {
6390 const u8 rd_idx = BITS(12, 15);
6391 const u8 rn_idx = BITS(0, 3);
6392 const u8 num_bits = BITS(16, 19);
6393 const s16 max = 0xFFFF >> (16 - num_bits);
6394 s16 rn_lo = (state->Reg[rn_idx]);
6395 s16 rn_hi = (state->Reg[rn_idx] >> 16);
6396
6397 if (max < rn_lo) {
6398 rn_lo = max;
6399 SETQ;
6400 } else if (rn_lo < 0) {
6401 rn_lo = 0;
6402 SETQ;
6403 }
6404
6405 if (max < rn_hi) {
6406 rn_hi = max;
6407 SETQ;
6408 } else if (rn_hi < 0) {
6409 rn_hi = 0;
6410 SETQ;
6411 }
6412
6413 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF);
6414 return 1;
6415 }
6416 else if (op2 == 0x03) {
6417 const u8 rotate = BITS(10, 11) * 8;
6418 const u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFF) & 0xFF);
6419
6420 if (BITS(16, 19) == 0xf)
6421 /* UXTB */
6422 state->Reg[BITS(12, 15)] = rm;
6423 else
6424 /* UXTAB */
6425 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
6426
6427 return 1;
6428 }
6429 else {
6430 printf("Unimplemented op: USAT");
6431 }
6432 }
6433 break;
6434
6435 case 0x6f: // UXTH, UXTAH, and REVSH.
6436 {
6437 const u8 op2 = BITS(5, 7);
6438
6439 // REVSH
6440 if (op2 == 0x05) {
6441 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00) >> 8);
6442 if (DEST & 0x8000)
6443 DEST |= 0xffff0000;
6444 return 1;
6445 }
6446 // UXTH and UXTAH
6447 else if (op2 == 0x03) {
6448 const u8 rotate = BITS(10, 11) * 8;
6449 const ARMword rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF);
6450
6451 // UXTH
6452 if (BITS(16, 19) == 0xf) {
6453 state->Reg[BITS(12, 15)] = rm;
6454 }
6455 // UXTAH
6456 else {
6457 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
6458 }
6459
6460 return 1;
6461 }
6462 }
6463 case 0x70:
6464 // ichfly
6465 // SMUAD, SMUSD, SMLAD, and SMLSD
6466 if ((instr & 0xf0d0) == 0xf010 || (instr & 0xf0d0) == 0xf050 ||
6467 (instr & 0xd0) == 0x10 || (instr & 0xd0) == 0x50)
6468 {
6469 const u8 rd_idx = BITS(16, 19);
6470 const u8 rn_idx = BITS(0, 3);
6471 const u8 rm_idx = BITS(8, 11);
6472 const u8 ra_idx = BITS(12, 15);
6473 const bool do_swap = (BIT(5) == 1);
5976 6474
5977 case 0x1d: { /* BICS reg */ 6475 u32 rm_val = state->Reg[rm_idx];
5978 if ((BITS (4, 7)) == 0x9) { 6476 const u32 rn_val = state->Reg[rn_idx];
5979 /* ldrexb */
5980 temp = LHS;
5981 LoadByte (state, instr, temp, LUNSIGNED);
5982 6477
5983 state->currentexaddr = temp; 6478 if (do_swap)
5984 state->currentexval = (u32)ARMul_ReadByte(state, temp); 6479 rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
5985 6480
5986 //state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]); 6481 const s16 rm_lo = (rm_val & 0xFFFF);
5987 //printf("ldrexb\n"); 6482 const s16 rm_hi = ((rm_val >> 16) & 0xFFFF);
5988 //printf("instr is %x rm is %d\n", instr, BITS(16, 19)); 6483 const s16 rn_lo = (rn_val & 0xFFFF);
5989 //exit(-1); 6484 const s16 rn_hi = ((rn_val >> 16) & 0xFFFF);
5990 6485
5991 //printf("In %s, ldrexb not implemented\n", __FUNCTION__); 6486 const u32 product1 = (rn_lo * rm_lo);
5992 return 1; 6487 const u32 product2 = (rn_hi * rm_hi);
5993 }
5994 break;
5995 }
5996 /* add end */
5997 6488
5998 case 0x6a: { 6489 // SMUAD and SMLAD
5999 ARMword Rm; 6490 if (BIT(6) == 0) {
6000 int ror = -1; 6491 state->Reg[rd_idx] = product1 + product2;
6001 6492
6002 switch (BITS (4, 11)) { 6493 if (BITS(12, 15) != 15) {
6003 case 0x07: 6494 state->Reg[rd_idx] += state->Reg[ra_idx];
6004 ror = 0; 6495 ARMul_AddOverflowQ(state, product1 + product2, state->Reg[ra_idx]);
6005 break; 6496 }
6006 case 0x47:
6007 ror = 8;
6008 break;
6009 case 0x87:
6010 ror = 16;
6011 break;
6012 case 0xc7:
6013 ror = 24;
6014 break;
6015 6497
6016 case 0x01: 6498 ARMul_AddOverflowQ(state, product1, product2);
6017 case 0xf3: 6499 }
6018 //ichfly 6500 // SMUSD and SMLSD
6019 //SSAT16 6501 else {
6020 { 6502 state->Reg[rd_idx] = product1 - product2;
6021 u8 tar = BITS(12,15); 6503
6022 u8 src = BITS(0, 3); 6504 if (BITS(12, 15) != 15)
6023 u8 val = BITS(16, 19) + 1; 6505 state->Reg[rd_idx] += state->Reg[ra_idx];
6024 s16 a1 = (state->Reg[src]); 6506 }
6025 s16 a2 = (state->Reg[src] >> 0x10);
6026 s16 min = (s16)(0x8000) >> (16 - val);
6027 s16 max = 0x7FFF >> (16 - val);
6028 if (min > a1) a1 = min;
6029 if (max < a1) a1 = max;
6030 if (min > a2) a2 = min;
6031 if (max < a2) a2 = max;
6032 u32 temp2 = ((u32)(a2)) << 0x10;
6033 state->Reg[tar] = (a1&0xFFFF) | (temp2);
6034 }
6035 6507
6036 return 1; 6508 return 1;
6037 default:
6038 break;
6039 } 6509 }
6040 6510 break;
6041 if (ror == -1) { 6511 case 0x74: // SMLALD and SMLSLD
6042 if (BITS (4, 6) == 0x7) { 6512 {
6043 printf ("Unhandled v6 insn: ssat\n"); 6513 const u8 rm_idx = BITS(8, 11);
6044 return 0; 6514 const u8 rn_idx = BITS(0, 3);
6515 const u8 rdlo_idx = BITS(12, 15);
6516 const u8 rdhi_idx = BITS(16, 19);
6517 const bool do_swap = (BIT(5) == 1);
6518
6519 const u32 rdlo_val = state->Reg[rdlo_idx];
6520 const u32 rdhi_val = state->Reg[rdhi_idx];
6521 const u32 rn_val = state->Reg[rn_idx];
6522 u32 rm_val = state->Reg[rm_idx];
6523
6524 if (do_swap)
6525 rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
6526
6527 const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF);
6528 const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF);
6529 s64 result;
6530
6531 // SMLALD
6532 if (BIT(6) == 0) {
6533 result = (product1 + product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
6534 }
6535 // SMLSLD
6536 else {
6537 result = (product1 - product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
6045 } 6538 }
6046 break;
6047 }
6048
6049 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF);
6050 if (Rm & 0x80)
6051 Rm |= 0xffffff00;
6052
6053 if (BITS (16, 19) == 0xf)
6054 /* SXTB */
6055 state->Reg[BITS (12, 15)] = Rm;
6056 else
6057 /* SXTAB */
6058 state->Reg[BITS (12, 15)] += Rm;
6059 }
6060 return 1;
6061
6062 case 0x6b: {
6063 ARMword Rm;
6064 int ror = -1;
6065
6066 switch (BITS (4, 11)) {
6067 case 0x07:
6068 ror = 0;
6069 break;
6070 case 0x47:
6071 ror = 8;
6072 break;
6073 case 0x87:
6074 ror = 16;
6075 break;
6076 case 0xc7:
6077 ror = 24;
6078 break;
6079 6539
6080 case 0xf3: 6540 state->Reg[rdlo_idx] = (result & 0xFFFFFFFF);
6081 DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24); 6541 state->Reg[rdhi_idx] = ((result >> 32) & 0xFFFFFFFF);
6082 return 1; 6542 return 1;
6083 case 0xfb:
6084 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8);
6085 return 1;
6086 default:
6087 break;
6088 } 6543 }
6544 break;
6545 case 0x75: // SMMLA, SMMUL, and SMMLS
6546 {
6547 const u8 rm_idx = BITS(8, 11);
6548 const u8 rn_idx = BITS(0, 3);
6549 const u8 ra_idx = BITS(12, 15);
6550 const u8 rd_idx = BITS(16, 19);
6551 const bool do_round = (BIT(5) == 1);
6089 6552
6090 if (ror == -1) 6553 const u32 rm_val = state->Reg[rm_idx];
6091 break; 6554 const u32 rn_val = state->Reg[rn_idx];
6092 6555
6093 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF); 6556 // Assume SMMUL by default.
6094 if (Rm & 0x8000) 6557 s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val;
6095 Rm |= 0xffff0000;
6096 6558
6097 if (BITS (16, 19) == 0xf) 6559 if (ra_idx != 15) {
6098 /* SXTH */ 6560 const u32 ra_val = state->Reg[ra_idx];
6099 state->Reg[BITS (12, 15)] = Rm;
6100 else
6101 /* SXTAH */
6102 state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm;
6103 }
6104 return 1;
6105 6561
6106 case 0x6e: { 6562 // SMMLA, otherwise SMMLS
6107 ARMword Rm; 6563 if (BIT(6) == 0)
6108 int ror = -1; 6564 result += ((s64)ra_val << 32);
6565 else
6566 result = ((s64)ra_val << 32) - result;
6567 }
6109 6568
6110 switch (BITS (4, 11)) { 6569 if (do_round)
6111 case 0x07: 6570 result += 0x80000000;
6112 ror = 0;
6113 break;
6114 case 0x47:
6115 ror = 8;
6116 break;
6117 case 0x87:
6118 ror = 16;
6119 break;
6120 case 0xc7:
6121 ror = 24;
6122 break;
6123 6571
6124 case 0x01: 6572 state->Reg[rd_idx] = ((result >> 32) & 0xFFFFFFFF);
6125 case 0xf3:
6126 //ichfly
6127 //USAT16
6128 {
6129 u8 tar = BITS(12, 15);
6130 u8 src = BITS(0, 3);
6131 u8 val = BITS(16, 19);
6132 s16 a1 = (state->Reg[src]);
6133 s16 a2 = (state->Reg[src] >> 0x10);
6134 s16 max = 0xFFFF >> (16 - val);
6135 if (max < a1) a1 = max;
6136 if (max < a2) a2 = max;
6137 u32 temp2 = ((u32)(a2)) << 0x10;
6138 state->Reg[tar] = (a1 & 0xFFFF) | (temp2);
6139 }
6140 return 1; 6573 return 1;
6141 default:
6142 break;
6143 }
6144
6145 if (ror == -1) {
6146 if (BITS (4, 6) == 0x7) {
6147 printf ("Unhandled v6 insn: usat\n");
6148 return 0;
6149 }
6150 break;
6151 } 6574 }
6575 break;
6576 case 0x78:
6577 if (BITS(20, 24) == 0x18)
6578 {
6579 const u8 rm_idx = BITS(8, 11);
6580 const u8 rn_idx = BITS(0, 3);
6581 const u8 rd_idx = BITS(16, 19);
6152 6582
6153 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF); 6583 const u32 rm_val = state->Reg[rm_idx];
6154 6584 const u32 rn_val = state->Reg[rn_idx];
6155 if (BITS (16, 19) == 0xf)
6156 /* UXTB */
6157 state->Reg[BITS (12, 15)] = Rm;
6158 else
6159 /* UXTAB */
6160 state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm;
6161 }
6162 return 1;
6163 6585
6164 case 0x6f: { 6586 const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF);
6165 ARMword Rm; 6587 const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF);
6166 int ror = -1; 6588 const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF);
6589 const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF);
6167 6590
6168 switch (BITS (4, 11)) { 6591 u32 finalDif = (diff1 + diff2 + diff3 + diff4);
6169 case 0x07:
6170 ror = 0;
6171 break;
6172 case 0x47:
6173 ror = 8;
6174 break;
6175 case 0x87:
6176 ror = 16;
6177 break;
6178 case 0xc7:
6179 ror = 24;
6180 break;
6181 6592
6182 case 0xfb: 6593 // Op is USADA8 if true.
6183 printf ("Unhandled v6 insn: revsh\n"); 6594 const u8 ra_idx = BITS(12, 15);
6184 return 0; 6595 if (ra_idx != 15)
6185 default: 6596 finalDif += state->Reg[ra_idx];
6186 break;
6187 }
6188 6597
6189 if (ror == -1) 6598 state->Reg[rd_idx] = finalDif;
6190 break; 6599 return 1;
6191
6192 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF);
6193
6194 /* UXT */
6195 /* state->Reg[BITS (12, 15)] = Rm; */
6196 /* dyf add */
6197 if (BITS (16, 19) == 0xf) {
6198 state->Reg[BITS (12, 15)] = (Rm >> (8 * BITS(10, 11))) & 0x0000FFFF;
6199 } else {
6200 /* UXTAH */
6201 /* state->Reg[BITS (12, 15)] = state->Reg [BITS (16, 19)] + Rm; */
6202// printf("rd is %x rn is %x rm is %x rotate is %x\n", state->Reg[BITS (12, 15)], state->Reg[BITS (16, 19)]
6203// , Rm, BITS(10, 11));
6204// printf("icounter is %lld\n", state->NumInstrs);
6205 state->Reg[BITS (12, 15)] = (state->Reg[BITS (16, 19)] >> (8 * (BITS(10, 11)))) + Rm;
6206// printf("rd is %x\n", state->Reg[BITS (12, 15)]);
6207// exit(-1);
6208 } 6600 }
6209 } 6601 break;
6210 return 1; 6602 case 0x7a:
6211 6603 printf ("Unhandled v6 insn: usbfx\n");
6212#if 0 6604 break;
6605 case 0x7c:
6606 printf ("Unhandled v6 insn: bfc/bfi\n");
6607 break;
6213 case 0x84: 6608 case 0x84:
6214 printf ("Unhandled v6 insn: srs\n"); 6609 printf ("Unhandled v6 insn: srs\n");
6215 break; 6610 break;
6216#endif
6217 default: 6611 default:
6218 break; 6612 break;
6219 } 6613 }
6220 printf("Unhandled v6 insn: UNKNOWN: %08x %08X\n", instr, BITS(20, 27)); 6614 printf("Unhandled v6 insn: UNKNOWN: %08x %08X\n", instr, BITS(20, 27));
6221 return 0; 6615 return 0;
6222 } 6616 } \ No newline at end of file
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
index 2568b93ef..426b67831 100644
--- a/src/core/arm/interpreter/armsupp.cpp
+++ b/src/core/arm/interpreter/armsupp.cpp
@@ -227,8 +227,9 @@ ARMul_CPSRAltered (ARMul_State * state)
227 //state->Cpsr &= ~CBIT; 227 //state->Cpsr &= ~CBIT;
228 ASSIGNV ((state->Cpsr & VBIT) != 0); 228 ASSIGNV ((state->Cpsr & VBIT) != 0);
229 //state->Cpsr &= ~VBIT; 229 //state->Cpsr &= ~VBIT;
230 ASSIGNS ((state->Cpsr & SBIT) != 0); 230 ASSIGNQ ((state->Cpsr & QBIT) != 0);
231 //state->Cpsr &= ~SBIT; 231 //state->Cpsr &= ~QBIT;
232 state->GEFlag = (state->Cpsr & 0x000F0000);
232#ifdef MODET 233#ifdef MODET
233 ASSIGNT ((state->Cpsr & TBIT) != 0); 234 ASSIGNT ((state->Cpsr & TBIT) != 0);
234 //state->Cpsr &= ~TBIT; 235 //state->Cpsr &= ~TBIT;
@@ -391,6 +392,15 @@ ARMul_NthReg (ARMword instr, unsigned number)
391 return (bit - 1); 392 return (bit - 1);
392} 393}
393 394
395/* Unsigned sum of absolute difference */
396u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right)
397{
398 if (left > right)
399 return left - right;
400
401 return right - left;
402}
403
394/* Assigns the N and Z flags depending on the value of result. */ 404/* Assigns the N and Z flags depending on the value of result. */
395 405
396void 406void
@@ -443,6 +453,14 @@ ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
443 ASSIGNV (AddOverflow (a, b, result)); 453 ASSIGNV (AddOverflow (a, b, result));
444} 454}
445 455
456/* Assigns the Q flag if the given result is considered an overflow from the addition of a and b */
457void ARMul_AddOverflowQ(ARMul_State* state, ARMword a, ARMword b)
458{
459 u32 result = a + b;
460 if (((result ^ a) & (u32)0x80000000) && ((a ^ b) & (u32)0x80000000) == 0)
461 SETQ;
462}
463
446/* Assigns the C flag after an subtraction of a and b to give result. */ 464/* Assigns the C flag after an subtraction of a and b to give result. */
447 465
448void 466void
@@ -460,6 +478,142 @@ ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
460 ASSIGNV (SubOverflow (a, b, result)); 478 ASSIGNV (SubOverflow (a, b, result));
461} 479}
462 480
481/* 8-bit signed saturated addition */
482u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right)
483{
484 u8 result = left + right;
485
486 if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) == 0) {
487 if (left & 0x80)
488 result = 0x80;
489 else
490 result = 0x7F;
491 }
492
493 return result;
494}
495
496/* 8-bit signed saturated subtraction */
497u8 ARMul_SignedSaturatedSub8(u8 left, u8 right)
498{
499 u8 result = left - right;
500
501 if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) != 0) {
502 if (left & 0x80)
503 result = 0x80;
504 else
505 result = 0x7F;
506 }
507
508 return result;
509}
510
511/* 16-bit signed saturated addition */
512u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right)
513{
514 u16 result = left + right;
515
516 if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) == 0) {
517 if (left & 0x8000)
518 result = 0x8000;
519 else
520 result = 0x7FFF;
521 }
522
523 return result;
524}
525
526/* 16-bit signed saturated subtraction */
527u16 ARMul_SignedSaturatedSub16(u16 left, u16 right)
528{
529 u16 result = left - right;
530
531 if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) != 0) {
532 if (left & 0x8000)
533 result = 0x8000;
534 else
535 result = 0x7FFF;
536 }
537
538 return result;
539}
540
541/* 8-bit unsigned saturated addition */
542u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right)
543{
544 u8 result = left + right;
545
546 if (result < left)
547 result = 0xFF;
548
549 return result;
550}
551
552/* 16-bit unsigned saturated addition */
553u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right)
554{
555 u16 result = left + right;
556
557 if (result < left)
558 result = 0xFFFF;
559
560 return result;
561}
562
563/* 8-bit unsigned saturated subtraction */
564u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right)
565{
566 if (left <= right)
567 return 0;
568
569 return left - right;
570}
571
572/* 16-bit unsigned saturated subtraction */
573u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right)
574{
575 if (left <= right)
576 return 0;
577
578 return left - right;
579}
580
581// Signed saturation.
582u32 ARMul_SignedSatQ(s32 value, u8 shift, bool* saturation_occurred)
583{
584 const u32 max = (1 << shift) - 1;
585 const s32 top = (value >> shift);
586
587 if (top > 0) {
588 *saturation_occurred = true;
589 return max;
590 }
591 else if (top < -1) {
592 *saturation_occurred = true;
593 return ~max;
594 }
595
596 *saturation_occurred = false;
597 return (u32)value;
598}
599
600// Unsigned saturation
601u32 ARMul_UnsignedSatQ(s32 value, u8 shift, bool* saturation_occurred)
602{
603 const u32 max = (1 << shift) - 1;
604
605 if (value < 0) {
606 *saturation_occurred = true;
607 return 0;
608 } else if ((u32)value > max) {
609 *saturation_occurred = true;
610 return max;
611 }
612
613 *saturation_occurred = false;
614 return (u32)value;
615}
616
463/* This function does the work of generating the addresses used in an 617/* This function does the work of generating the addresses used in an
464 LDC instruction. The code here is always post-indexed, it's up to the 618 LDC instruction. The code here is always post-indexed, it's up to the
465 caller to get the input address correct and to handle base register 619 caller to get the input address correct and to handle base register
@@ -665,7 +819,7 @@ ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
665 //if (!CP_ACCESS_ALLOWED (state, CPNum)) { 819 //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
666 if (!state->MCR[CPNum]) { 820 if (!state->MCR[CPNum]) {
667 //chy 2004-07-19 should fix in the future ????!!!! 821 //chy 2004-07-19 should fix in the future ????!!!!
668 DEBUG("SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr CPnum is %x, source %x\n",CPNum, source); 822 LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr CPnum is %x, source %x",CPNum, source);
669 ARMul_UndefInstr (state, instr); 823 ARMul_UndefInstr (state, instr);
670 return; 824 return;
671 } 825 }
@@ -690,7 +844,7 @@ ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
690 } 844 }
691 845
692 if (cpab == ARMul_CANT) { 846 if (cpab == ARMul_CANT) {
693 DEBUG("SKYEYE ARMul_MCR, CANT, UndefinedInstr %x CPnum is %x, source %x\n", instr, CPNum, source); //ichfly todo 847 LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MCR, CANT, UndefinedInstr %x CPnum is %x, source %x", instr, CPNum, source); //ichfly todo
694 //ARMul_Abort (state, ARMul_UndefinedInstrV); 848 //ARMul_Abort (state, ARMul_UndefinedInstrV);
695 } else { 849 } else {
696 BUSUSEDINCPCN; 850 BUSUSEDINCPCN;
@@ -762,7 +916,7 @@ ARMword ARMul_MRC (ARMul_State * state, ARMword instr)
762 //if (!CP_ACCESS_ALLOWED (state, CPNum)) { 916 //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
763 if (!state->MRC[CPNum]) { 917 if (!state->MRC[CPNum]) {
764 //chy 2004-07-19 should fix in the future????!!!! 918 //chy 2004-07-19 should fix in the future????!!!!
765 DEBUG("SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr CPnum is %x, instr %x\n", CPNum, instr); 919 LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr CPnum is %x, instr %x", CPNum, instr);
766 ARMul_UndefInstr (state, instr); 920 ARMul_UndefInstr (state, instr);
767 return -1; 921 return -1;
768 } 922 }
@@ -865,7 +1019,7 @@ void
865ARMul_UndefInstr (ARMul_State * state, ARMword instr) 1019ARMul_UndefInstr (ARMul_State * state, ARMword instr)
866{ 1020{
867 std::string disasm = ARM_Disasm::Disassemble(state->pc, instr); 1021 std::string disasm = ARM_Disasm::Disassemble(state->pc, instr);
868 ERROR_LOG(ARM11, "Undefined instruction!! Disasm: %s Opcode: 0x%x", disasm.c_str(), instr); 1022 LOG_ERROR(Core_ARM11, "Undefined instruction!! Disasm: %s Opcode: 0x%x", disasm.c_str(), instr);
869 ARMul_Abort (state, ARMul_UndefinedInstrV); 1023 ARMul_Abort (state, ARMul_UndefinedInstrV);
870} 1024}
871 1025
diff --git a/src/core/arm/interpreter/thumbemu.cpp b/src/core/arm/interpreter/thumbemu.cpp
index f7f11f714..9cf80672d 100644
--- a/src/core/arm/interpreter/thumbemu.cpp
+++ b/src/core/arm/interpreter/thumbemu.cpp
@@ -467,7 +467,7 @@ ARMul_ThumbDecode (
467 (state->Reg[14] + ((tinstr & 0x07FF) << 1)) & 0xFFFFFFFC; 467 (state->Reg[14] + ((tinstr & 0x07FF) << 1)) & 0xFFFFFFFC;
468 state->Reg[14] = (tmp | 1); 468 state->Reg[14] = (tmp | 1);
469 CLEART; 469 CLEART;
470 DEBUG_LOG(ARM11, "In %s, After BLX(1),LR=0x%x,PC=0x%x, offset=0x%x\n", __FUNCTION__, state->Reg[14], state->Reg[15], (tinstr &0x7FF) << 1); 470 LOG_DEBUG(Core_ARM11, "After BLX(1),LR=0x%x,PC=0x%x, offset=0x%x", state->Reg[14], state->Reg[15], (tinstr &0x7FF) << 1);
471 valid = t_branch; 471 valid = t_branch;
472 FLUSHPIPE; 472 FLUSHPIPE;
473 } 473 }
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h
index 8343aaa01..8611d7392 100644
--- a/src/core/arm/skyeye_common/armdefs.h
+++ b/src/core/arm/skyeye_common/armdefs.h
@@ -18,38 +18,26 @@
18#ifndef _ARMDEFS_H_ 18#ifndef _ARMDEFS_H_
19#define _ARMDEFS_H_ 19#define _ARMDEFS_H_
20 20
21#include <stdio.h> 21#include <cerrno>
22#include <stdlib.h> 22#include <csignal>
23#include <errno.h> 23#include <cstdio>
24 24#include <cstdlib>
25#include "common/platform.h" 25#include <cstring>
26 26#include <fcntl.h>
27//teawater add for arm2x86 2005.02.14------------------------------------------- 27#include <sys/stat.h>
28// koodailar remove it for mingw 2005.12.18---------------- 28#include <sys/types.h>
29//anthonylee modify it for portable 2007.01.30
30//#include "portable/mman.h"
31 29
32#include "arm_regformat.h" 30#include "arm_regformat.h"
31#include "common/common_types.h"
33#include "common/platform.h" 32#include "common/platform.h"
33#include "core/arm/skyeye_common/armmmu.h"
34#include "core/arm/skyeye_common/skyeye_defs.h" 34#include "core/arm/skyeye_common/skyeye_defs.h"
35 35
36//AJ2D--------------------------------------------------------------------------
37
38//teawater add for arm2x86 2005.07.03-------------------------------------------
39
40#include <sys/types.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44#if EMU_PLATFORM == PLATFORM_LINUX 36#if EMU_PLATFORM == PLATFORM_LINUX
37#include <sys/time.h>
45#include <unistd.h> 38#include <unistd.h>
46#endif 39#endif
47#include <errno.h>
48#include <sys/stat.h>
49#include <fcntl.h>
50 40
51//#include <memory_space.h>
52//AJ2D--------------------------------------------------------------------------
53#if 0 41#if 0
54#if 0 42#if 0
55#define DIFF_STATE 1 43#define DIFF_STATE 1
@@ -70,25 +58,8 @@
70#define LOWHIGH 1 58#define LOWHIGH 1
71#define HIGHLOW 2 59#define HIGHLOW 2
72 60
73//teawater add DBCT_TEST_SPEED 2005.10.04---------------------------------------
74#include <signal.h>
75
76#include "common/platform.h"
77
78#if EMU_PLATFORM == PLATFORM_LINUX
79#include <sys/time.h>
80#endif
81
82//#define DBCT_TEST_SPEED 61//#define DBCT_TEST_SPEED
83#define DBCT_TEST_SPEED_SEC 10 62#define DBCT_TEST_SPEED_SEC 10
84//AJ2D--------------------------------------------------------------------------
85
86//teawater add compile switch for DBCT GDB RSP function 2005.10.21--------------
87//#define DBCT_GDBRSP
88//AJ2D--------------------------------------------------------------------------
89
90//#include <skyeye_defs.h>
91//#include <skyeye_types.h>
92 63
93#define ARM_BYTE_TYPE 0 64#define ARM_BYTE_TYPE 0
94#define ARM_HALFWORD_TYPE 1 65#define ARM_HALFWORD_TYPE 1
@@ -103,71 +74,34 @@
103typedef char *VoidStar; 74typedef char *VoidStar;
104#endif 75#endif
105 76
106typedef unsigned long long ARMdword; /* must be 64 bits wide */ 77typedef u64 ARMdword; // must be 64 bits wide
107typedef unsigned int ARMword; /* must be 32 bits wide */ 78typedef u32 ARMword; // must be 32 bits wide
108typedef unsigned char ARMbyte; /* must be 8 bits wide */ 79typedef u16 ARMhword; // must be 16 bits wide
109typedef unsigned short ARMhword; /* must be 16 bits wide */ 80typedef u8 ARMbyte; // must be 8 bits wide
110typedef struct ARMul_State ARMul_State; 81typedef struct ARMul_State ARMul_State;
111typedef struct ARMul_io ARMul_io; 82typedef struct ARMul_io ARMul_io;
112typedef struct ARMul_Energy ARMul_Energy; 83typedef struct ARMul_Energy ARMul_Energy;
113 84
114//teawater add for arm2x86 2005.06.24-------------------------------------------
115#include <stdint.h>
116//AJ2D--------------------------------------------------------------------------
117/*
118//chy 2005-05-11
119#ifndef __CYGWIN__
120//teawater add for arm2x86 2005.02.14-------------------------------------------
121typedef unsigned char uint8_t;
122typedef unsigned short uint16_t;
123typedef unsigned int u32;
124#if defined (__x86_64__)
125typedef unsigned long uint64_t;
126#else
127typedef unsigned long long uint64_t;
128#endif
129////AJ2D--------------------------------------------------------------------------
130#endif
131*/
132 85
133#include "core/arm/skyeye_common/armmmu.h" 86typedef unsigned ARMul_CPInits(ARMul_State* state);
134//#include "lcd/skyeye_lcd.h" 87typedef unsigned ARMul_CPExits(ARMul_State* state);
135 88typedef unsigned ARMul_LDCs(ARMul_State* state, unsigned type, ARMword instr, ARMword value);
136 89typedef unsigned ARMul_STCs(ARMul_State* state, unsigned type, ARMword instr, ARMword* value);
137//#include "skyeye.h" 90typedef unsigned ARMul_MRCs(ARMul_State* state, unsigned type, ARMword instr, ARMword* value);
138//#include "skyeye_device.h" 91typedef unsigned ARMul_MCRs(ARMul_State* state, unsigned type, ARMword instr, ARMword value);
139//#include "net/skyeye_net.h" 92typedef unsigned ARMul_MRRCs(ARMul_State* state, unsigned type, ARMword instr, ARMword* value1, ARMword* value2);
140//#include "skyeye_config.h" 93typedef unsigned ARMul_MCRRs(ARMul_State* state, unsigned type, ARMword instr, ARMword value1, ARMword value2);
141 94typedef unsigned ARMul_CDPs(ARMul_State* state, unsigned type, ARMword instr);
142 95typedef unsigned ARMul_CPReads(ARMul_State* state, unsigned reg, ARMword* value);
143typedef unsigned ARMul_CPInits (ARMul_State * state); 96typedef unsigned ARMul_CPWrites(ARMul_State* state, unsigned reg, ARMword value);
144typedef unsigned ARMul_CPExits (ARMul_State * state);
145typedef unsigned ARMul_LDCs (ARMul_State * state, unsigned type,
146 ARMword instr, ARMword value);
147typedef unsigned ARMul_STCs (ARMul_State * state, unsigned type,
148 ARMword instr, ARMword * value);
149typedef unsigned ARMul_MRCs (ARMul_State * state, unsigned type,
150 ARMword instr, ARMword * value);
151typedef unsigned ARMul_MCRs (ARMul_State * state, unsigned type,
152 ARMword instr, ARMword value);
153typedef unsigned ARMul_MRRCs (ARMul_State * state, unsigned type,
154 ARMword instr, ARMword * value1, ARMword * value2);
155typedef unsigned ARMul_MCRRs (ARMul_State * state, unsigned type,
156 ARMword instr, ARMword value1, ARMword value2);
157typedef unsigned ARMul_CDPs (ARMul_State * state, unsigned type,
158 ARMword instr);
159typedef unsigned ARMul_CPReads (ARMul_State * state, unsigned reg,
160 ARMword * value);
161typedef unsigned ARMul_CPWrites (ARMul_State * state, unsigned reg,
162 ARMword value);
163 97
164 98
165//added by ksh,2004-3-5 99//added by ksh,2004-3-5
166struct ARMul_io 100struct ARMul_io
167{ 101{
168 ARMword *instr; //to display the current interrupt state 102 ARMword *instr; // to display the current interrupt state
169 ARMword *net_flag; //to judge if network is enabled 103 ARMword *net_flag; // to judge if network is enabled
170 ARMword *net_int; //netcard interrupt 104 ARMword *net_int; // netcard interrupt
171 105
172 //ywc,2004-04-01 106 //ywc,2004-04-01
173 ARMword *ts_int; 107 ARMword *ts_int;
@@ -180,17 +114,17 @@ struct ARMul_io
180/* added by ksh,2004-11-26,some energy profiling */ 114/* added by ksh,2004-11-26,some energy profiling */
181struct ARMul_Energy 115struct ARMul_Energy
182{ 116{
183 int energy_prof; /* <tktan> BUG200103282109 : for energy profiling */ 117 int energy_prof; /* <tktan> BUG200103282109 : for energy profiling */
184 int enable_func_energy; /* <tktan> BUG200105181702 */ 118 int enable_func_energy; /* <tktan> BUG200105181702 */
185 char *func_energy; 119 char *func_energy;
186 int func_display; /* <tktan> BUG200103311509 : for function call display */ 120 int func_display; /* <tktan> BUG200103311509 : for function call display */
187 int func_disp_start; /* <tktan> BUG200104191428 : to start func profiling */ 121 int func_disp_start; /* <tktan> BUG200104191428 : to start func profiling */
188 char *start_func; /* <tktan> BUG200104191428 */ 122 char *start_func; /* <tktan> BUG200104191428 */
189 123
190 FILE *outfile; /* <tktan> BUG200105201531 : direct console to file */ 124 FILE *outfile; /* <tktan> BUG200105201531 : direct console to file */
191 long long tcycle, pcycle; 125 long long tcycle, pcycle;
192 float t_energy; 126 float t_energy;
193 void *cur_task; /* <tktan> BUG200103291737 */ 127 void *cur_task; /* <tktan> BUG200103291737 */
194 long long t_mem_cycle, t_idle_cycle, t_uart_cycle; 128 long long t_mem_cycle, t_idle_cycle, t_uart_cycle;
195 long long p_mem_cycle, p_idle_cycle, p_uart_cycle; 129 long long p_mem_cycle, p_idle_cycle, p_uart_cycle;
196 long long p_io_update_tcycle; 130 long long p_io_update_tcycle;
@@ -203,13 +137,12 @@ struct ARMul_Energy
203 137
204typedef struct mem_bank 138typedef struct mem_bank
205{ 139{
206 ARMword (*read_byte) (ARMul_State * state, ARMword addr); 140 ARMword (*read_byte) (ARMul_State* state, ARMword addr);
207 void (*write_byte) (ARMul_State * state, ARMword addr, ARMword data); 141 void (*write_byte) (ARMul_State* state, ARMword addr, ARMword data);
208 ARMword (*read_halfword) (ARMul_State * state, ARMword addr); 142 ARMword (*read_halfword) (ARMul_State* state, ARMword addr);
209 void (*write_halfword) (ARMul_State * state, ARMword addr, 143 void (*write_halfword) (ARMul_State* state, ARMword addr, ARMword data);
210 ARMword data); 144 ARMword (*read_word) (ARMul_State* state, ARMword addr);
211 ARMword (*read_word) (ARMul_State * state, ARMword addr); 145 void (*write_word) (ARMul_State* state, ARMword addr, ARMword data);
212 void (*write_word) (ARMul_State * state, ARMword addr, ARMword data);
213 unsigned int addr, len; 146 unsigned int addr, len;
214 char filename[MAX_STR]; 147 char filename[MAX_STR];
215 unsigned type; //chy 2003-09-21: maybe io,ram,rom 148 unsigned type; //chy 2003-09-21: maybe io,ram,rom
@@ -224,24 +157,24 @@ typedef struct
224#define VFP_REG_NUM 64 157#define VFP_REG_NUM 64
225struct ARMul_State 158struct ARMul_State
226{ 159{
227 ARMword Emulate; /* to start and stop emulation */ 160 ARMword Emulate; /* to start and stop emulation */
228 unsigned EndCondition; /* reason for stopping */ 161 unsigned EndCondition; /* reason for stopping */
229 unsigned ErrorCode; /* type of illegal instruction */ 162 unsigned ErrorCode; /* type of illegal instruction */
230 163
231 /* Order of the following register should not be modified */ 164 /* Order of the following register should not be modified */
232 ARMword Reg[16]; /* the current register file */ 165 ARMword Reg[16]; /* the current register file */
233 ARMword Cpsr; /* the current psr */ 166 ARMword Cpsr; /* the current psr */
234 ARMword Spsr_copy; 167 ARMword Spsr_copy;
235 ARMword phys_pc; 168 ARMword phys_pc;
236 ARMword Reg_usr[2]; 169 ARMword Reg_usr[2];
237 ARMword Reg_svc[2]; /* R13_SVC R14_SVC */ 170 ARMword Reg_svc[2]; /* R13_SVC R14_SVC */
238 ARMword Reg_abort[2]; /* R13_ABORT R14_ABORT */ 171 ARMword Reg_abort[2]; /* R13_ABORT R14_ABORT */
239 ARMword Reg_undef[2]; /* R13 UNDEF R14 UNDEF */ 172 ARMword Reg_undef[2]; /* R13 UNDEF R14 UNDEF */
240 ARMword Reg_irq[2]; /* R13_IRQ R14_IRQ */ 173 ARMword Reg_irq[2]; /* R13_IRQ R14_IRQ */
241 ARMword Reg_firq[7]; /* R8---R14 FIRQ */ 174 ARMword Reg_firq[7]; /* R8---R14 FIRQ */
242 ARMword Spsr[7]; /* the exception psr's */ 175 ARMword Spsr[7]; /* the exception psr's */
243 ARMword Mode; /* the current mode */ 176 ARMword Mode; /* the current mode */
244 ARMword Bank; /* the current register bank */ 177 ARMword Bank; /* the current register bank */
245 ARMword exclusive_tag; 178 ARMword exclusive_tag;
246 ARMword exclusive_state; 179 ARMword exclusive_state;
247 ARMword exclusive_result; 180 ARMword exclusive_result;
@@ -265,7 +198,7 @@ struct ARMul_State
265 //ARMword translate_pc; 198 //ARMword translate_pc;
266 199
267 /* add armv6 flags dyf:2010-08-09 */ 200 /* add armv6 flags dyf:2010-08-09 */
268 ARMword GEFlag, EFlag, AFlag, QFlags; 201 ARMword GEFlag, EFlag, AFlag, QFlag;
269 //chy:2003-08-19, used in arm v5e|xscale 202 //chy:2003-08-19, used in arm v5e|xscale
270 ARMword SFlag; 203 ARMword SFlag;
271#ifdef MODET 204#ifdef MODET
@@ -281,38 +214,39 @@ struct ARMul_State
281 214
282 ARMword currentexaddr; 215 ARMword currentexaddr;
283 ARMword currentexval; 216 ARMword currentexval;
217 ARMword currentexvald;
284 ARMword servaddr; 218 ARMword servaddr;
285 219
286 unsigned NextInstr; 220 unsigned NextInstr;
287 unsigned VectorCatch; /* caught exception mask */ 221 unsigned VectorCatch; /* caught exception mask */
288 unsigned CallDebug; /* set to call the debugger */ 222 unsigned CallDebug; /* set to call the debugger */
289 unsigned CanWatch; /* set by memory interface if its willing to suffer the 223 unsigned CanWatch; /* set by memory interface if its willing to suffer the
290 overhead of checking for watchpoints on each memory 224 overhead of checking for watchpoints on each memory
291 access */ 225 access */
292 unsigned int StopHandle; 226 unsigned int StopHandle;
293 227
294 char *CommandLine; /* Command Line from ARMsd */ 228 char *CommandLine; /* Command Line from ARMsd */
295 229
296 ARMul_CPInits *CPInit[16]; /* coprocessor initialisers */ 230 ARMul_CPInits *CPInit[16]; /* coprocessor initialisers */
297 ARMul_CPExits *CPExit[16]; /* coprocessor finalisers */ 231 ARMul_CPExits *CPExit[16]; /* coprocessor finalisers */
298 ARMul_LDCs *LDC[16]; /* LDC instruction */ 232 ARMul_LDCs *LDC[16]; /* LDC instruction */
299 ARMul_STCs *STC[16]; /* STC instruction */ 233 ARMul_STCs *STC[16]; /* STC instruction */
300 ARMul_MRCs *MRC[16]; /* MRC instruction */ 234 ARMul_MRCs *MRC[16]; /* MRC instruction */
301 ARMul_MCRs *MCR[16]; /* MCR instruction */ 235 ARMul_MCRs *MCR[16]; /* MCR instruction */
302 ARMul_MRRCs *MRRC[16]; /* MRRC instruction */ 236 ARMul_MRRCs *MRRC[16]; /* MRRC instruction */
303 ARMul_MCRRs *MCRR[16]; /* MCRR instruction */ 237 ARMul_MCRRs *MCRR[16]; /* MCRR instruction */
304 ARMul_CDPs *CDP[16]; /* CDP instruction */ 238 ARMul_CDPs *CDP[16]; /* CDP instruction */
305 ARMul_CPReads *CPRead[16]; /* Read CP register */ 239 ARMul_CPReads *CPRead[16]; /* Read CP register */
306 ARMul_CPWrites *CPWrite[16]; /* Write CP register */ 240 ARMul_CPWrites *CPWrite[16]; /* Write CP register */
307 unsigned char *CPData[16]; /* Coprocessor data */ 241 unsigned char *CPData[16]; /* Coprocessor data */
308 unsigned char const *CPRegWords[16]; /* map of coprocessor register sizes */ 242 unsigned char const *CPRegWords[16]; /* map of coprocessor register sizes */
309 243
310 unsigned EventSet; /* the number of events in the queue */ 244 unsigned EventSet; /* the number of events in the queue */
311 unsigned int Now; /* time to the nearest cycle */ 245 unsigned int Now; /* time to the nearest cycle */
312 struct EventNode **EventPtr; /* the event list */ 246 struct EventNode **EventPtr; /* the event list */
313 247
314 unsigned Debug; /* show instructions as they are executed */ 248 unsigned Debug; /* show instructions as they are executed */
315 unsigned NresetSig; /* reset the processor */ 249 unsigned NresetSig; /* reset the processor */
316 unsigned NfiqSig; 250 unsigned NfiqSig;
317 unsigned NirqSig; 251 unsigned NirqSig;
318 252
@@ -356,12 +290,12 @@ So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model)
356*/ 290*/
357 unsigned lateabtSig; 291 unsigned lateabtSig;
358 292
359 ARMword Vector; /* synthesize aborts in cycle modes */ 293 ARMword Vector; /* synthesize aborts in cycle modes */
360 ARMword Aborted; /* sticky flag for aborts */ 294 ARMword Aborted; /* sticky flag for aborts */
361 ARMword Reseted; /* sticky flag for Reset */ 295 ARMword Reseted; /* sticky flag for Reset */
362 ARMword Inted, LastInted; /* sticky flags for interrupts */ 296 ARMword Inted, LastInted; /* sticky flags for interrupts */
363 ARMword Base; /* extra hand for base writeback */ 297 ARMword Base; /* extra hand for base writeback */
364 ARMword AbortAddr; /* to keep track of Prefetch aborts */ 298 ARMword AbortAddr; /* to keep track of Prefetch aborts */
365 299
366 const struct Dbg_HostosInterface *hostif; 300 const struct Dbg_HostosInterface *hostif;
367 301
@@ -378,7 +312,7 @@ So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model)
378 //chy: 2003-08-11, for different arm core type 312 //chy: 2003-08-11, for different arm core type
379 unsigned is_v4; /* Are we emulating a v4 architecture (or higher) ? */ 313 unsigned is_v4; /* Are we emulating a v4 architecture (or higher) ? */
380 unsigned is_v5; /* Are we emulating a v5 architecture ? */ 314 unsigned is_v5; /* Are we emulating a v5 architecture ? */
381 unsigned is_v5e; /* Are we emulating a v5e architecture ? */ 315 unsigned is_v5e; /* Are we emulating a v5e architecture ? */
382 unsigned is_v6; /* Are we emulating a v6 architecture ? */ 316 unsigned is_v6; /* Are we emulating a v6 architecture ? */
383 unsigned is_v7; /* Are we emulating a v7 architecture ? */ 317 unsigned is_v7; /* Are we emulating a v7 architecture ? */
384 unsigned is_XScale; /* Are we emulating an XScale architecture ? */ 318 unsigned is_XScale; /* Are we emulating an XScale architecture ? */
@@ -387,51 +321,43 @@ So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model)
387 //chy 2005-09-19 321 //chy 2005-09-19
388 unsigned is_pxa27x; /* Are we emulating a Intel PXA27x co-processor ? */ 322 unsigned is_pxa27x; /* Are we emulating a Intel PXA27x co-processor ? */
389 //chy: seems only used in xscale's CP14 323 //chy: seems only used in xscale's CP14
390 unsigned int LastTime; /* Value of last call to ARMul_Time() */ 324 unsigned int LastTime; /* Value of last call to ARMul_Time() */
391 ARMword CP14R0_CCD; /* used to count 64 clock cycles with CP14 R0 bit 3 set */ 325 ARMword CP14R0_CCD; /* used to count 64 clock cycles with CP14 R0 bit 3 set */
392 326
393 327
394//added by ksh:for handle different machs io 2004-3-5 328 //added by ksh:for handle different machs io 2004-3-5
395 ARMul_io mach_io; 329 ARMul_io mach_io;
396 330
397/*added by ksh,2004-11-26,some energy profiling*/ 331 /*added by ksh,2004-11-26,some energy profiling*/
398 ARMul_Energy energy; 332 ARMul_Energy energy;
399 333
400//teawater add for next_dis 2004.10.27----------------------- 334 //teawater add for next_dis 2004.10.27-----------------------
401 int disassemble; 335 int disassemble;
402//AJ2D------------------------------------------
403 336
404//teawater add for arm2x86 2005.02.15------------------------------------------- 337
338 //teawater add for arm2x86 2005.02.15-------------------------------------------
405 u32 trap; 339 u32 trap;
406 u32 tea_break_addr; 340 u32 tea_break_addr;
407 u32 tea_break_ok; 341 u32 tea_break_ok;
408 int tea_pc; 342 int tea_pc;
409//AJ2D--------------------------------------------------------------------------
410//teawater add for arm2x86 2005.07.03-------------------------------------------
411
412 /*
413 * 2007-01-24 removed the term-io functions by Anthony Lee,
414 * moved to "device/uart/skyeye_uart_stdio.c".
415 */
416 343
417//AJ2D-------------------------------------------------------------------------- 344 //teawater add for arm2x86 2005.07.05-------------------------------------------
418//teawater add for arm2x86 2005.07.05-------------------------------------------
419 //arm_arm A2-18 345 //arm_arm A2-18
420 int abort_model; //0 Base Restored Abort Model, 1 the Early Abort Model, 2 Base Updated Abort Model 346 int abort_model; //0 Base Restored Abort Model, 1 the Early Abort Model, 2 Base Updated Abort Model
421//AJ2D-------------------------------------------------------------------------- 347
422//teawater change for return if running tb dirty 2005.07.09--------------------- 348 //teawater change for return if running tb dirty 2005.07.09---------------------
423 void *tb_now; 349 void *tb_now;
424//AJ2D--------------------------------------------------------------------------
425 350
426//teawater add for record reg value to ./reg.txt 2005.07.10--------------------- 351
352 //teawater add for record reg value to ./reg.txt 2005.07.10---------------------
427 FILE *tea_reg_fd; 353 FILE *tea_reg_fd;
428//AJ2D--------------------------------------------------------------------------
429 354
430/*added by ksh in 2005-10-1*/ 355
356 /*added by ksh in 2005-10-1*/
431 cpu_config_t *cpu; 357 cpu_config_t *cpu;
432 //mem_config_t *mem_bank; 358 //mem_config_t *mem_bank;
433 359
434/* added LPC remap function */ 360 /* added LPC remap function */
435 int vector_remap_flag; 361 int vector_remap_flag;
436 u32 vector_remap_addr; 362 u32 vector_remap_addr;
437 u32 vector_remap_size; 363 u32 vector_remap_size;
@@ -486,17 +412,14 @@ typedef ARMul_State arm_core_t;
486#define ARM_Debug_Prop 0x10 412#define ARM_Debug_Prop 0x10
487#define ARM_Isync_Prop ARM_Debug_Prop 413#define ARM_Isync_Prop ARM_Debug_Prop
488#define ARM_Lock_Prop 0x20 414#define ARM_Lock_Prop 0x20
489//chy 2003-08-11
490#define ARM_v4_Prop 0x40 415#define ARM_v4_Prop 0x40
491#define ARM_v5_Prop 0x80 416#define ARM_v5_Prop 0x80
492/*jeff.du 2010-08-05 */
493#define ARM_v6_Prop 0xc0 417#define ARM_v6_Prop 0xc0
494 418
495#define ARM_v5e_Prop 0x100 419#define ARM_v5e_Prop 0x100
496#define ARM_XScale_Prop 0x200 420#define ARM_XScale_Prop 0x200
497#define ARM_ep9312_Prop 0x400 421#define ARM_ep9312_Prop 0x400
498#define ARM_iWMMXt_Prop 0x800 422#define ARM_iWMMXt_Prop 0x800
499//chy 2005-09-19
500#define ARM_PXA27X_Prop 0x1000 423#define ARM_PXA27X_Prop 0x1000
501#define ARM_v7_Prop 0x2000 424#define ARM_v7_Prop 0x2000
502 425
@@ -591,47 +514,44 @@ typedef ARMul_State arm_core_t;
591#ifdef __cplusplus 514#ifdef __cplusplus
592extern "C" { 515extern "C" {
593#endif 516#endif
594extern void ARMul_EmulateInit (void); 517extern void ARMul_EmulateInit();
595extern void ARMul_Reset (ARMul_State * state); 518extern void ARMul_Reset(ARMul_State* state);
596#ifdef __cplusplus 519#ifdef __cplusplus
597 } 520 }
598#endif 521#endif
599extern ARMul_State *ARMul_NewState (ARMul_State * state); 522extern ARMul_State *ARMul_NewState(ARMul_State* state);
600extern ARMword ARMul_DoProg (ARMul_State * state); 523extern ARMword ARMul_DoProg(ARMul_State* state);
601extern ARMword ARMul_DoInstr (ARMul_State * state); 524extern ARMword ARMul_DoInstr(ARMul_State* state);
602/***************************************************************************\ 525/***************************************************************************\
603* Definitons of things for event handling * 526* Definitons of things for event handling *
604\***************************************************************************/ 527\***************************************************************************/
605 528
606extern void ARMul_ScheduleEvent (ARMul_State * state, unsigned int delay, 529extern void ARMul_ScheduleEvent(ARMul_State* state, unsigned int delay, unsigned(*func) ());
607 unsigned (*func) ()); 530extern void ARMul_EnvokeEvent(ARMul_State* state);
608extern void ARMul_EnvokeEvent (ARMul_State * state); 531extern unsigned int ARMul_Time(ARMul_State* state);
609extern unsigned int ARMul_Time (ARMul_State * state);
610 532
611/***************************************************************************\ 533/***************************************************************************\
612* Useful support routines * 534* Useful support routines *
613\***************************************************************************/ 535\***************************************************************************/
614 536
615extern ARMword ARMul_GetReg (ARMul_State * state, unsigned mode, 537extern ARMword ARMul_GetReg (ARMul_State* state, unsigned mode, unsigned reg);
616 unsigned reg); 538extern void ARMul_SetReg (ARMul_State* state, unsigned mode, unsigned reg, ARMword value);
617extern void ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, 539extern ARMword ARMul_GetPC(ARMul_State* state);
618 ARMword value); 540extern ARMword ARMul_GetNextPC(ARMul_State* state);
619extern ARMword ARMul_GetPC (ARMul_State * state); 541extern void ARMul_SetPC(ARMul_State* state, ARMword value);
620extern ARMword ARMul_GetNextPC (ARMul_State * state); 542extern ARMword ARMul_GetR15(ARMul_State* state);
621extern void ARMul_SetPC (ARMul_State * state, ARMword value); 543extern void ARMul_SetR15(ARMul_State* state, ARMword value);
622extern ARMword ARMul_GetR15 (ARMul_State * state); 544
623extern void ARMul_SetR15 (ARMul_State * state, ARMword value); 545extern ARMword ARMul_GetCPSR(ARMul_State* state);
624 546extern void ARMul_SetCPSR(ARMul_State* state, ARMword value);
625extern ARMword ARMul_GetCPSR (ARMul_State * state); 547extern ARMword ARMul_GetSPSR(ARMul_State* state, ARMword mode);
626extern void ARMul_SetCPSR (ARMul_State * state, ARMword value); 548extern void ARMul_SetSPSR(ARMul_State* state, ARMword mode, ARMword value);
627extern ARMword ARMul_GetSPSR (ARMul_State * state, ARMword mode);
628extern void ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value);
629 549
630/***************************************************************************\ 550/***************************************************************************\
631* Definitons of things to handle aborts * 551* Definitons of things to handle aborts *
632\***************************************************************************/ 552\***************************************************************************/
633 553
634extern void ARMul_Abort (ARMul_State * state, ARMword address); 554extern void ARMul_Abort(ARMul_State* state, ARMword address);
635#ifdef MODET 555#ifdef MODET
636#define ARMul_ABORTWORD (state->TFlag ? 0xefffdfff : 0xefffffff) /* SWI -1 */ 556#define ARMul_ABORTWORD (state->TFlag ? 0xefffdfff : 0xefffffff) /* SWI -1 */
637#define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \ 557#define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \
@@ -649,54 +569,40 @@ extern void ARMul_Abort (ARMul_State * state, ARMword address);
649* Definitons of things in the memory interface * 569* Definitons of things in the memory interface *
650\***************************************************************************/ 570\***************************************************************************/
651 571
652extern unsigned ARMul_MemoryInit (ARMul_State * state, 572extern unsigned ARMul_MemoryInit(ARMul_State* state, unsigned int initmemsize);
653 unsigned int initmemsize); 573extern void ARMul_MemoryExit(ARMul_State* state);
654extern void ARMul_MemoryExit (ARMul_State * state);
655 574
656extern ARMword ARMul_LoadInstrS (ARMul_State * state, ARMword address, 575extern ARMword ARMul_LoadInstrS(ARMul_State* state, ARMword address, ARMword isize);
657 ARMword isize); 576extern ARMword ARMul_LoadInstrN(ARMul_State* state, ARMword address, ARMword isize);
658extern ARMword ARMul_LoadInstrN (ARMul_State * state, ARMword address,
659 ARMword isize);
660#ifdef __cplusplus 577#ifdef __cplusplus
661extern "C" { 578extern "C" {
662#endif 579#endif
663extern ARMword ARMul_ReLoadInstr (ARMul_State * state, ARMword address, 580extern ARMword ARMul_ReLoadInstr(ARMul_State* state, ARMword address, ARMword isize);
664 ARMword isize);
665#ifdef __cplusplus 581#ifdef __cplusplus
666 } 582 }
667#endif 583#endif
668extern ARMword ARMul_LoadWordS (ARMul_State * state, ARMword address); 584extern ARMword ARMul_LoadWordS(ARMul_State* state, ARMword address);
669extern ARMword ARMul_LoadWordN (ARMul_State * state, ARMword address); 585extern ARMword ARMul_LoadWordN(ARMul_State* state, ARMword address);
670extern ARMword ARMul_LoadHalfWord (ARMul_State * state, ARMword address); 586extern ARMword ARMul_LoadHalfWord(ARMul_State* state, ARMword address);
671extern ARMword ARMul_LoadByte (ARMul_State * state, ARMword address); 587extern ARMword ARMul_LoadByte(ARMul_State* state, ARMword address);
672 588
673extern void ARMul_StoreWordS (ARMul_State * state, ARMword address, 589extern void ARMul_StoreWordS(ARMul_State* state, ARMword address, ARMword data);
674 ARMword data); 590extern void ARMul_StoreWordN(ARMul_State* state, ARMword address, ARMword data);
675extern void ARMul_StoreWordN (ARMul_State * state, ARMword address, 591extern void ARMul_StoreHalfWord(ARMul_State* state, ARMword address, ARMword data);
676 ARMword data); 592extern void ARMul_StoreByte(ARMul_State* state, ARMword address, ARMword data);
677extern void ARMul_StoreHalfWord (ARMul_State * state, ARMword address, 593
678 ARMword data); 594extern ARMword ARMul_SwapWord(ARMul_State* state, ARMword address, ARMword data);
679extern void ARMul_StoreByte (ARMul_State * state, ARMword address, 595extern ARMword ARMul_SwapByte(ARMul_State* state, ARMword address, ARMword data);
680 ARMword data); 596
681 597extern void ARMul_Icycles(ARMul_State* state, unsigned number, ARMword address);
682extern ARMword ARMul_SwapWord (ARMul_State * state, ARMword address, 598extern void ARMul_Ccycles(ARMul_State* state, unsigned number, ARMword address);
683 ARMword data); 599
684extern ARMword ARMul_SwapByte (ARMul_State * state, ARMword address, 600extern ARMword ARMul_ReadWord(ARMul_State* state, ARMword address);
685 ARMword data); 601extern ARMword ARMul_ReadByte(ARMul_State* state, ARMword address);
686 602extern void ARMul_WriteWord(ARMul_State* state, ARMword address, ARMword data);
687extern void ARMul_Icycles (ARMul_State * state, unsigned number, 603extern void ARMul_WriteByte(ARMul_State* state, ARMword address, ARMword data);
688 ARMword address); 604
689extern void ARMul_Ccycles (ARMul_State * state, unsigned number, 605extern ARMword ARMul_MemAccess(ARMul_State* state, ARMword, ARMword,
690 ARMword address);
691
692extern ARMword ARMul_ReadWord (ARMul_State * state, ARMword address);
693extern ARMword ARMul_ReadByte (ARMul_State * state, ARMword address);
694extern void ARMul_WriteWord (ARMul_State * state, ARMword address,
695 ARMword data);
696extern void ARMul_WriteByte (ARMul_State * state, ARMword address,
697 ARMword data);
698
699extern ARMword ARMul_MemAccess (ARMul_State * state, ARMword, ARMword,
700 ARMword, ARMword, ARMword, ARMword, ARMword, 606 ARMword, ARMword, ARMword, ARMword, ARMword,
701 ARMword, ARMword, ARMword); 607 ARMword, ARMword, ARMword);
702 608
@@ -739,66 +645,40 @@ extern ARMword ARMul_MemAccess (ARMul_State * state, ARMword, ARMword,
739#define ARMul_CP15_DBCON_E1 0x000c 645#define ARMul_CP15_DBCON_E1 0x000c
740#define ARMul_CP15_DBCON_E0 0x0003 646#define ARMul_CP15_DBCON_E0 0x0003
741 647
742extern unsigned ARMul_CoProInit (ARMul_State * state); 648extern unsigned ARMul_CoProInit(ARMul_State* state);
743extern void ARMul_CoProExit (ARMul_State * state); 649extern void ARMul_CoProExit(ARMul_State* state);
744extern void ARMul_CoProAttach (ARMul_State * state, unsigned number, 650extern void ARMul_CoProAttach (ARMul_State* state, unsigned number,
745 ARMul_CPInits * init, ARMul_CPExits * exit, 651 ARMul_CPInits* init, ARMul_CPExits* exit,
746 ARMul_LDCs * ldc, ARMul_STCs * stc, 652 ARMul_LDCs* ldc, ARMul_STCs* stc,
747 ARMul_MRCs * mrc, ARMul_MCRs * mcr, 653 ARMul_MRCs* mrc, ARMul_MCRs* mcr,
748 ARMul_MRRCs * mrrc, ARMul_MCRRs * mcrr, 654 ARMul_MRRCs* mrrc, ARMul_MCRRs* mcrr,
749 ARMul_CDPs * cdp, 655 ARMul_CDPs* cdp,
750 ARMul_CPReads * read, ARMul_CPWrites * write); 656 ARMul_CPReads* read, ARMul_CPWrites* write);
751extern void ARMul_CoProDetach (ARMul_State * state, unsigned number); 657extern void ARMul_CoProDetach(ARMul_State* state, unsigned number);
752 658
753/***************************************************************************\ 659/***************************************************************************\
754* Definitons of things in the host environment * 660* Definitons of things in the host environment *
755\***************************************************************************/ 661\***************************************************************************/
756 662
757extern unsigned ARMul_OSInit (ARMul_State * state); 663extern unsigned ARMul_OSInit(ARMul_State* state);
758extern void ARMul_OSExit (ARMul_State * state); 664extern void ARMul_OSExit(ARMul_State* state);
759 665
760#ifdef __cplusplus 666#ifdef __cplusplus
761 extern "C" { 667 extern "C" {
762#endif 668#endif
763 669
764extern unsigned ARMul_OSHandleSWI (ARMul_State * state, ARMword number); 670extern unsigned ARMul_OSHandleSWI(ARMul_State* state, ARMword number);
765#ifdef __cplusplus 671#ifdef __cplusplus
766} 672}
767#endif 673#endif
768 674
769 675
770extern ARMword ARMul_OSLastErrorP (ARMul_State * state); 676extern ARMword ARMul_OSLastErrorP(ARMul_State* state);
771 677
772extern ARMword ARMul_Debug (ARMul_State * state, ARMword pc, ARMword instr); 678extern ARMword ARMul_Debug(ARMul_State* state, ARMword pc, ARMword instr);
773extern unsigned ARMul_OSException (ARMul_State * state, ARMword vector, 679extern unsigned ARMul_OSException(ARMul_State* state, ARMword vector, ARMword pc);
774 ARMword pc);
775extern int rdi_log; 680extern int rdi_log;
776 681
777/***************************************************************************\
778* Host-dependent stuff *
779\***************************************************************************/
780
781#ifdef macintosh
782pascal void SpinCursor (short increment); /* copied from CursorCtl.h */
783# define HOURGLASS SpinCursor( 1 )
784# define HOURGLASS_RATE 1023 /* 2^n - 1 */
785#endif
786
787//teawater add for arm2x86 2005.02.14-------------------------------------------
788/*ywc 2005-03-31*/
789/*
790#include "arm2x86.h"
791#include "arm2x86_dp.h"
792#include "arm2x86_movl.h"
793#include "arm2x86_psr.h"
794#include "arm2x86_shift.h"
795#include "arm2x86_mem.h"
796#include "arm2x86_mul.h"
797#include "arm2x86_test.h"
798#include "arm2x86_other.h"
799#include "list.h"
800#include "tb.h"
801*/
802enum ConditionCode { 682enum ConditionCode {
803 EQ = 0, 683 EQ = 0,
804 NE = 1, 684 NE = 1,
@@ -851,32 +731,16 @@ enum ConditionCode {
851#define ZBIT_SHIFT 30 731#define ZBIT_SHIFT 30
852#define CBIT_SHIFT 29 732#define CBIT_SHIFT 29
853#define VBIT_SHIFT 28 733#define VBIT_SHIFT 28
854#ifdef DBCT 734
855//teawater change for local tb branch directly jump 2005.10.18------------------
856#include "dbct/list.h"
857#include "dbct/arm2x86.h"
858#include "dbct/arm2x86_dp.h"
859#include "dbct/arm2x86_movl.h"
860#include "dbct/arm2x86_psr.h"
861#include "dbct/arm2x86_shift.h"
862#include "dbct/arm2x86_mem.h"
863#include "dbct/arm2x86_mul.h"
864#include "dbct/arm2x86_test.h"
865#include "dbct/arm2x86_other.h"
866#include "dbct/arm2x86_coproc.h"
867#include "dbct/tb.h"
868#endif
869//AJ2D--------------------------------------------------------------------------
870//AJ2D--------------------------------------------------------------------------
871#define SKYEYE_OUTREGS(fd) { fprintf ((fd), "R %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,C %x,S %x,%x,%x,%x,%x,%x,%x,M %x,B %x,E %x,I %x,P %x,T %x,L %x,D %x,",\ 735#define SKYEYE_OUTREGS(fd) { fprintf ((fd), "R %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,C %x,S %x,%x,%x,%x,%x,%x,%x,M %x,B %x,E %x,I %x,P %x,T %x,L %x,D %x,",\
872 state->Reg[0],state->Reg[1],state->Reg[2],state->Reg[3], \ 736 state->Reg[0],state->Reg[1],state->Reg[2],state->Reg[3], \
873 state->Reg[4],state->Reg[5],state->Reg[6],state->Reg[7], \ 737 state->Reg[4],state->Reg[5],state->Reg[6],state->Reg[7], \
874 state->Reg[8],state->Reg[9],state->Reg[10],state->Reg[11], \ 738 state->Reg[8],state->Reg[9],state->Reg[10],state->Reg[11], \
875 state->Reg[12],state->Reg[13],state->Reg[14],state->Reg[15], \ 739 state->Reg[12],state->Reg[13],state->Reg[14],state->Reg[15], \
876 state->Cpsr, state->Spsr[0], state->Spsr[1], state->Spsr[2],\ 740 state->Cpsr, state->Spsr[0], state->Spsr[1], state->Spsr[2],\
877 state->Spsr[3],state->Spsr[4], state->Spsr[5], state->Spsr[6],\ 741 state->Spsr[3],state->Spsr[4], state->Spsr[5], state->Spsr[6],\
878 state->Mode,state->Bank,state->ErrorCode,state->instr,state->pc,\ 742 state->Mode,state->Bank,state->ErrorCode,state->instr,state->pc,\
879 state->temp,state->loaded,state->decoded);} 743 state->temp,state->loaded,state->decoded);}
880 744
881#define SKYEYE_OUTMOREREGS(fd) { fprintf ((fd),"\ 745#define SKYEYE_OUTMOREREGS(fd) { fprintf ((fd),"\
882RUs %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\ 746RUs %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\
@@ -914,17 +778,30 @@ RUn %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",\
914 778
915#define SA1110 0x6901b110 779#define SA1110 0x6901b110
916#define SA1100 0x4401a100 780#define SA1100 0x4401a100
917#define PXA250 0x69052100 781#define PXA250 0x69052100
918#define PXA270 0x69054110 782#define PXA270 0x69054110
919//#define PXA250 0x69052903 783//#define PXA250 0x69052903
920// 0x69052903; //PXA250 B1 from intel 278522-001.pdf 784// 0x69052903; //PXA250 B1 from intel 278522-001.pdf
921 785
922 786
923extern void ARMul_UndefInstr (ARMul_State *, ARMword); 787extern void ARMul_UndefInstr(ARMul_State*, ARMword);
924extern void ARMul_FixCPSR (ARMul_State *, ARMword, ARMword); 788extern void ARMul_FixCPSR(ARMul_State*, ARMword, ARMword);
925extern void ARMul_FixSPSR (ARMul_State *, ARMword, ARMword); 789extern void ARMul_FixSPSR(ARMul_State*, ARMword, ARMword);
926extern void ARMul_ConsolePrint (ARMul_State *, const char *, ...); 790extern void ARMul_ConsolePrint(ARMul_State*, const char*, ...);
927extern void ARMul_SelectProcessor (ARMul_State *, unsigned); 791extern void ARMul_SelectProcessor(ARMul_State*, unsigned);
792
793extern u8 ARMul_SignedSaturatedAdd8(u8, u8);
794extern u8 ARMul_SignedSaturatedSub8(u8, u8);
795extern u16 ARMul_SignedSaturatedAdd16(u16, u16);
796extern u16 ARMul_SignedSaturatedSub16(u16, u16);
797
798extern u8 ARMul_UnsignedSaturatedAdd8(u8, u8);
799extern u16 ARMul_UnsignedSaturatedAdd16(u16, u16);
800extern u8 ARMul_UnsignedSaturatedSub8(u8, u8);
801extern u16 ARMul_UnsignedSaturatedSub16(u16, u16);
802extern u8 ARMul_UnsignedAbsoluteDifference(u8, u8);
803extern u32 ARMul_SignedSatQ(s32, u8, bool*);
804extern u32 ARMul_UnsignedSatQ(s32, u8, bool*);
928 805
929#define DIFF_LOG 0 806#define DIFF_LOG 0
930#define SAVE_LOG 0 807#define SAVE_LOG 0
diff --git a/src/core/arm/skyeye_common/armemu.h b/src/core/arm/skyeye_common/armemu.h
index 075fc7e9e..3ea14b5a3 100644
--- a/src/core/arm/skyeye_common/armemu.h
+++ b/src/core/arm/skyeye_common/armemu.h
@@ -23,8 +23,6 @@
23 23
24//extern ARMword isize; 24//extern ARMword isize;
25 25
26#define DEBUG(...) DEBUG_LOG(ARM11, __VA_ARGS__)
27
28/* Shift Opcodes. */ 26/* Shift Opcodes. */
29#define LSL 0 27#define LSL 0
30#define LSR 1 28#define LSR 1
@@ -36,7 +34,7 @@
36#define ZBIT (1L << 30) 34#define ZBIT (1L << 30)
37#define CBIT (1L << 29) 35#define CBIT (1L << 29)
38#define VBIT (1L << 28) 36#define VBIT (1L << 28)
39#define SBIT (1L << 27) 37#define QBIT (1L << 27)
40#define IBIT (1L << 7) 38#define IBIT (1L << 7)
41#define FBIT (1L << 6) 39#define FBIT (1L << 6)
42#define IFBITS (3L << 6) 40#define IFBITS (3L << 6)
@@ -158,13 +156,14 @@
158#define R15PCMODE (state->Reg[15] & (R15PCBITS | R15MODEBITS)) 156#define R15PCMODE (state->Reg[15] & (R15PCBITS | R15MODEBITS))
159#define R15MODE (state->Reg[15] & R15MODEBITS) 157#define R15MODE (state->Reg[15] & R15MODEBITS)
160 158
161#define ECC ((NFLAG << 31) | (ZFLAG << 30) | (CFLAG << 29) | (VFLAG << 28) | (SFLAG << 27)) 159#define ECC ((NFLAG << 31) | (ZFLAG << 30) | (CFLAG << 29) | (VFLAG << 28) | (QFLAG << 27))
162#define EINT (IFFLAGS << 6) 160#define EINT (IFFLAGS << 6)
163#define ER15INT (IFFLAGS << 26) 161#define ER15INT (IFFLAGS << 26)
164#define EMODE (state->Mode) 162#define EMODE (state->Mode)
163#define EGEBITS (state->GEFlag & 0x000F0000)
165 164
166#ifdef MODET 165#ifdef MODET
167#define CPSR (ECC | EINT | EMODE | (TFLAG << 5)) 166#define CPSR (ECC | EGEBITS | (EFLAG << 9) | (AFLAG << 8) | EINT | (TFLAG << 5) | EMODE)
168#else 167#else
169#define CPSR (ECC | EINT | EMODE) 168#define CPSR (ECC | EINT | EMODE)
170#endif 169#endif
@@ -485,7 +484,7 @@ tdstate;
485 * out-of-updated with the newer ISA. 484 * out-of-updated with the newer ISA.
486 * -- Michael.Kang 485 * -- Michael.Kang
487 ********************************************************************************/ 486 ********************************************************************************/
488#define UNDEF_WARNING WARN_LOG(ARM11, "undefined or unpredicted behavior for arm instruction.\n"); 487#define UNDEF_WARNING LOG_WARNING(Core_ARM11, "undefined or unpredicted behavior for arm instruction.");
489 488
490/* Macros to scrutinize instructions. */ 489/* Macros to scrutinize instructions. */
491#define UNDEF_Test UNDEF_WARNING 490#define UNDEF_Test UNDEF_WARNING
@@ -603,6 +602,7 @@ extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword);
603extern void ARMul_MSRCpsr (ARMul_State *, ARMword, ARMword); 602extern void ARMul_MSRCpsr (ARMul_State *, ARMword, ARMword);
604extern void ARMul_SubOverflow (ARMul_State *, ARMword, ARMword, ARMword); 603extern void ARMul_SubOverflow (ARMul_State *, ARMword, ARMword, ARMword);
605extern void ARMul_AddOverflow (ARMul_State *, ARMword, ARMword, ARMword); 604extern void ARMul_AddOverflow (ARMul_State *, ARMword, ARMword, ARMword);
605extern void ARMul_AddOverflowQ(ARMul_State*, ARMword, ARMword);
606extern void ARMul_SubCarry (ARMul_State *, ARMword, ARMword, ARMword); 606extern void ARMul_SubCarry (ARMul_State *, ARMword, ARMword, ARMword);
607extern void ARMul_AddCarry (ARMul_State *, ARMword, ARMword, ARMword); 607extern void ARMul_AddCarry (ARMul_State *, ARMword, ARMword, ARMword);
608extern tdstate ARMul_ThumbDecode (ARMul_State *, ARMword, ARMword, ARMword *); 608extern tdstate ARMul_ThumbDecode (ARMul_State *, ARMword, ARMword, ARMword *);
diff --git a/src/core/arm/skyeye_common/vfp/vfp.cpp b/src/core/arm/skyeye_common/vfp/vfp.cpp
index 454f60099..5c036caeb 100644
--- a/src/core/arm/skyeye_common/vfp/vfp.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfp.cpp
@@ -32,8 +32,7 @@
32 32
33//ARMul_State* persistent_state; /* function calls from SoftFloat lib don't have an access to ARMul_state. */ 33//ARMul_State* persistent_state; /* function calls from SoftFloat lib don't have an access to ARMul_state. */
34 34
35unsigned 35unsigned VFPInit(ARMul_State* state)
36VFPInit (ARMul_State *state)
37{ 36{
38 state->VFP[VFP_OFFSET(VFP_FPSID)] = VFP_FPSID_IMPLMEN<<24 | VFP_FPSID_SW<<23 | VFP_FPSID_SUBARCH<<16 | 37 state->VFP[VFP_OFFSET(VFP_FPSID)] = VFP_FPSID_IMPLMEN<<24 | VFP_FPSID_SW<<23 | VFP_FPSID_SUBARCH<<16 |
39 VFP_FPSID_PARTNUM<<8 | VFP_FPSID_VARIANT<<4 | VFP_FPSID_REVISION; 38 VFP_FPSID_PARTNUM<<8 | VFP_FPSID_VARIANT<<4 | VFP_FPSID_REVISION;
@@ -46,8 +45,7 @@ VFPInit (ARMul_State *state)
46 return 0; 45 return 0;
47} 46}
48 47
49unsigned 48unsigned VFPMRC(ARMul_State* state, unsigned type, u32 instr, u32* value)
50VFPMRC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
51{ 49{
52 /* MRC<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */ 50 /* MRC<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
53 int CoProc = BITS (8, 11); /* 10 or 11 */ 51 int CoProc = BITS (8, 11); /* 10 or 11 */
@@ -61,10 +59,21 @@ VFPMRC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
61 59
62 /* CRn/opc1 CRm/opc2 */ 60 /* CRn/opc1 CRm/opc2 */
63 61
64 if (CoProc == 10 || CoProc == 11) { 62 if (CoProc == 10 || CoProc == 11)
65#define VFP_MRC_TRANS 63 {
66#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 64 if (OPC_1 == 0x0 && CRm == 0 && (OPC_2 & 0x3) == 0)
67#undef VFP_MRC_TRANS 65 {
66 /* VMOV r to s */
67 /* Transfering Rt is not mandatory, as the value of interest is pointed by value */
68 VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, value);
69 return ARMul_DONE;
70 }
71
72 if (OPC_1 == 0x7 && CRm == 0 && OPC_2 == 0)
73 {
74 VMRS(state, CRn, Rt, value);
75 return ARMul_DONE;
76 }
68 } 77 }
69 DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n", 78 DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n",
70 instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2); 79 instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2);
@@ -72,8 +81,7 @@ VFPMRC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
72 return ARMul_CANT; 81 return ARMul_CANT;
73} 82}
74 83
75unsigned 84unsigned VFPMCR(ARMul_State* state, unsigned type, u32 instr, u32 value)
76VFPMCR (ARMul_State * state, unsigned type, u32 instr, u32 value)
77{ 85{
78 /* MCR<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */ 86 /* MCR<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
79 int CoProc = BITS (8, 11); /* 10 or 11 */ 87 int CoProc = BITS (8, 11); /* 10 or 11 */
@@ -86,10 +94,33 @@ VFPMCR (ARMul_State * state, unsigned type, u32 instr, u32 value)
86 /* TODO check access permission */ 94 /* TODO check access permission */
87 95
88 /* CRn/opc1 CRm/opc2 */ 96 /* CRn/opc1 CRm/opc2 */
89 if (CoProc == 10 || CoProc == 11) { 97 if (CoProc == 10 || CoProc == 11)
90#define VFP_MCR_TRANS 98 {
91#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 99 if (OPC_1 == 0x0 && CRm == 0 && (OPC_2 & 0x3) == 0)
92#undef VFP_MCR_TRANS 100 {
101 /* VMOV s to r */
102 /* Transfering Rt is not mandatory, as the value of interest is pointed by value */
103 VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, &value);
104 return ARMul_DONE;
105 }
106
107 if (OPC_1 == 0x7 && CRm == 0 && OPC_2 == 0)
108 {
109 VMSR(state, CRn, Rt);
110 return ARMul_DONE;
111 }
112
113 if ((OPC_1 & 0x4) == 0 && CoProc == 11 && CRm == 0)
114 {
115 VFP_DEBUG_UNIMPLEMENTED(VMOVBRC);
116 return ARMul_DONE;
117 }
118
119 if (CoProc == 11 && CRm == 0)
120 {
121 VFP_DEBUG_UNIMPLEMENTED(VMOVBCR);
122 return ARMul_DONE;
123 }
93 } 124 }
94 DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n", 125 DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n",
95 instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2); 126 instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2);
@@ -97,8 +128,7 @@ VFPMCR (ARMul_State * state, unsigned type, u32 instr, u32 value)
97 return ARMul_CANT; 128 return ARMul_CANT;
98} 129}
99 130
100unsigned 131unsigned VFPMRRC(ARMul_State* state, unsigned type, u32 instr, u32* value1, u32* value2)
101VFPMRRC (ARMul_State * state, unsigned type, u32 instr, u32 * value1, u32 * value2)
102{ 132{
103 /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */ 133 /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
104 int CoProc = BITS (8, 11); /* 10 or 11 */ 134 int CoProc = BITS (8, 11); /* 10 or 11 */
@@ -107,10 +137,20 @@ VFPMRRC (ARMul_State * state, unsigned type, u32 instr, u32 * value1, u32 * valu
107 int Rt2 = BITS (16, 19); 137 int Rt2 = BITS (16, 19);
108 int CRm = BITS (0, 3); 138 int CRm = BITS (0, 3);
109 139
110 if (CoProc == 10 || CoProc == 11) { 140 if (CoProc == 10 || CoProc == 11)
111#define VFP_MRRC_TRANS 141 {
112#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 142 if (CoProc == 10 && (OPC_1 & 0xD) == 1)
113#undef VFP_MRRC_TRANS 143 {
144 VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS);
145 return ARMul_DONE;
146 }
147
148 if (CoProc == 11 && (OPC_1 & 0xD) == 1)
149 {
150 /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */
151 VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, value1, value2);
152 return ARMul_DONE;
153 }
114 } 154 }
115 DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n", 155 DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",
116 instr, CoProc, OPC_1, Rt, Rt2, CRm); 156 instr, CoProc, OPC_1, Rt, Rt2, CRm);
@@ -118,8 +158,7 @@ VFPMRRC (ARMul_State * state, unsigned type, u32 instr, u32 * value1, u32 * valu
118 return ARMul_CANT; 158 return ARMul_CANT;
119} 159}
120 160
121unsigned 161unsigned VFPMCRR(ARMul_State* state, unsigned type, u32 instr, u32 value1, u32 value2)
122VFPMCRR (ARMul_State * state, unsigned type, u32 instr, u32 value1, u32 value2)
123{ 162{
124 /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */ 163 /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
125 int CoProc = BITS (8, 11); /* 10 or 11 */ 164 int CoProc = BITS (8, 11); /* 10 or 11 */
@@ -132,10 +171,20 @@ VFPMCRR (ARMul_State * state, unsigned type, u32 instr, u32 value1, u32 value2)
132 171
133 /* CRn/opc1 CRm/opc2 */ 172 /* CRn/opc1 CRm/opc2 */
134 173
135 if (CoProc == 11 || CoProc == 10) { 174 if (CoProc == 11 || CoProc == 10)
136#define VFP_MCRR_TRANS 175 {
137#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 176 if (CoProc == 10 && (OPC_1 & 0xD) == 1)
138#undef VFP_MCRR_TRANS 177 {
178 VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS);
179 return ARMul_DONE;
180 }
181
182 if (CoProc == 11 && (OPC_1 & 0xD) == 1)
183 {
184 /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */
185 VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, &value1, &value2);
186 return ARMul_DONE;
187 }
139 } 188 }
140 DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n", 189 DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",
141 instr, CoProc, OPC_1, Rt, Rt2, CRm); 190 instr, CoProc, OPC_1, Rt, Rt2, CRm);
@@ -143,8 +192,7 @@ VFPMCRR (ARMul_State * state, unsigned type, u32 instr, u32 value1, u32 value2)
143 return ARMul_CANT; 192 return ARMul_CANT;
144} 193}
145 194
146unsigned 195unsigned VFPSTC(ARMul_State* state, unsigned type, u32 instr, u32 * value)
147VFPSTC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
148{ 196{
149 /* STC{L}<c> <coproc>,<CRd>,[<Rn>],<option> */ 197 /* STC{L}<c> <coproc>,<CRd>,[<Rn>],<option> */
150 int CoProc = BITS (8, 11); /* 10 or 11 */ 198 int CoProc = BITS (8, 11); /* 10 or 11 */
@@ -175,9 +223,17 @@ VFPSTC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
175 } 223 }
176#endif 224#endif
177 225
178#define VFP_STC_TRANS 226 if (P == 1 && W == 0)
179#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 227 {
180#undef VFP_STC_TRANS 228 return VSTR(state, type, instr, value);
229 }
230
231 if (P == 1 && U == 0 && W == 1 && Rn == 0xD)
232 {
233 return VPUSH(state, type, instr, value);
234 }
235
236 return VSTM(state, type, instr, value);
181 } 237 }
182 DEBUG("Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n", 238 DEBUG("Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n",
183 instr, CoProc, CRd, Rn, imm8, P, U, D, W); 239 instr, CoProc, CRd, Rn, imm8, P, U, D, W);
@@ -185,8 +241,7 @@ VFPSTC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
185 return ARMul_CANT; 241 return ARMul_CANT;
186} 242}
187 243
188unsigned 244unsigned VFPLDC(ARMul_State* state, unsigned type, u32 instr, u32 value)
189VFPLDC (ARMul_State * state, unsigned type, u32 instr, u32 value)
190{ 245{
191 /* LDC{L}<c> <coproc>,<CRd>,[<Rn>] */ 246 /* LDC{L}<c> <coproc>,<CRd>,[<Rn>] */
192 int CoProc = BITS (8, 11); /* 10 or 11 */ 247 int CoProc = BITS (8, 11); /* 10 or 11 */
@@ -204,10 +259,19 @@ VFPLDC (ARMul_State * state, unsigned type, u32 instr, u32 value)
204 DEBUG("In %s, UNDEFINED\n", __FUNCTION__); 259 DEBUG("In %s, UNDEFINED\n", __FUNCTION__);
205 exit(-1); 260 exit(-1);
206 } 261 }
207 if (CoProc == 10 || CoProc == 11) { 262 if (CoProc == 10 || CoProc == 11)
208#define VFP_LDC_TRANS 263 {
209#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 264 if (P == 1 && W == 0)
210#undef VFP_LDC_TRANS 265 {
266 return VLDR(state, type, instr, value);
267 }
268
269 if (P == 0 && U == 1 && W == 1 && Rn == 0xD)
270 {
271 return VPOP(state, type, instr, value);
272 }
273
274 return VLDM(state, type, instr, value);
211 } 275 }
212 DEBUG("Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n", 276 DEBUG("Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n",
213 instr, CoProc, CRd, Rn, imm8, P, U, D, W); 277 instr, CoProc, CRd, Rn, imm8, P, U, D, W);
@@ -215,8 +279,7 @@ VFPLDC (ARMul_State * state, unsigned type, u32 instr, u32 value)
215 return ARMul_CANT; 279 return ARMul_CANT;
216} 280}
217 281
218unsigned 282unsigned VFPCDP(ARMul_State* state, unsigned type, u32 instr)
219VFPCDP (ARMul_State * state, unsigned type, u32 instr)
220{ 283{
221 /* CDP<c> <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> */ 284 /* CDP<c> <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> */
222 int CoProc = BITS (8, 11); /* 10 or 11 */ 285 int CoProc = BITS (8, 11); /* 10 or 11 */
@@ -275,10 +338,83 @@ VFPCDP (ARMul_State * state, unsigned type, u32 instr)
275 338
276 /* CRn/opc1 CRm/opc2 */ 339 /* CRn/opc1 CRm/opc2 */
277 340
278 if (CoProc == 10 || CoProc == 11) { 341 if (CoProc == 10 || CoProc == 11)
279#define VFP_CDP_TRANS 342 {
280#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 343 if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 0)
281#undef VFP_CDP_TRANS 344 DBG("VMLA :\n");
345
346 if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 2)
347 DBG("VMLS :\n");
348
349 if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 2)
350 DBG("VNMLA :\n");
351
352 if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 0)
353 DBG("VNMLS :\n");
354
355 if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 2)
356 DBG("VNMUL :\n");
357
358 if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 0)
359 DBG("VMUL :\n");
360
361 if ((OPC_1 & 0xB) == 3 && (OPC_2 & 0x2) == 0)
362 DBG("VADD :\n");
363
364 if ((OPC_1 & 0xB) == 3 && (OPC_2 & 0x2) == 2)
365 DBG("VSUB :\n");
366
367 if ((OPC_1 & 0xB) == 0xA && (OPC_2 & 0x2) == 0)
368 DBG("VDIV :\n");
369
370 if ((OPC_1 & 0xB) == 0xB && BITS(4, 7) == 0)
371 {
372 unsigned int single = BIT(8) == 0;
373 unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4);
374 unsigned int imm;
375 instr = BITS(16, 19) << 4 | BITS(0, 3); /* FIXME dirty workaround to get a correct imm */
376
377 if (single)
378 imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0x1f : 0)<<25 | BITS(0, 5)<<19;
379 else
380 imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0xff : 0)<<22 | BITS(0, 5)<<16;
381
382 VMOVI(state, single, d, imm);
383 return ARMul_DONE;
384 }
385
386 if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x6) == 0x2)
387 {
388 unsigned int single = BIT(8) == 0;
389 unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4);
390 unsigned int m = (single ? BITS( 0, 3)<<1 | BIT( 5) : BITS( 0, 3) | BIT( 5)<<4);;
391 VMOVR(state, single, d, m);
392 return ARMul_DONE;
393 }
394
395 if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x7) == 6)
396 DBG("VABS :\n");
397
398 if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 2)
399 DBG("VNEG :\n");
400
401 if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 6)
402 DBG("VSQRT :\n");
403
404 if ((OPC_1 & 0xB) == 0xB && CRn == 4 && (OPC_2 & 0x2) == 2)
405 DBG("VCMP(1) :\n");
406
407 if ((OPC_1 & 0xB) == 0xB && CRn == 5 && (OPC_2 & 0x2) == 2 && CRm == 0)
408 DBG("VCMP(2) :\n");
409
410 if ((OPC_1 & 0xB) == 0xB && CRn == 7 && (OPC_2 & 0x6) == 6)
411 DBG("VCVT(BDS) :\n");
412
413 if ((OPC_1 & 0xB) == 0xB && CRn >= 0xA && (OPC_2 & 0x2) == 2)
414 DBG("VCVT(BFF) :\n");
415
416 if ((OPC_1 & 0xB) == 0xB && CRn > 7 && (OPC_2 & 0x2) == 2)
417 DBG("VCVT(BFI) :\n");
282 418
283 int exceptions = 0; 419 int exceptions = 0;
284 if (CoProc == 10) 420 if (CoProc == 10)
@@ -296,23 +432,93 @@ VFPCDP (ARMul_State * state, unsigned type, u32 instr)
296 432
297 433
298/* ----------- MRC ------------ */ 434/* ----------- MRC ------------ */
299#define VFP_MRC_IMPL 435void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* value)
300#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 436{
301#undef VFP_MRC_IMPL 437 DBG("VMOV(BRS) :\n");
302 438 if (to_arm)
303#define VFP_MRRC_IMPL 439 {
304#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 440 DBG("\tr%d <= s%d=[%x]\n", t, n, state->ExtReg[n]);
305#undef VFP_MRRC_IMPL 441 *value = state->ExtReg[n];
306 442 }
443 else
444 {
445 DBG("\ts%d <= r%d=[%x]\n", n, t, *value);
446 state->ExtReg[n] = *value;
447 }
448}
449void VMRS(ARMul_State* state, ARMword reg, ARMword Rt, ARMword* value)
450{
451 DBG("VMRS :");
452 if (reg == 1)
453 {
454 if (Rt != 15)
455 {
456 *value = state->VFP[VFP_OFFSET(VFP_FPSCR)];
457 DBG("\tr%d <= fpscr[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPSCR)]);
458 }
459 else
460 {
461 *value = state->VFP[VFP_OFFSET(VFP_FPSCR)] ;
462 DBG("\tflags <= fpscr[%1xxxxxxxx]\n", state->VFP[VFP_OFFSET(VFP_FPSCR)]>>28);
463 }
464 }
465 else
466 {
467 switch (reg)
468 {
469 case 0:
470 *value = state->VFP[VFP_OFFSET(VFP_FPSID)];
471 DBG("\tr%d <= fpsid[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPSID)]);
472 break;
473 case 6:
474 /* MVFR1, VFPv3 only ? */
475 DBG("\tr%d <= MVFR1 unimplemented\n", Rt);
476 break;
477 case 7:
478 /* MVFR0, VFPv3 only? */
479 DBG("\tr%d <= MVFR0 unimplemented\n", Rt);
480 break;
481 case 8:
482 *value = state->VFP[VFP_OFFSET(VFP_FPEXC)];
483 DBG("\tr%d <= fpexc[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPEXC)]);
484 break;
485 default:
486 DBG("\tSUBARCHITECTURE DEFINED\n");
487 break;
488 }
489 }
490}
491void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2)
492{
493 DBG("VMOV(BRRD) :\n");
494 if (to_arm)
495 {
496 DBG("\tr[%d-%d] <= s[%d-%d]=[%x-%x]\n", t2, t, n*2+1, n*2, state->ExtReg[n*2+1], state->ExtReg[n*2]);
497 *value2 = state->ExtReg[n*2+1];
498 *value1 = state->ExtReg[n*2];
499 }
500 else
501 {
502 DBG("\ts[%d-%d] <= r[%d-%d]=[%x-%x]\n", n*2+1, n*2, t2, t, *value2, *value1);
503 state->ExtReg[n*2+1] = *value2;
504 state->ExtReg[n*2] = *value1;
505 }
506}
307 507
308/* ----------- MCR ------------ */ 508/* ----------- MCR ------------ */
309#define VFP_MCR_IMPL 509void VMSR(ARMul_State* state, ARMword reg, ARMword Rt)
310#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 510{
311#undef VFP_MCR_IMPL 511 if (reg == 1)
312 512 {
313#define VFP_MCRR_IMPL 513 DBG("VMSR :\tfpscr <= r%d=[%x]\n", Rt, state->Reg[Rt]);
314#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 514 state->VFP[VFP_OFFSET(VFP_FPSCR)] = state->Reg[Rt];
315#undef VFP_MCRR_IMPL 515 }
516 else if (reg == 8)
517 {
518 DBG("VMSR :\tfpexc <= r%d=[%x]\n", Rt, state->Reg[Rt]);
519 state->VFP[VFP_OFFSET(VFP_FPEXC)] = state->Reg[Rt];
520 }
521}
316 522
317/* Memory operation are not inlined, as old Interpreter and Fast interpreter 523/* Memory operation are not inlined, as old Interpreter and Fast interpreter
318 don't have the same memory operation interface. 524 don't have the same memory operation interface.
@@ -322,21 +528,342 @@ VFPCDP (ARMul_State * state, unsigned type, u32 instr)
322 of vfp instructions in old interpreter and fast interpreter are separate. */ 528 of vfp instructions in old interpreter and fast interpreter are separate. */
323 529
324/* ----------- STC ------------ */ 530/* ----------- STC ------------ */
325#define VFP_STC_IMPL 531int VSTR(ARMul_State* state, int type, ARMword instr, ARMword* value)
326#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 532{
327#undef VFP_STC_IMPL 533 static int i = 0;
534 static int single_reg, add, d, n, imm32, regs;
535 if (type == ARMul_FIRST)
536 {
537 single_reg = BIT(8) == 0; /* Double precision */
538 add = BIT(23); /* */
539 imm32 = BITS(0,7)<<2; /* may not be used */
540 d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
541 n = BITS(16, 19); /* destination register */
328 542
543 DBG("VSTR :\n");
544
545 i = 0;
546 regs = 1;
547
548 return ARMul_DONE;
549 }
550 else if (type == ARMul_DATA)
551 {
552 if (single_reg)
553 {
554 *value = state->ExtReg[d+i];
555 DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d+i]);
556 i++;
557 if (i < regs)
558 return ARMul_INC;
559 else
560 return ARMul_DONE;
561 }
562 else
563 {
564 /* FIXME Careful of endianness, may need to rework this */
565 *value = state->ExtReg[d*2+i];
566 DBG("\taddr[?] <= s[%d]=[%x]\n", d*2+i, state->ExtReg[d*2+i]);
567 i++;
568 if (i < regs*2)
569 return ARMul_INC;
570 else
571 return ARMul_DONE;
572 }
573 }
574
575 return -1;
576}
577int VPUSH(ARMul_State* state, int type, ARMword instr, ARMword* value)
578{
579 static int i = 0;
580 static int single_regs, add, wback, d, n, imm32, regs;
581 if (type == ARMul_FIRST)
582 {
583 single_regs = BIT(8) == 0; /* Single precision */
584 d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
585 imm32 = BITS(0,7)<<2; /* may not be used */
586 regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FSTMX if regs is odd */
587
588 DBG("VPUSH :\n");
589 DBG("\tsp[%x]", state->Reg[R13]);
590 state->Reg[R13] = state->Reg[R13] - imm32;
591 DBG("=>[%x]\n", state->Reg[R13]);
592
593 i = 0;
594
595 return ARMul_DONE;
596 }
597 else if (type == ARMul_DATA)
598 {
599 if (single_regs)
600 {
601 *value = state->ExtReg[d + i];
602 DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d + i]);
603 i++;
604 if (i < regs)
605 return ARMul_INC;
606 else
607 return ARMul_DONE;
608 }
609 else
610 {
611 /* FIXME Careful of endianness, may need to rework this */
612 *value = state->ExtReg[d*2 + i];
613 DBG("\taddr[?] <= s[%d]=[%x]\n", d*2 + i, state->ExtReg[d*2 + i]);
614 i++;
615 if (i < regs*2)
616 return ARMul_INC;
617 else
618 return ARMul_DONE;
619 }
620 }
621
622 return -1;
623}
624int VSTM(ARMul_State* state, int type, ARMword instr, ARMword* value)
625{
626 static int i = 0;
627 static int single_regs, add, wback, d, n, imm32, regs;
628 if (type == ARMul_FIRST)
629 {
630 single_regs = BIT(8) == 0; /* Single precision */
631 add = BIT(23); /* */
632 wback = BIT(21); /* write-back */
633 d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
634 n = BITS(16, 19); /* destination register */
635 imm32 = BITS(0,7) * 4; /* may not be used */
636 regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FSTMX if regs is odd */
637
638 DBG("VSTM :\n");
639
640 if (wback) {
641 state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32);
642 DBG("\twback r%d[%x]\n", n, state->Reg[n]);
643 }
644
645 i = 0;
646
647 return ARMul_DONE;
648 }
649 else if (type == ARMul_DATA)
650 {
651 if (single_regs)
652 {
653 *value = state->ExtReg[d + i];
654 DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d + i]);
655 i++;
656 if (i < regs)
657 return ARMul_INC;
658 else
659 return ARMul_DONE;
660 }
661 else
662 {
663 /* FIXME Careful of endianness, may need to rework this */
664 *value = state->ExtReg[d*2 + i];
665 DBG("\taddr[?] <= s[%d]=[%x]\n", d*2 + i, state->ExtReg[d*2 + i]);
666 i++;
667 if (i < regs*2)
668 return ARMul_INC;
669 else
670 return ARMul_DONE;
671 }
672 }
673
674 return -1;
675}
329 676
330/* ----------- LDC ------------ */ 677/* ----------- LDC ------------ */
331#define VFP_LDC_IMPL 678int VPOP(ARMul_State* state, int type, ARMword instr, ARMword value)
332#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 679{
333#undef VFP_LDC_IMPL 680 static int i = 0;
681 static int single_regs, add, wback, d, n, imm32, regs;
682 if (type == ARMul_FIRST)
683 {
684 single_regs = BIT(8) == 0; /* Single precision */
685 d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
686 imm32 = BITS(0,7)<<2; /* may not be used */
687 regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FLDMX if regs is odd */
334 688
689 DBG("VPOP :\n");
690 DBG("\tsp[%x]", state->Reg[R13]);
691 state->Reg[R13] = state->Reg[R13] + imm32;
692 DBG("=>[%x]\n", state->Reg[R13]);
693
694 i = 0;
695
696 return ARMul_DONE;
697 }
698 else if (type == ARMul_TRANSFER)
699 {
700 return ARMul_DONE;
701 }
702 else if (type == ARMul_DATA)
703 {
704 if (single_regs)
705 {
706 state->ExtReg[d + i] = value;
707 DBG("\ts%d <= [%x]\n", d + i, value);
708 i++;
709 if (i < regs)
710 return ARMul_INC;
711 else
712 return ARMul_DONE;
713 }
714 else
715 {
716 /* FIXME Careful of endianness, may need to rework this */
717 state->ExtReg[d*2 + i] = value;
718 DBG("\ts%d <= [%x]\n", d*2 + i, value);
719 i++;
720 if (i < regs*2)
721 return ARMul_INC;
722 else
723 return ARMul_DONE;
724 }
725 }
726
727 return -1;
728}
729int VLDR(ARMul_State* state, int type, ARMword instr, ARMword value)
730{
731 static int i = 0;
732 static int single_reg, add, d, n, imm32, regs;
733 if (type == ARMul_FIRST)
734 {
735 single_reg = BIT(8) == 0; /* Double precision */
736 add = BIT(23); /* */
737 imm32 = BITS(0,7)<<2; /* may not be used */
738 d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
739 n = BITS(16, 19); /* destination register */
740
741 DBG("VLDR :\n");
742
743 i = 0;
744 regs = 1;
745
746 return ARMul_DONE;
747 }
748 else if (type == ARMul_TRANSFER)
749 {
750 return ARMul_DONE;
751 }
752 else if (type == ARMul_DATA)
753 {
754 if (single_reg)
755 {
756 state->ExtReg[d+i] = value;
757 DBG("\ts%d <= [%x]\n", d+i, value);
758 i++;
759 if (i < regs)
760 return ARMul_INC;
761 else
762 return ARMul_DONE;
763 }
764 else
765 {
766 /* FIXME Careful of endianness, may need to rework this */
767 state->ExtReg[d*2+i] = value;
768 DBG("\ts[%d] <= [%x]\n", d*2+i, value);
769 i++;
770 if (i < regs*2)
771 return ARMul_INC;
772 else
773 return ARMul_DONE;
774 }
775 }
776
777 return -1;
778}
779int VLDM(ARMul_State* state, int type, ARMword instr, ARMword value)
780{
781 static int i = 0;
782 static int single_regs, add, wback, d, n, imm32, regs;
783 if (type == ARMul_FIRST)
784 {
785 single_regs = BIT(8) == 0; /* Single precision */
786 add = BIT(23); /* */
787 wback = BIT(21); /* write-back */
788 d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
789 n = BITS(16, 19); /* destination register */
790 imm32 = BITS(0,7) * 4; /* may not be used */
791 regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FLDMX if regs is odd */
792
793 DBG("VLDM :\n");
794
795 if (wback) {
796 state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32);
797 DBG("\twback r%d[%x]\n", n, state->Reg[n]);
798 }
799
800 i = 0;
801
802 return ARMul_DONE;
803 }
804 else if (type == ARMul_DATA)
805 {
806 if (single_regs)
807 {
808 state->ExtReg[d + i] = value;
809 DBG("\ts%d <= [%x] addr[?]\n", d+i, state->ExtReg[d + i]);
810 i++;
811 if (i < regs)
812 return ARMul_INC;
813 else
814 return ARMul_DONE;
815 }
816 else
817 {
818 /* FIXME Careful of endianness, may need to rework this */
819 state->ExtReg[d*2 + i] = value;
820 DBG("\ts[%d] <= [%x] addr[?]\n", d*2 + i, state->ExtReg[d*2 + i]);
821 i++;
822 if (i < regs*2)
823 return ARMul_INC;
824 else
825 return ARMul_DONE;
826 }
827 }
828
829 return -1;
830}
335 831
336/* ----------- CDP ------------ */ 832/* ----------- CDP ------------ */
337#define VFP_CDP_IMPL 833void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm)
338#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 834{
339#undef VFP_CDP_IMPL 835 DBG("VMOV(I) :\n");
836
837 if (single)
838 {
839 DBG("\ts%d <= [%x]\n", d, imm);
840 state->ExtReg[d] = imm;
841 }
842 else
843 {
844 /* Check endian please */
845 DBG("\ts[%d-%d] <= [%x-%x]\n", d*2+1, d*2, imm, 0);
846 state->ExtReg[d*2+1] = imm;
847 state->ExtReg[d*2] = 0;
848 }
849}
850void VMOVR(ARMul_State* state, ARMword single, ARMword d, ARMword m)
851{
852 DBG("VMOV(R) :\n");
853
854 if (single)
855 {
856 DBG("\ts%d <= s%d[%x]\n", d, m, state->ExtReg[m]);
857 state->ExtReg[d] = state->ExtReg[m];
858 }
859 else
860 {
861 /* Check endian please */
862 DBG("\ts[%d-%d] <= s[%d-%d][%x-%x]\n", d*2+1, d*2, m*2+1, m*2, state->ExtReg[m*2+1], state->ExtReg[m*2]);
863 state->ExtReg[d*2+1] = state->ExtReg[m*2+1];
864 state->ExtReg[d*2] = state->ExtReg[m*2];
865 }
866}
340 867
341/* Miscellaneous functions */ 868/* Miscellaneous functions */
342int32_t vfp_get_float(arm_core_t* state, unsigned int reg) 869int32_t vfp_get_float(arm_core_t* state, unsigned int reg)
@@ -366,8 +893,6 @@ void vfp_put_double(arm_core_t* state, uint64_t val, unsigned int reg)
366 state->ExtReg[reg*2+1] = (uint32_t) (val>>32); 893 state->ExtReg[reg*2+1] = (uint32_t) (val>>32);
367} 894}
368 895
369
370
371/* 896/*
372 * Process bitmask of exception conditions. (from vfpmodule.c) 897 * Process bitmask of exception conditions. (from vfpmodule.c)
373 */ 898 */
diff --git a/src/core/arm/skyeye_common/vfp/vfp.h b/src/core/arm/skyeye_common/vfp/vfp.h
index 7256701f3..f9e8d521d 100644
--- a/src/core/arm/skyeye_common/vfp/vfp.h
+++ b/src/core/arm/skyeye_common/vfp/vfp.h
@@ -27,6 +27,12 @@
27 27
28#include "core/arm/skyeye_common/vfp/vfp_helper.h" /* for references to cdp SoftFloat functions */ 28#include "core/arm/skyeye_common/vfp/vfp_helper.h" /* for references to cdp SoftFloat functions */
29 29
30#define VFP_DEBUG_TRANSLATE DBG("in func %s, %x\n", __FUNCTION__, inst);
31#define VFP_DEBUG_UNIMPLEMENTED(x) printf("in func %s, " #x " unimplemented\n", __FUNCTION__); exit(-1);
32#define VFP_DEBUG_UNTESTED(x) printf("in func %s, " #x " untested\n", __FUNCTION__);
33#define CHECK_VFP_ENABLED
34#define CHECK_VFP_CDP_RET vfp_raise_exceptions(cpu, ret, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); //if (ret == -1) {printf("VFP CDP FAILURE %x\n", inst_cream->instr); exit(-1);}
35
30unsigned VFPInit (ARMul_State *state); 36unsigned VFPInit (ARMul_State *state);
31unsigned VFPMRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value); 37unsigned VFPMRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value);
32unsigned VFPMCR (ARMul_State * state, unsigned type, ARMword instr, ARMword value); 38unsigned VFPMCR (ARMul_State * state, unsigned type, ARMword instr, ARMword value);
diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
index 45208fb13..27dc8a008 100644
--- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
@@ -28,34 +28,19 @@
28/* ----------------------------------------------------------------------- */ 28/* ----------------------------------------------------------------------- */
29/* VMLA */ 29/* VMLA */
30/* cond 1110 0D00 Vn-- Vd-- 101X N0M0 Vm-- */ 30/* cond 1110 0D00 Vn-- Vd-- 101X N0M0 Vm-- */
31#define vfpinstr vmla
32#define vfpinstr_inst vmla_inst
33#define VFPLABEL_INST VMLA_INST
34#ifdef VFP_DECODE
35{"vmla", 4, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0},
36#endif
37#ifdef VFP_DECODE_EXCLUSION
38{"vmla", 0, ARMVFP2, 0},
39#endif
40#ifdef VFP_INTERPRETER_TABLE
41INTERPRETER_TRANSLATE(vfpinstr),
42#endif
43#ifdef VFP_INTERPRETER_LABEL
44&&VFPLABEL_INST,
45#endif
46#ifdef VFP_INTERPRETER_STRUCT 31#ifdef VFP_INTERPRETER_STRUCT
47typedef struct _vmla_inst { 32typedef struct _vmla_inst {
48 unsigned int instr; 33 unsigned int instr;
49 unsigned int dp_operation; 34 unsigned int dp_operation;
50} vfpinstr_inst; 35} vmla_inst;
51#endif 36#endif
52#ifdef VFP_INTERPRETER_TRANS 37#ifdef VFP_INTERPRETER_TRANS
53ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 38ARM_INST_PTR INTERPRETER_TRANSLATE(vmla)(unsigned int inst, int index)
54{ 39{
55 VFP_DEBUG_TRANSLATE; 40 VFP_DEBUG_TRANSLATE;
56 41
57 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 42 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmla_inst));
58 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 43 vmla_inst *inst_cream = (vmla_inst *)inst_base->component;
59 44
60 inst_base->cond = BITS(inst, 28, 31); 45 inst_base->cond = BITS(inst, 28, 31);
61 inst_base->idx = index; 46 inst_base->idx = index;
@@ -69,15 +54,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
69} 54}
70#endif 55#endif
71#ifdef VFP_INTERPRETER_IMPL 56#ifdef VFP_INTERPRETER_IMPL
72VFPLABEL_INST: 57VMLA_INST:
73{ 58{
74 INC_ICOUNTER;
75 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 59 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
76 CHECK_VFP_ENABLED; 60 CHECK_VFP_ENABLED;
77 61
78 DBG("VMLA :\n"); 62 DBG("VMLA :\n");
79 63
80 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 64 vmla_inst *inst_cream = (vmla_inst *)inst_base->component;
81 65
82 int ret; 66 int ret;
83 67
@@ -89,22 +73,17 @@ VFPLABEL_INST:
89 CHECK_VFP_CDP_RET; 73 CHECK_VFP_CDP_RET;
90 } 74 }
91 cpu->Reg[15] += GET_INST_SIZE(cpu); 75 cpu->Reg[15] += GET_INST_SIZE(cpu);
92 INC_PC(sizeof(vfpinstr_inst)); 76 INC_PC(sizeof(vmla_inst));
93 FETCH_INST; 77 FETCH_INST;
94 GOTO_NEXT_INST; 78 GOTO_NEXT_INST;
95} 79}
96#endif 80#endif
97#ifdef VFP_CDP_TRANS 81
98if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 0)
99{
100 DBG("VMLA :\n");
101}
102#endif
103#ifdef VFP_DYNCOM_TABLE 82#ifdef VFP_DYNCOM_TABLE
104DYNCOM_FILL_ACTION(vfpinstr), 83DYNCOM_FILL_ACTION(vmla),
105#endif 84#endif
106#ifdef VFP_DYNCOM_TAG 85#ifdef VFP_DYNCOM_TAG
107int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 86int DYNCOM_TAG(vmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
108{ 87{
109 int instr_size = INSTR_SIZE; 88 int instr_size = INSTR_SIZE;
110 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 89 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -114,7 +93,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
114} 93}
115#endif 94#endif
116#ifdef VFP_DYNCOM_TRANS 95#ifdef VFP_DYNCOM_TRANS
117int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 96int DYNCOM_TRANS(vmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
118 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 97 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
119 //arch_arm_undef(cpu, bb, instr); 98 //arch_arm_undef(cpu, bb, instr);
120 int m; 99 int m;
@@ -168,41 +147,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
168 return No_exp; 147 return No_exp;
169} 148}
170#endif 149#endif
171#undef vfpinstr
172#undef vfpinstr_inst
173#undef VFPLABEL_INST
174 150
175/* ----------------------------------------------------------------------- */ 151/* ----------------------------------------------------------------------- */
176/* VNMLS */ 152/* VNMLS */
177/* cond 1110 0D00 Vn-- Vd-- 101X N1M0 Vm-- */ 153/* cond 1110 0D00 Vn-- Vd-- 101X N1M0 Vm-- */
178#define vfpinstr vmls
179#define vfpinstr_inst vmls_inst
180#define VFPLABEL_INST VMLS_INST
181#ifdef VFP_DECODE
182{"vmls", 7, ARMVFP2, 28 , 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0},
183#endif
184#ifdef VFP_DECODE_EXCLUSION
185{"vmls", 0, ARMVFP2, 0},
186#endif
187#ifdef VFP_INTERPRETER_TABLE
188INTERPRETER_TRANSLATE(vfpinstr),
189#endif
190#ifdef VFP_INTERPRETER_LABEL
191&&VFPLABEL_INST,
192#endif
193#ifdef VFP_INTERPRETER_STRUCT 154#ifdef VFP_INTERPRETER_STRUCT
194typedef struct _vmls_inst { 155typedef struct _vmls_inst {
195 unsigned int instr; 156 unsigned int instr;
196 unsigned int dp_operation; 157 unsigned int dp_operation;
197} vfpinstr_inst; 158} vmls_inst;
198#endif 159#endif
199#ifdef VFP_INTERPRETER_TRANS 160#ifdef VFP_INTERPRETER_TRANS
200ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 161ARM_INST_PTR INTERPRETER_TRANSLATE(vmls)(unsigned int inst, int index)
201{ 162{
202 VFP_DEBUG_TRANSLATE; 163 VFP_DEBUG_TRANSLATE;
203 164
204 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 165 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmls_inst));
205 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 166 vmls_inst *inst_cream = (vmls_inst *)inst_base->component;
206 167
207 inst_base->cond = BITS(inst, 28, 31); 168 inst_base->cond = BITS(inst, 28, 31);
208 inst_base->idx = index; 169 inst_base->idx = index;
@@ -216,15 +177,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
216} 177}
217#endif 178#endif
218#ifdef VFP_INTERPRETER_IMPL 179#ifdef VFP_INTERPRETER_IMPL
219VFPLABEL_INST: 180VMLS_INST:
220{ 181{
221 INC_ICOUNTER;
222 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 182 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
223 CHECK_VFP_ENABLED; 183 CHECK_VFP_ENABLED;
224 184
225 DBG("VMLS :\n"); 185 DBG("VMLS :\n");
226 186
227 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 187 vmls_inst *inst_cream = (vmls_inst *)inst_base->component;
228 188
229 int ret; 189 int ret;
230 190
@@ -236,22 +196,17 @@ VFPLABEL_INST:
236 CHECK_VFP_CDP_RET; 196 CHECK_VFP_CDP_RET;
237 } 197 }
238 cpu->Reg[15] += GET_INST_SIZE(cpu); 198 cpu->Reg[15] += GET_INST_SIZE(cpu);
239 INC_PC(sizeof(vfpinstr_inst)); 199 INC_PC(sizeof(vmls_inst));
240 FETCH_INST; 200 FETCH_INST;
241 GOTO_NEXT_INST; 201 GOTO_NEXT_INST;
242} 202}
243#endif 203#endif
244#ifdef VFP_CDP_TRANS 204
245if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 2)
246{
247 DBG("VMLS :\n");
248}
249#endif
250#ifdef VFP_DYNCOM_TABLE 205#ifdef VFP_DYNCOM_TABLE
251DYNCOM_FILL_ACTION(vfpinstr), 206DYNCOM_FILL_ACTION(vmls),
252#endif 207#endif
253#ifdef VFP_DYNCOM_TAG 208#ifdef VFP_DYNCOM_TAG
254int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 209int DYNCOM_TAG(vmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
255{ 210{
256 int instr_size = INSTR_SIZE; 211 int instr_size = INSTR_SIZE;
257 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 212 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -261,7 +216,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
261} 216}
262#endif 217#endif
263#ifdef VFP_DYNCOM_TRANS 218#ifdef VFP_DYNCOM_TRANS
264int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 219int DYNCOM_TRANS(vmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
265 DBG("\t\tin %s VMLS instruction is executed out of here.\n", __FUNCTION__); 220 DBG("\t\tin %s VMLS instruction is executed out of here.\n", __FUNCTION__);
266 //arch_arm_undef(cpu, bb, instr); 221 //arch_arm_undef(cpu, bb, instr);
267 int m; 222 int m;
@@ -315,47 +270,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
315 return No_exp; 270 return No_exp;
316} 271}
317#endif 272#endif
318#undef vfpinstr
319#undef vfpinstr_inst
320#undef VFPLABEL_INST
321 273
322/* ----------------------------------------------------------------------- */ 274/* ----------------------------------------------------------------------- */
323/* VNMLA */ 275/* VNMLA */
324/* cond 1110 0D01 Vn-- Vd-- 101X N1M0 Vm-- */ 276/* cond 1110 0D01 Vn-- Vd-- 101X N1M0 Vm-- */
325#define vfpinstr vnmla
326#define vfpinstr_inst vnmla_inst
327#define VFPLABEL_INST VNMLA_INST
328#ifdef VFP_DECODE
329//{"vnmla", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
330{"vnmla", 4, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0},
331{"vnmla", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
332//{"vnmla", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
333#endif
334#ifdef VFP_DECODE_EXCLUSION
335{"vnmla", 0, ARMVFP2, 0},
336{"vnmla", 0, ARMVFP2, 0},
337#endif
338#ifdef VFP_INTERPRETER_TABLE
339INTERPRETER_TRANSLATE(vfpinstr),
340INTERPRETER_TRANSLATE(vfpinstr),
341#endif
342#ifdef VFP_INTERPRETER_LABEL
343&&VFPLABEL_INST,
344&&VFPLABEL_INST,
345#endif
346#ifdef VFP_INTERPRETER_STRUCT 277#ifdef VFP_INTERPRETER_STRUCT
347typedef struct _vnmla_inst { 278typedef struct _vnmla_inst {
348 unsigned int instr; 279 unsigned int instr;
349 unsigned int dp_operation; 280 unsigned int dp_operation;
350} vfpinstr_inst; 281} vnmla_inst;
351#endif 282#endif
352#ifdef VFP_INTERPRETER_TRANS 283#ifdef VFP_INTERPRETER_TRANS
353ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 284ARM_INST_PTR INTERPRETER_TRANSLATE(vnmla)(unsigned int inst, int index)
354{ 285{
355 VFP_DEBUG_TRANSLATE; 286 VFP_DEBUG_TRANSLATE;
356 287
357 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 288 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmla_inst));
358 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 289 vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component;
359 290
360 inst_base->cond = BITS(inst, 28, 31); 291 inst_base->cond = BITS(inst, 28, 31);
361 inst_base->idx = index; 292 inst_base->idx = index;
@@ -369,15 +300,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
369} 300}
370#endif 301#endif
371#ifdef VFP_INTERPRETER_IMPL 302#ifdef VFP_INTERPRETER_IMPL
372VFPLABEL_INST: 303VNMLA_INST:
373{ 304{
374 INC_ICOUNTER;
375 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 305 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
376 CHECK_VFP_ENABLED; 306 CHECK_VFP_ENABLED;
377 307
378 DBG("VNMLA :\n"); 308 DBG("VNMLA :\n");
379 309
380 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 310 vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component;
381 311
382 int ret; 312 int ret;
383 313
@@ -389,23 +319,18 @@ VFPLABEL_INST:
389 CHECK_VFP_CDP_RET; 319 CHECK_VFP_CDP_RET;
390 } 320 }
391 cpu->Reg[15] += GET_INST_SIZE(cpu); 321 cpu->Reg[15] += GET_INST_SIZE(cpu);
392 INC_PC(sizeof(vfpinstr_inst)); 322 INC_PC(sizeof(vnmla_inst));
393 FETCH_INST; 323 FETCH_INST;
394 GOTO_NEXT_INST; 324 GOTO_NEXT_INST;
395} 325}
396#endif 326#endif
397#ifdef VFP_CDP_TRANS 327
398if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 2)
399{
400 DBG("VNMLA :\n");
401}
402#endif
403#ifdef VFP_DYNCOM_TABLE 328#ifdef VFP_DYNCOM_TABLE
404DYNCOM_FILL_ACTION(vfpinstr), 329DYNCOM_FILL_ACTION(vnmla),
405DYNCOM_FILL_ACTION(vfpinstr), 330DYNCOM_FILL_ACTION(vnmla),
406#endif 331#endif
407#ifdef VFP_DYNCOM_TAG 332#ifdef VFP_DYNCOM_TAG
408int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 333int DYNCOM_TAG(vnmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
409{ 334{
410 int instr_size = INSTR_SIZE; 335 int instr_size = INSTR_SIZE;
411 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 336 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -415,7 +340,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
415} 340}
416#endif 341#endif
417#ifdef VFP_DYNCOM_TRANS 342#ifdef VFP_DYNCOM_TRANS
418int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 343int DYNCOM_TRANS(vnmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
419 DBG("\t\tin %s VNMLA instruction is executed out of here.\n", __FUNCTION__); 344 DBG("\t\tin %s VNMLA instruction is executed out of here.\n", __FUNCTION__);
420 //arch_arm_undef(cpu, bb, instr); 345 //arch_arm_undef(cpu, bb, instr);
421 int m; 346 int m;
@@ -469,41 +394,24 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
469 return No_exp; 394 return No_exp;
470} 395}
471#endif 396#endif
472#undef vfpinstr
473#undef vfpinstr_inst
474#undef VFPLABEL_INST
475 397
476/* ----------------------------------------------------------------------- */ 398/* ----------------------------------------------------------------------- */
477/* VNMLS */ 399/* VNMLS */
478/* cond 1110 0D01 Vn-- Vd-- 101X N0M0 Vm-- */ 400/* cond 1110 0D01 Vn-- Vd-- 101X N0M0 Vm-- */
479#define vfpinstr vnmls 401
480#define vfpinstr_inst vnmls_inst
481#define VFPLABEL_INST VNMLS_INST
482#ifdef VFP_DECODE
483{"vnmls", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x1, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
484#endif
485#ifdef VFP_DECODE_EXCLUSION
486{"vnmls", 0, ARMVFP2, 0},
487#endif
488#ifdef VFP_INTERPRETER_TABLE
489INTERPRETER_TRANSLATE(vfpinstr),
490#endif
491#ifdef VFP_INTERPRETER_LABEL
492&&VFPLABEL_INST,
493#endif
494#ifdef VFP_INTERPRETER_STRUCT 402#ifdef VFP_INTERPRETER_STRUCT
495typedef struct _vnmls_inst { 403typedef struct _vnmls_inst {
496 unsigned int instr; 404 unsigned int instr;
497 unsigned int dp_operation; 405 unsigned int dp_operation;
498} vfpinstr_inst; 406} vnmls_inst;
499#endif 407#endif
500#ifdef VFP_INTERPRETER_TRANS 408#ifdef VFP_INTERPRETER_TRANS
501ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 409ARM_INST_PTR INTERPRETER_TRANSLATE(vnmls)(unsigned int inst, int index)
502{ 410{
503 VFP_DEBUG_TRANSLATE; 411 VFP_DEBUG_TRANSLATE;
504 412
505 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 413 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmls_inst));
506 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 414 vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component;
507 415
508 inst_base->cond = BITS(inst, 28, 31); 416 inst_base->cond = BITS(inst, 28, 31);
509 inst_base->idx = index; 417 inst_base->idx = index;
@@ -517,15 +425,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
517} 425}
518#endif 426#endif
519#ifdef VFP_INTERPRETER_IMPL 427#ifdef VFP_INTERPRETER_IMPL
520VFPLABEL_INST: 428VNMLS_INST:
521{ 429{
522 INC_ICOUNTER;
523 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 430 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
524 CHECK_VFP_ENABLED; 431 CHECK_VFP_ENABLED;
525 432
526 DBG("VNMLS :\n"); 433 DBG("VNMLS :\n");
527 434
528 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 435 vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component;
529 436
530 int ret; 437 int ret;
531 438
@@ -537,22 +444,17 @@ VFPLABEL_INST:
537 CHECK_VFP_CDP_RET; 444 CHECK_VFP_CDP_RET;
538 } 445 }
539 cpu->Reg[15] += GET_INST_SIZE(cpu); 446 cpu->Reg[15] += GET_INST_SIZE(cpu);
540 INC_PC(sizeof(vfpinstr_inst)); 447 INC_PC(sizeof(vnmls_inst));
541 FETCH_INST; 448 FETCH_INST;
542 GOTO_NEXT_INST; 449 GOTO_NEXT_INST;
543} 450}
544#endif 451#endif
545#ifdef VFP_CDP_TRANS 452
546if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 0)
547{
548 DBG("VNMLS :\n");
549}
550#endif
551#ifdef VFP_DYNCOM_TABLE 453#ifdef VFP_DYNCOM_TABLE
552DYNCOM_FILL_ACTION(vfpinstr), 454DYNCOM_FILL_ACTION(vnmls),
553#endif 455#endif
554#ifdef VFP_DYNCOM_TAG 456#ifdef VFP_DYNCOM_TAG
555int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 457int DYNCOM_TAG(vnmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
556{ 458{
557 int instr_size = INSTR_SIZE; 459 int instr_size = INSTR_SIZE;
558 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 460 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -562,7 +464,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
562} 464}
563#endif 465#endif
564#ifdef VFP_DYNCOM_TRANS 466#ifdef VFP_DYNCOM_TRANS
565int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 467int DYNCOM_TRANS(vnmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
566 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 468 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
567 //arch_arm_undef(cpu, bb, instr); 469 //arch_arm_undef(cpu, bb, instr);
568 int m; 470 int m;
@@ -616,41 +518,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
616 return No_exp; 518 return No_exp;
617} 519}
618#endif 520#endif
619#undef vfpinstr
620#undef vfpinstr_inst
621#undef VFPLABEL_INST
622 521
623/* ----------------------------------------------------------------------- */ 522/* ----------------------------------------------------------------------- */
624/* VNMUL */ 523/* VNMUL */
625/* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */ 524/* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */
626#define vfpinstr vnmul
627#define vfpinstr_inst vnmul_inst
628#define VFPLABEL_INST VNMUL_INST
629#ifdef VFP_DECODE
630{"vnmul", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
631#endif
632#ifdef VFP_DECODE_EXCLUSION
633{"vnmul", 0, ARMVFP2, 0},
634#endif
635#ifdef VFP_INTERPRETER_TABLE
636INTERPRETER_TRANSLATE(vfpinstr),
637#endif
638#ifdef VFP_INTERPRETER_LABEL
639&&VFPLABEL_INST,
640#endif
641#ifdef VFP_INTERPRETER_STRUCT 525#ifdef VFP_INTERPRETER_STRUCT
642typedef struct _vnmul_inst { 526typedef struct _vnmul_inst {
643 unsigned int instr; 527 unsigned int instr;
644 unsigned int dp_operation; 528 unsigned int dp_operation;
645} vfpinstr_inst; 529} vnmul_inst;
646#endif 530#endif
647#ifdef VFP_INTERPRETER_TRANS 531#ifdef VFP_INTERPRETER_TRANS
648ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 532ARM_INST_PTR INTERPRETER_TRANSLATE(vnmul)(unsigned int inst, int index)
649{ 533{
650 VFP_DEBUG_TRANSLATE; 534 VFP_DEBUG_TRANSLATE;
651 535
652 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 536 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmul_inst));
653 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 537 vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component;
654 538
655 inst_base->cond = BITS(inst, 28, 31); 539 inst_base->cond = BITS(inst, 28, 31);
656 inst_base->idx = index; 540 inst_base->idx = index;
@@ -664,15 +548,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
664} 548}
665#endif 549#endif
666#ifdef VFP_INTERPRETER_IMPL 550#ifdef VFP_INTERPRETER_IMPL
667VFPLABEL_INST: 551VNMUL_INST:
668{ 552{
669 INC_ICOUNTER;
670 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 553 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
671 CHECK_VFP_ENABLED; 554 CHECK_VFP_ENABLED;
672 555
673 DBG("VNMUL :\n"); 556 DBG("VNMUL :\n");
674 557
675 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 558 vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component;
676 559
677 int ret; 560 int ret;
678 561
@@ -684,22 +567,17 @@ VFPLABEL_INST:
684 CHECK_VFP_CDP_RET; 567 CHECK_VFP_CDP_RET;
685 } 568 }
686 cpu->Reg[15] += GET_INST_SIZE(cpu); 569 cpu->Reg[15] += GET_INST_SIZE(cpu);
687 INC_PC(sizeof(vfpinstr_inst)); 570 INC_PC(sizeof(vnmul_inst));
688 FETCH_INST; 571 FETCH_INST;
689 GOTO_NEXT_INST; 572 GOTO_NEXT_INST;
690} 573}
691#endif 574#endif
692#ifdef VFP_CDP_TRANS 575
693if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 2)
694{
695 DBG("VNMUL :\n");
696}
697#endif
698#ifdef VFP_DYNCOM_TABLE 576#ifdef VFP_DYNCOM_TABLE
699DYNCOM_FILL_ACTION(vfpinstr), 577DYNCOM_FILL_ACTION(vnmul),
700#endif 578#endif
701#ifdef VFP_DYNCOM_TAG 579#ifdef VFP_DYNCOM_TAG
702int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 580int DYNCOM_TAG(vnmul)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
703{ 581{
704 int instr_size = INSTR_SIZE; 582 int instr_size = INSTR_SIZE;
705 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 583 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -709,7 +587,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
709} 587}
710#endif 588#endif
711#ifdef VFP_DYNCOM_TRANS 589#ifdef VFP_DYNCOM_TRANS
712int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 590int DYNCOM_TRANS(vnmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
713 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 591 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
714 //arch_arm_undef(cpu, bb, instr); 592 //arch_arm_undef(cpu, bb, instr);
715 int m; 593 int m;
@@ -753,41 +631,24 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
753 return No_exp; 631 return No_exp;
754} 632}
755#endif 633#endif
756#undef vfpinstr 634
757#undef vfpinstr_inst
758#undef VFPLABEL_INST
759 635
760/* ----------------------------------------------------------------------- */ 636/* ----------------------------------------------------------------------- */
761/* VMUL */ 637/* VMUL */
762/* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */ 638/* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */
763#define vfpinstr vmul
764#define vfpinstr_inst vmul_inst
765#define VFPLABEL_INST VMUL_INST
766#ifdef VFP_DECODE
767{"vmul", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
768#endif
769#ifdef VFP_DECODE_EXCLUSION
770{"vmul", 0, ARMVFP2, 0},
771#endif
772#ifdef VFP_INTERPRETER_TABLE
773INTERPRETER_TRANSLATE(vfpinstr),
774#endif
775#ifdef VFP_INTERPRETER_LABEL
776&&VFPLABEL_INST,
777#endif
778#ifdef VFP_INTERPRETER_STRUCT 639#ifdef VFP_INTERPRETER_STRUCT
779typedef struct _vmul_inst { 640typedef struct _vmul_inst {
780 unsigned int instr; 641 unsigned int instr;
781 unsigned int dp_operation; 642 unsigned int dp_operation;
782} vfpinstr_inst; 643} vmul_inst;
783#endif 644#endif
784#ifdef VFP_INTERPRETER_TRANS 645#ifdef VFP_INTERPRETER_TRANS
785ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 646ARM_INST_PTR INTERPRETER_TRANSLATE(vmul)(unsigned int inst, int index)
786{ 647{
787 VFP_DEBUG_TRANSLATE; 648 VFP_DEBUG_TRANSLATE;
788 649
789 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 650 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmul_inst));
790 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 651 vmul_inst *inst_cream = (vmul_inst *)inst_base->component;
791 652
792 inst_base->cond = BITS(inst, 28, 31); 653 inst_base->cond = BITS(inst, 28, 31);
793 inst_base->idx = index; 654 inst_base->idx = index;
@@ -801,15 +662,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
801} 662}
802#endif 663#endif
803#ifdef VFP_INTERPRETER_IMPL 664#ifdef VFP_INTERPRETER_IMPL
804VFPLABEL_INST: 665VMUL_INST:
805{ 666{
806 INC_ICOUNTER;
807 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 667 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
808 CHECK_VFP_ENABLED; 668 CHECK_VFP_ENABLED;
809 669
810 DBG("VMUL :\n"); 670 DBG("VMUL :\n");
811 671
812 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 672 vmul_inst *inst_cream = (vmul_inst *)inst_base->component;
813 673
814 int ret; 674 int ret;
815 675
@@ -821,22 +681,17 @@ VFPLABEL_INST:
821 CHECK_VFP_CDP_RET; 681 CHECK_VFP_CDP_RET;
822 } 682 }
823 cpu->Reg[15] += GET_INST_SIZE(cpu); 683 cpu->Reg[15] += GET_INST_SIZE(cpu);
824 INC_PC(sizeof(vfpinstr_inst)); 684 INC_PC(sizeof(vmul_inst));
825 FETCH_INST; 685 FETCH_INST;
826 GOTO_NEXT_INST; 686 GOTO_NEXT_INST;
827} 687}
828#endif 688#endif
829#ifdef VFP_CDP_TRANS 689
830if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 0)
831{
832 DBG("VMUL :\n");
833}
834#endif
835#ifdef VFP_DYNCOM_TABLE 690#ifdef VFP_DYNCOM_TABLE
836DYNCOM_FILL_ACTION(vfpinstr), 691DYNCOM_FILL_ACTION(vmul),
837#endif 692#endif
838#ifdef VFP_DYNCOM_TAG 693#ifdef VFP_DYNCOM_TAG
839int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 694int DYNCOM_TAG(vmul)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
840{ 695{
841 int instr_size = INSTR_SIZE; 696 int instr_size = INSTR_SIZE;
842 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 697 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -846,7 +701,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
846} 701}
847#endif 702#endif
848#ifdef VFP_DYNCOM_TRANS 703#ifdef VFP_DYNCOM_TRANS
849int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 704int DYNCOM_TRANS(vmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
850 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 705 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
851 //printf("\n\n\t\tin %s instruction is executed out.\n\n", __FUNCTION__); 706 //printf("\n\n\t\tin %s instruction is executed out.\n\n", __FUNCTION__);
852 //arch_arm_undef(cpu, bb, instr); 707 //arch_arm_undef(cpu, bb, instr);
@@ -904,41 +759,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
904 return No_exp; 759 return No_exp;
905} 760}
906#endif 761#endif
907#undef vfpinstr
908#undef vfpinstr_inst
909#undef VFPLABEL_INST
910 762
911/* ----------------------------------------------------------------------- */ 763/* ----------------------------------------------------------------------- */
912/* VADD */ 764/* VADD */
913/* cond 1110 0D11 Vn-- Vd-- 101X N0M0 Vm-- */ 765/* cond 1110 0D11 Vn-- Vd-- 101X N0M0 Vm-- */
914#define vfpinstr vadd
915#define vfpinstr_inst vadd_inst
916#define VFPLABEL_INST VADD_INST
917#ifdef VFP_DECODE
918{"vadd", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
919#endif
920#ifdef VFP_DECODE_EXCLUSION
921{"vadd", 0, ARMVFP2, 0},
922#endif
923#ifdef VFP_INTERPRETER_TABLE
924INTERPRETER_TRANSLATE(vfpinstr),
925#endif
926#ifdef VFP_INTERPRETER_LABEL
927&&VFPLABEL_INST,
928#endif
929#ifdef VFP_INTERPRETER_STRUCT 766#ifdef VFP_INTERPRETER_STRUCT
930typedef struct _vadd_inst { 767typedef struct _vadd_inst {
931 unsigned int instr; 768 unsigned int instr;
932 unsigned int dp_operation; 769 unsigned int dp_operation;
933} vfpinstr_inst; 770} vadd_inst;
934#endif 771#endif
935#ifdef VFP_INTERPRETER_TRANS 772#ifdef VFP_INTERPRETER_TRANS
936ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 773ARM_INST_PTR INTERPRETER_TRANSLATE(vadd)(unsigned int inst, int index)
937{ 774{
938 VFP_DEBUG_TRANSLATE; 775 VFP_DEBUG_TRANSLATE;
939 776
940 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 777 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vadd_inst));
941 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 778 vadd_inst *inst_cream = (vadd_inst *)inst_base->component;
942 779
943 inst_base->cond = BITS(inst, 28, 31); 780 inst_base->cond = BITS(inst, 28, 31);
944 inst_base->idx = index; 781 inst_base->idx = index;
@@ -952,15 +789,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
952} 789}
953#endif 790#endif
954#ifdef VFP_INTERPRETER_IMPL 791#ifdef VFP_INTERPRETER_IMPL
955VFPLABEL_INST: 792VADD_INST:
956{ 793{
957 INC_ICOUNTER;
958 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 794 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
959 CHECK_VFP_ENABLED; 795 CHECK_VFP_ENABLED;
960 796
961 DBG("VADD :\n"); 797 DBG("VADD :\n");
962 798
963 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 799 vadd_inst *inst_cream = (vadd_inst *)inst_base->component;
964 800
965 int ret; 801 int ret;
966 802
@@ -972,22 +808,17 @@ VFPLABEL_INST:
972 CHECK_VFP_CDP_RET; 808 CHECK_VFP_CDP_RET;
973 } 809 }
974 cpu->Reg[15] += GET_INST_SIZE(cpu); 810 cpu->Reg[15] += GET_INST_SIZE(cpu);
975 INC_PC(sizeof(vfpinstr_inst)); 811 INC_PC(sizeof(vadd_inst));
976 FETCH_INST; 812 FETCH_INST;
977 GOTO_NEXT_INST; 813 GOTO_NEXT_INST;
978} 814}
979#endif 815#endif
980#ifdef VFP_CDP_TRANS 816
981if ((OPC_1 & 0xB) == 3 && (OPC_2 & 0x2) == 0)
982{
983 DBG("VADD :\n");
984}
985#endif
986#ifdef VFP_DYNCOM_TABLE 817#ifdef VFP_DYNCOM_TABLE
987DYNCOM_FILL_ACTION(vfpinstr), 818DYNCOM_FILL_ACTION(vadd),
988#endif 819#endif
989#ifdef VFP_DYNCOM_TAG 820#ifdef VFP_DYNCOM_TAG
990int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 821int DYNCOM_TAG(vadd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
991{ 822{
992 int instr_size = INSTR_SIZE; 823 int instr_size = INSTR_SIZE;
993 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 824 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -997,7 +828,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
997} 828}
998#endif 829#endif
999#ifdef VFP_DYNCOM_TRANS 830#ifdef VFP_DYNCOM_TRANS
1000int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 831int DYNCOM_TRANS(vadd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1001 DBG("\t\tin %s instruction will implement out of JIT.\n", __FUNCTION__); 832 DBG("\t\tin %s instruction will implement out of JIT.\n", __FUNCTION__);
1002 //arch_arm_undef(cpu, bb, instr); 833 //arch_arm_undef(cpu, bb, instr);
1003 int m; 834 int m;
@@ -1049,41 +880,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
1049 return No_exp; 880 return No_exp;
1050} 881}
1051#endif 882#endif
1052#undef vfpinstr
1053#undef vfpinstr_inst
1054#undef VFPLABEL_INST
1055 883
1056/* ----------------------------------------------------------------------- */ 884/* ----------------------------------------------------------------------- */
1057/* VSUB */ 885/* VSUB */
1058/* cond 1110 0D11 Vn-- Vd-- 101X N1M0 Vm-- */ 886/* cond 1110 0D11 Vn-- Vd-- 101X N1M0 Vm-- */
1059#define vfpinstr vsub
1060#define vfpinstr_inst vsub_inst
1061#define VFPLABEL_INST VSUB_INST
1062#ifdef VFP_DECODE
1063{"vsub", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
1064#endif
1065#ifdef VFP_DECODE_EXCLUSION
1066{"vsub", 0, ARMVFP2, 0},
1067#endif
1068#ifdef VFP_INTERPRETER_TABLE
1069INTERPRETER_TRANSLATE(vfpinstr),
1070#endif
1071#ifdef VFP_INTERPRETER_LABEL
1072&&VFPLABEL_INST,
1073#endif
1074#ifdef VFP_INTERPRETER_STRUCT 887#ifdef VFP_INTERPRETER_STRUCT
1075typedef struct _vsub_inst { 888typedef struct _vsub_inst {
1076 unsigned int instr; 889 unsigned int instr;
1077 unsigned int dp_operation; 890 unsigned int dp_operation;
1078} vfpinstr_inst; 891} vsub_inst;
1079#endif 892#endif
1080#ifdef VFP_INTERPRETER_TRANS 893#ifdef VFP_INTERPRETER_TRANS
1081ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 894ARM_INST_PTR INTERPRETER_TRANSLATE(vsub)(unsigned int inst, int index)
1082{ 895{
1083 VFP_DEBUG_TRANSLATE; 896 VFP_DEBUG_TRANSLATE;
1084 897
1085 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 898 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsub_inst));
1086 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 899 vsub_inst *inst_cream = (vsub_inst *)inst_base->component;
1087 900
1088 inst_base->cond = BITS(inst, 28, 31); 901 inst_base->cond = BITS(inst, 28, 31);
1089 inst_base->idx = index; 902 inst_base->idx = index;
@@ -1097,15 +910,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
1097} 910}
1098#endif 911#endif
1099#ifdef VFP_INTERPRETER_IMPL 912#ifdef VFP_INTERPRETER_IMPL
1100VFPLABEL_INST: 913VSUB_INST:
1101{ 914{
1102 INC_ICOUNTER;
1103 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 915 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1104 CHECK_VFP_ENABLED; 916 CHECK_VFP_ENABLED;
1105 917
1106 DBG("VSUB :\n"); 918 DBG("VSUB :\n");
1107 919
1108 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 920 vsub_inst *inst_cream = (vsub_inst *)inst_base->component;
1109 921
1110 int ret; 922 int ret;
1111 923
@@ -1117,22 +929,16 @@ VFPLABEL_INST:
1117 CHECK_VFP_CDP_RET; 929 CHECK_VFP_CDP_RET;
1118 } 930 }
1119 cpu->Reg[15] += GET_INST_SIZE(cpu); 931 cpu->Reg[15] += GET_INST_SIZE(cpu);
1120 INC_PC(sizeof(vfpinstr_inst)); 932 INC_PC(sizeof(vsub_inst));
1121 FETCH_INST; 933 FETCH_INST;
1122 GOTO_NEXT_INST; 934 GOTO_NEXT_INST;
1123} 935}
1124#endif 936#endif
1125#ifdef VFP_CDP_TRANS
1126if ((OPC_1 & 0xB) == 3 && (OPC_2 & 0x2) == 2)
1127{
1128 DBG("VSUB :\n");
1129}
1130#endif
1131#ifdef VFP_DYNCOM_TABLE 937#ifdef VFP_DYNCOM_TABLE
1132DYNCOM_FILL_ACTION(vfpinstr), 938DYNCOM_FILL_ACTION(vsub),
1133#endif 939#endif
1134#ifdef VFP_DYNCOM_TAG 940#ifdef VFP_DYNCOM_TAG
1135int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 941int DYNCOM_TAG(vsub)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1136{ 942{
1137 int instr_size = INSTR_SIZE; 943 int instr_size = INSTR_SIZE;
1138 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 944 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
@@ -1141,7 +947,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
1141} 947}
1142#endif 948#endif
1143#ifdef VFP_DYNCOM_TRANS 949#ifdef VFP_DYNCOM_TRANS
1144int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 950int DYNCOM_TRANS(vsub)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1145 DBG("\t\tin %s instr=0x%x, instruction is executed out of JIT.\n", __FUNCTION__, instr); 951 DBG("\t\tin %s instr=0x%x, instruction is executed out of JIT.\n", __FUNCTION__, instr);
1146 //arch_arm_undef(cpu, bb, instr); 952 //arch_arm_undef(cpu, bb, instr);
1147 int m; 953 int m;
@@ -1193,41 +999,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
1193 return No_exp; 999 return No_exp;
1194} 1000}
1195#endif 1001#endif
1196#undef vfpinstr
1197#undef vfpinstr_inst
1198#undef VFPLABEL_INST
1199 1002
1200/* ----------------------------------------------------------------------- */ 1003/* ----------------------------------------------------------------------- */
1201/* VDIV */ 1004/* VDIV */
1202/* cond 1110 1D00 Vn-- Vd-- 101X N0M0 Vm-- */ 1005/* cond 1110 1D00 Vn-- Vd-- 101X N0M0 Vm-- */
1203#define vfpinstr vdiv
1204#define vfpinstr_inst vdiv_inst
1205#define VFPLABEL_INST VDIV_INST
1206#ifdef VFP_DECODE
1207{"vdiv", 5, ARMVFP2, 23, 27, 0x1d, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
1208#endif
1209#ifdef VFP_DECODE_EXCLUSION
1210{"vdiv", 0, ARMVFP2, 0},
1211#endif
1212#ifdef VFP_INTERPRETER_TABLE
1213INTERPRETER_TRANSLATE(vfpinstr),
1214#endif
1215#ifdef VFP_INTERPRETER_LABEL
1216&&VFPLABEL_INST,
1217#endif
1218#ifdef VFP_INTERPRETER_STRUCT 1006#ifdef VFP_INTERPRETER_STRUCT
1219typedef struct _vdiv_inst { 1007typedef struct _vdiv_inst {
1220 unsigned int instr; 1008 unsigned int instr;
1221 unsigned int dp_operation; 1009 unsigned int dp_operation;
1222} vfpinstr_inst; 1010} vdiv_inst;
1223#endif 1011#endif
1224#ifdef VFP_INTERPRETER_TRANS 1012#ifdef VFP_INTERPRETER_TRANS
1225ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1013ARM_INST_PTR INTERPRETER_TRANSLATE(vdiv)(unsigned int inst, int index)
1226{ 1014{
1227 VFP_DEBUG_TRANSLATE; 1015 VFP_DEBUG_TRANSLATE;
1228 1016
1229 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1017 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vdiv_inst));
1230 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1018 vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component;
1231 1019
1232 inst_base->cond = BITS(inst, 28, 31); 1020 inst_base->cond = BITS(inst, 28, 31);
1233 inst_base->idx = index; 1021 inst_base->idx = index;
@@ -1241,15 +1029,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
1241} 1029}
1242#endif 1030#endif
1243#ifdef VFP_INTERPRETER_IMPL 1031#ifdef VFP_INTERPRETER_IMPL
1244VFPLABEL_INST: 1032VDIV_INST:
1245{ 1033{
1246 INC_ICOUNTER;
1247 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1034 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1248 CHECK_VFP_ENABLED; 1035 CHECK_VFP_ENABLED;
1249 1036
1250 DBG("VDIV :\n"); 1037 DBG("VDIV :\n");
1251 1038
1252 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1039 vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component;
1253 1040
1254 int ret; 1041 int ret;
1255 1042
@@ -1261,22 +1048,17 @@ VFPLABEL_INST:
1261 CHECK_VFP_CDP_RET; 1048 CHECK_VFP_CDP_RET;
1262 } 1049 }
1263 cpu->Reg[15] += GET_INST_SIZE(cpu); 1050 cpu->Reg[15] += GET_INST_SIZE(cpu);
1264 INC_PC(sizeof(vfpinstr_inst)); 1051 INC_PC(sizeof(vdiv_inst));
1265 FETCH_INST; 1052 FETCH_INST;
1266 GOTO_NEXT_INST; 1053 GOTO_NEXT_INST;
1267} 1054}
1268#endif 1055#endif
1269#ifdef VFP_CDP_TRANS 1056
1270if ((OPC_1 & 0xB) == 0xA && (OPC_2 & 0x2) == 0)
1271{
1272 DBG("VDIV :\n");
1273}
1274#endif
1275#ifdef VFP_DYNCOM_TABLE 1057#ifdef VFP_DYNCOM_TABLE
1276DYNCOM_FILL_ACTION(vfpinstr), 1058DYNCOM_FILL_ACTION(vdiv),
1277#endif 1059#endif
1278#ifdef VFP_DYNCOM_TAG 1060#ifdef VFP_DYNCOM_TAG
1279int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1061int DYNCOM_TAG(vdiv)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1280{ 1062{
1281 int instr_size = INSTR_SIZE; 1063 int instr_size = INSTR_SIZE;
1282 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1064 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -1286,7 +1068,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
1286} 1068}
1287#endif 1069#endif
1288#ifdef VFP_DYNCOM_TRANS 1070#ifdef VFP_DYNCOM_TRANS
1289int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1071int DYNCOM_TRANS(vdiv)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1290 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1072 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1291 //arch_arm_undef(cpu, bb, instr); 1073 //arch_arm_undef(cpu, bb, instr);
1292 int m; 1074 int m;
@@ -1338,43 +1120,25 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
1338 return No_exp; 1120 return No_exp;
1339} 1121}
1340#endif 1122#endif
1341#undef vfpinstr
1342#undef vfpinstr_inst
1343#undef VFPLABEL_INST
1344 1123
1345/* ----------------------------------------------------------------------- */ 1124/* ----------------------------------------------------------------------- */
1346/* VMOVI move immediate */ 1125/* VMOVI move immediate */
1347/* cond 1110 1D11 im4H Vd-- 101X 0000 im4L */ 1126/* cond 1110 1D11 im4H Vd-- 101X 0000 im4L */
1348/* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */ 1127/* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */
1349#define vfpinstr vmovi
1350#define vfpinstr_inst vmovi_inst
1351#define VFPLABEL_INST VMOVI_INST
1352#ifdef VFP_DECODE
1353{"vmov(i)", 4, ARMVFP3, 23, 27, 0x1d, 20, 21, 0x3, 9, 11, 0x5, 4, 7, 0},
1354#endif
1355#ifdef VFP_DECODE_EXCLUSION
1356{"vmov(i)", 0, ARMVFP3, 0},
1357#endif
1358#ifdef VFP_INTERPRETER_TABLE
1359INTERPRETER_TRANSLATE(vfpinstr),
1360#endif
1361#ifdef VFP_INTERPRETER_LABEL
1362&&VFPLABEL_INST,
1363#endif
1364#ifdef VFP_INTERPRETER_STRUCT 1128#ifdef VFP_INTERPRETER_STRUCT
1365typedef struct _vmovi_inst { 1129typedef struct _vmovi_inst {
1366 unsigned int single; 1130 unsigned int single;
1367 unsigned int d; 1131 unsigned int d;
1368 unsigned int imm; 1132 unsigned int imm;
1369} vfpinstr_inst; 1133} vmovi_inst;
1370#endif 1134#endif
1371#ifdef VFP_INTERPRETER_TRANS 1135#ifdef VFP_INTERPRETER_TRANS
1372ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1136ARM_INST_PTR INTERPRETER_TRANSLATE(vmovi)(unsigned int inst, int index)
1373{ 1137{
1374 VFP_DEBUG_TRANSLATE; 1138 VFP_DEBUG_TRANSLATE;
1375 1139
1376 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1140 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovi_inst));
1377 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1141 vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component;
1378 1142
1379 inst_base->cond = BITS(inst, 28, 31); 1143 inst_base->cond = BITS(inst, 28, 31);
1380 inst_base->idx = index; 1144 inst_base->idx = index;
@@ -1392,62 +1156,27 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
1392} 1156}
1393#endif 1157#endif
1394#ifdef VFP_INTERPRETER_IMPL 1158#ifdef VFP_INTERPRETER_IMPL
1395VFPLABEL_INST: 1159VMOVI_INST:
1396{ 1160{
1397 INC_ICOUNTER;
1398 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1161 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1399 CHECK_VFP_ENABLED; 1162 CHECK_VFP_ENABLED;
1400 1163
1401 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1164 vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component;
1402 1165
1403 VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm); 1166 VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm);
1404 } 1167 }
1405 cpu->Reg[15] += GET_INST_SIZE(cpu); 1168 cpu->Reg[15] += GET_INST_SIZE(cpu);
1406 INC_PC(sizeof(vfpinstr_inst)); 1169 INC_PC(sizeof(vmovi_inst));
1407 FETCH_INST; 1170 FETCH_INST;
1408 GOTO_NEXT_INST; 1171 GOTO_NEXT_INST;
1409} 1172}
1410#endif 1173#endif
1411#ifdef VFP_CDP_TRANS 1174
1412if ( (OPC_1 & 0xb) == 0xb && BITS(4, 7) == 0)
1413{
1414 unsigned int single = BIT(8) == 0;
1415 unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4);
1416 unsigned int imm;
1417 instr = BITS(16, 19) << 4 | BITS(0, 3); /* FIXME dirty workaround to get a correct imm */
1418 if (single) {
1419 imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0x1f : 0)<<25 | BITS(0, 5)<<19;
1420 } else {
1421 imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0xff : 0)<<22 | BITS(0, 5)<<16;
1422 }
1423 VMOVI(state, single, d, imm);
1424 return ARMul_DONE;
1425}
1426#endif
1427#ifdef VFP_CDP_IMPL
1428void VMOVI(ARMul_State * state, ARMword single, ARMword d, ARMword imm)
1429{
1430 DBG("VMOV(I) :\n");
1431
1432 if (single)
1433 {
1434 DBG("\ts%d <= [%x]\n", d, imm);
1435 state->ExtReg[d] = imm;
1436 }
1437 else
1438 {
1439 /* Check endian please */
1440 DBG("\ts[%d-%d] <= [%x-%x]\n", d*2+1, d*2, imm, 0);
1441 state->ExtReg[d*2+1] = imm;
1442 state->ExtReg[d*2] = 0;
1443 }
1444}
1445#endif
1446#ifdef VFP_DYNCOM_TABLE 1175#ifdef VFP_DYNCOM_TABLE
1447DYNCOM_FILL_ACTION(vfpinstr), 1176DYNCOM_FILL_ACTION(vmovi),
1448#endif 1177#endif
1449#ifdef VFP_DYNCOM_TAG 1178#ifdef VFP_DYNCOM_TAG
1450int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1179int DYNCOM_TAG(vmovi)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1451{ 1180{
1452 int instr_size = INSTR_SIZE; 1181 int instr_size = INSTR_SIZE;
1453 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1182 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -1456,7 +1185,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
1456} 1185}
1457#endif 1186#endif
1458#ifdef VFP_DYNCOM_TRANS 1187#ifdef VFP_DYNCOM_TRANS
1459int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1188int DYNCOM_TRANS(vmovi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1460 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1189 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1461 //arch_arm_undef(cpu, bb, instr); 1190 //arch_arm_undef(cpu, bb, instr);
1462 int single = (BIT(8) == 0); 1191 int single = (BIT(8) == 0);
@@ -1482,44 +1211,26 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
1482 return No_exp; 1211 return No_exp;
1483} 1212}
1484#endif 1213#endif
1485#undef vfpinstr
1486#undef vfpinstr_inst
1487#undef VFPLABEL_INST
1488 1214
1489/* ----------------------------------------------------------------------- */ 1215/* ----------------------------------------------------------------------- */
1490/* VMOVR move register */ 1216/* VMOVR move register */
1491/* cond 1110 1D11 0000 Vd-- 101X 01M0 Vm-- */ 1217/* cond 1110 1D11 0000 Vd-- 101X 01M0 Vm-- */
1492/* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */ 1218/* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */
1493#define vfpinstr vmovr
1494#define vfpinstr_inst vmovr_inst
1495#define VFPLABEL_INST VMOVR_INST
1496#ifdef VFP_DECODE
1497{"vmov(r)", 5, ARMVFP3, 23, 27, 0x1d, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 1, 4, 4, 0},
1498#endif
1499#ifdef VFP_DECODE_EXCLUSION
1500{"vmov(r)", 0, ARMVFP3, 0},
1501#endif
1502#ifdef VFP_INTERPRETER_TABLE
1503INTERPRETER_TRANSLATE(vfpinstr),
1504#endif
1505#ifdef VFP_INTERPRETER_LABEL
1506&&VFPLABEL_INST,
1507#endif
1508#ifdef VFP_INTERPRETER_STRUCT 1219#ifdef VFP_INTERPRETER_STRUCT
1509typedef struct _vmovr_inst { 1220typedef struct _vmovr_inst {
1510 unsigned int single; 1221 unsigned int single;
1511 unsigned int d; 1222 unsigned int d;
1512 unsigned int m; 1223 unsigned int m;
1513} vfpinstr_inst; 1224} vmovr_inst;
1514#endif 1225#endif
1515#ifdef VFP_INTERPRETER_TRANS 1226#ifdef VFP_INTERPRETER_TRANS
1516ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1227ARM_INST_PTR INTERPRETER_TRANSLATE(vmovr)(unsigned int inst, int index)
1517{ 1228{
1518 VFP_DEBUG_TRANSLATE; 1229 VFP_DEBUG_TRANSLATE;
1519 VFP_DEBUG_UNTESTED(VMOVR); 1230 VFP_DEBUG_UNTESTED(VMOVR);
1520 1231
1521 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1232 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovr_inst));
1522 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1233 vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component;
1523 1234
1524 inst_base->cond = BITS(inst, 28, 31); 1235 inst_base->cond = BITS(inst, 28, 31);
1525 inst_base->idx = index; 1236 inst_base->idx = index;
@@ -1533,56 +1244,27 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
1533} 1244}
1534#endif 1245#endif
1535#ifdef VFP_INTERPRETER_IMPL 1246#ifdef VFP_INTERPRETER_IMPL
1536VFPLABEL_INST: 1247VMOVR_INST:
1537{ 1248{
1538 INC_ICOUNTER;
1539 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1249 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1540 CHECK_VFP_ENABLED; 1250 CHECK_VFP_ENABLED;
1541 1251
1542 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1252 vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component;
1543 1253
1544 VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m); 1254 VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m);
1545 } 1255 }
1546 cpu->Reg[15] += GET_INST_SIZE(cpu); 1256 cpu->Reg[15] += GET_INST_SIZE(cpu);
1547 INC_PC(sizeof(vfpinstr_inst)); 1257 INC_PC(sizeof(vmovr_inst));
1548 FETCH_INST; 1258 FETCH_INST;
1549 GOTO_NEXT_INST; 1259 GOTO_NEXT_INST;
1550} 1260}
1551#endif 1261#endif
1552#ifdef VFP_CDP_TRANS 1262
1553if ( (OPC_1 & 0xb) == 0xb && CRn == 0 && (OPC_2 & 0x6) == 0x2 )
1554{
1555 unsigned int single = BIT(8) == 0;
1556 unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4);
1557 unsigned int m = (single ? BITS( 0, 3)<<1 | BIT( 5) : BITS( 0, 3) | BIT( 5)<<4);;
1558 VMOVR(state, single, d, m);
1559 return ARMul_DONE;
1560}
1561#endif
1562#ifdef VFP_CDP_IMPL
1563void VMOVR(ARMul_State * state, ARMword single, ARMword d, ARMword m)
1564{
1565 DBG("VMOV(R) :\n");
1566
1567 if (single)
1568 {
1569 DBG("\ts%d <= s%d[%x]\n", d, m, state->ExtReg[m]);
1570 state->ExtReg[d] = state->ExtReg[m];
1571 }
1572 else
1573 {
1574 /* Check endian please */
1575 DBG("\ts[%d-%d] <= s[%d-%d][%x-%x]\n", d*2+1, d*2, m*2+1, m*2, state->ExtReg[m*2+1], state->ExtReg[m*2]);
1576 state->ExtReg[d*2+1] = state->ExtReg[m*2+1];
1577 state->ExtReg[d*2] = state->ExtReg[m*2];
1578 }
1579}
1580#endif
1581#ifdef VFP_DYNCOM_TABLE 1263#ifdef VFP_DYNCOM_TABLE
1582DYNCOM_FILL_ACTION(vfpinstr), 1264DYNCOM_FILL_ACTION(vmovr),
1583#endif 1265#endif
1584#ifdef VFP_DYNCOM_TAG 1266#ifdef VFP_DYNCOM_TAG
1585int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1267int DYNCOM_TAG(vmovr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1586{ 1268{
1587 int instr_size = INSTR_SIZE; 1269 int instr_size = INSTR_SIZE;
1588 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 1270 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
@@ -1594,7 +1276,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
1594} 1276}
1595#endif 1277#endif
1596#ifdef VFP_DYNCOM_TRANS 1278#ifdef VFP_DYNCOM_TRANS
1597int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1279int DYNCOM_TRANS(vmovr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1598 DBG("\t\tin %s VMOV \n", __FUNCTION__); 1280 DBG("\t\tin %s VMOV \n", __FUNCTION__);
1599 int single = BIT(8) == 0; 1281 int single = BIT(8) == 0;
1600 int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15)); 1282 int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15));
@@ -1613,41 +1295,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
1613 return No_exp; 1295 return No_exp;
1614} 1296}
1615#endif 1297#endif
1616#undef vfpinstr
1617#undef vfpinstr_inst
1618#undef VFPLABEL_INST
1619 1298
1620/* ----------------------------------------------------------------------- */ 1299/* ----------------------------------------------------------------------- */
1621/* VABS */ 1300/* VABS */
1622/* cond 1110 1D11 0000 Vd-- 101X 11M0 Vm-- */ 1301/* cond 1110 1D11 0000 Vd-- 101X 11M0 Vm-- */
1623#define vfpinstr vabs
1624#define vfpinstr_inst vabs_inst
1625#define VFPLABEL_INST VABS_INST
1626#ifdef VFP_DECODE
1627{"vabs", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 3, 4, 4, 0},
1628#endif
1629#ifdef VFP_DECODE_EXCLUSION
1630{"vabs", 0, ARMVFP2, 0},
1631#endif
1632#ifdef VFP_INTERPRETER_TABLE
1633INTERPRETER_TRANSLATE(vfpinstr),
1634#endif
1635#ifdef VFP_INTERPRETER_LABEL
1636&&VFPLABEL_INST,
1637#endif
1638#ifdef VFP_INTERPRETER_STRUCT 1302#ifdef VFP_INTERPRETER_STRUCT
1639typedef struct _vabs_inst { 1303typedef struct _vabs_inst {
1640 unsigned int instr; 1304 unsigned int instr;
1641 unsigned int dp_operation; 1305 unsigned int dp_operation;
1642} vfpinstr_inst; 1306} vabs_inst;
1643#endif 1307#endif
1644#ifdef VFP_INTERPRETER_TRANS 1308#ifdef VFP_INTERPRETER_TRANS
1645ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1309ARM_INST_PTR INTERPRETER_TRANSLATE(vabs)(unsigned int inst, int index)
1646{ 1310{
1647 VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VABS); 1311 VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VABS);
1648 1312
1649 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1313 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vabs_inst));
1650 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1314 vabs_inst *inst_cream = (vabs_inst *)inst_base->component;
1651 1315
1652 inst_base->cond = BITS(inst, 28, 31); 1316 inst_base->cond = BITS(inst, 28, 31);
1653 inst_base->idx = index; 1317 inst_base->idx = index;
@@ -1661,15 +1325,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
1661} 1325}
1662#endif 1326#endif
1663#ifdef VFP_INTERPRETER_IMPL 1327#ifdef VFP_INTERPRETER_IMPL
1664VFPLABEL_INST: 1328VABS_INST:
1665{ 1329{
1666 INC_ICOUNTER;
1667 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1330 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1668 CHECK_VFP_ENABLED; 1331 CHECK_VFP_ENABLED;
1669 1332
1670 DBG("VABS :\n"); 1333 DBG("VABS :\n");
1671 1334
1672 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1335 vabs_inst *inst_cream = (vabs_inst *)inst_base->component;
1673 1336
1674 int ret; 1337 int ret;
1675 1338
@@ -1681,22 +1344,17 @@ VFPLABEL_INST:
1681 CHECK_VFP_CDP_RET; 1344 CHECK_VFP_CDP_RET;
1682 } 1345 }
1683 cpu->Reg[15] += GET_INST_SIZE(cpu); 1346 cpu->Reg[15] += GET_INST_SIZE(cpu);
1684 INC_PC(sizeof(vfpinstr_inst)); 1347 INC_PC(sizeof(vabs_inst));
1685 FETCH_INST; 1348 FETCH_INST;
1686 GOTO_NEXT_INST; 1349 GOTO_NEXT_INST;
1687} 1350}
1688#endif 1351#endif
1689#ifdef VFP_CDP_TRANS 1352
1690if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x7) == 6)
1691{
1692 DBG("VABS :\n");
1693}
1694#endif
1695#ifdef VFP_DYNCOM_TABLE 1353#ifdef VFP_DYNCOM_TABLE
1696DYNCOM_FILL_ACTION(vfpinstr), 1354DYNCOM_FILL_ACTION(vabs),
1697#endif 1355#endif
1698#ifdef VFP_DYNCOM_TAG 1356#ifdef VFP_DYNCOM_TAG
1699int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1357int DYNCOM_TAG(vabs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1700{ 1358{
1701 int instr_size = INSTR_SIZE; 1359 int instr_size = INSTR_SIZE;
1702 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1360 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -1706,7 +1364,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
1706} 1364}
1707#endif 1365#endif
1708#ifdef VFP_DYNCOM_TRANS 1366#ifdef VFP_DYNCOM_TRANS
1709int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1367int DYNCOM_TRANS(vabs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1710 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1368 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1711 //arch_arm_undef(cpu, bb, instr); 1369 //arch_arm_undef(cpu, bb, instr);
1712 int single = BIT(8) == 0; 1370 int single = BIT(8) == 0;
@@ -1744,42 +1402,24 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
1744 return No_exp; 1402 return No_exp;
1745} 1403}
1746#endif 1404#endif
1747#undef vfpinstr
1748#undef vfpinstr_inst
1749#undef VFPLABEL_INST
1750 1405
1751/* ----------------------------------------------------------------------- */ 1406/* ----------------------------------------------------------------------- */
1752/* VNEG */ 1407/* VNEG */
1753/* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */ 1408/* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */
1754#define vfpinstr vneg 1409
1755#define vfpinstr_inst vneg_inst
1756#define VFPLABEL_INST VNEG_INST
1757#ifdef VFP_DECODE
1758//{"vneg", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 1, 4, 4, 0},
1759{"vneg", 5, ARMVFP2, 23, 27, 0x1d, 17, 21, 0x18, 9, 11, 0x5, 6, 7, 1, 4, 4, 0},
1760#endif
1761#ifdef VFP_DECODE_EXCLUSION
1762{"vneg", 0, ARMVFP2, 0},
1763#endif
1764#ifdef VFP_INTERPRETER_TABLE
1765INTERPRETER_TRANSLATE(vfpinstr),
1766#endif
1767#ifdef VFP_INTERPRETER_LABEL
1768&&VFPLABEL_INST,
1769#endif
1770#ifdef VFP_INTERPRETER_STRUCT 1410#ifdef VFP_INTERPRETER_STRUCT
1771typedef struct _vneg_inst { 1411typedef struct _vneg_inst {
1772 unsigned int instr; 1412 unsigned int instr;
1773 unsigned int dp_operation; 1413 unsigned int dp_operation;
1774} vfpinstr_inst; 1414} vneg_inst;
1775#endif 1415#endif
1776#ifdef VFP_INTERPRETER_TRANS 1416#ifdef VFP_INTERPRETER_TRANS
1777ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1417ARM_INST_PTR INTERPRETER_TRANSLATE(vneg)(unsigned int inst, int index)
1778{ 1418{
1779 VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VNEG); 1419 VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VNEG);
1780 1420
1781 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1421 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vneg_inst));
1782 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1422 vneg_inst *inst_cream = (vneg_inst *)inst_base->component;
1783 1423
1784 inst_base->cond = BITS(inst, 28, 31); 1424 inst_base->cond = BITS(inst, 28, 31);
1785 inst_base->idx = index; 1425 inst_base->idx = index;
@@ -1793,15 +1433,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
1793} 1433}
1794#endif 1434#endif
1795#ifdef VFP_INTERPRETER_IMPL 1435#ifdef VFP_INTERPRETER_IMPL
1796VFPLABEL_INST: 1436VNEG_INST:
1797{ 1437{
1798 INC_ICOUNTER;
1799 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1438 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1800 CHECK_VFP_ENABLED; 1439 CHECK_VFP_ENABLED;
1801 1440
1802 DBG("VNEG :\n"); 1441 DBG("VNEG :\n");
1803 1442
1804 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1443 vneg_inst *inst_cream = (vneg_inst *)inst_base->component;
1805 1444
1806 int ret; 1445 int ret;
1807 1446
@@ -1813,22 +1452,17 @@ VFPLABEL_INST:
1813 CHECK_VFP_CDP_RET; 1452 CHECK_VFP_CDP_RET;
1814 } 1453 }
1815 cpu->Reg[15] += GET_INST_SIZE(cpu); 1454 cpu->Reg[15] += GET_INST_SIZE(cpu);
1816 INC_PC(sizeof(vfpinstr_inst)); 1455 INC_PC(sizeof(vneg_inst));
1817 FETCH_INST; 1456 FETCH_INST;
1818 GOTO_NEXT_INST; 1457 GOTO_NEXT_INST;
1819} 1458}
1820#endif 1459#endif
1821#ifdef VFP_CDP_TRANS 1460
1822if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 2)
1823{
1824 DBG("VNEG :\n");
1825}
1826#endif
1827#ifdef VFP_DYNCOM_TABLE 1461#ifdef VFP_DYNCOM_TABLE
1828DYNCOM_FILL_ACTION(vfpinstr), 1462DYNCOM_FILL_ACTION(vneg),
1829#endif 1463#endif
1830#ifdef VFP_DYNCOM_TAG 1464#ifdef VFP_DYNCOM_TAG
1831int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1465int DYNCOM_TAG(vneg)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1832{ 1466{
1833 int instr_size = INSTR_SIZE; 1467 int instr_size = INSTR_SIZE;
1834 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1468 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -1838,7 +1472,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
1838} 1472}
1839#endif 1473#endif
1840#ifdef VFP_DYNCOM_TRANS 1474#ifdef VFP_DYNCOM_TRANS
1841int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1475int DYNCOM_TRANS(vneg)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1842 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1476 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1843 //arch_arm_undef(cpu, bb, instr); 1477 //arch_arm_undef(cpu, bb, instr);
1844 int single = BIT(8) == 0; 1478 int single = BIT(8) == 0;
@@ -1876,41 +1510,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
1876 return No_exp; 1510 return No_exp;
1877} 1511}
1878#endif 1512#endif
1879#undef vfpinstr
1880#undef vfpinstr_inst
1881#undef VFPLABEL_INST
1882 1513
1883/* ----------------------------------------------------------------------- */ 1514/* ----------------------------------------------------------------------- */
1884/* VSQRT */ 1515/* VSQRT */
1885/* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */ 1516/* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */
1886#define vfpinstr vsqrt
1887#define vfpinstr_inst vsqrt_inst
1888#define VFPLABEL_INST VSQRT_INST
1889#ifdef VFP_DECODE
1890{"vsqrt", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x31, 9, 11, 0x5, 6, 7, 3, 4, 4, 0},
1891#endif
1892#ifdef VFP_DECODE_EXCLUSION
1893{"vsqrt", 0, ARMVFP2, 0},
1894#endif
1895#ifdef VFP_INTERPRETER_TABLE
1896INTERPRETER_TRANSLATE(vfpinstr),
1897#endif
1898#ifdef VFP_INTERPRETER_LABEL
1899&&VFPLABEL_INST,
1900#endif
1901#ifdef VFP_INTERPRETER_STRUCT 1517#ifdef VFP_INTERPRETER_STRUCT
1902typedef struct _vsqrt_inst { 1518typedef struct _vsqrt_inst {
1903 unsigned int instr; 1519 unsigned int instr;
1904 unsigned int dp_operation; 1520 unsigned int dp_operation;
1905} vfpinstr_inst; 1521} vsqrt_inst;
1906#endif 1522#endif
1907#ifdef VFP_INTERPRETER_TRANS 1523#ifdef VFP_INTERPRETER_TRANS
1908ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1524ARM_INST_PTR INTERPRETER_TRANSLATE(vsqrt)(unsigned int inst, int index)
1909{ 1525{
1910 VFP_DEBUG_TRANSLATE; 1526 VFP_DEBUG_TRANSLATE;
1911 1527
1912 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1528 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsqrt_inst));
1913 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1529 vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component;
1914 1530
1915 inst_base->cond = BITS(inst, 28, 31); 1531 inst_base->cond = BITS(inst, 28, 31);
1916 inst_base->idx = index; 1532 inst_base->idx = index;
@@ -1924,15 +1540,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
1924} 1540}
1925#endif 1541#endif
1926#ifdef VFP_INTERPRETER_IMPL 1542#ifdef VFP_INTERPRETER_IMPL
1927VFPLABEL_INST: 1543VSQRT_INST:
1928{ 1544{
1929 INC_ICOUNTER;
1930 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1545 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1931 CHECK_VFP_ENABLED; 1546 CHECK_VFP_ENABLED;
1932 1547
1933 DBG("VSQRT :\n"); 1548 DBG("VSQRT :\n");
1934 1549
1935 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1550 vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component;
1936 1551
1937 int ret; 1552 int ret;
1938 1553
@@ -1944,22 +1559,17 @@ VFPLABEL_INST:
1944 CHECK_VFP_CDP_RET; 1559 CHECK_VFP_CDP_RET;
1945 } 1560 }
1946 cpu->Reg[15] += GET_INST_SIZE(cpu); 1561 cpu->Reg[15] += GET_INST_SIZE(cpu);
1947 INC_PC(sizeof(vfpinstr_inst)); 1562 INC_PC(sizeof(vsqrt_inst));
1948 FETCH_INST; 1563 FETCH_INST;
1949 GOTO_NEXT_INST; 1564 GOTO_NEXT_INST;
1950} 1565}
1951#endif 1566#endif
1952#ifdef VFP_CDP_TRANS 1567
1953if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 6)
1954{
1955 DBG("VSQRT :\n");
1956}
1957#endif
1958#ifdef VFP_DYNCOM_TABLE 1568#ifdef VFP_DYNCOM_TABLE
1959DYNCOM_FILL_ACTION(vfpinstr), 1569DYNCOM_FILL_ACTION(vsqrt),
1960#endif 1570#endif
1961#ifdef VFP_DYNCOM_TAG 1571#ifdef VFP_DYNCOM_TAG
1962int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1572int DYNCOM_TAG(vsqrt)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1963{ 1573{
1964 int instr_size = INSTR_SIZE; 1574 int instr_size = INSTR_SIZE;
1965 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1575 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -1969,7 +1579,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
1969} 1579}
1970#endif 1580#endif
1971#ifdef VFP_DYNCOM_TRANS 1581#ifdef VFP_DYNCOM_TRANS
1972int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1582int DYNCOM_TRANS(vsqrt)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1973 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1583 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1974 //arch_arm_undef(cpu, bb, instr); 1584 //arch_arm_undef(cpu, bb, instr);
1975 int dp_op = (BIT(8) == 1); 1585 int dp_op = (BIT(8) == 1);
@@ -1995,41 +1605,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
1995 return No_exp; 1605 return No_exp;
1996} 1606}
1997#endif 1607#endif
1998#undef vfpinstr
1999#undef vfpinstr_inst
2000#undef VFPLABEL_INST
2001 1608
2002/* ----------------------------------------------------------------------- */ 1609/* ----------------------------------------------------------------------- */
2003/* VCMP VCMPE */ 1610/* VCMP VCMPE */
2004/* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 1 */ 1611/* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 1 */
2005#define vfpinstr vcmp
2006#define vfpinstr_inst vcmp_inst
2007#define VFPLABEL_INST VCMP_INST
2008#ifdef VFP_DECODE
2009{"vcmp", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x34, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
2010#endif
2011#ifdef VFP_DECODE_EXCLUSION
2012{"vcmp", 0, ARMVFP2, 0},
2013#endif
2014#ifdef VFP_INTERPRETER_TABLE
2015INTERPRETER_TRANSLATE(vfpinstr),
2016#endif
2017#ifdef VFP_INTERPRETER_LABEL
2018&&VFPLABEL_INST,
2019#endif
2020#ifdef VFP_INTERPRETER_STRUCT 1612#ifdef VFP_INTERPRETER_STRUCT
2021typedef struct _vcmp_inst { 1613typedef struct _vcmp_inst {
2022 unsigned int instr; 1614 unsigned int instr;
2023 unsigned int dp_operation; 1615 unsigned int dp_operation;
2024} vfpinstr_inst; 1616} vcmp_inst;
2025#endif 1617#endif
2026#ifdef VFP_INTERPRETER_TRANS 1618#ifdef VFP_INTERPRETER_TRANS
2027ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1619ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp)(unsigned int inst, int index)
2028{ 1620{
2029 VFP_DEBUG_TRANSLATE; 1621 VFP_DEBUG_TRANSLATE;
2030 1622
2031 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1623 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp_inst));
2032 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1624 vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component;
2033 1625
2034 inst_base->cond = BITS(inst, 28, 31); 1626 inst_base->cond = BITS(inst, 28, 31);
2035 inst_base->idx = index; 1627 inst_base->idx = index;
@@ -2043,15 +1635,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
2043} 1635}
2044#endif 1636#endif
2045#ifdef VFP_INTERPRETER_IMPL 1637#ifdef VFP_INTERPRETER_IMPL
2046VFPLABEL_INST: 1638VCMP_INST:
2047{ 1639{
2048 INC_ICOUNTER;
2049 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1640 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
2050 CHECK_VFP_ENABLED; 1641 CHECK_VFP_ENABLED;
2051 1642
2052 DBG("VCMP(1) :\n"); 1643 DBG("VCMP(1) :\n");
2053 1644
2054 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1645 vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component;
2055 1646
2056 int ret; 1647 int ret;
2057 1648
@@ -2063,22 +1654,17 @@ VFPLABEL_INST:
2063 CHECK_VFP_CDP_RET; 1654 CHECK_VFP_CDP_RET;
2064 } 1655 }
2065 cpu->Reg[15] += GET_INST_SIZE(cpu); 1656 cpu->Reg[15] += GET_INST_SIZE(cpu);
2066 INC_PC(sizeof(vfpinstr_inst)); 1657 INC_PC(sizeof(vcmp_inst));
2067 FETCH_INST; 1658 FETCH_INST;
2068 GOTO_NEXT_INST; 1659 GOTO_NEXT_INST;
2069} 1660}
2070#endif 1661#endif
2071#ifdef VFP_CDP_TRANS 1662
2072if ((OPC_1 & 0xB) == 0xB && CRn == 4 && (OPC_2 & 0x2) == 2)
2073{
2074 DBG("VCMP(1) :\n");
2075}
2076#endif
2077#ifdef VFP_DYNCOM_TABLE 1663#ifdef VFP_DYNCOM_TABLE
2078DYNCOM_FILL_ACTION(vfpinstr), 1664DYNCOM_FILL_ACTION(vcmp),
2079#endif 1665#endif
2080#ifdef VFP_DYNCOM_TAG 1666#ifdef VFP_DYNCOM_TAG
2081int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1667int DYNCOM_TAG(vcmp)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2082{ 1668{
2083 int instr_size = INSTR_SIZE; 1669 int instr_size = INSTR_SIZE;
2084 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 1670 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
@@ -2087,7 +1673,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
2087} 1673}
2088#endif 1674#endif
2089#ifdef VFP_DYNCOM_TRANS 1675#ifdef VFP_DYNCOM_TRANS
2090int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1676int DYNCOM_TRANS(vcmp)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2091 DBG("\t\tin %s instruction is executed out of JIT.\n", __FUNCTION__); 1677 DBG("\t\tin %s instruction is executed out of JIT.\n", __FUNCTION__);
2092 //arch_arm_undef(cpu, bb, instr); 1678 //arch_arm_undef(cpu, bb, instr);
2093 int dp_op = (BIT(8) == 1); 1679 int dp_op = (BIT(8) == 1);
@@ -2141,41 +1727,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
2141 return No_exp; 1727 return No_exp;
2142} 1728}
2143#endif 1729#endif
2144#undef vfpinstr
2145#undef vfpinstr_inst
2146#undef VFPLABEL_INST
2147 1730
2148/* ----------------------------------------------------------------------- */ 1731/* ----------------------------------------------------------------------- */
2149/* VCMP VCMPE */ 1732/* VCMP VCMPE */
2150/* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 2 */ 1733/* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 2 */
2151#define vfpinstr vcmp2
2152#define vfpinstr_inst vcmp2_inst
2153#define VFPLABEL_INST VCMP2_INST
2154#ifdef VFP_DECODE
2155{"vcmp2", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x35, 9, 11, 0x5, 0, 6, 0x40},
2156#endif
2157#ifdef VFP_DECODE_EXCLUSION
2158{"vcmp2", 0, ARMVFP2, 0},
2159#endif
2160#ifdef VFP_INTERPRETER_TABLE
2161INTERPRETER_TRANSLATE(vfpinstr),
2162#endif
2163#ifdef VFP_INTERPRETER_LABEL
2164&&VFPLABEL_INST,
2165#endif
2166#ifdef VFP_INTERPRETER_STRUCT 1734#ifdef VFP_INTERPRETER_STRUCT
2167typedef struct _vcmp2_inst { 1735typedef struct _vcmp2_inst {
2168 unsigned int instr; 1736 unsigned int instr;
2169 unsigned int dp_operation; 1737 unsigned int dp_operation;
2170} vfpinstr_inst; 1738} vcmp2_inst;
2171#endif 1739#endif
2172#ifdef VFP_INTERPRETER_TRANS 1740#ifdef VFP_INTERPRETER_TRANS
2173ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1741ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp2)(unsigned int inst, int index)
2174{ 1742{
2175 VFP_DEBUG_TRANSLATE; 1743 VFP_DEBUG_TRANSLATE;
2176 1744
2177 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1745 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp2_inst));
2178 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1746 vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component;
2179 1747
2180 inst_base->cond = BITS(inst, 28, 31); 1748 inst_base->cond = BITS(inst, 28, 31);
2181 inst_base->idx = index; 1749 inst_base->idx = index;
@@ -2189,15 +1757,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
2189} 1757}
2190#endif 1758#endif
2191#ifdef VFP_INTERPRETER_IMPL 1759#ifdef VFP_INTERPRETER_IMPL
2192VFPLABEL_INST: 1760VCMP2_INST:
2193{ 1761{
2194 INC_ICOUNTER;
2195 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1762 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
2196 CHECK_VFP_ENABLED; 1763 CHECK_VFP_ENABLED;
2197 1764
2198 DBG("VCMP(2) :\n"); 1765 DBG("VCMP(2) :\n");
2199 1766
2200 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1767 vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component;
2201 1768
2202 int ret; 1769 int ret;
2203 1770
@@ -2209,22 +1776,17 @@ VFPLABEL_INST:
2209 CHECK_VFP_CDP_RET; 1776 CHECK_VFP_CDP_RET;
2210 } 1777 }
2211 cpu->Reg[15] += GET_INST_SIZE(cpu); 1778 cpu->Reg[15] += GET_INST_SIZE(cpu);
2212 INC_PC(sizeof(vfpinstr_inst)); 1779 INC_PC(sizeof(vcmp2_inst));
2213 FETCH_INST; 1780 FETCH_INST;
2214 GOTO_NEXT_INST; 1781 GOTO_NEXT_INST;
2215} 1782}
2216#endif 1783#endif
2217#ifdef VFP_CDP_TRANS 1784
2218if ((OPC_1 & 0xB) == 0xB && CRn == 5 && (OPC_2 & 0x2) == 2 && CRm == 0)
2219{
2220 DBG("VCMP(2) :\n");
2221}
2222#endif
2223#ifdef VFP_DYNCOM_TABLE 1785#ifdef VFP_DYNCOM_TABLE
2224DYNCOM_FILL_ACTION(vfpinstr), 1786DYNCOM_FILL_ACTION(vcmp2),
2225#endif 1787#endif
2226#ifdef VFP_DYNCOM_TAG 1788#ifdef VFP_DYNCOM_TAG
2227int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1789int DYNCOM_TAG(vcmp2)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2228{ 1790{
2229 int instr_size = INSTR_SIZE; 1791 int instr_size = INSTR_SIZE;
2230 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 1792 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
@@ -2233,7 +1795,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
2233} 1795}
2234#endif 1796#endif
2235#ifdef VFP_DYNCOM_TRANS 1797#ifdef VFP_DYNCOM_TRANS
2236int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1798int DYNCOM_TRANS(vcmp2)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2237 DBG("\t\tin %s instruction will executed out of JIT.\n", __FUNCTION__); 1799 DBG("\t\tin %s instruction will executed out of JIT.\n", __FUNCTION__);
2238 //arch_arm_undef(cpu, bb, instr); 1800 //arch_arm_undef(cpu, bb, instr);
2239 int dp_op = (BIT(8) == 1); 1801 int dp_op = (BIT(8) == 1);
@@ -2287,41 +1849,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
2287 return No_exp; 1849 return No_exp;
2288} 1850}
2289#endif 1851#endif
2290#undef vfpinstr
2291#undef vfpinstr_inst
2292#undef VFPLABEL_INST
2293 1852
2294/* ----------------------------------------------------------------------- */ 1853/* ----------------------------------------------------------------------- */
2295/* VCVTBDS between double and single */ 1854/* VCVTBDS between double and single */
2296/* cond 1110 1D11 0111 Vd-- 101X 11M0 Vm-- */ 1855/* cond 1110 1D11 0111 Vd-- 101X 11M0 Vm-- */
2297#define vfpinstr vcvtbds
2298#define vfpinstr_inst vcvtbds_inst
2299#define VFPLABEL_INST VCVTBDS_INST
2300#ifdef VFP_DECODE
2301{"vcvt(bds)", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x37, 9, 11, 0x5, 6, 7, 3, 4, 4, 0},
2302#endif
2303#ifdef VFP_DECODE_EXCLUSION
2304{"vcvt(bds)", 0, ARMVFP2, 0},
2305#endif
2306#ifdef VFP_INTERPRETER_TABLE
2307INTERPRETER_TRANSLATE(vfpinstr),
2308#endif
2309#ifdef VFP_INTERPRETER_LABEL
2310&&VFPLABEL_INST,
2311#endif
2312#ifdef VFP_INTERPRETER_STRUCT 1856#ifdef VFP_INTERPRETER_STRUCT
2313typedef struct _vcvtbds_inst { 1857typedef struct _vcvtbds_inst {
2314 unsigned int instr; 1858 unsigned int instr;
2315 unsigned int dp_operation; 1859 unsigned int dp_operation;
2316} vfpinstr_inst; 1860} vcvtbds_inst;
2317#endif 1861#endif
2318#ifdef VFP_INTERPRETER_TRANS 1862#ifdef VFP_INTERPRETER_TRANS
2319ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1863ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbds)(unsigned int inst, int index)
2320{ 1864{
2321 VFP_DEBUG_TRANSLATE; 1865 VFP_DEBUG_TRANSLATE;
2322 1866
2323 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1867 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbds_inst));
2324 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1868 vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component;
2325 1869
2326 inst_base->cond = BITS(inst, 28, 31); 1870 inst_base->cond = BITS(inst, 28, 31);
2327 inst_base->idx = index; 1871 inst_base->idx = index;
@@ -2335,15 +1879,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
2335} 1879}
2336#endif 1880#endif
2337#ifdef VFP_INTERPRETER_IMPL 1881#ifdef VFP_INTERPRETER_IMPL
2338VFPLABEL_INST: 1882VCVTBDS_INST:
2339{ 1883{
2340 INC_ICOUNTER;
2341 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1884 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
2342 CHECK_VFP_ENABLED; 1885 CHECK_VFP_ENABLED;
2343 1886
2344 DBG("VCVT(BDS) :\n"); 1887 DBG("VCVT(BDS) :\n");
2345 1888
2346 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1889 vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component;
2347 1890
2348 int ret; 1891 int ret;
2349 1892
@@ -2355,22 +1898,17 @@ VFPLABEL_INST:
2355 CHECK_VFP_CDP_RET; 1898 CHECK_VFP_CDP_RET;
2356 } 1899 }
2357 cpu->Reg[15] += GET_INST_SIZE(cpu); 1900 cpu->Reg[15] += GET_INST_SIZE(cpu);
2358 INC_PC(sizeof(vfpinstr_inst)); 1901 INC_PC(sizeof(vcvtbds_inst));
2359 FETCH_INST; 1902 FETCH_INST;
2360 GOTO_NEXT_INST; 1903 GOTO_NEXT_INST;
2361} 1904}
2362#endif 1905#endif
2363#ifdef VFP_CDP_TRANS 1906
2364if ((OPC_1 & 0xB) == 0xB && CRn == 7 && (OPC_2 & 0x6) == 6)
2365{
2366 DBG("VCVT(BDS) :\n");
2367}
2368#endif
2369#ifdef VFP_DYNCOM_TABLE 1907#ifdef VFP_DYNCOM_TABLE
2370DYNCOM_FILL_ACTION(vfpinstr), 1908DYNCOM_FILL_ACTION(vcvtbds),
2371#endif 1909#endif
2372#ifdef VFP_DYNCOM_TAG 1910#ifdef VFP_DYNCOM_TAG
2373int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1911int DYNCOM_TAG(vcvtbds)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2374{ 1912{
2375 int instr_size = INSTR_SIZE; 1913 int instr_size = INSTR_SIZE;
2376 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 1914 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
@@ -2379,7 +1917,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
2379} 1917}
2380#endif 1918#endif
2381#ifdef VFP_DYNCOM_TRANS 1919#ifdef VFP_DYNCOM_TRANS
2382int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1920int DYNCOM_TRANS(vcvtbds)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2383 DBG("\t\tin %s instruction is executed out.\n", __FUNCTION__); 1921 DBG("\t\tin %s instruction is executed out.\n", __FUNCTION__);
2384 //arch_arm_undef(cpu, bb, instr); 1922 //arch_arm_undef(cpu, bb, instr);
2385 int dp_op = (BIT(8) == 1); 1923 int dp_op = (BIT(8) == 1);
@@ -2407,41 +1945,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
2407 return No_exp; 1945 return No_exp;
2408} 1946}
2409#endif 1947#endif
2410#undef vfpinstr
2411#undef vfpinstr_inst
2412#undef VFPLABEL_INST
2413 1948
2414/* ----------------------------------------------------------------------- */ 1949/* ----------------------------------------------------------------------- */
2415/* VCVTBFF between floating point and fixed point */ 1950/* VCVTBFF between floating point and fixed point */
2416/* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */ 1951/* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */
2417#define vfpinstr vcvtbff
2418#define vfpinstr_inst vcvtbff_inst
2419#define VFPLABEL_INST VCVTBFF_INST
2420#ifdef VFP_DECODE
2421{"vcvt(bff)", 6, ARMVFP3, 23, 27, 0x1d, 19, 21, 0x7, 17, 17, 0x1, 9, 11, 0x5, 6, 6, 1},
2422#endif
2423#ifdef VFP_DECODE_EXCLUSION
2424{"vcvt(bff)", 0, ARMVFP3, 4, 4, 1},
2425#endif
2426#ifdef VFP_INTERPRETER_TABLE
2427INTERPRETER_TRANSLATE(vfpinstr),
2428#endif
2429#ifdef VFP_INTERPRETER_LABEL
2430&&VFPLABEL_INST,
2431#endif
2432#ifdef VFP_INTERPRETER_STRUCT 1952#ifdef VFP_INTERPRETER_STRUCT
2433typedef struct _vcvtbff_inst { 1953typedef struct _vcvtbff_inst {
2434 unsigned int instr; 1954 unsigned int instr;
2435 unsigned int dp_operation; 1955 unsigned int dp_operation;
2436} vfpinstr_inst; 1956} vcvtbff_inst;
2437#endif 1957#endif
2438#ifdef VFP_INTERPRETER_TRANS 1958#ifdef VFP_INTERPRETER_TRANS
2439ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1959ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbff)(unsigned int inst, int index)
2440{ 1960{
2441 VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VCVTBFF); 1961 VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VCVTBFF);
2442 1962
2443 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1963 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbff_inst));
2444 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1964 vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component;
2445 1965
2446 inst_base->cond = BITS(inst, 28, 31); 1966 inst_base->cond = BITS(inst, 28, 31);
2447 inst_base->idx = index; 1967 inst_base->idx = index;
@@ -2455,15 +1975,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
2455} 1975}
2456#endif 1976#endif
2457#ifdef VFP_INTERPRETER_IMPL 1977#ifdef VFP_INTERPRETER_IMPL
2458VFPLABEL_INST: 1978VCVTBFF_INST:
2459{ 1979{
2460 INC_ICOUNTER;
2461 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1980 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
2462 CHECK_VFP_ENABLED; 1981 CHECK_VFP_ENABLED;
2463 1982
2464 DBG("VCVT(BFF) :\n"); 1983 DBG("VCVT(BFF) :\n");
2465 1984
2466 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1985 vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component;
2467 1986
2468 int ret; 1987 int ret;
2469 1988
@@ -2475,22 +1994,17 @@ VFPLABEL_INST:
2475 CHECK_VFP_CDP_RET; 1994 CHECK_VFP_CDP_RET;
2476 } 1995 }
2477 cpu->Reg[15] += GET_INST_SIZE(cpu); 1996 cpu->Reg[15] += GET_INST_SIZE(cpu);
2478 INC_PC(sizeof(vfpinstr_inst)); 1997 INC_PC(sizeof(vcvtbff_inst));
2479 FETCH_INST; 1998 FETCH_INST;
2480 GOTO_NEXT_INST; 1999 GOTO_NEXT_INST;
2481} 2000}
2482#endif 2001#endif
2483#ifdef VFP_CDP_TRANS 2002
2484if ((OPC_1 & 0xB) == 0xB && CRn >= 0xA && (OPC_2 & 0x2) == 2)
2485{
2486 DBG("VCVT(BFF) :\n");
2487}
2488#endif
2489#ifdef VFP_DYNCOM_TABLE 2003#ifdef VFP_DYNCOM_TABLE
2490DYNCOM_FILL_ACTION(vfpinstr), 2004DYNCOM_FILL_ACTION(vcvtbff),
2491#endif 2005#endif
2492#ifdef VFP_DYNCOM_TAG 2006#ifdef VFP_DYNCOM_TAG
2493int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2007int DYNCOM_TAG(vcvtbff)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2494{ 2008{
2495 int instr_size = INSTR_SIZE; 2009 int instr_size = INSTR_SIZE;
2496 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2010 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -2499,47 +2013,29 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
2499} 2013}
2500#endif 2014#endif
2501#ifdef VFP_DYNCOM_TRANS 2015#ifdef VFP_DYNCOM_TRANS
2502int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2016int DYNCOM_TRANS(vcvtbff)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2503 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2017 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2504 arch_arm_undef(cpu, bb, instr); 2018 arch_arm_undef(cpu, bb, instr);
2505 return No_exp; 2019 return No_exp;
2506} 2020}
2507#endif 2021#endif
2508#undef vfpinstr
2509#undef vfpinstr_inst
2510#undef VFPLABEL_INST
2511 2022
2512/* ----------------------------------------------------------------------- */ 2023/* ----------------------------------------------------------------------- */
2513/* VCVTBFI between floating point and integer */ 2024/* VCVTBFI between floating point and integer */
2514/* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */ 2025/* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */
2515#define vfpinstr vcvtbfi
2516#define vfpinstr_inst vcvtbfi_inst
2517#define VFPLABEL_INST VCVTBFI_INST
2518#ifdef VFP_DECODE
2519{"vcvt(bfi)", 5, ARMVFP2, 23, 27, 0x1d, 19, 21, 0x7, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
2520#endif
2521#ifdef VFP_DECODE_EXCLUSION
2522{"vcvt(bfi)", 0, ARMVFP2, 0},
2523#endif
2524#ifdef VFP_INTERPRETER_TABLE
2525INTERPRETER_TRANSLATE(vfpinstr),
2526#endif
2527#ifdef VFP_INTERPRETER_LABEL
2528&&VFPLABEL_INST,
2529#endif
2530#ifdef VFP_INTERPRETER_STRUCT 2026#ifdef VFP_INTERPRETER_STRUCT
2531typedef struct _vcvtbfi_inst { 2027typedef struct _vcvtbfi_inst {
2532 unsigned int instr; 2028 unsigned int instr;
2533 unsigned int dp_operation; 2029 unsigned int dp_operation;
2534} vfpinstr_inst; 2030} vcvtbfi_inst;
2535#endif 2031#endif
2536#ifdef VFP_INTERPRETER_TRANS 2032#ifdef VFP_INTERPRETER_TRANS
2537ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2033ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbfi)(unsigned int inst, int index)
2538{ 2034{
2539 VFP_DEBUG_TRANSLATE; 2035 VFP_DEBUG_TRANSLATE;
2540 2036
2541 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2037 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbfi_inst));
2542 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2038 vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component;
2543 2039
2544 inst_base->cond = BITS(inst, 28, 31); 2040 inst_base->cond = BITS(inst, 28, 31);
2545 inst_base->idx = index; 2041 inst_base->idx = index;
@@ -2554,15 +2050,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
2554} 2050}
2555#endif 2051#endif
2556#ifdef VFP_INTERPRETER_IMPL 2052#ifdef VFP_INTERPRETER_IMPL
2557VFPLABEL_INST: 2053VCVTBFI_INST:
2558{ 2054{
2559 INC_ICOUNTER;
2560 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2055 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
2561 CHECK_VFP_ENABLED; 2056 CHECK_VFP_ENABLED;
2562 2057
2563 DBG("VCVT(BFI) :\n"); 2058 DBG("VCVT(BFI) :\n");
2564 2059
2565 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2060 vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component;
2566 2061
2567 int ret; 2062 int ret;
2568 2063
@@ -2574,22 +2069,17 @@ VFPLABEL_INST:
2574 CHECK_VFP_CDP_RET; 2069 CHECK_VFP_CDP_RET;
2575 } 2070 }
2576 cpu->Reg[15] += GET_INST_SIZE(cpu); 2071 cpu->Reg[15] += GET_INST_SIZE(cpu);
2577 INC_PC(sizeof(vfpinstr_inst)); 2072 INC_PC(sizeof(vcvtbfi_inst));
2578 FETCH_INST; 2073 FETCH_INST;
2579 GOTO_NEXT_INST; 2074 GOTO_NEXT_INST;
2580} 2075}
2581#endif 2076#endif
2582#ifdef VFP_CDP_TRANS 2077
2583if ((OPC_1 & 0xB) == 0xB && CRn > 7 && (OPC_2 & 0x2) == 2)
2584{
2585 DBG("VCVT(BFI) :\n");
2586}
2587#endif
2588#ifdef VFP_DYNCOM_TABLE 2078#ifdef VFP_DYNCOM_TABLE
2589DYNCOM_FILL_ACTION(vfpinstr), 2079DYNCOM_FILL_ACTION(vcvtbfi),
2590#endif 2080#endif
2591#ifdef VFP_DYNCOM_TAG 2081#ifdef VFP_DYNCOM_TAG
2592int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2082int DYNCOM_TAG(vcvtbfi)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2593{ 2083{
2594 int instr_size = INSTR_SIZE; 2084 int instr_size = INSTR_SIZE;
2595 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2085 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -2600,7 +2090,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
2600} 2090}
2601#endif 2091#endif
2602#ifdef VFP_DYNCOM_TRANS 2092#ifdef VFP_DYNCOM_TRANS
2603int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2093int DYNCOM_TRANS(vcvtbfi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2604 DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__); 2094 DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__);
2605 //arch_arm_undef(cpu, bb, instr); 2095 //arch_arm_undef(cpu, bb, instr);
2606 unsigned int opc2 = BITS(16,18); 2096 unsigned int opc2 = BITS(16,18);
@@ -2694,9 +2184,6 @@ int vcvtbfi_instr_impl(arm_core_t* cpu, uint32 instr){
2694 return 0; 2184 return 0;
2695} 2185}
2696#endif 2186#endif
2697#undef vfpinstr
2698#undef vfpinstr_inst
2699#undef VFPLABEL_INST
2700 2187
2701/* ----------------------------------------------------------------------- */ 2188/* ----------------------------------------------------------------------- */
2702/* MRC / MCR instructions */ 2189/* MRC / MCR instructions */
@@ -2707,35 +2194,20 @@ int vcvtbfi_instr_impl(arm_core_t* cpu, uint32 instr){
2707/* VMOVBRS between register and single precision */ 2194/* VMOVBRS between register and single precision */
2708/* cond 1110 000o Vn-- Rt-- 1010 N001 0000 */ 2195/* cond 1110 000o Vn-- Rt-- 1010 N001 0000 */
2709/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */ 2196/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */
2710#define vfpinstr vmovbrs
2711#define vfpinstr_inst vmovbrs_inst
2712#define VFPLABEL_INST VMOVBRS_INST
2713#ifdef VFP_DECODE
2714{"vmovbrs", 3, ARMVFP2, 21, 27, 0x70, 8, 11, 0xA, 0, 6, 0x10},
2715#endif
2716#ifdef VFP_DECODE_EXCLUSION
2717{"vmovbrs", 0, ARMVFP2, 0},
2718#endif
2719#ifdef VFP_INTERPRETER_TABLE
2720INTERPRETER_TRANSLATE(vfpinstr),
2721#endif
2722#ifdef VFP_INTERPRETER_LABEL
2723&&VFPLABEL_INST,
2724#endif
2725#ifdef VFP_INTERPRETER_STRUCT 2197#ifdef VFP_INTERPRETER_STRUCT
2726typedef struct _vmovbrs_inst { 2198typedef struct _vmovbrs_inst {
2727 unsigned int to_arm; 2199 unsigned int to_arm;
2728 unsigned int t; 2200 unsigned int t;
2729 unsigned int n; 2201 unsigned int n;
2730} vfpinstr_inst; 2202} vmovbrs_inst;
2731#endif 2203#endif
2732#ifdef VFP_INTERPRETER_TRANS 2204#ifdef VFP_INTERPRETER_TRANS
2733ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2205ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrs)(unsigned int inst, int index)
2734{ 2206{
2735 VFP_DEBUG_TRANSLATE; 2207 VFP_DEBUG_TRANSLATE;
2736 2208
2737 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2209 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrs_inst));
2738 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2210 vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component;
2739 2211
2740 inst_base->cond = BITS(inst, 28, 31); 2212 inst_base->cond = BITS(inst, 28, 31);
2741 inst_base->idx = index; 2213 inst_base->idx = index;
@@ -2750,61 +2222,27 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
2750} 2222}
2751#endif 2223#endif
2752#ifdef VFP_INTERPRETER_IMPL 2224#ifdef VFP_INTERPRETER_IMPL
2753VFPLABEL_INST: 2225VMOVBRS_INST:
2754{ 2226{
2755 INC_ICOUNTER;
2756 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2227 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
2757 CHECK_VFP_ENABLED; 2228 CHECK_VFP_ENABLED;
2758 2229
2759 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2230 vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component;
2760 2231
2761 VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t])); 2232 VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t]));
2762 } 2233 }
2763 cpu->Reg[15] += GET_INST_SIZE(cpu); 2234 cpu->Reg[15] += GET_INST_SIZE(cpu);
2764 INC_PC(sizeof(vfpinstr_inst)); 2235 INC_PC(sizeof(vmovbrs_inst));
2765 FETCH_INST; 2236 FETCH_INST;
2766 GOTO_NEXT_INST; 2237 GOTO_NEXT_INST;
2767} 2238}
2768#endif 2239#endif
2769#ifdef VFP_MRC_TRANS 2240
2770if (OPC_1 == 0x0 && CRm == 0 && (OPC_2 & 0x3) == 0)
2771{
2772 /* VMOV r to s */
2773 /* Transfering Rt is not mandatory, as the value of interest is pointed by value */
2774 VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, value);
2775 return ARMul_DONE;
2776}
2777#endif
2778#ifdef VFP_MCR_TRANS
2779if (OPC_1 == 0x0 && CRm == 0 && (OPC_2 & 0x3) == 0)
2780{
2781 /* VMOV s to r */
2782 /* Transfering Rt is not mandatory, as the value of interest is pointed by value */
2783 VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, &value);
2784 return ARMul_DONE;
2785}
2786#endif
2787#ifdef VFP_MRC_IMPL
2788void VMOVBRS(ARMul_State * state, ARMword to_arm, ARMword t, ARMword n, ARMword *value)
2789{
2790 DBG("VMOV(BRS) :\n");
2791 if (to_arm)
2792 {
2793 DBG("\tr%d <= s%d=[%x]\n", t, n, state->ExtReg[n]);
2794 *value = state->ExtReg[n];
2795 }
2796 else
2797 {
2798 DBG("\ts%d <= r%d=[%x]\n", n, t, *value);
2799 state->ExtReg[n] = *value;
2800 }
2801}
2802#endif
2803#ifdef VFP_DYNCOM_TABLE 2241#ifdef VFP_DYNCOM_TABLE
2804DYNCOM_FILL_ACTION(vfpinstr), 2242DYNCOM_FILL_ACTION(vmovbrs),
2805#endif 2243#endif
2806#ifdef VFP_DYNCOM_TAG 2244#ifdef VFP_DYNCOM_TAG
2807int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2245int DYNCOM_TAG(vmovbrs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2808{ 2246{
2809 int instr_size = INSTR_SIZE; 2247 int instr_size = INSTR_SIZE;
2810 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2248 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -2813,7 +2251,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
2813} 2251}
2814#endif 2252#endif
2815#ifdef VFP_DYNCOM_TRANS 2253#ifdef VFP_DYNCOM_TRANS
2816int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2254int DYNCOM_TRANS(vmovbrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2817 DBG("VMOV(BRS) :\n"); 2255 DBG("VMOV(BRS) :\n");
2818 int to_arm = BIT(20) == 1; 2256 int to_arm = BIT(20) == 1;
2819 int t = BITS(12, 15); 2257 int t = BITS(12, 15);
@@ -2832,42 +2270,24 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
2832 return No_exp; 2270 return No_exp;
2833} 2271}
2834#endif 2272#endif
2835#undef vfpinstr
2836#undef vfpinstr_inst
2837#undef VFPLABEL_INST
2838 2273
2839/* ----------------------------------------------------------------------- */ 2274/* ----------------------------------------------------------------------- */
2840/* VMSR */ 2275/* VMSR */
2841/* cond 1110 1110 reg- Rt-- 1010 0001 0000 */ 2276/* cond 1110 1110 reg- Rt-- 1010 0001 0000 */
2842/* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */ 2277/* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */
2843#define vfpinstr vmsr
2844#define vfpinstr_inst vmsr_inst
2845#define VFPLABEL_INST VMSR_INST
2846#ifdef VFP_DECODE
2847{"vmsr", 2, ARMVFP2, 20, 27, 0xEE, 0, 11, 0xA10},
2848#endif
2849#ifdef VFP_DECODE_EXCLUSION
2850{"vmsr", 0, ARMVFP2, 0},
2851#endif
2852#ifdef VFP_INTERPRETER_TABLE
2853INTERPRETER_TRANSLATE(vfpinstr),
2854#endif
2855#ifdef VFP_INTERPRETER_LABEL
2856&&VFPLABEL_INST,
2857#endif
2858#ifdef VFP_INTERPRETER_STRUCT 2278#ifdef VFP_INTERPRETER_STRUCT
2859typedef struct _vmsr_inst { 2279typedef struct _vmsr_inst {
2860 unsigned int reg; 2280 unsigned int reg;
2861 unsigned int Rd; 2281 unsigned int Rd;
2862} vfpinstr_inst; 2282} vmsr_inst;
2863#endif 2283#endif
2864#ifdef VFP_INTERPRETER_TRANS 2284#ifdef VFP_INTERPRETER_TRANS
2865ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2285ARM_INST_PTR INTERPRETER_TRANSLATE(vmsr)(unsigned int inst, int index)
2866{ 2286{
2867 VFP_DEBUG_TRANSLATE; 2287 VFP_DEBUG_TRANSLATE;
2868 2288
2869 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2289 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmsr_inst));
2870 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2290 vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component;
2871 2291
2872 inst_base->cond = BITS(inst, 28, 31); 2292 inst_base->cond = BITS(inst, 28, 31);
2873 inst_base->idx = index; 2293 inst_base->idx = index;
@@ -2881,52 +2301,30 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
2881} 2301}
2882#endif 2302#endif
2883#ifdef VFP_INTERPRETER_IMPL 2303#ifdef VFP_INTERPRETER_IMPL
2884VFPLABEL_INST: 2304VMSR_INST:
2885{ 2305{
2886 INC_ICOUNTER;
2887 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2306 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
2888 /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled , 2307 /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled ,
2889 and in privilegied mode */ 2308 and in privilegied mode */
2890 /* Exceptions must be checked, according to v7 ref manual */ 2309 /* Exceptions must be checked, according to v7 ref manual */
2891 CHECK_VFP_ENABLED; 2310 CHECK_VFP_ENABLED;
2892 2311
2893 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2312 vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component;
2894 2313
2895 VMSR(cpu, inst_cream->reg, inst_cream->Rd); 2314 VMSR(cpu, inst_cream->reg, inst_cream->Rd);
2896 } 2315 }
2897 cpu->Reg[15] += GET_INST_SIZE(cpu); 2316 cpu->Reg[15] += GET_INST_SIZE(cpu);
2898 INC_PC(sizeof(vfpinstr_inst)); 2317 INC_PC(sizeof(vmsr_inst));
2899 FETCH_INST; 2318 FETCH_INST;
2900 GOTO_NEXT_INST; 2319 GOTO_NEXT_INST;
2901} 2320}
2902#endif 2321#endif
2903#ifdef VFP_MCR_TRANS 2322
2904if (OPC_1 == 0x7 && CRm == 0 && OPC_2 == 0)
2905{
2906 VMSR(state, CRn, Rt);
2907 return ARMul_DONE;
2908}
2909#endif
2910#ifdef VFP_MCR_IMPL
2911void VMSR(ARMul_State * state, ARMword reg, ARMword Rt)
2912{
2913 if (reg == 1)
2914 {
2915 DBG("VMSR :\tfpscr <= r%d=[%x]\n", Rt, state->Reg[Rt]);
2916 state->VFP[VFP_OFFSET(VFP_FPSCR)] = state->Reg[Rt];
2917 }
2918 else if (reg == 8)
2919 {
2920 DBG("VMSR :\tfpexc <= r%d=[%x]\n", Rt, state->Reg[Rt]);
2921 state->VFP[VFP_OFFSET(VFP_FPEXC)] = state->Reg[Rt];
2922 }
2923}
2924#endif
2925#ifdef VFP_DYNCOM_TABLE 2323#ifdef VFP_DYNCOM_TABLE
2926DYNCOM_FILL_ACTION(vfpinstr), 2324DYNCOM_FILL_ACTION(vmsr),
2927#endif 2325#endif
2928#ifdef VFP_DYNCOM_TAG 2326#ifdef VFP_DYNCOM_TAG
2929int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2327int DYNCOM_TAG(vmsr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2930{ 2328{
2931 int instr_size = INSTR_SIZE; 2329 int instr_size = INSTR_SIZE;
2932 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2330 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -2936,7 +2334,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
2936} 2334}
2937#endif 2335#endif
2938#ifdef VFP_DYNCOM_TRANS 2336#ifdef VFP_DYNCOM_TRANS
2939int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2337int DYNCOM_TRANS(vmsr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2940 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2338 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2941 //arch_arm_undef(cpu, bb, instr); 2339 //arch_arm_undef(cpu, bb, instr);
2942 DBG("VMSR :"); 2340 DBG("VMSR :");
@@ -2969,44 +2367,26 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
2969 return No_exp; 2367 return No_exp;
2970} 2368}
2971#endif 2369#endif
2972#undef vfpinstr
2973#undef vfpinstr_inst
2974#undef VFPLABEL_INST
2975 2370
2976/* ----------------------------------------------------------------------- */ 2371/* ----------------------------------------------------------------------- */
2977/* VMOVBRC register to scalar */ 2372/* VMOVBRC register to scalar */
2978/* cond 1110 0XX0 Vd-- Rt-- 1011 DXX1 0000 */ 2373/* cond 1110 0XX0 Vd-- Rt-- 1011 DXX1 0000 */
2979/* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */ 2374/* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */
2980#define vfpinstr vmovbrc
2981#define vfpinstr_inst vmovbrc_inst
2982#define VFPLABEL_INST VMOVBRC_INST
2983#ifdef VFP_DECODE
2984{"vmovbrc", 4, ARMVFP2, 23, 27, 0x1C, 20, 20, 0x0, 8,11,0xB, 0,4,0x10},
2985#endif
2986#ifdef VFP_DECODE_EXCLUSION
2987{"vmovbrc", 0, ARMVFP2, 0},
2988#endif
2989#ifdef VFP_INTERPRETER_TABLE
2990INTERPRETER_TRANSLATE(vfpinstr),
2991#endif
2992#ifdef VFP_INTERPRETER_LABEL
2993&&VFPLABEL_INST,
2994#endif
2995#ifdef VFP_INTERPRETER_STRUCT 2375#ifdef VFP_INTERPRETER_STRUCT
2996typedef struct _vmovbrc_inst { 2376typedef struct _vmovbrc_inst {
2997 unsigned int esize; 2377 unsigned int esize;
2998 unsigned int index; 2378 unsigned int index;
2999 unsigned int d; 2379 unsigned int d;
3000 unsigned int t; 2380 unsigned int t;
3001} vfpinstr_inst; 2381} vmovbrc_inst;
3002#endif 2382#endif
3003#ifdef VFP_INTERPRETER_TRANS 2383#ifdef VFP_INTERPRETER_TRANS
3004ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2384ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrc)(unsigned int inst, int index)
3005{ 2385{
3006 VFP_DEBUG_TRANSLATE; 2386 VFP_DEBUG_TRANSLATE;
3007 2387
3008 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2388 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrc_inst));
3009 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2389 vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component;
3010 2390
3011 inst_base->cond = BITS(inst, 28, 31); 2391 inst_base->cond = BITS(inst, 28, 31);
3012 inst_base->idx = index; 2392 inst_base->idx = index;
@@ -3023,34 +2403,27 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
3023} 2403}
3024#endif 2404#endif
3025#ifdef VFP_INTERPRETER_IMPL 2405#ifdef VFP_INTERPRETER_IMPL
3026VFPLABEL_INST: 2406VMOVBRC_INST:
3027{ 2407{
3028 INC_ICOUNTER;
3029 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2408 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
3030 CHECK_VFP_ENABLED; 2409 CHECK_VFP_ENABLED;
3031 2410
3032 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2411 vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component;
3033 2412
3034 VFP_DEBUG_UNIMPLEMENTED(VMOVBRC); 2413 VFP_DEBUG_UNIMPLEMENTED(VMOVBRC);
3035 } 2414 }
3036 cpu->Reg[15] += GET_INST_SIZE(cpu); 2415 cpu->Reg[15] += GET_INST_SIZE(cpu);
3037 INC_PC(sizeof(vfpinstr_inst)); 2416 INC_PC(sizeof(vmovbrc_inst));
3038 FETCH_INST; 2417 FETCH_INST;
3039 GOTO_NEXT_INST; 2418 GOTO_NEXT_INST;
3040} 2419}
3041#endif 2420#endif
3042#ifdef VFP_MCR_TRANS 2421
3043if ((OPC_1 & 0x4) == 0 && CoProc == 11 && CRm == 0)
3044{
3045 VFP_DEBUG_UNIMPLEMENTED(VMOVBRC);
3046 return ARMul_DONE;
3047}
3048#endif
3049#ifdef VFP_DYNCOM_TABLE 2422#ifdef VFP_DYNCOM_TABLE
3050DYNCOM_FILL_ACTION(vfpinstr), 2423DYNCOM_FILL_ACTION(vmovbrc),
3051#endif 2424#endif
3052#ifdef VFP_DYNCOM_TAG 2425#ifdef VFP_DYNCOM_TAG
3053int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2426int DYNCOM_TAG(vmovbrc)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
3054{ 2427{
3055 int instr_size = INSTR_SIZE; 2428 int instr_size = INSTR_SIZE;
3056 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2429 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -3059,48 +2432,30 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
3059} 2432}
3060#endif 2433#endif
3061#ifdef VFP_DYNCOM_TRANS 2434#ifdef VFP_DYNCOM_TRANS
3062int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2435int DYNCOM_TRANS(vmovbrc)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
3063 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2436 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
3064 arch_arm_undef(cpu, bb, instr); 2437 arch_arm_undef(cpu, bb, instr);
3065 return No_exp; 2438 return No_exp;
3066} 2439}
3067#endif 2440#endif
3068#undef vfpinstr
3069#undef vfpinstr_inst
3070#undef VFPLABEL_INST
3071 2441
3072/* ----------------------------------------------------------------------- */ 2442/* ----------------------------------------------------------------------- */
3073/* VMRS */ 2443/* VMRS */
3074/* cond 1110 1111 CRn- Rt-- 1010 0001 0000 */ 2444/* cond 1110 1111 CRn- Rt-- 1010 0001 0000 */
3075/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */ 2445/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */
3076#define vfpinstr vmrs
3077#define vfpinstr_inst vmrs_inst
3078#define VFPLABEL_INST VMRS_INST
3079#ifdef VFP_DECODE
3080{"vmrs", 2, ARMVFP2, 20, 27, 0xEF, 0, 11, 0xa10},
3081#endif
3082#ifdef VFP_DECODE_EXCLUSION
3083{"vmrs", 0, ARMVFP2, 0},
3084#endif
3085#ifdef VFP_INTERPRETER_TABLE
3086INTERPRETER_TRANSLATE(vfpinstr),
3087#endif
3088#ifdef VFP_INTERPRETER_LABEL
3089&&VFPLABEL_INST,
3090#endif
3091#ifdef VFP_INTERPRETER_STRUCT 2446#ifdef VFP_INTERPRETER_STRUCT
3092typedef struct _vmrs_inst { 2447typedef struct _vmrs_inst {
3093 unsigned int reg; 2448 unsigned int reg;
3094 unsigned int Rt; 2449 unsigned int Rt;
3095} vfpinstr_inst; 2450} vmrs_inst;
3096#endif 2451#endif
3097#ifdef VFP_INTERPRETER_TRANS 2452#ifdef VFP_INTERPRETER_TRANS
3098ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2453ARM_INST_PTR INTERPRETER_TRANSLATE(vmrs)(unsigned int inst, int index)
3099{ 2454{
3100 VFP_DEBUG_TRANSLATE; 2455 VFP_DEBUG_TRANSLATE;
3101 2456
3102 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2457 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmrs_inst));
3103 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2458 vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component;
3104 2459
3105 inst_base->cond = BITS(inst, 28, 31); 2460 inst_base->cond = BITS(inst, 28, 31);
3106 inst_base->idx = index; 2461 inst_base->idx = index;
@@ -3109,21 +2464,20 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
3109 2464
3110 inst_cream->reg = BITS(inst, 16, 19); 2465 inst_cream->reg = BITS(inst, 16, 19);
3111 inst_cream->Rt = BITS(inst, 12, 15); 2466 inst_cream->Rt = BITS(inst, 12, 15);
3112 2467
3113 return inst_base; 2468 return inst_base;
3114} 2469}
3115#endif 2470#endif
3116#ifdef VFP_INTERPRETER_IMPL 2471#ifdef VFP_INTERPRETER_IMPL
3117VFPLABEL_INST: 2472VMRS_INST:
3118{ 2473{
3119 INC_ICOUNTER;
3120 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2474 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
3121 /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled, 2475 /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled,
3122 and in privilegied mode */ 2476 and in privilegied mode */
3123 /* Exceptions must be checked, according to v7 ref manual */ 2477 /* Exceptions must be checked, according to v7 ref manual */
3124 CHECK_VFP_ENABLED; 2478 CHECK_VFP_ENABLED;
3125 2479
3126 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2480 vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component;
3127 2481
3128 DBG("VMRS :"); 2482 DBG("VMRS :");
3129 2483
@@ -3170,67 +2524,17 @@ VFPLABEL_INST:
3170 } 2524 }
3171 } 2525 }
3172 cpu->Reg[15] += GET_INST_SIZE(cpu); 2526 cpu->Reg[15] += GET_INST_SIZE(cpu);
3173 INC_PC(sizeof(vfpinstr_inst)); 2527 INC_PC(sizeof(vmrs_inst));
3174 FETCH_INST; 2528 FETCH_INST;
3175 GOTO_NEXT_INST; 2529 GOTO_NEXT_INST;
3176} 2530}
3177#endif 2531#endif
3178#ifdef VFP_MRC_TRANS 2532
3179if (OPC_1 == 0x7 && CRm == 0 && OPC_2 == 0)
3180{
3181 VMRS(state, CRn, Rt, value);
3182 return ARMul_DONE;
3183}
3184#endif
3185#ifdef VFP_MRC_IMPL
3186void VMRS(ARMul_State * state, ARMword reg, ARMword Rt, ARMword * value)
3187{
3188 DBG("VMRS :");
3189 if (reg == 1)
3190 {
3191 if (Rt != 15)
3192 {
3193 *value = state->VFP[VFP_OFFSET(VFP_FPSCR)];
3194 DBG("\tr%d <= fpscr[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPSCR)]);
3195 }
3196 else
3197 {
3198 *value = state->VFP[VFP_OFFSET(VFP_FPSCR)] ;
3199 DBG("\tflags <= fpscr[%1xxxxxxxx]\n", state->VFP[VFP_OFFSET(VFP_FPSCR)]>>28);
3200 }
3201 }
3202 else
3203 {
3204 switch (reg)
3205 {
3206 case 0:
3207 *value = state->VFP[VFP_OFFSET(VFP_FPSID)];
3208 DBG("\tr%d <= fpsid[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPSID)]);
3209 break;
3210 case 6:
3211 /* MVFR1, VFPv3 only ? */
3212 DBG("\tr%d <= MVFR1 unimplemented\n", Rt);
3213 break;
3214 case 7:
3215 /* MVFR0, VFPv3 only? */
3216 DBG("\tr%d <= MVFR0 unimplemented\n", Rt);
3217 break;
3218 case 8:
3219 *value = state->VFP[VFP_OFFSET(VFP_FPEXC)];
3220 DBG("\tr%d <= fpexc[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPEXC)]);
3221 break;
3222 default:
3223 DBG("\tSUBARCHITECTURE DEFINED\n");
3224 break;
3225 }
3226 }
3227}
3228#endif
3229#ifdef VFP_DYNCOM_TABLE 2533#ifdef VFP_DYNCOM_TABLE
3230DYNCOM_FILL_ACTION(vfpinstr), 2534DYNCOM_FILL_ACTION(vmrs),
3231#endif 2535#endif
3232#ifdef VFP_DYNCOM_TAG 2536#ifdef VFP_DYNCOM_TAG
3233int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2537int DYNCOM_TAG(vmrs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
3234{ 2538{
3235 int instr_size = INSTR_SIZE; 2539 int instr_size = INSTR_SIZE;
3236 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2540 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -3241,7 +2545,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
3241} 2545}
3242#endif 2546#endif
3243#ifdef VFP_DYNCOM_TRANS 2547#ifdef VFP_DYNCOM_TRANS
3244int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2548int DYNCOM_TRANS(vmrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
3245 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2549 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
3246 //arch_arm_undef(cpu, bb, instr); 2550 //arch_arm_undef(cpu, bb, instr);
3247 2551
@@ -3292,44 +2596,26 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
3292 return No_exp; 2596 return No_exp;
3293} 2597}
3294#endif 2598#endif
3295#undef vfpinstr
3296#undef vfpinstr_inst
3297#undef VFPLABEL_INST
3298 2599
3299/* ----------------------------------------------------------------------- */ 2600/* ----------------------------------------------------------------------- */
3300/* VMOVBCR scalar to register */ 2601/* VMOVBCR scalar to register */
3301/* cond 1110 XXX1 Vd-- Rt-- 1011 NXX1 0000 */ 2602/* cond 1110 XXX1 Vd-- Rt-- 1011 NXX1 0000 */
3302/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MCR */ 2603/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MCR */
3303#define vfpinstr vmovbcr
3304#define vfpinstr_inst vmovbcr_inst
3305#define VFPLABEL_INST VMOVBCR_INST
3306#ifdef VFP_DECODE
3307{"vmovbcr", 4, ARMVFP2, 24, 27, 0xE, 20, 20, 1, 8, 11,0xB, 0,4, 0x10},
3308#endif
3309#ifdef VFP_DECODE_EXCLUSION
3310{"vmovbcr", 0, ARMVFP2, 0},
3311#endif
3312#ifdef VFP_INTERPRETER_TABLE
3313INTERPRETER_TRANSLATE(vfpinstr),
3314#endif
3315#ifdef VFP_INTERPRETER_LABEL
3316&&VFPLABEL_INST,
3317#endif
3318#ifdef VFP_INTERPRETER_STRUCT 2604#ifdef VFP_INTERPRETER_STRUCT
3319typedef struct _vmovbcr_inst { 2605typedef struct _vmovbcr_inst {
3320 unsigned int esize; 2606 unsigned int esize;
3321 unsigned int index; 2607 unsigned int index;
3322 unsigned int d; 2608 unsigned int d;
3323 unsigned int t; 2609 unsigned int t;
3324} vfpinstr_inst; 2610} vmovbcr_inst;
3325#endif 2611#endif
3326#ifdef VFP_INTERPRETER_TRANS 2612#ifdef VFP_INTERPRETER_TRANS
3327ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2613ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbcr)(unsigned int inst, int index)
3328{ 2614{
3329 VFP_DEBUG_TRANSLATE; 2615 VFP_DEBUG_TRANSLATE;
3330 2616
3331 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2617 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbcr_inst));
3332 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2618 vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component;
3333 2619
3334 inst_base->cond = BITS(inst, 28, 31); 2620 inst_base->cond = BITS(inst, 28, 31);
3335 inst_base->idx = index; 2621 inst_base->idx = index;
@@ -3346,34 +2632,27 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
3346} 2632}
3347#endif 2633#endif
3348#ifdef VFP_INTERPRETER_IMPL 2634#ifdef VFP_INTERPRETER_IMPL
3349VFPLABEL_INST: 2635VMOVBCR_INST:
3350{ 2636{
3351 INC_ICOUNTER;
3352 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2637 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
3353 CHECK_VFP_ENABLED; 2638 CHECK_VFP_ENABLED;
3354 2639
3355 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2640 vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component;
3356 2641
3357 VFP_DEBUG_UNIMPLEMENTED(VMOVBCR); 2642 VFP_DEBUG_UNIMPLEMENTED(VMOVBCR);
3358 } 2643 }
3359 cpu->Reg[15] += GET_INST_SIZE(cpu); 2644 cpu->Reg[15] += GET_INST_SIZE(cpu);
3360 INC_PC(sizeof(vfpinstr_inst)); 2645 INC_PC(sizeof(vmovbcr_inst));
3361 FETCH_INST; 2646 FETCH_INST;
3362 GOTO_NEXT_INST; 2647 GOTO_NEXT_INST;
3363} 2648}
3364#endif 2649#endif
3365#ifdef VFP_MCR_TRANS 2650
3366if (CoProc == 11 && CRm == 0)
3367{
3368 VFP_DEBUG_UNIMPLEMENTED(VMOVBCR);
3369 return ARMul_DONE;
3370}
3371#endif
3372#ifdef VFP_DYNCOM_TABLE 2651#ifdef VFP_DYNCOM_TABLE
3373DYNCOM_FILL_ACTION(vfpinstr), 2652DYNCOM_FILL_ACTION(vmovbcr),
3374#endif 2653#endif
3375#ifdef VFP_DYNCOM_TAG 2654#ifdef VFP_DYNCOM_TAG
3376int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2655int DYNCOM_TAG(vmovbcr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
3377{ 2656{
3378 int instr_size = INSTR_SIZE; 2657 int instr_size = INSTR_SIZE;
3379 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2658 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -3382,15 +2661,12 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
3382} 2661}
3383#endif 2662#endif
3384#ifdef VFP_DYNCOM_TRANS 2663#ifdef VFP_DYNCOM_TRANS
3385int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2664int DYNCOM_TRANS(vmovbcr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
3386 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2665 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
3387 arch_arm_undef(cpu, bb, instr); 2666 arch_arm_undef(cpu, bb, instr);
3388 return No_exp; 2667 return No_exp;
3389} 2668}
3390#endif 2669#endif
3391#undef vfpinstr
3392#undef vfpinstr_inst
3393#undef VFPLABEL_INST
3394 2670
3395/* ----------------------------------------------------------------------- */ 2671/* ----------------------------------------------------------------------- */
3396/* MRRC / MCRR instructions */ 2672/* MRRC / MCRR instructions */
@@ -3401,36 +2677,21 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
3401/* VMOVBRRSS between 2 registers to 2 singles */ 2677/* VMOVBRRSS between 2 registers to 2 singles */
3402/* cond 1100 010X Rt2- Rt-- 1010 00X1 Vm-- */ 2678/* cond 1100 010X Rt2- Rt-- 1010 00X1 Vm-- */
3403/* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */ 2679/* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */
3404#define vfpinstr vmovbrrss
3405#define vfpinstr_inst vmovbrrss_inst
3406#define VFPLABEL_INST VMOVBRRSS_INST
3407#ifdef VFP_DECODE
3408{"vmovbrrss", 3, ARMVFP2, 21, 27, 0x62, 8, 11, 0xA, 4, 4, 1},
3409#endif
3410#ifdef VFP_DECODE_EXCLUSION
3411{"vmovbrrss", 0, ARMVFP2, 0},
3412#endif
3413#ifdef VFP_INTERPRETER_TABLE
3414INTERPRETER_TRANSLATE(vfpinstr),
3415#endif
3416#ifdef VFP_INTERPRETER_LABEL
3417&&VFPLABEL_INST,
3418#endif
3419#ifdef VFP_INTERPRETER_STRUCT 2680#ifdef VFP_INTERPRETER_STRUCT
3420typedef struct _vmovbrrss_inst { 2681typedef struct _vmovbrrss_inst {
3421 unsigned int to_arm; 2682 unsigned int to_arm;
3422 unsigned int t; 2683 unsigned int t;
3423 unsigned int t2; 2684 unsigned int t2;
3424 unsigned int m; 2685 unsigned int m;
3425} vfpinstr_inst; 2686} vmovbrrss_inst;
3426#endif 2687#endif
3427#ifdef VFP_INTERPRETER_TRANS 2688#ifdef VFP_INTERPRETER_TRANS
3428ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2689ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrss)(unsigned int inst, int index)
3429{ 2690{
3430 VFP_DEBUG_TRANSLATE; 2691 VFP_DEBUG_TRANSLATE;
3431 2692
3432 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2693 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrss_inst));
3433 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2694 vmovbrrss_inst *inst_cream = (vmovbrrss_inst *)inst_base->component;
3434 2695
3435 inst_base->cond = BITS(inst, 28, 31); 2696 inst_base->cond = BITS(inst, 28, 31);
3436 inst_base->idx = index; 2697 inst_base->idx = index;
@@ -3446,41 +2707,26 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
3446} 2707}
3447#endif 2708#endif
3448#ifdef VFP_INTERPRETER_IMPL 2709#ifdef VFP_INTERPRETER_IMPL
3449VFPLABEL_INST: 2710VMOVBRRSS_INST:
3450{ 2711{
3451 INC_ICOUNTER;
3452 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2712 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
3453 CHECK_VFP_ENABLED; 2713 CHECK_VFP_ENABLED;
3454 2714
3455 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2715 vmovbrrss_inst *inst_cream = (vmovbrrss_inst *)inst_base->component;
3456 2716
3457 VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS); 2717 VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS);
3458 } 2718 }
3459 cpu->Reg[15] += GET_INST_SIZE(cpu); 2719 cpu->Reg[15] += GET_INST_SIZE(cpu);
3460 INC_PC(sizeof(vfpinstr_inst)); 2720 INC_PC(sizeof(vmovbrrss_inst));
3461 FETCH_INST; 2721 FETCH_INST;
3462 GOTO_NEXT_INST; 2722 GOTO_NEXT_INST;
3463} 2723}
3464#endif 2724#endif
3465#ifdef VFP_MCRR_TRANS
3466if (CoProc == 10 && (OPC_1 & 0xD) == 1)
3467{
3468 VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS);
3469 return ARMul_DONE;
3470}
3471#endif
3472#ifdef VFP_MRRC_TRANS
3473if (CoProc == 10 && (OPC_1 & 0xD) == 1)
3474{
3475 VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS);
3476 return ARMul_DONE;
3477}
3478#endif
3479#ifdef VFP_DYNCOM_TABLE 2725#ifdef VFP_DYNCOM_TABLE
3480DYNCOM_FILL_ACTION(vfpinstr), 2726DYNCOM_FILL_ACTION(vmovbrrss),
3481#endif 2727#endif
3482#ifdef VFP_DYNCOM_TAG 2728#ifdef VFP_DYNCOM_TAG
3483int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2729int DYNCOM_TAG(vmovbrrss)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
3484{ 2730{
3485 int instr_size = INSTR_SIZE; 2731 int instr_size = INSTR_SIZE;
3486 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2732 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -3489,50 +2735,32 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
3489} 2735}
3490#endif 2736#endif
3491#ifdef VFP_DYNCOM_TRANS 2737#ifdef VFP_DYNCOM_TRANS
3492int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2738int DYNCOM_TRANS(vmovbrrss)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
3493 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2739 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
3494 arch_arm_undef(cpu, bb, instr); 2740 arch_arm_undef(cpu, bb, instr);
3495 return No_exp; 2741 return No_exp;
3496} 2742}
3497#endif 2743#endif
3498#undef vfpinstr
3499#undef vfpinstr_inst
3500#undef VFPLABEL_INST
3501 2744
3502/* ----------------------------------------------------------------------- */ 2745/* ----------------------------------------------------------------------- */
3503/* VMOVBRRD between 2 registers and 1 double */ 2746/* VMOVBRRD between 2 registers and 1 double */
3504/* cond 1100 010X Rt2- Rt-- 1011 00X1 Vm-- */ 2747/* cond 1100 010X Rt2- Rt-- 1011 00X1 Vm-- */
3505/* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */ 2748/* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */
3506#define vfpinstr vmovbrrd
3507#define vfpinstr_inst vmovbrrd_inst
3508#define VFPLABEL_INST VMOVBRRD_INST
3509#ifdef VFP_DECODE
3510{"vmovbrrd", 3, ARMVFP2, 21, 27, 0x62, 6, 11, 0x2c, 4, 4, 1},
3511#endif
3512#ifdef VFP_DECODE_EXCLUSION
3513{"vmovbrrd", 0, ARMVFP2, 0},
3514#endif
3515#ifdef VFP_INTERPRETER_TABLE
3516INTERPRETER_TRANSLATE(vfpinstr),
3517#endif
3518#ifdef VFP_INTERPRETER_LABEL
3519&&VFPLABEL_INST,
3520#endif
3521#ifdef VFP_INTERPRETER_STRUCT 2749#ifdef VFP_INTERPRETER_STRUCT
3522typedef struct _vmovbrrd_inst { 2750typedef struct _vmovbrrd_inst {
3523 unsigned int to_arm; 2751 unsigned int to_arm;
3524 unsigned int t; 2752 unsigned int t;
3525 unsigned int t2; 2753 unsigned int t2;
3526 unsigned int m; 2754 unsigned int m;
3527} vfpinstr_inst; 2755} vmovbrrd_inst;
3528#endif 2756#endif
3529#ifdef VFP_INTERPRETER_TRANS 2757#ifdef VFP_INTERPRETER_TRANS
3530ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2758ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrd)(unsigned int inst, int index)
3531{ 2759{
3532 VFP_DEBUG_TRANSLATE; 2760 VFP_DEBUG_TRANSLATE;
3533 2761
3534 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2762 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrd_inst));
3535 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2763 vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component;
3536 2764
3537 inst_base->cond = BITS(inst, 28, 31); 2765 inst_base->cond = BITS(inst, 28, 31);
3538 inst_base->idx = index; 2766 inst_base->idx = index;
@@ -3548,63 +2776,28 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
3548} 2776}
3549#endif 2777#endif
3550#ifdef VFP_INTERPRETER_IMPL 2778#ifdef VFP_INTERPRETER_IMPL
3551VFPLABEL_INST: 2779VMOVBRRD_INST:
3552{ 2780{
3553 INC_ICOUNTER;
3554 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2781 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
3555 CHECK_VFP_ENABLED; 2782 CHECK_VFP_ENABLED;
3556 2783
3557 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2784 vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component;
3558 2785
3559 VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, 2786 VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m,
3560 &(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2])); 2787 &(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2]));
3561 } 2788 }
3562 cpu->Reg[15] += GET_INST_SIZE(cpu); 2789 cpu->Reg[15] += GET_INST_SIZE(cpu);
3563 INC_PC(sizeof(vfpinstr_inst)); 2790 INC_PC(sizeof(vmovbrrd_inst));
3564 FETCH_INST; 2791 FETCH_INST;
3565 GOTO_NEXT_INST; 2792 GOTO_NEXT_INST;
3566} 2793}
3567#endif 2794#endif
3568#ifdef VFP_MCRR_TRANS
3569if (CoProc == 11 && (OPC_1 & 0xD) == 1)
3570{
3571 /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */
3572 VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, &value1, &value2);
3573 return ARMul_DONE;
3574}
3575#endif
3576#ifdef VFP_MRRC_TRANS
3577if (CoProc == 11 && (OPC_1 & 0xD) == 1)
3578{
3579 /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */
3580 VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, value1, value2);
3581 return ARMul_DONE;
3582}
3583#endif
3584#ifdef VFP_MRRC_IMPL
3585void VMOVBRRD(ARMul_State * state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword *value1, ARMword *value2)
3586{
3587 DBG("VMOV(BRRD) :\n");
3588 if (to_arm)
3589 {
3590 DBG("\tr[%d-%d] <= s[%d-%d]=[%x-%x]\n", t2, t, n*2+1, n*2, state->ExtReg[n*2+1], state->ExtReg[n*2]);
3591 *value2 = state->ExtReg[n*2+1];
3592 *value1 = state->ExtReg[n*2];
3593 }
3594 else
3595 {
3596 DBG("\ts[%d-%d] <= r[%d-%d]=[%x-%x]\n", n*2+1, n*2, t2, t, *value2, *value1);
3597 state->ExtReg[n*2+1] = *value2;
3598 state->ExtReg[n*2] = *value1;
3599 }
3600}
3601 2795
3602#endif
3603#ifdef VFP_DYNCOM_TABLE 2796#ifdef VFP_DYNCOM_TABLE
3604DYNCOM_FILL_ACTION(vfpinstr), 2797DYNCOM_FILL_ACTION(vmovbrrd),
3605#endif 2798#endif
3606#ifdef VFP_DYNCOM_TAG 2799#ifdef VFP_DYNCOM_TAG
3607int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2800int DYNCOM_TAG(vmovbrrd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
3608{ 2801{
3609 int instr_size = INSTR_SIZE; 2802 int instr_size = INSTR_SIZE;
3610 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2803 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -3615,7 +2808,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
3615} 2808}
3616#endif 2809#endif
3617#ifdef VFP_DYNCOM_TRANS 2810#ifdef VFP_DYNCOM_TRANS
3618int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2811int DYNCOM_TRANS(vmovbrrd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
3619 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2812 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
3620 //arch_arm_undef(cpu, bb, instr); 2813 //arch_arm_undef(cpu, bb, instr);
3621 int to_arm = BIT(20) == 1; 2814 int to_arm = BIT(20) == 1;
@@ -3633,9 +2826,6 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
3633 return No_exp; 2826 return No_exp;
3634} 2827}
3635#endif 2828#endif
3636#undef vfpinstr
3637#undef vfpinstr_inst
3638#undef VFPLABEL_INST
3639 2829
3640/* ----------------------------------------------------------------------- */ 2830/* ----------------------------------------------------------------------- */
3641/* LDC/STC between 2 registers and 1 double */ 2831/* LDC/STC between 2 registers and 1 double */
@@ -3645,21 +2835,6 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
3645/* ----------------------------------------------------------------------- */ 2835/* ----------------------------------------------------------------------- */
3646/* VSTR */ 2836/* VSTR */
3647/* cond 1101 UD00 Rn-- Vd-- 101X imm8 imm8 */ 2837/* cond 1101 UD00 Rn-- Vd-- 101X imm8 imm8 */
3648#define vfpinstr vstr
3649#define vfpinstr_inst vstr_inst
3650#define VFPLABEL_INST VSTR_INST
3651#ifdef VFP_DECODE
3652{"vstr", 3, ARMVFP2, 24, 27, 0xd, 20, 21, 0, 9, 11, 0x5},
3653#endif
3654#ifdef VFP_DECODE_EXCLUSION
3655{"vstr", 0, ARMVFP2, 0},
3656#endif
3657#ifdef VFP_INTERPRETER_TABLE
3658INTERPRETER_TRANSLATE(vfpinstr),
3659#endif
3660#ifdef VFP_INTERPRETER_LABEL
3661&&VFPLABEL_INST,
3662#endif
3663#ifdef VFP_INTERPRETER_STRUCT 2838#ifdef VFP_INTERPRETER_STRUCT
3664typedef struct _vstr_inst { 2839typedef struct _vstr_inst {
3665 unsigned int single; 2840 unsigned int single;
@@ -3667,15 +2842,15 @@ typedef struct _vstr_inst {
3667 unsigned int d; 2842 unsigned int d;
3668 unsigned int imm32; 2843 unsigned int imm32;
3669 unsigned int add; 2844 unsigned int add;
3670} vfpinstr_inst; 2845} vstr_inst;
3671#endif 2846#endif
3672#ifdef VFP_INTERPRETER_TRANS 2847#ifdef VFP_INTERPRETER_TRANS
3673ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2848ARM_INST_PTR INTERPRETER_TRANSLATE(vstr)(unsigned int inst, int index)
3674{ 2849{
3675 VFP_DEBUG_TRANSLATE; 2850 VFP_DEBUG_TRANSLATE;
3676 2851
3677 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2852 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstr_inst));
3678 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2853 vstr_inst *inst_cream = (vstr_inst *)inst_base->component;
3679 2854
3680 inst_base->cond = BITS(inst, 28, 31); 2855 inst_base->cond = BITS(inst, 28, 31);
3681 inst_base->idx = index; 2856 inst_base->idx = index;
@@ -3692,13 +2867,12 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
3692} 2867}
3693#endif 2868#endif
3694#ifdef VFP_INTERPRETER_IMPL 2869#ifdef VFP_INTERPRETER_IMPL
3695VFPLABEL_INST: 2870VSTR_INST:
3696{ 2871{
3697 INC_ICOUNTER;
3698 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2872 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
3699 CHECK_VFP_ENABLED; 2873 CHECK_VFP_ENABLED;
3700 2874
3701 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2875 vstr_inst *inst_cream = (vstr_inst *)inst_base->component;
3702 2876
3703 unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]); 2877 unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]);
3704 addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32); 2878 addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32);
@@ -3736,65 +2910,12 @@ VFPLABEL_INST:
3736 GOTO_NEXT_INST; 2910 GOTO_NEXT_INST;
3737} 2911}
3738#endif 2912#endif
3739#ifdef VFP_STC_TRANS
3740if (P == 1 && W == 0)
3741{
3742 return VSTR(state, type, instr, value);
3743}
3744#endif
3745#ifdef VFP_STC_IMPL
3746int VSTR(ARMul_State * state, int type, ARMword instr, ARMword * value)
3747{
3748 static int i = 0;
3749 static int single_reg, add, d, n, imm32, regs;
3750 if (type == ARMul_FIRST)
3751 {
3752 single_reg = BIT(8) == 0; /* Double precision */
3753 add = BIT(23); /* */
3754 imm32 = BITS(0,7)<<2; /* may not be used */
3755 d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
3756 n = BITS(16, 19); /* destination register */
3757
3758 DBG("VSTR :\n");
3759
3760 i = 0;
3761 regs = 1;
3762
3763 return ARMul_DONE;
3764 }
3765 else if (type == ARMul_DATA)
3766 {
3767 if (single_reg)
3768 {
3769 *value = state->ExtReg[d+i];
3770 DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d+i]);
3771 i++;
3772 if (i < regs)
3773 return ARMul_INC;
3774 else
3775 return ARMul_DONE;
3776 }
3777 else
3778 {
3779 /* FIXME Careful of endianness, may need to rework this */
3780 *value = state->ExtReg[d*2+i];
3781 DBG("\taddr[?] <= s[%d]=[%x]\n", d*2+i, state->ExtReg[d*2+i]);
3782 i++;
3783 if (i < regs*2)
3784 return ARMul_INC;
3785 else
3786 return ARMul_DONE;
3787 }
3788 }
3789 2913
3790 return -1;
3791}
3792#endif
3793#ifdef VFP_DYNCOM_TABLE 2914#ifdef VFP_DYNCOM_TABLE
3794DYNCOM_FILL_ACTION(vfpinstr), 2915DYNCOM_FILL_ACTION(vstr),
3795#endif 2916#endif
3796#ifdef VFP_DYNCOM_TAG 2917#ifdef VFP_DYNCOM_TAG
3797int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2918int DYNCOM_TAG(vstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
3798{ 2919{
3799 int instr_size = INSTR_SIZE; 2920 int instr_size = INSTR_SIZE;
3800 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 2921 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
@@ -3807,7 +2928,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
3807} 2928}
3808#endif 2929#endif
3809#ifdef VFP_DYNCOM_TRANS 2930#ifdef VFP_DYNCOM_TRANS
3810int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2931int DYNCOM_TRANS(vstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
3811 int single = BIT(8) == 0; 2932 int single = BIT(8) == 0;
3812 int add = BIT(23); 2933 int add = BIT(23);
3813 int imm32 = BITS(0,7) << 2; 2934 int imm32 = BITS(0,7) << 2;
@@ -3853,43 +2974,25 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
3853 return No_exp; 2974 return No_exp;
3854} 2975}
3855#endif 2976#endif
3856#undef vfpinstr
3857#undef vfpinstr_inst
3858#undef VFPLABEL_INST
3859 2977
3860/* ----------------------------------------------------------------------- */ 2978/* ----------------------------------------------------------------------- */
3861/* VPUSH */ 2979/* VPUSH */
3862/* cond 1101 0D10 1101 Vd-- 101X imm8 imm8 */ 2980/* cond 1101 0D10 1101 Vd-- 101X imm8 imm8 */
3863#define vfpinstr vpush
3864#define vfpinstr_inst vpush_inst
3865#define VFPLABEL_INST VPUSH_INST
3866#ifdef VFP_DECODE
3867{"vpush", 3, ARMVFP2, 23, 27, 0x1a, 16, 21, 0x2d, 9, 11, 0x5},
3868#endif
3869#ifdef VFP_DECODE_EXCLUSION
3870{"vpush", 0, ARMVFP2, 0},
3871#endif
3872#ifdef VFP_INTERPRETER_TABLE
3873INTERPRETER_TRANSLATE(vfpinstr),
3874#endif
3875#ifdef VFP_INTERPRETER_LABEL
3876&&VFPLABEL_INST,
3877#endif
3878#ifdef VFP_INTERPRETER_STRUCT 2981#ifdef VFP_INTERPRETER_STRUCT
3879typedef struct _vpush_inst { 2982typedef struct _vpush_inst {
3880 unsigned int single; 2983 unsigned int single;
3881 unsigned int d; 2984 unsigned int d;
3882 unsigned int imm32; 2985 unsigned int imm32;
3883 unsigned int regs; 2986 unsigned int regs;
3884} vfpinstr_inst; 2987} vpush_inst;
3885#endif 2988#endif
3886#ifdef VFP_INTERPRETER_TRANS 2989#ifdef VFP_INTERPRETER_TRANS
3887ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2990ARM_INST_PTR INTERPRETER_TRANSLATE(vpush)(unsigned int inst, int index)
3888{ 2991{
3889 VFP_DEBUG_TRANSLATE; 2992 VFP_DEBUG_TRANSLATE;
3890 2993
3891 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2994 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpush_inst));
3892 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2995 vpush_inst *inst_cream = (vpush_inst *)inst_base->component;
3893 2996
3894 inst_base->cond = BITS(inst, 28, 31); 2997 inst_base->cond = BITS(inst, 28, 31);
3895 inst_base->idx = index; 2998 inst_base->idx = index;
@@ -3905,15 +3008,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
3905} 3008}
3906#endif 3009#endif
3907#ifdef VFP_INTERPRETER_IMPL 3010#ifdef VFP_INTERPRETER_IMPL
3908VFPLABEL_INST: 3011VPUSH_INST:
3909{ 3012{
3910 INC_ICOUNTER;
3911 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 3013 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
3912 CHECK_VFP_ENABLED; 3014 CHECK_VFP_ENABLED;
3913 3015
3914 int i; 3016 int i;
3915 3017
3916 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3018 vpush_inst *inst_cream = (vpush_inst *)inst_base->component;
3917 3019
3918 DBG("VPUSH :\n"); 3020 DBG("VPUSH :\n");
3919 3021
@@ -3958,66 +3060,11 @@ VFPLABEL_INST:
3958 GOTO_NEXT_INST; 3060 GOTO_NEXT_INST;
3959} 3061}
3960#endif 3062#endif
3961#ifdef VFP_STC_TRANS
3962if (P == 1 && U == 0 && W == 1 && Rn == 0xD)
3963{
3964 return VPUSH(state, type, instr, value);
3965}
3966#endif
3967#ifdef VFP_STC_IMPL
3968int VPUSH(ARMul_State * state, int type, ARMword instr, ARMword * value)
3969{
3970 static int i = 0;
3971 static int single_regs, add, wback, d, n, imm32, regs;
3972 if (type == ARMul_FIRST)
3973 {
3974 single_regs = BIT(8) == 0; /* Single precision */
3975 d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
3976 imm32 = BITS(0,7)<<2; /* may not be used */
3977 regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FSTMX if regs is odd */
3978
3979 DBG("VPUSH :\n");
3980 DBG("\tsp[%x]", state->Reg[R13]);
3981 state->Reg[R13] = state->Reg[R13] - imm32;
3982 DBG("=>[%x]\n", state->Reg[R13]);
3983
3984 i = 0;
3985
3986 return ARMul_DONE;
3987 }
3988 else if (type == ARMul_DATA)
3989 {
3990 if (single_regs)
3991 {
3992 *value = state->ExtReg[d + i];
3993 DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d + i]);
3994 i++;
3995 if (i < regs)
3996 return ARMul_INC;
3997 else
3998 return ARMul_DONE;
3999 }
4000 else
4001 {
4002 /* FIXME Careful of endianness, may need to rework this */
4003 *value = state->ExtReg[d*2 + i];
4004 DBG("\taddr[?] <= s[%d]=[%x]\n", d*2 + i, state->ExtReg[d*2 + i]);
4005 i++;
4006 if (i < regs*2)
4007 return ARMul_INC;
4008 else
4009 return ARMul_DONE;
4010 }
4011 }
4012
4013 return -1;
4014}
4015#endif
4016#ifdef VFP_DYNCOM_TABLE 3063#ifdef VFP_DYNCOM_TABLE
4017DYNCOM_FILL_ACTION(vfpinstr), 3064DYNCOM_FILL_ACTION(vpush),
4018#endif 3065#endif
4019#ifdef VFP_DYNCOM_TAG 3066#ifdef VFP_DYNCOM_TAG
4020int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 3067int DYNCOM_TAG(vpush)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
4021{ 3068{
4022 int instr_size = INSTR_SIZE; 3069 int instr_size = INSTR_SIZE;
4023 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 3070 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
@@ -4030,7 +3077,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
4030} 3077}
4031#endif 3078#endif
4032#ifdef VFP_DYNCOM_TRANS 3079#ifdef VFP_DYNCOM_TRANS
4033int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 3080int DYNCOM_TRANS(vpush)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
4034 int single = BIT(8) == 0; 3081 int single = BIT(8) == 0;
4035 int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4)); 3082 int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4));
4036 int imm32 = BITS(0, 7)<<2; 3083 int imm32 = BITS(0, 7)<<2;
@@ -4087,28 +3134,10 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
4087 return No_exp; 3134 return No_exp;
4088} 3135}
4089#endif 3136#endif
4090#undef vfpinstr
4091#undef vfpinstr_inst
4092#undef VFPLABEL_INST
4093 3137
4094/* ----------------------------------------------------------------------- */ 3138/* ----------------------------------------------------------------------- */
4095/* VSTM */ 3139/* VSTM */
4096/* cond 110P UDW0 Rn-- Vd-- 101X imm8 imm8 */ 3140/* cond 110P UDW0 Rn-- Vd-- 101X imm8 imm8 */
4097#define vfpinstr vstm
4098#define vfpinstr_inst vstm_inst
4099#define VFPLABEL_INST VSTM_INST
4100#ifdef VFP_DECODE
4101{"vstm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 0, 9, 11, 0x5},
4102#endif
4103#ifdef VFP_DECODE_EXCLUSION
4104{"vstm", 0, ARMVFP2, 0},
4105#endif
4106#ifdef VFP_INTERPRETER_TABLE
4107INTERPRETER_TRANSLATE(vfpinstr),
4108#endif
4109#ifdef VFP_INTERPRETER_LABEL
4110&&VFPLABEL_INST,
4111#endif
4112#ifdef VFP_INTERPRETER_STRUCT 3141#ifdef VFP_INTERPRETER_STRUCT
4113typedef struct _vstm_inst { 3142typedef struct _vstm_inst {
4114 unsigned int single; 3143 unsigned int single;
@@ -4118,15 +3147,15 @@ typedef struct _vstm_inst {
4118 unsigned int n; 3147 unsigned int n;
4119 unsigned int imm32; 3148 unsigned int imm32;
4120 unsigned int regs; 3149 unsigned int regs;
4121} vfpinstr_inst; 3150} vstm_inst;
4122#endif 3151#endif
4123#ifdef VFP_INTERPRETER_TRANS 3152#ifdef VFP_INTERPRETER_TRANS
4124ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 3153ARM_INST_PTR INTERPRETER_TRANSLATE(vstm)(unsigned int inst, int index)
4125{ 3154{
4126 VFP_DEBUG_TRANSLATE; 3155 VFP_DEBUG_TRANSLATE;
4127 3156
4128 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 3157 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstm_inst));
4129 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3158 vstm_inst *inst_cream = (vstm_inst *)inst_base->component;
4130 3159
4131 inst_base->cond = BITS(inst, 28, 31); 3160 inst_base->cond = BITS(inst, 28, 31);
4132 inst_base->idx = index; 3161 inst_base->idx = index;
@@ -4145,15 +3174,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
4145} 3174}
4146#endif 3175#endif
4147#ifdef VFP_INTERPRETER_IMPL 3176#ifdef VFP_INTERPRETER_IMPL
4148VFPLABEL_INST: /* encoding 1 */ 3177VSTM_INST: /* encoding 1 */
4149{ 3178{
4150 INC_ICOUNTER;
4151 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 3179 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4152 CHECK_VFP_ENABLED; 3180 CHECK_VFP_ENABLED;
4153 3181
4154 int i; 3182 int i;
4155 3183
4156 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3184 vstm_inst *inst_cream = (vstm_inst *)inst_base->component;
4157 3185
4158 addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); 3186 addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32);
4159 DBG("VSTM : addr[%x]\n", addr); 3187 DBG("VSTM : addr[%x]\n", addr);
@@ -4203,69 +3231,12 @@ VFPLABEL_INST: /* encoding 1 */
4203 GOTO_NEXT_INST; 3231 GOTO_NEXT_INST;
4204} 3232}
4205#endif 3233#endif
4206#ifdef VFP_STC_TRANS
4207/* Should be the last operation of STC */
4208return VSTM(state, type, instr, value);
4209#endif
4210#ifdef VFP_STC_IMPL
4211int VSTM(ARMul_State * state, int type, ARMword instr, ARMword * value)
4212{
4213 static int i = 0;
4214 static int single_regs, add, wback, d, n, imm32, regs;
4215 if (type == ARMul_FIRST)
4216 {
4217 single_regs = BIT(8) == 0; /* Single precision */
4218 add = BIT(23); /* */
4219 wback = BIT(21); /* write-back */
4220 d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
4221 n = BITS(16, 19); /* destination register */
4222 imm32 = BITS(0,7) * 4; /* may not be used */
4223 regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FSTMX if regs is odd */
4224
4225 DBG("VSTM :\n");
4226
4227 if (wback) {
4228 state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32);
4229 DBG("\twback r%d[%x]\n", n, state->Reg[n]);
4230 }
4231
4232 i = 0;
4233
4234 return ARMul_DONE;
4235 }
4236 else if (type == ARMul_DATA)
4237 {
4238 if (single_regs)
4239 {
4240 *value = state->ExtReg[d + i];
4241 DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d + i]);
4242 i++;
4243 if (i < regs)
4244 return ARMul_INC;
4245 else
4246 return ARMul_DONE;
4247 }
4248 else
4249 {
4250 /* FIXME Careful of endianness, may need to rework this */
4251 *value = state->ExtReg[d*2 + i];
4252 DBG("\taddr[?] <= s[%d]=[%x]\n", d*2 + i, state->ExtReg[d*2 + i]);
4253 i++;
4254 if (i < regs*2)
4255 return ARMul_INC;
4256 else
4257 return ARMul_DONE;
4258 }
4259 }
4260 3234
4261 return -1;
4262}
4263#endif
4264#ifdef VFP_DYNCOM_TABLE 3235#ifdef VFP_DYNCOM_TABLE
4265DYNCOM_FILL_ACTION(vfpinstr), 3236DYNCOM_FILL_ACTION(vstm),
4266#endif 3237#endif
4267#ifdef VFP_DYNCOM_TAG 3238#ifdef VFP_DYNCOM_TAG
4268int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 3239int DYNCOM_TAG(vstm)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
4269{ 3240{
4270 int instr_size = INSTR_SIZE; 3241 int instr_size = INSTR_SIZE;
4271 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 3242 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -4280,7 +3251,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
4280} 3251}
4281#endif 3252#endif
4282#ifdef VFP_DYNCOM_TRANS 3253#ifdef VFP_DYNCOM_TRANS
4283int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 3254int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
4284 //arch_arm_undef(cpu, bb, instr); 3255 //arch_arm_undef(cpu, bb, instr);
4285 int single = BIT(8) == 0; 3256 int single = BIT(8) == 0;
4286 int add = BIT(23); 3257 int add = BIT(23);
@@ -4356,43 +3327,25 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
4356 return No_exp; 3327 return No_exp;
4357} 3328}
4358#endif 3329#endif
4359#undef vfpinstr
4360#undef vfpinstr_inst
4361#undef VFPLABEL_INST
4362 3330
4363/* ----------------------------------------------------------------------- */ 3331/* ----------------------------------------------------------------------- */
4364/* VPOP */ 3332/* VPOP */
4365/* cond 1100 1D11 1101 Vd-- 101X imm8 imm8 */ 3333/* cond 1100 1D11 1101 Vd-- 101X imm8 imm8 */
4366#define vfpinstr vpop
4367#define vfpinstr_inst vpop_inst
4368#define VFPLABEL_INST VPOP_INST
4369#ifdef VFP_DECODE
4370{"vpop", 3, ARMVFP2, 23, 27, 0x19, 16, 21, 0x3d, 9, 11, 0x5},
4371#endif
4372#ifdef VFP_DECODE_EXCLUSION
4373{"vpop", 0, ARMVFP2, 0},
4374#endif
4375#ifdef VFP_INTERPRETER_TABLE
4376INTERPRETER_TRANSLATE(vfpinstr),
4377#endif
4378#ifdef VFP_INTERPRETER_LABEL
4379&&VFPLABEL_INST,
4380#endif
4381#ifdef VFP_INTERPRETER_STRUCT 3334#ifdef VFP_INTERPRETER_STRUCT
4382typedef struct _vpop_inst { 3335typedef struct _vpop_inst {
4383 unsigned int single; 3336 unsigned int single;
4384 unsigned int d; 3337 unsigned int d;
4385 unsigned int imm32; 3338 unsigned int imm32;
4386 unsigned int regs; 3339 unsigned int regs;
4387} vfpinstr_inst; 3340} vpop_inst;
4388#endif 3341#endif
4389#ifdef VFP_INTERPRETER_TRANS 3342#ifdef VFP_INTERPRETER_TRANS
4390ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 3343ARM_INST_PTR INTERPRETER_TRANSLATE(vpop)(unsigned int inst, int index)
4391{ 3344{
4392 VFP_DEBUG_TRANSLATE; 3345 VFP_DEBUG_TRANSLATE;
4393 3346
4394 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 3347 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpop_inst));
4395 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3348 vpop_inst *inst_cream = (vpop_inst *)inst_base->component;
4396 3349
4397 inst_base->cond = BITS(inst, 28, 31); 3350 inst_base->cond = BITS(inst, 28, 31);
4398 inst_base->idx = index; 3351 inst_base->idx = index;
@@ -4408,16 +3361,15 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
4408} 3361}
4409#endif 3362#endif
4410#ifdef VFP_INTERPRETER_IMPL 3363#ifdef VFP_INTERPRETER_IMPL
4411VFPLABEL_INST: 3364VPOP_INST:
4412{ 3365{
4413 INC_ICOUNTER;
4414 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 3366 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4415 CHECK_VFP_ENABLED; 3367 CHECK_VFP_ENABLED;
4416 3368
4417 int i; 3369 int i;
4418 unsigned int value1, value2; 3370 unsigned int value1, value2;
4419 3371
4420 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3372 vpop_inst *inst_cream = (vpop_inst *)inst_base->component;
4421 3373
4422 DBG("VPOP :\n"); 3374 DBG("VPOP :\n");
4423 3375
@@ -4468,70 +3420,12 @@ VFPLABEL_INST:
4468 GOTO_NEXT_INST; 3420 GOTO_NEXT_INST;
4469} 3421}
4470#endif 3422#endif
4471#ifdef VFP_LDC_TRANS
4472if (P == 0 && U == 1 && W == 1 && Rn == 0xD)
4473{
4474 return VPOP(state, type, instr, value);
4475}
4476#endif
4477#ifdef VFP_LDC_IMPL
4478int VPOP(ARMul_State * state, int type, ARMword instr, ARMword value)
4479{
4480 static int i = 0;
4481 static int single_regs, add, wback, d, n, imm32, regs;
4482 if (type == ARMul_FIRST)
4483 {
4484 single_regs = BIT(8) == 0; /* Single precision */
4485 d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
4486 imm32 = BITS(0,7)<<2; /* may not be used */
4487 regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FLDMX if regs is odd */
4488 3423
4489 DBG("VPOP :\n");
4490 DBG("\tsp[%x]", state->Reg[R13]);
4491 state->Reg[R13] = state->Reg[R13] + imm32;
4492 DBG("=>[%x]\n", state->Reg[R13]);
4493
4494 i = 0;
4495
4496 return ARMul_DONE;
4497 }
4498 else if (type == ARMul_TRANSFER)
4499 {
4500 return ARMul_DONE;
4501 }
4502 else if (type == ARMul_DATA)
4503 {
4504 if (single_regs)
4505 {
4506 state->ExtReg[d + i] = value;
4507 DBG("\ts%d <= [%x]\n", d + i, value);
4508 i++;
4509 if (i < regs)
4510 return ARMul_INC;
4511 else
4512 return ARMul_DONE;
4513 }
4514 else
4515 {
4516 /* FIXME Careful of endianness, may need to rework this */
4517 state->ExtReg[d*2 + i] = value;
4518 DBG("\ts%d <= [%x]\n", d*2 + i, value);
4519 i++;
4520 if (i < regs*2)
4521 return ARMul_INC;
4522 else
4523 return ARMul_DONE;
4524 }
4525 }
4526
4527 return -1;
4528}
4529#endif
4530#ifdef VFP_DYNCOM_TABLE 3424#ifdef VFP_DYNCOM_TABLE
4531DYNCOM_FILL_ACTION(vfpinstr), 3425DYNCOM_FILL_ACTION(vpop),
4532#endif 3426#endif
4533#ifdef VFP_DYNCOM_TAG 3427#ifdef VFP_DYNCOM_TAG
4534int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 3428int DYNCOM_TAG(vpop)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
4535{ 3429{
4536 int instr_size = INSTR_SIZE; 3430 int instr_size = INSTR_SIZE;
4537 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 3431 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -4547,7 +3441,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
4547} 3441}
4548#endif 3442#endif
4549#ifdef VFP_DYNCOM_TRANS 3443#ifdef VFP_DYNCOM_TRANS
4550int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 3444int DYNCOM_TRANS(vpop)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
4551 DBG("\t\tin %s instruction .\n", __FUNCTION__); 3445 DBG("\t\tin %s instruction .\n", __FUNCTION__);
4552 //arch_arm_undef(cpu, bb, instr); 3446 //arch_arm_undef(cpu, bb, instr);
4553 int single = BIT(8) == 0; 3447 int single = BIT(8) == 0;
@@ -4611,28 +3505,10 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
4611 return No_exp; 3505 return No_exp;
4612} 3506}
4613#endif 3507#endif
4614#undef vfpinstr
4615#undef vfpinstr_inst
4616#undef VFPLABEL_INST
4617 3508
4618/* ----------------------------------------------------------------------- */ 3509/* ----------------------------------------------------------------------- */
4619/* VLDR */ 3510/* VLDR */
4620/* cond 1101 UD01 Rn-- Vd-- 101X imm8 imm8 */ 3511/* cond 1101 UD01 Rn-- Vd-- 101X imm8 imm8 */
4621#define vfpinstr vldr
4622#define vfpinstr_inst vldr_inst
4623#define VFPLABEL_INST VLDR_INST
4624#ifdef VFP_DECODE
4625{"vldr", 3, ARMVFP2, 24, 27, 0xd, 20, 21, 0x1, 9, 11, 0x5},
4626#endif
4627#ifdef VFP_DECODE_EXCLUSION
4628{"vldr", 0, ARMVFP2, 0},
4629#endif
4630#ifdef VFP_INTERPRETER_TABLE
4631INTERPRETER_TRANSLATE(vfpinstr),
4632#endif
4633#ifdef VFP_INTERPRETER_LABEL
4634&&VFPLABEL_INST,
4635#endif
4636#ifdef VFP_INTERPRETER_STRUCT 3512#ifdef VFP_INTERPRETER_STRUCT
4637typedef struct _vldr_inst { 3513typedef struct _vldr_inst {
4638 unsigned int single; 3514 unsigned int single;
@@ -4640,15 +3516,15 @@ typedef struct _vldr_inst {
4640 unsigned int d; 3516 unsigned int d;
4641 unsigned int imm32; 3517 unsigned int imm32;
4642 unsigned int add; 3518 unsigned int add;
4643} vfpinstr_inst; 3519} vldr_inst;
4644#endif 3520#endif
4645#ifdef VFP_INTERPRETER_TRANS 3521#ifdef VFP_INTERPRETER_TRANS
4646ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 3522ARM_INST_PTR INTERPRETER_TRANSLATE(vldr)(unsigned int inst, int index)
4647{ 3523{
4648 VFP_DEBUG_TRANSLATE; 3524 VFP_DEBUG_TRANSLATE;
4649 3525
4650 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 3526 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldr_inst));
4651 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3527 vldr_inst *inst_cream = (vldr_inst *)inst_base->component;
4652 3528
4653 inst_base->cond = BITS(inst, 28, 31); 3529 inst_base->cond = BITS(inst, 28, 31);
4654 inst_base->idx = index; 3530 inst_base->idx = index;
@@ -4665,13 +3541,12 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
4665} 3541}
4666#endif 3542#endif
4667#ifdef VFP_INTERPRETER_IMPL 3543#ifdef VFP_INTERPRETER_IMPL
4668VFPLABEL_INST: 3544VLDR_INST:
4669{ 3545{
4670 INC_ICOUNTER;
4671 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 3546 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4672 CHECK_VFP_ENABLED; 3547 CHECK_VFP_ENABLED;
4673 3548
4674 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3549 vldr_inst *inst_cream = (vldr_inst *)inst_base->component;
4675 3550
4676 unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]); 3551 unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]);
4677 addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32); 3552 addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32);
@@ -4710,69 +3585,12 @@ VFPLABEL_INST:
4710 GOTO_NEXT_INST; 3585 GOTO_NEXT_INST;
4711} 3586}
4712#endif 3587#endif
4713#ifdef VFP_LDC_TRANS
4714if (P == 1 && W == 0)
4715{
4716 return VLDR(state, type, instr, value);
4717}
4718#endif
4719#ifdef VFP_LDC_IMPL
4720int VLDR(ARMul_State * state, int type, ARMword instr, ARMword value)
4721{
4722 static int i = 0;
4723 static int single_reg, add, d, n, imm32, regs;
4724 if (type == ARMul_FIRST)
4725 {
4726 single_reg = BIT(8) == 0; /* Double precision */
4727 add = BIT(23); /* */
4728 imm32 = BITS(0,7)<<2; /* may not be used */
4729 d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
4730 n = BITS(16, 19); /* destination register */
4731
4732 DBG("VLDR :\n");
4733
4734 i = 0;
4735 regs = 1;
4736
4737 return ARMul_DONE;
4738 }
4739 else if (type == ARMul_TRANSFER)
4740 {
4741 return ARMul_DONE;
4742 }
4743 else if (type == ARMul_DATA)
4744 {
4745 if (single_reg)
4746 {
4747 state->ExtReg[d+i] = value;
4748 DBG("\ts%d <= [%x]\n", d+i, value);
4749 i++;
4750 if (i < regs)
4751 return ARMul_INC;
4752 else
4753 return ARMul_DONE;
4754 }
4755 else
4756 {
4757 /* FIXME Careful of endianness, may need to rework this */
4758 state->ExtReg[d*2+i] = value;
4759 DBG("\ts[%d] <= [%x]\n", d*2+i, value);
4760 i++;
4761 if (i < regs*2)
4762 return ARMul_INC;
4763 else
4764 return ARMul_DONE;
4765 }
4766 }
4767 3588
4768 return -1;
4769}
4770#endif
4771#ifdef VFP_DYNCOM_TABLE 3589#ifdef VFP_DYNCOM_TABLE
4772DYNCOM_FILL_ACTION(vfpinstr), 3590DYNCOM_FILL_ACTION(vldr),
4773#endif 3591#endif
4774#ifdef VFP_DYNCOM_TAG 3592#ifdef VFP_DYNCOM_TAG
4775int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 3593int DYNCOM_TAG(vldr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
4776{ 3594{
4777 int instr_size = INSTR_SIZE; 3595 int instr_size = INSTR_SIZE;
4778 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 3596 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -4788,7 +3606,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
4788} 3606}
4789#endif 3607#endif
4790#ifdef VFP_DYNCOM_TRANS 3608#ifdef VFP_DYNCOM_TRANS
4791int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 3609int DYNCOM_TRANS(vldr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
4792 int single = BIT(8) == 0; 3610 int single = BIT(8) == 0;
4793 int add = BIT(23); 3611 int add = BIT(23);
4794 int wback = BIT(21); 3612 int wback = BIT(21);
@@ -4846,28 +3664,10 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
4846 return No_exp; 3664 return No_exp;
4847} 3665}
4848#endif 3666#endif
4849#undef vfpinstr
4850#undef vfpinstr_inst
4851#undef VFPLABEL_INST
4852 3667
4853/* ----------------------------------------------------------------------- */ 3668/* ----------------------------------------------------------------------- */
4854/* VLDM */ 3669/* VLDM */
4855/* cond 110P UDW1 Rn-- Vd-- 101X imm8 imm8 */ 3670/* cond 110P UDW1 Rn-- Vd-- 101X imm8 imm8 */
4856#define vfpinstr vldm
4857#define vfpinstr_inst vldm_inst
4858#define VFPLABEL_INST VLDM_INST
4859#ifdef VFP_DECODE
4860{"vldm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 1, 9, 11, 0x5},
4861#endif
4862#ifdef VFP_DECODE_EXCLUSION
4863{"vldm", 0, ARMVFP2, 0},
4864#endif
4865#ifdef VFP_INTERPRETER_TABLE
4866INTERPRETER_TRANSLATE(vfpinstr),
4867#endif
4868#ifdef VFP_INTERPRETER_LABEL
4869&&VFPLABEL_INST,
4870#endif
4871#ifdef VFP_INTERPRETER_STRUCT 3671#ifdef VFP_INTERPRETER_STRUCT
4872typedef struct _vldm_inst { 3672typedef struct _vldm_inst {
4873 unsigned int single; 3673 unsigned int single;
@@ -4877,15 +3677,15 @@ typedef struct _vldm_inst {
4877 unsigned int n; 3677 unsigned int n;
4878 unsigned int imm32; 3678 unsigned int imm32;
4879 unsigned int regs; 3679 unsigned int regs;
4880} vfpinstr_inst; 3680} vldm_inst;
4881#endif 3681#endif
4882#ifdef VFP_INTERPRETER_TRANS 3682#ifdef VFP_INTERPRETER_TRANS
4883ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 3683ARM_INST_PTR INTERPRETER_TRANSLATE(vldm)(unsigned int inst, int index)
4884{ 3684{
4885 VFP_DEBUG_TRANSLATE; 3685 VFP_DEBUG_TRANSLATE;
4886 3686
4887 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 3687 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldm_inst));
4888 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3688 vldm_inst *inst_cream = (vldm_inst *)inst_base->component;
4889 3689
4890 inst_base->cond = BITS(inst, 28, 31); 3690 inst_base->cond = BITS(inst, 28, 31);
4891 inst_base->idx = index; 3691 inst_base->idx = index;
@@ -4904,15 +3704,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
4904} 3704}
4905#endif 3705#endif
4906#ifdef VFP_INTERPRETER_IMPL 3706#ifdef VFP_INTERPRETER_IMPL
4907VFPLABEL_INST: 3707VLDM_INST:
4908{ 3708{
4909 INC_ICOUNTER;
4910 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 3709 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4911 CHECK_VFP_ENABLED; 3710 CHECK_VFP_ENABLED;
4912 3711
4913 int i; 3712 int i;
4914 3713
4915 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3714 vldm_inst *inst_cream = (vldm_inst *)inst_base->component;
4916 3715
4917 addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); 3716 addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32);
4918 DBG("VLDM : addr[%x]\n", addr); 3717 DBG("VLDM : addr[%x]\n", addr);
@@ -4952,74 +3751,17 @@ VFPLABEL_INST:
4952 3751
4953 } 3752 }
4954 cpu->Reg[15] += GET_INST_SIZE(cpu); 3753 cpu->Reg[15] += GET_INST_SIZE(cpu);
4955 INC_PC(sizeof(vfpinstr_inst)); 3754 INC_PC(sizeof(vldm_inst));
4956 FETCH_INST; 3755 FETCH_INST;
4957 GOTO_NEXT_INST; 3756 GOTO_NEXT_INST;
4958} 3757}
4959#endif 3758#endif
4960#ifdef VFP_LDC_TRANS
4961/* Should be the last operation of LDC */
4962return VLDM(state, type, instr, value);
4963#endif
4964#ifdef VFP_LDC_IMPL
4965int VLDM(ARMul_State * state, int type, ARMword instr, ARMword value)
4966{
4967 static int i = 0;
4968 static int single_regs, add, wback, d, n, imm32, regs;
4969 if (type == ARMul_FIRST)
4970 {
4971 single_regs = BIT(8) == 0; /* Single precision */
4972 add = BIT(23); /* */
4973 wback = BIT(21); /* write-back */
4974 d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
4975 n = BITS(16, 19); /* destination register */
4976 imm32 = BITS(0,7) * 4; /* may not be used */
4977 regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FLDMX if regs is odd */
4978
4979 DBG("VLDM :\n");
4980
4981 if (wback) {
4982 state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32);
4983 DBG("\twback r%d[%x]\n", n, state->Reg[n]);
4984 }
4985
4986 i = 0;
4987
4988 return ARMul_DONE;
4989 }
4990 else if (type == ARMul_DATA)
4991 {
4992 if (single_regs)
4993 {
4994 state->ExtReg[d + i] = value;
4995 DBG("\ts%d <= [%x] addr[?]\n", d+i, state->ExtReg[d + i]);
4996 i++;
4997 if (i < regs)
4998 return ARMul_INC;
4999 else
5000 return ARMul_DONE;
5001 }
5002 else
5003 {
5004 /* FIXME Careful of endianness, may need to rework this */
5005 state->ExtReg[d*2 + i] = value;
5006 DBG("\ts[%d] <= [%x] addr[?]\n", d*2 + i, state->ExtReg[d*2 + i]);
5007 i++;
5008 if (i < regs*2)
5009 return ARMul_INC;
5010 else
5011 return ARMul_DONE;
5012 }
5013 }
5014 3759
5015 return -1;
5016}
5017#endif
5018#ifdef VFP_DYNCOM_TABLE 3760#ifdef VFP_DYNCOM_TABLE
5019DYNCOM_FILL_ACTION(vfpinstr), 3761DYNCOM_FILL_ACTION(vldm),
5020#endif 3762#endif
5021#ifdef VFP_DYNCOM_TAG 3763#ifdef VFP_DYNCOM_TAG
5022int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 3764int DYNCOM_TAG(vldm)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
5023{ 3765{
5024 int instr_size = INSTR_SIZE; 3766 int instr_size = INSTR_SIZE;
5025 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 3767 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -5034,7 +3776,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
5034} 3776}
5035#endif 3777#endif
5036#ifdef VFP_DYNCOM_TRANS 3778#ifdef VFP_DYNCOM_TRANS
5037int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 3779int DYNCOM_TRANS(vldm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
5038 int single = BIT(8) == 0; 3780 int single = BIT(8) == 0;
5039 int add = BIT(23); 3781 int add = BIT(23);
5040 int wback = BIT(21); 3782 int wback = BIT(21);
@@ -5110,14 +3852,3 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
5110 return No_exp; 3852 return No_exp;
5111} 3853}
5112#endif 3854#endif
5113#undef vfpinstr
5114#undef vfpinstr_inst
5115#undef VFPLABEL_INST
5116
5117#define VFP_DEBUG_TRANSLATE DBG("in func %s, %x\n", __FUNCTION__, inst);
5118#define VFP_DEBUG_UNIMPLEMENTED(x) printf("in func %s, " #x " unimplemented\n", __FUNCTION__); exit(-1);
5119#define VFP_DEBUG_UNTESTED(x) printf("in func %s, " #x " untested\n", __FUNCTION__);
5120
5121#define CHECK_VFP_ENABLED
5122
5123#define CHECK_VFP_CDP_RET vfp_raise_exceptions(cpu, ret, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); //if (ret == -1) {printf("VFP CDP FAILURE %x\n", inst_cream->instr); exit(-1);}
diff --git a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp
index 07d0c1f44..6c33d8b78 100644
--- a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp
@@ -522,8 +522,7 @@ static s64 vfp_single_to_doubleintern(ARMul_State* state, s32 m, u32 fpscr) //ic
522 if (tm == VFP_QNAN) 522 if (tm == VFP_QNAN)
523 vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN; 523 vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN;
524 goto pack_nan; 524 goto pack_nan;
525 } 525 } else if (tm & VFP_ZERO)
526 else if (tm & VFP_ZERO)
527 vdd.exponent = 0; 526 vdd.exponent = 0;
528 else 527 else
529 vdd.exponent = vsm.exponent + (1023 - 127); 528 vdd.exponent = vsm.exponent + (1023 - 127);
@@ -615,12 +614,12 @@ static u32 vfp_single_ftoui(ARMul_State* state, int sd, int unused, s32 m, u32 f
615 exceptions |= FPSCR_IDC; 614 exceptions |= FPSCR_IDC;
616 615
617 if (tm & VFP_NAN) 616 if (tm & VFP_NAN)
618 vsm.sign = 0; 617 vsm.sign = 1;
619 618
620 if (vsm.exponent >= 127 + 32) { 619 if (vsm.exponent >= 127 + 32) {
621 d = vsm.sign ? 0 : 0xffffffff; 620 d = vsm.sign ? 0 : 0xffffffff;
622 exceptions = FPSCR_IOC; 621 exceptions = FPSCR_IOC;
623 } else if (vsm.exponent >= 127 - 1) { 622 } else if (vsm.exponent >= 127) {
624 int shift = 127 + 31 - vsm.exponent; 623 int shift = 127 + 31 - vsm.exponent;
625 u32 rem, incr = 0; 624 u32 rem, incr = 0;
626 625
@@ -705,7 +704,7 @@ static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 f
705 if (vsm.sign) 704 if (vsm.sign)
706 d = ~d; 705 d = ~d;
707 exceptions |= FPSCR_IOC; 706 exceptions |= FPSCR_IOC;
708 } else if (vsm.exponent >= 127 - 1) { 707 } else if (vsm.exponent >= 127) {
709 int shift = 127 + 31 - vsm.exponent; 708 int shift = 127 + 31 - vsm.exponent;
710 u32 rem, incr = 0; 709 u32 rem, incr = 0;
711 710
@@ -1149,7 +1148,10 @@ static u32 vfp_single_fsub(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr)
1149 /* 1148 /*
1150 * Subtraction is addition with one sign inverted. 1149 * Subtraction is addition with one sign inverted.
1151 */ 1150 */
1152 return vfp_single_fadd(state, sd, sn, vfp_single_packed_negate(m), fpscr); 1151 if (m != 0x7FC00000) // Only negate if m isn't NaN.
1152 m = vfp_single_packed_negate(m);
1153
1154 return vfp_single_fadd(state, sd, sn, m, fpscr);
1153} 1155}
1154 1156
1155/* 1157/*