This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH, ARM] Re-use VFP encoding functions for VLDR/VSTR
- From: Julian Brown <julian at codesourcery dot com>
- To: binutils at sources dot redhat dot com
- Cc: Mark Shinwell <shinwell at codesourcery dot com>, Paul Brook <paul at codesourcery dot com>
- Date: Mon, 05 Jun 2006 14:51:37 +0100
- Subject: [PATCH, ARM] Re-use VFP encoding functions for VLDR/VSTR
Hi,
This patch removes some redundant code in the gas support for the
VFP/Neon instructions VLDR/VSTR, and uses the previous VFP routines
instead. (The syntax is basically the same apart from the initial
mnemonic, and the do_vfp_nsyn_opcode function wasn't there when
do_neon_ldr_str was initially written.)
This fixes a problem that the VLDR/VSTR instructions don't currently
handle relocations properly, so e.g. offsets had to be fixed at parsing
time. A followup patch (Mark Shinwell) tests that functionality further.
This patch alone tests ok with "make check" with cross to arm-none-eabi.
OK for mainline? The csl branch?
Cheers,
Julian
ChangeLog:
* config/tc-arm.c (do_vfp_nsyn_ldr_str): Remove, fold into...
(do_neon_ldr_str): Always defer to VFP encoding routines, which
handle relocs properly.
Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.250.2.16
diff -c -p -r1.250.2.16 tc-arm.c
*** gas/config/tc-arm.c 15 May 2006 20:46:24 -0000 1.250.2.16
--- gas/config/tc-arm.c 5 Jun 2006 13:40:45 -0000
*************** do_vfp_nsyn_ldm_stm (int is_dbmode)
*** 10620,10634 ****
}
static void
- do_vfp_nsyn_ldr_str (int is_ldr)
- {
- if (is_ldr)
- do_vfp_nsyn_opcode ("flds");
- else
- do_vfp_nsyn_opcode ("fsts");
- }
-
- static void
do_vfp_nsyn_sqrt (void)
{
enum neon_shape rs = neon_select_shape (NS_FF, NS_DD, NS_NULL);
--- 10620,10625 ----
*************** do_neon_ldm_stm (void)
*** 12650,12707 ****
static void
do_neon_ldr_str (void)
{
- unsigned offsetbits;
- int offset_up = 1;
int is_ldr = (inst.instruction & (1 << 20)) != 0;
if (inst.operands[0].issingle)
{
! do_vfp_nsyn_ldr_str (is_ldr);
! return;
! }
!
! inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
! inst.instruction |= HI1 (inst.operands[0].reg) << 22;
!
! constraint (inst.reloc.pc_rel && !is_ldr,
! _("PC-relative addressing unavailable with VSTR"));
!
! constraint (!inst.reloc.pc_rel && inst.reloc.exp.X_op != O_constant,
! _("Immediate value must be a constant"));
!
! if (inst.reloc.exp.X_add_number < 0)
! {
! offset_up = 0;
! offsetbits = -inst.reloc.exp.X_add_number / 4;
}
else
- offsetbits = inst.reloc.exp.X_add_number / 4;
-
- /* FIXME: Does this catch everything? */
- constraint (!inst.operands[1].isreg || !inst.operands[1].preind
- || inst.operands[1].postind || inst.operands[1].writeback
- || inst.operands[1].immisreg || inst.operands[1].shifted,
- BAD_ADDR_MODE);
- constraint ((inst.operands[1].imm & 3) != 0,
- _("Offset must be a multiple of 4"));
- constraint (offsetbits != (offsetbits & 0xff),
- _("Immediate offset out of range"));
-
- inst.instruction |= inst.operands[1].reg << 16;
- inst.instruction |= offsetbits & 0xff;
- inst.instruction |= offset_up << 23;
-
- do_vfp_cond_or_thumb ();
-
- if (inst.reloc.pc_rel)
{
! if (thumb_mode)
! inst.reloc.type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
else
! inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
}
- else
- inst.reloc.type = BFD_RELOC_UNUSED;
}
/* "interleave" version also handles non-interleaving register VLD1/VST1
--- 12641,12662 ----
static void
do_neon_ldr_str (void)
{
int is_ldr = (inst.instruction & (1 << 20)) != 0;
if (inst.operands[0].issingle)
{
! if (is_ldr)
! do_vfp_nsyn_opcode ("flds");
! else
! do_vfp_nsyn_opcode ("fsts");
}
else
{
! if (is_ldr)
! do_vfp_nsyn_opcode ("fldd");
else
! do_vfp_nsyn_opcode ("fstd");
}
}
/* "interleave" version also handles non-interleaving register VLD1/VST1