145 |
|
#elif defined(__sparc__) && (defined(SPARC_V8_ASSEMBLY) || defined(SPARC_V9_ASSEMBLY)) |
146 |
|
|
147 |
|
struct flag_struct { |
148 |
< |
union { |
149 |
< |
unsigned short all; |
150 |
< |
unsigned char bytes[2]; |
151 |
< |
}; |
148 |
> |
unsigned char nzvc; |
149 |
> |
unsigned char x; |
150 |
|
}; |
151 |
|
|
152 |
< |
typedef unsigned short * flags_addr; |
155 |
< |
extern struct flag_struct regflags; |
156 |
< |
#define M68K_FLAGS_ADDR ((flags_addr)(®flags.all)) |
157 |
< |
#define M68K_FLAGS_NZVC regflags.bytes[1] |
158 |
< |
#define M68K_FLAGS_X regflags.bytes[0] |
152 |
> |
extern struct flag_struct regflags; |
153 |
|
|
154 |
< |
#if 0 |
155 |
< |
|
156 |
< |
#define SET_ZFLG(y) (M68K_FLAGS_NZVC = (M68K_FLAGS_NZVC & ~0x01) | ((y) & 1)) |
157 |
< |
#define SET_CFLG(y) (M68K_FLAGS_NZVC = (M68K_FLAGS_NZVC & ~0x02) | (((y) & 1) << 1)) |
158 |
< |
#define SET_XFLG(y) (M68K_FLAGS_X = ((y) & 1) << 1) |
159 |
< |
#define SET_VFLG(y) (M68K_FLAGS_NZVC = (M68K_FLAGS_NZVC & ~0x10) | (((y) & 1) << 4)) |
160 |
< |
#define SET_NFLG(y) (M68K_FLAGS_NZVC = (M68K_FLAGS_NZVC & ~0x80) | (((y) & 1) << 7)) |
161 |
< |
|
162 |
< |
#define GET_ZFLG (M68K_FLAGS_NZVC & 1) |
163 |
< |
#define GET_CFLG ((M68K_FLAGS_NZVC >> 1) & 1) |
164 |
< |
#define GET_XFLG ((M68K_FLAGS_X >> 1) & 1) |
171 |
< |
#define GET_VFLG ((M68K_FLAGS_NZVC >> 4) & 1) |
172 |
< |
#define GET_NFLG ((M68K_FLAGS_NZVC >> 7) & 1) |
173 |
< |
|
174 |
< |
#define CLEAR_CZNV (M68K_FLAGS_NZVC = 0) |
175 |
< |
#define COPY_CARRY (M68K_FLAGS_X = M68K_FLAGS_NZVC) |
176 |
< |
|
177 |
< |
#else |
178 |
< |
|
179 |
< |
#define M68K_FLAGS_ALL regflags.all |
180 |
< |
|
181 |
< |
#define SET_ZFLG(y) (M68K_FLAGS_ALL = (M68K_FLAGS_ALL & ~0x01) | ((y) & 1)) |
182 |
< |
#define SET_CFLG(y) (M68K_FLAGS_ALL = (M68K_FLAGS_ALL & ~0x02) | (((y) & 1) << 1)) |
183 |
< |
#define SET_XFLG(y) (M68K_FLAGS_ALL = (M68K_FLAGS_ALL & ~0x200)| (((y) & 1) << 9)) |
184 |
< |
#define SET_VFLG(y) (M68K_FLAGS_ALL = (M68K_FLAGS_ALL & ~0x10) | (((y) & 1) << 4)) |
185 |
< |
#define SET_NFLG(y) (M68K_FLAGS_ALL = (M68K_FLAGS_ALL & ~0x80) | (((y) & 1) << 7)) |
186 |
< |
|
187 |
< |
#define GET_ZFLG (M68K_FLAGS_ALL & 1) |
188 |
< |
#define GET_CFLG ((M68K_FLAGS_ALL >> 1) & 1) |
189 |
< |
#define GET_XFLG ((M68K_FLAGS_ALL >> 9) & 1) |
190 |
< |
#define GET_VFLG ((M68K_FLAGS_ALL >> 4) & 1) |
191 |
< |
#define GET_NFLG ((M68K_FLAGS_ALL >> 7) & 1) |
192 |
< |
|
193 |
< |
#define CLEAR_CZNV (M68K_FLAGS_NZVC = 0) |
194 |
< |
#define COPY_CARRY (M68K_FLAGS_X = M68K_FLAGS_NZVC) |
154 |
> |
#define SET_ZFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x04) | (((y) & 1) << 2)) |
155 |
> |
#define SET_CFLG(y) (regflags.nzvc = (regflags.nzvc & ~1) | ((y) & 1)) |
156 |
> |
#define SET_VFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x02) | (((y) & 1) << 1)) |
157 |
> |
#define SET_NFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x08) | (((y) & 1) << 3)) |
158 |
> |
#define SET_XFLG(y) (regflags.x = (y)) |
159 |
> |
|
160 |
> |
#define GET_ZFLG ((regflags.nzvc >> 2) & 1) |
161 |
> |
#define GET_CFLG (regflags.nzvc & 1) |
162 |
> |
#define GET_VFLG ((regflags.nzvc >> 1) & 1) |
163 |
> |
#define GET_NFLG ((regflags.nzvc >> 3) & 1) |
164 |
> |
#define GET_XFLG (regflags.x & 1) |
165 |
|
|
166 |
< |
#endif |
166 |
> |
#define CLEAR_CZNV (regflags.nzvc = 0) |
167 |
> |
#define COPY_CARRY (regflags.x = regflags.nzvc) |
168 |
|
|
169 |
|
static __inline__ int cctrue(int cc) |
170 |
|
{ |
171 |
< |
uae_u32 nzvc = M68K_FLAGS_NZVC; |
171 |
> |
uae_u32 nzvc = regflags.nzvc; |
172 |
|
switch(cc){ |
173 |
< |
case 0: return 1; /* T */ |
174 |
< |
case 1: return 0; /* F */ |
175 |
< |
case 2: return (nzvc & 0x03) == 0; /* !GET_CFLG && !GET_ZFLG; HI */ |
176 |
< |
case 3: return (nzvc & 0x03) != 0; /* GET_CFLG || GET_ZFLG; LS */ |
177 |
< |
case 4: return (nzvc & 0x02) == 0; /* !GET_CFLG; CC */ |
178 |
< |
case 5: return (nzvc & 0x02) != 0; /* GET_CFLG; CS */ |
179 |
< |
case 6: return (nzvc & 0x01) == 0; /* !GET_ZFLG; NE */ |
180 |
< |
case 7: return (nzvc & 0x01) != 0; /* GET_ZFLG; EQ */ |
181 |
< |
case 8: return (nzvc & 0x10) == 0; /* !GET_VFLG; VC */ |
182 |
< |
case 9: return (nzvc & 0x10) != 0; /* GET_VFLG; VS */ |
183 |
< |
case 10:return (nzvc & 0x80) == 0; /* !GET_NFLG; PL */ |
184 |
< |
case 11:return (nzvc & 0x80) != 0; /* GET_NFLG; MI */ |
185 |
< |
case 12:return (((nzvc << 3) ^ nzvc) & 0x80) == 0; /* GET_NFLG == GET_VFLG; GE */ |
186 |
< |
case 13:return (((nzvc << 3) ^ nzvc) & 0x80) != 0; /* GET_NFLG != GET_VFLG; LT */ |
173 |
> |
case 0: return 1; /* T */ |
174 |
> |
case 1: return 0; /* F */ |
175 |
> |
case 2: return (nzvc & 0x05) == 0; /* !GET_CFLG && !GET_ZFLG; HI */ |
176 |
> |
case 3: return (nzvc & 0x05) != 0; /* GET_CFLG || GET_ZFLG; LS */ |
177 |
> |
case 4: return (nzvc & 1) == 0; /* !GET_CFLG; CC */ |
178 |
> |
case 5: return (nzvc & 1) != 0; /* GET_CFLG; CS */ |
179 |
> |
case 6: return (nzvc & 0x04) == 0; /* !GET_ZFLG; NE */ |
180 |
> |
case 7: return (nzvc & 0x04) != 0; /* GET_ZFLG; EQ */ |
181 |
> |
case 8: return (nzvc & 0x02) == 0;/* !GET_VFLG; VC */ |
182 |
> |
case 9: return (nzvc & 0x02) != 0;/* GET_VFLG; VS */ |
183 |
> |
case 10:return (nzvc & 0x08) == 0; /* !GET_NFLG; PL */ |
184 |
> |
case 11:return (nzvc & 0x08) != 0; /* GET_NFLG; MI */ |
185 |
> |
case 12:return (((nzvc << 2) ^ nzvc) & 0x08) == 0; /* GET_NFLG == GET_VFLG; GE */ |
186 |
> |
case 13:return (((nzvc << 2) ^ nzvc) & 0x08) != 0;/* GET_NFLG != GET_VFLG; LT */ |
187 |
|
case 14: |
188 |
< |
/* N--V--CZ shifted by 3 leads to V--CZ--- */ |
189 |
< |
return (((nzvc << 3) ^ nzvc) & 0x88) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG); GT */ |
188 |
> |
nzvc &= 0x0e; |
189 |
> |
return (((nzvc << 2) ^ nzvc) & 0x0c) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG); GT */ |
190 |
|
case 15: |
191 |
< |
return (((nzvc << 3) ^ nzvc) & 0x88) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG); LE */ |
191 |
> |
nzvc &= 0x0e; |
192 |
> |
return (((nzvc << 2) ^ nzvc) & 0x0c) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG); LE */ |
193 |
|
} |
194 |
|
return 0; |
195 |
|
} |
196 |
|
|
197 |
|
#ifdef SPARC_V8_ASSEMBLY |
198 |
|
|
199 |
< |
static inline char *str_flags(void) |
228 |
< |
{ |
229 |
< |
static char str[8]; |
230 |
< |
sprintf(str, "%c%c%c%c%c", |
231 |
< |
GET_XFLG ? 'X' : '-', |
232 |
< |
GET_NFLG ? 'N' : '-', |
233 |
< |
GET_ZFLG ? 'Z' : '-', |
234 |
< |
GET_VFLG ? 'V' : '-', |
235 |
< |
GET_CFLG ? 'C' : '-' |
236 |
< |
); |
237 |
< |
return str; |
238 |
< |
} |
239 |
< |
|
240 |
< |
static inline uae_u32 sparc_v8_flag_add_8(flags_addr pflags, uae_u32 src, uae_u32 dst) |
199 |
> |
static inline uae_u32 sparc_v8_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst) |
200 |
|
{ |
201 |
|
uae_u32 value; |
202 |
|
__asm__ ("\n" |
203 |
|
" sll %2, 24, %%o0\n" |
204 |
|
" sll %3, 24, %%o1\n" |
205 |
|
" addcc %%o0, %%o1, %%o0\n" |
206 |
< |
" subx %%g0, %%g0, %%o1\n" |
207 |
< |
" srl %%o0, 24, %0 ! 8-bit result\n" |
208 |
< |
" and %%o1, 0x202, %%o1 ! X, C flags\n" |
209 |
< |
" and %0, 0x80, %%o0\n" |
210 |
< |
" or %%o1, %%o0, %%o1 ! N flag\n" |
211 |
< |
" subcc %%g0, %0, %%g0\n" |
212 |
< |
" subx %%o1, -1, %%o1 ! Z flag\n" |
206 |
> |
" addx %%g0, %%g0, %%o1 ! X,C flags\n" |
207 |
> |
" srl %%o0, 24, %0\n" |
208 |
> |
" stb %%o1, [%1 + 1]\n" |
209 |
> |
" bl,a .+8\n" |
210 |
> |
" or %%o1, 0x08, %%o1 ! N flag\n" |
211 |
> |
" bz,a .+8\n" |
212 |
> |
" or %%o1, 0x04, %%o1 ! Z flag\n" |
213 |
|
" bvs,a .+8\n" |
214 |
< |
" or %%o1, 0x10, %%o1 ! V flag\n" |
215 |
< |
" sth %%o1, [%1]\n" |
214 |
> |
" or %%o1, 0x02, %%o1 ! V flag\n" |
215 |
> |
" stb %%o1, [%1]\n" |
216 |
|
: "=&r" (value) |
217 |
< |
: "r" (pflags), "r" (dst), "r" (src), "0" (value) |
217 |
> |
: "r" (flags), "r" (dst), "r" (src) |
218 |
|
: "cc", "o0", "o1" |
219 |
|
); |
261 |
– |
|
262 |
– |
// printf("%d + %d = %d (flags = %s)\n", dst, src, value, str_flags()); |
220 |
|
return value; |
221 |
|
} |
222 |
|
|
223 |
< |
static inline uae_u32 sparc_v8_flag_add_16(flags_addr pflags, uae_u32 src, uae_u32 dst) |
223 |
> |
static inline uae_u32 sparc_v8_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst) |
224 |
|
{ |
225 |
|
uae_u32 value; |
226 |
|
__asm__ ("\n" |
227 |
|
" sll %2, 16, %%o0\n" |
228 |
|
" sll %3, 16, %%o1\n" |
229 |
|
" addcc %%o0, %%o1, %%o0\n" |
230 |
< |
" subx %%g0, %%g0, %%o1\n" |
231 |
< |
" srl %%o0, 16, %0 ! 16-bit result\n" |
232 |
< |
" and %%o1, 0x202, %%o1 ! X, C flags\n" |
233 |
< |
" sra %%o0, 24, %%o0\n" |
234 |
< |
" and %%o0, 0x80, %%o0\n" |
235 |
< |
" or %%o1, %%o0, %%o1 ! N flag\n" |
236 |
< |
" subcc %%g0, %0, %%g0\n" |
280 |
< |
" subx %%o1, -1, %%o1 ! Z flag\n" |
230 |
> |
" addx %%g0, %%g0, %%o1 ! X,C flags\n" |
231 |
> |
" srl %%o0, 16, %0\n" |
232 |
> |
" stb %%o1, [%1 + 1]\n" |
233 |
> |
" bl,a .+8\n" |
234 |
> |
" or %%o1, 0x08, %%o1 ! N flag\n" |
235 |
> |
" bz,a .+8\n" |
236 |
> |
" or %%o1, 0x04, %%o1 ! Z flag\n" |
237 |
|
" bvs,a .+8\n" |
238 |
< |
" or %%o1, 0x10, %%o1 ! V flag\n" |
239 |
< |
" sth %%o1, [%1]\n" |
238 |
> |
" or %%o1, 0x02, %%o1 ! V flag\n" |
239 |
> |
" stb %%o1, [%1]\n" |
240 |
|
: "=&r" (value) |
241 |
< |
: "r" (pflags), "r" (dst), "r" (src), "0" (value) |
241 |
> |
: "r" (flags), "r" (dst), "r" (src) |
242 |
|
: "cc", "o0", "o1" |
243 |
|
); |
244 |
|
return value; |
245 |
|
} |
246 |
|
|
247 |
< |
static inline uae_u32 sparc_v8_flag_add_32(flags_addr pflags, uae_u32 src, uae_u32 dst) |
247 |
> |
static inline uae_u32 sparc_v8_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst) |
248 |
|
{ |
249 |
|
uae_u32 value; |
250 |
|
__asm__ ("\n" |
251 |
|
" addcc %2, %3, %0\n" |
252 |
< |
" subx %%g0, %%g0, %%o0\n" |
253 |
< |
" sra %0, 24, %%o1\n" |
254 |
< |
" and %%o0, 0x202, %%o0 ! X, C flags\n" |
255 |
< |
" and %%o1, 0x80, %%o1\n" |
256 |
< |
" or %%o0, %%o1, %%o0 ! N flag\n" |
257 |
< |
" subcc %%g0, %0, %%g0\n" |
302 |
< |
" subx %%o0, -1, %%o0 ! Z flag\n" |
252 |
> |
" addx %%g0, %%g0, %%o0 ! X,C flags\n" |
253 |
> |
" stb %%o0, [%1 + 1]\n" |
254 |
> |
" bl,a .+8\n" |
255 |
> |
" or %%o0, 0x08, %%o0 ! N flag\n" |
256 |
> |
" bz,a .+8\n" |
257 |
> |
" or %%o0, 0x04, %%o0 ! Z flag\n" |
258 |
|
" bvs,a .+8\n" |
259 |
< |
" or %%o0, 0x10, %%o0 ! V flag\n" |
260 |
< |
" sth %%o0, [%1]\n" |
259 |
> |
" or %%o0, 0x02, %%o0 ! V flag\n" |
260 |
> |
" stb %%o0, [%1]\n" |
261 |
|
: "=&r" (value) |
262 |
< |
: "r" (pflags), "r" (dst), "r" (src), "0" (value) |
263 |
< |
: "cc", "o0", "o1" |
262 |
> |
: "r" (flags), "r" (dst), "r" (src) |
263 |
> |
: "cc", "o0" |
264 |
|
); |
265 |
|
return value; |
266 |
|
} |
394 |
|
); |
395 |
|
} |
396 |
|
|
397 |
+ |
static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst) |
398 |
+ |
{ |
399 |
+ |
uae_u32 value; |
400 |
+ |
__asm__ ("\n" |
401 |
+ |
" ldub [%1 + 1], %%o1 ! Get the X Flag\n" |
402 |
+ |
" subcc %%g0, %%o1, %%g0 ! Set the SPARC carry flag, if X set\n" |
403 |
+ |
" addxcc %2, %3, %0\n" |
404 |
+ |
: "=&r" (value) |
405 |
+ |
: "r" (flags), "r" (dst), "r" (src) |
406 |
+ |
: "cc", "o0", "o1" |
407 |
+ |
); |
408 |
+ |
return value; |
409 |
+ |
} |
410 |
+ |
|
411 |
+ |
#if 0 |
412 |
+ |
VERY SLOW... |
413 |
+ |
static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst) |
414 |
+ |
{ |
415 |
+ |
uae_u32 value; |
416 |
+ |
__asm__ ("\n" |
417 |
+ |
" sll %2, 24, %%o0\n" |
418 |
+ |
" sll %3, 24, %%o1\n" |
419 |
+ |
" addcc %%o0, %%o1, %%o0\n" |
420 |
+ |
" addx %%g0, %%g0, %%o1 ! X,C flags\n" |
421 |
+ |
" bvs,a .+8\n" |
422 |
+ |
" or %%o1, 0x02, %%o1 ! V flag\n" |
423 |
+ |
" ldub [%1 + 1], %%o2\n" |
424 |
+ |
" subcc %%g0, %%o2, %%g0\n" |
425 |
+ |
" addx %%g0, %%g0, %%o2\n" |
426 |
+ |
" sll %%o2, 24, %%o2\n" |
427 |
+ |
" addcc %%o0, %%o2, %%o0\n" |
428 |
+ |
" srl %%o0, 24, %0\n" |
429 |
+ |
" addx %%g0, %%g0, %%o2\n" |
430 |
+ |
" or %%o1, %%o2, %%o1 ! update X,C flags\n" |
431 |
+ |
" bl,a .+8\n" |
432 |
+ |
" or %%o1, 0x08, %%o1 ! N flag\n" |
433 |
+ |
" ldub [%1], %%o0 ! retreive the old NZVC flags (XXX)\n" |
434 |
+ |
" bvs,a .+8\n" |
435 |
+ |
" or %%o1, 0x02, %%o1 ! update V flag\n" |
436 |
+ |
" and %%o0, 0x04, %%o0 ! (XXX) but keep only Z flag\n" |
437 |
+ |
" and %%o1, 1, %%o2 ! keep C flag in %%o2\n" |
438 |
+ |
" bnz,a .+8\n" |
439 |
+ |
" or %%g0, %%g0, %%o0 ! Z flag cleared if non-zero result\n" |
440 |
+ |
" stb %%o2, [%1 + 1] ! store the X flag\n" |
441 |
+ |
" or %%o1, %%o0, %%o1\n" |
442 |
+ |
" stb %%o1, [%1]\n" |
443 |
+ |
: "=&r" (value) |
444 |
+ |
: "r" (flags), "r" (dst), "r" (src) |
445 |
+ |
: "cc", "o0", "o1", "o2" |
446 |
+ |
); |
447 |
+ |
return value; |
448 |
+ |
} |
449 |
+ |
#endif |
450 |
+ |
|
451 |
+ |
static inline uae_u32 sparc_v8_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst) |
452 |
+ |
{ |
453 |
+ |
uae_u32 value; |
454 |
+ |
__asm__ ("\n" |
455 |
+ |
" ldub [%1 + 1], %%o0 ! Get the X Flag\n" |
456 |
+ |
" subcc %%g0, %%o0, %%g0 ! Set the SPARC carry flag, if X set\n" |
457 |
+ |
" addxcc %2, %3, %0\n" |
458 |
+ |
" ldub [%1], %%o0 ! retreive the old NZVC flags\n" |
459 |
+ |
" and %%o0, 0x04, %%o0 ! but keep only Z flag\n" |
460 |
+ |
" addx %%o0, %%g0, %%o0 ! X,C flags\n" |
461 |
+ |
" bl,a .+8\n" |
462 |
+ |
" or %%o0, 0x08, %%o0 ! N flag\n" |
463 |
+ |
" bvs,a .+8\n" |
464 |
+ |
" or %%o0, 0x02, %%o0 ! V flag\n" |
465 |
+ |
" bnz,a .+8\n" |
466 |
+ |
" and %%o0, 0x0B, %%o0 ! Z flag cleared if result is non-zero\n" |
467 |
+ |
" stb %%o0, [%1]\n" |
468 |
+ |
" stb %%o0, [%1 + 1]\n" |
469 |
+ |
: "=&r" (value) |
470 |
+ |
: "r" (flags), "r" (dst), "r" (src) |
471 |
+ |
: "cc", "o0" |
472 |
+ |
); |
473 |
+ |
return value; |
474 |
+ |
} |
475 |
+ |
|
476 |
|
#endif /* SPARC_V8_ASSEMBLY */ |
477 |
|
|
478 |
|
#ifdef SPARC_V9_ASSEMBLY |