NASM 0.98.15
[platform/upstream/nasm.git] / assemble.c
1 /* assemble.c   code generation for the Netwide Assembler
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  * the actual codes (C syntax, i.e. octal):
9  * \0            - terminates the code. (Unless it's a literal of course.)
10  * \1, \2, \3    - that many literal bytes follow in the code stream
11  * \4, \6        - the POP/PUSH (respectively) codes for CS, DS, ES, SS
12  *                 (POP is never used for CS) depending on operand 0
13  * \5, \7        - the second byte of POP/PUSH codes for FS, GS, depending
14  *                 on operand 0
15  * \10, \11, \12 - a literal byte follows in the code stream, to be added
16  *                 to the register value of operand 0, 1 or 2
17  * \17           - encodes the literal byte 0. (Some compilers don't take
18  *                 kindly to a zero byte in the _middle_ of a compile time
19  *                 string constant, so I had to put this hack in.)
20  * \14, \15, \16 - a signed byte immediate operand, from operand 0, 1 or 2
21  * \20, \21, \22 - a byte immediate operand, from operand 0, 1 or 2
22  * \24, \25, \26 - an unsigned byte immediate operand, from operand 0, 1 or 2
23  * \30, \31, \32 - a word immediate operand, from operand 0, 1 or 2
24  * \34, \35, \36 - select between \3[012] and \4[012] depending on 16/32 bit
25  *                 assembly mode or the address-size override on the operand
26  * \37           - a word constant, from the _segment_ part of operand 0
27  * \40, \41, \42 - a long immediate operand, from operand 0, 1 or 2
28  * \50, \51, \52 - a byte relative operand, from operand 0, 1 or 2
29  * \60, \61, \62 - a word relative operand, from operand 0, 1 or 2
30  * \64, \65, \66 - select between \6[012] and \7[012] depending on 16/32 bit
31  *                 assembly mode or the address-size override on the operand
32  * \70, \71, \72 - a long relative operand, from operand 0, 1 or 2
33  * \1ab          - a ModRM, calculated on EA in operand a, with the spare
34  *                 field the register value of operand b.
35  * \130,\131,\132 - an immediate word or signed byte for operand 0, 1, or 2
36  * \133,\134,\135 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
37  *                  is a signed byte rather than a word.
38  * \140,\141,\142 - an immediate dword or signed byte for operand 0, 1, or 2
39  * \143,\144,\145 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
40  *                  is a signed byte rather than a dword.
41  * \2ab          - a ModRM, calculated on EA in operand a, with the spare
42  *                 field equal to digit b.
43  * \30x          - might be an 0x67 byte, depending on the address size of
44  *                 the memory reference in operand x.
45  * \310          - indicates fixed 16-bit address size, i.e. optional 0x67.
46  * \311          - indicates fixed 32-bit address size, i.e. optional 0x67.
47  * \312          - (disassembler only) marker on LOOP, LOOPxx instructions.
48  * \320          - indicates fixed 16-bit operand size, i.e. optional 0x66.
49  * \321          - indicates fixed 32-bit operand size, i.e. optional 0x66.
50  * \322          - indicates that this instruction is only valid when the
51  *                 operand size is the default (instruction to disassembler,
52  *                 generates no code in the assembler)
53  * \330          - a literal byte follows in the code stream, to be added
54  *                 to the condition code value of the instruction.
55  * \331          - instruction not valid with REP prefix.  Hint for
56  *                 disassembler only; for SSE instructions.
57  * \332          - disassemble a rep (0xF3 byte) prefix as repe not rep.
58  * \333          - REP prefix (0xF3 byte); for SSE instructions.  Not encoded
59  *                 as a literal byte in order to aid the disassembler.
60  * \340          - reserve <operand 0> bytes of uninitialised storage.
61  *                 Operand 0 had better be a segmentless constant.
62  * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
63  *                 370 is used for Jcc, 371 is used for JMP.
64  * \373          - assemble 0x03 if bits==16, 0x05 if bits==32;
65  *                 used for conditional jump over longer jump
66  */
67
68 #include <stdio.h>
69 #include <string.h>
70
71 #include "nasm.h"
72 #include "nasmlib.h"
73 #include "assemble.h"
74 #include "insns.h"
75
76 extern struct itemplate *nasm_instructions[];
77
78 typedef struct {
79     int sib_present;                   /* is a SIB byte necessary? */
80     int bytes;                         /* # of bytes of offset needed */
81     int size;                          /* lazy - this is sib+bytes+1 */
82     unsigned char modrm, sib;          /* the bytes themselves */
83 } ea;
84
85 static unsigned long cpu;               /* cpu level received from nasm.c */
86 static efunc errfunc;
87 static struct ofmt *outfmt;
88 static ListGen *list;
89
90 static long calcsize (long, long, int, insn *, char *);
91 static void gencode (long, long, int, insn *, char *, long);
92 static int  regval (operand *o);
93 static int  matches (struct itemplate *, insn *);
94 static ea * process_ea (operand *, ea *, int, int, int);
95 static int  chsize (operand *, int);
96
97 /*
98  * This routine wrappers the real output format's output routine,
99  * in order to pass a copy of the data off to the listing file
100  * generator at the same time.
101  */
102 static void out (long offset, long segto, void *data, unsigned long type,
103                  long segment, long wrt) 
104 {
105     long lineno;
106     char *lnfname = NULL;
107
108     if ((type & OUT_TYPMASK) == OUT_ADDRESS) {
109         if (segment != NO_SEG || wrt != NO_SEG) {
110             /*
111              * This address is relocated. We must write it as
112              * OUT_ADDRESS, so there's no work to be done here.
113              */
114             list->output (offset, data, type);
115         } 
116         else {
117             unsigned char p[4], *q = p;
118             /*
119              * This is a non-relocated address, and we're going to
120              * convert it into RAWDATA format.
121              */
122             if ((type & OUT_SIZMASK) == 4) {
123                 WRITELONG (q, * (long *) data);
124                 list->output (offset, p, OUT_RAWDATA+4);
125             } 
126             else {
127                 WRITESHORT (q, * (long *) data);
128                 list->output (offset, p, OUT_RAWDATA+2);
129             }
130         }
131     } 
132     else if ((type & OUT_TYPMASK) == OUT_RAWDATA) {
133         list->output (offset, data, type);
134     } 
135     else if ((type & OUT_TYPMASK) == OUT_RESERVE) {
136         list->output (offset, NULL, type);
137     } 
138     else if ((type & OUT_TYPMASK) == OUT_REL2ADR ||
139                (type & OUT_TYPMASK) == OUT_REL4ADR) {
140         list->output (offset, data, type);
141     }
142
143     if (src_get(&lineno,&lnfname))
144     {
145         outfmt->current_dfmt->linenum(lnfname,lineno,segto);
146         if (lnfname) nasm_free(lnfname);
147     }
148
149     outfmt->output (segto, data, type, segment, wrt);
150 }
151
152 static int jmp_match (long segment, long offset, int bits,
153                 insn *ins, char *code)
154 {   long isize;
155     unsigned char c = code[0];
156
157
158     if (c != 0370 && c != 0371) return 0;
159     if (ins->oprs[0].opflags & OPFLAG_FORWARD) {
160         if (optimizing<0 && c==0370) return 1;
161         else return (pass0==0); /* match a forward reference */
162     }
163     isize = calcsize (segment, offset, bits, ins, code);
164     if (ins->oprs[0].segment != segment) return 0;
165     isize = ins->oprs[0].offset - offset - isize;       /* isize is now the delta */
166     if (isize >= -128L && isize <= 127L) return 1;      /* it is byte size */
167
168     return 0;
169 }               
170
171
172 long assemble (long segment, long offset, int bits, unsigned long cp,
173                insn *instruction, struct ofmt *output, efunc error,
174                ListGen *listgen) 
175 {
176     struct itemplate *temp;
177     int    j;
178     int    size_prob;
179     long   insn_end;
180     long   itimes;
181     long   start = offset;
182     long   wsize = 0;                  /* size for DB etc. */
183
184     errfunc = error;                   /* to pass to other functions */
185     cpu = cp;
186     outfmt = output;                   /* likewise */
187     list = listgen;                    /* and again */
188
189     switch (instruction->opcode) 
190     {
191         case   -1: return 0;
192         case I_DB: wsize = 1; break;
193         case I_DW: wsize = 2; break;
194         case I_DD: wsize = 4; break;
195         case I_DQ: wsize = 8; break;
196         case I_DT: wsize = 10; break;
197     }
198
199     if (wsize) {
200         extop  * e;
201         long   t = instruction->times;
202         if (t < 0)
203             errfunc(ERR_PANIC, "instruction->times < 0 (%ld) in assemble()",t);
204
205         while (t--)                    /* repeat TIMES times */
206         {
207             for (e = instruction->eops; e; e = e->next) 
208             {
209                 if (e->type == EOT_DB_NUMBER) 
210                 {
211                     if (wsize == 1) {
212                         if (e->segment != NO_SEG)
213                             errfunc (ERR_NONFATAL,
214                                      "one-byte relocation attempted");
215                         else {
216                             unsigned char out_byte = e->offset;
217                             out (offset, segment, &out_byte, OUT_RAWDATA+1,
218                                  NO_SEG, NO_SEG);
219                         }
220                     } 
221                     else if (wsize > 5) {
222                         errfunc (ERR_NONFATAL, "integer supplied to a D%c"
223                                  " instruction", wsize==8 ? 'Q' : 'T');
224                     } 
225                     else
226                         out (offset, segment, &e->offset,
227                              OUT_ADDRESS+wsize, e->segment,
228                              e->wrt);
229                     offset += wsize;
230                 } 
231                 else if (e->type == EOT_DB_STRING) 
232                 {
233                     int align;
234
235                     out (offset, segment, e->stringval,
236                          OUT_RAWDATA+e->stringlen, NO_SEG, NO_SEG);
237                     align = e->stringlen % wsize;
238
239                     if (align) {
240                         align = wsize - align;
241                         out (offset, segment, "\0\0\0\0\0\0\0\0",
242                              OUT_RAWDATA+align, NO_SEG, NO_SEG);
243                         }
244                     offset += e->stringlen + align;
245                 }
246             }
247             if (t > 0 && t == instruction->times-1) 
248             {
249                 /*
250                  * Dummy call to list->output to give the offset to the
251                  * listing module.
252                  */
253                 list->output (offset, NULL, OUT_RAWDATA);
254                 list->uplevel (LIST_TIMES);
255             }
256         }
257         if (instruction->times > 1)
258             list->downlevel (LIST_TIMES);
259         return offset - start;
260     }
261
262     if (instruction->opcode == I_INCBIN) 
263     {
264         static char fname[FILENAME_MAX];
265         FILE        * fp;
266         long        len;
267
268         len = FILENAME_MAX-1;
269         if (len > instruction->eops->stringlen)
270             len = instruction->eops->stringlen;
271         strncpy (fname, instruction->eops->stringval, len);
272         fname[len] = '\0';
273
274         if ( (fp = fopen(fname, "rb")) == NULL)
275             error (ERR_NONFATAL, "`incbin': unable to open file `%s'", fname);
276         else if (fseek(fp, 0L, SEEK_END) < 0)
277             error (ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
278                    fname);
279         else 
280         {
281             static char buf[2048];
282             long t = instruction->times;
283             long base = 0;
284
285             len = ftell (fp);
286             if (instruction->eops->next) {
287                 base = instruction->eops->next->offset;
288                 len -= base;
289                 if (instruction->eops->next->next &&
290                     len > instruction->eops->next->next->offset)
291                     len = instruction->eops->next->next->offset;
292             }
293             /*
294              * Dummy call to list->output to give the offset to the
295              * listing module.
296              */
297             list->output (offset, NULL, OUT_RAWDATA);
298             list->uplevel(LIST_INCBIN);
299             while (t--) 
300             {
301                 long l;
302
303                 fseek (fp, base, SEEK_SET);             
304                 l = len;
305                 while (l > 0) {
306                     long m = fread (buf, 1, (l>sizeof(buf)?sizeof(buf):l),
307                                     fp);
308                     if (!m) {
309                         /*
310                          * This shouldn't happen unless the file
311                          * actually changes while we are reading
312                          * it.
313                          */
314                         error (ERR_NONFATAL, "`incbin': unexpected EOF while"
315                                " reading file `%s'", fname);
316                         t=0;  /* Try to exit cleanly */
317                         break;
318                     }
319                     out (offset, segment, buf, OUT_RAWDATA+m,
320                          NO_SEG, NO_SEG);
321                     l -= m;
322                 }
323             }
324             list->downlevel(LIST_INCBIN);
325             if (instruction->times > 1) {
326                 /*
327                  * Dummy call to list->output to give the offset to the
328                  * listing module.
329                  */
330                 list->output (offset, NULL, OUT_RAWDATA);
331                 list->uplevel(LIST_TIMES);
332                 list->downlevel(LIST_TIMES);
333             }
334             fclose (fp);
335             return instruction->times * len;
336         }
337         return 0;                      /* if we're here, there's an error */
338     }
339
340     size_prob = FALSE;
341     temp = nasm_instructions[instruction->opcode];
342     while (temp->opcode != -1) {
343         int m = matches (temp, instruction);
344         if (m == 99)
345             m += jmp_match(segment, offset, bits, instruction, temp->code);
346
347         if (m == 100)                  /* matches! */
348         {
349             char *codes = temp->code;
350             long insn_size = calcsize(segment, offset, bits,
351                                       instruction, codes);
352             itimes = instruction->times;
353             if (insn_size < 0)         /* shouldn't be, on pass two */
354                 error (ERR_PANIC, "errors made it through from pass one");
355             else while (itimes--) {
356                 insn_end = offset + insn_size;
357                 for (j=0; j<instruction->nprefix; j++) {
358                     unsigned char c=0;
359                     switch (instruction->prefixes[j]) {
360                       case P_LOCK:
361                         c = 0xF0; break;
362                       case P_REPNE: case P_REPNZ:
363                         c = 0xF2; break;
364                       case P_REPE: case P_REPZ: case P_REP:
365                         c = 0xF3; break;
366                       case R_CS: c = 0x2E; break;
367                       case R_DS: c = 0x3E; break;
368                       case R_ES: c = 0x26; break;
369                       case R_FS: c = 0x64; break;
370                       case R_GS: c = 0x65; break;
371                       case R_SS: c = 0x36; break;
372                       case P_A16:
373                         if (bits != 16)
374                             c = 0x67;
375                         break;
376                       case P_A32:
377                         if (bits != 32)
378                             c = 0x67;
379                         break;
380                       case P_O16:
381                         if (bits != 16)
382                             c = 0x66;
383                         break;
384                       case P_O32:
385                         if (bits != 32)
386                             c = 0x66;
387                         break;
388                       default:
389                         error (ERR_PANIC,
390                                "invalid instruction prefix");
391                     }
392                     if (c != 0) {
393                         out (offset, segment, &c, OUT_RAWDATA+1,
394                              NO_SEG, NO_SEG);
395                         offset++;
396                     }
397                 }
398                 gencode (segment, offset, bits, instruction, codes, insn_end);
399                 offset += insn_size;
400                 if (itimes > 0 && itimes == instruction->times-1) {
401                     /*
402                      * Dummy call to list->output to give the offset to the
403                      * listing module.
404                      */
405                     list->output (offset, NULL, OUT_RAWDATA);
406                     list->uplevel (LIST_TIMES);
407                 }
408             }
409             if (instruction->times > 1)
410                 list->downlevel (LIST_TIMES);
411             return offset - start;
412         } else if (m > 0  &&  m > size_prob) {
413             size_prob = m;
414         }
415         temp++;
416     }
417
418     if (temp->opcode == -1) {          /* didn't match any instruction */
419         if (size_prob == 1)            /* would have matched, but for size */
420             error (ERR_NONFATAL, "operation size not specified");
421         else if (size_prob == 2)
422             error (ERR_NONFATAL, "mismatch in operand sizes");
423         else if (size_prob == 3)
424             error (ERR_NONFATAL, "no instruction for this cpu level");
425         else
426             error (ERR_NONFATAL,
427                    "invalid combination of opcode and operands");
428     }
429     return 0;
430 }
431
432 long insn_size (long segment, long offset, int bits, unsigned long cp,
433                 insn *instruction, efunc error) 
434 {
435     struct itemplate *temp;
436
437     errfunc = error;                   /* to pass to other functions */
438     cpu = cp;
439
440     if (instruction->opcode == -1)
441         return 0;
442
443     if (instruction->opcode == I_DB ||
444         instruction->opcode == I_DW ||
445         instruction->opcode == I_DD ||
446         instruction->opcode == I_DQ ||
447         instruction->opcode == I_DT) 
448     {
449         extop *e;
450         long isize, osize, wsize = 0;  /* placate gcc */
451
452         isize = 0;
453         switch (instruction->opcode) 
454         {
455           case I_DB: wsize = 1; break;
456           case I_DW: wsize = 2; break;
457           case I_DD: wsize = 4; break;
458           case I_DQ: wsize = 8; break;
459           case I_DT: wsize = 10; break;
460         }
461
462         for (e = instruction->eops; e; e = e->next) 
463         {
464             long align;
465
466             osize = 0;
467             if (e->type == EOT_DB_NUMBER)
468                 osize = 1;
469             else if (e->type == EOT_DB_STRING)
470                 osize = e->stringlen;
471
472             align = (-osize) % wsize;
473             if (align < 0)
474                 align += wsize;
475             isize += osize + align;
476         }
477         return isize * instruction->times;
478     }
479
480     if (instruction->opcode == I_INCBIN) 
481     {
482         char  fname[FILENAME_MAX];
483         FILE  * fp;
484         long  len;
485
486         len = FILENAME_MAX-1;
487         if (len > instruction->eops->stringlen)
488             len = instruction->eops->stringlen;
489         strncpy (fname, instruction->eops->stringval, len);
490         fname[len] = '\0';
491         if ( (fp = fopen(fname, "rb")) == NULL )
492             error (ERR_NONFATAL, "`incbin': unable to open file `%s'", fname);
493         else if (fseek(fp, 0L, SEEK_END) < 0)
494             error (ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
495                    fname);
496         else 
497         {
498             len = ftell (fp);
499             fclose (fp);
500             if (instruction->eops->next) 
501             {
502                 len -= instruction->eops->next->offset;
503                 if (instruction->eops->next->next &&
504                     len > instruction->eops->next->next->offset)
505                 {
506                     len = instruction->eops->next->next->offset;
507                 }
508             }
509             return instruction->times * len;
510         }
511         return 0;                      /* if we're here, there's an error */
512     }
513
514     temp = nasm_instructions[instruction->opcode];
515     while (temp->opcode != -1) {
516         int m = matches(temp, instruction);
517         if (m == 99)
518             m += jmp_match(segment, offset, bits, instruction, temp->code);
519         
520         if (m == 100) {
521             /* we've matched an instruction. */
522             long  isize;
523             char  * codes = temp->code;
524             int   j;
525
526             isize = calcsize(segment, offset, bits, instruction, codes);
527             if (isize < 0)
528                 return -1;
529             for (j = 0; j < instruction->nprefix; j++) 
530             {
531                 if ((instruction->prefixes[j] != P_A16 &&
532                      instruction->prefixes[j] != P_O16 && bits==16) ||
533                     (instruction->prefixes[j] != P_A32 &&
534                      instruction->prefixes[j] != P_O32 && bits==32))
535                 {
536                     isize++;
537                 }
538             }
539             return isize * instruction->times;
540         }
541         temp++;
542     }
543     return -1;                         /* didn't match any instruction */
544 }
545
546
547 /* check that  opn[op]  is a signed byte of size 16 or 32,
548                                         and return the signed value*/
549 static int is_sbyte (insn *ins, int op, int size)
550 {
551     signed long v;
552     int ret;
553     
554     ret = !(ins->forw_ref && ins->oprs[op].opflags ) && /* dead in the water on forward reference or External */
555           (optimizing>0 || !(ins->oprs[op].type & (BITS16|BITS32))) &&
556           ins->oprs[op].wrt==NO_SEG && ins->oprs[op].segment==NO_SEG;
557
558     v = ins->oprs[op].offset;
559     if (size==16) v = (signed short)v;   /* sign extend if 16 bits */
560     
561     return ret && v>=-128L && v<=127L;
562 }
563
564 static long calcsize (long segment, long offset, int bits,
565                       insn *ins, char *codes) 
566 {
567     long           length = 0;
568     unsigned char  c;
569
570     (void) segment;  /* Don't warn that this parameter is unused */
571     (void) offset;   /* Don't warn that this parameter is unused */
572
573     while (*codes) switch (c = *codes++) {
574       case 01: case 02: case 03:
575         codes += c, length += c; break;
576       case 04: case 05: case 06: case 07:
577         length++; break;
578       case 010: case 011: case 012:
579         codes++, length++; break;
580       case 017:
581         length++; break;
582       case 014: case 015: case 016:
583         length++; break;
584       case 020: case 021: case 022:
585         length++; break;
586       case 024: case 025: case 026:
587         length++; break;
588       case 030: case 031: case 032:
589         length += 2; break;
590       case 034: case 035: case 036:
591         length += ((ins->oprs[c-034].addr_size ?
592                     ins->oprs[c-034].addr_size : bits) == 16 ? 2 : 4); break;
593       case 037:
594         length += 2; break;
595       case 040: case 041: case 042:
596         length += 4; break;
597       case 050: case 051: case 052:
598         length++; break;
599       case 060: case 061: case 062:
600         length += 2; break;
601       case 064: case 065: case 066:
602         length += ((ins->oprs[c-064].addr_size ?
603                     ins->oprs[c-064].addr_size : bits) == 16 ? 2 : 4); break;
604       case 070: case 071: case 072:
605         length += 4; break;
606       case 0130: case 0131: case 0132:          
607         length += is_sbyte(ins, c-0130, 16) ? 1 : 2; break;
608       case 0133: case 0134: case 0135:
609         codes+=2; length++; break;
610       case 0140: case 0141: case 0142:
611         length += is_sbyte(ins, c-0140, 32) ? 1 : 4; break;
612       case 0143: case 0144: case 0145:
613         codes+=2; length++; break;
614       case 0300: case 0301: case 0302:
615         length += chsize (&ins->oprs[c-0300], bits);
616         break;
617       case 0310:
618         length += (bits==32);
619         break;
620       case 0311:
621         length += (bits==16);
622         break;
623       case 0312:
624         break;
625       case 0320:
626         length += (bits==32);
627         break;
628       case 0321:
629         length += (bits==16);
630         break;
631       case 0322:
632         break;
633       case 0330:
634         codes++, length++; break;
635       case 0331:
636       case 0332:
637         break;
638       case 0333:
639         length++; break;
640       case 0340: case 0341: case 0342:
641         if (ins->oprs[0].segment != NO_SEG)
642             errfunc (ERR_NONFATAL, "attempt to reserve non-constant"
643                      " quantity of BSS space");
644         else
645             length += ins->oprs[0].offset << (c-0340);
646         break;
647       case 0370: case 0371: case 0372:
648         break;
649       case 0373:
650         length++; break;
651       default:                         /* can't do it by 'case' statements */
652         if (c>=0100 && c<=0277) {      /* it's an EA */
653             ea ea_data;
654             if (!process_ea (&ins->oprs[(c>>3)&7], &ea_data, bits, 0,
655                              ins->forw_ref)) {
656                 errfunc (ERR_NONFATAL, "invalid effective address");
657                 return -1;
658             } else
659                 length += ea_data.size;
660         } else
661             errfunc (ERR_PANIC, "internal instruction table corrupt"
662                      ": instruction code 0x%02X given", c);
663     }
664     return length;
665 }
666
667 static void gencode (long segment, long offset, int bits,
668                      insn *ins, char *codes, long insn_end) 
669 {
670     static char condval[] = { /* conditional opcodes */
671         0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
672         0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
673         0x0, 0xA, 0xA, 0xB, 0x8, 0x4
674     };
675     unsigned char c;
676     unsigned char bytes[4];
677     long          data, size;
678
679     while (*codes)
680         switch (c = *codes++) 
681         {
682         case 01: case 02: case 03:
683             out (offset, segment, codes, OUT_RAWDATA+c, NO_SEG, NO_SEG);
684             codes += c;
685             offset += c;
686             break;
687
688         case 04: case 06:
689             switch (ins->oprs[0].basereg) 
690             {
691             case R_CS: 
692                 bytes[0] = 0x0E + (c == 0x04 ? 1 : 0); break;
693             case R_DS: 
694                 bytes[0] = 0x1E + (c == 0x04 ? 1 : 0); break;
695             case R_ES: 
696                 bytes[0] = 0x06 + (c == 0x04 ? 1 : 0); break;
697             case R_SS: 
698                 bytes[0] = 0x16 + (c == 0x04 ? 1 : 0); break;
699             default:
700                 errfunc (ERR_PANIC, "bizarre 8086 segment register received");
701             }
702             out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
703             offset++;
704             break;
705
706         case 05: case 07:
707             switch (ins->oprs[0].basereg) {
708             case R_FS: bytes[0] = 0xA0 + (c == 0x05 ? 1 : 0); break;
709             case R_GS: bytes[0] = 0xA8 + (c == 0x05 ? 1 : 0); break;
710             default:
711                 errfunc (ERR_PANIC, "bizarre 386 segment register received");
712             }
713             out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
714             offset++;
715             break;
716
717         case 010: case 011: case 012:
718             bytes[0] = *codes++ + regval(&ins->oprs[c-010]);
719             out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
720             offset += 1;
721             break;
722
723         case 017:
724             bytes[0] = 0;
725             out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
726             offset += 1;
727             break;
728
729         case 014: case 015: case 016:
730             if (ins->oprs[c-014].offset < -128 
731                 || ins->oprs[c-014].offset > 127)
732             {
733                 errfunc (ERR_WARNING, "signed byte value exceeds bounds");
734             }
735
736             if (ins->oprs[c-014].segment != NO_SEG) 
737             {
738                 data = ins->oprs[c-014].offset;
739                 out (offset, segment, &data, OUT_ADDRESS+1,
740                      ins->oprs[c-014].segment, ins->oprs[c-014].wrt);
741             } 
742             else {
743                 bytes[0] = ins->oprs[c-014].offset;
744                 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
745             }
746             offset += 1;
747             break;
748
749         case 020: case 021: case 022:
750             if (ins->oprs[c-020].offset < -256 
751                 || ins->oprs[c-020].offset > 255)
752             {
753                 errfunc (ERR_WARNING, "byte value exceeds bounds");
754             }
755             if (ins->oprs[c-020].segment != NO_SEG) {
756                 data = ins->oprs[c-020].offset;
757                 out (offset, segment, &data, OUT_ADDRESS+1,
758                      ins->oprs[c-020].segment, ins->oprs[c-020].wrt);
759             } 
760             else {
761                 bytes[0] = ins->oprs[c-020].offset;
762                 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
763             }
764             offset += 1;
765             break;
766         
767         case 024: case 025: case 026:
768             if (ins->oprs[c-024].offset < 0 || ins->oprs[c-024].offset > 255)
769                 errfunc (ERR_WARNING, "unsigned byte value exceeds bounds");
770             if (ins->oprs[c-024].segment != NO_SEG) {
771                 data = ins->oprs[c-024].offset;
772                 out (offset, segment, &data, OUT_ADDRESS+1,
773                      ins->oprs[c-024].segment, ins->oprs[c-024].wrt);
774             }
775             else {
776                 bytes[0] = ins->oprs[c-024].offset;
777                 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
778             }
779             offset += 1;
780             break;
781
782         case 030: case 031: case 032:
783             if (ins->oprs[c-030].segment == NO_SEG &&
784                 ins->oprs[c-030].wrt == NO_SEG &&
785                 (ins->oprs[c-030].offset < -65536L ||
786                  ins->oprs[c-030].offset > 65535L))
787             {
788                 errfunc (ERR_WARNING, "word value exceeds bounds");
789             }
790             data = ins->oprs[c-030].offset;
791             out (offset, segment, &data, OUT_ADDRESS+2,
792                  ins->oprs[c-030].segment, ins->oprs[c-030].wrt);
793             offset += 2;
794             break;
795
796         case 034: case 035: case 036:
797             data = ins->oprs[c-034].offset;
798             size = ((ins->oprs[c-034].addr_size ?
799                      ins->oprs[c-034].addr_size : bits) == 16 ? 2 : 4);
800             if (size==2 && (data < -65536L || data > 65535L))
801                 errfunc (ERR_WARNING, "word value exceeds bounds");
802             out (offset, segment, &data, OUT_ADDRESS+size,
803                  ins->oprs[c-034].segment, ins->oprs[c-034].wrt);
804             offset += size;
805             break;
806
807         case 037:
808             if (ins->oprs[0].segment == NO_SEG)
809                 errfunc (ERR_NONFATAL, "value referenced by FAR is not"
810                          " relocatable");
811             data = 0L;
812             out (offset, segment, &data, OUT_ADDRESS+2,
813                  outfmt->segbase(1+ins->oprs[0].segment),
814                  ins->oprs[0].wrt);
815             offset += 2;
816                 break;
817
818         case 040: case 041: case 042:
819             data = ins->oprs[c-040].offset;
820             out (offset, segment, &data, OUT_ADDRESS+4,
821                  ins->oprs[c-040].segment, ins->oprs[c-040].wrt);
822             offset += 4;
823             break;
824
825         case 050: case 051: case 052:
826             if (ins->oprs[c-050].segment != segment)
827                 errfunc (ERR_NONFATAL, "short relative jump outside segment");
828             data = ins->oprs[c-050].offset - insn_end;
829             if (data > 127 || data < -128)
830                 errfunc (ERR_NONFATAL, "short jump is out of range");
831             bytes[0] = data;
832             out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
833             offset += 1;
834             break;
835
836         case 060: case 061: case 062:
837             if (ins->oprs[c-060].segment != segment) {
838                 data = ins->oprs[c-060].offset;
839                 out (offset, segment, &data, OUT_REL2ADR+insn_end-offset,
840                      ins->oprs[c-060].segment, ins->oprs[c-060].wrt);
841             } else {
842                 data = ins->oprs[c-060].offset - insn_end;
843                 out (offset, segment, &data,
844                      OUT_ADDRESS+2, NO_SEG, NO_SEG);
845             }
846             offset += 2;
847             break;
848
849         case 064: case 065: case 066:
850             size = ((ins->oprs[c-064].addr_size ?
851                      ins->oprs[c-064].addr_size : bits) == 16 ? 2 : 4);
852             if (ins->oprs[c-064].segment != segment) {
853                 data = ins->oprs[c-064].offset;
854                 size = (bits == 16 ? OUT_REL2ADR : OUT_REL4ADR);
855                 out (offset, segment, &data, size+insn_end-offset,
856                      ins->oprs[c-064].segment, ins->oprs[c-064].wrt);
857                 size = (bits == 16 ? 2 : 4);
858             } else {
859                 data = ins->oprs[c-064].offset - insn_end;
860                 out (offset, segment, &data,
861                      OUT_ADDRESS+size, NO_SEG, NO_SEG);
862             }
863             offset += size;
864             break;
865
866         case 070: case 071: case 072:
867             if (ins->oprs[c-070].segment != segment) {
868                 data = ins->oprs[c-070].offset;
869                 out (offset, segment, &data, OUT_REL4ADR+insn_end-offset,
870                      ins->oprs[c-070].segment, ins->oprs[c-070].wrt);
871             } else {
872                 data = ins->oprs[c-070].offset - insn_end;
873                 out (offset, segment, &data,
874                      OUT_ADDRESS+4, NO_SEG, NO_SEG);
875             }
876             offset += 4;
877             break;
878
879         case 0130: case 0131: case 0132:
880             data = ins->oprs[c-0130].offset;
881             if (is_sbyte(ins, c-0130, 16)) {
882                 out (offset, segment, &data, OUT_RAWDATA+1, NO_SEG, NO_SEG);
883                 offset++;
884             } else {
885                 if (ins->oprs[c-0130].segment == NO_SEG &&
886                         ins->oprs[c-0130].wrt == NO_SEG &&
887                         (data < -65536L || data > 65535L)) {
888                     errfunc (ERR_WARNING, "word value exceeds bounds");
889                 }    
890                 out (offset, segment, &data, OUT_ADDRESS+2,
891                           ins->oprs[c-0130].segment, ins->oprs[c-0130].wrt);
892                 offset += 2;
893             }
894             break;
895
896         case 0133: case 0134: case 0135:
897             codes++;
898             bytes[0] = *codes++;
899             if (is_sbyte(ins, c-0133, 16)) bytes[0] |= 2;   /* s-bit */
900             out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
901             offset++;
902             break;
903                 
904         case 0140: case 0141: case 0142:
905             data = ins->oprs[c-0140].offset;
906             if (is_sbyte(ins, c-0140, 32)) {
907                 out (offset, segment, &data, OUT_RAWDATA+1, NO_SEG, NO_SEG);
908                 offset++;
909             } else {
910                 out (offset, segment, &data, OUT_ADDRESS+4,
911                           ins->oprs[c-0140].segment, ins->oprs[c-0140].wrt);
912                 offset += 4;
913             }
914             break;
915
916         case 0143: case 0144: case 0145:
917             codes++;
918             bytes[0] = *codes++;
919             if (is_sbyte(ins, c-0143, 32)) bytes[0] |= 2;   /* s-bit */
920             out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
921             offset++;
922             break;
923                     
924         case 0300: case 0301: case 0302:
925             if (chsize (&ins->oprs[c-0300], bits)) {
926                 *bytes = 0x67;
927                 out (offset, segment, bytes,
928                      OUT_RAWDATA+1, NO_SEG, NO_SEG);
929                 offset += 1;
930             } else
931                 offset += 0;
932             break;
933
934         case 0310:
935             if (bits==32) {
936                 *bytes = 0x67;
937                 out (offset, segment, bytes,
938                      OUT_RAWDATA+1, NO_SEG, NO_SEG);
939                 offset += 1;
940             } else
941                 offset += 0;
942             break;
943
944         case 0311:
945             if (bits==16) {
946                 *bytes = 0x67;
947                 out (offset, segment, bytes,
948                      OUT_RAWDATA+1, NO_SEG, NO_SEG);
949                 offset += 1;
950             } else
951                 offset += 0;
952             break;
953
954         case 0312:
955             break;
956
957         case 0320:
958             if (bits==32) {
959                 *bytes = 0x66;
960                 out (offset, segment, bytes,
961                      OUT_RAWDATA+1, NO_SEG, NO_SEG);
962                 offset += 1;
963             } else
964                 offset += 0;
965             break;
966
967         case 0321:
968             if (bits==16) {
969                 *bytes = 0x66;
970                 out (offset, segment, bytes,
971                      OUT_RAWDATA+1, NO_SEG, NO_SEG);
972                 offset += 1;
973             } else
974                 offset += 0;
975             break;
976
977         case 0322:
978             break;
979
980         case 0330:
981             *bytes = *codes++ ^ condval[ins->condition];
982             out (offset, segment, bytes,
983                  OUT_RAWDATA+1, NO_SEG, NO_SEG);
984             offset += 1;
985             break;
986
987         case 0331:
988         case 0332:
989             break;
990
991         case 0333:
992             *bytes = 0xF3;
993             out (offset, segment, bytes,
994                  OUT_RAWDATA+1, NO_SEG, NO_SEG);
995             offset += 1;
996             break;
997
998         case 0340: case 0341: case 0342:
999             if (ins->oprs[0].segment != NO_SEG)
1000                 errfunc (ERR_PANIC, "non-constant BSS size in pass two");
1001             else {
1002                 long size = ins->oprs[0].offset << (c-0340);
1003                 if (size > 0)
1004                     out (offset, segment, NULL,
1005                          OUT_RESERVE+size, NO_SEG, NO_SEG);
1006                 offset += size;
1007             }
1008             break;
1009
1010         case 0370: case 0371: case 0372:
1011             break;
1012         
1013         case 0373:
1014             *bytes = bits==16 ? 3 : 5;
1015             out (offset, segment, bytes,
1016                  OUT_RAWDATA+1, NO_SEG, NO_SEG);
1017             offset += 1;
1018             break;
1019
1020         default:                       /* can't do it by 'case' statements */
1021             if (c>=0100 && c<=0277) {      /* it's an EA */
1022                 ea ea_data;
1023                 int rfield;
1024                 unsigned char *p;
1025                 long s;
1026
1027                 if (c<=0177)           /* pick rfield from operand b */
1028                     rfield = regval (&ins->oprs[c&7]);
1029                 else                   /* rfield is constant */
1030                     rfield = c & 7;
1031
1032                 if (!process_ea (&ins->oprs[(c>>3)&7], &ea_data, bits, rfield,
1033                                  ins->forw_ref))
1034                 {
1035                     errfunc (ERR_NONFATAL, "invalid effective address");
1036                 }
1037
1038                 p = bytes;
1039                 *p++ = ea_data.modrm;
1040                 if (ea_data.sib_present)
1041                     *p++ = ea_data.sib;
1042
1043                 s = p-bytes;
1044                 out (offset, segment, bytes, OUT_RAWDATA + s,
1045                      NO_SEG, NO_SEG);
1046
1047                 switch (ea_data.bytes) {
1048                 case 0:
1049                     break;
1050                 case 1:
1051                     if (ins->oprs[(c>>3)&7].segment != NO_SEG) {
1052                         data = ins->oprs[(c>>3)&7].offset;
1053                         out (offset, segment, &data, OUT_ADDRESS+1,
1054                              ins->oprs[(c>>3)&7].segment,
1055                              ins->oprs[(c>>3)&7].wrt);
1056                     } else {
1057                         *bytes = ins->oprs[(c>>3)&7].offset;
1058                         out (offset, segment, bytes, OUT_RAWDATA+1,
1059                              NO_SEG, NO_SEG);
1060                     }
1061                     s++;
1062                     break;
1063                 case 2:
1064                 case 4:
1065                     data = ins->oprs[(c>>3)&7].offset;
1066                     out (offset, segment, &data,
1067                          OUT_ADDRESS+ea_data.bytes,
1068                          ins->oprs[(c>>3)&7].segment, ins->oprs[(c>>3)&7].wrt);
1069                     s += ea_data.bytes;
1070                     break;
1071                 }
1072                 offset += s;
1073             } else
1074                 errfunc (ERR_PANIC, "internal instruction table corrupt"
1075                      ": instruction code 0x%02X given", c);
1076         }
1077 }
1078
1079 static int regval (operand *o) 
1080 {
1081     switch (o->basereg) {
1082       case R_EAX: case R_AX: case R_AL: case R_ES: case R_CR0: case R_DR0:
1083       case R_ST0: case R_MM0: case R_XMM0:
1084         return 0;
1085       case R_ECX: case R_CX: case R_CL: case R_CS: case R_DR1: case R_ST1:
1086       case R_MM1: case R_XMM1:
1087         return 1;
1088       case R_EDX: case R_DX: case R_DL: case R_SS: case R_CR2: case R_DR2:
1089       case R_ST2: case R_MM2:  case R_XMM2:
1090         return 2;
1091       case R_EBX: case R_BX: case R_BL: case R_DS: case R_CR3: case R_DR3:
1092       case R_TR3: case R_ST3: case R_MM3:  case R_XMM3:
1093         return 3;
1094       case R_ESP: case R_SP: case R_AH: case R_FS: case R_CR4: case R_TR4:
1095       case R_ST4: case R_MM4:  case R_XMM4:
1096         return 4;
1097       case R_EBP: case R_BP: case R_CH: case R_GS: case R_TR5: case R_ST5:
1098       case R_MM5:  case R_XMM5:
1099         return 5;
1100       case R_ESI: case R_SI: case R_DH: case R_DR6: case R_TR6: case R_ST6:
1101       case R_MM6:  case R_XMM6:
1102         return 6;
1103       case R_EDI: case R_DI: case R_BH: case R_DR7: case R_TR7: case R_ST7:
1104       case R_MM7:  case R_XMM7:
1105         return 7;
1106       default:                         /* panic */
1107         errfunc (ERR_PANIC, "invalid register operand given to regval()");
1108         return 0;
1109     }
1110 }
1111
1112 static int matches (struct itemplate *itemp, insn *instruction) 
1113 {
1114     int i, size[3], asize, oprs, ret;
1115
1116     ret = 100;
1117
1118     /*
1119      * Check the opcode
1120      */
1121     if (itemp->opcode != instruction->opcode) return 0;
1122
1123     /*
1124      * Count the operands
1125      */
1126     if (itemp->operands != instruction->operands) return 0;
1127
1128     /*
1129      * Check that no spurious colons or TOs are present
1130      */
1131     for (i=0; i<itemp->operands; i++)
1132         if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON|TO))
1133             return 0;
1134
1135     /*
1136      * Check that the operand flags all match up
1137      */
1138     for (i=0; i<itemp->operands; i++)
1139         if (itemp->opd[i] & ~instruction->oprs[i].type ||
1140             ((itemp->opd[i] & SIZE_MASK) &&
1141              ((itemp->opd[i] ^ instruction->oprs[i].type) & SIZE_MASK)))
1142         {
1143             if ((itemp->opd[i] & ~instruction->oprs[i].type & NON_SIZE) ||
1144                 (instruction->oprs[i].type & SIZE_MASK))
1145                 return 0;
1146             else
1147 /*              ret = 1;   */
1148                 return 1;
1149         }
1150
1151     /*
1152      * Check operand sizes
1153      */
1154     if (itemp->flags & IF_ARMASK) {
1155       size[0] = size[1] = size[2] = 0;
1156
1157       switch (itemp->flags & IF_ARMASK) {
1158       case IF_AR0: i = 0; break;
1159       case IF_AR1: i = 1; break;
1160       case IF_AR2: i = 2; break;
1161       default:     break;       /* Shouldn't happen */
1162       }
1163       if (itemp->flags & IF_SB) {
1164         size[i] = BITS8;
1165       } else if (itemp->flags & IF_SW) {
1166         size[i] = BITS16;
1167       } else if (itemp->flags & IF_SD) {
1168         size[i] = BITS32;
1169       }
1170     } else {
1171       asize = 0;
1172       if (itemp->flags & IF_SB) {
1173         asize = BITS8;
1174         oprs = itemp->operands;
1175       } else if (itemp->flags & IF_SW) {
1176         asize = BITS16;
1177         oprs = itemp->operands;
1178       } else if (itemp->flags & IF_SD) {
1179         asize = BITS32;
1180         oprs = itemp->operands;
1181       }
1182       size[0] = size[1] = size[2] = asize;
1183     }
1184
1185     if (itemp->flags & (IF_SM | IF_SM2)) {
1186       oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands);
1187       asize = 0;
1188       for (i=0; i<oprs; i++) {
1189         if ( (asize = itemp->opd[i] & SIZE_MASK) != 0) {
1190           int j;
1191           for (j=0; j<oprs; j++)
1192             size[j] = asize;
1193           break;
1194         }
1195       }
1196     } else {
1197       oprs = itemp->operands;
1198     }
1199
1200     for (i=0; i<itemp->operands; i++)
1201         if (!(itemp->opd[i] & SIZE_MASK) &&
1202             (instruction->oprs[i].type & SIZE_MASK & ~size[i]))
1203 /*          ret = 2;  */
1204             return 2;
1205
1206     /*
1207      * Check template is okay at the set cpu level
1208      */
1209     if ((itemp->flags & IF_PLEVEL) > cpu) return 3;
1210     
1211     /*
1212      * Check if special handling needed for Jumps
1213      */
1214     if ((unsigned char)(itemp->code[0]) >= 0370) return 99;
1215      
1216     return ret;
1217 }
1218
1219 static ea *process_ea (operand *input, ea *output, int addrbits, int rfield,
1220                        int forw_ref) 
1221 {
1222     if (!(REGISTER & ~input->type)) {  /* it's a single register */
1223         static int regs[] = {
1224           R_AL,   R_CL,   R_DL,   R_BL,   R_AH,   R_CH,   R_DH,   R_BH,
1225           R_AX,   R_CX,   R_DX,   R_BX,   R_SP,   R_BP,   R_SI,   R_DI,
1226           R_EAX,  R_ECX,  R_EDX,  R_EBX,  R_ESP,  R_EBP,  R_ESI,  R_EDI,
1227           R_MM0,  R_MM1,  R_MM2,  R_MM3,  R_MM4,  R_MM5,  R_MM6,  R_MM7,
1228           R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7
1229         };
1230         int i;
1231
1232         for (i=0; i<elements(regs); i++)
1233             if (input->basereg == regs[i]) break;
1234         if (i<elements(regs)) {
1235             output->sib_present = FALSE;/* no SIB necessary */
1236             output->bytes = 0;         /* no offset necessary either */
1237             output->modrm = 0xC0 | (rfield << 3) | (i & 7);
1238         } 
1239         else
1240             return NULL;
1241     } else {                           /* it's a memory reference */
1242         if (input->basereg==-1 && (input->indexreg==-1 || input->scale==0)) {
1243             /* it's a pure offset */
1244             if (input->addr_size)
1245                 addrbits = input->addr_size;
1246             output->sib_present = FALSE;
1247             output->bytes = (addrbits==32 ? 4 : 2);
1248             output->modrm = (addrbits==32 ? 5 : 6) | (rfield << 3);
1249         } 
1250         else {                 /* it's an indirection */
1251             int i=input->indexreg, b=input->basereg, s=input->scale;
1252             long o=input->offset, seg=input->segment;
1253             int hb=input->hintbase, ht=input->hinttype;
1254             int t;
1255
1256             if (s==0) i = -1;          /* make this easy, at least */
1257
1258             if (i==R_EAX || i==R_EBX || i==R_ECX || i==R_EDX
1259                 || i==R_EBP || i==R_ESP || i==R_ESI || i==R_EDI
1260                 || b==R_EAX || b==R_EBX || b==R_ECX || b==R_EDX
1261                 || b==R_EBP || b==R_ESP || b==R_ESI || b==R_EDI) {
1262                 /* it must be a 32-bit memory reference. Firstly we have
1263                  * to check that all registers involved are type Exx. */
1264                 if (i!=-1 && i!=R_EAX && i!=R_EBX && i!=R_ECX && i!=R_EDX
1265                     && i!=R_EBP && i!=R_ESP && i!=R_ESI && i!=R_EDI)
1266                     return NULL;
1267                 if (b!=-1 && b!=R_EAX && b!=R_EBX && b!=R_ECX && b!=R_EDX
1268                     && b!=R_EBP && b!=R_ESP && b!=R_ESI && b!=R_EDI)
1269                     return NULL;
1270
1271                 /* While we're here, ensure the user didn't specify WORD. */
1272                 if (input->addr_size == 16)
1273                     return NULL;
1274
1275                 /* now reorganise base/index */
1276                 if (s == 1 && b != i && b != -1 && i != -1 &&
1277                     ((hb==b&&ht==EAH_NOTBASE) || (hb==i&&ht==EAH_MAKEBASE)))
1278                     t = b, b = i, i = t;   /* swap if hints say so */
1279                 if (b==i)              /* convert EAX+2*EAX to 3*EAX */
1280                     b = -1, s++;
1281                 if (b==-1 && s==1 && !(hb == i && ht == EAH_NOTBASE))
1282                     b = i, i = -1;     /* make single reg base, unless hint */
1283                 if (((s==2 && i!=R_ESP && !(input->eaflags & EAF_TIMESTWO)) ||
1284                      s==3 || s==5 || s==9) && b==-1)
1285                     b = i, s--;       /* convert 3*EAX to EAX+2*EAX */
1286                 if (s==1 && i==R_ESP)  /* swap ESP into base if scale is 1 */
1287                     i = b, b = R_ESP;
1288                 if (i==R_ESP || (s!=1 && s!=2 && s!=4 && s!=8 && i!=-1))
1289                     return NULL;      /* wrong, for various reasons */
1290
1291                 if (i==-1 && b!=R_ESP) {/* no SIB needed */
1292                     int mod, rm;
1293                     switch(b) {
1294                       case R_EAX: rm = 0; break;
1295                       case R_ECX: rm = 1; break;
1296                       case R_EDX: rm = 2; break;
1297                       case R_EBX: rm = 3; break;
1298                       case R_EBP: rm = 5; break;
1299                       case R_ESI: rm = 6; break;
1300                       case R_EDI: rm = 7; break;
1301                       case -1: rm = 5; break;
1302                       default:         /* should never happen */
1303                         return NULL;
1304                     }
1305                     if (b==-1 || (b!=R_EBP && o==0 &&
1306                                   seg==NO_SEG && !forw_ref &&
1307                                   !(input->eaflags &
1308                                     (EAF_BYTEOFFS|EAF_WORDOFFS))))
1309                         mod = 0;
1310                     else if (input->eaflags & EAF_BYTEOFFS ||
1311                              (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1312                               !(input->eaflags & EAF_WORDOFFS))) {
1313                         mod = 1;
1314                     } 
1315                     else
1316                         mod = 2;
1317
1318                     output->sib_present = FALSE;
1319                     output->bytes = (b==-1 || mod==2 ? 4 : mod);
1320                     output->modrm = (mod<<6) | (rfield<<3) | rm;
1321                 } 
1322                 else {         /* we need a SIB */
1323                     int mod, scale, index, base;
1324
1325                     switch (b) {
1326                       case R_EAX: base = 0; break;
1327                       case R_ECX: base = 1; break;
1328                       case R_EDX: base = 2; break;
1329                       case R_EBX: base = 3; break;
1330                       case R_ESP: base = 4; break;
1331                       case R_EBP: case -1: base = 5; break;
1332                       case R_ESI: base = 6; break;
1333                       case R_EDI: base = 7; break;
1334                       default:         /* then what the smeg is it? */
1335                         return NULL;  /* panic */
1336                     }
1337
1338                     switch (i) {
1339                       case R_EAX: index = 0; break;
1340                       case R_ECX: index = 1; break;
1341                       case R_EDX: index = 2; break;
1342                       case R_EBX: index = 3; break;
1343                       case -1: index = 4; break;
1344                       case R_EBP: index = 5; break;
1345                       case R_ESI: index = 6; break;
1346                       case R_EDI: index = 7; break;
1347                       default:         /* then what the smeg is it? */
1348                         return NULL;  /* panic */
1349                     }
1350
1351                     if (i==-1) s = 1;
1352                     switch (s) {
1353                       case 1: scale = 0; break;
1354                       case 2: scale = 1; break;
1355                       case 4: scale = 2; break;
1356                       case 8: scale = 3; break;
1357                       default:         /* then what the smeg is it? */
1358                         return NULL;  /* panic */
1359                     }
1360
1361                     if (b==-1 || (b!=R_EBP && o==0 &&
1362                                   seg==NO_SEG && !forw_ref &&
1363                                   !(input->eaflags &
1364                                     (EAF_BYTEOFFS|EAF_WORDOFFS))))
1365                         mod = 0;
1366                     else if (input->eaflags & EAF_BYTEOFFS ||
1367                              (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1368                               !(input->eaflags & EAF_WORDOFFS)))
1369                         mod = 1;
1370                     else
1371                         mod = 2;
1372
1373                     output->sib_present = TRUE;
1374                     output->bytes = (b==-1 || mod==2 ? 4 : mod);
1375                     output->modrm = (mod<<6) | (rfield<<3) | 4;
1376                     output->sib = (scale<<6) | (index<<3) | base;
1377                 }
1378             } 
1379             else {                     /* it's 16-bit */
1380                 int mod, rm;
1381
1382                 /* check all registers are BX, BP, SI or DI */
1383                 if ((b!=-1 && b!=R_BP && b!=R_BX && b!=R_SI && b!=R_DI) ||
1384                     (i!=-1 && i!=R_BP && i!=R_BX && i!=R_SI && i!=R_DI))
1385                     return NULL;
1386
1387                 /* ensure the user didn't specify DWORD */
1388                 if (input->addr_size == 32)
1389                     return NULL;
1390
1391                 if (s!=1 && i!=-1) return NULL;/* no can do, in 16-bit EA */
1392                 if (b==-1 && i!=-1) b ^= i ^= b ^= i;   /* swap them round */
1393                 if ((b==R_SI || b==R_DI) && i!=-1)
1394                     b ^= i ^= b ^= i; /* have BX/BP as base, SI/DI index */
1395                 if (b==i) return NULL;/* shouldn't ever happen, in theory */
1396                 if (i!=-1 && b!=-1 &&
1397                     (i==R_BP || i==R_BX || b==R_SI || b==R_DI))
1398                     return NULL;      /* invalid combinations */
1399                 if (b==-1)             /* pure offset: handled above */
1400                     return NULL;      /* so if it gets to here, panic! */
1401
1402                 rm = -1;
1403                 if (i!=-1)
1404                     switch (i*256 + b) {
1405                       case R_SI*256+R_BX: rm=0; break;
1406                       case R_DI*256+R_BX: rm=1; break;
1407                       case R_SI*256+R_BP: rm=2; break;
1408                       case R_DI*256+R_BP: rm=3; break;
1409                     }
1410                 else
1411                     switch (b) {
1412                       case R_SI: rm=4; break;
1413                       case R_DI: rm=5; break;
1414                       case R_BP: rm=6; break;
1415                       case R_BX: rm=7; break;
1416                     }
1417                 if (rm==-1)            /* can't happen, in theory */
1418                     return NULL;      /* so panic if it does */
1419
1420                 if (o==0 && seg==NO_SEG && !forw_ref && rm!=6 &&
1421                     !(input->eaflags & (EAF_BYTEOFFS|EAF_WORDOFFS)))
1422                     mod = 0;
1423                 else if (input->eaflags & EAF_BYTEOFFS ||
1424                          (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1425                           !(input->eaflags & EAF_WORDOFFS)))
1426                     mod = 1;
1427                 else
1428                     mod = 2;
1429
1430                 output->sib_present = FALSE;  /* no SIB - it's 16-bit */
1431                 output->bytes = mod;  /* bytes of offset needed */
1432                 output->modrm = (mod<<6) | (rfield<<3) | rm;
1433             }
1434         }
1435     }
1436     output->size = 1 + output->sib_present + output->bytes;
1437     return output;
1438 }
1439
1440 static int chsize (operand *input, int addrbits) 
1441 {
1442     if (!(MEMORY & ~input->type)) {
1443         int i=input->indexreg, b=input->basereg;
1444
1445         if (input->scale==0) i = -1;
1446
1447         if (i == -1 && b == -1) /* pure offset */
1448             return (input->addr_size != 0 && input->addr_size != addrbits);
1449
1450         if (i==R_EAX || i==R_EBX || i==R_ECX || i==R_EDX
1451             || i==R_EBP || i==R_ESP || i==R_ESI || i==R_EDI
1452             || b==R_EAX || b==R_EBX || b==R_ECX || b==R_EDX
1453             || b==R_EBP || b==R_ESP || b==R_ESI || b==R_EDI)
1454             return (addrbits==16);
1455         else
1456             return (addrbits==32);
1457     } 
1458     else
1459         return 0;
1460 }