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]

[PATCH 2] New option for automatically generating IT instructions and enhancing validations


Hi,
 this is the last version of the patch for the automatic IT instructions generation.

With this patch, the assembler allows use of conditional Thumb-2 instructions without requiring explicit IT instructions.

The patch adds the -mimplicit-it command-line option.

This option controls the behavior of the assembler when conditional instructions are not enclosed in IT blocks.
There are four possible behaviors.
If -mimplicit-it=never is specified, such constructs cause a warning in ARM code and an error in Thumb-2 code.
If -mimplicit-it=always is specified, such constructs are accepted in both ARM and Thumb-2 code; the IT instruction is added implicitly.
If -mimplicit-it=arm is specified, such constructs are accepted in ARM code and cause an error in Thumb-2 code.
If -mimplicit-it=thumb is specified, such constructs cause a warning in ARM code and are accepted in Thumb-2 code.
If you omit this option, the behavior is equivalent to -mimplicit-it=arm.

I tested this by running the gas testsuite, plus the test cases I added.

Please note that I don't have write access, so please commit this for me if accepted.


Thanks, Daniel.

------------

   gas/
   * config/tc-arm.c (implicit_it_mode): New enum.
   (implicit_it_mode): New global.
   (it_instruction_type): New enum.
   (arm_parse_it_mode): New function.
   (arm_long_opts): New option added.
   (arm_it): New field.
   (it_state): New enum.
   (now_it): New macro.
   (check_it_blocks_finished): New function.
   (insns[]): Use the IT Thumb opcodes for ARM too.
   (arm_cleanup): Call check_it_blocks_finished.
   (now_it_compatible): New function.
   (conditional_insn): New function.
   (set_it_insn_type): New macro.
   (set_it_insn_type_last): New macro.
   (do_it): Call automatic IT machinery functions.
   (do_t_add_sub): Likewise
   (do_t_arit3): Likewise.
   (do_t_arit3c): Likewise.
   (do_t_blx): Likewise.
   (do_t_branch): Likewise.
   (do_t_bkpt): Likewise.
   (do_t_branch23): Likewise.
   (do_t_bx): Likewise.
   (do_t_bxj): Likewise.
   (do_t_cps): Likewise.
   (do_t_cpsi): Likewise.
   (do_t_cbz): Likewise.
   (do_t_it): Likewise.
   (encode_thumb2_ldmstm): Likewise.
   (do_t_ldst): Likewise.
   (do_t_mov_cmp): Likewise.
   (do_t_mvn_tst): Likewise.
   (do_t_mul): Likewise.
   (do_t_neg): Likewise.
   (do_t_setend): Likewise.
   (do_t_shift): Likewise.
   (do_t_tb): Likewise.
   (output_it_inst): New function.
   (new_automatic_it_block): New function.
   (close_automatic_it_block): New function.
   (now_it_add_mask): New function.
   (it_fsm_pre_encode): New function.
   (handle_it_state): New function.
   (it_fsm_post_encode): New function.
   (force_automatic_it_block_close): New function.
   (in_it_block): New function.
   (md_assemble): Call automatic IT block machinery functions.
   (arm_frob_label): Likewise.
   (arm_opts): New element.
   * config/tc-arm.h (it_state): New enum.
   (current_it): New struct.
   (arm_segment_info_type): New member added.
   * doc/c-arm.texi: New option -mimplicit-it documented.

gas/testsuite/
* gas/arm/arm-it-auto.d: New test.
* gas/arm/arm-it-auto.s: New file.
* gas/arm/arm-it-auto-2.d: New test case.
* gas/arm/arm-it-auto-2.s: New file.
* gas/arm/arm-it-auto-3.d: New test case.
* gas/arm/arm-it-auto-3.s: New file.
* gas/arm/arm-it-bad.d: New test case.
* gas/arm/arm-it-bad.l: New file.
* gas/arm/arm-it-bad.s: New file.
* gas/arm/arm-it-bad-2.d: New test case.
* gas/arm/arm-it-bad-2.l: New file.
* gas/arm/arm-it-bad-2.s: New file.
* gas/arm/arm-it-bad-3.d: New test case.
* gas/arm/arm-it-bad-3.l: New file.
* gas/arm/arm-it-bad-3.s: New file.
* gas/arm/thumb2_it_auto.d: New test.
* gas/arm/thumb2_it_bad.l: Error message updated.
* gas/arm/thumb2_it_bad_auto.d: New test.
* gas/arm/thumb2_it.d: Comment added.
* gas/arm/thumb2_it_bad.d: Comment added.
Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.385
diff -u -p -r1.385 tc-arm.c
--- gas/config/tc-arm.c	13 May 2009 16:44:56 -0000	1.385
+++ gas/config/tc-arm.c	9 Jun 2009 21:11:00 -0000
@@ -265,6 +265,16 @@ static int thumb_mode = 0;
    tc_frag_data field of a frag.  */
 #define MODE_RECORDED (1 << 4)
 
+/* Specifies the intrinsic IT insn behavior mode.  */
+enum implicit_it_mode
+{
+  IMPLICIT_IT_MODE_NEVER  = 0x00,
+  IMPLICIT_IT_MODE_ARM    = 0x01,
+  IMPLICIT_IT_MODE_THUMB  = 0x02,
+  IMPLICIT_IT_MODE_ALWAYS = (IMPLICIT_IT_MODE_ARM | IMPLICIT_IT_MODE_THUMB)
+};
+static int implicit_it_mode = IMPLICIT_IT_MODE_ARM;
+
 /* If unified_syntax is true, we are processing the new unified
    ARM/Thumb syntax.  Important differences from the old ARM mode:
 
@@ -315,6 +325,18 @@ struct neon_type
   unsigned elems;
 };
 
+enum it_instruction_type
+{
+   OUTSIDE_IT_INSN,
+   INSIDE_IT_INSN,
+   INSIDE_IT_LAST_INSN,
+   IF_INSIDE_IT_LAST_INSN, /* Either outside or inside;
+                              if inside, should be the last one.  */
+   NEUTRAL_IT_INSN,        /* This could be either inside or outside,
+                              i.e. BKPT and NOP.  */
+   IT_INSN                 /* The IT insn has been parsed.  */
+};
+
 struct arm_it
 {
   const char *	error;
@@ -337,6 +359,8 @@ struct arm_it
     int			     pc_rel;
   } reloc;
 
+  enum it_instruction_type it_insn_type;
+
   struct
   {
     unsigned reg;
@@ -674,6 +698,9 @@ struct asm_opcode
 #define BAD_BRANCH	_("branch must be last instruction in IT block")
 #define BAD_NOT_IT	_("instruction not allowed in IT block")
 #define BAD_FPU		_("selected FPU does not support instruction")
+#define BAD_OUT_IT  _("thumb conditional instruction should be in IT block")
+#define BAD_IT_COND _("incorrect condition in IT block")
+#define BAD_IT_IT   _("IT falling in the range of a previous IT block")
 
 static struct hash_control *arm_ops_hsh;
 static struct hash_control *arm_cond_hsh;
@@ -695,7 +722,7 @@ static struct hash_control *arm_barrier_
 
 symbolS *  last_label_seen;
 static int label_is_thumb_function_name = FALSE;
-
+
 /* Literal pool structure.  Held on a per-section
    and per-sub-section basis.  */
 
@@ -714,10 +741,41 @@ typedef struct literal_pool
 /* Pointer to a linked list of literal pools.  */
 literal_pool * list_of_pools = NULL;
 
-/* State variables for IT block handling.  */
-static bfd_boolean current_it_mask = 0;
-static int current_cc;
-
+#define now_it seg_info (now_seg)->tc_segment_info_data.current_it
+
+static inline int
+now_it_compatible (int cond)
+{
+  return (cond & ~1) == (now_it.cc & ~1);
+}
+
+static inline int
+conditional_insn(void)
+{
+  return inst.cond != COND_ALWAYS;
+}
+
+static int in_it_block (void);
+
+static int handle_it_state (void);
+
+static void force_automatic_it_block_close (void);
+
+#define set_it_insn_type(type)      \
+  do{                               \
+    inst.it_insn_type = type;       \
+    if (handle_it_state () == FAIL) \
+      return;                       \
+  }while(0)
+
+#define set_it_insn_type_last()                     \
+  do{                                               \
+    if (inst.cond == COND_ALWAYS)                   \
+      set_it_insn_type (IF_INSIDE_IT_LAST_INSN);    \
+    else                                            \
+      set_it_insn_type (INSIDE_IT_LAST_INSN);       \
+  }while(0)
+
 /* Pure syntax.	 */
 
 /* This array holds the chars that always start a comment.  If the
@@ -6120,7 +6178,7 @@ parse_operands (char *str, const unsigne
 #undef po_reg_or_goto
 #undef po_imm_or_fail
 #undef po_scalar_or_fail
-
+
 /* Shorthand macro for instruction encoding functions issuing errors.  */
 #define constraint(expr, err) do {		\
   if (expr)					\
@@ -6960,8 +7018,17 @@ static void
 do_it (void)
 {
   /* There is no IT instruction in ARM mode.  We
-     process it but do not generate code for it.  */
+     process it to do the validation as if in
+     thumb mode, just in case the code gets
+     assembled for thumb using the unified syntax.  */
+
   inst.size = 0;
+  if (unified_syntax)
+    {
+      set_it_insn_type (IT_INSN);
+      now_it.mask = (inst.instruction & 0xf) | 0x10;
+      now_it.cc = inst.operands[0].imm;
+    }
 }
 
 static void
@@ -8482,6 +8549,9 @@ do_t_add_sub (void)
 	? inst.operands[1].reg    /* Rd, Rs, foo */
 	: inst.operands[0].reg);  /* Rd, foo -> Rd, Rd, foo */
 
