summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/citra_qt/debugger/disassembler.cpp4
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.cpp74
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp401
-rw-r--r--src/core/arm/interpreter/armemu.cpp535
-rw-r--r--src/core/arm/interpreter/armsupp.cpp50
-rw-r--r--src/core/arm/skyeye_common/armdefs.h6
-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.cpp1925
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp7
-rw-r--r--src/core/hle/kernel/event.cpp15
-rw-r--r--src/core/hle/kernel/kernel.cpp124
-rw-r--r--src/core/hle/kernel/kernel.h196
-rw-r--r--src/core/hle/kernel/mutex.cpp11
-rw-r--r--src/core/hle/kernel/semaphore.cpp9
-rw-r--r--src/core/hle/kernel/session.h4
-rw-r--r--src/core/hle/kernel/shared_memory.cpp11
-rw-r--r--src/core/hle/kernel/thread.cpp27
-rw-r--r--src/core/hle/kernel/thread.h3
-rw-r--r--src/core/hle/service/fs/archive.cpp10
-rw-r--r--src/core/hle/service/service.cpp5
-rw-r--r--src/core/hle/service/service.h5
-rw-r--r--src/core/hle/svc.cpp30
23 files changed, 1962 insertions, 2159 deletions
diff --git a/src/citra_qt/debugger/disassembler.cpp b/src/citra_qt/debugger/disassembler.cpp
index 2ee877743..14745f3bb 100644
--- a/src/citra_qt/debugger/disassembler.cpp
+++ b/src/citra_qt/debugger/disassembler.cpp
@@ -220,7 +220,9 @@ void DisassemblerWidget::OnPause()
220 emu_thread.SetCpuRunning(false); 220 emu_thread.SetCpuRunning(false);
221 221
222 // TODO: By now, the CPU might not have actually stopped... 222 // TODO: By now, the CPU might not have actually stopped...
223 model->SetNextInstruction(Core::g_app_core->GetPC()); 223 if (Core::g_app_core) {
224 model->SetNextInstruction(Core::g_app_core->GetPC());
225 }
224} 226}
225 227
226void DisassemblerWidget::OnToggleStartStop() 228void DisassemblerWidget::OnToggleStartStop()
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp
index 5d174a08f..551bb77a6 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp
@@ -28,9 +28,40 @@
28#include "core/arm/dyncom/arm_dyncom_dec.h" 28#include "core/arm/dyncom/arm_dyncom_dec.h"
29 29
30const ISEITEM arm_instruction[] = { 30const ISEITEM arm_instruction[] = {
31 #define VFP_DECODE 31 {"vmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0},
32 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 32 {"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 33 {"vnmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0},
34 {"vnmla", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
35 {"vnmls", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
36 {"vnmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
37 {"vmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
38 {"vadd", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
39 {"vsub", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
40 {"vdiv", 5, ARMVFP2, 23, 27, 0x1D, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
41 {"vmov(i)", 4, ARMVFP3, 23, 27, 0x1D, 20, 21, 0x3, 9, 11, 0x5, 4, 7, 0},
42 {"vmov(r)", 5, ARMVFP3, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 1, 4, 4, 0},
43 {"vabs", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 3, 4, 4, 0},
44 {"vneg", 5, ARMVFP2, 23, 27, 0x1D, 17, 21, 0x18, 9, 11, 0x5, 6, 7, 1, 4, 4, 0},
45 {"vsqrt", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x31, 9, 11, 0x5, 6, 7, 3, 4, 4, 0},
46 {"vcmp", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x34, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
47 {"vcmp2", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x35, 9, 11, 0x5, 0, 6, 0x40},
48 {"vcvt(bds)", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x37, 9, 11, 0x5, 6, 7, 3, 4, 4, 0},
49 {"vcvt(bff)", 6, ARMVFP3, 23, 27, 0x1D, 19, 21, 0x7, 17, 17, 0x1, 9, 11,5, 6, 6, 1},
50 {"vcvt(bfi)", 5, ARMVFP2, 23, 27, 0x1D, 19, 21, 0x7, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
51 {"vmovbrs", 3, ARMVFP2, 21, 27, 0x70, 8, 11, 0xA, 0, 6, 0x10},
52 {"vmsr", 2, ARMVFP2, 20, 27, 0xEE, 0, 11, 0xA10},
53 {"vmovbrc", 4, ARMVFP2, 23, 27, 0x1C, 20, 20, 0x0, 8, 11, 0xB, 0,4,0x10},
54 {"vmrs", 2, ARMVFP2, 20, 27, 0xEF, 0, 11, 0xA10},
55 {"vmovbcr", 4, ARMVFP2, 24, 27, 0xE, 20, 20, 1, 8, 11, 0xB, 0,4,0x10},
56 {"vmovbrrss", 3, ARMVFP2, 21, 27, 0x62, 8, 11, 0xA, 4, 4, 1},
57 {"vmovbrrd", 3, ARMVFP2, 21, 27, 0x62, 6, 11, 0x2C, 4, 4, 1},
58 {"vstr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 0, 9, 11,5},
59 {"vpush", 3, ARMVFP2, 23, 27, 0x1A, 16, 21, 0x2D, 9, 11,5},
60 {"vstm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 0, 9, 11,5},
61 {"vpop", 3, ARMVFP2, 23, 27, 0x19, 16, 21, 0x3D, 9, 11,5},
62 {"vldr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 1, 9, 11,5},
63 {"vldm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 1, 9, 11,5},
64
34 {"srs" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d, 8, 11, 0x00000005}, 65 {"srs" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d, 8, 11, 0x00000005},
35 {"rfe" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001, 8, 11, 0x0000000a}, 66 {"rfe" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001, 8, 11, 0x0000000a},
36 {"bkpt" , 2 , 3 , 20, 31, 0x00000e12, 4, 7, 0x00000007}, 67 {"bkpt" , 2 , 3 , 20, 31, 0x00000e12, 4, 7, 0x00000007},
@@ -187,9 +218,40 @@ const ISEITEM arm_instruction[] = {
187}; 218};
188 219
189const ISEITEM arm_exclusion_code[] = { 220const ISEITEM arm_exclusion_code[] = {
190 #define VFP_DECODE_EXCLUSION 221 {"vmla", 0, ARMVFP2, 0},
191 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 222 {"vmls", 0, ARMVFP2, 0},
192 #undef VFP_DECODE_EXCLUSION 223 {"vnmla", 0, ARMVFP2, 0},
224 {"vnmla", 0, ARMVFP2, 0},
225 {"vnmls", 0, ARMVFP2, 0},
226 {"vnmul", 0, ARMVFP2, 0},
227 {"vmul", 0, ARMVFP2, 0},
228 {"vadd", 0, ARMVFP2, 0},
229 {"vsub", 0, ARMVFP2, 0},
230 {"vdiv", 0, ARMVFP2, 0},
231 {"vmov(i)", 0, ARMVFP3, 0},
232 {"vmov(r)", 0, ARMVFP3, 0},
233 {"vabs", 0, ARMVFP2, 0},
234 {"vneg", 0, ARMVFP2, 0},
235 {"vsqrt", 0, ARMVFP2, 0},
236 {"vcmp", 0, ARMVFP2, 0},
237 {"vcmp2", 0, ARMVFP2, 0},
238 {"vcvt(bff)", 0, ARMVFP3, 4, 4, 1},
239 {"vcvt(bds)", 0, ARMVFP2, 0},
240 {"vcvt(bfi)", 0, ARMVFP2, 0},
241 {"vmovbrs", 0, ARMVFP2, 0},
242 {"vmsr", 0, ARMVFP2, 0},
243 {"vmovbrc", 0, ARMVFP2, 0},
244 {"vmrs", 0, ARMVFP2, 0},
245 {"vmovbcr", 0, ARMVFP2, 0},
246 {"vmovbrrss", 0, ARMVFP2, 0},
247 {"vmovbrrd", 0, ARMVFP2, 0},
248 {"vstr", 0, ARMVFP2, 0},
249 {"vpush", 0, ARMVFP2, 0},
250 {"vstm", 0, ARMVFP2, 0},
251 {"vpop", 0, ARMVFP2, 0},
252 {"vldr", 0, ARMVFP2, 0},
253 {"vldm", 0, ARMVFP2, 0},
254
193 {"srs" , 0 , 6 , 0}, 255 {"srs" , 0 , 6 , 0},
194 {"rfe" , 0 , 6 , 0}, 256 {"rfe" , 0 , 6 , 0},
195 {"bkpt" , 0 , 3 , 0}, 257 {"bkpt" , 0 , 3 , 0},
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 460001b1a..b4ee64203 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -1427,6 +1427,13 @@ typedef struct _blx_1_thumb {
1427 unsigned int instr; 1427 unsigned int instr;
1428}blx_1_thumb; 1428}blx_1_thumb;
1429 1429
1430typedef struct _pkh_inst {
1431 u32 Rm;
1432 u32 Rn;
1433 u32 Rd;
1434 u8 imm;
1435} pkh_inst;
1436
1430typedef arm_inst * ARM_INST_PTR; 1437typedef arm_inst * ARM_INST_PTR;
1431 1438
1432#define CACHE_BUFFER_SIZE (64 * 1024 * 2000) 1439#define CACHE_BUFFER_SIZE (64 * 1024 * 2000)
@@ -2376,8 +2383,30 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index)
2376 } 2383 }
2377 return inst_base; 2384 return inst_base;
2378} 2385}
2379ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("PKHBT"); } 2386
2380ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("PKHTB"); } 2387ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index)
2388{
2389 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst));
2390 pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
2391
2392 inst_base->cond = BITS(inst, 28, 31);
2393 inst_base->idx = index;
2394 inst_base->br = NON_BRANCH;
2395 inst_base->load_r15 = 0;
2396
2397 inst_cream->Rd = BITS(inst, 12, 15);
2398 inst_cream->Rn = BITS(inst, 16, 19);
2399 inst_cream->Rm = BITS(inst, 0, 3);
2400 inst_cream->imm = BITS(inst, 7, 11);
2401
2402 return inst_base;
2403}
2404
2405ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index)
2406{
2407 return INTERPRETER_TRANSLATE(pkhbt)(inst, index);
2408}
2409
2381ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index) 2410ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index)
2382{ 2411{
2383 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst)); 2412 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst));
@@ -3086,15 +3115,47 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index)
3086 inst_base->load_r15 = 1; 3115 inst_base->load_r15 = 1;
3087 return inst_base; 3116 return inst_base;
3088} 3117}
3089ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); }
3090ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD8"); } 3118ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD8"); }
3119ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); }
3091ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADDSUBX"); } 3120ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADDSUBX"); }
3092ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHADD16"); } 3121ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index)
3093ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHADD8"); } 3122{
3094ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHADDSUBX"); } 3123 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
3095ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHSUB16"); } 3124 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
3096ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHSUB8"); } 3125
3097ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHSUBADDX"); } 3126 inst_base->cond = BITS(inst, 28, 31);
3127 inst_base->idx = index;
3128 inst_base->br = NON_BRANCH;
3129 inst_base->load_r15 = 0;
3130
3131 inst_cream->op1 = BITS(inst, 20, 21);
3132 inst_cream->op2 = BITS(inst, 5, 7);
3133 inst_cream->Rm = BITS(inst, 0, 3);
3134 inst_cream->Rn = BITS(inst, 16, 19);
3135 inst_cream->Rd = BITS(inst, 12, 15);
3136
3137 return inst_base;
3138}
3139ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index)
3140{
3141 return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
3142}
3143ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index)
3144{
3145 return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
3146}
3147ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index)
3148{
3149 return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
3150}
3151ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index)
3152{
3153 return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
3154}
3155ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index)
3156{
3157 return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
3158}
3098ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index) 3159ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index)
3099{ 3160{
3100 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umaal_inst)); 3161 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umaal_inst));
@@ -3217,14 +3278,66 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index)
3217 return inst_base; 3278 return inst_base;
3218} 3279}
3219 3280
3220ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQADD16"); } 3281ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index)
3221ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQADD8"); } 3282{
3222ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQADDSUBX"); } 3283 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
3223ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQSUB16"); } 3284 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
3224ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQSUB8"); } 3285
3225ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQSUBADDX"); } 3286 inst_base->cond = BITS(inst, 28, 31);
3226ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAD8"); } 3287 inst_base->idx = index;
3227ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USADA8"); } 3288 inst_base->br = NON_BRANCH;
3289 inst_base->load_r15 = 0;
3290
3291 inst_cream->Rm = BITS(inst, 0, 3);
3292 inst_cream->Rn = BITS(inst, 16, 19);
3293 inst_cream->Rd = BITS(inst, 12, 15);
3294 inst_cream->op1 = BITS(inst, 20, 21);
3295 inst_cream->op2 = BITS(inst, 5, 7);
3296
3297 return inst_base;
3298}
3299ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index)
3300{
3301 return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
3302}
3303ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index)
3304{
3305 return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
3306}
3307ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index)
3308{
3309 return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
3310}
3311ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index)
3312{
3313 return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
3314}
3315ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index)
3316{
3317 return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
3318}
3319ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index)
3320{
3321 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
3322 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
3323
3324 inst_base->cond = BITS(inst, 28, 31);
3325 inst_base->idx = index;
3326 inst_base->br = NON_BRANCH;
3327 inst_base->load_r15 = 0;
3328
3329 inst_cream->op1 = BITS(inst, 20, 24);
3330 inst_cream->op2 = BITS(inst, 5, 7);
3331 inst_cream->Rm = BITS(inst, 8, 11);
3332 inst_cream->Rn = BITS(inst, 0, 3);
3333 inst_cream->Ra = BITS(inst, 12, 15);
3334
3335 return inst_base;
3336}
3337ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index)
3338{
3339 return INTERPRETER_TRANSLATE(usada8)(inst, index);
3340}
3228ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT"); } 3341ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT"); }
3229ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT16"); } 3342ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT16"); }
3230ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB16"); } 3343ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB16"); }
@@ -3250,9 +3363,40 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index) { UN
3250typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int); 3363typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int);
3251 3364
3252const transop_fp_t arm_instruction_trans[] = { 3365const transop_fp_t arm_instruction_trans[] = {
3253 #define VFP_INTERPRETER_TABLE 3366 INTERPRETER_TRANSLATE(vmla),
3254 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 3367 INTERPRETER_TRANSLATE(vmls),
3255 #undef VFP_INTERPRETER_TABLE 3368 INTERPRETER_TRANSLATE(vnmla),
3369 INTERPRETER_TRANSLATE(vnmla),
3370 INTERPRETER_TRANSLATE(vnmls),
3371 INTERPRETER_TRANSLATE(vnmul),
3372 INTERPRETER_TRANSLATE(vmul),
3373 INTERPRETER_TRANSLATE(vadd),
3374 INTERPRETER_TRANSLATE(vsub),
3375 INTERPRETER_TRANSLATE(vdiv),
3376 INTERPRETER_TRANSLATE(vmovi),
3377 INTERPRETER_TRANSLATE(vmovr),
3378 INTERPRETER_TRANSLATE(vabs),
3379 INTERPRETER_TRANSLATE(vneg),
3380 INTERPRETER_TRANSLATE(vsqrt),
3381 INTERPRETER_TRANSLATE(vcmp),
3382 INTERPRETER_TRANSLATE(vcmp2),
3383 INTERPRETER_TRANSLATE(vcvtbds),
3384 INTERPRETER_TRANSLATE(vcvtbff),
3385 INTERPRETER_TRANSLATE(vcvtbfi),
3386 INTERPRETER_TRANSLATE(vmovbrs),
3387 INTERPRETER_TRANSLATE(vmsr),
3388 INTERPRETER_TRANSLATE(vmovbrc),
3389 INTERPRETER_TRANSLATE(vmrs),
3390 INTERPRETER_TRANSLATE(vmovbcr),
3391 INTERPRETER_TRANSLATE(vmovbrrss),
3392 INTERPRETER_TRANSLATE(vmovbrrd),
3393 INTERPRETER_TRANSLATE(vstr),
3394 INTERPRETER_TRANSLATE(vpush),
3395 INTERPRETER_TRANSLATE(vstm),
3396 INTERPRETER_TRANSLATE(vpop),
3397 INTERPRETER_TRANSLATE(vldr),
3398 INTERPRETER_TRANSLATE(vldm),
3399
3256 INTERPRETER_TRANSLATE(srs), 3400 INTERPRETER_TRANSLATE(srs),
3257 INTERPRETER_TRANSLATE(rfe), 3401 INTERPRETER_TRANSLATE(rfe),
3258 INTERPRETER_TRANSLATE(bkpt), 3402 INTERPRETER_TRANSLATE(bkpt),
@@ -4093,10 +4237,12 @@ unsigned InterpreterMainLoop(ARMul_State* state)
4093 // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback 4237 // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback
4094 // to a clunky switch statement. 4238 // to a clunky switch statement.
4095#if defined __GNUC__ || defined __clang__ 4239#if defined __GNUC__ || defined __clang__
4096 void *InstLabel[] = { 4240 void *InstLabel[] = {
4097 #define VFP_INTERPRETER_LABEL 4241 &&VMLA_INST, &&VMLS_INST, &&VNMLA_INST, &&VNMLA_INST, &&VNMLS_INST, &&VNMUL_INST, &&VMUL_INST, &&VADD_INST, &&VSUB_INST,
4098 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 4242 &&VDIV_INST, &&VMOVI_INST, &&VMOVR_INST, &&VABS_INST, &&VNEG_INST, &&VSQRT_INST, &&VCMP_INST, &&VCMP2_INST, &&VCVTBDS_INST,
4099 #undef VFP_INTERPRETER_LABEL 4243 &&VCVTBFF_INST, &&VCVTBFI_INST, &&VMOVBRS_INST, &&VMSR_INST, &&VMOVBRC_INST, &&VMRS_INST, &&VMOVBCR_INST, &&VMOVBRRSS_INST,
4244 &&VMOVBRRD_INST, &&VSTR_INST, &&VPUSH_INST, &&VSTM_INST, &&VPOP_INST, &&VLDR_INST, &&VLDM_INST,
4245
4100 &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST, 4246 &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST,
4101 &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST, 4247 &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST,
4102 &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST, 4248 &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST,
@@ -4130,7 +4276,7 @@ unsigned InterpreterMainLoop(ARMul_State* state)
4130 DISPATCH: 4276 DISPATCH:
4131 { 4277 {
4132 if (!cpu->NirqSig) { 4278 if (!cpu->NirqSig) {
4133 if (!(cpu->Cpsr & 0x80)) { 4279 if (!(cpu->Cpsr & 0x80)) {
4134 goto END; 4280 goto END;
4135 } 4281 }
4136 } 4282 }
@@ -5575,8 +5721,34 @@ unsigned InterpreterMainLoop(ARMul_State* state)
5575 FETCH_INST; 5721 FETCH_INST;
5576 GOTO_NEXT_INST; 5722 GOTO_NEXT_INST;
5577 } 5723 }
5724
5578 PKHBT_INST: 5725 PKHBT_INST:
5726 {
5727 INC_ICOUNTER;
5728 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5729 pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
5730 RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000);
5731 }
5732 cpu->Reg[15] += GET_INST_SIZE(cpu);
5733 INC_PC(sizeof(pkh_inst));
5734 FETCH_INST;
5735 GOTO_NEXT_INST;
5736 }
5737
5579 PKHTB_INST: 5738 PKHTB_INST:
5739 {
5740 INC_ICOUNTER;
5741 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5742 pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
5743 int shift_imm = inst_cream->imm ? inst_cream->imm : 31;
5744 RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000);
5745 }
5746 cpu->Reg[15] += GET_INST_SIZE(cpu);
5747 INC_PC(sizeof(pkh_inst));
5748 FETCH_INST;
5749 GOTO_NEXT_INST;
5750 }
5751
5580 PLD_INST: 5752 PLD_INST:
5581 { 5753 {
5582 INC_ICOUNTER; 5754 INC_ICOUNTER;
@@ -6622,15 +6794,95 @@ unsigned InterpreterMainLoop(ARMul_State* state)
6622 FETCH_INST; 6794 FETCH_INST;
6623 GOTO_NEXT_INST; 6795 GOTO_NEXT_INST;
6624 } 6796 }
6625 UADD16_INST:
6626 UADD8_INST: 6797 UADD8_INST:
6798 UADD16_INST:
6627 UADDSUBX_INST: 6799 UADDSUBX_INST:
6628 UHADD16_INST: 6800
6629 UHADD8_INST: 6801 UHADD8_INST:
6802 UHADD16_INST:
6630 UHADDSUBX_INST: 6803 UHADDSUBX_INST:
6631 UHSUB16_INST:
6632 UHSUB8_INST:
6633 UHSUBADDX_INST: 6804 UHSUBADDX_INST:
6805 UHSUB8_INST:
6806 UHSUB16_INST:
6807 {
6808 INC_ICOUNTER;
6809 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
6810 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
6811
6812 const u32 rm_val = RM;
6813 const u32 rn_val = RN;
6814 const u8 op2 = inst_cream->op2;
6815
6816
6817 if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03)
6818 {
6819 u32 lo_val = 0;
6820 u32 hi_val = 0;
6821
6822 // UHADD16
6823 if (op2 == 0x00) {
6824 lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
6825 hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
6826 }
6827 // UHASX
6828 else if (op2 == 0x01) {
6829 lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
6830 hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
6831 }
6832 // UHSAX
6833 else if (op2 == 0x02) {
6834 lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
6835 hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
6836 }
6837 // UHSUB16
6838 else if (op2 == 0x03) {
6839 lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
6840 hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
6841 }
6842
6843 lo_val >>= 1;
6844 hi_val >>= 1;
6845
6846 RD = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16);
6847 }
6848 else if (op2 == 0x04 || op2 == 0x07) {
6849 u32 sum1;
6850 u32 sum2;
6851 u32 sum3;
6852 u32 sum4;
6853
6854 // UHADD8
6855 if (op2 == 0x04) {
6856 sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
6857 sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
6858 sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
6859 sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
6860 }
6861 // UHSUB8
6862 else {
6863 sum1 = (rn_val & 0xFF) - (rm_val & 0xFF);
6864 sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
6865 sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
6866 sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
6867 }
6868
6869 sum1 >>= 1;
6870 sum2 >>= 1;
6871 sum3 >>= 1;
6872 sum4 >>= 1;
6873
6874 RD = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24);
6875 }
6876
6877 }
6878
6879 cpu->Reg[15] += GET_INST_SIZE(cpu);
6880 INC_PC(sizeof(generic_arm_inst));
6881 FETCH_INST;
6882 GOTO_NEXT_INST;
6883 }
6884
6885
6634 UMAAL_INST: 6886 UMAAL_INST:
6635 { 6887 {
6636 INC_ICOUNTER; 6888 INC_ICOUNTER;
@@ -6764,14 +7016,101 @@ unsigned InterpreterMainLoop(ARMul_State* state)
6764 goto DISPATCH; 7016 goto DISPATCH;
6765 } 7017 }
6766 7018
6767 UQADD16_INST:
6768 UQADD8_INST: 7019 UQADD8_INST:
7020 UQADD16_INST:
6769 UQADDSUBX_INST: 7021 UQADDSUBX_INST:
6770 UQSUB16_INST:
6771 UQSUB8_INST: 7022 UQSUB8_INST:
7023 UQSUB16_INST:
6772 UQSUBADDX_INST: 7024 UQSUBADDX_INST:
7025 {
7026 INC_ICOUNTER;
7027
7028 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
7029 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
7030
7031 const u8 op2 = inst_cream->op2;
7032 const u32 rm_val = RM;
7033 const u32 rn_val = RN;
7034
7035 u16 lo_val = 0;
7036 u16 hi_val = 0;
7037
7038 // UQADD16
7039 if (op2 == 0x00) {
7040 lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF);
7041 hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
7042 }
7043 // UQASX
7044 else if (op2 == 0x01) {
7045 lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
7046 hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
7047 }
7048 // UQSAX
7049 else if (op2 == 0x02) {
7050 lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
7051 hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
7052 }
7053 // UQSUB16
7054 else if (op2 == 0x03) {
7055 lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF);
7056 hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
7057 }
7058 // UQADD8
7059 else if (op2 == 0x04) {
7060 lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) |
7061 ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8;
7062 hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) |
7063 ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8;
7064 }
7065 // UQSUB8
7066 else {
7067 lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) |
7068 ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8;
7069 hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) |
7070 ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8;
7071 }
7072
7073 RD = ((lo_val & 0xFFFF) | hi_val << 16);
7074 }
7075
7076 cpu->Reg[15] += GET_INST_SIZE(cpu);
7077 INC_PC(sizeof(generic_arm_inst));
7078 FETCH_INST;
7079 GOTO_NEXT_INST;
7080 }
7081
6773 USAD8_INST: 7082 USAD8_INST:
6774 USADA8_INST: 7083 USADA8_INST:
7084 {
7085 INC_ICOUNTER;
7086
7087 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
7088 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
7089
7090 const u8 ra_idx = inst_cream->Ra;
7091 const u32 rm_val = RM;
7092 const u32 rn_val = RN;
7093
7094 const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF);
7095 const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF);
7096 const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF);
7097 const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF);
7098
7099 u32 finalDif = (diff1 + diff2 + diff3 + diff4);
7100
7101 // Op is USADA8 if true.
7102 if (ra_idx != 15)
7103 finalDif += cpu->Reg[ra_idx];
7104
7105 RD = finalDif;
7106 }
7107
7108 cpu->Reg[15] += GET_INST_SIZE(cpu);
7109 INC_PC(sizeof(generic_arm_inst));
7110 FETCH_INST;
7111 GOTO_NEXT_INST;
7112 }
7113
6775 USAT_INST: 7114 USAT_INST:
6776 USAT16_INST: 7115 USAT16_INST:
6777 USUB16_INST: 7116 USUB16_INST:
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index d54dbeac5..f0d349de7 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -3100,7 +3100,6 @@ mainswitch:
3100 break; 3100 break;
3101 3101
3102 case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */ 3102 case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */
3103 //ichfly PKHBT PKHTB todo check this
3104 if ((instr & 0x70) == 0x10) { //pkhbt 3103 if ((instr & 0x70) == 0x10) { //pkhbt
3105 u8 idest = BITS(12, 15); 3104 u8 idest = BITS(12, 15);
3106 u8 rfis = BITS(16, 19); 3105 u8 rfis = BITS(16, 19);
@@ -3109,18 +3108,11 @@ mainswitch:
3109 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);
3110 break; 3109 break;
3111 } else if ((instr & 0x70) == 0x50) { //pkhtb 3110 } else if ((instr & 0x70) == 0x50) { //pkhtb
3112 const u8 rd_idx = BITS(12, 15); 3111 u8 rd_idx = BITS(12, 15);
3113 const u8 rn_idx = BITS(16, 19); 3112 u8 rn_idx = BITS(16, 19);
3114 const u8 rm_idx = BITS(0, 3); 3113 u8 rm_idx = BITS(0, 3);
3115 const u8 imm5 = BITS(7, 11); 3114 u8 imm5 = BITS(7, 11) ? BITS(7, 11) : 31;
3116 3115 state->Reg[rd_idx] = ((static_cast<s32>(state->Reg[rm_idx]) >> imm5) & 0xFFFF) | ((state->Reg[rn_idx]) & 0xFFFF0000);
3117 ARMword val;
3118 if (imm5 >= 32)
3119 val = (state->Reg[rm_idx] >> 31);
3120 else
3121 val = (state->Reg[rm_idx] >> imm5);
3122
3123 state->Reg[rd_idx] = (val & 0xFFFF) | ((state->Reg[rn_idx]) & 0xFFFF0000);
3124 break; 3116 break;
3125 } else if (BIT (4)) { 3117 } else if (BIT (4)) {
3126#ifdef MODE32 3118#ifdef MODE32
@@ -6117,30 +6109,130 @@ L_stm_s_takeabort:
6117 } 6109 }
6118 printf("Unhandled v6 insn: uasx/usax\n"); 6110 printf("Unhandled v6 insn: uasx/usax\n");
6119 break; 6111 break;
6120 case 0x66: 6112 case 0x66: // UQADD16, UQASX, UQSAX, UQSUB16, UQADD8, and UQSUB8
6121 if ((instr & 0x0FF00FF0) == 0x06600FF0) { //uqsub8 6113 {
6122 u32 rd = (instr >> 12) & 0xF; 6114 const u8 rd_idx = BITS(12, 15);
6123 u32 rm = (instr >> 16) & 0xF; 6115 const u8 rm_idx = BITS(0, 3);
6124 u32 rn = (instr >> 0) & 0xF; 6116 const u8 rn_idx = BITS(16, 19);
6125 u32 subfrom = state->Reg[rm]; 6117 const u8 op2 = BITS(5, 7);
6126 u32 tosub = state->Reg[rn]; 6118 const u32 rm_val = state->Reg[rm_idx];
6127 6119 const u32 rn_val = state->Reg[rn_idx];
6128 u8 b1 = (u8)((u8)(subfrom)-(u8)(tosub)); 6120
6129 if (b1 > (u8)(subfrom)) b1 = 0; 6121 u16 lo_val = 0;
6130 u8 b2 = (u8)((u8)(subfrom >> 8) - (u8)(tosub >> 8)); 6122 u16 hi_val = 0;
6131 if (b2 > (u8)(subfrom >> 8)) b2 = 0; 6123
6132 u8 b3 = (u8)((u8)(subfrom >> 16) - (u8)(tosub >> 16)); 6124 // UQADD16
6133 if (b3 > (u8)(subfrom >> 16)) b3 = 0; 6125 if (op2 == 0x00) {
6134 u8 b4 = (u8)((u8)(subfrom >> 24) - (u8)(tosub >> 24)); 6126 lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF);
6135 if (b4 > (u8)(subfrom >> 24)) b4 = 0; 6127 hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
6136 state->Reg[rd] = (u32)(b1 | b2 << 8 | b3 << 16 | b4 << 24); 6128 }
6129 // UQASX
6130 else if (op2 == 0x01) {
6131 lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
6132 hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
6133 }
6134 // UQSAX
6135 else if (op2 == 0x02) {
6136 lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
6137 hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
6138 }
6139 // UQSUB16
6140 else if (op2 == 0x03) {
6141 lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF);
6142 hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
6143 }
6144 // UQADD8
6145 else if (op2 == 0x04) {
6146 lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) |
6147 ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8;
6148 hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) |
6149 ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8;
6150 }
6151 // UQSUB8
6152 else {
6153 lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) |
6154 ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8;
6155 hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) |
6156 ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8;
6157 }
6158
6159 state->Reg[rd_idx] = ((lo_val & 0xFFFF) | hi_val << 16);
6137 return 1; 6160 return 1;
6138 } else {
6139 printf ("Unhandled v6 insn: uqsub16\n");
6140 } 6161 }
6141 break; 6162 break;
6142 case 0x67: 6163 case 0x67: // UHADD16, UHASX, UHSAX, UHSUB16, UHADD8, and UHSUB8.
6143 printf ("Unhandled v6 insn: uhadd/uhsub\n"); 6164 {
6165 const u8 op2 = BITS(5, 7);
6166
6167 const u8 rm_idx = BITS(0, 3);
6168 const u8 rn_idx = BITS(16, 19);
6169 const u8 rd_idx = BITS(12, 15);
6170
6171 const u32 rm_val = state->Reg[rm_idx];
6172 const u32 rn_val = state->Reg[rn_idx];
6173
6174 if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03)
6175 {
6176 u32 lo_val = 0;
6177 u32 hi_val = 0;
6178
6179 // UHADD16
6180 if (op2 == 0x00) {
6181 lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
6182 hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
6183 }
6184 // UHASX
6185 else if (op2 == 0x01) {
6186 lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
6187 hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
6188 }
6189 // UHSAX
6190 else if (op2 == 0x02) {
6191 lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
6192 hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
6193 }
6194 // UHSUB16
6195 else if (op2 == 0x03) {
6196 lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
6197 hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
6198 }
6199
6200 lo_val >>= 1;
6201 hi_val >>= 1;
6202
6203 state->Reg[rd_idx] = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16);
6204 return 1;
6205 }
6206 else if (op2 == 0x04 || op2 == 0x07) {
6207 u32 sum1;
6208 u32 sum2;
6209 u32 sum3;
6210 u32 sum4;
6211
6212 // UHADD8
6213 if (op2 == 0x04) {
6214 sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
6215 sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
6216 sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
6217 sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
6218 }
6219 // UHSUB8
6220 else {
6221 sum1 = (rn_val & 0xFF) - (rm_val & 0xFF);
6222 sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
6223 sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
6224 sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
6225 }
6226
6227 sum1 >>= 1;
6228 sum2 >>= 1;
6229 sum3 >>= 1;
6230 sum4 >>= 1;
6231
6232 state->Reg[rd_idx] = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24);
6233 return 1;
6234 }
6235 }
6144 break; 6236 break;
6145 case 0x68: 6237 case 0x68:
6146 { 6238 {
@@ -6172,129 +6264,94 @@ L_stm_s_takeabort:
6172 return 1; 6264 return 1;
6173 } 6265 }
6174 } 6266 }
6175 printf("Unhandled v6 insn: pkh/sxtab/selsxtb\n"); 6267 printf("Unhandled v6 insn: pkh/sxtab/selsxtb\n");
6176 break; 6268 break;
6177 case 0x6a: {
6178 ARMword Rm;
6179 int ror = -1;
6180
6181 switch (BITS(4, 11)) {
6182 case 0x07:
6183 ror = 0;
6184 break;
6185 case 0x47:
6186 ror = 8;
6187 break;
6188 case 0x87:
6189 ror = 16;
6190 break;
6191 case 0xc7:
6192 ror = 24;
6193 break;
6194
6195 case 0x01:
6196 case 0xf3:
6197 //ichfly
6198 //SSAT16
6199 {
6200 const u8 rd_idx = BITS(12, 15);
6201 const u8 rn_idx = BITS(0, 3);
6202 const u8 num_bits = BITS(16, 19) + 1;
6203 const s16 min = -(0x8000 >> (16 - num_bits));
6204 const s16 max = (0x7FFF >> (16 - num_bits));
6205 s16 rn_lo = (state->Reg[rn_idx]);
6206 s16 rn_hi = (state->Reg[rn_idx] >> 16);
6207
6208 if (rn_lo > max) {
6209 rn_lo = max;
6210 SETQ;
6211 } else if (rn_lo < min) {
6212 rn_lo = min;
6213 SETQ;
6214 }
6215
6216 if (rn_hi > max) {
6217 rn_hi = max;
6218 SETQ;
6219 } else if (rn_hi < min) {
6220 rn_hi = min;
6221 SETQ;
6222 }
6223
6224 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi & 0xFFFF) << 16);
6225 return 1;
6226 }
6227 6269
6228 default: 6270 case 0x6a: // SSAT, SSAT16, SXTB, and SXTAB
6229 break; 6271 {
6230 } 6272 const u8 op2 = BITS(5, 7);
6231 6273
6232 if (ror == -1) { 6274 // SSAT16
6233 if (BITS(4, 6) == 0x7) { 6275 if (op2 == 0x01) {
6234 printf("Unhandled v6 insn: ssat\n"); 6276 const u8 rd_idx = BITS(12, 15);
6235 return 0; 6277 const u8 rn_idx = BITS(0, 3);
6278 const u8 num_bits = BITS(16, 19) + 1;
6279 const s16 min = -(0x8000 >> (16 - num_bits));
6280 const s16 max = (0x7FFF >> (16 - num_bits));
6281 s16 rn_lo = (state->Reg[rn_idx]);
6282 s16 rn_hi = (state->Reg[rn_idx] >> 16);
6283
6284 if (rn_lo > max) {
6285 rn_lo = max;
6286 SETQ;
6287 } else if (rn_lo < min) {
6288 rn_lo = min;
6289 SETQ;
6236 } 6290 }
6237 break;
6238 }
6239 6291
6240 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF); 6292 if (rn_hi > max) {
6241 if (Rm & 0x80) 6293 rn_hi = max;
6242 Rm |= 0xffffff00; 6294 SETQ;
6295 } else if (rn_hi < min) {
6296 rn_hi = min;
6297 SETQ;
6298 }
6243 6299
6244 if (BITS(16, 19) == 0xf) 6300 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi & 0xFFFF) << 16);
6245 /* SXTB */ 6301 return 1;
6246 state->Reg[BITS(12, 15)] = Rm; 6302 }
6247 else 6303 else if (op2 == 0x03) {
6248 /* SXTAB */ 6304 const u8 rotation = BITS(10, 11) * 8;
6249 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm; 6305 u32 rm = ((state->Reg[BITS(0, 3)] >> rotation) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotation)) & 0xFF) & 0xFF);
6306 if (rm & 0x80)
6307 rm |= 0xffffff00;
6308
6309 // SXTB, otherwise SXTAB
6310 if (BITS(16, 19) == 0xf)
6311 state->Reg[BITS(12, 15)] = rm;
6312 else
6313 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
6250 6314
6251 return 1; 6315 return 1;
6316 }
6317 else {
6318 printf("Unimplemented op: SSAT");
6319 }
6252 } 6320 }
6253 case 0x6b: 6321 break;
6322
6323 case 0x6b: // REV, REV16, SXTH, and SXTAH
6254 { 6324 {
6255 ARMword Rm; 6325 const u8 op2 = BITS(5, 7);
6256 int ror = -1;
6257
6258 switch (BITS(4, 11)) {
6259 case 0x07:
6260 ror = 0;
6261 break;
6262 case 0x47:
6263 ror = 8;
6264 break;
6265 case 0x87:
6266 ror = 16;
6267 break;
6268 case 0xc7:
6269 ror = 24;
6270 break;
6271
6272 case 0xf3: // REV
6273 DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24);
6274 return 1;
6275 case 0xfb: // REV16
6276 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8);
6277 return 1;
6278 default:
6279 break;
6280 }
6281 6326
6282 if (ror == -1) 6327 // REV
6283 break; 6328 if (op2 == 0x01) {
6329 DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24);
6330 return 1;
6331 }
6332 // REV16
6333 else if (op2 == 0x05) {
6334 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8);
6335 return 1;
6336 }
6337 else if (op2 == 0x03) {
6338 const u8 rotate = BITS(10, 11) * 8;
6284 6339
6285 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF); 6340 u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF);
6286 if (Rm & 0x8000) 6341 if (rm & 0x8000)
6287 Rm |= 0xffff0000; 6342 rm |= 0xffff0000;
6288 6343
6289 if (BITS(16, 19) == 0xf) 6344 // SXTH, otherwise SXTAH
6290 /* SXTH */ 6345 if (BITS(16, 19) == 15)
6291 state->Reg[BITS(12, 15)] = Rm; 6346 state->Reg[BITS(12, 15)] = rm;
6292 else 6347 else
6293 /* SXTAH */ 6348 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
6294 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm;
6295 6349
6296 return 1; 6350 return 1;
6351 }
6297 } 6352 }
6353 break;
6354
6298 case 0x6c: // UXTB16 and UXTAB16 6355 case 0x6c: // UXTB16 and UXTAB16
6299 { 6356 {
6300 const u8 rm_idx = BITS(0, 3); 6357 const u8 rm_idx = BITS(0, 3);
@@ -6322,132 +6379,84 @@ L_stm_s_takeabort:
6322 return 1; 6379 return 1;
6323 } 6380 }
6324 break; 6381 break;
6325 case 0x6e: { 6382 case 0x6e: // USAT, USAT16, UXTB, and UXTAB
6326 ARMword Rm; 6383 {
6327 int ror = -1; 6384 const u8 op2 = BITS(5, 7);
6328
6329 switch (BITS(4, 11)) {
6330 case 0x07:
6331 ror = 0;
6332 break;
6333 case 0x47:
6334 ror = 8;
6335 break;
6336 case 0x87:
6337 ror = 16;
6338 break;
6339 case 0xc7:
6340 ror = 24;
6341 break;
6342
6343 case 0x01:
6344 case 0xf3:
6345 //ichfly
6346 //USAT16
6347 {
6348 const u8 rd_idx = BITS(12, 15);
6349 const u8 rn_idx = BITS(0, 3);
6350 const u8 num_bits = BITS(16, 19);
6351 const s16 max = 0xFFFF >> (16 - num_bits);
6352 s16 rn_lo = (state->Reg[rn_idx]);
6353 s16 rn_hi = (state->Reg[rn_idx] >> 16);
6354
6355 if (max < rn_lo) {
6356 rn_lo = max;
6357 SETQ;
6358 } else if (rn_lo < 0) {
6359 rn_lo = 0;
6360 SETQ;
6361 }
6362
6363 if (max < rn_hi) {
6364 rn_hi = max;
6365 SETQ;
6366 } else if (rn_hi < 0) {
6367 rn_hi = 0;
6368 SETQ;
6369 }
6370
6371 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF);
6372 return 1;
6373 }
6374
6375 default:
6376 break;
6377 }
6378 6385
6379 if (ror == -1) { 6386 // USAT16
6380 if (BITS(4, 6) == 0x7) { 6387 if (op2 == 0x01) {
6381 printf("Unhandled v6 insn: usat\n"); 6388 const u8 rd_idx = BITS(12, 15);
6382 return 0; 6389 const u8 rn_idx = BITS(0, 3);
6390 const u8 num_bits = BITS(16, 19);
6391 const s16 max = 0xFFFF >> (16 - num_bits);
6392 s16 rn_lo = (state->Reg[rn_idx]);
6393 s16 rn_hi = (state->Reg[rn_idx] >> 16);
6394
6395 if (max < rn_lo) {
6396 rn_lo = max;
6397 SETQ;
6398 } else if (rn_lo < 0) {
6399 rn_lo = 0;
6400 SETQ;
6401 }
6402
6403 if (max < rn_hi) {
6404 rn_hi = max;
6405 SETQ;
6406 } else if (rn_hi < 0) {
6407 rn_hi = 0;
6408 SETQ;
6383 } 6409 }
6384 break; 6410
6411 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF);
6412 return 1;
6385 } 6413 }
6386 6414 else if (op2 == 0x03) {
6387 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF); 6415 const u8 rotate = BITS(10, 11) * 8;
6388 6416 const u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFF) & 0xFF);
6389 if (BITS(16, 19) == 0xf) 6417
6418 if (BITS(16, 19) == 0xf)
6390 /* UXTB */ 6419 /* UXTB */
6391 state->Reg[BITS(12, 15)] = Rm; 6420 state->Reg[BITS(12, 15)] = rm;
6392 else 6421 else
6393 /* UXTAB */ 6422 /* UXTAB */
6394 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm; 6423 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
6395 6424
6396 return 1; 6425 return 1;
6397 }
6398
6399 case 0x6f: {
6400 ARMword Rm;
6401 int ror = -1;
6402
6403 switch (BITS(4, 11)) {
6404 case 0x07:
6405 ror = 0;
6406 break;
6407 case 0x47:
6408 ror = 8;
6409 break;
6410 case 0x87:
6411 ror = 16;
6412 break;
6413 case 0xc7:
6414 ror = 24;
6415 break;
6416
6417 case 0xfb: // REVSH
6418 {
6419 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00) >> 8);
6420 if (DEST & 0x8000)
6421 DEST |= 0xffff0000;
6422 return 1;
6423 }
6424 default:
6425 break;
6426 } 6426 }
6427 else {
6428 printf("Unimplemented op: USAT");
6429 }
6430 }
6431 break;
6427 6432
6428 if (ror == -1) 6433 case 0x6f: // UXTH, UXTAH, and REVSH.
6429 break; 6434 {
6430 6435 const u8 op2 = BITS(5, 7);
6431 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF);
6432 6436
6433 /* UXT */ 6437 // REVSH
6434 /* state->Reg[BITS (12, 15)] = Rm; */ 6438 if (op2 == 0x05) {
6435 /* dyf add */ 6439 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00) >> 8);
6436 if (BITS(16, 19) == 0xf) { 6440 if (DEST & 0x8000)
6437 state->Reg[BITS(12, 15)] = Rm; 6441 DEST |= 0xffff0000;
6438 } 6442 return 1;
6439 else {
6440 /* UXTAH */
6441 /* state->Reg[BITS (12, 15)] = state->Reg [BITS (16, 19)] + Rm; */
6442 // printf("rd is %x rn is %x rm is %x rotate is %x\n", state->Reg[BITS (12, 15)], state->Reg[BITS (16, 19)]
6443 // , Rm, BITS(10, 11));
6444 // printf("icounter is %lld\n", state->NumInstrs);
6445 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm;
6446 // printf("rd is %x\n", state->Reg[BITS (12, 15)]);
6447 // exit(-1);
6448 } 6443 }
6444 // UXTH and UXTAH
6445 else if (op2 == 0x03) {
6446 const u8 rotate = BITS(10, 11) * 8;
6447 const ARMword rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF);
6448
6449 // UXTH
6450 if (BITS(16, 19) == 0xf) {
6451 state->Reg[BITS(12, 15)] = rm;
6452 }
6453 // UXTAH
6454 else {
6455 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
6456 }
6449 6457
6450 return 1; 6458 return 1;
6459 }
6451 } 6460 }
6452 case 0x70: 6461 case 0x70:
6453 // ichfly 6462 // ichfly
@@ -6572,10 +6581,10 @@ L_stm_s_takeabort:
6572 const u32 rm_val = state->Reg[rm_idx]; 6581 const u32 rm_val = state->Reg[rm_idx];
6573 const u32 rn_val = state->Reg[rn_idx]; 6582 const u32 rn_val = state->Reg[rn_idx];
6574 6583
6575 const u8 diff1 = (u8)std::labs((rn_val & 0xFF) - (rm_val & 0xFF)); 6584 const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF);
6576 const u8 diff2 = (u8)std::labs(((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF)); 6585 const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF);
6577 const u8 diff3 = (u8)std::labs(((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF)); 6586 const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF);
6578 const u8 diff4 = (u8)std::labs(((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF)); 6587 const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF);
6579 6588
6580 u32 finalDif = (diff1 + diff2 + diff3 + diff4); 6589 u32 finalDif = (diff1 + diff2 + diff3 + diff4);
6581 6590
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
index 6774f8a74..8f158e2c8 100644
--- a/src/core/arm/interpreter/armsupp.cpp
+++ b/src/core/arm/interpreter/armsupp.cpp
@@ -392,6 +392,15 @@ ARMul_NthReg (ARMword instr, unsigned number)
392 return (bit - 1); 392 return (bit - 1);
393} 393}
394 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
395/* 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. */
396 405
397void 406void
@@ -469,6 +478,47 @@ ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
469 ASSIGNV (SubOverflow (a, b, result)); 478 ASSIGNV (SubOverflow (a, b, result));
470} 479}
471 480
481/* 8-bit unsigned saturated addition */
482u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right)
483{
484 u8 result = left + right;
485
486 if (result < left)
487 result = 0xFF;
488
489 return result;
490}
491
492/* 16-bit unsigned saturated addition */
493u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right)
494{
495 u16 result = left + right;
496
497 if (result < left)
498 result = 0xFFFF;
499
500 return result;
501}
502
503/* 8-bit unsigned saturated subtraction */
504u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right)
505{
506 if (left <= right)
507 return 0;
508
509 return left - right;
510}
511
512/* 16-bit unsigned saturated subtraction */
513u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right)
514{
515 if (left <= right)
516 return 0;
517
518 return left - right;
519}
520
521
472/* This function does the work of generating the addresses used in an 522/* This function does the work of generating the addresses used in an
473 LDC instruction. The code here is always post-indexed, it's up to the 523 LDC instruction. The code here is always post-indexed, it's up to the
474 caller to get the input address correct and to handle base register 524 caller to get the input address correct and to handle base register
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h
index 34eb5aaf7..c7509fcb2 100644
--- a/src/core/arm/skyeye_common/armdefs.h
+++ b/src/core/arm/skyeye_common/armdefs.h
@@ -790,6 +790,12 @@ extern void ARMul_FixSPSR(ARMul_State*, ARMword, ARMword);
790extern void ARMul_ConsolePrint(ARMul_State*, const char*, ...); 790extern void ARMul_ConsolePrint(ARMul_State*, const char*, ...);
791extern void ARMul_SelectProcessor(ARMul_State*, unsigned); 791extern void ARMul_SelectProcessor(ARMul_State*, unsigned);
792 792
793extern u8 ARMul_UnsignedSaturatedAdd8(u8, u8);
794extern u16 ARMul_UnsignedSaturatedAdd16(u16, u16);
795extern u8 ARMul_UnsignedSaturatedSub8(u8, u8);
796extern u16 ARMul_UnsignedSaturatedSub16(u16, u16);
797extern u8 ARMul_UnsignedAbsoluteDifference(u8, u8);
798
793#define DIFF_LOG 0 799#define DIFF_LOG 0
794#define SAVE_LOG 0 800#define SAVE_LOG 0
795 801
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..2320449b6 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,7 +54,7 @@ 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; 59 INC_ICOUNTER;
75 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 60 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -77,7 +62,7 @@ VFPLABEL_INST:
77 62
78 DBG("VMLA :\n"); 63 DBG("VMLA :\n");
79 64
80 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 65 vmla_inst *inst_cream = (vmla_inst *)inst_base->component;
81 66
82 int ret; 67 int ret;
83 68
@@ -89,22 +74,17 @@ VFPLABEL_INST:
89 CHECK_VFP_CDP_RET; 74 CHECK_VFP_CDP_RET;
90 } 75 }
91 cpu->Reg[15] += GET_INST_SIZE(cpu); 76 cpu->Reg[15] += GET_INST_SIZE(cpu);
92 INC_PC(sizeof(vfpinstr_inst)); 77 INC_PC(sizeof(vmla_inst));
93 FETCH_INST; 78 FETCH_INST;
94 GOTO_NEXT_INST; 79 GOTO_NEXT_INST;
95} 80}
96#endif 81#endif
97#ifdef VFP_CDP_TRANS 82
98if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 0)
99{
100 DBG("VMLA :\n");
101}
102#endif
103#ifdef VFP_DYNCOM_TABLE 83#ifdef VFP_DYNCOM_TABLE
104DYNCOM_FILL_ACTION(vfpinstr), 84DYNCOM_FILL_ACTION(vmla),
105#endif 85#endif
106#ifdef VFP_DYNCOM_TAG 86#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) 87int DYNCOM_TAG(vmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
108{ 88{
109 int instr_size = INSTR_SIZE; 89 int instr_size = INSTR_SIZE;
110 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 90 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -114,7 +94,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
114} 94}
115#endif 95#endif
116#ifdef VFP_DYNCOM_TRANS 96#ifdef VFP_DYNCOM_TRANS
117int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 97int 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__); 98 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
119 //arch_arm_undef(cpu, bb, instr); 99 //arch_arm_undef(cpu, bb, instr);
120 int m; 100 int m;
@@ -168,41 +148,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
168 return No_exp; 148 return No_exp;
169} 149}
170#endif 150#endif
171#undef vfpinstr
172#undef vfpinstr_inst
173#undef VFPLABEL_INST
174 151
175/* ----------------------------------------------------------------------- */ 152/* ----------------------------------------------------------------------- */
176/* VNMLS */ 153/* VNMLS */
177/* cond 1110 0D00 Vn-- Vd-- 101X N1M0 Vm-- */ 154/* 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 155#ifdef VFP_INTERPRETER_STRUCT
194typedef struct _vmls_inst { 156typedef struct _vmls_inst {
195 unsigned int instr; 157 unsigned int instr;
196 unsigned int dp_operation; 158 unsigned int dp_operation;
197} vfpinstr_inst; 159} vmls_inst;
198#endif 160#endif
199#ifdef VFP_INTERPRETER_TRANS 161#ifdef VFP_INTERPRETER_TRANS
200ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 162ARM_INST_PTR INTERPRETER_TRANSLATE(vmls)(unsigned int inst, int index)
201{ 163{
202 VFP_DEBUG_TRANSLATE; 164 VFP_DEBUG_TRANSLATE;
203 165
204 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 166 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmls_inst));
205 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 167 vmls_inst *inst_cream = (vmls_inst *)inst_base->component;
206 168
207 inst_base->cond = BITS(inst, 28, 31); 169 inst_base->cond = BITS(inst, 28, 31);
208 inst_base->idx = index; 170 inst_base->idx = index;
@@ -216,7 +178,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
216} 178}
217#endif 179#endif
218#ifdef VFP_INTERPRETER_IMPL 180#ifdef VFP_INTERPRETER_IMPL
219VFPLABEL_INST: 181VMLS_INST:
220{ 182{
221 INC_ICOUNTER; 183 INC_ICOUNTER;
222 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 184 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -224,7 +186,7 @@ VFPLABEL_INST:
224 186
225 DBG("VMLS :\n"); 187 DBG("VMLS :\n");
226 188
227 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 189 vmls_inst *inst_cream = (vmls_inst *)inst_base->component;
228 190
229 int ret; 191 int ret;
230 192
@@ -236,22 +198,17 @@ VFPLABEL_INST:
236 CHECK_VFP_CDP_RET; 198 CHECK_VFP_CDP_RET;
237 } 199 }
238 cpu->Reg[15] += GET_INST_SIZE(cpu); 200 cpu->Reg[15] += GET_INST_SIZE(cpu);
239 INC_PC(sizeof(vfpinstr_inst)); 201 INC_PC(sizeof(vmls_inst));
240 FETCH_INST; 202 FETCH_INST;
241 GOTO_NEXT_INST; 203 GOTO_NEXT_INST;
242} 204}
243#endif 205#endif
244#ifdef VFP_CDP_TRANS 206
245if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 2)
246{
247 DBG("VMLS :\n");
248}
249#endif
250#ifdef VFP_DYNCOM_TABLE 207#ifdef VFP_DYNCOM_TABLE
251DYNCOM_FILL_ACTION(vfpinstr), 208DYNCOM_FILL_ACTION(vmls),
252#endif 209#endif
253#ifdef VFP_DYNCOM_TAG 210#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) 211int DYNCOM_TAG(vmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
255{ 212{
256 int instr_size = INSTR_SIZE; 213 int instr_size = INSTR_SIZE;
257 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 214 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -261,7 +218,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
261} 218}
262#endif 219#endif
263#ifdef VFP_DYNCOM_TRANS 220#ifdef VFP_DYNCOM_TRANS
264int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 221int 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__); 222 DBG("\t\tin %s VMLS instruction is executed out of here.\n", __FUNCTION__);
266 //arch_arm_undef(cpu, bb, instr); 223 //arch_arm_undef(cpu, bb, instr);
267 int m; 224 int m;
@@ -315,47 +272,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
315 return No_exp; 272 return No_exp;
316} 273}
317#endif 274#endif
318#undef vfpinstr
319#undef vfpinstr_inst
320#undef VFPLABEL_INST
321 275
322/* ----------------------------------------------------------------------- */ 276/* ----------------------------------------------------------------------- */
323/* VNMLA */ 277/* VNMLA */
324/* cond 1110 0D01 Vn-- Vd-- 101X N1M0 Vm-- */ 278/* 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 279#ifdef VFP_INTERPRETER_STRUCT
347typedef struct _vnmla_inst { 280typedef struct _vnmla_inst {
348 unsigned int instr; 281 unsigned int instr;
349 unsigned int dp_operation; 282 unsigned int dp_operation;
350} vfpinstr_inst; 283} vnmla_inst;
351#endif 284#endif
352#ifdef VFP_INTERPRETER_TRANS 285#ifdef VFP_INTERPRETER_TRANS
353ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 286ARM_INST_PTR INTERPRETER_TRANSLATE(vnmla)(unsigned int inst, int index)
354{ 287{
355 VFP_DEBUG_TRANSLATE; 288 VFP_DEBUG_TRANSLATE;
356 289
357 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 290 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmla_inst));
358 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 291 vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component;
359 292
360 inst_base->cond = BITS(inst, 28, 31); 293 inst_base->cond = BITS(inst, 28, 31);
361 inst_base->idx = index; 294 inst_base->idx = index;
@@ -369,7 +302,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
369} 302}
370#endif 303#endif
371#ifdef VFP_INTERPRETER_IMPL 304#ifdef VFP_INTERPRETER_IMPL
372VFPLABEL_INST: 305VNMLA_INST:
373{ 306{
374 INC_ICOUNTER; 307 INC_ICOUNTER;
375 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 308 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -377,7 +310,7 @@ VFPLABEL_INST:
377 310
378 DBG("VNMLA :\n"); 311 DBG("VNMLA :\n");
379 312
380 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 313 vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component;
381 314
382 int ret; 315 int ret;
383 316
@@ -389,23 +322,18 @@ VFPLABEL_INST:
389 CHECK_VFP_CDP_RET; 322 CHECK_VFP_CDP_RET;
390 } 323 }
391 cpu->Reg[15] += GET_INST_SIZE(cpu); 324 cpu->Reg[15] += GET_INST_SIZE(cpu);
392 INC_PC(sizeof(vfpinstr_inst)); 325 INC_PC(sizeof(vnmla_inst));
393 FETCH_INST; 326 FETCH_INST;
394 GOTO_NEXT_INST; 327 GOTO_NEXT_INST;
395} 328}
396#endif 329#endif
397#ifdef VFP_CDP_TRANS 330
398if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 2)
399{
400 DBG("VNMLA :\n");
401}
402#endif
403#ifdef VFP_DYNCOM_TABLE 331#ifdef VFP_DYNCOM_TABLE
404DYNCOM_FILL_ACTION(vfpinstr), 332DYNCOM_FILL_ACTION(vnmla),
405DYNCOM_FILL_ACTION(vfpinstr), 333DYNCOM_FILL_ACTION(vnmla),
406#endif 334#endif
407#ifdef VFP_DYNCOM_TAG 335#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) 336int DYNCOM_TAG(vnmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
409{ 337{
410 int instr_size = INSTR_SIZE; 338 int instr_size = INSTR_SIZE;
411 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 339 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -415,7 +343,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
415} 343}
416#endif 344#endif
417#ifdef VFP_DYNCOM_TRANS 345#ifdef VFP_DYNCOM_TRANS
418int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 346int 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__); 347 DBG("\t\tin %s VNMLA instruction is executed out of here.\n", __FUNCTION__);
420 //arch_arm_undef(cpu, bb, instr); 348 //arch_arm_undef(cpu, bb, instr);
421 int m; 349 int m;
@@ -469,41 +397,24 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
469 return No_exp; 397 return No_exp;
470} 398}
471#endif 399#endif
472#undef vfpinstr
473#undef vfpinstr_inst
474#undef VFPLABEL_INST
475 400
476/* ----------------------------------------------------------------------- */ 401/* ----------------------------------------------------------------------- */
477/* VNMLS */ 402/* VNMLS */
478/* cond 1110 0D01 Vn-- Vd-- 101X N0M0 Vm-- */ 403/* cond 1110 0D01 Vn-- Vd-- 101X N0M0 Vm-- */
479#define vfpinstr vnmls 404
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 405#ifdef VFP_INTERPRETER_STRUCT
495typedef struct _vnmls_inst { 406typedef struct _vnmls_inst {
496 unsigned int instr; 407 unsigned int instr;
497 unsigned int dp_operation; 408 unsigned int dp_operation;
498} vfpinstr_inst; 409} vnmls_inst;
499#endif 410#endif
500#ifdef VFP_INTERPRETER_TRANS 411#ifdef VFP_INTERPRETER_TRANS
501ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 412ARM_INST_PTR INTERPRETER_TRANSLATE(vnmls)(unsigned int inst, int index)
502{ 413{
503 VFP_DEBUG_TRANSLATE; 414 VFP_DEBUG_TRANSLATE;
504 415
505 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 416 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmls_inst));
506 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 417 vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component;
507 418
508 inst_base->cond = BITS(inst, 28, 31); 419 inst_base->cond = BITS(inst, 28, 31);
509 inst_base->idx = index; 420 inst_base->idx = index;
@@ -517,7 +428,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
517} 428}
518#endif 429#endif
519#ifdef VFP_INTERPRETER_IMPL 430#ifdef VFP_INTERPRETER_IMPL
520VFPLABEL_INST: 431VNMLS_INST:
521{ 432{
522 INC_ICOUNTER; 433 INC_ICOUNTER;
523 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 434 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -525,7 +436,7 @@ VFPLABEL_INST:
525 436
526 DBG("VNMLS :\n"); 437 DBG("VNMLS :\n");
527 438
528 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 439 vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component;
529 440
530 int ret; 441 int ret;
531 442
@@ -537,22 +448,17 @@ VFPLABEL_INST:
537 CHECK_VFP_CDP_RET; 448 CHECK_VFP_CDP_RET;
538 } 449 }
539 cpu->Reg[15] += GET_INST_SIZE(cpu); 450 cpu->Reg[15] += GET_INST_SIZE(cpu);
540 INC_PC(sizeof(vfpinstr_inst)); 451 INC_PC(sizeof(vnmls_inst));
541 FETCH_INST; 452 FETCH_INST;
542 GOTO_NEXT_INST; 453 GOTO_NEXT_INST;
543} 454}
544#endif 455#endif
545#ifdef VFP_CDP_TRANS 456
546if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 0)
547{
548 DBG("VNMLS :\n");
549}
550#endif
551#ifdef VFP_DYNCOM_TABLE 457#ifdef VFP_DYNCOM_TABLE
552DYNCOM_FILL_ACTION(vfpinstr), 458DYNCOM_FILL_ACTION(vnmls),
553#endif 459#endif
554#ifdef VFP_DYNCOM_TAG 460#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) 461int DYNCOM_TAG(vnmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
556{ 462{
557 int instr_size = INSTR_SIZE; 463 int instr_size = INSTR_SIZE;
558 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 464 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -562,7 +468,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
562} 468}
563#endif 469#endif
564#ifdef VFP_DYNCOM_TRANS 470#ifdef VFP_DYNCOM_TRANS
565int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 471int 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__); 472 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
567 //arch_arm_undef(cpu, bb, instr); 473 //arch_arm_undef(cpu, bb, instr);
568 int m; 474 int m;
@@ -616,41 +522,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
616 return No_exp; 522 return No_exp;
617} 523}
618#endif 524#endif
619#undef vfpinstr
620#undef vfpinstr_inst
621#undef VFPLABEL_INST
622 525
623/* ----------------------------------------------------------------------- */ 526/* ----------------------------------------------------------------------- */
624/* VNMUL */ 527/* VNMUL */
625/* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */ 528/* 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 529#ifdef VFP_INTERPRETER_STRUCT
642typedef struct _vnmul_inst { 530typedef struct _vnmul_inst {
643 unsigned int instr; 531 unsigned int instr;
644 unsigned int dp_operation; 532 unsigned int dp_operation;
645} vfpinstr_inst; 533} vnmul_inst;
646#endif 534#endif
647#ifdef VFP_INTERPRETER_TRANS 535#ifdef VFP_INTERPRETER_TRANS
648ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 536ARM_INST_PTR INTERPRETER_TRANSLATE(vnmul)(unsigned int inst, int index)
649{ 537{
650 VFP_DEBUG_TRANSLATE; 538 VFP_DEBUG_TRANSLATE;
651 539
652 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 540 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmul_inst));
653 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 541 vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component;
654 542
655 inst_base->cond = BITS(inst, 28, 31); 543 inst_base->cond = BITS(inst, 28, 31);
656 inst_base->idx = index; 544 inst_base->idx = index;
@@ -664,7 +552,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
664} 552}
665#endif 553#endif
666#ifdef VFP_INTERPRETER_IMPL 554#ifdef VFP_INTERPRETER_IMPL
667VFPLABEL_INST: 555VNMUL_INST:
668{ 556{
669 INC_ICOUNTER; 557 INC_ICOUNTER;
670 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 558 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -672,7 +560,7 @@ VFPLABEL_INST:
672 560
673 DBG("VNMUL :\n"); 561 DBG("VNMUL :\n");
674 562
675 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 563 vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component;
676 564
677 int ret; 565 int ret;
678 566
@@ -684,22 +572,17 @@ VFPLABEL_INST:
684 CHECK_VFP_CDP_RET; 572 CHECK_VFP_CDP_RET;
685 } 573 }
686 cpu->Reg[15] += GET_INST_SIZE(cpu); 574 cpu->Reg[15] += GET_INST_SIZE(cpu);
687 INC_PC(sizeof(vfpinstr_inst)); 575 INC_PC(sizeof(vnmul_inst));
688 FETCH_INST; 576 FETCH_INST;
689 GOTO_NEXT_INST; 577 GOTO_NEXT_INST;
690} 578}
691#endif 579#endif
692#ifdef VFP_CDP_TRANS 580
693if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 2)
694{
695 DBG("VNMUL :\n");
696}
697#endif
698#ifdef VFP_DYNCOM_TABLE 581#ifdef VFP_DYNCOM_TABLE
699DYNCOM_FILL_ACTION(vfpinstr), 582DYNCOM_FILL_ACTION(vnmul),
700#endif 583#endif
701#ifdef VFP_DYNCOM_TAG 584#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) 585int DYNCOM_TAG(vnmul)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
703{ 586{
704 int instr_size = INSTR_SIZE; 587 int instr_size = INSTR_SIZE;
705 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 588 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -709,7 +592,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
709} 592}
710#endif 593#endif
711#ifdef VFP_DYNCOM_TRANS 594#ifdef VFP_DYNCOM_TRANS
712int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 595int 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__); 596 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
714 //arch_arm_undef(cpu, bb, instr); 597 //arch_arm_undef(cpu, bb, instr);
715 int m; 598 int m;
@@ -753,41 +636,24 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
753 return No_exp; 636 return No_exp;
754} 637}
755#endif 638#endif
756#undef vfpinstr 639
757#undef vfpinstr_inst
758#undef VFPLABEL_INST
759 640
760/* ----------------------------------------------------------------------- */ 641/* ----------------------------------------------------------------------- */
761/* VMUL */ 642/* VMUL */
762/* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */ 643/* 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 644#ifdef VFP_INTERPRETER_STRUCT
779typedef struct _vmul_inst { 645typedef struct _vmul_inst {
780 unsigned int instr; 646 unsigned int instr;
781 unsigned int dp_operation; 647 unsigned int dp_operation;
782} vfpinstr_inst; 648} vmul_inst;
783#endif 649#endif
784#ifdef VFP_INTERPRETER_TRANS 650#ifdef VFP_INTERPRETER_TRANS
785ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 651ARM_INST_PTR INTERPRETER_TRANSLATE(vmul)(unsigned int inst, int index)
786{ 652{
787 VFP_DEBUG_TRANSLATE; 653 VFP_DEBUG_TRANSLATE;
788 654
789 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 655 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmul_inst));
790 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 656 vmul_inst *inst_cream = (vmul_inst *)inst_base->component;
791 657
792 inst_base->cond = BITS(inst, 28, 31); 658 inst_base->cond = BITS(inst, 28, 31);
793 inst_base->idx = index; 659 inst_base->idx = index;
@@ -801,7 +667,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
801} 667}
802#endif 668#endif
803#ifdef VFP_INTERPRETER_IMPL 669#ifdef VFP_INTERPRETER_IMPL
804VFPLABEL_INST: 670VMUL_INST:
805{ 671{
806 INC_ICOUNTER; 672 INC_ICOUNTER;
807 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 673 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -809,7 +675,7 @@ VFPLABEL_INST:
809 675
810 DBG("VMUL :\n"); 676 DBG("VMUL :\n");
811 677
812 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 678 vmul_inst *inst_cream = (vmul_inst *)inst_base->component;
813 679
814 int ret; 680 int ret;
815 681
@@ -821,22 +687,17 @@ VFPLABEL_INST:
821 CHECK_VFP_CDP_RET; 687 CHECK_VFP_CDP_RET;
822 } 688 }
823 cpu->Reg[15] += GET_INST_SIZE(cpu); 689 cpu->Reg[15] += GET_INST_SIZE(cpu);
824 INC_PC(sizeof(vfpinstr_inst)); 690 INC_PC(sizeof(vmul_inst));
825 FETCH_INST; 691 FETCH_INST;
826 GOTO_NEXT_INST; 692 GOTO_NEXT_INST;
827} 693}
828#endif 694#endif
829#ifdef VFP_CDP_TRANS 695
830if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 0)
831{
832 DBG("VMUL :\n");
833}
834#endif
835#ifdef VFP_DYNCOM_TABLE 696#ifdef VFP_DYNCOM_TABLE
836DYNCOM_FILL_ACTION(vfpinstr), 697DYNCOM_FILL_ACTION(vmul),
837#endif 698#endif
838#ifdef VFP_DYNCOM_TAG 699#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) 700int DYNCOM_TAG(vmul)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
840{ 701{
841 int instr_size = INSTR_SIZE; 702 int instr_size = INSTR_SIZE;
842 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 703 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -846,7 +707,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
846} 707}
847#endif 708#endif
848#ifdef VFP_DYNCOM_TRANS 709#ifdef VFP_DYNCOM_TRANS
849int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 710int 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__); 711 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
851 //printf("\n\n\t\tin %s instruction is executed out.\n\n", __FUNCTION__); 712 //printf("\n\n\t\tin %s instruction is executed out.\n\n", __FUNCTION__);
852 //arch_arm_undef(cpu, bb, instr); 713 //arch_arm_undef(cpu, bb, instr);
@@ -904,41 +765,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
904 return No_exp; 765 return No_exp;
905} 766}
906#endif 767#endif
907#undef vfpinstr
908#undef vfpinstr_inst
909#undef VFPLABEL_INST
910 768
911/* ----------------------------------------------------------------------- */ 769/* ----------------------------------------------------------------------- */
912/* VADD */ 770/* VADD */
913/* cond 1110 0D11 Vn-- Vd-- 101X N0M0 Vm-- */ 771/* 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 772#ifdef VFP_INTERPRETER_STRUCT
930typedef struct _vadd_inst { 773typedef struct _vadd_inst {
931 unsigned int instr; 774 unsigned int instr;
932 unsigned int dp_operation; 775 unsigned int dp_operation;
933} vfpinstr_inst; 776} vadd_inst;
934#endif 777#endif
935#ifdef VFP_INTERPRETER_TRANS 778#ifdef VFP_INTERPRETER_TRANS
936ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 779ARM_INST_PTR INTERPRETER_TRANSLATE(vadd)(unsigned int inst, int index)
937{ 780{
938 VFP_DEBUG_TRANSLATE; 781 VFP_DEBUG_TRANSLATE;
939 782
940 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 783 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vadd_inst));
941 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 784 vadd_inst *inst_cream = (vadd_inst *)inst_base->component;
942 785
943 inst_base->cond = BITS(inst, 28, 31); 786 inst_base->cond = BITS(inst, 28, 31);
944 inst_base->idx = index; 787 inst_base->idx = index;
@@ -952,7 +795,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
952} 795}
953#endif 796#endif
954#ifdef VFP_INTERPRETER_IMPL 797#ifdef VFP_INTERPRETER_IMPL
955VFPLABEL_INST: 798VADD_INST:
956{ 799{
957 INC_ICOUNTER; 800 INC_ICOUNTER;
958 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 801 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -960,7 +803,7 @@ VFPLABEL_INST:
960 803
961 DBG("VADD :\n"); 804 DBG("VADD :\n");
962 805
963 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 806 vadd_inst *inst_cream = (vadd_inst *)inst_base->component;
964 807
965 int ret; 808 int ret;
966 809
@@ -972,22 +815,17 @@ VFPLABEL_INST:
972 CHECK_VFP_CDP_RET; 815 CHECK_VFP_CDP_RET;
973 } 816 }
974 cpu->Reg[15] += GET_INST_SIZE(cpu); 817 cpu->Reg[15] += GET_INST_SIZE(cpu);
975 INC_PC(sizeof(vfpinstr_inst)); 818 INC_PC(sizeof(vadd_inst));
976 FETCH_INST; 819 FETCH_INST;
977 GOTO_NEXT_INST; 820 GOTO_NEXT_INST;
978} 821}
979#endif 822#endif
980#ifdef VFP_CDP_TRANS 823
981if ((OPC_1 & 0xB) == 3 && (OPC_2 & 0x2) == 0)
982{
983 DBG("VADD :\n");
984}
985#endif
986#ifdef VFP_DYNCOM_TABLE 824#ifdef VFP_DYNCOM_TABLE
987DYNCOM_FILL_ACTION(vfpinstr), 825DYNCOM_FILL_ACTION(vadd),
988#endif 826#endif
989#ifdef VFP_DYNCOM_TAG 827#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) 828int DYNCOM_TAG(vadd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
991{ 829{
992 int instr_size = INSTR_SIZE; 830 int instr_size = INSTR_SIZE;
993 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 831 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -997,7 +835,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
997} 835}
998#endif 836#endif
999#ifdef VFP_DYNCOM_TRANS 837#ifdef VFP_DYNCOM_TRANS
1000int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 838int 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__); 839 DBG("\t\tin %s instruction will implement out of JIT.\n", __FUNCTION__);
1002 //arch_arm_undef(cpu, bb, instr); 840 //arch_arm_undef(cpu, bb, instr);
1003 int m; 841 int m;
@@ -1049,41 +887,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
1049 return No_exp; 887 return No_exp;
1050} 888}
1051#endif 889#endif
1052#undef vfpinstr
1053#undef vfpinstr_inst
1054#undef VFPLABEL_INST
1055 890
1056/* ----------------------------------------------------------------------- */ 891/* ----------------------------------------------------------------------- */
1057/* VSUB */ 892/* VSUB */
1058/* cond 1110 0D11 Vn-- Vd-- 101X N1M0 Vm-- */ 893/* 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 894#ifdef VFP_INTERPRETER_STRUCT
1075typedef struct _vsub_inst { 895typedef struct _vsub_inst {
1076 unsigned int instr; 896 unsigned int instr;
1077 unsigned int dp_operation; 897 unsigned int dp_operation;
1078} vfpinstr_inst; 898} vsub_inst;
1079#endif 899#endif
1080#ifdef VFP_INTERPRETER_TRANS 900#ifdef VFP_INTERPRETER_TRANS
1081ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 901ARM_INST_PTR INTERPRETER_TRANSLATE(vsub)(unsigned int inst, int index)
1082{ 902{
1083 VFP_DEBUG_TRANSLATE; 903 VFP_DEBUG_TRANSLATE;
1084 904
1085 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 905 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsub_inst));
1086 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 906 vsub_inst *inst_cream = (vsub_inst *)inst_base->component;
1087 907
1088 inst_base->cond = BITS(inst, 28, 31); 908 inst_base->cond = BITS(inst, 28, 31);
1089 inst_base->idx = index; 909 inst_base->idx = index;
@@ -1097,7 +917,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
1097} 917}
1098#endif 918#endif
1099#ifdef VFP_INTERPRETER_IMPL 919#ifdef VFP_INTERPRETER_IMPL
1100VFPLABEL_INST: 920VSUB_INST:
1101{ 921{
1102 INC_ICOUNTER; 922 INC_ICOUNTER;
1103 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 923 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -1105,7 +925,7 @@ VFPLABEL_INST:
1105 925
1106 DBG("VSUB :\n"); 926 DBG("VSUB :\n");
1107 927
1108 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 928 vsub_inst *inst_cream = (vsub_inst *)inst_base->component;
1109 929
1110 int ret; 930 int ret;
1111 931
@@ -1117,22 +937,16 @@ VFPLABEL_INST:
1117 CHECK_VFP_CDP_RET; 937 CHECK_VFP_CDP_RET;
1118 } 938 }
1119 cpu->Reg[15] += GET_INST_SIZE(cpu); 939 cpu->Reg[15] += GET_INST_SIZE(cpu);
1120 INC_PC(sizeof(vfpinstr_inst)); 940 INC_PC(sizeof(vsub_inst));
1121 FETCH_INST; 941 FETCH_INST;
1122 GOTO_NEXT_INST; 942 GOTO_NEXT_INST;
1123} 943}
1124#endif 944#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 945#ifdef VFP_DYNCOM_TABLE
1132DYNCOM_FILL_ACTION(vfpinstr), 946DYNCOM_FILL_ACTION(vsub),
1133#endif 947#endif
1134#ifdef VFP_DYNCOM_TAG 948#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) 949int DYNCOM_TAG(vsub)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1136{ 950{
1137 int instr_size = INSTR_SIZE; 951 int instr_size = INSTR_SIZE;
1138 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 952 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
@@ -1141,7 +955,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
1141} 955}
1142#endif 956#endif
1143#ifdef VFP_DYNCOM_TRANS 957#ifdef VFP_DYNCOM_TRANS
1144int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 958int 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); 959 DBG("\t\tin %s instr=0x%x, instruction is executed out of JIT.\n", __FUNCTION__, instr);
1146 //arch_arm_undef(cpu, bb, instr); 960 //arch_arm_undef(cpu, bb, instr);
1147 int m; 961 int m;
@@ -1193,41 +1007,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
1193 return No_exp; 1007 return No_exp;
1194} 1008}
1195#endif 1009#endif
1196#undef vfpinstr
1197#undef vfpinstr_inst
1198#undef VFPLABEL_INST
1199 1010
1200/* ----------------------------------------------------------------------- */ 1011/* ----------------------------------------------------------------------- */
1201/* VDIV */ 1012/* VDIV */
1202/* cond 1110 1D00 Vn-- Vd-- 101X N0M0 Vm-- */ 1013/* 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 1014#ifdef VFP_INTERPRETER_STRUCT
1219typedef struct _vdiv_inst { 1015typedef struct _vdiv_inst {
1220 unsigned int instr; 1016 unsigned int instr;
1221 unsigned int dp_operation; 1017 unsigned int dp_operation;
1222} vfpinstr_inst; 1018} vdiv_inst;
1223#endif 1019#endif
1224#ifdef VFP_INTERPRETER_TRANS 1020#ifdef VFP_INTERPRETER_TRANS
1225ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1021ARM_INST_PTR INTERPRETER_TRANSLATE(vdiv)(unsigned int inst, int index)
1226{ 1022{
1227 VFP_DEBUG_TRANSLATE; 1023 VFP_DEBUG_TRANSLATE;
1228 1024
1229 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1025 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vdiv_inst));
1230 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1026 vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component;
1231 1027
1232 inst_base->cond = BITS(inst, 28, 31); 1028 inst_base->cond = BITS(inst, 28, 31);
1233 inst_base->idx = index; 1029 inst_base->idx = index;
@@ -1241,7 +1037,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
1241} 1037}
1242#endif 1038#endif
1243#ifdef VFP_INTERPRETER_IMPL 1039#ifdef VFP_INTERPRETER_IMPL
1244VFPLABEL_INST: 1040VDIV_INST:
1245{ 1041{
1246 INC_ICOUNTER; 1042 INC_ICOUNTER;
1247 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1043 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -1249,7 +1045,7 @@ VFPLABEL_INST:
1249 1045
1250 DBG("VDIV :\n"); 1046 DBG("VDIV :\n");
1251 1047
1252 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1048 vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component;
1253 1049
1254 int ret; 1050 int ret;
1255 1051
@@ -1261,22 +1057,17 @@ VFPLABEL_INST:
1261 CHECK_VFP_CDP_RET; 1057 CHECK_VFP_CDP_RET;
1262 } 1058 }
1263 cpu->Reg[15] += GET_INST_SIZE(cpu); 1059 cpu->Reg[15] += GET_INST_SIZE(cpu);
1264 INC_PC(sizeof(vfpinstr_inst)); 1060 INC_PC(sizeof(vdiv_inst));
1265 FETCH_INST; 1061 FETCH_INST;
1266 GOTO_NEXT_INST; 1062 GOTO_NEXT_INST;
1267} 1063}
1268#endif 1064#endif
1269#ifdef VFP_CDP_TRANS 1065
1270if ((OPC_1 & 0xB) == 0xA && (OPC_2 & 0x2) == 0)
1271{
1272 DBG("VDIV :\n");
1273}
1274#endif
1275#ifdef VFP_DYNCOM_TABLE 1066#ifdef VFP_DYNCOM_TABLE
1276DYNCOM_FILL_ACTION(vfpinstr), 1067DYNCOM_FILL_ACTION(vdiv),
1277#endif 1068#endif
1278#ifdef VFP_DYNCOM_TAG 1069#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) 1070int DYNCOM_TAG(vdiv)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1280{ 1071{
1281 int instr_size = INSTR_SIZE; 1072 int instr_size = INSTR_SIZE;
1282 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1073 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -1286,7 +1077,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
1286} 1077}
1287#endif 1078#endif
1288#ifdef VFP_DYNCOM_TRANS 1079#ifdef VFP_DYNCOM_TRANS
1289int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1080int 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__); 1081 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1291 //arch_arm_undef(cpu, bb, instr); 1082 //arch_arm_undef(cpu, bb, instr);
1292 int m; 1083 int m;
@@ -1338,43 +1129,25 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
1338 return No_exp; 1129 return No_exp;
1339} 1130}
1340#endif 1131#endif
1341#undef vfpinstr
1342#undef vfpinstr_inst
1343#undef VFPLABEL_INST
1344 1132
1345/* ----------------------------------------------------------------------- */ 1133/* ----------------------------------------------------------------------- */
1346/* VMOVI move immediate */ 1134/* VMOVI move immediate */
1347/* cond 1110 1D11 im4H Vd-- 101X 0000 im4L */ 1135/* cond 1110 1D11 im4H Vd-- 101X 0000 im4L */
1348/* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */ 1136/* 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 1137#ifdef VFP_INTERPRETER_STRUCT
1365typedef struct _vmovi_inst { 1138typedef struct _vmovi_inst {
1366 unsigned int single; 1139 unsigned int single;
1367 unsigned int d; 1140 unsigned int d;
1368 unsigned int imm; 1141 unsigned int imm;
1369} vfpinstr_inst; 1142} vmovi_inst;
1370#endif 1143#endif
1371#ifdef VFP_INTERPRETER_TRANS 1144#ifdef VFP_INTERPRETER_TRANS
1372ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1145ARM_INST_PTR INTERPRETER_TRANSLATE(vmovi)(unsigned int inst, int index)
1373{ 1146{
1374 VFP_DEBUG_TRANSLATE; 1147 VFP_DEBUG_TRANSLATE;
1375 1148
1376 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1149 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovi_inst));
1377 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1150 vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component;
1378 1151
1379 inst_base->cond = BITS(inst, 28, 31); 1152 inst_base->cond = BITS(inst, 28, 31);
1380 inst_base->idx = index; 1153 inst_base->idx = index;
@@ -1392,62 +1165,28 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
1392} 1165}
1393#endif 1166#endif
1394#ifdef VFP_INTERPRETER_IMPL 1167#ifdef VFP_INTERPRETER_IMPL
1395VFPLABEL_INST: 1168VMOVI_INST:
1396{ 1169{
1397 INC_ICOUNTER; 1170 INC_ICOUNTER;
1398 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1171 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1399 CHECK_VFP_ENABLED; 1172 CHECK_VFP_ENABLED;
1400 1173
1401 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1174 vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component;
1402 1175
1403 VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm); 1176 VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm);
1404 } 1177 }
1405 cpu->Reg[15] += GET_INST_SIZE(cpu); 1178 cpu->Reg[15] += GET_INST_SIZE(cpu);
1406 INC_PC(sizeof(vfpinstr_inst)); 1179 INC_PC(sizeof(vmovi_inst));
1407 FETCH_INST; 1180 FETCH_INST;
1408 GOTO_NEXT_INST; 1181 GOTO_NEXT_INST;
1409} 1182}
1410#endif 1183#endif
1411#ifdef VFP_CDP_TRANS 1184
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 1185#ifdef VFP_DYNCOM_TABLE
1447DYNCOM_FILL_ACTION(vfpinstr), 1186DYNCOM_FILL_ACTION(vmovi),
1448#endif 1187#endif
1449#ifdef VFP_DYNCOM_TAG 1188#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) 1189int DYNCOM_TAG(vmovi)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1451{ 1190{
1452 int instr_size = INSTR_SIZE; 1191 int instr_size = INSTR_SIZE;
1453 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1192 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -1456,7 +1195,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
1456} 1195}
1457#endif 1196#endif
1458#ifdef VFP_DYNCOM_TRANS 1197#ifdef VFP_DYNCOM_TRANS
1459int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1198int 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__); 1199 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1461 //arch_arm_undef(cpu, bb, instr); 1200 //arch_arm_undef(cpu, bb, instr);
1462 int single = (BIT(8) == 0); 1201 int single = (BIT(8) == 0);
@@ -1482,44 +1221,26 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
1482 return No_exp; 1221 return No_exp;
1483} 1222}
1484#endif 1223#endif
1485#undef vfpinstr
1486#undef vfpinstr_inst
1487#undef VFPLABEL_INST
1488 1224
1489/* ----------------------------------------------------------------------- */ 1225/* ----------------------------------------------------------------------- */
1490/* VMOVR move register */ 1226/* VMOVR move register */
1491/* cond 1110 1D11 0000 Vd-- 101X 01M0 Vm-- */ 1227/* cond 1110 1D11 0000 Vd-- 101X 01M0 Vm-- */
1492/* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */ 1228/* 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 1229#ifdef VFP_INTERPRETER_STRUCT
1509typedef struct _vmovr_inst { 1230typedef struct _vmovr_inst {
1510 unsigned int single; 1231 unsigned int single;
1511 unsigned int d; 1232 unsigned int d;
1512 unsigned int m; 1233 unsigned int m;
1513} vfpinstr_inst; 1234} vmovr_inst;
1514#endif 1235#endif
1515#ifdef VFP_INTERPRETER_TRANS 1236#ifdef VFP_INTERPRETER_TRANS
1516ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1237ARM_INST_PTR INTERPRETER_TRANSLATE(vmovr)(unsigned int inst, int index)
1517{ 1238{
1518 VFP_DEBUG_TRANSLATE; 1239 VFP_DEBUG_TRANSLATE;
1519 VFP_DEBUG_UNTESTED(VMOVR); 1240 VFP_DEBUG_UNTESTED(VMOVR);
1520 1241
1521 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1242 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovr_inst));
1522 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1243 vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component;
1523 1244
1524 inst_base->cond = BITS(inst, 28, 31); 1245 inst_base->cond = BITS(inst, 28, 31);
1525 inst_base->idx = index; 1246 inst_base->idx = index;
@@ -1533,56 +1254,28 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
1533} 1254}
1534#endif 1255#endif
1535#ifdef VFP_INTERPRETER_IMPL 1256#ifdef VFP_INTERPRETER_IMPL
1536VFPLABEL_INST: 1257VMOVR_INST:
1537{ 1258{
1538 INC_ICOUNTER; 1259 INC_ICOUNTER;
1539 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1260 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1540 CHECK_VFP_ENABLED; 1261 CHECK_VFP_ENABLED;
1541 1262
1542 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1263 vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component;
1543 1264
1544 VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m); 1265 VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m);
1545 } 1266 }
1546 cpu->Reg[15] += GET_INST_SIZE(cpu); 1267 cpu->Reg[15] += GET_INST_SIZE(cpu);
1547 INC_PC(sizeof(vfpinstr_inst)); 1268 INC_PC(sizeof(vmovr_inst));
1548 FETCH_INST; 1269 FETCH_INST;
1549 GOTO_NEXT_INST; 1270 GOTO_NEXT_INST;
1550} 1271}
1551#endif 1272#endif
1552#ifdef VFP_CDP_TRANS 1273
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 1274#ifdef VFP_DYNCOM_TABLE
1582DYNCOM_FILL_ACTION(vfpinstr), 1275DYNCOM_FILL_ACTION(vmovr),
1583#endif 1276#endif
1584#ifdef VFP_DYNCOM_TAG 1277#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) 1278int DYNCOM_TAG(vmovr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1586{ 1279{
1587 int instr_size = INSTR_SIZE; 1280 int instr_size = INSTR_SIZE;
1588 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 1281 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
@@ -1594,7 +1287,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
1594} 1287}
1595#endif 1288#endif
1596#ifdef VFP_DYNCOM_TRANS 1289#ifdef VFP_DYNCOM_TRANS
1597int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1290int DYNCOM_TRANS(vmovr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1598 DBG("\t\tin %s VMOV \n", __FUNCTION__); 1291 DBG("\t\tin %s VMOV \n", __FUNCTION__);
1599 int single = BIT(8) == 0; 1292 int single = BIT(8) == 0;
1600 int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15)); 1293 int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15));
@@ -1613,41 +1306,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
1613 return No_exp; 1306 return No_exp;
1614} 1307}
1615#endif 1308#endif
1616#undef vfpinstr
1617#undef vfpinstr_inst
1618#undef VFPLABEL_INST
1619 1309
1620/* ----------------------------------------------------------------------- */ 1310/* ----------------------------------------------------------------------- */
1621/* VABS */ 1311/* VABS */
1622/* cond 1110 1D11 0000 Vd-- 101X 11M0 Vm-- */ 1312/* 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 1313#ifdef VFP_INTERPRETER_STRUCT
1639typedef struct _vabs_inst { 1314typedef struct _vabs_inst {
1640 unsigned int instr; 1315 unsigned int instr;
1641 unsigned int dp_operation; 1316 unsigned int dp_operation;
1642} vfpinstr_inst; 1317} vabs_inst;
1643#endif 1318#endif
1644#ifdef VFP_INTERPRETER_TRANS 1319#ifdef VFP_INTERPRETER_TRANS
1645ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1320ARM_INST_PTR INTERPRETER_TRANSLATE(vabs)(unsigned int inst, int index)
1646{ 1321{
1647 VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VABS); 1322 VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VABS);
1648 1323
1649 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1324 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vabs_inst));
1650 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1325 vabs_inst *inst_cream = (vabs_inst *)inst_base->component;
1651 1326
1652 inst_base->cond = BITS(inst, 28, 31); 1327 inst_base->cond = BITS(inst, 28, 31);
1653 inst_base->idx = index; 1328 inst_base->idx = index;
@@ -1661,7 +1336,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
1661} 1336}
1662#endif 1337#endif
1663#ifdef VFP_INTERPRETER_IMPL 1338#ifdef VFP_INTERPRETER_IMPL
1664VFPLABEL_INST: 1339VABS_INST:
1665{ 1340{
1666 INC_ICOUNTER; 1341 INC_ICOUNTER;
1667 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1342 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -1669,7 +1344,7 @@ VFPLABEL_INST:
1669 1344
1670 DBG("VABS :\n"); 1345 DBG("VABS :\n");
1671 1346
1672 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1347 vabs_inst *inst_cream = (vabs_inst *)inst_base->component;
1673 1348
1674 int ret; 1349 int ret;
1675 1350
@@ -1681,22 +1356,17 @@ VFPLABEL_INST:
1681 CHECK_VFP_CDP_RET; 1356 CHECK_VFP_CDP_RET;
1682 } 1357 }
1683 cpu->Reg[15] += GET_INST_SIZE(cpu); 1358 cpu->Reg[15] += GET_INST_SIZE(cpu);
1684 INC_PC(sizeof(vfpinstr_inst)); 1359 INC_PC(sizeof(vabs_inst));
1685 FETCH_INST; 1360 FETCH_INST;
1686 GOTO_NEXT_INST; 1361 GOTO_NEXT_INST;
1687} 1362}
1688#endif 1363#endif
1689#ifdef VFP_CDP_TRANS 1364
1690if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x7) == 6)
1691{
1692 DBG("VABS :\n");
1693}
1694#endif
1695#ifdef VFP_DYNCOM_TABLE 1365#ifdef VFP_DYNCOM_TABLE
1696DYNCOM_FILL_ACTION(vfpinstr), 1366DYNCOM_FILL_ACTION(vabs),
1697#endif 1367#endif
1698#ifdef VFP_DYNCOM_TAG 1368#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) 1369int DYNCOM_TAG(vabs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1700{ 1370{
1701 int instr_size = INSTR_SIZE; 1371 int instr_size = INSTR_SIZE;
1702 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1372 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -1706,7 +1376,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
1706} 1376}
1707#endif 1377#endif
1708#ifdef VFP_DYNCOM_TRANS 1378#ifdef VFP_DYNCOM_TRANS
1709int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1379int 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__); 1380 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1711 //arch_arm_undef(cpu, bb, instr); 1381 //arch_arm_undef(cpu, bb, instr);
1712 int single = BIT(8) == 0; 1382 int single = BIT(8) == 0;
@@ -1744,42 +1414,24 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
1744 return No_exp; 1414 return No_exp;
1745} 1415}
1746#endif 1416#endif
1747#undef vfpinstr
1748#undef vfpinstr_inst
1749#undef VFPLABEL_INST
1750 1417
1751/* ----------------------------------------------------------------------- */ 1418/* ----------------------------------------------------------------------- */
1752/* VNEG */ 1419/* VNEG */
1753/* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */ 1420/* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */
1754#define vfpinstr vneg 1421
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 1422#ifdef VFP_INTERPRETER_STRUCT
1771typedef struct _vneg_inst { 1423typedef struct _vneg_inst {
1772 unsigned int instr; 1424 unsigned int instr;
1773 unsigned int dp_operation; 1425 unsigned int dp_operation;
1774} vfpinstr_inst; 1426} vneg_inst;
1775#endif 1427#endif
1776#ifdef VFP_INTERPRETER_TRANS 1428#ifdef VFP_INTERPRETER_TRANS
1777ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1429ARM_INST_PTR INTERPRETER_TRANSLATE(vneg)(unsigned int inst, int index)
1778{ 1430{
1779 VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VNEG); 1431 VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VNEG);
1780 1432
1781 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1433 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vneg_inst));
1782 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1434 vneg_inst *inst_cream = (vneg_inst *)inst_base->component;
1783 1435
1784 inst_base->cond = BITS(inst, 28, 31); 1436 inst_base->cond = BITS(inst, 28, 31);
1785 inst_base->idx = index; 1437 inst_base->idx = index;
@@ -1793,7 +1445,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
1793} 1445}
1794#endif 1446#endif
1795#ifdef VFP_INTERPRETER_IMPL 1447#ifdef VFP_INTERPRETER_IMPL
1796VFPLABEL_INST: 1448VNEG_INST:
1797{ 1449{
1798 INC_ICOUNTER; 1450 INC_ICOUNTER;
1799 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1451 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -1801,7 +1453,7 @@ VFPLABEL_INST:
1801 1453
1802 DBG("VNEG :\n"); 1454 DBG("VNEG :\n");
1803 1455
1804 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1456 vneg_inst *inst_cream = (vneg_inst *)inst_base->component;
1805 1457
1806 int ret; 1458 int ret;
1807 1459
@@ -1813,22 +1465,17 @@ VFPLABEL_INST:
1813 CHECK_VFP_CDP_RET; 1465 CHECK_VFP_CDP_RET;
1814 } 1466 }
1815 cpu->Reg[15] += GET_INST_SIZE(cpu); 1467 cpu->Reg[15] += GET_INST_SIZE(cpu);
1816 INC_PC(sizeof(vfpinstr_inst)); 1468 INC_PC(sizeof(vneg_inst));
1817 FETCH_INST; 1469 FETCH_INST;
1818 GOTO_NEXT_INST; 1470 GOTO_NEXT_INST;
1819} 1471}
1820#endif 1472#endif
1821#ifdef VFP_CDP_TRANS 1473
1822if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 2)
1823{
1824 DBG("VNEG :\n");
1825}
1826#endif
1827#ifdef VFP_DYNCOM_TABLE 1474#ifdef VFP_DYNCOM_TABLE
1828DYNCOM_FILL_ACTION(vfpinstr), 1475DYNCOM_FILL_ACTION(vneg),
1829#endif 1476#endif
1830#ifdef VFP_DYNCOM_TAG 1477#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) 1478int DYNCOM_TAG(vneg)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1832{ 1479{
1833 int instr_size = INSTR_SIZE; 1480 int instr_size = INSTR_SIZE;
1834 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1481 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -1838,7 +1485,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
1838} 1485}
1839#endif 1486#endif
1840#ifdef VFP_DYNCOM_TRANS 1487#ifdef VFP_DYNCOM_TRANS
1841int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1488int 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__); 1489 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1843 //arch_arm_undef(cpu, bb, instr); 1490 //arch_arm_undef(cpu, bb, instr);
1844 int single = BIT(8) == 0; 1491 int single = BIT(8) == 0;
@@ -1876,41 +1523,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
1876 return No_exp; 1523 return No_exp;
1877} 1524}
1878#endif 1525#endif
1879#undef vfpinstr
1880#undef vfpinstr_inst
1881#undef VFPLABEL_INST
1882 1526
1883/* ----------------------------------------------------------------------- */ 1527/* ----------------------------------------------------------------------- */
1884/* VSQRT */ 1528/* VSQRT */
1885/* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */ 1529/* 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 1530#ifdef VFP_INTERPRETER_STRUCT
1902typedef struct _vsqrt_inst { 1531typedef struct _vsqrt_inst {
1903 unsigned int instr; 1532 unsigned int instr;
1904 unsigned int dp_operation; 1533 unsigned int dp_operation;
1905} vfpinstr_inst; 1534} vsqrt_inst;
1906#endif 1535#endif
1907#ifdef VFP_INTERPRETER_TRANS 1536#ifdef VFP_INTERPRETER_TRANS
1908ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1537ARM_INST_PTR INTERPRETER_TRANSLATE(vsqrt)(unsigned int inst, int index)
1909{ 1538{
1910 VFP_DEBUG_TRANSLATE; 1539 VFP_DEBUG_TRANSLATE;
1911 1540
1912 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1541 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsqrt_inst));
1913 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1542 vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component;
1914 1543
1915 inst_base->cond = BITS(inst, 28, 31); 1544 inst_base->cond = BITS(inst, 28, 31);
1916 inst_base->idx = index; 1545 inst_base->idx = index;
@@ -1924,7 +1553,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
1924} 1553}
1925#endif 1554#endif
1926#ifdef VFP_INTERPRETER_IMPL 1555#ifdef VFP_INTERPRETER_IMPL
1927VFPLABEL_INST: 1556VSQRT_INST:
1928{ 1557{
1929 INC_ICOUNTER; 1558 INC_ICOUNTER;
1930 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1559 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -1932,7 +1561,7 @@ VFPLABEL_INST:
1932 1561
1933 DBG("VSQRT :\n"); 1562 DBG("VSQRT :\n");
1934 1563
1935 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1564 vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component;
1936 1565
1937 int ret; 1566 int ret;
1938 1567
@@ -1944,22 +1573,17 @@ VFPLABEL_INST:
1944 CHECK_VFP_CDP_RET; 1573 CHECK_VFP_CDP_RET;
1945 } 1574 }
1946 cpu->Reg[15] += GET_INST_SIZE(cpu); 1575 cpu->Reg[15] += GET_INST_SIZE(cpu);
1947 INC_PC(sizeof(vfpinstr_inst)); 1576 INC_PC(sizeof(vsqrt_inst));
1948 FETCH_INST; 1577 FETCH_INST;
1949 GOTO_NEXT_INST; 1578 GOTO_NEXT_INST;
1950} 1579}
1951#endif 1580#endif
1952#ifdef VFP_CDP_TRANS 1581
1953if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 6)
1954{
1955 DBG("VSQRT :\n");
1956}
1957#endif
1958#ifdef VFP_DYNCOM_TABLE 1582#ifdef VFP_DYNCOM_TABLE
1959DYNCOM_FILL_ACTION(vfpinstr), 1583DYNCOM_FILL_ACTION(vsqrt),
1960#endif 1584#endif
1961#ifdef VFP_DYNCOM_TAG 1585#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) 1586int DYNCOM_TAG(vsqrt)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1963{ 1587{
1964 int instr_size = INSTR_SIZE; 1588 int instr_size = INSTR_SIZE;
1965 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1589 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -1969,7 +1593,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
1969} 1593}
1970#endif 1594#endif
1971#ifdef VFP_DYNCOM_TRANS 1595#ifdef VFP_DYNCOM_TRANS
1972int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1596int 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__); 1597 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1974 //arch_arm_undef(cpu, bb, instr); 1598 //arch_arm_undef(cpu, bb, instr);
1975 int dp_op = (BIT(8) == 1); 1599 int dp_op = (BIT(8) == 1);
@@ -1995,41 +1619,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
1995 return No_exp; 1619 return No_exp;
1996} 1620}
1997#endif 1621#endif
1998#undef vfpinstr
1999#undef vfpinstr_inst
2000#undef VFPLABEL_INST
2001 1622
2002/* ----------------------------------------------------------------------- */ 1623/* ----------------------------------------------------------------------- */
2003/* VCMP VCMPE */ 1624/* VCMP VCMPE */
2004/* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 1 */ 1625/* 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 1626#ifdef VFP_INTERPRETER_STRUCT
2021typedef struct _vcmp_inst { 1627typedef struct _vcmp_inst {
2022 unsigned int instr; 1628 unsigned int instr;
2023 unsigned int dp_operation; 1629 unsigned int dp_operation;
2024} vfpinstr_inst; 1630} vcmp_inst;
2025#endif 1631#endif
2026#ifdef VFP_INTERPRETER_TRANS 1632#ifdef VFP_INTERPRETER_TRANS
2027ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1633ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp)(unsigned int inst, int index)
2028{ 1634{
2029 VFP_DEBUG_TRANSLATE; 1635 VFP_DEBUG_TRANSLATE;
2030 1636
2031 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1637 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp_inst));
2032 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1638 vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component;
2033 1639
2034 inst_base->cond = BITS(inst, 28, 31); 1640 inst_base->cond = BITS(inst, 28, 31);
2035 inst_base->idx = index; 1641 inst_base->idx = index;
@@ -2043,7 +1649,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
2043} 1649}
2044#endif 1650#endif
2045#ifdef VFP_INTERPRETER_IMPL 1651#ifdef VFP_INTERPRETER_IMPL
2046VFPLABEL_INST: 1652VCMP_INST:
2047{ 1653{
2048 INC_ICOUNTER; 1654 INC_ICOUNTER;
2049 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1655 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -2051,7 +1657,7 @@ VFPLABEL_INST:
2051 1657
2052 DBG("VCMP(1) :\n"); 1658 DBG("VCMP(1) :\n");
2053 1659
2054 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1660 vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component;
2055 1661
2056 int ret; 1662 int ret;
2057 1663
@@ -2063,22 +1669,17 @@ VFPLABEL_INST:
2063 CHECK_VFP_CDP_RET; 1669 CHECK_VFP_CDP_RET;
2064 } 1670 }
2065 cpu->Reg[15] += GET_INST_SIZE(cpu); 1671 cpu->Reg[15] += GET_INST_SIZE(cpu);
2066 INC_PC(sizeof(vfpinstr_inst)); 1672 INC_PC(sizeof(vcmp_inst));
2067 FETCH_INST; 1673 FETCH_INST;
2068 GOTO_NEXT_INST; 1674 GOTO_NEXT_INST;
2069} 1675}
2070#endif 1676#endif
2071#ifdef VFP_CDP_TRANS 1677
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 1678#ifdef VFP_DYNCOM_TABLE
2078DYNCOM_FILL_ACTION(vfpinstr), 1679DYNCOM_FILL_ACTION(vcmp),
2079#endif 1680#endif
2080#ifdef VFP_DYNCOM_TAG 1681#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) 1682int DYNCOM_TAG(vcmp)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2082{ 1683{
2083 int instr_size = INSTR_SIZE; 1684 int instr_size = INSTR_SIZE;
2084 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 1685 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
@@ -2087,7 +1688,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
2087} 1688}
2088#endif 1689#endif
2089#ifdef VFP_DYNCOM_TRANS 1690#ifdef VFP_DYNCOM_TRANS
2090int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1691int 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__); 1692 DBG("\t\tin %s instruction is executed out of JIT.\n", __FUNCTION__);
2092 //arch_arm_undef(cpu, bb, instr); 1693 //arch_arm_undef(cpu, bb, instr);
2093 int dp_op = (BIT(8) == 1); 1694 int dp_op = (BIT(8) == 1);
@@ -2141,41 +1742,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
2141 return No_exp; 1742 return No_exp;
2142} 1743}
2143#endif 1744#endif
2144#undef vfpinstr
2145#undef vfpinstr_inst
2146#undef VFPLABEL_INST
2147 1745
2148/* ----------------------------------------------------------------------- */ 1746/* ----------------------------------------------------------------------- */
2149/* VCMP VCMPE */ 1747/* VCMP VCMPE */
2150/* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 2 */ 1748/* 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 1749#ifdef VFP_INTERPRETER_STRUCT
2167typedef struct _vcmp2_inst { 1750typedef struct _vcmp2_inst {
2168 unsigned int instr; 1751 unsigned int instr;
2169 unsigned int dp_operation; 1752 unsigned int dp_operation;
2170} vfpinstr_inst; 1753} vcmp2_inst;
2171#endif 1754#endif
2172#ifdef VFP_INTERPRETER_TRANS 1755#ifdef VFP_INTERPRETER_TRANS
2173ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1756ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp2)(unsigned int inst, int index)
2174{ 1757{
2175 VFP_DEBUG_TRANSLATE; 1758 VFP_DEBUG_TRANSLATE;
2176 1759
2177 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1760 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp2_inst));
2178 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1761 vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component;
2179 1762
2180 inst_base->cond = BITS(inst, 28, 31); 1763 inst_base->cond = BITS(inst, 28, 31);
2181 inst_base->idx = index; 1764 inst_base->idx = index;
@@ -2189,7 +1772,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
2189} 1772}
2190#endif 1773#endif
2191#ifdef VFP_INTERPRETER_IMPL 1774#ifdef VFP_INTERPRETER_IMPL
2192VFPLABEL_INST: 1775VCMP2_INST:
2193{ 1776{
2194 INC_ICOUNTER; 1777 INC_ICOUNTER;
2195 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1778 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -2197,7 +1780,7 @@ VFPLABEL_INST:
2197 1780
2198 DBG("VCMP(2) :\n"); 1781 DBG("VCMP(2) :\n");
2199 1782
2200 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1783 vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component;
2201 1784
2202 int ret; 1785 int ret;
2203 1786
@@ -2209,22 +1792,17 @@ VFPLABEL_INST:
2209 CHECK_VFP_CDP_RET; 1792 CHECK_VFP_CDP_RET;
2210 } 1793 }
2211 cpu->Reg[15] += GET_INST_SIZE(cpu); 1794 cpu->Reg[15] += GET_INST_SIZE(cpu);
2212 INC_PC(sizeof(vfpinstr_inst)); 1795 INC_PC(sizeof(vcmp2_inst));
2213 FETCH_INST; 1796 FETCH_INST;
2214 GOTO_NEXT_INST; 1797 GOTO_NEXT_INST;
2215} 1798}
2216#endif 1799#endif
2217#ifdef VFP_CDP_TRANS 1800
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 1801#ifdef VFP_DYNCOM_TABLE
2224DYNCOM_FILL_ACTION(vfpinstr), 1802DYNCOM_FILL_ACTION(vcmp2),
2225#endif 1803#endif
2226#ifdef VFP_DYNCOM_TAG 1804#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) 1805int DYNCOM_TAG(vcmp2)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2228{ 1806{
2229 int instr_size = INSTR_SIZE; 1807 int instr_size = INSTR_SIZE;
2230 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 1808 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
@@ -2233,7 +1811,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
2233} 1811}
2234#endif 1812#endif
2235#ifdef VFP_DYNCOM_TRANS 1813#ifdef VFP_DYNCOM_TRANS
2236int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1814int 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__); 1815 DBG("\t\tin %s instruction will executed out of JIT.\n", __FUNCTION__);
2238 //arch_arm_undef(cpu, bb, instr); 1816 //arch_arm_undef(cpu, bb, instr);
2239 int dp_op = (BIT(8) == 1); 1817 int dp_op = (BIT(8) == 1);
@@ -2287,41 +1865,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
2287 return No_exp; 1865 return No_exp;
2288} 1866}
2289#endif 1867#endif
2290#undef vfpinstr
2291#undef vfpinstr_inst
2292#undef VFPLABEL_INST
2293 1868
2294/* ----------------------------------------------------------------------- */ 1869/* ----------------------------------------------------------------------- */
2295/* VCVTBDS between double and single */ 1870/* VCVTBDS between double and single */
2296/* cond 1110 1D11 0111 Vd-- 101X 11M0 Vm-- */ 1871/* 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 1872#ifdef VFP_INTERPRETER_STRUCT
2313typedef struct _vcvtbds_inst { 1873typedef struct _vcvtbds_inst {
2314 unsigned int instr; 1874 unsigned int instr;
2315 unsigned int dp_operation; 1875 unsigned int dp_operation;
2316} vfpinstr_inst; 1876} vcvtbds_inst;
2317#endif 1877#endif
2318#ifdef VFP_INTERPRETER_TRANS 1878#ifdef VFP_INTERPRETER_TRANS
2319ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1879ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbds)(unsigned int inst, int index)
2320{ 1880{
2321 VFP_DEBUG_TRANSLATE; 1881 VFP_DEBUG_TRANSLATE;
2322 1882
2323 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1883 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbds_inst));
2324 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1884 vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component;
2325 1885
2326 inst_base->cond = BITS(inst, 28, 31); 1886 inst_base->cond = BITS(inst, 28, 31);
2327 inst_base->idx = index; 1887 inst_base->idx = index;
@@ -2335,7 +1895,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
2335} 1895}
2336#endif 1896#endif
2337#ifdef VFP_INTERPRETER_IMPL 1897#ifdef VFP_INTERPRETER_IMPL
2338VFPLABEL_INST: 1898VCVTBDS_INST:
2339{ 1899{
2340 INC_ICOUNTER; 1900 INC_ICOUNTER;
2341 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1901 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -2343,7 +1903,7 @@ VFPLABEL_INST:
2343 1903
2344 DBG("VCVT(BDS) :\n"); 1904 DBG("VCVT(BDS) :\n");
2345 1905
2346 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1906 vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component;
2347 1907
2348 int ret; 1908 int ret;
2349 1909
@@ -2355,22 +1915,17 @@ VFPLABEL_INST:
2355 CHECK_VFP_CDP_RET; 1915 CHECK_VFP_CDP_RET;
2356 } 1916 }
2357 cpu->Reg[15] += GET_INST_SIZE(cpu); 1917 cpu->Reg[15] += GET_INST_SIZE(cpu);
2358 INC_PC(sizeof(vfpinstr_inst)); 1918 INC_PC(sizeof(vcvtbds_inst));
2359 FETCH_INST; 1919 FETCH_INST;
2360 GOTO_NEXT_INST; 1920 GOTO_NEXT_INST;
2361} 1921}
2362#endif 1922#endif
2363#ifdef VFP_CDP_TRANS 1923
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 1924#ifdef VFP_DYNCOM_TABLE
2370DYNCOM_FILL_ACTION(vfpinstr), 1925DYNCOM_FILL_ACTION(vcvtbds),
2371#endif 1926#endif
2372#ifdef VFP_DYNCOM_TAG 1927#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) 1928int DYNCOM_TAG(vcvtbds)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2374{ 1929{
2375 int instr_size = INSTR_SIZE; 1930 int instr_size = INSTR_SIZE;
2376 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 1931 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
@@ -2379,7 +1934,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
2379} 1934}
2380#endif 1935#endif
2381#ifdef VFP_DYNCOM_TRANS 1936#ifdef VFP_DYNCOM_TRANS
2382int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1937int 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__); 1938 DBG("\t\tin %s instruction is executed out.\n", __FUNCTION__);
2384 //arch_arm_undef(cpu, bb, instr); 1939 //arch_arm_undef(cpu, bb, instr);
2385 int dp_op = (BIT(8) == 1); 1940 int dp_op = (BIT(8) == 1);
@@ -2407,41 +1962,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
2407 return No_exp; 1962 return No_exp;
2408} 1963}
2409#endif 1964#endif
2410#undef vfpinstr
2411#undef vfpinstr_inst
2412#undef VFPLABEL_INST
2413 1965
2414/* ----------------------------------------------------------------------- */ 1966/* ----------------------------------------------------------------------- */
2415/* VCVTBFF between floating point and fixed point */ 1967/* VCVTBFF between floating point and fixed point */
2416/* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */ 1968/* 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 1969#ifdef VFP_INTERPRETER_STRUCT
2433typedef struct _vcvtbff_inst { 1970typedef struct _vcvtbff_inst {
2434 unsigned int instr; 1971 unsigned int instr;
2435 unsigned int dp_operation; 1972 unsigned int dp_operation;
2436} vfpinstr_inst; 1973} vcvtbff_inst;
2437#endif 1974#endif
2438#ifdef VFP_INTERPRETER_TRANS 1975#ifdef VFP_INTERPRETER_TRANS
2439ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 1976ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbff)(unsigned int inst, int index)
2440{ 1977{
2441 VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VCVTBFF); 1978 VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VCVTBFF);
2442 1979
2443 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 1980 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbff_inst));
2444 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 1981 vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component;
2445 1982
2446 inst_base->cond = BITS(inst, 28, 31); 1983 inst_base->cond = BITS(inst, 28, 31);
2447 inst_base->idx = index; 1984 inst_base->idx = index;
@@ -2455,7 +1992,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
2455} 1992}
2456#endif 1993#endif
2457#ifdef VFP_INTERPRETER_IMPL 1994#ifdef VFP_INTERPRETER_IMPL
2458VFPLABEL_INST: 1995VCVTBFF_INST:
2459{ 1996{
2460 INC_ICOUNTER; 1997 INC_ICOUNTER;
2461 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1998 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -2463,7 +2000,7 @@ VFPLABEL_INST:
2463 2000
2464 DBG("VCVT(BFF) :\n"); 2001 DBG("VCVT(BFF) :\n");
2465 2002
2466 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2003 vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component;
2467 2004
2468 int ret; 2005 int ret;
2469 2006
@@ -2475,22 +2012,17 @@ VFPLABEL_INST:
2475 CHECK_VFP_CDP_RET; 2012 CHECK_VFP_CDP_RET;
2476 } 2013 }
2477 cpu->Reg[15] += GET_INST_SIZE(cpu); 2014 cpu->Reg[15] += GET_INST_SIZE(cpu);
2478 INC_PC(sizeof(vfpinstr_inst)); 2015 INC_PC(sizeof(vcvtbff_inst));
2479 FETCH_INST; 2016 FETCH_INST;
2480 GOTO_NEXT_INST; 2017 GOTO_NEXT_INST;
2481} 2018}
2482#endif 2019#endif
2483#ifdef VFP_CDP_TRANS 2020
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 2021#ifdef VFP_DYNCOM_TABLE
2490DYNCOM_FILL_ACTION(vfpinstr), 2022DYNCOM_FILL_ACTION(vcvtbff),
2491#endif 2023#endif
2492#ifdef VFP_DYNCOM_TAG 2024#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) 2025int DYNCOM_TAG(vcvtbff)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2494{ 2026{
2495 int instr_size = INSTR_SIZE; 2027 int instr_size = INSTR_SIZE;
2496 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2028 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -2499,47 +2031,29 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
2499} 2031}
2500#endif 2032#endif
2501#ifdef VFP_DYNCOM_TRANS 2033#ifdef VFP_DYNCOM_TRANS
2502int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2034int 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__); 2035 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2504 arch_arm_undef(cpu, bb, instr); 2036 arch_arm_undef(cpu, bb, instr);
2505 return No_exp; 2037 return No_exp;
2506} 2038}
2507#endif 2039#endif
2508#undef vfpinstr
2509#undef vfpinstr_inst
2510#undef VFPLABEL_INST
2511 2040
2512/* ----------------------------------------------------------------------- */ 2041/* ----------------------------------------------------------------------- */
2513/* VCVTBFI between floating point and integer */ 2042/* VCVTBFI between floating point and integer */
2514/* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */ 2043/* 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 2044#ifdef VFP_INTERPRETER_STRUCT
2531typedef struct _vcvtbfi_inst { 2045typedef struct _vcvtbfi_inst {
2532 unsigned int instr; 2046 unsigned int instr;
2533 unsigned int dp_operation; 2047 unsigned int dp_operation;
2534} vfpinstr_inst; 2048} vcvtbfi_inst;
2535#endif 2049#endif
2536#ifdef VFP_INTERPRETER_TRANS 2050#ifdef VFP_INTERPRETER_TRANS
2537ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2051ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbfi)(unsigned int inst, int index)
2538{ 2052{
2539 VFP_DEBUG_TRANSLATE; 2053 VFP_DEBUG_TRANSLATE;
2540 2054
2541 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2055 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbfi_inst));
2542 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2056 vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component;
2543 2057
2544 inst_base->cond = BITS(inst, 28, 31); 2058 inst_base->cond = BITS(inst, 28, 31);
2545 inst_base->idx = index; 2059 inst_base->idx = index;
@@ -2554,7 +2068,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
2554} 2068}
2555#endif 2069#endif
2556#ifdef VFP_INTERPRETER_IMPL 2070#ifdef VFP_INTERPRETER_IMPL
2557VFPLABEL_INST: 2071VCVTBFI_INST:
2558{ 2072{
2559 INC_ICOUNTER; 2073 INC_ICOUNTER;
2560 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2074 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -2562,7 +2076,7 @@ VFPLABEL_INST:
2562 2076
2563 DBG("VCVT(BFI) :\n"); 2077 DBG("VCVT(BFI) :\n");
2564 2078
2565 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2079 vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component;
2566 2080
2567 int ret; 2081 int ret;
2568 2082
@@ -2574,22 +2088,17 @@ VFPLABEL_INST:
2574 CHECK_VFP_CDP_RET; 2088 CHECK_VFP_CDP_RET;
2575 } 2089 }
2576 cpu->Reg[15] += GET_INST_SIZE(cpu); 2090 cpu->Reg[15] += GET_INST_SIZE(cpu);
2577 INC_PC(sizeof(vfpinstr_inst)); 2091 INC_PC(sizeof(vcvtbfi_inst));
2578 FETCH_INST; 2092 FETCH_INST;
2579 GOTO_NEXT_INST; 2093 GOTO_NEXT_INST;
2580} 2094}
2581#endif 2095#endif
2582#ifdef VFP_CDP_TRANS 2096
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 2097#ifdef VFP_DYNCOM_TABLE
2589DYNCOM_FILL_ACTION(vfpinstr), 2098DYNCOM_FILL_ACTION(vcvtbfi),
2590#endif 2099#endif
2591#ifdef VFP_DYNCOM_TAG 2100#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) 2101int DYNCOM_TAG(vcvtbfi)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2593{ 2102{
2594 int instr_size = INSTR_SIZE; 2103 int instr_size = INSTR_SIZE;
2595 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2104 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -2600,7 +2109,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
2600} 2109}
2601#endif 2110#endif
2602#ifdef VFP_DYNCOM_TRANS 2111#ifdef VFP_DYNCOM_TRANS
2603int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2112int 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__); 2113 DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__);
2605 //arch_arm_undef(cpu, bb, instr); 2114 //arch_arm_undef(cpu, bb, instr);
2606 unsigned int opc2 = BITS(16,18); 2115 unsigned int opc2 = BITS(16,18);
@@ -2694,9 +2203,6 @@ int vcvtbfi_instr_impl(arm_core_t* cpu, uint32 instr){
2694 return 0; 2203 return 0;
2695} 2204}
2696#endif 2205#endif
2697#undef vfpinstr
2698#undef vfpinstr_inst
2699#undef VFPLABEL_INST
2700 2206
2701/* ----------------------------------------------------------------------- */ 2207/* ----------------------------------------------------------------------- */
2702/* MRC / MCR instructions */ 2208/* MRC / MCR instructions */
@@ -2707,35 +2213,20 @@ int vcvtbfi_instr_impl(arm_core_t* cpu, uint32 instr){
2707/* VMOVBRS between register and single precision */ 2213/* VMOVBRS between register and single precision */
2708/* cond 1110 000o Vn-- Rt-- 1010 N001 0000 */ 2214/* cond 1110 000o Vn-- Rt-- 1010 N001 0000 */
2709/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */ 2215/* 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 2216#ifdef VFP_INTERPRETER_STRUCT
2726typedef struct _vmovbrs_inst { 2217typedef struct _vmovbrs_inst {
2727 unsigned int to_arm; 2218 unsigned int to_arm;
2728 unsigned int t; 2219 unsigned int t;
2729 unsigned int n; 2220 unsigned int n;
2730} vfpinstr_inst; 2221} vmovbrs_inst;
2731#endif 2222#endif
2732#ifdef VFP_INTERPRETER_TRANS 2223#ifdef VFP_INTERPRETER_TRANS
2733ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2224ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrs)(unsigned int inst, int index)
2734{ 2225{
2735 VFP_DEBUG_TRANSLATE; 2226 VFP_DEBUG_TRANSLATE;
2736 2227
2737 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2228 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrs_inst));
2738 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2229 vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component;
2739 2230
2740 inst_base->cond = BITS(inst, 28, 31); 2231 inst_base->cond = BITS(inst, 28, 31);
2741 inst_base->idx = index; 2232 inst_base->idx = index;
@@ -2750,61 +2241,28 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
2750} 2241}
2751#endif 2242#endif
2752#ifdef VFP_INTERPRETER_IMPL 2243#ifdef VFP_INTERPRETER_IMPL
2753VFPLABEL_INST: 2244VMOVBRS_INST:
2754{ 2245{
2755 INC_ICOUNTER; 2246 INC_ICOUNTER;
2756 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2247 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
2757 CHECK_VFP_ENABLED; 2248 CHECK_VFP_ENABLED;
2758 2249
2759 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2250 vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component;
2760 2251
2761 VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t])); 2252 VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t]));
2762 } 2253 }
2763 cpu->Reg[15] += GET_INST_SIZE(cpu); 2254 cpu->Reg[15] += GET_INST_SIZE(cpu);
2764 INC_PC(sizeof(vfpinstr_inst)); 2255 INC_PC(sizeof(vmovbrs_inst));
2765 FETCH_INST; 2256 FETCH_INST;
2766 GOTO_NEXT_INST; 2257 GOTO_NEXT_INST;
2767} 2258}
2768#endif 2259#endif
2769#ifdef VFP_MRC_TRANS 2260
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 2261#ifdef VFP_DYNCOM_TABLE
2804DYNCOM_FILL_ACTION(vfpinstr), 2262DYNCOM_FILL_ACTION(vmovbrs),
2805#endif 2263#endif
2806#ifdef VFP_DYNCOM_TAG 2264#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) 2265int DYNCOM_TAG(vmovbrs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2808{ 2266{
2809 int instr_size = INSTR_SIZE; 2267 int instr_size = INSTR_SIZE;
2810 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2268 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -2813,7 +2271,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
2813} 2271}
2814#endif 2272#endif
2815#ifdef VFP_DYNCOM_TRANS 2273#ifdef VFP_DYNCOM_TRANS
2816int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2274int DYNCOM_TRANS(vmovbrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2817 DBG("VMOV(BRS) :\n"); 2275 DBG("VMOV(BRS) :\n");
2818 int to_arm = BIT(20) == 1; 2276 int to_arm = BIT(20) == 1;
2819 int t = BITS(12, 15); 2277 int t = BITS(12, 15);
@@ -2832,42 +2290,24 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
2832 return No_exp; 2290 return No_exp;
2833} 2291}
2834#endif 2292#endif
2835#undef vfpinstr
2836#undef vfpinstr_inst
2837#undef VFPLABEL_INST
2838 2293
2839/* ----------------------------------------------------------------------- */ 2294/* ----------------------------------------------------------------------- */
2840/* VMSR */ 2295/* VMSR */
2841/* cond 1110 1110 reg- Rt-- 1010 0001 0000 */ 2296/* cond 1110 1110 reg- Rt-- 1010 0001 0000 */
2842/* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */ 2297/* 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 2298#ifdef VFP_INTERPRETER_STRUCT
2859typedef struct _vmsr_inst { 2299typedef struct _vmsr_inst {
2860 unsigned int reg; 2300 unsigned int reg;
2861 unsigned int Rd; 2301 unsigned int Rd;
2862} vfpinstr_inst; 2302} vmsr_inst;
2863#endif 2303#endif
2864#ifdef VFP_INTERPRETER_TRANS 2304#ifdef VFP_INTERPRETER_TRANS
2865ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2305ARM_INST_PTR INTERPRETER_TRANSLATE(vmsr)(unsigned int inst, int index)
2866{ 2306{
2867 VFP_DEBUG_TRANSLATE; 2307 VFP_DEBUG_TRANSLATE;
2868 2308
2869 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2309 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmsr_inst));
2870 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2310 vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component;
2871 2311
2872 inst_base->cond = BITS(inst, 28, 31); 2312 inst_base->cond = BITS(inst, 28, 31);
2873 inst_base->idx = index; 2313 inst_base->idx = index;
@@ -2881,7 +2321,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
2881} 2321}
2882#endif 2322#endif
2883#ifdef VFP_INTERPRETER_IMPL 2323#ifdef VFP_INTERPRETER_IMPL
2884VFPLABEL_INST: 2324VMSR_INST:
2885{ 2325{
2886 INC_ICOUNTER; 2326 INC_ICOUNTER;
2887 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2327 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -2890,43 +2330,22 @@ VFPLABEL_INST:
2890 /* Exceptions must be checked, according to v7 ref manual */ 2330 /* Exceptions must be checked, according to v7 ref manual */
2891 CHECK_VFP_ENABLED; 2331 CHECK_VFP_ENABLED;
2892 2332
2893 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2333 vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component;
2894 2334
2895 VMSR(cpu, inst_cream->reg, inst_cream->Rd); 2335 VMSR(cpu, inst_cream->reg, inst_cream->Rd);
2896 } 2336 }
2897 cpu->Reg[15] += GET_INST_SIZE(cpu); 2337 cpu->Reg[15] += GET_INST_SIZE(cpu);
2898 INC_PC(sizeof(vfpinstr_inst)); 2338 INC_PC(sizeof(vmsr_inst));
2899 FETCH_INST; 2339 FETCH_INST;
2900 GOTO_NEXT_INST; 2340 GOTO_NEXT_INST;
2901} 2341}
2902#endif 2342#endif
2903#ifdef VFP_MCR_TRANS 2343
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 2344#ifdef VFP_DYNCOM_TABLE
2926DYNCOM_FILL_ACTION(vfpinstr), 2345DYNCOM_FILL_ACTION(vmsr),
2927#endif 2346#endif
2928#ifdef VFP_DYNCOM_TAG 2347#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) 2348int DYNCOM_TAG(vmsr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2930{ 2349{
2931 int instr_size = INSTR_SIZE; 2350 int instr_size = INSTR_SIZE;
2932 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2351 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -2936,7 +2355,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
2936} 2355}
2937#endif 2356#endif
2938#ifdef VFP_DYNCOM_TRANS 2357#ifdef VFP_DYNCOM_TRANS
2939int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2358int 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__); 2359 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2941 //arch_arm_undef(cpu, bb, instr); 2360 //arch_arm_undef(cpu, bb, instr);
2942 DBG("VMSR :"); 2361 DBG("VMSR :");
@@ -2969,44 +2388,26 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
2969 return No_exp; 2388 return No_exp;
2970} 2389}
2971#endif 2390#endif
2972#undef vfpinstr
2973#undef vfpinstr_inst
2974#undef VFPLABEL_INST
2975 2391
2976/* ----------------------------------------------------------------------- */ 2392/* ----------------------------------------------------------------------- */
2977/* VMOVBRC register to scalar */ 2393/* VMOVBRC register to scalar */
2978/* cond 1110 0XX0 Vd-- Rt-- 1011 DXX1 0000 */ 2394/* cond 1110 0XX0 Vd-- Rt-- 1011 DXX1 0000 */
2979/* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */ 2395/* 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 2396#ifdef VFP_INTERPRETER_STRUCT
2996typedef struct _vmovbrc_inst { 2397typedef struct _vmovbrc_inst {
2997 unsigned int esize; 2398 unsigned int esize;
2998 unsigned int index; 2399 unsigned int index;
2999 unsigned int d; 2400 unsigned int d;
3000 unsigned int t; 2401 unsigned int t;
3001} vfpinstr_inst; 2402} vmovbrc_inst;
3002#endif 2403#endif
3003#ifdef VFP_INTERPRETER_TRANS 2404#ifdef VFP_INTERPRETER_TRANS
3004ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2405ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrc)(unsigned int inst, int index)
3005{ 2406{
3006 VFP_DEBUG_TRANSLATE; 2407 VFP_DEBUG_TRANSLATE;
3007 2408
3008 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2409 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrc_inst));
3009 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2410 vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component;
3010 2411
3011 inst_base->cond = BITS(inst, 28, 31); 2412 inst_base->cond = BITS(inst, 28, 31);
3012 inst_base->idx = index; 2413 inst_base->idx = index;
@@ -3023,34 +2424,28 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
3023} 2424}
3024#endif 2425#endif
3025#ifdef VFP_INTERPRETER_IMPL 2426#ifdef VFP_INTERPRETER_IMPL
3026VFPLABEL_INST: 2427VMOVBRC_INST:
3027{ 2428{
3028 INC_ICOUNTER; 2429 INC_ICOUNTER;
3029 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2430 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
3030 CHECK_VFP_ENABLED; 2431 CHECK_VFP_ENABLED;
3031 2432
3032 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2433 vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component;
3033 2434
3034 VFP_DEBUG_UNIMPLEMENTED(VMOVBRC); 2435 VFP_DEBUG_UNIMPLEMENTED(VMOVBRC);
3035 } 2436 }
3036 cpu->Reg[15] += GET_INST_SIZE(cpu); 2437 cpu->Reg[15] += GET_INST_SIZE(cpu);
3037 INC_PC(sizeof(vfpinstr_inst)); 2438 INC_PC(sizeof(vmovbrc_inst));
3038 FETCH_INST; 2439 FETCH_INST;
3039 GOTO_NEXT_INST; 2440 GOTO_NEXT_INST;
3040} 2441}
3041#endif 2442#endif
3042#ifdef VFP_MCR_TRANS 2443
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 2444#ifdef VFP_DYNCOM_TABLE
3050DYNCOM_FILL_ACTION(vfpinstr), 2445DYNCOM_FILL_ACTION(vmovbrc),
3051#endif 2446#endif
3052#ifdef VFP_DYNCOM_TAG 2447#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) 2448int DYNCOM_TAG(vmovbrc)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
3054{ 2449{
3055 int instr_size = INSTR_SIZE; 2450 int instr_size = INSTR_SIZE;
3056 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2451 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -3059,48 +2454,30 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
3059} 2454}
3060#endif 2455#endif
3061#ifdef VFP_DYNCOM_TRANS 2456#ifdef VFP_DYNCOM_TRANS
3062int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2457int 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__); 2458 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
3064 arch_arm_undef(cpu, bb, instr); 2459 arch_arm_undef(cpu, bb, instr);
3065 return No_exp; 2460 return No_exp;
3066} 2461}
3067#endif 2462#endif
3068#undef vfpinstr
3069#undef vfpinstr_inst
3070#undef VFPLABEL_INST
3071 2463
3072/* ----------------------------------------------------------------------- */ 2464/* ----------------------------------------------------------------------- */
3073/* VMRS */ 2465/* VMRS */
3074/* cond 1110 1111 CRn- Rt-- 1010 0001 0000 */ 2466/* cond 1110 1111 CRn- Rt-- 1010 0001 0000 */
3075/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */ 2467/* 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 2468#ifdef VFP_INTERPRETER_STRUCT
3092typedef struct _vmrs_inst { 2469typedef struct _vmrs_inst {
3093 unsigned int reg; 2470 unsigned int reg;
3094 unsigned int Rt; 2471 unsigned int Rt;
3095} vfpinstr_inst; 2472} vmrs_inst;
3096#endif 2473#endif
3097#ifdef VFP_INTERPRETER_TRANS 2474#ifdef VFP_INTERPRETER_TRANS
3098ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2475ARM_INST_PTR INTERPRETER_TRANSLATE(vmrs)(unsigned int inst, int index)
3099{ 2476{
3100 VFP_DEBUG_TRANSLATE; 2477 VFP_DEBUG_TRANSLATE;
3101 2478
3102 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2479 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmrs_inst));
3103 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2480 vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component;
3104 2481
3105 inst_base->cond = BITS(inst, 28, 31); 2482 inst_base->cond = BITS(inst, 28, 31);
3106 inst_base->idx = index; 2483 inst_base->idx = index;
@@ -3109,12 +2486,12 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
3109 2486
3110 inst_cream->reg = BITS(inst, 16, 19); 2487 inst_cream->reg = BITS(inst, 16, 19);
3111 inst_cream->Rt = BITS(inst, 12, 15); 2488 inst_cream->Rt = BITS(inst, 12, 15);
3112 2489
3113 return inst_base; 2490 return inst_base;
3114} 2491}
3115#endif 2492#endif
3116#ifdef VFP_INTERPRETER_IMPL 2493#ifdef VFP_INTERPRETER_IMPL
3117VFPLABEL_INST: 2494VMRS_INST:
3118{ 2495{
3119 INC_ICOUNTER; 2496 INC_ICOUNTER;
3120 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2497 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -3123,7 +2500,7 @@ VFPLABEL_INST:
3123 /* Exceptions must be checked, according to v7 ref manual */ 2500 /* Exceptions must be checked, according to v7 ref manual */
3124 CHECK_VFP_ENABLED; 2501 CHECK_VFP_ENABLED;
3125 2502
3126 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2503 vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component;
3127 2504
3128 DBG("VMRS :"); 2505 DBG("VMRS :");
3129 2506
@@ -3170,67 +2547,17 @@ VFPLABEL_INST:
3170 } 2547 }
3171 } 2548 }
3172 cpu->Reg[15] += GET_INST_SIZE(cpu); 2549 cpu->Reg[15] += GET_INST_SIZE(cpu);
3173 INC_PC(sizeof(vfpinstr_inst)); 2550 INC_PC(sizeof(vmrs_inst));
3174 FETCH_INST; 2551 FETCH_INST;
3175 GOTO_NEXT_INST; 2552 GOTO_NEXT_INST;
3176} 2553}
3177#endif 2554#endif
3178#ifdef VFP_MRC_TRANS 2555
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 2556#ifdef VFP_DYNCOM_TABLE
3230DYNCOM_FILL_ACTION(vfpinstr), 2557DYNCOM_FILL_ACTION(vmrs),
3231#endif 2558#endif
3232#ifdef VFP_DYNCOM_TAG 2559#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) 2560int DYNCOM_TAG(vmrs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
3234{ 2561{
3235 int instr_size = INSTR_SIZE; 2562 int instr_size = INSTR_SIZE;
3236 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2563 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -3241,7 +2568,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
3241} 2568}
3242#endif 2569#endif
3243#ifdef VFP_DYNCOM_TRANS 2570#ifdef VFP_DYNCOM_TRANS
3244int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2571int 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__); 2572 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
3246 //arch_arm_undef(cpu, bb, instr); 2573 //arch_arm_undef(cpu, bb, instr);
3247 2574
@@ -3292,44 +2619,26 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
3292 return No_exp; 2619 return No_exp;
3293} 2620}
3294#endif 2621#endif
3295#undef vfpinstr
3296#undef vfpinstr_inst
3297#undef VFPLABEL_INST
3298 2622
3299/* ----------------------------------------------------------------------- */ 2623/* ----------------------------------------------------------------------- */
3300/* VMOVBCR scalar to register */ 2624/* VMOVBCR scalar to register */
3301/* cond 1110 XXX1 Vd-- Rt-- 1011 NXX1 0000 */ 2625/* cond 1110 XXX1 Vd-- Rt-- 1011 NXX1 0000 */
3302/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MCR */ 2626/* 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 2627#ifdef VFP_INTERPRETER_STRUCT
3319typedef struct _vmovbcr_inst { 2628typedef struct _vmovbcr_inst {
3320 unsigned int esize; 2629 unsigned int esize;
3321 unsigned int index; 2630 unsigned int index;
3322 unsigned int d; 2631 unsigned int d;
3323 unsigned int t; 2632 unsigned int t;
3324} vfpinstr_inst; 2633} vmovbcr_inst;
3325#endif 2634#endif
3326#ifdef VFP_INTERPRETER_TRANS 2635#ifdef VFP_INTERPRETER_TRANS
3327ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2636ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbcr)(unsigned int inst, int index)
3328{ 2637{
3329 VFP_DEBUG_TRANSLATE; 2638 VFP_DEBUG_TRANSLATE;
3330 2639
3331 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2640 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbcr_inst));
3332 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2641 vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component;
3333 2642
3334 inst_base->cond = BITS(inst, 28, 31); 2643 inst_base->cond = BITS(inst, 28, 31);
3335 inst_base->idx = index; 2644 inst_base->idx = index;
@@ -3346,34 +2655,28 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
3346} 2655}
3347#endif 2656#endif
3348#ifdef VFP_INTERPRETER_IMPL 2657#ifdef VFP_INTERPRETER_IMPL
3349VFPLABEL_INST: 2658VMOVBCR_INST:
3350{ 2659{
3351 INC_ICOUNTER; 2660 INC_ICOUNTER;
3352 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2661 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
3353 CHECK_VFP_ENABLED; 2662 CHECK_VFP_ENABLED;
3354 2663
3355 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2664 vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component;
3356 2665
3357 VFP_DEBUG_UNIMPLEMENTED(VMOVBCR); 2666 VFP_DEBUG_UNIMPLEMENTED(VMOVBCR);
3358 } 2667 }
3359 cpu->Reg[15] += GET_INST_SIZE(cpu); 2668 cpu->Reg[15] += GET_INST_SIZE(cpu);
3360 INC_PC(sizeof(vfpinstr_inst)); 2669 INC_PC(sizeof(vmovbcr_inst));
3361 FETCH_INST; 2670 FETCH_INST;
3362 GOTO_NEXT_INST; 2671 GOTO_NEXT_INST;
3363} 2672}
3364#endif 2673#endif
3365#ifdef VFP_MCR_TRANS 2674
3366if (CoProc == 11 && CRm == 0)
3367{
3368 VFP_DEBUG_UNIMPLEMENTED(VMOVBCR);
3369 return ARMul_DONE;
3370}
3371#endif
3372#ifdef VFP_DYNCOM_TABLE 2675#ifdef VFP_DYNCOM_TABLE
3373DYNCOM_FILL_ACTION(vfpinstr), 2676DYNCOM_FILL_ACTION(vmovbcr),
3374#endif 2677#endif
3375#ifdef VFP_DYNCOM_TAG 2678#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) 2679int DYNCOM_TAG(vmovbcr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
3377{ 2680{
3378 int instr_size = INSTR_SIZE; 2681 int instr_size = INSTR_SIZE;
3379 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2682 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -3382,15 +2685,12 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
3382} 2685}
3383#endif 2686#endif
3384#ifdef VFP_DYNCOM_TRANS 2687#ifdef VFP_DYNCOM_TRANS
3385int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2688int 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__); 2689 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
3387 arch_arm_undef(cpu, bb, instr); 2690 arch_arm_undef(cpu, bb, instr);
3388 return No_exp; 2691 return No_exp;
3389} 2692}
3390#endif 2693#endif
3391#undef vfpinstr
3392#undef vfpinstr_inst
3393#undef VFPLABEL_INST
3394 2694
3395/* ----------------------------------------------------------------------- */ 2695/* ----------------------------------------------------------------------- */
3396/* MRRC / MCRR instructions */ 2696/* MRRC / MCRR instructions */
@@ -3401,36 +2701,21 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
3401/* VMOVBRRSS between 2 registers to 2 singles */ 2701/* VMOVBRRSS between 2 registers to 2 singles */
3402/* cond 1100 010X Rt2- Rt-- 1010 00X1 Vm-- */ 2702/* cond 1100 010X Rt2- Rt-- 1010 00X1 Vm-- */
3403/* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */ 2703/* 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 2704#ifdef VFP_INTERPRETER_STRUCT
3420typedef struct _vmovbrrss_inst { 2705typedef struct _vmovbrrss_inst {
3421 unsigned int to_arm; 2706 unsigned int to_arm;
3422 unsigned int t; 2707 unsigned int t;
3423 unsigned int t2; 2708 unsigned int t2;
3424 unsigned int m; 2709 unsigned int m;
3425} vfpinstr_inst; 2710} vmovbrrss_inst;
3426#endif 2711#endif
3427#ifdef VFP_INTERPRETER_TRANS 2712#ifdef VFP_INTERPRETER_TRANS
3428ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2713ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrss)(unsigned int inst, int index)
3429{ 2714{
3430 VFP_DEBUG_TRANSLATE; 2715 VFP_DEBUG_TRANSLATE;
3431 2716
3432 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2717 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrss_inst));
3433 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2718 vmovbrrss_inst *inst_cream = (vmovbrrss_inst *)inst_base->component;
3434 2719
3435 inst_base->cond = BITS(inst, 28, 31); 2720 inst_base->cond = BITS(inst, 28, 31);
3436 inst_base->idx = index; 2721 inst_base->idx = index;
@@ -3446,41 +2731,27 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
3446} 2731}
3447#endif 2732#endif
3448#ifdef VFP_INTERPRETER_IMPL 2733#ifdef VFP_INTERPRETER_IMPL
3449VFPLABEL_INST: 2734VMOVBRRSS_INST:
3450{ 2735{
3451 INC_ICOUNTER; 2736 INC_ICOUNTER;
3452 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2737 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
3453 CHECK_VFP_ENABLED; 2738 CHECK_VFP_ENABLED;
3454 2739
3455 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2740 vmovbrrss_inst *inst_cream = (vmovbrrss_inst *)inst_base->component;
3456 2741
3457 VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS); 2742 VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS);
3458 } 2743 }
3459 cpu->Reg[15] += GET_INST_SIZE(cpu); 2744 cpu->Reg[15] += GET_INST_SIZE(cpu);
3460 INC_PC(sizeof(vfpinstr_inst)); 2745 INC_PC(sizeof(vmovbrrss_inst));
3461 FETCH_INST; 2746 FETCH_INST;
3462 GOTO_NEXT_INST; 2747 GOTO_NEXT_INST;
3463} 2748}
3464#endif 2749#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 2750#ifdef VFP_DYNCOM_TABLE
3480DYNCOM_FILL_ACTION(vfpinstr), 2751DYNCOM_FILL_ACTION(vmovbrrss),
3481#endif 2752#endif
3482#ifdef VFP_DYNCOM_TAG 2753#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) 2754int DYNCOM_TAG(vmovbrrss)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
3484{ 2755{
3485 int instr_size = INSTR_SIZE; 2756 int instr_size = INSTR_SIZE;
3486 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2757 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -3489,50 +2760,32 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
3489} 2760}
3490#endif 2761#endif
3491#ifdef VFP_DYNCOM_TRANS 2762#ifdef VFP_DYNCOM_TRANS
3492int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2763int 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__); 2764 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
3494 arch_arm_undef(cpu, bb, instr); 2765 arch_arm_undef(cpu, bb, instr);
3495 return No_exp; 2766 return No_exp;
3496} 2767}
3497#endif 2768#endif
3498#undef vfpinstr
3499#undef vfpinstr_inst
3500#undef VFPLABEL_INST
3501 2769
3502/* ----------------------------------------------------------------------- */ 2770/* ----------------------------------------------------------------------- */
3503/* VMOVBRRD between 2 registers and 1 double */ 2771/* VMOVBRRD between 2 registers and 1 double */
3504/* cond 1100 010X Rt2- Rt-- 1011 00X1 Vm-- */ 2772/* cond 1100 010X Rt2- Rt-- 1011 00X1 Vm-- */
3505/* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */ 2773/* 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 2774#ifdef VFP_INTERPRETER_STRUCT
3522typedef struct _vmovbrrd_inst { 2775typedef struct _vmovbrrd_inst {
3523 unsigned int to_arm; 2776 unsigned int to_arm;
3524 unsigned int t; 2777 unsigned int t;
3525 unsigned int t2; 2778 unsigned int t2;
3526 unsigned int m; 2779 unsigned int m;
3527} vfpinstr_inst; 2780} vmovbrrd_inst;
3528#endif 2781#endif
3529#ifdef VFP_INTERPRETER_TRANS 2782#ifdef VFP_INTERPRETER_TRANS
3530ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2783ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrd)(unsigned int inst, int index)
3531{ 2784{
3532 VFP_DEBUG_TRANSLATE; 2785 VFP_DEBUG_TRANSLATE;
3533 2786
3534 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2787 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrd_inst));
3535 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2788 vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component;
3536 2789
3537 inst_base->cond = BITS(inst, 28, 31); 2790 inst_base->cond = BITS(inst, 28, 31);
3538 inst_base->idx = index; 2791 inst_base->idx = index;
@@ -3548,63 +2801,29 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
3548} 2801}
3549#endif 2802#endif
3550#ifdef VFP_INTERPRETER_IMPL 2803#ifdef VFP_INTERPRETER_IMPL
3551VFPLABEL_INST: 2804VMOVBRRD_INST:
3552{ 2805{
3553 INC_ICOUNTER; 2806 INC_ICOUNTER;
3554 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2807 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
3555 CHECK_VFP_ENABLED; 2808 CHECK_VFP_ENABLED;
3556 2809
3557 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2810 vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component;
3558 2811
3559 VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, 2812 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])); 2813 &(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2]));
3561 } 2814 }
3562 cpu->Reg[15] += GET_INST_SIZE(cpu); 2815 cpu->Reg[15] += GET_INST_SIZE(cpu);
3563 INC_PC(sizeof(vfpinstr_inst)); 2816 INC_PC(sizeof(vmovbrrd_inst));
3564 FETCH_INST; 2817 FETCH_INST;
3565 GOTO_NEXT_INST; 2818 GOTO_NEXT_INST;
3566} 2819}
3567#endif 2820#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 2821
3602#endif
3603#ifdef VFP_DYNCOM_TABLE 2822#ifdef VFP_DYNCOM_TABLE
3604DYNCOM_FILL_ACTION(vfpinstr), 2823DYNCOM_FILL_ACTION(vmovbrrd),
3605#endif 2824#endif
3606#ifdef VFP_DYNCOM_TAG 2825#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) 2826int DYNCOM_TAG(vmovbrrd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
3608{ 2827{
3609 int instr_size = INSTR_SIZE; 2828 int instr_size = INSTR_SIZE;
3610 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2829 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -3615,7 +2834,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
3615} 2834}
3616#endif 2835#endif
3617#ifdef VFP_DYNCOM_TRANS 2836#ifdef VFP_DYNCOM_TRANS
3618int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2837int 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__); 2838 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
3620 //arch_arm_undef(cpu, bb, instr); 2839 //arch_arm_undef(cpu, bb, instr);
3621 int to_arm = BIT(20) == 1; 2840 int to_arm = BIT(20) == 1;
@@ -3633,9 +2852,6 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
3633 return No_exp; 2852 return No_exp;
3634} 2853}
3635#endif 2854#endif
3636#undef vfpinstr
3637#undef vfpinstr_inst
3638#undef VFPLABEL_INST
3639 2855
3640/* ----------------------------------------------------------------------- */ 2856/* ----------------------------------------------------------------------- */
3641/* LDC/STC between 2 registers and 1 double */ 2857/* LDC/STC between 2 registers and 1 double */
@@ -3645,21 +2861,6 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
3645/* ----------------------------------------------------------------------- */ 2861/* ----------------------------------------------------------------------- */
3646/* VSTR */ 2862/* VSTR */
3647/* cond 1101 UD00 Rn-- Vd-- 101X imm8 imm8 */ 2863/* 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 2864#ifdef VFP_INTERPRETER_STRUCT
3664typedef struct _vstr_inst { 2865typedef struct _vstr_inst {
3665 unsigned int single; 2866 unsigned int single;
@@ -3667,15 +2868,15 @@ typedef struct _vstr_inst {
3667 unsigned int d; 2868 unsigned int d;
3668 unsigned int imm32; 2869 unsigned int imm32;
3669 unsigned int add; 2870 unsigned int add;
3670} vfpinstr_inst; 2871} vstr_inst;
3671#endif 2872#endif
3672#ifdef VFP_INTERPRETER_TRANS 2873#ifdef VFP_INTERPRETER_TRANS
3673ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 2874ARM_INST_PTR INTERPRETER_TRANSLATE(vstr)(unsigned int inst, int index)
3674{ 2875{
3675 VFP_DEBUG_TRANSLATE; 2876 VFP_DEBUG_TRANSLATE;
3676 2877
3677 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 2878 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstr_inst));
3678 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2879 vstr_inst *inst_cream = (vstr_inst *)inst_base->component;
3679 2880
3680 inst_base->cond = BITS(inst, 28, 31); 2881 inst_base->cond = BITS(inst, 28, 31);
3681 inst_base->idx = index; 2882 inst_base->idx = index;
@@ -3692,13 +2893,13 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
3692} 2893}
3693#endif 2894#endif
3694#ifdef VFP_INTERPRETER_IMPL 2895#ifdef VFP_INTERPRETER_IMPL
3695VFPLABEL_INST: 2896VSTR_INST:
3696{ 2897{
3697 INC_ICOUNTER; 2898 INC_ICOUNTER;
3698 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2899 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
3699 CHECK_VFP_ENABLED; 2900 CHECK_VFP_ENABLED;
3700 2901
3701 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 2902 vstr_inst *inst_cream = (vstr_inst *)inst_base->component;
3702 2903
3703 unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]); 2904 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); 2905 addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32);
@@ -3736,65 +2937,12 @@ VFPLABEL_INST:
3736 GOTO_NEXT_INST; 2937 GOTO_NEXT_INST;
3737} 2938}
3738#endif 2939#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 2940
3790 return -1;
3791}
3792#endif
3793#ifdef VFP_DYNCOM_TABLE 2941#ifdef VFP_DYNCOM_TABLE
3794DYNCOM_FILL_ACTION(vfpinstr), 2942DYNCOM_FILL_ACTION(vstr),
3795#endif 2943#endif
3796#ifdef VFP_DYNCOM_TAG 2944#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) 2945int DYNCOM_TAG(vstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
3798{ 2946{
3799 int instr_size = INSTR_SIZE; 2947 int instr_size = INSTR_SIZE;
3800 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 2948 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
@@ -3807,7 +2955,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
3807} 2955}
3808#endif 2956#endif
3809#ifdef VFP_DYNCOM_TRANS 2957#ifdef VFP_DYNCOM_TRANS
3810int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2958int DYNCOM_TRANS(vstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
3811 int single = BIT(8) == 0; 2959 int single = BIT(8) == 0;
3812 int add = BIT(23); 2960 int add = BIT(23);
3813 int imm32 = BITS(0,7) << 2; 2961 int imm32 = BITS(0,7) << 2;
@@ -3853,43 +3001,25 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
3853 return No_exp; 3001 return No_exp;
3854} 3002}
3855#endif 3003#endif
3856#undef vfpinstr
3857#undef vfpinstr_inst
3858#undef VFPLABEL_INST
3859 3004
3860/* ----------------------------------------------------------------------- */ 3005/* ----------------------------------------------------------------------- */
3861/* VPUSH */ 3006/* VPUSH */
3862/* cond 1101 0D10 1101 Vd-- 101X imm8 imm8 */ 3007/* 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 3008#ifdef VFP_INTERPRETER_STRUCT
3879typedef struct _vpush_inst { 3009typedef struct _vpush_inst {
3880 unsigned int single; 3010 unsigned int single;
3881 unsigned int d; 3011 unsigned int d;
3882 unsigned int imm32; 3012 unsigned int imm32;
3883 unsigned int regs; 3013 unsigned int regs;
3884} vfpinstr_inst; 3014} vpush_inst;
3885#endif 3015#endif
3886#ifdef VFP_INTERPRETER_TRANS 3016#ifdef VFP_INTERPRETER_TRANS
3887ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 3017ARM_INST_PTR INTERPRETER_TRANSLATE(vpush)(unsigned int inst, int index)
3888{ 3018{
3889 VFP_DEBUG_TRANSLATE; 3019 VFP_DEBUG_TRANSLATE;
3890 3020
3891 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 3021 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpush_inst));
3892 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3022 vpush_inst *inst_cream = (vpush_inst *)inst_base->component;
3893 3023
3894 inst_base->cond = BITS(inst, 28, 31); 3024 inst_base->cond = BITS(inst, 28, 31);
3895 inst_base->idx = index; 3025 inst_base->idx = index;
@@ -3905,7 +3035,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
3905} 3035}
3906#endif 3036#endif
3907#ifdef VFP_INTERPRETER_IMPL 3037#ifdef VFP_INTERPRETER_IMPL
3908VFPLABEL_INST: 3038VPUSH_INST:
3909{ 3039{
3910 INC_ICOUNTER; 3040 INC_ICOUNTER;
3911 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 3041 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -3913,7 +3043,7 @@ VFPLABEL_INST:
3913 3043
3914 int i; 3044 int i;
3915 3045
3916 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3046 vpush_inst *inst_cream = (vpush_inst *)inst_base->component;
3917 3047
3918 DBG("VPUSH :\n"); 3048 DBG("VPUSH :\n");
3919 3049
@@ -3958,66 +3088,11 @@ VFPLABEL_INST:
3958 GOTO_NEXT_INST; 3088 GOTO_NEXT_INST;
3959} 3089}
3960#endif 3090#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 3091#ifdef VFP_DYNCOM_TABLE
4017DYNCOM_FILL_ACTION(vfpinstr), 3092DYNCOM_FILL_ACTION(vpush),
4018#endif 3093#endif
4019#ifdef VFP_DYNCOM_TAG 3094#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) 3095int DYNCOM_TAG(vpush)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
4021{ 3096{
4022 int instr_size = INSTR_SIZE; 3097 int instr_size = INSTR_SIZE;
4023 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 3098 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
@@ -4030,7 +3105,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
4030} 3105}
4031#endif 3106#endif
4032#ifdef VFP_DYNCOM_TRANS 3107#ifdef VFP_DYNCOM_TRANS
4033int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 3108int DYNCOM_TRANS(vpush)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
4034 int single = BIT(8) == 0; 3109 int single = BIT(8) == 0;
4035 int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4)); 3110 int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4));
4036 int imm32 = BITS(0, 7)<<2; 3111 int imm32 = BITS(0, 7)<<2;
@@ -4087,28 +3162,10 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
4087 return No_exp; 3162 return No_exp;
4088} 3163}
4089#endif 3164#endif
4090#undef vfpinstr
4091#undef vfpinstr_inst
4092#undef VFPLABEL_INST
4093 3165
4094/* ----------------------------------------------------------------------- */ 3166/* ----------------------------------------------------------------------- */
4095/* VSTM */ 3167/* VSTM */
4096/* cond 110P UDW0 Rn-- Vd-- 101X imm8 imm8 */ 3168/* 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 3169#ifdef VFP_INTERPRETER_STRUCT
4113typedef struct _vstm_inst { 3170typedef struct _vstm_inst {
4114 unsigned int single; 3171 unsigned int single;
@@ -4118,15 +3175,15 @@ typedef struct _vstm_inst {
4118 unsigned int n; 3175 unsigned int n;
4119 unsigned int imm32; 3176 unsigned int imm32;
4120 unsigned int regs; 3177 unsigned int regs;
4121} vfpinstr_inst; 3178} vstm_inst;
4122#endif 3179#endif
4123#ifdef VFP_INTERPRETER_TRANS 3180#ifdef VFP_INTERPRETER_TRANS
4124ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 3181ARM_INST_PTR INTERPRETER_TRANSLATE(vstm)(unsigned int inst, int index)
4125{ 3182{
4126 VFP_DEBUG_TRANSLATE; 3183 VFP_DEBUG_TRANSLATE;
4127 3184
4128 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 3185 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstm_inst));
4129 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3186 vstm_inst *inst_cream = (vstm_inst *)inst_base->component;
4130 3187
4131 inst_base->cond = BITS(inst, 28, 31); 3188 inst_base->cond = BITS(inst, 28, 31);
4132 inst_base->idx = index; 3189 inst_base->idx = index;
@@ -4145,7 +3202,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
4145} 3202}
4146#endif 3203#endif
4147#ifdef VFP_INTERPRETER_IMPL 3204#ifdef VFP_INTERPRETER_IMPL
4148VFPLABEL_INST: /* encoding 1 */ 3205VSTM_INST: /* encoding 1 */
4149{ 3206{
4150 INC_ICOUNTER; 3207 INC_ICOUNTER;
4151 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 3208 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -4153,7 +3210,7 @@ VFPLABEL_INST: /* encoding 1 */
4153 3210
4154 int i; 3211 int i;
4155 3212
4156 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3213 vstm_inst *inst_cream = (vstm_inst *)inst_base->component;
4157 3214
4158 addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); 3215 addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32);
4159 DBG("VSTM : addr[%x]\n", addr); 3216 DBG("VSTM : addr[%x]\n", addr);
@@ -4203,69 +3260,12 @@ VFPLABEL_INST: /* encoding 1 */
4203 GOTO_NEXT_INST; 3260 GOTO_NEXT_INST;
4204} 3261}
4205#endif 3262#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 3263
4261 return -1;
4262}
4263#endif
4264#ifdef VFP_DYNCOM_TABLE 3264#ifdef VFP_DYNCOM_TABLE
4265DYNCOM_FILL_ACTION(vfpinstr), 3265DYNCOM_FILL_ACTION(vstm),
4266#endif 3266#endif
4267#ifdef VFP_DYNCOM_TAG 3267#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) 3268int DYNCOM_TAG(vstm)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
4269{ 3269{
4270 int instr_size = INSTR_SIZE; 3270 int instr_size = INSTR_SIZE;
4271 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 3271 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -4280,7 +3280,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
4280} 3280}
4281#endif 3281#endif
4282#ifdef VFP_DYNCOM_TRANS 3282#ifdef VFP_DYNCOM_TRANS
4283int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 3283int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
4284 //arch_arm_undef(cpu, bb, instr); 3284 //arch_arm_undef(cpu, bb, instr);
4285 int single = BIT(8) == 0; 3285 int single = BIT(8) == 0;
4286 int add = BIT(23); 3286 int add = BIT(23);
@@ -4356,43 +3356,25 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
4356 return No_exp; 3356 return No_exp;
4357} 3357}
4358#endif 3358#endif
4359#undef vfpinstr
4360#undef vfpinstr_inst
4361#undef VFPLABEL_INST
4362 3359
4363/* ----------------------------------------------------------------------- */ 3360/* ----------------------------------------------------------------------- */
4364/* VPOP */ 3361/* VPOP */
4365/* cond 1100 1D11 1101 Vd-- 101X imm8 imm8 */ 3362/* 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 3363#ifdef VFP_INTERPRETER_STRUCT
4382typedef struct _vpop_inst { 3364typedef struct _vpop_inst {
4383 unsigned int single; 3365 unsigned int single;
4384 unsigned int d; 3366 unsigned int d;
4385 unsigned int imm32; 3367 unsigned int imm32;
4386 unsigned int regs; 3368 unsigned int regs;
4387} vfpinstr_inst; 3369} vpop_inst;
4388#endif 3370#endif
4389#ifdef VFP_INTERPRETER_TRANS 3371#ifdef VFP_INTERPRETER_TRANS
4390ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 3372ARM_INST_PTR INTERPRETER_TRANSLATE(vpop)(unsigned int inst, int index)
4391{ 3373{
4392 VFP_DEBUG_TRANSLATE; 3374 VFP_DEBUG_TRANSLATE;
4393 3375
4394 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 3376 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpop_inst));
4395 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3377 vpop_inst *inst_cream = (vpop_inst *)inst_base->component;
4396 3378
4397 inst_base->cond = BITS(inst, 28, 31); 3379 inst_base->cond = BITS(inst, 28, 31);
4398 inst_base->idx = index; 3380 inst_base->idx = index;
@@ -4408,7 +3390,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
4408} 3390}
4409#endif 3391#endif
4410#ifdef VFP_INTERPRETER_IMPL 3392#ifdef VFP_INTERPRETER_IMPL
4411VFPLABEL_INST: 3393VPOP_INST:
4412{ 3394{
4413 INC_ICOUNTER; 3395 INC_ICOUNTER;
4414 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 3396 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -4417,7 +3399,7 @@ VFPLABEL_INST:
4417 int i; 3399 int i;
4418 unsigned int value1, value2; 3400 unsigned int value1, value2;
4419 3401
4420 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3402 vpop_inst *inst_cream = (vpop_inst *)inst_base->component;
4421 3403
4422 DBG("VPOP :\n"); 3404 DBG("VPOP :\n");
4423 3405
@@ -4468,70 +3450,12 @@ VFPLABEL_INST:
4468 GOTO_NEXT_INST; 3450 GOTO_NEXT_INST;
4469} 3451}
4470#endif 3452#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 3453
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 3454#ifdef VFP_DYNCOM_TABLE
4531DYNCOM_FILL_ACTION(vfpinstr), 3455DYNCOM_FILL_ACTION(vpop),
4532#endif 3456#endif
4533#ifdef VFP_DYNCOM_TAG 3457#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) 3458int DYNCOM_TAG(vpop)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
4535{ 3459{
4536 int instr_size = INSTR_SIZE; 3460 int instr_size = INSTR_SIZE;
4537 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 3461 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -4547,7 +3471,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
4547} 3471}
4548#endif 3472#endif
4549#ifdef VFP_DYNCOM_TRANS 3473#ifdef VFP_DYNCOM_TRANS
4550int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 3474int DYNCOM_TRANS(vpop)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
4551 DBG("\t\tin %s instruction .\n", __FUNCTION__); 3475 DBG("\t\tin %s instruction .\n", __FUNCTION__);
4552 //arch_arm_undef(cpu, bb, instr); 3476 //arch_arm_undef(cpu, bb, instr);
4553 int single = BIT(8) == 0; 3477 int single = BIT(8) == 0;
@@ -4611,28 +3535,10 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
4611 return No_exp; 3535 return No_exp;
4612} 3536}
4613#endif 3537#endif
4614#undef vfpinstr
4615#undef vfpinstr_inst
4616#undef VFPLABEL_INST
4617 3538
4618/* ----------------------------------------------------------------------- */ 3539/* ----------------------------------------------------------------------- */
4619/* VLDR */ 3540/* VLDR */
4620/* cond 1101 UD01 Rn-- Vd-- 101X imm8 imm8 */ 3541/* 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 3542#ifdef VFP_INTERPRETER_STRUCT
4637typedef struct _vldr_inst { 3543typedef struct _vldr_inst {
4638 unsigned int single; 3544 unsigned int single;
@@ -4640,15 +3546,15 @@ typedef struct _vldr_inst {
4640 unsigned int d; 3546 unsigned int d;
4641 unsigned int imm32; 3547 unsigned int imm32;
4642 unsigned int add; 3548 unsigned int add;
4643} vfpinstr_inst; 3549} vldr_inst;
4644#endif 3550#endif
4645#ifdef VFP_INTERPRETER_TRANS 3551#ifdef VFP_INTERPRETER_TRANS
4646ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 3552ARM_INST_PTR INTERPRETER_TRANSLATE(vldr)(unsigned int inst, int index)
4647{ 3553{
4648 VFP_DEBUG_TRANSLATE; 3554 VFP_DEBUG_TRANSLATE;
4649 3555
4650 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 3556 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldr_inst));
4651 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3557 vldr_inst *inst_cream = (vldr_inst *)inst_base->component;
4652 3558
4653 inst_base->cond = BITS(inst, 28, 31); 3559 inst_base->cond = BITS(inst, 28, 31);
4654 inst_base->idx = index; 3560 inst_base->idx = index;
@@ -4665,13 +3571,13 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
4665} 3571}
4666#endif 3572#endif
4667#ifdef VFP_INTERPRETER_IMPL 3573#ifdef VFP_INTERPRETER_IMPL
4668VFPLABEL_INST: 3574VLDR_INST:
4669{ 3575{
4670 INC_ICOUNTER; 3576 INC_ICOUNTER;
4671 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 3577 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4672 CHECK_VFP_ENABLED; 3578 CHECK_VFP_ENABLED;
4673 3579
4674 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3580 vldr_inst *inst_cream = (vldr_inst *)inst_base->component;
4675 3581
4676 unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]); 3582 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); 3583 addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32);
@@ -4710,69 +3616,12 @@ VFPLABEL_INST:
4710 GOTO_NEXT_INST; 3616 GOTO_NEXT_INST;
4711} 3617}
4712#endif 3618#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 3619
4768 return -1;
4769}
4770#endif
4771#ifdef VFP_DYNCOM_TABLE 3620#ifdef VFP_DYNCOM_TABLE
4772DYNCOM_FILL_ACTION(vfpinstr), 3621DYNCOM_FILL_ACTION(vldr),
4773#endif 3622#endif
4774#ifdef VFP_DYNCOM_TAG 3623#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) 3624int DYNCOM_TAG(vldr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
4776{ 3625{
4777 int instr_size = INSTR_SIZE; 3626 int instr_size = INSTR_SIZE;
4778 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 3627 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -4788,7 +3637,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
4788} 3637}
4789#endif 3638#endif
4790#ifdef VFP_DYNCOM_TRANS 3639#ifdef VFP_DYNCOM_TRANS
4791int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 3640int DYNCOM_TRANS(vldr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
4792 int single = BIT(8) == 0; 3641 int single = BIT(8) == 0;
4793 int add = BIT(23); 3642 int add = BIT(23);
4794 int wback = BIT(21); 3643 int wback = BIT(21);
@@ -4846,28 +3695,10 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
4846 return No_exp; 3695 return No_exp;
4847} 3696}
4848#endif 3697#endif
4849#undef vfpinstr
4850#undef vfpinstr_inst
4851#undef VFPLABEL_INST
4852 3698
4853/* ----------------------------------------------------------------------- */ 3699/* ----------------------------------------------------------------------- */
4854/* VLDM */ 3700/* VLDM */
4855/* cond 110P UDW1 Rn-- Vd-- 101X imm8 imm8 */ 3701/* 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 3702#ifdef VFP_INTERPRETER_STRUCT
4872typedef struct _vldm_inst { 3703typedef struct _vldm_inst {
4873 unsigned int single; 3704 unsigned int single;
@@ -4877,15 +3708,15 @@ typedef struct _vldm_inst {
4877 unsigned int n; 3708 unsigned int n;
4878 unsigned int imm32; 3709 unsigned int imm32;
4879 unsigned int regs; 3710 unsigned int regs;
4880} vfpinstr_inst; 3711} vldm_inst;
4881#endif 3712#endif
4882#ifdef VFP_INTERPRETER_TRANS 3713#ifdef VFP_INTERPRETER_TRANS
4883ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) 3714ARM_INST_PTR INTERPRETER_TRANSLATE(vldm)(unsigned int inst, int index)
4884{ 3715{
4885 VFP_DEBUG_TRANSLATE; 3716 VFP_DEBUG_TRANSLATE;
4886 3717
4887 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst)); 3718 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldm_inst));
4888 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3719 vldm_inst *inst_cream = (vldm_inst *)inst_base->component;
4889 3720
4890 inst_base->cond = BITS(inst, 28, 31); 3721 inst_base->cond = BITS(inst, 28, 31);
4891 inst_base->idx = index; 3722 inst_base->idx = index;
@@ -4904,7 +3735,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
4904} 3735}
4905#endif 3736#endif
4906#ifdef VFP_INTERPRETER_IMPL 3737#ifdef VFP_INTERPRETER_IMPL
4907VFPLABEL_INST: 3738VLDM_INST:
4908{ 3739{
4909 INC_ICOUNTER; 3740 INC_ICOUNTER;
4910 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 3741 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -4912,7 +3743,7 @@ VFPLABEL_INST:
4912 3743
4913 int i; 3744 int i;
4914 3745
4915 vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; 3746 vldm_inst *inst_cream = (vldm_inst *)inst_base->component;
4916 3747
4917 addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); 3748 addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32);
4918 DBG("VLDM : addr[%x]\n", addr); 3749 DBG("VLDM : addr[%x]\n", addr);
@@ -4952,74 +3783,17 @@ VFPLABEL_INST:
4952 3783
4953 } 3784 }
4954 cpu->Reg[15] += GET_INST_SIZE(cpu); 3785 cpu->Reg[15] += GET_INST_SIZE(cpu);
4955 INC_PC(sizeof(vfpinstr_inst)); 3786 INC_PC(sizeof(vldm_inst));
4956 FETCH_INST; 3787 FETCH_INST;
4957 GOTO_NEXT_INST; 3788 GOTO_NEXT_INST;
4958} 3789}
4959#endif 3790#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 3791
5015 return -1;
5016}
5017#endif
5018#ifdef VFP_DYNCOM_TABLE 3792#ifdef VFP_DYNCOM_TABLE
5019DYNCOM_FILL_ACTION(vfpinstr), 3793DYNCOM_FILL_ACTION(vldm),
5020#endif 3794#endif
5021#ifdef VFP_DYNCOM_TAG 3795#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) 3796int DYNCOM_TAG(vldm)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
5023{ 3797{
5024 int instr_size = INSTR_SIZE; 3798 int instr_size = INSTR_SIZE;
5025 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 3799 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -5034,7 +3808,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
5034} 3808}
5035#endif 3809#endif
5036#ifdef VFP_DYNCOM_TRANS 3810#ifdef VFP_DYNCOM_TRANS
5037int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 3811int DYNCOM_TRANS(vldm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
5038 int single = BIT(8) == 0; 3812 int single = BIT(8) == 0;
5039 int add = BIT(23); 3813 int add = BIT(23);
5040 int wback = BIT(21); 3814 int wback = BIT(21);
@@ -5110,14 +3884,3 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
5110 return No_exp; 3884 return No_exp;
5111} 3885}
5112#endif 3886#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/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index 77491900a..38705e3cd 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -20,8 +20,8 @@ public:
20 std::string GetTypeName() const override { return "Arbiter"; } 20 std::string GetTypeName() const override { return "Arbiter"; }
21 std::string GetName() const override { return name; } 21 std::string GetName() const override { return name; }
22 22
23 static Kernel::HandleType GetStaticHandleType() { return HandleType::AddressArbiter; } 23 static const HandleType HANDLE_TYPE = HandleType::AddressArbiter;
24 Kernel::HandleType GetHandleType() const override { return HandleType::AddressArbiter; } 24 HandleType GetHandleType() const override { return HANDLE_TYPE; }
25 25
26 std::string name; ///< Name of address arbiter object (optional) 26 std::string name; ///< Name of address arbiter object (optional)
27}; 27};
@@ -62,7 +62,8 @@ ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s3
62/// Create an address arbiter 62/// Create an address arbiter
63AddressArbiter* CreateAddressArbiter(Handle& handle, const std::string& name) { 63AddressArbiter* CreateAddressArbiter(Handle& handle, const std::string& name) {
64 AddressArbiter* address_arbiter = new AddressArbiter; 64 AddressArbiter* address_arbiter = new AddressArbiter;
65 handle = Kernel::g_object_pool.Create(address_arbiter); 65 // TOOD(yuriks): Fix error reporting
66 handle = Kernel::g_handle_table.Create(address_arbiter).ValueOr(INVALID_HANDLE);
66 address_arbiter->name = name; 67 address_arbiter->name = name;
67 return address_arbiter; 68 return address_arbiter;
68} 69}
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp
index 4de3fab3c..e43c3ee4e 100644
--- a/src/core/hle/kernel/event.cpp
+++ b/src/core/hle/kernel/event.cpp
@@ -19,8 +19,8 @@ public:
19 std::string GetTypeName() const override { return "Event"; } 19 std::string GetTypeName() const override { return "Event"; }
20 std::string GetName() const override { return name; } 20 std::string GetName() const override { return name; }
21 21
22 static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Event; } 22 static const HandleType HANDLE_TYPE = HandleType::Event;
23 Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Event; } 23 HandleType GetHandleType() const override { return HANDLE_TYPE; }
24 24
25 ResetType intitial_reset_type; ///< ResetType specified at Event initialization 25 ResetType intitial_reset_type; ///< ResetType specified at Event initialization
26 ResetType reset_type; ///< Current ResetType 26 ResetType reset_type; ///< Current ResetType
@@ -53,7 +53,7 @@ public:
53 * @return Result of operation, 0 on success, otherwise error code 53 * @return Result of operation, 0 on success, otherwise error code
54 */ 54 */
55ResultCode SetPermanentLock(Handle handle, const bool permanent_locked) { 55ResultCode SetPermanentLock(Handle handle, const bool permanent_locked) {
56 Event* evt = g_object_pool.Get<Event>(handle); 56 Event* evt = g_handle_table.Get<Event>(handle);
57 if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); 57 if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel);
58 58
59 evt->permanent_locked = permanent_locked; 59 evt->permanent_locked = permanent_locked;
@@ -67,7 +67,7 @@ ResultCode SetPermanentLock(Handle handle, const bool permanent_locked) {
67 * @return Result of operation, 0 on success, otherwise error code 67 * @return Result of operation, 0 on success, otherwise error code
68 */ 68 */
69ResultCode SetEventLocked(const Handle handle, const bool locked) { 69ResultCode SetEventLocked(const Handle handle, const bool locked) {
70 Event* evt = g_object_pool.Get<Event>(handle); 70 Event* evt = g_handle_table.Get<Event>(handle);
71 if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); 71 if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel);
72 72
73 if (!evt->permanent_locked) { 73 if (!evt->permanent_locked) {
@@ -82,7 +82,7 @@ ResultCode SetEventLocked(const Handle handle, const bool locked) {
82 * @return Result of operation, 0 on success, otherwise error code 82 * @return Result of operation, 0 on success, otherwise error code
83 */ 83 */
84ResultCode SignalEvent(const Handle handle) { 84ResultCode SignalEvent(const Handle handle) {
85 Event* evt = g_object_pool.Get<Event>(handle); 85 Event* evt = g_handle_table.Get<Event>(handle);
86 if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); 86 if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel);
87 87
88 // Resume threads waiting for event to signal 88 // Resume threads waiting for event to signal
@@ -110,7 +110,7 @@ ResultCode SignalEvent(const Handle handle) {
110 * @return Result of operation, 0 on success, otherwise error code 110 * @return Result of operation, 0 on success, otherwise error code
111 */ 111 */
112ResultCode ClearEvent(Handle handle) { 112ResultCode ClearEvent(Handle handle) {
113 Event* evt = g_object_pool.Get<Event>(handle); 113 Event* evt = g_handle_table.Get<Event>(handle);
114 if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); 114 if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel);
115 115
116 if (!evt->permanent_locked) { 116 if (!evt->permanent_locked) {
@@ -129,7 +129,8 @@ ResultCode ClearEvent(Handle handle) {
129Event* CreateEvent(Handle& handle, const ResetType reset_type, const std::string& name) { 129Event* CreateEvent(Handle& handle, const ResetType reset_type, const std::string& name) {
130 Event* evt = new Event; 130 Event* evt = new Event;
131 131
132 handle = Kernel::g_object_pool.Create(evt); 132 // TOOD(yuriks): Fix error reporting
133 handle = Kernel::g_handle_table.Create(evt).ValueOr(INVALID_HANDLE);
133 134
134 evt->locked = true; 135 evt->locked = true;
135 evt->permanent_locked = false; 136 evt->permanent_locked = false;
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 5fd06046e..e59ed1b57 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -13,77 +13,93 @@
13namespace Kernel { 13namespace Kernel {
14 14
15Handle g_main_thread = 0; 15Handle g_main_thread = 0;
16ObjectPool g_object_pool; 16HandleTable g_handle_table;
17u64 g_program_id = 0; 17u64 g_program_id = 0;
18 18
19ObjectPool::ObjectPool() { 19HandleTable::HandleTable() {
20 next_id = INITIAL_NEXT_ID; 20 next_generation = 1;
21 Clear();
21} 22}
22 23
23Handle ObjectPool::Create(Object* obj, int range_bottom, int range_top) { 24ResultVal<Handle> HandleTable::Create(Object* obj) {
24 if (range_top > MAX_COUNT) { 25 _dbg_assert_(Kernel, obj != nullptr);
25 range_top = MAX_COUNT; 26
26 } 27 u16 slot = next_free_slot;
27 if (next_id >= range_bottom && next_id < range_top) { 28 if (slot >= generations.size()) {
28 range_bottom = next_id++; 29 LOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use.");
29 } 30 return ERR_OUT_OF_HANDLES;
30 for (int i = range_bottom; i < range_top; i++) {
31 if (!occupied[i]) {
32 occupied[i] = true;
33 pool[i] = obj;
34 pool[i]->handle = i + HANDLE_OFFSET;
35 return i + HANDLE_OFFSET;
36 }
37 } 31 }
38 LOG_ERROR(Kernel, "Unable to allocate kernel object, too many objects slots in use."); 32 next_free_slot = generations[slot];
39 return 0;
40}
41 33
42bool ObjectPool::IsValid(Handle handle) const { 34 u16 generation = next_generation++;
43 int index = handle - HANDLE_OFFSET;
44 if (index < 0)
45 return false;
46 if (index >= MAX_COUNT)
47 return false;
48 35
49 return occupied[index]; 36 // Overflow count so it fits in the 15 bits dedicated to the generation in the handle.
37 // CTR-OS doesn't use generation 0, so skip straight to 1.
38 if (next_generation >= (1 << 15)) next_generation = 1;
39
40 generations[slot] = generation;
41 intrusive_ptr_add_ref(obj);
42 objects[slot] = obj;
43
44 Handle handle = generation | (slot << 15);
45 obj->handle = handle;
46 return MakeResult<Handle>(handle);
50} 47}
51 48
52void ObjectPool::Clear() { 49ResultVal<Handle> HandleTable::Duplicate(Handle handle) {
53 for (int i = 0; i < MAX_COUNT; i++) { 50 Object* object = GetGeneric(handle);
54 //brutally clear everything, no validation 51 if (object == nullptr) {
55 if (occupied[i]) 52 LOG_ERROR(Kernel, "Tried to duplicate invalid handle: %08X", handle);
56 delete pool[i]; 53 return ERR_INVALID_HANDLE;
57 occupied[i] = false;
58 } 54 }
59 pool.fill(nullptr); 55 return Create(object);
60 next_id = INITIAL_NEXT_ID;
61} 56}
62 57
63Object* &ObjectPool::operator [](Handle handle) 58ResultCode HandleTable::Close(Handle handle) {
64{ 59 if (!IsValid(handle))
65 _dbg_assert_msg_(Kernel, IsValid(handle), "GRABBING UNALLOCED KERNEL OBJ"); 60 return ERR_INVALID_HANDLE;
66 return pool[handle - HANDLE_OFFSET]; 61
62 size_t slot = GetSlot(handle);
63 u16 generation = GetGeneration(handle);
64
65 intrusive_ptr_release(objects[slot]);
66 objects[slot] = nullptr;
67
68 generations[generation] = next_free_slot;
69 next_free_slot = slot;
70 return RESULT_SUCCESS;
67} 71}
68 72
69void ObjectPool::List() { 73bool HandleTable::IsValid(Handle handle) const {
70 for (int i = 0; i < MAX_COUNT; i++) { 74 size_t slot = GetSlot(handle);
71 if (occupied[i]) { 75 u16 generation = GetGeneration(handle);
72 if (pool[i]) { 76
73 LOG_DEBUG(Kernel, "KO %i: %s \"%s\"", i + HANDLE_OFFSET, pool[i]->GetTypeName().c_str(), 77 return slot < MAX_COUNT && objects[slot] != nullptr && generations[slot] == generation;
74 pool[i]->GetName().c_str());
75 }
76 }
77 }
78} 78}
79 79
80int ObjectPool::GetCount() const { 80Object* HandleTable::GetGeneric(Handle handle) const {
81 return std::count(occupied.begin(), occupied.end(), true); 81 if (handle == CurrentThread) {
82 // TODO(yuriks) Directly return the pointer once this is possible.
83 handle = GetCurrentThreadHandle();
84 } else if (handle == CurrentProcess) {
85 LOG_ERROR(Kernel, "Current process (%08X) pseudo-handle not supported", CurrentProcess);
86 return nullptr;
87 }
88
89 if (!IsValid(handle)) {
90 return nullptr;
91 }
92 return objects[GetSlot(handle)];
82} 93}
83 94
84Object* ObjectPool::CreateByIDType(int type) { 95void HandleTable::Clear() {
85 LOG_ERROR(Kernel, "Unimplemented: %d.", type); 96 for (size_t i = 0; i < MAX_COUNT; ++i) {
86 return nullptr; 97 generations[i] = i + 1;
98 if (objects[i] != nullptr)
99 intrusive_ptr_release(objects[i]);
100 objects[i] = nullptr;
101 }
102 next_free_slot = 0;
87} 103}
88 104
89/// Initialize the kernel 105/// Initialize the kernel
@@ -95,7 +111,7 @@ void Init() {
95void Shutdown() { 111void Shutdown() {
96 Kernel::ThreadingShutdown(); 112 Kernel::ThreadingShutdown();
97 113
98 g_object_pool.Clear(); // Free all kernel objects 114 g_handle_table.Clear(); // Free all kernel objects
99} 115}
100 116
101/** 117/**
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 32258d5a0..7f86fd07d 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -12,13 +12,17 @@
12typedef u32 Handle; 12typedef u32 Handle;
13typedef s32 Result; 13typedef s32 Result;
14 14
15const Handle INVALID_HANDLE = 0;
16
15namespace Kernel { 17namespace Kernel {
16 18
17// From kernel.h. Declarations duplicated here to avoid a circular header dependency. 19// TODO: Verify code
18class Thread; 20const ResultCode ERR_OUT_OF_HANDLES(ErrorDescription::OutOfMemory, ErrorModule::Kernel,
19Thread* GetCurrentThread(); 21 ErrorSummary::OutOfResource, ErrorLevel::Temporary);
22// TOOD: Verify code
23const ResultCode ERR_INVALID_HANDLE = InvalidHandle(ErrorModule::Kernel);
20 24
21enum KernelHandle { 25enum KernelHandle : Handle {
22 CurrentThread = 0xFFFF8000, 26 CurrentThread = 0xFFFF8000,
23 CurrentProcess = 0xFFFF8001, 27 CurrentProcess = 0xFFFF8001,
24}; 28};
@@ -41,10 +45,10 @@ enum {
41 DEFAULT_STACK_SIZE = 0x4000, 45 DEFAULT_STACK_SIZE = 0x4000,
42}; 46};
43 47
44class ObjectPool; 48class HandleTable;
45 49
46class Object : NonCopyable { 50class Object : NonCopyable {
47 friend class ObjectPool; 51 friend class HandleTable;
48 u32 handle; 52 u32 handle;
49public: 53public:
50 virtual ~Object() {} 54 virtual ~Object() {}
@@ -61,106 +65,130 @@ public:
61 LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); 65 LOG_ERROR(Kernel, "(UNIMPLEMENTED)");
62 return UnimplementedFunction(ErrorModule::Kernel); 66 return UnimplementedFunction(ErrorModule::Kernel);
63 } 67 }
64};
65 68
66class ObjectPool : NonCopyable { 69private:
67public: 70 friend void intrusive_ptr_add_ref(Object*);
68 ObjectPool(); 71 friend void intrusive_ptr_release(Object*);
69 ~ObjectPool() {}
70 72
71 // Allocates a handle within the range and inserts the object into the map. 73 unsigned int ref_count = 0;
72 Handle Create(Object* obj, int range_bottom=INITIAL_NEXT_ID, int range_top=0x7FFFFFFF); 74};
73 75
74 static Object* CreateByIDType(int type); 76// Special functions that will later be used by boost::instrusive_ptr to do automatic ref-counting
77inline void intrusive_ptr_add_ref(Object* object) {
78 ++object->ref_count;
79}
75 80
76 template <class T> 81inline void intrusive_ptr_release(Object* object) {
77 void Destroy(Handle handle) { 82 if (--object->ref_count == 0) {
78 if (Get<T>(handle)) { 83 delete object;
79 occupied[handle - HANDLE_OFFSET] = false;
80 delete pool[handle - HANDLE_OFFSET];
81 }
82 } 84 }
85}
83 86
84 bool IsValid(Handle handle) const; 87/**
88 * This class allows the creation of Handles, which are references to objects that can be tested
89 * for validity and looked up. Here they are used to pass references to kernel objects to/from the
90 * emulated process. it has been designed so that it follows the same handle format and has
91 * approximately the same restrictions as the handle manager in the CTR-OS.
92 *
93 * Handles contain two sub-fields: a slot index (bits 31:15) and a generation value (bits 14:0).
94 * The slot index is used to index into the arrays in this class to access the data corresponding
95 * to the Handle.
96 *
97 * To prevent accidental use of a freed Handle whose slot has already been reused, a global counter
98 * is kept and incremented every time a Handle is created. This is the Handle's "generation". The
99 * value of the counter is stored into the Handle as well as in the handle table (in the
100 * "generations" array). When looking up a handle, the Handle's generation must match with the
101 * value stored on the class, otherwise the Handle is considered invalid.
102 *
103 * To find free slots when allocating a Handle without needing to scan the entire object array, the
104 * generations field of unallocated slots is re-purposed as a linked list of indices to free slots.
105 * When a Handle is created, an index is popped off the list and used for the new Handle. When it
106 * is destroyed, it is again pushed onto the list to be re-used by the next allocation. It is
107 * likely that this allocation strategy differs from the one used in CTR-OS, but this hasn't been
108 * verified and isn't likely to cause any problems.
109 */
110class HandleTable final : NonCopyable {
111public:
112 HandleTable();
85 113
86 template <class T> 114 /**
87 T* Get(Handle handle) { 115 * Allocates a handle for the given object.
88 if (handle == CurrentThread) { 116 * @return The created Handle or one of the following errors:
89 return reinterpret_cast<T*>(GetCurrentThread()); 117 * - `ERR_OUT_OF_HANDLES`: the maximum number of handles has been exceeded.
90 } 118 */
119 ResultVal<Handle> Create(Object* obj);
91 120
92 if (handle < HANDLE_OFFSET || handle >= HANDLE_OFFSET + MAX_COUNT || !occupied[handle - HANDLE_OFFSET]) { 121 /**
93 if (handle != 0) { 122 * Returns a new handle that points to the same object as the passed in handle.
94 LOG_ERROR(Kernel, "Bad object handle %08x", handle); 123 * @return The duplicated Handle or one of the following errors:
95 } 124 * - `ERR_INVALID_HANDLE`: an invalid handle was passed in.
96 return nullptr; 125 * - Any errors returned by `Create()`.
97 } else { 126 */
98 Object* t = pool[handle - HANDLE_OFFSET]; 127 ResultVal<Handle> Duplicate(Handle handle);
99 if (t->GetHandleType() != T::GetStaticHandleType()) {
100 LOG_ERROR(Kernel, "Wrong object type for %08x", handle);
101 return nullptr;
102 }
103 return static_cast<T*>(t);
104 }
105 }
106 128
107 // ONLY use this when you know the handle is valid. 129 /**
108 template <class T> 130 * Closes a handle, removing it from the table and decreasing the object's ref-count.
109 T *GetFast(Handle handle) { 131 * @return `RESULT_SUCCESS` or one of the following errors:
110 if (handle == CurrentThread) { 132 * - `ERR_INVALID_HANDLE`: an invalid handle was passed in.
111 return reinterpret_cast<T*>(GetCurrentThread()); 133 */
112 } 134 ResultCode Close(Handle handle);
113 135
114 const Handle realHandle = handle - HANDLE_OFFSET; 136 /// Checks if a handle is valid and points to an existing object.
115 _dbg_assert_(Kernel, realHandle >= 0 && realHandle < MAX_COUNT && occupied[realHandle]); 137 bool IsValid(Handle handle) const;
116 return static_cast<T*>(pool[realHandle]);
117 }
118 138
119 template <class T, typename ArgT> 139 /**
120 void Iterate(bool func(T*, ArgT), ArgT arg) { 140 * Looks up a handle.
121 int type = T::GetStaticIDType(); 141 * @returns Pointer to the looked-up object, or `nullptr` if the handle is not valid.
122 for (int i = 0; i < MAX_COUNT; i++) 142 */
123 { 143 Object* GetGeneric(Handle handle) const;
124 if (!occupied[i])
125 continue;
126 T* t = static_cast<T*>(pool[i]);
127 if (t->GetIDType() == type) {
128 if (!func(t, arg))
129 break;
130 }
131 }
132 }
133 144
134 bool GetIDType(Handle handle, HandleType* type) const { 145 /**
135 if ((handle < HANDLE_OFFSET) || (handle >= HANDLE_OFFSET + MAX_COUNT) || 146 * Looks up a handle while verifying its type.
136 !occupied[handle - HANDLE_OFFSET]) { 147 * @returns Pointer to the looked-up object, or `nullptr` if the handle is not valid or its
137 LOG_ERROR(Kernel, "Bad object handle %08X", handle); 148 * type differs from the handle type `T::HANDLE_TYPE`.
138 return false; 149 */
150 template <class T>
151 T* Get(Handle handle) const {
152 Object* object = GetGeneric(handle);
153 if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) {
154 return static_cast<T*>(object);
139 } 155 }
140 Object* t = pool[handle - HANDLE_OFFSET]; 156 return nullptr;
141 *type = t->GetHandleType();
142 return true;
143 } 157 }
144 158
145 Object* &operator [](Handle handle); 159 /// Closes all handles held in this table.
146 void List();
147 void Clear(); 160 void Clear();
148 int GetCount() const;
149 161
150private: 162private:
163 /**
164 * This is the maximum limit of handles allowed per process in CTR-OS. It can be further
165 * reduced by ExHeader values, but this is not emulated here.
166 */
167 static const size_t MAX_COUNT = 4096;
168
169 static size_t GetSlot(Handle handle) { return handle >> 15; }
170 static u16 GetGeneration(Handle handle) { return handle & 0x7FFF; }
171
172 /// Stores the Object referenced by the handle or null if the slot is empty.
173 std::array<Object*, MAX_COUNT> objects;
151 174
152 enum { 175 /**
153 MAX_COUNT = 0x1000, 176 * The value of `next_generation` when the handle was created, used to check for validity. For
154 HANDLE_OFFSET = 0x100, 177 * empty slots, contains the index of the next free slot in the list.
155 INITIAL_NEXT_ID = 0x10, 178 */
156 }; 179 std::array<u16, MAX_COUNT> generations;
180
181 /**
182 * Global counter of the number of created handles. Stored in `generations` when a handle is
183 * created, and wraps around to 1 when it hits 0x8000.
184 */
185 u16 next_generation;
157 186
158 std::array<Object*, MAX_COUNT> pool; 187 /// Head of the free slots linked list.
159 std::array<bool, MAX_COUNT> occupied; 188 u16 next_free_slot;
160 int next_id;
161}; 189};
162 190
163extern ObjectPool g_object_pool; 191extern HandleTable g_handle_table;
164extern Handle g_main_thread; 192extern Handle g_main_thread;
165 193
166/// The ID code of the currently running game 194/// The ID code of the currently running game
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index 5a18af114..558068c79 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -18,8 +18,8 @@ public:
18 std::string GetTypeName() const override { return "Mutex"; } 18 std::string GetTypeName() const override { return "Mutex"; }
19 std::string GetName() const override { return name; } 19 std::string GetName() const override { return name; }
20 20
21 static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Mutex; } 21 static const HandleType HANDLE_TYPE = HandleType::Mutex;
22 Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Mutex; } 22 HandleType GetHandleType() const override { return HANDLE_TYPE; }
23 23
24 bool initial_locked; ///< Initial lock state when mutex was created 24 bool initial_locked; ///< Initial lock state when mutex was created
25 bool locked; ///< Current locked state 25 bool locked; ///< Current locked state
@@ -87,7 +87,7 @@ void ReleaseThreadMutexes(Handle thread) {
87 87
88 // Release every mutex that the thread holds, and resume execution on the waiting threads 88 // Release every mutex that the thread holds, and resume execution on the waiting threads
89 for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter) { 89 for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter) {
90 Mutex* mutex = g_object_pool.GetFast<Mutex>(iter->second); 90 Mutex* mutex = g_handle_table.Get<Mutex>(iter->second);
91 ResumeWaitingThread(mutex); 91 ResumeWaitingThread(mutex);
92 } 92 }
93 93
@@ -115,7 +115,7 @@ bool ReleaseMutex(Mutex* mutex) {
115 * @param handle Handle to mutex to release 115 * @param handle Handle to mutex to release
116 */ 116 */
117ResultCode ReleaseMutex(Handle handle) { 117ResultCode ReleaseMutex(Handle handle) {
118 Mutex* mutex = Kernel::g_object_pool.Get<Mutex>(handle); 118 Mutex* mutex = Kernel::g_handle_table.Get<Mutex>(handle);
119 if (mutex == nullptr) return InvalidHandle(ErrorModule::Kernel); 119 if (mutex == nullptr) return InvalidHandle(ErrorModule::Kernel);
120 120
121 if (!ReleaseMutex(mutex)) { 121 if (!ReleaseMutex(mutex)) {
@@ -136,7 +136,8 @@ ResultCode ReleaseMutex(Handle handle) {
136 */ 136 */
137Mutex* CreateMutex(Handle& handle, bool initial_locked, const std::string& name) { 137Mutex* CreateMutex(Handle& handle, bool initial_locked, const std::string& name) {
138 Mutex* mutex = new Mutex; 138 Mutex* mutex = new Mutex;
139 handle = Kernel::g_object_pool.Create(mutex); 139 // TODO(yuriks): Fix error reporting
140 handle = Kernel::g_handle_table.Create(mutex).ValueOr(INVALID_HANDLE);
140 141
141 mutex->locked = mutex->initial_locked = initial_locked; 142 mutex->locked = mutex->initial_locked = initial_locked;
142 mutex->name = name; 143 mutex->name = name;
diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp
index b81d0b26a..6bc8066a6 100644
--- a/src/core/hle/kernel/semaphore.cpp
+++ b/src/core/hle/kernel/semaphore.cpp
@@ -17,8 +17,8 @@ public:
17 std::string GetTypeName() const override { return "Semaphore"; } 17 std::string GetTypeName() const override { return "Semaphore"; }
18 std::string GetName() const override { return name; } 18 std::string GetName() const override { return name; }
19 19
20 static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Semaphore; } 20 static const HandleType HANDLE_TYPE = HandleType::Semaphore;
21 Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Semaphore; } 21 HandleType GetHandleType() const override { return HANDLE_TYPE; }
22 22
23 s32 max_count; ///< Maximum number of simultaneous holders the semaphore can have 23 s32 max_count; ///< Maximum number of simultaneous holders the semaphore can have
24 s32 available_count; ///< Number of free slots left in the semaphore 24 s32 available_count; ///< Number of free slots left in the semaphore
@@ -57,7 +57,8 @@ ResultCode CreateSemaphore(Handle* handle, s32 initial_count,
57 ErrorSummary::WrongArgument, ErrorLevel::Permanent); 57 ErrorSummary::WrongArgument, ErrorLevel::Permanent);
58 58
59 Semaphore* semaphore = new Semaphore; 59 Semaphore* semaphore = new Semaphore;
60 *handle = g_object_pool.Create(semaphore); 60 // TOOD(yuriks): Fix error reporting
61 *handle = g_handle_table.Create(semaphore).ValueOr(INVALID_HANDLE);
61 62
62 // When the semaphore is created, some slots are reserved for other threads, 63 // When the semaphore is created, some slots are reserved for other threads,
63 // and the rest is reserved for the caller thread 64 // and the rest is reserved for the caller thread
@@ -69,7 +70,7 @@ ResultCode CreateSemaphore(Handle* handle, s32 initial_count,
69} 70}
70 71
71ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) { 72ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) {
72 Semaphore* semaphore = g_object_pool.Get<Semaphore>(handle); 73 Semaphore* semaphore = g_handle_table.Get<Semaphore>(handle);
73 if (semaphore == nullptr) 74 if (semaphore == nullptr)
74 return InvalidHandle(ErrorModule::Kernel); 75 return InvalidHandle(ErrorModule::Kernel);
75 76
diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h
index 6760f346e..91f3ffc2c 100644
--- a/src/core/hle/kernel/session.h
+++ b/src/core/hle/kernel/session.h
@@ -45,8 +45,8 @@ class Session : public Object {
45public: 45public:
46 std::string GetTypeName() const override { return "Session"; } 46 std::string GetTypeName() const override { return "Session"; }
47 47
48 static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Session; } 48 static const HandleType HANDLE_TYPE = HandleType::Session;
49 Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Session; } 49 HandleType GetHandleType() const override { return HANDLE_TYPE; }
50 50
51 /** 51 /**
52 * Handles a synchronous call to this session using HLE emulation. Emulated <-> emulated calls 52 * Handles a synchronous call to this session using HLE emulation. Emulated <-> emulated calls
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index 2840f13bb..cea1f6fa1 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -13,8 +13,8 @@ class SharedMemory : public Object {
13public: 13public:
14 std::string GetTypeName() const override { return "SharedMemory"; } 14 std::string GetTypeName() const override { return "SharedMemory"; }
15 15
16 static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::SharedMemory; } 16 static const HandleType HANDLE_TYPE = HandleType::SharedMemory;
17 Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::SharedMemory; } 17 HandleType GetHandleType() const override { return HANDLE_TYPE; }
18 18
19 u32 base_address; ///< Address of shared memory block in RAM 19 u32 base_address; ///< Address of shared memory block in RAM
20 MemoryPermission permissions; ///< Permissions of shared memory block (SVC field) 20 MemoryPermission permissions; ///< Permissions of shared memory block (SVC field)
@@ -32,7 +32,8 @@ public:
32 */ 32 */
33SharedMemory* CreateSharedMemory(Handle& handle, const std::string& name) { 33SharedMemory* CreateSharedMemory(Handle& handle, const std::string& name) {
34 SharedMemory* shared_memory = new SharedMemory; 34 SharedMemory* shared_memory = new SharedMemory;
35 handle = Kernel::g_object_pool.Create(shared_memory); 35 // TOOD(yuriks): Fix error reporting
36 handle = Kernel::g_handle_table.Create(shared_memory).ValueOr(INVALID_HANDLE);
36 shared_memory->name = name; 37 shared_memory->name = name;
37 return shared_memory; 38 return shared_memory;
38} 39}
@@ -60,7 +61,7 @@ ResultCode MapSharedMemory(u32 handle, u32 address, MemoryPermission permissions
60 return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, 61 return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel,
61 ErrorSummary::InvalidArgument, ErrorLevel::Permanent); 62 ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
62 } 63 }
63 SharedMemory* shared_memory = Kernel::g_object_pool.Get<SharedMemory>(handle); 64 SharedMemory* shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle);
64 if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel); 65 if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel);
65 66
66 shared_memory->base_address = address; 67 shared_memory->base_address = address;
@@ -71,7 +72,7 @@ ResultCode MapSharedMemory(u32 handle, u32 address, MemoryPermission permissions
71} 72}
72 73
73ResultVal<u8*> GetSharedMemoryPointer(Handle handle, u32 offset) { 74ResultVal<u8*> GetSharedMemoryPointer(Handle handle, u32 offset) {
74 SharedMemory* shared_memory = Kernel::g_object_pool.Get<SharedMemory>(handle); 75 SharedMemory* shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle);
75 if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel); 76 if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel);
76 77
77 if (0 != shared_memory->base_address) 78 if (0 != shared_memory->base_address)
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index c6a8dc7b9..872df2d14 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -26,8 +26,8 @@ public:
26 std::string GetName() const override { return name; } 26 std::string GetName() const override { return name; }
27 std::string GetTypeName() const override { return "Thread"; } 27 std::string GetTypeName() const override { return "Thread"; }
28 28
29 static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Thread; } 29 static const HandleType HANDLE_TYPE = HandleType::Thread;
30 Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Thread; } 30 HandleType GetHandleType() const override { return HANDLE_TYPE; }
31 31
32 inline bool IsRunning() const { return (status & THREADSTATUS_RUNNING) != 0; } 32 inline bool IsRunning() const { return (status & THREADSTATUS_RUNNING) != 0; }
33 inline bool IsStopped() const { return (status & THREADSTATUS_DORMANT) != 0; } 33 inline bool IsStopped() const { return (status & THREADSTATUS_DORMANT) != 0; }
@@ -164,7 +164,7 @@ static bool CheckWaitType(const Thread* thread, WaitType type, Handle wait_handl
164 164
165/// Stops the current thread 165/// Stops the current thread
166ResultCode StopThread(Handle handle, const char* reason) { 166ResultCode StopThread(Handle handle, const char* reason) {
167 Thread* thread = g_object_pool.Get<Thread>(handle); 167 Thread* thread = g_handle_table.Get<Thread>(handle);
168 if (thread == nullptr) return InvalidHandle(ErrorModule::Kernel); 168 if (thread == nullptr) return InvalidHandle(ErrorModule::Kernel);
169 169
170 // Release all the mutexes that this thread holds 170 // Release all the mutexes that this thread holds
@@ -173,7 +173,7 @@ ResultCode StopThread(Handle handle, const char* reason) {
173 ChangeReadyState(thread, false); 173 ChangeReadyState(thread, false);
174 thread->status = THREADSTATUS_DORMANT; 174 thread->status = THREADSTATUS_DORMANT;
175 for (Handle waiting_handle : thread->waiting_threads) { 175 for (Handle waiting_handle : thread->waiting_threads) {
176 Thread* waiting_thread = g_object_pool.Get<Thread>(waiting_handle); 176 Thread* waiting_thread = g_handle_table.Get<Thread>(waiting_handle);
177 177
178 if (CheckWaitType(waiting_thread, WAITTYPE_THREADEND, handle)) 178 if (CheckWaitType(waiting_thread, WAITTYPE_THREADEND, handle))
179 ResumeThreadFromWait(waiting_handle); 179 ResumeThreadFromWait(waiting_handle);
@@ -210,7 +210,7 @@ Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address) {
210 210
211 // Iterate through threads, find highest priority thread that is waiting to be arbitrated... 211 // Iterate through threads, find highest priority thread that is waiting to be arbitrated...
212 for (Handle handle : thread_queue) { 212 for (Handle handle : thread_queue) {
213 Thread* thread = g_object_pool.Get<Thread>(handle); 213 Thread* thread = g_handle_table.Get<Thread>(handle);
214 214
215 if (!CheckWaitType(thread, WAITTYPE_ARB, arbiter, address)) 215 if (!CheckWaitType(thread, WAITTYPE_ARB, arbiter, address))
216 continue; 216 continue;
@@ -235,7 +235,7 @@ void ArbitrateAllThreads(u32 arbiter, u32 address) {
235 235
236 // Iterate through threads, find highest priority thread that is waiting to be arbitrated... 236 // Iterate through threads, find highest priority thread that is waiting to be arbitrated...
237 for (Handle handle : thread_queue) { 237 for (Handle handle : thread_queue) {
238 Thread* thread = g_object_pool.Get<Thread>(handle); 238 Thread* thread = g_handle_table.Get<Thread>(handle);
239 239
240 if (CheckWaitType(thread, WAITTYPE_ARB, arbiter, address)) 240 if (CheckWaitType(thread, WAITTYPE_ARB, arbiter, address))
241 ResumeThreadFromWait(handle); 241 ResumeThreadFromWait(handle);
@@ -288,7 +288,7 @@ Thread* NextThread() {
288 if (next == 0) { 288 if (next == 0) {
289 return nullptr; 289 return nullptr;
290 } 290 }
291 return Kernel::g_object_pool.Get<Thread>(next); 291 return Kernel::g_handle_table.Get<Thread>(next);
292} 292}
293 293
294void WaitCurrentThread(WaitType wait_type, Handle wait_handle) { 294void WaitCurrentThread(WaitType wait_type, Handle wait_handle) {
@@ -305,7 +305,7 @@ void WaitCurrentThread(WaitType wait_type, Handle wait_handle, VAddr wait_addres
305 305
306/// Resumes a thread from waiting by marking it as "ready" 306/// Resumes a thread from waiting by marking it as "ready"
307void ResumeThreadFromWait(Handle handle) { 307void ResumeThreadFromWait(Handle handle) {
308 Thread* thread = Kernel::g_object_pool.Get<Thread>(handle); 308 Thread* thread = Kernel::g_handle_table.Get<Thread>(handle);
309 if (thread) { 309 if (thread) {
310 thread->status &= ~THREADSTATUS_WAIT; 310 thread->status &= ~THREADSTATUS_WAIT;
311 thread->wait_handle = 0; 311 thread->wait_handle = 0;
@@ -341,7 +341,8 @@ Thread* CreateThread(Handle& handle, const char* name, u32 entry_point, s32 prio
341 341
342 Thread* thread = new Thread; 342 Thread* thread = new Thread;
343 343
344 handle = Kernel::g_object_pool.Create(thread); 344 // TOOD(yuriks): Fix error reporting
345 handle = Kernel::g_handle_table.Create(thread).ValueOr(INVALID_HANDLE);
345 346
346 thread_queue.push_back(handle); 347 thread_queue.push_back(handle);
347 thread_ready_queue.prepare(priority); 348 thread_ready_queue.prepare(priority);
@@ -398,7 +399,7 @@ Handle CreateThread(const char* name, u32 entry_point, s32 priority, u32 arg, s3
398 399
399/// Get the priority of the thread specified by handle 400/// Get the priority of the thread specified by handle
400ResultVal<u32> GetThreadPriority(const Handle handle) { 401ResultVal<u32> GetThreadPriority(const Handle handle) {
401 Thread* thread = g_object_pool.Get<Thread>(handle); 402 Thread* thread = g_handle_table.Get<Thread>(handle);
402 if (thread == nullptr) return InvalidHandle(ErrorModule::Kernel); 403 if (thread == nullptr) return InvalidHandle(ErrorModule::Kernel);
403 404
404 return MakeResult<u32>(thread->current_priority); 405 return MakeResult<u32>(thread->current_priority);
@@ -410,7 +411,7 @@ ResultCode SetThreadPriority(Handle handle, s32 priority) {
410 if (!handle) { 411 if (!handle) {
411 thread = GetCurrentThread(); // TODO(bunnei): Is this correct behavior? 412 thread = GetCurrentThread(); // TODO(bunnei): Is this correct behavior?
412 } else { 413 } else {
413 thread = g_object_pool.Get<Thread>(handle); 414 thread = g_handle_table.Get<Thread>(handle);
414 if (thread == nullptr) { 415 if (thread == nullptr) {
415 return InvalidHandle(ErrorModule::Kernel); 416 return InvalidHandle(ErrorModule::Kernel);
416 } 417 }
@@ -481,7 +482,7 @@ void Reschedule() {
481 LOG_TRACE(Kernel, "cannot context switch from 0x%08X, no higher priority thread!", prev->GetHandle()); 482 LOG_TRACE(Kernel, "cannot context switch from 0x%08X, no higher priority thread!", prev->GetHandle());
482 483
483 for (Handle handle : thread_queue) { 484 for (Handle handle : thread_queue) {
484 Thread* thread = g_object_pool.Get<Thread>(handle); 485 Thread* thread = g_handle_table.Get<Thread>(handle);
485 LOG_TRACE(Kernel, "\thandle=0x%08X prio=0x%02X, status=0x%08X wait_type=0x%08X wait_handle=0x%08X", 486 LOG_TRACE(Kernel, "\thandle=0x%08X prio=0x%02X, status=0x%08X wait_type=0x%08X wait_handle=0x%08X",
486 thread->GetHandle(), thread->current_priority, thread->status, thread->wait_type, thread->wait_handle); 487 thread->GetHandle(), thread->current_priority, thread->status, thread->wait_type, thread->wait_handle);
487 } 488 }
@@ -497,7 +498,7 @@ void Reschedule() {
497} 498}
498 499
499ResultCode GetThreadId(u32* thread_id, Handle handle) { 500ResultCode GetThreadId(u32* thread_id, Handle handle) {
500 Thread* thread = g_object_pool.Get<Thread>(handle); 501 Thread* thread = g_handle_table.Get<Thread>(handle);
501 if (thread == nullptr) 502 if (thread == nullptr)
502 return ResultCode(ErrorDescription::InvalidHandle, ErrorModule::OS, 503 return ResultCode(ErrorDescription::InvalidHandle, ErrorModule::OS,
503 ErrorSummary::WrongArgument, ErrorLevel::Permanent); 504 ErrorSummary::WrongArgument, ErrorLevel::Permanent);
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 9396b6b26..0e1397cd9 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -77,9 +77,6 @@ Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address);
77/// Arbitrate all threads currently waiting... 77/// Arbitrate all threads currently waiting...
78void ArbitrateAllThreads(u32 arbiter, u32 address); 78void ArbitrateAllThreads(u32 arbiter, u32 address);
79 79
80/// Gets the current thread
81Thread* GetCurrentThread();
82
83/// Gets the current thread handle 80/// Gets the current thread handle
84Handle GetCurrentThreadHandle(); 81Handle GetCurrentThreadHandle();
85 82
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index 98db02f15..487bf3aa7 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -133,7 +133,7 @@ public:
133 case FileCommand::Close: 133 case FileCommand::Close:
134 { 134 {
135 LOG_TRACE(Service_FS, "Close %s %s", GetTypeName().c_str(), GetName().c_str()); 135 LOG_TRACE(Service_FS, "Close %s %s", GetTypeName().c_str(), GetName().c_str());
136 Kernel::g_object_pool.Destroy<File>(GetHandle()); 136 backend->Close();
137 break; 137 break;
138 } 138 }
139 139
@@ -189,7 +189,7 @@ public:
189 case DirectoryCommand::Close: 189 case DirectoryCommand::Close:
190 { 190 {
191 LOG_TRACE(Service_FS, "Close %s %s", GetTypeName().c_str(), GetName().c_str()); 191 LOG_TRACE(Service_FS, "Close %s %s", GetTypeName().c_str(), GetName().c_str());
192 Kernel::g_object_pool.Destroy<Directory>(GetHandle()); 192 backend->Close();
193 break; 193 break;
194 } 194 }
195 195
@@ -283,7 +283,8 @@ ResultVal<Handle> OpenFileFromArchive(ArchiveHandle archive_handle, const FileSy
283 } 283 }
284 284
285 auto file = Common::make_unique<File>(std::move(backend), path); 285 auto file = Common::make_unique<File>(std::move(backend), path);
286 Handle handle = Kernel::g_object_pool.Create(file.release()); 286 // TOOD(yuriks): Fix error reporting
287 Handle handle = Kernel::g_handle_table.Create(file.release()).ValueOr(INVALID_HANDLE);
287 return MakeResult<Handle>(handle); 288 return MakeResult<Handle>(handle);
288} 289}
289 290
@@ -388,7 +389,8 @@ ResultVal<Handle> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const F
388 } 389 }
389 390
390 auto directory = Common::make_unique<Directory>(std::move(backend), path); 391 auto directory = Common::make_unique<Directory>(std::move(backend), path);
391 Handle handle = Kernel::g_object_pool.Create(directory.release()); 392 // TOOD(yuriks): Fix error reporting
393 Handle handle = Kernel::g_handle_table.Create(directory.release()).ValueOr(INVALID_HANDLE);
392 return MakeResult<Handle>(handle); 394 return MakeResult<Handle>(handle);
393} 395}
394 396
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 44e4fbcb2..0f3cc2aa8 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -56,7 +56,8 @@ Manager::~Manager() {
56 56
57/// Add a service to the manager (does not create it though) 57/// Add a service to the manager (does not create it though)
58void Manager::AddService(Interface* service) { 58void Manager::AddService(Interface* service) {
59 m_port_map[service->GetPortName()] = Kernel::g_object_pool.Create(service); 59 // TOOD(yuriks): Fix error reporting
60 m_port_map[service->GetPortName()] = Kernel::g_handle_table.Create(service).ValueOr(INVALID_HANDLE);
60 m_services.push_back(service); 61 m_services.push_back(service);
61} 62}
62 63
@@ -70,7 +71,7 @@ void Manager::DeleteService(const std::string& port_name) {
70 71
71/// Get a Service Interface from its Handle 72/// Get a Service Interface from its Handle
72Interface* Manager::FetchFromHandle(Handle handle) { 73Interface* Manager::FetchFromHandle(Handle handle) {
73 return Kernel::g_object_pool.Get<Interface>(handle); 74 return Kernel::g_handle_table.Get<Interface>(handle);
74} 75}
75 76
76/// Get a Service Interface from its port 77/// Get a Service Interface from its port
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index 0616822fa..28b4ccd17 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -54,7 +54,8 @@ public:
54 54
55 /// Allocates a new handle for the service 55 /// Allocates a new handle for the service
56 Handle CreateHandle(Kernel::Object *obj) { 56 Handle CreateHandle(Kernel::Object *obj) {
57 Handle handle = Kernel::g_object_pool.Create(obj); 57 // TODO(yuriks): Fix error reporting
58 Handle handle = Kernel::g_handle_table.Create(obj).ValueOr(INVALID_HANDLE);
58 m_handles.push_back(handle); 59 m_handles.push_back(handle);
59 return handle; 60 return handle;
60 } 61 }
@@ -62,7 +63,7 @@ public:
62 /// Frees a handle from the service 63 /// Frees a handle from the service
63 template <class T> 64 template <class T>
64 void DeleteHandle(const Handle handle) { 65 void DeleteHandle(const Handle handle) {
65 Kernel::g_object_pool.Destroy<T>(handle); 66 Kernel::g_handle_table.Close(handle);
66 m_handles.erase(std::remove(m_handles.begin(), m_handles.end(), handle), m_handles.end()); 67 m_handles.erase(std::remove(m_handles.begin(), m_handles.end(), handle), m_handles.end());
67 } 68 }
68 69
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index c98168e51..25944fc68 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -92,7 +92,7 @@ static Result ConnectToPort(Handle* out, const char* port_name) {
92 92
93/// Synchronize to an OS service 93/// Synchronize to an OS service
94static Result SendSyncRequest(Handle handle) { 94static Result SendSyncRequest(Handle handle) {
95 Kernel::Session* session = Kernel::g_object_pool.Get<Kernel::Session>(handle); 95 Kernel::Session* session = Kernel::g_handle_table.Get<Kernel::Session>(handle);
96 if (session == nullptr) { 96 if (session == nullptr) {
97 return InvalidHandle(ErrorModule::Kernel).raw; 97 return InvalidHandle(ErrorModule::Kernel).raw;
98 } 98 }
@@ -119,11 +119,9 @@ static Result WaitSynchronization1(Handle handle, s64 nano_seconds) {
119 // TODO(bunnei): Do something with nano_seconds, currently ignoring this 119 // TODO(bunnei): Do something with nano_seconds, currently ignoring this
120 bool wait_infinite = (nano_seconds == -1); // Used to wait until a thread has terminated 120 bool wait_infinite = (nano_seconds == -1); // Used to wait until a thread has terminated
121 121
122 if (!Kernel::g_object_pool.IsValid(handle)) { 122 Kernel::Object* object = Kernel::g_handle_table.GetGeneric(handle);
123 if (object == nullptr)
123 return InvalidHandle(ErrorModule::Kernel).raw; 124 return InvalidHandle(ErrorModule::Kernel).raw;
124 }
125 Kernel::Object* object = Kernel::g_object_pool.GetFast<Kernel::Object>(handle);
126 _dbg_assert_(Kernel, object != nullptr);
127 125
128 LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle, object->GetTypeName().c_str(), 126 LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle, object->GetTypeName().c_str(),
129 object->GetName().c_str(), nano_seconds); 127 object->GetName().c_str(), nano_seconds);
@@ -150,10 +148,9 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count,
150 148
151 // Iterate through each handle, synchronize kernel object 149 // Iterate through each handle, synchronize kernel object
152 for (s32 i = 0; i < handle_count; i++) { 150 for (s32 i = 0; i < handle_count; i++) {
153 if (!Kernel::g_object_pool.IsValid(handles[i])) { 151 Kernel::Object* object = Kernel::g_handle_table.GetGeneric(handles[i]);
152 if (object == nullptr)
154 return InvalidHandle(ErrorModule::Kernel).raw; 153 return InvalidHandle(ErrorModule::Kernel).raw;
155 }
156 Kernel::Object* object = Kernel::g_object_pool.GetFast<Kernel::Object>(handles[i]);
157 154
158 LOG_TRACE(Kernel_SVC, "\thandle[%d] = 0x%08X(%s:%s)", i, handles[i], object->GetTypeName().c_str(), 155 LOG_TRACE(Kernel_SVC, "\thandle[%d] = 0x%08X(%s:%s)", i, handles[i], object->GetTypeName().c_str(),
159 object->GetName().c_str()); 156 object->GetName().c_str());
@@ -321,19 +318,12 @@ static Result CreateEvent(Handle* evt, u32 reset_type) {
321 318
322/// Duplicates a kernel handle 319/// Duplicates a kernel handle
323static Result DuplicateHandle(Handle* out, Handle handle) { 320static Result DuplicateHandle(Handle* out, Handle handle) {
324 LOG_WARNING(Kernel_SVC, "(STUBBED) called handle=0x%08X", handle); 321 ResultVal<Handle> out_h = Kernel::g_handle_table.Duplicate(handle);
325 322 if (out_h.Succeeded()) {
326 // Translate kernel handles -> real handles 323 *out = *out_h;
327 if (handle == Kernel::CurrentThread) { 324 LOG_TRACE(Kernel_SVC, "duplicated 0x%08X to 0x%08X", handle, *out);
328 handle = Kernel::GetCurrentThreadHandle();
329 } 325 }
330 _assert_msg_(KERNEL, (handle != Kernel::CurrentProcess), 326 return out_h.Code().raw;
331 "(UNIMPLEMENTED) process handle duplication!");
332
333 // TODO(bunnei): FixMe - This is a hack to return the handle that we were asked to duplicate.
334 *out = handle;
335
336 return 0;
337} 327}
338 328
339/// Signals an event 329/// Signals an event