mn10300.c (REG_SAVE_BYTES): Allocate space for AM33 registers.
* mn10300.c (REG_SAVE_BYTES): Allocate space for AM33 registers. (asm_file_start): Emit .am33 into assembly file when compiling for the AM33. (print_operand_address): Handle POST_INC addresses. (can_use_return_insn, initial_offset): Check AM33 registers too. (expand_prologue): Check & save AM33 registers too. (expand_epilogue): Similarly. wise. (REG_CLASS_CONTENTS, REGNO_REG_CLASS): Likewise. (INDEX_REG_CLASS, REG_CLASS_FROM_LETTER): Likewise. (REGNO_OK_FOR_INDEX_P, PREFERRED_RELOAD_CLASS): Likewise. (PREFERRED_OUTPUT_RELOAD_CLASS, LIMIT_RELOAD_CLASS): Likewise. (REGISTER_MOVE_COST, REGISTER_NAMES): Likewise. (HAVE_POST_INCREMENT): Define. (GO_IF_LEGITIMATE_ADDRESS): Allow POST_INC addresses for the AM33. (GO_IF_MODE_DEPENDENT_ADDRESS): POST_INC is a mode dependent address. * mn10300.md (movqi, movhi, addsi, subsi): Add AM33 variants. (mulsi, andsi, iorsi, xorsi, notsi): Likewise. (ashiftsi, lshiftrtsi, ashiftrtsi): Likewise. (zero_extend to SI from QI/HI): Likewise. (sign_extend to SI from QI/HI): Likewise. (mulsidi3, umulsidi3): New patterns for the AM33. (tstsi with zero extension from QI/HI): Add AM33 variants. (movsi, movsf, movdi, movdf): Generate efficient code for the AM33 too. (return_internal_regs, store_movm): Handle new AM33 registers. * t-mn10300 (MULTILIB_OPTIONS, MULTILIB_DIRNAMES): Define. (LIBGCC, INSTALL_LIBGCC): Likewise. * invoke.texi: Document new flags. From-SVN: r30748
This commit is contained in:
parent
d525dfdf29
commit
705ac34f06
|
@ -1,3 +1,42 @@
|
|||
Wed Dec 1 16:51:22 1999 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
* mn10300.c (REG_SAVE_BYTES): Allocate space for AM33 registers.
|
||||
(asm_file_start): Emit .am33 into assembly file when compiling for
|
||||
the AM33.
|
||||
(print_operand_address): Handle POST_INC addresses.
|
||||
(can_use_return_insn, initial_offset): Check AM33 registers too.
|
||||
(expand_prologue): Check & save AM33 registers too.
|
||||
(expand_epilogue): Similarly.
|
||||
(secondary_reload_class): Handle AM33 specific secondary reloads.
|
||||
(output_tst): Emit efficient code for the AM33 too.
|
||||
* mn10300.h (CPP_SPEC, TARGET_AM33): Define.
|
||||
(TARGET_SWITCHES): Add -mam33 switch.
|
||||
(FIRST_PSEUDO_REGISTER): Handle new AM33 registers.
|
||||
(FIXED_REGISTERS, CALL_USED_REGISTERS): Likewise.
|
||||
(REG_ALLOC_ORDER, CONDITIONAL_REGISTER_USAGE): Likewise.
|
||||
(HARD_REGNO_MODE_OK, MODES_TIEABLE_P): Likewise.
|
||||
(enum reg_class, REG_CLASS_NAMES): Likewise.
|
||||
(REG_CLASS_CONTENTS, REGNO_REG_CLASS): Likewise.
|
||||
(INDEX_REG_CLASS, REG_CLASS_FROM_LETTER): Likewise.
|
||||
(REGNO_OK_FOR_INDEX_P, PREFERRED_RELOAD_CLASS): Likewise.
|
||||
(PREFERRED_OUTPUT_RELOAD_CLASS, LIMIT_RELOAD_CLASS): Likewise.
|
||||
(REGISTER_MOVE_COST, REGISTER_NAMES): Likewise.
|
||||
(HAVE_POST_INCREMENT): Define.
|
||||
(GO_IF_LEGITIMATE_ADDRESS): Allow POST_INC addresses for the AM33.
|
||||
(GO_IF_MODE_DEPENDENT_ADDRESS): POST_INC is a mode dependent address.
|
||||
* mn10300.md (movqi, movhi, addsi, subsi): Add AM33 variants.
|
||||
(mulsi, andsi, iorsi, xorsi, notsi): Likewise.
|
||||
(ashiftsi, lshiftrtsi, ashiftrtsi): Likewise.
|
||||
(zero_extend to SI from QI/HI): Likewise.
|
||||
(sign_extend to SI from QI/HI): Likewise.
|
||||
(mulsidi3, umulsidi3): New patterns for the AM33.
|
||||
(tstsi with zero extension from QI/HI): Add AM33 variants.
|
||||
(movsi, movsf, movdi, movdf): Generate efficient code for the AM33 too.
|
||||
(return_internal_regs, store_movm): Handle new AM33 registers.
|
||||
* t-mn10300 (MULTILIB_OPTIONS, MULTILIB_DIRNAMES): Define.
|
||||
(LIBGCC, INSTALL_LIBGCC): Likewise.
|
||||
* invoke.texi: Document new flags.
|
||||
|
||||
Fri Nov 26 10:59:12 CET 1999 Jan Hubicka <hubicka@freesoft.cz>
|
||||
|
||||
* i386.md (addsi3_cc): Add "binary_operator_ok" to the condition.
|
||||
|
|
|
@ -42,8 +42,10 @@ Boston, MA 02111-1307, USA. */
|
|||
speed standpoint, so we want to optimize this sooner or later. */
|
||||
#define REG_SAVE_BYTES (4 * regs_ever_live[2] \
|
||||
+ 4 * regs_ever_live[3] \
|
||||
+ 4 * regs_ever_live[6] \
|
||||
+ 4 * regs_ever_live[7])
|
||||
+ 4 * regs_ever_live[6] \
|
||||
+ 4 * regs_ever_live[7] \
|
||||
+ 16 * (regs_ever_live[14] || regs_ever_live[15] \
|
||||
|| regs_ever_live[16] || regs_ever_live[17]))
|
||||
|
||||
void
|
||||
asm_file_start (file)
|
||||
|
@ -54,6 +56,9 @@ asm_file_start (file)
|
|||
fprintf (file, "# -O%d\n", optimize);
|
||||
else
|
||||
fprintf (file, "\n\n");
|
||||
|
||||
if (TARGET_AM33)
|
||||
fprintf (file, "\t.am33\n");
|
||||
output_file_directive (file, main_input_filename);
|
||||
}
|
||||
|
||||
|
@ -312,6 +317,10 @@ print_operand_address (file, addr)
|
|||
{
|
||||
switch (GET_CODE (addr))
|
||||
{
|
||||
case POST_INC:
|
||||
print_operand_address (file, XEXP (addr, 0));
|
||||
fputc ('+', file);
|
||||
break;
|
||||
case REG:
|
||||
if (addr == stack_pointer_rtx)
|
||||
print_operand_address (file, gen_rtx_PLUS (SImode,
|
||||
|
@ -360,6 +369,10 @@ can_use_return_insn ()
|
|||
&& !regs_ever_live[3]
|
||||
&& !regs_ever_live[6]
|
||||
&& !regs_ever_live[7]
|
||||
&& !regs_ever_live[14]
|
||||
&& !regs_ever_live[15]
|
||||
&& !regs_ever_live[16]
|
||||
&& !regs_ever_live[17]
|
||||
&& !frame_pointer_needed);
|
||||
}
|
||||
|
||||
|
@ -388,6 +401,8 @@ expand_prologue ()
|
|||
single two byte instruction. */
|
||||
if (regs_ever_live[2] || regs_ever_live[3]
|
||||
|| regs_ever_live[6] || regs_ever_live[7]
|
||||
|| regs_ever_live[14] || regs_ever_live[15]
|
||||
|| regs_ever_live[16] || regs_ever_live[17]
|
||||
|| frame_pointer_needed)
|
||||
emit_insn (gen_store_movm ());
|
||||
|
||||
|
@ -432,6 +447,8 @@ expand_epilogue ()
|
|||
size = 0;
|
||||
}
|
||||
else if ((regs_ever_live[2] || regs_ever_live[3]
|
||||
|| regs_ever_live[14] || regs_ever_live[15]
|
||||
|| regs_ever_live[16] || regs_ever_live[17]
|
||||
|| regs_ever_live[6] || regs_ever_live[7])
|
||||
&& size + REG_SAVE_BYTES > 255)
|
||||
{
|
||||
|
@ -448,6 +465,8 @@ expand_epilogue ()
|
|||
stack requirements and is faster. */
|
||||
if (regs_ever_live[2] || regs_ever_live[3]
|
||||
|| regs_ever_live[6] || regs_ever_live[7]
|
||||
|| regs_ever_live[14] || regs_ever_live[15]
|
||||
|| regs_ever_live[16] || regs_ever_live[17]
|
||||
|| frame_pointer_needed)
|
||||
emit_jump_insn (gen_return_internal_regs (GEN_INT (size + REG_SAVE_BYTES)));
|
||||
else
|
||||
|
@ -554,6 +573,8 @@ secondary_reload_class (class, mode, in)
|
|||
&& (mode == QImode || mode == HImode)
|
||||
&& (class == ADDRESS_REGS || class == SP_REGS))
|
||||
{
|
||||
if (TARGET_AM33)
|
||||
return DATA_OR_EXTENDED_REGS;
|
||||
return DATA_REGS;
|
||||
}
|
||||
|
||||
|
@ -562,6 +583,9 @@ secondary_reload_class (class, mode, in)
|
|||
if (class != SP_REGS
|
||||
&& class != ADDRESS_REGS
|
||||
&& class != SP_OR_ADDRESS_REGS
|
||||
&& class != SP_OR_EXTENDED_REGS
|
||||
&& class != ADDRESS_OR_EXTENDED_REGS
|
||||
&& class != SP_OR_ADDRESS_OR_EXTENDED_REGS
|
||||
&& (in == stack_pointer_rtx
|
||||
|| (GET_CODE (in) == PLUS
|
||||
&& (XEXP (in, 0) == stack_pointer_rtx
|
||||
|
@ -572,6 +596,8 @@ secondary_reload_class (class, mode, in)
|
|||
&& (XEXP (in, 0) == stack_pointer_rtx
|
||||
|| XEXP (in, 1) == stack_pointer_rtx))
|
||||
{
|
||||
if (TARGET_AM33)
|
||||
return DATA_OR_EXTENDED_REGS;
|
||||
return DATA_REGS;
|
||||
}
|
||||
|
||||
|
@ -589,6 +615,8 @@ initial_offset (from, to)
|
|||
{
|
||||
if (regs_ever_live[2] || regs_ever_live[3]
|
||||
|| regs_ever_live[6] || regs_ever_live[7]
|
||||
|| regs_ever_live[14] || regs_ever_live[15]
|
||||
|| regs_ever_live[16] || regs_ever_live[17]
|
||||
|| frame_pointer_needed)
|
||||
return REG_SAVE_BYTES;
|
||||
else
|
||||
|
@ -602,6 +630,8 @@ initial_offset (from, to)
|
|||
{
|
||||
if (regs_ever_live[2] || regs_ever_live[3]
|
||||
|| regs_ever_live[6] || regs_ever_live[7]
|
||||
|| regs_ever_live[14] || regs_ever_live[15]
|
||||
|| regs_ever_live[16] || regs_ever_live[17]
|
||||
|| frame_pointer_needed)
|
||||
return (get_frame_size () + REG_SAVE_BYTES
|
||||
+ (current_function_outgoing_args_size
|
||||
|
@ -855,6 +885,26 @@ output_tst (operand, insn)
|
|||
&& !reg_set_between_p (SET_DEST (set), temp, insn)
|
||||
&& (REGNO_REG_CLASS (REGNO (SET_DEST (set)))
|
||||
== REGNO_REG_CLASS (REGNO (operand)))
|
||||
&& REGNO_REG_CLASS (REGNO (SET_DEST (set))) != EXTENDED_REGS
|
||||
&& REGNO (SET_DEST (set)) != REGNO (operand)
|
||||
&& (!past_call
|
||||
|| !call_used_regs[REGNO (SET_DEST (set))]))
|
||||
{
|
||||
rtx xoperands[2];
|
||||
xoperands[0] = operand;
|
||||
xoperands[1] = SET_DEST (set);
|
||||
|
||||
output_asm_insn ("cmp %1,%0", xoperands);
|
||||
return "";
|
||||
}
|
||||
|
||||
if (REGNO_REG_CLASS (REGNO (operand)) == EXTENDED_REGS
|
||||
&& REG_P (SET_DEST (set))
|
||||
&& SET_SRC (set) == CONST0_RTX (GET_MODE (SET_DEST (set)))
|
||||
&& !reg_set_between_p (SET_DEST (set), temp, insn)
|
||||
&& (REGNO_REG_CLASS (REGNO (SET_DEST (set)))
|
||||
!= REGNO_REG_CLASS (REGNO (operand)))
|
||||
&& REGNO_REG_CLASS (REGNO (SET_DEST (set))) == EXTENDED_REGS
|
||||
&& REGNO (SET_DEST (set)) != REGNO (operand)
|
||||
&& (!past_call
|
||||
|| !call_used_regs[REGNO (SET_DEST (set))]))
|
||||
|
|
|
@ -32,6 +32,8 @@ Boston, MA 02111-1307, USA. */
|
|||
|
||||
#define CPP_PREDEFINES "-D__mn10300__ -D__MN10300__"
|
||||
|
||||
#define CPP_SPEC "%{mam33:-D__AM33__}"
|
||||
|
||||
/* Run-time compilation parameters selecting different hardware subsets. */
|
||||
|
||||
extern int target_flags;
|
||||
|
@ -46,9 +48,16 @@ extern int target_flags;
|
|||
|
||||
/* Generate code to work around mul/mulq bugs on the mn10300. */
|
||||
#define TARGET_MULT_BUG (target_flags & 0x1)
|
||||
|
||||
/* Generate code for the AM33 processor. */
|
||||
#define TARGET_AM33 (target_flags & 0x2)
|
||||
|
||||
#define TARGET_SWITCHES \
|
||||
{{ "mult-bug", 0x1, "Work around hardware multiply bug"}, \
|
||||
{ "no-mult-bug", -0x1, "Do not work around hardware multiply bug"},\
|
||||
{ "am33", 0x2}, \
|
||||
{ "am33", -(0x1)},\
|
||||
{ "no-am33", -0x2}, \
|
||||
{ "", TARGET_DEFAULT, NULL}}
|
||||
|
||||
#ifndef TARGET_DEFAULT
|
||||
|
@ -134,13 +143,13 @@ 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 10
|
||||
#define FIRST_PSEUDO_REGISTER 18
|
||||
|
||||
/* 1 for registers that have pervasive standard uses
|
||||
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, 1, 1, 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
|
||||
|
@ -151,10 +160,19 @@ extern int target_flags;
|
|||
like. */
|
||||
|
||||
#define CALL_USED_REGISTERS \
|
||||
{ 1, 1, 0, 0, 1, 1, 0, 0, 1, 1}
|
||||
{ 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}
|
||||
|
||||
#define REG_ALLOC_ORDER \
|
||||
{ 0, 1, 4, 5, 2, 3, 6, 7, 8, 9}
|
||||
{ 0, 1, 4, 5, 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 8, 9}
|
||||
|
||||
#define CONDITIONAL_REGISTER_USAGE \
|
||||
{ \
|
||||
if (!TARGET_AM33) \
|
||||
{ \
|
||||
for (i = 10; i < 18; i++) \
|
||||
fixed_regs[i] = call_used_regs[i] = 1; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Return number of consecutive hard regs needed starting at reg REGNO
|
||||
to hold something of mode MODE.
|
||||
|
@ -169,7 +187,9 @@ extern int target_flags;
|
|||
MODE. */
|
||||
|
||||
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
|
||||
(REGNO_REG_CLASS (REGNO) == DATA_REGS \
|
||||
((REGNO_REG_CLASS (REGNO) == DATA_REGS \
|
||||
|| (TARGET_AM33 && REGNO_REG_CLASS (REGNO) == ADDRESS_REGS) \
|
||||
|| REGNO_REG_CLASS (REGNO) == EXTENDED_REGS) \
|
||||
? ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) <= 4 \
|
||||
: ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) == 4)
|
||||
|
||||
|
@ -178,7 +198,9 @@ extern int target_flags;
|
|||
If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
|
||||
for any hard reg, then this must be 0 for correct output. */
|
||||
#define MODES_TIEABLE_P(MODE1, MODE2) \
|
||||
(MODE1 == MODE2 || (GET_MODE_SIZE (MODE1) <= 4 && GET_MODE_SIZE (MODE2) <= 4))
|
||||
(TARGET_AM33 \
|
||||
|| MODE1 == MODE2 \
|
||||
|| (GET_MODE_SIZE (MODE1) <= 4 && GET_MODE_SIZE (MODE2) <= 4))
|
||||
|
||||
/* 4 data, and effectively 3 address registers is small as far as I'm
|
||||
concerned. */
|
||||
|
@ -207,6 +229,8 @@ extern int target_flags;
|
|||
enum reg_class {
|
||||
NO_REGS, DATA_REGS, ADDRESS_REGS, SP_REGS,
|
||||
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,
|
||||
GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES
|
||||
};
|
||||
|
||||
|
@ -217,6 +241,9 @@ enum reg_class {
|
|||
#define REG_CLASS_NAMES \
|
||||
{ "NO_REGS", "DATA_REGS", "ADDRESS_REGS", \
|
||||
"SP_REGS", "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", \
|
||||
"GENERAL_REGS", "ALL_REGS", "LIM_REGS" }
|
||||
|
||||
/* Define which registers fit in which classes.
|
||||
|
@ -225,13 +252,18 @@ enum reg_class {
|
|||
|
||||
#define REG_CLASS_CONTENTS \
|
||||
{ 0, /* No regs */ \
|
||||
0x00f, /* DATA_REGS */ \
|
||||
0x1f0, /* ADDRESS_REGS */ \
|
||||
0x200, /* SP_REGS */ \
|
||||
0x1ff, /* DATA_OR_ADDRESS_REGS */\
|
||||
0x1f0, /* SP_OR_ADDRESS_REGS */\
|
||||
0x1ff, /* GENERAL_REGS */ \
|
||||
0x3ff, /* ALL_REGS */ \
|
||||
0x0000f, /* DATA_REGS */ \
|
||||
0x001f0, /* ADDRESS_REGS */ \
|
||||
0x00200, /* SP_REGS */ \
|
||||
0x001ff, /* DATA_OR_ADDRESS_REGS */\
|
||||
0x003f0, /* SP_OR_ADDRESS_REGS */\
|
||||
0x2fc00, /* EXTENDED_REGS */ \
|
||||
0x2fc0f, /* DATA_OR_EXTENDED_REGS */ \
|
||||
0x2fdf0, /* ADDRESS_OR_EXTENDED_REGS */ \
|
||||
0x2fe00, /* SP_OR_EXTENDED_REGS */ \
|
||||
0x2fff0, /* SP_OR_ADDRESS_OR_EXTENDED_REGS */ \
|
||||
0x2fdff, /* GENERAL_REGS */ \
|
||||
0x2ffff, /* ALL_REGS */ \
|
||||
}
|
||||
|
||||
/* The same information, inverted:
|
||||
|
@ -242,10 +274,11 @@ enum reg_class {
|
|||
#define REGNO_REG_CLASS(REGNO) \
|
||||
((REGNO) < 4 ? DATA_REGS : \
|
||||
(REGNO) < 9 ? ADDRESS_REGS : \
|
||||
(REGNO) == 9 ? SP_REGS : 0)
|
||||
(REGNO) == 9 ? SP_REGS : \
|
||||
(REGNO) < 18 ? EXTENDED_REGS : 0)
|
||||
|
||||
/* The class value for index registers, and the one for base regs. */
|
||||
#define INDEX_REG_CLASS DATA_REGS
|
||||
#define INDEX_REG_CLASS DATA_OR_EXTENDED_REGS
|
||||
#define BASE_REG_CLASS SP_OR_ADDRESS_REGS
|
||||
|
||||
/* Get reg_class from a letter such as appears in the machine description. */
|
||||
|
@ -253,6 +286,7 @@ enum reg_class {
|
|||
#define REG_CLASS_FROM_LETTER(C) \
|
||||
((C) == 'd' ? DATA_REGS : \
|
||||
(C) == 'a' ? ADDRESS_REGS : \
|
||||
(C) == 'x' ? EXTENDED_REGS : \
|
||||
(C) == 'y' ? SP_REGS : NO_REGS)
|
||||
|
||||
/* Macros to check register numbers against specific register classes. */
|
||||
|
@ -273,6 +307,8 @@ enum reg_class {
|
|||
|
||||
#define REGNO_OK_FOR_INDEX_P(regno) \
|
||||
(((regno) >= 0 && regno < 4) \
|
||||
|| ((regno) >= 10 && regno < 18) \
|
||||
|| (reg_renumber[regno] >= 10 && reg_renumber[regno] < 18) \
|
||||
|| (reg_renumber[regno] >= 0 && reg_renumber[regno] < 4))
|
||||
|
||||
|
||||
|
@ -282,13 +318,15 @@ enum reg_class {
|
|||
in some cases it is preferable to use a more restrictive class. */
|
||||
|
||||
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
|
||||
(X == stack_pointer_rtx && CLASS != SP_REGS ? ADDRESS_REGS : CLASS)
|
||||
(X == stack_pointer_rtx && CLASS != SP_REGS \
|
||||
? ADDRESS_OR_EXTENDED_REGS : CLASS)
|
||||
|
||||
#define PREFERRED_OUTPUT_RELOAD_CLASS(X,CLASS) \
|
||||
(X == stack_pointer_rtx && CLASS != SP_REGS ? ADDRESS_REGS : CLASS)
|
||||
(X == stack_pointer_rtx && CLASS != SP_REGS \
|
||||
? ADDRESS_OR_EXTENDED_REGS : CLASS)
|
||||
|
||||
#define LIMIT_RELOAD_CLASS(MODE, CLASS) \
|
||||
((MODE == QImode || MODE == HImode) ? DATA_REGS : CLASS)
|
||||
(!TARGET_AM33 && (MODE == QImode || MODE == HImode) ? DATA_REGS : CLASS)
|
||||
|
||||
#define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
|
||||
secondary_reload_class(CLASS,MODE,IN)
|
||||
|
@ -645,6 +683,8 @@ extern struct rtx_def *mn10300_va_arg();
|
|||
#endif
|
||||
|
||||
|
||||
#define HAVE_POST_INCREMENT (TARGET_AM33)
|
||||
|
||||
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
|
||||
that is a valid memory address for an instruction.
|
||||
The MODE argument is the machine mode for the MEM expression
|
||||
|
@ -678,6 +718,11 @@ extern struct rtx_def *mn10300_va_arg();
|
|||
goto ADDR; \
|
||||
if (RTX_OK_FOR_BASE_P (X)) \
|
||||
goto ADDR; \
|
||||
if (TARGET_AM33 \
|
||||
&& GET_CODE (X) == POST_INC \
|
||||
&& RTX_OK_FOR_BASE_P (XEXP (X, 0)) \
|
||||
&& (MODE == SImode || MODE == SFmode || MODE == HImode))\
|
||||
goto ADDR; \
|
||||
if (GET_CODE (X) == PLUS) \
|
||||
{ \
|
||||
rtx base = 0, index = 0; \
|
||||
|
@ -719,7 +764,9 @@ extern struct rtx_def *legitimize_address ();
|
|||
/* Go to LABEL if ADDR (a legitimate address expression)
|
||||
has an effect that depends on the machine mode it is used for. */
|
||||
|
||||
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) {}
|
||||
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \
|
||||
if (GET_CODE (ADDR) == POST_INC) \
|
||||
goto LABEL
|
||||
|
||||
/* Nonzero if the constant value X is a legitimate general operand.
|
||||
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
|
||||
|
@ -772,8 +819,9 @@ extern struct rtx_def *legitimize_address ();
|
|||
case CONST_DOUBLE: \
|
||||
return 8;
|
||||
|
||||
|
||||
#define REGISTER_MOVE_COST(CLASS1, CLASS2) (CLASS1 != CLASS2 ? 4 : 2)
|
||||
#define REGISTER_MOVE_COST(CLASS1, CLASS2) \
|
||||
((CLASS1 == CLASS2 && (CLASS1 == ADDRESS_REGS || CLASS1 == DATA_REGS)) ? 2 :\
|
||||
CLASS1 == CLASS2 && CLASS1 == EXTENDED_REGS ? 6 : 4)
|
||||
|
||||
/* A crude cut at RTX_COSTS for the MN10300. */
|
||||
|
||||
|
@ -923,7 +971,8 @@ do { char dstr[30]; \
|
|||
This sequence is indexed by compiler's hard-register-number (see above). */
|
||||
|
||||
#define REGISTER_NAMES \
|
||||
{ "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", "ap", "sp" }
|
||||
{ "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", "ap", "sp", \
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" }
|
||||
|
||||
/* Print an instruction operand X on file FILE.
|
||||
look in mn10300.c for details */
|
||||
|
|
|
@ -55,6 +55,52 @@
|
|||
operands[1] = copy_to_mode_reg (QImode, operand1);
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:QI 0 "general_operand" "=dx,a,dx,a,dx,a,dx,a,dxa,m")
|
||||
(match_operand:QI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dxa"))]
|
||||
"TARGET_AM33
|
||||
&& (register_operand (operands[0], QImode)
|
||||
|| register_operand (operands[1], QImode))"
|
||||
"*
|
||||
{
|
||||
switch (which_alternative)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
return \"nop\";
|
||||
case 2:
|
||||
return \"clr %0\";
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
if (GET_CODE (operands[1]) == CONST_DOUBLE)
|
||||
{
|
||||
rtx xoperands[2];
|
||||
xoperands[0] = operands[0];
|
||||
xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
|
||||
output_asm_insn (\"mov %1,%0\", xoperands);
|
||||
return \"\";
|
||||
}
|
||||
|
||||
if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
|
||||
&& GET_CODE (operands[1]) == CONST_INT)
|
||||
{
|
||||
HOST_WIDE_INT val = INTVAL (operands[1]);
|
||||
|
||||
if (((val & 0x80) && ! (val & 0xffffff00))
|
||||
|| ((val & 0x800000) && ! (val & 0xff000000)))
|
||||
return \"movu %1,%0\";
|
||||
}
|
||||
return \"mov %1,%0\";
|
||||
case 8:
|
||||
case 9:
|
||||
return \"movbu %1,%0\";
|
||||
}
|
||||
}"
|
||||
[(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:QI 0 "general_operand" "=dx,*a,dx,*a,dx,*a,dx,*a,dx,m")
|
||||
(match_operand:QI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dx"))]
|
||||
|
@ -105,6 +151,52 @@
|
|||
operands[1] = copy_to_mode_reg (HImode, operand1);
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "general_operand" "=dx,a,dx,a,dx,a,dx,a,dxa,m")
|
||||
(match_operand:HI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dxa"))]
|
||||
"TARGET_AM33
|
||||
&& (register_operand (operands[0], HImode)
|
||||
|| register_operand (operands[1], HImode))"
|
||||
"*
|
||||
{
|
||||
switch (which_alternative)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
return \"nop\";
|
||||
case 2:
|
||||
return \"clr %0\";
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
if (GET_CODE (operands[1]) == CONST_DOUBLE)
|
||||
{
|
||||
rtx xoperands[2];
|
||||
xoperands[0] = operands[0];
|
||||
xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
|
||||
output_asm_insn (\"mov %1,%0\", xoperands);
|
||||
return \"\";
|
||||
}
|
||||
|
||||
if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
|
||||
&& GET_CODE (operands[1]) == CONST_INT)
|
||||
{
|
||||
HOST_WIDE_INT val = INTVAL (operands[1]);
|
||||
|
||||
if (((val & 0x80) && ! (val & 0xffffff00))
|
||||
|| ((val & 0x800000) && ! (val & 0xff000000)))
|
||||
return \"movu %1,%0\";
|
||||
}
|
||||
return \"mov %1,%0\";
|
||||
case 8:
|
||||
case 9:
|
||||
return \"movhu %1,%0\";
|
||||
}
|
||||
}"
|
||||
[(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "general_operand" "=dx,*a,dx,*a,dx,*a,dx,*a,dx,m")
|
||||
(match_operand:HI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dx"))]
|
||||
|
@ -229,6 +321,16 @@
|
|||
output_asm_insn (\"mov %1,%0\", xoperands);
|
||||
return \"\";
|
||||
}
|
||||
|
||||
if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
|
||||
&& GET_CODE (operands[1]) == CONST_INT)
|
||||
{
|
||||
HOST_WIDE_INT val = INTVAL (operands[1]);
|
||||
|
||||
if (((val & 0x80) && ! (val & 0xffffff00))
|
||||
|| ((val & 0x800000) && ! (val & 0xff000000)))
|
||||
return \"movu %1,%0\";
|
||||
}
|
||||
return \"mov %1,%0\";
|
||||
}
|
||||
}"
|
||||
|
@ -263,6 +365,15 @@
|
|||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
|
||||
&& GET_CODE (operands[1]) == CONST_INT)
|
||||
{
|
||||
HOST_WIDE_INT val = INTVAL (operands[1]);
|
||||
|
||||
if (((val & 0x80) && ! (val & 0xffffff00))
|
||||
|| ((val & 0x800000) && ! (val & 0xff000000)))
|
||||
return \"movu %1,%0\";
|
||||
}
|
||||
return \"mov %1,%0\";
|
||||
}
|
||||
}"
|
||||
|
@ -376,6 +487,11 @@
|
|||
else
|
||||
output_asm_insn (\"mov %L1,%L0\", operands);
|
||||
}
|
||||
else if ((REGNO_REG_CLASS (true_regnum (operands[0]))
|
||||
== EXTENDED_REGS)
|
||||
&& (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
|
||||
|| ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
|
||||
output_asm_insn (\"movu %1,%0\", operands);
|
||||
else
|
||||
output_asm_insn (\"mov %L1,%L0\", operands);
|
||||
|
||||
|
@ -392,6 +508,11 @@
|
|||
|| GET_CODE (operands[1]) == CONST_DOUBLE)
|
||||
&& val[0] == val[1])
|
||||
output_asm_insn (\"mov %L0,%H0\", operands);
|
||||
else if ((REGNO_REG_CLASS (true_regnum (operands[0]))
|
||||
== EXTENDED_REGS)
|
||||
&& (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
|
||||
|| ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
|
||||
output_asm_insn (\"movu %1,%0\", operands);
|
||||
else
|
||||
output_asm_insn (\"mov %H1,%H0\", operands);
|
||||
return \"\";
|
||||
|
@ -508,6 +629,11 @@
|
|||
else
|
||||
output_asm_insn (\"mov %L1,%L0\", operands);
|
||||
}
|
||||
else if ((REGNO_REG_CLASS (true_regnum (operands[0]))
|
||||
== EXTENDED_REGS)
|
||||
&& (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
|
||||
|| ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
|
||||
output_asm_insn (\"movu %1,%0\", operands);
|
||||
else
|
||||
output_asm_insn (\"mov %L1,%L0\", operands);
|
||||
|
||||
|
@ -524,6 +650,11 @@
|
|||
|| GET_CODE (operands[1]) == CONST_DOUBLE)
|
||||
&& val[0] == val[1])
|
||||
output_asm_insn (\"mov %L0,%H0\", operands);
|
||||
else if ((REGNO_REG_CLASS (true_regnum (operands[0]))
|
||||
== EXTENDED_REGS)
|
||||
&& (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
|
||||
|| ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
|
||||
output_asm_insn (\"movu %1,%0\", operands);
|
||||
else
|
||||
output_asm_insn (\"mov %H1,%H0\", operands);
|
||||
return \"\";
|
||||
|
@ -546,19 +677,30 @@
|
|||
"* return output_tst (operands[0], insn);"
|
||||
[(set_attr "cc" "set_znv")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a")))]
|
||||
"TARGET_AM33"
|
||||
"* return output_tst (operands[0], insn);"
|
||||
[(set_attr "cc" "set_znv")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))]
|
||||
""
|
||||
"* return output_tst (operands[0], insn);"
|
||||
[(set_attr "cc" "set_znv")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a")))]
|
||||
"TARGET_AM33"
|
||||
"* return output_tst (operands[0], insn);"
|
||||
[(set_attr "cc" "set_znv")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))]
|
||||
""
|
||||
"* return output_tst (operands[0], insn);"
|
||||
[(set_attr "cc" "set_znv")])
|
||||
|
||||
|
||||
(define_insn "cmpsi"
|
||||
[(set (cc0)
|
||||
(compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax")
|
||||
|
@ -593,6 +735,82 @@
|
|||
}
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dx,ax,ax,dax,xy,!dax")
|
||||
(plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
|
||||
(match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
|
||||
"TARGET_AM33"
|
||||
"*
|
||||
{
|
||||
switch (which_alternative)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
return \"inc %0\";
|
||||
case 2:
|
||||
return \"inc4 %0\";
|
||||
case 3:
|
||||
case 4:
|
||||
return \"add %2,%0\";
|
||||
case 5:
|
||||
{
|
||||
enum reg_class src1_class, src2_class, dst_class;
|
||||
|
||||
src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
|
||||
src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
|
||||
dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
|
||||
|
||||
/* I'm not sure if this can happen or not. Might as well be prepared
|
||||
and generate the best possible code if it does happen. */
|
||||
if (true_regnum (operands[0]) == true_regnum (operands[1]))
|
||||
return \"add %2,%0\";
|
||||
if (true_regnum (operands[0]) == true_regnum (operands[2]))
|
||||
return \"add %1,%0\";
|
||||
|
||||
/* Catch cases where no extended register was used. These should be
|
||||
handled just like the mn10300. */
|
||||
if (src1_class != EXTENDED_REGS
|
||||
&& src2_class != EXTENDED_REGS
|
||||
&& dst_class != EXTENDED_REGS)
|
||||
{
|
||||
/* We have to copy one of the sources into the destination, then
|
||||
add the other source to the destination.
|
||||
|
||||
Carefully select which source to copy to the destination; a naive
|
||||
implementation will waste a byte when the source classes are
|
||||
different and the destination is an address register. Selecting
|
||||
the lowest cost register copy will optimize this sequence. */
|
||||
if (REGNO_REG_CLASS (true_regnum (operands[1]))
|
||||
== REGNO_REG_CLASS (true_regnum (operands[0])))
|
||||
return \"mov %1,%0\;add %2,%0\";
|
||||
return \"mov %2,%0\;add %1,%0\";
|
||||
}
|
||||
|
||||
/* At least one register is an extended register. */
|
||||
|
||||
/* The three operand add instruction on the am33 is a win iff the
|
||||
output register is an extended register, or if both source
|
||||
registers are extended registers. */
|
||||
if (dst_class == EXTENDED_REGS
|
||||
|| src1_class == src2_class)
|
||||
return \"add %2,%1,%0\";
|
||||
|
||||
/* It is better to copy one of the sources to the destination, then
|
||||
perform a 2 address add. The destination in this case must be
|
||||
an address or data register and one of the sources must be an
|
||||
extended register and the remaining source must not be an extended
|
||||
register.
|
||||
|
||||
The best code for this case is to copy the extended reg to the
|
||||
destination, then emit a two address add. */
|
||||
if (src1_class == EXTENDED_REGS)
|
||||
return \"mov %1,%0\;add %2,%0\";
|
||||
return \"mov %2,%0\;add %1,%0\";
|
||||
}
|
||||
}
|
||||
}"
|
||||
[(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dx,ax,ax,dax,xy,!dax")
|
||||
(plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
|
||||
|
@ -644,6 +862,36 @@
|
|||
""
|
||||
"")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dax,!dax")
|
||||
(minus:SI (match_operand:SI 1 "register_operand" "0,dax")
|
||||
(match_operand:SI 2 "nonmemory_operand" "daxi,dax")))]
|
||||
"TARGET_AM33"
|
||||
"*
|
||||
{
|
||||
if (true_regnum (operands[0]) == true_regnum (operands[1]))
|
||||
return \"sub %2,%0\";
|
||||
else
|
||||
{
|
||||
enum reg_class src1_class, src2_class, dst_class;
|
||||
|
||||
src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
|
||||
src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
|
||||
dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
|
||||
|
||||
/* If no extended registers are used, then the best way to handle
|
||||
this is to copy the first source operand into the destination
|
||||
and emit a two address subtraction. */
|
||||
if (src1_class != EXTENDED_REGS
|
||||
&& src2_class != EXTENDED_REGS
|
||||
&& dst_class != EXTENDED_REGS
|
||||
&& true_regnum (operands[0]) != true_regnum (operands[2]))
|
||||
return \"mov %1,%0\;sub %2,%0\";
|
||||
return \"sub %2,%1,%0\";
|
||||
}
|
||||
}"
|
||||
[(set_attr "cc" "set_zn")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dax")
|
||||
(minus:SI (match_operand:SI 1 "register_operand" "0")
|
||||
|
@ -670,6 +918,22 @@
|
|||
;; MULTIPLY INSTRUCTIONS
|
||||
;; ----------------------------------------------------------------------
|
||||
|
||||
(define_insn "mulsidi3"
|
||||
[(set (match_operand:DI 0 "register_operand" "=dax")
|
||||
(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "dax"))
|
||||
(sign_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
|
||||
"TARGET_AM33"
|
||||
"mul %1,%2,%H0,%L0"
|
||||
[(set_attr "cc" "set_zn")])
|
||||
|
||||
(define_insn "umulsidi3"
|
||||
[(set (match_operand:DI 0 "register_operand" "=dax")
|
||||
(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "dax"))
|
||||
(zero_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
|
||||
"TARGET_AM33"
|
||||
"mulu %1,%2,%H0,%L0"
|
||||
[(set_attr "cc" "set_zn")])
|
||||
|
||||
(define_expand "mulsi3"
|
||||
[(set (match_operand:SI 0 "register_operand" "")
|
||||
(mult:SI (match_operand:SI 1 "register_operand" "")
|
||||
|
@ -677,6 +941,20 @@
|
|||
""
|
||||
"")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dx,!dax")
|
||||
(mult:SI (match_operand:SI 1 "register_operand" "%0,0")
|
||||
(match_operand:SI 2 "nonmemory_operand" "dx,daxi")))]
|
||||
"TARGET_AM33"
|
||||
"*
|
||||
{
|
||||
if (TARGET_MULT_BUG)
|
||||
return \"nop\;nop\;mul %2,%0\";
|
||||
else
|
||||
return \"mul %2,%0\";
|
||||
}"
|
||||
[(set_attr "cc" "set_zn")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dx")
|
||||
(mult:SI (match_operand:SI 1 "register_operand" "%0")
|
||||
|
@ -737,6 +1015,51 @@
|
|||
""
|
||||
"")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax")
|
||||
(and:SI (match_operand:SI 1 "register_operand" "%0,0,dax")
|
||||
(match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))]
|
||||
"TARGET_AM33"
|
||||
"*
|
||||
{
|
||||
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
|
||||
return \"extbu %0\";
|
||||
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
|
||||
return \"exthu %0\";
|
||||
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
|
||||
return \"add %0,%0\;lsr 1,%0\";
|
||||
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
|
||||
return \"asl2 %0\;lsr 2,%0\";
|
||||
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
|
||||
return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
|
||||
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
|
||||
return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
|
||||
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
|
||||
return \"lsr 1,%0\;add %0,%0\";
|
||||
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
|
||||
return \"lsr 2,%0\;asl2 %0\";
|
||||
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
|
||||
return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
|
||||
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
|
||||
return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
|
||||
if (REG_P (operands[2]) && REG_P (operands[1])
|
||||
&& true_regnum (operands[0]) != true_regnum (operands[1])
|
||||
&& true_regnum (operands[0]) != true_regnum (operands[2])
|
||||
&& REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
|
||||
&& REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
|
||||
&& REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
|
||||
return \"mov %1,%0\;and %2,%0\";
|
||||
if (REG_P (operands[2]) && REG_P (operands[1])
|
||||
&& true_regnum (operands[0]) != true_regnum (operands[1])
|
||||
&& true_regnum (operands[0]) != true_regnum (operands[2]))
|
||||
return \"and %1,%2,%0\";
|
||||
if (REG_P (operands[2]) && REG_P (operands[0])
|
||||
&& true_regnum (operands[2]) == true_regnum (operands[0]))
|
||||
return \"and %1,%0\";
|
||||
return \"and %2,%0\";
|
||||
}"
|
||||
[(set_attr "cc" "none_0hit,set_znv,set_znv")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dx,dx")
|
||||
(and:SI (match_operand:SI 1 "register_operand" "%0,0")
|
||||
|
@ -779,6 +1102,31 @@
|
|||
""
|
||||
"")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dx,!dax")
|
||||
(ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
|
||||
(match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
|
||||
"TARGET_AM33"
|
||||
"*
|
||||
{
|
||||
if (REG_P (operands[2]) && REG_P (operands[1])
|
||||
&& true_regnum (operands[0]) != true_regnum (operands[1])
|
||||
&& true_regnum (operands[0]) != true_regnum (operands[2])
|
||||
&& REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
|
||||
&& REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
|
||||
&& REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
|
||||
return \"mov %1,%0\;or %2,%0\";
|
||||
if (REG_P (operands[2]) && REG_P (operands[1])
|
||||
&& true_regnum (operands[0]) != true_regnum (operands[1])
|
||||
&& true_regnum (operands[0]) != true_regnum (operands[2]))
|
||||
return \"or %1,%2,%0\";
|
||||
if (REG_P (operands[2]) && REG_P (operands[0])
|
||||
&& true_regnum (operands[2]) == true_regnum (operands[0]))
|
||||
return \"or %1,%0\";
|
||||
return \"or %2,%0\";
|
||||
}"
|
||||
[(set_attr "cc" "set_znv")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dx")
|
||||
(ior:SI (match_operand:SI 1 "register_operand" "%0")
|
||||
|
@ -798,6 +1146,31 @@
|
|||
""
|
||||
"")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dx,!dax")
|
||||
(xor:SI (match_operand:SI 1 "register_operand" "%0,dax")
|
||||
(match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
|
||||
"TARGET_AM33"
|
||||
"*
|
||||
{
|
||||
if (REG_P (operands[2]) && REG_P (operands[1])
|
||||
&& true_regnum (operands[0]) != true_regnum (operands[1])
|
||||
&& true_regnum (operands[0]) != true_regnum (operands[2])
|
||||
&& REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
|
||||
&& REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
|
||||
&& REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
|
||||
return \"mov %1,%0\;xor %2,%0\";
|
||||
if (REG_P (operands[2]) && REG_P (operands[1])
|
||||
&& true_regnum (operands[0]) != true_regnum (operands[1])
|
||||
&& true_regnum (operands[0]) != true_regnum (operands[2]))
|
||||
return \"xor %1,%2,%0\";
|
||||
if (REG_P (operands[2]) && REG_P (operands[0])
|
||||
&& true_regnum (operands[2]) == true_regnum (operands[0]))
|
||||
return \"xor %1,%0\";
|
||||
return \"xor %2,%0\";
|
||||
}"
|
||||
[(set_attr "cc" "set_znv")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dx")
|
||||
(xor:SI (match_operand:SI 1 "register_operand" "%0")
|
||||
|
@ -815,7 +1188,14 @@
|
|||
(not:SI (match_operand:SI 1 "register_operand" "")))]
|
||||
""
|
||||
"")
|
||||
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dx,!dax")
|
||||
(not:SI (match_operand:SI 1 "register_operand" "0,0")))]
|
||||
"TARGET_AM33"
|
||||
"not %0"
|
||||
[(set_attr "cc" "set_znv")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dx")
|
||||
(not:SI (match_operand:SI 1 "register_operand" "0")))]
|
||||
|
@ -1214,6 +1594,20 @@
|
|||
""
|
||||
"")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "general_operand" "=dx,dx,dx,!dax,!dax,!dax")
|
||||
(zero_extend:SI
|
||||
(match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))]
|
||||
"TARGET_AM33"
|
||||
"@
|
||||
extbu %0
|
||||
mov %1,%0\;extbu %0
|
||||
movbu %1,%0
|
||||
extbu %0
|
||||
mov %1,%0\;extbu %0
|
||||
movbu %1,%0"
|
||||
[(set_attr "cc" "none_0hit")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "general_operand" "=dx,dx,dx")
|
||||
(zero_extend:SI
|
||||
|
@ -1232,6 +1626,20 @@
|
|||
""
|
||||
"")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "general_operand" "=dx,dx,dx,!dax,!dax,!dax")
|
||||
(zero_extend:SI
|
||||
(match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))]
|
||||
"TARGET_AM33"
|
||||
"@
|
||||
exthu %0
|
||||
mov %1,%0\;exthu %0
|
||||
movhu %1,%0
|
||||
exthu %0
|
||||
mov %1,%0\;exthu %0
|
||||
movhu %1,%0"
|
||||
[(set_attr "cc" "none_0hit")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "general_operand" "=dx,dx,dx")
|
||||
(zero_extend:SI
|
||||
|
@ -1252,6 +1660,18 @@
|
|||
""
|
||||
"")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "general_operand" "=dx,dx,!dax,!dax")
|
||||
(sign_extend:SI
|
||||
(match_operand:QI 1 "general_operand" "0,dx,0,dax")))]
|
||||
"TARGET_AM33"
|
||||
"@
|
||||
extb %0
|
||||
mov %1,%0\;extb %0
|
||||
extb %0
|
||||
mov %1,%0\;extb %0"
|
||||
[(set_attr "cc" "none_0hit")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "general_operand" "=dx,dx")
|
||||
(sign_extend:SI
|
||||
|
@ -1269,6 +1689,18 @@
|
|||
""
|
||||
"")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "general_operand" "=dx,dx,!dax,!dax")
|
||||
(sign_extend:SI
|
||||
(match_operand:HI 1 "general_operand" "0,dax,0,dax")))]
|
||||
"TARGET_AM33"
|
||||
"@
|
||||
exth %0
|
||||
mov %1,%0\;exth %0
|
||||
exth %0
|
||||
mov %1,%0\;exth %0"
|
||||
[(set_attr "cc" "none_0hit")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "general_operand" "=dx,dx")
|
||||
(sign_extend:SI
|
||||
|
@ -1291,6 +1723,39 @@
|
|||
""
|
||||
"")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
|
||||
(ashift:SI
|
||||
(match_operand:SI 1 "register_operand" "0,0,dax")
|
||||
(match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
|
||||
"TARGET_AM33"
|
||||
"*
|
||||
{
|
||||
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1)
|
||||
return \"add %0,%0\";
|
||||
|
||||
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2)
|
||||
return \"asl2 %0\";
|
||||
|
||||
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 3
|
||||
&& REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
|
||||
return \"asl2 %0\;add %0,%0\";
|
||||
|
||||
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 4
|
||||
&& REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
|
||||
return \"asl2 %0\;asl2 %0\";
|
||||
|
||||
if (true_regnum (operands[1]) == true_regnum (operands[0]))
|
||||
return \"asl %S2,%0\";
|
||||
|
||||
if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
|
||||
&& REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
|
||||
&& true_regnum (operands[0]) != true_regnum (operands[2]))
|
||||
return \"mov %1,%0\;asl %S2,%0\";
|
||||
return \"asl %2,%1,%0\";
|
||||
}"
|
||||
[(set_attr "cc" "set_zn")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
|
||||
(ashift:SI
|
||||
|
@ -1313,6 +1778,25 @@
|
|||
""
|
||||
"")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dx,!dax")
|
||||
(lshiftrt:SI
|
||||
(match_operand:SI 1 "register_operand" "0,dax")
|
||||
(match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
|
||||
"TARGET_AM33"
|
||||
"*
|
||||
{
|
||||
if (true_regnum (operands[1]) == true_regnum (operands[0]))
|
||||
return \"lsr %S2,%0\";
|
||||
|
||||
if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
|
||||
&& REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
|
||||
&& true_regnum (operands[0]) != true_regnum (operands[2]))
|
||||
return \"mov %1,%0\;lsr %S2,%0\";
|
||||
return \"lsr %2,%1,%0\";
|
||||
}"
|
||||
[(set_attr "cc" "set_zn")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dx")
|
||||
(lshiftrt:SI
|
||||
|
@ -1330,6 +1814,25 @@
|
|||
""
|
||||
"")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dx,!dax")
|
||||
(ashiftrt:SI
|
||||
(match_operand:SI 1 "register_operand" "0,dax")
|
||||
(match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
|
||||
"TARGET_AM33"
|
||||
"*
|
||||
{
|
||||
if (true_regnum (operands[1]) == true_regnum (operands[0]))
|
||||
return \"asr %S2,%0\";
|
||||
|
||||
if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
|
||||
&& REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
|
||||
&& true_regnum (operands[0]) != true_regnum (operands[2]))
|
||||
return \"mov %1,%0\;asr %S2,%0\";
|
||||
return \"asr %2,%1,%0\";
|
||||
}"
|
||||
[(set_attr "cc" "set_zn")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=dx")
|
||||
(ashiftrt:SI
|
||||
|
@ -1495,6 +1998,7 @@
|
|||
{
|
||||
int i, need_comma;
|
||||
int d2, d3, a2, a3;
|
||||
int exreg1;
|
||||
|
||||
need_comma = 0;
|
||||
fputs (\"\\tret [\", asm_out_file);
|
||||
|
@ -1524,6 +2028,14 @@
|
|||
fputs (\"a3\", asm_out_file);
|
||||
need_comma = 1;
|
||||
}
|
||||
if (regs_ever_live[14] || regs_ever_live[15]
|
||||
|| regs_ever_live[16] || regs_ever_live[17])
|
||||
{
|
||||
if (need_comma)
|
||||
fputc (',', asm_out_file);
|
||||
fputs (\"exreg1\", asm_out_file);
|
||||
need_comma = 1;
|
||||
}
|
||||
fprintf (asm_out_file, \"],%d\\n\", INTVAL (operands[0]));
|
||||
return \"\";
|
||||
}"
|
||||
|
@ -1536,6 +2048,7 @@
|
|||
{
|
||||
int i, need_comma;
|
||||
int d2, d3, a2, a3;
|
||||
int exreg1;
|
||||
|
||||
need_comma = 0;
|
||||
fputs (\"\\tmovm [\", asm_out_file);
|
||||
|
@ -1565,6 +2078,14 @@
|
|||
fputs (\"a3\", asm_out_file);
|
||||
need_comma = 1;
|
||||
}
|
||||
if (regs_ever_live[14] || regs_ever_live[15]
|
||||
|| regs_ever_live[16] || regs_ever_live[17])
|
||||
{
|
||||
if (need_comma)
|
||||
fputc (',', asm_out_file);
|
||||
fputs (\"exreg1\", asm_out_file);
|
||||
need_comma = 1;
|
||||
}
|
||||
fputs (\"],(sp)\\n\", asm_out_file);
|
||||
return \"\";
|
||||
}"
|
||||
|
|
|
@ -18,3 +18,9 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
|
|||
echo '#define FLOAT_BIT_ORDER_MISMATCH' >>fp-bit.c
|
||||
echo '#endif' >> fp-bit.c
|
||||
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
|
||||
|
||||
MULTILIB_OPTIONS = mam33
|
||||
MULTILIB_DIRNAMES = am33
|
||||
|
||||
LIBGCC = stmp-multilib
|
||||
INSTALL_LIBGCC = install-multilib
|
||||
|
|
|
@ -291,6 +291,8 @@ in the following sections.
|
|||
@emph{MN10300 Options}
|
||||
-mmult-bug
|
||||
-mno-mult-bug
|
||||
-mam33
|
||||
-mno-am33
|
||||
-mrelax
|
||||
|
||||
@emph{M32R/D Options}
|
||||
|
@ -4641,6 +4643,14 @@ processors. This is the default.
|
|||
Do not generate code to avoid bugs in the multiply instructions for the
|
||||
MN10300 processors.
|
||||
|
||||
@table @code
|
||||
@item -mam33
|
||||
Generate code which uses features specific to the AM33 processor.
|
||||
|
||||
@item -mno-am33
|
||||
Do not generate code which uses features specific to the AM33 processor. This
|
||||
is the default.
|
||||
|
||||
@item -mrelax
|
||||
Indicate to the linker that it should perform a relaxation optimization pass
|
||||
to shorten branches, calls and absolute memory addresses. This option only
|
||||
|
|
Loading…
Reference in New Issue