This is the mail archive of the binutils@sources.redhat.com 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]

ARM GAS: unpredictable writeback in LDM/STM


Hi Guys,

  The ARM LDM and STM instructions can be UNPREDICTABLE if the
  writeback bit is used incorrectly, but GAS was not issuing warning
  about such instructions.  The (soon to be applied) patch below adds
  these warnings.

  I will shortly be checking in a related patch to GCC to make it stop
  generating such unpredictable instructions. :-)

Cheers
        Nick

2002-09-17  Nick Clifton  <nickc@redhat.com>

	* config/tc-arm.c (do_ldmstm): Warn about unpredictable
	behavior of instructions.

Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.128
diff -c -3 -p -w -r1.128 tc-arm.c
*** gas/config/tc-arm.c	5 Sep 2002 00:01:16 -0000	1.128
--- gas/config/tc-arm.c	17 Sep 2002 18:53:38 -0000
*************** do_ldmstm (str)
*** 5766,5771 ****
--- 5766,5796 ----
        inst.instruction |= LDM_TYPE_2_OR_3;
      }
  
+   if (inst.instruction & WRITE_BACK)
+     {
+       /* Check for unpredictable uses of writeback.  */
+       if (inst.instruction & LOAD_BIT)
+ 	{
+ 	  /* Not allowed in LDM type 2.  */
+ 	  if ((inst.instruction & LDM_TYPE_2_OR_3)
+ 	      && ((range & (1 << REG_PC)) == 0))
+ 	    as_warn (_("writeback of base register is UNPREDICTABLE"));
+ 	  /* Only allowed if base reg not in list for other types.  */
+ 	  else if (range & (1 << base_reg))
+ 	    as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
+ 	}
+       else /* STM.  */
+ 	{
+ 	  /* Not allowed for type 2.  */
+ 	  if (inst.instruction & LDM_TYPE_2_OR_3)
+ 	    as_warn (_("writeback of base register is UNPREDICTABLE"));
+ 	  /* Only allowed if base reg not in list, or first in list.  */
+ 	  else if ((range & (1 << base_reg))
+ 		   && (range & ((1 << base_reg) - 1)))
+ 	    as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
+ 	}
+     }
+   
    inst.instruction |= range;
    end_of_line (str);
    return;


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