+  if (Rd == REG_PC)
+    set_it_insn_type_last ();
+
   if (unified_syntax)
     {
       bfd_boolean flags;
@@ -8491,9 +8561,9 @@ do_t_add_sub (void)
       flags = (inst.instruction == T_MNEM_adds
 	       || inst.instruction == T_MNEM_subs);
       if (flags)
-	narrow = (current_it_mask == 0);
+	narrow = !in_it_block ();
       else
-	narrow = (current_it_mask != 0);
+	narrow = in_it_block ();
       if (!inst.operands[2].isreg)
 	{
 	  int add;
@@ -8745,9 +8815,9 @@ do_t_arit3 (void)
 
 	  /* See if we can do this with a 16-bit instruction.  */
 	  if (THUMB_SETS_FLAGS (inst.instruction))
-	    narrow = current_it_mask == 0;
+	    narrow = !in_it_block ();
 	  else
-	    narrow = current_it_mask != 0;
+	    narrow = in_it_block ();
 
 	  if (Rd > 7 || Rn > 7 || Rs > 7)
 	    narrow = FALSE;
@@ -8833,9 +8903,9 @@ do_t_arit3c (void)
 
 	  /* See if we can do this with a 16-bit instruction.  */
 	  if (THUMB_SETS_FLAGS (inst.instruction))
-	    narrow = current_it_mask == 0;
+	    narrow = !in_it_block ();
 	  else
-	    narrow = current_it_mask != 0;
+	    narrow = in_it_block ();
 
 	  if (Rd > 7 || Rn > 7 || Rs > 7)
 	    narrow = FALSE;
@@ -8988,7 +9058,8 @@ do_t_bfx (void)
 static void
 do_t_blx (void)
 {
-  constraint (current_it_mask && current_it_mask != 0x10, BAD_BRANCH);
+  set_it_insn_type_last ();
+
   if (inst.operands[0].isreg)
     {
       constraint (inst.operands[0].reg == REG_PC, BAD_PC);
@@ -9010,13 +9081,14 @@ do_t_branch (void)
   int opcode;
   int cond;
 
-  if (current_it_mask)
+  cond = inst.cond;
+  set_it_insn_type (IF_INSIDE_IT_LAST_INSN);
+
+  if (in_it_block ())
     {
       /* Conditional branches inside IT blocks are encoded as unconditional
          branches.  */
       cond = COND_ALWAYS;
-      /* A branch must be the last instruction in an IT block.  */
-      constraint (current_it_mask != 0x10, BAD_BRANCH);
     }
   else
     cond = inst.cond;
@@ -9066,13 +9138,14 @@ do_t_bkpt (void)
       constraint (inst.operands[0].imm > 255,
 		  _("immediate value out of range"));
       inst.instruction |= inst.operands[0].imm;
+      set_it_insn_type (NEUTRAL_IT_INSN);
     }
 }
 
 static void
 do_t_branch23 (void)
 {
-  constraint (current_it_mask && current_it_mask != 0x10, BAD_BRANCH);
+  set_it_insn_type_last ();
   inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
   inst.reloc.pc_rel = 1;
 
@@ -9093,7 +9166,7 @@ do_t_branch23 (void)
 static void
 do_t_bx (void)
 {
-  constraint (current_it_mask && current_it_mask != 0x10, BAD_BRANCH);
+  set_it_insn_type_last ();
   inst.instruction |= inst.operands[0].reg << 3;
   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.	 The reloc
      should cause the alignment to be checked once it is known.	 This is
@@ -9105,7 +9178,7 @@ do_t_bxj (void)
 {
   int Rm;
 
-  constraint (current_it_mask && current_it_mask != 0x10, BAD_BRANCH);
+  set_it_insn_type_last ();
   Rm = inst.operands[0].reg;
   reject_bad_reg (Rm);
   inst.instruction |= Rm << 16;
@@ -9131,14 +9204,14 @@ do_t_clz (void)
 static void
 do_t_cps (void)
 {
-  constraint (current_it_mask, BAD_NOT_IT);
+  set_it_insn_type (OUTSIDE_IT_INSN);
   inst.instruction |= inst.operands[0].imm;
 }
 
 static void
 do_t_cpsi (void)
 {
-  constraint (current_it_mask, BAD_NOT_IT);
+  set_it_insn_type (OUTSIDE_IT_INSN);
   if (unified_syntax
       && (inst.operands[1].present || inst.size_req == 4)
       && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6_notm))
@@ -9185,7 +9258,7 @@ do_t_cpy (void)
 static void
 do_t_cbz (void)
 {
-  constraint (current_it_mask, BAD_NOT_IT);
+  set_it_insn_type (OUTSIDE_IT_INSN);
   constraint (inst.operands[0].reg > 7, BAD_HIREG);
   inst.instruction |= inst.operands[0].reg;
   inst.reloc.pc_rel = 1;
@@ -9231,9 +9304,9 @@ do_t_it (void)
 {
   unsigned int cond = inst.operands[0].imm;
 
-  constraint (current_it_mask, BAD_NOT_IT);
-  current_it_mask = (inst.instruction & 0xf) | 0x10;
-  current_cc = cond;
+  set_it_insn_type (IT_INSN);
+  now_it.mask = (inst.instruction & 0xf) | 0x10;
+  now_it.cc = cond;
 
   /* If the condition is a negative condition, invert the mask.  */
   if ((cond & 0x1) == 0x0)
@@ -9268,9 +9341,13 @@ encode_thumb2_ldmstm (int base, unsigned
     inst.error =  _("SP not allowed in register list");
   if (load)
     {
-      if (mask & (1 << 14)
-	  && mask & (1 << 15))
-	inst.error = _("LR and PC should not both be in register list");
+      if (mask & (1 << 15))
+        {
+          if (mask & (1 << 14))
+            inst.error = _("LR and PC should not both be in register list");
+          else
+            set_it_insn_type_last ();
+        }
 
       if ((mask & (1 << base)) != 0
 	  && writeback)
@@ -9446,6 +9523,13 @@ do_t_ldst (void)
   unsigned long opcode;
   int Rn;
 
+  if (inst.operands[0].isreg
+      && !inst.operands[0].preind
+      && inst.operands[0].reg == REG_PC)
+    {
+      set_it_insn_type_last ();
+    }
+
   opcode = inst.instruction;
   if (unified_syntax)
     {
@@ -9666,6 +9750,9 @@ do_t_mov_cmp (void)
   Rn = inst.operands[0].reg;
   Rm = inst.operands[1].reg;
 
+  if (Rn == REG_PC)
+    set_it_insn_type_last ();
+
   if (unified_syntax)
     {
       int r0off = (inst.instruction == T_MNEM_mov
@@ -9676,7 +9763,7 @@ do_t_mov_cmp (void)
 
       low_regs = (Rn <= 7 && Rm <= 7);
       opcode = inst.instruction;
-      if (current_it_mask)
+      if (in_it_block ())
 	narrow = opcode != T_MNEM_movs;
       else
 	narrow = opcode != T_MNEM_movs || low_regs;
@@ -9731,7 +9818,7 @@ do_t_mov_cmp (void)
       if (!inst.operands[1].isreg)
 	{
 	  /* Immediate operand.  */
-	  if (current_it_mask == 0 && opcode == T_MNEM_mov)
+	  if (!in_it_block () && opcode == T_MNEM_mov)
 	    narrow = 0;
 	  if (low_regs && narrow)
 	    {
@@ -9757,7 +9844,7 @@ do_t_mov_cmp (void)
 	  /* Register shifts are encoded as separate shift instructions.  */
 	  bfd_boolean flags = (inst.instruction == T_MNEM_movs);
 
-	  if (current_it_mask)
+	  if (in_it_block ())
 	    narrow = !flags;
 	  else
 	    narrow = flags;
@@ -9813,7 +9900,7 @@ do_t_mov_cmp (void)
 	      && (inst.instruction == T_MNEM_mov
 		  || inst.instruction == T_MNEM_movs))
 	    {
-	      if (current_it_mask)
+	      if (in_it_block ())
 		narrow = (inst.instruction == T_MNEM_mov);
 	      else
 		narrow = (inst.instruction == T_MNEM_movs);
@@ -9975,9 +10062,9 @@ do_t_mvn_tst (void)
       else if (inst.instruction == T_MNEM_cmn)
 	narrow = TRUE;
       else if (THUMB_SETS_FLAGS (inst.instruction))
-	narrow = (current_it_mask == 0);
+	narrow = !in_it_block ();
       else
-	narrow = (current_it_mask != 0);
+	narrow = in_it_block ();
 
       if (!inst.operands[1].isreg)
 	{
@@ -10116,9 +10203,9 @@ do_t_mul (void)
 	  || Rm > 7)
 	narrow = FALSE;
       else if (inst.instruction == T_MNEM_muls)
-	narrow = (current_it_mask == 0);
+	narrow = !in_it_block ();
       else
-	narrow = (current_it_mask != 0);
+	narrow = in_it_block ();
     }
   else
     {
@@ -10184,6 +10271,8 @@ do_t_mull (void)
 static void
 do_t_nop (void)
 {
+  set_it_insn_type(NEUTRAL_IT_INSN);
+
   if (unified_syntax)
     {
       if (inst.size_req == 4 || inst.operands[0].imm > 15)
@@ -10220,9 +10309,9 @@ do_t_neg (void)
       bfd_boolean narrow;
 
       if (THUMB_SETS_FLAGS (inst.instruction))
-	narrow = (current_it_mask == 0);
+	narrow = !in_it_block ();
       else
-	narrow = (current_it_mask != 0);
+	narrow = in_it_block ();
       if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
 	narrow = FALSE;
       if (inst.size_req == 4)
@@ -10446,9 +10535,9 @@ do_t_rsb (void)
       bfd_boolean narrow;
 
       if ((inst.instruction & 0x00100000) != 0)
-	narrow = (current_it_mask == 0);
+	narrow = !in_it_block ();
       else
-	narrow = (current_it_mask != 0);
+	narrow = in_it_block ();
 
       if (Rd > 7 || Rs > 7)
 	narrow = FALSE;
@@ -10482,7 +10571,7 @@ do_t_rsb (void)
 static void
 do_t_setend (void)
 {
-  constraint (current_it_mask, BAD_NOT_IT);
+  set_it_insn_type (OUTSIDE_IT_INSN);
   if (inst.operands[0].imm)
     inst.instruction |= 0x8;
 }
@@ -10512,9 +10601,9 @@ do_t_shift (void)
 	}
 
       if (THUMB_SETS_FLAGS (inst.instruction))
-	narrow = (current_it_mask == 0);
+	narrow = !in_it_block ();
       else
-	narrow = (current_it_mask != 0);
+	narrow = in_it_block ();
       if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
 	narrow = FALSE;
       if (!inst.operands[2].isreg && shift_kind == SHIFT_ROR)
@@ -10800,7 +10889,7 @@ do_t_tb (void)
   int half;
 
   half = (inst.instruction & 0x10) != 0;
-  constraint (current_it_mask && current_it_mask != 0x10, BAD_BRANCH);
+  set_it_insn_type_last ();
   constraint (inst.operands[0].immisreg,
 	      _("instruction requires register index"));
 
@@ -14437,6 +14526,28 @@ output_inst (const char * str)
   dwarf2_emit_insn (inst.size);
 }
 
+static char*
+output_it_inst (int cond, int mask, char* to)
+{
+  unsigned long instruction = 0xbf00;
+
+  mask &= 0xf;
+  instruction |= mask;
+  instruction |= cond << 4;
+
+  if (to == NULL)
+    {
+      to = frag_more (2);
+#ifdef OBJ_ELF
+      dwarf2_emit_insn (2);
+#endif
+    }
+
+  md_number_to_chars (to, instruction, 2);
+
+  return to;
+}
+
 /* Tag values used in struct asm_opcode's tag field.  */
 enum opcode_tag
 {
@@ -14682,6 +14793,316 @@ opcode_lookup (char **str)
   return 0;
 }
 
+/* This function generates an initial IT instruction, leaving its block
+   virtually open for the new instructions. Eventually,
+   the mask will be updated by now_it_add_mask () each time
+   a new instruction needs to be included in the IT block.
+   Finally, the block is closed with close_automatic_it_block ().
+   The block closure can be requested either from md_assemble (),
+   a tencode (), or due to a label hook.  */
+static void
+new_automatic_it_block (int cond)
+{
+  now_it.state = AUTOMATIC_IT_BLOCK;
+  now_it.mask = 0x18;
+  now_it.cc = cond;
+  now_it.block_length = 1;
+  now_it.insn = output_it_inst(cond, now_it.mask, NULL);
+}
+
+/* Close an automatic IT block.
+   See comments in new_automatic_it_block ().  */
+static void
+close_automatic_it_block (void)
+{
+  now_it.mask = 0x10;
+  now_it.block_length = 0;
+}
+
+/* Update the mask of the current automatically-generated IT
+   instruction. See comments in new_automatic_it_block ().  */
+static void
+now_it_add_mask (int cond)
+{
+#define CLEAR_BIT(value, nbit)  ((value) & ~(1 << (nbit)))
+#define SET_BIT_VALUE(value, bitvalue, nbit)  (CLEAR_BIT(value, nbit) \
+                                              | ((bitvalue) << (nbit)))
+
+  const int resulting_bit = (cond & 1);
+  now_it.mask &= 0xf;
+  now_it.mask = SET_BIT_VALUE (now_it.mask,
+                                   resulting_bit,
+                                  (5 - now_it.block_length));
+  now_it.mask = SET_BIT_VALUE (now_it.mask,
+                                   1,
+                                   ((5 - now_it.block_length) - 1) );
+  output_it_inst (now_it.cc, now_it.mask, now_it.insn);
+
+#undef CLEAR_BIT
+#undef SET_BIT_VALUE
+
+}
+
+/* The IT blocks handling machinery is accessed through the these functions:
+     it_fsm_pre_encode ()               from md_assemble ()
+     set_it_insn_type ()                optional, from the tencode functions
+     set_it_insn_type_last ()           ditto
+     in_it_block ()                     ditto
+     it_fsm_post_encode ()              from md_assemble ()
+     force_automatic_it_block_close ()  from label habdling functions
+
+   Rationale:
+     1) md_assemble () calls it_fsm_pre_encode () before calling tencode (),
+        initializing the IT insn type with a generic initial value depending
+        on the inst.condition.
+     2) During the tencode function, two things may happen:
+        a) The tencode function overrides the IT insn type by
+           calling either set_it_insn_type (type) or set_it_insn_type_last ().
+        b) The tencode function queries the IT block state by
+           calling in_it_block () (i.e. to determine narrow/not narrow mode).
+
+        Both set_it_insn_type and in_it_block run the internal FSM state
+        handling function (handle_it_state), because: a) setting the IT insn
+        type may incur in an invalid state (exiting the function),
+        and b) querying the state requires the FSM to be updated.
+        Specifically we want to avoid creating an IT block for conditional
+        branches, so it_fsm_pre_encode is actually a guess and we can't
+        determine whether an IT block is required until the tencode () routine
+        has decided what type of instruction this actually it.
+        Because of this, if set_it_insn_type and in_it_block have to be used,
+        set_it_insn_type has to be called first.
+
+        set_it_insn_type_last () is a wrapper of set_it_insn_type (type), that
+        determines the insn IT type depending on the inst.cond code.
+        When a tencode () routine encodes an instruction that can be
+        either outside an IT block, or, in the case of being inside, has to be
+        the last one, set_it_insn_type_last () will determine the proper
+        IT instruction type based on the inst.cond code. Otherwise,
+        set_it_insn_type can be called for overriding that logic or
+        for covering other cases.
+
+        Calling handle_it_state () may not transition the IT block state to
+        OUTSIDE_IT_BLOCK immediatelly, since the (current) state could be
+        still queried. Instead, if the FSM determines that the state should
+        be transitioned to OUTSIDE_IT_BLOCK, a flag is marked to be closed
+        after the tencode () function: that's what it_fsm_post_encode () does.
+
+        Since in_it_block () calls the state handling function to get an
+        updated state, an error may occur (due to invalid insns combination).
+        In that case, inst.error is set.
+        Therefore, inst.error has to be checked after the execution of
+        the tencode () routine.
+
+     3) Back in md_assemble(), it_fsm_post_encode () is called to commit
+        any pending state change (if any) that didn't take place in
+        handle_it_state () as explained above.  */
+
+static void
+it_fsm_pre_encode (void)
+{
+  if (inst.cond != COND_ALWAYS)
+    inst.it_insn_type = INSIDE_IT_INSN;
+  else
+    inst.it_insn_type = OUTSIDE_IT_INSN;
+
+  now_it.state_handled = 0;
+}
+
+/* IT state FSM handling function.  */
+static int
+handle_it_state (void)
+{
+  now_it.state_handled = 1;
+
+  switch(now_it.state)
+    {
+      case OUTSIDE_IT_BLOCK:
+        switch (inst.it_insn_type)
+          {
+            case OUTSIDE_IT_INSN:
+              break;
+
+            case INSIDE_IT_INSN:
+            case INSIDE_IT_LAST_INSN:
+              if (thumb_mode == 0)
+		{
+		  if (unified_syntax 
+		      && !(implicit_it_mode & IMPLICIT_IT_MODE_ARM))
+		    as_tsktsk (_("Warning: conditional outside an IT block"\
+				 " for Thumb."));
+                }
+              else
+                {
+                  if ((implicit_it_mode & IMPLICIT_IT_MODE_THUMB)
+		      && ARM_CPU_HAS_FEATURE (cpu_variant, arm_arch_t2))
+                    {
+                      /* Automatically generate the IT instruction.  */
+                      new_automatic_it_block (inst.cond);
+                      if (inst.it_insn_type == INSIDE_IT_LAST_INSN)
+                        close_automatic_it_block ();
+                    }
+                  else
+                    {
+                      inst.error = BAD_OUT_IT;
+                      return FAIL;
+                    }
+                }
+              break;
+
+            case IF_INSIDE_IT_LAST_INSN:
+            case NEUTRAL_IT_INSN:
+              break;
+
+            case IT_INSN:
+              now_it.state = MANUAL_IT_BLOCK;
+              now_it.block_length = 0;
+              break;
+          }
+      break;
+
+      case AUTOMATIC_IT_BLOCK:
+          /* Three things may happen now:
+              a) We should increment current it block size;
+              b) We should close current it block (closing insn or 4 insns);
+              c) We should close current it block and start a new one (due
+                 to incompatible conditions or
+                 4 insns-length block reached).  */
+
+        switch (inst.it_insn_type)
+          {
+            case OUTSIDE_IT_INSN:
+              /* The closure of the block shall happen immediatelly,
+                 so any in_it_block () call reports the block as closed.  */
+              force_automatic_it_block_close ();
+              break;
+
+            case INSIDE_IT_INSN:
+            case INSIDE_IT_LAST_INSN:
+            case IF_INSIDE_IT_LAST_INSN:
+              now_it.block_length++;
+
+              if (now_it.block_length > 4
+                  || !now_it_compatible (inst.cond))
+                {
+                  force_automatic_it_block_close ();
+                  if (inst.it_insn_type != IF_INSIDE_IT_LAST_INSN)
+                    new_automatic_it_block (inst.cond);
+                }
+              else
+                {
+                  now_it_add_mask (inst.cond);
+                }
+
+              if (now_it.state == AUTOMATIC_IT_BLOCK
+		  && (inst.it_insn_type == INSIDE_IT_LAST_INSN
+		      || inst.it_insn_type == IF_INSIDE_IT_LAST_INSN))
+                close_automatic_it_block ();
+              break;
+
+            case NEUTRAL_IT_INSN:
+              now_it.block_length++;
+
+              if (now_it.block_length > 4)
+                  force_automatic_it_block_close ();
+              else
+                  now_it_add_mask (now_it.cc & 1);
+              break;
+
+            case IT_INSN:
+              close_automatic_it_block ();
+              now_it.state = MANUAL_IT_BLOCK;
+              break;
+          }
+        break;
+
+      case MANUAL_IT_BLOCK:
+        {
+          /* Check conditional suffixes.  */
+          const int cond = now_it.cc ^ ((now_it.mask >> 4) & 1) ^ 1;
+          int is_last;
+          now_it.mask <<= 1;
+          now_it.mask &= 0x1f;
+          is_last = (now_it.mask == 0x10);
+
+          switch (inst.it_insn_type)
+            {
+              case OUTSIDE_IT_INSN:
+                inst.error = BAD_NOT_IT;
+                return FAIL;
+
+              case INSIDE_IT_INSN:
+                if (cond != inst.cond)
+                  {
+                    inst.error = BAD_IT_COND;
+                    return FAIL;
+                  }
+                break;
+
+              case INSIDE_IT_LAST_INSN:
+              case IF_INSIDE_IT_LAST_INSN:
+                if (cond != inst.cond)
+                  {
+                    inst.error = BAD_IT_COND;
+                    return FAIL;
+                  }
+                if (!is_last)
+                  {
+                    inst.error = BAD_BRANCH;
+                    return FAIL;
+                  }
+                break;
+
+              case NEUTRAL_IT_INSN:
+                /* The BKPT instruction is unconditional even in an IT block.  */
+                break;
+
+              case IT_INSN:
+                inst.error = BAD_IT_IT;
+                return FAIL;
+            }
+        }
+      break;
+    }
+
+  return SUCCESS;
+}
+
+static void
+it_fsm_post_encode (void)
+{
+  int is_last;
+
+  if (!now_it.state_handled)
+    handle_it_state ();
+
+  is_last = (now_it.mask == 0x10);
+  if (is_last)
+    {
+      now_it.state = OUTSIDE_IT_BLOCK;
+      now_it.mask = 0;
+    }
+}
+
+static void
+force_automatic_it_block_close (void)
+{
+  if (now_it.state == AUTOMATIC_IT_BLOCK)
+    {
+      close_automatic_it_block ();
+      now_it.state = OUTSIDE_IT_BLOCK;
+      now_it.mask = 0;
+    }
+}
+
+static int
+in_it_block (void)
+{
+  if (!now_it.state_handled)
+    handle_it_state ();
+
+  return now_it.state != OUTSIDE_IT_BLOCK;
+}
+
 void
 md_assemble (char *str)
 {
@@ -14751,36 +15172,19 @@ md_assemble (char *str)
 	    inst.size_req = 2;
 	}
 
-      /* Check conditional suffixes.  */
-      if (current_it_mask)
-	{
-	  int cond;
-	  cond = current_cc ^ ((current_it_mask >> 4) & 1) ^ 1;
-	  current_it_mask <<= 1;
-	  current_it_mask &= 0x1f;
-	  /* The BKPT instruction is unconditional even in an IT block.  */
-	  if (!inst.error
-	      && cond != inst.cond && opcode->tencode != do_t_bkpt)
-	    {
-	      as_bad (_("incorrect condition in IT block"));
-	      return;
-	    }
-	}
-      else if (inst.cond != COND_ALWAYS && opcode->tencode != do_t_branch)
-	{
-	  as_bad (_("thumb conditional instruction not in IT block"));
-	  return;
-	}
-
       mapping_state (MAP_THUMB);
       inst.instruction = opcode->tvalue;
 
       if (!parse_operands (p, opcode->operands))
-	opcode->tencode ();
+        {
+          /* Prepare the it_insn_type for those encodings that don't set
+             it.  */
+          it_fsm_pre_encode ();
 
-      /* Clear current_it_mask at the end of an IT block.  */
-      if (current_it_mask == 0x10)
-	current_it_mask = 0;
+          opcode->tencode ();
+
+          it_fsm_post_encode ();
+        }
 
       if (!(inst.error || inst.relax))
 	{
@@ -14839,7 +15243,11 @@ md_assemble (char *str)
 	inst.instruction |= inst.cond << 28;
       inst.size = INSN_SIZE;
       if (!parse_operands (p, opcode->operands))
-	opcode->aencode ();
+        {
+          it_fsm_pre_encode ();
+          opcode->aencode ();
+          it_fsm_post_encode ();
+        }
       /* Arm mode bx is marked as both v4T and v5 because it's still required
          on a hypothetical non-thumb v5 core.  */
       if (is_bx)
@@ -14857,6 +15265,20 @@ md_assemble (char *str)
   output_inst (str);
 }
 
+static void
+check_it_blocks_finished (void)
+{
+  asection *sect;
+
+  for (sect = stdoutput->sections; sect != NULL; sect = sect->next)
+    if (seg_info (sect)->tc_segment_info_data.current_it.state
+	== MANUAL_IT_BLOCK)
+      {
+	as_warn (_("section '%s' finished with an open IT block."),
+		 sect->name);
+      }
+}
+
 /* Various frobbings of labels and their addresses.  */
 
 void
@@ -14876,6 +15298,8 @@ arm_frob_label (symbolS * sym)
   ARM_SET_INTERWORK (sym, support_interwork);
 #endif
 
+  force_automatic_it_block_close ();
+
   /* Note - do not allow local symbols (.Lxxx) to be labelled
      as Thumb functions.  This is because these labels, whilst
      they exist inside Thumb code, are not the entry points for
@@ -15830,24 +16254,26 @@ static const struct asm_opcode insns[] =
 
   UT(cbnz,      b900,    2, (RR, EXP), t_cbz),
   UT(cbz,       b100,    2, (RR, EXP), t_cbz),
- /* ARM does not really have an IT instruction, so always allow it.  */
+ /* ARM does not really have an IT instruction, so always allow it. The opcode
+    is copied from Thumb in order to allow warnings
+    in -mimplicit-it=[never | arm] modes.  */
 #undef ARM_VARIANT
 #define ARM_VARIANT &arm_ext_v1
- TUE(it,        0,        bf08,     1, (COND),   it,    t_it),
- TUE(itt,       0,        bf0c,     1, (COND),   it,    t_it),
- TUE(ite,       0,        bf04,     1, (COND),   it,    t_it),
- TUE(ittt,      0,        bf0e,     1, (COND),   it,    t_it),
- TUE(itet,      0,        bf06,     1, (COND),   it,    t_it),
- TUE(itte,      0,        bf0a,     1, (COND),   it,    t_it),
- TUE(itee,      0,        bf02,     1, (COND),   it,    t_it),
- TUE(itttt,     0,        bf0f,     1, (COND),   it,    t_it),
- TUE(itett,     0,        bf07,     1, (COND),   it,    t_it),
- TUE(ittet,     0,        bf0b,     1, (COND),   it,    t_it),
- TUE(iteet,     0,        bf03,     1, (COND),   it,    t_it),
- TUE(ittte,     0,        bf0d,     1, (COND),   it,    t_it),
- TUE(itete,     0,        bf05,     1, (COND),   it,    t_it),
- TUE(ittee,     0,        bf09,     1, (COND),   it,    t_it),
- TUE(iteee,     0,        bf01,     1, (COND),   it,    t_it),
+ TUE(it,        bf08,        bf08,     1, (COND),   it,    t_it),
+ TUE(itt,       bf0c,        bf0c,     1, (COND),   it,    t_it),
+ TUE(ite,       bf04,        bf04,     1, (COND),   it,    t_it),
+ TUE(ittt,      bf0e,        bf0e,     1, (COND),   it,    t_it),
+ TUE(itet,      bf06,        bf06,     1, (COND),   it,    t_it),
+ TUE(itte,      bf0a,        bf0a,     1, (COND),   it,    t_it),
+ TUE(itee,      bf02,        bf02,     1, (COND),   it,    t_it),
+ TUE(itttt,     bf0f,        bf0f,     1, (COND),   it,    t_it),
+ TUE(itett,     bf07,        bf07,     1, (COND),   it,    t_it),
+ TUE(ittet,     bf0b,        bf0b,     1, (COND),   it,    t_it),
+ TUE(iteet,     bf03,        bf03,     1, (COND),   it,    t_it),
+ TUE(ittte,     bf0d,        bf0d,     1, (COND),   it,    t_it),
+ TUE(itete,     bf05,        bf05,     1, (COND),   it,    t_it),
+ TUE(ittee,     bf09,        bf09,     1, (COND),   it,    t_it),
+ TUE(iteee,     bf01,        bf01,     1, (COND),   it,    t_it),
  /* ARM/Thumb-2 instructions with no Thumb-1 equivalent.  */
  TC3(rrx,       01a00060, ea4f0030, 2, (RR, RR), rd_rm, t_rrx),
  TC3(rrxs,      01b00060, ea5f0030, 2, (RR, RR), rd_rm, t_rrx),
@@ -20258,15 +20684,14 @@ armelf_frob_symbol (symbolS * symp,
 
 /* MD interface: Finalization.	*/
 
-/* A good place to do this, although this was probably not intended
-   for this kind of use.  We need to dump the literal pool before
-   references are made to a null symbol pointer.  */
-
 void
 arm_cleanup (void)
 {
   literal_pool * pool;
 
+  /* Ensure that all the IT blocks are properly closed.  */
+  check_it_blocks_finished ();
+
   for (pool = list_of_pools; pool; pool = pool->next)
     {
       /* Put it at the end of the relevant section.  */
@@ -21276,6 +21701,29 @@ arm_parse_eabi (char * str)
 }
 #endif
 
+static int
+arm_parse_it_mode (char * str)
+{
+  int ret = 1;
+
+  if (streq ("arm", str))
+    implicit_it_mode = IMPLICIT_IT_MODE_ARM;
+  else if (streq ("thumb", str))
+    implicit_it_mode = IMPLICIT_IT_MODE_THUMB;
+  else if (streq ("always", str))
+    implicit_it_mode = IMPLICIT_IT_MODE_ALWAYS;
+  else if (streq ("never", str))
+    implicit_it_mode = IMPLICIT_IT_MODE_NEVER;
+  else
+    {
+      as_bad (_("unknown implicit IT mode `%s', should be "\
+                "arm, thumb, always, or never."), str);
+      ret = 0;
+    }
+
+  return ret;
+}
+
 struct arm_long_option_table arm_long_opts[] =
 {
   {"mcpu=", N_("<cpu name>\t  assemble for CPU <cpu name>"),
@@ -21290,6 +21738,8 @@ struct arm_long_option_table arm_long_op
   {"meabi=", N_("<ver>\t\t  assemble for eabi version <ver>"),
    arm_parse_eabi, NULL},
 #endif
+  {"mimplicit-it=", N_("<mode>\t  controls implicit insertion of IT instructions"),
+   arm_parse_it_mode, NULL},
   {NULL, NULL, 0, NULL}
 };
 
Index: gas/config/tc-arm.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.h,v
retrieving revision 1.50
diff -u -p -r1.50 tc-arm.h
--- gas/config/tc-arm.h	5 May 2009 11:41:31 -0000	1.50
+++ gas/config/tc-arm.h	9 Jun 2009 21:11:00 -0000
@@ -235,10 +235,26 @@ enum mstate
 
 void mapping_state (enum mstate);
 
+/* State variables for IT block handling.  */
+enum it_state
+{
+  OUTSIDE_IT_BLOCK, MANUAL_IT_BLOCK, AUTOMATIC_IT_BLOCK
+};
+struct current_it
+{
+  int mask;
+  enum it_state state;
+  int cc;
+  int block_length;
+  char *insn;
+  int state_handled;
+};
+
 struct arm_segment_info_type
 {
   enum mstate mapstate;
   unsigned int marked_pr_dependency;
+  struct current_it current_it;
 };
 
 /* We want .cfi_* pseudo-ops for generating unwind info.  */
Index: gas/doc/c-arm.texi
===================================================================
RCS file: /cvs/src/src/gas/doc/c-arm.texi,v
retrieving revision 1.56
diff -u -p -r1.56 c-arm.texi
--- gas/doc/c-arm.texi	2 Apr 2009 09:43:56 -0000	1.56
+++ gas/doc/c-arm.texi	9 Jun 2009 21:11:00 -0000
@@ -227,6 +227,11 @@ instructions; that is, it should behave 
 This option specifies that the output generated by the assembler should
 be marked as supporting interworking.
 
+@cindex @code{-mauto-it} command line option, ARM
+@item -mauto-it
+This option enables the automatic generation of IT instructions for
+conditional instructions not covered by an IT block.
+
 @cindex @code{-mapcs} command line option, ARM
 @item -mapcs @code{[26|32]}
 This option specifies that the output generated by the assembler should
Index: gas/testsuite/gas/arm/arm-it-auto-2.d
===================================================================
RCS file: gas/testsuite/gas/arm/arm-it-auto-2.d
diff -N gas/testsuite/gas/arm/arm-it-auto-2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/arm-it-auto-2.d	9 Jun 2009 21:11:00 -0000
@@ -0,0 +1,15 @@
+#name: ARM IT automatic instruction generation 2
+#as: -mthumb -march=armv7a -mimplicit-it=always
+#objdump: -d --prefix-addresses --show-raw-insn
+#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+00000000 <.text> 3a40      	subs	r2, #64
+00000002 <.text\+0x2> bfa1      	itttt	ge
+00000004 <.text\+0x4> e8a0 500a 	stmiage.w	r0!, {r1, r3, ip, lr}
+00000008 <.text\+0x8> e8a0 500a 	stmiage.w	r0!, {r1, r3, ip, lr}
+0000000c <.text\+0xc> e8a0 500a 	stmiage.w	r0!, {r1, r3, ip, lr}
+00000010 <.text\+0x10> e8a0 500a 	stmiage.w	r0!, {r1, r3, ip, lr}
+00000014 <.text\+0x14> dcf4      	bgt.n	00000000 <.text>
Index: gas/testsuite/gas/arm/arm-it-auto-2.s
===================================================================
RCS file: gas/testsuite/gas/arm/arm-it-auto-2.s
diff -N gas/testsuite/gas/arm/arm-it-auto-2.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/arm-it-auto-2.s	9 Jun 2009 21:11:00 -0000
@@ -0,0 +1,8 @@
+.syntax unified
+2:	subs	r2, r2, #64
+					@ IT generated automatically
+	stmge	r0!, {r1, r3, ip, lr}	@ 64 bytes at a time.
+	stmge	r0!, {r1, r3, ip, lr}
+	stmge	r0!, {r1, r3, ip, lr}
+	stmge	r0!, {r1, r3, ip, lr}
+	bgt	2b			@ This should not generate a new IT block
Index: gas/testsuite/gas/arm/arm-it-auto-3.d
===================================================================
RCS file: gas/testsuite/gas/arm/arm-it-auto-3.d
diff -N gas/testsuite/gas/arm/arm-it-auto-3.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/arm-it-auto-3.d	9 Jun 2009 21:11:00 -0000
@@ -0,0 +1,15 @@
+#name: ARM IT automatic instruction generation 3
+#as: -mthumb -march=armv7a -mimplicit-it=always
+#objdump: -d --prefix-addresses --show-raw-insn
+#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+
+.*: +file format .*arm.*
+
+Disassembly of section .text.one:
+00000000 <.text.one> 2800      	cmp	r0, #0
+00000002 <.text.one\+0x2> bf08      	it	eq
+00000004 <.text.one\+0x4> 3102      	addeq	r1, #2
+
+Disassembly of section .text.two:
+00000000 <.text.two> bf08      	it	eq
+00000002 <.text.two\+0x2> 3103      	addeq	r1, #3
Index: gas/testsuite/gas/arm/arm-it-auto-3.s
===================================================================
RCS file: gas/testsuite/gas/arm/arm-it-auto-3.s
diff -N gas/testsuite/gas/arm/arm-it-auto-3.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/arm-it-auto-3.s	9 Jun 2009 21:11:00 -0000
@@ -0,0 +1,10 @@
+	.syntax unified
+	.thumb
+	.section .text.one
+	cmp	r0, #0
+	addeq	r1, #2
+	.data
+	.word	33
+	.section .text.two
+	addeq	r1, #3
+
Index: gas/testsuite/gas/arm/arm-it-auto.d
===================================================================
RCS file: gas/testsuite/gas/arm/arm-it-auto.d
diff -N gas/testsuite/gas/arm/arm-it-auto.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/arm-it-auto.d	9 Jun 2009 21:11:00 -0000
@@ -0,0 +1,81 @@
+#name: ARM IT automatic instruction generation
+#as: -mthumb -march=armv7 -mimplicit-it=always
+#objdump: -d --prefix-addresses --show-raw-insn
+#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+00000000 <main> f000 f821 	bl	00000046 <main\+0x46>
+00000004 <main\+0x4> f000 f80c 	bl	00000020 <main\+0x20>
+00000008 <main\+0x8> f000 f813 	bl	00000032 <main\+0x32>
+0000000c <main\+0xc> d142      	bne.n	00000094 <main\+0x94>
+0000000e <main\+0xe> bf18      	it	ne
+00000010 <main\+0x10> 4487      	addne	pc, r0
+00000012 <main\+0x12> bf18      	it	ne
+00000014 <main\+0x14> e8d0 f001 	tbbne	\[r0, r1\]
+00000018 <main\+0x18> bf08      	it	eq
+0000001a <main\+0x1a> e8d1 f010 	tbheq	\[r1, r0, lsl #1\]
+0000001e <main\+0x1e> bf0a      	itet	eq
+00000020 <main\+0x20> 2002      	moveq	r0, #2
+00000022 <main\+0x22> 2003      	movne	r0, #3
+00000024 <main\+0x24> 2004      	moveq	r0, #4
+00000026 <main\+0x26> bf16      	itet	ne
+00000028 <main\+0x28> 2002      	movne	r0, #2
+0000002a <main\+0x2a> 2003      	moveq	r0, #3
+0000002c <main\+0x2c> 2004      	movne	r0, #4
+0000002e <main\+0x2e> bf18      	it	ne
+00000030 <main\+0x30> 2001      	movne	r0, #1
+00000032 <main\+0x32> bf0c      	ite	eq
+00000034 <main\+0x34> 2002      	moveq	r0, #2
+00000036 <main\+0x36> f8d1 f000 	ldrne.w	pc, \[r1\]
+0000003a <main\+0x3a> bf18      	it	ne
+0000003c <main\+0x3c> f000 f82a 	blne	00000094 <main\+0x94>
+00000040 <main\+0x40> bfb8      	it	lt
+00000042 <main\+0x42> f000 f828 	bllt	00000096 <main\+0x96>
+00000046 <main\+0x46> bf17      	itett	ne
+00000048 <main\+0x48> 202d      	movne	r0, #45
+0000004a <main\+0x4a> 2005      	moveq	r0, #5
+0000004c <main\+0x4c> 2006      	movne	r0, #6
+0000004e <main\+0x4e> 4487      	addne	pc, r0
+00000050 <main\+0x50> bf0d      	iteet	eq
+00000052 <main\+0x52> 2007      	moveq	r0, #7
+00000054 <main\+0x54> 2008      	movne	r0, #8
+00000056 <main\+0x56> 2003      	movne	r0, #3
+00000058 <main\+0x58> 2004      	moveq	r0, #4
+0000005a <main\+0x5a> bf0b      	itete	eq
+0000005c <main\+0x5c> 2005      	moveq	r0, #5
+0000005e <main\+0x5e> 2006      	movne	r0, #6
+00000060 <main\+0x60> 2007      	moveq	r0, #7
+00000062 <main\+0x62> 2008      	movne	r0, #8
+00000064 <main\+0x64> bf0c      	ite	eq
+00000066 <main\+0x66> 2005      	moveq	r0, #5
+00000068 <main\+0x68> 2006      	movne	r0, #6
+0000006a <main\+0x6a> 4687      	mov	pc, r0
+0000006c <main\+0x6c> bf0b      	itete	eq
+0000006e <main\+0x6e> 2007      	moveq	r0, #7
+00000070 <main\+0x70> 2008      	movne	r0, #8
+00000072 <main\+0x72> 2005      	moveq	r0, #5
+00000074 <main\+0x74> 2006      	movne	r0, #6
+00000076 <main\+0x76> 4487      	add	pc, r0
+00000078 <main\+0x78> bf0c      	ite	eq
+0000007a <main\+0x7a> 2007      	moveq	r0, #7
+0000007c <main\+0x7c> 2008      	movne	r0, #8
+0000007e <main\+0x7e> bfcc      	ite	gt
+00000080 <main\+0x80> 2009      	movgt	r0, #9
+00000082 <main\+0x82> 200a      	movle	r0, #10
+00000084 <main\+0x84> bf08      	it	eq
+00000086 <main\+0x86> 200b      	moveq	r0, #11
+00000088 <main\+0x88> bfd8      	it	le
+0000008a <main\+0x8a> 200c      	movle	r0, #12
+0000008c <main\+0x8c> bf18      	it	ne
+0000008e <main\+0x8e> 200d      	movne	r0, #13
+00000090 <main\+0x90> f7ff fffe 	bl	00000000 <f>
+00000094 <f\+0x94> bd10      	pop	{r4, pc}
+00000096 <f\+0x96> f7ff fffe 	bl	00000000 <f>
+0000009a <f\+0x9a> bfb8      	it	lt
+0000009c <f\+0x9c> 2000      	movlt	r0, #0
+0000009e <f\+0x9e> 4348      	muls	r0, r1
+000000a0 <f\+0xa0> bfb8      	it	lt
+000000a2 <f\+0xa2> 2000      	movlt	r0, #0
+000000a4 <f\+0xa4> 4348      	muls	r0, r1
Index: gas/testsuite/gas/arm/arm-it-auto.s
===================================================================
RCS file: gas/testsuite/gas/arm/arm-it-auto.s
diff -N gas/testsuite/gas/arm/arm-it-auto.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/arm-it-auto.s	9 Jun 2009 21:11:00 -0000
@@ -0,0 +1,110 @@
+	.syntax unified
+	.arch armv7
+	.thumb
+main:
+
+@These branches are to see the labels in the generated file
+	bl .L888
+	bl .L111
+	bl .L777
+
+@No IT block here:
+	bne .L4
+
+@The following groups should be an IT block each.
+@it ne
+	addne.n   pc, r0
+
+@it ne
+	tbbne [r0, r1]
+
+@it eq
+	tbheq [r1, r0]
+
+@The following group should be left as is:
+	itet	eq
+.L111:	moveq	r0, #2
+	movne   r0, #3
+	moveq   r0, #4
+
+@Same, reverted condition:
+	itet	ne
+	movne	r0, #2
+	moveq   r0, #3
+	movne   r0, #4
+
+
+@Two groups shall be generated, due to the label:
+    movne   r0, #1
+@ second group, the label should be at the IT insn
+.L777:	moveq	r0, #2
+	ldrne   pc, [r1]
+
+@it ne
+	blne .L4
+    
+@it lt
+	bllt .L9
+
+@itett ne
+.L888:	movne   r0, #45
+	moveq   r0, #5
+	movne	r0, #6
+	addne.n pc, r0
+
+@iteet eq
+	moveq   r0, #7
+	movne	r0, #8
+	movne   r0, #3
+	moveq	r0, #4
+
+@itete eq
+	moveq   r0, #5
+	movne	r0, #6
+	moveq   r0, #7
+	movne	r0, #8
+
+@ite eq - this group finishes due to the mov.n pc, rn
+	moveq   r0, #5
+	movne	r0, #6
+	mov.n   pc, r0
+
+@itete eq
+	moveq   r0, #7
+	movne	r0, #8
+	moveq   r0, #5
+	movne	r0, #6
+
+@this shall not generate an IT block
+	add.n   pc, r0
+
+@ite eq - testing condition change (eq -> gt)
+	moveq   r0, #7
+	movne	r0, #8
+
+@ite gt (group shall finish due to another condition change)
+	movgt	r0, #9
+	movle	r0, #10
+
+@it eq
+	moveq	r0, #11
+
+@it le
+	movle	r0, #12
+
+@it ne
+	movne	r0, #13
+
+	bl	f
+.L4:
+	pop	{r4, pc}
+.L9:
+	bl	f
+
+@Only the movlt shall be enclosed in the IT block
+movlt r0, #0
+muls r0, r0, r1
+
+@Same here:
+movlt r0, #0
+muls r0, r0, r1
Index: gas/testsuite/gas/arm/arm-it-bad-2.d
===================================================================
RCS file: gas/testsuite/gas/arm/arm-it-bad-2.d
diff -N gas/testsuite/gas/arm/arm-it-bad-2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/arm-it-bad-2.d	9 Jun 2009 21:11:00 -0000
@@ -0,0 +1,3 @@
+#name: Test unclosed IT block validation.
+#as: -march=armv7a
+#error-output: arm-it-bad-2.l
Index: gas/testsuite/gas/arm/arm-it-bad-2.l
===================================================================
RCS file: gas/testsuite/gas/arm/arm-it-bad-2.l
diff -N gas/testsuite/gas/arm/arm-it-bad-2.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/arm-it-bad-2.l	9 Jun 2009 21:11:00 -0000
@@ -0,0 +1,3 @@
+[^:]*: Assembler messages:
+[^:]*:9: Warning: section '.text' finished with an open IT block.
+[^:]*:9: Warning: section 'second' finished with an open IT block.
Index: gas/testsuite/gas/arm/arm-it-bad-2.s
===================================================================
RCS file: gas/testsuite/gas/arm/arm-it-bad-2.s
diff -N gas/testsuite/gas/arm/arm-it-bad-2.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/arm-it-bad-2.s	9 Jun 2009 21:11:00 -0000
@@ -0,0 +1,9 @@
+        .syntax unified
+        .text
+        cmp     r0, #0
+        itt     eq
+        moveq   r0, r1
+.section second
+	itt ne
+	movne r0, r1
+
Index: gas/testsuite/gas/arm/arm-it-bad-3.d
===================================================================
RCS file: gas/testsuite/gas/arm/arm-it-bad-3.d
diff -N gas/testsuite/gas/arm/arm-it-bad-3.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/arm-it-bad-3.d	9 Jun 2009 21:11:00 -0000
@@ -0,0 +1,3 @@
+#name: Test automatic IT generation in Thumb-1 architectures.
+#as: -mimplicit-it=always
+#error-output: arm-it-bad-3.l
Index: gas/testsuite/gas/arm/arm-it-bad-3.l
===================================================================
RCS file: gas/testsuite/gas/arm/arm-it-bad-3.l
diff -N gas/testsuite/gas/arm/arm-it-bad-3.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/arm-it-bad-3.l	9 Jun 2009 21:11:00 -0000
@@ -0,0 +1,3 @@
+[^:]*: Assembler messages:
+[^:]*:4: Error: thumb conditional instruction should be in IT block -- `moveq r1,r8'
+[^:]*:5: Error: thumb conditional instruction should be in IT block -- `movne r1,r9'
Index: gas/testsuite/gas/arm/arm-it-bad-3.s
===================================================================
RCS file: gas/testsuite/gas/arm/arm-it-bad-3.s
diff -N gas/testsuite/gas/arm/arm-it-bad-3.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/arm-it-bad-3.s	9 Jun 2009 21:11:00 -0000
@@ -0,0 +1,6 @@
+.syntax unified
+.arch armv6
+.thumb
+moveq   r1, r8
+movne   r1, r9
+
Index: gas/testsuite/gas/arm/arm-it-bad.d
===================================================================
RCS file: gas/testsuite/gas/arm/arm-it-bad.d
diff -N gas/testsuite/gas/arm/arm-it-bad.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/arm-it-bad.d	9 Jun 2009 21:11:00 -0000
@@ -0,0 +1,3 @@
+#name: Test IT block validation in ARM mode.
+#as: -march=armv7a -mimplicit-it=never
+#error-output: arm-it-bad.l
Index: gas/testsuite/gas/arm/arm-it-bad.l
===================================================================
RCS file: gas/testsuite/gas/arm/arm-it-bad.l
diff -N gas/testsuite/gas/arm/arm-it-bad.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/arm-it-bad.l	9 Jun 2009 21:11:00 -0000
@@ -0,0 +1,3 @@
+[^:]*: Assembler messages:
+[^:]*:8: Error: incorrect condition in IT block -- `moveq r0,r1'
+[^:]*:10: Warning: conditional outside an IT block for Thumb.
Index: gas/testsuite/gas/arm/arm-it-bad.s
===================================================================
RCS file: gas/testsuite/gas/arm/arm-it-bad.s
diff -N gas/testsuite/gas/arm/arm-it-bad.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/arm-it-bad.s	9 Jun 2009 21:11:00 -0000
@@ -0,0 +1,10 @@
+	.syntax unified
+	.text
+	.global x
+x:
+	mov	r0, r1
+	cmp	r0, #0
+	it	ne
+	moveq	r0, r1
+	bx	lr
+	movgt	r1, r2
Index: gas/testsuite/gas/arm/thumb2_it.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/thumb2_it.d,v
retrieving revision 1.2
diff -u -p -r1.2 thumb2_it.d
--- gas/testsuite/gas/arm/thumb2_it.d	15 Aug 2005 19:19:55 -0000	1.2
+++ gas/testsuite/gas/arm/thumb2_it.d	9 Jun 2009 21:11:00 -0000
@@ -1,62 +1,61 @@
 # name: Mixed 16 and 32-bit Thumb conditional instructions
 # as: -march=armv6kt2
 # objdump: -dr --prefix-addresses --show-raw-insn
-# Many of these patterns use "(eq|s)". These should be changed to just "eq"
-# once the disassembler is fixed. Likewise for "(eq)?"
+# Modifications to this file shall be mirrored to thumb2_it_auto.d
 
 .*: +file format .*arm.*
 
 Disassembly of section .text:
 0+000 <[^>]+> bf05      	ittet	eq
-0+002 <[^>]+> 1880      	add(eq|s)	r0, r0, r2
-0+004 <[^>]+> 4440      	add(eq)?	r0, r8
-0+006 <[^>]+> 1888      	add(ne|s)	r0, r1, r2
-0+008 <[^>]+> eb11 0002 	adds(eq)?.w	r0, r1, r2
+0+002 <[^>]+> 1880      	addeq	r0, r0, r2
+0+004 <[^>]+> 4440      	addeq	r0, r8
+0+006 <[^>]+> 1888      	addne	r0, r1, r2
+0+008 <[^>]+> eb11 0002 	addseq.w	r0, r1, r2
 0+00c <[^>]+> 4410      	add	r0, r2
 0+00e <[^>]+> 4440      	add	r0, r8
 0+010 <[^>]+> 1880      	adds	r0, r0, r2
 0+012 <[^>]+> eb10 0008 	adds.w	r0, r0, r8
 0+016 <[^>]+> 1888      	adds	r0, r1, r2
 0+018 <[^>]+> bf0a      	itet	eq
-0+01a <[^>]+> 4310      	orr(eq|s)	r0, r2
-0+01c <[^>]+> ea40 0008 	orr(ne)?.w	r0, r0, r8
-0+020 <[^>]+> ea50 0002 	orrs(eq)?.w	r0, r0, r2
+0+01a <[^>]+> 4310      	orreq	r0, r2
+0+01c <[^>]+> ea40 0008 	orrne.w	r0, r0, r8
+0+020 <[^>]+> ea50 0002 	orrseq.w	r0, r0, r2
 0+024 <[^>]+> ea40 0002 	orr.w	r0, r0, r2
 0+028 <[^>]+> ea40 0008 	orr.w	r0, r0, r8
 0+02c <[^>]+> 4310      	orrs	r0, r2
 0+02e <[^>]+> bf01      	itttt	eq
-0+030 <[^>]+> 4090      	lsl(eq|s)	r0, r2
-0+032 <[^>]+> fa00 f008 	lsl(eq)?.w	r0, r0, r8
-0+036 <[^>]+> fa01 f002 	lsl(eq)?.w	r0, r1, r2
-0+03a <[^>]+> fa10 f002 	lsls(eq)?.w	r0, r0, r2
+0+030 <[^>]+> 4090      	lsleq	r0, r2
+0+032 <[^>]+> fa00 f008 	lsleq.w	r0, r0, r8
+0+036 <[^>]+> fa01 f002 	lsleq.w	r0, r1, r2
+0+03a <[^>]+> fa10 f002 	lslseq.w	r0, r0, r2
 0+03e <[^>]+> bf02      	ittt	eq
-0+040 <[^>]+> 0048      	lsl(eq|s)	r0, r1, #1
-0+042 <[^>]+> ea4f 0048 	mov(eq)?.w	r0, r8, lsl #1
-0+046 <[^>]+> ea5f 0040 	movs(eq)?.w	r0, r0, lsl #1
+0+040 <[^>]+> 0048      	lsleq	r0, r1, #1
+0+042 <[^>]+> ea4f 0048 	moveq.w	r0, r8, lsl #1
+0+046 <[^>]+> ea5f 0040 	movseq.w	r0, r0, lsl #1
 0+04a <[^>]+> fa00 f002 	lsl.w	r0, r0, r2
 0+04e <[^>]+> 4090      	lsls	r0, r2
 0+050 <[^>]+> ea4f 0041 	mov.w	r0, r1, lsl #1
 0+054 <[^>]+> 0048      	lsls	r0, r1, #1
 0+056 <[^>]+> bf01      	itttt	eq
-0+058 <[^>]+> 4288      	cmp(eq)?	r0, r1
-0+05a <[^>]+> 4540      	cmp(eq)?	r0, r8
-0+05c <[^>]+> 4608      	mov(eq)?	r0, r1
-0+05e <[^>]+> ea5f 0001 	movs(eq)?.w	r0, r1
+0+058 <[^>]+> 4288      	cmpeq	r0, r1
+0+05a <[^>]+> 4540      	cmpeq	r0, r8
+0+05c <[^>]+> 4608      	moveq	r0, r1
+0+05e <[^>]+> ea5f 0001 	movseq.w	r0, r1
 0+062 <[^>]+> bf08      	it	eq
-0+064 <[^>]+> 4640      	mov(eq)?	r0, r8
-0+066 <[^>]+> 4608      	mov(eq)?	r0, r1
+0+064 <[^>]+> 4640      	moveq	r0, r8
+0+066 <[^>]+> 4608      	mov	r0, r1
 0+068 <[^>]+> 1c08      	adds	r0, r1, #0
 0+06a <[^>]+> ea5f 0008 	movs.w	r0, r8
 0+06e <[^>]+> bf01      	itttt	eq
-0+070 <[^>]+> 43c8      	mvn(eq|s)	r0, r1
-0+072 <[^>]+> ea6f 0008 	mvn(eq)?.w	r0, r8
-0+076 <[^>]+> ea7f 0001 	mvns(eq)?.w	r0, r1
-0+07a <[^>]+> 42c8      	cmn(eq)?	r0, r1
+0+070 <[^>]+> 43c8      	mvneq	r0, r1
+0+072 <[^>]+> ea6f 0008 	mvneq.w	r0, r8
+0+076 <[^>]+> ea7f 0001 	mvnseq.w	r0, r1
+0+07a <[^>]+> 42c8      	cmneq	r0, r1
 0+07c <[^>]+> ea6f 0001 	mvn.w	r0, r1
 0+080 <[^>]+> 43c8      	mvns	r0, r1
 0+082 <[^>]+> bf02      	ittt	eq
-0+084 <[^>]+> 4248      	neg(eq|s)	r0, r1
-0+086 <[^>]+> f1c8 0000 	rsb(eq)?	r0, r8, #0	; 0x0
-0+08a <[^>]+> f1d1 0000 	rsbs(eq)?	r0, r1, #0	; 0x0
+0+084 <[^>]+> 4248      	negeq	r0, r1
+0+086 <[^>]+> f1c8 0000 	rsbeq	r0, r8, #0	; 0x0
+0+08a <[^>]+> f1d1 0000 	rsbseq	r0, r1, #0	; 0x0
 0+08e <[^>]+> f1c1 0000 	rsb	r0, r1, #0	; 0x0
 0+092 <[^>]+> 4248      	negs	r0, r1
Index: gas/testsuite/gas/arm/thumb2_it_auto.d
===================================================================
RCS file: gas/testsuite/gas/arm/thumb2_it_auto.d
diff -N gas/testsuite/gas/arm/thumb2_it_auto.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/thumb2_it_auto.d	9 Jun 2009 21:11:00 -0000
@@ -0,0 +1,61 @@
+# name: Mixed 16 and 32-bit Thumb conditional instructions
+# as: -march=armv6kt2 -mimplicit-it=always
+# source: thumb2_it.s
+# objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0+000 <[^>]+> bf05      	ittet	eq
+0+002 <[^>]+> 1880      	addeq	r0, r0, r2
+0+004 <[^>]+> 4440      	addeq	r0, r8
+0+006 <[^>]+> 1888      	addne	r0, r1, r2
+0+008 <[^>]+> eb11 0002 	addseq.w	r0, r1, r2
+0+00c <[^>]+> 4410      	add	r0, r2
+0+00e <[^>]+> 4440      	add	r0, r8
+0+010 <[^>]+> 1880      	adds	r0, r0, r2
+0+012 <[^>]+> eb10 0008 	adds.w	r0, r0, r8
+0+016 <[^>]+> 1888      	adds	r0, r1, r2
+0+018 <[^>]+> bf0a      	itet	eq
+0+01a <[^>]+> 4310      	orreq	r0, r2
+0+01c <[^>]+> ea40 0008 	orrne.w	r0, r0, r8
+0+020 <[^>]+> ea50 0002 	orrseq.w	r0, r0, r2
+0+024 <[^>]+> ea40 0002 	orr.w	r0, r0, r2
+0+028 <[^>]+> ea40 0008 	orr.w	r0, r0, r8
+0+02c <[^>]+> 4310      	orrs	r0, r2
+0+02e <[^>]+> bf01      	itttt	eq
+0+030 <[^>]+> 4090      	lsleq	r0, r2
+0+032 <[^>]+> fa00 f008 	lsleq.w	r0, r0, r8
+0+036 <[^>]+> fa01 f002 	lsleq.w	r0, r1, r2
+0+03a <[^>]+> fa10 f002 	lslseq.w	r0, r0, r2
+0+03e <[^>]+> bf02      	ittt	eq
+0+040 <[^>]+> 0048      	lsleq	r0, r1, #1
+0+042 <[^>]+> ea4f 0048 	moveq.w	r0, r8, lsl #1
+0+046 <[^>]+> ea5f 0040 	movseq.w	r0, r0, lsl #1
+0+04a <[^>]+> fa00 f002 	lsl.w	r0, r0, r2
+0+04e <[^>]+> 4090      	lsls	r0, r2
+0+050 <[^>]+> ea4f 0041 	mov.w	r0, r1, lsl #1
+0+054 <[^>]+> 0048      	lsls	r0, r1, #1
+0+056 <[^>]+> bf01      	itttt	eq
+0+058 <[^>]+> 4288      	cmpeq	r0, r1
+0+05a <[^>]+> 4540      	cmpeq	r0, r8
+0+05c <[^>]+> 4608      	moveq	r0, r1
+0+05e <[^>]+> ea5f 0001 	movseq.w	r0, r1
+0+062 <[^>]+> bf08      	it	eq
+0+064 <[^>]+> 4640      	moveq	r0, r8
+0+066 <[^>]+> 4608      	mov	r0, r1
+0+068 <[^>]+> 1c08      	adds	r0, r1, #0
+0+06a <[^>]+> ea5f 0008 	movs.w	r0, r8
+0+06e <[^>]+> bf01      	itttt	eq
+0+070 <[^>]+> 43c8      	mvneq	r0, r1
+0+072 <[^>]+> ea6f 0008 	mvneq.w	r0, r8
+0+076 <[^>]+> ea7f 0001 	mvnseq.w	r0, r1
+0+07a <[^>]+> 42c8      	cmneq	r0, r1
+0+07c <[^>]+> ea6f 0001 	mvn.w	r0, r1
+0+080 <[^>]+> 43c8      	mvns	r0, r1
+0+082 <[^>]+> bf02      	ittt	eq
+0+084 <[^>]+> 4248      	negeq	r0, r1
+0+086 <[^>]+> f1c8 0000 	rsbeq	r0, r8, #0	; 0x0
+0+08a <[^>]+> f1d1 0000 	rsbseq	r0, r1, #0	; 0x0
+0+08e <[^>]+> f1c1 0000 	rsb	r0, r1, #0	; 0x0
+0+092 <[^>]+> 4248      	negs	r0, r1
Index: gas/testsuite/gas/arm/thumb2_it_bad.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/thumb2_it_bad.d,v
retrieving revision 1.3
diff -u -p -r1.3 thumb2_it_bad.d
--- gas/testsuite/gas/arm/thumb2_it_bad.d	20 Apr 2006 12:39:51 -0000	1.3
+++ gas/testsuite/gas/arm/thumb2_it_bad.d	9 Jun 2009 21:11:00 -0000
@@ -1,3 +1,4 @@
 #name: Invalid IT instructions
 #as:
 #error-output: thumb2_it_bad.l
+# Modifications to this test shall be mirrored to thumb2_it_bad_auto.d.
Index: gas/testsuite/gas/arm/thumb2_it_bad.l
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/thumb2_it_bad.l,v
retrieving revision 1.1
diff -u -p -r1.1 thumb2_it_bad.l
--- gas/testsuite/gas/arm/thumb2_it_bad.l	20 Mar 2006 15:38:02 -0000	1.1
+++ gas/testsuite/gas/arm/thumb2_it_bad.l	9 Jun 2009 21:11:00 -0000
@@ -9,4 +9,4 @@
 [^:]*:17: Error: instruction not allowed in IT block -- `cpseq #0x10'
 [^:]*:19: Error: instruction is always unconditional -- `bkpteq 0'
 [^:]*:20: Error: instruction not allowed in IT block -- `setendeq le'
-[^:]*:22: Error: instruction not allowed in IT block -- `iteq eq'
+[^:]*:22: Error: IT falling in the range of a previous IT block -- `iteq eq'
Index: gas/testsuite/gas/arm/thumb2_it_bad_auto.d
===================================================================
RCS file: gas/testsuite/gas/arm/thumb2_it_bad_auto.d
diff -N gas/testsuite/gas/arm/thumb2_it_bad_auto.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/thumb2_it_bad_auto.d	9 Jun 2009 21:11:00 -0000
@@ -0,0 +1,4 @@
+#name: Invalid IT instructions
+#as: -mimplicit-it=always
+#source: thumb2_it_bad.s
+#error-output: thumb2_it_bad.l

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