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 04/21] Warn on deprecated IT blocks.


ARMv8 deprecates various forms of IT blocks.  This patch adds warnings
for these cases.

The IT block forms deprecated are:
 * Those with more than one instruction in the IT block
 * Those with a 32-bit instruction in the IT block
 * Various 16-bit instructions (mostly involving PC).

This patch does not change the handling of automatic IT block generation.
This is to be done in a later patch.

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

	* config/tc-arm.c (do_t_it): Fully initialise now_it.
	(new_automatic_it_block): Likewise.
	(handle_it_block): Record whether current instruction is
	conditionally executed.
	* config/tc-arm.c (depr_insn_mask): New structure.
	(depr_it_insns): New variable.
	(it_fsm_post_encode): Warn on deprecated uses.
	* config/tc-arm.h (current_it): Add new fields.

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

	* gas/arm/armv8-a-it-bad.d: New testcase.
	* gas/arm/armv8-a-it-bad.l: Likewise.
	* gas/arm/armv8-a-it-bad.s: Likewise.
	* gas/arm/ldr-t-bad.s: Update testcase.
	* gas/arm/ldr-t.d: Likewise.
	* gas/arm/ldr-t.s: Likewise.
	* gas/arm/neon-cond-bad-inc.s: Likewise.
	* gas/arm/sp-pc-validations-bad-t: Likewise.
	* gas/arm/vfp-fma-inc.s: Likewise.
	* gas/arm/vfp-neon-syntax-inc.s: Likewise.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 02e843d..d9cf3d3 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -10356,6 +10356,7 @@ do_t_it (void)
   set_it_insn_type (IT_INSN);
   now_it.mask = (inst.instruction & 0xf) | 0x10;
   now_it.cc = cond;
+  now_it.warn_deprecated = FALSE;
 
   /* If the condition is a negative condition, invert the mask.  */
   if ((cond & 0x1) == 0x0)
@@ -10363,13 +10364,25 @@ do_t_it (void)
       unsigned int mask = inst.instruction & 0x000f;
 
       if ((mask & 0x7) == 0)
-	/* no conversion needed */;
+	{
+	  /* No conversion needed.  */
+	  now_it.block_length = 1;
+	}
       else if ((mask & 0x3) == 0)
-	mask ^= 0x8;
+	{
+	  mask ^= 0x8;
+	  now_it.block_length = 2;
+	}
       else if ((mask & 0x1) == 0)
-	mask ^= 0xC;
+	{
+	  mask ^= 0xC;
+	  now_it.block_length = 3;
+	}
       else
-	mask ^= 0xE;
+	{
+	  mask ^= 0xE;
+	  now_it.block_length = 4;
+	}
 
       inst.instruction &= 0xfff0;
       inst.instruction |= mask;
@@ -16187,6 +16200,8 @@ new_automatic_it_block (int cond)
   now_it.block_length = 1;
   mapping_state (MAP_THUMB);
   now_it.insn = output_it_inst (cond, now_it.mask, NULL);
