1 |
cebix |
1.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 |