Commit 4c9649a967e45bc3086d2e752871878e08d6cdf2
1 parent
6fa4cea9
Alpha architecture emulation core.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2597 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
9 changed files
with
3752 additions
and
0 deletions
Too many changes to show.
To preserve performance only 9 of 10 files are displayed.
target-alpha/cpu.h
0 → 100644
1 | +/* | ||
2 | + * Alpha emulation cpu definitions for qemu. | ||
3 | + * | ||
4 | + * Copyright (c) 2007 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 | +#if !defined (__CPU_ALPHA_H__) | ||
22 | +#define __CPU_ALPHA_H__ | ||
23 | + | ||
24 | +#include "config.h" | ||
25 | + | ||
26 | +#define TARGET_LONG_BITS 64 | ||
27 | + | ||
28 | +#include "cpu-defs.h" | ||
29 | + | ||
30 | + | ||
31 | +#include <setjmp.h> | ||
32 | + | ||
33 | +#include "softfloat.h" | ||
34 | + | ||
35 | +/* XXX: put this in a common place */ | ||
36 | +#define likely(x) __builtin_expect(!!(x), 1) | ||
37 | +#define unlikely(x) __builtin_expect(!!(x), 0) | ||
38 | + | ||
39 | +#define TARGET_HAS_ICE 1 | ||
40 | + | ||
41 | +#define ELF_MACHINE EM_ALPHA | ||
42 | + | ||
43 | +#define ICACHE_LINE_SIZE 32 | ||
44 | +#define DCACHE_LINE_SIZE 32 | ||
45 | + | ||
46 | +#define TARGET_PAGE_BITS 12 | ||
47 | + | ||
48 | +#define VA_BITS 43 | ||
49 | + | ||
50 | +/* Alpha major type */ | ||
51 | +enum { | ||
52 | + ALPHA_EV3 = 1, | ||
53 | + ALPHA_EV4 = 2, | ||
54 | + ALPHA_SIM = 3, | ||
55 | + ALPHA_LCA = 4, | ||
56 | + ALPHA_EV5 = 5, /* 21164 */ | ||
57 | + ALPHA_EV45 = 6, /* 21064A */ | ||
58 | + ALPHA_EV56 = 7, /* 21164A */ | ||
59 | +}; | ||
60 | + | ||
61 | +/* EV4 minor type */ | ||
62 | +enum { | ||
63 | + ALPHA_EV4_2 = 0, | ||
64 | + ALPHA_EV4_3 = 1, | ||
65 | +}; | ||
66 | + | ||
67 | +/* LCA minor type */ | ||
68 | +enum { | ||
69 | + ALPHA_LCA_1 = 1, /* 21066 */ | ||
70 | + ALPHA_LCA_2 = 2, /* 20166 */ | ||
71 | + ALPHA_LCA_3 = 3, /* 21068 */ | ||
72 | + ALPHA_LCA_4 = 4, /* 21068 */ | ||
73 | + ALPHA_LCA_5 = 5, /* 21066A */ | ||
74 | + ALPHA_LCA_6 = 6, /* 21068A */ | ||
75 | +}; | ||
76 | + | ||
77 | +/* EV5 minor type */ | ||
78 | +enum { | ||
79 | + ALPHA_EV5_1 = 1, /* Rev BA, CA */ | ||
80 | + ALPHA_EV5_2 = 2, /* Rev DA, EA */ | ||
81 | + ALPHA_EV5_3 = 3, /* Pass 3 */ | ||
82 | + ALPHA_EV5_4 = 4, /* Pass 3.2 */ | ||
83 | + ALPHA_EV5_5 = 5, /* Pass 4 */ | ||
84 | +}; | ||
85 | + | ||
86 | +/* EV45 minor type */ | ||
87 | +enum { | ||
88 | + ALPHA_EV45_1 = 1, /* Pass 1 */ | ||
89 | + ALPHA_EV45_2 = 2, /* Pass 1.1 */ | ||
90 | + ALPHA_EV45_3 = 3, /* Pass 2 */ | ||
91 | +}; | ||
92 | + | ||
93 | +/* EV56 minor type */ | ||
94 | +enum { | ||
95 | + ALPHA_EV56_1 = 1, /* Pass 1 */ | ||
96 | + ALPHA_EV56_2 = 2, /* Pass 2 */ | ||
97 | +}; | ||
98 | + | ||
99 | +enum { | ||
100 | + IMPLVER_2106x = 0, /* EV4, EV45 & LCA45 */ | ||
101 | + IMPLVER_21164 = 1, /* EV5, EV56 & PCA45 */ | ||
102 | + IMPLVER_21264 = 2, /* EV6, EV67 & EV68x */ | ||
103 | + IMPLVER_21364 = 3, /* EV7 & EV79 */ | ||
104 | +}; | ||
105 | + | ||
106 | +enum { | ||
107 | + AMASK_BWX = 0x00000001, | ||
108 | + AMASK_FIX = 0x00000002, | ||
109 | + AMASK_CIX = 0x00000004, | ||
110 | + AMASK_MVI = 0x00000100, | ||
111 | + AMASK_TRAP = 0x00000200, | ||
112 | + AMASK_PREFETCH = 0x00001000, | ||
113 | +}; | ||
114 | + | ||
115 | +enum { | ||
116 | + VAX_ROUND_NORMAL = 0, | ||
117 | + VAX_ROUND_CHOPPED, | ||
118 | +}; | ||
119 | + | ||
120 | +enum { | ||
121 | + IEEE_ROUND_NORMAL = 0, | ||
122 | + IEEE_ROUND_DYNAMIC, | ||
123 | + IEEE_ROUND_PLUS, | ||
124 | + IEEE_ROUND_MINUS, | ||
125 | + IEEE_ROUND_CHOPPED, | ||
126 | +}; | ||
127 | + | ||
128 | +/* IEEE floating-point operations encoding */ | ||
129 | +/* Trap mode */ | ||
130 | +enum { | ||
131 | + FP_TRAP_I = 0x0, | ||
132 | + FP_TRAP_U = 0x1, | ||
133 | + FP_TRAP_S = 0x4, | ||
134 | + FP_TRAP_SU = 0x5, | ||
135 | + FP_TRAP_SUI = 0x7, | ||
136 | +}; | ||
137 | + | ||
138 | +/* Rounding mode */ | ||
139 | +enum { | ||
140 | + FP_ROUND_CHOPPED = 0x0, | ||
141 | + FP_ROUND_MINUS = 0x1, | ||
142 | + FP_ROUND_NORMAL = 0x2, | ||
143 | + FP_ROUND_DYNAMIC = 0x3, | ||
144 | +}; | ||
145 | + | ||
146 | +/* Internal processor registers */ | ||
147 | +/* XXX: TOFIX: most of those registers are implementation dependant */ | ||
148 | +enum { | ||
149 | + /* Ebox IPRs */ | ||
150 | + IPR_CC = 0xC0, | ||
151 | + IPR_CC_CTL = 0xC1, | ||
152 | + IPR_VA = 0xC2, | ||
153 | + IPR_VA_CTL = 0xC4, | ||
154 | + IPR_VA_FORM = 0xC3, | ||
155 | + /* Ibox IPRs */ | ||
156 | + IPR_ITB_TAG = 0x00, | ||
157 | + IPR_ITB_PTE = 0x01, | ||
158 | + IPT_ITB_IAP = 0x02, | ||
159 | + IPT_ITB_IA = 0x03, | ||
160 | + IPT_ITB_IS = 0x04, | ||
161 | + IPR_PMPC = 0x05, | ||
162 | + IPR_EXC_ADDR = 0x06, | ||
163 | + IPR_IVA_FORM = 0x07, | ||
164 | + IPR_CM = 0x09, | ||
165 | + IPR_IER = 0x0A, | ||
166 | + IPR_SIRR = 0x0C, | ||
167 | + IPR_ISUM = 0x0D, | ||
168 | + IPR_HW_INT_CLR = 0x0E, | ||
169 | + IPR_EXC_SUM = 0x0F, | ||
170 | + IPR_PAL_BASE = 0x10, | ||
171 | + IPR_I_CTL = 0x11, | ||
172 | + IPR_I_STAT = 0x16, | ||
173 | + IPR_IC_FLUSH = 0x13, | ||
174 | + IPR_IC_FLUSH_ASM = 0x12, | ||
175 | + IPR_CLR_MAP = 0x15, | ||
176 | + IPR_SLEEP = 0x17, | ||
177 | + IPR_PCTX = 0x40, | ||
178 | + IPR_PCTR_CTL = 0x14, | ||
179 | + /* Mbox IPRs */ | ||
180 | + IPR_DTB_TAG0 = 0x20, | ||
181 | + IPR_DTB_TAG1 = 0xA0, | ||
182 | + IPR_DTB_PTE0 = 0x21, | ||
183 | + IPR_DTB_PTE1 = 0xA1, | ||
184 | + IPR_DTB_ALTMODE = 0xA6, | ||
185 | + IPR_DTB_IAP = 0xA2, | ||
186 | + IPR_DTB_IA = 0xA3, | ||
187 | + IPR_DTB_IS0 = 0x24, | ||
188 | + IPR_DTB_IS1 = 0xA4, | ||
189 | + IPR_DTB_ASN0 = 0x25, | ||
190 | + IPR_DTB_ASN1 = 0xA5, | ||
191 | + IPR_MM_STAT = 0x27, | ||
192 | + IPR_M_CTL = 0x28, | ||
193 | + IPR_DC_CTL = 0x29, | ||
194 | + IPR_DC_STAT = 0x2A, | ||
195 | + /* Cbox IPRs */ | ||
196 | + IPR_C_DATA = 0x2B, | ||
197 | + IPR_C_SHIFT = 0x2C, | ||
198 | + | ||
199 | + IPR_ASN, | ||
200 | + IPR_ASTEN, | ||
201 | + IPR_ASTSR, | ||
202 | + IPR_DATFX, | ||
203 | + IPR_ESP, | ||
204 | + IPR_FEN, | ||
205 | + IPR_IPIR, | ||
206 | + IPR_IPL, | ||
207 | + IPR_KSP, | ||
208 | + IPR_MCES, | ||
209 | + IPR_PERFMON, | ||
210 | + IPR_PCBB, | ||
211 | + IPR_PRBR, | ||
212 | + IPR_PTBR, | ||
213 | + IPR_SCBB, | ||
214 | + IPR_SISR, | ||
215 | + IPR_SSP, | ||
216 | + IPR_SYSPTBR, | ||
217 | + IPR_TBCHK, | ||
218 | + IPR_TBIA, | ||
219 | + IPR_TBIAP, | ||
220 | + IPR_TBIS, | ||
221 | + IPR_TBISD, | ||
222 | + IPR_TBISI, | ||
223 | + IPR_USP, | ||
224 | + IPR_VIRBND, | ||
225 | + IPR_VPTB, | ||
226 | + IPR_WHAMI, | ||
227 | + IPR_ALT_MODE, | ||
228 | + IPR_LAST, | ||
229 | +}; | ||
230 | + | ||
231 | +typedef struct CPUAlphaState CPUAlphaState; | ||
232 | + | ||
233 | +typedef struct pal_handler_t pal_handler_t; | ||
234 | +struct pal_handler_t { | ||
235 | + /* Reset */ | ||
236 | + void (*reset)(CPUAlphaState *env); | ||
237 | + /* Uncorrectable hardware error */ | ||
238 | + void (*machine_check)(CPUAlphaState *env); | ||
239 | + /* Arithmetic exception */ | ||
240 | + void (*arithmetic)(CPUAlphaState *env); | ||
241 | + /* Interrupt / correctable hardware error */ | ||
242 | + void (*interrupt)(CPUAlphaState *env); | ||
243 | + /* Data fault */ | ||
244 | + void (*dfault)(CPUAlphaState *env); | ||
245 | + /* DTB miss pal */ | ||
246 | + void (*dtb_miss_pal)(CPUAlphaState *env); | ||
247 | + /* DTB miss native */ | ||
248 | + void (*dtb_miss_native)(CPUAlphaState *env); | ||
249 | + /* Unaligned access */ | ||
250 | + void (*unalign)(CPUAlphaState *env); | ||
251 | + /* ITB miss */ | ||
252 | + void (*itb_miss)(CPUAlphaState *env); | ||
253 | + /* Instruction stream access violation */ | ||
254 | + void (*itb_acv)(CPUAlphaState *env); | ||
255 | + /* Reserved or privileged opcode */ | ||
256 | + void (*opcdec)(CPUAlphaState *env); | ||
257 | + /* Floating point exception */ | ||
258 | + void (*fen)(CPUAlphaState *env); | ||
259 | + /* Call pal instruction */ | ||
260 | + void (*call_pal)(CPUAlphaState *env, uint32_t palcode); | ||
261 | +}; | ||
262 | + | ||
263 | +struct CPUAlphaState { | ||
264 | + uint64_t ir[31]; | ||
265 | + float64 fir[31]; | ||
266 | + float_status fp_status; | ||
267 | + uint64_t fpcr; | ||
268 | + uint64_t pc; | ||
269 | + uint64_t lock; | ||
270 | + uint32_t pcc[2]; | ||
271 | + uint64_t ipr[IPR_LAST]; | ||
272 | + uint64_t ps; | ||
273 | + uint64_t unique; | ||
274 | + int saved_mode; /* Used for HW_LD / HW_ST */ | ||
275 | + | ||
276 | + /* */ | ||
277 | + double ft0, ft1, ft2; | ||
278 | + | ||
279 | + /* Those resources are used only in Qemu core */ | ||
280 | + CPU_COMMON | ||
281 | + | ||
282 | + jmp_buf jmp_env; | ||
283 | + int user_mode_only; /* user mode only simulation */ | ||
284 | + uint32_t hflags; | ||
285 | + int halted; | ||
286 | + | ||
287 | + int exception_index; | ||
288 | + int error_code; | ||
289 | + int interrupt_request; | ||
290 | + | ||
291 | + uint32_t features; | ||
292 | + uint32_t amask; | ||
293 | + int implver; | ||
294 | + pal_handler_t *pal_handler; | ||
295 | +}; | ||
296 | + | ||
297 | +#include "cpu-all.h" | ||
298 | + | ||
299 | +enum { | ||
300 | + FEATURE_ASN = 0x00000001, | ||
301 | + FEATURE_SPS = 0x00000002, | ||
302 | + FEATURE_VIRBND = 0x00000004, | ||
303 | + FEATURE_TBCHK = 0x00000008, | ||
304 | +}; | ||
305 | + | ||
306 | +enum { | ||
307 | + EXCP_RESET = 0x0000, | ||
308 | + EXCP_MCHK = 0x0020, | ||
309 | + EXCP_ARITH = 0x0060, | ||
310 | + EXCP_HW_INTERRUPT = 0x00E0, | ||
311 | + EXCP_DFAULT = 0x01E0, | ||
312 | + EXCP_DTB_MISS_PAL = 0x09E0, | ||
313 | + EXCP_ITB_MISS = 0x03E0, | ||
314 | + EXCP_ITB_ACV = 0x07E0, | ||
315 | + EXCP_DTB_MISS_NATIVE = 0x08E0, | ||
316 | + EXCP_UNALIGN = 0x11E0, | ||
317 | + EXCP_OPCDEC = 0x13E0, | ||
318 | + EXCP_FEN = 0x17E0, | ||
319 | + EXCP_CALL_PAL = 0x2000, | ||
320 | + EXCP_CALL_PALP = 0x3000, | ||
321 | + EXCP_CALL_PALE = 0x4000, | ||
322 | + /* Pseudo exception for console */ | ||
323 | + EXCP_CONSOLE_DISPATCH = 0x4001, | ||
324 | + EXCP_CONSOLE_FIXUP = 0x4002, | ||
325 | +}; | ||
326 | + | ||
327 | +/* Arithmetic exception */ | ||
328 | +enum { | ||
329 | + EXCP_ARITH_OVERFLOW, | ||
330 | +}; | ||
331 | + | ||
332 | +enum { | ||
333 | + PALCODE_CALL = 0x00000000, | ||
334 | + PALCODE_LD = 0x01000000, | ||
335 | + PALCODE_ST = 0x02000000, | ||
336 | + PALCODE_MFPR = 0x03000000, | ||
337 | + PALCODE_MTPR = 0x04000000, | ||
338 | + PALCODE_REI = 0x05000000, | ||
339 | + PALCODE_INIT = 0xF0000000, | ||
340 | +}; | ||
341 | + | ||
342 | +enum { | ||
343 | + IR_V0 = 0, | ||
344 | + IR_T0 = 1, | ||
345 | + IR_T1 = 2, | ||
346 | + IR_T2 = 3, | ||
347 | + IR_T3 = 4, | ||
348 | + IR_T4 = 5, | ||
349 | + IR_T5 = 6, | ||
350 | + IR_T6 = 7, | ||
351 | + IR_T7 = 8, | ||
352 | + IR_S0 = 9, | ||
353 | + IR_S1 = 10, | ||
354 | + IR_S2 = 11, | ||
355 | + IR_S3 = 12, | ||
356 | + IR_S4 = 13, | ||
357 | + IR_S5 = 14, | ||
358 | + IR_S6 = 15, | ||
359 | +#define IR_FP IR_S6 | ||
360 | + IR_A0 = 16, | ||
361 | + IR_A1 = 17, | ||
362 | + IR_A2 = 18, | ||
363 | + IR_A3 = 19, | ||
364 | + IR_A4 = 20, | ||
365 | + IR_A5 = 21, | ||
366 | + IR_T8 = 22, | ||
367 | + IR_T9 = 23, | ||
368 | + IR_T10 = 24, | ||
369 | + IR_T11 = 25, | ||
370 | + IR_RA = 26, | ||
371 | + IR_T12 = 27, | ||
372 | +#define IR_PV IR_T12 | ||
373 | + IR_AT = 28, | ||
374 | + IR_GP = 29, | ||
375 | + IR_SP = 30, | ||
376 | + IR_ZERO = 31, | ||
377 | +}; | ||
378 | + | ||
379 | +int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp); | ||
380 | +int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp); | ||
381 | +void cpu_loop_exit (void); | ||
382 | +void pal_init (CPUState *env); | ||
383 | +void call_pal (CPUState *env, int palcode); | ||
384 | + | ||
385 | +#endif /* !defined (__CPU_ALPHA_H__) */ |
target-alpha/exec.h
0 → 100644
1 | +/* | ||
2 | + * Alpha emulation cpu run-time definitions for qemu. | ||
3 | + * | ||
4 | + * Copyright (c) 2007 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 | +#if !defined (__ALPHA_EXEC_H__) | ||
22 | +#define __ALPHA_EXEC_H__ | ||
23 | + | ||
24 | +#include "config.h" | ||
25 | + | ||
26 | +#include "dyngen-exec.h" | ||
27 | + | ||
28 | +#define TARGET_LONG_BITS 64 | ||
29 | + | ||
30 | +register struct CPUAlphaState *env asm(AREG0); | ||
31 | + | ||
32 | +#if TARGET_LONG_BITS > HOST_LONG_BITS | ||
33 | + | ||
34 | +/* no registers can be used */ | ||
35 | +#define T0 (env->t0) | ||
36 | +#define T1 (env->t1) | ||
37 | +#define T2 (env->t2) | ||
38 | + | ||
39 | +#else | ||
40 | + | ||
41 | +register uint64_t T0 asm(AREG1); | ||
42 | +register uint64_t T1 asm(AREG2); | ||
43 | +register uint64_t T2 asm(AREG3); | ||
44 | + | ||
45 | +#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ | ||
46 | + | ||
47 | +#define PARAM(n) ((uint64_t)PARAM##n) | ||
48 | +#define SPARAM(n) ((int32_t)PARAM##n) | ||
49 | +#define FT0 (env->ft0) | ||
50 | +#define FT1 (env->ft1) | ||
51 | +#define FT2 (env->ft2) | ||
52 | +#define FP_STATUS (env->fp_status) | ||
53 | + | ||
54 | +#if defined (DEBUG_OP) | ||
55 | +#define RETURN() __asm__ __volatile__("nop" : : : "memory"); | ||
56 | +#else | ||
57 | +#define RETURN() __asm__ __volatile__("" : : : "memory"); | ||
58 | +#endif | ||
59 | + | ||
60 | +#include "cpu.h" | ||
61 | +#include "exec-all.h" | ||
62 | + | ||
63 | +#if !defined(CONFIG_USER_ONLY) | ||
64 | +#include "softmmu_exec.h" | ||
65 | +#endif /* !defined(CONFIG_USER_ONLY) */ | ||
66 | + | ||
67 | +static inline void env_to_regs(void) | ||
68 | +{ | ||
69 | +} | ||
70 | + | ||
71 | +static inline void regs_to_env(void) | ||
72 | +{ | ||
73 | +} | ||
74 | + | ||
75 | +int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw, | ||
76 | + int is_user, int is_softmmu); | ||
77 | +int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp); | ||
78 | +int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp); | ||
79 | + | ||
80 | +void do_interrupt (CPUState *env); | ||
81 | + | ||
82 | +#endif /* !defined (__ALPHA_EXEC_H__) */ |
target-alpha/helper.c
0 → 100644
1 | +/* | ||
2 | + * Alpha emulation cpu helpers for qemu. | ||
3 | + * | ||
4 | + * Copyright (c) 2007 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 | +#include <stdint.h> | ||
22 | +#include <stdlib.h> | ||
23 | +#include <stdio.h> | ||
24 | + | ||
25 | +#include "cpu.h" | ||
26 | +#include "exec-all.h" | ||
27 | + | ||
28 | +#if defined(CONFIG_USER_ONLY) | ||
29 | + | ||
30 | +int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | ||
31 | + int is_user, int is_softmmu) | ||
32 | +{ | ||
33 | + if (rw == 2) | ||
34 | + env->exception_index = EXCP_ITB_MISS; | ||
35 | + else | ||
36 | + env->exception_index = EXCP_DFAULT; | ||
37 | + env->ipr[IPR_EXC_ADDR] = address; | ||
38 | + | ||
39 | + return 1; | ||
40 | +} | ||
41 | + | ||
42 | +target_ulong cpu_get_phys_page_debug (CPUState *env, target_ulong addr) | ||
43 | +{ | ||
44 | + return addr; | ||
45 | +} | ||
46 | + | ||
47 | +void do_interrupt (CPUState *env) | ||
48 | +{ | ||
49 | + env->exception_index = -1; | ||
50 | +} | ||
51 | + | ||
52 | +#else | ||
53 | + | ||
54 | +target_ulong cpu_get_phys_page_debug (CPUState *env, target_ulong addr) | ||
55 | +{ | ||
56 | + return -1; | ||
57 | +} | ||
58 | + | ||
59 | +int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | ||
60 | + int is_user, int is_softmmu) | ||
61 | +{ | ||
62 | + uint32_t opc; | ||
63 | + | ||
64 | + if (rw == 2) { | ||
65 | + /* Instruction translation buffer miss */ | ||
66 | + env->exception_index = EXCP_ITB_MISS; | ||
67 | + } else { | ||
68 | + if (env->ipr[IPR_EXC_ADDR] & 1) | ||
69 | + env->exception_index = EXCP_DTB_MISS_PAL; | ||
70 | + else | ||
71 | + env->exception_index = EXCP_DTB_MISS_NATIVE; | ||
72 | + opc = (ldl_code(env->pc) >> 21) << 4; | ||
73 | + if (rw) { | ||
74 | + opc |= 0x9; | ||
75 | + } else { | ||
76 | + opc |= 0x4; | ||
77 | + } | ||
78 | + env->ipr[IPR_MM_STAT] = opc; | ||
79 | + } | ||
80 | + | ||
81 | + return 1; | ||
82 | +} | ||
83 | + | ||
84 | +int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp) | ||
85 | +{ | ||
86 | + uint64_t hwpcb; | ||
87 | + int ret = 0; | ||
88 | + | ||
89 | + hwpcb = env->ipr[IPR_PCBB]; | ||
90 | + switch (iprn) { | ||
91 | + case IPR_ASN: | ||
92 | + if (env->features & FEATURE_ASN) | ||
93 | + *valp = env->ipr[IPR_ASN]; | ||
94 | + else | ||
95 | + *valp = 0; | ||
96 | + break; | ||
97 | + case IPR_ASTEN: | ||
98 | + *valp = ((int64_t)(env->ipr[IPR_ASTEN] << 60)) >> 60; | ||
99 | + break; | ||
100 | + case IPR_ASTSR: | ||
101 | + *valp = ((int64_t)(env->ipr[IPR_ASTSR] << 60)) >> 60; | ||
102 | + break; | ||
103 | + case IPR_DATFX: | ||
104 | + /* Write only */ | ||
105 | + ret = -1; | ||
106 | + break; | ||
107 | + case IPR_ESP: | ||
108 | + if (env->features & FEATURE_SPS) | ||
109 | + *valp = env->ipr[IPR_ESP]; | ||
110 | + else | ||
111 | + *valp = ldq_raw(hwpcb + 8); | ||
112 | + break; | ||
113 | + case IPR_FEN: | ||
114 | + *valp = ((int64_t)(env->ipr[IPR_FEN] << 63)) >> 63; | ||
115 | + break; | ||
116 | + case IPR_IPIR: | ||
117 | + /* Write-only */ | ||
118 | + ret = -1; | ||
119 | + break; | ||
120 | + case IPR_IPL: | ||
121 | + *valp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59; | ||
122 | + break; | ||
123 | + case IPR_KSP: | ||
124 | + if (!(env->ipr[IPR_EXC_ADDR] & 1)) { | ||
125 | + ret = -1; | ||
126 | + } else { | ||
127 | + if (env->features & FEATURE_SPS) | ||
128 | + *valp = env->ipr[IPR_KSP]; | ||
129 | + else | ||
130 | + *valp = ldq_raw(hwpcb + 0); | ||
131 | + } | ||
132 | + break; | ||
133 | + case IPR_MCES: | ||
134 | + *valp = ((int64_t)(env->ipr[IPR_MCES] << 59)) >> 59; | ||
135 | + break; | ||
136 | + case IPR_PERFMON: | ||
137 | + /* Implementation specific */ | ||
138 | + *valp = 0; | ||
139 | + break; | ||
140 | + case IPR_PCBB: | ||
141 | + *valp = ((int64_t)env->ipr[IPR_PCBB] << 16) >> 16; | ||
142 | + break; | ||
143 | + case IPR_PRBR: | ||
144 | + *valp = env->ipr[IPR_PRBR]; | ||
145 | + break; | ||
146 | + case IPR_PTBR: | ||
147 | + *valp = env->ipr[IPR_PTBR]; | ||
148 | + break; | ||
149 | + case IPR_SCBB: | ||
150 | + *valp = (int64_t)((int32_t)env->ipr[IPR_SCBB]); | ||
151 | + break; | ||
152 | + case IPR_SIRR: | ||
153 | + /* Write-only */ | ||
154 | + ret = -1; | ||
155 | + break; | ||
156 | + case IPR_SISR: | ||
157 | + *valp = (int64_t)((int16_t)env->ipr[IPR_SISR]); | ||
158 | + case IPR_SSP: | ||
159 | + if (env->features & FEATURE_SPS) | ||
160 | + *valp = env->ipr[IPR_SSP]; | ||
161 | + else | ||
162 | + *valp = ldq_raw(hwpcb + 16); | ||
163 | + break; | ||
164 | + case IPR_SYSPTBR: | ||
165 | + if (env->features & FEATURE_VIRBND) | ||
166 | + *valp = env->ipr[IPR_SYSPTBR]; | ||
167 | + else | ||
168 | + ret = -1; | ||
169 | + break; | ||
170 | + case IPR_TBCHK: | ||
171 | + if ((env->features & FEATURE_TBCHK)) { | ||
172 | + /* XXX: TODO */ | ||
173 | + *valp = 0; | ||
174 | + ret = -1; | ||
175 | + } else { | ||
176 | + ret = -1; | ||
177 | + } | ||
178 | + break; | ||
179 | + case IPR_TBIA: | ||
180 | + /* Write-only */ | ||
181 | + ret = -1; | ||
182 | + break; | ||
183 | + case IPR_TBIAP: | ||
184 | + /* Write-only */ | ||
185 | + ret = -1; | ||
186 | + break; | ||
187 | + case IPR_TBIS: | ||
188 | + /* Write-only */ | ||
189 | + ret = -1; | ||
190 | + break; | ||
191 | + case IPR_TBISD: | ||
192 | + /* Write-only */ | ||
193 | + ret = -1; | ||
194 | + break; | ||
195 | + case IPR_TBISI: | ||
196 | + /* Write-only */ | ||
197 | + ret = -1; | ||
198 | + break; | ||
199 | + case IPR_USP: | ||
200 | + if (env->features & FEATURE_SPS) | ||
201 | + *valp = env->ipr[IPR_USP]; | ||
202 | + else | ||
203 | + *valp = ldq_raw(hwpcb + 24); | ||
204 | + break; | ||
205 | + case IPR_VIRBND: | ||
206 | + if (env->features & FEATURE_VIRBND) | ||
207 | + *valp = env->ipr[IPR_VIRBND]; | ||
208 | + else | ||
209 | + ret = -1; | ||
210 | + break; | ||
211 | + case IPR_VPTB: | ||
212 | + *valp = env->ipr[IPR_VPTB]; | ||
213 | + break; | ||
214 | + case IPR_WHAMI: | ||
215 | + *valp = env->ipr[IPR_WHAMI]; | ||
216 | + break; | ||
217 | + default: | ||
218 | + /* Invalid */ | ||
219 | + ret = -1; | ||
220 | + break; | ||
221 | + } | ||
222 | + | ||
223 | + return ret; | ||
224 | +} | ||
225 | + | ||
226 | +int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp) | ||
227 | +{ | ||
228 | + uint64_t hwpcb, tmp64; | ||
229 | + uint8_t tmp8; | ||
230 | + int ret = 0; | ||
231 | + | ||
232 | + hwpcb = env->ipr[IPR_PCBB]; | ||
233 | + switch (iprn) { | ||
234 | + case IPR_ASN: | ||
235 | + /* Read-only */ | ||
236 | + ret = -1; | ||
237 | + break; | ||
238 | + case IPR_ASTEN: | ||
239 | + tmp8 = ((int8_t)(env->ipr[IPR_ASTEN] << 4)) >> 4; | ||
240 | + *oldvalp = tmp8; | ||
241 | + tmp8 &= val & 0xF; | ||
242 | + tmp8 |= (val >> 4) & 0xF; | ||
243 | + env->ipr[IPR_ASTEN] &= ~0xF; | ||
244 | + env->ipr[IPR_ASTEN] |= tmp8; | ||
245 | + ret = 1; | ||
246 | + break; | ||
247 | + case IPR_ASTSR: | ||
248 | + tmp8 = ((int8_t)(env->ipr[IPR_ASTSR] << 4)) >> 4; | ||
249 | + *oldvalp = tmp8; | ||
250 | + tmp8 &= val & 0xF; | ||
251 | + tmp8 |= (val >> 4) & 0xF; | ||
252 | + env->ipr[IPR_ASTSR] &= ~0xF; | ||
253 | + env->ipr[IPR_ASTSR] |= tmp8; | ||
254 | + ret = 1; | ||
255 | + case IPR_DATFX: | ||
256 | + env->ipr[IPR_DATFX] &= ~0x1; | ||
257 | + env->ipr[IPR_DATFX] |= val & 1; | ||
258 | + tmp64 = ldq_raw(hwpcb + 56); | ||
259 | + tmp64 &= ~0x8000000000000000ULL; | ||
260 | + tmp64 |= (val & 1) << 63; | ||
261 | + stq_raw(hwpcb + 56, tmp64); | ||
262 | + break; | ||
263 | + case IPR_ESP: | ||
264 | + if (env->features & FEATURE_SPS) | ||
265 | + env->ipr[IPR_ESP] = val; | ||
266 | + else | ||
267 | + stq_raw(hwpcb + 8, val); | ||
268 | + break; | ||
269 | + case IPR_FEN: | ||
270 | + env->ipr[IPR_FEN] = val & 1; | ||
271 | + tmp64 = ldq_raw(hwpcb + 56); | ||
272 | + tmp64 &= ~1; | ||
273 | + tmp64 |= val & 1; | ||
274 | + stq_raw(hwpcb + 56, tmp64); | ||
275 | + break; | ||
276 | + case IPR_IPIR: | ||
277 | + /* XXX: TODO: Send IRQ to CPU #ir[16] */ | ||
278 | + break; | ||
279 | + case IPR_IPL: | ||
280 | + *oldvalp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59; | ||
281 | + env->ipr[IPR_IPL] &= ~0x1F; | ||
282 | + env->ipr[IPR_IPL] |= val & 0x1F; | ||
283 | + /* XXX: may issue an interrupt or ASR _now_ */ | ||
284 | + ret = 1; | ||
285 | + break; | ||
286 | + case IPR_KSP: | ||
287 | + if (!(env->ipr[IPR_EXC_ADDR] & 1)) { | ||
288 | + ret = -1; | ||
289 | + } else { | ||
290 | + if (env->features & FEATURE_SPS) | ||
291 | + env->ipr[IPR_KSP] = val; | ||
292 | + else | ||
293 | + stq_raw(hwpcb + 0, val); | ||
294 | + } | ||
295 | + break; | ||
296 | + case IPR_MCES: | ||
297 | + env->ipr[IPR_MCES] &= ~((val & 0x7) | 0x18); | ||
298 | + env->ipr[IPR_MCES] |= val & 0x18; | ||
299 | + break; | ||
300 | + case IPR_PERFMON: | ||
301 | + /* Implementation specific */ | ||
302 | + *oldvalp = 0; | ||
303 | + ret = 1; | ||
304 | + break; | ||
305 | + case IPR_PCBB: | ||
306 | + /* Read-only */ | ||
307 | + ret = -1; | ||
308 | + break; | ||
309 | + case IPR_PRBR: | ||
310 | + env->ipr[IPR_PRBR] = val; | ||
311 | + break; | ||
312 | + case IPR_PTBR: | ||
313 | + /* Read-only */ | ||
314 | + ret = -1; | ||
315 | + break; | ||
316 | + case IPR_SCBB: | ||
317 | + env->ipr[IPR_SCBB] = (uint32_t)val; | ||
318 | + break; | ||
319 | + case IPR_SIRR: | ||
320 | + if (val & 0xF) { | ||
321 | + env->ipr[IPR_SISR] |= 1 << (val & 0xF); | ||
322 | + /* XXX: request a software interrupt _now_ */ | ||
323 | + } | ||
324 | + break; | ||
325 | + case IPR_SISR: | ||
326 | + /* Read-only */ | ||
327 | + ret = -1; | ||
328 | + break; | ||
329 | + case IPR_SSP: | ||
330 | + if (env->features & FEATURE_SPS) | ||
331 | + env->ipr[IPR_SSP] = val; | ||
332 | + else | ||
333 | + stq_raw(hwpcb + 16, val); | ||
334 | + break; | ||
335 | + case IPR_SYSPTBR: | ||
336 | + if (env->features & FEATURE_VIRBND) | ||
337 | + env->ipr[IPR_SYSPTBR] = val; | ||
338 | + else | ||
339 | + ret = -1; | ||
340 | + case IPR_TBCHK: | ||
341 | + /* Read-only */ | ||
342 | + ret = -1; | ||
343 | + break; | ||
344 | + case IPR_TBIA: | ||
345 | + tlb_flush(env, 1); | ||
346 | + break; | ||
347 | + case IPR_TBIAP: | ||
348 | + tlb_flush(env, 1); | ||
349 | + break; | ||
350 | + case IPR_TBIS: | ||
351 | + tlb_flush_page(env, val); | ||
352 | + break; | ||
353 | + case IPR_TBISD: | ||
354 | + tlb_flush_page(env, val); | ||
355 | + break; | ||
356 | + case IPR_TBISI: | ||
357 | + tlb_flush_page(env, val); | ||
358 | + break; | ||
359 | + case IPR_USP: | ||
360 | + if (env->features & FEATURE_SPS) | ||
361 | + env->ipr[IPR_USP] = val; | ||
362 | + else | ||
363 | + stq_raw(hwpcb + 24, val); | ||
364 | + break; | ||
365 | + case IPR_VIRBND: | ||
366 | + if (env->features & FEATURE_VIRBND) | ||
367 | + env->ipr[IPR_VIRBND] = val; | ||
368 | + else | ||
369 | + ret = -1; | ||
370 | + break; | ||
371 | + case IPR_VPTB: | ||
372 | + env->ipr[IPR_VPTB] = val; | ||
373 | + break; | ||
374 | + case IPR_WHAMI: | ||
375 | + /* Read-only */ | ||
376 | + ret = -1; | ||
377 | + break; | ||
378 | + default: | ||
379 | + /* Invalid */ | ||
380 | + ret = -1; | ||
381 | + break; | ||
382 | + } | ||
383 | + | ||
384 | + return ret; | ||
385 | +} | ||
386 | + | ||
387 | +void do_interrupt (CPUState *env) | ||
388 | +{ | ||
389 | + int excp; | ||
390 | + | ||
391 | + env->ipr[IPR_EXC_ADDR] = env->pc | 1; | ||
392 | + excp = env->exception_index; | ||
393 | + env->exception_index = 0; | ||
394 | + env->error_code = 0; | ||
395 | + /* XXX: disable interrupts and memory mapping */ | ||
396 | + if (env->ipr[IPR_PAL_BASE] != -1ULL) { | ||
397 | + /* We use native PALcode */ | ||
398 | + env->pc = env->ipr[IPR_PAL_BASE] + excp; | ||
399 | + } else { | ||
400 | + /* We use emulated PALcode */ | ||
401 | + call_pal(env); | ||
402 | + /* Emulate REI */ | ||
403 | + env->pc = env->ipr[IPR_EXC_ADDR] & ~7; | ||
404 | + env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1; | ||
405 | + /* XXX: re-enable interrupts and memory mapping */ | ||
406 | + } | ||
407 | +} | ||
408 | +#endif | ||
409 | + | ||
410 | +void cpu_dump_state (CPUState *env, FILE *f, | ||
411 | + int (*cpu_fprintf)(FILE *f, const char *fmt, ...), | ||
412 | + int flags) | ||
413 | +{ | ||
414 | + static unsigned char *linux_reg_names[] = { | ||
415 | + "v0 ", "t0 ", "t1 ", "t2 ", "t3 ", "t4 ", "t5 ", "t6 ", | ||
416 | + "t7 ", "s0 ", "s1 ", "s2 ", "s3 ", "s4 ", "s5 ", "fp ", | ||
417 | + "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ", "t8 ", "t9 ", | ||
418 | + "t10", "t11", "ra ", "t12", "at ", "gp ", "sp ", "zero", | ||
419 | + }; | ||
420 | + int i; | ||
421 | + | ||
422 | + cpu_fprintf(f, " PC " TARGET_FMT_lx " PS " TARGET_FMT_lx "\n", | ||
423 | + env->pc, env->ps); | ||
424 | + for (i = 0; i < 31; i++) { | ||
425 | + cpu_fprintf(f, "IR%02d %s " TARGET_FMT_lx " ", i, | ||
426 | + linux_reg_names[i], env->ir[i]); | ||
427 | + if ((i % 3) == 2) | ||
428 | + cpu_fprintf(f, "\n"); | ||
429 | + } | ||
430 | + cpu_fprintf(f, "\n"); | ||
431 | + for (i = 0; i < 31; i++) { | ||
432 | + cpu_fprintf(f, "FIR%02d " TARGET_FMT_lx " ", i, | ||
433 | + *((uint64_t *)(&env->fir[i]))); | ||
434 | + if ((i % 3) == 2) | ||
435 | + cpu_fprintf(f, "\n"); | ||
436 | + } | ||
437 | + cpu_fprintf(f, "FT " TARGET_FMT_lx " " TARGET_FMT_lx " " TARGET_FMT_lx, | ||
438 | + *((uint64_t *)(&env->ft0)), *((uint64_t *)(&env->ft1)), | ||
439 | + *((uint64_t *)(&env->ft2))); | ||
440 | + cpu_fprintf(f, "\nMEM " TARGET_FMT_lx " %d %d\n", | ||
441 | + ldq_raw(0x000000004007df60ULL), | ||
442 | + (uint8_t *)(&env->ft0), (uint8_t *)(&env->fir[0])); | ||
443 | +} | ||
444 | + | ||
445 | +void cpu_dump_EA (target_ulong EA) | ||
446 | +{ | ||
447 | + FILE *f; | ||
448 | + | ||
449 | + if (logfile) | ||
450 | + f = logfile; | ||
451 | + else | ||
452 | + f = stdout; | ||
453 | + fprintf(f, "Memory access at address " TARGET_FMT_lx "\n", EA); | ||
454 | +} |
target-alpha/op.c
0 → 100644
1 | +/* | ||
2 | + * Alpha emulation cpu micro-operations for qemu. | ||
3 | + * | ||
4 | + * Copyright (c) 2007 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 | +#define DEBUG_OP | ||
22 | + | ||
23 | +#include "config.h" | ||
24 | +#include "exec.h" | ||
25 | + | ||
26 | +#include "op_helper.h" | ||
27 | + | ||
28 | +#define REG 0 | ||
29 | +#include "op_template.h" | ||
30 | + | ||
31 | +#define REG 1 | ||
32 | +#include "op_template.h" | ||
33 | + | ||
34 | +#define REG 2 | ||
35 | +#include "op_template.h" | ||
36 | + | ||
37 | +#define REG 3 | ||
38 | +#include "op_template.h" | ||
39 | + | ||
40 | +#define REG 4 | ||
41 | +#include "op_template.h" | ||
42 | + | ||
43 | +#define REG 5 | ||
44 | +#include "op_template.h" | ||
45 | + | ||
46 | +#define REG 6 | ||
47 | +#include "op_template.h" | ||
48 | + | ||
49 | +#define REG 7 | ||
50 | +#include "op_template.h" | ||
51 | + | ||
52 | +#define REG 8 | ||
53 | +#include "op_template.h" | ||
54 | + | ||
55 | +#define REG 9 | ||
56 | +#include "op_template.h" | ||
57 | + | ||
58 | +#define REG 10 | ||
59 | +#include "op_template.h" | ||
60 | + | ||
61 | +#define REG 11 | ||
62 | +#include "op_template.h" | ||
63 | + | ||
64 | +#define REG 12 | ||
65 | +#include "op_template.h" | ||
66 | + | ||
67 | +#define REG 13 | ||
68 | +#include "op_template.h" | ||
69 | + | ||
70 | +#define REG 14 | ||
71 | +#include "op_template.h" | ||
72 | + | ||
73 | +#define REG 15 | ||
74 | +#include "op_template.h" | ||
75 | + | ||
76 | +#define REG 16 | ||
77 | +#include "op_template.h" | ||
78 | + | ||
79 | +#define REG 17 | ||
80 | +#include "op_template.h" | ||
81 | + | ||
82 | +#define REG 18 | ||
83 | +#include "op_template.h" | ||
84 | + | ||
85 | +#define REG 19 | ||
86 | +#include "op_template.h" | ||
87 | + | ||
88 | +#define REG 20 | ||
89 | +#include "op_template.h" | ||
90 | + | ||
91 | +#define REG 21 | ||
92 | +#include "op_template.h" | ||
93 | + | ||
94 | +#define REG 22 | ||
95 | +#include "op_template.h" | ||
96 | + | ||
97 | +#define REG 23 | ||
98 | +#include "op_template.h" | ||
99 | + | ||
100 | +#define REG 24 | ||
101 | +#include "op_template.h" | ||
102 | + | ||
103 | +#define REG 25 | ||
104 | +#include "op_template.h" | ||
105 | + | ||
106 | +#define REG 26 | ||
107 | +#include "op_template.h" | ||
108 | + | ||
109 | +#define REG 27 | ||
110 | +#include "op_template.h" | ||
111 | + | ||
112 | +#define REG 28 | ||
113 | +#include "op_template.h" | ||
114 | + | ||
115 | +#define REG 29 | ||
116 | +#include "op_template.h" | ||
117 | + | ||
118 | +#define REG 30 | ||
119 | +#include "op_template.h" | ||
120 | + | ||
121 | +#define REG 31 | ||
122 | +#include "op_template.h" | ||
123 | + | ||
124 | +/* Debug stuff */ | ||
125 | +void OPPROTO op_no_op (void) | ||
126 | +{ | ||
127 | +#if !defined (DEBUG_OP) | ||
128 | + __asm__ __volatile__("nop" : : : "memory"); | ||
129 | +#endif | ||
130 | + RETURN(); | ||
131 | +} | ||
132 | + | ||
133 | +void OPPROTO op_tb_flush (void) | ||
134 | +{ | ||
135 | + helper_tb_flush(); | ||
136 | + RETURN(); | ||
137 | +} | ||
138 | + | ||
139 | +/* Load and stores */ | ||
140 | +#define MEMSUFFIX _raw | ||
141 | +#include "op_mem.h" | ||
142 | +#if !defined(CONFIG_USER_ONLY) | ||
143 | +#define MEMSUFFIX _user | ||
144 | +#include "op_mem.h" | ||
145 | +#define MEMSUFFIX _kernel | ||
146 | +#include "op_mem.h" | ||
147 | +/* Those are used for supervisor, executive and pal modes */ | ||
148 | +#define MEMSUFFIX _data | ||
149 | +#include "op_mem.h" | ||
150 | +#endif | ||
151 | + | ||
152 | +/* Special operation for load and store */ | ||
153 | +void OPPROTO op_n7 (void) | ||
154 | +{ | ||
155 | + T0 &= ~(uint64_t)0x7; | ||
156 | + RETURN(); | ||
157 | +} | ||
158 | + | ||
159 | +/* Misc */ | ||
160 | +void OPPROTO op_excp (void) | ||
161 | +{ | ||
162 | + helper_excp(PARAM(1), PARAM(2)); | ||
163 | + RETURN(); | ||
164 | +} | ||
165 | + | ||
166 | +void OPPROTO op_load_amask (void) | ||
167 | +{ | ||
168 | + helper_amask(); | ||
169 | + RETURN(); | ||
170 | +} | ||
171 | + | ||
172 | +void OPPROTO op_load_pcc (void) | ||
173 | +{ | ||
174 | + helper_load_pcc(); | ||
175 | + RETURN(); | ||
176 | +} | ||
177 | + | ||
178 | +void OPPROTO op_load_implver (void) | ||
179 | +{ | ||
180 | + helper_load_implver(); | ||
181 | + RETURN(); | ||
182 | +} | ||
183 | + | ||
184 | +void OPPROTO op_load_fpcr (void) | ||
185 | +{ | ||
186 | + helper_load_fpcr(); | ||
187 | + RETURN(); | ||
188 | +} | ||
189 | + | ||
190 | +void OPPROTO op_store_fpcr (void) | ||
191 | +{ | ||
192 | + helper_store_fpcr(); | ||
193 | + RETURN(); | ||
194 | +} | ||
195 | + | ||
196 | +void OPPROTO op_load_irf (void) | ||
197 | +{ | ||
198 | + helper_load_irf(); | ||
199 | + RETURN(); | ||
200 | +} | ||
201 | + | ||
202 | +void OPPROTO op_set_irf (void) | ||
203 | +{ | ||
204 | + helper_set_irf(); | ||
205 | + RETURN(); | ||
206 | +} | ||
207 | + | ||
208 | +void OPPROTO op_clear_irf (void) | ||
209 | +{ | ||
210 | + helper_clear_irf(); | ||
211 | + RETURN(); | ||
212 | +} | ||
213 | + | ||
214 | +void OPPROTO op_exit_tb (void) | ||
215 | +{ | ||
216 | + EXIT_TB(); | ||
217 | +} | ||
218 | + | ||
219 | +/* Arithmetic */ | ||
220 | +void OPPROTO op_addq (void) | ||
221 | +{ | ||
222 | + T0 += T1; | ||
223 | + RETURN(); | ||
224 | +} | ||
225 | + | ||
226 | +void OPPROTO op_addqv (void) | ||
227 | +{ | ||
228 | + helper_addqv(); | ||
229 | + RETURN(); | ||
230 | +} | ||
231 | + | ||
232 | +void OPPROTO op_addl (void) | ||
233 | +{ | ||
234 | + T0 = (int64_t)((int32_t)(T0 + T1)); | ||
235 | + RETURN(); | ||
236 | +} | ||
237 | + | ||
238 | +void OPPROTO op_addlv (void) | ||
239 | +{ | ||
240 | + helper_addlv(); | ||
241 | + RETURN(); | ||
242 | +} | ||
243 | + | ||
244 | +void OPPROTO op_subq (void) | ||
245 | +{ | ||
246 | + T0 -= T1; | ||
247 | + RETURN(); | ||
248 | +} | ||
249 | + | ||
250 | +void OPPROTO op_subqv (void) | ||
251 | +{ | ||
252 | + helper_subqv(); | ||
253 | + RETURN(); | ||
254 | +} | ||
255 | + | ||
256 | +void OPPROTO op_subl (void) | ||
257 | +{ | ||
258 | + T0 = (int64_t)((int32_t)(T0 - T1)); | ||
259 | + RETURN(); | ||
260 | +} | ||
261 | + | ||
262 | +void OPPROTO op_sublv (void) | ||
263 | +{ | ||
264 | + helper_sublv(); | ||
265 | + RETURN(); | ||
266 | +} | ||
267 | + | ||
268 | +void OPPROTO op_s4 (void) | ||
269 | +{ | ||
270 | + T0 <<= 2; | ||
271 | + RETURN(); | ||
272 | +} | ||
273 | + | ||
274 | +void OPPROTO op_s8 (void) | ||
275 | +{ | ||
276 | + T0 <<= 3; | ||
277 | + RETURN(); | ||
278 | +} | ||
279 | + | ||
280 | +void OPPROTO op_mull (void) | ||
281 | +{ | ||
282 | + T0 = (int64_t)((int32_t)T0 * (int32_t)T1); | ||
283 | + RETURN(); | ||
284 | +} | ||
285 | + | ||
286 | +void OPPROTO op_mullv (void) | ||
287 | +{ | ||
288 | + helper_mullv(); | ||
289 | + RETURN(); | ||
290 | +} | ||
291 | + | ||
292 | +void OPPROTO op_mulq (void) | ||
293 | +{ | ||
294 | + T0 *= T1; | ||
295 | + RETURN(); | ||
296 | +} | ||
297 | + | ||
298 | +void OPPROTO op_mulqv (void) | ||
299 | +{ | ||
300 | + helper_mulqv(); | ||
301 | + RETURN(); | ||
302 | +} | ||
303 | + | ||
304 | +void OPPROTO op_umulh (void) | ||
305 | +{ | ||
306 | + helper_umulh(); | ||
307 | + RETURN(); | ||
308 | +} | ||
309 | + | ||
310 | +/* Logical */ | ||
311 | +void OPPROTO op_and (void) | ||
312 | +{ | ||
313 | + T0 &= T1; | ||
314 | + RETURN(); | ||
315 | +} | ||
316 | + | ||
317 | +void OPPROTO op_bic (void) | ||
318 | +{ | ||
319 | + T0 &= ~T1; | ||
320 | + RETURN(); | ||
321 | +} | ||
322 | + | ||
323 | +void OPPROTO op_bis (void) | ||
324 | +{ | ||
325 | + T0 |= T1; | ||
326 | + RETURN(); | ||
327 | +} | ||
328 | + | ||
329 | +void OPPROTO op_eqv (void) | ||
330 | +{ | ||
331 | + T0 ^= ~T1; | ||
332 | + RETURN(); | ||
333 | +} | ||
334 | + | ||
335 | +void OPPROTO op_ornot (void) | ||
336 | +{ | ||
337 | + T0 |= ~T1; | ||
338 | + RETURN(); | ||
339 | +} | ||
340 | + | ||
341 | +void OPPROTO op_xor (void) | ||
342 | +{ | ||
343 | + T0 ^= T1; | ||
344 | + RETURN(); | ||
345 | +} | ||
346 | + | ||
347 | +void OPPROTO op_sll (void) | ||
348 | +{ | ||
349 | + T0 <<= T1; | ||
350 | + RETURN(); | ||
351 | +} | ||
352 | + | ||
353 | +void OPPROTO op_srl (void) | ||
354 | +{ | ||
355 | + T0 >>= T1; | ||
356 | + RETURN(); | ||
357 | +} | ||
358 | + | ||
359 | +void OPPROTO op_sra (void) | ||
360 | +{ | ||
361 | + T0 = (int64_t)T0 >> T1; | ||
362 | + RETURN(); | ||
363 | +} | ||
364 | + | ||
365 | +void OPPROTO op_sextb (void) | ||
366 | +{ | ||
367 | + T0 = (int64_t)((int8_t)T0); | ||
368 | + RETURN(); | ||
369 | +} | ||
370 | + | ||
371 | +void OPPROTO op_sextw (void) | ||
372 | +{ | ||
373 | + T0 = (int64_t)((int16_t)T0); | ||
374 | + RETURN(); | ||
375 | + | ||
376 | +} | ||
377 | + | ||
378 | +void OPPROTO op_ctpop (void) | ||
379 | +{ | ||
380 | + helper_ctpop(); | ||
381 | + RETURN(); | ||
382 | +} | ||
383 | + | ||
384 | +void OPPROTO op_ctlz (void) | ||
385 | +{ | ||
386 | + helper_ctlz(); | ||
387 | + RETURN(); | ||
388 | +} | ||
389 | + | ||
390 | +void OPPROTO op_cttz (void) | ||
391 | +{ | ||
392 | + helper_cttz(); | ||
393 | + RETURN(); | ||
394 | +} | ||
395 | + | ||
396 | +void OPPROTO op_mskbl (void) | ||
397 | +{ | ||
398 | + helper_mskbl(); | ||
399 | + RETURN(); | ||
400 | +} | ||
401 | + | ||
402 | +void OPPROTO op_extbl (void) | ||
403 | +{ | ||
404 | + helper_extbl(); | ||
405 | + RETURN(); | ||
406 | +} | ||
407 | + | ||
408 | +void OPPROTO op_insbl (void) | ||
409 | +{ | ||
410 | + helper_insbl(); | ||
411 | + RETURN(); | ||
412 | +} | ||
413 | + | ||
414 | +void OPPROTO op_mskwl (void) | ||
415 | +{ | ||
416 | + helper_mskwl(); | ||
417 | + RETURN(); | ||
418 | +} | ||
419 | + | ||
420 | +void OPPROTO op_extwl (void) | ||
421 | +{ | ||
422 | + helper_extwl(); | ||
423 | + RETURN(); | ||
424 | +} | ||
425 | + | ||
426 | +void OPPROTO op_inswl (void) | ||
427 | +{ | ||
428 | + helper_inswl(); | ||
429 | + RETURN(); | ||
430 | +} | ||
431 | + | ||
432 | +void OPPROTO op_mskll (void) | ||
433 | +{ | ||
434 | + helper_mskll(); | ||
435 | + RETURN(); | ||
436 | +} | ||
437 | + | ||
438 | +void OPPROTO op_extll (void) | ||
439 | +{ | ||
440 | + helper_extll(); | ||
441 | + RETURN(); | ||
442 | +} | ||
443 | + | ||
444 | +void OPPROTO op_insll (void) | ||
445 | +{ | ||
446 | + helper_insll(); | ||
447 | + RETURN(); | ||
448 | +} | ||
449 | + | ||
450 | +void OPPROTO op_zap (void) | ||
451 | +{ | ||
452 | + helper_zap(); | ||
453 | + RETURN(); | ||
454 | +} | ||
455 | + | ||
456 | +void OPPROTO op_zapnot (void) | ||
457 | +{ | ||
458 | + helper_zapnot(); | ||
459 | + RETURN(); | ||
460 | +} | ||
461 | + | ||
462 | +void OPPROTO op_mskql (void) | ||
463 | +{ | ||
464 | + helper_mskql(); | ||
465 | + RETURN(); | ||
466 | +} | ||
467 | + | ||
468 | +void OPPROTO op_extql (void) | ||
469 | +{ | ||
470 | + helper_extql(); | ||
471 | + RETURN(); | ||
472 | +} | ||
473 | + | ||
474 | +void OPPROTO op_insql (void) | ||
475 | +{ | ||
476 | + helper_insql(); | ||
477 | + RETURN(); | ||
478 | +} | ||
479 | + | ||
480 | +void OPPROTO op_mskwh (void) | ||
481 | +{ | ||
482 | + helper_mskwh(); | ||
483 | + RETURN(); | ||
484 | +} | ||
485 | + | ||
486 | +void OPPROTO op_inswh (void) | ||
487 | +{ | ||
488 | + helper_inswh(); | ||
489 | + RETURN(); | ||
490 | +} | ||
491 | + | ||
492 | +void OPPROTO op_extwh (void) | ||
493 | +{ | ||
494 | + helper_extwh(); | ||
495 | + RETURN(); | ||
496 | +} | ||
497 | + | ||
498 | +void OPPROTO op_msklh (void) | ||
499 | +{ | ||
500 | + helper_msklh(); | ||
501 | + RETURN(); | ||
502 | +} | ||
503 | + | ||
504 | +void OPPROTO op_inslh (void) | ||
505 | +{ | ||
506 | + helper_inslh(); | ||
507 | + RETURN(); | ||
508 | +} | ||
509 | + | ||
510 | +void OPPROTO op_extlh (void) | ||
511 | +{ | ||
512 | + helper_extlh(); | ||
513 | + RETURN(); | ||
514 | +} | ||
515 | + | ||
516 | +void OPPROTO op_mskqh (void) | ||
517 | +{ | ||
518 | + helper_mskqh(); | ||
519 | + RETURN(); | ||
520 | +} | ||
521 | + | ||
522 | +void OPPROTO op_insqh (void) | ||
523 | +{ | ||
524 | + helper_insqh(); | ||
525 | + RETURN(); | ||
526 | +} | ||
527 | + | ||
528 | +void OPPROTO op_extqh (void) | ||
529 | +{ | ||
530 | + helper_extqh(); | ||
531 | + RETURN(); | ||
532 | +} | ||
533 | + | ||
534 | +/* Tests */ | ||
535 | +void OPPROTO op_cmpult (void) | ||
536 | +{ | ||
537 | + if (T0 < T1) | ||
538 | + T0 = 1; | ||
539 | + else | ||
540 | + T0 = 0; | ||
541 | + RETURN(); | ||
542 | +} | ||
543 | + | ||
544 | +void OPPROTO op_cmpule (void) | ||
545 | +{ | ||
546 | + if (T0 <= T1) | ||
547 | + T0 = 1; | ||
548 | + else | ||
549 | + T0 = 0; | ||
550 | + RETURN(); | ||
551 | +} | ||
552 | + | ||
553 | +void OPPROTO op_cmpeq (void) | ||
554 | +{ | ||
555 | + if (T0 == T1) | ||
556 | + T0 = 1; | ||
557 | + else | ||
558 | + T0 = 0; | ||
559 | + RETURN(); | ||
560 | +} | ||
561 | + | ||
562 | +void OPPROTO op_cmplt (void) | ||
563 | +{ | ||
564 | + if ((int64_t)T0 < (int64_t)T1) | ||
565 | + T0 = 1; | ||
566 | + else | ||
567 | + T0 = 0; | ||
568 | + RETURN(); | ||
569 | +} | ||
570 | + | ||
571 | +void OPPROTO op_cmple (void) | ||
572 | +{ | ||
573 | + if ((int64_t)T0 <= (int64_t)T1) | ||
574 | + T0 = 1; | ||
575 | + else | ||
576 | + T0 = 0; | ||
577 | + RETURN(); | ||
578 | +} | ||
579 | + | ||
580 | +void OPPROTO op_cmpbge (void) | ||
581 | +{ | ||
582 | + helper_cmpbge(); | ||
583 | + RETURN(); | ||
584 | +} | ||
585 | + | ||
586 | +void OPPROTO op_cmpeqz (void) | ||
587 | +{ | ||
588 | + if (T0 == 0) | ||
589 | + T0 = 1; | ||
590 | + else | ||
591 | + T0 = 0; | ||
592 | + RETURN(); | ||
593 | +} | ||
594 | + | ||
595 | +void OPPROTO op_cmpnez (void) | ||
596 | +{ | ||
597 | + if (T0 != 0) | ||
598 | + T0 = 1; | ||
599 | + else | ||
600 | + T0 = 0; | ||
601 | + RETURN(); | ||
602 | +} | ||
603 | + | ||
604 | +void OPPROTO op_cmpltz (void) | ||
605 | +{ | ||
606 | + if ((int64_t)T0 < 0) | ||
607 | + T0 = 1; | ||
608 | + else | ||
609 | + T0 = 0; | ||
610 | + RETURN(); | ||
611 | +} | ||
612 | + | ||
613 | +void OPPROTO op_cmplez (void) | ||
614 | +{ | ||
615 | + if ((int64_t)T0 <= 0) | ||
616 | + T0 = 1; | ||
617 | + else | ||
618 | + T0 = 0; | ||
619 | + RETURN(); | ||
620 | +} | ||
621 | + | ||
622 | +void OPPROTO op_cmpgtz (void) | ||
623 | +{ | ||
624 | + if ((int64_t)T0 > 0) | ||
625 | + T0 = 1; | ||
626 | + else | ||
627 | + T0 = 0; | ||
628 | + RETURN(); | ||
629 | +} | ||
630 | + | ||
631 | +void OPPROTO op_cmpgez (void) | ||
632 | +{ | ||
633 | + if ((int64_t)T0 >= 0) | ||
634 | + T0 = 1; | ||
635 | + else | ||
636 | + T0 = 0; | ||
637 | + RETURN(); | ||
638 | +} | ||
639 | + | ||
640 | +void OPPROTO op_cmplbs (void) | ||
641 | +{ | ||
642 | + T0 &= 1; | ||
643 | + RETURN(); | ||
644 | +} | ||
645 | + | ||
646 | +void OPPROTO op_cmplbc (void) | ||
647 | +{ | ||
648 | + T0 = (~T0) & 1; | ||
649 | + RETURN(); | ||
650 | +} | ||
651 | + | ||
652 | +/* Branches */ | ||
653 | +void OPPROTO op_branch (void) | ||
654 | +{ | ||
655 | + env->pc = T0 & ~3; | ||
656 | + RETURN(); | ||
657 | +} | ||
658 | + | ||
659 | +void OPPROTO op_addq1 (void) | ||
660 | +{ | ||
661 | + T1 += T0; | ||
662 | + RETURN(); | ||
663 | +} | ||
664 | + | ||
665 | +#if 0 // Qemu does not know how to do this... | ||
666 | +void OPPROTO op_bcond (void) | ||
667 | +{ | ||
668 | + if (T0) | ||
669 | + env->pc = T1 & ~3; | ||
670 | + else | ||
671 | + env->pc = PARAM(1); | ||
672 | + RETURN(); | ||
673 | +} | ||
674 | +#else | ||
675 | +void OPPROTO op_bcond (void) | ||
676 | +{ | ||
677 | + if (T0) | ||
678 | + env->pc = T1 & ~3; | ||
679 | + else | ||
680 | + env->pc = ((uint64_t)PARAM(1) << 32) | (uint64_t)PARAM(2); | ||
681 | + RETURN(); | ||
682 | +} | ||
683 | +#endif | ||
684 | + | ||
685 | +#if 0 // Qemu does not know how to do this... | ||
686 | +void OPPROTO op_update_pc (void) | ||
687 | +{ | ||
688 | + env->pc = PARAM(1); | ||
689 | + RETURN(); | ||
690 | +} | ||
691 | +#else | ||
692 | +void OPPROTO op_update_pc (void) | ||
693 | +{ | ||
694 | + env->pc = ((uint64_t)PARAM(1) << 32) | (uint64_t)PARAM(2); | ||
695 | + RETURN(); | ||
696 | +} | ||
697 | +#endif | ||
698 | + | ||
699 | +/* Optimization for 32 bits hosts architectures */ | ||
700 | +void OPPROTO op_update_pc32 (void) | ||
701 | +{ | ||
702 | + env->pc = (uint64_t)PARAM(1); | ||
703 | + RETURN(); | ||
704 | +} | ||
705 | + | ||
706 | +/* IEEE floating point arithmetic */ | ||
707 | +/* S floating (single) */ | ||
708 | +void OPPROTO op_adds (void) | ||
709 | +{ | ||
710 | + FT0 = float32_add(FT0, FT1, &FP_STATUS); | ||
711 | + RETURN(); | ||
712 | +} | ||
713 | + | ||
714 | +void OPPROTO op_subs (void) | ||
715 | +{ | ||
716 | + FT0 = float32_sub(FT0, FT1, &FP_STATUS); | ||
717 | + RETURN(); | ||
718 | +} | ||
719 | + | ||
720 | +void OPPROTO op_muls (void) | ||
721 | +{ | ||
722 | + FT0 = float32_mul(FT0, FT1, &FP_STATUS); | ||
723 | + RETURN(); | ||
724 | +} | ||
725 | + | ||
726 | +void OPPROTO op_divs (void) | ||
727 | +{ | ||
728 | + FT0 = float32_div(FT0, FT1, &FP_STATUS); | ||
729 | + RETURN(); | ||
730 | +} | ||
731 | + | ||
732 | +void OPPROTO op_sqrts (void) | ||
733 | +{ | ||
734 | + helper_sqrts(); | ||
735 | + RETURN(); | ||
736 | +} | ||
737 | + | ||
738 | +void OPPROTO op_cpys (void) | ||
739 | +{ | ||
740 | + helper_cpys(); | ||
741 | + RETURN(); | ||
742 | +} | ||
743 | + | ||
744 | +void OPPROTO op_cpysn (void) | ||
745 | +{ | ||
746 | + helper_cpysn(); | ||
747 | + RETURN(); | ||
748 | +} | ||
749 | + | ||
750 | +void OPPROTO op_cpyse (void) | ||
751 | +{ | ||
752 | + helper_cpyse(); | ||
753 | + RETURN(); | ||
754 | +} | ||
755 | + | ||
756 | +void OPPROTO op_itofs (void) | ||
757 | +{ | ||
758 | + helper_itofs(); | ||
759 | + RETURN(); | ||
760 | +} | ||
761 | + | ||
762 | +void OPPROTO op_ftois (void) | ||
763 | +{ | ||
764 | + helper_ftois(); | ||
765 | + RETURN(); | ||
766 | +} | ||
767 | + | ||
768 | +/* T floating (double) */ | ||
769 | +void OPPROTO op_addt (void) | ||
770 | +{ | ||
771 | + FT0 = float64_add(FT0, FT1, &FP_STATUS); | ||
772 | + RETURN(); | ||
773 | +} | ||
774 | + | ||
775 | +void OPPROTO op_subt (void) | ||
776 | +{ | ||
777 | + FT0 = float64_sub(FT0, FT1, &FP_STATUS); | ||
778 | + RETURN(); | ||
779 | +} | ||
780 | + | ||
781 | +void OPPROTO op_mult (void) | ||
782 | +{ | ||
783 | + FT0 = float64_mul(FT0, FT1, &FP_STATUS); | ||
784 | + RETURN(); | ||
785 | +} | ||
786 | + | ||
787 | +void OPPROTO op_divt (void) | ||
788 | +{ | ||
789 | + FT0 = float64_div(FT0, FT1, &FP_STATUS); | ||
790 | + RETURN(); | ||
791 | +} | ||
792 | + | ||
793 | +void OPPROTO op_sqrtt (void) | ||
794 | +{ | ||
795 | + helper_sqrtt(); | ||
796 | + RETURN(); | ||
797 | +} | ||
798 | + | ||
799 | +void OPPROTO op_cmptun (void) | ||
800 | +{ | ||
801 | + helper_cmptun(); | ||
802 | + RETURN(); | ||
803 | +} | ||
804 | + | ||
805 | +void OPPROTO op_cmpteq (void) | ||
806 | +{ | ||
807 | + helper_cmpteq(); | ||
808 | + RETURN(); | ||
809 | +} | ||
810 | + | ||
811 | +void OPPROTO op_cmptle (void) | ||
812 | +{ | ||
813 | + helper_cmptle(); | ||
814 | + RETURN(); | ||
815 | +} | ||
816 | + | ||
817 | +void OPPROTO op_cmptlt (void) | ||
818 | +{ | ||
819 | + helper_cmptlt(); | ||
820 | + RETURN(); | ||
821 | +} | ||
822 | + | ||
823 | +void OPPROTO op_itoft (void) | ||
824 | +{ | ||
825 | + helper_itoft(); | ||
826 | + RETURN(); | ||
827 | +} | ||
828 | + | ||
829 | +void OPPROTO op_ftoit (void) | ||
830 | +{ | ||
831 | + helper_ftoit(); | ||
832 | + RETURN(); | ||
833 | +} | ||
834 | + | ||
835 | +/* VAX floating point arithmetic */ | ||
836 | +/* F floating */ | ||
837 | +void OPPROTO op_addf (void) | ||
838 | +{ | ||
839 | + helper_addf(); | ||
840 | + RETURN(); | ||
841 | +} | ||
842 | + | ||
843 | +void OPPROTO op_subf (void) | ||
844 | +{ | ||
845 | + helper_subf(); | ||
846 | + RETURN(); | ||
847 | +} | ||
848 | + | ||
849 | +void OPPROTO op_mulf (void) | ||
850 | +{ | ||
851 | + helper_mulf(); | ||
852 | + RETURN(); | ||
853 | +} | ||
854 | + | ||
855 | +void OPPROTO op_divf (void) | ||
856 | +{ | ||
857 | + helper_divf(); | ||
858 | + RETURN(); | ||
859 | +} | ||
860 | + | ||
861 | +void OPPROTO op_sqrtf (void) | ||
862 | +{ | ||
863 | + helper_sqrtf(); | ||
864 | + RETURN(); | ||
865 | +} | ||
866 | + | ||
867 | +void OPPROTO op_cmpfeq (void) | ||
868 | +{ | ||
869 | + helper_cmpfeq(); | ||
870 | + RETURN(); | ||
871 | +} | ||
872 | + | ||
873 | +void OPPROTO op_cmpfne (void) | ||
874 | +{ | ||
875 | + helper_cmpfne(); | ||
876 | + RETURN(); | ||
877 | +} | ||
878 | + | ||
879 | +void OPPROTO op_cmpflt (void) | ||
880 | +{ | ||
881 | + helper_cmpflt(); | ||
882 | + RETURN(); | ||
883 | +} | ||
884 | + | ||
885 | +void OPPROTO op_cmpfle (void) | ||
886 | +{ | ||
887 | + helper_cmpfle(); | ||
888 | + RETURN(); | ||
889 | +} | ||
890 | + | ||
891 | +void OPPROTO op_cmpfgt (void) | ||
892 | +{ | ||
893 | + helper_cmpfgt(); | ||
894 | + RETURN(); | ||
895 | +} | ||
896 | + | ||
897 | +void OPPROTO op_cmpfge (void) | ||
898 | +{ | ||
899 | + helper_cmpfge(); | ||
900 | + RETURN(); | ||
901 | +} | ||
902 | + | ||
903 | +void OPPROTO op_itoff (void) | ||
904 | +{ | ||
905 | + helper_itoff(); | ||
906 | + RETURN(); | ||
907 | +} | ||
908 | + | ||
909 | +/* G floating */ | ||
910 | +void OPPROTO op_addg (void) | ||
911 | +{ | ||
912 | + helper_addg(); | ||
913 | + RETURN(); | ||
914 | +} | ||
915 | + | ||
916 | +void OPPROTO op_subg (void) | ||
917 | +{ | ||
918 | + helper_subg(); | ||
919 | + RETURN(); | ||
920 | +} | ||
921 | + | ||
922 | +void OPPROTO op_mulg (void) | ||
923 | +{ | ||
924 | + helper_mulg(); | ||
925 | + RETURN(); | ||
926 | +} | ||
927 | + | ||
928 | +void OPPROTO op_divg (void) | ||
929 | +{ | ||
930 | + helper_divg(); | ||
931 | + RETURN(); | ||
932 | +} | ||
933 | + | ||
934 | +void OPPROTO op_sqrtg (void) | ||
935 | +{ | ||
936 | + helper_sqrtg(); | ||
937 | + RETURN(); | ||
938 | +} | ||
939 | + | ||
940 | +void OPPROTO op_cmpgeq (void) | ||
941 | +{ | ||
942 | + helper_cmpgeq(); | ||
943 | + RETURN(); | ||
944 | +} | ||
945 | + | ||
946 | +void OPPROTO op_cmpglt (void) | ||
947 | +{ | ||
948 | + helper_cmpglt(); | ||
949 | + RETURN(); | ||
950 | +} | ||
951 | + | ||
952 | +void OPPROTO op_cmpgle (void) | ||
953 | +{ | ||
954 | + helper_cmpgle(); | ||
955 | + RETURN(); | ||
956 | +} | ||
957 | + | ||
958 | +/* Floating point format conversion */ | ||
959 | +void OPPROTO op_cvtst (void) | ||
960 | +{ | ||
961 | + FT0 = (float)FT0; | ||
962 | + RETURN(); | ||
963 | +} | ||
964 | + | ||
965 | +void OPPROTO op_cvtqs (void) | ||
966 | +{ | ||
967 | + helper_cvtqs(); | ||
968 | + RETURN(); | ||
969 | +} | ||
970 | + | ||
971 | +void OPPROTO op_cvtts (void) | ||
972 | +{ | ||
973 | + FT0 = (float)FT0; | ||
974 | + RETURN(); | ||
975 | +} | ||
976 | + | ||
977 | +void OPPROTO op_cvttq (void) | ||
978 | +{ | ||
979 | + helper_cvttq(); | ||
980 | + RETURN(); | ||
981 | +} | ||
982 | + | ||
983 | +void OPPROTO op_cvtqt (void) | ||
984 | +{ | ||
985 | + helper_cvtqt(); | ||
986 | + RETURN(); | ||
987 | +} | ||
988 | + | ||
989 | +void OPPROTO op_cvtqf (void) | ||
990 | +{ | ||
991 | + helper_cvtqf(); | ||
992 | + RETURN(); | ||
993 | +} | ||
994 | + | ||
995 | +void OPPROTO op_cvtgf (void) | ||
996 | +{ | ||
997 | + helper_cvtgf(); | ||
998 | + RETURN(); | ||
999 | +} | ||
1000 | + | ||
1001 | +void OPPROTO op_cvtgd (void) | ||
1002 | +{ | ||
1003 | + helper_cvtgd(); | ||
1004 | + RETURN(); | ||
1005 | +} | ||
1006 | + | ||
1007 | +void OPPROTO op_cvtgq (void) | ||
1008 | +{ | ||
1009 | + helper_cvtgq(); | ||
1010 | + RETURN(); | ||
1011 | +} | ||
1012 | + | ||
1013 | +void OPPROTO op_cvtqg (void) | ||
1014 | +{ | ||
1015 | + helper_cvtqg(); | ||
1016 | + RETURN(); | ||
1017 | +} | ||
1018 | + | ||
1019 | +void OPPROTO op_cvtdg (void) | ||
1020 | +{ | ||
1021 | + helper_cvtdg(); | ||
1022 | + RETURN(); | ||
1023 | +} | ||
1024 | + | ||
1025 | +void OPPROTO op_cvtlq (void) | ||
1026 | +{ | ||
1027 | + helper_cvtlq(); | ||
1028 | + RETURN(); | ||
1029 | +} | ||
1030 | + | ||
1031 | +void OPPROTO op_cvtql (void) | ||
1032 | +{ | ||
1033 | + helper_cvtql(); | ||
1034 | + RETURN(); | ||
1035 | +} | ||
1036 | + | ||
1037 | +void OPPROTO op_cvtqlv (void) | ||
1038 | +{ | ||
1039 | + helper_cvtqlv(); | ||
1040 | + RETURN(); | ||
1041 | +} | ||
1042 | + | ||
1043 | +void OPPROTO op_cvtqlsv (void) | ||
1044 | +{ | ||
1045 | + helper_cvtqlsv(); | ||
1046 | + RETURN(); | ||
1047 | +} | ||
1048 | + | ||
1049 | +/* PALcode support special instructions */ | ||
1050 | +#if !defined (CONFIG_USER_ONLY) | ||
1051 | +void OPPROTO op_hw_rei (void) | ||
1052 | +{ | ||
1053 | + env->pc = env->ipr[IPR_EXC_ADDR] & ~3; | ||
1054 | + env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1; | ||
1055 | + /* XXX: re-enable interrupts and memory mapping */ | ||
1056 | + RETURN(); | ||
1057 | +} | ||
1058 | + | ||
1059 | +void OPPROTO op_hw_ret (void) | ||
1060 | +{ | ||
1061 | + env->pc = T0 & ~3; | ||
1062 | + env->ipr[IPR_EXC_ADDR] = T0 & 1; | ||
1063 | + /* XXX: re-enable interrupts and memory mapping */ | ||
1064 | + RETURN(); | ||
1065 | +} | ||
1066 | + | ||
1067 | +void OPPROTO op_mfpr (void) | ||
1068 | +{ | ||
1069 | + helper_mfpr(PARAM(1)); | ||
1070 | + RETURN(); | ||
1071 | +} | ||
1072 | + | ||
1073 | +void OPPROTO op_mtpr (void) | ||
1074 | +{ | ||
1075 | + helper_mtpr(PARAM(1)); | ||
1076 | + RETURN(); | ||
1077 | +} | ||
1078 | + | ||
1079 | +void OPPROTO op_set_alt_mode (void) | ||
1080 | +{ | ||
1081 | + env->saved_mode = env->ps & 0xC; | ||
1082 | + env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC); | ||
1083 | + RETURN(); | ||
1084 | +} | ||
1085 | + | ||
1086 | +void OPPROTO op_restore_mode (void) | ||
1087 | +{ | ||
1088 | + env->ps = (env->ps & ~0xC) | env->saved_mode; | ||
1089 | + RETURN(); | ||
1090 | +} | ||
1091 | + | ||
1092 | +void OPPROTO op_ld_phys_to_virt (void) | ||
1093 | +{ | ||
1094 | + helper_ld_phys_to_virt(); | ||
1095 | + RETURN(); | ||
1096 | +} | ||
1097 | + | ||
1098 | +void OPPROTO op_st_phys_to_virt (void) | ||
1099 | +{ | ||
1100 | + helper_st_phys_to_virt(); | ||
1101 | + RETURN(); | ||
1102 | +} | ||
1103 | +#endif /* !defined (CONFIG_USER_ONLY) */ |
target-alpha/op_helper.c
0 → 100644
1 | +/* | ||
2 | + * Alpha emulation cpu micro-operations helpers for qemu. | ||
3 | + * | ||
4 | + * Copyright (c) 2007 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 | +#include "exec.h" | ||
22 | +#include "softfloat.h" | ||
23 | + | ||
24 | +#include "op_helper.h" | ||
25 | + | ||
26 | +#define MEMSUFFIX _raw | ||
27 | +#include "op_helper_mem.h" | ||
28 | + | ||
29 | +#if !defined(CONFIG_USER_ONLY) | ||
30 | +#define MEMSUFFIX _user | ||
31 | +#include "op_helper_mem.h" | ||
32 | + | ||
33 | +#define MEMSUFFIX _kernel | ||
34 | +#include "op_helper_mem.h" | ||
35 | + | ||
36 | +/* Those are used for supervisor and executive modes */ | ||
37 | +#define MEMSUFFIX _data | ||
38 | +#include "op_helper_mem.h" | ||
39 | +#endif | ||
40 | + | ||
41 | +void helper_tb_flush (void) | ||
42 | +{ | ||
43 | + tlb_flush(env, 1); | ||
44 | +} | ||
45 | + | ||
46 | +void cpu_dump_EA (target_ulong EA); | ||
47 | +void helper_print_mem_EA (target_ulong EA) | ||
48 | +{ | ||
49 | + cpu_dump_EA(EA); | ||
50 | +} | ||
51 | + | ||
52 | +/*****************************************************************************/ | ||
53 | +/* Exceptions processing helpers */ | ||
54 | +void helper_excp (uint32_t excp, uint32_t error) | ||
55 | +{ | ||
56 | + env->exception_index = excp; | ||
57 | + env->error_code = error; | ||
58 | + cpu_loop_exit(); | ||
59 | +} | ||
60 | + | ||
61 | +void helper_amask (void) | ||
62 | +{ | ||
63 | + switch (env->implver) { | ||
64 | + case IMPLVER_2106x: | ||
65 | + /* EV4, EV45, LCA, LCA45 & EV5 */ | ||
66 | + break; | ||
67 | + case IMPLVER_21164: | ||
68 | + case IMPLVER_21264: | ||
69 | + case IMPLVER_21364: | ||
70 | + T0 &= ~env->amask; | ||
71 | + break; | ||
72 | + } | ||
73 | +} | ||
74 | + | ||
75 | +void helper_load_pcc (void) | ||
76 | +{ | ||
77 | + /* XXX: TODO */ | ||
78 | + T0 = 0; | ||
79 | +} | ||
80 | + | ||
81 | +void helper_load_implver (void) | ||
82 | +{ | ||
83 | + T0 = env->implver; | ||
84 | +} | ||
85 | + | ||
86 | +void helper_load_fpcr (void) | ||
87 | +{ | ||
88 | + T0 = 0; | ||
89 | +#ifdef CONFIG_SOFTFLOAT | ||
90 | + T0 |= env->fp_status.float_exception_flags << 52; | ||
91 | + if (env->fp_status.float_exception_flags) | ||
92 | + T0 |= 1ULL << 63; | ||
93 | + env->ipr[IPR_EXC_SUM] &= ~0x3E: | ||
94 | + env->ipr[IPR_EXC_SUM] |= env->fp_status.float_exception_flags << 1; | ||
95 | +#endif | ||
96 | + switch (env->fp_status.float_rounding_mode) { | ||
97 | + case float_round_nearest_even: | ||
98 | + T0 |= 2ULL << 58; | ||
99 | + break; | ||
100 | + case float_round_down: | ||
101 | + T0 |= 1ULL << 58; | ||
102 | + break; | ||
103 | + case float_round_up: | ||
104 | + T0 |= 3ULL << 58; | ||
105 | + break; | ||
106 | + case float_round_to_zero: | ||
107 | + break; | ||
108 | + } | ||
109 | +} | ||
110 | + | ||
111 | +void helper_store_fpcr (void) | ||
112 | +{ | ||
113 | +#ifdef CONFIG_SOFTFLOAT | ||
114 | + set_float_exception_flags((T0 >> 52) & 0x3F, &FP_STATUS); | ||
115 | +#endif | ||
116 | + switch ((T0 >> 58) & 3) { | ||
117 | + case 0: | ||
118 | + set_float_rounding_mode(float_round_to_zero, &FP_STATUS); | ||
119 | + break; | ||
120 | + case 1: | ||
121 | + set_float_rounding_mode(float_round_down, &FP_STATUS); | ||
122 | + break; | ||
123 | + case 2: | ||
124 | + set_float_rounding_mode(float_round_nearest_even, &FP_STATUS); | ||
125 | + break; | ||
126 | + case 3: | ||
127 | + set_float_rounding_mode(float_round_up, &FP_STATUS); | ||
128 | + break; | ||
129 | + } | ||
130 | +} | ||
131 | + | ||
132 | +void helper_load_irf (void) | ||
133 | +{ | ||
134 | + /* XXX: TODO */ | ||
135 | + T0 = 0; | ||
136 | +} | ||
137 | + | ||
138 | +void helper_set_irf (void) | ||
139 | +{ | ||
140 | + /* XXX: TODO */ | ||
141 | +} | ||
142 | + | ||
143 | +void helper_clear_irf (void) | ||
144 | +{ | ||
145 | + /* XXX: TODO */ | ||
146 | +} | ||
147 | + | ||
148 | +void helper_addqv (void) | ||
149 | +{ | ||
150 | + T2 = T0; | ||
151 | + T0 += T1; | ||
152 | + if (unlikely((T2 ^ T1 ^ (-1ULL)) & (T2 ^ T0) & (1ULL << 63))) { | ||
153 | + helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); | ||
154 | + } | ||
155 | +} | ||
156 | + | ||
157 | +void helper_addlv (void) | ||
158 | +{ | ||
159 | + T2 = T0; | ||
160 | + T0 = (uint32_t)(T0 + T1); | ||
161 | + if (unlikely((T2 ^ T1 ^ (-1UL)) & (T2 ^ T0) & (1UL << 31))) { | ||
162 | + helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); | ||
163 | + } | ||
164 | +} | ||
165 | + | ||
166 | +void helper_subqv (void) | ||
167 | +{ | ||
168 | + T2 = T0; | ||
169 | + T0 -= T1; | ||
170 | + if (unlikely(((~T2) ^ T0 ^ (-1ULL)) & ((~T2) ^ T1) & (1ULL << 63))) { | ||
171 | + helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); | ||
172 | + } | ||
173 | +} | ||
174 | + | ||
175 | +void helper_sublv (void) | ||
176 | +{ | ||
177 | + T2 = T0; | ||
178 | + T0 = (uint32_t)(T0 - T1); | ||
179 | + if (unlikely(((~T2) ^ T0 ^ (-1UL)) & ((~T2) ^ T1) & (1UL << 31))) { | ||
180 | + helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); | ||
181 | + } | ||
182 | +} | ||
183 | + | ||
184 | +void helper_mullv (void) | ||
185 | +{ | ||
186 | + int64_t res = (int64_t)T0 * (int64_t)T1; | ||
187 | + | ||
188 | + if (unlikely((int32_t)res != res)) { | ||
189 | + helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); | ||
190 | + } | ||
191 | + T0 = (int64_t)((int32_t)res); | ||
192 | +} | ||
193 | + | ||
194 | +void helper_mulqv () | ||
195 | +{ | ||
196 | + uint64_t res, tmp0, tmp1; | ||
197 | + | ||
198 | + res = (T0 >> 32) * (T1 >> 32); | ||
199 | + tmp0 = ((T0 & 0xFFFFFFFF) * (T1 >> 32)) + | ||
200 | + ((T0 >> 32) * (T1 & 0xFFFFFFFF)); | ||
201 | + tmp1 = (T0 & 0xFFFFFFFF) * (T1 & 0xFFFFFFFF); | ||
202 | + tmp0 += tmp1 >> 32; | ||
203 | + res += tmp0 >> 32; | ||
204 | + T0 *= T1; | ||
205 | + if (unlikely(res != 0)) { | ||
206 | + helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); | ||
207 | + } | ||
208 | +} | ||
209 | + | ||
210 | +void helper_umulh (void) | ||
211 | +{ | ||
212 | + uint64_t tmp0, tmp1; | ||
213 | + | ||
214 | + tmp0 = ((T0 & 0xFFFFFFFF) * (T1 >> 32)) + | ||
215 | + ((T0 >> 32) * (T1 & 0xFFFFFFFF)); | ||
216 | + tmp1 = (T0 & 0xFFFFFFFF) * (T1 & 0xFFFFFFFF); | ||
217 | + tmp0 += tmp1 >> 32; | ||
218 | + T0 = (T0 >> 32) * (T0 >> 32); | ||
219 | + T0 += tmp0 >> 32; | ||
220 | +} | ||
221 | + | ||
222 | +void helper_ctpop (void) | ||
223 | +{ | ||
224 | + int n; | ||
225 | + | ||
226 | + for (n = 0; T0 != 0; n++) | ||
227 | + T0 = T0 ^ (T0 - 1); | ||
228 | + T0 = n; | ||
229 | +} | ||
230 | + | ||
231 | +void helper_ctlz (void) | ||
232 | +{ | ||
233 | + uint32_t op32; | ||
234 | + int n; | ||
235 | + | ||
236 | + n = 0; | ||
237 | + if (!(T0 & 0xFFFFFFFF00000000ULL)) { | ||
238 | + n += 32; | ||
239 | + T0 <<= 32; | ||
240 | + } | ||
241 | + /* Make it easier for 32 bits hosts */ | ||
242 | + op32 = T0 >> 32; | ||
243 | + if (!(op32 & 0xFFFF0000UL)) { | ||
244 | + n += 16; | ||
245 | + op32 <<= 16; | ||
246 | + } | ||
247 | + if (!(op32 & 0xFF000000UL)) { | ||
248 | + n += 8; | ||
249 | + op32 <<= 8; | ||
250 | + } | ||
251 | + if (!(op32 & 0xF0000000UL)) { | ||
252 | + n += 4; | ||
253 | + op32 <<= 4; | ||
254 | + } | ||
255 | + if (!(op32 & 0xC0000000UL)) { | ||
256 | + n += 2; | ||
257 | + op32 <<= 2; | ||
258 | + } | ||
259 | + if (!(op32 & 0x80000000UL)) { | ||
260 | + n++; | ||
261 | + op32 <<= 1; | ||
262 | + } | ||
263 | + if (!(op32 & 0x80000000UL)) { | ||
264 | + n++; | ||
265 | + } | ||
266 | + T0 = n; | ||
267 | +} | ||
268 | + | ||
269 | +void helper_cttz (void) | ||
270 | +{ | ||
271 | + uint32_t op32; | ||
272 | + int n; | ||
273 | + | ||
274 | + n = 0; | ||
275 | + if (!(T0 & 0x00000000FFFFFFFFULL)) { | ||
276 | + n += 32; | ||
277 | + T0 >>= 32; | ||
278 | + } | ||
279 | + /* Make it easier for 32 bits hosts */ | ||
280 | + op32 = T0; | ||
281 | + if (!(op32 & 0x0000FFFFUL)) { | ||
282 | + n += 16; | ||
283 | + op32 >>= 16; | ||
284 | + } | ||
285 | + if (!(op32 & 0x000000FFUL)) { | ||
286 | + n += 8; | ||
287 | + op32 >>= 8; | ||
288 | + } | ||
289 | + if (!(op32 & 0x0000000FUL)) { | ||
290 | + n += 4; | ||
291 | + op32 >>= 4; | ||
292 | + } | ||
293 | + if (!(op32 & 0x00000003UL)) { | ||
294 | + n += 2; | ||
295 | + op32 >>= 2; | ||
296 | + } | ||
297 | + if (!(op32 & 0x00000001UL)) { | ||
298 | + n++; | ||
299 | + op32 >>= 1; | ||
300 | + } | ||
301 | + if (!(op32 & 0x00000001UL)) { | ||
302 | + n++; | ||
303 | + } | ||
304 | + T0 = n; | ||
305 | +} | ||
306 | + | ||
307 | +static inline uint64_t byte_zap (uint64_t op, uint8_t mskb) | ||
308 | +{ | ||
309 | + uint64_t mask; | ||
310 | + | ||
311 | + mask = 0; | ||
312 | + mask |= ((mskb >> 0) & 1) * 0x00000000000000FFULL; | ||
313 | + mask |= ((mskb >> 1) & 1) * 0x000000000000FF00ULL; | ||
314 | + mask |= ((mskb >> 2) & 1) * 0x0000000000FF0000ULL; | ||
315 | + mask |= ((mskb >> 3) & 1) * 0x00000000FF000000ULL; | ||
316 | + mask |= ((mskb >> 4) & 1) * 0x000000FF00000000ULL; | ||
317 | + mask |= ((mskb >> 5) & 1) * 0x0000FF0000000000ULL; | ||
318 | + mask |= ((mskb >> 6) & 1) * 0x00FF000000000000ULL; | ||
319 | + mask |= ((mskb >> 7) & 1) * 0xFF00000000000000ULL; | ||
320 | + | ||
321 | + return op & ~mask; | ||
322 | +} | ||
323 | + | ||
324 | +void helper_mskbl (void) | ||
325 | +{ | ||
326 | + T0 = byte_zap(T0, 0x01 << (T1 & 7)); | ||
327 | +} | ||
328 | + | ||
329 | +void helper_extbl (void) | ||
330 | +{ | ||
331 | + T0 >>= (T1 & 7) * 8; | ||
332 | + T0 = byte_zap(T0, 0xFE); | ||
333 | +} | ||
334 | + | ||
335 | +void helper_insbl (void) | ||
336 | +{ | ||
337 | + T0 <<= (T1 & 7) * 8; | ||
338 | + T0 = byte_zap(T0, ~(0x01 << (T1 & 7))); | ||
339 | +} | ||
340 | + | ||
341 | +void helper_mskwl (void) | ||
342 | +{ | ||
343 | + T0 = byte_zap(T0, 0x03 << (T1 & 7)); | ||
344 | +} | ||
345 | + | ||
346 | +void helper_extwl (void) | ||
347 | +{ | ||
348 | + T0 >>= (T1 & 7) * 8; | ||
349 | + T0 = byte_zap(T0, 0xFC); | ||
350 | +} | ||
351 | + | ||
352 | +void helper_inswl (void) | ||
353 | +{ | ||
354 | + T0 <<= (T1 & 7) * 8; | ||
355 | + T0 = byte_zap(T0, ~(0x03 << (T1 & 7))); | ||
356 | +} | ||
357 | + | ||
358 | +void helper_mskll (void) | ||
359 | +{ | ||
360 | + T0 = byte_zap(T0, 0x0F << (T1 & 7)); | ||
361 | +} | ||
362 | + | ||
363 | +void helper_extll (void) | ||
364 | +{ | ||
365 | + T0 >>= (T1 & 7) * 8; | ||
366 | + T0 = byte_zap(T0, 0xF0); | ||
367 | +} | ||
368 | + | ||
369 | +void helper_insll (void) | ||
370 | +{ | ||
371 | + T0 <<= (T1 & 7) * 8; | ||
372 | + T0 = byte_zap(T0, ~(0x0F << (T1 & 7))); | ||
373 | +} | ||
374 | + | ||
375 | +void helper_zap (void) | ||
376 | +{ | ||
377 | + T0 = byte_zap(T0, T1); | ||
378 | +} | ||
379 | + | ||
380 | +void helper_zapnot (void) | ||
381 | +{ | ||
382 | + T0 = byte_zap(T0, ~T1); | ||
383 | +} | ||
384 | + | ||
385 | +void helper_mskql (void) | ||
386 | +{ | ||
387 | + T0 = byte_zap(T0, 0xFF << (T1 & 7)); | ||
388 | +} | ||
389 | + | ||
390 | +void helper_extql (void) | ||
391 | +{ | ||
392 | + T0 >>= (T1 & 7) * 8; | ||
393 | + T0 = byte_zap(T0, 0x00); | ||
394 | +} | ||
395 | + | ||
396 | +void helper_insql (void) | ||
397 | +{ | ||
398 | + T0 <<= (T1 & 7) * 8; | ||
399 | + T0 = byte_zap(T0, ~(0xFF << (T1 & 7))); | ||
400 | +} | ||
401 | + | ||
402 | +void helper_mskwh (void) | ||
403 | +{ | ||
404 | + T0 = byte_zap(T0, (0x03 << (T1 & 7)) >> 8); | ||
405 | +} | ||
406 | + | ||
407 | +void helper_inswh (void) | ||
408 | +{ | ||
409 | + T0 >>= 64 - ((T1 & 7) * 8); | ||
410 | + T0 = byte_zap(T0, ~((0x03 << (T1 & 7)) >> 8)); | ||
411 | +} | ||
412 | + | ||
413 | +void helper_extwh (void) | ||
414 | +{ | ||
415 | + T0 <<= 64 - ((T1 & 7) * 8); | ||
416 | + T0 = byte_zap(T0, ~0x07); | ||
417 | +} | ||
418 | + | ||
419 | +void helper_msklh (void) | ||
420 | +{ | ||
421 | + T0 = byte_zap(T0, (0x0F << (T1 & 7)) >> 8); | ||
422 | +} | ||
423 | + | ||
424 | +void helper_inslh (void) | ||
425 | +{ | ||
426 | + T0 >>= 64 - ((T1 & 7) * 8); | ||
427 | + T0 = byte_zap(T0, ~((0x0F << (T1 & 7)) >> 8)); | ||
428 | +} | ||
429 | + | ||
430 | +void helper_extlh (void) | ||
431 | +{ | ||
432 | + T0 <<= 64 - ((T1 & 7) * 8); | ||
433 | + T0 = byte_zap(T0, ~0x0F); | ||
434 | +} | ||
435 | + | ||
436 | +void helper_mskqh (void) | ||
437 | +{ | ||
438 | + T0 = byte_zap(T0, (0xFF << (T1 & 7)) >> 8); | ||
439 | +} | ||
440 | + | ||
441 | +void helper_insqh (void) | ||
442 | +{ | ||
443 | + T0 >>= 64 - ((T1 & 7) * 8); | ||
444 | + T0 = byte_zap(T0, ~((0xFF << (T1 & 7)) >> 8)); | ||
445 | +} | ||
446 | + | ||
447 | +void helper_extqh (void) | ||
448 | +{ | ||
449 | + T0 <<= 64 - ((T1 & 7) * 8); | ||
450 | + T0 = byte_zap(T0, 0x00); | ||
451 | +} | ||
452 | + | ||
453 | +void helper_cmpbge (void) | ||
454 | +{ | ||
455 | + uint8_t opa, opb, res; | ||
456 | + int i; | ||
457 | + | ||
458 | + res = 0; | ||
459 | + for (i = 0; i < 7; i++) { | ||
460 | + opa = T0 >> (i * 8); | ||
461 | + opb = T1 >> (i * 8); | ||
462 | + if (opa >= opb) | ||
463 | + res |= 1 << i; | ||
464 | + } | ||
465 | + T0 = res; | ||
466 | +} | ||
467 | + | ||
468 | +void helper_cmov_fir (int freg) | ||
469 | +{ | ||
470 | + if (FT0 != 0) | ||
471 | + env->fir[freg] = FT1; | ||
472 | +} | ||
473 | + | ||
474 | +void helper_sqrts (void) | ||
475 | +{ | ||
476 | + FT0 = float32_sqrt(FT0, &FP_STATUS); | ||
477 | +} | ||
478 | + | ||
479 | +void helper_cpys (void) | ||
480 | +{ | ||
481 | + union { | ||
482 | + double d; | ||
483 | + uint64_t i; | ||
484 | + } p, q, r; | ||
485 | + | ||
486 | + p.d = FT0; | ||
487 | + q.d = FT1; | ||
488 | + r.i = p.i & 0x8000000000000000ULL; | ||
489 | + r.i |= q.i & ~0x8000000000000000ULL; | ||
490 | + FT0 = r.d; | ||
491 | +} | ||
492 | + | ||
493 | +void helper_cpysn (void) | ||
494 | +{ | ||
495 | + union { | ||
496 | + double d; | ||
497 | + uint64_t i; | ||
498 | + } p, q, r; | ||
499 | + | ||
500 | + p.d = FT0; | ||
501 | + q.d = FT1; | ||
502 | + r.i = (~p.i) & 0x8000000000000000ULL; | ||
503 | + r.i |= q.i & ~0x8000000000000000ULL; | ||
504 | + FT0 = r.d; | ||
505 | +} | ||
506 | + | ||
507 | +void helper_cpyse (void) | ||
508 | +{ | ||
509 | + union { | ||
510 | + double d; | ||
511 | + uint64_t i; | ||
512 | + } p, q, r; | ||
513 | + | ||
514 | + p.d = FT0; | ||
515 | + q.d = FT1; | ||
516 | + r.i = p.i & 0xFFF0000000000000ULL; | ||
517 | + r.i |= q.i & ~0xFFF0000000000000ULL; | ||
518 | + FT0 = r.d; | ||
519 | +} | ||
520 | + | ||
521 | +void helper_itofs (void) | ||
522 | +{ | ||
523 | + union { | ||
524 | + double d; | ||
525 | + uint64_t i; | ||
526 | + } p; | ||
527 | + | ||
528 | + p.d = FT0; | ||
529 | + FT0 = int64_to_float32(p.i, &FP_STATUS); | ||
530 | +} | ||
531 | + | ||
532 | +void helper_ftois (void) | ||
533 | +{ | ||
534 | + union { | ||
535 | + double d; | ||
536 | + uint64_t i; | ||
537 | + } p; | ||
538 | + | ||
539 | + p.i = float32_to_int64(FT0, &FP_STATUS); | ||
540 | + FT0 = p.d; | ||
541 | +} | ||
542 | + | ||
543 | +void helper_sqrtt (void) | ||
544 | +{ | ||
545 | + FT0 = float64_sqrt(FT0, &FP_STATUS); | ||
546 | +} | ||
547 | + | ||
548 | +void helper_cmptun (void) | ||
549 | +{ | ||
550 | + union { | ||
551 | + double d; | ||
552 | + uint64_t i; | ||
553 | + } p; | ||
554 | + | ||
555 | + p.i = 0; | ||
556 | + if (float64_is_nan(FT0) || float64_is_nan(FT1)) | ||
557 | + p.i = 0x4000000000000000ULL; | ||
558 | + FT0 = p.d; | ||
559 | +} | ||
560 | + | ||
561 | +void helper_cmpteq (void) | ||
562 | +{ | ||
563 | + union { | ||
564 | + double d; | ||
565 | + uint64_t i; | ||
566 | + } p; | ||
567 | + | ||
568 | + p.i = 0; | ||
569 | + if (float64_eq(FT0, FT1, &FP_STATUS)) | ||
570 | + p.i = 0x4000000000000000ULL; | ||
571 | + FT0 = p.d; | ||
572 | +} | ||
573 | + | ||
574 | +void helper_cmptle (void) | ||
575 | +{ | ||
576 | + union { | ||
577 | + double d; | ||
578 | + uint64_t i; | ||
579 | + } p; | ||
580 | + | ||
581 | + p.i = 0; | ||
582 | + if (float64_le(FT0, FT1, &FP_STATUS)) | ||
583 | + p.i = 0x4000000000000000ULL; | ||
584 | + FT0 = p.d; | ||
585 | +} | ||
586 | + | ||
587 | +void helper_cmptlt (void) | ||
588 | +{ | ||
589 | + union { | ||
590 | + double d; | ||
591 | + uint64_t i; | ||
592 | + } p; | ||
593 | + | ||
594 | + p.i = 0; | ||
595 | + if (float64_lt(FT0, FT1, &FP_STATUS)) | ||
596 | + p.i = 0x4000000000000000ULL; | ||
597 | + FT0 = p.d; | ||
598 | +} | ||
599 | + | ||
600 | +void helper_itoft (void) | ||
601 | +{ | ||
602 | + union { | ||
603 | + double d; | ||
604 | + uint64_t i; | ||
605 | + } p; | ||
606 | + | ||
607 | + p.d = FT0; | ||
608 | + FT0 = int64_to_float64(p.i, &FP_STATUS); | ||
609 | +} | ||
610 | + | ||
611 | +void helper_ftoit (void) | ||
612 | +{ | ||
613 | + union { | ||
614 | + double d; | ||
615 | + uint64_t i; | ||
616 | + } p; | ||
617 | + | ||
618 | + p.i = float64_to_int64(FT0, &FP_STATUS); | ||
619 | + FT0 = p.d; | ||
620 | +} | ||
621 | + | ||
622 | +static int vaxf_is_valid (float ff) | ||
623 | +{ | ||
624 | + union { | ||
625 | + float f; | ||
626 | + uint32_t i; | ||
627 | + } p; | ||
628 | + uint32_t exp, mant; | ||
629 | + | ||
630 | + p.f = ff; | ||
631 | + exp = (p.i >> 23) & 0xFF; | ||
632 | + mant = p.i & 0x007FFFFF; | ||
633 | + if (exp == 0 && ((p.i & 0x80000000) || mant != 0)) { | ||
634 | + /* Reserved operands / Dirty zero */ | ||
635 | + return 0; | ||
636 | + } | ||
637 | + | ||
638 | + return 1; | ||
639 | +} | ||
640 | + | ||
641 | +static float vaxf_to_ieee32 (float ff) | ||
642 | +{ | ||
643 | + union { | ||
644 | + float f; | ||
645 | + uint32_t i; | ||
646 | + } p; | ||
647 | + uint32_t exp; | ||
648 | + | ||
649 | + p.f = ff; | ||
650 | + exp = (p.i >> 23) & 0xFF; | ||
651 | + if (exp < 3) { | ||
652 | + /* Underflow */ | ||
653 | + p.f = 0.0; | ||
654 | + } else { | ||
655 | + p.f *= 0.25; | ||
656 | + } | ||
657 | + | ||
658 | + return p.f; | ||
659 | +} | ||
660 | + | ||
661 | +static float ieee32_to_vaxf (float fi) | ||
662 | +{ | ||
663 | + union { | ||
664 | + float f; | ||
665 | + uint32_t i; | ||
666 | + } p; | ||
667 | + uint32_t exp, mant; | ||
668 | + | ||
669 | + p.f = fi; | ||
670 | + exp = (p.i >> 23) & 0xFF; | ||
671 | + mant = p.i & 0x007FFFFF; | ||
672 | + if (exp == 255) { | ||
673 | + /* NaN or infinity */ | ||
674 | + p.i = 1; | ||
675 | + } else if (exp == 0) { | ||
676 | + if (mant == 0) { | ||
677 | + /* Zero */ | ||
678 | + p.i = 0; | ||
679 | + } else { | ||
680 | + /* Denormalized */ | ||
681 | + p.f *= 2.0; | ||
682 | + } | ||
683 | + } else { | ||
684 | + if (exp >= 253) { | ||
685 | + /* Overflow */ | ||
686 | + p.i = 1; | ||
687 | + } else { | ||
688 | + p.f *= 4.0; | ||
689 | + } | ||
690 | + } | ||
691 | + | ||
692 | + return p.f; | ||
693 | +} | ||
694 | + | ||
695 | +void helper_addf (void) | ||
696 | +{ | ||
697 | + float ft0, ft1, ft2; | ||
698 | + | ||
699 | + if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) { | ||
700 | + /* XXX: TODO */ | ||
701 | + } | ||
702 | + ft0 = vaxf_to_ieee32(FT0); | ||
703 | + ft1 = vaxf_to_ieee32(FT1); | ||
704 | + ft2 = float32_add(ft0, ft1, &FP_STATUS); | ||
705 | + FT0 = ieee32_to_vaxf(ft2); | ||
706 | +} | ||
707 | + | ||
708 | +void helper_subf (void) | ||
709 | +{ | ||
710 | + float ft0, ft1, ft2; | ||
711 | + | ||
712 | + if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) { | ||
713 | + /* XXX: TODO */ | ||
714 | + } | ||
715 | + ft0 = vaxf_to_ieee32(FT0); | ||
716 | + ft1 = vaxf_to_ieee32(FT1); | ||
717 | + ft2 = float32_sub(ft0, ft1, &FP_STATUS); | ||
718 | + FT0 = ieee32_to_vaxf(ft2); | ||
719 | +} | ||
720 | + | ||
721 | +void helper_mulf (void) | ||
722 | +{ | ||
723 | + float ft0, ft1, ft2; | ||
724 | + | ||
725 | + if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) { | ||
726 | + /* XXX: TODO */ | ||
727 | + } | ||
728 | + ft0 = vaxf_to_ieee32(FT0); | ||
729 | + ft1 = vaxf_to_ieee32(FT1); | ||
730 | + ft2 = float32_mul(ft0, ft1, &FP_STATUS); | ||
731 | + FT0 = ieee32_to_vaxf(ft2); | ||
732 | +} | ||
733 | + | ||
734 | +void helper_divf (void) | ||
735 | +{ | ||
736 | + float ft0, ft1, ft2; | ||
737 | + | ||
738 | + if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) { | ||
739 | + /* XXX: TODO */ | ||
740 | + } | ||
741 | + ft0 = vaxf_to_ieee32(FT0); | ||
742 | + ft1 = vaxf_to_ieee32(FT1); | ||
743 | + ft2 = float32_div(ft0, ft1, &FP_STATUS); | ||
744 | + FT0 = ieee32_to_vaxf(ft2); | ||
745 | +} | ||
746 | + | ||
747 | +void helper_sqrtf (void) | ||
748 | +{ | ||
749 | + float ft0, ft1; | ||
750 | + | ||
751 | + if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) { | ||
752 | + /* XXX: TODO */ | ||
753 | + } | ||
754 | + ft0 = vaxf_to_ieee32(FT0); | ||
755 | + ft1 = float32_sqrt(ft0, &FP_STATUS); | ||
756 | + FT0 = ieee32_to_vaxf(ft1); | ||
757 | +} | ||
758 | + | ||
759 | +void helper_itoff (void) | ||
760 | +{ | ||
761 | + /* XXX: TODO */ | ||
762 | +} | ||
763 | + | ||
764 | +static int vaxg_is_valid (double ff) | ||
765 | +{ | ||
766 | + union { | ||
767 | + double f; | ||
768 | + uint64_t i; | ||
769 | + } p; | ||
770 | + uint64_t exp, mant; | ||
771 | + | ||
772 | + p.f = ff; | ||
773 | + exp = (p.i >> 52) & 0x7FF; | ||
774 | + mant = p.i & 0x000FFFFFFFFFFFFFULL; | ||
775 | + if (exp == 0 && ((p.i & 0x8000000000000000ULL) || mant != 0)) { | ||
776 | + /* Reserved operands / Dirty zero */ | ||
777 | + return 0; | ||
778 | + } | ||
779 | + | ||
780 | + return 1; | ||
781 | +} | ||
782 | + | ||
783 | +static double vaxg_to_ieee64 (double fg) | ||
784 | +{ | ||
785 | + union { | ||
786 | + double f; | ||
787 | + uint64_t i; | ||
788 | + } p; | ||
789 | + uint32_t exp; | ||
790 | + | ||
791 | + p.f = fg; | ||
792 | + exp = (p.i >> 52) & 0x7FF; | ||
793 | + if (exp < 3) { | ||
794 | + /* Underflow */ | ||
795 | + p.f = 0.0; | ||
796 | + } else { | ||
797 | + p.f *= 0.25; | ||
798 | + } | ||
799 | + | ||
800 | + return p.f; | ||
801 | +} | ||
802 | + | ||
803 | +static double ieee64_to_vaxg (double fi) | ||
804 | +{ | ||
805 | + union { | ||
806 | + double f; | ||
807 | + uint64_t i; | ||
808 | + } p; | ||
809 | + uint64_t mant; | ||
810 | + uint32_t exp; | ||
811 | + | ||
812 | + p.f = fi; | ||
813 | + exp = (p.i >> 52) & 0x7FF; | ||
814 | + mant = p.i & 0x000FFFFFFFFFFFFFULL; | ||
815 | + if (exp == 255) { | ||
816 | + /* NaN or infinity */ | ||
817 | + p.i = 1; /* VAX dirty zero */ | ||
818 | + } else if (exp == 0) { | ||
819 | + if (mant == 0) { | ||
820 | + /* Zero */ | ||
821 | + p.i = 0; | ||
822 | + } else { | ||
823 | + /* Denormalized */ | ||
824 | + p.f *= 2.0; | ||
825 | + } | ||
826 | + } else { | ||
827 | + if (exp >= 2045) { | ||
828 | + /* Overflow */ | ||
829 | + p.i = 1; /* VAX dirty zero */ | ||
830 | + } else { | ||
831 | + p.f *= 4.0; | ||
832 | + } | ||
833 | + } | ||
834 | + | ||
835 | + return p.f; | ||
836 | +} | ||
837 | + | ||
838 | +void helper_addg (void) | ||
839 | +{ | ||
840 | + double ft0, ft1, ft2; | ||
841 | + | ||
842 | + if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) { | ||
843 | + /* XXX: TODO */ | ||
844 | + } | ||
845 | + ft0 = vaxg_to_ieee64(FT0); | ||
846 | + ft1 = vaxg_to_ieee64(FT1); | ||
847 | + ft2 = float64_add(ft0, ft1, &FP_STATUS); | ||
848 | + FT0 = ieee64_to_vaxg(ft2); | ||
849 | +} | ||
850 | + | ||
851 | +void helper_subg (void) | ||
852 | +{ | ||
853 | + double ft0, ft1, ft2; | ||
854 | + | ||
855 | + if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) { | ||
856 | + /* XXX: TODO */ | ||
857 | + } | ||
858 | + ft0 = vaxg_to_ieee64(FT0); | ||
859 | + ft1 = vaxg_to_ieee64(FT1); | ||
860 | + ft2 = float64_sub(ft0, ft1, &FP_STATUS); | ||
861 | + FT0 = ieee64_to_vaxg(ft2); | ||
862 | +} | ||
863 | + | ||
864 | +void helper_mulg (void) | ||
865 | +{ | ||
866 | + double ft0, ft1, ft2; | ||
867 | + | ||
868 | + if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) { | ||
869 | + /* XXX: TODO */ | ||
870 | + } | ||
871 | + ft0 = vaxg_to_ieee64(FT0); | ||
872 | + ft1 = vaxg_to_ieee64(FT1); | ||
873 | + ft2 = float64_mul(ft0, ft1, &FP_STATUS); | ||
874 | + FT0 = ieee64_to_vaxg(ft2); | ||
875 | +} | ||
876 | + | ||
877 | +void helper_divg (void) | ||
878 | +{ | ||
879 | + double ft0, ft1, ft2; | ||
880 | + | ||
881 | + if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) { | ||
882 | + /* XXX: TODO */ | ||
883 | + } | ||
884 | + ft0 = vaxg_to_ieee64(FT0); | ||
885 | + ft1 = vaxg_to_ieee64(FT1); | ||
886 | + ft2 = float64_div(ft0, ft1, &FP_STATUS); | ||
887 | + FT0 = ieee64_to_vaxg(ft2); | ||
888 | +} | ||
889 | + | ||
890 | +void helper_sqrtg (void) | ||
891 | +{ | ||
892 | + double ft0, ft1; | ||
893 | + | ||
894 | + if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) { | ||
895 | + /* XXX: TODO */ | ||
896 | + } | ||
897 | + ft0 = vaxg_to_ieee64(FT0); | ||
898 | + ft1 = float64_sqrt(ft0, &FP_STATUS); | ||
899 | + FT0 = ieee64_to_vaxg(ft1); | ||
900 | +} | ||
901 | + | ||
902 | +void helper_cmpgeq (void) | ||
903 | +{ | ||
904 | + union { | ||
905 | + double d; | ||
906 | + uint64_t u; | ||
907 | + } p; | ||
908 | + double ft0, ft1; | ||
909 | + | ||
910 | + if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) { | ||
911 | + /* XXX: TODO */ | ||
912 | + } | ||
913 | + ft0 = vaxg_to_ieee64(FT0); | ||
914 | + ft1 = vaxg_to_ieee64(FT1); | ||
915 | + p.u = 0; | ||
916 | + if (float64_eq(ft0, ft1, &FP_STATUS)) | ||
917 | + p.u = 0x4000000000000000ULL; | ||
918 | + FT0 = p.d; | ||
919 | +} | ||
920 | + | ||
921 | +void helper_cmpglt (void) | ||
922 | +{ | ||
923 | + union { | ||
924 | + double d; | ||
925 | + uint64_t u; | ||
926 | + } p; | ||
927 | + double ft0, ft1; | ||
928 | + | ||
929 | + if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) { | ||
930 | + /* XXX: TODO */ | ||
931 | + } | ||
932 | + ft0 = vaxg_to_ieee64(FT0); | ||
933 | + ft1 = vaxg_to_ieee64(FT1); | ||
934 | + p.u = 0; | ||
935 | + if (float64_lt(ft0, ft1, &FP_STATUS)) | ||
936 | + p.u = 0x4000000000000000ULL; | ||
937 | + FT0 = p.d; | ||
938 | +} | ||
939 | + | ||
940 | +void helper_cmpgle (void) | ||
941 | +{ | ||
942 | + union { | ||
943 | + double d; | ||
944 | + uint64_t u; | ||
945 | + } p; | ||
946 | + double ft0, ft1; | ||
947 | + | ||
948 | + if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) { | ||
949 | + /* XXX: TODO */ | ||
950 | + } | ||
951 | + ft0 = vaxg_to_ieee64(FT0); | ||
952 | + ft1 = vaxg_to_ieee64(FT1); | ||
953 | + p.u = 0; | ||
954 | + if (float64_le(ft0, ft1, &FP_STATUS)) | ||
955 | + p.u = 0x4000000000000000ULL; | ||
956 | + FT0 = p.d; | ||
957 | +} | ||
958 | + | ||
959 | +void helper_cvtqs (void) | ||
960 | +{ | ||
961 | + union { | ||
962 | + double d; | ||
963 | + uint64_t u; | ||
964 | + } p; | ||
965 | + | ||
966 | + p.d = FT0; | ||
967 | + FT0 = (float)p.u; | ||
968 | +} | ||
969 | + | ||
970 | +void helper_cvttq (void) | ||
971 | +{ | ||
972 | + union { | ||
973 | + double d; | ||
974 | + uint64_t u; | ||
975 | + } p; | ||
976 | + | ||
977 | + p.u = FT0; | ||
978 | + FT0 = p.d; | ||
979 | +} | ||
980 | + | ||
981 | +void helper_cvtqt (void) | ||
982 | +{ | ||
983 | + union { | ||
984 | + double d; | ||
985 | + uint64_t u; | ||
986 | + } p; | ||
987 | + | ||
988 | + p.d = FT0; | ||
989 | + FT0 = p.u; | ||
990 | +} | ||
991 | + | ||
992 | +void helper_cvtqf (void) | ||
993 | +{ | ||
994 | + union { | ||
995 | + double d; | ||
996 | + uint64_t u; | ||
997 | + } p; | ||
998 | + | ||
999 | + p.d = FT0; | ||
1000 | + FT0 = ieee32_to_vaxf(p.u); | ||
1001 | +} | ||
1002 | + | ||
1003 | +void helper_cvtgf (void) | ||
1004 | +{ | ||
1005 | + double ft0; | ||
1006 | + | ||
1007 | + ft0 = vaxg_to_ieee64(FT0); | ||
1008 | + FT0 = ieee32_to_vaxf(ft0); | ||
1009 | +} | ||
1010 | + | ||
1011 | +void helper_cvtgd (void) | ||
1012 | +{ | ||
1013 | + /* XXX: TODO */ | ||
1014 | +} | ||
1015 | + | ||
1016 | +void helper_cvtgq (void) | ||
1017 | +{ | ||
1018 | + union { | ||
1019 | + double d; | ||
1020 | + uint64_t u; | ||
1021 | + } p; | ||
1022 | + | ||
1023 | + p.u = vaxg_to_ieee64(FT0); | ||
1024 | + FT0 = p.d; | ||
1025 | +} | ||
1026 | + | ||
1027 | +void helper_cvtqg (void) | ||
1028 | +{ | ||
1029 | + union { | ||
1030 | + double d; | ||
1031 | + uint64_t u; | ||
1032 | + } p; | ||
1033 | + | ||
1034 | + p.d = FT0; | ||
1035 | + FT0 = ieee64_to_vaxg(p.u); | ||
1036 | +} | ||
1037 | + | ||
1038 | +void helper_cvtdg (void) | ||
1039 | +{ | ||
1040 | + /* XXX: TODO */ | ||
1041 | +} | ||
1042 | + | ||
1043 | +void helper_cvtlq (void) | ||
1044 | +{ | ||
1045 | + union { | ||
1046 | + double d; | ||
1047 | + uint64_t u; | ||
1048 | + } p, q; | ||
1049 | + | ||
1050 | + p.d = FT0; | ||
1051 | + q.u = (p.u >> 29) & 0x3FFFFFFF; | ||
1052 | + q.u |= (p.u >> 32); | ||
1053 | + q.u = (int64_t)((int32_t)q.u); | ||
1054 | + FT0 = q.d; | ||
1055 | +} | ||
1056 | + | ||
1057 | +static inline void __helper_cvtql (int s, int v) | ||
1058 | +{ | ||
1059 | + union { | ||
1060 | + double d; | ||
1061 | + uint64_t u; | ||
1062 | + } p, q; | ||
1063 | + | ||
1064 | + p.d = FT0; | ||
1065 | + q.u = ((uint64_t)(p.u & 0xC0000000)) << 32; | ||
1066 | + q.u |= ((uint64_t)(p.u & 0x7FFFFFFF)) << 29; | ||
1067 | + FT0 = q.d; | ||
1068 | + if (v && (int64_t)((int32_t)p.u) != (int64_t)p.u) { | ||
1069 | + helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); | ||
1070 | + } | ||
1071 | + if (s) { | ||
1072 | + /* TODO */ | ||
1073 | + } | ||
1074 | +} | ||
1075 | + | ||
1076 | +void helper_cvtql (void) | ||
1077 | +{ | ||
1078 | + __helper_cvtql(0, 0); | ||
1079 | +} | ||
1080 | + | ||
1081 | +void helper_cvtqlv (void) | ||
1082 | +{ | ||
1083 | + __helper_cvtql(0, 1); | ||
1084 | +} | ||
1085 | + | ||
1086 | +void helper_cvtqlsv (void) | ||
1087 | +{ | ||
1088 | + __helper_cvtql(1, 1); | ||
1089 | +} | ||
1090 | + | ||
1091 | +void helper_cmpfeq (void) | ||
1092 | +{ | ||
1093 | + if (float64_eq(FT0, FT1, &FP_STATUS)) | ||
1094 | + T0 = 1; | ||
1095 | + else | ||
1096 | + T0 = 0; | ||
1097 | +} | ||
1098 | + | ||
1099 | +void helper_cmpfne (void) | ||
1100 | +{ | ||
1101 | + if (float64_eq(FT0, FT1, &FP_STATUS)) | ||
1102 | + T0 = 0; | ||
1103 | + else | ||
1104 | + T0 = 1; | ||
1105 | +} | ||
1106 | + | ||
1107 | +void helper_cmpflt (void) | ||
1108 | +{ | ||
1109 | + if (float64_lt(FT0, FT1, &FP_STATUS)) | ||
1110 | + T0 = 1; | ||
1111 | + else | ||
1112 | + T0 = 0; | ||
1113 | +} | ||
1114 | + | ||
1115 | +void helper_cmpfle (void) | ||
1116 | +{ | ||
1117 | + if (float64_lt(FT0, FT1, &FP_STATUS)) | ||
1118 | + T0 = 1; | ||
1119 | + else | ||
1120 | + T0 = 0; | ||
1121 | +} | ||
1122 | + | ||
1123 | +void helper_cmpfgt (void) | ||
1124 | +{ | ||
1125 | + if (float64_le(FT0, FT1, &FP_STATUS)) | ||
1126 | + T0 = 0; | ||
1127 | + else | ||
1128 | + T0 = 1; | ||
1129 | +} | ||
1130 | + | ||
1131 | +void helper_cmpfge (void) | ||
1132 | +{ | ||
1133 | + if (float64_lt(FT0, FT1, &FP_STATUS)) | ||
1134 | + T0 = 0; | ||
1135 | + else | ||
1136 | + T0 = 1; | ||
1137 | +} | ||
1138 | + | ||
1139 | +#if !defined (CONFIG_USER_ONLY) | ||
1140 | +void helper_mfpr (int iprn) | ||
1141 | +{ | ||
1142 | + uint64_t val; | ||
1143 | + | ||
1144 | + if (cpu_alpha_mfpr(env, iprn, &val) == 0) | ||
1145 | + T0 = val; | ||
1146 | +} | ||
1147 | + | ||
1148 | +void helper_mtpr (int iprn) | ||
1149 | +{ | ||
1150 | + cpu_alpha_mtpr(env, iprn, T0, NULL); | ||
1151 | +} | ||
1152 | +#endif | ||
1153 | + | ||
1154 | +/*****************************************************************************/ | ||
1155 | +/* Softmmu support */ | ||
1156 | +#if !defined (CONFIG_USER_ONLY) | ||
1157 | + | ||
1158 | +#define GETPC() (__builtin_return_address(0)) | ||
1159 | + | ||
1160 | +/* XXX: the two following helpers are pure hacks. | ||
1161 | + * Hopefully, we emulate the PALcode, then we should never see | ||
1162 | + * HW_LD / HW_ST instructions. | ||
1163 | + */ | ||
1164 | +void helper_ld_phys_to_virt (void) | ||
1165 | +{ | ||
1166 | + uint64_t tlb_addr, physaddr; | ||
1167 | + int index, is_user; | ||
1168 | + void *retaddr; | ||
1169 | + | ||
1170 | + is_user = (env->ps >> 3) & 3; | ||
1171 | + index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | ||
1172 | + redo: | ||
1173 | + tlb_addr = env->tlb_table[is_user][index].addr_read; | ||
1174 | + if ((T0 & TARGET_PAGE_MASK) == | ||
1175 | + (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { | ||
1176 | + physaddr = T0 + env->tlb_table[is_user][index].addend; | ||
1177 | + } else { | ||
1178 | + /* the page is not in the TLB : fill it */ | ||
1179 | + retaddr = GETPC(); | ||
1180 | + tlb_fill(T0, 0, is_user, retaddr); | ||
1181 | + goto redo; | ||
1182 | + } | ||
1183 | + T0 = physaddr; | ||
1184 | +} | ||
1185 | + | ||
1186 | +void helper_st_phys_to_virt (void) | ||
1187 | +{ | ||
1188 | + uint64_t tlb_addr, physaddr; | ||
1189 | + int index, is_user; | ||
1190 | + void *retaddr; | ||
1191 | + | ||
1192 | + is_user = (env->ps >> 3) & 3; | ||
1193 | + index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | ||
1194 | + redo: | ||
1195 | + tlb_addr = env->tlb_table[is_user][index].addr_write; | ||
1196 | + if ((T0 & TARGET_PAGE_MASK) == | ||
1197 | + (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { | ||
1198 | + physaddr = T0 + env->tlb_table[is_user][index].addend; | ||
1199 | + } else { | ||
1200 | + /* the page is not in the TLB : fill it */ | ||
1201 | + retaddr = GETPC(); | ||
1202 | + tlb_fill(T0, 1, is_user, retaddr); | ||
1203 | + goto redo; | ||
1204 | + } | ||
1205 | + T0 = physaddr; | ||
1206 | +} | ||
1207 | + | ||
1208 | +#define MMUSUFFIX _mmu | ||
1209 | + | ||
1210 | +#define SHIFT 0 | ||
1211 | +#include "softmmu_template.h" | ||
1212 | + | ||
1213 | +#define SHIFT 1 | ||
1214 | +#include "softmmu_template.h" | ||
1215 | + | ||
1216 | +#define SHIFT 2 | ||
1217 | +#include "softmmu_template.h" | ||
1218 | + | ||
1219 | +#define SHIFT 3 | ||
1220 | +#include "softmmu_template.h" | ||
1221 | + | ||
1222 | +/* try to fill the TLB and return an exception if error. If retaddr is | ||
1223 | + NULL, it means that the function was called in C code (i.e. not | ||
1224 | + from generated code or from helper.c) */ | ||
1225 | +/* XXX: fix it to restore all registers */ | ||
1226 | +void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr) | ||
1227 | +{ | ||
1228 | + TranslationBlock *tb; | ||
1229 | + CPUState *saved_env; | ||
1230 | + target_phys_addr_t pc; | ||
1231 | + int ret; | ||
1232 | + | ||
1233 | + /* XXX: hack to restore env in all cases, even if not called from | ||
1234 | + generated code */ | ||
1235 | + saved_env = env; | ||
1236 | + env = cpu_single_env; | ||
1237 | + ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, is_user, 1); | ||
1238 | + if (!likely(ret == 0)) { | ||
1239 | + if (likely(retaddr)) { | ||
1240 | + /* now we have a real cpu fault */ | ||
1241 | + pc = (target_phys_addr_t)retaddr; | ||
1242 | + tb = tb_find_pc(pc); | ||
1243 | + if (likely(tb)) { | ||
1244 | + /* the PC is inside the translated code. It means that we have | ||
1245 | + a virtual CPU fault */ | ||
1246 | + cpu_restore_state(tb, env, pc, NULL); | ||
1247 | + } | ||
1248 | + } | ||
1249 | + /* Exception index and error code are already set */ | ||
1250 | + cpu_loop_exit(); | ||
1251 | + } | ||
1252 | + env = saved_env; | ||
1253 | +} | ||
1254 | + | ||
1255 | +#endif |
target-alpha/op_helper.h
0 → 100644
1 | +/* | ||
2 | + * Alpha emulation cpu micro-operations helpers definitions for qemu. | ||
3 | + * | ||
4 | + * Copyright (c) 2007 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 helper_call_pal (uint32_t palcode); | ||
22 | +void helper_excp (uint32_t excp, uint32_t error); | ||
23 | +void helper_amask (void); | ||
24 | +void helper_load_pcc (void); | ||
25 | +void helper_load_implver (void); | ||
26 | +void helper_load_fpcr (void); | ||
27 | +void helper_store_fpcr (void); | ||
28 | +void helper_load_irf (void); | ||
29 | +void helper_set_irf (void); | ||
30 | +void helper_clear_irf (void); | ||
31 | +void helper_addqv (void); | ||
32 | +void helper_addlv (void); | ||
33 | +void helper_subqv (void); | ||
34 | +void helper_sublv (void); | ||
35 | +void helper_mullv (void); | ||
36 | +void helper_mulqv (void); | ||
37 | +void helper_umulh (void); | ||
38 | +void helper_ctpop (void); | ||
39 | +void helper_ctlz (void); | ||
40 | +void helper_cttz (void); | ||
41 | +void helper_mskbl (void); | ||
42 | +void helper_extbl (void); | ||
43 | +void helper_insbl (void); | ||
44 | +void helper_mskwl (void); | ||
45 | +void helper_extwl (void); | ||
46 | +void helper_inswl (void); | ||
47 | +void helper_mskll (void); | ||
48 | +void helper_extll (void); | ||
49 | +void helper_insll (void); | ||
50 | +void helper_zap (void); | ||
51 | +void helper_zapnot (void); | ||
52 | +void helper_mskql (void); | ||
53 | +void helper_extql (void); | ||
54 | +void helper_insql (void); | ||
55 | +void helper_mskwh (void); | ||
56 | +void helper_inswh (void); | ||
57 | +void helper_extwh (void); | ||
58 | +void helper_msklh (void); | ||
59 | +void helper_inslh (void); | ||
60 | +void helper_extlh (void); | ||
61 | +void helper_mskqh (void); | ||
62 | +void helper_insqh (void); | ||
63 | +void helper_extqh (void); | ||
64 | +void helper_cmpbge (void); | ||
65 | +void helper_cmov_fir (int freg); | ||
66 | + | ||
67 | +double helper_ldff_raw (target_ulong ea); | ||
68 | +void helper_stff_raw (target_ulong ea, double op); | ||
69 | +double helper_ldfg_raw (target_ulong ea); | ||
70 | +void helper_stfg_raw (target_ulong ea, double op); | ||
71 | +#if !defined(CONFIG_USER_ONLY) | ||
72 | +double helper_ldff_user (target_ulong ea); | ||
73 | +void helper_stff_user (target_ulong ea, double op); | ||
74 | +double helper_ldff_kernel (target_ulong ea); | ||
75 | +void helper_stff_kernel (target_ulong ea, double op); | ||
76 | +double helper_ldff_data (target_ulong ea); | ||
77 | +void helper_stff_data (target_ulong ea, double op); | ||
78 | +double helper_ldfg_user (target_ulong ea); | ||
79 | +void helper_stfg_user (target_ulong ea, double op); | ||
80 | +double helper_ldfg_kernel (target_ulong ea); | ||
81 | +void helper_stfg_kernel (target_ulong ea, double op); | ||
82 | +double helper_ldfg_data (target_ulong ea); | ||
83 | +void helper_stfg_data (target_ulong ea, double op); | ||
84 | +#endif | ||
85 | + | ||
86 | +void helper_sqrts (void); | ||
87 | +void helper_cpys (void); | ||
88 | +void helper_cpysn (void); | ||
89 | +void helper_cpyse (void); | ||
90 | +void helper_itofs (void); | ||
91 | +void helper_ftois (void); | ||
92 | + | ||
93 | +void helper_sqrtt (void); | ||
94 | +void helper_cmptun (void); | ||
95 | +void helper_cmpteq (void); | ||
96 | +void helper_cmptle (void); | ||
97 | +void helper_cmptlt (void); | ||
98 | +void helper_itoft (void); | ||
99 | +void helper_ftoit (void); | ||
100 | + | ||
101 | +void helper_addf (void); | ||
102 | +void helper_subf (void); | ||
103 | +void helper_mulf (void); | ||
104 | +void helper_divf (void); | ||
105 | +void helper_sqrtf (void); | ||
106 | +void helper_cmpfeq (void); | ||
107 | +void helper_cmpfne (void); | ||
108 | +void helper_cmpflt (void); | ||
109 | +void helper_cmpfle (void); | ||
110 | +void helper_cmpfgt (void); | ||
111 | +void helper_cmpfge (void); | ||
112 | +void helper_itoff (void); | ||
113 | + | ||
114 | +void helper_addg (void); | ||
115 | +void helper_subg (void); | ||
116 | +void helper_mulg (void); | ||
117 | +void helper_divg (void); | ||
118 | +void helper_sqrtg (void); | ||
119 | +void helper_cmpgeq (void); | ||
120 | +void helper_cmpglt (void); | ||
121 | +void helper_cmpgle (void); | ||
122 | + | ||
123 | +void helper_cvtqs (void); | ||
124 | +void helper_cvttq (void); | ||
125 | +void helper_cvtqt (void); | ||
126 | +void helper_cvtqf (void); | ||
127 | +void helper_cvtgf (void); | ||
128 | +void helper_cvtgd (void); | ||
129 | +void helper_cvtgq (void); | ||
130 | +void helper_cvtqg (void); | ||
131 | +void helper_cvtdg (void); | ||
132 | +void helper_cvtlq (void); | ||
133 | +void helper_cvtql (void); | ||
134 | +void helper_cvtqlv (void); | ||
135 | +void helper_cvtqlsv (void); | ||
136 | + | ||
137 | +void helper_mfpr (int iprn); | ||
138 | +void helper_mtpr (int iprn); | ||
139 | +void helper_ld_phys_to_virt (void); | ||
140 | +void helper_st_phys_to_virt (void); | ||
141 | +void helper_tb_flush (void); |
target-alpha/op_helper_mem.h
0 → 100644
1 | +/* | ||
2 | + * Alpha emulation cpu micro-operations helpers for memory accesses for qemu. | ||
3 | + * | ||
4 | + * Copyright (c) 2007 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 | +/* XXX: TODO */ | ||
22 | +double glue(helper_ldff, MEMSUFFIX) (target_ulong ea) | ||
23 | +{ | ||
24 | + return 0; | ||
25 | +} | ||
26 | + | ||
27 | +void glue(helper_stff, MEMSUFFIX) (target_ulong ea, double op) | ||
28 | +{ | ||
29 | +} | ||
30 | + | ||
31 | +double glue(helper_ldfg, MEMSUFFIX) (target_ulong ea) | ||
32 | +{ | ||
33 | + return 0; | ||
34 | +} | ||
35 | + | ||
36 | +void glue(helper_stfg, MEMSUFFIX) (target_ulong ea, double op) | ||
37 | +{ | ||
38 | +} | ||
39 | + | ||
40 | +#undef MEMSUFFIX |
target-alpha/op_mem.h
0 → 100644
1 | +/* | ||
2 | + * Alpha emulation cpu micro-operations for memory accesses for qemu. | ||
3 | + * | ||
4 | + * Copyright (c) 2007 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 | +#define DEBUG_MEM_ACCESSES | ||
22 | +#if defined (DEBUG_MEM_ACCESSES) | ||
23 | +void helper_print_mem_EA (target_ulong EA); | ||
24 | +#define print_mem_EA(EA) do { helper_print_mem_EA(EA); } while (0) | ||
25 | +#else | ||
26 | +#define print_mem_EA(EA) do { } while (0) | ||
27 | +#endif | ||
28 | + | ||
29 | +static inline uint32_t glue(ldl_l, MEMSUFFIX) (target_ulong EA) | ||
30 | +{ | ||
31 | + env->lock = EA; | ||
32 | + | ||
33 | + return glue(ldl, MEMSUFFIX)(EA); | ||
34 | +} | ||
35 | + | ||
36 | +static inline uint32_t glue(ldq_l, MEMSUFFIX) (target_ulong EA) | ||
37 | +{ | ||
38 | + env->lock = EA; | ||
39 | + | ||
40 | + return glue(ldq, MEMSUFFIX)(EA); | ||
41 | +} | ||
42 | + | ||
43 | +static inline void glue(stl_c, MEMSUFFIX) (target_ulong EA, uint32_t data) | ||
44 | +{ | ||
45 | + if (EA == env->lock) { | ||
46 | + glue(stl, MEMSUFFIX)(EA, data); | ||
47 | + T0 = 0; | ||
48 | + } else { | ||
49 | + T0 = 1; | ||
50 | + } | ||
51 | + env->lock = -1; | ||
52 | +} | ||
53 | + | ||
54 | +static inline void glue(stq_c, MEMSUFFIX) (target_ulong EA, uint64_t data) | ||
55 | +{ | ||
56 | + if (EA == env->lock) { | ||
57 | + glue(stq, MEMSUFFIX)(EA, data); | ||
58 | + T0 = 0; | ||
59 | + } else { | ||
60 | + T0 = 1; | ||
61 | + } | ||
62 | + env->lock = -1; | ||
63 | +} | ||
64 | + | ||
65 | +#define ALPHA_LD_OP(name, op) \ | ||
66 | +void OPPROTO glue(glue(op_ld, name), MEMSUFFIX) (void) \ | ||
67 | +{ \ | ||
68 | + print_mem_EA(T0); \ | ||
69 | + T1 = glue(op, MEMSUFFIX)(T0); \ | ||
70 | + RETURN(); \ | ||
71 | +} | ||
72 | + | ||
73 | +#define ALPHA_ST_OP(name, op) \ | ||
74 | +void OPPROTO glue(glue(op_st, name), MEMSUFFIX) (void) \ | ||
75 | +{ \ | ||
76 | + print_mem_EA(T0); \ | ||
77 | + glue(op, MEMSUFFIX)(T0, T1); \ | ||
78 | + RETURN(); \ | ||
79 | +} | ||
80 | + | ||
81 | +ALPHA_LD_OP(bu, ldub); | ||
82 | +ALPHA_ST_OP(b, stb); | ||
83 | +ALPHA_LD_OP(wu, lduw); | ||
84 | +ALPHA_ST_OP(w, stw); | ||
85 | +ALPHA_LD_OP(l, ldl); | ||
86 | +ALPHA_ST_OP(l, stl); | ||
87 | +ALPHA_LD_OP(q, ldq); | ||
88 | +ALPHA_ST_OP(q, stq); | ||
89 | + | ||
90 | +ALPHA_LD_OP(q_u, ldq); | ||
91 | +ALPHA_ST_OP(q_u, stq); | ||
92 | + | ||
93 | +ALPHA_LD_OP(l_l, ldl_l); | ||
94 | +ALPHA_LD_OP(q_l, ldq_l); | ||
95 | +ALPHA_ST_OP(l_c, stl_c); | ||
96 | +ALPHA_ST_OP(q_c, stq_c); | ||
97 | + | ||
98 | +#define ALPHA_LDF_OP(name, op) \ | ||
99 | +void OPPROTO glue(glue(op_ld, name), MEMSUFFIX) (void) \ | ||
100 | +{ \ | ||
101 | + print_mem_EA(T0); \ | ||
102 | + FT1 = glue(op, MEMSUFFIX)(T0); \ | ||
103 | + RETURN(); \ | ||
104 | +} | ||
105 | + | ||
106 | +#define ALPHA_STF_OP(name, op) \ | ||
107 | +void OPPROTO glue(glue(op_st, name), MEMSUFFIX) (void) \ | ||
108 | +{ \ | ||
109 | + print_mem_EA(T0); \ | ||
110 | + glue(op, MEMSUFFIX)(T0, FT1); \ | ||
111 | + RETURN(); \ | ||
112 | +} | ||
113 | + | ||
114 | +ALPHA_LDF_OP(t, ldfq); | ||
115 | +ALPHA_STF_OP(t, stfq); | ||
116 | +ALPHA_LDF_OP(s, ldfl); | ||
117 | +ALPHA_STF_OP(s, stfl); | ||
118 | + | ||
119 | +/* VAX floating point */ | ||
120 | +ALPHA_LDF_OP(f, helper_ldff); | ||
121 | +ALPHA_STF_OP(f, helper_stff); | ||
122 | +ALPHA_LDF_OP(g, helper_ldfg); | ||
123 | +ALPHA_STF_OP(g, helper_stfg); | ||
124 | + | ||
125 | +#undef MEMSUFFIX |
target-alpha/op_template.h
0 → 100644
1 | +/* | ||
2 | + * Alpha emulation cpu micro-operations templates for qemu. | ||
3 | + * | ||
4 | + * Copyright (c) 2007 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 | +/* Optimized constant loads */ | ||
22 | +#if REG < 3 | ||
23 | +void OPPROTO glue(op_reset_T, REG) (void) | ||
24 | +{ | ||
25 | + glue(T, REG) = 0; | ||
26 | + RETURN(); | ||
27 | +} | ||
28 | + | ||
29 | +void OPPROTO glue(op_reset_FT, REG) (void) | ||
30 | +{ | ||
31 | + glue(FT, REG) = 0; | ||
32 | + RETURN(); | ||
33 | +} | ||
34 | + | ||
35 | +/* XXX: This can be great on most RISC machines */ | ||
36 | +#if !defined(__i386__) && !defined(__x86_64__) | ||
37 | +void OPPROTO glue(op_set_s16_T, REG) (void) | ||
38 | +{ | ||
39 | + glue(T, REG) = (int16_t)PARAM(1); | ||
40 | + RETURN(); | ||
41 | +} | ||
42 | + | ||
43 | +void OPPROTO glue(op_set_u16_T, REG) (void) | ||
44 | +{ | ||
45 | + glue(T, REG) = (uint16_t)PARAM(1); | ||
46 | + RETURN(); | ||
47 | +} | ||
48 | +#endif | ||
49 | + | ||
50 | +void OPPROTO glue(op_set_s32_T, REG) (void) | ||
51 | +{ | ||
52 | + glue(T, REG) = (int32_t)PARAM(1); | ||
53 | + RETURN(); | ||
54 | +} | ||
55 | + | ||
56 | +void OPPROTO glue(op_set_u32_T, REG) (void) | ||
57 | +{ | ||
58 | + glue(T, REG) = (uint32_t)PARAM(1); | ||
59 | + RETURN(); | ||
60 | +} | ||
61 | + | ||
62 | +#if 0 // Qemu does not know how to do this... | ||
63 | +void OPPROTO glue(op_set_64_T, REG) (void) | ||
64 | +{ | ||
65 | + glue(T, REG) = (int64_t)PARAM(1); | ||
66 | + RETURN(); | ||
67 | +} | ||
68 | +#else | ||
69 | +void OPPROTO glue(op_set_64_T, REG) (void) | ||
70 | +{ | ||
71 | + glue(T, REG) = ((int64_t)PARAM(1) << 32) | (int64_t)PARAM(2); | ||
72 | + RETURN(); | ||
73 | +} | ||
74 | +#endif | ||
75 | + | ||
76 | +#endif /* REG < 3 */ | ||
77 | + | ||
78 | +/* Fixed-point register moves */ | ||
79 | +#if REG < 31 | ||
80 | +void OPPROTO glue(op_load_T0_ir, REG) (void) | ||
81 | +{ | ||
82 | + T0 = env->ir[REG]; | ||
83 | + RETURN(); | ||
84 | +} | ||
85 | + | ||
86 | +void OPPROTO glue(op_load_T1_ir, REG) (void) | ||
87 | +{ | ||
88 | + T1 = env->ir[REG]; | ||
89 | + RETURN(); | ||
90 | +} | ||
91 | + | ||
92 | +void OPPROTO glue(op_load_T2_ir, REG) (void) | ||
93 | +{ | ||
94 | + T2 = env->ir[REG]; | ||
95 | + RETURN(); | ||
96 | +} | ||
97 | + | ||
98 | +void OPPROTO glue(op_store_T0_ir, REG) (void) | ||
99 | +{ | ||
100 | + env->ir[REG] = T0; | ||
101 | + RETURN(); | ||
102 | +} | ||
103 | + | ||
104 | +void OPPROTO glue(op_store_T1_ir, REG) (void) | ||
105 | +{ | ||
106 | + env->ir[REG] = T1; | ||
107 | + RETURN(); | ||
108 | +} | ||
109 | + | ||
110 | +void OPPROTO glue(op_store_T2_ir, REG) (void) | ||
111 | +{ | ||
112 | + env->ir[REG] = T2; | ||
113 | + RETURN(); | ||
114 | +} | ||
115 | + | ||
116 | +void OPPROTO glue(op_cmov_ir, REG) (void) | ||
117 | +{ | ||
118 | + if (T0) | ||
119 | + env->ir[REG] = T1; | ||
120 | + RETURN(); | ||
121 | +} | ||
122 | + | ||
123 | +/* floating point registers moves */ | ||
124 | +void OPPROTO glue(op_load_FT0_fir, REG) (void) | ||
125 | +{ | ||
126 | + FT0 = env->fir[REG]; | ||
127 | + RETURN(); | ||
128 | +} | ||
129 | + | ||
130 | +void OPPROTO glue(op_load_FT1_fir, REG) (void) | ||
131 | +{ | ||
132 | + FT1 = env->fir[REG]; | ||
133 | + RETURN(); | ||
134 | +} | ||
135 | + | ||
136 | +void OPPROTO glue(op_load_FT2_fir, REG) (void) | ||
137 | +{ | ||
138 | + FT2 = env->fir[REG]; | ||
139 | + RETURN(); | ||
140 | +} | ||
141 | + | ||
142 | +void OPPROTO glue(op_store_FT0_fir, REG) (void) | ||
143 | +{ | ||
144 | + env->fir[REG] = FT0; | ||
145 | + RETURN(); | ||
146 | +} | ||
147 | + | ||
148 | +void OPPROTO glue(op_store_FT1_fir, REG) (void) | ||
149 | +{ | ||
150 | + env->fir[REG] = FT1; | ||
151 | + RETURN(); | ||
152 | +} | ||
153 | + | ||
154 | +void OPPROTO glue(op_store_FT2_fir, REG) (void) | ||
155 | +{ | ||
156 | + env->fir[REG] = FT2; | ||
157 | + RETURN(); | ||
158 | +} | ||
159 | + | ||
160 | +void OPPROTO glue(op_cmov_fir, REG) (void) | ||
161 | +{ | ||
162 | + helper_cmov_fir(REG); | ||
163 | + RETURN(); | ||
164 | +} | ||
165 | +#endif /* REG < 31 */ | ||
166 | + | ||
167 | +#undef REG |