diff options
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_dec.cpp | 875 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 11234 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_run.cpp | 45 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_thumb.cpp | 863 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfpinstr.cpp | 32 |
5 files changed, 5962 insertions, 7087 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 @@ | |||
| 1 | /* Copyright (C) | 1 | // Copyright 2012 Michael Kang, 2014 Citra Emulator Project |
| 2 | * 2012 - Michael.Kang blackfin.kang@gmail.com | 2 | // Licensed under GPLv2 or any later version |
| 3 | * This program is free software; you can redistribute it and/or | 3 | // Refer to the license.txt file included. |
| 4 | * modify it under the terms of the GNU General Public License | ||
| 5 | * as published by the Free Software Foundation; either version 2 | ||
| 6 | * of the License, or (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program; if not, write to the Free Software | ||
| 15 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | /** | ||
| 19 | * @file arm_dyncom_dec.cpp | ||
| 20 | * @brief Some common utility for arm decoder | ||
| 21 | * @author Michael.Kang blackfin.kang@gmail.com | ||
| 22 | * @version 7849 | ||
| 23 | * @date 2012-03-15 | ||
| 24 | */ | ||
| 25 | 4 | ||
| 26 | #include "core/arm/skyeye_common/arm_regformat.h" | 5 | #include "core/arm/skyeye_common/arm_regformat.h" |
| 27 | #include "core/arm/skyeye_common/armdefs.h" | 6 | #include "core/arm/skyeye_common/armdefs.h" |
| 28 | #include "core/arm/dyncom/arm_dyncom_dec.h" | 7 | #include "core/arm/dyncom/arm_dyncom_dec.h" |
| 29 | 8 | ||
| 30 | const ISEITEM arm_instruction[] = { | 9 | const ISEITEM arm_instruction[] = { |
| 31 | {"vmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0}, | 10 | { "vmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0 }, |
| 32 | {"vmls", 7, ARMVFP2, 28, 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0}, | 11 | { "vmls", 7, ARMVFP2, 28, 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0 }, |
| 33 | {"vnmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0}, | 12 | { "vnmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0 }, |
| 34 | {"vnmla", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0}, | 13 | { "vnmla", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }, |
| 35 | {"vnmls", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 6, 6, 0, 4, 4, 0}, | 14 | { "vnmls", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }, |
| 36 | {"vnmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0}, | 15 | { "vnmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }, |
| 37 | {"vmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 0, 4, 4, 0}, | 16 | { "vmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }, |
| 38 | {"vadd", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 0, 4, 4, 0}, | 17 | { "vadd", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }, |
| 39 | {"vsub", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 1, 4, 4, 0}, | 18 | { "vsub", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }, |
| 40 | {"vdiv", 5, ARMVFP2, 23, 27, 0x1D, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 0, 4, 4, 0}, | 19 | { "vdiv", 5, ARMVFP2, 23, 27, 0x1D, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }, |
| 41 | {"vmov(i)", 4, ARMVFP3, 23, 27, 0x1D, 20, 21, 0x3, 9, 11, 0x5, 4, 7, 0}, | 20 | { "vmov(i)", 4, ARMVFP3, 23, 27, 0x1D, 20, 21, 0x3, 9, 11, 0x5, 4, 7, 0 }, |
| 42 | {"vmov(r)", 5, ARMVFP3, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 1, 4, 4, 0}, | 21 | { "vmov(r)", 5, ARMVFP3, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 1, 4, 4, 0 }, |
| 43 | {"vabs", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 3, 4, 4, 0}, | 22 | { "vabs", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 }, |
| 44 | {"vneg", 5, ARMVFP2, 23, 27, 0x1D, 17, 21, 0x18, 9, 11, 0x5, 6, 7, 1, 4, 4, 0}, | 23 | { "vneg", 5, ARMVFP2, 23, 27, 0x1D, 17, 21, 0x18, 9, 11, 0x5, 6, 7, 1, 4, 4, 0 }, |
| 45 | {"vsqrt", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x31, 9, 11, 0x5, 6, 7, 3, 4, 4, 0}, | 24 | { "vsqrt", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x31, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 }, |
| 46 | {"vcmp", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x34, 9, 11, 0x5, 6, 6, 1, 4, 4, 0}, | 25 | { "vcmp", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x34, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }, |
| 47 | {"vcmp2", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x35, 9, 11, 0x5, 0, 6, 0x40}, | 26 | { "vcmp2", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x35, 9, 11, 0x5, 0, 6, 0x40 }, |
| 48 | {"vcvt(bds)", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x37, 9, 11, 0x5, 6, 7, 3, 4, 4, 0}, | 27 | { "vcvt(bds)", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x37, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 }, |
| 49 | {"vcvt(bff)", 6, ARMVFP3, 23, 27, 0x1D, 19, 21, 0x7, 17, 17, 0x1, 9, 11,5, 6, 6, 1}, | 28 | { "vcvt(bff)", 6, ARMVFP3, 23, 27, 0x1D, 19, 21, 0x7, 17, 17, 0x1, 9, 11, 5, 6, 6, 1 }, |
| 50 | {"vcvt(bfi)", 5, ARMVFP2, 23, 27, 0x1D, 19, 21, 0x7, 9, 11, 0x5, 6, 6, 1, 4, 4, 0}, | 29 | { "vcvt(bfi)", 5, ARMVFP2, 23, 27, 0x1D, 19, 21, 0x7, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }, |
| 51 | {"vmovbrs", 3, ARMVFP2, 21, 27, 0x70, 8, 11, 0xA, 0, 6, 0x10}, | 30 | { "vmovbrs", 3, ARMVFP2, 21, 27, 0x70, 8, 11, 0xA, 0, 6, 0x10 }, |
| 52 | {"vmsr", 2, ARMVFP2, 20, 27, 0xEE, 0, 11, 0xA10}, | 31 | { "vmsr", 2, ARMVFP2, 20, 27, 0xEE, 0, 11, 0xA10 }, |
| 53 | {"vmovbrc", 4, ARMVFP2, 23, 27, 0x1C, 20, 20, 0x0, 8, 11, 0xB, 0,4,0x10}, | 32 | { "vmovbrc", 4, ARMVFP2, 23, 27, 0x1C, 20, 20, 0x0, 8, 11, 0xB, 0, 4, 0x10 }, |
| 54 | {"vmrs", 2, ARMVFP2, 20, 27, 0xEF, 0, 11, 0xA10}, | 33 | { "vmrs", 2, ARMVFP2, 20, 27, 0xEF, 0, 11, 0xA10 }, |
| 55 | {"vmovbcr", 4, ARMVFP2, 24, 27, 0xE, 20, 20, 1, 8, 11, 0xB, 0,4,0x10}, | 34 | { "vmovbcr", 4, ARMVFP2, 24, 27, 0xE, 20, 20, 1, 8, 11, 0xB, 0, 4, 0x10 }, |
| 56 | {"vmovbrrss", 3, ARMVFP2, 21, 27, 0x62, 8, 11, 0xA, 4, 4, 1}, | 35 | { "vmovbrrss", 3, ARMVFP2, 21, 27, 0x62, 8, 11, 0xA, 4, 4, 1 }, |
| 57 | {"vmovbrrd", 3, ARMVFP2, 21, 27, 0x62, 6, 11, 0x2C, 4, 4, 1}, | 36 | { "vmovbrrd", 3, ARMVFP2, 21, 27, 0x62, 6, 11, 0x2C, 4, 4, 1 }, |
| 58 | {"vstr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 0, 9, 11,5}, | 37 | { "vstr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 0, 9, 11, 5 }, |
| 59 | {"vpush", 3, ARMVFP2, 23, 27, 0x1A, 16, 21, 0x2D, 9, 11,5}, | 38 | { "vpush", 3, ARMVFP2, 23, 27, 0x1A, 16, 21, 0x2D, 9, 11, 5 }, |
| 60 | {"vstm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 0, 9, 11,5}, | 39 | { "vstm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 0, 9, 11, 5 }, |
| 61 | {"vpop", 3, ARMVFP2, 23, 27, 0x19, 16, 21, 0x3D, 9, 11,5}, | 40 | { "vpop", 3, ARMVFP2, 23, 27, 0x19, 16, 21, 0x3D, 9, 11, 5 }, |
| 62 | {"vldr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 1, 9, 11,5}, | 41 | { "vldr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 1, 9, 11, 5 }, |
| 63 | {"vldm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 1, 9, 11,5}, | 42 | { "vldm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 1, 9, 11, 5 }, |
| 64 | 43 | ||
| 65 | {"srs" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d, 8, 11, 0x00000005}, | 44 | { "srs", 4, 6, 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d, 8, 11, 0x00000005 }, |
| 66 | {"rfe" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001, 8, 11, 0x0000000a}, | 45 | { "rfe", 4, 6, 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001, 8, 11, 0x0000000a }, |
| 67 | {"bkpt" , 2 , 3 , 20, 31, 0x00000e12, 4, 7, 0x00000007}, | 46 | { "bkpt", 2, 3, 20, 31, 0x00000e12, 4, 7, 0x00000007 }, |
| 68 | {"blx" , 1 , 3 , 25, 31, 0x0000007d}, | 47 | { "blx", 1, 3, 25, 31, 0x0000007d }, |
| 69 | {"cps" , 3 , 6 , 20, 31, 0x00000f10, 16, 16, 0x00000000, 5, 5, 0x00000000}, | 48 | { "cps", 3, 6, 20, 31, 0x00000f10, 16, 16, 0x00000000, 5, 5, 0x00000000 }, |
| 70 | {"pld" , 4 , 4 , 26, 31, 0x0000003d, 24, 24, 0x00000001, 20, 22, 0x00000005, 12, 15, 0x0000000f}, | 49 | { "pld", 4, 4, 26, 31, 0x0000003d, 24, 24, 0x00000001, 20, 22, 0x00000005, 12, 15, 0x0000000f }, |
| 71 | {"setend" , 2 , 6 , 16, 31, 0x0000f101, 4, 7, 0x00000000}, | 50 | { "setend", 2, 6, 16, 31, 0x0000f101, 4, 7, 0x00000000 }, |
| 72 | {"clrex" , 1 , 6 , 0, 31, 0xf57ff01f}, | 51 | { "clrex", 1, 6, 0, 31, 0xf57ff01f }, |
| 73 | {"rev16" , 2 , 6 , 16, 27, 0x000006bf, 4, 11, 0x000000fb}, | 52 | { "rev16", 2, 6, 16, 27, 0x000006bf, 4, 11, 0x000000fb }, |
| 74 | {"usad8" , 3 , 6 , 20, 27, 0x00000078, 12, 15, 0x0000000f, 4, 7, 0x00000001}, | 53 | { "usad8", 3, 6, 20, 27, 0x00000078, 12, 15, 0x0000000f, 4, 7, 0x00000001 }, |
| 75 | {"sxtb" , 2 , 6 , 16, 27, 0x000006af, 4, 7, 0x00000007}, | 54 | { "sxtb", 2, 6, 16, 27, 0x000006af, 4, 7, 0x00000007 }, |
| 76 | {"uxtb" , 2 , 6 , 16, 27, 0x000006ef, 4, 7, 0x00000007}, | 55 | { "uxtb", 2, 6, 16, 27, 0x000006ef, 4, 7, 0x00000007 }, |
| 77 | {"sxth" , 2 , 6 , 16, 27, 0x000006bf, 4, 7, 0x00000007}, | 56 | { "sxth", 2, 6, 16, 27, 0x000006bf, 4, 7, 0x00000007 }, |
| 78 | {"sxtb16" , 2 , 6 , 16, 27, 0x0000068f, 4, 7, 0x00000007}, | 57 | { "sxtb16", 2, 6, 16, 27, 0x0000068f, 4, 7, 0x00000007 }, |
| 79 | {"uxth" , 2 , 6 , 16, 27, 0x000006ff, 4, 7, 0x00000007}, | 58 | { "uxth", 2, 6, 16, 27, 0x000006ff, 4, 7, 0x00000007 }, |
| 80 | {"uxtb16" , 2 , 6 , 16, 27, 0x000006cf, 4, 7, 0x00000007}, | 59 | { "uxtb16", 2, 6, 16, 27, 0x000006cf, 4, 7, 0x00000007 }, |
| 81 | {"cpy" , 2 , 6 , 20, 27, 0x0000001a, 4, 11, 0x00000000}, | 60 | { "cpy", 2, 6, 20, 27, 0x0000001a, 4, 11, 0x00000000 }, |
| 82 | {"uxtab" , 2 , 6 , 20, 27, 0x0000006e, 4, 9, 0x00000007}, | 61 | { "uxtab", 2, 6, 20, 27, 0x0000006e, 4, 9, 0x00000007 }, |
| 83 | {"ssub8" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x0000000f}, | 62 | { "ssub8", 2, 6, 20, 27, 0x00000061, 4, 7, 0x0000000f }, |
| 84 | {"shsub8" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x0000000f}, | 63 | { "shsub8", 2, 6, 20, 27, 0x00000063, 4, 7, 0x0000000f }, |
| 85 | {"ssubaddx" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000005}, | 64 | { "ssubaddx", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000005 }, |
| 86 | {"strex" , 2 , 6 , 20, 27, 0x00000018, 4, 7, 0x00000009}, | 65 | { "strex", 2, 6, 20, 27, 0x00000018, 4, 7, 0x00000009 }, |
| 87 | {"strexb" , 2 , 7 , 20, 27, 0x0000001c, 4, 7, 0x00000009}, | 66 | { "strexb", 2, 7, 20, 27, 0x0000001c, 4, 7, 0x00000009 }, |
| 88 | {"swp" , 2 , 0 , 20, 27, 0x00000010, 4, 7, 0x00000009}, | 67 | { "swp", 2, 0, 20, 27, 0x00000010, 4, 7, 0x00000009 }, |
| 89 | {"swpb" , 2 , 0 , 20, 27, 0x00000014, 4, 7, 0x00000009}, | 68 | { "swpb", 2, 0, 20, 27, 0x00000014, 4, 7, 0x00000009 }, |
| 90 | {"ssub16" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000007}, | 69 | { "ssub16", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000007 }, |
| 91 | {"ssat16" , 2 , 6 , 20, 27, 0x0000006a, 4, 7, 0x00000003}, | 70 | { "ssat16", 2, 6, 20, 27, 0x0000006a, 4, 7, 0x00000003 }, |
| 92 | {"shsubaddx" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000005}, | 71 | { "shsubaddx", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000005 }, |
| 93 | {"qsubaddx" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000005}, | 72 | { "qsubaddx", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000005 }, |
| 94 | {"shaddsubx" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000003}, | 73 | { "shaddsubx", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000003 }, |
| 95 | {"shadd8" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000009}, | 74 | { "shadd8", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000009 }, |
| 96 | {"shadd16" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000001}, | 75 | { "shadd16", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000001 }, |
| 97 | {"sel" , 2 , 6 , 20, 27, 0x00000068, 4, 7, 0x0000000b}, | 76 | { "sel", 2, 6, 20, 27, 0x00000068, 4, 7, 0x0000000b }, |
| 98 | {"saddsubx" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000003}, | 77 | { "saddsubx", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000003 }, |
| 99 | {"sadd8" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000009}, | 78 | { "sadd8", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000009 }, |
| 100 | {"sadd16" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000001}, | 79 | { "sadd16", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000001 }, |
| 101 | {"shsub16" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000007}, | 80 | { "shsub16", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000007 }, |
| 102 | {"umaal" , 2 , 6 , 20, 27, 0x00000004, 4, 7, 0x00000009}, | 81 | { "umaal", 2, 6, 20, 27, 0x00000004, 4, 7, 0x00000009 }, |
| 103 | {"uxtab16" , 2 , 6 , 20, 27, 0x0000006c, 4, 7, 0x00000007}, | 82 | { "uxtab16", 2, 6, 20, 27, 0x0000006c, 4, 7, 0x00000007 }, |
| 104 | {"usubaddx" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000005}, | 83 | { "usubaddx", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000005 }, |
| 105 | {"usub8" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x0000000f}, | 84 | { "usub8", 2, 6, 20, 27, 0x00000065, 4, 7, 0x0000000f }, |
| 106 | {"usub16" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000007}, | 85 | { "usub16", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000007 }, |
| 107 | {"usat16" , 2 , 6 , 20, 27, 0x0000006e, 4, 7, 0x00000003}, | 86 | { "usat16", 2, 6, 20, 27, 0x0000006e, 4, 7, 0x00000003 }, |
| 108 | {"usada8" , 2 , 6 , 20, 27, 0x00000078, 4, 7, 0x00000001}, | 87 | { "usada8", 2, 6, 20, 27, 0x00000078, 4, 7, 0x00000001 }, |
| 109 | {"uqsubaddx" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000005}, | 88 | { "uqsubaddx", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000005 }, |
| 110 | {"uqsub8" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x0000000f}, | 89 | { "uqsub8", 2, 6, 20, 27, 0x00000066, 4, 7, 0x0000000f }, |
| 111 | {"uqsub16" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000007}, | 90 | { "uqsub16", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000007 }, |
| 112 | {"uqaddsubx" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000003}, | 91 | { "uqaddsubx", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000003 }, |
| 113 | {"uqadd8" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000009}, | 92 | { "uqadd8", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000009 }, |
| 114 | {"uqadd16" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000001}, | 93 | { "uqadd16", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000001 }, |
| 115 | {"sxtab" , 2 , 6 , 20, 27, 0x0000006a, 4, 7, 0x00000007}, | 94 | { "sxtab", 2, 6, 20, 27, 0x0000006a, 4, 7, 0x00000007 }, |
| 116 | {"uhsubaddx" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000005}, | 95 | { "uhsubaddx", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000005 }, |
| 117 | {"uhsub8" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x0000000f}, | 96 | { "uhsub8", 2, 6, 20, 27, 0x00000067, 4, 7, 0x0000000f }, |
| 118 | {"uhsub16" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000007}, | 97 | { "uhsub16", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000007 }, |
| 119 | {"uhaddsubx" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000003}, | 98 | { "uhaddsubx", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000003 }, |
| 120 | {"uhadd8" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000009}, | 99 | { "uhadd8", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000009 }, |
| 121 | {"uhadd16" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000001}, | 100 | { "uhadd16", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000001 }, |
| 122 | {"uaddsubx" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000003}, | 101 | { "uaddsubx", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000003 }, |
| 123 | {"uadd8" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000009}, | 102 | { "uadd8", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000009 }, |
| 124 | {"uadd16" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000001}, | 103 | { "uadd16", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000001 }, |
| 125 | {"sxtah" , 2 , 6 , 20, 27, 0x0000006b, 4, 7, 0x00000007}, | 104 | { "sxtah", 2, 6, 20, 27, 0x0000006b, 4, 7, 0x00000007 }, |
| 126 | {"sxtab16" , 2 , 6 , 20, 27, 0x00000068, 4, 7, 0x00000007}, | 105 | { "sxtab16", 2, 6, 20, 27, 0x00000068, 4, 7, 0x00000007 }, |
| 127 | {"qadd8" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000009}, | 106 | { "qadd8", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000009 }, |
| 128 | {"bxj" , 2 , 5 , 20, 27, 0x00000012, 4, 7, 0x00000002}, | 107 | { "bxj", 2, 5, 20, 27, 0x00000012, 4, 7, 0x00000002 }, |
| 129 | {"clz" , 2 , 3 , 20, 27, 0x00000016, 4, 7, 0x00000001}, | 108 | { "clz", 2, 3, 20, 27, 0x00000016, 4, 7, 0x00000001 }, |
| 130 | {"uxtah" , 2 , 6 , 20, 27, 0x0000006f, 4, 7, 0x00000007}, | 109 | { "uxtah", 2, 6, 20, 27, 0x0000006f, 4, 7, 0x00000007 }, |
| 131 | {"bx" , 2 , 2 , 20, 27, 0x00000012, 4, 7, 0x00000001}, | 110 | { "bx", 2, 2, 20, 27, 0x00000012, 4, 7, 0x00000001 }, |
| 132 | {"rev" , 2 , 6 , 20, 27, 0x0000006b, 4, 7, 0x00000003}, | 111 | { "rev", 2, 6, 20, 27, 0x0000006b, 4, 7, 0x00000003 }, |
| 133 | {"blx" , 2 , 3 , 20, 27, 0x00000012, 4, 7, 0x00000003}, | 112 | { "blx", 2, 3, 20, 27, 0x00000012, 4, 7, 0x00000003 }, |
| 134 | {"revsh" , 2 , 6 , 20, 27, 0x0000006f, 4, 7, 0x0000000b}, | 113 | { "revsh", 2, 6, 20, 27, 0x0000006f, 4, 7, 0x0000000b }, |
| 135 | {"qadd" , 2 , 4 , 20, 27, 0x00000010, 4, 7, 0x00000005}, | 114 | { "qadd", 2, 4, 20, 27, 0x00000010, 4, 7, 0x00000005 }, |
| 136 | {"qadd16" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000001}, | 115 | { "qadd16", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000001 }, |
| 137 | {"qaddsubx" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000003}, | 116 | { "qaddsubx", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000003 }, |
| 138 | {"ldrex" , 2 , 0 , 20, 27, 0x00000019, 4, 7, 0x00000009}, | 117 | { "ldrex", 2, 0, 20, 27, 0x00000019, 4, 7, 0x00000009 }, |
| 139 | {"qdadd" , 2 , 4 , 20, 27, 0x00000014, 4, 7, 0x00000005}, | 118 | { "qdadd", 2, 4, 20, 27, 0x00000014, 4, 7, 0x00000005 }, |
| 140 | {"qdsub" , 2 , 4 , 20, 27, 0x00000016, 4, 7, 0x00000005}, | 119 | { "qdsub", 2, 4, 20, 27, 0x00000016, 4, 7, 0x00000005 }, |
| 141 | {"qsub" , 2 , 4 , 20, 27, 0x00000012, 4, 7, 0x00000005}, | 120 | { "qsub", 2, 4, 20, 27, 0x00000012, 4, 7, 0x00000005 }, |
| 142 | {"ldrexb" , 2 , 7 , 20, 27, 0x0000001d, 4, 7, 0x00000009}, | 121 | { "ldrexb", 2, 7, 20, 27, 0x0000001d, 4, 7, 0x00000009 }, |
| 143 | {"qsub8" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x0000000f}, | 122 | { "qsub8", 2, 6, 20, 27, 0x00000062, 4, 7, 0x0000000f }, |
| 144 | {"qsub16" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000007}, | 123 | { "qsub16", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000007 }, |
| 145 | {"smuad" , 4 , 6 , 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001}, | 124 | { "smuad", 4, 6, 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001 }, |
| 146 | {"smmul" , 4 , 6 , 20, 27, 0x00000075, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001}, | 125 | { "smmul", 4, 6, 20, 27, 0x00000075, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001 }, |
| 147 | {"smusd" , 4 , 6 , 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000001, 4, 4, 0x00000001}, | 126 | { "smusd", 4, 6, 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000001, 4, 4, 0x00000001 }, |
| 148 | {"smlsd" , 3 , 6 , 20, 27, 0x00000070, 6, 7, 0x00000001, 4, 4, 0x00000001}, | 127 | { "smlsd", 3, 6, 20, 27, 0x00000070, 6, 7, 0x00000001, 4, 4, 0x00000001 }, |
| 149 | {"smlsld" , 3 , 6 , 20, 27, 0x00000074, 6, 7, 0x00000001, 4, 4, 0x00000001}, | 128 | { "smlsld", 3, 6, 20, 27, 0x00000074, 6, 7, 0x00000001, 4, 4, 0x00000001 }, |
| 150 | {"smmla" , 3 , 6 , 20, 27, 0x00000075, 6, 7, 0x00000000, 4, 4, 0x00000001}, | 129 | { "smmla", 3, 6, 20, 27, 0x00000075, 6, 7, 0x00000000, 4, 4, 0x00000001 }, |
| 151 | {"smmls" , 3 , 6 , 20, 27, 0x00000075, 6, 7, 0x00000003, 4, 4, 0x00000001}, | 130 | { "smmls", 3, 6, 20, 27, 0x00000075, 6, 7, 0x00000003, 4, 4, 0x00000001 }, |
| 152 | {"smlald" , 3 , 6 , 20, 27, 0x00000074, 6, 7, 0x00000000, 4, 4, 0x00000001}, | 131 | { "smlald", 3, 6, 20, 27, 0x00000074, 6, 7, 0x00000000, 4, 4, 0x00000001 }, |
| 153 | {"smlad" , 3 , 6 , 20, 27, 0x00000070, 6, 7, 0x00000000, 4, 4, 0x00000001}, | 132 | { "smlad", 3, 6, 20, 27, 0x00000070, 6, 7, 0x00000000, 4, 4, 0x00000001 }, |
| 154 | {"smlaw" , 3 , 4 , 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000000}, | 133 | { "smlaw", 3, 4, 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000000 }, |
| 155 | {"smulw" , 3 , 4 , 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000002}, | 134 | { "smulw", 3, 4, 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000002 }, |
| 156 | {"pkhtb" , 2 , 6 , 20, 27, 0x00000068, 4, 6, 0x00000005}, | 135 | { "pkhtb", 2, 6, 20, 27, 0x00000068, 4, 6, 0x00000005 }, |
| 157 | {"pkhbt" , 2 , 6 , 20, 27, 0x00000068, 4, 6, 0x00000001}, | 136 | { "pkhbt", 2, 6, 20, 27, 0x00000068, 4, 6, 0x00000001 }, |
| 158 | {"smul" , 3 , 4 , 20, 27, 0x00000016, 7, 7, 0x00000001, 4, 4, 0x00000000}, | 137 | { "smul", 3, 4, 20, 27, 0x00000016, 7, 7, 0x00000001, 4, 4, 0x00000000 }, |
| 159 | {"smlalxy" , 3 , 4 , 20, 27, 0x00000014, 7, 7, 0x00000001, 4, 4, 0x00000000}, | 138 | { "smlalxy", 3, 4, 20, 27, 0x00000014, 7, 7, 0x00000001, 4, 4, 0x00000000 }, |
| 160 | // {"smlal" , 2 , 4 , 21, 27, 0x00000007, 4, 7, 0x00000009}, | 139 | // {"smlal" , 2 , 4 , 21, 27, 0x00000007, 4, 7, 0x00000009}, |
| 161 | {"smla" , 3 , 4 , 20, 27, 0x00000010, 7, 7, 0x00000001, 4, 4, 0x00000000}, | 140 | { "smla", 3, 4, 20, 27, 0x00000010, 7, 7, 0x00000001, 4, 4, 0x00000000 }, |
| 162 | {"mcrr" , 1 , 6 , 20, 27, 0x000000c4}, | 141 | { "mcrr", 1, 6, 20, 27, 0x000000c4 }, |
| 163 | {"mrrc" , 1 , 6 , 20, 27, 0x000000c5}, | 142 | { "mrrc", 1, 6, 20, 27, 0x000000c5 }, |
| 164 | {"cmp" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000015}, | 143 | { "cmp", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000015 }, |
| 165 | {"tst" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000011}, | 144 | { "tst", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000011 }, |
| 166 | {"teq" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000013}, | 145 | { "teq", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000013 }, |
| 167 | {"cmn" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000017}, | 146 | { "cmn", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000017 }, |
| 168 | {"smull" , 2 , 0 , 21, 27, 0x00000006, 4, 7, 0x00000009}, | 147 | { "smull", 2, 0, 21, 27, 0x00000006, 4, 7, 0x00000009 }, |
| 169 | {"umull" , 2 , 0 , 21, 27, 0x00000004, 4, 7, 0x00000009}, | 148 | { "umull", 2, 0, 21, 27, 0x00000004, 4, 7, 0x00000009 }, |
| 170 | {"umlal" , 2 , 0 , 21, 27, 0x00000005, 4, 7, 0x00000009}, | 149 | { "umlal", 2, 0, 21, 27, 0x00000005, 4, 7, 0x00000009 }, |
| 171 | {"smlal" , 2 , 0 , 21, 27, 0x00000007, 4, 7, 0x00000009}, | 150 | { "smlal", 2, 0, 21, 27, 0x00000007, 4, 7, 0x00000009 }, |
| 172 | {"mul" , 2 , 0 , 21, 27, 0x00000000, 4, 7, 0x00000009}, | 151 | { "mul", 2, 0, 21, 27, 0x00000000, 4, 7, 0x00000009 }, |
| 173 | {"mla" , 2 , 0 , 21, 27, 0x00000001, 4, 7, 0x00000009}, | 152 | { "mla", 2, 0, 21, 27, 0x00000001, 4, 7, 0x00000009 }, |
| 174 | {"ssat" , 2 , 6 , 21, 27, 0x00000035, 4, 5, 0x00000001}, | 153 | { "ssat", 2, 6, 21, 27, 0x00000035, 4, 5, 0x00000001 }, |
| 175 | {"usat" , 2 , 6 , 21, 27, 0x00000037, 4, 5, 0x00000001}, | 154 | { "usat", 2, 6, 21, 27, 0x00000037, 4, 5, 0x00000001 }, |
| 176 | {"mrs" , 4 , 0 , 23, 27, 0x00000002, 20, 21, 0x00000000, 16, 19, 0x0000000f, 0, 11, 0x00000000}, | 155 | { "mrs", 4, 0, 23, 27, 0x00000002, 20, 21, 0x00000000, 16, 19, 0x0000000f, 0, 11, 0x00000000 }, |
| 177 | {"msr" , 3 , 0 , 23, 27, 0x00000002, 20, 21, 0x00000002, 4, 7, 0x00000000}, | 156 | { "msr", 3, 0, 23, 27, 0x00000002, 20, 21, 0x00000002, 4, 7, 0x00000000 }, |
| 178 | {"and" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000000}, | 157 | { "and", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000000 }, |
| 179 | {"bic" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000e}, | 158 | { "bic", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000e }, |
| 180 | {"ldm" , 3 , 0 , 25, 27, 0x00000004, 20, 22, 0x00000005, 15, 15, 0x00000000}, | 159 | { "ldm", 3, 0, 25, 27, 0x00000004, 20, 22, 0x00000005, 15, 15, 0x00000000 }, |
| 181 | {"eor" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000001}, | 160 | { "eor", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000001 }, |
| 182 | {"add" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000004}, | 161 | { "add", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000004 }, |
| 183 | {"rsb" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000003}, | 162 | { "rsb", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000003 }, |
| 184 | {"rsc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000007}, | 163 | { "rsc", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000007 }, |
| 185 | {"sbc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000006}, | 164 | { "sbc", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000006 }, |
| 186 | {"adc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000005}, | 165 | { "adc", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000005 }, |
| 187 | {"sub" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000002}, | 166 | { "sub", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000002 }, |
| 188 | {"orr" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000c}, | 167 | { "orr", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000c }, |
| 189 | {"mvn" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000f}, | 168 | { "mvn", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000f }, |
| 190 | {"mov" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000d}, | 169 | { "mov", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000d }, |
| 191 | {"stm" , 2 , 0 , 25, 27, 0x00000004, 20, 22, 0x00000004}, | 170 | { "stm", 2, 0, 25, 27, 0x00000004, 20, 22, 0x00000004 }, |
| 192 | {"ldm" , 4 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000001, 20, 20, 0x00000001, 15, 15, 0x00000001}, | 171 | { "ldm", 4, 0, 25, 27, 0x00000004, 22, 22, 0x00000001, 20, 20, 0x00000001, 15, 15, 0x00000001 }, |
| 193 | {"ldrsh" , 3 , 2 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000f}, | 172 | { "ldrsh", 3, 2, 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000f }, |
| 194 | {"stm" , 3 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000000}, | 173 | { "stm", 3, 0, 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000000 }, |
| 195 | {"ldm" , 3 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000001}, | 174 | { "ldm", 3, 0, 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000001 }, |
| 196 | {"ldrsb" , 3 , 2 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000d}, | 175 | { "ldrsb", 3, 2, 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000d }, |
| 197 | {"strd" , 3 , 4 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000f}, | 176 | { "strd", 3, 4, 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000f }, |
| 198 | {"ldrh" , 3 , 0 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000b}, | 177 | { "ldrh", 3, 0, 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000b }, |
| 199 | {"strh" , 3 , 0 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000b}, | 178 | { "strh", 3, 0, 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000b }, |
| 200 | {"ldrd" , 3 , 4 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000d}, | 179 | { "ldrd", 3, 4, 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000d }, |
| 201 | {"strt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000002}, | 180 | { "strt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000002 }, |
| 202 | {"strbt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000006}, | 181 | { "strbt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000006 }, |
| 203 | {"ldrbt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000007}, | 182 | { "ldrbt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000007 }, |
| 204 | {"ldrt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000003}, | 183 | { "ldrt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000003 }, |
| 205 | {"mrc" , 3 , 6 , 24, 27, 0x0000000e, 20, 20, 0x00000001, 4, 4, 0x00000001}, | 184 | { "mrc", 3, 6, 24, 27, 0x0000000e, 20, 20, 0x00000001, 4, 4, 0x00000001 }, |
| 206 | {"mcr" , 3 , 0 , 24, 27, 0x0000000e, 20, 20, 0x00000000, 4, 4, 0x00000001}, | 185 | { "mcr", 3, 0, 24, 27, 0x0000000e, 20, 20, 0x00000000, 4, 4, 0x00000001 }, |
| 207 | {"msr" , 2 , 0 , 23, 27, 0x00000006, 20, 21, 0x00000002}, | 186 | { "msr", 2, 0, 23, 27, 0x00000006, 20, 21, 0x00000002 }, |
| 208 | {"ldrb" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000001}, | 187 | { "ldrb", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000001 }, |
| 209 | {"strb" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000000}, | 188 | { "strb", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000000 }, |
| 210 | {"ldr" , 4 , 0 , 28, 31, 0x0000000e, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001}, | 189 | { "ldr", 4, 0, 28, 31, 0x0000000e, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001 }, |
| 211 | {"ldrcond" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001}, | 190 | { "ldrcond", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001 }, |
| 212 | {"str" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000000}, | 191 | { "str", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000000 }, |
| 213 | {"cdp" , 2 , 0 , 24, 27, 0x0000000e, 4, 4, 0x00000000}, | 192 | { "cdp", 2, 0, 24, 27, 0x0000000e, 4, 4, 0x00000000 }, |
| 214 | {"stc" , 2 , 0 , 25, 27, 0x00000006, 20, 20, 0x00000000}, | 193 | { "stc", 2, 0, 25, 27, 0x00000006, 20, 20, 0x00000000 }, |
| 215 | {"ldc" , 2 , 0 , 25, 27, 0x00000006, 20, 20, 0x00000001}, | 194 | { "ldc", 2, 0, 25, 27, 0x00000006, 20, 20, 0x00000001 }, |
| 216 | {"swi" , 1 , 0 , 24, 27, 0x0000000f}, | 195 | { "swi", 1, 0, 24, 27, 0x0000000f }, |
| 217 | {"bbl" , 1 , 0 , 25, 27, 0x00000005}, | 196 | { "bbl", 1, 0, 25, 27, 0x00000005 }, |
| 218 | }; | 197 | }; |
| 219 | 198 | ||
| 220 | const ISEITEM arm_exclusion_code[] = { | 199 | const ISEITEM arm_exclusion_code[] = { |
| 221 | {"vmla", 0, ARMVFP2, 0}, | 200 | { "vmla", 0, ARMVFP2, 0 }, |
| 222 | {"vmls", 0, ARMVFP2, 0}, | 201 | { "vmls", 0, ARMVFP2, 0 }, |
| 223 | {"vnmla", 0, ARMVFP2, 0}, | 202 | { "vnmla", 0, ARMVFP2, 0 }, |
| 224 | {"vnmla", 0, ARMVFP2, 0}, | 203 | { "vnmla", 0, ARMVFP2, 0 }, |
| 225 | {"vnmls", 0, ARMVFP2, 0}, | 204 | { "vnmls", 0, ARMVFP2, 0 }, |
| 226 | {"vnmul", 0, ARMVFP2, 0}, | 205 | { "vnmul", 0, ARMVFP2, 0 }, |
| 227 | {"vmul", 0, ARMVFP2, 0}, | 206 | { "vmul", 0, ARMVFP2, 0 }, |
| 228 | {"vadd", 0, ARMVFP2, 0}, | 207 | { "vadd", 0, ARMVFP2, 0 }, |
| 229 | {"vsub", 0, ARMVFP2, 0}, | 208 | { "vsub", 0, ARMVFP2, 0 }, |
| 230 | {"vdiv", 0, ARMVFP2, 0}, | 209 | { "vdiv", 0, ARMVFP2, 0 }, |
| 231 | {"vmov(i)", 0, ARMVFP3, 0}, | 210 | { "vmov(i)", 0, ARMVFP3, 0 }, |
| 232 | {"vmov(r)", 0, ARMVFP3, 0}, | 211 | { "vmov(r)", 0, ARMVFP3, 0 }, |
| 233 | {"vabs", 0, ARMVFP2, 0}, | 212 | { "vabs", 0, ARMVFP2, 0 }, |
| 234 | {"vneg", 0, ARMVFP2, 0}, | 213 | { "vneg", 0, ARMVFP2, 0 }, |
| 235 | {"vsqrt", 0, ARMVFP2, 0}, | 214 | { "vsqrt", 0, ARMVFP2, 0 }, |
| 236 | {"vcmp", 0, ARMVFP2, 0}, | 215 | { "vcmp", 0, ARMVFP2, 0 }, |
| 237 | {"vcmp2", 0, ARMVFP2, 0}, | 216 | { "vcmp2", 0, ARMVFP2, 0 }, |
| 238 | {"vcvt(bff)", 0, ARMVFP3, 4, 4, 1}, | 217 | { "vcvt(bff)", 0, ARMVFP3, 4, 4, 1 }, |
| 239 | {"vcvt(bds)", 0, ARMVFP2, 0}, | 218 | { "vcvt(bds)", 0, ARMVFP2, 0 }, |
| 240 | {"vcvt(bfi)", 0, ARMVFP2, 0}, | 219 | { "vcvt(bfi)", 0, ARMVFP2, 0 }, |
| 241 | {"vmovbrs", 0, ARMVFP2, 0}, | 220 | { "vmovbrs", 0, ARMVFP2, 0 }, |
| 242 | {"vmsr", 0, ARMVFP2, 0}, | 221 | { "vmsr", 0, ARMVFP2, 0 }, |
| 243 | {"vmovbrc", 0, ARMVFP2, 0}, | 222 | { "vmovbrc", 0, ARMVFP2, 0 }, |
| 244 | {"vmrs", 0, ARMVFP2, 0}, | 223 | { "vmrs", 0, ARMVFP2, 0 }, |
| 245 | {"vmovbcr", 0, ARMVFP2, 0}, | 224 | { "vmovbcr", 0, ARMVFP2, 0 }, |
| 246 | {"vmovbrrss", 0, ARMVFP2, 0}, | 225 | { "vmovbrrss", 0, ARMVFP2, 0 }, |
| 247 | {"vmovbrrd", 0, ARMVFP2, 0}, | 226 | { "vmovbrrd", 0, ARMVFP2, 0 }, |
| 248 | {"vstr", 0, ARMVFP2, 0}, | 227 | { "vstr", 0, ARMVFP2, 0 }, |
| 249 | {"vpush", 0, ARMVFP2, 0}, | 228 | { "vpush", 0, ARMVFP2, 0 }, |
| 250 | {"vstm", 0, ARMVFP2, 0}, | 229 | { "vstm", 0, ARMVFP2, 0 }, |
| 251 | {"vpop", 0, ARMVFP2, 0}, | 230 | { "vpop", 0, ARMVFP2, 0 }, |
| 252 | {"vldr", 0, ARMVFP2, 0}, | 231 | { "vldr", 0, ARMVFP2, 0 }, |
| 253 | {"vldm", 0, ARMVFP2, 0}, | 232 | { "vldm", 0, ARMVFP2, 0 }, |
| 254 | 233 | ||
| 255 | {"srs" , 0 , 6 , 0}, | 234 | { "srs", 0, 6, 0 }, |
| 256 | {"rfe" , 0 , 6 , 0}, | 235 | { "rfe", 0, 6, 0 }, |
| 257 | {"bkpt" , 0 , 3 , 0}, | 236 | { "bkpt", 0, 3, 0 }, |
| 258 | {"blx" , 0 , 3 , 0}, | 237 | { "blx", 0, 3, 0 }, |
| 259 | {"cps" , 0 , 6 , 0}, | 238 | { "cps", 0, 6, 0 }, |
| 260 | {"pld" , 0 , 4 , 0}, | 239 | { "pld", 0, 4, 0 }, |
| 261 | {"setend" , 0 , 6 , 0}, | 240 | { "setend", 0, 6, 0 }, |
| 262 | {"clrex" , 0 , 6 , 0}, | 241 | { "clrex", 0, 6, 0 }, |
| 263 | {"rev16" , 0 , 6 , 0}, | 242 | { "rev16", 0, 6, 0 }, |
| 264 | {"usad8" , 0 , 6 , 0}, | 243 | { "usad8", 0, 6, 0 }, |
| 265 | {"sxtb" , 0 , 6 , 0}, | 244 | { "sxtb", 0, 6, 0 }, |
| 266 | {"uxtb" , 0 , 6 , 0}, | 245 | { "uxtb", 0, 6, 0 }, |
| 267 | {"sxth" , 0 , 6 , 0}, | 246 | { "sxth", 0, 6, 0 }, |
| 268 | {"sxtb16" , 0 , 6 , 0}, | 247 | { "sxtb16", 0, 6, 0 }, |
| 269 | {"uxth" , 0 , 6 , 0}, | 248 | { "uxth", 0, 6, 0 }, |
| 270 | {"uxtb16" , 0 , 6 , 0}, | 249 | { "uxtb16", 0, 6, 0 }, |
| 271 | {"cpy" , 0 , 6 , 0}, | 250 | { "cpy", 0, 6, 0 }, |
| 272 | {"uxtab" , 0 , 6 , 0}, | 251 | { "uxtab", 0, 6, 0 }, |
| 273 | {"ssub8" , 0 , 6 , 0}, | 252 | { "ssub8", 0, 6, 0 }, |
| 274 | {"shsub8" , 0 , 6 , 0}, | 253 | { "shsub8", 0, 6, 0 }, |
| 275 | {"ssubaddx" , 0 , 6 , 0}, | 254 | { "ssubaddx", 0, 6, 0 }, |
| 276 | {"strex" , 0 , 6 , 0}, | 255 | { "strex", 0, 6, 0 }, |
| 277 | {"strexb" , 0 , 7 , 0}, | 256 | { "strexb", 0, 7, 0 }, |
| 278 | {"swp" , 0 , 0 , 0}, | 257 | { "swp", 0, 0, 0 }, |
| 279 | {"swpb" , 0 , 0 , 0}, | 258 | { "swpb", 0, 0, 0 }, |
| 280 | {"ssub16" , 0 , 6 , 0}, | 259 | { "ssub16", 0, 6, 0 }, |
| 281 | {"ssat16" , 0 , 6 , 0}, | 260 | { "ssat16", 0, 6, 0 }, |
| 282 | {"shsubaddx" , 0 , 6 , 0}, | 261 | { "shsubaddx", 0, 6, 0 }, |
| 283 | {"qsubaddx" , 0 , 6 , 0}, | 262 | { "qsubaddx", 0, 6, 0 }, |
| 284 | {"shaddsubx" , 0 , 6 , 0}, | 263 | { "shaddsubx", 0, 6, 0 }, |
| 285 | {"shadd8" , 0 , 6 , 0}, | 264 | { "shadd8", 0, 6, 0 }, |
| 286 | {"shadd16" , 0 , 6 , 0}, | 265 | { "shadd16", 0, 6, 0 }, |
| 287 | {"sel" , 0 , 6 , 0}, | 266 | { "sel", 0, 6, 0 }, |
| 288 | {"saddsubx" , 0 , 6 , 0}, | 267 | { "saddsubx", 0, 6, 0 }, |
| 289 | {"sadd8" , 0 , 6 , 0}, | 268 | { "sadd8", 0, 6, 0 }, |
| 290 | {"sadd16" , 0 , 6 , 0}, | 269 | { "sadd16", 0, 6, 0 }, |
| 291 | {"shsub16" , 0 , 6 , 0}, | 270 | { "shsub16", 0, 6, 0 }, |
| 292 | {"umaal" , 0 , 6 , 0}, | 271 | { "umaal", 0, 6, 0 }, |
| 293 | {"uxtab16" , 0 , 6 , 0}, | 272 | { "uxtab16", 0, 6, 0 }, |
| 294 | {"usubaddx" , 0 , 6 , 0}, | 273 | { "usubaddx", 0, 6, 0 }, |
| 295 | {"usub8" , 0 , 6 , 0}, | 274 | { "usub8", 0, 6, 0 }, |
| 296 | {"usub16" , 0 , 6 , 0}, | 275 | { "usub16", 0, 6, 0 }, |
| 297 | {"usat16" , 0 , 6 , 0}, | 276 | { "usat16", 0, 6, 0 }, |
| 298 | {"usada8" , 0 , 6 , 0}, | 277 | { "usada8", 0, 6, 0 }, |
| 299 | {"uqsubaddx" , 0 , 6 , 0}, | 278 | { "uqsubaddx", 0, 6, 0 }, |
| 300 | {"uqsub8" , 0 , 6 , 0}, | 279 | { "uqsub8", 0, 6, 0 }, |
| 301 | {"uqsub16" , 0 , 6 , 0}, | 280 | { "uqsub16", 0, 6, 0 }, |
| 302 | {"uqaddsubx" , 0 , 6 , 0}, | 281 | { "uqaddsubx", 0, 6, 0 }, |
| 303 | {"uqadd8" , 0 , 6 , 0}, | 282 | { "uqadd8", 0, 6, 0 }, |
| 304 | {"uqadd16" , 0 , 6 , 0}, | 283 | { "uqadd16", 0, 6, 0 }, |
| 305 | {"sxtab" , 0 , 6 , 0}, | 284 | { "sxtab", 0, 6, 0 }, |
| 306 | {"uhsubaddx" , 0 , 6 , 0}, | 285 | { "uhsubaddx", 0, 6, 0 }, |
| 307 | {"uhsub8" , 0 , 6 , 0}, | 286 | { "uhsub8", 0, 6, 0 }, |
| 308 | {"uhsub16" , 0 , 6 , 0}, | 287 | { "uhsub16", 0, 6, 0 }, |
| 309 | {"uhaddsubx" , 0 , 6 , 0}, | 288 | { "uhaddsubx", 0, 6, 0 }, |
| 310 | {"uhadd8" , 0 , 6 , 0}, | 289 | { "uhadd8", 0, 6, 0 }, |
| 311 | {"uhadd16" , 0 , 6 , 0}, | 290 | { "uhadd16", 0, 6, 0 }, |
| 312 | {"uaddsubx" , 0 , 6 , 0}, | 291 | { "uaddsubx", 0, 6, 0 }, |
| 313 | {"uadd8" , 0 , 6 , 0}, | 292 | { "uadd8", 0, 6, 0 }, |
| 314 | {"uadd16" , 0 , 6 , 0}, | 293 | { "uadd16", 0, 6, 0 }, |
| 315 | {"sxtah" , 0 , 6 , 0}, | 294 | { "sxtah", 0, 6, 0 }, |
| 316 | {"sxtab16" , 0 , 6 , 0}, | 295 | { "sxtab16", 0, 6, 0 }, |
| 317 | {"qadd8" , 0 , 6 , 0}, | 296 | { "qadd8", 0, 6, 0 }, |
| 318 | {"bxj" , 0 , 5 , 0}, | 297 | { "bxj", 0, 5, 0 }, |
| 319 | {"clz" , 0 , 3 , 0}, | 298 | { "clz", 0, 3, 0 }, |
| 320 | {"uxtah" , 0 , 6 , 0}, | 299 | { "uxtah", 0, 6, 0 }, |
| 321 | {"bx" , 0 , 2 , 0}, | 300 | { "bx", 0, 2, 0 }, |
| 322 | {"rev" , 0 , 6 , 0}, | 301 | { "rev", 0, 6, 0 }, |
| 323 | {"blx" , 0 , 3 , 0}, | 302 | { "blx", 0, 3, 0 }, |
| 324 | {"revsh" , 0 , 6 , 0}, | 303 | { "revsh", 0, 6, 0 }, |
| 325 | {"qadd" , 0 , 4 , 0}, | 304 | { "qadd", 0, 4, 0 }, |
| 326 | {"qadd16" , 0 , 6 , 0}, | 305 | { "qadd16", 0, 6, 0 }, |
| 327 | {"qaddsubx" , 0 , 6 , 0}, | 306 | { "qaddsubx", 0, 6, 0 }, |
| 328 | {"ldrex" , 0 , 0 , 0}, | 307 | { "ldrex", 0, 0, 0 }, |
| 329 | {"qdadd" , 0 , 4 , 0}, | 308 | { "qdadd", 0, 4, 0 }, |
| 330 | {"qdsub" , 0 , 4 , 0}, | 309 | { "qdsub", 0, 4, 0 }, |
| 331 | {"qsub" , 0 , 4 , 0}, | 310 | { "qsub", 0, 4, 0 }, |
| 332 | {"ldrexb" , 0 , 7 , 0}, | 311 | { "ldrexb", 0, 7, 0 }, |
| 333 | {"qsub8" , 0 , 6 , 0}, | 312 | { "qsub8", 0, 6, 0 }, |
| 334 | {"qsub16" , 0 , 6 , 0}, | 313 | { "qsub16", 0, 6, 0 }, |
| 335 | {"smuad" , 0 , 6 , 0}, | 314 | { "smuad", 0, 6, 0 }, |
| 336 | {"smmul" , 0 , 6 , 0}, | 315 | { "smmul", 0, 6, 0 }, |
| 337 | {"smusd" , 0 , 6 , 0}, | 316 | { "smusd", 0, 6, 0 }, |
| 338 | {"smlsd" , 0 , 6 , 0}, | 317 | { "smlsd", 0, 6, 0 }, |
| 339 | {"smlsld" , 0 , 6 , 0}, | 318 | { "smlsld", 0, 6, 0 }, |
| 340 | {"smmla" , 0 , 6 , 0}, | 319 | { "smmla", 0, 6, 0 }, |
| 341 | {"smmls" , 0 , 6 , 0}, | 320 | { "smmls", 0, 6, 0 }, |
| 342 | {"smlald" , 0 , 6 , 0}, | 321 | { "smlald", 0, 6, 0 }, |
| 343 | {"smlad" , 0 , 6 , 0}, | 322 | { "smlad", 0, 6, 0 }, |
| 344 | {"smlaw" , 0 , 4 , 0}, | 323 | { "smlaw", 0, 4, 0 }, |
| 345 | {"smulw" , 0 , 4 , 0}, | 324 | { "smulw", 0, 4, 0 }, |
| 346 | {"pkhtb" , 0 , 6 , 0}, | 325 | { "pkhtb", 0, 6, 0 }, |
| 347 | {"pkhbt" , 0 , 6 , 0}, | 326 | { "pkhbt", 0, 6, 0 }, |
| 348 | {"smul" , 0 , 4 , 0}, | 327 | { "smul", 0, 4, 0 }, |
| 349 | {"smlal" , 0 , 4 , 0}, | 328 | { "smlal", 0, 4, 0 }, |
| 350 | {"smla" , 0 , 4 , 0}, | 329 | { "smla", 0, 4, 0 }, |
| 351 | {"mcrr" , 0 , 6 , 0}, | 330 | { "mcrr", 0, 6, 0 }, |
| 352 | {"mrrc" , 0 , 6 , 0}, | 331 | { "mrrc", 0, 6, 0 }, |
| 353 | {"cmp" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 332 | { "cmp", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 354 | {"tst" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 333 | { "tst", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 355 | {"teq" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 334 | { "teq", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 356 | {"cmn" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 335 | { "cmn", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 357 | {"smull" , 0 , 0 , 0}, | 336 | { "smull", 0, 0, 0 }, |
| 358 | {"umull" , 0 , 0 , 0}, | 337 | { "umull", 0, 0, 0 }, |
| 359 | {"umlal" , 0 , 0 , 0}, | 338 | { "umlal", 0, 0, 0 }, |
| 360 | {"smlal" , 0 , 0 , 0}, | 339 | { "smlal", 0, 0, 0 }, |
| 361 | {"mul" , 0 , 0 , 0}, | 340 | { "mul", 0, 0, 0 }, |
| 362 | {"mla" , 0 , 0 , 0}, | 341 | { "mla", 0, 0, 0 }, |
| 363 | {"ssat" , 0 , 6 , 0}, | 342 | { "ssat", 0, 6, 0 }, |
| 364 | {"usat" , 0 , 6 , 0}, | 343 | { "usat", 0, 6, 0 }, |
| 365 | {"mrs" , 0 , 0 , 0}, | 344 | { "mrs", 0, 0, 0 }, |
| 366 | {"msr" , 0 , 0 , 0}, | 345 | { "msr", 0, 0, 0 }, |
| 367 | {"and" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 346 | { "and", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 368 | {"bic" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 347 | { "bic", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 369 | {"ldm" , 0 , 0 , 0}, | 348 | { "ldm", 0, 0, 0 }, |
| 370 | {"eor" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 349 | { "eor", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 371 | {"add" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 350 | { "add", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 372 | {"rsb" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 351 | { "rsb", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 373 | {"rsc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 352 | { "rsc", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 374 | {"sbc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 353 | { "sbc", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 375 | {"adc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 354 | { "adc", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 376 | {"sub" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 355 | { "sub", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 377 | {"orr" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 356 | { "orr", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 378 | {"mvn" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 357 | { "mvn", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 379 | {"mov" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 358 | { "mov", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 380 | {"stm" , 0 , 0 , 0}, | 359 | { "stm", 0, 0, 0 }, |
| 381 | {"ldm" , 0 , 0 , 0}, | 360 | { "ldm", 0, 0, 0 }, |
| 382 | {"ldrsh" , 0 , 2 , 0}, | 361 | { "ldrsh", 0, 2, 0 }, |
| 383 | {"stm" , 0 , 0 , 0}, | 362 | { "stm", 0, 0, 0 }, |
| 384 | {"ldm" , 0 , 0 , 0}, | 363 | { "ldm", 0, 0, 0 }, |
| 385 | {"ldrsb" , 0 , 2 , 0}, | 364 | { "ldrsb", 0, 2, 0 }, |
| 386 | {"strd" , 0 , 4 , 0}, | 365 | { "strd", 0, 4, 0 }, |
| 387 | {"ldrh" , 0 , 0 , 0}, | 366 | { "ldrh", 0, 0, 0 }, |
| 388 | {"strh" , 0 , 0 , 0}, | 367 | { "strh", 0, 0, 0 }, |
| 389 | {"ldrd" , 0 , 4 , 0}, | 368 | { "ldrd", 0, 4, 0 }, |
| 390 | {"strt" , 0 , 0 , 0}, | 369 | { "strt", 0, 0, 0 }, |
| 391 | {"strbt" , 0 , 0 , 0}, | 370 | { "strbt", 0, 0, 0 }, |
| 392 | {"ldrbt" , 0 , 0 , 0}, | 371 | { "ldrbt", 0, 0, 0 }, |
| 393 | {"ldrt" , 0 , 0 , 0}, | 372 | { "ldrt", 0, 0, 0 }, |
| 394 | {"mrc" , 0 , 6 , 0}, | 373 | { "mrc", 0, 6, 0 }, |
| 395 | {"mcr" , 0 , 0 , 0}, | 374 | { "mcr", 0, 0, 0 }, |
| 396 | {"msr" , 0 , 0 , 0}, | 375 | { "msr", 0, 0, 0 }, |
| 397 | {"ldrb" , 0 , 0 , 0}, | 376 | { "ldrb", 0, 0, 0 }, |
| 398 | {"strb" , 0 , 0 , 0}, | 377 | { "strb", 0, 0, 0 }, |
| 399 | {"ldr" , 0 , 0 , 0}, | 378 | { "ldr", 0, 0, 0 }, |
| 400 | {"ldrcond" , 1 , 0 , 28, 31, 0x0000000e}, | 379 | { "ldrcond", 1, 0, 28, 31, 0x0000000e }, |
| 401 | {"str" , 0 , 0 , 0}, | 380 | { "str", 0, 0, 0 }, |
| 402 | {"cdp" , 0 , 0 , 0}, | 381 | { "cdp", 0, 0, 0 }, |
| 403 | {"stc" , 0 , 0 , 0}, | 382 | { "stc", 0, 0, 0 }, |
| 404 | {"ldc" , 0 , 0 , 0}, | 383 | { "ldc", 0, 0, 0 }, |
| 405 | {"swi" , 0 , 0 , 0}, | 384 | { "swi", 0, 0, 0 }, |
| 406 | {"bbl" , 0 , 0 , 0}, | 385 | { "bbl", 0, 0, 0 }, |
| 407 | {"bl_1_thumb", 0, INVALID, 0},/* should be table[-4] */ | 386 | { "bl_1_thumb", 0, INVALID, 0 }, // Should be table[-4] |
| 408 | {"bl_2_thumb", 0, INVALID, 0}, /* should be located at the end of the table[-3] */ | 387 | { "bl_2_thumb", 0, INVALID, 0 }, // Should be located at the end of the table[-3] |
| 409 | {"blx_1_thumb", 0, INVALID, 0}, /* should be located at table[-2] */ | 388 | { "blx_1_thumb", 0, INVALID, 0 }, // Should be located at table[-2] |
| 410 | {"invalid", 0, INVALID, 0} | 389 | { "invalid", 0, INVALID, 0 } |
| 411 | }; | 390 | }; |
| 412 | 391 | ||
| 413 | int decode_arm_instr(uint32_t instr, int32_t *idx) | 392 | int decode_arm_instr(uint32_t instr, int32_t *idx) { |
| 414 | { | 393 | int n = 0; |
| 415 | int n = 0; | 394 | int base = 0; |
| 416 | int base = 0; | 395 | int ret = DECODE_FAILURE; |
| 417 | int ret = DECODE_FAILURE; | 396 | int i = 0; |
| 418 | int i = 0; | 397 | int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM); |
| 419 | int instr_slots = sizeof(arm_instruction)/sizeof(ISEITEM); | 398 | for (i = 0; i < instr_slots; i++) { |
| 420 | for (i = 0; i < instr_slots; i++) | 399 | n = arm_instruction[i].attribute_value; |
| 421 | { | 400 | base = 0; |
| 422 | // ret = DECODE_SUCCESS; | ||
| 423 | n = arm_instruction[i].attribute_value; | ||
| 424 | base = 0; | ||
| 425 | while (n) { | ||
| 426 | if (arm_instruction[i].content[base + 1] == 31 && arm_instruction[i].content[base] == 0) { | ||
| 427 | /* clrex */ | ||
| 428 | if (instr != arm_instruction[i].content[base + 2]) { | ||
| 429 | break; | ||
| 430 | } | ||
| 431 | } else if (BITS(arm_instruction[i].content[base], arm_instruction[i].content[base + 1]) != arm_instruction[i].content[base + 2]) { | ||
| 432 | break; | ||
| 433 | } | ||
| 434 | base += 3; | ||
| 435 | n --; | ||
| 436 | } | ||
| 437 | //All conditions is satisfied. | ||
| 438 | if (n == 0) | ||
| 439 | ret = DECODE_SUCCESS; | ||
| 440 | 401 | ||
| 441 | if (ret == DECODE_SUCCESS) { | 402 | while (n) { |
| 442 | n = arm_exclusion_code[i].attribute_value; | 403 | if (arm_instruction[i].content[base + 1] == 31 && arm_instruction[i].content[base] == 0) { |
| 443 | if (n != 0) { | 404 | // clrex |
| 444 | base = 0; | 405 | if (instr != arm_instruction[i].content[base + 2]) { |
| 445 | while (n) { | 406 | break; |
| 446 | if (BITS(arm_exclusion_code[i].content[base], arm_exclusion_code[i].content[base + 1]) != arm_exclusion_code[i].content[base + 2]) { | 407 | } |
| 447 | break; } | 408 | } else if (BITS(arm_instruction[i].content[base], arm_instruction[i].content[base + 1]) != arm_instruction[i].content[base + 2]) { |
| 448 | base += 3; | 409 | break; |
| 449 | n --; | 410 | } |
| 450 | } | 411 | base += 3; |
| 451 | //All conditions is satisfied. | 412 | n--; |
| 452 | if (n == 0) | 413 | } |
| 453 | ret = DECODE_FAILURE; | ||
| 454 | } | ||
| 455 | } | ||
| 456 | 414 | ||
| 457 | if (ret == DECODE_SUCCESS) { | 415 | // All conditions is satisfied. |
| 458 | *idx = i; | 416 | if (n == 0) |
| 459 | return ret; | 417 | ret = DECODE_SUCCESS; |
| 460 | } | 418 | |
| 461 | } | 419 | if (ret == DECODE_SUCCESS) { |
| 462 | return ret; | 420 | n = arm_exclusion_code[i].attribute_value; |
| 463 | } | 421 | if (n != 0) { |
| 422 | base = 0; | ||
| 423 | while (n) { | ||
| 424 | if (BITS(arm_exclusion_code[i].content[base], arm_exclusion_code[i].content[base + 1]) != arm_exclusion_code[i].content[base + 2]) { | ||
| 425 | break; | ||
| 426 | } | ||
| 427 | base += 3; | ||
| 428 | n--; | ||
| 429 | } | ||
| 464 | 430 | ||
| 431 | // All conditions is satisfied. | ||
| 432 | if (n == 0) | ||
| 433 | ret = DECODE_FAILURE; | ||
| 434 | } | ||
| 435 | } | ||
| 436 | |||
| 437 | if (ret == DECODE_SUCCESS) { | ||
| 438 | *idx = i; | ||
| 439 | return ret; | ||
| 440 | } | ||
| 441 | } | ||
| 442 | return ret; | ||
| 443 | } | ||
diff --git a/src/core/arm/dyncom/arm_dyncom_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 @@ | |||
| 1 | /* Copyright (C) | 1 | // Copyright 2012 Michael Kang, 2014 Citra Emulator Project |
| 2 | * 2012 - Michael.Kang blackfin.kang@gmail.com | 2 | // Licensed under GPLv2 or any later version |
| 3 | * This program is free software; you can redistribute it and/or | 3 | // Refer to the license.txt file included. |
| 4 | * modify it under the terms of the GNU General Public License | ||
| 5 | * as published by the Free Software Foundation; either version 2 | ||
| 6 | * of the License, or (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program; if not, write to the Free Software | ||
| 15 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | /** | ||
| 19 | * @file arm_dyncom_interpreter.cpp | ||
| 20 | * @brief The fast interpreter for arm | ||
| 21 | * @author Michael.Kang blackfin.kang@gmail.com | ||
| 22 | * @version 7849 | ||
| 23 | * @date 2012-03-15 | ||
| 24 | */ | ||
| 25 | 4 | ||
| 26 | #define CITRA_IGNORE_EXIT(x) | 5 | #define CITRA_IGNORE_EXIT(x) |
| 27 | 6 | ||
| @@ -39,10 +18,6 @@ using namespace std; | |||
| 39 | #include "arm_dyncom_thumb.h" | 18 | #include "arm_dyncom_thumb.h" |
| 40 | #include "arm_dyncom_run.h" | 19 | #include "arm_dyncom_run.h" |
| 41 | #include "core/arm/skyeye_common/vfp/vfp.h" | 20 | #include "core/arm/skyeye_common/vfp/vfp.h" |
| 42 | /* shenoubang 2012-6-14 */ | ||
| 43 | #ifdef __WIN32__ | ||
| 44 | #include "bank_defs.h" | ||
| 45 | #endif | ||
| 46 | 21 | ||
| 47 | #include "core/mem_map.h" | 22 | #include "core/mem_map.h" |
| 48 | #include "core/hle/hle.h" | 23 | #include "core/hle/hle.h" |
| @@ -58,325 +33,243 @@ enum { | |||
| 58 | THUMB = (1 << 7) | 33 | THUMB = (1 << 7) |
| 59 | }; | 34 | }; |
| 60 | 35 | ||
| 61 | #define USER_MODE_OPT 1 | 36 | #define USER_MODE_OPT 1 |
| 62 | #define HYBRID_MODE 0 // Enable for JIT mode | 37 | #define HYBRID_MODE 0 // Enable for JIT mode |
| 63 | 38 | ||
| 64 | #define THRESHOLD 1000 | 39 | #define THRESHOLD 1000 |
| 65 | #define DURATION 500 | 40 | #define DURATION 500 |
| 66 | //#define PRINT_PROFILE_INFO | ||
| 67 | 41 | ||
| 68 | #define CHECK_RS if(RS == 15) rs += 8 | 42 | #define CHECK_RS if(RS == 15) rs += 8 |
| 69 | #define CHECK_RM if(RM == 15) rm += 8 | 43 | #define CHECK_RM if(RM == 15) rm += 8 |
| 70 | 44 | ||
| 71 | //#define BITS(s, a, b) (((s) >> (a)) & ((1 << (1 + (b) - (a))) - 1)) | ||
| 72 | #undef BITS | 45 | #undef BITS |
| 73 | #define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1)) | 46 | #define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1)) |
| 74 | #define BIT(s, n) ((s >> (n)) & 1) | 47 | #define BIT(s, n) ((s >> (n)) & 1) |
| 75 | #define RM BITS(sht_oper, 0, 3) | 48 | #define RM BITS(sht_oper, 0, 3) |
| 76 | #define RS BITS(sht_oper, 8, 11) | 49 | #define RS BITS(sht_oper, 8, 11) |
| 77 | 50 | ||
| 78 | #define glue(x, y) x ## y | 51 | #define glue(x, y) x ## y |
| 79 | #define DPO(s) glue(DataProcessingOperands, s) | 52 | #define DPO(s) glue(DataProcessingOperands, s) |
| 80 | #define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i)) | 53 | #define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i)) |
| 81 | #define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i)) | 54 | #define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i)) |
| 82 | #define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32) | 55 | #define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32) |
| 83 | #define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32) | 56 | #define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32) |
| 84 | 57 | ||
| 85 | //#define rotr(x,n) ((((x)>>(n))&((1<<(sizeof(x) * 8)-1))|(x<<(sizeof(x)*8-n)))) | ||
| 86 | //#define rotl(x,n) ((((x)<<(n))&(-(1<<(n))))|(((x)>>(sizeof(x)*8-n))&((1<<(n))-1))) | ||
| 87 | #define rotr(x,n) ( (x >> n) | ((x & ((1 << (n + 1)) - 1)) << (32 - n)) ) | 58 | #define rotr(x,n) ( (x >> n) | ((x & ((1 << (n + 1)) - 1)) << (32 - n)) ) |
| 88 | 59 | ||
| 89 | extern void switch_mode(arm_core_t *core, uint32_t mode); | 60 | extern void switch_mode(arm_core_t *core, uint32_t mode); |
| 90 | //extern bool InAPrivilegedMode(arm_core_t *core); | ||
| 91 | 61 | ||
| 92 | typedef arm_core_t arm_processor; | 62 | typedef arm_core_t arm_processor; |
| 93 | typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper); | 63 | typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper); |
| 94 | 64 | ||
| 95 | /* exclusive memory access */ | 65 | // Exclusive memory access |
| 96 | static int exclusive_detect(ARMul_State* state, ARMword addr){ | 66 | static int exclusive_detect(ARMul_State* state, ARMword addr){ |
| 97 | #if 0 | 67 | if(state->exclusive_tag == addr) |
| 98 | for(int i = 0; i < 128; i++){ | 68 | return 0; |
| 99 | if(state->exclusive_tag_array[i] == addr) | 69 | else |
| 100 | return 0; | 70 | return -1; |
| 101 | } | ||
| 102 | #endif | ||
| 103 | if(state->exclusive_tag == addr) | ||
| 104 | return 0; | ||
| 105 | else | ||
| 106 | return -1; | ||
| 107 | } | 71 | } |
| 108 | 72 | ||
| 109 | static void add_exclusive_addr(ARMul_State* state, ARMword addr){ | 73 | static void add_exclusive_addr(ARMul_State* state, ARMword addr){ |
| 110 | #if 0 | 74 | state->exclusive_tag = addr; |
| 111 | for(int i = 0; i < 128; i++){ | 75 | return; |
| 112 | if(state->exclusive_tag_array[i] == 0xffffffff){ | ||
| 113 | state->exclusive_tag_array[i] = addr; | ||
| 114 | //DEBUG_LOG(ARM11, "In %s, add addr 0x%x\n", __func__, addr); | ||
| 115 | return; | ||
| 116 | } | ||
| 117 | } | ||
| 118 | DEBUG_LOG(ARM11, "In %s ,can not monitor the addr, out of array\n", __FUNCTION__); | ||
| 119 | #endif | ||
| 120 | state->exclusive_tag = addr; | ||
| 121 | return; | ||
| 122 | } | 76 | } |
| 123 | 77 | ||
| 124 | static void remove_exclusive(ARMul_State* state, ARMword addr){ | 78 | static void remove_exclusive(ARMul_State* state, ARMword addr){ |
| 125 | #if 0 | 79 | state->exclusive_tag = 0xFFFFFFFF; |
| 126 | int i; | 80 | } |
| 127 | for(i = 0; i < 128; i++){ | 81 | |
| 128 | if(state->exclusive_tag_array[i] == addr){ | 82 | |
| 129 | state->exclusive_tag_array[i] = 0xffffffff; | 83 | unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) { |
| 130 | //DEBUG_LOG(ARM11, "In %s, remove addr 0x%x\n", __func__, addr); | 84 | unsigned int immed_8 = BITS(sht_oper, 0, 7); |
| 131 | return; | 85 | unsigned int rotate_imm = BITS(sht_oper, 8, 11); |
| 132 | } | 86 | unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2); |
| 133 | } | 87 | if (rotate_imm == 0) |
| 134 | #endif | 88 | cpu->shifter_carry_out = cpu->CFlag; |
| 135 | state->exclusive_tag = 0xFFFFFFFF; | 89 | else |
| 136 | } | 90 | cpu->shifter_carry_out = BIT(shifter_operand, 31); |
| 137 | 91 | return shifter_operand; | |
| 138 | 92 | } | |
| 139 | unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) | 93 | |
| 140 | { | 94 | unsigned int DPO(Register)(arm_processor *cpu, unsigned int sht_oper) { |
| 141 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | 95 | unsigned int rm = CHECK_READ_REG15(cpu, RM); |
| 142 | unsigned int immed_8 = BITS(sht_oper, 0, 7); | 96 | unsigned int shifter_operand = rm; |
| 143 | unsigned int rotate_imm = BITS(sht_oper, 8, 11); | 97 | cpu->shifter_carry_out = cpu->CFlag; |
| 144 | // DEBUG_LOG(ARM11, "immed_8 is %x\n", immed_8); | 98 | return shifter_operand; |
| 145 | // DEBUG_LOG(ARM11, "rotate_imm is %x\n", rotate_imm); | 99 | } |
| 146 | unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2);//ROTATE_RIGHT_32(immed_8, rotate_imm * 2); | 100 | |
| 147 | // DEBUG_LOG(ARM11, "shifter_operand : %x\n", shifter_operand); | 101 | unsigned int DPO(LogicalShiftLeftByImmediate)(arm_processor *cpu, unsigned int sht_oper) { |
| 148 | /* set c flag */ | 102 | int shift_imm = BITS(sht_oper, 7, 11); |
| 149 | if (rotate_imm == 0) | 103 | unsigned int rm = CHECK_READ_REG15(cpu, RM); |
| 150 | cpu->shifter_carry_out = cpu->CFlag; | 104 | unsigned int shifter_operand; |
| 151 | else | 105 | if (shift_imm == 0) { |
| 152 | cpu->shifter_carry_out = BIT(shifter_operand, 31); | 106 | shifter_operand = rm; |
| 153 | return shifter_operand; | 107 | cpu->shifter_carry_out = cpu->CFlag; |
| 154 | } | 108 | } else { |
| 155 | 109 | shifter_operand = rm << shift_imm; | |
| 156 | unsigned int DPO(Register)(arm_processor *cpu, unsigned int sht_oper) | 110 | cpu->shifter_carry_out = BIT(rm, 32 - shift_imm); |
| 157 | { | 111 | } |
| 158 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | 112 | return shifter_operand; |
| 159 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | 113 | } |
| 160 | //if (RM == 15) rm += 8; | 114 | |
| 161 | unsigned int shifter_operand = rm; | 115 | unsigned int DPO(LogicalShiftLeftByRegister)(arm_processor *cpu, unsigned int sht_oper) { |
| 162 | cpu->shifter_carry_out = cpu->CFlag; | 116 | int shifter_operand; |
| 163 | return shifter_operand; | 117 | unsigned int rm = CHECK_READ_REG15(cpu, RM); |
| 118 | unsigned int rs = CHECK_READ_REG15(cpu, RS); | ||
| 119 | if (BITS(rs, 0, 7) == 0) { | ||
| 120 | shifter_operand = rm; | ||
| 121 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 122 | } else if (BITS(rs, 0, 7) < 32) { | ||
| 123 | shifter_operand = rm << BITS(rs, 0, 7); | ||
| 124 | cpu->shifter_carry_out = BIT(rm, 32 - BITS(rs, 0, 7)); | ||
| 125 | } else if (BITS(rs, 0, 7) == 32) { | ||
| 126 | shifter_operand = 0; | ||
| 127 | cpu->shifter_carry_out = BIT(rm, 0); | ||
| 128 | } else { | ||
| 129 | shifter_operand = 0; | ||
| 130 | cpu->shifter_carry_out = 0; | ||
| 131 | } | ||
| 132 | return shifter_operand; | ||
| 133 | } | ||
| 134 | |||
| 135 | unsigned int DPO(LogicalShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) { | ||
| 136 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 137 | unsigned int shifter_operand; | ||
| 138 | int shift_imm = BITS(sht_oper, 7, 11); | ||
| 139 | if (shift_imm == 0) { | ||
| 140 | shifter_operand = 0; | ||
| 141 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 142 | } else { | ||
| 143 | shifter_operand = rm >> shift_imm; | ||
| 144 | cpu->shifter_carry_out = BIT(rm, shift_imm - 1); | ||
| 145 | } | ||
| 146 | return shifter_operand; | ||
| 147 | } | ||
| 148 | |||
| 149 | unsigned int DPO(LogicalShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper) { | ||
| 150 | unsigned int rs = CHECK_READ_REG15(cpu, RS); | ||
| 151 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 152 | unsigned int shifter_operand; | ||
| 153 | if (BITS(rs, 0, 7) == 0) { | ||
| 154 | shifter_operand = rm; | ||
| 155 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 156 | } else if (BITS(rs, 0, 7) < 32) { | ||
| 157 | shifter_operand = rm >> BITS(rs, 0, 7); | ||
| 158 | cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1); | ||
| 159 | } else if (BITS(rs, 0, 7) == 32) { | ||
| 160 | shifter_operand = 0; | ||
| 161 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 162 | } else { | ||
| 163 | shifter_operand = 0; | ||
| 164 | cpu->shifter_carry_out = 0; | ||
| 165 | } | ||
| 166 | return shifter_operand; | ||
| 167 | } | ||
| 168 | |||
| 169 | unsigned int DPO(ArithmeticShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) { | ||
| 170 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 171 | unsigned int shifter_operand; | ||
| 172 | int shift_imm = BITS(sht_oper, 7, 11); | ||
| 173 | if (shift_imm == 0) { | ||
| 174 | if (BIT(rm, 31)) { | ||
| 175 | shifter_operand = 0; | ||
| 176 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 177 | } else { | ||
| 178 | shifter_operand = 0xFFFFFFFF; | ||
| 179 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 180 | } | ||
| 181 | } else { | ||
| 182 | shifter_operand = static_cast<int>(rm) >> shift_imm; | ||
| 183 | cpu->shifter_carry_out = BIT(rm, shift_imm - 1); | ||
| 184 | } | ||
| 185 | return shifter_operand; | ||
| 186 | } | ||
| 187 | |||
| 188 | unsigned int DPO(ArithmeticShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper) { | ||
| 189 | unsigned int rs = CHECK_READ_REG15(cpu, RS); | ||
| 190 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 191 | unsigned int shifter_operand; | ||
| 192 | if (BITS(rs, 0, 7) == 0) { | ||
| 193 | shifter_operand = rm; | ||
| 194 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 195 | } else if (BITS(rs, 0, 7) < 32) { | ||
| 196 | shifter_operand = static_cast<int>(rm) >> BITS(rs, 0, 7); | ||
| 197 | cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1); | ||
| 198 | } else { | ||
| 199 | if (BIT(rm, 31) == 0) | ||
| 200 | shifter_operand = 0; | ||
| 201 | else | ||
| 202 | shifter_operand = 0xffffffff; | ||
| 203 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 204 | } | ||
| 205 | return shifter_operand; | ||
| 206 | } | ||
| 207 | |||
| 208 | unsigned int DPO(RotateRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) { | ||
| 209 | unsigned int shifter_operand; | ||
| 210 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 211 | int shift_imm = BITS(sht_oper, 7, 11); | ||
| 212 | if (shift_imm == 0) { | ||
| 213 | shifter_operand = (cpu->CFlag << 31) | (rm >> 1); | ||
| 214 | cpu->shifter_carry_out = BIT(rm, 0); | ||
| 215 | } else { | ||
| 216 | shifter_operand = ROTATE_RIGHT_32(rm, shift_imm); | ||
| 217 | cpu->shifter_carry_out = BIT(rm, shift_imm - 1); | ||
| 218 | } | ||
| 219 | return shifter_operand; | ||
| 220 | } | ||
| 221 | |||
| 222 | unsigned int DPO(RotateRightByRegister)(arm_processor *cpu, unsigned int sht_oper) { | ||
| 223 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 224 | unsigned int rs = CHECK_READ_REG15(cpu, RS); | ||
| 225 | unsigned int shifter_operand; | ||
| 226 | if (BITS(rs, 0, 7) == 0) { | ||
| 227 | shifter_operand = rm; | ||
| 228 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 229 | } else if (BITS(rs, 0, 4) == 0) { | ||
| 230 | shifter_operand = rm; | ||
| 231 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 232 | } else { | ||
| 233 | shifter_operand = ROTATE_RIGHT_32(rm, BITS(rs, 0, 4)); | ||
| 234 | cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 4) - 1); | ||
| 235 | } | ||
| 236 | return shifter_operand; | ||
| 164 | } | 237 | } |
| 165 | 238 | ||
| 166 | unsigned int DPO(LogicalShiftLeftByImmediate)(arm_processor *cpu, unsigned int sht_oper) | ||
| 167 | { | ||
| 168 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 169 | int shift_imm = BITS(sht_oper, 7, 11); | ||
| 170 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 171 | //if (RM == 15) rm += 8; | ||
| 172 | unsigned int shifter_operand; | ||
| 173 | if (shift_imm == 0) { | ||
| 174 | shifter_operand = rm; | ||
| 175 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 176 | } else { | ||
| 177 | shifter_operand = rm << shift_imm; | ||
| 178 | cpu->shifter_carry_out = BIT(rm, 32 - shift_imm); | ||
| 179 | } | ||
| 180 | return shifter_operand; | ||
| 181 | } | ||
| 182 | |||
| 183 | unsigned int DPO(LogicalShiftLeftByRegister)(arm_processor *cpu, unsigned int sht_oper) | ||
| 184 | { | ||
| 185 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 186 | int shifter_operand; | ||
| 187 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 188 | unsigned int rs = CHECK_READ_REG15(cpu, RS); | ||
| 189 | //if (RM == 15) rm += 8; | ||
| 190 | //if (RS == 15) rs += 8; | ||
| 191 | if (BITS(rs, 0, 7) == 0) { | ||
| 192 | shifter_operand = rm; | ||
| 193 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 194 | } else if (BITS(rs, 0, 7) < 32) { | ||
| 195 | shifter_operand = rm << BITS(rs, 0, 7); | ||
| 196 | cpu->shifter_carry_out = BIT(rm, 32 - BITS(rs, 0, 7)); | ||
| 197 | } else if (BITS(rs, 0, 7) == 32) { | ||
| 198 | shifter_operand = 0; | ||
| 199 | cpu->shifter_carry_out = BIT(rm, 0); | ||
| 200 | } else { | ||
| 201 | shifter_operand = 0; | ||
| 202 | cpu->shifter_carry_out = 0; | ||
| 203 | } | ||
| 204 | return shifter_operand; | ||
| 205 | } | ||
| 206 | |||
| 207 | unsigned int DPO(LogicalShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) | ||
| 208 | { | ||
| 209 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 210 | //unsigned int rm = cpu->Reg[RM]; | ||
| 211 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 212 | //if (RM == 15) rm += 8; | ||
| 213 | unsigned int shifter_operand; | ||
| 214 | int shift_imm = BITS(sht_oper, 7, 11); | ||
| 215 | if (shift_imm == 0) { | ||
| 216 | shifter_operand = 0; | ||
| 217 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 218 | } else { | ||
| 219 | shifter_operand = rm >> shift_imm; | ||
| 220 | cpu->shifter_carry_out = BIT(rm, shift_imm - 1); | ||
| 221 | } | ||
| 222 | return shifter_operand; | ||
| 223 | } | ||
| 224 | |||
| 225 | unsigned int DPO(LogicalShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper) | ||
| 226 | { | ||
| 227 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 228 | unsigned int rs = CHECK_READ_REG15(cpu, RS); | ||
| 229 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 230 | //if (RS == 15) rs += 8; | ||
| 231 | //if (RM == 15) rm += 8; | ||
| 232 | unsigned int shifter_operand; | ||
| 233 | if (BITS(rs, 0, 7) == 0) { | ||
| 234 | shifter_operand = rm; | ||
| 235 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 236 | } else if (BITS(rs, 0, 7) < 32) { | ||
| 237 | shifter_operand = rm >> BITS(rs, 0, 7); | ||
| 238 | cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1); | ||
| 239 | } else if (BITS(rs, 0, 7) == 32) { | ||
| 240 | shifter_operand = 0; | ||
| 241 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 242 | } else { | ||
| 243 | shifter_operand = 0; | ||
| 244 | cpu->shifter_carry_out = 0; | ||
| 245 | } | ||
| 246 | return shifter_operand; | ||
| 247 | } | ||
| 248 | |||
| 249 | unsigned int DPO(ArithmeticShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) | ||
| 250 | { | ||
| 251 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 252 | //unsigned int rm = cpu->Reg[RM]; | ||
| 253 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 254 | //if (RM == 15) rm += 8; | ||
| 255 | unsigned int shifter_operand; | ||
| 256 | int shift_imm = BITS(sht_oper, 7, 11); | ||
| 257 | if (shift_imm == 0) { | ||
| 258 | if (BIT(rm, 31)) { | ||
| 259 | shifter_operand = 0; | ||
| 260 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 261 | } else { | ||
| 262 | shifter_operand = 0xFFFFFFFF; | ||
| 263 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 264 | } | ||
| 265 | } else { | ||
| 266 | shifter_operand = static_cast<int>(rm) >> shift_imm; | ||
| 267 | cpu->shifter_carry_out = BIT(rm, shift_imm - 1); | ||
| 268 | } | ||
| 269 | return shifter_operand; | ||
| 270 | } | ||
| 271 | |||
| 272 | unsigned int DPO(ArithmeticShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper) | ||
| 273 | { | ||
| 274 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 275 | //unsigned int rs = cpu->Reg[RS]; | ||
| 276 | unsigned int rs = CHECK_READ_REG15(cpu, RS); | ||
| 277 | //unsigned int rm = cpu->Reg[RM]; | ||
| 278 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 279 | //if (RS == 15) rs += 8; | ||
| 280 | //if (RM == 15) rm += 8; | ||
| 281 | unsigned int shifter_operand; | ||
| 282 | if (BITS(rs, 0, 7) == 0) { | ||
| 283 | shifter_operand = rm; | ||
| 284 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 285 | } else if (BITS(rs, 0, 7) < 32) { | ||
| 286 | shifter_operand = static_cast<int>(rm) >> BITS(rs, 0, 7); | ||
| 287 | cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1); | ||
| 288 | } else { | ||
| 289 | if (BIT(rm, 31) == 0) { | ||
| 290 | shifter_operand = 0; | ||
| 291 | } else | ||
| 292 | shifter_operand = 0xffffffff; | ||
| 293 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 294 | } | ||
| 295 | return shifter_operand; | ||
| 296 | } | ||
| 297 | |||
| 298 | unsigned int DPO(RotateRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) | ||
| 299 | { | ||
| 300 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 301 | unsigned int shifter_operand; | ||
| 302 | //unsigned int rm = cpu->Reg[RM]; | ||
| 303 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 304 | //if (RM == 15) rm += 8; | ||
| 305 | int shift_imm = BITS(sht_oper, 7, 11); | ||
| 306 | if (shift_imm == 0) { | ||
| 307 | shifter_operand = (cpu->CFlag << 31) | | ||
| 308 | (rm >> 1); | ||
| 309 | cpu->shifter_carry_out = BIT(rm, 0); | ||
| 310 | } else { | ||
| 311 | shifter_operand = ROTATE_RIGHT_32(rm, shift_imm); | ||
| 312 | cpu->shifter_carry_out = BIT(rm, shift_imm - 1); | ||
| 313 | } | ||
| 314 | return shifter_operand; | ||
| 315 | } | ||
| 316 | |||
| 317 | unsigned int DPO(RotateRightByRegister)(arm_processor *cpu, unsigned int sht_oper) | ||
| 318 | { | ||
| 319 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 320 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 321 | //if (RM == 15) rm += 8; | ||
| 322 | unsigned int rs = CHECK_READ_REG15(cpu, RS); | ||
| 323 | //if (RS == 15) rs += 8; | ||
| 324 | unsigned int shifter_operand; | ||
| 325 | if (BITS(rs, 0, 7) == 0) { | ||
| 326 | shifter_operand = rm; | ||
| 327 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 328 | } else if (BITS(rs, 0, 4) == 0) { | ||
| 329 | shifter_operand = rm; | ||
| 330 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 331 | } else { | ||
| 332 | shifter_operand = ROTATE_RIGHT_32(rm, BITS(rs, 0, 4)); | ||
| 333 | cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 4) - 1); | ||
| 334 | } | ||
| 335 | #if 0 | ||
| 336 | if (cpu->icounter >= 20371544) { | ||
| 337 | DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 338 | DEBUG_LOG(ARM11, "RM:%d\nRS:%d\n", RM, RS); | ||
| 339 | DEBUG_LOG(ARM11, "rm:0x%08x\nrs:0x%08x\n", cpu->Reg[RM], cpu->Reg[RS]); | ||
| 340 | } | ||
| 341 | #endif | ||
| 342 | return shifter_operand; | ||
| 343 | } | ||
| 344 | |||
| 345 | //typedef unsigned int (*get_addr_fp_t)(arm_processor *cpu); | ||
| 346 | typedef struct _MiscImmeData { | 239 | typedef struct _MiscImmeData { |
| 347 | unsigned int U; | 240 | unsigned int U; |
| 348 | unsigned int Rn; | 241 | unsigned int Rn; |
| 349 | unsigned int offset_8; | 242 | unsigned int offset_8; |
| 350 | } MiscLSData; | 243 | } MiscLSData; |
| 351 | 244 | ||
| 352 | typedef struct _MiscRegData { | 245 | typedef struct _MiscRegData { |
| 353 | unsigned int U; | 246 | unsigned int U; |
| 354 | unsigned int Rn; | 247 | unsigned int Rn; |
| 355 | unsigned int Rm; | 248 | unsigned int Rm; |
| 356 | } MiscRegData; | 249 | } MiscRegData; |
| 357 | 250 | ||
| 358 | typedef struct _MiscImmePreIdx { | 251 | typedef struct _MiscImmePreIdx { |
| 359 | unsigned int offset_8; | 252 | unsigned int offset_8; |
| 360 | unsigned int U; | 253 | unsigned int U; |
| 361 | unsigned int Rn; | 254 | unsigned int Rn; |
| 362 | } MiscImmePreIdx; | 255 | } MiscImmePreIdx; |
| 363 | 256 | ||
| 364 | typedef struct _MiscRegPreIdx { | 257 | typedef struct _MiscRegPreIdx { |
| 365 | unsigned int U; | 258 | unsigned int U; |
| 366 | unsigned int Rn; | 259 | unsigned int Rn; |
| 367 | unsigned int Rm; | 260 | unsigned int Rm; |
| 368 | } MiscRegPreIdx; | 261 | } MiscRegPreIdx; |
| 369 | 262 | ||
| 370 | typedef struct _MiscImmePstIdx { | 263 | typedef struct _MiscImmePstIdx { |
| 371 | unsigned int offset_8; | 264 | unsigned int offset_8; |
| 372 | unsigned int U; | 265 | unsigned int U; |
| 373 | unsigned int Rn; | 266 | unsigned int Rn; |
| 374 | } MIscImmePstIdx; | 267 | } MIscImmePstIdx; |
| 375 | 268 | ||
| 376 | typedef struct _MiscRegPstIdx { | 269 | typedef struct _MiscRegPstIdx { |
| 377 | unsigned int Rn; | 270 | unsigned int Rn; |
| 378 | unsigned int Rm; | 271 | unsigned int Rm; |
| 379 | unsigned int U; | 272 | unsigned int U; |
| 380 | } MiscRegPstIdx; | 273 | } MiscRegPstIdx; |
| 381 | 274 | ||
| 382 | typedef struct _LSWordorUnsignedByte { | 275 | typedef struct _LSWordorUnsignedByte { |
| @@ -384,40 +277,38 @@ typedef struct _LSWordorUnsignedByte { | |||
| 384 | 277 | ||
| 385 | #if USER_MODE_OPT | 278 | #if USER_MODE_OPT |
| 386 | static inline fault_t interpreter_read_memory(addr_t virt_addr, addr_t phys_addr, uint32_t &value, uint32_t size){ | 279 | static inline fault_t interpreter_read_memory(addr_t virt_addr, addr_t phys_addr, uint32_t &value, uint32_t size){ |
| 387 | switch(size) { | 280 | switch(size) { |
| 388 | case 8: | 281 | case 8: |
| 389 | value = Memory::Read8(virt_addr); | 282 | value = Memory::Read8(virt_addr); |
| 390 | break; | 283 | break; |
| 391 | case 16: | 284 | case 16: |
| 392 | value = Memory::Read16(virt_addr); | 285 | value = Memory::Read16(virt_addr); |
| 393 | break; | 286 | break; |
| 394 | case 32: | 287 | case 32: |
| 395 | value = Memory::Read32(virt_addr); | 288 | value = Memory::Read32(virt_addr); |
| 396 | break; | 289 | break; |
| 397 | } | 290 | } |
| 398 | return NO_FAULT; | 291 | return NO_FAULT; |
| 399 | } | 292 | } |
| 400 | 293 | ||
| 401 | //static inline void interpreter_write_memory(void *mem_ptr, uint32_t offset, uint32_t value, int size) | 294 | static inline fault_t interpreter_write_memory(addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size) { |
| 402 | static inline fault_t interpreter_write_memory(addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size) | 295 | switch(size) { |
| 403 | { | 296 | case 8: |
| 404 | switch(size) { | ||
| 405 | case 8: | ||
| 406 | Memory::Write8(virt_addr, value & 0xff); | 297 | Memory::Write8(virt_addr, value & 0xff); |
| 407 | break; | 298 | break; |
| 408 | case 16: | 299 | case 16: |
| 409 | Memory::Write16(virt_addr, value & 0xffff); | 300 | Memory::Write16(virt_addr, value & 0xffff); |
| 410 | break; | 301 | break; |
| 411 | case 32: | 302 | case 32: |
| 412 | Memory::Write32(virt_addr, value); | 303 | Memory::Write32(virt_addr, value); |
| 413 | break; | 304 | break; |
| 414 | } | 305 | } |
| 415 | return NO_FAULT; | 306 | return NO_FAULT; |
| 416 | } | 307 | } |
| 417 | 308 | ||
| 418 | static inline fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_addr, uint32_t rw){ | 309 | static inline fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_addr, uint32_t rw) { |
| 419 | *phys_addr = virt_addr; | 310 | *phys_addr = virt_addr; |
| 420 | return NO_FAULT; | 311 | return NO_FAULT; |
| 421 | } | 312 | } |
| 422 | 313 | ||
| 423 | #else | 314 | #else |
| @@ -430,745 +321,679 @@ fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_ | |||
| 430 | typedef fault_t (*get_addr_fp_t)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw); | 321 | typedef fault_t (*get_addr_fp_t)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw); |
| 431 | 322 | ||
| 432 | typedef struct _ldst_inst { | 323 | typedef struct _ldst_inst { |
| 433 | unsigned int inst; | 324 | unsigned int inst; |
| 434 | get_addr_fp_t get_addr; | 325 | get_addr_fp_t get_addr; |
| 435 | } ldst_inst; | 326 | } ldst_inst; |
| 436 | #define DEBUG_MSG LOG_DEBUG(Core_ARM11, "inst is %x", inst); CITRA_IGNORE_EXIT(0) | 327 | #define DEBUG_MSG LOG_DEBUG(Core_ARM11, "inst is %x", inst); CITRA_IGNORE_EXIT(0) |
| 437 | 328 | ||
| 438 | int CondPassed(arm_processor *cpu, unsigned int cond); | 329 | int CondPassed(arm_processor *cpu, unsigned int cond); |
| 439 | #define LnSWoUB(s) glue(LnSWoUB, s) | 330 | #define LnSWoUB(s) glue(LnSWoUB, s) |
| 440 | #define MLnS(s) glue(MLnS, s) | 331 | #define MLnS(s) glue(MLnS, s) |
| 441 | #define LdnStM(s) glue(LdnStM, s) | 332 | #define LdnStM(s) glue(LdnStM, s) |
| 442 | 333 | ||
| 443 | #define W_BIT BIT(inst, 21) | 334 | #define W_BIT BIT(inst, 21) |
| 444 | #define U_BIT BIT(inst, 23) | 335 | #define U_BIT BIT(inst, 23) |
| 445 | #define I_BIT BIT(inst, 25) | 336 | #define I_BIT BIT(inst, 25) |
| 446 | #define P_BIT BIT(inst, 24) | 337 | #define P_BIT BIT(inst, 24) |
| 447 | #define OFFSET_12 BITS(inst, 0, 11) | 338 | #define OFFSET_12 BITS(inst, 0, 11) |
| 448 | fault_t LnSWoUB(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 339 | fault_t LnSWoUB(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 449 | { | 340 | unsigned int Rn = BITS(inst, 16, 19); |
| 450 | unsigned int Rn = BITS(inst, 16, 19); | 341 | unsigned int addr; |
| 451 | unsigned int addr; | 342 | fault_t fault; |
| 452 | fault_t fault; | 343 | if (U_BIT) { |
| 453 | if (U_BIT) { | 344 | addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; |
| 454 | addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; | 345 | } else { |
| 455 | } else { | 346 | addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; |
| 456 | addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; | 347 | } |
| 457 | } | 348 | virt_addr = addr; |
| 458 | //if (Rn == 15) rn += 8; | 349 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 459 | virt_addr = addr; | 350 | return fault; |
| 460 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 351 | } |
| 461 | return fault; | 352 | |
| 462 | // return addr; | 353 | fault_t LnSWoUB(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 463 | } | 354 | fault_t fault; |
| 464 | 355 | unsigned int Rn = BITS(inst, 16, 19); | |
| 465 | fault_t LnSWoUB(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 356 | unsigned int Rm = BITS(inst, 0, 3); |
| 466 | { | 357 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 467 | fault_t fault; | 358 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 468 | unsigned int Rn = BITS(inst, 16, 19); | 359 | unsigned int addr; |
| 469 | unsigned int Rm = BITS(inst, 0, 3); | 360 | if (U_BIT) { |
| 470 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 361 | addr = rn + rm; |
| 471 | //if (Rn == 15) rn += 8; | 362 | } else { |
| 472 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 363 | addr = rn - rm; |
| 473 | //if (Rm == 15) rm += 8; | 364 | } |
| 474 | unsigned int addr; | 365 | virt_addr = addr; |
| 475 | if (U_BIT) { | 366 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 476 | addr = rn + rm; | 367 | return fault; |
| 477 | } else { | 368 | } |
| 478 | addr = rn - rm; | 369 | |
| 479 | } | 370 | fault_t LnSWoUB(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 480 | virt_addr = addr; | 371 | fault_t fault; |
| 481 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 372 | unsigned int Rn = BITS(inst, 16, 19); |
| 482 | return fault; | 373 | unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn); |
| 483 | } | 374 | |
| 484 | 375 | virt_addr = addr; | |
| 485 | fault_t LnSWoUB(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 376 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 486 | { | 377 | if (fault) return fault; |
| 487 | fault_t fault; | 378 | |
| 488 | unsigned int Rn = BITS(inst, 16, 19); | 379 | if (U_BIT) { |
| 489 | unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn); | 380 | cpu->Reg[Rn] += OFFSET_12; |
| 490 | //if (Rn == 15) addr += 8; | 381 | } else { |
| 382 | cpu->Reg[Rn] -= OFFSET_12; | ||
| 383 | } | ||
| 384 | return fault; | ||
| 385 | } | ||
| 386 | |||
| 387 | fault_t LnSWoUB(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | ||
| 388 | fault_t fault; | ||
| 389 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 390 | unsigned int addr; | ||
| 391 | if (U_BIT) { | ||
| 392 | addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; | ||
| 393 | } else { | ||
| 394 | addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; | ||
| 395 | } | ||
| 396 | |||
| 397 | virt_addr = addr; | ||
| 398 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 399 | if (fault) return fault; | ||
| 400 | |||
| 401 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | ||
| 402 | cpu->Reg[Rn] = addr; | ||
| 403 | } | ||
| 404 | return fault; | ||
| 405 | } | ||
| 406 | |||
| 407 | fault_t MLnS(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | ||
| 408 | fault_t fault; | ||
| 409 | unsigned int addr; | ||
| 410 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 411 | unsigned int Rm = BITS(inst, 0, 3); | ||
| 412 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 413 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | ||
| 414 | |||
| 415 | if (U_BIT) { | ||
| 416 | addr = rn + rm; | ||
| 417 | } else | ||
| 418 | addr = rn - rm; | ||
| 419 | if(BIT(inst, 20)){ // L BIT | ||
| 420 | } | ||
| 421 | if(BIT(inst, 6)){ // Sign Bit | ||
| 422 | } | ||
| 423 | if(BIT(inst, 5)){ // Half Bit | ||
| 424 | } | ||
| 425 | |||
| 426 | virt_addr = addr; | ||
| 427 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 428 | if (fault) return fault; | ||
| 429 | |||
| 430 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | ||
| 431 | cpu->Reg[Rn] = addr; | ||
| 432 | } | ||
| 433 | return fault; | ||
| 434 | } | ||
| 435 | |||
| 436 | fault_t LnSWoUB(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | ||
| 437 | fault_t fault; | ||
| 438 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 439 | unsigned int Rm = BITS(inst, 0, 3); | ||
| 440 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 441 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | ||
| 442 | unsigned int addr; | ||
| 443 | if (U_BIT) { | ||
| 444 | addr = rn + rm; | ||
| 445 | } else { | ||
| 446 | addr = rn - rm; | ||
| 447 | } | ||
| 448 | virt_addr = addr; | ||
| 449 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 450 | if(fault) | ||
| 451 | return fault; | ||
| 452 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | ||
| 453 | cpu->Reg[Rn] = addr; | ||
| 454 | } | ||
| 455 | return fault; | ||
| 456 | } | ||
| 457 | fault_t LnSWoUB(ScaledRegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | ||
| 458 | fault_t fault; | ||
| 459 | unsigned int shift = BITS(inst, 5, 6); | ||
| 460 | unsigned int shift_imm = BITS(inst, 7, 11); | ||
| 461 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 462 | unsigned int Rm = BITS(inst, 0, 3); | ||
| 463 | unsigned int index; | ||
| 464 | unsigned int addr; | ||
| 465 | |||
| 466 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | ||
| 467 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 468 | |||
| 469 | switch (shift) { | ||
| 470 | case 0: | ||
| 471 | index = rm << shift_imm; | ||
| 472 | break; | ||
| 473 | case 1: | ||
| 474 | if (shift_imm == 0) { | ||
| 475 | index = 0; | ||
| 476 | } else { | ||
| 477 | index = rm >> shift_imm; | ||
| 478 | } | ||
| 479 | break; | ||
| 480 | case 2: | ||
| 481 | DEBUG_MSG; | ||
| 482 | break; | ||
| 483 | case 3: | ||
| 484 | DEBUG_MSG; | ||
| 485 | break; | ||
| 486 | } | ||
| 487 | if (U_BIT) { | ||
| 488 | addr = rn + index; | ||
| 489 | } else | ||
| 490 | addr = rn - index; | ||
| 491 | virt_addr = addr; | ||
| 492 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 493 | if(fault) | ||
| 494 | return fault; | ||
| 495 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | ||
| 496 | cpu->Reg[Rn] = addr; | ||
| 497 | } | ||
| 491 | 498 | ||
| 492 | virt_addr = addr; | 499 | return fault; |
| 493 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 500 | } |
| 494 | if (fault) return fault; | 501 | |
| 502 | fault_t LnSWoUB(ScaledRegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | ||
| 503 | fault_t fault; | ||
| 504 | unsigned int shift = BITS(inst, 5, 6); | ||
| 505 | unsigned int shift_imm = BITS(inst, 7, 11); | ||
| 506 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 507 | unsigned int Rm = BITS(inst, 0, 3); | ||
| 508 | unsigned int index; | ||
| 509 | unsigned int addr; | ||
| 510 | |||
| 511 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | ||
| 512 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 513 | addr = rn; | ||
| 514 | switch (shift) { | ||
| 515 | case 0: | ||
| 516 | index = rm << shift_imm; | ||
| 517 | break; | ||
| 518 | case 1: | ||
| 519 | if (shift_imm == 0) { | ||
| 520 | index = 0; | ||
| 521 | } else { | ||
| 522 | index = rm >> shift_imm; | ||
| 523 | } | ||
| 524 | break; | ||
| 525 | case 2: | ||
| 526 | DEBUG_MSG; | ||
| 527 | break; | ||
| 528 | case 3: | ||
| 529 | DEBUG_MSG; | ||
| 530 | break; | ||
| 531 | } | ||
| 532 | virt_addr = addr; | ||
| 533 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 534 | if(fault) | ||
| 535 | return fault; | ||
| 536 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | ||
| 537 | if (U_BIT) | ||
| 538 | cpu->Reg[Rn] += index; | ||
| 539 | else | ||
| 540 | cpu->Reg[Rn] -= index; | ||
| 541 | } | ||
| 495 | 542 | ||
| 496 | if (U_BIT) { | 543 | return fault; |
| 497 | cpu->Reg[Rn] += OFFSET_12; | ||
| 498 | } else { | ||
| 499 | cpu->Reg[Rn] -= OFFSET_12; | ||
| 500 | } | ||
| 501 | return fault; | ||
| 502 | } | 544 | } |
| 503 | 545 | ||
| 504 | fault_t LnSWoUB(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 546 | fault_t LnSWoUB(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 505 | { | 547 | fault_t fault; |
| 506 | fault_t fault; | 548 | unsigned int Rn = BITS(inst, 16, 19); |
| 507 | unsigned int Rn = BITS(inst, 16, 19); | 549 | unsigned int Rm = BITS(inst, 0, 3); |
| 508 | unsigned int addr; | 550 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 509 | if (U_BIT) { | 551 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 510 | addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; | 552 | |
| 511 | } else { | 553 | unsigned int addr = rn; |
| 512 | addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; | 554 | virt_addr = addr; |
| 513 | } | 555 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 514 | #if 0 | 556 | if (fault) return fault; |
| 515 | if (Rn == 15) { | 557 | |
| 516 | addr += 8; | 558 | if (CondPassed(cpu, BITS(inst, 28, 31))) { |
| 517 | } | 559 | if (U_BIT) { |
| 518 | #endif | 560 | cpu->Reg[Rn] += rm; |
| 519 | 561 | } else { | |
| 520 | virt_addr = addr; | 562 | cpu->Reg[Rn] -= rm; |
| 521 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 563 | } |
| 522 | if (fault) return fault; | 564 | } |
| 523 | 565 | return fault; | |
| 524 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 566 | } |
| 525 | cpu->Reg[Rn] = addr; | 567 | |
| 526 | } | 568 | fault_t MLnS(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 527 | return fault; | 569 | fault_t fault; |
| 528 | } | 570 | unsigned int immedL = BITS(inst, 0, 3); |
| 529 | 571 | unsigned int immedH = BITS(inst, 8, 11); | |
| 530 | fault_t MLnS(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 572 | |
| 531 | { | 573 | unsigned int Rn = BITS(inst, 16, 19); |
| 532 | fault_t fault; | 574 | unsigned int addr; |
| 533 | unsigned int addr; | 575 | |
| 534 | unsigned int Rn = BITS(inst, 16, 19); | 576 | unsigned int offset_8 = (immedH << 4) | immedL; |
| 535 | unsigned int Rm = BITS(inst, 0, 3); | 577 | if (U_BIT) { |
| 536 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 578 | addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8; |
| 537 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 579 | } else |
| 538 | //if (Rn == 15) rn += 8; | 580 | addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8; |
| 539 | //if (Rm == 15) rm += 8; | 581 | |
| 540 | if (U_BIT) { | 582 | virt_addr = addr; |
| 541 | addr = rn + rm; | 583 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 542 | } else | 584 | return fault; |
| 543 | addr = rn - rm; | 585 | } |
| 544 | if(BIT(inst, 20)){ /* L BIT */ | 586 | |
| 545 | } | 587 | fault_t MLnS(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 546 | if(BIT(inst, 6)){ /* Sign Bit */ | 588 | fault_t fault; |
| 547 | } | 589 | unsigned int addr; |
| 548 | if(BIT(inst, 5)){ /* Half Bit */ | 590 | unsigned int Rn = BITS(inst, 16, 19); |
| 549 | } | 591 | unsigned int Rm = BITS(inst, 0, 3); |
| 550 | 592 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | |
| 551 | virt_addr = addr; | 593 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 552 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 594 | if (U_BIT) { |
| 553 | if (fault) return fault; | 595 | addr = rn + rm; |
| 554 | 596 | } else | |
| 555 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 597 | addr = rn - rm; |
| 556 | cpu->Reg[Rn] = addr; | 598 | if(BIT(inst, 20)){ // L BIT |
| 557 | } | 599 | } |
| 558 | return fault; | 600 | if(BIT(inst, 6)){ // Sign Bit |
| 559 | } | 601 | } |
| 560 | 602 | if(BIT(inst, 5)){ // Half Bit | |
| 561 | fault_t LnSWoUB(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 603 | } |
| 562 | { | 604 | virt_addr = addr; |
| 563 | fault_t fault; | 605 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 564 | unsigned int Rn = BITS(inst, 16, 19); | 606 | return fault; |
| 565 | unsigned int Rm = BITS(inst, 0, 3); | 607 | } |
| 566 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 608 | |
| 567 | //if (Rn == 15) rn += 8; | 609 | fault_t MLnS(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 568 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 610 | fault_t fault; |
| 569 | //if (Rm == 15) rm += 8; | 611 | unsigned int Rn = BITS(inst, 16, 19); |
| 570 | unsigned int addr; | 612 | unsigned int immedH = BITS(inst, 8, 11); |
| 571 | if (U_BIT) { | 613 | unsigned int immedL = BITS(inst, 0, 3); |
| 572 | addr = rn + rm; | 614 | unsigned int addr; |
| 573 | } else { | 615 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 574 | addr = rn - rm; | 616 | unsigned int offset_8 = (immedH << 4) | immedL; |
| 575 | } | 617 | |
| 576 | virt_addr = addr; | 618 | if (U_BIT) { |
| 577 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 619 | addr = rn + offset_8; |
| 578 | if(fault) | 620 | } else |
| 579 | return fault; | 621 | addr = rn - offset_8; |
| 580 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 622 | |
| 581 | cpu->Reg[Rn] = addr; | 623 | virt_addr = addr; |
| 582 | } | 624 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 583 | return fault; | 625 | if (fault) return fault; |
| 584 | } | 626 | |
| 585 | fault_t LnSWoUB(ScaledRegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 627 | if (CondPassed(cpu, BITS(inst, 28, 31))) { |
| 586 | { | 628 | cpu->Reg[Rn] = addr; |
| 587 | fault_t fault; | 629 | } |
| 588 | unsigned int shift = BITS(inst, 5, 6); | 630 | return fault; |
| 589 | unsigned int shift_imm = BITS(inst, 7, 11); | 631 | } |
| 590 | unsigned int Rn = BITS(inst, 16, 19); | 632 | |
| 591 | unsigned int Rm = BITS(inst, 0, 3); | 633 | fault_t MLnS(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 592 | unsigned int index; | 634 | fault_t fault; |
| 593 | unsigned int addr; | 635 | unsigned int Rn = BITS(inst, 16, 19); |
| 594 | 636 | unsigned int immedH = BITS(inst, 8, 11); | |
| 595 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 637 | unsigned int immedL = BITS(inst, 0, 3); |
| 596 | //if (Rm == 15) rm += 8; | 638 | unsigned int addr; |
| 597 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 639 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 598 | //if (Rn == 15) rn += 8; | 640 | addr = rn; |
| 599 | switch (shift) { | 641 | |
| 600 | case 0: | 642 | virt_addr = addr; |
| 601 | //DEBUG_MSG; | 643 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 602 | index = rm << shift_imm; | 644 | if (fault) return fault; |
| 603 | break; | 645 | |
| 604 | case 1: | 646 | if (CondPassed(cpu, BITS(inst, 28, 31))) { |
| 605 | // DEBUG_MSG; | 647 | unsigned int offset_8 = (immedH << 4) | immedL; |
| 606 | if (shift_imm == 0) { | 648 | if (U_BIT) { |
| 607 | index = 0; | 649 | rn += offset_8; |
| 608 | } else { | 650 | } else { |
| 609 | index = rm >> shift_imm; | 651 | rn -= offset_8; |
| 610 | } | 652 | } |
| 611 | break; | 653 | cpu->Reg[Rn] = rn; |
| 612 | case 2: | 654 | } |
| 613 | DEBUG_MSG; | 655 | |
| 614 | break; | 656 | return fault; |
| 615 | case 3: | 657 | } |
| 616 | DEBUG_MSG; | 658 | fault_t MLnS(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 617 | break; | 659 | fault_t fault; |
| 618 | } | 660 | unsigned int Rn = BITS(inst, 16, 19); |
| 619 | if (U_BIT) { | 661 | unsigned int Rm = BITS(inst, 0, 3); |
| 620 | addr = rn + index; | 662 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 621 | } else | 663 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 622 | addr = rn - index; | 664 | unsigned int addr = rn; |
| 623 | virt_addr = addr; | 665 | |
| 624 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 666 | virt_addr = addr; |
| 625 | if(fault) | 667 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 626 | return fault; | 668 | if (fault) return fault; |
| 627 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 669 | |
| 628 | cpu->Reg[Rn] = addr; | 670 | if (CondPassed(cpu, BITS(inst, 28, 31))) { |
| 629 | } | 671 | if (U_BIT) { |
| 630 | 672 | cpu->Reg[Rn] += rm; | |
| 631 | return fault; | 673 | } else { |
| 632 | } | 674 | cpu->Reg[Rn] -= rm; |
| 633 | 675 | } | |
| 634 | fault_t LnSWoUB(ScaledRegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 676 | } |
| 635 | { | 677 | return fault; |
| 636 | fault_t fault; | 678 | } |
| 637 | unsigned int shift = BITS(inst, 5, 6); | 679 | |
| 638 | unsigned int shift_imm = BITS(inst, 7, 11); | 680 | fault_t LdnStM(DecrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 639 | unsigned int Rn = BITS(inst, 16, 19); | 681 | fault_t fault; |
| 640 | unsigned int Rm = BITS(inst, 0, 3); | 682 | unsigned int Rn = BITS(inst, 16, 19); |
| 641 | unsigned int index; | 683 | unsigned int i = BITS(inst, 0, 15); |
| 642 | unsigned int addr; | 684 | int count = 0; |
| 643 | 685 | while(i) { | |
| 644 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 686 | if(i & 1) count ++; |
| 645 | //if (Rm == 15) rm += 8; | 687 | i = i >> 1; |
| 646 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 688 | } |
| 647 | //if (Rn == 15) rn += 8; | 689 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 648 | addr = rn; | 690 | unsigned int start_addr = rn - count * 4; |
| 649 | switch (shift) { | 691 | unsigned int end_addr = rn - 4; |
| 650 | case 0: | 692 | |
| 651 | //DEBUG_MSG; | 693 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); |
| 652 | index = rm << shift_imm; | 694 | virt_addr = end_addr; |
| 653 | break; | 695 | if (fault) return fault; |
| 654 | case 1: | 696 | |
| 655 | // DEBUG_MSG; | 697 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); |
| 656 | if (shift_imm == 0) { | 698 | virt_addr = start_addr; |
| 657 | index = 0; | 699 | if (fault) return fault; |
| 658 | } else { | 700 | |
| 659 | index = rm >> shift_imm; | 701 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { |
| 660 | } | 702 | cpu->Reg[Rn] -= count * 4; |
| 661 | break; | 703 | } |
| 662 | case 2: | 704 | |
| 663 | DEBUG_MSG; | 705 | return fault; |
| 664 | break; | 706 | } |
| 665 | case 3: | 707 | |
| 666 | DEBUG_MSG; | 708 | fault_t LdnStM(IncrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 667 | break; | 709 | fault_t fault; |
| 668 | } | 710 | unsigned int Rn = BITS(inst, 16, 19); |
| 669 | virt_addr = addr; | 711 | unsigned int i = BITS(inst, 0, 15); |
| 670 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 712 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 671 | if(fault) | 713 | int count = 0; |
| 672 | return fault; | 714 | while(i) { |
| 673 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 715 | if(i & 1) count ++; |
| 674 | if (U_BIT) | 716 | i = i >> 1; |
| 675 | cpu->Reg[Rn] += index; | 717 | } |
| 676 | else | 718 | |
| 677 | cpu->Reg[Rn] -= index; | 719 | unsigned int start_addr = rn + 4; |
| 678 | } | 720 | unsigned int end_addr = rn + count * 4; |
| 679 | 721 | ||
| 680 | return fault; | 722 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); |
| 681 | } | 723 | virt_addr = end_addr; |
| 682 | 724 | if (fault) return fault; | |
| 683 | fault_t LnSWoUB(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 725 | |
| 684 | { | 726 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); |
| 685 | fault_t fault; | 727 | virt_addr = start_addr; |
| 686 | unsigned int Rn = BITS(inst, 16, 19); | 728 | if (fault) return fault; |
| 687 | unsigned int Rm = BITS(inst, 0, 3); | 729 | |
| 688 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 730 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { |
| 689 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 731 | cpu->Reg[Rn] += count * 4; |
| 690 | 732 | } | |
| 691 | unsigned int addr = rn; | 733 | return fault; |
| 692 | virt_addr = addr; | 734 | } |
| 693 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 735 | |
| 694 | if (fault) return fault; | 736 | fault_t LdnStM(IncrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 695 | 737 | fault_t fault; | |
| 696 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 738 | unsigned int Rn = BITS(inst, 16, 19); |
| 697 | if (U_BIT) { | 739 | unsigned int i = BITS(inst, 0, 15); |
| 698 | cpu->Reg[Rn] += rm; | 740 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 699 | } else { | 741 | int count = 0; |
| 700 | cpu->Reg[Rn] -= rm; | 742 | while(i) { |
| 701 | } | 743 | if(i & 1) count ++; |
| 702 | } | 744 | i = i >> 1; |
| 703 | return fault; | 745 | } |
| 704 | } | 746 | unsigned int start_addr = rn; |
| 705 | 747 | unsigned int end_addr = rn + count * 4 - 4; | |
| 706 | fault_t MLnS(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 748 | |
| 707 | { | 749 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); |
| 708 | fault_t fault; | 750 | virt_addr = end_addr; |
| 709 | unsigned int immedL = BITS(inst, 0, 3); | 751 | if (fault) return fault; |
| 710 | unsigned int immedH = BITS(inst, 8, 11); | 752 | |
| 711 | 753 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); | |
| 712 | unsigned int Rn = BITS(inst, 16, 19); | 754 | virt_addr = start_addr; |
| 713 | unsigned int addr; | 755 | if (fault) return fault; |
| 714 | 756 | ||
| 715 | unsigned int offset_8 = (immedH << 4) | immedL; | 757 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { |
| 716 | if (U_BIT) { | 758 | cpu->Reg[Rn] += count * 4; |
| 717 | addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8; | 759 | } |
| 718 | } else | 760 | return fault; |
| 719 | addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8; | 761 | } |
| 720 | #if 0 | 762 | |
| 721 | if (Rn == 15) { | 763 | fault_t LdnStM(DecrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 722 | addr += 8; | 764 | fault_t fault; |
| 723 | } | 765 | unsigned int Rn = BITS(inst, 16, 19); |
| 724 | #endif | 766 | unsigned int i = BITS(inst, 0, 15); |
| 725 | virt_addr = addr; | 767 | int count = 0; |
| 726 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 768 | while(i) { |
| 727 | return fault; | 769 | if(i & 1) count ++; |
| 728 | } | 770 | i = i >> 1; |
| 729 | 771 | } | |
| 730 | fault_t MLnS(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 772 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 731 | { | 773 | unsigned int start_addr = rn - count * 4 + 4; |
| 732 | fault_t fault; | 774 | unsigned int end_addr = rn; |
| 733 | unsigned int addr; | 775 | |
| 734 | unsigned int Rn = BITS(inst, 16, 19); | 776 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); |
| 735 | unsigned int Rm = BITS(inst, 0, 3); | 777 | virt_addr = end_addr; |
| 736 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 778 | if (fault) return fault; |
| 737 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 779 | |
| 738 | //if (Rn == 15) rn += 8; | 780 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); |
| 739 | //if (Rm == 15) rm += 8; | 781 | if (fault) return fault; |
| 740 | if (U_BIT) { | 782 | virt_addr = start_addr; |
| 741 | addr = rn + rm; | 783 | |
| 742 | } else | 784 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { |
| 743 | addr = rn - rm; | 785 | cpu->Reg[Rn] -= count * 4; |
| 744 | if(BIT(inst, 20)){ /* L BIT */ | 786 | } |
| 745 | } | 787 | return fault; |
| 746 | if(BIT(inst, 6)){ /* Sign Bit */ | 788 | } |
| 747 | } | 789 | |
| 748 | if(BIT(inst, 5)){ /* Half Bit */ | 790 | fault_t LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 749 | } | 791 | fault_t fault; |
| 750 | virt_addr = addr; | 792 | unsigned int shift = BITS(inst, 5, 6); |
| 751 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 793 | unsigned int shift_imm = BITS(inst, 7, 11); |
| 752 | return fault; | 794 | unsigned int Rn = BITS(inst, 16, 19); |
| 753 | } | 795 | unsigned int Rm = BITS(inst, 0, 3); |
| 754 | 796 | unsigned int index; | |
| 755 | fault_t MLnS(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 797 | unsigned int addr; |
| 756 | { | 798 | |
| 757 | fault_t fault; | 799 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 758 | unsigned int Rn = BITS(inst, 16, 19); | 800 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 759 | unsigned int immedH = BITS(inst, 8, 11); | 801 | switch (shift) { |
| 760 | unsigned int immedL = BITS(inst, 0, 3); | 802 | case 0: |
| 761 | unsigned int addr; | 803 | index = rm << shift_imm; |
| 762 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 804 | break; |
| 763 | //if (Rn == 15) rn += 8; | 805 | case 1: |
| 764 | 806 | if (shift_imm == 0) { | |
| 765 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | 807 | index = 0; |
| 766 | unsigned int offset_8 = (immedH << 4) | immedL; | 808 | } else { |
| 767 | if (U_BIT) { | 809 | index = rm >> shift_imm; |
| 768 | addr = rn + offset_8; | 810 | } |
| 769 | } else | 811 | break; |
| 770 | addr = rn - offset_8; | 812 | case 2: |
| 771 | 813 | if (shift_imm == 0){ // ASR #32 | |
| 772 | virt_addr = addr; | 814 | if (rm >> 31) |
| 773 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 815 | index = 0xFFFFFFFF; |
| 774 | if (fault) return fault; | 816 | else |
| 775 | 817 | index = 0; | |
| 776 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 818 | } |
| 777 | cpu->Reg[Rn] = addr; | 819 | else { |
| 778 | } | 820 | index = static_cast<int>(rm) >> shift_imm; |
| 779 | return fault; | 821 | } |
| 780 | } | 822 | break; |
| 781 | 823 | case 3: | |
| 782 | fault_t MLnS(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 824 | DEBUG_MSG; |
| 783 | { | 825 | break; |
| 784 | fault_t fault; | 826 | } |
| 785 | unsigned int Rn = BITS(inst, 16, 19); | 827 | if (U_BIT) { |
| 786 | unsigned int immedH = BITS(inst, 8, 11); | 828 | addr = rn + index; |
| 787 | unsigned int immedL = BITS(inst, 0, 3); | 829 | } else |
| 788 | unsigned int addr; | 830 | addr = rn - index; |
| 789 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 831 | |
| 790 | addr = rn; | 832 | virt_addr = addr; |
| 791 | 833 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | |
| 792 | virt_addr = addr; | 834 | |
| 793 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 835 | return fault; |
| 794 | if (fault) return fault; | 836 | } |
| 795 | 837 | ||
| 796 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 838 | #define ISNEG(n) (n < 0) |
| 797 | unsigned int offset_8 = (immedH << 4) | immedL; | 839 | #define ISPOS(n) (n >= 0) |
| 798 | if (U_BIT) { | ||
| 799 | rn += offset_8; | ||
| 800 | } else { | ||
| 801 | rn -= offset_8; | ||
| 802 | } | ||
| 803 | cpu->Reg[Rn] = rn; | ||
| 804 | } | ||
| 805 | |||
| 806 | return fault; | ||
| 807 | } | ||
| 808 | fault_t MLnS(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | ||
| 809 | { | ||
| 810 | fault_t fault; | ||
| 811 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 812 | unsigned int Rm = BITS(inst, 0, 3); | ||
| 813 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | ||
| 814 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 815 | |||
| 816 | unsigned int addr = rn; | ||
| 817 | virt_addr = addr; | ||
| 818 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 819 | if (fault) return fault; | ||
| 820 | |||
| 821 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | ||
| 822 | if (U_BIT) { | ||
| 823 | cpu->Reg[Rn] += rm; | ||
| 824 | } else { | ||
| 825 | cpu->Reg[Rn] -= rm; | ||
| 826 | } | ||
| 827 | } | ||
| 828 | return fault; | ||
| 829 | } | ||
| 830 | |||
| 831 | fault_t LdnStM(DecrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | ||
| 832 | { | ||
| 833 | fault_t fault; | ||
| 834 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 835 | unsigned int i = BITS(inst, 0, 15); | ||
| 836 | int count = 0; | ||
| 837 | while(i) { | ||
| 838 | if(i & 1) count ++; | ||
| 839 | i = i >> 1; | ||
| 840 | } | ||
| 841 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 842 | //if (Rn == 15) rn += 8; | ||
| 843 | unsigned int start_addr = rn - count * 4; | ||
| 844 | unsigned int end_addr = rn - 4; | ||
| 845 | |||
| 846 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); | ||
| 847 | virt_addr = end_addr; | ||
| 848 | if (fault) return fault; | ||
| 849 | |||
| 850 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); | ||
| 851 | virt_addr = start_addr; | ||
| 852 | if (fault) return fault; | ||
| 853 | |||
| 854 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { | ||
| 855 | cpu->Reg[Rn] -= count * 4; | ||
| 856 | } | ||
| 857 | |||
| 858 | return fault; | ||
| 859 | } | ||
| 860 | |||
| 861 | fault_t LdnStM(IncrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | ||
| 862 | { | ||
| 863 | fault_t fault; | ||
| 864 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 865 | unsigned int i = BITS(inst, 0, 15); | ||
| 866 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 867 | //if (Rn == 15) rn += 8; | ||
| 868 | int count = 0; | ||
| 869 | while(i) { | ||
| 870 | if(i & 1) count ++; | ||
| 871 | i = i >> 1; | ||
| 872 | } | ||
| 873 | |||
| 874 | unsigned int start_addr = rn + 4; | ||
| 875 | unsigned int end_addr = rn + count * 4; | ||
| 876 | |||
| 877 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); | ||
| 878 | virt_addr = end_addr; | ||
| 879 | if (fault) return fault; | ||
| 880 | |||
| 881 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); | ||
| 882 | virt_addr = start_addr; | ||
| 883 | if (fault) return fault; | ||
| 884 | |||
| 885 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { | ||
| 886 | cpu->Reg[Rn] += count * 4; | ||
| 887 | } | ||
| 888 | return fault; | ||
| 889 | } | ||
| 890 | |||
| 891 | fault_t LdnStM(IncrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | ||
| 892 | { | ||
| 893 | fault_t fault; | ||
| 894 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 895 | unsigned int i = BITS(inst, 0, 15); | ||
| 896 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 897 | int count = 0; | ||
| 898 | while(i) { | ||
| 899 | if(i & 1) count ++; | ||
| 900 | i = i >> 1; | ||
| 901 | } | ||
| 902 | //if (Rn == 15) rn += 8; | ||
| 903 | unsigned int start_addr = rn; | ||
| 904 | unsigned int end_addr = rn + count * 4 - 4; | ||
| 905 | |||
| 906 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); | ||
| 907 | virt_addr = end_addr; | ||
| 908 | if (fault) return fault; | ||
| 909 | |||
| 910 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); | ||
| 911 | virt_addr = start_addr; | ||
| 912 | if (fault) return fault; | ||
| 913 | |||
| 914 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { | ||
| 915 | cpu->Reg[Rn] += count * 4; | ||
| 916 | } | ||
| 917 | return fault; | ||
| 918 | } | ||
| 919 | |||
| 920 | fault_t LdnStM(DecrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | ||
| 921 | { | ||
| 922 | fault_t fault; | ||
| 923 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 924 | unsigned int i = BITS(inst, 0, 15); | ||
| 925 | int count = 0; | ||
| 926 | while(i) { | ||
| 927 | if(i & 1) count ++; | ||
| 928 | i = i >> 1; | ||
| 929 | } | ||
| 930 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 931 | //if (Rn == 15) rn += 8; | ||
| 932 | unsigned int start_addr = rn - count * 4 + 4; | ||
| 933 | unsigned int end_addr = rn; | ||
| 934 | |||
| 935 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); | ||
| 936 | virt_addr = end_addr; | ||
| 937 | if (fault) return fault; | ||
| 938 | |||
| 939 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); | ||
| 940 | if (fault) return fault; | ||
| 941 | virt_addr = start_addr; | ||
| 942 | |||
| 943 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { | ||
| 944 | cpu->Reg[Rn] -= count * 4; | ||
| 945 | } | ||
| 946 | return fault; | ||
| 947 | } | ||
| 948 | |||
| 949 | fault_t LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | ||
| 950 | { | ||
| 951 | fault_t fault; | ||
| 952 | unsigned int shift = BITS(inst, 5, 6); | ||
| 953 | unsigned int shift_imm = BITS(inst, 7, 11); | ||
| 954 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 955 | unsigned int Rm = BITS(inst, 0, 3); | ||
| 956 | unsigned int index; | ||
| 957 | unsigned int addr; | ||
| 958 | |||
| 959 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | ||
| 960 | //if (Rm == 15) rm += 8; | ||
| 961 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 962 | //if (Rn == 15) rn += 8; | ||
| 963 | switch (shift) { | ||
| 964 | case 0: | ||
| 965 | //DEBUG_MSG; | ||
| 966 | index = rm << shift_imm; | ||
| 967 | break; | ||
| 968 | case 1: | ||
| 969 | // DEBUG_MSG; | ||
| 970 | if (shift_imm == 0) { | ||
| 971 | index = 0; | ||
| 972 | } else { | ||
| 973 | index = rm >> shift_imm; | ||
| 974 | } | ||
| 975 | break; | ||
| 976 | case 2: | ||
| 977 | if (shift_imm == 0){ /* ASR #32 */ | ||
| 978 | if (rm >> 31) | ||
| 979 | index = 0xFFFFFFFF; | ||
| 980 | else | ||
| 981 | index = 0; | ||
| 982 | } | ||
| 983 | else { | ||
| 984 | index = static_cast<int>(rm) >> shift_imm; | ||
| 985 | } | ||
| 986 | break; | ||
| 987 | case 3: | ||
| 988 | DEBUG_MSG; | ||
| 989 | break; | ||
| 990 | } | ||
| 991 | if (U_BIT) { | ||
| 992 | addr = rn + index; | ||
| 993 | } else | ||
| 994 | addr = rn - index; | ||
| 995 | virt_addr = addr; | ||
| 996 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 997 | return fault; | ||
| 998 | } | ||
| 999 | |||
| 1000 | #define ISNEG(n) (n < 0) | ||
| 1001 | #define ISPOS(n) (n >= 0) | ||
| 1002 | |||
| 1003 | //enum { | ||
| 1004 | // COND = (1 << 0), | ||
| 1005 | // NON_BRANCH = (1 << 1), | ||
| 1006 | // DIRECT_BRANCH = (1 << 2), | ||
| 1007 | // INDIRECT_BRANCH = (1 << 3), | ||
| 1008 | // CALL = (1 << 4), | ||
| 1009 | // RET = (1 << 5), | ||
| 1010 | // END_OF_PAGE = (1 << 6), | ||
| 1011 | // THUMB = (1 << 7) | ||
| 1012 | //}; | ||
| 1013 | 840 | ||
| 1014 | typedef struct _arm_inst { | 841 | typedef struct _arm_inst { |
| 1015 | unsigned int idx; | 842 | unsigned int idx; |
| 1016 | unsigned int cond; | 843 | unsigned int cond; |
| 1017 | int br; | 844 | int br; |
| 1018 | int load_r15; | 845 | int load_r15; |
| 1019 | char component[0]; | 846 | char component[0]; |
| 1020 | } arm_inst; | 847 | } arm_inst; |
| 1021 | 848 | ||
| 1022 | typedef struct generic_arm_inst { | 849 | typedef struct generic_arm_inst { |
| 1023 | u32 Ra; | 850 | u32 Ra; |
| 1024 | u32 Rm; | 851 | u32 Rm; |
| 1025 | u32 Rn; | 852 | u32 Rn; |
| 1026 | u32 Rd; | 853 | u32 Rd; |
| 1027 | u8 op1; | 854 | u8 op1; |
| 1028 | u8 op2; | 855 | u8 op2; |
| 1029 | } generic_arm_inst; | 856 | } generic_arm_inst; |
| 1030 | 857 | ||
| 1031 | typedef struct _adc_inst { | 858 | typedef struct _adc_inst { |
| 1032 | unsigned int I; | 859 | unsigned int I; |
| 1033 | unsigned int S; | 860 | unsigned int S; |
| 1034 | unsigned int Rn; | 861 | unsigned int Rn; |
| 1035 | unsigned int Rd; | 862 | unsigned int Rd; |
| 1036 | unsigned int shifter_operand; | 863 | unsigned int shifter_operand; |
| 1037 | shtop_fp_t shtop_func; | 864 | shtop_fp_t shtop_func; |
| 1038 | } adc_inst; | 865 | } adc_inst; |
| 1039 | 866 | ||
| 1040 | typedef struct _add_inst { | 867 | typedef struct _add_inst { |
| 1041 | unsigned int I; | 868 | unsigned int I; |
| 1042 | unsigned int S; | 869 | unsigned int S; |
| 1043 | unsigned int Rn; | 870 | unsigned int Rn; |
| 1044 | unsigned int Rd; | 871 | unsigned int Rd; |
| 1045 | unsigned int shifter_operand; | 872 | unsigned int shifter_operand; |
| 1046 | shtop_fp_t shtop_func; | 873 | shtop_fp_t shtop_func; |
| 1047 | } add_inst; | 874 | } add_inst; |
| 1048 | 875 | ||
| 1049 | typedef struct _orr_inst { | 876 | typedef struct _orr_inst { |
| 1050 | unsigned int I; | 877 | unsigned int I; |
| 1051 | unsigned int S; | 878 | unsigned int S; |
| 1052 | unsigned int Rn; | 879 | unsigned int Rn; |
| 1053 | unsigned int Rd; | 880 | unsigned int Rd; |
| 1054 | unsigned int shifter_operand; | 881 | unsigned int shifter_operand; |
| 1055 | shtop_fp_t shtop_func; | 882 | shtop_fp_t shtop_func; |
| 1056 | } orr_inst; | 883 | } orr_inst; |
| 1057 | 884 | ||
| 1058 | typedef struct _and_inst { | 885 | typedef struct _and_inst { |
| 1059 | unsigned int I; | 886 | unsigned int I; |
| 1060 | unsigned int S; | 887 | unsigned int S; |
| 1061 | unsigned int Rn; | 888 | unsigned int Rn; |
| 1062 | unsigned int Rd; | 889 | unsigned int Rd; |
| 1063 | unsigned int shifter_operand; | 890 | unsigned int shifter_operand; |
| 1064 | shtop_fp_t shtop_func; | 891 | shtop_fp_t shtop_func; |
| 1065 | } and_inst; | 892 | } and_inst; |
| 1066 | 893 | ||
| 1067 | typedef struct _eor_inst { | 894 | typedef struct _eor_inst { |
| 1068 | unsigned int I; | 895 | unsigned int I; |
| 1069 | unsigned int S; | 896 | unsigned int S; |
| 1070 | unsigned int Rn; | 897 | unsigned int Rn; |
| 1071 | unsigned int Rd; | 898 | unsigned int Rd; |
| 1072 | unsigned int shifter_operand; | 899 | unsigned int shifter_operand; |
| 1073 | shtop_fp_t shtop_func; | 900 | shtop_fp_t shtop_func; |
| 1074 | } eor_inst; | 901 | } eor_inst; |
| 1075 | 902 | ||
| 1076 | typedef struct _bbl_inst { | 903 | typedef struct _bbl_inst { |
| 1077 | unsigned int L; | 904 | unsigned int L; |
| 1078 | int signed_immed_24; | 905 | int signed_immed_24; |
| 1079 | unsigned int next_addr; | 906 | unsigned int next_addr; |
| 1080 | unsigned int jmp_addr; | 907 | unsigned int jmp_addr; |
| 1081 | } bbl_inst; | 908 | } bbl_inst; |
| 1082 | 909 | ||
| 1083 | typedef struct _bx_inst { | 910 | typedef struct _bx_inst { |
| 1084 | unsigned int Rm; | 911 | unsigned int Rm; |
| 1085 | } bx_inst; | 912 | } bx_inst; |
| 1086 | 913 | ||
| 1087 | typedef struct _blx_inst { | 914 | typedef struct _blx_inst { |
| 1088 | union { | 915 | union { |
| 1089 | int32_t signed_immed_24; | 916 | int32_t signed_immed_24; |
| 1090 | uint32_t Rm; | 917 | uint32_t Rm; |
| 1091 | } val; | 918 | } val; |
| 1092 | unsigned int inst; | 919 | unsigned int inst; |
| 1093 | } blx_inst; | 920 | } blx_inst; |
| 1094 | 921 | ||
| 1095 | typedef struct _clz_inst { | 922 | typedef struct _clz_inst { |
| 1096 | unsigned int Rm; | 923 | unsigned int Rm; |
| 1097 | unsigned int Rd; | 924 | unsigned int Rd; |
| 1098 | } clz_inst; | 925 | } clz_inst; |
| 1099 | 926 | ||
| 1100 | typedef struct _cps_inst { | 927 | typedef struct _cps_inst { |
| 1101 | unsigned int imod0; | 928 | unsigned int imod0; |
| 1102 | unsigned int imod1; | 929 | unsigned int imod1; |
| 1103 | unsigned int mmod; | 930 | unsigned int mmod; |
| 1104 | unsigned int A, I, F; | 931 | unsigned int A, I, F; |
| 1105 | unsigned int mode; | 932 | unsigned int mode; |
| 1106 | } cps_inst; | 933 | } cps_inst; |
| 1107 | 934 | ||
| 1108 | typedef struct _clrex_inst { | 935 | typedef struct _clrex_inst { |
| 1109 | } clrex_inst; | 936 | } clrex_inst; |
| 1110 | 937 | ||
| 1111 | typedef struct _cpy_inst { | 938 | typedef struct _cpy_inst { |
| 1112 | unsigned int Rm; | 939 | unsigned int Rm; |
| 1113 | unsigned int Rd; | 940 | unsigned int Rd; |
| 1114 | } cpy_inst; | 941 | } cpy_inst; |
| 1115 | 942 | ||
| 1116 | typedef struct _bic_inst { | 943 | typedef struct _bic_inst { |
| 1117 | unsigned int I; | 944 | unsigned int I; |
| 1118 | unsigned int S; | 945 | unsigned int S; |
| 1119 | unsigned int Rn; | 946 | unsigned int Rn; |
| 1120 | unsigned int Rd; | 947 | unsigned int Rd; |
| 1121 | unsigned int shifter_operand; | 948 | unsigned int shifter_operand; |
| 1122 | shtop_fp_t shtop_func; | 949 | shtop_fp_t shtop_func; |
| 1123 | } bic_inst; | 950 | } bic_inst; |
| 1124 | 951 | ||
| 1125 | typedef struct _sub_inst { | 952 | typedef struct _sub_inst { |
| 1126 | unsigned int I; | 953 | unsigned int I; |
| 1127 | unsigned int S; | 954 | unsigned int S; |
| 1128 | unsigned int Rn; | 955 | unsigned int Rn; |
| 1129 | unsigned int Rd; | 956 | unsigned int Rd; |
| 1130 | unsigned int shifter_operand; | 957 | unsigned int shifter_operand; |
| 1131 | shtop_fp_t shtop_func; | 958 | shtop_fp_t shtop_func; |
| 1132 | } sub_inst; | 959 | } sub_inst; |
| 1133 | 960 | ||
| 1134 | typedef struct _tst_inst { | 961 | typedef struct _tst_inst { |
| 1135 | unsigned int I; | 962 | unsigned int I; |
| 1136 | unsigned int S; | 963 | unsigned int S; |
| 1137 | unsigned int Rn; | 964 | unsigned int Rn; |
| 1138 | unsigned int Rd; | 965 | unsigned int Rd; |
| 1139 | unsigned int shifter_operand; | 966 | unsigned int shifter_operand; |
| 1140 | shtop_fp_t shtop_func; | 967 | shtop_fp_t shtop_func; |
| 1141 | } tst_inst; | 968 | } tst_inst; |
| 1142 | 969 | ||
| 1143 | typedef struct _cmn_inst { | 970 | typedef struct _cmn_inst { |
| 1144 | unsigned int I; | 971 | unsigned int I; |
| 1145 | //unsigned int S; | 972 | unsigned int Rn; |
| 1146 | unsigned int Rn; | 973 | unsigned int shifter_operand; |
| 1147 | //unsigned int Rd; | 974 | shtop_fp_t shtop_func; |
| 1148 | unsigned int shifter_operand; | ||
| 1149 | shtop_fp_t shtop_func; | ||
| 1150 | } cmn_inst; | 975 | } cmn_inst; |
| 1151 | 976 | ||
| 1152 | typedef struct _teq_inst { | 977 | typedef struct _teq_inst { |
| 1153 | unsigned int I; | 978 | unsigned int I; |
| 1154 | unsigned int Rn; | 979 | unsigned int Rn; |
| 1155 | unsigned int shifter_operand; | 980 | unsigned int shifter_operand; |
| 1156 | shtop_fp_t shtop_func; | 981 | shtop_fp_t shtop_func; |
| 1157 | } teq_inst; | 982 | } teq_inst; |
| 1158 | 983 | ||
| 1159 | typedef struct _stm_inst { | 984 | typedef struct _stm_inst { |
| 1160 | unsigned int inst; | 985 | unsigned int inst; |
| 1161 | } stm_inst; | 986 | } stm_inst; |
| 1162 | 987 | ||
| 1163 | struct bkpt_inst { | 988 | struct bkpt_inst { |
| 1164 | }; | 989 | }; |
| 1165 | 990 | ||
| 1166 | struct blx1_inst { | 991 | struct blx1_inst { |
| 1167 | unsigned int addr; | 992 | unsigned int addr; |
| 1168 | }; | 993 | }; |
| 1169 | 994 | ||
| 1170 | struct blx2_inst { | 995 | struct blx2_inst { |
| 1171 | unsigned int Rm; | 996 | unsigned int Rm; |
| 1172 | }; | 997 | }; |
| 1173 | 998 | ||
| 1174 | typedef struct _stc_inst { | 999 | typedef struct _stc_inst { |
| @@ -1178,457 +1003,418 @@ typedef struct _ldc_inst { | |||
| 1178 | } ldc_inst; | 1003 | } ldc_inst; |
| 1179 | 1004 | ||
| 1180 | typedef struct _swi_inst { | 1005 | typedef struct _swi_inst { |
| 1181 | unsigned int num; | 1006 | unsigned int num; |
| 1182 | } swi_inst; | 1007 | } swi_inst; |
| 1183 | 1008 | ||
| 1184 | typedef struct _cmp_inst { | 1009 | typedef struct _cmp_inst { |
| 1185 | unsigned int I; | 1010 | unsigned int I; |
| 1186 | unsigned int Rn; | 1011 | unsigned int Rn; |
| 1187 | unsigned int shifter_operand; | 1012 | unsigned int shifter_operand; |
| 1188 | shtop_fp_t shtop_func; | 1013 | shtop_fp_t shtop_func; |
| 1189 | } cmp_inst; | 1014 | } cmp_inst; |
| 1190 | 1015 | ||
| 1191 | typedef struct _mov_inst { | 1016 | typedef struct _mov_inst { |
| 1192 | unsigned int I; | 1017 | unsigned int I; |
| 1193 | unsigned int S; | 1018 | unsigned int S; |
| 1194 | unsigned int Rd; | 1019 | unsigned int Rd; |
| 1195 | unsigned int shifter_operand; | 1020 | unsigned int shifter_operand; |
| 1196 | shtop_fp_t shtop_func; | 1021 | shtop_fp_t shtop_func; |
| 1197 | } mov_inst; | 1022 | } mov_inst; |
| 1198 | 1023 | ||
| 1199 | typedef struct _mvn_inst { | 1024 | typedef struct _mvn_inst { |
| 1200 | unsigned int I; | 1025 | unsigned int I; |
| 1201 | unsigned int S; | 1026 | unsigned int S; |
| 1202 | unsigned int Rd; | 1027 | unsigned int Rd; |
| 1203 | unsigned int shifter_operand; | 1028 | unsigned int shifter_operand; |
| 1204 | shtop_fp_t shtop_func; | 1029 | shtop_fp_t shtop_func; |
| 1205 | } mvn_inst; | 1030 | } mvn_inst; |
| 1206 | 1031 | ||
| 1207 | typedef struct _rev_inst { | 1032 | typedef struct _rev_inst { |
| 1208 | unsigned int Rd; | 1033 | unsigned int Rd; |
| 1209 | unsigned int Rm; | 1034 | unsigned int Rm; |
| 1210 | } rev_inst; | 1035 | } rev_inst; |
| 1211 | 1036 | ||
| 1212 | typedef struct _rsb_inst { | 1037 | typedef struct _rsb_inst { |
| 1213 | unsigned int I; | 1038 | unsigned int I; |
| 1214 | unsigned int S; | 1039 | unsigned int S; |
| 1215 | unsigned int Rn; | 1040 | unsigned int Rn; |
| 1216 | unsigned int Rd; | 1041 | unsigned int Rd; |
| 1217 | unsigned int shifter_operand; | 1042 | unsigned int shifter_operand; |
| 1218 | shtop_fp_t shtop_func; | 1043 | shtop_fp_t shtop_func; |
| 1219 | } rsb_inst; | 1044 | } rsb_inst; |
| 1220 | 1045 | ||
| 1221 | typedef struct _rsc_inst { | 1046 | typedef struct _rsc_inst { |
| 1222 | unsigned int I; | 1047 | unsigned int I; |
| 1223 | unsigned int S; | 1048 | unsigned int S; |
| 1224 | unsigned int Rn; | 1049 | unsigned int Rn; |
| 1225 | unsigned int Rd; | 1050 | unsigned int Rd; |
| 1226 | unsigned int shifter_operand; | 1051 | unsigned int shifter_operand; |
| 1227 | shtop_fp_t shtop_func; | 1052 | shtop_fp_t shtop_func; |
| 1228 | } rsc_inst; | 1053 | } rsc_inst; |
| 1229 | 1054 | ||
| 1230 | typedef struct _sbc_inst { | 1055 | typedef struct _sbc_inst { |
| 1231 | unsigned int I; | 1056 | unsigned int I; |
| 1232 | unsigned int S; | 1057 | unsigned int S; |
| 1233 | unsigned int Rn; | 1058 | unsigned int Rn; |
| 1234 | unsigned int Rd; | 1059 | unsigned int Rd; |
| 1235 | unsigned int shifter_operand; | 1060 | unsigned int shifter_operand; |
| 1236 | shtop_fp_t shtop_func; | 1061 | shtop_fp_t shtop_func; |
| 1237 | } sbc_inst; | 1062 | } sbc_inst; |
| 1238 | 1063 | ||
| 1239 | typedef struct _mul_inst { | 1064 | typedef struct _mul_inst { |
| 1240 | unsigned int S; | 1065 | unsigned int S; |
| 1241 | unsigned int Rd; | 1066 | unsigned int Rd; |
| 1242 | unsigned int Rs; | 1067 | unsigned int Rs; |
| 1243 | unsigned int Rm; | 1068 | unsigned int Rm; |
| 1244 | } mul_inst; | 1069 | } mul_inst; |
| 1245 | 1070 | ||
| 1246 | typedef struct _smul_inst { | 1071 | typedef struct _smul_inst { |
| 1247 | unsigned int Rd; | 1072 | unsigned int Rd; |
| 1248 | unsigned int Rs; | 1073 | unsigned int Rs; |
| 1249 | unsigned int Rm; | 1074 | unsigned int Rm; |
| 1250 | unsigned int x; | 1075 | unsigned int x; |
| 1251 | unsigned int y; | 1076 | unsigned int y; |
| 1252 | } smul_inst; | 1077 | } smul_inst; |
| 1253 | 1078 | ||
| 1254 | typedef struct _umull_inst { | 1079 | typedef struct _umull_inst { |
| 1255 | unsigned int S; | 1080 | unsigned int S; |
| 1256 | unsigned int RdHi; | 1081 | unsigned int RdHi; |
| 1257 | unsigned int RdLo; | 1082 | unsigned int RdLo; |
| 1258 | unsigned int Rs; | 1083 | unsigned int Rs; |
| 1259 | unsigned int Rm; | 1084 | unsigned int Rm; |
| 1260 | } umull_inst; | 1085 | } umull_inst; |
| 1261 | typedef struct _smlad_inst { | 1086 | typedef struct _smlad_inst { |
| 1262 | unsigned int m; | 1087 | unsigned int m; |
| 1263 | unsigned int Rm; | 1088 | unsigned int Rm; |
| 1264 | unsigned int Rd; | 1089 | unsigned int Rd; |
| 1265 | unsigned int Ra; | 1090 | unsigned int Ra; |
| 1266 | unsigned int Rn; | 1091 | unsigned int Rn; |
| 1267 | } smlad_inst; | 1092 | } smlad_inst; |
| 1268 | 1093 | ||
| 1269 | typedef struct _smla_inst { | 1094 | typedef struct _smla_inst { |
| 1270 | unsigned int x; | 1095 | unsigned int x; |
| 1271 | unsigned int y; | 1096 | unsigned int y; |
| 1272 | unsigned int Rm; | 1097 | unsigned int Rm; |
| 1273 | unsigned int Rd; | 1098 | unsigned int Rd; |
| 1274 | unsigned int Rs; | 1099 | unsigned int Rs; |
| 1275 | unsigned int Rn; | 1100 | unsigned int Rn; |
| 1276 | } smla_inst; | 1101 | } smla_inst; |
| 1277 | 1102 | ||
| 1278 | typedef struct umaal_inst { | 1103 | typedef struct umaal_inst { |
| 1279 | unsigned int Rn; | 1104 | unsigned int Rn; |
| 1280 | unsigned int Rm; | 1105 | unsigned int Rm; |
| 1281 | unsigned int RdHi; | 1106 | unsigned int RdHi; |
| 1282 | unsigned int RdLo; | 1107 | unsigned int RdLo; |
| 1283 | } umaal_inst; | 1108 | } umaal_inst; |
| 1284 | 1109 | ||
| 1285 | typedef struct _umlal_inst { | 1110 | typedef struct _umlal_inst { |
| 1286 | unsigned int S; | 1111 | unsigned int S; |
| 1287 | unsigned int Rm; | 1112 | unsigned int Rm; |
| 1288 | unsigned int Rs; | 1113 | unsigned int Rs; |
| 1289 | unsigned int RdHi; | 1114 | unsigned int RdHi; |
| 1290 | unsigned int RdLo; | 1115 | unsigned int RdLo; |
| 1291 | } umlal_inst; | 1116 | } umlal_inst; |
| 1292 | 1117 | ||
| 1293 | typedef struct _smlal_inst { | 1118 | typedef struct _smlal_inst { |
| 1294 | unsigned int S; | 1119 | unsigned int S; |
| 1295 | unsigned int Rm; | 1120 | unsigned int Rm; |
| 1296 | unsigned int Rs; | 1121 | unsigned int Rs; |
| 1297 | unsigned int RdHi; | 1122 | unsigned int RdHi; |
| 1298 | unsigned int RdLo; | 1123 | unsigned int RdLo; |
| 1299 | } smlal_inst; | 1124 | } smlal_inst; |
| 1300 | 1125 | ||
| 1301 | typedef struct _mla_inst { | 1126 | typedef struct _mla_inst { |
| 1302 | unsigned int S; | 1127 | unsigned int S; |
| 1303 | unsigned int Rn; | 1128 | unsigned int Rn; |
| 1304 | unsigned int Rd; | 1129 | unsigned int Rd; |
| 1305 | unsigned int Rs; | 1130 | unsigned int Rs; |
| 1306 | unsigned int Rm; | 1131 | unsigned int Rm; |
| 1307 | } mla_inst; | 1132 | } mla_inst; |
| 1308 | 1133 | ||
| 1309 | typedef struct _mrc_inst { | 1134 | typedef struct _mrc_inst { |
| 1310 | unsigned int opcode_1; | 1135 | unsigned int opcode_1; |
| 1311 | unsigned int opcode_2; | 1136 | unsigned int opcode_2; |
| 1312 | unsigned int cp_num; | 1137 | unsigned int cp_num; |
| 1313 | unsigned int crn; | 1138 | unsigned int crn; |
| 1314 | unsigned int crm; | 1139 | unsigned int crm; |
| 1315 | unsigned int Rd; | 1140 | unsigned int Rd; |
| 1316 | unsigned int inst; | 1141 | unsigned int inst; |
| 1317 | } mrc_inst; | 1142 | } mrc_inst; |
| 1318 | 1143 | ||
| 1319 | typedef struct _mcr_inst { | 1144 | typedef struct _mcr_inst { |
| 1320 | unsigned int opcode_1; | 1145 | unsigned int opcode_1; |
| 1321 | unsigned int opcode_2; | 1146 | unsigned int opcode_2; |
| 1322 | unsigned int cp_num; | 1147 | unsigned int cp_num; |
| 1323 | unsigned int crn; | 1148 | unsigned int crn; |
| 1324 | unsigned int crm; | 1149 | unsigned int crm; |
| 1325 | unsigned int Rd; | 1150 | unsigned int Rd; |
| 1326 | unsigned int inst; | 1151 | unsigned int inst; |
| 1327 | } mcr_inst; | 1152 | } mcr_inst; |
| 1328 | 1153 | ||
| 1329 | typedef struct _mrs_inst { | 1154 | typedef struct _mrs_inst { |
| 1330 | unsigned int R; | 1155 | unsigned int R; |
| 1331 | unsigned int Rd; | 1156 | unsigned int Rd; |
| 1332 | } mrs_inst; | 1157 | } mrs_inst; |
| 1333 | 1158 | ||
| 1334 | typedef struct _msr_inst { | 1159 | typedef struct _msr_inst { |
| 1335 | unsigned int field_mask; | 1160 | unsigned int field_mask; |
| 1336 | unsigned int R; | 1161 | unsigned int R; |
| 1337 | unsigned int inst; | 1162 | unsigned int inst; |
| 1338 | } msr_inst; | 1163 | } msr_inst; |
| 1339 | 1164 | ||
| 1340 | typedef struct _pld_inst { | 1165 | typedef struct _pld_inst { |
| 1341 | } pld_inst; | 1166 | } pld_inst; |
| 1342 | 1167 | ||
| 1343 | typedef struct _sxtb_inst { | 1168 | typedef struct _sxtb_inst { |
| 1344 | unsigned int Rd; | 1169 | unsigned int Rd; |
| 1345 | unsigned int Rm; | 1170 | unsigned int Rm; |
| 1346 | unsigned int rotate; | 1171 | unsigned int rotate; |
| 1347 | } sxtb_inst; | 1172 | } sxtb_inst; |
| 1348 | 1173 | ||
| 1349 | typedef struct _sxtab_inst { | 1174 | typedef struct _sxtab_inst { |
| 1350 | unsigned int Rd; | 1175 | unsigned int Rd; |
| 1351 | unsigned int Rn; | 1176 | unsigned int Rn; |
| 1352 | unsigned int Rm; | 1177 | unsigned int Rm; |
| 1353 | unsigned rotate; | 1178 | unsigned rotate; |
| 1354 | } sxtab_inst; | 1179 | } sxtab_inst; |
| 1355 | 1180 | ||
| 1356 | typedef struct _sxtah_inst { | 1181 | typedef struct _sxtah_inst { |
| 1357 | unsigned int Rd; | 1182 | unsigned int Rd; |
| 1358 | unsigned int Rn; | 1183 | unsigned int Rn; |
| 1359 | unsigned int Rm; | 1184 | unsigned int Rm; |
| 1360 | unsigned int rotate; | 1185 | unsigned int rotate; |
| 1361 | } sxtah_inst; | 1186 | } sxtah_inst; |
| 1362 | 1187 | ||
| 1363 | typedef struct _sxth_inst { | 1188 | typedef struct _sxth_inst { |
| 1364 | unsigned int Rd; | 1189 | unsigned int Rd; |
| 1365 | unsigned int Rm; | 1190 | unsigned int Rm; |
| 1366 | unsigned int rotate; | 1191 | unsigned int rotate; |
| 1367 | } sxth_inst; | 1192 | } sxth_inst; |
| 1368 | 1193 | ||
| 1369 | typedef struct _uxtab_inst { | 1194 | typedef struct _uxtab_inst { |
| 1370 | unsigned int Rn; | 1195 | unsigned int Rn; |
| 1371 | unsigned int Rd; | 1196 | unsigned int Rd; |
| 1372 | unsigned int rotate; | 1197 | unsigned int rotate; |
| 1373 | unsigned int Rm; | 1198 | unsigned int Rm; |
| 1374 | } uxtab_inst; | 1199 | } uxtab_inst; |
| 1375 | 1200 | ||
| 1376 | typedef struct _uxtah_inst { | 1201 | typedef struct _uxtah_inst { |
| 1377 | unsigned int Rn; | 1202 | unsigned int Rn; |
| 1378 | unsigned int Rd; | 1203 | unsigned int Rd; |
| 1379 | unsigned int rotate; | 1204 | unsigned int rotate; |
| 1380 | unsigned int Rm; | 1205 | unsigned int Rm; |
| 1381 | } uxtah_inst; | 1206 | } uxtah_inst; |
| 1382 | 1207 | ||
| 1383 | typedef struct _uxth_inst { | 1208 | typedef struct _uxth_inst { |
| 1384 | unsigned int Rd; | 1209 | unsigned int Rd; |
| 1385 | unsigned int Rm; | 1210 | unsigned int Rm; |
| 1386 | unsigned int rotate; | 1211 | unsigned int rotate; |
| 1387 | } uxth_inst; | 1212 | } uxth_inst; |
| 1388 | 1213 | ||
| 1389 | typedef struct _cdp_inst { | 1214 | typedef struct _cdp_inst { |
| 1390 | unsigned int opcode_1; | 1215 | unsigned int opcode_1; |
| 1391 | unsigned int CRn; | 1216 | unsigned int CRn; |
| 1392 | unsigned int CRd; | 1217 | unsigned int CRd; |
| 1393 | unsigned int cp_num; | 1218 | unsigned int cp_num; |
| 1394 | unsigned int opcode_2; | 1219 | unsigned int opcode_2; |
| 1395 | unsigned int CRm; | 1220 | unsigned int CRm; |
| 1396 | uint32 inst; | 1221 | uint32 inst; |
| 1397 | }cdp_inst; | 1222 | }cdp_inst; |
| 1398 | 1223 | ||
| 1399 | typedef struct _uxtb_inst { | 1224 | typedef struct _uxtb_inst { |
| 1400 | unsigned int Rd; | 1225 | unsigned int Rd; |
| 1401 | unsigned int Rm; | 1226 | unsigned int Rm; |
| 1402 | unsigned int rotate; | 1227 | unsigned int rotate; |
| 1403 | } uxtb_inst; | 1228 | } uxtb_inst; |
| 1404 | 1229 | ||
| 1405 | typedef struct _swp_inst { | 1230 | typedef struct _swp_inst { |
| 1406 | unsigned int Rn; | 1231 | unsigned int Rn; |
| 1407 | unsigned int Rd; | 1232 | unsigned int Rd; |
| 1408 | unsigned int Rm; | 1233 | unsigned int Rm; |
| 1409 | } swp_inst; | 1234 | } swp_inst; |
| 1410 | 1235 | ||
| 1411 | typedef struct _b_2_thumb { | 1236 | typedef struct _b_2_thumb { |
| 1412 | unsigned int imm; | 1237 | unsigned int imm; |
| 1413 | }b_2_thumb; | 1238 | }b_2_thumb; |
| 1414 | typedef struct _b_cond_thumb { | 1239 | typedef struct _b_cond_thumb { |
| 1415 | unsigned int imm; | 1240 | unsigned int imm; |
| 1416 | unsigned int cond; | 1241 | unsigned int cond; |
| 1417 | }b_cond_thumb; | 1242 | }b_cond_thumb; |
| 1418 | 1243 | ||
| 1419 | typedef struct _bl_1_thumb { | 1244 | typedef struct _bl_1_thumb { |
| 1420 | unsigned int imm; | 1245 | unsigned int imm; |
| 1421 | }bl_1_thumb; | 1246 | }bl_1_thumb; |
| 1422 | typedef struct _bl_2_thumb { | 1247 | typedef struct _bl_2_thumb { |
| 1423 | unsigned int imm; | 1248 | unsigned int imm; |
| 1424 | }bl_2_thumb; | 1249 | }bl_2_thumb; |
| 1425 | typedef struct _blx_1_thumb { | 1250 | typedef struct _blx_1_thumb { |
| 1426 | unsigned int imm; | 1251 | unsigned int imm; |
| 1427 | unsigned int instr; | 1252 | unsigned int instr; |
| 1428 | }blx_1_thumb; | 1253 | }blx_1_thumb; |
| 1429 | 1254 | ||
| 1430 | typedef struct _pkh_inst { | 1255 | typedef struct _pkh_inst { |
| 1431 | u32 Rm; | 1256 | u32 Rm; |
| 1432 | u32 Rn; | 1257 | u32 Rn; |
| 1433 | u32 Rd; | 1258 | u32 Rd; |
| 1434 | u8 imm; | 1259 | u8 imm; |
| 1435 | } pkh_inst; | 1260 | } pkh_inst; |
| 1436 | 1261 | ||
| 1437 | typedef arm_inst * ARM_INST_PTR; | 1262 | typedef arm_inst * ARM_INST_PTR; |
| 1438 | 1263 | ||
| 1439 | #define CACHE_BUFFER_SIZE (64 * 1024 * 2000) | 1264 | #define CACHE_BUFFER_SIZE (64 * 1024 * 2000) |
| 1440 | char inst_buf[CACHE_BUFFER_SIZE]; | 1265 | char inst_buf[CACHE_BUFFER_SIZE]; |
| 1441 | int top = 0; | 1266 | int top = 0; |
| 1442 | inline void *AllocBuffer(unsigned int size) | 1267 | inline void *AllocBuffer(unsigned int size) { |
| 1443 | { | 1268 | int start = top; |
| 1444 | int start = top; | 1269 | top += size; |
| 1445 | top += size; | 1270 | if (top > CACHE_BUFFER_SIZE) { |
| 1446 | if (top > CACHE_BUFFER_SIZE) { | 1271 | LOG_ERROR(Core_ARM11, "inst_buf is full"); |
| 1447 | LOG_ERROR(Core_ARM11, "inst_buf is full"); | 1272 | CITRA_IGNORE_EXIT(-1); |
| 1448 | CITRA_IGNORE_EXIT(-1); | 1273 | } |
| 1449 | } | 1274 | return (void *)&inst_buf[start]; |
| 1450 | return (void *)&inst_buf[start]; | 1275 | } |
| 1451 | } | 1276 | |
| 1452 | 1277 | int CondPassed(arm_processor *cpu, unsigned int cond) { | |
| 1453 | int CondPassed(arm_processor *cpu, unsigned int cond) | 1278 | #define NFLAG cpu->NFlag |
| 1454 | { | 1279 | #define ZFLAG cpu->ZFlag |
| 1455 | #define NFLAG cpu->NFlag | 1280 | #define CFLAG cpu->CFlag |
| 1456 | #define ZFLAG cpu->ZFlag | 1281 | #define VFLAG cpu->VFlag |
| 1457 | #define CFLAG cpu->CFlag | 1282 | |
| 1458 | #define VFLAG cpu->VFlag | 1283 | int temp; |
| 1459 | int temp; | 1284 | |
| 1460 | switch (cond) { | 1285 | switch (cond) { |
| 1461 | case 0x0: | 1286 | case 0x0: |
| 1462 | temp = ZFLAG; | 1287 | temp = ZFLAG; |
| 1463 | break; | 1288 | break; |
| 1464 | case 0x1: /* NE */ | 1289 | case 0x1: // NE |
| 1465 | temp = !ZFLAG; | 1290 | temp = !ZFLAG; |
| 1466 | break; | 1291 | break; |
| 1467 | case 0x6: /* VS */ | 1292 | case 0x6: // VS |
| 1468 | temp = VFLAG; | 1293 | temp = VFLAG; |
| 1469 | break; | 1294 | break; |
| 1470 | case 0x7: /* VC */ | 1295 | case 0x7: // VC |
| 1471 | temp = !VFLAG; | 1296 | temp = !VFLAG; |
| 1472 | break; | 1297 | break; |
| 1473 | case 0x4: /* MI */ | 1298 | case 0x4: // MI |
| 1474 | temp = NFLAG; | 1299 | temp = NFLAG; |
| 1475 | break; | 1300 | break; |
| 1476 | case 0x5: /* PL */ | 1301 | case 0x5: // PL |
| 1477 | temp = !NFLAG; | 1302 | temp = !NFLAG; |
| 1478 | break; | 1303 | break; |
| 1479 | case 0x2: /* CS */ | 1304 | case 0x2: // CS |
| 1480 | temp = CFLAG; | 1305 | temp = CFLAG; |
| 1481 | break; | 1306 | break; |
| 1482 | case 0x3: /* CC */ | 1307 | case 0x3: // CC |
| 1483 | temp = !CFLAG; | 1308 | temp = !CFLAG; |
| 1484 | break; | 1309 | break; |
| 1485 | case 0x8: /* HI */ | 1310 | case 0x8: // HI |
| 1486 | temp = (CFLAG && !ZFLAG); | 1311 | temp = (CFLAG && !ZFLAG); |
| 1487 | break; | 1312 | break; |
| 1488 | case 0x9: /* LS */ | 1313 | case 0x9: // LS |
| 1489 | temp = (!CFLAG || ZFLAG); | 1314 | temp = (!CFLAG || ZFLAG); |
| 1490 | break; | 1315 | break; |
| 1491 | case 0xa: /* GE */ | 1316 | case 0xa: // GE |
| 1492 | temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG)); | 1317 | temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG)); |
| 1493 | break; | 1318 | break; |
| 1494 | case 0xb: /* LT */ | 1319 | case 0xb: // LT |
| 1495 | temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)); | 1320 | temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)); |
| 1496 | break; | 1321 | break; |
| 1497 | case 0xc: /* GT */ | 1322 | case 0xc: // GT |
| 1498 | temp = ((!NFLAG && !VFLAG && !ZFLAG) | 1323 | temp = ((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG)); |
| 1499 | || (NFLAG && VFLAG && !ZFLAG)); | 1324 | break; |
| 1500 | break; | 1325 | case 0xd: // LE |
| 1501 | case 0xd: /* LE */ | 1326 | temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG; |
| 1502 | temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) | 1327 | break; |
| 1503 | || ZFLAG; | 1328 | case 0xe: // AL |
| 1504 | break; | 1329 | temp = 1; |
| 1505 | case 0xe: /* AL */ | 1330 | break; |
| 1506 | temp = 1; | 1331 | case 0xf: |
| 1507 | break; | 1332 | temp = 1; |
| 1508 | case 0xf: | 1333 | break; |
| 1509 | // DEBUG_LOG(ARM11, "inst is %x\n"); | 1334 | } |
| 1510 | // DEBUG_LOG(ARM11, "icounter is %lld\n", cpu->icounter); | 1335 | return temp; |
| 1511 | // CITRA_IGNORE_EXIT(-1); | ||
| 1512 | temp = 1; | ||
| 1513 | break; | ||
| 1514 | } | ||
| 1515 | return temp; | ||
| 1516 | } | 1336 | } |
| 1517 | 1337 | ||
| 1518 | enum DECODE_STATUS { | 1338 | enum DECODE_STATUS { |
| 1519 | DECODE_SUCCESS, | 1339 | DECODE_SUCCESS, |
| 1520 | DECODE_FAILURE | 1340 | DECODE_FAILURE |
| 1521 | }; | 1341 | }; |
| 1522 | 1342 | ||
| 1523 | int decode_arm_instr(uint32_t instr, int32_t *idx); | 1343 | int decode_arm_instr(uint32_t instr, int32_t *idx); |
| 1524 | 1344 | ||
| 1525 | shtop_fp_t get_shtop(unsigned int inst) | 1345 | shtop_fp_t get_shtop(unsigned int inst) { |
| 1526 | { | 1346 | if (BIT(inst, 25)) { |
| 1527 | if (BIT(inst, 25)) { | 1347 | return DPO(Immediate); |
| 1528 | return DPO(Immediate); | 1348 | } else if (BITS(inst, 4, 11) == 0) { |
| 1529 | } else if (BITS(inst, 4, 11) == 0) { | 1349 | return DPO(Register); |
| 1530 | return DPO(Register); | 1350 | } else if (BITS(inst, 4, 6) == 0) { |
| 1531 | } else if (BITS(inst, 4, 6) == 0) { | 1351 | return DPO(LogicalShiftLeftByImmediate); |
| 1532 | return DPO(LogicalShiftLeftByImmediate); | 1352 | } else if (BITS(inst, 4, 7) == 1) { |
| 1533 | } else if (BITS(inst, 4, 7) == 1) { | 1353 | return DPO(LogicalShiftLeftByRegister); |
| 1534 | return DPO(LogicalShiftLeftByRegister); | 1354 | } else if (BITS(inst, 4, 6) == 2) { |
| 1535 | } else if (BITS(inst, 4, 6) == 2) { | 1355 | return DPO(LogicalShiftRightByImmediate); |
| 1536 | return DPO(LogicalShiftRightByImmediate); | 1356 | } else if (BITS(inst, 4, 7) == 3) { |
| 1537 | } else if (BITS(inst, 4, 7) == 3) { | 1357 | return DPO(LogicalShiftRightByRegister); |
| 1538 | return DPO(LogicalShiftRightByRegister); | 1358 | } else if (BITS(inst, 4, 6) == 4) { |
| 1539 | } else if (BITS(inst, 4, 6) == 4) { | 1359 | return DPO(ArithmeticShiftRightByImmediate); |
| 1540 | return DPO(ArithmeticShiftRightByImmediate); | 1360 | } else if (BITS(inst, 4, 7) == 5) { |
| 1541 | } else if (BITS(inst, 4, 7) == 5) { | 1361 | return DPO(ArithmeticShiftRightByRegister); |
| 1542 | return DPO(ArithmeticShiftRightByRegister); | 1362 | } else if (BITS(inst, 4, 6) == 6) { |
| 1543 | } else if (BITS(inst, 4, 6) == 6) { | 1363 | return DPO(RotateRightByImmediate); |
| 1544 | return DPO(RotateRightByImmediate); | 1364 | } else if (BITS(inst, 4, 7) == 7) { |
| 1545 | } else if (BITS(inst, 4, 7) == 7) { | 1365 | return DPO(RotateRightByRegister); |
| 1546 | return DPO(RotateRightByRegister); | 1366 | } |
| 1547 | } | 1367 | return nullptr; |
| 1548 | return NULL; | 1368 | } |
| 1549 | } | 1369 | |
| 1550 | 1370 | get_addr_fp_t get_calc_addr_op(unsigned int inst) { | |
| 1551 | get_addr_fp_t get_calc_addr_op(unsigned int inst) | 1371 | if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) { |
| 1552 | { | 1372 | return LnSWoUB(ImmediateOffset); |
| 1553 | /* 1 */ | 1373 | } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) { |
| 1554 | if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) { | 1374 | return LnSWoUB(RegisterOffset); |
| 1555 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | 1375 | } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) { |
| 1556 | return LnSWoUB(ImmediateOffset); | 1376 | return LnSWoUB(ScaledRegisterOffset); |
| 1557 | } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) { | 1377 | } else if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 1) { |
| 1558 | // DEBUG_MSG; | 1378 | return LnSWoUB(ImmediatePreIndexed); |
| 1559 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | 1379 | } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BITS(inst, 4, 11) == 0) { |
| 1560 | return LnSWoUB(RegisterOffset); | 1380 | return LnSWoUB(RegisterPreIndexed); |
| 1561 | } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) { | 1381 | } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BIT(inst, 4) == 0) { |
| 1562 | // DEBUG_MSG; | 1382 | return LnSWoUB(ScaledRegisterPreIndexed); |
| 1563 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | 1383 | } else if (BITS(inst, 24, 27) == 4 && BIT(inst, 21) == 0) { |
| 1564 | return LnSWoUB(ScaledRegisterOffset); | 1384 | return LnSWoUB(ImmediatePostIndexed); |
| 1565 | } else if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 1) { | 1385 | } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) { |
| 1566 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | 1386 | return LnSWoUB(RegisterPostIndexed); |
| 1567 | return LnSWoUB(ImmediatePreIndexed); | 1387 | } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) { |
| 1568 | } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BITS(inst, 4, 11) == 0) { | 1388 | return LnSWoUB(ScaledRegisterPostIndexed); |
| 1569 | return LnSWoUB(RegisterPreIndexed); | 1389 | } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { |
| 1570 | } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BIT(inst, 4) == 0) { | 1390 | return MLnS(ImmediateOffset); |
| 1571 | return LnSWoUB(ScaledRegisterPreIndexed); | 1391 | } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { |
| 1572 | } else if (BITS(inst, 24, 27) == 4 && BIT(inst, 21) == 0) { | 1392 | return MLnS(RegisterOffset); |
| 1573 | return LnSWoUB(ImmediatePostIndexed); | 1393 | } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { |
| 1574 | } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) { | 1394 | return MLnS(ImmediatePreIndexed); |
| 1575 | // DEBUG_MSG; | 1395 | } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { |
| 1576 | return LnSWoUB(RegisterPostIndexed); | 1396 | return MLnS(RegisterPreIndexed); |
| 1577 | } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) { | 1397 | } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { |
| 1578 | return LnSWoUB(ScaledRegisterPostIndexed); | 1398 | return MLnS(ImmediatePostIndexed); |
| 1579 | // DEBUG_MSG; | 1399 | } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { |
| 1580 | } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { | 1400 | return MLnS(RegisterPostIndexed); |
| 1581 | /* 2 */ | 1401 | } else if (BITS(inst, 23, 27) == 0x11) { |
| 1582 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | 1402 | return LdnStM(IncrementAfter); |
| 1583 | return MLnS(ImmediateOffset); | 1403 | } else if (BITS(inst, 23, 27) == 0x13) { |
| 1584 | // DEBUG_MSG; | 1404 | return LdnStM(IncrementBefore); |
| 1585 | } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { | 1405 | } else if (BITS(inst, 23, 27) == 0x10) { |
| 1586 | // DEBUG_LOG(ARM11, "line is %d\n", __LINE__); | 1406 | return LdnStM(DecrementAfter); |
| 1587 | return MLnS(RegisterOffset); | 1407 | } else if (BITS(inst, 23, 27) == 0x12) { |
| 1588 | // DEBUG_MSG; | 1408 | return LdnStM(DecrementBefore); |
| 1589 | } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { | 1409 | } |
| 1590 | // DEBUG_LOG(ARM11, "line is %d\n", __LINE__); | 1410 | return nullptr; |
| 1591 | return MLnS(ImmediatePreIndexed); | ||
| 1592 | // DEBUG_MSG; | ||
| 1593 | } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { | ||
| 1594 | return MLnS(RegisterPreIndexed); | ||
| 1595 | } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { | ||
| 1596 | // DEBUG_MSG; | ||
| 1597 | return MLnS(ImmediatePostIndexed); | ||
| 1598 | } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { | ||
| 1599 | //DEBUG_MSG; | ||
| 1600 | return MLnS(RegisterPostIndexed); | ||
| 1601 | } else if (BITS(inst, 23, 27) == 0x11) { | ||
| 1602 | /* 3 */ | ||
| 1603 | // DEBUG_MSG; | ||
| 1604 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | ||
| 1605 | return LdnStM(IncrementAfter); | ||
| 1606 | } else if (BITS(inst, 23, 27) == 0x13) { | ||
| 1607 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | ||
| 1608 | return LdnStM(IncrementBefore); | ||
| 1609 | // DEBUG_MSG; | ||
| 1610 | } else if (BITS(inst, 23, 27) == 0x10) { | ||
| 1611 | // DEBUG_MSG; | ||
| 1612 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | ||
| 1613 | return LdnStM(DecrementAfter); | ||
| 1614 | } else if (BITS(inst, 23, 27) == 0x12) { | ||
| 1615 | // DEBUG_MSG; | ||
| 1616 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | ||
| 1617 | return LdnStM(DecrementBefore); | ||
| 1618 | } | ||
| 1619 | #if 0 | ||
| 1620 | DEBUG_LOG(ARM11, "In %s Unknown addressing mode\n", __FUNCTION__); | ||
| 1621 | DEBUG_LOG(ARM11, "inst:%x\n", inst); | ||
| 1622 | CITRA_IGNORE_EXIT(-1); | ||
| 1623 | #endif | ||
| 1624 | return NULL; | ||
| 1625 | } | 1411 | } |
| 1626 | 1412 | ||
| 1627 | #define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s) | 1413 | #define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s) |
| 1628 | 1414 | ||
| 1629 | #define CHECK_RN (inst_cream->Rn == 15) | 1415 | #define CHECK_RN (inst_cream->Rn == 15) |
| 1630 | #define CHECK_RM (inst_cream->Rm == 15) | 1416 | #define CHECK_RM (inst_cream->Rm == 15) |
| 1631 | #define CHECK_RS (inst_cream->Rs == 15) | 1417 | #define CHECK_RS (inst_cream->Rs == 15) |
| 1632 | 1418 | ||
| 1633 | #define UNIMPLEMENTED_INSTRUCTION(mnemonic) \ | 1419 | #define UNIMPLEMENTED_INSTRUCTION(mnemonic) \ |
| 1634 | LOG_ERROR(Core_ARM11, "unimplemented instruction: %s", mnemonic); \ | 1420 | LOG_ERROR(Core_ARM11, "unimplemented instruction: %s", mnemonic); \ |
| @@ -1637,972 +1423,969 @@ get_addr_fp_t get_calc_addr_op(unsigned int inst) | |||
| 1637 | 1423 | ||
| 1638 | ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index) | 1424 | ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index) |
| 1639 | { | 1425 | { |
| 1640 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst)); | 1426 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst)); |
| 1641 | adc_inst *inst_cream = (adc_inst *)inst_base->component; | 1427 | adc_inst *inst_cream = (adc_inst *)inst_base->component; |
| 1642 | 1428 | ||
| 1643 | inst_base->cond = BITS(inst, 28, 31); | 1429 | inst_base->cond = BITS(inst, 28, 31); |
| 1644 | inst_base->idx = index; | 1430 | inst_base->idx = index; |
| 1645 | inst_base->br = NON_BRANCH; | 1431 | inst_base->br = NON_BRANCH; |
| 1646 | inst_base->load_r15 = 0; | 1432 | inst_base->load_r15 = 0; |
| 1647 | 1433 | ||
| 1648 | inst_cream->I = BIT(inst, 25); | 1434 | inst_cream->I = BIT(inst, 25); |
| 1649 | inst_cream->S = BIT(inst, 20); | 1435 | inst_cream->S = BIT(inst, 20); |
| 1650 | inst_cream->Rn = BITS(inst, 16, 19); | 1436 | inst_cream->Rn = BITS(inst, 16, 19); |
| 1651 | inst_cream->Rd = BITS(inst, 12, 15); | 1437 | inst_cream->Rd = BITS(inst, 12, 15); |
| 1652 | if (CHECK_RN) | 1438 | if (CHECK_RN) |
| 1653 | inst_base->load_r15 = 1; | 1439 | inst_base->load_r15 = 1; |
| 1654 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 1440 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 1655 | inst_cream->shtop_func = get_shtop(inst); | 1441 | inst_cream->shtop_func = get_shtop(inst); |
| 1656 | if (inst_cream->Rd == 15) { | 1442 | if (inst_cream->Rd == 15) { |
| 1657 | inst_base->br = INDIRECT_BRANCH; | 1443 | inst_base->br = INDIRECT_BRANCH; |
| 1658 | } | 1444 | } |
| 1659 | return inst_base; | 1445 | return inst_base; |
| 1660 | } | 1446 | } |
| 1661 | ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index) | 1447 | ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index) |
| 1662 | { | 1448 | { |
| 1663 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst)); | 1449 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst)); |
| 1664 | add_inst *inst_cream = (add_inst *)inst_base->component; | 1450 | add_inst *inst_cream = (add_inst *)inst_base->component; |
| 1665 | 1451 | ||
| 1666 | inst_base->cond = BITS(inst, 28, 31); | 1452 | inst_base->cond = BITS(inst, 28, 31); |
| 1667 | inst_base->idx = index; | 1453 | inst_base->idx = index; |
| 1668 | inst_base->br = NON_BRANCH; | 1454 | inst_base->br = NON_BRANCH; |
| 1669 | inst_base->load_r15 = 0; | 1455 | inst_base->load_r15 = 0; |
| 1670 | 1456 | ||
| 1671 | inst_cream->I = BIT(inst, 25); | 1457 | inst_cream->I = BIT(inst, 25); |
| 1672 | inst_cream->S = BIT(inst, 20); | 1458 | inst_cream->S = BIT(inst, 20); |
| 1673 | inst_cream->Rn = BITS(inst, 16, 19); | 1459 | inst_cream->Rn = BITS(inst, 16, 19); |
| 1674 | inst_cream->Rd = BITS(inst, 12, 15); | 1460 | inst_cream->Rd = BITS(inst, 12, 15); |
| 1675 | if (CHECK_RN) | 1461 | if (CHECK_RN) |
| 1676 | inst_base->load_r15 = 1; | 1462 | inst_base->load_r15 = 1; |
| 1677 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 1463 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 1678 | inst_cream->shtop_func = get_shtop(inst); | 1464 | inst_cream->shtop_func = get_shtop(inst); |
| 1679 | if (inst_cream->Rd == 15) { | 1465 | if (inst_cream->Rd == 15) { |
| 1680 | inst_base->br = INDIRECT_BRANCH; | 1466 | inst_base->br = INDIRECT_BRANCH; |
| 1681 | } | 1467 | } |
| 1682 | return inst_base; | 1468 | return inst_base; |
| 1683 | } | 1469 | } |
| 1684 | ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index) | 1470 | ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index) |
| 1685 | { | 1471 | { |
| 1686 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst)); | 1472 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst)); |
| 1687 | and_inst *inst_cream = (and_inst *)inst_base->component; | 1473 | and_inst *inst_cream = (and_inst *)inst_base->component; |
| 1688 | 1474 | ||
| 1689 | inst_base->cond = BITS(inst, 28, 31); | 1475 | inst_base->cond = BITS(inst, 28, 31); |
| 1690 | inst_base->idx = index; | 1476 | inst_base->idx = index; |
| 1691 | inst_base->br = NON_BRANCH; | 1477 | inst_base->br = NON_BRANCH; |
| 1692 | inst_base->load_r15 = 0; | 1478 | inst_base->load_r15 = 0; |
| 1693 | 1479 | ||
| 1694 | inst_cream->I = BIT(inst, 25); | 1480 | inst_cream->I = BIT(inst, 25); |
| 1695 | inst_cream->S = BIT(inst, 20); | 1481 | inst_cream->S = BIT(inst, 20); |
| 1696 | inst_cream->Rn = BITS(inst, 16, 19); | 1482 | inst_cream->Rn = BITS(inst, 16, 19); |
| 1697 | inst_cream->Rd = BITS(inst, 12, 15); | 1483 | inst_cream->Rd = BITS(inst, 12, 15); |
| 1698 | if (CHECK_RN) | 1484 | if (CHECK_RN) |
| 1699 | inst_base->load_r15 = 1; | 1485 | inst_base->load_r15 = 1; |
| 1700 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 1486 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 1701 | inst_cream->shtop_func = get_shtop(inst); | 1487 | inst_cream->shtop_func = get_shtop(inst); |
| 1702 | if (inst_cream->Rd == 15) | 1488 | if (inst_cream->Rd == 15) |
| 1703 | inst_base->br = INDIRECT_BRANCH; | 1489 | inst_base->br = INDIRECT_BRANCH; |
| 1704 | return inst_base; | 1490 | return inst_base; |
| 1705 | } | 1491 | } |
| 1706 | ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index) | 1492 | ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index) |
| 1707 | { | 1493 | { |
| 1708 | #define POSBRANCH ((inst & 0x7fffff) << 2) | 1494 | #define POSBRANCH ((inst & 0x7fffff) << 2) |
| 1709 | #define NEGBRANCH ((0xff000000 |(inst & 0xffffff)) << 2) | 1495 | #define NEGBRANCH ((0xff000000 |(inst & 0xffffff)) << 2) |
| 1710 | 1496 | ||
| 1711 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst)); | 1497 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst)); |
| 1712 | bbl_inst *inst_cream = (bbl_inst *)inst_base->component; | 1498 | bbl_inst *inst_cream = (bbl_inst *)inst_base->component; |
| 1713 | 1499 | ||
| 1714 | inst_base->cond = BITS(inst, 28, 31); | 1500 | inst_base->cond = BITS(inst, 28, 31); |
| 1715 | inst_base->idx = index; | 1501 | inst_base->idx = index; |
| 1716 | inst_base->br = DIRECT_BRANCH; | 1502 | inst_base->br = DIRECT_BRANCH; |
| 1717 | 1503 | ||
| 1718 | if (BIT(inst, 24)) | 1504 | if (BIT(inst, 24)) |
| 1719 | inst_base->br = CALL; | 1505 | inst_base->br = CALL; |
| 1720 | if (BITS(inst, 28, 31) <= 0xe) | 1506 | if (BITS(inst, 28, 31) <= 0xe) |
| 1721 | inst_base->br |= COND; | 1507 | inst_base->br |= COND; |
| 1722 | 1508 | ||
| 1723 | inst_cream->L = BIT(inst, 24); | 1509 | inst_cream->L = BIT(inst, 24); |
| 1724 | inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH; | 1510 | inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH; |
| 1725 | 1511 | ||
| 1726 | return inst_base; | 1512 | return inst_base; |
| 1727 | } | 1513 | } |
| 1728 | ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index) | 1514 | ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index) |
| 1729 | { | 1515 | { |
| 1730 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst)); | 1516 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst)); |
| 1731 | bic_inst *inst_cream = (bic_inst *)inst_base->component; | 1517 | bic_inst *inst_cream = (bic_inst *)inst_base->component; |
| 1732 | 1518 | ||
| 1733 | inst_base->cond = BITS(inst, 28, 31); | 1519 | inst_base->cond = BITS(inst, 28, 31); |
| 1734 | inst_base->idx = index; | 1520 | inst_base->idx = index; |
| 1735 | inst_base->br = NON_BRANCH; | 1521 | inst_base->br = NON_BRANCH; |
| 1736 | inst_base->load_r15 = 0; | 1522 | inst_base->load_r15 = 0; |
| 1737 | 1523 | ||
| 1738 | inst_cream->I = BIT(inst, 25); | 1524 | inst_cream->I = BIT(inst, 25); |
| 1739 | inst_cream->S = BIT(inst, 20); | 1525 | inst_cream->S = BIT(inst, 20); |
| 1740 | inst_cream->Rn = BITS(inst, 16, 19); | 1526 | inst_cream->Rn = BITS(inst, 16, 19); |
| 1741 | inst_cream->Rd = BITS(inst, 12, 15); | 1527 | inst_cream->Rd = BITS(inst, 12, 15); |
| 1742 | if (CHECK_RN) | 1528 | if (CHECK_RN) |
| 1743 | inst_base->load_r15 = 1; | 1529 | inst_base->load_r15 = 1; |
| 1744 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 1530 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 1745 | inst_cream->shtop_func = get_shtop(inst); | 1531 | inst_cream->shtop_func = get_shtop(inst); |
| 1746 | 1532 | ||
| 1747 | if (inst_cream->Rd == 15) | 1533 | if (inst_cream->Rd == 15) |
| 1748 | inst_base->br = INDIRECT_BRANCH; | 1534 | inst_base->br = INDIRECT_BRANCH; |
| 1749 | return inst_base; | 1535 | return inst_base; |
| 1750 | } | 1536 | } |
| 1751 | ARM_INST_PTR INTERPRETER_TRANSLATE(bkpt)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("BKPT"); } | 1537 | ARM_INST_PTR INTERPRETER_TRANSLATE(bkpt)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("BKPT"); } |
| 1752 | ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index) | 1538 | ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index) |
| 1753 | { | 1539 | { |
| 1754 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst)); | 1540 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst)); |
| 1755 | blx_inst *inst_cream = (blx_inst *)inst_base->component; | 1541 | blx_inst *inst_cream = (blx_inst *)inst_base->component; |
| 1756 | 1542 | ||
| 1757 | inst_base->cond = BITS(inst, 28, 31); | 1543 | inst_base->cond = BITS(inst, 28, 31); |
| 1758 | inst_base->idx = index; | 1544 | inst_base->idx = index; |
| 1759 | inst_base->br = INDIRECT_BRANCH; | 1545 | inst_base->br = INDIRECT_BRANCH; |
| 1760 | 1546 | ||
| 1761 | inst_cream->inst = inst; | 1547 | inst_cream->inst = inst; |
| 1762 | if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { | 1548 | if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { |
| 1763 | inst_cream->val.Rm = BITS(inst, 0, 3); | 1549 | inst_cream->val.Rm = BITS(inst, 0, 3); |
| 1764 | } else { | 1550 | } else { |
| 1765 | inst_cream->val.signed_immed_24 = BITS(inst, 0, 23); | 1551 | inst_cream->val.signed_immed_24 = BITS(inst, 0, 23); |
| 1766 | //DEBUG_LOG(ARM11, " blx inst is %x\n", inst); | 1552 | } |
| 1767 | //CITRA_IGNORE_EXIT(-1); | ||
| 1768 | // DEBUG_MSG; | ||
| 1769 | } | ||
| 1770 | 1553 | ||
| 1771 | return inst_base; | 1554 | return inst_base; |
| 1772 | } | 1555 | } |
| 1773 | ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index) | 1556 | ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index) |
| 1774 | { | 1557 | { |
| 1775 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst)); | 1558 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst)); |
| 1776 | bx_inst *inst_cream = (bx_inst *)inst_base->component; | 1559 | bx_inst *inst_cream = (bx_inst *)inst_base->component; |
| 1777 | 1560 | ||
| 1778 | inst_base->cond = BITS(inst, 28, 31); | 1561 | inst_base->cond = BITS(inst, 28, 31); |
| 1779 | inst_base->idx = index; | 1562 | inst_base->idx = index; |
| 1780 | inst_base->br = INDIRECT_BRANCH; | 1563 | inst_base->br = INDIRECT_BRANCH; |
| 1781 | 1564 | ||
| 1782 | inst_cream->Rm = BITS(inst, 0, 3); | 1565 | inst_cream->Rm = BITS(inst, 0, 3); |
| 1783 | 1566 | ||
| 1784 | return inst_base; | 1567 | return inst_base; |
| 1785 | } | 1568 | } |
| 1786 | ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("BXJ"); } | 1569 | ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("BXJ"); } |
| 1787 | ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){ | 1570 | ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){ |
| 1788 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst)); | 1571 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst)); |
| 1789 | cdp_inst *inst_cream = (cdp_inst *)inst_base->component; | 1572 | cdp_inst *inst_cream = (cdp_inst *)inst_base->component; |
| 1790 | inst_base->cond = BITS(inst, 28, 31); | 1573 | inst_base->cond = BITS(inst, 28, 31); |
| 1791 | inst_base->idx = index; | 1574 | inst_base->idx = index; |
| 1792 | inst_base->br = NON_BRANCH; | 1575 | inst_base->br = NON_BRANCH; |
| 1793 | inst_base->load_r15 = 0; | 1576 | inst_base->load_r15 = 0; |
| 1794 | 1577 | ||
| 1795 | inst_cream->CRm = BITS(inst, 0, 3); | 1578 | inst_cream->CRm = BITS(inst, 0, 3); |
| 1796 | inst_cream->CRd = BITS(inst, 12, 15); | 1579 | inst_cream->CRd = BITS(inst, 12, 15); |
| 1797 | inst_cream->CRn = BITS(inst, 16, 19); | 1580 | inst_cream->CRn = BITS(inst, 16, 19); |
| 1798 | inst_cream->cp_num = BITS(inst, 8, 11); | 1581 | inst_cream->cp_num = BITS(inst, 8, 11); |
| 1799 | inst_cream->opcode_2 = BITS(inst, 5, 7); | 1582 | inst_cream->opcode_2 = BITS(inst, 5, 7); |
| 1800 | inst_cream->opcode_1 = BITS(inst, 20, 23); | 1583 | inst_cream->opcode_1 = BITS(inst, 20, 23); |
| 1801 | inst_cream->inst = inst; | 1584 | inst_cream->inst = inst; |
| 1802 | 1585 | ||
| 1803 | LOG_TRACE(Core_ARM11, "inst %x index %x", inst, index); | 1586 | LOG_TRACE(Core_ARM11, "inst %x index %x", inst, index); |
| 1804 | return inst_base; | 1587 | return inst_base; |
| 1805 | } | 1588 | } |
| 1806 | ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index) | 1589 | ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index) |
| 1807 | { | 1590 | { |
| 1808 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst)); | 1591 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst)); |
| 1809 | inst_base->cond = BITS(inst, 28, 31); | 1592 | inst_base->cond = BITS(inst, 28, 31); |
| 1810 | inst_base->idx = index; | 1593 | inst_base->idx = index; |
| 1811 | inst_base->br = NON_BRANCH; | 1594 | inst_base->br = NON_BRANCH; |
| 1812 | 1595 | ||
| 1813 | return inst_base; | 1596 | return inst_base; |
| 1814 | } | 1597 | } |
| 1815 | ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index) | 1598 | ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index) |
| 1816 | { | 1599 | { |
| 1817 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst)); | 1600 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst)); |
| 1818 | clz_inst *inst_cream = (clz_inst *)inst_base->component; | 1601 | clz_inst *inst_cream = (clz_inst *)inst_base->component; |
| 1819 | 1602 | ||
| 1820 | inst_base->cond = BITS(inst, 28, 31); | 1603 | inst_base->cond = BITS(inst, 28, 31); |
| 1821 | inst_base->idx = index; | 1604 | inst_base->idx = index; |
| 1822 | inst_base->br = NON_BRANCH; | 1605 | inst_base->br = NON_BRANCH; |
| 1823 | inst_base->load_r15 = 0; | 1606 | inst_base->load_r15 = 0; |
| 1824 | 1607 | ||
| 1825 | inst_cream->Rm = BITS(inst, 0, 3); | 1608 | inst_cream->Rm = BITS(inst, 0, 3); |
| 1826 | inst_cream->Rd = BITS(inst, 12, 15); | 1609 | inst_cream->Rd = BITS(inst, 12, 15); |
| 1827 | if (CHECK_RM) | 1610 | if (CHECK_RM) |
| 1828 | inst_base->load_r15 = 1; | 1611 | inst_base->load_r15 = 1; |
| 1829 | 1612 | ||
| 1830 | return inst_base; | 1613 | return inst_base; |
| 1831 | } | 1614 | } |
| 1832 | ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index) | 1615 | ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index) |
| 1833 | { | 1616 | { |
| 1834 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst)); | 1617 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst)); |
| 1835 | cmn_inst *inst_cream = (cmn_inst *)inst_base->component; | 1618 | cmn_inst *inst_cream = (cmn_inst *)inst_base->component; |
| 1836 | 1619 | ||
| 1837 | inst_base->cond = BITS(inst, 28, 31); | 1620 | inst_base->cond = BITS(inst, 28, 31); |
| 1838 | inst_base->idx = index; | 1621 | inst_base->idx = index; |
| 1839 | inst_base->br = NON_BRANCH; | 1622 | inst_base->br = NON_BRANCH; |
| 1840 | inst_base->load_r15 = 0; | 1623 | inst_base->load_r15 = 0; |
| 1841 | 1624 | ||
| 1842 | inst_cream->I = BIT(inst, 25); | 1625 | inst_cream->I = BIT(inst, 25); |
| 1843 | //inst_cream->S = BIT(inst, 20); | 1626 | //inst_cream->S = BIT(inst, 20); |
| 1844 | inst_cream->Rn = BITS(inst, 16, 19); | 1627 | inst_cream->Rn = BITS(inst, 16, 19); |
| 1845 | //inst_cream->Rd = BITS(inst, 12, 15); | 1628 | //inst_cream->Rd = BITS(inst, 12, 15); |
| 1846 | if (CHECK_RN) | 1629 | if (CHECK_RN) |
| 1847 | inst_base->load_r15 = 1; | 1630 | inst_base->load_r15 = 1; |
| 1848 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 1631 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 1849 | inst_cream->shtop_func = get_shtop(inst); | 1632 | inst_cream->shtop_func = get_shtop(inst); |
| 1850 | return inst_base; | 1633 | return inst_base; |
| 1851 | } | 1634 | } |
| 1852 | ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index) | 1635 | ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index) |
| 1853 | { | 1636 | { |
| 1854 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst)); | 1637 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst)); |
| 1855 | cmp_inst *inst_cream = (cmp_inst *)inst_base->component; | 1638 | cmp_inst *inst_cream = (cmp_inst *)inst_base->component; |
| 1856 | 1639 | ||
| 1857 | inst_base->cond = BITS(inst, 28, 31); | 1640 | inst_base->cond = BITS(inst, 28, 31); |
| 1858 | inst_base->idx = index; | 1641 | inst_base->idx = index; |
| 1859 | inst_base->br = NON_BRANCH; | 1642 | inst_base->br = NON_BRANCH; |
| 1860 | inst_base->load_r15 = 0; | 1643 | inst_base->load_r15 = 0; |
| 1861 | 1644 | ||
| 1862 | inst_cream->I = BIT(inst, 25); | 1645 | inst_cream->I = BIT(inst, 25); |
| 1863 | inst_cream->Rn = BITS(inst, 16, 19); | 1646 | inst_cream->Rn = BITS(inst, 16, 19); |
| 1864 | if (CHECK_RN) | 1647 | if (CHECK_RN) |
| 1865 | inst_base->load_r15 = 1; | 1648 | inst_base->load_r15 = 1; |
| 1866 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 1649 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 1867 | inst_cream->shtop_func = get_shtop(inst); | 1650 | inst_cream->shtop_func = get_shtop(inst); |
| 1868 | return inst_base; | 1651 | return inst_base; |
| 1869 | } | 1652 | } |
| 1870 | ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index) | 1653 | ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index) |
| 1871 | { | 1654 | { |
| 1872 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst)); | 1655 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst)); |
| 1873 | cps_inst *inst_cream = (cps_inst *)inst_base->component; | 1656 | cps_inst *inst_cream = (cps_inst *)inst_base->component; |
| 1874 | 1657 | ||
| 1875 | inst_base->cond = BITS(inst, 28, 31); | 1658 | inst_base->cond = BITS(inst, 28, 31); |
| 1876 | inst_base->idx = index; | 1659 | inst_base->idx = index; |
| 1877 | inst_base->br = NON_BRANCH; | 1660 | inst_base->br = NON_BRANCH; |
| 1878 | 1661 | ||
| 1879 | inst_cream->imod0 = BIT(inst, 18); | 1662 | inst_cream->imod0 = BIT(inst, 18); |
| 1880 | inst_cream->imod1 = BIT(inst, 19); | 1663 | inst_cream->imod1 = BIT(inst, 19); |
| 1881 | inst_cream->mmod = BIT(inst, 17); | 1664 | inst_cream->mmod = BIT(inst, 17); |
| 1882 | inst_cream->A = BIT(inst, 8); | 1665 | inst_cream->A = BIT(inst, 8); |
| 1883 | inst_cream->I = BIT(inst, 7); | 1666 | inst_cream->I = BIT(inst, 7); |
| 1884 | inst_cream->F = BIT(inst, 6); | 1667 | inst_cream->F = BIT(inst, 6); |
| 1885 | inst_cream->mode = BITS(inst, 0, 4); | 1668 | inst_cream->mode = BITS(inst, 0, 4); |
| 1886 | 1669 | ||
| 1887 | return inst_base; | 1670 | return inst_base; |
| 1888 | } | 1671 | } |
| 1889 | ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index) | 1672 | ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index) |
| 1890 | { | 1673 | { |
| 1891 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); | 1674 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); |
| 1892 | mov_inst *inst_cream = (mov_inst *)inst_base->component; | 1675 | mov_inst *inst_cream = (mov_inst *)inst_base->component; |
| 1893 | 1676 | ||
| 1894 | inst_base->cond = BITS(inst, 28, 31); | 1677 | inst_base->cond = BITS(inst, 28, 31); |
| 1895 | inst_base->idx = index; | 1678 | inst_base->idx = index; |
| 1896 | inst_base->br = NON_BRANCH; | 1679 | inst_base->br = NON_BRANCH; |
| 1897 | 1680 | ||
| 1898 | inst_cream->I = BIT(inst, 25); | 1681 | inst_cream->I = BIT(inst, 25); |
| 1899 | inst_cream->S = BIT(inst, 20); | 1682 | inst_cream->S = BIT(inst, 20); |
| 1900 | inst_cream->Rd = BITS(inst, 12, 15); | 1683 | inst_cream->Rd = BITS(inst, 12, 15); |
| 1901 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 1684 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 1902 | inst_cream->shtop_func = get_shtop(inst); | 1685 | inst_cream->shtop_func = get_shtop(inst); |
| 1903 | 1686 | ||
| 1904 | if (inst_cream->Rd == 15) { | 1687 | if (inst_cream->Rd == 15) { |
| 1905 | inst_base->br = INDIRECT_BRANCH; | 1688 | inst_base->br = INDIRECT_BRANCH; |
| 1906 | } | 1689 | } |
| 1907 | return inst_base; | 1690 | return inst_base; |
| 1908 | } | 1691 | } |
| 1909 | ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index) | 1692 | ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index) |
| 1910 | { | 1693 | { |
| 1911 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst)); | 1694 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst)); |
| 1912 | eor_inst *inst_cream = (eor_inst *)inst_base->component; | 1695 | eor_inst *inst_cream = (eor_inst *)inst_base->component; |
| 1913 | 1696 | ||
| 1914 | inst_base->cond = BITS(inst, 28, 31); | 1697 | inst_base->cond = BITS(inst, 28, 31); |
| 1915 | inst_base->idx = index; | 1698 | inst_base->idx = index; |
| 1916 | inst_base->br = NON_BRANCH; | 1699 | inst_base->br = NON_BRANCH; |
| 1917 | inst_base->load_r15 = 0; | 1700 | inst_base->load_r15 = 0; |
| 1918 | 1701 | ||
| 1919 | inst_cream->I = BIT(inst, 25); | 1702 | inst_cream->I = BIT(inst, 25); |
| 1920 | inst_cream->S = BIT(inst, 20); | 1703 | inst_cream->S = BIT(inst, 20); |
| 1921 | inst_cream->Rn = BITS(inst, 16, 19); | 1704 | inst_cream->Rn = BITS(inst, 16, 19); |
| 1922 | inst_cream->Rd = BITS(inst, 12, 15); | 1705 | inst_cream->Rd = BITS(inst, 12, 15); |
| 1923 | if (CHECK_RN) | 1706 | if (CHECK_RN) |
| 1924 | inst_base->load_r15 = 1; | 1707 | inst_base->load_r15 = 1; |
| 1925 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 1708 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 1926 | inst_cream->shtop_func = get_shtop(inst); | 1709 | inst_cream->shtop_func = get_shtop(inst); |
| 1927 | if (inst_cream->Rd == 15) { | 1710 | if (inst_cream->Rd == 15) { |
| 1928 | inst_base->br = INDIRECT_BRANCH; | 1711 | inst_base->br = INDIRECT_BRANCH; |
| 1929 | } | 1712 | } |
| 1930 | return inst_base; | 1713 | return inst_base; |
| 1931 | } | 1714 | } |
| 1932 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index) | 1715 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index) |
| 1933 | { | 1716 | { |
| 1934 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst)); | 1717 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst)); |
| 1935 | inst_base->cond = BITS(inst, 28, 31); | 1718 | inst_base->cond = BITS(inst, 28, 31); |
| 1936 | inst_base->idx = index; | 1719 | inst_base->idx = index; |
| 1937 | inst_base->br = NON_BRANCH; | 1720 | inst_base->br = NON_BRANCH; |
| 1938 | 1721 | ||
| 1939 | return inst_base; | 1722 | return inst_base; |
| 1940 | } | 1723 | } |
| 1941 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index) | 1724 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index) |
| 1942 | { | 1725 | { |
| 1943 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1726 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 1944 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1727 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 1945 | 1728 | ||
| 1946 | inst_base->cond = BITS(inst, 28, 31); | 1729 | inst_base->cond = BITS(inst, 28, 31); |
| 1947 | inst_base->idx = index; | 1730 | inst_base->idx = index; |
| 1948 | inst_base->br = NON_BRANCH; | 1731 | inst_base->br = NON_BRANCH; |
| 1949 | 1732 | ||
| 1950 | inst_cream->inst = inst; | 1733 | inst_cream->inst = inst; |
| 1951 | inst_cream->get_addr = get_calc_addr_op(inst); | 1734 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 1952 | 1735 | ||
| 1953 | if (BIT(inst, 15)) { | 1736 | if (BIT(inst, 15)) { |
| 1954 | inst_base->br = INDIRECT_BRANCH; | 1737 | inst_base->br = INDIRECT_BRANCH; |
| 1955 | } | 1738 | } |
| 1956 | return inst_base; | 1739 | return inst_base; |
| 1957 | } | 1740 | } |
| 1958 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index) | 1741 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index) |
| 1959 | { | 1742 | { |
| 1960 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); | 1743 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); |
| 1961 | sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; | 1744 | sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; |
| 1962 | 1745 | ||
| 1963 | inst_base->cond = BITS(inst, 28, 31); | 1746 | inst_base->cond = BITS(inst, 28, 31); |
| 1964 | inst_base->idx = index; | 1747 | inst_base->idx = index; |
| 1965 | inst_base->br = NON_BRANCH; | 1748 | inst_base->br = NON_BRANCH; |
| 1966 | inst_base->load_r15 = 0; | 1749 | inst_base->load_r15 = 0; |
| 1967 | 1750 | ||
| 1968 | inst_cream->Rd = BITS(inst, 12, 15); | 1751 | inst_cream->Rd = BITS(inst, 12, 15); |
| 1969 | inst_cream->Rm = BITS(inst, 0, 3); | 1752 | inst_cream->Rm = BITS(inst, 0, 3); |
| 1970 | inst_cream->rotate = BITS(inst, 10, 11); | 1753 | inst_cream->rotate = BITS(inst, 10, 11); |
| 1971 | if (CHECK_RM) | 1754 | if (CHECK_RM) |
| 1972 | inst_base->load_r15 = 1; | 1755 | inst_base->load_r15 = 1; |
| 1973 | 1756 | ||
| 1974 | return inst_base; | 1757 | return inst_base; |
| 1975 | } | 1758 | } |
| 1976 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index) | 1759 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index) |
| 1977 | { | 1760 | { |
| 1978 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1761 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 1979 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1762 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 1980 | 1763 | ||
| 1981 | inst_base->cond = BITS(inst, 28, 31); | 1764 | inst_base->cond = BITS(inst, 28, 31); |
| 1982 | inst_base->idx = index; | 1765 | inst_base->idx = index; |
| 1983 | inst_base->br = NON_BRANCH; | 1766 | inst_base->br = NON_BRANCH; |
| 1984 | inst_base->load_r15 = 0; | 1767 | inst_base->load_r15 = 0; |
| 1985 | 1768 | ||
| 1986 | inst_cream->inst = inst; | 1769 | inst_cream->inst = inst; |
| 1987 | inst_cream->get_addr = get_calc_addr_op(inst); | 1770 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 1988 | 1771 | ||
| 1989 | if (BITS(inst, 12, 15) == 15) { | 1772 | if (BITS(inst, 12, 15) == 15) { |
| 1990 | inst_base->br = INDIRECT_BRANCH; | 1773 | inst_base->br = INDIRECT_BRANCH; |
| 1991 | } | 1774 | } |
| 1992 | return inst_base; | 1775 | return inst_base; |
| 1993 | } | 1776 | } |
| 1994 | 1777 | ||
| 1995 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index) | 1778 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index) |
| 1996 | { | 1779 | { |
| 1997 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1780 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 1998 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1781 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 1999 | 1782 | ||
| 2000 | inst_base->cond = BITS(inst, 28, 31); | 1783 | inst_base->cond = BITS(inst, 28, 31); |
| 2001 | inst_base->idx = index; | 1784 | inst_base->idx = index; |
| 2002 | inst_base->br = NON_BRANCH; | 1785 | inst_base->br = NON_BRANCH; |
| 2003 | inst_base->load_r15 = 0; | 1786 | inst_base->load_r15 = 0; |
| 2004 | 1787 | ||
| 2005 | inst_cream->inst = inst; | 1788 | inst_cream->inst = inst; |
| 2006 | inst_cream->get_addr = get_calc_addr_op(inst); | 1789 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2007 | 1790 | ||
| 2008 | if (BITS(inst, 12, 15) == 15) { | 1791 | if (BITS(inst, 12, 15) == 15) { |
| 2009 | inst_base->br = INDIRECT_BRANCH; | 1792 | inst_base->br = INDIRECT_BRANCH; |
| 2010 | } | 1793 | } |
| 2011 | return inst_base; | 1794 | return inst_base; |
| 2012 | } | 1795 | } |
| 2013 | 1796 | ||
| 2014 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index) | 1797 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index) |
| 2015 | { | 1798 | { |
| 2016 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); | 1799 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); |
| 2017 | uxth_inst *inst_cream = (uxth_inst *)inst_base->component; | 1800 | uxth_inst *inst_cream = (uxth_inst *)inst_base->component; |
| 2018 | 1801 | ||
| 2019 | inst_base->cond = BITS(inst, 28, 31); | 1802 | inst_base->cond = BITS(inst, 28, 31); |
| 2020 | inst_base->idx = index; | 1803 | inst_base->idx = index; |
| 2021 | inst_base->br = NON_BRANCH; | 1804 | inst_base->br = NON_BRANCH; |
| 2022 | inst_base->load_r15 = 0; | 1805 | inst_base->load_r15 = 0; |
| 2023 | 1806 | ||
| 2024 | inst_cream->Rd = BITS(inst, 12, 15); | 1807 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2025 | inst_cream->rotate = BITS(inst, 10, 11); | 1808 | inst_cream->rotate = BITS(inst, 10, 11); |
| 2026 | inst_cream->Rm = BITS(inst, 0, 3); | 1809 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2027 | if (CHECK_RM) | 1810 | if (CHECK_RM) |
| 2028 | inst_base->load_r15 = 1; | 1811 | inst_base->load_r15 = 1; |
| 2029 | 1812 | ||
| 2030 | return inst_base; | 1813 | return inst_base; |
| 2031 | } | 1814 | } |
| 2032 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index) | 1815 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index) |
| 2033 | { | 1816 | { |
| 2034 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst)); | 1817 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst)); |
| 2035 | uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component; | 1818 | uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component; |
| 2036 | 1819 | ||
| 2037 | inst_base->cond = BITS(inst, 28, 31); | 1820 | inst_base->cond = BITS(inst, 28, 31); |
| 2038 | inst_base->idx = index; | 1821 | inst_base->idx = index; |
| 2039 | inst_base->br = NON_BRANCH; | 1822 | inst_base->br = NON_BRANCH; |
| 2040 | inst_base->load_r15 = 0; | 1823 | inst_base->load_r15 = 0; |
| 2041 | 1824 | ||
| 2042 | inst_cream->Rn = BITS(inst, 16, 19); | 1825 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2043 | inst_cream->Rd = BITS(inst, 12, 15); | 1826 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2044 | inst_cream->rotate = BITS(inst, 10, 11); | 1827 | inst_cream->rotate = BITS(inst, 10, 11); |
| 2045 | inst_cream->Rm = BITS(inst, 0, 3); | 1828 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2046 | if (CHECK_RM || CHECK_RN) | 1829 | if (CHECK_RM || CHECK_RN) |
| 2047 | inst_base->load_r15 = 1; | 1830 | inst_base->load_r15 = 1; |
| 2048 | 1831 | ||
| 2049 | return inst_base; | 1832 | return inst_base; |
| 2050 | } | 1833 | } |
| 2051 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index) | 1834 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index) |
| 2052 | { | 1835 | { |
| 2053 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1836 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2054 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1837 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2055 | 1838 | ||
| 2056 | inst_base->cond = BITS(inst, 28, 31); | 1839 | inst_base->cond = BITS(inst, 28, 31); |
| 2057 | inst_base->idx = index; | 1840 | inst_base->idx = index; |
| 2058 | inst_base->br = NON_BRANCH; | 1841 | inst_base->br = NON_BRANCH; |
| 2059 | 1842 | ||
| 2060 | inst_cream->inst = inst; | 1843 | inst_cream->inst = inst; |
| 2061 | inst_cream->get_addr = get_calc_addr_op(inst); | 1844 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2062 | 1845 | ||
| 2063 | if (BITS(inst, 12, 15) == 15) { | 1846 | if (BITS(inst, 12, 15) == 15) { |
| 2064 | inst_base->br = INDIRECT_BRANCH; | 1847 | inst_base->br = INDIRECT_BRANCH; |
| 2065 | } | 1848 | } |
| 2066 | return inst_base; | 1849 | return inst_base; |
| 2067 | } | 1850 | } |
| 2068 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index) | 1851 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index) |
| 2069 | { | 1852 | { |
| 2070 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1853 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2071 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1854 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2072 | 1855 | ||
| 2073 | inst_base->cond = BITS(inst, 28, 31); | 1856 | inst_base->cond = BITS(inst, 28, 31); |
| 2074 | inst_base->idx = index; | 1857 | inst_base->idx = index; |
| 2075 | inst_base->br = NON_BRANCH; | 1858 | inst_base->br = NON_BRANCH; |
| 2076 | 1859 | ||
| 2077 | inst_cream->inst = inst; | 1860 | inst_cream->inst = inst; |
| 2078 | if (I_BIT == 0) { | 1861 | if (I_BIT == 0) { |
| 2079 | inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); | 1862 | inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); |
| 2080 | } else { | 1863 | } else { |
| 2081 | DEBUG_MSG; | 1864 | DEBUG_MSG; |
| 2082 | } | 1865 | } |
| 2083 | #if 0 | 1866 | #if 0 |
| 2084 | inst_cream->get_addr = get_calc_addr_op(inst); | 1867 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2085 | if(inst == 0x54f13001) { | 1868 | if(inst == 0x54f13001) { |
| 2086 | DEBUG_LOG(ARM11, "get_calc_addr_op:%llx\n", inst_cream->get_addr); | 1869 | DEBUG_LOG(ARM11, "get_calc_addr_op:%llx\n", inst_cream->get_addr); |
| 2087 | } | 1870 | } |
| 2088 | #endif | 1871 | #endif |
| 2089 | 1872 | ||
| 2090 | if (BITS(inst, 12, 15) == 15) { | 1873 | if (BITS(inst, 12, 15) == 15) { |
| 2091 | inst_base->br = INDIRECT_BRANCH; | 1874 | inst_base->br = INDIRECT_BRANCH; |
| 2092 | } | 1875 | } |
| 2093 | return inst_base; | 1876 | return inst_base; |
| 2094 | } | 1877 | } |
| 2095 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index) | 1878 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index) |
| 2096 | { | 1879 | { |
| 2097 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1880 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2098 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1881 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2099 | 1882 | ||
| 2100 | inst_base->cond = BITS(inst, 28, 31); | 1883 | inst_base->cond = BITS(inst, 28, 31); |
| 2101 | inst_base->idx = index; | 1884 | inst_base->idx = index; |
| 2102 | inst_base->br = NON_BRANCH; | 1885 | inst_base->br = NON_BRANCH; |
| 2103 | 1886 | ||
| 2104 | inst_cream->inst = inst; | 1887 | inst_cream->inst = inst; |
| 2105 | inst_cream->get_addr = get_calc_addr_op(inst); | 1888 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2106 | 1889 | ||
| 2107 | return inst_base; | 1890 | return inst_base; |
| 2108 | } | 1891 | } |
| 2109 | 1892 | ||
| 2110 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index) | 1893 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index) |
| 2111 | { | 1894 | { |
| 2112 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1895 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2113 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1896 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2114 | 1897 | ||
| 2115 | inst_base->cond = BITS(inst, 28, 31); | 1898 | inst_base->cond = BITS(inst, 28, 31); |
| 2116 | inst_base->idx = index; | 1899 | inst_base->idx = index; |
| 2117 | inst_base->br = NON_BRANCH; | 1900 | inst_base->br = NON_BRANCH; |
| 2118 | 1901 | ||
| 2119 | inst_cream->inst = inst; | 1902 | inst_cream->inst = inst; |
| 2120 | //inst_cream->get_addr = get_calc_addr_op(inst); | 1903 | //inst_cream->get_addr = get_calc_addr_op(inst); |
| 2121 | 1904 | ||
| 2122 | if (BITS(inst, 12, 15) == 15) { | 1905 | if (BITS(inst, 12, 15) == 15) { |
| 2123 | inst_base->br = INDIRECT_BRANCH; | 1906 | inst_base->br = INDIRECT_BRANCH; |
| 2124 | } | 1907 | } |
| 2125 | return inst_base; | 1908 | return inst_base; |
| 2126 | } | 1909 | } |
| 2127 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index) | 1910 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index) |
| 2128 | { | 1911 | { |
| 2129 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1912 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2130 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1913 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2131 | 1914 | ||
| 2132 | inst_base->cond = BITS(inst, 28, 31); | 1915 | inst_base->cond = BITS(inst, 28, 31); |
| 2133 | inst_base->idx = index; | 1916 | inst_base->idx = index; |
| 2134 | inst_base->br = NON_BRANCH; | 1917 | inst_base->br = NON_BRANCH; |
| 2135 | 1918 | ||
| 2136 | inst_cream->inst = inst; | 1919 | inst_cream->inst = inst; |
| 2137 | inst_cream->get_addr = get_calc_addr_op(inst); | 1920 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2138 | 1921 | ||
| 2139 | if (BITS(inst, 12, 15) == 15) { | 1922 | if (BITS(inst, 12, 15) == 15) { |
| 2140 | inst_base->br = INDIRECT_BRANCH; | 1923 | inst_base->br = INDIRECT_BRANCH; |
| 2141 | } | 1924 | } |
| 2142 | return inst_base; | 1925 | return inst_base; |
| 2143 | } | 1926 | } |
| 2144 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index) | 1927 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index) |
| 2145 | { | 1928 | { |
| 2146 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1929 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2147 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1930 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2148 | 1931 | ||
| 2149 | inst_base->cond = BITS(inst, 28, 31); | 1932 | inst_base->cond = BITS(inst, 28, 31); |
| 2150 | inst_base->idx = index; | 1933 | inst_base->idx = index; |
| 2151 | inst_base->br = NON_BRANCH; | 1934 | inst_base->br = NON_BRANCH; |
| 2152 | 1935 | ||
| 2153 | inst_cream->inst = inst; | 1936 | inst_cream->inst = inst; |
| 2154 | inst_cream->get_addr = get_calc_addr_op(inst); | 1937 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2155 | 1938 | ||
| 2156 | if (BITS(inst, 12, 15) == 15) { | 1939 | if (BITS(inst, 12, 15) == 15) { |
| 2157 | inst_base->br = INDIRECT_BRANCH; | 1940 | inst_base->br = INDIRECT_BRANCH; |
| 2158 | } | 1941 | } |
| 2159 | return inst_base; | 1942 | return inst_base; |
| 2160 | } | 1943 | } |
| 2161 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index) | 1944 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index) |
| 2162 | { | 1945 | { |
| 2163 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1946 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2164 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1947 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2165 | 1948 | ||
| 2166 | inst_base->cond = BITS(inst, 28, 31); | 1949 | inst_base->cond = BITS(inst, 28, 31); |
| 2167 | inst_base->idx = index; | 1950 | inst_base->idx = index; |
| 2168 | inst_base->br = NON_BRANCH; | 1951 | inst_base->br = NON_BRANCH; |
| 2169 | 1952 | ||
| 2170 | inst_cream->inst = inst; | 1953 | inst_cream->inst = inst; |
| 2171 | inst_cream->get_addr = get_calc_addr_op(inst); | 1954 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2172 | 1955 | ||
| 2173 | if (BITS(inst, 12, 15) == 15) { | 1956 | if (BITS(inst, 12, 15) == 15) { |
| 2174 | inst_base->br = INDIRECT_BRANCH; | 1957 | inst_base->br = INDIRECT_BRANCH; |
| 2175 | } | 1958 | } |
| 2176 | return inst_base; | 1959 | return inst_base; |
| 2177 | } | 1960 | } |
| 2178 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index) | 1961 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index) |
| 2179 | { | 1962 | { |
| 2180 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1963 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2181 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1964 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2182 | 1965 | ||
| 2183 | inst_base->cond = BITS(inst, 28, 31); | 1966 | inst_base->cond = BITS(inst, 28, 31); |
| 2184 | inst_base->idx = index; | 1967 | inst_base->idx = index; |
| 2185 | inst_base->br = NON_BRANCH; | 1968 | inst_base->br = NON_BRANCH; |
| 2186 | 1969 | ||
| 2187 | inst_cream->inst = inst; | 1970 | inst_cream->inst = inst; |
| 2188 | inst_cream->get_addr = get_calc_addr_op(inst); | 1971 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2189 | 1972 | ||
| 2190 | if (BITS(inst, 12, 15) == 15) { | 1973 | if (BITS(inst, 12, 15) == 15) { |
| 2191 | inst_base->br = INDIRECT_BRANCH; | 1974 | inst_base->br = INDIRECT_BRANCH; |
| 2192 | } | 1975 | } |
| 2193 | return inst_base; | 1976 | return inst_base; |
| 2194 | } | 1977 | } |
| 2195 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index) | 1978 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index) |
| 2196 | { | 1979 | { |
| 2197 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1980 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2198 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1981 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2199 | 1982 | ||
| 2200 | inst_base->cond = BITS(inst, 28, 31); | 1983 | inst_base->cond = BITS(inst, 28, 31); |
| 2201 | inst_base->idx = index; | 1984 | inst_base->idx = index; |
| 2202 | inst_base->br = NON_BRANCH; | 1985 | inst_base->br = NON_BRANCH; |
| 2203 | 1986 | ||
| 2204 | inst_cream->inst = inst; | 1987 | inst_cream->inst = inst; |
| 2205 | if (I_BIT == 0) { | 1988 | if (I_BIT == 0) { |
| 2206 | inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); | 1989 | inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); |
| 2207 | } else { | 1990 | } else { |
| 2208 | DEBUG_MSG; | 1991 | DEBUG_MSG; |
| 2209 | } | 1992 | } |
| 2210 | 1993 | ||
| 2211 | if (BITS(inst, 12, 15) == 15) { | 1994 | if (BITS(inst, 12, 15) == 15) { |
| 2212 | inst_base->br = INDIRECT_BRANCH; | 1995 | inst_base->br = INDIRECT_BRANCH; |
| 2213 | } | 1996 | } |
| 2214 | return inst_base; | 1997 | return inst_base; |
| 2215 | } | 1998 | } |
| 2216 | ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index) | 1999 | ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index) |
| 2217 | { | 2000 | { |
| 2218 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst)); | 2001 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst)); |
| 2219 | mcr_inst *inst_cream = (mcr_inst *)inst_base->component; | 2002 | mcr_inst *inst_cream = (mcr_inst *)inst_base->component; |
| 2220 | inst_base->cond = BITS(inst, 28, 31); | 2003 | inst_base->cond = BITS(inst, 28, 31); |
| 2221 | inst_base->idx = index; | 2004 | inst_base->idx = index; |
| 2222 | inst_base->br = NON_BRANCH; | 2005 | inst_base->br = NON_BRANCH; |
| 2223 | 2006 | ||
| 2224 | inst_cream->crn = BITS(inst, 16, 19); | 2007 | inst_cream->crn = BITS(inst, 16, 19); |
| 2225 | inst_cream->crm = BITS(inst, 0, 3); | 2008 | inst_cream->crm = BITS(inst, 0, 3); |
| 2226 | inst_cream->opcode_1 = BITS(inst, 21, 23); | 2009 | inst_cream->opcode_1 = BITS(inst, 21, 23); |
| 2227 | inst_cream->opcode_2 = BITS(inst, 5, 7); | 2010 | inst_cream->opcode_2 = BITS(inst, 5, 7); |
| 2228 | inst_cream->Rd = BITS(inst, 12, 15); | 2011 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2229 | inst_cream->cp_num = BITS(inst, 8, 11); | 2012 | inst_cream->cp_num = BITS(inst, 8, 11); |
| 2230 | inst_cream->inst = inst; | 2013 | inst_cream->inst = inst; |
| 2231 | return inst_base; | 2014 | return inst_base; |
| 2232 | } | 2015 | } |
| 2233 | ARM_INST_PTR INTERPRETER_TRANSLATE(mcrr)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("MCRR"); } | 2016 | ARM_INST_PTR INTERPRETER_TRANSLATE(mcrr)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("MCRR"); } |
| 2234 | ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index) | 2017 | ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index) |
| 2235 | { | 2018 | { |
| 2236 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst)); | 2019 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst)); |
| 2237 | mla_inst *inst_cream = (mla_inst *)inst_base->component; | 2020 | mla_inst *inst_cream = (mla_inst *)inst_base->component; |
| 2238 | 2021 | ||
| 2239 | inst_base->cond = BITS(inst, 28, 31); | 2022 | inst_base->cond = BITS(inst, 28, 31); |
| 2240 | inst_base->idx = index; | 2023 | inst_base->idx = index; |
| 2241 | inst_base->br = NON_BRANCH; | 2024 | inst_base->br = NON_BRANCH; |
| 2242 | inst_base->load_r15 = 0; | 2025 | inst_base->load_r15 = 0; |
| 2243 | 2026 | ||
| 2244 | inst_cream->S = BIT(inst, 20); | 2027 | inst_cream->S = BIT(inst, 20); |
| 2245 | inst_cream->Rn = BITS(inst, 12, 15); | 2028 | inst_cream->Rn = BITS(inst, 12, 15); |
| 2246 | inst_cream->Rd = BITS(inst, 16, 19); | 2029 | inst_cream->Rd = BITS(inst, 16, 19); |
| 2247 | inst_cream->Rs = BITS(inst, 8, 11); | 2030 | inst_cream->Rs = BITS(inst, 8, 11); |
| 2248 | inst_cream->Rm = BITS(inst, 0, 3); | 2031 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2249 | 2032 | ||
| 2250 | if (CHECK_RM || CHECK_RN || CHECK_RS) | 2033 | if (CHECK_RM || CHECK_RN || CHECK_RS) |
| 2251 | inst_base->load_r15 = 1; | 2034 | inst_base->load_r15 = 1; |
| 2252 | 2035 | ||
| 2253 | return inst_base; | 2036 | return inst_base; |
| 2254 | } | 2037 | } |
| 2255 | ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index) | 2038 | ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index) |
| 2256 | { | 2039 | { |
| 2257 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); | 2040 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); |
| 2258 | mov_inst *inst_cream = (mov_inst *)inst_base->component; | 2041 | mov_inst *inst_cream = (mov_inst *)inst_base->component; |
| 2259 | 2042 | ||
| 2260 | inst_base->cond = BITS(inst, 28, 31); | 2043 | inst_base->cond = BITS(inst, 28, 31); |
| 2261 | inst_base->idx = index; | 2044 | inst_base->idx = index; |
| 2262 | inst_base->br = NON_BRANCH; | 2045 | inst_base->br = NON_BRANCH; |
| 2263 | 2046 | ||
| 2264 | inst_cream->I = BIT(inst, 25); | 2047 | inst_cream->I = BIT(inst, 25); |
| 2265 | inst_cream->S = BIT(inst, 20); | 2048 | inst_cream->S = BIT(inst, 20); |
| 2266 | inst_cream->Rd = BITS(inst, 12, 15); | 2049 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2267 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2050 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 2268 | inst_cream->shtop_func = get_shtop(inst); | 2051 | inst_cream->shtop_func = get_shtop(inst); |
| 2269 | 2052 | ||
| 2270 | if (inst_cream->Rd == 15) { | 2053 | if (inst_cream->Rd == 15) { |
| 2271 | inst_base->br = INDIRECT_BRANCH; | 2054 | inst_base->br = INDIRECT_BRANCH; |
| 2272 | } | 2055 | } |
| 2273 | return inst_base; | 2056 | return inst_base; |
| 2274 | } | 2057 | } |
| 2275 | ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index) | 2058 | ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index) |
| 2276 | { | 2059 | { |
| 2277 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst)); | 2060 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst)); |
| 2278 | mrc_inst *inst_cream = (mrc_inst *)inst_base->component; | 2061 | mrc_inst *inst_cream = (mrc_inst *)inst_base->component; |
| 2279 | inst_base->cond = BITS(inst, 28, 31); | 2062 | inst_base->cond = BITS(inst, 28, 31); |
| 2280 | inst_base->idx = index; | 2063 | inst_base->idx = index; |
| 2281 | inst_base->br = NON_BRANCH; | 2064 | inst_base->br = NON_BRANCH; |
| 2282 | 2065 | ||
| 2283 | inst_cream->crn = BITS(inst, 16, 19); | 2066 | inst_cream->crn = BITS(inst, 16, 19); |
| 2284 | inst_cream->crm = BITS(inst, 0, 3); | 2067 | inst_cream->crm = BITS(inst, 0, 3); |
| 2285 | inst_cream->opcode_1 = BITS(inst, 21, 23); | 2068 | inst_cream->opcode_1 = BITS(inst, 21, 23); |
| 2286 | inst_cream->opcode_2 = BITS(inst, 5, 7); | 2069 | inst_cream->opcode_2 = BITS(inst, 5, 7); |
| 2287 | inst_cream->Rd = BITS(inst, 12, 15); | 2070 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2288 | inst_cream->cp_num = BITS(inst, 8, 11); | 2071 | inst_cream->cp_num = BITS(inst, 8, 11); |
| 2289 | inst_cream->inst = inst; | 2072 | inst_cream->inst = inst; |
| 2290 | return inst_base; | 2073 | return inst_base; |
| 2291 | } | 2074 | } |
| 2292 | ARM_INST_PTR INTERPRETER_TRANSLATE(mrrc)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("MRRC"); } | 2075 | ARM_INST_PTR INTERPRETER_TRANSLATE(mrrc)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("MRRC"); } |
| 2293 | ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index) | 2076 | ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index) |
| 2294 | { | 2077 | { |
| 2295 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst)); | 2078 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst)); |
| 2296 | mrs_inst *inst_cream = (mrs_inst *)inst_base->component; | 2079 | mrs_inst *inst_cream = (mrs_inst *)inst_base->component; |
| 2297 | 2080 | ||
| 2298 | inst_base->cond = BITS(inst, 28, 31); | 2081 | inst_base->cond = BITS(inst, 28, 31); |
| 2299 | inst_base->idx = index; | 2082 | inst_base->idx = index; |
| 2300 | inst_base->br = NON_BRANCH; | 2083 | inst_base->br = NON_BRANCH; |
| 2301 | 2084 | ||
| 2302 | inst_cream->Rd = BITS(inst, 12, 15); | 2085 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2303 | inst_cream->R = BIT(inst, 22); | 2086 | inst_cream->R = BIT(inst, 22); |
| 2304 | 2087 | ||
| 2305 | return inst_base; | 2088 | return inst_base; |
| 2306 | } | 2089 | } |
| 2307 | ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index) | 2090 | ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index) |
| 2308 | { | 2091 | { |
| 2309 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst)); | 2092 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst)); |
| 2310 | msr_inst *inst_cream = (msr_inst *)inst_base->component; | 2093 | msr_inst *inst_cream = (msr_inst *)inst_base->component; |
| 2311 | 2094 | ||
| 2312 | inst_base->cond = BITS(inst, 28, 31); | 2095 | inst_base->cond = BITS(inst, 28, 31); |
| 2313 | inst_base->idx = index; | 2096 | inst_base->idx = index; |
| 2314 | inst_base->br = NON_BRANCH; | 2097 | inst_base->br = NON_BRANCH; |
| 2315 | 2098 | ||
| 2316 | inst_cream->field_mask = BITS(inst, 16, 19); | 2099 | inst_cream->field_mask = BITS(inst, 16, 19); |
| 2317 | inst_cream->R = BIT(inst, 22); | 2100 | inst_cream->R = BIT(inst, 22); |
| 2318 | inst_cream->inst = inst; | 2101 | inst_cream->inst = inst; |
| 2319 | 2102 | ||
| 2320 | return inst_base; | 2103 | return inst_base; |
| 2321 | } | 2104 | } |
| 2322 | ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index) | 2105 | ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index) |
| 2323 | { | 2106 | { |
| 2324 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst)); | 2107 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst)); |
| 2325 | mul_inst *inst_cream = (mul_inst *)inst_base->component; | 2108 | mul_inst *inst_cream = (mul_inst *)inst_base->component; |
| 2326 | 2109 | ||
| 2327 | inst_base->cond = BITS(inst, 28, 31); | 2110 | inst_base->cond = BITS(inst, 28, 31); |
| 2328 | inst_base->idx = index; | 2111 | inst_base->idx = index; |
| 2329 | inst_base->br = NON_BRANCH; | 2112 | inst_base->br = NON_BRANCH; |
| 2330 | inst_base->load_r15 = 0; | 2113 | inst_base->load_r15 = 0; |
| 2331 | 2114 | ||
| 2332 | inst_cream->S = BIT(inst, 20); | 2115 | inst_cream->S = BIT(inst, 20); |
| 2333 | inst_cream->Rm = BITS(inst, 0, 3); | 2116 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2334 | inst_cream->Rs = BITS(inst, 8, 11); | 2117 | inst_cream->Rs = BITS(inst, 8, 11); |
| 2335 | inst_cream->Rd = BITS(inst, 16, 19); | 2118 | inst_cream->Rd = BITS(inst, 16, 19); |
| 2336 | 2119 | ||
| 2337 | if (CHECK_RM || CHECK_RS) | 2120 | if (CHECK_RM || CHECK_RS) |
| 2338 | inst_base->load_r15 = 1; | 2121 | inst_base->load_r15 = 1; |
| 2339 | return inst_base; | 2122 | return inst_base; |
| 2340 | } | 2123 | } |
| 2341 | ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index) | 2124 | ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index) |
| 2342 | { | 2125 | { |
| 2343 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst)); | 2126 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst)); |
| 2344 | mvn_inst *inst_cream = (mvn_inst *)inst_base->component; | 2127 | mvn_inst *inst_cream = (mvn_inst *)inst_base->component; |
| 2345 | 2128 | ||
| 2346 | inst_base->cond = BITS(inst, 28, 31); | 2129 | inst_base->cond = BITS(inst, 28, 31); |
| 2347 | inst_base->idx = index; | 2130 | inst_base->idx = index; |
| 2348 | inst_base->br = NON_BRANCH; | 2131 | inst_base->br = NON_BRANCH; |
| 2349 | 2132 | ||
| 2350 | inst_cream->I = BIT(inst, 25); | 2133 | inst_cream->I = BIT(inst, 25); |
| 2351 | inst_cream->S = BIT(inst, 20); | 2134 | inst_cream->S = BIT(inst, 20); |
| 2352 | inst_cream->Rd = BITS(inst, 12, 15); | 2135 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2353 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2136 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 2354 | inst_cream->shtop_func = get_shtop(inst); | 2137 | inst_cream->shtop_func = get_shtop(inst); |
| 2355 | 2138 | ||
| 2356 | if (inst_cream->Rd == 15) { | 2139 | if (inst_cream->Rd == 15) { |
| 2357 | inst_base->br = INDIRECT_BRANCH; | 2140 | inst_base->br = INDIRECT_BRANCH; |
| 2358 | } | 2141 | } |
| 2359 | return inst_base; | 2142 | return inst_base; |
| 2360 | 2143 | ||
| 2361 | } | 2144 | } |
| 2362 | ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index) | 2145 | ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index) |
| 2363 | { | 2146 | { |
| 2364 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst)); | 2147 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst)); |
| 2365 | orr_inst *inst_cream = (orr_inst *)inst_base->component; | 2148 | orr_inst *inst_cream = (orr_inst *)inst_base->component; |
| 2366 | 2149 | ||
| 2367 | inst_base->cond = BITS(inst, 28, 31); | 2150 | inst_base->cond = BITS(inst, 28, 31); |
| 2368 | inst_base->idx = index; | 2151 | inst_base->idx = index; |
| 2369 | inst_base->br = NON_BRANCH; | 2152 | inst_base->br = NON_BRANCH; |
| 2370 | inst_base->load_r15 = 0; | 2153 | inst_base->load_r15 = 0; |
| 2371 | 2154 | ||
| 2372 | inst_cream->I = BIT(inst, 25); | 2155 | inst_cream->I = BIT(inst, 25); |
| 2373 | inst_cream->S = BIT(inst, 20); | 2156 | inst_cream->S = BIT(inst, 20); |
| 2374 | inst_cream->Rd = BITS(inst, 12, 15); | 2157 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2375 | inst_cream->Rn = BITS(inst, 16, 19); | 2158 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2376 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2159 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 2377 | inst_cream->shtop_func = get_shtop(inst); | 2160 | inst_cream->shtop_func = get_shtop(inst); |
| 2378 | 2161 | ||
| 2379 | if (CHECK_RN) | 2162 | if (CHECK_RN) |
| 2380 | inst_base->load_r15 = 1; | 2163 | inst_base->load_r15 = 1; |
| 2381 | if (inst_cream->Rd == 15) { | 2164 | if (inst_cream->Rd == 15) { |
| 2382 | inst_base->br = INDIRECT_BRANCH; | 2165 | inst_base->br = INDIRECT_BRANCH; |
| 2383 | } | 2166 | } |
| 2384 | return inst_base; | 2167 | return inst_base; |
| 2385 | } | 2168 | } |
| 2386 | 2169 | ||
| 2387 | ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index) | 2170 | ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index) |
| 2388 | { | 2171 | { |
| 2389 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst)); | 2172 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst)); |
| 2390 | pkh_inst *inst_cream = (pkh_inst *)inst_base->component; | 2173 | pkh_inst *inst_cream = (pkh_inst *)inst_base->component; |
| 2391 | 2174 | ||
| 2392 | inst_base->cond = BITS(inst, 28, 31); | 2175 | inst_base->cond = BITS(inst, 28, 31); |
| 2393 | inst_base->idx = index; | 2176 | inst_base->idx = index; |
| 2394 | inst_base->br = NON_BRANCH; | 2177 | inst_base->br = NON_BRANCH; |
| 2395 | inst_base->load_r15 = 0; | 2178 | inst_base->load_r15 = 0; |
| 2396 | 2179 | ||
| 2397 | inst_cream->Rd = BITS(inst, 12, 15); | 2180 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2398 | inst_cream->Rn = BITS(inst, 16, 19); | 2181 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2399 | inst_cream->Rm = BITS(inst, 0, 3); | 2182 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2400 | inst_cream->imm = BITS(inst, 7, 11); | 2183 | inst_cream->imm = BITS(inst, 7, 11); |
| 2401 | 2184 | ||
| 2402 | return inst_base; | 2185 | return inst_base; |
| 2403 | } | 2186 | } |
| 2404 | 2187 | ||
| 2405 | ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index) | 2188 | ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index) |
| 2406 | { | 2189 | { |
| 2407 | return INTERPRETER_TRANSLATE(pkhbt)(inst, index); | 2190 | return INTERPRETER_TRANSLATE(pkhbt)(inst, index); |
| 2408 | } | 2191 | } |
| 2409 | 2192 | ||
| 2410 | ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index) | 2193 | ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index) |
| 2411 | { | 2194 | { |
| 2412 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst)); | 2195 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst)); |
| 2413 | 2196 | ||
| 2414 | inst_base->cond = BITS(inst, 28, 31); | 2197 | inst_base->cond = BITS(inst, 28, 31); |
| 2415 | inst_base->idx = index; | 2198 | inst_base->idx = index; |
| 2416 | inst_base->br = NON_BRANCH; | 2199 | inst_base->br = NON_BRANCH; |
| 2417 | inst_base->load_r15 = 0; | 2200 | inst_base->load_r15 = 0; |
| 2418 | 2201 | ||
| 2419 | return inst_base; | 2202 | return inst_base; |
| 2420 | } | 2203 | } |
| 2421 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD"); } | 2204 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD"); } |
| 2422 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index) | 2205 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index) |
| 2423 | { | 2206 | { |
| 2424 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); | 2207 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| 2425 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | 2208 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 2426 | 2209 | ||
| 2427 | inst_base->cond = BITS(inst, 28, 31); | 2210 | inst_base->cond = BITS(inst, 28, 31); |
| 2428 | inst_base->idx = index; | 2211 | inst_base->idx = index; |
| 2429 | inst_base->br = NON_BRANCH; | 2212 | inst_base->br = NON_BRANCH; |
| 2430 | inst_base->load_r15 = 0; | 2213 | inst_base->load_r15 = 0; |
| 2431 | 2214 | ||
| 2432 | inst_cream->Rm = BITS(inst, 0, 3); | 2215 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2433 | inst_cream->Rn = BITS(inst, 16, 19); | 2216 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2434 | inst_cream->Rd = BITS(inst, 12, 15); | 2217 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2435 | inst_cream->op1 = BITS(inst, 20, 21); | 2218 | inst_cream->op1 = BITS(inst, 20, 21); |
| 2436 | inst_cream->op2 = BITS(inst, 5, 7); | 2219 | inst_cream->op2 = BITS(inst, 5, 7); |
| 2437 | 2220 | ||
| 2438 | return inst_base; | 2221 | return inst_base; |
| 2439 | } | 2222 | } |
| 2440 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index) | 2223 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index) |
| 2441 | { | 2224 | { |
| 2442 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); | 2225 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); |
| 2443 | } | 2226 | } |
| 2444 | ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index) | 2227 | ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index) |
| 2445 | { | 2228 | { |
| 2446 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); | 2229 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); |
| 2447 | } | 2230 | } |
| 2448 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDADD"); } | 2231 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDADD"); } |
| 2449 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDSUB"); } | 2232 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDSUB"); } |
| 2450 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB"); } | 2233 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB"); } |
| 2451 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index) | 2234 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index) |
| 2452 | { | 2235 | { |
| 2453 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); | 2236 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); |
| 2454 | } | 2237 | } |
| 2455 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index) | 2238 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index) |
| 2456 | { | 2239 | { |
| 2457 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); | 2240 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); |
| 2458 | } | 2241 | } |
| 2459 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index) | 2242 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index) |
| 2460 | { | 2243 | { |
| 2461 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); | 2244 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); |
| 2462 | } | 2245 | } |
| 2463 | ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index) | 2246 | ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index) |
| 2464 | { | 2247 | { |
| 2465 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); | 2248 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); |
| 2466 | rev_inst *inst_cream = (rev_inst *)inst_base->component; | 2249 | rev_inst *inst_cream = (rev_inst *)inst_base->component; |
| 2467 | 2250 | ||
| 2468 | inst_base->cond = BITS(inst, 28, 31); | 2251 | inst_base->cond = BITS(inst, 28, 31); |
| 2469 | inst_base->idx = index; | 2252 | inst_base->idx = index; |
| 2470 | inst_base->br = NON_BRANCH; | 2253 | inst_base->br = NON_BRANCH; |
| 2471 | inst_base->load_r15 = 0; | 2254 | inst_base->load_r15 = 0; |
| 2472 | 2255 | ||
| 2473 | inst_cream->Rm = BITS(inst, 0, 3); | 2256 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2474 | inst_cream->Rd = BITS(inst, 12, 15); | 2257 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2475 | 2258 | ||
| 2476 | return inst_base; | 2259 | return inst_base; |
| 2477 | } | 2260 | } |
| 2478 | ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index){ | 2261 | ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index){ |
| 2479 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); | 2262 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); |
| 2480 | rev_inst *inst_cream = (rev_inst *)inst_base->component; | 2263 | rev_inst *inst_cream = (rev_inst *)inst_base->component; |
| 2481 | 2264 | ||
| 2482 | inst_base->cond = BITS(inst, 28, 31); | 2265 | inst_base->cond = BITS(inst, 28, 31); |
| 2483 | inst_base->idx = index; | 2266 | inst_base->idx = index; |
| 2484 | inst_base->br = NON_BRANCH; | 2267 | inst_base->br = NON_BRANCH; |
| 2485 | inst_base->load_r15 = 0; | 2268 | inst_base->load_r15 = 0; |
| 2486 | 2269 | ||
| 2487 | inst_cream->Rm = BITS(inst, 0, 3); | 2270 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2488 | inst_cream->Rd = BITS(inst, 12, 15); | 2271 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2489 | 2272 | ||
| 2490 | return inst_base; | 2273 | return inst_base; |
| 2491 | } | 2274 | } |
| 2492 | ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("REVSH"); } | 2275 | ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("REVSH"); } |
| 2493 | ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("RFE"); } | 2276 | ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("RFE"); } |
| 2494 | ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index) | 2277 | ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index) |
| 2495 | { | 2278 | { |
| 2496 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst)); | 2279 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst)); |
| 2497 | rsb_inst *inst_cream = (rsb_inst *)inst_base->component; | 2280 | rsb_inst *inst_cream = (rsb_inst *)inst_base->component; |
| 2498 | 2281 | ||
| 2499 | inst_base->cond = BITS(inst, 28, 31); | 2282 | inst_base->cond = BITS(inst, 28, 31); |
| 2500 | inst_base->idx = index; | 2283 | inst_base->idx = index; |
| 2501 | inst_base->br = NON_BRANCH; | 2284 | inst_base->br = NON_BRANCH; |
| 2502 | inst_base->load_r15 = 0; | 2285 | inst_base->load_r15 = 0; |
| 2503 | 2286 | ||
| 2504 | inst_cream->I = BIT(inst, 25); | 2287 | inst_cream->I = BIT(inst, 25); |
| 2505 | inst_cream->S = BIT(inst, 20); | 2288 | inst_cream->S = BIT(inst, 20); |
| 2506 | inst_cream->Rn = BITS(inst, 16, 19); | 2289 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2507 | inst_cream->Rd = BITS(inst, 12, 15); | 2290 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2508 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2291 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 2509 | inst_cream->shtop_func = get_shtop(inst); | 2292 | inst_cream->shtop_func = get_shtop(inst); |
| 2510 | if (CHECK_RN) | 2293 | if (CHECK_RN) |
| 2511 | inst_base->load_r15 = 1; | 2294 | inst_base->load_r15 = 1; |
| 2512 | 2295 | ||
| 2513 | if (inst_cream->Rd == 15) { | 2296 | if (inst_cream->Rd == 15) { |
| 2514 | inst_base->br = INDIRECT_BRANCH; | 2297 | inst_base->br = INDIRECT_BRANCH; |
| 2515 | } | 2298 | } |
| 2516 | return inst_base; | 2299 | return inst_base; |
| 2517 | } | 2300 | } |
| 2518 | ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index) | 2301 | ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index) |
| 2519 | { | 2302 | { |
| 2520 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst)); | 2303 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst)); |
| 2521 | rsc_inst *inst_cream = (rsc_inst *)inst_base->component; | 2304 | rsc_inst *inst_cream = (rsc_inst *)inst_base->component; |
| 2522 | 2305 | ||
| 2523 | inst_base->cond = BITS(inst, 28, 31); | 2306 | inst_base->cond = BITS(inst, 28, 31); |
| 2524 | inst_base->idx = index; | 2307 | inst_base->idx = index; |
| 2525 | inst_base->br = NON_BRANCH; | 2308 | inst_base->br = NON_BRANCH; |
| 2526 | inst_base->load_r15 = 0; | 2309 | inst_base->load_r15 = 0; |
| 2527 | 2310 | ||
| 2528 | inst_cream->I = BIT(inst, 25); | 2311 | inst_cream->I = BIT(inst, 25); |
| 2529 | inst_cream->S = BIT(inst, 20); | 2312 | inst_cream->S = BIT(inst, 20); |
| 2530 | inst_cream->Rn = BITS(inst, 16, 19); | 2313 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2531 | inst_cream->Rd = BITS(inst, 12, 15); | 2314 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2532 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2315 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 2533 | inst_cream->shtop_func = get_shtop(inst); | 2316 | inst_cream->shtop_func = get_shtop(inst); |
| 2534 | if (CHECK_RN) | 2317 | if (CHECK_RN) |
| 2535 | inst_base->load_r15 = 1; | 2318 | inst_base->load_r15 = 1; |
| 2536 | 2319 | ||
| 2537 | if (inst_cream->Rd == 15) { | 2320 | if (inst_cream->Rd == 15) { |
| 2538 | inst_base->br = INDIRECT_BRANCH; | 2321 | inst_base->br = INDIRECT_BRANCH; |
| 2539 | } | 2322 | } |
| 2540 | return inst_base; | 2323 | return inst_base; |
| 2541 | } | 2324 | } |
| 2542 | ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SADD8"); } | 2325 | ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SADD8"); } |
| 2543 | ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index) | 2326 | ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index) |
| 2544 | { | 2327 | { |
| 2545 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); | 2328 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| 2546 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | 2329 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 2547 | 2330 | ||
| 2548 | inst_base->cond = BITS(inst, 28, 31); | 2331 | inst_base->cond = BITS(inst, 28, 31); |
| 2549 | inst_base->idx = index; | 2332 | inst_base->idx = index; |
| 2550 | inst_base->br = NON_BRANCH; | 2333 | inst_base->br = NON_BRANCH; |
| 2551 | inst_base->load_r15 = 0; | 2334 | inst_base->load_r15 = 0; |
| 2552 | 2335 | ||
| 2553 | inst_cream->Rm = BITS(inst, 0, 3); | 2336 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2554 | inst_cream->Rn = BITS(inst, 16, 19); | 2337 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2555 | inst_cream->Rd = BITS(inst, 12, 15); | 2338 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2556 | inst_cream->op1 = BITS(inst, 20, 21); | 2339 | inst_cream->op1 = BITS(inst, 20, 21); |
| 2557 | inst_cream->op2 = BITS(inst, 5, 7); | 2340 | inst_cream->op2 = BITS(inst, 5, 7); |
| 2558 | 2341 | ||
| 2559 | return inst_base; | 2342 | return inst_base; |
| 2560 | } | 2343 | } |
| 2561 | ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index) | 2344 | ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index) |
| 2562 | { | 2345 | { |
| 2563 | return INTERPRETER_TRANSLATE(sadd16)(inst, index); | 2346 | return INTERPRETER_TRANSLATE(sadd16)(inst, index); |
| 2564 | } | 2347 | } |
| 2565 | ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index) | 2348 | ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index) |
| 2566 | { | 2349 | { |
| 2567 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst)); | 2350 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst)); |
| 2568 | sbc_inst *inst_cream = (sbc_inst *)inst_base->component; | 2351 | sbc_inst *inst_cream = (sbc_inst *)inst_base->component; |
| 2569 | 2352 | ||
| 2570 | inst_base->cond = BITS(inst, 28, 31); | 2353 | inst_base->cond = BITS(inst, 28, 31); |
| 2571 | inst_base->idx = index; | 2354 | inst_base->idx = index; |
| 2572 | inst_base->br = NON_BRANCH; | 2355 | inst_base->br = NON_BRANCH; |
| 2573 | inst_base->load_r15 = 0; | 2356 | inst_base->load_r15 = 0; |
| 2574 | 2357 | ||
| 2575 | inst_cream->I = BIT(inst, 25); | 2358 | inst_cream->I = BIT(inst, 25); |
| 2576 | inst_cream->S = BIT(inst, 20); | 2359 | inst_cream->S = BIT(inst, 20); |
| 2577 | inst_cream->Rn = BITS(inst, 16, 19); | 2360 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2578 | inst_cream->Rd = BITS(inst, 12, 15); | 2361 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2579 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2362 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 2580 | inst_cream->shtop_func = get_shtop(inst); | 2363 | inst_cream->shtop_func = get_shtop(inst); |
| 2581 | if (CHECK_RN) | 2364 | if (CHECK_RN) |
| 2582 | inst_base->load_r15 = 1; | 2365 | inst_base->load_r15 = 1; |
| 2583 | 2366 | ||
| 2584 | if (inst_cream->Rd == 15) { | 2367 | if (inst_cream->Rd == 15) { |
| 2585 | inst_base->br = INDIRECT_BRANCH; | 2368 | inst_base->br = INDIRECT_BRANCH; |
| 2586 | } | 2369 | } |
| 2587 | return inst_base; | 2370 | return inst_base; |
| 2588 | } | 2371 | } |
| 2589 | ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index) | 2372 | ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index) |
| 2590 | { | 2373 | { |
| 2591 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); | 2374 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| 2592 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | 2375 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 2593 | 2376 | ||
| 2594 | inst_base->cond = BITS(inst, 28, 31); | 2377 | inst_base->cond = BITS(inst, 28, 31); |
| 2595 | inst_base->idx = index; | 2378 | inst_base->idx = index; |
| 2596 | inst_base->br = NON_BRANCH; | 2379 | inst_base->br = NON_BRANCH; |
| 2597 | inst_base->load_r15 = 0; | 2380 | inst_base->load_r15 = 0; |
| 2598 | 2381 | ||
| 2599 | inst_cream->Rm = BITS(inst, 0, 3); | 2382 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2600 | inst_cream->Rn = BITS(inst, 16, 19); | 2383 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2601 | inst_cream->Rd = BITS(inst, 12, 15); | 2384 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2602 | inst_cream->op1 = BITS(inst, 20, 22); | 2385 | inst_cream->op1 = BITS(inst, 20, 22); |
| 2603 | inst_cream->op2 = BITS(inst, 5, 7); | 2386 | inst_cream->op2 = BITS(inst, 5, 7); |
| 2604 | 2387 | ||
| 2605 | return inst_base; | 2388 | return inst_base; |
| 2606 | } | 2389 | } |
| 2607 | ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SETEND"); } | 2390 | ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SETEND"); } |
| 2608 | ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADD16"); } | 2391 | 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 | |||
| 2613 | ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUBADDX"); } | 2396 | ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUBADDX"); } |
| 2614 | ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index) | 2397 | ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index) |
| 2615 | { | 2398 | { |
| 2616 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst)); | 2399 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst)); |
| 2617 | smla_inst *inst_cream = (smla_inst *)inst_base->component; | 2400 | smla_inst *inst_cream = (smla_inst *)inst_base->component; |
| 2618 | 2401 | ||
| 2619 | inst_base->cond = BITS(inst, 28, 31); | 2402 | inst_base->cond = BITS(inst, 28, 31); |
| 2620 | inst_base->idx = index; | 2403 | inst_base->idx = index; |
| 2621 | inst_base->br = NON_BRANCH; | 2404 | inst_base->br = NON_BRANCH; |
| 2622 | inst_base->load_r15 = 0; | 2405 | inst_base->load_r15 = 0; |
| 2623 | 2406 | ||
| 2624 | inst_cream->x = BIT(inst, 5); | 2407 | inst_cream->x = BIT(inst, 5); |
| 2625 | inst_cream->y = BIT(inst, 6); | 2408 | inst_cream->y = BIT(inst, 6); |
| 2626 | inst_cream->Rm = BITS(inst, 0, 3); | 2409 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2627 | inst_cream->Rs = BITS(inst, 8, 11); | 2410 | inst_cream->Rs = BITS(inst, 8, 11); |
| 2628 | inst_cream->Rd = BITS(inst, 16, 19); | 2411 | inst_cream->Rd = BITS(inst, 16, 19); |
| 2629 | inst_cream->Rn = BITS(inst, 12, 15); | 2412 | inst_cream->Rn = BITS(inst, 12, 15); |
| 2630 | 2413 | ||
| 2631 | return inst_base; | 2414 | return inst_base; |
| 2632 | } | 2415 | } |
| 2633 | ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index){ | 2416 | ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index){ |
| 2634 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); | 2417 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); |
| 2635 | smlad_inst *inst_cream = (smlad_inst *)inst_base->component; | 2418 | smlad_inst *inst_cream = (smlad_inst *)inst_base->component; |
| 2636 | 2419 | ||
| 2637 | inst_base->cond = BITS(inst, 28, 31); | 2420 | inst_base->cond = BITS(inst, 28, 31); |
| 2638 | inst_base->idx = index; | 2421 | inst_base->idx = index; |
| 2639 | inst_base->br = NON_BRANCH; | 2422 | inst_base->br = NON_BRANCH; |
| 2640 | inst_base->load_r15 = 0; | 2423 | inst_base->load_r15 = 0; |
| 2641 | 2424 | ||
| 2642 | inst_cream->m = BIT(inst, 4); | 2425 | inst_cream->m = BIT(inst, 4); |
| 2643 | inst_cream->Rn = BITS(inst, 0, 3); | 2426 | inst_cream->Rn = BITS(inst, 0, 3); |
| 2644 | inst_cream->Rm = BITS(inst, 8, 11); | 2427 | inst_cream->Rm = BITS(inst, 8, 11); |
| 2645 | inst_cream->Rd = BITS(inst, 16, 19); | 2428 | inst_cream->Rd = BITS(inst, 16, 19); |
| 2646 | inst_cream->Ra = BITS(inst, 12, 15); | 2429 | inst_cream->Ra = BITS(inst, 12, 15); |
| 2647 | 2430 | ||
| 2648 | if (CHECK_RM ) | 2431 | if (CHECK_RM ) |
| 2649 | inst_base->load_r15 = 1; | 2432 | inst_base->load_r15 = 1; |
| 2650 | return inst_base; | 2433 | return inst_base; |
| 2651 | } | 2434 | } |
| 2652 | ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index) | 2435 | ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index) |
| 2653 | { | 2436 | { |
| 2654 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); | 2437 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); |
| 2655 | umlal_inst *inst_cream = (umlal_inst *)inst_base->component; | 2438 | umlal_inst *inst_cream = (umlal_inst *)inst_base->component; |
| 2656 | 2439 | ||
| 2657 | inst_base->cond = BITS(inst, 28, 31); | 2440 | inst_base->cond = BITS(inst, 28, 31); |
| 2658 | inst_base->idx = index; | 2441 | inst_base->idx = index; |
| 2659 | inst_base->br = NON_BRANCH; | 2442 | inst_base->br = NON_BRANCH; |
| 2660 | inst_base->load_r15 = 0; | 2443 | inst_base->load_r15 = 0; |
| 2661 | 2444 | ||
| 2662 | inst_cream->S = BIT(inst, 20); | 2445 | inst_cream->S = BIT(inst, 20); |
| 2663 | inst_cream->Rm = BITS(inst, 0, 3); | 2446 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2664 | inst_cream->Rs = BITS(inst, 8, 11); | 2447 | inst_cream->Rs = BITS(inst, 8, 11); |
| 2665 | inst_cream->RdHi = BITS(inst, 16, 19); | 2448 | inst_cream->RdHi = BITS(inst, 16, 19); |
| 2666 | inst_cream->RdLo = BITS(inst, 12, 15); | 2449 | inst_cream->RdLo = BITS(inst, 12, 15); |
| 2667 | 2450 | ||
| 2668 | if (CHECK_RM || CHECK_RS) | 2451 | if (CHECK_RM || CHECK_RS) |
| 2669 | inst_base->load_r15 = 1; | 2452 | inst_base->load_r15 = 1; |
| 2670 | return inst_base; | 2453 | return inst_base; |
| 2671 | } | 2454 | } |
| 2672 | ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALXY"); } | 2455 | ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALXY"); } |
| 2673 | ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALD"); } | 2456 | 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 | |||
| 2680 | ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUAD"); } | 2463 | ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUAD"); } |
| 2681 | ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index) | 2464 | ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index) |
| 2682 | { | 2465 | { |
| 2683 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst)); | 2466 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst)); |
| 2684 | smul_inst *inst_cream = (smul_inst *)inst_base->component; | 2467 | smul_inst *inst_cream = (smul_inst *)inst_base->component; |
| 2685 | 2468 | ||
| 2686 | inst_base->cond = BITS(inst, 28, 31); | 2469 | inst_base->cond = BITS(inst, 28, 31); |
| 2687 | inst_base->idx = index; | 2470 | inst_base->idx = index; |
| 2688 | inst_base->br = NON_BRANCH; | 2471 | inst_base->br = NON_BRANCH; |
| 2689 | inst_base->load_r15 = 0; | 2472 | inst_base->load_r15 = 0; |
| 2690 | 2473 | ||
| 2691 | inst_cream->Rd = BITS(inst, 16, 19); | 2474 | inst_cream->Rd = BITS(inst, 16, 19); |
| 2692 | inst_cream->Rs = BITS(inst, 8, 11); | 2475 | inst_cream->Rs = BITS(inst, 8, 11); |
| 2693 | inst_cream->Rm = BITS(inst, 0, 3); | 2476 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2694 | 2477 | ||
| 2695 | inst_cream->x = BIT(inst, 5); | 2478 | inst_cream->x = BIT(inst, 5); |
| 2696 | inst_cream->y = BIT(inst, 6); | 2479 | inst_cream->y = BIT(inst, 6); |
| 2697 | 2480 | ||
| 2698 | if (CHECK_RM || CHECK_RS) | 2481 | if (CHECK_RM || CHECK_RS) |
| 2699 | inst_base->load_r15 = 1; | 2482 | inst_base->load_r15 = 1; |
| 2700 | return inst_base; | 2483 | return inst_base; |
| 2701 | 2484 | ||
| 2702 | } | 2485 | } |
| 2703 | ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index) | 2486 | ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index) |
| 2704 | { | 2487 | { |
| 2705 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); | 2488 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); |
| 2706 | umull_inst *inst_cream = (umull_inst *)inst_base->component; | 2489 | umull_inst *inst_cream = (umull_inst *)inst_base->component; |
| 2707 | 2490 | ||
| 2708 | inst_base->cond = BITS(inst, 28, 31); | 2491 | inst_base->cond = BITS(inst, 28, 31); |
| 2709 | inst_base->idx = index; | 2492 | inst_base->idx = index; |
| 2710 | inst_base->br = NON_BRANCH; | 2493 | inst_base->br = NON_BRANCH; |
| 2711 | inst_base->load_r15 = 0; | 2494 | inst_base->load_r15 = 0; |
| 2712 | 2495 | ||
| 2713 | inst_cream->S = BIT(inst, 20); | 2496 | inst_cream->S = BIT(inst, 20); |
| 2714 | inst_cream->Rm = BITS(inst, 0, 3); | 2497 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2715 | inst_cream->Rs = BITS(inst, 8, 11); | 2498 | inst_cream->Rs = BITS(inst, 8, 11); |
| 2716 | inst_cream->RdHi = BITS(inst, 16, 19); | 2499 | inst_cream->RdHi = BITS(inst, 16, 19); |
| 2717 | inst_cream->RdLo = BITS(inst, 12, 15); | 2500 | inst_cream->RdLo = BITS(inst, 12, 15); |
| 2718 | 2501 | ||
| 2719 | if (CHECK_RM || CHECK_RS) | 2502 | if (CHECK_RM || CHECK_RS) |
| 2720 | inst_base->load_r15 = 1; | 2503 | inst_base->load_r15 = 1; |
| 2721 | return inst_base; | 2504 | return inst_base; |
| 2722 | } | 2505 | } |
| 2723 | 2506 | ||
| 2724 | ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index) | 2507 | ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index) |
| 2725 | { | 2508 | { |
| 2726 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); | 2509 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); |
| 2727 | smlad_inst *inst_cream = (smlad_inst *)inst_base->component; | 2510 | smlad_inst *inst_cream = (smlad_inst *)inst_base->component; |
| 2728 | 2511 | ||
| 2729 | inst_base->cond = BITS(inst, 28, 31); | 2512 | inst_base->cond = BITS(inst, 28, 31); |
| 2730 | inst_base->idx = index; | 2513 | inst_base->idx = index; |
| 2731 | inst_base->br = NON_BRANCH; | 2514 | inst_base->br = NON_BRANCH; |
| 2732 | inst_base->load_r15 = 0; | 2515 | inst_base->load_r15 = 0; |
| 2733 | 2516 | ||
| 2734 | inst_cream->m = BIT(inst, 6); | 2517 | inst_cream->m = BIT(inst, 6); |
| 2735 | inst_cream->Rm = BITS(inst, 8, 11); | 2518 | inst_cream->Rm = BITS(inst, 8, 11); |
| 2736 | inst_cream->Rn = BITS(inst, 0, 3); | 2519 | inst_cream->Rn = BITS(inst, 0, 3); |
| 2737 | inst_cream->Rd = BITS(inst, 16, 19); | 2520 | inst_cream->Rd = BITS(inst, 16, 19); |
| 2738 | 2521 | ||
| 2739 | if (CHECK_RM || CHECK_RN) | 2522 | if (CHECK_RM || CHECK_RN) |
| 2740 | inst_base->load_r15 = 1; | 2523 | inst_base->load_r15 = 1; |
| 2741 | return inst_base; | 2524 | return inst_base; |
| 2742 | } | 2525 | } |
| 2743 | ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUSD"); } | 2526 | ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUSD"); } |
| 2744 | ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SRS"); } | 2527 | 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 | |||
| 2747 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSUB8"); } | 2530 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSUB8"); } |
| 2748 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index) | 2531 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index) |
| 2749 | { | 2532 | { |
| 2750 | return INTERPRETER_TRANSLATE(sadd16)(inst, index); | 2533 | return INTERPRETER_TRANSLATE(sadd16)(inst, index); |
| 2751 | } | 2534 | } |
| 2752 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index) | 2535 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index) |
| 2753 | { | 2536 | { |
| 2754 | return INTERPRETER_TRANSLATE(sadd16)(inst, index); | 2537 | return INTERPRETER_TRANSLATE(sadd16)(inst, index); |
| 2755 | } | 2538 | } |
| 2756 | ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index) | 2539 | ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index) |
| 2757 | { | 2540 | { |
| 2758 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst)); | 2541 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst)); |
| 2759 | inst_base->cond = BITS(inst, 28, 31); | 2542 | inst_base->cond = BITS(inst, 28, 31); |
| 2760 | inst_base->idx = index; | 2543 | inst_base->idx = index; |
| 2761 | inst_base->br = NON_BRANCH; | 2544 | inst_base->br = NON_BRANCH; |
| 2762 | 2545 | ||
| 2763 | return inst_base; | 2546 | return inst_base; |
| 2764 | } | 2547 | } |
| 2765 | ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(unsigned int inst, int index) | 2548 | ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(unsigned int inst, int index) |
| 2766 | { | 2549 | { |
| 2767 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2550 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2768 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2551 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2769 | 2552 | ||
| 2770 | inst_base->cond = BITS(inst, 28, 31); | 2553 | inst_base->cond = BITS(inst, 28, 31); |
| 2771 | inst_base->idx = index; | 2554 | inst_base->idx = index; |
| 2772 | inst_base->br = NON_BRANCH; | 2555 | inst_base->br = NON_BRANCH; |
| 2773 | 2556 | ||
| 2774 | inst_cream->inst = inst; | 2557 | inst_cream->inst = inst; |
| 2775 | inst_cream->get_addr = get_calc_addr_op(inst); | 2558 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2776 | return inst_base; | 2559 | return inst_base; |
| 2777 | } | 2560 | } |
| 2778 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index) | 2561 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index) |
| 2779 | { | 2562 | { |
| 2780 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); | 2563 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); |
| 2781 | sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; | 2564 | sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; |
| 2782 | 2565 | ||
| 2783 | inst_base->cond = BITS(inst, 28, 31); | 2566 | inst_base->cond = BITS(inst, 28, 31); |
| 2784 | inst_base->idx = index; | 2567 | inst_base->idx = index; |
| 2785 | inst_base->br = NON_BRANCH; | 2568 | inst_base->br = NON_BRANCH; |
| 2786 | inst_base->load_r15 = 0; | 2569 | inst_base->load_r15 = 0; |
| 2787 | 2570 | ||
| 2788 | inst_cream->Rd = BITS(inst, 12, 15); | 2571 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2789 | inst_cream->Rm = BITS(inst, 0, 3); | 2572 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2790 | inst_cream->rotate = BITS(inst, 10, 11); | 2573 | inst_cream->rotate = BITS(inst, 10, 11); |
| 2791 | 2574 | ||
| 2792 | if (CHECK_RM) | 2575 | if (CHECK_RM) |
| 2793 | inst_base->load_r15 = 1; | 2576 | inst_base->load_r15 = 1; |
| 2794 | return inst_base; | 2577 | return inst_base; |
| 2795 | } | 2578 | } |
| 2796 | ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index) | 2579 | ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index) |
| 2797 | { | 2580 | { |
| 2798 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2581 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2799 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2582 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2800 | 2583 | ||
| 2801 | inst_base->cond = BITS(inst, 28, 31); | 2584 | inst_base->cond = BITS(inst, 28, 31); |
| 2802 | inst_base->idx = index; | 2585 | inst_base->idx = index; |
| 2803 | inst_base->br = NON_BRANCH; | 2586 | inst_base->br = NON_BRANCH; |
| 2804 | 2587 | ||
| 2805 | inst_cream->inst = inst; | 2588 | inst_cream->inst = inst; |
| 2806 | inst_cream->get_addr = get_calc_addr_op(inst); | 2589 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2807 | 2590 | ||
| 2808 | if (BITS(inst, 12, 15) == 15) { | 2591 | if (BITS(inst, 12, 15) == 15) { |
| 2809 | inst_base->br = INDIRECT_BRANCH; | 2592 | inst_base->br = INDIRECT_BRANCH; |
| 2810 | } | 2593 | } |
| 2811 | return inst_base; | 2594 | return inst_base; |
| 2812 | } | 2595 | } |
| 2813 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index) | 2596 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index) |
| 2814 | { | 2597 | { |
| 2815 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); | 2598 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); |
| 2816 | uxth_inst *inst_cream = (uxth_inst *)inst_base->component; | 2599 | uxth_inst *inst_cream = (uxth_inst *)inst_base->component; |
| 2817 | 2600 | ||
| 2818 | inst_base->cond = BITS(inst, 28, 31); | 2601 | inst_base->cond = BITS(inst, 28, 31); |
| 2819 | inst_base->idx = index; | 2602 | inst_base->idx = index; |
| 2820 | inst_base->br = NON_BRANCH; | 2603 | inst_base->br = NON_BRANCH; |
| 2821 | inst_base->load_r15 = 0; | 2604 | inst_base->load_r15 = 0; |
| 2822 | 2605 | ||
| 2823 | inst_cream->Rd = BITS(inst, 12, 15); | 2606 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2824 | inst_cream->rotate = BITS(inst, 10, 11); | 2607 | inst_cream->rotate = BITS(inst, 10, 11); |
| 2825 | inst_cream->Rm = BITS(inst, 0, 3); | 2608 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2826 | 2609 | ||
| 2827 | if (CHECK_RM) | 2610 | if (CHECK_RM) |
| 2828 | inst_base->load_r15 = 1; | 2611 | inst_base->load_r15 = 1; |
| 2829 | return inst_base; | 2612 | return inst_base; |
| 2830 | } | 2613 | } |
| 2831 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index) | 2614 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index) |
| 2832 | { | 2615 | { |
| 2833 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst)); | 2616 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst)); |
| 2834 | uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component; | 2617 | uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component; |
| 2835 | 2618 | ||
| 2836 | inst_base->cond = BITS(inst, 28, 31); | 2619 | inst_base->cond = BITS(inst, 28, 31); |
| 2837 | inst_base->idx = index; | 2620 | inst_base->idx = index; |
| 2838 | inst_base->br = NON_BRANCH; | 2621 | inst_base->br = NON_BRANCH; |
| 2839 | inst_base->load_r15 = 0; | 2622 | inst_base->load_r15 = 0; |
| 2840 | 2623 | ||
| 2841 | inst_cream->Rd = BITS(inst, 12, 15); | 2624 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2842 | inst_cream->rotate = BITS(inst, 10, 11); | 2625 | inst_cream->rotate = BITS(inst, 10, 11); |
| 2843 | inst_cream->Rm = BITS(inst, 0, 3); | 2626 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2844 | inst_cream->Rn = BITS(inst, 16, 19); | 2627 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2845 | 2628 | ||
| 2846 | return inst_base; | 2629 | return inst_base; |
| 2847 | } | 2630 | } |
| 2848 | ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index) | 2631 | ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index) |
| 2849 | { | 2632 | { |
| 2850 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2633 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2851 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2634 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2852 | 2635 | ||
| 2853 | inst_base->cond = BITS(inst, 28, 31); | 2636 | inst_base->cond = BITS(inst, 28, 31); |
| 2854 | inst_base->idx = index; | 2637 | inst_base->idx = index; |
| 2855 | inst_base->br = NON_BRANCH; | 2638 | inst_base->br = NON_BRANCH; |
| 2856 | 2639 | ||
| 2857 | inst_cream->inst = inst; | 2640 | inst_cream->inst = inst; |
| 2858 | inst_cream->get_addr = get_calc_addr_op(inst); | 2641 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2859 | 2642 | ||
| 2860 | if (BITS(inst, 12, 15) == 15) { | 2643 | if (BITS(inst, 12, 15) == 15) { |
| 2861 | inst_base->br = INDIRECT_BRANCH; | 2644 | inst_base->br = INDIRECT_BRANCH; |
| 2862 | } | 2645 | } |
| 2863 | return inst_base; | 2646 | return inst_base; |
| 2864 | } | 2647 | } |
| 2865 | ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index) | 2648 | ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index) |
| 2866 | { | 2649 | { |
| 2867 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2650 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2868 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2651 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2869 | 2652 | ||
| 2870 | inst_base->cond = BITS(inst, 28, 31); | 2653 | inst_base->cond = BITS(inst, 28, 31); |
| 2871 | inst_base->idx = index; | 2654 | inst_base->idx = index; |
| 2872 | inst_base->br = NON_BRANCH; | 2655 | inst_base->br = NON_BRANCH; |
| 2873 | 2656 | ||
| 2874 | inst_cream->inst = inst; | 2657 | inst_cream->inst = inst; |
| 2875 | // inst_cream->get_addr = get_calc_addr_op(inst); | 2658 | // inst_cream->get_addr = get_calc_addr_op(inst); |
| 2876 | if (I_BIT == 0) { | 2659 | if (I_BIT == 0) { |
| 2877 | inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); | 2660 | inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); |
| 2878 | } else { | 2661 | } else { |
| 2879 | DEBUG_MSG; | 2662 | DEBUG_MSG; |
| 2880 | } | 2663 | } |
| 2881 | 2664 | ||
| 2882 | if (BITS(inst, 12, 15) == 15) { | 2665 | if (BITS(inst, 12, 15) == 15) { |
| 2883 | inst_base->br = INDIRECT_BRANCH; | 2666 | inst_base->br = INDIRECT_BRANCH; |
| 2884 | } | 2667 | } |
| 2885 | return inst_base; | 2668 | return inst_base; |
| 2886 | } | 2669 | } |
| 2887 | ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){ | 2670 | ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){ |
| 2888 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2671 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2889 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2672 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2890 | 2673 | ||
| 2891 | inst_base->cond = BITS(inst, 28, 31); | 2674 | inst_base->cond = BITS(inst, 28, 31); |
| 2892 | inst_base->idx = index; | 2675 | inst_base->idx = index; |
| 2893 | inst_base->br = NON_BRANCH; | 2676 | inst_base->br = NON_BRANCH; |
| 2894 | 2677 | ||
| 2895 | inst_cream->inst = inst; | 2678 | inst_cream->inst = inst; |
| 2896 | inst_cream->get_addr = get_calc_addr_op(inst); | 2679 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2897 | 2680 | ||
| 2898 | if (BITS(inst, 12, 15) == 15) { | 2681 | if (BITS(inst, 12, 15) == 15) { |
| 2899 | inst_base->br = INDIRECT_BRANCH; | 2682 | inst_base->br = INDIRECT_BRANCH; |
| 2900 | } | 2683 | } |
| 2901 | return inst_base; | 2684 | return inst_base; |
| 2902 | } | 2685 | } |
| 2903 | ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index) | 2686 | ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index) |
| 2904 | { | 2687 | { |
| 2905 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2688 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2906 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2689 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2907 | 2690 | ||
| 2908 | inst_base->cond = BITS(inst, 28, 31); | 2691 | inst_base->cond = BITS(inst, 28, 31); |
| 2909 | inst_base->idx = index; | 2692 | inst_base->idx = index; |
| 2910 | inst_base->br = NON_BRANCH; | 2693 | inst_base->br = NON_BRANCH; |
| 2911 | 2694 | ||
| 2912 | inst_cream->inst = inst; | 2695 | inst_cream->inst = inst; |
| 2913 | inst_cream->get_addr = get_calc_addr_op(inst); | 2696 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2914 | 2697 | ||
| 2915 | if (BITS(inst, 12, 15) == 15) { | 2698 | if (BITS(inst, 12, 15) == 15) { |
| 2916 | inst_base->br = INDIRECT_BRANCH; | 2699 | inst_base->br = INDIRECT_BRANCH; |
| 2917 | } | 2700 | } |
| 2918 | return inst_base; | 2701 | return inst_base; |
| 2919 | } | 2702 | } |
| 2920 | ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index) | 2703 | ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index) |
| 2921 | { | 2704 | { |
| 2922 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2705 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2923 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2706 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2924 | 2707 | ||
| 2925 | inst_base->cond = BITS(inst, 28, 31); | 2708 | inst_base->cond = BITS(inst, 28, 31); |
| 2926 | inst_base->idx = index; | 2709 | inst_base->idx = index; |
| 2927 | inst_base->br = NON_BRANCH; | 2710 | inst_base->br = NON_BRANCH; |
| 2928 | 2711 | ||
| 2929 | inst_cream->inst = inst; | 2712 | inst_cream->inst = inst; |
| 2930 | inst_cream->get_addr = get_calc_addr_op(inst); | 2713 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2931 | 2714 | ||
| 2932 | if (BITS(inst, 12, 15) == 15) { | 2715 | if (BITS(inst, 12, 15) == 15) { |
| 2933 | inst_base->br = INDIRECT_BRANCH; | 2716 | inst_base->br = INDIRECT_BRANCH; |
| 2934 | } | 2717 | } |
| 2935 | return inst_base; | 2718 | return inst_base; |
| 2936 | } | 2719 | } |
| 2937 | ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index) | 2720 | ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index) |
| 2938 | { | 2721 | { |
| 2939 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2722 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2940 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2723 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2941 | 2724 | ||
| 2942 | inst_base->cond = BITS(inst, 28, 31); | 2725 | inst_base->cond = BITS(inst, 28, 31); |
| 2943 | inst_base->idx = index; | 2726 | inst_base->idx = index; |
| 2944 | inst_base->br = NON_BRANCH; | 2727 | inst_base->br = NON_BRANCH; |
| 2945 | 2728 | ||
| 2946 | inst_cream->inst = inst; | 2729 | inst_cream->inst = inst; |
| 2947 | inst_cream->get_addr = get_calc_addr_op(inst); | 2730 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2948 | 2731 | ||
| 2949 | if (BITS(inst, 12, 15) == 15) { | 2732 | if (BITS(inst, 12, 15) == 15) { |
| 2950 | inst_base->br = INDIRECT_BRANCH; | 2733 | inst_base->br = INDIRECT_BRANCH; |
| 2951 | } | 2734 | } |
| 2952 | return inst_base; | 2735 | return inst_base; |
| 2953 | } | 2736 | } |
| 2954 | ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index) | 2737 | ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index) |
| 2955 | { | 2738 | { |
| 2956 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2739 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2957 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2740 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2958 | 2741 | ||
| 2959 | inst_base->cond = BITS(inst, 28, 31); | 2742 | inst_base->cond = BITS(inst, 28, 31); |
| 2960 | inst_base->idx = index; | 2743 | inst_base->idx = index; |
| 2961 | inst_base->br = NON_BRANCH; | 2744 | inst_base->br = NON_BRANCH; |
| 2962 | 2745 | ||
| 2963 | inst_cream->inst = inst; | 2746 | inst_cream->inst = inst; |
| 2964 | if (I_BIT == 0) { | 2747 | if (I_BIT == 0) { |
| 2965 | inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); | 2748 | inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); |
| 2966 | } else { | 2749 | } else { |
| 2967 | DEBUG_MSG; | 2750 | DEBUG_MSG; |
| 2968 | } | 2751 | } |
| 2969 | 2752 | ||
| 2970 | if (BITS(inst, 12, 15) == 15) { | 2753 | if (BITS(inst, 12, 15) == 15) { |
| 2971 | inst_base->br = INDIRECT_BRANCH; | 2754 | inst_base->br = INDIRECT_BRANCH; |
| 2972 | } | 2755 | } |
| 2973 | return inst_base; | 2756 | return inst_base; |
| 2974 | } | 2757 | } |
| 2975 | ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index) | 2758 | ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index) |
| 2976 | { | 2759 | { |
| 2977 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst)); | 2760 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst)); |
| 2978 | sub_inst *inst_cream = (sub_inst *)inst_base->component; | 2761 | sub_inst *inst_cream = (sub_inst *)inst_base->component; |
| 2979 | 2762 | ||
| 2980 | inst_base->cond = BITS(inst, 28, 31); | 2763 | inst_base->cond = BITS(inst, 28, 31); |
| 2981 | inst_base->idx = index; | 2764 | inst_base->idx = index; |
| 2982 | inst_base->br = NON_BRANCH; | 2765 | inst_base->br = NON_BRANCH; |
| 2983 | inst_base->load_r15 = 0; | 2766 | inst_base->load_r15 = 0; |
| 2984 | 2767 | ||
| 2985 | inst_cream->I = BIT(inst, 25); | 2768 | inst_cream->I = BIT(inst, 25); |
| 2986 | inst_cream->S = BIT(inst, 20); | 2769 | inst_cream->S = BIT(inst, 20); |
| 2987 | inst_cream->Rn = BITS(inst, 16, 19); | 2770 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2988 | inst_cream->Rd = BITS(inst, 12, 15); | 2771 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2989 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2772 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 2990 | inst_cream->shtop_func = get_shtop(inst); | 2773 | inst_cream->shtop_func = get_shtop(inst); |
| 2991 | if (inst_cream->Rd == 15) { | 2774 | if (inst_cream->Rd == 15) { |
| 2992 | inst_base->br = INDIRECT_BRANCH; | 2775 | inst_base->br = INDIRECT_BRANCH; |
| 2993 | } | 2776 | } |
| 2994 | if (CHECK_RN) | 2777 | if (CHECK_RN) |
| 2995 | inst_base->load_r15 = 1; | 2778 | inst_base->load_r15 = 1; |
| 2996 | 2779 | ||
| 2997 | return inst_base; | 2780 | return inst_base; |
| 2998 | } | 2781 | } |
| 2999 | ARM_INST_PTR INTERPRETER_TRANSLATE(swi)(unsigned int inst, int index) | 2782 | ARM_INST_PTR INTERPRETER_TRANSLATE(swi)(unsigned int inst, int index) |
| 3000 | { | 2783 | { |
| 3001 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst)); | 2784 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst)); |
| 3002 | swi_inst *inst_cream = (swi_inst *)inst_base->component; | 2785 | swi_inst *inst_cream = (swi_inst *)inst_base->component; |
| 3003 | 2786 | ||
| 3004 | inst_base->cond = BITS(inst, 28, 31); | 2787 | inst_base->cond = BITS(inst, 28, 31); |
| 3005 | inst_base->idx = index; | 2788 | inst_base->idx = index; |
| 3006 | inst_base->br = NON_BRANCH; | 2789 | inst_base->br = NON_BRANCH; |
| 3007 | 2790 | ||
| 3008 | inst_cream->num = BITS(inst, 0, 23); | 2791 | inst_cream->num = BITS(inst, 0, 23); |
| 3009 | return inst_base; | 2792 | return inst_base; |
| 3010 | } | 2793 | } |
| 3011 | ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index) | 2794 | ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index) |
| 3012 | { | 2795 | { |
| 3013 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); | 2796 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); |
| 3014 | swp_inst *inst_cream = (swp_inst *)inst_base->component; | 2797 | swp_inst *inst_cream = (swp_inst *)inst_base->component; |
| 3015 | 2798 | ||
| 3016 | inst_base->cond = BITS(inst, 28, 31); | 2799 | inst_base->cond = BITS(inst, 28, 31); |
| 3017 | inst_base->idx = index; | 2800 | inst_base->idx = index; |
| 3018 | inst_base->br = NON_BRANCH; | 2801 | inst_base->br = NON_BRANCH; |
| 3019 | 2802 | ||
| 3020 | inst_cream->Rn = BITS(inst, 16, 19); | 2803 | inst_cream->Rn = BITS(inst, 16, 19); |
| 3021 | inst_cream->Rd = BITS(inst, 12, 15); | 2804 | inst_cream->Rd = BITS(inst, 12, 15); |
| 3022 | inst_cream->Rm = BITS(inst, 0, 3); | 2805 | inst_cream->Rm = BITS(inst, 0, 3); |
| 3023 | 2806 | ||
| 3024 | if (inst_cream->Rd == 15) { | 2807 | if (inst_cream->Rd == 15) { |
| 3025 | inst_base->br = INDIRECT_BRANCH; | 2808 | inst_base->br = INDIRECT_BRANCH; |
| 3026 | } | 2809 | } |
| 3027 | return inst_base; | 2810 | return inst_base; |
| 3028 | } | 2811 | } |
| 3029 | ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){ | 2812 | ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){ |
| 3030 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); | 2813 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); |
| 3031 | swp_inst *inst_cream = (swp_inst *)inst_base->component; | 2814 | swp_inst *inst_cream = (swp_inst *)inst_base->component; |
| 3032 | 2815 | ||
| 3033 | inst_base->cond = BITS(inst, 28, 31); | 2816 | inst_base->cond = BITS(inst, 28, 31); |
| 3034 | inst_base->idx = index; | 2817 | inst_base->idx = index; |
| 3035 | inst_base->br = NON_BRANCH; | 2818 | inst_base->br = NON_BRANCH; |
| 3036 | 2819 | ||
| 3037 | inst_cream->Rn = BITS(inst, 16, 19); | 2820 | inst_cream->Rn = BITS(inst, 16, 19); |
| 3038 | inst_cream->Rd = BITS(inst, 12, 15); | 2821 | inst_cream->Rd = BITS(inst, 12, 15); |
| 3039 | inst_cream->Rm = BITS(inst, 0, 3); | 2822 | inst_cream->Rm = BITS(inst, 0, 3); |
| 3040 | 2823 | ||
| 3041 | if (inst_cream->Rd == 15) { | 2824 | if (inst_cream->Rd == 15) { |
| 3042 | inst_base->br = INDIRECT_BRANCH; | 2825 | inst_base->br = INDIRECT_BRANCH; |
| 3043 | } | 2826 | } |
| 3044 | return inst_base; | 2827 | return inst_base; |
| 3045 | } | 2828 | } |
| 3046 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){ | 2829 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){ |
| 3047 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst)); | 2830 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst)); |
| 3048 | sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component; | 2831 | sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component; |
| 3049 | 2832 | ||
| 3050 | inst_base->cond = BITS(inst, 28, 31); | 2833 | inst_base->cond = BITS(inst, 28, 31); |
| 3051 | inst_base->idx = index; | 2834 | inst_base->idx = index; |
| 3052 | inst_base->br = NON_BRANCH; | 2835 | inst_base->br = NON_BRANCH; |
| 3053 | inst_base->load_r15 = 0; | 2836 | inst_base->load_r15 = 0; |
| 3054 | 2837 | ||
| 3055 | inst_cream->Rd = BITS(inst, 12, 15); | 2838 | inst_cream->Rd = BITS(inst, 12, 15); |
| 3056 | inst_cream->rotate = BITS(inst, 10, 11); | 2839 | inst_cream->rotate = BITS(inst, 10, 11); |
| 3057 | inst_cream->Rm = BITS(inst, 0, 3); | 2840 | inst_cream->Rm = BITS(inst, 0, 3); |
| 3058 | inst_cream->Rn = BITS(inst, 16, 19); | 2841 | inst_cream->Rn = BITS(inst, 16, 19); |
| 3059 | 2842 | ||
| 3060 | return inst_base; | 2843 | return inst_base; |
| 3061 | } | 2844 | } |
| 3062 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SXTAB16"); } | 2845 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SXTAB16"); } |
| 3063 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index){ | 2846 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index){ |
| 3064 | LOG_WARNING(Core_ARM11, "SXTAH untested"); | 2847 | LOG_WARNING(Core_ARM11, "SXTAH untested"); |
| 3065 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst)); | 2848 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst)); |
| 3066 | sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component; | 2849 | sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component; |
| 3067 | 2850 | ||
| 3068 | inst_base->cond = BITS(inst, 28, 31); | 2851 | inst_base->cond = BITS(inst, 28, 31); |
| 3069 | inst_base->idx = index; | 2852 | inst_base->idx = index; |
| 3070 | inst_base->br = NON_BRANCH; | 2853 | inst_base->br = NON_BRANCH; |
| 3071 | inst_base->load_r15 = 0; | 2854 | inst_base->load_r15 = 0; |
| 3072 | 2855 | ||
| 3073 | inst_cream->Rd = BITS(inst, 12, 15); | 2856 | inst_cream->Rd = BITS(inst, 12, 15); |
| 3074 | inst_cream->rotate = BITS(inst, 10, 11); | 2857 | inst_cream->rotate = BITS(inst, 10, 11); |
| 3075 | inst_cream->Rm = BITS(inst, 0, 3); | 2858 | inst_cream->Rm = BITS(inst, 0, 3); |
| 3076 | inst_cream->Rn = BITS(inst, 16, 19); | 2859 | inst_cream->Rn = BITS(inst, 16, 19); |
| 3077 | 2860 | ||
| 3078 | return inst_base; | 2861 | return inst_base; |
| 3079 | } | 2862 | } |
| 3080 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SXTB16"); } | 2863 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SXTB16"); } |
| 3081 | ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index) | 2864 | ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index) |
| 3082 | { | 2865 | { |
| 3083 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst)); | 2866 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst)); |
| 3084 | teq_inst *inst_cream = (teq_inst *)inst_base->component; | 2867 | teq_inst *inst_cream = (teq_inst *)inst_base->component; |
| 3085 | 2868 | ||
| 3086 | inst_base->cond = BITS(inst, 28, 31); | 2869 | inst_base->cond = BITS(inst, 28, 31); |
| 3087 | inst_base->idx = index; | 2870 | inst_base->idx = index; |
| 3088 | inst_base->br = NON_BRANCH; | 2871 | inst_base->br = NON_BRANCH; |
| 3089 | inst_base->load_r15 = 0; | 2872 | inst_base->load_r15 = 0; |
| 3090 | 2873 | ||
| 3091 | inst_cream->I = BIT(inst, 25); | 2874 | inst_cream->I = BIT(inst, 25); |
| 3092 | inst_cream->Rn = BITS(inst, 16, 19); | 2875 | inst_cream->Rn = BITS(inst, 16, 19); |
| 3093 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2876 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 3094 | inst_cream->shtop_func = get_shtop(inst); | 2877 | inst_cream->shtop_func = get_shtop(inst); |
| 3095 | 2878 | ||
| 3096 | if (CHECK_RN) | 2879 | if (CHECK_RN) |
| 3097 | inst_base->load_r15 = 1; | 2880 | inst_base->load_r15 = 1; |
| 3098 | return inst_base; | 2881 | return inst_base; |
| 3099 | } | 2882 | } |
| 3100 | ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index) | 2883 | ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index) |
| 3101 | { | 2884 | { |
| 3102 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst)); | 2885 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst)); |
| 3103 | tst_inst *inst_cream = (tst_inst *)inst_base->component; | 2886 | tst_inst *inst_cream = (tst_inst *)inst_base->component; |
| 3104 | 2887 | ||
| 3105 | inst_base->cond = BITS(inst, 28, 31); | 2888 | inst_base->cond = BITS(inst, 28, 31); |
| 3106 | inst_base->idx = index; | 2889 | inst_base->idx = index; |
| 3107 | inst_base->br = NON_BRANCH; | 2890 | inst_base->br = NON_BRANCH; |
| 3108 | inst_base->load_r15 = 0; | 2891 | inst_base->load_r15 = 0; |
| 3109 | 2892 | ||
| 3110 | inst_cream->I = BIT(inst, 25); | 2893 | inst_cream->I = BIT(inst, 25); |
| 3111 | inst_cream->S = BIT(inst, 20); | 2894 | inst_cream->S = BIT(inst, 20); |
| 3112 | inst_cream->Rn = BITS(inst, 16, 19); | 2895 | inst_cream->Rn = BITS(inst, 16, 19); |
| 3113 | inst_cream->Rd = BITS(inst, 12, 15); | 2896 | inst_cream->Rd = BITS(inst, 12, 15); |
| 3114 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2897 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 3115 | inst_cream->shtop_func = get_shtop(inst); | 2898 | inst_cream->shtop_func = get_shtop(inst); |
| 3116 | if (inst_cream->Rd == 15) { | 2899 | if (inst_cream->Rd == 15) { |
| 3117 | inst_base->br = INDIRECT_BRANCH; | 2900 | inst_base->br = INDIRECT_BRANCH; |
| 3118 | } | 2901 | } |
| 3119 | 2902 | ||
| 3120 | if (CHECK_RN) | 2903 | if (CHECK_RN) |
| 3121 | inst_base->load_r15 = 1; | 2904 | inst_base->load_r15 = 1; |
| 3122 | return inst_base; | 2905 | return inst_base; |
| 3123 | } | 2906 | } |
| 3124 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD8"); } | 2907 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD8"); } |
| 3125 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); } | 2908 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); } |
| 3126 | ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADDSUBX"); } | 2909 | ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADDSUBX"); } |
| 3127 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) | 2910 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) |
| 3128 | { | 2911 | { |
| 3129 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); | 2912 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| 3130 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | 2913 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 3131 | 2914 | ||
| 3132 | inst_base->cond = BITS(inst, 28, 31); | 2915 | inst_base->cond = BITS(inst, 28, 31); |
| 3133 | inst_base->idx = index; | 2916 | inst_base->idx = index; |
| 3134 | inst_base->br = NON_BRANCH; | 2917 | inst_base->br = NON_BRANCH; |
| 3135 | inst_base->load_r15 = 0; | 2918 | inst_base->load_r15 = 0; |
| 3136 | 2919 | ||
| 3137 | inst_cream->op1 = BITS(inst, 20, 21); | 2920 | inst_cream->op1 = BITS(inst, 20, 21); |
| 3138 | inst_cream->op2 = BITS(inst, 5, 7); | 2921 | inst_cream->op2 = BITS(inst, 5, 7); |
| 3139 | inst_cream->Rm = BITS(inst, 0, 3); | 2922 | inst_cream->Rm = BITS(inst, 0, 3); |
| 3140 | inst_cream->Rn = BITS(inst, 16, 19); | 2923 | inst_cream->Rn = BITS(inst, 16, 19); |
| 3141 | inst_cream->Rd = BITS(inst, 12, 15); | 2924 | inst_cream->Rd = BITS(inst, 12, 15); |
| 3142 | 2925 | ||
| 3143 | return inst_base; | 2926 | return inst_base; |
| 3144 | } | 2927 | } |
| 3145 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index) | 2928 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index) |
| 3146 | { | 2929 | { |
| 3147 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); | 2930 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); |
| 3148 | } | 2931 | } |
| 3149 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index) | 2932 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index) |
| 3150 | { | 2933 | { |
| 3151 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); | 2934 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); |
| 3152 | } | 2935 | } |
| 3153 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index) | 2936 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index) |
| 3154 | { | 2937 | { |
| 3155 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); | 2938 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); |
| 3156 | } | 2939 | } |
| 3157 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index) | 2940 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index) |
| 3158 | { | 2941 | { |
| 3159 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); | 2942 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); |
| 3160 | } | 2943 | } |
| 3161 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index) | 2944 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index) |
| 3162 | { | 2945 | { |
| 3163 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); | 2946 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); |
| 3164 | } | 2947 | } |
| 3165 | ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index) | 2948 | ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index) |
| 3166 | { | 2949 | { |
| 3167 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umaal_inst)); | 2950 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umaal_inst)); |
| 3168 | umaal_inst* const inst_cream = (umaal_inst*)inst_base->component; | 2951 | umaal_inst* const inst_cream = (umaal_inst*)inst_base->component; |
| 3169 | 2952 | ||
| 3170 | inst_base->cond = BITS(inst, 28, 31); | 2953 | inst_base->cond = BITS(inst, 28, 31); |
| 3171 | inst_base->idx = index; | 2954 | inst_base->idx = index; |
| 3172 | inst_base->br = NON_BRANCH; | 2955 | inst_base->br = NON_BRANCH; |
| 3173 | inst_base->load_r15 = 0; | 2956 | inst_base->load_r15 = 0; |
| 3174 | 2957 | ||
| 3175 | inst_cream->Rm = BITS(inst, 8, 11); | 2958 | inst_cream->Rm = BITS(inst, 8, 11); |
| 3176 | inst_cream->Rn = BITS(inst, 0, 3); | 2959 | inst_cream->Rn = BITS(inst, 0, 3); |
| 3177 | inst_cream->RdLo = BITS(inst, 12, 15); | 2960 | inst_cream->RdLo = BITS(inst, 12, 15); |
| 3178 | inst_cream->RdHi = BITS(inst, 16, 19); | 2961 | inst_cream->RdHi = BITS(inst, 16, 19); |
| 3179 | 2962 | ||
| 3180 | if (CHECK_RM || CHECK_RN) | 2963 | if (CHECK_RM || CHECK_RN) |
| 3181 | inst_base->load_r15 = 1; | 2964 | inst_base->load_r15 = 1; |
| 3182 | 2965 | ||
| 3183 | return inst_base; | 2966 | return inst_base; |
| 3184 | } | 2967 | } |
| 3185 | ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index) | 2968 | ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index) |
| 3186 | { | 2969 | { |
| 3187 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); | 2970 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); |
| 3188 | umlal_inst *inst_cream = (umlal_inst *)inst_base->component; | 2971 | umlal_inst *inst_cream = (umlal_inst *)inst_base->component; |
| 3189 | 2972 | ||
| 3190 | inst_base->cond = BITS(inst, 28, 31); | 2973 | inst_base->cond = BITS(inst, 28, 31); |
| 3191 | inst_base->idx = index; | 2974 | inst_base->idx = index; |
| 3192 | inst_base->br = NON_BRANCH; | 2975 | inst_base->br = NON_BRANCH; |
| 3193 | inst_base->load_r15 = 0; | 2976 | inst_base->load_r15 = 0; |
| 3194 | 2977 | ||
| 3195 | inst_cream->S = BIT(inst, 20); | 2978 | inst_cream->S = BIT(inst, 20); |
| 3196 | inst_cream->Rm = BITS(inst, 0, 3); | 2979 | inst_cream->Rm = BITS(inst, 0, 3); |
| 3197 | inst_cream->Rs = BITS(inst, 8, 11); | 2980 | inst_cream->Rs = BITS(inst, 8, 11); |
| 3198 | inst_cream->RdHi = BITS(inst, 16, 19); | 2981 | inst_cream->RdHi = BITS(inst, 16, 19); |
| 3199 | inst_cream->RdLo = BITS(inst, 12, 15); | 2982 | inst_cream->RdLo = BITS(inst, 12, 15); |
| 3200 | 2983 | ||
| 3201 | if (CHECK_RM || CHECK_RS) | 2984 | if (CHECK_RM || CHECK_RS) |
| 3202 | inst_base->load_r15 = 1; | 2985 | inst_base->load_r15 = 1; |
| 3203 | return inst_base; | 2986 | |
| 2987 | return inst_base; | ||
| 3204 | } | 2988 | } |
| 3205 | ARM_INST_PTR INTERPRETER_TRANSLATE(umull)(unsigned int inst, int index) | 2989 | ARM_INST_PTR INTERPRETER_TRANSLATE(umull)(unsigned int inst, int index) |
| 3206 | { | 2990 | { |
| 3207 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); | 2991 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); |
| 3208 | umull_inst *inst_cream = (umull_inst *)inst_base->component; | 2992 | umull_inst *inst_cream = (umull_inst *)inst_base->component; |
| 3209 | 2993 | ||
| 3210 | inst_base->cond = BITS(inst, 28, 31); | 2994 | inst_base->cond = BITS(inst, 28, 31); |
| 3211 | inst_base->idx = index; | 2995 | inst_base->idx = index; |
| 3212 | inst_base->br = NON_BRANCH; | 2996 | inst_base->br = NON_BRANCH; |
| 3213 | inst_base->load_r15 = 0; | 2997 | inst_base->load_r15 = 0; |
| 3214 | 2998 | ||
| 3215 | inst_cream->S = BIT(inst, 20); | 2999 | inst_cream->S = BIT(inst, 20); |
| 3216 | inst_cream->Rm = BITS(inst, 0, 3); | 3000 | inst_cream->Rm = BITS(inst, 0, 3); |
| 3217 | inst_cream->Rs = BITS(inst, 8, 11); | 3001 | inst_cream->Rs = BITS(inst, 8, 11); |
| 3218 | inst_cream->RdHi = BITS(inst, 16, 19); | 3002 | inst_cream->RdHi = BITS(inst, 16, 19); |
| 3219 | inst_cream->RdLo = BITS(inst, 12, 15); | 3003 | inst_cream->RdLo = BITS(inst, 12, 15); |
| 3220 | 3004 | ||
| 3221 | if (CHECK_RM || CHECK_RS) | 3005 | if (CHECK_RM || CHECK_RS) |
| 3222 | inst_base->load_r15 = 1; | 3006 | inst_base->load_r15 = 1; |
| 3223 | return inst_base; | 3007 | return inst_base; |
| 3224 | } | 3008 | } |
| 3225 | 3009 | ||
| 3226 | ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index) | 3010 | ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index) |
| 3227 | { | 3011 | { |
| 3228 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb)); | 3012 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb)); |
| 3229 | b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component; | 3013 | b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component; |
| 3014 | |||
| 3015 | inst_cream->imm = ((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0); | ||
| 3230 | 3016 | ||
| 3231 | inst_cream->imm =((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0); | 3017 | inst_base->idx = index; |
| 3232 | //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm); | 3018 | inst_base->br = DIRECT_BRANCH; |
| 3233 | inst_base->idx = index; | 3019 | |
| 3234 | inst_base->br = DIRECT_BRANCH; | 3020 | return inst_base; |
| 3235 | return inst_base; | ||
| 3236 | } | 3021 | } |
| 3237 | 3022 | ||
| 3238 | ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index) | 3023 | ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index) |
| 3239 | { | 3024 | { |
| 3240 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb)); | 3025 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb)); |
| 3241 | b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component; | 3026 | b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component; |
| 3027 | |||
| 3028 | inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0)); | ||
| 3029 | inst_cream->cond = ((tinst >> 8) & 0xf); | ||
| 3030 | inst_base->idx = index; | ||
| 3031 | inst_base->br = DIRECT_BRANCH; | ||
| 3242 | 3032 | ||
| 3243 | inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0)); | 3033 | return inst_base; |
| 3244 | inst_cream->cond = ((tinst >> 8) & 0xf); | ||
| 3245 | //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x, cond=0x%x\n", __FUNCTION__, tinst, inst_cream->imm, inst_cream->cond); | ||
| 3246 | inst_base->idx = index; | ||
| 3247 | inst_base->br = DIRECT_BRANCH; | ||
| 3248 | return inst_base; | ||
| 3249 | } | 3034 | } |
| 3250 | 3035 | ||
| 3251 | ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index) | 3036 | ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index) |
| 3252 | { | 3037 | { |
| 3253 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb)); | 3038 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb)); |
| 3254 | bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component; | 3039 | bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component; |
| 3255 | 3040 | ||
| 3256 | inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0)); | 3041 | inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0)); |
| 3257 | //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm); | ||
| 3258 | 3042 | ||
| 3259 | inst_base->idx = index; | 3043 | inst_base->idx = index; |
| 3260 | inst_base->br = NON_BRANCH; | 3044 | inst_base->br = NON_BRANCH; |
| 3261 | return inst_base; | 3045 | return inst_base; |
| 3262 | } | 3046 | } |
| 3263 | ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index) | 3047 | ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index) |
| 3264 | { | 3048 | { |
| 3265 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb)); | 3049 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb)); |
| 3266 | bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component; | 3050 | bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component; |
| 3051 | |||
| 3052 | inst_cream->imm = (tinst & 0x07FF) << 1; | ||
| 3267 | 3053 | ||
| 3268 | inst_cream->imm = (tinst & 0x07FF) << 1; | 3054 | inst_base->idx = index; |
| 3269 | //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm); | 3055 | inst_base->br = DIRECT_BRANCH; |
| 3270 | inst_base->idx = index; | 3056 | return inst_base; |
| 3271 | inst_base->br = DIRECT_BRANCH; | ||
| 3272 | return inst_base; | ||
| 3273 | } | 3057 | } |
| 3274 | ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index) | 3058 | ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index) |
| 3275 | { | 3059 | { |
| 3276 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb)); | 3060 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb)); |
| 3277 | blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component; | 3061 | blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component; |
| 3278 | 3062 | ||
| 3279 | inst_cream->imm = (tinst & 0x07FF) << 1; | 3063 | inst_cream->imm = (tinst & 0x07FF) << 1; |
| 3280 | //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm); | 3064 | inst_cream->instr = tinst; |
| 3281 | inst_cream->instr = tinst; | 3065 | |
| 3282 | inst_base->idx = index; | 3066 | inst_base->idx = index; |
| 3283 | inst_base->br = DIRECT_BRANCH; | 3067 | inst_base->br = DIRECT_BRANCH; |
| 3284 | return inst_base; | 3068 | return inst_base; |
| 3285 | } | 3069 | } |
| 3286 | 3070 | ||
| 3287 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index) | 3071 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index) |
| 3288 | { | 3072 | { |
| 3289 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); | 3073 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| 3290 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | 3074 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 3291 | 3075 | ||
| 3292 | inst_base->cond = BITS(inst, 28, 31); | 3076 | inst_base->cond = BITS(inst, 28, 31); |
| 3293 | inst_base->idx = index; | 3077 | inst_base->idx = index; |
| 3294 | inst_base->br = NON_BRANCH; | 3078 | inst_base->br = NON_BRANCH; |
| 3295 | inst_base->load_r15 = 0; | 3079 | inst_base->load_r15 = 0; |
| 3296 | 3080 | ||
| 3297 | inst_cream->Rm = BITS(inst, 0, 3); | 3081 | inst_cream->Rm = BITS(inst, 0, 3); |
| 3298 | inst_cream->Rn = BITS(inst, 16, 19); | 3082 | inst_cream->Rn = BITS(inst, 16, 19); |
| 3299 | inst_cream->Rd = BITS(inst, 12, 15); | 3083 | inst_cream->Rd = BITS(inst, 12, 15); |
| 3300 | inst_cream->op1 = BITS(inst, 20, 21); | 3084 | inst_cream->op1 = BITS(inst, 20, 21); |
| 3301 | inst_cream->op2 = BITS(inst, 5, 7); | 3085 | inst_cream->op2 = BITS(inst, 5, 7); |
| 3302 | 3086 | ||
| 3303 | return inst_base; | 3087 | return inst_base; |
| 3304 | } | 3088 | } |
| 3305 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index) | 3089 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index) |
| 3306 | { | 3090 | { |
| 3307 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); | 3091 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); |
| 3308 | } | 3092 | } |
| 3309 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index) | 3093 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index) |
| 3310 | { | 3094 | { |
| 3311 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); | 3095 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); |
| 3312 | } | 3096 | } |
| 3313 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index) | 3097 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index) |
| 3314 | { | 3098 | { |
| 3315 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); | 3099 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); |
| 3316 | } | 3100 | } |
| 3317 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index) | 3101 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index) |
| 3318 | { | 3102 | { |
| 3319 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); | 3103 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); |
| 3320 | } | 3104 | } |
| 3321 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index) | 3105 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index) |
| 3322 | { | 3106 | { |
| 3323 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); | 3107 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); |
| 3324 | } | 3108 | } |
| 3325 | ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index) | 3109 | ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index) |
| 3326 | { | 3110 | { |
| 3327 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); | 3111 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| 3328 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | 3112 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 3329 | 3113 | ||
| 3330 | inst_base->cond = BITS(inst, 28, 31); | 3114 | inst_base->cond = BITS(inst, 28, 31); |
| 3331 | inst_base->idx = index; | 3115 | inst_base->idx = index; |
| 3332 | inst_base->br = NON_BRANCH; | 3116 | inst_base->br = NON_BRANCH; |
| 3333 | inst_base->load_r15 = 0; | 3117 | inst_base->load_r15 = 0; |
| 3334 | 3118 | ||
| 3335 | inst_cream->op1 = BITS(inst, 20, 24); | 3119 | inst_cream->op1 = BITS(inst, 20, 24); |
| 3336 | inst_cream->op2 = BITS(inst, 5, 7); | 3120 | inst_cream->op2 = BITS(inst, 5, 7); |
| 3337 | inst_cream->Rm = BITS(inst, 8, 11); | 3121 | inst_cream->Rm = BITS(inst, 8, 11); |
| 3338 | inst_cream->Rn = BITS(inst, 0, 3); | 3122 | inst_cream->Rn = BITS(inst, 0, 3); |
| 3339 | inst_cream->Ra = BITS(inst, 12, 15); | 3123 | inst_cream->Ra = BITS(inst, 12, 15); |
| 3340 | 3124 | ||
| 3341 | return inst_base; | 3125 | return inst_base; |
| 3342 | } | 3126 | } |
| 3343 | ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index) | 3127 | ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index) |
| 3344 | { | 3128 | { |
| 3345 | return INTERPRETER_TRANSLATE(usada8)(inst, index); | 3129 | return INTERPRETER_TRANSLATE(usada8)(inst, index); |
| 3346 | } | 3130 | } |
| 3347 | ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT"); } | 3131 | ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT"); } |
| 3348 | ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT16"); } | 3132 | 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 | |||
| 3352 | 3136 | ||
| 3353 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index) | 3137 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index) |
| 3354 | { | 3138 | { |
| 3355 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst)); | 3139 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst)); |
| 3356 | uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component; | 3140 | uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component; |
| 3357 | 3141 | ||
| 3358 | inst_base->cond = BITS(inst, 28, 31); | 3142 | inst_base->cond = BITS(inst, 28, 31); |
| 3359 | inst_base->idx = index; | 3143 | inst_base->idx = index; |
| 3360 | inst_base->br = NON_BRANCH; | 3144 | inst_base->br = NON_BRANCH; |
| 3361 | inst_base->load_r15 = 0; | 3145 | inst_base->load_r15 = 0; |
| 3362 | 3146 | ||
| 3363 | inst_cream->Rm = BITS(inst, 0, 3); | 3147 | inst_cream->Rm = BITS(inst, 0, 3); |
| 3364 | inst_cream->Rn = BITS(inst, 16, 19); | 3148 | inst_cream->Rn = BITS(inst, 16, 19); |
| 3365 | inst_cream->Rd = BITS(inst, 12, 15); | 3149 | inst_cream->Rd = BITS(inst, 12, 15); |
| 3366 | inst_cream->rotate = BITS(inst, 10, 11); | 3150 | inst_cream->rotate = BITS(inst, 10, 11); |
| 3367 | 3151 | ||
| 3368 | return inst_base; | 3152 | return inst_base; |
| 3369 | } | 3153 | } |
| 3370 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index) | 3154 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index) |
| 3371 | { | 3155 | { |
| 3372 | return INTERPRETER_TRANSLATE(uxtab16)(inst, index); | 3156 | return INTERPRETER_TRANSLATE(uxtab16)(inst, index); |
| 3373 | } | 3157 | } |
| 3374 | 3158 | ||
| 3375 | /* Floating point VFPv3 structures and instructions */ | 3159 | // Floating point VFPv3 structures and instructions |
| 3376 | 3160 | ||
| 3377 | #define VFP_INTERPRETER_STRUCT | 3161 | #define VFP_INTERPRETER_STRUCT |
| 3378 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | 3162 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" |
| @@ -3382,352 +3166,288 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index) | |||
| 3382 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | 3166 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" |
| 3383 | #undef VFP_INTERPRETER_TRANS | 3167 | #undef VFP_INTERPRETER_TRANS |
| 3384 | 3168 | ||
| 3385 | |||
| 3386 | |||
| 3387 | typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int); | 3169 | typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int); |
| 3388 | 3170 | ||
| 3389 | const transop_fp_t arm_instruction_trans[] = { | 3171 | const transop_fp_t arm_instruction_trans[] = { |
| 3390 | INTERPRETER_TRANSLATE(vmla), | 3172 | INTERPRETER_TRANSLATE(vmla), |
| 3391 | INTERPRETER_TRANSLATE(vmls), | 3173 | INTERPRETER_TRANSLATE(vmls), |
| 3392 | INTERPRETER_TRANSLATE(vnmla), | 3174 | INTERPRETER_TRANSLATE(vnmla), |
| 3393 | INTERPRETER_TRANSLATE(vnmla), | 3175 | INTERPRETER_TRANSLATE(vnmla), |
| 3394 | INTERPRETER_TRANSLATE(vnmls), | 3176 | INTERPRETER_TRANSLATE(vnmls), |
| 3395 | INTERPRETER_TRANSLATE(vnmul), | 3177 | INTERPRETER_TRANSLATE(vnmul), |
| 3396 | INTERPRETER_TRANSLATE(vmul), | 3178 | INTERPRETER_TRANSLATE(vmul), |
| 3397 | INTERPRETER_TRANSLATE(vadd), | 3179 | INTERPRETER_TRANSLATE(vadd), |
| 3398 | INTERPRETER_TRANSLATE(vsub), | 3180 | INTERPRETER_TRANSLATE(vsub), |
| 3399 | INTERPRETER_TRANSLATE(vdiv), | 3181 | INTERPRETER_TRANSLATE(vdiv), |
| 3400 | INTERPRETER_TRANSLATE(vmovi), | 3182 | INTERPRETER_TRANSLATE(vmovi), |
| 3401 | INTERPRETER_TRANSLATE(vmovr), | 3183 | INTERPRETER_TRANSLATE(vmovr), |
| 3402 | INTERPRETER_TRANSLATE(vabs), | 3184 | INTERPRETER_TRANSLATE(vabs), |
| 3403 | INTERPRETER_TRANSLATE(vneg), | 3185 | INTERPRETER_TRANSLATE(vneg), |
| 3404 | INTERPRETER_TRANSLATE(vsqrt), | 3186 | INTERPRETER_TRANSLATE(vsqrt), |
| 3405 | INTERPRETER_TRANSLATE(vcmp), | 3187 | INTERPRETER_TRANSLATE(vcmp), |
| 3406 | INTERPRETER_TRANSLATE(vcmp2), | 3188 | INTERPRETER_TRANSLATE(vcmp2), |
| 3407 | INTERPRETER_TRANSLATE(vcvtbds), | 3189 | INTERPRETER_TRANSLATE(vcvtbds), |
| 3408 | INTERPRETER_TRANSLATE(vcvtbff), | 3190 | INTERPRETER_TRANSLATE(vcvtbff), |
| 3409 | INTERPRETER_TRANSLATE(vcvtbfi), | 3191 | INTERPRETER_TRANSLATE(vcvtbfi), |
| 3410 | INTERPRETER_TRANSLATE(vmovbrs), | 3192 | INTERPRETER_TRANSLATE(vmovbrs), |
| 3411 | INTERPRETER_TRANSLATE(vmsr), | 3193 | INTERPRETER_TRANSLATE(vmsr), |
| 3412 | INTERPRETER_TRANSLATE(vmovbrc), | 3194 | INTERPRETER_TRANSLATE(vmovbrc), |
| 3413 | INTERPRETER_TRANSLATE(vmrs), | 3195 | INTERPRETER_TRANSLATE(vmrs), |
| 3414 | INTERPRETER_TRANSLATE(vmovbcr), | 3196 | INTERPRETER_TRANSLATE(vmovbcr), |
| 3415 | INTERPRETER_TRANSLATE(vmovbrrss), | 3197 | INTERPRETER_TRANSLATE(vmovbrrss), |
| 3416 | INTERPRETER_TRANSLATE(vmovbrrd), | 3198 | INTERPRETER_TRANSLATE(vmovbrrd), |
| 3417 | INTERPRETER_TRANSLATE(vstr), | 3199 | INTERPRETER_TRANSLATE(vstr), |
| 3418 | INTERPRETER_TRANSLATE(vpush), | 3200 | INTERPRETER_TRANSLATE(vpush), |
| 3419 | INTERPRETER_TRANSLATE(vstm), | 3201 | INTERPRETER_TRANSLATE(vstm), |
| 3420 | INTERPRETER_TRANSLATE(vpop), | 3202 | INTERPRETER_TRANSLATE(vpop), |
| 3421 | INTERPRETER_TRANSLATE(vldr), | 3203 | INTERPRETER_TRANSLATE(vldr), |
| 3422 | INTERPRETER_TRANSLATE(vldm), | 3204 | INTERPRETER_TRANSLATE(vldm), |
| 3423 | 3205 | ||
| 3424 | INTERPRETER_TRANSLATE(srs), | 3206 | INTERPRETER_TRANSLATE(srs), |
| 3425 | INTERPRETER_TRANSLATE(rfe), | 3207 | INTERPRETER_TRANSLATE(rfe), |
| 3426 | INTERPRETER_TRANSLATE(bkpt), | 3208 | INTERPRETER_TRANSLATE(bkpt), |
| 3427 | INTERPRETER_TRANSLATE(blx), | 3209 | INTERPRETER_TRANSLATE(blx), |
| 3428 | INTERPRETER_TRANSLATE(cps), | 3210 | INTERPRETER_TRANSLATE(cps), |
| 3429 | INTERPRETER_TRANSLATE(pld), | 3211 | INTERPRETER_TRANSLATE(pld), |
| 3430 | INTERPRETER_TRANSLATE(setend), | 3212 | INTERPRETER_TRANSLATE(setend), |
| 3431 | INTERPRETER_TRANSLATE(clrex), | 3213 | INTERPRETER_TRANSLATE(clrex), |
| 3432 | INTERPRETER_TRANSLATE(rev16), | 3214 | INTERPRETER_TRANSLATE(rev16), |
| 3433 | INTERPRETER_TRANSLATE(usad8), | 3215 | INTERPRETER_TRANSLATE(usad8), |
| 3434 | INTERPRETER_TRANSLATE(sxtb), | 3216 | INTERPRETER_TRANSLATE(sxtb), |
| 3435 | INTERPRETER_TRANSLATE(uxtb), | 3217 | INTERPRETER_TRANSLATE(uxtb), |
| 3436 | INTERPRETER_TRANSLATE(sxth), | 3218 | INTERPRETER_TRANSLATE(sxth), |
| 3437 | INTERPRETER_TRANSLATE(sxtb16), | 3219 | INTERPRETER_TRANSLATE(sxtb16), |
| 3438 | INTERPRETER_TRANSLATE(uxth), | 3220 | INTERPRETER_TRANSLATE(uxth), |
| 3439 | INTERPRETER_TRANSLATE(uxtb16), | 3221 | INTERPRETER_TRANSLATE(uxtb16), |
| 3440 | INTERPRETER_TRANSLATE(cpy), | 3222 | INTERPRETER_TRANSLATE(cpy), |
| 3441 | INTERPRETER_TRANSLATE(uxtab), | 3223 | INTERPRETER_TRANSLATE(uxtab), |
| 3442 | INTERPRETER_TRANSLATE(ssub8), | 3224 | INTERPRETER_TRANSLATE(ssub8), |
| 3443 | INTERPRETER_TRANSLATE(shsub8), | 3225 | INTERPRETER_TRANSLATE(shsub8), |
| 3444 | INTERPRETER_TRANSLATE(ssubaddx), | 3226 | INTERPRETER_TRANSLATE(ssubaddx), |
| 3445 | INTERPRETER_TRANSLATE(strex), | 3227 | INTERPRETER_TRANSLATE(strex), |
| 3446 | INTERPRETER_TRANSLATE(strexb), | 3228 | INTERPRETER_TRANSLATE(strexb), |
| 3447 | INTERPRETER_TRANSLATE(swp), | 3229 | INTERPRETER_TRANSLATE(swp), |
| 3448 | INTERPRETER_TRANSLATE(swpb), | 3230 | INTERPRETER_TRANSLATE(swpb), |
| 3449 | INTERPRETER_TRANSLATE(ssub16), | 3231 | INTERPRETER_TRANSLATE(ssub16), |
| 3450 | INTERPRETER_TRANSLATE(ssat16), | 3232 | INTERPRETER_TRANSLATE(ssat16), |
| 3451 | INTERPRETER_TRANSLATE(shsubaddx), | 3233 | INTERPRETER_TRANSLATE(shsubaddx), |
| 3452 | INTERPRETER_TRANSLATE(qsubaddx), | 3234 | INTERPRETER_TRANSLATE(qsubaddx), |
| 3453 | INTERPRETER_TRANSLATE(shaddsubx), | 3235 | INTERPRETER_TRANSLATE(shaddsubx), |
| 3454 | INTERPRETER_TRANSLATE(shadd8), | 3236 | INTERPRETER_TRANSLATE(shadd8), |
| 3455 | INTERPRETER_TRANSLATE(shadd16), | 3237 | INTERPRETER_TRANSLATE(shadd16), |
| 3456 | INTERPRETER_TRANSLATE(sel), | 3238 | INTERPRETER_TRANSLATE(sel), |
| 3457 | INTERPRETER_TRANSLATE(saddsubx), | 3239 | INTERPRETER_TRANSLATE(saddsubx), |
| 3458 | INTERPRETER_TRANSLATE(sadd8), | 3240 | INTERPRETER_TRANSLATE(sadd8), |
| 3459 | INTERPRETER_TRANSLATE(sadd16), | 3241 | INTERPRETER_TRANSLATE(sadd16), |
| 3460 | INTERPRETER_TRANSLATE(shsub16), | 3242 | INTERPRETER_TRANSLATE(shsub16), |
| 3461 | INTERPRETER_TRANSLATE(umaal), | 3243 | INTERPRETER_TRANSLATE(umaal), |
| 3462 | INTERPRETER_TRANSLATE(uxtab16), | 3244 | INTERPRETER_TRANSLATE(uxtab16), |
| 3463 | INTERPRETER_TRANSLATE(usubaddx), | 3245 | INTERPRETER_TRANSLATE(usubaddx), |
| 3464 | INTERPRETER_TRANSLATE(usub8), | 3246 | INTERPRETER_TRANSLATE(usub8), |
| 3465 | INTERPRETER_TRANSLATE(usub16), | 3247 | INTERPRETER_TRANSLATE(usub16), |
| 3466 | INTERPRETER_TRANSLATE(usat16), | 3248 | INTERPRETER_TRANSLATE(usat16), |
| 3467 | INTERPRETER_TRANSLATE(usada8), | 3249 | INTERPRETER_TRANSLATE(usada8), |
| 3468 | INTERPRETER_TRANSLATE(uqsubaddx), | 3250 | INTERPRETER_TRANSLATE(uqsubaddx), |
| 3469 | INTERPRETER_TRANSLATE(uqsub8), | 3251 | INTERPRETER_TRANSLATE(uqsub8), |
| 3470 | INTERPRETER_TRANSLATE(uqsub16), | 3252 | INTERPRETER_TRANSLATE(uqsub16), |
| 3471 | INTERPRETER_TRANSLATE(uqaddsubx), | 3253 | INTERPRETER_TRANSLATE(uqaddsubx), |
| 3472 | INTERPRETER_TRANSLATE(uqadd8), | 3254 | INTERPRETER_TRANSLATE(uqadd8), |
| 3473 | INTERPRETER_TRANSLATE(uqadd16), | 3255 | INTERPRETER_TRANSLATE(uqadd16), |
| 3474 | INTERPRETER_TRANSLATE(sxtab), | 3256 | INTERPRETER_TRANSLATE(sxtab), |
| 3475 | INTERPRETER_TRANSLATE(uhsubaddx), | 3257 | INTERPRETER_TRANSLATE(uhsubaddx), |
| 3476 | INTERPRETER_TRANSLATE(uhsub8), | 3258 | INTERPRETER_TRANSLATE(uhsub8), |
| 3477 | INTERPRETER_TRANSLATE(uhsub16), | 3259 | INTERPRETER_TRANSLATE(uhsub16), |
| 3478 | INTERPRETER_TRANSLATE(uhaddsubx), | 3260 | INTERPRETER_TRANSLATE(uhaddsubx), |
| 3479 | INTERPRETER_TRANSLATE(uhadd8), | 3261 | INTERPRETER_TRANSLATE(uhadd8), |
| 3480 | INTERPRETER_TRANSLATE(uhadd16), | 3262 | INTERPRETER_TRANSLATE(uhadd16), |
| 3481 | INTERPRETER_TRANSLATE(uaddsubx), | 3263 | INTERPRETER_TRANSLATE(uaddsubx), |
| 3482 | INTERPRETER_TRANSLATE(uadd8), | 3264 | INTERPRETER_TRANSLATE(uadd8), |
| 3483 | INTERPRETER_TRANSLATE(uadd16), | 3265 | INTERPRETER_TRANSLATE(uadd16), |
| 3484 | INTERPRETER_TRANSLATE(sxtah), | 3266 | INTERPRETER_TRANSLATE(sxtah), |
| 3485 | INTERPRETER_TRANSLATE(sxtab16), | 3267 | INTERPRETER_TRANSLATE(sxtab16), |
| 3486 | INTERPRETER_TRANSLATE(qadd8), | 3268 | INTERPRETER_TRANSLATE(qadd8), |
| 3487 | INTERPRETER_TRANSLATE(bxj), | 3269 | INTERPRETER_TRANSLATE(bxj), |
| 3488 | INTERPRETER_TRANSLATE(clz), | 3270 | INTERPRETER_TRANSLATE(clz), |
| 3489 | INTERPRETER_TRANSLATE(uxtah), | 3271 | INTERPRETER_TRANSLATE(uxtah), |
| 3490 | INTERPRETER_TRANSLATE(bx), | 3272 | INTERPRETER_TRANSLATE(bx), |
| 3491 | INTERPRETER_TRANSLATE(rev), | 3273 | INTERPRETER_TRANSLATE(rev), |
| 3492 | INTERPRETER_TRANSLATE(blx), | 3274 | INTERPRETER_TRANSLATE(blx), |
| 3493 | INTERPRETER_TRANSLATE(revsh), | 3275 | INTERPRETER_TRANSLATE(revsh), |
| 3494 | INTERPRETER_TRANSLATE(qadd), | 3276 | INTERPRETER_TRANSLATE(qadd), |
| 3495 | INTERPRETER_TRANSLATE(qadd16), | 3277 | INTERPRETER_TRANSLATE(qadd16), |
| 3496 | INTERPRETER_TRANSLATE(qaddsubx), | 3278 | INTERPRETER_TRANSLATE(qaddsubx), |
| 3497 | INTERPRETER_TRANSLATE(ldrex), | 3279 | INTERPRETER_TRANSLATE(ldrex), |
| 3498 | INTERPRETER_TRANSLATE(qdadd), | 3280 | INTERPRETER_TRANSLATE(qdadd), |
| 3499 | INTERPRETER_TRANSLATE(qdsub), | 3281 | INTERPRETER_TRANSLATE(qdsub), |
| 3500 | INTERPRETER_TRANSLATE(qsub), | 3282 | INTERPRETER_TRANSLATE(qsub), |
| 3501 | INTERPRETER_TRANSLATE(ldrexb), | 3283 | INTERPRETER_TRANSLATE(ldrexb), |
| 3502 | INTERPRETER_TRANSLATE(qsub8), | 3284 | INTERPRETER_TRANSLATE(qsub8), |
| 3503 | INTERPRETER_TRANSLATE(qsub16), | 3285 | INTERPRETER_TRANSLATE(qsub16), |
| 3504 | INTERPRETER_TRANSLATE(smuad), | 3286 | INTERPRETER_TRANSLATE(smuad), |
| 3505 | INTERPRETER_TRANSLATE(smmul), | 3287 | INTERPRETER_TRANSLATE(smmul), |
| 3506 | INTERPRETER_TRANSLATE(smusd), | 3288 | INTERPRETER_TRANSLATE(smusd), |
| 3507 | INTERPRETER_TRANSLATE(smlsd), | 3289 | INTERPRETER_TRANSLATE(smlsd), |
| 3508 | INTERPRETER_TRANSLATE(smlsld), | 3290 | INTERPRETER_TRANSLATE(smlsld), |
| 3509 | INTERPRETER_TRANSLATE(smmla), | 3291 | INTERPRETER_TRANSLATE(smmla), |
| 3510 | INTERPRETER_TRANSLATE(smmls), | 3292 | INTERPRETER_TRANSLATE(smmls), |
| 3511 | INTERPRETER_TRANSLATE(smlald), | 3293 | INTERPRETER_TRANSLATE(smlald), |
| 3512 | INTERPRETER_TRANSLATE(smlad), | 3294 | INTERPRETER_TRANSLATE(smlad), |
| 3513 | INTERPRETER_TRANSLATE(smlaw), | 3295 | INTERPRETER_TRANSLATE(smlaw), |
| 3514 | INTERPRETER_TRANSLATE(smulw), | 3296 | INTERPRETER_TRANSLATE(smulw), |
| 3515 | INTERPRETER_TRANSLATE(pkhtb), | 3297 | INTERPRETER_TRANSLATE(pkhtb), |
| 3516 | INTERPRETER_TRANSLATE(pkhbt), | 3298 | INTERPRETER_TRANSLATE(pkhbt), |
| 3517 | INTERPRETER_TRANSLATE(smul), | 3299 | INTERPRETER_TRANSLATE(smul), |
| 3518 | INTERPRETER_TRANSLATE(smlalxy), | 3300 | INTERPRETER_TRANSLATE(smlalxy), |
| 3519 | INTERPRETER_TRANSLATE(smla), | 3301 | INTERPRETER_TRANSLATE(smla), |
| 3520 | INTERPRETER_TRANSLATE(mcrr), | 3302 | INTERPRETER_TRANSLATE(mcrr), |
| 3521 | INTERPRETER_TRANSLATE(mrrc), | 3303 | INTERPRETER_TRANSLATE(mrrc), |
| 3522 | INTERPRETER_TRANSLATE(cmp), | 3304 | INTERPRETER_TRANSLATE(cmp), |
| 3523 | INTERPRETER_TRANSLATE(tst), | 3305 | INTERPRETER_TRANSLATE(tst), |
| 3524 | INTERPRETER_TRANSLATE(teq), | 3306 | INTERPRETER_TRANSLATE(teq), |
| 3525 | INTERPRETER_TRANSLATE(cmn), | 3307 | INTERPRETER_TRANSLATE(cmn), |
| 3526 | INTERPRETER_TRANSLATE(smull), | 3308 | INTERPRETER_TRANSLATE(smull), |
| 3527 | INTERPRETER_TRANSLATE(umull), | 3309 | INTERPRETER_TRANSLATE(umull), |
| 3528 | INTERPRETER_TRANSLATE(umlal), | 3310 | INTERPRETER_TRANSLATE(umlal), |
| 3529 | INTERPRETER_TRANSLATE(smlal), | 3311 | INTERPRETER_TRANSLATE(smlal), |
| 3530 | INTERPRETER_TRANSLATE(mul), | 3312 | INTERPRETER_TRANSLATE(mul), |
| 3531 | INTERPRETER_TRANSLATE(mla), | 3313 | INTERPRETER_TRANSLATE(mla), |
| 3532 | INTERPRETER_TRANSLATE(ssat), | 3314 | INTERPRETER_TRANSLATE(ssat), |
| 3533 | INTERPRETER_TRANSLATE(usat), | 3315 | INTERPRETER_TRANSLATE(usat), |
| 3534 | INTERPRETER_TRANSLATE(mrs), | 3316 | INTERPRETER_TRANSLATE(mrs), |
| 3535 | INTERPRETER_TRANSLATE(msr), | 3317 | INTERPRETER_TRANSLATE(msr), |
| 3536 | INTERPRETER_TRANSLATE(and), | 3318 | INTERPRETER_TRANSLATE(and), |
| 3537 | INTERPRETER_TRANSLATE(bic), | 3319 | INTERPRETER_TRANSLATE(bic), |
| 3538 | INTERPRETER_TRANSLATE(ldm), | 3320 | INTERPRETER_TRANSLATE(ldm), |
| 3539 | INTERPRETER_TRANSLATE(eor), | 3321 | INTERPRETER_TRANSLATE(eor), |
| 3540 | INTERPRETER_TRANSLATE(add), | 3322 | INTERPRETER_TRANSLATE(add), |
| 3541 | INTERPRETER_TRANSLATE(rsb), | 3323 | INTERPRETER_TRANSLATE(rsb), |
| 3542 | INTERPRETER_TRANSLATE(rsc), | 3324 | INTERPRETER_TRANSLATE(rsc), |
| 3543 | INTERPRETER_TRANSLATE(sbc), | 3325 | INTERPRETER_TRANSLATE(sbc), |
| 3544 | INTERPRETER_TRANSLATE(adc), | 3326 | INTERPRETER_TRANSLATE(adc), |
| 3545 | INTERPRETER_TRANSLATE(sub), | 3327 | INTERPRETER_TRANSLATE(sub), |
| 3546 | INTERPRETER_TRANSLATE(orr), | 3328 | INTERPRETER_TRANSLATE(orr), |
| 3547 | INTERPRETER_TRANSLATE(mvn), | 3329 | INTERPRETER_TRANSLATE(mvn), |
| 3548 | INTERPRETER_TRANSLATE(mov), | 3330 | INTERPRETER_TRANSLATE(mov), |
| 3549 | INTERPRETER_TRANSLATE(stm), | 3331 | INTERPRETER_TRANSLATE(stm), |
| 3550 | INTERPRETER_TRANSLATE(ldm), | 3332 | INTERPRETER_TRANSLATE(ldm), |
| 3551 | INTERPRETER_TRANSLATE(ldrsh), | 3333 | INTERPRETER_TRANSLATE(ldrsh), |
| 3552 | INTERPRETER_TRANSLATE(stm), | 3334 | INTERPRETER_TRANSLATE(stm), |
| 3553 | INTERPRETER_TRANSLATE(ldm), | 3335 | INTERPRETER_TRANSLATE(ldm), |
| 3554 | INTERPRETER_TRANSLATE(ldrsb), | 3336 | INTERPRETER_TRANSLATE(ldrsb), |
| 3555 | INTERPRETER_TRANSLATE(strd), | 3337 | INTERPRETER_TRANSLATE(strd), |
| 3556 | INTERPRETER_TRANSLATE(ldrh), | 3338 | INTERPRETER_TRANSLATE(ldrh), |
| 3557 | INTERPRETER_TRANSLATE(strh), | 3339 | INTERPRETER_TRANSLATE(strh), |
| 3558 | INTERPRETER_TRANSLATE(ldrd), | 3340 | INTERPRETER_TRANSLATE(ldrd), |
| 3559 | INTERPRETER_TRANSLATE(strt), | 3341 | INTERPRETER_TRANSLATE(strt), |
| 3560 | INTERPRETER_TRANSLATE(strbt), | 3342 | INTERPRETER_TRANSLATE(strbt), |
| 3561 | INTERPRETER_TRANSLATE(ldrbt), | 3343 | INTERPRETER_TRANSLATE(ldrbt), |
| 3562 | INTERPRETER_TRANSLATE(ldrt), | 3344 | INTERPRETER_TRANSLATE(ldrt), |
| 3563 | INTERPRETER_TRANSLATE(mrc), | 3345 | INTERPRETER_TRANSLATE(mrc), |
| 3564 | INTERPRETER_TRANSLATE(mcr), | 3346 | INTERPRETER_TRANSLATE(mcr), |
| 3565 | INTERPRETER_TRANSLATE(msr), | 3347 | INTERPRETER_TRANSLATE(msr), |
| 3566 | INTERPRETER_TRANSLATE(ldrb), | 3348 | INTERPRETER_TRANSLATE(ldrb), |
| 3567 | INTERPRETER_TRANSLATE(strb), | 3349 | INTERPRETER_TRANSLATE(strb), |
| 3568 | INTERPRETER_TRANSLATE(ldr), | 3350 | INTERPRETER_TRANSLATE(ldr), |
| 3569 | INTERPRETER_TRANSLATE(ldrcond), | 3351 | INTERPRETER_TRANSLATE(ldrcond), |
| 3570 | INTERPRETER_TRANSLATE(str), | 3352 | INTERPRETER_TRANSLATE(str), |
| 3571 | INTERPRETER_TRANSLATE(cdp), | 3353 | INTERPRETER_TRANSLATE(cdp), |
| 3572 | INTERPRETER_TRANSLATE(stc), | 3354 | INTERPRETER_TRANSLATE(stc), |
| 3573 | INTERPRETER_TRANSLATE(ldc), | 3355 | INTERPRETER_TRANSLATE(ldc), |
| 3574 | INTERPRETER_TRANSLATE(swi), | 3356 | INTERPRETER_TRANSLATE(swi), |
| 3575 | INTERPRETER_TRANSLATE(bbl), | 3357 | INTERPRETER_TRANSLATE(bbl), |
| 3576 | /* All the thumb instructions should be placed the end of table */ | 3358 | // All the thumb instructions should be placed the end of table |
| 3577 | INTERPRETER_TRANSLATE(b_2_thumb), | 3359 | INTERPRETER_TRANSLATE(b_2_thumb), |
| 3578 | INTERPRETER_TRANSLATE(b_cond_thumb), | 3360 | INTERPRETER_TRANSLATE(b_cond_thumb), |
| 3579 | INTERPRETER_TRANSLATE(bl_1_thumb), | 3361 | INTERPRETER_TRANSLATE(bl_1_thumb), |
| 3580 | INTERPRETER_TRANSLATE(bl_2_thumb), | 3362 | INTERPRETER_TRANSLATE(bl_2_thumb), |
| 3581 | INTERPRETER_TRANSLATE(blx_1_thumb) | 3363 | INTERPRETER_TRANSLATE(blx_1_thumb) |
| 3582 | }; | 3364 | }; |
| 3583 | 3365 | ||
| 3584 | typedef std::unordered_map<u32, int> bb_map; | 3366 | typedef std::unordered_map<u32, int> bb_map; |
| 3585 | bb_map CreamCache; | 3367 | bb_map CreamCache; |
| 3586 | 3368 | ||
| 3587 | //#define USE_DUMMY_CACHE | 3369 | void insert_bb(unsigned int addr, int start) { |
| 3588 | 3370 | CreamCache[addr] = start; | |
| 3589 | #ifdef USE_DUMMY_CACHE | ||
| 3590 | unsigned int DummyCache[0x100000]; | ||
| 3591 | #endif | ||
| 3592 | |||
| 3593 | void insert_bb(unsigned int addr, int start) | ||
| 3594 | { | ||
| 3595 | #ifdef USE_DUMMY_CACHE | ||
| 3596 | DummyCache[addr] = start; | ||
| 3597 | #else | ||
| 3598 | CreamCache[addr] = start; | ||
| 3599 | #endif | ||
| 3600 | } | 3371 | } |
| 3601 | 3372 | ||
| 3602 | #define TRANS_THRESHOLD 65000 | 3373 | #define TRANS_THRESHOLD 65000 |
| 3603 | int find_bb(unsigned int addr, int &start) | 3374 | int find_bb(unsigned int addr, int &start) { |
| 3604 | { | 3375 | int ret = -1; |
| 3605 | int ret = -1; | 3376 | bb_map::const_iterator it = CreamCache.find(addr); |
| 3606 | #ifdef USE_DUMMY_CACHE | 3377 | if (it != CreamCache.end()) { |
| 3607 | start = DummyCache[addr]; | 3378 | start = static_cast<int>(it->second); |
| 3608 | if (start) { | 3379 | ret = 0; |
| 3609 | ret = 0; | 3380 | } else { |
| 3610 | } else | 3381 | ret = -1; |
| 3611 | ret = -1; | 3382 | } |
| 3612 | #else | 3383 | return ret; |
| 3613 | bb_map::const_iterator it = CreamCache.find(addr); | ||
| 3614 | if (it != CreamCache.end()) { | ||
| 3615 | start = static_cast<int>(it->second); | ||
| 3616 | ret = 0; | ||
| 3617 | #if HYBRID_MODE | ||
| 3618 | #if PROFILE | ||
| 3619 | #else | ||
| 3620 | /* increase the bb counter */ | ||
| 3621 | if(get_bb_prof(cpu, addr, 1) == TRANS_THRESHOLD){ | ||
| 3622 | push_to_compiled(cpu, addr); | ||
| 3623 | } | ||
| 3624 | #endif | ||
| 3625 | #endif | ||
| 3626 | } else { | ||
| 3627 | ret = -1; | ||
| 3628 | } | ||
| 3629 | #endif | ||
| 3630 | return ret; | ||
| 3631 | } | 3384 | } |
| 3632 | 3385 | ||
| 3633 | |||
| 3634 | enum { | 3386 | enum { |
| 3635 | FETCH_SUCCESS, | 3387 | FETCH_SUCCESS, |
| 3636 | FETCH_FAILURE | 3388 | FETCH_FAILURE |
| 3637 | }; | 3389 | }; |
| 3390 | |||
| 3638 | 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){ | 3391 | 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){ |
| 3639 | /* Check if in Thumb mode. */ | 3392 | // Check if in Thumb mode |
| 3640 | tdstate ret; | 3393 | tdstate ret = thumb_translate (addr, inst, arm_inst, inst_size); |
| 3641 | ret = thumb_translate (addr, inst, arm_inst, inst_size); | 3394 | if(ret == t_branch){ |
| 3642 | if(ret == t_branch){ | 3395 | // TODO: FIXME, endian should be judged |
| 3643 | /* FIXME, endian should be judged */ | 3396 | uint32 tinstr; |
| 3644 | uint32 tinstr; | 3397 | if((addr & 0x3) != 0) |
| 3645 | if((addr & 0x3) != 0) | 3398 | tinstr = inst >> 16; |
| 3646 | tinstr = inst >> 16; | 3399 | else |
| 3647 | else | 3400 | tinstr = inst & 0xFFFF; |
| 3648 | tinstr = inst & 0xFFFF; | 3401 | |
| 3649 | 3402 | int inst_index; | |
| 3650 | //tinstr = inst & 0xFFFF; | 3403 | int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t); |
| 3651 | int inst_index; | 3404 | |
| 3652 | /* table_length */ | 3405 | switch((tinstr & 0xF800) >> 11){ |
| 3653 | int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t); | 3406 | case 26: |
| 3654 | 3407 | case 27: | |
| 3655 | switch((tinstr & 0xF800) >> 11){ | 3408 | if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){ |
| 3656 | /* we will translate the thumb instruction directly here */ | 3409 | uint32 cond = (tinstr & 0x0F00) >> 8; |
| 3657 | /* we will translate the thumb instruction directly here */ | 3410 | inst_index = table_length - 4; |
| 3658 | case 26: | 3411 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); |
| 3659 | case 27: | 3412 | } else { |
| 3660 | if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){ | 3413 | LOG_ERROR(Core_ARM11, "thumb decoder error"); |
| 3661 | uint32 cond = (tinstr & 0x0F00) >> 8; | 3414 | } |
| 3662 | inst_index = table_length - 4; | 3415 | break; |
| 3663 | //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d\n", __FUNCTION__, tinstr, inst_index); | 3416 | case 28: |
| 3664 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); | 3417 | // Branch 2, unconditional branch |
| 3665 | } | 3418 | inst_index = table_length - 5; |
| 3666 | else{ | 3419 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); |
| 3667 | /* something wrong */ | 3420 | break; |
| 3668 | LOG_ERROR(Core_ARM11, "thumb decoder error"); | 3421 | |
| 3669 | } | 3422 | case 8: |
| 3670 | break; | 3423 | case 29: |
| 3671 | case 28: | 3424 | // For BLX 1 thumb instruction |
| 3672 | /* Branch 2, unconditional branch */ | 3425 | inst_index = table_length - 1; |
| 3673 | inst_index = table_length - 5; | 3426 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); |
| 3674 | //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d\n", __FUNCTION__, tinstr, inst_index); | 3427 | break; |
| 3675 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); | 3428 | case 30: |
| 3676 | break; | 3429 | // For BL 1 thumb instruction |
| 3677 | 3430 | inst_index = table_length - 3; | |
| 3678 | case 8: | 3431 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); |
| 3679 | case 29: | 3432 | break; |
| 3680 | /* For BLX 1 thumb instruction*/ | 3433 | case 31: |
| 3681 | inst_index = table_length - 1; | 3434 | // For BL 2 thumb instruction |
| 3682 | //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d, pc=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc); | 3435 | inst_index = table_length - 2; |
| 3683 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); | 3436 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); |
| 3684 | break; | 3437 | break; |
| 3685 | case 30: | 3438 | default: |
| 3686 | /* For BL 1 thumb instruction*/ | 3439 | ret = t_undefined; |
| 3687 | inst_index = table_length - 3; | 3440 | break; |
| 3688 | //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, bl 1 thumb index=%d, pc=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc); | 3441 | } |
| 3689 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); | 3442 | } |
| 3690 | break; | 3443 | return ret; |
| 3691 | case 31: | ||
| 3692 | /* For BL 2 thumb instruction*/ | ||
| 3693 | inst_index = table_length - 2; | ||
| 3694 | //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, bl 2 thumb index=%d, px=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc); | ||
| 3695 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); | ||
| 3696 | break; | ||
| 3697 | default: | ||
| 3698 | ret = t_undefined; | ||
| 3699 | break; | ||
| 3700 | } | ||
| 3701 | } | ||
| 3702 | return ret; | ||
| 3703 | } | ||
| 3704 | |||
| 3705 | #if 0 | ||
| 3706 | int FetchInst(cpu_t *core, unsigned int &inst) | ||
| 3707 | { | ||
| 3708 | //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t"); | ||
| 3709 | arm_processor *cpu = (arm_processor *)(core->cpu_data->obj); | ||
| 3710 | // fault_t fault = interpreter_read_memory(cpu->translate_pc, inst, 32); | ||
| 3711 | fault_t fault = interpreter_fetch(core, cpu->translate_pc, inst, 32); | ||
| 3712 | if (!core->is_user_mode) { | ||
| 3713 | if (fault) { | ||
| 3714 | cpu->abortSig = true; | ||
| 3715 | cpu->Aborted = ARMul_PrefetchAbortV; | ||
| 3716 | cpu->AbortAddr = cpu->translate_pc; | ||
| 3717 | cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; | ||
| 3718 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->translate_pc; | ||
| 3719 | return FETCH_FAILURE; | ||
| 3720 | } | ||
| 3721 | } | ||
| 3722 | return FETCH_SUCCESS; | ||
| 3723 | } | 3444 | } |
| 3724 | #endif | ||
| 3725 | 3445 | ||
| 3726 | unsigned int *InstLength; | 3446 | unsigned int *InstLength; |
| 3727 | 3447 | ||
| 3728 | enum { | 3448 | enum { |
| 3729 | KEEP_GOING, | 3449 | KEEP_GOING, |
| 3730 | FETCH_EXCEPTION | 3450 | FETCH_EXCEPTION |
| 3731 | }; | 3451 | }; |
| 3732 | 3452 | ||
| 3733 | typedef struct instruction_set_encoding_item ISEITEM; | 3453 | typedef struct instruction_set_encoding_item ISEITEM; |
| @@ -3736,274 +3456,148 @@ extern const ISEITEM arm_instruction[]; | |||
| 3736 | 3456 | ||
| 3737 | vector<uint64_t> code_page_set; | 3457 | vector<uint64_t> code_page_set; |
| 3738 | 3458 | ||
| 3739 | void flush_bb(uint32_t addr) | 3459 | void flush_bb(uint32_t addr) { |
| 3740 | { | 3460 | bb_map::iterator it; |
| 3741 | bb_map::iterator it; | 3461 | uint32_t start; |
| 3742 | uint32_t start; | 3462 | |
| 3743 | 3463 | addr &= 0xfffff000; | |
| 3744 | addr &= 0xfffff000; | 3464 | for (it = CreamCache.begin(); it != CreamCache.end(); ) { |
| 3745 | for (it = CreamCache.begin(); it != CreamCache.end(); ) { | 3465 | start = static_cast<uint32_t>(it->first); |
| 3746 | start = static_cast<uint32_t>(it->first); | 3466 | start &= 0xfffff000; |
| 3747 | //start = (start >> 12) << 12; | 3467 | if (start == addr) { |
| 3748 | start &= 0xfffff000; | 3468 | CreamCache.erase(it++); |
| 3749 | if (start == addr) { | 3469 | } else |
| 3750 | //DEBUG_LOG(ARM11, "[ERASE][0x%08x]\n", static_cast<int>(it->first)); | 3470 | ++it; |
| 3751 | CreamCache.erase(it++); | 3471 | } |
| 3752 | } else | 3472 | } |
| 3753 | ++it; | ||
| 3754 | } | ||
| 3755 | |||
| 3756 | //DEBUG_LOG(ARM11, "flush bb @ %x\n", addr); | ||
| 3757 | } | ||
| 3758 | |||
| 3759 | //static uint32_t get_bank_addr(void *addr) | ||
| 3760 | //{ | ||
| 3761 | // uint64_t address = (uint64_t)addr; | ||
| 3762 | // uint64_t bank0 = get_dma_addr(BANK0_START); | ||
| 3763 | // if ((address >= bank0) && (address < (bank0 + BANK0_SIZE))) { | ||
| 3764 | // //DEBUG_LOG(ARM11, "1.addr is %llx\n", addr); | ||
| 3765 | // return ((uint64_t)addr - bank0) + BANK0_START; | ||
| 3766 | // } | ||
| 3767 | // return 0; | ||
| 3768 | //} | ||
| 3769 | |||
| 3770 | /* shenoubang add win32 2012-6-12 */ | ||
| 3771 | //#ifndef __WIN32__ | ||
| 3772 | //static void flush_code_cache(int signal_number, siginfo_t *si, void *unused) | ||
| 3773 | //{ | ||
| 3774 | // DEBUG_LOG(ARM11, "in %s, addr=0x%llx\n", __FUNCTION__, si->si_addr); | ||
| 3775 | // uint64_t addr = (uint64_t)si->si_addr; | ||
| 3776 | // addr = (addr >> 12) << 12; | ||
| 3777 | // skyeye_backtrace(); | ||
| 3778 | // #if 0 | ||
| 3779 | // if (addr == 0) { | ||
| 3780 | // return; | ||
| 3781 | // } | ||
| 3782 | // const vector<uint64_t>::iterator it = find(code_page_set.begin(), | ||
| 3783 | // code_page_set.end(), | ||
| 3784 | // (uint64_t)addr); | ||
| 3785 | // if (it != code_page_set.end()) { | ||
| 3786 | // code_page_set.erase(it); | ||
| 3787 | // } | ||
| 3788 | // mprotect((void *)addr, 4096, PROT_READ | PROT_WRITE); | ||
| 3789 | // //DEBUG_LOG(ARM11, "[flush][ADDR:0x%08llx]\n", addr); | ||
| 3790 | // uint32_t phys_addr = get_bank_addr((void *)addr); | ||
| 3791 | //// DEBUG_LOG(ARM11, "[PHYSICAL][ADDR:0x%08llx]\n", phys_addr); | ||
| 3792 | // flush_bb(phys_addr); | ||
| 3793 | // flush_bb(phys_addr + 4096); | ||
| 3794 | //#if HYBRID_MODE | ||
| 3795 | // /* flush the translated BB of dyncom */ | ||
| 3796 | // clear_translated_cache(phys_addr); | ||
| 3797 | //#endif | ||
| 3798 | // #endif | ||
| 3799 | //} | ||
| 3800 | //#endif /* shenoubang */ | ||
| 3801 | |||
| 3802 | //void protect_code_page(uint32_t addr) | ||
| 3803 | //{ | ||
| 3804 | // void *mem_ptr = (void *)get_dma_addr(addr); | ||
| 3805 | // mem_ptr = (void *)((long long int)mem_ptr & 0xfffffffffffff000LL); | ||
| 3806 | // | ||
| 3807 | // const vector<uint64_t>::iterator it = find(code_page_set.begin(), | ||
| 3808 | // code_page_set.end(), | ||
| 3809 | // (uint64_t)mem_ptr); | ||
| 3810 | // if (it != code_page_set.end()) { | ||
| 3811 | // return; | ||
| 3812 | // } | ||
| 3813 | // //DEBUG_LOG(ARM11, "[mprotect][ADDR:0x%08llx]\n", mem_ptr); | ||
| 3814 | // /* shenoubang add win32 2012-6-12 */ | ||
| 3815 | //#ifndef __WIN32__ | ||
| 3816 | // struct sigaction sa; | ||
| 3817 | // | ||
| 3818 | // memset(&sa, 0, sizeof(sa)); | ||
| 3819 | // sa.sa_flags = SA_RESTART | SA_SIGINFO; | ||
| 3820 | // sa.sa_sigaction = &flush_code_cache; | ||
| 3821 | // sigaction(SIGSEGV, &sa, NULL); | ||
| 3822 | // | ||
| 3823 | // //mprotect(mem_ptr, 4096, PROT_READ); | ||
| 3824 | // | ||
| 3825 | // code_page_set.push_back((uint64_t)mem_ptr); | ||
| 3826 | //#endif /* shenoubang */ | ||
| 3827 | //} | ||
| 3828 | |||
| 3829 | |||
| 3830 | |||
| 3831 | int InterpreterTranslate(arm_processor *cpu, int &bb_start, addr_t addr) | ||
| 3832 | { | ||
| 3833 | /* Decode instruction, get index */ | ||
| 3834 | /* Allocate memory and init InsCream */ | ||
| 3835 | /* Go on next, until terminal instruction */ | ||
| 3836 | /* Save start addr of basicblock in CreamCache */ | ||
| 3837 | //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t"); | ||
| 3838 | //arm_processor *cpu = (arm_processor *)(core->cpu_data->obj); | ||
| 3839 | ARM_INST_PTR inst_base = NULL; | ||
| 3840 | unsigned int inst, inst_size = 4; | ||
| 3841 | int idx; | ||
| 3842 | int ret = NON_BRANCH; | ||
| 3843 | int thumb = 0; | ||
| 3844 | /* instruction size of basic block */ | ||
| 3845 | int size = 0; | ||
| 3846 | /* (R15 - 8) ? */ | ||
| 3847 | //cpu->translate_pc = cpu->Reg[15]; | ||
| 3848 | bb_start = top; | ||
| 3849 | |||
| 3850 | if (cpu->TFlag) | ||
| 3851 | thumb = THUMB; | ||
| 3852 | |||
| 3853 | addr_t phys_addr; | ||
| 3854 | addr_t pc_start; | ||
| 3855 | fault_t fault = NO_FAULT; | ||
| 3856 | //fault = check_address_validity(cpu, addr, &phys_addr, 1, INSN_TLB); | ||
| 3857 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 3858 | if(fault != NO_FAULT){ | ||
| 3859 | cpu->abortSig = true; | ||
| 3860 | cpu->Aborted = ARMul_PrefetchAbortV; | ||
| 3861 | cpu->AbortAddr = addr; | ||
| 3862 | cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; | ||
| 3863 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; | ||
| 3864 | return FETCH_EXCEPTION; | ||
| 3865 | } | ||
| 3866 | pc_start = phys_addr; | ||
| 3867 | //phys_addr = get_dma_addr(phys_addr); | ||
| 3868 | while(ret == NON_BRANCH) { | ||
| 3869 | /* shenoubang add win32 2012-6-14 */ | ||
| 3870 | #ifdef __WIN32__ | ||
| 3871 | mem_bank_t* bank; | ||
| 3872 | if (bank = bank_ptr(addr)) { | ||
| 3873 | bank->bank_read(32, phys_addr, &inst); | ||
| 3874 | } | ||
| 3875 | else { | ||
| 3876 | LOG_ERROR(Core_ARM11, "SKYEYE: Read physical addr 0x%x error!!\n", phys_addr); | ||
| 3877 | return FETCH_FAILURE; | ||
| 3878 | } | ||
| 3879 | #else | ||
| 3880 | inst = Memory::Read32(phys_addr & 0xFFFFFFFC);//*(uint32_t *)(phys_addr & 0xFFFFFFFC); | ||
| 3881 | #endif | ||
| 3882 | //or_tag(core, phys_addr, TAG_FAST_INTERP); | ||
| 3883 | |||
| 3884 | /*if (ret == FETCH_FAILURE) { | ||
| 3885 | return FETCH_EXCEPTION; | ||
| 3886 | }*/ | ||
| 3887 | |||
| 3888 | size ++; | ||
| 3889 | /* If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction */ | ||
| 3890 | if (cpu->TFlag){ | ||
| 3891 | //if(cpu->Cpsr & (1 << THUMB_BIT)){ | ||
| 3892 | uint32_t arm_inst; | ||
| 3893 | tdstate state; | ||
| 3894 | state = decode_thumb_instr(cpu, inst, phys_addr, &arm_inst, &inst_size, &inst_base); | ||
| 3895 | //or_tag(core, phys_addr, TAG_THUMB); | ||
| 3896 | //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); | ||
| 3897 | /* we have translated the branch instruction of thumb in thumb decoder */ | ||
| 3898 | if(state == t_branch){ | ||
| 3899 | goto translated; | ||
| 3900 | } | ||
| 3901 | inst = arm_inst; | ||
| 3902 | } | ||
| 3903 | |||
| 3904 | ret = decode_arm_instr(inst, &idx); | ||
| 3905 | if (ret == DECODE_FAILURE) { | ||
| 3906 | LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : [%x]", phys_addr, inst); | ||
| 3907 | LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]); | ||
| 3908 | CITRA_IGNORE_EXIT(-1); | ||
| 3909 | } | ||
| 3910 | // DEBUG_LOG(ARM11, "PC : [0x%x] INST : %s\n", cpu->translate_pc, arm_instruction[idx].name); | ||
| 3911 | inst_base = arm_instruction_trans[idx](inst, idx); | ||
| 3912 | // DEBUG_LOG(ARM11, "translated @ %x INST : %x\n", cpu->translate_pc, inst); | ||
| 3913 | // DEBUG_LOG(ARM11, "inst size is %d\n", InstLength[idx]); | ||
| 3914 | translated: | ||
| 3915 | phys_addr += inst_size; | ||
| 3916 | 3473 | ||
| 3917 | if ((phys_addr & 0xfff) == 0) { | 3474 | int InterpreterTranslate(arm_processor *cpu, int &bb_start, addr_t addr) { |
| 3918 | inst_base->br = END_OF_PAGE; | 3475 | // Decode instruction, get index |
| 3919 | } | 3476 | // Allocate memory and init InsCream |
| 3920 | ret = inst_base->br; | 3477 | // Go on next, until terminal instruction |
| 3921 | }; | 3478 | // Save start addr of basicblock in CreamCache |
| 3479 | ARM_INST_PTR inst_base = nullptr; | ||
| 3480 | unsigned int inst, inst_size = 4; | ||
| 3481 | int idx; | ||
| 3482 | int ret = NON_BRANCH; | ||
| 3483 | int thumb = 0; | ||
| 3484 | int size = 0; // instruction size of basic block | ||
| 3485 | bb_start = top; | ||
| 3486 | |||
| 3487 | if (cpu->TFlag) | ||
| 3488 | thumb = THUMB; | ||
| 3489 | |||
| 3490 | addr_t phys_addr; | ||
| 3491 | addr_t pc_start; | ||
| 3492 | fault_t fault = NO_FAULT; | ||
| 3493 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 3494 | if(fault != NO_FAULT){ | ||
| 3495 | cpu->abortSig = true; | ||
| 3496 | cpu->Aborted = ARMul_PrefetchAbortV; | ||
| 3497 | cpu->AbortAddr = addr; | ||
| 3498 | cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; | ||
| 3499 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; | ||
| 3500 | return FETCH_EXCEPTION; | ||
| 3501 | } | ||
| 3922 | 3502 | ||
| 3923 | //DEBUG_LOG(ARM11, "In %s,insert_bb pc=0x%x, TFlag=0x%x\n", __FUNCTION__, pc_start, cpu->TFlag); | 3503 | pc_start = phys_addr; |
| 3924 | insert_bb(pc_start, bb_start); | ||
| 3925 | return KEEP_GOING; | ||
| 3926 | } | ||
| 3927 | 3504 | ||
| 3928 | #define LOG_IN_CLR skyeye_printf_in_color | 3505 | while(ret == NON_BRANCH) { |
| 3506 | inst = Memory::Read32(phys_addr & 0xFFFFFFFC);//*(uint32_t *)(phys_addr & 0xFFFFFFFC); | ||
| 3929 | 3507 | ||
| 3930 | int cmp(const void *x, const void *y) | 3508 | size ++; |
| 3931 | { | 3509 | // If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction |
| 3932 | return *(unsigned long long int*)x - *(unsigned long long int *)y; | 3510 | if (cpu->TFlag) { |
| 3511 | uint32_t arm_inst; | ||
| 3512 | tdstate state; | ||
| 3513 | state = decode_thumb_instr(cpu, inst, phys_addr, &arm_inst, &inst_size, &inst_base); | ||
| 3514 | // We have translated the branch instruction of thumb in thumb decoder | ||
| 3515 | if(state == t_branch){ | ||
| 3516 | goto translated; | ||
| 3517 | } | ||
| 3518 | inst = arm_inst; | ||
| 3519 | } | ||
| 3520 | |||
| 3521 | ret = decode_arm_instr(inst, &idx); | ||
| 3522 | if (ret == DECODE_FAILURE) { | ||
| 3523 | LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : [%x]", phys_addr, inst); | ||
| 3524 | LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]); | ||
| 3525 | CITRA_IGNORE_EXIT(-1); | ||
| 3526 | } | ||
| 3527 | inst_base = arm_instruction_trans[idx](inst, idx); | ||
| 3528 | translated: | ||
| 3529 | phys_addr += inst_size; | ||
| 3530 | |||
| 3531 | if ((phys_addr & 0xfff) == 0) { | ||
| 3532 | inst_base->br = END_OF_PAGE; | ||
| 3533 | } | ||
| 3534 | ret = inst_base->br; | ||
| 3535 | }; | ||
| 3536 | insert_bb(pc_start, bb_start); | ||
| 3537 | return KEEP_GOING; | ||
| 3538 | } | ||
| 3539 | |||
| 3540 | #define LOG_IN_CLR skyeye_printf_in_color | ||
| 3541 | |||
| 3542 | int cmp(const void *x, const void *y) { | ||
| 3543 | return *(unsigned long long int*)x - *(unsigned long long int *)y; | ||
| 3544 | } | ||
| 3545 | |||
| 3546 | void InterpreterInitInstLength(unsigned long long int *ptr, size_t size) { | ||
| 3547 | int array_size = size / sizeof(void *); | ||
| 3548 | unsigned long long int *InstLabel = new unsigned long long int[array_size]; | ||
| 3549 | memcpy(InstLabel, ptr, size); | ||
| 3550 | qsort(InstLabel, array_size, sizeof(void *), cmp); | ||
| 3551 | InstLength = new unsigned int[array_size - 4]; | ||
| 3552 | for (int i = 0; i < array_size - 4; i ++) { | ||
| 3553 | for (int j = 0; j < array_size; j ++) { | ||
| 3554 | if (ptr[i] == InstLabel[j]) { | ||
| 3555 | InstLength[i] = InstLabel[j + 1] - InstLabel[j]; | ||
| 3556 | break; | ||
| 3557 | } | ||
| 3558 | } | ||
| 3559 | } | ||
| 3560 | for (int i = 0; i < array_size - 4; i ++) | ||
| 3561 | LOG_DEBUG(Core_ARM11, "[%d]:%d", i, InstLength[i]); | ||
| 3933 | } | 3562 | } |
| 3934 | 3563 | ||
| 3935 | void InterpreterInitInstLength(unsigned long long int *ptr, size_t size) | 3564 | int clz(unsigned int x) { |
| 3936 | { | 3565 | int n; |
| 3937 | int array_size = size / sizeof(void *); | 3566 | if (x == 0) return (32); |
| 3938 | unsigned long long int *InstLabel = new unsigned long long int[array_size]; | 3567 | n = 1; |
| 3939 | memcpy(InstLabel, ptr, size); | 3568 | if ((x >> 16) == 0) { n = n + 16; x = x << 16;} |
| 3940 | qsort(InstLabel, array_size, sizeof(void *), cmp); | 3569 | if ((x >> 24) == 0) { n = n + 8; x = x << 8;} |
| 3941 | InstLength = new unsigned int[array_size - 4]; | 3570 | if ((x >> 28) == 0) { n = n + 4; x = x << 4;} |
| 3942 | for (int i = 0; i < array_size - 4; i ++) { | 3571 | if ((x >> 30) == 0) { n = n + 2; x = x << 2;} |
| 3943 | for (int j = 0; j < array_size; j ++) { | 3572 | n = n - (x >> 31); |
| 3944 | if (ptr[i] == InstLabel[j]) { | 3573 | return n; |
| 3945 | InstLength[i] = InstLabel[j + 1] - InstLabel[j]; | ||
| 3946 | break; | ||
| 3947 | } | ||
| 3948 | } | ||
| 3949 | } | ||
| 3950 | for (int i = 0; i < array_size - 4; i ++) | ||
| 3951 | LOG_DEBUG(Core_ARM11, "[%d]:%d", i, InstLength[i]); | ||
| 3952 | } | ||
| 3953 | |||
| 3954 | int clz(unsigned int x) | ||
| 3955 | { | ||
| 3956 | int n; | ||
| 3957 | if (x == 0) return (32); | ||
| 3958 | n = 1; | ||
| 3959 | if ((x >> 16) == 0) { n = n + 16; x = x << 16;} | ||
| 3960 | if ((x >> 24) == 0) { n = n + 8; x = x << 8;} | ||
| 3961 | if ((x >> 28) == 0) { n = n + 4; x = x << 4;} | ||
| 3962 | if ((x >> 30) == 0) { n = n + 2; x = x << 2;} | ||
| 3963 | n = n - (x >> 31); | ||
| 3964 | return n; | ||
| 3965 | } | 3574 | } |
| 3966 | 3575 | ||
| 3967 | unsigned arm_dyncom_SWI (ARMul_State * state, ARMword number); | 3576 | unsigned arm_dyncom_SWI (ARMul_State * state, ARMword number); |
| 3968 | 3577 | ||
| 3969 | static bool InAPrivilegedMode(arm_core_t *core) | 3578 | static bool InAPrivilegedMode(arm_core_t *core) { |
| 3970 | { | 3579 | return (core->Mode != USER32MODE); |
| 3971 | return (core->Mode != USER32MODE); | ||
| 3972 | } | 3580 | } |
| 3973 | 3581 | ||
| 3974 | /* r15 = r15 + 8 */ | 3582 | unsigned InterpreterMainLoop(ARMul_State* state) { |
| 3975 | unsigned InterpreterMainLoop(ARMul_State* state) | 3583 | #define CRn inst_cream->crn |
| 3976 | { | 3584 | #define OPCODE_2 inst_cream->opcode_2 |
| 3977 | #define CRn inst_cream->crn | 3585 | #define CRm inst_cream->crm |
| 3978 | #define OPCODE_2 inst_cream->opcode_2 | 3586 | #define CP15_REG(n) cpu->CP15[CP15(n)] |
| 3979 | #define CRm inst_cream->crm | 3587 | #define RD cpu->Reg[inst_cream->Rd] |
| 3980 | #define CP15_REG(n) cpu->CP15[CP15(n)] | 3588 | #define RN cpu->Reg[inst_cream->Rn] |
| 3981 | #define RD cpu->Reg[inst_cream->Rd] | 3589 | #define RM cpu->Reg[inst_cream->Rm] |
| 3982 | #define RN cpu->Reg[inst_cream->Rn] | 3590 | #define RS cpu->Reg[inst_cream->Rs] |
| 3983 | #define RM cpu->Reg[inst_cream->Rm] | 3591 | #define RDHI cpu->Reg[inst_cream->RdHi] |
| 3984 | #define RS cpu->Reg[inst_cream->Rs] | 3592 | #define RDLO cpu->Reg[inst_cream->RdLo] |
| 3985 | #define RDHI cpu->Reg[inst_cream->RdHi] | 3593 | #define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4) |
| 3986 | #define RDLO cpu->Reg[inst_cream->RdLo] | 3594 | #define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24) |
| 3987 | #define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4) | 3595 | #define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand) |
| 3988 | #define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24) | 3596 | |
| 3989 | #define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand) | 3597 | #define FETCH_INST if (inst_base->br != NON_BRANCH) goto DISPATCH; \ |
| 3990 | 3598 | inst_base = (arm_inst *)&inst_buf[ptr] | |
| 3991 | #if ENABLE_ICOUNTER | 3599 | |
| 3992 | #define INC_ICOUNTER cpu->icounter++; \ | 3600 | #define INC_PC(l) ptr += sizeof(arm_inst) + l |
| 3993 | if(cpu->Reg[15] > 0xc0000000) \ | ||
| 3994 | cpu->kernel_icounter++; | ||
| 3995 | /*if (debug_function(core)) \ | ||
| 3996 | if (core->check_int_flag) \ | ||
| 3997 | goto END*/ | ||
| 3998 | //LOG_TRACE(Core_ARM11, "icounter is %llx pc is %x\n", cpu->icounter, cpu->Reg[15]) | ||
| 3999 | #else | ||
| 4000 | #define INC_ICOUNTER ; | ||
| 4001 | #endif | ||
| 4002 | |||
| 4003 | #define FETCH_INST if (inst_base->br != NON_BRANCH) \ | ||
| 4004 | goto DISPATCH; \ | ||
| 4005 | inst_base = (arm_inst *)&inst_buf[ptr] | ||
| 4006 | #define INC_PC(l) ptr += sizeof(arm_inst) + l | ||
| 4007 | 3601 | ||
| 4008 | // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a | 3602 | // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a |
| 4009 | // clunky switch statement. | 3603 | // clunky switch statement. |
| @@ -4213,3014 +3807,2522 @@ unsigned InterpreterMainLoop(ARMul_State* state) | |||
| 4213 | } | 3807 | } |
| 4214 | #endif | 3808 | #endif |
| 4215 | 3809 | ||
| 4216 | #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0) | 3810 | #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0) |
| 4217 | #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1) | 3811 | #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1) |
| 4218 | /* #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((ISNEG(lop) && ISPOS(rop)) || \ | 3812 | |
| 4219 | (ISNEG(lop) && ISPOS(dst)) || \ | 3813 | #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((dst < lop) || (dst < rop))) |
| 4220 | (ISPOS(rop) && ISPOS(dst)))) */ | 3814 | #define UPDATE_CFLAG_CARRY_FROM_ADD(lop, rop, flag) (cpu->CFlag = (((uint64_t) lop + (uint64_t) rop + (uint64_t) flag) > 0xffffffff) ) |
| 4221 | #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((dst < lop) || (dst < rop))) | 3815 | #define UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(lop, rop, flag) (cpu->CFlag = ((uint64_t) lop >= ((uint64_t) rop + (uint64_t) flag))) |
| 4222 | #define UPDATE_CFLAG_CARRY_FROM_ADD(lop, rop, flag) (cpu->CFlag = (((uint64_t) lop + (uint64_t) rop + (uint64_t) flag) > 0xffffffff) ) | 3816 | #define UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop) (cpu->CFlag = (lop >= rop)) |
| 4223 | #define UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(lop, rop, flag) (cpu->CFlag = ((uint64_t) lop >= ((uint64_t) rop + (uint64_t) flag))) | 3817 | #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) (cpu->CFlag = !(dst < lop)) |
| 4224 | #define UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop) (cpu->CFlag = (lop >= rop)) | 3818 | #define UPDATE_CFLAG_WITH_SC (cpu->CFlag = cpu->shifter_carry_out) |
| 4225 | #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) (cpu->CFlag = !(dst < lop)) | 3819 | |
| 4226 | #define UPDATE_CFLAG_WITH_SC cpu->CFlag = cpu->shifter_carry_out | 3820 | #define UPDATE_VFLAG(dst, lop, rop) (cpu->VFlag = (((lop < 0) && (rop < 0) && (dst >= 0)) || \ |
| 4227 | /* #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || \ | 3821 | ((lop >= 0) && (rop) >= 0 && (dst < 0)))) |
| 4228 | (ISNEG(lop) && ISPOS(dst)) || \ | 3822 | #define UPDATE_VFLAG_WITH_NOT(dst, lop, rop) (cpu->VFlag = !(((lop < 0) && (rop < 0) && (dst >= 0)) || \ |
| 4229 | (ISPOS(rop) && ISPOS(dst))) */ | 3823 | ((lop >= 0) && (rop) >= 0 && (dst < 0)))) |
| 4230 | #define UPDATE_VFLAG(dst, lop, rop) (cpu->VFlag = (((lop < 0) && (rop < 0) && (dst >= 0)) || \ | 3824 | #define UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop) (cpu->VFlag = (((lop ^ rop) & (lop ^ dst)) >> 31)) |
| 4231 | ((lop >= 0) && (rop) >= 0 && (dst < 0)))) | 3825 | |
| 4232 | #define UPDATE_VFLAG_WITH_NOT(dst, lop, rop) (cpu->VFlag = !(((lop < 0) && (rop < 0) && (dst >= 0)) || \ | 3826 | #define SAVE_NZCVT cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \ |
| 4233 | ((lop >= 0) && (rop) >= 0 && (dst < 0)))) | 3827 | (cpu->NFlag << 31) | \ |
| 4234 | #define UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop) (cpu->VFlag = (((lop ^ rop) & (lop ^ dst)) >> 31)) | 3828 | (cpu->ZFlag << 30) | \ |
| 4235 | 3829 | (cpu->CFlag << 29) | \ | |
| 4236 | #define SAVE_NZCVT cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \ | 3830 | (cpu->VFlag << 28) | \ |
| 4237 | (cpu->NFlag << 31) | \ | 3831 | (cpu->TFlag << 5) |
| 4238 | (cpu->ZFlag << 30) | \ | 3832 | #define LOAD_NZCVT cpu->NFlag = (cpu->Cpsr >> 31); \ |
| 4239 | (cpu->CFlag << 29) | \ | 3833 | cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \ |
| 4240 | (cpu->VFlag << 28) | \ | 3834 | cpu->CFlag = (cpu->Cpsr >> 29) & 1; \ |
| 4241 | (cpu->TFlag << 5) | 3835 | cpu->VFlag = (cpu->Cpsr >> 28) & 1; \ |
| 4242 | #define LOAD_NZCVT cpu->NFlag = (cpu->Cpsr >> 31); \ | 3836 | cpu->TFlag = (cpu->Cpsr >> 5) & 1; |
| 4243 | cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \ | 3837 | |
| 4244 | cpu->CFlag = (cpu->Cpsr >> 29) & 1; \ | 3838 | #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE) |
| 4245 | cpu->VFlag = (cpu->Cpsr >> 28) & 1; \ | 3839 | #define PC (cpu->Reg[15]) |
| 4246 | cpu->TFlag = (cpu->Cpsr >> 5) & 1; | 3840 | #define CHECK_EXT_INT if (!cpu->NirqSig && !(cpu->Cpsr & 0x80)) goto END; |
| 4247 | 3841 | ||
| 4248 | #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE) | 3842 | arm_processor *cpu = state; |
| 4249 | #define PC (cpu->Reg[15]) | ||
| 4250 | #define CHECK_EXT_INT if (!cpu->NirqSig) { \ | ||
| 4251 | if (!(cpu->Cpsr & 0x80)) { \ | ||
| 4252 | goto END; \ | ||
| 4253 | } \ | ||
| 4254 | } | ||
| 4255 | |||
| 4256 | |||
| 4257 | |||
| 4258 | //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t"); | ||
| 4259 | arm_processor *cpu = state; //(arm_processor *)(core->cpu_data->obj); | ||
| 4260 | 3843 | ||
| 4261 | // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback | 3844 | // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback |
| 4262 | // to a clunky switch statement. | 3845 | // to a clunky switch statement. |
| 4263 | #if defined __GNUC__ || defined __clang__ | 3846 | #if defined __GNUC__ || defined __clang__ |
| 4264 | void *InstLabel[] = { | 3847 | void *InstLabel[] = { |
| 4265 | &&VMLA_INST, &&VMLS_INST, &&VNMLA_INST, &&VNMLA_INST, &&VNMLS_INST, &&VNMUL_INST, &&VMUL_INST, &&VADD_INST, &&VSUB_INST, | 3848 | &&VMLA_INST, &&VMLS_INST, &&VNMLA_INST, &&VNMLA_INST, &&VNMLS_INST, &&VNMUL_INST, &&VMUL_INST, &&VADD_INST, &&VSUB_INST, |
| 4266 | &&VDIV_INST, &&VMOVI_INST, &&VMOVR_INST, &&VABS_INST, &&VNEG_INST, &&VSQRT_INST, &&VCMP_INST, &&VCMP2_INST, &&VCVTBDS_INST, | 3849 | &&VDIV_INST, &&VMOVI_INST, &&VMOVR_INST, &&VABS_INST, &&VNEG_INST, &&VSQRT_INST, &&VCMP_INST, &&VCMP2_INST, &&VCVTBDS_INST, |
| 4267 | &&VCVTBFF_INST, &&VCVTBFI_INST, &&VMOVBRS_INST, &&VMSR_INST, &&VMOVBRC_INST, &&VMRS_INST, &&VMOVBCR_INST, &&VMOVBRRSS_INST, | 3850 | &&VCVTBFF_INST, &&VCVTBFI_INST, &&VMOVBRS_INST, &&VMSR_INST, &&VMOVBRC_INST, &&VMRS_INST, &&VMOVBCR_INST, &&VMOVBRRSS_INST, |
| 4268 | &&VMOVBRRD_INST, &&VSTR_INST, &&VPUSH_INST, &&VSTM_INST, &&VPOP_INST, &&VLDR_INST, &&VLDM_INST, | 3851 | &&VMOVBRRD_INST, &&VSTR_INST, &&VPUSH_INST, &&VSTM_INST, &&VPOP_INST, &&VLDR_INST, &&VLDM_INST, |
| 4269 | 3852 | ||
| 4270 | &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST, | 3853 | &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST, |
| 4271 | &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST, | 3854 | &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST, |
| 4272 | &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST, | 3855 | &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST, |
| 4273 | &&SHADD8_INST,&&SHADD16_INST,&&SEL_INST,&&SADDSUBX_INST,&&SADD8_INST,&&SADD16_INST,&&SHSUB16_INST,&&UMAAL_INST,&&UXTAB16_INST, | 3856 | &&SHADD8_INST,&&SHADD16_INST,&&SEL_INST,&&SADDSUBX_INST,&&SADD8_INST,&&SADD16_INST,&&SHSUB16_INST,&&UMAAL_INST,&&UXTAB16_INST, |
| 4274 | &&USUBADDX_INST,&&USUB8_INST,&&USUB16_INST,&&USAT16_INST,&&USADA8_INST,&&UQSUBADDX_INST,&&UQSUB8_INST,&&UQSUB16_INST, | 3857 | &&USUBADDX_INST,&&USUB8_INST,&&USUB16_INST,&&USAT16_INST,&&USADA8_INST,&&UQSUBADDX_INST,&&UQSUB8_INST,&&UQSUB16_INST, |
| 4275 | &&UQADDSUBX_INST,&&UQADD8_INST,&&UQADD16_INST,&&SXTAB_INST,&&UHSUBADDX_INST,&&UHSUB8_INST,&&UHSUB16_INST,&&UHADDSUBX_INST,&&UHADD8_INST, | 3858 | &&UQADDSUBX_INST,&&UQADD8_INST,&&UQADD16_INST,&&SXTAB_INST,&&UHSUBADDX_INST,&&UHSUB8_INST,&&UHSUB16_INST,&&UHADDSUBX_INST,&&UHADD8_INST, |
| 4276 | &&UHADD16_INST,&&UADDSUBX_INST,&&UADD8_INST,&&UADD16_INST,&&SXTAH_INST,&&SXTAB16_INST,&&QADD8_INST,&&BXJ_INST,&&CLZ_INST,&&UXTAH_INST, | 3859 | &&UHADD16_INST,&&UADDSUBX_INST,&&UADD8_INST,&&UADD16_INST,&&SXTAH_INST,&&SXTAB16_INST,&&QADD8_INST,&&BXJ_INST,&&CLZ_INST,&&UXTAH_INST, |
| 4277 | &&BX_INST,&&REV_INST,&&BLX_INST,&&REVSH_INST,&&QADD_INST,&&QADD16_INST,&&QADDSUBX_INST,&&LDREX_INST,&&QDADD_INST,&&QDSUB_INST, | 3860 | &&BX_INST,&&REV_INST,&&BLX_INST,&&REVSH_INST,&&QADD_INST,&&QADD16_INST,&&QADDSUBX_INST,&&LDREX_INST,&&QDADD_INST,&&QDSUB_INST, |
| 4278 | &&QSUB_INST,&&LDREXB_INST,&&QSUB8_INST,&&QSUB16_INST,&&SMUAD_INST,&&SMMUL_INST,&&SMUSD_INST,&&SMLSD_INST,&&SMLSLD_INST,&&SMMLA_INST, | 3861 | &&QSUB_INST,&&LDREXB_INST,&&QSUB8_INST,&&QSUB16_INST,&&SMUAD_INST,&&SMMUL_INST,&&SMUSD_INST,&&SMLSD_INST,&&SMLSLD_INST,&&SMMLA_INST, |
| 4279 | &&SMMLS_INST,&&SMLALD_INST,&&SMLAD_INST,&&SMLAW_INST,&&SMULW_INST,&&PKHTB_INST,&&PKHBT_INST,&&SMUL_INST,&&SMLALXY_INST,&&SMLA_INST, | 3862 | &&SMMLS_INST,&&SMLALD_INST,&&SMLAD_INST,&&SMLAW_INST,&&SMULW_INST,&&PKHTB_INST,&&PKHBT_INST,&&SMUL_INST,&&SMLALXY_INST,&&SMLA_INST, |
| 4280 | &&MCRR_INST,&&MRRC_INST,&&CMP_INST,&&TST_INST,&&TEQ_INST,&&CMN_INST,&&SMULL_INST,&&UMULL_INST,&&UMLAL_INST,&&SMLAL_INST,&&MUL_INST, | 3863 | &&MCRR_INST,&&MRRC_INST,&&CMP_INST,&&TST_INST,&&TEQ_INST,&&CMN_INST,&&SMULL_INST,&&UMULL_INST,&&UMLAL_INST,&&SMLAL_INST,&&MUL_INST, |
| 4281 | &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST, | 3864 | &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST, |
| 4282 | &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST, | 3865 | &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST, |
| 4283 | &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST, | 3866 | &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST, |
| 4284 | &&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, | 3867 | &&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, |
| 4285 | &&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,&&INIT_INST_LENGTH,&&END | 3868 | &&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,&&INIT_INST_LENGTH,&&END |
| 4286 | }; | 3869 | }; |
| 4287 | #endif | 3870 | #endif |
| 4288 | arm_inst * inst_base; | 3871 | arm_inst * inst_base; |
| 4289 | unsigned int lop, rop, dst; | 3872 | unsigned int lop, rop, dst; |
| 4290 | unsigned int addr; | 3873 | unsigned int addr; |
| 4291 | unsigned int phys_addr; | 3874 | unsigned int phys_addr; |
| 4292 | unsigned int last_pc = 0; | 3875 | unsigned int last_pc = 0; |
| 4293 | unsigned int num_instrs = 0; | 3876 | unsigned int num_instrs = 0; |
| 4294 | fault_t fault; | 3877 | fault_t fault; |
| 4295 | static unsigned int last_physical_base = 0, last_logical_base = 0; | 3878 | static unsigned int last_physical_base = 0, last_logical_base = 0; |
| 4296 | int ptr; | 3879 | int ptr; |
| 4297 | bool single_step = (cpu->NumInstrsToExecute == 1); | 3880 | bool single_step = (cpu->NumInstrsToExecute == 1); |
| 4298 | 3881 | ||
| 4299 | LOAD_NZCVT; | 3882 | LOAD_NZCVT; |
| 4300 | DISPATCH: | 3883 | DISPATCH: |
| 4301 | { | 3884 | { |
| 4302 | if (!cpu->NirqSig) { | 3885 | if (!cpu->NirqSig) { |
| 4303 | if (!(cpu->Cpsr & 0x80)) { | 3886 | if (!(cpu->Cpsr & 0x80)) { |
| 4304 | goto END; | 3887 | goto END; |
| 4305 | } | 3888 | } |
| 4306 | } | 3889 | } |
| 4307 | 3890 | ||
| 4308 | if (cpu->TFlag) { | 3891 | if (cpu->TFlag) |
| 4309 | cpu->Reg[15] &= 0xfffffffe; | 3892 | cpu->Reg[15] &= 0xfffffffe; |
| 4310 | } else | 3893 | else |
| 4311 | cpu->Reg[15] &= 0xfffffffc; | 3894 | cpu->Reg[15] &= 0xfffffffc; |
| 4312 | #if PROFILE | 3895 | |
| 4313 | /* check next instruction address is valid. */ | 3896 | phys_addr = cpu->Reg[15]; |
| 4314 | last_pc = cpu->Reg[15]; | 3897 | |
| 4315 | #endif | 3898 | if (find_bb(phys_addr, ptr) == -1) |
| 4316 | #if USER_MODE_OPT | ||
| 4317 | phys_addr = cpu->Reg[15]; | ||
| 4318 | #else | ||
| 4319 | { | ||
| 4320 | if (last_logical_base == (cpu->Reg[15] & 0xfffff000)) | ||
| 4321 | phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff); | ||
| 4322 | else { | ||
| 4323 | /* check next instruction address is valid. */ | ||
| 4324 | fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB); | ||
| 4325 | if (fault) { | ||
| 4326 | cpu->abortSig = true; | ||
| 4327 | cpu->Aborted = ARMul_PrefetchAbortV; | ||
| 4328 | cpu->AbortAddr = cpu->Reg[15]; | ||
| 4329 | cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; | ||
| 4330 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15]; | ||
| 4331 | goto END; | ||
| 4332 | } | ||
| 4333 | last_logical_base = cpu->Reg[15] & 0xfffff000; | ||
| 4334 | last_physical_base = phys_addr & 0xfffff000; | ||
| 4335 | } | ||
| 4336 | } | ||
| 4337 | #if HYBRID_MODE | ||
| 4338 | /* check if the native code of dyncom is available */ | ||
| 4339 | //fast_map hash_map = core->dyncom_engine->fmap; | ||
| 4340 | //void * pfunc = NULL; | ||
| 4341 | //PFUNC(phys_addr); | ||
| 4342 | //if(pfunc){ | ||
| 4343 | if(is_translated_entry(core, phys_addr)){ | ||
| 4344 | int rc = JIT_RETURN_NOERR; | ||
| 4345 | //DEBUG_LOG(ARM11, "enter jit icounter is %lld, pc=0x%x\n", core->icounter, cpu->Reg[15]); | ||
| 4346 | SAVE_NZCVT; | ||
| 4347 | // resume_timing(); | ||
| 4348 | rc = cpu_run(core); | ||
| 4349 | LOAD_NZCVT; | ||
| 4350 | //DEBUG_LOG(ARM11, "out of jit ret is %d icounter is %lld, pc=0x%x\n", rc, core->icounter, cpu->Reg[15]); | ||
| 4351 | if((rc == JIT_RETURN_FUNCNOTFOUND) || (rc == JIT_RETURN_FUNC_BLANK)){ | ||
| 4352 | /* keep the tflag same with the bit in CPSR */ | ||
| 4353 | //cpu->TFlag = cpu->Cpsr & (1 << THUMB_BIT); | ||
| 4354 | //cpu->TFlag = cpu->Cpsr & (1 << 5); | ||
| 4355 | //switch_mode(cpu, cpu->Cpsr & 0x1f); | ||
| 4356 | //DEBUG_LOG(ARM11, "FUNCTION not found , pc=0x%x\n", cpu->Reg[15]); | ||
| 4357 | fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB); | ||
| 4358 | if (fault) { | ||
| 4359 | cpu->abortSig = true; | ||
| 4360 | cpu->Aborted = ARMul_PrefetchAbortV; | ||
| 4361 | cpu->AbortAddr = cpu->Reg[15]; | ||
| 4362 | cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; | ||
| 4363 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15]; | ||
| 4364 | goto END; | ||
| 4365 | } | ||
| 4366 | last_logical_base = cpu->Reg[15] & 0xfffff000; | ||
| 4367 | last_physical_base = phys_addr & 0xfffff000; | ||
| 4368 | core->current_page_phys = last_physical_base; | ||
| 4369 | core->current_page_effec = last_logical_base; | ||
| 4370 | //push_to_compiled(core, phys_addr); | ||
| 4371 | } | ||
| 4372 | else{ | ||
| 4373 | if((cpu->CP15[CP15(CP15_TLB_FAULT_STATUS)] & 0xf0)){ | ||
| 4374 | //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]); | ||
| 4375 | //core->Reg[15] -= get_instr_size(cpu_dyncom); | ||
| 4376 | fill_tlb(cpu); | ||
| 4377 | goto END; | ||
| 4378 | } | ||
| 4379 | if (cpu->syscallSig) { | ||
| 4380 | goto END; | ||
| 4381 | } | ||
| 4382 | if (cpu->abortSig) { | ||
| 4383 | cpu->CP15[CP15_TLB_FAULT_STATUS - CP15_BASE] &= 0xFFFFFFF0; | ||
| 4384 | goto END; | ||
| 4385 | } | ||
| 4386 | if (!cpu->NirqSig) { | ||
| 4387 | if (!(cpu->Cpsr & 0x80)) { | ||
| 4388 | goto END; | ||
| 4389 | } | ||
| 4390 | } | ||
| 4391 | |||
| 4392 | /* if regular trap */ | ||
| 4393 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4394 | /*uint32_t mode = cpu->Cpsr & 0x1f; | ||
| 4395 | if ((mode != cpu->Mode) && (!is_user_mode(core))) { | ||
| 4396 | switch_mode(cpu, mode); | ||
| 4397 | return 1; | ||
| 4398 | }*/ | ||
| 4399 | |||
| 4400 | goto END; | ||
| 4401 | } | ||
| 4402 | //phys_addr = cpu->Reg[15]; | ||
| 4403 | } | ||
| 4404 | else{ | ||
| 4405 | if (last_logical_base == (cpu->Reg[15] & 0xfffff000)) | ||
| 4406 | phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff); | ||
| 4407 | else { | ||
| 4408 | /* check next instruction address is valid. */ | ||
| 4409 | fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB); | ||
| 4410 | if (fault) { | ||
| 4411 | cpu->abortSig = true; | ||
| 4412 | cpu->Aborted = ARMul_PrefetchAbortV; | ||
| 4413 | cpu->AbortAddr = cpu->Reg[15]; | ||
| 4414 | cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; | ||
| 4415 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15]; | ||
| 4416 | goto END; | ||
| 4417 | } | ||
| 4418 | last_logical_base = cpu->Reg[15] & 0xfffff000; | ||
| 4419 | last_physical_base = phys_addr & 0xfffff000; | ||
| 4420 | } | ||
| 4421 | } | ||
| 4422 | #endif /* #if HYBRID_MODE */ | ||
| 4423 | #endif /* #if USER_MODE_OPT */ | ||
| 4424 | if (true){//if(is_fast_interp_code(core, phys_addr)){ | ||
| 4425 | if (find_bb(phys_addr, ptr) == -1) | ||
| 4426 | if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION) | ||
| 4427 | goto END; | ||
| 4428 | } | ||
| 4429 | else{ | ||
| 4430 | if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION) | 3899 | if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION) |
| 4431 | goto END; | 3900 | goto END; |
| 4432 | } | 3901 | |
| 4433 | #if PROFILE | 3902 | inst_base = (arm_inst *)&inst_buf[ptr]; |
| 4434 | resume_timing(); | 3903 | GOTO_NEXT_INST; |
| 4435 | #endif | 3904 | } |
| 4436 | inst_base = (arm_inst *)&inst_buf[ptr]; | 3905 | ADC_INST: |
| 4437 | GOTO_NEXT_INST; | 3906 | { |
| 4438 | } | 3907 | adc_inst *inst_cream = (adc_inst *)inst_base->component; |
| 4439 | ADC_INST: | 3908 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4440 | { | 3909 | lop = RN; |
| 4441 | INC_ICOUNTER; | 3910 | unsigned int sht_op = SHIFTER_OPERAND; |
| 4442 | adc_inst *inst_cream = (adc_inst *)inst_base->component; | 3911 | rop = SHIFTER_OPERAND + cpu->CFlag; |
| 4443 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 3912 | RD = dst = lop + rop; |
| 4444 | lop = RN; | 3913 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 4445 | unsigned int sht_op = SHIFTER_OPERAND; | 3914 | if (CurrentModeHasSPSR) { |
| 4446 | rop = SHIFTER_OPERAND + cpu->CFlag; | 3915 | cpu->Cpsr = cpu->Spsr_copy; |
| 4447 | RD = dst = lop + rop; | 3916 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); |
| 4448 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 3917 | LOAD_NZCVT; |
| 4449 | /* cpsr = spsr */ | 3918 | } |
| 4450 | if (CurrentModeHasSPSR) { | 3919 | } else if (inst_cream->S) { |
| 4451 | cpu->Cpsr = cpu->Spsr_copy; | 3920 | UPDATE_NFLAG(dst); |
| 4452 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 3921 | UPDATE_ZFLAG(dst); |
| 4453 | LOAD_NZCVT; | 3922 | UPDATE_CFLAG_CARRY_FROM_ADD(lop, sht_op, cpu->CFlag); |
| 4454 | } | 3923 | UPDATE_VFLAG((int)dst, (int)lop, (int)rop); |
| 4455 | } else if (inst_cream->S) { | 3924 | } |
| 4456 | UPDATE_NFLAG(dst); | 3925 | if (inst_cream->Rd == 15) { |
| 4457 | UPDATE_ZFLAG(dst); | 3926 | INC_PC(sizeof(adc_inst)); |
| 4458 | UPDATE_CFLAG_CARRY_FROM_ADD(lop, sht_op, cpu->CFlag); | 3927 | goto DISPATCH; |
| 4459 | UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | 3928 | } |
| 4460 | } | 3929 | } |
| 4461 | if (inst_cream->Rd == 15) { | 3930 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4462 | INC_PC(sizeof(adc_inst)); | 3931 | INC_PC(sizeof(adc_inst)); |
| 4463 | goto DISPATCH; | 3932 | FETCH_INST; |
| 4464 | } | 3933 | GOTO_NEXT_INST; |
| 4465 | } | 3934 | } |
| 4466 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 3935 | ADD_INST: |
| 4467 | INC_PC(sizeof(adc_inst)); | 3936 | { |
| 4468 | FETCH_INST; | 3937 | add_inst *inst_cream = (add_inst *)inst_base->component; |
| 4469 | GOTO_NEXT_INST; | 3938 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4470 | } | 3939 | lop = RN; |
| 4471 | ADD_INST: | 3940 | if (inst_cream->Rn == 15) { |
| 4472 | { | 3941 | lop += 2 * GET_INST_SIZE(cpu); |
| 4473 | INC_ICOUNTER; | 3942 | } |
| 4474 | add_inst *inst_cream = (add_inst *)inst_base->component; | 3943 | rop = SHIFTER_OPERAND; |
| 4475 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 3944 | RD = dst = lop + rop; |
| 4476 | lop = RN; | 3945 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 4477 | if (inst_cream->Rn == 15) { | 3946 | if (CurrentModeHasSPSR) { |
| 4478 | lop += 2 * GET_INST_SIZE(cpu); | 3947 | cpu->Cpsr = cpu->Spsr_copy; |
| 4479 | } | 3948 | switch_mode(cpu, cpu->Cpsr & 0x1f); |
| 4480 | rop = SHIFTER_OPERAND; | 3949 | LOAD_NZCVT; |
| 4481 | RD = dst = lop + rop; | 3950 | } |
| 4482 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 3951 | } else if (inst_cream->S) { |
| 4483 | /* cpsr = spsr*/ | 3952 | UPDATE_NFLAG(dst); |
| 4484 | if (CurrentModeHasSPSR) { | 3953 | UPDATE_ZFLAG(dst); |
| 4485 | cpu->Cpsr = cpu->Spsr_copy; | 3954 | UPDATE_CFLAG(dst, lop, rop); |
| 4486 | switch_mode(cpu, cpu->Cpsr & 0x1f); | 3955 | UPDATE_VFLAG((int)dst, (int)lop, (int)rop); |
| 4487 | LOAD_NZCVT; | 3956 | } |
| 4488 | } | 3957 | if (inst_cream->Rd == 15) { |
| 4489 | } else if (inst_cream->S) { | 3958 | INC_PC(sizeof(add_inst)); |
| 4490 | UPDATE_NFLAG(dst); | 3959 | goto DISPATCH; |
| 4491 | UPDATE_ZFLAG(dst); | 3960 | } |
| 4492 | UPDATE_CFLAG(dst, lop, rop); | 3961 | } |
| 4493 | UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | 3962 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4494 | } | 3963 | INC_PC(sizeof(add_inst)); |
| 4495 | if (inst_cream->Rd == 15) { | 3964 | FETCH_INST; |
| 4496 | INC_PC(sizeof(add_inst)); | 3965 | GOTO_NEXT_INST; |
| 4497 | goto DISPATCH; | 3966 | } |
| 4498 | } | 3967 | AND_INST: |
| 4499 | } | 3968 | { |
| 4500 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 3969 | and_inst *inst_cream = (and_inst *)inst_base->component; |
| 4501 | INC_PC(sizeof(add_inst)); | 3970 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4502 | FETCH_INST; | 3971 | lop = RN; |
| 4503 | GOTO_NEXT_INST; | 3972 | rop = SHIFTER_OPERAND; |
| 4504 | } | 3973 | RD = dst = lop & rop; |
| 4505 | AND_INST: | 3974 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 4506 | { | 3975 | if (CurrentModeHasSPSR) { |
| 4507 | INC_ICOUNTER; | 3976 | cpu->Cpsr = cpu->Spsr_copy; |
| 4508 | and_inst *inst_cream = (and_inst *)inst_base->component; | 3977 | switch_mode(cpu, cpu->Cpsr & 0x1f); |
| 4509 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 3978 | LOAD_NZCVT; |
| 4510 | lop = RN; | 3979 | } |
| 4511 | rop = SHIFTER_OPERAND; | 3980 | } else if (inst_cream->S) { |
| 4512 | RD = dst = lop & rop; | 3981 | UPDATE_NFLAG(dst); |
| 4513 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 3982 | UPDATE_ZFLAG(dst); |
| 4514 | /* cpsr = spsr*/ | 3983 | UPDATE_CFLAG_WITH_SC; |
| 4515 | if (CurrentModeHasSPSR) { | 3984 | } |
| 4516 | cpu->Cpsr = cpu->Spsr_copy; | 3985 | if (inst_cream->Rd == 15) { |
| 4517 | switch_mode(cpu, cpu->Cpsr & 0x1f); | 3986 | INC_PC(sizeof(and_inst)); |
| 4518 | LOAD_NZCVT; | 3987 | goto DISPATCH; |
| 4519 | } | 3988 | } |
| 4520 | } else if (inst_cream->S) { | 3989 | } |
| 4521 | UPDATE_NFLAG(dst); | 3990 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4522 | UPDATE_ZFLAG(dst); | 3991 | INC_PC(sizeof(and_inst)); |
| 4523 | UPDATE_CFLAG_WITH_SC; | 3992 | FETCH_INST; |
| 4524 | //UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | 3993 | GOTO_NEXT_INST; |
| 4525 | } | 3994 | } |
| 4526 | if (inst_cream->Rd == 15) { | 3995 | BBL_INST: |
| 4527 | INC_PC(sizeof(and_inst)); | 3996 | { |
| 4528 | goto DISPATCH; | 3997 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4529 | } | 3998 | bbl_inst *inst_cream = (bbl_inst *)inst_base->component; |
| 4530 | } | 3999 | if (inst_cream->L) { |
| 4531 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4000 | LINK_RTN_ADDR; |
| 4532 | INC_PC(sizeof(and_inst)); | 4001 | } |
| 4533 | FETCH_INST; | 4002 | SET_PC; |
| 4534 | GOTO_NEXT_INST; | 4003 | INC_PC(sizeof(bbl_inst)); |
| 4535 | } | 4004 | goto DISPATCH; |
| 4536 | BBL_INST: | 4005 | } |
| 4537 | { | 4006 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4538 | INC_ICOUNTER; | 4007 | INC_PC(sizeof(bbl_inst)); |
| 4539 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4008 | goto DISPATCH; |
| 4540 | bbl_inst *inst_cream = (bbl_inst *)inst_base->component; | 4009 | } |
| 4541 | if (inst_cream->L) { | 4010 | BIC_INST: |
| 4542 | LINK_RTN_ADDR; | 4011 | { |
| 4543 | } | 4012 | bic_inst *inst_cream = (bic_inst *)inst_base->component; |
| 4544 | SET_PC; | 4013 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4545 | INC_PC(sizeof(bbl_inst)); | 4014 | lop = RN; |
| 4546 | goto DISPATCH; | 4015 | if (inst_cream->Rn == 15) { |
| 4547 | } | 4016 | lop += 2 * GET_INST_SIZE(cpu); |
| 4548 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4017 | } |
| 4549 | INC_PC(sizeof(bbl_inst)); | 4018 | rop = SHIFTER_OPERAND; |
| 4550 | goto DISPATCH; | 4019 | RD = dst = lop & (~rop); |
| 4551 | } | 4020 | if ((inst_cream->S) && (inst_cream->Rd == 15)) { |
| 4552 | BIC_INST: | 4021 | if (CurrentModeHasSPSR) { |
| 4553 | { | 4022 | cpu->Cpsr = cpu->Spsr_copy; |
| 4554 | INC_ICOUNTER; | 4023 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); |
| 4555 | bic_inst *inst_cream = (bic_inst *)inst_base->component; | 4024 | LOAD_NZCVT; |
| 4556 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4025 | } |
| 4557 | lop = RN; | 4026 | } else if (inst_cream->S) { |
| 4558 | if (inst_cream->Rn == 15) { | 4027 | UPDATE_NFLAG(dst); |
| 4559 | lop += 2 * GET_INST_SIZE(cpu); | 4028 | UPDATE_ZFLAG(dst); |
| 4560 | } | 4029 | UPDATE_CFLAG_WITH_SC; |
| 4561 | rop = SHIFTER_OPERAND; | 4030 | } |
| 4562 | // RD = dst = lop & (rop ^ 0xffffffff); | 4031 | if (inst_cream->Rd == 15) { |
| 4563 | RD = dst = lop & (~rop); | 4032 | INC_PC(sizeof(bic_inst)); |
| 4564 | if ((inst_cream->S) && (inst_cream->Rd == 15)) { | 4033 | goto DISPATCH; |
| 4565 | /* cpsr = spsr */ | 4034 | } |
| 4566 | if (CurrentModeHasSPSR) { | 4035 | } |
| 4567 | cpu->Cpsr = cpu->Spsr_copy; | 4036 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4568 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 4037 | INC_PC(sizeof(bic_inst)); |
| 4569 | LOAD_NZCVT; | 4038 | FETCH_INST; |
| 4570 | } | 4039 | GOTO_NEXT_INST; |
| 4571 | } else if (inst_cream->S) { | 4040 | } |
| 4572 | UPDATE_NFLAG(dst); | 4041 | BKPT_INST: |
| 4573 | UPDATE_ZFLAG(dst); | 4042 | BLX_INST: |
| 4574 | UPDATE_CFLAG_WITH_SC; | 4043 | { |
| 4575 | } | 4044 | blx_inst *inst_cream = (blx_inst *)inst_base->component; |
| 4576 | if (inst_cream->Rd == 15) { | 4045 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4577 | INC_PC(sizeof(bic_inst)); | 4046 | unsigned int inst = inst_cream->inst; |
| 4578 | goto DISPATCH; | 4047 | if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { |
| 4579 | } | 4048 | cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); |
| 4580 | } | 4049 | if(cpu->TFlag) |
| 4581 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4050 | cpu->Reg[14] |= 0x1; |
| 4582 | INC_PC(sizeof(bic_inst)); | 4051 | cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe; |
| 4583 | FETCH_INST; | 4052 | cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1; |
| 4584 | GOTO_NEXT_INST; | 4053 | } else { |
| 4585 | } | 4054 | cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); |
| 4586 | BKPT_INST: | 4055 | cpu->TFlag = 0x1; |
| 4587 | BLX_INST: | 4056 | int signed_int = inst_cream->val.signed_immed_24; |
| 4588 | { | 4057 | signed_int = (signed_int) & 0x800000 ? (0x3F000000 | signed_int) : signed_int; |
| 4589 | INC_ICOUNTER; | 4058 | signed_int = signed_int << 2; |
| 4590 | blx_inst *inst_cream = (blx_inst *)inst_base->component; | 4059 | cpu->Reg[15] = cpu->Reg[15] + 8 + signed_int + (BIT(inst, 24) << 1); |
| 4591 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4060 | } |
| 4592 | unsigned int inst = inst_cream->inst; | 4061 | INC_PC(sizeof(blx_inst)); |
| 4593 | if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { | 4062 | goto DISPATCH; |
| 4594 | //LINK_RTN_ADDR; | 4063 | } |
| 4595 | cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); | 4064 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4596 | if(cpu->TFlag) | 4065 | INC_PC(sizeof(blx_inst)); |
| 4597 | cpu->Reg[14] |= 0x1; | 4066 | goto DISPATCH; |
| 4598 | cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe; | 4067 | } |
| 4599 | cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1; | 4068 | BX_INST: |
| 4600 | //cpu->Reg[15] = cpu->Reg[BITS(inst, 0, 3)] & 0xfffffffe; | 4069 | { |
| 4601 | //cpu->TFlag = cpu->Reg[BITS(inst, 0, 3)] & 0x1; | 4070 | bx_inst *inst_cream = (bx_inst *)inst_base->component; |
| 4602 | } else { | 4071 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4603 | cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); | 4072 | if (inst_cream->Rm == 15) |
| 4604 | cpu->TFlag = 0x1; | 4073 | LOG_WARNING(Core_ARM11, "BX at pc %x: use of Rm = R15 is discouraged", cpu->Reg[15]); |
| 4605 | int signed_int = inst_cream->val.signed_immed_24; | 4074 | cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1; |
| 4606 | signed_int = (signed_int) & 0x800000 ? (0x3F000000 | signed_int) : signed_int; | 4075 | cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe; |
| 4607 | signed_int = signed_int << 2; | 4076 | INC_PC(sizeof(bx_inst)); |
| 4608 | // cpu->Reg[15] = cpu->Reg[15] + 2 * GET_INST_SIZE(cpu) | 4077 | goto DISPATCH; |
| 4609 | cpu->Reg[15] = cpu->Reg[15] + 8 | 4078 | } |
| 4610 | + signed_int + (BIT(inst, 24) << 1); | 4079 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4611 | //DEBUG_MSG; | 4080 | INC_PC(sizeof(bx_inst)); |
| 4612 | } | 4081 | goto DISPATCH; |
| 4613 | INC_PC(sizeof(blx_inst)); | 4082 | } |
| 4614 | goto DISPATCH; | 4083 | BXJ_INST: |
| 4615 | } | 4084 | CDP_INST: |
| 4616 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4085 | { |
| 4617 | // INC_PC(sizeof(bx_inst)); | 4086 | cdp_inst *inst_cream = (cdp_inst *)inst_base->component; |
| 4618 | INC_PC(sizeof(blx_inst)); | 4087 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4619 | goto DISPATCH; | 4088 | // Undefined instruction here |
| 4620 | } | 4089 | cpu->NumInstrsToExecute = 0; |
| 4621 | BX_INST: | 4090 | return num_instrs; |
| 4622 | { | 4091 | } |
| 4623 | INC_ICOUNTER; | 4092 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4624 | bx_inst *inst_cream = (bx_inst *)inst_base->component; | 4093 | INC_PC(sizeof(cdp_inst)); |
| 4625 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4094 | FETCH_INST; |
| 4626 | if (inst_cream->Rm == 15) | 4095 | GOTO_NEXT_INST; |
| 4627 | LOG_WARNING(Core_ARM11, "BX at pc %x: use of Rm = R15 is discouraged", cpu->Reg[15]); | 4096 | } |
| 4628 | cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1; | 4097 | |
| 4629 | cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe; | 4098 | CLREX_INST: |
| 4630 | // cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1; | 4099 | { |
| 4631 | INC_PC(sizeof(bx_inst)); | 4100 | remove_exclusive(cpu, 0); |
| 4632 | goto DISPATCH; | 4101 | cpu->exclusive_state = 0; |
| 4633 | } | 4102 | |
| 4634 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4103 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4635 | // INC_PC(sizeof(bx_inst)); | 4104 | INC_PC(sizeof(clrex_inst)); |
| 4636 | INC_PC(sizeof(bx_inst)); | 4105 | FETCH_INST; |
| 4637 | goto DISPATCH; | 4106 | GOTO_NEXT_INST; |
| 4638 | } | 4107 | } |
| 4639 | BXJ_INST: | 4108 | CLZ_INST: |
| 4640 | CDP_INST: | 4109 | { |
| 4641 | { | 4110 | clz_inst *inst_cream = (clz_inst *)inst_base->component; |
| 4642 | INC_ICOUNTER; | 4111 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4643 | cdp_inst *inst_cream = (cdp_inst *)inst_base->component; | 4112 | RD = clz(RM); |
| 4644 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4113 | } |
| 4645 | /* FIXME, check if cp access allowed */ | 4114 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4646 | #define CP_ACCESS_ALLOW 0 | 4115 | INC_PC(sizeof(clz_inst)); |
| 4647 | if(CP_ACCESS_ALLOW){ | 4116 | FETCH_INST; |
| 4648 | /* undefined instruction here */ | 4117 | GOTO_NEXT_INST; |
| 4649 | cpu->NumInstrsToExecute = 0; | 4118 | } |
| 4650 | return num_instrs; | 4119 | CMN_INST: |
| 4651 | } | 4120 | { |
| 4652 | LOG_ERROR(Core_ARM11, "CDP insn inst=0x%x, pc=0x%x\n", inst_cream->inst, cpu->Reg[15]); | 4121 | cmn_inst *inst_cream = (cmn_inst *)inst_base->component; |
| 4653 | unsigned cpab = (cpu->CDP[inst_cream->cp_num]) (cpu, ARMul_FIRST, inst_cream->inst); | 4122 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4654 | if(cpab != ARMul_DONE){ | 4123 | lop = RN; |
| 4655 | LOG_ERROR(Core_ARM11, "CDP insn wrong, inst=0x%x, cp_num=0x%x\n", inst_cream->inst, inst_cream->cp_num); | 4124 | rop = SHIFTER_OPERAND; |
| 4656 | //CITRA_IGNORE_EXIT(-1); | 4125 | dst = lop + rop; |
| 4657 | } | 4126 | UPDATE_NFLAG(dst); |
| 4658 | } | 4127 | UPDATE_ZFLAG(dst); |
| 4659 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4128 | UPDATE_CFLAG(dst, lop, rop); |
| 4660 | INC_PC(sizeof(cdp_inst)); | 4129 | UPDATE_VFLAG((int)dst, (int)lop, (int)rop); |
| 4661 | FETCH_INST; | 4130 | } |
| 4662 | GOTO_NEXT_INST; | 4131 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4663 | } | 4132 | INC_PC(sizeof(cmn_inst)); |
| 4664 | 4133 | FETCH_INST; | |
| 4665 | CLREX_INST: | 4134 | GOTO_NEXT_INST; |
| 4666 | { | 4135 | } |
| 4667 | INC_ICOUNTER; | 4136 | CMP_INST: |
| 4668 | remove_exclusive(cpu, 0); | 4137 | { |
| 4669 | cpu->exclusive_state = 0; | 4138 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4670 | 4139 | cmp_inst *inst_cream = (cmp_inst *)inst_base->component; | |
| 4671 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4140 | lop = RN; |
| 4672 | INC_PC(sizeof(clrex_inst)); | 4141 | if (inst_cream->Rn == 15) { |
| 4673 | FETCH_INST; | 4142 | lop += 2 * GET_INST_SIZE(cpu); |
| 4674 | GOTO_NEXT_INST; | 4143 | } |
| 4675 | } | 4144 | rop = SHIFTER_OPERAND; |
| 4676 | CLZ_INST: | 4145 | dst = lop - rop; |
| 4677 | { | 4146 | |
| 4678 | INC_ICOUNTER; | 4147 | UPDATE_NFLAG(dst); |
| 4679 | clz_inst *inst_cream = (clz_inst *)inst_base->component; | 4148 | UPDATE_ZFLAG(dst); |
| 4680 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4149 | UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); |
| 4681 | RD = clz(RM); | 4150 | UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); |
| 4682 | } | 4151 | } |
| 4683 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4152 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4684 | INC_PC(sizeof(clz_inst)); | 4153 | INC_PC(sizeof(cmp_inst)); |
| 4685 | FETCH_INST; | 4154 | FETCH_INST; |
| 4686 | GOTO_NEXT_INST; | 4155 | GOTO_NEXT_INST; |
| 4687 | } | 4156 | } |
| 4688 | CMN_INST: | 4157 | CPS_INST: |
| 4689 | { | 4158 | { |
| 4690 | INC_ICOUNTER; | 4159 | cps_inst *inst_cream = (cps_inst *)inst_base->component; |
| 4691 | cmn_inst *inst_cream = (cmn_inst *)inst_base->component; | 4160 | uint32_t aif_val = 0; |
| 4692 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4161 | uint32_t aif_mask = 0; |
| 4693 | // DEBUG_LOG(ARM11, "RN is %x\n", RN); | 4162 | if (InAPrivilegedMode(cpu)) { |
| 4694 | lop = RN; | 4163 | if (inst_cream->imod1) { |
| 4695 | rop = SHIFTER_OPERAND; | 4164 | if (inst_cream->A) { |
| 4696 | dst = lop + rop; | 4165 | aif_val |= (inst_cream->imod0 << 8); |
| 4697 | UPDATE_NFLAG(dst); | 4166 | aif_mask |= 1 << 8; |
| 4698 | UPDATE_ZFLAG(dst); | 4167 | } |
| 4699 | UPDATE_CFLAG(dst, lop, rop); | 4168 | if (inst_cream->I) { |
| 4700 | UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | 4169 | aif_val |= (inst_cream->imod0 << 7); |
| 4701 | } | 4170 | aif_mask |= 1 << 7; |
| 4702 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4171 | } |
| 4703 | INC_PC(sizeof(cmn_inst)); | 4172 | if (inst_cream->F) { |
| 4704 | FETCH_INST; | 4173 | aif_val |= (inst_cream->imod0 << 6); |
| 4705 | GOTO_NEXT_INST; | 4174 | aif_mask |= 1 << 6; |
| 4706 | } | 4175 | } |
| 4707 | CMP_INST: | 4176 | aif_mask = ~aif_mask; |
| 4708 | { | 4177 | cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val; |
| 4709 | // DEBUG_LOG(ARM11, "cmp inst\n"); | 4178 | } |
| 4710 | // DEBUG_LOG(ARM11, "pc: %x\n", cpu->Reg[15]); | 4179 | if (inst_cream->mmod) { |
| 4711 | INC_ICOUNTER; | 4180 | cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode; |
| 4712 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4181 | switch_mode(cpu, inst_cream->mode); |
| 4713 | // DEBUG_LOG(ARM11, "r0 is %x\n", cpu->Reg[0]); | 4182 | } |
| 4714 | cmp_inst *inst_cream = (cmp_inst *)inst_base->component; | 4183 | } |
| 4715 | lop = RN; | 4184 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4716 | if (inst_cream->Rn == 15) { | 4185 | INC_PC(sizeof(cps_inst)); |
| 4717 | lop += 2 * GET_INST_SIZE(cpu); | 4186 | FETCH_INST; |
| 4718 | } | 4187 | GOTO_NEXT_INST; |
| 4719 | rop = SHIFTER_OPERAND; | 4188 | } |
| 4720 | dst = lop - rop; | 4189 | CPY_INST: |
| 4721 | 4190 | { | |
| 4722 | UPDATE_NFLAG(dst); | 4191 | mov_inst *inst_cream = (mov_inst *)inst_base->component; |
| 4723 | UPDATE_ZFLAG(dst); | 4192 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4724 | // UPDATE_CFLAG(dst, lop, rop); | 4193 | RD = SHIFTER_OPERAND; |
| 4725 | UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); | 4194 | if ((inst_cream->Rd == 15)) { |
| 4726 | // UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | 4195 | INC_PC(sizeof(mov_inst)); |
| 4727 | UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); | 4196 | goto DISPATCH; |
| 4728 | // UPDATE_VFLAG_WITH_NOT(dst, lop, rop); | 4197 | } |
| 4729 | } | 4198 | } |
| 4730 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4199 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4731 | INC_PC(sizeof(cmp_inst)); | 4200 | INC_PC(sizeof(mov_inst)); |
| 4732 | FETCH_INST; | 4201 | FETCH_INST; |
| 4733 | GOTO_NEXT_INST; | 4202 | GOTO_NEXT_INST; |
| 4734 | } | 4203 | } |
| 4735 | CPS_INST: | 4204 | EOR_INST: |
| 4736 | { | 4205 | { |
| 4737 | INC_ICOUNTER; | 4206 | eor_inst *inst_cream = (eor_inst *)inst_base->component; |
| 4738 | cps_inst *inst_cream = (cps_inst *)inst_base->component; | 4207 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4739 | uint32_t aif_val = 0; | 4208 | lop = RN; |
| 4740 | uint32_t aif_mask = 0; | 4209 | if (inst_cream->Rn == 15) { |
| 4741 | if (InAPrivilegedMode(cpu)) { | 4210 | lop += 2 * GET_INST_SIZE(cpu); |
| 4742 | /* isInAPrivilegedMode */ | 4211 | } |
| 4743 | if (inst_cream->imod1) { | 4212 | rop = SHIFTER_OPERAND; |
| 4744 | if (inst_cream->A) { | 4213 | RD = dst = lop ^ rop; |
| 4745 | aif_val |= (inst_cream->imod0 << 8); | 4214 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 4746 | aif_mask |= 1 << 8; | 4215 | if (CurrentModeHasSPSR) { |
| 4747 | } | 4216 | cpu->Cpsr = cpu->Spsr_copy; |
| 4748 | if (inst_cream->I) { | 4217 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); |
| 4749 | aif_val |= (inst_cream->imod0 << 7); | 4218 | LOAD_NZCVT; |
| 4750 | aif_mask |= 1 << 7; | 4219 | } |
| 4751 | } | 4220 | } else if (inst_cream->S) { |
| 4752 | if (inst_cream->F) { | 4221 | UPDATE_NFLAG(dst); |
| 4753 | aif_val |= (inst_cream->imod0 << 6); | 4222 | UPDATE_ZFLAG(dst); |
| 4754 | aif_mask |= 1 << 6; | 4223 | UPDATE_CFLAG_WITH_SC; |
| 4755 | } | 4224 | } |
| 4756 | aif_mask = ~aif_mask; | 4225 | if (inst_cream->Rd == 15) { |
| 4757 | cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val; | 4226 | INC_PC(sizeof(eor_inst)); |
| 4758 | } | 4227 | goto DISPATCH; |
| 4759 | if (inst_cream->mmod) { | 4228 | } |
| 4760 | cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode; | 4229 | } |
| 4761 | switch_mode(cpu, inst_cream->mode); | 4230 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4762 | } | 4231 | INC_PC(sizeof(eor_inst)); |
| 4763 | } | 4232 | FETCH_INST; |
| 4764 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4233 | GOTO_NEXT_INST; |
| 4765 | INC_PC(sizeof(cps_inst)); | 4234 | } |
| 4766 | FETCH_INST; | 4235 | LDC_INST: |
| 4767 | GOTO_NEXT_INST; | 4236 | { |
| 4768 | } | 4237 | // Instruction not implemented |
| 4769 | CPY_INST: | 4238 | //LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); |
| 4770 | { | 4239 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4771 | INC_ICOUNTER; | 4240 | INC_PC(sizeof(ldc_inst)); |
| 4772 | mov_inst *inst_cream = (mov_inst *)inst_base->component; | 4241 | FETCH_INST; |
| 4773 | // cpy_inst *inst_cream = (cpy_inst *)inst_base->component; | 4242 | GOTO_NEXT_INST; |
| 4774 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4243 | } |
| 4775 | RD = SHIFTER_OPERAND; | 4244 | LDM_INST: |
| 4776 | // RD = RM; | 4245 | { |
| 4777 | if ((inst_cream->Rd == 15)) { | 4246 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4778 | INC_PC(sizeof(mov_inst)); | 4247 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4779 | goto DISPATCH; | 4248 | int i; |
| 4780 | } | 4249 | unsigned int ret; |
| 4781 | } | 4250 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); |
| 4782 | // DEBUG_LOG(ARM11, "cpy inst %x\n", cpu->Reg[15]); | 4251 | if (fault) { |
| 4783 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4252 | goto MMU_EXCEPTION; |
| 4784 | INC_PC(sizeof(mov_inst)); | 4253 | } |
| 4785 | FETCH_INST; | 4254 | unsigned int inst = inst_cream->inst; |
| 4786 | GOTO_NEXT_INST; | 4255 | if (BIT(inst, 22) && !BIT(inst, 15)) { |
| 4787 | } | 4256 | for (i = 0; i < 13; i++) { |
| 4788 | EOR_INST: | 4257 | if(BIT(inst, i)){ |
| 4789 | { | 4258 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); |
| 4790 | INC_ICOUNTER; | 4259 | cpu->Reg[i] = ret; |
| 4791 | eor_inst *inst_cream = (eor_inst *)inst_base->component; | 4260 | addr += 4; |
| 4792 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4261 | if ((addr & 0xfff) == 0) { |
| 4793 | lop = RN; | 4262 | fault = check_address_validity(cpu, addr, &phys_addr, 1); |
| 4794 | if (inst_cream->Rn == 15) { | 4263 | } else { |
| 4795 | lop += 2 * GET_INST_SIZE(cpu); | 4264 | phys_addr += 4; |
| 4796 | } | 4265 | } |
| 4797 | rop = SHIFTER_OPERAND; | 4266 | } |
| 4798 | RD = dst = lop ^ rop; | 4267 | } |
| 4799 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 4268 | if (BIT(inst, 13)) { |
| 4800 | /* cpsr = spsr*/ | 4269 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); |
| 4801 | if (CurrentModeHasSPSR) { | 4270 | |
| 4802 | cpu->Cpsr = cpu->Spsr_copy; | 4271 | if (cpu->Mode == USER32MODE) |
| 4803 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 4272 | cpu->Reg[13] = ret; |
| 4804 | LOAD_NZCVT; | 4273 | else |
| 4805 | } | 4274 | cpu->Reg_usr[0] = ret; |
| 4806 | } else if (inst_cream->S) { | 4275 | addr += 4; |
| 4807 | UPDATE_NFLAG(dst); | 4276 | if ((addr & 0xfff) == 0) { |
| 4808 | UPDATE_ZFLAG(dst); | 4277 | fault = check_address_validity(cpu, addr, &phys_addr, 1); |
| 4809 | UPDATE_CFLAG_WITH_SC; | 4278 | } else { |
| 4810 | // UPDATE_CFLAG(dst, lop, rop); | 4279 | phys_addr += 4; |
| 4811 | // UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | 4280 | } |
| 4812 | } | 4281 | } |
| 4813 | if (inst_cream->Rd == 15) { | 4282 | if (BIT(inst, 14)) { |
| 4814 | INC_PC(sizeof(eor_inst)); | 4283 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); |
| 4815 | goto DISPATCH; | 4284 | |
| 4816 | } | 4285 | if (cpu->Mode == USER32MODE) |
| 4817 | } | 4286 | cpu->Reg[14] = ret; |
| 4818 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4287 | else |
| 4819 | INC_PC(sizeof(eor_inst)); | 4288 | cpu->Reg_usr[1] = ret; |
| 4820 | FETCH_INST; | 4289 | } |
| 4821 | GOTO_NEXT_INST; | 4290 | } else if (!BIT(inst, 22)) { |
| 4822 | } | 4291 | for( i = 0; i < 16; i ++ ){ |
| 4823 | LDC_INST: | 4292 | if(BIT(inst, i)){ |
| 4824 | { | 4293 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); |
| 4825 | INC_ICOUNTER; | 4294 | if (fault) goto MMU_EXCEPTION; |
| 4826 | /* NOT IMPL */ | 4295 | |
| 4827 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4296 | // For armv5t, should enter thumb when bits[0] is non-zero. |
| 4828 | INC_PC(sizeof(ldc_inst)); | 4297 | if(i == 15){ |
| 4829 | FETCH_INST; | 4298 | cpu->TFlag = ret & 0x1; |
| 4830 | GOTO_NEXT_INST; | 4299 | ret &= 0xFFFFFFFE; |
| 4831 | } | 4300 | } |
| 4832 | LDM_INST: | 4301 | |
| 4833 | { | 4302 | cpu->Reg[i] = ret; |
| 4834 | INC_ICOUNTER; | 4303 | addr += 4; |
| 4835 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4304 | if ((addr & 0xfff) == 0) { |
| 4836 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4305 | fault = check_address_validity(cpu, addr, &phys_addr, 1); |
| 4837 | int i; | 4306 | } else { |
| 4838 | unsigned int ret; | 4307 | phys_addr += 4; |
| 4839 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4308 | } |
| 4840 | if (fault) { | 4309 | } |
| 4841 | goto MMU_EXCEPTION; | 4310 | } |
| 4842 | } | 4311 | } else if (BIT(inst, 22) && BIT(inst, 15)) { |
| 4843 | unsigned int inst = inst_cream->inst; | 4312 | for( i = 0; i < 15; i ++ ){ |
| 4844 | if (BIT(inst, 22) && !BIT(inst, 15)) { | 4313 | if(BIT(inst, i)){ |
| 4845 | // DEBUG_MSG; | 4314 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); |
| 4846 | #if 1 | 4315 | cpu->Reg[i] = ret; |
| 4847 | /* LDM (2) user */ | 4316 | addr += 4; |
| 4848 | for (i = 0; i < 13; i++) { | 4317 | if ((addr & 0xfff) == 0) { |
| 4849 | if(BIT(inst, i)){ | 4318 | fault = check_address_validity(cpu, addr, &phys_addr, 1); |
| 4850 | #if 0 | 4319 | } else { |
| 4851 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 4320 | phys_addr += 4; |
| 4852 | if (fault) { | 4321 | } |
| 4853 | goto MMU_EXCEPTION; | 4322 | } |
| 4854 | } | 4323 | } |
| 4855 | #endif | 4324 | |
| 4856 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | 4325 | if (CurrentModeHasSPSR) { |
| 4857 | //if (fault) goto MMU_EXCEPTION; | 4326 | cpu->Cpsr = cpu->Spsr_copy; |
| 4858 | cpu->Reg[i] = ret; | 4327 | switch_mode(cpu, cpu->Cpsr & 0x1f); |
| 4859 | addr += 4; | 4328 | LOAD_NZCVT; |
| 4860 | if ((addr & 0xfff) == 0) { | 4329 | } |
| 4861 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 4330 | |
| 4862 | } else { | 4331 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); |
| 4863 | phys_addr += 4; | 4332 | if (fault) { |
| 4864 | } | 4333 | goto MMU_EXCEPTION; |
| 4865 | } | 4334 | } |
| 4866 | } | 4335 | cpu->Reg[15] = ret; |
| 4867 | if (BIT(inst, 13)) { | 4336 | } |
| 4868 | #if 0 | 4337 | if (BIT(inst, 15)) { |
| 4869 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 4338 | INC_PC(sizeof(ldst_inst)); |
| 4870 | if (fault) { | 4339 | goto DISPATCH; |
| 4871 | goto MMU_EXCEPTION; | 4340 | } |
| 4872 | } | 4341 | } |
| 4873 | #endif | 4342 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4874 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | 4343 | INC_PC(sizeof(ldst_inst)); |
| 4875 | //if (fault) goto MMU_EXCEPTION; | 4344 | FETCH_INST; |
| 4876 | if (cpu->Mode == USER32MODE) | 4345 | GOTO_NEXT_INST; |
| 4877 | cpu->Reg[13] = ret; | 4346 | } |
| 4878 | else | 4347 | SXTH_INST: |
| 4879 | cpu->Reg_usr[0] = ret; | 4348 | { |
| 4880 | addr += 4; | 4349 | sxth_inst *inst_cream = (sxth_inst *)inst_base->component; |
| 4881 | if ((addr & 0xfff) == 0) { | 4350 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4882 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 4351 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); |
| 4883 | } else { | 4352 | if (BIT(operand2, 15)) { |
| 4884 | phys_addr += 4; | 4353 | operand2 |= 0xffff0000; |
| 4885 | } | 4354 | } else { |
| 4886 | } | 4355 | operand2 &= 0xffff; |
| 4887 | if (BIT(inst, 14)) { | 4356 | } |
| 4888 | #if 0 | 4357 | RD = operand2; |
| 4889 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 4358 | } |
| 4890 | if (fault) { | 4359 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4891 | goto MMU_EXCEPTION; | 4360 | INC_PC(sizeof(sxth_inst)); |
| 4892 | } | 4361 | FETCH_INST; |
| 4893 | #endif | 4362 | GOTO_NEXT_INST; |
| 4894 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | 4363 | } |
| 4895 | //if (fault) goto MMU_EXCEPTION; | 4364 | LDR_INST: |
| 4896 | if (cpu->Mode == USER32MODE) | 4365 | { |
| 4897 | cpu->Reg[14] = ret; | 4366 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4898 | else | 4367 | //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4899 | cpu->Reg_usr[1] = ret; | 4368 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); |
| 4900 | } | 4369 | if (fault) goto MMU_EXCEPTION; |
| 4901 | #endif | 4370 | unsigned int value; |
| 4902 | } else if (!BIT(inst, 22)) { | 4371 | fault = interpreter_read_memory(addr, phys_addr, value, 32); |
| 4903 | for( i = 0; i < 16; i ++ ){ | 4372 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) |
| 4904 | if(BIT(inst, i)){ | 4373 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4905 | //bus_read(32, addr, &ret); | 4374 | else { |
| 4906 | #if 0 | 4375 | value = ROTATE_RIGHT_32(value,(8*(addr&0x3))); |
| 4907 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 4376 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4908 | if (fault) { | 4377 | } |
| 4909 | goto MMU_EXCEPTION; | 4378 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 4910 | } | 4379 | // For armv5t, should enter thumb when bits[0] is non-zero. |
| 4911 | #endif | 4380 | cpu->TFlag = value & 0x1; |
| 4912 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | 4381 | cpu->Reg[15] &= 0xFFFFFFFE; |
| 4913 | if (fault) goto MMU_EXCEPTION; | 4382 | INC_PC(sizeof(ldst_inst)); |
| 4914 | /* For armv5t, should enter thumb when bits[0] is non-zero. */ | 4383 | goto DISPATCH; |
| 4915 | if(i == 15){ | 4384 | } |
| 4916 | cpu->TFlag = ret & 0x1; | 4385 | //} |
| 4917 | ret &= 0xFFFFFFFE; | 4386 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4918 | //DEBUG_LOG(ARM11, "In %s, TFlag ret=0x%x\n", __FUNCTION__, ret); | 4387 | INC_PC(sizeof(ldst_inst)); |
| 4919 | } | 4388 | FETCH_INST; |
| 4920 | 4389 | GOTO_NEXT_INST; | |
| 4921 | cpu->Reg[i] = ret; | 4390 | } |
| 4922 | addr += 4; | 4391 | LDRCOND_INST: |
| 4923 | if ((addr & 0xfff) == 0) { | 4392 | { |
| 4924 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 4393 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4925 | } else { | 4394 | if (CondPassed(cpu, inst_base->cond)) { |
| 4926 | phys_addr += 4; | 4395 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); |
| 4927 | } | 4396 | if (fault) goto MMU_EXCEPTION; |
| 4928 | } | 4397 | unsigned int value; |
| 4929 | } | 4398 | fault = interpreter_read_memory(addr, phys_addr, value, 32); |
| 4930 | } else if (BIT(inst, 22) && BIT(inst, 15)) { | 4399 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) |
| 4931 | for( i = 0; i < 15; i ++ ){ | 4400 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4932 | if(BIT(inst, i)){ | 4401 | else { |
| 4933 | #if 0 | 4402 | value = ROTATE_RIGHT_32(value,(8*(addr&0x3))); |
| 4934 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 4403 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4935 | if (fault) { | 4404 | } |
| 4936 | goto MMU_EXCEPTION; | 4405 | |
| 4937 | } | 4406 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 4938 | #endif | 4407 | // For armv5t, should enter thumb when bits[0] is non-zero. |
| 4939 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | 4408 | cpu->TFlag = value & 0x1; |
| 4940 | //if (fault) goto MMU_EXCEPTION; | 4409 | cpu->Reg[15] &= 0xFFFFFFFE; |
| 4941 | cpu->Reg[i] = ret; | 4410 | INC_PC(sizeof(ldst_inst)); |
| 4942 | addr += 4; | 4411 | goto DISPATCH; |
| 4943 | if ((addr & 0xfff) == 0) { | 4412 | } |
| 4944 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 4413 | } |
| 4945 | } else { | 4414 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4946 | phys_addr += 4; | 4415 | INC_PC(sizeof(ldst_inst)); |
| 4947 | } | 4416 | FETCH_INST; |
| 4948 | } | 4417 | GOTO_NEXT_INST; |
| 4949 | } | 4418 | } |
| 4950 | 4419 | UXTH_INST: | |
| 4951 | if (CurrentModeHasSPSR) { | 4420 | { |
| 4952 | cpu->Cpsr = cpu->Spsr_copy; | 4421 | uxth_inst *inst_cream = (uxth_inst *)inst_base->component; |
| 4953 | switch_mode(cpu, cpu->Cpsr & 0x1f); | 4422 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4954 | LOAD_NZCVT; | 4423 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) |
| 4955 | } | 4424 | & 0xffff; |
| 4956 | #if 0 | 4425 | RD = operand2; |
| 4957 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 4426 | } |
| 4958 | if (fault) { | 4427 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4959 | goto MMU_EXCEPTION; | 4428 | INC_PC(sizeof(uxth_inst)); |
| 4960 | } | 4429 | FETCH_INST; |
| 4961 | #endif | 4430 | GOTO_NEXT_INST; |
| 4962 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | 4431 | } |
| 4963 | if (fault) { | 4432 | UXTAH_INST: |
| 4964 | goto MMU_EXCEPTION; | 4433 | { |
| 4965 | } | 4434 | uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component; |
| 4966 | cpu->Reg[15] = ret; | 4435 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4967 | #if 0 | 4436 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) |
| 4968 | addr += 4; | 4437 | & 0xffff; |
| 4969 | phys_addr += 4; | 4438 | RD = RN + operand2; |
| 4970 | #endif | 4439 | if (inst_cream->Rn == 15 || inst_cream->Rm == 15) { |
| 4971 | } | 4440 | LOG_ERROR(Core_ARM11, "invalid operands for UXTAH"); |
| 4972 | if (BIT(inst, 15)) { | 4441 | CITRA_IGNORE_EXIT(-1); |
| 4973 | INC_PC(sizeof(ldst_inst)); | 4442 | } |
| 4974 | goto DISPATCH; | 4443 | } |
| 4975 | } | 4444 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4976 | } | 4445 | INC_PC(sizeof(uxtah_inst)); |
| 4977 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4446 | FETCH_INST; |
| 4978 | INC_PC(sizeof(ldst_inst)); | 4447 | GOTO_NEXT_INST; |
| 4979 | FETCH_INST; | 4448 | } |
| 4980 | GOTO_NEXT_INST; | 4449 | LDRB_INST: |
| 4981 | } | 4450 | { |
| 4982 | SXTH_INST: | 4451 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4983 | { | 4452 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4984 | INC_ICOUNTER; | 4453 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); |
| 4985 | sxth_inst *inst_cream = (sxth_inst *)inst_base->component; | 4454 | if (fault) goto MMU_EXCEPTION; |
| 4986 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4455 | unsigned int value; |
| 4987 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); | 4456 | fault = interpreter_read_memory(addr, phys_addr, value, 8); |
| 4988 | if (BIT(operand2, 15)) { | 4457 | if (fault) goto MMU_EXCEPTION; |
| 4989 | operand2 |= 0xffff0000; | 4458 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4990 | } else { | 4459 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 4991 | operand2 &= 0xffff; | 4460 | INC_PC(sizeof(ldst_inst)); |
| 4992 | } | 4461 | goto DISPATCH; |
| 4993 | RD = operand2; | 4462 | } |
| 4994 | } | 4463 | } |
| 4995 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4464 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4996 | INC_PC(sizeof(sxth_inst)); | 4465 | INC_PC(sizeof(ldst_inst)); |
| 4997 | FETCH_INST; | 4466 | FETCH_INST; |
| 4998 | GOTO_NEXT_INST; | 4467 | GOTO_NEXT_INST; |
| 4999 | } | 4468 | } |
| 5000 | LDR_INST: | 4469 | LDRBT_INST: |
| 5001 | { | 4470 | { |
| 5002 | INC_ICOUNTER; | 4471 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5003 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4472 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5004 | //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4473 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); |
| 5005 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4474 | if (fault) goto MMU_EXCEPTION; |
| 5006 | if (fault) goto MMU_EXCEPTION; | 4475 | unsigned int value; |
| 5007 | unsigned int value; | 4476 | fault = interpreter_read_memory(addr, phys_addr, value, 8); |
| 5008 | //bus_read(32, addr, &value); | 4477 | if (fault) goto MMU_EXCEPTION; |
| 5009 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | 4478 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 5010 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) | 4479 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 5011 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4480 | INC_PC(sizeof(ldst_inst)); |
| 5012 | else { | 4481 | goto DISPATCH; |
| 5013 | value = ROTATE_RIGHT_32(value,(8*(addr&0x3))); | 4482 | } |
| 5014 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4483 | } |
| 5015 | } | 4484 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5016 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4485 | INC_PC(sizeof(ldst_inst)); |
| 5017 | /* For armv5t, should enter thumb when bits[0] is non-zero. */ | 4486 | FETCH_INST; |
| 5018 | cpu->TFlag = value & 0x1; | 4487 | GOTO_NEXT_INST; |
| 5019 | cpu->Reg[15] &= 0xFFFFFFFE; | 4488 | } |
| 5020 | INC_PC(sizeof(ldst_inst)); | 4489 | LDRD_INST: |
| 5021 | goto DISPATCH; | 4490 | { |
| 5022 | } | 4491 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5023 | //} | 4492 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5024 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4493 | // Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0) |
| 5025 | INC_PC(sizeof(ldst_inst)); | 4494 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); |
| 5026 | FETCH_INST; | 4495 | if (fault) goto MMU_EXCEPTION; |
| 5027 | GOTO_NEXT_INST; | 4496 | uint32_t rear_phys_addr; |
| 5028 | } | 4497 | fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 1); |
| 5029 | LDRCOND_INST: | 4498 | if(fault){ |
| 5030 | { | 4499 | LOG_ERROR(Core_ARM11, "MMU fault , should rollback the above get_addr\n"); |
| 5031 | INC_ICOUNTER; | 4500 | CITRA_IGNORE_EXIT(-1); |
| 5032 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4501 | goto MMU_EXCEPTION; |
| 5033 | if (CondPassed(cpu, inst_base->cond)) { | 4502 | } |
| 5034 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4503 | unsigned int value; |
| 5035 | if (fault) goto MMU_EXCEPTION; | 4504 | fault = interpreter_read_memory(addr, phys_addr, value, 32); |
| 5036 | unsigned int value; | 4505 | if (fault) goto MMU_EXCEPTION; |
| 5037 | //bus_read(32, addr, &value); | 4506 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 5038 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | 4507 | fault = interpreter_read_memory(addr + 4, rear_phys_addr, value, 32); |
| 5039 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) | 4508 | if (fault) goto MMU_EXCEPTION; |
| 5040 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4509 | cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = value; |
| 5041 | else { | 4510 | |
| 5042 | value = ROTATE_RIGHT_32(value,(8*(addr&0x3))); | 4511 | // No dispatch since this operation should not modify R15 |
| 5043 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4512 | } |
| 4513 | cpu->Reg[15] += 4; | ||
| 4514 | INC_PC(sizeof(ldst_inst)); | ||
| 4515 | FETCH_INST; | ||
| 4516 | GOTO_NEXT_INST; | ||
| 4517 | } | ||
| 4518 | |||
| 4519 | LDREX_INST: | ||
| 4520 | { | ||
| 4521 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 4522 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4523 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | ||
| 4524 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4525 | if (fault) goto MMU_EXCEPTION; | ||
| 4526 | unsigned int value; | ||
| 4527 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | ||
| 4528 | if (fault) goto MMU_EXCEPTION; | ||
| 4529 | |||
| 4530 | add_exclusive_addr(cpu, phys_addr); | ||
| 4531 | cpu->exclusive_state = 1; | ||
| 4532 | |||
| 4533 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 4534 | if (BITS(inst_cream->inst, 12, 15) == 15) { | ||
| 4535 | INC_PC(sizeof(ldst_inst)); | ||
| 4536 | goto DISPATCH; | ||
| 4537 | } | ||
| 4538 | } | ||
| 4539 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4540 | INC_PC(sizeof(ldst_inst)); | ||
| 4541 | FETCH_INST; | ||
| 4542 | GOTO_NEXT_INST; | ||
| 4543 | } | ||
| 4544 | LDREXB_INST: | ||
| 4545 | { | ||
| 4546 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 4547 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4548 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | ||
| 4549 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4550 | if (fault) goto MMU_EXCEPTION; | ||
| 4551 | unsigned int value; | ||
| 4552 | fault = interpreter_read_memory(addr, phys_addr, value, 8); | ||
| 4553 | if (fault) goto MMU_EXCEPTION; | ||
| 4554 | |||
| 4555 | add_exclusive_addr(cpu, phys_addr); | ||
| 4556 | cpu->exclusive_state = 1; | ||
| 4557 | |||
| 4558 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 4559 | if (BITS(inst_cream->inst, 12, 15) == 15) { | ||
| 4560 | INC_PC(sizeof(ldst_inst)); | ||
| 4561 | goto DISPATCH; | ||
| 4562 | } | ||
| 4563 | } | ||
| 4564 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4565 | INC_PC(sizeof(ldst_inst)); | ||
| 4566 | FETCH_INST; | ||
| 4567 | GOTO_NEXT_INST; | ||
| 4568 | } | ||
| 4569 | LDRH_INST: | ||
| 4570 | { | ||
| 4571 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 4572 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4573 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | ||
| 4574 | if (fault) goto MMU_EXCEPTION; | ||
| 4575 | unsigned int value = 0; | ||
| 4576 | fault = interpreter_read_memory(addr, phys_addr, value, 16); | ||
| 4577 | if (fault) goto MMU_EXCEPTION; | ||
| 4578 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 4579 | if (BITS(inst_cream->inst, 12, 15) == 15) { | ||
| 4580 | INC_PC(sizeof(ldst_inst)); | ||
| 4581 | goto DISPATCH; | ||
| 4582 | } | ||
| 4583 | } | ||
| 4584 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4585 | INC_PC(sizeof(ldst_inst)); | ||
| 4586 | FETCH_INST; | ||
| 4587 | GOTO_NEXT_INST; | ||
| 4588 | } | ||
| 4589 | LDRSB_INST: | ||
| 4590 | { | ||
| 4591 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 4592 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4593 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | ||
| 4594 | if (fault) goto MMU_EXCEPTION; | ||
| 4595 | unsigned int value; | ||
| 4596 | fault = interpreter_read_memory(addr, phys_addr, value, 8); | ||
| 4597 | if (fault) goto MMU_EXCEPTION; | ||
| 4598 | if (BIT(value, 7)) { | ||
| 4599 | value |= 0xffffff00; | ||
| 4600 | } | ||
| 4601 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 4602 | if (BITS(inst_cream->inst, 12, 15) == 15) { | ||
| 4603 | INC_PC(sizeof(ldst_inst)); | ||
| 4604 | goto DISPATCH; | ||
| 4605 | } | ||
| 4606 | } | ||
| 4607 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4608 | INC_PC(sizeof(ldst_inst)); | ||
| 4609 | FETCH_INST; | ||
| 4610 | GOTO_NEXT_INST; | ||
| 4611 | } | ||
| 4612 | LDRSH_INST: | ||
| 4613 | { | ||
| 4614 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 4615 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4616 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | ||
| 4617 | if (fault) goto MMU_EXCEPTION; | ||
| 4618 | unsigned int value; | ||
| 4619 | fault = interpreter_read_memory(addr, phys_addr, value, 16); | ||
| 4620 | if (fault) goto MMU_EXCEPTION; | ||
| 4621 | if (BIT(value, 15)) { | ||
| 4622 | value |= 0xffff0000; | ||
| 4623 | } | ||
| 4624 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 4625 | if (BITS(inst_cream->inst, 12, 15) == 15) { | ||
| 4626 | INC_PC(sizeof(ldst_inst)); | ||
| 4627 | goto DISPATCH; | ||
| 4628 | } | ||
| 4629 | } | ||
| 4630 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4631 | INC_PC(sizeof(ldst_inst)); | ||
| 4632 | FETCH_INST; | ||
| 4633 | GOTO_NEXT_INST; | ||
| 4634 | } | ||
| 4635 | LDRT_INST: | ||
| 4636 | { | ||
| 4637 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 4638 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4639 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | ||
| 4640 | if (fault) goto MMU_EXCEPTION; | ||
| 4641 | unsigned int value; | ||
| 4642 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | ||
| 4643 | if (fault) goto MMU_EXCEPTION; | ||
| 4644 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 4645 | |||
| 4646 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) | ||
| 4647 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 4648 | else | ||
| 4649 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ROTATE_RIGHT_32(value,(8*(addr&0x3))) ; | ||
| 4650 | |||
| 4651 | if (BITS(inst_cream->inst, 12, 15) == 15) { | ||
| 4652 | INC_PC(sizeof(ldst_inst)); | ||
| 4653 | goto DISPATCH; | ||
| 4654 | } | ||
| 4655 | } | ||
| 4656 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4657 | INC_PC(sizeof(ldst_inst)); | ||
| 4658 | FETCH_INST; | ||
| 4659 | GOTO_NEXT_INST; | ||
| 4660 | } | ||
| 4661 | MCR_INST: | ||
| 4662 | { | ||
| 4663 | mcr_inst *inst_cream = (mcr_inst *)inst_base->component; | ||
| 4664 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4665 | unsigned int inst = inst_cream->inst; | ||
| 4666 | if (inst_cream->Rd == 15) { | ||
| 4667 | DEBUG_MSG; | ||
| 4668 | } else { | ||
| 4669 | if (inst_cream->cp_num == 15) { | ||
| 4670 | if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) { | ||
| 4671 | CP15_REG(CP15_MAIN_ID) = RD; | ||
| 4672 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) { | ||
| 4673 | CP15_REG(CP15_AUXILIARY_CONTROL) = RD; | ||
| 4674 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) { | ||
| 4675 | CP15_REG(CP15_COPROCESSOR_ACCESS_CONTROL) = RD; | ||
| 4676 | } else if(CRn == 1 && CRm == 0 && OPCODE_2 == 0) { | ||
| 4677 | CP15_REG(CP15_CONTROL) = RD; | ||
| 4678 | } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) { | ||
| 4679 | CP15_REG(CP15_DOMAIN_ACCESS_CONTROL) = RD; | ||
| 4680 | } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) { | ||
| 4681 | CP15_REG(CP15_TRANSLATION_BASE_TABLE_0) = RD; | ||
| 4682 | } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 1) { | ||
| 4683 | CP15_REG(CP15_TRANSLATION_BASE_TABLE_1) = RD; | ||
| 4684 | } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 2) { | ||
| 4685 | CP15_REG(CP15_TRANSLATION_BASE_CONTROL) = RD; | ||
| 4686 | } else if(CRn == MMU_CACHE_OPS){ | ||
| 4687 | //LOG_WARNING(Core_ARM11, "cache operations have not implemented."); | ||
| 4688 | } else if(CRn == MMU_TLB_OPS){ | ||
| 4689 | switch (CRm) { | ||
| 4690 | case 5: // ITLB | ||
| 4691 | switch(OPCODE_2) { | ||
| 4692 | case 0: // Invalidate all | ||
| 4693 | LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate all"); | ||
| 4694 | break; | ||
| 4695 | case 1: // Invalidate by MVA | ||
| 4696 | LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate by mva"); | ||
| 4697 | break; | ||
| 4698 | case 2: // Invalidate by asid | ||
| 4699 | LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate by asid"); | ||
| 4700 | break; | ||
| 4701 | default: | ||
| 4702 | break; | ||
| 4703 | } | ||
| 4704 | |||
| 4705 | break; | ||
| 4706 | case 6: // DTLB | ||
| 4707 | switch(OPCODE_2){ | ||
| 4708 | case 0: // Invalidate all | ||
| 4709 | LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate all"); | ||
| 4710 | break; | ||
| 4711 | case 1: // Invalidate by MVA | ||
| 4712 | LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate by mva"); | ||
| 4713 | break; | ||
| 4714 | case 2: // Invalidate by asid | ||
| 4715 | LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate by asid"); | ||
| 4716 | break; | ||
| 4717 | default: | ||
| 4718 | break; | ||
| 4719 | } | ||
| 4720 | break; | ||
| 4721 | case 7: // UNIFILED TLB | ||
| 4722 | switch(OPCODE_2){ | ||
| 4723 | case 0: // invalidate all | ||
| 4724 | LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate all"); | ||
| 4725 | break; | ||
| 4726 | case 1: // Invalidate by MVA | ||
| 4727 | LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate by mva"); | ||
| 4728 | break; | ||
| 4729 | case 2: // Invalidate by asid | ||
| 4730 | LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate by asid"); | ||
| 4731 | break; | ||
| 4732 | default: | ||
| 4733 | break; | ||
| 4734 | } | ||
| 4735 | break; | ||
| 4736 | default: | ||
| 4737 | break; | ||
| 4738 | } | ||
| 4739 | } else if(CRn == MMU_PID) { | ||
| 4740 | if(OPCODE_2 == 0) | ||
| 4741 | CP15_REG(CP15_PID) = RD; | ||
| 4742 | else if(OPCODE_2 == 1) | ||
| 4743 | CP15_REG(CP15_CONTEXT_ID) = RD; | ||
| 4744 | else if(OPCODE_2 == 3) { | ||
| 4745 | CP15_REG(CP15_THREAD_URO) = RD; | ||
| 4746 | } else { | ||
| 4747 | LOG_ERROR(Core_ARM11, "mmu_mcr wrote UNKNOWN - reg %d", CRn); | ||
| 4748 | } | ||
| 4749 | } else { | ||
| 4750 | LOG_ERROR(Core_ARM11, "mcr CRn=%d, CRm=%d OP2=%d is not implemented", CRn, CRm, OPCODE_2); | ||
| 4751 | } | ||
| 4752 | } | ||
| 4753 | } | ||
| 4754 | } | ||
| 4755 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4756 | INC_PC(sizeof(mcr_inst)); | ||
| 4757 | FETCH_INST; | ||
| 4758 | GOTO_NEXT_INST; | ||
| 4759 | } | ||
| 4760 | MCRR_INST: | ||
| 4761 | MLA_INST: | ||
| 4762 | { | ||
| 4763 | mla_inst *inst_cream = (mla_inst *)inst_base->component; | ||
| 4764 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4765 | uint64_t rm = RM; | ||
| 4766 | uint64_t rs = RS; | ||
| 4767 | uint64_t rn = RN; | ||
| 4768 | if (inst_cream->Rm == 15 || inst_cream->Rs == 15 || inst_cream->Rn == 15) { | ||
| 4769 | LOG_ERROR(Core_ARM11, "invalid operands for MLA"); | ||
| 4770 | CITRA_IGNORE_EXIT(-1); | ||
| 4771 | } | ||
| 4772 | RD = dst = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff); | ||
| 4773 | if (inst_cream->S) { | ||
| 4774 | UPDATE_NFLAG(dst); | ||
| 4775 | UPDATE_ZFLAG(dst); | ||
| 4776 | } | ||
| 4777 | if (inst_cream->Rd == 15) { | ||
| 4778 | INC_PC(sizeof(mla_inst)); | ||
| 4779 | goto DISPATCH; | ||
| 4780 | } | ||
| 4781 | } | ||
| 4782 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4783 | INC_PC(sizeof(mla_inst)); | ||
| 4784 | FETCH_INST; | ||
| 4785 | GOTO_NEXT_INST; | ||
| 4786 | } | ||
| 4787 | MOV_INST: | ||
| 4788 | { | ||
| 4789 | mov_inst *inst_cream = (mov_inst *)inst_base->component; | ||
| 4790 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4791 | RD = dst = SHIFTER_OPERAND; | ||
| 4792 | if (inst_cream->S && (inst_cream->Rd == 15)) { | ||
| 4793 | if (CurrentModeHasSPSR) { | ||
| 4794 | cpu->Cpsr = cpu->Spsr_copy; | ||
| 4795 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | ||
| 4796 | LOAD_NZCVT; | ||
| 4797 | } | ||
| 4798 | } else if (inst_cream->S) { | ||
| 4799 | UPDATE_NFLAG(dst); | ||
| 4800 | UPDATE_ZFLAG(dst); | ||
| 4801 | UPDATE_CFLAG_WITH_SC; | ||
| 4802 | } | ||
| 4803 | if (inst_cream->Rd == 15) { | ||
| 4804 | INC_PC(sizeof(mov_inst)); | ||
| 4805 | goto DISPATCH; | ||
| 4806 | } | ||
| 4807 | } | ||
| 4808 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4809 | INC_PC(sizeof(mov_inst)); | ||
| 4810 | FETCH_INST; | ||
| 4811 | GOTO_NEXT_INST; | ||
| 4812 | } | ||
| 4813 | MRC_INST: | ||
| 4814 | { | ||
| 4815 | mrc_inst *inst_cream = (mrc_inst *)inst_base->component; | ||
| 4816 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4817 | unsigned int inst = inst_cream->inst; | ||
| 4818 | if (inst_cream->Rd == 15) { | ||
| 4819 | DEBUG_MSG; | ||
| 4820 | } | ||
| 4821 | if (inst_cream->inst == 0xeef04a10) { | ||
| 4822 | // Undefined instruction fmrx | ||
| 4823 | RD = 0x20000000; | ||
| 4824 | CITRA_IGNORE_EXIT(-1); | ||
| 4825 | goto END; | ||
| 4826 | } else { | ||
| 4827 | if (inst_cream->cp_num == 15) { | ||
| 4828 | if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) { | ||
| 4829 | RD = cpu->CP15[CP15(CP15_MAIN_ID)]; | ||
| 4830 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 0) { | ||
| 4831 | RD = cpu->CP15[CP15(CP15_CONTROL)]; | ||
| 4832 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) { | ||
| 4833 | RD = cpu->CP15[CP15(CP15_AUXILIARY_CONTROL)]; | ||
| 4834 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) { | ||
| 4835 | RD = cpu->CP15[CP15(CP15_COPROCESSOR_ACCESS_CONTROL)]; | ||
| 4836 | } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) { | ||
| 4837 | RD = cpu->CP15[CP15(CP15_DOMAIN_ACCESS_CONTROL)]; | ||
| 4838 | } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) { | ||
| 4839 | RD = cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_0)]; | ||
| 4840 | } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 0) { | ||
| 4841 | RD = cpu->CP15[CP15(CP15_FAULT_STATUS)]; | ||
| 4842 | } else if (CRn == 6 && CRm == 0 && OPCODE_2 == 0) { | ||
| 4843 | RD = cpu->CP15[CP15(CP15_FAULT_ADDRESS)]; | ||
| 4844 | } else if (CRn == 0 && CRm == 0 && OPCODE_2 == 1) { | ||
| 4845 | RD = cpu->CP15[CP15(CP15_CACHE_TYPE)]; | ||
| 4846 | } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 1) { | ||
| 4847 | RD = cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)]; | ||
| 4848 | } else if (CRn == 13) { | ||
| 4849 | if(OPCODE_2 == 0) | ||
| 4850 | RD = CP15_REG(CP15_PID); | ||
| 4851 | else if(OPCODE_2 == 1) | ||
| 4852 | RD = CP15_REG(CP15_CONTEXT_ID); | ||
| 4853 | else if(OPCODE_2 == 3) { | ||
| 4854 | RD = Memory::KERNEL_MEMORY_VADDR; | ||
| 4855 | } else { | ||
| 4856 | LOG_ERROR(Core_ARM11, "mmu_mrr wrote UNKNOWN - reg %d", CRn); | ||
| 5044 | } | 4857 | } |
| 4858 | } else { | ||
| 4859 | LOG_ERROR(Core_ARM11, "mrc CRn=%d, CRm=%d, OP2=%d is not implemented", CRn, CRm, OPCODE_2); | ||
| 4860 | } | ||
| 4861 | } | ||
| 4862 | } | ||
| 4863 | } | ||
| 4864 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4865 | INC_PC(sizeof(mrc_inst)); | ||
| 4866 | FETCH_INST; | ||
| 4867 | GOTO_NEXT_INST; | ||
| 4868 | } | ||
| 4869 | MRRC_INST: | ||
| 4870 | MRS_INST: | ||
| 4871 | { | ||
| 4872 | mrs_inst *inst_cream = (mrs_inst *)inst_base->component; | ||
| 4873 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4874 | if (inst_cream->R) { | ||
| 4875 | RD = cpu->Spsr_copy; | ||
| 4876 | } else { | ||
| 4877 | SAVE_NZCVT; | ||
| 4878 | RD = cpu->Cpsr; | ||
| 4879 | } | ||
| 4880 | } | ||
| 4881 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4882 | INC_PC(sizeof(mrs_inst)); | ||
| 4883 | FETCH_INST; | ||
| 4884 | GOTO_NEXT_INST; | ||
| 4885 | } | ||
| 4886 | MSR_INST: | ||
| 4887 | { | ||
| 4888 | msr_inst *inst_cream = (msr_inst *)inst_base->component; | ||
| 4889 | const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020; | ||
| 4890 | unsigned int inst = inst_cream->inst; | ||
| 4891 | unsigned int operand; | ||
| 4892 | |||
| 4893 | if (BIT(inst, 25)) { | ||
| 4894 | int rot_imm = BITS(inst, 8, 11) * 2; | ||
| 4895 | operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm); | ||
| 4896 | } else { | ||
| 4897 | operand = cpu->Reg[BITS(inst, 0, 3)]; | ||
| 4898 | } | ||
| 4899 | uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0) | ||
| 4900 | | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0); | ||
| 4901 | uint32_t mask; | ||
| 4902 | if (!inst_cream->R) { | ||
| 4903 | if (InAPrivilegedMode(cpu)) { | ||
| 4904 | if ((operand & StateMask) != 0) { | ||
| 4905 | /// UNPREDICTABLE | ||
| 4906 | DEBUG_MSG; | ||
| 4907 | } else | ||
| 4908 | mask = byte_mask & (UserMask | PrivMask); | ||
| 4909 | } else { | ||
| 4910 | mask = byte_mask & UserMask; | ||
| 4911 | } | ||
| 4912 | SAVE_NZCVT; | ||
| 4913 | |||
| 4914 | cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask); | ||
| 4915 | switch_mode(cpu, cpu->Cpsr & 0x1f); | ||
| 4916 | LOAD_NZCVT; | ||
| 4917 | } else { | ||
| 4918 | if (CurrentModeHasSPSR) { | ||
| 4919 | mask = byte_mask & (UserMask | PrivMask | StateMask); | ||
| 4920 | cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask); | ||
| 4921 | } | ||
| 4922 | } | ||
| 4923 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4924 | INC_PC(sizeof(msr_inst)); | ||
| 4925 | FETCH_INST; | ||
| 4926 | GOTO_NEXT_INST; | ||
| 4927 | } | ||
| 4928 | MUL_INST: | ||
| 4929 | { | ||
| 4930 | mul_inst *inst_cream = (mul_inst *)inst_base->component; | ||
| 4931 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4932 | uint64_t rm = RM; | ||
| 4933 | uint64_t rs = RS; | ||
| 4934 | RD = dst = static_cast<uint32_t>((rm * rs) & 0xffffffff); | ||
| 4935 | if (inst_cream->S) { | ||
| 4936 | UPDATE_NFLAG(dst); | ||
| 4937 | UPDATE_ZFLAG(dst); | ||
| 4938 | } | ||
| 4939 | if (inst_cream->Rd == 15) { | ||
| 4940 | INC_PC(sizeof(mul_inst)); | ||
| 4941 | goto DISPATCH; | ||
| 4942 | } | ||
| 4943 | } | ||
| 4944 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4945 | INC_PC(sizeof(mul_inst)); | ||
| 4946 | FETCH_INST; | ||
| 4947 | GOTO_NEXT_INST; | ||
| 4948 | } | ||
| 4949 | MVN_INST: | ||
| 4950 | { | ||
| 4951 | mvn_inst *inst_cream = (mvn_inst *)inst_base->component; | ||
| 4952 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4953 | RD = dst = ~SHIFTER_OPERAND; | ||
| 4954 | if (inst_cream->S && (inst_cream->Rd == 15)) { | ||
| 4955 | if (CurrentModeHasSPSR) { | ||
| 4956 | cpu->Cpsr = cpu->Spsr_copy; | ||
| 4957 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | ||
| 4958 | LOAD_NZCVT; | ||
| 4959 | } | ||
| 4960 | } else if (inst_cream->S) { | ||
| 4961 | UPDATE_NFLAG(dst); | ||
| 4962 | UPDATE_ZFLAG(dst); | ||
| 4963 | UPDATE_CFLAG_WITH_SC; | ||
| 4964 | } | ||
| 4965 | if (inst_cream->Rd == 15) { | ||
| 4966 | INC_PC(sizeof(mvn_inst)); | ||
| 4967 | goto DISPATCH; | ||
| 4968 | } | ||
| 4969 | } | ||
| 4970 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4971 | INC_PC(sizeof(mvn_inst)); | ||
| 4972 | FETCH_INST; | ||
| 4973 | GOTO_NEXT_INST; | ||
| 4974 | } | ||
| 4975 | ORR_INST: | ||
| 4976 | { | ||
| 4977 | orr_inst *inst_cream = (orr_inst *)inst_base->component; | ||
| 4978 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4979 | lop = RN; | ||
| 4980 | rop = SHIFTER_OPERAND; | ||
| 4981 | RD = dst = lop | rop; | ||
| 4982 | if (inst_cream->S && (inst_cream->Rd == 15)) { | ||
| 4983 | if (CurrentModeHasSPSR) { | ||
| 4984 | cpu->Cpsr = cpu->Spsr_copy; | ||
| 4985 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | ||
| 4986 | LOAD_NZCVT; | ||
| 4987 | } | ||
| 4988 | } else if (inst_cream->S) { | ||
| 4989 | UPDATE_NFLAG(dst); | ||
| 4990 | UPDATE_ZFLAG(dst); | ||
| 4991 | UPDATE_CFLAG_WITH_SC; | ||
| 4992 | } | ||
| 4993 | if (inst_cream->Rd == 15) { | ||
| 4994 | INC_PC(sizeof(orr_inst)); | ||
| 4995 | goto DISPATCH; | ||
| 4996 | } | ||
| 4997 | } | ||
| 4998 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4999 | INC_PC(sizeof(orr_inst)); | ||
| 5000 | FETCH_INST; | ||
| 5001 | GOTO_NEXT_INST; | ||
| 5002 | } | ||
| 5003 | |||
| 5004 | PKHBT_INST: | ||
| 5005 | { | ||
| 5006 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 5007 | pkh_inst *inst_cream = (pkh_inst *)inst_base->component; | ||
| 5008 | RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000); | ||
| 5009 | } | ||
| 5010 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5011 | INC_PC(sizeof(pkh_inst)); | ||
| 5012 | FETCH_INST; | ||
| 5013 | GOTO_NEXT_INST; | ||
| 5014 | } | ||
| 5015 | |||
| 5016 | PKHTB_INST: | ||
| 5017 | { | ||
| 5018 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 5019 | pkh_inst *inst_cream = (pkh_inst *)inst_base->component; | ||
| 5020 | int shift_imm = inst_cream->imm ? inst_cream->imm : 31; | ||
| 5021 | RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000); | ||
| 5022 | } | ||
| 5023 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5024 | INC_PC(sizeof(pkh_inst)); | ||
| 5025 | FETCH_INST; | ||
| 5026 | GOTO_NEXT_INST; | ||
| 5027 | } | ||
| 5028 | |||
| 5029 | PLD_INST: | ||
| 5030 | { | ||
| 5031 | // Instruction not implemented | ||
| 5032 | //LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); | ||
| 5033 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5034 | INC_PC(sizeof(stc_inst)); | ||
| 5035 | FETCH_INST; | ||
| 5036 | GOTO_NEXT_INST; | ||
| 5037 | } | ||
| 5038 | |||
| 5039 | QADD_INST: | ||
| 5040 | QADD8_INST: | ||
| 5041 | QADD16_INST: | ||
| 5042 | QADDSUBX_INST: | ||
| 5043 | QSUB8_INST: | ||
| 5044 | QSUB16_INST: | ||
| 5045 | QSUBADDX_INST: | ||
| 5046 | { | ||
| 5047 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 5048 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 5049 | const u16 rm_lo = (RM & 0xFFFF); | ||
| 5050 | const u16 rm_hi = ((RM >> 16) & 0xFFFF); | ||
| 5051 | const u16 rn_lo = (RN & 0xFFFF); | ||
| 5052 | const u16 rn_hi = ((RN >> 16) & 0xFFFF); | ||
| 5053 | const u8 op2 = inst_cream->op2; | ||
| 5054 | |||
| 5055 | u16 lo_result = 0; | ||
| 5056 | u16 hi_result = 0; | ||
| 5057 | |||
| 5058 | // QADD16 | ||
| 5059 | if (op2 == 0x00) { | ||
| 5060 | lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo); | ||
| 5061 | hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi); | ||
| 5062 | } | ||
| 5063 | // QASX | ||
| 5064 | else if (op2 == 0x01) { | ||
| 5065 | lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi); | ||
| 5066 | hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo); | ||
| 5067 | } | ||
| 5068 | // QSAX | ||
| 5069 | else if (op2 == 0x02) { | ||
| 5070 | lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi); | ||
| 5071 | hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo); | ||
| 5072 | } | ||
| 5073 | // QSUB16 | ||
| 5074 | else if (op2 == 0x03) { | ||
| 5075 | lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo); | ||
| 5076 | hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi); | ||
| 5077 | } | ||
| 5078 | // QADD8 | ||
| 5079 | else if (op2 == 0x04) { | ||
| 5080 | lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) | | ||
| 5081 | ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8; | ||
| 5082 | hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) | | ||
| 5083 | ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8; | ||
| 5084 | } | ||
| 5085 | // QSUB8 | ||
| 5086 | else if (op2 == 0x07) { | ||
| 5087 | lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) | | ||
| 5088 | ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8; | ||
| 5089 | hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) | | ||
| 5090 | ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8; | ||
| 5091 | } | ||
| 5092 | |||
| 5093 | RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); | ||
| 5094 | } | ||
| 5095 | |||
| 5096 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5097 | INC_PC(sizeof(generic_arm_inst)); | ||
| 5098 | FETCH_INST; | ||
| 5099 | GOTO_NEXT_INST; | ||
| 5100 | } | ||
| 5101 | |||
| 5102 | QDADD_INST: | ||
| 5103 | QDSUB_INST: | ||
| 5104 | QSUB_INST: | ||
| 5105 | REV_INST: | ||
| 5106 | { | ||
| 5107 | rev_inst *inst_cream = (rev_inst *)inst_base->component; | ||
| 5108 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5109 | RD = ((RM & 0xff) << 24) | | ||
| 5110 | (((RM >> 8) & 0xff) << 16) | | ||
| 5111 | (((RM >> 16) & 0xff) << 8) | | ||
| 5112 | ((RM >> 24) & 0xff); | ||
| 5113 | if (inst_cream->Rm == 15) { | ||
| 5114 | LOG_ERROR(Core_ARM11, "invalid operand for REV"); | ||
| 5115 | CITRA_IGNORE_EXIT(-1); | ||
| 5116 | } | ||
| 5117 | } | ||
| 5118 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5119 | INC_PC(sizeof(rev_inst)); | ||
| 5120 | FETCH_INST; | ||
| 5121 | GOTO_NEXT_INST; | ||
| 5122 | } | ||
| 5123 | REV16_INST: | ||
| 5124 | { | ||
| 5125 | rev_inst *inst_cream = (rev_inst *)inst_base->component; | ||
| 5126 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5127 | RD = (BITS(RM, 0, 7) << 8) | | ||
| 5128 | BITS(RM, 8, 15) | | ||
| 5129 | (BITS(RM, 16, 23) << 24) | | ||
| 5130 | (BITS(RM, 24, 31) << 16); | ||
| 5131 | } | ||
| 5132 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5133 | INC_PC(sizeof(rev_inst)); | ||
| 5134 | FETCH_INST; | ||
| 5135 | GOTO_NEXT_INST; | ||
| 5136 | } | ||
| 5137 | REVSH_INST: | ||
| 5138 | RFE_INST: | ||
| 5139 | RSB_INST: | ||
| 5140 | { | ||
| 5141 | rsb_inst *inst_cream = (rsb_inst *)inst_base->component; | ||
| 5142 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5143 | rop = RN; | ||
| 5144 | lop = SHIFTER_OPERAND; | ||
| 5145 | if (inst_cream->Rn == 15) { | ||
| 5146 | rop += 2 * GET_INST_SIZE(cpu);; | ||
| 5147 | } | ||
| 5148 | RD = dst = lop - rop; | ||
| 5149 | if (inst_cream->S && (inst_cream->Rd == 15)) { | ||
| 5150 | if (CurrentModeHasSPSR) { | ||
| 5151 | cpu->Cpsr = cpu->Spsr_copy; | ||
| 5152 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | ||
| 5153 | LOAD_NZCVT; | ||
| 5154 | } | ||
| 5155 | } else if (inst_cream->S) { | ||
| 5156 | UPDATE_NFLAG(dst); | ||
| 5157 | UPDATE_ZFLAG(dst); | ||
| 5158 | UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); | ||
| 5159 | UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); | ||
| 5160 | } | ||
| 5161 | if (inst_cream->Rd == 15) { | ||
| 5162 | INC_PC(sizeof(rsb_inst)); | ||
| 5163 | goto DISPATCH; | ||
| 5164 | } | ||
| 5165 | } | ||
| 5166 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5167 | INC_PC(sizeof(rsb_inst)); | ||
| 5168 | FETCH_INST; | ||
| 5169 | GOTO_NEXT_INST; | ||
| 5170 | } | ||
| 5171 | RSC_INST: | ||
| 5172 | { | ||
| 5173 | rsc_inst *inst_cream = (rsc_inst *)inst_base->component; | ||
| 5174 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5175 | lop = RN; | ||
| 5176 | rop = SHIFTER_OPERAND; | ||
| 5177 | RD = dst = rop - lop - !cpu->CFlag; | ||
| 5178 | if (inst_cream->S && (inst_cream->Rd == 15)) { | ||
| 5179 | if (CurrentModeHasSPSR) { | ||
| 5180 | cpu->Cpsr = cpu->Spsr_copy; | ||
| 5181 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | ||
| 5182 | LOAD_NZCVT; | ||
| 5183 | } | ||
| 5184 | } else if (inst_cream->S) { | ||
| 5185 | UPDATE_NFLAG(dst); | ||
| 5186 | UPDATE_ZFLAG(dst); | ||
| 5187 | UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(rop, lop, !cpu->CFlag); | ||
| 5188 | UPDATE_VFLAG_OVERFLOW_FROM((int)dst, (int)rop, (int)lop); | ||
| 5189 | } | ||
| 5190 | if (inst_cream->Rd == 15) { | ||
| 5191 | INC_PC(sizeof(rsc_inst)); | ||
| 5192 | goto DISPATCH; | ||
| 5193 | } | ||
| 5194 | } | ||
| 5195 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5196 | INC_PC(sizeof(rsc_inst)); | ||
| 5197 | FETCH_INST; | ||
| 5198 | GOTO_NEXT_INST; | ||
| 5199 | } | ||
| 5200 | |||
| 5201 | SADD8_INST: | ||
| 5202 | SADD16_INST: | ||
| 5203 | SADDSUBX_INST: | ||
| 5204 | SSUBADDX_INST: | ||
| 5205 | SSUB16_INST: | ||
| 5206 | { | ||
| 5207 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 5208 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 5209 | |||
| 5210 | const s16 rn_lo = (RN & 0xFFFF); | ||
| 5211 | const s16 rn_hi = ((RN >> 16) & 0xFFFF); | ||
| 5212 | const s16 rm_lo = (RM & 0xFFFF); | ||
| 5213 | const s16 rm_hi = ((RM >> 16) & 0xFFFF); | ||
| 5214 | |||
| 5215 | s32 lo_result = 0; | ||
| 5216 | s32 hi_result = 0; | ||
| 5217 | |||
| 5218 | // SADD16 | ||
| 5219 | if (inst_cream->op2 == 0x00) { | ||
| 5220 | lo_result = (rn_lo + rm_lo); | ||
| 5221 | hi_result = (rn_hi + rm_hi); | ||
| 5222 | } | ||
| 5223 | // SASX | ||
| 5224 | else if (inst_cream->op2 == 0x01) { | ||
| 5225 | lo_result = (rn_lo - rm_hi); | ||
| 5226 | hi_result = (rn_hi + rm_lo); | ||
| 5227 | } | ||
| 5228 | // SSAX | ||
| 5229 | else if (inst_cream->op2 == 0x02) { | ||
| 5230 | lo_result = (rn_lo + rm_hi); | ||
| 5231 | hi_result = (rn_hi - rm_lo); | ||
| 5232 | } | ||
| 5233 | // SSUB16 | ||
| 5234 | else if (inst_cream->op2 == 0x03) { | ||
| 5235 | lo_result = (rn_lo - rm_lo); | ||
| 5236 | hi_result = (rn_hi - rm_hi); | ||
| 5237 | } | ||
| 5238 | |||
| 5239 | RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); | ||
| 5240 | |||
| 5241 | if (lo_result >= 0) { | ||
| 5242 | cpu->Cpsr |= (1 << 16); | ||
| 5243 | cpu->Cpsr |= (1 << 17); | ||
| 5244 | } else { | ||
| 5245 | cpu->Cpsr &= ~(1 << 16); | ||
| 5246 | cpu->Cpsr &= ~(1 << 17); | ||
| 5247 | } | ||
| 5248 | |||
| 5249 | if (hi_result >= 0) { | ||
| 5250 | cpu->Cpsr |= (1 << 18); | ||
| 5251 | cpu->Cpsr |= (1 << 19); | ||
| 5252 | } else { | ||
| 5253 | cpu->Cpsr &= ~(1 << 18); | ||
| 5254 | cpu->Cpsr &= ~(1 << 19); | ||
| 5255 | } | ||
| 5256 | } | ||
| 5257 | |||
| 5258 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5259 | INC_PC(sizeof(generic_arm_inst)); | ||
| 5260 | FETCH_INST; | ||
| 5261 | GOTO_NEXT_INST; | ||
| 5262 | } | ||
| 5263 | |||
| 5264 | SBC_INST: | ||
| 5265 | { | ||
| 5266 | sbc_inst *inst_cream = (sbc_inst *)inst_base->component; | ||
| 5267 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5268 | lop = SHIFTER_OPERAND + !cpu->CFlag; | ||
| 5269 | rop = RN; | ||
| 5270 | RD = dst = rop - lop; | ||
| 5271 | if (inst_cream->S && (inst_cream->Rd == 15)) { | ||
| 5272 | if (CurrentModeHasSPSR) { | ||
| 5273 | cpu->Cpsr = cpu->Spsr_copy; | ||
| 5274 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | ||
| 5275 | LOAD_NZCVT; | ||
| 5276 | } | ||
| 5277 | } else if (inst_cream->S) { | ||
| 5278 | UPDATE_NFLAG(dst); | ||
| 5279 | UPDATE_ZFLAG(dst); | ||
| 5280 | |||
| 5281 | if(rop >= !cpu->CFlag) | ||
| 5282 | UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND); | ||
| 5283 | else | ||
| 5284 | UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag); | ||
| 5285 | |||
| 5286 | UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop); | ||
| 5287 | } | ||
| 5288 | if (inst_cream->Rd == 15) { | ||
| 5289 | INC_PC(sizeof(sbc_inst)); | ||
| 5290 | goto DISPATCH; | ||
| 5291 | } | ||
| 5292 | } | ||
| 5293 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5294 | INC_PC(sizeof(sbc_inst)); | ||
| 5295 | FETCH_INST; | ||
| 5296 | GOTO_NEXT_INST; | ||
| 5297 | } | ||
| 5298 | |||
| 5299 | SEL_INST: | ||
| 5300 | { | ||
| 5301 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 5302 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 5303 | |||
| 5304 | const u32 to = RM; | ||
| 5305 | const u32 from = RN; | ||
| 5306 | const u32 cpsr = cpu->Cpsr; | ||
| 5307 | |||
| 5308 | u32 result; | ||
| 5309 | if (cpsr & (1 << 16)) | ||
| 5310 | result = from & 0xff; | ||
| 5311 | else | ||
| 5312 | result = to & 0xff; | ||
| 5313 | |||
| 5314 | if (cpsr & (1 << 17)) | ||
| 5315 | result |= from & 0x0000ff00; | ||
| 5316 | else | ||
| 5317 | result |= to & 0x0000ff00; | ||
| 5318 | |||
| 5319 | if (cpsr & (1 << 18)) | ||
| 5320 | result |= from & 0x00ff0000; | ||
| 5321 | else | ||
| 5322 | result |= to & 0x00ff0000; | ||
| 5323 | |||
| 5324 | if (cpsr & (1 << 19)) | ||
| 5325 | result |= from & 0xff000000; | ||
| 5326 | else | ||
| 5327 | result |= to & 0xff000000; | ||
| 5328 | |||
| 5329 | RD = result; | ||
| 5330 | } | ||
| 5331 | |||
| 5332 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5333 | INC_PC(sizeof(generic_arm_inst)); | ||
| 5334 | FETCH_INST; | ||
| 5335 | GOTO_NEXT_INST; | ||
| 5336 | } | ||
| 5337 | |||
| 5338 | SETEND_INST: | ||
| 5339 | SHADD16_INST: | ||
| 5340 | SHADD8_INST: | ||
| 5341 | SHADDSUBX_INST: | ||
| 5342 | SHSUB16_INST: | ||
| 5343 | SHSUB8_INST: | ||
| 5344 | SHSUBADDX_INST: | ||
| 5345 | SMLA_INST: | ||
| 5346 | { | ||
| 5347 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5348 | smla_inst *inst_cream = (smla_inst *)inst_base->component; | ||
| 5349 | int32_t operand1, operand2; | ||
| 5350 | if (inst_cream->x == 0) | ||
| 5351 | operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); | ||
| 5352 | else | ||
| 5353 | operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); | ||
| 5354 | |||
| 5355 | if (inst_cream->y == 0) | ||
| 5356 | operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); | ||
| 5357 | else | ||
| 5358 | operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); | ||
| 5359 | RD = operand1 * operand2 + RN; | ||
| 5360 | |||
| 5361 | // TODO: FIXME: UPDATE Q FLAGS | ||
| 5362 | } | ||
| 5363 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5364 | INC_PC(sizeof(smla_inst)); | ||
| 5365 | FETCH_INST; | ||
| 5366 | GOTO_NEXT_INST; | ||
| 5367 | } | ||
| 5368 | SMLAD_INST: | ||
| 5369 | { | ||
| 5370 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5371 | smlad_inst *inst_cream = (smlad_inst *)inst_base->component; | ||
| 5372 | long long int rm = cpu->Reg[inst_cream->Rm]; | ||
| 5373 | long long int rn = cpu->Reg[inst_cream->Rn]; | ||
| 5374 | long long int ra = cpu->Reg[inst_cream->Ra]; | ||
| 5375 | |||
| 5376 | // See SMUAD | ||
| 5377 | if(inst_cream->Ra == 15) | ||
| 5378 | CITRA_IGNORE_EXIT(-1); | ||
| 5379 | int operand2 = (inst_cream->m)? ROTATE_RIGHT_32(rm, 16):rm; | ||
| 5380 | int half_rn, half_operand2; | ||
| 5381 | |||
| 5382 | half_rn = rn & 0xFFFF; | ||
| 5383 | half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; | ||
| 5384 | |||
| 5385 | half_operand2 = operand2 & 0xFFFF; | ||
| 5386 | half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; | ||
| 5387 | |||
| 5388 | long long int product1 = half_rn * half_operand2; | ||
| 5389 | |||
| 5390 | half_rn = (rn & 0xFFFF0000) >> 16; | ||
| 5391 | half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; | ||
| 5392 | |||
| 5393 | half_operand2 = (operand2 & 0xFFFF0000) >> 16; | ||
| 5394 | half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; | ||
| 5395 | |||
| 5396 | long long int product2 = half_rn * half_operand2; | ||
| 5397 | |||
| 5398 | long long int signed_ra = (ra & 0x80000000)? (0xFFFFFFFF00000000LL) | ra : ra; | ||
| 5399 | long long int result = product1 + product2 + signed_ra; | ||
| 5400 | cpu->Reg[inst_cream->Rd] = result & 0xFFFFFFFF; | ||
| 5401 | |||
| 5402 | // TODO: FIXME should check Signed overflow | ||
| 5403 | } | ||
| 5404 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5405 | INC_PC(sizeof(umlal_inst)); | ||
| 5406 | FETCH_INST; | ||
| 5407 | GOTO_NEXT_INST; | ||
| 5408 | } | ||
| 5409 | |||
| 5410 | SMLAL_INST: | ||
| 5411 | { | ||
| 5412 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5413 | umlal_inst *inst_cream = (umlal_inst *)inst_base->component; | ||
| 5414 | long long int rm = RM; | ||
| 5415 | long long int rs = RS; | ||
| 5416 | if (BIT(rm, 31)) { | ||
| 5417 | rm |= 0xffffffff00000000LL; | ||
| 5418 | } | ||
| 5419 | if (BIT(rs, 31)) { | ||
| 5420 | rs |= 0xffffffff00000000LL; | ||
| 5421 | } | ||
| 5422 | long long int rst = rm * rs; | ||
| 5423 | long long int rdhi32 = RDHI; | ||
| 5424 | long long int hilo = (rdhi32 << 32) + RDLO; | ||
| 5425 | rst += hilo; | ||
| 5426 | RDLO = BITS(rst, 0, 31); | ||
| 5427 | RDHI = BITS(rst, 32, 63); | ||
| 5428 | if (inst_cream->S) { | ||
| 5429 | cpu->NFlag = BIT(RDHI, 31); | ||
| 5430 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); | ||
| 5431 | } | ||
| 5432 | } | ||
| 5433 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5434 | INC_PC(sizeof(umlal_inst)); | ||
| 5435 | FETCH_INST; | ||
| 5436 | GOTO_NEXT_INST; | ||
| 5437 | } | ||
| 5438 | SMLALXY_INST: | ||
| 5439 | SMLALD_INST: | ||
| 5440 | SMLAW_INST: | ||
| 5441 | SMLSD_INST: | ||
| 5442 | SMLSLD_INST: | ||
| 5443 | SMMLA_INST: | ||
| 5444 | SMMLS_INST: | ||
| 5445 | SMMUL_INST: | ||
| 5446 | SMUAD_INST: | ||
| 5447 | SMUL_INST: | ||
| 5448 | { | ||
| 5449 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5450 | smul_inst *inst_cream = (smul_inst *)inst_base->component; | ||
| 5451 | uint32_t operand1, operand2; | ||
| 5452 | if (inst_cream->x == 0) | ||
| 5453 | operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); | ||
| 5454 | else | ||
| 5455 | operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); | ||
| 5456 | |||
| 5457 | if (inst_cream->y == 0) | ||
| 5458 | operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); | ||
| 5459 | else | ||
| 5460 | operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); | ||
| 5461 | RD = operand1 * operand2; | ||
| 5462 | } | ||
| 5463 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5464 | INC_PC(sizeof(smul_inst)); | ||
| 5465 | FETCH_INST; | ||
| 5466 | GOTO_NEXT_INST; | ||
| 5467 | } | ||
| 5468 | SMULL_INST: | ||
| 5469 | { | ||
| 5470 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5471 | umull_inst *inst_cream = (umull_inst *)inst_base->component; | ||
| 5472 | int64_t rm = RM; | ||
| 5473 | int64_t rs = RS; | ||
| 5474 | if (BIT(rm, 31)) { | ||
| 5475 | rm |= 0xffffffff00000000LL; | ||
| 5476 | } | ||
| 5477 | if (BIT(rs, 31)) { | ||
| 5478 | rs |= 0xffffffff00000000LL; | ||
| 5479 | } | ||
| 5480 | int64_t rst = rm * rs; | ||
| 5481 | RDHI = BITS(rst, 32, 63); | ||
| 5482 | RDLO = BITS(rst, 0, 31); | ||
| 5483 | |||
| 5484 | if (inst_cream->S) { | ||
| 5485 | cpu->NFlag = BIT(RDHI, 31); | ||
| 5486 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); | ||
| 5487 | } | ||
| 5488 | } | ||
| 5489 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5490 | INC_PC(sizeof(umull_inst)); | ||
| 5491 | FETCH_INST; | ||
| 5492 | GOTO_NEXT_INST; | ||
| 5493 | } | ||
| 5045 | 5494 | ||
| 5046 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 5495 | SMULW_INST: |
| 5047 | /* For armv5t, should enter thumb when bits[0] is non-zero. */ | 5496 | { |
| 5048 | cpu->TFlag = value & 0x1; | 5497 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5049 | cpu->Reg[15] &= 0xFFFFFFFE; | 5498 | smlad_inst *inst_cream = (smlad_inst *)inst_base->component; |
| 5050 | INC_PC(sizeof(ldst_inst)); | 5499 | int64_t rm = RM; |
| 5051 | goto DISPATCH; | 5500 | int64_t rn = RN; |
| 5052 | } | 5501 | if (inst_cream->m) |
| 5053 | } | 5502 | rm = BITS(rm, 16, 31); |
| 5054 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5503 | else |
| 5055 | INC_PC(sizeof(ldst_inst)); | 5504 | rm = BITS(rm, 0, 15); |
| 5056 | FETCH_INST; | 5505 | int64_t rst = rm * rn; |
| 5057 | GOTO_NEXT_INST; | 5506 | RD = BITS(rst, 16, 47); |
| 5058 | } | 5507 | } |
| 5059 | UXTH_INST: | 5508 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5060 | { | 5509 | INC_PC(sizeof(smlad_inst)); |
| 5061 | INC_ICOUNTER; | 5510 | FETCH_INST; |
| 5062 | uxth_inst *inst_cream = (uxth_inst *)inst_base->component; | 5511 | GOTO_NEXT_INST; |
| 5063 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5512 | } |
| 5064 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) | 5513 | |
| 5065 | & 0xffff; | 5514 | SMUSD_INST: |
| 5066 | RD = operand2; | 5515 | SRS_INST: |
| 5067 | } | 5516 | SSAT_INST: |
| 5068 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5517 | SSAT16_INST: |
| 5069 | INC_PC(sizeof(uxth_inst)); | 5518 | SSUB8_INST: |
| 5070 | FETCH_INST; | 5519 | STC_INST: |
| 5071 | GOTO_NEXT_INST; | 5520 | { |
| 5072 | } | 5521 | // Instruction not implemented |
| 5073 | UXTAH_INST: | 5522 | //LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); |
| 5074 | { | 5523 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5075 | INC_ICOUNTER; | 5524 | INC_PC(sizeof(stc_inst)); |
| 5076 | uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component; | 5525 | FETCH_INST; |
| 5077 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5526 | GOTO_NEXT_INST; |
| 5078 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) | 5527 | } |
| 5079 | & 0xffff; | 5528 | STM_INST: |
| 5080 | RD = RN + operand2; | 5529 | { |
| 5081 | if (inst_cream->Rn == 15 || inst_cream->Rm == 15) { | 5530 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5082 | LOG_ERROR(Core_ARM11, "invalid operands for UXTAH"); | 5531 | unsigned int inst = inst_cream->inst; |
| 5083 | CITRA_IGNORE_EXIT(-1); | 5532 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5084 | } | 5533 | int i; |
| 5085 | } | 5534 | unsigned int Rn = BITS(inst, 16, 19); |
| 5086 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5535 | unsigned int old_RN = cpu->Reg[Rn]; |
| 5087 | INC_PC(sizeof(uxtah_inst)); | 5536 | |
| 5088 | FETCH_INST; | 5537 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); |
| 5089 | GOTO_NEXT_INST; | 5538 | if (fault) goto MMU_EXCEPTION; |
| 5090 | } | 5539 | if (BIT(inst_cream->inst, 22) == 1) { |
| 5091 | LDRB_INST: | 5540 | for (i = 0; i < 13; i++) { |
| 5092 | { | 5541 | if(BIT(inst_cream->inst, i)){ |
| 5093 | INC_ICOUNTER; | 5542 | fault = check_address_validity(cpu, addr, &phys_addr, 0); |
| 5094 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5543 | if (fault) goto MMU_EXCEPTION; |
| 5095 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5544 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); |
| 5096 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 5545 | if (fault) goto MMU_EXCEPTION; |
| 5097 | if (fault) goto MMU_EXCEPTION; | 5546 | addr += 4; |
| 5098 | unsigned int value; | 5547 | phys_addr += 4; |
| 5099 | fault = interpreter_read_memory(addr, phys_addr, value, 8); | 5548 | } |
| 5100 | if (fault) goto MMU_EXCEPTION; | 5549 | } |
| 5101 | //bus_read(8, addr, &value); | 5550 | if (BIT(inst_cream->inst, 13)) { |
| 5102 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 5551 | if (cpu->Mode == USER32MODE) { |
| 5103 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 5552 | fault = check_address_validity(cpu, addr, &phys_addr, 0); |
| 5104 | INC_PC(sizeof(ldst_inst)); | 5553 | if (fault) goto MMU_EXCEPTION; |
| 5105 | goto DISPATCH; | 5554 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); |
| 5106 | } | 5555 | if (fault) goto MMU_EXCEPTION; |
| 5107 | } | 5556 | addr += 4; |
| 5108 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5557 | phys_addr += 4; |
| 5109 | INC_PC(sizeof(ldst_inst)); | 5558 | } else { |
| 5110 | FETCH_INST; | 5559 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[0], 32); |
| 5111 | GOTO_NEXT_INST; | 5560 | if (fault) goto MMU_EXCEPTION; |
| 5112 | } | 5561 | addr += 4; |
| 5113 | LDRBT_INST: | 5562 | phys_addr += 4; |
| 5114 | { | 5563 | } |
| 5115 | INC_ICOUNTER; | 5564 | } |
| 5116 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5565 | if (BIT(inst_cream->inst, 14)) { |
| 5117 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5566 | if (cpu->Mode == USER32MODE) { |
| 5118 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 5567 | fault = check_address_validity(cpu, addr, &phys_addr, 0); |
| 5119 | if (fault) goto MMU_EXCEPTION; | 5568 | if (fault) goto MMU_EXCEPTION; |
| 5120 | unsigned int value; | 5569 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); |
| 5121 | fault = interpreter_read_memory(addr, phys_addr, value, 8); | 5570 | if (fault) goto MMU_EXCEPTION; |
| 5122 | if (fault) goto MMU_EXCEPTION; | 5571 | addr += 4; |
| 5123 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 5572 | phys_addr += 4; |
| 5124 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 5573 | } else { |
| 5125 | INC_PC(sizeof(ldst_inst)); | 5574 | fault = check_address_validity(cpu, addr, &phys_addr, 0); |
| 5126 | goto DISPATCH; | 5575 | if (fault) goto MMU_EXCEPTION; |
| 5127 | } | 5576 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[1], 32); |
| 5128 | } | 5577 | if (fault) goto MMU_EXCEPTION; |
| 5129 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5578 | addr += 4; |
| 5130 | INC_PC(sizeof(ldst_inst)); | 5579 | phys_addr += 4; |
| 5131 | FETCH_INST; | 5580 | } |
| 5132 | GOTO_NEXT_INST; | 5581 | } |
| 5133 | } | 5582 | if (BIT(inst_cream->inst, 15)) { |
| 5134 | LDRD_INST: | 5583 | fault = check_address_validity(cpu, addr, &phys_addr, 0); |
| 5135 | { | 5584 | if (fault) goto MMU_EXCEPTION; |
| 5136 | INC_ICOUNTER; | 5585 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32); |
| 5137 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5586 | if (fault) goto MMU_EXCEPTION; |
| 5138 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5587 | } |
| 5139 | /* Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0) */ | 5588 | } else { |
| 5140 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 5589 | for( i = 0; i < 15; i ++ ) { |
| 5141 | if (fault) goto MMU_EXCEPTION; | 5590 | if(BIT(inst_cream->inst, i)) { |
| 5142 | uint32_t rear_phys_addr; | 5591 | fault = check_address_validity(cpu, addr, &phys_addr, 0); |
| 5143 | fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 1); | 5592 | if (fault) goto MMU_EXCEPTION; |
| 5144 | if(fault){ | 5593 | if(i == Rn) |
| 5145 | LOG_ERROR(Core_ARM11, "mmu fault , should rollback the above get_addr\n"); | 5594 | fault = interpreter_write_memory(addr, phys_addr, old_RN, 32); |
| 5146 | CITRA_IGNORE_EXIT(-1); | 5595 | else |
| 5147 | goto MMU_EXCEPTION; | 5596 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); |
| 5148 | } | 5597 | if (fault) goto MMU_EXCEPTION; |
| 5149 | unsigned int value; | 5598 | addr += 4; |
| 5150 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | 5599 | phys_addr += 4; |
| 5151 | if (fault) goto MMU_EXCEPTION; | 5600 | } |
| 5152 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 5601 | } |
| 5153 | fault = interpreter_read_memory(addr + 4, rear_phys_addr, value, 32); | 5602 | |
| 5154 | if (fault) goto MMU_EXCEPTION; | 5603 | // Check PC reg |
| 5155 | cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = value; | 5604 | if(BIT(inst_cream->inst, i)) { |
| 5156 | /* No dispatch since this operation should not modify R15 */ | 5605 | fault = check_address_validity(cpu, addr, &phys_addr, 0); |
| 5157 | } | 5606 | if (fault) goto MMU_EXCEPTION; |
| 5158 | cpu->Reg[15] += 4; | 5607 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32); |
| 5159 | INC_PC(sizeof(ldst_inst)); | 5608 | if (fault) goto MMU_EXCEPTION; |
| 5160 | FETCH_INST; | 5609 | } |
| 5161 | GOTO_NEXT_INST; | 5610 | } |
| 5162 | } | 5611 | } |
| 5163 | 5612 | cpu->Reg[15] += GET_INST_SIZE(cpu); | |
| 5164 | LDREX_INST: | 5613 | INC_PC(sizeof(ldst_inst)); |
| 5165 | { | 5614 | FETCH_INST; |
| 5166 | INC_ICOUNTER; | 5615 | GOTO_NEXT_INST; |
| 5167 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5616 | } |
| 5168 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5617 | SXTB_INST: |
| 5169 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | 5618 | { |
| 5170 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 5619 | sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; |
| 5171 | if (fault) goto MMU_EXCEPTION; | 5620 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5172 | unsigned int value; | 5621 | if (inst_cream->Rm == 15) { |
| 5173 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | 5622 | LOG_ERROR(Core_ARM11, "invalid operand for SXTB"); |
| 5174 | if (fault) goto MMU_EXCEPTION; | 5623 | CITRA_IGNORE_EXIT(-1); |
| 5175 | 5624 | } | |
| 5176 | add_exclusive_addr(cpu, phys_addr); | 5625 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); |
| 5177 | cpu->exclusive_state = 1; | 5626 | if (BIT(operand2, 7)) { |
| 5178 | 5627 | operand2 |= 0xffffff00; | |
| 5179 | //bus_read(32, addr, &value); | 5628 | } else |
| 5180 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 5629 | operand2 &= 0xff; |
| 5181 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 5630 | RD = operand2; |
| 5182 | INC_PC(sizeof(ldst_inst)); | 5631 | } |
| 5183 | goto DISPATCH; | 5632 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5184 | } | 5633 | INC_PC(sizeof(sxtb_inst)); |
| 5185 | } | 5634 | FETCH_INST; |
| 5186 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5635 | GOTO_NEXT_INST; |
| 5187 | INC_PC(sizeof(ldst_inst)); | 5636 | } |
| 5188 | FETCH_INST; | 5637 | STR_INST: |
| 5189 | GOTO_NEXT_INST; | 5638 | { |
| 5190 | } | 5639 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5191 | LDREXB_INST: | 5640 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5192 | { | 5641 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); |
| 5193 | INC_ICOUNTER; | 5642 | if (fault) goto MMU_EXCEPTION; |
| 5194 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5643 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; |
| 5195 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5644 | fault = interpreter_write_memory(addr, phys_addr, value, 32); |
| 5196 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | 5645 | if (fault) goto MMU_EXCEPTION; |
| 5197 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 5646 | } |
| 5198 | if (fault) goto MMU_EXCEPTION; | 5647 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5199 | unsigned int value; | 5648 | INC_PC(sizeof(ldst_inst)); |
| 5200 | fault = interpreter_read_memory(addr, phys_addr, value, 8); | 5649 | FETCH_INST; |
| 5201 | if (fault) goto MMU_EXCEPTION; | 5650 | GOTO_NEXT_INST; |
| 5202 | 5651 | } | |
| 5203 | add_exclusive_addr(cpu, phys_addr); | 5652 | UXTB_INST: |
| 5204 | cpu->exclusive_state = 1; | 5653 | { |
| 5205 | 5654 | uxtb_inst *inst_cream = (uxtb_inst *)inst_base->component; | |
| 5206 | //bus_read(8, addr, &value); | 5655 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5207 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 5656 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) |
| 5208 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 5657 | & 0xff; |
| 5209 | INC_PC(sizeof(ldst_inst)); | 5658 | RD = operand2; |
| 5210 | goto DISPATCH; | 5659 | } |
| 5211 | } | 5660 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5212 | } | 5661 | INC_PC(sizeof(uxtb_inst)); |
| 5213 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5662 | FETCH_INST; |
| 5214 | INC_PC(sizeof(ldst_inst)); | 5663 | GOTO_NEXT_INST; |
| 5215 | FETCH_INST; | 5664 | } |
| 5216 | GOTO_NEXT_INST; | 5665 | UXTAB_INST: |
| 5217 | } | 5666 | { |
| 5218 | LDRH_INST: | 5667 | uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component; |
| 5219 | { | 5668 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5220 | INC_ICOUNTER; | 5669 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) |
| 5221 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5670 | & 0xff; |
| 5222 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5671 | RD = RN + operand2; |
| 5223 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 5672 | } |
| 5224 | if (fault) goto MMU_EXCEPTION; | 5673 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5225 | unsigned int value = 0; | 5674 | INC_PC(sizeof(uxtab_inst)); |
| 5226 | fault = interpreter_read_memory(addr, phys_addr, value, 16); | 5675 | FETCH_INST; |
| 5227 | // fault = interpreter_read_memory(addr, value, 32); | 5676 | GOTO_NEXT_INST; |
| 5228 | if (fault) goto MMU_EXCEPTION; | 5677 | } |
| 5229 | //if (value == 0xffff && cpu->icounter > 190000000 && cpu->icounter < 210000000) { | 5678 | STRB_INST: |
| 5230 | // value = 0xffffffff; | 5679 | { |
| 5231 | //} | 5680 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5232 | //bus_read(16, addr, &value); | 5681 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5233 | // cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value & 0xffff; | 5682 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); |
| 5234 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 5683 | if (fault) goto MMU_EXCEPTION; |
| 5235 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 5684 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; |
| 5236 | INC_PC(sizeof(ldst_inst)); | 5685 | fault = interpreter_write_memory(addr, phys_addr, value, 8); |
| 5237 | goto DISPATCH; | 5686 | if (fault) goto MMU_EXCEPTION; |
| 5238 | } | 5687 | } |
| 5239 | } | 5688 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5240 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5689 | INC_PC(sizeof(ldst_inst)); |
| 5241 | INC_PC(sizeof(ldst_inst)); | 5690 | FETCH_INST; |
| 5242 | FETCH_INST; | 5691 | GOTO_NEXT_INST; |
| 5243 | GOTO_NEXT_INST; | 5692 | } |
| 5244 | } | 5693 | STRBT_INST: |
| 5245 | LDRSB_INST: | 5694 | { |
| 5246 | { | 5695 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5247 | INC_ICOUNTER; | 5696 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5248 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5697 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); |
| 5249 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5698 | if (fault) goto MMU_EXCEPTION; |
| 5250 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 5699 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; |
| 5251 | if (fault) goto MMU_EXCEPTION; | 5700 | fault = interpreter_write_memory(addr, phys_addr, value, 8); |
| 5252 | unsigned int value; | 5701 | if (fault) goto MMU_EXCEPTION; |
| 5253 | // DEBUG_LOG(ARM11, "ldrsb addr is %x\n", addr); | 5702 | } |
| 5254 | fault = interpreter_read_memory(addr, phys_addr, value, 8); | 5703 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5255 | if (fault) goto MMU_EXCEPTION; | 5704 | INC_PC(sizeof(ldst_inst)); |
| 5256 | //bus_read(8, addr, &value); | 5705 | FETCH_INST; |
| 5257 | if (BIT(value, 7)) { | 5706 | GOTO_NEXT_INST; |
| 5258 | value |= 0xffffff00; | 5707 | } |
| 5259 | } | 5708 | STRD_INST: |
| 5260 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 5709 | { |
| 5261 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 5710 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5262 | INC_PC(sizeof(ldst_inst)); | 5711 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5263 | goto DISPATCH; | 5712 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); |
| 5264 | } | 5713 | if (fault) goto MMU_EXCEPTION; |
| 5265 | } | 5714 | uint32_t rear_phys_addr; |
| 5266 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5715 | fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 0); |
| 5267 | INC_PC(sizeof(ldst_inst)); | ||
| 5268 | FETCH_INST; | ||
| 5269 | GOTO_NEXT_INST; | ||
| 5270 | } | ||
| 5271 | LDRSH_INST: | ||
| 5272 | { | ||
| 5273 | INC_ICOUNTER; | ||
| 5274 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 5275 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5276 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | ||
| 5277 | if (fault) goto MMU_EXCEPTION; | ||
| 5278 | unsigned int value; | ||
| 5279 | fault = interpreter_read_memory(addr, phys_addr, value, 16); | ||
| 5280 | if (fault) goto MMU_EXCEPTION; | ||
| 5281 | //bus_read(16, addr, &value); | ||
| 5282 | if (BIT(value, 15)) { | ||
| 5283 | value |= 0xffff0000; | ||
| 5284 | } | ||
| 5285 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 5286 | if (BITS(inst_cream->inst, 12, 15) == 15) { | ||
| 5287 | INC_PC(sizeof(ldst_inst)); | ||
| 5288 | goto DISPATCH; | ||
| 5289 | } | ||
| 5290 | } | ||
| 5291 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5292 | INC_PC(sizeof(ldst_inst)); | ||
| 5293 | FETCH_INST; | ||
| 5294 | GOTO_NEXT_INST; | ||
| 5295 | } | ||
| 5296 | LDRT_INST: | ||
| 5297 | { | ||
| 5298 | INC_ICOUNTER; | ||
| 5299 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 5300 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5301 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | ||
| 5302 | if (fault) goto MMU_EXCEPTION; | ||
| 5303 | unsigned int value; | ||
| 5304 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | ||
| 5305 | if (fault) goto MMU_EXCEPTION; | ||
| 5306 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 5307 | |||
| 5308 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) | ||
| 5309 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 5310 | else | ||
| 5311 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ROTATE_RIGHT_32(value,(8*(addr&0x3))) ; | ||
| 5312 | |||
| 5313 | if (BITS(inst_cream->inst, 12, 15) == 15) { | ||
| 5314 | INC_PC(sizeof(ldst_inst)); | ||
| 5315 | goto DISPATCH; | ||
| 5316 | } | ||
| 5317 | } | ||
| 5318 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5319 | INC_PC(sizeof(ldst_inst)); | ||
| 5320 | FETCH_INST; | ||
| 5321 | GOTO_NEXT_INST; | ||
| 5322 | } | ||
| 5323 | MCR_INST: | ||
| 5324 | { | ||
| 5325 | INC_ICOUNTER; | ||
| 5326 | /* NOT IMPL */ | ||
| 5327 | mcr_inst *inst_cream = (mcr_inst *)inst_base->component; | ||
| 5328 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5329 | unsigned int inst = inst_cream->inst; | ||
| 5330 | if (inst_cream->Rd == 15) { | ||
| 5331 | DEBUG_MSG; | ||
| 5332 | } else { | ||
| 5333 | if (inst_cream->cp_num == 15) { | ||
| 5334 | if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) { | ||
| 5335 | //LET(RD, CONST(0x0007b000)); | ||
| 5336 | //LET(RD, CONST(0x410FB760)); | ||
| 5337 | //LET(CP15_MAIN_ID, R(RD)); | ||
| 5338 | CP15_REG(CP15_MAIN_ID) = RD; | ||
| 5339 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) { | ||
| 5340 | //LET(RD, R(CP15_CONTROL)); | ||
| 5341 | CP15_REG(CP15_AUXILIARY_CONTROL) = RD; | ||
| 5342 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) { | ||
| 5343 | //LET(RD, R(CP15_CONTROL)); | ||
| 5344 | CP15_REG(CP15_COPROCESSOR_ACCESS_CONTROL) = RD; | ||
| 5345 | } else if(CRn == 1 && CRm == 0 && OPCODE_2 == 0) { | ||
| 5346 | //LET(CP15_CONTROL, R(RD)); | ||
| 5347 | CP15_REG(CP15_CONTROL) = RD; | ||
| 5348 | } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) { | ||
| 5349 | //LET(CP15_DOMAIN_ACCESS_CONTROL, R(RD)); | ||
| 5350 | CP15_REG(CP15_DOMAIN_ACCESS_CONTROL) = RD; | ||
| 5351 | } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) { | ||
| 5352 | //LET(CP15_TRANSLATION_BASE_TABLE_0, R(RD)); | ||
| 5353 | CP15_REG(CP15_TRANSLATION_BASE_TABLE_0) = RD; | ||
| 5354 | } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 1) { | ||
| 5355 | //LET(CP15_TRANSLATION_BASE_TABLE_1, R(RD)); | ||
| 5356 | CP15_REG(CP15_TRANSLATION_BASE_TABLE_1) = RD; | ||
| 5357 | } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 2) { | ||
| 5358 | //LET(CP15_TRANSLATION_BASE_CONTROL, R(RD)); | ||
| 5359 | CP15_REG(CP15_TRANSLATION_BASE_CONTROL) = RD; | ||
| 5360 | } else if(CRn == MMU_CACHE_OPS){ | ||
| 5361 | //SKYEYE_WARNING("cache operation have not implemented.\n"); | ||
| 5362 | } else if(CRn == MMU_TLB_OPS){ | ||
| 5363 | switch (CRm) { | ||
| 5364 | case 5: /* ITLB */ | ||
| 5365 | switch(OPCODE_2){ | ||
| 5366 | case 0: /* invalidate all */ | ||
| 5367 | //invalidate_all_tlb(state); | ||
| 5368 | LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate all"); | ||
| 5369 | //remove_tlb(INSN_TLB); | ||
| 5370 | //erase_all(core, INSN_TLB); | ||
| 5371 | break; | ||
| 5372 | case 1: /* invalidate by MVA */ | ||
| 5373 | //invalidate_by_mva(state, value); | ||
| 5374 | //DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by mva\n"); | ||
| 5375 | //remove_tlb_by_mva(RD, INSN_TLB); | ||
| 5376 | //erase_by_mva(core, RD, INSN_TLB); | ||
| 5377 | break; | ||
| 5378 | case 2: /* invalidate by asid */ | ||
| 5379 | //invalidate_by_asid(state, value); | ||
| 5380 | //DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by asid\n"); | ||
| 5381 | //erase_by_asid(core, RD, INSN_TLB); | ||
| 5382 | break; | ||
| 5383 | default: | ||
| 5384 | break; | ||
| 5385 | } | ||
| 5386 | |||
| 5387 | break; | ||
| 5388 | case 6: /* DTLB */ | ||
| 5389 | switch(OPCODE_2){ | ||
| 5390 | case 0: /* invalidate all */ | ||
| 5391 | //invalidate_all_tlb(state); | ||
| 5392 | //remove_tlb(DATA_TLB); | ||
| 5393 | //erase_all(core, DATA_TLB); | ||
| 5394 | LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate all"); | ||
| 5395 | break; | ||
| 5396 | case 1: /* invalidate by MVA */ | ||
| 5397 | //invalidate_by_mva(state, value); | ||
| 5398 | //remove_tlb_by_mva(RD, DATA_TLB); | ||
| 5399 | //erase_by_mva(core, RD, DATA_TLB); | ||
| 5400 | //DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by mva\n"); | ||
| 5401 | break; | ||
| 5402 | case 2: /* invalidate by asid */ | ||
| 5403 | //invalidate_by_asid(state, value); | ||
| 5404 | //remove_tlb_by_asid(RD, DATA_TLB); | ||
| 5405 | //erase_by_asid(core, RD, DATA_TLB); | ||
| 5406 | //DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by asid\n"); | ||
| 5407 | break; | ||
| 5408 | default: | ||
| 5409 | break; | ||
| 5410 | } | ||
| 5411 | break; | ||
| 5412 | case 7: /* UNIFILED TLB */ | ||
| 5413 | switch(OPCODE_2){ | ||
| 5414 | case 0: /* invalidate all */ | ||
| 5415 | //invalidate_all_tlb(state); | ||
| 5416 | //erase_all(core, INSN_TLB); | ||
| 5417 | //erase_all(core, DATA_TLB); | ||
| 5418 | //remove_tlb(DATA_TLB); | ||
| 5419 | //remove_tlb(INSN_TLB); | ||
| 5420 | //DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate all\n"); | ||
| 5421 | break; | ||
| 5422 | case 1: /* invalidate by MVA */ | ||
| 5423 | //invalidate_by_mva(state, value); | ||
| 5424 | //erase_by_mva(core, RD, DATA_TLB); | ||
| 5425 | //erase_by_mva(core, RD, INSN_TLB); | ||
| 5426 | LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate by mva"); | ||
| 5427 | break; | ||
| 5428 | case 2: /* invalidate by asid */ | ||
| 5429 | //invalidate_by_asid(state, value); | ||
| 5430 | //erase_by_asid(core, RD, DATA_TLB); | ||
| 5431 | //erase_by_asid(core, RD, INSN_TLB); | ||
| 5432 | LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate by asid"); | ||
| 5433 | break; | ||
| 5434 | default: | ||
| 5435 | break; | ||
| 5436 | } | ||
| 5437 | break; | ||
| 5438 | default: | ||
| 5439 | break; | ||
| 5440 | } | ||
| 5441 | } else if(CRn == MMU_PID){ | ||
| 5442 | if(OPCODE_2 == 0) | ||
| 5443 | CP15_REG(CP15_PID) = RD; | ||
| 5444 | else if(OPCODE_2 == 1) | ||
| 5445 | CP15_REG(CP15_CONTEXT_ID) = RD; | ||
| 5446 | else if(OPCODE_2 == 3){ | ||
| 5447 | CP15_REG(CP15_THREAD_URO) = RD; | ||
| 5448 | } | ||
| 5449 | else{ | ||
| 5450 | printf ("mmu_mcr wrote UNKNOWN - reg %d\n", CRn); | ||
| 5451 | } | ||
| 5452 | |||
| 5453 | } else { | ||
| 5454 | LOG_ERROR(Core_ARM11, "mcr CRn=%d, CRm=%d OP2=%d is not implemented", CRn, CRm, OPCODE_2); | ||
| 5455 | } | ||
| 5456 | } | ||
| 5457 | } | ||
| 5458 | } | ||
| 5459 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5460 | INC_PC(sizeof(mcr_inst)); | ||
| 5461 | FETCH_INST; | ||
| 5462 | GOTO_NEXT_INST; | ||
| 5463 | } | ||
| 5464 | MCRR_INST: | ||
| 5465 | MLA_INST: | ||
| 5466 | { | ||
| 5467 | INC_ICOUNTER; | ||
| 5468 | mla_inst *inst_cream = (mla_inst *)inst_base->component; | ||
| 5469 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5470 | uint64_t rm = RM; | ||
| 5471 | uint64_t rs = RS; | ||
| 5472 | uint64_t rn = RN; | ||
| 5473 | if (inst_cream->Rm == 15 || inst_cream->Rs == 15 || inst_cream->Rn == 15) { | ||
| 5474 | LOG_ERROR(Core_ARM11, "invalid operands for MLA"); | ||
| 5475 | CITRA_IGNORE_EXIT(-1); | ||
| 5476 | } | ||
| 5477 | // RD = dst = RM * RS + RN; | ||
| 5478 | RD = dst = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff); | ||
| 5479 | if (inst_cream->S) { | ||
| 5480 | UPDATE_NFLAG(dst); | ||
| 5481 | UPDATE_ZFLAG(dst); | ||
| 5482 | } | ||
| 5483 | if (inst_cream->Rd == 15) { | ||
| 5484 | INC_PC(sizeof(mla_inst)); | ||
| 5485 | goto DISPATCH; | ||
| 5486 | } | ||
| 5487 | } | ||
| 5488 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5489 | INC_PC(sizeof(mla_inst)); | ||
| 5490 | FETCH_INST; | ||
| 5491 | GOTO_NEXT_INST; | ||
| 5492 | } | ||
| 5493 | MOV_INST: | ||
| 5494 | { | ||
| 5495 | // DEBUG_LOG(ARM11, "mov inst\n"); | ||
| 5496 | // DEBUG_LOG(ARM11, "pc: %x\n", cpu->Reg[15]); | ||
| 5497 | // debug_function(cpu); | ||
| 5498 | // cpu->icount ++; | ||
| 5499 | INC_ICOUNTER; | ||
| 5500 | mov_inst *inst_cream = (mov_inst *)inst_base->component; | ||
| 5501 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5502 | RD = dst = SHIFTER_OPERAND; | ||
| 5503 | if (inst_cream->S && (inst_cream->Rd == 15)) { | ||
| 5504 | /* cpsr = spsr */ | ||
| 5505 | if (CurrentModeHasSPSR) { | ||
| 5506 | cpu->Cpsr = cpu->Spsr_copy; | ||
| 5507 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | ||
| 5508 | LOAD_NZCVT; | ||
| 5509 | } | ||
| 5510 | } else if (inst_cream->S) { | ||
| 5511 | UPDATE_NFLAG(dst); | ||
| 5512 | UPDATE_ZFLAG(dst); | ||
| 5513 | UPDATE_CFLAG_WITH_SC; | ||
| 5514 | } | ||
| 5515 | if (inst_cream->Rd == 15) { | ||
| 5516 | INC_PC(sizeof(mov_inst)); | ||
| 5517 | goto DISPATCH; | ||
| 5518 | } | ||
| 5519 | // return; | ||
| 5520 | } | ||
| 5521 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5522 | INC_PC(sizeof(mov_inst)); | ||
| 5523 | FETCH_INST; | ||
| 5524 | GOTO_NEXT_INST; | ||
| 5525 | } | ||
| 5526 | MRC_INST: | ||
| 5527 | { | ||
| 5528 | INC_ICOUNTER; | ||
| 5529 | /* NOT IMPL */ | ||
| 5530 | mrc_inst *inst_cream = (mrc_inst *)inst_base->component; | ||
| 5531 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5532 | unsigned int inst = inst_cream->inst; | ||
| 5533 | if (inst_cream->Rd == 15) { | ||
| 5534 | DEBUG_MSG; | ||
| 5535 | } | ||
| 5536 | if (inst_cream->inst == 0xeef04a10) { | ||
| 5537 | /* undefined instruction fmrx */ | ||
| 5538 | RD = 0x20000000; | ||
| 5539 | CITRA_IGNORE_EXIT(-1); | ||
| 5540 | goto END; | ||
| 5541 | } else { | ||
| 5542 | if (inst_cream->cp_num == 15) { | ||
| 5543 | if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) { | ||
| 5544 | //LET(RD, CONST(0x0007b000)); | ||
| 5545 | //LET(RD, CONST(0x410FB760)); | ||
| 5546 | //LET(RD, R(CP15_MAIN_ID)); | ||
| 5547 | RD = cpu->CP15[CP15(CP15_MAIN_ID)]; | ||
| 5548 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 0) { | ||
| 5549 | //LET(RD, R(CP15_CONTROL)); | ||
| 5550 | RD = cpu->CP15[CP15(CP15_CONTROL)]; | ||
| 5551 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) { | ||
| 5552 | //LET(RD, R(CP15_CONTROL)); | ||
| 5553 | RD = cpu->CP15[CP15(CP15_AUXILIARY_CONTROL)]; | ||
| 5554 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) { | ||
| 5555 | //LET(RD, R(CP15_CONTROL)); | ||
| 5556 | RD = cpu->CP15[CP15(CP15_COPROCESSOR_ACCESS_CONTROL)]; | ||
| 5557 | } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) { | ||
| 5558 | //LET(RD, R(CP15_DOMAIN_ACCESS_CONTROL)); | ||
| 5559 | RD = cpu->CP15[CP15(CP15_DOMAIN_ACCESS_CONTROL)]; | ||
| 5560 | } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) { | ||
| 5561 | //LET(RD, R(CP15_TRANSLATION_BASE_TABLE_0)); | ||
| 5562 | RD = cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_0)]; | ||
| 5563 | } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 0) { | ||
| 5564 | //LET(RD, R(CP15_FAULT_STATUS)); | ||
| 5565 | RD = cpu->CP15[CP15(CP15_FAULT_STATUS)]; | ||
| 5566 | } else if (CRn == 6 && CRm == 0 && OPCODE_2 == 0) { | ||
| 5567 | //LET(RD, R(CP15_FAULT_ADDRESS)); | ||
| 5568 | RD = cpu->CP15[CP15(CP15_FAULT_ADDRESS)]; | ||
| 5569 | } else if (CRn == 0 && CRm == 0 && OPCODE_2 == 1) { | ||
| 5570 | //LET(RD, R(CP15_CACHE_TYPE)); | ||
| 5571 | RD = cpu->CP15[CP15(CP15_CACHE_TYPE)]; | ||
| 5572 | } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 1) { | ||
| 5573 | //LET(RD, R(CP15_INSTR_FAULT_STATUS)); | ||
| 5574 | RD = cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)]; | ||
| 5575 | } else if (CRn == 13) { | ||
| 5576 | if(OPCODE_2 == 0) | ||
| 5577 | RD = CP15_REG(CP15_PID); | ||
| 5578 | else if(OPCODE_2 == 1) | ||
| 5579 | RD = CP15_REG(CP15_CONTEXT_ID); | ||
| 5580 | else if(OPCODE_2 == 3){ | ||
| 5581 | RD = Memory::KERNEL_MEMORY_VADDR; | ||
| 5582 | } | ||
| 5583 | else{ | ||
| 5584 | printf ("mmu_mrr wrote UNKNOWN - reg %d\n", CRn); | ||
| 5585 | } | ||
| 5586 | } | ||
| 5587 | else { | ||
| 5588 | LOG_ERROR(Core_ARM11, "mrc CRn=%d, CRm=%d, OP2=%d is not implemented", CRn, CRm, OPCODE_2); | ||
| 5589 | } | ||
| 5590 | } | ||
| 5591 | //DEBUG_LOG(ARM11, "mrc is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2); | ||
| 5592 | } | ||
| 5593 | } | ||
| 5594 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5595 | INC_PC(sizeof(mrc_inst)); | ||
| 5596 | FETCH_INST; | ||
| 5597 | GOTO_NEXT_INST; | ||
| 5598 | } | ||
| 5599 | MRRC_INST: | ||
| 5600 | MRS_INST: | ||
| 5601 | { | ||
| 5602 | INC_ICOUNTER; | ||
| 5603 | mrs_inst *inst_cream = (mrs_inst *)inst_base->component; | ||
| 5604 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5605 | if (inst_cream->R) { | ||
| 5606 | RD = cpu->Spsr_copy; | ||
| 5607 | } else { | ||
| 5608 | SAVE_NZCVT; | ||
| 5609 | RD = cpu->Cpsr; | ||
| 5610 | } | ||
| 5611 | } | ||
| 5612 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5613 | INC_PC(sizeof(mrs_inst)); | ||
| 5614 | FETCH_INST; | ||
| 5615 | GOTO_NEXT_INST; | ||
| 5616 | } | ||
| 5617 | MSR_INST: | ||
| 5618 | { | ||
| 5619 | INC_ICOUNTER; | ||
| 5620 | msr_inst *inst_cream = (msr_inst *)inst_base->component; | ||
| 5621 | const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020; | ||
| 5622 | unsigned int inst = inst_cream->inst; | ||
| 5623 | unsigned int operand; | ||
| 5624 | |||
| 5625 | if (BIT(inst, 25)) { | ||
| 5626 | int rot_imm = BITS(inst, 8, 11) * 2; | ||
| 5627 | //operand = ROTL(CONST(BITS(0, 7)), CONST(32 - rot_imm)); | ||
| 5628 | operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm); | ||
| 5629 | } else { | ||
| 5630 | //operand = R(RM); | ||
| 5631 | operand = cpu->Reg[BITS(inst, 0, 3)]; | ||
| 5632 | } | ||
| 5633 | uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0) | ||
| 5634 | | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0); | ||
| 5635 | uint32_t mask; | ||
| 5636 | if (!inst_cream->R) { | ||
| 5637 | if (InAPrivilegedMode(cpu)) { | ||
| 5638 | if ((operand & StateMask) != 0) { | ||
| 5639 | /* UNPREDICTABLE */ | ||
| 5640 | DEBUG_MSG; | ||
| 5641 | } else | ||
| 5642 | mask = byte_mask & (UserMask | PrivMask); | ||
| 5643 | } else { | ||
| 5644 | mask = byte_mask & UserMask; | ||
| 5645 | } | ||
| 5646 | //LET(CPSR_REG, OR(AND(R(CPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask)))); | ||
| 5647 | SAVE_NZCVT; | ||
| 5648 | |||
| 5649 | cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask); | ||
| 5650 | switch_mode(cpu, cpu->Cpsr & 0x1f); | ||
| 5651 | LOAD_NZCVT; | ||
| 5652 | } else { | ||
| 5653 | if (CurrentModeHasSPSR) { | ||
| 5654 | mask = byte_mask & (UserMask | PrivMask | StateMask); | ||
| 5655 | //LET(SPSR_REG, OR(AND(R(SPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask)))); | ||
| 5656 | cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask); | ||
| 5657 | } | ||
| 5658 | } | ||
| 5659 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5660 | INC_PC(sizeof(msr_inst)); | ||
| 5661 | FETCH_INST; | ||
| 5662 | GOTO_NEXT_INST; | ||
| 5663 | } | ||
| 5664 | MUL_INST: | ||
| 5665 | { | ||
| 5666 | INC_ICOUNTER; | ||
| 5667 | mul_inst *inst_cream = (mul_inst *)inst_base->component; | ||
| 5668 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5669 | // RD = dst = SHIFTER_OPERAND; | ||
| 5670 | uint64_t rm = RM; | ||
| 5671 | uint64_t rs = RS; | ||
| 5672 | RD = dst = static_cast<uint32_t>((rm * rs) & 0xffffffff); | ||
| 5673 | if (inst_cream->S) { | ||
| 5674 | UPDATE_NFLAG(dst); | ||
| 5675 | UPDATE_ZFLAG(dst); | ||
| 5676 | } | ||
| 5677 | if (inst_cream->Rd == 15) { | ||
| 5678 | INC_PC(sizeof(mul_inst)); | ||
| 5679 | goto DISPATCH; | ||
| 5680 | } | ||
| 5681 | } | ||
| 5682 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5683 | INC_PC(sizeof(mul_inst)); | ||
| 5684 | FETCH_INST; | ||
| 5685 | GOTO_NEXT_INST; | ||
| 5686 | } | ||
| 5687 | MVN_INST: | ||
| 5688 | { | ||
| 5689 | INC_ICOUNTER; | ||
| 5690 | mvn_inst *inst_cream = (mvn_inst *)inst_base->component; | ||
| 5691 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5692 | // RD = dst = (SHIFTER_OPERAND ^ 0xffffffff); | ||
| 5693 | RD = dst = ~SHIFTER_OPERAND; | ||
| 5694 | if (inst_cream->S && (inst_cream->Rd == 15)) { | ||
| 5695 | /* cpsr = spsr */ | ||
| 5696 | if (CurrentModeHasSPSR) { | ||
| 5697 | cpu->Cpsr = cpu->Spsr_copy; | ||
| 5698 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | ||
| 5699 | LOAD_NZCVT; | ||
| 5700 | } | ||
| 5701 | } else if (inst_cream->S) { | ||
| 5702 | UPDATE_NFLAG(dst); | ||
| 5703 | UPDATE_ZFLAG(dst); | ||
| 5704 | UPDATE_CFLAG_WITH_SC; | ||
| 5705 | } | ||
| 5706 | if (inst_cream->Rd == 15) { | ||
| 5707 | INC_PC(sizeof(mvn_inst)); | ||
| 5708 | goto DISPATCH; | ||
| 5709 | } | ||
| 5710 | } | ||
| 5711 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5712 | INC_PC(sizeof(mvn_inst)); | ||
| 5713 | FETCH_INST; | ||
| 5714 | GOTO_NEXT_INST; | ||
| 5715 | } | ||
| 5716 | ORR_INST: | ||
| 5717 | { | ||
| 5718 | INC_ICOUNTER; | ||
| 5719 | orr_inst *inst_cream = (orr_inst *)inst_base->component; | ||
| 5720 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5721 | lop = RN; | ||
| 5722 | rop = SHIFTER_OPERAND; | ||
| 5723 | // DEBUG_LOG(ARM11, "lop is %x, rop is %x, r2 is %x, r3 is %x\n", lop, rop, cpu->Reg[2], cpu->Reg[3]); | ||
| 5724 | RD = dst = lop | rop; | ||
| 5725 | if (inst_cream->S && (inst_cream->Rd == 15)) { | ||
| 5726 | /* cpsr = spsr*/ | ||
| 5727 | if (CurrentModeHasSPSR) { | ||
| 5728 | cpu->Cpsr = cpu->Spsr_copy; | ||
| 5729 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | ||
| 5730 | LOAD_NZCVT; | ||
| 5731 | } | ||
| 5732 | } else if (inst_cream->S) { | ||
| 5733 | UPDATE_NFLAG(dst); | ||
| 5734 | UPDATE_ZFLAG(dst); | ||
| 5735 | UPDATE_CFLAG_WITH_SC; | ||
| 5736 | // UPDATE_CFLAG(dst, lop, rop); | ||
| 5737 | } | ||
| 5738 | if (inst_cream->Rd == 15) { | ||
| 5739 | INC_PC(sizeof(orr_inst)); | ||
| 5740 | goto DISPATCH; | ||
| 5741 | } | ||
| 5742 | } | ||
| 5743 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5744 | INC_PC(sizeof(orr_inst)); | ||
| 5745 | FETCH_INST; | ||
| 5746 | GOTO_NEXT_INST; | ||
| 5747 | } | ||
| 5748 | |||
| 5749 | PKHBT_INST: | ||
| 5750 | { | ||
| 5751 | INC_ICOUNTER; | ||
| 5752 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 5753 | pkh_inst *inst_cream = (pkh_inst *)inst_base->component; | ||
| 5754 | RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000); | ||
| 5755 | } | ||
| 5756 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5757 | INC_PC(sizeof(pkh_inst)); | ||
| 5758 | FETCH_INST; | ||
| 5759 | GOTO_NEXT_INST; | ||
| 5760 | } | ||
| 5761 | |||
| 5762 | PKHTB_INST: | ||
| 5763 | { | ||
| 5764 | INC_ICOUNTER; | ||
| 5765 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 5766 | pkh_inst *inst_cream = (pkh_inst *)inst_base->component; | ||
| 5767 | int shift_imm = inst_cream->imm ? inst_cream->imm : 31; | ||
| 5768 | RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000); | ||
| 5769 | } | ||
| 5770 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5771 | INC_PC(sizeof(pkh_inst)); | ||
| 5772 | FETCH_INST; | ||
| 5773 | GOTO_NEXT_INST; | ||
| 5774 | } | ||
| 5775 | |||
| 5776 | PLD_INST: | ||
| 5777 | { | ||
| 5778 | INC_ICOUNTER; | ||
| 5779 | /* NOT IMPL */ | ||
| 5780 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5781 | INC_PC(sizeof(stc_inst)); | ||
| 5782 | FETCH_INST; | ||
| 5783 | GOTO_NEXT_INST; | ||
| 5784 | } | ||
| 5785 | QADD_INST: | ||
| 5786 | |||
| 5787 | QADD8_INST: | ||
| 5788 | QADD16_INST: | ||
| 5789 | QADDSUBX_INST: | ||
| 5790 | QSUB8_INST: | ||
| 5791 | QSUB16_INST: | ||
| 5792 | QSUBADDX_INST: | ||
| 5793 | { | ||
| 5794 | INC_ICOUNTER; | ||
| 5795 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 5796 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 5797 | const u16 rm_lo = (RM & 0xFFFF); | ||
| 5798 | const u16 rm_hi = ((RM >> 16) & 0xFFFF); | ||
| 5799 | const u16 rn_lo = (RN & 0xFFFF); | ||
| 5800 | const u16 rn_hi = ((RN >> 16) & 0xFFFF); | ||
| 5801 | const u8 op2 = inst_cream->op2; | ||
| 5802 | |||
| 5803 | u16 lo_result = 0; | ||
| 5804 | u16 hi_result = 0; | ||
| 5805 | |||
| 5806 | // QADD16 | ||
| 5807 | if (op2 == 0x00) { | ||
| 5808 | lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo); | ||
| 5809 | hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi); | ||
| 5810 | } | ||
| 5811 | // QASX | ||
| 5812 | else if (op2 == 0x01) { | ||
| 5813 | lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi); | ||
| 5814 | hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo); | ||
| 5815 | } | ||
| 5816 | // QSAX | ||
| 5817 | else if (op2 == 0x02) { | ||
| 5818 | lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi); | ||
| 5819 | hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo); | ||
| 5820 | } | ||
| 5821 | // QSUB16 | ||
| 5822 | else if (op2 == 0x03) { | ||
| 5823 | lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo); | ||
| 5824 | hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi); | ||
| 5825 | } | ||
| 5826 | // QADD8 | ||
| 5827 | else if (op2 == 0x04) { | ||
| 5828 | lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) | | ||
| 5829 | ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8; | ||
| 5830 | hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) | | ||
| 5831 | ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8; | ||
| 5832 | } | ||
| 5833 | // QSUB8 | ||
| 5834 | else if (op2 == 0x07) { | ||
| 5835 | lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) | | ||
| 5836 | ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8; | ||
| 5837 | hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) | | ||
| 5838 | ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8; | ||
| 5839 | } | ||
| 5840 | |||
| 5841 | RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); | ||
| 5842 | } | ||
| 5843 | |||
| 5844 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5845 | INC_PC(sizeof(generic_arm_inst)); | ||
| 5846 | FETCH_INST; | ||
| 5847 | GOTO_NEXT_INST; | ||
| 5848 | } | ||
| 5849 | |||
| 5850 | QDADD_INST: | ||
| 5851 | QDSUB_INST: | ||
| 5852 | QSUB_INST: | ||
| 5853 | REV_INST: | ||
| 5854 | { | ||
| 5855 | INC_ICOUNTER; | ||
| 5856 | rev_inst *inst_cream = (rev_inst *)inst_base->component; | ||
| 5857 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5858 | RD = ((RM & 0xff) << 24) | | ||
| 5859 | (((RM >> 8) & 0xff) << 16) | | ||
| 5860 | (((RM >> 16) & 0xff) << 8) | | ||
| 5861 | ((RM >> 24) & 0xff); | ||
| 5862 | if (inst_cream->Rm == 15) { | ||
| 5863 | LOG_ERROR(Core_ARM11, "invalid operand for REV"); | ||
| 5864 | CITRA_IGNORE_EXIT(-1); | ||
| 5865 | } | ||
| 5866 | } | ||
| 5867 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5868 | INC_PC(sizeof(rev_inst)); | ||
| 5869 | FETCH_INST; | ||
| 5870 | GOTO_NEXT_INST; | ||
| 5871 | } | ||
| 5872 | REV16_INST: | ||
| 5873 | { | ||
| 5874 | INC_ICOUNTER; | ||
| 5875 | rev_inst *inst_cream = (rev_inst *)inst_base->component; | ||
| 5876 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5877 | RD = (BITS(RM, 0, 7) << 8) | | ||
| 5878 | BITS(RM, 8, 15) | | ||
| 5879 | (BITS(RM, 16, 23) << 24) | | ||
| 5880 | (BITS(RM, 24, 31) << 16); | ||
| 5881 | } | ||
| 5882 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5883 | INC_PC(sizeof(rev_inst)); | ||
| 5884 | FETCH_INST; | ||
| 5885 | GOTO_NEXT_INST; | ||
| 5886 | } | ||
| 5887 | REVSH_INST: | ||
| 5888 | RFE_INST: | ||
| 5889 | RSB_INST: | ||
| 5890 | { | ||
| 5891 | INC_ICOUNTER; | ||
| 5892 | rsb_inst *inst_cream = (rsb_inst *)inst_base->component; | ||
| 5893 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5894 | rop = RN; | ||
| 5895 | lop = SHIFTER_OPERAND; | ||
| 5896 | if (inst_cream->Rn == 15) { | ||
| 5897 | rop += 2 * GET_INST_SIZE(cpu);; | ||
| 5898 | } | ||
| 5899 | RD = dst = lop - rop; | ||
| 5900 | if (inst_cream->S && (inst_cream->Rd == 15)) { | ||
| 5901 | /* cpsr = spsr */ | ||
| 5902 | if (CurrentModeHasSPSR) { | ||
| 5903 | cpu->Cpsr = cpu->Spsr_copy; | ||
| 5904 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | ||
| 5905 | LOAD_NZCVT; | ||
| 5906 | } | ||
| 5907 | } else if (inst_cream->S) { | ||
| 5908 | UPDATE_NFLAG(dst); | ||
| 5909 | UPDATE_ZFLAG(dst); | ||
| 5910 | UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); | ||
| 5911 | // UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | ||
| 5912 | UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); | ||
| 5913 | } | ||
| 5914 | if (inst_cream->Rd == 15) { | ||
| 5915 | INC_PC(sizeof(rsb_inst)); | ||
| 5916 | goto DISPATCH; | ||
| 5917 | } | ||
| 5918 | } | ||
| 5919 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5920 | INC_PC(sizeof(rsb_inst)); | ||
| 5921 | FETCH_INST; | ||
| 5922 | GOTO_NEXT_INST; | ||
| 5923 | } | ||
| 5924 | RSC_INST: | ||
| 5925 | { | ||
| 5926 | INC_ICOUNTER; | ||
| 5927 | rsc_inst *inst_cream = (rsc_inst *)inst_base->component; | ||
| 5928 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5929 | //lop = RN + !cpu->CFlag; | ||
| 5930 | //rop = SHIFTER_OPERAND; | ||
| 5931 | //RD = dst = rop - lop; | ||
| 5932 | lop = RN; | ||
| 5933 | rop = SHIFTER_OPERAND; | ||
| 5934 | RD = dst = rop - lop - !cpu->CFlag; | ||
| 5935 | if (inst_cream->S && (inst_cream->Rd == 15)) { | ||
| 5936 | /* cpsr = spsr */ | ||
| 5937 | if (CurrentModeHasSPSR) { | ||
| 5938 | cpu->Cpsr = cpu->Spsr_copy; | ||
| 5939 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | ||
| 5940 | LOAD_NZCVT; | ||
| 5941 | } | ||
| 5942 | } else if (inst_cream->S) { | ||
| 5943 | UPDATE_NFLAG(dst); | ||
| 5944 | UPDATE_ZFLAG(dst); | ||
| 5945 | // UPDATE_CFLAG(dst, lop, rop); | ||
| 5946 | // UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop); | ||
| 5947 | UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(rop, lop, !cpu->CFlag); | ||
| 5948 | // cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst))); | ||
| 5949 | UPDATE_VFLAG_OVERFLOW_FROM((int)dst, (int)rop, (int)lop); | ||
| 5950 | } | ||
| 5951 | if (inst_cream->Rd == 15) { | ||
| 5952 | INC_PC(sizeof(rsc_inst)); | ||
| 5953 | goto DISPATCH; | ||
| 5954 | } | ||
| 5955 | } | ||
| 5956 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5957 | INC_PC(sizeof(rsc_inst)); | ||
| 5958 | FETCH_INST; | ||
| 5959 | GOTO_NEXT_INST; | ||
| 5960 | } | ||
| 5961 | SADD8_INST: | ||
| 5962 | |||
| 5963 | SADD16_INST: | ||
| 5964 | SADDSUBX_INST: | ||
| 5965 | SSUBADDX_INST: | ||
| 5966 | SSUB16_INST: | ||
| 5967 | { | ||
| 5968 | INC_ICOUNTER; | ||
| 5969 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 5970 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 5971 | |||
| 5972 | const s16 rn_lo = (RN & 0xFFFF); | ||
| 5973 | const s16 rn_hi = ((RN >> 16) & 0xFFFF); | ||
| 5974 | const s16 rm_lo = (RM & 0xFFFF); | ||
| 5975 | const s16 rm_hi = ((RM >> 16) & 0xFFFF); | ||
| 5976 | |||
| 5977 | s32 lo_result = 0; | ||
| 5978 | s32 hi_result = 0; | ||
| 5979 | |||
| 5980 | // SADD16 | ||
| 5981 | if (inst_cream->op2 == 0x00) { | ||
| 5982 | lo_result = (rn_lo + rm_lo); | ||
| 5983 | hi_result = (rn_hi + rm_hi); | ||
| 5984 | } | ||
| 5985 | // SASX | ||
| 5986 | else if (inst_cream->op2 == 0x01) { | ||
| 5987 | lo_result = (rn_lo - rm_hi); | ||
| 5988 | hi_result = (rn_hi + rm_lo); | ||
| 5989 | } | ||
| 5990 | // SSAX | ||
| 5991 | else if (inst_cream->op2 == 0x02) { | ||
| 5992 | lo_result = (rn_lo + rm_hi); | ||
| 5993 | hi_result = (rn_hi - rm_lo); | ||
| 5994 | } | ||
| 5995 | // SSUB16 | ||
| 5996 | else if (inst_cream->op2 == 0x03) { | ||
| 5997 | lo_result = (rn_lo - rm_lo); | ||
| 5998 | hi_result = (rn_hi - rm_hi); | ||
| 5999 | } | ||
| 6000 | |||
| 6001 | RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); | ||
| 6002 | |||
| 6003 | if (lo_result >= 0) { | ||
| 6004 | cpu->Cpsr |= (1 << 16); | ||
| 6005 | cpu->Cpsr |= (1 << 17); | ||
| 6006 | } else { | ||
| 6007 | cpu->Cpsr &= ~(1 << 16); | ||
| 6008 | cpu->Cpsr &= ~(1 << 17); | ||
| 6009 | } | ||
| 6010 | |||
| 6011 | if (hi_result >= 0) { | ||
| 6012 | cpu->Cpsr |= (1 << 18); | ||
| 6013 | cpu->Cpsr |= (1 << 19); | ||
| 6014 | } else { | ||
| 6015 | cpu->Cpsr &= ~(1 << 18); | ||
| 6016 | cpu->Cpsr &= ~(1 << 19); | ||
| 6017 | } | ||
| 6018 | } | ||
| 6019 | |||
| 6020 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6021 | INC_PC(sizeof(generic_arm_inst)); | ||
| 6022 | FETCH_INST; | ||
| 6023 | GOTO_NEXT_INST; | ||
| 6024 | } | ||
| 6025 | |||
| 6026 | SBC_INST: | ||
| 6027 | { | ||
| 6028 | INC_ICOUNTER; | ||
| 6029 | sbc_inst *inst_cream = (sbc_inst *)inst_base->component; | ||
| 6030 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 6031 | lop = SHIFTER_OPERAND + !cpu->CFlag; | ||
| 6032 | rop = RN; | ||
| 6033 | RD = dst = rop - lop; | ||
| 6034 | if (inst_cream->S && (inst_cream->Rd == 15)) { | ||
| 6035 | /* cpsr = spsr */ | ||
| 6036 | if (CurrentModeHasSPSR) { | ||
| 6037 | cpu->Cpsr = cpu->Spsr_copy; | ||
| 6038 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | ||
| 6039 | LOAD_NZCVT; | ||
| 6040 | } | ||
| 6041 | } else if (inst_cream->S) { | ||
| 6042 | UPDATE_NFLAG(dst); | ||
| 6043 | UPDATE_ZFLAG(dst); | ||
| 6044 | // UPDATE_CFLAG(dst, lop, rop); | ||
| 6045 | //UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop); | ||
| 6046 | //rop = rop - !cpu->CFlag; | ||
| 6047 | if(rop >= !cpu->CFlag) | ||
| 6048 | UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND); | ||
| 6049 | else | ||
| 6050 | UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag); | ||
| 6051 | // cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst))); | ||
| 6052 | UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop); | ||
| 6053 | } | ||
| 6054 | if (inst_cream->Rd == 15) { | ||
| 6055 | INC_PC(sizeof(sbc_inst)); | ||
| 6056 | goto DISPATCH; | ||
| 6057 | } | ||
| 6058 | } | ||
| 6059 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6060 | INC_PC(sizeof(sbc_inst)); | ||
| 6061 | FETCH_INST; | ||
| 6062 | GOTO_NEXT_INST; | ||
| 6063 | } | ||
| 6064 | |||
| 6065 | SEL_INST: | ||
| 6066 | { | ||
| 6067 | INC_ICOUNTER; | ||
| 6068 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 6069 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 6070 | |||
| 6071 | const u32 to = RM; | ||
| 6072 | const u32 from = RN; | ||
| 6073 | const u32 cpsr = cpu->Cpsr; | ||
| 6074 | |||
| 6075 | u32 result; | ||
| 6076 | if (cpsr & (1 << 16)) | ||
| 6077 | result = from & 0xff; | ||
| 6078 | else | ||
| 6079 | result = to & 0xff; | ||
| 6080 | |||
| 6081 | if (cpsr & (1 << 17)) | ||
| 6082 | result |= from & 0x0000ff00; | ||
| 6083 | else | ||
| 6084 | result |= to & 0x0000ff00; | ||
| 6085 | |||
| 6086 | if (cpsr & (1 << 18)) | ||
| 6087 | result |= from & 0x00ff0000; | ||
| 6088 | else | ||
| 6089 | result |= to & 0x00ff0000; | ||
| 6090 | |||
| 6091 | if (cpsr & (1 << 19)) | ||
| 6092 | result |= from & 0xff000000; | ||
| 6093 | else | ||
| 6094 | result |= to & 0xff000000; | ||
| 6095 | |||
| 6096 | RD = result; | ||
| 6097 | } | ||
| 6098 | |||
| 6099 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6100 | INC_PC(sizeof(generic_arm_inst)); | ||
| 6101 | FETCH_INST; | ||
| 6102 | GOTO_NEXT_INST; | ||
| 6103 | } | ||
| 6104 | |||
| 6105 | SETEND_INST: | ||
| 6106 | SHADD16_INST: | ||
| 6107 | SHADD8_INST: | ||
| 6108 | SHADDSUBX_INST: | ||
| 6109 | SHSUB16_INST: | ||
| 6110 | SHSUB8_INST: | ||
| 6111 | SHSUBADDX_INST: | ||
| 6112 | SMLA_INST: | ||
| 6113 | { | ||
| 6114 | INC_ICOUNTER; | ||
| 6115 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 6116 | smla_inst *inst_cream = (smla_inst *)inst_base->component; | ||
| 6117 | int32_t operand1, operand2; | ||
| 6118 | if (inst_cream->x == 0) | ||
| 6119 | operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); | ||
| 6120 | else | ||
| 6121 | operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); | ||
| 6122 | |||
| 6123 | if (inst_cream->y == 0) | ||
| 6124 | operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); | ||
| 6125 | else | ||
| 6126 | operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); | ||
| 6127 | RD = operand1 * operand2 + RN; | ||
| 6128 | //FIXME: UPDATE Q FLAGS | ||
| 6129 | } | ||
| 6130 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6131 | INC_PC(sizeof(smla_inst)); | ||
| 6132 | FETCH_INST; | ||
| 6133 | GOTO_NEXT_INST; | ||
| 6134 | } | ||
| 6135 | SMLAD_INST: | ||
| 6136 | { | ||
| 6137 | INC_ICOUNTER; | ||
| 6138 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 6139 | smlad_inst *inst_cream = (smlad_inst *)inst_base->component; | ||
| 6140 | long long int rm = cpu->Reg[inst_cream->Rm]; | ||
| 6141 | long long int rn = cpu->Reg[inst_cream->Rn]; | ||
| 6142 | long long int ra = cpu->Reg[inst_cream->Ra]; | ||
| 6143 | /* see SMUAD */ | ||
| 6144 | if(inst_cream->Ra == 15) | ||
| 6145 | CITRA_IGNORE_EXIT(-1); | ||
| 6146 | int operand2 = (inst_cream->m)? ROTATE_RIGHT_32(rm, 16):rm; | ||
| 6147 | |||
| 6148 | int half_rn, half_operand2; | ||
| 6149 | half_rn = rn & 0xFFFF; | ||
| 6150 | half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; | ||
| 6151 | |||
| 6152 | half_operand2 = operand2 & 0xFFFF; | ||
| 6153 | half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; | ||
| 6154 | |||
| 6155 | long long int product1 = half_rn * half_operand2; | ||
| 6156 | |||
| 6157 | half_rn = (rn & 0xFFFF0000) >> 16; | ||
| 6158 | half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; | ||
| 6159 | |||
| 6160 | half_operand2 = (operand2 & 0xFFFF0000) >> 16; | ||
| 6161 | half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; | ||
| 6162 | |||
| 6163 | long long int product2 = half_rn * half_operand2; | ||
| 6164 | |||
| 6165 | long long int signed_ra = (ra & 0x80000000)? (0xFFFFFFFF00000000LL) | ra : ra; | ||
| 6166 | long long int result = product1 + product2 + signed_ra; | ||
| 6167 | cpu->Reg[inst_cream->Rd] = result & 0xFFFFFFFF; | ||
| 6168 | /* FIXME , should check Signed overflow */ | ||
| 6169 | } | ||
| 6170 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6171 | INC_PC(sizeof(umlal_inst)); | ||
| 6172 | FETCH_INST; | ||
| 6173 | GOTO_NEXT_INST; | ||
| 6174 | } | ||
| 6175 | |||
| 6176 | SMLAL_INST: | ||
| 6177 | { | ||
| 6178 | INC_ICOUNTER; | ||
| 6179 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 6180 | umlal_inst *inst_cream = (umlal_inst *)inst_base->component; | ||
| 6181 | long long int rm = RM; | ||
| 6182 | long long int rs = RS; | ||
| 6183 | if (BIT(rm, 31)) { | ||
| 6184 | rm |= 0xffffffff00000000LL; | ||
| 6185 | } | ||
| 6186 | if (BIT(rs, 31)) { | ||
| 6187 | rs |= 0xffffffff00000000LL; | ||
| 6188 | } | ||
| 6189 | long long int rst = rm * rs; | ||
| 6190 | long long int rdhi32 = RDHI; | ||
| 6191 | long long int hilo = (rdhi32 << 32) + RDLO; | ||
| 6192 | rst += hilo; | ||
| 6193 | RDLO = BITS(rst, 0, 31); | ||
| 6194 | RDHI = BITS(rst, 32, 63); | ||
| 6195 | if (inst_cream->S) { | ||
| 6196 | cpu->NFlag = BIT(RDHI, 31); | ||
| 6197 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); | ||
| 6198 | } | ||
| 6199 | } | ||
| 6200 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6201 | INC_PC(sizeof(umlal_inst)); | ||
| 6202 | FETCH_INST; | ||
| 6203 | GOTO_NEXT_INST; | ||
| 6204 | } | ||
| 6205 | SMLALXY_INST: | ||
| 6206 | SMLALD_INST: | ||
| 6207 | SMLAW_INST: | ||
| 6208 | SMLSD_INST: | ||
| 6209 | SMLSLD_INST: | ||
| 6210 | SMMLA_INST: | ||
| 6211 | SMMLS_INST: | ||
| 6212 | SMMUL_INST: | ||
| 6213 | SMUAD_INST: | ||
| 6214 | SMUL_INST: | ||
| 6215 | { | ||
| 6216 | INC_ICOUNTER; | ||
| 6217 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 6218 | smul_inst *inst_cream = (smul_inst *)inst_base->component; | ||
| 6219 | uint32_t operand1, operand2; | ||
| 6220 | if (inst_cream->x == 0) | ||
| 6221 | operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); | ||
| 6222 | else | ||
| 6223 | operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); | ||
| 6224 | |||
| 6225 | if (inst_cream->y == 0) | ||
| 6226 | operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); | ||
| 6227 | else | ||
| 6228 | operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); | ||
| 6229 | RD = operand1 * operand2; | ||
| 6230 | } | ||
| 6231 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6232 | INC_PC(sizeof(smul_inst)); | ||
| 6233 | FETCH_INST; | ||
| 6234 | GOTO_NEXT_INST; | ||
| 6235 | } | ||
| 6236 | SMULL_INST: | ||
| 6237 | { | ||
| 6238 | INC_ICOUNTER; | ||
| 6239 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 6240 | umull_inst *inst_cream = (umull_inst *)inst_base->component; | ||
| 6241 | // DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst); | ||
| 6242 | int64_t rm = RM; | ||
| 6243 | int64_t rs = RS; | ||
| 6244 | if (BIT(rm, 31)) { | ||
| 6245 | rm |= 0xffffffff00000000LL; | ||
| 6246 | } | ||
| 6247 | if (BIT(rs, 31)) { | ||
| 6248 | rs |= 0xffffffff00000000LL; | ||
| 6249 | } | ||
| 6250 | int64_t rst = rm * rs; | ||
| 6251 | RDHI = BITS(rst, 32, 63); | ||
| 6252 | RDLO = BITS(rst, 0, 31); | ||
| 6253 | |||
| 6254 | |||
| 6255 | if (inst_cream->S) { | ||
| 6256 | cpu->NFlag = BIT(RDHI, 31); | ||
| 6257 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); | ||
| 6258 | } | ||
| 6259 | } | ||
| 6260 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6261 | INC_PC(sizeof(umull_inst)); | ||
| 6262 | FETCH_INST; | ||
| 6263 | GOTO_NEXT_INST; | ||
| 6264 | } | ||
| 6265 | SMULW_INST: | ||
| 6266 | INC_ICOUNTER; | ||
| 6267 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 6268 | smlad_inst *inst_cream = (smlad_inst *)inst_base->component; | ||
| 6269 | // DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst); | ||
| 6270 | int64_t rm = RM; | ||
| 6271 | int64_t rn = RN; | ||
| 6272 | if (inst_cream->m) | ||
| 6273 | rm = BITS(rm,16 , 31); | ||
| 6274 | else | ||
| 6275 | rm = BITS(rm,0 , 15); | ||
| 6276 | int64_t rst = rm * rn; | ||
| 6277 | RD = BITS(rst, 16, 47); | ||
| 6278 | } | ||
| 6279 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6280 | INC_PC(sizeof(smlad_inst)); | ||
| 6281 | FETCH_INST; | ||
| 6282 | GOTO_NEXT_INST; | ||
| 6283 | |||
| 6284 | SMUSD_INST: | ||
| 6285 | SRS_INST: | ||
| 6286 | SSAT_INST: | ||
| 6287 | SSAT16_INST: | ||
| 6288 | SSUB8_INST: | ||
| 6289 | STC_INST: | ||
| 6290 | { | ||
| 6291 | INC_ICOUNTER; | ||
| 6292 | /* NOT IMPL */ | ||
| 6293 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6294 | INC_PC(sizeof(stc_inst)); | ||
| 6295 | FETCH_INST; | ||
| 6296 | GOTO_NEXT_INST; | ||
| 6297 | } | ||
| 6298 | STM_INST: | ||
| 6299 | { | ||
| 6300 | INC_ICOUNTER; | ||
| 6301 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 6302 | unsigned int inst = inst_cream->inst; | ||
| 6303 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 6304 | int i; | ||
| 6305 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 6306 | unsigned int old_RN = cpu->Reg[Rn]; | ||
| 6307 | |||
| 6308 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | ||
| 6309 | if (fault) goto MMU_EXCEPTION; | ||
| 6310 | if (BIT(inst_cream->inst, 22) == 1) { | ||
| 6311 | // DEBUG_MSG; | ||
| 6312 | #if 1 | ||
| 6313 | for (i = 0; i < 13; i++) { | ||
| 6314 | if(BIT(inst_cream->inst, i)){ | ||
| 6315 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | ||
| 6316 | if (fault) { | ||
| 6317 | goto MMU_EXCEPTION; | ||
| 6318 | } | ||
| 6319 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); | ||
| 6320 | if (fault) goto MMU_EXCEPTION; | ||
| 6321 | addr += 4; | ||
| 6322 | phys_addr += 4; | ||
| 6323 | } | ||
| 6324 | } | ||
| 6325 | if (BIT(inst_cream->inst, 13)) { | ||
| 6326 | if (cpu->Mode == USER32MODE) { | ||
| 6327 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | ||
| 6328 | if (fault) { | ||
| 6329 | goto MMU_EXCEPTION; | ||
| 6330 | } | ||
| 6331 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); | ||
| 6332 | if (fault) goto MMU_EXCEPTION; | ||
| 6333 | addr += 4; | ||
| 6334 | phys_addr += 4; | ||
| 6335 | } else { | ||
| 6336 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[0], 32); | ||
| 6337 | if (fault) goto MMU_EXCEPTION; | ||
| 6338 | addr += 4; | ||
| 6339 | phys_addr += 4; | ||
| 6340 | } | ||
| 6341 | } | ||
| 6342 | if (BIT(inst_cream->inst, 14)) { | ||
| 6343 | if (cpu->Mode == USER32MODE) { | ||
| 6344 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | ||
| 6345 | if (fault) { | ||
| 6346 | goto MMU_EXCEPTION; | ||
| 6347 | } | ||
| 6348 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); | ||
| 6349 | if (fault) goto MMU_EXCEPTION; | ||
| 6350 | addr += 4; | ||
| 6351 | phys_addr += 4; | ||
| 6352 | } else { | ||
| 6353 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | ||
| 6354 | if (fault) { | ||
| 6355 | goto MMU_EXCEPTION; | ||
| 6356 | } | ||
| 6357 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[1], 32); | ||
| 6358 | if (fault) goto MMU_EXCEPTION; | ||
| 6359 | addr += 4; | ||
| 6360 | phys_addr += 4; | ||
| 6361 | } | ||
| 6362 | } | ||
| 6363 | if (BIT(inst_cream->inst, 15)) { | ||
| 6364 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | ||
| 6365 | if (fault) { | ||
| 6366 | goto MMU_EXCEPTION; | ||
| 6367 | } | ||
| 6368 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32); | ||
| 6369 | if (fault) goto MMU_EXCEPTION; | ||
| 6370 | } | ||
| 6371 | #endif | ||
| 6372 | } else { | ||
| 6373 | for( i = 0; i < 15; i ++ ){ | ||
| 6374 | if(BIT(inst_cream->inst, i)){ | ||
| 6375 | //arch_write_memory(cpu, bb, Addr, R(i), 32); | ||
| 6376 | //bus_write(32, addr, cpu->Reg[i]); | ||
| 6377 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | ||
| 6378 | if (fault) { | ||
| 6379 | goto MMU_EXCEPTION; | ||
| 6380 | } | ||
| 6381 | if(i == Rn) | ||
| 6382 | fault = interpreter_write_memory(addr, phys_addr, old_RN, 32); | ||
| 6383 | else | ||
| 6384 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); | ||
| 6385 | if (fault) goto MMU_EXCEPTION; | ||
| 6386 | addr += 4; | ||
| 6387 | phys_addr += 4; | ||
| 6388 | //Addr = ADD(Addr, CONST(4)); | ||
| 6389 | } | ||
| 6390 | } | ||
| 6391 | |||
| 6392 | /* check pc reg*/ | ||
| 6393 | if(BIT(inst_cream->inst, i)){ | ||
| 6394 | //arch_write_memory(cpu, bb, Addr, STOREM_CHECK_PC, 32); | ||
| 6395 | //bus_write(32, addr, cpu->Reg[i] + 8); | ||
| 6396 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | ||
| 6397 | if (fault) { | ||
| 6398 | goto MMU_EXCEPTION; | ||
| 6399 | } | ||
| 6400 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32); | ||
| 6401 | if (fault) goto MMU_EXCEPTION; | ||
| 6402 | } | ||
| 6403 | } | ||
| 6404 | } | ||
| 6405 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6406 | INC_PC(sizeof(ldst_inst)); | ||
| 6407 | FETCH_INST; | ||
| 6408 | GOTO_NEXT_INST; | ||
| 6409 | } | ||
| 6410 | SXTB_INST: | ||
| 6411 | { | ||
| 6412 | INC_ICOUNTER; | ||
| 6413 | sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; | ||
| 6414 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 6415 | if (inst_cream->Rm == 15) { | ||
| 6416 | LOG_ERROR(Core_ARM11, "invalid operand for SXTB"); | ||
| 6417 | CITRA_IGNORE_EXIT(-1); | ||
| 6418 | } | ||
| 6419 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); | ||
| 6420 | if (BIT(operand2, 7)) { | ||
| 6421 | operand2 |= 0xffffff00; | ||
| 6422 | } else | ||
| 6423 | operand2 &= 0xff; | ||
| 6424 | RD = operand2; | ||
| 6425 | } | ||
| 6426 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6427 | INC_PC(sizeof(sxtb_inst)); | ||
| 6428 | FETCH_INST; | ||
| 6429 | GOTO_NEXT_INST; | ||
| 6430 | } | ||
| 6431 | STR_INST: | ||
| 6432 | { | ||
| 6433 | INC_ICOUNTER; | ||
| 6434 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 6435 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 6436 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | ||
| 6437 | if (fault) goto MMU_EXCEPTION; | ||
| 6438 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; | ||
| 6439 | //bus_write(32, addr, value); | ||
| 6440 | fault = interpreter_write_memory(addr, phys_addr, value, 32); | ||
| 6441 | if (fault) goto MMU_EXCEPTION; | ||
| 6442 | } | ||
| 6443 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6444 | INC_PC(sizeof(ldst_inst)); | ||
| 6445 | FETCH_INST; | ||
| 6446 | GOTO_NEXT_INST; | ||
| 6447 | } | ||
| 6448 | UXTB_INST: | ||
| 6449 | { | ||
| 6450 | INC_ICOUNTER; | ||
| 6451 | uxtb_inst *inst_cream = (uxtb_inst *)inst_base->component; | ||
| 6452 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 6453 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) | ||
| 6454 | & 0xff; | ||
| 6455 | RD = operand2; | ||
| 6456 | } | ||
| 6457 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6458 | INC_PC(sizeof(uxtb_inst)); | ||
| 6459 | FETCH_INST; | ||
| 6460 | GOTO_NEXT_INST; | ||
| 6461 | } | ||
| 6462 | UXTAB_INST: | ||
| 6463 | { | ||
| 6464 | INC_ICOUNTER; | ||
| 6465 | uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component; | ||
| 6466 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 6467 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) | ||
| 6468 | & 0xff; | ||
| 6469 | RD = RN + operand2; | ||
| 6470 | } | ||
| 6471 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6472 | INC_PC(sizeof(uxtab_inst)); | ||
| 6473 | FETCH_INST; | ||
| 6474 | GOTO_NEXT_INST; | ||
| 6475 | } | ||
| 6476 | STRB_INST: | ||
| 6477 | { | ||
| 6478 | INC_ICOUNTER; | ||
| 6479 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 6480 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 6481 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | ||
| 6482 | if (fault) goto MMU_EXCEPTION; | ||
| 6483 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; | ||
| 6484 | //bus_write(8, addr, value); | ||
| 6485 | fault = interpreter_write_memory(addr, phys_addr, value, 8); | ||
| 6486 | if (fault) goto MMU_EXCEPTION; | ||
| 6487 | } | ||
| 6488 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6489 | INC_PC(sizeof(ldst_inst)); | ||
| 6490 | FETCH_INST; | ||
| 6491 | GOTO_NEXT_INST; | ||
| 6492 | } | ||
| 6493 | STRBT_INST: | ||
| 6494 | { | ||
| 6495 | INC_ICOUNTER; | ||
| 6496 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 6497 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 6498 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | ||
| 6499 | if (fault) goto MMU_EXCEPTION; | ||
| 6500 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; | ||
| 6501 | //bus_write(8, addr, value); | ||
| 6502 | fault = interpreter_write_memory(addr, phys_addr, value, 8); | ||
| 6503 | if (fault) goto MMU_EXCEPTION; | ||
| 6504 | } | ||
| 6505 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6506 | //if (BITS(inst_cream->inst, 12, 15) == 15) | ||
| 6507 | // goto DISPATCH; | ||
| 6508 | INC_PC(sizeof(ldst_inst)); | ||
| 6509 | FETCH_INST; | ||
| 6510 | GOTO_NEXT_INST; | ||
| 6511 | } | ||
| 6512 | STRD_INST: | ||
| 6513 | { | ||
| 6514 | INC_ICOUNTER; | ||
| 6515 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 6516 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 6517 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | ||
| 6518 | if (fault) goto MMU_EXCEPTION; | ||
| 6519 | uint32_t rear_phys_addr; | ||
| 6520 | fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 0); | ||
| 6521 | if (fault){ | 5716 | if (fault){ |
| 6522 | LOG_ERROR(Core_ARM11, "mmu fault , should rollback the above get_addr\n"); | 5717 | LOG_ERROR(Core_ARM11, "MMU fault , should rollback the above get_addr"); |
| 6523 | CITRA_IGNORE_EXIT(-1); | 5718 | CITRA_IGNORE_EXIT(-1); |
| 6524 | goto MMU_EXCEPTION; | 5719 | goto MMU_EXCEPTION; |
| 6525 | } | 5720 | } |
| 6526 | 5721 | ||
| 6527 | //fault = inst_cream->get_addr(cpu, inst_cream->inst, addr + 4, phys_addr + 4, 0); | 5722 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; |
| 6528 | //if (fault) goto MMU_EXCEPTION; | 5723 | fault = interpreter_write_memory(addr, phys_addr, value, 32); |
| 6529 | 5724 | if (fault) goto MMU_EXCEPTION; | |
| 6530 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; | 5725 | value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]; |
| 6531 | //bus_write(32, addr, value); | 5726 | fault = interpreter_write_memory(addr + 4, rear_phys_addr, value, 32); |
| 6532 | fault = interpreter_write_memory(addr, phys_addr, value, 32); | 5727 | if (fault) goto MMU_EXCEPTION; |
| 6533 | if (fault) goto MMU_EXCEPTION; | 5728 | } |
| 6534 | value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]; | 5729 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6535 | //bus_write(32, addr, value); | 5730 | INC_PC(sizeof(ldst_inst)); |
| 6536 | fault = interpreter_write_memory(addr + 4, rear_phys_addr, value, 32); | 5731 | FETCH_INST; |
| 6537 | if (fault) goto MMU_EXCEPTION; | 5732 | GOTO_NEXT_INST; |
| 6538 | } | 5733 | } |
| 6539 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5734 | STREX_INST: |
| 6540 | INC_PC(sizeof(ldst_inst)); | 5735 | { |
| 6541 | FETCH_INST; | 5736 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 6542 | GOTO_NEXT_INST; | 5737 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6543 | } | 5738 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; |
| 6544 | STREX_INST: | 5739 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)]; |
| 6545 | { | 5740 | fault = check_address_validity(cpu, addr, &phys_addr, 0); |
| 6546 | INC_ICOUNTER; | 5741 | if (fault) goto MMU_EXCEPTION; |
| 6547 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5742 | |
| 6548 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5743 | int dest_reg = BITS(inst_cream->inst, 12, 15); |
| 6549 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | 5744 | if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){ |
| 6550 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)]; | 5745 | remove_exclusive(cpu, phys_addr); |
| 6551 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 5746 | cpu->Reg[dest_reg] = 0; |
| 6552 | if (fault) goto MMU_EXCEPTION; | 5747 | cpu->exclusive_state = 0; |
| 6553 | 5748 | ||
| 6554 | int dest_reg = BITS(inst_cream->inst, 12, 15); | 5749 | fault = interpreter_write_memory(addr, phys_addr, value, 32); |
| 6555 | if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){ | 5750 | if (fault) goto MMU_EXCEPTION; |
| 6556 | remove_exclusive(cpu, phys_addr); | 5751 | } else { |
| 6557 | cpu->Reg[dest_reg] = 0; | 5752 | // Failed to write due to mutex access |
| 6558 | cpu->exclusive_state = 0; | 5753 | cpu->Reg[dest_reg] = 1; |
| 6559 | 5754 | } | |
| 6560 | // bus_write(32, addr, value); | 5755 | } |
| 6561 | fault = interpreter_write_memory(addr, phys_addr, value, 32); | 5756 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6562 | if (fault) goto MMU_EXCEPTION; | 5757 | INC_PC(sizeof(ldst_inst)); |
| 6563 | } | 5758 | FETCH_INST; |
| 6564 | else{ | 5759 | GOTO_NEXT_INST; |
| 6565 | /* Failed to write due to mutex access */ | 5760 | } |
| 6566 | cpu->Reg[dest_reg] = 1; | 5761 | STREXB_INST: |
| 6567 | } | 5762 | { |
| 6568 | } | 5763 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 6569 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5764 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6570 | INC_PC(sizeof(ldst_inst)); | 5765 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; |
| 6571 | FETCH_INST; | 5766 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff; |
| 6572 | GOTO_NEXT_INST; | 5767 | fault = check_address_validity(cpu, addr, &phys_addr, 0); |
| 6573 | } | 5768 | if (fault) goto MMU_EXCEPTION; |
| 6574 | STREXB_INST: | 5769 | int dest_reg = BITS(inst_cream->inst, 12, 15); |
| 6575 | { | 5770 | if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){ |
| 6576 | INC_ICOUNTER; | 5771 | remove_exclusive(cpu, phys_addr); |
| 6577 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5772 | cpu->Reg[dest_reg] = 0; |
| 6578 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5773 | cpu->exclusive_state = 0; |
| 6579 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | 5774 | fault = interpreter_write_memory(addr, phys_addr, value, 8); |
| 6580 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff; | 5775 | if (fault) goto MMU_EXCEPTION; |
| 6581 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 5776 | } else { |
| 6582 | if (fault) goto MMU_EXCEPTION; | 5777 | cpu->Reg[dest_reg] = 1; |
| 6583 | //bus_write(8, addr, value); | 5778 | } |
| 6584 | int dest_reg = BITS(inst_cream->inst, 12, 15); | 5779 | } |
| 6585 | if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){ | 5780 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6586 | remove_exclusive(cpu, phys_addr); | 5781 | INC_PC(sizeof(ldst_inst)); |
| 6587 | cpu->Reg[dest_reg] = 0; | 5782 | FETCH_INST; |
| 6588 | cpu->exclusive_state = 0; | 5783 | GOTO_NEXT_INST; |
| 6589 | fault = interpreter_write_memory(addr, phys_addr, value, 8); | 5784 | } |
| 6590 | if (fault) goto MMU_EXCEPTION; | 5785 | STRH_INST: |
| 6591 | 5786 | { | |
| 6592 | } | 5787 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 6593 | else{ | 5788 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6594 | cpu->Reg[dest_reg] = 1; | 5789 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); |
| 6595 | } | 5790 | if (fault) goto MMU_EXCEPTION; |
| 6596 | } | 5791 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff; |
| 6597 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5792 | fault = interpreter_write_memory(addr, phys_addr, value, 16); |
| 6598 | INC_PC(sizeof(ldst_inst)); | 5793 | if (fault) goto MMU_EXCEPTION; |
| 6599 | FETCH_INST; | 5794 | } |
| 6600 | GOTO_NEXT_INST; | 5795 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6601 | } | 5796 | INC_PC(sizeof(ldst_inst)); |
| 6602 | STRH_INST: | 5797 | FETCH_INST; |
| 6603 | { | 5798 | GOTO_NEXT_INST; |
| 6604 | INC_ICOUNTER; | 5799 | } |
| 6605 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5800 | STRT_INST: |
| 6606 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5801 | { |
| 6607 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | 5802 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 6608 | if (fault) goto MMU_EXCEPTION; | 5803 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6609 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff; | 5804 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); |
| 6610 | //bus_write(16, addr, value); | 5805 | if (fault) goto MMU_EXCEPTION; |
| 6611 | fault = interpreter_write_memory(addr, phys_addr, value, 16); | 5806 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; |
| 6612 | if (fault) goto MMU_EXCEPTION; | 5807 | fault = interpreter_write_memory(addr, phys_addr, value, 32); |
| 6613 | } | 5808 | if (fault) goto MMU_EXCEPTION; |
| 6614 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5809 | } |
| 6615 | //if (BITS(inst_cream->inst, 12, 15) == 15) | 5810 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6616 | // goto DISPATCH; | 5811 | INC_PC(sizeof(ldst_inst)); |
| 6617 | INC_PC(sizeof(ldst_inst)); | 5812 | FETCH_INST; |
| 6618 | FETCH_INST; | 5813 | GOTO_NEXT_INST; |
| 6619 | GOTO_NEXT_INST; | 5814 | } |
| 6620 | } | 5815 | SUB_INST: |
| 6621 | STRT_INST: | 5816 | { |
| 6622 | { | 5817 | sub_inst *inst_cream = (sub_inst *)inst_base->component; |
| 6623 | INC_ICOUNTER; | 5818 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6624 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5819 | lop = RN; |
| 6625 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5820 | if (inst_cream->Rn == 15) { |
| 6626 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | 5821 | lop += 8; |
| 6627 | if (fault) goto MMU_EXCEPTION; | 5822 | } |
| 6628 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; | 5823 | rop = SHIFTER_OPERAND; |
| 6629 | //bus_write(16, addr, value); | 5824 | RD = dst = lop - rop; |
| 6630 | fault = interpreter_write_memory(addr, phys_addr, value, 32); | 5825 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 6631 | if (fault) goto MMU_EXCEPTION; | 5826 | if (CurrentModeHasSPSR) { |
| 6632 | } | 5827 | cpu->Cpsr = cpu->Spsr_copy; |
| 6633 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5828 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); |
| 6634 | INC_PC(sizeof(ldst_inst)); | 5829 | LOAD_NZCVT; |
| 6635 | FETCH_INST; | 5830 | } |
| 6636 | GOTO_NEXT_INST; | 5831 | } else if (inst_cream->S) { |
| 6637 | } | 5832 | UPDATE_NFLAG(dst); |
| 6638 | SUB_INST: | 5833 | UPDATE_ZFLAG(dst); |
| 6639 | { | 5834 | UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); |
| 6640 | INC_ICOUNTER; | 5835 | UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); |
| 6641 | sub_inst *inst_cream = (sub_inst *)inst_base->component; | 5836 | } |
| 6642 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5837 | if (inst_cream->Rd == 15) { |
| 6643 | lop = RN; | 5838 | INC_PC(sizeof(sub_inst)); |
| 6644 | if (inst_cream->Rn == 15) { | 5839 | goto DISPATCH; |
| 6645 | lop += 8; | 5840 | } |
| 6646 | } | 5841 | } |
| 6647 | rop = SHIFTER_OPERAND; | 5842 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6648 | RD = dst = lop - rop; | 5843 | INC_PC(sizeof(sub_inst)); |
| 6649 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 5844 | FETCH_INST; |
| 6650 | /* cpsr = spsr */ | 5845 | GOTO_NEXT_INST; |
| 6651 | if (CurrentModeHasSPSR) { | 5846 | } |
| 6652 | cpu->Cpsr = cpu->Spsr_copy; | 5847 | SWI_INST: |
| 6653 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 5848 | { |
| 6654 | LOAD_NZCVT; | 5849 | swi_inst *inst_cream = (swi_inst *)inst_base->component; |
| 6655 | } | 5850 | |
| 6656 | } else if (inst_cream->S) { | 5851 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) |
| 6657 | UPDATE_NFLAG(dst); | 5852 | HLE::CallSVC(Memory::Read32(cpu->Reg[15])); |
| 6658 | UPDATE_ZFLAG(dst); | 5853 | |
| 6659 | // UPDATE_CFLAG(dst, lop, rop); | 5854 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6660 | UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); | 5855 | INC_PC(sizeof(swi_inst)); |
| 6661 | // UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | 5856 | FETCH_INST; |
| 6662 | UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); | 5857 | GOTO_NEXT_INST; |
| 6663 | } | 5858 | } |
| 6664 | if (inst_cream->Rd == 15) { | 5859 | SWP_INST: |
| 6665 | INC_PC(sizeof(sub_inst)); | 5860 | { |
| 6666 | goto DISPATCH; | 5861 | swp_inst *inst_cream = (swp_inst *)inst_base->component; |
| 6667 | } | 5862 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6668 | } | 5863 | addr = RN; |
| 6669 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5864 | fault = check_address_validity(cpu, addr, &phys_addr, 1); |
| 6670 | INC_PC(sizeof(sub_inst)); | 5865 | if (fault) goto MMU_EXCEPTION; |
| 6671 | FETCH_INST; | 5866 | unsigned int value; |
| 6672 | GOTO_NEXT_INST; | 5867 | fault = interpreter_read_memory(addr, phys_addr, value, 32); |
| 6673 | } | 5868 | if (fault) goto MMU_EXCEPTION; |
| 6674 | SWI_INST: | 5869 | fault = interpreter_write_memory(addr, phys_addr, RM, 32); |
| 6675 | { | 5870 | if (fault) goto MMU_EXCEPTION; |
| 6676 | INC_ICOUNTER; | 5871 | |
| 6677 | swi_inst *inst_cream = (swi_inst *)inst_base->component; | 5872 | assert((phys_addr & 0x3) == 0); |
| 6678 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5873 | RD = value; |
| 6679 | if (true){ //if (core->is_user_mode) { --> Citra only emulates user mode | 5874 | } |
| 6680 | //arm_dyncom_SWI(cpu, inst_cream->num); | 5875 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6681 | HLE::CallSVC(Memory::Read32(cpu->Reg[15])); | 5876 | INC_PC(sizeof(swp_inst)); |
| 6682 | } else { | 5877 | FETCH_INST; |
| 6683 | cpu->syscallSig = 1; | 5878 | GOTO_NEXT_INST; |
| 6684 | goto END; | 5879 | } |
| 6685 | } | 5880 | SWPB_INST: |
| 6686 | } | 5881 | { |
| 6687 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5882 | swp_inst *inst_cream = (swp_inst *)inst_base->component; |
| 6688 | INC_PC(sizeof(swi_inst)); | 5883 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6689 | FETCH_INST; | 5884 | addr = RN; |
| 6690 | GOTO_NEXT_INST; | 5885 | fault = check_address_validity(cpu, addr, &phys_addr, 1); |
| 6691 | } | 5886 | if (fault) goto MMU_EXCEPTION; |
| 6692 | SWP_INST: | 5887 | unsigned int value; |
| 6693 | { | 5888 | fault = interpreter_read_memory(addr, phys_addr, value, 8); |
| 6694 | INC_ICOUNTER; | 5889 | if (fault) goto MMU_EXCEPTION; |
| 6695 | swp_inst *inst_cream = (swp_inst *)inst_base->component; | 5890 | fault = interpreter_write_memory(addr, phys_addr, (RM & 0xFF), 8); |
| 6696 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5891 | if (fault) goto MMU_EXCEPTION; |
| 6697 | addr = RN; | 5892 | } |
| 6698 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 5893 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6699 | if (fault) goto MMU_EXCEPTION; | 5894 | INC_PC(sizeof(swp_inst)); |
| 6700 | unsigned int value; | 5895 | FETCH_INST; |
| 6701 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | 5896 | GOTO_NEXT_INST; |
| 6702 | if (fault) goto MMU_EXCEPTION; | 5897 | } |
| 6703 | fault = interpreter_write_memory(addr, phys_addr, RM, 32); | 5898 | SXTAB_INST: |
| 6704 | if (fault) goto MMU_EXCEPTION; | 5899 | { |
| 6705 | 5900 | sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component; | |
| 6706 | /* ROR(data, 8*UInt(address<1:0>)); */ | 5901 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6707 | assert((phys_addr & 0x3) == 0); | 5902 | // R15 should be check |
| 6708 | RD = value; | 5903 | if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){ |
| 6709 | } | 5904 | CITRA_IGNORE_EXIT(-1); |
| 6710 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5905 | } |
| 6711 | INC_PC(sizeof(swp_inst)); | 5906 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff; |
| 6712 | FETCH_INST; | 5907 | |
| 6713 | GOTO_NEXT_INST; | 5908 | // Sign extend for byte |
| 6714 | } | 5909 | operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2; |
| 6715 | SWPB_INST: | 5910 | RD = RN + operand2; |
| 6716 | { | 5911 | } |
| 6717 | INC_ICOUNTER; | 5912 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6718 | swp_inst *inst_cream = (swp_inst *)inst_base->component; | 5913 | INC_PC(sizeof(uxtab_inst)); |
| 6719 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5914 | FETCH_INST; |
| 6720 | addr = RN; | 5915 | GOTO_NEXT_INST; |
| 6721 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 5916 | } |
| 6722 | if (fault) goto MMU_EXCEPTION; | 5917 | SXTAB16_INST: |
| 6723 | unsigned int value; | 5918 | SXTAH_INST: |
| 6724 | fault = interpreter_read_memory(addr, phys_addr, value, 8); | 5919 | { |
| 6725 | if (fault) goto MMU_EXCEPTION; | 5920 | sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component; |
| 6726 | fault = interpreter_write_memory(addr, phys_addr, (RM & 0xFF), 8); | 5921 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6727 | if (fault) goto MMU_EXCEPTION; | 5922 | // R15 should be check |
| 6728 | 5923 | if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15) { | |
| 6729 | /* FIXME */ | 5924 | CITRA_IGNORE_EXIT(-1); |
| 6730 | #if 0 | 5925 | } |
| 6731 | if Shared(address) then | 5926 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; |
| 6732 | /* ARMv6 */ | 5927 | // Sign extend for half |
| 6733 | physical_address = TLB(address) | 5928 | operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2; |
| 6734 | ClearExclusiveByAddress(physical_address,processor_id,1) | 5929 | RD = RN + operand2; |
| 6735 | /* See Summary of operation on page A2-49 */ | 5930 | } |
| 6736 | #endif | 5931 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6737 | } | 5932 | INC_PC(sizeof(sxtah_inst)); |
| 6738 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5933 | FETCH_INST; |
| 6739 | INC_PC(sizeof(swp_inst)); | 5934 | GOTO_NEXT_INST; |
| 6740 | FETCH_INST; | 5935 | } |
| 6741 | GOTO_NEXT_INST; | 5936 | SXTB16_INST: |
| 6742 | } | 5937 | TEQ_INST: |
| 6743 | SXTAB_INST: | 5938 | { |
| 6744 | { | 5939 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6745 | INC_ICOUNTER; | 5940 | teq_inst *inst_cream = (teq_inst *)inst_base->component; |
| 6746 | sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component; | 5941 | lop = RN; |
| 6747 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5942 | |
| 6748 | /* R15 should be check */ | 5943 | if (inst_cream->Rn == 15) |
| 6749 | if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){ | 5944 | lop += GET_INST_SIZE(cpu) * 2; |
| 6750 | CITRA_IGNORE_EXIT(-1); | 5945 | |
| 6751 | } | 5946 | rop = SHIFTER_OPERAND; |
| 6752 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) | 5947 | dst = lop ^ rop; |
| 6753 | & 0xff; | 5948 | |
| 6754 | /* sign extend for byte */ | 5949 | UPDATE_NFLAG(dst); |
| 6755 | operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2; | 5950 | UPDATE_ZFLAG(dst); |
| 6756 | RD = RN + operand2; | 5951 | UPDATE_CFLAG_WITH_SC; |
| 6757 | } | 5952 | } |
| 6758 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5953 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6759 | INC_PC(sizeof(uxtab_inst)); | 5954 | INC_PC(sizeof(teq_inst)); |
| 6760 | FETCH_INST; | 5955 | FETCH_INST; |
| 6761 | GOTO_NEXT_INST; | 5956 | GOTO_NEXT_INST; |
| 6762 | } | 5957 | } |
| 6763 | SXTAB16_INST: | 5958 | TST_INST: |
| 6764 | SXTAH_INST: | 5959 | { |
| 6765 | { | 5960 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6766 | INC_ICOUNTER; | 5961 | tst_inst *inst_cream = (tst_inst *)inst_base->component; |
| 6767 | sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component; | 5962 | lop = RN; |
| 6768 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5963 | |
| 6769 | /* R15 should be check */ | 5964 | if (inst_cream->Rn == 15) |
| 6770 | if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){ | 5965 | lop += GET_INST_SIZE(cpu) * 2; |
| 6771 | CITRA_IGNORE_EXIT(-1); | 5966 | |
| 6772 | } | 5967 | rop = SHIFTER_OPERAND; |
| 6773 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; | 5968 | dst = lop & rop; |
| 6774 | /* sign extend for half */ | 5969 | |
| 6775 | operand2 = (0x8000 & operand2)? (0xFFFF0000 | operand2):operand2; | 5970 | UPDATE_NFLAG(dst); |
| 6776 | RD = RN + operand2; | 5971 | UPDATE_ZFLAG(dst); |
| 6777 | } | 5972 | UPDATE_CFLAG_WITH_SC; |
| 6778 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5973 | } |
| 6779 | INC_PC(sizeof(sxtah_inst)); | 5974 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6780 | FETCH_INST; | 5975 | INC_PC(sizeof(tst_inst)); |
| 6781 | GOTO_NEXT_INST; | 5976 | FETCH_INST; |
| 6782 | } | 5977 | GOTO_NEXT_INST; |
| 6783 | SXTB16_INST: | 5978 | } |
| 6784 | TEQ_INST: | 5979 | UADD8_INST: |
| 6785 | { | 5980 | UADD16_INST: |
| 6786 | INC_ICOUNTER; | 5981 | UADDSUBX_INST: |
| 6787 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5982 | |
| 6788 | teq_inst *inst_cream = (teq_inst *)inst_base->component; | 5983 | UHADD8_INST: |
| 6789 | lop = RN; | 5984 | UHADD16_INST: |
| 6790 | if (inst_cream->Rn == 15) | 5985 | UHADDSUBX_INST: |
| 6791 | lop += GET_INST_SIZE(cpu) * 2; | 5986 | UHSUBADDX_INST: |
| 6792 | 5987 | UHSUB8_INST: | |
| 6793 | rop = SHIFTER_OPERAND; | 5988 | UHSUB16_INST: |
| 6794 | dst = lop ^ rop; | 5989 | { |
| 6795 | 5990 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | |
| 6796 | UPDATE_NFLAG(dst); | 5991 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 6797 | UPDATE_ZFLAG(dst); | 5992 | const u32 rm_val = RM; |
| 6798 | UPDATE_CFLAG_WITH_SC; | 5993 | const u32 rn_val = RN; |
| 6799 | } | 5994 | const u8 op2 = inst_cream->op2; |
| 6800 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5995 | |
| 6801 | INC_PC(sizeof(teq_inst)); | 5996 | if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) |
| 6802 | FETCH_INST; | 5997 | { |
| 6803 | GOTO_NEXT_INST; | 5998 | u32 lo_val = 0; |
| 6804 | } | 5999 | u32 hi_val = 0; |
| 6805 | TST_INST: | 6000 | |
| 6806 | { | 6001 | // UHADD16 |
| 6807 | INC_ICOUNTER; | 6002 | if (op2 == 0x00) { |
| 6808 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 6003 | lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF); |
| 6809 | tst_inst *inst_cream = (tst_inst *)inst_base->component; | 6004 | hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); |
| 6810 | lop = RN; | 6005 | } |
| 6811 | if (inst_cream->Rn == 15) | 6006 | // UHASX |
| 6812 | lop += GET_INST_SIZE(cpu) * 2; | 6007 | else if (op2 == 0x01) { |
| 6813 | rop = SHIFTER_OPERAND; | 6008 | lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); |
| 6814 | dst = lop & rop; | 6009 | hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF); |
| 6815 | 6010 | } | |
| 6816 | UPDATE_NFLAG(dst); | 6011 | // UHSAX |
| 6817 | UPDATE_ZFLAG(dst); | 6012 | else if (op2 == 0x02) { |
| 6818 | UPDATE_CFLAG_WITH_SC; | 6013 | lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); |
| 6819 | } | 6014 | hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF); |
| 6820 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6015 | } |
| 6821 | INC_PC(sizeof(tst_inst)); | 6016 | // UHSUB16 |
| 6822 | FETCH_INST; | 6017 | else if (op2 == 0x03) { |
| 6823 | GOTO_NEXT_INST; | 6018 | lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF); |
| 6824 | } | 6019 | hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); |
| 6825 | UADD8_INST: | 6020 | } |
| 6826 | UADD16_INST: | 6021 | |
| 6827 | UADDSUBX_INST: | 6022 | lo_val >>= 1; |
| 6828 | 6023 | hi_val >>= 1; | |
| 6829 | UHADD8_INST: | 6024 | |
| 6830 | UHADD16_INST: | 6025 | RD = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16); |
| 6831 | UHADDSUBX_INST: | 6026 | } |
| 6832 | UHSUBADDX_INST: | 6027 | else if (op2 == 0x04 || op2 == 0x07) { |
| 6833 | UHSUB8_INST: | 6028 | u32 sum1; |
| 6834 | UHSUB16_INST: | 6029 | u32 sum2; |
| 6835 | { | 6030 | u32 sum3; |
| 6836 | INC_ICOUNTER; | 6031 | u32 sum4; |
| 6837 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | 6032 | |
| 6838 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | 6033 | // UHADD8 |
| 6839 | 6034 | if (op2 == 0x04) { | |
| 6840 | const u32 rm_val = RM; | 6035 | sum1 = (rn_val & 0xFF) + (rm_val & 0xFF); |
| 6841 | const u32 rn_val = RN; | 6036 | sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF); |
| 6842 | const u8 op2 = inst_cream->op2; | 6037 | sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF); |
| 6843 | 6038 | sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF); | |
| 6844 | 6039 | } | |
| 6845 | if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) | 6040 | // UHSUB8 |
| 6846 | { | 6041 | else { |
| 6847 | u32 lo_val = 0; | 6042 | sum1 = (rn_val & 0xFF) - (rm_val & 0xFF); |
| 6848 | u32 hi_val = 0; | 6043 | sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF); |
| 6849 | 6044 | sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF); | |
| 6850 | // UHADD16 | 6045 | sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF); |
| 6851 | if (op2 == 0x00) { | 6046 | } |
| 6852 | lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF); | 6047 | |
| 6853 | hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); | 6048 | sum1 >>= 1; |
| 6854 | } | 6049 | sum2 >>= 1; |
| 6855 | // UHASX | 6050 | sum3 >>= 1; |
| 6856 | else if (op2 == 0x01) { | 6051 | sum4 >>= 1; |
| 6857 | lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); | 6052 | |
| 6858 | hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF); | 6053 | RD = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24); |
| 6859 | } | 6054 | } |
| 6860 | // UHSAX | 6055 | } |
| 6861 | else if (op2 == 0x02) { | 6056 | |
| 6862 | lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); | 6057 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6863 | hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF); | 6058 | INC_PC(sizeof(generic_arm_inst)); |
| 6864 | } | 6059 | FETCH_INST; |
| 6865 | // UHSUB16 | 6060 | GOTO_NEXT_INST; |
| 6866 | else if (op2 == 0x03) { | 6061 | } |
| 6867 | lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF); | 6062 | |
| 6868 | hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); | 6063 | UMAAL_INST: |
| 6869 | } | 6064 | { |
| 6870 | 6065 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | |
| 6871 | lo_val >>= 1; | 6066 | umaal_inst* const inst_cream = (umaal_inst*)inst_base->component; |
| 6872 | hi_val >>= 1; | 6067 | const u32 rm = RM; |
| 6873 | 6068 | const u32 rn = RN; | |
| 6874 | RD = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16); | 6069 | const u32 rd_lo = RDLO; |
| 6875 | } | 6070 | const u32 rd_hi = RDHI; |
| 6876 | else if (op2 == 0x04 || op2 == 0x07) { | 6071 | const u64 result = (rm * rn) + rd_lo + rd_hi; |
| 6877 | u32 sum1; | 6072 | |
| 6878 | u32 sum2; | 6073 | RDLO = (result & 0xFFFFFFFF); |
| 6879 | u32 sum3; | 6074 | RDHI = ((result >> 32) & 0xFFFFFFFF); |
| 6880 | u32 sum4; | 6075 | } |
| 6881 | 6076 | cpu->Reg[15] += GET_INST_SIZE(cpu); | |
| 6882 | // UHADD8 | 6077 | INC_PC(sizeof(umaal_inst)); |
| 6883 | if (op2 == 0x04) { | 6078 | FETCH_INST; |
| 6884 | sum1 = (rn_val & 0xFF) + (rm_val & 0xFF); | 6079 | GOTO_NEXT_INST; |
| 6885 | sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF); | 6080 | } |
| 6886 | sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF); | 6081 | UMLAL_INST: |
| 6887 | sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF); | 6082 | { |
| 6888 | } | 6083 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6889 | // UHSUB8 | 6084 | umlal_inst *inst_cream = (umlal_inst *)inst_base->component; |
| 6890 | else { | 6085 | unsigned long long int rm = RM; |
| 6891 | sum1 = (rn_val & 0xFF) - (rm_val & 0xFF); | 6086 | unsigned long long int rs = RS; |
| 6892 | sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF); | 6087 | unsigned long long int rst = rm * rs; |
| 6893 | sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF); | 6088 | unsigned long long int add = ((unsigned long long) RDHI)<<32; |
| 6894 | sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF); | 6089 | add += RDLO; |
| 6895 | } | 6090 | rst += add; |
| 6896 | 6091 | RDLO = BITS(rst, 0, 31); | |
| 6897 | sum1 >>= 1; | 6092 | RDHI = BITS(rst, 32, 63); |
| 6898 | sum2 >>= 1; | 6093 | |
| 6899 | sum3 >>= 1; | 6094 | if (inst_cream->S) { |
| 6900 | sum4 >>= 1; | 6095 | cpu->NFlag = BIT(RDHI, 31); |
| 6901 | 6096 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); | |
| 6902 | RD = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24); | 6097 | } |
| 6903 | } | 6098 | } |
| 6904 | 6099 | cpu->Reg[15] += GET_INST_SIZE(cpu); | |
| 6905 | } | 6100 | INC_PC(sizeof(umlal_inst)); |
| 6906 | 6101 | FETCH_INST; | |
| 6907 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6102 | GOTO_NEXT_INST; |
| 6908 | INC_PC(sizeof(generic_arm_inst)); | 6103 | } |
| 6909 | FETCH_INST; | 6104 | UMULL_INST: |
| 6910 | GOTO_NEXT_INST; | 6105 | { |
| 6911 | } | 6106 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6912 | 6107 | umull_inst *inst_cream = (umull_inst *)inst_base->component; | |
| 6913 | 6108 | unsigned long long int rm = RM; | |
| 6914 | UMAAL_INST: | 6109 | unsigned long long int rs = RS; |
| 6915 | { | 6110 | unsigned long long int rst = rm * rs; |
| 6916 | INC_ICOUNTER; | 6111 | RDHI = BITS(rst, 32, 63); |
| 6917 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | 6112 | RDLO = BITS(rst, 0, 31); |
| 6918 | umaal_inst* const inst_cream = (umaal_inst*)inst_base->component; | 6113 | |
| 6919 | 6114 | if (inst_cream->S) { | |
| 6920 | const u32 rm = RM; | 6115 | cpu->NFlag = BIT(RDHI, 31); |
| 6921 | const u32 rn = RN; | 6116 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); |
| 6922 | const u32 rd_lo = RDLO; | 6117 | } |
| 6923 | const u32 rd_hi = RDHI; | 6118 | } |
| 6924 | 6119 | cpu->Reg[15] += GET_INST_SIZE(cpu); | |
| 6925 | const u64 result = (rm * rn) + rd_lo + rd_hi; | 6120 | INC_PC(sizeof(umull_inst)); |
| 6926 | 6121 | FETCH_INST; | |
| 6927 | RDLO = (result & 0xFFFFFFFF); | 6122 | GOTO_NEXT_INST; |
| 6928 | RDHI = ((result >> 32) & 0xFFFFFFFF); | 6123 | } |
| 6929 | } | 6124 | B_2_THUMB: |
| 6930 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6125 | { |
| 6931 | INC_PC(sizeof(umaal_inst)); | 6126 | b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component; |
| 6932 | FETCH_INST; | 6127 | cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; |
| 6933 | GOTO_NEXT_INST; | 6128 | INC_PC(sizeof(b_2_thumb)); |
| 6934 | } | 6129 | goto DISPATCH; |
| 6935 | UMLAL_INST: | 6130 | } |
| 6936 | { | 6131 | B_COND_THUMB: |
| 6937 | INC_ICOUNTER; | 6132 | { |
| 6938 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 6133 | b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component; |
| 6939 | umlal_inst *inst_cream = (umlal_inst *)inst_base->component; | 6134 | |
| 6940 | unsigned long long int rm = RM; | 6135 | if(CondPassed(cpu, inst_cream->cond)) |
| 6941 | unsigned long long int rs = RS; | 6136 | cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; |
| 6942 | unsigned long long int rst = rm * rs; | 6137 | else |
| 6943 | unsigned long long int add = ((unsigned long long) RDHI)<<32; | 6138 | cpu->Reg[15] += 2; |
| 6944 | add += RDLO; | 6139 | |
| 6945 | //DEBUG_LOG(ARM11, "rm[%llx] * rs[%llx] = rst[%llx] | add[%llx]\n", RM, RS, rst, add); | 6140 | INC_PC(sizeof(b_cond_thumb)); |
| 6946 | rst += add; | 6141 | goto DISPATCH; |
| 6947 | RDLO = BITS(rst, 0, 31); | 6142 | } |
| 6948 | RDHI = BITS(rst, 32, 63); | 6143 | BL_1_THUMB: |
| 6949 | 6144 | { | |
| 6950 | if (inst_cream->S) | 6145 | bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component; |
| 6951 | { | 6146 | cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm; |
| 6952 | cpu->NFlag = BIT(RDHI, 31); | 6147 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6953 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); | 6148 | INC_PC(sizeof(bl_1_thumb)); |
| 6954 | } | 6149 | FETCH_INST; |
| 6955 | } | 6150 | GOTO_NEXT_INST; |
| 6956 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6151 | } |
| 6957 | INC_PC(sizeof(umlal_inst)); | 6152 | BL_2_THUMB: |
| 6958 | FETCH_INST; | 6153 | { |
| 6959 | GOTO_NEXT_INST; | 6154 | bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component; |
| 6960 | } | 6155 | int tmp = ((cpu->Reg[15] + 2) | 1); |
| 6961 | UMULL_INST: | 6156 | cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm); |
| 6962 | { | 6157 | cpu->Reg[14] = tmp; |
| 6963 | INC_ICOUNTER; | 6158 | INC_PC(sizeof(bl_2_thumb)); |
| 6964 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 6159 | goto DISPATCH; |
| 6965 | umull_inst *inst_cream = (umull_inst *)inst_base->component; | 6160 | } |
| 6966 | unsigned long long int rm = RM; | 6161 | BLX_1_THUMB: |
| 6967 | unsigned long long int rs = RS; | 6162 | { |
| 6968 | unsigned long long int rst = rm * rs; | 6163 | // BLX 1 for armv5t and above |
| 6969 | // DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst); | 6164 | uint32 tmp = cpu->Reg[15]; |
| 6970 | RDHI = BITS(rst, 32, 63); | 6165 | blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component; |
| 6971 | RDLO = BITS(rst, 0, 31); | 6166 | cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC; |
| 6972 | 6167 | cpu->Reg[14] = ((tmp + 2) | 1); | |
| 6973 | if (inst_cream->S) { | 6168 | cpu->TFlag = 0; |
| 6974 | cpu->NFlag = BIT(RDHI, 31); | 6169 | INC_PC(sizeof(blx_1_thumb)); |
| 6975 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); | 6170 | goto DISPATCH; |
| 6976 | } | 6171 | } |
| 6977 | } | 6172 | |
| 6978 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6173 | UQADD8_INST: |
| 6979 | INC_PC(sizeof(umull_inst)); | 6174 | UQADD16_INST: |
| 6980 | FETCH_INST; | 6175 | UQADDSUBX_INST: |
| 6981 | GOTO_NEXT_INST; | 6176 | UQSUB8_INST: |
| 6982 | } | 6177 | UQSUB16_INST: |
| 6983 | B_2_THUMB: | 6178 | UQSUBADDX_INST: |
| 6984 | { | 6179 | { |
| 6985 | INC_ICOUNTER; | 6180 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 6986 | b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component; | 6181 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 6987 | cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; | 6182 | |
| 6988 | //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]); | 6183 | const u8 op2 = inst_cream->op2; |
| 6989 | INC_PC(sizeof(b_2_thumb)); | 6184 | const u32 rm_val = RM; |
| 6990 | goto DISPATCH; | 6185 | const u32 rn_val = RN; |
| 6991 | } | 6186 | |
| 6992 | B_COND_THUMB: | 6187 | u16 lo_val = 0; |
| 6993 | { | 6188 | u16 hi_val = 0; |
| 6994 | INC_ICOUNTER; | 6189 | |
| 6995 | b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component; | 6190 | // UQADD16 |
| 6996 | if(CondPassed(cpu, inst_cream->cond)) | 6191 | if (op2 == 0x00) { |
| 6997 | cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; | 6192 | lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF); |
| 6998 | else | 6193 | hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); |
| 6999 | cpu->Reg[15] += 2; | 6194 | } |
| 7000 | //DEBUG_LOG(ARM11, " B_COND_THUMB: imm=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[15]); | 6195 | // UQASX |
| 7001 | INC_PC(sizeof(b_cond_thumb)); | 6196 | else if (op2 == 0x01) { |
| 7002 | goto DISPATCH; | 6197 | lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); |
| 7003 | } | 6198 | hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); |
| 7004 | BL_1_THUMB: | 6199 | } |
| 7005 | { | 6200 | // UQSAX |
| 7006 | INC_ICOUNTER; | 6201 | else if (op2 == 0x02) { |
| 7007 | bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component; | 6202 | lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); |
| 7008 | cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm; | 6203 | hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); |
| 7009 | //cpu->Reg[15] += 2; | 6204 | } |
| 7010 | //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]); | 6205 | // UQSUB16 |
| 7011 | 6206 | else if (op2 == 0x03) { | |
| 7012 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6207 | lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF); |
| 7013 | INC_PC(sizeof(bl_1_thumb)); | 6208 | hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); |
| 7014 | FETCH_INST; | 6209 | } |
| 7015 | GOTO_NEXT_INST; | 6210 | // UQADD8 |
| 7016 | 6211 | else if (op2 == 0x04) { | |
| 7017 | } | 6212 | lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) | |
| 7018 | BL_2_THUMB: | 6213 | ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8; |
| 7019 | { | 6214 | hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) | |
| 7020 | INC_ICOUNTER; | 6215 | ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8; |
| 7021 | bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component; | 6216 | } |
| 7022 | int tmp = ((cpu->Reg[15] + 2) | 1); | 6217 | // UQSUB8 |
| 7023 | cpu->Reg[15] = | 6218 | else { |
| 7024 | (cpu->Reg[14] + inst_cream->imm); | 6219 | lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) | |
| 7025 | cpu->Reg[14] = tmp; | 6220 | ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8; |
| 7026 | //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]); | 6221 | hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) | |
| 7027 | INC_PC(sizeof(bl_2_thumb)); | 6222 | ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8; |
| 7028 | goto DISPATCH; | 6223 | } |
| 7029 | } | 6224 | |
| 7030 | BLX_1_THUMB: | 6225 | RD = ((lo_val & 0xFFFF) | hi_val << 16); |
| 7031 | { | 6226 | } |
| 7032 | /* BLX 1 for armv5t and above */ | 6227 | |
| 7033 | INC_ICOUNTER; | 6228 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 7034 | uint32 tmp = cpu->Reg[15]; | 6229 | INC_PC(sizeof(generic_arm_inst)); |
| 7035 | blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component; | 6230 | FETCH_INST; |
| 7036 | cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC; | 6231 | GOTO_NEXT_INST; |
| 7037 | //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); | 6232 | } |
| 7038 | cpu->Reg[14] = ((tmp + 2) | 1); | 6233 | |
| 7039 | //(state->Reg[14] + ((tinstr & 0x07FF) << 1)) & 0xFFFFFFFC; | 6234 | USAD8_INST: |
| 7040 | /* switch to arm state from thumb state */ | 6235 | USADA8_INST: |
| 7041 | cpu->TFlag = 0; | 6236 | { |
| 7042 | //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]); | 6237 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 7043 | INC_PC(sizeof(blx_1_thumb)); | 6238 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 7044 | goto DISPATCH; | 6239 | |
| 7045 | } | 6240 | const u8 ra_idx = inst_cream->Ra; |
| 7046 | 6241 | const u32 rm_val = RM; | |
| 7047 | UQADD8_INST: | 6242 | const u32 rn_val = RN; |
| 7048 | UQADD16_INST: | 6243 | |
| 7049 | UQADDSUBX_INST: | 6244 | const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF); |
| 7050 | UQSUB8_INST: | 6245 | const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF); |
| 7051 | UQSUB16_INST: | 6246 | const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF); |
| 7052 | UQSUBADDX_INST: | 6247 | const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF); |
| 7053 | { | 6248 | |
| 7054 | INC_ICOUNTER; | 6249 | u32 finalDif = (diff1 + diff2 + diff3 + diff4); |
| 7055 | 6250 | ||
| 7056 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | 6251 | // Op is USADA8 if true. |
| 7057 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | 6252 | if (ra_idx != 15) |
| 7058 | 6253 | finalDif += cpu->Reg[ra_idx]; | |
| 7059 | const u8 op2 = inst_cream->op2; | 6254 | |
| 7060 | const u32 rm_val = RM; | 6255 | RD = finalDif; |
| 7061 | const u32 rn_val = RN; | 6256 | } |
| 7062 | 6257 | ||
| 7063 | u16 lo_val = 0; | 6258 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 7064 | u16 hi_val = 0; | 6259 | INC_PC(sizeof(generic_arm_inst)); |
| 7065 | 6260 | FETCH_INST; | |
| 7066 | // UQADD16 | 6261 | GOTO_NEXT_INST; |
| 7067 | if (op2 == 0x00) { | 6262 | } |
| 7068 | lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF); | 6263 | |
| 7069 | hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); | 6264 | USAT_INST: |
| 7070 | } | 6265 | USAT16_INST: |
| 7071 | // UQASX | 6266 | USUB16_INST: |
| 7072 | else if (op2 == 0x01) { | 6267 | USUB8_INST: |
| 7073 | lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); | 6268 | USUBADDX_INST: |
| 7074 | hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); | 6269 | UXTAB16_INST: |
| 7075 | } | 6270 | UXTB16_INST: |
| 7076 | // UQSAX | 6271 | { |
| 7077 | else if (op2 == 0x02) { | 6272 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 7078 | lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); | 6273 | uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component; |
| 7079 | hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); | 6274 | |
| 7080 | } | 6275 | const u8 rn_idx = inst_cream->Rn; |
| 7081 | // UQSUB16 | 6276 | const u32 rm_val = RM; |
| 7082 | else if (op2 == 0x03) { | 6277 | const u32 rotation = inst_cream->rotate * 8; |
| 7083 | lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF); | 6278 | const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation)); |
| 7084 | hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); | 6279 | |
| 7085 | } | 6280 | // UXTB16, otherwise UXTAB16 |
| 7086 | // UQADD8 | 6281 | if (rn_idx == 15) { |
| 7087 | else if (op2 == 0x04) { | 6282 | RD = rotated_rm & 0x00FF00FF; |
| 7088 | lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) | | 6283 | } else { |
| 7089 | ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8; | 6284 | const u32 rn_val = RN; |
| 7090 | hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) | | 6285 | const u8 lo_rotated = (rotated_rm & 0xFF); |
| 7091 | ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8; | 6286 | const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated; |
| 7092 | } | 6287 | const u8 hi_rotated = (rotated_rm >> 16) & 0xFF; |
| 7093 | // UQSUB8 | 6288 | const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated; |
| 7094 | else { | 6289 | |
| 7095 | lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) | | 6290 | RD = ((hi_result << 16) | (lo_result & 0xFFFF)); |
| 7096 | ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8; | 6291 | } |
| 7097 | hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) | | 6292 | } |
| 7098 | ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8; | 6293 | |
| 7099 | } | 6294 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 7100 | 6295 | INC_PC(sizeof(uxtab_inst)); | |
| 7101 | RD = ((lo_val & 0xFFFF) | hi_val << 16); | 6296 | FETCH_INST; |
| 7102 | } | 6297 | GOTO_NEXT_INST; |
| 7103 | 6298 | } | |
| 7104 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6299 | |
| 7105 | INC_PC(sizeof(generic_arm_inst)); | 6300 | #define VFP_INTERPRETER_IMPL |
| 7106 | FETCH_INST; | 6301 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" |
| 7107 | GOTO_NEXT_INST; | 6302 | #undef VFP_INTERPRETER_IMPL |
| 7108 | } | 6303 | MMU_EXCEPTION: |
| 7109 | 6304 | { | |
| 7110 | USAD8_INST: | 6305 | SAVE_NZCVT; |
| 7111 | USADA8_INST: | 6306 | cpu->abortSig = true; |
| 7112 | { | 6307 | cpu->Aborted = ARMul_DataAbortV; |
| 7113 | INC_ICOUNTER; | 6308 | cpu->AbortAddr = addr; |
| 7114 | 6309 | cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff; | |
| 7115 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | 6310 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; |
| 7116 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 6311 | cpu->NumInstrsToExecute = 0; |
| 7117 | 6312 | return num_instrs; | |
| 7118 | const u8 ra_idx = inst_cream->Ra; | 6313 | } |
| 7119 | const u32 rm_val = RM; | 6314 | END: |
| 7120 | const u32 rn_val = RN; | 6315 | { |
| 7121 | 6316 | SAVE_NZCVT; | |
| 7122 | const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF); | 6317 | cpu->NumInstrsToExecute = 0; |
| 7123 | const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF); | 6318 | return num_instrs; |
| 7124 | const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF); | 6319 | } |
| 7125 | const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF); | 6320 | INIT_INST_LENGTH: |
| 7126 | 6321 | { | |
| 7127 | u32 finalDif = (diff1 + diff2 + diff3 + diff4); | ||
| 7128 | |||
| 7129 | // Op is USADA8 if true. | ||
| 7130 | if (ra_idx != 15) | ||
| 7131 | finalDif += cpu->Reg[ra_idx]; | ||
| 7132 | |||
| 7133 | RD = finalDif; | ||
| 7134 | } | ||
| 7135 | |||
| 7136 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 7137 | INC_PC(sizeof(generic_arm_inst)); | ||
| 7138 | FETCH_INST; | ||
| 7139 | GOTO_NEXT_INST; | ||
| 7140 | } | ||
| 7141 | |||
| 7142 | USAT_INST: | ||
| 7143 | USAT16_INST: | ||
| 7144 | USUB16_INST: | ||
| 7145 | USUB8_INST: | ||
| 7146 | USUBADDX_INST: | ||
| 7147 | |||
| 7148 | UXTAB16_INST: | ||
| 7149 | UXTB16_INST: | ||
| 7150 | { | ||
| 7151 | INC_ICOUNTER; | ||
| 7152 | |||
| 7153 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 7154 | uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component; | ||
| 7155 | |||
| 7156 | const u8 rn_idx = inst_cream->Rn; | ||
| 7157 | const u32 rm_val = RM; | ||
| 7158 | const u32 rotation = inst_cream->rotate * 8; | ||
| 7159 | const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation)); | ||
| 7160 | |||
| 7161 | // UXTB16, otherwise UXTAB16 | ||
| 7162 | if (rn_idx == 15) { | ||
| 7163 | RD = rotated_rm & 0x00FF00FF; | ||
| 7164 | } | ||
| 7165 | else { | ||
| 7166 | const u32 rn_val = RN; | ||
| 7167 | |||
| 7168 | const u8 lo_rotated = (rotated_rm & 0xFF); | ||
| 7169 | const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated; | ||
| 7170 | |||
| 7171 | const u8 hi_rotated = (rotated_rm >> 16) & 0xFF; | ||
| 7172 | const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated; | ||
| 7173 | |||
| 7174 | RD = ((hi_result << 16) | (lo_result & 0xFFFF)); | ||
| 7175 | } | ||
| 7176 | } | ||
| 7177 | |||
| 7178 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 7179 | INC_PC(sizeof(uxtab_inst)); | ||
| 7180 | FETCH_INST; | ||
| 7181 | GOTO_NEXT_INST; | ||
| 7182 | } | ||
| 7183 | |||
| 7184 | #define VFP_INTERPRETER_IMPL | ||
| 7185 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | ||
| 7186 | #undef VFP_INTERPRETER_IMPL | ||
| 7187 | MMU_EXCEPTION: | ||
| 7188 | { | ||
| 7189 | SAVE_NZCVT; | ||
| 7190 | cpu->abortSig = true; | ||
| 7191 | cpu->Aborted = ARMul_DataAbortV; | ||
| 7192 | cpu->AbortAddr = addr; | ||
| 7193 | cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff; | ||
| 7194 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; | ||
| 7195 | cpu->NumInstrsToExecute = 0; | ||
| 7196 | return num_instrs; | ||
| 7197 | } | ||
| 7198 | END: | ||
| 7199 | { | ||
| 7200 | SAVE_NZCVT; | ||
| 7201 | cpu->NumInstrsToExecute = 0; | ||
| 7202 | return num_instrs; | ||
| 7203 | } | ||
| 7204 | INIT_INST_LENGTH: | ||
| 7205 | { | ||
| 7206 | #if 0 | ||
| 7207 | DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel)); | ||
| 7208 | for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++) | ||
| 7209 | DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]); | ||
| 7210 | DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel)); | ||
| 7211 | #endif | ||
| 7212 | #if defined __GNUC__ || defined __clang__ | 6322 | #if defined __GNUC__ || defined __clang__ |
| 7213 | InterpreterInitInstLength((unsigned long long int *)InstLabel, sizeof(InstLabel)); | 6323 | InterpreterInitInstLength((unsigned long long int *)InstLabel, sizeof(InstLabel)); |
| 7214 | #endif | ||
| 7215 | #if 0 | ||
| 7216 | for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++) | ||
| 7217 | DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]); | ||
| 7218 | DEBUG_LOG(ARM11, "%llx\n", InstEndLabel[1]); | ||
| 7219 | DEBUG_LOG(ARM11, "%llx\n", InstLabel[1]); | ||
| 7220 | DEBUG_LOG(ARM11, "%lld\n", (char *)InstEndLabel[1] - (char *)InstLabel[1]); | ||
| 7221 | #endif | 6324 | #endif |
| 7222 | cpu->NumInstrsToExecute = 0; | 6325 | cpu->NumInstrsToExecute = 0; |
| 7223 | return num_instrs; | 6326 | return num_instrs; |
| 7224 | } | 6327 | } |
| 7225 | } | 6328 | } |
| 7226 | |||
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 @@ | |||
| 1 | /* Copyright (C) | 1 | // Copyright 2012 Michael Kang, 2014 Citra Emulator Project |
| 2 | * 2011 - Michael.Kang blackfin.kang@gmail.com | 2 | // Licensed under GPLv2 or any later version |
| 3 | * This program is free software; you can redistribute it and/or | 3 | // Refer to the license.txt file included. |
| 4 | * modify it under the terms of the GNU General Public License | ||
| 5 | * as published by the Free Software Foundation; either version 2 | ||
| 6 | * of the License, or (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program; if not, write to the Free Software | ||
| 15 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | /** | ||
| 19 | * @file arm_dyncom_run.cpp | ||
| 20 | * @brief The dyncom run implementation for arm | ||
| 21 | * @author Michael.Kang blackfin.kang@gmail.com | ||
| 22 | * @version 78.77 | ||
| 23 | * @date 2011-11-20 | ||
| 24 | */ | ||
| 25 | 4 | ||
| 26 | #include <assert.h> | 5 | #include <assert.h> |
| 27 | 6 | ||
| 28 | #include "core/arm/skyeye_common/armdefs.h" | 7 | #include "core/arm/skyeye_common/armdefs.h" |
| 29 | 8 | ||
| 30 | void switch_mode(arm_core_t *core, uint32_t mode) | 9 | void switch_mode(arm_core_t *core, uint32_t mode) { |
| 31 | { | 10 | if (core->Mode == mode) |
| 32 | if (core->Mode == mode) { | ||
| 33 | //Mode not changed. | ||
| 34 | //printf("mode not changed\n"); | ||
| 35 | return; | 11 | return; |
| 36 | } | 12 | |
| 37 | //printf("%d --->>> %d\n", core->Mode, mode); | ||
| 38 | //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); | ||
| 39 | if (mode != USERBANK) { | 13 | if (mode != USERBANK) { |
| 40 | switch (core->Mode) { | 14 | switch (core->Mode) { |
| 41 | case USER32MODE: | 15 | case USER32MODE: |
| @@ -109,11 +83,8 @@ void switch_mode(arm_core_t *core, uint32_t mode) | |||
| 109 | 83 | ||
| 110 | } | 84 | } |
| 111 | core->Mode = mode; | 85 | core->Mode = mode; |
| 112 | //printf("In %si end, Cpsr=0x%x, R15=0x%x, last_pc=0x%x, cpsr=0x%x, spsr_copy=0x%x, icounter=%lld\n", __FUNCTION__, core->Cpsr, core->Reg[15], core->last_pc, core->Cpsr, core->Spsr_copy, core->icounter); | 86 | } else { |
| 113 | //printf("\n--------------------------------------\n"); | 87 | LOG_CRITICAL(Core_ARM11, "user mode"); |
| 114 | } | ||
| 115 | else { | ||
| 116 | printf("user mode\n"); | ||
| 117 | exit(-2); | 88 | exit(-2); |
| 118 | } | 89 | } |
| 119 | } | 90 | } |
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp index e10f2f9ee..de70ca8ae 100644 --- a/src/core/arm/dyncom/arm_dyncom_thumb.cpp +++ b/src/core/arm/dyncom/arm_dyncom_thumb.cpp | |||
| @@ -1,35 +1,13 @@ | |||
| 1 | /* Copyright (C) | 1 | // Copyright 2012 Michael Kang, 2014 Citra Emulator Project |
| 2 | * 2011 - Michael.Kang blackfin.kang@gmail.com | 2 | // Licensed under GPLv2 or any later version |
| 3 | * This program is free software; you can redistribute it and/or | 3 | // Refer to the license.txt file included. |
| 4 | * modify it under the terms of the GNU General Public License | 4 | |
| 5 | * as published by the Free Software Foundation; either version 2 | 5 | // We can provide simple Thumb simulation by decoding the Thumb instruction into its corresponding |
| 6 | * of the License, or (at your option) any later version. | 6 | // ARM instruction, and using the existing ARM simulator. |
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program; if not, write to the Free Software | ||
| 15 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | /** | ||
| 19 | * @file arm_dyncom_thumb.c | ||
| 20 | * @brief The thumb dynamic interpreter | ||
| 21 | * @author Michael.Kang blackfin.kang@gmail.com | ||
| 22 | * @version 78.77 | ||
| 23 | * @date 2011-11-07 | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* We can provide simple Thumb simulation by decoding the Thumb | ||
| 27 | instruction into its corresponding ARM instruction, and using the | ||
| 28 | existing ARM simulator. */ | ||
| 29 | 7 | ||
| 30 | #include "core/arm/skyeye_common/skyeye_defs.h" | 8 | #include "core/arm/skyeye_common/skyeye_defs.h" |
| 31 | 9 | ||
| 32 | #ifndef MODET /* required for the Thumb instruction support */ | 10 | #ifndef MODET // Required for the Thumb instruction support |
| 33 | #if 1 | 11 | #if 1 |
| 34 | #error "MODET needs to be defined for the Thumb world to work" | 12 | #error "MODET needs to be defined for the Thumb world to work" |
| 35 | #else | 13 | #else |
| @@ -40,482 +18,359 @@ existing ARM simulator. */ | |||
| 40 | #include "core/arm/skyeye_common/armos.h" | 18 | #include "core/arm/skyeye_common/armos.h" |
| 41 | #include "core/arm/dyncom/arm_dyncom_thumb.h" | 19 | #include "core/arm/dyncom/arm_dyncom_thumb.h" |
| 42 | 20 | ||
| 43 | /* Decode a 16bit Thumb instruction. The instruction is in the low | 21 | // Decode a 16bit Thumb instruction. The instruction is in the low 16-bits of the tinstr field, |
| 44 | 16-bits of the tinstr field, with the following Thumb instruction | 22 | // with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions |
| 45 | held in the high 16-bits. Passing in two Thumb instructions allows | 23 | // allows easier simulation of the special dual BL instruction. |
| 46 | easier simulation of the special dual BL instruction. */ | ||
| 47 | 24 | ||
| 48 | tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size) | 25 | tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size) { |
| 49 | { | ||
| 50 | tdstate valid = t_uninitialized; | 26 | tdstate valid = t_uninitialized; |
| 51 | ARMword next_instr; | 27 | ARMword tinstr; |
| 52 | ARMword tinstr; | 28 | tinstr = instr; |
| 53 | tinstr = instr; | 29 | |
| 54 | /* The endian should be judge here */ | 30 | // The endian should be judge here |
| 55 | #if 0 | 31 | if((addr & 0x3) != 0) |
| 56 | if (state->bigendSig) { | 32 | tinstr = instr >> 16; |
| 57 | next_instr = tinstr & 0xFFFF; | 33 | else |
| 58 | tinstr >>= 16; | 34 | tinstr &= 0xFFFF; |
| 59 | } | 35 | |
| 60 | else { | 36 | *ainstr = 0xDEADC0DE; // Debugging to catch non updates |
| 61 | next_instr = tinstr >> 16; | 37 | |
| 62 | tinstr &= 0xFFFF; | 38 | switch ((tinstr & 0xF800) >> 11) { |
| 63 | } | 39 | case 0: // LSL |
| 64 | #endif | 40 | case 1: // LSR |
| 65 | if((addr & 0x3) != 0) | 41 | case 2: // ASR |
| 66 | tinstr = instr >> 16; | 42 | *ainstr = 0xE1B00000 // base opcode |
| 67 | else | 43 | | ((tinstr & 0x1800) >> (11 - 5)) // shift type |
| 68 | tinstr &= 0xFFFF; | 44 | |((tinstr & 0x07C0) << (7 - 6)) // imm5 |
| 69 | 45 | |((tinstr & 0x0038) >> 3) // Rs | |
| 70 | //printf("In %s, instr=0x%x, tinstr=0x%x, r15=0x%x\n", __FUNCTION__, instr, tinstr, cpu->translate_pc); | 46 | |((tinstr & 0x0007) << 12); // Rd |
| 71 | #if 1 /* debugging to catch non updates */ | 47 | break; |
| 72 | *ainstr = 0xDEADC0DE; | 48 | |
| 73 | #endif | 49 | case 3: // ADD/SUB |
| 50 | { | ||
| 51 | ARMword subset[4] = { | ||
| 52 | 0xE0900000, // ADDS Rd,Rs,Rn | ||
| 53 | 0xE0500000, // SUBS Rd,Rs,Rn | ||
| 54 | 0xE2900000, // ADDS Rd,Rs,#imm3 | ||
| 55 | 0xE2500000 // SUBS Rd,Rs,#imm3 | ||
| 56 | }; | ||
| 57 | // It is quicker indexing into a table, than performing switch or conditionals: | ||
| 58 | *ainstr = subset[(tinstr & 0x0600) >> 9] // base opcode | ||
| 59 | |((tinstr & 0x01C0) >> 6) // Rn or imm3 | ||
| 60 | |((tinstr & 0x0038) << (16 - 3)) // Rs | ||
| 61 | |((tinstr & 0x0007) << (12 - 0)); // Rd | ||
| 62 | } | ||
| 63 | break; | ||
| 64 | |||
| 65 | case 4: // MOV | ||
| 66 | case 5: // CMP | ||
| 67 | case 6: // ADD | ||
| 68 | case 7: // SUB | ||
| 69 | { | ||
| 70 | ARMword subset[4] = { | ||
| 71 | 0xE3B00000, // MOVS Rd,#imm8 | ||
| 72 | 0xE3500000, // CMP Rd,#imm8 | ||
| 73 | 0xE2900000, // ADDS Rd,Rd,#imm8 | ||
| 74 | 0xE2500000, // SUBS Rd,Rd,#imm8 | ||
| 75 | }; | ||
| 76 | |||
| 77 | *ainstr = subset[(tinstr & 0x1800) >> 11] // base opcode | ||
| 78 | |((tinstr & 0x00FF) >> 0) // imm8 | ||
| 79 | |((tinstr & 0x0700) << (16 - 8)) // Rn | ||
| 80 | |((tinstr & 0x0700) << (12 - 8)); // Rd | ||
| 81 | } | ||
| 82 | break; | ||
| 83 | |||
| 84 | case 8: // Arithmetic and high register transfers | ||
| 85 | |||
| 86 | // TODO: Since the subsets for both Format 4 and Format 5 instructions are made up of | ||
| 87 | // different ARM encodings, we could save the following conditional, and just have one | ||
| 88 | // large subset | ||
| 89 | |||
| 90 | if ((tinstr & (1 << 10)) == 0) { | ||
| 91 | enum otype { | ||
| 92 | t_norm, | ||
| 93 | t_shift, | ||
| 94 | t_neg, | ||
| 95 | t_mul | ||
| 96 | }; | ||
| 97 | |||
| 98 | struct { | ||
| 99 | ARMword opcode; | ||
| 100 | otype type; | ||
| 101 | } subset[16] = { | ||
| 102 | { 0xE0100000, t_norm }, // ANDS Rd,Rd,Rs | ||
| 103 | { 0xE0300000, t_norm }, // EORS Rd,Rd,Rs | ||
| 104 | { 0xE1B00010, t_shift }, // MOVS Rd,Rd,LSL Rs | ||
| 105 | { 0xE1B00030, t_shift }, // MOVS Rd,Rd,LSR Rs | ||
| 106 | { 0xE1B00050, t_shift }, // MOVS Rd,Rd,ASR Rs | ||
| 107 | { 0xE0B00000, t_norm }, // ADCS Rd,Rd,Rs | ||
| 108 | { 0xE0D00000, t_norm }, // SBCS Rd,Rd,Rs | ||
| 109 | { 0xE1B00070, t_shift }, // MOVS Rd,Rd,ROR Rs | ||
| 110 | { 0xE1100000, t_norm }, // TST Rd,Rs | ||
| 111 | { 0xE2700000, t_neg }, // RSBS Rd,Rs,#0 | ||
| 112 | { 0xE1500000, t_norm }, // CMP Rd,Rs | ||
| 113 | { 0xE1700000, t_norm }, // CMN Rd,Rs | ||
| 114 | { 0xE1900000, t_norm }, // ORRS Rd,Rd,Rs | ||
| 115 | { 0xE0100090, t_mul }, // MULS Rd,Rd,Rs | ||
| 116 | { 0xE1D00000, t_norm }, // BICS Rd,Rd,Rs | ||
| 117 | { 0xE1F00000, t_norm } // MVNS Rd,Rs | ||
| 118 | }; | ||
| 119 | |||
| 120 | *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; // base | ||
| 121 | |||
| 122 | switch (subset[(tinstr & 0x03C0) >> 6].type) { | ||
| 123 | case t_norm: | ||
| 124 | *ainstr |= ((tinstr & 0x0007) << 16) // Rn | ||
| 125 | |((tinstr & 0x0007) << 12) // Rd | ||
| 126 | |((tinstr & 0x0038) >> 3); // Rs | ||
| 127 | break; | ||
| 128 | case t_shift: | ||
| 129 | *ainstr |= ((tinstr & 0x0007) << 12) // Rd | ||
| 130 | |((tinstr & 0x0007) >> 0) // Rm | ||
| 131 | |((tinstr & 0x0038) << (8 - 3)); // Rs | ||
| 132 | break; | ||
| 133 | case t_neg: | ||
| 134 | *ainstr |= ((tinstr & 0x0007) << 12) // Rd | ||
| 135 | |((tinstr & 0x0038) << (16 - 3)); // Rn | ||
| 136 | break; | ||
| 137 | case t_mul: | ||
| 138 | *ainstr |= ((tinstr & 0x0007) << 16) // Rd | ||
| 139 | |((tinstr & 0x0007) << 8) // Rs | ||
| 140 | |((tinstr & 0x0038) >> 3); // Rm | ||
| 141 | break; | ||
| 142 | } | ||
| 143 | } else { | ||
| 144 | ARMword Rd = ((tinstr & 0x0007) >> 0); | ||
| 145 | ARMword Rs = ((tinstr & 0x0038) >> 3); | ||
| 146 | |||
| 147 | if (tinstr & (1 << 7)) | ||
| 148 | Rd += 8; | ||
| 149 | if (tinstr & (1 << 6)) | ||
| 150 | Rs += 8; | ||
| 151 | |||
| 152 | switch ((tinstr & 0x03C0) >> 6) { | ||
| 153 | case 0x1: // ADD Rd,Rd,Hs | ||
| 154 | case 0x2: // ADD Hd,Hd,Rs | ||
| 155 | case 0x3: // ADD Hd,Hd,Hs | ||
| 156 | *ainstr = 0xE0800000 // base | ||
| 157 | | (Rd << 16) // Rn | ||
| 158 | |(Rd << 12) // Rd | ||
| 159 | |(Rs << 0); // Rm | ||
| 160 | break; | ||
| 161 | case 0x5: // CMP Rd,Hs | ||
| 162 | case 0x6: // CMP Hd,Rs | ||
| 163 | case 0x7: // CMP Hd,Hs | ||
| 164 | *ainstr = 0xE1500000 // base | ||
| 165 | | (Rd << 16) // Rn | ||
| 166 | |(Rd << 12) // Rd | ||
| 167 | |(Rs << 0); // Rm | ||
| 168 | break; | ||
| 169 | case 0x9: // MOV Rd,Hs | ||
| 170 | case 0xA: // MOV Hd,Rs | ||
| 171 | case 0xB: // MOV Hd,Hs | ||
| 172 | *ainstr = 0xE1A00000 // base | ||
| 173 | | (Rd << 16) // Rn | ||
| 174 | |(Rd << 12) // Rd | ||
| 175 | |(Rs << 0); // Rm | ||
| 176 | break; | ||
| 177 | case 0xC: // BX Rs | ||
| 178 | case 0xD: // BX Hs | ||
| 179 | *ainstr = 0xE12FFF10 // base | ||
| 180 | | ((tinstr & 0x0078) >> 3); // Rd | ||
| 181 | break; | ||
| 182 | case 0x0: // UNDEFINED | ||
| 183 | case 0x4: // UNDEFINED | ||
| 184 | case 0x8: // UNDEFINED | ||
| 185 | valid = t_undefined; | ||
| 186 | break; | ||
| 187 | case 0xE: // BLX | ||
| 188 | case 0xF: // BLX | ||
| 189 | *ainstr = 0xE1200030 // base | ||
| 190 | | (Rs << 0); // Rm | ||
| 191 | break; | ||
| 192 | } | ||
| 193 | } | ||
| 194 | break; | ||
| 195 | |||
| 196 | case 9: // LDR Rd,[PC,#imm8] | ||
| 197 | *ainstr = 0xE59F0000 // base | ||
| 198 | | ((tinstr & 0x0700) << (12 - 8)) // Rd | ||
| 199 | |((tinstr & 0x00FF) << (2 - 0)); // off8 | ||
| 200 | break; | ||
| 201 | |||
| 202 | case 10: | ||
| 203 | case 11: | ||
| 204 | // TODO: Format 7 and Format 8 perform the same ARM encoding, so the following could be | ||
| 205 | // merged into a single subset, saving on the following boolean: | ||
| 206 | |||
| 207 | if ((tinstr & (1 << 9)) == 0) { | ||
| 208 | ARMword subset[4] = { | ||
| 209 | 0xE7800000, // STR Rd,[Rb,Ro] | ||
| 210 | 0xE7C00000, // STRB Rd,[Rb,Ro] | ||
| 211 | 0xE7900000, // LDR Rd,[Rb,Ro] | ||
| 212 | 0xE7D00000 // LDRB Rd,[Rb,Ro] | ||
| 213 | }; | ||
| 214 | |||
| 215 | *ainstr = subset[(tinstr & 0x0C00) >> 10] // base | ||
| 216 | |((tinstr & 0x0007) << (12 - 0)) // Rd | ||
| 217 | |((tinstr & 0x0038) << (16 - 3)) // Rb | ||
| 218 | |((tinstr & 0x01C0) >> 6); // Ro | ||
| 219 | |||
| 220 | } else { | ||
| 221 | ARMword subset[4] = { | ||
| 222 | 0xE18000B0, // STRH Rd,[Rb,Ro] | ||
| 223 | 0xE19000D0, // LDRSB Rd,[Rb,Ro] | ||
| 224 | 0xE19000B0, // LDRH Rd,[Rb,Ro] | ||
| 225 | 0xE19000F0 // LDRSH Rd,[Rb,Ro] | ||
| 226 | }; | ||
| 227 | *ainstr = subset[(tinstr & 0x0C00) >> 10] // base | ||
| 228 | |((tinstr & 0x0007) << (12 - 0)) // Rd | ||
| 229 | |((tinstr & 0x0038) << (16 - 3)) // Rb | ||
| 230 | |((tinstr & 0x01C0) >> 6); // Ro | ||
| 231 | } | ||
| 232 | break; | ||
| 233 | |||
| 234 | case 12: // STR Rd,[Rb,#imm5] | ||
| 235 | case 13: // LDR Rd,[Rb,#imm5] | ||
| 236 | case 14: // STRB Rd,[Rb,#imm5] | ||
| 237 | case 15: // LDRB Rd,[Rb,#imm5] | ||
| 238 | { | ||
| 239 | ARMword subset[4] = { | ||
| 240 | 0xE5800000, // STR Rd,[Rb,#imm5] | ||
| 241 | 0xE5900000, // LDR Rd,[Rb,#imm5] | ||
| 242 | 0xE5C00000, // STRB Rd,[Rb,#imm5] | ||
| 243 | 0xE5D00000 // LDRB Rd,[Rb,#imm5] | ||
| 244 | }; | ||
| 245 | // The offset range defends on whether we are transferring a byte or word value: | ||
| 246 | *ainstr = subset[(tinstr & 0x1800) >> 11] // base | ||
| 247 | |((tinstr & 0x0007) << (12 - 0)) // Rd | ||
| 248 | |((tinstr & 0x0038) << (16 - 3)) // Rb | ||
| 249 | |((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); // off5 | ||
| 250 | } | ||
| 251 | break; | ||
| 252 | |||
| 253 | case 16: // STRH Rd,[Rb,#imm5] | ||
| 254 | case 17: // LDRH Rd,[Rb,#imm5] | ||
| 255 | *ainstr = ((tinstr & (1 << 11)) // base | ||
| 256 | ? 0xE1D000B0 // LDRH | ||
| 257 | : 0xE1C000B0) // STRH | ||
| 258 | |((tinstr & 0x0007) << (12 - 0)) // Rd | ||
| 259 | |((tinstr & 0x0038) << (16 - 3)) // Rb | ||
| 260 | |((tinstr & 0x01C0) >> (6 - 1)) // off5, low nibble | ||
| 261 | |((tinstr & 0x0600) >> (9 - 8)); // off5, high nibble | ||
| 262 | break; | ||
| 263 | |||
| 264 | case 18: // STR Rd,[SP,#imm8] | ||
| 265 | case 19: // LDR Rd,[SP,#imm8] | ||
| 266 | *ainstr = ((tinstr & (1 << 11)) // base | ||
| 267 | ? 0xE59D0000 // LDR | ||
| 268 | : 0xE58D0000) // STR | ||
| 269 | |((tinstr & 0x0700) << (12 - 8)) // Rd | ||
| 270 | |((tinstr & 0x00FF) << 2); // off8 | ||
| 271 | break; | ||
| 272 | |||
| 273 | case 20: // ADD Rd,PC,#imm8 | ||
| 274 | case 21: // ADD Rd,SP,#imm8 | ||
| 275 | |||
| 276 | if ((tinstr & (1 << 11)) == 0) { | ||
| 277 | |||
| 278 | // NOTE: The PC value used here should by word aligned. We encode shift-left-by-2 in the | ||
| 279 | // rotate immediate field, so no shift of off8 is needed. | ||
| 280 | |||
| 281 | *ainstr = 0xE28F0F00 // base | ||
| 282 | | ((tinstr & 0x0700) << (12 - 8)) // Rd | ||
| 283 | |(tinstr & 0x00FF); // off8 | ||
| 284 | } else { | ||
| 285 | // We encode shift-left-by-2 in the rotate immediate field, so no shift of off8 is needed. | ||
| 286 | *ainstr = 0xE28D0F00 // base | ||
| 287 | | ((tinstr & 0x0700) << (12 - 8)) // Rd | ||
| 288 | |(tinstr & 0x00FF); // off8 | ||
| 289 | } | ||
| 290 | break; | ||
| 291 | |||
| 292 | case 22: | ||
| 293 | case 23: | ||
| 294 | if ((tinstr & 0x0F00) == 0x0000) { | ||
| 295 | // NOTE: The instruction contains a shift left of 2 equivalent (implemented as ROR #30): | ||
| 296 | *ainstr = ((tinstr & (1 << 7)) // base | ||
| 297 | ? 0xE24DDF00 // SUB | ||
| 298 | : 0xE28DDF00) // ADD | ||
| 299 | |(tinstr & 0x007F); // off7 | ||
| 300 | } else if ((tinstr & 0x0F00) == 0x0e00) | ||
| 301 | *ainstr = 0xEF000000 | SWI_Breakpoint; | ||
| 302 | else { | ||
| 303 | ARMword subset[4] = { | ||
| 304 | 0xE92D0000, // STMDB sp!,{rlist} | ||
| 305 | 0xE92D4000, // STMDB sp!,{rlist,lr} | ||
| 306 | 0xE8BD0000, // LDMIA sp!,{rlist} | ||
| 307 | 0xE8BD8000 // LDMIA sp!,{rlist,pc} | ||
| 308 | }; | ||
| 309 | *ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)] // base | ||
| 310 | |(tinstr & 0x00FF); // mask8 | ||
| 311 | } | ||
| 312 | break; | ||
| 313 | |||
| 314 | case 24: // STMIA | ||
| 315 | case 25: // LDMIA | ||
| 316 | *ainstr = ((tinstr & (1 << 11)) // base | ||
| 317 | ? 0xE8B00000 // LDMIA | ||
| 318 | : 0xE8A00000) // STMIA | ||
| 319 | |((tinstr & 0x0700) << (16 - 8)) // Rb | ||
| 320 | |(tinstr & 0x00FF); // mask8 | ||
| 321 | break; | ||
| 322 | |||
| 323 | case 26: // Bcc | ||
| 324 | case 27: // Bcc/SWI | ||
| 325 | if ((tinstr & 0x0F00) == 0x0F00) { | ||
| 326 | // Format 17 : SWI | ||
| 327 | *ainstr = 0xEF000000; | ||
| 328 | // Breakpoint must be handled specially. | ||
| 329 | if ((tinstr & 0x00FF) == 0x18) | ||
| 330 | *ainstr |= ((tinstr & 0x00FF) << 16); | ||
| 331 | // New breakpoint value. See gdb/arm-tdep.c | ||
| 332 | else if ((tinstr & 0x00FF) == 0xFE) | ||
| 333 | *ainstr |= SWI_Breakpoint; | ||
| 334 | else | ||
| 335 | *ainstr |= (tinstr & 0x00FF); | ||
| 336 | } else if ((tinstr & 0x0F00) != 0x0E00) | ||
| 337 | valid = t_branch; | ||
| 338 | else // UNDEFINED : cc=1110(AL) uses different format | ||
| 339 | valid = t_undefined; | ||
| 340 | |||
| 341 | break; | ||
| 342 | |||
| 343 | case 28: // B | ||
| 344 | valid = t_branch; | ||
| 345 | break; | ||
| 346 | |||
| 347 | case 29: | ||
| 348 | if(tinstr & 0x1) | ||
| 349 | valid = t_undefined; | ||
| 350 | else | ||
| 351 | valid = t_branch; | ||
| 352 | break; | ||
| 353 | |||
| 354 | case 30: // BL instruction 1 | ||
| 355 | |||
| 356 | // There is no single ARM instruction equivalent for this Thumb instruction. To keep the | ||
| 357 | // simulation simple (from the user perspective) we check if the following instruction is | ||
| 358 | // the second half of this BL, and if it is we simulate it immediately | ||
| 359 | |||
| 360 | valid = t_branch; | ||
| 361 | break; | ||
| 362 | |||
| 363 | case 31: // BL instruction 2 | ||
| 364 | |||
| 365 | // There is no single ARM instruction equivalent for this instruction. Also, it should only | ||
| 366 | // ever be matched with the fmt19 "BL instruction 1" instruction. However, we do allow the | ||
| 367 | // simulation of it on its own, with undefined results if r14 is not suitably initialised. | ||
| 368 | |||
| 369 | valid = t_branch; | ||
| 370 | break; | ||
| 371 | } | ||
| 372 | |||
| 373 | *inst_size = 2; | ||
| 74 | 374 | ||
| 75 | switch ((tinstr & 0xF800) >> 11) { | 375 | return valid; |
| 76 | case 0: /* LSL */ | ||
| 77 | case 1: /* LSR */ | ||
| 78 | case 2: /* ASR */ | ||
| 79 | /* Format 1 */ | ||
| 80 | *ainstr = 0xE1B00000 /* base opcode */ | ||
| 81 | | ((tinstr & 0x1800) >> (11 - 5)) /* shift type */ | ||
| 82 | |((tinstr & 0x07C0) << (7 - 6)) /* imm5 */ | ||
| 83 | |((tinstr & 0x0038) >> 3) /* Rs */ | ||
| 84 | |((tinstr & 0x0007) << 12); /* Rd */ | ||
| 85 | break; | ||
| 86 | case 3: /* ADD/SUB */ | ||
| 87 | /* Format 2 */ | ||
| 88 | { | ||
| 89 | ARMword subset[4] = { | ||
| 90 | 0xE0900000, /* ADDS Rd,Rs,Rn */ | ||
| 91 | 0xE0500000, /* SUBS Rd,Rs,Rn */ | ||
| 92 | 0xE2900000, /* ADDS Rd,Rs,#imm3 */ | ||
| 93 | 0xE2500000 /* SUBS Rd,Rs,#imm3 */ | ||
| 94 | }; | ||
| 95 | /* It is quicker indexing into a table, than performing switch | ||
| 96 | or conditionals: */ | ||
| 97 | *ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */ | ||
| 98 | |((tinstr & 0x01C0) >> 6) /* Rn or imm3 */ | ||
| 99 | |((tinstr & 0x0038) << (16 - 3)) /* Rs */ | ||
| 100 | |((tinstr & 0x0007) << (12 - 0)); /* Rd */ | ||
| 101 | } | ||
| 102 | break; | ||
| 103 | case 4: /* MOV */ | ||
| 104 | case 5: /* CMP */ | ||
| 105 | case 6: /* ADD */ | ||
| 106 | case 7: /* SUB */ | ||
| 107 | /* Format 3 */ | ||
| 108 | { | ||
| 109 | ARMword subset[4] = { | ||
| 110 | 0xE3B00000, /* MOVS Rd,#imm8 */ | ||
| 111 | 0xE3500000, /* CMP Rd,#imm8 */ | ||
| 112 | 0xE2900000, /* ADDS Rd,Rd,#imm8 */ | ||
| 113 | 0xE2500000, /* SUBS Rd,Rd,#imm8 */ | ||
| 114 | }; | ||
| 115 | *ainstr = subset[(tinstr & 0x1800) >> 11] /* base opcode */ | ||
| 116 | |((tinstr & 0x00FF) >> 0) /* imm8 */ | ||
| 117 | |((tinstr & 0x0700) << (16 - 8)) /* Rn */ | ||
| 118 | |((tinstr & 0x0700) << (12 - 8)); /* Rd */ | ||
| 119 | } | ||
| 120 | break; | ||
| 121 | case 8: /* Arithmetic and high register transfers */ | ||
| 122 | /* TODO: Since the subsets for both Format 4 and Format 5 | ||
| 123 | instructions are made up of different ARM encodings, we could | ||
| 124 | save the following conditional, and just have one large | ||
| 125 | subset. */ | ||
| 126 | if ((tinstr & (1 << 10)) == 0) { | ||
| 127 | typedef enum | ||
| 128 | { t_norm, t_shift, t_neg, t_mul }otype_t; | ||
| 129 | |||
| 130 | /* Format 4 */ | ||
| 131 | struct | ||
| 132 | { | ||
| 133 | ARMword opcode; | ||
| 134 | otype_t otype; | ||
| 135 | } | ||
| 136 | subset[16] = { | ||
| 137 | { | ||
| 138 | 0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */ | ||
| 139 | { | ||
| 140 | 0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */ | ||
| 141 | { | ||
| 142 | 0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */ | ||
| 143 | { | ||
| 144 | 0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */ | ||
| 145 | { | ||
| 146 | 0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */ | ||
| 147 | { | ||
| 148 | 0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */ | ||
| 149 | { | ||
| 150 | 0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */ | ||
| 151 | { | ||
| 152 | 0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */ | ||
| 153 | { | ||
| 154 | 0xE1100000, t_norm}, /* TST Rd,Rs */ | ||
| 155 | { | ||
| 156 | 0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */ | ||
| 157 | { | ||
| 158 | 0xE1500000, t_norm}, /* CMP Rd,Rs */ | ||
| 159 | { | ||
| 160 | 0xE1700000, t_norm}, /* CMN Rd,Rs */ | ||
| 161 | { | ||
| 162 | 0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */ | ||
| 163 | { | ||
| 164 | 0xE0100090, t_mul}, /* MULS Rd,Rd,Rs */ | ||
| 165 | { | ||
| 166 | 0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */ | ||
| 167 | { | ||
| 168 | 0xE1F00000, t_norm} /* MVNS Rd,Rs */ | ||
| 169 | }; | ||
| 170 | *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */ | ||
| 171 | switch (subset[(tinstr & 0x03C0) >> 6].otype) { | ||
| 172 | case t_norm: | ||
| 173 | *ainstr |= ((tinstr & 0x0007) << 16) /* Rn */ | ||
| 174 | |((tinstr & 0x0007) << 12) /* Rd */ | ||
| 175 | |((tinstr & 0x0038) >> 3); /* Rs */ | ||
| 176 | break; | ||
| 177 | case t_shift: | ||
| 178 | *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */ | ||
| 179 | |((tinstr & 0x0007) >> 0) /* Rm */ | ||
| 180 | |((tinstr & 0x0038) << (8 - 3)); /* Rs */ | ||
| 181 | break; | ||
| 182 | case t_neg: | ||
| 183 | *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */ | ||
| 184 | |((tinstr & 0x0038) << (16 - 3)); /* Rn */ | ||
| 185 | break; | ||
| 186 | case t_mul: | ||
| 187 | *ainstr |= ((tinstr & 0x0007) << 16) /* Rd */ | ||
| 188 | |((tinstr & 0x0007) << 8) /* Rs */ | ||
| 189 | |((tinstr & 0x0038) >> 3); /* Rm */ | ||
| 190 | break; | ||
| 191 | } | ||
| 192 | } | ||
| 193 | else { | ||
| 194 | /* Format 5 */ | ||
| 195 | ARMword Rd = ((tinstr & 0x0007) >> 0); | ||
| 196 | ARMword Rs = ((tinstr & 0x0038) >> 3); | ||
| 197 | if (tinstr & (1 << 7)) | ||
| 198 | Rd += 8; | ||
| 199 | if (tinstr & (1 << 6)) | ||
| 200 | Rs += 8; | ||
| 201 | switch ((tinstr & 0x03C0) >> 6) { | ||
| 202 | case 0x1: /* ADD Rd,Rd,Hs */ | ||
| 203 | case 0x2: /* ADD Hd,Hd,Rs */ | ||
| 204 | case 0x3: /* ADD Hd,Hd,Hs */ | ||
| 205 | *ainstr = 0xE0800000 /* base */ | ||
| 206 | | (Rd << 16) /* Rn */ | ||
| 207 | |(Rd << 12) /* Rd */ | ||
| 208 | |(Rs << 0); /* Rm */ | ||
| 209 | break; | ||
| 210 | case 0x5: /* CMP Rd,Hs */ | ||
| 211 | case 0x6: /* CMP Hd,Rs */ | ||
| 212 | case 0x7: /* CMP Hd,Hs */ | ||
| 213 | *ainstr = 0xE1500000 /* base */ | ||
| 214 | | (Rd << 16) /* Rn */ | ||
| 215 | |(Rd << 12) /* Rd */ | ||
| 216 | |(Rs << 0); /* Rm */ | ||
| 217 | break; | ||
| 218 | case 0x9: /* MOV Rd,Hs */ | ||
| 219 | case 0xA: /* MOV Hd,Rs */ | ||
| 220 | case 0xB: /* MOV Hd,Hs */ | ||
| 221 | *ainstr = 0xE1A00000 /* base */ | ||
| 222 | | (Rd << 16) /* Rn */ | ||
| 223 | |(Rd << 12) /* Rd */ | ||
| 224 | |(Rs << 0); /* Rm */ | ||
| 225 | break; | ||
| 226 | case 0xC: /* BX Rs */ | ||
| 227 | case 0xD: /* BX Hs */ | ||
| 228 | *ainstr = 0xE12FFF10 /* base */ | ||
| 229 | | ((tinstr & 0x0078) >> 3); /* Rd */ | ||
| 230 | break; | ||
| 231 | case 0x0: /* UNDEFINED */ | ||
| 232 | case 0x4: /* UNDEFINED */ | ||
| 233 | case 0x8: /* UNDEFINED */ | ||
| 234 | valid = t_undefined; | ||
| 235 | break; | ||
| 236 | case 0xE: /* BLX */ | ||
| 237 | case 0xF: /* BLX */ | ||
| 238 | |||
| 239 | //if (state->is_v5) { | ||
| 240 | if(1){ | ||
| 241 | //valid = t_branch; | ||
| 242 | #if 1 | ||
| 243 | *ainstr = 0xE1200030 /* base */ | ||
| 244 | |(Rs << 0); /* Rm */ | ||
| 245 | #endif | ||
| 246 | } else { | ||
| 247 | valid = t_undefined; | ||
| 248 | } | ||
| 249 | break; | ||
| 250 | } | ||
| 251 | } | ||
| 252 | break; | ||
| 253 | case 9: /* LDR Rd,[PC,#imm8] */ | ||
| 254 | /* Format 6 */ | ||
| 255 | *ainstr = 0xE59F0000 /* base */ | ||
| 256 | | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ | ||
| 257 | |((tinstr & 0x00FF) << (2 - 0)); /* off8 */ | ||
| 258 | break; | ||
| 259 | case 10: | ||
| 260 | case 11: | ||
| 261 | /* TODO: Format 7 and Format 8 perform the same ARM encoding, so | ||
| 262 | the following could be merged into a single subset, saving on | ||
| 263 | the following boolean: */ | ||
| 264 | if ((tinstr & (1 << 9)) == 0) { | ||
| 265 | /* Format 7 */ | ||
| 266 | ARMword subset[4] = { | ||
| 267 | 0xE7800000, /* STR Rd,[Rb,Ro] */ | ||
| 268 | 0xE7C00000, /* STRB Rd,[Rb,Ro] */ | ||
| 269 | 0xE7900000, /* LDR Rd,[Rb,Ro] */ | ||
| 270 | 0xE7D00000 /* LDRB Rd,[Rb,Ro] */ | ||
| 271 | }; | ||
| 272 | *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */ | ||
| 273 | |((tinstr & 0x0007) << (12 - 0)) /* Rd */ | ||
| 274 | |((tinstr & 0x0038) << (16 - 3)) /* Rb */ | ||
| 275 | |((tinstr & 0x01C0) >> 6); /* Ro */ | ||
| 276 | } | ||
| 277 | else { | ||
| 278 | /* Format 8 */ | ||
| 279 | ARMword subset[4] = { | ||
| 280 | 0xE18000B0, /* STRH Rd,[Rb,Ro] */ | ||
| 281 | 0xE19000D0, /* LDRSB Rd,[Rb,Ro] */ | ||
| 282 | 0xE19000B0, /* LDRH Rd,[Rb,Ro] */ | ||
| 283 | 0xE19000F0 /* LDRSH Rd,[Rb,Ro] */ | ||
| 284 | }; | ||
| 285 | *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */ | ||
| 286 | |((tinstr & 0x0007) << (12 - 0)) /* Rd */ | ||
| 287 | |((tinstr & 0x0038) << (16 - 3)) /* Rb */ | ||
| 288 | |((tinstr & 0x01C0) >> 6); /* Ro */ | ||
| 289 | } | ||
| 290 | break; | ||
| 291 | case 12: /* STR Rd,[Rb,#imm5] */ | ||
| 292 | case 13: /* LDR Rd,[Rb,#imm5] */ | ||
| 293 | case 14: /* STRB Rd,[Rb,#imm5] */ | ||
| 294 | case 15: /* LDRB Rd,[Rb,#imm5] */ | ||
| 295 | /* Format 9 */ | ||
| 296 | { | ||
| 297 | ARMword subset[4] = { | ||
| 298 | 0xE5800000, /* STR Rd,[Rb,#imm5] */ | ||
| 299 | 0xE5900000, /* LDR Rd,[Rb,#imm5] */ | ||
| 300 | 0xE5C00000, /* STRB Rd,[Rb,#imm5] */ | ||
| 301 | 0xE5D00000 /* LDRB Rd,[Rb,#imm5] */ | ||
| 302 | }; | ||
| 303 | /* The offset range defends on whether we are transferring a | ||
| 304 | byte or word value: */ | ||
| 305 | *ainstr = subset[(tinstr & 0x1800) >> 11] /* base */ | ||
| 306 | |((tinstr & 0x0007) << (12 - 0)) /* Rd */ | ||
| 307 | |((tinstr & 0x0038) << (16 - 3)) /* Rb */ | ||
| 308 | |((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */ | ||
| 309 | } | ||
| 310 | break; | ||
| 311 | case 16: /* STRH Rd,[Rb,#imm5] */ | ||
| 312 | case 17: /* LDRH Rd,[Rb,#imm5] */ | ||
| 313 | /* Format 10 */ | ||
| 314 | *ainstr = ((tinstr & (1 << 11)) /* base */ | ||
| 315 | ? 0xE1D000B0 /* LDRH */ | ||
| 316 | : 0xE1C000B0) /* STRH */ | ||
| 317 | |((tinstr & 0x0007) << (12 - 0)) /* Rd */ | ||
| 318 | |((tinstr & 0x0038) << (16 - 3)) /* Rb */ | ||
| 319 | |((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */ | ||
| 320 | |((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */ | ||
| 321 | break; | ||
| 322 | case 18: /* STR Rd,[SP,#imm8] */ | ||
| 323 | case 19: /* LDR Rd,[SP,#imm8] */ | ||
| 324 | /* Format 11 */ | ||
| 325 | *ainstr = ((tinstr & (1 << 11)) /* base */ | ||
| 326 | ? 0xE59D0000 /* LDR */ | ||
| 327 | : 0xE58D0000) /* STR */ | ||
| 328 | |((tinstr & 0x0700) << (12 - 8)) /* Rd */ | ||
| 329 | |((tinstr & 0x00FF) << 2); /* off8 */ | ||
| 330 | break; | ||
| 331 | case 20: /* ADD Rd,PC,#imm8 */ | ||
| 332 | case 21: /* ADD Rd,SP,#imm8 */ | ||
| 333 | /* Format 12 */ | ||
| 334 | if ((tinstr & (1 << 11)) == 0) { | ||
| 335 | /* NOTE: The PC value used here should by word aligned */ | ||
| 336 | /* We encode shift-left-by-2 in the rotate immediate field, | ||
| 337 | so no shift of off8 is needed. */ | ||
| 338 | *ainstr = 0xE28F0F00 /* base */ | ||
| 339 | | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ | ||
| 340 | |(tinstr & 0x00FF); /* off8 */ | ||
| 341 | } | ||
| 342 | else { | ||
| 343 | /* We encode shift-left-by-2 in the rotate immediate field, | ||
| 344 | so no shift of off8 is needed. */ | ||
| 345 | *ainstr = 0xE28D0F00 /* base */ | ||
| 346 | | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ | ||
| 347 | |(tinstr & 0x00FF); /* off8 */ | ||
| 348 | } | ||
| 349 | break; | ||
| 350 | case 22: | ||
| 351 | case 23: | ||
| 352 | if ((tinstr & 0x0F00) == 0x0000) { | ||
| 353 | /* Format 13 */ | ||
| 354 | /* NOTE: The instruction contains a shift left of 2 | ||
| 355 | equivalent (implemented as ROR #30): */ | ||
| 356 | *ainstr = ((tinstr & (1 << 7)) /* base */ | ||
| 357 | ? 0xE24DDF00 /* SUB */ | ||
| 358 | : 0xE28DDF00) /* ADD */ | ||
| 359 | |(tinstr & 0x007F); /* off7 */ | ||
| 360 | } | ||
| 361 | else if ((tinstr & 0x0F00) == 0x0e00) | ||
| 362 | *ainstr = 0xEF000000 | SWI_Breakpoint; | ||
| 363 | else { | ||
| 364 | /* Format 14 */ | ||
| 365 | ARMword subset[4] = { | ||
| 366 | 0xE92D0000, /* STMDB sp!,{rlist} */ | ||
| 367 | 0xE92D4000, /* STMDB sp!,{rlist,lr} */ | ||
| 368 | 0xE8BD0000, /* LDMIA sp!,{rlist} */ | ||
| 369 | 0xE8BD8000 /* LDMIA sp!,{rlist,pc} */ | ||
| 370 | }; | ||
| 371 | *ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)] /* base */ | ||
| 372 | |(tinstr & 0x00FF); /* mask8 */ | ||
| 373 | } | ||
| 374 | break; | ||
| 375 | case 24: /* STMIA */ | ||
| 376 | case 25: /* LDMIA */ | ||
| 377 | /* Format 15 */ | ||
| 378 | *ainstr = ((tinstr & (1 << 11)) /* base */ | ||
| 379 | ? 0xE8B00000 /* LDMIA */ | ||
| 380 | : 0xE8A00000) /* STMIA */ | ||
| 381 | |((tinstr & 0x0700) << (16 - 8)) /* Rb */ | ||
| 382 | |(tinstr & 0x00FF); /* mask8 */ | ||
| 383 | break; | ||
| 384 | case 26: /* Bcc */ | ||
| 385 | case 27: /* Bcc/SWI */ | ||
| 386 | if ((tinstr & 0x0F00) == 0x0F00) { | ||
| 387 | #if 0 | ||
| 388 | if (tinstr == (ARMul_ABORTWORD & 0xffff) && | ||
| 389 | state->AbortAddr == pc) { | ||
| 390 | *ainstr = ARMul_ABORTWORD; | ||
| 391 | break; | ||
| 392 | } | ||
| 393 | #endif | ||
| 394 | /* Format 17 : SWI */ | ||
| 395 | *ainstr = 0xEF000000; | ||
| 396 | /* Breakpoint must be handled specially. */ | ||
| 397 | if ((tinstr & 0x00FF) == 0x18) | ||
| 398 | *ainstr |= ((tinstr & 0x00FF) << 16); | ||
| 399 | /* New breakpoint value. See gdb/arm-tdep.c */ | ||
| 400 | else if ((tinstr & 0x00FF) == 0xFE) | ||
| 401 | *ainstr |= SWI_Breakpoint; | ||
| 402 | else | ||
| 403 | *ainstr |= (tinstr & 0x00FF); | ||
| 404 | } | ||
| 405 | else if ((tinstr & 0x0F00) != 0x0E00) { | ||
| 406 | /* Format 16 */ | ||
| 407 | #if 0 | ||
| 408 | int doit = FALSE; | ||
| 409 | /* TODO: Since we are doing a switch here, we could just add | ||
| 410 | the SWI and undefined instruction checks into this | ||
| 411 | switch to same on a couple of conditionals: */ | ||
| 412 | switch ((tinstr & 0x0F00) >> 8) { | ||
| 413 | case EQ: | ||
| 414 | doit = ZFLAG; | ||
| 415 | break; | ||
| 416 | case NE: | ||
| 417 | doit = !ZFLAG; | ||
| 418 | break; | ||
| 419 | case VS: | ||
| 420 | doit = VFLAG; | ||
| 421 | break; | ||
| 422 | case VC: | ||
| 423 | doit = !VFLAG; | ||
| 424 | break; | ||
| 425 | case MI: | ||
| 426 | doit = NFLAG; | ||
| 427 | break; | ||
| 428 | case PL: | ||
| 429 | doit = !NFLAG; | ||
| 430 | break; | ||
| 431 | case CS: | ||
| 432 | doit = CFLAG; | ||
| 433 | break; | ||
| 434 | case CC: | ||
| 435 | doit = !CFLAG; | ||
| 436 | break; | ||
| 437 | case HI: | ||
| 438 | doit = (CFLAG && !ZFLAG); | ||
| 439 | break; | ||
| 440 | case LS: | ||
| 441 | doit = (!CFLAG || ZFLAG); | ||
| 442 | break; | ||
| 443 | case GE: | ||
| 444 | doit = ((!NFLAG && !VFLAG) | ||
| 445 | || (NFLAG && VFLAG)); | ||
| 446 | break; | ||
| 447 | case LT: | ||
| 448 | doit = ((NFLAG && !VFLAG) | ||
| 449 | || (!NFLAG && VFLAG)); | ||
| 450 | break; | ||
| 451 | case GT: | ||
| 452 | doit = ((!NFLAG && !VFLAG && !ZFLAG) | ||
| 453 | || (NFLAG && VFLAG && !ZFLAG)); | ||
| 454 | break; | ||
| 455 | case LE: | ||
| 456 | doit = ((NFLAG && !VFLAG) | ||
| 457 | || (!NFLAG && VFLAG)) || ZFLAG; | ||
| 458 | break; | ||
| 459 | } | ||
| 460 | if (doit) { | ||
| 461 | state->Reg[15] = (pc + 4 | ||
| 462 | + (((tinstr & 0x7F) << 1) | ||
| 463 | | ((tinstr & (1 << 7)) ? | ||
| 464 | 0xFFFFFF00 : 0))); | ||
| 465 | FLUSHPIPE; | ||
| 466 | } | ||
| 467 | #endif | ||
| 468 | valid = t_branch; | ||
| 469 | } | ||
| 470 | else /* UNDEFINED : cc=1110(AL) uses different format */ | ||
| 471 | valid = t_undefined; | ||
| 472 | break; | ||
| 473 | case 28: /* B */ | ||
| 474 | /* Format 18 */ | ||
| 475 | #if 0 | ||
| 476 | state->Reg[15] = (pc + 4 + (((tinstr & 0x3FF) << 1) | ||
| 477 | | ((tinstr & (1 << 10)) ? | ||
| 478 | 0xFFFFF800 : 0))); | ||
| 479 | #endif | ||
| 480 | //FLUSHPIPE; | ||
| 481 | valid = t_branch; | ||
| 482 | break; | ||
| 483 | case 29: | ||
| 484 | if(tinstr & 0x1) | ||
| 485 | valid = t_undefined; | ||
| 486 | else{ | ||
| 487 | /* BLX 1 for armv5t and above */ | ||
| 488 | //printf("In %s, After BLX(1),LR=0x%x,PC=0x%x, offset=0x%x\n", __FUNCTION__, state->Reg[14], state->Reg[15], (tinstr &0x7FF) << 1); | ||
| 489 | valid = t_branch; | ||
| 490 | } | ||
| 491 | break; | ||
| 492 | case 30: /* BL instruction 1 */ | ||
| 493 | /* Format 19 */ | ||
| 494 | /* There is no single ARM instruction equivalent for this Thumb | ||
| 495 | instruction. To keep the simulation simple (from the user | ||
| 496 | perspective) we check if the following instruction is the | ||
| 497 | second half of this BL, and if it is we simulate it | ||
| 498 | immediately. */ | ||
| 499 | valid = t_branch; | ||
| 500 | break; | ||
| 501 | case 31: /* BL instruction 2 */ | ||
| 502 | /* Format 19 */ | ||
| 503 | /* There is no single ARM instruction equivalent for this | ||
| 504 | instruction. Also, it should only ever be matched with the | ||
| 505 | fmt19 "BL instruction 1" instruction. However, we do allow | ||
| 506 | the simulation of it on its own, with undefined results if | ||
| 507 | r14 is not suitably initialised. */ | ||
| 508 | { | ||
| 509 | #if 0 | ||
| 510 | ARMword tmp = (pc + 2); | ||
| 511 | state->Reg[15] = | ||
| 512 | (state->Reg[14] + ((tinstr & 0x07FF) << 1)); | ||
| 513 | state->Reg[14] = (tmp | 1); | ||
| 514 | #endif | ||
| 515 | valid = t_branch; | ||
| 516 | } | ||
| 517 | break; | ||
| 518 | } | ||
| 519 | *inst_size = 2; | ||
| 520 | return valid; | ||
| 521 | } | 376 | } |
diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp index 2320449b6..27dc8a008 100644 --- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp | |||
| @@ -56,7 +56,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vmla)(unsigned int inst, int index) | |||
| 56 | #ifdef VFP_INTERPRETER_IMPL | 56 | #ifdef VFP_INTERPRETER_IMPL |
| 57 | VMLA_INST: | 57 | VMLA_INST: |
| 58 | { | 58 | { |
| 59 | INC_ICOUNTER; | ||
| 60 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 59 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 61 | CHECK_VFP_ENABLED; | 60 | CHECK_VFP_ENABLED; |
| 62 | 61 | ||
| @@ -180,7 +179,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vmls)(unsigned int inst, int index) | |||
| 180 | #ifdef VFP_INTERPRETER_IMPL | 179 | #ifdef VFP_INTERPRETER_IMPL |
| 181 | VMLS_INST: | 180 | VMLS_INST: |
| 182 | { | 181 | { |
| 183 | INC_ICOUNTER; | ||
| 184 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 182 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 185 | CHECK_VFP_ENABLED; | 183 | CHECK_VFP_ENABLED; |
| 186 | 184 | ||
| @@ -304,7 +302,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vnmla)(unsigned int inst, int index) | |||
| 304 | #ifdef VFP_INTERPRETER_IMPL | 302 | #ifdef VFP_INTERPRETER_IMPL |
| 305 | VNMLA_INST: | 303 | VNMLA_INST: |
| 306 | { | 304 | { |
| 307 | INC_ICOUNTER; | ||
| 308 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 305 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 309 | CHECK_VFP_ENABLED; | 306 | CHECK_VFP_ENABLED; |
| 310 | 307 | ||
| @@ -430,7 +427,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vnmls)(unsigned int inst, int index) | |||
| 430 | #ifdef VFP_INTERPRETER_IMPL | 427 | #ifdef VFP_INTERPRETER_IMPL |
| 431 | VNMLS_INST: | 428 | VNMLS_INST: |
| 432 | { | 429 | { |
| 433 | INC_ICOUNTER; | ||
| 434 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 430 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 435 | CHECK_VFP_ENABLED; | 431 | CHECK_VFP_ENABLED; |
| 436 | 432 | ||
| @@ -554,7 +550,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vnmul)(unsigned int inst, int index) | |||
| 554 | #ifdef VFP_INTERPRETER_IMPL | 550 | #ifdef VFP_INTERPRETER_IMPL |
| 555 | VNMUL_INST: | 551 | VNMUL_INST: |
| 556 | { | 552 | { |
| 557 | INC_ICOUNTER; | ||
| 558 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 553 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 559 | CHECK_VFP_ENABLED; | 554 | CHECK_VFP_ENABLED; |
| 560 | 555 | ||
| @@ -669,7 +664,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vmul)(unsigned int inst, int index) | |||
| 669 | #ifdef VFP_INTERPRETER_IMPL | 664 | #ifdef VFP_INTERPRETER_IMPL |
| 670 | VMUL_INST: | 665 | VMUL_INST: |
| 671 | { | 666 | { |
| 672 | INC_ICOUNTER; | ||
| 673 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 667 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 674 | CHECK_VFP_ENABLED; | 668 | CHECK_VFP_ENABLED; |
| 675 | 669 | ||
| @@ -797,7 +791,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vadd)(unsigned int inst, int index) | |||
| 797 | #ifdef VFP_INTERPRETER_IMPL | 791 | #ifdef VFP_INTERPRETER_IMPL |
| 798 | VADD_INST: | 792 | VADD_INST: |
| 799 | { | 793 | { |
| 800 | INC_ICOUNTER; | ||
| 801 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 794 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 802 | CHECK_VFP_ENABLED; | 795 | CHECK_VFP_ENABLED; |
| 803 | 796 | ||
| @@ -919,7 +912,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vsub)(unsigned int inst, int index) | |||
| 919 | #ifdef VFP_INTERPRETER_IMPL | 912 | #ifdef VFP_INTERPRETER_IMPL |
| 920 | VSUB_INST: | 913 | VSUB_INST: |
| 921 | { | 914 | { |
| 922 | INC_ICOUNTER; | ||
| 923 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 915 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 924 | CHECK_VFP_ENABLED; | 916 | CHECK_VFP_ENABLED; |
| 925 | 917 | ||
| @@ -1039,7 +1031,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vdiv)(unsigned int inst, int index) | |||
| 1039 | #ifdef VFP_INTERPRETER_IMPL | 1031 | #ifdef VFP_INTERPRETER_IMPL |
| 1040 | VDIV_INST: | 1032 | VDIV_INST: |
| 1041 | { | 1033 | { |
| 1042 | INC_ICOUNTER; | ||
| 1043 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 1034 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 1044 | CHECK_VFP_ENABLED; | 1035 | CHECK_VFP_ENABLED; |
| 1045 | 1036 | ||
| @@ -1167,7 +1158,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vmovi)(unsigned int inst, int index) | |||
| 1167 | #ifdef VFP_INTERPRETER_IMPL | 1158 | #ifdef VFP_INTERPRETER_IMPL |
| 1168 | VMOVI_INST: | 1159 | VMOVI_INST: |
| 1169 | { | 1160 | { |
| 1170 | INC_ICOUNTER; | ||
| 1171 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 1161 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 1172 | CHECK_VFP_ENABLED; | 1162 | CHECK_VFP_ENABLED; |
| 1173 | 1163 | ||
| @@ -1256,7 +1246,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vmovr)(unsigned int inst, int index) | |||
| 1256 | #ifdef VFP_INTERPRETER_IMPL | 1246 | #ifdef VFP_INTERPRETER_IMPL |
| 1257 | VMOVR_INST: | 1247 | VMOVR_INST: |
| 1258 | { | 1248 | { |
| 1259 | INC_ICOUNTER; | ||
| 1260 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 1249 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 1261 | CHECK_VFP_ENABLED; | 1250 | CHECK_VFP_ENABLED; |
| 1262 | 1251 | ||
| @@ -1338,7 +1327,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vabs)(unsigned int inst, int index) | |||
| 1338 | #ifdef VFP_INTERPRETER_IMPL | 1327 | #ifdef VFP_INTERPRETER_IMPL |
| 1339 | VABS_INST: | 1328 | VABS_INST: |
| 1340 | { | 1329 | { |
| 1341 | INC_ICOUNTER; | ||
| 1342 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 1330 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 1343 | CHECK_VFP_ENABLED; | 1331 | CHECK_VFP_ENABLED; |
| 1344 | 1332 | ||
| @@ -1447,7 +1435,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vneg)(unsigned int inst, int index) | |||
| 1447 | #ifdef VFP_INTERPRETER_IMPL | 1435 | #ifdef VFP_INTERPRETER_IMPL |
| 1448 | VNEG_INST: | 1436 | VNEG_INST: |
| 1449 | { | 1437 | { |
| 1450 | INC_ICOUNTER; | ||
| 1451 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 1438 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 1452 | CHECK_VFP_ENABLED; | 1439 | CHECK_VFP_ENABLED; |
| 1453 | 1440 | ||
| @@ -1555,7 +1542,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vsqrt)(unsigned int inst, int index) | |||
| 1555 | #ifdef VFP_INTERPRETER_IMPL | 1542 | #ifdef VFP_INTERPRETER_IMPL |
| 1556 | VSQRT_INST: | 1543 | VSQRT_INST: |
| 1557 | { | 1544 | { |
| 1558 | INC_ICOUNTER; | ||
| 1559 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 1545 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 1560 | CHECK_VFP_ENABLED; | 1546 | CHECK_VFP_ENABLED; |
| 1561 | 1547 | ||
| @@ -1651,7 +1637,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp)(unsigned int inst, int index) | |||
| 1651 | #ifdef VFP_INTERPRETER_IMPL | 1637 | #ifdef VFP_INTERPRETER_IMPL |
| 1652 | VCMP_INST: | 1638 | VCMP_INST: |
| 1653 | { | 1639 | { |
| 1654 | INC_ICOUNTER; | ||
| 1655 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 1640 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 1656 | CHECK_VFP_ENABLED; | 1641 | CHECK_VFP_ENABLED; |
| 1657 | 1642 | ||
| @@ -1774,7 +1759,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp2)(unsigned int inst, int index) | |||
| 1774 | #ifdef VFP_INTERPRETER_IMPL | 1759 | #ifdef VFP_INTERPRETER_IMPL |
| 1775 | VCMP2_INST: | 1760 | VCMP2_INST: |
| 1776 | { | 1761 | { |
| 1777 | INC_ICOUNTER; | ||
| 1778 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 1762 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 1779 | CHECK_VFP_ENABLED; | 1763 | CHECK_VFP_ENABLED; |
| 1780 | 1764 | ||
| @@ -1897,7 +1881,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbds)(unsigned int inst, int index) | |||
| 1897 | #ifdef VFP_INTERPRETER_IMPL | 1881 | #ifdef VFP_INTERPRETER_IMPL |
| 1898 | VCVTBDS_INST: | 1882 | VCVTBDS_INST: |
| 1899 | { | 1883 | { |
| 1900 | INC_ICOUNTER; | ||
| 1901 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 1884 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 1902 | CHECK_VFP_ENABLED; | 1885 | CHECK_VFP_ENABLED; |
| 1903 | 1886 | ||
| @@ -1994,7 +1977,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbff)(unsigned int inst, int index) | |||
| 1994 | #ifdef VFP_INTERPRETER_IMPL | 1977 | #ifdef VFP_INTERPRETER_IMPL |
| 1995 | VCVTBFF_INST: | 1978 | VCVTBFF_INST: |
| 1996 | { | 1979 | { |
| 1997 | INC_ICOUNTER; | ||
| 1998 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 1980 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 1999 | CHECK_VFP_ENABLED; | 1981 | CHECK_VFP_ENABLED; |
| 2000 | 1982 | ||
| @@ -2070,7 +2052,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbfi)(unsigned int inst, int index) | |||
| 2070 | #ifdef VFP_INTERPRETER_IMPL | 2052 | #ifdef VFP_INTERPRETER_IMPL |
| 2071 | VCVTBFI_INST: | 2053 | VCVTBFI_INST: |
| 2072 | { | 2054 | { |
| 2073 | INC_ICOUNTER; | ||
| 2074 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 2055 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 2075 | CHECK_VFP_ENABLED; | 2056 | CHECK_VFP_ENABLED; |
| 2076 | 2057 | ||
| @@ -2243,7 +2224,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrs)(unsigned int inst, int index) | |||
| 2243 | #ifdef VFP_INTERPRETER_IMPL | 2224 | #ifdef VFP_INTERPRETER_IMPL |
| 2244 | VMOVBRS_INST: | 2225 | VMOVBRS_INST: |
| 2245 | { | 2226 | { |
| 2246 | INC_ICOUNTER; | ||
| 2247 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 2227 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 2248 | CHECK_VFP_ENABLED; | 2228 | CHECK_VFP_ENABLED; |
| 2249 | 2229 | ||
| @@ -2323,7 +2303,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vmsr)(unsigned int inst, int index) | |||
| 2323 | #ifdef VFP_INTERPRETER_IMPL | 2303 | #ifdef VFP_INTERPRETER_IMPL |
| 2324 | VMSR_INST: | 2304 | VMSR_INST: |
| 2325 | { | 2305 | { |
| 2326 | INC_ICOUNTER; | ||
| 2327 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 2306 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 2328 | /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled , | 2307 | /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled , |
| 2329 | and in privilegied mode */ | 2308 | and in privilegied mode */ |
| @@ -2426,7 +2405,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrc)(unsigned int inst, int index) | |||
| 2426 | #ifdef VFP_INTERPRETER_IMPL | 2405 | #ifdef VFP_INTERPRETER_IMPL |
| 2427 | VMOVBRC_INST: | 2406 | VMOVBRC_INST: |
| 2428 | { | 2407 | { |
| 2429 | INC_ICOUNTER; | ||
| 2430 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 2408 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 2431 | CHECK_VFP_ENABLED; | 2409 | CHECK_VFP_ENABLED; |
| 2432 | 2410 | ||
| @@ -2493,7 +2471,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vmrs)(unsigned int inst, int index) | |||
| 2493 | #ifdef VFP_INTERPRETER_IMPL | 2471 | #ifdef VFP_INTERPRETER_IMPL |
| 2494 | VMRS_INST: | 2472 | VMRS_INST: |
| 2495 | { | 2473 | { |
| 2496 | INC_ICOUNTER; | ||
| 2497 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 2474 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 2498 | /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled, | 2475 | /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled, |
| 2499 | and in privilegied mode */ | 2476 | and in privilegied mode */ |
| @@ -2657,7 +2634,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbcr)(unsigned int inst, int index) | |||
| 2657 | #ifdef VFP_INTERPRETER_IMPL | 2634 | #ifdef VFP_INTERPRETER_IMPL |
| 2658 | VMOVBCR_INST: | 2635 | VMOVBCR_INST: |
| 2659 | { | 2636 | { |
| 2660 | INC_ICOUNTER; | ||
| 2661 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 2637 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 2662 | CHECK_VFP_ENABLED; | 2638 | CHECK_VFP_ENABLED; |
| 2663 | 2639 | ||
| @@ -2733,7 +2709,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrss)(unsigned int inst, int index) | |||
| 2733 | #ifdef VFP_INTERPRETER_IMPL | 2709 | #ifdef VFP_INTERPRETER_IMPL |
| 2734 | VMOVBRRSS_INST: | 2710 | VMOVBRRSS_INST: |
| 2735 | { | 2711 | { |
| 2736 | INC_ICOUNTER; | ||
| 2737 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 2712 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 2738 | CHECK_VFP_ENABLED; | 2713 | CHECK_VFP_ENABLED; |
| 2739 | 2714 | ||
| @@ -2803,7 +2778,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrd)(unsigned int inst, int index) | |||
| 2803 | #ifdef VFP_INTERPRETER_IMPL | 2778 | #ifdef VFP_INTERPRETER_IMPL |
| 2804 | VMOVBRRD_INST: | 2779 | VMOVBRRD_INST: |
| 2805 | { | 2780 | { |
| 2806 | INC_ICOUNTER; | ||
| 2807 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 2781 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 2808 | CHECK_VFP_ENABLED; | 2782 | CHECK_VFP_ENABLED; |
| 2809 | 2783 | ||
| @@ -2895,7 +2869,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vstr)(unsigned int inst, int index) | |||
| 2895 | #ifdef VFP_INTERPRETER_IMPL | 2869 | #ifdef VFP_INTERPRETER_IMPL |
| 2896 | VSTR_INST: | 2870 | VSTR_INST: |
| 2897 | { | 2871 | { |
| 2898 | INC_ICOUNTER; | ||
| 2899 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 2872 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 2900 | CHECK_VFP_ENABLED; | 2873 | CHECK_VFP_ENABLED; |
| 2901 | 2874 | ||
| @@ -3037,7 +3010,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vpush)(unsigned int inst, int index) | |||
| 3037 | #ifdef VFP_INTERPRETER_IMPL | 3010 | #ifdef VFP_INTERPRETER_IMPL |
| 3038 | VPUSH_INST: | 3011 | VPUSH_INST: |
| 3039 | { | 3012 | { |
| 3040 | INC_ICOUNTER; | ||
| 3041 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 3013 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 3042 | CHECK_VFP_ENABLED; | 3014 | CHECK_VFP_ENABLED; |
| 3043 | 3015 | ||
| @@ -3204,7 +3176,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vstm)(unsigned int inst, int index) | |||
| 3204 | #ifdef VFP_INTERPRETER_IMPL | 3176 | #ifdef VFP_INTERPRETER_IMPL |
| 3205 | VSTM_INST: /* encoding 1 */ | 3177 | VSTM_INST: /* encoding 1 */ |
| 3206 | { | 3178 | { |
| 3207 | INC_ICOUNTER; | ||
| 3208 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 3179 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 3209 | CHECK_VFP_ENABLED; | 3180 | CHECK_VFP_ENABLED; |
| 3210 | 3181 | ||
| @@ -3392,7 +3363,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vpop)(unsigned int inst, int index) | |||
| 3392 | #ifdef VFP_INTERPRETER_IMPL | 3363 | #ifdef VFP_INTERPRETER_IMPL |
| 3393 | VPOP_INST: | 3364 | VPOP_INST: |
| 3394 | { | 3365 | { |
| 3395 | INC_ICOUNTER; | ||
| 3396 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 3366 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 3397 | CHECK_VFP_ENABLED; | 3367 | CHECK_VFP_ENABLED; |
| 3398 | 3368 | ||
| @@ -3573,7 +3543,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vldr)(unsigned int inst, int index) | |||
| 3573 | #ifdef VFP_INTERPRETER_IMPL | 3543 | #ifdef VFP_INTERPRETER_IMPL |
| 3574 | VLDR_INST: | 3544 | VLDR_INST: |
| 3575 | { | 3545 | { |
| 3576 | INC_ICOUNTER; | ||
| 3577 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 3546 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 3578 | CHECK_VFP_ENABLED; | 3547 | CHECK_VFP_ENABLED; |
| 3579 | 3548 | ||
| @@ -3737,7 +3706,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vldm)(unsigned int inst, int index) | |||
| 3737 | #ifdef VFP_INTERPRETER_IMPL | 3706 | #ifdef VFP_INTERPRETER_IMPL |
| 3738 | VLDM_INST: | 3707 | VLDM_INST: |
| 3739 | { | 3708 | { |
| 3740 | INC_ICOUNTER; | ||
| 3741 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 3709 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 3742 | CHECK_VFP_ENABLED; | 3710 | CHECK_VFP_ENABLED; |
| 3743 | 3711 | ||