blob: e30be18fd487cc113e9e7fddd627972d2b9074a5 [file] [log] [blame]
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001/* 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
H. Peter Anvin3ba46772002-05-27 23:19:35 +000025 * assembly mode or the operand-size override on the operand
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000026 * \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
H. Peter Anvin3ba46772002-05-27 23:19:35 +000028 * \44, \45, \46 - select between \3[012] and \4[012] depending on 16/32 bit
29 * assembly mode or the address-size override on the operand
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000030 * \50, \51, \52 - a byte relative operand, from operand 0, 1 or 2
31 * \60, \61, \62 - a word relative operand, from operand 0, 1 or 2
32 * \64, \65, \66 - select between \6[012] and \7[012] depending on 16/32 bit
H. Peter Anvin17799b42002-05-21 03:31:21 +000033 * assembly mode or the operand-size override on the operand
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000034 * \70, \71, \72 - a long relative operand, from operand 0, 1 or 2
35 * \1ab - a ModRM, calculated on EA in operand a, with the spare
36 * field the register value of operand b.
H. Peter Anvinaf535c12002-04-30 20:59:21 +000037 * \130,\131,\132 - an immediate word or signed byte for operand 0, 1, or 2
38 * \133,\134,\135 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
39 * is a signed byte rather than a word.
40 * \140,\141,\142 - an immediate dword or signed byte for operand 0, 1, or 2
41 * \143,\144,\145 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
42 * is a signed byte rather than a dword.
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000043 * \2ab - a ModRM, calculated on EA in operand a, with the spare
44 * field equal to digit b.
45 * \30x - might be an 0x67 byte, depending on the address size of
46 * the memory reference in operand x.
47 * \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
48 * \311 - indicates fixed 32-bit address size, i.e. optional 0x67.
H. Peter Anvinaf535c12002-04-30 20:59:21 +000049 * \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000050 * \320 - indicates fixed 16-bit operand size, i.e. optional 0x66.
51 * \321 - indicates fixed 32-bit operand size, i.e. optional 0x66.
52 * \322 - indicates that this instruction is only valid when the
53 * operand size is the default (instruction to disassembler,
54 * generates no code in the assembler)
55 * \330 - a literal byte follows in the code stream, to be added
56 * to the condition code value of the instruction.
H. Peter Anvinef7468f2002-04-30 20:57:59 +000057 * \331 - instruction not valid with REP prefix. Hint for
58 * disassembler only; for SSE instructions.
59 * \332 - disassemble a rep (0xF3 byte) prefix as repe not rep.
60 * \333 - REP prefix (0xF3 byte); for SSE instructions. Not encoded
61 * as a literal byte in order to aid the disassembler.
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000062 * \340 - reserve <operand 0> bytes of uninitialised storage.
63 * Operand 0 had better be a segmentless constant.
H. Peter Anvin788e6c12002-04-30 21:02:01 +000064 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
65 * 370 is used for Jcc, 371 is used for JMP.
H. Peter Anvinaf535c12002-04-30 20:59:21 +000066 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
67 * used for conditional jump over longer jump
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000068 */
69
70#include <stdio.h>
71#include <string.h>
72
73#include "nasm.h"
H. Peter Anvin6768eb72002-04-30 20:52:26 +000074#include "nasmlib.h"
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000075#include "assemble.h"
76#include "insns.h"
77
78extern struct itemplate *nasm_instructions[];
79
80typedef struct {
81 int sib_present; /* is a SIB byte necessary? */
82 int bytes; /* # of bytes of offset needed */
83 int size; /* lazy - this is sib+bytes+1 */
84 unsigned char modrm, sib; /* the bytes themselves */
85} ea;
86
H. Peter Anvinaf535c12002-04-30 20:59:21 +000087static unsigned long cpu; /* cpu level received from nasm.c */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000088static efunc errfunc;
89static struct ofmt *outfmt;
H. Peter Anvin6768eb72002-04-30 20:52:26 +000090static ListGen *list;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000091
92static long calcsize (long, long, int, insn *, char *);
93static void gencode (long, long, int, insn *, char *, long);
H. Peter Anvineba20a72002-04-30 20:53:55 +000094static int regval (operand *o);
95static int matches (struct itemplate *, insn *);
96static ea * process_ea (operand *, ea *, int, int, int);
97static int chsize (operand *, int);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000098
H. Peter Anvin6768eb72002-04-30 20:52:26 +000099/*
100 * This routine wrappers the real output format's output routine,
101 * in order to pass a copy of the data off to the listing file
102 * generator at the same time.
103 */
104static void out (long offset, long segto, void *data, unsigned long type,
H. Peter Anvineba20a72002-04-30 20:53:55 +0000105 long segment, long wrt)
106{
H. Peter Anvin9eb185b2002-04-30 21:02:47 +0000107 long lineno;
108 char *lnfname = NULL;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000109
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000110 if ((type & OUT_TYPMASK) == OUT_ADDRESS) {
111 if (segment != NO_SEG || wrt != NO_SEG) {
112 /*
113 * This address is relocated. We must write it as
114 * OUT_ADDRESS, so there's no work to be done here.
115 */
116 list->output (offset, data, type);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000117 }
118 else {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000119 unsigned char p[4], *q = p;
120 /*
121 * This is a non-relocated address, and we're going to
122 * convert it into RAWDATA format.
123 */
124 if ((type & OUT_SIZMASK) == 4) {
125 WRITELONG (q, * (long *) data);
126 list->output (offset, p, OUT_RAWDATA+4);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000127 }
128 else {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000129 WRITESHORT (q, * (long *) data);
130 list->output (offset, p, OUT_RAWDATA+2);
131 }
132 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000133 }
134 else if ((type & OUT_TYPMASK) == OUT_RAWDATA) {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000135 list->output (offset, data, type);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000136 }
137 else if ((type & OUT_TYPMASK) == OUT_RESERVE) {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000138 list->output (offset, NULL, type);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000139 }
140 else if ((type & OUT_TYPMASK) == OUT_REL2ADR ||
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000141 (type & OUT_TYPMASK) == OUT_REL4ADR) {
142 list->output (offset, data, type);
143 }
144
H. Peter Anvineba20a72002-04-30 20:53:55 +0000145 if (src_get(&lineno,&lnfname))
H. Peter Anvince616072002-04-30 21:02:23 +0000146 {
H. Peter Anvineba20a72002-04-30 20:53:55 +0000147 outfmt->current_dfmt->linenum(lnfname,lineno,segto);
H. Peter Anvin9eb185b2002-04-30 21:02:47 +0000148 if (lnfname) nasm_free(lnfname);
H. Peter Anvince616072002-04-30 21:02:23 +0000149 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000150
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000151 outfmt->output (segto, data, type, segment, wrt);
152}
153
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000154static int jmp_match (long segment, long offset, int bits,
155 insn *ins, char *code)
156{ long isize;
157 unsigned char c = code[0];
158
159
H. Peter Anvin788e6c12002-04-30 21:02:01 +0000160 if (c != 0370 && c != 0371) return 0;
161 if (ins->oprs[0].opflags & OPFLAG_FORWARD) {
H. Peter Anvin01377d82002-05-21 03:16:33 +0000162 if ((optimizing<0 || (ins->oprs[0].type & STRICT))
163 && c==0370) return 1;
H. Peter Anvin788e6c12002-04-30 21:02:01 +0000164 else return (pass0==0); /* match a forward reference */
165 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000166 isize = calcsize (segment, offset, bits, ins, code);
167 if (ins->oprs[0].segment != segment) return 0;
168 isize = ins->oprs[0].offset - offset - isize; /* isize is now the delta */
169 if (isize >= -128L && isize <= 127L) return 1; /* it is byte size */
170
171 return 0;
172}
173
174
175long assemble (long segment, long offset, int bits, unsigned long cp,
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000176 insn *instruction, struct ofmt *output, efunc error,
H. Peter Anvineba20a72002-04-30 20:53:55 +0000177 ListGen *listgen)
178{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000179 struct itemplate *temp;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000180 int j;
181 int size_prob;
182 long insn_end;
183 long itimes;
184 long start = offset;
185 long wsize = 0; /* size for DB etc. */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000186
187 errfunc = error; /* to pass to other functions */
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000188 cpu = cp;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000189 outfmt = output; /* likewise */
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000190 list = listgen; /* and again */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000191
H. Peter Anvineba20a72002-04-30 20:53:55 +0000192 switch (instruction->opcode)
193 {
194 case -1: return 0;
195 case I_DB: wsize = 1; break;
196 case I_DW: wsize = 2; break;
197 case I_DD: wsize = 4; break;
198 case I_DQ: wsize = 8; break;
199 case I_DT: wsize = 10; break;
200 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000201
H. Peter Anvineba20a72002-04-30 20:53:55 +0000202 if (wsize) {
203 extop * e;
204 long t = instruction->times;
205 if (t < 0)
206 errfunc(ERR_PANIC, "instruction->times < 0 (%ld) in assemble()",t);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000207
H. Peter Anvineba20a72002-04-30 20:53:55 +0000208 while (t--) /* repeat TIMES times */
209 {
210 for (e = instruction->eops; e; e = e->next)
211 {
212 if (e->type == EOT_DB_NUMBER)
213 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000214 if (wsize == 1) {
215 if (e->segment != NO_SEG)
216 errfunc (ERR_NONFATAL,
217 "one-byte relocation attempted");
218 else {
H. Peter Anvin41bf8002002-04-30 20:58:18 +0000219 unsigned char out_byte = e->offset;
220 out (offset, segment, &out_byte, OUT_RAWDATA+1,
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000221 NO_SEG, NO_SEG);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000222 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000223 }
224 else if (wsize > 5) {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000225 errfunc (ERR_NONFATAL, "integer supplied to a D%c"
226 " instruction", wsize==8 ? 'Q' : 'T');
H. Peter Anvineba20a72002-04-30 20:53:55 +0000227 }
228 else
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000229 out (offset, segment, &e->offset,
230 OUT_ADDRESS+wsize, e->segment,
231 e->wrt);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000232 offset += wsize;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000233 }
234 else if (e->type == EOT_DB_STRING)
235 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000236 int align;
237
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000238 out (offset, segment, e->stringval,
239 OUT_RAWDATA+e->stringlen, NO_SEG, NO_SEG);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000240 align = e->stringlen % wsize;
241
242 if (align) {
243 align = wsize - align;
244 out (offset, segment, "\0\0\0\0\0\0\0\0",
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000245 OUT_RAWDATA+align, NO_SEG, NO_SEG);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000246 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000247 offset += e->stringlen + align;
248 }
249 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000250 if (t > 0 && t == instruction->times-1)
251 {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000252 /*
253 * Dummy call to list->output to give the offset to the
254 * listing module.
255 */
256 list->output (offset, NULL, OUT_RAWDATA);
257 list->uplevel (LIST_TIMES);
258 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000259 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000260 if (instruction->times > 1)
261 list->downlevel (LIST_TIMES);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000262 return offset - start;
263 }
264
H. Peter Anvineba20a72002-04-30 20:53:55 +0000265 if (instruction->opcode == I_INCBIN)
266 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000267 static char fname[FILENAME_MAX];
H. Peter Anvineba20a72002-04-30 20:53:55 +0000268 FILE * fp;
269 long len;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000270
271 len = FILENAME_MAX-1;
272 if (len > instruction->eops->stringlen)
273 len = instruction->eops->stringlen;
274 strncpy (fname, instruction->eops->stringval, len);
275 fname[len] = '\0';
H. Peter Anvineba20a72002-04-30 20:53:55 +0000276
277 if ( (fp = fopen(fname, "rb")) == NULL)
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000278 error (ERR_NONFATAL, "`incbin': unable to open file `%s'", fname);
279 else if (fseek(fp, 0L, SEEK_END) < 0)
280 error (ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
281 fname);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000282 else
283 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000284 static char buf[2048];
285 long t = instruction->times;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000286 long base = 0;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000287
288 len = ftell (fp);
289 if (instruction->eops->next) {
H. Peter Anvineba20a72002-04-30 20:53:55 +0000290 base = instruction->eops->next->offset;
291 len -= base;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000292 if (instruction->eops->next->next &&
293 len > instruction->eops->next->next->offset)
294 len = instruction->eops->next->next->offset;
295 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000296 /*
297 * Dummy call to list->output to give the offset to the
298 * listing module.
299 */
300 list->output (offset, NULL, OUT_RAWDATA);
301 list->uplevel(LIST_INCBIN);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000302 while (t--)
303 {
304 long l;
305
306 fseek (fp, base, SEEK_SET);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000307 l = len;
308 while (l > 0) {
309 long m = fread (buf, 1, (l>sizeof(buf)?sizeof(buf):l),
310 fp);
311 if (!m) {
312 /*
313 * This shouldn't happen unless the file
314 * actually changes while we are reading
315 * it.
316 */
317 error (ERR_NONFATAL, "`incbin': unexpected EOF while"
318 " reading file `%s'", fname);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000319 t=0; /* Try to exit cleanly */
320 break;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000321 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000322 out (offset, segment, buf, OUT_RAWDATA+m,
323 NO_SEG, NO_SEG);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000324 l -= m;
325 }
326 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000327 list->downlevel(LIST_INCBIN);
328 if (instruction->times > 1) {
329 /*
330 * Dummy call to list->output to give the offset to the
331 * listing module.
332 */
333 list->output (offset, NULL, OUT_RAWDATA);
334 list->uplevel(LIST_TIMES);
335 list->downlevel(LIST_TIMES);
336 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000337 fclose (fp);
338 return instruction->times * len;
339 }
340 return 0; /* if we're here, there's an error */
341 }
342
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000343 size_prob = FALSE;
344 temp = nasm_instructions[instruction->opcode];
345 while (temp->opcode != -1) {
346 int m = matches (temp, instruction);
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000347 if (m == 99)
348 m += jmp_match(segment, offset, bits, instruction, temp->code);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000349
350 if (m == 100) /* matches! */
351 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000352 char *codes = temp->code;
353 long insn_size = calcsize(segment, offset, bits,
354 instruction, codes);
355 itimes = instruction->times;
356 if (insn_size < 0) /* shouldn't be, on pass two */
357 error (ERR_PANIC, "errors made it through from pass one");
358 else while (itimes--) {
359 insn_end = offset + insn_size;
360 for (j=0; j<instruction->nprefix; j++) {
H. Peter Anvineba20a72002-04-30 20:53:55 +0000361 unsigned char c=0;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000362 switch (instruction->prefixes[j]) {
363 case P_LOCK:
364 c = 0xF0; break;
365 case P_REPNE: case P_REPNZ:
366 c = 0xF2; break;
367 case P_REPE: case P_REPZ: case P_REP:
368 c = 0xF3; break;
369 case R_CS: c = 0x2E; break;
370 case R_DS: c = 0x3E; break;
371 case R_ES: c = 0x26; break;
372 case R_FS: c = 0x64; break;
373 case R_GS: c = 0x65; break;
374 case R_SS: c = 0x36; break;
H. Peter Anvin232badb2002-06-06 02:41:20 +0000375 case R_SEGR6:
376 case R_SEGR7:
377 error (ERR_NONFATAL, "segr6 and segr7 cannot be used as prefixes");
378 break;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000379 case P_A16:
H. Peter Anvineba20a72002-04-30 20:53:55 +0000380 if (bits != 16)
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000381 c = 0x67;
382 break;
383 case P_A32:
H. Peter Anvineba20a72002-04-30 20:53:55 +0000384 if (bits != 32)
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000385 c = 0x67;
386 break;
387 case P_O16:
H. Peter Anvineba20a72002-04-30 20:53:55 +0000388 if (bits != 16)
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000389 c = 0x66;
390 break;
391 case P_O32:
H. Peter Anvineba20a72002-04-30 20:53:55 +0000392 if (bits != 32)
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000393 c = 0x66;
394 break;
395 default:
396 error (ERR_PANIC,
397 "invalid instruction prefix");
398 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000399 if (c != 0) {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000400 out (offset, segment, &c, OUT_RAWDATA+1,
401 NO_SEG, NO_SEG);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000402 offset++;
403 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000404 }
405 gencode (segment, offset, bits, instruction, codes, insn_end);
406 offset += insn_size;
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000407 if (itimes > 0 && itimes == instruction->times-1) {
408 /*
409 * Dummy call to list->output to give the offset to the
410 * listing module.
411 */
412 list->output (offset, NULL, OUT_RAWDATA);
413 list->uplevel (LIST_TIMES);
414 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000415 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000416 if (instruction->times > 1)
417 list->downlevel (LIST_TIMES);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000418 return offset - start;
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000419 } else if (m > 0 && m > size_prob) {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000420 size_prob = m;
421 }
422 temp++;
423 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000424
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000425 if (temp->opcode == -1) { /* didn't match any instruction */
426 if (size_prob == 1) /* would have matched, but for size */
427 error (ERR_NONFATAL, "operation size not specified");
428 else if (size_prob == 2)
429 error (ERR_NONFATAL, "mismatch in operand sizes");
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000430 else if (size_prob == 3)
431 error (ERR_NONFATAL, "no instruction for this cpu level");
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000432 else
433 error (ERR_NONFATAL,
434 "invalid combination of opcode and operands");
435 }
436 return 0;
437}
438
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000439long insn_size (long segment, long offset, int bits, unsigned long cp,
H. Peter Anvineba20a72002-04-30 20:53:55 +0000440 insn *instruction, efunc error)
441{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000442 struct itemplate *temp;
443
444 errfunc = error; /* to pass to other functions */
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000445 cpu = cp;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000446
447 if (instruction->opcode == -1)
448 return 0;
449
450 if (instruction->opcode == I_DB ||
451 instruction->opcode == I_DW ||
452 instruction->opcode == I_DD ||
453 instruction->opcode == I_DQ ||
H. Peter Anvineba20a72002-04-30 20:53:55 +0000454 instruction->opcode == I_DT)
455 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000456 extop *e;
457 long isize, osize, wsize = 0; /* placate gcc */
458
459 isize = 0;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000460 switch (instruction->opcode)
461 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000462 case I_DB: wsize = 1; break;
463 case I_DW: wsize = 2; break;
464 case I_DD: wsize = 4; break;
465 case I_DQ: wsize = 8; break;
466 case I_DT: wsize = 10; break;
467 }
468
H. Peter Anvineba20a72002-04-30 20:53:55 +0000469 for (e = instruction->eops; e; e = e->next)
470 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000471 long align;
472
473 osize = 0;
474 if (e->type == EOT_DB_NUMBER)
475 osize = 1;
476 else if (e->type == EOT_DB_STRING)
477 osize = e->stringlen;
478
479 align = (-osize) % wsize;
480 if (align < 0)
481 align += wsize;
482 isize += osize + align;
483 }
484 return isize * instruction->times;
485 }
486
H. Peter Anvineba20a72002-04-30 20:53:55 +0000487 if (instruction->opcode == I_INCBIN)
488 {
489 char fname[FILENAME_MAX];
490 FILE * fp;
491 long len;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000492
493 len = FILENAME_MAX-1;
494 if (len > instruction->eops->stringlen)
495 len = instruction->eops->stringlen;
496 strncpy (fname, instruction->eops->stringval, len);
497 fname[len] = '\0';
H. Peter Anvineba20a72002-04-30 20:53:55 +0000498 if ( (fp = fopen(fname, "rb")) == NULL )
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000499 error (ERR_NONFATAL, "`incbin': unable to open file `%s'", fname);
500 else if (fseek(fp, 0L, SEEK_END) < 0)
501 error (ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
502 fname);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000503 else
504 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000505 len = ftell (fp);
506 fclose (fp);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000507 if (instruction->eops->next)
508 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000509 len -= instruction->eops->next->offset;
510 if (instruction->eops->next->next &&
511 len > instruction->eops->next->next->offset)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000512 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000513 len = instruction->eops->next->next->offset;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000514 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000515 }
516 return instruction->times * len;
517 }
518 return 0; /* if we're here, there's an error */
519 }
520
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000521 temp = nasm_instructions[instruction->opcode];
522 while (temp->opcode != -1) {
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000523 int m = matches(temp, instruction);
524 if (m == 99)
525 m += jmp_match(segment, offset, bits, instruction, temp->code);
526
527 if (m == 100) {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000528 /* we've matched an instruction. */
H. Peter Anvineba20a72002-04-30 20:53:55 +0000529 long isize;
530 char * codes = temp->code;
531 int j;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000532
533 isize = calcsize(segment, offset, bits, instruction, codes);
534 if (isize < 0)
535 return -1;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000536 for (j = 0; j < instruction->nprefix; j++)
537 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000538 if ((instruction->prefixes[j] != P_A16 &&
539 instruction->prefixes[j] != P_O16 && bits==16) ||
540 (instruction->prefixes[j] != P_A32 &&
541 instruction->prefixes[j] != P_O32 && bits==32))
H. Peter Anvineba20a72002-04-30 20:53:55 +0000542 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000543 isize++;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000544 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000545 }
546 return isize * instruction->times;
547 }
548 temp++;
549 }
550 return -1; /* didn't match any instruction */
551}
552
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000553
554/* check that opn[op] is a signed byte of size 16 or 32,
555 and return the signed value*/
556static int is_sbyte (insn *ins, int op, int size)
557{
558 signed long v;
559 int ret;
560
561 ret = !(ins->forw_ref && ins->oprs[op].opflags ) && /* dead in the water on forward reference or External */
H. Peter Anvin01377d82002-05-21 03:16:33 +0000562 optimizing>=0 &&
563 !(ins->oprs[op].type & STRICT) &&
564 ins->oprs[op].wrt==NO_SEG && ins->oprs[op].segment==NO_SEG;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000565
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000566 v = ins->oprs[op].offset;
567 if (size==16) v = (signed short)v; /* sign extend if 16 bits */
568
569 return ret && v>=-128L && v<=127L;
570}
571
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000572static long calcsize (long segment, long offset, int bits,
H. Peter Anvineba20a72002-04-30 20:53:55 +0000573 insn *ins, char *codes)
574{
575 long length = 0;
576 unsigned char c;
577
578 (void) segment; /* Don't warn that this parameter is unused */
579 (void) offset; /* Don't warn that this parameter is unused */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000580
581 while (*codes) switch (c = *codes++) {
582 case 01: case 02: case 03:
583 codes += c, length += c; break;
584 case 04: case 05: case 06: case 07:
585 length++; break;
586 case 010: case 011: case 012:
587 codes++, length++; break;
588 case 017:
589 length++; break;
590 case 014: case 015: case 016:
591 length++; break;
592 case 020: case 021: case 022:
593 length++; break;
594 case 024: case 025: case 026:
595 length++; break;
596 case 030: case 031: case 032:
597 length += 2; break;
598 case 034: case 035: case 036:
H. Peter Anvin3ba46772002-05-27 23:19:35 +0000599 if ( ins->oprs[c-034].type & (BITS16|BITS32) )
600 length += (ins->oprs[c-034].type & BITS16) ? 2 : 4;
601 else
602 length += (bits == 16) ? 2 : 4;
603 break;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000604 case 037:
605 length += 2; break;
606 case 040: case 041: case 042:
607 length += 4; break;
H. Peter Anvin3ba46772002-05-27 23:19:35 +0000608 case 044: case 045: case 046:
609 length += ((ins->oprs[c-044].addr_size ?
610 ins->oprs[c-044].addr_size : bits) == 16 ? 2 : 4); break;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000611 case 050: case 051: case 052:
612 length++; break;
613 case 060: case 061: case 062:
614 length += 2; break;
615 case 064: case 065: case 066:
H. Peter Anvin17799b42002-05-21 03:31:21 +0000616 if ( ins->oprs[c-064].type & (BITS16|BITS32) )
617 length += (ins->oprs[c-064].type & BITS16) ? 2 : 4;
618 else
619 length += (bits == 16) ? 2 : 4;
620 break;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000621 case 070: case 071: case 072:
622 length += 4; break;
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000623 case 0130: case 0131: case 0132:
624 length += is_sbyte(ins, c-0130, 16) ? 1 : 2; break;
625 case 0133: case 0134: case 0135:
626 codes+=2; length++; break;
627 case 0140: case 0141: case 0142:
628 length += is_sbyte(ins, c-0140, 32) ? 1 : 4; break;
629 case 0143: case 0144: case 0145:
630 codes+=2; length++; break;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000631 case 0300: case 0301: case 0302:
632 length += chsize (&ins->oprs[c-0300], bits);
633 break;
634 case 0310:
635 length += (bits==32);
636 break;
637 case 0311:
638 length += (bits==16);
639 break;
640 case 0312:
641 break;
642 case 0320:
643 length += (bits==32);
644 break;
645 case 0321:
646 length += (bits==16);
647 break;
648 case 0322:
649 break;
650 case 0330:
651 codes++, length++; break;
H. Peter Anvinef7468f2002-04-30 20:57:59 +0000652 case 0331:
653 case 0332:
654 break;
655 case 0333:
656 length++; break;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000657 case 0340: case 0341: case 0342:
658 if (ins->oprs[0].segment != NO_SEG)
659 errfunc (ERR_NONFATAL, "attempt to reserve non-constant"
660 " quantity of BSS space");
661 else
662 length += ins->oprs[0].offset << (c-0340);
663 break;
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000664 case 0370: case 0371: case 0372:
665 break;
666 case 0373:
667 length++; break;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000668 default: /* can't do it by 'case' statements */
669 if (c>=0100 && c<=0277) { /* it's an EA */
670 ea ea_data;
H. Peter Anvinea838272002-04-30 20:51:53 +0000671 if (!process_ea (&ins->oprs[(c>>3)&7], &ea_data, bits, 0,
672 ins->forw_ref)) {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000673 errfunc (ERR_NONFATAL, "invalid effective address");
674 return -1;
675 } else
676 length += ea_data.size;
677 } else
678 errfunc (ERR_PANIC, "internal instruction table corrupt"
679 ": instruction code 0x%02X given", c);
680 }
681 return length;
682}
683
684static void gencode (long segment, long offset, int bits,
H. Peter Anvineba20a72002-04-30 20:53:55 +0000685 insn *ins, char *codes, long insn_end)
686{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000687 static char condval[] = { /* conditional opcodes */
688 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
689 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
690 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
691 };
H. Peter Anvineba20a72002-04-30 20:53:55 +0000692 unsigned char c;
693 unsigned char bytes[4];
694 long data, size;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000695
H. Peter Anvineba20a72002-04-30 20:53:55 +0000696 while (*codes)
697 switch (c = *codes++)
698 {
699 case 01: case 02: case 03:
700 out (offset, segment, codes, OUT_RAWDATA+c, NO_SEG, NO_SEG);
701 codes += c;
702 offset += c;
703 break;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000704
H. Peter Anvineba20a72002-04-30 20:53:55 +0000705 case 04: case 06:
706 switch (ins->oprs[0].basereg)
707 {
708 case R_CS:
709 bytes[0] = 0x0E + (c == 0x04 ? 1 : 0); break;
710 case R_DS:
711 bytes[0] = 0x1E + (c == 0x04 ? 1 : 0); break;
712 case R_ES:
713 bytes[0] = 0x06 + (c == 0x04 ? 1 : 0); break;
714 case R_SS:
715 bytes[0] = 0x16 + (c == 0x04 ? 1 : 0); break;
716 default:
H. Peter Anvin4836e332002-04-30 20:56:43 +0000717 errfunc (ERR_PANIC, "bizarre 8086 segment register received");
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000718 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000719 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
720 offset++;
721 break;
722
723 case 05: case 07:
724 switch (ins->oprs[0].basereg) {
725 case R_FS: bytes[0] = 0xA0 + (c == 0x05 ? 1 : 0); break;
726 case R_GS: bytes[0] = 0xA8 + (c == 0x05 ? 1 : 0); break;
727 default:
H. Peter Anvin4836e332002-04-30 20:56:43 +0000728 errfunc (ERR_PANIC, "bizarre 386 segment register received");
H. Peter Anvineba20a72002-04-30 20:53:55 +0000729 }
730 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
731 offset++;
732 break;
733
734 case 010: case 011: case 012:
735 bytes[0] = *codes++ + regval(&ins->oprs[c-010]);
736 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
737 offset += 1;
738 break;
739
740 case 017:
741 bytes[0] = 0;
742 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
743 offset += 1;
744 break;
745
746 case 014: case 015: case 016:
747 if (ins->oprs[c-014].offset < -128
748 || ins->oprs[c-014].offset > 127)
749 {
750 errfunc (ERR_WARNING, "signed byte value exceeds bounds");
751 }
752
753 if (ins->oprs[c-014].segment != NO_SEG)
754 {
755 data = ins->oprs[c-014].offset;
756 out (offset, segment, &data, OUT_ADDRESS+1,
757 ins->oprs[c-014].segment, ins->oprs[c-014].wrt);
758 }
759 else {
760 bytes[0] = ins->oprs[c-014].offset;
761 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
762 }
763 offset += 1;
764 break;
765
766 case 020: case 021: case 022:
767 if (ins->oprs[c-020].offset < -256
768 || ins->oprs[c-020].offset > 255)
769 {
770 errfunc (ERR_WARNING, "byte value exceeds bounds");
771 }
772 if (ins->oprs[c-020].segment != NO_SEG) {
773 data = ins->oprs[c-020].offset;
774 out (offset, segment, &data, OUT_ADDRESS+1,
775 ins->oprs[c-020].segment, ins->oprs[c-020].wrt);
776 }
777 else {
778 bytes[0] = ins->oprs[c-020].offset;
779 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
780 }
781 offset += 1;
782 break;
783
784 case 024: case 025: case 026:
785 if (ins->oprs[c-024].offset < 0 || ins->oprs[c-024].offset > 255)
786 errfunc (ERR_WARNING, "unsigned byte value exceeds bounds");
787 if (ins->oprs[c-024].segment != NO_SEG) {
788 data = ins->oprs[c-024].offset;
789 out (offset, segment, &data, OUT_ADDRESS+1,
790 ins->oprs[c-024].segment, ins->oprs[c-024].wrt);
791 }
792 else {
793 bytes[0] = ins->oprs[c-024].offset;
794 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
795 }
796 offset += 1;
797 break;
798
799 case 030: case 031: case 032:
800 if (ins->oprs[c-030].segment == NO_SEG &&
801 ins->oprs[c-030].wrt == NO_SEG &&
802 (ins->oprs[c-030].offset < -65536L ||
803 ins->oprs[c-030].offset > 65535L))
804 {
805 errfunc (ERR_WARNING, "word value exceeds bounds");
806 }
807 data = ins->oprs[c-030].offset;
808 out (offset, segment, &data, OUT_ADDRESS+2,
809 ins->oprs[c-030].segment, ins->oprs[c-030].wrt);
810 offset += 2;
811 break;
812
813 case 034: case 035: case 036:
H. Peter Anvin3ba46772002-05-27 23:19:35 +0000814 if ( ins->oprs[c-034].type & (BITS16|BITS32) )
815 size = (ins->oprs[c-034].type & BITS16) ? 2 : 4;
816 else
817 size = (bits == 16) ? 2 : 4;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000818 data = ins->oprs[c-034].offset;
H. Peter Anvin4cf17482002-04-30 21:01:38 +0000819 if (size==2 && (data < -65536L || data > 65535L))
H. Peter Anvineba20a72002-04-30 20:53:55 +0000820 errfunc (ERR_WARNING, "word value exceeds bounds");
821 out (offset, segment, &data, OUT_ADDRESS+size,
822 ins->oprs[c-034].segment, ins->oprs[c-034].wrt);
823 offset += size;
824 break;
825
826 case 037:
827 if (ins->oprs[0].segment == NO_SEG)
828 errfunc (ERR_NONFATAL, "value referenced by FAR is not"
829 " relocatable");
830 data = 0L;
831 out (offset, segment, &data, OUT_ADDRESS+2,
832 outfmt->segbase(1+ins->oprs[0].segment),
833 ins->oprs[0].wrt);
834 offset += 2;
835 break;
836
837 case 040: case 041: case 042:
838 data = ins->oprs[c-040].offset;
839 out (offset, segment, &data, OUT_ADDRESS+4,
840 ins->oprs[c-040].segment, ins->oprs[c-040].wrt);
841 offset += 4;
842 break;
843
H. Peter Anvin3ba46772002-05-27 23:19:35 +0000844 case 044: case 045: case 046:
845 data = ins->oprs[c-044].offset;
846 size = ((ins->oprs[c-044].addr_size ?
847 ins->oprs[c-044].addr_size : bits) == 16 ? 2 : 4);
848 if (size==2 && (data < -65536L || data > 65535L))
849 errfunc (ERR_WARNING, "word value exceeds bounds");
850 out (offset, segment, &data, OUT_ADDRESS+size,
851 ins->oprs[c-044].segment, ins->oprs[c-044].wrt);
852 offset += size;
853 break;
854
H. Peter Anvineba20a72002-04-30 20:53:55 +0000855 case 050: case 051: case 052:
856 if (ins->oprs[c-050].segment != segment)
857 errfunc (ERR_NONFATAL, "short relative jump outside segment");
858 data = ins->oprs[c-050].offset - insn_end;
859 if (data > 127 || data < -128)
860 errfunc (ERR_NONFATAL, "short jump is out of range");
861 bytes[0] = data;
862 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
863 offset += 1;
864 break;
865
866 case 060: case 061: case 062:
867 if (ins->oprs[c-060].segment != segment) {
868 data = ins->oprs[c-060].offset;
869 out (offset, segment, &data, OUT_REL2ADR+insn_end-offset,
870 ins->oprs[c-060].segment, ins->oprs[c-060].wrt);
871 } else {
872 data = ins->oprs[c-060].offset - insn_end;
873 out (offset, segment, &data,
874 OUT_ADDRESS+2, NO_SEG, NO_SEG);
875 }
876 offset += 2;
877 break;
878
879 case 064: case 065: case 066:
H. Peter Anvin17799b42002-05-21 03:31:21 +0000880 if ( ins->oprs[c-064].type & (BITS16|BITS32) )
881 size = (ins->oprs[c-064].type & BITS16) ? 2 : 4;
882 else
883 size = (bits == 16) ? 2 : 4;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000884 if (ins->oprs[c-064].segment != segment) {
H. Peter Anvin17799b42002-05-21 03:31:21 +0000885 long reltype = (size == 2 ? OUT_REL2ADR : OUT_REL4ADR);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000886 data = ins->oprs[c-064].offset;
H. Peter Anvin17799b42002-05-21 03:31:21 +0000887 out (offset, segment, &data, reltype+insn_end-offset,
H. Peter Anvineba20a72002-04-30 20:53:55 +0000888 ins->oprs[c-064].segment, ins->oprs[c-064].wrt);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000889 } else {
890 data = ins->oprs[c-064].offset - insn_end;
891 out (offset, segment, &data,
892 OUT_ADDRESS+size, NO_SEG, NO_SEG);
893 }
894 offset += size;
895 break;
896
897 case 070: case 071: case 072:
898 if (ins->oprs[c-070].segment != segment) {
899 data = ins->oprs[c-070].offset;
900 out (offset, segment, &data, OUT_REL4ADR+insn_end-offset,
901 ins->oprs[c-070].segment, ins->oprs[c-070].wrt);
902 } else {
903 data = ins->oprs[c-070].offset - insn_end;
904 out (offset, segment, &data,
905 OUT_ADDRESS+4, NO_SEG, NO_SEG);
906 }
907 offset += 4;
908 break;
909
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000910 case 0130: case 0131: case 0132:
911 data = ins->oprs[c-0130].offset;
912 if (is_sbyte(ins, c-0130, 16)) {
913 out (offset, segment, &data, OUT_RAWDATA+1, NO_SEG, NO_SEG);
914 offset++;
915 } else {
916 if (ins->oprs[c-0130].segment == NO_SEG &&
917 ins->oprs[c-0130].wrt == NO_SEG &&
918 (data < -65536L || data > 65535L)) {
919 errfunc (ERR_WARNING, "word value exceeds bounds");
920 }
921 out (offset, segment, &data, OUT_ADDRESS+2,
922 ins->oprs[c-0130].segment, ins->oprs[c-0130].wrt);
923 offset += 2;
924 }
925 break;
926
927 case 0133: case 0134: case 0135:
928 codes++;
929 bytes[0] = *codes++;
930 if (is_sbyte(ins, c-0133, 16)) bytes[0] |= 2; /* s-bit */
931 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
932 offset++;
933 break;
934
935 case 0140: case 0141: case 0142:
936 data = ins->oprs[c-0140].offset;
937 if (is_sbyte(ins, c-0140, 32)) {
938 out (offset, segment, &data, OUT_RAWDATA+1, NO_SEG, NO_SEG);
939 offset++;
940 } else {
941 out (offset, segment, &data, OUT_ADDRESS+4,
942 ins->oprs[c-0140].segment, ins->oprs[c-0140].wrt);
943 offset += 4;
944 }
945 break;
946
947 case 0143: case 0144: case 0145:
948 codes++;
949 bytes[0] = *codes++;
950 if (is_sbyte(ins, c-0143, 32)) bytes[0] |= 2; /* s-bit */
951 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
952 offset++;
953 break;
954
H. Peter Anvineba20a72002-04-30 20:53:55 +0000955 case 0300: case 0301: case 0302:
956 if (chsize (&ins->oprs[c-0300], bits)) {
957 *bytes = 0x67;
958 out (offset, segment, bytes,
959 OUT_RAWDATA+1, NO_SEG, NO_SEG);
960 offset += 1;
961 } else
962 offset += 0;
963 break;
964
965 case 0310:
966 if (bits==32) {
967 *bytes = 0x67;
968 out (offset, segment, bytes,
969 OUT_RAWDATA+1, NO_SEG, NO_SEG);
970 offset += 1;
971 } else
972 offset += 0;
973 break;
974
975 case 0311:
976 if (bits==16) {
977 *bytes = 0x67;
978 out (offset, segment, bytes,
979 OUT_RAWDATA+1, NO_SEG, NO_SEG);
980 offset += 1;
981 } else
982 offset += 0;
983 break;
984
985 case 0312:
986 break;
987
988 case 0320:
989 if (bits==32) {
990 *bytes = 0x66;
991 out (offset, segment, bytes,
992 OUT_RAWDATA+1, NO_SEG, NO_SEG);
993 offset += 1;
994 } else
995 offset += 0;
996 break;
997
998 case 0321:
999 if (bits==16) {
1000 *bytes = 0x66;
1001 out (offset, segment, bytes,
1002 OUT_RAWDATA+1, NO_SEG, NO_SEG);
1003 offset += 1;
1004 } else
1005 offset += 0;
1006 break;
1007
1008 case 0322:
1009 break;
1010
1011 case 0330:
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001012 *bytes = *codes++ ^ condval[ins->condition];
H. Peter Anvineba20a72002-04-30 20:53:55 +00001013 out (offset, segment, bytes,
1014 OUT_RAWDATA+1, NO_SEG, NO_SEG);
1015 offset += 1;
1016 break;
1017
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001018 case 0331:
1019 case 0332:
1020 break;
1021
1022 case 0333:
1023 *bytes = 0xF3;
1024 out (offset, segment, bytes,
1025 OUT_RAWDATA+1, NO_SEG, NO_SEG);
1026 offset += 1;
1027 break;
1028
H. Peter Anvineba20a72002-04-30 20:53:55 +00001029 case 0340: case 0341: case 0342:
1030 if (ins->oprs[0].segment != NO_SEG)
1031 errfunc (ERR_PANIC, "non-constant BSS size in pass two");
1032 else {
1033 long size = ins->oprs[0].offset << (c-0340);
1034 if (size > 0)
1035 out (offset, segment, NULL,
1036 OUT_RESERVE+size, NO_SEG, NO_SEG);
1037 offset += size;
1038 }
1039 break;
1040
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001041 case 0370: case 0371: case 0372:
1042 break;
1043
1044 case 0373:
1045 *bytes = bits==16 ? 3 : 5;
1046 out (offset, segment, bytes,
1047 OUT_RAWDATA+1, NO_SEG, NO_SEG);
1048 offset += 1;
1049 break;
1050
H. Peter Anvineba20a72002-04-30 20:53:55 +00001051 default: /* can't do it by 'case' statements */
1052 if (c>=0100 && c<=0277) { /* it's an EA */
1053 ea ea_data;
1054 int rfield;
1055 unsigned char *p;
1056 long s;
1057
1058 if (c<=0177) /* pick rfield from operand b */
1059 rfield = regval (&ins->oprs[c&7]);
1060 else /* rfield is constant */
1061 rfield = c & 7;
1062
1063 if (!process_ea (&ins->oprs[(c>>3)&7], &ea_data, bits, rfield,
1064 ins->forw_ref))
1065 {
1066 errfunc (ERR_NONFATAL, "invalid effective address");
1067 }
1068
1069 p = bytes;
1070 *p++ = ea_data.modrm;
1071 if (ea_data.sib_present)
1072 *p++ = ea_data.sib;
1073
1074 s = p-bytes;
1075 out (offset, segment, bytes, OUT_RAWDATA + s,
1076 NO_SEG, NO_SEG);
1077
1078 switch (ea_data.bytes) {
1079 case 0:
1080 break;
1081 case 1:
1082 if (ins->oprs[(c>>3)&7].segment != NO_SEG) {
1083 data = ins->oprs[(c>>3)&7].offset;
1084 out (offset, segment, &data, OUT_ADDRESS+1,
1085 ins->oprs[(c>>3)&7].segment,
1086 ins->oprs[(c>>3)&7].wrt);
1087 } else {
1088 *bytes = ins->oprs[(c>>3)&7].offset;
1089 out (offset, segment, bytes, OUT_RAWDATA+1,
1090 NO_SEG, NO_SEG);
1091 }
1092 s++;
1093 break;
1094 case 2:
1095 case 4:
1096 data = ins->oprs[(c>>3)&7].offset;
1097 out (offset, segment, &data,
1098 OUT_ADDRESS+ea_data.bytes,
1099 ins->oprs[(c>>3)&7].segment, ins->oprs[(c>>3)&7].wrt);
1100 s += ea_data.bytes;
1101 break;
1102 }
1103 offset += s;
1104 } else
1105 errfunc (ERR_PANIC, "internal instruction table corrupt"
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001106 ": instruction code 0x%02X given", c);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001107 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001108}
1109
H. Peter Anvin232badb2002-06-06 02:41:20 +00001110#include "regvals.c"
1111
H. Peter Anvineba20a72002-04-30 20:53:55 +00001112static int regval (operand *o)
1113{
H. Peter Anvin232badb2002-06-06 02:41:20 +00001114 if ( o->basereg < EXPR_REG_START || o->basereg >= REG_ENUM_LIMIT ) {
1115 errfunc (ERR_PANIC, "invalid operand passed to regval()");
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001116 }
H. Peter Anvin232badb2002-06-06 02:41:20 +00001117 return regvals[o->basereg];
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001118}
1119
H. Peter Anvineba20a72002-04-30 20:53:55 +00001120static int matches (struct itemplate *itemp, insn *instruction)
1121{
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001122 int i, size[3], asize, oprs, ret;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001123
1124 ret = 100;
1125
1126 /*
1127 * Check the opcode
1128 */
1129 if (itemp->opcode != instruction->opcode) return 0;
1130
1131 /*
1132 * Count the operands
1133 */
1134 if (itemp->operands != instruction->operands) return 0;
1135
1136 /*
1137 * Check that no spurious colons or TOs are present
1138 */
1139 for (i=0; i<itemp->operands; i++)
1140 if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON|TO))
1141 return 0;
1142
1143 /*
1144 * Check that the operand flags all match up
1145 */
1146 for (i=0; i<itemp->operands; i++)
1147 if (itemp->opd[i] & ~instruction->oprs[i].type ||
1148 ((itemp->opd[i] & SIZE_MASK) &&
H. Peter Anvineba20a72002-04-30 20:53:55 +00001149 ((itemp->opd[i] ^ instruction->oprs[i].type) & SIZE_MASK)))
1150 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001151 if ((itemp->opd[i] & ~instruction->oprs[i].type & NON_SIZE) ||
1152 (instruction->oprs[i].type & SIZE_MASK))
1153 return 0;
1154 else
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001155/* ret = 1; */
1156 return 1;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001157 }
1158
1159 /*
1160 * Check operand sizes
1161 */
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001162 if (itemp->flags & IF_ARMASK) {
1163 size[0] = size[1] = size[2] = 0;
1164
1165 switch (itemp->flags & IF_ARMASK) {
1166 case IF_AR0: i = 0; break;
1167 case IF_AR1: i = 1; break;
1168 case IF_AR2: i = 2; break;
1169 default: break; /* Shouldn't happen */
1170 }
1171 if (itemp->flags & IF_SB) {
1172 size[i] = BITS8;
1173 } else if (itemp->flags & IF_SW) {
1174 size[i] = BITS16;
1175 } else if (itemp->flags & IF_SD) {
1176 size[i] = BITS32;
1177 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001178 } else {
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001179 asize = 0;
1180 if (itemp->flags & IF_SB) {
1181 asize = BITS8;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001182 oprs = itemp->operands;
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001183 } else if (itemp->flags & IF_SW) {
1184 asize = BITS16;
1185 oprs = itemp->operands;
1186 } else if (itemp->flags & IF_SD) {
1187 asize = BITS32;
1188 oprs = itemp->operands;
1189 }
1190 size[0] = size[1] = size[2] = asize;
1191 }
1192
1193 if (itemp->flags & (IF_SM | IF_SM2)) {
1194 oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands);
1195 asize = 0;
1196 for (i=0; i<oprs; i++) {
1197 if ( (asize = itemp->opd[i] & SIZE_MASK) != 0) {
1198 int j;
1199 for (j=0; j<oprs; j++)
1200 size[j] = asize;
1201 break;
1202 }
1203 }
1204 } else {
1205 oprs = itemp->operands;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001206 }
1207
1208 for (i=0; i<itemp->operands; i++)
1209 if (!(itemp->opd[i] & SIZE_MASK) &&
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001210 (instruction->oprs[i].type & SIZE_MASK & ~size[i]))
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001211/* ret = 2; */
1212 return 2;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001213
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001214 /*
1215 * Check template is okay at the set cpu level
1216 */
1217 if ((itemp->flags & IF_PLEVEL) > cpu) return 3;
1218
1219 /*
1220 * Check if special handling needed for Jumps
1221 */
1222 if ((unsigned char)(itemp->code[0]) >= 0370) return 99;
1223
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001224 return ret;
1225}
1226
H. Peter Anvinea838272002-04-30 20:51:53 +00001227static ea *process_ea (operand *input, ea *output, int addrbits, int rfield,
H. Peter Anvineba20a72002-04-30 20:53:55 +00001228 int forw_ref)
1229{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001230 if (!(REGISTER & ~input->type)) { /* it's a single register */
1231 static int regs[] = {
H. Peter Anvin4836e332002-04-30 20:56:43 +00001232 R_AL, R_CL, R_DL, R_BL, R_AH, R_CH, R_DH, R_BH,
1233 R_AX, R_CX, R_DX, R_BX, R_SP, R_BP, R_SI, R_DI,
1234 R_EAX, R_ECX, R_EDX, R_EBX, R_ESP, R_EBP, R_ESI, R_EDI,
1235 R_MM0, R_MM1, R_MM2, R_MM3, R_MM4, R_MM5, R_MM6, R_MM7,
1236 R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001237 };
1238 int i;
1239
1240 for (i=0; i<elements(regs); i++)
1241 if (input->basereg == regs[i]) break;
1242 if (i<elements(regs)) {
1243 output->sib_present = FALSE;/* no SIB necessary */
1244 output->bytes = 0; /* no offset necessary either */
H. Peter Anvin4836e332002-04-30 20:56:43 +00001245 output->modrm = 0xC0 | (rfield << 3) | (i & 7);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001246 }
1247 else
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001248 return NULL;
1249 } else { /* it's a memory reference */
1250 if (input->basereg==-1 && (input->indexreg==-1 || input->scale==0)) {
1251 /* it's a pure offset */
1252 if (input->addr_size)
1253 addrbits = input->addr_size;
1254 output->sib_present = FALSE;
1255 output->bytes = (addrbits==32 ? 4 : 2);
1256 output->modrm = (addrbits==32 ? 5 : 6) | (rfield << 3);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001257 }
1258 else { /* it's an indirection */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001259 int i=input->indexreg, b=input->basereg, s=input->scale;
1260 long o=input->offset, seg=input->segment;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001261 int hb=input->hintbase, ht=input->hinttype;
1262 int t;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001263
1264 if (s==0) i = -1; /* make this easy, at least */
1265
1266 if (i==R_EAX || i==R_EBX || i==R_ECX || i==R_EDX
1267 || i==R_EBP || i==R_ESP || i==R_ESI || i==R_EDI
1268 || 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 /* it must be a 32-bit memory reference. Firstly we have
1271 * to check that all registers involved are type Exx. */
1272 if (i!=-1 && i!=R_EAX && i!=R_EBX && i!=R_ECX && i!=R_EDX
1273 && i!=R_EBP && i!=R_ESP && i!=R_ESI && i!=R_EDI)
1274 return NULL;
1275 if (b!=-1 && b!=R_EAX && b!=R_EBX && b!=R_ECX && b!=R_EDX
1276 && b!=R_EBP && b!=R_ESP && b!=R_ESI && b!=R_EDI)
1277 return NULL;
1278
1279 /* While we're here, ensure the user didn't specify WORD. */
1280 if (input->addr_size == 16)
1281 return NULL;
1282
1283 /* now reorganise base/index */
H. Peter Anvin76690a12002-04-30 20:52:49 +00001284 if (s == 1 && b != i && b != -1 && i != -1 &&
1285 ((hb==b&&ht==EAH_NOTBASE) || (hb==i&&ht==EAH_MAKEBASE)))
1286 t = b, b = i, i = t; /* swap if hints say so */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001287 if (b==i) /* convert EAX+2*EAX to 3*EAX */
1288 b = -1, s++;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001289 if (b==-1 && s==1 && !(hb == i && ht == EAH_NOTBASE))
1290 b = i, i = -1; /* make single reg base, unless hint */
1291 if (((s==2 && i!=R_ESP && !(input->eaflags & EAF_TIMESTWO)) ||
1292 s==3 || s==5 || s==9) && b==-1)
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001293 b = i, s--; /* convert 3*EAX to EAX+2*EAX */
H. Peter Anvinea838272002-04-30 20:51:53 +00001294 if (s==1 && i==R_ESP) /* swap ESP into base if scale is 1 */
1295 i = b, b = R_ESP;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001296 if (i==R_ESP || (s!=1 && s!=2 && s!=4 && s!=8 && i!=-1))
1297 return NULL; /* wrong, for various reasons */
1298
1299 if (i==-1 && b!=R_ESP) {/* no SIB needed */
1300 int mod, rm;
1301 switch(b) {
1302 case R_EAX: rm = 0; break;
1303 case R_ECX: rm = 1; break;
1304 case R_EDX: rm = 2; break;
1305 case R_EBX: rm = 3; break;
1306 case R_EBP: rm = 5; break;
1307 case R_ESI: rm = 6; break;
1308 case R_EDI: rm = 7; break;
1309 case -1: rm = 5; break;
1310 default: /* should never happen */
1311 return NULL;
1312 }
H. Peter Anvinea838272002-04-30 20:51:53 +00001313 if (b==-1 || (b!=R_EBP && o==0 &&
H. Peter Anvin76690a12002-04-30 20:52:49 +00001314 seg==NO_SEG && !forw_ref &&
1315 !(input->eaflags &
1316 (EAF_BYTEOFFS|EAF_WORDOFFS))))
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001317 mod = 0;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001318 else if (input->eaflags & EAF_BYTEOFFS ||
1319 (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1320 !(input->eaflags & EAF_WORDOFFS))) {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001321 mod = 1;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001322 }
1323 else
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001324 mod = 2;
H. Peter Anvinea838272002-04-30 20:51:53 +00001325
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001326 output->sib_present = FALSE;
1327 output->bytes = (b==-1 || mod==2 ? 4 : mod);
1328 output->modrm = (mod<<6) | (rfield<<3) | rm;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001329 }
1330 else { /* we need a SIB */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001331 int mod, scale, index, base;
1332
1333 switch (b) {
1334 case R_EAX: base = 0; break;
1335 case R_ECX: base = 1; break;
1336 case R_EDX: base = 2; break;
1337 case R_EBX: base = 3; break;
1338 case R_ESP: base = 4; break;
1339 case R_EBP: case -1: base = 5; break;
1340 case R_ESI: base = 6; break;
1341 case R_EDI: base = 7; break;
1342 default: /* then what the smeg is it? */
1343 return NULL; /* panic */
1344 }
1345
1346 switch (i) {
1347 case R_EAX: index = 0; break;
1348 case R_ECX: index = 1; break;
1349 case R_EDX: index = 2; break;
1350 case R_EBX: index = 3; break;
1351 case -1: index = 4; break;
1352 case R_EBP: index = 5; break;
1353 case R_ESI: index = 6; break;
1354 case R_EDI: index = 7; break;
1355 default: /* then what the smeg is it? */
1356 return NULL; /* panic */
1357 }
1358
1359 if (i==-1) s = 1;
1360 switch (s) {
1361 case 1: scale = 0; break;
1362 case 2: scale = 1; break;
1363 case 4: scale = 2; break;
1364 case 8: scale = 3; break;
1365 default: /* then what the smeg is it? */
1366 return NULL; /* panic */
1367 }
1368
H. Peter Anvinea838272002-04-30 20:51:53 +00001369 if (b==-1 || (b!=R_EBP && o==0 &&
H. Peter Anvin76690a12002-04-30 20:52:49 +00001370 seg==NO_SEG && !forw_ref &&
1371 !(input->eaflags &
1372 (EAF_BYTEOFFS|EAF_WORDOFFS))))
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001373 mod = 0;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001374 else if (input->eaflags & EAF_BYTEOFFS ||
1375 (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1376 !(input->eaflags & EAF_WORDOFFS)))
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001377 mod = 1;
1378 else
1379 mod = 2;
1380
1381 output->sib_present = TRUE;
1382 output->bytes = (b==-1 || mod==2 ? 4 : mod);
1383 output->modrm = (mod<<6) | (rfield<<3) | 4;
1384 output->sib = (scale<<6) | (index<<3) | base;
1385 }
H. Peter Anvineba20a72002-04-30 20:53:55 +00001386 }
1387 else { /* it's 16-bit */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001388 int mod, rm;
1389
1390 /* check all registers are BX, BP, SI or DI */
1391 if ((b!=-1 && b!=R_BP && b!=R_BX && b!=R_SI && b!=R_DI) ||
1392 (i!=-1 && i!=R_BP && i!=R_BX && i!=R_SI && i!=R_DI))
1393 return NULL;
1394
1395 /* ensure the user didn't specify DWORD */
1396 if (input->addr_size == 32)
1397 return NULL;
1398
1399 if (s!=1 && i!=-1) return NULL;/* no can do, in 16-bit EA */
H. Peter Anvin87e1fcd2002-05-11 04:01:26 +00001400 if (b==-1 && i!=-1) { int tmp = b; b = i; i = tmp; } /* swap */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001401 if ((b==R_SI || b==R_DI) && i!=-1)
H. Peter Anvin87e1fcd2002-05-11 04:01:26 +00001402 { int tmp = b; b = i; i = tmp; }
1403 /* have BX/BP as base, SI/DI index */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001404 if (b==i) return NULL;/* shouldn't ever happen, in theory */
1405 if (i!=-1 && b!=-1 &&
1406 (i==R_BP || i==R_BX || b==R_SI || b==R_DI))
1407 return NULL; /* invalid combinations */
H. Peter Anvin87e1fcd2002-05-11 04:01:26 +00001408 if (b==-1) /* pure offset: handled above */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001409 return NULL; /* so if it gets to here, panic! */
1410
1411 rm = -1;
1412 if (i!=-1)
1413 switch (i*256 + b) {
1414 case R_SI*256+R_BX: rm=0; break;
1415 case R_DI*256+R_BX: rm=1; break;
1416 case R_SI*256+R_BP: rm=2; break;
1417 case R_DI*256+R_BP: rm=3; break;
1418 }
1419 else
1420 switch (b) {
1421 case R_SI: rm=4; break;
1422 case R_DI: rm=5; break;
1423 case R_BP: rm=6; break;
1424 case R_BX: rm=7; break;
1425 }
1426 if (rm==-1) /* can't happen, in theory */
1427 return NULL; /* so panic if it does */
1428
H. Peter Anvin76690a12002-04-30 20:52:49 +00001429 if (o==0 && seg==NO_SEG && !forw_ref && rm!=6 &&
1430 !(input->eaflags & (EAF_BYTEOFFS|EAF_WORDOFFS)))
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001431 mod = 0;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001432 else if (input->eaflags & EAF_BYTEOFFS ||
1433 (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1434 !(input->eaflags & EAF_WORDOFFS)))
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001435 mod = 1;
1436 else
1437 mod = 2;
1438
1439 output->sib_present = FALSE; /* no SIB - it's 16-bit */
1440 output->bytes = mod; /* bytes of offset needed */
1441 output->modrm = (mod<<6) | (rfield<<3) | rm;
1442 }
1443 }
1444 }
1445 output->size = 1 + output->sib_present + output->bytes;
1446 return output;
1447}
1448
H. Peter Anvineba20a72002-04-30 20:53:55 +00001449static int chsize (operand *input, int addrbits)
1450{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001451 if (!(MEMORY & ~input->type)) {
1452 int i=input->indexreg, b=input->basereg;
1453
1454 if (input->scale==0) i = -1;
1455
1456 if (i == -1 && b == -1) /* pure offset */
1457 return (input->addr_size != 0 && input->addr_size != addrbits);
1458
1459 if (i==R_EAX || i==R_EBX || i==R_ECX || i==R_EDX
1460 || i==R_EBP || i==R_ESP || i==R_ESI || i==R_EDI
1461 || b==R_EAX || b==R_EBX || b==R_ECX || b==R_EDX
1462 || b==R_EBP || b==R_ESP || b==R_ESI || b==R_EDI)
1463 return (addrbits==16);
1464 else
1465 return (addrbits==32);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001466 }
1467 else
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001468 return 0;
1469}