|
|
1.1 ! root 1: /* i386.c -- Assemble code for the Intel 80386 ! 2: Copyright (C) 1989, Free Software Foundation. ! 3: ! 4: This file is part of GAS, the GNU Assembler. ! 5: ! 6: GAS is free software; you can redistribute it and/or modify ! 7: it under the terms of the GNU General Public License as published by ! 8: the Free Software Foundation; either version 1, or (at your option) ! 9: any later version. ! 10: ! 11: GAS is distributed in the hope that it will be useful, ! 12: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: GNU General Public License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GAS; see the file COPYING. If not, write to ! 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 19: ! 20: /* ! 21: Intel 80386 machine specific gas. ! 22: Written by Eliot Dresselhaus ([email protected]). ! 23: Bugs & suggestions are completely welcome. This is free software. ! 24: Please help us make it better. ! 25: */ ! 26: ! 27: #include <stdio.h> ! 28: #include <stdlib.h> ! 29: #include <string.h> ! 30: #include <ctype.h> ! 31: ! 32: #include "as.h" ! 33: #include "struc-symbol.h" ! 34: #include "flonum.h" ! 35: #include "expr.h" ! 36: #include "read.h" ! 37: #include "obstack.h" ! 38: #include "frags.h" ! 39: #include "symbols.h" ! 40: #include "fixes.h" ! 41: #include "md.h" ! 42: #include "xmalloc.h" ! 43: #include "messages.h" ! 44: #include "i386.h" ! 45: #include "i386-opcode.h" ! 46: #include "sections.h" ! 47: #include "input-scrub.h" ! 48: ! 49: /* ! 50: * These are the default cputype and cpusubtype for the i386 architecture. ! 51: */ ! 52: const cpu_type_t md_cputype = CPU_TYPE_I386; ! 53: cpu_subtype_t md_cpusubtype = CPU_SUBTYPE_I386_ALL; ! 54: ! 55: /* This is the byte sex for the i386 architecture */ ! 56: const enum byte_sex md_target_byte_sex = LITTLE_ENDIAN_BYTE_SEX; ! 57: ! 58: const char md_FLT_CHARS[] = "fFdDxX"; ! 59: const char md_EXP_CHARS[] = "eE"; ! 60: const char md_line_comment_chars[] = "#"; ! 61: const char md_comment_chars[] = "#"; ! 62: ! 63: /* tables for lexical analysis */ ! 64: static char opcode_chars[256]; ! 65: static char register_chars[256]; ! 66: static char operand_chars[256]; ! 67: static char space_chars[256]; ! 68: static char identifier_chars[256]; ! 69: static char digit_chars[256]; ! 70: ! 71: /* lexical macros */ ! 72: #define is_opcode_char(x) (opcode_chars[(unsigned char) x]) ! 73: #define is_operand_char(x) (operand_chars[(unsigned char) x]) ! 74: #define is_register_char(x) (register_chars[(unsigned char) x]) ! 75: #define is_space_char(x) (space_chars[(unsigned char) x]) ! 76: #define is_identifier_char(x) (identifier_chars[(unsigned char) x]) ! 77: #define is_digit_char(x) (digit_chars[(unsigned char) x]) ! 78: ! 79: /* put here all non-digit non-letter charcters that may occur in an operand */ ! 80: #ifdef NeXT ! 81: static char operand_special_chars[] = "%$-+(,)*._~/<>|&^!:\""; ! 82: #else ! 83: static char operand_special_chars[] = "%$-+(,)*._~/<>|&^!:"; ! 84: #endif ! 85: ! 86: static char *ordinal_names[] = { "first", "second", "third" }; /* for printfs */ ! 87: ! 88: /* md_assemble() always leaves the strings it's passed unaltered. To ! 89: effect this we maintain a stack of saved characters that we've smashed ! 90: with '\0's (indicating end of strings for various sub-fields of the ! 91: assembler instruction). */ ! 92: static char save_stack[32]; ! 93: static char *save_stack_p; /* stack pointer */ ! 94: #define END_STRING_AND_SAVE(s) *save_stack_p++ = *s; *s = '\0' ! 95: #define RESTORE_END_STRING(s) *s = *--save_stack_p ! 96: ! 97: /* The instruction we're assembling. */ ! 98: static i386_insn i; ! 99: ! 100: /* Per instruction expressionS buffers: 2 displacements & 2 immediate max. */ ! 101: static expressionS disp_expressions[2], im_expressions[2]; ! 102: ! 103: /* pointers to ebp & esp entries in reg_hash hash table */ ! 104: static reg_entry *ebp, *esp; ! 105: ! 106: static int this_operand; /* current operand we are working on */ ! 107: ! 108: /* ! 109: Interface to relax_segment. ! 110: There are 2 relax states for 386 jump insns: one for conditional & one ! 111: for unconditional jumps. This is because the these two types of jumps ! 112: add different sizes to frags when we're figuring out what sort of jump ! 113: to choose to reach a given label. */ ! 114: ! 115: /* types */ ! 116: #define COND_JUMP 1 /* conditional jump */ ! 117: #define UNCOND_JUMP 2 /* unconditional jump */ ! 118: /* sizes */ ! 119: #define BYTE 0 ! 120: #define WORD 1 ! 121: #define DWORD 2 ! 122: #define UNKNOWN_SIZE 3 ! 123: ! 124: #define ENCODE_RELAX_STATE(type,size) ((type<<2) | (size)) ! 125: #define SIZE_FROM_RELAX_STATE(s) \ ! 126: ( (((s) & 0x3) == BYTE ? 1 : (((s) & 0x3) == WORD ? 2 : 4)) ) ! 127: ! 128: const relax_typeS md_relax_table[] = { ! 129: /* ! 130: The fields are: ! 131: 1) most positive reach of this state, ! 132: 2) most negative reach of this state, ! 133: 3) how many bytes this mode will add to the size of the current frag ! 134: 4) which index into the table to try if we can't fit into this one. ! 135: */ ! 136: {1, 1, 0, 0}, ! 137: {1, 1, 0, 0}, ! 138: {1, 1, 0, 0}, ! 139: {1, 1, 0, 0}, ! 140: ! 141: /* For now we don't use word displacement jumps: they may be ! 142: untrustworthy. */ ! 143: {127+1, -128+1, 0, ENCODE_RELAX_STATE(COND_JUMP,DWORD) }, ! 144: /* word conditionals add 3 bytes to frag: ! 145: 2 opcode prefix; 1 displacement bytes */ ! 146: {32767+2, -32768+2, 3, ENCODE_RELAX_STATE(COND_JUMP,DWORD) }, ! 147: /* dword conditionals adds 4 bytes to frag: ! 148: 1 opcode prefix; 3 displacement bytes */ ! 149: {0, 0, 4, 0}, ! 150: {1, 1, 0, 0}, ! 151: ! 152: {127+1, -128+1, 0, ENCODE_RELAX_STATE(UNCOND_JUMP,DWORD) }, ! 153: /* word jmp adds 2 bytes to frag: ! 154: 1 opcode prefix; 1 displacement bytes */ ! 155: {32767+2, -32768+2, 2, ENCODE_RELAX_STATE(UNCOND_JUMP,DWORD) }, ! 156: /* dword jmp adds 3 bytes to frag: ! 157: 0 opcode prefix; 3 displacement bytes */ ! 158: {0, 0, 3, 0}, ! 159: {1, 1, 0, 0}, ! 160: ! 161: }; ! 162: ! 163: /* Ignore certain directives generated by gcc. This probably should ! 164: not be here. */ ! 165: static ! 166: void ! 167: dummy( ! 168: int value) ! 169: { ! 170: while (*input_line_pointer && *input_line_pointer != '\n') ! 171: input_line_pointer++; ! 172: } ! 173: ! 174: const pseudo_typeS md_pseudo_table[] = { ! 175: { "ffloat", float_cons, 'f' }, ! 176: { "dfloat", float_cons, 'd' }, ! 177: { "tfloat", float_cons, 'x' }, ! 178: { "value", cons, 2 }, ! 179: { "word", cons, 2 }, ! 180: { "ident", dummy, 0 }, /* ignore these directives */ ! 181: { "def", dummy, 0 }, ! 182: { "optim", dummy, 0 }, /* For sun386i cc */ ! 183: { "version", dummy, 0 }, ! 184: { "ln", dummy, 0 }, ! 185: { 0, 0, 0 } ! 186: }; ! 187: ! 188: static int i386_operand( ! 189: char *operand_string); ! 190: static char *output_invalid( ! 191: char c); ! 192: static reg_entry *parse_register( ! 193: char *reg_string); ! 194: #ifdef NeXT ! 195: static int is_local_symbol( ! 196: struct symbol *sym); ! 197: static int add_seg_prefix( ! 198: int seg_prefix); ! 199: #endif /* NeXT */ ! 200: ! 201: /* obstack for constructing various things in md_begin */ ! 202: static struct obstack o; ! 203: ! 204: /* hash table for opcode lookup */ ! 205: static struct hash_control *op_hash = (struct hash_control *) 0; ! 206: /* hash table for register lookup */ ! 207: static struct hash_control *reg_hash = (struct hash_control *) 0; ! 208: /* hash table for prefix lookup */ ! 209: static struct hash_control *prefix_hash = (struct hash_control *) 0; ! 210: ! 211: void ! 212: md_begin( ! 213: void) ! 214: { ! 215: char * hash_err; ! 216: ! 217: obstack_begin (&o,4096); ! 218: ! 219: /* initialize op_hash hash table */ ! 220: op_hash = hash_new(); /* xmalloc handles error */ ! 221: ! 222: { ! 223: register const template *optab; ! 224: register templates *core_optab; ! 225: char *prev_name; ! 226: ! 227: optab = i386_optab; /* setup for loop */ ! 228: prev_name = optab->name; ! 229: obstack_grow (&o, optab, sizeof(template)); ! 230: core_optab = (templates *) xmalloc (sizeof (templates)); ! 231: ! 232: for (optab++; optab < i386_optab_end; optab++) { ! 233: if (! strcmp (optab->name, prev_name)) { ! 234: /* same name as before --> append to current template list */ ! 235: obstack_grow (&o, optab, sizeof(template)); ! 236: } else { ! 237: /* different name --> ship out current template list; ! 238: add to hash table; & begin anew */ ! 239: /* Note: end must be set before start! since obstack_next_free changes ! 240: upon opstack_finish */ ! 241: core_optab->end = (template *) obstack_next_free(&o); ! 242: core_optab->start = (template *) obstack_finish(&o); ! 243: hash_err = hash_insert (op_hash, prev_name, (char *) core_optab); ! 244: if (hash_err && *hash_err) { ! 245: hash_error: ! 246: as_fatal("Internal Error: Can't hash %s: %s",prev_name, hash_err); ! 247: } ! 248: prev_name = optab->name; ! 249: core_optab = (templates *) xmalloc (sizeof(templates)); ! 250: obstack_grow (&o, optab, sizeof(template)); ! 251: } ! 252: } ! 253: } ! 254: ! 255: /* initialize reg_hash hash table */ ! 256: reg_hash = hash_new(); ! 257: { ! 258: register const reg_entry *regtab; ! 259: ! 260: for (regtab = i386_regtab; regtab < i386_regtab_end; regtab++) { ! 261: hash_err = hash_insert (reg_hash, regtab->reg_name, (char *)regtab); ! 262: if (hash_err && *hash_err) goto hash_error; ! 263: } ! 264: } ! 265: ! 266: esp = (reg_entry *) hash_find (reg_hash, "esp"); ! 267: ebp = (reg_entry *) hash_find (reg_hash, "ebp"); ! 268: ! 269: /* initialize reg_hash hash table */ ! 270: prefix_hash = hash_new(); ! 271: { ! 272: register const prefix_entry *prefixtab; ! 273: ! 274: for (prefixtab = i386_prefixtab; ! 275: prefixtab < i386_prefixtab_end; prefixtab++) { ! 276: hash_err = hash_insert (prefix_hash, prefixtab->prefix_name, (char *)prefixtab); ! 277: if (hash_err && *hash_err) goto hash_error; ! 278: } ! 279: } ! 280: ! 281: /* fill in lexical tables: opcode_chars, operand_chars, space_chars */ ! 282: { ! 283: register unsigned int c; ! 284: ! 285: memset(opcode_chars, '\0', sizeof(opcode_chars)); ! 286: memset(operand_chars, '\0', sizeof(operand_chars)); ! 287: memset(space_chars, '\0', sizeof(space_chars)); ! 288: memset(identifier_chars, '\0', sizeof(identifier_chars)); ! 289: memset(digit_chars, '\0', sizeof(digit_chars)); ! 290: ! 291: for (c = 0; c < 256; c++) { ! 292: if (islower(c) || isdigit(c)) { ! 293: opcode_chars[c] = c; ! 294: register_chars[c] = c; ! 295: } else if (isupper(c)) { ! 296: opcode_chars[c] = tolower(c); ! 297: register_chars[c] = opcode_chars[c]; ! 298: } else if (c == PREFIX_SEPERATOR) { ! 299: opcode_chars[c] = c; ! 300: } else if (c == ')' || c == '(') { ! 301: register_chars[c] = c; ! 302: } ! 303: ! 304: if (isupper(c) || islower(c) || isdigit(c)) ! 305: operand_chars[c] = c; ! 306: else if (c && strchr(operand_special_chars, c)) ! 307: operand_chars[c] = c; ! 308: ! 309: if (isdigit(c) || c == '-') digit_chars[c] = c; ! 310: ! 311: if (isalpha(c) || c == '_' || c == '.' || isdigit(c)) ! 312: identifier_chars[c] = c; ! 313: ! 314: if (c == ' ' || c == '\t') space_chars[c] = c; ! 315: } ! 316: } ! 317: } ! 318: ! 319: void ! 320: md_end( ! 321: void) ! 322: {} /* not much to do here. */ ! 323: ! 324: #ifdef DEBUG386 ! 325: ! 326: /* debugging routines for md_assemble */ ! 327: static void pi( ! 328: char *line, ! 329: i386_insn *x); ! 330: static void pte( ! 331: template *t); ! 332: static void pe( ! 333: expressionS *e); ! 334: static void ps( ! 335: symbolS *s); ! 336: static void pt( ! 337: uint t); ! 338: ! 339: static ! 340: void ! 341: pi( ! 342: char *line, ! 343: i386_insn *x) ! 344: { ! 345: register template *p; ! 346: int i; ! 347: ! 348: fprintf (stdout, "%s: template ", line); ! 349: pte (&x->tm); ! 350: fprintf (stdout, " modrm: mode %x reg %x reg/mem %x", ! 351: x->rm.mode, x->rm.reg, x->rm.regmem); ! 352: fprintf (stdout, " base %x index %x scale %x\n", ! 353: x->bi.base, x->bi.index, x->bi.scale); ! 354: for (i = 0; i < x->operands; i++) { ! 355: fprintf (stdout, " #%d: ", i+1); ! 356: pt (x->types[i]); ! 357: fprintf (stdout, "\n"); ! 358: if (x->types[i] & Reg) fprintf (stdout, "%s\n", x->regs[i]->reg_name); ! 359: if (x->types[i] & Imm) pe (x->imms[i]); ! 360: if (x->types[i] & (Disp|Abs)) pe (x->disps[i]); ! 361: } ! 362: } ! 363: ! 364: static ! 365: void ! 366: pte( ! 367: template *t) ! 368: { ! 369: int i; ! 370: fprintf (stdout, " %d operands ", t->operands); ! 371: fprintf (stdout, "opcode %x ", ! 372: t->base_opcode); ! 373: if (t->extension_opcode != None) ! 374: fprintf (stdout, "ext %x ", t->extension_opcode); ! 375: if (t->opcode_modifier&D) ! 376: fprintf (stdout, "D"); ! 377: if (t->opcode_modifier&W) ! 378: fprintf (stdout, "W"); ! 379: fprintf (stdout, "\n"); ! 380: for (i = 0; i < t->operands; i++) { ! 381: fprintf (stdout, " #%d type ", i+1); ! 382: pt (t->operand_types[i]); ! 383: fprintf (stdout, "\n"); ! 384: } ! 385: } ! 386: ! 387: static char *seg_names[] = { ! 388: "SEG_ABSOLUTE", "SEG_TEXT", "SEG_DATA", "SEG_BSS", "SEG_UNKNOWN", ! 389: "SEG_NONE", "SEG_PASS1", "SEG_GOOF", "SEG_BIG", "SEG_DIFFERENCE" }; ! 390: ! 391: static ! 392: void ! 393: pe( ! 394: expressionS *e) ! 395: { ! 396: fprintf (stdout, " segment %s\n", seg_names[(int) e->X_seg]); ! 397: fprintf (stdout, " add_number %d (%x)\n", ! 398: e->X_add_number, e->X_add_number); ! 399: if (e->X_add_symbol) { ! 400: fprintf (stdout, " add_symbol "); ! 401: ps (e->X_add_symbol); ! 402: fprintf (stdout, "\n"); ! 403: } ! 404: if (e->X_subtract_symbol) { ! 405: fprintf (stdout, " sub_symbol "); ! 406: ps (e->X_subtract_symbol); ! 407: fprintf (stdout, "\n"); ! 408: } ! 409: } ! 410: ! 411: #define SYMBOL_TYPE(t) \ ! 412: (((t&N_TYPE) == N_UNDF) ? "UNDEFINED" : \ ! 413: (((t&N_TYPE) == N_ABS) ? "ABSOLUTE" : \ ! 414: (((t&N_TYPE) == N_TEXT) ? "TEXT" : \ ! 415: (((t&N_TYPE) == N_DATA) ? "DATA" : \ ! 416: (((t&N_TYPE) == N_BSS) ? "BSS" : "Bad n_type!"))))) ! 417: ! 418: static ! 419: void ! 420: ps( ! 421: symbolS *s) ! 422: { ! 423: fprintf (stdout, "%s type %s%s", ! 424: s->sy_nlist.n_un.n_name, ! 425: (s->sy_nlist.n_type&N_EXT) ? "EXTERNAL " : "", ! 426: SYMBOL_TYPE (s->sy_nlist.n_type)); ! 427: } ! 428: ! 429: static struct type_name { ! 430: uint mask; ! 431: char *tname; ! 432: } type_names[] = { ! 433: { Reg8, "r8" }, { Reg16, "r16" }, { Reg32, "r32" }, { Imm8, "i8" }, ! 434: { Imm8S, "i8s" }, ! 435: { Imm16, "i16" }, { Imm32, "i32" }, { Mem8, "Mem8"}, { Mem16, "Mem16"}, ! 436: { Mem32, "Mem32"}, { BaseIndex, "BaseIndex" }, ! 437: { Abs8, "Abs8" }, { Abs16, "Abs16" }, { Abs32, "Abs32" }, ! 438: { Disp8, "d8" }, { Disp16, "d16" }, ! 439: { Disp32, "d32" }, { SReg2, "SReg2" }, { SReg3, "SReg3" }, { Acc, "Acc" }, ! 440: { InOutPortReg, "InOutPortReg" }, { ShiftCount, "ShiftCount" }, ! 441: { Imm1, "i1" }, { Control, "control reg" }, {Test, "test reg"}, ! 442: { FloatReg, "FReg"}, {FloatAcc, "FAcc"}, ! 443: { JumpAbsolute, "Jump Absolute"}, ! 444: { 0, "" } ! 445: }; ! 446: ! 447: static ! 448: void ! 449: pt( ! 450: uint t) ! 451: { ! 452: register struct type_name *ty; ! 453: ! 454: if (t == Unknown) { ! 455: fprintf (stdout, "Unknown"); ! 456: } else { ! 457: for (ty = type_names; ty->mask; ty++) ! 458: if (t & ty->mask) fprintf (stdout, "%s, ", ty->tname); ! 459: } ! 460: fflush (stdout); ! 461: } ! 462: #endif /* DEBUG386 */ ! 463: ! 464: /* ! 465: This is the guts of the machine-dependent assembler. LINE points to a ! 466: machine dependent instruction. This funciton is supposed to emit ! 467: the frags/bytes it assembles to. ! 468: */ ! 469: void ! 470: md_assemble( ! 471: char *line) ! 472: { ! 473: /* Holds temlate once we've found it. */ ! 474: register template * t; ! 475: ! 476: /* Possible templates for current insn */ ! 477: templates *current_templates = (templates *) 0; ! 478: ! 479: /* Initialize globals. */ ! 480: memset(&i, '\0', sizeof(i)); ! 481: memset(disp_expressions, '\0', sizeof(disp_expressions)); ! 482: memset(im_expressions, '\0', sizeof(im_expressions)); ! 483: save_stack_p = save_stack; /* reset stack pointer */ ! 484: ! 485: /* Fist parse an opcode & call i386_operand for the operands. ! 486: We assume that the scrubber has arranged it so that line[0] is the valid ! 487: start of a (possibly prefixed) opcode. */ ! 488: { ! 489: register char *l = line; /* Fast place to put LINE. */ ! 490: ! 491: /* TRUE if operand is pending after ','. */ ! 492: uint expecting_operand = 0; ! 493: /* TRUE if we found a prefix only acceptable with string insns. */ ! 494: uint expecting_string_instruction = 0; ! 495: /* Non-zero if operand parens not balenced. */ ! 496: uint paren_not_balenced; ! 497: char * token_start = l; ! 498: ! 499: while (! is_space_char(*l) && *l != END_OF_INSN) { ! 500: if (! is_opcode_char(*l)) { ! 501: as_bad ("invalid character %s in opcode", output_invalid(*l)); ! 502: return; ! 503: } else if (*l != PREFIX_SEPERATOR) { ! 504: *l = opcode_chars[(unsigned char) *l]; /* fold case of opcodes */ ! 505: l++; ! 506: } else { /* this opcode's got a prefix */ ! 507: register int q; ! 508: register prefix_entry * prefix; ! 509: ! 510: if (l == token_start) { ! 511: as_bad ("expecting prefix; got nothing"); ! 512: return; ! 513: } ! 514: END_STRING_AND_SAVE (l); ! 515: prefix = (prefix_entry *) hash_find (prefix_hash, token_start); ! 516: if (! prefix) { ! 517: as_bad ("no such opcode prefix ('%s')", token_start); ! 518: return; ! 519: } ! 520: RESTORE_END_STRING (l); ! 521: /* check for repeated prefix */ ! 522: for (q = 0; q < i.prefixes; q++) ! 523: if (i.prefix[q] == (char)prefix->prefix_code) { ! 524: as_bad ("same prefix used twice; you don't really want this!"); ! 525: return; ! 526: } ! 527: if (i.prefixes == MAX_PREFIXES) { ! 528: as_bad ("too many opcode prefixes"); ! 529: return; ! 530: } ! 531: i.prefix[i.prefixes++] = prefix->prefix_code; ! 532: if (prefix->prefix_code == REPE || prefix->prefix_code == REPNE) ! 533: expecting_string_instruction = TRUE; ! 534: /* skip past PREFIX_SEPERATOR and reset token_start */ ! 535: token_start = ++l; ! 536: } ! 537: } ! 538: END_STRING_AND_SAVE (l); ! 539: if (token_start == l) { ! 540: as_bad ("expecting opcode; got nothing"); ! 541: return; ! 542: } ! 543: ! 544: /* Lookup insn in hash; try intel & att naming conventions if appropriate; ! 545: that is: we only use the opcode suffix 'b' 'w' or 'l' if we need to. */ ! 546: current_templates = (templates *) hash_find (op_hash, token_start); ! 547: if (! current_templates) { ! 548: int last_index = strlen(token_start) - 1; ! 549: char last_char = token_start[last_index]; ! 550: switch (last_char) { ! 551: case DWORD_OPCODE_SUFFIX: ! 552: case WORD_OPCODE_SUFFIX: ! 553: case BYTE_OPCODE_SUFFIX: ! 554: token_start[last_index] = '\0'; ! 555: current_templates = (templates *) hash_find (op_hash, token_start); ! 556: token_start[last_index] = last_char; ! 557: i.suffix = last_char; ! 558: } ! 559: if (!current_templates) { ! 560: as_bad ("no such 386 instruction: `%s'", token_start); return; ! 561: } ! 562: } ! 563: RESTORE_END_STRING (l); ! 564: ! 565: /* check for rep/repne without a string instruction */ ! 566: if (expecting_string_instruction && ! 567: ! IS_STRING_INSTRUCTION (current_templates-> ! 568: start->base_opcode)) { ! 569: as_bad ("expecting string instruction after rep/repne"); ! 570: return; ! 571: } ! 572: ! 573: /* There may be operands to parse. */ ! 574: #ifdef NeXT ! 575: /* The kludge in the comment below has the bug where a segment override ! 576: is not picked up if it is part of the operand. For example: ! 577: movsl %fs:0(%esi),0(%edi) ! 578: does not pick up the segment override %fs. Also of course by ignoring ! 579: all characters of the operands will confuse users when errors are not ! 580: checked at all. This is a hairy fix as the struct i386_insn was changed ! 581: in i386.h and i386_operand() was changed and some very special case ! 582: checking for each of the string instructions was added. (bug #26409) */ ! 583: if (*l != END_OF_INSN) ! 584: #else /* !defined(NeXT) */ ! 585: if (*l != END_OF_INSN && ! 586: /* For string instructions, we ignore any operands if given. This ! 587: kludges, for example, 'rep/movsb %ds:(%esi), %es:(%edi)' where ! 588: the operands are always going to be the same, and are not really ! 589: encoded in machine code. */ ! 590: ! IS_STRING_INSTRUCTION (current_templates-> ! 591: start->base_opcode)) ! 592: #endif /* NeXT */ ! 593: { ! 594: /* parse operands */ ! 595: do { ! 596: /* skip optional white space before operand */ ! 597: while (! is_operand_char(*l) && *l != END_OF_INSN) { ! 598: if (! is_space_char(*l)) { ! 599: as_bad ("invalid character %s before %s operand", ! 600: output_invalid(*l), ! 601: ordinal_names[i.operands]); ! 602: return; ! 603: } ! 604: l++; ! 605: } ! 606: token_start = l; /* after white space */ ! 607: paren_not_balenced = 0; ! 608: while (paren_not_balenced || *l != ',') { ! 609: if (*l == END_OF_INSN) { ! 610: if (paren_not_balenced) { ! 611: as_bad ("unbalenced parenthesis in %s operand.", ! 612: ordinal_names[i.operands]); ! 613: return; ! 614: } else break; /* we are done */ ! 615: #ifdef NeXT ! 616: } else if (*l == '"') { ! 617: char *p = l; ! 618: l++; ! 619: while (*l != '"' && *l != END_OF_INSN) { ! 620: l++; ! 621: } ! 622: if (*l != '"') ! 623: as_bad ("invalid operand %s (missing ending \")", p); ! 624: #endif /* NeXT */ ! 625: } else if (! is_operand_char(*l)) { ! 626: as_bad ("invalid character %s in %s operand", ! 627: output_invalid(*l), ! 628: ordinal_names[i.operands]); ! 629: return; ! 630: } ! 631: if (*l == '(') ++paren_not_balenced; ! 632: if (*l == ')') --paren_not_balenced; ! 633: l++; ! 634: } ! 635: if (l != token_start) { /* yes, we've read in another operand */ ! 636: uint operand_ok; ! 637: this_operand = i.operands++; ! 638: if (i.operands > MAX_OPERANDS) { ! 639: as_bad ("spurious operands; (%d operands/instruction max)", ! 640: MAX_OPERANDS); ! 641: return; ! 642: } ! 643: /* now parse operand adding info to 'i' as we go along */ ! 644: END_STRING_AND_SAVE (l); ! 645: operand_ok = i386_operand (token_start); ! 646: RESTORE_END_STRING (l); /* restore old contents */ ! 647: if (!operand_ok) return; ! 648: } else { ! 649: if (expecting_operand) { ! 650: expecting_operand_after_comma: ! 651: as_bad ("expecting operand after ','; got nothing"); ! 652: return; ! 653: } ! 654: if (*l == ',') { ! 655: as_bad ("expecting operand before ','; got nothing"); ! 656: return; ! 657: } ! 658: } ! 659: ! 660: /* now *l must be either ',' or END_OF_INSN */ ! 661: if (*l == ',') { ! 662: if (*++l == END_OF_INSN) { /* just skip it, if it's \n complain */ ! 663: goto expecting_operand_after_comma; ! 664: } ! 665: expecting_operand = TRUE; ! 666: } ! 667: } while (*l != END_OF_INSN); /* until we get end of insn */ ! 668: } ! 669: } ! 670: ! 671: /* Now we've parsed the opcode into a set of templates, and have the ! 672: operands at hand. ! 673: Next, we find a template that matches the given insn, ! 674: making sure the overlap of the given operands types is consistent ! 675: with the template operand types. */ ! 676: ! 677: #define MATCH(overlap,given_type) \ ! 678: (overlap && \ ! 679: (overlap & (JumpAbsolute|BaseIndex|Mem8)) \ ! 680: == (given_type & (JumpAbsolute|BaseIndex|Mem8))) ! 681: ! 682: /* If m0 and m1 are register matches they must be consistent ! 683: with the expected operand types t0 and t1. ! 684: That is, if both m0 & m1 are register matches ! 685: i.e. ( ((m0 & (Reg)) && (m1 & (Reg)) ) ? ! 686: then, either 1. or 2. must be true: ! 687: 1. the expected operand type register overlap is null: ! 688: (t0 & t1 & Reg) == 0 ! 689: AND ! 690: the given register overlap is null: ! 691: (m0 & m1 & Reg) == 0 ! 692: 2. the expected operand type register overlap == the given ! 693: operand type overlap: (t0 & t1 & m0 & m1 & Reg). ! 694: */ ! 695: #define CONSISTENT_REGISTER_MATCH(m0, m1, t0, t1) \ ! 696: ( ((m0 & (Reg)) && (m1 & (Reg))) ? \ ! 697: ( ((t0 & t1 & (Reg)) == 0 && (m0 & m1 & (Reg)) == 0) || \ ! 698: ((t0 & t1) & (m0 & m1) & (Reg)) \ ! 699: ) : 1) ! 700: { ! 701: register uint overlap0, overlap1; ! 702: expressionS * exp; ! 703: uint overlap2; ! 704: uint found_reverse_match; ! 705: ! 706: overlap0 = overlap1 = overlap2 = found_reverse_match = 0; ! 707: for (t = current_templates->start; ! 708: t < current_templates->end; ! 709: t++) { ! 710: ! 711: /* must have right number of operands */ ! 712: if (i.operands != t->operands) continue; ! 713: else if (!t->operands) break; /* 0 operands always matches */ ! 714: ! 715: overlap0 = i.types[0] & t->operand_types[0]; ! 716: switch (t->operands) { ! 717: case 1: ! 718: if (! MATCH (overlap0,i.types[0])) continue; ! 719: break; ! 720: case 2: case 3: ! 721: overlap1 = i.types[1] & t->operand_types[1]; ! 722: if (! MATCH (overlap0,i.types[0]) || ! 723: ! MATCH (overlap1,i.types[1]) || ! 724: ! CONSISTENT_REGISTER_MATCH(overlap0, overlap1, ! 725: t->operand_types[0], ! 726: t->operand_types[1])) { ! 727: ! 728: /* check if other direction is valid ... */ ! 729: if (! (t->opcode_modifier & COMES_IN_BOTH_DIRECTIONS)) ! 730: continue; ! 731: ! 732: /* try reversing direction of operands */ ! 733: overlap0 = i.types[0] & t->operand_types[1]; ! 734: overlap1 = i.types[1] & t->operand_types[0]; ! 735: if (! MATCH (overlap0,i.types[0]) || ! 736: ! MATCH (overlap1,i.types[1]) || ! 737: ! CONSISTENT_REGISTER_MATCH (overlap0, overlap1, ! 738: t->operand_types[0], ! 739: t->operand_types[1])) { ! 740: /* does not match either direction */ ! 741: continue; ! 742: } ! 743: /* found a reverse match here -- slip through */ ! 744: /* found_reverse_match holds which of D or FloatD we've found */ ! 745: found_reverse_match = t->opcode_modifier & COMES_IN_BOTH_DIRECTIONS; ! 746: } /* endif: not forward match */ ! 747: /* found either forward/reverse 2 operand match here */ ! 748: if (t->operands == 3) { ! 749: overlap2 = i.types[2] & t->operand_types[2]; ! 750: if (! MATCH (overlap2,i.types[2]) || ! 751: ! CONSISTENT_REGISTER_MATCH (overlap0, overlap2, ! 752: t->operand_types[0], ! 753: t->operand_types[2]) || ! 754: ! CONSISTENT_REGISTER_MATCH (overlap1, overlap2, ! 755: t->operand_types[1], ! 756: t->operand_types[2])) ! 757: continue; ! 758: } ! 759: /* found either forward/reverse 2 or 3 operand match here: ! 760: slip through to break */ ! 761: } ! 762: break; /* we've found a match; break out of loop */ ! 763: } /* for (t = ... */ ! 764: if (t == current_templates->end) { /* we found no match */ ! 765: #ifdef NeXT ! 766: string_instruction_bad_match: ! 767: #endif /* NeXT */ ! 768: as_bad ("operands given don't match any known 386 instruction"); ! 769: return; ! 770: } ! 771: ! 772: #ifdef NeXT ! 773: /* ! 774: * This bit of special checking code checks the string instructions that ! 775: * have operands so that segment overrides get picked up correctly. ! 776: */ ! 777: if(IS_STRING_INSTRUCTION((t->base_opcode)) && i.operands != 0){ ! 778: ! 779: if(i.operands == 2){ ! 780: if(t->base_opcode == MOVS_OPCODE || /* movs %seg:0(%esi),%es:0(%edi) */ ! 781: t->base_opcode == CMPS_OPCODE){ /* cmps %seg:0(%esi),%es:0(%edi) */ ! 782: ! 783: if(i.base_reg != (reg_entry *)hash_find(reg_hash, "esi") || ! 784: i.base_reg2nd != (reg_entry *)hash_find(reg_hash, "edi")) ! 785: goto string_instruction_bad_match; ! 786: ! 787: if(i.seg2nd && i.seg2nd != &es) ! 788: goto string_instruction_bad_match; ! 789: ! 790: if(i.seg) ! 791: if(add_seg_prefix(i.seg->seg_prefix)) ! 792: return; ! 793: } ! 794: else if(t->base_opcode == LODS_OPCODE){ /* lods %seg:(%esi),%eax */ ! 795: ! 796: if(i.base_reg != (reg_entry *)hash_find(reg_hash, "esi")) ! 797: goto string_instruction_bad_match; ! 798: ! 799: if(i.seg) ! 800: if(add_seg_prefix(i.seg->seg_prefix)) ! 801: return; ! 802: } ! 803: else if(t->base_opcode == SCAS_OPCODE || /* scas %eax,%seg:(%edi) */ ! 804: t->base_opcode == STOS_OPCODE){ /* stos %eax,%seg:(%edi) */ ! 805: ! 806: if(i.base_reg != (reg_entry *)hash_find(reg_hash, "edi")) ! 807: goto string_instruction_bad_match; ! 808: ! 809: if(i.seg) ! 810: if(add_seg_prefix(i.seg->seg_prefix)) ! 811: return; ! 812: } ! 813: ! 814: if(i.index_reg || i.index_reg2nd) ! 815: goto string_instruction_bad_match; ! 816: ! 817: if(i.disps[0]){ ! 818: if(i.disps[0]->X_add_symbol || i.disps[0]->X_subtract_symbol || ! 819: i.disps[0]->X_seg != SEG_ABSOLUTE || i.disps[0]->X_add_number != 0) ! 820: goto string_instruction_bad_match; ! 821: } ! 822: ! 823: if(i.disps[1]){ ! 824: if(i.disps[1]->X_add_symbol || i.disps[1]->X_subtract_symbol || ! 825: i.disps[1]->X_seg != SEG_ABSOLUTE || i.disps[1]->X_add_number != 0) ! 826: goto string_instruction_bad_match; ! 827: } ! 828: } ! 829: /* ! 830: * Now that the operands have been checked for correctness remove them ! 831: * so the correct opcode bytes are put out. ! 832: */ ! 833: i.seg = 0; ! 834: i.base_reg = 0; ! 835: i.base_reg2nd = 0; ! 836: i.disp_operands = 0; ! 837: i.disps[0] = 0; ! 838: i.disps[1] = 0; ! 839: } ! 840: #endif /* NeXT */ ! 841: ! 842: #ifdef NeXT ! 843: if(t->cpus && !force_cpusubtype_ALL){ ! 844: if(*(t->cpus) == '5'){ ! 845: if(archflag_cpusubtype == CPU_SUBTYPE_486 || ! 846: archflag_cpusubtype == CPU_SUBTYPE_486SX) ! 847: as_bad("586 instruction not allowed with -arch i486 or -arch i486SX"); ! 848: if(md_cpusubtype != CPU_SUBTYPE_586SX) ! 849: md_cpusubtype = CPU_SUBTYPE_586; ! 850: } ! 851: else if(*(t->cpus) == '4' && ! 852: (md_cpusubtype != CPU_SUBTYPE_586 && ! 853: md_cpusubtype != CPU_SUBTYPE_586SX)) ! 854: if(md_cpusubtype != CPU_SUBTYPE_486SX) ! 855: md_cpusubtype = CPU_SUBTYPE_486; ! 856: } ! 857: #endif /* NeXT */ ! 858: ! 859: /* Copy the template we found (we may change it!). */ ! 860: memcpy(&i.tm, t, sizeof (template)); ! 861: t = &i.tm; /* alter new copy of template */ ! 862: ! 863: /* If there's no opcode suffix we try to invent one based on register ! 864: operands. */ ! 865: if (! i.suffix && i.reg_operands) { ! 866: /* We take i.suffix from the LAST register operand specified. This ! 867: assumes that the last register operands is the destination register ! 868: operand. */ ! 869: int o; ! 870: for (o = 0; o < MAX_OPERANDS; o++) ! 871: if (i.types[o] & Reg) { ! 872: #ifdef NeXT ! 873: /* Need to and with `Reg' because %al and %ax have `Acc' in their ! 874: types and they were coming up with a 'l' suffix. */ ! 875: i.suffix = ((i.types[o] & Reg) == Reg8) ? BYTE_OPCODE_SUFFIX : ! 876: ((i.types[o] & Reg) == Reg16) ? WORD_OPCODE_SUFFIX : ! 877: DWORD_OPCODE_SUFFIX; ! 878: #else /* !defined(NeXT) */ ! 879: i.suffix = (i.types[o] == Reg8) ? BYTE_OPCODE_SUFFIX : ! 880: (i.types[o] == Reg16) ? WORD_OPCODE_SUFFIX : ! 881: DWORD_OPCODE_SUFFIX; ! 882: #endif /* NeXT */ ! 883: } ! 884: } ! 885: ! 886: /* Make still unresolved immediate matches conform to size of immediate ! 887: given in i.suffix. Note: overlap2 cannot be an immediate! ! 888: We assume this. */ ! 889: #ifdef NeXT ! 890: /* Need to check for the case the immediate is larger than the suffix and ! 891: force the value of overlap to the correct immediate size. */ ! 892: if(overlap0 & (Imm8|Imm8S|Imm16|Imm32)){ ! 893: if(i.suffix == BYTE_OPCODE_SUFFIX && (overlap0 & (Imm8|Imm8S)) == 0) ! 894: overlap0 = Imm8|Imm8S; ! 895: else if(i.suffix == WORD_OPCODE_SUFFIX && ! 896: (overlap0 & (Imm16|Imm8|Imm8S)) == 0) ! 897: overlap0 = Imm16; ! 898: } ! 899: #endif /* NeXT */ ! 900: if ((overlap0 & (Imm8|Imm8S|Imm16|Imm32)) ! 901: && overlap0 != Imm8 && overlap0 != Imm8S ! 902: && overlap0 != Imm16 && overlap0 != Imm32) { ! 903: if (! i.suffix) { ! 904: as_bad ("no opcode suffix given; can't determine immediate size"); ! 905: return; ! 906: } ! 907: overlap0 &= (i.suffix == BYTE_OPCODE_SUFFIX ? (Imm8|Imm8S) : ! 908: (i.suffix == WORD_OPCODE_SUFFIX ? Imm16 : Imm32)); ! 909: } ! 910: #ifdef NeXT ! 911: if(overlap1 & (Imm8|Imm8S|Imm16|Imm32)){ ! 912: if(i.suffix == BYTE_OPCODE_SUFFIX && (overlap1 & (Imm8|Imm8S)) == 0) ! 913: overlap1 = Imm8|Imm8S; ! 914: else if(i.suffix == WORD_OPCODE_SUFFIX && ! 915: (overlap0 & (Imm16|Imm8|Imm8S)) == 0) ! 916: overlap1 = Imm16; ! 917: } ! 918: #endif /* NeXT */ ! 919: if ((overlap1 & (Imm8|Imm8S|Imm16|Imm32)) ! 920: && overlap1 != Imm8 && overlap1 != Imm8S ! 921: && overlap1 != Imm16 && overlap1 != Imm32) { ! 922: if (! i.suffix) { ! 923: as_bad ("no opcode suffix given; can't determine immediate size"); ! 924: return; ! 925: } ! 926: overlap1 &= (i.suffix == BYTE_OPCODE_SUFFIX ? (Imm8|Imm8S) : ! 927: (i.suffix == WORD_OPCODE_SUFFIX ? Imm16 : Imm32)); ! 928: } ! 929: ! 930: i.types[0] = overlap0; ! 931: i.types[1] = overlap1; ! 932: i.types[2] = overlap2; ! 933: ! 934: if (overlap0 & ImplicitRegister) i.reg_operands--; ! 935: if (overlap1 & ImplicitRegister) i.reg_operands--; ! 936: if (overlap2 & ImplicitRegister) i.reg_operands--; ! 937: if (overlap0 & Imm1) i.imm_operands = 0; /* kludge for shift insns */ ! 938: ! 939: if (found_reverse_match) { ! 940: uint save; ! 941: save = t->operand_types[0]; ! 942: t->operand_types[0] = t->operand_types[1]; ! 943: t->operand_types[1] = save; ! 944: } ! 945: ! 946: /* Finalize opcode. First, we change the opcode based on the operand ! 947: size given by i.suffix: we never have to change things for byte insns, ! 948: or when no opcode suffix is need to size the operands. */ ! 949: ! 950: if (! i.suffix && (t->opcode_modifier & W)) { ! 951: as_bad ("no opcode suffix given and no register operands; can't size instruction"); ! 952: return; ! 953: } ! 954: ! 955: if (i.suffix && i.suffix != BYTE_OPCODE_SUFFIX) { ! 956: /* Select between byte and word/dword operations. */ ! 957: if (t->opcode_modifier & W) ! 958: t->base_opcode |= W; ! 959: /* Now select between word & dword operations via the ! 960: operand size prefix. */ ! 961: if (i.suffix == WORD_OPCODE_SUFFIX) { ! 962: if (i.prefixes == MAX_PREFIXES) { ! 963: as_bad ("%d prefixes given and 'w' opcode suffix gives too many prefixes", ! 964: MAX_PREFIXES); ! 965: return; ! 966: } ! 967: i.prefix[i.prefixes++] = WORD_PREFIX_OPCODE; ! 968: } ! 969: } ! 970: ! 971: /* For insns with operands there are more diddles to do to the opcode. */ ! 972: if (i.operands) { ! 973: /* If we found a reverse match we must alter the opcode direction bit ! 974: found_reverse_match holds bit to set (different for int & ! 975: float insns). */ ! 976: ! 977: if (found_reverse_match) { ! 978: t->base_opcode |= found_reverse_match; ! 979: } ! 980: ! 981: #if defined(i486) || defined (i586) ! 982: if (t->base_opcode == BSWAP_OPCODE) { ! 983: t->base_opcode |= i.regs[0]->reg_num; ! 984: } ! 985: #endif /* defined (i486) || defined (i586) */ ! 986: ! 987: /* ! 988: The imul $imm, %reg instruction is converted into ! 989: imul $imm, %reg, %reg. */ ! 990: if (t->opcode_modifier & imulKludge) { ! 991: i.regs[2] = i.regs[1]; /* Pretend we saw the 3 operand case. */ ! 992: i.reg_operands = 2; ! 993: } ! 994: ! 995: /* Certain instructions expect the destination to be in the i.rm.reg ! 996: field. This is by far the exceptional case. For these instructions, ! 997: if the source operand is a register, we must reverse the i.rm.reg ! 998: and i.rm.regmem fields. We accomplish this by faking that the ! 999: two register operands were given in the reverse order. */ ! 1000: if ((t->opcode_modifier & ReverseRegRegmem) && i.reg_operands == 2) { ! 1001: uint first_reg_operand = (i.types[0] & Reg) ? 0 : 1; ! 1002: uint second_reg_operand = first_reg_operand + 1; ! 1003: reg_entry *tmp = i.regs[first_reg_operand]; ! 1004: i.regs[first_reg_operand] = i.regs[second_reg_operand]; ! 1005: i.regs[second_reg_operand] = tmp; ! 1006: } ! 1007: ! 1008: if (t->opcode_modifier & ShortForm) { ! 1009: /* The register or float register operand is in operand 0 or 1. */ ! 1010: uint o = (i.types[0] & (Reg|FloatReg)) ? 0 : 1; ! 1011: /* Register goes in low 3 bits of opcode. */ ! 1012: t->base_opcode |= i.regs[o]->reg_num; ! 1013: } else if (t->opcode_modifier & ShortFormW) { ! 1014: /* Short form with 0x8 width bit. Register is always dest. operand */ ! 1015: t->base_opcode |= i.regs[1]->reg_num; ! 1016: if (i.suffix == WORD_OPCODE_SUFFIX || ! 1017: i.suffix == DWORD_OPCODE_SUFFIX) ! 1018: t->base_opcode |= 0x8; ! 1019: } else if (t->opcode_modifier & Seg2ShortForm) { ! 1020: if (t->base_opcode == POP_SEG_SHORT && i.regs[0]->reg_num == 1) { ! 1021: as_bad ("you can't 'pop cs' on the 386."); ! 1022: return; ! 1023: } ! 1024: t->base_opcode |= (i.regs[0]->reg_num << 3); ! 1025: } else if (t->opcode_modifier & Seg3ShortForm) { ! 1026: /* 'push %fs' is 0x0fa0; 'pop %fs' is 0x0fa1. ! 1027: 'push %gs' is 0x0fa8; 'pop %fs' is 0x0fa9. ! 1028: So, only if i.regs[0]->reg_num == 5 (%gs) do we need ! 1029: to change the opcode. */ ! 1030: if (i.regs[0]->reg_num == 5) ! 1031: t->base_opcode |= 0x08; ! 1032: } else if (t->opcode_modifier & Modrm) { ! 1033: /* The opcode is completed (modulo t->extension_opcode which must ! 1034: be put into the modrm byte. ! 1035: Now, we make the modrm & index base bytes based on all the info ! 1036: we've collected. */ ! 1037: ! 1038: /* i.reg_operands MUST be the number of real register operands; ! 1039: implicit registers do not count. */ ! 1040: if (i.reg_operands == 2) { ! 1041: uint source, dest; ! 1042: source = (i.types[0] & (Reg|SReg2|SReg3|Control|Debug|Test)) ? 0 : 1; ! 1043: dest = source + 1; ! 1044: i.rm.mode = 3; ! 1045: /* We must be careful to make sure that all segment/control/test/ ! 1046: debug registers go into the i.rm.reg field (despite the whether ! 1047: they are source or destination operands). */ ! 1048: if (i.regs[dest]->reg_type & (SReg2|SReg3|Control|Debug|Test)) { ! 1049: i.rm.reg = i.regs[dest]->reg_num; ! 1050: i.rm.regmem = i.regs[source]->reg_num; ! 1051: } else { ! 1052: i.rm.reg = i.regs[source]->reg_num; ! 1053: i.rm.regmem = i.regs[dest]->reg_num; ! 1054: } ! 1055: } else { /* if it's not 2 reg operands... */ ! 1056: if (i.mem_operands) { ! 1057: uint fake_zero_displacement = FALSE; ! 1058: uint o = (i.types[0] & Mem) ? 0 : ((i.types[1] & Mem) ? 1 : 2); ! 1059: ! 1060: /* Encode memory operand into modrm byte and base index byte. */ ! 1061: ! 1062: if (i.base_reg == esp && ! i.index_reg) { ! 1063: /* <disp>(%esp) becomes two byte modrm with no index register. */ ! 1064: i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; ! 1065: i.rm.mode = MODE_FROM_DISP_SIZE (i.types[o]); ! 1066: i.bi.base = ESP_REG_NUM; ! 1067: i.bi.index = NO_INDEX_REGISTER; ! 1068: i.bi.scale = 0; /* Must be zero! */ ! 1069: } else if (i.base_reg == ebp && !i.index_reg) { ! 1070: if (! (i.types[o] & Disp)) { ! 1071: /* Must fake a zero byte displacement. ! 1072: There is no direct way to code '(%ebp)' directly. */ ! 1073: fake_zero_displacement = TRUE; ! 1074: /* fake_zero_displacement code does not set this. */ ! 1075: i.types[o] |= Disp8; ! 1076: } ! 1077: i.rm.mode = MODE_FROM_DISP_SIZE (i.types[o]); ! 1078: i.rm.regmem = EBP_REG_NUM; ! 1079: } else if (! i.base_reg && (i.types[o] & BaseIndex)) { ! 1080: /* There are three cases here. ! 1081: Case 1: '<32bit disp>(,1)' -- indirect absolute. ! 1082: (Same as cases 2 & 3 with NO index register) ! 1083: Case 2: <32bit disp> (,<index>) -- no base register with disp ! 1084: Case 3: (, <index>) --- no base register; ! 1085: no disp (must add 32bit 0 disp). */ ! 1086: i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; ! 1087: i.rm.mode = 0; /* 32bit mode */ ! 1088: i.bi.base = NO_BASE_REGISTER; ! 1089: i.types[o] &= ~Disp; ! 1090: i.types[o] |= Disp32; /* Must be 32bit! */ ! 1091: if (i.index_reg) { /* case 2 or case 3 */ ! 1092: i.bi.index = i.index_reg->reg_num; ! 1093: i.bi.scale = i.log2_scale_factor; ! 1094: if (i.disp_operands == 0) ! 1095: fake_zero_displacement = TRUE; /* case 3 */ ! 1096: } else { ! 1097: i.bi.index = NO_INDEX_REGISTER; ! 1098: i.bi.scale = 0; ! 1099: } ! 1100: } else if (i.disp_operands && !i.base_reg && !i.index_reg) { ! 1101: /* Operand is just <32bit disp> */ ! 1102: i.rm.regmem = EBP_REG_NUM; ! 1103: i.rm.mode = 0; ! 1104: i.types[o] &= ~Disp; ! 1105: i.types[o] |= Disp32; ! 1106: } else { ! 1107: /* It's not a special case; rev'em up. */ ! 1108: i.rm.regmem = i.base_reg->reg_num; ! 1109: i.rm.mode = MODE_FROM_DISP_SIZE (i.types[o]); ! 1110: if (i.index_reg) { ! 1111: i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; ! 1112: i.bi.base = i.base_reg->reg_num; ! 1113: i.bi.index = i.index_reg->reg_num; ! 1114: i.bi.scale = i.log2_scale_factor; ! 1115: if (i.base_reg == ebp && i.disp_operands == 0) { /* pace */ ! 1116: fake_zero_displacement = TRUE; ! 1117: i.types[o] |= Disp8; ! 1118: i.rm.mode = MODE_FROM_DISP_SIZE (i.types[o]); ! 1119: } ! 1120: } ! 1121: } ! 1122: if (fake_zero_displacement) { ! 1123: /* Fakes a zero displacement assuming that i.types[o] holds ! 1124: the correct displacement size. */ ! 1125: exp = &disp_expressions[i.disp_operands++]; ! 1126: i.disps[o] = exp; ! 1127: exp->X_seg = SEG_ABSOLUTE; ! 1128: exp->X_add_number = 0; ! 1129: exp->X_add_symbol = (symbolS *) 0; ! 1130: exp->X_subtract_symbol = (symbolS *) 0; ! 1131: } ! 1132: ! 1133: /* Select the correct segment for the memory operand. */ ! 1134: if (i.seg) { ! 1135: uint seg_index; ! 1136: const seg_entry * default_seg; ! 1137: ! 1138: if (i.rm.regmem == ESCAPE_TO_TWO_BYTE_ADDRESSING) { ! 1139: seg_index = (i.rm.mode<<3) | i.bi.base; ! 1140: default_seg = two_byte_segment_defaults [seg_index]; ! 1141: } else { ! 1142: seg_index = (i.rm.mode<<3) | i.rm.regmem; ! 1143: default_seg = one_byte_segment_defaults [seg_index]; ! 1144: } ! 1145: /* If the specified segment is not the default, use an ! 1146: opcode prefix to select it */ ! 1147: if (i.seg != default_seg) { ! 1148: if (i.prefixes == MAX_PREFIXES) { ! 1149: as_bad ("%d prefixes given and %s segment override gives too many prefixes", ! 1150: MAX_PREFIXES, i.seg->seg_name); ! 1151: return; ! 1152: } ! 1153: #ifdef NeXT ! 1154: if(add_seg_prefix(i.seg->seg_prefix)) ! 1155: return; ! 1156: #else /* !defined(NeXT) */ ! 1157: i.prefix[i.prefixes++] = i.seg->seg_prefix; ! 1158: #endif /* NeXT */ ! 1159: } ! 1160: } ! 1161: } ! 1162: ! 1163: /* Fill in i.rm.reg or i.rm.regmem field with register operand ! 1164: (if any) based on t->extension_opcode. Again, we must be careful ! 1165: to make sure that segment/control/debug/test registers are coded ! 1166: into the i.rm.reg field. */ ! 1167: if (i.reg_operands) { ! 1168: uint o = ! 1169: (i.types[0] & (Reg|SReg2|SReg3|Control|Debug|Test)) ? 0 : ! 1170: (i.types[1] & (Reg|SReg2|SReg3|Control|Debug|Test)) ? 1 : 2; ! 1171: /* If there is an extension opcode to put here, the register number ! 1172: must be put into the regmem field. */ ! 1173: if (t->extension_opcode != None) ! 1174: i.rm.regmem = i.regs[o]->reg_num; ! 1175: else i.rm.reg = i.regs[o]->reg_num; ! 1176: ! 1177: /* Now, if no memory operand has set i.rm.mode = 0, 1, 2 ! 1178: we must set it to 3 to indicate this is a register operand ! 1179: int the regmem field */ ! 1180: if (! i.mem_operands) i.rm.mode = 3; ! 1181: } ! 1182: ! 1183: /* Fill in i.rm.reg field with extension opcode (if any). */ ! 1184: if (t->extension_opcode != None) ! 1185: i.rm.reg = t->extension_opcode; ! 1186: } ! 1187: #ifdef NeXT ! 1188: } else if (i.seg) { ! 1189: if (i.prefixes == MAX_PREFIXES) { ! 1190: as_bad ("%d prefixes given and %s segment override gives too many " ! 1191: " prefixes", MAX_PREFIXES, i.seg->seg_name); ! 1192: return; ! 1193: } ! 1194: if(add_seg_prefix(i.seg->seg_prefix)) ! 1195: return; ! 1196: #endif /* NeXT */ ! 1197: } ! 1198: } ! 1199: } ! 1200: ! 1201: /* Handle conversion of 'int $3' --> special int3 insn. */ ! 1202: if (t->base_opcode == INT_OPCODE && i.imms[0]->X_add_number == 3) { ! 1203: t->base_opcode = INT3_OPCODE; ! 1204: i.imm_operands = 0; ! 1205: } ! 1206: ! 1207: #ifdef NeXT /* generate stabs for debugging assembly code */ ! 1208: /* ! 1209: * If the -g flag is present generate a line number stab for the ! 1210: * instruction. ! 1211: * ! 1212: * See the detailed comments about stabs in read_a_source_file() for a ! 1213: * description of what is going on here. ! 1214: */ ! 1215: if (flagseen['g'] && frchain_now->frch_nsect == text_nsect) { ! 1216: (void)symbol_new( ! 1217: "", ! 1218: 68 /* N_SLINE */, ! 1219: text_nsect, ! 1220: logical_input_line /* n_desc, line number */, ! 1221: obstack_next_free(&frags) - frag_now->fr_literal, ! 1222: frag_now); ! 1223: } ! 1224: #endif /* NeXT */ ! 1225: /* We are ready to output the insn. */ ! 1226: { ! 1227: register char * p; ! 1228: ! 1229: /* Output jumps. */ ! 1230: if (t->opcode_modifier & Jump) { ! 1231: int n = i.disps[0]->X_add_number; ! 1232: ! 1233: switch (i.disps[0]->X_seg) { ! 1234: case SEG_ABSOLUTE: ! 1235: #ifndef NeXT ! 1236: if (FITS_IN_SIGNED_BYTE (n)) { ! 1237: p = frag_more (2); ! 1238: p[0] = t->base_opcode; ! 1239: p[1] = n; ! 1240: #if 0 /* leave out 16 bit jumps - pace */ ! 1241: } else if (FITS_IN_SIGNED_WORD (n)) { ! 1242: p = frag_more (4); ! 1243: p[0] = WORD_PREFIX_OPCODE; ! 1244: p[1] = t->base_opcode; ! 1245: md_number_to_chars (&p[2], n, 2); ! 1246: #endif ! 1247: } else ! 1248: #endif /* !defined(NeXT) */ ! 1249: { /* It's an absolute dword displacement. */ ! 1250: if (t->base_opcode == JUMP_PC_RELATIVE) { /* pace */ ! 1251: /* unconditional jump */ ! 1252: p = frag_more (5); ! 1253: p[0] = 0xe9; ! 1254: md_number_to_chars (&p[1], n , 4); ! 1255: #ifdef NeXT ! 1256: fix_new(frag_now, p - frag_now->fr_literal + 1, 4, 0, 0, n, 1, 1, 0); ! 1257: #endif /* NeXT */ ! 1258: } else { ! 1259: /* conditional jump */ ! 1260: p = frag_more (6); ! 1261: p[0] = TWO_BYTE_OPCODE_ESCAPE; ! 1262: p[1] = t->base_opcode + 0x10; ! 1263: md_number_to_chars (&p[2], n, 4); ! 1264: #ifdef NeXT ! 1265: fix_new(frag_now, p - frag_now->fr_literal + 2, 4, 0, 0, n, 1, 1, 0); ! 1266: #endif /* NeXT */ ! 1267: } ! 1268: } ! 1269: break; ! 1270: default: ! 1271: /* It's a symbol; end frag & setup for relax. ! 1272: Make sure there are 6 chars left in the current frag; if not ! 1273: we'll have to start a new one. */ ! 1274: /* I caught it failing with obstack_room == 6, ! 1275: so I changed to <= pace */ ! 1276: if (obstack_room (&frags) <= 6) { ! 1277: frag_wane(frag_now); ! 1278: frag_new (0); ! 1279: } ! 1280: #ifdef NeXT ! 1281: /* ! 1282: * NeXT scatter-loading forces the use of only 32 bit jumps ! 1283: * for everything that isn't local. We assume that our compiler ! 1284: * will NOT generate jumps to local variables that are outside ! 1285: * of the scope of a block. ! 1286: */ ! 1287: if (!is_local_symbol(i.disps[0]->X_add_symbol)) { ! 1288: ! 1289: if (t->base_opcode == JUMP_PC_RELATIVE) { ! 1290: p = frag_more(1); ! 1291: *p = 0xe9; /* use 32-bit version */ ! 1292: } else { ! 1293: p = frag_more (2); /* opcode can be at most two bytes */ ! 1294: /* put out high byte first: can't use md_number_to_chars! */ ! 1295: *p++ = TWO_BYTE_OPCODE_ESCAPE; ! 1296: *p = (t->base_opcode + 0x10) & 0xff; ! 1297: } ! 1298: p = frag_more (4); ! 1299: fix_new (frag_now, p - frag_now->fr_literal, 4, ! 1300: i.disps[0]->X_add_symbol, i.disps[0]->X_subtract_symbol, ! 1301: i.disps[0]->X_add_number, 1, 1, 0); ! 1302: } else ! 1303: #endif ! 1304: { ! 1305: p = frag_more (1); ! 1306: p[0] = t->base_opcode; ! 1307: frag_var (rs_machine_dependent, ! 1308: 6, /* 2 opcode/prefix + 4 displacement */ ! 1309: 1, ! 1310: ((uchar) *p == JUMP_PC_RELATIVE ! 1311: ? ENCODE_RELAX_STATE (UNCOND_JUMP, BYTE) ! 1312: : ENCODE_RELAX_STATE (COND_JUMP, BYTE)), ! 1313: i.disps[0]->X_add_symbol, ! 1314: n, p); ! 1315: } ! 1316: break; ! 1317: } ! 1318: } else if (t->opcode_modifier & (JumpByte|JumpDword)) { ! 1319: int size = (t->opcode_modifier & JumpByte) ? 1 : 4; ! 1320: int n = i.disps[0]->X_add_number; ! 1321: ! 1322: #ifdef NeXT ! 1323: register char *q; ! 1324: ! 1325: if((t->opcode_modifier & JumpByte) == 0 && i.suffix == 'w') ! 1326: size = 2; ! 1327: ! 1328: /* First the prefix bytes. */ ! 1329: for (q = i.prefix; q < i.prefix + i.prefixes; q++) { ! 1330: p = frag_more (1); ! 1331: md_number_to_chars (p, (uint) *q, 1); ! 1332: } ! 1333: #endif /* NeXT */ ! 1334: ! 1335: if (FITS_IN_UNSIGNED_BYTE((int)t->base_opcode)) { ! 1336: FRAG_APPEND_1_CHAR (t->base_opcode); ! 1337: } else { ! 1338: p = frag_more (2); /* opcode can be at most two bytes */ ! 1339: /* put out high byte first: can't use md_number_to_chars! */ ! 1340: *p++ = (t->base_opcode >> 8) & 0xff; ! 1341: *p = t->base_opcode & 0xff; ! 1342: } ! 1343: ! 1344: p = frag_more (size); ! 1345: switch (i.disps[0]->X_seg) { ! 1346: case SEG_ABSOLUTE: ! 1347: #ifdef NeXT ! 1348: /* two bugs here, 1) this displacement is pc relitive and this case ! 1349: with an absolute value did not subtract the pc 2) since it is ! 1350: pc relitive a relocation entry must be emitted so the link editor ! 1351: will fix this when it moves the instruction */ ! 1352: md_number_to_chars (p, n - ! 1353: (obstack_next_free(&frags) - frag_now->fr_literal), size); ! 1354: #else /* !defined(NeXT) */ ! 1355: md_number_to_chars (p, n, size); ! 1356: #endif /* NeXT */ ! 1357: if (size == 1 && ! FITS_IN_SIGNED_BYTE (n)) { ! 1358: as_bad ("loop/jecx only takes byte displacement; %d shortened to %d", ! 1359: n, *p); ! 1360: } ! 1361: #ifndef NeXT ! 1362: break; ! 1363: #endif /* NeXT */ ! 1364: default: ! 1365: { ! 1366: if(i.disps[0]->X_add_symbol != NULL && ! 1367: (i.disps[0]->X_subtract_symbol != NULL || ! 1368: i.disps[0]->X_add_symbol->sy_name[0] != 'L' || ! 1369: flagseen ['L'])) ! 1370: fix_new (frag_now, p - frag_now->fr_literal, size, ! 1371: i.disps[0]->X_add_symbol, i.disps[0]->X_subtract_symbol, ! 1372: i.disps[0]->X_add_number, 1, 1, 0); ! 1373: else ! 1374: fix_new (frag_now, p - frag_now->fr_literal, size, ! 1375: i.disps[0]->X_add_symbol, i.disps[0]->X_subtract_symbol, ! 1376: i.disps[0]->X_add_number, 1, 0, 0); ! 1377: } ! 1378: break; ! 1379: } ! 1380: } else if (t->opcode_modifier & JumpInterSegment) { ! 1381: p = frag_more (1 + 2 + 4); /* 1 opcode; 2 segment; 4 offset */ ! 1382: p[0] = t->base_opcode; ! 1383: if (i.imms[1]->X_seg == SEG_ABSOLUTE) ! 1384: md_number_to_chars (p + 1, i.imms[1]->X_add_number, 4); ! 1385: else ! 1386: fix_new (frag_now, p + 1 - frag_now->fr_literal, 4, ! 1387: i.imms[1]->X_add_symbol, ! 1388: i.imms[1]->X_subtract_symbol, ! 1389: i.imms[1]->X_add_number, 0, 0, 0); ! 1390: if (i.imms[0]->X_seg != SEG_ABSOLUTE) ! 1391: as_bad ("can't handle non absolute segment in long call/jmp"); ! 1392: md_number_to_chars (p + 5, i.imms[0]->X_add_number, 2); ! 1393: } else { ! 1394: /* Output normal instructions here. */ ! 1395: register char *q; ! 1396: ! 1397: /* First the prefix bytes. */ ! 1398: for (q = i.prefix; q < i.prefix + i.prefixes; q++) { ! 1399: p = frag_more (1); ! 1400: md_number_to_chars (p, (uint) *q, 1); ! 1401: } ! 1402: ! 1403: /* Now the opcode; be careful about word order here! */ ! 1404: if (FITS_IN_UNSIGNED_BYTE((int)t->base_opcode)) { ! 1405: FRAG_APPEND_1_CHAR (t->base_opcode); ! 1406: } else if (FITS_IN_UNSIGNED_WORD((int)t->base_opcode)) { ! 1407: p = frag_more (2); ! 1408: /* put out high byte first: can't use md_number_to_chars! */ ! 1409: *p++ = (t->base_opcode >> 8) & 0xff; ! 1410: *p = t->base_opcode & 0xff; ! 1411: } else { /* opcode is either 3 or 4 bytes */ ! 1412: if (t->base_opcode & 0xff000000) { ! 1413: p = frag_more (4); ! 1414: *p++ = (t->base_opcode >> 24) & 0xff; ! 1415: } else p = frag_more (3); ! 1416: *p++ = (t->base_opcode >> 16) & 0xff; ! 1417: *p++ = (t->base_opcode >> 8) & 0xff; ! 1418: *p = (t->base_opcode ) & 0xff; ! 1419: } ! 1420: ! 1421: /* Now the modrm byte and base index byte (if present). */ ! 1422: if (t->opcode_modifier & Modrm) { ! 1423: p = frag_more (1); ! 1424: /* md_number_to_chars (p, i.rm, 1); */ ! 1425: md_number_to_chars (p, (i.rm.regmem<<0 | i.rm.reg<<3 | i.rm.mode<<6), 1); ! 1426: /* If i.rm.regmem == ESP (4) && i.rm.mode != Mode 3 (Register mode) ! 1427: ==> need second modrm byte. */ ! 1428: if (i.rm.regmem == ESCAPE_TO_TWO_BYTE_ADDRESSING && i.rm.mode != 3) { ! 1429: p = frag_more (1); ! 1430: /* md_number_to_chars (p, i.bi, 1); */ ! 1431: md_number_to_chars (p,(i.bi.base<<0 | i.bi.index<<3 | i.bi.scale<<6), 1); ! 1432: } ! 1433: } ! 1434: ! 1435: if (i.disp_operands) { ! 1436: register int n; ! 1437: ! 1438: for (n = 0; n < i.operands; n++) { ! 1439: if (i.disps[n]) { ! 1440: if (i.disps[n]->X_seg == SEG_ABSOLUTE) { ! 1441: if (i.types[n] & (Disp8|Abs8)) { ! 1442: p = frag_more (1); ! 1443: md_number_to_chars (p, i.disps[n]->X_add_number, 1); ! 1444: } else if (i.types[n] & (Disp16|Abs16)) { ! 1445: p = frag_more (2); ! 1446: md_number_to_chars (p, i.disps[n]->X_add_number, 2); ! 1447: } else { /* Disp32|Abs32 */ ! 1448: p = frag_more (4); ! 1449: md_number_to_chars (p, i.disps[n]->X_add_number, 4); ! 1450: } ! 1451: } else { /* not SEG_ABSOLUTE */ ! 1452: /* need a 32-bit fixup (don't support 8bit non-absolute disps) */ ! 1453: p = frag_more (4); ! 1454: fix_new (frag_now, p - frag_now->fr_literal, 4, ! 1455: i.disps[n]->X_add_symbol, i.disps[n]->X_subtract_symbol, ! 1456: i.disps[n]->X_add_number, 0, 0, 0); ! 1457: } ! 1458: } ! 1459: } ! 1460: } /* end displacement output */ ! 1461: ! 1462: /* output immediate */ ! 1463: if (i.imm_operands) { ! 1464: register int n; ! 1465: ! 1466: for (n = 0; n < i.operands; n++) { ! 1467: if (i.imms[n]) { ! 1468: if (i.imms[n]->X_seg == SEG_ABSOLUTE) { ! 1469: if (i.types[n] & (Imm8|Imm8S)) { ! 1470: p = frag_more (1); ! 1471: md_number_to_chars (p, i.imms[n]->X_add_number, 1); ! 1472: } else if (i.types[n] & Imm16) { ! 1473: p = frag_more (2); ! 1474: md_number_to_chars (p, i.imms[n]->X_add_number, 2); ! 1475: } else { ! 1476: p = frag_more (4); ! 1477: md_number_to_chars (p, i.imms[n]->X_add_number, 4); ! 1478: } ! 1479: } else { /* not SEG_ABSOLUTE */ ! 1480: /* need a 32-bit fixup (don't support 8bit non-absolute ims) */ ! 1481: /* try to support other sizes ... */ ! 1482: int size; ! 1483: if (i.types[n] & (Imm8|Imm8S)) ! 1484: size = 1; ! 1485: else if (i.types[n] & Imm16) ! 1486: size = 2; ! 1487: else ! 1488: size = 4; ! 1489: p = frag_more (size); ! 1490: fix_new (frag_now, p - frag_now->fr_literal, size, ! 1491: i.imms[n]->X_add_symbol, i.imms[n]->X_subtract_symbol, ! 1492: i.imms[n]->X_add_number, 0, 0, 0); ! 1493: } ! 1494: } ! 1495: } ! 1496: } /* end immediate output */ ! 1497: } ! 1498: ! 1499: #ifdef DEBUG386 ! 1500: if (flagseen ['D']) { ! 1501: pi (line, &i); ! 1502: } ! 1503: #endif /* DEBUG386 */ ! 1504: ! 1505: } ! 1506: return; ! 1507: } ! 1508: ! 1509: /* Parse OPERAND_STRING into the i386_insn structure I. Returns non-zero ! 1510: on error. */ ! 1511: static ! 1512: int ! 1513: i386_operand( ! 1514: char *operand_string) ! 1515: { ! 1516: register char *op_string = operand_string; ! 1517: ! 1518: /* Address of '\0' at end of operand_string. */ ! 1519: char * end_of_operand_string = operand_string + strlen(operand_string); ! 1520: ! 1521: /* Start and end of displacement string expression (if found). */ ! 1522: char * displacement_string_start = 0; ! 1523: char * displacement_string_end = 0; ! 1524: ! 1525: /* We check for an absolute prefix (differentiating, ! 1526: for example, 'jmp pc_relative_label' from 'jmp *absolute_label'. */ ! 1527: if (*op_string == ABSOLUTE_PREFIX) { ! 1528: op_string++; ! 1529: i.types[this_operand] |= JumpAbsolute; ! 1530: } ! 1531: ! 1532: /* Check if operand is a register. */ ! 1533: if (*op_string == REGISTER_PREFIX) { ! 1534: register reg_entry * r; ! 1535: if (! (r = parse_register (op_string))) { ! 1536: as_bad ("bad register name ('%s')", op_string); ! 1537: return 0; ! 1538: } ! 1539: /* Check for segment override, rather than segment register by ! 1540: searching for ':' after %<x>s where <x> = s, c, d, e, f, g. */ ! 1541: if ((r->reg_type & (SReg2|SReg3)) && op_string[3] == ':') { ! 1542: switch (r->reg_num) { ! 1543: case 0: ! 1544: #ifdef NeXT ! 1545: if(i.mem_operands != 0) i.seg2nd = &es; else ! 1546: #endif /* NeXT */ ! 1547: i.seg = &es; break; ! 1548: case 1: ! 1549: #ifdef NeXT ! 1550: if(i.mem_operands != 0) i.seg2nd = &cs; else ! 1551: #endif /* NeXT */ ! 1552: i.seg = &cs; break; ! 1553: case 2: ! 1554: #ifdef NeXT ! 1555: if(i.mem_operands != 0) i.seg2nd = &ss; else ! 1556: #endif /* NeXT */ ! 1557: i.seg = &ss; break; ! 1558: case 3: ! 1559: #ifdef NeXT ! 1560: if(i.mem_operands != 0) i.seg2nd = &ds; else ! 1561: #endif /* NeXT */ ! 1562: i.seg = &ds; break; ! 1563: case 4: ! 1564: #ifdef NeXT ! 1565: if(i.mem_operands != 0) i.seg2nd = &fs; else ! 1566: #endif /* NeXT */ ! 1567: i.seg = &fs; break; ! 1568: case 5: ! 1569: #ifdef NeXT ! 1570: if(i.mem_operands != 0) i.seg2nd = &gs; else ! 1571: #endif /* NeXT */ ! 1572: i.seg = &gs; break; ! 1573: } ! 1574: op_string += 4; /* skip % <x> s : */ ! 1575: operand_string = op_string; /* Pretend given string starts here. */ ! 1576: if (!is_digit_char(*op_string) && !is_identifier_char(*op_string) ! 1577: && *op_string != '(' && *op_string != ABSOLUTE_PREFIX) { ! 1578: as_bad ("bad memory operand after segment override"); ! 1579: return 0; ! 1580: } ! 1581: /* Handle case of %es:*foo. */ ! 1582: if (*op_string == ABSOLUTE_PREFIX) { ! 1583: op_string++; ! 1584: i.types[this_operand] |= JumpAbsolute; ! 1585: } ! 1586: goto do_memory_reference; ! 1587: } ! 1588: i.types[this_operand] |= r->reg_type; ! 1589: i.regs[this_operand] = r; ! 1590: i.reg_operands++; ! 1591: } else if (*op_string == IMMEDIATE_PREFIX) { /* ... or an immediate */ ! 1592: char * save_input_line_pointer; ! 1593: register expressionS *exp; ! 1594: segT exp_seg; ! 1595: if (i.imm_operands == MAX_IMMEDIATE_OPERANDS) { ! 1596: as_bad ("only 1 or 2 immediate operands are allowed"); ! 1597: return 0; ! 1598: } ! 1599: exp = &im_expressions[i.imm_operands++]; ! 1600: i.imms [this_operand] = exp; ! 1601: save_input_line_pointer = input_line_pointer; ! 1602: input_line_pointer = ++op_string; /* must advance op_string! */ ! 1603: exp_seg = expression (exp); ! 1604: input_line_pointer = save_input_line_pointer; ! 1605: switch (exp_seg) { ! 1606: case SEG_NONE: /* missing or bad expr becomes absolute 0 */ ! 1607: as_bad ("missing or invalid immediate expression '%s' taken as 0", ! 1608: operand_string); ! 1609: exp->X_seg = SEG_ABSOLUTE; ! 1610: exp->X_add_number = 0; ! 1611: exp->X_add_symbol = (symbolS *) 0; ! 1612: exp->X_subtract_symbol = (symbolS *) 0; ! 1613: i.types[this_operand] |= Imm; ! 1614: break; ! 1615: case SEG_ABSOLUTE: ! 1616: i.types[this_operand] |= SMALLEST_IMM_TYPE (exp->X_add_number); ! 1617: break; ! 1618: case SEG_SECT: ! 1619: case SEG_UNKNOWN: ! 1620: case SEG_DIFFSECT: ! 1621: i.types[this_operand] |= Imm32; /* this is an address ==> 32bit */ ! 1622: break; ! 1623: default: ! 1624: as_bad ("Unimplemented segment type %d in parse_operand", exp_seg); ! 1625: return 0; ! 1626: } ! 1627: /* shorten this type of this operand if the instruction wants ! 1628: * fewer bits than are present in the immediate. The bit field ! 1629: * code can put out 'andb $0xffffff, %al', for example. pace ! 1630: * also 'movw $foo,(%eax)' ! 1631: */ ! 1632: switch (i.suffix) { ! 1633: case WORD_OPCODE_SUFFIX: ! 1634: i.types[this_operand] |= Imm16; ! 1635: break; ! 1636: case BYTE_OPCODE_SUFFIX: ! 1637: i.types[this_operand] |= Imm16 | Imm8 | Imm8S; ! 1638: break; ! 1639: } ! 1640: } else if (is_digit_char(*op_string) || is_identifier_char(*op_string) ! 1641: || *op_string == '(') { ! 1642: /* This is a memory reference of some sort. */ ! 1643: register char * base_string; ! 1644: uint found_base_index_form; ! 1645: ! 1646: do_memory_reference: ! 1647: if (i.mem_operands == MAX_MEMORY_OPERANDS) { ! 1648: as_bad ("more than 1 memory reference in instruction"); ! 1649: return 0; ! 1650: } ! 1651: i.mem_operands++; ! 1652: ! 1653: /* Determine type of memory operand from opcode_suffix; ! 1654: no opcode suffix implies general memory references. */ ! 1655: switch (i.suffix) { ! 1656: case BYTE_OPCODE_SUFFIX: ! 1657: i.types[this_operand] |= Mem8; ! 1658: break; ! 1659: case WORD_OPCODE_SUFFIX: ! 1660: i.types[this_operand] |= Mem16; ! 1661: break; ! 1662: case DWORD_OPCODE_SUFFIX: ! 1663: default: ! 1664: i.types[this_operand] |= Mem32; ! 1665: } ! 1666: ! 1667: /* Check for base index form. We detect the base index form by ! 1668: looking for an ')' at the end of the operand, searching ! 1669: for the '(' matching it, and finding a REGISTER_PREFIX or ',' ! 1670: after it. */ ! 1671: base_string = end_of_operand_string - 1; ! 1672: found_base_index_form = FALSE; ! 1673: if (*base_string == ')') { ! 1674: uint parens_balenced = 1; ! 1675: /* We've already checked that the number of left & right ()'s are equal, ! 1676: so this loop will not be infinite. */ ! 1677: do { ! 1678: base_string--; ! 1679: if (*base_string == ')') parens_balenced++; ! 1680: if (*base_string == '(') parens_balenced--; ! 1681: } while (parens_balenced); ! 1682: base_string++; /* Skip past '('. */ ! 1683: if (*base_string == REGISTER_PREFIX || *base_string == ',') ! 1684: found_base_index_form = TRUE; ! 1685: } ! 1686: ! 1687: /* If we can't parse a base index register expression, we've found ! 1688: a pure displacement expression. We set up displacement_string_start ! 1689: and displacement_string_end for the code below. */ ! 1690: if (! found_base_index_form) { ! 1691: displacement_string_start = op_string; ! 1692: displacement_string_end = end_of_operand_string; ! 1693: } else { ! 1694: char *base_reg_name, *index_reg_name, *num_string; ! 1695: int num; ! 1696: ! 1697: i.types[this_operand] |= BaseIndex; ! 1698: ! 1699: /* If there is a displacement set-up for it to be parsed later. */ ! 1700: if (base_string != op_string + 1) { ! 1701: displacement_string_start = op_string; ! 1702: displacement_string_end = base_string - 1; ! 1703: } ! 1704: ! 1705: /* Find base register (if any). */ ! 1706: if (*base_string != ',') { ! 1707: base_reg_name = base_string++; ! 1708: /* skip past register name & parse it */ ! 1709: while (isalpha(*base_string)) base_string++; ! 1710: if (base_string == base_reg_name+1) { ! 1711: as_bad ("can't find base register name after '(%c'", ! 1712: REGISTER_PREFIX); ! 1713: return 0; ! 1714: } ! 1715: END_STRING_AND_SAVE (base_string); ! 1716: #ifdef NeXT ! 1717: if (i.base_reg){ ! 1718: if (! (i.base_reg2nd = parse_register (base_reg_name))) { ! 1719: as_bad ("bad base register name ('%s')", base_reg_name); ! 1720: return 0; ! 1721: } ! 1722: } ! 1723: else ! 1724: #endif /* NeXT */ ! 1725: if (! (i.base_reg = parse_register (base_reg_name))) { ! 1726: as_bad ("bad base register name ('%s')", base_reg_name); ! 1727: return 0; ! 1728: } ! 1729: RESTORE_END_STRING (base_string); ! 1730: } ! 1731: ! 1732: /* Now check seperator; must be ',' ==> index reg ! 1733: OR num ==> no index reg. just scale factor ! 1734: OR ')' ==> end. (scale factor = 1) */ ! 1735: if (*base_string != ',' && *base_string != ')') { ! 1736: as_bad ("expecting ',' or ')' after base register in `%s'", ! 1737: operand_string); ! 1738: return 0; ! 1739: } ! 1740: ! 1741: /* There may index reg here; and there may be a scale factor. */ ! 1742: if (*base_string == ',' && *(base_string+1) == REGISTER_PREFIX) { ! 1743: index_reg_name = ++base_string; ! 1744: while (isalpha(*++base_string)); ! 1745: END_STRING_AND_SAVE (base_string); ! 1746: #ifdef NeXT ! 1747: if (i.index_reg) { ! 1748: if(! (i.index_reg2nd = parse_register(index_reg_name))) { ! 1749: as_bad ("bad index register name ('%s')", index_reg_name); ! 1750: return 0; ! 1751: } ! 1752: } ! 1753: else ! 1754: #endif /* NeXT */ ! 1755: if (! (i.index_reg = parse_register(index_reg_name))) { ! 1756: as_bad ("bad index register name ('%s')", index_reg_name); ! 1757: return 0; ! 1758: } ! 1759: RESTORE_END_STRING (base_string); ! 1760: } ! 1761: ! 1762: /* Check for scale factor. */ ! 1763: if (*base_string == ',' && isdigit(*(base_string+1))) { ! 1764: num_string = ++base_string; ! 1765: while (is_digit_char(*base_string)) base_string++; ! 1766: if (base_string == num_string) { ! 1767: as_bad ("can't find a scale factor after ','"); ! 1768: return 0; ! 1769: } ! 1770: END_STRING_AND_SAVE (base_string); ! 1771: /* We've got a scale factor. */ ! 1772: if (! sscanf (num_string, "%d", &num)) { ! 1773: as_bad ("can't parse scale factor from '%s'", num_string); ! 1774: return 0; ! 1775: } ! 1776: RESTORE_END_STRING (base_string); ! 1777: switch (num) { /* must be 1 digit scale */ ! 1778: case 1: ! 1779: #ifdef NeXT ! 1780: if (i.index_reg2nd) i.log2_scale_factor2nd = 0; else ! 1781: #endif /* NeXT */ ! 1782: i.log2_scale_factor = 0; break; ! 1783: case 2: ! 1784: #ifdef NeXT ! 1785: if (i.index_reg2nd) i.log2_scale_factor2nd = 1; else ! 1786: #endif /* NeXT */ ! 1787: i.log2_scale_factor = 1; break; ! 1788: case 4: ! 1789: #ifdef NeXT ! 1790: if (i.index_reg2nd) i.log2_scale_factor2nd = 2; else ! 1791: #endif /* NeXT */ ! 1792: i.log2_scale_factor = 2; break; ! 1793: case 8: ! 1794: #ifdef NeXT ! 1795: if (i.index_reg2nd) i.log2_scale_factor2nd = 3; else ! 1796: #endif /* NeXT */ ! 1797: i.log2_scale_factor = 3; break; ! 1798: default: ! 1799: as_bad ("expecting scale factor of 1, 2, 4, 8; got %d", num); ! 1800: return 0; ! 1801: } ! 1802: } else { ! 1803: if (! i.index_reg && *base_string == ',') { ! 1804: as_bad ("expecting index register or scale factor after ','; got '%c'", ! 1805: *(base_string+1)); ! 1806: return 0; ! 1807: } ! 1808: } ! 1809: } ! 1810: ! 1811: /* If there's an expression begining the operand, parse it, ! 1812: assuming displacement_string_start and displacement_string_end ! 1813: are meaningful. */ ! 1814: if (displacement_string_start) { ! 1815: register expressionS * exp; ! 1816: segT exp_seg; ! 1817: char * save_input_line_pointer; ! 1818: exp = &disp_expressions[i.disp_operands]; ! 1819: i.disps [this_operand] = exp; ! 1820: i.disp_operands++; ! 1821: save_input_line_pointer = input_line_pointer; ! 1822: input_line_pointer = displacement_string_start; ! 1823: END_STRING_AND_SAVE (displacement_string_end); ! 1824: exp_seg = expression (exp); ! 1825: if(*input_line_pointer) ! 1826: as_bad("Ignoring junk '%s' after expression",input_line_pointer); ! 1827: RESTORE_END_STRING (displacement_string_end); ! 1828: input_line_pointer = save_input_line_pointer; ! 1829: switch (exp_seg) { ! 1830: case SEG_NONE: ! 1831: /* missing expr becomes absolute 0 */ ! 1832: as_bad ("missing or invalid displacement '%s' taken as 0", ! 1833: operand_string); ! 1834: i.types[this_operand] |= (Disp|Abs); ! 1835: exp->X_seg = SEG_ABSOLUTE; ! 1836: exp->X_add_number = 0; ! 1837: exp->X_add_symbol = (symbolS *) 0; ! 1838: exp->X_subtract_symbol = (symbolS *) 0; ! 1839: break; ! 1840: case SEG_ABSOLUTE: ! 1841: i.types[this_operand] |= SMALLEST_DISP_TYPE (exp->X_add_number); ! 1842: break; ! 1843: case SEG_SECT: ! 1844: case SEG_DIFFSECT: ! 1845: case SEG_UNKNOWN: /* must be 32 bit displacement (i.e. address) */ ! 1846: i.types[this_operand] |= Disp32; ! 1847: break; ! 1848: default: ! 1849: as_bad ("Unimplemented segment type %d in parse_operand", exp_seg); ! 1850: return 0; ! 1851: } ! 1852: } ! 1853: ! 1854: /* Make sure the memory operand we've been dealt is valid. */ ! 1855: if (i.base_reg && i.index_reg && ! 1856: ! (i.base_reg->reg_type & i.index_reg->reg_type & Reg)) { ! 1857: as_bad ("register size mismatch in (base,index,scale) expression"); ! 1858: return 0; ! 1859: } ! 1860: if ((i.base_reg && (i.base_reg->reg_type & Reg32) == 0) || ! 1861: (i.index_reg && (i.index_reg->reg_type & Reg32) == 0)) { ! 1862: as_bad ("base/index register must be 32 bit register"); ! 1863: return 0; ! 1864: } ! 1865: if (i.index_reg && i.index_reg == esp) { ! 1866: as_bad ("%s may not be used as an index register", esp->reg_name); ! 1867: return 0; ! 1868: } ! 1869: } else { /* it's not a memory operand; argh! */ ! 1870: as_bad ("invalid char %s begining %s operand '%s'", ! 1871: output_invalid(*op_string), ordinal_names[this_operand], ! 1872: op_string); ! 1873: return 0; ! 1874: } ! 1875: return 1; /* normal return */ ! 1876: } ! 1877: ! 1878: /* ! 1879: * md_estimate_size_before_relax() ! 1880: * ! 1881: * Called just before relax(). ! 1882: * Any symbol that is now undefined will not become defined. ! 1883: * Return the correct fr_subtype in the frag. ! 1884: * Return the initial "guess for fr_var" to caller. ! 1885: * The guess for fr_var is ACTUALLY the growth beyond fr_fix. ! 1886: * Whatever we do to grow fr_fix or fr_var contributes to our returned value. ! 1887: * Although it may not be explicit in the frag, pretend fr_var starts with a ! 1888: * 0 value. ! 1889: */ ! 1890: int ! 1891: md_estimate_size_before_relax (fragP, segment_type) ! 1892: register fragS * fragP; ! 1893: register int segment_type; /* N_DATA or N_TEXT. */ ! 1894: { ! 1895: register uchar * opcode; ! 1896: register int old_fr_fix; ! 1897: ! 1898: old_fr_fix = fragP -> fr_fix; ! 1899: opcode = (uchar *) fragP -> fr_opcode; ! 1900: /* We've already got fragP->fr_subtype right; all we have to do is check ! 1901: for un-relaxable symbols. */ ! 1902: #ifdef NeXT ! 1903: if ((fragP -> fr_symbol -> sy_type & N_TYPE) != N_SECT || ! 1904: fragP -> fr_symbol -> sy_other != segment_type) ! 1905: #else ! 1906: if ((fragP -> fr_symbol -> sy_type & N_TYPE) != segment_type) ! 1907: #endif ! 1908: { ! 1909: /* symbol is undefined in this segment */ ! 1910: switch (opcode[0]) { ! 1911: case JUMP_PC_RELATIVE: /* make jmp (0xeb) a dword displacement jump */ ! 1912: opcode[0] = 0xe9; /* dword disp jmp */ ! 1913: fragP -> fr_fix += 4; ! 1914: fix_new (fragP, old_fr_fix, 4, ! 1915: fragP -> fr_symbol, ! 1916: (symbolS *) 0, ! 1917: fragP -> fr_offset, 1, 1, 0); ! 1918: break; ! 1919: ! 1920: default: ! 1921: /* This changes the byte-displacement jump 0x7N --> ! 1922: the dword-displacement jump 0x0f8N */ ! 1923: opcode[1] = opcode[0] + 0x10; ! 1924: opcode[0] = TWO_BYTE_OPCODE_ESCAPE; /* two-byte escape */ ! 1925: fragP -> fr_fix += 1 + 4; /* we've added an opcode byte */ ! 1926: fix_new (fragP, old_fr_fix + 1, 4, ! 1927: fragP -> fr_symbol, ! 1928: (symbolS *) 0, ! 1929: fragP -> fr_offset, 1, 1, 0); ! 1930: break; ! 1931: } ! 1932: frag_wane (fragP); ! 1933: } ! 1934: return (fragP -> fr_var + fragP -> fr_fix - old_fr_fix); ! 1935: } /* md_estimate_size_before_relax() */ ! 1936: ! 1937: /* ! 1938: * md_convert_frag(); ! 1939: * ! 1940: * Called after relax() is finished. ! 1941: * In: Address of frag. ! 1942: * fr_type == rs_machine_dependent. ! 1943: * fr_subtype is what the address relaxed to. ! 1944: * ! 1945: * Out: Any fixSs and constants are set up. ! 1946: * Caller will turn frag into a ".space 0". ! 1947: */ ! 1948: void ! 1949: md_convert_frag( ! 1950: fragS *fragP) ! 1951: { ! 1952: register uchar * opcode; ! 1953: uchar * where_to_put_displacement = 0; ! 1954: uint target_address, opcode_address; ! 1955: uint extension = 0; ! 1956: int displacement_from_opcode_start; ! 1957: ! 1958: opcode = (uchar *) fragP -> fr_opcode; ! 1959: ! 1960: /* Address we want to reach in file space. */ ! 1961: target_address = fragP->fr_symbol->sy_value + fragP->fr_offset; ! 1962: ! 1963: /* Address opcode resides at in file space. */ ! 1964: opcode_address = fragP->fr_address + fragP->fr_fix; ! 1965: ! 1966: /* Displacement from opcode start to fill into instruction. */ ! 1967: displacement_from_opcode_start = target_address - opcode_address; ! 1968: ! 1969: switch (fragP->fr_subtype) { ! 1970: case ENCODE_RELAX_STATE (COND_JUMP, BYTE): ! 1971: case ENCODE_RELAX_STATE (UNCOND_JUMP, BYTE): ! 1972: /* don't have to change opcode */ ! 1973: extension = 1; /* 1 opcode + 1 displacement */ ! 1974: where_to_put_displacement = &opcode[1]; ! 1975: break; ! 1976: ! 1977: case ENCODE_RELAX_STATE (COND_JUMP, WORD): ! 1978: opcode[1] = TWO_BYTE_OPCODE_ESCAPE; ! 1979: opcode[2] = opcode[0] + 0x10; ! 1980: opcode[0] = WORD_PREFIX_OPCODE; ! 1981: extension = 4; /* 3 opcode + 2 displacement */ ! 1982: where_to_put_displacement = &opcode[3]; ! 1983: break; ! 1984: ! 1985: case ENCODE_RELAX_STATE (UNCOND_JUMP, WORD): ! 1986: opcode[1] = 0xe9; ! 1987: opcode[0] = WORD_PREFIX_OPCODE; ! 1988: extension = 3; /* 2 opcode + 2 displacement */ ! 1989: where_to_put_displacement = &opcode[2]; ! 1990: break; ! 1991: ! 1992: case ENCODE_RELAX_STATE (COND_JUMP, DWORD): ! 1993: opcode[1] = opcode[0] + 0x10; ! 1994: opcode[0] = TWO_BYTE_OPCODE_ESCAPE; ! 1995: extension = 5; /* 2 opcode + 4 displacement */ ! 1996: where_to_put_displacement = &opcode[2]; ! 1997: break; ! 1998: ! 1999: case ENCODE_RELAX_STATE (UNCOND_JUMP, DWORD): ! 2000: opcode[0] = 0xe9; ! 2001: extension = 4; /* 1 opcode + 4 displacement */ ! 2002: where_to_put_displacement = &opcode[1]; ! 2003: break; ! 2004: ! 2005: default: ! 2006: BAD_CASE(((int)fragP -> fr_subtype)); ! 2007: break; ! 2008: } ! 2009: /* now put displacement after opcode */ ! 2010: md_number_to_chars (where_to_put_displacement, ! 2011: displacement_from_opcode_start - extension, ! 2012: SIZE_FROM_RELAX_STATE (fragP->fr_subtype)); ! 2013: fragP -> fr_fix += extension; ! 2014: } ! 2015: ! 2016: int ! 2017: md_parse_option( ! 2018: char **argP, ! 2019: int *cntP, ! 2020: char ***vecP) ! 2021: { ! 2022: return 1; ! 2023: } ! 2024: ! 2025: void /* Knows about order of bytes in address. */ ! 2026: md_number_to_chars( ! 2027: char *con, /* Return 'nbytes' of chars here. */ ! 2028: long value, /* The value of the bits. */ ! 2029: int nbytes) /* Number of bytes in the output. */ ! 2030: { ! 2031: register char * p = con; ! 2032: ! 2033: switch (nbytes) { ! 2034: case 1: ! 2035: p[0] = value & 0xff; ! 2036: break; ! 2037: case 2: ! 2038: p[0] = value & 0xff; ! 2039: p[1] = (value >> 8) & 0xff; ! 2040: break; ! 2041: case 4: ! 2042: p[0] = value & 0xff; ! 2043: p[1] = (value>>8) & 0xff; ! 2044: p[2] = (value>>16) & 0xff; ! 2045: p[3] = (value>>24) & 0xff; ! 2046: break; ! 2047: default: ! 2048: BAD_CASE (nbytes); ! 2049: } ! 2050: } ! 2051: ! 2052: ! 2053: void /* Knows about order of bytes in address. */ ! 2054: md_number_to_imm( ! 2055: unsigned char *con, /* Return 'nbytes' of chars here. */ ! 2056: long value, /* The value of the bits. */ ! 2057: int nbytes, /* Number of bytes in the output. */ ! 2058: fixS *fixP, ! 2059: int nsect) ! 2060: { ! 2061: char * answer = alloca (nbytes); ! 2062: register char * p = answer; ! 2063: ! 2064: switch (nbytes) { ! 2065: case 1: ! 2066: *p = value; ! 2067: break; ! 2068: case 2: ! 2069: *p++ = value; ! 2070: *p = (value>>8); ! 2071: break; ! 2072: case 4: ! 2073: *p++ = value; ! 2074: *p++ = (value>>8); ! 2075: *p++ = (value>>16); ! 2076: *p = (value>>24); ! 2077: break; ! 2078: default: ! 2079: BAD_CASE (nbytes); ! 2080: } ! 2081: memcpy(con, answer, nbytes); ! 2082: } ! 2083: ! 2084: #define MAX_LITTLENUMS 6 ! 2085: ! 2086: /* Turn the string pointed to by litP into a floating point constant of type ! 2087: type, and emit the appropriate bytes. The number of LITTLENUMS emitted ! 2088: is stored in *sizeP . An error message is returned, or NULL on OK. ! 2089: */ ! 2090: char * ! 2091: md_atof( ! 2092: int type, ! 2093: char *litP, ! 2094: int *sizeP) ! 2095: { ! 2096: int prec; ! 2097: LITTLENUM_TYPE words[MAX_LITTLENUMS]; ! 2098: LITTLENUM_TYPE *wordP; ! 2099: char *t; ! 2100: char *atof_ieee(); ! 2101: ! 2102: switch(type) { ! 2103: case 'f': ! 2104: case 'F': ! 2105: prec = 2; ! 2106: break; ! 2107: ! 2108: case 'd': ! 2109: case 'D': ! 2110: prec = 4; ! 2111: break; ! 2112: ! 2113: case 'x': ! 2114: case 'X': ! 2115: prec = 5; ! 2116: break; ! 2117: ! 2118: default: ! 2119: *sizeP=0; ! 2120: return "Bad call to md_atof ()"; ! 2121: } ! 2122: t = atof_ieee (input_line_pointer,type,words); ! 2123: if(t) ! 2124: input_line_pointer=t; ! 2125: ! 2126: *sizeP = prec * sizeof(LITTLENUM_TYPE); ! 2127: /* this loops outputs the LITTLENUMs in REVERSE order; in accord with ! 2128: the bigendian 386 */ ! 2129: for(wordP = words + prec - 1;prec--;) { ! 2130: md_number_to_chars (litP, (long) (*wordP--), sizeof(LITTLENUM_TYPE)); ! 2131: litP += sizeof(LITTLENUM_TYPE); ! 2132: } ! 2133: return ""; /* Someone should teach Dean about null pointers */ ! 2134: } ! 2135: ! 2136: static char output_invalid_buf[8]; ! 2137: ! 2138: static ! 2139: char * ! 2140: output_invalid( ! 2141: char c) ! 2142: { ! 2143: if (isprint(c)) sprintf (output_invalid_buf, "'%c'", c); ! 2144: else sprintf (output_invalid_buf, "(0x%x)", c); ! 2145: return output_invalid_buf; ! 2146: } ! 2147: ! 2148: static ! 2149: reg_entry * ! 2150: parse_register( ! 2151: char *reg_string) /* reg_string starts *before* REGISTER_PREFIX */ ! 2152: { ! 2153: register char *s = reg_string; ! 2154: register char *p; ! 2155: char reg_name_given[MAX_REG_NAME_SIZE]; ! 2156: ! 2157: s++; /* skip REGISTER_PREFIX */ ! 2158: for (p = reg_name_given; is_register_char (*s); p++, s++) { ! 2159: *p = register_chars [(int)*s]; ! 2160: if (p >= reg_name_given + MAX_REG_NAME_SIZE) ! 2161: return (reg_entry *) 0; ! 2162: } ! 2163: *p = '\0'; ! 2164: return (reg_entry *) hash_find (reg_hash, reg_name_given); ! 2165: } ! 2166: ! 2167: ! 2168: #ifdef NeXT ! 2169: static ! 2170: int ! 2171: is_local_symbol( ! 2172: struct symbol *sym) ! 2173: { ! 2174: if (sym->sy_name[0] == 'L') { ! 2175: return 1; ! 2176: } ! 2177: return 0; ! 2178: } ! 2179: ! 2180: static ! 2181: int ! 2182: add_seg_prefix( ! 2183: int seg_prefix) ! 2184: { ! 2185: unsigned long j; ! 2186: ! 2187: for(j = 0; j < i.prefixes; j++){ ! 2188: if(i.prefix[j] == /* cs */ 0x2e || ! 2189: i.prefix[j] == /* ds */ 0x3e || ! 2190: i.prefix[j] == /* es */ 0x26 || ! 2191: i.prefix[j] == /* fs */ 0x64 || ! 2192: i.prefix[j] == /* gs */ 0x65 || ! 2193: i.prefix[j] == /* ss */ 0x36){ ! 2194: as_bad ("segment override specified more than once"); ! 2195: return(1); ! 2196: } ! 2197: } ! 2198: if (i.prefixes == MAX_PREFIXES) { ! 2199: as_bad ("too many opcode prefixes"); ! 2200: return(1); ! 2201: } ! 2202: i.prefix[i.prefixes++] = seg_prefix; ! 2203: return(0); ! 2204: } ! 2205: #endif /* NeXT */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.