summaryrefslogtreecommitdiff
path: root/bfd/cpu-ns32k.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/cpu-ns32k.c')
-rw-r--r--bfd/cpu-ns32k.c150
1 files changed, 78 insertions, 72 deletions
diff --git a/bfd/cpu-ns32k.c b/bfd/cpu-ns32k.c
index c01599e080a..2cfa26fe7d4 100644
--- a/bfd/cpu-ns32k.c
+++ b/bfd/cpu-ns32k.c
@@ -1,5 +1,5 @@
/* BFD support for the ns32k architecture.
- Copyright 1990, 1991, 1994, 1995, 1998, 2000
+ Copyright 1990, 1991, 1994, 1995, 1998, 2000, 2001
Free Software Foundation, Inc.
Almost totally rewritten by Ian Dall from initial work
by Andrew Cagney.
@@ -36,40 +36,36 @@ static const bfd_arch_info_type arch_info_struct[] =
const bfd_arch_info_type bfd_ns32k_arch =
N(32032,"ns32k:32032",false, &arch_info_struct[0]);
-static long
-ns32k_sign_extend(value, bits)
- int value;
- int bits;
-{
- value = value & ((1 << bits) - 1);
- return (value & (1 << (bits-1))
- ? value | (~((1 << bits) - 1))
- : value);
-}
+static bfd_reloc_status_type do_ns32k_reloc
+ PARAMS ((bfd *, arelent *, struct symbol_cache_entry *, PTR, asection *,
+ bfd *, char **,
+ bfd_vma (*) (bfd_byte *, int),
+ int (*) (bfd_vma, bfd_byte *, int)));
-long
-_bfd_ns32k_get_displacement(buffer, offset, size)
+bfd_vma
+_bfd_ns32k_get_displacement (buffer, size)
bfd_byte *buffer;
- long offset;
- long size;
+ int size;
{
- long value;
- buffer += offset;
+ bfd_signed_vma value;
switch (size)
{
case 1:
- value = ns32k_sign_extend (*buffer, 7);
+ value = ((*buffer & 0x7f) ^ 0x40) - 0x40;
break;
+
case 2:
- value = ns32k_sign_extend(*buffer++, 6);
+ value = ((*buffer++ & 0x3f) ^ 0x20) - 0x20;
value = (value << 8) | (0xff & *buffer);
break;
+
case 4:
- value = ns32k_sign_extend(*buffer++, 6);
+ value = ((*buffer++ & 0x3f) ^ 0x20) - 0x20;
value = (value << 8) | (0xff & *buffer++);
value = (value << 8) | (0xff & *buffer++);
value = (value << 8) | (0xff & *buffer);
break;
+
default:
abort ();
return 0;
@@ -78,37 +74,38 @@ _bfd_ns32k_get_displacement(buffer, offset, size)
}
int
-_bfd_ns32k_put_displacement(value, buffer, offset, size)
- long value;
+_bfd_ns32k_put_displacement (value, buffer, size)
+ bfd_vma value;
bfd_byte *buffer;
- long offset;
- long size;
+ int size;
{
- buffer += offset;
switch (size)
{
case 1:
- if (value < -64 || value > 63)
+ if (value + 0x40 > 0x7f)
return -1;
- value&=0x7f;
- *buffer++=value;
+ value &= 0x7f;
+ *buffer++ = value;
break;
+
case 2:
- if (value < -8192 || value > 8191)
+ if (value + 0x2000 > 0x3fff)
return -1;
- value&=0x3fff;
- value|=0x8000;
- *buffer++=(value>>8);
- *buffer++=value;
+ value &= 0x3fff;
+ value |= 0x8000;
+ *buffer++ = (value >> 8);
+ *buffer++ = value;
break;
+
case 4:
- if (value < -0x1f000000 || value >= 0x20000000)
+ /* FIXME: is this correct? -0x1f000000 <= value < 0x2000000 */
+ if (value + 0x1f000000 > 0x3effffff)
return -1;
- value|=0xc0000000;
- *buffer++=(value>>24);
- *buffer++=(value>>16);
- *buffer++=(value>>8);
- *buffer++=value;
+ value |= (bfd_vma) 0xc0000000;
+ *buffer++ = (value >> 24);
+ *buffer++ = (value >> 16);
+ *buffer++ = (value >> 8);
+ *buffer++ = value;
break;
default:
return -1;
@@ -116,19 +113,21 @@ _bfd_ns32k_put_displacement(value, buffer, offset, size)
return 0;
}
-long
-_bfd_ns32k_get_immediate (buffer, offset, size)
+bfd_vma
+_bfd_ns32k_get_immediate (buffer, size)
bfd_byte *buffer;
- long offset;
- long size;
+ int size;
{
- long value = 0;
- buffer += offset;
+ bfd_vma value = 0;
switch (size)
{
+ case 8:
+ value = (value << 8) | (*buffer++ & 0xff);
+ value = (value << 8) | (*buffer++ & 0xff);
+ value = (value << 8) | (*buffer++ & 0xff);
+ value = (value << 8) | (*buffer++ & 0xff);
case 4:
value = (value << 8) | (*buffer++ & 0xff);
- case 3:
value = (value << 8) | (*buffer++ & 0xff);
case 2:
value = (value << 8) | (*buffer++ & 0xff);
@@ -139,18 +138,21 @@ _bfd_ns32k_get_immediate (buffer, offset, size)
}
int
-_bfd_ns32k_put_immediate (value, buffer, offset, size)
- long value;
+_bfd_ns32k_put_immediate (value, buffer, size)
+ bfd_vma value;
bfd_byte *buffer;
- long offset;
- long size;
+ int size;
{
- buffer += offset + size - 1;
+ buffer += size - 1;
switch (size)
{
+ case 8:
+ *buffer-- = (value & 0xff); value >>= 8;
+ *buffer-- = (value & 0xff); value >>= 8;
+ *buffer-- = (value & 0xff); value >>= 8;
+ *buffer-- = (value & 0xff); value >>= 8;
case 4:
*buffer-- = (value & 0xff); value >>= 8;
- case 3:
*buffer-- = (value & 0xff); value >>= 8;
case 2:
*buffer-- = (value & 0xff); value >>= 8;
@@ -175,8 +177,8 @@ do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
asection *input_section;
bfd *output_bfd;
char **error_message ATTRIBUTE_UNUSED;
- long (*get_data) ();
- int (*put_data) ();
+ bfd_vma (*get_data) PARAMS ((bfd_byte *, int));
+ int (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
{
int overflow = 0;
bfd_vma relocation;
@@ -185,6 +187,7 @@ do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
bfd_vma output_base = 0;
reloc_howto_type *howto = reloc_entry->howto;
asection *reloc_target_output_section;
+ bfd_byte *location;
if ((symbol->section == &bfd_abs_section)
&& output_bfd != (bfd *) NULL)
@@ -433,7 +436,8 @@ space consuming. For each target:
bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
if (((bfd_vma) check & ~reloc_bits) != 0
- && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
+ && (((bfd_vma) check & ~reloc_bits)
+ != (-(bfd_vma) 1 & ~reloc_bits)))
{
/* The above right shift is incorrect for a signed
value. See if turning on the upper bits fixes the
@@ -444,7 +448,8 @@ space consuming. For each target:
check |= ((bfd_vma) - 1
& ~((bfd_vma) - 1
>> (howto->rightshift - howto->bitpos)));
- if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
+ if (((bfd_vma) check & ~reloc_bits)
+ != (-(bfd_vma) 1 & ~reloc_bits))
flag = bfd_reloc_overflow;
}
else
@@ -528,38 +533,39 @@ space consuming. For each target:
#define DOIT(x) \
x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
+ location = (bfd_byte *) data + addr;
switch (howto->size)
{
case 0:
{
- char x = get_data (data, addr, 1);
+ char x = get_data (location, 1);
DOIT (x);
- overflow = put_data(x, data, addr, 1);
+ overflow = put_data ((bfd_vma) x, location, 1);
}
break;
case 1:
if (relocation)
{
- short x = get_data (data, addr, 2);
+ short x = get_data (location, 2);
DOIT (x);
- overflow = put_data(x, (unsigned char *) data, addr, 2);
+ overflow = put_data ((bfd_vma) x, location, 2);
}
break;
case 2:
if (relocation)
{
- long x = get_data (data, addr, 4);
+ long x = get_data (location, 4);
DOIT (x);
- overflow = put_data(x, data, addr, 4);
+ overflow = put_data ((bfd_vma) x, location, 4);
}
break;
case -2:
{
- long x = get_data(data, addr, 4);
+ long x = get_data (location, 4);
relocation = -relocation;
DOIT(x);
- overflow = put_data(x, data , addr, 4);
+ overflow = put_data ((bfd_vma) x, location, 4);
}
break;
@@ -571,9 +577,9 @@ space consuming. For each target:
#ifdef BFD64
if (relocation)
{
- bfd_vma x = get_data (data, addr, 8);
+ bfd_vma x = get_data (location, 8);
DOIT (x);
- overflow = put_data(x, data, addr, 8);
+ overflow = put_data (x, location, 8);
}
#else
abort ();
@@ -591,14 +597,14 @@ space consuming. For each target:
/* Relocate a given location using a given value and howto. */
bfd_reloc_status_type
-_bfd_do_ns32k_reloc_contents ( howto, input_bfd, relocation, location,
+_bfd_do_ns32k_reloc_contents (howto, input_bfd, relocation, location,
get_data, put_data)
reloc_howto_type *howto;
bfd *input_bfd ATTRIBUTE_UNUSED;
bfd_vma relocation;
bfd_byte *location;
- long (*get_data) ();
- int (*put_data) ();
+ bfd_vma (*get_data) PARAMS ((bfd_byte *, int));
+ int (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
{
int size;
bfd_vma x;
@@ -622,7 +628,7 @@ _bfd_do_ns32k_reloc_contents ( howto, input_bfd, relocation, location,
#ifdef BFD64
case 8:
#endif
- x = get_data (location, 0, size);
+ x = get_data (location, size);
break;
}
@@ -729,7 +735,7 @@ _bfd_do_ns32k_reloc_contents ( howto, input_bfd, relocation, location,
if ((check & ~reloc_bits) != 0
&& (((bfd_vma) signed_check & ~reloc_bits)
- != (-1 & ~reloc_bits)))
+ != (-(bfd_vma) 1 & ~reloc_bits)))
overflow = true;
}
break;
@@ -758,7 +764,7 @@ _bfd_do_ns32k_reloc_contents ( howto, input_bfd, relocation, location,
#ifdef BFD64
case 8:
#endif
- put_data(x, location, 0, size);
+ put_data (x, location, size);
break;
}