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;
}
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
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]));
}
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)
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;
int labelno;
{
long value_long[2];
- union real_extract u;
+ REAL_VALUE_TYPE r;
int size;
fprintf (file, "\t.literal .LC%u, ", (unsigned) 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:
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;