Revision 4c9649a9
b/target-alpha/cpu.h | ||
---|---|---|
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__) */ |
b/target-alpha/exec.h | ||
---|---|---|
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__) */ |
b/target-alpha/helper.c | ||
---|---|---|
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 |
} |
b/target-alpha/op.c | ||
---|---|---|
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; |
Also available in: Unified diff