NASM 0.98.21
[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 &&
556 /*          !(ins->oprs[op].type & (BITS16|BITS32)) && */
557           ins->oprs[op].wrt==NO_SEG && ins->oprs[op].segment==NO_SEG;
558
559     v = ins->oprs[op].offset;
560     if (size==16) v = (signed short)v;   /* sign extend if 16 bits */
561     
562     return ret && v>=-128L && v<=127L;
563 }
564
565 static long calcsize (long segment, long offset, int bits,
566                       insn *ins, char *codes) 
567 {
568     long           length = 0;
569     unsigned char  c;
570
571     (void) segment;  /* Don't warn that this parameter is unused */
572     (void) offset;   /* Don't warn that this parameter is unused */
573
574     while (*codes) switch (c = *codes++) {
575       case 01: case 02: case 03:
576         codes += c, length += c; break;
577       case 04: case 05: case 06: case 07:
578         length++; break;
579       case 010: case 011: case 012:
580         codes++, length++; break;
581       case 017:
582         length++; break;
583       case 014: case 015: case 016:
584         length++; break;
585       case 020: case 021: case 022:
586         length++; break;
587       case 024: case 025: case 026:
588         length++; break;
589       case 030: case 031: case 032:
590         length += 2; break;
591       case 034: case 035: case 036:
592         length += ((ins->oprs[c-034].addr_size ?
593                     ins->oprs[c-034].addr_size : bits) == 16 ? 2 : 4); break;
594       case 037:
595         length += 2; break;
596       case 040: case 041: case 042:
597         length += 4; break;
598       case 050: case 051: case 052:
599         length++; break;
600       case 060: case 061: case 062:
601         length += 2; break;
602       case 064: case 065: case 066:
603         length += ((ins->oprs[c-064].addr_size ?
604                     ins->oprs[c-064].addr_size : bits) == 16 ? 2 : 4); break;
605       case 070: case 071: case 072:
606         length += 4; break;
607       case 0130: case 0131: case 0132:          
608         length += is_sbyte(ins, c-0130, 16) ? 1 : 2; break;
609       case 0133: case 0134: case 0135:
610         codes+=2; length++; break;
611       case 0140: case 0141: case 0142:
612         length += is_sbyte(ins, c-0140, 32) ? 1 : 4; break;
613       case 0143: case 0144: case 0145:
614         codes+=2; length++; break;
615       case 0300: case 0301: case 0302:
616         length += chsize (&ins->oprs[c-0300], bits);
617         break;
618       case 0310:
619         length += (bits==32);
620         break;
621       case 0311:
622         length += (bits==16);
623         break;
624       case 0312:
625         break;
626       case 0320:
627         length += (bits==32);
628         break;
629       case 0321:
630         length += (bits==16);
631         break;
632       case 0322:
633         break;
634       case 0330:
635         codes++, length++; break;
636       case 0331:
637       case 0332:
638         break;
639       case 0333:
640         length++; break;
641       case 0340: case 0341: case 0342:
642         if (ins->oprs[0].segment != NO_SEG)
643             errfunc (ERR_NONFATAL, "attempt to reserve non-constant"
644                      " quantity of BSS space");
645         else
646             length += ins->oprs[0].offset << (c-0340);
647         break;
648       case 0370: case 0371: case 0372:
649         break;
650       case 0373:
651         length++; break;
652       default:                         /* can't do it by 'case' statements */
653         if (c>=0100 && c<=0277) {      /* it's an EA */
654             ea ea_data;
655             if (!process_ea (&ins->oprs[(c>>3)&7], &ea_data, bits, 0,
656                              ins->forw_ref)) {
657                 errfunc (ERR_NONFATAL, "invalid effective address");
658                 return -1;
659             } else
660                 length += ea_data.size;
661         } else
662             errfunc (ERR_PANIC, "internal instruction table corrupt"
663                      ": instruction code 0x%02X given", c);
664     }
665     return length;
666 }
667
668 static void gencode (long segment, long offset, int bits,
669                      insn *ins, char *codes, long insn_end) 
670 {
671     static char condval[] = { /* conditional opcodes */
672         0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
673         0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
674         0x0, 0xA, 0xA, 0xB, 0x8, 0x4
675     };
676     unsigned char c;
677     unsigned char bytes[4];
678     long          data, size;
679
680     while (*codes)
681         switch (c = *codes++) 
682         {
683         case 01: case 02: case 03:
684             out (offset, segment, codes, OUT_RAWDATA+c, NO_SEG, NO_SEG);
685             codes += c;
686             offset += c;
687             break;
688
689         case 04: case 06:
690             switch (ins->oprs[0].basereg) 
691             {
692             case R_CS: 
693                 bytes[0] = 0x0E + (c == 0x04 ? 1 : 0); break;
694             case R_DS: 
695                 bytes[0] = 0x1E + (c == 0x04 ? 1 : 0); break;
696             case R_ES: 
697                 bytes[0] = 0x06 + (c == 0x04 ? 1 : 0); break;
698             case R_SS: 
699                 bytes[0] = 0x16 + (c == 0x04 ? 1 : 0); break;
700             default:
701                 errfunc (ERR_PANIC, "bizarre 8086 segment register received");
702             }
703             out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
704             offset++;
705             break;
706
707         case 05: case 07:
708             switch (ins->oprs[0].basereg) {
709             case R_FS: bytes[0] = 0xA0 + (c == 0x05 ? 1 : 0); break;
710             case R_GS: bytes[0] = 0xA8 + (c == 0x05 ? 1 : 0); break;
711             default:
712                 errfunc (ERR_PANIC, "bizarre 386 segment register received");
713             }
714             out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
715             offset++;
716             break;
717
718         case 010: case 011: case 012:
719             bytes[0] = *codes++ + regval(&ins->oprs[c-010]);
720             out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
721             offset += 1;
722             break;
723
724         case 017:
725             bytes[0] = 0;
726             out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
727             offset += 1;
728             break;
729
730         case 014: case 015: case 016:
731             if (ins->oprs[c-014].offset < -128 
732                 || ins->oprs[c-014].offset > 127)
733             {
734                 errfunc (ERR_WARNING, "signed byte value exceeds bounds");
735             }
736
737             if (ins->oprs[c-014].segment != NO_SEG) 
738             {
739                 data = ins->oprs[c-014].offset;
740                 out (offset, segment, &data, OUT_ADDRESS+1,
741                      ins->oprs[c-014].segment, ins->oprs[c-014].wrt);
742             } 
743             else {
744                 bytes[0] = ins->oprs[c-014].offset;
745                 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
746             }
747             offset += 1;
748             break;
749
750         case 020: case 021: case 022:
751             if (ins->oprs[c-020].offset < -256 
752                 || ins->oprs[c-020].offset > 255)
753             {
754                 errfunc (ERR_WARNING, "byte value exceeds bounds");
755             }
756             if (ins->oprs[c-020].segment != NO_SEG) {
757                 data = ins->oprs[c-020].offset;
758                 out (offset, segment, &data, OUT_ADDRESS+1,
759                      ins->oprs[c-020].segment, ins->oprs[c-020].wrt);
760             } 
761             else {
762                 bytes[0] = ins->oprs[c-020].offset;
763                 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
764             }
765             offset += 1;
766             break;
767         
768         case 024: case 025: case 026:
769             if (ins->oprs[c-024].offset < 0 || ins->oprs[c-024].offset > 255)
770                 errfunc (ERR_WARNING, "unsigned byte value exceeds bounds");
771             if (ins->oprs[c-024].segment != NO_SEG) {
772                 data = ins->oprs[c-024].offset;
773                 out (offset, segment, &data, OUT_ADDRESS+1,
774                      ins->oprs[c-024].segment, ins->oprs[c-024].wrt);
775             }
776             else {
777                 bytes[0] = ins->oprs[c-024].offset;
778                 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
779             }
780             offset += 1;
781             break;
782
783         case 030: case 031: case 032:
784             if (ins->oprs[c-030].segment == NO_SEG &&
785                 ins->oprs[c-030].wrt == NO_SEG &&
786                 (ins->oprs[c-030].offset < -65536L ||
787                  ins->oprs[c-030].offset > 65535L))
788             {
789                 errfunc (ERR_WARNING, "word value exceeds bounds");
790             }
791             data = ins->oprs[c-030].offset;
792             out (offset, segment, &data, OUT_ADDRESS+2,
793                  ins->oprs[c-030].segment, ins->oprs[c-030].wrt);
794             offset += 2;
795             break;
796
797         case 034: case 035: case 036:
798             data = ins->oprs[c-034].offset;
799             size = ((ins->oprs[c-034].addr_size ?
800                      ins->oprs[c-034].addr_size : bits) == 16 ? 2 : 4);
801             if (size==2 && (data < -65536L || data > 65535L))
802                 errfunc (ERR_WARNING, "word value exceeds bounds");
803             out (offset, segment, &data, OUT_ADDRESS+size,
804                  ins->oprs[c-034].segment, ins->oprs[c-034].wrt);
805             offset += size;
806             break;
807
808         case 037:
809             if (ins->oprs[0].segment == NO_SEG)
810                 errfunc (ERR_NONFATAL, "value referenced by FAR is not"
811                          " relocatable");
812             data = 0L;
813             out (offset, segment, &data, OUT_ADDRESS+2,
814                  outfmt->segbase(1+ins->oprs[0].segment),
815                  ins->oprs[0].wrt);
816             offset += 2;
817                 break;
818
819         case 040: case 041: case 042:
820             data = ins->oprs[c-040].offset;
821             out (offset, segment, &data, OUT_ADDRESS+4,
822                  ins->oprs[c-040].segment, ins->oprs[c-040].wrt);
823             offset += 4;
824             break;
825
826         case 050: case 051: case 052:
827             if (ins->oprs[c-050].segment != segment)
828                 errfunc (ERR_NONFATAL, "short relative jump outside segment");
829             data = ins->oprs[c-050].offset - insn_end;
830             if (data > 127 || data < -128)
831                 errfunc (ERR_NONFATAL, "short jump is out of range");
832             bytes[0] = data;
833             out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
834             offset += 1;
835             break;
836
837         case 060: case 061: case 062:
838             if (ins->oprs[c-060].segment != segment) {
839                 data = ins->oprs[c-060].offset;
840                 out (offset, segment, &data, OUT_REL2ADR+insn_end-offset,
841                      ins->oprs[c-060].segment, ins->oprs[c-060].wrt);
842             } else {
843                 data = ins->oprs[c-060].offset - insn_end;
844                 out (offset, segment, &data,
845                      OUT_ADDRESS+2, NO_SEG, NO_SEG);
846             }
847             offset += 2;
848             break;
849
850         case 064: case 065: case 066:
851             size = ((ins->oprs[c-064].addr_size ?
852                      ins->oprs[c-064].addr_size : bits) == 16 ? 2 : 4);
853             if (ins->oprs[c-064].segment != segment) {
854                 data = ins->oprs[c-064].offset;
855                 size = (bits == 16 ? OUT_REL2ADR : OUT_REL4ADR);
856                 out (offset, segment, &data, size+insn_end-offset,
857                      ins->oprs[c-064].segment, ins->oprs[c-064].wrt);
858                 size = (bits == 16 ? 2 : 4);
859             } else {
860                 data = ins->oprs[c-064].offset - insn_end;
861                 out (offset, segment, &data,
862                      OUT_ADDRESS+size, NO_SEG, NO_SEG);
863             }
864             offset += size;
865             break;
866
867         case 070: case 071: case 072:
868             if (ins->oprs[c-070].segment != segment) {
869                 data = ins->oprs[c-070].offset;
870                 out (offset, segment, &data, OUT_REL4ADR+insn_end-offset,
871                      ins->oprs[c-070].segment, ins->oprs[c-070].wrt);
872             } else {
873                 data = ins->oprs[c-070].offset - insn_end;
874                 out (offset, segment, &data,
875                      OUT_ADDRESS+4, NO_SEG, NO_SEG);
876             }
877             offset += 4;
878             break;
879
880         case 0130: case 0131: case 0132:
881             data = ins->oprs[c-0130].offset;
882             if (is_sbyte(ins, c-0130, 16)) {
883                 out (offset, segment, &data, OUT_RAWDATA+1, NO_SEG, NO_SEG);
884                 offset++;
885             } else {
886                 if (ins->oprs[c-0130].segment == NO_SEG &&
887                         ins->oprs[c-0130].wrt == NO_SEG &&
888                         (data < -65536L || data > 65535L)) {
889                     errfunc (ERR_WARNING, "word value exceeds bounds");
890                 }    
891                 out (offset, segment, &data, OUT_ADDRESS+2,
892                           ins->oprs[c-0130].segment, ins->oprs[c-0130].wrt);
893                 offset += 2;
894             }
895             break;
896
897         case 0133: case 0134: case 0135:
898             codes++;
899             bytes[0] = *codes++;
900             if (is_sbyte(ins, c-0133, 16)) bytes[0] |= 2;   /* s-bit */
901             out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
902             offset++;
903             break;
904                 
905         case 0140: case 0141: case 0142:
906             data = ins->oprs[c-0140].offset;
907             if (is_sbyte(ins, c-0140, 32)) {
908                 out (offset, segment, &data, OUT_RAWDATA+1, NO_SEG, NO_SEG);
909                 offset++;
910             } else {
911                 out (offset, segment, &data, OUT_ADDRESS+4,
912                           ins->oprs[c-0140].segment, ins->oprs[c-0140].wrt);
913                 offset += 4;
914             }
915             break;
916
917         case 0143: case 0144: case 0145:
918             codes++;
919             bytes[0] = *codes++;
920             if (is_sbyte(ins, c-0143, 32)) bytes[0] |= 2;   /* s-bit */
921             out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
922             offset++;
923             break;
924                     
925         case 0300: case 0301: case 0302:
926             if (chsize (&ins->oprs[c-0300], bits)) {
927                 *bytes = 0x67;
928                 out (offset, segment, bytes,
929                      OUT_RAWDATA+1, NO_SEG, NO_SEG);
930                 offset += 1;
931             } else
932                 offset += 0;
933             break;
934
935         case 0310:
936             if (bits==32) {
937                 *bytes = 0x67;
938                 out (offset, segment, bytes,
939                      OUT_RAWDATA+1, NO_SEG, NO_SEG);
940                 offset += 1;
941             } else
942                 offset += 0;
943             break;
944
945         case 0311:
946             if (bits==16) {
947                 *bytes = 0x67;
948                 out (offset, segment, bytes,
949                      OUT_RAWDATA+1, NO_SEG, NO_SEG);
950                 offset += 1;
951             } else
952                 offset += 0;
953             break;
954
955         case 0312:
956             break;
957
958         case 0320:
959             if (bits==32) {
960                 *bytes = 0x66;
961                 out (offset, segment, bytes,
962                      OUT_RAWDATA+1, NO_SEG, NO_SEG);
963                 offset += 1;
964             } else
965                 offset += 0;
966             break;
967
968         case 0321:
969             if (bits==16) {
970                 *bytes = 0x66;
971                 out (offset, segment, bytes,
972                      OUT_RAWDATA+1, NO_SEG, NO_SEG);
973                 offset += 1;
974             } else
975                 offset += 0;
976             break;
977
978         case 0322:
979             break;
980
981         case 0330:
982             *bytes = *codes++ ^ condval[ins->condition];
983             out (offset, segment, bytes,
984                  OUT_RAWDATA+1, NO_SEG, NO_SEG);
985             offset += 1;
986             break;
987
988         case 0331:
989         case 0332:
990             break;
991
992         case 0333:
993             *bytes = 0xF3;
994             out (offset, segment, bytes,
995                  OUT_RAWDATA+1, NO_SEG, NO_SEG);
996             offset += 1;
997             break;
998
999         case 0340: case 0341: case 0342:
1000             if (ins->oprs[0].segment != NO_SEG)
1001                 errfunc (ERR_PANIC, "non-constant BSS size in pass two");
1002             else {
1003                 long size = ins->oprs[0].offset << (c-0340);
1004                 if (size > 0)
1005                     out (offset, segment, NULL,
1006                          OUT_RESERVE+size, NO_SEG, NO_SEG);
1007                 offset += size;
1008             }
1009             break;
1010
1011         case 0370: case 0371: case 0372:
1012             break;
1013         
1014         case 0373:
1015             *bytes = bits==16 ? 3 : 5;
1016             out (offset, segment, bytes,
1017                  OUT_RAWDATA+1, NO_SEG, NO_SEG);
1018             offset += 1;
1019             break;
1020
1021         default:                       /* can't do it by 'case' statements */
1022             if (c>=0100 && c<=0277) {      /* it's an EA */
1023                 ea ea_data;
1024                 int rfield;
1025                 unsigned char *p;
1026                 long s;
1027
1028                 if (c<=0177)           /* pick rfield from operand b */
1029                     rfield = regval (&ins->oprs[c&7]);
1030                 else                   /* rfield is constant */
1031                     rfield = c & 7;
1032
1033                 if (!process_ea (&ins->oprs[(c>>3)&7], &ea_data, bits, rfield,
1034                                  ins->forw_ref))
1035                 {
1036                     errfunc (ERR_NONFATAL, "invalid effective address");
1037                 }
1038
1039                 p = bytes;
1040                 *p++ = ea_data.modrm;
1041                 if (ea_data.sib_present)
1042                     *p++ = ea_data.sib;
1043
1044                 s = p-bytes;
1045                 out (offset, segment, bytes, OUT_RAWDATA + s,
1046                      NO_SEG, NO_SEG);
1047
1048                 switch (ea_data.bytes) {
1049                 case 0:
1050                     break;
1051                 case 1:
1052                     if (ins->oprs[(c>>3)&7].segment != NO_SEG) {
1053                         data = ins->oprs[(c>>3)&7].offset;
1054                         out (offset, segment, &data, OUT_ADDRESS+1,
1055                              ins->oprs[(c>>3)&7].segment,
1056                              ins->oprs[(c>>3)&7].wrt);
1057                     } else {
1058                         *bytes = ins->oprs[(c>>3)&7].offset;
1059                         out (offset, segment, bytes, OUT_RAWDATA+1,
1060                              NO_SEG, NO_SEG);
1061                     }
1062                     s++;
1063                     break;
1064                 case 2:
1065                 case 4:
1066                     data = ins->oprs[(c>>3)&7].offset;
1067                     out (offset, segment, &data,
1068                          OUT_ADDRESS+ea_data.bytes,
1069                          ins->oprs[(c>>3)&7].segment, ins->oprs[(c>>3)&7].wrt);
1070                     s += ea_data.bytes;
1071                     break;
1072                 }
1073                 offset += s;
1074             } else
1075                 errfunc (ERR_PANIC, "internal instruction table corrupt"
1076                      ": instruction code 0x%02X given", c);
1077         }
1078 }
1079
1080 static int regval (operand *o) 
1081 {
1082     switch (o->basereg) {
1083       case R_EAX: case R_AX: case R_AL: case R_ES: case R_CR0: case R_DR0:
1084       case R_ST0: case R_MM0: case R_XMM0:
1085         return 0;
1086       case R_ECX: case R_CX: case R_CL: case R_CS: case R_DR1: case R_ST1:
1087       case R_MM1: case R_XMM1:
1088         return 1;
1089       case R_EDX: case R_DX: case R_DL: case R_SS: case R_CR2: case R_DR2:
1090       case R_ST2: case R_MM2:  case R_XMM2:
1091         return 2;
1092       case R_EBX: case R_BX: case R_BL: case R_DS: case R_CR3: case R_DR3:
1093       case R_TR3: case R_ST3: case R_MM3:  case R_XMM3:
1094         return 3;
1095       case R_ESP: case R_SP: case R_AH: case R_FS: case R_CR4: case R_TR4:
1096       case R_ST4: case R_MM4:  case R_XMM4:
1097         return 4;
1098       case R_EBP: case R_BP: case R_CH: case R_GS: case R_TR5: case R_ST5:
1099       case R_MM5:  case R_XMM5:
1100         return 5;
1101       case R_ESI: case R_SI: case R_DH: case R_DR6: case R_TR6: case R_ST6:
1102       case R_MM6:  case R_XMM6:
1103         return 6;
1104       case R_EDI: case R_DI: case R_BH: case R_DR7: case R_TR7: case R_ST7:
1105       case R_MM7:  case R_XMM7:
1106         return 7;
1107       default:                         /* panic */
1108         errfunc (ERR_PANIC, "invalid register operand given to regval()");
1109         return 0;
1110     }
1111 }
1112
1113 static int matches (struct itemplate *itemp, insn *instruction) 
1114 {
1115     int i, size[3], asize, oprs, ret;
1116
1117     ret = 100;
1118
1119     /*
1120      * Check the opcode
1121      */
1122     if (itemp->opcode != instruction->opcode) return 0;
1123
1124     /*
1125      * Count the operands
1126      */
1127     if (itemp->operands != instruction->operands) return 0;
1128
1129     /*
1130      * Check that no spurious colons or TOs are present
1131      */
1132     for (i=0; i<itemp->operands; i++)
1133         if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON|TO))
1134             return 0;
1135
1136     /*
1137      * Check that the operand flags all match up
1138      */
1139     for (i=0; i<itemp->operands; i++)
1140         if (itemp->opd[i] & ~instruction->oprs[i].type ||
1141             ((itemp->opd[i] & SIZE_MASK) &&
1142              ((itemp->opd[i] ^ instruction->oprs[i].type) & SIZE_MASK)))
1143         {
1144             if ((itemp->opd[i] & ~instruction->oprs[i].type & NON_SIZE) ||
1145                 (instruction->oprs[i].type & SIZE_MASK))
1146                 return 0;
1147             else
1148 /*              ret = 1;   */
1149                 return 1;
1150         }
1151
1152     /*
1153      * Check operand sizes
1154      */
1155     if (itemp->flags & IF_ARMASK) {
1156       size[0] = size[1] = size[2] = 0;
1157
1158       switch (itemp->flags & IF_ARMASK) {
1159       case IF_AR0: i = 0; break;
1160       case IF_AR1: i = 1; break;
1161       case IF_AR2: i = 2; break;
1162       default:     break;       /* Shouldn't happen */
1163       }
1164       if (itemp->flags & IF_SB) {
1165         size[i] = BITS8;
1166       } else if (itemp->flags & IF_SW) {
1167         size[i] = BITS16;
1168       } else if (itemp->flags & IF_SD) {
1169         size[i] = BITS32;
1170       }
1171     } else {
1172       asize = 0;
1173       if (itemp->flags & IF_SB) {
1174         asize = BITS8;
1175         oprs = itemp->operands;
1176       } else if (itemp->flags & IF_SW) {
1177         asize = BITS16;
1178         oprs = itemp->operands;
1179       } else if (itemp->flags & IF_SD) {
1180         asize = BITS32;
1181         oprs = itemp->operands;
1182       }
1183       size[0] = size[1] = size[2] = asize;
1184     }
1185
1186     if (itemp->flags & (IF_SM | IF_SM2)) {
1187       oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands);
1188       asize = 0;
1189       for (i=0; i<oprs; i++) {
1190         if ( (asize = itemp->opd[i] & SIZE_MASK) != 0) {
1191           int j;
1192           for (j=0; j<oprs; j++)
1193             size[j] = asize;
1194           break;
1195         }
1196       }
1197     } else {
1198       oprs = itemp->operands;
1199     }
1200
1201     for (i=0; i<itemp->operands; i++)
1202         if (!(itemp->opd[i] & SIZE_MASK) &&
1203             (instruction->oprs[i].type & SIZE_MASK & ~size[i]))
1204 /*          ret = 2;  */
1205             return 2;
1206
1207     /*
1208      * Check template is okay at the set cpu level
1209      */
1210     if ((itemp->flags & IF_PLEVEL) > cpu) return 3;
1211     
1212     /*
1213      * Check if special handling needed for Jumps
1214      */
1215     if ((unsigned char)(itemp->code[0]) >= 0370) return 99;
1216      
1217     return ret;
1218 }
1219
1220 static ea *process_ea (operand *input, ea *output, int addrbits, int rfield,
1221                        int forw_ref) 
1222 {
1223     if (!(REGISTER & ~input->type)) {  /* it's a single register */
1224         static int regs[] = {
1225           R_AL,   R_CL,   R_DL,   R_BL,   R_AH,   R_CH,   R_DH,   R_BH,
1226           R_AX,   R_CX,   R_DX,   R_BX,   R_SP,   R_BP,   R_SI,   R_DI,
1227           R_EAX,  R_ECX,  R_EDX,  R_EBX,  R_ESP,  R_EBP,  R_ESI,  R_EDI,
1228           R_MM0,  R_MM1,  R_MM2,  R_MM3,  R_MM4,  R_MM5,  R_MM6,  R_MM7,
1229           R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7
1230         };
1231         int i;
1232
1233         for (i=0; i<elements(regs); i++)
1234             if (input->basereg == regs[i]) break;
1235         if (i<elements(regs)) {
1236             output->sib_present = FALSE;/* no SIB necessary */
1237             output->bytes = 0;         /* no offset necessary either */
1238             output->modrm = 0xC0 | (rfield << 3) | (i & 7);
1239         } 
1240         else
1241             return NULL;
1242     } else {                           /* it's a memory reference */
1243         if (input->basereg==-1 && (input->indexreg==-1 || input->scale==0)) {
1244             /* it's a pure offset */
1245             if (input->addr_size)
1246                 addrbits = input->addr_size;
1247             output->sib_present = FALSE;
1248             output->bytes = (addrbits==32 ? 4 : 2);
1249             output->modrm = (addrbits==32 ? 5 : 6) | (rfield << 3);
1250         } 
1251         else {                 /* it's an indirection */
1252             int i=input->indexreg, b=input->basereg, s=input->scale;
1253             long o=input->offset, seg=input->segment;
1254             int hb=input->hintbase, ht=input->hinttype;
1255             int t;
1256
1257             if (s==0) i = -1;          /* make this easy, at least */
1258
1259             if (i==R_EAX || i==R_EBX || i==R_ECX || i==R_EDX
1260                 || i==R_EBP || i==R_ESP || i==R_ESI || i==R_EDI
1261                 || b==R_EAX || b==R_EBX || b==R_ECX || b==R_EDX
1262                 || b==R_EBP || b==R_ESP || b==R_ESI || b==R_EDI) {
1263                 /* it must be a 32-bit memory reference. Firstly we have
1264                  * to check that all registers involved are type Exx. */
1265                 if (i!=-1 && i!=R_EAX && i!=R_EBX && i!=R_ECX && i!=R_EDX
1266                     && i!=R_EBP && i!=R_ESP && i!=R_ESI && i!=R_EDI)
1267                     return NULL;
1268                 if (b!=-1 && b!=R_EAX && b!=R_EBX && b!=R_ECX && b!=R_EDX
1269                     && b!=R_EBP && b!=R_ESP && b!=R_ESI && b!=R_EDI)
1270                     return NULL;
1271
1272                 /* While we're here, ensure the user didn't specify WORD. */
1273                 if (input->addr_size == 16)
1274                     return NULL;
1275
1276                 /* now reorganise base/index */
1277                 if (s == 1 && b != i && b != -1 && i != -1 &&
1278                     ((hb==b&&ht==EAH_NOTBASE) || (hb==i&&ht==EAH_MAKEBASE)))
1279                     t = b, b = i, i = t;   /* swap if hints say so */
1280                 if (b==i)              /* convert EAX+2*EAX to 3*EAX */
1281                     b = -1, s++;
1282                 if (b==-1 && s==1 && !(hb == i && ht == EAH_NOTBASE))
1283                     b = i, i = -1;     /* make single reg base, unless hint */
1284                 if (((s==2 && i!=R_ESP && !(input->eaflags & EAF_TIMESTWO)) ||
1285                      s==3 || s==5 || s==9) && b==-1)
1286                     b = i, s--;       /* convert 3*EAX to EAX+2*EAX */
1287                 if (s==1 && i==R_ESP)  /* swap ESP into base if scale is 1 */
1288                     i = b, b = R_ESP;
1289                 if (i==R_ESP || (s!=1 && s!=2 && s!=4 && s!=8 && i!=-1))
1290                     return NULL;      /* wrong, for various reasons */
1291
1292                 if (i==-1 && b!=R_ESP) {/* no SIB needed */
1293                     int mod, rm;
1294                     switch(b) {
1295                       case R_EAX: rm = 0; break;
1296                       case R_ECX: rm = 1; break;
1297                       case R_EDX: rm = 2; break;
1298                       case R_EBX: rm = 3; break;
1299                       case R_EBP: rm = 5; break;
1300                       case R_ESI: rm = 6; break;
1301                       case R_EDI: rm = 7; break;
1302                       case -1: rm = 5; break;
1303                       default:         /* should never happen */
1304                         return NULL;
1305                     }
1306                     if (b==-1 || (b!=R_EBP && o==0 &&
1307                                   seg==NO_SEG && !forw_ref &&
1308                                   !(input->eaflags &
1309                                     (EAF_BYTEOFFS|EAF_WORDOFFS))))
1310                         mod = 0;
1311                     else if (input->eaflags & EAF_BYTEOFFS ||
1312                              (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1313                               !(input->eaflags & EAF_WORDOFFS))) {
1314                         mod = 1;
1315                     } 
1316                     else
1317                         mod = 2;
1318
1319                     output->sib_present = FALSE;
1320                     output->bytes = (b==-1 || mod==2 ? 4 : mod);
1321                     output->modrm = (mod<<6) | (rfield<<3) | rm;
1322                 } 
1323                 else {         /* we need a SIB */
1324                     int mod, scale, index, base;
1325
1326                     switch (b) {
1327                       case R_EAX: base = 0; break;
1328                       case R_ECX: base = 1; break;
1329                       case R_EDX: base = 2; break;
1330                       case R_EBX: base = 3; break;
1331                       case R_ESP: base = 4; break;
1332                       case R_EBP: case -1: base = 5; break;
1333                       case R_ESI: base = 6; break;
1334                       case R_EDI: base = 7; break;
1335                       default:         /* then what the smeg is it? */
1336                         return NULL;  /* panic */
1337                     }
1338
1339                     switch (i) {
1340                       case R_EAX: index = 0; break;
1341                       case R_ECX: index = 1; break;
1342                       case R_EDX: index = 2; break;
1343                       case R_EBX: index = 3; break;
1344                       case -1: index = 4; break;
1345                       case R_EBP: index = 5; break;
1346                       case R_ESI: index = 6; break;
1347                       case R_EDI: index = 7; break;
1348                       default:         /* then what the smeg is it? */
1349                         return NULL;  /* panic */
1350                     }
1351
1352                     if (i==-1) s = 1;
1353                     switch (s) {
1354                       case 1: scale = 0; break;
1355                       case 2: scale = 1; break;
1356                       case 4: scale = 2; break;
1357                       case 8: scale = 3; break;
1358                       default:         /* then what the smeg is it? */
1359                         return NULL;  /* panic */
1360                     }
1361
1362                     if (b==-1 || (b!=R_EBP && o==0 &&
1363                                   seg==NO_SEG && !forw_ref &&
1364                                   !(input->eaflags &
1365                                     (EAF_BYTEOFFS|EAF_WORDOFFS))))
1366                         mod = 0;
1367                     else if (input->eaflags & EAF_BYTEOFFS ||
1368                              (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1369                               !(input->eaflags & EAF_WORDOFFS)))
1370                         mod = 1;
1371                     else
1372                         mod = 2;
1373
1374                     output->sib_present = TRUE;
1375                     output->bytes = (b==-1 || mod==2 ? 4 : mod);
1376                     output->modrm = (mod<<6) | (rfield<<3) | 4;
1377                     output->sib = (scale<<6) | (index<<3) | base;
1378                 }
1379             } 
1380             else {                     /* it's 16-bit */
1381                 int mod, rm;
1382
1383                 /* check all registers are BX, BP, SI or DI */
1384                 if ((b!=-1 && b!=R_BP && b!=R_BX && b!=R_SI && b!=R_DI) ||
1385                     (i!=-1 && i!=R_BP && i!=R_BX && i!=R_SI && i!=R_DI))
1386                     return NULL;
1387
1388                 /* ensure the user didn't specify DWORD */
1389                 if (input->addr_size == 32)
1390                     return NULL;
1391
1392                 if (s!=1 && i!=-1) return NULL;/* no can do, in 16-bit EA */
1393                 if (b==-1 && i!=-1) b ^= i ^= b ^= i;   /* swap them round */
1394                 if ((b==R_SI || b==R_DI) && i!=-1)
1395                     b ^= i ^= b ^= i; /* have BX/BP as base, SI/DI index */
1396                 if (b==i) return NULL;/* shouldn't ever happen, in theory */
1397                 if (i!=-1 && b!=-1 &&
1398                     (i==R_BP || i==R_BX || b==R_SI || b==R_DI))
1399                     return NULL;      /* invalid combinations */
1400                 if (b==-1)             /* pure offset: handled above */
1401                     return NULL;      /* so if it gets to here, panic! */
1402
1403                 rm = -1;
1404                 if (i!=-1)
1405                     switch (i*256 + b) {
1406                       case R_SI*256+R_BX: rm=0; break;
1407                       case R_DI*256+R_BX: rm=1; break;
1408                       case R_SI*256+R_BP: rm=2; break;
1409                       case R_DI*256+R_BP: rm=3; break;
1410                     }
1411                 else
1412                     switch (b) {
1413                       case R_SI: rm=4; break;
1414                       case R_DI: rm=5; break;
1415                       case R_BP: rm=6; break;
1416                       case R_BX: rm=7; break;
1417                     }
1418                 if (rm==-1)            /* can't happen, in theory */
1419                     return NULL;      /* so panic if it does */
1420
1421                 if (o==0 && seg==NO_SEG && !forw_ref && rm!=6 &&
1422                     !(input->eaflags & (EAF_BYTEOFFS|EAF_WORDOFFS)))
1423                     mod = 0;
1424                 else if (input->eaflags & EAF_BYTEOFFS ||
1425                          (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1426                           !(input->eaflags & EAF_WORDOFFS)))
1427                     mod = 1;
1428                 else
1429                     mod = 2;
1430
1431                 output->sib_present = FALSE;  /* no SIB - it's 16-bit */
1432                 output->bytes = mod;  /* bytes of offset needed */
1433                 output->modrm = (mod<<6) | (rfield<<3) | rm;
1434             }
1435         }
1436     }
1437     output->size = 1 + output->sib_present + output->bytes;
1438     return output;
1439 }
1440
1441 static int chsize (operand *input, int addrbits) 
1442 {
1443     if (!(MEMORY & ~input->type)) {
1444         int i=input->indexreg, b=input->basereg;
1445
1446         if (input->scale==0) i = -1;
1447
1448         if (i == -1 && b == -1) /* pure offset */
1449             return (input->addr_size != 0 && input->addr_size != addrbits);
1450
1451         if (i==R_EAX || i==R_EBX || i==R_ECX || i==R_EDX
1452             || i==R_EBP || i==R_ESP || i==R_ESI || i==R_EDI
1453             || b==R_EAX || b==R_EBX || b==R_ECX || b==R_EDX
1454             || b==R_EBP || b==R_ESP || b==R_ESI || b==R_EDI)
1455             return (addrbits==16);
1456         else
1457             return (addrbits==32);
1458     } 
1459     else
1460         return 0;
1461 }