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]

Re: [patch] Arm FPA stfpls


> The problem instructions are {ldf,stf,cmp,cmn,teq,tst}pls, all of which
> change meaning if you try to apply the new UAL rules to them.  (on the
> comparison instructions above, the 's' was redundant but accepted by the
> assembler in legacy mode).
>
> The intent of UAL is that existing ARM code (but not thumb) can be
> re-assembled in UAL mode without changing the meaning.  The above kind
> of break this intent if you apply the new rules strictly.  I've
> discussed this with a colleague and we have concluded that for these
> instructions only, the UAL interpretation should be the same as the
> traditional interpretation: that is, they should continue to use the
> infix notation.

Attached patch implements this. 

Tested with cross to arm-unknown-eabi.
Ok?

Paul

2005-09-02  Paul Brook  <paul@codeourcery.com>

gas/
	* config/tc-arm.c (opcode_tag): Add OT_cinfix3_pls.
	(opcode_lookup): Handle OT_cinfix3_pls.  Revert earlier change for
	normal infix conditions.
	(CP, cCP): Define.
	(insns): Use them for ambiguous mnemonics.
	* gas/arm/fpa-mem.s: Update comments. Add unambiguous conditional
	mnemonics.
	* gas/arm/fpa-mem.d: Update expected results.  Suppress warnings.
Index: gas/config/tc-arm.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/config/tc-arm.c,v
retrieving revision 1.222
diff -u -p -r1.222 tc-arm.c
--- gas/config/tc-arm.c	2 Sep 2005 13:12:39 -0000	1.222
+++ gas/config/tc-arm.c	2 Sep 2005 15:06:22 -0000
@@ -7547,6 +7547,9 @@ enum opcode_tag
   OT_cinfix3,		/* Instruction takes a conditional infix,
 			   beginning at character index 3.  (In
 			   unified mode, it becomes a suffix.)  */
+  OT_cinfix3_pls,	/* Instruction that may be ambiguous between infix
+			   and suffix mode.  The ambiguous case ("PLS") is
+			   always treated as <opcode>S conditional PL.  */
   OT_csuf_or_in3,	/* Instruction takes either a conditional
 			   suffix or an infix at character index 3.
 			   (In unified mode, a suffix only.  */
@@ -7681,12 +7684,17 @@ opcode_lookup (char **str)
       /* step CE */
       switch (opcode->tag)
 	{
+	case OT_cinfix3_pls:
+	  /* Some legacy mnemonics are ambiguous between infix and suffix
+	     conditions.  For backwards compatibility these are always
+	     treated as the infix version.  */
+	  if (cond->value == 9) /* LS */
+	    break;
+	  /* else fall through */
 	case OT_cinfix3:
 	case OT_odd_infix_unc:
-	  /* Some mnemonics are ambiguous between infix and suffix
-	     conditions.  Disambiguate based on assembly syntax.  */
 	  if (!unified_syntax)
-	    break;
+	    return 0;
 	  /* else fall through */
 
 	case OT_csuffix:
@@ -7723,7 +7731,8 @@ opcode_lookup (char **str)
       memmove (affix + 2, affix, (end - affix) - 2);
       memcpy (affix, save, 2);
     }
