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