+  now_it.warn_deprecated = FALSE;
+  now_it.insn_cond = TRUE;
 }
 
 /* Close an automatic IT block.
@@ -16294,6 +16309,7 @@ static int
 handle_it_state (void)
 {
   now_it.state_handled = 1;
+  now_it.insn_cond = FALSE;
 
   switch (now_it.state)
     {
@@ -16371,6 +16387,7 @@ handle_it_state (void)
 	    }
 	  else
 	    {
+	      now_it.insn_cond = TRUE;
 	      now_it_add_mask (inst.cond);
 	    }
 
@@ -16382,6 +16399,7 @@ handle_it_state (void)
 
 	case NEUTRAL_IT_INSN:
 	  now_it.block_length++;
+	  now_it.insn_cond = TRUE;
 
 	  if (now_it.block_length > 4)
 	    force_automatic_it_block_close ();
@@ -16404,6 +16422,7 @@ handle_it_state (void)
 	now_it.mask <<= 1;
 	now_it.mask &= 0x1f;
 	is_last = (now_it.mask == 0x10);
+	now_it.insn_cond = TRUE;
 
 	switch (inst.it_insn_type)
 	  {
@@ -16448,6 +16467,25 @@ handle_it_state (void)
   return SUCCESS;
 }
 
+struct depr_insn_mask
+{
+  unsigned long pattern;
+  unsigned long mask;
+  const char* description;
+};
+
+/* List of 16-bit instruction patterns deprecated in an IT block in
+   ARMv8.  */
+static const struct depr_insn_mask depr_it_insns[] = {
+  { 0xc000, 0xc000, N_("Short branches, Undefined, SVC, LDM/STM") },
+  { 0xb000, 0xb000, N_("Miscellaneous 16-bit instructions") },
+  { 0xa000, 0xb800, N_("ADR") },
+  { 0x4800, 0xf800, N_("Literal loads") },
+  { 0x4478, 0xf478, N_("Hi-register ADD, MOV, CMP, BX, BLX using pc") },
+  { 0x4487, 0xfc87, N_("Hi-register ADD, MOV, CMP using pc") },
+  { 0, 0, NULL }
+};
+
 static void
 it_fsm_post_encode (void)
 {
@@ -16456,6 +16494,44 @@ it_fsm_post_encode (void)
   if (!now_it.state_handled)
     handle_it_state ();
 
+  if (now_it.insn_cond
+      && !now_it.warn_deprecated
+      && warn_on_deprecated
+      && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
+    {
+      if (inst.instruction >= 0x10000)
+	{
+	  as_warn (_("it blocks containing wide Thumb instructions are "
+		     "deprecated in ARMv8"));
+	  now_it.warn_deprecated = TRUE;
+	}
+      else
+	{
+	  const struct depr_insn_mask *p = depr_it_insns;
+
+	  while (p->mask != 0)
+	    {
+	      if ((inst.instruction & p->mask) == p->pattern)
+		{
+		  as_warn (_("it blocks containing 16-bit Thumb intsructions "
+			     "of the following class are deprecated in ARMv8: "
+			     "%s"), p->description);
+		  now_it.warn_deprecated = TRUE;
+		  break;
+		}
+
+	      ++p;
+	    }
+	}
+
+      if (now_it.block_length > 1)
+	{
+	  as_warn (_("it blocks of more than one conditional instruction are "
+		     "deprecated in ARMv8"));
+	  now_it.warn_deprecated = TRUE;
+	}
+    }
+
   is_last = (now_it.mask == 0x10);
   if (is_last)
     {
diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h
index 4425d75..da6469c 100644
--- a/gas/config/tc-arm.h
+++ b/gas/config/tc-arm.h
@@ -257,6 +257,8 @@ struct current_it
   int block_length;
   char *insn;
   int state_handled;
+  int warn_deprecated;
+  int insn_cond;
 };
 
 #ifdef OBJ_ELF
diff --git a/gas/testsuite/gas/arm/armv8-a-it-bad.d b/gas/testsuite/gas/arm/armv8-a-it-bad.d
new file mode 100644
index 0000000..4789484
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8-a-it-bad.d
@@ -0,0 +1,3 @@
+#name: Deprecated IT blocks (ARM v8)
+#error-output: armv8-a-it-bad.l
+#as: -mimplicit-it=always
diff --git a/gas/testsuite/gas/arm/armv8-a-it-bad.l b/gas/testsuite/gas/arm/armv8-a-it-bad.l
new file mode 100644
index 0000000..aa1b53b
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8-a-it-bad.l
@@ -0,0 +1,14 @@
+.*: Assembler messages:
+.*:7: Warning: it blocks containing wide Thumb instructions are deprecated in ARMv8
+.*:15: Warning: it blocks of more than one conditional instruction are deprecated in ARMv8
+.*:20: Warning: it blocks of more than one conditional instruction are deprecated in ARMv8
+.*:30: Warning: it blocks containing wide Thumb instructions are deprecated in ARMv8
+.*:36: Warning: it blocks of more than one conditional instruction are deprecated in ARMv8
+.*:40: Warning: it blocks containing 16-bit Thumb intsructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+.*:43: Warning: it blocks containing 16-bit Thumb intsructions of the following class are deprecated in ARMv8: Miscellaneous 16-bit instructions
+.*:49: Warning: it blocks containing 16-bit Thumb intsructions of the following class are deprecated in ARMv8: Literal loads
+.*:52: Warning: it blocks containing 16-bit Thumb intsructions of the following class are deprecated in ARMv8: Hi-register ADD, MOV, CMP, BX, BLX using pc
+.*:55: Warning: it blocks containing 16-bit Thumb intsructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+.*:55: Error: r15 not allowed here -- `addeq r0,pc,pc'
+.*:58: Warning: it blocks containing 16-bit Thumb intsructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+.*:58: Error: r15 not allowed here -- `addeq pc,r0,r0'
diff --git a/gas/testsuite/gas/arm/armv8-a-it-bad.s b/gas/testsuite/gas/arm/armv8-a-it-bad.s
new file mode 100644
index 0000000..42f2b86
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8-a-it-bad.s
@@ -0,0 +1,58 @@
+.syntax unified
+.arch armv8-a
+
+.thumb
+@ Wide instruction in IT block is deprecated.
+it eq
+ldrdeq r0, [r1]
+
+@ This IT block is not deprecated.
+it eq
+moveq r2, r3
+
+@ IT block of more than one instruction is deprecated.
+itt eq
+moveq r0, r1
+moveq r2, r3
+
+@ Even for auto IT blocks
+moveq r2, r3
+movne r2, r3
+
+adds r0, r1
+
+@ This automatic IT block is valid
+moveq r2,r3
+
+add r0, r1, r2
+
+@ This one is too wide.
+ldrdeq r0, [r1]
+
+add r0, r1, r2
+
+@ Test automatic IT block generation at end of a file.
+movne r0, r1
+moveq r1, r0
+
+@ Test the various classes of 16-bit instructions that are deprecated.
+it eq
+svceq 0
+
+it eq
+uxtheq r0, r1
+
+it eq
+addeq r0, pc, #0
+
+it eq
+ldreq r0, [pc, #4]
+
+it eq
+bxeq pc
+
+it eq
+addeq r0, pc, pc
+
+it eq
+addeq pc, r0, r0
diff --git a/gas/testsuite/gas/arm/ldr-t-bad.s b/gas/testsuite/gas/arm/ldr-t-bad.s
index 81c17a5..a1e22bd 100644
--- a/gas/testsuite/gas/arm/ldr-t-bad.s
+++ b/gas/testsuite/gas/arm/ldr-t-bad.s
@@ -1,5 +1,5 @@
 .syntax unified
-
+.arch armv7-a
 .thumb
 
 	@ldr-immediate
diff --git a/gas/testsuite/gas/arm/ldr-t.d b/gas/testsuite/gas/arm/ldr-t.d
index 1b50837..ddcd612 100644
--- a/gas/testsuite/gas/arm/ldr-t.d
+++ b/gas/testsuite/gas/arm/ldr-t.d
@@ -11,22 +11,22 @@ Disassembly of section [^>]+:
 0+10 <[^>]+> f8df f004 	ldr.w	pc, \[pc, #4\]	; 0+18 <[^>]+0x18>
 0+14 <[^>]+> bfa2      	ittt	ge
 0+16 <[^>]+> 4901      	ldrge	r1, \[pc, #4\]	; \(0+1c <[^>]+0x1c>\)
-0+18 <[^>]+> 46c0      	nopge			; \(mov r8, r8\)
-0+1a <[^>]+> 46c0      	nopge			; \(mov r8, r8\)
+0+18 <[^>]+> bf00      	nopge
+0+1a <[^>]+> bf00      	nopge
 0+1c <[^>]+> bfa8      	it	ge
 0+1e <[^>]+> f8df f004 	ldrge.w	pc, \[pc, #4\]	; 0+24 <[^>]+0x24>
 0+22 <[^>]+> bfa2      	ittt	ge
 0+24 <[^>]+> f85f 1ab8 	ldrge.w	r1, \[pc, #-2744\]	; fffff570 <[^>]+>
-0+28 <[^>]+> 46c0      	nopge			; \(mov r8, r8\)
-0+2a <[^>]+> 46c0      	nopge			; \(mov r8, r8\)
+0+28 <[^>]+> bf00      	nopge
+0+2a <[^>]+> bf00      	nopge
 0+2c <[^>]+> bfa8      	it	ge
 0+2e <[^>]+> f85f fab6 	ldrge.w	pc, \[pc, #-2742\]	; fffff57a <[^>]+>
 0+32 <[^>]+> f85f 1ab9 	ldr.w	r1, \[pc, #-2745\]	; fffff57b <[^>]+>
 0+36 <[^>]+> f85f fab6 	ldr.w	pc, \[pc, #-2742\]	; fffff582 <[^>]+>
 0+3a <[^>]+> bfa2      	ittt	ge
 0+3c <[^>]+> 5851      	ldrge	r1, \[r2, r1\]
-0+3e <[^>]+> 46c0      	nopge			; \(mov r8, r8\)
-0+40 <[^>]+> 46c0      	nopge			; \(mov r8, r8\)
+0+3e <[^>]+> bf00      	nopge
+0+40 <[^>]+> bf00      	nopge
 0+42 <[^>]+> bfa8      	it	ge
 0+44 <[^>]+> f852 f001 	ldrge.w	pc, \[r2, r1\]
 0+48 <[^>]+> 58d1      	ldr	r1, \[r2, r3\]
diff --git a/gas/testsuite/gas/arm/ldr-t.s b/gas/testsuite/gas/arm/ldr-t.s
index b6462c9..4aaecdf 100644
--- a/gas/testsuite/gas/arm/ldr-t.s
+++ b/gas/testsuite/gas/arm/ldr-t.s
@@ -1,5 +1,5 @@
 .syntax unified
-
+.arch armv7-a
 .thumb
 	.global foo
 foo:
diff --git a/gas/testsuite/gas/arm/neon-cond-bad-inc.s b/gas/testsuite/gas/arm/neon-cond-bad-inc.s
index a92d196..2f56773 100644
--- a/gas/testsuite/gas/arm/neon-cond-bad-inc.s
+++ b/gas/testsuite/gas/arm/neon-cond-bad-inc.s
@@ -1,9 +1,9 @@
 # Check for illegal conditional Neon instructions in ARM mode. The instructions
 # which overlap with VFP are the tricky cases, so test those.
-
 	.include "itblock.s"
-
 	.syntax unified
+	.arch armv7-a
+	.fpu neon
 	.text
 func:
 	itblock 4 eq
diff --git a/gas/testsuite/gas/arm/sp-pc-validations-bad-t.s b/gas/testsuite/gas/arm/sp-pc-validations-bad-t.s
index 0b155fb..3da0861 100644
--- a/gas/testsuite/gas/arm/sp-pc-validations-bad-t.s
+++ b/gas/testsuite/gas/arm/sp-pc-validations-bad-t.s
@@ -1,6 +1,6 @@
 .syntax unified
+.arch armv7-a
 .thumb
-
 .macro it_test opcode operands:vararg
 itt eq
 \opcode\()eq r15, \operands
diff --git a/gas/testsuite/gas/arm/vfp-fma-inc.s b/gas/testsuite/gas/arm/vfp-fma-inc.s
index a9dcb14..4f349e1 100644
--- a/gas/testsuite/gas/arm/vfp-fma-inc.s
+++ b/gas/testsuite/gas/arm/vfp-fma-inc.s
@@ -1,4 +1,6 @@
 	.syntax unified
+	.arch armv7-a
+	.fpu neon-vfpv4
 
 	.include "itblock.s"
 
diff --git a/gas/testsuite/gas/arm/vfp-neon-syntax-inc.s b/gas/testsuite/gas/arm/vfp-neon-syntax-inc.s
index fad0bde..5005cb7 100644
--- a/gas/testsuite/gas/arm/vfp-neon-syntax-inc.s
+++ b/gas/testsuite/gas/arm/vfp-neon-syntax-inc.s
@@ -1,5 +1,6 @@
 @ VFP with Neon-style syntax
 	.syntax unified
+	.arch armv7-a
 
 	.include "itblock.s"
 

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