* Fix for PR 16389, brought over from d30v branch.
authorFrank Ch. Eigler <fche@redhat.com>
Thu, 30 Jul 1998 19:41:18 +0000 (19:41 +0000)
committerFrank Ch. Eigler <fche@redhat.com>
Thu, 30 Jul 1998 19:41:18 +0000 (19:41 +0000)
Thu Jul 30 21:38:43 1998  Frank Ch. Eigler  <fche@cygnus.com>
* config/tc-d30v.c ({cur,prev}_left_kills_right_p): New variables.
(write_2_short): Emit warning if new flag is set.
(do_assemble): Set flags if left instruction is one of special
"right-instruction-killer" type.

gas/ChangeLog
gas/config/tc-d30v.c

index a54ab3a95a3cd3eb21627780ec17a90d45542f2e..f8b451df3ee88395976f9bbfbfd2238b9829772e 100644 (file)
@@ -1,3 +1,17 @@
+Thu Jul 30 21:38:43 1998  Frank Ch. Eigler  <fche@cygnus.com>
+
+       * config/tc-d30v.c ({cur,prev}_left_kills_right_p): New variables.
+       (write_2_short): Emit warning if new flag is set.
+       (do_assemble): Set flags if left instruction is one of special
+       "right-instruction-killer" type.
+
+Tue Jun 28 18:12:28 1998  Stan Cox  <scox@cygnus.com>
+       
+       * config/tc-sparc.c (md_number_to_chars, cons_fix_new_sparc):
+       Always output words in debug_info section as big endian.
+       (sparc_target_format): Choose correct bfd target.
+       (md_apply_fix3): Rename BFD_RELOC_SPARC_32LE to BFD_RELOC_SPARC_REV32.
+       
 Tue Jul 28 11:01:21 1998  Jeffrey A Law  (law@cygnus.com)
 
        * config/tc-mn10300.c (md_assemble): Fix "errmsg" initialization
index 46e5eb9eb37a720b7abd0e3df041a2c4bb248b60..e0b5959b7eaf2bd5ad305a713b72f6088295ad7b 100644 (file)
@@ -83,6 +83,11 @@ static int prev_mul32_p = 0;
 static int flag_explicitly_parallel = 0; 
 static int flag_xp_state = 0;
 
+/* Whether current and previous left sub-instruction disables
+   execution of right sub-instruction.  */
+static int cur_left_kills_right_p = 0;
+static int prev_left_kills_right_p = 0;
+
 /* The known current alignment of the current section.  */
 static int d30v_current_align;
 static segT d30v_current_align_seg;
@@ -223,6 +228,16 @@ check_range (num, bits, flags)
   if (bits == 32)
     return 0;
 
+  if (flags & OPERAND_SHIFT)
+    {
+      /* We know that all shifts are right by three bits.... */
+      
+      if (flags & OPERAND_SIGNED)
+       num = (unsigned long) (((/*signed*/ long) num) >> 3);
+      else
+       num >>= 3;
+    }
+
   if (flags & OPERAND_SIGNED)
     {
       max = (1 << (bits - 1))-1; 
@@ -770,6 +785,10 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
     case EXEC_SEQ:     /* sequential */
       if (opcode1->op->unit == IU)
        as_fatal (_("IU instruction may not be in the left container"));
+      if (prev_left_kills_right_p)
+       as_warn (_("special left instruction `%s' kills instruction "
+                  "`%s' in right container"),
+                opcode1->op->name, opcode2->op->name);
       insn = FM01 | (insn1 << 32) | insn2;  
       fx = fx->next;
       break;
@@ -1404,6 +1423,45 @@ do_assemble (str, opcode, shortp, is_parallel)
        }
     }
 
+  /* Propagate left_kills_right status */
+  if (insn != -1)
+    {
+      prev_left_kills_right_p = cur_left_kills_right_p;
+
+      if (opcode->op->flags_set & FLAG_LKR)
+       {
+         cur_left_kills_right_p = 1;
+         
+         if (strcmp (opcode->op->name, "mvtsys") == 0)
+           {
+             /* Left kills right for only mvtsys only for PSW/PSWH/PSWL/flags target. */
+             if ((myops[0].X_op == O_register) &&
+                 ((myops[0].X_add_number == OPERAND_CONTROL) || /* psw */
+                  (myops[0].X_add_number == OPERAND_CONTROL+MAX_CONTROL_REG+2) || /* pswh */
+                  (myops[0].X_add_number == OPERAND_CONTROL+MAX_CONTROL_REG+1) || /* pswl */
+                  (myops[0].X_add_number == OPERAND_FLAG+0) || /* f0 */
+                  (myops[0].X_add_number == OPERAND_FLAG+1) || /* f1 */
+                  (myops[0].X_add_number == OPERAND_FLAG+2) || /* f2 */
+                  (myops[0].X_add_number == OPERAND_FLAG+3) || /* f3 */
+                  (myops[0].X_add_number == OPERAND_FLAG+4) || /* f4 */
+                  (myops[0].X_add_number == OPERAND_FLAG+5) || /* f5 */
+                  (myops[0].X_add_number == OPERAND_FLAG+6) || /* f6 */
+                  (myops[0].X_add_number == OPERAND_FLAG+7))) /* f7 */
+               {
+                 cur_left_kills_right_p = 1;
+               }
+             else
+               {
+                 /* Other mvtsys target registers don't kill right instruction. */
+                 cur_left_kills_right_p = 0;
+               }
+           } /* mvtsys */
+       }
+      else
+       cur_left_kills_right_p = 0;
+    }
+
+
   return (insn);
 }
 
@@ -1859,8 +1917,11 @@ d30v_align (n, pfill, label)
      temporarily when -g is in effect.  */
   int switched_seg_p = (d30v_current_align_seg != now_seg);
 
-  if (d30v_current_align >= n && !switched_seg_p)
-    return;
+  /* Do not assume that if 'd30v_current_align >= n' and
+     '! switched_seg_p' that it is safe to avoid performing
+     this alignement request.  The alignment of the current frag
+     can be changed under our feet, for example by a .ascii
+     directive in the source code.  cf testsuite/gas/d30v/reloc.s  */
 
   d30v_cleanup ();