diff -Nru binutils-2005-12-13-ORIG/src/gas/config/tc-or32.c binutils-2005-12-13-DONE/src/gas/config/tc-or32.c --- binutils-2005-12-13-ORIG/src/gas/config/tc-or32.c 2005-08-11 04:25:28.000000000 +0300 +++ binutils-2005-12-13-DONE/src/gas/config/tc-or32.c 2005-12-13 19:42:15.000000000 +0200 @@ -1,8 +1,10 @@ /* Assembly backend for the OpenRISC 1000. - Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. - Contributed by Damjan Lampret . - Modified bu Johan Rydberg, . - Based upon a29k port. + Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Contributed by Damjan Lampret + Modified by Johan Rydberg + Gyorgy Jeney + + Based upon a29k port and mips port. This file is part of GAS, the GNU Assembler. @@ -18,18 +20,38 @@ You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to - the Free Software Foundation, 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ /* tc-a29k.c used as a template. */ #include "safe-ctype.h" #include "as.h" #include "opcode/or32.h" -#include "elf/or32.h" +#include "struc-symbol.h" + +#include "elf/or32.h" #define DEBUG 0 +#if DEBUG > 1 +#define DEBUG1(x...) fprintf(stderr, x) +#else +#define DEBUG1(x...) +#endif + +#if DEBUG > 2 +#define DEBUG2(x...) fprintf(stderr, x) +#else +#define DEBUG2(x...) +#endif + +#if DEBUG > 3 +#define DEBUG3(x...) fprintf(stderr, x) +#else +#define DEBUG3(x...) +#endif + #ifndef REGISTER_PREFIX #define REGISTER_PREFIX '%' #endif @@ -44,33 +66,45 @@ static struct hash_control *op_hash = NULL; struct machine_it -{ - char * error; - unsigned long opcode; - struct nlist * nlistp; - expressionS exp; - int pcrel; - int reloc_offset; /* Offset of reloc within insn. */ - int reloc; -} + { + char * error; + unsigned long opcode; + struct nlist * nlistp; + expressionS exp; + int pcrel; + int reloc; + } the_insn; +static void machine_ip PARAMS ((char *)); + const pseudo_typeS md_pseudo_table[] = -{ - {"align", s_align_bytes, 4 }, - {"space", s_space, 0 }, - {"cputype", s_ignore, 0 }, - {"reg", s_lsym, 0 }, /* Register equate, same as equ. */ - {"sect", s_ignore, 0 }, /* Creation of coff sections. */ - {"proc", s_ignore, 0 }, /* Start of a function. */ - {"endproc", s_ignore, 0 }, /* Function end. */ - {"word", cons, 4 }, - {NULL, 0, 0 }, -}; + { + {"align", s_align_bytes, 4 }, + {"space", s_space, 0 }, + {"cputype", s_ignore, 0 }, + {"reg", s_lsym, 0 }, /* Register equate, same as equ. */ + {"sect", s_ignore, 0 }, /* Creation of coff sections. */ + {"proc", s_ignore, 0 }, /* Start of a function. */ + {"endproc", s_ignore, 0 }, /* Function end. */ + {"half", cons, 2 }, + {"word", cons, 4 }, + {NULL, 0, 0 }, + }; int md_short_jump_size = 4; int md_long_jump_size = 4; +#if defined(BFD_HEADERS) +#ifdef RELSZ +const int md_reloc_size = RELSZ; /* Coff headers. */ +#else +const int md_reloc_size = 12; /* Something else headers. */ +#endif +#else +const int md_reloc_size = 12; /* Not bfdized. */ +#endif + /* This array holds the chars that always start a comment. If the pre-processor is disabled, these aren't very useful. */ const char comment_chars[] = "#"; @@ -99,26 +133,27 @@ /* "l.jalr r9" precalculated opcode. */ static unsigned long jalr_r9_opcode; -static void machine_ip (char *); +static int check_invalid_opcode PARAMS ((unsigned long)); +static void encode PARAMS ((const struct machine_opcode *, unsigned long *, signed long, char)); +static char * parse_operand PARAMS ((char *, expressionS *, int)); /* Set bits in machine opcode according to insn->encoding - description and passed operand. */ + description and passed operand. */ -static void -encode (const struct machine_opcode *insn, - unsigned long *opcode, - signed long param_val, - char param_ch) +static void +encode (insn, opcode, param_val, param_ch) + const struct machine_opcode *insn; + unsigned long *opcode; + signed long param_val; + char param_ch; { int opc_pos = 0; int param_pos = 0; char *enc; -#if DEBUG - printf (" encode: opcode=%.8lx param_val=%.8lx abs=%.8lx param_ch=%c\n", + DEBUG2(" encode: opcode=%.8lx param_val=%.8lx abs=%.8lx param_ch=%c\n", *opcode, param_val, abs (param_val), param_ch); -#endif for (enc = insn->encoding; *enc != '\0'; enc++) if (*enc == param_ch) { @@ -132,7 +167,7 @@ for (enc = insn->encoding; *enc != '\0';) { - if ((*enc == '0') && (*(enc + 1) == 'x')) + if ((*enc == '0') && (*(enc + 1) == 'x')) { int tmp = strtol (enc, NULL, 16); @@ -140,25 +175,25 @@ *opcode |= tmp << opc_pos; enc += 3; } - else if ((*enc == '0') || (*enc == '-')) + else if ((*enc == '0') || (*enc == '-')) { opc_pos--; enc++; } - else if (*enc == '1') + else if (*enc == '1') { opc_pos--; *opcode |= 1 << opc_pos; enc++; } - else if (*enc == param_ch) + else if (*enc == param_ch) { opc_pos--; param_pos--; *opcode |= ((param_val >> param_pos) & 0x1) << opc_pos; enc++; } - else if (ISALPHA (*enc)) + else if (ISALPHA (*enc)) { opc_pos--; enc++; @@ -166,10 +201,8 @@ else enc++; } - -#if DEBUG - printf (" opcode=%.8lx\n", *opcode); -#endif + + DEBUG2(" opcode=%.8lx\n", *opcode); } /* This function is called once, at assembler startup time. It should @@ -177,17 +210,17 @@ need. */ void -md_begin (void) +md_begin () { const char *retval = NULL; int lose = 0; int skipnext = 0; - unsigned int i; + int i; /* Hash up all the opcodes for fast use later. */ op_hash = hash_new (); - for (i = 0; i < or32_num_opcodes; i++) + for (i = 0; i < num_opcodes; i++) { const char *name = machine_opcodes[i].name; @@ -197,7 +230,7 @@ continue; } - retval = hash_insert (op_hash, name, (void *) &machine_opcodes[i]); + retval = hash_insert (op_hash, name, (PTR) &machine_opcodes[i]); if (retval != NULL) { fprintf (stderr, "internal error: can't hash `%s': %s\n", @@ -212,10 +245,11 @@ encode (&machine_opcodes[insn_index ("l.jalr")], &jalr_r9_opcode, 9, 'B'); } -/* Returns non zero if instruction is to be used. */ +/* Returs non zero if instruction is to be used. */ static int -check_invalid_opcode (unsigned long opcode) +check_invalid_opcode (opcode) + unsigned long opcode; { return opcode == jalr_r9_opcode; } @@ -225,13 +259,12 @@ produce the bytes of data and relocation. */ void -md_assemble (char *str) +md_assemble (str) + char *str; { char *toP; -#if DEBUG - printf ("NEW INSTRUCTION\n"); -#endif + DEBUG1("NEW INSTRUCTION %s\n", str); know (str); machine_ip (str); @@ -243,8 +276,12 @@ /* Put out the symbol-dependent stuff. */ if (the_insn.reloc != BFD_RELOC_NONE) { + DEBUG1(" fix_new_exp> pcrel=%i reloc=%i sym=%s\n", + the_insn.pcrel, the_insn.reloc, + the_insn.exp.X_add_symbol->bsym ? + the_insn.exp.X_add_symbol->bsym->name : "(none)"); fix_new_exp (frag_now, - (toP - frag_now->fr_literal + the_insn.reloc_offset), + (toP - frag_now->fr_literal), 4, /* size */ &the_insn.exp, the_insn.pcrel, @@ -252,26 +289,23 @@ } } -/* This is true of the we have issued a "lo(" or "hi"(. */ -static int waiting_for_shift = 0; - static int mask_or_shift = 0; static char * -parse_operand (char *s, expressionS *operandp, int opt) +parse_operand (s, operandp, opt) + char *s; + expressionS *operandp; + int opt; { char *save = input_line_pointer; char *new; -#if DEBUG - printf (" PROCESS NEW OPERAND(%s) == %c (%d)\n", s, opt ? opt : '!', opt); -#endif + DEBUG3(" PROCESS NEW OPERAND(%s) == %c (%d)\n", s, opt ? opt : '!', opt); input_line_pointer = s; if (strncasecmp (s, "HI(", 3) == 0) { - waiting_for_shift = 1; mask_or_shift = BFD_RELOC_HI16; input_line_pointer += 3; @@ -288,14 +322,14 @@ if ((*s == '(') && (*(s+1) == 'r')) s++; - if ((*s == 'r') && ISDIGIT (*(s + 1))) + if ((*s == 'r') && ISDIGIT (*(s + 1))) { operandp->X_add_number = strtol (s + 1, NULL, 10); operandp->X_op = O_register; for (; (*s != ',') && (*s != '\0');) - s++; + s++; input_line_pointer = save; - return s; + return s; } expression (operandp); @@ -310,13 +344,11 @@ operandp->X_op = O_constant; } } - + new = input_line_pointer; input_line_pointer = save; - -#if DEBUG - printf (" %s=parse_operand(%s): operandp->X_op = %u\n", new, s, operandp->X_op); -#endif + + DEBUG3(" %s=parse_operand(%s): operandp->X_op = %u\n", new, s, operandp->X_op); return new; } @@ -326,24 +358,20 @@ Warnings or errors are generated. */ static void -machine_ip (char *str) +machine_ip (str) + char *str; { char *s; const char *args; const struct machine_opcode *insn; - char *argsStart; unsigned long opcode; - expressionS the_operand; - expressionS *operand = &the_operand; - unsigned int regno; + expressionS operand; int reloc = BFD_RELOC_NONE; -#if DEBUG - printf ("machine_ip(%s)\n", str); -#endif + DEBUG2("machine_ip(%s)\n", str); s = str; - for (; ISALNUM (*s) || *s == '.'; ++s) + for (; ISALNUM (*s) || *s == '.' || *s == '_'; ++s) if (ISUPPER (*s)) *s = TOLOWER (*s); @@ -367,7 +395,6 @@ return; } - argsStart = s; opcode = 0; memset (&the_insn, '\0', sizeof (the_insn)); the_insn.reloc = BFD_RELOC_NONE; @@ -376,18 +403,21 @@ /* Build the opcode, checking as we go to make sure that the operands match. - + If an operand matches, we modify the_insn or opcode appropriately, and do a "continue". If an operand fails to match, we "break". */ if (insn->args[0] != '\0') - /* Prime the pump. */ - s = parse_operand (s, operand, insn->args[0] == 'I'); + { + /* Prime the pump. */ + s = parse_operand (s, + &operand, + (insn->args[0] == 'I') || + (strcmp(insn->name, "l.nop") == 0) ); + } for (args = insn->args;; ++args) { -#if DEBUG - printf (" args = %s\n", args); -#endif + DEBUG2(" args = %s\n", args); switch (*args) { case '\0': /* End of args. */ @@ -400,7 +430,7 @@ /* We are truly done. */ the_insn.opcode = opcode; if (check_invalid_opcode (opcode)) - as_bad (_("instruction not allowed: %s"), str); + as_bad (_("instruction not allowed: %s"), str); return; } as_bad (_("too many operands: %s"), s); @@ -412,106 +442,77 @@ reloc = BFD_RELOC_NONE; /* Parse next operand. */ - s = parse_operand (s, operand, args[1] == 'I'); -#if DEBUG - printf (" ',' case: operand->X_add_number = %d, *args = %s, *s = %s\n", - operand->X_add_number, args, s); -#endif + s = parse_operand (s, &operand, args[1] == 'I'); + DEBUG3(" ',' case: operand->X_add_number = %d, *args = %s, *s = %s\n", + operand.X_add_number, args, s); continue; } break; case '(': /* Must match a (. */ - s = parse_operand (s, operand, args[1] == 'I'); + s = parse_operand (s, &operand, args[1] == 'I'); continue; - + case ')': /* Must match a ). */ continue; case 'r': /* A general register. */ args++; - if (operand->X_op != O_register) + if (operand.X_op != O_register) break; /* Only registers. */ - - know (operand->X_add_symbol == 0); - know (operand->X_op_symbol == 0); - regno = operand->X_add_number; - encode (insn, &opcode, regno, *args); -#if DEBUG - printf (" r: operand->X_op = %d\n", operand->X_op); -#endif + + know (operand.X_add_symbol == 0); + know (operand.X_op_symbol == 0); + encode (insn, &opcode, operand.X_add_number, *args); + DEBUG3(" r: operand->X_op = %d\n", operand.X_op); continue; default: - /* if (! ISALPHA (*args)) - break; */ /* Only immediate values. */ - if (mask_or_shift) { -#if DEBUG - printf ("mask_or_shift = %d\n", mask_or_shift); -#endif + DEBUG3("mask_or_shift = %d\n", mask_or_shift); reloc = mask_or_shift; } mask_or_shift = 0; - - if (strncasecmp (args, "LO(", 3) == 0) - { -#if DEBUG - printf ("reloc_const\n"); -#endif - reloc = BFD_RELOC_LO16; - } - else if (strncasecmp (args, "HI(", 3) == 0) - { -#if DEBUG - printf ("reloc_consth\n"); -#endif - reloc = BFD_RELOC_HI16; - } - - if (*s == '(') - operand->X_op = O_constant; + + if (*s == '(') + operand.X_op = O_constant; else if (*s == ')') s += 1; -#if DEBUG - printf (" default case: operand->X_add_number = %d, *args = %s, *s = %s\n", operand->X_add_number, args, s); -#endif - if (operand->X_op == O_constant) + DEBUG3(" default case: operand.X_add_number = %d, *args = %s, *s = %s\n", + operand.X_add_number, args, s); + if (operand.X_op == O_constant) { + unsigned long add = operand.X_add_number; if (reloc == BFD_RELOC_NONE) { bfd_vma v, mask; mask = 0x3ffffff; - v = abs (operand->X_add_number) & ~ mask; + v = abs (operand.X_add_number) & ~ mask; if (v) as_bad (_("call/jmp target out of range (1)")); } if (reloc == BFD_RELOC_HI16) - operand->X_add_number = ((operand->X_add_number >> 16) & 0xffff); + add = (operand.X_add_number >> 16) & 0xffff; the_insn.pcrel = 0; - encode (insn, &opcode, operand->X_add_number, *args); - /* the_insn.reloc = BFD_RELOC_NONE; */ - continue; + encode (insn, &opcode, add, *args); + continue; } if (reloc == BFD_RELOC_NONE) - the_insn.reloc = BFD_RELOC_32_GOT_PCREL; + the_insn.reloc = BFD_RELOC_28_PCREL_S2; else the_insn.reloc = reloc; /* the_insn.reloc = insn->reloc; */ -#if DEBUG - printf (" reloc sym=%d\n", the_insn.reloc); - printf (" BFD_RELOC_NONE=%d\n", BFD_RELOC_NONE); -#endif - the_insn.exp = *operand; - - /* the_insn.reloc_offset = 1; */ + DEBUG1(" reloc sym=%d\n", the_insn.reloc); + DEBUG1(" BFD_RELOC_NONE=%d\n", BFD_RELOC_NONE); + the_insn.exp = operand; + the_insn.pcrel = 1; /* Assume PC-relative jump. */ /* FIXME-SOON, Do we figure out whether abs later, after @@ -519,10 +520,13 @@ if (reloc == BFD_RELOC_LO16 || reloc == BFD_RELOC_HI16) the_insn.pcrel = 0; - encode (insn, &opcode, operand->X_add_number, *args); + if (reloc == BFD_RELOC_NONE) + encode (insn, &opcode, operand.X_add_number, *args); + else + encode (insn, &opcode, 0, *args); continue; } - + /* Types or values of args don't match. */ as_bad (_("invalid operands")); return; @@ -541,7 +545,10 @@ #define MAX_LITTLENUMS 6 char * -md_atof (int type, char * litP, int * sizeP) +md_atof (type, litP, sizeP) + char type; + char * litP; + int * sizeP; { int prec; LITTLENUM_TYPE words[MAX_LITTLENUMS]; @@ -597,24 +604,27 @@ /* Write out big-endian. */ void -md_number_to_chars (char *buf, valueT val, int n) +md_number_to_chars (buf, val, n) + char *buf; + valueT val; + int n; { number_to_chars_bigendian (buf, val, n); } void -md_apply_fix (fixS * fixP, valueT * val, segT seg ATTRIBUTE_UNUSED) +md_apply_fix (fixS *fixP, valueT *val, segT seg ATTRIBUTE_UNUSED) { - char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; - long t_val; + bfd_byte *buf; + long insn; - t_val = (long) *val; + buf = (bfd_byte *) (fixP->fx_where + fixP->fx_frag->fr_literal); -#if DEBUG - printf ("md_apply_fix val:%x\n", t_val); -#endif + DEBUG1("md_apply_fix3 *val=%x fixP->fx_r_type=%i sym=%s\n", *val, + fixP->fx_r_type, fixP->fx_addsy ? fixP->fx_addsy->bsym->name : "(none)"); - fixP->fx_addnumber = t_val; /* Remember value for emit_reloc. */ + if ((fixP->fx_addsy == (symbolS *) NULL) && !fixP->fx_pcrel) + fixP->fx_done = 1; know (fixP->fx_size == 4); know (fixP->fx_r_type < BFD_RELOC_NONE); @@ -622,65 +632,58 @@ switch (fixP->fx_r_type) { case BFD_RELOC_32: /* XXXXXXXX pattern in a word. */ -#if DEBUG - printf ("reloc_const: val=%x\n", t_val); -#endif - buf[0] = t_val >> 24; - buf[1] = t_val >> 16; - buf[2] = t_val >> 8; - buf[3] = t_val; + DEBUG1("reloc_const: val=%x\n", *val); + /* If we are deleting this reloc entry, we must fill in the + value now. This can happen if we have a .word which is not + resolved when it appears but is later defined. We also need + to fill in the value if this is an embedded PIC switch table + entry. */ + if (fixP->fx_done) + md_number_to_chars ((char *) buf, *val, 4); break; case BFD_RELOC_16: /* XXXX0000 pattern in a word. */ -#if DEBUG - printf ("reloc_const: val=%x\n", t_val); -#endif - buf[0] = t_val >> 8; - buf[1] = t_val; + DEBUG1("reloc_const: val=%x\n", *val); + /* If we are deleting this reloc entry, we must fill in the + value now. */ + assert (fixP->fx_size == 2); + if (fixP->fx_done) + md_number_to_chars ((char *) buf, *val, 2); break; case BFD_RELOC_8: /* XX000000 pattern in a word. */ -#if DEBUG - printf ("reloc_const: val=%x\n", t_val); -#endif - buf[0] = t_val; - break; - case BFD_RELOC_LO16: /* 0000XXXX pattern in a word. */ -#if DEBUG - printf ("reloc_const: val=%x\n", t_val); -#endif - buf[2] = t_val >> 8; /* Holds bits 0000XXXX. */ - buf[3] = t_val; + DEBUG1("reloc_const: val=%x\n", *val); break; case BFD_RELOC_HI16: /* 0000XXXX pattern in a word. */ -#if DEBUG - printf ("reloc_consth: val=%x\n", t_val); -#endif - buf[2] = t_val >> 24; /* Holds bits XXXX0000. */ - buf[3] = t_val >> 16; + DEBUG1("reloc_consth: val=%x\n", *val); break; - case BFD_RELOC_32_GOT_PCREL: /* 0000XXXX pattern in a word. */ - if (!fixP->fx_done) - ; - else if (fixP->fx_pcrel) - { - long v = t_val >> 28; - - if (v != 0 && v != -1) - as_bad_where (fixP->fx_file, fixP->fx_line, - _("call/jmp target out of range (2)")); - } + case BFD_RELOC_28_PCREL_S2: /* 0000XXXX pattern in a word. */ + DEBUG1("reloc_pcrel: *val=%x done=%d fixP->fx_pcrel=%i line=%i\n", *val, + fixP->fx_done, fixP->fx_pcrel, fixP->fx_line); + if ((*val & 0x3) != 0) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("Branch to odd address (%lx)"), (long) *val); + + /* + * We need to save the bits in the instruction since fixup_segment() + * might be deleting the relocation entry (i.e., a branch within + * the current segment). + */ + if (! fixP->fx_done) + break; + + /* update old instruction data */ + if (target_big_endian) + insn = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; else - /* This case was supposed to be handled in machine_ip. */ - abort (); + insn = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; - buf[0] |= (t_val >> 26) & 0x03; /* Holds bits 0FFFFFFC of address. */ - buf[1] = t_val >> 18; - buf[2] = t_val >> 10; - buf[3] = t_val >> 2; + insn |= (*val >> 2) & 0x03ffffff; + md_number_to_chars ((char *) buf, insn, 4); + DEBUG1("Resulting instruction: %08x\n", insn); break; case BFD_RELOC_VTABLE_INHERIT: @@ -694,18 +697,47 @@ break; } - if (fixP->fx_addsy == (symbolS *) NULL) - fixP->fx_done = 1; + fixP->fx_addnumber = *val; /* Remember value for emit_reloc. */ +} + +#ifdef OBJ_COFF +short +tc_coff_fix2rtype (fixP) + fixS *fixP; +{ + DEBUG1("tc_coff_fix2rtype\n"); + + switch (fixP->fx_r_type) + { + case RELOC_32: + return (R_WORD); + case RELOC_8: + return (R_BYTE); + case RELOC_CONST: + return (R_ILOHALF); + case RELOC_CONSTH: + return (R_IHIHALF); + case RELOC_JUMPTARG: + return (R_IREL); + default: + printf ("need %d\n", fixP->fx_r_type); + abort (); + } + + return 0; } +#endif /* OBJ_COFF */ + /* Should never be called for or32. */ void -md_create_short_jump (char * ptr ATTRIBUTE_UNUSED, - addressT from_addr ATTRIBUTE_UNUSED, - addressT to_addr ATTRIBUTE_UNUSED, - fragS * frag ATTRIBUTE_UNUSED, - symbolS * to_symbol ATTRIBUTE_UNUSED) +md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol) + char * ptr ATTRIBUTE_UNUSED; + addressT from_addr ATTRIBUTE_UNUSED; + addressT to_addr ATTRIBUTE_UNUSED; + fragS * frag ATTRIBUTE_UNUSED; + symbolS * to_symbol ATTRIBUTE_UNUSED; { as_fatal ("or32_create_short_jmp\n"); } @@ -713,21 +745,23 @@ /* Should never be called for or32. */ void -md_convert_frag (bfd * headers ATTRIBUTE_UNUSED, - segT seg ATTRIBUTE_UNUSED, - fragS * fragP ATTRIBUTE_UNUSED) +md_convert_frag (headers, seg, fragP) + bfd * headers ATTRIBUTE_UNUSED; + segT seg ATTRIBUTE_UNUSED; + fragS * fragP ATTRIBUTE_UNUSED; { as_fatal ("or32_convert_frag\n"); -} +} /* Should never be called for or32. */ void -md_create_long_jump (char * ptr ATTRIBUTE_UNUSED, - addressT from_addr ATTRIBUTE_UNUSED, - addressT to_addr ATTRIBUTE_UNUSED, - fragS * frag ATTRIBUTE_UNUSED, - symbolS * to_symbol ATTRIBUTE_UNUSED) +md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) + char * ptr ATTRIBUTE_UNUSED; + addressT from_addr ATTRIBUTE_UNUSED; + addressT to_addr ATTRIBUTE_UNUSED; + fragS * frag ATTRIBUTE_UNUSED; + symbolS * to_symbol ATTRIBUTE_UNUSED; { as_fatal ("or32_create_long_jump\n"); } @@ -735,8 +769,9 @@ /* Should never be called for or32. */ int -md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, - segT segtype ATTRIBUTE_UNUSED) +md_estimate_size_before_relax (fragP, segtype) + fragS * fragP ATTRIBUTE_UNUSED; + segT segtype ATTRIBUTE_UNUSED; { as_fatal ("or32_estimate_size_before_relax\n"); return 0; @@ -752,15 +787,14 @@ #ifdef OBJ_AOUT void -tc_aout_fix_to_chars (char *where, - fixS *fixP, - relax_addressT segment_address_in_file) +tc_aout_fix_to_chars (where, fixP, segment_address_in_file) + char *where; + fixS *fixP; + relax_addressT segment_address_in_file; { long r_symbolnum; -#if DEBUG - printf ("tc_aout_fix_to_chars\n"); -#endif + DEBUG1("tc_aout_fix_to_chars\n"); know (fixP->fx_r_type < BFD_RELOC_NONE); know (fixP->fx_addsy != NULL); @@ -788,19 +822,22 @@ const char *md_shortopts = ""; struct option md_longopts[] = -{ - { NULL, no_argument, NULL, 0 } -}; + { + { NULL, no_argument, NULL, 0 } + }; size_t md_longopts_size = sizeof (md_longopts); int -md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED) +md_parse_option (c, arg) + int c ATTRIBUTE_UNUSED; + char * arg ATTRIBUTE_UNUSED; { return 0; } void -md_show_usage (FILE * stream ATTRIBUTE_UNUSED) +md_show_usage (stream) + FILE * stream ATTRIBUTE_UNUSED; { } @@ -808,7 +845,8 @@ definitions of or32 style local labels. */ int -or32_unrecognized_line (int c) +or32_unrecognized_line (c) + int c; { int lab; char *s; @@ -848,7 +886,8 @@ are a lot of them. */ symbolS * -md_undefined_symbol (char *name ATTRIBUTE_UNUSED) +md_undefined_symbol (name) + char *name ATTRIBUTE_UNUSED; { return NULL; } @@ -856,11 +895,10 @@ /* Parse an operand that is machine-specific. */ void -md_operand (expressionS *expressionP) +md_operand (expressionP) + expressionS *expressionP; { -#if DEBUG - printf (" md_operand(input_line_pointer = %s)\n", input_line_pointer); -#endif + DEBUG3(" md_operand(input_line_pointer = %s)\n", input_line_pointer); if (input_line_pointer[0] == REGISTER_PREFIX && input_line_pointer[1] == 'r') { @@ -892,7 +930,7 @@ long lab; char *name; symbolS *sym; - + /* This is a local label. */ ++input_line_pointer; lab = (long) get_absolute_expression (); @@ -944,7 +982,7 @@ type = 'x'; fieldlimit = 4; } - else + else return; if (ISDIGIT (*s)) @@ -973,7 +1011,7 @@ SKIP_WHITESPACE (); input_line_pointer = s; - expressionP->X_op = O_constant; + expressionP->X_op = O_constant; expressionP->X_unsigned = 1; expressionP->X_add_number = ((floatbuf[fieldnum * 2] << LITTLENUM_NUMBER_OF_BITS) @@ -982,11 +1020,14 @@ } /* Round up a section size to the appropriate boundary. */ - valueT -md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size ATTRIBUTE_UNUSED) +md_section_align (seg, addr) + asection *seg; + valueT addr; { - return size; /* Byte alignment is fine. */ + int align = bfd_get_section_alignment (stdoutput, seg); + + return ((addr + (1 << align) - 1) & (-1 << align)); } /* Exactly what point is a PC-relative offset relative TO? @@ -994,7 +1035,8 @@ which we have set up as the address of the fixup too. */ long -md_pcrel_from (fixS *fixP) +md_pcrel_from (fixP) + fixS *fixP; { return fixP->fx_where + fixP->fx_frag->fr_address; } @@ -1002,15 +1044,22 @@ /* Generate a reloc for a fixup. */ arelent * -tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp) +tc_gen_reloc (seg, fixp) + asection *seg ATTRIBUTE_UNUSED; + fixS *fixp; { arelent *reloc; + DEBUG1("tc_gen_reloc fixp (off=%08x addn=%08x line=%i pcrel=%i sym=%s)\n", + fixp->fx_offset, fixp->fx_addnumber, fixp->fx_line, fixp->fx_pcrel, + fixp->fx_addsy ? fixp->fx_addsy->bsym->name : "(none)"); - reloc = xmalloc (sizeof (arelent)); - reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); + reloc = (arelent *) xmalloc (sizeof (arelent)); + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; - /* reloc->address = fixp->fx_frag->fr_address + fixp->fx_where + fixp->fx_addnumber;*/ + DEBUG1("reloc->address=%08x fixp->fx_frag->fr_address=%08x fixp->fx_where=%08x fixp->fx_addnumber=%08x\n", + reloc->address, fixp->fx_frag->fr_address, fixp->fx_where, + fixp->fx_addnumber); reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); if (reloc->howto == (reloc_howto_type *) NULL) @@ -1023,7 +1072,33 @@ if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) reloc->address = fixp->fx_offset; + else if (fixp->fx_pcrel) + { + bfd_vma pcrel_address; + + pcrel_address = reloc->address; + + if (OUTPUT_FLAVOR == bfd_target_elf_flavour) + { + /* At this point, fx_addnumber is "symbol offset - pcrel_address". + Relocations want only the symbol offset. */ + reloc->addend = fixp->fx_addnumber; + } + else + { + if (OUTPUT_FLAVOR != bfd_target_aout_flavour) + /* A gruesome hack which is a result of the gruesome gas reloc + handling. */ + reloc->addend = pcrel_address; + else + reloc->addend = -pcrel_address; + } + } + else + reloc->addend = fixp->fx_addnumber; + + DEBUG1("addend: %x\n", reloc->addend); - reloc->addend = fixp->fx_addnumber; return reloc; } + diff -Nru binutils-2005-12-13-ORIG/src/gas/config/tc-or32.h binutils-2005-12-13-DONE/src/gas/config/tc-or32.h --- binutils-2005-12-13-ORIG/src/gas/config/tc-or32.h 2005-08-11 04:25:28.000000000 +0300 +++ binutils-2005-12-13-DONE/src/gas/config/tc-or32.h 2005-12-13 19:42:36.000000000 +0200 @@ -1,6 +1,8 @@ /* tc-or32.h -- Assemble for the OpenRISC 1000. - Copyright (C) 2002, 2003. 2005 Free Software Foundation, Inc. - Contributed by Damjan Lampret . + Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Contributed by Damjan Lampret + Modified by Gyorgy Jeney + Based upon a29k port. This file is part of GAS, the GNU Assembler. @@ -17,8 +19,8 @@ You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to - the Free Software Foundation, 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ #define TC_OR32 @@ -38,10 +40,16 @@ #define tc_unrecognized_line(c) or32_unrecognized_line (c) -extern int or32_unrecognized_line (int); - -#define tc_coff_symbol_emit_hook(a) ; /* Not used. */ +extern int or32_unrecognized_line PARAMS ((int)); +#define tc_headers_hook(a) ; /* not used */ +#define tc_headers_hook(a) ; /* not used */ +#define tc_crawl_symbol_chain(a) ; /* not used */ +#define tc_coff_symbol_emit_hook(a) ; /* not used */ + +#define AOUT_MACHTYPE 80 +#define TC_COFF_FIX2RTYPE(fix_ptr) tc_coff_fix2rtype (fix_ptr) +#define BFD_ARCH bfd_arch_or32 #define COFF_MAGIC SIPFBOMAGIC /* No shared lib support, so we don't need to ensure externally @@ -53,4 +61,14 @@ #define MD_APPLY_SYM_VALUE(FIX) 0 #endif +/* Should the reloc be output ? + on the 29k, this is true only if there is a symbol attatched. + on the h8, this is allways true, since no fixup is done. */ +#define TC_COUNT_RELOC(x) (x->fx_addsy) +#define TC_CONS_RELOC RELOC_32 + +#define COFF_FLAGS F_AR32W +#define NEED_FX_R_TYPE + #define ZERO_BASED_SEGMENTS +