include/elf/

* v850.h (R_V850_LO16_SPLIT_OFFSET): New reloc.

bfd/
	* reloc.c (BFD_RELOC_V850_LO16_SPLIT_OFFSET): New bfd_reloc_code_type.
	* elf32-v850.c (v850_elf_howto_table): Add entry for
	R_V850_LO16_SPLIT_OFFSET.
	(v850_elf_reloc_map): Map it to BFD_RELOC_V850_LO16_SPLIT_OFFSET.
	(v850_elf_perform_lo16_relocation): New function, extracted from...
	(v850_elf_perform_relocation): ...here.  Use it to handle
	R_V850_LO16_SPLIT_OFFSET.
	(v850_elf_check_relocs, v850_elf_final_link_relocate): Handle
	R_V850_LO16_SPLIT_OFFSET.
	* libbfd.h, bfd-in2.h: Regenerate.

gas/
	* config/tc-v850.c (handle_lo16): New function.
	(v850_reloc_prefix): Use it to check lo().
	(md_assemble, md_apply_fix3): Handle BFD_RELOC_V850_LO16_SPLIT_OFFSET.

gas/testsuite/
	* gas/v850/split-lo16.{s,d}: New test.
	* gas/v850/v850.exp: Run it.

ld/testsuite/
	* ld-v850: New directory.
This commit is contained in:
Richard Sandiford 2004-12-16 16:56:04 +00:00
parent 2fbd2a87e2
commit 1e50d24d55
18 changed files with 369 additions and 179 deletions

View file

@ -1,3 +1,16 @@
2004-12-16 Richard Sandiford <rsandifo@redhat.com>
* reloc.c (BFD_RELOC_V850_LO16_SPLIT_OFFSET): New bfd_reloc_code_type.
* elf32-v850.c (v850_elf_howto_table): Add entry for
R_V850_LO16_SPLIT_OFFSET.
(v850_elf_reloc_map): Map it to BFD_RELOC_V850_LO16_SPLIT_OFFSET.
(v850_elf_perform_lo16_relocation): New function, extracted from...
(v850_elf_perform_relocation): ...here. Use it to handle
R_V850_LO16_SPLIT_OFFSET.
(v850_elf_check_relocs, v850_elf_final_link_relocate): Handle
R_V850_LO16_SPLIT_OFFSET.
* libbfd.h, bfd-in2.h: Regenerate.
2004-12-14 P.J. Darcy <darcypj@us.ibm.com>
* config.bfd: Add s390x-ibm-tpf support.

View file

@ -2967,6 +2967,10 @@ bits placed non-contiguously in the instruction. */
/* Used to maintain alignment whilst relaxing. */
BFD_RELOC_V850_ALIGN,
/* This is a variation of BFD_RELOC_LO16 that can be used in v850e ld.bu
instructions. */
BFD_RELOC_V850_LO16_SPLIT_OFFSET,
/* This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the
instruction. */
BFD_RELOC_MN10300_32_PCREL,

View file

