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]

[PATCH] ia64: diagnostics for bad use of registers


(resending; ChangeLog entry wasn't correct)

The assembler silently permitted using
- r0, f0, or f1 as output operands
- the same predicate twice as output operands
- r0 as address of a base update load or store
- the same GR as output and address of a base update load
- two even- or two odd-numbered FRs as output operands of a floating
point
parallel load

Built and tested on ia64-unknown-linux-gnu.

Jan

gas/
2005-02-10  Jan Beulich  <jbeulich@novell.com>

	* config/tc-ia64.c (parse_operands): New local variables reg1,
reg2,
	reg_class. Check operands and emit diagnostics for illegal use
of
	registers.

gas/testsuite/
2005-02-10  Jan Beulich  <jbeulich@novell.com>

	* gas/ia64/dv-raw-err.s: Don't use r0 or f0 as output operand.
	* gas/ia64/dv-waw-err.s: Likewise.
	* gas/ia64/reg-err.[ls]: New.
	* gas/ia64/ia64.exp: Run new test.

---
/home/jbeulich/src/binutils/mainline/2005-02-08/gas/config/tc-ia64.c	2005-02-02
08:33:18.000000000 +0100
+++ 2005-02-08/gas/config/tc-ia64.c	2005-02-10 13:41:21.796344557
+0100
@@ -5936,6 +5936,8 @@ parse_operands (idesc)
 {
   int i = 0, highest_unmatched_operand, num_operands = 0, num_outputs
= 0;
   int error_pos, out_of_range_pos, curr_out_of_range_pos, sep = 0;
+  int reg1, reg2;
+  char reg_class;
   enum ia64_opnd expected_operand = IA64_OPND_NIL;
   enum operand_match_result result;
   char mnemonic[129];
@@ -6117,6 +6119,116 @@ parse_operands (idesc)
 	as_bad ("Operand mismatch");
       return 0;
     }
+  reg2 = reg1 = -1;
+  for (i = 0; i < num_operands; ++i)
+    {
+      int regno = 0;
+
+      reg_class = 0;
+      switch (idesc->operands[i])
+	{
+	case IA64_OPND_R1:
+	case IA64_OPND_R2:
+	case IA64_OPND_R3:
+	  if (i < num_outputs)
+	    {
+	      if (CURR_SLOT.opnd[i].X_add_number == REG_GR)
+		reg_class = 'r';
+	      else if (reg1 < 0)
+		reg1 = CURR_SLOT.opnd[i].X_add_number;
+	      else if (reg2 < 0)
+		reg2 = CURR_SLOT.opnd[i].X_add_number;
+	    }
+	  break;
+	case IA64_OPND_P1:
+	case IA64_OPND_P2:
+	  if (i < num_outputs)
+	    {
+	      if (reg1 < 0)
+		reg1 = CURR_SLOT.opnd[i].X_add_number;
+	      else if (reg2 < 0)
+		reg2 = CURR_SLOT.opnd[i].X_add_number;
+	    }
+	  break;
+	case IA64_OPND_F1:
+	case IA64_OPND_F2:
+	case IA64_OPND_F3:
+	case IA64_OPND_F4:
+	  if (i < num_outputs)
+	    {
+	      if (CURR_SLOT.opnd[i].X_add_number >= REG_FR
+		  && CURR_SLOT.opnd[i].X_add_number <= REG_FR + 1)
+		{
+		  reg_class = 'f';
+		  regno = CURR_SLOT.opnd[i].X_add_number - REG_FR;
+		}
+	      else if (reg1 < 0)
+		reg1 = CURR_SLOT.opnd[i].X_add_number;
+	      else if (reg2 < 0)
+		reg2 = CURR_SLOT.opnd[i].X_add_number;
+	    }
+	  break;
+	case IA64_OPND_MR3:
+	  if (idesc->flags & IA64_OPCODE_POSTINC)
+	    {
+	      if (CURR_SLOT.opnd[i].X_add_number == REG_GR)
+		reg_class = 'm';
+	      else if (reg1 < 0)
+		reg1 = CURR_SLOT.opnd[i].X_add_number;
+	      else if (reg2 < 0)
+		reg2 = CURR_SLOT.opnd[i].X_add_number;
+	    }
+	  break;
+	default:
+	  break;
+	}
+      switch (reg_class)
+	{
+	case 0:
+	  break;
+	default:
+	  as_warn ("Invalid use of `%c%d' as output operand", reg_class,
regno);
+	  break;
+	case 'm':
+	  as_warn ("Invalid use of `r%d' as base update address
operand", regno);
+	  break;
+	}
+    }
+  if (reg1 == reg2)
+    {
+      if (reg1 >= REG_GR && reg1 <= REG_GR + 127)
+	{
+	  reg1 -= REG_GR;
+	  reg_class = 'r';
+	}
+      else if (reg1 >= REG_P && reg1 <= REG_P + 63)
+	{
+	  reg1 -= REG_P;
+	  reg_class = 'p';
+	}
+      else if (reg1 >= REG_FR && reg1 <= REG_FR + 127)
+	{
+	  reg1 -= REG_FR;
+	  reg_class = 'f';
+	}
+      else
+	reg_class = 0;
+      if (reg_class)
+	as_warn ("Invalid duplicate use of `%c%d'", reg_class, reg1);
+    }
+  else if (((reg1 >= REG_FR && reg1 <= REG_FR + 31
+	     && reg2 >= REG_FR && reg2 <= REG_FR + 31)
+	    || (reg1 >= REG_FR + 32 && reg1 <= REG_FR + 127
+	     && reg2 >= REG_FR + 32 && reg2 <= REG_FR + 127))
+	   && ! ((reg1 ^ reg2) & 1))
+    as_warn ("Invalid simultaneous use of `f%d' and `f%d'",
+	     reg1 - REG_FR, reg2 - REG_FR);
+  else if ((reg1 >= REG_FR && reg1 <= REG_FR + 31
+	    && reg2 >= REG_FR + 32 && reg2 <= REG_FR + 127)
+	   || (reg1 >= REG_FR + 32 && reg1 <= REG_FR + 127
+	    && reg2 >= REG_FR && reg2 <= REG_FR + 31))
+    as_warn ("Dangerous simultaneous use of `f%d' and `f%d'",
+	     reg1 - REG_FR, reg2 - REG_FR);
   return idesc;
 }
 
---
/home/jbeulich/src/binutils/mainline/2005-02-08/gas/testsuite/gas/ia64/dv-raw-err.s	2004-06-16
15:23:12.000000000 +0200
+++ 2005-02-08/gas/testsuite/gas/ia64/dv-raw-err.s	2005-02-10
13:41:21.802203932 +0100
@@ -6,8 +6,8 @@
 .text
 	.explicit
 // AR[BSP]
-	mov	ar.bspstore = r1
-	mov	r0 = ar.bsp
+	mov	ar.bspstore = r0
+	mov	r1 = ar.bsp
 	;;
 
 // AR[BSPSTORE]	
@@ -108,12 +108,12 @@
 
 // BR%
 	mov	b0 = r0
-	mov	r0 = b0
+	mov	r2 = b0
 	;;
 	
 // CFM	
 	br.wtop.sptk	L
-	fadd	f0 = f1, f32	// read from rotating register region
+	fadd	f2 = f1, f32	// read from rotating register region
 	;;
 	
 // CR[CMCV]
@@ -276,7 +276,7 @@
 	;;
 
 // GR%
-	ld8.c.clr	r0 = [r1]	// no DV here
+	ld8.c.clr	r1 = [r1]	// no DV here
 	mov		r2 = r0		
 	;;
 	mov		r3 = r4
@@ -357,7 +357,7 @@
 	
 // PR63
 	br.wtop.sptk	L
-(p63)	add	r0 = r1, r2
+(p63)	add	r3 = r1, r2
 	;;
 	fcmp.eq p62, p63 = f2, f3
 (p63)	add	r3 = r4, r5	
@@ -368,17 +368,17 @@
 
 // PSR.ac
 	rum	(1<<3)
-	ld8	r0 = [r1]
+	ld8	r2 = [r1]
 	;;
 
 // PSR.be
 	rum	(1<<1)
-	ld8	r0 = [r1]
+	ld8	r2 = [r1]
 	;;
 	
 // PSR.bn
 	bsw.0
-	mov	r0 = r15	// no DV here, since gr < 16
+	mov	r1 = r15	// no DV here, since gr < 16
 	;;
 	bsw.1			// GAS automatically emits a stop after
bsw.n
 	mov	r1 = r16	// so this conflict is avoided          
    
@@ -439,24 +439,24 @@
 	
 // PSR.di
 	rsm	(1<<22)
-	mov	r0 = psr
+	mov	r1 = psr
 	;;
 
 // PSR.dt
 	rsm	(1<<17)
-	ld8	r0 = [r1]
+	ld8	r1 = [r1]
 	;;
 	
 // PSR.ed (rfi is the only writer)
 // PSR.i
 	ssm	(1<<14)
-	mov	r0 = psr
+	mov	r1 = psr
 	;;
 	
 // PSR.ia (no DV semantics)
 // PSR.ic
 	ssm	(1<<13)
-	mov	r0 = psr
+	mov	r1 = psr
 	;;
 	srlz.d
 	rsm	(1<<13)
@@ -479,17 +479,17 @@
 // PSR.mc (rfi is the only writer)
 // PSR.mfh
 	mov	f32 = f33
-	mov	r0 = psr
+	mov	r1 = psr
 	;;
 
 // PSR.mfl
 	mov	f2 = f3
-	mov	r0 = psr
+	mov	r1 = psr
 	;;
 
 // PSR.pk
 	rsm	(1<<15)
-	ld8	r0 = [r1]
+	ld8	r1 = [r1]
 	;;
 	rsm	(1<<15)
 	mov	r2 = psr
@@ -497,7 +497,7 @@
 
 // PSR.pp
 	rsm	(1<<21)
-	mov	r0 = psr
+	mov	r1 = psr
 	;;
 
 // PSR.ri (no DV semantics)
@@ -509,7 +509,7 @@
 
 // PSR.si
 	rsm	(1<<23)
-	mov	r0 = ar.itc
+	mov	r1 = ar.itc
 	;;
 	ssm	(1<<23)
 	mov	r1 = ar.ec	// no DV here
@@ -517,13 +517,13 @@
 
 // PSR.sp
 	ssm	(1<<20)
-	mov	r0 = pmd[r1]
+	mov	r1 = pmd[r1]
 	;;
 	ssm	(1<<20)
 	rum	0xff
 	;;
 	ssm	(1<<20)
-	mov	r0 = rr[r1]
+	mov	r1 = rr[r1]
 	;;
 
 // PSR.ss (rfi is the only writer)
@@ -534,7 +534,7 @@
 
 // PSR.up
 	rsm	(1<<2)
-	mov	r0 = psr.um
+	mov	r1 = psr.um
 	;;
 	srlz.d
 
---
/home/jbeulich/src/binutils/mainline/2005-02-08/gas/testsuite/gas/ia64/dv-waw-err.s	2000-09-22
21:43:48.000000000 +0200
+++ 2005-02-08/gas/testsuite/gas/ia64/dv-waw-err.s	2005-02-10
08:25:00.000000000 +0100
@@ -186,8 +186,8 @@
 	;;
 
 // CR[IRR%] (and others)
-	mov	r0 = cr.ivr
-	mov	r1 = cr.ivr
+	mov	r2 = cr.ivr
+	mov	r3 = cr.ivr
 	;;
 	
 // CR[ISR]
@@ -441,13 +441,13 @@
 // PSR.mc (rfi is the only writer)
 // PSR.mfh
 	mov	f32 = f33
-	mov	r0 = psr
+	mov	r10 = psr
 	;;
 	ssm	(1<<5)
 	ssm	(1<<5)
 	;;
 	ssm	(1<<5)
-	mov	psr.um = r0
+	mov	psr.um = r10
 	;;
 	rum	(1<<5)
 	rum	(1<<5)
@@ -458,13 +458,13 @@
 
 // PSR.mfl
 	mov	f2 = f3
-	mov	r0 = psr
+	mov	r10 = psr
 	;;
 	ssm	(1<<4)
 	ssm	(1<<4)
 	;;
 	ssm	(1<<4)
-	mov	psr.um = r0
+	mov	psr.um = r10
 	;;
 	rum	(1<<4)
 	rum	(1<<4)
---
/home/jbeulich/src/binutils/mainline/2005-02-08/gas/testsuite/gas/ia64/ia64.exp	2005-02-02
08:33:18.000000000 +0100
+++ 2005-02-08/gas/testsuite/gas/ia64/ia64.exp	2005-02-10
13:44:32.936967215 +0100
@@ -28,6 +28,7 @@ if [istarget "ia64-*"] then {
     run_dump_test "nop_x"
     run_dump_test "mov-ar"
     run_list_test "operands" ""
+    run_list_test "reg-err" ""
 
     run_list_test "dv-raw-err" ""
     run_list_test "dv-waw-err" ""
---
/home/jbeulich/src/binutils/mainline/2005-02-08/gas/testsuite/gas/ia64/reg-err.l	1970-01-01
01:00:00.000000000 +0100
+++ 2005-02-08/gas/testsuite/gas/ia64/reg-err.l	2005-02-09
18:07:52.000000000 +0100
@@ -0,0 +1,14 @@
+.*: Assembler messages:
+.*:3: (Error|Warning): Invalid use of `r0' as output operand
+.*:4: (Error|Warning): Invalid use of `r0' as base update address
operand
+.*:5: (Error|Warning): Invalid duplicate use of `r1'
+.*:6: (Error|Warning): Invalid use of `r0' as base update address
operand
+.*:7: (Error|Warning): Invalid duplicate use of `p1'
+.*:8: (Error|Warning): Invalid use of `f0' as output operand
+.*:9: (Error|Warning): Invalid use of `f1' as output operand
+.*:10: (Error|Warning): Invalid use of `f0' as output operand
+.*:11: (Error|Warning): Invalid use of `f1' as output operand
+.*:12: (Error|Warning): Invalid use of `f0' as output operand
+.*:12: (Error|Warning): Invalid use of `f1' as output operand
+.*:13: (Error|Warning): Invalid simultaneous use of `f2' and `f4'
+.*:14: (Error|Warning): Dangerous simultaneous use of `f31' and `f32'
---
/home/jbeulich/src/binutils/mainline/2005-02-08/gas/testsuite/gas/ia64/reg-err.s	1970-01-01
01:00:00.000000000 +0100
+++ 2005-02-08/gas/testsuite/gas/ia64/reg-err.s	2005-02-09
18:06:38.000000000 +0100
@@ -0,0 +1,14 @@
+	.text
+_start:
+	mov	r0 = r0
+	ld1	r1 = [r0], 1
+	ld1	r1 = [r1], 1
+	st1	[r0] = r0, 1
+	cmp.eq	p1, p1 = 0, r0
+	mov	f0 = f0
+	mov	f1 = f1
+	ldfs	f0 = [r0]
+	ldfs	f1 = [r0]
+	ldfps	f0, f1 = [r0]
+	ldfps	f2, f4 = [r0]
+	ldfps	f31, f32 = [r0]

Attachment: binutils-mainline-ia64-bad-reg-diags.patch
Description: Text document


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