From 680227f309bd080edf85896139329c62a5f35d98 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Sat, 1 Aug 1992 23:20:55 +0000 Subject: [PATCH] fix for pr1371: heed fx_offset in pcrel relocs --- gas/ChangeLog | 5 + gas/config/tc-sparc.c | 2991 ++++++++++++++++++++++------------------- 2 files changed, 1591 insertions(+), 1405 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 933ddc22216..c154fa5d664 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +Sat Aug 1 19:10:13 1992 Ken Raeburn (raeburn@cygnus.com) + + * config/tc-sparc.c (tc_aout_fix_to_chars): If pc-relative, take + fx_offset into account. + Fri Jul 31 21:53:28 1992 Ken Raeburn (raeburn@cygnus.com) * configure.in (mips host): Accept "ultrix" with version number. diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c index b52043fae23..afde1686052 100644 --- a/gas/config/tc-sparc.c +++ b/gas/config/tc-sparc.c @@ -45,7 +45,7 @@ static int architecture_requested = 0; static int warn_on_bump = 0; const relax_typeS md_relax_table[] = { - 0 }; + 0 }; /* handle of the OPCODE hash table */ static struct hash_control *op_hash = NULL; @@ -55,17 +55,17 @@ extern void s_globl(), s_long(), s_short(), s_space(), cons(); extern void s_align_bytes(), s_ignore(); const pseudo_typeS md_pseudo_table[] = { -{ "align", s_align_bytes, 0 }, /* Defaulting is invalid (0) */ -{ "common", s_common, 0 }, -{ "global", s_globl, 0 }, -{ "half", cons, 2 }, -{ "optim", s_ignore, 0 }, -{ "proc", s_proc, 0 }, -{ "reserve", s_reserve, 0 }, -{ "seg", s_seg, 0 }, -{ "skip", s_space, 0 }, -{ "word", cons, 4 }, -{ NULL, 0, 0 }, + { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0) */ + { "common", s_common, 0 }, + { "global", s_globl, 0 }, + { "half", cons, 2 }, + { "optim", s_ignore, 0 }, + { "proc", s_proc, 0 }, + { "reserve", s_reserve, 0 }, + { "seg", s_seg, 0 }, + { "skip", s_space, 0 }, + { "word", cons, 4 }, + { NULL, 0, 0 }, }; const int md_short_jump_size = 4; @@ -104,12 +104,12 @@ static unsigned char octal[256]; static unsigned char toHex[256]; struct sparc_it { - char *error; -unsigned long opcode; -struct nlist *nlistp; -expressionS exp; -int pcrel; -enum reloc_type reloc; + char *error; + unsigned long opcode; + struct nlist *nlistp; + expressionS exp; + int pcrel; + enum reloc_type reloc; } the_insn, set_insn; #if __STDC__ == 1 @@ -142,249 +142,289 @@ static int max_alignment = 15; static void s_reserve() { char *name; - char *p; - char c; - int align; - int size; - int temp; - symbolS *symbolP; - - name = input_line_pointer; - c = get_symbol_end(); - p = input_line_pointer; - *p = c; - SKIP_WHITESPACE(); - - if (*input_line_pointer != ',') { - as_bad("Expected comma after name"); - ignore_rest_of_line(); - return; - } - - ++input_line_pointer; - - if ((size = get_absolute_expression()) < 0) { - as_bad("BSS length (%d.) <0! Ignored.", size); - ignore_rest_of_line(); - return; - } /* bad length */ - - *p = 0; - symbolP = symbol_find_or_make(name); - *p = c; - - if (strncmp(input_line_pointer, ",\"bss\"", 6) != 0) { - as_bad("bad .reserve segment: `%s'", input_line_pointer); - return; - } /* if not bss */ - - input_line_pointer += 6; - SKIP_WHITESPACE(); - - if (*input_line_pointer == ',') { - ++input_line_pointer; + char *p; + char c; + int align; + int size; + int temp; + symbolS *symbolP; + name = input_line_pointer; + c = get_symbol_end(); + p = input_line_pointer; + *p = c; SKIP_WHITESPACE(); - if (*input_line_pointer == '\n') { - as_bad("Missing alignment"); - return; - } - align = get_absolute_expression(); - if (align > max_alignment){ - align = max_alignment; - as_warn("Alignment too large: %d. assumed.", align); - } else if (align < 0) { - align = 0; - as_warn("Alignment negative. 0 assumed."); + if (*input_line_pointer != ',') { + as_bad("Expected comma after name"); + ignore_rest_of_line(); + return; } + + ++input_line_pointer; + + if ((size = get_absolute_expression()) < 0) { + as_bad("BSS length (%d.) <0! Ignored.", size); + ignore_rest_of_line(); + return; + } /* bad length */ + + *p = 0; + symbolP = symbol_find_or_make(name); + *p = c; + + if (strncmp(input_line_pointer, ",\"bss\"", 6) != 0) { + as_bad("bad .reserve segment: `%s'", input_line_pointer); + return; + } /* if not bss */ + + input_line_pointer += 6; + SKIP_WHITESPACE(); + + if (*input_line_pointer == ',') { + ++input_line_pointer; + + SKIP_WHITESPACE(); + if (*input_line_pointer == '\n') { + as_bad("Missing alignment"); + return; + } + + align = get_absolute_expression(); + if (align > max_alignment){ + align = max_alignment; + as_warn("Alignment too large: %d. assumed.", align); + } else if (align < 0) { + align = 0; + as_warn("Alignment negative. 0 assumed."); + } #ifdef MANY_SEGMENTS #define SEG_BSS SEG_E2 - record_alignment(SEG_E2, align); + record_alignment(SEG_E2, align); #else - record_alignment(SEG_BSS, align); + record_alignment(SEG_BSS, align); #endif + + /* convert to a power of 2 alignment */ + for (temp = 0; (align & 1) == 0; align >>= 1, ++temp) ;; + + if (align != 1) { + as_bad("Alignment not a power of 2"); + ignore_rest_of_line(); + return; + } /* not a power of two */ + + align = temp; + + /* Align */ + align = ~((~0) << align); /* Convert to a mask */ + local_bss_counter = (local_bss_counter + align) & (~align); + } /* if has optional alignment */ - /* convert to a power of 2 alignment */ - for (temp = 0; (align & 1) == 0; align >>= 1, ++temp) ;; - - if (align != 1) { - as_bad("Alignment not a power of 2"); - ignore_rest_of_line(); - return; - } /* not a power of two */ - - align = temp; + if (S_GET_OTHER(symbolP) == 0 + && S_GET_DESC(symbolP) == 0 + && ((S_GET_SEGMENT(symbolP) == SEG_BSS + && S_GET_VALUE(symbolP) == local_bss_counter) + || !S_IS_DEFINED(symbolP))) { + S_SET_VALUE(symbolP, local_bss_counter); + S_SET_SEGMENT(symbolP, SEG_BSS); + symbolP->sy_frag = &bss_address_frag; + local_bss_counter += size; + } else { + as_warn("Ignoring attempt to re-define symbol from %d. to %d.", + S_GET_VALUE(symbolP), local_bss_counter); + } /* if not redefining */ - /* Align */ - align = ~((~0) << align); /* Convert to a mask */ - local_bss_counter = (local_bss_counter + align) & (~align); - } /* if has optional alignment */ - - if (S_GET_OTHER(symbolP) == 0 - && S_GET_DESC(symbolP) == 0 - && ((S_GET_SEGMENT(symbolP) == SEG_BSS - && S_GET_VALUE(symbolP) == local_bss_counter) - || !S_IS_DEFINED(symbolP))) { - S_SET_VALUE(symbolP, local_bss_counter); - S_SET_SEGMENT(symbolP, SEG_BSS); - symbolP->sy_frag = &bss_address_frag; - local_bss_counter += size; - } else { - as_warn("Ignoring attempt to re-define symbol from %d. to %d.", - S_GET_VALUE(symbolP), local_bss_counter); - } /* if not redefining */ - - demand_empty_rest_of_line(); - return; + demand_empty_rest_of_line(); + return; } /* s_reserve() */ static void s_common() { register char *name; - register char c; - register char *p; - register int temp; - register symbolS * symbolP; - - name = input_line_pointer; - c = get_symbol_end(); - /* just after name is now '\0' */ - p = input_line_pointer; - *p = c; - SKIP_WHITESPACE(); - if (* input_line_pointer != ',') { - as_bad("Expected comma after symbol-name"); - ignore_rest_of_line(); - return; - } - input_line_pointer ++; /* skip ',' */ - if ((temp = get_absolute_expression ()) < 0) { - as_bad(".COMMon length (%d.) <0! Ignored.", temp); - ignore_rest_of_line(); - return; - } - *p = 0; - symbolP = symbol_find_or_make(name); - *p = c; - if (S_IS_DEFINED(symbolP)) { - as_bad("Ignoring attempt to re-define symbol"); - ignore_rest_of_line(); - return; - } - if (S_GET_VALUE(symbolP) != 0) { - if (S_GET_VALUE(symbolP) != temp) { - as_warn("Length of .comm \"%s\" is already %d. Not changed to %d.", - S_GET_NAME(symbolP), S_GET_VALUE(symbolP), temp); + register char c; + register char *p; + register int temp; + register symbolS * symbolP; + + name = input_line_pointer; + c = get_symbol_end(); + /* just after name is now '\0' */ + p = input_line_pointer; + *p = c; + SKIP_WHITESPACE(); + if (* input_line_pointer != ',') { + as_bad("Expected comma after symbol-name"); + ignore_rest_of_line(); + return; + } + input_line_pointer ++; /* skip ',' */ + if ((temp = get_absolute_expression ()) < 0) { + as_bad(".COMMon length (%d.) <0! Ignored.", temp); + ignore_rest_of_line(); + return; + } + *p = 0; + symbolP = symbol_find_or_make(name); + *p = c; + if (S_IS_DEFINED(symbolP)) { + as_bad("Ignoring attempt to re-define symbol"); + ignore_rest_of_line(); + return; + } + if (S_GET_VALUE(symbolP) != 0) { + if (S_GET_VALUE(symbolP) != temp) { + as_warn("Length of .comm \"%s\" is already %d. Not changed to %d.", + S_GET_NAME(symbolP), S_GET_VALUE(symbolP), temp); + } + } else { + S_SET_VALUE(symbolP, temp); + S_SET_EXTERNAL(symbolP); } - } else { - S_SET_VALUE(symbolP, temp); - S_SET_EXTERNAL(symbolP); - } - know(symbolP->sy_frag == &zero_address_frag); - if (strncmp(input_line_pointer, ",\"bss\"", 6) != 0 - && strncmp(input_line_pointer, ",\"data\"", 7) != 0) { - p=input_line_pointer; - while(*p && *p!='\n') - p++; - c= *p; - *p='\0'; - as_bad("bad .common segment: `%s'", input_line_pointer); - *p=c; + know(symbolP->sy_frag == &zero_address_frag); + if (strncmp(input_line_pointer, ",\"bss\"", 6) != 0 + && strncmp(input_line_pointer, ",\"data\"", 7) != 0) { + p=input_line_pointer; + while(*p && *p!='\n') + p++; + c= *p; + *p='\0'; + as_bad("bad .common segment: `%s'", input_line_pointer); + *p=c; + return; + } + input_line_pointer += 6 + (input_line_pointer[2] == 'd'); /* Skip either */ + demand_empty_rest_of_line(); return; - } - input_line_pointer += 6 + (input_line_pointer[2] == 'd'); /* Skip either */ - demand_empty_rest_of_line(); - return; } /* s_common() */ static void s_seg() { if (strncmp(input_line_pointer, "\"text\"", 6) == 0) { - input_line_pointer += 6; - s_text(); - return; + input_line_pointer += 6; + s_text(); + return; } - if (strncmp(input_line_pointer, "\"data\"", 6) == 0) { - input_line_pointer += 6; - s_data(); - return; - } - if (strncmp(input_line_pointer, "\"data1\"", 7) == 0) { - input_line_pointer += 7; - s_data1(); - return; - } - if (strncmp(input_line_pointer, "\"bss\"", 5) == 0) { - input_line_pointer += 5; - /* We only support 2 segments -- text and data -- for now, so - things in the "bss segment" will have to go into data for now. - You can still allocate SEG_BSS stuff with .lcomm or .reserve. */ - subseg_new(SEG_DATA, 255); /* FIXME-SOMEDAY */ + if (strncmp(input_line_pointer, "\"data\"", 6) == 0) { + input_line_pointer += 6; + s_data(); + return; + } + if (strncmp(input_line_pointer, "\"data1\"", 7) == 0) { + input_line_pointer += 7; + s_data1(); + return; + } + if (strncmp(input_line_pointer, "\"bss\"", 5) == 0) { + input_line_pointer += 5; + /* We only support 2 segments -- text and data -- for now, so + things in the "bss segment" will have to go into data for now. + You can still allocate SEG_BSS stuff with .lcomm or .reserve. */ + subseg_new(SEG_DATA, 255); /* FIXME-SOMEDAY */ + return; + } + as_bad("Unknown segment type"); + demand_empty_rest_of_line(); return; - } - as_bad("Unknown segment type"); - demand_empty_rest_of_line(); - return; } /* s_seg() */ static void s_data1() { subseg_new(SEG_DATA, 1); - demand_empty_rest_of_line(); - return; + demand_empty_rest_of_line(); + return; } /* s_data1() */ static void s_proc() { extern char is_end_of_line[]; - - while (!is_end_of_line[*input_line_pointer]) { + + while (!is_end_of_line[*input_line_pointer]) { + ++input_line_pointer; + } ++input_line_pointer; - } - ++input_line_pointer; - return; + return; } /* s_proc() */ +/* start-sanitize-v9 */ +#ifndef NO_V9 +struct priv_reg_entry { char *name; int regnum; }; +struct priv_reg_entry priv_reg_table[] = +{ + { "tpc", 0 }, + { "tnpc", 1 }, + { "tstate", 2 }, + { "tt", 3 }, + { "tick", 4 }, + { "tba", 5 }, + { "pstate", 6 }, + { "tl", 7 }, + { "pil", 8 }, + { "cwp", 9 }, + { "cansave", 10 }, + { "canrestore", 11 }, + { "cleanwin", 12 }, + { "otherwin", 13 }, + { "wstate", 14}, + { "fpq", 15}, + { "ver", 31 }, + { "", -1 }, /* end marker */ +}; + +static int cmp_reg_entry (p, q) + struct priv_reg_entry *p, *q; +{ + return strcmp (q->name, p->name); +} +#endif +/* end-sanitize-v9 */ + /* This function is called once, at assembler startup time. It should set up all the tables, etc. that the MD part of the assembler will need. */ void md_begin() { register char *retval = NULL; - int lose = 0; - register unsigned int i = 0; - - op_hash = hash_new(); - if (op_hash == NULL) - as_fatal("Virtual memory exhausted"); - - while (i < NUMOPCODES) { - const char *name = sparc_opcodes[i].name; - retval = hash_insert(op_hash, name, &sparc_opcodes[i]); - if(retval != NULL && *retval != '\0') { - fprintf (stderr, "internal error: can't hash `%s': %s\n", - sparc_opcodes[i].name, retval); - lose = 1; + int lose = 0; + register unsigned int i = 0; + + op_hash = hash_new(); + if (op_hash == NULL) + as_fatal("Virtual memory exhausted"); + + while (i < NUMOPCODES) { + const char *name = sparc_opcodes[i].name; + retval = hash_insert(op_hash, name, &sparc_opcodes[i]); + if(retval != NULL && *retval != '\0') { + fprintf (stderr, "internal error: can't hash `%s': %s\n", + sparc_opcodes[i].name, retval); + lose = 1; + } + do + { + if (sparc_opcodes[i].match & sparc_opcodes[i].lose) { + fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n", + sparc_opcodes[i].name, sparc_opcodes[i].args); + lose = 1; + } + ++i; + } while (i < NUMOPCODES + && !strcmp(sparc_opcodes[i].name, name)); } - do - { - if (sparc_opcodes[i].match & sparc_opcodes[i].lose) { - fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n", - sparc_opcodes[i].name, sparc_opcodes[i].args); - lose = 1; - } - ++i; - } while (i < NUMOPCODES - && !strcmp(sparc_opcodes[i].name, name)); - } - - if (lose) - as_fatal("Broken assembler. No assembly attempted."); - - for (i = '0'; i < '8'; ++i) - octal[i] = 1; - for (i = '0'; i <= '9'; ++i) - toHex[i] = i - '0'; - for (i = 'a'; i <= 'f'; ++i) - toHex[i] = i + 10 - 'a'; - for (i = 'A'; i <= 'F'; ++i) - toHex[i] = i + 10 - 'A'; + + if (lose) + as_fatal("Broken assembler. No assembly attempted."); + + for (i = '0'; i < '8'; ++i) + octal[i] = 1; + for (i = '0'; i <= '9'; ++i) + toHex[i] = i - '0'; + for (i = 'a'; i <= 'f'; ++i) + toHex[i] = i + 10 - 'a'; + for (i = 'A'; i <= 'F'; ++i) + toHex[i] = i + 10 - 'A'; + +/* start-sanitize-v9 */ +#ifndef NO_V9 + qsort (priv_reg_table, sizeof (priv_reg_table) / sizeof (priv_reg_table[0]), + sizeof (priv_reg_table[0]), cmp_reg_entry); +#endif +/* end-sanitize-v9 */ } /* md_begin() */ void md_end() { @@ -392,827 +432,963 @@ void md_end() { } /* md_end() */ void md_assemble(str) - char *str; +char *str; { - char *toP; - int rsd; - - know(str); - sparc_ip(str); - - /* See if "set" operand is absolute and small; skip sethi if so. */ - if (special_case == SPECIAL_CASE_SET && the_insn.exp.X_seg == SEG_ABSOLUTE) { - if (the_insn.exp.X_add_number >= -(1<<12) - && the_insn.exp.X_add_number < (1<<12)) { - the_insn.opcode = 0x80102000 /* or %g0,imm,... */ - | (the_insn.opcode & 0x3E000000) /* dest reg */ - | (the_insn.exp.X_add_number & 0x1FFF); /* imm */ - special_case = 0; /* No longer special */ - the_insn.reloc = NO_RELOC; /* No longer relocated */ - } - } - - toP = frag_more(4); - /* put out the opcode */ - md_number_to_chars(toP, the_insn.opcode, 4); - - /* put out the symbol-dependent stuff */ - if (the_insn.reloc != NO_RELOC) { - fix_new(frag_now, /* which frag */ - (toP - frag_now->fr_literal), /* where */ - 4, /* size */ - the_insn.exp.X_add_symbol, - the_insn.exp.X_subtract_symbol, - the_insn.exp.X_add_number, - the_insn.pcrel, - the_insn.reloc); - } - switch (special_case) { + char *toP; + int rsd; - case SPECIAL_CASE_SET: - special_case = 0; - assert(the_insn.reloc == RELOC_HI22); - /* See if "set" operand has no low-order bits; skip OR if so. */ - if (the_insn.exp.X_seg == SEG_ABSOLUTE - && ((the_insn.exp.X_add_number & 0x3FF) == 0)) - return; - toP = frag_more(4); - rsd = (the_insn.opcode >> 25) & 0x1f; - the_insn.opcode = 0x80102000 | (rsd << 25) | (rsd << 14); - md_number_to_chars(toP, the_insn.opcode, 4); - fix_new(frag_now, /* which frag */ - (toP - frag_now->fr_literal), /* where */ - 4, /* size */ - the_insn.exp.X_add_symbol, - the_insn.exp.X_subtract_symbol, - the_insn.exp.X_add_number, - the_insn.pcrel, - RELOC_LO10); - return; + know(str); + sparc_ip(str); + + /* See if "set" operand is absolute and small; skip sethi if so. */ + if (special_case == SPECIAL_CASE_SET && the_insn.exp.X_seg == SEG_ABSOLUTE) { + if (the_insn.exp.X_add_number >= -(1<<12) + && the_insn.exp.X_add_number < (1<<12)) { + the_insn.opcode = 0x80102000 /* or %g0,imm,... */ + | (the_insn.opcode & 0x3E000000) /* dest reg */ + | (the_insn.exp.X_add_number & 0x1FFF); /* imm */ + special_case = 0; /* No longer special */ + the_insn.reloc = NO_RELOC; /* No longer relocated */ + } + } - case SPECIAL_CASE_FDIV: - /* According to information leaked from Sun, the "fdiv" instructions - on early SPARC machines would produce incorrect results sometimes. - The workaround is to add an fmovs of the destination register to - itself just after the instruction. This was true on machines - with Weitek 1165 float chips, such as the Sun-4/260 and /280. */ - special_case = 0; - assert(the_insn.reloc == NO_RELOC); toP = frag_more(4); - rsd = (the_insn.opcode >> 25) & 0x1f; - the_insn.opcode = 0x81A00020 | (rsd << 25) | rsd; /* fmovs dest,dest */ + /* put out the opcode */ md_number_to_chars(toP, the_insn.opcode, 4); - return; - case 0: - return; - - default: - as_fatal("failed sanity check."); - } + /* put out the symbol-dependent stuff */ + if (the_insn.reloc != NO_RELOC) { + fix_new(frag_now, /* which frag */ + (toP - frag_now->fr_literal), /* where */ + 4, /* size */ + the_insn.exp.X_add_symbol, + the_insn.exp.X_subtract_symbol, + the_insn.exp.X_add_number, + the_insn.pcrel, + the_insn.reloc); + } + switch (special_case) { + + case SPECIAL_CASE_SET: + special_case = 0; + assert(the_insn.reloc == RELOC_HI22); + /* See if "set" operand has no low-order bits; skip OR if so. */ + if (the_insn.exp.X_seg == SEG_ABSOLUTE + && ((the_insn.exp.X_add_number & 0x3FF) == 0)) + return; + toP = frag_more(4); + rsd = (the_insn.opcode >> 25) & 0x1f; + the_insn.opcode = 0x80102000 | (rsd << 25) | (rsd << 14); + md_number_to_chars(toP, the_insn.opcode, 4); + fix_new(frag_now, /* which frag */ + (toP - frag_now->fr_literal), /* where */ + 4, /* size */ + the_insn.exp.X_add_symbol, + the_insn.exp.X_subtract_symbol, + the_insn.exp.X_add_number, + the_insn.pcrel, + RELOC_LO10); + return; + + case SPECIAL_CASE_FDIV: + /* According to information leaked from Sun, the "fdiv" instructions + on early SPARC machines would produce incorrect results sometimes. + The workaround is to add an fmovs of the destination register to + itself just after the instruction. This was true on machines + with Weitek 1165 float chips, such as the Sun-4/260 and /280. */ + special_case = 0; + assert(the_insn.reloc == NO_RELOC); + toP = frag_more(4); + rsd = (the_insn.opcode >> 25) & 0x1f; + the_insn.opcode = 0x81A00020 | (rsd << 25) | rsd; /* fmovs dest,dest */ + md_number_to_chars(toP, the_insn.opcode, 4); + return; + + case 0: + return; + + default: + as_fatal("failed sanity check."); + } } /* md_assemble() */ static void sparc_ip(str) - char *str; +char *str; { - char *error_message = ""; - char *s; - const char *args; - char c; - struct sparc_opcode *insn; - char *argsStart; - unsigned long opcode; - unsigned int mask = 0; - int match = 0; - int comma = 0; - - for (s = str; islower(*s) || (*s >= '0' && *s <= '3'); ++s) - ; - switch (*s) { - - case '\0': - break; - - case ',': - comma = 1; - - /*FALLTHROUGH */ - - case ' ': - *s++ = '\0'; - break; + char *error_message = ""; + char *s; + const char *args; + char c; + struct sparc_opcode *insn; + char *argsStart; + unsigned long opcode; + unsigned int mask = 0; + int match = 0; + int comma = 0; - default: - as_bad("Unknown opcode: `%s'", str); - exit(1); - } - if ((insn = (struct sparc_opcode *) hash_find(op_hash, str)) == NULL) { - as_bad("Unknown opcode: `%s'", str); - return; - } - if (comma) { - *--s = ','; - } - argsStart = s; - for (;;) { - opcode = insn->match; - memset(&the_insn, '\0', sizeof(the_insn)); - the_insn.reloc = NO_RELOC; - - /* - * Build the opcode, checking as we go to make - * sure that the operands match - */ - for (args = insn->args; ; ++args) { - switch (*args) { + for (s = str; islower(*s) || (*s >= '0' && *s <= '3'); ++s) + ; + switch (*s) { - case 'M': - case 'm': - if (strncmp(s, "%asr", 4) == 0) { - s += 4; - - if (isdigit(*s)) { - long num = 0; - - while (isdigit(*s)) { - num = num*10 + *s-'0'; - ++s; - } - - if (num < 16 || 31 < num) { - error_message = ": asr number must be between 15 and 31"; - goto error; - } /* out of range */ - - opcode |= (*args == 'M' ? RS1(num) : RD(num)); - continue; - } else { - error_message = ": expecting %asrN"; - goto error; - } /* if %asr followed by a number. */ - - } /* if %asr */ - break; - - /* start-sanitize-v9 */ -#ifndef NO_V9 - case 'I': - the_insn.reloc = RELOC_11; - goto immediate; - - case 'k': - the_insn.reloc = RELOC_WDISP2_14; - the_insn.pcrel = 1; - goto immediate; - - case 'G': - the_insn.reloc = RELOC_WDISP19; - the_insn.pcrel = 1; - goto immediate; - - case 'N': - if (*s == 'p' && s[1] == 'n') { - s += 2; - continue; - } - break; - - case 'T': - if (*s == 'p' && s[1] == 't') { - s += 2; - continue; - } - break; - - case 'Y': - if (strncmp(s, "%amr", 4) == 0) { - s += 4; - continue; - } - break; - - case 'z': - if (*s == ' ') { - ++s; - } - if (strncmp(s, "icc", 3) == 0) { - s += 3; - continue; - } - break; - - case 'Z': - if (*s == ' ') { - ++s; - } - if (strncmp(s, "xcc", 3) == 0) { - s += 3; - continue; - } - break; - - case '6': - if (*s == ' ') { - ++s; - } - if (strncmp(s, "fcc0", 4) == 0) { - s += 4; - continue; - } - break; - - case '7': - if (*s == ' ') { - ++s; - } - if (strncmp(s, "fcc1", 4) == 0) { - s += 4; - continue; - } - break; - - case '8': - if (*s == ' ') { - ++s; - } - if (strncmp(s, "fcc2", 4) == 0) { - s += 4; - continue; - } - break; - - case '9': - if (*s == ' ') { - ++s; - } - if (strncmp(s, "fcc3", 4) == 0) { - s += 4; - continue; - } - break; - - case 'P': - if (strncmp(s, "%pc", 3) == 0) { - s += 3; - continue; - } - break; - - case 'E': - if (strncmp(s, "%modes", 6) == 0) { - s += 6; - continue; - } - break; - - case 'W': - if (strncmp(s, "%tick", 5) == 0) { - s += 5; - continue; - } - break; -#endif /* NO_V9 */ - /* end-sanitize-v9 */ - - case '\0': /* end of args */ - if (*s == '\0') { - match = 1; - } + case '\0': break; - case '+': - if (*s == '+') { - ++s; - continue; - } - if (*s == '-') { - continue; - } - break; + case ',': + comma = 1; - case '[': /* these must match exactly */ - case ']': - case ',': - case ' ': - if (*s++ == *args) - continue; - break; - - case '#': /* must be at least one digit */ - if (isdigit(*s++)) { - while (isdigit(*s)) { - ++s; - } - continue; - } - break; + /*FALLTHROUGH */ - case 'C': /* coprocessor state register */ - if (strncmp(s, "%csr", 4) == 0) { - s += 4; - continue; - } + case ' ': + *s++ = '\0'; break; - case 'b': /* next operand is a coprocessor register */ - case 'c': - case 'D': - if (*s++ == '%' && *s++ == 'c' && isdigit(*s)) { - mask = *s++; - if (isdigit(*s)) { - mask = 10 * (mask - '0') + (*s++ - '0'); - if (mask >= 32) { - break; - } - } else { - mask -= '0'; - } - switch (*args) { - - case 'b': - opcode |= mask << 14; - continue; - - case 'c': - opcode |= mask; - continue; - - case 'D': - opcode |= mask << 25; - continue; - } - } - break; + default: + as_bad("Unknown opcode: `%s'", str); + exit(1); + } + if ((insn = (struct sparc_opcode *) hash_find(op_hash, str)) == NULL) { + as_bad("Unknown opcode: `%s'", str); + return; + } + if (comma) { + *--s = ','; + } + argsStart = s; + for (;;) { + opcode = insn->match; + memset(&the_insn, '\0', sizeof(the_insn)); + the_insn.reloc = NO_RELOC; - case 'r': /* next operand must be a register */ - case '1': - case '2': - case 'd': - if (*s++ == '%') { - switch (c = *s++) { - - case 'f': /* frame pointer */ - if (*s++ == 'p') { - mask = 0x1e; - break; - } - goto error; - - case 'g': /* global register */ - if (isoctal(c = *s++)) { - mask = c - '0'; - break; - } - goto error; - - case 'i': /* in register */ - if (isoctal(c = *s++)) { - mask = c - '0' + 24; - break; - } - goto error; - - case 'l': /* local register */ - if (isoctal(c = *s++)) { - mask= (c - '0' + 16) ; - break; - } - goto error; - - case 'o': /* out register */ - if (isoctal(c = *s++)) { - mask= (c - '0' + 8) ; - break; - } - goto error; - - case 's': /* stack pointer */ - if (*s++ == 'p') { - mask= 0xe; - break; - } - goto error; - - case 'r': /* any register */ - if (!isdigit(c = *s++)) { - goto error; - } - /* FALLTHROUGH */ - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - if (isdigit(*s)) { - if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) { + /* + * Build the opcode, checking as we go to make + * sure that the operands match + */ + for (args = insn->args; ; ++args) { + switch (*args) { + + /* start-sanitize-v9 */ +#ifndef NO_V9 + case 'K': + { + /* Load is 0; Store is 1. + We compute the mask based on the values + we find in S. OK is set set + if we see something we don't like. */ + int ok = 1; + int mask = 0; + while (ok == 1) + { + int lo = 0, hi = 0; + if (*s == '#') + { + s += 1; + if (! (lo = (s[0] == 'S'))) + ok = (s[0] == 'L'); + if (! (hi = (s[1] == 'S'))) + ok = (s[1] == 'L'); + mask |= (1 << ((hi<<1) | lo)); + s += 2; + } + else + { + /* Parse a number, somehow. */ + ok = 0; + } + if (s[2] != '|') + break; + } + if (! ok) + { + error_message = "unrecognizable mmask"; goto error; + } + opcode |= SIMM13(mask); + continue; + } + + case '*': + /* Parse a prefetch function. */ + if (*s == '#') + { + int prefetch_fcn = 0; + + s += 1; + if (! strncmp (s, "n_reads", 7)) + prefetch_fcn = 0, s += 7; + else if (! strncmp (s, "one_read", 8)) + prefetch_fcn = 1, s += 8; + else if (! strncmp (s, "n_writes", 8)) + prefetch_fcn = 2, s += 8; + else if (! strncmp (s, "one_write", 9)) + prefetch_fcn = 3, s += 9; + else if (! strncmp (s, "page", 4)) + prefetch_fcn = 4, s += 4; + else + { + error_message = "unrecognizable prefetch fucntion"; + goto error; + } } - } else { - c -= '0'; - } - mask= c; - break; - - default: - goto error; - } - /* - * Got the register, now figure out where - * it goes in the opcode. - */ - switch (*args) { - - case '1': - opcode |= mask << 14; - continue; - - case '2': - opcode |= mask; - continue; - - case 'd': - opcode |= mask << 25; - continue; - - case 'r': - opcode |= (mask << 25) | (mask << 14); - continue; - } - } - break; - - /* start-sanitize-v9 */ + else + { + /* Parse a number, somehow. */ + error_message = "unrecognizable prefetch fucntion"; + goto error; + } + continue; + + case '!': + case '?': + /* Parse a privileged register. */ + if (*s == '%') + { + struct priv_reg_entry *p = priv_reg_table; + int len; + + s += 1; + while (p->name[0] > s[0]) + p++; + while (p->name[0] == s[0]) + { + len = strlen (p->name); + if (strncmp (p->name, s, len) == 0) + break; + p++; + } + if (p->name[0] != s[0]) + { + error_message = "unrecognizable privileged register"; + goto error; + } + if (*args == '?') + opcode |= (p->regnum << 14); + else + opcode |= (p->regnum << 25); + s += len; + continue; + } + else + { + error_message = "unrecognizable privileged register"; + goto error; + } +#endif + /* end-sanitize-v9 */ + + case 'M': + case 'm': + if (strncmp(s, "%asr", 4) == 0) { + s += 4; + + if (isdigit(*s)) { + long num = 0; + + while (isdigit(*s)) { + num = num*10 + *s-'0'; + ++s; + } + + if (num < 16 || 31 < num) { + error_message = ": asr number must be between 15 and 31"; + goto error; + } /* out of range */ + + opcode |= (*args == 'M' ? RS1(num) : RD(num)); + continue; + } else { + error_message = ": expecting %asrN"; + goto error; + } /* if %asr followed by a number. */ + + } /* if %asr */ + break; + + /* start-sanitize-v9 */ #ifndef NO_V9 - case 'j': - case 'u': - case 'U': + case 'I': + the_insn.reloc = RELOC_11; + goto immediate; + + case 'k': + the_insn.reloc = RELOC_WDISP2_14; + the_insn.pcrel = 1; + goto immediate; + + case 'G': + the_insn.reloc = RELOC_WDISP19; + the_insn.pcrel = 1; + goto immediate; + + case 'N': + if (*s == 'p' && s[1] == 'n') { + s += 2; + continue; + } + break; + + case 'T': + if (*s == 'p' && s[1] == 't') { + s += 2; + continue; + } + break; + + case 'Y': + if (strncmp(s, "%amr", 4) == 0) { + s += 4; + continue; + } + break; + + case 'z': + if (*s == ' ') { + ++s; + } + if (strncmp(s, "icc", 3) == 0) { + s += 3; + continue; + } + break; + + case 'Z': + if (*s == ' ') { + ++s; + } + if (strncmp(s, "xcc", 3) == 0) { + s += 3; + continue; + } + break; + + case '6': + if (*s == ' ') { + ++s; + } + if (strncmp(s, "fcc0", 4) == 0) { + s += 4; + continue; + } + break; + + case '7': + if (*s == ' ') { + ++s; + } + if (strncmp(s, "fcc1", 4) == 0) { + s += 4; + continue; + } + break; + + case '8': + if (*s == ' ') { + ++s; + } + if (strncmp(s, "fcc2", 4) == 0) { + s += 4; + continue; + } + break; + + case '9': + if (*s == ' ') { + ++s; + } + if (strncmp(s, "fcc3", 4) == 0) { + s += 4; + continue; + } + break; + + case 'P': + if (strncmp(s, "%pc", 3) == 0) { + s += 3; + continue; + } + break; + + case 'E': + if (strncmp(s, "%modes", 6) == 0) { + s += 6; + continue; + } + break; + + case 'W': + if (strncmp(s, "%tick", 5) == 0) { + s += 5; + continue; + } + break; #endif /* NO_V9 */ - /* end-sanitize-v9 */ - case 'e': /* next operand is a floating point register */ - case 'v': - case 'V': - - case 'f': - case 'B': - case 'R': - - case 'g': - case 'H': - case 'J': { - char format; - - if (*s++ == '%' - - /* start-sanitize-v9 */ + /* end-sanitize-v9 */ + + case '\0': /* end of args */ + if (*s == '\0') { + match = 1; + } + break; + + case '+': + if (*s == '+') { + ++s; + continue; + } + if (*s == '-') { + continue; + } + break; + + case '[': /* these must match exactly */ + case ']': + case ',': + case ' ': + if (*s++ == *args) + continue; + break; + + case '#': /* must be at least one digit */ + if (isdigit(*s++)) { + while (isdigit(*s)) { + ++s; + } + continue; + } + break; + + case 'C': /* coprocessor state register */ + if (strncmp(s, "%csr", 4) == 0) { + s += 4; + continue; + } + break; + + case 'b': /* next operand is a coprocessor register */ + case 'c': + case 'D': + if (*s++ == '%' && *s++ == 'c' && isdigit(*s)) { + mask = *s++; + if (isdigit(*s)) { + mask = 10 * (mask - '0') + (*s++ - '0'); + if (mask >= 32) { + break; + } + } else { + mask -= '0'; + } + switch (*args) { + + case 'b': + opcode |= mask << 14; + continue; + + case 'c': + opcode |= mask; + continue; + + case 'D': + opcode |= mask << 25; + continue; + } + } + break; + + case 'r': /* next operand must be a register */ + case '1': + case '2': + case 'd': + if (*s++ == '%') { + switch (c = *s++) { + + case 'f': /* frame pointer */ + if (*s++ == 'p') { + mask = 0x1e; + break; + } + goto error; + + case 'g': /* global register */ + if (isoctal(c = *s++)) { + mask = c - '0'; + break; + } + goto error; + + case 'i': /* in register */ + if (isoctal(c = *s++)) { + mask = c - '0' + 24; + break; + } + goto error; + + case 'l': /* local register */ + if (isoctal(c = *s++)) { + mask= (c - '0' + 16) ; + break; + } + goto error; + + case 'o': /* out register */ + if (isoctal(c = *s++)) { + mask= (c - '0' + 8) ; + break; + } + goto error; + + case 's': /* stack pointer */ + if (*s++ == 'p') { + mask= 0xe; + break; + } + goto error; + + case 'r': /* any register */ + if (!isdigit(c = *s++)) { + goto error; + } + /* FALLTHROUGH */ + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (isdigit(*s)) { + if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) { + goto error; + } + } else { + c -= '0'; + } + mask= c; + break; + + default: + goto error; + } + /* + * Got the register, now figure out where + * it goes in the opcode. + */ + switch (*args) { + + case '1': + opcode |= mask << 14; + continue; + + case '2': + opcode |= mask; + continue; + + case 'd': + opcode |= mask << 25; + continue; + + case 'r': + opcode |= (mask << 25) | (mask << 14); + continue; + } + } + break; + + /* start-sanitize-v9 */ +#ifndef NO_V9 + case 'j': + case 'u': + case 'U': +#endif /* NO_V9 */ + /* end-sanitize-v9 */ + case 'e': /* next operand is a floating point register */ + case 'v': + case 'V': + + case 'f': + case 'B': + case 'R': + + case 'g': + case 'H': + case 'J': { + char format; + + if (*s++ == '%' + + /* start-sanitize-v9 */ #ifndef NO_V9 - && ((format = *s) == 'f' - || *s == 'd' - || *s == 'q') + && ((format = *s) == 'f' + || *s == 'd' + || *s == 'q') #else - /* end-sanitize-v9 */ - && ((format = *s) == 'f') - - /* start-sanitize-v9 */ + /* end-sanitize-v9 */ + && ((format = *s) == 'f') + + /* start-sanitize-v9 */ #endif /* NO_V9 */ - /* end-sanitize-v9 */ - && isdigit(*++s)) { - - - - for (mask = 0; isdigit(*s); ++s) { - mask = 10 * mask + (*s - '0'); - } /* read the number */ - - if ((*args == 'u' - || *args == 'v' - || *args == 'B' - || *args == 'H') - && (mask & 1)) { - break; - } /* register must be even numbered */ - - if ((*args == 'U' - || *args == 'V' - || *args == 'R' - || *args == 'J') - && (mask & 3)) { - break; - } /* register must be multiple of 4 */ - - if (format == 'f') { - if (mask >= 32) { - error_message = ": There are only 32 f registers; [0-31]"; - goto error; - } /* on error */ - /* start-sanitize-v9 */ + /* end-sanitize-v9 */ + && isdigit(*++s)) { + + + + for (mask = 0; isdigit(*s); ++s) { + mask = 10 * mask + (*s - '0'); + } /* read the number */ + + if ((*args == 'u' + || *args == 'v' + || *args == 'B' + || *args == 'H') + && (mask & 1)) { + break; + } /* register must be even numbered */ + + if ((*args == 'U' + || *args == 'V' + || *args == 'R' + || *args == 'J') + && (mask & 3)) { + break; + } /* register must be multiple of 4 */ + + if (format == 'f') { + if (mask >= 32) { + error_message = ": There are only 32 f registers; [0-31]"; + goto error; + } /* on error */ + /* start-sanitize-v9 */ #ifndef NO_V9 - } else { - if (format == 'd') { - if (mask >= 64) { - error_message = ": There are only 32 d registers [0, 2, ... 62]."; - goto error; - } else if (mask & 1) { - error_message = ": Only even numbered d registers exist."; - goto error; - } /* on error */ - - } else if (format == 'q') { - if (mask >= 64) { - error_message = - ": There are only 16 q registers [0, 4, ... 60]."; - goto error; - } else if (mask & 3) { - error_message = - ": Only q registers evenly divisible by four exist."; - goto error; - } /* on error */ - } else { - know(0); - } /* depending on format */ - - if (mask >= 32) { - mask -= 31; - } /* wrap high bit */ + } else { + if (format == 'd') { + if (mask >= 64) { + error_message = ": There are only 32 d registers [0, 2, ... 62]."; + goto error; + } else if (mask & 1) { + error_message = ": Only even numbered d registers exist."; + goto error; + } /* on error */ + + } else if (format == 'q') { + if (mask >= 64) { + error_message = + ": There are only 16 q registers [0, 4, ... 60]."; + goto error; + } else if (mask & 3) { + error_message = + ": Only q registers evenly divisible by four exist."; + goto error; + } /* on error */ + } else { + know(0); + } /* depending on format */ + + if (mask >= 32) { + mask -= 31; + } /* wrap high bit */ #endif /* NO_V9 */ - /* end-sanitize-v9 */ - } /* if not an 'f' register. */ - } /* on error */ - - switch (*args) { - /* start-sanitize-v9 */ + /* end-sanitize-v9 */ + } /* if not an 'f' register. */ + } /* on error */ + + switch (*args) { + /* start-sanitize-v9 */ #ifndef NO_V9 - case 'j': - case 'u': - case 'U': - opcode |= (mask & 0x1f) << 9; - continue; + case 'j': + case 'u': + case 'U': + opcode |= (mask & 0x1f) << 9; + continue; #endif /* NO_V9 */ - /* end-sanitize-v9 */ - - case 'v': - case 'V': - case 'e': - opcode |= RS1(mask); - continue; - - - case 'f': - case 'B': - case 'R': - opcode |= RS2(mask); - continue; - - case 'g': - case 'H': - case 'J': - opcode |= RD(mask); - continue; - } /* pack it in. */ - - know(0); - break; - } /* float arg */ - - case 'F': - if (strncmp(s, "%fsr", 4) == 0) { - s += 4; - continue; - } - break; - - case 'h': /* high 22 bits */ - the_insn.reloc = RELOC_HI22; - goto immediate; - - case 'l': /* 22 bit PC relative immediate */ - the_insn.reloc = RELOC_WDISP22; - the_insn.pcrel = 1; - goto immediate; - - case 'L': /* 30 bit immediate */ - the_insn.reloc = RELOC_WDISP30; - the_insn.pcrel = 1; - goto immediate; - - case 'n': /* 22 bit immediate */ - the_insn.reloc = RELOC_22; - goto immediate; - - case 'i': /* 13 bit immediate */ - the_insn.reloc = RELOC_BASE13; - - /*FALLTHROUGH */ - - immediate: - if(*s==' ') - s++; - if (*s == '%') { - if ((c = s[1]) == 'h' && s[2] == 'i') { - the_insn.reloc = RELOC_HI22; - s+=3; - } else if (c == 'l' && s[2] == 'o') { - the_insn.reloc = RELOC_LO10; - s+=3; - /* start-sanitize-v9 */ + /* end-sanitize-v9 */ + + case 'v': + case 'V': + case 'e': + opcode |= RS1(mask); + continue; + + + case 'f': + case 'B': + case 'R': + opcode |= RS2(mask); + continue; + + case 'g': + case 'H': + case 'J': + opcode |= RD(mask); + continue; + } /* pack it in. */ + + know(0); + break; + } /* float arg */ + + case 'F': + if (strncmp(s, "%fsr", 4) == 0) { + s += 4; + continue; + } + break; + + case 'h': /* high 22 bits */ + the_insn.reloc = RELOC_HI22; + goto immediate; + + case 'l': /* 22 bit PC relative immediate */ + the_insn.reloc = RELOC_WDISP22; + the_insn.pcrel = 1; + goto immediate; + + case 'L': /* 30 bit immediate */ + the_insn.reloc = RELOC_WDISP30; + the_insn.pcrel = 1; + goto immediate; + + case 'n': /* 22 bit immediate */ + the_insn.reloc = RELOC_22; + goto immediate; + + case 'i': /* 13 bit immediate */ + the_insn.reloc = RELOC_BASE13; + + /*FALLTHROUGH */ + + immediate: + if(*s==' ') + s++; + if (*s == '%') { + if ((c = s[1]) == 'h' && s[2] == 'i') { + the_insn.reloc = RELOC_HI22; + s+=3; + } else if (c == 'l' && s[2] == 'o') { + the_insn.reloc = RELOC_LO10; + s+=3; + /* start-sanitize-v9 */ #ifndef NO_V9 - } else if (c == 'h' - && s[2] == 'h' - && s[3] == 'i') { - the_insn.reloc = RELOC_HHI22; - s += 4; - - } else if (c == 'h' - && s[2] == 'l' - && s[3] == 'o') { - the_insn.reloc = RELOC_HLO10; - s += 4; + } else if (c == 'h' + && s[2] == 'h' + && s[3] == 'i') { + the_insn.reloc = RELOC_HHI22; + s += 4; + + } else if (c == 'h' + && s[2] == 'l' + && s[3] == 'o') { + the_insn.reloc = RELOC_HLO10; + s += 4; #endif /* NO_V9 */ - /* end-sanitize-v9 */ - } else + /* end-sanitize-v9 */ + } else + break; + } + /* Note that if the getExpression() fails, we + will still have created U entries in the + symbol table for the 'symbols' in the input + string. Try not to create U symbols for + registers, etc. */ + { + /* This stuff checks to see if the + expression ends in +%reg If it does, + it removes the register from the + expression, and re-sets 's' to point + to the right place */ + + char *s1; + + for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++) ;; + + if (s1 != s && isdigit(s1[-1])) { + if(s1[-2] == '%' && s1[-3] == '+') { + s1 -= 3; + *s1 = '\0'; + (void) getExpression(s); + *s1 = '+'; + s = s1; + continue; + } else if (strchr("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+') { + s1 -= 4; + *s1 = '\0'; + (void) getExpression(s); + *s1 = '+'; + s = s1; + continue; + } + } + } + (void)getExpression(s); + s = expr_end; + continue; + + case 'a': + if (*s++ == 'a') { + opcode |= ANNUL; + continue; + } + break; + + case 'A': { + char *push = input_line_pointer; + expressionS e; + + input_line_pointer = s; + + if (expression(&e) == SEG_ABSOLUTE) { + opcode |= e.X_add_number << 5; + s = input_line_pointer; + input_line_pointer = push; + continue; + } /* if absolute */ + + break; + } /* alternate space */ + + case 'p': + if (strncmp(s, "%psr", 4) == 0) { + s += 4; + continue; + } + break; + + case 'q': /* floating point queue */ + if (strncmp(s, "%fq", 3) == 0) { + s += 3; + continue; + } + break; + + case 'Q': /* coprocessor queue */ + if (strncmp(s, "%cq", 3) == 0) { + s += 3; + continue; + } + break; + + case 'S': + if (strcmp(str, "set") == 0) { + special_case = SPECIAL_CASE_SET; + continue; + } else if (strncmp(str, "fdiv", 4) == 0) { + special_case = SPECIAL_CASE_FDIV; + continue; + } + break; + +/* start-sanitize-v9 */ +#ifndef NO_V9 + case 's': + if (strncmp (s, "%usr", 4) != 0) + break; + s += 4; + continue; + + case 'o': + if (strncmp (s, "%asi", 4) != 0) + break; + s += 4; + continue; +#endif /* NO_V9 */ + /* end-sanitize-v9 */ + + case 't': + if (strncmp(s, "%tbr", 4) != 0) + break; + s += 4; + continue; + + case 'w': + if (strncmp(s, "%wim", 4) != 0) + break; + s += 4; + continue; + + case 'y': + if (strncmp(s, "%y", 2) != 0) + break; + s += 2; + continue; + + default: + as_fatal("failed sanity check."); + } /* switch on arg code */ break; - } - /* Note that if the getExpression() fails, we - will still have created U entries in the - symbol table for the 'symbols' in the input - string. Try not to create U symbols for - registers, etc. */ - { - /* This stuff checks to see if the - expression ends in +%reg If it does, - it removes the register from the - expression, and re-sets 's' to point - to the right place */ - - char *s1; - - for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++) ;; - - if (s1 != s && isdigit(s1[-1])) { - if(s1[-2] == '%' && s1[-3] == '+') { - s1 -= 3; - *s1 = '\0'; - (void) getExpression(s); - *s1 = '+'; - s = s1; - continue; - } else if (strchr("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+') { - s1 -= 4; - *s1 = '\0'; - (void) getExpression(s); - *s1 = '+'; - s = s1; - continue; - } - } - } - (void)getExpression(s); - s = expr_end; - continue; - - case 'a': - if (*s++ == 'a') { - opcode |= ANNUL; - continue; - } - break; - - case 'A': { - char *push = input_line_pointer; - expressionS e; - - input_line_pointer = s; - - if (expression(&e) == SEG_ABSOLUTE) { - opcode |= e.X_add_number << 5; - s = input_line_pointer; - input_line_pointer = push; - continue; - } /* if absolute */ - - break; - } /* alternate space */ - - case 'p': - if (strncmp(s, "%psr", 4) == 0) { - s += 4; - continue; - } - break; - - case 'q': /* floating point queue */ - if (strncmp(s, "%fq", 3) == 0) { - s += 3; - continue; - } - break; - - case 'Q': /* coprocessor queue */ - if (strncmp(s, "%cq", 3) == 0) { - s += 3; - continue; - } - break; + } /* for each arg that we expect */ + error: + if (match == 0) { + /* Args don't match. */ + if (((unsigned) (&insn[1] - sparc_opcodes)) < NUMOPCODES + && !strcmp(insn->name, insn[1].name)) { + ++insn; + s = argsStart; + continue; + } else { + as_bad("Illegal operands%s", error_message); + return; + } + } else { + if (insn->architecture > current_architecture) { + if ((!architecture_requested || warn_on_bump) + && +/* start-sanitize-v9 */ +#ifndef NO_V9 + ! ARCHITECTURES_CONFLICT_P (current_architecture, + insn->architecture) +#else +/* end-sanitize-v9 */ + 1 +/* start-sanitize-v9 */ +#endif +/* end-sanitize-v9 */ + ) { + if (warn_on_bump) { + as_warn("architecture bumped from \"%s\" to \"%s\" on \"%s\"", + architecture_pname[current_architecture], + architecture_pname[insn->architecture], + str); + } /* if warning */ + + current_architecture = insn->architecture; + } else { + as_bad("architecture mismatch on \"%s\" (\"%s\"). current architecture is \"%s\"", + str, + architecture_pname[insn->architecture], + architecture_pname[current_architecture]); + return; + } /* if bump ok else error */ + } /* if architecture higher */ + } /* if no match */ - case 'S': - if (strcmp(str, "set") == 0) { - special_case = SPECIAL_CASE_SET; - continue; - } else if (strncmp(str, "fdiv", 4) == 0) { - special_case = SPECIAL_CASE_FDIV; - continue; - } break; - - case 't': - if (strncmp(s, "%tbr", 4) != 0) - break; - s += 4; - continue; - - case 'w': - if (strncmp(s, "%wim", 4) != 0) - break; - s += 4; - continue; - - case 'y': - if (strncmp(s, "%y", 2) != 0) - break; - s += 2; - continue; - - default: - as_fatal("failed sanity check."); - } /* switch on arg code */ - break; - } /* for each arg that we expect */ - error: - if (match == 0) { - /* Args don't match. */ - if (((unsigned) (&insn[1] - sparc_opcodes)) < NUMOPCODES - && !strcmp(insn->name, insn[1].name)) { - ++insn; - s = argsStart; - continue; - } else { - as_bad("Illegal operands%s", error_message); - return; - } - } else { - if (insn->architecture > current_architecture) { - if (!architecture_requested || warn_on_bump) { - - if (warn_on_bump) { - as_warn("architecture bumped from \"%s\" to \"%s\" on \"%s\"", - architecture_pname[current_architecture], - architecture_pname[insn->architecture], - str); - } /* if warning */ - - current_architecture = insn->architecture; - } else { - as_bad("architecture mismatch on \"%s\" (\"%s\"). current architecture is \"%s\"", - str, - architecture_pname[insn->architecture], - architecture_pname[current_architecture]); - return; - } /* if bump ok else error */ - } /* if architecture higher */ - } /* if no match */ + } /* forever looking for a match */ - break; - } /* forever looking for a match */ - - the_insn.opcode = opcode; - return; + the_insn.opcode = opcode; + return; } /* sparc_ip() */ static int getExpression(str) - char *str; +char *str; { - char *save_in; - segT seg; - - save_in = input_line_pointer; - input_line_pointer = str; - switch (seg = expression(&the_insn.exp)) { - - case SEG_ABSOLUTE: - case SEG_TEXT: - case SEG_DATA: - case SEG_BSS: - case SEG_UNKNOWN: - case SEG_DIFFERENCE: - case SEG_BIG: - case SEG_ABSENT: - break; + char *save_in; + segT seg; - default: - the_insn.error = "bad segment"; + save_in = input_line_pointer; + input_line_pointer = str; + switch (seg = expression(&the_insn.exp)) { + + case SEG_ABSOLUTE: + case SEG_TEXT: + case SEG_DATA: + case SEG_BSS: + case SEG_UNKNOWN: + case SEG_DIFFERENCE: + case SEG_BIG: + case SEG_ABSENT: + break; + + default: + the_insn.error = "bad segment"; + expr_end = input_line_pointer; + input_line_pointer=save_in; + return 1; + } expr_end = input_line_pointer; - input_line_pointer=save_in; - return 1; - } - expr_end = input_line_pointer; - input_line_pointer = save_in; - return 0; + input_line_pointer = save_in; + return 0; } /* getExpression() */ @@ -1229,259 +1405,259 @@ static int getExpression(str) #define MAX_LITTLENUMS 6 char *md_atof(type,litP,sizeP) - char type; - char *litP; - int *sizeP; +char type; +char *litP; +int *sizeP; { - int prec; - LITTLENUM_TYPE words[MAX_LITTLENUMS]; - LITTLENUM_TYPE *wordP; - char *t; - char *atof_ieee(); - - switch(type) { - - case 'f': - case 'F': - case 's': - case 'S': - prec = 2; - break; + int prec; + LITTLENUM_TYPE words[MAX_LITTLENUMS]; + LITTLENUM_TYPE *wordP; + char *t; + char *atof_ieee(); - case 'd': - case 'D': - case 'r': - case 'R': - prec = 4; - break; - - case 'x': - case 'X': - prec = 6; - break; - - case 'p': - case 'P': - prec = 6; - break; - - default: - *sizeP=0; - return "Bad call to MD_ATOF()"; - } - t=atof_ieee(input_line_pointer,type,words); - if(t) - input_line_pointer=t; - *sizeP=prec * sizeof(LITTLENUM_TYPE); - for(wordP=words;prec--;) { - md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE)); - litP+=sizeof(LITTLENUM_TYPE); - } - return ""; /* Someone should teach Dean about null pointers */ + switch(type) { + + case 'f': + case 'F': + case 's': + case 'S': + prec = 2; + break; + + case 'd': + case 'D': + case 'r': + case 'R': + prec = 4; + break; + + case 'x': + case 'X': + prec = 6; + break; + + case 'p': + case 'P': + prec = 6; + break; + + default: + *sizeP=0; + return "Bad call to MD_ATOF()"; + } + t=atof_ieee(input_line_pointer,type,words); + if(t) + input_line_pointer=t; + *sizeP=prec * sizeof(LITTLENUM_TYPE); + for(wordP=words;prec--;) { + md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE)); + litP+=sizeof(LITTLENUM_TYPE); + } + return ""; /* Someone should teach Dean about null pointers */ } /* md_atof() */ /* * Write out big-endian. */ void md_number_to_chars(buf,val,n) - char *buf; - long val; - int n; +char *buf; +long val; +int n; { - - switch(n) { - - case 4: - *buf++ = val >> 24; - *buf++ = val >> 16; - case 2: - *buf++ = val >> 8; - case 1: - *buf = val; - break; - default: - as_fatal("failed sanity check."); - } - return; + switch(n) { + + case 4: + *buf++ = val >> 24; + *buf++ = val >> 16; + case 2: + *buf++ = val >> 8; + case 1: + *buf = val; + break; + + default: + as_fatal("failed sanity check."); + } + return; } /* md_number_to_chars() */ /* Apply a fixS to the frags, now that we know the value it ought to hold. */ void md_apply_fix(fixP, val) - fixS *fixP; - long val; +fixS *fixP; +long val; { - char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; - - assert(fixP->fx_size == 4); - assert(fixP->fx_r_type < NO_RELOC); - - fixP->fx_addnumber = val; /* Remember value for emit_reloc */ - - /* - * This is a hack. There should be a better way to - * handle this. - */ - if (fixP->fx_r_type == RELOC_WDISP30 && fixP->fx_addsy) { - val += fixP->fx_where + fixP->fx_frag->fr_address; - } - - switch (fixP->fx_r_type) { + char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; + + assert(fixP->fx_size == 4); + assert(fixP->fx_r_type < NO_RELOC); - case RELOC_32: - buf[0] = 0; /* val >> 24; */ - buf[1] = 0; /* val >> 16; */ - buf[2] = 0; /* val >> 8; */ - buf[3] = 0; /* val; */ - break; + fixP->fx_addnumber = val; /* Remember value for emit_reloc */ + /* + * This is a hack. There should be a better way to + * handle this. + */ + if (fixP->fx_r_type == RELOC_WDISP30 && fixP->fx_addsy) { + val += fixP->fx_where + fixP->fx_frag->fr_address; + } + + switch (fixP->fx_r_type) { + + case RELOC_32: + buf[0] = 0; /* val >> 24; */ + buf[1] = 0; /* val >> 16; */ + buf[2] = 0; /* val >> 8; */ + buf[3] = 0; /* val; */ + break; + #if 0 - case RELOC_8: /* These don't seem to ever be needed. */ - case RELOC_16: - case RELOC_DISP8: - case RELOC_DISP16: - case RELOC_DISP32: + case RELOC_8: /* These don't seem to ever be needed. */ + case RELOC_16: + case RELOC_DISP8: + case RELOC_DISP16: + case RELOC_DISP32: #endif - case RELOC_WDISP30: - val = (val >>= 2) + 1; - buf[0] |= (val >> 24) & 0x3f; - buf[1]= (val >> 16); - buf[2] = val >> 8; - buf[3] = val; - break; - - /* start-sanitize-v9 */ + case RELOC_WDISP30: + val = (val >>= 2) + 1; + buf[0] |= (val >> 24) & 0x3f; + buf[1]= (val >> 16); + buf[2] = val >> 8; + buf[3] = val; + break; + + /* start-sanitize-v9 */ #ifndef NO_V9 - case RELOC_11: - if (((val > 0) && (val & ~0x7ff)) - || ((val < 0) && (~(val - 1) & ~0x7ff))) { - as_bad("relocation overflow."); - } /* on overflow */ - - buf[2] = (val >> 8) & 0x7; - buf[3] = val & 0xff; - break; - - case RELOC_WDISP2_14: - if (((val > 0) && (val & ~0x3fffc)) - || ((val < 0) && (~(val - 1) & ~0x3fffc))) { - as_bad("relocation overflow."); - } /* on overflow */ - - val = (val >>= 2) + 1; - buf[1] |= ((val >> 14) & 0x3) << 3; - buf[2] |= (val >> 8) & 0x3f ; - buf[3] = val & 0xff; - break; - - case RELOC_WDISP19: - if (((val > 0) && (val & ~0x1ffffc)) - || ((val < 0) && (~(val - 1) & ~0x1ffffc))) { - as_bad("relocation overflow."); - } /* on overflow */ - - val = (val >>= 2) + 1; - buf[1] |= (val >> 16) & 0x7; - buf[2] = (val >> 8) & 0xff; - buf[3] = val & 0xff; - break; - - case RELOC_HHI22: - val >>= 32; - /* intentional fallthrough */ + case RELOC_11: + if (((val > 0) && (val & ~0x7ff)) + || ((val < 0) && (~(val - 1) & ~0x7ff))) { + as_bad("relocation overflow."); + } /* on overflow */ + + buf[2] = (val >> 8) & 0x7; + buf[3] = val & 0xff; + break; + + case RELOC_WDISP2_14: + if (((val > 0) && (val & ~0x3fffc)) + || ((val < 0) && (~(val - 1) & ~0x3fffc))) { + as_bad("relocation overflow."); + } /* on overflow */ + + val = (val >>= 2) + 1; + buf[1] |= ((val >> 14) & 0x3) << 3; + buf[2] |= (val >> 8) & 0x3f ; + buf[3] = val & 0xff; + break; + + case RELOC_WDISP19: + if (((val > 0) && (val & ~0x1ffffc)) + || ((val < 0) && (~(val - 1) & ~0x1ffffc))) { + as_bad("relocation overflow."); + } /* on overflow */ + + val = (val >>= 2) + 1; + buf[1] |= (val >> 16) & 0x7; + buf[2] = (val >> 8) & 0xff; + buf[3] = val & 0xff; + break; + + case RELOC_HHI22: + val >>= 32; + /* intentional fallthrough */ #endif /* NO_V9 */ - /* end-sanitize-v9 */ - - case RELOC_HI22: - if(!fixP->fx_addsy) { - buf[1] |= (val >> 26) & 0x3f; - buf[2] = val >> 18; - buf[3] = val >> 10; - } else { - buf[2]=0; - buf[3]=0; - } - break; - - case RELOC_22: - if (val & ~0x003fffff) { - as_bad("relocation overflow"); - } /* on overflow */ - buf[1] |= (val >> 16) & 0x3f; - buf[2] = val >> 8; - buf[3] = val & 0xff; - break; - - case RELOC_13: - if (val & ~0x00001fff) { - as_bad("relocation overflow"); - } /* on overflow */ - buf[2] = (val >> 8) & 0x1f; - buf[3] = val & 0xff; - break; - - /* start-sanitize-v9 */ + /* end-sanitize-v9 */ + + case RELOC_HI22: + if(!fixP->fx_addsy) { + buf[1] |= (val >> 26) & 0x3f; + buf[2] = val >> 18; + buf[3] = val >> 10; + } else { + buf[2]=0; + buf[3]=0; + } + break; + + case RELOC_22: + if (val & ~0x003fffff) { + as_bad("relocation overflow"); + } /* on overflow */ + buf[1] |= (val >> 16) & 0x3f; + buf[2] = val >> 8; + buf[3] = val & 0xff; + break; + + case RELOC_13: + if (val & ~0x00001fff) { + as_bad("relocation overflow"); + } /* on overflow */ + buf[2] = (val >> 8) & 0x1f; + buf[3] = val & 0xff; + break; + + /* start-sanitize-v9 */ #ifndef NO_V9 - case RELOC_HLO10: - val >>= 32; - /* intentional fallthrough */ + case RELOC_HLO10: + val >>= 32; + /* intentional fallthrough */ #endif /* NO_V9 */ - /* end-sanitize-v9 */ - - case RELOC_LO10: - if(!fixP->fx_addsy) { - buf[2] |= (val >> 8) & 0x03; - buf[3] = val; - } else - buf[3]=0; - break; + /* end-sanitize-v9 */ + + case RELOC_LO10: + if(!fixP->fx_addsy) { + buf[2] |= (val >> 8) & 0x03; + buf[3] = val; + } else + buf[3]=0; + break; #if 0 - case RELOC_SFA_BASE: - case RELOC_SFA_OFF13: - case RELOC_BASE10: + case RELOC_SFA_BASE: + case RELOC_SFA_OFF13: + case RELOC_BASE10: #endif - case RELOC_BASE13: - buf[2] |= (val >> 8) & 0x1f; - buf[3] = val; - break; - - case RELOC_WDISP22: - val = (val >>= 2) + 1; - /* FALLTHROUGH */ - case RELOC_BASE22: - buf[1] |= (val >> 16) & 0x3f; - buf[2] = val >> 8; - buf[3] = val; - break; - + case RELOC_BASE13: + buf[2] |= (val >> 8) & 0x1f; + buf[3] = val; + break; + + case RELOC_WDISP22: + val = (val >>= 2) + 1; + /* FALLTHROUGH */ + case RELOC_BASE22: + buf[1] |= (val >> 16) & 0x3f; + buf[2] = val >> 8; + buf[3] = val; + break; + #if 0 - case RELOC_PC10: - case RELOC_PC22: - case RELOC_JMP_TBL: - case RELOC_SEGOFF16: - case RELOC_GLOB_DAT: - case RELOC_JMP_SLOT: - case RELOC_RELATIVE: + case RELOC_PC10: + case RELOC_PC22: + case RELOC_JMP_TBL: + case RELOC_SEGOFF16: + case RELOC_GLOB_DAT: + case RELOC_JMP_SLOT: + case RELOC_RELATIVE: #endif - - case NO_RELOC: - default: - as_bad("bad relocation type: 0x%02x", fixP->fx_r_type); - break; - } + + case NO_RELOC: + default: + as_bad("bad relocation type: 0x%02x", fixP->fx_r_type); + break; + } } /* md_apply_fix() */ /* should never be called for sparc */ void md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol) - char *ptr; - long from_addr; - long to_addr; - fragS *frag; - symbolS *to_symbol; +char *ptr; +long from_addr; +long to_addr; +fragS *frag; +symbolS *to_symbol; { - as_fatal("sparc_create_short_jmp\n"); + as_fatal("sparc_create_short_jmp\n"); } /* md_create_short_jump() */ /* Translate internal representation of relocation info to target format. @@ -1491,136 +1667,137 @@ void md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol) bit 7 as external, bits 6 & 5 unused, and the lower five bits as relocation type. Next 4 bytes are long addend. */ /* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */ -void tc_aout_fix_to_chars(where, fixP, segment_address_in_file) - char *where; - fixS *fixP; - relax_addressT segment_address_in_file; +void +tc_aout_fix_to_chars(where, fixP, segment_address_in_file) + char *where; + fixS *fixP; + relax_addressT segment_address_in_file; { - long r_index; - long r_extern; - long r_addend = 0; - long r_address; - - know(fixP->fx_addsy); - - if ((S_GET_TYPE(fixP->fx_addsy)) == N_UNDF) { - r_extern = 1; - r_index = fixP->fx_addsy->sy_number; - } else { - r_extern = 0; - r_index = S_GET_TYPE(fixP->fx_addsy); - } - - /* this is easy */ - md_number_to_chars(where, - r_address = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, - 4); - - /* now the fun stuff */ - where[4] = (r_index >> 16) & 0x0ff; - where[5] = (r_index >> 8) & 0x0ff; - where[6] = r_index & 0x0ff; - where[7] = ((r_extern << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F); - - /* Also easy */ - if (fixP->fx_addsy->sy_frag) { - r_addend = fixP->fx_addsy->sy_frag->fr_address; - } - - if (fixP->fx_pcrel) { - r_addend -= r_address; - } else { - r_addend = fixP->fx_addnumber; - } - - md_number_to_chars(&where[8], r_addend, 4); - - return; + long r_index; + long r_extern; + long r_addend = 0; + long r_address; + + know(fixP->fx_addsy); + + if (!S_IS_DEFINED(fixP->fx_addsy)) { + r_extern = 1; + r_index = fixP->fx_addsy->sy_number; + } else { + r_extern = 0; + r_index = S_GET_TYPE(fixP->fx_addsy); + } + + /* this is easy */ + md_number_to_chars(where, + r_address = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, + 4); + + /* now the fun stuff */ + where[4] = (r_index >> 16) & 0x0ff; + where[5] = (r_index >> 8) & 0x0ff; + where[6] = r_index & 0x0ff; + where[7] = ((r_extern << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F); + + /* Also easy */ + if (fixP->fx_addsy->sy_frag) { + r_addend = fixP->fx_addsy->sy_frag->fr_address; + } + + if (fixP->fx_pcrel) { + r_addend += fixP->fx_offset - r_address; + } else { + r_addend = fixP->fx_addnumber; + } + + md_number_to_chars(&where[8], r_addend, 4); + + return; } /* tc_aout_fix_to_chars() */ /* should never be called for sparc */ void md_convert_frag(headers, fragP) - object_headers *headers; - register fragS *fragP; +object_headers *headers; +register fragS *fragP; { - as_fatal("sparc_convert_frag\n"); + as_fatal("sparc_convert_frag\n"); } /* md_convert_frag() */ /* should never be called for sparc */ void md_create_long_jump(ptr, from_addr, to_addr, frag, to_symbol) - char *ptr; - long from_addr, to_addr; - fragS *frag; - symbolS *to_symbol; +char *ptr; +long from_addr, to_addr; +fragS *frag; +symbolS *to_symbol; { - as_fatal("sparc_create_long_jump\n"); + as_fatal("sparc_create_long_jump\n"); } /* md_create_long_jump() */ /* should never be called for sparc */ int md_estimate_size_before_relax(fragP, segtype) - fragS *fragP; - segT segtype; +fragS *fragP; +segT segtype; { - as_fatal("sparc_estimate_size_before_relax\n"); - return(1); + as_fatal("sparc_estimate_size_before_relax\n"); + return(1); } /* md_estimate_size_before_relax() */ #if 0 /* for debugging only */ static void print_insn(insn) - struct sparc_it *insn; +struct sparc_it *insn; { - char *Reloc[] = { - "RELOC_8", - "RELOC_16", - "RELOC_32", - "RELOC_DISP8", - "RELOC_DISP16", - "RELOC_DISP32", - "RELOC_WDISP30", - "RELOC_WDISP22", - "RELOC_HI22", - "RELOC_22", - "RELOC_13", - "RELOC_LO10", - "RELOC_SFA_BASE", - "RELOC_SFA_OFF13", - "RELOC_BASE10", - "RELOC_BASE13", - "RELOC_BASE22", - "RELOC_PC10", - "RELOC_PC22", - "RELOC_JMP_TBL", - "RELOC_SEGOFF16", - "RELOC_GLOB_DAT", - "RELOC_JMP_SLOT", - "RELOC_RELATIVE", - "NO_RELOC" - }; - - if (insn->error) { - fprintf(stderr, "ERROR: %s\n"); - } - fprintf(stderr, "opcode=0x%08x\n", insn->opcode); - fprintf(stderr, "reloc = %s\n", Reloc[insn->reloc]); - fprintf(stderr, "exp = { + char *Reloc[] = { + "RELOC_8", + "RELOC_16", + "RELOC_32", + "RELOC_DISP8", + "RELOC_DISP16", + "RELOC_DISP32", + "RELOC_WDISP30", + "RELOC_WDISP22", + "RELOC_HI22", + "RELOC_22", + "RELOC_13", + "RELOC_LO10", + "RELOC_SFA_BASE", + "RELOC_SFA_OFF13", + "RELOC_BASE10", + "RELOC_BASE13", + "RELOC_BASE22", + "RELOC_PC10", + "RELOC_PC22", + "RELOC_JMP_TBL", + "RELOC_SEGOFF16", + "RELOC_GLOB_DAT", + "RELOC_JMP_SLOT", + "RELOC_RELATIVE", + "NO_RELOC" + }; + + if (insn->error) { + fprintf(stderr, "ERROR: %s\n"); + } + fprintf(stderr, "opcode=0x%08x\n", insn->opcode); + fprintf(stderr, "reloc = %s\n", Reloc[insn->reloc]); + fprintf(stderr, "exp = { \n"); - fprintf(stderr, "\t\tX_add_symbol = %s\n", - ((insn->exp.X_add_symbol != NULL) - ? ((S_GET_NAME(insn->exp.X_add_symbol) != NULL) - ? S_GET_NAME(insn->exp.X_add_symbol) - : "???") - : "0")); - fprintf(stderr, "\t\tX_sub_symbol = %s\n", - ((insn->exp.X_subtract_symbol != NULL) - ? (S_GET_NAME(insn->exp.X_subtract_symbol) - ? S_GET_NAME(insn->exp.X_subtract_symbol) - : "???") - : "0")); - fprintf(stderr, "\t\tX_add_number = %d\n", - insn->exp.X_add_number); - fprintf(stderr, "}\n"); - return; + fprintf(stderr, "\t\tX_add_symbol = %s\n", + ((insn->exp.X_add_symbol != NULL) + ? ((S_GET_NAME(insn->exp.X_add_symbol) != NULL) + ? S_GET_NAME(insn->exp.X_add_symbol) + : "???") + : "0")); + fprintf(stderr, "\t\tX_sub_symbol = %s\n", + ((insn->exp.X_subtract_symbol != NULL) + ? (S_GET_NAME(insn->exp.X_subtract_symbol) + ? S_GET_NAME(insn->exp.X_subtract_symbol) + : "???") + : "0")); + fprintf(stderr, "\t\tX_add_number = %d\n", + insn->exp.X_add_number); + fprintf(stderr, "}\n"); + return; } /* print_insn() */ #endif @@ -1637,47 +1814,47 @@ static void print_insn(insn) */ #if defined(OBJ_AOUT) || defined(OBJ_BOUT) void emit_sparc_reloc(fixP, segment_address_in_file) - register fixS *fixP; - relax_addressT segment_address_in_file; +register fixS *fixP; +relax_addressT segment_address_in_file; { - struct reloc_info_generic ri; - register symbolS *symbolP; - extern char *next_object_file_charP; - /* long add_number; */ - - memset((char *) &ri, '\0', sizeof(ri)); - for (; fixP; fixP = fixP->fx_next) { - - if (fixP->fx_r_type >= NO_RELOC) { - as_fatal("fixP->fx_r_type = %d\n", fixP->fx_r_type); - } + struct reloc_info_generic ri; + register symbolS *symbolP; + extern char *next_object_file_charP; + /* long add_number; */ - if ((symbolP = fixP->fx_addsy) != NULL) { - ri.r_address = fixP->fx_frag->fr_address + - fixP->fx_where - segment_address_in_file; - if ((S_GET_TYPE(symbolP)) == N_UNDF) { - ri.r_extern = 1; - ri.r_index = symbolP->sy_number; - } else { - ri.r_extern = 0; - ri.r_index = S_GET_TYPE(symbolP); - } - if (symbolP && symbolP->sy_frag) { - ri.r_addend = symbolP->sy_frag->fr_address; - } - ri.r_type = fixP->fx_r_type; - if (fixP->fx_pcrel) { - /* ri.r_addend -= fixP->fx_where; */ - ri.r_addend -= ri.r_address; - } else { - ri.r_addend = fixP->fx_addnumber; - } - - md_ri_to_chars(next_object_file_charP, &ri); - next_object_file_charP += md_reloc_size; + memset((char *) &ri, '\0', sizeof(ri)); + for (; fixP; fixP = fixP->fx_next) { + + if (fixP->fx_r_type >= NO_RELOC) { + as_fatal("fixP->fx_r_type = %d\n", fixP->fx_r_type); + } + + if ((symbolP = fixP->fx_addsy) != NULL) { + ri.r_address = fixP->fx_frag->fr_address + + fixP->fx_where - segment_address_in_file; + if ((S_GET_TYPE(symbolP)) == N_UNDF) { + ri.r_extern = 1; + ri.r_index = symbolP->sy_number; + } else { + ri.r_extern = 0; + ri.r_index = S_GET_TYPE(symbolP); + } + if (symbolP && symbolP->sy_frag) { + ri.r_addend = symbolP->sy_frag->fr_address; + } + ri.r_type = fixP->fx_r_type; + if (fixP->fx_pcrel) { + /* ri.r_addend -= fixP->fx_where; */ + ri.r_addend -= ri.r_address; + } else { + ri.r_addend = fixP->fx_addnumber; + } + + md_ri_to_chars(next_object_file_charP, &ri); + next_object_file_charP += md_reloc_size; + } } - } - return; + return; } /* emit_sparc_reloc() */ #endif /* aout or bout */ #endif /* comment */ @@ -1690,7 +1867,7 @@ void emit_sparc_reloc(fixP, segment_address_in_file) * -bump * Warn on architecture bumps. See also -A. * - * -Av6, -Av7, -Av8 + * -Av6, -Av7, -Av8, -Asparclite * Select the architecture. Instructions or features not * supported by the selected architecture cause fatal errors. * @@ -1708,52 +1885,56 @@ void emit_sparc_reloc(fixP, segment_address_in_file) * architecture starts at the specified level, but bumps are * warnings. * + * start-sanitize-v9 + * Bumping between incompatible architectures is always an + * error. For example, from sparclite to v9. + * end-sanitize-v9 */ /* start-sanitize-v9 */ /* There is also a -Av9 architecture option. xoxorich. */ /* end-sanitize-v9 */ int md_parse_option(argP, cntP, vecP) - char **argP; - int *cntP; - char ***vecP; +char **argP; +int *cntP; +char ***vecP; { - char *p; - const char **arch; - - if (!strcmp(*argP,"bump")){ - warn_on_bump = 1; - - } else if (**argP == 'A'){ - p = (*argP) + 1; - - for (arch = architecture_pname; *arch != NULL; ++arch){ - if (strcmp(p, *arch) == 0){ - break; - } /* found a match */ - } /* walk the pname table */ + char *p; + const char **arch; - if (*arch == NULL){ - as_bad("unknown architecture: %s", p); + if (!strcmp(*argP,"bump")){ + warn_on_bump = 1; + + } else if (**argP == 'A'){ + p = (*argP) + 1; + + for (arch = architecture_pname; *arch != NULL; ++arch){ + if (strcmp(p, *arch) == 0){ + break; + } /* found a match */ + } /* walk the pname table */ + + if (*arch == NULL){ + as_bad("unknown architecture: %s", p); + } else { + current_architecture = (enum sparc_architecture) (arch - architecture_pname); + architecture_requested = 1; + } } else { - current_architecture = (enum sparc_architecture) (arch - architecture_pname); - architecture_requested = 1; + /* Unknown option */ + (*argP)++; + return 0; } - } else { - /* Unknown option */ - (*argP)++; - return 0; - } - **argP = '\0'; /* Done parsing this switch */ - return 1; + **argP = '\0'; /* Done parsing this switch */ + return 1; } /* md_parse_option() */ /* We have no need to default values of symbols. */ /* ARGSUSED */ symbolS *md_undefined_symbol(name) - char *name; +char *name; { - return 0; + return 0; } /* md_undefined_symbol() */ /* Parse an operand that is machine-specific. @@ -1762,16 +1943,16 @@ symbolS *md_undefined_symbol(name) /* ARGSUSED */ void md_operand(expressionP) - expressionS *expressionP; +expressionS *expressionP; { } /* md_operand() */ /* Round up a section size to the appropriate boundary. */ long md_section_align (segment, size) - segT segment; - long size; +segT segment; +long size; { - return (size + 7) & ~7; /* Round all sects to multiple of 8 */ + return (size + 7) & ~7; /* Round all sects to multiple of 8 */ } /* md_section_align() */ /* Exactly what point is a PC-relative offset relative TO? @@ -1779,16 +1960,16 @@ long md_section_align (segment, size) its size. This gets us to the following instruction. (??? Is this right? FIXME-SOON) */ long md_pcrel_from(fixP) - fixS *fixP; +fixS *fixP; { - return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; + return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; } /* md_pcrel_from() */ void tc_aout_pre_write_hook(headers) - object_headers *headers; +object_headers *headers; { - H_SET_VERSION(headers, 1); - return; + H_SET_VERSION(headers, 1); + return; } /* tc_aout_pre_write_hook() */ /* -- 2.30.2