blob: 1e8b9b9e722062a65ab566eb8a76e8e37b1e9238 [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) {
H. Peter Anvin01377d82002-05-21 03:16:33 +0000160 if ((optimizing<0 || (ins->oprs[0].type & STRICT))
161 && c==0370) return 1;
H. Peter Anvin788e6c12002-04-30 21:02:01 +0000162 else return (pass0==0); /* match a forward reference */
163 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000164 isize = calcsize (segment, offset, bits, ins, code);
165 if (ins->oprs[0].segment != segment) return 0;
166 isize = ins->oprs[0].offset - offset - isize; /* isize is now the delta */
167 if (isize >= -128L && isize <= 127L) return 1; /* it is byte size */
168
169 return 0;
170}
171
172
173long assemble (long segment, long offset, int bits, unsigned long cp,
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000174 insn *instruction, struct ofmt *output, efunc error,
H. Peter Anvineba20a72002-04-30 20:53:55 +0000175 ListGen *listgen)
176{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000177 struct itemplate *temp;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000178 int j;
179 int size_prob;
180 long insn_end;
181 long itimes;
182 long start = offset;
183 long wsize = 0; /* size for DB etc. */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000184
185 errfunc = error; /* to pass to other functions */
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000186 cpu = cp;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000187 outfmt = output; /* likewise */
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000188 list = listgen; /* and again */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000189
H. Peter Anvineba20a72002-04-30 20:53:55 +0000190 switch (instruction->opcode)
191 {
192 case -1: return 0;
193 case I_DB: wsize = 1; break;
194 case I_DW: wsize = 2; break;
195 case I_DD: wsize = 4; break;
196 case I_DQ: wsize = 8; break;
197 case I_DT: wsize = 10; break;
198 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000199
H. Peter Anvineba20a72002-04-30 20:53:55 +0000200 if (wsize) {
201 extop * e;
202 long t = instruction->times;
203 if (t < 0)
204 errfunc(ERR_PANIC, "instruction->times < 0 (%ld) in assemble()",t);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000205
H. Peter Anvineba20a72002-04-30 20:53:55 +0000206 while (t--) /* repeat TIMES times */
207 {
208 for (e = instruction->eops; e; e = e->next)
209 {
210 if (e->type == EOT_DB_NUMBER)
211 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000212 if (wsize == 1) {
213 if (e->segment != NO_SEG)
214 errfunc (ERR_NONFATAL,
215 "one-byte relocation attempted");
216 else {
H. Peter Anvin41bf8002002-04-30 20:58:18 +0000217 unsigned char out_byte = e->offset;
218 out (offset, segment, &out_byte, OUT_RAWDATA+1,
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000219 NO_SEG, NO_SEG);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000220 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000221 }
222 else if (wsize > 5) {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000223 errfunc (ERR_NONFATAL, "integer supplied to a D%c"
224 " instruction", wsize==8 ? 'Q' : 'T');
H. Peter Anvineba20a72002-04-30 20:53:55 +0000225 }
226 else
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000227 out (offset, segment, &e->offset,
228 OUT_ADDRESS+wsize, e->segment,
229 e->wrt);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000230 offset += wsize;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000231 }
232 else if (e->type == EOT_DB_STRING)
233 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000234 int align;
235
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000236 out (offset, segment, e->stringval,
237 OUT_RAWDATA+e->stringlen, NO_SEG, NO_SEG);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000238 align = e->stringlen % wsize;
239
240 if (align) {
241 align = wsize - align;
242 out (offset, segment, "\0\0\0\0\0\0\0\0",
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000243 OUT_RAWDATA+align, NO_SEG, NO_SEG);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000244 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000245 offset += e->stringlen + align;
246 }
247 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000248 if (t > 0 && t == instruction->times-1)
249 {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000250 /*
251 * Dummy call to list->output to give the offset to the
252 * listing module.
253 */
254 list->output (offset, NULL, OUT_RAWDATA);
255 list->uplevel (LIST_TIMES);
256 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000257 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000258 if (instruction->times > 1)
259 list->downlevel (LIST_TIMES);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000260 return offset - start;
261 }
262
H. Peter Anvineba20a72002-04-30 20:53:55 +0000263 if (instruction->opcode == I_INCBIN)
264 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000265 static char fname[FILENAME_MAX];
H. Peter Anvineba20a72002-04-30 20:53:55 +0000266 FILE * fp;
267 long len;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000268
269 len = FILENAME_MAX-1;
270 if (len > instruction->eops->stringlen)
271 len = instruction->eops->stringlen;
272 strncpy (fname, instruction->eops->stringval, len);
273 fname[len] = '\0';
H. Peter Anvineba20a72002-04-30 20:53:55 +0000274
275 if ( (fp = fopen(fname, "rb")) == NULL)
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000276 error (ERR_NONFATAL, "`incbin': unable to open file `%s'", fname);
277 else if (fseek(fp, 0L, SEEK_END) < 0)
278 error (ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
279 fname);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000280 else
281 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000282 static char buf[2048];
283 long t = instruction->times;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000284 long base = 0;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000285
286 len = ftell (fp);
287 if (instruction->eops->next) {
H. Peter Anvineba20a72002-04-30 20:53:55 +0000288 base = instruction->eops->next->offset;
289 len -= base;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000290 if (instruction->eops->next->next &&
291 len > instruction->eops->next->next->offset)
292 len = instruction->eops->next->next->offset;
293 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000294 /*
295 * Dummy call to list->output to give the offset to the
296 * listing module.
297 */
298 list->output (offset, NULL, OUT_RAWDATA);
299 list->uplevel(LIST_INCBIN);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000300 while (t--)
301 {
302 long l;
303
304 fseek (fp, base, SEEK_SET);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000305 l = len;
306 while (l > 0) {
307 long m = fread (buf, 1, (l>sizeof(buf)?sizeof(buf):l),
308 fp);
309 if (!m) {
310 /*
311 * This shouldn't happen unless the file
312 * actually changes while we are reading
313 * it.
314 */
315 error (ERR_NONFATAL, "`incbin': unexpected EOF while"
316 " reading file `%s'", fname);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000317 t=0; /* Try to exit cleanly */
318 break;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000319 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000320 out (offset, segment, buf, OUT_RAWDATA+m,
321 NO_SEG, NO_SEG);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000322 l -= m;
323 }
324 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000325 list->downlevel(LIST_INCBIN);
326 if (instruction->times > 1) {
327 /*
328 * Dummy call to list->output to give the offset to the
329 * listing module.
330 */
331 list->output (offset, NULL, OUT_RAWDATA);
332 list->uplevel(LIST_TIMES);
333 list->downlevel(LIST_TIMES);
334 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000335 fclose (fp);
336 return instruction->times * len;
337 }
338 return 0; /* if we're here, there's an error */
339 }
340
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000341 size_prob = FALSE;
342 temp = nasm_instructions[instruction->opcode];
343 while (temp->opcode != -1) {
344 int m = matches (temp, instruction);
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000345 if (m == 99)
346 m += jmp_match(segment, offset, bits, instruction, temp->code);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000347
348 if (m == 100) /* matches! */
349 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000350 char *codes = temp->code;
351 long insn_size = calcsize(segment, offset, bits,
352 instruction, codes);
353 itimes = instruction->times;
354 if (insn_size < 0) /* shouldn't be, on pass two */
355 error (ERR_PANIC, "errors made it through from pass one");
356 else while (itimes--) {
357 insn_end = offset + insn_size;
358 for (j=0; j<instruction->nprefix; j++) {
H. Peter Anvineba20a72002-04-30 20:53:55 +0000359 unsigned char c=0;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000360 switch (instruction->prefixes[j]) {
361 case P_LOCK:
362 c = 0xF0; break;
363 case P_REPNE: case P_REPNZ:
364 c = 0xF2; break;
365 case P_REPE: case P_REPZ: case P_REP:
366 c = 0xF3; break;
367 case R_CS: c = 0x2E; break;
368 case R_DS: c = 0x3E; break;
369 case R_ES: c = 0x26; break;
370 case R_FS: c = 0x64; break;
371 case R_GS: c = 0x65; break;
372 case R_SS: c = 0x36; break;
373 case P_A16:
H. Peter Anvineba20a72002-04-30 20:53:55 +0000374 if (bits != 16)
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000375 c = 0x67;
376 break;
377 case P_A32:
H. Peter Anvineba20a72002-04-30 20:53:55 +0000378 if (bits != 32)
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000379 c = 0x67;
380 break;
381 case P_O16:
H. Peter Anvineba20a72002-04-30 20:53:55 +0000382 if (bits != 16)
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000383 c = 0x66;
384 break;
385 case P_O32:
H. Peter Anvineba20a72002-04-30 20:53:55 +0000386 if (bits != 32)
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000387 c = 0x66;
388 break;
389 default:
390 error (ERR_PANIC,
391 "invalid instruction prefix");
392 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000393 if (c != 0) {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000394 out (offset, segment, &c, OUT_RAWDATA+1,
395 NO_SEG, NO_SEG);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000396 offset++;
397 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000398 }
399 gencode (segment, offset, bits, instruction, codes, insn_end);
400 offset += insn_size;
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000401 if (itimes > 0 && itimes == instruction->times-1) {
402 /*
403 * Dummy call to list->output to give the offset to the
404 * listing module.
405 */
406 list->output (offset, NULL, OUT_RAWDATA);
407 list->uplevel (LIST_TIMES);
408 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000409 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000410 if (instruction->times > 1)
411 list->downlevel (LIST_TIMES);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000412 return offset - start;
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000413 } else if (m > 0 && m > size_prob) {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000414 size_prob = m;
415 }
416 temp++;
417 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000418
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000419 if (temp->opcode == -1) { /* didn't match any instruction */
420 if (size_prob == 1) /* would have matched, but for size */
421 error (ERR_NONFATAL, "operation size not specified");
422 else if (size_prob == 2)
423 error (ERR_NONFATAL, "mismatch in operand sizes");
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000424 else if (size_prob == 3)
425 error (ERR_NONFATAL, "no instruction for this cpu level");
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000426 else
427 error (ERR_NONFATAL,
428 "invalid combination of opcode and operands");
429 }
430 return 0;
431}
432
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000433long insn_size (long segment, long offset, int bits, unsigned long cp,
H. Peter Anvineba20a72002-04-30 20:53:55 +0000434 insn *instruction, efunc error)
435{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000436 struct itemplate *temp;
437
438 errfunc = error; /* to pass to other functions */
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000439 cpu = cp;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000440
441 if (instruction->opcode == -1)
442 return 0;
443
444 if (instruction->opcode == I_DB ||
445 instruction->opcode == I_DW ||
446 instruction->opcode == I_DD ||
447 instruction->opcode == I_DQ ||
H. Peter Anvineba20a72002-04-30 20:53:55 +0000448 instruction->opcode == I_DT)
449 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000450 extop *e;
451 long isize, osize, wsize = 0; /* placate gcc */
452
453 isize = 0;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000454 switch (instruction->opcode)
455 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000456 case I_DB: wsize = 1; break;
457 case I_DW: wsize = 2; break;
458 case I_DD: wsize = 4; break;
459 case I_DQ: wsize = 8; break;
460 case I_DT: wsize = 10; break;
461 }
462
H. Peter Anvineba20a72002-04-30 20:53:55 +0000463 for (e = instruction->eops; e; e = e->next)
464 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000465 long align;
466
467 osize = 0;
468 if (e->type == EOT_DB_NUMBER)
469 osize = 1;
470 else if (e->type == EOT_DB_STRING)
471 osize = e->stringlen;
472
473 align = (-osize) % wsize;
474 if (align < 0)
475 align += wsize;
476 isize += osize + align;
477 }
478 return isize * instruction->times;
479 }
480
H. Peter Anvineba20a72002-04-30 20:53:55 +0000481 if (instruction->opcode == I_INCBIN)
482 {
483 char fname[FILENAME_MAX];
484 FILE * fp;
485 long len;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000486
487 len = FILENAME_MAX-1;
488 if (len > instruction->eops->stringlen)
489 len = instruction->eops->stringlen;
490 strncpy (fname, instruction->eops->stringval, len);
491 fname[len] = '\0';
H. Peter Anvineba20a72002-04-30 20:53:55 +0000492 if ( (fp = fopen(fname, "rb")) == NULL )
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000493 error (ERR_NONFATAL, "`incbin': unable to open file `%s'", fname);
494 else if (fseek(fp, 0L, SEEK_END) < 0)
495 error (ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
496 fname);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000497 else
498 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000499 len = ftell (fp);
500 fclose (fp);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000501 if (instruction->eops->next)
502 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000503 len -= instruction->eops->next->offset;
504 if (instruction->eops->next->next &&
505 len > instruction->eops->next->next->offset)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000506 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000507 len = instruction->eops->next->next->offset;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000508 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000509 }
510 return instruction->times * len;
511 }
512 return 0; /* if we're here, there's an error */
513 }
514
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000515 temp = nasm_instructions[instruction->opcode];
516 while (temp->opcode != -1) {
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000517 int m = matches(temp, instruction);
518 if (m == 99)
519 m += jmp_match(segment, offset, bits, instruction, temp->code);
520
521 if (m == 100) {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000522 /* we've matched an instruction. */
H. Peter Anvineba20a72002-04-30 20:53:55 +0000523 long isize;
524 char * codes = temp->code;
525 int j;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000526
527 isize = calcsize(segment, offset, bits, instruction, codes);
528 if (isize < 0)
529 return -1;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000530 for (j = 0; j < instruction->nprefix; j++)
531 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000532 if ((instruction->prefixes[j] != P_A16 &&
533 instruction->prefixes[j] != P_O16 && bits==16) ||
534 (instruction->prefixes[j] != P_A32 &&
535 instruction->prefixes[j] != P_O32 && bits==32))
H. Peter Anvineba20a72002-04-30 20:53:55 +0000536 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000537 isize++;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000538 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000539 }
540 return isize * instruction->times;
541 }
542 temp++;
543 }
544 return -1; /* didn't match any instruction */
545}
546
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000547
548/* check that opn[op] is a signed byte of size 16 or 32,
549 and return the signed value*/
550static int is_sbyte (insn *ins, int op, int size)
551{
552 signed long v;
553 int ret;
554
555 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 +0000556 optimizing>=0 &&
557 !(ins->oprs[op].type & STRICT) &&
558 ins->oprs[op].wrt==NO_SEG && ins->oprs[op].segment==NO_SEG;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000559
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000560 v = ins->oprs[op].offset;
561 if (size==16) v = (signed short)v; /* sign extend if 16 bits */
562
563 return ret && v>=-128L && v<=127L;
564}
565
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000566static long calcsize (long segment, long offset, int bits,
H. Peter Anvineba20a72002-04-30 20:53:55 +0000567 insn *ins, char *codes)
568{
569 long length = 0;
570 unsigned char c;
571
572 (void) segment; /* Don't warn that this parameter is unused */
573 (void) offset; /* Don't warn that this parameter is unused */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000574
575 while (*codes) switch (c = *codes++) {
576 case 01: case 02: case 03:
577 codes += c, length += c; break;
578 case 04: case 05: case 06: case 07:
579 length++; break;
580 case 010: case 011: case 012:
581 codes++, length++; break;
582 case 017:
583 length++; break;
584 case 014: case 015: case 016:
585 length++; break;
586 case 020: case 021: case 022:
587 length++; break;
588 case 024: case 025: case 026:
589 length++; break;
590 case 030: case 031: case 032:
591 length += 2; break;
592 case 034: case 035: case 036:
593 length += ((ins->oprs[c-034].addr_size ?
594 ins->oprs[c-034].addr_size : bits) == 16 ? 2 : 4); break;
595 case 037:
596 length += 2; break;
597 case 040: case 041: case 042:
598 length += 4; break;
599 case 050: case 051: case 052:
600 length++; break;
601 case 060: case 061: case 062:
602 length += 2; break;
603 case 064: case 065: case 066:
604 length += ((ins->oprs[c-064].addr_size ?
605 ins->oprs[c-064].addr_size : bits) == 16 ? 2 : 4); break;
606 case 070: case 071: case 072:
607 length += 4; break;
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000608 case 0130: case 0131: case 0132:
609 length += is_sbyte(ins, c-0130, 16) ? 1 : 2; break;
610 case 0133: case 0134: case 0135:
611 codes+=2; length++; break;
612 case 0140: case 0141: case 0142:
613 length += is_sbyte(ins, c-0140, 32) ? 1 : 4; break;
614 case 0143: case 0144: case 0145:
615 codes+=2; length++; break;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000616 case 0300: case 0301: case 0302:
617 length += chsize (&ins->oprs[c-0300], bits);
618 break;
619 case 0310:
620 length += (bits==32);
621 break;
622 case 0311:
623 length += (bits==16);
624 break;
625 case 0312:
626 break;
627 case 0320:
628 length += (bits==32);
629 break;
630 case 0321:
631 length += (bits==16);
632 break;
633 case 0322:
634 break;
635 case 0330:
636 codes++, length++; break;
H. Peter Anvinef7468f2002-04-30 20:57:59 +0000637 case 0331:
638 case 0332:
639 break;
640 case 0333:
641 length++; break;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000642 case 0340: case 0341: case 0342:
643 if (ins->oprs[0].segment != NO_SEG)
644 errfunc (ERR_NONFATAL, "attempt to reserve non-constant"
645 " quantity of BSS space");
646 else
647 length += ins->oprs[0].offset << (c-0340);
648 break;
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000649 case 0370: case 0371: case 0372:
650 break;
651 case 0373:
652 length++; break;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000653 default: /* can't do it by 'case' statements */
654 if (c>=0100 && c<=0277) { /* it's an EA */
655 ea ea_data;
H. Peter Anvinea838272002-04-30 20:51:53 +0000656 if (!process_ea (&ins->oprs[(c>>3)&7], &ea_data, bits, 0,
657 ins->forw_ref)) {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000658 errfunc (ERR_NONFATAL, "invalid effective address");
659 return -1;
660 } else
661 length += ea_data.size;
662 } else
663 errfunc (ERR_PANIC, "internal instruction table corrupt"
664 ": instruction code 0x%02X given", c);
665 }
666 return length;
667}
668
669static void gencode (long segment, long offset, int bits,
H. Peter Anvineba20a72002-04-30 20:53:55 +0000670 insn *ins, char *codes, long insn_end)
671{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000672 static char condval[] = { /* conditional opcodes */
673 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
674 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
675 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
676 };
H. Peter Anvineba20a72002-04-30 20:53:55 +0000677 unsigned char c;
678 unsigned char bytes[4];
679 long data, size;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000680
H. Peter Anvineba20a72002-04-30 20:53:55 +0000681 while (*codes)
682 switch (c = *codes++)
683 {
684 case 01: case 02: case 03:
685 out (offset, segment, codes, OUT_RAWDATA+c, NO_SEG, NO_SEG);
686 codes += c;
687 offset += c;
688 break;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000689
H. Peter Anvineba20a72002-04-30 20:53:55 +0000690 case 04: case 06:
691 switch (ins->oprs[0].basereg)
692 {
693 case R_CS:
694 bytes[0] = 0x0E + (c == 0x04 ? 1 : 0); break;
695 case R_DS:
696 bytes[0] = 0x1E + (c == 0x04 ? 1 : 0); break;
697 case R_ES:
698 bytes[0] = 0x06 + (c == 0x04 ? 1 : 0); break;
699 case R_SS:
700 bytes[0] = 0x16 + (c == 0x04 ? 1 : 0); break;
701 default:
H. Peter Anvin4836e332002-04-30 20:56:43 +0000702 errfunc (ERR_PANIC, "bizarre 8086 segment register received");
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000703 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000704 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
705 offset++;
706 break;
707
708 case 05: case 07:
709 switch (ins->oprs[0].basereg) {
710 case R_FS: bytes[0] = 0xA0 + (c == 0x05 ? 1 : 0); break;
711 case R_GS: bytes[0] = 0xA8 + (c == 0x05 ? 1 : 0); break;
712 default:
H. Peter Anvin4836e332002-04-30 20:56:43 +0000713 errfunc (ERR_PANIC, "bizarre 386 segment register received");
H. Peter Anvineba20a72002-04-30 20:53:55 +0000714 }
715 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
716 offset++;
717 break;
718
719 case 010: case 011: case 012:
720 bytes[0] = *codes++ + regval(&ins->oprs[c-010]);
721 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
722 offset += 1;
723 break;
724
725 case 017:
726 bytes[0] = 0;
727 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
728 offset += 1;
729 break;
730
731 case 014: case 015: case 016:
732 if (ins->oprs[c-014].offset < -128
733 || ins->oprs[c-014].offset > 127)
734 {
735 errfunc (ERR_WARNING, "signed byte value exceeds bounds");
736 }
737
738 if (ins->oprs[c-014].segment != NO_SEG)
739 {
740 data = ins->oprs[c-014].offset;
741 out (offset, segment, &data, OUT_ADDRESS+1,
742 ins->oprs[c-014].segment, ins->oprs[c-014].wrt);
743 }
744 else {
745 bytes[0] = ins->oprs[c-014].offset;
746 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
747 }
748 offset += 1;
749 break;
750
751 case 020: case 021: case 022:
752 if (ins->oprs[c-020].offset < -256
753 || ins->oprs[c-020].offset > 255)
754 {
755 errfunc (ERR_WARNING, "byte value exceeds bounds");
756 }
757 if (ins->oprs[c-020].segment != NO_SEG) {
758 data = ins->oprs[c-020].offset;
759 out (offset, segment, &data, OUT_ADDRESS+1,
760 ins->oprs[c-020].segment, ins->oprs[c-020].wrt);
761 }
762 else {
763 bytes[0] = ins->oprs[c-020].offset;
764 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
765 }
766 offset += 1;
767 break;
768
769 case 024: case 025: case 026:
770 if (ins->oprs[c-024].offset < 0 || ins->oprs[c-024].offset > 255)
771 errfunc (ERR_WARNING, "unsigned byte value exceeds bounds");
772 if (ins->oprs[c-024].segment != NO_SEG) {
773 data = ins->oprs[c-024].offset;
774 out (offset, segment, &data, OUT_ADDRESS+1,
775 ins->oprs[c-024].segment, ins->oprs[c-024].wrt);
776 }
777 else {
778 bytes[0] = ins->oprs[c-024].offset;
779 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
780 }
781 offset += 1;
782 break;
783
784 case 030: case 031: case 032:
785 if (ins->oprs[c-030].segment == NO_SEG &&
786 ins->oprs[c-030].wrt == NO_SEG &&
787 (ins->oprs[c-030].offset < -65536L ||
788 ins->oprs[c-030].offset > 65535L))
789 {
790 errfunc (ERR_WARNING, "word value exceeds bounds");
791 }
792 data = ins->oprs[c-030].offset;
793 out (offset, segment, &data, OUT_ADDRESS+2,
794 ins->oprs[c-030].segment, ins->oprs[c-030].wrt);
795 offset += 2;
796 break;
797
798 case 034: case 035: case 036:
799 data = ins->oprs[c-034].offset;
800 size = ((ins->oprs[c-034].addr_size ?
801 ins->oprs[c-034].addr_size : bits) == 16 ? 2 : 4);
H. Peter Anvin4cf17482002-04-30 21:01:38 +0000802 if (size==2 && (data < -65536L || data > 65535L))
H. Peter Anvineba20a72002-04-30 20:53:55 +0000803 errfunc (ERR_WARNING, "word value exceeds bounds");
804 out (offset, segment, &data, OUT_ADDRESS+size,
805 ins->oprs[c-034].segment, ins->oprs[c-034].wrt);
806 offset += size;
807 break;
808
809 case 037:
810 if (ins->oprs[0].segment == NO_SEG)
811 errfunc (ERR_NONFATAL, "value referenced by FAR is not"
812 " relocatable");
813 data = 0L;
814 out (offset, segment, &data, OUT_ADDRESS+2,
815 outfmt->segbase(1+ins->oprs[0].segment),
816 ins->oprs[0].wrt);
817 offset += 2;
818 break;
819
820 case 040: case 041: case 042:
821 data = ins->oprs[c-040].offset;
822 out (offset, segment, &data, OUT_ADDRESS+4,
823 ins->oprs[c-040].segment, ins->oprs[c-040].wrt);
824 offset += 4;
825 break;
826
827 case 050: case 051: case 052:
828 if (ins->oprs[c-050].segment != segment)
829 errfunc (ERR_NONFATAL, "short relative jump outside segment");
830 data = ins->oprs[c-050].offset - insn_end;
831 if (data > 127 || data < -128)
832 errfunc (ERR_NONFATAL, "short jump is out of range");
833 bytes[0] = data;
834 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
835 offset += 1;
836 break;
837
838 case 060: case 061: case 062:
839 if (ins->oprs[c-060].segment != segment) {
840 data = ins->oprs[c-060].offset;
841 out (offset, segment, &data, OUT_REL2ADR+insn_end-offset,
842 ins->oprs[c-060].segment, ins->oprs[c-060].wrt);
843 } else {
844 data = ins->oprs[c-060].offset - insn_end;
845 out (offset, segment, &data,
846 OUT_ADDRESS+2, NO_SEG, NO_SEG);
847 }
848 offset += 2;
849 break;
850
851 case 064: case 065: case 066:
852 size = ((ins->oprs[c-064].addr_size ?
853 ins->oprs[c-064].addr_size : bits) == 16 ? 2 : 4);
854 if (ins->oprs[c-064].segment != segment) {
855 data = ins->oprs[c-064].offset;
856 size = (bits == 16 ? OUT_REL2ADR : OUT_REL4ADR);
857 out (offset, segment, &data, size+insn_end-offset,
858 ins->oprs[c-064].segment, ins->oprs[c-064].wrt);
859 size = (bits == 16 ? 2 : 4);
860 } else {
861 data = ins->oprs[c-064].offset - insn_end;
862 out (offset, segment, &data,
863 OUT_ADDRESS+size, NO_SEG, NO_SEG);
864 }
865 offset += size;
866 break;
867
868 case 070: case 071: case 072:
869 if (ins->oprs[c-070].segment != segment) {
870 data = ins->oprs[c-070].offset;
871 out (offset, segment, &data, OUT_REL4ADR+insn_end-offset,
872 ins->oprs[c-070].segment, ins->oprs[c-070].wrt);
873 } else {
874 data = ins->oprs[c-070].offset - insn_end;
875 out (offset, segment, &data,
876 OUT_ADDRESS+4, NO_SEG, NO_SEG);
877 }
878 offset += 4;
879 break;
880
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000881 case 0130: case 0131: case 0132:
882 data = ins->oprs[c-0130].offset;
883 if (is_sbyte(ins, c-0130, 16)) {
884 out (offset, segment, &data, OUT_RAWDATA+1, NO_SEG, NO_SEG);
885 offset++;
886 } else {
887 if (ins->oprs[c-0130].segment == NO_SEG &&
888 ins->oprs[c-0130].wrt == NO_SEG &&
889 (data < -65536L || data > 65535L)) {
890 errfunc (ERR_WARNING, "word value exceeds bounds");
891 }
892 out (offset, segment, &data, OUT_ADDRESS+2,
893 ins->oprs[c-0130].segment, ins->oprs[c-0130].wrt);
894 offset += 2;
895 }
896 break;
897
898 case 0133: case 0134: case 0135:
899 codes++;
900 bytes[0] = *codes++;
901 if (is_sbyte(ins, c-0133, 16)) bytes[0] |= 2; /* s-bit */
902 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
903 offset++;
904 break;
905
906 case 0140: case 0141: case 0142:
907 data = ins->oprs[c-0140].offset;
908 if (is_sbyte(ins, c-0140, 32)) {
909 out (offset, segment, &data, OUT_RAWDATA+1, NO_SEG, NO_SEG);
910 offset++;
911 } else {
912 out (offset, segment, &data, OUT_ADDRESS+4,
913 ins->oprs[c-0140].segment, ins->oprs[c-0140].wrt);
914 offset += 4;
915 }
916 break;
917
918 case 0143: case 0144: case 0145:
919 codes++;
920 bytes[0] = *codes++;
921 if (is_sbyte(ins, c-0143, 32)) bytes[0] |= 2; /* s-bit */
922 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
923 offset++;
924 break;
925
H. Peter Anvineba20a72002-04-30 20:53:55 +0000926 case 0300: case 0301: case 0302:
927 if (chsize (&ins->oprs[c-0300], bits)) {
928 *bytes = 0x67;
929 out (offset, segment, bytes,
930 OUT_RAWDATA+1, NO_SEG, NO_SEG);
931 offset += 1;
932 } else
933 offset += 0;
934 break;
935
936 case 0310:
937 if (bits==32) {
938 *bytes = 0x67;
939 out (offset, segment, bytes,
940 OUT_RAWDATA+1, NO_SEG, NO_SEG);
941 offset += 1;
942 } else
943 offset += 0;
944 break;
945
946 case 0311:
947 if (bits==16) {
948 *bytes = 0x67;
949 out (offset, segment, bytes,
950 OUT_RAWDATA+1, NO_SEG, NO_SEG);
951 offset += 1;
952 } else
953 offset += 0;
954 break;
955
956 case 0312:
957 break;
958
959 case 0320:
960 if (bits==32) {
961 *bytes = 0x66;
962 out (offset, segment, bytes,
963 OUT_RAWDATA+1, NO_SEG, NO_SEG);
964 offset += 1;
965 } else
966 offset += 0;
967 break;
968
969 case 0321:
970 if (bits==16) {
971 *bytes = 0x66;
972 out (offset, segment, bytes,
973 OUT_RAWDATA+1, NO_SEG, NO_SEG);
974 offset += 1;
975 } else
976 offset += 0;
977 break;
978
979 case 0322:
980 break;
981
982 case 0330:
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000983 *bytes = *codes++ ^ condval[ins->condition];
H. Peter Anvineba20a72002-04-30 20:53:55 +0000984 out (offset, segment, bytes,
985 OUT_RAWDATA+1, NO_SEG, NO_SEG);
986 offset += 1;
987 break;
988
H. Peter Anvinef7468f2002-04-30 20:57:59 +0000989 case 0331:
990 case 0332:
991 break;
992
993 case 0333:
994 *bytes = 0xF3;
995 out (offset, segment, bytes,
996 OUT_RAWDATA+1, NO_SEG, NO_SEG);
997 offset += 1;
998 break;
999
H. Peter Anvineba20a72002-04-30 20:53:55 +00001000 case 0340: case 0341: case 0342:
1001 if (ins->oprs[0].segment != NO_SEG)
1002 errfunc (ERR_PANIC, "non-constant BSS size in pass two");
1003 else {
1004 long size = ins->oprs[0].offset << (c-0340);
1005 if (size > 0)
1006 out (offset, segment, NULL,
1007 OUT_RESERVE+size, NO_SEG, NO_SEG);
1008 offset += size;
1009 }
1010 break;
1011
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001012 case 0370: case 0371: case 0372:
1013 break;
1014
1015 case 0373:
1016 *bytes = bits==16 ? 3 : 5;
1017 out (offset, segment, bytes,
1018 OUT_RAWDATA+1, NO_SEG, NO_SEG);
1019 offset += 1;
1020 break;
1021
H. Peter Anvineba20a72002-04-30 20:53:55 +00001022 default: /* can't do it by 'case' statements */
1023 if (c>=0100 && c<=0277) { /* it's an EA */
1024 ea ea_data;
1025 int rfield;
1026 unsigned char *p;
1027 long s;
1028
1029 if (c<=0177) /* pick rfield from operand b */
1030 rfield = regval (&ins->oprs[c&7]);
1031 else /* rfield is constant */
1032 rfield = c & 7;
1033
1034 if (!process_ea (&ins->oprs[(c>>3)&7], &ea_data, bits, rfield,
1035 ins->forw_ref))
1036 {
1037 errfunc (ERR_NONFATAL, "invalid effective address");
1038 }
1039
1040 p = bytes;
1041 *p++ = ea_data.modrm;
1042 if (ea_data.sib_present)
1043 *p++ = ea_data.sib;
1044
1045 s = p-bytes;
1046 out (offset, segment, bytes, OUT_RAWDATA + s,
1047 NO_SEG, NO_SEG);
1048
1049 switch (ea_data.bytes) {
1050 case 0:
1051 break;
1052 case 1:
1053 if (ins->oprs[(c>>3)&7].segment != NO_SEG) {
1054 data = ins->oprs[(c>>3)&7].offset;
1055 out (offset, segment, &data, OUT_ADDRESS+1,
1056 ins->oprs[(c>>3)&7].segment,
1057 ins->oprs[(c>>3)&7].wrt);
1058 } else {
1059 *bytes = ins->oprs[(c>>3)&7].offset;
1060 out (offset, segment, bytes, OUT_RAWDATA+1,
1061 NO_SEG, NO_SEG);
1062 }
1063 s++;
1064 break;
1065 case 2:
1066 case 4:
1067 data = ins->oprs[(c>>3)&7].offset;
1068 out (offset, segment, &data,
1069 OUT_ADDRESS+ea_data.bytes,
1070 ins->oprs[(c>>3)&7].segment, ins->oprs[(c>>3)&7].wrt);
1071 s += ea_data.bytes;
1072 break;
1073 }
1074 offset += s;
1075 } else
1076 errfunc (ERR_PANIC, "internal instruction table corrupt"
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001077 ": instruction code 0x%02X given", c);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001078 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001079}
1080
H. Peter Anvineba20a72002-04-30 20:53:55 +00001081static int regval (operand *o)
1082{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001083 switch (o->basereg) {
1084 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 +00001085 case R_ST0: case R_MM0: case R_XMM0:
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001086 return 0;
1087 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 +00001088 case R_MM1: case R_XMM1:
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001089 return 1;
1090 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 +00001091 case R_ST2: case R_MM2: case R_XMM2:
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001092 return 2;
1093 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 +00001094 case R_TR3: case R_ST3: case R_MM3: case R_XMM3:
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001095 return 3;
1096 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 +00001097 case R_ST4: case R_MM4: case R_XMM4:
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001098 return 4;
1099 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 +00001100 case R_MM5: case R_XMM5:
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001101 return 5;
1102 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 +00001103 case R_MM6: case R_XMM6:
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001104 return 6;
1105 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 +00001106 case R_MM7: case R_XMM7:
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001107 return 7;
1108 default: /* panic */
H. Peter Anvin4836e332002-04-30 20:56:43 +00001109 errfunc (ERR_PANIC, "invalid register operand given to regval()");
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001110 return 0;
1111 }
1112}
1113
H. Peter Anvineba20a72002-04-30 20:53:55 +00001114static int matches (struct itemplate *itemp, insn *instruction)
1115{
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001116 int i, size[3], asize, oprs, ret;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001117
1118 ret = 100;
1119
1120 /*
1121 * Check the opcode
1122 */
1123 if (itemp->opcode != instruction->opcode) return 0;
1124
1125 /*
1126 * Count the operands
1127 */
1128 if (itemp->operands != instruction->operands) return 0;
1129
1130 /*
1131 * Check that no spurious colons or TOs are present
1132 */
1133 for (i=0; i<itemp->operands; i++)
1134 if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON|TO))
1135 return 0;
1136
1137 /*
1138 * Check that the operand flags all match up
1139 */
1140 for (i=0; i<itemp->operands; i++)
1141 if (itemp->opd[i] & ~instruction->oprs[i].type ||
1142 ((itemp->opd[i] & SIZE_MASK) &&
H. Peter Anvineba20a72002-04-30 20:53:55 +00001143 ((itemp->opd[i] ^ instruction->oprs[i].type) & SIZE_MASK)))
1144 {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001145 if ((itemp->opd[i] & ~instruction->oprs[i].type & NON_SIZE) ||
1146 (instruction->oprs[i].type & SIZE_MASK))
1147 return 0;
1148 else
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001149/* ret = 1; */
1150 return 1;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001151 }
1152
1153 /*
1154 * Check operand sizes
1155 */
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001156 if (itemp->flags & IF_ARMASK) {
1157 size[0] = size[1] = size[2] = 0;
1158
1159 switch (itemp->flags & IF_ARMASK) {
1160 case IF_AR0: i = 0; break;
1161 case IF_AR1: i = 1; break;
1162 case IF_AR2: i = 2; break;
1163 default: break; /* Shouldn't happen */
1164 }
1165 if (itemp->flags & IF_SB) {
1166 size[i] = BITS8;
1167 } else if (itemp->flags & IF_SW) {
1168 size[i] = BITS16;
1169 } else if (itemp->flags & IF_SD) {
1170 size[i] = BITS32;
1171 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001172 } else {
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001173 asize = 0;
1174 if (itemp->flags & IF_SB) {
1175 asize = BITS8;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001176 oprs = itemp->operands;
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001177 } else if (itemp->flags & IF_SW) {
1178 asize = BITS16;
1179 oprs = itemp->operands;
1180 } else if (itemp->flags & IF_SD) {
1181 asize = BITS32;
1182 oprs = itemp->operands;
1183 }
1184 size[0] = size[1] = size[2] = asize;
1185 }
1186
1187 if (itemp->flags & (IF_SM | IF_SM2)) {
1188 oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands);
1189 asize = 0;
1190 for (i=0; i<oprs; i++) {
1191 if ( (asize = itemp->opd[i] & SIZE_MASK) != 0) {
1192 int j;
1193 for (j=0; j<oprs; j++)
1194 size[j] = asize;
1195 break;
1196 }
1197 }
1198 } else {
1199 oprs = itemp->operands;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001200 }
1201
1202 for (i=0; i<itemp->operands; i++)
1203 if (!(itemp->opd[i] & SIZE_MASK) &&
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001204 (instruction->oprs[i].type & SIZE_MASK & ~size[i]))
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001205/* ret = 2; */
1206 return 2;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001207
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001208 /*
1209 * Check template is okay at the set cpu level
1210 */
1211 if ((itemp->flags & IF_PLEVEL) > cpu) return 3;
1212
1213 /*
1214 * Check if special handling needed for Jumps
1215 */
1216 if ((unsigned char)(itemp->code[0]) >= 0370) return 99;
1217
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001218 return ret;
1219}
1220
H. Peter Anvinea838272002-04-30 20:51:53 +00001221static ea *process_ea (operand *input, ea *output, int addrbits, int rfield,
H. Peter Anvineba20a72002-04-30 20:53:55 +00001222 int forw_ref)
1223{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001224 if (!(REGISTER & ~input->type)) { /* it's a single register */
1225 static int regs[] = {
H. Peter Anvin4836e332002-04-30 20:56:43 +00001226 R_AL, R_CL, R_DL, R_BL, R_AH, R_CH, R_DH, R_BH,
1227 R_AX, R_CX, R_DX, R_BX, R_SP, R_BP, R_SI, R_DI,
1228 R_EAX, R_ECX, R_EDX, R_EBX, R_ESP, R_EBP, R_ESI, R_EDI,
1229 R_MM0, R_MM1, R_MM2, R_MM3, R_MM4, R_MM5, R_MM6, R_MM7,
1230 R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001231 };
1232 int i;
1233
1234 for (i=0; i<elements(regs); i++)
1235 if (input->basereg == regs[i]) break;
1236 if (i<elements(regs)) {
1237 output->sib_present = FALSE;/* no SIB necessary */
1238 output->bytes = 0; /* no offset necessary either */
H. Peter Anvin4836e332002-04-30 20:56:43 +00001239 output->modrm = 0xC0 | (rfield << 3) | (i & 7);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001240 }
1241 else
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001242 return NULL;
1243 } else { /* it's a memory reference */
1244 if (input->basereg==-1 && (input->indexreg==-1 || input->scale==0)) {
1245 /* it's a pure offset */
1246 if (input->addr_size)
1247 addrbits = input->addr_size;
1248 output->sib_present = FALSE;
1249 output->bytes = (addrbits==32 ? 4 : 2);
1250 output->modrm = (addrbits==32 ? 5 : 6) | (rfield << 3);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001251 }
1252 else { /* it's an indirection */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001253 int i=input->indexreg, b=input->basereg, s=input->scale;
1254 long o=input->offset, seg=input->segment;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001255 int hb=input->hintbase, ht=input->hinttype;
1256 int t;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001257
1258 if (s==0) i = -1; /* make this easy, at least */
1259
1260 if (i==R_EAX || i==R_EBX || i==R_ECX || i==R_EDX
1261 || i==R_EBP || i==R_ESP || i==R_ESI || i==R_EDI
1262 || b==R_EAX || b==R_EBX || b==R_ECX || b==R_EDX
1263 || b==R_EBP || b==R_ESP || b==R_ESI || b==R_EDI) {
1264 /* it must be a 32-bit memory reference. Firstly we have
1265 * to check that all registers involved are type Exx. */
1266 if (i!=-1 && 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 return NULL;
1269 if (b!=-1 && b!=R_EAX && b!=R_EBX && b!=R_ECX && b!=R_EDX
1270 && b!=R_EBP && b!=R_ESP && b!=R_ESI && b!=R_EDI)
1271 return NULL;
1272
1273 /* While we're here, ensure the user didn't specify WORD. */
1274 if (input->addr_size == 16)
1275 return NULL;
1276
1277 /* now reorganise base/index */
H. Peter Anvin76690a12002-04-30 20:52:49 +00001278 if (s == 1 && b != i && b != -1 && i != -1 &&
1279 ((hb==b&&ht==EAH_NOTBASE) || (hb==i&&ht==EAH_MAKEBASE)))
1280 t = b, b = i, i = t; /* swap if hints say so */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001281 if (b==i) /* convert EAX+2*EAX to 3*EAX */
1282 b = -1, s++;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001283 if (b==-1 && s==1 && !(hb == i && ht == EAH_NOTBASE))
1284 b = i, i = -1; /* make single reg base, unless hint */
1285 if (((s==2 && i!=R_ESP && !(input->eaflags & EAF_TIMESTWO)) ||
1286 s==3 || s==5 || s==9) && b==-1)
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001287 b = i, s--; /* convert 3*EAX to EAX+2*EAX */
H. Peter Anvinea838272002-04-30 20:51:53 +00001288 if (s==1 && i==R_ESP) /* swap ESP into base if scale is 1 */
1289 i = b, b = R_ESP;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001290 if (i==R_ESP || (s!=1 && s!=2 && s!=4 && s!=8 && i!=-1))
1291 return NULL; /* wrong, for various reasons */
1292
1293 if (i==-1 && b!=R_ESP) {/* no SIB needed */
1294 int mod, rm;
1295 switch(b) {
1296 case R_EAX: rm = 0; break;
1297 case R_ECX: rm = 1; break;
1298 case R_EDX: rm = 2; break;
1299 case R_EBX: rm = 3; break;
1300 case R_EBP: rm = 5; break;
1301 case R_ESI: rm = 6; break;
1302 case R_EDI: rm = 7; break;
1303 case -1: rm = 5; break;
1304 default: /* should never happen */
1305 return NULL;
1306 }
H. Peter Anvinea838272002-04-30 20:51:53 +00001307 if (b==-1 || (b!=R_EBP && o==0 &&
H. Peter Anvin76690a12002-04-30 20:52:49 +00001308 seg==NO_SEG && !forw_ref &&
1309 !(input->eaflags &
1310 (EAF_BYTEOFFS|EAF_WORDOFFS))))
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001311 mod = 0;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001312 else if (input->eaflags & EAF_BYTEOFFS ||
1313 (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1314 !(input->eaflags & EAF_WORDOFFS))) {
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001315 mod = 1;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001316 }
1317 else
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001318 mod = 2;
H. Peter Anvinea838272002-04-30 20:51:53 +00001319
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001320 output->sib_present = FALSE;
1321 output->bytes = (b==-1 || mod==2 ? 4 : mod);
1322 output->modrm = (mod<<6) | (rfield<<3) | rm;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001323 }
1324 else { /* we need a SIB */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001325 int mod, scale, index, base;
1326
1327 switch (b) {
1328 case R_EAX: base = 0; break;
1329 case R_ECX: base = 1; break;
1330 case R_EDX: base = 2; break;
1331 case R_EBX: base = 3; break;
1332 case R_ESP: base = 4; break;
1333 case R_EBP: case -1: base = 5; break;
1334 case R_ESI: base = 6; break;
1335 case R_EDI: base = 7; break;
1336 default: /* then what the smeg is it? */
1337 return NULL; /* panic */
1338 }
1339
1340 switch (i) {
1341 case R_EAX: index = 0; break;
1342 case R_ECX: index = 1; break;
1343 case R_EDX: index = 2; break;
1344 case R_EBX: index = 3; break;
1345 case -1: index = 4; break;
1346 case R_EBP: index = 5; break;
1347 case R_ESI: index = 6; break;
1348 case R_EDI: index = 7; break;
1349 default: /* then what the smeg is it? */
1350 return NULL; /* panic */
1351 }
1352
1353 if (i==-1) s = 1;
1354 switch (s) {
1355 case 1: scale = 0; break;
1356 case 2: scale = 1; break;
1357 case 4: scale = 2; break;
1358 case 8: scale = 3; break;
1359 default: /* then what the smeg is it? */
1360 return NULL; /* panic */
1361 }
1362
H. Peter Anvinea838272002-04-30 20:51:53 +00001363 if (b==-1 || (b!=R_EBP && o==0 &&
H. Peter Anvin76690a12002-04-30 20:52:49 +00001364 seg==NO_SEG && !forw_ref &&
1365 !(input->eaflags &
1366 (EAF_BYTEOFFS|EAF_WORDOFFS))))
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001367 mod = 0;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001368 else if (input->eaflags & EAF_BYTEOFFS ||
1369 (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1370 !(input->eaflags & EAF_WORDOFFS)))
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001371 mod = 1;
1372 else
1373 mod = 2;
1374
1375 output->sib_present = TRUE;
1376 output->bytes = (b==-1 || mod==2 ? 4 : mod);
1377 output->modrm = (mod<<6) | (rfield<<3) | 4;
1378 output->sib = (scale<<6) | (index<<3) | base;
1379 }
H. Peter Anvineba20a72002-04-30 20:53:55 +00001380 }
1381 else { /* it's 16-bit */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001382 int mod, rm;
1383
1384 /* check all registers are BX, BP, SI or DI */
1385 if ((b!=-1 && b!=R_BP && b!=R_BX && b!=R_SI && b!=R_DI) ||
1386 (i!=-1 && i!=R_BP && i!=R_BX && i!=R_SI && i!=R_DI))
1387 return NULL;
1388
1389 /* ensure the user didn't specify DWORD */
1390 if (input->addr_size == 32)
1391 return NULL;
1392
1393 if (s!=1 && i!=-1) return NULL;/* no can do, in 16-bit EA */
H. Peter Anvin87e1fcd2002-05-11 04:01:26 +00001394 if (b==-1 && i!=-1) { int tmp = b; b = i; i = tmp; } /* swap */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001395 if ((b==R_SI || b==R_DI) && i!=-1)
H. Peter Anvin87e1fcd2002-05-11 04:01:26 +00001396 { int tmp = b; b = i; i = tmp; }
1397 /* have BX/BP as base, SI/DI index */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001398 if (b==i) return NULL;/* shouldn't ever happen, in theory */
1399 if (i!=-1 && b!=-1 &&
1400 (i==R_BP || i==R_BX || b==R_SI || b==R_DI))
1401 return NULL; /* invalid combinations */
H. Peter Anvin87e1fcd2002-05-11 04:01:26 +00001402 if (b==-1) /* pure offset: handled above */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001403 return NULL; /* so if it gets to here, panic! */
1404
1405 rm = -1;
1406 if (i!=-1)
1407 switch (i*256 + b) {
1408 case R_SI*256+R_BX: rm=0; break;
1409 case R_DI*256+R_BX: rm=1; break;
1410 case R_SI*256+R_BP: rm=2; break;
1411 case R_DI*256+R_BP: rm=3; break;
1412 }
1413 else
1414 switch (b) {
1415 case R_SI: rm=4; break;
1416 case R_DI: rm=5; break;
1417 case R_BP: rm=6; break;
1418 case R_BX: rm=7; break;
1419 }
1420 if (rm==-1) /* can't happen, in theory */
1421 return NULL; /* so panic if it does */
1422
H. Peter Anvin76690a12002-04-30 20:52:49 +00001423 if (o==0 && seg==NO_SEG && !forw_ref && rm!=6 &&
1424 !(input->eaflags & (EAF_BYTEOFFS|EAF_WORDOFFS)))
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001425 mod = 0;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001426 else if (input->eaflags & EAF_BYTEOFFS ||
1427 (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1428 !(input->eaflags & EAF_WORDOFFS)))
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001429 mod = 1;
1430 else
1431 mod = 2;
1432
1433 output->sib_present = FALSE; /* no SIB - it's 16-bit */
1434 output->bytes = mod; /* bytes of offset needed */
1435 output->modrm = (mod<<6) | (rfield<<3) | rm;
1436 }
1437 }
1438 }
1439 output->size = 1 + output->sib_present + output->bytes;
1440 return output;
1441}
1442
H. Peter Anvineba20a72002-04-30 20:53:55 +00001443static int chsize (operand *input, int addrbits)
1444{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001445 if (!(MEMORY & ~input->type)) {
1446 int i=input->indexreg, b=input->basereg;
1447
1448 if (input->scale==0) i = -1;
1449
1450 if (i == -1 && b == -1) /* pure offset */
1451 return (input->addr_size != 0 && input->addr_size != addrbits);
1452
1453 if (i==R_EAX || i==R_EBX || i==R_ECX || i==R_EDX
1454 || i==R_EBP || i==R_ESP || i==R_ESI || i==R_EDI
1455 || b==R_EAX || b==R_EBX || b==R_ECX || b==R_EDX
1456 || b==R_EBP || b==R_ESP || b==R_ESI || b==R_EDI)
1457 return (addrbits==16);
1458 else
1459 return (addrbits==32);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001460 }
1461 else
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001462 return 0;
1463}