@ -533,6 +533,21 @@ static reloc_howto_type v850_elf_howto_table[] =
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* An ld.bu version of R_V850_LO16. */
HOWTO (R_V850_LO16_SPLIT_OFFSET, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_LO16_SPLIT_OFFSET", /* name */
FALSE, /* partial_inplace */
0xfffe0020, /* src_mask */
0xfffe0020, /* dst_mask */
FALSE), /* pcrel_offset */
};
/* Map BFD reloc types to V850 ELF reloc types. */
@ -567,6 +582,7 @@ static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
{ BFD_RELOC_V850_TDA_16_16_OFFSET, R_V850_TDA_16_16_OFFSET },
{ BFD_RELOC_V850_TDA_4_5_OFFSET, R_V850_TDA_4_5_OFFSET },
{ BFD_RELOC_V850_TDA_4_4_OFFSET, R_V850_TDA_4_4_OFFSET },
{ BFD_RELOC_V850_LO16_SPLIT_OFFSET, R_V850_LO16_SPLIT_OFFSET },
{ BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET },
{ BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET },
{ BFD_RELOC_V850_CALLT_6_7_OFFSET, R_V850_CALLT_6_7_OFFSET },
@ -687,6 +703,7 @@ v850_elf_check_relocs (abfd, info, sec, relocs)
case R_V850_HI16_S:
case R_V850_HI16:
case R_V850_LO16:
case R_V850_LO16_SPLIT_OFFSET:
case R_V850_ABS32:
case R_V850_REL32:
case R_V850_16:
@ -902,6 +919,187 @@ find_remembered_hi16s_reloc (addend, already_found)
return addr;
}
/* Calculate the final operand value for a R_V850_LO16 or
R_V850_LO16_SPLIT_OFFSET. *INSN is the current operand value and
ADDEND is the sum of the relocation symbol and offset. Store the
operand value in *INSN and return true on success.
The assembler has already done some of this: If the value stored in
the instruction has its 15th bit set, (counting from zero) then the
assembler will have added 1 to the value stored in the associated
HI16S reloc. So for example, these relocations:
movhi hi( fred ), r0, r1
movea lo( fred ), r1, r1
will store 0 in the value fields for the MOVHI and MOVEA instructions
and addend will be the address of fred, but for these instructions:
movhi hi( fred + 0x123456), r0, r1
movea lo( fred + 0x123456), r1, r1
the value stored in the MOVHI instruction will be 0x12 and the value
stored in the MOVEA instruction will be 0x3456. If however the
instructions were:
movhi hi( fred + 0x10ffff), r0, r1
movea lo( fred + 0x10ffff), r1, r1
then the value stored in the MOVHI instruction would be 0x11 (not
0x10) and the value stored in the MOVEA instruction would be 0xffff.
Thus (assuming for the moment that the addend is 0), at run time the
MOVHI instruction loads 0x110000 into r1, then the MOVEA instruction
adds 0xffffffff (sign extension!) producing 0x10ffff. Similarly if
the instructions were:
movhi hi( fred - 1), r0, r1
movea lo( fred - 1), r1, r1
then 0 is stored in the MOVHI instruction and -1 is stored in the
MOVEA instruction.
Overflow can occur if the addition of the value stored in the
instruction plus the addend sets the 15th bit when before it was clear.
This is because the 15th bit will be sign extended into the high part,
thus reducing its value by one, but since the 15th bit was originally
clear, the assembler will not have added 1 to the previous HI16S reloc
to compensate for this effect. For example:
movhi hi( fred + 0x123456), r0, r1
movea lo( fred + 0x123456), r1, r1
The value stored in HI16S reloc is 0x12, the value stored in the LO16
reloc is 0x3456. If we assume that the address of fred is 0x00007000
then the relocations become:
HI16S: 0x0012 + (0x00007000 >> 16) = 0x12
LO16: 0x3456 + (0x00007000 & 0xffff) = 0xa456
but when the instructions are executed, the MOVEA instruction's value
is signed extended, so the sum becomes:
0x00120000
+ 0xffffa456
------------
0x0011a456 but 'fred + 0x123456' = 0x0012a456
Note that if the 15th bit was set in the value stored in the LO16
reloc, then we do not have to do anything:
movhi hi( fred + 0x10ffff), r0, r1
movea lo( fred + 0x10ffff), r1, r1
HI16S: 0x0011 + (0x00007000 >> 16) = 0x11
LO16: 0xffff + (0x00007000 & 0xffff) = 0x6fff
0x00110000
+ 0x00006fff
------------
0x00116fff = fred + 0x10ffff = 0x7000 + 0x10ffff
Overflow can also occur if the computation carries into the 16th bit
and it also results in the 15th bit having the same value as the 15th
bit of the original value. What happens is that the HI16S reloc
will have already examined the 15th bit of the original value and
added 1 to the high part if the bit is set. This compensates for the
sign extension of 15th bit of the result of the computation. But now
there is a carry into the 16th bit, and this has not been allowed for.
So, for example if fred is at address 0xf000:
movhi hi( fred + 0xffff), r0, r1 [bit 15 of the offset is set]
movea lo( fred + 0xffff), r1, r1
HI16S: 0x0001 + (0x0000f000 >> 16) = 0x0001
LO16: 0xffff + (0x0000f000 & 0xffff) = 0xefff (carry into bit 16 is lost)
0x00010000
+ 0xffffefff
------------
0x0000efff but 'fred + 0xffff' = 0x0001efff
Similarly, if the 15th bit remains clear, but overflow occurs into
the 16th bit then (assuming the address of fred is 0xf000):
movhi hi( fred + 0x7000), r0, r1 [bit 15 of the offset is clear]
movea lo( fred + 0x7000), r1, r1
HI16S: 0x0000 + (0x0000f000 >> 16) = 0x0000
LO16: 0x7000 + (0x0000f000 & 0xffff) = 0x6fff (carry into bit 16 is lost)
0x00000000
+ 0x00006fff
------------
0x00006fff but 'fred + 0x7000' = 0x00016fff
Note - there is no need to change anything if a carry occurs, and the
15th bit changes its value from being set to being clear, as the HI16S
reloc will have already added in 1 to the high part for us:
movhi hi( fred + 0xffff), r0, r1 [bit 15 of the offset is set]
movea lo( fred + 0xffff), r1, r1
HI16S: 0x0001 + (0x00007000 >> 16)
LO16: 0xffff + (0x00007000 & 0xffff) = 0x6fff (carry into bit 16 is lost)
0x00010000
+ 0x00006fff (bit 15 not set, so the top half is zero)
------------
0x00016fff which is right (assuming that fred is at 0x7000)
but if the 15th bit goes from being clear to being set, then we must
once again handle overflow:
movhi hi( fred + 0x7000), r0, r1 [bit 15 of the offset is clear]
movea lo( fred + 0x7000), r1, r1
HI16S: 0x0000 + (0x0000ffff >> 16)
LO16: 0x7000 + (0x0000ffff & 0xffff) = 0x6fff (carry into bit 16)
0x00000000
+ 0x00006fff (bit 15 not set, so the top half is zero)
------------
0x00006fff which is wrong (assuming that fred is at 0xffff). */
static bfd_boolean
v850_elf_perform_lo16_relocation (bfd *abfd, unsigned long *insn,
unsigned long addend)
{
#define BIT15_SET(x) ((x) & 0x8000)
#define OVERFLOWS(a,i) ((((a) & 0xffff) + (i)) > 0xffff)
if ((BIT15_SET (*insn + addend) && ! BIT15_SET (addend))
|| (OVERFLOWS (addend, *insn)
&& ((! BIT15_SET (*insn)) || (BIT15_SET (addend)))))
{
bfd_boolean already_updated;
bfd_byte *hi16s_address = find_remembered_hi16s_reloc
(addend, & already_updated);
/* Amend the matching HI16_S relocation. */
if (hi16s_address != NULL)
{
if (! already_updated)
{
unsigned long hi_insn = bfd_get_16 (abfd, hi16s_address);
hi_insn += 1;
bfd_put_16 (abfd, hi_insn, hi16s_address);
}
}
else
{
fprintf (stderr, _("FAILED to find previous HI16 reloc\n"));
return FALSE;
}
}
#undef OVERFLOWS
#undef BIT15_SET
/* Do not complain if value has top bit set, as this has been
anticipated. */
*insn = (*insn + addend) & 0xffff;
return TRUE;
}
/* FIXME: The code here probably ought to be removed and the code in reloc.c
allowed to do its stuff instead. At least for most of the relocs, anyway. */
@ -913,6 +1111,7 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
bfd_byte *address;
{
unsigned long insn;
unsigned long result;
bfd_signed_vma saddend = (bfd_signed_vma) addend;
switch (r_type)
@ -972,183 +1171,10 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
break;
case R_V850_LO16:
/* Calculate the sum of the value stored in the instruction and the
addend and check for overflow from the low 16 bits into the high
16 bits. The assembler has already done some of this: If the
value stored in the instruction has its 15th bit set, (counting
from zero) then the assembler will have added 1 to the value
stored in the associated HI16S reloc. So for example, these
relocations:
movhi hi( fred ), r0, r1
movea lo( fred ), r1, r1
will store 0 in the value fields for the MOVHI and MOVEA instructions
and addend will be the address of fred, but for these instructions:
movhi hi( fred + 0x123456), r0, r1
movea lo( fred + 0x123456), r1, r1
the value stored in the MOVHI instruction will be 0x12 and the value
stored in the MOVEA instruction will be 0x3456. If however the
instructions were:
movhi hi( fred + 0x10ffff), r0, r1
movea lo( fred + 0x10ffff), r1, r1
then the value stored in the MOVHI instruction would be 0x11 (not
0x10) and the value stored in the MOVEA instruction would be 0xffff.
Thus (assuming for the moment that the addend is 0), at run time the
MOVHI instruction loads 0x110000 into r1, then the MOVEA instruction
adds 0xffffffff (sign extension!) producing 0x10ffff. Similarly if
the instructions were:
movhi hi( fred - 1), r0, r1
movea lo( fred - 1), r1, r1
then 0 is stored in the MOVHI instruction and -1 is stored in the
MOVEA instruction.
Overflow can occur if the addition of the value stored in the
instruction plus the addend sets the 15th bit when before it was clear.
This is because the 15th bit will be sign extended into the high part,
thus reducing its value by one, but since the 15th bit was originally
clear, the assembler will not have added 1 to the previous HI16S reloc
to compensate for this effect. For example:
movhi hi( fred + 0x123456), r0, r1
movea lo( fred + 0x123456), r1, r1
The value stored in HI16S reloc is 0x12, the value stored in the LO16
reloc is 0x3456. If we assume that the address of fred is 0x00007000
then the relocations become:
HI16S: 0x0012 + (0x00007000 >> 16) = 0x12
LO16: 0x3456 + (0x00007000 & 0xffff) = 0xa456
but when the instructions are executed, the MOVEA instruction's value
is signed extended, so the sum becomes:
0x00120000
+ 0xffffa456
------------
0x0011a456 but 'fred + 0x123456' = 0x0012a456
Note that if the 15th bit was set in the value stored in the LO16
reloc, then we do not have to do anything:
movhi hi( fred + 0x10ffff), r0, r1
movea lo( fred + 0x10ffff), r1, r1
HI16S: 0x0011 + (0x00007000 >> 16) = 0x11
LO16: 0xffff + (0x00007000 & 0xffff) = 0x6fff
0x00110000
+ 0x00006fff
------------
0x00116fff = fred + 0x10ffff = 0x7000 + 0x10ffff
Overflow can also occur if the computation carries into the 16th bit
and it also results in the 15th bit having the same value as the 15th
bit of the original value. What happens is that the HI16S reloc
will have already examined the 15th bit of the original value and
added 1 to the high part if the bit is set. This compensates for the
sign extension of 15th bit of the result of the computation. But now
there is a carry into the 16th bit, and this has not been allowed for.
So, for example if fred is at address 0xf000:
movhi hi( fred + 0xffff), r0, r1 [bit 15 of the offset is set]
movea lo( fred + 0xffff), r1, r1
HI16S: 0x0001 + (0x0000f000 >> 16) = 0x0001
LO16: 0xffff + (0x0000f000 & 0xffff) = 0xefff (carry into bit 16 is lost)
0x00010000
+ 0xffffefff
------------
0x0000efff but 'fred + 0xffff' = 0x0001efff
Similarly, if the 15th bit remains clear, but overflow occurs into
the 16th bit then (assuming the address of fred is 0xf000):
movhi hi( fred + 0x7000), r0, r1 [bit 15 of the offset is clear]
movea lo( fred + 0x7000), r1, r1
HI16S: 0x0000 + (0x0000f000 >> 16) = 0x0000
LO16: 0x7000 + (0x0000f000 & 0xffff) = 0x6fff (carry into bit 16 is lost)
0x00000000
+ 0x00006fff
------------
0x00006fff but 'fred + 0x7000' = 0x00016fff
Note - there is no need to change anything if a carry occurs, and the
15th bit changes its value from being set to being clear, as the HI16S
reloc will have already added in 1 to the high part for us:
movhi hi( fred + 0xffff), r0, r1 [bit 15 of the offset is set]
movea lo( fred + 0xffff), r1, r1
HI16S: 0x0001 + (0x00007000 >> 16)
LO16: 0xffff + (0x00007000 & 0xffff) = 0x6fff (carry into bit 16 is lost)
0x00010000
+ 0x00006fff (bit 15 not set, so the top half is zero)
------------
0x00016fff which is right (assuming that fred is at 0x7000)
but if the 15th bit goes from being clear to being set, then we must
once again handle overflow:
movhi hi( fred + 0x7000), r0, r1 [bit 15 of the offset is clear]
movea lo( fred + 0x7000), r1, r1
HI16S: 0x0000 + (0x0000ffff >> 16)
LO16: 0x7000 + (0x0000ffff & 0xffff) = 0x6fff (carry into bit 16)
0x00000000
+ 0x00006fff (bit 15 not set, so the top half is zero)
------------
0x00006fff which is wrong (assuming that fred is at 0xffff). */
{
long result;
insn = bfd_get_16 (abfd, address);
result = insn + addend;
#define BIT15_SET(x) ((x) & 0x8000)
#define OVERFLOWS(a,i) ((((a) & 0xffff) + (i)) > 0xffff)
if ((BIT15_SET (result) && ! BIT15_SET (addend))
|| (OVERFLOWS (addend, insn)
&& ((! BIT15_SET (insn)) || (BIT15_SET (addend)))))
{
bfd_boolean already_updated;
bfd_byte *hi16s_address = find_remembered_hi16s_reloc
(addend, & already_updated);
/* Amend the matching HI16_S relocation. */
if (hi16s_address != NULL)
{
if (! already_updated)
{
insn = bfd_get_16 (abfd, hi16s_address);
insn += 1;
bfd_put_16 (abfd, (bfd_vma) insn, hi16s_address);
}
}
else
{
fprintf (stderr, _("FAILED to find previous HI16 reloc\n"));
return bfd_reloc_overflow;
}
}
/* Do not complain if value has top bit set, as this has been anticipated. */
insn = result & 0xffff;
break;
}
insn = bfd_get_16 (abfd, address);
if (! v850_elf_perform_lo16_relocation (abfd, &insn, addend))
return bfd_reloc_overflow;
break;
case R_V850_8:
addend += (char) bfd_get_8 (abfd, address);
@ -1278,6 +1304,17 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
insn |= addend;
break;
case R_V850_LO16_SPLIT_OFFSET:
insn = bfd_get_32 (abfd, address);
result = ((insn & 0xfffe0000) >> 16) | ((insn & 0x20) >> 5);
if (! v850_elf_perform_lo16_relocation (abfd, &result, addend))
return bfd_reloc_overflow;
insn = (((result << 16) & 0xfffe0000)
| ((result << 5) & 0x20)
| (insn & ~0xfffe0020));
bfd_put_32 (abfd, insn, address);
return bfd_reloc_ok;
case R_V850_ZDA_16_16_SPLIT_OFFSET:
case R_V850_SDA_16_16_SPLIT_OFFSET:
insn = bfd_get_32 (abfd, address);
@ -1492,6 +1529,7 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
case R_V850_HI16_S:
case R_V850_HI16:
case R_V850_LO16:
case R_V850_LO16_SPLIT_OFFSET:
case R_V850_16:
case R_V850_ABS32:
case R_V850_8:

View file

@ -1299,6 +1299,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_V850_LONGCALL",
"BFD_RELOC_V850_LONGJUMP",
"BFD_RELOC_V850_ALIGN",
"BFD_RELOC_V850_LO16_SPLIT_OFFSET",
"BFD_RELOC_MN10300_32_PCREL",
"BFD_RELOC_MN10300_16_PCREL",
"BFD_RELOC_TIC30_LDP",

View file

@ -3098,6 +3098,11 @@ ENUM
BFD_RELOC_V850_ALIGN
ENUMDOC
Used to maintain alignment whilst relaxing.
ENUM
BFD_RELOC_V850_LO16_SPLIT_OFFSET
ENUMDOC
This is a variation of BFD_RELOC_LO16 that can be used in v850e ld.bu
instructions.
ENUM
BFD_RELOC_MN10300_32_PCREL
ENUMDOC

View file

@ -1,3 +1,9 @@
2004-12-16 Richard Sandiford <rsandifo@redhat.com>
* config/tc-v850.c (handle_lo16): New function.
(v850_reloc_prefix): Use it to check lo().
(md_assemble, md_apply_fix3): Handle BFD_RELOC_V850_LO16_SPLIT_OFFSET.
2004-12-14 P.J. Darcy <darcypj@us.ibm.com>
* configure.in: Add s390x-ibm-tpf support.

View file

@ -1375,6 +1375,25 @@ md_begin ()
bfd_set_arch_mach (stdoutput, TARGET_ARCH, machine);
}
static bfd_reloc_code_real_type
handle_lo16 (const struct v850_operand *operand)
{
if (operand != NULL)
{
if (operand->bits == -1)
return BFD_RELOC_V850_LO16_SPLIT_OFFSET;
if (!(operand->bits == 16 && operand->shift == 16)
&& !(operand->bits == 15 && operand->shift == 17))
{
as_bad (_("lo() relocation used on an instruction which does "
"not support it"));
return BFD_RELOC_64; /* Used to indicate an error condition. */
}
}
return BFD_RELOC_LO16;
}
static bfd_reloc_code_real_type handle_ctoff
PARAMS ((const struct v850_operand *));
@ -1516,7 +1535,7 @@ v850_reloc_prefix (operand)
CHECK_ ("hi0", BFD_RELOC_HI16 );
CHECK_ ("hi", BFD_RELOC_HI16_S );
CHECK_ ("lo", BFD_RELOC_LO16 );
CHECK_ ("lo", handle_lo16 (operand) );
CHECK_ ("sdaoff", handle_sdaoff (operand));
CHECK_ ("zdaoff", handle_zdaoff (operand));
CHECK_ ("tdaoff", handle_tdaoff (operand));
@ -1755,6 +1774,7 @@ md_assemble (str)
/* Fall through. */
case BFD_RELOC_LO16:
case BFD_RELOC_V850_LO16_SPLIT_OFFSET:
{
/* Truncate, then sign extend the value. */
ex.X_add_number = SEXT16 (ex.X_add_number);
@ -2199,6 +2219,7 @@ md_assemble (str)
switch (reloc)
{
case BFD_RELOC_LO16:
case BFD_RELOC_V850_LO16_SPLIT_OFFSET:
case BFD_RELOC_HI16:
case BFD_RELOC_HI16_S:
fixP->fx_no_overflow = 1;
@ -2405,7 +2426,11 @@ md_apply_fix3 (fixP, valueP, seg)
/* We still have to insert the value into memory! */
where = fixP->fx_frag->fr_literal + fixP->fx_where;
if (fixP->fx_size == 1)
if (fixP->fx_r_type == BFD_RELOC_V850_LO16_SPLIT_OFFSET)
bfd_putl32 (((value << 16) & 0xfffe0000)
| ((value << 5) & 0x20)
| (bfd_getl32 (where) & ~0xfffe0020), where);
else if (fixP->fx_size == 1)
*where = value & 0xff;
else if (fixP->fx_size == 2)
bfd_putl16 (value & 0xffff, (unsigned char *) where);

View file

@ -1,3 +1,8 @@
2004-12-16 Richard Sandiford <rsandifo@redhat.com>
* gas/v850/split-lo16.{s,d}: New test.
* gas/v850/v850.exp: Run it.
2004-12-15 Jan Beulich <jbeulich@novell.com>
* gas/elf/section5.[els]: New.

View file

@ -436,4 +436,5 @@ if [istarget v850*-*-*] then {
gas_test_error "range.s" "-mwarn-signed-overflow" "Check for range error on byte load/store"
run_dump_test "v850e1"
run_dump_test "split-lo16"
}

View file

@ -0,0 +1,16 @@
#objdump: -dr
#name: V850E split LO16 tests
#as: -mv850e
#...
00000000 <.*>:
0: 40 0e 00 00 movhi 0, r0, r1
2: R_V850_HI16_S foo
4: 01 16 00 00 addi 0, r1, r2
6: R_V850_LO16 foo
8: 01 17 00 00 ld\.b 0\[r1\],r2
a: R_V850_LO16 foo
c: 81 17 01 00 ld\.bu 0\[r1\],r2
c: R_V850_LO16_SPLIT_OFFSET foo
10: a1 17 45 23 ld\.bu 9029\[r1\],r2
14: 81 17 57 34 ld\.bu 13398\[r1\],r2
#pass

View file

@ -0,0 +1,7 @@
movhi hi(foo),r0,r1
addi lo(foo),r1,r2
ld.b lo(foo),r1,r2
ld.bu lo(foo),r1,r2
ld.bu lo(0x12345),r1,r2
ld.bu lo(0x123456),r1,r2

View file

@ -1,3 +1,7 @@
2004-12-16 Richard Sandiford <rsandifo@redhat.com>
* v850.h (R_V850_LO16_SPLIT_OFFSET): New reloc.
2004-12-09 Ian Lance Taylor <ian@wasabisystems.com>
* mips.h (E_MIPS_MACH_9000): Define.

View file

@ -79,6 +79,7 @@ START_RELOC_NUMBERS (v850_reloc_type)
RELOC_NUMBER (R_V850_LONGJUMP, 26)
RELOC_NUMBER (R_V850_ALIGN, 27)
RELOC_NUMBER (R_V850_REL32, 28)
RELOC_NUMBER (R_V850_LO16_SPLIT_OFFSET, 29) /* For ld.bu */
END_RELOC_NUMBERS (R_V850_max)

View file

@ -1,3 +1,7 @@
2004-12-16 Richard Sandiford <rsandifo@redhat.com>
* ld-v850: New directory.
2004-12-14 Richard Sandiford <rsandifo@redhat.com>
* ld-mips-elf/jal-overflow-2.[sd]: New test.

View file

@ -0,0 +1,26 @@
#source: split-lo16.s -mv850e
#ld: -Tsplit-lo16.ld
#objdump: -d
#...
00010000 <.*>:
10000: 40 0e 34 12 movhi 4660, r0, r1
10004: 01 16 78 56 addi 22136, r1, r2
10008: 81 17 79 56 ld\.bu 22136\[r1\],r2
1000c: 40 0e 36 12 movhi 4662, r0, r1
10010: 01 16 78 d8 addi -10120, r1, r2
10014: 81 17 79 d8 ld\.bu -10120\[r1\],r2
10018: 40 0e 12 00 movhi 18, r0, r1
1001c: 81 17 57 34 ld\.bu 13398\[r1\],r2
10020: 01 16 56 34 addi 13398, r1, r2
10024: 40 0e 14 00 movhi 20, r0, r1
10028: 81 17 57 b6 ld\.bu -18858\[r1\],r2
1002c: 01 16 56 b6 addi -18858, r1, r2
10030: 40 0e 79 56 movhi 22137, r0, r1
10034: 01 16 bc 9a addi -25924, r1, r2
10038: 81 17 bd 9a ld\.bu -25924\[r1\],r2
1003c: 40 0e 9b 78 movhi 30875, r0, r1
10040: 81 17 df bc ld\.bu -17186\[r1\],r2
10044: 01 16 de bc addi -17186, r1, r2
10048: 40 0e 45 23 movhi 9029, r0, r1
1004c: a1 17 89 67 ld\.bu 26505\[r1\],r2
#pass

View file

@ -0,0 +1,11 @@
SECTIONS
{
lo16_carry = 0x56789abc;
lo16_nocarry = 0x12345678;
split_lo16_carry = 0x789abcde;
split_lo16_nocarry = 0x00123456;
odd = 0x23456789;
. = 0x10000;
.text : { *(.text); }
/DISCARD/ : { *(*); }
}

View file

@ -0,0 +1,20 @@
movhi hi(lo16_nocarry),r0,r1
addi lo(lo16_nocarry),r1,r2
ld.bu lo(lo16_nocarry)[r1],r2
movhi hi(lo16_nocarry + 0x18200),r0,r1
addi lo(lo16_nocarry + 0x18200),r1,r2
ld.bu lo(lo16_nocarry + 0x18200)[r1],r2
movhi hi(split_lo16_nocarry),r0,r1
ld.bu lo(split_lo16_nocarry)[r1],r2
addi lo(split_lo16_nocarry),r1,r2
movhi hi(split_lo16_nocarry + 0x18200),r0,r1
ld.bu lo(split_lo16_nocarry + 0x18200)[r1],r2
addi lo(split_lo16_nocarry + 0x18200),r1,r2
movhi hi(lo16_carry),r0,r1
addi lo(lo16_carry),r1,r2
ld.bu lo(lo16_carry)[r1],r2
movhi hi(split_lo16_carry),r0,r1
ld.bu lo(split_lo16_carry)[r1],r2
addi lo(split_lo16_carry),r1,r2
movhi hi(odd),r0,r1
ld.bu lo(odd)[r1],r2

View file

@ -0,0 +1,3 @@
if [istarget v850*-*-*] {
run_dump_test "split-lo16"
}