1 // license:BSD-3-Clause
2 // copyright-holders:Steve Ellenoff,R. Belmont,Ryan Holtz
3 #include "emu.h"
4 #include "arm7.h"
5 #include "arm7core.h"
6 #include "arm7help.h"
7
8 // this is our master dispatch jump table for THUMB mode, representing [(INSN & 0xffc0) >> 6] bits of the 16-bit decoded instruction
9 const arm7_cpu_device::arm7thumb_ophandler arm7_cpu_device::thumb_handler[0x40*0x10] =
10 {
11 // #define THUMB_SHIFT_R ((uint16_t)0x0800)
12 &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0,
13 &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0,
14 &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0,
15 &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0,
16 &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0,
17 &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0,
18 &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0,
19 &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0, &arm7_cpu_device::tg00_0,
20 &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1,
21 &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1,
22 &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1,
23 &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1,
24 &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1,
25 &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1,
26 &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1,
27 &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1, &arm7_cpu_device::tg00_1,
28 // #define THUMB_INSN_ADDSUB ((uint16_t)0x0800) // #define THUMB_ADDSUB_TYPE ((uint16_t)0x0600)
29 &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0,
30 &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0,
31 &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0,
32 &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0,
33 &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0,
34 &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0,
35 &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0,
36 &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0, &arm7_cpu_device::tg01_0,
37 &arm7_cpu_device::tg01_10, &arm7_cpu_device::tg01_10, &arm7_cpu_device::tg01_10, &arm7_cpu_device::tg01_10,
38 &arm7_cpu_device::tg01_10, &arm7_cpu_device::tg01_10, &arm7_cpu_device::tg01_10, &arm7_cpu_device::tg01_10,
39 &arm7_cpu_device::tg01_11, &arm7_cpu_device::tg01_11, &arm7_cpu_device::tg01_11, &arm7_cpu_device::tg01_11,
40 &arm7_cpu_device::tg01_11, &arm7_cpu_device::tg01_11, &arm7_cpu_device::tg01_11, &arm7_cpu_device::tg01_11,
41 &arm7_cpu_device::tg01_12, &arm7_cpu_device::tg01_12, &arm7_cpu_device::tg01_12, &arm7_cpu_device::tg01_12,
42 &arm7_cpu_device::tg01_12, &arm7_cpu_device::tg01_12, &arm7_cpu_device::tg01_12, &arm7_cpu_device::tg01_12,
43 &arm7_cpu_device::tg01_13, &arm7_cpu_device::tg01_13, &arm7_cpu_device::tg01_13, &arm7_cpu_device::tg01_13,
44 &arm7_cpu_device::tg01_13, &arm7_cpu_device::tg01_13, &arm7_cpu_device::tg01_13, &arm7_cpu_device::tg01_13,
45 // #define THUMB_INSN_CMP ((uint16_t)0x0800)
46 &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0,
47 &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0,
48 &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0,
49 &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0,
50 &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0,
51 &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0,
52 &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0,
53 &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0, &arm7_cpu_device::tg02_0,
54 &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1,
55 &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1,
56 &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1,
57 &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1,
58 &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1,
59 &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1,
60 &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1,
61 &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1, &arm7_cpu_device::tg02_1,
62 // #define THUMB_INSN_SUB ((uint16_t)0x0800)
63 &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0,
64 &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0,
65 &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0,
66 &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0,
67 &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0,
68 &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0,
69 &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0,
70 &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0, &arm7_cpu_device::tg03_0,
71 &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1,
72 &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1,
73 &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1,
74 &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1,
75 &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1,
76 &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1,
77 &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1,
78 &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1, &arm7_cpu_device::tg03_1,
79 //#define THUMB_GROUP4_TYPE ((uint16_t)0x0c00) //#define THUMB_ALUOP_TYPE ((uint16_t)0x03c0) // #define THUMB_HIREG_OP ((uint16_t)0x0300) // #define THUMB_HIREG_H ((uint16_t)0x00c0)
80 &arm7_cpu_device::tg04_00_00, &arm7_cpu_device::tg04_00_01, &arm7_cpu_device::tg04_00_02, &arm7_cpu_device::tg04_00_03,
81 &arm7_cpu_device::tg04_00_04, &arm7_cpu_device::tg04_00_05, &arm7_cpu_device::tg04_00_06, &arm7_cpu_device::tg04_00_07,
82 &arm7_cpu_device::tg04_00_08, &arm7_cpu_device::tg04_00_09, &arm7_cpu_device::tg04_00_0a, &arm7_cpu_device::tg04_00_0b,
83 &arm7_cpu_device::tg04_00_0c, &arm7_cpu_device::tg04_00_0d, &arm7_cpu_device::tg04_00_0e, &arm7_cpu_device::tg04_00_0f,
84 &arm7_cpu_device::tg04_01_00, &arm7_cpu_device::tg04_01_01, &arm7_cpu_device::tg04_01_02, &arm7_cpu_device::tg04_01_03,
85 &arm7_cpu_device::tg04_01_10, &arm7_cpu_device::tg04_01_11, &arm7_cpu_device::tg04_01_12, &arm7_cpu_device::tg04_01_13,
86 &arm7_cpu_device::tg04_01_20, &arm7_cpu_device::tg04_01_21, &arm7_cpu_device::tg04_01_22, &arm7_cpu_device::tg04_01_23,
87 &arm7_cpu_device::tg04_01_30, &arm7_cpu_device::tg04_01_31, &arm7_cpu_device::tg04_01_32, &arm7_cpu_device::tg04_01_33,
88 &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203,
89 &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203,
90 &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203,
91 &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203,
92 &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203,
93 &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203,
94 &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203,
95 &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203, &arm7_cpu_device::tg04_0203,
96 //#define THUMB_GROUP5_TYPE ((uint16_t)0x0e00)
97 &arm7_cpu_device::tg05_0, &arm7_cpu_device::tg05_0, &arm7_cpu_device::tg05_0, &arm7_cpu_device::tg05_0,
98 &arm7_cpu_device::tg05_0, &arm7_cpu_device::tg05_0, &arm7_cpu_device::tg05_0, &arm7_cpu_device::tg05_0,
99 &arm7_cpu_device::tg05_1, &arm7_cpu_device::tg05_1, &arm7_cpu_device::tg05_1, &arm7_cpu_device::tg05_1,
100 &arm7_cpu_device::tg05_1, &arm7_cpu_device::tg05_1, &arm7_cpu_device::tg05_1, &arm7_cpu_device::tg05_1,
101 &arm7_cpu_device::tg05_2, &arm7_cpu_device::tg05_2, &arm7_cpu_device::tg05_2, &arm7_cpu_device::tg05_2,
102 &arm7_cpu_device::tg05_2, &arm7_cpu_device::tg05_2, &arm7_cpu_device::tg05_2, &arm7_cpu_device::tg05_2,
103 &arm7_cpu_device::tg05_3, &arm7_cpu_device::tg05_3, &arm7_cpu_device::tg05_3, &arm7_cpu_device::tg05_3,
104 &arm7_cpu_device::tg05_3, &arm7_cpu_device::tg05_3, &arm7_cpu_device::tg05_3, &arm7_cpu_device::tg05_3,
105 &arm7_cpu_device::tg05_4, &arm7_cpu_device::tg05_4, &arm7_cpu_device::tg05_4, &arm7_cpu_device::tg05_4,
106 &arm7_cpu_device::tg05_4, &arm7_cpu_device::tg05_4, &arm7_cpu_device::tg05_4, &arm7_cpu_device::tg05_4,
107 &arm7_cpu_device::tg05_5, &arm7_cpu_device::tg05_5, &arm7_cpu_device::tg05_5, &arm7_cpu_device::tg05_5,
108 &arm7_cpu_device::tg05_5, &arm7_cpu_device::tg05_5, &arm7_cpu_device::tg05_5, &arm7_cpu_device::tg05_5,
109 &arm7_cpu_device::tg05_6, &arm7_cpu_device::tg05_6, &arm7_cpu_device::tg05_6, &arm7_cpu_device::tg05_6,
110 &arm7_cpu_device::tg05_6, &arm7_cpu_device::tg05_6, &arm7_cpu_device::tg05_6, &arm7_cpu_device::tg05_6,
111 &arm7_cpu_device::tg05_7, &arm7_cpu_device::tg05_7, &arm7_cpu_device::tg05_7, &arm7_cpu_device::tg05_7,
112 &arm7_cpu_device::tg05_7, &arm7_cpu_device::tg05_7, &arm7_cpu_device::tg05_7, &arm7_cpu_device::tg05_7,
113 //#define THUMB_LSOP_L ((uint16_t)0x0800)
114 &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0,
115 &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0,
116 &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0,
117 &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0,
118 &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0,
119 &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0,
120 &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0,
121 &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0, &arm7_cpu_device::tg06_0,
122 &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1,
123 &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1,
124 &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1,
125 &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1,
126 &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1,
127 &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1,
128 &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1,
129 &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1, &arm7_cpu_device::tg06_1,
130 //#define THUMB_LSOP_L ((uint16_t)0x0800)
131 &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0,
132 &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0,
133 &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0,
134 &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0,
135 &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0,
136 &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0,
137 &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0,
138 &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0, &arm7_cpu_device::tg07_0,
139 &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1,
140 &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1,
141 &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1,
142 &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1,
143 &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1,
144 &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1,
145 &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1,
146 &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1, &arm7_cpu_device::tg07_1,
147 // #define THUMB_HALFOP_L ((uint16_t)0x0800)
148 &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0,
149 &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0,
150 &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0,
151 &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0,
152 &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0,
153 &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0,
154 &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0,
155 &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0, &arm7_cpu_device::tg08_0,
156 &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1,
157 &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1,
158 &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1,
159 &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1,
160 &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1,
161 &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1,
162 &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1,
163 &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1, &arm7_cpu_device::tg08_1,
164 // #define THUMB_STACKOP_L ((uint16_t)0x0800)
165 &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0,
166 &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0,
167 &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0,
168 &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0,
169 &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0,
170 &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0,
171 &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0,
172 &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0, &arm7_cpu_device::tg09_0,
173 &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1,
174 &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1,
175 &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1,
176 &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1,
177 &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1,
178 &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1,
179 &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1,
180 &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1, &arm7_cpu_device::tg09_1,
181 // #define THUMB_RELADDR_SP ((uint16_t)0x0800)
182 &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0,
183 &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0,
184 &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0,
185 &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0,
186 &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0,
187 &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0,
188 &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0,
189 &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0, &arm7_cpu_device::tg0a_0,
190 &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1,
191 &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1,
192 &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1,
193 &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1,
194 &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1,
195 &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1,
196 &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1,
197 &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1, &arm7_cpu_device::tg0a_1,
198 // #define THUMB_STACKOP_TYPE ((uint16_t)0x0f00)
199 &arm7_cpu_device::tg0b_0, &arm7_cpu_device::tg0b_0, &arm7_cpu_device::tg0b_0, &arm7_cpu_device::tg0b_0,
200 &arm7_cpu_device::tg0b_1, &arm7_cpu_device::tg0b_1, &arm7_cpu_device::tg0b_1, &arm7_cpu_device::tg0b_1,
201 &arm7_cpu_device::tg0b_2, &arm7_cpu_device::tg0b_2, &arm7_cpu_device::tg0b_2, &arm7_cpu_device::tg0b_2,
202 &arm7_cpu_device::tg0b_3, &arm7_cpu_device::tg0b_3, &arm7_cpu_device::tg0b_3, &arm7_cpu_device::tg0b_3,
203 &arm7_cpu_device::tg0b_4, &arm7_cpu_device::tg0b_4, &arm7_cpu_device::tg0b_4, &arm7_cpu_device::tg0b_4,
204 &arm7_cpu_device::tg0b_5, &arm7_cpu_device::tg0b_5, &arm7_cpu_device::tg0b_5, &arm7_cpu_device::tg0b_5,
205 &arm7_cpu_device::tg0b_6, &arm7_cpu_device::tg0b_6, &arm7_cpu_device::tg0b_6, &arm7_cpu_device::tg0b_6,
206 &arm7_cpu_device::tg0b_7, &arm7_cpu_device::tg0b_7, &arm7_cpu_device::tg0b_7, &arm7_cpu_device::tg0b_7,
207 &arm7_cpu_device::tg0b_8, &arm7_cpu_device::tg0b_8, &arm7_cpu_device::tg0b_8, &arm7_cpu_device::tg0b_8,
208 &arm7_cpu_device::tg0b_9, &arm7_cpu_device::tg0b_9, &arm7_cpu_device::tg0b_9, &arm7_cpu_device::tg0b_9,
209 &arm7_cpu_device::tg0b_a, &arm7_cpu_device::tg0b_a, &arm7_cpu_device::tg0b_a, &arm7_cpu_device::tg0b_a,
210 &arm7_cpu_device::tg0b_b, &arm7_cpu_device::tg0b_b, &arm7_cpu_device::tg0b_b, &arm7_cpu_device::tg0b_b,
211 &arm7_cpu_device::tg0b_c, &arm7_cpu_device::tg0b_c, &arm7_cpu_device::tg0b_c, &arm7_cpu_device::tg0b_c,
212 &arm7_cpu_device::tg0b_d, &arm7_cpu_device::tg0b_d, &arm7_cpu_device::tg0b_d, &arm7_cpu_device::tg0b_d,
213 &arm7_cpu_device::tg0b_e, &arm7_cpu_device::tg0b_e, &arm7_cpu_device::tg0b_e, &arm7_cpu_device::tg0b_e,
214 &arm7_cpu_device::tg0b_f, &arm7_cpu_device::tg0b_f, &arm7_cpu_device::tg0b_f, &arm7_cpu_device::tg0b_f,
215 // #define THUMB_MULTLS ((uint16_t)0x0800)
216 &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0,
217 &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0,
218 &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0,
219 &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0,
220 &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0,
221 &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0,
222 &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0,
223 &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0, &arm7_cpu_device::tg0c_0,
224 &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1,
225 &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1,
226 &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1,
227 &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1,
228 &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1,
229 &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1,
230 &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1,
231 &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1, &arm7_cpu_device::tg0c_1,
232 // #define THUMB_COND_TYPE ((uint16_t)0x0f00)
233 &arm7_cpu_device::tg0d_0, &arm7_cpu_device::tg0d_0, &arm7_cpu_device::tg0d_0, &arm7_cpu_device::tg0d_0,
234 &arm7_cpu_device::tg0d_1, &arm7_cpu_device::tg0d_1, &arm7_cpu_device::tg0d_1, &arm7_cpu_device::tg0d_1,
235 &arm7_cpu_device::tg0d_2, &arm7_cpu_device::tg0d_2, &arm7_cpu_device::tg0d_2, &arm7_cpu_device::tg0d_2,
236 &arm7_cpu_device::tg0d_3, &arm7_cpu_device::tg0d_3, &arm7_cpu_device::tg0d_3, &arm7_cpu_device::tg0d_3,
237 &arm7_cpu_device::tg0d_4, &arm7_cpu_device::tg0d_4, &arm7_cpu_device::tg0d_4, &arm7_cpu_device::tg0d_4,
238 &arm7_cpu_device::tg0d_5, &arm7_cpu_device::tg0d_5, &arm7_cpu_device::tg0d_5, &arm7_cpu_device::tg0d_5,
239 &arm7_cpu_device::tg0d_6, &arm7_cpu_device::tg0d_6, &arm7_cpu_device::tg0d_6, &arm7_cpu_device::tg0d_6,
240 &arm7_cpu_device::tg0d_7, &arm7_cpu_device::tg0d_7, &arm7_cpu_device::tg0d_7, &arm7_cpu_device::tg0d_7,
241 &arm7_cpu_device::tg0d_8, &arm7_cpu_device::tg0d_8, &arm7_cpu_device::tg0d_8, &arm7_cpu_device::tg0d_8,
242 &arm7_cpu_device::tg0d_9, &arm7_cpu_device::tg0d_9, &arm7_cpu_device::tg0d_9, &arm7_cpu_device::tg0d_9,
243 &arm7_cpu_device::tg0d_a, &arm7_cpu_device::tg0d_a, &arm7_cpu_device::tg0d_a, &arm7_cpu_device::tg0d_a,
244 &arm7_cpu_device::tg0d_b, &arm7_cpu_device::tg0d_b, &arm7_cpu_device::tg0d_b, &arm7_cpu_device::tg0d_b,
245 &arm7_cpu_device::tg0d_c, &arm7_cpu_device::tg0d_c, &arm7_cpu_device::tg0d_c, &arm7_cpu_device::tg0d_c,
246 &arm7_cpu_device::tg0d_d, &arm7_cpu_device::tg0d_d, &arm7_cpu_device::tg0d_d, &arm7_cpu_device::tg0d_d,
247 &arm7_cpu_device::tg0d_e, &arm7_cpu_device::tg0d_e, &arm7_cpu_device::tg0d_e, &arm7_cpu_device::tg0d_e,
248 &arm7_cpu_device::tg0d_f, &arm7_cpu_device::tg0d_f, &arm7_cpu_device::tg0d_f, &arm7_cpu_device::tg0d_f,
249 // #define THUMB_BLOP_LO ((uint16_t)0x0800)
250 &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0,
251 &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0,
252 &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0,
253 &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0,
254 &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0,
255 &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0,
256 &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0,
257 &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0, &arm7_cpu_device::tg0e_0,
258 &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1,
259 &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1,
260 &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1,
261 &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1,
262 &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1,
263 &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1,
264 &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1,
265 &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1, &arm7_cpu_device::tg0e_1,
266 // #define THUMB_BLOP_LO ((uint16_t)0x0800)
267 &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0,
268 &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0,
269 &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0,
270 &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0,
271 &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0,
272 &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0,
273 &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0,
274 &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0, &arm7_cpu_device::tg0f_0,
275 &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1,
276 &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1,
277 &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1,
278 &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1,
279 &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1,
280 &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1,
281 &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1,
282 &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1, &arm7_cpu_device::tg0f_1,
283 };
284
285 /* Shift operations */
286
tg00_0(uint32_t pc,uint32_t op)287 void arm7_cpu_device::tg00_0(uint32_t pc, uint32_t op) /* Shift left */
288 {
289 uint32_t rs, rd, rrs;
290 int32_t offs;
291
292 set_cpsr(GET_CPSR & ~(N_MASK | Z_MASK));
293
294 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
295 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
296 rrs = GetRegister(rs);
297 offs = (op & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT;
298 if (offs != 0)
299 {
300 SetRegister(rd, rrs << offs);
301 if (rrs & (1 << (31 - (offs - 1))))
302 {
303 set_cpsr(GET_CPSR | C_MASK);
304 }
305 else
306 {
307 set_cpsr(GET_CPSR & ~C_MASK);
308 }
309 }
310 else
311 {
312 SetRegister(rd, rrs);
313 }
314 set_cpsr(GET_CPSR & ~(Z_MASK | N_MASK));
315 set_cpsr(GET_CPSR | HandleALUNZFlags(GetRegister(rd)));
316 R15 += 2;
317 }
318
tg00_1(uint32_t pc,uint32_t op)319 void arm7_cpu_device::tg00_1(uint32_t pc, uint32_t op) /* Shift right */
320 {
321 uint32_t rs, rd, rrs;
322 int32_t offs;
323
324 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
325 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
326 rrs = GetRegister(rs);
327 offs = (op & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT;
328 if (offs != 0)
329 {
330 SetRegister(rd, rrs >> offs);
331 if (rrs & (1 << (offs - 1)))
332 {
333 set_cpsr(GET_CPSR | C_MASK);
334 }
335 else
336 {
337 set_cpsr(GET_CPSR & ~C_MASK);
338 }
339 }
340 else
341 {
342 SetRegister(rd, 0);
343 if (rrs & 0x80000000)
344 {
345 set_cpsr(GET_CPSR | C_MASK);
346 }
347 else
348 {
349 set_cpsr(GET_CPSR & ~C_MASK);
350 }
351 }
352 set_cpsr(GET_CPSR & ~(Z_MASK | N_MASK));
353 set_cpsr(GET_CPSR | HandleALUNZFlags(GetRegister(rd)));
354 R15 += 2;
355 }
356
357 /* Arithmetic */
358
tg01_0(uint32_t pc,uint32_t op)359 void arm7_cpu_device::tg01_0(uint32_t pc, uint32_t op)
360 {
361 uint32_t rs, rd, rrs;
362 int32_t offs;
363 /* ASR.. */
364 //if (op & THUMB_SHIFT_R) /* Shift right */
365 {
366 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
367 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
368 rrs = GetRegister(rs);
369 offs = (op & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT;
370 if (offs == 0)
371 {
372 offs = 32;
373 }
374 if (offs >= 32)
375 {
376 if (rrs >> 31)
377 {
378 set_cpsr(GET_CPSR | C_MASK);
379 }
380 else
381 {
382 set_cpsr(GET_CPSR & ~C_MASK);
383 }
384 SetRegister(rd, (rrs & 0x80000000) ? 0xFFFFFFFF : 0x00000000);
385 }
386 else
387 {
388 if ((rrs >> (offs - 1)) & 1)
389 {
390 set_cpsr(GET_CPSR | C_MASK);
391 }
392 else
393 {
394 set_cpsr(GET_CPSR & ~C_MASK);
395 }
396 SetRegister(rd,
397 (rrs & 0x80000000)
398 ? ((0xFFFFFFFF << (32 - offs)) | (rrs >> offs))
399 : (rrs >> offs));
400 }
401 set_cpsr(GET_CPSR & ~(N_MASK | Z_MASK));
402 set_cpsr(GET_CPSR | HandleALUNZFlags(GetRegister(rd)));
403 R15 += 2;
404 }
405 }
406
tg01_10(uint32_t pc,uint32_t op)407 void arm7_cpu_device::tg01_10(uint32_t pc, uint32_t op) /* ADD Rd, Rs, Rn */
408 {
409 uint32_t rn = GetRegister((op & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT);
410 uint32_t rs = GetRegister((op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
411 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
412 SetRegister(rd, rs + rn);
413 HandleThumbALUAddFlags(GetRegister(rd), rs, rn);
414
415 }
416
tg01_11(uint32_t pc,uint32_t op)417 void arm7_cpu_device::tg01_11(uint32_t pc, uint32_t op) /* SUB Rd, Rs, Rn */
418 {
419 uint32_t rn = GetRegister((op & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT);
420 uint32_t rs = GetRegister((op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
421 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
422 SetRegister(rd, rs - rn);
423 HandleThumbALUSubFlags(GetRegister(rd), rs, rn);
424
425 }
426
tg01_12(uint32_t pc,uint32_t op)427 void arm7_cpu_device::tg01_12(uint32_t pc, uint32_t op) /* ADD Rd, Rs, #imm */
428 {
429 uint32_t imm = (op & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT;
430 uint32_t rs = GetRegister((op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
431 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
432 SetRegister(rd, rs + imm);
433 HandleThumbALUAddFlags(GetRegister(rd), rs, imm);
434
435 }
436
tg01_13(uint32_t pc,uint32_t op)437 void arm7_cpu_device::tg01_13(uint32_t pc, uint32_t op) /* SUB Rd, Rs, #imm */
438 {
439 uint32_t imm = (op & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT;
440 uint32_t rs = GetRegister((op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
441 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
442 SetRegister(rd, rs - imm);
443 HandleThumbALUSubFlags(GetRegister(rd), rs,imm);
444
445 }
446
447 /* CMP / MOV */
448
tg02_0(uint32_t pc,uint32_t op)449 void arm7_cpu_device::tg02_0(uint32_t pc, uint32_t op)
450 {
451 uint32_t rd = (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT;
452 uint32_t op2 = (op & THUMB_INSN_IMM);
453 SetRegister(rd, op2);
454 set_cpsr(GET_CPSR & ~(Z_MASK | N_MASK));
455 set_cpsr(GET_CPSR | HandleALUNZFlags(GetRegister(rd)));
456 R15 += 2;
457 }
458
tg02_1(uint32_t pc,uint32_t op)459 void arm7_cpu_device::tg02_1(uint32_t pc, uint32_t op)
460 {
461 uint32_t rn = GetRegister((op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT);
462 uint32_t op2 = op & THUMB_INSN_IMM;
463 uint32_t rd = rn - op2;
464 HandleThumbALUSubFlags(rd, rn, op2);
465 }
466
467 /* ADD/SUB immediate */
468
tg03_0(uint32_t pc,uint32_t op)469 void arm7_cpu_device::tg03_0(uint32_t pc, uint32_t op) /* ADD Rd, #Offset8 */
470 {
471 uint32_t rn = GetRegister((op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT);
472 uint32_t op2 = op & THUMB_INSN_IMM;
473 uint32_t rd = rn + op2;
474 SetRegister((op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, rd);
475 HandleThumbALUAddFlags(rd, rn, op2);
476 }
477
tg03_1(uint32_t pc,uint32_t op)478 void arm7_cpu_device::tg03_1(uint32_t pc, uint32_t op) /* SUB Rd, #Offset8 */
479 {
480 uint32_t rn = GetRegister((op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT);
481 uint32_t op2 = op & THUMB_INSN_IMM;
482 uint32_t rd = rn - op2;
483 SetRegister((op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, rd);
484 HandleThumbALUSubFlags(rd, rn, op2);
485 }
486
487 /* Rd & Rm instructions */
488
tg04_00_00(uint32_t pc,uint32_t op)489 void arm7_cpu_device::tg04_00_00(uint32_t pc, uint32_t op) /* AND Rd, Rs */
490 {
491 uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
492 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
493 SetRegister(rd, GetRegister(rd) & GetRegister(rs));
494 set_cpsr(GET_CPSR & ~(Z_MASK | N_MASK));
495 set_cpsr(GET_CPSR | HandleALUNZFlags(GetRegister(rd)));
496 R15 += 2;
497 }
498
tg04_00_01(uint32_t pc,uint32_t op)499 void arm7_cpu_device::tg04_00_01(uint32_t pc, uint32_t op) /* EOR Rd, Rs */
500 {
501 uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
502 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
503 SetRegister(rd, GetRegister(rd) ^ GetRegister(rs));
504 set_cpsr(GET_CPSR & ~(Z_MASK | N_MASK));
505 set_cpsr(GET_CPSR | HandleALUNZFlags(GetRegister(rd)));
506 R15 += 2;
507 }
508
tg04_00_02(uint32_t pc,uint32_t op)509 void arm7_cpu_device::tg04_00_02(uint32_t pc, uint32_t op) /* LSL Rd, Rs */
510 {
511 uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
512 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
513 uint32_t rrd = GetRegister(rd);
514 int32_t offs = GetRegister(rs) & 0x000000ff;
515 if (offs > 0)
516 {
517 if (offs < 32)
518 {
519 SetRegister(rd, rrd << offs);
520 if (rrd & (1 << (31 - (offs - 1))))
521 {
522 set_cpsr(GET_CPSR | C_MASK);
523 }
524 else
525 {
526 set_cpsr(GET_CPSR & ~C_MASK);
527 }
528 }
529 else if (offs == 32)
530 {
531 SetRegister(rd, 0);
532 if (rrd & 1)
533 {
534 set_cpsr(GET_CPSR | C_MASK);
535 }
536 else
537 {
538 set_cpsr(GET_CPSR & ~C_MASK);
539 }
540 }
541 else
542 {
543 SetRegister(rd, 0);
544 set_cpsr(GET_CPSR & ~C_MASK);
545 }
546 }
547 set_cpsr(GET_CPSR & ~(Z_MASK | N_MASK));
548 set_cpsr(GET_CPSR | HandleALUNZFlags(GetRegister(rd)));
549 R15 += 2;
550 }
551
tg04_00_03(uint32_t pc,uint32_t op)552 void arm7_cpu_device::tg04_00_03(uint32_t pc, uint32_t op) /* LSR Rd, Rs */
553 {
554 uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
555 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
556 uint32_t rrd = GetRegister(rd);
557 int32_t offs = GetRegister(rs) & 0x000000ff;
558 if (offs > 0)
559 {
560 if (offs < 32)
561 {
562 SetRegister(rd, rrd >> offs);
563 if (rrd & (1 << (offs - 1)))
564 {
565 set_cpsr(GET_CPSR | C_MASK);
566 }
567 else
568 {
569 set_cpsr(GET_CPSR & ~C_MASK);
570 }
571 }
572 else if (offs == 32)
573 {
574 SetRegister(rd, 0);
575 if (rrd & 0x80000000)
576 {
577 set_cpsr(GET_CPSR | C_MASK);
578 }
579 else
580 {
581 set_cpsr(GET_CPSR & ~C_MASK);
582 }
583 }
584 else
585 {
586 SetRegister(rd, 0);
587 set_cpsr(GET_CPSR & ~C_MASK);
588 }
589 }
590 set_cpsr(GET_CPSR & ~(Z_MASK | N_MASK));
591 set_cpsr(GET_CPSR | HandleALUNZFlags(GetRegister(rd)));
592 R15 += 2;
593 }
594
tg04_00_04(uint32_t pc,uint32_t op)595 void arm7_cpu_device::tg04_00_04(uint32_t pc, uint32_t op) /* ASR Rd, Rs */
596 {
597 uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
598 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
599 uint32_t rrs = GetRegister(rs)&0xff;
600 uint32_t rrd = GetRegister(rd);
601 if (rrs != 0)
602 {
603 if (rrs >= 32)
604 {
605 if (rrd >> 31)
606 {
607 set_cpsr(GET_CPSR | C_MASK);
608 }
609 else
610 {
611 set_cpsr(GET_CPSR & ~C_MASK);
612 }
613 SetRegister(rd, (GetRegister(rd) & 0x80000000) ? 0xFFFFFFFF : 0x00000000);
614 }
615 else
616 {
617 if ((rrd >> (rrs-1)) & 1)
618 {
619 set_cpsr(GET_CPSR | C_MASK);
620 }
621 else
622 {
623 set_cpsr(GET_CPSR & ~C_MASK);
624 }
625 SetRegister(rd, (rrd & 0x80000000)
626 ? ((0xFFFFFFFF << (32 - rrs)) | (rrd >> rrs))
627 : (rrd >> rrs));
628 }
629 }
630 set_cpsr(GET_CPSR & ~(N_MASK | Z_MASK));
631 set_cpsr(GET_CPSR | HandleALUNZFlags(GetRegister(rd)));
632 R15 += 2;
633 }
634
tg04_00_05(uint32_t pc,uint32_t op)635 void arm7_cpu_device::tg04_00_05(uint32_t pc, uint32_t op) /* ADC Rd, Rs */
636 {
637 uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
638 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
639 uint32_t op2 = (GET_CPSR & C_MASK) ? 1 : 0;
640 uint32_t rn = GetRegister(rd) + GetRegister(rs) + op2;
641 HandleThumbALUAddFlags(rn, GetRegister(rd), (GetRegister(rs))); // ?
642 SetRegister(rd, rn);
643 }
644
tg04_00_06(uint32_t pc,uint32_t op)645 void arm7_cpu_device::tg04_00_06(uint32_t pc, uint32_t op) /* SBC Rd, Rs */
646 {
647 uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
648 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
649 uint32_t op2 = (GET_CPSR & C_MASK) ? 0 : 1;
650 uint32_t rn = GetRegister(rd) - GetRegister(rs) - op2;
651 HandleThumbALUSubFlags(rn, GetRegister(rd), (GetRegister(rs))); //?
652 SetRegister(rd, rn);
653 }
654
tg04_00_07(uint32_t pc,uint32_t op)655 void arm7_cpu_device::tg04_00_07(uint32_t pc, uint32_t op) /* ROR Rd, Rs */
656 {
657 const uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
658 const uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
659 const uint32_t rrd = GetRegister(rd);
660 const uint32_t imm = GetRegister(rs) & 0xff;
661 const uint32_t imm_masked = imm & 0x1f;
662 if (imm > 0)
663 {
664 SetRegister(rd, (rrd >> imm_masked) | (rrd << (32 - imm_masked)));
665 if (rrd & (1 << ((imm - 1) & 0x1f)))
666 {
667 set_cpsr(GET_CPSR | C_MASK);
668 }
669 else
670 {
671 set_cpsr(GET_CPSR & ~C_MASK);
672 }
673 }
674 set_cpsr(GET_CPSR & ~(Z_MASK | N_MASK));
675 set_cpsr(GET_CPSR | HandleALUNZFlags(GetRegister(rd)));
676 R15 += 2;
677 }
678
tg04_00_08(uint32_t pc,uint32_t op)679 void arm7_cpu_device::tg04_00_08(uint32_t pc, uint32_t op) /* TST Rd, Rs */
680 {
681 uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
682 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
683 set_cpsr(GET_CPSR & ~(Z_MASK | N_MASK));
684 set_cpsr(GET_CPSR | HandleALUNZFlags(GetRegister(rd) & GetRegister(rs)));
685 R15 += 2;
686 }
687
tg04_00_09(uint32_t pc,uint32_t op)688 void arm7_cpu_device::tg04_00_09(uint32_t pc, uint32_t op) /* NEG Rd, Rs */
689 {
690 uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
691 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
692 uint32_t rrs = GetRegister(rs);
693 SetRegister(rd, 0 - rrs);
694 HandleThumbALUSubFlags(GetRegister(rd), 0, rrs);
695 }
696
tg04_00_0a(uint32_t pc,uint32_t op)697 void arm7_cpu_device::tg04_00_0a(uint32_t pc, uint32_t op) /* CMP Rd, Rs */
698 {
699 uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
700 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
701 uint32_t rn = GetRegister(rd) - GetRegister(rs);
702 HandleThumbALUSubFlags(rn, GetRegister(rd), GetRegister(rs));
703 }
704
tg04_00_0b(uint32_t pc,uint32_t op)705 void arm7_cpu_device::tg04_00_0b(uint32_t pc, uint32_t op) /* CMN Rd, Rs - check flags, add dasm */
706 {
707 uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
708 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
709 uint32_t rn = GetRegister(rd) + GetRegister(rs);
710 HandleThumbALUAddFlags(rn, GetRegister(rd), GetRegister(rs));
711 }
712
tg04_00_0c(uint32_t pc,uint32_t op)713 void arm7_cpu_device::tg04_00_0c(uint32_t pc, uint32_t op) /* ORR Rd, Rs */
714 {
715 uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
716 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
717 SetRegister(rd, GetRegister(rd) | GetRegister(rs));
718 set_cpsr(GET_CPSR & ~(Z_MASK | N_MASK));
719 set_cpsr(GET_CPSR | HandleALUNZFlags(GetRegister(rd)));
720 R15 += 2;
721 }
722
tg04_00_0d(uint32_t pc,uint32_t op)723 void arm7_cpu_device::tg04_00_0d(uint32_t pc, uint32_t op) /* MUL Rd, Rs */
724 {
725 uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
726 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
727 uint32_t rn = GetRegister(rd) * GetRegister(rs);
728 set_cpsr(GET_CPSR & ~(Z_MASK | N_MASK));
729 SetRegister(rd, rn);
730 set_cpsr(GET_CPSR | HandleALUNZFlags(rn));
731 R15 += 2;
732 }
733
tg04_00_0e(uint32_t pc,uint32_t op)734 void arm7_cpu_device::tg04_00_0e(uint32_t pc, uint32_t op) /* BIC Rd, Rs */
735 {
736 uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
737 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
738 SetRegister(rd, GetRegister(rd) & (~GetRegister(rs)));
739 set_cpsr(GET_CPSR & ~(Z_MASK | N_MASK));
740 set_cpsr(GET_CPSR | HandleALUNZFlags(GetRegister(rd)));
741 R15 += 2;
742 }
743
tg04_00_0f(uint32_t pc,uint32_t op)744 void arm7_cpu_device::tg04_00_0f(uint32_t pc, uint32_t op) /* MVN Rd, Rs */
745 {
746 uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
747 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
748 uint32_t op2 = GetRegister(rs);
749 SetRegister(rd, ~op2);
750 set_cpsr(GET_CPSR & ~(Z_MASK | N_MASK));
751 set_cpsr(GET_CPSR | HandleALUNZFlags(GetRegister(rd)));
752 R15 += 2;
753 }
754
755 /* ADD Rd, Rs group */
756
tg04_01_00(uint32_t pc,uint32_t op)757 void arm7_cpu_device::tg04_01_00(uint32_t pc, uint32_t op)
758 {
759 fatalerror("%08x: G4-1-0 Undefined Thumb instruction: %04x %x\n", pc, op, (op & THUMB_HIREG_H) >> THUMB_HIREG_H_SHIFT);
760 }
761
tg04_01_01(uint32_t pc,uint32_t op)762 void arm7_cpu_device::tg04_01_01(uint32_t pc, uint32_t op) /* ADD Rd, HRs */
763 {
764 uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
765 uint32_t rd = op & THUMB_HIREG_RD;
766 SetRegister(rd, GetRegister(rd) + GetRegister(rs+8));
767 // emulate the effects of pre-fetch
768 if (rs == 7)
769 {
770 SetRegister(rd, GetRegister(rd) + 4);
771 }
772
773 R15 += 2;
774 }
775
tg04_01_02(uint32_t pc,uint32_t op)776 void arm7_cpu_device::tg04_01_02(uint32_t pc, uint32_t op) /* ADD HRd, Rs */
777 {
778 uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
779 uint32_t rd = op & THUMB_HIREG_RD;
780 SetRegister(rd+8, GetRegister(rd+8) + GetRegister(rs));
781 if (rd == 7)
782 {
783 R15 += 2;
784 }
785
786 R15 += 2;
787 }
788
tg04_01_03(uint32_t pc,uint32_t op)789 void arm7_cpu_device::tg04_01_03(uint32_t pc, uint32_t op) /* Add HRd, HRs */
790 {
791 uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
792 uint32_t rd = op & THUMB_HIREG_RD;
793 SetRegister(rd+8, GetRegister(rd+8) + GetRegister(rs+8));
794 // emulate the effects of pre-fetch
795 if (rs == 7)
796 {
797 SetRegister(rd+8, GetRegister(rd+8) + 4);
798 }
799 if (rd == 7)
800 {
801 R15 += 2;
802 }
803
804 R15 += 2;
805 }
806
tg04_01_10(uint32_t pc,uint32_t op)807 void arm7_cpu_device::tg04_01_10(uint32_t pc, uint32_t op) /* CMP Rd, Rs */
808 {
809 uint32_t rs = GetRegister(((op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT));
810 uint32_t rd = GetRegister(op & THUMB_HIREG_RD);
811 uint32_t rn = rd - rs;
812 HandleThumbALUSubFlags(rn, rd, rs);
813 }
814
tg04_01_11(uint32_t pc,uint32_t op)815 void arm7_cpu_device::tg04_01_11(uint32_t pc, uint32_t op) /* CMP Rd, Hs */
816 {
817 uint32_t rs = GetRegister(((op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT) + 8);
818 uint32_t rd = GetRegister(op & THUMB_HIREG_RD);
819 uint32_t rn = rd - rs;
820 HandleThumbALUSubFlags(rn, rd, rs);
821 }
822
tg04_01_12(uint32_t pc,uint32_t op)823 void arm7_cpu_device::tg04_01_12(uint32_t pc, uint32_t op) /* CMP Hd, Rs */
824 {
825 uint32_t rs = GetRegister(((op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT));
826 uint32_t rd = GetRegister((op & THUMB_HIREG_RD) + 8);
827 uint32_t rn = rd - rs;
828 HandleThumbALUSubFlags(rn, rd, rs);
829 }
830
tg04_01_13(uint32_t pc,uint32_t op)831 void arm7_cpu_device::tg04_01_13(uint32_t pc, uint32_t op) /* CMP Hd, Hs */
832 {
833 uint32_t rs = GetRegister(((op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT) + 8);
834 uint32_t rd = GetRegister((op & THUMB_HIREG_RD) + 8);
835 uint32_t rn = rd - rs;
836 HandleThumbALUSubFlags(rn, rd, rs);
837 }
838
839 /* MOV group */
840
841 // "The action of H1 = 0, H2 = 0 for Op = 00 (ADD), Op = 01 (CMP) and Op = 10 (MOV) is undefined, and should not be used."
tg04_01_20(uint32_t pc,uint32_t op)842 void arm7_cpu_device::tg04_01_20(uint32_t pc, uint32_t op) /* MOV Rd, Rs (undefined) */
843 {
844 uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
845 uint32_t rd = op & THUMB_HIREG_RD;
846 SetRegister(rd, GetRegister(rs));
847 R15 += 2;
848 }
849
tg04_01_21(uint32_t pc,uint32_t op)850 void arm7_cpu_device::tg04_01_21(uint32_t pc, uint32_t op) /* MOV Rd, Hs */
851 {
852 uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
853 uint32_t rd = op & THUMB_HIREG_RD;
854 SetRegister(rd, GetRegister(rs + 8));
855 if (rs == 7)
856 {
857 SetRegister(rd, GetRegister(rd) + 4);
858 }
859 R15 += 2;
860 }
861
tg04_01_22(uint32_t pc,uint32_t op)862 void arm7_cpu_device::tg04_01_22(uint32_t pc, uint32_t op) /* MOV Hd, Rs */
863 {
864 uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
865 uint32_t rd = op & THUMB_HIREG_RD;
866 SetRegister(rd + 8, GetRegister(rs));
867 if (rd != 7)
868 {
869 R15 += 2;
870 }
871 else
872 {
873 R15 &= ~1;
874 }
875 }
876
tg04_01_23(uint32_t pc,uint32_t op)877 void arm7_cpu_device::tg04_01_23(uint32_t pc, uint32_t op) /* MOV Hd, Hs */
878 {
879 uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
880 uint32_t rd = op & THUMB_HIREG_RD;
881 if (rs == 7)
882 {
883 SetRegister(rd + 8, GetRegister(rs+8)+4);
884 }
885 else
886 {
887 SetRegister(rd + 8, GetRegister(rs+8));
888 }
889 if (rd != 7)
890 {
891 R15 += 2;
892 }
893 else
894 {
895 R15 &= ~1;
896 }
897 }
898
tg04_01_30(uint32_t pc,uint32_t op)899 void arm7_cpu_device::tg04_01_30(uint32_t pc, uint32_t op)
900 {
901 uint32_t rd = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
902 uint32_t addr = GetRegister(rd);
903 if (addr & 1)
904 {
905 addr &= ~1;
906 }
907 else
908 {
909 set_cpsr(GET_CPSR & ~T_MASK);
910 if (addr & 2)
911 {
912 addr += 2;
913 }
914 }
915 R15 = addr;
916 }
917
tg04_01_31(uint32_t pc,uint32_t op)918 void arm7_cpu_device::tg04_01_31(uint32_t pc, uint32_t op)
919 {
920 uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
921 uint32_t addr = GetRegister(rs+8);
922 if (rs == 7)
923 {
924 addr += 2;
925 }
926 if (addr & 1)
927 {
928 addr &= ~1;
929 }
930 else
931 {
932 set_cpsr(GET_CPSR & ~T_MASK);
933 if (addr & 2)
934 {
935 addr += 2;
936 }
937 }
938 R15 = addr;
939 }
940
941 /* BLX */
tg04_01_32(uint32_t pc,uint32_t op)942 void arm7_cpu_device::tg04_01_32(uint32_t pc, uint32_t op)
943 {
944 uint32_t addr = GetRegister((op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT);
945 SetRegister(14, (R15 + 2) | 1);
946
947 // are we also switching to ARM mode?
948 if (!(addr & 1))
949 {
950 set_cpsr(GET_CPSR & ~T_MASK);
951 if (addr & 2)
952 {
953 addr += 2;
954 }
955 }
956 else
957 {
958 addr &= ~1;
959 }
960
961 R15 = addr;
962 }
963
tg04_01_33(uint32_t pc,uint32_t op)964 void arm7_cpu_device::tg04_01_33(uint32_t pc, uint32_t op)
965 {
966 fatalerror("%08x: G4-3 Undefined Thumb instruction: %04x\n", pc, op);
967 }
968
tg04_0203(uint32_t pc,uint32_t op)969 void arm7_cpu_device::tg04_0203(uint32_t pc, uint32_t op)
970 {
971 uint32_t readword = READ32((R15 & ~2) + 4 + ((op & THUMB_INSN_IMM) << 2));
972 SetRegister((op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, readword);
973 R15 += 2;
974 }
975
976 /* LDR* STR* group */
977
tg05_0(uint32_t pc,uint32_t op)978 void arm7_cpu_device::tg05_0(uint32_t pc, uint32_t op) /* STR Rd, [Rn, Rm] */
979 {
980 uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
981 uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
982 uint32_t rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
983 uint32_t addr = GetRegister(rn) + GetRegister(rm);
984 WRITE32(addr, GetRegister(rd));
985 R15 += 2;
986 }
987
tg05_1(uint32_t pc,uint32_t op)988 void arm7_cpu_device::tg05_1(uint32_t pc, uint32_t op) /* STRH Rd, [Rn, Rm] */
989 {
990 uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
991 uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
992 uint32_t rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
993 uint32_t addr = GetRegister(rn) + GetRegister(rm);
994 WRITE16(addr, GetRegister(rd));
995 R15 += 2;
996 }
997
tg05_2(uint32_t pc,uint32_t op)998 void arm7_cpu_device::tg05_2(uint32_t pc, uint32_t op) /* STRB Rd, [Rn, Rm] */
999 {
1000 uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
1001 uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
1002 uint32_t rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
1003 uint32_t addr = GetRegister(rn) + GetRegister(rm);
1004 WRITE8(addr, GetRegister(rd));
1005 R15 += 2;
1006 }
1007
tg05_3(uint32_t pc,uint32_t op)1008 void arm7_cpu_device::tg05_3(uint32_t pc, uint32_t op) /* LDSB Rd, [Rn, Rm] todo, add dasm */
1009 {
1010 uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
1011 uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
1012 uint32_t rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
1013 uint32_t addr = GetRegister(rn) + GetRegister(rm);
1014 uint32_t op2 = READ8(addr);
1015 if (op2 & 0x00000080)
1016 {
1017 op2 |= 0xffffff00;
1018 }
1019 SetRegister(rd, op2);
1020 R15 += 2;
1021 }
1022
tg05_4(uint32_t pc,uint32_t op)1023 void arm7_cpu_device::tg05_4(uint32_t pc, uint32_t op) /* LDR Rd, [Rn, Rm] */
1024 {
1025 uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
1026 uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
1027 uint32_t rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
1028 uint32_t addr = GetRegister(rn) + GetRegister(rm);
1029 uint32_t op2 = READ32(addr);
1030 SetRegister(rd, op2);
1031 R15 += 2;
1032 }
1033
tg05_5(uint32_t pc,uint32_t op)1034 void arm7_cpu_device::tg05_5(uint32_t pc, uint32_t op) /* LDRH Rd, [Rn, Rm] */
1035 {
1036 uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
1037 uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
1038 uint32_t rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
1039 uint32_t addr = GetRegister(rn) + GetRegister(rm);
1040 uint32_t op2 = READ16(addr);
1041 SetRegister(rd, op2);
1042 R15 += 2;
1043 }
1044
tg05_6(uint32_t pc,uint32_t op)1045 void arm7_cpu_device::tg05_6(uint32_t pc, uint32_t op) /* LDRB Rd, [Rn, Rm] */
1046 {
1047 uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
1048 uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
1049 uint32_t rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
1050 uint32_t addr = GetRegister(rn) + GetRegister(rm);
1051 uint32_t op2 = READ8(addr);
1052 SetRegister(rd, op2);
1053 R15 += 2;
1054 }
1055
tg05_7(uint32_t pc,uint32_t op)1056 void arm7_cpu_device::tg05_7(uint32_t pc, uint32_t op) /* LDSH Rd, [Rn, Rm] */
1057 {
1058 uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
1059 uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
1060 uint32_t rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
1061 uint32_t addr = GetRegister(rn) + GetRegister(rm);
1062 int32_t op2 = (int32_t)(int16_t)(uint16_t)READ16(addr & ~1);
1063 if ((addr & 1) && m_archRev < 5)
1064 op2 >>= 8;
1065 SetRegister(rd, op2);
1066 R15 += 2;
1067 }
1068
1069 /* Word Store w/ Immediate Offset */
1070
tg06_0(uint32_t pc,uint32_t op)1071 void arm7_cpu_device::tg06_0(uint32_t pc, uint32_t op) /* Store */
1072 {
1073 uint32_t rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
1074 uint32_t rd = op & THUMB_ADDSUB_RD;
1075 int32_t offs = ((op & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT) << 2;
1076 WRITE32(GetRegister(rn) + offs, GetRegister(rd));
1077 R15 += 2;
1078 }
1079
tg06_1(uint32_t pc,uint32_t op)1080 void arm7_cpu_device::tg06_1(uint32_t pc, uint32_t op) /* Load */
1081 {
1082 uint32_t rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
1083 uint32_t rd = op & THUMB_ADDSUB_RD;
1084 int32_t offs = ((op & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT) << 2;
1085 SetRegister(rd, READ32(GetRegister(rn) + offs)); // fix
1086 R15 += 2;
1087 }
1088
1089 /* Byte Store w/ Immeidate Offset */
1090
tg07_0(uint32_t pc,uint32_t op)1091 void arm7_cpu_device::tg07_0(uint32_t pc, uint32_t op) /* Store */
1092 {
1093 uint32_t rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
1094 uint32_t rd = op & THUMB_ADDSUB_RD;
1095 int32_t offs = (op & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT;
1096 WRITE8(GetRegister(rn) + offs, GetRegister(rd));
1097 R15 += 2;
1098 }
1099
tg07_1(uint32_t pc,uint32_t op)1100 void arm7_cpu_device::tg07_1(uint32_t pc, uint32_t op) /* Load */
1101 {
1102 uint32_t rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
1103 uint32_t rd = op & THUMB_ADDSUB_RD;
1104 int32_t offs = (op & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT;
1105 SetRegister(rd, READ8(GetRegister(rn) + offs));
1106 R15 += 2;
1107 }
1108
1109 /* Load/Store Halfword */
1110
tg08_0(uint32_t pc,uint32_t op)1111 void arm7_cpu_device::tg08_0(uint32_t pc, uint32_t op) /* Store */
1112 {
1113 uint32_t imm = (op & THUMB_HALFOP_OFFS) >> THUMB_HALFOP_OFFS_SHIFT;
1114 uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
1115 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
1116 WRITE16(GetRegister(rs) + (imm << 1), GetRegister(rd));
1117 R15 += 2;
1118 }
1119
tg08_1(uint32_t pc,uint32_t op)1120 void arm7_cpu_device::tg08_1(uint32_t pc, uint32_t op) /* Load */
1121 {
1122 uint32_t imm = (op & THUMB_HALFOP_OFFS) >> THUMB_HALFOP_OFFS_SHIFT;
1123 uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
1124 uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
1125 SetRegister(rd, READ16(GetRegister(rs) + (imm << 1)));
1126 R15 += 2;
1127 }
1128
1129 /* Stack-Relative Load/Store */
1130
tg09_0(uint32_t pc,uint32_t op)1131 void arm7_cpu_device::tg09_0(uint32_t pc, uint32_t op) /* Store */
1132 {
1133 uint32_t rd = (op & THUMB_STACKOP_RD) >> THUMB_STACKOP_RD_SHIFT;
1134 int32_t offs = (uint8_t)(op & THUMB_INSN_IMM);
1135 WRITE32(GetRegister(13) + ((uint32_t)offs << 2), GetRegister(rd));
1136 R15 += 2;
1137 }
1138
tg09_1(uint32_t pc,uint32_t op)1139 void arm7_cpu_device::tg09_1(uint32_t pc, uint32_t op) /* Load */
1140 {
1141 uint32_t rd = (op & THUMB_STACKOP_RD) >> THUMB_STACKOP_RD_SHIFT;
1142 int32_t offs = (uint8_t)(op & THUMB_INSN_IMM);
1143 uint32_t readword = READ32((GetRegister(13) + ((uint32_t)offs << 2)) & ~3);
1144 SetRegister(rd, readword);
1145 R15 += 2;
1146 }
1147
1148 /* Get relative address */
1149
tg0a_0(uint32_t pc,uint32_t op)1150 void arm7_cpu_device::tg0a_0(uint32_t pc, uint32_t op) /* ADD Rd, PC, #nn */
1151 {
1152 uint32_t rd = (op & THUMB_RELADDR_RD) >> THUMB_RELADDR_RD_SHIFT;
1153 int32_t offs = (uint8_t)(op & THUMB_INSN_IMM) << 2;
1154 SetRegister(rd, ((R15 + 4) & ~2) + offs);
1155 R15 += 2;
1156 }
1157
tg0a_1(uint32_t pc,uint32_t op)1158 void arm7_cpu_device::tg0a_1(uint32_t pc, uint32_t op) /* ADD Rd, SP, #nn */
1159 {
1160 uint32_t rd = (op & THUMB_RELADDR_RD) >> THUMB_RELADDR_RD_SHIFT;
1161 int32_t offs = (uint8_t)(op & THUMB_INSN_IMM) << 2;
1162 SetRegister(rd, GetRegister(13) + offs);
1163 R15 += 2;
1164 }
1165
1166 /* Stack-Related Opcodes */
1167
tg0b_0(uint32_t pc,uint32_t op)1168 void arm7_cpu_device::tg0b_0(uint32_t pc, uint32_t op) /* ADD SP, #imm */
1169 {
1170 uint32_t addr = (op & THUMB_INSN_IMM);
1171 addr &= ~THUMB_INSN_IMM_S;
1172 SetRegister(13, GetRegister(13) + ((op & THUMB_INSN_IMM_S) ? -(addr << 2) : (addr << 2)));
1173 R15 += 2;
1174 }
1175
tg0b_1(uint32_t pc,uint32_t op)1176 void arm7_cpu_device::tg0b_1(uint32_t pc, uint32_t op)
1177 {
1178 fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1179 }
1180
tg0b_2(uint32_t pc,uint32_t op)1181 void arm7_cpu_device::tg0b_2(uint32_t pc, uint32_t op)
1182 {
1183 fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1184 }
1185
tg0b_3(uint32_t pc,uint32_t op)1186 void arm7_cpu_device::tg0b_3(uint32_t pc, uint32_t op)
1187 {
1188 fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1189 }
1190
tg0b_4(uint32_t pc,uint32_t op)1191 void arm7_cpu_device::tg0b_4(uint32_t pc, uint32_t op) /* PUSH {Rlist} */
1192 {
1193 for (int32_t offs = 7; offs >= 0; offs--)
1194 {
1195 if (op & (1 << offs))
1196 {
1197 SetRegister(13, GetRegister(13) - 4);
1198 WRITE32(GetRegister(13), GetRegister(offs));
1199 }
1200 }
1201 R15 += 2;
1202 }
1203
tg0b_5(uint32_t pc,uint32_t op)1204 void arm7_cpu_device::tg0b_5(uint32_t pc, uint32_t op) /* PUSH {Rlist}{LR} */
1205 {
1206 SetRegister(13, GetRegister(13) - 4);
1207 WRITE32(GetRegister(13), GetRegister(14));
1208 for (int32_t offs = 7; offs >= 0; offs--)
1209 {
1210 if (op & (1 << offs))
1211 {
1212 SetRegister(13, GetRegister(13) - 4);
1213 WRITE32(GetRegister(13), GetRegister(offs));
1214 }
1215 }
1216 R15 += 2;
1217 }
1218
tg0b_6(uint32_t pc,uint32_t op)1219 void arm7_cpu_device::tg0b_6(uint32_t pc, uint32_t op)
1220 {
1221 fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1222 }
1223
tg0b_7(uint32_t pc,uint32_t op)1224 void arm7_cpu_device::tg0b_7(uint32_t pc, uint32_t op)
1225 {
1226 fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1227 }
1228
tg0b_8(uint32_t pc,uint32_t op)1229 void arm7_cpu_device::tg0b_8(uint32_t pc, uint32_t op)
1230 {
1231 fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1232 }
1233
tg0b_9(uint32_t pc,uint32_t op)1234 void arm7_cpu_device::tg0b_9(uint32_t pc, uint32_t op)
1235 {
1236 fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1237 }
1238
tg0b_a(uint32_t pc,uint32_t op)1239 void arm7_cpu_device::tg0b_a(uint32_t pc, uint32_t op)
1240 {
1241 fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1242 }
1243
tg0b_b(uint32_t pc,uint32_t op)1244 void arm7_cpu_device::tg0b_b(uint32_t pc, uint32_t op)
1245 {
1246 fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1247 }
1248
tg0b_c(uint32_t pc,uint32_t op)1249 void arm7_cpu_device::tg0b_c(uint32_t pc, uint32_t op) /* POP {Rlist} */
1250 {
1251 for (int32_t offs = 0; offs < 8; offs++)
1252 {
1253 if (op & (1 << offs))
1254 {
1255 SetRegister(offs, READ32(GetRegister(13) & ~3));
1256 SetRegister(13, GetRegister(13) + 4);
1257 }
1258 }
1259 R15 += 2;
1260 }
1261
tg0b_d(uint32_t pc,uint32_t op)1262 void arm7_cpu_device::tg0b_d(uint32_t pc, uint32_t op) /* POP {Rlist}{PC} */
1263 {
1264 for (int32_t offs = 0; offs < 8; offs++)
1265 {
1266 if (op & (1 << offs))
1267 {
1268 SetRegister(offs, READ32(GetRegister(13) & ~3));
1269 SetRegister(13, GetRegister(13) + 4);
1270 }
1271 }
1272 uint32_t addr = READ32(GetRegister(13) & ~3);
1273 if (m_archRev < 5)
1274 {
1275 R15 = addr & ~1;
1276 }
1277 else
1278 {
1279 if (addr & 1)
1280 {
1281 addr &= ~1;
1282 }
1283 else
1284 {
1285 set_cpsr(GET_CPSR & ~T_MASK);
1286 if (addr & 2)
1287 {
1288 addr += 2;
1289 }
1290 }
1291
1292 R15 = addr;
1293 }
1294 SetRegister(13, GetRegister(13) + 4);
1295 }
1296
tg0b_e(uint32_t pc,uint32_t op)1297 void arm7_cpu_device::tg0b_e(uint32_t pc, uint32_t op)
1298 {
1299 fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1300 }
1301
tg0b_f(uint32_t pc,uint32_t op)1302 void arm7_cpu_device::tg0b_f(uint32_t pc, uint32_t op)
1303 {
1304 fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1305 }
1306
1307 /* Multiple Load/Store */
1308
1309 // "The address should normally be a word aligned quantity and non-word aligned addresses do not affect the instruction."
1310 // "However, the bottom 2 bits of the address will appear on A[1:0] and might be interpreted by the memory system."
1311
1312 // Endrift says LDMIA/STMIA ignore the low 2 bits and GBA Test Suite assumes it.
1313
tg0c_0(uint32_t pc,uint32_t op)1314 void arm7_cpu_device::tg0c_0(uint32_t pc, uint32_t op) /* Store */
1315 {
1316 uint32_t rd = (op & THUMB_MULTLS_BASE) >> THUMB_MULTLS_BASE_SHIFT;
1317 uint32_t ld_st_address = GetRegister(rd);
1318 for (int32_t offs = 0; offs < 8; offs++)
1319 {
1320 if (op & (1 << offs))
1321 {
1322 WRITE32(ld_st_address & ~3, GetRegister(offs));
1323 ld_st_address += 4;
1324 }
1325 }
1326 SetRegister(rd, ld_st_address);
1327 R15 += 2;
1328 }
1329
tg0c_1(uint32_t pc,uint32_t op)1330 void arm7_cpu_device::tg0c_1(uint32_t pc, uint32_t op) /* Load */
1331 {
1332 uint32_t rd = (op & THUMB_MULTLS_BASE) >> THUMB_MULTLS_BASE_SHIFT;
1333 int rd_in_list = op & (1 << rd);
1334 uint32_t ld_st_address = GetRegister(rd);
1335 for (int32_t offs = 0; offs < 8; offs++)
1336 {
1337 if (op & (1 << offs))
1338 {
1339 SetRegister(offs, READ32(ld_st_address & ~3));
1340 ld_st_address += 4;
1341 }
1342 }
1343 if (!rd_in_list)
1344 {
1345 SetRegister(rd, ld_st_address);
1346 }
1347 R15 += 2;
1348 }
1349
1350 /* Conditional Branch */
1351
tg0d_0(uint32_t pc,uint32_t op)1352 void arm7_cpu_device::tg0d_0(uint32_t pc, uint32_t op) // COND_EQ:
1353 {
1354 int32_t offs = (int8_t)(op & THUMB_INSN_IMM);
1355 if (Z_IS_SET(GET_CPSR))
1356 {
1357 R15 += 4 + (offs << 1);
1358 }
1359 else
1360 {
1361 R15 += 2;
1362 }
1363
1364 }
1365
tg0d_1(uint32_t pc,uint32_t op)1366 void arm7_cpu_device::tg0d_1(uint32_t pc, uint32_t op) // COND_NE:
1367 {
1368 int32_t offs = (int8_t)(op & THUMB_INSN_IMM);
1369 if (Z_IS_CLEAR(GET_CPSR))
1370 {
1371 R15 += 4 + (offs << 1);
1372 }
1373 else
1374 {
1375 R15 += 2;
1376 }
1377 }
1378
tg0d_2(uint32_t pc,uint32_t op)1379 void arm7_cpu_device::tg0d_2(uint32_t pc, uint32_t op) // COND_CS:
1380 {
1381 int32_t offs = (int8_t)(op & THUMB_INSN_IMM);
1382 if (C_IS_SET(GET_CPSR))
1383 {
1384 R15 += 4 + (offs << 1);
1385 }
1386 else
1387 {
1388 R15 += 2;
1389 }
1390 }
1391
tg0d_3(uint32_t pc,uint32_t op)1392 void arm7_cpu_device::tg0d_3(uint32_t pc, uint32_t op) // COND_CC:
1393 {
1394 int32_t offs = (int8_t)(op & THUMB_INSN_IMM);
1395 if (C_IS_CLEAR(GET_CPSR))
1396 {
1397 R15 += 4 + (offs << 1);
1398 }
1399 else
1400 {
1401 R15 += 2;
1402 }
1403 }
1404
tg0d_4(uint32_t pc,uint32_t op)1405 void arm7_cpu_device::tg0d_4(uint32_t pc, uint32_t op) // COND_MI:
1406 {
1407 int32_t offs = (int8_t)(op & THUMB_INSN_IMM);
1408 if (N_IS_SET(GET_CPSR))
1409 {
1410 R15 += 4 + (offs << 1);
1411 }
1412 else
1413 {
1414 R15 += 2;
1415 }
1416 }
1417
tg0d_5(uint32_t pc,uint32_t op)1418 void arm7_cpu_device::tg0d_5(uint32_t pc, uint32_t op) // COND_PL:
1419 {
1420 int32_t offs = (int8_t)(op & THUMB_INSN_IMM);
1421 if (N_IS_CLEAR(GET_CPSR))
1422 {
1423 R15 += 4 + (offs << 1);
1424 }
1425 else
1426 {
1427 R15 += 2;
1428 }
1429 }
1430
tg0d_6(uint32_t pc,uint32_t op)1431 void arm7_cpu_device::tg0d_6(uint32_t pc, uint32_t op) // COND_VS:
1432 {
1433 int32_t offs = (int8_t)(op & THUMB_INSN_IMM);
1434 if (V_IS_SET(GET_CPSR))
1435 {
1436 R15 += 4 + (offs << 1);
1437 }
1438 else
1439 {
1440 R15 += 2;
1441 }
1442 }
1443
tg0d_7(uint32_t pc,uint32_t op)1444 void arm7_cpu_device::tg0d_7(uint32_t pc, uint32_t op) // COND_VC:
1445 {
1446 int32_t offs = (int8_t)(op & THUMB_INSN_IMM);
1447 if (V_IS_CLEAR(GET_CPSR))
1448 {
1449 R15 += 4 + (offs << 1);
1450 }
1451 else
1452 {
1453 R15 += 2;
1454 }
1455 }
1456
tg0d_8(uint32_t pc,uint32_t op)1457 void arm7_cpu_device::tg0d_8(uint32_t pc, uint32_t op) // COND_HI:
1458 {
1459 int32_t offs = (int8_t)(op & THUMB_INSN_IMM);
1460 if (C_IS_SET(GET_CPSR) && Z_IS_CLEAR(GET_CPSR))
1461 {
1462 R15 += 4 + (offs << 1);
1463 }
1464 else
1465 {
1466 R15 += 2;
1467 }
1468 }
1469
tg0d_9(uint32_t pc,uint32_t op)1470 void arm7_cpu_device::tg0d_9(uint32_t pc, uint32_t op) // COND_LS:
1471 {
1472 int32_t offs = (int8_t)(op & THUMB_INSN_IMM);
1473 if (C_IS_CLEAR(GET_CPSR) || Z_IS_SET(GET_CPSR))
1474 {
1475 R15 += 4 + (offs << 1);
1476 }
1477 else
1478 {
1479 R15 += 2;
1480 }
1481 }
1482
tg0d_a(uint32_t pc,uint32_t op)1483 void arm7_cpu_device::tg0d_a(uint32_t pc, uint32_t op) // COND_GE:
1484 {
1485 int32_t offs = (int8_t)(op & THUMB_INSN_IMM);
1486 if (!(GET_CPSR & N_MASK) == !(GET_CPSR & V_MASK))
1487 {
1488 R15 += 4 + (offs << 1);
1489 }
1490 else
1491 {
1492 R15 += 2;
1493 }
1494 }
1495
tg0d_b(uint32_t pc,uint32_t op)1496 void arm7_cpu_device::tg0d_b(uint32_t pc, uint32_t op) // COND_LT:
1497 {
1498 int32_t offs = (int8_t)(op & THUMB_INSN_IMM);
1499 if (!(GET_CPSR & N_MASK) != !(GET_CPSR & V_MASK))
1500 {
1501 R15 += 4 + (offs << 1);
1502 }
1503 else
1504 {
1505 R15 += 2;
1506 }
1507 }
1508
tg0d_c(uint32_t pc,uint32_t op)1509 void arm7_cpu_device::tg0d_c(uint32_t pc, uint32_t op) // COND_GT:
1510 {
1511 int32_t offs = (int8_t)(op & THUMB_INSN_IMM);
1512 if (Z_IS_CLEAR(GET_CPSR) && !(GET_CPSR & N_MASK) == !(GET_CPSR & V_MASK))
1513 {
1514 R15 += 4 + (offs << 1);
1515 }
1516 else
1517 {
1518 R15 += 2;
1519 }
1520 }
1521
tg0d_d(uint32_t pc,uint32_t op)1522 void arm7_cpu_device::tg0d_d(uint32_t pc, uint32_t op) // COND_LE:
1523 {
1524 int32_t offs = (int8_t)(op & THUMB_INSN_IMM);
1525 if (Z_IS_SET(GET_CPSR) || !(GET_CPSR & N_MASK) != !(GET_CPSR & V_MASK))
1526 {
1527 R15 += 4 + (offs << 1);
1528 }
1529 else
1530 {
1531 R15 += 2;
1532 }
1533 }
1534
tg0d_e(uint32_t pc,uint32_t op)1535 void arm7_cpu_device::tg0d_e(uint32_t pc, uint32_t op) // COND_AL:
1536 {
1537 fatalerror("%08x: Undefined Thumb instruction: %04x (ARM9 reserved)\n", pc, op);
1538 }
1539
tg0d_f(uint32_t pc,uint32_t op)1540 void arm7_cpu_device::tg0d_f(uint32_t pc, uint32_t op) // COND_NV: // SWI (this is sort of a "hole" in the opcode encoding)
1541 {
1542 m_pendingSwi = 1;
1543 update_irq_state();
1544 arm7_check_irq_state();
1545 }
1546
1547 /* B #offs */
1548
tg0e_0(uint32_t pc,uint32_t op)1549 void arm7_cpu_device::tg0e_0(uint32_t pc, uint32_t op)
1550 {
1551 int32_t offs = (op & THUMB_BRANCH_OFFS) << 1;
1552 if (offs & 0x00000800)
1553 {
1554 offs |= 0xfffff800;
1555 }
1556 R15 += 4 + offs;
1557 }
1558
tg0e_1(uint32_t pc,uint32_t op)1559 void arm7_cpu_device::tg0e_1(uint32_t pc, uint32_t op)
1560 {
1561 /* BLX (LO) */
1562
1563 uint32_t addr = GetRegister(14);
1564 addr += (op & THUMB_BLOP_OFFS) << 1;
1565 addr &= 0xfffffffc;
1566 SetRegister(14, (R15 + 2) | 1);
1567 R15 = addr;
1568 set_cpsr(GET_CPSR & ~T_MASK);
1569 }
1570
1571
tg0f_0(uint32_t pc,uint32_t op)1572 void arm7_cpu_device::tg0f_0(uint32_t pc, uint32_t op)
1573 {
1574 /* BL (HI) */
1575
1576 uint32_t addr = (op & THUMB_BLOP_OFFS) << 12;
1577 if (addr & (1 << 22))
1578 {
1579 addr |= 0xff800000;
1580 }
1581 addr += R15 + 4;
1582 SetRegister(14, addr);
1583 R15 += 2;
1584 }
1585
tg0f_1(uint32_t pc,uint32_t op)1586 void arm7_cpu_device::tg0f_1(uint32_t pc, uint32_t op) /* BL */
1587 {
1588 /* BL (LO) */
1589
1590 uint32_t addr = GetRegister(14) & ~1;
1591 addr += (op & THUMB_BLOP_OFFS) << 1;
1592 SetRegister(14, (R15 + 2) | 1);
1593 R15 = addr;
1594 //R15 += 2;
1595 }
1596