OSDN Git Service

* config/xtensa/xtensa.c (print_operand): Fix incorrect mode
[pf3gnuchains/gcc-fork.git] / gcc / config / xtensa / xtensa.c
index 979b3e2..e99d537 100644 (file)
@@ -440,12 +440,32 @@ mem_operand (op, mode)
 
 
 int
-non_acc_reg_operand (op, mode)
-     rtx op;
+xtensa_valid_move (mode, operands)
      enum machine_mode mode;
+     rtx *operands;
 {
-  if (register_operand (op, mode))
-    return !ACC_REG_P (xt_true_regnum (op));
+  /* Either the destination or source must be a register, and the
+     MAC16 accumulator doesn't count.  */
+
+  if (register_operand (operands[0], mode))
+    {
+      int dst_regnum = xt_true_regnum (operands[0]);
+
+      /* The stack pointer can only be assigned with a MOVSP opcode. */
+      if (dst_regnum == STACK_POINTER_REGNUM)
+       return (mode == SImode
+               && register_operand (operands[1], mode)
+               && !ACC_REG_P (xt_true_regnum (operands[1])));
+
+      if (!ACC_REG_P (dst_regnum))
+       return true;
+    }
+  else if (register_operand (operands[1], mode))
+    {
+      int src_regnum = xt_true_regnum (operands[1]);
+      if (!ACC_REG_P (src_regnum))
+       return true;
+    }
   return FALSE;
 }
 
@@ -1239,8 +1259,7 @@ xtensa_emit_move_sequence (operands, mode)
 
   if (!(reload_in_progress | reload_completed))
     {
-      if (!non_acc_reg_operand (operands[0], mode)
-         && !non_acc_reg_operand (operands[1], mode))
+      if (!xtensa_valid_move (mode, operands))
        operands[1] = force_reg (mode, operands[1]);
 
       /* Check if this move is copying an incoming argument in a7.  If
@@ -1353,8 +1372,8 @@ xtensa_expand_block_move (operands)
     return 0;
 
    /* make sure the memory addresses are valid */
-  operands[0] = change_address (dest, VOIDmode, NULL);
-  operands[1] = change_address (src, VOIDmode, NULL);
+  operands[0] = validize_mem (dest);
+  operands[1] = validize_mem (src);
 
   emit_insn (gen_movstrsi_internal (operands[0], operands[1],
                                    operands[2], operands[3]));
@@ -1907,10 +1926,8 @@ print_operand (file, op, letter)
       }
 
     case MEM:
-        /*
-        * For a volatile memory reference, emit a MEMW before the
-        * load or store.
-        */
+      /* For a volatile memory reference, emit a MEMW before the
+        load or store.  */
        if (letter == 'v')
          {
            if (MEM_VOLATILE_P (op) && TARGET_SERIALIZE_VOLATILE)
@@ -1918,7 +1935,16 @@ print_operand (file, op, letter)
            break;
          }
        else if (letter == 'N')
-         op = adjust_address (op, GET_MODE (op), 4);
+         {
+           enum machine_mode mode;
+           switch (GET_MODE (op))
+             {
+             case DFmode: mode = SFmode; break;
+             case DImode: mode = SImode; break;
+             default: abort ();
+             }
+           op = adjust_address (op, mode, 4);
+         }
 
        output_address (XEXP (op, 0));
        break;
@@ -2059,7 +2085,7 @@ xtensa_output_literal (file, x, mode, labelno)
      int labelno;
 {
   long value_long[2];
-  union real_extract u;
+  REAL_VALUE_TYPE r;
   int size;
 
   fprintf (file, "\t.literal .LC%u, ", (unsigned) labelno);
@@ -2070,18 +2096,18 @@ xtensa_output_literal (file, x, mode, labelno)
       if (GET_CODE (x) != CONST_DOUBLE)
        abort ();
 
-      memcpy ((char *) &u, (char *) &CONST_DOUBLE_LOW (x), sizeof u);
+      REAL_VALUE_FROM_CONST_DOUBLE (r, x);
       switch (mode)
        {
        case SFmode:
-         REAL_VALUE_TO_TARGET_SINGLE (u.d, value_long[0]);
-         fprintf (file, "0x%08lx\t\t# %.12g (float)\n", value_long[0], u.d);
+         REAL_VALUE_TO_TARGET_SINGLE (r, value_long[0]);
+         fprintf (file, "0x%08lx\n", value_long[0]);
          break;
 
        case DFmode:
-         REAL_VALUE_TO_TARGET_DOUBLE (u.d, value_long);
-         fprintf (file, "0x%08lx, 0x%08lx # %.20g (double)\n",
-                  value_long[0], value_long[1], u.d);
+         REAL_VALUE_TO_TARGET_DOUBLE (r, value_long);
+         fprintf (file, "0x%08lx, 0x%08lx\n",
+                  value_long[0], value_long[1]);
          break;
 
        default:
@@ -2539,6 +2565,22 @@ xtensa_va_arg (valist, type)
 
 
 enum reg_class
+xtensa_preferred_reload_class (x, class)
+     rtx x;
+     enum reg_class class;
+{
+  if (CONSTANT_P (x) && GET_CODE (x) == CONST_DOUBLE)
+    return NO_REGS;
+
+  /* Don't use sp for reloads! */
+  if (class == AR_REGS)
+    return GR_REGS;
+
+  return class;
+}
+
+
+enum reg_class
 xtensa_secondary_reload_class (class, mode, x, isoutput)
      enum reg_class class;
      enum machine_mode mode ATTRIBUTE_UNUSED;