1 /**
2  * @ingroup   lib_emu68
3  * @file      emu68/macro68.h
4  * @brief     68K instruction emulation macro definitions.
5  * @author    Benjamin Gerard
6  * @date      1999/13/03
7  */
8 
9 /* Copyright (c) 1998-2015 Benjamin Gerard */
10 
11 #ifndef EMU68_MACRO68_H
12 #define EMU68_MACRO68_H
13 
14 /**
15  * @cond emu68macros
16  */
17 
18 /* Determine what instruction to inline.
19  *
20  * EMU68_INLINE_LVL
21  */
22 
23 #define EMU68_INLINE_MAX 1000           /**< Inlines all,                */
24 #define EMU68_INLINE_RAR 999            /**< Inlines almost all          */
25 #define EMU68_INLINE_MID 50             /**< Inlines balanced            */
26 #define EMU68_INLINE_NON 0              /**< Inlines not forced          */
27 #define EMU68_INLINE_YES 1              /**< Inline almost all */
28 
29 #ifndef EMU68_INLINE_LVL
30 # if defined(EMU68_INLINE_ALL)
31 #  define EMU68_INLINE_LVL EMU68_INLINE_MAX /* All would be inlined      */
32 # elif defined(EMU68_MONOLITIC)
33 #  define EMU68_INLINE_LVL EMU68_INLINE_MAX /* Monolitic; compiler rules */
34 # elif defined(DEBUG)
35 #  define EMU68_INLINE_LVL EMU68_INLINE_NON /* Debug; do not force       */
36 # elif defined(LIBSC68_NDEBUG)
37 #  define EMU68_INLINE_LVL EMU68_INLINE_YES /* Release; almost all       */
38 # else
39 #  define EMU68_INLINE_LVL EMU68_INLINE_MID /* Standard; balanced        */
40 # endif
41 #endif
42 
43 
44 /*                                           Instruction family   (cnt)
45                                              ------------------    ---  */
46 #define EMU68_INLINE_ARI 278              /* Arithmetic           (278) */
47 #define EMU68_INLINE_BCD EMU68_INLINE_RAR /* Binary coded decimal (  6) */
48 #define EMU68_INLINE_BIT 36               /* Bit Operation        ( 36) */
49 #define EMU68_INLINE_LOG 171              /* Logic                (171) */
50 #define EMU68_INLINE_SHT 56               /* Shifting             ( 56) */
51 #define EMU68_INLINE_TST 240              /* Test and move        (240) */
52 #define EMU68_INLINE_BSR EMU68_INLINE_YES /* Branch               (   ) */
53 
54 
55 #define ADDCYCLE(N) inl_addcycle68(emu68,N)
56 #define SETCYCLE(N) inl_setcycle68(emu68,N)
57 #define EXCEPTION(VECTOR,LEVEL)  inl_exception68(emu68,VECTOR,LEVEL)
58 
59 
60 /* ,---------------------------------------------------------------------.
61  * |                              BRANCH                                 |
62  * `---------------------------------------------------------------------'
63  */
64 
65 #if EMU68_INLINE_BSR < EMU68_INLINE_LVL
66 # define JSR(PC)      inl_jsr68(emu68,PC)
67 # define JMP(PC)      inl_jmp68(emu68,PC)
68 #else
69 # define JSR(PC)          jsr68(emu68,PC)
70 # define JMP(PC)          jmp68(emu68,PC)
71 #endif
72 
73 /* ,---------------------------------------------------------------------.
74  * |                          BIT MANIPULATION                           |
75  * `---------------------------------------------------------------------'
76  */
77 
78 #if EMU68_INLINE_LOG < EMU68_INLINE_LVL
79 # define _BTST(V,BIT)  inl_btst68(emu68, V, BIT)
80 # define _BCHG(V,BIT)  inl_bchg68(emu68, V, BIT)
81 # define _BCLR(V,BIT)  inl_bclr68(emu68, V, BIT)
82 # define _BSET(V,BIT)  inl_bset68(emu68, V, BIT)
83 #else
84 # define _BTST(V,BIT)      btst68(emu68, V, BIT)
85 # define _BCHG(V,BIT)      bchg68(emu68, V, BIT)
86 # define _BCLR(V,BIT)      bclr68(emu68, V, BIT)
87 # define _BSET(V,BIT)      bset68(emu68, V, BIT)
88 #endif
89 #define BTSTB(R, V, BIT)     _BTST(V, BIT & 7)
90 #define BTSTL(R, V, BIT)     _BTST(V, BIT & 31)
91 #define BCHGB(R, V, BIT) R = _BCHG(V, BIT & 7)
92 #define BCHGL(R, V, BIT) R = _BCHG(V, BIT & 31)
93 #define BSETB(R, V, BIT) R = _BSET(V, BIT & 7)
94 #define BSETL(R, V, BIT) R = _BSET(V, BIT & 31)
95 #define BCLRB(R, V, BIT) R = _BCLR(V, BIT & 7)
96 #define BCLRL(R, V, BIT) R = _BCLR(V, BIT & 31)
97 
98 /* ,---------------------------------------------------------------------.
99  * |                            MOVE AND TEST                            |
100  * `---------------------------------------------------------------------'
101  */
102 
103 #if EMU68_INLINE_TST < EMU68_INLINE_LVL
104 # define _TST(A)  inl_tst68(emu68, A)
105 # define _TAS(A)  inl_tas68(emu68, A)
106 #else
107 # define _TST(A)      tst68(emu68, A)
108 # define _TAS(A)      tas68(emu68, A)
109 #endif
110 #define TSTB(R, A)      _TST(A)
111 #define TSTW(R, A)      _TST(A)
112 #define TSTL(R, A)      _TST(A)
113 #define TASB(R, A)  R = _TAS(A)
114 
115 #define MOVEB(A)        _TST(A)
116 #define MOVEW(A)        _TST(A)
117 #define MOVEL(A)        _TST(A)
118 
119 #define EXTW(A)         _TST(A)
120 #define EXTL(A)         _TST(A)
121 
122 
123 /* ,---------------------------------------------------------------------.
124  * |                                LOGIC                                |
125  * `---------------------------------------------------------------------'
126  */
127 
128 #if EMU68_INLINE_LOG < EMU68_INLINE_LVL
129 # define _AND68(A,B) inl_and68(emu68, A, B)
130 # define _ORR68(A,B) inl_orr68(emu68, A, B)
131 # define _EOR68(A,B) inl_eor68(emu68, A, B)
132 # define _NOT68(A)   inl_not68(emu68, A)
133 #else
134 # define _AND68(A,B)     and68(emu68, A, B)
135 # define _ORR68(A,B)     orr68(emu68, A, B)
136 # define _EOR68(A,B)     eor68(emu68, A, B)
137 # define _NOT68(A)       not68(emu68, A)
138 #endif
139 
140 #define ANDB(S, A, B)  S = _AND68(A, B)
141 #define ANDW(S, A, B)  S = _AND68(A, B)
142 #define ANDL(S, A, B)  S = _AND68(A, B)
143 #define ORRB(S, A, B)  S = _ORR68(A, B)
144 #define ORRW(S, A, B)  S = _ORR68(A, B)
145 #define ORRL(S, A, B)  S = _ORR68(A, B)
146 #define EORB(S, A, B)  S = _EOR68(A, B)
147 #define EORW(S, A, B)  S = _EOR68(A, B)
148 #define EORL(S, A, B)  S = _EOR68(A, B)
149 #define NOTB(S, A)     S = _NOT68(A|~NRM_BYTE_MSK)
150 #define NOTW(S, A)     S = _NOT68(A|~NRM_WORD_MSK)
151 #define NOTL(S, A)     S = _NOT68(A|~NRM_LONG_MSK)
152 
153 
154 #define BYTE_SR_X ( (int68_t)(REG68.sr&SR_X) << (BYTE_FIX-SR_X_BIT) )
155 #define WORD_SR_X ( (int68_t)(REG68.sr&SR_X) << (WORD_FIX-SR_X_BIT) )
156 #define LONG_SR_X ( (int68_t)((REG68.sr>>SR_X_BIT) & 1) << LONG_FIX )
157 
158 
159 /* ,---------------------------------------------------------------------.
160  * |                              ARITHMETIC                             |
161  * `---------------------------------------------------------------------'
162  */
163 
164 #if EMU68_INLINE_ARI < EMU68_INLINE_LVL
165 # define _ADD68(A, B, X)  inl_add68(emu68, A, B, X)
166 # define _SUB68(A, B, X)  inl_sub68(emu68, A, B, X)
167 # define _CMP68(A, B)     inl_cmp68(emu68, A, B   )
168 # define _NEG68(B, X)     inl_neg68(emu68,    B, X)
169 # define _CLR68()         inl_clr68(emu68)
170 # define _MULS(A, B)      inl_muls68(emu68, A, B)
171 # define _MULU(A, B)      inl_mulu68(emu68, A, B)
172 # define _DIVS(A, B)      inl_divs68(emu68, A, B)
173 # define _DIVU(A, B)      inl_divu68(emu68, A, B)
174 #else
175 # define _ADD68(A, B, X)      add68(emu68, A, B, X)
176 # define _SUB68(A, B, X)      sub68(emu68, A, B, X)
177 # define _CMP68(A, B)         cmp68(emu68, A, B   )
178 # define _NEG68(B, X)         neg68(emu68,    B, X)
179 # define _CLR68()             clr68(emu68)
180 # define _MULS(A, B)          muls68(emu68, A, B)
181 # define _MULU(A, B)          mulu68(emu68, A, B)
182 # define _DIVS(A, B)          divs68(emu68, A, B)
183 # define _DIVU(A, B)          divu68(emu68, A, B)
184 #endif
185 #define  _ADDA(A, B)  (B) + (A)
186 #define  _SUBA(A, B)  (B) - (A)
187 #define  _CMPA(A, B)  _CMP68(A, B)
188 
189 #define ADDB(S, A, B)   S = _ADD68(A, B, 0)
190 #define ADDW(S, A, B)   S = _ADD68(A, B, 0)
191 #define ADDL(S, A, B)   S = _ADD68(A, B, 0)
192 #define SUBB(S, A, B)   S = _SUB68(A, B, 0)
193 #define SUBW(S, A, B)   S = _SUB68(A, B, 0)
194 #define SUBL(S, A, B)   S = _SUB68(A, B, 0)
195 #define CMPB(A, B)          _CMP68(A, B   )
196 #define CMPW(A, B)          _CMP68(A, B   )
197 #define CMPL(A, B)          _CMP68(A, B   )
198 #define NEGB(S, B)      S = _NEG68(   B, 0)
199 #define NEGW(S, B)      S = _NEG68(   B, 0)
200 #define NEGL(S, B)      S = _NEG68(   B, 0)
201 #define CLRB(S, B)      S = _CLR68()
202 #define CLRW(S, B)      S = _CLR68()
203 #define CLRL(S, B)      S = _CLR68()
204 
205 #define ADDXB(S, A, B)  S = _ADD68(A, B, BYTE_SR_X)
206 #define ADDXW(S, A, B)  S = _ADD68(A, B, WORD_SR_X)
207 #define ADDXL(S, A, B)  S = _ADD68(A, B, LONG_SR_X)
208 #define SUBXB(S, A, B)  S = _SUB68(A, B, BYTE_SR_X)
209 #define SUBXW(S, A, B)  S = _SUB68(A, B, WORD_SR_X)
210 #define SUBXL(S, A, B)  S = _SUB68(A, B, LONG_SR_X)
211 #define NEGXB(S, B)     S = _NEG68(   B, BYTE_SR_X)
212 #define NEGXW(S, B)     S = _NEG68(   B, WORD_SR_X)
213 #define NEGXL(S, B)     S = _NEG68(   B, LONG_SR_X)
214 
215 #define ADDAW(S, A, B)  S = _ADDA(A, B)
216 #define ADDAL(S, A, B)  S = _ADDA(A, B)
217 #define SUBAW(S, A, B)  S = _SUBA(A, B)
218 #define SUBAL(S, A, B)  S = _SUBA(A, B)
219 #define CMPAW(A, B)         _CMPA(A, B)
220 #define CMPAL(A, B)         _CMPA(A, B)
221 
222 #define MULSW(S, A, B)  S = _MULS(A, B)
223 #define MULUW(S, A, B)  S = _MULU(A, B)
224 #define DIVSW(S, A, B)  S = _DIVS(A, B)
225 #define DIVUW(S, A, B)  S = _DIVU(A, B)
226 
227 
228 /* ,---------------------------------------------------------------------.
229  * |                               SHIFTING                              |
230  * `---------------------------------------------------------------------'
231  */
232 
233 #if EMU68_INLINE_SHT < EMU68_INLINE_LVL
234 # define _LSL(D,CNT,SZ)   inl_lsl68(emu68,D,CNT,SZ)
235 # define _LSR(D,CNT,SZ)   inl_lsr68(emu68,D,CNT,SZ)
236 # define _ASL(D,CNT,SZ)   inl_asl68(emu68,D,CNT,SZ)
237 # define _ASR(D,CNT,SZ)   inl_asr68(emu68,D,CNT,SZ)
238 # define _ROL(D,CNT,SZ)   inl_rol68(emu68,D,CNT,SZ)
239 # define _ROR(D,CNT,SZ)   inl_ror68(emu68,D,CNT,SZ)
240 # define _ROXL(D,CNT,SZ)  inl_roxl68(emu68,D,CNT,SZ)
241 # define _ROXR(D,CNT,SZ)  inl_roxr68(emu68,D,CNT,SZ)
242 #else
243 # define _LSL(D,CNT,SZ)       lsl68(emu68,D,CNT,SZ)
244 # define _LSR(D,CNT,SZ)       lsr68(emu68,D,CNT,SZ)
245 # define _ASL(D,CNT,SZ)       asl68(emu68,D,CNT,SZ)
246 # define _ASR(D,CNT,SZ)       asr68(emu68,D,CNT,SZ)
247 # define _ROL(D,CNT,SZ)       rol68(emu68,D,CNT,SZ)
248 # define _ROR(D,CNT,SZ)       ror68(emu68,D,CNT,SZ)
249 # define _ROXL(D,CNT,SZ)      roxl68(emu68,D,CNT,SZ)
250 # define _ROXR(D,CNT,SZ)      roxr68(emu68,D,CNT,SZ)
251 #endif
252 
253 
254 #define LSRB(R, A, B)   R = _LSR(A, B,  8-1)
255 #define LSRW(R, A, B)   R = _LSR(A, B, 16-1)
256 #define LSRL(R, A, B)   R = _LSR(A, B, 32-1)
257 #define LSLB(R, A, B)   R = _LSL(A, B,  8-1)
258 #define LSLW(R, A, B)   R = _LSL(A, B, 16-1)
259 #define LSLL(R, A, B)   R = _LSL(A, B, 32-1)
260 
261 #define ASRB(R, A, B)   R = _ASR(A, B,  8-1)
262 #define ASRW(R, A, B)   R = _ASR(A, B, 16-1)
263 #define ASRL(R, A, B)   R = _ASR(A, B, 32-1)
264 #define ASLB(R, A, B)   R = _ASL(A, B,  8-1)
265 #define ASLW(R, A, B)   R = _ASL(A, B, 16-1)
266 #define ASLL(R, A, B)   R = _ASL(A, B, 32-1)
267 
268 #define RORB(R, A, B)   R = _ROR(A, B,  8-1)
269 #define RORW(R, A, B)   R = _ROR(A, B, 16-1)
270 #define RORL(R, A, B)   R = _ROR(A, B, 32-1)
271 #define ROLB(R, A, B)   R = _ROL(A, B,  8-1)
272 #define ROLW(R, A, B)   R = _ROL(A, B, 16-1)
273 #define ROLL(R, A, B)   R = _ROL(A, B, 32-1)
274 
275 #define ROXRB(R, A, B)  R = _ROXR(A ,B,  8-1)
276 #define ROXRW(R, A, B)  R = _ROXR(A ,B, 16-1)
277 #define ROXRL(R, A, B)  R = _ROXR(A ,B, 32-1)
278 #define ROXLB(R, A, B)  R = _ROXL(A ,B,  8-1)
279 #define ROXLW(R, A, B)  R = _ROXL(A ,B, 16-1)
280 #define ROXLL(R, A, B)  R = _ROXL(A ,B, 32-1)
281 
282 
283 
284 /* ,---------------------------------------------------------------------.
285  * |                         BINARY CODED DECIMAL                        |
286  * `---------------------------------------------------------------------'
287  */
288 
289 #if EMU68_INLINE_BCD < EMU68_INLINE_LVL
290 # define _ABCD(A,B)  inl_abcd68(emu68, A, B)
291 # define _SBCD(A,B)  inl_sbcd68(emu68, A, B)
292 # define _NBCD(A)    inl_nbcd68(emu68, A)
293 #else
294 # define _ABCD(A,B)      abcd68(emu68, A, B)
295 # define _SBCD(A,B)      sbcd68(emu68, A, B)
296 # define _NBCD(A)        nbcd68(emu68, A)
297 #endif
298 #define ABCDB(S, A, B)  S = _ABCD(A, B)
299 #define SBCDB(S, A, B)  S = _SBCD(A, B)
300 #define NBCDB(S, A)     S = _NBCD(A)
301 
302 
303 /* ,---------------------------------------------------------------------.
304  * |                  INSTRUCTIONS ALMOST NEVER INLINED                  |
305  * `---------------------------------------------------------------------'
306  */
307 
308 #if EMU68_INLINE_RAR < EMU68_INLINE_LVL
309 # define CHKW(A,B)        inl_chk68(emu68, A, B)
310 #else
311 # define CHKW(A,B)            chk68(emu68, A, B)
312 #endif
313 
314 /* ,---------------------------------------------------------------------.
315  * |                 INSTRUCTIONS ALMOST ALWAYS INLINED                  |
316  * `---------------------------------------------------------------------'
317  */
318 
319 #if EMU68_INLINE_ONE < EMU68_INLINE_LVL
320 # define SWAP(R)          inl_swap68(emu68,R)
321 # define RTS              inl_rts68(emu68)
322 # define RTE              inl_rte68(emu68)
323 # define RTR              inl_rtr68(emu68)
324 # define ILLEGAL          inl_illegal68(emu68)
325 # define TRAP(N)          inl_trap68(emu68,N)
326 # define TRAPV            inl_trapv68(emu68)
327 # define NOP              inl_nop68(emu68)
328 # define RESET            inl_reset68(emu68)
329 # define STOP             inl_stop68(emu68)
330 # define LINK(R)          inl_link68(emu68,R)
331 # define UNLK(R)          inl_unlk68(emu68,R)
332 # define LINEA            inl_linea68(emu68)
333 # define LINEF            inl_linef68(emu68)
334 # define EXG(RX,RY)       inl_exg68(emu68,RX,RY)
335 #else
336 # define SWAP(R)              swap68(emu68,R)
337 # define RTS                  rts68(emu68)
338 # define RTE                  rte68(emu68)
339 # define RTR                  rtr68(emu68)
340 # define ILLEGAL              illegal68(emu68)
341 # define TRAP(N)              trap68(emu68,N)
342 # define TRAPV                trapv68(emu68)
343 # define NOP                  nop68(emu68)
344 # define RESET                reset68(emu68)
345 # define STOP                 stop68(emu68)
346 # define LINK(R)              link68(emu68,R)
347 # define UNLK(R)              unlk68(emu68,R)
348 # define LINEA                linea68(emu68)
349 # define LINEF                linef68(emu68)
350 # define EXG(RX,RY)           exg68(emu68,RX,RY)
351 #endif
352 
353 /* ,---------------------------------------------------------------------.
354  * |                        CODE CONDITIONS TABLE                        |
355  * `---------------------------------------------------------------------'
356  */
357 
358 #define SCC(CC)      scc68[CC](emu68)
359 #define BCC(PC,CC)   bcc68[CC](emu68,PC)
360 #define DBCC(DN,CC)  dbcc68[CC](emu68,DN)
361 
362 /**
363  * @endcond
364  */
365 
366 #endif
367