This is the mail archive of the
cgen@sources.redhat.com
mailing list for the CGEN project.
Possible reloc patch (2/2)
- To: <cgen at sources dot redhat dot com>
- Subject: Possible reloc patch (2/2)
- From: Richard Sandiford <rsandifo at cygnus dot com>
- Date: Tue, 23 Jan 2001 18:31:20 +0000 (GMT)
Following up on my previous message about fixups. When you don't provide
a custom operand parser, CGEN generates standard relocs like BFD_RELOC_16
and BFD_RELOC_32 for external addresses. But the associated fixup regions
seem to describe the whole instruction rather than the operand itself.
I find that if I have an instruction with a 32-bit reloc in the second
word of a 64-bit insn, the reloc is generated for the first 32-bits rather
than the second.
Looking at the way CGEN handles fixups, it seems that:
- when gas_cgen_finish_insn() creates a fixup,
+ FX_WHERE points to the start of the instruction
+ FX_SIZE is the length of the instruction in bytes
+ FX_R_TYPE contains an encoding of the operand index
- these values are unchanged when gas_cgen_md_apply_fix3() is called.
The function needs FX_WHERE to point to the start of the instruction,
because it can call operand insertion routines, which want the same
thing.
- When passed a fixup generated by gas_cgen_finish_insn(),
gas_cgen_md_apply_fix3() tries to resolve the fixup. If it
can't, it replaces FX_R_TYPE with the real BFD reloc type
(which might be BFD_RELOC_16, BFD_RELOC_32, etc., or some
custom reloc).
- When it changes FX_R_TYPE, it doesn't change FX_WHERE or FX_SIZE,
so the fixup region is still the complete instruction.
The question is, is adjusting the reloc region to the operand always
the correct behaviour? The following patch works for me, but I don't
know if this new behaviour is appropriate for custom relocs.
Richard
2001-01-23 Richard Sandiford <r.sandiford@redhat.com>
* cgen.c (gas_cgen_md_apply_fix3): If we generate a reloc for
the fixup, adjust the fixup region so that it describes the
operand rather than the whole instruction.
Index: ./gas/cgen.c
===================================================================
RCS file: /cvs/src/src/gas/cgen.c,v
retrieving revision 1.8
diff -c -d -p -r1.8 cgen.c
*** ./gas/cgen.c 2001/01/12 23:34:43 1.8
--- ./gas/cgen.c 2001/01/23 18:28:34
*************** gas_cgen_md_apply_fix3 (fixP, valueP, se
*** 590,595 ****
--- 590,601 ----
reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
if (reloc_type != BFD_RELOC_NONE)
{
+ const CGEN_IFLD *field;
+
+ field = cgen_ifield_lookup_by_num (gas_cgen_cpu_desc,
+ operand->ifield);
+ fixP->fx_where += field->word_offset / 8;
+ fixP->fx_size = field->length / 8;
fixP->fx_r_type = reloc_type;
}
else