* som.c (NO_PCREL_MODES): Define if the system does not define

R_SHORT_PCREL_MODE.
        (hppa_som_gen_reloc_type): Handle both short and long pcrel branches.
        (som_write_fixups): Eliminate redundant pcrel mode relocs.  Handle
        R_LONG_PCREL_MODE and R_SHORT_PCREL_MODE
        * libhppa.h (dis_assemble_22): New function.
        (bfd_hppa_insn2fmt): Handle long branch.

        * libhppa.h (bfd_hppa_insn2fmt): Decode and handle formats found
        in PA2.0.
This commit is contained in:
Jeff Law 1999-09-19 18:22:20 +00:00
parent 77c02e18c1
commit 2667095fc0
3 changed files with 100 additions and 1 deletions

View file

@ -1,3 +1,16 @@
Sun Sep 19 12:16:47 1999 Jeffrey A Law (law@cygnus.com)
* som.c (NO_PCREL_MODES): Define if the system does not define
R_SHORT_PCREL_MODE.
(hppa_som_gen_reloc_type): Handle both short and long pcrel branches.
(som_write_fixups): Eliminate redundant pcrel mode relocs. Handle
R_LONG_PCREL_MODE and R_SHORT_PCREL_MODE
* libhppa.h (dis_assemble_22): New function.
(bfd_hppa_insn2fmt): Handle long branch.
* libhppa.h (bfd_hppa_insn2fmt): Decode and handle formats found
in PA2.0.
1999-09-17 Alan Modra <alan@spri.levels.unisa.edu.au>
* coff-i386.c (coff_i386_reloc_type_lookup): Support BFD_RELOC_16,

View file

@ -52,6 +52,10 @@ static INLINE unsigned long assemble_17 (unsigned int, unsigned int,
static INLINE void dis_assemble_17 (unsigned int, unsigned int *,
unsigned int *, unsigned int *)
__attribute__ ((__unused__));
static INLINE void dis_assemble_22 (unsigned int, unsigned int *,
unsigned int *, unsigned int *,
unsigned int *)
__attribute__ ((__unused__));
static INLINE unsigned long assemble_21 (unsigned int)
__attribute ((__unused__));
static INLINE void dis_assemble_21 (unsigned int, unsigned int *)
@ -332,6 +336,18 @@ dis_assemble_17 (as17, x, y, z)
*y = (((as17 & 0x00400) >> 10) | ((as17 & 0x3ff) << 1)) & 0x7ff;
}
static INLINE void
dis_assemble_22 (as22, a, b, c, d)
unsigned int as22;
unsigned int *a, *b, *c, *d;
{
*d = (as22 & 0x200000) >> 21;
*a = (as22 & 0x1f0000) >> 16;
*b = (as22 & 0x0f800) >> 11;
*c = (((as22 & 0x00400) >> 10) | ((as22 & 0x3ff) << 1)) & 0x7ff;
}
static INLINE unsigned long
assemble_21 (x)
unsigned int x;
@ -548,6 +564,15 @@ hppa_field_adjust (value, constant_value, r_field)
#define BLE 0x39
#define BE 0x38
#define CMPBDT 0x27
#define CMPBDF 0x2f
#define CMPIBD 0x3b
#define LDD 0x14
#define STD 0x1c
#define LDWL 0x17
#define STWL 0x1f
#define FDLW 0x16
#define FSTW 0x1e
/* Given a machine instruction, return its format.
@ -580,6 +605,9 @@ bfd_hppa_insn2fmt (insn)
case ADDIBF:
case BVB:
case BB:
case CMPBDT:
case CMPBDF:
case CMPIBD:
fmt = 12;
break;
case LDO:
@ -593,9 +621,24 @@ bfd_hppa_insn2fmt (insn)
case STWM:
fmt = 14;
break;
case LDWL:
case STWL:
case FDLW:
case FSTW:
/* This is a hack. Unfortunately, format 11 is already taken
and we're using integers rather than an enum, so it's hard
to describe the 10a format. */
fmt = -11;
break;
case LDD:
case STD:
fmt = 10;
break;
case BL:
case BE:
case BLE:
if ((insn & 0x00008000) == 0x00008000)
return 22;
fmt = 17;
break;
case LDIL:

View file

@ -751,6 +751,7 @@ static const int comp3_opcodes[] =
/* And these first appeared in hpux10. */
#ifndef R_SHORT_PCREL_MODE
#define NO_PCREL_MODES
#define R_SHORT_PCREL_MODE 0x3e
#endif
@ -1684,9 +1685,28 @@ hppa_som_gen_reloc_type (abfd, base_type, format, field, sym_diff, sym)
case R_HPPA_NONE:
case R_HPPA_ABS_CALL:
case R_HPPA_PCREL_CALL:
/* Right now we can default all these. */
break;
case R_HPPA_PCREL_CALL:
{
#ifndef NO_PCREL_MODES
/* If we have short and long pcrel modes, then generate the proper
mode selector, then the pcrel relocation. Redundant selectors
will be eliminted as the relocs are sized and emitted. */
final_types[0] = (int *) bfd_alloc (abfd, sizeof (int));
if (!final_types[0])
return NULL;
if (format == 17)
*final_types[0] = R_SHORT_PCREL_MODE;
else
*final_types[0] = R_LONG_PCREL_MODE;
final_types[1] = final_type;
final_types[2] = NULL;
*final_type = base_type;
#endif
break;
}
}
return final_types;
}
@ -2665,6 +2685,9 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
subsection = subsection->next)
{
int reloc_offset, current_rounding_mode;
#ifndef NO_PCREL_MODES
int current_call_mode;
#endif
/* Find a subspace of this space. */
if (!som_is_subspace (subsection)
@ -2699,6 +2722,9 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
reloc_offset = 0;
som_initialize_reloc_queue (reloc_queue);
current_rounding_mode = R_N_MODE;
#ifndef NO_PCREL_MODES
current_call_mode = R_SHORT_PCREL_MODE;
#endif
/* Translate each BFD relocation into one or more SOM
relocations. */
@ -2763,6 +2789,10 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
case R_END_TRY:
case R_N0SEL:
case R_N1SEL:
#ifndef NO_PCREL_MODES
case R_SHORT_PCREL_MODE:
case R_LONG_PCREL_MODE:
#endif
reloc_offset = bfd_reloc->address;
break;
@ -2887,6 +2917,19 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
}
break;
#ifndef NO_PCREL_MODES
case R_LONG_PCREL_MODE:
case R_SHORT_PCREL_MODE:
if (bfd_reloc->howto->type != current_call_mode)
{
bfd_put_8 (abfd, bfd_reloc->howto->type, p);
subspace_reloc_size += 1;
p += 1;
current_call_mode = bfd_reloc->howto->type;
}
break;
#endif
case R_EXIT:
case R_ALT_ENTRY:
case R_FSEL: