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: Fix uninitialised CRIS insn


> From: Hans-Peter Nilsson <hp@axis.com>
> Date: Mon, 16 Jun 2014 15:31:48 +0200

> > From: Alan Modra <amodra@gmail.com>
> > Date: Mon, 16 Jun 2014 09:40:34 +0200

> > I was hoping you'd deal with the testcase errors, rather than have
> > me blundering around in your ports.
> 
> Ok, let's do that, thanks for your work.

Here's the fix for CRIS.

There wasn't complete test-suite coverage for the possible
double-error situations, so I added some missing tests.  There
*still* isn't full coverage, but the missing cases are currently
impossible (as SIZE_FIELD_UNSIGNED is not fully implemented and
unused in the opcode table).  Some of the failures of the new
tests seems to have been caused by fall-through bugs; not the
recent changes.

(N.B. I did not fix the capitalization errors in the messages, I
just made sure the new test would not have to be adjusted
if/when that's done.  Also, it seems there's a language error
with hyphenation, unfixed.)

Committed.

gas:
	* config/tc-cris.c (cris_bad): New function.
	(cris_process_instruction): Where applicable, use it instead of
	as_bad.

gas/testsuite:
	* gas/cris/range-err-3.s: New test.

diff --git a/gas/config/tc-cris.c b/gas/config/tc-cris.c
index aba4ef7..2989f02 100644
--- a/gas/config/tc-cris.c
+++ b/gas/config/tc-cris.c
@@ -1492,6 +1492,19 @@ md_assemble (char *str)
     }
 }
 
+/* Helper error-reporting function: calls as_bad for a format string
+   for a single value and zeroes the offending value (zero assumed
+   being a valid value) to avoid repeated error reports in later value
+   checking.  */
+
+static void
+cris_bad (const char *format, offsetT *valp)
+{
+  /* We cast to long so the format string can assume that format.  */
+  as_bad (format, (long) *valp);
+  *valp = 0;
+}
+
 /* Low level text-to-bits assembly.  */
 
 static void
@@ -1646,8 +1659,8 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
 		  if (out_insnp->expr.X_op == O_constant
 		      && (out_insnp->expr.X_add_number < 0
 			  || out_insnp->expr.X_add_number > 31))
-		    as_bad (_("Immediate value not in 5 bit unsigned range: %ld"),
-			    out_insnp->expr.X_add_number);
+		    cris_bad (_("Immediate value not in 5 bit unsigned range: %ld"),
+			      &out_insnp->expr.X_add_number);
 
 		  out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_5;
 		  continue;
@@ -1662,8 +1675,8 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
 		  if (out_insnp->expr.X_op == O_constant
 		      && (out_insnp->expr.X_add_number < 0
 			  || out_insnp->expr.X_add_number > 15))
-		    as_bad (_("Immediate value not in 4 bit unsigned range: %ld"),
-			    out_insnp->expr.X_add_number);
+		    cris_bad (_("Immediate value not in 4 bit unsigned range: %ld"),
+			      &out_insnp->expr.X_add_number);
 
 		  out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_4;
 		  continue;
@@ -1714,8 +1727,9 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
 		  if (out_insnp->expr.X_op == O_constant
 		      && (out_insnp->expr.X_add_number < -32
 			  || out_insnp->expr.X_add_number > 31))
-		    as_bad (_("Immediate value not in 6 bit range: %ld"),
-			    out_insnp->expr.X_add_number);
+		    cris_bad (_("Immediate value not in 6 bit range: %ld"),
+			      &out_insnp->expr.X_add_number);
+
 		  out_insnp->reloc = BFD_RELOC_CRIS_SIGNED_6;
 		  continue;
 		}
@@ -1729,8 +1743,9 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
 		  if (out_insnp->expr.X_op == O_constant
 		      && (out_insnp->expr.X_add_number < 0
 			  || out_insnp->expr.X_add_number > 63))
-		    as_bad (_("Immediate value not in 6 bit unsigned range: %ld"),
-			    out_insnp->expr.X_add_number);
+		    cris_bad (_("Immediate value not in 6 bit unsigned range: %ld"),
+			      &out_insnp->expr.X_add_number);
+
 		  out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_6;
 		  continue;
 		}
@@ -2122,8 +2137,8 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
 			if (out_insnp->expr.X_op == O_constant
 			    && (out_insnp->expr.X_add_number < -128
 				|| out_insnp->expr.X_add_number > 255))
