Support r/m operands for non-integer types
[platform/upstream/nasm.git] / disasm.c
1 /* disasm.c   where all the _work_ gets done in the Netwide Disassembler
2  *
3  * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
4  * Julian Hall. All rights reserved. The software is
5  * redistributable under the licence given in the file "Licence"
6  * distributed in the NASM archive.
7  *
8  * initial version 27/iii/95 by Simon Tatham
9  */
10
11 #include <stdio.h>
12 #include <string.h>
13 #include <limits.h>
14 #include <inttypes.h>
15
16 #include "nasm.h"
17 #include "disasm.h"
18 #include "sync.h"
19 #include "insns.h"
20
21 #include "names.c"
22
23 /*
24  * Flags that go into the `segment' field of `insn' structures
25  * during disassembly.
26  */
27 #define SEG_RELATIVE      1
28 #define SEG_32BIT         2
29 #define SEG_RMREG         4
30 #define SEG_DISP8         8
31 #define SEG_DISP16       16
32 #define SEG_DISP32       32
33 #define SEG_NODISP       64
34 #define SEG_SIGNED      128
35 #define SEG_64BIT       256
36
37 #include "regdis.c"
38
39 /*
40  * Prefix information
41  */
42 struct prefix_info {
43     uint8_t osize;              /* Operand size */
44     uint8_t asize;              /* Address size */
45     uint8_t osp;                /* Operand size prefix present */
46     uint8_t asp;                /* Address size prefix present */
47     uint8_t rep;                /* Rep prefix present */
48     uint8_t seg;                /* Segment override prefix present */
49     uint8_t lock;               /* Lock prefix present */
50     uint8_t rex;                /* Rex prefix present */
51 };
52
53 #define getu8(x) (*(uint8_t *)(x))
54 #if defined(__i386__) || defined(__x86_64__)
55 /* Littleendian CPU which can handle unaligned references */
56 #define getu16(x) (*(uint16_t *)(x))
57 #define getu32(x) (*(uint32_t *)(x))
58 #define getu64(x) (*(uint64_t *)(x))
59 #else
60 static uint16_t getu16(uint8_t *data)
61 {
62     return (uint16_t)data[0] + ((uint16_t)data[1] << 8);
63 }
64 static uint32_t getu32(uint8_t *data)
65 {
66     return (uint32_t)getu16(data) + ((uint32_t)getu16(data+2) << 16);
67 }
68 static uint64_t getu64(uint8_t *data)
69 {
70     return (uint64_t)getu32(data) + ((uint64_t)getu32(data+4) << 32);
71 }
72 #endif
73
74 #define gets8(x) ((int8_t)getu8(x))
75 #define gets16(x) ((int16_t)getu16(x))
76 #define gets32(x) ((int32_t)getu32(x))
77 #define gets64(x) ((int64_t)getu64(x))
78
79 /* Important: regval must already have been adjusted for rex extensions */
80 static enum reg_enum whichreg(int32_t regflags, int regval, int rex)
81 {
82     if (!(regflags & (REGISTER|REGMEM)))
83         return 0;               /* Registers not permissible?! */
84
85     regflags |= REGISTER;
86
87     if (!(REG_AL & ~regflags))
88         return R_AL;
89     if (!(REG_AX & ~regflags))
90         return R_AX;
91     if (!(REG_EAX & ~regflags))
92         return R_EAX;
93     if (!(REG_RAX & ~regflags))
94         return R_RAX;
95     if (!(REG_DL & ~regflags))
96         return R_DL;
97     if (!(REG_DX & ~regflags))
98         return R_DX;
99     if (!(REG_EDX & ~regflags))
100         return R_EDX;
101     if (!(REG_RDX & ~regflags))
102         return R_RDX;
103     if (!(REG_CL & ~regflags))
104         return R_CL;
105     if (!(REG_CX & ~regflags))
106         return R_CX;
107     if (!(REG_ECX & ~regflags))
108         return R_ECX;
109     if (!(REG_RCX & ~regflags))
110         return R_RCX;
111     if (!(FPU0 & ~regflags))
112         return R_ST0;
113     if (!(REG_CS & ~regflags))
114         return (regval == 1) ? R_CS : 0;
115     if (!(REG_DESS & ~regflags))
116         return (regval == 0 || regval == 2
117                 || regval == 3 ? rd_sreg[regval] : 0);
118     if (!(REG_FSGS & ~regflags))
119         return (regval == 4 || regval == 5 ? rd_sreg[regval] : 0);
120     if (!(REG_SEG67 & ~regflags))
121         return (regval == 6 || regval == 7 ? rd_sreg[regval] : 0);
122
123     /* All the entries below look up regval in an 16-entry array */
124     if (regval < 0 || regval > 15)
125         return 0;
126
127     if (!(REG8 & ~regflags)) {
128         if (rex & REX_P)
129             return rd_reg8_rex[regval];
130         else
131             return rd_reg8[regval];
132     }
133     if (!(REG16 & ~regflags))
134         return rd_reg16[regval];
135     if (!(REG32 & ~regflags))
136         return rd_reg32[regval];
137     if (!(REG64 & ~regflags))
138         return rd_reg64[regval];
139     if (!(REG_SREG & ~regflags))
140         return rd_sreg[regval & 7]; /* Ignore REX */
141     if (!(REG_CREG & ~regflags))
142         return rd_creg[regval];
143     if (!(REG_DREG & ~regflags))
144         return rd_dreg[regval];
145     if (!(REG_TREG & ~regflags)) {
146         if (rex & REX_P)
147             return 0;           /* TR registers are ill-defined with rex */
148         return rd_treg[regval];
149     }
150     if (!(FPUREG & ~regflags))
151         return rd_fpureg[regval & 7]; /* Ignore REX */
152     if (!(MMXREG & ~regflags))
153         return rd_mmxreg[regval & 7]; /* Ignore REX */
154     if (!(XMMREG & ~regflags))
155         return rd_xmmreg[regval];
156
157     return 0;
158 }
159
160 static const char *whichcond(int condval)
161 {
162     static int conds[] = {
163         C_O, C_NO, C_C, C_NC, C_Z, C_NZ, C_NA, C_A,
164         C_S, C_NS, C_PE, C_PO, C_L, C_NL, C_NG, C_G
165     };
166     return conditions[conds[condval]];
167 }
168
169 /*
170  * Process an effective address (ModRM) specification.
171  */
172 static uint8_t *do_ea(uint8_t *data, int modrm, int asize,
173                       int segsize, operand * op, int rex)
174 {
175     int mod, rm, scale, index, base;
176
177     mod = (modrm >> 6) & 03;
178     rm = modrm & 07;
179
180     if (mod == 3) {             /* pure register version */
181         op->basereg = rm+(rex & REX_B ? 8 : 0);
182         op->segment |= SEG_RMREG;
183         return data;
184     }
185
186     op->addr_size = 0;
187     op->eaflags = 0;
188
189     if (asize == 16) {
190         /*
191          * <mod> specifies the displacement size (none, byte or
192          * word), and <rm> specifies the register combination.
193          * Exception: mod=0,rm=6 does not specify [BP] as one might
194          * expect, but instead specifies [disp16].
195          */
196         op->indexreg = op->basereg = -1;
197         op->scale = 1;          /* always, in 16 bits */
198         switch (rm) {
199         case 0:
200             op->basereg = R_BX;
201             op->indexreg = R_SI;
202             break;
203         case 1:
204             op->basereg = R_BX;
205             op->indexreg = R_DI;
206             break;
207         case 2:
208             op->basereg = R_BP;
209             op->indexreg = R_SI;
210             break;
211         case 3:
212             op->basereg = R_BP;
213             op->indexreg = R_DI;
214             break;
215         case 4:
216             op->basereg = R_SI;
217             break;
218         case 5:
219             op->basereg = R_DI;
220             break;
221         case 6:
222             op->basereg = R_BP;
223             break;
224         case 7:
225             op->basereg = R_BX;
226             break;
227         }
228         if (rm == 6 && mod == 0) {      /* special case */
229             op->basereg = -1;
230             if (segsize != 16)
231                 op->addr_size = 16;
232             mod = 2;            /* fake disp16 */
233         }
234         switch (mod) {
235         case 0:
236             op->segment |= SEG_NODISP;
237             break;
238         case 1:
239             op->segment |= SEG_DISP8;
240             op->offset = (int8_t)*data++;
241             break;
242         case 2:
243             op->segment |= SEG_DISP16;
244             op->offset = *data++;
245             op->offset |= ((unsigned)*data++) << 8;
246             break;
247         }
248         return data;
249     } else {
250         /*
251          * Once again, <mod> specifies displacement size (this time
252          * none, byte or *dword*), while <rm> specifies the base
253          * register. Again, [EBP] is missing, replaced by a pure
254          * disp32 (this time that's mod=0,rm=*5*) in 32-bit mode,
255          * and RIP-relative addressing in 64-bit mode.
256          *
257          * However, rm=4
258          * indicates not a single base register, but instead the
259          * presence of a SIB byte...
260          */
261         int a64 = asize == 64;
262
263         op->indexreg = -1;
264
265         if (a64)
266             op->basereg = rd_reg64[rm | ((rex & REX_B) ? 8 : 0)];
267         else
268             op->basereg = rd_reg32[rm | ((rex & REX_B) ? 8 : 0)];
269
270         if (rm == 5 && mod == 0) {
271             if (segsize == 64) {
272                 op->eaflags |= EAF_REL;
273                 op->segment |= SEG_RELATIVE;
274                 mod = 2;        /* fake disp32 */
275             }
276
277             if (asize != 64)
278                 op->addr_size = asize;
279
280             op->basereg = -1;
281             mod = 2;            /* fake disp32 */
282         }
283
284         if (rm == 4) {          /* process SIB */
285             scale = (*data >> 6) & 03;
286             index = (*data >> 3) & 07;
287             base = *data & 07;
288             data++;
289
290             op->scale = 1 << scale;
291
292             if (index == 4)
293                 op->indexreg = -1; /* ESP/RSP/R12 cannot be an index */
294             else if (a64)
295                 op->indexreg = rd_reg64[index | ((rex & REX_X) ? 8 : 0)];
296             else
297                 op->indexreg = rd_reg64[index | ((rex & REX_X) ? 8 : 0)];
298
299             if (base == 5 && mod == 0) {
300                 op->basereg = -1;
301                 mod = 2;        /* Fake disp32 */
302             } else if (a64)
303                 op->basereg = rd_reg64[base | ((rex & REX_B) ? 8 : 0)];
304             else
305                 op->basereg = rd_reg32[base | ((rex & REX_B) ? 8 : 0)];
306
307             if (segsize != 32)
308                 op->addr_size = 32;
309         }
310
311         switch (mod) {
312         case 0:
313             op->segment |= SEG_NODISP;
314             break;
315         case 1:
316             op->segment |= SEG_DISP8;
317             op->offset = gets8(data);
318             data++;
319             break;
320         case 2:
321             op->segment |= SEG_DISP32;
322             op->offset = getu32(data);
323             data += 4;
324             break;
325         }
326         return data;
327     }
328 }
329
330 /*
331  * Determine whether the instruction template in t corresponds to the data
332  * stream in data. Return the number of bytes matched if so.
333  */
334 static int matches(const struct itemplate *t, uint8_t *data,
335                    const struct prefix_info *prefix, int segsize, insn *ins)
336 {
337     uint8_t *r = (uint8_t *)(t->code);
338     uint8_t *origdata = data;
339     int a_used = FALSE, o_used = FALSE;
340     enum prefixes drep = 0;
341     uint8_t lock = prefix->lock;
342     int osize = prefix->osize;
343     int asize = prefix->asize;
344
345     ins->oprs[0].segment = ins->oprs[1].segment =
346         ins->oprs[2].segment =
347         ins->oprs[0].addr_size = ins->oprs[1].addr_size =
348         ins->oprs[2].addr_size = (segsize == 64 ? SEG_64BIT :
349                                   segsize == 32 ? SEG_32BIT : 0);
350     ins->condition = -1;
351     ins->rex = prefix->rex;
352
353     if (t->flags & (segsize == 64 ? IF_NOLONG : IF_LONG))
354         return FALSE;
355
356     if (prefix->rep == 0xF2)
357         drep = P_REPNE;
358     else if (prefix->rep == 0xF3)
359         drep = P_REP;
360
361     while (*r) {
362         int c = *r++;
363
364         /* FIX: change this into a switch */
365         if (c >= 01 && c <= 03) {
366             while (c--)
367                 if (*r++ != *data++)
368                     return FALSE;
369         } else if (c == 04) {
370             switch (*data++) {
371             case 0x07:
372                 ins->oprs[0].basereg = 0;
373                 break;
374             case 0x17:
375                 ins->oprs[0].basereg = 2;
376                 break;
377             case 0x1F:
378                 ins->oprs[0].basereg = 3;
379                 break;
380             default:
381                 return FALSE;
382             }
383         } else if (c == 05) {
384             switch (*data++) {
385             case 0xA1:
386                 ins->oprs[0].basereg = 4;
387                 break;
388             case 0xA9:
389                 ins->oprs[0].basereg = 5;
390                 break;
391             default:
392                 return FALSE;
393             }
394         } else if (c == 06) {
395             switch (*data++) {
396             case 0x06:
397                 ins->oprs[0].basereg = 0;
398                 break;
399             case 0x0E:
400                 ins->oprs[0].basereg = 1;
401                 break;
402             case 0x16:
403                 ins->oprs[0].basereg = 2;
404                 break;
405             case 0x1E:
406                 ins->oprs[0].basereg = 3;
407                 break;
408             default:
409                 return FALSE;
410             }
411         } else if (c == 07) {
412             switch (*data++) {
413             case 0xA0:
414                 ins->oprs[0].basereg = 4;
415                 break;
416             case 0xA8:
417                 ins->oprs[0].basereg = 5;
418                 break;
419             default:
420                 return FALSE;
421             }
422         } else if (c >= 010 && c <= 012) {
423             int t = *r++, d = *data++;
424             if (d < t || d > t + 7)
425                 return FALSE;
426             else {
427                 ins->oprs[c - 010].basereg = (d-t)+
428                     (ins->rex & REX_B ? 8 : 0);
429                 ins->oprs[c - 010].segment |= SEG_RMREG;
430             }
431         } else if (c == 017) {
432             if (*data++)
433                 return FALSE;
434         } else if (c >= 014 && c <= 016) {
435             ins->oprs[c - 014].offset = (int8_t)*data++;
436             ins->oprs[c - 014].segment |= SEG_SIGNED;
437         } else if (c >= 020 && c <= 022) {
438             ins->oprs[c - 020].offset = *data++;
439         } else if (c >= 024 && c <= 026) {
440             ins->oprs[c - 024].offset = *data++;
441         } else if (c >= 030 && c <= 032) {
442             ins->oprs[c - 030].offset = getu16(data);
443             data += 2;
444         } else if (c >= 034 && c <= 036) {
445             if (osize == 32) {
446                 ins->oprs[c - 034].offset = getu32(data);
447                 data += 4;
448             } else {
449                 ins->oprs[c - 034].offset = getu16(data);
450                 data += 2;
451             }
452             if (segsize != asize)
453                 ins->oprs[c - 034].addr_size = asize;
454         } else if (c >= 040 && c <= 042) {
455             ins->oprs[c - 040].offset = getu32(data);
456             data += 4;
457         } else if (c >= 044 && c <= 046) {
458             switch (asize) {
459             case 16:
460                 ins->oprs[c - 044].offset = getu16(data);
461                 data += 2;
462                 break;
463             case 32:
464                 ins->oprs[c - 044].offset = getu32(data);
465                 data += 4;
466                 break;
467             case 64:
468                 ins->oprs[c - 044].offset = getu64(data);
469                 data += 8;
470                 break;
471             }
472             if (segsize != asize)
473                 ins->oprs[c - 044].addr_size = asize;
474         } else if (c >= 050 && c <= 052) {
475             ins->oprs[c - 050].offset = gets8(data++);
476             ins->oprs[c - 050].segment |= SEG_RELATIVE;
477         } else if (c >= 054 && c <= 056) {
478             ins->oprs[c - 054].offset = getu64(data);
479             data += 8;
480         } else if (c >= 060 && c <= 062) {
481             ins->oprs[c - 060].offset = gets16(data);
482             data += 2;
483             ins->oprs[c - 060].segment |= SEG_RELATIVE;
484             ins->oprs[c - 060].segment &= ~SEG_32BIT;
485         } else if (c >= 064 && c <= 066) {
486             if (osize == 16) {
487                 ins->oprs[c - 064].offset = getu16(data);
488                 data += 2;
489                 ins->oprs[c - 064].segment &= ~(SEG_32BIT|SEG_64BIT);
490             } else if (osize == 32) {
491                 ins->oprs[c - 064].offset = getu32(data);
492                 data += 4;
493                 ins->oprs[c - 064].segment &= ~SEG_64BIT;
494                 ins->oprs[c - 064].segment |= SEG_32BIT;
495             }   
496             if (segsize != osize) {
497                 ins->oprs[c - 064].type =
498                     (ins->oprs[c - 064].type & ~SIZE_MASK)
499                     | ((osize == 16) ? BITS16 : BITS32);
500             }
501         } else if (c >= 070 && c <= 072) {
502             ins->oprs[c - 070].offset = getu32(data);
503             data += 4;
504             ins->oprs[c - 070].segment |= SEG_32BIT | SEG_RELATIVE;
505         } else if (c >= 0100 && c < 0130) {
506             int modrm = *data++;
507             ins->oprs[c & 07].basereg = ((modrm >> 3)&7)+
508                 (ins->rex & REX_R ? 8 : 0);
509             ins->oprs[c & 07].segment |= SEG_RMREG;
510             data = do_ea(data, modrm, asize, segsize,
511                          &ins->oprs[(c >> 3) & 07], ins->rex);
512         } else if (c >= 0130 && c <= 0132) {
513             ins->oprs[c - 0130].offset = getu16(data);
514             data += 2;
515         } else if (c >= 0140 && c <= 0142) {
516             ins->oprs[c - 0140].offset = getu32(data);
517             data += 4;
518         } else if (c >= 0200 && c <= 0277) {
519             int modrm = *data++;
520             if (((modrm >> 3) & 07) != (c & 07))
521                 return FALSE;   /* spare field doesn't match up */
522             data = do_ea(data, modrm, asize, segsize,
523                          &ins->oprs[(c >> 3) & 07], ins->rex);
524         } else if (c >= 0300 && c <= 0302) {
525             a_used = TRUE;
526         } else if (c == 0310) {
527             if (asize != 16)
528                 return FALSE;
529             else
530                 a_used = TRUE;
531         } else if (c == 0311) {
532             if (asize == 16)
533                 return FALSE;
534             else
535                 a_used = TRUE;
536         } else if (c == 0312) {
537             if (asize != segsize)
538                 return FALSE;
539             else
540                 a_used = TRUE;
541         } else if (c == 0313) {
542             if (asize != 64)
543                 return FALSE;
544             else
545                 a_used = TRUE;
546         } else if (c == 0320) {
547             if (osize != 16)
548                 return FALSE;
549             else
550                 o_used = TRUE;
551         } else if (c == 0321) {
552             if (osize != 32)
553                 return FALSE;
554             else
555                 o_used = TRUE;
556         } else if (c == 0322) {
557             if (osize != (segsize == 16) ? 16 : 32)
558                 return FALSE;
559             else
560                 o_used = TRUE;
561         } else if (c == 0323) {
562             ins->rex |= REX_W;  /* 64-bit only instruction */
563             osize = 64;
564         } else if (c == 0324) {
565             if (!(ins->rex & (REX_P|REX_W)) || osize != 64)
566                 return FALSE;
567         } else if (c == 0330) {
568             int t = *r++, d = *data++;
569             if (d < t || d > t + 15)
570                 return FALSE;
571             else
572                 ins->condition = d - t;
573         } else if (c == 0331) {
574             if (prefix->rep)
575                 return FALSE;
576         } else if (c == 0332) {
577             if (drep == P_REP)
578                 drep = P_REPE;
579         } else if (c == 0333) {
580             if (prefix->rep != 0xF3)
581                 return FALSE;
582             drep = 0;
583         } else if (c == 0334) {
584             if (lock) {
585                 ins->rex |= REX_R;
586                 lock = 0;
587             }
588         } else if (c == 0364) {
589             if (prefix->osp)
590                 return FALSE;
591         } else if (c == 0365) {
592             if (prefix->asp)
593                 return FALSE;
594         } else if (c == 0366) {
595             if (!prefix->osp)
596                 return FALSE;
597             o_used = TRUE;
598         } else if (c == 0367) {
599             if (!prefix->asp)
600                 return FALSE;
601             o_used = TRUE;
602         }
603     }
604
605     /*
606      * Check for unused rep or a/o prefixes.
607      */
608     ins->nprefix = 0;
609     if (lock)
610         ins->prefixes[ins->nprefix++] = P_LOCK;
611     if (drep)
612         ins->prefixes[ins->nprefix++] = drep;
613     if (!a_used && asize != segsize)
614         ins->prefixes[ins->nprefix++] = asize == 16 ? P_A16 : P_A32;
615     if (!o_used && osize == ((segsize == 16) ? 32 : 16))
616         ins->prefixes[ins->nprefix++] = osize == 16 ? P_O16 : P_O32;
617
618     /* Fix: check for redundant REX prefixes */
619
620     return data - origdata;
621 }
622
623 int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
624             int32_t offset, int autosync, uint32_t prefer)
625 {
626     const struct itemplate * const *p, * const *best_p;
627     int length, best_length = 0;
628     char *segover;
629     int i, slen, colon;
630     uint8_t *origdata;
631     int works;
632     insn tmp_ins, ins;
633     uint32_t goodness, best;
634     int best_pref;
635     struct prefix_info prefix;
636
637     memset(&ins, 0, sizeof ins);
638
639     /*
640      * Scan for prefixes.
641      */
642     memset(&prefix, 0, sizeof prefix);
643     prefix.asize = segsize;
644     prefix.osize = (segsize == 64) ? 32 : segsize;
645     segover = NULL;
646     origdata = data;
647     for (;;) {
648         if (*data == 0xF3 || *data == 0xF2)
649             prefix.rep = *data++;
650         else if (*data == 0xF0)
651             prefix.lock = *data++;
652         else if (*data == 0x2E)
653             segover = "cs", prefix.seg = *data++;
654         else if (*data == 0x36)
655             segover = "ss", prefix.seg = *data++;
656         else if (*data == 0x3E)
657             segover = "ds", prefix.seg = *data++;
658         else if (*data == 0x26)
659             segover = "es", prefix.seg = *data++;
660         else if (*data == 0x64)
661             segover = "fs", prefix.seg = *data++;
662         else if (*data == 0x65)
663             segover = "gs", prefix.seg = *data++;
664         else if (*data == 0x66) {
665             prefix.osize = (segsize == 16) ? 32 : 16;
666             prefix.osp = *data++;
667         } else if (*data == 0x67) {
668             prefix.asize = (segsize == 32) ? 16 : 32;
669             prefix.asp = *data++;
670         } else if (segsize == 64 && (*data & 0xf0) == REX_P) {
671             prefix.rex = *data++;
672             if (prefix.rex & REX_W)
673                 prefix.osize = 64;
674             break;              /* REX is always the last prefix */
675         } else {
676             break;
677         }
678     }
679
680     best = -1;                  /* Worst possible */
681     best_p = NULL;
682     best_pref = INT_MAX;
683
684     for (p = itable[*data]; *p; p++) {
685         if ((length = matches(*p, data, &prefix, segsize, &tmp_ins))) {
686             works = TRUE;
687             /*
688              * Final check to make sure the types of r/m match up.
689              * XXX: Need to make sure this is actually correct.
690              */
691             for (i = 0; i < (*p)->operands; i++) {
692                 if (
693                        /* If it's a mem-only EA but we have a register, die. */
694                        ((tmp_ins.oprs[i].segment & SEG_RMREG) &&
695                         !(MEMORY & ~(*p)->opd[i])) ||
696                        /* If it's a reg-only EA but we have a memory ref, die. */
697                        (!(tmp_ins.oprs[i].segment & SEG_RMREG) &&
698                         !(REG_EA & ~(*p)->opd[i]) &&
699                         !((*p)->opd[i] & REG_SMASK)) ||
700                        /* Register type mismatch (eg FS vs REG_DESS): die. */
701                        ((((*p)->opd[i] & (REGISTER | FPUREG)) ||
702                          (tmp_ins.oprs[i].segment & SEG_RMREG)) &&
703                         !whichreg((*p)->opd[i],
704                                   tmp_ins.oprs[i].basereg, tmp_ins.rex))) {
705                     works = FALSE;
706                     break;
707                 }
708             }
709
710             /*
711              * Note: we always prefer instructions which incorporate
712              * prefixes in the instructions themselves.  This is to allow
713              * e.g. PAUSE to be preferred to REP NOP, and deal with
714              * MMX/SSE instructions where prefixes are used to select
715              * between MMX and SSE register sets or outright opcode
716              * selection.
717              */
718             if (works) {
719                 goodness = ((*p)->flags & IF_PFMASK) ^ prefer;
720                 if (tmp_ins.nprefix < best_pref ||
721                     (tmp_ins.nprefix == best_pref && goodness < best)) {
722                     /* This is the best one found so far */
723                     best = goodness;
724                     best_p = p;
725                     best_pref = tmp_ins.nprefix;
726                     best_length = length;
727                     ins = tmp_ins;
728                 }
729             }
730         }
731     }
732
733     if (!best_p)
734         return 0;               /* no instruction was matched */
735
736     /* Pick the best match */
737     p = best_p;
738     length = best_length;
739
740     slen = 0;
741
742     /* TODO: snprintf returns the value that the string would have if
743      *      the buffer were long enough, and not the actual length of 
744      *      the returned string, so each instance of using the return
745      *      value of snprintf should actually be checked to assure that
746      *      the return value is "sane."  Maybe a macro wrapper could
747      *      be used for that purpose.
748      */
749     for (i = 0; i < ins.nprefix; i++)
750         switch (ins.prefixes[i]) {
751         case P_LOCK:
752             slen += snprintf(output + slen, outbufsize - slen, "lock ");
753             break;
754         case P_REP:
755             slen += snprintf(output + slen, outbufsize - slen, "rep ");
756             break;
757         case P_REPE:
758             slen += snprintf(output + slen, outbufsize - slen, "repe ");
759             break;
760         case P_REPNE:
761             slen += snprintf(output + slen, outbufsize - slen, "repne ");
762             break;
763         case P_A16:
764             slen += snprintf(output + slen, outbufsize - slen, "a16 ");
765             break;
766         case P_A32:
767             slen += snprintf(output + slen, outbufsize - slen, "a32 ");
768             break;
769         case P_O16:
770             slen += snprintf(output + slen, outbufsize - slen, "o16 ");
771             break;
772         case P_O32:
773             slen += snprintf(output + slen, outbufsize - slen, "o32 ");
774             break;
775         default:
776             break;
777         }
778
779     for (i = 0; i < (int)elements(ico); i++)
780         if ((*p)->opcode == ico[i]) {
781             slen +=
782                 snprintf(output + slen, outbufsize - slen, "%s%s", icn[i],
783                          whichcond(ins.condition));
784             break;
785         }
786     if (i >= (int)elements(ico))
787         slen +=
788             snprintf(output + slen, outbufsize - slen, "%s",
789                      insn_names[(*p)->opcode]);
790     colon = FALSE;
791     length += data - origdata;  /* fix up for prefixes */
792     for (i = 0; i < (*p)->operands; i++) {
793         output[slen++] = (colon ? ':' : i == 0 ? ' ' : ',');
794
795         if (ins.oprs[i].segment & SEG_RELATIVE) {
796             ins.oprs[i].offset += offset + length;
797             /*
798              * sort out wraparound
799              */
800             if (!(ins.oprs[i].segment & (SEG_32BIT|SEG_64BIT)))
801                 ins.oprs[i].offset &= 0xffff;
802             /*
803              * add sync marker, if autosync is on
804              */
805             if (autosync)
806                 add_sync(ins.oprs[i].offset, 0L);
807         }
808
809         if ((*p)->opd[i] & COLON)
810             colon = TRUE;
811         else
812             colon = FALSE;
813
814         if (((*p)->opd[i] & (REGISTER | FPUREG)) ||
815             (ins.oprs[i].segment & SEG_RMREG)) {
816             ins.oprs[i].basereg = whichreg((*p)->opd[i],
817                                            ins.oprs[i].basereg, ins.rex);
818             if ((*p)->opd[i] & TO)
819                 slen += snprintf(output + slen, outbufsize - slen, "to ");
820             slen += snprintf(output + slen, outbufsize - slen, "%s",
821                              reg_names[ins.oprs[i].basereg -
822                                        EXPR_REG_START]);
823         } else if (!(UNITY & ~(*p)->opd[i])) {
824             output[slen++] = '1';
825         } else if ((*p)->opd[i] & IMMEDIATE) {
826             if ((*p)->opd[i] & BITS8) {
827                 slen +=
828                     snprintf(output + slen, outbufsize - slen, "byte ");
829                 if (ins.oprs[i].segment & SEG_SIGNED) {
830                     if (ins.oprs[i].offset < 0) {
831                         ins.oprs[i].offset *= -1;
832                         output[slen++] = '-';
833                     } else
834                         output[slen++] = '+';
835                 }
836             } else if ((*p)->opd[i] & BITS16) {
837                 slen +=
838                     snprintf(output + slen, outbufsize - slen, "word ");
839             } else if ((*p)->opd[i] & BITS32) {
840                 slen +=
841                     snprintf(output + slen, outbufsize - slen, "dword ");
842             } else if ((*p)->opd[i] & BITS64) {
843                 slen +=
844                     snprintf(output + slen, outbufsize - slen, "qword ");
845             } else if ((*p)->opd[i] & NEAR) {
846                 slen +=
847                     snprintf(output + slen, outbufsize - slen, "near ");
848             } else if ((*p)->opd[i] & SHORT) {
849                 slen +=
850                     snprintf(output + slen, outbufsize - slen, "short ");
851             }
852             slen +=
853                 snprintf(output + slen, outbufsize - slen, "0x%"PRIx64"",
854                          ins.oprs[i].offset);
855         } else if (!(MEM_OFFS & ~(*p)->opd[i])) {
856             slen +=
857                 snprintf(output + slen, outbufsize - slen, "[%s%s%s0x%"PRIx64"]",
858                          (segover ? segover : ""),
859                          (segover ? ":" : ""),
860                          (ins.oprs[i].addr_size ==
861                           32 ? "dword " : ins.oprs[i].addr_size ==
862                           16 ? "word " : ""), ins.oprs[i].offset);
863             segover = NULL;
864         } else if (!(REGMEM & ~(*p)->opd[i])) {
865             int started = FALSE;
866             if ((*p)->opd[i] & BITS8)
867                 slen +=
868                     snprintf(output + slen, outbufsize - slen, "byte ");
869             if ((*p)->opd[i] & BITS16)
870                 slen +=
871                     snprintf(output + slen, outbufsize - slen, "word ");
872             if ((*p)->opd[i] & BITS32)
873                 slen +=
874                     snprintf(output + slen, outbufsize - slen, "dword ");
875             if ((*p)->opd[i] & BITS64)
876                 slen +=
877                     snprintf(output + slen, outbufsize - slen, "qword ");
878             if ((*p)->opd[i] & BITS80)
879                 slen +=
880                     snprintf(output + slen, outbufsize - slen, "tword ");
881             if ((*p)->opd[i] & FAR)
882                 slen += snprintf(output + slen, outbufsize - slen, "far ");
883             if ((*p)->opd[i] & NEAR)
884                 slen +=
885                     snprintf(output + slen, outbufsize - slen, "near ");
886             output[slen++] = '[';
887             if (ins.oprs[i].addr_size)
888                 slen += snprintf(output + slen, outbufsize - slen, "%s",
889                                  (ins.oprs[i].addr_size == 64 ? "qword " :
890                                   ins.oprs[i].addr_size == 32 ? "dword " :
891                                   ins.oprs[i].addr_size == 16 ? "word " :
892                                   ""));
893             if (ins.oprs[i].eaflags & EAF_REL)
894                 slen += snprintf(output + slen, outbufsize - slen, "rel ");
895             if (segover) {
896                 slen +=
897                     snprintf(output + slen, outbufsize - slen, "%s:",
898                              segover);
899                 segover = NULL;
900             }
901             if (ins.oprs[i].basereg != -1) {
902                 slen += snprintf(output + slen, outbufsize - slen, "%s",
903                                  reg_names[(ins.oprs[i].basereg -
904                                             EXPR_REG_START)]);
905                 started = TRUE;
906             }
907             if (ins.oprs[i].indexreg != -1) {
908                 if (started)
909                     output[slen++] = '+';
910                 slen += snprintf(output + slen, outbufsize - slen, "%s",
911                                  reg_names[(ins.oprs[i].indexreg -
912                                             EXPR_REG_START)]);
913                 if (ins.oprs[i].scale > 1)
914                     slen +=
915                         snprintf(output + slen, outbufsize - slen, "*%d",
916                                  ins.oprs[i].scale);
917                 started = TRUE;
918             }
919             if (ins.oprs[i].segment & SEG_DISP8) {
920                 int minus = 0;
921                 int8_t offset = ins.oprs[i].offset;
922                 if (offset < 0) {
923                     minus = 1;
924                     offset = -offset;
925                 }
926                 slen +=
927                     snprintf(output + slen, outbufsize - slen, "%s0x%"PRIx8"",
928                              minus ? "-" : "+", offset);
929             } else if (ins.oprs[i].segment & SEG_DISP16) {
930                 int minus = 0;
931                 int16_t offset = ins.oprs[i].offset;
932                 if (offset < 0) {
933                     minus = 1;
934                     offset = -offset;
935                 }
936                 slen +=
937                     snprintf(output + slen, outbufsize - slen, "%s0x%"PRIx16"",
938                              minus ? "-" : started ? "+" : "", offset);
939             } else if (ins.oprs[i].segment & SEG_DISP32) {
940                     char *prefix = "";
941                     int32_t offset = ins.oprs[i].offset;
942                     if (offset < 0) {
943                         offset = -offset;
944                         prefix = "-";
945                     } else {
946                         prefix = started ? "+" : "";
947                     }
948                     slen +=
949                         snprintf(output + slen, outbufsize - slen,
950                                  "%s0x%"PRIx32"", prefix, offset);
951             }
952             output[slen++] = ']';
953         } else {
954             slen +=
955                 snprintf(output + slen, outbufsize - slen, "<operand%d>",
956                          i);
957         }
958     }
959     output[slen] = '\0';
960     if (segover) {              /* unused segment override */
961         char *p = output;
962         int count = slen + 1;
963         while (count--)
964             p[count + 3] = p[count];
965         strncpy(output, segover, 2);
966         output[2] = ' ';
967     }
968     return length;
969 }
970
971 int32_t eatbyte(uint8_t *data, char *output, int outbufsize)
972 {
973     snprintf(output, outbufsize, "db 0x%02X", *data);
974     return 1;
975 }