Commit 28b6751f30603a4c7146282fde9efcf8b5f31f7b
1 parent
79aceca5
suppressed use of gen_multi - use intermediate FT0 register for floats - use T0 …
…temporary for fpscr update - use PARAM1 for spr access - added untested single load/store support git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@473 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
385 additions
and
227 deletions
target-ppc/cpu.h
@@ -172,6 +172,7 @@ typedef struct CPUPPCState { | @@ -172,6 +172,7 @@ typedef struct CPUPPCState { | ||
172 | uint32_t exception; | 172 | uint32_t exception; |
173 | 173 | ||
174 | /* qemu dedicated */ | 174 | /* qemu dedicated */ |
175 | + uint64_t ft0; /* temporary float register */ | ||
175 | int interrupt_request; | 176 | int interrupt_request; |
176 | jmp_buf jmp_env; | 177 | jmp_buf jmp_env; |
177 | int exception_index; | 178 | int exception_index; |
target-ppc/op.c
@@ -22,20 +22,110 @@ | @@ -22,20 +22,110 @@ | ||
22 | #include "exec.h" | 22 | #include "exec.h" |
23 | 23 | ||
24 | #define regs (env) | 24 | #define regs (env) |
25 | -extern uint32_t __a; | ||
26 | -extern uint32_t __b; | ||
27 | -extern uint32_t __c; | ||
28 | -extern uint32_t __d; | ||
29 | -extern uint32_t __e; | ||
30 | -extern uint32_t __f; | ||
31 | #define Ts0 (int32_t)T0 | 25 | #define Ts0 (int32_t)T0 |
32 | #define Ts1 (int32_t)T1 | 26 | #define Ts1 (int32_t)T1 |
33 | #define Ts2 (int32_t)T2 | 27 | #define Ts2 (int32_t)T2 |
34 | 28 | ||
35 | -#include "op-multi.c" | 29 | +#define FT0 (env->ft0) |
36 | 30 | ||
37 | #define PPC_OP(name) void op_##name(void) | 31 | #define PPC_OP(name) void op_##name(void) |
38 | 32 | ||
33 | +#define REG 0 | ||
34 | +#include "op_template.h" | ||
35 | + | ||
36 | +#define REG 1 | ||
37 | +#include "op_template.h" | ||
38 | + | ||
39 | +#define REG 2 | ||
40 | +#include "op_template.h" | ||
41 | + | ||
42 | +#define REG 3 | ||
43 | +#include "op_template.h" | ||
44 | + | ||
45 | +#define REG 4 | ||
46 | +#include "op_template.h" | ||
47 | + | ||
48 | +#define REG 5 | ||
49 | +#include "op_template.h" | ||
50 | + | ||
51 | +#define REG 6 | ||
52 | +#include "op_template.h" | ||
53 | + | ||
54 | +#define REG 7 | ||
55 | +#include "op_template.h" | ||
56 | + | ||
57 | +#define REG 8 | ||
58 | +#include "op_template.h" | ||
59 | + | ||
60 | +#define REG 9 | ||
61 | +#include "op_template.h" | ||
62 | + | ||
63 | +#define REG 10 | ||
64 | +#include "op_template.h" | ||
65 | + | ||
66 | +#define REG 11 | ||
67 | +#include "op_template.h" | ||
68 | + | ||
69 | +#define REG 12 | ||
70 | +#include "op_template.h" | ||
71 | + | ||
72 | +#define REG 13 | ||
73 | +#include "op_template.h" | ||
74 | + | ||
75 | +#define REG 14 | ||
76 | +#include "op_template.h" | ||
77 | + | ||
78 | +#define REG 15 | ||
79 | +#include "op_template.h" | ||
80 | + | ||
81 | +#define REG 16 | ||
82 | +#include "op_template.h" | ||
83 | + | ||
84 | +#define REG 17 | ||
85 | +#include "op_template.h" | ||
86 | + | ||
87 | +#define REG 18 | ||
88 | +#include "op_template.h" | ||
89 | + | ||
90 | +#define REG 19 | ||
91 | +#include "op_template.h" | ||
92 | + | ||
93 | +#define REG 20 | ||
94 | +#include "op_template.h" | ||
95 | + | ||
96 | +#define REG 21 | ||
97 | +#include "op_template.h" | ||
98 | + | ||
99 | +#define REG 22 | ||
100 | +#include "op_template.h" | ||
101 | + | ||
102 | +#define REG 23 | ||
103 | +#include "op_template.h" | ||
104 | + | ||
105 | +#define REG 24 | ||
106 | +#include "op_template.h" | ||
107 | + | ||
108 | +#define REG 25 | ||
109 | +#include "op_template.h" | ||
110 | + | ||
111 | +#define REG 26 | ||
112 | +#include "op_template.h" | ||
113 | + | ||
114 | +#define REG 27 | ||
115 | +#include "op_template.h" | ||
116 | + | ||
117 | +#define REG 28 | ||
118 | +#include "op_template.h" | ||
119 | + | ||
120 | +#define REG 29 | ||
121 | +#include "op_template.h" | ||
122 | + | ||
123 | +#define REG 30 | ||
124 | +#include "op_template.h" | ||
125 | + | ||
126 | +#define REG 31 | ||
127 | +#include "op_template.h" | ||
128 | + | ||
39 | /* PPC state maintenance operations */ | 129 | /* PPC state maintenance operations */ |
40 | /* set_Rc0 */ | 130 | /* set_Rc0 */ |
41 | PPC_OP(set_Rc0) | 131 | PPC_OP(set_Rc0) |
@@ -1114,3 +1204,135 @@ PPC_OP(stswx) | @@ -1114,3 +1204,135 @@ PPC_OP(stswx) | ||
1114 | do_stsw(PARAM(1), T0, T1 + T2); | 1204 | do_stsw(PARAM(1), T0, T1 + T2); |
1115 | RETURN(); | 1205 | RETURN(); |
1116 | } | 1206 | } |
1207 | + | ||
1208 | +/* SPR */ | ||
1209 | +PPC_OP(load_spr) | ||
1210 | +{ | ||
1211 | + T0 = regs->spr[PARAM(1)]; | ||
1212 | +} | ||
1213 | + | ||
1214 | +PPC_OP(store_spr) | ||
1215 | +{ | ||
1216 | + regs->spr[PARAM(1)] = T0; | ||
1217 | +} | ||
1218 | + | ||
1219 | +/* FPSCR */ | ||
1220 | +PPC_OP(load_fpscr) | ||
1221 | +{ | ||
1222 | + T0 = do_load_fpscr(); | ||
1223 | +} | ||
1224 | + | ||
1225 | +PPC_OP(store_fpscr) | ||
1226 | +{ | ||
1227 | + do_store_fpscr(PARAM(1), T0); | ||
1228 | +} | ||
1229 | + | ||
1230 | +/*** Floating-point store ***/ | ||
1231 | + | ||
1232 | +static inline uint32_t dtos(uint64_t f) | ||
1233 | +{ | ||
1234 | + unsigned int e, m, s; | ||
1235 | + e = (((f >> 52) & 0x7ff) - 1022) + 126; | ||
1236 | + s = (f >> 63); | ||
1237 | + m = (f >> 29); | ||
1238 | + return (s << 31) | (e << 23) | m; | ||
1239 | +} | ||
1240 | + | ||
1241 | +static inline uint64_t stod(uint32_t f) | ||
1242 | +{ | ||
1243 | + unsigned int e, m, s; | ||
1244 | + e = ((f >> 23) & 0xff) - 126 + 1022; | ||
1245 | + s = f >> 31; | ||
1246 | + m = f & ((1 << 23) - 1); | ||
1247 | + return ((uint64_t)s << 63) | ((uint64_t)e << 52) | ((uint64_t)m << 29); | ||
1248 | +} | ||
1249 | + | ||
1250 | +PPC_OP(stfd_z_FT0) | ||
1251 | +{ | ||
1252 | + st64(SPARAM(1), FT0); | ||
1253 | +} | ||
1254 | + | ||
1255 | +PPC_OP(stfd_FT0) | ||
1256 | +{ | ||
1257 | + T0 += SPARAM(1); | ||
1258 | + st64(T0, FT0); | ||
1259 | +} | ||
1260 | + | ||
1261 | +PPC_OP(stfdx_z_FT0) | ||
1262 | +{ | ||
1263 | + st64(T0, FT0); | ||
1264 | +} | ||
1265 | + | ||
1266 | +PPC_OP(stfdx_FT0) | ||
1267 | +{ | ||
1268 | + T0 += T1; | ||
1269 | + st64(T0, FT0); | ||
1270 | +} | ||
1271 | + | ||
1272 | + | ||
1273 | +PPC_OP(stfs_z_FT0) | ||
1274 | +{ | ||
1275 | + st32(SPARAM(1), dtos(FT0)); | ||
1276 | +} | ||
1277 | + | ||
1278 | +PPC_OP(stfs_FT0) | ||
1279 | +{ | ||
1280 | + T0 += SPARAM(1); | ||
1281 | + st32(T0, dtos(FT0)); | ||
1282 | +} | ||
1283 | + | ||
1284 | +PPC_OP(stfsx_z_FT0) | ||
1285 | +{ | ||
1286 | + st32(T0, dtos(FT0)); | ||
1287 | +} | ||
1288 | + | ||
1289 | +PPC_OP(stfsx_FT0) | ||
1290 | +{ | ||
1291 | + T0 += T1; | ||
1292 | + st32(T0, dtos(FT0)); | ||
1293 | +} | ||
1294 | + | ||
1295 | +/*** Floating-point load ***/ | ||
1296 | +PPC_OP(lfd_z_FT0) | ||
1297 | +{ | ||
1298 | + FT0 = ld64(SPARAM(1)); | ||
1299 | +} | ||
1300 | + | ||
1301 | +PPC_OP(lfd_FT0) | ||
1302 | +{ | ||
1303 | + T0 += SPARAM(1); | ||
1304 | + FT0 = ld64(T0); | ||
1305 | +} | ||
1306 | + | ||
1307 | +PPC_OP(lfdx_z_FT0) | ||
1308 | +{ | ||
1309 | + FT0 = ld64(T0); | ||
1310 | +} | ||
1311 | + | ||
1312 | +PPC_OP(lfdx_FT0) | ||
1313 | +{ | ||
1314 | + T0 += T1; | ||
1315 | + FT0 = ld64(T0); | ||
1316 | +} | ||
1317 | + | ||
1318 | +PPC_OP(lfs_z_FT0) | ||
1319 | +{ | ||
1320 | + FT0 = stod(ld32(SPARAM(1))); | ||
1321 | +} | ||
1322 | + | ||
1323 | +PPC_OP(lfs_FT0) | ||
1324 | +{ | ||
1325 | + T0 += SPARAM(1); | ||
1326 | + FT0 = stod(ld32(T0)); | ||
1327 | +} | ||
1328 | + | ||
1329 | +PPC_OP(lfsx_z_FT0) | ||
1330 | +{ | ||
1331 | + FT0 = stod(ld32(T0)); | ||
1332 | +} | ||
1333 | + | ||
1334 | +PPC_OP(lfsx_FT0) | ||
1335 | +{ | ||
1336 | + T0 += T1; | ||
1337 | + FT0 = stod(ld32(T0)); | ||
1338 | +} |
target-ppc/op.tpl deleted
100644 → 0
1 | -/* | ||
2 | - * PPC emulation micro-operations for qemu. | ||
3 | - * | ||
4 | - * Copyright (c) 2003 Jocelyn Mayer | ||
5 | - * | ||
6 | - * This library is free software; you can redistribute it and/or | ||
7 | - * modify it under the terms of the GNU Lesser General Public | ||
8 | - * License as published by the Free Software Foundation; either | ||
9 | - * version 2 of the License, or (at your option) any later version. | ||
10 | - * | ||
11 | - * This library is distributed in the hope that it will be useful, | ||
12 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | - * Lesser General Public License for more details. | ||
15 | - * | ||
16 | - * You should have received a copy of the GNU Lesser General Public | ||
17 | - * License along with this library; if not, write to the Free Software | ||
18 | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | - */ | ||
20 | - | ||
21 | -/* Host registers definitions */ | ||
22 | -$DEFH T 3 | ||
23 | -/* PPC registers definitions */ | ||
24 | -$DEF gpr 32 | ||
25 | -$DEF fpr 32 | ||
26 | -$DEF crf 8 | ||
27 | -$DEF spr 1024 | ||
28 | - | ||
29 | -/* PPC registers <-> host registers move */ | ||
30 | -/* GPR */ | ||
31 | -$OP load_gpr_T0 gpr | ||
32 | -{ | ||
33 | - T0 = regs->gpra; | ||
34 | - RETURN(); | ||
35 | -} | ||
36 | -$ENDOP | ||
37 | - | ||
38 | -$OP load_gpr_T1 gpr | ||
39 | -{ | ||
40 | - T1 = regs->gpra; | ||
41 | - RETURN(); | ||
42 | -} | ||
43 | -$ENDOP | ||
44 | - | ||
45 | -$OP load_gpr_T2 gpr | ||
46 | -{ | ||
47 | - T2 = regs->gpra; | ||
48 | - RETURN(); | ||
49 | -} | ||
50 | -$ENDOP | ||
51 | - | ||
52 | -$OP store_T0_gpr gpr | ||
53 | -{ | ||
54 | - regs->gpra = T0; | ||
55 | - RETURN(); | ||
56 | -} | ||
57 | -$ENDOP | ||
58 | - | ||
59 | -$OP store_T1_gpr gpr | ||
60 | -{ | ||
61 | - regs->gpra = T1; | ||
62 | - RETURN(); | ||
63 | -} | ||
64 | -$ENDOP | ||
65 | - | ||
66 | -$OP store_gpr_P gpr PARAM | ||
67 | -{ | ||
68 | - regs->gpra = PARAM(1); | ||
69 | - RETURN(); | ||
70 | -} | ||
71 | -$ENDOP | ||
72 | - | ||
73 | -/* crf */ | ||
74 | -$OP load_crf_T0 crf | ||
75 | -{ | ||
76 | - T0 = regs->crfa; | ||
77 | - RETURN(); | ||
78 | -} | ||
79 | -$ENDOP | ||
80 | - | ||
81 | -$OP load_crf_T1 crf | ||
82 | -{ | ||
83 | - T1 = regs->crfa; | ||
84 | - RETURN(); | ||
85 | -} | ||
86 | -$ENDOP | ||
87 | - | ||
88 | -$OP store_T0_crf crf | ||
89 | -{ | ||
90 | - regs->crfa = T0; | ||
91 | - RETURN(); | ||
92 | -} | ||
93 | -$ENDOP | ||
94 | - | ||
95 | -$OP store_T1_crf crf | ||
96 | -{ | ||
97 | - regs->crfa = T1; | ||
98 | - RETURN(); | ||
99 | -} | ||
100 | -$ENDOP | ||
101 | - | ||
102 | -/* SPR */ | ||
103 | -$OP load_spr spr | ||
104 | -{ | ||
105 | - T0 = regs->spra; | ||
106 | - RETURN(); | ||
107 | -} | ||
108 | -$ENDOP | ||
109 | - | ||
110 | -$OP store_spr spr | ||
111 | -{ | ||
112 | - regs->spra = T0; | ||
113 | - RETURN(); | ||
114 | -} | ||
115 | -$ENDOP | ||
116 | - | ||
117 | -/* FPSCR */ | ||
118 | -$OP load_fpscr fpr | ||
119 | -{ | ||
120 | - regs->fpra = do_load_fpscr(); | ||
121 | - RETURN(); | ||
122 | -} | ||
123 | -$ENDOP | ||
124 | - | ||
125 | -$OP store_fpscr fpr PARAM | ||
126 | -{ | ||
127 | - do_store_fpscr(PARAM(1), regs->fpra); | ||
128 | - RETURN(); | ||
129 | -} | ||
130 | -$ENDOP | ||
131 | - | ||
132 | -/*** Floating-point store ***/ | ||
133 | -/* candidate for helper (too long on x86 host) */ | ||
134 | -$OP stfd_z fpr PARAM | ||
135 | -{ | ||
136 | - st64(SPARAM(1), regs->fpra); | ||
137 | - RETURN(); | ||
138 | -} | ||
139 | -$ENDOP | ||
140 | - | ||
141 | -/* candidate for helper (too long on x86 host) */ | ||
142 | -$OP stfd fpr PARAM | ||
143 | -{ | ||
144 | - T0 += SPARAM(1); | ||
145 | - st64(T0, regs->fpra); | ||
146 | - RETURN(); | ||
147 | -} | ||
148 | -$ENDOP | ||
149 | - | ||
150 | -/* candidate for helper (too long on x86 host) */ | ||
151 | -$OP stfdx_z fpr | ||
152 | -{ | ||
153 | - st64(T0, regs->fpra); | ||
154 | - RETURN(); | ||
155 | -} | ||
156 | -$ENDOP | ||
157 | -/* candidate for helper (too long on x86 host) */ | ||
158 | -$OP stfdx fpr | ||
159 | -{ | ||
160 | - T0 += T1; | ||
161 | - st64(T0, regs->fpra); | ||
162 | - RETURN(); | ||
163 | -} | ||
164 | -$ENDOP | ||
165 | - | ||
166 | -/* candidate for helper (too long on x86 host) */ | ||
167 | -$OP lfd_z fpr PARAM | ||
168 | -{ | ||
169 | - regs->fpra = ld64(SPARAM(1)); | ||
170 | - RETURN(); | ||
171 | -} | ||
172 | -$ENDOP | ||
173 | - | ||
174 | -/* candidate for helper (too long) */ | ||
175 | -$OP lfd fpr PARAM | ||
176 | -{ | ||
177 | - T0 += SPARAM(1); | ||
178 | - regs->fpra = ld64(T0); | ||
179 | - RETURN(); | ||
180 | -} | ||
181 | -$ENDOP | ||
182 | - | ||
183 | -$OP lfdx_z fpr | ||
184 | -{ | ||
185 | - regs->fpra = ld64(T0); | ||
186 | - RETURN(); | ||
187 | -} | ||
188 | -$ENDOP | ||
189 | - | ||
190 | -$OP lfdx fpr | ||
191 | -{ | ||
192 | - T0 += T1; | ||
193 | - regs->fpra = ld64(T0); | ||
194 | - RETURN(); | ||
195 | -} | ||
196 | -$ENDOP | ||
197 | -/*****************************************************************************/ |
target-ppc/op_template.h
0 → 100644
1 | +/* | ||
2 | + * PPC emulation micro-operations for qemu. | ||
3 | + * | ||
4 | + * Copyright (c) 2003 Jocelyn Mayer | ||
5 | + * | ||
6 | + * This library is free software; you can redistribute it and/or | ||
7 | + * modify it under the terms of the GNU Lesser General Public | ||
8 | + * License as published by the Free Software Foundation; either | ||
9 | + * version 2 of the License, or (at your option) any later version. | ||
10 | + * | ||
11 | + * This library is distributed in the hope that it will be useful, | ||
12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | + * Lesser General Public License for more details. | ||
15 | + * | ||
16 | + * You should have received a copy of the GNU Lesser General Public | ||
17 | + * License along with this library; if not, write to the Free Software | ||
18 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | + */ | ||
20 | + | ||
21 | +void OPPROTO glue(op_load_gpr_T0_gpr, REG)(void) | ||
22 | +{ | ||
23 | + T0 = regs->gpr[REG]; | ||
24 | +} | ||
25 | + | ||
26 | +void OPPROTO glue(op_load_gpr_T1_gpr, REG)(void) | ||
27 | +{ | ||
28 | + T1 = regs->gpr[REG]; | ||
29 | +} | ||
30 | + | ||
31 | +void OPPROTO glue(op_load_gpr_T2_gpr, REG)(void) | ||
32 | +{ | ||
33 | + T2 = regs->gpr[REG]; | ||
34 | +} | ||
35 | + | ||
36 | +void OPPROTO glue(op_store_T0_gpr_gpr, REG)(void) | ||
37 | +{ | ||
38 | + regs->gpr[REG] = T0; | ||
39 | +} | ||
40 | + | ||
41 | +void OPPROTO glue(op_store_T1_gpr_gpr, REG)(void) | ||
42 | +{ | ||
43 | + regs->gpr[REG] = T1; | ||
44 | +} | ||
45 | + | ||
46 | +void OPPROTO glue(op_store_T2_gpr_gpr, REG)(void) | ||
47 | +{ | ||
48 | + regs->gpr[REG] = T2; | ||
49 | +} | ||
50 | + | ||
51 | +#if REG <= 7 | ||
52 | + | ||
53 | +void OPPROTO glue(op_load_crf_T0_crf, REG)(void) | ||
54 | +{ | ||
55 | + T0 = regs->crf[REG]; | ||
56 | +} | ||
57 | + | ||
58 | +void OPPROTO glue(op_load_crf_T1_crf, REG)(void) | ||
59 | +{ | ||
60 | + T1 = regs->crf[REG]; | ||
61 | +} | ||
62 | + | ||
63 | +void OPPROTO glue(op_store_T0_crf_crf, REG)(void) | ||
64 | +{ | ||
65 | + regs->crf[REG] = T0; | ||
66 | +} | ||
67 | + | ||
68 | +void OPPROTO glue(op_store_T1_crf_crf, REG)(void) | ||
69 | +{ | ||
70 | + regs->crf[REG] = T1; | ||
71 | +} | ||
72 | + | ||
73 | +#endif /* REG <= 7 */ | ||
74 | + | ||
75 | +/* float moves */ | ||
76 | + | ||
77 | +void OPPROTO glue(op_load_FT0_fpr, REG)(void) | ||
78 | +{ | ||
79 | + FT0 = env->fpr[REG]; | ||
80 | +} | ||
81 | + | ||
82 | +void OPPROTO glue(op_store_FT0_fpr, REG)(void) | ||
83 | +{ | ||
84 | + env->fpr[REG] = FT0; | ||
85 | +} | ||
86 | + | ||
87 | +#undef REG |
target-ppc/translate.c
@@ -36,7 +36,50 @@ static uint16_t *gen_opc_ptr; | @@ -36,7 +36,50 @@ static uint16_t *gen_opc_ptr; | ||
36 | static uint32_t *gen_opparam_ptr; | 36 | static uint32_t *gen_opparam_ptr; |
37 | 37 | ||
38 | #include "gen-op.h" | 38 | #include "gen-op.h" |
39 | -#include "select.h" | 39 | + |
40 | +typedef void (GenOpFunc)(void); | ||
41 | + | ||
42 | +#define GEN8(func, NAME) \ | ||
43 | +static GenOpFunc *NAME ## _table [8] = {\ | ||
44 | +NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,\ | ||
45 | +NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,\ | ||
46 | +};\ | ||
47 | +static inline void func(int n)\ | ||
48 | +{\ | ||
49 | + NAME ## _table[n]();\ | ||
50 | +} | ||
51 | + | ||
52 | +#define GEN32(func, NAME) \ | ||
53 | +static GenOpFunc *NAME ## _table [32] = {\ | ||
54 | +NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,\ | ||
55 | +NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,\ | ||
56 | +NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,\ | ||
57 | +NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,\ | ||
58 | +NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,\ | ||
59 | +NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,\ | ||
60 | +NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,\ | ||
61 | +NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,\ | ||
62 | +};\ | ||
63 | +static inline void func(int n)\ | ||
64 | +{\ | ||
65 | + NAME ## _table[n]();\ | ||
66 | +} | ||
67 | + | ||
68 | +GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf) | ||
69 | +GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf) | ||
70 | +GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf) | ||
71 | +GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf) | ||
72 | + | ||
73 | +GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr) | ||
74 | +GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr) | ||
75 | +GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr) | ||
76 | + | ||
77 | +GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr) | ||
78 | +GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr) | ||
79 | +GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr) | ||
80 | + | ||
81 | +GEN32(gen_op_load_FT0_fpr, gen_op_load_FT0_fpr) | ||
82 | +GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr) | ||
40 | 83 | ||
41 | static uint8_t spr_access[1024 / 2]; | 84 | static uint8_t spr_access[1024 / 2]; |
42 | 85 | ||
@@ -810,7 +853,8 @@ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT) | @@ -810,7 +853,8 @@ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT) | ||
810 | /* mffs */ | 853 | /* mffs */ |
811 | GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT) | 854 | GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT) |
812 | { | 855 | { |
813 | - gen_op_load_fpscr(rD(ctx->opcode)); | 856 | + gen_op_load_fpscr(); |
857 | + gen_op_store_T0_gpr(rD(ctx->opcode)); | ||
814 | if (Rc(ctx->opcode)) { | 858 | if (Rc(ctx->opcode)) { |
815 | /* Update CR1 */ | 859 | /* Update CR1 */ |
816 | } | 860 | } |
@@ -832,7 +876,8 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT) | @@ -832,7 +876,8 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT) | ||
832 | /* mtfsf */ | 876 | /* mtfsf */ |
833 | GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT) | 877 | GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT) |
834 | { | 878 | { |
835 | - gen_op_store_fpscr(FM(ctx->opcode), rB(ctx->opcode)); | 879 | + gen_op_load_gpr_T0(rB(ctx->opcode)); |
880 | + gen_op_store_fpscr(FM(ctx->opcode)); | ||
836 | if (Rc(ctx->opcode)) { | 881 | if (Rc(ctx->opcode)) { |
837 | /* Update CR1 */ | 882 | /* Update CR1 */ |
838 | } | 883 | } |
@@ -1182,11 +1227,12 @@ GEN_HANDLER(lf##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ | @@ -1182,11 +1227,12 @@ GEN_HANDLER(lf##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ | ||
1182 | { \ | 1227 | { \ |
1183 | uint32_t simm = SIMM(ctx->opcode); \ | 1228 | uint32_t simm = SIMM(ctx->opcode); \ |
1184 | if (rA(ctx->opcode) == 0) { \ | 1229 | if (rA(ctx->opcode) == 0) { \ |
1185 | - gen_op_lf##width##_z(simm, rD(ctx->opcode)); \ | 1230 | + gen_op_lf##width##_z_FT0(simm); \ |
1186 | } else { \ | 1231 | } else { \ |
1187 | gen_op_load_gpr_T0(rA(ctx->opcode)); \ | 1232 | gen_op_load_gpr_T0(rA(ctx->opcode)); \ |
1188 | - gen_op_lf##width(simm, rD(ctx->opcode)); \ | 1233 | + gen_op_lf##width##_FT0(simm); \ |
1189 | } \ | 1234 | } \ |
1235 | + gen_op_store_FT0_fpr(rD(ctx->opcode));\ | ||
1190 | SET_RETVAL(0); \ | 1236 | SET_RETVAL(0); \ |
1191 | } | 1237 | } |
1192 | 1238 | ||
@@ -1197,7 +1243,8 @@ GEN_HANDLER(lf##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ | @@ -1197,7 +1243,8 @@ GEN_HANDLER(lf##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ | ||
1197 | rA(ctx->opcode) == rD(ctx->opcode)) \ | 1243 | rA(ctx->opcode) == rD(ctx->opcode)) \ |
1198 | SET_RETVAL(EXCP_INVAL); \ | 1244 | SET_RETVAL(EXCP_INVAL); \ |
1199 | gen_op_load_gpr_T0(rA(ctx->opcode)); \ | 1245 | gen_op_load_gpr_T0(rA(ctx->opcode)); \ |
1200 | - gen_op_lf##width(SIMM(ctx->opcode), rD(ctx->opcode)); \ | 1246 | + gen_op_lf##width##_FT0(SIMM(ctx->opcode)); \ |
1247 | + gen_op_store_FT0_fpr(rD(ctx->opcode));\ | ||
1201 | gen_op_store_T0_gpr(rA(ctx->opcode)); \ | 1248 | gen_op_store_T0_gpr(rA(ctx->opcode)); \ |
1202 | SET_RETVAL(0); \ | 1249 | SET_RETVAL(0); \ |
1203 | } | 1250 | } |
@@ -1210,7 +1257,8 @@ GEN_HANDLER(lf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ | @@ -1210,7 +1257,8 @@ GEN_HANDLER(lf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ | ||
1210 | SET_RETVAL(EXCP_INVAL); \ | 1257 | SET_RETVAL(EXCP_INVAL); \ |
1211 | gen_op_load_gpr_T0(rA(ctx->opcode)); \ | 1258 | gen_op_load_gpr_T0(rA(ctx->opcode)); \ |
1212 | gen_op_load_gpr_T1(rB(ctx->opcode)); \ | 1259 | gen_op_load_gpr_T1(rB(ctx->opcode)); \ |
1213 | - gen_op_lf##width##x(rD(ctx->opcode)); \ | 1260 | + gen_op_lf##width##x_FT0(); \ |
1261 | + gen_op_store_FT0_fpr(rD(ctx->opcode));\ | ||
1214 | gen_op_store_T0_gpr(rA(ctx->opcode)); \ | 1262 | gen_op_store_T0_gpr(rA(ctx->opcode)); \ |
1215 | SET_RETVAL(0); \ | 1263 | SET_RETVAL(0); \ |
1216 | } | 1264 | } |
@@ -1220,12 +1268,13 @@ GEN_HANDLER(lf##width##x, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ | @@ -1220,12 +1268,13 @@ GEN_HANDLER(lf##width##x, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ | ||
1220 | { \ | 1268 | { \ |
1221 | if (rA(ctx->opcode) == 0) { \ | 1269 | if (rA(ctx->opcode) == 0) { \ |
1222 | gen_op_load_gpr_T0(rB(ctx->opcode)); \ | 1270 | gen_op_load_gpr_T0(rB(ctx->opcode)); \ |
1223 | - gen_op_lf##width##x_z(rD(ctx->opcode)); \ | 1271 | + gen_op_lf##width##x_z_FT0(); \ |
1224 | } else { \ | 1272 | } else { \ |
1225 | gen_op_load_gpr_T0(rA(ctx->opcode)); \ | 1273 | gen_op_load_gpr_T0(rA(ctx->opcode)); \ |
1226 | gen_op_load_gpr_T1(rB(ctx->opcode)); \ | 1274 | gen_op_load_gpr_T1(rB(ctx->opcode)); \ |
1227 | - gen_op_lf##width##x(rD(ctx->opcode)); \ | 1275 | + gen_op_lf##width##x_FT0(); \ |
1228 | } \ | 1276 | } \ |
1277 | + gen_op_store_FT0_fpr(rD(ctx->opcode));\ | ||
1229 | SET_RETVAL(0); \ | 1278 | SET_RETVAL(0); \ |
1230 | } | 1279 | } |
1231 | 1280 | ||
@@ -1238,10 +1287,6 @@ GEN_LFX(width, opc | 0x00) | @@ -1238,10 +1287,6 @@ GEN_LFX(width, opc | 0x00) | ||
1238 | /* lfd lfdu lfdux lfdx */ | 1287 | /* lfd lfdu lfdux lfdx */ |
1239 | GEN_LDF(d, 0x12); | 1288 | GEN_LDF(d, 0x12); |
1240 | /* lfs lfsu lfsux lfsx */ | 1289 | /* lfs lfsu lfsux lfsx */ |
1241 | -#define gen_op_lfs_z(a, b) | ||
1242 | -#define gen_op_lfs(a, b) | ||
1243 | -#define gen_op_lfsx_z(a) | ||
1244 | -#define gen_op_lfsx(a) | ||
1245 | GEN_LDF(s, 0x10); | 1290 | GEN_LDF(s, 0x10); |
1246 | 1291 | ||
1247 | /*** Floating-point store ***/ | 1292 | /*** Floating-point store ***/ |
@@ -1249,11 +1294,12 @@ GEN_LDF(s, 0x10); | @@ -1249,11 +1294,12 @@ GEN_LDF(s, 0x10); | ||
1249 | GEN_HANDLER(stf##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ | 1294 | GEN_HANDLER(stf##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ |
1250 | { \ | 1295 | { \ |
1251 | uint32_t simm = SIMM(ctx->opcode); \ | 1296 | uint32_t simm = SIMM(ctx->opcode); \ |
1297 | + gen_op_load_FT0_fpr(rS(ctx->opcode));\ | ||
1252 | if (rA(ctx->opcode) == 0) { \ | 1298 | if (rA(ctx->opcode) == 0) { \ |
1253 | - gen_op_stf##width##_z(simm, rS(ctx->opcode)); \ | 1299 | + gen_op_stf##width##_z_FT0(simm); \ |
1254 | } else { \ | 1300 | } else { \ |
1255 | gen_op_load_gpr_T0(rA(ctx->opcode)); \ | 1301 | gen_op_load_gpr_T0(rA(ctx->opcode)); \ |
1256 | - gen_op_stf##width(simm, rS(ctx->opcode)); \ | 1302 | + gen_op_stf##width##_FT0(simm); \ |
1257 | } \ | 1303 | } \ |
1258 | SET_RETVAL(0); \ | 1304 | SET_RETVAL(0); \ |
1259 | } | 1305 | } |
@@ -1264,7 +1310,8 @@ GEN_HANDLER(stf##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ | @@ -1264,7 +1310,8 @@ GEN_HANDLER(stf##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ | ||
1264 | if (rA(ctx->opcode) == 0) \ | 1310 | if (rA(ctx->opcode) == 0) \ |
1265 | SET_RETVAL(EXCP_INVAL); \ | 1311 | SET_RETVAL(EXCP_INVAL); \ |
1266 | gen_op_load_gpr_T0(rA(ctx->opcode)); \ | 1312 | gen_op_load_gpr_T0(rA(ctx->opcode)); \ |
1267 | - gen_op_stf##width(SIMM(ctx->opcode), rS(ctx->opcode)); \ | 1313 | + gen_op_load_FT0_fpr(rS(ctx->opcode));\ |
1314 | + gen_op_stf##width##_FT0(SIMM(ctx->opcode)); \ | ||
1268 | gen_op_store_T0_gpr(rA(ctx->opcode)); \ | 1315 | gen_op_store_T0_gpr(rA(ctx->opcode)); \ |
1269 | SET_RETVAL(0); \ | 1316 | SET_RETVAL(0); \ |
1270 | } | 1317 | } |
@@ -1276,7 +1323,8 @@ GEN_HANDLER(stf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ | @@ -1276,7 +1323,8 @@ GEN_HANDLER(stf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ | ||
1276 | SET_RETVAL(EXCP_INVAL); \ | 1323 | SET_RETVAL(EXCP_INVAL); \ |
1277 | gen_op_load_gpr_T0(rA(ctx->opcode)); \ | 1324 | gen_op_load_gpr_T0(rA(ctx->opcode)); \ |
1278 | gen_op_load_gpr_T1(rB(ctx->opcode)); \ | 1325 | gen_op_load_gpr_T1(rB(ctx->opcode)); \ |
1279 | - gen_op_stf##width##x(rS(ctx->opcode)); \ | 1326 | + gen_op_load_FT0_fpr(rS(ctx->opcode));\ |
1327 | + gen_op_stf##width##x_FT0(); \ | ||
1280 | gen_op_store_T0_gpr(rA(ctx->opcode)); \ | 1328 | gen_op_store_T0_gpr(rA(ctx->opcode)); \ |
1281 | SET_RETVAL(0); \ | 1329 | SET_RETVAL(0); \ |
1282 | } | 1330 | } |
@@ -1284,13 +1332,14 @@ GEN_HANDLER(stf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ | @@ -1284,13 +1332,14 @@ GEN_HANDLER(stf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ | ||
1284 | #define GEN_STFX(width, opc) \ | 1332 | #define GEN_STFX(width, opc) \ |
1285 | GEN_HANDLER(stf##width##x, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ | 1333 | GEN_HANDLER(stf##width##x, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ |
1286 | { \ | 1334 | { \ |
1335 | + gen_op_load_FT0_fpr(rS(ctx->opcode));\ | ||
1287 | if (rA(ctx->opcode) == 0) { \ | 1336 | if (rA(ctx->opcode) == 0) { \ |
1288 | gen_op_load_gpr_T0(rB(ctx->opcode)); \ | 1337 | gen_op_load_gpr_T0(rB(ctx->opcode)); \ |
1289 | - gen_op_stf##width##x_z(rS(ctx->opcode)); \ | 1338 | + gen_op_stf##width##x_z_FT0(); \ |
1290 | } else { \ | 1339 | } else { \ |
1291 | gen_op_load_gpr_T0(rA(ctx->opcode)); \ | 1340 | gen_op_load_gpr_T0(rA(ctx->opcode)); \ |
1292 | gen_op_load_gpr_T1(rB(ctx->opcode)); \ | 1341 | gen_op_load_gpr_T1(rB(ctx->opcode)); \ |
1293 | - gen_op_stf##width##x(rS(ctx->opcode)); \ | 1342 | + gen_op_stf##width##x_FT0(); \ |
1294 | } \ | 1343 | } \ |
1295 | SET_RETVAL(0); \ | 1344 | SET_RETVAL(0); \ |
1296 | } | 1345 | } |
@@ -1304,10 +1353,6 @@ GEN_STFX(width, opc | 0x00) | @@ -1304,10 +1353,6 @@ GEN_STFX(width, opc | 0x00) | ||
1304 | /* stfd stfdu stfdux stfdx */ | 1353 | /* stfd stfdu stfdux stfdx */ |
1305 | GEN_STOF(d, 0x16); | 1354 | GEN_STOF(d, 0x16); |
1306 | /* stfs stfsu stfsux stfsx */ | 1355 | /* stfs stfsu stfsux stfsx */ |
1307 | -#define gen_op_stfs_z(a, b) | ||
1308 | -#define gen_op_stfs(a, b) | ||
1309 | -#define gen_op_stfsx_z(a) | ||
1310 | -#define gen_op_stfsx(a) | ||
1311 | GEN_STOF(s, 0x14); | 1356 | GEN_STOF(s, 0x14); |
1312 | 1357 | ||
1313 | /* Optional: */ | 1358 | /* Optional: */ |