blob: b8eac2c2d0162189575b5d69afeb92d6af475b9e [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
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.
H. Peter Anvinaf535c12002-04-30 20:59:21 +000035 * \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.
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000041 * \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.
H. Peter Anvinaf535c12002-04-30 20:59:21 +000047 * \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000048 * \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.
H. Peter Anvinef7468f2002-04-30 20:57:59 +000055 * \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.
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000060 * \340 - reserve <operand 0> bytes of uninitialised storage.
61 * Operand 0 had better be a segmentless constant.
H. Peter Anvin788e6c12002-04-30 21:02:01 +000062 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
63 * 370 is used for Jcc, 371 is used for JMP.
H. Peter Anvinaf535c12002-04-30 20:59:21 +000064 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
65 * used for conditional jump over longer jump
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000066 */
67
68#include <stdio.h>
69#include <string.h>
70
71#include "nasm.h"
H. Peter Anvin6768eb72002-04-30 20:52:26 +000072#include "nasmlib.h"
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000073#include "assemble.h"
74#include "insns.h"
75
76extern struct itemplate *nasm_instructions[];
77
78typedef 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
H. Peter Anvinaf535c12002-04-30 20:59:21 +000085static unsigned long cpu; /* cpu level received from nasm.c */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000086static efunc errfunc;
87static struct ofmt *outfmt;
H. Peter Anvin6768eb72002-04-30 20:52:26 +000088static ListGen *list;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000089
90static long calcsize (long, long, int, insn *, char *);
91static void gencode (long, long, int, insn *, char *, long);
H. Peter Anvineba20a72002-04-30 20:53:55 +000092static int regval (operand *o);
93static int matches (struct itemplate *, insn *);
94static ea * process_ea (operand *, ea *, int, int, int);
95static int chsize (operand *, int);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000096
H. Peter Anvin6768eb72002-04-30 20:52:26 +000097/*
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 */
102static void out (long offset, long segto, void *data, unsigned long type,
H. Peter Anvineba20a72002-04-30 20:53:55 +0000103 long segment, long wrt)
104{
H. Peter Anvin9eb185b2002-04-30 21:02:47 +0000105 long lineno;
106 char *lnfname = NULL;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000107
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000108 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);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000115 }
116 else {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000117 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);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000125 }
126 else {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000127 WRITESHORT (q, * (long *) data);
128 list->output (offset, p, OUT_RAWDATA+2);
129 }
130 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000131 }
132 else if ((type & OUT_TYPMASK) == OUT_RAWDATA) {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000133 list->output (offset, data, type);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000134 }
135 else if ((type & OUT_TYPMASK) == OUT_RESERVE) {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000136 list->output (offset, NULL, type);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000137 }
138 else if ((type & OUT_TYPMASK) == OUT_REL2ADR ||
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000139 (type & OUT_TYPMASK) == OUT_REL4ADR) {
140 list->output (offset, data, type);
141 }
142
H. Peter Anvineba20a72002-04-30 20:53:55 +0000143 if (src_get(&lineno,&lnfname))
H. Peter Anvince616072002-04-30 21:02:23 +0000144 {
H. Peter Anvineba20a72002-04-30 20:53:55 +0000145 outfmt->current_dfmt->linenum(lnfname,lineno,segto);
H. Peter Anvin9eb185b2002-04-30 21:02:47 +0000146 if (lnfname) nasm_free(lnfname);
H. Peter Anvince616072002-04-30 21:02:23 +0000147 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000148
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000149 outfmt->output (segto, data, type, segment, wrt);
150}
151
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000152static 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
H. Peter Anvin788e6c12002-04-30 21:02:01 +0000158 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 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000163 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
172long assemble (long segment, long offset, int bits, unsigned long cp,
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000173 insn *instruction, struct ofmt *output, efunc error,
H. Peter Anvineba20a72002-04-30 20:53:55 +0000174 ListGen *listgen)
175{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000176 struct itemplate *temp;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000177 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. */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000183
184 errfunc = error; /* to pass to other functions */
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000185 cpu = cp;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000186 outfmt = output; /* likewise */
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000187 list = listgen; /* and again */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000188
H. Peter Anvineba20a72002-04-30 20:53:55 +0000189 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 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000198
H. Peter Anvineba20a72002-04-30 20:53:55 +0000199 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);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000204
H. Peter Anvineba20a72002-04-30 20:53:55 +0000205 while (t--) /* repeat TIMES times */
206 {
207 for (e = instruction->eops; e; e = e->next)
208 {
209 if (e->type == EOT_DB_NUMBER)
210 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000211 if (wsize == 1) {
212 if (e->segment != NO_SEG)
213 errfunc (ERR_NONFATAL,
214 "one-byte relocation attempted");
215 else {
H. Peter Anvin41bf8002002-04-30 20:58:18 +0000216 unsigned char out_byte = e->offset;
217 out (offset, segment, &out_byte, OUT_RAWDATA+1,
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000218 NO_SEG, NO_SEG);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000219 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000220 }
221 else if (wsize > 5) {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000222 errfunc (ERR_NONFATAL, "integer supplied to a D%c"
223 " instruction", wsize==8 ? 'Q' : 'T');
H. Peter Anvineba20a72002-04-30 20:53:55 +0000224 }
225 else
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000226 out (offset, segment, &e->offset,
227 OUT_ADDRESS+wsize, e->segment,
228 e->wrt);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000229 offset += wsize;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000230 }
231 else if (e->type == EOT_DB_STRING)
232 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000233 int align;
234
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000235 out (offset, segment, e->stringval,
236 OUT_RAWDATA+e->stringlen, NO_SEG, NO_SEG);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000237 align = e->stringlen % wsize;
238
239 if (align) {
240 align = wsize - align;
241 out (offset, segment, "\0\0\0\0\0\0\0\0",
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000242 OUT_RAWDATA+align, NO_SEG, NO_SEG);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000243 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000244 offset += e->stringlen + align;
245 }
246 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000247 if (t > 0 && t == instruction->times-1)
248 {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000249 /*
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 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000256 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000257 if (instruction->times > 1)
258 list->downlevel (LIST_TIMES);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000259 return offset - start;
260 }
261
H. Peter Anvineba20a72002-04-30 20:53:55 +0000262 if (instruction->opcode == I_INCBIN)
263 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000264 static char fname[FILENAME_MAX];
H. Peter Anvineba20a72002-04-30 20:53:55 +0000265 FILE * fp;
266 long len;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000267
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';
H. Peter Anvineba20a72002-04-30 20:53:55 +0000273
274 if ( (fp = fopen(fname, "rb")) == NULL)
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000275 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);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000279 else
280 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000281 static char buf[2048];
282 long t = instruction->times;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000283 long base = 0;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000284
285 len = ftell (fp);
286 if (instruction->eops->next) {
H. Peter Anvineba20a72002-04-30 20:53:55 +0000287 base = instruction->eops->next->offset;
288 len -= base;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000289 if (instruction->eops->next->next &&
290 len > instruction->eops->next->next->offset)
291 len = instruction->eops->next->next->offset;
292 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000293 /*
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);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000299 while (t--)
300 {
301 long l;
302
303 fseek (fp, base, SEEK_SET);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000304 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);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000316 t=0; /* Try to exit cleanly */
317 break;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000318 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000319 out (offset, segment, buf, OUT_RAWDATA+m,
320 NO_SEG, NO_SEG);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000321 l -= m;
322 }
323 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000324 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 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000334 fclose (fp);
335 return instruction->times * len;
336 }
337 return 0; /* if we're here, there's an error */
338 }
339
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000340 size_prob = FALSE;
341 temp = nasm_instructions[instruction->opcode];
342 while (temp->opcode != -1) {
343 int m = matches (temp, instruction);
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000344 if (m == 99)
345 m += jmp_match(segment, offset, bits, instruction, temp->code);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000346
347 if (m == 100) /* matches! */
348 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000349 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++) {
H. Peter Anvineba20a72002-04-30 20:53:55 +0000358 unsigned char c=0;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000359 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:
H. Peter Anvineba20a72002-04-30 20:53:55 +0000373 if (bits != 16)
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000374 c = 0x67;
375 break;
376 case P_A32:
H. Peter Anvineba20a72002-04-30 20:53:55 +0000377 if (bits != 32)
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000378 c = 0x67;
379 break;
380 case P_O16:
H. Peter Anvineba20a72002-04-30 20:53:55 +0000381 if (bits != 16)
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000382 c = 0x66;
383 break;
384 case P_O32:
H. Peter Anvineba20a72002-04-30 20:53:55 +0000385 if (bits != 32)
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000386 c = 0x66;
387 break;
388 default:
389 error (ERR_PANIC,
390 "invalid instruction prefix");
391 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000392 if (c != 0) {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000393 out (offset, segment, &c, OUT_RAWDATA+1,
394 NO_SEG, NO_SEG);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000395 offset++;
396 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000397 }
398 gencode (segment, offset, bits, instruction, codes, insn_end);
399 offset += insn_size;
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000400 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 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000408 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000409 if (instruction->times > 1)
410 list->downlevel (LIST_TIMES);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000411 return offset - start;
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000412 } else if (m > 0 && m > size_prob) {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000413 size_prob = m;
414 }
415 temp++;
416 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000417
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000418 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");
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000423 else if (size_prob == 3)
424 error (ERR_NONFATAL, "no instruction for this cpu level");
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000425 else
426 error (ERR_NONFATAL,
427 "invalid combination of opcode and operands");
428 }
429 return 0;
430}
431
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000432long insn_size (long segment, long offset, int bits, unsigned long cp,
H. Peter Anvineba20a72002-04-30 20:53:55 +0000433 insn *instruction, efunc error)
434{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000435 struct itemplate *temp;
436
437 errfunc = error; /* to pass to other functions */
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000438 cpu = cp;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000439
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 ||
H. Peter Anvineba20a72002-04-30 20:53:55 +0000447 instruction->opcode == I_DT)
448 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000449 extop *e;
450 long isize, osize, wsize = 0; /* placate gcc */
451
452 isize = 0;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000453 switch (instruction->opcode)
454 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000455 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
H. Peter Anvineba20a72002-04-30 20:53:55 +0000462 for (e = instruction->eops; e; e = e->next)
463 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000464 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
H. Peter Anvineba20a72002-04-30 20:53:55 +0000480 if (instruction->opcode == I_INCBIN)
481 {
482 char fname[FILENAME_MAX];
483 FILE * fp;
484 long len;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000485
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';
H. Peter Anvineba20a72002-04-30 20:53:55 +0000491 if ( (fp = fopen(fname, "rb")) == NULL )
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000492 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);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000496 else
497 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000498 len = ftell (fp);
499 fclose (fp);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000500 if (instruction->eops->next)
501 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000502 len -= instruction->eops->next->offset;
503 if (instruction->eops->next->next &&
504 len > instruction->eops->next->next->offset)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000505 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000506 len = instruction->eops->next->next->offset;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000507 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000508 }
509 return instruction->times * len;
510 }
511 return 0; /* if we're here, there's an error */
512 }
513
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000514 temp = nasm_instructions[instruction->opcode];
515 while (temp->opcode != -1) {
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000516 int m = matches(temp, instruction);
517 if (m == 99)
518 m += jmp_match(segment, offset, bits, instruction, temp->code);
519
520 if (m == 100) {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000521 /* we've matched an instruction. */
H. Peter Anvineba20a72002-04-30 20:53:55 +0000522 long isize;
523 char * codes = temp->code;
524 int j;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000525
526 isize = calcsize(segment, offset, bits, instruction, codes);
527 if (isize < 0)
528 return -1;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000529 for (j = 0; j < instruction->nprefix; j++)
530 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000531 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))
H. Peter Anvineba20a72002-04-30 20:53:55 +0000535 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000536 isize++;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000537 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000538 }
539 return isize * instruction->times;
540 }
541 temp++;
542 }
543 return -1; /* didn't match any instruction */
544}
545
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000546
547/* check that opn[op] is a signed byte of size 16 or 32,
548 and return the signed value*/
549static 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 */
H. Peter Anvin09f6acb2002-04-30 21:05:55 +0000555 optimizing>=0 &&
556/* !(ins->oprs[op].type & (BITS16|BITS32)) && */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000557 ins->oprs[op].wrt==NO_SEG && ins->oprs[op].segment==NO_SEG;
558
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000559 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
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000565static long calcsize (long segment, long offset, int bits,
H. Peter Anvineba20a72002-04-30 20:53:55 +0000566 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 */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000573
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;
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000607 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;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000615 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;
H. Peter Anvinef7468f2002-04-30 20:57:59 +0000636 case 0331:
637 case 0332:
638 break;
639 case 0333:
640 length++; break;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000641 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;
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000648 case 0370: case 0371: case 0372:
649 break;
650 case 0373:
651 length++; break;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000652 default: /* can't do it by 'case' statements */
653 if (c>=0100 && c<=0277) { /* it's an EA */
654 ea ea_data;
H. Peter Anvinea838272002-04-30 20:51:53 +0000655 if (!process_ea (&ins->oprs[(c>>3)&7], &ea_data, bits, 0,
656 ins->forw_ref)) {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000657 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
668static void gencode (long segment, long offset, int bits,
H. Peter Anvineba20a72002-04-30 20:53:55 +0000669 insn *ins, char *codes, long insn_end)
670{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000671 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 };
H. Peter Anvineba20a72002-04-30 20:53:55 +0000676 unsigned char c;
677 unsigned char bytes[4];
678 long data, size;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000679
H. Peter Anvineba20a72002-04-30 20:53:55 +0000680 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;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000688
H. Peter Anvineba20a72002-04-30 20:53:55 +0000689 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:
H. Peter Anvin4836e332002-04-30 20:56:43 +0000701 errfunc (ERR_PANIC, "bizarre 8086 segment register received");
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000702 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000703 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:
H. Peter Anvin4836e332002-04-30 20:56:43 +0000712 errfunc (ERR_PANIC, "bizarre 386 segment register received");
H. Peter Anvineba20a72002-04-30 20:53:55 +0000713 }
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);
H. Peter Anvin4cf17482002-04-30 21:01:38 +0000801 if (size==2 && (data < -65536L || data > 65535L))
H. Peter Anvineba20a72002-04-30 20:53:55 +0000802 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
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000880 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
H. Peter Anvineba20a72002-04-30 20:53:55 +0000925 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:
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000982 *bytes = *codes++ ^ condval[ins->condition];
H. Peter Anvineba20a72002-04-30 20:53:55 +0000983 out (offset, segment, bytes,
984 OUT_RAWDATA+1, NO_SEG, NO_SEG);
985 offset += 1;
986 break;
987
H. Peter Anvinef7468f2002-04-30 20:57:59 +0000988 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
H. Peter Anvineba20a72002-04-30 20:53:55 +0000999 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
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001011 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
H. Peter Anvineba20a72002-04-30 20:53:55 +00001021 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"
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001076 ": instruction code 0x%02X given", c);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001077 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001078}
1079
H. Peter Anvineba20a72002-04-30 20:53:55 +00001080static int regval (operand *o)
1081{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001082 switch (o->basereg) {
1083 case R_EAX: case R_AX: case R_AL: case R_ES: case R_CR0: case R_DR0:
H. Peter Anvin4836e332002-04-30 20:56:43 +00001084 case R_ST0: case R_MM0: case R_XMM0:
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001085 return 0;
1086 case R_ECX: case R_CX: case R_CL: case R_CS: case R_DR1: case R_ST1:
H. Peter Anvin4836e332002-04-30 20:56:43 +00001087 case R_MM1: case R_XMM1:
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001088 return 1;
1089 case R_EDX: case R_DX: case R_DL: case R_SS: case R_CR2: case R_DR2:
H. Peter Anvin4836e332002-04-30 20:56:43 +00001090 case R_ST2: case R_MM2: case R_XMM2:
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001091 return 2;
1092 case R_EBX: case R_BX: case R_BL: case R_DS: case R_CR3: case R_DR3:
H. Peter Anvin4836e332002-04-30 20:56:43 +00001093 case R_TR3: case R_ST3: case R_MM3: case R_XMM3:
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001094 return 3;
1095 case R_ESP: case R_SP: case R_AH: case R_FS: case R_CR4: case R_TR4:
H. Peter Anvin4836e332002-04-30 20:56:43 +00001096 case R_ST4: case R_MM4: case R_XMM4:
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001097 return 4;
1098 case R_EBP: case R_BP: case R_CH: case R_GS: case R_TR5: case R_ST5:
H. Peter Anvin4836e332002-04-30 20:56:43 +00001099 case R_MM5: case R_XMM5:
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001100 return 5;
1101 case R_ESI: case R_SI: case R_DH: case R_DR6: case R_TR6: case R_ST6:
H. Peter Anvin4836e332002-04-30 20:56:43 +00001102 case R_MM6: case R_XMM6:
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001103 return 6;
1104 case R_EDI: case R_DI: case R_BH: case R_DR7: case R_TR7: case R_ST7:
H. Peter Anvin4836e332002-04-30 20:56:43 +00001105 case R_MM7: case R_XMM7:
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001106 return 7;
1107 default: /* panic */
H. Peter Anvin4836e332002-04-30 20:56:43 +00001108 errfunc (ERR_PANIC, "invalid register operand given to regval()");
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001109 return 0;
1110 }
1111}
1112
H. Peter Anvineba20a72002-04-30 20:53:55 +00001113static int matches (struct itemplate *itemp, insn *instruction)
1114{
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001115 int i, size[3], asize, oprs, ret;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001116
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) &&
H. Peter Anvineba20a72002-04-30 20:53:55 +00001142 ((itemp->opd[i] ^ instruction->oprs[i].type) & SIZE_MASK)))
1143 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001144 if ((itemp->opd[i] & ~instruction->oprs[i].type & NON_SIZE) ||
1145 (instruction->oprs[i].type & SIZE_MASK))
1146 return 0;
1147 else
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001148/* ret = 1; */
1149 return 1;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001150 }
1151
1152 /*
1153 * Check operand sizes
1154 */
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001155 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 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001171 } else {
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001172 asize = 0;
1173 if (itemp->flags & IF_SB) {
1174 asize = BITS8;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001175 oprs = itemp->operands;
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001176 } 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;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001199 }
1200
1201 for (i=0; i<itemp->operands; i++)
1202 if (!(itemp->opd[i] & SIZE_MASK) &&
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001203 (instruction->oprs[i].type & SIZE_MASK & ~size[i]))
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001204/* ret = 2; */
1205 return 2;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001206
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001207 /*
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
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001217 return ret;
1218}
1219
H. Peter Anvinea838272002-04-30 20:51:53 +00001220static ea *process_ea (operand *input, ea *output, int addrbits, int rfield,
H. Peter Anvineba20a72002-04-30 20:53:55 +00001221 int forw_ref)
1222{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001223 if (!(REGISTER & ~input->type)) { /* it's a single register */
1224 static int regs[] = {
H. Peter Anvin4836e332002-04-30 20:56:43 +00001225 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
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001230 };
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 */
H. Peter Anvin4836e332002-04-30 20:56:43 +00001238 output->modrm = 0xC0 | (rfield << 3) | (i & 7);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001239 }
1240 else
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001241 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);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001250 }
1251 else { /* it's an indirection */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001252 int i=input->indexreg, b=input->basereg, s=input->scale;
1253 long o=input->offset, seg=input->segment;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001254 int hb=input->hintbase, ht=input->hinttype;
1255 int t;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001256
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 */
H. Peter Anvin76690a12002-04-30 20:52:49 +00001277 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 */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001280 if (b==i) /* convert EAX+2*EAX to 3*EAX */
1281 b = -1, s++;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001282 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)
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001286 b = i, s--; /* convert 3*EAX to EAX+2*EAX */
H. Peter Anvinea838272002-04-30 20:51:53 +00001287 if (s==1 && i==R_ESP) /* swap ESP into base if scale is 1 */
1288 i = b, b = R_ESP;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001289 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 }
H. Peter Anvinea838272002-04-30 20:51:53 +00001306 if (b==-1 || (b!=R_EBP && o==0 &&
H. Peter Anvin76690a12002-04-30 20:52:49 +00001307 seg==NO_SEG && !forw_ref &&
1308 !(input->eaflags &
1309 (EAF_BYTEOFFS|EAF_WORDOFFS))))
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001310 mod = 0;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001311 else if (input->eaflags & EAF_BYTEOFFS ||
1312 (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1313 !(input->eaflags & EAF_WORDOFFS))) {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001314 mod = 1;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001315 }
1316 else
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001317 mod = 2;
H. Peter Anvinea838272002-04-30 20:51:53 +00001318
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001319 output->sib_present = FALSE;
1320 output->bytes = (b==-1 || mod==2 ? 4 : mod);
1321 output->modrm = (mod<<6) | (rfield<<3) | rm;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001322 }
1323 else { /* we need a SIB */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001324 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
H. Peter Anvinea838272002-04-30 20:51:53 +00001362 if (b==-1 || (b!=R_EBP && o==0 &&
H. Peter Anvin76690a12002-04-30 20:52:49 +00001363 seg==NO_SEG && !forw_ref &&
1364 !(input->eaflags &
1365 (EAF_BYTEOFFS|EAF_WORDOFFS))))
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001366 mod = 0;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001367 else if (input->eaflags & EAF_BYTEOFFS ||
1368 (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1369 !(input->eaflags & EAF_WORDOFFS)))
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001370 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 }
H. Peter Anvineba20a72002-04-30 20:53:55 +00001379 }
1380 else { /* it's 16-bit */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001381 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 */
H. Peter Anvin87e1fcd2002-05-11 04:01:26 +00001393 if (b==-1 && i!=-1) { int tmp = b; b = i; i = tmp; } /* swap */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001394 if ((b==R_SI || b==R_DI) && i!=-1)
H. Peter Anvin87e1fcd2002-05-11 04:01:26 +00001395 { int tmp = b; b = i; i = tmp; }
1396 /* have BX/BP as base, SI/DI index */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001397 if (b==i) return NULL;/* shouldn't ever happen, in theory */
1398 if (i!=-1 && b!=-1 &&
1399 (i==R_BP || i==R_BX || b==R_SI || b==R_DI))
1400 return NULL; /* invalid combinations */
H. Peter Anvin87e1fcd2002-05-11 04:01:26 +00001401 if (b==-1) /* pure offset: handled above */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001402 return NULL; /* so if it gets to here, panic! */
1403
1404 rm = -1;
1405 if (i!=-1)
1406 switch (i*256 + b) {
1407 case R_SI*256+R_BX: rm=0; break;
1408 case R_DI*256+R_BX: rm=1; break;
1409 case R_SI*256+R_BP: rm=2; break;
1410 case R_DI*256+R_BP: rm=3; break;
1411 }
1412 else
1413 switch (b) {
1414 case R_SI: rm=4; break;
1415 case R_DI: rm=5; break;
1416 case R_BP: rm=6; break;
1417 case R_BX: rm=7; break;
1418 }
1419 if (rm==-1) /* can't happen, in theory */
1420 return NULL; /* so panic if it does */
1421
H. Peter Anvin76690a12002-04-30 20:52:49 +00001422 if (o==0 && seg==NO_SEG && !forw_ref && rm!=6 &&
1423 !(input->eaflags & (EAF_BYTEOFFS|EAF_WORDOFFS)))
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001424 mod = 0;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001425 else if (input->eaflags & EAF_BYTEOFFS ||
1426 (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1427 !(input->eaflags & EAF_WORDOFFS)))
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001428 mod = 1;
1429 else
1430 mod = 2;
1431
1432 output->sib_present = FALSE; /* no SIB - it's 16-bit */
1433 output->bytes = mod; /* bytes of offset needed */
1434 output->modrm = (mod<<6) | (rfield<<3) | rm;
1435 }
1436 }
1437 }
1438 output->size = 1 + output->sib_present + output->bytes;
1439 return output;
1440}
1441
H. Peter Anvineba20a72002-04-30 20:53:55 +00001442static int chsize (operand *input, int addrbits)
1443{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001444 if (!(MEMORY & ~input->type)) {
1445 int i=input->indexreg, b=input->basereg;
1446
1447 if (input->scale==0) i = -1;
1448
1449 if (i == -1 && b == -1) /* pure offset */
1450 return (input->addr_size != 0 && input->addr_size != addrbits);
1451
1452 if (i==R_EAX || i==R_EBX || i==R_ECX || i==R_EDX
1453 || i==R_EBP || i==R_ESP || i==R_ESI || i==R_EDI
1454 || b==R_EAX || b==R_EBX || b==R_ECX || b==R_EDX
1455 || b==R_EBP || b==R_ESP || b==R_ESI || b==R_EDI)
1456 return (addrbits==16);
1457 else
1458 return (addrbits==32);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001459 }
1460 else
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001461 return 0;
1462}