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]

[Xtensa] check for multiple writes to a register


Some future Xtensa processors will allow instructions that write multiple outputs to different registers in a single register file, but it is not legal to have an instruction that attempts to write multiple values into one register. I've committed this patch from Sterling Augustine to check this condition.

gas/ChangeLog:
2008-11-04  Sterling Augustine  <sterling@tensilica.com>
	
	* config/tc-xtensa.c (tinsn_check_arguments): Check for multiple
	writes to the same register.

Index: config/tc-xtensa.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-xtensa.c,v
retrieving revision 1.105
diff -u -p -r1.105 tc-xtensa.c
--- config/tc-xtensa.c	4 Nov 2008 23:11:02 -0000	1.105
+++ config/tc-xtensa.c	5 Nov 2008 00:06:37 -0000
@@ -11457,6 +11457,12 @@ tinsn_check_arguments (const TInsn *insn
 {
   xtensa_isa isa = xtensa_default_isa;
   xtensa_opcode opcode = insn->opcode;
+  xtensa_regfile t1_regfile, t2_regfile;
+  int t1_reg, t2_reg;
+  int t1_base_reg, t1_last_reg;
+  int t2_base_reg, t2_last_reg;
+  char t1_inout, t2_inout;
+  int i, j;
 
   if (opcode == XTENSA_UNDEFINED)
     {
@@ -11475,6 +11481,54 @@ tinsn_check_arguments (const TInsn *insn
       as_bad (_("too many operands"));
       return TRUE;
     }
+
+  /* Check registers.  */
+  for (j = 0; j < insn->ntok; j++)
+    {
+      if (xtensa_operand_is_register (isa, insn->opcode, j) != 1)
+	continue;
+
+      t2_regfile = xtensa_operand_regfile (isa, insn->opcode, j);
+      t2_base_reg = insn->tok[j].X_add_number;
+      t2_last_reg
+	= t2_base_reg + xtensa_operand_num_regs (isa, insn->opcode, j);
+
+      for (i = 0; i < insn->ntok; i++)
+	{
+	  if (i == j)
+	    continue;
+
+	  if (xtensa_operand_is_register (isa, insn->opcode, i) != 1)
+	    continue;
+
+	  t1_regfile = xtensa_operand_regfile (isa, insn->opcode, i);
+
+	  if (t1_regfile != t2_regfile)
+	    continue;
+
+	  t1_inout = xtensa_operand_inout (isa, insn->opcode, i);
+	  t2_inout = xtensa_operand_inout (isa, insn->opcode, j);
+
+	  t1_base_reg = insn->tok[i].X_add_number;
+	  t1_last_reg = (t1_base_reg
+			 + xtensa_operand_num_regs (isa, insn->opcode, i));
+
+	  for (t1_reg = t1_base_reg; t1_reg < t1_last_reg; t1_reg++)
+	    {
+	      for (t2_reg = t2_base_reg; t2_reg < t2_last_reg; t2_reg++)
+		{
+		  if (t1_reg != t2_reg)
+		    continue;
+
+		  if (t1_inout != 'i' && t2_inout != 'i')
+		    {
+		      as_bad (_("multiple writes to the same register"));
+		      return TRUE;
+		    }
+		}
+	    }
+	}
+    }
   return FALSE;
 }
 

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