This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]