2009-07-01 Paul Brook <paul@codesourcery.com>
authorPaul Brook <paul@codesourcery.com>
Wed, 1 Jul 2009 11:44:54 +0000 (11:44 +0000)
committerPaul Brook <paul@codesourcery.com>
Wed, 1 Jul 2009 11:44:54 +0000 (11:44 +0000)
gas/
* config/tc-arm.c (MISSING_FNSTART): Define.
(s_arm_unwind_fnstart): Diagnose duplicate directive.
(s_arm_unwind_handlerdata, s_arm_unwind_fnend, s_arm_unwind_fnend,
s_arm_unwind_cantunwind, s_arm_unwind_personalityindex,
s_arm_unwind_personality, s_arm_unwind_save, s_arm_unwind_movsp,
s_arm_unwind_pad, s_arm_unwind_setfp, s_arm_unwind_raw): Error if
not inside function unwinding region.

gas/testsuite/
* gas/arm/fp-save.s: Add .fnstart and .fnend directives.

gas/ChangeLog
gas/config/tc-arm.c
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/fp-save.s

index 6d09980ca44bc44aff5ed7b22bc064342045b03a..32bb41305b963ad0a578ccf9bbf66c7ff92bc52a 100644 (file)
@@ -1,3 +1,13 @@
+2009-07-01  Paul Brook <paul@codesourcery.com>
+
+       * config/tc-arm.c (MISSING_FNSTART): Define.
+       (s_arm_unwind_fnstart): Diagnose duplicate directive.
+       (s_arm_unwind_handlerdata, s_arm_unwind_fnend, s_arm_unwind_fnend,
+       s_arm_unwind_cantunwind, s_arm_unwind_personalityindex,
+       s_arm_unwind_personality, s_arm_unwind_save, s_arm_unwind_movsp,
+       s_arm_unwind_pad, s_arm_unwind_setfp, s_arm_unwind_raw): Error if
+       not inside function unwinding region.
+
 2009-06-29  H.J. Lu  <hongjiu.lu@intel.com>
 
        * config/tc-i386.c: Reformat.
index e853f239284e1d9cf2501ccb9021dee3acff6c17..35498f20c912c87216dd6dec0ea07da810cc49d9 100644 (file)
@@ -701,6 +701,7 @@ struct asm_opcode
 #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")
+#define MISSING_FNSTART        _("missing .fnstart before unwinding directive")
 
 static struct hash_control *arm_ops_hsh;
 static struct hash_control *arm_cond_hsh;
@@ -3156,6 +3157,12 @@ static void
 s_arm_unwind_fnstart (int ignored ATTRIBUTE_UNUSED)
 {
   demand_empty_rest_of_line ();
+  if (unwind.proc_start)
+    {
+      as_bad(_("duplicate .fnstart directive"));
+      return;
+    }
+
   /* Mark the start of the function.  */
   unwind.proc_start = expr_build_dot ();
 
@@ -3179,6 +3186,9 @@ static void
 s_arm_unwind_handlerdata (int ignored ATTRIBUTE_UNUSED)
 {
   demand_empty_rest_of_line ();
+  if (!unwind.proc_start)
+    as_bad(MISSING_FNSTART);
+
   if (unwind.table_entry)
     as_bad (_("duplicate .handlerdata directive"));
 
@@ -3196,6 +3206,12 @@ s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
 
   demand_empty_rest_of_line ();
 
+  if (!unwind.proc_start)
+    {
+      as_bad(_(".fnend directive without .fnstart"));
+      return;
+    }
+
   /* Add eh table entry.  */
   if (unwind.table_entry == NULL)
     val = create_unwind_entry (0);
@@ -3242,6 +3258,8 @@ s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
 
   /* Restore the original section.  */
   subseg_set (unwind.saved_seg, unwind.saved_subseg);
+
+  unwind.proc_start = NULL;
 }
 
 
@@ -3251,6 +3269,9 @@ static void
 s_arm_unwind_cantunwind (int ignored ATTRIBUTE_UNUSED)
 {
   demand_empty_rest_of_line ();
+  if (!unwind.proc_start)
+    as_bad(MISSING_FNSTART);
+
   if (unwind.personality_routine || unwind.personality_index != -1)
     as_bad (_("personality routine specified for cantunwind frame"));
 
@@ -3265,6 +3286,9 @@ s_arm_unwind_personalityindex (int ignored ATTRIBUTE_UNUSED)
 {
   expressionS exp;
 
+  if (!unwind.proc_start)
+    as_bad(MISSING_FNSTART);
+
   if (unwind.personality_routine || unwind.personality_index != -1)
     as_bad (_("duplicate .personalityindex directive"));
 
@@ -3291,6 +3315,9 @@ s_arm_unwind_personality (int ignored ATTRIBUTE_UNUSED)
 {
   char *name, *p, c;
 
+  if (!unwind.proc_start)
+    as_bad(MISSING_FNSTART);
+
   if (unwind.personality_routine || unwind.personality_index != -1)
     as_bad (_("duplicate .personality directive"));
 
@@ -3727,6 +3754,9 @@ s_arm_unwind_save (int arch_v6)
   struct reg_entry *reg;
   bfd_boolean had_brace = FALSE;
 
+  if (!unwind.proc_start)
+    as_bad(MISSING_FNSTART);
+
   /* Figure out what sort of save we have.  */
   peek = input_line_pointer;
 
@@ -3784,6 +3814,9 @@ s_arm_unwind_movsp (int ignored ATTRIBUTE_UNUSED)
   valueT op;
   int offset;
 
+  if (!unwind.proc_start)
+    as_bad(MISSING_FNSTART);
+
   reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
   if (reg == FAIL)
     {
@@ -3829,6 +3862,9 @@ s_arm_unwind_pad (int ignored ATTRIBUTE_UNUSED)
 {
   int offset;
 
+  if (!unwind.proc_start)
+    as_bad(MISSING_FNSTART);
+
   if (immediate_for_directive (&offset) == FAIL)
     return;
 
@@ -3855,6 +3891,9 @@ s_arm_unwind_setfp (int ignored ATTRIBUTE_UNUSED)
   int fp_reg;
   int offset;
 
+  if (!unwind.proc_start)
+    as_bad(MISSING_FNSTART);
+
   fp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
   if (skip_past_comma (&input_line_pointer) == FAIL)
     sp_reg = FAIL;
@@ -3905,6 +3944,9 @@ s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED)
   unsigned char op[16];
   int count;
 
+  if (!unwind.proc_start)
+    as_bad(MISSING_FNSTART);
+
   expression (&exp);
   if (exp.X_op == O_constant
       && skip_past_comma (&input_line_pointer) != FAIL)
index 678a0a260172a8486008cecd0a24d4fe8aef8b8a..09149bbb6e4f349a1cfa72b20598a8429edc9f7e 100644 (file)
@@ -1,3 +1,7 @@
+2009-07-01  Paul Brook <paul@codesourcery.com>
+
+       * gas/arm/fp-save.s: Add .fnstart and .fnend directives.
+
 2009-06-30  Nick Clifton  <nickc@redhat.com>
 
        PR 10288
index d86d7493523f72269aecdf84ccf0aa697298bb96..d0a572aab4018c8a523884fa5ea681a84f551265 100644 (file)
@@ -1,2 +1,4 @@
+       .fnstart\r
        sfmfd   f4, 1, [sp]!\r
        .save f4, 1\r
+       .fnend\r