aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-d10v.c
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2001-12-04 17:30:43 +0000
committerAlexandre Oliva <aoliva@redhat.com>2001-12-04 17:30:43 +0000
commitc2c607a4885b1b9b36371f3873086de591abbb8c (patch)
tree5313f2250d257a7fc07a5a2cb0b2385ce9820dae /gas/config/tc-d10v.c
parent2d842f13592bfef71b23c428f6b951e62bdea014 (diff)
downloadfsf-binutils-gdb-c2c607a4885b1b9b36371f3873086de591abbb8c.zip
fsf-binutils-gdb-c2c607a4885b1b9b36371f3873086de591abbb8c.tar.gz
fsf-binutils-gdb-c2c607a4885b1b9b36371f3873086de591abbb8c.tar.bz2
* config/tc-d10v.c (write_2_short): Don't skip dummy fixups, so
that we can tell which operand refers to the insn put in the L container and mark it as such, so that the relocation type can be adjusted.
Diffstat (limited to 'gas/config/tc-d10v.c')
-rw-r--r--gas/config/tc-d10v.c46
1 files changed, 18 insertions, 28 deletions
diff --git a/gas/config/tc-d10v.c b/gas/config/tc-d10v.c
index 5238fb9..0dbf98a 100644
--- a/gas/config/tc-d10v.c
+++ b/gas/config/tc-d10v.c
@@ -799,22 +799,14 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
else if (opcode2->unit == MU)
insn = FM00 | (insn2 << 15) | insn1;
else
- {
- insn = FM00 | (insn1 << 15) | insn2;
- /* Advance over dummy fixup since packed insn1 in L. */
- fx = fx->next;
- }
+ insn = FM00 | (insn1 << 15) | insn2;
}
else if (opcode1->unit == IU)
/* Reverse sequential with IU opcode1 on right and done first. */
insn = FM10 | (insn2 << 15) | insn1;
else
- {
- /* Sequential with non-IU opcode1 on left and done first. */
- insn = FM01 | (insn1 << 15) | insn2;
- /* Advance over dummy fixup since packed insn1 in L. */
- fx = fx->next;
- }
+ /* Sequential with non-IU opcode1 on left and done first. */
+ insn = FM01 | (insn1 << 15) | insn2;
break;
case PACK_PARALLEL:
@@ -838,11 +830,7 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
insn = FM00 | (insn2 << 15) | insn1;
}
else
- {
- insn = FM00 | (insn1 << 15) | insn2;
- /* Advance over dummy fixup since packed insn1 in L. */
- fx = fx->next;
- }
+ insn = FM00 | (insn1 << 15) | insn2;
break;
case PACK_LEFT_RIGHT:
@@ -858,8 +846,6 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
as_fatal (_("IU instruction may not be in the left container"));
if (opcode1->exec_type & ALONE)
as_warn (_("Instruction in R container is squashed by flow control instruction in L container."));
- /* Advance over dummy fixup. */
- fx = fx->next;
break;
case PACK_RIGHT_LEFT:
@@ -875,8 +861,6 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
as_fatal (_("MU instruction may not be in the right container"));
if (opcode2->exec_type & ALONE)
as_warn (_("Instruction in R container is squashed by flow control instruction in L container."));
- /* Advance over dummy fixup. */
- fx = fx->next;
break;
default:
@@ -886,13 +870,8 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
f = frag_more (4);
number_to_chars_bigendian (f, insn, 4);
- /* Process fixup chains.
- Note that the packing code above advanced fx conditionally.
- dlindsay@cygnus.com: There's something subtle going on here involving
- _dummy_first_bfd_reloc_code_real. This is related to the
- difference between BFD_RELOC_D10V_10_PCREL_R and _L, ie whether
- a fixup is done in the L or R container. A bug in this code
- can pass Plum Hall fine, yet still affect hand-written assembler. */
+ /* Process fixup chains. fx refers to insn2 when j == 0, and to
+ insn1 when j == 1. Yes, it's reversed. */
for (j = 0; j < 2; j++)
{
@@ -904,7 +883,18 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
if (fx->fix[i].size == 2)
where += 2;
- if ((fx->fix[i].reloc == BFD_RELOC_D10V_10_PCREL_R) && (j == 0))
+ if (fx->fix[i].reloc == BFD_RELOC_D10V_10_PCREL_R
+ /* A BFD_RELOC_D10V_10_PCREL_R relocation applied to
+ the instruction in the L container has to be
+ adjusted to BDF_RELOC_D10V_10_PCREL_L. When
+ j==0, we're processing insn2's operands, so we
+ want to mark the operand if insn2 is *not* in the
+ R container. When j==1, we're processing insn1's
+ operands, so we want to mark the operand if insn2
+ *is* in the R container. Note that, if two
+ instructions are identical, we're never going to
+ swap them, so the test is safe. */
+ && j == ((insn & 0x7fff) == insn2))
fx->fix[i].operand |= 1024;
if (fx->fix[i].reloc == BFD_RELOC_D10V_18)