changes for gnu disassembler and further porting
[cacao.git] / i386 / ngen.h
1 /* i386/ngen.h *****************************************************************
2
3     Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
4
5     See file COPYRIGHT for information on usage and disclaimer of warranties
6
7     Contains the machine dependent code generator definitions and macros for an
8     Alpha processor.
9
10     Authors: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
11              Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
12
13     Last Change: 1998/11/04
14
15 *******************************************************************************/
16
17 #ifndef _NGEN_H
18 #define _NGEN_H
19
20 /* see also file calling.doc for explanation of calling conventions           */
21
22 /* preallocated registers *****************************************************/
23
24 /* integer registers */
25   
26 #define REG_RESULT      I386_EAX /* to deliver method results                 */
27 #define REG_RESULT2     I386_EDX /* to deliver long method results            */
28
29 #define REG_RA          26   /* return address                                */
30 #define REG_PV          27   /* procedure vector, must be provided by caller  */
31 #define REG_METHODPTR   28   /* pointer to the place from where the procedure */
32                              /* vector has been fetched                       */
33 #define REG_ITMP1       I386_EAX /* temporary register                        */
34 #define REG_ITMP2       I386_EDX /* temporary register and method pointer     */
35 #define REG_ITMP3       I386_ECX /* temporary register                        */
36
37 #define REG_ITMP1_XPTR  I386_EAX /* exception pointer = temporary register 1  */
38 #define REG_ITMP2_XPC   I386_EDX /* exception pc = temporary register 2       */
39
40 #define REG_SP          I386_ESP /* stack pointer                             */
41 #define REG_ZERO        31   /* always zero                                   */
42
43 /* floating point registers */
44
45 #define REG_FRESULT     0    /* to deliver floating point method results      */
46 #define REG_FTMP1       0    /* temporary floating point register             */
47 #define REG_FTMP2       1    /* temporary floating point register             */
48 #define REG_FTMP3       2    /* temporary floating point register             */
49
50 #define REG_IFTMP       28   /* temporary integer and floating point register */
51
52 /* register descripton - array ************************************************/
53
54 /* #define REG_RES   0         reserved register for OS or code generator     */
55 /* #define REG_RET   1         return value register                          */
56 /* #define REG_EXC   2         exception value register (only old jit)        */
57 /* #define REG_SAV   3         (callee) saved register                        */
58 /* #define REG_TMP   4         scratch temporary register (caller saved)      */
59 /* #define REG_ARG   5         argument register (caller saved)               */
60
61 /* #define REG_END   -1        last entry in tables */
62
63 int nregdescint[] = {
64     REG_RET, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
65     REG_END };
66
67 #define INT_SAV_CNT      0   /* number of int callee saved registers          */
68 #define INT_ARG_CNT      0   /* number of int argument registers              */
69
70 /* for use of reserved registers, see comment above */
71
72 int nregdescfloat[] = {
73     REG_ARG, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
74     REG_END };
75
76 #define FLT_SAV_CNT      0   /* number of flt callee saved registers          */
77 #define FLT_ARG_CNT      0   /* number of flt argument registers              */
78
79 /* for use of reserved registers, see comment above */
80
81
82 /* parameter allocation mode */
83
84 int nreg_parammode = PARAMMODE_NUMBERED;  
85
86    /* parameter-registers will be allocated by assigning the
87       1. parameter:   int/float-reg 16
88       2. parameter:   int/float-reg 17  
89       3. parameter:   int/float-reg 18 ....
90    */
91
92
93 /* stackframe-infos ***********************************************************/
94
95 int parentargs_base; /* offset in stackframe for the parameter from the caller*/
96
97 /* -> see file 'calling.doc' */
98
99
100 /* macros to create code ******************************************************/
101
102 #define M_OP3(op,fu,a,b,c,const) \
103 do { \
104         printf("M_OP3: %d\n", __LINE__); \
105         *((s4 *) (((s4) mcodeptr)++)) = 0x0F; \
106         *((s4 *) (((s4) mcodeptr)++)) = 0x04; \
107 } while (0)
108
109 #define M_FOP3(op,fu,a,b,c)     M_OP3(0,0,0,0,0,0)
110 #define M_BRA(op,a,disp)        M_OP3(0,0,0,0,0,0)
111 #define M_MEM(op,a,b,disp)      M_OP3(0,0,0,0,0,0)
112
113
114
115 /*
116  * immediate data union
117  */
118 typedef union {
119     s4 i;
120     s8 l;
121     float f;
122     double d;
123     void *a;
124     u1 b[8];
125 } i386_imm_buf;
126
127
128 /*
129  * x86 register numbers
130  */
131 typedef enum {
132     I386_EAX = 0,
133     I386_ECX = 1,
134     I386_EDX = 2,
135     I386_EBX = 3,
136     I386_ESP = 4,
137     I386_EBP = 5,
138     I386_ESI = 6,
139     I386_EDI = 7,
140     I386_NREG
141 } I386_Reg_No;
142
143 /*
144  * opcodes for alu instructions
145  */
146 typedef enum {
147     I386_ADD = 0,
148     I386_OR  = 1,
149     I386_ADC = 2,
150     I386_SBB = 3,
151     I386_AND = 4,
152     I386_SUB = 5,
153     I386_XOR = 6,
154     I386_CMP = 7,
155     I386_NALU
156 } I386_ALU_Opcode;
157
158 typedef enum {
159     I386_ROL = 0,
160     I386_ROR = 1,
161     I386_RCL = 2,
162     I386_RCR = 3,
163     I386_SHL = 4,
164     I386_SHR = 5,
165     I386_SAR = 7,
166     I386_NSHIFT = 8
167 } I386_Shift_Opcode;
168
169 typedef enum {
170     I386_CC_O = 0,
171     I386_CC_NO = 1,
172     I386_CC_B = 2, I386_CC_C = 2, I386_CC_NAE = 2,
173     I386_CC_BE = 6, I386_CC_NA = 6,
174     I386_CC_AE = 3, I386_CC_NB = 3, I386_CC_NC = 3,
175     I386_CC_E = 4, I386_CC_Z = 4,
176     I386_CC_NE = 5, I386_CC_NZ = 5,
177     I386_CC_A = 7, I386_CC_NBE = 7,
178     I386_CC_S = 8, I386_CC_LZ = 8,
179     I386_CC_NS = 9, I386_CC_GEZ = 9,
180     I386_CC_P = 0x0a, I386_CC_PE = 0x0a,
181     I386_CC_NP = 0x0b, I386_CC_PO = 0x0b,
182     I386_CC_L = 0x0c, I386_CC_NGE = 0x0c,
183     I386_CC_GE = 0x0d, I386_CC_NL = 0x0d,
184     I386_CC_LE = 0x0e, I386_CC_NG = 0x0e,
185     I386_CC_G = 0x0f, I386_CC_NLE = 0x0f,
186     I386_NCC
187 } I386_CC;
188
189 static const unsigned char i386_jcc_map[] = {
190     0x70, /* o  */
191     0x71, /* no */
192     0x72, /* b, lt  */
193     0x73, /* ae */
194     0x74, /* e  */
195     0x75, /* ne */
196     0x76, /* be */
197     0x77, /* a  */
198     0x78, /* s  */
199     0x79, /* ns */
200     0x7a, /* p  */
201     0x7b, /* np */
202     0x7c, /* l  */
203     0x7d, /* ge */
204     0x7e, /* le */
205     0x7f  /* g  */
206 };
207
208
209
210 /*
211  * modrm and stuff
212  */
213 #define i386_address_byte(mod, reg, rm) \
214     do { \
215         *(((u1 *) mcodeptr)++) = ((((mod) & 0x03) << 6) | (((reg) & 0x07) << 3) | (((rm) & 0x07))); \
216     } while (0)
217
218
219 #define i386_emit_reg(reg,rm) \
220     do { \
221         i386_address_byte(3,(reg),(rm)); \
222     } while (0)
223
224
225 #define i386_is_imm8(imm)       (((int)(imm) >= -128 && (int)(imm) <= 127))
226
227
228 #define i386_emit_imm8(imm) \
229     do { \
230         *(((u1 *) mcodeptr)++) = (u1) ((imm) & 0xff); \
231     } while (0)
232
233
234 #define i386_emit_imm32(imm) \
235     do { \
236         i386_imm_buf imb; \
237         imb.i = (int) (imm); \
238         *(((u1 *) mcodeptr)++) = imb.b[0]; \
239         *(((u1 *) mcodeptr)++) = imb.b[1]; \
240         *(((u1 *) mcodeptr)++) = imb.b[2]; \
241         *(((u1 *) mcodeptr)++) = imb.b[3]; \
242     } while (0)
243
244
245 #define i386_emit_float32(imm) \
246     do { \
247         i386_imm_buf imb; \
248         imb.f = (float) (imm); \
249         *(((u1 *) mcodeptr)++) = imb.b[0]; \
250         *(((u1 *) mcodeptr)++) = imb.b[1]; \
251         *(((u1 *) mcodeptr)++) = imb.b[2]; \
252         *(((u1 *) mcodeptr)++) = imb.b[3]; \
253     } while (0)
254
255
256 #define i386_emit_mem(r,disp) \
257     do { \
258         i386_address_byte(0,(r),5); \
259         i386_emit_imm32((disp)); \
260     } while (0)
261
262
263 #define i386_emit_membase(basereg,disp,dreg) \
264     do { \
265         if ((basereg) == I386_ESP) { \
266             if ((disp) == 0) { \
267                 i386_address_byte(0, (dreg), I386_ESP); \
268                 i386_address_byte(0, I386_ESP, I386_ESP); \
269             } else if (i386_is_imm8((disp))) { \
270                 i386_address_byte(1, (dreg), I386_ESP); \
271                 i386_address_byte(0, I386_ESP, I386_ESP); \
272                 i386_emit_imm8((disp)); \
273             } else { \
274                 i386_address_byte(2, (dreg), I386_ESP); \
275                 i386_address_byte(0, I386_ESP, I386_ESP); \
276                 i386_emit_imm32((disp)); \
277             } \
278             break; \
279         } \
280         \
281         if ((disp) == 0 && (basereg) != I386_EBP) { \
282             i386_address_byte(0, (dreg), (basereg)); \
283             break; \
284         } \
285         \
286         if (i386_is_imm8((disp))) { \
287             i386_address_byte(1, (dreg), (basereg)); \
288             i386_emit_imm8((disp)); \
289         } else { \
290             i386_address_byte(2, (dreg), (basereg)); \
291             i386_emit_imm32((disp)); \
292         } \
293     } while (0)
294
295
296 #define i386_emit_memindex(reg,disp,basereg,indexreg,scale) \
297     do { \
298         if ((basereg) == -1) { \
299             i386_address_byte(0, (reg), 4); \
300             i386_address_byte((scale), (indexreg), 5); \
301             i386_emit_imm32((disp)); \
302         \
303         } else if ((disp) == 0 && (basereg) != I386_EBP) { \
304             i386_address_byte(0, (reg), 4); \
305             i386_address_byte((scale), (indexreg), (basereg)); \
306         \
307         } else if (i386_is_imm8((disp))) { \
308             i386_address_byte(1, (reg), 4); \
309             i386_address_byte((scale), (indexreg), (basereg)); \
310             i386_emit_imm8 ((disp)); \
311         \
312         } else { \
313             i386_address_byte(2, (reg), 4); \
314             i386_address_byte((scale), (indexreg), 5); \
315             i386_emit_imm32((disp)); \
316         }    \
317      } while (0)
318
319
320
321 /*
322  * mov ops
323  */
324 #define i386_mov_reg_reg(reg,dreg) \
325     do { \
326         *(((u1 *) mcodeptr)++) = (u1) 0x89; \
327         i386_emit_reg((reg),(dreg)); \
328     } while (0)
329
330
331 #define i386_mov_imm_reg(imm,reg) \
332     do { \
333         *(((u1 *) mcodeptr)++) = (u1) 0xb8 + ((reg) & 0x07); \
334         i386_emit_imm32((imm)); \
335     } while (0)
336
337
338 #define i386_mov_float_reg(imm,reg) \
339     do { \
340         *(((u1 *) mcodeptr)++) = (u1) 0xb8 + ((reg) & 0x07); \
341         i386_emit_float32((imm)); \
342     } while (0)
343
344
345 #define i386_mov_reg_mem(reg,mem) \
346     do { \
347         *(((u1 *) mcodeptr)++) = (u1) 0x89; \
348         i386_emit_mem((reg),(mem)); \
349     } while (0)
350
351
352 #define i386_mov_mem_reg(mem,reg) \
353     do { \
354         *(((u1 *) mcodeptr)++) = (u1) 0x8b; \
355         i386_emit_mem((reg),(mem)); \
356     } while (0)
357
358
359 #define i386_mov_membase_reg(basereg,disp,reg) \
360     do { \
361         *(((u1 *) mcodeptr)++) = (u1) 0x8b; \
362         i386_emit_membase((basereg),(disp),(reg)); \
363     } while (0)
364
365
366 #define i386_movw_membase_reg(basereg,disp,reg) \
367     do { \
368         *(((u1 *) mcodeptr)++) = (u1) 0x66; \
369         i386_mov_membase_reg((basereg),(disp),(reg)); \
370     } while (0)
371
372
373 #define i386_mov_reg_membase(reg,basereg,disp) \
374     do { \
375         *(((u1 *) mcodeptr)++) = (u1) 0x89; \
376         i386_emit_membase((basereg),(disp),(reg)); \
377     } while (0)
378
379
380 #define i386_movw_reg_membase(reg,basereg,disp) \
381     do { \
382         *(((u1 *) mcodeptr)++) = (u1) 0x66; \
383         i386_mov_reg_membase((reg),(basereg),(disp)); \
384     } while (0)
385
386
387 #define i386_mov_memindex_reg(disp,basereg,indexreg,scale,reg) \
388     do { \
389         *(((u1 *) mcodeptr)++) = (u1) 0x8b; \
390         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
391     } while (0)
392
393
394 #define i386_mov_reg_memindex(reg,disp,basereg,indexreg,scale) \
395     do { \
396         *(((u1 *) mcodeptr)++) = (u1) 0x89; \
397         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
398     } while (0)
399
400
401 #define i386_mov_imm_membase(imm,basereg,disp) \
402     do { \
403         *(((u1 *) mcodeptr)++) = (u1) 0xc7; \
404         i386_emit_membase((basereg),(disp),0); \
405         i386_emit_imm32((imm)); \
406     } while (0)
407
408
409 #define i386_mov_float_membase(imm,basereg,disp) \
410     do { \
411         *(((u1 *) mcodeptr)++) = (u1) 0xc7; \
412         i386_emit_membase((basereg),(disp),0); \
413         i386_emit_float32((imm)); \
414     } while (0)
415
416
417 #define i386_movsbl_reg_reg(reg,dreg) \
418     do { \
419         *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
420         *(((u1 *) mcodeptr)++) = (u1) 0xbe; \
421         i386_emit_reg((reg),(dreg)); \
422     } while (0)
423
424
425
426 /*
427  * alu operations
428  */
429 #define i386_alu_reg_reg(opc,reg,dreg) \
430     do { \
431         *(((u1 *) mcodeptr)++) = (((u1) (opc)) << 3) + 1; \
432         i386_emit_reg((reg),(dreg)); \
433     } while (0)
434
435
436 #define i386_alu_reg_membase(opc,reg,basereg,disp) \
437     do { \
438         *(((u1 *) mcodeptr)++) = (((u1) (opc)) << 3) + 1; \
439         i386_emit_membase((basereg),(disp),(reg)); \
440     } while (0)
441
442
443 #define i386_alu_membase_reg(opc,basereg,disp,reg) \
444     do { \
445         *(((u1 *) mcodeptr)++) = (((u1) (opc)) << 3) + 3; \
446         i386_emit_membase((basereg),(disp),(reg)); \
447     } while (0)
448
449
450 #define i386_alu_imm_reg(opc,imm,dreg) \
451     do { \
452         if (i386_is_imm8(imm)) { \
453             *(((u1 *) mcodeptr)++) = (u1) 0x83; \
454             i386_emit_reg((opc),(dreg)); \
455             i386_emit_imm8((imm)); \
456         } else { \
457             *(((u1 *) mcodeptr)++) = (u1) 0x81; \
458             i386_emit_reg((opc),(dreg)); \
459             i386_emit_imm32((imm)); \
460         } \
461     } while (0)
462
463
464 #define i386_alu_imm_membase(opc,imm,basereg,disp) \
465     do { \
466         if (i386_is_imm8(imm)) { \
467             *(((u1 *) mcodeptr)++) = (u1) 0x83; \
468             i386_emit_membase((basereg),(disp),(opc)); \
469             i386_emit_imm8((imm)); \
470         } else { \
471             *(((u1 *) mcodeptr)++) = (u1) 0x81; \
472             i386_emit_membase((basereg),(disp),(opc)); \
473             i386_emit_imm32((imm)); \
474         } \
475     } while (0)
476
477
478 #define i386_test_reg_reg(reg,dreg) \
479     do { \
480         *(((u1 *) mcodeptr)++) = (u1) 0x85; \
481         i386_emit_reg((reg),(dreg)); \
482     } while (0)
483
484
485 #define i386_test_imm_reg(imm,reg) \
486     do { \
487         *(((u1 *) mcodeptr)++) = (u1) 0xf7; \
488         i386_emit_reg(0,(reg)); \
489         i386_emit_imm32((imm)); \
490     } while (0)
491
492
493 #define i386_shld_reg_reg(reg,dreg) \
494     do { \
495         *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
496         *(((u1 *) mcodeptr)++) = (u1) 0xa5; \
497         i386_emit_reg((reg),(dreg)); \
498     } while (0)
499
500
501 #define i386_shld_reg_membase(reg,basereg,disp) \
502     do { \
503         *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
504         *(((u1 *) mcodeptr)++) = (u1) 0xa5; \
505         i386_emit_membase((basereg),(disp),(reg)); \
506     } while (0)
507
508
509 #define i386_shrd_reg_reg(reg,dreg) \
510     do { \
511         *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
512         *(((u1 *) mcodeptr)++) = (u1) 0xad; \
513         i386_emit_reg((reg),(dreg)); \
514     } while (0)
515
516
517 #define i386_shrd_reg_membase(reg,basereg,disp) \
518     do { \
519         *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
520         *(((u1 *) mcodeptr)++) = (u1) 0xad; \
521         i386_emit_membase((basereg),(disp),(reg)); \
522     } while (0)
523
524
525
526 /*
527  * inc, dec operations
528  */
529 #define i386_inc_reg(reg) \
530     do { \
531         *(((u1 *) mcodeptr)++) = (u1) 0x40 + ((reg) & 0x07); \
532     } while (0)
533
534
535 #define i386_inc_membase(basereg,disp) \
536     do { \
537         *(((u1 *) mcodeptr)++) = (u1) 0xff; \
538         i386_emit_membase((basereg),(disp),0); \
539     } while (0)
540
541
542 #define i386_dec_reg(reg) \
543     do { \
544         *(((u1 *) mcodeptr)++) = (u1) 0x48 + ((reg) & 0x07); \
545     } while (0)
546
547         
548 #define i386_dec_membase(basereg,disp) \
549     do { \
550         *(((u1 *) mcodeptr)++) = (u1) 0xff; \
551         i386_emit_membase((basereg),(disp),1); \
552     } while (0)
553
554
555
556
557 #define i386_cltd() \
558     do { \
559         *(((u1 *) mcodeptr)++) = (u1) 0x99; \
560     } while (0)
561
562
563
564 #define i386_imul_reg_reg(reg,dreg) \
565     do { \
566         *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
567         *(((u1 *) mcodeptr)++) = (u1) 0xaf; \
568         i386_emit_reg((dreg),(reg)); \
569     } while (0)
570
571
572 #define i386_imul_membase_reg(basereg,disp,dreg) \
573     do { \
574         *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
575         *(((u1 *) mcodeptr)++) = (u1) 0xaf; \
576         i386_emit_membase((basereg),(disp),(dreg)); \
577     } while (0)
578
579
580 #define i386_imul_imm_reg(imm,dreg) \
581     do { \
582         if (i386_is_imm8((imm))) { \
583             *(((u1 *) mcodeptr)++) = (u1) 0x6b; \
584             i386_emit_reg(0,(dreg)); \
585             i386_emit_imm8((imm)); \
586         } else { \
587             *(((u1 *) mcodeptr)++) = (u1) 0x69; \
588             i386_emit_reg(0,(dreg)); \
589             i386_emit_imm32((imm)); \
590         } \
591     } while (0)
592
593
594 #define i386_imul_imm_reg_reg(imm,reg,dreg) \
595     do { \
596         if (i386_is_imm8((imm))) { \
597             *(((u1 *) mcodeptr)++) = (u1) 0x6b; \
598             i386_emit_reg((dreg),(reg)); \
599             i386_emit_imm8((imm)); \
600         } else { \
601             *(((u1 *) mcodeptr)++) = (u1) 0x69; \
602             i386_emit_reg((dreg),(reg)); \
603             i386_emit_imm32((imm)); \
604         } \
605     } while (0)
606
607
608 #define i386_imul_imm_membase_reg(imm,basereg,disp,dreg) \
609     do { \
610         if (i386_is_imm8((imm))) { \
611             *(((u1 *) mcodeptr)++) = (u1) 0x6b; \
612             i386_emit_membase((basereg),(disp),(dreg)); \
613             i386_emit_imm8((imm)); \
614         } else { \
615             *(((u1 *) mcodeptr)++) = (u1) 0x69; \
616             i386_emit_membase((basereg),(disp),(dreg)); \
617             i386_emit_imm32((imm)); \
618         } \
619     } while (0)
620
621
622 #define i386_mul_reg(reg) \
623     do { \
624         *(((u1 *) mcodeptr)++) = (u1) 0xf7; \
625         i386_emit_reg(4,(reg)); \
626     } while (0)
627
628
629 #define i386_mul_membase(basereg,disp) \
630     do { \
631         *(((u1 *) mcodeptr)++) = (u1) 0xf7; \
632         i386_emit_membase((basereg),(disp),4); \
633     } while (0)
634
635
636 #define i386_idiv_reg(reg) \
637     do { \
638         *(((u1 *) mcodeptr)++) = (u1) 0xf7; \
639         i386_emit_reg(7,(reg)); \
640     } while (0)
641
642
643 #define i386_idiv_membase(basereg,disp) \
644     do { \
645         *(((u1 *) mcodeptr)++) = (u1) 0xf7; \
646         i386_emit_membase((basereg),(disp),7); \
647     } while (0)
648
649
650
651 #define i386_ret() \
652     do { \
653         *(((u1 *) mcodeptr)++) = (u1) 0xc3; \
654     } while (0)
655
656
657 #define i386_leave() \
658     do { \
659         *(((u1 *) mcodeptr)++) = (u1) 0xc9; \
660     } while (0)
661
662
663
664 /*
665  * shift ops
666  */
667 #define i386_shift_reg(opc,reg) \
668     do { \
669         *(((u1 *) mcodeptr)++) = (u1) 0xd3; \
670         i386_emit_reg((opc),(reg)); \
671     } while (0)
672
673
674 #define i386_shift_membase(opc,basereg,disp) \
675     do { \
676         *(((u1 *) mcodeptr)++) = (u1) 0xd3; \
677         i386_emit_membase((basereg),(disp),(opc)); \
678     } while (0)
679
680
681 #define i386_shift_imm_reg(opc,imm,dreg) \
682     do { \
683         if ((imm) == 1) { \
684             *(((u1 *) mcodeptr)++) = (u1) 0xd1; \
685             i386_emit_reg((opc),(dreg)); \
686         } else { \
687             *(((u1 *) mcodeptr)++) = (u1) 0xc1; \
688             i386_emit_reg((opc),(dreg)); \
689             i386_emit_imm8((imm)); \
690         } \
691     } while (0)
692
693
694 #define i386_shift_imm_membase(opc,imm,basereg,disp) \
695     do { \
696         if ((imm) == 1) { \
697             *(((u1 *) mcodeptr)++) = (u1) 0xd1; \
698             i386_emit_membase((basereg),(disp),(opc)); \
699         } else { \
700             *(((u1 *) mcodeptr)++) = (u1) 0xc1; \
701             i386_emit_membase((basereg),(disp),(opc)); \
702             i386_emit_imm8((imm)); \
703         } \
704     } while (0)
705
706
707
708 /*
709  * jump operations
710  */
711 #define i386_jmp(imm) \
712     do { \
713         *(((u1 *) mcodeptr)++) = (u1) 0xe9; \
714         i386_emit_imm32((imm)); \
715     } while (0)
716
717
718 #define i386_jmp_reg(reg) \
719     do { \
720         *(((u1 *) mcodeptr)++) = (u1) 0xff; \
721         i386_emit_reg(4,(reg)); \
722     } while (0)
723
724
725 #define i386_jcc(opc,imm) \
726     do { \
727         *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
728         *(((u1 *) mcodeptr)++) = (u1) (i386_jcc_map[(opc)] + 0x10); \
729         i386_emit_imm32((imm)); \
730     } while (0)
731
732
733
734
735 #define i386_neg_reg(reg) \
736     do { \
737         *(((u1 *) mcodeptr)++) = (u1) 0xf7; \
738         i386_emit_reg(3,(reg)); \
739     } while (0)
740
741
742 #define i386_neg_mem(mem) \
743     do { \
744         *(((u1 *) mcodeptr)++) = (u1) 0xf7; \
745         i386_emit_mem(3,(mem)); \
746     } while (0)
747
748
749 #define i386_neg_membase(basereg,disp) \
750     do { \
751         *(((u1 *) mcodeptr)++) = (u1) 0xf7; \
752         i386_emit_membase((basereg),(disp),3); \
753     } while (0)
754
755
756
757 #define i386_push_reg(reg) \
758     do { \
759         *(((u1 *) mcodeptr)++) = (u1) 0x50 + (0x07 & (reg)); \
760     } while (0)
761
762
763 #define i386_push_membase(basereg,disp) \
764     do { \
765         *(((u1 *) mcodeptr)++) = (u1) 0xff; \
766         i386_emit_membase((basereg),(disp),6); \
767     } while (0)
768
769
770 #define i386_push_imm(imm) \
771     do { \
772         *(((u1 *) mcodeptr)++) = (u1) 0x68; \
773         i386_emit_imm32((imm)); \
774     } while (0)
775
776
777 #define i386_pop_reg(reg) \
778     do { \
779         *(((u1 *) mcodeptr)++) = (u1) 0x58 + (0x07 & (reg)); \
780     } while (0)
781
782
783 #define i386_nop() \
784     do { \
785         *(((u1 *) mcodeptr)++) = (u1) 0x90; \
786     } while (0)
787
788
789
790 /*
791  * call instructions
792  */
793 #define i386_call_reg(reg) \
794     do { \
795         *(((u1 *) mcodeptr)++) = (u1) 0xff; \
796         i386_emit_reg(2,(reg)); \
797     } while (0)
798
799
800
801 /*
802  * floating point instructions
803  */
804 #define i386_flds_mem(mem) \
805     do { \
806         *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
807         i386_emit_mem(0,(mem)); \
808     } while (0)
809
810
811 #define i386_fldl_mem(mem) \
812     do { \
813         *(((u1 *) mcodeptr)++) = (u1) 0xdd; \
814         i386_emit_mem(0,(mem)); \
815     } while (0)
816
817
818 #define i386_flds_membase(basereg,disp) \
819     do { \
820         *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
821         i386_emit_membase((basereg),(disp),0); \
822     } while (0)
823
824
825 #define i386_fldl_membase(basereg,disp) \
826     do { \
827         *(((u1 *) mcodeptr)++) = (u1) 0xdd; \
828         i386_emit_membase((basereg),(disp),0); \
829     } while (0)
830
831
832 #define i386_fildl_mem(mem) \
833     do { \
834         *(((u1 *) mcodeptr)++) = (u1) 0xdb; \
835         i386_emit_mem(0,(mem)); \
836     } while (0)
837
838
839 #define i386_fildl_membase(basereg,disp) \
840     do { \
841         *(((u1 *) mcodeptr)++) = (u1) 0xdb; \
842         i386_emit_membase((basereg),(disp),0); \
843     } while (0)
844
845
846 #define i386_fildll_membase(basereg,disp) \
847     do { \
848         *(((u1 *) mcodeptr)++) = (u1) 0xdf; \
849         i386_emit_membase((basereg),(disp),5); \
850     } while (0)
851
852
853
854
855 #define i386_fstps_mem(mem) \
856     do { \
857         *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
858         i386_emit_mem(3,(mem)); \
859     } while (0)
860
861
862 #define i386_fstpl_mem(mem) \
863     do { \
864         *(((u1 *) mcodeptr)++) = (u1) 0xdd; \
865         i386_emit_mem(3,(mem)); \
866     } while (0)
867
868
869 #define i386_fstps_membase(basereg,disp) \
870     do { \
871         *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
872         i386_emit_membase((basereg),(disp),3); \
873     } while (0)
874
875
876 #define i386_fstpl_membase(basereg,disp) \
877     do { \
878         *(((u1 *) mcodeptr)++) = (u1) 0xdd; \
879         i386_emit_membase((basereg),(disp),3); \
880     } while (0)
881
882
883
884
885 #define i386_fistpl_mem(mem) \
886     do { \
887         *(((u1 *) mcodeptr)++) = (u1) 0xdb; \
888         i386_emit_mem(3,(mem)); \
889     } while (0)
890
891
892 #define i386_fistpll_mem(mem) \
893     do { \
894         *(((u1 *) mcodeptr)++) = (u1) 0xdf; \
895         i386_emit_mem(7,(mem)); \
896     } while (0)
897
898
899 #define i386_fistpl_membase(basereg,disp) \
900     do { \
901         *(((u1 *) mcodeptr)++) = (u1) 0xdb; \
902         i386_emit_membase((basereg),(disp),3); \
903     } while (0)
904
905
906 #define i386_fistpll_membase(basereg,disp) \
907     do { \
908         *(((u1 *) mcodeptr)++) = (u1) 0xdf; \
909         i386_emit_membase((basereg),(disp),7); \
910     } while (0)
911
912
913
914
915 #define i386_fchs() \
916     do { \
917         *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
918         *(((u1 *) mcodeptr)++) = (u1) 0xe0; \
919     } while (0)
920
921
922 #define i386_faddp() \
923     do { \
924         *(((u1 *) mcodeptr)++) = (u1) 0xde; \
925         *(((u1 *) mcodeptr)++) = (u1) 0xc1; \
926     } while (0)
927
928
929 #define i386_fadds_membase(basereg,disp) \
930     do { \
931         *(((u1 *) mcodeptr)++) = (u1) 0xd8; \
932         i386_emit_membase((basereg),(disp),0); \
933     } while (0)
934
935
936 #define i386_faddl_membase(basereg,disp) \
937     do { \
938         *(((u1 *) mcodeptr)++) = (u1) 0xdc; \
939         i386_emit_membase((basereg),(disp),0); \
940     } while (0)
941
942
943 #define i386_fsubp() \
944     do { \
945         *(((u1 *) mcodeptr)++) = (u1) 0xde; \
946         *(((u1 *) mcodeptr)++) = (u1) 0xe9; \
947     } while (0)
948
949
950 #define i386_fsubs_membase(basereg,disp) \
951     do { \
952         *(((u1 *) mcodeptr)++) = (u1) 0xd8; \
953         i386_emit_membase((basereg),(disp),4); \
954     } while (0)
955
956
957 #define i386_fmulp() \
958     do { \
959         *(((u1 *) mcodeptr)++) = (u1) 0xde; \
960         *(((u1 *) mcodeptr)++) = (u1) 0xc9; \
961     } while (0)
962
963
964 #define i386_fdivp() \
965     do { \
966         *(((u1 *) mcodeptr)++) = (u1) 0xde; \
967         *(((u1 *) mcodeptr)++) = (u1) 0xf9; \
968     } while (0)
969
970
971 #define i386_fxch() \
972     do { \
973         *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
974         *(((u1 *) mcodeptr)++) = (u1) 0xc9; \
975     } while (0)
976
977
978 #define i386_fxch_reg(reg) \
979     do { \
980         *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
981         *(((u1 *) mcodeptr)++) = (u1) 0xc8 + (0x0f & (reg)); \
982     } while (0)
983
984
985 #define i386_fprem1() \
986     do { \
987         *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
988         *(((u1 *) mcodeptr)++) = (u1) 0xf5; \
989     } while (0)
990
991
992 #define i386_fucom() \
993     do { \
994         *(((u1 *) mcodeptr)++) = (u1) 0xdd; \
995         *(((u1 *) mcodeptr)++) = (u1) 0xe1; \
996     } while (0)
997
998
999 #define i386_fucompp() \
1000     do { \
1001         *(((u1 *) mcodeptr)++) = (u1) 0xda; \
1002         *(((u1 *) mcodeptr)++) = (u1) 0xe9; \
1003     } while (0)
1004
1005
1006 #define i386_fnstsw() \
1007     do { \
1008         *(((u1 *) mcodeptr)++) = (u1) 0xdf; \
1009         *(((u1 *) mcodeptr)++) = (u1) 0xe0; \
1010     } while (0)
1011
1012
1013
1014 /* macros for all used commands (see an Alpha-manual for description) *********/ 
1015
1016 #define M_LDA(a,b,disp)         M_MEM (0x08,a,b,disp)           /* low const  */
1017 #define M_LDAH(a,b,disp)        M_MEM (0x09,a,b,disp)           /* high const */
1018 #define M_BLDU(a,b,disp)        M_MEM (0x0a,a,b,disp)           /*  8 load    */
1019 #define M_SLDU(a,b,disp)        M_MEM (0x0c,a,b,disp)           /* 16 load    */
1020 #define M_ILD(a,b,disp)         M_MEM (0x28,a,b,disp)           /* 32 load    */
1021 #define M_LLD(a,b,disp)         M_MEM (0x29,a,b,disp)           /* 64 load    */
1022 #define M_ALD(a,b,disp)         M_MEM (0x29,a,b,disp)           /* addr load  */
1023 #define M_BST(a,b,disp)         M_MEM (0x0e,a,b,disp)           /*  8 store   */
1024 #define M_SST(a,b,disp)         M_MEM (0x0d,a,b,disp)           /* 16 store   */
1025 #define M_IST(a,b,disp)         M_MEM (0x2c,a,b,disp)           /* 32 store   */
1026 #define M_LST(a,b,disp)         M_MEM (0x2d,a,b,disp)           /* 64 store   */
1027 #define M_AST(a,b,disp)         M_MEM (0x2d,a,b,disp)           /* addr store */
1028
1029 #define M_BSEXT(b,c)            M_OP3 (0x1c,0x0,REG_ZERO,b,c,0) /*  8 signext */
1030 #define M_SSEXT(b,c)            M_OP3 (0x1c,0x1,REG_ZERO,b,c,0) /* 16 signext */
1031
1032 #define M_BR(disp)              M_BRA (0x30,REG_ZERO,disp)      /* branch     */
1033 #define M_BSR(ra,disp)          M_BRA (0x34,ra,disp)            /* branch sbr */
1034 #define M_BEQZ(a,disp)          M_BRA (0x39,a,disp)             /* br a == 0  */
1035 #define M_BLTZ(a,disp)          M_BRA (0x3a,a,disp)             /* br a <  0  */
1036 #define M_BLEZ(a,disp)          M_BRA (0x3b,a,disp)             /* br a <= 0  */
1037 #define M_BNEZ(a,disp)          M_BRA (0x3d,a,disp)             /* br a != 0  */
1038 #define M_BGEZ(a,disp)          M_BRA (0x3e,a,disp)             /* br a >= 0  */
1039 #define M_BGTZ(a,disp)          M_BRA (0x3f,a,disp)             /* br a >  0  */
1040
1041 #define M_JMP(a,b)              M_MEM (0x1a,a,b,0x0000)         /* jump       */
1042 #define M_JSR(a,b)              M_MEM (0x1a,a,b,0x4000)         /* call sbr   */
1043 #define M_RET(a,b)              M_MEM (0x1a,a,b,0x8000)         /* return     */
1044
1045 #define M_IADD(a,b,c)           M_OP3 (0x10,0x0,  a,b,c,0)      /* 32 add     */
1046 #define M_LADD(a,b,c)           M_OP3 (0x10,0x20, a,b,c,0)      /* 64 add     */
1047 #define M_ISUB(a,b,c)           M_OP3 (0x10,0x09, a,b,c,0)      /* 32 sub     */
1048 #define M_LSUB(a,b,c)           M_OP3 (0x10,0x29, a,b,c,0)      /* 64 sub     */
1049 #define M_IMUL(a,b,c)           M_OP3 (0x13,0x00, a,b,c,0)      /* 32 mul     */
1050 #define M_LMUL(a,b,c)           M_OP3 (0x13,0x20, a,b,c,0)      /* 64 mul     */
1051
1052 #define M_IADD_IMM(a,b,c)       M_OP3 (0x10,0x0,  a,b,c,1)      /* 32 add     */
1053 #define M_LADD_IMM(a,b,c)       M_OP3 (0x10,0x20, a,b,c,1)      /* 64 add     */
1054 #define M_ISUB_IMM(a,b,c)       M_OP3 (0x10,0x09, a,b,c,1)      /* 32 sub     */
1055 #define M_LSUB_IMM(a,b,c)       M_OP3 (0x10,0x29, a,b,c,1)      /* 64 sub     */
1056 #define M_IMUL_IMM(a,b,c)       M_OP3 (0x13,0x00, a,b,c,1)      /* 32 mul     */
1057 #define M_LMUL_IMM(a,b,c)       M_OP3 (0x13,0x20, a,b,c,1)      /* 64 mul     */
1058
1059 #define M_CMPEQ(a,b,c)          M_OP3 (0x10,0x2d, a,b,c,0)      /* c = a == b */
1060 #define M_CMPLT(a,b,c)          M_OP3 (0x10,0x4d, a,b,c,0)      /* c = a <  b */
1061 #define M_CMPLE(a,b,c)          M_OP3 (0x10,0x6d, a,b,c,0)      /* c = a <= b */
1062
1063 #define M_CMPULE(a,b,c)         M_OP3 (0x10,0x3d, a,b,c,0)      /* c = a <= b */
1064 #define M_CMPULT(a,b,c)         M_OP3 (0x10,0x1d, a,b,c,0)      /* c = a <= b */
1065
1066 #define M_CMPEQ_IMM(a,b,c)      M_OP3 (0x10,0x2d, a,b,c,1)      /* c = a == b */
1067 #define M_CMPLT_IMM(a,b,c)      M_OP3 (0x10,0x4d, a,b,c,1)      /* c = a <  b */
1068 #define M_CMPLE_IMM(a,b,c)      M_OP3 (0x10,0x6d, a,b,c,1)      /* c = a <= b */
1069
1070 #define M_CMPULE_IMM(a,b,c)     M_OP3 (0x10,0x3d, a,b,c,1)      /* c = a <= b */
1071 #define M_CMPULT_IMM(a,b,c)     M_OP3 (0x10,0x1d, a,b,c,1)      /* c = a <= b */
1072
1073 #define M_AND(a,b,c)            M_OP3 (0x11,0x00, a,b,c,0)      /* c = a &  b */
1074 #define M_OR( a,b,c)            M_OP3 (0x11,0x20, a,b,c,0)      /* c = a |  b */
1075 #define M_XOR(a,b,c)            M_OP3 (0x11,0x40, a,b,c,0)      /* c = a ^  b */
1076
1077 #define M_AND_IMM(a,b,c)        M_OP3 (0x11,0x00, a,b,c,1)      /* c = a &  b */
1078 #define M_OR_IMM( a,b,c)        M_OP3 (0x11,0x20, a,b,c,1)      /* c = a |  b */
1079 #define M_XOR_IMM(a,b,c)        M_OP3 (0x11,0x40, a,b,c,1)      /* c = a ^  b */
1080
1081 #define M_MOV(a,c)              M_OR (a,a,c)                    /* c = a      */
1082 #define M_CLR(c)                M_OR (31,31,c)                  /* c = 0      */
1083 #define M_NOP                   M_OR (31,31,31)                 /* ;          */
1084
1085 #define M_SLL(a,b,c)            M_OP3 (0x12,0x39, a,b,c,0)      /* c = a << b */
1086 #define M_SRA(a,b,c)            M_OP3 (0x12,0x3c, a,b,c,0)      /* c = a >> b */
1087 #define M_SRL(a,b,c)            M_OP3 (0x12,0x34, a,b,c,0)      /* c = a >>>b */
1088
1089 #define M_SLL_IMM(a,b,c)        M_OP3 (0x12,0x39, a,b,c,1)      /* c = a << b */
1090 #define M_SRA_IMM(a,b,c)        M_OP3 (0x12,0x3c, a,b,c,1)      /* c = a >> b */
1091 #define M_SRL_IMM(a,b,c)        M_OP3 (0x12,0x34, a,b,c,1)      /* c = a >>>b */
1092
1093 #define M_FLD(a,b,disp)         M_MEM (0x22,a,b,disp)           /* load flt   */
1094 #define M_DLD(a,b,disp)         M_MEM (0x23,a,b,disp)           /* load dbl   */
1095 #define M_FST(a,b,disp)         M_MEM (0x26,a,b,disp)           /* store flt  */
1096 #define M_DST(a,b,disp)         M_MEM (0x27,a,b,disp)           /* store dbl  */
1097
1098 #define M_FADD(a,b,c)           M_FOP3 (0x16, 0x080, a,b,c)     /* flt add    */
1099 #define M_DADD(a,b,c)           M_FOP3 (0x16, 0x0a0, a,b,c)     /* dbl add    */
1100 #define M_FSUB(a,b,c)           M_FOP3 (0x16, 0x081, a,b,c)     /* flt sub    */
1101 #define M_DSUB(a,b,c)           M_FOP3 (0x16, 0x0a1, a,b,c)     /* dbl sub    */
1102 #define M_FMUL(a,b,c)           M_FOP3 (0x16, 0x082, a,b,c)     /* flt mul    */
1103 #define M_DMUL(a,b,c)           M_FOP3 (0x16, 0x0a2, a,b,c)     /* dbl mul    */
1104 #define M_FDIV(a,b,c)           M_FOP3 (0x16, 0x083, a,b,c)     /* flt div    */
1105 #define M_DDIV(a,b,c)           M_FOP3 (0x16, 0x0a3, a,b,c)     /* dbl div    */
1106
1107 #define M_FADDS(a,b,c)          M_FOP3 (0x16, 0x580, a,b,c)     /* flt add    */
1108 #define M_DADDS(a,b,c)          M_FOP3 (0x16, 0x5a0, a,b,c)     /* dbl add    */
1109 #define M_FSUBS(a,b,c)          M_FOP3 (0x16, 0x581, a,b,c)     /* flt sub    */
1110 #define M_DSUBS(a,b,c)          M_FOP3 (0x16, 0x5a1, a,b,c)     /* dbl sub    */
1111 #define M_FMULS(a,b,c)          M_FOP3 (0x16, 0x582, a,b,c)     /* flt mul    */
1112 #define M_DMULS(a,b,c)          M_FOP3 (0x16, 0x5a2, a,b,c)     /* dbl mul    */
1113 #define M_FDIVS(a,b,c)          M_FOP3 (0x16, 0x583, a,b,c)     /* flt div    */
1114 #define M_DDIVS(a,b,c)          M_FOP3 (0x16, 0x5a3, a,b,c)     /* dbl div    */
1115
1116 #define M_CVTDF(b,c)            M_FOP3 (0x16, 0x0ac, 31,b,c)    /* dbl2long   */
1117 #define M_CVTLF(b,c)            M_FOP3 (0x16, 0x0bc, 31,b,c)    /* long2flt   */
1118 #define M_CVTLD(b,c)            M_FOP3 (0x16, 0x0be, 31,b,c)    /* long2dbl   */
1119 #define M_CVTDL(b,c)            M_FOP3 (0x16, 0x1af, 31,b,c)    /* dbl2long   */
1120 #define M_CVTDL_C(b,c)          M_FOP3 (0x16, 0x12f, 31,b,c)    /* dbl2long   */
1121 #define M_CVTLI(b,c)            M_FOP3 (0x17, 0x130, 31,b,c)    /* long2int   */
1122
1123 #define M_CVTDFS(b,c)           M_FOP3 (0x16, 0x5ac, 31,b,c)    /* dbl2long   */
1124 #define M_CVTDLS(b,c)           M_FOP3 (0x16, 0x5af, 31,b,c)    /* dbl2long   */
1125 #define M_CVTDL_CS(b,c)         M_FOP3 (0x16, 0x52f, 31,b,c)    /* dbl2long   */
1126 #define M_CVTLIS(b,c)           M_FOP3 (0x17, 0x530, 31,b,c)    /* long2int   */
1127
1128 #define M_FCMPEQ(a,b,c)         M_FOP3 (0x16, 0x0a5, a,b,c)     /* c = a==b   */
1129 #define M_FCMPLT(a,b,c)         M_FOP3 (0x16, 0x0a6, a,b,c)     /* c = a<b    */
1130
1131 #define M_FCMPEQS(a,b,c)        M_FOP3 (0x16, 0x5a5, a,b,c)     /* c = a==b   */
1132 #define M_FCMPLTS(a,b,c)        M_FOP3 (0x16, 0x5a6, a,b,c)     /* c = a<b    */
1133
1134 #define M_FMOV(fa,fb)           M_FOP3 (0x17, 0x020, fa,fa,fb)  /* b = a      */
1135 #define M_FMOVN(fa,fb)          M_FOP3 (0x17, 0x021, fa,fa,fb)  /* b = -a     */
1136
1137 #define M_FNOP                  M_FMOV (31,31)
1138
1139 #define M_FBEQZ(fa,disp)        M_BRA (0x31,fa,disp)            /* br a == 0.0*/
1140
1141 /* macros for special commands (see an Alpha-manual for description) **********/ 
1142
1143 #define M_TRAPB                 M_MEM (0x18,0,0,0x0000)        /* trap barrier*/
1144
1145 #define M_S4ADDL(a,b,c)         M_OP3 (0x10,0x02, a,b,c,0)     /* c = a*4 + b */
1146 #define M_S4ADDQ(a,b,c)         M_OP3 (0x10,0x22, a,b,c,0)     /* c = a*4 + b */
1147 #define M_S4SUBL(a,b,c)         M_OP3 (0x10,0x0b, a,b,c,0)     /* c = a*4 - b */
1148 #define M_S4SUBQ(a,b,c)         M_OP3 (0x10,0x2b, a,b,c,0)     /* c = a*4 - b */
1149 #define M_S8ADDL(a,b,c)         M_OP3 (0x10,0x12, a,b,c,0)     /* c = a*8 + b */
1150 #define M_S8ADDQ(a,b,c)         M_OP3 (0x10,0x32, a,b,c,0)     /* c = a*8 + b */
1151 #define M_S8SUBL(a,b,c)         M_OP3 (0x10,0x1b, a,b,c,0)     /* c = a*8 - b */
1152 #define M_S8SUBQ(a,b,c)         M_OP3 (0x10,0x3b, a,b,c,0)     /* c = a*8 - b */
1153 #define M_SAADDQ(a,b,c)         M_S8ADDQ(a,b,c)                /* c = a*8 + b */
1154
1155 #define M_S4ADDL_IMM(a,b,c)     M_OP3 (0x10,0x02, a,b,c,1)     /* c = a*4 + b */
1156 #define M_S4ADDQ_IMM(a,b,c)     M_OP3 (0x10,0x22, a,b,c,1)     /* c = a*4 + b */
1157 #define M_S4SUBL_IMM(a,b,c)     M_OP3 (0x10,0x0b, a,b,c,1)     /* c = a*4 - b */
1158 #define M_S4SUBQ_IMM(a,b,c)     M_OP3 (0x10,0x2b, a,b,c,1)     /* c = a*4 - b */
1159 #define M_S8ADDL_IMM(a,b,c)     M_OP3 (0x10,0x12, a,b,c,1)     /* c = a*8 + b */
1160 #define M_S8ADDQ_IMM(a,b,c)     M_OP3 (0x10,0x32, a,b,c,1)     /* c = a*8 + b */
1161 #define M_S8SUBL_IMM(a,b,c)     M_OP3 (0x10,0x1b, a,b,c,1)     /* c = a*8 - b */
1162 #define M_S8SUBQ_IMM(a,b,c)     M_OP3 (0x10,0x3b, a,b,c,1)     /* c = a*8 - b */
1163
1164 #define M_LLD_U(a,b,disp)       M_MEM (0x0b,a,b,disp)          /* unalign ld  */
1165 #define M_LST_U(a,b,disp)       M_MEM (0x0f,a,b,disp)          /* unalign st  */
1166
1167 #define M_ZAP(a,b,c)            M_OP3 (0x12,0x30, a,b,c,0)
1168 #define M_ZAPNOT(a,b,c)         M_OP3 (0x12,0x31, a,b,c,0)
1169
1170 #define M_ZAP_IMM(a,b,c)        M_OP3 (0x12,0x30, a,b,c,1)
1171 #define M_ZAPNOT_IMM(a,b,c)     M_OP3 (0x12,0x31, a,b,c,1)
1172
1173 #define M_BZEXT(a,b)            M_ZAPNOT_IMM(a, 0x01, b)       /*  8 zeroext  */
1174 #define M_CZEXT(a,b)            M_ZAPNOT_IMM(a, 0x03, b)       /* 16 zeroext  */
1175 #define M_IZEXT(a,b)            M_ZAPNOT_IMM(a, 0x0f, b)       /* 32 zeroext  */
1176
1177 #define M_EXTBL(a,b,c)          M_OP3 (0x12,0x06, a,b,c,0)
1178 #define M_EXTWL(a,b,c)          M_OP3 (0x12,0x16, a,b,c,0)
1179 #define M_EXTLL(a,b,c)          M_OP3 (0x12,0x26, a,b,c,0)
1180 #define M_EXTQL(a,b,c)          M_OP3 (0x12,0x36, a,b,c,0)
1181 #define M_EXTWH(a,b,c)          M_OP3 (0x12,0x5a, a,b,c,0)
1182 #define M_EXTLH(a,b,c)          M_OP3 (0x12,0x6a, a,b,c,0)
1183 #define M_EXTQH(a,b,c)          M_OP3 (0x12,0x7a, a,b,c,0)
1184 #define M_INSBL(a,b,c)          M_OP3 (0x12,0x0b, a,b,c,0)
1185 #define M_INSWL(a,b,c)          M_OP3 (0x12,0x1b, a,b,c,0)
1186 #define M_INSLL(a,b,c)          M_OP3 (0x12,0x2b, a,b,c,0)
1187 #define M_INSQL(a,b,c)          M_OP3 (0x12,0x3b, a,b,c,0)
1188 #define M_INSWH(a,b,c)          M_OP3 (0x12,0x57, a,b,c,0)
1189 #define M_INSLH(a,b,c)          M_OP3 (0x12,0x67, a,b,c,0)
1190 #define M_INSQH(a,b,c)          M_OP3 (0x12,0x77, a,b,c,0)
1191 #define M_MSKBL(a,b,c)          M_OP3 (0x12,0x02, a,b,c,0)
1192 #define M_MSKWL(a,b,c)          M_OP3 (0x12,0x12, a,b,c,0)
1193 #define M_MSKLL(a,b,c)          M_OP3 (0x12,0x22, a,b,c,0)
1194 #define M_MSKQL(a,b,c)          M_OP3 (0x12,0x32, a,b,c,0)
1195 #define M_MSKWH(a,b,c)          M_OP3 (0x12,0x52, a,b,c,0)
1196 #define M_MSKLH(a,b,c)          M_OP3 (0x12,0x62, a,b,c,0)
1197 #define M_MSKQH(a,b,c)          M_OP3 (0x12,0x72, a,b,c,0)
1198
1199 #define M_EXTBL_IMM(a,b,c)      M_OP3 (0x12,0x06, a,b,c,1)
1200 #define M_EXTWL_IMM(a,b,c)      M_OP3 (0x12,0x16, a,b,c,1)
1201 #define M_EXTLL_IMM(a,b,c)      M_OP3 (0x12,0x26, a,b,c,1)
1202 #define M_EXTQL_IMM(a,b,c)      M_OP3 (0x12,0x36, a,b,c,1)
1203 #define M_EXTWH_IMM(a,b,c)      M_OP3 (0x12,0x5a, a,b,c,1)
1204 #define M_EXTLH_IMM(a,b,c)      M_OP3 (0x12,0x6a, a,b,c,1)
1205 #define M_EXTQH_IMM(a,b,c)      M_OP3 (0x12,0x7a, a,b,c,1)
1206 #define M_INSBL_IMM(a,b,c)      M_OP3 (0x12,0x0b, a,b,c,1)
1207 #define M_INSWL_IMM(a,b,c)      M_OP3 (0x12,0x1b, a,b,c,1)
1208 #define M_INSLL_IMM(a,b,c)      M_OP3 (0x12,0x2b, a,b,c,1)
1209 #define M_INSQL_IMM(a,b,c)      M_OP3 (0x12,0x3b, a,b,c,1)
1210 #define M_INSWH_IMM(a,b,c)      M_OP3 (0x12,0x57, a,b,c,1)
1211 #define M_INSLH_IMM(a,b,c)      M_OP3 (0x12,0x67, a,b,c,1)
1212 #define M_INSQH_IMM(a,b,c)      M_OP3 (0x12,0x77, a,b,c,1)
1213 #define M_MSKBL_IMM(a,b,c)      M_OP3 (0x12,0x02, a,b,c,1)
1214 #define M_MSKWL_IMM(a,b,c)      M_OP3 (0x12,0x12, a,b,c,1)
1215 #define M_MSKLL_IMM(a,b,c)      M_OP3 (0x12,0x22, a,b,c,1)
1216 #define M_MSKQL_IMM(a,b,c)      M_OP3 (0x12,0x32, a,b,c,1)
1217 #define M_MSKWH_IMM(a,b,c)      M_OP3 (0x12,0x52, a,b,c,1)
1218 #define M_MSKLH_IMM(a,b,c)      M_OP3 (0x12,0x62, a,b,c,1)
1219 #define M_MSKQH_IMM(a,b,c)      M_OP3 (0x12,0x72, a,b,c,1)
1220
1221 #define M_UMULH(a,b,c)          M_OP3 (0x13,0x30, a,b,c,0)     /* 64 umulh    */
1222
1223 #define M_UMULH_IMM(a,b,c)      M_OP3 (0x13,0x30, a,b,c,1)     /* 64 umulh    */
1224
1225 #define M_CMOVEQ(a,b,c)         M_OP3 (0x11,0x24, a,b,c,0)     /* a==0 ? c=b  */
1226 #define M_CMOVNE(a,b,c)         M_OP3 (0x11,0x26, a,b,c,0)     /* a!=0 ? c=b  */
1227 #define M_CMOVLT(a,b,c)         M_OP3 (0x11,0x44, a,b,c,0)     /* a< 0 ? c=b  */
1228 #define M_CMOVGE(a,b,c)         M_OP3 (0x11,0x46, a,b,c,0)     /* a>=0 ? c=b  */
1229 #define M_CMOVLE(a,b,c)         M_OP3 (0x11,0x64, a,b,c,0)     /* a<=0 ? c=b  */
1230 #define M_CMOVGT(a,b,c)         M_OP3 (0x11,0x66, a,b,c,0)     /* a> 0 ? c=b  */
1231
1232 #define M_CMOVEQ_IMM(a,b,c)     M_OP3 (0x11,0x24, a,b,c,1)     /* a==0 ? c=b  */
1233 #define M_CMOVNE_IMM(a,b,c)     M_OP3 (0x11,0x26, a,b,c,1)     /* a!=0 ? c=b  */
1234 #define M_CMOVLT_IMM(a,b,c)     M_OP3 (0x11,0x44, a,b,c,1)     /* a< 0 ? c=b  */
1235 #define M_CMOVGE_IMM(a,b,c)     M_OP3 (0x11,0x46, a,b,c,1)     /* a>=0 ? c=b  */
1236 #define M_CMOVLE_IMM(a,b,c)     M_OP3 (0x11,0x64, a,b,c,1)     /* a<=0 ? c=b  */
1237 #define M_CMOVGT_IMM(a,b,c)     M_OP3 (0x11,0x66, a,b,c,1)     /* a> 0 ? c=b  */
1238
1239 /* macros for unused commands (see an Alpha-manual for description) ***********/ 
1240
1241 #define M_ANDNOT(a,b,c,const)   M_OP3 (0x11,0x08, a,b,c,const) /* c = a &~ b  */
1242 #define M_ORNOT(a,b,c,const)    M_OP3 (0x11,0x28, a,b,c,const) /* c = a |~ b  */
1243 #define M_XORNOT(a,b,c,const)   M_OP3 (0x11,0x48, a,b,c,const) /* c = a ^~ b  */
1244
1245 #define M_CMPBGE(a,b,c,const)   M_OP3 (0x10,0x0f, a,b,c,const)
1246
1247 #define M_FCMPUN(a,b,c)         M_FOP3 (0x16, 0x0a4, a,b,c)    /* unordered   */
1248 #define M_FCMPLE(a,b,c)         M_FOP3 (0x16, 0x0a7, a,b,c)    /* c = a<=b    */
1249
1250 #define M_FCMPUNS(a,b,c)        M_FOP3 (0x16, 0x5a4, a,b,c)    /* unordered   */
1251 #define M_FCMPLES(a,b,c)        M_FOP3 (0x16, 0x5a7, a,b,c)    /* c = a<=b    */
1252
1253 #define M_FBNEZ(fa,disp)        M_BRA (0x35,fa,disp)
1254 #define M_FBLEZ(fa,disp)        M_BRA (0x33,fa,disp)
1255
1256 #define M_JMP_CO(a,b)           M_MEM (0x1a,a,b,0xc000)        /* call cosub  */
1257
1258
1259 /* function gen_resolvebranch **************************************************
1260
1261     backpatches a branch instruction; Alpha branch instructions are very
1262     regular, so it is only necessary to overwrite some fixed bits in the
1263     instruction.
1264
1265     parameters: ip ... pointer to instruction after branch (void*)
1266                 so ... offset of instruction after branch  (s4)
1267                 to ... offset of branch target             (s4)
1268
1269 *******************************************************************************/
1270
1271 /* #define gen_resolvebranch(ip,so,to) ((s4*)(ip))[-1]|=((s4)(to)-(so))>>2&0x1fffff */
1272 #define gen_resolvebranch(ip,so,to) \
1273     do { \
1274         *(((s4 *) (ip)) - 1) = ((s4) ((to) - (so))); \
1275     } while (0)
1276
1277 #define SOFTNULLPTRCHECK       /* soft null pointer check supportet as option */
1278
1279 #endif