summaryrefslogtreecommitdiffstats
path: root/src/core/arm/dyncom
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2014-12-29 07:39:12 +0100
committerbunnei <bunneidev@gmail.com>2014-12-30 03:50:47 +0100
commitaa49019afbaacf85c9768d8df5632719d99e6aa4 (patch)
treec1e9ca0db07c5cbda68ace0a7bdcc76b2348dfee /src/core/arm/dyncom
parentMerge pull request #361 from lioncash/moreqops (diff)
downloadyuzu-aa49019afbaacf85c9768d8df5632719d99e6aa4.tar
yuzu-aa49019afbaacf85c9768d8df5632719d99e6aa4.tar.gz
yuzu-aa49019afbaacf85c9768d8df5632719d99e6aa4.tar.bz2
yuzu-aa49019afbaacf85c9768d8df5632719d99e6aa4.tar.lz
yuzu-aa49019afbaacf85c9768d8df5632719d99e6aa4.tar.xz
yuzu-aa49019afbaacf85c9768d8df5632719d99e6aa4.tar.zst
yuzu-aa49019afbaacf85c9768d8df5632719d99e6aa4.zip
Diffstat (limited to '')
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.cpp875
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp11234
-rw-r--r--src/core/arm/dyncom/arm_dyncom_run.cpp45
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.cpp863
4 files changed, 5962 insertions, 7055 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp
index 551bb77a6..333b40f54 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp
@@ -1,464 +1,443 @@
-/* Copyright (C)
-* 2012 - Michael.Kang blackfin.kang@gmail.com
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-*/
-/**
-* @file arm_dyncom_dec.cpp
-* @brief Some common utility for arm decoder
-* @author Michael.Kang blackfin.kang@gmail.com
-* @version 7849
-* @date 2012-03-15
-*/
+// Copyright 2012 Michael Kang, 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
#include "core/arm/skyeye_common/arm_regformat.h"
#include "core/arm/skyeye_common/armdefs.h"
#include "core/arm/dyncom/arm_dyncom_dec.h"
const ISEITEM arm_instruction[] = {
- {"vmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0},
- {"vmls", 7, ARMVFP2, 28, 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0},
- {"vnmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0},
- {"vnmla", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
- {"vnmls", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
- {"vnmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
- {"vmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
- {"vadd", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
- {"vsub", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
- {"vdiv", 5, ARMVFP2, 23, 27, 0x1D, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
- {"vmov(i)", 4, ARMVFP3, 23, 27, 0x1D, 20, 21, 0x3, 9, 11, 0x5, 4, 7, 0},
- {"vmov(r)", 5, ARMVFP3, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 1, 4, 4, 0},
- {"vabs", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 3, 4, 4, 0},
- {"vneg", 5, ARMVFP2, 23, 27, 0x1D, 17, 21, 0x18, 9, 11, 0x5, 6, 7, 1, 4, 4, 0},
- {"vsqrt", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x31, 9, 11, 0x5, 6, 7, 3, 4, 4, 0},
- {"vcmp", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x34, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
- {"vcmp2", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x35, 9, 11, 0x5, 0, 6, 0x40},
- {"vcvt(bds)", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x37, 9, 11, 0x5, 6, 7, 3, 4, 4, 0},
- {"vcvt(bff)", 6, ARMVFP3, 23, 27, 0x1D, 19, 21, 0x7, 17, 17, 0x1, 9, 11,5, 6, 6, 1},
- {"vcvt(bfi)", 5, ARMVFP2, 23, 27, 0x1D, 19, 21, 0x7, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
- {"vmovbrs", 3, ARMVFP2, 21, 27, 0x70, 8, 11, 0xA, 0, 6, 0x10},
- {"vmsr", 2, ARMVFP2, 20, 27, 0xEE, 0, 11, 0xA10},
- {"vmovbrc", 4, ARMVFP2, 23, 27, 0x1C, 20, 20, 0x0, 8, 11, 0xB, 0,4,0x10},
- {"vmrs", 2, ARMVFP2, 20, 27, 0xEF, 0, 11, 0xA10},
- {"vmovbcr", 4, ARMVFP2, 24, 27, 0xE, 20, 20, 1, 8, 11, 0xB, 0,4,0x10},
- {"vmovbrrss", 3, ARMVFP2, 21, 27, 0x62, 8, 11, 0xA, 4, 4, 1},
- {"vmovbrrd", 3, ARMVFP2, 21, 27, 0x62, 6, 11, 0x2C, 4, 4, 1},
- {"vstr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 0, 9, 11,5},
- {"vpush", 3, ARMVFP2, 23, 27, 0x1A, 16, 21, 0x2D, 9, 11,5},
- {"vstm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 0, 9, 11,5},
- {"vpop", 3, ARMVFP2, 23, 27, 0x19, 16, 21, 0x3D, 9, 11,5},
- {"vldr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 1, 9, 11,5},
- {"vldm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 1, 9, 11,5},
+ { "vmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0 },
+ { "vmls", 7, ARMVFP2, 28, 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0 },
+ { "vnmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0 },
+ { "vnmla", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 },
+ { "vnmls", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 },
+ { "vnmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 },
+ { "vmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 },
+ { "vadd", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 },
+ { "vsub", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 },
+ { "vdiv", 5, ARMVFP2, 23, 27, 0x1D, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 },
+ { "vmov(i)", 4, ARMVFP3, 23, 27, 0x1D, 20, 21, 0x3, 9, 11, 0x5, 4, 7, 0 },
+ { "vmov(r)", 5, ARMVFP3, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 1, 4, 4, 0 },
+ { "vabs", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 },
+ { "vneg", 5, ARMVFP2, 23, 27, 0x1D, 17, 21, 0x18, 9, 11, 0x5, 6, 7, 1, 4, 4, 0 },
+ { "vsqrt", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x31, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 },
+ { "vcmp", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x34, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 },
+ { "vcmp2", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x35, 9, 11, 0x5, 0, 6, 0x40 },
+ { "vcvt(bds)", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x37, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 },
+ { "vcvt(bff)", 6, ARMVFP3, 23, 27, 0x1D, 19, 21, 0x7, 17, 17, 0x1, 9, 11, 5, 6, 6, 1 },
+ { "vcvt(bfi)", 5, ARMVFP2, 23, 27, 0x1D, 19, 21, 0x7, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 },
+ { "vmovbrs", 3, ARMVFP2, 21, 27, 0x70, 8, 11, 0xA, 0, 6, 0x10 },
+ { "vmsr", 2, ARMVFP2, 20, 27, 0xEE, 0, 11, 0xA10 },
+ { "vmovbrc", 4, ARMVFP2, 23, 27, 0x1C, 20, 20, 0x0, 8, 11, 0xB, 0, 4, 0x10 },
+ { "vmrs", 2, ARMVFP2, 20, 27, 0xEF, 0, 11, 0xA10 },
+ { "vmovbcr", 4, ARMVFP2, 24, 27, 0xE, 20, 20, 1, 8, 11, 0xB, 0, 4, 0x10 },
+ { "vmovbrrss", 3, ARMVFP2, 21, 27, 0x62, 8, 11, 0xA, 4, 4, 1 },
+ { "vmovbrrd", 3, ARMVFP2, 21, 27, 0x62, 6, 11, 0x2C, 4, 4, 1 },
+ { "vstr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 0, 9, 11, 5 },
+ { "vpush", 3, ARMVFP2, 23, 27, 0x1A, 16, 21, 0x2D, 9, 11, 5 },
+ { "vstm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 0, 9, 11, 5 },
+ { "vpop", 3, ARMVFP2, 23, 27, 0x19, 16, 21, 0x3D, 9, 11, 5 },
+ { "vldr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 1, 9, 11, 5 },
+ { "vldm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 1, 9, 11, 5 },
- {"srs" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d, 8, 11, 0x00000005},
- {"rfe" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001, 8, 11, 0x0000000a},
- {"bkpt" , 2 , 3 , 20, 31, 0x00000e12, 4, 7, 0x00000007},
- {"blx" , 1 , 3 , 25, 31, 0x0000007d},
- {"cps" , 3 , 6 , 20, 31, 0x00000f10, 16, 16, 0x00000000, 5, 5, 0x00000000},
- {"pld" , 4 , 4 , 26, 31, 0x0000003d, 24, 24, 0x00000001, 20, 22, 0x00000005, 12, 15, 0x0000000f},
- {"setend" , 2 , 6 , 16, 31, 0x0000f101, 4, 7, 0x00000000},
- {"clrex" , 1 , 6 , 0, 31, 0xf57ff01f},
- {"rev16" , 2 , 6 , 16, 27, 0x000006bf, 4, 11, 0x000000fb},
- {"usad8" , 3 , 6 , 20, 27, 0x00000078, 12, 15, 0x0000000f, 4, 7, 0x00000001},
- {"sxtb" , 2 , 6 , 16, 27, 0x000006af, 4, 7, 0x00000007},
- {"uxtb" , 2 , 6 , 16, 27, 0x000006ef, 4, 7, 0x00000007},
- {"sxth" , 2 , 6 , 16, 27, 0x000006bf, 4, 7, 0x00000007},
- {"sxtb16" , 2 , 6 , 16, 27, 0x0000068f, 4, 7, 0x00000007},
- {"uxth" , 2 , 6 , 16, 27, 0x000006ff, 4, 7, 0x00000007},
- {"uxtb16" , 2 , 6 , 16, 27, 0x000006cf, 4, 7, 0x00000007},
- {"cpy" , 2 , 6 , 20, 27, 0x0000001a, 4, 11, 0x00000000},
- {"uxtab" , 2 , 6 , 20, 27, 0x0000006e, 4, 9, 0x00000007},
- {"ssub8" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x0000000f},
- {"shsub8" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x0000000f},
- {"ssubaddx" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000005},
- {"strex" , 2 , 6 , 20, 27, 0x00000018, 4, 7, 0x00000009},
- {"strexb" , 2 , 7 , 20, 27, 0x0000001c, 4, 7, 0x00000009},
- {"swp" , 2 , 0 , 20, 27, 0x00000010, 4, 7, 0x00000009},
- {"swpb" , 2 , 0 , 20, 27, 0x00000014, 4, 7, 0x00000009},
- {"ssub16" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000007},
- {"ssat16" , 2 , 6 , 20, 27, 0x0000006a, 4, 7, 0x00000003},
- {"shsubaddx" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000005},
- {"qsubaddx" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000005},
- {"shaddsubx" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000003},
- {"shadd8" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000009},
- {"shadd16" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000001},
- {"sel" , 2 , 6 , 20, 27, 0x00000068, 4, 7, 0x0000000b},
- {"saddsubx" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000003},
- {"sadd8" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000009},
- {"sadd16" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000001},
- {"shsub16" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000007},
- {"umaal" , 2 , 6 , 20, 27, 0x00000004, 4, 7, 0x00000009},
- {"uxtab16" , 2 , 6 , 20, 27, 0x0000006c, 4, 7, 0x00000007},
- {"usubaddx" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000005},
- {"usub8" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x0000000f},
- {"usub16" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000007},
- {"usat16" , 2 , 6 , 20, 27, 0x0000006e, 4, 7, 0x00000003},
- {"usada8" , 2 , 6 , 20, 27, 0x00000078, 4, 7, 0x00000001},
- {"uqsubaddx" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000005},
- {"uqsub8" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x0000000f},
- {"uqsub16" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000007},
- {"uqaddsubx" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000003},
- {"uqadd8" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000009},
- {"uqadd16" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000001},
- {"sxtab" , 2 , 6 , 20, 27, 0x0000006a, 4, 7, 0x00000007},
- {"uhsubaddx" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000005},
- {"uhsub8" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x0000000f},
- {"uhsub16" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000007},
- {"uhaddsubx" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000003},
- {"uhadd8" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000009},
- {"uhadd16" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000001},
- {"uaddsubx" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000003},
- {"uadd8" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000009},
- {"uadd16" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000001},
- {"sxtah" , 2 , 6 , 20, 27, 0x0000006b, 4, 7, 0x00000007},
- {"sxtab16" , 2 , 6 , 20, 27, 0x00000068, 4, 7, 0x00000007},
- {"qadd8" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000009},
- {"bxj" , 2 , 5 , 20, 27, 0x00000012, 4, 7, 0x00000002},
- {"clz" , 2 , 3 , 20, 27, 0x00000016, 4, 7, 0x00000001},
- {"uxtah" , 2 , 6 , 20, 27, 0x0000006f, 4, 7, 0x00000007},
- {"bx" , 2 , 2 , 20, 27, 0x00000012, 4, 7, 0x00000001},
- {"rev" , 2 , 6 , 20, 27, 0x0000006b, 4, 7, 0x00000003},
- {"blx" , 2 , 3 , 20, 27, 0x00000012, 4, 7, 0x00000003},
- {"revsh" , 2 , 6 , 20, 27, 0x0000006f, 4, 7, 0x0000000b},
- {"qadd" , 2 , 4 , 20, 27, 0x00000010, 4, 7, 0x00000005},
- {"qadd16" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000001},
- {"qaddsubx" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000003},
- {"ldrex" , 2 , 0 , 20, 27, 0x00000019, 4, 7, 0x00000009},
- {"qdadd" , 2 , 4 , 20, 27, 0x00000014, 4, 7, 0x00000005},
- {"qdsub" , 2 , 4 , 20, 27, 0x00000016, 4, 7, 0x00000005},
- {"qsub" , 2 , 4 , 20, 27, 0x00000012, 4, 7, 0x00000005},
- {"ldrexb" , 2 , 7 , 20, 27, 0x0000001d, 4, 7, 0x00000009},
- {"qsub8" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x0000000f},
- {"qsub16" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000007},
- {"smuad" , 4 , 6 , 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001},
- {"smmul" , 4 , 6 , 20, 27, 0x00000075, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001},
- {"smusd" , 4 , 6 , 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000001, 4, 4, 0x00000001},
- {"smlsd" , 3 , 6 , 20, 27, 0x00000070, 6, 7, 0x00000001, 4, 4, 0x00000001},
- {"smlsld" , 3 , 6 , 20, 27, 0x00000074, 6, 7, 0x00000001, 4, 4, 0x00000001},
- {"smmla" , 3 , 6 , 20, 27, 0x00000075, 6, 7, 0x00000000, 4, 4, 0x00000001},
- {"smmls" , 3 , 6 , 20, 27, 0x00000075, 6, 7, 0x00000003, 4, 4, 0x00000001},
- {"smlald" , 3 , 6 , 20, 27, 0x00000074, 6, 7, 0x00000000, 4, 4, 0x00000001},
- {"smlad" , 3 , 6 , 20, 27, 0x00000070, 6, 7, 0x00000000, 4, 4, 0x00000001},
- {"smlaw" , 3 , 4 , 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000000},
- {"smulw" , 3 , 4 , 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000002},
- {"pkhtb" , 2 , 6 , 20, 27, 0x00000068, 4, 6, 0x00000005},
- {"pkhbt" , 2 , 6 , 20, 27, 0x00000068, 4, 6, 0x00000001},
- {"smul" , 3 , 4 , 20, 27, 0x00000016, 7, 7, 0x00000001, 4, 4, 0x00000000},
- {"smlalxy" , 3 , 4 , 20, 27, 0x00000014, 7, 7, 0x00000001, 4, 4, 0x00000000},
-// {"smlal" , 2 , 4 , 21, 27, 0x00000007, 4, 7, 0x00000009},
- {"smla" , 3 , 4 , 20, 27, 0x00000010, 7, 7, 0x00000001, 4, 4, 0x00000000},
- {"mcrr" , 1 , 6 , 20, 27, 0x000000c4},
- {"mrrc" , 1 , 6 , 20, 27, 0x000000c5},
- {"cmp" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000015},
- {"tst" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000011},
- {"teq" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000013},
- {"cmn" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000017},
- {"smull" , 2 , 0 , 21, 27, 0x00000006, 4, 7, 0x00000009},
- {"umull" , 2 , 0 , 21, 27, 0x00000004, 4, 7, 0x00000009},
- {"umlal" , 2 , 0 , 21, 27, 0x00000005, 4, 7, 0x00000009},
- {"smlal" , 2 , 0 , 21, 27, 0x00000007, 4, 7, 0x00000009},
- {"mul" , 2 , 0 , 21, 27, 0x00000000, 4, 7, 0x00000009},
- {"mla" , 2 , 0 , 21, 27, 0x00000001, 4, 7, 0x00000009},
- {"ssat" , 2 , 6 , 21, 27, 0x00000035, 4, 5, 0x00000001},
- {"usat" , 2 , 6 , 21, 27, 0x00000037, 4, 5, 0x00000001},
- {"mrs" , 4 , 0 , 23, 27, 0x00000002, 20, 21, 0x00000000, 16, 19, 0x0000000f, 0, 11, 0x00000000},
- {"msr" , 3 , 0 , 23, 27, 0x00000002, 20, 21, 0x00000002, 4, 7, 0x00000000},
- {"and" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000000},
- {"bic" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000e},
- {"ldm" , 3 , 0 , 25, 27, 0x00000004, 20, 22, 0x00000005, 15, 15, 0x00000000},
- {"eor" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000001},
- {"add" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000004},
- {"rsb" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000003},
- {"rsc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000007},
- {"sbc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000006},
- {"adc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000005},
- {"sub" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000002},
- {"orr" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000c},
- {"mvn" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000f},
- {"mov" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000d},
- {"stm" , 2 , 0 , 25, 27, 0x00000004, 20, 22, 0x00000004},
- {"ldm" , 4 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000001, 20, 20, 0x00000001, 15, 15, 0x00000001},
- {"ldrsh" , 3 , 2 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000f},
- {"stm" , 3 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000000},
- {"ldm" , 3 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000001},
- {"ldrsb" , 3 , 2 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000d},
- {"strd" , 3 , 4 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000f},
- {"ldrh" , 3 , 0 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000b},
- {"strh" , 3 , 0 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000b},
- {"ldrd" , 3 , 4 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000d},
- {"strt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000002},
- {"strbt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000006},
- {"ldrbt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000007},
- {"ldrt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000003},
- {"mrc" , 3 , 6 , 24, 27, 0x0000000e, 20, 20, 0x00000001, 4, 4, 0x00000001},
- {"mcr" , 3 , 0 , 24, 27, 0x0000000e, 20, 20, 0x00000000, 4, 4, 0x00000001},
- {"msr" , 2 , 0 , 23, 27, 0x00000006, 20, 21, 0x00000002},
- {"ldrb" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000001},
- {"strb" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000000},
- {"ldr" , 4 , 0 , 28, 31, 0x0000000e, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001},
- {"ldrcond" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001},
- {"str" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000000},
- {"cdp" , 2 , 0 , 24, 27, 0x0000000e, 4, 4, 0x00000000},
- {"stc" , 2 , 0 , 25, 27, 0x00000006, 20, 20, 0x00000000},
- {"ldc" , 2 , 0 , 25, 27, 0x00000006, 20, 20, 0x00000001},
- {"swi" , 1 , 0 , 24, 27, 0x0000000f},
- {"bbl" , 1 , 0 , 25, 27, 0x00000005},
+ { "srs", 4, 6, 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d, 8, 11, 0x00000005 },
+ { "rfe", 4, 6, 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001, 8, 11, 0x0000000a },
+ { "bkpt", 2, 3, 20, 31, 0x00000e12, 4, 7, 0x00000007 },
+ { "blx", 1, 3, 25, 31, 0x0000007d },
+ { "cps", 3, 6, 20, 31, 0x00000f10, 16, 16, 0x00000000, 5, 5, 0x00000000 },
+ { "pld", 4, 4, 26, 31, 0x0000003d, 24, 24, 0x00000001, 20, 22, 0x00000005, 12, 15, 0x0000000f },
+ { "setend", 2, 6, 16, 31, 0x0000f101, 4, 7, 0x00000000 },
+ { "clrex", 1, 6, 0, 31, 0xf57ff01f },
+ { "rev16", 2, 6, 16, 27, 0x000006bf, 4, 11, 0x000000fb },
+ { "usad8", 3, 6, 20, 27, 0x00000078, 12, 15, 0x0000000f, 4, 7, 0x00000001 },
+ { "sxtb", 2, 6, 16, 27, 0x000006af, 4, 7, 0x00000007 },
+ { "uxtb", 2, 6, 16, 27, 0x000006ef, 4, 7, 0x00000007 },
+ { "sxth", 2, 6, 16, 27, 0x000006bf, 4, 7, 0x00000007 },
+ { "sxtb16", 2, 6, 16, 27, 0x0000068f, 4, 7, 0x00000007 },
+ { "uxth", 2, 6, 16, 27, 0x000006ff, 4, 7, 0x00000007 },
+ { "uxtb16", 2, 6, 16, 27, 0x000006cf, 4, 7, 0x00000007 },
+ { "cpy", 2, 6, 20, 27, 0x0000001a, 4, 11, 0x00000000 },
+ { "uxtab", 2, 6, 20, 27, 0x0000006e, 4, 9, 0x00000007 },
+ { "ssub8", 2, 6, 20, 27, 0x00000061, 4, 7, 0x0000000f },
+ { "shsub8", 2, 6, 20, 27, 0x00000063, 4, 7, 0x0000000f },
+ { "ssubaddx", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000005 },
+ { "strex", 2, 6, 20, 27, 0x00000018, 4, 7, 0x00000009 },
+ { "strexb", 2, 7, 20, 27, 0x0000001c, 4, 7, 0x00000009 },
+ { "swp", 2, 0, 20, 27, 0x00000010, 4, 7, 0x00000009 },
+ { "swpb", 2, 0, 20, 27, 0x00000014, 4, 7, 0x00000009 },
+ { "ssub16", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000007 },
+ { "ssat16", 2, 6, 20, 27, 0x0000006a, 4, 7, 0x00000003 },
+ { "shsubaddx", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000005 },
+ { "qsubaddx", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000005 },
+ { "shaddsubx", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000003 },
+ { "shadd8", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000009 },
+ { "shadd16", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000001 },
+ { "sel", 2, 6, 20, 27, 0x00000068, 4, 7, 0x0000000b },
+ { "saddsubx", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000003 },
+ { "sadd8", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000009 },
+ { "sadd16", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000001 },
+ { "shsub16", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000007 },
+ { "umaal", 2, 6, 20, 27, 0x00000004, 4, 7, 0x00000009 },
+ { "uxtab16", 2, 6, 20, 27, 0x0000006c, 4, 7, 0x00000007 },
+ { "usubaddx", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000005 },
+ { "usub8", 2, 6, 20, 27, 0x00000065, 4, 7, 0x0000000f },
+ { "usub16", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000007 },
+ { "usat16", 2, 6, 20, 27, 0x0000006e, 4, 7, 0x00000003 },
+ { "usada8", 2, 6, 20, 27, 0x00000078, 4, 7, 0x00000001 },
+ { "uqsubaddx", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000005 },
+ { "uqsub8", 2, 6, 20, 27, 0x00000066, 4, 7, 0x0000000f },
+ { "uqsub16", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000007 },
+ { "uqaddsubx", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000003 },
+ { "uqadd8", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000009 },
+ { "uqadd16", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000001 },
+ { "sxtab", 2, 6, 20, 27, 0x0000006a, 4, 7, 0x00000007 },
+ { "uhsubaddx", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000005 },
+ { "uhsub8", 2, 6, 20, 27, 0x00000067, 4, 7, 0x0000000f },
+ { "uhsub16", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000007 },
+ { "uhaddsubx", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000003 },
+ { "uhadd8", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000009 },
+ { "uhadd16", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000001 },
+ { "uaddsubx", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000003 },
+ { "uadd8", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000009 },
+ { "uadd16", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000001 },
+ { "sxtah", 2, 6, 20, 27, 0x0000006b, 4, 7, 0x00000007 },
+ { "sxtab16", 2, 6, 20, 27, 0x00000068, 4, 7, 0x00000007 },
+ { "qadd8", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000009 },
+ { "bxj", 2, 5, 20, 27, 0x00000012, 4, 7, 0x00000002 },
+ { "clz", 2, 3, 20, 27, 0x00000016, 4, 7, 0x00000001 },
+ { "uxtah", 2, 6, 20, 27, 0x0000006f, 4, 7, 0x00000007 },
+ { "bx", 2, 2, 20, 27, 0x00000012, 4, 7, 0x00000001 },
+ { "rev", 2, 6, 20, 27, 0x0000006b, 4, 7, 0x00000003 },
+ { "blx", 2, 3, 20, 27, 0x00000012, 4, 7, 0x00000003 },
+ { "revsh", 2, 6, 20, 27, 0x0000006f, 4, 7, 0x0000000b },
+ { "qadd", 2, 4, 20, 27, 0x00000010, 4, 7, 0x00000005 },
+ { "qadd16", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000001 },
+ { "qaddsubx", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000003 },
+ { "ldrex", 2, 0, 20, 27, 0x00000019, 4, 7, 0x00000009 },
+ { "qdadd", 2, 4, 20, 27, 0x00000014, 4, 7, 0x00000005 },
+ { "qdsub", 2, 4, 20, 27, 0x00000016, 4, 7, 0x00000005 },
+ { "qsub", 2, 4, 20, 27, 0x00000012, 4, 7, 0x00000005 },
+ { "ldrexb", 2, 7, 20, 27, 0x0000001d, 4, 7, 0x00000009 },
+ { "qsub8", 2, 6, 20, 27, 0x00000062, 4, 7, 0x0000000f },
+ { "qsub16", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000007 },
+ { "smuad", 4, 6, 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001 },
+ { "smmul", 4, 6, 20, 27, 0x00000075, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001 },
+ { "smusd", 4, 6, 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000001, 4, 4, 0x00000001 },
+ { "smlsd", 3, 6, 20, 27, 0x00000070, 6, 7, 0x00000001, 4, 4, 0x00000001 },
+ { "smlsld", 3, 6, 20, 27, 0x00000074, 6, 7, 0x00000001, 4, 4, 0x00000001 },
+ { "smmla", 3, 6, 20, 27, 0x00000075, 6, 7, 0x00000000, 4, 4, 0x00000001 },
+ { "smmls", 3, 6, 20, 27, 0x00000075, 6, 7, 0x00000003, 4, 4, 0x00000001 },
+ { "smlald", 3, 6, 20, 27, 0x00000074, 6, 7, 0x00000000, 4, 4, 0x00000001 },
+ { "smlad", 3, 6, 20, 27, 0x00000070, 6, 7, 0x00000000, 4, 4, 0x00000001 },
+ { "smlaw", 3, 4, 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000000 },
+ { "smulw", 3, 4, 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000002 },
+ { "pkhtb", 2, 6, 20, 27, 0x00000068, 4, 6, 0x00000005 },
+ { "pkhbt", 2, 6, 20, 27, 0x00000068, 4, 6, 0x00000001 },
+ { "smul", 3, 4, 20, 27, 0x00000016, 7, 7, 0x00000001, 4, 4, 0x00000000 },
+ { "smlalxy", 3, 4, 20, 27, 0x00000014, 7, 7, 0x00000001, 4, 4, 0x00000000 },
+ // {"smlal" , 2 , 4 , 21, 27, 0x00000007, 4, 7, 0x00000009},
+ { "smla", 3, 4, 20, 27, 0x00000010, 7, 7, 0x00000001, 4, 4, 0x00000000 },
+ { "mcrr", 1, 6, 20, 27, 0x000000c4 },
+ { "mrrc", 1, 6, 20, 27, 0x000000c5 },
+ { "cmp", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000015 },
+ { "tst", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000011 },
+ { "teq", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000013 },
+ { "cmn", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000017 },
+ { "smull", 2, 0, 21, 27, 0x00000006, 4, 7, 0x00000009 },
+ { "umull", 2, 0, 21, 27, 0x00000004, 4, 7, 0x00000009 },
+ { "umlal", 2, 0, 21, 27, 0x00000005, 4, 7, 0x00000009 },
+ { "smlal", 2, 0, 21, 27, 0x00000007, 4, 7, 0x00000009 },
+ { "mul", 2, 0, 21, 27, 0x00000000, 4, 7, 0x00000009 },
+ { "mla", 2, 0, 21, 27, 0x00000001, 4, 7, 0x00000009 },
+ { "ssat", 2, 6, 21, 27, 0x00000035, 4, 5, 0x00000001 },
+ { "usat", 2, 6, 21, 27, 0x00000037, 4, 5, 0x00000001 },
+ { "mrs", 4, 0, 23, 27, 0x00000002, 20, 21, 0x00000000, 16, 19, 0x0000000f, 0, 11, 0x00000000 },
+ { "msr", 3, 0, 23, 27, 0x00000002, 20, 21, 0x00000002, 4, 7, 0x00000000 },
+ { "and", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000000 },
+ { "bic", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000e },
+ { "ldm", 3, 0, 25, 27, 0x00000004, 20, 22, 0x00000005, 15, 15, 0x00000000 },
+ { "eor", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000001 },
+ { "add", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000004 },
+ { "rsb", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000003 },
+ { "rsc", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000007 },
+ { "sbc", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000006 },
+ { "adc", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000005 },
+ { "sub", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000002 },
+ { "orr", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000c },
+ { "mvn", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000f },
+ { "mov", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000d },
+ { "stm", 2, 0, 25, 27, 0x00000004, 20, 22, 0x00000004 },
+ { "ldm", 4, 0, 25, 27, 0x00000004, 22, 22, 0x00000001, 20, 20, 0x00000001, 15, 15, 0x00000001 },
+ { "ldrsh", 3, 2, 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000f },
+ { "stm", 3, 0, 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000000 },
+ { "ldm", 3, 0, 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000001 },
+ { "ldrsb", 3, 2, 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000d },
+ { "strd", 3, 4, 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000f },
+ { "ldrh", 3, 0, 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000b },
+ { "strh", 3, 0, 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000b },
+ { "ldrd", 3, 4, 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000d },
+ { "strt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000002 },
+ { "strbt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000006 },
+ { "ldrbt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000007 },
+ { "ldrt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000003 },
+ { "mrc", 3, 6, 24, 27, 0x0000000e, 20, 20, 0x00000001, 4, 4, 0x00000001 },
+ { "mcr", 3, 0, 24, 27, 0x0000000e, 20, 20, 0x00000000, 4, 4, 0x00000001 },
+ { "msr", 2, 0, 23, 27, 0x00000006, 20, 21, 0x00000002 },
+ { "ldrb", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000001 },
+ { "strb", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000000 },
+ { "ldr", 4, 0, 28, 31, 0x0000000e, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001 },
+ { "ldrcond", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001 },
+ { "str", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000000 },
+ { "cdp", 2, 0, 24, 27, 0x0000000e, 4, 4, 0x00000000 },
+ { "stc", 2, 0, 25, 27, 0x00000006, 20, 20, 0x00000000 },
+ { "ldc", 2, 0, 25, 27, 0x00000006, 20, 20, 0x00000001 },
+ { "swi", 1, 0, 24, 27, 0x0000000f },
+ { "bbl", 1, 0, 25, 27, 0x00000005 },
};
const ISEITEM arm_exclusion_code[] = {
- {"vmla", 0, ARMVFP2, 0},
- {"vmls", 0, ARMVFP2, 0},
- {"vnmla", 0, ARMVFP2, 0},
- {"vnmla", 0, ARMVFP2, 0},
- {"vnmls", 0, ARMVFP2, 0},
- {"vnmul", 0, ARMVFP2, 0},
- {"vmul", 0, ARMVFP2, 0},
- {"vadd", 0, ARMVFP2, 0},
- {"vsub", 0, ARMVFP2, 0},
- {"vdiv", 0, ARMVFP2, 0},
- {"vmov(i)", 0, ARMVFP3, 0},
- {"vmov(r)", 0, ARMVFP3, 0},
- {"vabs", 0, ARMVFP2, 0},
- {"vneg", 0, ARMVFP2, 0},
- {"vsqrt", 0, ARMVFP2, 0},
- {"vcmp", 0, ARMVFP2, 0},
- {"vcmp2", 0, ARMVFP2, 0},
- {"vcvt(bff)", 0, ARMVFP3, 4, 4, 1},
- {"vcvt(bds)", 0, ARMVFP2, 0},
- {"vcvt(bfi)", 0, ARMVFP2, 0},
- {"vmovbrs", 0, ARMVFP2, 0},
- {"vmsr", 0, ARMVFP2, 0},
- {"vmovbrc", 0, ARMVFP2, 0},
- {"vmrs", 0, ARMVFP2, 0},
- {"vmovbcr", 0, ARMVFP2, 0},
- {"vmovbrrss", 0, ARMVFP2, 0},
- {"vmovbrrd", 0, ARMVFP2, 0},
- {"vstr", 0, ARMVFP2, 0},
- {"vpush", 0, ARMVFP2, 0},
- {"vstm", 0, ARMVFP2, 0},
- {"vpop", 0, ARMVFP2, 0},
- {"vldr", 0, ARMVFP2, 0},
- {"vldm", 0, ARMVFP2, 0},
+ { "vmla", 0, ARMVFP2, 0 },
+ { "vmls", 0, ARMVFP2, 0 },
+ { "vnmla", 0, ARMVFP2, 0 },
+ { "vnmla", 0, ARMVFP2, 0 },
+ { "vnmls", 0, ARMVFP2, 0 },
+ { "vnmul", 0, ARMVFP2, 0 },
+ { "vmul", 0, ARMVFP2, 0 },
+ { "vadd", 0, ARMVFP2, 0 },
+ { "vsub", 0, ARMVFP2, 0 },
+ { "vdiv", 0, ARMVFP2, 0 },
+ { "vmov(i)", 0, ARMVFP3, 0 },
+ { "vmov(r)", 0, ARMVFP3, 0 },
+ { "vabs", 0, ARMVFP2, 0 },
+ { "vneg", 0, ARMVFP2, 0 },
+ { "vsqrt", 0, ARMVFP2, 0 },
+ { "vcmp", 0, ARMVFP2, 0 },
+ { "vcmp2", 0, ARMVFP2, 0 },
+ { "vcvt(bff)", 0, ARMVFP3, 4, 4, 1 },
+ { "vcvt(bds)", 0, ARMVFP2, 0 },
+ { "vcvt(bfi)", 0, ARMVFP2, 0 },
+ { "vmovbrs", 0, ARMVFP2, 0 },
+ { "vmsr", 0, ARMVFP2, 0 },
+ { "vmovbrc", 0, ARMVFP2, 0 },
+ { "vmrs", 0, ARMVFP2, 0 },
+ { "vmovbcr", 0, ARMVFP2, 0 },
+ { "vmovbrrss", 0, ARMVFP2, 0 },
+ { "vmovbrrd", 0, ARMVFP2, 0 },
+ { "vstr", 0, ARMVFP2, 0 },
+ { "vpush", 0, ARMVFP2, 0 },
+ { "vstm", 0, ARMVFP2, 0 },
+ { "vpop", 0, ARMVFP2, 0 },
+ { "vldr", 0, ARMVFP2, 0 },
+ { "vldm", 0, ARMVFP2, 0 },
- {"srs" , 0 , 6 , 0},
- {"rfe" , 0 , 6 , 0},
- {"bkpt" , 0 , 3 , 0},
- {"blx" , 0 , 3 , 0},
- {"cps" , 0 , 6 , 0},
- {"pld" , 0 , 4 , 0},
- {"setend" , 0 , 6 , 0},
- {"clrex" , 0 , 6 , 0},
- {"rev16" , 0 , 6 , 0},
- {"usad8" , 0 , 6 , 0},
- {"sxtb" , 0 , 6 , 0},
- {"uxtb" , 0 , 6 , 0},
- {"sxth" , 0 , 6 , 0},
- {"sxtb16" , 0 , 6 , 0},
- {"uxth" , 0 , 6 , 0},
- {"uxtb16" , 0 , 6 , 0},
- {"cpy" , 0 , 6 , 0},
- {"uxtab" , 0 , 6 , 0},
- {"ssub8" , 0 , 6 , 0},
- {"shsub8" , 0 , 6 , 0},
- {"ssubaddx" , 0 , 6 , 0},
- {"strex" , 0 , 6 , 0},
- {"strexb" , 0 , 7 , 0},
- {"swp" , 0 , 0 , 0},
- {"swpb" , 0 , 0 , 0},
- {"ssub16" , 0 , 6 , 0},
- {"ssat16" , 0 , 6 , 0},
- {"shsubaddx" , 0 , 6 , 0},
- {"qsubaddx" , 0 , 6 , 0},
- {"shaddsubx" , 0 , 6 , 0},
- {"shadd8" , 0 , 6 , 0},
- {"shadd16" , 0 , 6 , 0},
- {"sel" , 0 , 6 , 0},
- {"saddsubx" , 0 , 6 , 0},
- {"sadd8" , 0 , 6 , 0},
- {"sadd16" , 0 , 6 , 0},
- {"shsub16" , 0 , 6 , 0},
- {"umaal" , 0 , 6 , 0},
- {"uxtab16" , 0 , 6 , 0},
- {"usubaddx" , 0 , 6 , 0},
- {"usub8" , 0 , 6 , 0},
- {"usub16" , 0 , 6 , 0},
- {"usat16" , 0 , 6 , 0},
- {"usada8" , 0 , 6 , 0},
- {"uqsubaddx" , 0 , 6 , 0},
- {"uqsub8" , 0 , 6 , 0},
- {"uqsub16" , 0 , 6 , 0},
- {"uqaddsubx" , 0 , 6 , 0},
- {"uqadd8" , 0 , 6 , 0},
- {"uqadd16" , 0 , 6 , 0},
- {"sxtab" , 0 , 6 , 0},
- {"uhsubaddx" , 0 , 6 , 0},
- {"uhsub8" , 0 , 6 , 0},
- {"uhsub16" , 0 , 6 , 0},
- {"uhaddsubx" , 0 , 6 , 0},
- {"uhadd8" , 0 , 6 , 0},
- {"uhadd16" , 0 , 6 , 0},
- {"uaddsubx" , 0 , 6 , 0},
- {"uadd8" , 0 , 6 , 0},
- {"uadd16" , 0 , 6 , 0},
- {"sxtah" , 0 , 6 , 0},
- {"sxtab16" , 0 , 6 , 0},
- {"qadd8" , 0 , 6 , 0},
- {"bxj" , 0 , 5 , 0},
- {"clz" , 0 , 3 , 0},
- {"uxtah" , 0 , 6 , 0},
- {"bx" , 0 , 2 , 0},
- {"rev" , 0 , 6 , 0},
- {"blx" , 0 , 3 , 0},
- {"revsh" , 0 , 6 , 0},
- {"qadd" , 0 , 4 , 0},
- {"qadd16" , 0 , 6 , 0},
- {"qaddsubx" , 0 , 6 , 0},
- {"ldrex" , 0 , 0 , 0},
- {"qdadd" , 0 , 4 , 0},
- {"qdsub" , 0 , 4 , 0},
- {"qsub" , 0 , 4 , 0},
- {"ldrexb" , 0 , 7 , 0},
- {"qsub8" , 0 , 6 , 0},
- {"qsub16" , 0 , 6 , 0},
- {"smuad" , 0 , 6 , 0},
- {"smmul" , 0 , 6 , 0},
- {"smusd" , 0 , 6 , 0},
- {"smlsd" , 0 , 6 , 0},
- {"smlsld" , 0 , 6 , 0},
- {"smmla" , 0 , 6 , 0},
- {"smmls" , 0 , 6 , 0},
- {"smlald" , 0 , 6 , 0},
- {"smlad" , 0 , 6 , 0},
- {"smlaw" , 0 , 4 , 0},
- {"smulw" , 0 , 4 , 0},
- {"pkhtb" , 0 , 6 , 0},
- {"pkhbt" , 0 , 6 , 0},
- {"smul" , 0 , 4 , 0},
- {"smlal" , 0 , 4 , 0},
- {"smla" , 0 , 4 , 0},
- {"mcrr" , 0 , 6 , 0},
- {"mrrc" , 0 , 6 , 0},
- {"cmp" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
- {"tst" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
- {"teq" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
- {"cmn" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
- {"smull" , 0 , 0 , 0},
- {"umull" , 0 , 0 , 0},
- {"umlal" , 0 , 0 , 0},
- {"smlal" , 0 , 0 , 0},
- {"mul" , 0 , 0 , 0},
- {"mla" , 0 , 0 , 0},
- {"ssat" , 0 , 6 , 0},
- {"usat" , 0 , 6 , 0},
- {"mrs" , 0 , 0 , 0},
- {"msr" , 0 , 0 , 0},
- {"and" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
- {"bic" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
- {"ldm" , 0 , 0 , 0},
- {"eor" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
- {"add" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
- {"rsb" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
- {"rsc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
- {"sbc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
- {"adc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
- {"sub" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
- {"orr" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
- {"mvn" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
- {"mov" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
- {"stm" , 0 , 0 , 0},
- {"ldm" , 0 , 0 , 0},
- {"ldrsh" , 0 , 2 , 0},
- {"stm" , 0 , 0 , 0},
- {"ldm" , 0 , 0 , 0},
- {"ldrsb" , 0 , 2 , 0},
- {"strd" , 0 , 4 , 0},
- {"ldrh" , 0 , 0 , 0},
- {"strh" , 0 , 0 , 0},
- {"ldrd" , 0 , 4 , 0},
- {"strt" , 0 , 0 , 0},
- {"strbt" , 0 , 0 , 0},
- {"ldrbt" , 0 , 0 , 0},
- {"ldrt" , 0 , 0 , 0},
- {"mrc" , 0 , 6 , 0},
- {"mcr" , 0 , 0 , 0},
- {"msr" , 0 , 0 , 0},
- {"ldrb" , 0 , 0 , 0},
- {"strb" , 0 , 0 , 0},
- {"ldr" , 0 , 0 , 0},
- {"ldrcond" , 1 , 0 , 28, 31, 0x0000000e},
- {"str" , 0 , 0 , 0},
- {"cdp" , 0 , 0 , 0},
- {"stc" , 0 , 0 , 0},
- {"ldc" , 0 , 0 , 0},
- {"swi" , 0 , 0 , 0},
- {"bbl" , 0 , 0 , 0},
- {"bl_1_thumb", 0, INVALID, 0},/* should be table[-4] */
- {"bl_2_thumb", 0, INVALID, 0}, /* should be located at the end of the table[-3] */
- {"blx_1_thumb", 0, INVALID, 0}, /* should be located at table[-2] */
- {"invalid", 0, INVALID, 0}
+ { "srs", 0, 6, 0 },
+ { "rfe", 0, 6, 0 },
+ { "bkpt", 0, 3, 0 },
+ { "blx", 0, 3, 0 },
+ { "cps", 0, 6, 0 },
+ { "pld", 0, 4, 0 },
+ { "setend", 0, 6, 0 },
+ { "clrex", 0, 6, 0 },
+ { "rev16", 0, 6, 0 },
+ { "usad8", 0, 6, 0 },
+ { "sxtb", 0, 6, 0 },
+ { "uxtb", 0, 6, 0 },
+ { "sxth", 0, 6, 0 },
+ { "sxtb16", 0, 6, 0 },
+ { "uxth", 0, 6, 0 },
+ { "uxtb16", 0, 6, 0 },
+ { "cpy", 0, 6, 0 },
+ { "uxtab", 0, 6, 0 },
+ { "ssub8", 0, 6, 0 },
+ { "shsub8", 0, 6, 0 },
+ { "ssubaddx", 0, 6, 0 },
+ { "strex", 0, 6, 0 },
+ { "strexb", 0, 7, 0 },
+ { "swp", 0, 0, 0 },
+ { "swpb", 0, 0, 0 },
+ { "ssub16", 0, 6, 0 },
+ { "ssat16", 0, 6, 0 },
+ { "shsubaddx", 0, 6, 0 },
+ { "qsubaddx", 0, 6, 0 },
+ { "shaddsubx", 0, 6, 0 },
+ { "shadd8", 0, 6, 0 },
+ { "shadd16", 0, 6, 0 },
+ { "sel", 0, 6, 0 },
+ { "saddsubx", 0, 6, 0 },
+ { "sadd8", 0, 6, 0 },
+ { "sadd16", 0, 6, 0 },
+ { "shsub16", 0, 6, 0 },
+ { "umaal", 0, 6, 0 },
+ { "uxtab16", 0, 6, 0 },
+ { "usubaddx", 0, 6, 0 },
+ { "usub8", 0, 6, 0 },
+ { "usub16", 0, 6, 0 },
+ { "usat16", 0, 6, 0 },
+ { "usada8", 0, 6, 0 },
+ { "uqsubaddx", 0, 6, 0 },
+ { "uqsub8", 0, 6, 0 },
+ { "uqsub16", 0, 6, 0 },
+ { "uqaddsubx", 0, 6, 0 },
+ { "uqadd8", 0, 6, 0 },
+ { "uqadd16", 0, 6, 0 },
+ { "sxtab", 0, 6, 0 },
+ { "uhsubaddx", 0, 6, 0 },
+ { "uhsub8", 0, 6, 0 },
+ { "uhsub16", 0, 6, 0 },
+ { "uhaddsubx", 0, 6, 0 },
+ { "uhadd8", 0, 6, 0 },
+ { "uhadd16", 0, 6, 0 },
+ { "uaddsubx", 0, 6, 0 },
+ { "uadd8", 0, 6, 0 },
+ { "uadd16", 0, 6, 0 },
+ { "sxtah", 0, 6, 0 },
+ { "sxtab16", 0, 6, 0 },
+ { "qadd8", 0, 6, 0 },
+ { "bxj", 0, 5, 0 },
+ { "clz", 0, 3, 0 },
+ { "uxtah", 0, 6, 0 },
+ { "bx", 0, 2, 0 },
+ { "rev", 0, 6, 0 },
+ { "blx", 0, 3, 0 },
+ { "revsh", 0, 6, 0 },
+ { "qadd", 0, 4, 0 },
+ { "qadd16", 0, 6, 0 },
+ { "qaddsubx", 0, 6, 0 },
+ { "ldrex", 0, 0, 0 },
+ { "qdadd", 0, 4, 0 },
+ { "qdsub", 0, 4, 0 },
+ { "qsub", 0, 4, 0 },
+ { "ldrexb", 0, 7, 0 },
+ { "qsub8", 0, 6, 0 },
+ { "qsub16", 0, 6, 0 },
+ { "smuad", 0, 6, 0 },
+ { "smmul", 0, 6, 0 },
+ { "smusd", 0, 6, 0 },
+ { "smlsd", 0, 6, 0 },
+ { "smlsld", 0, 6, 0 },
+ { "smmla", 0, 6, 0 },
+ { "smmls", 0, 6, 0 },
+ { "smlald", 0, 6, 0 },
+ { "smlad", 0, 6, 0 },
+ { "smlaw", 0, 4, 0 },
+ { "smulw", 0, 4, 0 },
+ { "pkhtb", 0, 6, 0 },
+ { "pkhbt", 0, 6, 0 },
+ { "smul", 0, 4, 0 },
+ { "smlal", 0, 4, 0 },
+ { "smla", 0, 4, 0 },
+ { "mcrr", 0, 6, 0 },
+ { "mrrc", 0, 6, 0 },
+ { "cmp", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
+ { "tst", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
+ { "teq", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
+ { "cmn", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
+ { "smull", 0, 0, 0 },
+ { "umull", 0, 0, 0 },
+ { "umlal", 0, 0, 0 },
+ { "smlal", 0, 0, 0 },
+ { "mul", 0, 0, 0 },
+ { "mla", 0, 0, 0 },
+ { "ssat", 0, 6, 0 },
+ { "usat", 0, 6, 0 },
+ { "mrs", 0, 0, 0 },
+ { "msr", 0, 0, 0 },
+ { "and", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
+ { "bic", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
+ { "ldm", 0, 0, 0 },
+ { "eor", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
+ { "add", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
+ { "rsb", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
+ { "rsc", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
+ { "sbc", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
+ { "adc", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
+ { "sub", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
+ { "orr", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
+ { "mvn", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
+ { "mov", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 },
+ { "stm", 0, 0, 0 },
+ { "ldm", 0, 0, 0 },
+ { "ldrsh", 0, 2, 0 },
+ { "stm", 0, 0, 0 },
+ { "ldm", 0, 0, 0 },
+ { "ldrsb", 0, 2, 0 },
+ { "strd", 0, 4, 0 },
+ { "ldrh", 0, 0, 0 },
+ { "strh", 0, 0, 0 },
+ { "ldrd", 0, 4, 0 },
+ { "strt", 0, 0, 0 },
+ { "strbt", 0, 0, 0 },
+ { "ldrbt", 0, 0, 0 },
+ { "ldrt", 0, 0, 0 },
+ { "mrc", 0, 6, 0 },
+ { "mcr", 0, 0, 0 },
+ { "msr", 0, 0, 0 },
+ { "ldrb", 0, 0, 0 },
+ { "strb", 0, 0, 0 },
+ { "ldr", 0, 0, 0 },
+ { "ldrcond", 1, 0, 28, 31, 0x0000000e },
+ { "str", 0, 0, 0 },
+ { "cdp", 0, 0, 0 },
+ { "stc", 0, 0, 0 },
+ { "ldc", 0, 0, 0 },
+ { "swi", 0, 0, 0 },
+ { "bbl", 0, 0, 0 },
+ { "bl_1_thumb", 0, INVALID, 0 }, // Should be table[-4]
+ { "bl_2_thumb", 0, INVALID, 0 }, // Should be located at the end of the table[-3]
+ { "blx_1_thumb", 0, INVALID, 0 }, // Should be located at table[-2]
+ { "invalid", 0, INVALID, 0 }
};
-int decode_arm_instr(uint32_t instr, int32_t *idx)
-{
- int n = 0;
- int base = 0;
- int ret = DECODE_FAILURE;
- int i = 0;
- int instr_slots = sizeof(arm_instruction)/sizeof(ISEITEM);
- for (i = 0; i < instr_slots; i++)
- {
-// ret = DECODE_SUCCESS;
- n = arm_instruction[i].attribute_value;
- base = 0;
- while (n) {
- if (arm_instruction[i].content[base + 1] == 31 && arm_instruction[i].content[base] == 0) {
- /* clrex */
- if (instr != arm_instruction[i].content[base + 2]) {
- break;
- }
- } else if (BITS(arm_instruction[i].content[base], arm_instruction[i].content[base + 1]) != arm_instruction[i].content[base + 2]) {
- break;
- }
- base += 3;
- n --;
- }
- //All conditions is satisfied.
- if (n == 0)
- ret = DECODE_SUCCESS;
+int decode_arm_instr(uint32_t instr, int32_t *idx) {
+ int n = 0;
+ int base = 0;
+ int ret = DECODE_FAILURE;
+ int i = 0;
+ int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM);
+ for (i = 0; i < instr_slots; i++) {
+ n = arm_instruction[i].attribute_value;
+ base = 0;
- if (ret == DECODE_SUCCESS) {
- n = arm_exclusion_code[i].attribute_value;
- if (n != 0) {
- base = 0;
- while (n) {
- if (BITS(arm_exclusion_code[i].content[base], arm_exclusion_code[i].content[base + 1]) != arm_exclusion_code[i].content[base + 2]) {
- break; }
- base += 3;
- n --;
- }
- //All conditions is satisfied.
- if (n == 0)
- ret = DECODE_FAILURE;
- }
- }
+ while (n) {
+ if (arm_instruction[i].content[base + 1] == 31 && arm_instruction[i].content[base] == 0) {
+ // clrex
+ if (instr != arm_instruction[i].content[base + 2]) {
+ break;
+ }
+ } else if (BITS(arm_instruction[i].content[base], arm_instruction[i].content[base + 1]) != arm_instruction[i].content[base + 2]) {
+ break;
+ }
+ base += 3;
+ n--;
+ }
- if (ret == DECODE_SUCCESS) {
- *idx = i;
- return ret;
- }
- }
- return ret;
-}
+ // All conditions is satisfied.
+ if (n == 0)
+ ret = DECODE_SUCCESS;
+
+ if (ret == DECODE_SUCCESS) {
+ n = arm_exclusion_code[i].attribute_value;
+ if (n != 0) {
+ base = 0;
+ while (n) {
+ if (BITS(arm_exclusion_code[i].content[base], arm_exclusion_code[i].content[base + 1]) != arm_exclusion_code[i].content[base + 2]) {
+ break;
+ }
+ base += 3;
+ n--;
+ }
+ // All conditions is satisfied.
+ if (n == 0)
+ ret = DECODE_FAILURE;
+ }
+ }
+
+ if (ret == DECODE_SUCCESS) {
+ *idx = i;
+ return ret;
+ }
+ }
+ return ret;
+}
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index f58b4731a..0ee103c56 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -1,27 +1,6 @@
-/* Copyright (C)
-* 2012 - Michael.Kang blackfin.kang@gmail.com
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-*/
-/**
-* @file arm_dyncom_interpreter.cpp
-* @brief The fast interpreter for arm
-* @author Michael.Kang blackfin.kang@gmail.com
-* @version 7849
-* @date 2012-03-15
-*/
+// Copyright 2012 Michael Kang, 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
#define CITRA_IGNORE_EXIT(x)
@@ -39,10 +18,6 @@ using namespace std;
#include "arm_dyncom_thumb.h"
#include "arm_dyncom_run.h"
#include "core/arm/skyeye_common/vfp/vfp.h"
-/* shenoubang 2012-6-14 */
-#ifdef __WIN32__
-#include "bank_defs.h"
-#endif
#include "core/mem_map.h"
#include "core/hle/hle.h"
@@ -58,325 +33,243 @@ enum {
THUMB = (1 << 7)
};
-#define USER_MODE_OPT 1
-#define HYBRID_MODE 0 // Enable for JIT mode
+#define USER_MODE_OPT 1
+#define HYBRID_MODE 0 // Enable for JIT mode
-#define THRESHOLD 1000
-#define DURATION 500
-//#define PRINT_PROFILE_INFO
+#define THRESHOLD 1000
+#define DURATION 500
-#define CHECK_RS if(RS == 15) rs += 8
-#define CHECK_RM if(RM == 15) rm += 8
+#define CHECK_RS if(RS == 15) rs += 8
+#define CHECK_RM if(RM == 15) rm += 8
-//#define BITS(s, a, b) (((s) >> (a)) & ((1 << (1 + (b) - (a))) - 1))
#undef BITS
#define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1))
#define BIT(s, n) ((s >> (n)) & 1)
-#define RM BITS(sht_oper, 0, 3)
-#define RS BITS(sht_oper, 8, 11)
-
-#define glue(x, y) x ## y
-#define DPO(s) glue(DataProcessingOperands, s)
-#define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i))
-#define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i))
-#define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32)
-#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32)
-
-//#define rotr(x,n) ((((x)>>(n))&((1<<(sizeof(x) * 8)-1))|(x<<(sizeof(x)*8-n))))
-//#define rotl(x,n) ((((x)<<(n))&(-(1<<(n))))|(((x)>>(sizeof(x)*8-n))&((1<<(n))-1)))
+#define RM BITS(sht_oper, 0, 3)
+#define RS BITS(sht_oper, 8, 11)
+
+#define glue(x, y) x ## y
+#define DPO(s) glue(DataProcessingOperands, s)
+#define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i))
+#define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i))
+#define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32)
+#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32)
+
#define rotr(x,n) ( (x >> n) | ((x & ((1 << (n + 1)) - 1)) << (32 - n)) )
extern void switch_mode(arm_core_t *core, uint32_t mode);
-//extern bool InAPrivilegedMode(arm_core_t *core);
typedef arm_core_t arm_processor;
typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper);
-/* exclusive memory access */
+// Exclusive memory access
static int exclusive_detect(ARMul_State* state, ARMword addr){
- #if 0
- for(int i = 0; i < 128; i++){
- if(state->exclusive_tag_array[i] == addr)
- return 0;
- }
- #endif
- if(state->exclusive_tag == addr)
- return 0;
- else
- return -1;
+ if(state->exclusive_tag == addr)
+ return 0;
+ else
+ return -1;
}
static void add_exclusive_addr(ARMul_State* state, ARMword addr){
- #if 0
- for(int i = 0; i < 128; i++){
- if(state->exclusive_tag_array[i] == 0xffffffff){
- state->exclusive_tag_array[i] = addr;
- //DEBUG_LOG(ARM11, "In %s, add addr 0x%x\n", __func__, addr);
- return;
- }
- }
- DEBUG_LOG(ARM11, "In %s ,can not monitor the addr, out of array\n", __FUNCTION__);
- #endif
- state->exclusive_tag = addr;
- return;
+ state->exclusive_tag = addr;
+ return;
}
static void remove_exclusive(ARMul_State* state, ARMword addr){
- #if 0
- int i;
- for(i = 0; i < 128; i++){
- if(state->exclusive_tag_array[i] == addr){
- state->exclusive_tag_array[i] = 0xffffffff;
- //DEBUG_LOG(ARM11, "In %s, remove addr 0x%x\n", __func__, addr);
- return;
- }
- }
- #endif
- state->exclusive_tag = 0xFFFFFFFF;
-}
-
-
-unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper)
-{
-// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
- unsigned int immed_8 = BITS(sht_oper, 0, 7);
- unsigned int rotate_imm = BITS(sht_oper, 8, 11);
-// DEBUG_LOG(ARM11, "immed_8 is %x\n", immed_8);
-// DEBUG_LOG(ARM11, "rotate_imm is %x\n", rotate_imm);
- unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2);//ROTATE_RIGHT_32(immed_8, rotate_imm * 2);
-// DEBUG_LOG(ARM11, "shifter_operand : %x\n", shifter_operand);
- /* set c flag */
- if (rotate_imm == 0)
- cpu->shifter_carry_out = cpu->CFlag;
- else
- cpu->shifter_carry_out = BIT(shifter_operand, 31);
- return shifter_operand;
-}
-
-unsigned int DPO(Register)(arm_processor *cpu, unsigned int sht_oper)
-{
-// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- //if (RM == 15) rm += 8;
- unsigned int shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- return shifter_operand;
+ state->exclusive_tag = 0xFFFFFFFF;
+}
+
+
+unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) {
+ unsigned int immed_8 = BITS(sht_oper, 0, 7);
+ unsigned int rotate_imm = BITS(sht_oper, 8, 11);
+ unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2);
+ if (rotate_imm == 0)
+ cpu->shifter_carry_out = cpu->CFlag;
+ else
+ cpu->shifter_carry_out = BIT(shifter_operand, 31);
+ return shifter_operand;
+}
+
+unsigned int DPO(Register)(arm_processor *cpu, unsigned int sht_oper) {
+ unsigned int rm = CHECK_READ_REG15(cpu, RM);
+ unsigned int shifter_operand = rm;
+ cpu->shifter_carry_out = cpu->CFlag;
+ return shifter_operand;
+}
+
+unsigned int DPO(LogicalShiftLeftByImmediate)(arm_processor *cpu, unsigned int sht_oper) {
+ int shift_imm = BITS(sht_oper, 7, 11);
+ unsigned int rm = CHECK_READ_REG15(cpu, RM);
+ unsigned int shifter_operand;
+ if (shift_imm == 0) {
+ shifter_operand = rm;
+ cpu->shifter_carry_out = cpu->CFlag;
+ } else {
+ shifter_operand = rm << shift_imm;
+ cpu->shifter_carry_out = BIT(rm, 32 - shift_imm);
+ }
+ return shifter_operand;
+}
+
+unsigned int DPO(LogicalShiftLeftByRegister)(arm_processor *cpu, unsigned int sht_oper) {
+ int shifter_operand;
+ unsigned int rm = CHECK_READ_REG15(cpu, RM);
+ unsigned int rs = CHECK_READ_REG15(cpu, RS);
+ if (BITS(rs, 0, 7) == 0) {
+ shifter_operand = rm;
+ cpu->shifter_carry_out = cpu->CFlag;
+ } else if (BITS(rs, 0, 7) < 32) {
+ shifter_operand = rm << BITS(rs, 0, 7);
+ cpu->shifter_carry_out = BIT(rm, 32 - BITS(rs, 0, 7));
+ } else if (BITS(rs, 0, 7) == 32) {
+ shifter_operand = 0;
+ cpu->shifter_carry_out = BIT(rm, 0);
+ } else {
+ shifter_operand = 0;
+ cpu->shifter_carry_out = 0;
+ }
+ return shifter_operand;
+}
+
+unsigned int DPO(LogicalShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) {
+ unsigned int rm = CHECK_READ_REG15(cpu, RM);
+ unsigned int shifter_operand;
+ int shift_imm = BITS(sht_oper, 7, 11);
+ if (shift_imm == 0) {
+ shifter_operand = 0;
+ cpu->shifter_carry_out = BIT(rm, 31);
+ } else {
+ shifter_operand = rm >> shift_imm;
+ cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
+ }
+ return shifter_operand;
+}
+
+unsigned int DPO(LogicalShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper) {
+ unsigned int rs = CHECK_READ_REG15(cpu, RS);
+ unsigned int rm = CHECK_READ_REG15(cpu, RM);
+ unsigned int shifter_operand;
+ if (BITS(rs, 0, 7) == 0) {
+ shifter_operand = rm;
+ cpu->shifter_carry_out = cpu->CFlag;
+ } else if (BITS(rs, 0, 7) < 32) {
+ shifter_operand = rm >> BITS(rs, 0, 7);
+ cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
+ } else if (BITS(rs, 0, 7) == 32) {
+ shifter_operand = 0;
+ cpu->shifter_carry_out = BIT(rm, 31);
+ } else {
+ shifter_operand = 0;
+ cpu->shifter_carry_out = 0;
+ }
+ return shifter_operand;
+}
+
+unsigned int DPO(ArithmeticShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) {
+ unsigned int rm = CHECK_READ_REG15(cpu, RM);
+ unsigned int shifter_operand;
+ int shift_imm = BITS(sht_oper, 7, 11);
+ if (shift_imm == 0) {
+ if (BIT(rm, 31)) {
+ shifter_operand = 0;
+ cpu->shifter_carry_out = BIT(rm, 31);
+ } else {
+ shifter_operand = 0xFFFFFFFF;
+ cpu->shifter_carry_out = BIT(rm, 31);
+ }
+ } else {
+ shifter_operand = static_cast<int>(rm) >> shift_imm;
+ cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
+ }
+ return shifter_operand;
+}
+
+unsigned int DPO(ArithmeticShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper) {
+ unsigned int rs = CHECK_READ_REG15(cpu, RS);
+ unsigned int rm = CHECK_READ_REG15(cpu, RM);
+ unsigned int shifter_operand;
+ if (BITS(rs, 0, 7) == 0) {
+ shifter_operand = rm;
+ cpu->shifter_carry_out = cpu->CFlag;
+ } else if (BITS(rs, 0, 7) < 32) {
+ shifter_operand = static_cast<int>(rm) >> BITS(rs, 0, 7);
+ cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
+ } else {
+ if (BIT(rm, 31) == 0)
+ shifter_operand = 0;
+ else
+ shifter_operand = 0xffffffff;
+ cpu->shifter_carry_out = BIT(rm, 31);
+ }
+ return shifter_operand;
+}
+
+unsigned int DPO(RotateRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) {
+ unsigned int shifter_operand;
+ unsigned int rm = CHECK_READ_REG15(cpu, RM);
+ int shift_imm = BITS(sht_oper, 7, 11);
+ if (shift_imm == 0) {
+ shifter_operand = (cpu->CFlag << 31) | (rm >> 1);
+ cpu->shifter_carry_out = BIT(rm, 0);
+ } else {
+ shifter_operand = ROTATE_RIGHT_32(rm, shift_imm);
+ cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
+ }
+ return shifter_operand;
+}
+
+unsigned int DPO(RotateRightByRegister)(arm_processor *cpu, unsigned int sht_oper) {
+ unsigned int rm = CHECK_READ_REG15(cpu, RM);
+ unsigned int rs = CHECK_READ_REG15(cpu, RS);
+ unsigned int shifter_operand;
+ if (BITS(rs, 0, 7) == 0) {
+ shifter_operand = rm;
+ cpu->shifter_carry_out = cpu->CFlag;
+ } else if (BITS(rs, 0, 4) == 0) {
+ shifter_operand = rm;
+ cpu->shifter_carry_out = BIT(rm, 31);
+ } else {
+ shifter_operand = ROTATE_RIGHT_32(rm, BITS(rs, 0, 4));
+ cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 4) - 1);
+ }
+ return shifter_operand;
}
-unsigned int DPO(LogicalShiftLeftByImmediate)(arm_processor *cpu, unsigned int sht_oper)
-{
-// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
- int shift_imm = BITS(sht_oper, 7, 11);
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- //if (RM == 15) rm += 8;
- unsigned int shifter_operand;
- if (shift_imm == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- } else {
- shifter_operand = rm << shift_imm;
- cpu->shifter_carry_out = BIT(rm, 32 - shift_imm);
- }
- return shifter_operand;
-}
-
-unsigned int DPO(LogicalShiftLeftByRegister)(arm_processor *cpu, unsigned int sht_oper)
-{
-// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
- int shifter_operand;
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- unsigned int rs = CHECK_READ_REG15(cpu, RS);
- //if (RM == 15) rm += 8;
- //if (RS == 15) rs += 8;
- if (BITS(rs, 0, 7) == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- } else if (BITS(rs, 0, 7) < 32) {
- shifter_operand = rm << BITS(rs, 0, 7);
- cpu->shifter_carry_out = BIT(rm, 32 - BITS(rs, 0, 7));
- } else if (BITS(rs, 0, 7) == 32) {
- shifter_operand = 0;
- cpu->shifter_carry_out = BIT(rm, 0);
- } else {
- shifter_operand = 0;
- cpu->shifter_carry_out = 0;
- }
- return shifter_operand;
-}
-
-unsigned int DPO(LogicalShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper)
-{
-// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
- //unsigned int rm = cpu->Reg[RM];
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- //if (RM == 15) rm += 8;
- unsigned int shifter_operand;
- int shift_imm = BITS(sht_oper, 7, 11);
- if (shift_imm == 0) {
- shifter_operand = 0;
- cpu->shifter_carry_out = BIT(rm, 31);
- } else {
- shifter_operand = rm >> shift_imm;
- cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
- }
- return shifter_operand;
-}
-
-unsigned int DPO(LogicalShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper)
-{
-// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
- unsigned int rs = CHECK_READ_REG15(cpu, RS);
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- //if (RS == 15) rs += 8;
- //if (RM == 15) rm += 8;
- unsigned int shifter_operand;
- if (BITS(rs, 0, 7) == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- } else if (BITS(rs, 0, 7) < 32) {
- shifter_operand = rm >> BITS(rs, 0, 7);
- cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
- } else if (BITS(rs, 0, 7) == 32) {
- shifter_operand = 0;
- cpu->shifter_carry_out = BIT(rm, 31);
- } else {
- shifter_operand = 0;
- cpu->shifter_carry_out = 0;
- }
- return shifter_operand;
-}
-
-unsigned int DPO(ArithmeticShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper)
-{
-// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
- //unsigned int rm = cpu->Reg[RM];
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- //if (RM == 15) rm += 8;
- unsigned int shifter_operand;
- int shift_imm = BITS(sht_oper, 7, 11);
- if (shift_imm == 0) {
- if (BIT(rm, 31)) {
- shifter_operand = 0;
- cpu->shifter_carry_out = BIT(rm, 31);
- } else {
- shifter_operand = 0xFFFFFFFF;
- cpu->shifter_carry_out = BIT(rm, 31);
- }
- } else {
- shifter_operand = static_cast<int>(rm) >> shift_imm;
- cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
- }
- return shifter_operand;
-}
-
-unsigned int DPO(ArithmeticShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper)
-{
-// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
- //unsigned int rs = cpu->Reg[RS];
- unsigned int rs = CHECK_READ_REG15(cpu, RS);
- //unsigned int rm = cpu->Reg[RM];
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- //if (RS == 15) rs += 8;
- //if (RM == 15) rm += 8;
- unsigned int shifter_operand;
- if (BITS(rs, 0, 7) == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- } else if (BITS(rs, 0, 7) < 32) {
- shifter_operand = static_cast<int>(rm) >> BITS(rs, 0, 7);
- cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
- } else {
- if (BIT(rm, 31) == 0) {
- shifter_operand = 0;
- } else
- shifter_operand = 0xffffffff;
- cpu->shifter_carry_out = BIT(rm, 31);
- }
- return shifter_operand;
-}
-
-unsigned int DPO(RotateRightByImmediate)(arm_processor *cpu, unsigned int sht_oper)
-{
-// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
- unsigned int shifter_operand;
- //unsigned int rm = cpu->Reg[RM];
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- //if (RM == 15) rm += 8;
- int shift_imm = BITS(sht_oper, 7, 11);
- if (shift_imm == 0) {
- shifter_operand = (cpu->CFlag << 31) |
- (rm >> 1);
- cpu->shifter_carry_out = BIT(rm, 0);
- } else {
- shifter_operand = ROTATE_RIGHT_32(rm, shift_imm);
- cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
- }
- return shifter_operand;
-}
-
-unsigned int DPO(RotateRightByRegister)(arm_processor *cpu, unsigned int sht_oper)
-{
-// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- //if (RM == 15) rm += 8;
- unsigned int rs = CHECK_READ_REG15(cpu, RS);
- //if (RS == 15) rs += 8;
- unsigned int shifter_operand;
- if (BITS(rs, 0, 7) == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- } else if (BITS(rs, 0, 4) == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = BIT(rm, 31);
- } else {
- shifter_operand = ROTATE_RIGHT_32(rm, BITS(rs, 0, 4));
- cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 4) - 1);
- }
- #if 0
- if (cpu->icounter >= 20371544) {
- DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
- DEBUG_LOG(ARM11, "RM:%d\nRS:%d\n", RM, RS);
- DEBUG_LOG(ARM11, "rm:0x%08x\nrs:0x%08x\n", cpu->Reg[RM], cpu->Reg[RS]);
- }
- #endif
- return shifter_operand;
-}
-
-//typedef unsigned int (*get_addr_fp_t)(arm_processor *cpu);
typedef struct _MiscImmeData {
- unsigned int U;
- unsigned int Rn;
- unsigned int offset_8;
+ unsigned int U;
+ unsigned int Rn;
+ unsigned int offset_8;
} MiscLSData;
typedef struct _MiscRegData {
- unsigned int U;
- unsigned int Rn;
- unsigned int Rm;
+ unsigned int U;
+ unsigned int Rn;
+ unsigned int Rm;
} MiscRegData;
typedef struct _MiscImmePreIdx {
- unsigned int offset_8;
- unsigned int U;
- unsigned int Rn;
+ unsigned int offset_8;
+ unsigned int U;
+ unsigned int Rn;
} MiscImmePreIdx;
typedef struct _MiscRegPreIdx {
- unsigned int U;
- unsigned int Rn;
- unsigned int Rm;
+ unsigned int U;
+ unsigned int Rn;
+ unsigned int Rm;
} MiscRegPreIdx;
typedef struct _MiscImmePstIdx {
- unsigned int offset_8;
- unsigned int U;
- unsigned int Rn;
+ unsigned int offset_8;
+ unsigned int U;
+ unsigned int Rn;
} MIscImmePstIdx;
typedef struct _MiscRegPstIdx {
- unsigned int Rn;
- unsigned int Rm;
- unsigned int U;
+ unsigned int Rn;
+ unsigned int Rm;
+ unsigned int U;
} MiscRegPstIdx;
typedef struct _LSWordorUnsignedByte {
@@ -384,40 +277,38 @@ typedef struct _LSWordorUnsignedByte {
#if USER_MODE_OPT
static inline fault_t interpreter_read_memory(addr_t virt_addr, addr_t phys_addr, uint32_t &value, uint32_t size){
- switch(size) {
- case 8:
+ switch(size) {
+ case 8:
value = Memory::Read8(virt_addr);
- break;
- case 16:
+ break;
+ case 16:
value = Memory::Read16(virt_addr);
- break;
- case 32:
+ break;
+ case 32:
value = Memory::Read32(virt_addr);
- break;
- }
- return NO_FAULT;
+ break;
+ }
+ return NO_FAULT;
}
-//static inline void interpreter_write_memory(void *mem_ptr, uint32_t offset, uint32_t value, int size)
-static inline fault_t interpreter_write_memory(addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size)
-{
- switch(size) {
- case 8:
+static inline fault_t interpreter_write_memory(addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size) {
+ switch(size) {
+ case 8:
Memory::Write8(virt_addr, value & 0xff);
- break;
- case 16:
- Memory::Write16(virt_addr, value & 0xffff);
- break;
- case 32:
- Memory::Write32(virt_addr, value);
- break;
- }
- return NO_FAULT;
+ break;
+ case 16:
+ Memory::Write16(virt_addr, value & 0xffff);
+ break;
+ case 32:
+ Memory::Write32(virt_addr, value);
+ break;
+ }
+ return NO_FAULT;
}
-static inline fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_addr, uint32_t rw){
- *phys_addr = virt_addr;
- return NO_FAULT;
+static inline fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_addr, uint32_t rw) {
+ *phys_addr = virt_addr;
+ return NO_FAULT;
}
#else
@@ -430,745 +321,679 @@ fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_
typedef fault_t (*get_addr_fp_t)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw);
typedef struct _ldst_inst {
- unsigned int inst;
- get_addr_fp_t get_addr;
+ unsigned int inst;
+ get_addr_fp_t get_addr;
} ldst_inst;
#define DEBUG_MSG LOG_DEBUG(Core_ARM11, "inst is %x", inst); CITRA_IGNORE_EXIT(0)
int CondPassed(arm_processor *cpu, unsigned int cond);
-#define LnSWoUB(s) glue(LnSWoUB, s)
-#define MLnS(s) glue(MLnS, s)
-#define LdnStM(s) glue(LdnStM, s)
-
-#define W_BIT BIT(inst, 21)
-#define U_BIT BIT(inst, 23)
-#define I_BIT BIT(inst, 25)
-#define P_BIT BIT(inst, 24)
-#define OFFSET_12 BITS(inst, 0, 11)
-fault_t LnSWoUB(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int addr;
- fault_t fault;
- if (U_BIT) {
- addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
- } else {
- addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
- }
- //if (Rn == 15) rn += 8;
- virt_addr = addr;
- fault = check_address_validity(cpu, addr, &phys_addr, rw);
- return fault;
-// return addr;
-}
-
-fault_t LnSWoUB(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- //if (Rn == 15) rn += 8;
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- //if (Rm == 15) rm += 8;
- unsigned int addr;
- if (U_BIT) {
- addr = rn + rm;
- } else {
- addr = rn - rm;
- }
- virt_addr = addr;
- fault = check_address_validity(cpu, addr, &phys_addr, rw);
- return fault;
-}
-
-fault_t LnSWoUB(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn);
- //if (Rn == 15) addr += 8;
+#define LnSWoUB(s) glue(LnSWoUB, s)
+#define MLnS(s) glue(MLnS, s)
+#define LdnStM(s) glue(LdnStM, s)
+
+#define W_BIT BIT(inst, 21)
+#define U_BIT BIT(inst, 23)
+#define I_BIT BIT(inst, 25)
+#define P_BIT BIT(inst, 24)
+#define OFFSET_12 BITS(inst, 0, 11)
+fault_t LnSWoUB(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int addr;
+ fault_t fault;
+ if (U_BIT) {
+ addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
+ } else {
+ addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
+ }
+ virt_addr = addr;
+ fault = check_address_validity(cpu, addr, &phys_addr, rw);
+ return fault;
+}
+
+fault_t LnSWoUB(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int Rm = BITS(inst, 0, 3);
+ unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+ unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+ unsigned int addr;
+ if (U_BIT) {
+ addr = rn + rm;
+ } else {
+ addr = rn - rm;
+ }
+ virt_addr = addr;
+ fault = check_address_validity(cpu, addr, &phys_addr, rw);
+ return fault;
+}
+
+fault_t LnSWoUB(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn);
+
+ virt_addr = addr;
+ fault = check_address_validity(cpu, addr, &phys_addr, rw);
+ if (fault) return fault;
+
+ if (U_BIT) {
+ cpu->Reg[Rn] += OFFSET_12;
+ } else {
+ cpu->Reg[Rn] -= OFFSET_12;
+ }
+ return fault;
+}
+
+fault_t LnSWoUB(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int addr;
+ if (U_BIT) {
+ addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
+ } else {
+ addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
+ }
+
+ virt_addr = addr;
+ fault = check_address_validity(cpu, addr, &phys_addr, rw);
+ if (fault) return fault;
+
+ if (CondPassed(cpu, BITS(inst, 28, 31))) {
+ cpu->Reg[Rn] = addr;
+ }
+ return fault;
+}
+
+fault_t MLnS(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int addr;
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int Rm = BITS(inst, 0, 3);
+ unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+ unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+
+ if (U_BIT) {
+ addr = rn + rm;
+ } else
+ addr = rn - rm;
+ if(BIT(inst, 20)){ // L BIT
+ }
+ if(BIT(inst, 6)){ // Sign Bit
+ }
+ if(BIT(inst, 5)){ // Half Bit
+ }
+
+ virt_addr = addr;
+ fault = check_address_validity(cpu, addr, &phys_addr, rw);
+ if (fault) return fault;
+
+ if (CondPassed(cpu, BITS(inst, 28, 31))) {
+ cpu->Reg[Rn] = addr;
+ }
+ return fault;
+}
+
+fault_t LnSWoUB(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int Rm = BITS(inst, 0, 3);
+ unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+ unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+ unsigned int addr;
+ if (U_BIT) {
+ addr = rn + rm;
+ } else {
+ addr = rn - rm;
+ }
+ virt_addr = addr;
+ fault = check_address_validity(cpu, addr, &phys_addr, rw);
+ if(fault)
+ return fault;
+ if (CondPassed(cpu, BITS(inst, 28, 31))) {
+ cpu->Reg[Rn] = addr;
+ }
+ return fault;
+}
+fault_t LnSWoUB(ScaledRegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int shift = BITS(inst, 5, 6);
+ unsigned int shift_imm = BITS(inst, 7, 11);
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int Rm = BITS(inst, 0, 3);
+ unsigned int index;
+ unsigned int addr;
+
+ unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+ unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+
+ switch (shift) {
+ case 0:
+ index = rm << shift_imm;
+ break;
+ case 1:
+ if (shift_imm == 0) {
+ index = 0;
+ } else {
+ index = rm >> shift_imm;
+ }
+ break;
+ case 2:
+ DEBUG_MSG;
+ break;
+ case 3:
+ DEBUG_MSG;
+ break;
+ }
+ if (U_BIT) {
+ addr = rn + index;
+ } else
+ addr = rn - index;
+ virt_addr = addr;
+ fault = check_address_validity(cpu, addr, &phys_addr, rw);
+ if(fault)
+ return fault;
+ if (CondPassed(cpu, BITS(inst, 28, 31))) {
+ cpu->Reg[Rn] = addr;
+ }
- virt_addr = addr;
- fault = check_address_validity(cpu, addr, &phys_addr, rw);
- if (fault) return fault;
+ return fault;
+}
+
+fault_t LnSWoUB(ScaledRegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int shift = BITS(inst, 5, 6);
+ unsigned int shift_imm = BITS(inst, 7, 11);
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int Rm = BITS(inst, 0, 3);
+ unsigned int index;
+ unsigned int addr;
+
+ unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+ unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+ addr = rn;
+ switch (shift) {
+ case 0:
+ index = rm << shift_imm;
+ break;
+ case 1:
+ if (shift_imm == 0) {
+ index = 0;
+ } else {
+ index = rm >> shift_imm;
+ }
+ break;
+ case 2:
+ DEBUG_MSG;
+ break;
+ case 3:
+ DEBUG_MSG;
+ break;
+ }
+ virt_addr = addr;
+ fault = check_address_validity(cpu, addr, &phys_addr, rw);
+ if(fault)
+ return fault;
+ if (CondPassed(cpu, BITS(inst, 28, 31))) {
+ if (U_BIT)
+ cpu->Reg[Rn] += index;
+ else
+ cpu->Reg[Rn] -= index;
+ }
- if (U_BIT) {
- cpu->Reg[Rn] += OFFSET_12;
- } else {
- cpu->Reg[Rn] -= OFFSET_12;
- }
- return fault;
+ return fault;
}
-fault_t LnSWoUB(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int addr;
- if (U_BIT) {
- addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
- } else {
- addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
- }
- #if 0
- if (Rn == 15) {
- addr += 8;
- }
- #endif
-
- virt_addr = addr;
- fault = check_address_validity(cpu, addr, &phys_addr, rw);
- if (fault) return fault;
-
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- cpu->Reg[Rn] = addr;
- }
- return fault;
-}
-
-fault_t MLnS(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int addr;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- //if (Rn == 15) rn += 8;
- //if (Rm == 15) rm += 8;
- if (U_BIT) {
- addr = rn + rm;
- } else
- addr = rn - rm;
- if(BIT(inst, 20)){ /* L BIT */
- }
- if(BIT(inst, 6)){ /* Sign Bit */
- }
- if(BIT(inst, 5)){ /* Half Bit */
- }
-
- virt_addr = addr;
- fault = check_address_validity(cpu, addr, &phys_addr, rw);
- if (fault) return fault;
-
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- cpu->Reg[Rn] = addr;
- }
- return fault;
-}
-
-fault_t LnSWoUB(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- //if (Rn == 15) rn += 8;
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- //if (Rm == 15) rm += 8;
- unsigned int addr;
- if (U_BIT) {
- addr = rn + rm;
- } else {
- addr = rn - rm;
- }
- virt_addr = addr;
- fault = check_address_validity(cpu, addr, &phys_addr, rw);
- if(fault)
- return fault;
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- cpu->Reg[Rn] = addr;
- }
- return fault;
-}
-fault_t LnSWoUB(ScaledRegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int shift = BITS(inst, 5, 6);
- unsigned int shift_imm = BITS(inst, 7, 11);
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int index;
- unsigned int addr;
-
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- //if (Rm == 15) rm += 8;
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- //if (Rn == 15) rn += 8;
- switch (shift) {
- case 0:
- //DEBUG_MSG;
- index = rm << shift_imm;
- break;
- case 1:
-// DEBUG_MSG;
- if (shift_imm == 0) {
- index = 0;
- } else {
- index = rm >> shift_imm;
- }
- break;
- case 2:
- DEBUG_MSG;
- break;
- case 3:
- DEBUG_MSG;
- break;
- }
- if (U_BIT) {
- addr = rn + index;
- } else
- addr = rn - index;
- virt_addr = addr;
- fault = check_address_validity(cpu, addr, &phys_addr, rw);
- if(fault)
- return fault;
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- cpu->Reg[Rn] = addr;
- }
-
- return fault;
-}
-
-fault_t LnSWoUB(ScaledRegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int shift = BITS(inst, 5, 6);
- unsigned int shift_imm = BITS(inst, 7, 11);
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int index;
- unsigned int addr;
-
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- //if (Rm == 15) rm += 8;
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- //if (Rn == 15) rn += 8;
- addr = rn;
- switch (shift) {
- case 0:
- //DEBUG_MSG;
- index = rm << shift_imm;
- break;
- case 1:
-// DEBUG_MSG;
- if (shift_imm == 0) {
- index = 0;
- } else {
- index = rm >> shift_imm;
- }
- break;
- case 2:
- DEBUG_MSG;
- break;
- case 3:
- DEBUG_MSG;
- break;
- }
- virt_addr = addr;
- fault = check_address_validity(cpu, addr, &phys_addr, rw);
- if(fault)
- return fault;
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- if (U_BIT)
- cpu->Reg[Rn] += index;
- else
- cpu->Reg[Rn] -= index;
- }
-
- return fault;
-}
-
-fault_t LnSWoUB(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
-
- unsigned int addr = rn;
- virt_addr = addr;
- fault = check_address_validity(cpu, addr, &phys_addr, rw);
- if (fault) return fault;
-
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- if (U_BIT) {
- cpu->Reg[Rn] += rm;
- } else {
- cpu->Reg[Rn] -= rm;
- }
- }
- return fault;
-}
-
-fault_t MLnS(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int immedL = BITS(inst, 0, 3);
- unsigned int immedH = BITS(inst, 8, 11);
-
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int addr;
-
- unsigned int offset_8 = (immedH << 4) | immedL;
- if (U_BIT) {
- addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8;
- } else
- addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8;
- #if 0
- if (Rn == 15) {
- addr += 8;
- }
- #endif
- virt_addr = addr;
- fault = check_address_validity(cpu, addr, &phys_addr, rw);
- return fault;
-}
-
-fault_t MLnS(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int addr;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- //if (Rn == 15) rn += 8;
- //if (Rm == 15) rm += 8;
- if (U_BIT) {
- addr = rn + rm;
- } else
- addr = rn - rm;
- if(BIT(inst, 20)){ /* L BIT */
- }
- if(BIT(inst, 6)){ /* Sign Bit */
- }
- if(BIT(inst, 5)){ /* Half Bit */
- }
- virt_addr = addr;
- fault = check_address_validity(cpu, addr, &phys_addr, rw);
- return fault;
-}
-
-fault_t MLnS(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int immedH = BITS(inst, 8, 11);
- unsigned int immedL = BITS(inst, 0, 3);
- unsigned int addr;
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- //if (Rn == 15) rn += 8;
-
-// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
- unsigned int offset_8 = (immedH << 4) | immedL;
- if (U_BIT) {
- addr = rn + offset_8;
- } else
- addr = rn - offset_8;
-
- virt_addr = addr;
- fault = check_address_validity(cpu, addr, &phys_addr, rw);
- if (fault) return fault;
-
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- cpu->Reg[Rn] = addr;
- }
- return fault;
-}
-
-fault_t MLnS(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int immedH = BITS(inst, 8, 11);
- unsigned int immedL = BITS(inst, 0, 3);
- unsigned int addr;
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- addr = rn;
-
- virt_addr = addr;
- fault = check_address_validity(cpu, addr, &phys_addr, rw);
- if (fault) return fault;
-
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- unsigned int offset_8 = (immedH << 4) | immedL;
- if (U_BIT) {
- rn += offset_8;
- } else {
- rn -= offset_8;
- }
- cpu->Reg[Rn] = rn;
- }
-
- return fault;
-}
-fault_t MLnS(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
-
- unsigned int addr = rn;
- virt_addr = addr;
- fault = check_address_validity(cpu, addr, &phys_addr, rw);
- if (fault) return fault;
-
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- if (U_BIT) {
- cpu->Reg[Rn] += rm;
- } else {
- cpu->Reg[Rn] -= rm;
- }
- }
- return fault;
-}
-
-fault_t LdnStM(DecrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int i = BITS(inst, 0, 15);
- int count = 0;
- while(i) {
- if(i & 1) count ++;
- i = i >> 1;
- }
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- //if (Rn == 15) rn += 8;
- unsigned int start_addr = rn - count * 4;
- unsigned int end_addr = rn - 4;
-
- fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
- virt_addr = end_addr;
- if (fault) return fault;
-
- fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
- virt_addr = start_addr;
- if (fault) return fault;
-
- if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
- cpu->Reg[Rn] -= count * 4;
- }
-
- return fault;
-}
-
-fault_t LdnStM(IncrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int i = BITS(inst, 0, 15);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- //if (Rn == 15) rn += 8;
- int count = 0;
- while(i) {
- if(i & 1) count ++;
- i = i >> 1;
- }
-
- unsigned int start_addr = rn + 4;
- unsigned int end_addr = rn + count * 4;
-
- fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
- virt_addr = end_addr;
- if (fault) return fault;
-
- fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
- virt_addr = start_addr;
- if (fault) return fault;
-
- if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
- cpu->Reg[Rn] += count * 4;
- }
- return fault;
-}
-
-fault_t LdnStM(IncrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int i = BITS(inst, 0, 15);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- int count = 0;
- while(i) {
- if(i & 1) count ++;
- i = i >> 1;
- }
- //if (Rn == 15) rn += 8;
- unsigned int start_addr = rn;
- unsigned int end_addr = rn + count * 4 - 4;
-
- fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
- virt_addr = end_addr;
- if (fault) return fault;
-
- fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
- virt_addr = start_addr;
- if (fault) return fault;
-
- if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
- cpu->Reg[Rn] += count * 4;
- }
- return fault;
-}
-
-fault_t LdnStM(DecrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int i = BITS(inst, 0, 15);
- int count = 0;
- while(i) {
- if(i & 1) count ++;
- i = i >> 1;
- }
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- //if (Rn == 15) rn += 8;
- unsigned int start_addr = rn - count * 4 + 4;
- unsigned int end_addr = rn;
-
- fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
- virt_addr = end_addr;
- if (fault) return fault;
-
- fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
- if (fault) return fault;
- virt_addr = start_addr;
-
- if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
- cpu->Reg[Rn] -= count * 4;
- }
- return fault;
-}
-
-fault_t LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
-{
- fault_t fault;
- unsigned int shift = BITS(inst, 5, 6);
- unsigned int shift_imm = BITS(inst, 7, 11);
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int index;
- unsigned int addr;
-
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- //if (Rm == 15) rm += 8;
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- //if (Rn == 15) rn += 8;
- switch (shift) {
- case 0:
- //DEBUG_MSG;
- index = rm << shift_imm;
- break;
- case 1:
-// DEBUG_MSG;
- if (shift_imm == 0) {
- index = 0;
- } else {
- index = rm >> shift_imm;
- }
- break;
- case 2:
- if (shift_imm == 0){ /* ASR #32 */
- if (rm >> 31)
- index = 0xFFFFFFFF;
- else
- index = 0;
- }
- else {
- index = static_cast<int>(rm) >> shift_imm;
- }
- break;
- case 3:
- DEBUG_MSG;
- break;
- }
- if (U_BIT) {
- addr = rn + index;
- } else
- addr = rn - index;
- virt_addr = addr;
- fault = check_address_validity(cpu, addr, &phys_addr, rw);
- return fault;
-}
-
-#define ISNEG(n) (n < 0)
-#define ISPOS(n) (n >= 0)
-
-//enum {
-// COND = (1 << 0),
-// NON_BRANCH = (1 << 1),
-// DIRECT_BRANCH = (1 << 2),
-// INDIRECT_BRANCH = (1 << 3),
-// CALL = (1 << 4),
-// RET = (1 << 5),
-// END_OF_PAGE = (1 << 6),
-// THUMB = (1 << 7)
-//};
+fault_t LnSWoUB(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int Rm = BITS(inst, 0, 3);
+ unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+ unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+
+ unsigned int addr = rn;
+ virt_addr = addr;
+ fault = check_address_validity(cpu, addr, &phys_addr, rw);
+ if (fault) return fault;
+
+ if (CondPassed(cpu, BITS(inst, 28, 31))) {
+ if (U_BIT) {
+ cpu->Reg[Rn] += rm;
+ } else {
+ cpu->Reg[Rn] -= rm;
+ }
+ }
+ return fault;
+}
+
+fault_t MLnS(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int immedL = BITS(inst, 0, 3);
+ unsigned int immedH = BITS(inst, 8, 11);
+
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int addr;
+
+ unsigned int offset_8 = (immedH << 4) | immedL;
+ if (U_BIT) {
+ addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8;
+ } else
+ addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8;
+
+ virt_addr = addr;
+ fault = check_address_validity(cpu, addr, &phys_addr, rw);
+ return fault;
+}
+
+fault_t MLnS(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int addr;
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int Rm = BITS(inst, 0, 3);
+ unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+ unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+ if (U_BIT) {
+ addr = rn + rm;
+ } else
+ addr = rn - rm;
+ if(BIT(inst, 20)){ // L BIT
+ }
+ if(BIT(inst, 6)){ // Sign Bit
+ }
+ if(BIT(inst, 5)){ // Half Bit
+ }
+ virt_addr = addr;
+ fault = check_address_validity(cpu, addr, &phys_addr, rw);
+ return fault;
+}
+
+fault_t MLnS(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int immedH = BITS(inst, 8, 11);
+ unsigned int immedL = BITS(inst, 0, 3);
+ unsigned int addr;
+ unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+ unsigned int offset_8 = (immedH << 4) | immedL;
+
+ if (U_BIT) {
+ addr = rn + offset_8;
+ } else
+ addr = rn - offset_8;
+
+ virt_addr = addr;
+ fault = check_address_validity(cpu, addr, &phys_addr, rw);
+ if (fault) return fault;
+
+ if (CondPassed(cpu, BITS(inst, 28, 31))) {
+ cpu->Reg[Rn] = addr;
+ }
+ return fault;
+}
+
+fault_t MLnS(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int immedH = BITS(inst, 8, 11);
+ unsigned int immedL = BITS(inst, 0, 3);
+ unsigned int addr;
+ unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+ addr = rn;
+
+ virt_addr = addr;
+ fault = check_address_validity(cpu, addr, &phys_addr, rw);
+ if (fault) return fault;
+
+ if (CondPassed(cpu, BITS(inst, 28, 31))) {
+ unsigned int offset_8 = (immedH << 4) | immedL;
+ if (U_BIT) {
+ rn += offset_8;
+ } else {
+ rn -= offset_8;
+ }
+ cpu->Reg[Rn] = rn;
+ }
+
+ return fault;
+}
+fault_t MLnS(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int Rm = BITS(inst, 0, 3);
+ unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+ unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+ unsigned int addr = rn;
+
+ virt_addr = addr;
+ fault = check_address_validity(cpu, addr, &phys_addr, rw);
+ if (fault) return fault;
+
+ if (CondPassed(cpu, BITS(inst, 28, 31))) {
+ if (U_BIT) {
+ cpu->Reg[Rn] += rm;
+ } else {
+ cpu->Reg[Rn] -= rm;
+ }
+ }
+ return fault;
+}
+
+fault_t LdnStM(DecrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int i = BITS(inst, 0, 15);
+ int count = 0;
+ while(i) {
+ if(i & 1) count ++;
+ i = i >> 1;
+ }
+ unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+ unsigned int start_addr = rn - count * 4;
+ unsigned int end_addr = rn - 4;
+
+ fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
+ virt_addr = end_addr;
+ if (fault) return fault;
+
+ fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
+ virt_addr = start_addr;
+ if (fault) return fault;
+
+ if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
+ cpu->Reg[Rn] -= count * 4;
+ }
+
+ return fault;
+}
+
+fault_t LdnStM(IncrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int i = BITS(inst, 0, 15);
+ unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+ int count = 0;
+ while(i) {
+ if(i & 1) count ++;
+ i = i >> 1;
+ }
+
+ unsigned int start_addr = rn + 4;
+ unsigned int end_addr = rn + count * 4;
+
+ fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
+ virt_addr = end_addr;
+ if (fault) return fault;
+
+ fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
+ virt_addr = start_addr;
+ if (fault) return fault;
+
+ if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
+ cpu->Reg[Rn] += count * 4;
+ }
+ return fault;
+}
+
+fault_t LdnStM(IncrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int i = BITS(inst, 0, 15);
+ unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+ int count = 0;
+ while(i) {
+ if(i & 1) count ++;
+ i = i >> 1;
+ }
+ unsigned int start_addr = rn;
+ unsigned int end_addr = rn + count * 4 - 4;
+
+ fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
+ virt_addr = end_addr;
+ if (fault) return fault;
+
+ fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
+ virt_addr = start_addr;
+ if (fault) return fault;
+
+ if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
+ cpu->Reg[Rn] += count * 4;
+ }
+ return fault;
+}
+
+fault_t LdnStM(DecrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int i = BITS(inst, 0, 15);
+ int count = 0;
+ while(i) {
+ if(i & 1) count ++;
+ i = i >> 1;
+ }
+ unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+ unsigned int start_addr = rn - count * 4 + 4;
+ unsigned int end_addr = rn;
+
+ fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
+ virt_addr = end_addr;
+ if (fault) return fault;
+
+ fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
+ if (fault) return fault;
+ virt_addr = start_addr;
+
+ if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
+ cpu->Reg[Rn] -= count * 4;
+ }
+ return fault;
+}
+
+fault_t LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) {
+ fault_t fault;
+ unsigned int shift = BITS(inst, 5, 6);
+ unsigned int shift_imm = BITS(inst, 7, 11);
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int Rm = BITS(inst, 0, 3);
+ unsigned int index;
+ unsigned int addr;
+
+ unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+ unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+ switch (shift) {
+ case 0:
+ index = rm << shift_imm;
+ break;
+ case 1:
+ if (shift_imm == 0) {
+ index = 0;
+ } else {
+ index = rm >> shift_imm;
+ }
+ break;
+ case 2:
+ if (shift_imm == 0){ // ASR #32
+ if (rm >> 31)
+ index = 0xFFFFFFFF;
+ else
+ index = 0;
+ }
+ else {
+ index = static_cast<int>(rm) >> shift_imm;
+ }
+ break;
+ case 3:
+ DEBUG_MSG;
+ break;
+ }
+ if (U_BIT) {
+ addr = rn + index;
+ } else
+ addr = rn - index;
+
+ virt_addr = addr;
+ fault = check_address_validity(cpu, addr, &phys_addr, rw);
+
+ return fault;
+}
+
+#define ISNEG(n) (n < 0)
+#define ISPOS(n) (n >= 0)
typedef struct _arm_inst {
- unsigned int idx;
- unsigned int cond;
- int br;
- int load_r15;
- char component[0];
+ unsigned int idx;
+ unsigned int cond;
+ int br;
+ int load_r15;
+ char component[0];
} arm_inst;
typedef struct generic_arm_inst {
- u32 Ra;
- u32 Rm;
- u32 Rn;
- u32 Rd;
- u8 op1;
- u8 op2;
+ u32 Ra;
+ u32 Rm;
+ u32 Rn;
+ u32 Rd;
+ u8 op1;
+ u8 op2;
} generic_arm_inst;
typedef struct _adc_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
} adc_inst;
typedef struct _add_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
} add_inst;
typedef struct _orr_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
} orr_inst;
typedef struct _and_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
} and_inst;
typedef struct _eor_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
} eor_inst;
typedef struct _bbl_inst {
- unsigned int L;
- int signed_immed_24;
- unsigned int next_addr;
- unsigned int jmp_addr;
+ unsigned int L;
+ int signed_immed_24;
+ unsigned int next_addr;
+ unsigned int jmp_addr;
} bbl_inst;
typedef struct _bx_inst {
- unsigned int Rm;
+ unsigned int Rm;
} bx_inst;
typedef struct _blx_inst {
- union {
- int32_t signed_immed_24;
- uint32_t Rm;
- } val;
- unsigned int inst;
+ union {
+ int32_t signed_immed_24;
+ uint32_t Rm;
+ } val;
+ unsigned int inst;
} blx_inst;
typedef struct _clz_inst {
- unsigned int Rm;
- unsigned int Rd;
+ unsigned int Rm;
+ unsigned int Rd;
} clz_inst;
typedef struct _cps_inst {
- unsigned int imod0;
- unsigned int imod1;
- unsigned int mmod;
- unsigned int A, I, F;
- unsigned int mode;
+ unsigned int imod0;
+ unsigned int imod1;
+ unsigned int mmod;
+ unsigned int A, I, F;
+ unsigned int mode;
} cps_inst;
typedef struct _clrex_inst {
} clrex_inst;
typedef struct _cpy_inst {
- unsigned int Rm;
- unsigned int Rd;
+ unsigned int Rm;
+ unsigned int Rd;
} cpy_inst;
typedef struct _bic_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
} bic_inst;
typedef struct _sub_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
} sub_inst;
typedef struct _tst_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
} tst_inst;
typedef struct _cmn_inst {
- unsigned int I;
- //unsigned int S;
- unsigned int Rn;
- //unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
+ unsigned int I;
+ unsigned int Rn;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
} cmn_inst;
typedef struct _teq_inst {
- unsigned int I;
- unsigned int Rn;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
+ unsigned int I;
+ unsigned int Rn;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
} teq_inst;
typedef struct _stm_inst {
- unsigned int inst;
+ unsigned int inst;
} stm_inst;
struct bkpt_inst {
};
struct blx1_inst {
- unsigned int addr;
+ unsigned int addr;
};
struct blx2_inst {
- unsigned int Rm;
+ unsigned int Rm;
};
typedef struct _stc_inst {
@@ -1178,457 +1003,418 @@ typedef struct _ldc_inst {
} ldc_inst;
typedef struct _swi_inst {
- unsigned int num;
+ unsigned int num;
} swi_inst;
typedef struct _cmp_inst {
- unsigned int I;
- unsigned int Rn;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
+ unsigned int I;
+ unsigned int Rn;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
} cmp_inst;
typedef struct _mov_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
} mov_inst;
typedef struct _mvn_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
} mvn_inst;
typedef struct _rev_inst {
- unsigned int Rd;
- unsigned int Rm;
+ unsigned int Rd;
+ unsigned int Rm;
} rev_inst;
typedef struct _rsb_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
} rsb_inst;
typedef struct _rsc_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
} rsc_inst;
typedef struct _sbc_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
} sbc_inst;
typedef struct _mul_inst {
- unsigned int S;
- unsigned int Rd;
- unsigned int Rs;
- unsigned int Rm;
+ unsigned int S;
+ unsigned int Rd;
+ unsigned int Rs;
+ unsigned int Rm;
} mul_inst;
typedef struct _smul_inst {
- unsigned int Rd;
- unsigned int Rs;
- unsigned int Rm;
- unsigned int x;
- unsigned int y;
+ unsigned int Rd;
+ unsigned int Rs;
+ unsigned int Rm;
+ unsigned int x;
+ unsigned int y;
} smul_inst;
typedef struct _umull_inst {
- unsigned int S;
- unsigned int RdHi;
- unsigned int RdLo;
- unsigned int Rs;
- unsigned int Rm;
+ unsigned int S;
+ unsigned int RdHi;
+ unsigned int RdLo;
+ unsigned int Rs;
+ unsigned int Rm;
} umull_inst;
typedef struct _smlad_inst {
- unsigned int m;
- unsigned int Rm;
- unsigned int Rd;
- unsigned int Ra;
- unsigned int Rn;
+ unsigned int m;
+ unsigned int Rm;
+ unsigned int Rd;
+ unsigned int Ra;
+ unsigned int Rn;
} smlad_inst;
typedef struct _smla_inst {
- unsigned int x;
- unsigned int y;
- unsigned int Rm;
- unsigned int Rd;
- unsigned int Rs;
- unsigned int Rn;
+ unsigned int x;
+ unsigned int y;
+ unsigned int Rm;
+ unsigned int Rd;
+ unsigned int Rs;
+ unsigned int Rn;
} smla_inst;
typedef struct umaal_inst {
- unsigned int Rn;
- unsigned int Rm;
- unsigned int RdHi;
- unsigned int RdLo;
+ unsigned int Rn;
+ unsigned int Rm;
+ unsigned int RdHi;
+ unsigned int RdLo;
} umaal_inst;
typedef struct _umlal_inst {
- unsigned int S;
- unsigned int Rm;
- unsigned int Rs;
- unsigned int RdHi;
- unsigned int RdLo;
+ unsigned int S;
+ unsigned int Rm;
+ unsigned int Rs;
+ unsigned int RdHi;
+ unsigned int RdLo;
} umlal_inst;
typedef struct _smlal_inst {
- unsigned int S;
- unsigned int Rm;
- unsigned int Rs;
- unsigned int RdHi;
- unsigned int RdLo;
+ unsigned int S;
+ unsigned int Rm;
+ unsigned int Rs;
+ unsigned int RdHi;
+ unsigned int RdLo;
} smlal_inst;
typedef struct _mla_inst {
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int Rs;
- unsigned int Rm;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int Rs;
+ unsigned int Rm;
} mla_inst;
typedef struct _mrc_inst {
- unsigned int opcode_1;
- unsigned int opcode_2;
- unsigned int cp_num;
- unsigned int crn;
- unsigned int crm;
- unsigned int Rd;
- unsigned int inst;
+ unsigned int opcode_1;
+ unsigned int opcode_2;
+ unsigned int cp_num;
+ unsigned int crn;
+ unsigned int crm;
+ unsigned int Rd;
+ unsigned int inst;
} mrc_inst;
typedef struct _mcr_inst {
- unsigned int opcode_1;
- unsigned int opcode_2;
- unsigned int cp_num;
- unsigned int crn;
- unsigned int crm;
- unsigned int Rd;
- unsigned int inst;
+ unsigned int opcode_1;
+ unsigned int opcode_2;
+ unsigned int cp_num;
+ unsigned int crn;
+ unsigned int crm;
+ unsigned int Rd;
+ unsigned int inst;
} mcr_inst;
typedef struct _mrs_inst {
- unsigned int R;
- unsigned int Rd;
+ unsigned int R;
+ unsigned int Rd;
} mrs_inst;
typedef struct _msr_inst {
- unsigned int field_mask;
- unsigned int R;
- unsigned int inst;
+ unsigned int field_mask;
+ unsigned int R;
+ unsigned int inst;
} msr_inst;
typedef struct _pld_inst {
} pld_inst;
typedef struct _sxtb_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int rotate;
+ unsigned int Rd;
+ unsigned int Rm;
+ unsigned int rotate;
} sxtb_inst;
typedef struct _sxtab_inst {
- unsigned int Rd;
- unsigned int Rn;
- unsigned int Rm;
- unsigned rotate;
+ unsigned int Rd;
+ unsigned int Rn;
+ unsigned int Rm;
+ unsigned rotate;
} sxtab_inst;
typedef struct _sxtah_inst {
- unsigned int Rd;
- unsigned int Rn;
- unsigned int Rm;
- unsigned int rotate;
+ unsigned int Rd;
+ unsigned int Rn;
+ unsigned int Rm;
+ unsigned int rotate;
} sxtah_inst;
typedef struct _sxth_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int rotate;
+ unsigned int Rd;
+ unsigned int Rm;
+ unsigned int rotate;
} sxth_inst;
typedef struct _uxtab_inst {
- unsigned int Rn;
- unsigned int Rd;
- unsigned int rotate;
- unsigned int Rm;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int rotate;
+ unsigned int Rm;
} uxtab_inst;
typedef struct _uxtah_inst {
- unsigned int Rn;
- unsigned int Rd;
- unsigned int rotate;
- unsigned int Rm;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int rotate;
+ unsigned int Rm;
} uxtah_inst;
typedef struct _uxth_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int rotate;
+ unsigned int Rd;
+ unsigned int Rm;
+ unsigned int rotate;
} uxth_inst;
typedef struct _cdp_inst {
- unsigned int opcode_1;
- unsigned int CRn;
- unsigned int CRd;
- unsigned int cp_num;
- unsigned int opcode_2;
- unsigned int CRm;
- uint32 inst;
+ unsigned int opcode_1;
+ unsigned int CRn;
+ unsigned int CRd;
+ unsigned int cp_num;
+ unsigned int opcode_2;
+ unsigned int CRm;
+ uint32 inst;
}cdp_inst;
typedef struct _uxtb_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int rotate;
+ unsigned int Rd;
+ unsigned int Rm;
+ unsigned int rotate;
} uxtb_inst;
typedef struct _swp_inst {
- unsigned int Rn;
- unsigned int Rd;
- unsigned int Rm;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int Rm;
} swp_inst;
typedef struct _b_2_thumb {
- unsigned int imm;
+ unsigned int imm;
}b_2_thumb;
typedef struct _b_cond_thumb {
- unsigned int imm;
- unsigned int cond;
+ unsigned int imm;
+ unsigned int cond;
}b_cond_thumb;
typedef struct _bl_1_thumb {
- unsigned int imm;
+ unsigned int imm;
}bl_1_thumb;
typedef struct _bl_2_thumb {
- unsigned int imm;
+ unsigned int imm;
}bl_2_thumb;
typedef struct _blx_1_thumb {
- unsigned int imm;
- unsigned int instr;
+ unsigned int imm;
+ unsigned int instr;
}blx_1_thumb;
typedef struct _pkh_inst {
- u32 Rm;
- u32 Rn;
- u32 Rd;
- u8 imm;
+ u32 Rm;
+ u32 Rn;
+ u32 Rd;
+ u8 imm;
} pkh_inst;
typedef arm_inst * ARM_INST_PTR;
-#define CACHE_BUFFER_SIZE (64 * 1024 * 2000)
+#define CACHE_BUFFER_SIZE (64 * 1024 * 2000)
char inst_buf[CACHE_BUFFER_SIZE];
int top = 0;
-inline void *AllocBuffer(unsigned int size)
-{
- int start = top;
- top += size;
- if (top > CACHE_BUFFER_SIZE) {
- LOG_ERROR(Core_ARM11, "inst_buf is full");
- CITRA_IGNORE_EXIT(-1);
- }
- return (void *)&inst_buf[start];
-}
-
-int CondPassed(arm_processor *cpu, unsigned int cond)
-{
- #define NFLAG cpu->NFlag
- #define ZFLAG cpu->ZFlag
- #define CFLAG cpu->CFlag
- #define VFLAG cpu->VFlag
- int temp;
- switch (cond) {
- case 0x0:
- temp = ZFLAG;
- break;
- case 0x1: /* NE */
- temp = !ZFLAG;
- break;
- case 0x6: /* VS */
- temp = VFLAG;
- break;
- case 0x7: /* VC */
- temp = !VFLAG;
- break;
- case 0x4: /* MI */
- temp = NFLAG;
- break;
- case 0x5: /* PL */
- temp = !NFLAG;
- break;
- case 0x2: /* CS */
- temp = CFLAG;
- break;
- case 0x3: /* CC */
- temp = !CFLAG;
- break;
- case 0x8: /* HI */
- temp = (CFLAG && !ZFLAG);
- break;
- case 0x9: /* LS */
- temp = (!CFLAG || ZFLAG);
- break;
- case 0xa: /* GE */
- temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
- break;
- case 0xb: /* LT */
- temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
- break;
- case 0xc: /* GT */
- temp = ((!NFLAG && !VFLAG && !ZFLAG)
- || (NFLAG && VFLAG && !ZFLAG));
- break;
- case 0xd: /* LE */
- temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG))
- || ZFLAG;
- break;
- case 0xe: /* AL */
- temp = 1;
- break;
- case 0xf:
-// DEBUG_LOG(ARM11, "inst is %x\n");
-// DEBUG_LOG(ARM11, "icounter is %lld\n", cpu->icounter);
-// CITRA_IGNORE_EXIT(-1);
- temp = 1;
- break;
- }
- return temp;
+inline void *AllocBuffer(unsigned int size) {
+ int start = top;
+ top += size;
+ if (top > CACHE_BUFFER_SIZE) {
+ LOG_ERROR(Core_ARM11, "inst_buf is full");
+ CITRA_IGNORE_EXIT(-1);
+ }
+ return (void *)&inst_buf[start];
+}
+
+int CondPassed(arm_processor *cpu, unsigned int cond) {
+ #define NFLAG cpu->NFlag
+ #define ZFLAG cpu->ZFlag
+ #define CFLAG cpu->CFlag
+ #define VFLAG cpu->VFlag
+
+ int temp;
+
+ switch (cond) {
+ case 0x0:
+ temp = ZFLAG;
+ break;
+ case 0x1: // NE
+ temp = !ZFLAG;
+ break;
+ case 0x6: // VS
+ temp = VFLAG;
+ break;
+ case 0x7: // VC
+ temp = !VFLAG;
+ break;
+ case 0x4: // MI
+ temp = NFLAG;
+ break;
+ case 0x5: // PL
+ temp = !NFLAG;
+ break;
+ case 0x2: // CS
+ temp = CFLAG;
+ break;
+ case 0x3: // CC
+ temp = !CFLAG;
+ break;
+ case 0x8: // HI
+ temp = (CFLAG && !ZFLAG);
+ break;
+ case 0x9: // LS
+ temp = (!CFLAG || ZFLAG);
+ break;
+ case 0xa: // GE
+ temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
+ break;
+ case 0xb: // LT
+ temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
+ break;
+ case 0xc: // GT
+ temp = ((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG));
+ break;
+ case 0xd: // LE
+ temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
+ break;
+ case 0xe: // AL
+ temp = 1;
+ break;
+ case 0xf:
+ temp = 1;
+ break;
+ }
+ return temp;
}
enum DECODE_STATUS {
- DECODE_SUCCESS,
- DECODE_FAILURE
+ DECODE_SUCCESS,
+ DECODE_FAILURE
};
int decode_arm_instr(uint32_t instr, int32_t *idx);
-shtop_fp_t get_shtop(unsigned int inst)
-{
- if (BIT(inst, 25)) {
- return DPO(Immediate);
- } else if (BITS(inst, 4, 11) == 0) {
- return DPO(Register);
- } else if (BITS(inst, 4, 6) == 0) {
- return DPO(LogicalShiftLeftByImmediate);
- } else if (BITS(inst, 4, 7) == 1) {
- return DPO(LogicalShiftLeftByRegister);
- } else if (BITS(inst, 4, 6) == 2) {
- return DPO(LogicalShiftRightByImmediate);
- } else if (BITS(inst, 4, 7) == 3) {
- return DPO(LogicalShiftRightByRegister);
- } else if (BITS(inst, 4, 6) == 4) {
- return DPO(ArithmeticShiftRightByImmediate);
- } else if (BITS(inst, 4, 7) == 5) {
- return DPO(ArithmeticShiftRightByRegister);
- } else if (BITS(inst, 4, 6) == 6) {
- return DPO(RotateRightByImmediate);
- } else if (BITS(inst, 4, 7) == 7) {
- return DPO(RotateRightByRegister);
- }
- return NULL;
-}
-
-get_addr_fp_t get_calc_addr_op(unsigned int inst)
-{
- /* 1 */
- if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) {
-// DEBUG_LOG(ARM11, "line is %d", __LINE__);
- return LnSWoUB(ImmediateOffset);
- } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
-// DEBUG_MSG;
-// DEBUG_LOG(ARM11, "line is %d", __LINE__);
- return LnSWoUB(RegisterOffset);
- } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
-// DEBUG_MSG;
-// DEBUG_LOG(ARM11, "line is %d", __LINE__);
- return LnSWoUB(ScaledRegisterOffset);
- } else if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 1) {
-// DEBUG_LOG(ARM11, "line is %d", __LINE__);
- return LnSWoUB(ImmediatePreIndexed);
- } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BITS(inst, 4, 11) == 0) {
- return LnSWoUB(RegisterPreIndexed);
- } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BIT(inst, 4) == 0) {
- return LnSWoUB(ScaledRegisterPreIndexed);
- } else if (BITS(inst, 24, 27) == 4 && BIT(inst, 21) == 0) {
- return LnSWoUB(ImmediatePostIndexed);
- } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
-// DEBUG_MSG;
- return LnSWoUB(RegisterPostIndexed);
- } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
- return LnSWoUB(ScaledRegisterPostIndexed);
-// DEBUG_MSG;
- } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
- /* 2 */
-// DEBUG_LOG(ARM11, "line is %d", __LINE__);
- return MLnS(ImmediateOffset);
-// DEBUG_MSG;
- } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
-// DEBUG_LOG(ARM11, "line is %d\n", __LINE__);
- return MLnS(RegisterOffset);
-// DEBUG_MSG;
- } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
-// DEBUG_LOG(ARM11, "line is %d\n", __LINE__);
- return MLnS(ImmediatePreIndexed);
-// DEBUG_MSG;
- } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
- return MLnS(RegisterPreIndexed);
- } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
-// DEBUG_MSG;
- return MLnS(ImmediatePostIndexed);
- } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
- //DEBUG_MSG;
- return MLnS(RegisterPostIndexed);
- } else if (BITS(inst, 23, 27) == 0x11) {
- /* 3 */
-// DEBUG_MSG;
-// DEBUG_LOG(ARM11, "line is %d", __LINE__);
- return LdnStM(IncrementAfter);
- } else if (BITS(inst, 23, 27) == 0x13) {
-// DEBUG_LOG(ARM11, "line is %d", __LINE__);
- return LdnStM(IncrementBefore);
-// DEBUG_MSG;
- } else if (BITS(inst, 23, 27) == 0x10) {
-// DEBUG_MSG;
-// DEBUG_LOG(ARM11, "line is %d", __LINE__);
- return LdnStM(DecrementAfter);
- } else if (BITS(inst, 23, 27) == 0x12) {
-// DEBUG_MSG;
-// DEBUG_LOG(ARM11, "line is %d", __LINE__);
- return LdnStM(DecrementBefore);
- }
- #if 0
- DEBUG_LOG(ARM11, "In %s Unknown addressing mode\n", __FUNCTION__);
- DEBUG_LOG(ARM11, "inst:%x\n", inst);
- CITRA_IGNORE_EXIT(-1);
- #endif
- return NULL;
+shtop_fp_t get_shtop(unsigned int inst) {
+ if (BIT(inst, 25)) {
+ return DPO(Immediate);
+ } else if (BITS(inst, 4, 11) == 0) {
+ return DPO(Register);
+ } else if (BITS(inst, 4, 6) == 0) {
+ return DPO(LogicalShiftLeftByImmediate);
+ } else if (BITS(inst, 4, 7) == 1) {
+ return DPO(LogicalShiftLeftByRegister);
+ } else if (BITS(inst, 4, 6) == 2) {
+ return DPO(LogicalShiftRightByImmediate);
+ } else if (BITS(inst, 4, 7) == 3) {
+ return DPO(LogicalShiftRightByRegister);
+ } else if (BITS(inst, 4, 6) == 4) {
+ return DPO(ArithmeticShiftRightByImmediate);
+ } else if (BITS(inst, 4, 7) == 5) {
+ return DPO(ArithmeticShiftRightByRegister);
+ } else if (BITS(inst, 4, 6) == 6) {
+ return DPO(RotateRightByImmediate);
+ } else if (BITS(inst, 4, 7) == 7) {
+ return DPO(RotateRightByRegister);
+ }
+ return nullptr;
+}
+
+get_addr_fp_t get_calc_addr_op(unsigned int inst) {
+ if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) {
+ return LnSWoUB(ImmediateOffset);
+ } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
+ return LnSWoUB(RegisterOffset);
+ } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
+ return LnSWoUB(ScaledRegisterOffset);
+ } else if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 1) {
+ return LnSWoUB(ImmediatePreIndexed);
+ } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BITS(inst, 4, 11) == 0) {
+ return LnSWoUB(RegisterPreIndexed);
+ } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BIT(inst, 4) == 0) {
+ return LnSWoUB(ScaledRegisterPreIndexed);
+ } else if (BITS(inst, 24, 27) == 4 && BIT(inst, 21) == 0) {
+ return LnSWoUB(ImmediatePostIndexed);
+ } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
+ return LnSWoUB(RegisterPostIndexed);
+ } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
+ return LnSWoUB(ScaledRegisterPostIndexed);
+ } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+ return MLnS(ImmediateOffset);
+ } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+ return MLnS(RegisterOffset);
+ } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+ return MLnS(ImmediatePreIndexed);
+ } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+ return MLnS(RegisterPreIndexed);
+ } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+ return MLnS(ImmediatePostIndexed);
+ } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+ return MLnS(RegisterPostIndexed);
+ } else if (BITS(inst, 23, 27) == 0x11) {
+ return LdnStM(IncrementAfter);
+ } else if (BITS(inst, 23, 27) == 0x13) {
+ return LdnStM(IncrementBefore);
+ } else if (BITS(inst, 23, 27) == 0x10) {
+ return LdnStM(DecrementAfter);
+ } else if (BITS(inst, 23, 27) == 0x12) {
+ return LdnStM(DecrementBefore);
+ }
+ return nullptr;
}
#define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s)
-#define CHECK_RN (inst_cream->Rn == 15)
-#define CHECK_RM (inst_cream->Rm == 15)
-#define CHECK_RS (inst_cream->Rs == 15)
+#define CHECK_RN (inst_cream->Rn == 15)
+#define CHECK_RM (inst_cream->Rm == 15)
+#define CHECK_RS (inst_cream->Rs == 15)
#define UNIMPLEMENTED_INSTRUCTION(mnemonic) \
LOG_ERROR(Core_ARM11, "unimplemented instruction: %s", mnemonic); \
@@ -1637,972 +1423,969 @@ get_addr_fp_t get_calc_addr_op(unsigned int inst)
ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst));
- adc_inst *inst_cream = (adc_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- if (CHECK_RN)
- inst_base->load_r15 = 1;
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst));
+ adc_inst *inst_cream = (adc_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ if (CHECK_RN)
+ inst_base->load_r15 = 1;
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = get_shtop(inst);
+ if (inst_cream->Rd == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst));
- add_inst *inst_cream = (add_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- if (CHECK_RN)
- inst_base->load_r15 = 1;
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst));
+ add_inst *inst_cream = (add_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ if (CHECK_RN)
+ inst_base->load_r15 = 1;
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = get_shtop(inst);
+ if (inst_cream->Rd == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst));
- and_inst *inst_cream = (and_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- if (CHECK_RN)
- inst_base->load_r15 = 1;
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst));
+ and_inst *inst_cream = (and_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ if (CHECK_RN)
+ inst_base->load_r15 = 1;
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = get_shtop(inst);
+ if (inst_cream->Rd == 15)
+ inst_base->br = INDIRECT_BRANCH;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index)
{
- #define POSBRANCH ((inst & 0x7fffff) << 2)
- #define NEGBRANCH ((0xff000000 |(inst & 0xffffff)) << 2)
+ #define POSBRANCH ((inst & 0x7fffff) << 2)
+ #define NEGBRANCH ((0xff000000 |(inst & 0xffffff)) << 2)
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst));
- bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst));
+ bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = DIRECT_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = DIRECT_BRANCH;
- if (BIT(inst, 24))
- inst_base->br = CALL;
- if (BITS(inst, 28, 31) <= 0xe)
- inst_base->br |= COND;
+ if (BIT(inst, 24))
+ inst_base->br = CALL;
+ if (BITS(inst, 28, 31) <= 0xe)
+ inst_base->br |= COND;
- inst_cream->L = BIT(inst, 24);
- inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH;
+ inst_cream->L = BIT(inst, 24);
+ inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH;
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst));
- bic_inst *inst_cream = (bic_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- if (CHECK_RN)
- inst_base->load_r15 = 1;
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst));
+ bic_inst *inst_cream = (bic_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ if (CHECK_RN)
+ inst_base->load_r15 = 1;
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = get_shtop(inst);
+
+ if (inst_cream->Rd == 15)
+ inst_base->br = INDIRECT_BRANCH;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(bkpt)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("BKPT"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst));
- blx_inst *inst_cream = (blx_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst));
+ blx_inst *inst_cream = (blx_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = INDIRECT_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = INDIRECT_BRANCH;
- inst_cream->inst = inst;
- if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
- inst_cream->val.Rm = BITS(inst, 0, 3);
- } else {
- inst_cream->val.signed_immed_24 = BITS(inst, 0, 23);
- //DEBUG_LOG(ARM11, " blx inst is %x\n", inst);
- //CITRA_IGNORE_EXIT(-1);
-// DEBUG_MSG;
- }
+ inst_cream->inst = inst;
+ if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
+ inst_cream->val.Rm = BITS(inst, 0, 3);
+ } else {
+ inst_cream->val.signed_immed_24 = BITS(inst, 0, 23);
+ }
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst));
- bx_inst *inst_cream = (bx_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst));
+ bx_inst *inst_cream = (bx_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = INDIRECT_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = INDIRECT_BRANCH;
- inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rm = BITS(inst, 0, 3);
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("BXJ"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst));
- cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->CRm = BITS(inst, 0, 3);
- inst_cream->CRd = BITS(inst, 12, 15);
- inst_cream->CRn = BITS(inst, 16, 19);
- inst_cream->cp_num = BITS(inst, 8, 11);
- inst_cream->opcode_2 = BITS(inst, 5, 7);
- inst_cream->opcode_1 = BITS(inst, 20, 23);
- inst_cream->inst = inst;
-
- LOG_TRACE(Core_ARM11, "inst %x index %x", inst, index);
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst));
+ cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->CRm = BITS(inst, 0, 3);
+ inst_cream->CRd = BITS(inst, 12, 15);
+ inst_cream->CRn = BITS(inst, 16, 19);
+ inst_cream->cp_num = BITS(inst, 8, 11);
+ inst_cream->opcode_2 = BITS(inst, 5, 7);
+ inst_cream->opcode_1 = BITS(inst, 20, 23);
+ inst_cream->inst = inst;
+
+ LOG_TRACE(Core_ARM11, "inst %x index %x", inst, index);
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst));
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst));
- clz_inst *inst_cream = (clz_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst));
+ clz_inst *inst_cream = (clz_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 12, 15);
- if (CHECK_RM)
- inst_base->load_r15 = 1;
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ if (CHECK_RM)
+ inst_base->load_r15 = 1;
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst));
- cmn_inst *inst_cream = (cmn_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->I = BIT(inst, 25);
- //inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- //inst_cream->Rd = BITS(inst, 12, 15);
- if (CHECK_RN)
- inst_base->load_r15 = 1;
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst));
+ cmn_inst *inst_cream = (cmn_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->I = BIT(inst, 25);
+ //inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ //inst_cream->Rd = BITS(inst, 12, 15);
+ if (CHECK_RN)
+ inst_base->load_r15 = 1;
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = get_shtop(inst);
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst));
- cmp_inst *inst_cream = (cmp_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->Rn = BITS(inst, 16, 19);
- if (CHECK_RN)
- inst_base->load_r15 = 1;
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst));
+ cmp_inst *inst_cream = (cmp_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ if (CHECK_RN)
+ inst_base->load_r15 = 1;
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = get_shtop(inst);
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst));
- cps_inst *inst_cream = (cps_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst));
+ cps_inst *inst_cream = (cps_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->imod0 = BIT(inst, 18);
- inst_cream->imod1 = BIT(inst, 19);
- inst_cream->mmod = BIT(inst, 17);
- inst_cream->A = BIT(inst, 8);
- inst_cream->I = BIT(inst, 7);
- inst_cream->F = BIT(inst, 6);
- inst_cream->mode = BITS(inst, 0, 4);
+ inst_cream->imod0 = BIT(inst, 18);
+ inst_cream->imod1 = BIT(inst, 19);
+ inst_cream->mmod = BIT(inst, 17);
+ inst_cream->A = BIT(inst, 8);
+ inst_cream->I = BIT(inst, 7);
+ inst_cream->F = BIT(inst, 6);
+ inst_cream->mode = BITS(inst, 0, 4);
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
- mov_inst *inst_cream = (mov_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
+ mov_inst *inst_cream = (mov_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (inst_cream->Rd == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst));
- eor_inst *inst_cream = (eor_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- if (CHECK_RN)
- inst_base->load_r15 = 1;
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst));
+ eor_inst *inst_cream = (eor_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ if (CHECK_RN)
+ inst_base->load_r15 = 1;
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = get_shtop(inst);
+ if (inst_cream->Rd == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst));
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->inst = inst;
+ inst_cream->get_addr = get_calc_addr_op(inst);
- if (BIT(inst, 15)) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (BIT(inst, 15)) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
- sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
+ sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->rotate = BITS(inst, 10, 11);
- if (CHECK_RM)
- inst_base->load_r15 = 1;
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->rotate = BITS(inst, 10, 11);
+ if (CHECK_RM)
+ inst_base->load_r15 = 1;
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->inst = inst;
+ inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->inst = inst;
+ inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
- uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
+ uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- if (CHECK_RM)
- inst_base->load_r15 = 1;
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->rotate = BITS(inst, 10, 11);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ if (CHECK_RM)
+ inst_base->load_r15 = 1;
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst));
- uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst));
+ uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- if (CHECK_RM || CHECK_RN)
- inst_base->load_r15 = 1;
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->rotate = BITS(inst, 10, 11);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ if (CHECK_RM || CHECK_RN)
+ inst_base->load_r15 = 1;
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->inst = inst;
+ inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- if (I_BIT == 0) {
- inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
- } else {
- DEBUG_MSG;
- }
- #if 0
- inst_cream->get_addr = get_calc_addr_op(inst);
- if(inst == 0x54f13001) {
- DEBUG_LOG(ARM11, "get_calc_addr_op:%llx\n", inst_cream->get_addr);
- }
- #endif
-
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+
+ inst_cream->inst = inst;
+ if (I_BIT == 0) {
+ inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
+ } else {
+ DEBUG_MSG;
+ }
+ #if 0
+ inst_cream->get_addr = get_calc_addr_op(inst);
+ if(inst == 0x54f13001) {
+ DEBUG_LOG(ARM11, "get_calc_addr_op:%llx\n", inst_cream->get_addr);
+ }
+ #endif
+
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->inst = inst;
+ inst_cream->get_addr = get_calc_addr_op(inst);
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- //inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->inst = inst;
+ //inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->inst = inst;
+ inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->inst = inst;
+ inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->inst = inst;
+ inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->inst = inst;
+ inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- if (I_BIT == 0) {
- inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
- } else {
- DEBUG_MSG;
- }
+ inst_cream->inst = inst;
+ if (I_BIT == 0) {
+ inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
+ } else {
+ DEBUG_MSG;
+ }
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst));
- mcr_inst *inst_cream = (mcr_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->crn = BITS(inst, 16, 19);
- inst_cream->crm = BITS(inst, 0, 3);
- inst_cream->opcode_1 = BITS(inst, 21, 23);
- inst_cream->opcode_2 = BITS(inst, 5, 7);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->cp_num = BITS(inst, 8, 11);
- inst_cream->inst = inst;
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst));
+ mcr_inst *inst_cream = (mcr_inst *)inst_base->component;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+
+ inst_cream->crn = BITS(inst, 16, 19);
+ inst_cream->crm = BITS(inst, 0, 3);
+ inst_cream->opcode_1 = BITS(inst, 21, 23);
+ inst_cream->opcode_2 = BITS(inst, 5, 7);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->cp_num = BITS(inst, 8, 11);
+ inst_cream->inst = inst;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(mcrr)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("MCRR"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst));
- mla_inst *inst_cream = (mla_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst));
+ mla_inst *inst_cream = (mla_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 12, 15);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 12, 15);
+ inst_cream->Rd = BITS(inst, 16, 19);
+ inst_cream->Rs = BITS(inst, 8, 11);
+ inst_cream->Rm = BITS(inst, 0, 3);
- if (CHECK_RM || CHECK_RN || CHECK_RS)
- inst_base->load_r15 = 1;
+ if (CHECK_RM || CHECK_RN || CHECK_RS)
+ inst_base->load_r15 = 1;
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
- mov_inst *inst_cream = (mov_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
+ mov_inst *inst_cream = (mov_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (inst_cream->Rd == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst));
- mrc_inst *inst_cream = (mrc_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->crn = BITS(inst, 16, 19);
- inst_cream->crm = BITS(inst, 0, 3);
- inst_cream->opcode_1 = BITS(inst, 21, 23);
- inst_cream->opcode_2 = BITS(inst, 5, 7);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->cp_num = BITS(inst, 8, 11);
- inst_cream->inst = inst;
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst));
+ mrc_inst *inst_cream = (mrc_inst *)inst_base->component;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+
+ inst_cream->crn = BITS(inst, 16, 19);
+ inst_cream->crm = BITS(inst, 0, 3);
+ inst_cream->opcode_1 = BITS(inst, 21, 23);
+ inst_cream->opcode_2 = BITS(inst, 5, 7);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->cp_num = BITS(inst, 8, 11);
+ inst_cream->inst = inst;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(mrrc)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("MRRC"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst));
- mrs_inst *inst_cream = (mrs_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst));
+ mrs_inst *inst_cream = (mrs_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->R = BIT(inst, 22);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->R = BIT(inst, 22);
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst));
- msr_inst *inst_cream = (msr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst));
+ msr_inst *inst_cream = (msr_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->field_mask = BITS(inst, 16, 19);
- inst_cream->R = BIT(inst, 22);
- inst_cream->inst = inst;
+ inst_cream->field_mask = BITS(inst, 16, 19);
+ inst_cream->R = BIT(inst, 22);
+ inst_cream->inst = inst;
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst));
- mul_inst *inst_cream = (mul_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst));
+ mul_inst *inst_cream = (mul_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->Rd = BITS(inst, 16, 19);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rs = BITS(inst, 8, 11);
+ inst_cream->Rd = BITS(inst, 16, 19);
- if (CHECK_RM || CHECK_RS)
- inst_base->load_r15 = 1;
- return inst_base;
+ if (CHECK_RM || CHECK_RS)
+ inst_base->load_r15 = 1;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst));
- mvn_inst *inst_cream = (mvn_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst));
+ mvn_inst *inst_cream = (mvn_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (inst_cream->Rd == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst));
- orr_inst *inst_cream = (orr_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- if (CHECK_RN)
- inst_base->load_r15 = 1;
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst));
+ orr_inst *inst_cream = (orr_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = get_shtop(inst);
+
+ if (CHECK_RN)
+ inst_base->load_r15 = 1;
+ if (inst_cream->Rd == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst));
- pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst));
+ pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->imm = BITS(inst, 7, 11);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->imm = BITS(inst, 7, 11);
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(pkhbt)(inst, index);
+ return INTERPRETER_TRANSLATE(pkhbt)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst));
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index)
{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->op1 = BITS(inst, 20, 21);
+ inst_cream->op2 = BITS(inst, 5, 7);
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
+ return INTERPRETER_TRANSLATE(qadd8)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
+ return INTERPRETER_TRANSLATE(qadd8)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDADD"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDSUB"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
+ return INTERPRETER_TRANSLATE(qadd8)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
+ return INTERPRETER_TRANSLATE(qadd8)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
+ return INTERPRETER_TRANSLATE(qadd8)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
- rev_inst *inst_cream = (rev_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
+ rev_inst *inst_cream = (rev_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rd = BITS(inst, 12, 15);
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index){
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
- rev_inst *inst_cream = (rev_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
+ rev_inst *inst_cream = (rev_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rd = BITS(inst, 12, 15);
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("REVSH"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("RFE"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst));
- rsb_inst *inst_cream = (rsb_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (CHECK_RN)
- inst_base->load_r15 = 1;
-
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst));
+ rsb_inst *inst_cream = (rsb_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = get_shtop(inst);
+ if (CHECK_RN)
+ inst_base->load_r15 = 1;
+
+ if (inst_cream->Rd == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst));
- rsc_inst *inst_cream = (rsc_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (CHECK_RN)
- inst_base->load_r15 = 1;
-
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst));
+ rsc_inst *inst_cream = (rsc_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = get_shtop(inst);
+ if (CHECK_RN)
+ inst_base->load_r15 = 1;
+
+ if (inst_cream->Rd == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SADD8"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index)
{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
-
- return inst_base;
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->op1 = BITS(inst, 20, 21);
+ inst_cream->op2 = BITS(inst, 5, 7);
+
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(sadd16)(inst, index);
+ return INTERPRETER_TRANSLATE(sadd16)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst));
- sbc_inst *inst_cream = (sbc_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (CHECK_RN)
- inst_base->load_r15 = 1;
-
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst));
+ sbc_inst *inst_cream = (sbc_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = get_shtop(inst);
+ if (CHECK_RN)
+ inst_base->load_r15 = 1;
+
+ if (inst_cream->Rd == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index)
{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 22);
- inst_cream->op2 = BITS(inst, 5, 7);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->op1 = BITS(inst, 20, 22);
+ inst_cream->op2 = BITS(inst, 5, 7);
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SETEND"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADD16"); }
@@ -2613,61 +2396,61 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index) { UN
ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUBADDX"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst));
- smla_inst *inst_cream = (smla_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst));
+ smla_inst *inst_cream = (smla_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->x = BIT(inst, 5);
- inst_cream->y = BIT(inst, 6);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Rn = BITS(inst, 12, 15);
+ inst_cream->x = BIT(inst, 5);
+ inst_cream->y = BIT(inst, 6);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rs = BITS(inst, 8, 11);
+ inst_cream->Rd = BITS(inst, 16, 19);
+ inst_cream->Rn = BITS(inst, 12, 15);
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index){
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
- smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
+ smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->m = BIT(inst, 4);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Ra = BITS(inst, 12, 15);
+ inst_cream->m = BIT(inst, 4);
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->Rm = BITS(inst, 8, 11);
+ inst_cream->Rd = BITS(inst, 16, 19);
+ inst_cream->Ra = BITS(inst, 12, 15);
- if (CHECK_RM )
- inst_base->load_r15 = 1;
- return inst_base;
+ if (CHECK_RM )
+ inst_base->load_r15 = 1;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
- umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
+ umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->RdLo = BITS(inst, 12, 15);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rs = BITS(inst, 8, 11);
+ inst_cream->RdHi = BITS(inst, 16, 19);
+ inst_cream->RdLo = BITS(inst, 12, 15);
- if (CHECK_RM || CHECK_RS)
- inst_base->load_r15 = 1;
- return inst_base;
+ if (CHECK_RM || CHECK_RS)
+ inst_base->load_r15 = 1;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALXY"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALD"); }
@@ -2680,65 +2463,65 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index) { UNIM
ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUAD"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst));
- smul_inst *inst_cream = (smul_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst));
+ smul_inst *inst_cream = (smul_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rd = BITS(inst, 16, 19);
+ inst_cream->Rs = BITS(inst, 8, 11);
+ inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->x = BIT(inst, 5);
- inst_cream->y = BIT(inst, 6);
+ inst_cream->x = BIT(inst, 5);
+ inst_cream->y = BIT(inst, 6);
- if (CHECK_RM || CHECK_RS)
- inst_base->load_r15 = 1;
- return inst_base;
+ if (CHECK_RM || CHECK_RS)
+ inst_base->load_r15 = 1;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
- umull_inst *inst_cream = (umull_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
+ umull_inst *inst_cream = (umull_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->RdLo = BITS(inst, 12, 15);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rs = BITS(inst, 8, 11);
+ inst_cream->RdHi = BITS(inst, 16, 19);
+ inst_cream->RdLo = BITS(inst, 12, 15);
- if (CHECK_RM || CHECK_RS)
- inst_base->load_r15 = 1;
- return inst_base;
+ if (CHECK_RM || CHECK_RS)
+ inst_base->load_r15 = 1;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
- smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
+ smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->m = BIT(inst, 6);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 16, 19);
+ inst_cream->m = BIT(inst, 6);
+ inst_cream->Rm = BITS(inst, 8, 11);
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->Rd = BITS(inst, 16, 19);
- if (CHECK_RM || CHECK_RN)
- inst_base->load_r15 = 1;
- return inst_base;
+ if (CHECK_RM || CHECK_RN)
+ inst_base->load_r15 = 1;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUSD"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SRS"); }
@@ -2747,602 +2530,603 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index) { UNI
ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSUB8"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(sadd16)(inst, index);
+ return INTERPRETER_TRANSLATE(sadd16)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(sadd16)(inst, index);
+ return INTERPRETER_TRANSLATE(sadd16)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst));
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
- return inst_base;
+ inst_cream->inst = inst;
+ inst_cream->get_addr = get_calc_addr_op(inst);
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
- sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
+ sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->rotate = BITS(inst, 10, 11);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->rotate = BITS(inst, 10, 11);
- if (CHECK_RM)
- inst_base->load_r15 = 1;
- return inst_base;
+ if (CHECK_RM)
+ inst_base->load_r15 = 1;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->inst = inst;
+ inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
- uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
+ uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->rotate = BITS(inst, 10, 11);
+ inst_cream->Rm = BITS(inst, 0, 3);
- if (CHECK_RM)
- inst_base->load_r15 = 1;
- return inst_base;
+ if (CHECK_RM)
+ inst_base->load_r15 = 1;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
- uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
+ uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->rotate = BITS(inst, 10, 11);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->inst = inst;
+ inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
-// inst_cream->get_addr = get_calc_addr_op(inst);
- if (I_BIT == 0) {
- inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
- } else {
- DEBUG_MSG;
- }
-
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+
+ inst_cream->inst = inst;
+// inst_cream->get_addr = get_calc_addr_op(inst);
+ if (I_BIT == 0) {
+ inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
+ } else {
+ DEBUG_MSG;
+ }
+
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->inst = inst;
+ inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->inst = inst;
+ inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->inst = inst;
+ inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->inst = inst;
+ inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- if (I_BIT == 0) {
- inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
- } else {
- DEBUG_MSG;
- }
+ inst_cream->inst = inst;
+ if (I_BIT == 0) {
+ inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
+ } else {
+ DEBUG_MSG;
+ }
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst));
- sub_inst *inst_cream = (sub_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- if (CHECK_RN)
- inst_base->load_r15 = 1;
-
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst));
+ sub_inst *inst_cream = (sub_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = get_shtop(inst);
+ if (inst_cream->Rd == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ if (CHECK_RN)
+ inst_base->load_r15 = 1;
+
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(swi)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst));
- swi_inst *inst_cream = (swi_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst));
+ swi_inst *inst_cream = (swi_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->num = BITS(inst, 0, 23);
- return inst_base;
+ inst_cream->num = BITS(inst, 0, 23);
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
- swp_inst *inst_cream = (swp_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
+ swp_inst *inst_cream = (swp_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 0, 3);
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (inst_cream->Rd == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
- swp_inst *inst_cream = (swp_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
+ swp_inst *inst_cream = (swp_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 0, 3);
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ if (inst_cream->Rd == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst));
- sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst));
+ sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->rotate = BITS(inst, 10, 11);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SXTAB16"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index){
- LOG_WARNING(Core_ARM11, "SXTAH untested");
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst));
- sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
+ LOG_WARNING(Core_ARM11, "SXTAH untested");
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst));
+ sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->rotate = BITS(inst, 10, 11);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SXTB16"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst));
- teq_inst *inst_cream = (teq_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst));
+ teq_inst *inst_cream = (teq_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->I = BIT(inst, 25);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = get_shtop(inst);
- if (CHECK_RN)
- inst_base->load_r15 = 1;
- return inst_base;
+ if (CHECK_RN)
+ inst_base->load_r15 = 1;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst));
- tst_inst *inst_cream = (tst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
-
- if (CHECK_RN)
- inst_base->load_r15 = 1;
- return inst_base;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst));
+ tst_inst *inst_cream = (tst_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = get_shtop(inst);
+ if (inst_cream->Rd == 15) {
+ inst_base->br = INDIRECT_BRANCH;
+ }
+
+ if (CHECK_RN)
+ inst_base->load_r15 = 1;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD8"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADDSUBX"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index)
{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->op1 = BITS(inst, 20, 21);
+ inst_cream->op2 = BITS(inst, 5, 7);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
+ return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
+ return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
+ return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
+ return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
+ return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index)
{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umaal_inst));
- umaal_inst* const inst_cream = (umaal_inst*)inst_base->component;
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umaal_inst));
+ umaal_inst* const inst_cream = (umaal_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->RdLo = BITS(inst, 12, 15);
- inst_cream->RdHi = BITS(inst, 16, 19);
+ inst_cream->Rm = BITS(inst, 8, 11);
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->RdLo = BITS(inst, 12, 15);
+ inst_cream->RdHi = BITS(inst, 16, 19);
- if (CHECK_RM || CHECK_RN)
- inst_base->load_r15 = 1;
+ if (CHECK_RM || CHECK_RN)
+ inst_base->load_r15 = 1;
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
- umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
+ umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->RdLo = BITS(inst, 12, 15);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rs = BITS(inst, 8, 11);
+ inst_cream->RdHi = BITS(inst, 16, 19);
+ inst_cream->RdLo = BITS(inst, 12, 15);
- if (CHECK_RM || CHECK_RS)
- inst_base->load_r15 = 1;
- return inst_base;
+ if (CHECK_RM || CHECK_RS)
+ inst_base->load_r15 = 1;
+
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(umull)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
- umull_inst *inst_cream = (umull_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
+ umull_inst *inst_cream = (umull_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->RdLo = BITS(inst, 12, 15);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rs = BITS(inst, 8, 11);
+ inst_cream->RdHi = BITS(inst, 16, 19);
+ inst_cream->RdLo = BITS(inst, 12, 15);
- if (CHECK_RM || CHECK_RS)
- inst_base->load_r15 = 1;
- return inst_base;
+ if (CHECK_RM || CHECK_RS)
+ inst_base->load_r15 = 1;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb));
- b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb));
+ b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component;
+
+ inst_cream->imm = ((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0);
- inst_cream->imm =((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0);
- //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm);
- inst_base->idx = index;
- inst_base->br = DIRECT_BRANCH;
- return inst_base;
+ inst_base->idx = index;
+ inst_base->br = DIRECT_BRANCH;
+
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb));
- b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb));
+ b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component;
+
+ inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0));
+ inst_cream->cond = ((tinst >> 8) & 0xf);
+ inst_base->idx = index;
+ inst_base->br = DIRECT_BRANCH;
- inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0));
- inst_cream->cond = ((tinst >> 8) & 0xf);
- //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x, cond=0x%x\n", __FUNCTION__, tinst, inst_cream->imm, inst_cream->cond);
- inst_base->idx = index;
- inst_base->br = DIRECT_BRANCH;
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb));
- bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb));
+ bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component;
- inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0));
- //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm);
+ inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0));
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- return inst_base;
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb));
- bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb));
+ bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component;
+
+ inst_cream->imm = (tinst & 0x07FF) << 1;
- inst_cream->imm = (tinst & 0x07FF) << 1;
- //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm);
- inst_base->idx = index;
- inst_base->br = DIRECT_BRANCH;
- return inst_base;
+ inst_base->idx = index;
+ inst_base->br = DIRECT_BRANCH;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb));
- blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb));
+ blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
- inst_cream->imm = (tinst & 0x07FF) << 1;
- //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm);
- inst_cream->instr = tinst;
- inst_base->idx = index;
- inst_base->br = DIRECT_BRANCH;
- return inst_base;
+ inst_cream->imm = (tinst & 0x07FF) << 1;
+ inst_cream->instr = tinst;
+
+ inst_base->idx = index;
+ inst_base->br = DIRECT_BRANCH;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index)
{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->op1 = BITS(inst, 20, 21);
+ inst_cream->op2 = BITS(inst, 5, 7);
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
+ return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
+ return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
+ return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
+ return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
+ return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index)
{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->op1 = BITS(inst, 20, 24);
- inst_cream->op2 = BITS(inst, 5, 7);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Ra = BITS(inst, 12, 15);
+ inst_cream->op1 = BITS(inst, 20, 24);
+ inst_cream->op2 = BITS(inst, 5, 7);
+ inst_cream->Rm = BITS(inst, 8, 11);
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->Ra = BITS(inst, 12, 15);
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(usada8)(inst, index);
+ return INTERPRETER_TRANSLATE(usada8)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT16"); }
@@ -3352,27 +3136,27 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index) { UN
ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index)
{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
- uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component;
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
+ uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->rotate = BITS(inst, 10, 11);
- return inst_base;
+ return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(uxtab16)(inst, index);
+ return INTERPRETER_TRANSLATE(uxtab16)(inst, index);
}
-/* Floating point VFPv3 structures and instructions */
+// Floating point VFPv3 structures and instructions
#define VFP_INTERPRETER_STRUCT
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
@@ -3382,352 +3166,288 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index)
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
#undef VFP_INTERPRETER_TRANS
-
-
typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int);
const transop_fp_t arm_instruction_trans[] = {
- INTERPRETER_TRANSLATE(vmla),
- INTERPRETER_TRANSLATE(vmls),
- INTERPRETER_TRANSLATE(vnmla),
- INTERPRETER_TRANSLATE(vnmla),
- INTERPRETER_TRANSLATE(vnmls),
- INTERPRETER_TRANSLATE(vnmul),
- INTERPRETER_TRANSLATE(vmul),
- INTERPRETER_TRANSLATE(vadd),
- INTERPRETER_TRANSLATE(vsub),
- INTERPRETER_TRANSLATE(vdiv),
- INTERPRETER_TRANSLATE(vmovi),
- INTERPRETER_TRANSLATE(vmovr),
- INTERPRETER_TRANSLATE(vabs),
- INTERPRETER_TRANSLATE(vneg),
- INTERPRETER_TRANSLATE(vsqrt),
- INTERPRETER_TRANSLATE(vcmp),
- INTERPRETER_TRANSLATE(vcmp2),
- INTERPRETER_TRANSLATE(vcvtbds),
- INTERPRETER_TRANSLATE(vcvtbff),
- INTERPRETER_TRANSLATE(vcvtbfi),
- INTERPRETER_TRANSLATE(vmovbrs),
- INTERPRETER_TRANSLATE(vmsr),
- INTERPRETER_TRANSLATE(vmovbrc),
- INTERPRETER_TRANSLATE(vmrs),
- INTERPRETER_TRANSLATE(vmovbcr),
- INTERPRETER_TRANSLATE(vmovbrrss),
- INTERPRETER_TRANSLATE(vmovbrrd),
- INTERPRETER_TRANSLATE(vstr),
- INTERPRETER_TRANSLATE(vpush),
- INTERPRETER_TRANSLATE(vstm),
- INTERPRETER_TRANSLATE(vpop),
- INTERPRETER_TRANSLATE(vldr),
- INTERPRETER_TRANSLATE(vldm),
-
- INTERPRETER_TRANSLATE(srs),
- INTERPRETER_TRANSLATE(rfe),
- INTERPRETER_TRANSLATE(bkpt),
- INTERPRETER_TRANSLATE(blx),
- INTERPRETER_TRANSLATE(cps),
- INTERPRETER_TRANSLATE(pld),
- INTERPRETER_TRANSLATE(setend),
- INTERPRETER_TRANSLATE(clrex),
- INTERPRETER_TRANSLATE(rev16),
- INTERPRETER_TRANSLATE(usad8),
- INTERPRETER_TRANSLATE(sxtb),
- INTERPRETER_TRANSLATE(uxtb),
- INTERPRETER_TRANSLATE(sxth),
- INTERPRETER_TRANSLATE(sxtb16),
- INTERPRETER_TRANSLATE(uxth),
- INTERPRETER_TRANSLATE(uxtb16),
- INTERPRETER_TRANSLATE(cpy),
- INTERPRETER_TRANSLATE(uxtab),
- INTERPRETER_TRANSLATE(ssub8),
- INTERPRETER_TRANSLATE(shsub8),
- INTERPRETER_TRANSLATE(ssubaddx),
- INTERPRETER_TRANSLATE(strex),
- INTERPRETER_TRANSLATE(strexb),
- INTERPRETER_TRANSLATE(swp),
- INTERPRETER_TRANSLATE(swpb),
- INTERPRETER_TRANSLATE(ssub16),
- INTERPRETER_TRANSLATE(ssat16),
- INTERPRETER_TRANSLATE(shsubaddx),
- INTERPRETER_TRANSLATE(qsubaddx),
- INTERPRETER_TRANSLATE(shaddsubx),
- INTERPRETER_TRANSLATE(shadd8),
- INTERPRETER_TRANSLATE(shadd16),
- INTERPRETER_TRANSLATE(sel),
- INTERPRETER_TRANSLATE(saddsubx),
- INTERPRETER_TRANSLATE(sadd8),
- INTERPRETER_TRANSLATE(sadd16),
- INTERPRETER_TRANSLATE(shsub16),
- INTERPRETER_TRANSLATE(umaal),
- INTERPRETER_TRANSLATE(uxtab16),
- INTERPRETER_TRANSLATE(usubaddx),
- INTERPRETER_TRANSLATE(usub8),
- INTERPRETER_TRANSLATE(usub16),
- INTERPRETER_TRANSLATE(usat16),
- INTERPRETER_TRANSLATE(usada8),
- INTERPRETER_TRANSLATE(uqsubaddx),
- INTERPRETER_TRANSLATE(uqsub8),
- INTERPRETER_TRANSLATE(uqsub16),
- INTERPRETER_TRANSLATE(uqaddsubx),
- INTERPRETER_TRANSLATE(uqadd8),
- INTERPRETER_TRANSLATE(uqadd16),
- INTERPRETER_TRANSLATE(sxtab),
- INTERPRETER_TRANSLATE(uhsubaddx),
- INTERPRETER_TRANSLATE(uhsub8),
- INTERPRETER_TRANSLATE(uhsub16),
- INTERPRETER_TRANSLATE(uhaddsubx),
- INTERPRETER_TRANSLATE(uhadd8),
- INTERPRETER_TRANSLATE(uhadd16),
- INTERPRETER_TRANSLATE(uaddsubx),
- INTERPRETER_TRANSLATE(uadd8),
- INTERPRETER_TRANSLATE(uadd16),
- INTERPRETER_TRANSLATE(sxtah),
- INTERPRETER_TRANSLATE(sxtab16),
- INTERPRETER_TRANSLATE(qadd8),
- INTERPRETER_TRANSLATE(bxj),
- INTERPRETER_TRANSLATE(clz),
- INTERPRETER_TRANSLATE(uxtah),
- INTERPRETER_TRANSLATE(bx),
- INTERPRETER_TRANSLATE(rev),
- INTERPRETER_TRANSLATE(blx),
- INTERPRETER_TRANSLATE(revsh),
- INTERPRETER_TRANSLATE(qadd),
- INTERPRETER_TRANSLATE(qadd16),
- INTERPRETER_TRANSLATE(qaddsubx),
- INTERPRETER_TRANSLATE(ldrex),
- INTERPRETER_TRANSLATE(qdadd),
- INTERPRETER_TRANSLATE(qdsub),
- INTERPRETER_TRANSLATE(qsub),
- INTERPRETER_TRANSLATE(ldrexb),
- INTERPRETER_TRANSLATE(qsub8),
- INTERPRETER_TRANSLATE(qsub16),
- INTERPRETER_TRANSLATE(smuad),
- INTERPRETER_TRANSLATE(smmul),
- INTERPRETER_TRANSLATE(smusd),
- INTERPRETER_TRANSLATE(smlsd),
- INTERPRETER_TRANSLATE(smlsld),
- INTERPRETER_TRANSLATE(smmla),
- INTERPRETER_TRANSLATE(smmls),
- INTERPRETER_TRANSLATE(smlald),
- INTERPRETER_TRANSLATE(smlad),
- INTERPRETER_TRANSLATE(smlaw),
- INTERPRETER_TRANSLATE(smulw),
- INTERPRETER_TRANSLATE(pkhtb),
- INTERPRETER_TRANSLATE(pkhbt),
- INTERPRETER_TRANSLATE(smul),
- INTERPRETER_TRANSLATE(smlalxy),
- INTERPRETER_TRANSLATE(smla),
- INTERPRETER_TRANSLATE(mcrr),
- INTERPRETER_TRANSLATE(mrrc),
- INTERPRETER_TRANSLATE(cmp),
- INTERPRETER_TRANSLATE(tst),
- INTERPRETER_TRANSLATE(teq),
- INTERPRETER_TRANSLATE(cmn),
- INTERPRETER_TRANSLATE(smull),
- INTERPRETER_TRANSLATE(umull),
- INTERPRETER_TRANSLATE(umlal),
- INTERPRETER_TRANSLATE(smlal),
- INTERPRETER_TRANSLATE(mul),
- INTERPRETER_TRANSLATE(mla),
- INTERPRETER_TRANSLATE(ssat),
- INTERPRETER_TRANSLATE(usat),
- INTERPRETER_TRANSLATE(mrs),
- INTERPRETER_TRANSLATE(msr),
- INTERPRETER_TRANSLATE(and),
- INTERPRETER_TRANSLATE(bic),
- INTERPRETER_TRANSLATE(ldm),
- INTERPRETER_TRANSLATE(eor),
- INTERPRETER_TRANSLATE(add),
- INTERPRETER_TRANSLATE(rsb),
- INTERPRETER_TRANSLATE(rsc),
- INTERPRETER_TRANSLATE(sbc),
- INTERPRETER_TRANSLATE(adc),
- INTERPRETER_TRANSLATE(sub),
- INTERPRETER_TRANSLATE(orr),
- INTERPRETER_TRANSLATE(mvn),
- INTERPRETER_TRANSLATE(mov),
- INTERPRETER_TRANSLATE(stm),
- INTERPRETER_TRANSLATE(ldm),
- INTERPRETER_TRANSLATE(ldrsh),
- INTERPRETER_TRANSLATE(stm),
- INTERPRETER_TRANSLATE(ldm),
- INTERPRETER_TRANSLATE(ldrsb),
- INTERPRETER_TRANSLATE(strd),
- INTERPRETER_TRANSLATE(ldrh),
- INTERPRETER_TRANSLATE(strh),
- INTERPRETER_TRANSLATE(ldrd),
- INTERPRETER_TRANSLATE(strt),
- INTERPRETER_TRANSLATE(strbt),
- INTERPRETER_TRANSLATE(ldrbt),
- INTERPRETER_TRANSLATE(ldrt),
- INTERPRETER_TRANSLATE(mrc),
- INTERPRETER_TRANSLATE(mcr),
- INTERPRETER_TRANSLATE(msr),
- INTERPRETER_TRANSLATE(ldrb),
- INTERPRETER_TRANSLATE(strb),
- INTERPRETER_TRANSLATE(ldr),
- INTERPRETER_TRANSLATE(ldrcond),
- INTERPRETER_TRANSLATE(str),
- INTERPRETER_TRANSLATE(cdp),
- INTERPRETER_TRANSLATE(stc),
- INTERPRETER_TRANSLATE(ldc),
- INTERPRETER_TRANSLATE(swi),
- INTERPRETER_TRANSLATE(bbl),
- /* All the thumb instructions should be placed the end of table */
- INTERPRETER_TRANSLATE(b_2_thumb),
- INTERPRETER_TRANSLATE(b_cond_thumb),
- INTERPRETER_TRANSLATE(bl_1_thumb),
- INTERPRETER_TRANSLATE(bl_2_thumb),
- INTERPRETER_TRANSLATE(blx_1_thumb)
+ INTERPRETER_TRANSLATE(vmla),
+ INTERPRETER_TRANSLATE(vmls),
+ INTERPRETER_TRANSLATE(vnmla),
+ INTERPRETER_TRANSLATE(vnmla),
+ INTERPRETER_TRANSLATE(vnmls),
+ INTERPRETER_TRANSLATE(vnmul),
+ INTERPRETER_TRANSLATE(vmul),
+ INTERPRETER_TRANSLATE(vadd),
+ INTERPRETER_TRANSLATE(vsub),
+ INTERPRETER_TRANSLATE(vdiv),
+ INTERPRETER_TRANSLATE(vmovi),
+ INTERPRETER_TRANSLATE(vmovr),
+ INTERPRETER_TRANSLATE(vabs),
+ INTERPRETER_TRANSLATE(vneg),
+ INTERPRETER_TRANSLATE(vsqrt),
+ INTERPRETER_TRANSLATE(vcmp),
+ INTERPRETER_TRANSLATE(vcmp2),
+ INTERPRETER_TRANSLATE(vcvtbds),
+ INTERPRETER_TRANSLATE(vcvtbff),
+ INTERPRETER_TRANSLATE(vcvtbfi),
+ INTERPRETER_TRANSLATE(vmovbrs),
+ INTERPRETER_TRANSLATE(vmsr),
+ INTERPRETER_TRANSLATE(vmovbrc),
+ INTERPRETER_TRANSLATE(vmrs),
+ INTERPRETER_TRANSLATE(vmovbcr),
+ INTERPRETER_TRANSLATE(vmovbrrss),
+ INTERPRETER_TRANSLATE(vmovbrrd),
+ INTERPRETER_TRANSLATE(vstr),
+ INTERPRETER_TRANSLATE(vpush),
+ INTERPRETER_TRANSLATE(vstm),
+ INTERPRETER_TRANSLATE(vpop),
+ INTERPRETER_TRANSLATE(vldr),
+ INTERPRETER_TRANSLATE(vldm),
+
+ INTERPRETER_TRANSLATE(srs),
+ INTERPRETER_TRANSLATE(rfe),
+ INTERPRETER_TRANSLATE(bkpt),
+ INTERPRETER_TRANSLATE(blx),
+ INTERPRETER_TRANSLATE(cps),
+ INTERPRETER_TRANSLATE(pld),
+ INTERPRETER_TRANSLATE(setend),
+ INTERPRETER_TRANSLATE(clrex),
+ INTERPRETER_TRANSLATE(rev16),
+ INTERPRETER_TRANSLATE(usad8),
+ INTERPRETER_TRANSLATE(sxtb),
+ INTERPRETER_TRANSLATE(uxtb),
+ INTERPRETER_TRANSLATE(sxth),
+ INTERPRETER_TRANSLATE(sxtb16),
+ INTERPRETER_TRANSLATE(uxth),
+ INTERPRETER_TRANSLATE(uxtb16),
+ INTERPRETER_TRANSLATE(cpy),
+ INTERPRETER_TRANSLATE(uxtab),
+ INTERPRETER_TRANSLATE(ssub8),
+ INTERPRETER_TRANSLATE(shsub8),
+ INTERPRETER_TRANSLATE(ssubaddx),
+ INTERPRETER_TRANSLATE(strex),
+ INTERPRETER_TRANSLATE(strexb),
+ INTERPRETER_TRANSLATE(swp),
+ INTERPRETER_TRANSLATE(swpb),
+ INTERPRETER_TRANSLATE(ssub16),
+ INTERPRETER_TRANSLATE(ssat16),
+ INTERPRETER_TRANSLATE(shsubaddx),
+ INTERPRETER_TRANSLATE(qsubaddx),
+ INTERPRETER_TRANSLATE(shaddsubx),
+ INTERPRETER_TRANSLATE(shadd8),
+ INTERPRETER_TRANSLATE(shadd16),
+ INTERPRETER_TRANSLATE(sel),
+ INTERPRETER_TRANSLATE(saddsubx),
+ INTERPRETER_TRANSLATE(sadd8),
+ INTERPRETER_TRANSLATE(sadd16),
+ INTERPRETER_TRANSLATE(shsub16),
+ INTERPRETER_TRANSLATE(umaal),
+ INTERPRETER_TRANSLATE(uxtab16),
+ INTERPRETER_TRANSLATE(usubaddx),
+ INTERPRETER_TRANSLATE(usub8),
+ INTERPRETER_TRANSLATE(usub16),
+ INTERPRETER_TRANSLATE(usat16),
+ INTERPRETER_TRANSLATE(usada8),
+ INTERPRETER_TRANSLATE(uqsubaddx),
+ INTERPRETER_TRANSLATE(uqsub8),
+ INTERPRETER_TRANSLATE(uqsub16),
+ INTERPRETER_TRANSLATE(uqaddsubx),
+ INTERPRETER_TRANSLATE(uqadd8),
+ INTERPRETER_TRANSLATE(uqadd16),
+ INTERPRETER_TRANSLATE(sxtab),
+ INTERPRETER_TRANSLATE(uhsubaddx),
+ INTERPRETER_TRANSLATE(uhsub8),
+ INTERPRETER_TRANSLATE(uhsub16),
+ INTERPRETER_TRANSLATE(uhaddsubx),
+ INTERPRETER_TRANSLATE(uhadd8),
+ INTERPRETER_TRANSLATE(uhadd16),
+ INTERPRETER_TRANSLATE(uaddsubx),
+ INTERPRETER_TRANSLATE(uadd8),
+ INTERPRETER_TRANSLATE(uadd16),
+ INTERPRETER_TRANSLATE(sxtah),
+ INTERPRETER_TRANSLATE(sxtab16),
+ INTERPRETER_TRANSLATE(qadd8),
+ INTERPRETER_TRANSLATE(bxj),
+ INTERPRETER_TRANSLATE(clz),
+ INTERPRETER_TRANSLATE(uxtah),
+ INTERPRETER_TRANSLATE(bx),
+ INTERPRETER_TRANSLATE(rev),
+ INTERPRETER_TRANSLATE(blx),
+ INTERPRETER_TRANSLATE(revsh),
+ INTERPRETER_TRANSLATE(qadd),
+ INTERPRETER_TRANSLATE(qadd16),
+ INTERPRETER_TRANSLATE(qaddsubx),
+ INTERPRETER_TRANSLATE(ldrex),
+ INTERPRETER_TRANSLATE(qdadd),
+ INTERPRETER_TRANSLATE(qdsub),
+ INTERPRETER_TRANSLATE(qsub),
+ INTERPRETER_TRANSLATE(ldrexb),
+ INTERPRETER_TRANSLATE(qsub8),
+ INTERPRETER_TRANSLATE(qsub16),
+ INTERPRETER_TRANSLATE(smuad),
+ INTERPRETER_TRANSLATE(smmul),
+ INTERPRETER_TRANSLATE(smusd),
+ INTERPRETER_TRANSLATE(smlsd),
+ INTERPRETER_TRANSLATE(smlsld),
+ INTERPRETER_TRANSLATE(smmla),
+ INTERPRETER_TRANSLATE(smmls),
+ INTERPRETER_TRANSLATE(smlald),
+ INTERPRETER_TRANSLATE(smlad),
+ INTERPRETER_TRANSLATE(smlaw),
+ INTERPRETER_TRANSLATE(smulw),
+ INTERPRETER_TRANSLATE(pkhtb),
+ INTERPRETER_TRANSLATE(pkhbt),
+ INTERPRETER_TRANSLATE(smul),
+ INTERPRETER_TRANSLATE(smlalxy),
+ INTERPRETER_TRANSLATE(smla),
+ INTERPRETER_TRANSLATE(mcrr),
+ INTERPRETER_TRANSLATE(mrrc),
+ INTERPRETER_TRANSLATE(cmp),
+ INTERPRETER_TRANSLATE(tst),
+ INTERPRETER_TRANSLATE(teq),
+ INTERPRETER_TRANSLATE(cmn),
+ INTERPRETER_TRANSLATE(smull),
+ INTERPRETER_TRANSLATE(umull),
+ INTERPRETER_TRANSLATE(umlal),
+ INTERPRETER_TRANSLATE(smlal),
+ INTERPRETER_TRANSLATE(mul),
+ INTERPRETER_TRANSLATE(mla),
+ INTERPRETER_TRANSLATE(ssat),
+ INTERPRETER_TRANSLATE(usat),
+ INTERPRETER_TRANSLATE(mrs),
+ INTERPRETER_TRANSLATE(msr),
+ INTERPRETER_TRANSLATE(and),
+ INTERPRETER_TRANSLATE(bic),
+ INTERPRETER_TRANSLATE(ldm),
+ INTERPRETER_TRANSLATE(eor),
+ INTERPRETER_TRANSLATE(add),
+ INTERPRETER_TRANSLATE(rsb),
+ INTERPRETER_TRANSLATE(rsc),
+ INTERPRETER_TRANSLATE(sbc),
+ INTERPRETER_TRANSLATE(adc),
+ INTERPRETER_TRANSLATE(sub),
+ INTERPRETER_TRANSLATE(orr),
+ INTERPRETER_TRANSLATE(mvn),
+ INTERPRETER_TRANSLATE(mov),
+ INTERPRETER_TRANSLATE(stm),
+ INTERPRETER_TRANSLATE(ldm),
+ INTERPRETER_TRANSLATE(ldrsh),
+ INTERPRETER_TRANSLATE(stm),
+ INTERPRETER_TRANSLATE(ldm),
+ INTERPRETER_TRANSLATE(ldrsb),
+ INTERPRETER_TRANSLATE(strd),
+ INTERPRETER_TRANSLATE(ldrh),
+ INTERPRETER_TRANSLATE(strh),
+ INTERPRETER_TRANSLATE(ldrd),
+ INTERPRETER_TRANSLATE(strt),
+ INTERPRETER_TRANSLATE(strbt),
+ INTERPRETER_TRANSLATE(ldrbt),
+ INTERPRETER_TRANSLATE(ldrt),
+ INTERPRETER_TRANSLATE(mrc),
+ INTERPRETER_TRANSLATE(mcr),
+ INTERPRETER_TRANSLATE(msr),
+ INTERPRETER_TRANSLATE(ldrb),
+ INTERPRETER_TRANSLATE(strb),
+ INTERPRETER_TRANSLATE(ldr),
+ INTERPRETER_TRANSLATE(ldrcond),
+ INTERPRETER_TRANSLATE(str),
+ INTERPRETER_TRANSLATE(cdp),
+ INTERPRETER_TRANSLATE(stc),
+ INTERPRETER_TRANSLATE(ldc),
+ INTERPRETER_TRANSLATE(swi),
+ INTERPRETER_TRANSLATE(bbl),
+ // All the thumb instructions should be placed the end of table
+ INTERPRETER_TRANSLATE(b_2_thumb),
+ INTERPRETER_TRANSLATE(b_cond_thumb),
+ INTERPRETER_TRANSLATE(bl_1_thumb),
+ INTERPRETER_TRANSLATE(bl_2_thumb),
+ INTERPRETER_TRANSLATE(blx_1_thumb)
};
typedef std::unordered_map<u32, int> bb_map;
bb_map CreamCache;
-//#define USE_DUMMY_CACHE
-
-#ifdef USE_DUMMY_CACHE
-unsigned int DummyCache[0x100000];
-#endif
-
-void insert_bb(unsigned int addr, int start)
-{
-#ifdef USE_DUMMY_CACHE
- DummyCache[addr] = start;
-#else
- CreamCache[addr] = start;
-#endif
+void insert_bb(unsigned int addr, int start) {
+ CreamCache[addr] = start;
}
#define TRANS_THRESHOLD 65000
-int find_bb(unsigned int addr, int &start)
-{
- int ret = -1;
-#ifdef USE_DUMMY_CACHE
- start = DummyCache[addr];
- if (start) {
- ret = 0;
- } else
- ret = -1;
-#else
- bb_map::const_iterator it = CreamCache.find(addr);
- if (it != CreamCache.end()) {
- start = static_cast<int>(it->second);
- ret = 0;
-#if HYBRID_MODE
-#if PROFILE
-#else
- /* increase the bb counter */
- if(get_bb_prof(cpu, addr, 1) == TRANS_THRESHOLD){
- push_to_compiled(cpu, addr);
- }
-#endif
-#endif
- } else {
- ret = -1;
- }
-#endif
- return ret;
+int find_bb(unsigned int addr, int &start) {
+ int ret = -1;
+ bb_map::const_iterator it = CreamCache.find(addr);
+ if (it != CreamCache.end()) {
+ start = static_cast<int>(it->second);
+ ret = 0;
+ } else {
+ ret = -1;
+ }
+ return ret;
}
-
enum {
- FETCH_SUCCESS,
- FETCH_FAILURE
+ FETCH_SUCCESS,
+ FETCH_FAILURE
};
+
static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr, uint32_t *arm_inst, uint32_t* inst_size, ARM_INST_PTR* ptr_inst_base){
- /* Check if in Thumb mode. */
- tdstate ret;
- ret = thumb_translate (addr, inst, arm_inst, inst_size);
- if(ret == t_branch){
- /* FIXME, endian should be judged */
- uint32 tinstr;
- if((addr & 0x3) != 0)
- tinstr = inst >> 16;
- else
- tinstr = inst & 0xFFFF;
-
- //tinstr = inst & 0xFFFF;
- int inst_index;
- /* table_length */
- int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
-
- switch((tinstr & 0xF800) >> 11){
- /* we will translate the thumb instruction directly here */
- /* we will translate the thumb instruction directly here */
- case 26:
- case 27:
- if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){
- uint32 cond = (tinstr & 0x0F00) >> 8;
- inst_index = table_length - 4;
- //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d\n", __FUNCTION__, tinstr, inst_index);
- *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
- }
- else{
- /* something wrong */
- LOG_ERROR(Core_ARM11, "thumb decoder error");
- }
- break;
- case 28:
- /* Branch 2, unconditional branch */
- inst_index = table_length - 5;
- //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d\n", __FUNCTION__, tinstr, inst_index);
- *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
- break;
-
- case 8:
- case 29:
- /* For BLX 1 thumb instruction*/
- inst_index = table_length - 1;
- //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d, pc=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc);
- *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
- break;
- case 30:
- /* For BL 1 thumb instruction*/
- inst_index = table_length - 3;
- //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, bl 1 thumb index=%d, pc=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc);
- *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
- break;
- case 31:
- /* For BL 2 thumb instruction*/
- inst_index = table_length - 2;
- //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, bl 2 thumb index=%d, px=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc);
- *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
- break;
- default:
- ret = t_undefined;
- break;
- }
- }
- return ret;
-}
-
-#if 0
-int FetchInst(cpu_t *core, unsigned int &inst)
-{
- //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t");
- arm_processor *cpu = (arm_processor *)(core->cpu_data->obj);
-// fault_t fault = interpreter_read_memory(cpu->translate_pc, inst, 32);
- fault_t fault = interpreter_fetch(core, cpu->translate_pc, inst, 32);
- if (!core->is_user_mode) {
- if (fault) {
- cpu->abortSig = true;
- cpu->Aborted = ARMul_PrefetchAbortV;
- cpu->AbortAddr = cpu->translate_pc;
- cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
- cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->translate_pc;
- return FETCH_FAILURE;
- }
- }
- return FETCH_SUCCESS;
+ // Check if in Thumb mode
+ tdstate ret = thumb_translate (addr, inst, arm_inst, inst_size);
+ if(ret == t_branch){
+ // TODO: FIXME, endian should be judged
+ uint32 tinstr;
+ if((addr & 0x3) != 0)
+ tinstr = inst >> 16;
+ else
+ tinstr = inst & 0xFFFF;
+
+ int inst_index;
+ int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
+
+ switch((tinstr & 0xF800) >> 11){
+ case 26:
+ case 27:
+ if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){
+ uint32 cond = (tinstr & 0x0F00) >> 8;
+ inst_index = table_length - 4;
+ *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
+ } else {
+ LOG_ERROR(Core_ARM11, "thumb decoder error");
+ }
+ break;
+ case 28:
+ // Branch 2, unconditional branch
+ inst_index = table_length - 5;
+ *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
+ break;
+
+ case 8:
+ case 29:
+ // For BLX 1 thumb instruction
+ inst_index = table_length - 1;
+ *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
+ break;
+ case 30:
+ // For BL 1 thumb instruction
+ inst_index = table_length - 3;
+ *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
+ break;
+ case 31:
+ // For BL 2 thumb instruction
+ inst_index = table_length - 2;
+ *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
+ break;
+ default:
+ ret = t_undefined;
+ break;
+ }
+ }
+ return ret;
}
-#endif
unsigned int *InstLength;
enum {
- KEEP_GOING,
- FETCH_EXCEPTION
+ KEEP_GOING,
+ FETCH_EXCEPTION
};
typedef struct instruction_set_encoding_item ISEITEM;
@@ -3736,274 +3456,148 @@ extern const ISEITEM arm_instruction[];
vector<uint64_t> code_page_set;
-void flush_bb(uint32_t addr)
-{
- bb_map::iterator it;
- uint32_t start;
-
- addr &= 0xfffff000;
- for (it = CreamCache.begin(); it != CreamCache.end(); ) {
- start = static_cast<uint32_t>(it->first);
- //start = (start >> 12) << 12;
- start &= 0xfffff000;
- if (start == addr) {
- //DEBUG_LOG(ARM11, "[ERASE][0x%08x]\n", static_cast<int>(it->first));
- CreamCache.erase(it++);
- } else
- ++it;
- }
-
- //DEBUG_LOG(ARM11, "flush bb @ %x\n", addr);
-}
-
-//static uint32_t get_bank_addr(void *addr)
-//{
-// uint64_t address = (uint64_t)addr;
-// uint64_t bank0 = get_dma_addr(BANK0_START);
-// if ((address >= bank0) && (address < (bank0 + BANK0_SIZE))) {
-// //DEBUG_LOG(ARM11, "1.addr is %llx\n", addr);
-// return ((uint64_t)addr - bank0) + BANK0_START;
-// }
-// return 0;
-//}
-
-/* shenoubang add win32 2012-6-12 */
-//#ifndef __WIN32__
-//static void flush_code_cache(int signal_number, siginfo_t *si, void *unused)
-//{
-// DEBUG_LOG(ARM11, "in %s, addr=0x%llx\n", __FUNCTION__, si->si_addr);
-// uint64_t addr = (uint64_t)si->si_addr;
-// addr = (addr >> 12) << 12;
-// skyeye_backtrace();
-// #if 0
-// if (addr == 0) {
-// return;
-// }
-// const vector<uint64_t>::iterator it = find(code_page_set.begin(),
-// code_page_set.end(),
-// (uint64_t)addr);
-// if (it != code_page_set.end()) {
-// code_page_set.erase(it);
-// }
-// mprotect((void *)addr, 4096, PROT_READ | PROT_WRITE);
-// //DEBUG_LOG(ARM11, "[flush][ADDR:0x%08llx]\n", addr);
-// uint32_t phys_addr = get_bank_addr((void *)addr);
-//// DEBUG_LOG(ARM11, "[PHYSICAL][ADDR:0x%08llx]\n", phys_addr);
-// flush_bb(phys_addr);
-// flush_bb(phys_addr + 4096);
-//#if HYBRID_MODE
-// /* flush the translated BB of dyncom */
-// clear_translated_cache(phys_addr);
-//#endif
-// #endif
-//}
-//#endif /* shenoubang */
-
-//void protect_code_page(uint32_t addr)
-//{
-// void *mem_ptr = (void *)get_dma_addr(addr);
-// mem_ptr = (void *)((long long int)mem_ptr & 0xfffffffffffff000LL);
-//
-// const vector<uint64_t>::iterator it = find(code_page_set.begin(),
-// code_page_set.end(),
-// (uint64_t)mem_ptr);
-// if (it != code_page_set.end()) {
-// return;
-// }
-// //DEBUG_LOG(ARM11, "[mprotect][ADDR:0x%08llx]\n", mem_ptr);
-// /* shenoubang add win32 2012-6-12 */
-//#ifndef __WIN32__
-// struct sigaction sa;
-//
-// memset(&sa, 0, sizeof(sa));
-// sa.sa_flags = SA_RESTART | SA_SIGINFO;
-// sa.sa_sigaction = &flush_code_cache;
-// sigaction(SIGSEGV, &sa, NULL);
-//
-// //mprotect(mem_ptr, 4096, PROT_READ);
-//
-// code_page_set.push_back((uint64_t)mem_ptr);
-//#endif /* shenoubang */
-//}
-
-
-
-int InterpreterTranslate(arm_processor *cpu, int &bb_start, addr_t addr)
-{
- /* Decode instruction, get index */
- /* Allocate memory and init InsCream */
- /* Go on next, until terminal instruction */
- /* Save start addr of basicblock in CreamCache */
- //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t");
- //arm_processor *cpu = (arm_processor *)(core->cpu_data->obj);
- ARM_INST_PTR inst_base = NULL;
- unsigned int inst, inst_size = 4;
- int idx;
- int ret = NON_BRANCH;
- int thumb = 0;
- /* instruction size of basic block */
- int size = 0;
- /* (R15 - 8) ? */
- //cpu->translate_pc = cpu->Reg[15];
- bb_start = top;
-
- if (cpu->TFlag)
- thumb = THUMB;
-
- addr_t phys_addr;
- addr_t pc_start;
- fault_t fault = NO_FAULT;
- //fault = check_address_validity(cpu, addr, &phys_addr, 1, INSN_TLB);
- fault = check_address_validity(cpu, addr, &phys_addr, 1);
- if(fault != NO_FAULT){
- cpu->abortSig = true;
- cpu->Aborted = ARMul_PrefetchAbortV;
- cpu->AbortAddr = addr;
- cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
- cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr;
- return FETCH_EXCEPTION;
- }
- pc_start = phys_addr;
- //phys_addr = get_dma_addr(phys_addr);
- while(ret == NON_BRANCH) {
- /* shenoubang add win32 2012-6-14 */
-#ifdef __WIN32__
- mem_bank_t* bank;
- if (bank = bank_ptr(addr)) {
- bank->bank_read(32, phys_addr, &inst);
- }
- else {
- LOG_ERROR(Core_ARM11, "SKYEYE: Read physical addr 0x%x error!!\n", phys_addr);
- return FETCH_FAILURE;
- }
-#else
- inst = Memory::Read32(phys_addr & 0xFFFFFFFC);//*(uint32_t *)(phys_addr & 0xFFFFFFFC);
-#endif
- //or_tag(core, phys_addr, TAG_FAST_INTERP);
-
- /*if (ret == FETCH_FAILURE) {
- return FETCH_EXCEPTION;
- }*/
-
- size ++;
- /* If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction */
- if (cpu->TFlag){
- //if(cpu->Cpsr & (1 << THUMB_BIT)){
- uint32_t arm_inst;
- tdstate state;
- state = decode_thumb_instr(cpu, inst, phys_addr, &arm_inst, &inst_size, &inst_base);
- //or_tag(core, phys_addr, TAG_THUMB);
- //DEBUG_LOG(ARM11, "In thumb state, arm_inst=0x%x, inst_size=0x%x, pc=0x%x\n", arm_inst, inst_size, cpu->translate_pc);
- /* we have translated the branch instruction of thumb in thumb decoder */
- if(state == t_branch){
- goto translated;
- }
- inst = arm_inst;
- }
-
- ret = decode_arm_instr(inst, &idx);
- if (ret == DECODE_FAILURE) {
- LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : [%x]", phys_addr, inst);
- LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]);
- CITRA_IGNORE_EXIT(-1);
- }
-// DEBUG_LOG(ARM11, "PC : [0x%x] INST : %s\n", cpu->translate_pc, arm_instruction[idx].name);
- inst_base = arm_instruction_trans[idx](inst, idx);
-// DEBUG_LOG(ARM11, "translated @ %x INST : %x\n", cpu->translate_pc, inst);
-// DEBUG_LOG(ARM11, "inst size is %d\n", InstLength[idx]);
-translated:
- phys_addr += inst_size;
+void flush_bb(uint32_t addr) {
+ bb_map::iterator it;
+ uint32_t start;
+
+ addr &= 0xfffff000;
+ for (it = CreamCache.begin(); it != CreamCache.end(); ) {
+ start = static_cast<uint32_t>(it->first);
+ start &= 0xfffff000;
+ if (start == addr) {
+ CreamCache.erase(it++);
+ } else
+ ++it;
+ }
+}
- if ((phys_addr & 0xfff) == 0) {
- inst_base->br = END_OF_PAGE;
- }
- ret = inst_base->br;
- };
+int InterpreterTranslate(arm_processor *cpu, int &bb_start, addr_t addr) {
+ // Decode instruction, get index
+ // Allocate memory and init InsCream
+ // Go on next, until terminal instruction
+ // Save start addr of basicblock in CreamCache
+ ARM_INST_PTR inst_base = nullptr;
+ unsigned int inst, inst_size = 4;
+ int idx;
+ int ret = NON_BRANCH;
+ int thumb = 0;
+ int size = 0; // instruction size of basic block
+ bb_start = top;
+
+ if (cpu->TFlag)
+ thumb = THUMB;
+
+ addr_t phys_addr;
+ addr_t pc_start;
+ fault_t fault = NO_FAULT;
+ fault = check_address_validity(cpu, addr, &phys_addr, 1);
+ if(fault != NO_FAULT){
+ cpu->abortSig = true;
+ cpu->Aborted = ARMul_PrefetchAbortV;
+ cpu->AbortAddr = addr;
+ cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
+ cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr;
+ return FETCH_EXCEPTION;
+ }
- //DEBUG_LOG(ARM11, "In %s,insert_bb pc=0x%x, TFlag=0x%x\n", __FUNCTION__, pc_start, cpu->TFlag);
- insert_bb(pc_start, bb_start);
- return KEEP_GOING;
-}
+ pc_start = phys_addr;
-#define LOG_IN_CLR skyeye_printf_in_color
+ while(ret == NON_BRANCH) {
+ inst = Memory::Read32(phys_addr & 0xFFFFFFFC);//*(uint32_t *)(phys_addr & 0xFFFFFFFC);
-int cmp(const void *x, const void *y)
-{
- return *(unsigned long long int*)x - *(unsigned long long int *)y;
+ size ++;
+ // If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction
+ if (cpu->TFlag) {
+ uint32_t arm_inst;
+ tdstate state;
+ state = decode_thumb_instr(cpu, inst, phys_addr, &arm_inst, &inst_size, &inst_base);
+ // We have translated the branch instruction of thumb in thumb decoder
+ if(state == t_branch){
+ goto translated;
+ }
+ inst = arm_inst;
+ }
+
+ ret = decode_arm_instr(inst, &idx);
+ if (ret == DECODE_FAILURE) {
+ LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : [%x]", phys_addr, inst);
+ LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]);
+ CITRA_IGNORE_EXIT(-1);
+ }
+ inst_base = arm_instruction_trans[idx](inst, idx);
+translated:
+ phys_addr += inst_size;
+
+ if ((phys_addr & 0xfff) == 0) {
+ inst_base->br = END_OF_PAGE;
+ }
+ ret = inst_base->br;
+ };
+ insert_bb(pc_start, bb_start);
+ return KEEP_GOING;
+}
+
+#define LOG_IN_CLR skyeye_printf_in_color
+
+int cmp(const void *x, const void *y) {
+ return *(unsigned long long int*)x - *(unsigned long long int *)y;
+}
+
+void InterpreterInitInstLength(unsigned long long int *ptr, size_t size) {
+ int array_size = size / sizeof(void *);
+ unsigned long long int *InstLabel = new unsigned long long int[array_size];
+ memcpy(InstLabel, ptr, size);
+ qsort(InstLabel, array_size, sizeof(void *), cmp);
+ InstLength = new unsigned int[array_size - 4];
+ for (int i = 0; i < array_size - 4; i ++) {
+ for (int j = 0; j < array_size; j ++) {
+ if (ptr[i] == InstLabel[j]) {
+ InstLength[i] = InstLabel[j + 1] - InstLabel[j];
+ break;
+ }
+ }
+ }
+ for (int i = 0; i < array_size - 4; i ++)
+ LOG_DEBUG(Core_ARM11, "[%d]:%d", i, InstLength[i]);
}
-void InterpreterInitInstLength(unsigned long long int *ptr, size_t size)
-{
- int array_size = size / sizeof(void *);
- unsigned long long int *InstLabel = new unsigned long long int[array_size];
- memcpy(InstLabel, ptr, size);
- qsort(InstLabel, array_size, sizeof(void *), cmp);
- InstLength = new unsigned int[array_size - 4];
- for (int i = 0; i < array_size - 4; i ++) {
- for (int j = 0; j < array_size; j ++) {
- if (ptr[i] == InstLabel[j]) {
- InstLength[i] = InstLabel[j + 1] - InstLabel[j];
- break;
- }
- }
- }
- for (int i = 0; i < array_size - 4; i ++)
- LOG_DEBUG(Core_ARM11, "[%d]:%d", i, InstLength[i]);
-}
-
-int clz(unsigned int x)
-{
- int n;
- if (x == 0) return (32);
- n = 1;
- if ((x >> 16) == 0) { n = n + 16; x = x << 16;}
- if ((x >> 24) == 0) { n = n + 8; x = x << 8;}
- if ((x >> 28) == 0) { n = n + 4; x = x << 4;}
- if ((x >> 30) == 0) { n = n + 2; x = x << 2;}
- n = n - (x >> 31);
- return n;
+int clz(unsigned int x) {
+ int n;
+ if (x == 0) return (32);
+ n = 1;
+ if ((x >> 16) == 0) { n = n + 16; x = x << 16;}
+ if ((x >> 24) == 0) { n = n + 8; x = x << 8;}
+ if ((x >> 28) == 0) { n = n + 4; x = x << 4;}
+ if ((x >> 30) == 0) { n = n + 2; x = x << 2;}
+ n = n - (x >> 31);
+ return n;
}
unsigned arm_dyncom_SWI (ARMul_State * state, ARMword number);
-static bool InAPrivilegedMode(arm_core_t *core)
-{
- return (core->Mode != USER32MODE);
+static bool InAPrivilegedMode(arm_core_t *core) {
+ return (core->Mode != USER32MODE);
}
-/* r15 = r15 + 8 */
-unsigned InterpreterMainLoop(ARMul_State* state)
-{
- #define CRn inst_cream->crn
- #define OPCODE_2 inst_cream->opcode_2
- #define CRm inst_cream->crm
- #define CP15_REG(n) cpu->CP15[CP15(n)]
- #define RD cpu->Reg[inst_cream->Rd]
- #define RN cpu->Reg[inst_cream->Rn]
- #define RM cpu->Reg[inst_cream->Rm]
- #define RS cpu->Reg[inst_cream->Rs]
- #define RDHI cpu->Reg[inst_cream->RdHi]
- #define RDLO cpu->Reg[inst_cream->RdLo]
- #define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4)
- #define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24)
- #define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand)
-
- #if ENABLE_ICOUNTER
- #define INC_ICOUNTER cpu->icounter++; \
- if(cpu->Reg[15] > 0xc0000000) \
- cpu->kernel_icounter++;
- /*if (debug_function(core)) \
- if (core->check_int_flag) \
- goto END*/
- //LOG_TRACE(Core_ARM11, "icounter is %llx pc is %x\n", cpu->icounter, cpu->Reg[15])
- #else
- #define INC_ICOUNTER ;
- #endif
-
- #define FETCH_INST if (inst_base->br != NON_BRANCH) \
- goto DISPATCH; \
- inst_base = (arm_inst *)&inst_buf[ptr]
-#define INC_PC(l) ptr += sizeof(arm_inst) + l
+unsigned InterpreterMainLoop(ARMul_State* state) {
+ #define CRn inst_cream->crn
+ #define OPCODE_2 inst_cream->opcode_2
+ #define CRm inst_cream->crm
+ #define CP15_REG(n) cpu->CP15[CP15(n)]
+ #define RD cpu->Reg[inst_cream->Rd]
+ #define RN cpu->Reg[inst_cream->Rn]
+ #define RM cpu->Reg[inst_cream->Rm]
+ #define RS cpu->Reg[inst_cream->Rs]
+ #define RDHI cpu->Reg[inst_cream->RdHi]
+ #define RDLO cpu->Reg[inst_cream->RdLo]
+ #define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4)
+ #define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24)
+ #define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand)
+
+ #define FETCH_INST if (inst_base->br != NON_BRANCH) goto DISPATCH; \
+ inst_base = (arm_inst *)&inst_buf[ptr]
+
+ #define INC_PC(l) ptr += sizeof(arm_inst) + l
// GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a
// clunky switch statement.
@@ -4213,3014 +3807,2522 @@ unsigned InterpreterMainLoop(ARMul_State* state)
}
#endif
- #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0)
- #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1)
-/* #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((ISNEG(lop) && ISPOS(rop)) || \
- (ISNEG(lop) && ISPOS(dst)) || \
- (ISPOS(rop) && ISPOS(dst)))) */
- #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((dst < lop) || (dst < rop)))
- #define UPDATE_CFLAG_CARRY_FROM_ADD(lop, rop, flag) (cpu->CFlag = (((uint64_t) lop + (uint64_t) rop + (uint64_t) flag) > 0xffffffff) )
- #define UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(lop, rop, flag) (cpu->CFlag = ((uint64_t) lop >= ((uint64_t) rop + (uint64_t) flag)))
- #define UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop) (cpu->CFlag = (lop >= rop))
- #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) (cpu->CFlag = !(dst < lop))
- #define UPDATE_CFLAG_WITH_SC cpu->CFlag = cpu->shifter_carry_out
-/* #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || \
- (ISNEG(lop) && ISPOS(dst)) || \
- (ISPOS(rop) && ISPOS(dst))) */
- #define UPDATE_VFLAG(dst, lop, rop) (cpu->VFlag = (((lop < 0) && (rop < 0) && (dst >= 0)) || \
- ((lop >= 0) && (rop) >= 0 && (dst < 0))))
- #define UPDATE_VFLAG_WITH_NOT(dst, lop, rop) (cpu->VFlag = !(((lop < 0) && (rop < 0) && (dst >= 0)) || \
- ((lop >= 0) && (rop) >= 0 && (dst < 0))))
- #define UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop) (cpu->VFlag = (((lop ^ rop) & (lop ^ dst)) >> 31))
-
- #define SAVE_NZCVT cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \
- (cpu->NFlag << 31) | \
- (cpu->ZFlag << 30) | \
- (cpu->CFlag << 29) | \
- (cpu->VFlag << 28) | \
- (cpu->TFlag << 5)
- #define LOAD_NZCVT cpu->NFlag = (cpu->Cpsr >> 31); \
- cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \
- cpu->CFlag = (cpu->Cpsr >> 29) & 1; \
- cpu->VFlag = (cpu->Cpsr >> 28) & 1; \
- cpu->TFlag = (cpu->Cpsr >> 5) & 1;
-
- #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE)
- #define PC (cpu->Reg[15])
- #define CHECK_EXT_INT if (!cpu->NirqSig) { \
- if (!(cpu->Cpsr & 0x80)) { \
- goto END; \
- } \
- }
-
-
-
- //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t");
- arm_processor *cpu = state; //(arm_processor *)(core->cpu_data->obj);
+ #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0)
+ #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1)
+
+ #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((dst < lop) || (dst < rop)))
+ #define UPDATE_CFLAG_CARRY_FROM_ADD(lop, rop, flag) (cpu->CFlag = (((uint64_t) lop + (uint64_t) rop + (uint64_t) flag) > 0xffffffff) )
+ #define UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(lop, rop, flag) (cpu->CFlag = ((uint64_t) lop >= ((uint64_t) rop + (uint64_t) flag)))
+ #define UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop) (cpu->CFlag = (lop >= rop))
+ #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) (cpu->CFlag = !(dst < lop))
+ #define UPDATE_CFLAG_WITH_SC (cpu->CFlag = cpu->shifter_carry_out)
+
+ #define UPDATE_VFLAG(dst, lop, rop) (cpu->VFlag = (((lop < 0) && (rop < 0) && (dst >= 0)) || \
+ ((lop >= 0) && (rop) >= 0 && (dst < 0))))
+ #define UPDATE_VFLAG_WITH_NOT(dst, lop, rop) (cpu->VFlag = !(((lop < 0) && (rop < 0) && (dst >= 0)) || \
+ ((lop >= 0) && (rop) >= 0 && (dst < 0))))
+ #define UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop) (cpu->VFlag = (((lop ^ rop) & (lop ^ dst)) >> 31))
+
+ #define SAVE_NZCVT cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \
+ (cpu->NFlag << 31) | \
+ (cpu->ZFlag << 30) | \
+ (cpu->CFlag << 29) | \
+ (cpu->VFlag << 28) | \
+ (cpu->TFlag << 5)
+ #define LOAD_NZCVT cpu->NFlag = (cpu->Cpsr >> 31); \
+ cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \
+ cpu->CFlag = (cpu->Cpsr >> 29) & 1; \
+ cpu->VFlag = (cpu->Cpsr >> 28) & 1; \
+ cpu->TFlag = (cpu->Cpsr >> 5) & 1;
+
+ #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE)
+ #define PC (cpu->Reg[15])
+ #define CHECK_EXT_INT if (!cpu->NirqSig && !(cpu->Cpsr & 0x80)) goto END;
+
+ arm_processor *cpu = state;
// GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback
// to a clunky switch statement.
#if defined __GNUC__ || defined __clang__
- void *InstLabel[] = {
- &&VMLA_INST, &&VMLS_INST, &&VNMLA_INST, &&VNMLA_INST, &&VNMLS_INST, &&VNMUL_INST, &&VMUL_INST, &&VADD_INST, &&VSUB_INST,
- &&VDIV_INST, &&VMOVI_INST, &&VMOVR_INST, &&VABS_INST, &&VNEG_INST, &&VSQRT_INST, &&VCMP_INST, &&VCMP2_INST, &&VCVTBDS_INST,
- &&VCVTBFF_INST, &&VCVTBFI_INST, &&VMOVBRS_INST, &&VMSR_INST, &&VMOVBRC_INST, &&VMRS_INST, &&VMOVBCR_INST, &&VMOVBRRSS_INST,
- &&VMOVBRRD_INST, &&VSTR_INST, &&VPUSH_INST, &&VSTM_INST, &&VPOP_INST, &&VLDR_INST, &&VLDM_INST,
-
- &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST,
- &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST,
- &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST,
- &&SHADD8_INST,&&SHADD16_INST,&&SEL_INST,&&SADDSUBX_INST,&&SADD8_INST,&&SADD16_INST,&&SHSUB16_INST,&&UMAAL_INST,&&UXTAB16_INST,
- &&USUBADDX_INST,&&USUB8_INST,&&USUB16_INST,&&USAT16_INST,&&USADA8_INST,&&UQSUBADDX_INST,&&UQSUB8_INST,&&UQSUB16_INST,
- &&UQADDSUBX_INST,&&UQADD8_INST,&&UQADD16_INST,&&SXTAB_INST,&&UHSUBADDX_INST,&&UHSUB8_INST,&&UHSUB16_INST,&&UHADDSUBX_INST,&&UHADD8_INST,
- &&UHADD16_INST,&&UADDSUBX_INST,&&UADD8_INST,&&UADD16_INST,&&SXTAH_INST,&&SXTAB16_INST,&&QADD8_INST,&&BXJ_INST,&&CLZ_INST,&&UXTAH_INST,
- &&BX_INST,&&REV_INST,&&BLX_INST,&&REVSH_INST,&&QADD_INST,&&QADD16_INST,&&QADDSUBX_INST,&&LDREX_INST,&&QDADD_INST,&&QDSUB_INST,
- &&QSUB_INST,&&LDREXB_INST,&&QSUB8_INST,&&QSUB16_INST,&&SMUAD_INST,&&SMMUL_INST,&&SMUSD_INST,&&SMLSD_INST,&&SMLSLD_INST,&&SMMLA_INST,
- &&SMMLS_INST,&&SMLALD_INST,&&SMLAD_INST,&&SMLAW_INST,&&SMULW_INST,&&PKHTB_INST,&&PKHBT_INST,&&SMUL_INST,&&SMLALXY_INST,&&SMLA_INST,
- &&MCRR_INST,&&MRRC_INST,&&CMP_INST,&&TST_INST,&&TEQ_INST,&&CMN_INST,&&SMULL_INST,&&UMULL_INST,&&UMLAL_INST,&&SMLAL_INST,&&MUL_INST,
- &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST,
- &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST,
- &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST,
- &&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST,&&SWI_INST,&&BBL_INST,&&B_2_THUMB, &&B_COND_THUMB,
- &&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,&&INIT_INST_LENGTH,&&END
- };
+ void *InstLabel[] = {
+ &&VMLA_INST, &&VMLS_INST, &&VNMLA_INST, &&VNMLA_INST, &&VNMLS_INST, &&VNMUL_INST, &&VMUL_INST, &&VADD_INST, &&VSUB_INST,
+ &&VDIV_INST, &&VMOVI_INST, &&VMOVR_INST, &&VABS_INST, &&VNEG_INST, &&VSQRT_INST, &&VCMP_INST, &&VCMP2_INST, &&VCVTBDS_INST,
+ &&VCVTBFF_INST, &&VCVTBFI_INST, &&VMOVBRS_INST, &&VMSR_INST, &&VMOVBRC_INST, &&VMRS_INST, &&VMOVBCR_INST, &&VMOVBRRSS_INST,
+ &&VMOVBRRD_INST, &&VSTR_INST, &&VPUSH_INST, &&VSTM_INST, &&VPOP_INST, &&VLDR_INST, &&VLDM_INST,
+
+ &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST,
+ &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST,
+ &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST,
+ &&SHADD8_INST,&&SHADD16_INST,&&SEL_INST,&&SADDSUBX_INST,&&SADD8_INST,&&SADD16_INST,&&SHSUB16_INST,&&UMAAL_INST,&&UXTAB16_INST,
+ &&USUBADDX_INST,&&USUB8_INST,&&USUB16_INST,&&USAT16_INST,&&USADA8_INST,&&UQSUBADDX_INST,&&UQSUB8_INST,&&UQSUB16_INST,
+ &&UQADDSUBX_INST,&&UQADD8_INST,&&UQADD16_INST,&&SXTAB_INST,&&UHSUBADDX_INST,&&UHSUB8_INST,&&UHSUB16_INST,&&UHADDSUBX_INST,&&UHADD8_INST,
+ &&UHADD16_INST,&&UADDSUBX_INST,&&UADD8_INST,&&UADD16_INST,&&SXTAH_INST,&&SXTAB16_INST,&&QADD8_INST,&&BXJ_INST,&&CLZ_INST,&&UXTAH_INST,
+ &&BX_INST,&&REV_INST,&&BLX_INST,&&REVSH_INST,&&QADD_INST,&&QADD16_INST,&&QADDSUBX_INST,&&LDREX_INST,&&QDADD_INST,&&QDSUB_INST,
+ &&QSUB_INST,&&LDREXB_INST,&&QSUB8_INST,&&QSUB16_INST,&&SMUAD_INST,&&SMMUL_INST,&&SMUSD_INST,&&SMLSD_INST,&&SMLSLD_INST,&&SMMLA_INST,
+ &&SMMLS_INST,&&SMLALD_INST,&&SMLAD_INST,&&SMLAW_INST,&&SMULW_INST,&&PKHTB_INST,&&PKHBT_INST,&&SMUL_INST,&&SMLALXY_INST,&&SMLA_INST,
+ &&MCRR_INST,&&MRRC_INST,&&CMP_INST,&&TST_INST,&&TEQ_INST,&&CMN_INST,&&SMULL_INST,&&UMULL_INST,&&UMLAL_INST,&&SMLAL_INST,&&MUL_INST,
+ &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST,
+ &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST,
+ &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST,
+ &&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST,&&SWI_INST,&&BBL_INST,&&B_2_THUMB, &&B_COND_THUMB,
+ &&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,&&INIT_INST_LENGTH,&&END
+ };
#endif
- arm_inst * inst_base;
- unsigned int lop, rop, dst;
- unsigned int addr;
- unsigned int phys_addr;
- unsigned int last_pc = 0;
- unsigned int num_instrs = 0;
- fault_t fault;
- static unsigned int last_physical_base = 0, last_logical_base = 0;
- int ptr;
- bool single_step = (cpu->NumInstrsToExecute == 1);
-
- LOAD_NZCVT;
- DISPATCH:
- {
- if (!cpu->NirqSig) {
- if (!(cpu->Cpsr & 0x80)) {
- goto END;
- }
- }
-
- if (cpu->TFlag) {
- cpu->Reg[15] &= 0xfffffffe;
- } else
- cpu->Reg[15] &= 0xfffffffc;
-#if PROFILE
- /* check next instruction address is valid. */
- last_pc = cpu->Reg[15];
-#endif
-#if USER_MODE_OPT
- phys_addr = cpu->Reg[15];
-#else
- {
- if (last_logical_base == (cpu->Reg[15] & 0xfffff000))
- phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff);
- else {
- /* check next instruction address is valid. */
- fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB);
- if (fault) {
- cpu->abortSig = true;
- cpu->Aborted = ARMul_PrefetchAbortV;
- cpu->AbortAddr = cpu->Reg[15];
- cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
- cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15];
- goto END;
- }
- last_logical_base = cpu->Reg[15] & 0xfffff000;
- last_physical_base = phys_addr & 0xfffff000;
- }
- }
-#if HYBRID_MODE
- /* check if the native code of dyncom is available */
- //fast_map hash_map = core->dyncom_engine->fmap;
- //void * pfunc = NULL;
- //PFUNC(phys_addr);
- //if(pfunc){
- if(is_translated_entry(core, phys_addr)){
- int rc = JIT_RETURN_NOERR;
- //DEBUG_LOG(ARM11, "enter jit icounter is %lld, pc=0x%x\n", core->icounter, cpu->Reg[15]);
- SAVE_NZCVT;
-// resume_timing();
- rc = cpu_run(core);
- LOAD_NZCVT;
- //DEBUG_LOG(ARM11, "out of jit ret is %d icounter is %lld, pc=0x%x\n", rc, core->icounter, cpu->Reg[15]);
- if((rc == JIT_RETURN_FUNCNOTFOUND) || (rc == JIT_RETURN_FUNC_BLANK)){
- /* keep the tflag same with the bit in CPSR */
- //cpu->TFlag = cpu->Cpsr & (1 << THUMB_BIT);
- //cpu->TFlag = cpu->Cpsr & (1 << 5);
- //switch_mode(cpu, cpu->Cpsr & 0x1f);
- //DEBUG_LOG(ARM11, "FUNCTION not found , pc=0x%x\n", cpu->Reg[15]);
- fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB);
- if (fault) {
- cpu->abortSig = true;
- cpu->Aborted = ARMul_PrefetchAbortV;
- cpu->AbortAddr = cpu->Reg[15];
- cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
- cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15];
- goto END;
- }
- last_logical_base = cpu->Reg[15] & 0xfffff000;
- last_physical_base = phys_addr & 0xfffff000;
- core->current_page_phys = last_physical_base;
- core->current_page_effec = last_logical_base;
- //push_to_compiled(core, phys_addr);
- }
- else{
- if((cpu->CP15[CP15(CP15_TLB_FAULT_STATUS)] & 0xf0)){
- //DEBUG_LOG(ARM11, "\n\n###############In %s, fsr=0x%x, fault_addr=0x%x, pc=0x%x\n\n", __FUNCTION__, cpu->CP15[CP15(CP15_FAULT_STATUS)], cpu->CP15[CP15(CP15_FAULT_ADDRESS)], cpu->Reg[15]);
- //core->Reg[15] -= get_instr_size(cpu_dyncom);
- fill_tlb(cpu);
- goto END;
- }
- if (cpu->syscallSig) {
- goto END;
- }
- if (cpu->abortSig) {
- cpu->CP15[CP15_TLB_FAULT_STATUS - CP15_BASE] &= 0xFFFFFFF0;
- goto END;
- }
- if (!cpu->NirqSig) {
- if (!(cpu->Cpsr & 0x80)) {
- goto END;
- }
- }
-
- /* if regular trap */
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- /*uint32_t mode = cpu->Cpsr & 0x1f;
- if ((mode != cpu->Mode) && (!is_user_mode(core))) {
- switch_mode(cpu, mode);
- return 1;
- }*/
-
- goto END;
- }
- //phys_addr = cpu->Reg[15];
- }
- else{
- if (last_logical_base == (cpu->Reg[15] & 0xfffff000))
- phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff);
- else {
- /* check next instruction address is valid. */
- fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB);
- if (fault) {
- cpu->abortSig = true;
- cpu->Aborted = ARMul_PrefetchAbortV;
- cpu->AbortAddr = cpu->Reg[15];
- cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
- cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15];
- goto END;
- }
- last_logical_base = cpu->Reg[15] & 0xfffff000;
- last_physical_base = phys_addr & 0xfffff000;
- }
- }
-#endif /* #if HYBRID_MODE */
-#endif /* #if USER_MODE_OPT */
- if (true){//if(is_fast_interp_code(core, phys_addr)){
- if (find_bb(phys_addr, ptr) == -1)
- if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
- goto END;
- }
- else{
+ arm_inst * inst_base;
+ unsigned int lop, rop, dst;
+ unsigned int addr;
+ unsigned int phys_addr;
+ unsigned int last_pc = 0;
+ unsigned int num_instrs = 0;
+ fault_t fault;
+ static unsigned int last_physical_base = 0, last_logical_base = 0;
+ int ptr;
+ bool single_step = (cpu->NumInstrsToExecute == 1);
+
+ LOAD_NZCVT;
+ DISPATCH:
+ {
+ if (!cpu->NirqSig) {
+ if (!(cpu->Cpsr & 0x80)) {
+ goto END;
+ }
+ }
+
+ if (cpu->TFlag)
+ cpu->Reg[15] &= 0xfffffffe;
+ else
+ cpu->Reg[15] &= 0xfffffffc;
+
+ phys_addr = cpu->Reg[15];
+
+ if (find_bb(phys_addr, ptr) == -1)
if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
- goto END;
- }
-#if PROFILE
- resume_timing();
-#endif
- inst_base = (arm_inst *)&inst_buf[ptr];
- GOTO_NEXT_INST;
- }
- ADC_INST:
- {
- INC_ICOUNTER;
- adc_inst *inst_cream = (adc_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- lop = RN;
- unsigned int sht_op = SHIFTER_OPERAND;
- rop = SHIFTER_OPERAND + cpu->CFlag;
- RD = dst = lop + rop;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- /* cpsr = spsr */
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
- UPDATE_CFLAG_CARRY_FROM_ADD(lop, sht_op, cpu->CFlag);
- UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(adc_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(adc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- ADD_INST:
- {
- INC_ICOUNTER;
- add_inst *inst_cream = (add_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- lop = RN;
- if (inst_cream->Rn == 15) {
- lop += 2 * GET_INST_SIZE(cpu);
- }
- rop = SHIFTER_OPERAND;
- RD = dst = lop + rop;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- /* cpsr = spsr*/
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Cpsr & 0x1f);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
- UPDATE_CFLAG(dst, lop, rop);
- UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(add_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(add_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- AND_INST:
- {
- INC_ICOUNTER;
- and_inst *inst_cream = (and_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- lop = RN;
- rop = SHIFTER_OPERAND;
- RD = dst = lop & rop;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- /* cpsr = spsr*/
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Cpsr & 0x1f);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
- UPDATE_CFLAG_WITH_SC;
- //UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(and_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(and_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- BBL_INST:
- {
- INC_ICOUNTER;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
- if (inst_cream->L) {
- LINK_RTN_ADDR;
- }
- SET_PC;
- INC_PC(sizeof(bbl_inst));
- goto DISPATCH;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(bbl_inst));
- goto DISPATCH;
- }
- BIC_INST:
- {
- INC_ICOUNTER;
- bic_inst *inst_cream = (bic_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- lop = RN;
- if (inst_cream->Rn == 15) {
- lop += 2 * GET_INST_SIZE(cpu);
- }
- rop = SHIFTER_OPERAND;
-// RD = dst = lop & (rop ^ 0xffffffff);
- RD = dst = lop & (~rop);
- if ((inst_cream->S) && (inst_cream->Rd == 15)) {
- /* cpsr = spsr */
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(bic_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(bic_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- BKPT_INST:
- BLX_INST:
- {
- INC_ICOUNTER;
- blx_inst *inst_cream = (blx_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- unsigned int inst = inst_cream->inst;
- if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
- //LINK_RTN_ADDR;
- cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
- if(cpu->TFlag)
- cpu->Reg[14] |= 0x1;
- cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe;
- cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1;
- //cpu->Reg[15] = cpu->Reg[BITS(inst, 0, 3)] & 0xfffffffe;
- //cpu->TFlag = cpu->Reg[BITS(inst, 0, 3)] & 0x1;
- } else {
- cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
- cpu->TFlag = 0x1;
- int signed_int = inst_cream->val.signed_immed_24;
- signed_int = (signed_int) & 0x800000 ? (0x3F000000 | signed_int) : signed_int;
- signed_int = signed_int << 2;
- // cpu->Reg[15] = cpu->Reg[15] + 2 * GET_INST_SIZE(cpu)
- cpu->Reg[15] = cpu->Reg[15] + 8
- + signed_int + (BIT(inst, 24) << 1);
- //DEBUG_MSG;
- }
- INC_PC(sizeof(blx_inst));
- goto DISPATCH;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
-// INC_PC(sizeof(bx_inst));
- INC_PC(sizeof(blx_inst));
- goto DISPATCH;
- }
- BX_INST:
- {
- INC_ICOUNTER;
- bx_inst *inst_cream = (bx_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- if (inst_cream->Rm == 15)
- LOG_WARNING(Core_ARM11, "BX at pc %x: use of Rm = R15 is discouraged", cpu->Reg[15]);
- cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1;
- cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe;
-// cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1;
- INC_PC(sizeof(bx_inst));
- goto DISPATCH;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
-// INC_PC(sizeof(bx_inst));
- INC_PC(sizeof(bx_inst));
- goto DISPATCH;
- }
- BXJ_INST:
- CDP_INST:
- {
- INC_ICOUNTER;
- cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- /* FIXME, check if cp access allowed */
- #define CP_ACCESS_ALLOW 0
- if(CP_ACCESS_ALLOW){
- /* undefined instruction here */
- cpu->NumInstrsToExecute = 0;
- return num_instrs;
- }
- LOG_ERROR(Core_ARM11, "CDP insn inst=0x%x, pc=0x%x\n", inst_cream->inst, cpu->Reg[15]);
- unsigned cpab = (cpu->CDP[inst_cream->cp_num]) (cpu, ARMul_FIRST, inst_cream->inst);
- if(cpab != ARMul_DONE){
- LOG_ERROR(Core_ARM11, "CDP insn wrong, inst=0x%x, cp_num=0x%x\n", inst_cream->inst, inst_cream->cp_num);
- //CITRA_IGNORE_EXIT(-1);
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(cdp_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- CLREX_INST:
- {
- INC_ICOUNTER;
- remove_exclusive(cpu, 0);
- cpu->exclusive_state = 0;
-
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(clrex_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- CLZ_INST:
- {
- INC_ICOUNTER;
- clz_inst *inst_cream = (clz_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- RD = clz(RM);
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(clz_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- CMN_INST:
- {
- INC_ICOUNTER;
- cmn_inst *inst_cream = (cmn_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-// DEBUG_LOG(ARM11, "RN is %x\n", RN);
- lop = RN;
- rop = SHIFTER_OPERAND;
- dst = lop + rop;
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
- UPDATE_CFLAG(dst, lop, rop);
- UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(cmn_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- CMP_INST:
- {
-// DEBUG_LOG(ARM11, "cmp inst\n");
-// DEBUG_LOG(ARM11, "pc: %x\n", cpu->Reg[15]);
- INC_ICOUNTER;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-// DEBUG_LOG(ARM11, "r0 is %x\n", cpu->Reg[0]);
- cmp_inst *inst_cream = (cmp_inst *)inst_base->component;
- lop = RN;
- if (inst_cream->Rn == 15) {
- lop += 2 * GET_INST_SIZE(cpu);
- }
- rop = SHIFTER_OPERAND;
- dst = lop - rop;
-
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
-// UPDATE_CFLAG(dst, lop, rop);
- UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
-// UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
- UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
-// UPDATE_VFLAG_WITH_NOT(dst, lop, rop);
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(cmp_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- CPS_INST:
- {
- INC_ICOUNTER;
- cps_inst *inst_cream = (cps_inst *)inst_base->component;
- uint32_t aif_val = 0;
- uint32_t aif_mask = 0;
- if (InAPrivilegedMode(cpu)) {
- /* isInAPrivilegedMode */
- if (inst_cream->imod1) {
- if (inst_cream->A) {
- aif_val |= (inst_cream->imod0 << 8);
- aif_mask |= 1 << 8;
- }
- if (inst_cream->I) {
- aif_val |= (inst_cream->imod0 << 7);
- aif_mask |= 1 << 7;
- }
- if (inst_cream->F) {
- aif_val |= (inst_cream->imod0 << 6);
- aif_mask |= 1 << 6;
- }
- aif_mask = ~aif_mask;
- cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val;
- }
- if (inst_cream->mmod) {
- cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode;
- switch_mode(cpu, inst_cream->mode);
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(cps_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- CPY_INST:
- {
- INC_ICOUNTER;
- mov_inst *inst_cream = (mov_inst *)inst_base->component;
-// cpy_inst *inst_cream = (cpy_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- RD = SHIFTER_OPERAND;
-// RD = RM;
- if ((inst_cream->Rd == 15)) {
- INC_PC(sizeof(mov_inst));
- goto DISPATCH;
- }
- }
-// DEBUG_LOG(ARM11, "cpy inst %x\n", cpu->Reg[15]);
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(mov_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- EOR_INST:
- {
- INC_ICOUNTER;
- eor_inst *inst_cream = (eor_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- lop = RN;
- if (inst_cream->Rn == 15) {
- lop += 2 * GET_INST_SIZE(cpu);
- }
- rop = SHIFTER_OPERAND;
- RD = dst = lop ^ rop;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- /* cpsr = spsr*/
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
- UPDATE_CFLAG_WITH_SC;
-// UPDATE_CFLAG(dst, lop, rop);
-// UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(eor_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(eor_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDC_INST:
- {
- INC_ICOUNTER;
- /* NOT IMPL */
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDM_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- int i;
- unsigned int ret;
- fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
- if (fault) {
- goto MMU_EXCEPTION;
- }
- unsigned int inst = inst_cream->inst;
- if (BIT(inst, 22) && !BIT(inst, 15)) {
-// DEBUG_MSG;
- #if 1
- /* LDM (2) user */
- for (i = 0; i < 13; i++) {
- if(BIT(inst, i)){
- #if 0
- fault = check_address_validity(cpu, addr, &phys_addr, 1);
- if (fault) {
- goto MMU_EXCEPTION;
- }
- #endif
- fault = interpreter_read_memory(addr, phys_addr, ret, 32);
- //if (fault) goto MMU_EXCEPTION;
- cpu->Reg[i] = ret;
- addr += 4;
- if ((addr & 0xfff) == 0) {
- fault = check_address_validity(cpu, addr, &phys_addr, 1);
- } else {
- phys_addr += 4;
- }
- }
- }
- if (BIT(inst, 13)) {
- #if 0
- fault = check_address_validity(cpu, addr, &phys_addr, 1);
- if (fault) {
- goto MMU_EXCEPTION;
- }
- #endif
- fault = interpreter_read_memory(addr, phys_addr, ret, 32);
- //if (fault) goto MMU_EXCEPTION;
- if (cpu->Mode == USER32MODE)
- cpu->Reg[13] = ret;
- else
- cpu->Reg_usr[0] = ret;
- addr += 4;
- if ((addr & 0xfff) == 0) {
- fault = check_address_validity(cpu, addr, &phys_addr, 1);
- } else {
- phys_addr += 4;
- }
- }
- if (BIT(inst, 14)) {
- #if 0
- fault = check_address_validity(cpu, addr, &phys_addr, 1);
- if (fault) {
- goto MMU_EXCEPTION;
- }
- #endif
- fault = interpreter_read_memory(addr, phys_addr, ret, 32);
- //if (fault) goto MMU_EXCEPTION;
- if (cpu->Mode == USER32MODE)
- cpu->Reg[14] = ret;
- else
- cpu->Reg_usr[1] = ret;
- }
- #endif
- } else if (!BIT(inst, 22)) {
- for( i = 0; i < 16; i ++ ){
- if(BIT(inst, i)){
- //bus_read(32, addr, &ret);
- #if 0
- fault = check_address_validity(cpu, addr, &phys_addr, 1);
- if (fault) {
- goto MMU_EXCEPTION;
- }
- #endif
- fault = interpreter_read_memory(addr, phys_addr, ret, 32);
- if (fault) goto MMU_EXCEPTION;
- /* For armv5t, should enter thumb when bits[0] is non-zero. */
- if(i == 15){
- cpu->TFlag = ret & 0x1;
- ret &= 0xFFFFFFFE;
- //DEBUG_LOG(ARM11, "In %s, TFlag ret=0x%x\n", __FUNCTION__, ret);
- }
-
- cpu->Reg[i] = ret;
- addr += 4;
- if ((addr & 0xfff) == 0) {
- fault = check_address_validity(cpu, addr, &phys_addr, 1);
- } else {
- phys_addr += 4;
- }
- }
- }
- } else if (BIT(inst, 22) && BIT(inst, 15)) {
- for( i = 0; i < 15; i ++ ){
- if(BIT(inst, i)){
- #if 0
- fault = check_address_validity(cpu, addr, &phys_addr, 1);
- if (fault) {
- goto MMU_EXCEPTION;
- }
- #endif
- fault = interpreter_read_memory(addr, phys_addr, ret, 32);
- //if (fault) goto MMU_EXCEPTION;
- cpu->Reg[i] = ret;
- addr += 4;
- if ((addr & 0xfff) == 0) {
- fault = check_address_validity(cpu, addr, &phys_addr, 1);
- } else {
- phys_addr += 4;
- }
- }
- }
-
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Cpsr & 0x1f);
- LOAD_NZCVT;
- }
- #if 0
- fault = check_address_validity(cpu, addr, &phys_addr, 1);
- if (fault) {
- goto MMU_EXCEPTION;
- }
- #endif
- fault = interpreter_read_memory(addr, phys_addr, ret, 32);
- if (fault) {
- goto MMU_EXCEPTION;
- }
- cpu->Reg[15] = ret;
- #if 0
- addr += 4;
- phys_addr += 4;
- #endif
- }
- if (BIT(inst, 15)) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SXTH_INST:
- {
- INC_ICOUNTER;
- sxth_inst *inst_cream = (sxth_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
- if (BIT(operand2, 15)) {
- operand2 |= 0xffff0000;
- } else {
- operand2 &= 0xffff;
- }
- RD = operand2;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(sxth_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDR_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
- if (fault) goto MMU_EXCEPTION;
- unsigned int value;
- //bus_read(32, addr, &value);
- fault = interpreter_read_memory(addr, phys_addr, value, 32);
- if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- else {
- value = ROTATE_RIGHT_32(value,(8*(addr&0x3)));
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- }
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- /* For armv5t, should enter thumb when bits[0] is non-zero. */
- cpu->TFlag = value & 0x1;
- cpu->Reg[15] &= 0xFFFFFFFE;
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- //}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRCOND_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if (CondPassed(cpu, inst_base->cond)) {
- fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
- if (fault) goto MMU_EXCEPTION;
- unsigned int value;
- //bus_read(32, addr, &value);
- fault = interpreter_read_memory(addr, phys_addr, value, 32);
- if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- else {
- value = ROTATE_RIGHT_32(value,(8*(addr&0x3)));
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+ goto END;
+
+ inst_base = (arm_inst *)&inst_buf[ptr];
+ GOTO_NEXT_INST;
+ }
+ ADC_INST:
+ {
+ adc_inst *inst_cream = (adc_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ lop = RN;
+ unsigned int sht_op = SHIFTER_OPERAND;
+ rop = SHIFTER_OPERAND + cpu->CFlag;
+ RD = dst = lop + rop;
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ LOAD_NZCVT;
+ }
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+ UPDATE_CFLAG_CARRY_FROM_ADD(lop, sht_op, cpu->CFlag);
+ UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(adc_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(adc_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ ADD_INST:
+ {
+ add_inst *inst_cream = (add_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ lop = RN;
+ if (inst_cream->Rn == 15) {
+ lop += 2 * GET_INST_SIZE(cpu);
+ }
+ rop = SHIFTER_OPERAND;
+ RD = dst = lop + rop;
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ switch_mode(cpu, cpu->Cpsr & 0x1f);
+ LOAD_NZCVT;
+ }
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+ UPDATE_CFLAG(dst, lop, rop);
+ UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(add_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(add_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ AND_INST:
+ {
+ and_inst *inst_cream = (and_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ lop = RN;
+ rop = SHIFTER_OPERAND;
+ RD = dst = lop & rop;
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ switch_mode(cpu, cpu->Cpsr & 0x1f);
+ LOAD_NZCVT;
+ }
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+ UPDATE_CFLAG_WITH_SC;
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(and_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(and_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ BBL_INST:
+ {
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
+ if (inst_cream->L) {
+ LINK_RTN_ADDR;
+ }
+ SET_PC;
+ INC_PC(sizeof(bbl_inst));
+ goto DISPATCH;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(bbl_inst));
+ goto DISPATCH;
+ }
+ BIC_INST:
+ {
+ bic_inst *inst_cream = (bic_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ lop = RN;
+ if (inst_cream->Rn == 15) {
+ lop += 2 * GET_INST_SIZE(cpu);
+ }
+ rop = SHIFTER_OPERAND;
+ RD = dst = lop & (~rop);
+ if ((inst_cream->S) && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ LOAD_NZCVT;
+ }
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+ UPDATE_CFLAG_WITH_SC;
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(bic_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(bic_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ BKPT_INST:
+ BLX_INST:
+ {
+ blx_inst *inst_cream = (blx_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ unsigned int inst = inst_cream->inst;
+ if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
+ cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
+ if(cpu->TFlag)
+ cpu->Reg[14] |= 0x1;
+ cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe;
+ cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1;
+ } else {
+ cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
+ cpu->TFlag = 0x1;
+ int signed_int = inst_cream->val.signed_immed_24;
+ signed_int = (signed_int) & 0x800000 ? (0x3F000000 | signed_int) : signed_int;
+ signed_int = signed_int << 2;
+ cpu->Reg[15] = cpu->Reg[15] + 8 + signed_int + (BIT(inst, 24) << 1);
+ }
+ INC_PC(sizeof(blx_inst));
+ goto DISPATCH;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(blx_inst));
+ goto DISPATCH;
+ }
+ BX_INST:
+ {
+ bx_inst *inst_cream = (bx_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ if (inst_cream->Rm == 15)
+ LOG_WARNING(Core_ARM11, "BX at pc %x: use of Rm = R15 is discouraged", cpu->Reg[15]);
+ cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1;
+ cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe;
+ INC_PC(sizeof(bx_inst));
+ goto DISPATCH;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(bx_inst));
+ goto DISPATCH;
+ }
+ BXJ_INST:
+ CDP_INST:
+ {
+ cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ // Undefined instruction here
+ cpu->NumInstrsToExecute = 0;
+ return num_instrs;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(cdp_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ CLREX_INST:
+ {
+ remove_exclusive(cpu, 0);
+ cpu->exclusive_state = 0;
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(clrex_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ CLZ_INST:
+ {
+ clz_inst *inst_cream = (clz_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ RD = clz(RM);
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(clz_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ CMN_INST:
+ {
+ cmn_inst *inst_cream = (cmn_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ lop = RN;
+ rop = SHIFTER_OPERAND;
+ dst = lop + rop;
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+ UPDATE_CFLAG(dst, lop, rop);
+ UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(cmn_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ CMP_INST:
+ {
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ cmp_inst *inst_cream = (cmp_inst *)inst_base->component;
+ lop = RN;
+ if (inst_cream->Rn == 15) {
+ lop += 2 * GET_INST_SIZE(cpu);
+ }
+ rop = SHIFTER_OPERAND;
+ dst = lop - rop;
+
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+ UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
+ UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(cmp_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ CPS_INST:
+ {
+ cps_inst *inst_cream = (cps_inst *)inst_base->component;
+ uint32_t aif_val = 0;
+ uint32_t aif_mask = 0;
+ if (InAPrivilegedMode(cpu)) {
+ if (inst_cream->imod1) {
+ if (inst_cream->A) {
+ aif_val |= (inst_cream->imod0 << 8);
+ aif_mask |= 1 << 8;
+ }
+ if (inst_cream->I) {
+ aif_val |= (inst_cream->imod0 << 7);
+ aif_mask |= 1 << 7;
+ }
+ if (inst_cream->F) {
+ aif_val |= (inst_cream->imod0 << 6);
+ aif_mask |= 1 << 6;
+ }
+ aif_mask = ~aif_mask;
+ cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val;
+ }
+ if (inst_cream->mmod) {
+ cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode;
+ switch_mode(cpu, inst_cream->mode);
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(cps_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ CPY_INST:
+ {
+ mov_inst *inst_cream = (mov_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ RD = SHIFTER_OPERAND;
+ if ((inst_cream->Rd == 15)) {
+ INC_PC(sizeof(mov_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(mov_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ EOR_INST:
+ {
+ eor_inst *inst_cream = (eor_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ lop = RN;
+ if (inst_cream->Rn == 15) {
+ lop += 2 * GET_INST_SIZE(cpu);
+ }
+ rop = SHIFTER_OPERAND;
+ RD = dst = lop ^ rop;
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ LOAD_NZCVT;
+ }
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+ UPDATE_CFLAG_WITH_SC;
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(eor_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(eor_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ LDC_INST:
+ {
+ // Instruction not implemented
+ //LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldc_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ LDM_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ int i;
+ unsigned int ret;
+ fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+ if (fault) {
+ goto MMU_EXCEPTION;
+ }
+ unsigned int inst = inst_cream->inst;
+ if (BIT(inst, 22) && !BIT(inst, 15)) {
+ for (i = 0; i < 13; i++) {
+ if(BIT(inst, i)){
+ fault = interpreter_read_memory(addr, phys_addr, ret, 32);
+ cpu->Reg[i] = ret;
+ addr += 4;
+ if ((addr & 0xfff) == 0) {
+ fault = check_address_validity(cpu, addr, &phys_addr, 1);
+ } else {
+ phys_addr += 4;
+ }
+ }
+ }
+ if (BIT(inst, 13)) {
+ fault = interpreter_read_memory(addr, phys_addr, ret, 32);
+
+ if (cpu->Mode == USER32MODE)
+ cpu->Reg[13] = ret;
+ else
+ cpu->Reg_usr[0] = ret;
+ addr += 4;
+ if ((addr & 0xfff) == 0) {
+ fault = check_address_validity(cpu, addr, &phys_addr, 1);
+ } else {
+ phys_addr += 4;
+ }
+ }
+ if (BIT(inst, 14)) {
+ fault = interpreter_read_memory(addr, phys_addr, ret, 32);
+
+ if (cpu->Mode == USER32MODE)
+ cpu->Reg[14] = ret;
+ else
+ cpu->Reg_usr[1] = ret;
+ }
+ } else if (!BIT(inst, 22)) {
+ for( i = 0; i < 16; i ++ ){
+ if(BIT(inst, i)){
+ fault = interpreter_read_memory(addr, phys_addr, ret, 32);
+ if (fault) goto MMU_EXCEPTION;
+
+ // For armv5t, should enter thumb when bits[0] is non-zero.
+ if(i == 15){
+ cpu->TFlag = ret & 0x1;
+ ret &= 0xFFFFFFFE;
+ }
+
+ cpu->Reg[i] = ret;
+ addr += 4;
+ if ((addr & 0xfff) == 0) {
+ fault = check_address_validity(cpu, addr, &phys_addr, 1);
+ } else {
+ phys_addr += 4;
+ }
+ }
+ }
+ } else if (BIT(inst, 22) && BIT(inst, 15)) {
+ for( i = 0; i < 15; i ++ ){
+ if(BIT(inst, i)){
+ fault = interpreter_read_memory(addr, phys_addr, ret, 32);
+ cpu->Reg[i] = ret;
+ addr += 4;
+ if ((addr & 0xfff) == 0) {
+ fault = check_address_validity(cpu, addr, &phys_addr, 1);
+ } else {
+ phys_addr += 4;
+ }
+ }
+ }
+
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ switch_mode(cpu, cpu->Cpsr & 0x1f);
+ LOAD_NZCVT;
+ }
+
+ fault = interpreter_read_memory(addr, phys_addr, ret, 32);
+ if (fault) {
+ goto MMU_EXCEPTION;
+ }
+ cpu->Reg[15] = ret;
+ }
+ if (BIT(inst, 15)) {
+ INC_PC(sizeof(ldst_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ SXTH_INST:
+ {
+ sxth_inst *inst_cream = (sxth_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
+ if (BIT(operand2, 15)) {
+ operand2 |= 0xffff0000;
+ } else {
+ operand2 &= 0xffff;
+ }
+ RD = operand2;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(sxth_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ LDR_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+ if (fault) goto MMU_EXCEPTION;
+ unsigned int value;
+ fault = interpreter_read_memory(addr, phys_addr, value, 32);
+ if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+ else {
+ value = ROTATE_RIGHT_32(value,(8*(addr&0x3)));
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+ }
+ if (BITS(inst_cream->inst, 12, 15) == 15) {
+ // For armv5t, should enter thumb when bits[0] is non-zero.
+ cpu->TFlag = value & 0x1;
+ cpu->Reg[15] &= 0xFFFFFFFE;
+ INC_PC(sizeof(ldst_inst));
+ goto DISPATCH;
+ }
+ //}
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ LDRCOND_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if (CondPassed(cpu, inst_base->cond)) {
+ fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+ if (fault) goto MMU_EXCEPTION;
+ unsigned int value;
+ fault = interpreter_read_memory(addr, phys_addr, value, 32);
+ if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+ else {
+ value = ROTATE_RIGHT_32(value,(8*(addr&0x3)));
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+ }
+
+ if (BITS(inst_cream->inst, 12, 15) == 15) {
+ // For armv5t, should enter thumb when bits[0] is non-zero.
+ cpu->TFlag = value & 0x1;
+ cpu->Reg[15] &= 0xFFFFFFFE;
+ INC_PC(sizeof(ldst_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ UXTH_INST:
+ {
+ uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
+ & 0xffff;
+ RD = operand2;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(uxth_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ UXTAH_INST:
+ {
+ uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
+ & 0xffff;
+ RD = RN + operand2;
+ if (inst_cream->Rn == 15 || inst_cream->Rm == 15) {
+ LOG_ERROR(Core_ARM11, "invalid operands for UXTAH");
+ CITRA_IGNORE_EXIT(-1);
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(uxtah_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ LDRB_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+ if (fault) goto MMU_EXCEPTION;
+ unsigned int value;
+ fault = interpreter_read_memory(addr, phys_addr, value, 8);
+ if (fault) goto MMU_EXCEPTION;
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+ if (BITS(inst_cream->inst, 12, 15) == 15) {
+ INC_PC(sizeof(ldst_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ LDRBT_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+ if (fault) goto MMU_EXCEPTION;
+ unsigned int value;
+ fault = interpreter_read_memory(addr, phys_addr, value, 8);
+ if (fault) goto MMU_EXCEPTION;
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+ if (BITS(inst_cream->inst, 12, 15) == 15) {
+ INC_PC(sizeof(ldst_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ LDRD_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ // Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0)
+ fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+ if (fault) goto MMU_EXCEPTION;
+ uint32_t rear_phys_addr;
+ fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 1);
+ if(fault){
+ LOG_ERROR(Core_ARM11, "MMU fault , should rollback the above get_addr\n");
+ CITRA_IGNORE_EXIT(-1);
+ goto MMU_EXCEPTION;
+ }
+ unsigned int value;
+ fault = interpreter_read_memory(addr, phys_addr, value, 32);
+ if (fault) goto MMU_EXCEPTION;
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+ fault = interpreter_read_memory(addr + 4, rear_phys_addr, value, 32);
+ if (fault) goto MMU_EXCEPTION;
+ cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = value;
+
+ // No dispatch since this operation should not modify R15
+ }
+ cpu->Reg[15] += 4;
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ LDREX_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
+ fault = check_address_validity(cpu, addr, &phys_addr, 1);
+ if (fault) goto MMU_EXCEPTION;
+ unsigned int value;
+ fault = interpreter_read_memory(addr, phys_addr, value, 32);
+ if (fault) goto MMU_EXCEPTION;
+
+ add_exclusive_addr(cpu, phys_addr);
+ cpu->exclusive_state = 1;
+
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+ if (BITS(inst_cream->inst, 12, 15) == 15) {
+ INC_PC(sizeof(ldst_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ LDREXB_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
+ fault = check_address_validity(cpu, addr, &phys_addr, 1);
+ if (fault) goto MMU_EXCEPTION;
+ unsigned int value;
+ fault = interpreter_read_memory(addr, phys_addr, value, 8);
+ if (fault) goto MMU_EXCEPTION;
+
+ add_exclusive_addr(cpu, phys_addr);
+ cpu->exclusive_state = 1;
+
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+ if (BITS(inst_cream->inst, 12, 15) == 15) {
+ INC_PC(sizeof(ldst_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ LDRH_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+ if (fault) goto MMU_EXCEPTION;
+ unsigned int value = 0;
+ fault = interpreter_read_memory(addr, phys_addr, value, 16);
+ if (fault) goto MMU_EXCEPTION;
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+ if (BITS(inst_cream->inst, 12, 15) == 15) {
+ INC_PC(sizeof(ldst_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ LDRSB_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+ if (fault) goto MMU_EXCEPTION;
+ unsigned int value;
+ fault = interpreter_read_memory(addr, phys_addr, value, 8);
+ if (fault) goto MMU_EXCEPTION;
+ if (BIT(value, 7)) {
+ value |= 0xffffff00;
+ }
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+ if (BITS(inst_cream->inst, 12, 15) == 15) {
+ INC_PC(sizeof(ldst_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ LDRSH_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+ if (fault) goto MMU_EXCEPTION;
+ unsigned int value;
+ fault = interpreter_read_memory(addr, phys_addr, value, 16);
+ if (fault) goto MMU_EXCEPTION;
+ if (BIT(value, 15)) {
+ value |= 0xffff0000;
+ }
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+ if (BITS(inst_cream->inst, 12, 15) == 15) {
+ INC_PC(sizeof(ldst_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ LDRT_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+ if (fault) goto MMU_EXCEPTION;
+ unsigned int value;
+ fault = interpreter_read_memory(addr, phys_addr, value, 32);
+ if (fault) goto MMU_EXCEPTION;
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+
+ if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+ else
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ROTATE_RIGHT_32(value,(8*(addr&0x3))) ;
+
+ if (BITS(inst_cream->inst, 12, 15) == 15) {
+ INC_PC(sizeof(ldst_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ MCR_INST:
+ {
+ mcr_inst *inst_cream = (mcr_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ unsigned int inst = inst_cream->inst;
+ if (inst_cream->Rd == 15) {
+ DEBUG_MSG;
+ } else {
+ if (inst_cream->cp_num == 15) {
+ if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) {
+ CP15_REG(CP15_MAIN_ID) = RD;
+ } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) {
+ CP15_REG(CP15_AUXILIARY_CONTROL) = RD;
+ } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) {
+ CP15_REG(CP15_COPROCESSOR_ACCESS_CONTROL) = RD;
+ } else if(CRn == 1 && CRm == 0 && OPCODE_2 == 0) {
+ CP15_REG(CP15_CONTROL) = RD;
+ } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) {
+ CP15_REG(CP15_DOMAIN_ACCESS_CONTROL) = RD;
+ } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) {
+ CP15_REG(CP15_TRANSLATION_BASE_TABLE_0) = RD;
+ } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 1) {
+ CP15_REG(CP15_TRANSLATION_BASE_TABLE_1) = RD;
+ } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 2) {
+ CP15_REG(CP15_TRANSLATION_BASE_CONTROL) = RD;
+ } else if(CRn == MMU_CACHE_OPS){
+ //LOG_WARNING(Core_ARM11, "cache operations have not implemented.");
+ } else if(CRn == MMU_TLB_OPS){
+ switch (CRm) {
+ case 5: // ITLB
+ switch(OPCODE_2) {
+ case 0: // Invalidate all
+ LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate all");
+ break;
+ case 1: // Invalidate by MVA
+ LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate by mva");
+ break;
+ case 2: // Invalidate by asid
+ LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate by asid");
+ break;
+ default:
+ break;
+ }
+
+ break;
+ case 6: // DTLB
+ switch(OPCODE_2){
+ case 0: // Invalidate all
+ LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate all");
+ break;
+ case 1: // Invalidate by MVA
+ LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate by mva");
+ break;
+ case 2: // Invalidate by asid
+ LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate by asid");
+ break;
+ default:
+ break;
+ }
+ break;
+ case 7: // UNIFILED TLB
+ switch(OPCODE_2){
+ case 0: // invalidate all
+ LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate all");
+ break;
+ case 1: // Invalidate by MVA
+ LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate by mva");
+ break;
+ case 2: // Invalidate by asid
+ LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate by asid");
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ } else if(CRn == MMU_PID) {
+ if(OPCODE_2 == 0)
+ CP15_REG(CP15_PID) = RD;
+ else if(OPCODE_2 == 1)
+ CP15_REG(CP15_CONTEXT_ID) = RD;
+ else if(OPCODE_2 == 3) {
+ CP15_REG(CP15_THREAD_URO) = RD;
+ } else {
+ LOG_ERROR(Core_ARM11, "mmu_mcr wrote UNKNOWN - reg %d", CRn);
+ }
+ } else {
+ LOG_ERROR(Core_ARM11, "mcr CRn=%d, CRm=%d OP2=%d is not implemented", CRn, CRm, OPCODE_2);
+ }
+ }
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(mcr_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ MCRR_INST:
+ MLA_INST:
+ {
+ mla_inst *inst_cream = (mla_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ uint64_t rm = RM;
+ uint64_t rs = RS;
+ uint64_t rn = RN;
+ if (inst_cream->Rm == 15 || inst_cream->Rs == 15 || inst_cream->Rn == 15) {
+ LOG_ERROR(Core_ARM11, "invalid operands for MLA");
+ CITRA_IGNORE_EXIT(-1);
+ }
+ RD = dst = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff);
+ if (inst_cream->S) {
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(mla_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(mla_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ MOV_INST:
+ {
+ mov_inst *inst_cream = (mov_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ RD = dst = SHIFTER_OPERAND;
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ LOAD_NZCVT;
+ }
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+ UPDATE_CFLAG_WITH_SC;
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(mov_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(mov_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ MRC_INST:
+ {
+ mrc_inst *inst_cream = (mrc_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ unsigned int inst = inst_cream->inst;
+ if (inst_cream->Rd == 15) {
+ DEBUG_MSG;
+ }
+ if (inst_cream->inst == 0xeef04a10) {
+ // Undefined instruction fmrx
+ RD = 0x20000000;
+ CITRA_IGNORE_EXIT(-1);
+ goto END;
+ } else {
+ if (inst_cream->cp_num == 15) {
+ if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) {
+ RD = cpu->CP15[CP15(CP15_MAIN_ID)];
+ } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 0) {
+ RD = cpu->CP15[CP15(CP15_CONTROL)];
+ } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) {
+ RD = cpu->CP15[CP15(CP15_AUXILIARY_CONTROL)];
+ } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) {
+ RD = cpu->CP15[CP15(CP15_COPROCESSOR_ACCESS_CONTROL)];
+ } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) {
+ RD = cpu->CP15[CP15(CP15_DOMAIN_ACCESS_CONTROL)];
+ } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) {
+ RD = cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_0)];
+ } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 0) {
+ RD = cpu->CP15[CP15(CP15_FAULT_STATUS)];
+ } else if (CRn == 6 && CRm == 0 && OPCODE_2 == 0) {
+ RD = cpu->CP15[CP15(CP15_FAULT_ADDRESS)];
+ } else if (CRn == 0 && CRm == 0 && OPCODE_2 == 1) {
+ RD = cpu->CP15[CP15(CP15_CACHE_TYPE)];
+ } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 1) {
+ RD = cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)];
+ } else if (CRn == 13) {
+ if(OPCODE_2 == 0)
+ RD = CP15_REG(CP15_PID);
+ else if(OPCODE_2 == 1)
+ RD = CP15_REG(CP15_CONTEXT_ID);
+ else if(OPCODE_2 == 3) {
+ RD = Memory::KERNEL_MEMORY_VADDR;
+ } else {
+ LOG_ERROR(Core_ARM11, "mmu_mrr wrote UNKNOWN - reg %d", CRn);
}
+ } else {
+ LOG_ERROR(Core_ARM11, "mrc CRn=%d, CRm=%d, OP2=%d is not implemented", CRn, CRm, OPCODE_2);
+ }
+ }
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(mrc_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ MRRC_INST:
+ MRS_INST:
+ {
+ mrs_inst *inst_cream = (mrs_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ if (inst_cream->R) {
+ RD = cpu->Spsr_copy;
+ } else {
+ SAVE_NZCVT;
+ RD = cpu->Cpsr;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(mrs_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ MSR_INST:
+ {
+ msr_inst *inst_cream = (msr_inst *)inst_base->component;
+ const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020;
+ unsigned int inst = inst_cream->inst;
+ unsigned int operand;
+
+ if (BIT(inst, 25)) {
+ int rot_imm = BITS(inst, 8, 11) * 2;
+ operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm);
+ } else {
+ operand = cpu->Reg[BITS(inst, 0, 3)];
+ }
+ uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0)
+ | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0);
+ uint32_t mask;
+ if (!inst_cream->R) {
+ if (InAPrivilegedMode(cpu)) {
+ if ((operand & StateMask) != 0) {
+ /// UNPREDICTABLE
+ DEBUG_MSG;
+ } else
+ mask = byte_mask & (UserMask | PrivMask);
+ } else {
+ mask = byte_mask & UserMask;
+ }
+ SAVE_NZCVT;
+
+ cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask);
+ switch_mode(cpu, cpu->Cpsr & 0x1f);
+ LOAD_NZCVT;
+ } else {
+ if (CurrentModeHasSPSR) {
+ mask = byte_mask & (UserMask | PrivMask | StateMask);
+ cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask);
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(msr_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ MUL_INST:
+ {
+ mul_inst *inst_cream = (mul_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ uint64_t rm = RM;
+ uint64_t rs = RS;
+ RD = dst = static_cast<uint32_t>((rm * rs) & 0xffffffff);
+ if (inst_cream->S) {
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(mul_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(mul_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ MVN_INST:
+ {
+ mvn_inst *inst_cream = (mvn_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ RD = dst = ~SHIFTER_OPERAND;
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ LOAD_NZCVT;
+ }
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+ UPDATE_CFLAG_WITH_SC;
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(mvn_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(mvn_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ ORR_INST:
+ {
+ orr_inst *inst_cream = (orr_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ lop = RN;
+ rop = SHIFTER_OPERAND;
+ RD = dst = lop | rop;
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ LOAD_NZCVT;
+ }
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+ UPDATE_CFLAG_WITH_SC;
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(orr_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(orr_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ PKHBT_INST:
+ {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
+ RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000);
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(pkh_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ PKHTB_INST:
+ {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
+ int shift_imm = inst_cream->imm ? inst_cream->imm : 31;
+ RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000);
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(pkh_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ PLD_INST:
+ {
+ // Instruction not implemented
+ //LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(stc_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ QADD_INST:
+ QADD8_INST:
+ QADD16_INST:
+ QADDSUBX_INST:
+ QSUB8_INST:
+ QSUB16_INST:
+ QSUBADDX_INST:
+ {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+ const u16 rm_lo = (RM & 0xFFFF);
+ const u16 rm_hi = ((RM >> 16) & 0xFFFF);
+ const u16 rn_lo = (RN & 0xFFFF);
+ const u16 rn_hi = ((RN >> 16) & 0xFFFF);
+ const u8 op2 = inst_cream->op2;
+
+ u16 lo_result = 0;
+ u16 hi_result = 0;
+
+ // QADD16
+ if (op2 == 0x00) {
+ lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo);
+ hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi);
+ }
+ // QASX
+ else if (op2 == 0x01) {
+ lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi);
+ hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo);
+ }
+ // QSAX
+ else if (op2 == 0x02) {
+ lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi);
+ hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo);
+ }
+ // QSUB16
+ else if (op2 == 0x03) {
+ lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo);
+ hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi);
+ }
+ // QADD8
+ else if (op2 == 0x04) {
+ lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) |
+ ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8;
+ hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) |
+ ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8;
+ }
+ // QSUB8
+ else if (op2 == 0x07) {
+ lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) |
+ ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8;
+ hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) |
+ ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8;
+ }
+
+ RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ QDADD_INST:
+ QDSUB_INST:
+ QSUB_INST:
+ REV_INST:
+ {
+ rev_inst *inst_cream = (rev_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ RD = ((RM & 0xff) << 24) |
+ (((RM >> 8) & 0xff) << 16) |
+ (((RM >> 16) & 0xff) << 8) |
+ ((RM >> 24) & 0xff);
+ if (inst_cream->Rm == 15) {
+ LOG_ERROR(Core_ARM11, "invalid operand for REV");
+ CITRA_IGNORE_EXIT(-1);
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(rev_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ REV16_INST:
+ {
+ rev_inst *inst_cream = (rev_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ RD = (BITS(RM, 0, 7) << 8) |
+ BITS(RM, 8, 15) |
+ (BITS(RM, 16, 23) << 24) |
+ (BITS(RM, 24, 31) << 16);
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(rev_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ REVSH_INST:
+ RFE_INST:
+ RSB_INST:
+ {
+ rsb_inst *inst_cream = (rsb_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ rop = RN;
+ lop = SHIFTER_OPERAND;
+ if (inst_cream->Rn == 15) {
+ rop += 2 * GET_INST_SIZE(cpu);;
+ }
+ RD = dst = lop - rop;
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ LOAD_NZCVT;
+ }
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+ UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
+ UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(rsb_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(rsb_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ RSC_INST:
+ {
+ rsc_inst *inst_cream = (rsc_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ lop = RN;
+ rop = SHIFTER_OPERAND;
+ RD = dst = rop - lop - !cpu->CFlag;
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ LOAD_NZCVT;
+ }
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+ UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(rop, lop, !cpu->CFlag);
+ UPDATE_VFLAG_OVERFLOW_FROM((int)dst, (int)rop, (int)lop);
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(rsc_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(rsc_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ SADD8_INST:
+ SADD16_INST:
+ SADDSUBX_INST:
+ SSUBADDX_INST:
+ SSUB16_INST:
+ {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ const s16 rn_lo = (RN & 0xFFFF);
+ const s16 rn_hi = ((RN >> 16) & 0xFFFF);
+ const s16 rm_lo = (RM & 0xFFFF);
+ const s16 rm_hi = ((RM >> 16) & 0xFFFF);
+
+ s32 lo_result = 0;
+ s32 hi_result = 0;
+
+ // SADD16
+ if (inst_cream->op2 == 0x00) {
+ lo_result = (rn_lo + rm_lo);
+ hi_result = (rn_hi + rm_hi);
+ }
+ // SASX
+ else if (inst_cream->op2 == 0x01) {
+ lo_result = (rn_lo - rm_hi);
+ hi_result = (rn_hi + rm_lo);
+ }
+ // SSAX
+ else if (inst_cream->op2 == 0x02) {
+ lo_result = (rn_lo + rm_hi);
+ hi_result = (rn_hi - rm_lo);
+ }
+ // SSUB16
+ else if (inst_cream->op2 == 0x03) {
+ lo_result = (rn_lo - rm_lo);
+ hi_result = (rn_hi - rm_hi);
+ }
+
+ RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
+
+ if (lo_result >= 0) {
+ cpu->Cpsr |= (1 << 16);
+ cpu->Cpsr |= (1 << 17);
+ } else {
+ cpu->Cpsr &= ~(1 << 16);
+ cpu->Cpsr &= ~(1 << 17);
+ }
+
+ if (hi_result >= 0) {
+ cpu->Cpsr |= (1 << 18);
+ cpu->Cpsr |= (1 << 19);
+ } else {
+ cpu->Cpsr &= ~(1 << 18);
+ cpu->Cpsr &= ~(1 << 19);
+ }
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ SBC_INST:
+ {
+ sbc_inst *inst_cream = (sbc_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ lop = SHIFTER_OPERAND + !cpu->CFlag;
+ rop = RN;
+ RD = dst = rop - lop;
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ LOAD_NZCVT;
+ }
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+
+ if(rop >= !cpu->CFlag)
+ UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND);
+ else
+ UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag);
+
+ UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop);
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(sbc_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(sbc_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ SEL_INST:
+ {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ const u32 to = RM;
+ const u32 from = RN;
+ const u32 cpsr = cpu->Cpsr;
+
+ u32 result;
+ if (cpsr & (1 << 16))
+ result = from & 0xff;
+ else
+ result = to & 0xff;
+
+ if (cpsr & (1 << 17))
+ result |= from & 0x0000ff00;
+ else
+ result |= to & 0x0000ff00;
+
+ if (cpsr & (1 << 18))
+ result |= from & 0x00ff0000;
+ else
+ result |= to & 0x00ff0000;
+
+ if (cpsr & (1 << 19))
+ result |= from & 0xff000000;
+ else
+ result |= to & 0xff000000;
+
+ RD = result;
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ SETEND_INST:
+ SHADD16_INST:
+ SHADD8_INST:
+ SHADDSUBX_INST:
+ SHSUB16_INST:
+ SHSUB8_INST:
+ SHSUBADDX_INST:
+ SMLA_INST:
+ {
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ smla_inst *inst_cream = (smla_inst *)inst_base->component;
+ int32_t operand1, operand2;
+ if (inst_cream->x == 0)
+ operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
+ else
+ operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
+
+ if (inst_cream->y == 0)
+ operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
+ else
+ operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
+ RD = operand1 * operand2 + RN;
+
+ // TODO: FIXME: UPDATE Q FLAGS
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(smla_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ SMLAD_INST:
+ {
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
+ long long int rm = cpu->Reg[inst_cream->Rm];
+ long long int rn = cpu->Reg[inst_cream->Rn];
+ long long int ra = cpu->Reg[inst_cream->Ra];
+
+ // See SMUAD
+ if(inst_cream->Ra == 15)
+ CITRA_IGNORE_EXIT(-1);
+ int operand2 = (inst_cream->m)? ROTATE_RIGHT_32(rm, 16):rm;
+ int half_rn, half_operand2;
+
+ half_rn = rn & 0xFFFF;
+ half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn;
+
+ half_operand2 = operand2 & 0xFFFF;
+ half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2;
+
+ long long int product1 = half_rn * half_operand2;
+
+ half_rn = (rn & 0xFFFF0000) >> 16;
+ half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn;
+
+ half_operand2 = (operand2 & 0xFFFF0000) >> 16;
+ half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2;
+
+ long long int product2 = half_rn * half_operand2;
+
+ long long int signed_ra = (ra & 0x80000000)? (0xFFFFFFFF00000000LL) | ra : ra;
+ long long int result = product1 + product2 + signed_ra;
+ cpu->Reg[inst_cream->Rd] = result & 0xFFFFFFFF;
+
+ // TODO: FIXME should check Signed overflow
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(umlal_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ SMLAL_INST:
+ {
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
+ long long int rm = RM;
+ long long int rs = RS;
+ if (BIT(rm, 31)) {
+ rm |= 0xffffffff00000000LL;
+ }
+ if (BIT(rs, 31)) {
+ rs |= 0xffffffff00000000LL;
+ }
+ long long int rst = rm * rs;
+ long long int rdhi32 = RDHI;
+ long long int hilo = (rdhi32 << 32) + RDLO;
+ rst += hilo;
+ RDLO = BITS(rst, 0, 31);
+ RDHI = BITS(rst, 32, 63);
+ if (inst_cream->S) {
+ cpu->NFlag = BIT(RDHI, 31);
+ cpu->ZFlag = (RDHI == 0 && RDLO == 0);
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(umlal_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ SMLALXY_INST:
+ SMLALD_INST:
+ SMLAW_INST:
+ SMLSD_INST:
+ SMLSLD_INST:
+ SMMLA_INST:
+ SMMLS_INST:
+ SMMUL_INST:
+ SMUAD_INST:
+ SMUL_INST:
+ {
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ smul_inst *inst_cream = (smul_inst *)inst_base->component;
+ uint32_t operand1, operand2;
+ if (inst_cream->x == 0)
+ operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
+ else
+ operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
+
+ if (inst_cream->y == 0)
+ operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
+ else
+ operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
+ RD = operand1 * operand2;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(smul_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ SMULL_INST:
+ {
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ umull_inst *inst_cream = (umull_inst *)inst_base->component;
+ int64_t rm = RM;
+ int64_t rs = RS;
+ if (BIT(rm, 31)) {
+ rm |= 0xffffffff00000000LL;
+ }
+ if (BIT(rs, 31)) {
+ rs |= 0xffffffff00000000LL;
+ }
+ int64_t rst = rm * rs;
+ RDHI = BITS(rst, 32, 63);
+ RDLO = BITS(rst, 0, 31);
+
+ if (inst_cream->S) {
+ cpu->NFlag = BIT(RDHI, 31);
+ cpu->ZFlag = (RDHI == 0 && RDLO == 0);
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(umull_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- /* For armv5t, should enter thumb when bits[0] is non-zero. */
- cpu->TFlag = value & 0x1;
- cpu->Reg[15] &= 0xFFFFFFFE;
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UXTH_INST:
- {
- INC_ICOUNTER;
- uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
- & 0xffff;
- RD = operand2;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(uxth_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UXTAH_INST:
- {
- INC_ICOUNTER;
- uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
- & 0xffff;
- RD = RN + operand2;
- if (inst_cream->Rn == 15 || inst_cream->Rm == 15) {
- LOG_ERROR(Core_ARM11, "invalid operands for UXTAH");
- CITRA_IGNORE_EXIT(-1);
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(uxtah_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRB_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
- if (fault) goto MMU_EXCEPTION;
- unsigned int value;
- fault = interpreter_read_memory(addr, phys_addr, value, 8);
- if (fault) goto MMU_EXCEPTION;
- //bus_read(8, addr, &value);
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRBT_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
- if (fault) goto MMU_EXCEPTION;
- unsigned int value;
- fault = interpreter_read_memory(addr, phys_addr, value, 8);
- if (fault) goto MMU_EXCEPTION;
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRD_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- /* Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0) */
- fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
- if (fault) goto MMU_EXCEPTION;
- uint32_t rear_phys_addr;
- fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 1);
- if(fault){
- LOG_ERROR(Core_ARM11, "mmu fault , should rollback the above get_addr\n");
- CITRA_IGNORE_EXIT(-1);
- goto MMU_EXCEPTION;
- }
- unsigned int value;
- fault = interpreter_read_memory(addr, phys_addr, value, 32);
- if (fault) goto MMU_EXCEPTION;
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- fault = interpreter_read_memory(addr + 4, rear_phys_addr, value, 32);
- if (fault) goto MMU_EXCEPTION;
- cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = value;
- /* No dispatch since this operation should not modify R15 */
- }
- cpu->Reg[15] += 4;
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- LDREX_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
- fault = check_address_validity(cpu, addr, &phys_addr, 1);
- if (fault) goto MMU_EXCEPTION;
- unsigned int value;
- fault = interpreter_read_memory(addr, phys_addr, value, 32);
- if (fault) goto MMU_EXCEPTION;
-
- add_exclusive_addr(cpu, phys_addr);
- cpu->exclusive_state = 1;
-
- //bus_read(32, addr, &value);
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDREXB_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
- fault = check_address_validity(cpu, addr, &phys_addr, 1);
- if (fault) goto MMU_EXCEPTION;
- unsigned int value;
- fault = interpreter_read_memory(addr, phys_addr, value, 8);
- if (fault) goto MMU_EXCEPTION;
-
- add_exclusive_addr(cpu, phys_addr);
- cpu->exclusive_state = 1;
-
- //bus_read(8, addr, &value);
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRH_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
- if (fault) goto MMU_EXCEPTION;
- unsigned int value = 0;
- fault = interpreter_read_memory(addr, phys_addr, value, 16);
-// fault = interpreter_read_memory(addr, value, 32);
- if (fault) goto MMU_EXCEPTION;
- //if (value == 0xffff && cpu->icounter > 190000000 && cpu->icounter < 210000000) {
- // value = 0xffffffff;
- //}
- //bus_read(16, addr, &value);
-// cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value & 0xffff;
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRSB_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
- if (fault) goto MMU_EXCEPTION;
- unsigned int value;
-// DEBUG_LOG(ARM11, "ldrsb addr is %x\n", addr);
- fault = interpreter_read_memory(addr, phys_addr, value, 8);
- if (fault) goto MMU_EXCEPTION;
- //bus_read(8, addr, &value);
- if (BIT(value, 7)) {
- value |= 0xffffff00;
- }
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRSH_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
- if (fault) goto MMU_EXCEPTION;
- unsigned int value;
- fault = interpreter_read_memory(addr, phys_addr, value, 16);
- if (fault) goto MMU_EXCEPTION;
- //bus_read(16, addr, &value);
- if (BIT(value, 15)) {
- value |= 0xffff0000;
- }
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRT_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
- if (fault) goto MMU_EXCEPTION;
- unsigned int value;
- fault = interpreter_read_memory(addr, phys_addr, value, 32);
- if (fault) goto MMU_EXCEPTION;
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
-
- if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- else
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ROTATE_RIGHT_32(value,(8*(addr&0x3))) ;
-
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MCR_INST:
- {
- INC_ICOUNTER;
- /* NOT IMPL */
- mcr_inst *inst_cream = (mcr_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- unsigned int inst = inst_cream->inst;
- if (inst_cream->Rd == 15) {
- DEBUG_MSG;
- } else {
- if (inst_cream->cp_num == 15) {
- if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) {
- //LET(RD, CONST(0x0007b000));
- //LET(RD, CONST(0x410FB760));
- //LET(CP15_MAIN_ID, R(RD));
- CP15_REG(CP15_MAIN_ID) = RD;
- } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) {
- //LET(RD, R(CP15_CONTROL));
- CP15_REG(CP15_AUXILIARY_CONTROL) = RD;
- } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) {
- //LET(RD, R(CP15_CONTROL));
- CP15_REG(CP15_COPROCESSOR_ACCESS_CONTROL) = RD;
- } else if(CRn == 1 && CRm == 0 && OPCODE_2 == 0) {
- //LET(CP15_CONTROL, R(RD));
- CP15_REG(CP15_CONTROL) = RD;
- } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) {
- //LET(CP15_DOMAIN_ACCESS_CONTROL, R(RD));
- CP15_REG(CP15_DOMAIN_ACCESS_CONTROL) = RD;
- } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) {
- //LET(CP15_TRANSLATION_BASE_TABLE_0, R(RD));
- CP15_REG(CP15_TRANSLATION_BASE_TABLE_0) = RD;
- } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 1) {
- //LET(CP15_TRANSLATION_BASE_TABLE_1, R(RD));
- CP15_REG(CP15_TRANSLATION_BASE_TABLE_1) = RD;
- } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 2) {
- //LET(CP15_TRANSLATION_BASE_CONTROL, R(RD));
- CP15_REG(CP15_TRANSLATION_BASE_CONTROL) = RD;
- } else if(CRn == MMU_CACHE_OPS){
- //SKYEYE_WARNING("cache operation have not implemented.\n");
- } else if(CRn == MMU_TLB_OPS){
- switch (CRm) {
- case 5: /* ITLB */
- switch(OPCODE_2){
- case 0: /* invalidate all */
- //invalidate_all_tlb(state);
- LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate all");
- //remove_tlb(INSN_TLB);
- //erase_all(core, INSN_TLB);
- break;
- case 1: /* invalidate by MVA */
- //invalidate_by_mva(state, value);
- //DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by mva\n");
- //remove_tlb_by_mva(RD, INSN_TLB);
- //erase_by_mva(core, RD, INSN_TLB);
- break;
- case 2: /* invalidate by asid */
- //invalidate_by_asid(state, value);
- //DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by asid\n");
- //erase_by_asid(core, RD, INSN_TLB);
- break;
- default:
- break;
- }
-
- break;
- case 6: /* DTLB */
- switch(OPCODE_2){
- case 0: /* invalidate all */
- //invalidate_all_tlb(state);
- //remove_tlb(DATA_TLB);
- //erase_all(core, DATA_TLB);
- LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate all");
- break;
- case 1: /* invalidate by MVA */
- //invalidate_by_mva(state, value);
- //remove_tlb_by_mva(RD, DATA_TLB);
- //erase_by_mva(core, RD, DATA_TLB);
- //DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by mva\n");
- break;
- case 2: /* invalidate by asid */
- //invalidate_by_asid(state, value);
- //remove_tlb_by_asid(RD, DATA_TLB);
- //erase_by_asid(core, RD, DATA_TLB);
- //DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by asid\n");
- break;
- default:
- break;
- }
- break;
- case 7: /* UNIFILED TLB */
- switch(OPCODE_2){
- case 0: /* invalidate all */
- //invalidate_all_tlb(state);
- //erase_all(core, INSN_TLB);
- //erase_all(core, DATA_TLB);
- //remove_tlb(DATA_TLB);
- //remove_tlb(INSN_TLB);
- //DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate all\n");
- break;
- case 1: /* invalidate by MVA */
- //invalidate_by_mva(state, value);
- //erase_by_mva(core, RD, DATA_TLB);
- //erase_by_mva(core, RD, INSN_TLB);
- LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate by mva");
- break;
- case 2: /* invalidate by asid */
- //invalidate_by_asid(state, value);
- //erase_by_asid(core, RD, DATA_TLB);
- //erase_by_asid(core, RD, INSN_TLB);
- LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate by asid");
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- } else if(CRn == MMU_PID){
- if(OPCODE_2 == 0)
- CP15_REG(CP15_PID) = RD;
- else if(OPCODE_2 == 1)
- CP15_REG(CP15_CONTEXT_ID) = RD;
- else if(OPCODE_2 == 3){
- CP15_REG(CP15_THREAD_URO) = RD;
- }
- else{
- printf ("mmu_mcr wrote UNKNOWN - reg %d\n", CRn);
- }
-
- } else {
- LOG_ERROR(Core_ARM11, "mcr CRn=%d, CRm=%d OP2=%d is not implemented", CRn, CRm, OPCODE_2);
- }
- }
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(mcr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MCRR_INST:
- MLA_INST:
- {
- INC_ICOUNTER;
- mla_inst *inst_cream = (mla_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- uint64_t rm = RM;
- uint64_t rs = RS;
- uint64_t rn = RN;
- if (inst_cream->Rm == 15 || inst_cream->Rs == 15 || inst_cream->Rn == 15) {
- LOG_ERROR(Core_ARM11, "invalid operands for MLA");
- CITRA_IGNORE_EXIT(-1);
- }
-// RD = dst = RM * RS + RN;
- RD = dst = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff);
- if (inst_cream->S) {
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(mla_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(mla_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MOV_INST:
- {
-// DEBUG_LOG(ARM11, "mov inst\n");
-// DEBUG_LOG(ARM11, "pc: %x\n", cpu->Reg[15]);
-// debug_function(cpu);
-// cpu->icount ++;
- INC_ICOUNTER;
- mov_inst *inst_cream = (mov_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- RD = dst = SHIFTER_OPERAND;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- /* cpsr = spsr */
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(mov_inst));
- goto DISPATCH;
- }
-// return;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(mov_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MRC_INST:
- {
- INC_ICOUNTER;
- /* NOT IMPL */
- mrc_inst *inst_cream = (mrc_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- unsigned int inst = inst_cream->inst;
- if (inst_cream->Rd == 15) {
- DEBUG_MSG;
- }
- if (inst_cream->inst == 0xeef04a10) {
- /* undefined instruction fmrx */
- RD = 0x20000000;
- CITRA_IGNORE_EXIT(-1);
- goto END;
- } else {
- if (inst_cream->cp_num == 15) {
- if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) {
- //LET(RD, CONST(0x0007b000));
- //LET(RD, CONST(0x410FB760));
- //LET(RD, R(CP15_MAIN_ID));
- RD = cpu->CP15[CP15(CP15_MAIN_ID)];
- } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 0) {
- //LET(RD, R(CP15_CONTROL));
- RD = cpu->CP15[CP15(CP15_CONTROL)];
- } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) {
- //LET(RD, R(CP15_CONTROL));
- RD = cpu->CP15[CP15(CP15_AUXILIARY_CONTROL)];
- } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) {
- //LET(RD, R(CP15_CONTROL));
- RD = cpu->CP15[CP15(CP15_COPROCESSOR_ACCESS_CONTROL)];
- } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) {
- //LET(RD, R(CP15_DOMAIN_ACCESS_CONTROL));
- RD = cpu->CP15[CP15(CP15_DOMAIN_ACCESS_CONTROL)];
- } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) {
- //LET(RD, R(CP15_TRANSLATION_BASE_TABLE_0));
- RD = cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_0)];
- } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 0) {
- //LET(RD, R(CP15_FAULT_STATUS));
- RD = cpu->CP15[CP15(CP15_FAULT_STATUS)];
- } else if (CRn == 6 && CRm == 0 && OPCODE_2 == 0) {
- //LET(RD, R(CP15_FAULT_ADDRESS));
- RD = cpu->CP15[CP15(CP15_FAULT_ADDRESS)];
- } else if (CRn == 0 && CRm == 0 && OPCODE_2 == 1) {
- //LET(RD, R(CP15_CACHE_TYPE));
- RD = cpu->CP15[CP15(CP15_CACHE_TYPE)];
- } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 1) {
- //LET(RD, R(CP15_INSTR_FAULT_STATUS));
- RD = cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)];
- } else if (CRn == 13) {
- if(OPCODE_2 == 0)
- RD = CP15_REG(CP15_PID);
- else if(OPCODE_2 == 1)
- RD = CP15_REG(CP15_CONTEXT_ID);
- else if(OPCODE_2 == 3){
- RD = Memory::KERNEL_MEMORY_VADDR;
- }
- else{
- printf ("mmu_mrr wrote UNKNOWN - reg %d\n", CRn);
- }
- }
- else {
- LOG_ERROR(Core_ARM11, "mrc CRn=%d, CRm=%d, OP2=%d is not implemented", CRn, CRm, OPCODE_2);
- }
- }
- //DEBUG_LOG(ARM11, "mrc is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2);
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(mrc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MRRC_INST:
- MRS_INST:
- {
- INC_ICOUNTER;
- mrs_inst *inst_cream = (mrs_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- if (inst_cream->R) {
- RD = cpu->Spsr_copy;
- } else {
- SAVE_NZCVT;
- RD = cpu->Cpsr;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(mrs_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MSR_INST:
- {
- INC_ICOUNTER;
- msr_inst *inst_cream = (msr_inst *)inst_base->component;
- const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020;
- unsigned int inst = inst_cream->inst;
- unsigned int operand;
-
- if (BIT(inst, 25)) {
- int rot_imm = BITS(inst, 8, 11) * 2;
- //operand = ROTL(CONST(BITS(0, 7)), CONST(32 - rot_imm));
- operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm);
- } else {
- //operand = R(RM);
- operand = cpu->Reg[BITS(inst, 0, 3)];
- }
- uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0)
- | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0);
- uint32_t mask;
- if (!inst_cream->R) {
- if (InAPrivilegedMode(cpu)) {
- if ((operand & StateMask) != 0) {
- /* UNPREDICTABLE */
- DEBUG_MSG;
- } else
- mask = byte_mask & (UserMask | PrivMask);
- } else {
- mask = byte_mask & UserMask;
- }
- //LET(CPSR_REG, OR(AND(R(CPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask))));
- SAVE_NZCVT;
-
- cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask);
- switch_mode(cpu, cpu->Cpsr & 0x1f);
- LOAD_NZCVT;
- } else {
- if (CurrentModeHasSPSR) {
- mask = byte_mask & (UserMask | PrivMask | StateMask);
- //LET(SPSR_REG, OR(AND(R(SPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask))));
- cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask);
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(msr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MUL_INST:
- {
- INC_ICOUNTER;
- mul_inst *inst_cream = (mul_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-// RD = dst = SHIFTER_OPERAND;
- uint64_t rm = RM;
- uint64_t rs = RS;
- RD = dst = static_cast<uint32_t>((rm * rs) & 0xffffffff);
- if (inst_cream->S) {
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(mul_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(mul_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MVN_INST:
- {
- INC_ICOUNTER;
- mvn_inst *inst_cream = (mvn_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-// RD = dst = (SHIFTER_OPERAND ^ 0xffffffff);
- RD = dst = ~SHIFTER_OPERAND;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- /* cpsr = spsr */
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(mvn_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(mvn_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- ORR_INST:
- {
- INC_ICOUNTER;
- orr_inst *inst_cream = (orr_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- lop = RN;
- rop = SHIFTER_OPERAND;
-// DEBUG_LOG(ARM11, "lop is %x, rop is %x, r2 is %x, r3 is %x\n", lop, rop, cpu->Reg[2], cpu->Reg[3]);
- RD = dst = lop | rop;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- /* cpsr = spsr*/
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
- UPDATE_CFLAG_WITH_SC;
-// UPDATE_CFLAG(dst, lop, rop);
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(orr_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(orr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- PKHBT_INST:
- {
- INC_ICOUNTER;
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
- RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000);
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(pkh_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- PKHTB_INST:
- {
- INC_ICOUNTER;
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
- int shift_imm = inst_cream->imm ? inst_cream->imm : 31;
- RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000);
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(pkh_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- PLD_INST:
- {
- INC_ICOUNTER;
- /* NOT IMPL */
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(stc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- QADD_INST:
-
- QADD8_INST:
- QADD16_INST:
- QADDSUBX_INST:
- QSUB8_INST:
- QSUB16_INST:
- QSUBADDX_INST:
- {
- INC_ICOUNTER;
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- const u16 rm_lo = (RM & 0xFFFF);
- const u16 rm_hi = ((RM >> 16) & 0xFFFF);
- const u16 rn_lo = (RN & 0xFFFF);
- const u16 rn_hi = ((RN >> 16) & 0xFFFF);
- const u8 op2 = inst_cream->op2;
-
- u16 lo_result = 0;
- u16 hi_result = 0;
-
- // QADD16
- if (op2 == 0x00) {
- lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo);
- hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi);
- }
- // QASX
- else if (op2 == 0x01) {
- lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi);
- hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo);
- }
- // QSAX
- else if (op2 == 0x02) {
- lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi);
- hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo);
- }
- // QSUB16
- else if (op2 == 0x03) {
- lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo);
- hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi);
- }
- // QADD8
- else if (op2 == 0x04) {
- lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) |
- ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8;
- hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) |
- ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8;
- }
- // QSUB8
- else if (op2 == 0x07) {
- lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) |
- ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8;
- hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) |
- ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8;
- }
-
- RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
- }
-
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- QDADD_INST:
- QDSUB_INST:
- QSUB_INST:
- REV_INST:
- {
- INC_ICOUNTER;
- rev_inst *inst_cream = (rev_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- RD = ((RM & 0xff) << 24) |
- (((RM >> 8) & 0xff) << 16) |
- (((RM >> 16) & 0xff) << 8) |
- ((RM >> 24) & 0xff);
- if (inst_cream->Rm == 15) {
- LOG_ERROR(Core_ARM11, "invalid operand for REV");
- CITRA_IGNORE_EXIT(-1);
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(rev_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- REV16_INST:
- {
- INC_ICOUNTER;
- rev_inst *inst_cream = (rev_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- RD = (BITS(RM, 0, 7) << 8) |
- BITS(RM, 8, 15) |
- (BITS(RM, 16, 23) << 24) |
- (BITS(RM, 24, 31) << 16);
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(rev_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- REVSH_INST:
- RFE_INST:
- RSB_INST:
- {
- INC_ICOUNTER;
- rsb_inst *inst_cream = (rsb_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- rop = RN;
- lop = SHIFTER_OPERAND;
- if (inst_cream->Rn == 15) {
- rop += 2 * GET_INST_SIZE(cpu);;
- }
- RD = dst = lop - rop;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- /* cpsr = spsr */
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
- UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
-// UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
- UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(rsb_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(rsb_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- RSC_INST:
- {
- INC_ICOUNTER;
- rsc_inst *inst_cream = (rsc_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- //lop = RN + !cpu->CFlag;
- //rop = SHIFTER_OPERAND;
- //RD = dst = rop - lop;
- lop = RN;
- rop = SHIFTER_OPERAND;
- RD = dst = rop - lop - !cpu->CFlag;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- /* cpsr = spsr */
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
-// UPDATE_CFLAG(dst, lop, rop);
-// UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop);
- UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(rop, lop, !cpu->CFlag);
-// cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst)));
- UPDATE_VFLAG_OVERFLOW_FROM((int)dst, (int)rop, (int)lop);
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(rsc_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(rsc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SADD8_INST:
-
- SADD16_INST:
- SADDSUBX_INST:
- SSUBADDX_INST:
- SSUB16_INST:
- {
- INC_ICOUNTER;
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- const s16 rn_lo = (RN & 0xFFFF);
- const s16 rn_hi = ((RN >> 16) & 0xFFFF);
- const s16 rm_lo = (RM & 0xFFFF);
- const s16 rm_hi = ((RM >> 16) & 0xFFFF);
-
- s32 lo_result = 0;
- s32 hi_result = 0;
-
- // SADD16
- if (inst_cream->op2 == 0x00) {
- lo_result = (rn_lo + rm_lo);
- hi_result = (rn_hi + rm_hi);
- }
- // SASX
- else if (inst_cream->op2 == 0x01) {
- lo_result = (rn_lo - rm_hi);
- hi_result = (rn_hi + rm_lo);
- }
- // SSAX
- else if (inst_cream->op2 == 0x02) {
- lo_result = (rn_lo + rm_hi);
- hi_result = (rn_hi - rm_lo);
- }
- // SSUB16
- else if (inst_cream->op2 == 0x03) {
- lo_result = (rn_lo - rm_lo);
- hi_result = (rn_hi - rm_hi);
- }
-
- RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
-
- if (lo_result >= 0) {
- cpu->Cpsr |= (1 << 16);
- cpu->Cpsr |= (1 << 17);
- } else {
- cpu->Cpsr &= ~(1 << 16);
- cpu->Cpsr &= ~(1 << 17);
- }
-
- if (hi_result >= 0) {
- cpu->Cpsr |= (1 << 18);
- cpu->Cpsr |= (1 << 19);
- } else {
- cpu->Cpsr &= ~(1 << 18);
- cpu->Cpsr &= ~(1 << 19);
- }
- }
-
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- SBC_INST:
- {
- INC_ICOUNTER;
- sbc_inst *inst_cream = (sbc_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- lop = SHIFTER_OPERAND + !cpu->CFlag;
- rop = RN;
- RD = dst = rop - lop;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- /* cpsr = spsr */
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
-// UPDATE_CFLAG(dst, lop, rop);
- //UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop);
- //rop = rop - !cpu->CFlag;
- if(rop >= !cpu->CFlag)
- UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND);
- else
- UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag);
-// cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst)));
- UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop);
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(sbc_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(sbc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- SEL_INST:
- {
- INC_ICOUNTER;
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- const u32 to = RM;
- const u32 from = RN;
- const u32 cpsr = cpu->Cpsr;
-
- u32 result;
- if (cpsr & (1 << 16))
- result = from & 0xff;
- else
- result = to & 0xff;
-
- if (cpsr & (1 << 17))
- result |= from & 0x0000ff00;
- else
- result |= to & 0x0000ff00;
-
- if (cpsr & (1 << 18))
- result |= from & 0x00ff0000;
- else
- result |= to & 0x00ff0000;
-
- if (cpsr & (1 << 19))
- result |= from & 0xff000000;
- else
- result |= to & 0xff000000;
-
- RD = result;
- }
-
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- SETEND_INST:
- SHADD16_INST:
- SHADD8_INST:
- SHADDSUBX_INST:
- SHSUB16_INST:
- SHSUB8_INST:
- SHSUBADDX_INST:
- SMLA_INST:
- {
- INC_ICOUNTER;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- smla_inst *inst_cream = (smla_inst *)inst_base->component;
- int32_t operand1, operand2;
- if (inst_cream->x == 0)
- operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
- else
- operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
-
- if (inst_cream->y == 0)
- operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
- else
- operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
- RD = operand1 * operand2 + RN;
- //FIXME: UPDATE Q FLAGS
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(smla_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SMLAD_INST:
- {
- INC_ICOUNTER;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
- long long int rm = cpu->Reg[inst_cream->Rm];
- long long int rn = cpu->Reg[inst_cream->Rn];
- long long int ra = cpu->Reg[inst_cream->Ra];
- /* see SMUAD */
- if(inst_cream->Ra == 15)
- CITRA_IGNORE_EXIT(-1);
- int operand2 = (inst_cream->m)? ROTATE_RIGHT_32(rm, 16):rm;
-
- int half_rn, half_operand2;
- half_rn = rn & 0xFFFF;
- half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn;
-
- half_operand2 = operand2 & 0xFFFF;
- half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2;
-
- long long int product1 = half_rn * half_operand2;
-
- half_rn = (rn & 0xFFFF0000) >> 16;
- half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn;
-
- half_operand2 = (operand2 & 0xFFFF0000) >> 16;
- half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2;
-
- long long int product2 = half_rn * half_operand2;
-
- long long int signed_ra = (ra & 0x80000000)? (0xFFFFFFFF00000000LL) | ra : ra;
- long long int result = product1 + product2 + signed_ra;
- cpu->Reg[inst_cream->Rd] = result & 0xFFFFFFFF;
- /* FIXME , should check Signed overflow */
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(umlal_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- SMLAL_INST:
- {
- INC_ICOUNTER;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
- long long int rm = RM;
- long long int rs = RS;
- if (BIT(rm, 31)) {
- rm |= 0xffffffff00000000LL;
- }
- if (BIT(rs, 31)) {
- rs |= 0xffffffff00000000LL;
- }
- long long int rst = rm * rs;
- long long int rdhi32 = RDHI;
- long long int hilo = (rdhi32 << 32) + RDLO;
- rst += hilo;
- RDLO = BITS(rst, 0, 31);
- RDHI = BITS(rst, 32, 63);
- if (inst_cream->S) {
- cpu->NFlag = BIT(RDHI, 31);
- cpu->ZFlag = (RDHI == 0 && RDLO == 0);
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(umlal_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SMLALXY_INST:
- SMLALD_INST:
- SMLAW_INST:
- SMLSD_INST:
- SMLSLD_INST:
- SMMLA_INST:
- SMMLS_INST:
- SMMUL_INST:
- SMUAD_INST:
- SMUL_INST:
- {
- INC_ICOUNTER;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- smul_inst *inst_cream = (smul_inst *)inst_base->component;
- uint32_t operand1, operand2;
- if (inst_cream->x == 0)
- operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
- else
- operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
-
- if (inst_cream->y == 0)
- operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
- else
- operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
- RD = operand1 * operand2;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(smul_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SMULL_INST:
- {
- INC_ICOUNTER;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- umull_inst *inst_cream = (umull_inst *)inst_base->component;
-// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst);
- int64_t rm = RM;
- int64_t rs = RS;
- if (BIT(rm, 31)) {
- rm |= 0xffffffff00000000LL;
- }
- if (BIT(rs, 31)) {
- rs |= 0xffffffff00000000LL;
- }
- int64_t rst = rm * rs;
- RDHI = BITS(rst, 32, 63);
- RDLO = BITS(rst, 0, 31);
-
-
- if (inst_cream->S) {
- cpu->NFlag = BIT(RDHI, 31);
- cpu->ZFlag = (RDHI == 0 && RDLO == 0);
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(umull_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SMULW_INST:
- INC_ICOUNTER;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
-// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst);
- int64_t rm = RM;
- int64_t rn = RN;
- if (inst_cream->m)
- rm = BITS(rm,16 , 31);
- else
- rm = BITS(rm,0 , 15);
- int64_t rst = rm * rn;
- RD = BITS(rst, 16, 47);
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(smlad_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-
- SMUSD_INST:
- SRS_INST:
- SSAT_INST:
- SSAT16_INST:
- SSUB8_INST:
- STC_INST:
- {
- INC_ICOUNTER;
- /* NOT IMPL */
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(stc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STM_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- unsigned int inst = inst_cream->inst;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- int i;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int old_RN = cpu->Reg[Rn];
-
- fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
- if (fault) goto MMU_EXCEPTION;
- if (BIT(inst_cream->inst, 22) == 1) {
-// DEBUG_MSG;
- #if 1
- for (i = 0; i < 13; i++) {
- if(BIT(inst_cream->inst, i)){
- fault = check_address_validity(cpu, addr, &phys_addr, 0);
- if (fault) {
- goto MMU_EXCEPTION;
- }
- fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
- if (fault) goto MMU_EXCEPTION;
- addr += 4;
- phys_addr += 4;
- }
- }
- if (BIT(inst_cream->inst, 13)) {
- if (cpu->Mode == USER32MODE) {
- fault = check_address_validity(cpu, addr, &phys_addr, 0);
- if (fault) {
- goto MMU_EXCEPTION;
- }
- fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
- if (fault) goto MMU_EXCEPTION;
- addr += 4;
- phys_addr += 4;
- } else {
- fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[0], 32);
- if (fault) goto MMU_EXCEPTION;
- addr += 4;
- phys_addr += 4;
- }
- }
- if (BIT(inst_cream->inst, 14)) {
- if (cpu->Mode == USER32MODE) {
- fault = check_address_validity(cpu, addr, &phys_addr, 0);
- if (fault) {
- goto MMU_EXCEPTION;
- }
- fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
- if (fault) goto MMU_EXCEPTION;
- addr += 4;
- phys_addr += 4;
- } else {
- fault = check_address_validity(cpu, addr, &phys_addr, 0);
- if (fault) {
- goto MMU_EXCEPTION;
- }
- fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[1], 32);
- if (fault) goto MMU_EXCEPTION;
- addr += 4;
- phys_addr += 4;
- }
- }
- if (BIT(inst_cream->inst, 15)) {
- fault = check_address_validity(cpu, addr, &phys_addr, 0);
- if (fault) {
- goto MMU_EXCEPTION;
- }
- fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32);
- if (fault) goto MMU_EXCEPTION;
- }
- #endif
- } else {
- for( i = 0; i < 15; i ++ ){
- if(BIT(inst_cream->inst, i)){
- //arch_write_memory(cpu, bb, Addr, R(i), 32);
- //bus_write(32, addr, cpu->Reg[i]);
- fault = check_address_validity(cpu, addr, &phys_addr, 0);
- if (fault) {
- goto MMU_EXCEPTION;
- }
- if(i == Rn)
- fault = interpreter_write_memory(addr, phys_addr, old_RN, 32);
- else
- fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
- if (fault) goto MMU_EXCEPTION;
- addr += 4;
- phys_addr += 4;
- //Addr = ADD(Addr, CONST(4));
- }
- }
-
- /* check pc reg*/
- if(BIT(inst_cream->inst, i)){
- //arch_write_memory(cpu, bb, Addr, STOREM_CHECK_PC, 32);
- //bus_write(32, addr, cpu->Reg[i] + 8);
- fault = check_address_validity(cpu, addr, &phys_addr, 0);
- if (fault) {
- goto MMU_EXCEPTION;
- }
- fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32);
- if (fault) goto MMU_EXCEPTION;
- }
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SXTB_INST:
- {
- INC_ICOUNTER;
- sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- if (inst_cream->Rm == 15) {
- LOG_ERROR(Core_ARM11, "invalid operand for SXTB");
- CITRA_IGNORE_EXIT(-1);
- }
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
- if (BIT(operand2, 7)) {
- operand2 |= 0xffffff00;
- } else
- operand2 &= 0xff;
- RD = operand2;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(sxtb_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STR_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
- if (fault) goto MMU_EXCEPTION;
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
- //bus_write(32, addr, value);
- fault = interpreter_write_memory(addr, phys_addr, value, 32);
- if (fault) goto MMU_EXCEPTION;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UXTB_INST:
- {
- INC_ICOUNTER;
- uxtb_inst *inst_cream = (uxtb_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
- & 0xff;
- RD = operand2;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(uxtb_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UXTAB_INST:
- {
- INC_ICOUNTER;
- uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
- & 0xff;
- RD = RN + operand2;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(uxtab_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STRB_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
- if (fault) goto MMU_EXCEPTION;
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
- //bus_write(8, addr, value);
- fault = interpreter_write_memory(addr, phys_addr, value, 8);
- if (fault) goto MMU_EXCEPTION;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STRBT_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
- if (fault) goto MMU_EXCEPTION;
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
- //bus_write(8, addr, value);
- fault = interpreter_write_memory(addr, phys_addr, value, 8);
- if (fault) goto MMU_EXCEPTION;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- //if (BITS(inst_cream->inst, 12, 15) == 15)
- // goto DISPATCH;
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STRD_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
- if (fault) goto MMU_EXCEPTION;
- uint32_t rear_phys_addr;
- fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 0);
+ SMULW_INST:
+ {
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
+ int64_t rm = RM;
+ int64_t rn = RN;
+ if (inst_cream->m)
+ rm = BITS(rm, 16, 31);
+ else
+ rm = BITS(rm, 0, 15);
+ int64_t rst = rm * rn;
+ RD = BITS(rst, 16, 47);
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(smlad_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ SMUSD_INST:
+ SRS_INST:
+ SSAT_INST:
+ SSAT16_INST:
+ SSUB8_INST:
+ STC_INST:
+ {
+ // Instruction not implemented
+ //LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(stc_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ STM_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ unsigned int inst = inst_cream->inst;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ int i;
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int old_RN = cpu->Reg[Rn];
+
+ fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
+ if (fault) goto MMU_EXCEPTION;
+ if (BIT(inst_cream->inst, 22) == 1) {
+ for (i = 0; i < 13; i++) {
+ if(BIT(inst_cream->inst, i)){
+ fault = check_address_validity(cpu, addr, &phys_addr, 0);
+ if (fault) goto MMU_EXCEPTION;
+ fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
+ if (fault) goto MMU_EXCEPTION;
+ addr += 4;
+ phys_addr += 4;
+ }
+ }
+ if (BIT(inst_cream->inst, 13)) {
+ if (cpu->Mode == USER32MODE) {
+ fault = check_address_validity(cpu, addr, &phys_addr, 0);
+ if (fault) goto MMU_EXCEPTION;
+ fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
+ if (fault) goto MMU_EXCEPTION;
+ addr += 4;
+ phys_addr += 4;
+ } else {
+ fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[0], 32);
+ if (fault) goto MMU_EXCEPTION;
+ addr += 4;
+ phys_addr += 4;
+ }
+ }
+ if (BIT(inst_cream->inst, 14)) {
+ if (cpu->Mode == USER32MODE) {
+ fault = check_address_validity(cpu, addr, &phys_addr, 0);
+ if (fault) goto MMU_EXCEPTION;
+ fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
+ if (fault) goto MMU_EXCEPTION;
+ addr += 4;
+ phys_addr += 4;
+ } else {
+ fault = check_address_validity(cpu, addr, &phys_addr, 0);
+ if (fault) goto MMU_EXCEPTION;
+ fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[1], 32);
+ if (fault) goto MMU_EXCEPTION;
+ addr += 4;
+ phys_addr += 4;
+ }
+ }
+ if (BIT(inst_cream->inst, 15)) {
+ fault = check_address_validity(cpu, addr, &phys_addr, 0);
+ if (fault) goto MMU_EXCEPTION;
+ fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32);
+ if (fault) goto MMU_EXCEPTION;
+ }
+ } else {
+ for( i = 0; i < 15; i ++ ) {
+ if(BIT(inst_cream->inst, i)) {
+ fault = check_address_validity(cpu, addr, &phys_addr, 0);
+ if (fault) goto MMU_EXCEPTION;
+ if(i == Rn)
+ fault = interpreter_write_memory(addr, phys_addr, old_RN, 32);
+ else
+ fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
+ if (fault) goto MMU_EXCEPTION;
+ addr += 4;
+ phys_addr += 4;
+ }
+ }
+
+ // Check PC reg
+ if(BIT(inst_cream->inst, i)) {
+ fault = check_address_validity(cpu, addr, &phys_addr, 0);
+ if (fault) goto MMU_EXCEPTION;
+ fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32);
+ if (fault) goto MMU_EXCEPTION;
+ }
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ SXTB_INST:
+ {
+ sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ if (inst_cream->Rm == 15) {
+ LOG_ERROR(Core_ARM11, "invalid operand for SXTB");
+ CITRA_IGNORE_EXIT(-1);
+ }
+ unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
+ if (BIT(operand2, 7)) {
+ operand2 |= 0xffffff00;
+ } else
+ operand2 &= 0xff;
+ RD = operand2;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(sxtb_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ STR_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
+ if (fault) goto MMU_EXCEPTION;
+ unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
+ fault = interpreter_write_memory(addr, phys_addr, value, 32);
+ if (fault) goto MMU_EXCEPTION;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ UXTB_INST:
+ {
+ uxtb_inst *inst_cream = (uxtb_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
+ & 0xff;
+ RD = operand2;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(uxtb_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ UXTAB_INST:
+ {
+ uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
+ & 0xff;
+ RD = RN + operand2;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(uxtab_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ STRB_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
+ if (fault) goto MMU_EXCEPTION;
+ unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
+ fault = interpreter_write_memory(addr, phys_addr, value, 8);
+ if (fault) goto MMU_EXCEPTION;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ STRBT_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
+ if (fault) goto MMU_EXCEPTION;
+ unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
+ fault = interpreter_write_memory(addr, phys_addr, value, 8);
+ if (fault) goto MMU_EXCEPTION;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ STRD_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
+ if (fault) goto MMU_EXCEPTION;
+ uint32_t rear_phys_addr;
+ fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 0);
if (fault){
- LOG_ERROR(Core_ARM11, "mmu fault , should rollback the above get_addr\n");
- CITRA_IGNORE_EXIT(-1);
- goto MMU_EXCEPTION;
- }
-
- //fault = inst_cream->get_addr(cpu, inst_cream->inst, addr + 4, phys_addr + 4, 0);
- //if (fault) goto MMU_EXCEPTION;
-
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
- //bus_write(32, addr, value);
- fault = interpreter_write_memory(addr, phys_addr, value, 32);
- if (fault) goto MMU_EXCEPTION;
- value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1];
- //bus_write(32, addr, value);
- fault = interpreter_write_memory(addr + 4, rear_phys_addr, value, 32);
- if (fault) goto MMU_EXCEPTION;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STREX_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)];
- fault = check_address_validity(cpu, addr, &phys_addr, 0);
- if (fault) goto MMU_EXCEPTION;
-
- int dest_reg = BITS(inst_cream->inst, 12, 15);
- if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){
- remove_exclusive(cpu, phys_addr);
- cpu->Reg[dest_reg] = 0;
- cpu->exclusive_state = 0;
-
- // bus_write(32, addr, value);
- fault = interpreter_write_memory(addr, phys_addr, value, 32);
- if (fault) goto MMU_EXCEPTION;
- }
- else{
- /* Failed to write due to mutex access */
- cpu->Reg[dest_reg] = 1;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STREXB_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff;
- fault = check_address_validity(cpu, addr, &phys_addr, 0);
- if (fault) goto MMU_EXCEPTION;
- //bus_write(8, addr, value);
- int dest_reg = BITS(inst_cream->inst, 12, 15);
- if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){
- remove_exclusive(cpu, phys_addr);
- cpu->Reg[dest_reg] = 0;
- cpu->exclusive_state = 0;
- fault = interpreter_write_memory(addr, phys_addr, value, 8);
- if (fault) goto MMU_EXCEPTION;
-
- }
- else{
- cpu->Reg[dest_reg] = 1;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STRH_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
- if (fault) goto MMU_EXCEPTION;
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff;
- //bus_write(16, addr, value);
- fault = interpreter_write_memory(addr, phys_addr, value, 16);
- if (fault) goto MMU_EXCEPTION;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- //if (BITS(inst_cream->inst, 12, 15) == 15)
- // goto DISPATCH;
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STRT_INST:
- {
- INC_ICOUNTER;
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
- if (fault) goto MMU_EXCEPTION;
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
- //bus_write(16, addr, value);
- fault = interpreter_write_memory(addr, phys_addr, value, 32);
- if (fault) goto MMU_EXCEPTION;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SUB_INST:
- {
- INC_ICOUNTER;
- sub_inst *inst_cream = (sub_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- lop = RN;
- if (inst_cream->Rn == 15) {
- lop += 8;
- }
- rop = SHIFTER_OPERAND;
- RD = dst = lop - rop;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- /* cpsr = spsr */
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
-// UPDATE_CFLAG(dst, lop, rop);
- UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
- // UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
- UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(sub_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(sub_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SWI_INST:
- {
- INC_ICOUNTER;
- swi_inst *inst_cream = (swi_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- if (true){ //if (core->is_user_mode) { --> Citra only emulates user mode
- //arm_dyncom_SWI(cpu, inst_cream->num);
- HLE::CallSVC(Memory::Read32(cpu->Reg[15]));
- } else {
- cpu->syscallSig = 1;
- goto END;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(swi_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SWP_INST:
- {
- INC_ICOUNTER;
- swp_inst *inst_cream = (swp_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- addr = RN;
- fault = check_address_validity(cpu, addr, &phys_addr, 1);
- if (fault) goto MMU_EXCEPTION;
- unsigned int value;
- fault = interpreter_read_memory(addr, phys_addr, value, 32);
- if (fault) goto MMU_EXCEPTION;
- fault = interpreter_write_memory(addr, phys_addr, RM, 32);
- if (fault) goto MMU_EXCEPTION;
-
- /* ROR(data, 8*UInt(address<1:0>)); */
- assert((phys_addr & 0x3) == 0);
- RD = value;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(swp_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SWPB_INST:
- {
- INC_ICOUNTER;
- swp_inst *inst_cream = (swp_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- addr = RN;
- fault = check_address_validity(cpu, addr, &phys_addr, 1);
- if (fault) goto MMU_EXCEPTION;
- unsigned int value;
- fault = interpreter_read_memory(addr, phys_addr, value, 8);
- if (fault) goto MMU_EXCEPTION;
- fault = interpreter_write_memory(addr, phys_addr, (RM & 0xFF), 8);
- if (fault) goto MMU_EXCEPTION;
-
- /* FIXME */
- #if 0
- if Shared(address) then
- /* ARMv6 */
- physical_address = TLB(address)
- ClearExclusiveByAddress(physical_address,processor_id,1)
- /* See Summary of operation on page A2-49 */
- #endif
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(swp_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SXTAB_INST:
- {
- INC_ICOUNTER;
- sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- /* R15 should be check */
- if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){
- CITRA_IGNORE_EXIT(-1);
- }
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
- & 0xff;
- /* sign extend for byte */
- operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2;
- RD = RN + operand2;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(uxtab_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SXTAB16_INST:
- SXTAH_INST:
- {
- INC_ICOUNTER;
- sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- /* R15 should be check */
- if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){
- CITRA_IGNORE_EXIT(-1);
- }
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
- /* sign extend for half */
- operand2 = (0x8000 & operand2)? (0xFFFF0000 | operand2):operand2;
- RD = RN + operand2;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(sxtah_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SXTB16_INST:
- TEQ_INST:
- {
- INC_ICOUNTER;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- teq_inst *inst_cream = (teq_inst *)inst_base->component;
- lop = RN;
- if (inst_cream->Rn == 15)
- lop += GET_INST_SIZE(cpu) * 2;
-
- rop = SHIFTER_OPERAND;
- dst = lop ^ rop;
-
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
- UPDATE_CFLAG_WITH_SC;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(teq_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- TST_INST:
- {
- INC_ICOUNTER;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- tst_inst *inst_cream = (tst_inst *)inst_base->component;
- lop = RN;
- if (inst_cream->Rn == 15)
- lop += GET_INST_SIZE(cpu) * 2;
- rop = SHIFTER_OPERAND;
- dst = lop & rop;
-
- UPDATE_NFLAG(dst);
- UPDATE_ZFLAG(dst);
- UPDATE_CFLAG_WITH_SC;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(tst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UADD8_INST:
- UADD16_INST:
- UADDSUBX_INST:
-
- UHADD8_INST:
- UHADD16_INST:
- UHADDSUBX_INST:
- UHSUBADDX_INST:
- UHSUB8_INST:
- UHSUB16_INST:
- {
- INC_ICOUNTER;
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- const u32 rm_val = RM;
- const u32 rn_val = RN;
- const u8 op2 = inst_cream->op2;
-
-
- if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03)
- {
- u32 lo_val = 0;
- u32 hi_val = 0;
-
- // UHADD16
- if (op2 == 0x00) {
- lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
- hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
- }
- // UHASX
- else if (op2 == 0x01) {
- lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
- hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
- }
- // UHSAX
- else if (op2 == 0x02) {
- lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
- hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
- }
- // UHSUB16
- else if (op2 == 0x03) {
- lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
- hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
- }
-
- lo_val >>= 1;
- hi_val >>= 1;
-
- RD = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16);
- }
- else if (op2 == 0x04 || op2 == 0x07) {
- u32 sum1;
- u32 sum2;
- u32 sum3;
- u32 sum4;
-
- // UHADD8
- if (op2 == 0x04) {
- sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
- sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
- sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
- sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
- }
- // UHSUB8
- else {
- sum1 = (rn_val & 0xFF) - (rm_val & 0xFF);
- sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
- sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
- sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
- }
-
- sum1 >>= 1;
- sum2 >>= 1;
- sum3 >>= 1;
- sum4 >>= 1;
-
- RD = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24);
- }
-
- }
-
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
-
- UMAAL_INST:
- {
- INC_ICOUNTER;
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- umaal_inst* const inst_cream = (umaal_inst*)inst_base->component;
-
- const u32 rm = RM;
- const u32 rn = RN;
- const u32 rd_lo = RDLO;
- const u32 rd_hi = RDHI;
-
- const u64 result = (rm * rn) + rd_lo + rd_hi;
-
- RDLO = (result & 0xFFFFFFFF);
- RDHI = ((result >> 32) & 0xFFFFFFFF);
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(umaal_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UMLAL_INST:
- {
- INC_ICOUNTER;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
- unsigned long long int rm = RM;
- unsigned long long int rs = RS;
- unsigned long long int rst = rm * rs;
- unsigned long long int add = ((unsigned long long) RDHI)<<32;
- add += RDLO;
- //DEBUG_LOG(ARM11, "rm[%llx] * rs[%llx] = rst[%llx] | add[%llx]\n", RM, RS, rst, add);
- rst += add;
- RDLO = BITS(rst, 0, 31);
- RDHI = BITS(rst, 32, 63);
-
- if (inst_cream->S)
- {
- cpu->NFlag = BIT(RDHI, 31);
- cpu->ZFlag = (RDHI == 0 && RDLO == 0);
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(umlal_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UMULL_INST:
- {
- INC_ICOUNTER;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- umull_inst *inst_cream = (umull_inst *)inst_base->component;
- unsigned long long int rm = RM;
- unsigned long long int rs = RS;
- unsigned long long int rst = rm * rs;
-// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst);
- RDHI = BITS(rst, 32, 63);
- RDLO = BITS(rst, 0, 31);
-
- if (inst_cream->S) {
- cpu->NFlag = BIT(RDHI, 31);
- cpu->ZFlag = (RDHI == 0 && RDLO == 0);
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(umull_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- B_2_THUMB:
- {
- INC_ICOUNTER;
- b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component;
- cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
- //DEBUG_LOG(ARM11, " BL_1_THUMB: imm=0x%x, r14=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]);
- INC_PC(sizeof(b_2_thumb));
- goto DISPATCH;
- }
- B_COND_THUMB:
- {
- INC_ICOUNTER;
- b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component;
- if(CondPassed(cpu, inst_cream->cond))
- cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
- else
- cpu->Reg[15] += 2;
- //DEBUG_LOG(ARM11, " B_COND_THUMB: imm=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[15]);
- INC_PC(sizeof(b_cond_thumb));
- goto DISPATCH;
- }
- BL_1_THUMB:
- {
- INC_ICOUNTER;
- bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component;
- cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm;
- //cpu->Reg[15] += 2;
- //DEBUG_LOG(ARM11, " BL_1_THUMB: imm=0x%x, r14=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]);
-
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(bl_1_thumb));
- FETCH_INST;
- GOTO_NEXT_INST;
-
- }
- BL_2_THUMB:
- {
- INC_ICOUNTER;
- bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component;
- int tmp = ((cpu->Reg[15] + 2) | 1);
- cpu->Reg[15] =
- (cpu->Reg[14] + inst_cream->imm);
- cpu->Reg[14] = tmp;
- //DEBUG_LOG(ARM11, " BL_2_THUMB: imm=0x%x, r14=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]);
- INC_PC(sizeof(bl_2_thumb));
- goto DISPATCH;
- }
- BLX_1_THUMB:
- {
- /* BLX 1 for armv5t and above */
- INC_ICOUNTER;
- uint32 tmp = cpu->Reg[15];
- blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
- cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC;
- //DEBUG_LOG(ARM11, "In BLX_1_THUMB, BLX(1),imm=0x%x,r14=0x%x, instr=0x%x\n", inst_cream->imm, cpu->Reg[14], inst_cream->instr);
- cpu->Reg[14] = ((tmp + 2) | 1);
- //(state->Reg[14] + ((tinstr & 0x07FF) << 1)) & 0xFFFFFFFC;
- /* switch to arm state from thumb state */
- cpu->TFlag = 0;
- //DEBUG_LOG(ARM11, "In BLX_1_THUMB, BLX(1),imm=0x%x,r14=0x%x, r15=0x%x, \n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]);
- INC_PC(sizeof(blx_1_thumb));
- goto DISPATCH;
- }
-
- UQADD8_INST:
- UQADD16_INST:
- UQADDSUBX_INST:
- UQSUB8_INST:
- UQSUB16_INST:
- UQSUBADDX_INST:
- {
- INC_ICOUNTER;
-
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- const u8 op2 = inst_cream->op2;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
-
- u16 lo_val = 0;
- u16 hi_val = 0;
-
- // UQADD16
- if (op2 == 0x00) {
- lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF);
- hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
- }
- // UQASX
- else if (op2 == 0x01) {
- lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
- hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
- }
- // UQSAX
- else if (op2 == 0x02) {
- lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
- hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
- }
- // UQSUB16
- else if (op2 == 0x03) {
- lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF);
- hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
- }
- // UQADD8
- else if (op2 == 0x04) {
- lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) |
- ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8;
- hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) |
- ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8;
- }
- // UQSUB8
- else {
- lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) |
- ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8;
- hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) |
- ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8;
- }
-
- RD = ((lo_val & 0xFFFF) | hi_val << 16);
- }
-
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- USAD8_INST:
- USADA8_INST:
- {
- INC_ICOUNTER;
-
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
-
- const u8 ra_idx = inst_cream->Ra;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
-
- const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF);
- const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF);
- const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF);
- const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF);
-
- u32 finalDif = (diff1 + diff2 + diff3 + diff4);
-
- // Op is USADA8 if true.
- if (ra_idx != 15)
- finalDif += cpu->Reg[ra_idx];
-
- RD = finalDif;
- }
-
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- USAT_INST:
- USAT16_INST:
- USUB16_INST:
- USUB8_INST:
- USUBADDX_INST:
-
- UXTAB16_INST:
- UXTB16_INST:
- {
- INC_ICOUNTER;
-
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component;
-
- const u8 rn_idx = inst_cream->Rn;
- const u32 rm_val = RM;
- const u32 rotation = inst_cream->rotate * 8;
- const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
-
- // UXTB16, otherwise UXTAB16
- if (rn_idx == 15) {
- RD = rotated_rm & 0x00FF00FF;
- }
- else {
- const u32 rn_val = RN;
-
- const u8 lo_rotated = (rotated_rm & 0xFF);
- const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated;
-
- const u8 hi_rotated = (rotated_rm >> 16) & 0xFF;
- const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated;
-
- RD = ((hi_result << 16) | (lo_result & 0xFFFF));
- }
- }
-
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(uxtab_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- #define VFP_INTERPRETER_IMPL
- #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
- #undef VFP_INTERPRETER_IMPL
- MMU_EXCEPTION:
- {
- SAVE_NZCVT;
- cpu->abortSig = true;
- cpu->Aborted = ARMul_DataAbortV;
- cpu->AbortAddr = addr;
- cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff;
- cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr;
- cpu->NumInstrsToExecute = 0;
- return num_instrs;
- }
- END:
- {
- SAVE_NZCVT;
- cpu->NumInstrsToExecute = 0;
- return num_instrs;
- }
- INIT_INST_LENGTH:
- {
-#if 0
- DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel));
- for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++)
- DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]);
- DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel));
-#endif
+ LOG_ERROR(Core_ARM11, "MMU fault , should rollback the above get_addr");
+ CITRA_IGNORE_EXIT(-1);
+ goto MMU_EXCEPTION;
+ }
+
+ unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
+ fault = interpreter_write_memory(addr, phys_addr, value, 32);
+ if (fault) goto MMU_EXCEPTION;
+ value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1];
+ fault = interpreter_write_memory(addr + 4, rear_phys_addr, value, 32);
+ if (fault) goto MMU_EXCEPTION;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ STREX_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
+ unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)];
+ fault = check_address_validity(cpu, addr, &phys_addr, 0);
+ if (fault) goto MMU_EXCEPTION;
+
+ int dest_reg = BITS(inst_cream->inst, 12, 15);
+ if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){
+ remove_exclusive(cpu, phys_addr);
+ cpu->Reg[dest_reg] = 0;
+ cpu->exclusive_state = 0;
+
+ fault = interpreter_write_memory(addr, phys_addr, value, 32);
+ if (fault) goto MMU_EXCEPTION;
+ } else {
+ // Failed to write due to mutex access
+ cpu->Reg[dest_reg] = 1;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ STREXB_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
+ unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff;
+ fault = check_address_validity(cpu, addr, &phys_addr, 0);
+ if (fault) goto MMU_EXCEPTION;
+ int dest_reg = BITS(inst_cream->inst, 12, 15);
+ if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){
+ remove_exclusive(cpu, phys_addr);
+ cpu->Reg[dest_reg] = 0;
+ cpu->exclusive_state = 0;
+ fault = interpreter_write_memory(addr, phys_addr, value, 8);
+ if (fault) goto MMU_EXCEPTION;
+ } else {
+ cpu->Reg[dest_reg] = 1;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ STRH_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
+ if (fault) goto MMU_EXCEPTION;
+ unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff;
+ fault = interpreter_write_memory(addr, phys_addr, value, 16);
+ if (fault) goto MMU_EXCEPTION;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ STRT_INST:
+ {
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
+ if (fault) goto MMU_EXCEPTION;
+ unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
+ fault = interpreter_write_memory(addr, phys_addr, value, 32);
+ if (fault) goto MMU_EXCEPTION;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ SUB_INST:
+ {
+ sub_inst *inst_cream = (sub_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ lop = RN;
+ if (inst_cream->Rn == 15) {
+ lop += 8;
+ }
+ rop = SHIFTER_OPERAND;
+ RD = dst = lop - rop;
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ LOAD_NZCVT;
+ }
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+ UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
+ UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(sub_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(sub_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ SWI_INST:
+ {
+ swi_inst *inst_cream = (swi_inst *)inst_base->component;
+
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond))
+ HLE::CallSVC(Memory::Read32(cpu->Reg[15]));
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(swi_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ SWP_INST:
+ {
+ swp_inst *inst_cream = (swp_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ addr = RN;
+ fault = check_address_validity(cpu, addr, &phys_addr, 1);
+ if (fault) goto MMU_EXCEPTION;
+ unsigned int value;
+ fault = interpreter_read_memory(addr, phys_addr, value, 32);
+ if (fault) goto MMU_EXCEPTION;
+ fault = interpreter_write_memory(addr, phys_addr, RM, 32);
+ if (fault) goto MMU_EXCEPTION;
+
+ assert((phys_addr & 0x3) == 0);
+ RD = value;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(swp_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ SWPB_INST:
+ {
+ swp_inst *inst_cream = (swp_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ addr = RN;
+ fault = check_address_validity(cpu, addr, &phys_addr, 1);
+ if (fault) goto MMU_EXCEPTION;
+ unsigned int value;
+ fault = interpreter_read_memory(addr, phys_addr, value, 8);
+ if (fault) goto MMU_EXCEPTION;
+ fault = interpreter_write_memory(addr, phys_addr, (RM & 0xFF), 8);
+ if (fault) goto MMU_EXCEPTION;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(swp_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ SXTAB_INST:
+ {
+ sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ // R15 should be check
+ if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){
+ CITRA_IGNORE_EXIT(-1);
+ }
+ unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
+
+ // Sign extend for byte
+ operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2;
+ RD = RN + operand2;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(uxtab_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ SXTAB16_INST:
+ SXTAH_INST:
+ {
+ sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ // R15 should be check
+ if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15) {
+ CITRA_IGNORE_EXIT(-1);
+ }
+ unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
+ // Sign extend for half
+ operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2;
+ RD = RN + operand2;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(sxtah_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ SXTB16_INST:
+ TEQ_INST:
+ {
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ teq_inst *inst_cream = (teq_inst *)inst_base->component;
+ lop = RN;
+
+ if (inst_cream->Rn == 15)
+ lop += GET_INST_SIZE(cpu) * 2;
+
+ rop = SHIFTER_OPERAND;
+ dst = lop ^ rop;
+
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+ UPDATE_CFLAG_WITH_SC;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(teq_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ TST_INST:
+ {
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ tst_inst *inst_cream = (tst_inst *)inst_base->component;
+ lop = RN;
+
+ if (inst_cream->Rn == 15)
+ lop += GET_INST_SIZE(cpu) * 2;
+
+ rop = SHIFTER_OPERAND;
+ dst = lop & rop;
+
+ UPDATE_NFLAG(dst);
+ UPDATE_ZFLAG(dst);
+ UPDATE_CFLAG_WITH_SC;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(tst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ UADD8_INST:
+ UADD16_INST:
+ UADDSUBX_INST:
+
+ UHADD8_INST:
+ UHADD16_INST:
+ UHADDSUBX_INST:
+ UHSUBADDX_INST:
+ UHSUB8_INST:
+ UHSUB16_INST:
+ {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
+ const u8 op2 = inst_cream->op2;
+
+ if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03)
+ {
+ u32 lo_val = 0;
+ u32 hi_val = 0;
+
+ // UHADD16
+ if (op2 == 0x00) {
+ lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
+ hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
+ }
+ // UHASX
+ else if (op2 == 0x01) {
+ lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
+ hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
+ }
+ // UHSAX
+ else if (op2 == 0x02) {
+ lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
+ hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
+ }
+ // UHSUB16
+ else if (op2 == 0x03) {
+ lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
+ hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
+ }
+
+ lo_val >>= 1;
+ hi_val >>= 1;
+
+ RD = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16);
+ }
+ else if (op2 == 0x04 || op2 == 0x07) {
+ u32 sum1;
+ u32 sum2;
+ u32 sum3;
+ u32 sum4;
+
+ // UHADD8
+ if (op2 == 0x04) {
+ sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
+ sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
+ sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
+ sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
+ }
+ // UHSUB8
+ else {
+ sum1 = (rn_val & 0xFF) - (rm_val & 0xFF);
+ sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
+ sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
+ sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
+ }
+
+ sum1 >>= 1;
+ sum2 >>= 1;
+ sum3 >>= 1;
+ sum4 >>= 1;
+
+ RD = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24);
+ }
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ UMAAL_INST:
+ {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ umaal_inst* const inst_cream = (umaal_inst*)inst_base->component;
+ const u32 rm = RM;
+ const u32 rn = RN;
+ const u32 rd_lo = RDLO;
+ const u32 rd_hi = RDHI;
+ const u64 result = (rm * rn) + rd_lo + rd_hi;
+
+ RDLO = (result & 0xFFFFFFFF);
+ RDHI = ((result >> 32) & 0xFFFFFFFF);
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(umaal_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ UMLAL_INST:
+ {
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
+ unsigned long long int rm = RM;
+ unsigned long long int rs = RS;
+ unsigned long long int rst = rm * rs;
+ unsigned long long int add = ((unsigned long long) RDHI)<<32;
+ add += RDLO;
+ rst += add;
+ RDLO = BITS(rst, 0, 31);
+ RDHI = BITS(rst, 32, 63);
+
+ if (inst_cream->S) {
+ cpu->NFlag = BIT(RDHI, 31);
+ cpu->ZFlag = (RDHI == 0 && RDLO == 0);
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(umlal_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ UMULL_INST:
+ {
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ umull_inst *inst_cream = (umull_inst *)inst_base->component;
+ unsigned long long int rm = RM;
+ unsigned long long int rs = RS;
+ unsigned long long int rst = rm * rs;
+ RDHI = BITS(rst, 32, 63);
+ RDLO = BITS(rst, 0, 31);
+
+ if (inst_cream->S) {
+ cpu->NFlag = BIT(RDHI, 31);
+ cpu->ZFlag = (RDHI == 0 && RDLO == 0);
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(umull_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ B_2_THUMB:
+ {
+ b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component;
+ cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
+ INC_PC(sizeof(b_2_thumb));
+ goto DISPATCH;
+ }
+ B_COND_THUMB:
+ {
+ b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component;
+
+ if(CondPassed(cpu, inst_cream->cond))
+ cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
+ else
+ cpu->Reg[15] += 2;
+
+ INC_PC(sizeof(b_cond_thumb));
+ goto DISPATCH;
+ }
+ BL_1_THUMB:
+ {
+ bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component;
+ cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm;
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(bl_1_thumb));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ BL_2_THUMB:
+ {
+ bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component;
+ int tmp = ((cpu->Reg[15] + 2) | 1);
+ cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm);
+ cpu->Reg[14] = tmp;
+ INC_PC(sizeof(bl_2_thumb));
+ goto DISPATCH;
+ }
+ BLX_1_THUMB:
+ {
+ // BLX 1 for armv5t and above
+ uint32 tmp = cpu->Reg[15];
+ blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
+ cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC;
+ cpu->Reg[14] = ((tmp + 2) | 1);
+ cpu->TFlag = 0;
+ INC_PC(sizeof(blx_1_thumb));
+ goto DISPATCH;
+ }
+
+ UQADD8_INST:
+ UQADD16_INST:
+ UQADDSUBX_INST:
+ UQSUB8_INST:
+ UQSUB16_INST:
+ UQSUBADDX_INST:
+ {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ const u8 op2 = inst_cream->op2;
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
+
+ u16 lo_val = 0;
+ u16 hi_val = 0;
+
+ // UQADD16
+ if (op2 == 0x00) {
+ lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF);
+ hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ }
+ // UQASX
+ else if (op2 == 0x01) {
+ lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
+ }
+ // UQSAX
+ else if (op2 == 0x02) {
+ lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
+ }
+ // UQSUB16
+ else if (op2 == 0x03) {
+ lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF);
+ hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ }
+ // UQADD8
+ else if (op2 == 0x04) {
+ lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) |
+ ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8;
+ hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) |
+ ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8;
+ }
+ // UQSUB8
+ else {
+ lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) |
+ ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8;
+ hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) |
+ ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8;
+ }
+
+ RD = ((lo_val & 0xFFFF) | hi_val << 16);
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ USAD8_INST:
+ USADA8_INST:
+ {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
+
+ const u8 ra_idx = inst_cream->Ra;
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
+
+ const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF);
+ const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF);
+ const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF);
+ const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF);
+
+ u32 finalDif = (diff1 + diff2 + diff3 + diff4);
+
+ // Op is USADA8 if true.
+ if (ra_idx != 15)
+ finalDif += cpu->Reg[ra_idx];
+
+ RD = finalDif;
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ USAT_INST:
+ USAT16_INST:
+ USUB16_INST:
+ USUB8_INST:
+ USUBADDX_INST:
+ UXTAB16_INST:
+ UXTB16_INST:
+ {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component;
+
+ const u8 rn_idx = inst_cream->Rn;
+ const u32 rm_val = RM;
+ const u32 rotation = inst_cream->rotate * 8;
+ const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
+
+ // UXTB16, otherwise UXTAB16
+ if (rn_idx == 15) {
+ RD = rotated_rm & 0x00FF00FF;
+ } else {
+ const u32 rn_val = RN;
+ const u8 lo_rotated = (rotated_rm & 0xFF);
+ const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated;
+ const u8 hi_rotated = (rotated_rm >> 16) & 0xFF;
+ const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated;
+
+ RD = ((hi_result << 16) | (lo_result & 0xFFFF));
+ }
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(uxtab_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ #define VFP_INTERPRETER_IMPL
+ #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
+ #undef VFP_INTERPRETER_IMPL
+ MMU_EXCEPTION:
+ {
+ SAVE_NZCVT;
+ cpu->abortSig = true;
+ cpu->Aborted = ARMul_DataAbortV;
+ cpu->AbortAddr = addr;
+ cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff;
+ cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr;
+ cpu->NumInstrsToExecute = 0;
+ return num_instrs;
+ }
+ END:
+ {
+ SAVE_NZCVT;
+ cpu->NumInstrsToExecute = 0;
+ return num_instrs;
+ }
+ INIT_INST_LENGTH:
+ {
#if defined __GNUC__ || defined __clang__
- InterpreterInitInstLength((unsigned long long int *)InstLabel, sizeof(InstLabel));
-#endif
-#if 0
- for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++)
- DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]);
- DEBUG_LOG(ARM11, "%llx\n", InstEndLabel[1]);
- DEBUG_LOG(ARM11, "%llx\n", InstLabel[1]);
- DEBUG_LOG(ARM11, "%lld\n", (char *)InstEndLabel[1] - (char *)InstLabel[1]);
+ InterpreterInitInstLength((unsigned long long int *)InstLabel, sizeof(InstLabel));
#endif
- cpu->NumInstrsToExecute = 0;
- return num_instrs;
- }
+ cpu->NumInstrsToExecute = 0;
+ return num_instrs;
+ }
}
-
diff --git a/src/core/arm/dyncom/arm_dyncom_run.cpp b/src/core/arm/dyncom/arm_dyncom_run.cpp
index b66b92cf5..d457d0ac5 100644
--- a/src/core/arm/dyncom/arm_dyncom_run.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_run.cpp
@@ -1,41 +1,15 @@
-/* Copyright (C)
-* 2011 - Michael.Kang blackfin.kang@gmail.com
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-*/
-/**
-* @file arm_dyncom_run.cpp
-* @brief The dyncom run implementation for arm
-* @author Michael.Kang blackfin.kang@gmail.com
-* @version 78.77
-* @date 2011-11-20
-*/
+// Copyright 2012 Michael Kang, 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
#include <assert.h>
#include "core/arm/skyeye_common/armdefs.h"
-void switch_mode(arm_core_t *core, uint32_t mode)
-{
- if (core->Mode == mode) {
- //Mode not changed.
- //printf("mode not changed\n");
+void switch_mode(arm_core_t *core, uint32_t mode) {
+ if (core->Mode == mode)
return;
- }
- //printf("%d --->>> %d\n", core->Mode, mode);
- //printf("In %s, Cpsr=0x%x, R15=0x%x, last_pc=0x%x, cpsr=0x%x, spsr_copy=0x%x, icounter=%lld\n", __FUNCTION__, core->Cpsr, core->Reg[15], core->last_pc, core->Cpsr, core->Spsr_copy, core->icounter);
+
if (mode != USERBANK) {
switch (core->Mode) {
case USER32MODE:
@@ -109,11 +83,8 @@ void switch_mode(arm_core_t *core, uint32_t mode)
}
core->Mode = mode;
- //printf("In %si end, Cpsr=0x%x, R15=0x%x, last_pc=0x%x, cpsr=0x%x, spsr_copy=0x%x, icounter=%lld\n", __FUNCTION__, core->Cpsr, core->Reg[15], core->last_pc, core->Cpsr, core->Spsr_copy, core->icounter);
- //printf("\n--------------------------------------\n");
- }
- else {
- printf("user mode\n");
+ } else {
+ LOG_CRITICAL(Core_ARM11, "user mode");
exit(-2);
}
}
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
index e10f2f9ee..de70ca8ae 100644
--- a/src/core/arm/dyncom/arm_dyncom_thumb.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
@@ -1,35 +1,13 @@
-/* Copyright (C)
-* 2011 - Michael.Kang blackfin.kang@gmail.com
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-*/
-/**
-* @file arm_dyncom_thumb.c
-* @brief The thumb dynamic interpreter
-* @author Michael.Kang blackfin.kang@gmail.com
-* @version 78.77
-* @date 2011-11-07
-*/
-
-/* We can provide simple Thumb simulation by decoding the Thumb
-instruction into its corresponding ARM instruction, and using the
-existing ARM simulator. */
+// Copyright 2012 Michael Kang, 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+// We can provide simple Thumb simulation by decoding the Thumb instruction into its corresponding
+// ARM instruction, and using the existing ARM simulator.
#include "core/arm/skyeye_common/skyeye_defs.h"
-#ifndef MODET /* required for the Thumb instruction support */
+#ifndef MODET // Required for the Thumb instruction support
#if 1
#error "MODET needs to be defined for the Thumb world to work"
#else
@@ -40,482 +18,359 @@ existing ARM simulator. */
#include "core/arm/skyeye_common/armos.h"
#include "core/arm/dyncom/arm_dyncom_thumb.h"
-/* Decode a 16bit Thumb instruction. The instruction is in the low
- 16-bits of the tinstr field, with the following Thumb instruction
- held in the high 16-bits. Passing in two Thumb instructions allows
- easier simulation of the special dual BL instruction. */
+// Decode a 16bit Thumb instruction. The instruction is in the low 16-bits of the tinstr field,
+// with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions
+// allows easier simulation of the special dual BL instruction.
-tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size)
-{
+tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size) {
tdstate valid = t_uninitialized;
- ARMword next_instr;
- ARMword tinstr;
- tinstr = instr;
- /* The endian should be judge here */
- #if 0
- if (state->bigendSig) {
- next_instr = tinstr & 0xFFFF;
- tinstr >>= 16;
- }
- else {
- next_instr = tinstr >> 16;
- tinstr &= 0xFFFF;
- }
- #endif
- if((addr & 0x3) != 0)
- tinstr = instr >> 16;
- else
- tinstr &= 0xFFFF;
-
- //printf("In %s, instr=0x%x, tinstr=0x%x, r15=0x%x\n", __FUNCTION__, instr, tinstr, cpu->translate_pc);
-#if 1 /* debugging to catch non updates */
- *ainstr = 0xDEADC0DE;
-#endif
+ ARMword tinstr;
+ tinstr = instr;
+
+ // The endian should be judge here
+ if((addr & 0x3) != 0)
+ tinstr = instr >> 16;
+ else
+ tinstr &= 0xFFFF;
+
+ *ainstr = 0xDEADC0DE; // Debugging to catch non updates
+
+ switch ((tinstr & 0xF800) >> 11) {
+ case 0: // LSL
+ case 1: // LSR
+ case 2: // ASR
+ *ainstr = 0xE1B00000 // base opcode
+ | ((tinstr & 0x1800) >> (11 - 5)) // shift type
+ |((tinstr & 0x07C0) << (7 - 6)) // imm5
+ |((tinstr & 0x0038) >> 3) // Rs
+ |((tinstr & 0x0007) << 12); // Rd
+ break;
+
+ case 3: // ADD/SUB
+ {
+ ARMword subset[4] = {
+ 0xE0900000, // ADDS Rd,Rs,Rn
+ 0xE0500000, // SUBS Rd,Rs,Rn
+ 0xE2900000, // ADDS Rd,Rs,#imm3
+ 0xE2500000 // SUBS Rd,Rs,#imm3
+ };
+ // It is quicker indexing into a table, than performing switch or conditionals:
+ *ainstr = subset[(tinstr & 0x0600) >> 9] // base opcode
+ |((tinstr & 0x01C0) >> 6) // Rn or imm3
+ |((tinstr & 0x0038) << (16 - 3)) // Rs
+ |((tinstr & 0x0007) << (12 - 0)); // Rd
+ }
+ break;
+
+ case 4: // MOV
+ case 5: // CMP
+ case 6: // ADD
+ case 7: // SUB
+ {
+ ARMword subset[4] = {
+ 0xE3B00000, // MOVS Rd,#imm8
+ 0xE3500000, // CMP Rd,#imm8
+ 0xE2900000, // ADDS Rd,Rd,#imm8
+ 0xE2500000, // SUBS Rd,Rd,#imm8
+ };
+
+ *ainstr = subset[(tinstr & 0x1800) >> 11] // base opcode
+ |((tinstr & 0x00FF) >> 0) // imm8
+ |((tinstr & 0x0700) << (16 - 8)) // Rn
+ |((tinstr & 0x0700) << (12 - 8)); // Rd
+ }
+ break;
+
+ case 8: // Arithmetic and high register transfers
+
+ // TODO: Since the subsets for both Format 4 and Format 5 instructions are made up of
+ // different ARM encodings, we could save the following conditional, and just have one
+ // large subset
+
+ if ((tinstr & (1 << 10)) == 0) {
+ enum otype {
+ t_norm,
+ t_shift,
+ t_neg,
+ t_mul
+ };
+
+ struct {
+ ARMword opcode;
+ otype type;
+ } subset[16] = {
+ { 0xE0100000, t_norm }, // ANDS Rd,Rd,Rs
+ { 0xE0300000, t_norm }, // EORS Rd,Rd,Rs
+ { 0xE1B00010, t_shift }, // MOVS Rd,Rd,LSL Rs
+ { 0xE1B00030, t_shift }, // MOVS Rd,Rd,LSR Rs
+ { 0xE1B00050, t_shift }, // MOVS Rd,Rd,ASR Rs
+ { 0xE0B00000, t_norm }, // ADCS Rd,Rd,Rs
+ { 0xE0D00000, t_norm }, // SBCS Rd,Rd,Rs
+ { 0xE1B00070, t_shift }, // MOVS Rd,Rd,ROR Rs
+ { 0xE1100000, t_norm }, // TST Rd,Rs
+ { 0xE2700000, t_neg }, // RSBS Rd,Rs,#0
+ { 0xE1500000, t_norm }, // CMP Rd,Rs
+ { 0xE1700000, t_norm }, // CMN Rd,Rs
+ { 0xE1900000, t_norm }, // ORRS Rd,Rd,Rs
+ { 0xE0100090, t_mul }, // MULS Rd,Rd,Rs
+ { 0xE1D00000, t_norm }, // BICS Rd,Rd,Rs
+ { 0xE1F00000, t_norm } // MVNS Rd,Rs
+ };
+
+ *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; // base
+
+ switch (subset[(tinstr & 0x03C0) >> 6].type) {
+ case t_norm:
+ *ainstr |= ((tinstr & 0x0007) << 16) // Rn
+ |((tinstr & 0x0007) << 12) // Rd
+ |((tinstr & 0x0038) >> 3); // Rs
+ break;
+ case t_shift:
+ *ainstr |= ((tinstr & 0x0007) << 12) // Rd
+ |((tinstr & 0x0007) >> 0) // Rm
+ |((tinstr & 0x0038) << (8 - 3)); // Rs
+ break;
+ case t_neg:
+ *ainstr |= ((tinstr & 0x0007) << 12) // Rd
+ |((tinstr & 0x0038) << (16 - 3)); // Rn
+ break;
+ case t_mul:
+ *ainstr |= ((tinstr & 0x0007) << 16) // Rd
+ |((tinstr & 0x0007) << 8) // Rs
+ |((tinstr & 0x0038) >> 3); // Rm
+ break;
+ }
+ } else {
+ ARMword Rd = ((tinstr & 0x0007) >> 0);
+ ARMword Rs = ((tinstr & 0x0038) >> 3);
+
+ if (tinstr & (1 << 7))
+ Rd += 8;
+ if (tinstr & (1 << 6))
+ Rs += 8;
+
+ switch ((tinstr & 0x03C0) >> 6) {
+ case 0x1: // ADD Rd,Rd,Hs
+ case 0x2: // ADD Hd,Hd,Rs
+ case 0x3: // ADD Hd,Hd,Hs
+ *ainstr = 0xE0800000 // base
+ | (Rd << 16) // Rn
+ |(Rd << 12) // Rd
+ |(Rs << 0); // Rm
+ break;
+ case 0x5: // CMP Rd,Hs
+ case 0x6: // CMP Hd,Rs
+ case 0x7: // CMP Hd,Hs
+ *ainstr = 0xE1500000 // base
+ | (Rd << 16) // Rn
+ |(Rd << 12) // Rd
+ |(Rs << 0); // Rm
+ break;
+ case 0x9: // MOV Rd,Hs
+ case 0xA: // MOV Hd,Rs
+ case 0xB: // MOV Hd,Hs
+ *ainstr = 0xE1A00000 // base
+ | (Rd << 16) // Rn
+ |(Rd << 12) // Rd
+ |(Rs << 0); // Rm
+ break;
+ case 0xC: // BX Rs
+ case 0xD: // BX Hs
+ *ainstr = 0xE12FFF10 // base
+ | ((tinstr & 0x0078) >> 3); // Rd
+ break;
+ case 0x0: // UNDEFINED
+ case 0x4: // UNDEFINED
+ case 0x8: // UNDEFINED
+ valid = t_undefined;
+ break;
+ case 0xE: // BLX
+ case 0xF: // BLX
+ *ainstr = 0xE1200030 // base
+ | (Rs << 0); // Rm
+ break;
+ }
+ }
+ break;
+
+ case 9: // LDR Rd,[PC,#imm8]
+ *ainstr = 0xE59F0000 // base
+ | ((tinstr & 0x0700) << (12 - 8)) // Rd
+ |((tinstr & 0x00FF) << (2 - 0)); // off8
+ break;
+
+ case 10:
+ case 11:
+ // TODO: Format 7 and Format 8 perform the same ARM encoding, so the following could be
+ // merged into a single subset, saving on the following boolean:
+
+ if ((tinstr & (1 << 9)) == 0) {
+ ARMword subset[4] = {
+ 0xE7800000, // STR Rd,[Rb,Ro]
+ 0xE7C00000, // STRB Rd,[Rb,Ro]
+ 0xE7900000, // LDR Rd,[Rb,Ro]
+ 0xE7D00000 // LDRB Rd,[Rb,Ro]
+ };
+
+ *ainstr = subset[(tinstr & 0x0C00) >> 10] // base
+ |((tinstr & 0x0007) << (12 - 0)) // Rd
+ |((tinstr & 0x0038) << (16 - 3)) // Rb
+ |((tinstr & 0x01C0) >> 6); // Ro
+
+ } else {
+ ARMword subset[4] = {
+ 0xE18000B0, // STRH Rd,[Rb,Ro]
+ 0xE19000D0, // LDRSB Rd,[Rb,Ro]
+ 0xE19000B0, // LDRH Rd,[Rb,Ro]
+ 0xE19000F0 // LDRSH Rd,[Rb,Ro]
+ };
+ *ainstr = subset[(tinstr & 0x0C00) >> 10] // base
+ |((tinstr & 0x0007) << (12 - 0)) // Rd
+ |((tinstr & 0x0038) << (16 - 3)) // Rb
+ |((tinstr & 0x01C0) >> 6); // Ro
+ }
+ break;
+
+ case 12: // STR Rd,[Rb,#imm5]
+ case 13: // LDR Rd,[Rb,#imm5]
+ case 14: // STRB Rd,[Rb,#imm5]
+ case 15: // LDRB Rd,[Rb,#imm5]
+ {
+ ARMword subset[4] = {
+ 0xE5800000, // STR Rd,[Rb,#imm5]
+ 0xE5900000, // LDR Rd,[Rb,#imm5]
+ 0xE5C00000, // STRB Rd,[Rb,#imm5]
+ 0xE5D00000 // LDRB Rd,[Rb,#imm5]
+ };
+ // The offset range defends on whether we are transferring a byte or word value:
+ *ainstr = subset[(tinstr & 0x1800) >> 11] // base
+ |((tinstr & 0x0007) << (12 - 0)) // Rd
+ |((tinstr & 0x0038) << (16 - 3)) // Rb
+ |((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); // off5
+ }
+ break;
+
+ case 16: // STRH Rd,[Rb,#imm5]
+ case 17: // LDRH Rd,[Rb,#imm5]
+ *ainstr = ((tinstr & (1 << 11)) // base
+ ? 0xE1D000B0 // LDRH
+ : 0xE1C000B0) // STRH
+ |((tinstr & 0x0007) << (12 - 0)) // Rd
+ |((tinstr & 0x0038) << (16 - 3)) // Rb
+ |((tinstr & 0x01C0) >> (6 - 1)) // off5, low nibble
+ |((tinstr & 0x0600) >> (9 - 8)); // off5, high nibble
+ break;
+
+ case 18: // STR Rd,[SP,#imm8]
+ case 19: // LDR Rd,[SP,#imm8]
+ *ainstr = ((tinstr & (1 << 11)) // base
+ ? 0xE59D0000 // LDR
+ : 0xE58D0000) // STR
+ |((tinstr & 0x0700) << (12 - 8)) // Rd
+ |((tinstr & 0x00FF) << 2); // off8
+ break;
+
+ case 20: // ADD Rd,PC,#imm8
+ case 21: // ADD Rd,SP,#imm8
+
+ if ((tinstr & (1 << 11)) == 0) {
+
+ // NOTE: The PC value used here should by word aligned. We encode shift-left-by-2 in the
+ // rotate immediate field, so no shift of off8 is needed.
+
+ *ainstr = 0xE28F0F00 // base
+ | ((tinstr & 0x0700) << (12 - 8)) // Rd
+ |(tinstr & 0x00FF); // off8
+ } else {
+ // We encode shift-left-by-2 in the rotate immediate field, so no shift of off8 is needed.
+ *ainstr = 0xE28D0F00 // base
+ | ((tinstr & 0x0700) << (12 - 8)) // Rd
+ |(tinstr & 0x00FF); // off8
+ }
+ break;
+
+ case 22:
+ case 23:
+ if ((tinstr & 0x0F00) == 0x0000) {
+ // NOTE: The instruction contains a shift left of 2 equivalent (implemented as ROR #30):
+ *ainstr = ((tinstr & (1 << 7)) // base
+ ? 0xE24DDF00 // SUB
+ : 0xE28DDF00) // ADD
+ |(tinstr & 0x007F); // off7
+ } else if ((tinstr & 0x0F00) == 0x0e00)
+ *ainstr = 0xEF000000 | SWI_Breakpoint;
+ else {
+ ARMword subset[4] = {
+ 0xE92D0000, // STMDB sp!,{rlist}
+ 0xE92D4000, // STMDB sp!,{rlist,lr}
+ 0xE8BD0000, // LDMIA sp!,{rlist}
+ 0xE8BD8000 // LDMIA sp!,{rlist,pc}
+ };
+ *ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)] // base
+ |(tinstr & 0x00FF); // mask8
+ }
+ break;
+
+ case 24: // STMIA
+ case 25: // LDMIA
+ *ainstr = ((tinstr & (1 << 11)) // base
+ ? 0xE8B00000 // LDMIA
+ : 0xE8A00000) // STMIA
+ |((tinstr & 0x0700) << (16 - 8)) // Rb
+ |(tinstr & 0x00FF); // mask8
+ break;
+
+ case 26: // Bcc
+ case 27: // Bcc/SWI
+ if ((tinstr & 0x0F00) == 0x0F00) {
+ // Format 17 : SWI
+ *ainstr = 0xEF000000;
+ // Breakpoint must be handled specially.
+ if ((tinstr & 0x00FF) == 0x18)
+ *ainstr |= ((tinstr & 0x00FF) << 16);
+ // New breakpoint value. See gdb/arm-tdep.c
+ else if ((tinstr & 0x00FF) == 0xFE)
+ *ainstr |= SWI_Breakpoint;
+ else
+ *ainstr |= (tinstr & 0x00FF);
+ } else if ((tinstr & 0x0F00) != 0x0E00)
+ valid = t_branch;
+ else // UNDEFINED : cc=1110(AL) uses different format
+ valid = t_undefined;
+
+ break;
+
+ case 28: // B
+ valid = t_branch;
+ break;
+
+ case 29:
+ if(tinstr & 0x1)
+ valid = t_undefined;
+ else
+ valid = t_branch;
+ break;
+
+ case 30: // BL instruction 1
+
+ // There is no single ARM instruction equivalent for this Thumb instruction. To keep the
+ // simulation simple (from the user perspective) we check if the following instruction is
+ // the second half of this BL, and if it is we simulate it immediately
+
+ valid = t_branch;
+ break;
+
+ case 31: // BL instruction 2
+
+ // There is no single ARM instruction equivalent for this instruction. Also, it should only
+ // ever be matched with the fmt19 "BL instruction 1" instruction. However, we do allow the
+ // simulation of it on its own, with undefined results if r14 is not suitably initialised.
+
+ valid = t_branch;
+ break;
+ }
+
+ *inst_size = 2;
- switch ((tinstr & 0xF800) >> 11) {
- case 0: /* LSL */
- case 1: /* LSR */
- case 2: /* ASR */
- /* Format 1 */
- *ainstr = 0xE1B00000 /* base opcode */
- | ((tinstr & 0x1800) >> (11 - 5)) /* shift type */
- |((tinstr & 0x07C0) << (7 - 6)) /* imm5 */
- |((tinstr & 0x0038) >> 3) /* Rs */
- |((tinstr & 0x0007) << 12); /* Rd */
- break;
- case 3: /* ADD/SUB */
- /* Format 2 */
- {
- ARMword subset[4] = {
- 0xE0900000, /* ADDS Rd,Rs,Rn */
- 0xE0500000, /* SUBS Rd,Rs,Rn */
- 0xE2900000, /* ADDS Rd,Rs,#imm3 */
- 0xE2500000 /* SUBS Rd,Rs,#imm3 */
- };
- /* It is quicker indexing into a table, than performing switch
- or conditionals: */
- *ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */
- |((tinstr & 0x01C0) >> 6) /* Rn or imm3 */
- |((tinstr & 0x0038) << (16 - 3)) /* Rs */
- |((tinstr & 0x0007) << (12 - 0)); /* Rd */
- }
- break;
- case 4: /* MOV */
- case 5: /* CMP */
- case 6: /* ADD */
- case 7: /* SUB */
- /* Format 3 */
- {
- ARMword subset[4] = {
- 0xE3B00000, /* MOVS Rd,#imm8 */
- 0xE3500000, /* CMP Rd,#imm8 */
- 0xE2900000, /* ADDS Rd,Rd,#imm8 */
- 0xE2500000, /* SUBS Rd,Rd,#imm8 */
- };
- *ainstr = subset[(tinstr & 0x1800) >> 11] /* base opcode */
- |((tinstr & 0x00FF) >> 0) /* imm8 */
- |((tinstr & 0x0700) << (16 - 8)) /* Rn */
- |((tinstr & 0x0700) << (12 - 8)); /* Rd */
- }
- break;
- case 8: /* Arithmetic and high register transfers */
- /* TODO: Since the subsets for both Format 4 and Format 5
- instructions are made up of different ARM encodings, we could
- save the following conditional, and just have one large
- subset. */
- if ((tinstr & (1 << 10)) == 0) {
- typedef enum
- { t_norm, t_shift, t_neg, t_mul }otype_t;
-
- /* Format 4 */
- struct
- {
- ARMword opcode;
- otype_t otype;
- }
- subset[16] = {
- {
- 0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */
- {
- 0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */
- {
- 0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */
- {
- 0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */
- {
- 0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */
- {
- 0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */
- {
- 0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */
- {
- 0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */
- {
- 0xE1100000, t_norm}, /* TST Rd,Rs */
- {
- 0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */
- {
- 0xE1500000, t_norm}, /* CMP Rd,Rs */
- {
- 0xE1700000, t_norm}, /* CMN Rd,Rs */
- {
- 0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */
- {
- 0xE0100090, t_mul}, /* MULS Rd,Rd,Rs */
- {
- 0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */
- {
- 0xE1F00000, t_norm} /* MVNS Rd,Rs */
- };
- *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
- switch (subset[(tinstr & 0x03C0) >> 6].otype) {
- case t_norm:
- *ainstr |= ((tinstr & 0x0007) << 16) /* Rn */
- |((tinstr & 0x0007) << 12) /* Rd */
- |((tinstr & 0x0038) >> 3); /* Rs */
- break;
- case t_shift:
- *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
- |((tinstr & 0x0007) >> 0) /* Rm */
- |((tinstr & 0x0038) << (8 - 3)); /* Rs */
- break;
- case t_neg:
- *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
- |((tinstr & 0x0038) << (16 - 3)); /* Rn */
- break;
- case t_mul:
- *ainstr |= ((tinstr & 0x0007) << 16) /* Rd */
- |((tinstr & 0x0007) << 8) /* Rs */
- |((tinstr & 0x0038) >> 3); /* Rm */
- break;
- }
- }
- else {
- /* Format 5 */
- ARMword Rd = ((tinstr & 0x0007) >> 0);
- ARMword Rs = ((tinstr & 0x0038) >> 3);
- if (tinstr & (1 << 7))
- Rd += 8;
- if (tinstr & (1 << 6))
- Rs += 8;
- switch ((tinstr & 0x03C0) >> 6) {
- case 0x1: /* ADD Rd,Rd,Hs */
- case 0x2: /* ADD Hd,Hd,Rs */
- case 0x3: /* ADD Hd,Hd,Hs */
- *ainstr = 0xE0800000 /* base */
- | (Rd << 16) /* Rn */
- |(Rd << 12) /* Rd */
- |(Rs << 0); /* Rm */
- break;
- case 0x5: /* CMP Rd,Hs */
- case 0x6: /* CMP Hd,Rs */
- case 0x7: /* CMP Hd,Hs */
- *ainstr = 0xE1500000 /* base */
- | (Rd << 16) /* Rn */
- |(Rd << 12) /* Rd */
- |(Rs << 0); /* Rm */
- break;
- case 0x9: /* MOV Rd,Hs */
- case 0xA: /* MOV Hd,Rs */
- case 0xB: /* MOV Hd,Hs */
- *ainstr = 0xE1A00000 /* base */
- | (Rd << 16) /* Rn */
- |(Rd << 12) /* Rd */
- |(Rs << 0); /* Rm */
- break;
- case 0xC: /* BX Rs */
- case 0xD: /* BX Hs */
- *ainstr = 0xE12FFF10 /* base */
- | ((tinstr & 0x0078) >> 3); /* Rd */
- break;
- case 0x0: /* UNDEFINED */
- case 0x4: /* UNDEFINED */
- case 0x8: /* UNDEFINED */
- valid = t_undefined;
- break;
- case 0xE: /* BLX */
- case 0xF: /* BLX */
-
- //if (state->is_v5) {
- if(1){
- //valid = t_branch;
- #if 1
- *ainstr = 0xE1200030 /* base */
- |(Rs << 0); /* Rm */
- #endif
- } else {
- valid = t_undefined;
- }
- break;
- }
- }
- break;
- case 9: /* LDR Rd,[PC,#imm8] */
- /* Format 6 */
- *ainstr = 0xE59F0000 /* base */
- | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
- |((tinstr & 0x00FF) << (2 - 0)); /* off8 */
- break;
- case 10:
- case 11:
- /* TODO: Format 7 and Format 8 perform the same ARM encoding, so
- the following could be merged into a single subset, saving on
- the following boolean: */
- if ((tinstr & (1 << 9)) == 0) {
- /* Format 7 */
- ARMword subset[4] = {
- 0xE7800000, /* STR Rd,[Rb,Ro] */
- 0xE7C00000, /* STRB Rd,[Rb,Ro] */
- 0xE7900000, /* LDR Rd,[Rb,Ro] */
- 0xE7D00000 /* LDRB Rd,[Rb,Ro] */
- };
- *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
- |((tinstr & 0x0007) << (12 - 0)) /* Rd */
- |((tinstr & 0x0038) << (16 - 3)) /* Rb */
- |((tinstr & 0x01C0) >> 6); /* Ro */
- }
- else {
- /* Format 8 */
- ARMword subset[4] = {
- 0xE18000B0, /* STRH Rd,[Rb,Ro] */
- 0xE19000D0, /* LDRSB Rd,[Rb,Ro] */
- 0xE19000B0, /* LDRH Rd,[Rb,Ro] */
- 0xE19000F0 /* LDRSH Rd,[Rb,Ro] */
- };
- *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
- |((tinstr & 0x0007) << (12 - 0)) /* Rd */
- |((tinstr & 0x0038) << (16 - 3)) /* Rb */
- |((tinstr & 0x01C0) >> 6); /* Ro */
- }
- break;
- case 12: /* STR Rd,[Rb,#imm5] */
- case 13: /* LDR Rd,[Rb,#imm5] */
- case 14: /* STRB Rd,[Rb,#imm5] */
- case 15: /* LDRB Rd,[Rb,#imm5] */
- /* Format 9 */
- {
- ARMword subset[4] = {
- 0xE5800000, /* STR Rd,[Rb,#imm5] */
- 0xE5900000, /* LDR Rd,[Rb,#imm5] */
- 0xE5C00000, /* STRB Rd,[Rb,#imm5] */
- 0xE5D00000 /* LDRB Rd,[Rb,#imm5] */
- };
- /* The offset range defends on whether we are transferring a
- byte or word value: */
- *ainstr = subset[(tinstr & 0x1800) >> 11] /* base */
- |((tinstr & 0x0007) << (12 - 0)) /* Rd */
- |((tinstr & 0x0038) << (16 - 3)) /* Rb */
- |((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */
- }
- break;
- case 16: /* STRH Rd,[Rb,#imm5] */
- case 17: /* LDRH Rd,[Rb,#imm5] */
- /* Format 10 */
- *ainstr = ((tinstr & (1 << 11)) /* base */
- ? 0xE1D000B0 /* LDRH */
- : 0xE1C000B0) /* STRH */
- |((tinstr & 0x0007) << (12 - 0)) /* Rd */
- |((tinstr & 0x0038) << (16 - 3)) /* Rb */
- |((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */
- |((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */
- break;
- case 18: /* STR Rd,[SP,#imm8] */
- case 19: /* LDR Rd,[SP,#imm8] */
- /* Format 11 */
- *ainstr = ((tinstr & (1 << 11)) /* base */
- ? 0xE59D0000 /* LDR */
- : 0xE58D0000) /* STR */
- |((tinstr & 0x0700) << (12 - 8)) /* Rd */
- |((tinstr & 0x00FF) << 2); /* off8 */
- break;
- case 20: /* ADD Rd,PC,#imm8 */
- case 21: /* ADD Rd,SP,#imm8 */
- /* Format 12 */
- if ((tinstr & (1 << 11)) == 0) {
- /* NOTE: The PC value used here should by word aligned */
- /* We encode shift-left-by-2 in the rotate immediate field,
- so no shift of off8 is needed. */
- *ainstr = 0xE28F0F00 /* base */
- | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
- |(tinstr & 0x00FF); /* off8 */
- }
- else {
- /* We encode shift-left-by-2 in the rotate immediate field,
- so no shift of off8 is needed. */
- *ainstr = 0xE28D0F00 /* base */
- | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
- |(tinstr & 0x00FF); /* off8 */
- }
- break;
- case 22:
- case 23:
- if ((tinstr & 0x0F00) == 0x0000) {
- /* Format 13 */
- /* NOTE: The instruction contains a shift left of 2
- equivalent (implemented as ROR #30): */
- *ainstr = ((tinstr & (1 << 7)) /* base */
- ? 0xE24DDF00 /* SUB */
- : 0xE28DDF00) /* ADD */
- |(tinstr & 0x007F); /* off7 */
- }
- else if ((tinstr & 0x0F00) == 0x0e00)
- *ainstr = 0xEF000000 | SWI_Breakpoint;
- else {
- /* Format 14 */
- ARMword subset[4] = {
- 0xE92D0000, /* STMDB sp!,{rlist} */
- 0xE92D4000, /* STMDB sp!,{rlist,lr} */
- 0xE8BD0000, /* LDMIA sp!,{rlist} */
- 0xE8BD8000 /* LDMIA sp!,{rlist,pc} */
- };
- *ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)] /* base */
- |(tinstr & 0x00FF); /* mask8 */
- }
- break;
- case 24: /* STMIA */
- case 25: /* LDMIA */
- /* Format 15 */
- *ainstr = ((tinstr & (1 << 11)) /* base */
- ? 0xE8B00000 /* LDMIA */
- : 0xE8A00000) /* STMIA */
- |((tinstr & 0x0700) << (16 - 8)) /* Rb */
- |(tinstr & 0x00FF); /* mask8 */
- break;
- case 26: /* Bcc */
- case 27: /* Bcc/SWI */
- if ((tinstr & 0x0F00) == 0x0F00) {
- #if 0
- if (tinstr == (ARMul_ABORTWORD & 0xffff) &&
- state->AbortAddr == pc) {
- *ainstr = ARMul_ABORTWORD;
- break;
- }
- #endif
- /* Format 17 : SWI */
- *ainstr = 0xEF000000;
- /* Breakpoint must be handled specially. */
- if ((tinstr & 0x00FF) == 0x18)
- *ainstr |= ((tinstr & 0x00FF) << 16);
- /* New breakpoint value. See gdb/arm-tdep.c */
- else if ((tinstr & 0x00FF) == 0xFE)
- *ainstr |= SWI_Breakpoint;
- else
- *ainstr |= (tinstr & 0x00FF);
- }
- else if ((tinstr & 0x0F00) != 0x0E00) {
- /* Format 16 */
- #if 0
- int doit = FALSE;
- /* TODO: Since we are doing a switch here, we could just add
- the SWI and undefined instruction checks into this
- switch to same on a couple of conditionals: */
- switch ((tinstr & 0x0F00) >> 8) {
- case EQ:
- doit = ZFLAG;
- break;
- case NE:
- doit = !ZFLAG;
- break;
- case VS:
- doit = VFLAG;
- break;
- case VC:
- doit = !VFLAG;
- break;
- case MI:
- doit = NFLAG;
- break;
- case PL:
- doit = !NFLAG;
- break;
- case CS:
- doit = CFLAG;
- break;
- case CC:
- doit = !CFLAG;
- break;
- case HI:
- doit = (CFLAG && !ZFLAG);
- break;
- case LS:
- doit = (!CFLAG || ZFLAG);
- break;
- case GE:
- doit = ((!NFLAG && !VFLAG)
- || (NFLAG && VFLAG));
- break;
- case LT:
- doit = ((NFLAG && !VFLAG)
- || (!NFLAG && VFLAG));
- break;
- case GT:
- doit = ((!NFLAG && !VFLAG && !ZFLAG)
- || (NFLAG && VFLAG && !ZFLAG));
- break;
- case LE:
- doit = ((NFLAG && !VFLAG)
- || (!NFLAG && VFLAG)) || ZFLAG;
- break;
- }
- if (doit) {
- state->Reg[15] = (pc + 4
- + (((tinstr & 0x7F) << 1)
- | ((tinstr & (1 << 7)) ?
- 0xFFFFFF00 : 0)));
- FLUSHPIPE;
- }
- #endif
- valid = t_branch;
- }
- else /* UNDEFINED : cc=1110(AL) uses different format */
- valid = t_undefined;
- break;
- case 28: /* B */
- /* Format 18 */
- #if 0
- state->Reg[15] = (pc + 4 + (((tinstr & 0x3FF) << 1)
- | ((tinstr & (1 << 10)) ?
- 0xFFFFF800 : 0)));
- #endif
- //FLUSHPIPE;
- valid = t_branch;
- break;
- case 29:
- if(tinstr & 0x1)
- valid = t_undefined;
- else{
- /* BLX 1 for armv5t and above */
- //printf("In %s, After BLX(1),LR=0x%x,PC=0x%x, offset=0x%x\n", __FUNCTION__, state->Reg[14], state->Reg[15], (tinstr &0x7FF) << 1);
- valid = t_branch;
- }
- break;
- case 30: /* BL instruction 1 */
- /* Format 19 */
- /* There is no single ARM instruction equivalent for this Thumb
- instruction. To keep the simulation simple (from the user
- perspective) we check if the following instruction is the
- second half of this BL, and if it is we simulate it
- immediately. */
- valid = t_branch;
- break;
- case 31: /* BL instruction 2 */
- /* Format 19 */
- /* There is no single ARM instruction equivalent for this
- instruction. Also, it should only ever be matched with the
- fmt19 "BL instruction 1" instruction. However, we do allow
- the simulation of it on its own, with undefined results if
- r14 is not suitably initialised. */
- {
- #if 0
- ARMword tmp = (pc + 2);
- state->Reg[15] =
- (state->Reg[14] + ((tinstr & 0x07FF) << 1));
- state->Reg[14] = (tmp | 1);
- #endif
- valid = t_branch;
- }
- break;
- }
- *inst_size = 2;
- return valid;
+ return valid;
}