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]

[RFA/ARM 06/21] Add support diagnosing UNPREDICTABLE conditional instructions


Some of the new instructions in ARMv8 are UNPREDICTABLE when executed
in an IT block (these are all SIMD/FP instructions).

This patch adds infrastructure to support diagnosing these instructions
in the disassembler.

Note that the repurposing of %u in the opcode16 table is fine as it has
never been used previously.

opcodes/ChangeLog:
2012-08-23  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com

	* arm-dis.c (COND_UNCOND): New constant.
	(print_insn_coprocessor): Add support for %u format specifier.
	(print_insn_neon): Likewise.
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 74d78cb..532a6c8 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -92,7 +92,8 @@ struct opcode16
 
    %c			print condition code (always bits 28-31 in ARM mode)
    %q			print shifter argument
-   %u			print condition code (unconditional in ARM mode)
+   %u			print condition code (unconditional in ARM mode,
+                          UNPREDICTABLE if not AL in Thumb)
    %A			print address for ldc/stc/ldf/stf instruction
    %B			print vstm/vldm register list
    %I                   print cirrus signed shift immediate: bits 0..3|4..6
@@ -519,6 +520,8 @@ static const struct opcode32 coprocessor_opcodes[] =
    %%			%
 
    %c			print condition code
+   %u			print condition code (unconditional in ARM mode,
+                          UNPREDICTABLE if not AL in Thumb)
    %A			print v{st,ld}[1234] operands
    %B			print v{st,ld}[1234] any one operands
    %C			print v{st,ld}[1234] single->all operands
@@ -1692,6 +1695,9 @@ static unsigned int ifthen_next_state;
 /* The address of the insn for which the IT state is valid.  */
 static bfd_vma ifthen_address;
 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
+/* Indicates that the current Conditional state is unconditional or outside
+   an IT block.  */
+#define COND_UNCOND 16
 
 
 /* Functions.  */
@@ -1870,7 +1876,7 @@ print_insn_coprocessor (bfd_vma pc,
 	  if (ifthen_state)
 	    cond = IFTHEN_COND;
 	  else
-	    cond = 16;
+	    cond = COND_UNCOND;
 	}
       else
 	{
@@ -1879,13 +1885,13 @@ print_insn_coprocessor (bfd_vma pc,
 	  if ((given & 0xf0000000) == 0xf0000000)
 	    {
 	      mask |= 0xf0000000;
-	      cond = 16;
+	      cond = COND_UNCOND;
 	    }
 	  else
 	    {
 	      cond = (given >> 28) & 0xf;
 	      if (cond == 0xe)
-		cond = 16;
+		cond = COND_UNCOND;
 	    }
 	}
       
@@ -1979,6 +1985,11 @@ print_insn_coprocessor (bfd_vma pc,
 		  }
 		  break;
 
+		case 'u':
+		  if (cond != COND_UNCOND)
+		    is_unpredictable = TRUE;
+
+		  /* Fall through.  */
 		case 'c':
 		  func (stream, "%s", arm_conditional[cond]);
 		  break;
@@ -2488,6 +2499,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
       if ((given & insn->mask) == insn->value)
 	{
 	  signed long value_in_comment = 0;
+	  bfd_boolean is_unpredictable = FALSE;
 	  const char *c;
 
 	  for (c = insn->assembler; *c; c++)
@@ -2500,6 +2512,11 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
 		      func (stream, "%%");
 		      break;
 
+		    case 'u':
+		      if (thumb && ifthen_state)
+			is_unpredictable = TRUE;
+
+		      /* Fall through.  */
 		    case 'c':
 		      if (thumb && ifthen_state)
 			func (stream, "%s", arm_conditional[IFTHEN_COND]);
@@ -2913,6 +2930,9 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
 	  if (value_in_comment > 32 || value_in_comment < -16)
 	    func (stream, "\t; 0x%lx", value_in_comment);
 
+	  if (is_unpredictable)
+	    func (stream, UNPREDICTABLE_INSTRUCTION);
+
 	  return TRUE;
 	}
     }

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