1 |
/* |
2 |
* UAE - The Un*x Amiga Emulator |
3 |
* |
4 |
* MC68000 emulation - machine dependent bits |
5 |
* |
6 |
* Copyright 1996 Bernd Schmidt |
7 |
*/ |
8 |
|
9 |
#ifdef __i386__ |
10 |
|
11 |
struct flag_struct { |
12 |
unsigned int cznv; |
13 |
unsigned int x; |
14 |
}; |
15 |
|
16 |
#define SET_ZFLG(y) (regflags.cznv = (regflags.cznv & ~0x40) | (((y) & 1) << 6)) |
17 |
#define SET_CFLG(y) (regflags.cznv = (regflags.cznv & ~1) | ((y) & 1)) |
18 |
#define SET_VFLG(y) (regflags.cznv = (regflags.cznv & ~0x800) | (((y) & 1) << 11)) |
19 |
#define SET_NFLG(y) (regflags.cznv = (regflags.cznv & ~0x80) | (((y) & 1) << 7)) |
20 |
#define SET_XFLG(y) (regflags.x = (y)) |
21 |
|
22 |
#define GET_ZFLG ((regflags.cznv >> 6) & 1) |
23 |
#define GET_CFLG (regflags.cznv & 1) |
24 |
#define GET_VFLG ((regflags.cznv >> 11) & 1) |
25 |
#define GET_NFLG ((regflags.cznv >> 7) & 1) |
26 |
#define GET_XFLG (regflags.x & 1) |
27 |
|
28 |
#define CLEAR_CZNV (regflags.cznv = 0) |
29 |
#define COPY_CARRY (regflags.x = regflags.cznv) |
30 |
|
31 |
extern struct flag_struct regflags __asm__ ("regflags"); |
32 |
|
33 |
static __inline__ int cctrue(int cc) |
34 |
{ |
35 |
uae_u32 cznv = regflags.cznv; |
36 |
switch(cc){ |
37 |
case 0: return 1; /* T */ |
38 |
case 1: return 0; /* F */ |
39 |
case 2: return (cznv & 0x41) == 0; /* !GET_CFLG && !GET_ZFLG; HI */ |
40 |
case 3: return (cznv & 0x41) != 0; /* GET_CFLG || GET_ZFLG; LS */ |
41 |
case 4: return (cznv & 1) == 0; /* !GET_CFLG; CC */ |
42 |
case 5: return (cznv & 1) != 0; /* GET_CFLG; CS */ |
43 |
case 6: return (cznv & 0x40) == 0; /* !GET_ZFLG; NE */ |
44 |
case 7: return (cznv & 0x40) != 0; /* GET_ZFLG; EQ */ |
45 |
case 8: return (cznv & 0x800) == 0;/* !GET_VFLG; VC */ |
46 |
case 9: return (cznv & 0x800) != 0;/* GET_VFLG; VS */ |
47 |
case 10:return (cznv & 0x80) == 0; /* !GET_NFLG; PL */ |
48 |
case 11:return (cznv & 0x80) != 0; /* GET_NFLG; MI */ |
49 |
case 12:return (((cznv << 4) ^ cznv) & 0x800) == 0; /* GET_NFLG == GET_VFLG; GE */ |
50 |
case 13:return (((cznv << 4) ^ cznv) & 0x800) != 0;/* GET_NFLG != GET_VFLG; LT */ |
51 |
case 14: |
52 |
cznv &= 0x8c0; |
53 |
return (((cznv << 4) ^ cznv) & 0x840) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG); GT */ |
54 |
case 15: |
55 |
cznv &= 0x8c0; |
56 |
return (((cznv << 4) ^ cznv) & 0x840) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG); LE */ |
57 |
} |
58 |
return 0; |
59 |
} |
60 |
|
61 |
#define x86_flag_testl(v) \ |
62 |
__asm__ __volatile__ ("testl %1,%1\n\t" \ |
63 |
"pushfl\n\t" \ |
64 |
"popl %0\n\t" \ |
65 |
: "=r" (regflags.cznv) : "r" (v) : "cc") |
66 |
|
67 |
#define x86_flag_testw(v) \ |
68 |
__asm__ __volatile__ ("testw %w1,%w1\n\t" \ |
69 |
"pushfl\n\t" \ |
70 |
"popl %0\n\t" \ |
71 |
: "=r" (regflags.cznv) : "r" (v) : "cc") |
72 |
|
73 |
#define x86_flag_testb(v) \ |
74 |
__asm__ __volatile__ ("testb %b1,%b1\n\t" \ |
75 |
"pushfl\n\t" \ |
76 |
"popl %0\n\t" \ |
77 |
: "=r" (regflags.cznv) : "q" (v) : "cc") |
78 |
|
79 |
#define x86_flag_addl(v, s, d) do { \ |
80 |
__asm__ __volatile__ ("addl %k2,%k1\n\t" \ |
81 |
"pushfl\n\t" \ |
82 |
"popl %0\n\t" \ |
83 |
: "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \ |
84 |
COPY_CARRY; \ |
85 |
} while (0) |
86 |
|
87 |
#define x86_flag_addw(v, s, d) do { \ |
88 |
__asm__ __volatile__ ("addw %w2,%w1\n\t" \ |
89 |
"pushfl\n\t" \ |
90 |
"popl %0\n\t" \ |
91 |
: "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \ |
92 |
COPY_CARRY; \ |
93 |
} while (0) |
94 |
|
95 |
#define x86_flag_addb(v, s, d) do { \ |
96 |
__asm__ __volatile__ ("addb %b2,%b1\n\t" \ |
97 |
"pushfl\n\t" \ |
98 |
"popl %0\n\t" \ |
99 |
: "=r" (regflags.cznv), "=q" (v) : "qmi" (s), "1" (d) : "cc"); \ |
100 |
COPY_CARRY; \ |
101 |
} while (0) |
102 |
|
103 |
#define x86_flag_subl(v, s, d) do { \ |
104 |
__asm__ __volatile__ ("subl %k2,%k1\n\t" \ |
105 |
"pushfl\n\t" \ |
106 |
"popl %0\n\t" \ |
107 |
: "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \ |
108 |
COPY_CARRY; \ |
109 |
} while (0) |
110 |
|
111 |
#define x86_flag_subw(v, s, d) do { \ |
112 |
__asm__ __volatile__ ("subw %w2,%w1\n\t" \ |
113 |
"pushfl\n\t" \ |
114 |
"popl %0\n\t" \ |
115 |
: "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \ |
116 |
COPY_CARRY; \ |
117 |
} while (0) |
118 |
|
119 |
#define x86_flag_subb(v, s, d) do { \ |
120 |
__asm__ __volatile__ ("subb %b2,%b1\n\t" \ |
121 |
"pushfl\n\t" \ |
122 |
"popl %0\n\t" \ |
123 |
: "=r" (regflags.cznv), "=q" (v) : "qmi" (s), "1" (d) : "cc"); \ |
124 |
COPY_CARRY; \ |
125 |
} while (0) |
126 |
|
127 |
#define x86_flag_cmpl(s, d) \ |
128 |
__asm__ __volatile__ ("cmpl %k1,%k2\n\t" \ |
129 |
"pushfl\n\t" \ |
130 |
"popl %0\n\t" \ |
131 |
: "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc") |
132 |
|
133 |
#define x86_flag_cmpw(s, d) \ |
134 |
__asm__ __volatile__ ("cmpw %w1,%w2\n\t" \ |
135 |
"pushfl\n\t" \ |
136 |
"popl %0\n\t" \ |
137 |
: "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc") |
138 |
|
139 |
#define x86_flag_cmpb(s, d) \ |
140 |
__asm__ __volatile__ ("cmpb %b1,%b2\n\t" \ |
141 |
"pushfl\n\t" \ |
142 |
"popl %0\n\t" \ |
143 |
: "=r" (regflags.cznv) : "qmi" (s), "q" (d) : "cc") |
144 |
|
145 |
#else |
146 |
|
147 |
struct flag_struct { |
148 |
unsigned int c; |
149 |
unsigned int z; |
150 |
unsigned int n; |
151 |
unsigned int v; |
152 |
unsigned int x; |
153 |
}; |
154 |
|
155 |
extern struct flag_struct regflags; |
156 |
|
157 |
#define ZFLG (regflags.z) |
158 |
#define NFLG (regflags.n) |
159 |
#define CFLG (regflags.c) |
160 |
#define VFLG (regflags.v) |
161 |
#define XFLG (regflags.x) |
162 |
|
163 |
static __inline__ int cctrue(const int cc) |
164 |
{ |
165 |
switch(cc){ |
166 |
case 0: return 1; /* T */ |
167 |
case 1: return 0; /* F */ |
168 |
case 2: return !CFLG && !ZFLG; /* HI */ |
169 |
case 3: return CFLG || ZFLG; /* LS */ |
170 |
case 4: return !CFLG; /* CC */ |
171 |
case 5: return CFLG; /* CS */ |
172 |
case 6: return !ZFLG; /* NE */ |
173 |
case 7: return ZFLG; /* EQ */ |
174 |
case 8: return !VFLG; /* VC */ |
175 |
case 9: return VFLG; /* VS */ |
176 |
case 10:return !NFLG; /* PL */ |
177 |
case 11:return NFLG; /* MI */ |
178 |
case 12:return NFLG == VFLG; /* GE */ |
179 |
case 13:return NFLG != VFLG; /* LT */ |
180 |
case 14:return !ZFLG && (NFLG == VFLG); /* GT */ |
181 |
case 15:return ZFLG || (NFLG != VFLG); /* LE */ |
182 |
} |
183 |
return 0; |
184 |
} |
185 |
|
186 |
#endif |