-			  as_bad (_("Immediate value not in 8 bit range: %ld"),
-				  out_insnp->expr.X_add_number);
+			  cris_bad (_("Immediate value not in 8 bit range: %ld"),
+				    &out_insnp->expr.X_add_number);
 			/* Fall through.  */
 		      case 2:
 			/* FIXME:  We need an indicator in the instruction
@@ -2132,8 +2147,8 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
 			if (out_insnp->expr.X_op == O_constant
 			    && (out_insnp->expr.X_add_number < -32768
 				|| out_insnp->expr.X_add_number > 65535))
-			  as_bad (_("Immediate value not in 16 bit range: %ld"),
-				  out_insnp->expr.X_add_number);
+			  cris_bad (_("Immediate value not in 16 bit range: %ld"),
+				    &out_insnp->expr.X_add_number);
 			out_insnp->imm_oprnd_size = 2;
 			break;
 
@@ -2162,18 +2177,18 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
 			  if (instruction->imm_oprnd_size == SIZE_FIELD
 			      && (out_insnp->expr.X_add_number < -128
 				  || out_insnp->expr.X_add_number > 255))
-			    as_bad (_("Immediate value not in 8 bit range: %ld"),
-				    out_insnp->expr.X_add_number);
+			    cris_bad (_("Immediate value not in 8 bit range: %ld"),
+				      &out_insnp->expr.X_add_number);
 			  else if (instruction->imm_oprnd_size == SIZE_FIELD_SIGNED
 			      && (out_insnp->expr.X_add_number < -128
 				  || out_insnp->expr.X_add_number > 127))
-			    as_bad (_("Immediate value not in 8 bit signed range: %ld"),
-				    out_insnp->expr.X_add_number);
+			    cris_bad (_("Immediate value not in 8 bit signed range: %ld"),
+				      &out_insnp->expr.X_add_number);
 			  else if (instruction->imm_oprnd_size == SIZE_FIELD_UNSIGNED
 				   && (out_insnp->expr.X_add_number < 0
 				       || out_insnp->expr.X_add_number > 255))
-			    as_bad (_("Immediate value not in 8 bit unsigned range: %ld"),
-				    out_insnp->expr.X_add_number);
+			    cris_bad (_("Immediate value not in 8 bit unsigned range: %ld"),
+				      &out_insnp->expr.X_add_number);
 			}
 
 		      /* Fall through.  */
@@ -2183,18 +2198,18 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
 			  if (instruction->imm_oprnd_size == SIZE_FIELD
 			      && (out_insnp->expr.X_add_number < -32768
 				  || out_insnp->expr.X_add_number > 65535))
-			    as_bad (_("Immediate value not in 16 bit range: %ld"),
-				    out_insnp->expr.X_add_number);
+			    cris_bad (_("Immediate value not in 16 bit range: %ld"),
+				      &out_insnp->expr.X_add_number);
 			  else if (instruction->imm_oprnd_size == SIZE_FIELD_SIGNED
 			      && (out_insnp->expr.X_add_number < -32768
 				  || out_insnp->expr.X_add_number > 32767))
-			    as_bad (_("Immediate value not in 16 bit signed range: %ld"),
-				    out_insnp->expr.X_add_number);
+			    cris_bad (_("Immediate value not in 16 bit signed range: %ld"),
+				      &out_insnp->expr.X_add_number);
 			  else if (instruction->imm_oprnd_size == SIZE_FIELD_UNSIGNED
 			      && (out_insnp->expr.X_add_number < 0
 				  || out_insnp->expr.X_add_number > 65535))
-			    as_bad (_("Immediate value not in 16 bit unsigned range: %ld"),
-				    out_insnp->expr.X_add_number);
+			    cris_bad (_("Immediate value not in 16 bit unsigned range: %ld"),
+				      &out_insnp->expr.X_add_number);
 			}
 		      out_insnp->imm_oprnd_size = 2;
 		      break;

diff --git a/gas/testsuite/gas/cris/range-err-3.s b/gas/testsuite/gas/cris/range-err-3.s
new file mode 100644
index 0000000..601b24f
--- /dev/null
+++ b/gas/testsuite/gas/cris/range-err-3.s
@@ -0,0 +1,10 @@
+; Test more error cases for constant ranges.
+
+;  { dg-do assemble { target cris-*-* } }
+
+ .text
+start:
+ asrq 63,$r0 ; { dg-error "mmediate value not in 5 bit unsigned range: 63" }
+ move 65536,$p0 ; { dg-error "mmediate value not in 8 bit range: 65536" }
+ move 65536,$p5 ; { dg-error "mmediate value not in 16 bit range: 65536" }
+ bdap.b 65536,$r0 ; { dg-error "mmediate value not in 8 bit signed range: 65536" }


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