mn10300.h (PREDICATE_CODES): Define.
* config/mn10300/mn10300.h (PREDICATE_CODES): Define. 2001-05-01 Alexandre Oliva <aoliva@redhat.com> * config/mn10300/mn10300.md (sqrtsf2): flag_fast_math was renamed to flag_unsafe_math_optimizations. 2001-04-14 Alexandre Oliva <aoliva@redhat.com> * config/mn10300/mn10300.c (expand_prologue): Mark FP-register-saving insns as frame-related. 2001-02-13 Alexandre Oliva <aoliva@redhat.com> * config/mn10300/mn10300.c (mn10300_get_live_callee_saved_regs): Don't search past LAST_EXTENDED_REGNUM. (mn10300_gen_multiple_store, store_multiple_operation): Likewise. * config/mn10300/mn10300.md: Remove excessive line breaks from `@' output patterns that were accounted as additional alternatives. * config/mn10300/mn10300.md, config/mn10300/mn10300.c: Re-introduce changes accidentally removed in Richard Sandiford's 2000-12-05's patch. * config/mn10300/t-mn10300 (MULTILIB_OPTIONS, MULTILIB_DIRNAMES): Re-instate am33-2 lost in merge from net GCC. 2000-08-26 Alexandre Oliva <aoliva@redhat.com> * config/mn10300/mn10300.h (DBX_REGISTER_NUMBER): Added floating-point registers. 2000-08-07 Alexandre Oliva <aoliva@redhat.com> * config/mn10300/mn10300.md (movdf): Revert some am33-specific pessimizations that had gone in on 2000-05-08. 2000-06-28 Graham Stott <grahams@cygnus.co.uk> * config/mn10300/mn10300.h (REG_CLASS_CONTENTS): Fix typo. 2000-06-22 Graham Stott <grahams@cygnus.co.uk> * config/mn10300/mn10300.md (movqi): Use nonimmediate_operand for operand 0. * (movhi): Likewise. * (movsi): Likewise. * (movsf): Likewise. * (movdi): Likewise. * (movdf): Likewise. Wed May 24 13:16:09 2000 Alexandre Oliva <aoliva@cygnus.com> * config/mn10300/mn10300.c (fp_regs_to_save): New function. (can_use_return_insn, initial_offset): Add fp_regs_to_save. (expand_prologue, expand_epilogue): Save and restore FP regs. 2000-05-20 Alexandre Oliva <aoliva@cygnus.com> * config/mn10300/mn10300.md (movdi, movdf): 64-bit clean-up. 2000-05-13 Alexandre Oliva <aoliva@cygnus.com> * config/mn10300/mn10300.md (abssf2, negsf2, rsqrtsf2, addsf3, subsf3, mulsf3, divsf3, fmaddsf4, fmsubsf4, fnmaddsf4, fnmsubsf4): Do not clobber cc0. 2000-05-12 Alexandre Oliva <aoliva@cygnus.com> * config/mn10300/mn10300.md (abssf2, negsf2, rsqrtsf2): Discourage the two-argument, longer opcodes. (addsf3, subsf3, mulsf3, divsf3): Likewise for three-argument ones. * config/mn10300/mn10300.h (struct mn10300_cc_status_mdep): New. (CC_STATUS_MDEP, CC_STATUS_MDEP_INIT): Define. * config/mn10300/mn10300.md (cmpsf): New pattern. (branch): Test mdep.fpCC and output fbCC. * config/mn10300/mn10300.c (print_operand): Output conditions. (notice_cc_update): Recognize fcmp and set mdep.fpCC. 2000-05-10 Alexandre Oliva <aoliva@cygnus.com> * config/mn10300/mn10300.md (movsf, movdf, addsf3, subsf3, mulsf3, divsf3): Use the `F' constraint for FP values. * config/mn10300/mn10300.c (const_1f_operand): New function. * config/mn10300/mn10300-protos.h (const_1f_operand): Declare. * config/mn10300/mn10300.md (sqrtsf2): New expand. (rsqrtsf2): New insn. 2000-05-09 Alexandre Oliva <aoliva@cygnus.com> * config/mn10300/mn10300.md (movdf): Oops, I missed it in my previous check-in. 2000-05-08 Alexandre Oliva <aoliva@cygnus.com> * config/mn10300/mn10300.md (abssf2, negdf2): On TARGET_AM33_2, expand to... (abssf2_am33_2, negdf2_am33_2): New insns. (addsf3, subsf3, mulsf3, divsf3): Likewise. (fmaddsf4, fmsubsf4, fnmaddsf4, fnmsubsf4): Likewise. * config/mn10300/mn10300.md (movqi, movhi, movsi, movsf, movdi, movdf): Added FP regs. * invoke.texi (-mam33-2, -mno-am33-2): Document. 2000-04-29 Alexandre Oliva <aoliva@cygnus.com> * config/mn10300/mn10300.h (FIRST_FP_REGNUM, LAST_FP_REGNUM): New macros. (REGNO_AM33_2_FP_P): Renamed to... (REGNO_FP_P): Redefine in terms of FIRST_* and LAST_*. (CONDITIONAL_REGISTER_USAGE, REGNO_REG_CLASS): Likewise. 2000-04-27 Alexandre Oliva <aoliva@cygnus.com> * config/mn10300/mn10300.h (REG_CLASS_CONTENTS): Remove FP regs from GENERAL_REGS. 2000-04-27 Alexandre Oliva <aoliva@cygnus.com> * config/mn10300/mn10300.h (REGNO_AM33_2_FP_P): New macro. * config/mn10300/mn10300.c (mn10300_address_cost): Added FP_REGS. * config/mn10300/mn10300.h (REGISTER_MOVE_COST): Added FP_REGS. 2000-04-23 Alexandre Oliva <aoliva@cygnus.com> * config/mn10300/mn10300.h (CLASS_CANNOT_CHANGE_SIZE): Defined as FP_REGS. 2000-04-21 Alexandre Oliva <aoliva@cygnus.com> * config/mn10300/mn10300.h (OK_FOR_Q): New macro. (EXTRA_CONSTRAINT): Added OK_FOR_Q. * config/mn10300/mn10300.c (secondary_reload_class): Adjust. * config/mn10300/mn10300.c (print_operand): Support `D' for doubles. * config/mn10300/mn10300.h (FIRST_PSEUDO_REGISTER): Adjust. (FIXED_REGISTERS, CALL_USED_REGISTERS, REG_ALLOC_ORDER): Added AM33/2.0 floating-point registers. (CONDITIONAL_REGISTER_USAGE): Adjust. (enum reg_class, REG_CLASS_NAMES): Added FP_REGS and FP_ACC_REGS. (REG_CLASS_CONTENTS, REGNO_REG_CLASS): Adjust. (REG_CLASS_FROM_LETTER): Added `f' and `A'. (REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES): Adjust. * config/mn10300/t-mn10300 (MULTILIB_OPTIONS): Added am33-2. (MULTILIB_DIRNAMES): Likewise. * config/mn10300/mn10300.h (CPP_SPEC): Define `__AM33__=2' and `__AM33_2__' when `-mam33-2' is given. (TARGET_AM33_2): Define. (TARGET_SWITCHES): Adjust. * config/mn10300/mn10300.c (asm_file_start): Print `.am33_2' when appropriate. From-SVN: r69167
This commit is contained in:
parent
2ff167186b
commit
18e9d2f9e3
116
gcc/ChangeLog
116
gcc/ChangeLog
@ -1,3 +1,119 @@
|
||||
2003-07-09 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* config/mn10300/mn10300.h (PREDICATE_CODES): Define.
|
||||
2001-05-01 Alexandre Oliva <aoliva@redhat.com>
|
||||
* config/mn10300/mn10300.md (sqrtsf2): flag_fast_math was renamed
|
||||
to flag_unsafe_math_optimizations.
|
||||
2001-04-14 Alexandre Oliva <aoliva@redhat.com>
|
||||
* config/mn10300/mn10300.c (expand_prologue): Mark
|
||||
FP-register-saving insns as frame-related.
|
||||
2001-02-13 Alexandre Oliva <aoliva@redhat.com>
|
||||
* config/mn10300/mn10300.c
|
||||
(mn10300_get_live_callee_saved_regs): Don't search past
|
||||
LAST_EXTENDED_REGNUM.
|
||||
(mn10300_gen_multiple_store, store_multiple_operation): Likewise.
|
||||
* config/mn10300/mn10300.md: Remove excessive line breaks from
|
||||
`@' output patterns that were accounted as additional
|
||||
alternatives.
|
||||
* config/mn10300/mn10300.md, config/mn10300/mn10300.c:
|
||||
Re-introduce changes accidentally removed in Richard Sandiford's
|
||||
2000-12-05's patch.
|
||||
* config/mn10300/t-mn10300 (MULTILIB_OPTIONS, MULTILIB_DIRNAMES):
|
||||
Re-instate am33-2 lost in merge from net GCC.
|
||||
2000-08-26 Alexandre Oliva <aoliva@redhat.com>
|
||||
* config/mn10300/mn10300.h (DBX_REGISTER_NUMBER): Added
|
||||
floating-point registers.
|
||||
2000-08-07 Alexandre Oliva <aoliva@redhat.com>
|
||||
* config/mn10300/mn10300.md (movdf): Revert some am33-specific
|
||||
pessimizations that had gone in on 2000-05-08.
|
||||
2000-06-28 Graham Stott <grahams@cygnus.co.uk>
|
||||
* config/mn10300/mn10300.h (REG_CLASS_CONTENTS): Fix typo.
|
||||
2000-06-22 Graham Stott <grahams@cygnus.co.uk>
|
||||
* config/mn10300/mn10300.md (movqi): Use nonimmediate_operand for
|
||||
operand 0.
|
||||
* (movhi): Likewise.
|
||||
* (movsi): Likewise.
|
||||
* (movsf): Likewise.
|
||||
* (movdi): Likewise.
|
||||
* (movdf): Likewise.
|
||||
Wed May 24 13:16:09 2000 Alexandre Oliva <aoliva@cygnus.com>
|
||||
* config/mn10300/mn10300.c (fp_regs_to_save): New function.
|
||||
(can_use_return_insn, initial_offset): Add fp_regs_to_save.
|
||||
(expand_prologue, expand_epilogue): Save and restore FP regs.
|
||||
2000-05-20 Alexandre Oliva <aoliva@cygnus.com>
|
||||
* config/mn10300/mn10300.md (movdi, movdf): 64-bit clean-up.
|
||||
2000-05-13 Alexandre Oliva <aoliva@cygnus.com>
|
||||
* config/mn10300/mn10300.md (abssf2, negsf2, rsqrtsf2, addsf3,
|
||||
subsf3, mulsf3, divsf3, fmaddsf4, fmsubsf4, fnmaddsf4, fnmsubsf4):
|
||||
Do not clobber cc0.
|
||||
2000-05-12 Alexandre Oliva <aoliva@cygnus.com>
|
||||
* config/mn10300/mn10300.md (abssf2, negsf2, rsqrtsf2):
|
||||
Discourage the two-argument, longer opcodes.
|
||||
(addsf3, subsf3, mulsf3, divsf3): Likewise for three-argument
|
||||
ones.
|
||||
* config/mn10300/mn10300.h (struct mn10300_cc_status_mdep): New.
|
||||
(CC_STATUS_MDEP, CC_STATUS_MDEP_INIT): Define.
|
||||
* config/mn10300/mn10300.md (cmpsf): New pattern.
|
||||
(branch): Test mdep.fpCC and output fbCC.
|
||||
* config/mn10300/mn10300.c (print_operand): Output conditions.
|
||||
(notice_cc_update): Recognize fcmp and set mdep.fpCC.
|
||||
2000-05-10 Alexandre Oliva <aoliva@cygnus.com>
|
||||
* config/mn10300/mn10300.md (movsf, movdf, addsf3, subsf3,
|
||||
mulsf3, divsf3): Use the `F' constraint for FP values.
|
||||
* config/mn10300/mn10300.c (const_1f_operand): New function.
|
||||
* config/mn10300/mn10300-protos.h (const_1f_operand): Declare.
|
||||
* config/mn10300/mn10300.md (sqrtsf2): New expand.
|
||||
(rsqrtsf2): New insn.
|
||||
2000-05-09 Alexandre Oliva <aoliva@cygnus.com>
|
||||
* config/mn10300/mn10300.md (movdf): Oops, I missed it in my
|
||||
previous check-in.
|
||||
2000-05-08 Alexandre Oliva <aoliva@cygnus.com>
|
||||
* config/mn10300/mn10300.md (abssf2, negdf2): On
|
||||
TARGET_AM33_2, expand to...
|
||||
(abssf2_am33_2, negdf2_am33_2): New insns.
|
||||
(addsf3, subsf3, mulsf3, divsf3): Likewise.
|
||||
(fmaddsf4, fmsubsf4, fnmaddsf4, fnmsubsf4): Likewise.
|
||||
* config/mn10300/mn10300.md (movqi, movhi, movsi, movsf,
|
||||
movdi, movdf): Added FP regs.
|
||||
* invoke.texi (-mam33-2, -mno-am33-2): Document.
|
||||
2000-04-29 Alexandre Oliva <aoliva@cygnus.com>
|
||||
* config/mn10300/mn10300.h (FIRST_FP_REGNUM, LAST_FP_REGNUM):
|
||||
New macros.
|
||||
(REGNO_AM33_2_FP_P): Renamed to...
|
||||
(REGNO_FP_P): Redefine in terms of FIRST_* and LAST_*.
|
||||
(CONDITIONAL_REGISTER_USAGE, REGNO_REG_CLASS): Likewise.
|
||||
2000-04-27 Alexandre Oliva <aoliva@cygnus.com>
|
||||
* config/mn10300/mn10300.h (REG_CLASS_CONTENTS): Remove FP
|
||||
regs from GENERAL_REGS.
|
||||
2000-04-27 Alexandre Oliva <aoliva@cygnus.com>
|
||||
* config/mn10300/mn10300.h (REGNO_AM33_2_FP_P): New macro.
|
||||
* config/mn10300/mn10300.c (mn10300_address_cost): Added FP_REGS.
|
||||
* config/mn10300/mn10300.h (REGISTER_MOVE_COST): Added FP_REGS.
|
||||
2000-04-23 Alexandre Oliva <aoliva@cygnus.com>
|
||||
* config/mn10300/mn10300.h (CLASS_CANNOT_CHANGE_SIZE): Defined
|
||||
as FP_REGS.
|
||||
2000-04-21 Alexandre Oliva <aoliva@cygnus.com>
|
||||
* config/mn10300/mn10300.h (OK_FOR_Q): New macro.
|
||||
(EXTRA_CONSTRAINT): Added OK_FOR_Q.
|
||||
* config/mn10300/mn10300.c (secondary_reload_class): Adjust.
|
||||
* config/mn10300/mn10300.c (print_operand): Support `D' for doubles.
|
||||
* config/mn10300/mn10300.h (FIRST_PSEUDO_REGISTER): Adjust.
|
||||
(FIXED_REGISTERS, CALL_USED_REGISTERS, REG_ALLOC_ORDER): Added
|
||||
AM33/2.0 floating-point registers.
|
||||
(CONDITIONAL_REGISTER_USAGE): Adjust.
|
||||
(enum reg_class, REG_CLASS_NAMES): Added FP_REGS and FP_ACC_REGS.
|
||||
(REG_CLASS_CONTENTS, REGNO_REG_CLASS): Adjust.
|
||||
(REG_CLASS_FROM_LETTER): Added `f' and `A'.
|
||||
(REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES): Adjust.
|
||||
* config/mn10300/t-mn10300 (MULTILIB_OPTIONS): Added am33-2.
|
||||
(MULTILIB_DIRNAMES): Likewise.
|
||||
* config/mn10300/mn10300.h (CPP_SPEC): Define `__AM33__=2' and
|
||||
`__AM33_2__' when `-mam33-2' is given.
|
||||
(TARGET_AM33_2): Define.
|
||||
(TARGET_SWITCHES): Adjust.
|
||||
* config/mn10300/mn10300.c (asm_file_start): Print `.am33_2'
|
||||
when appropriate.
|
||||
|
||||
2003-07-09 Matt Kraai <kraai@alumni.cmu.edu>
|
||||
|
||||
* doc/install.texi: Add missing @.
|
||||
|
@ -82,7 +82,9 @@ mn10300_file_start ()
|
||||
{
|
||||
default_file_start ();
|
||||
|
||||
if (TARGET_AM33)
|
||||
if (TARGET_AM33_2)
|
||||
fprintf (asm_out_file, "\t.am33_2\n");
|
||||
else if (TARGET_AM33)
|
||||
fprintf (asm_out_file, "\t.am33\n");
|
||||
}
|
||||
|
||||
@ -100,6 +102,58 @@ print_operand (file, x, code)
|
||||
{
|
||||
case 'b':
|
||||
case 'B':
|
||||
if (cc_status.mdep.fpCC)
|
||||
{
|
||||
switch (code == 'b' ? GET_CODE (x)
|
||||
: reverse_condition_maybe_unordered (GET_CODE (x)))
|
||||
{
|
||||
case NE:
|
||||
fprintf (file, "ne");
|
||||
break;
|
||||
case EQ:
|
||||
fprintf (file, "eq");
|
||||
break;
|
||||
case GE:
|
||||
fprintf (file, "ge");
|
||||
break;
|
||||
case GT:
|
||||
fprintf (file, "gt");
|
||||
break;
|
||||
case LE:
|
||||
fprintf (file, "le");
|
||||
break;
|
||||
case LT:
|
||||
fprintf (file, "lt");
|
||||
break;
|
||||
case ORDERED:
|
||||
fprintf (file, "lge");
|
||||
break;
|
||||
case UNORDERED:
|
||||
fprintf (file, "uo");
|
||||
break;
|
||||
case LTGT:
|
||||
fprintf (file, "lg");
|
||||
break;
|
||||
case UNEQ:
|
||||
fprintf (file, "ue");
|
||||
break;
|
||||
case UNGE:
|
||||
fprintf (file, "uge");
|
||||
break;
|
||||
case UNGT:
|
||||
fprintf (file, "ug");
|
||||
break;
|
||||
case UNLE:
|
||||
fprintf (file, "ule");
|
||||
break;
|
||||
case UNLT:
|
||||
fprintf (file, "ul");
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* These are normal and reversed branches. */
|
||||
switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x)))
|
||||
{
|
||||
@ -151,6 +205,24 @@ print_operand (file, x, code)
|
||||
print_operand (file, x, 0);
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
switch (GET_CODE (x))
|
||||
{
|
||||
case MEM:
|
||||
fputc ('(', file);
|
||||
output_address (XEXP (x, 0));
|
||||
fputc (')', file);
|
||||
break;
|
||||
|
||||
case REG:
|
||||
fprintf (file, "fd%d", REGNO (x) - 18);
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
break;
|
||||
|
||||
/* These are the least significant word in a 64bit value. */
|
||||
case 'L':
|
||||
switch (GET_CODE (x))
|
||||
@ -388,6 +460,22 @@ print_operand_address (file, addr)
|
||||
}
|
||||
}
|
||||
|
||||
/* Count the number of FP registers that have to be saved. */
|
||||
static int
|
||||
fp_regs_to_save ()
|
||||
{
|
||||
int i, n = 0;
|
||||
|
||||
if (! TARGET_AM33_2)
|
||||
return 0;
|
||||
|
||||
for (i = FIRST_FP_REGNUM; i <= LAST_FP_REGNUM; ++i)
|
||||
if (regs_ever_live[i] && ! call_used_regs[i])
|
||||
++n;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Print a set of registers in the format required by "movm" and "ret".
|
||||
Register K is saved if bit K of MASK is set. The data and address
|
||||
registers can be stored individually, but the extended registers cannot.
|
||||
@ -446,6 +534,7 @@ can_use_return_insn ()
|
||||
&& !regs_ever_live[15]
|
||||
&& !regs_ever_live[16]
|
||||
&& !regs_ever_live[17]
|
||||
&& fp_regs_to_save () == 0
|
||||
&& !frame_pointer_needed);
|
||||
}
|
||||
|
||||
@ -460,7 +549,7 @@ mn10300_get_live_callee_saved_regs ()
|
||||
int i;
|
||||
|
||||
mask = 0;
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
for (i = 0; i <= LAST_EXTENDED_REGNUM; i++)
|
||||
if (regs_ever_live[i] && ! call_used_regs[i])
|
||||
mask |= (1 << i);
|
||||
if ((mask & 0x3c000) != 0)
|
||||
@ -501,7 +590,7 @@ mn10300_gen_multiple_store (mask)
|
||||
|
||||
/* Count how many registers need to be saved. */
|
||||
count = 0;
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
for (i = 0; i <= LAST_EXTENDED_REGNUM; i++)
|
||||
if ((mask & (1 << i)) != 0)
|
||||
count += 1;
|
||||
|
||||
@ -519,7 +608,7 @@ mn10300_gen_multiple_store (mask)
|
||||
|
||||
/* Create each store. */
|
||||
pari = 1;
|
||||
for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
|
||||
for (i = LAST_EXTENDED_REGNUM; i >= 0; i--)
|
||||
if ((mask & (1 << i)) != 0)
|
||||
{
|
||||
rtx address = gen_rtx_PLUS (SImode,
|
||||
@ -549,6 +638,240 @@ expand_prologue ()
|
||||
/* If we use any of the callee-saved registers, save them now. */
|
||||
mn10300_gen_multiple_store (mn10300_get_live_callee_saved_regs ());
|
||||
|
||||
if (TARGET_AM33_2 && fp_regs_to_save ())
|
||||
{
|
||||
int num_regs_to_save = fp_regs_to_save (), i;
|
||||
HOST_WIDE_INT xsize;
|
||||
enum { save_sp_merge,
|
||||
save_sp_no_merge,
|
||||
save_sp_partial_merge,
|
||||
save_a0_merge,
|
||||
save_a0_no_merge } strategy;
|
||||
unsigned int strategy_size = (unsigned)-1, this_strategy_size;
|
||||
rtx reg;
|
||||
rtx insn;
|
||||
|
||||
/* We have several different strategies to save FP registers.
|
||||
We can store them using SP offsets, which is beneficial if
|
||||
there are just a few registers to save, or we can use `a0' in
|
||||
post-increment mode (`a0' is the only call-clobbered address
|
||||
register that is never used to pass information to a
|
||||
function). Furthermore, if we don't need a frame pointer, we
|
||||
can merge the two SP adds into a single one, but this isn't
|
||||
always beneficial; sometimes we can just split the two adds
|
||||
so that we don't exceed a 16-bit constant size. The code
|
||||
below will select which strategy to use, so as to generate
|
||||
smallest code. Ties are broken in favor or shorter sequences
|
||||
(in terms of number of instructions). */
|
||||
|
||||
#define SIZE_ADD_AX(S) ((((S) >= (1 << 15)) || ((S) < -(1 << 15))) ? 6 \
|
||||
: (((S) >= (1 << 7)) || ((S) < -(1 << 7))) ? 4 : 2)
|
||||
#define SIZE_ADD_SP(S) ((((S) >= (1 << 15)) || ((S) < -(1 << 15))) ? 6 \
|
||||
: (((S) >= (1 << 7)) || ((S) < -(1 << 7))) ? 4 : 3)
|
||||
#define SIZE_FMOV_LIMIT(S,N,L,SIZE1,SIZE2,ELSE) \
|
||||
(((S) >= (L)) ? (SIZE1) * (N) \
|
||||
: ((S) + 4 * (N) >= (L)) ? (((L) - (S)) / 4 * (SIZE2) \
|
||||
+ ((S) + 4 * (N) - (L)) / 4 * (SIZE1)) \
|
||||
: (ELSE))
|
||||
#define SIZE_FMOV_SP_(S,N) \
|
||||
(SIZE_FMOV_LIMIT ((S), (N), (1 << 24), 7, 6, \
|
||||
SIZE_FMOV_LIMIT ((S), (N), (1 << 8), 6, 4, \
|
||||
(S) ? 4 * (N) : 3 + 4 * ((N) - 1))))
|
||||
#define SIZE_FMOV_SP(S,N) (SIZE_FMOV_SP_ ((unsigned HOST_WIDE_INT)(S), (N)))
|
||||
|
||||
/* Consider alternative save_sp_merge only if we don't need the
|
||||
frame pointer and size is non-zero. */
|
||||
if (! frame_pointer_needed && size)
|
||||
{
|
||||
/* Insn: add -(size + 4 * num_regs_to_save), sp. */
|
||||
this_strategy_size = SIZE_ADD_SP (-(size + 4 * num_regs_to_save));
|
||||
/* Insn: fmov fs#, (##, sp), for each fs# to be saved. */
|
||||
this_strategy_size += SIZE_FMOV_SP (size, num_regs_to_save);
|
||||
|
||||
if (this_strategy_size < strategy_size)
|
||||
{
|
||||
strategy = save_sp_merge;
|
||||
strategy_size = this_strategy_size;
|
||||
}
|
||||
}
|
||||
|
||||
/* Consider alternative save_sp_no_merge unconditionally. */
|
||||
/* Insn: add -4 * num_regs_to_save, sp. */
|
||||
this_strategy_size = SIZE_ADD_SP (-4 * num_regs_to_save);
|
||||
/* Insn: fmov fs#, (##, sp), for each fs# to be saved. */
|
||||
this_strategy_size += SIZE_FMOV_SP (0, num_regs_to_save);
|
||||
if (size)
|
||||
{
|
||||
/* Insn: add -size, sp. */
|
||||
this_strategy_size += SIZE_ADD_SP (-size);
|
||||
}
|
||||
|
||||
if (this_strategy_size < strategy_size)
|
||||
{
|
||||
strategy = save_sp_no_merge;
|
||||
strategy_size = this_strategy_size;
|
||||
}
|
||||
|
||||
/* Consider alternative save_sp_partial_merge only if we don't
|
||||
need a frame pointer and size is reasonably large. */
|
||||
if (! frame_pointer_needed && size + 4 * num_regs_to_save > 128)
|
||||
{
|
||||
/* Insn: add -128, sp. */
|
||||
this_strategy_size = SIZE_ADD_SP (-128);
|
||||
/* Insn: fmov fs#, (##, sp), for each fs# to be saved. */
|
||||
this_strategy_size += SIZE_FMOV_SP (128 - 4 * num_regs_to_save,
|
||||
num_regs_to_save);
|
||||
if (size)
|
||||
{
|
||||
/* Insn: add 128-size, sp. */
|
||||
this_strategy_size += SIZE_ADD_SP (128 - size);
|
||||
}
|
||||
|
||||
if (this_strategy_size < strategy_size)
|
||||
{
|
||||
strategy = save_sp_partial_merge;
|
||||
strategy_size = this_strategy_size;
|
||||
}
|
||||
}
|
||||
|
||||
/* Consider alternative save_a0_merge only if we don't need a
|
||||
frame pointer, size is non-zero and the user hasn't
|
||||
changed the calling conventions of a0. */
|
||||
if (! frame_pointer_needed && size
|
||||
&& call_used_regs[FIRST_ADDRESS_REGNUM]
|
||||
&& ! fixed_regs[FIRST_ADDRESS_REGNUM])
|
||||
{
|
||||
/* Insn: add -(size + 4 * num_regs_to_save), sp. */
|
||||
this_strategy_size = SIZE_ADD_SP (-(size + 4 * num_regs_to_save));
|
||||
/* Insn: mov sp, a0. */
|
||||
this_strategy_size++;
|
||||
if (size)
|
||||
{
|
||||
/* Insn: add size, a0. */
|
||||
this_strategy_size += SIZE_ADD_AX (size);
|
||||
}
|
||||
/* Insn: fmov fs#, (a0+), for each fs# to be saved. */
|
||||
this_strategy_size += 3 * num_regs_to_save;
|
||||
|
||||
if (this_strategy_size < strategy_size)
|
||||
{
|
||||
strategy = save_a0_merge;
|
||||
strategy_size = this_strategy_size;
|
||||
}
|
||||
}
|
||||
|
||||
/* Consider alternative save_a0_no_merge if the user hasn't
|
||||
changed the calling conventions of a0. */
|
||||
if (call_used_regs[FIRST_ADDRESS_REGNUM]
|
||||
&& ! fixed_regs[FIRST_ADDRESS_REGNUM])
|
||||
{
|
||||
/* Insn: add -4 * num_regs_to_save, sp. */
|
||||
this_strategy_size = SIZE_ADD_SP (-4 * num_regs_to_save);
|
||||
/* Insn: mov sp, a0. */
|
||||
this_strategy_size++;
|
||||
/* Insn: fmov fs#, (a0+), for each fs# to be saved. */
|
||||
this_strategy_size += 3 * num_regs_to_save;
|
||||
if (size)
|
||||
{
|
||||
/* Insn: add -size, sp. */
|
||||
this_strategy_size += SIZE_ADD_SP (-size);
|
||||
}
|
||||
|
||||
if (this_strategy_size < strategy_size)
|
||||
{
|
||||
strategy = save_a0_no_merge;
|
||||
strategy_size = this_strategy_size;
|
||||
}
|
||||
}
|
||||
|
||||
/* Emit the initial SP add, common to all strategies. */
|
||||
switch (strategy)
|
||||
{
|
||||
case save_sp_no_merge:
|
||||
case save_a0_no_merge:
|
||||
emit_insn (gen_addsi3 (stack_pointer_rtx,
|
||||
stack_pointer_rtx,
|
||||
GEN_INT (-4 * num_regs_to_save)));
|
||||
xsize = 0;
|
||||
break;
|
||||
|
||||
case save_sp_partial_merge:
|
||||
emit_insn (gen_addsi3 (stack_pointer_rtx,
|
||||
stack_pointer_rtx,
|
||||
GEN_INT (-128)));
|
||||
xsize = 128 - 4 * num_regs_to_save;
|
||||
size -= xsize;
|
||||
break;
|
||||
|
||||
case save_sp_merge:
|
||||
case save_a0_merge:
|
||||
emit_insn (gen_addsi3 (stack_pointer_rtx,
|
||||
stack_pointer_rtx,
|
||||
GEN_INT (-(size + 4 * num_regs_to_save))));
|
||||
/* We'll have to adjust FP register saves according to the
|
||||
frame size. */
|
||||
xsize = size;
|
||||
/* Since we've already created the stack frame, don't do it
|
||||
again at the end of the function. */
|
||||
size = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Now prepare register a0, if we have decided to use it. */
|
||||
switch (strategy)
|
||||
{
|
||||
case save_sp_merge:
|
||||
case save_sp_no_merge:
|
||||
case save_sp_partial_merge:
|
||||
reg = 0;
|
||||
break;
|
||||
|
||||
case save_a0_merge:
|
||||
case save_a0_no_merge:
|
||||
reg = gen_rtx_REG (SImode, FIRST_ADDRESS_REGNUM);
|
||||
emit_insn (gen_movsi (reg, stack_pointer_rtx));
|
||||
if (xsize)
|
||||
emit_insn (gen_addsi3 (reg, reg, GEN_INT (xsize)));
|
||||
reg = gen_rtx_POST_INC (SImode, reg);
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Now actually save the FP registers. */
|
||||
for (i = FIRST_FP_REGNUM; i <= LAST_FP_REGNUM; ++i)
|
||||
if (regs_ever_live[i] && ! call_used_regs[i])
|
||||
{
|
||||
rtx addr;
|
||||
|
||||
if (reg)
|
||||
addr = reg;
|
||||
else
|
||||
{
|
||||
/* If we aren't using `a0', use an SP offset. */
|
||||
if (xsize)
|
||||
{
|
||||
addr = gen_rtx_PLUS (SImode,
|
||||
stack_pointer_rtx,
|
||||
GEN_INT (xsize));
|
||||
}
|
||||
else
|
||||
addr = stack_pointer_rtx;
|
||||
|
||||
xsize += 4;
|
||||
}
|
||||
|
||||
insn = emit_insn (gen_movsi (gen_rtx_MEM (SImode, addr),
|
||||
gen_rtx_REG (SImode, i)));
|
||||
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now put the frame pointer into the frame pointer register. */
|
||||
if (frame_pointer_needed)
|
||||
emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
|
||||
@ -569,6 +892,193 @@ expand_epilogue ()
|
||||
size = get_frame_size () + current_function_outgoing_args_size;
|
||||
size += (current_function_outgoing_args_size ? 4 : 0);
|
||||
|
||||
if (TARGET_AM33_2 && fp_regs_to_save ())
|
||||
{
|
||||
int num_regs_to_save = fp_regs_to_save (), i;
|
||||
rtx reg = 0;
|
||||
|
||||
/* We have several options to restore FP registers. We could
|
||||
load them from SP offsets, but, if there are enough FP
|
||||
registers to restore, we win if we use a post-increment
|
||||
addressing mode. */
|
||||
|
||||
/* If we have a frame pointer, it's the best option, because we
|
||||
already know it has the value we want. */
|
||||
if (frame_pointer_needed)
|
||||
reg = gen_rtx_REG (SImode, FRAME_POINTER_REGNUM);
|
||||
/* Otherwise, we may use `a1', since it's call-clobbered and
|
||||
it's never used for return values. But only do so if it's
|
||||
smaller than using SP offsets. */
|
||||
else
|
||||
{
|
||||
enum { restore_sp_post_adjust,
|
||||
restore_sp_pre_adjust,
|
||||
restore_sp_partial_adjust,
|
||||
restore_a1 } strategy;
|
||||
unsigned int this_strategy_size, strategy_size = (unsigned)-1;
|
||||
|
||||
/* Consider using sp offsets before adjusting sp. */
|
||||
/* Insn: fmov (##,sp),fs#, for each fs# to be restored. */
|
||||
this_strategy_size = SIZE_FMOV_SP (size, num_regs_to_save);
|
||||
/* If size is too large, we'll have to adjust SP with an
|
||||
add. */
|
||||
if (size + 4 * num_regs_to_save + REG_SAVE_BYTES > 255)
|
||||
{
|
||||
/* Insn: add size + 4 * num_regs_to_save, sp. */
|
||||
this_strategy_size += SIZE_ADD_SP (size + 4 * num_regs_to_save);
|
||||
}
|
||||
/* If we don't have to restore any non-FP registers,
|
||||
we'll be able to save one byte by using rets. */
|
||||
if (! REG_SAVE_BYTES)
|
||||
this_strategy_size--;
|
||||
|
||||
if (this_strategy_size < strategy_size)
|
||||
{
|
||||
strategy = restore_sp_post_adjust;
|
||||
strategy_size = this_strategy_size;
|
||||
}
|
||||
|
||||
/* Consider using sp offsets after adjusting sp. */
|
||||
/* Insn: add size, sp. */
|
||||
this_strategy_size = SIZE_ADD_SP (size);
|
||||
/* Insn: fmov (##,sp),fs#, for each fs# to be restored. */
|
||||
this_strategy_size += SIZE_FMOV_SP (0, num_regs_to_save);
|
||||
/* We're going to use ret to release the FP registers
|
||||
save area, so, no savings. */
|
||||
|
||||
if (this_strategy_size < strategy_size)
|
||||
{
|
||||
strategy = restore_sp_pre_adjust;
|
||||
strategy_size = this_strategy_size;
|
||||
}
|
||||
|
||||
/* Consider using sp offsets after partially adjusting sp.
|
||||
When size is close to 32Kb, we may be able to adjust SP
|
||||
with an imm16 add instruction while still using fmov
|
||||
(d8,sp). */
|
||||
if (size + 4 * num_regs_to_save + REG_SAVE_BYTES > 255)
|
||||
{
|
||||
/* Insn: add size + 4 * num_regs_to_save
|
||||
+ REG_SAVE_BYTES - 252,sp. */
|
||||
this_strategy_size = SIZE_ADD_SP (size + 4 * num_regs_to_save
|
||||
+ REG_SAVE_BYTES - 252);
|
||||
/* Insn: fmov (##,sp),fs#, fo each fs# to be restored. */
|
||||
this_strategy_size += SIZE_FMOV_SP (252 - REG_SAVE_BYTES
|
||||
- 4 * num_regs_to_save,
|
||||
num_regs_to_save);
|
||||
/* We're going to use ret to release the FP registers
|
||||
save area, so, no savings. */
|
||||
|
||||
if (this_strategy_size < strategy_size)
|
||||
{
|
||||
strategy = restore_sp_partial_adjust;
|
||||
strategy_size = this_strategy_size;
|
||||
}
|
||||
}
|
||||
|
||||
/* Consider using a1 in post-increment mode, as long as the
|
||||
user hasn't changed the calling conventions of a1. */
|
||||
if (call_used_regs[FIRST_ADDRESS_REGNUM+1]
|
||||
&& ! fixed_regs[FIRST_ADDRESS_REGNUM+1])
|
||||
{
|
||||
/* Insn: mov sp,a1. */
|
||||
this_strategy_size = 1;
|
||||
if (size)
|
||||
{
|
||||
/* Insn: add size,a1. */
|
||||
this_strategy_size += SIZE_ADD_AX (size);
|
||||
}
|
||||
/* Insn: fmov (a1+),fs#, for each fs# to be restored. */
|
||||
this_strategy_size += 3 * num_regs_to_save;
|
||||
/* If size is large enough, we may be able to save a
|
||||
couple of bytes. */
|
||||
if (size + 4 * num_regs_to_save + REG_SAVE_BYTES > 255)
|
||||
{
|
||||
/* Insn: mov a1,sp. */
|
||||
this_strategy_size += 2;
|
||||
}
|
||||
/* If we don't have to restore any non-FP registers,
|
||||
we'll be able to save one byte by using rets. */
|
||||
if (! REG_SAVE_BYTES)
|
||||
this_strategy_size--;
|
||||
|
||||
if (this_strategy_size < strategy_size)
|
||||
{
|
||||
strategy = restore_a1;
|
||||
strategy_size = this_strategy_size;
|
||||
}
|
||||
}
|
||||
|
||||
switch (strategy)
|
||||
{
|
||||
case restore_sp_post_adjust:
|
||||
break;
|
||||
|
||||
case restore_sp_pre_adjust:
|
||||
emit_insn (gen_addsi3 (stack_pointer_rtx,
|
||||
stack_pointer_rtx,
|
||||
GEN_INT (size)));
|
||||
size = 0;
|
||||
break;
|
||||
|
||||
case restore_sp_partial_adjust:
|
||||
emit_insn (gen_addsi3 (stack_pointer_rtx,
|
||||
stack_pointer_rtx,
|
||||
GEN_INT (size + 4 * num_regs_to_save
|
||||
+ REG_SAVE_BYTES - 252)));
|
||||
size = 252 - REG_SAVE_BYTES - 4 * num_regs_to_save;
|
||||
break;
|
||||
|
||||
case restore_a1:
|
||||
reg = gen_rtx_REG (SImode, FIRST_ADDRESS_REGNUM + 1);
|
||||
emit_insn (gen_movsi (reg, stack_pointer_rtx));
|
||||
if (size)
|
||||
emit_insn (gen_addsi3 (reg, reg, GEN_INT (size)));
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjust the selected register, if any, for post-increment. */
|
||||
if (reg)
|
||||
reg = gen_rtx_POST_INC (SImode, reg);
|
||||
|
||||
for (i = FIRST_FP_REGNUM; i <= LAST_FP_REGNUM; ++i)
|
||||
if (regs_ever_live[i] && ! call_used_regs[i])
|
||||
{
|
||||
rtx addr;
|
||||
|
||||
if (reg)
|
||||
addr = reg;
|
||||
else if (size)
|
||||
{
|
||||
/* If we aren't using a post-increment register, use an
|
||||
SP offset. */
|
||||
addr = gen_rtx_PLUS (SImode,
|
||||
stack_pointer_rtx,
|
||||
GEN_INT (size));
|
||||
}
|
||||
else
|
||||
addr = stack_pointer_rtx;
|
||||
|
||||
size += 4;
|
||||
|
||||
emit_insn (gen_movsi (gen_rtx_REG (SImode, i),
|
||||
gen_rtx_MEM (SImode, addr)));
|
||||
}
|
||||
|
||||
/* If we were using the restore_a1 strategy and the number of
|
||||
bytes to be released won't fit in the `ret' byte, copy `a1'
|
||||
to `sp', to avoid having to use `add' to adjust it. */
|
||||
if (! frame_pointer_needed && reg && size + REG_SAVE_BYTES > 255)
|
||||
{
|
||||
emit_move_insn (stack_pointer_rtx, XEXP (reg, 0));
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Maybe cut back the stack, except for the register save area.
|
||||
|
||||
If the frame pointer exists, then use the frame pointer to
|
||||
@ -649,6 +1159,9 @@ notice_update_cc (body, insn)
|
||||
/* The insn is a compare instruction. */
|
||||
CC_STATUS_INIT;
|
||||
cc_status.value1 = SET_SRC (body);
|
||||
if (GET_CODE (cc_status.value1) == COMPARE
|
||||
&& GET_MODE (XEXP (cc_status.value1, 0)) == SFmode)
|
||||
cc_status.mdep.fpCC = 1;
|
||||
break;
|
||||
|
||||
case CC_INVERT:
|
||||
@ -714,7 +1227,7 @@ store_multiple_operation (op, mode)
|
||||
|
||||
LAST keeps track of the smallest-numbered register stored so far.
|
||||
MASK is the set of stored registers. */
|
||||
last = FIRST_PSEUDO_REGISTER;
|
||||
last = LAST_EXTENDED_REGNUM + 1;
|
||||
mask = 0;
|
||||
for (i = 1; i < count; i++)
|
||||
{
|
||||
@ -810,6 +1323,14 @@ secondary_reload_class (class, mode, in)
|
||||
return DATA_REGS;
|
||||
}
|
||||
|
||||
if (TARGET_AM33_2 && class == FP_REGS
|
||||
&& GET_CODE (in) == MEM && ! OK_FOR_Q (in))
|
||||
{
|
||||
if (TARGET_AM33)
|
||||
return DATA_OR_EXTENDED_REGS;
|
||||
return DATA_REGS;
|
||||
}
|
||||
|
||||
/* Otherwise assume no secondary reloads are needed. */
|
||||
return NO_REGS;
|
||||
}
|
||||
@ -826,8 +1347,10 @@ initial_offset (from, to)
|
||||
|| regs_ever_live[6] || regs_ever_live[7]
|
||||
|| regs_ever_live[14] || regs_ever_live[15]
|
||||
|| regs_ever_live[16] || regs_ever_live[17]
|
||||
|| fp_regs_to_save ()
|
||||
|| frame_pointer_needed)
|
||||
return REG_SAVE_BYTES;
|
||||
return REG_SAVE_BYTES
|
||||
+ 4 * fp_regs_to_save ();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
@ -841,8 +1364,10 @@ initial_offset (from, to)
|
||||
|| regs_ever_live[6] || regs_ever_live[7]
|
||||
|| regs_ever_live[14] || regs_ever_live[15]
|
||||
|| regs_ever_live[16] || regs_ever_live[17]
|
||||
|| fp_regs_to_save ()
|
||||
|| frame_pointer_needed)
|
||||
return (get_frame_size () + REG_SAVE_BYTES
|
||||
+ 4 * fp_regs_to_save ()
|
||||
+ (current_function_outgoing_args_size
|
||||
? current_function_outgoing_args_size + 4 : 0));
|
||||
else
|
||||
@ -1155,6 +1680,15 @@ const_8bit_operand (op, mode)
|
||||
&& INTVAL (op) < 256);
|
||||
}
|
||||
|
||||
/* Return true if the operand is the 1.0f constant. */
|
||||
int
|
||||
const_1f_operand (op, mode)
|
||||
register rtx op;
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return (op == CONST1_RTX (SFmode));
|
||||
}
|
||||
|
||||
/* Similarly, but when using a zero_extract pattern for a btst where
|
||||
the source operand might end up in memory. */
|
||||
int
|
||||
@ -1271,6 +1805,7 @@ mn10300_address_cost_1 (x, unsig)
|
||||
|
||||
case DATA_REGS:
|
||||
case EXTENDED_REGS:
|
||||
case FP_REGS:
|
||||
return 3;
|
||||
|
||||
case NO_REGS:
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Definitions of target machine for GNU compiler.
|
||||
Matsushita MN10300 series
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Jeff Law (law@cygnus.com).
|
||||
|
||||
@ -40,7 +40,7 @@ Boston, MA 02111-1307, USA. */
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define CPP_SPEC "%{mam33:-D__AM33__}"
|
||||
#define CPP_SPEC "%{mam33:-D__AM33__} %{mam33-2:-D__AM33__=2 -D__AM33_2__}"
|
||||
|
||||
/* Run-time compilation parameters selecting different hardware subsets. */
|
||||
|
||||
@ -60,6 +60,9 @@ extern int target_flags;
|
||||
/* Generate code for the AM33 processor. */
|
||||
#define TARGET_AM33 (target_flags & 0x2)
|
||||
|
||||
/* Generate code for the AM33/2.0 processor. */
|
||||
#define TARGET_AM33_2 (target_flags & 0x4)
|
||||
|
||||
#define TARGET_SWITCHES \
|
||||
{{ "mult-bug", 0x1, N_("Work around hardware multiply bug")}, \
|
||||
{ "no-mult-bug", -0x1, N_("Do not work around hardware multiply bug")},\
|
||||
@ -67,6 +70,9 @@ extern int target_flags;
|
||||
{ "am33", -(0x1), ""},\
|
||||
{ "no-am33", -0x2, ""}, \
|
||||
{ "no-crt0", 0, N_("No default crt0.o") }, \
|
||||
{ "am33-2", 0x6, N_("Target the AM33/2.0 processor")}, \
|
||||
{ "am33-2", -(0x1), ""},\
|
||||
{ "no-am33-2", -0x4, ""}, \
|
||||
{ "relax", 0, N_("Enable linker relaxations") }, \
|
||||
{ "", TARGET_DEFAULT, NULL}}
|
||||
|
||||
@ -131,7 +137,7 @@ extern int target_flags;
|
||||
All registers that the compiler knows about must be given numbers,
|
||||
even those that are not normally considered general registers. */
|
||||
|
||||
#define FIRST_PSEUDO_REGISTER 18
|
||||
#define FIRST_PSEUDO_REGISTER 50
|
||||
|
||||
/* Specify machine-specific register numbers. */
|
||||
#define FIRST_DATA_REGNUM 0
|
||||
@ -140,6 +146,8 @@ extern int target_flags;
|
||||
#define LAST_ADDRESS_REGNUM 8
|
||||
#define FIRST_EXTENDED_REGNUM 10
|
||||
#define LAST_EXTENDED_REGNUM 17
|
||||
#define FIRST_FP_REGNUM 18
|
||||
#define LAST_FP_REGNUM 49
|
||||
|
||||
/* Specify the registers used for certain standard purposes.
|
||||
The values of these macros are register numbers. */
|
||||
@ -162,7 +170,10 @@ extern int target_flags;
|
||||
and are not available for the register allocator. */
|
||||
|
||||
#define FIXED_REGISTERS \
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 \
|
||||
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \
|
||||
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \
|
||||
}
|
||||
|
||||
/* 1 for registers not available across function calls.
|
||||
These must include the FIXED_REGISTERS and also any
|
||||
@ -173,10 +184,16 @@ extern int target_flags;
|
||||
like. */
|
||||
|
||||
#define CALL_USED_REGISTERS \
|
||||
{ 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}
|
||||
{ 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 \
|
||||
, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \
|
||||
, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \
|
||||
}
|
||||
|
||||
#define REG_ALLOC_ORDER \
|
||||
{ 0, 1, 4, 5, 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 8, 9}
|
||||
{ 0, 1, 4, 5, 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 8, 9 \
|
||||
, 42, 43, 44, 45, 46, 47, 48, 49, 34, 35, 36, 37, 38, 39, 40, 41 \
|
||||
, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33 \
|
||||
}
|
||||
|
||||
#define CONDITIONAL_REGISTER_USAGE \
|
||||
{ \
|
||||
@ -188,6 +205,13 @@ extern int target_flags;
|
||||
i <= LAST_EXTENDED_REGNUM; i++) \
|
||||
fixed_regs[i] = call_used_regs[i] = 1; \
|
||||
} \
|
||||
if (!TARGET_AM33_2) \
|
||||
{ \
|
||||
for (i = FIRST_FP_REGNUM; \
|
||||
i <= LAST_FP_REGNUM; \
|
||||
i++) \
|
||||
fixed_regs[i] = call_used_regs[i] = 1; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Return number of consecutive hard regs needed starting at reg REGNO
|
||||
@ -247,6 +271,7 @@ enum reg_class {
|
||||
DATA_OR_ADDRESS_REGS, SP_OR_ADDRESS_REGS,
|
||||
EXTENDED_REGS, DATA_OR_EXTENDED_REGS, ADDRESS_OR_EXTENDED_REGS,
|
||||
SP_OR_EXTENDED_REGS, SP_OR_ADDRESS_OR_EXTENDED_REGS,
|
||||
FP_REGS, FP_ACC_REGS,
|
||||
GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES
|
||||
};
|
||||
|
||||
@ -260,6 +285,7 @@ enum reg_class {
|
||||
"EXTENDED_REGS", \
|
||||
"DATA_OR_EXTENDED_REGS", "ADDRESS_OR_EXTENDED_REGS", \
|
||||
"SP_OR_EXTENDED_REGS", "SP_OR_ADDRESS_OR_EXTENDED_REGS", \
|
||||
"FP_REGS", "FP_ACC_REGS", \
|
||||
"GENERAL_REGS", "ALL_REGS", "LIM_REGS" }
|
||||
|
||||
/* Define which registers fit in which classes.
|
||||
@ -267,19 +293,21 @@ enum reg_class {
|
||||
of length N_REG_CLASSES. */
|
||||
|
||||
#define REG_CLASS_CONTENTS \
|
||||
{ {0}, /* No regs */ \
|
||||
{0x0000f}, /* DATA_REGS */ \
|
||||
{0x001f0}, /* ADDRESS_REGS */ \
|
||||
{0x00200}, /* SP_REGS */ \
|
||||
{0x001ff}, /* DATA_OR_ADDRESS_REGS */\
|
||||
{0x003f0}, /* SP_OR_ADDRESS_REGS */\
|
||||
{0x3fc00}, /* EXTENDED_REGS */ \
|
||||
{0x3fc0f}, /* DATA_OR_EXTENDED_REGS */ \
|
||||
{0x3fdf0}, /* ADDRESS_OR_EXTENDED_REGS */ \
|
||||
{0x3fe00}, /* SP_OR_EXTENDED_REGS */ \
|
||||
{0x3fff0}, /* SP_OR_ADDRESS_OR_EXTENDED_REGS */ \
|
||||
{0x3fdff}, /* GENERAL_REGS */ \
|
||||
{0x3ffff}, /* ALL_REGS */ \
|
||||
{ { 0, 0 }, /* No regs */ \
|
||||
{ 0x0000f, 0 }, /* DATA_REGS */ \
|
||||
{ 0x001f0, 0 }, /* ADDRESS_REGS */ \
|
||||
{ 0x00200, 0 }, /* SP_REGS */ \
|
||||
{ 0x001ff, 0 }, /* DATA_OR_ADDRESS_REGS */\
|
||||
{ 0x003f0, 0 }, /* SP_OR_ADDRESS_REGS */\
|
||||
{ 0x3fc00, 0 }, /* EXTENDED_REGS */ \
|
||||
{ 0x3fc0f, 0 }, /* DATA_OR_EXTENDED_REGS */ \
|
||||
{ 0x3fdf0, 0 }, /* ADDRESS_OR_EXTENDED_REGS */ \
|
||||
{ 0x3fe00, 0 }, /* SP_OR_EXTENDED_REGS */ \
|
||||
{ 0x3fff0, 0 }, /* SP_OR_ADDRESS_OR_EXTENDED_REGS */ \
|
||||
{ 0xfffc0000, 0x3ffff }, /* FP_REGS */ \
|
||||
{ 0x03fc0000, 0 }, /* FP_ACC_REGS */ \
|
||||
{ 0x3fdff, 0 }, /* GENERAL_REGS */ \
|
||||
{ 0xffffffff, 0x3ffff } /* ALL_REGS */ \
|
||||
}
|
||||
|
||||
/* The same information, inverted:
|
||||
@ -292,6 +320,7 @@ enum reg_class {
|
||||
(REGNO) <= LAST_ADDRESS_REGNUM ? ADDRESS_REGS : \
|
||||
(REGNO) == STACK_POINTER_REGNUM ? SP_REGS : \
|
||||
(REGNO) <= LAST_EXTENDED_REGNUM ? EXTENDED_REGS : \
|
||||
(REGNO) <= LAST_FP_REGNUM ? FP_REGS : \
|
||||
NO_REGS)
|
||||
|
||||
/* The class value for index registers, and the one for base regs. */
|
||||
@ -306,6 +335,9 @@ enum reg_class {
|
||||
(C) == 'y' ? SP_REGS : \
|
||||
! TARGET_AM33 ? NO_REGS : \
|
||||
(C) == 'x' ? EXTENDED_REGS : \
|
||||
! TARGET_AM33_2 ? NO_REGS : \
|
||||
(C) == 'f' ? FP_REGS : \
|
||||
(C) == 'A' ? FP_ACC_REGS : \
|
||||
NO_REGS)
|
||||
|
||||
/* Macros to check register numbers against specific register classes. */
|
||||
@ -350,6 +382,8 @@ enum reg_class {
|
||||
#define REGNO_AM33_P(regno) \
|
||||
(REGNO_DATA_P ((regno)) || REGNO_ADDRESS_P ((regno)) \
|
||||
|| REGNO_EXTENDED_P ((regno)))
|
||||
#define REGNO_FP_P(regno) \
|
||||
REGNO_IN_RANGE_P ((regno), FIRST_FP_REGNUM, LAST_FP_REGNUM)
|
||||
|
||||
#define REGNO_OK_FOR_BASE_P(regno) \
|
||||
(REGNO_SP_P ((regno)) \
|
||||
@ -397,6 +431,11 @@ enum reg_class {
|
||||
#define CLASS_MAX_NREGS(CLASS, MODE) \
|
||||
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
|
||||
|
||||
/* A class that contains registers which the compiler must always
|
||||
access in a mode that is the same size as the mode in which it
|
||||
loaded the register. */
|
||||
#define CLASS_CANNOT_CHANGE_SIZE FP_REGS
|
||||
|
||||
/* The letters I, J, K, L, M, N, O, P in a register constraint string
|
||||
can be used to stand for particular ranges of immediate operands.
|
||||
This macro defines what the ranges are.
|
||||
@ -669,6 +708,9 @@ struct cum_arg {int nbytes; };
|
||||
|
||||
/* Extra constraints. */
|
||||
|
||||
#define OK_FOR_Q(OP) \
|
||||
(GET_CODE (OP) == MEM && ! CONSTANT_ADDRESS_P (XEXP (OP, 0)))
|
||||
|
||||
#define OK_FOR_R(OP) \
|
||||
(GET_CODE (OP) == MEM \
|
||||
&& GET_MODE (OP) == QImode \
|
||||
@ -692,6 +734,7 @@ struct cum_arg {int nbytes; };
|
||||
|
||||
#define EXTRA_CONSTRAINT(OP, C) \
|
||||
((C) == 'R' ? OK_FOR_R (OP) \
|
||||
: (C) == 'Q' ? OK_FOR_Q (OP) \
|
||||
: (C) == 'S' ? GET_CODE (OP) == SYMBOL_REF \
|
||||
: (C) == 'T' ? OK_FOR_T (OP) \
|
||||
: 0)
|
||||
@ -814,6 +857,7 @@ struct cum_arg {int nbytes; };
|
||||
! TARGET_AM33 ? 6 : \
|
||||
(CLASS1 == SP_REGS || CLASS2 == SP_REGS) ? 6 : \
|
||||
(CLASS1 == CLASS2 && CLASS1 == EXTENDED_REGS) ? 6 : \
|
||||
(CLASS1 == FP_REGS || CLASS2 == FP_REGS) ? 6 : \
|
||||
(CLASS1 == EXTENDED_REGS || CLASS2 == EXTENDED_REGS) ? 4 : \
|
||||
4)
|
||||
|
||||
@ -885,6 +929,10 @@ struct cum_arg {int nbytes; };
|
||||
#define REGISTER_NAMES \
|
||||
{ "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", "ap", "sp", \
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" \
|
||||
, "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7" \
|
||||
, "fs8", "fs9", "fs10", "fs11", "fs12", "fs13", "fs14", "fs15" \
|
||||
, "fs16", "fs17", "fs18", "fs19", "fs20", "fs21", "fs22", "fs23" \
|
||||
, "fs24", "fs25", "fs26", "fs27", "fs28", "fs29", "fs30", "fs31" \
|
||||
}
|
||||
|
||||
#define ADDITIONAL_REGISTER_NAMES \
|
||||
@ -892,6 +940,10 @@ struct cum_arg {int nbytes; };
|
||||
{"r12", 0}, {"r13", 1}, {"r14", 2}, {"r15", 3}, \
|
||||
{"e0", 10}, {"e1", 11}, {"e2", 12}, {"e3", 13}, \
|
||||
{"e4", 14}, {"e5", 15}, {"e6", 16}, {"e7", 17} \
|
||||
, {"fd0", 18}, {"fd2", 20}, {"fd4", 22}, {"fd6", 24} \
|
||||
, {"fd8", 26}, {"fd10", 28}, {"fd12", 30}, {"fd14", 32} \
|
||||
, {"fd16", 34}, {"fd18", 36}, {"fd20", 38}, {"fd22", 40} \
|
||||
, {"fd24", 42}, {"fd26", 44}, {"fd28", 46}, {"fd30", 48} \
|
||||
}
|
||||
|
||||
/* Print an instruction operand X on file FILE.
|
||||
@ -994,3 +1046,15 @@ struct cum_arg {int nbytes; };
|
||||
|
||||
#define FILE_ASM_OP "\t.file\n"
|
||||
|
||||
#define PREDICATE_CODES \
|
||||
{"const_1f_operand", {CONST_INT, CONST_DOUBLE}},
|
||||
|
||||
typedef struct mn10300_cc_status_mdep
|
||||
{
|
||||
int fpCC;
|
||||
}
|
||||
cc_status_mdep;
|
||||
|
||||
#define CC_STATUS_MDEP cc_status_mdep
|
||||
|
||||
#define CC_STATUS_MDEP_INIT (cc_status.mdep.fpCC = 0)
|
||||
|
@ -57,8 +57,8 @@
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:QI 0 "nonimmediate_operand" "=d*x*a,d*x,d*x*a,d*x*a,m")
|
||||
(match_operand:QI 1 "general_operand" "0,I,d*xai,m,d*xa"))]
|
||||
[(set (match_operand:QI 0 "nonimmediate_operand" "=d*x*a*f,d*x,d*x*a,d*x*a,m,*f,d*x*a")
|
||||
(match_operand:QI 1 "general_operand" "0,I,d*xai,m,d*xa,d*xa*f,*f"))]
|
||||
"TARGET_AM33
|
||||
&& (register_operand (operands[0], QImode)
|
||||
|| register_operand (operands[1], QImode))"
|
||||
@ -93,11 +93,14 @@
|
||||
case 3:
|
||||
case 4:
|
||||
return \"movbu %1,%0\";
|
||||
case 5:
|
||||
case 6:
|
||||
return \"fmov %1,%0\";
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}"
|
||||
[(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
|
||||
[(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:QI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
|
||||
@ -147,8 +150,8 @@
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "nonimmediate_operand" "=d*x*a,d*x,d*x*a,d*x*a,m")
|
||||
(match_operand:HI 1 "general_operand" "0,I,d*x*ai,m,d*x*a"))]
|
||||
[(set (match_operand:HI 0 "nonimmediate_operand" "=d*x*a*f,d*x,d*x*a,d*x*a,m,*f,d*x*a")
|
||||
(match_operand:HI 1 "general_operand" "0,I,d*x*ai,m,d*x*a,d*x*a*f,*f"))]
|
||||
"TARGET_AM33
|
||||
&& (register_operand (operands[0], HImode)
|
||||
|| register_operand (operands[1], HImode))"
|
||||
@ -183,11 +186,14 @@
|
||||
case 3:
|
||||
case 4:
|
||||
return \"movhu %1,%0\";
|
||||
case 5:
|
||||
case 6:
|
||||
return \"fmov %1,%0\";
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}"
|
||||
[(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
|
||||
[(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
|
||||
@ -277,9 +283,9 @@
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "nonimmediate_operand"
|
||||
"=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,axR,!*y")
|
||||
"=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,axR,!*y,*f,*f,dxaQ")
|
||||
(match_operand:SI 1 "general_operand"
|
||||
"0,0,I,I,dx,ax,dx,ax,dixm,aixm,dixm,aixm,!*y,axR"))]
|
||||
"0,0,I,I,dx,ax,dx,ax,dixm,aixm,dixm,aixm,!*y,axR,0,dxaQi*f,*f"))]
|
||||
"register_operand (operands[0], SImode)
|
||||
|| register_operand (operands[1], SImode)"
|
||||
"*
|
||||
@ -321,11 +327,16 @@
|
||||
return \"movu %1,%0\";
|
||||
}
|
||||
return \"mov %1,%0\";
|
||||
case 14:
|
||||
return \"nop\";
|
||||
case 15:
|
||||
case 16:
|
||||
return \"fmov %1,%0\";
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}"
|
||||
[(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
|
||||
[(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none,none_0hit,none_0hit")])
|
||||
|
||||
(define_expand "movsf"
|
||||
[(set (match_operand:SF 0 "general_operand" "")
|
||||
@ -340,8 +351,8 @@
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SF 0 "nonimmediate_operand" "=dx,ax,dx,a,daxm,dax")
|
||||
(match_operand:SF 1 "general_operand" "0,0,G,G,dax,daxFm"))]
|
||||
[(set (match_operand:SF 0 "nonimmediate_operand" "=f,dx,ax,dx,a,f,dxaQ,daxm,dax")
|
||||
(match_operand:SF 1 "general_operand" "0,0,0,G,G,fdxaQF,f,dax,daxFm"))]
|
||||
"register_operand (operands[0], SFmode)
|
||||
|| register_operand (operands[1], SFmode)"
|
||||
"*
|
||||
@ -350,12 +361,17 @@
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
return \"nop\";
|
||||
case 2:
|
||||
return \"clr %0\";
|
||||
return \"nop\";
|
||||
case 3:
|
||||
case 4:
|
||||
return \"clr %0\";
|
||||
/* case 4: below */
|
||||
case 5:
|
||||
case 6:
|
||||
return \"fmov %1, %0\";
|
||||
case 4:
|
||||
case 7:
|
||||
case 8:
|
||||
if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
|
||||
&& GET_CODE (operands[1]) == CONST_INT)
|
||||
{
|
||||
@ -370,7 +386,7 @@
|
||||
abort ();
|
||||
}
|
||||
}"
|
||||
[(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit")])
|
||||
[(set_attr "cc" "none,none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
|
||||
|
||||
(define_expand "movdi"
|
||||
[(set (match_operand:DI 0 "general_operand" "")
|
||||
@ -386,9 +402,9 @@
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:DI 0 "nonimmediate_operand"
|
||||
"=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
|
||||
"=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,*f,*f,*f,dxa,*f,Q")
|
||||
(match_operand:DI 1 "general_operand"
|
||||
"0,0,I,I,dx,ax,dx,ax,dxim,axim,dxim,axim"))]
|
||||
"0,0,I,I,dx,ax,dx,ax,dxim,axim,dxim,axim,0,*f,dxai,*f,Q,*f"))]
|
||||
"register_operand (operands[0], DImode)
|
||||
|| register_operand (operands[1], DImode)"
|
||||
"*
|
||||
@ -516,6 +532,26 @@
|
||||
output_asm_insn (\"mov %H1,%H0\", operands);
|
||||
return \"\";
|
||||
}
|
||||
case 12:
|
||||
return \"nop\";
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
return \"fmov %L1, %L0\;fmov %H1, %H0\";
|
||||
case 16:
|
||||
if (GET_CODE (operands[1]) == MEM
|
||||
&& GET_CODE (XEXP (operands[1], 0)) == CONST_INT
|
||||
&& (INTVAL (XEXP (operands[1], 0)) & 7) == 0)
|
||||
return \"fmov %D1, %D0\";
|
||||
else
|
||||
return \"fmov %L1, %L0\;fmov %H1, %H0\";
|
||||
case 17:
|
||||
if (GET_CODE (operands[0]) == MEM
|
||||
&& GET_CODE (XEXP (operands[0], 0)) == CONST_INT
|
||||
&& (INTVAL (XEXP (operands[0], 0)) & 7) == 0)
|
||||
return \"fmov %D1, %D0\";
|
||||
else
|
||||
return \"fmov %L1, %L0\;fmov %H1, %H0\";
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
@ -523,8 +559,9 @@
|
||||
[(set (attr "cc")
|
||||
(cond
|
||||
[
|
||||
(lt (symbol_ref "which_alternative") (const_int 2)
|
||||
) (const_string "none")
|
||||
(ior (lt (symbol_ref "which_alternative") (const_int 2))
|
||||
(eq (symbol_ref "which_alternative") (const_int 12))
|
||||
) (const_string "none")
|
||||
(eq (symbol_ref "which_alternative") (const_int 2)
|
||||
) (const_string "clobber")
|
||||
(eq (symbol_ref "which_alternative") (const_int 3)
|
||||
@ -555,9 +592,9 @@
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:DF 0 "nonimmediate_operand"
|
||||
"=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
|
||||
"=f,dx,ax,dx,f,f,dxa,f,Q,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
|
||||
(match_operand:DF 1 "general_operand"
|
||||
"0,0,G,G,dx,ax,dx,ax,dxFm,axFm,dxFm,axFm"))]
|
||||
"0,0,0,G,f,dxaF,f,Q,f,G,dx,ax,dx,ax,dxFm,axFm,dxFm,axFm"))]
|
||||
"register_operand (operands[0], DFmode)
|
||||
|| register_operand (operands[1], DFmode)"
|
||||
"*
|
||||
@ -569,24 +606,46 @@
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
return \"nop\";
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
return \"clr %L0\;clr %H0\";
|
||||
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
return \"fmov %L1, %L0\;fmov %H1, %H0\";
|
||||
|
||||
case 7:
|
||||
if (GET_CODE (operands[1]) == MEM
|
||||
&& GET_CODE (XEXP (operands[1], 0)) == CONST_INT
|
||||
&& (INTVAL (XEXP (operands[1], 0)) & 7) == 0)
|
||||
return \"fmov %D1, %D0\";
|
||||
else
|
||||
return \"fmov %L1, %L0\;fmov %H1, %H0\";
|
||||
|
||||
case 8:
|
||||
if (GET_CODE (operands[0]) == MEM
|
||||
&& GET_CODE (XEXP (operands[0], 0)) == CONST_INT
|
||||
&& (INTVAL (XEXP (operands[0], 0)) & 7) == 0)
|
||||
return \"fmov %D1, %D0\";
|
||||
else
|
||||
return \"fmov %L1, %L0\;fmov %H1, %H0\";
|
||||
|
||||
case 9:
|
||||
if (rtx_equal_p (operands[0], operands[1]))
|
||||
return \"sub %L1,%L0\;mov %L0,%H0\";
|
||||
else
|
||||
return \"mov %1,%L0\;mov %L0,%H0\";
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
case 17:
|
||||
if (GET_CODE (operands[1]) == CONST_INT)
|
||||
{
|
||||
rtx low, high;
|
||||
@ -692,17 +751,17 @@
|
||||
[(set (attr "cc")
|
||||
(cond
|
||||
[
|
||||
(lt (symbol_ref "which_alternative") (const_int 2)
|
||||
(lt (symbol_ref "which_alternative") (const_int 3)
|
||||
) (const_string "none")
|
||||
(eq (symbol_ref "which_alternative") (const_int 2)
|
||||
) (const_string "clobber")
|
||||
(eq (symbol_ref "which_alternative") (const_int 3)
|
||||
) (const_string "clobber")
|
||||
(eq (symbol_ref "which_alternative") (const_int 9)
|
||||
) (if_then_else
|
||||
(ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
|
||||
(const_int 0)) (const_string "clobber")
|
||||
(const_string "none_0hit"))
|
||||
(ior (eq (symbol_ref "which_alternative") (const_int 8))
|
||||
(eq (symbol_ref "which_alternative") (const_int 9))
|
||||
(ior (eq (symbol_ref "which_alternative") (const_int 14))
|
||||
(eq (symbol_ref "which_alternative") (const_int 15))
|
||||
) (if_then_else
|
||||
(ne (symbol_ref "mn10300_wide_const_load_uses_clr
|
||||
(operands)")
|
||||
@ -773,6 +832,14 @@
|
||||
btst 0,d0
|
||||
cmp %1,%0"
|
||||
[(set_attr "cc" "compare,compare")])
|
||||
|
||||
(define_insn "cmpsf"
|
||||
[(set (cc0)
|
||||
(compare (match_operand:SF 0 "register_operand" "f,f")
|
||||
(match_operand:SF 1 "nonmemory_operand" "f,F")))]
|
||||
"TARGET_AM33_2"
|
||||
"fcmp %1,%0"
|
||||
[(set_attr "cc" "compare,compare")])
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; ADD INSTRUCTIONS
|
||||
@ -1551,6 +1618,8 @@
|
||||
""
|
||||
"*
|
||||
{
|
||||
if (cc_status.mdep.fpCC)
|
||||
return \"fb%b1 %0\";
|
||||
if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
|
||||
&& (GET_CODE (operands[1]) == GT
|
||||
|| GET_CODE (operands[1]) == GE
|
||||
@ -1570,6 +1639,8 @@
|
||||
""
|
||||
"*
|
||||
{
|
||||
if (cc_status.mdep.fpCC)
|
||||
return \"fb%B1 %0\";
|
||||
if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
|
||||
&& (GET_CODE (operands[1]) == GT
|
||||
|| GET_CODE (operands[1]) == GE
|
||||
@ -1996,6 +2067,12 @@
|
||||
rtx result;
|
||||
rtx target;
|
||||
|
||||
if (TARGET_AM33_2)
|
||||
{
|
||||
emit_insn (gen_abssf2_am33_2 (operands[0], operands[1]));
|
||||
DONE;
|
||||
}
|
||||
|
||||
target = operand_subword_force (operands[0], 0, SFmode);
|
||||
result = expand_binop (SImode, and_optab,
|
||||
operand_subword_force (operands[1], 0, SFmode),
|
||||
@ -2012,6 +2089,15 @@
|
||||
}")
|
||||
|
||||
|
||||
(define_insn "abssf2_am33_2"
|
||||
[(set (match_operand:SF 0 "register_operand" "=f,f")
|
||||
(abs:SF (match_operand:SF 1 "register_operand" "0,?f")))]
|
||||
"TARGET_AM33_2"
|
||||
"@
|
||||
fabs %0
|
||||
fabs %1, %0"
|
||||
[(set_attr "cc" "none_0hit")])
|
||||
|
||||
(define_expand "negdf2"
|
||||
[(set (match_operand:DF 0 "register_operand" "")
|
||||
(neg:DF (match_operand:DF 1 "register_operand" "")))]
|
||||
@ -2052,6 +2138,12 @@
|
||||
rtx result;
|
||||
rtx target;
|
||||
|
||||
if (TARGET_AM33_2)
|
||||
{
|
||||
emit_insn (gen_negsf2_am33_2 (operands[0], operands[1]));
|
||||
DONE;
|
||||
}
|
||||
|
||||
target = operand_subword_force (operands[0], 0, SFmode);
|
||||
result = expand_binop (SImode, xor_optab,
|
||||
operand_subword_force (operands[1], 0, SFmode),
|
||||
@ -2068,6 +2160,114 @@
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn "negsf2_am33_2"
|
||||
[(set (match_operand:SF 0 "register_operand" "=f,f")
|
||||
(neg:SF (match_operand:SF 1 "register_operand" "0,?f")))]
|
||||
"TARGET_AM33_2"
|
||||
"@
|
||||
fneg %0
|
||||
fneg %1, %0"
|
||||
[(set_attr "cc" "none_0hit")])
|
||||
|
||||
(define_expand "sqrtsf2"
|
||||
[(set (match_operand:SF 0 "register_operand" "")
|
||||
(sqrt:SF (match_operand:SF 1 "register_operand" "")))]
|
||||
"TARGET_AM33_2 && flag_unsafe_math_optimizations"
|
||||
"
|
||||
{
|
||||
rtx scratch = gen_reg_rtx (SFmode);
|
||||
emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode)));
|
||||
emit_insn (gen_divsf3 (operands[0], force_reg (SFmode, CONST1_RTX (SFmode)),
|
||||
scratch));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn "rsqrtsf2"
|
||||
[(set (match_operand:SF 0 "register_operand" "=f,f")
|
||||
(div:SF (match_operand:SF 2 "const_1f_operand" "F,F")
|
||||
(sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))]
|
||||
"TARGET_AM33_2"
|
||||
"@
|
||||
frsqrt %0
|
||||
frsqrt %1, %0"
|
||||
[(set_attr "cc" "none_0hit")])
|
||||
|
||||
(define_insn "addsf3"
|
||||
[(set (match_operand:SF 0 "register_operand" "=f,f")
|
||||
(plus:SF (match_operand:SF 1 "register_operand" "%0,f")
|
||||
(match_operand:SF 2 "general_operand" "f,?fF")))]
|
||||
"TARGET_AM33_2"
|
||||
"@
|
||||
fadd %2, %0
|
||||
fadd %2, %1, %0"
|
||||
[(set_attr "cc" "none_0hit")])
|
||||
|
||||
(define_insn "subsf3"
|
||||
[(set (match_operand:SF 0 "register_operand" "=f,f")
|
||||
(minus:SF (match_operand:SF 1 "register_operand" "0,f")
|
||||
(match_operand:SF 2 "general_operand" "f,?fF")))]
|
||||
"TARGET_AM33_2"
|
||||
"@
|
||||
fsub %2, %0
|
||||
fsub %2, %1, %0"
|
||||
[(set_attr "cc" "none_0hit")])
|
||||
|
||||
(define_insn "mulsf3"
|
||||
[(set (match_operand:SF 0 "register_operand" "=f,f")
|
||||
(mult:SF (match_operand:SF 1 "register_operand" "%0,f")
|
||||
(match_operand:SF 2 "general_operand" "f,?fF")))]
|
||||
"TARGET_AM33_2"
|
||||
"@
|
||||
fmul %2, %0
|
||||
fmul %2, %1, %0"
|
||||
[(set_attr "cc" "none_0hit")])
|
||||
|
||||
(define_insn "divsf3"
|
||||
[(set (match_operand:SF 0 "register_operand" "=f,f")
|
||||
(div:SF (match_operand:SF 1 "register_operand" "0,f")
|
||||
(match_operand:SF 2 "general_operand" "f,?fF")))]
|
||||
"TARGET_AM33_2"
|
||||
"@
|
||||
fdiv %2, %0
|
||||
fdiv %2, %1, %0"
|
||||
[(set_attr "cc" "none_0hit")])
|
||||
|
||||
(define_insn "fmaddsf4"
|
||||
[(set (match_operand:SF 0 "register_operand" "=A")
|
||||
(plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
|
||||
(match_operand:SF 2 "register_operand" "f"))
|
||||
(match_operand:SF 3 "register_operand" "f")))]
|
||||
"TARGET_AM33_2"
|
||||
"fmadd %1, %2, %3, %0"
|
||||
[(set_attr "cc" "none_0hit")])
|
||||
|
||||
(define_insn "fmsubsf4"
|
||||
[(set (match_operand:SF 0 "register_operand" "=A")
|
||||
(minus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
|
||||
(match_operand:SF 2 "register_operand" "f"))
|
||||
(match_operand:SF 3 "register_operand" "f")))]
|
||||
"TARGET_AM33_2"
|
||||
"fmsub %1, %2, %3, %0"
|
||||
[(set_attr "cc" "none_0hit")])
|
||||
|
||||
(define_insn "fnmaddsf4"
|
||||
[(set (match_operand:SF 0 "register_operand" "=A")
|
||||
(minus:SF (match_operand:SF 3 "register_operand" "f")
|
||||
(mult:SF (match_operand:SF 1 "register_operand" "%f")
|
||||
(match_operand:SF 2 "register_operand" "f"))))]
|
||||
"TARGET_AM33_2"
|
||||
"fnmadd %1, %2, %3, %0"
|
||||
[(set_attr "cc" "none_0hit")])
|
||||
|
||||
(define_insn "fnmsubsf4"
|
||||
[(set (match_operand:SF 0 "register_operand" "=A")
|
||||
(minus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
|
||||
(match_operand:SF 2 "register_operand" "f")))
|
||||
(match_operand:SF 3 "register_operand" "f")))]
|
||||
"TARGET_AM33_2"
|
||||
"fnmsub %1, %2, %3, %0"
|
||||
[(set_attr "cc" "none_0hit")])
|
||||
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; PROLOGUE/EPILOGUE
|
||||
|
@ -10,8 +10,8 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
|
||||
echo '#define FLOAT' > fp-bit.c
|
||||
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
|
||||
|
||||
MULTILIB_OPTIONS = mam33
|
||||
MULTILIB_DIRNAMES = am33
|
||||
MULTILIB_OPTIONS = mam33/mam33-2
|
||||
MULTILIB_DIRNAMES = am33 am33-2
|
||||
|
||||
LIBGCC = stmp-multilib
|
||||
INSTALL_LIBGCC = install-multilib
|
||||
|
@ -386,6 +386,7 @@ in the following sections.
|
||||
@emph{MN10300 Options}
|
||||
@gccoptlist{-mmult-bug -mno-mult-bug @gol
|
||||
-mam33 -mno-am33 @gol
|
||||
-mam33-2 -mno-am33-2 @gol
|
||||
-mno-crt0 -mrelax}
|
||||
|
||||
@emph{M32R/D Options}
|
||||
|
Loading…
Reference in New Issue
Block a user