-  if (opcode && (opcode->tag == OT_cinfix3 || opcode->tag == OT_csuf_or_in3))
+  if (opcode && (opcode->tag == OT_cinfix3 || opcode->tag == OT_csuf_or_in3
+		 || opcode->tag == OT_cinfix3_pls))
     {
       /* step CM */
       if (unified_syntax)
@@ -8260,6 +8269,10 @@ static const struct asm_cond conds[] =
 #define C3(mnem, op, nops, ops, ae)	\
   { #mnem, OPS##nops ops, OT_cinfix3, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
 
+/* Special variant of C3 for mnemonics that may end in "pls".  */
+#define CP(mnem, op, nops, ops, ae)	\
+  { #mnem, OPS##nops ops, OT_cinfix3_pls, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
+
 /* Coprocessor instructions.  Isomorphic between Arm and Thumb-2.  */
 #define cCE(mnem,  op, nops, ops, ae)	\
   { #mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
@@ -8267,6 +8280,10 @@ static const struct asm_cond conds[] =
 #define cC3(mnem, op, nops, ops, ae)	\
   { #mnem, OPS##nops ops, OT_cinfix3, 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
 
+/* Special variant of cC3 for mnemonics that may end in "pls".  */
+#define cCP(mnem, op, nops, ops, ae)	\
+  { #mnem, OPS##nops ops, OT_cinfix3_pls, 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
+
 #define xCM_(m1, m2, m3, op, nops, ops, ae)	\
   { #m1 #m2 #m3, OPS##nops ops, \
     sizeof(#m2) == 1 ? OT_odd_infix_unc : OT_odd_infix_0 + sizeof(#m1) - 1, \
@@ -8335,13 +8352,13 @@ static const struct asm_opcode insns[] =
     have Thumb equivalents. */
  tCE(tst,	1100000, tst,	   2, (RR, SH),      cmp,  t_mvn_tst),
  tC3(tsts,	1100000, tst,	   2, (RR, SH),      cmp,  t_mvn_tst),
-  C3(tstp,	110f000,     	   2, (RR, SH),      cmp),
+  CP(tstp,	110f000,     	   2, (RR, SH),      cmp),
  tCE(cmp,	1500000, cmp,	   2, (RR, SH),      cmp,  t_mov_cmp),
  tC3(cmps,	1500000, cmp,	   2, (RR, SH),      cmp,  t_mov_cmp),
-  C3(cmpp,	150f000,     	   2, (RR, SH),      cmp),
+  CP(cmpp,	150f000,     	   2, (RR, SH),      cmp),
  tCE(cmn,	1700000, cmn,	   2, (RR, SH),      cmp,  t_mvn_tst),
  tC3(cmns,	1700000, cmn,	   2, (RR, SH),      cmp,  t_mvn_tst),
-  C3(cmnp,	170f000,     	   2, (RR, SH),      cmp),
+  CP(cmnp,	170f000,     	   2, (RR, SH),      cmp),
 
  tCE(mov,	1a00000, mov,	   2, (RR, SH),      mov,  t_mov_cmp),
  tC3(movs,	1b00000, movs,	   2, (RR, SH),      mov,  t_mov_cmp),
@@ -8392,7 +8409,7 @@ static const struct asm_opcode insns[] =
  TC3(rsbs,	0700000, ebd00000, 3, (RR, oRR, SH), arit, t_rsb),
  TCE(teq,	1300000, ea900f00, 2, (RR, SH),      cmp,  t_mvn_tst),
  TC3(teqs,	1300000, ea900f00, 2, (RR, SH),      cmp,  t_mvn_tst),
-  C3(teqp,	130f000,           2, (RR, SH),      cmp),
+  CP(teqp,	130f000,           2, (RR, SH),      cmp),
 
  TC3(ldrt,	4300000, f8500e00, 2, (RR, ADDR),    ldstt, t_ldstt),
  TC3(ldrbt,	4700000, f8300e00, 2, (RR, ADDR),    ldstt, t_ldstt),
@@ -8724,12 +8741,12 @@ static const struct asm_opcode insns[] =
  cC3(ldfs,	c100100, 2, (RF, ADDR),	     rd_cpaddr),
  cC3(ldfd,	c108100, 2, (RF, ADDR),	     rd_cpaddr),
  cC3(ldfe,	c500100, 2, (RF, ADDR),	     rd_cpaddr),
- cC3(ldfp,	c508100, 2, (RF, ADDR),	     rd_cpaddr),
+ cCP(ldfp,	c508100, 2, (RF, ADDR),	     rd_cpaddr),
 
  cC3(stfs,	c000100, 2, (RF, ADDR),	     rd_cpaddr),
  cC3(stfd,	c008100, 2, (RF, ADDR),	     rd_cpaddr),
  cC3(stfe,	c400100, 2, (RF, ADDR),	     rd_cpaddr),
- cC3(stfp,	c408100, 2, (RF, ADDR),	     rd_cpaddr),
+ cCP(stfp,	c408100, 2, (RF, ADDR),	     rd_cpaddr),
 
  cC3(mvfs,	e008100, 2, (RF, RF_IF),     rd_rm),
  cC3(mvfsp,	e008120, 2, (RF, RF_IF),     rd_rm),
Index: gas/testsuite/gas/arm/fpa-mem.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/testsuite/gas/arm/fpa-mem.d,v
retrieving revision 1.5
diff -u -p -r1.5 fpa-mem.d
--- gas/testsuite/gas/arm/fpa-mem.d	2 Sep 2005 12:50:44 -0000	1.5
+++ gas/testsuite/gas/arm/fpa-mem.d	2 Sep 2005 15:19:20 -0000
@@ -1,6 +1,7 @@
 #objdump: -dr --prefix-addresses --show-raw-insn
 #name: FPA memory insructions
-#as: -mfpu=fpa10 -mcpu=arm7m
+# Suppress warnings about infix operands
+#as: -mfpu=fpa10 -mcpu=arm7m -W
 
 # Test FPA memory instructions
 # This test should work for both big and little-endian assembly.
@@ -31,4 +32,8 @@ Disassembly of section .text:
 0+50 <[^>]*> ed00020c ?	sfm	f0, 4, \[r0, #-48\]
 0+54 <[^>]*> ed800200 ?	sfm	f0, 4, \[r0\]
 0+58 <[^>]*> 5d800100 ?	stfpls	f0, \[r0\]
-0+5c <[^>]*> 9dc08100 ?	stflsp	f0, \[r0\]
+0+5c <[^>]*> 5d800100 ?	stfpls	f0, \[r0\]
+0+60 <[^>]*> 1d800100 ?	stfnes	f0, \[r0\]
+0+64 <[^>]*> 1d800100 ?	stfnes	f0, \[r0\]
+0+68 <[^>]*> 1dc08100 ?	stfnep	f0, \[r0\]
+0+6c <[^>]*> 1dc08100 ?	stfnep	f0, \[r0\]
Index: gas/testsuite/gas/arm/fpa-mem.s
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/testsuite/gas/arm/fpa-mem.s,v
retrieving revision 1.3
diff -u -p -r1.3 fpa-mem.s
--- gas/testsuite/gas/arm/fpa-mem.s	2 Sep 2005 12:50:44 -0000	1.3
+++ gas/testsuite/gas/arm/fpa-mem.s	2 Sep 2005 15:09:56 -0000
@@ -26,9 +26,13 @@ F:
 	sfmea	f0, 4, [r0]
 	
 	# Test mnemonic that is ambiguous between infix and suffic
-	# condition codes
-	# sfts condition code pl
+	# condition codes.
+	# sftpls is always treated as stfs condition pl
 	stfpls	f0, [r0]
 	.syntax unified
-	# stfp condition code ls
 	stfpls	f0, [r0]
+	# Unambiguous forms accept both infix and suffix conditions
+	stfnes	f0, [r0]
+	stfsne	f0, [r0]
+	stfnep	f0, [r0]
+	stfpne	f0, [r0]

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