Commit 8e87e161 by Steve Chamberlain

*** empty log message ***

From-SVN: r7790
parent b1cf6cee
......@@ -132,6 +132,7 @@ push (rn)
void
pop (rn)
int rn;
{
emit_insn (gen_pop (gen_rtx (REG, SImode, rn)));
}
......@@ -299,7 +300,6 @@ print_operand_address (stream, x)
default:
debug_rtx (x);
abort ();
}
}
......@@ -354,9 +354,9 @@ print_operand (stream, x, code)
break;
case '@':
if (pragma_interrupt)
fprintf (stream,"rte");
fprintf (stream, "rte");
else
fprintf (stream,"rts");
fprintf (stream, "rts");
break;
case '#':
/* Output a nop if there's nothing in the delay slot */
......@@ -405,7 +405,9 @@ print_operand (stream, x, code)
}
static int
sextb (x)
int x;
{
x &= 0xff;
if (x > 127)
......@@ -592,10 +594,8 @@ expand_block_move (operands)
}
if (mode == SImode && constp && (bytes % 4 == 0))
{
char entry[30];
tree entry_name;
rtx func_addr_rtx;
int groups;
rtx r4 = gen_rtx (REG, SImode, 4);
rtx r5 = gen_rtx (REG, SImode, 5);
rtx r6 = gen_rtx (REG, SImode, 6);
......@@ -740,6 +740,7 @@ prepare_move_operands (operands, mode)
compare has been done. */
rtx
prepare_scc_operands (code)
int code;
{
if (GET_CODE (sh_compare_op0) != REG
|| REGNO (sh_compare_op0) != T_REG)
......@@ -863,6 +864,10 @@ output_movedouble (insn, operands, mode)
{
return "mov.l %1,%0\n\tmov.l %1+4,%R0";
}
else if (GET_CODE (inside) == POST_INC)
{
return "mov.l %1,%0\n\tmov.l %1,%R0 !mdi\n";
}
else
abort ();
......@@ -1022,11 +1027,6 @@ output_far_jump (insn, op)
{
rtx thislab = gen_label_rtx ();
/* See if we can grab a reg from the prev insn */
rtx gotone = 0;
rtx prev = PREV_INSN (insn);
rtx link;
if (dbr_sequence_length ())
{
/* Something to go in what would have been the delay
......@@ -1041,7 +1041,8 @@ output_far_jump (insn, op)
for (i = 0; i < 8; i++)
{
vec[1] = gen_rtx (REG, SImode, i);
if (!reg_referenced_p (vec[1], PATTERN (XVECEXP (final_sequence, 0, 1))))
if (!reg_referenced_p (vec[1],
PATTERN (XVECEXP (final_sequence, 0, 1))))
break;
}
......@@ -1072,9 +1073,8 @@ output_branch (logic, insn)
{
extern rtx recog_operand[];
int label = lf++;
int rn = -1;
int need_save;
/* fprintf (asm_out_file, "! pc %04x\n", insn_addresses[INSN_UID (insn)]);*/
/* fprintf (asm_out_file, "! pc %04x\n", insn_addresses[INSN_UID (insn)]);*/
switch (get_attr_length (insn))
{
......@@ -1245,7 +1245,7 @@ add_constant (x, mode)
/* Dump out interesting debug info */
rtx
void
final_prescan_insn (insn, opvec, noperands)
rtx insn;
rtx *opvec;
......@@ -1365,7 +1365,7 @@ output_file_start (file, f_options, f_len, W_options, W_len)
data_section ();
pos = fprintf (file, "\n! Hitachi SH cc1 (%s) (release D-1) arguments:", version_string);
pos = fprintf (file, "\n! Hitachi SH cc1 (%s) (release E-2) arguments:", version_string);
output_options (file, f_options, f_len, W_options, W_len,
pos, 75, " ", "\n! ", "\n\n");
}
......@@ -1410,25 +1410,30 @@ andcosts (RTX)
return 5;
}
int howshift (i)
int i;
int
howshift (i)
int i;
{
int total = 0;
while (i > 0)
{
if (i >= 16) {
if (i >= 16)
{
total++;
i -= 16;
}
else if (i >= 8) {
else if (i >= 8)
{
total++;
i -= 8;
}
else if (i >= 2) {
else if (i >= 2)
{
total++;
i -= 2;
}
else if (i>=1) {
else if (i >= 1)
{
total++;
i--;
}
......@@ -1442,7 +1447,7 @@ multcosts (RTX)
rtx RTX;
{
/* If mult by a power of 2 then work out how we'd shift to make it */
int insn_cost;
int insn_cost = 0;
if (GET_CODE (XEXP (RTX, 1)) == CONST_INT)
{
......@@ -1627,7 +1632,6 @@ dump_table (scan)
rtx scan;
{
int i;
int pass;
int need_align = 1;
......@@ -1706,6 +1710,10 @@ fixit (src, mode)
{
return 1;
}
if (GET_CODE (src) == LABEL_REF)
{
return 1;
}
if (GET_CODE (src) == CONST_INT)
{
/* All QI insns are ok */
......@@ -1740,17 +1748,18 @@ hi_const (src)
/* Find the last barrier less than MAX_COUNT bytes from FROM, or create one.
If an HI move is found, then make sure that MAX_COUNT_HI isn't broken from that one. */
static rtx from;
static
rtx
find_barrier (from)
rtx from;
find_barrier (from_)
rtx from_;
{
int count_si = 0;
int count_hi = 0;
int found_hi = 0;
int found_si = 0;
rtx found_barrier = 0;
from = from_;
while (from
&& count_si < max_count_si
&& count_hi < max_count_hi)
......@@ -1786,11 +1795,14 @@ find_barrier (from)
if (!found_barrier)
{
/* Insert a jump around the barrier here */
/* We didn't find a barrier in time to
dump our stuff, so we'll make one */
rtx label = gen_label_rtx ();
/* Walk back to be just before any jump */
from = PREV_INSN (from);
while (GET_CODE (from) == JUMP_INSN
|| GET_CODE (from) == NOTE)
|| GET_CODE (from) == NOTE
|| GET_CODE (from) == CODE_LABEL)
{
from = PREV_INSN (from);
}
......@@ -1836,7 +1848,6 @@ machine_dependent_reorg (first)
rtx first;
{
rtx insn;
int limit;
for (insn = first; insn; insn = NEXT_INSN (insn))
{
if (broken_move (insn))
......@@ -1895,7 +1906,7 @@ machine_dependent_reorg (first)
/* Called from the md file, set up the operands of a compare instruction */
int
void
from_compare (operands, code)
rtx *operands;
int code;
......@@ -1923,7 +1934,41 @@ equality_operator (x, mode)
}
/* Framefull frame looks like:
/* Add this function to the list of ones seen - temporary
gross hack to try out bsrs. */
struct flist
{
char *name;
struct flist *next;
};
struct flist *head;
static void
add_function (name)
char *name;
{
struct flist *n = (struct flist *) xmalloc (sizeof (struct flist));
int l = strlen (name) + 1;
n->name = xmalloc (l);
memcpy (n->name, name, l);
n->next = head;
head = n;
}
static int
seen_function (name)
char *name;
{
struct flist *p = head;
for (p = head; p; p = p->next)
{
if (strcmp (p->name, name) == 0)
return 1;
}
return 0;
}
/* Framefull frame looks like:
arg-5
arg-4
......@@ -1949,7 +1994,7 @@ equality_operator (x, mode)
*/
/* Code to generate prologue and epilogue sequences */
/* Code to generate prologue and epilogue sequences */
void
......@@ -1957,7 +2002,7 @@ sh_expand_prologue ()
{
int live_regs_mask;
int d;
extern tree current_function_decl;
live_regs_mask = calc_live_regs (&d);
/* We have pretend args if we had an object sent partially in registers
......@@ -1984,6 +2029,12 @@ sh_expand_prologue ()
{
emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
}
if (TARGET_BSR)
{
add_function (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
}
}
void
......@@ -2027,11 +2078,14 @@ sh_expand_epilogue ()
int
initial_elimination_offset (from, to)
int from;
int to;
{
int regs_saved;
int regs_saved_mask = calc_live_regs (&regs_saved);
int total_saved_regs_space;
int total_auto_space = get_frame_size ();
calc_live_regs (&regs_saved);
total_saved_regs_space = (regs_saved) * 4;
if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
......@@ -2074,12 +2128,12 @@ handle_pragma (file)
if (psize == 9 && strncmp (pbuf, "interrupt", 9) == 0)
{
pragma_interrupt = 1;
return;
return c;
}
if (psize == 5 && strncmp (pbuf, "trapa", 5) == 0)
{
pragma_interrupt = pragma_trapa = 1;
return;
return c;
}
c = getc (file);
}
......@@ -2103,12 +2157,12 @@ expand_acall (isa_retval, operands)
rtx call_target = operands[isa_retval + 0];
rtx numargs = operands[isa_retval + 1];
if (TARGET_BSR)
if (TARGET_BSR && bsr_operand (call_target, VOIDmode))
{
call = gen_rtx (CALL, VOIDmode, call_target, numargs);
}
else {
else
{
if (GET_CODE (call_target) == MEM)
{
call_target = force_reg (Pmode,
......@@ -2156,10 +2210,18 @@ general_movsrc_operand (op, mode)
GET_CODE (XEXP (op, 0)) == LABEL_REF)
return 1;
/* No predec allowed */
/* No post inc allowed */
if (GET_CODE (op) == MEM
&& (GET_CODE (XEXP (op, 0)) == POST_DEC
|| GET_CODE (XEXP (op, 0)) == PRE_INC
|| GET_CODE (XEXP (op, 0)) == PRE_DEC))
return 0;
/* Can't do that with large modes */
if (GET_CODE (op) == MEM
&& GET_CODE (XEXP (op, 0)) == PRE_DEC)
&& GET_CODE (XEXP (op, 0)) == POST_INC
&& GET_MODE_SIZE (mode) > 4)
return 0;
if ((mode == QImode || mode == HImode)
......@@ -2185,12 +2247,18 @@ general_movdst_operand (op, mode)
rtx op;
enum machine_mode mode;
{
/* No pre dec allowed */
if (GET_CODE (op) == MEM
&& (GET_CODE (XEXP (op, 0)) == PRE_INC
|| GET_CODE (XEXP (op, 0)) == POST_INC
|| GET_CODE (XEXP (op, 0)) == POST_DEC))
return 0;
if (GET_CODE (op) == MEM
&& GET_CODE (XEXP (op, 0)) == PRE_DEC
&& GET_MODE_SIZE (mode) > 4)
return 0;
return general_operand (op, mode);
}
......@@ -2200,11 +2268,19 @@ general_movdst_operand (op, mode)
int
bsr_operand (op, mode)
rtx op;
enum machine_mode mode;
rtx op;
enum machine_mode mode;
{
if (TARGET_BSR)
{
if (GET_CODE (op) == SYMBOL_REF)
{
if (!strcmp (XSTR (op, 0),
IDENTIFIER_POINTER (DECL_NAME (current_function_decl))))
return 1;
return (seen_function (XSTR (op, 0)));
}
}
return 0;
}
......@@ -2351,10 +2427,10 @@ mac_operand (op, mode)
rtx
sh_function_arg (cum, mode, type, named)
CUMULATIVE_ARGS cum;
enum machine_mode mode;
tree type;
int named;
CUMULATIVE_ARGS cum;
enum machine_mode mode;
tree type;
int named;
{
if (named)
{
......@@ -2363,11 +2439,11 @@ int named;
if (rr < NPARM_REGS)
{
return ((((mode) != BLKmode
&& ((type)==0 || ! TREE_ADDRESSABLE ((tree)(type)))
&& ((type)==0 || (mode) != BLKmode
&& ((type) == 0 || !TREE_ADDRESSABLE ((tree) (type)))
&& ((type) == 0 || (mode) != BLKmode
|| (TYPE_ALIGN ((type)) % PARM_BOUNDARY == 0))
? gen_rtx (REG, (mode),
(FIRST_PARM_REG + rr)): 0)));
(FIRST_PARM_REG + rr)) : 0)));
}
}
......@@ -2389,8 +2465,8 @@ sh_function_arg_partial_nregs (CUM, MODE, TYPE, NAMED)
{
if ((CUM) < NPARM_REGS)
{
if (((TYPE)==0 || ! TREE_ADDRESSABLE ((tree)(TYPE)))
&& ((TYPE)==0 || (MODE) != BLKmode
if (((TYPE) == 0 || !TREE_ADDRESSABLE ((tree) (TYPE)))
&& ((TYPE) == 0 || (MODE) != BLKmode
|| (TYPE_ALIGN ((TYPE)) % PARM_BOUNDARY == 0))
&& ((CUM) + ((MODE) == BLKmode
? ROUND_ADVANCE (int_size_in_bytes (TYPE))
......@@ -2401,4 +2477,3 @@ sh_function_arg_partial_nregs (CUM, MODE, TYPE, NAMED)
}
return 0;
}
/* Definitions of target machine for GNU compiler, for Hitachi Super-H.
/* Definitions of target machine for GNU compiler,
for Hitachi Super-H.
Copyright (C) 1993, 1994 Free Software Foundation, Inc.
Contributed by Steve Chamberlain (sac@cygnus.com)
......@@ -83,6 +84,7 @@ extern int target_flags;
#define CONSTLEN_0_BIT (1<<25)
#define BSR_BIT (1<<26)
#define SHORTADDR_BIT (1<<27)
#define PACKSTRUCT_BIT (1<<28)
/* Nonzero if we should generate code using type 0 insns */
#define TARGET_SH0 (target_flags & SH0_BIT)
......@@ -141,11 +143,14 @@ extern int target_flags;
/* Nonzero if using Hitachi's calling convention */
#define TARGET_HITACHI (target_flags & HITACHI_BIT)
#define TARGET_PARANOID (target_flags & PARANOID_BIT)
#define TARGET_RETR2 (target_flags & RETR2_BIT)
#define TARGET_SHORTADDR (target_flags & SHORTADDR_BIT)
#define TARGET_BSR (target_flags & BSR_BIT)
/* Nonzero if packing structures as small as they'll go (incompatible with Hitachi's compiler) */
#define TARGET_PACKSTRUCT (target_flags & PACKSTRUCT_BIT)
#define TARGET_SWITCHES \
{ {"isize", ( ISIZE_BIT) }, \
......@@ -170,10 +175,11 @@ extern int target_flags;
{"r2", ( RETR2_BIT) }, \
{"shortaddr", ( SHORTADDR_BIT) }, \
{"bsr", ( BSR_BIT) }, \
{"packstruct",( PACKSTRUCT_BIT) }, \
{"", TARGET_DEFAULT} \
}
#define TARGET_DEFAULT (FAST_BIT)
#define TARGET_DEFAULT (FAST_BIT | BIGTABLE_BIT)
/* Macro to define table for command options with values. */
#define TARGET_OPTIONS \
......@@ -206,7 +212,7 @@ do { \
if (max_hi) \
max_count_hi = atoi (max_hi); \
else \
max_count_hi = 505; \
max_count_hi = 500; \
if (TARGET_BSR) \
flag_no_function_cse = 1; \
} while (0)
......@@ -264,9 +270,6 @@ do { \
/* The best alignment to use in cases where we have a choice. */
#define FASTEST_ALIGNMENT 32
/* Every structures size must be a multiple of 32 bits. */
#define STRUCTURE_SIZE_BOUNDARY 32
/* Make strings word-aligned so strcpy from constants will be faster. */
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
((TREE_CODE (EXP) == STRING_CST \
......@@ -279,6 +282,11 @@ do { \
&& TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
&& (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
/* Number of bits which any structure or union's size must be a
multiple of. Each structure or union's size is rounded up to a
multiple of this. */
#define STRUCTURE_SIZE_BOUNDARY (TARGET_PACKSTRUCT ? 8 : 32)
/* Set this nonzero if move instructions will actually fail to work
when given unaligned data. */
#define STRICT_ALIGNMENT 1
......@@ -305,9 +313,7 @@ do { \
The hardware registers are assigned numbers for the compiler
from 0 to just below FIRST_PSEUDO_REGISTER.
All registers that the compiler knows about must be given numbers,
even those that are not normally considered general registers.
*/
even those that are not normally considered general registers. */
#define AP_REG 16
#define PR_REG 17
......@@ -867,7 +873,7 @@ extern int current_function_anonymous_args;
/* Nonzero if the constant value X is a legitimate general operand. */
#define LEGITIMATE_CONSTANT_P(X) \
(GET_CODE(X) != CONST_DOUBLE && GET_CODE(X) != LABEL_REF)
(GET_CODE(X) != CONST_DOUBLE /*&& GET_CODE(X) != LABEL_REF*/)
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
......@@ -877,9 +883,9 @@ extern int current_function_anonymous_args;
them unless they have been allocated suitable hard regs.
The symbol REG_OK_STRICT causes the latter definition to be used. */
#define MODE_DISP_OK_4(X,MODE) ((GET_MODE_SIZE(MODE)==4) && ((unsigned)INTVAL(X)<64))
#define MODE_DISP_OK_8(X,MODE) ((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<60))
#define MODE_DISP_OK_2(X,MODE) ((GET_MODE_SIZE(MODE)==2) && ((unsigned)INTVAL(X)<32) && TARGET_TRYR0)
#define MODE_DISP_OK_4(X,MODE) ((GET_MODE_SIZE(MODE)==4) && ((unsigned)INTVAL(X)<64) && (!(INTVAL(X) &3)))
#define MODE_DISP_OK_8(X,MODE) ((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<60) && (!(INTVAL(X) &3)))
#define MODE_DISP_OK_2(X,MODE) ((GET_MODE_SIZE(MODE)==2) && ((unsigned)INTVAL(X)<32) && TARGET_TRYR0 && (!INTVAL(X) &1))
#define MODE_DISP_OK_1(X,MODE) ((GET_MODE_SIZE(MODE)==1) && ((unsigned)INTVAL(X)<16) && TARGET_TRYR0)
#ifndef REG_OK_STRICT
......@@ -896,7 +902,7 @@ extern int current_function_anonymous_args;
(REGNO (X) == 0 || REGNO(X) >= FIRST_PSEUDO_REGISTER)
#define REG_OK_FOR_PRE_POST_P(X) \
(REG_OK_FOR_INDEX_P (X))
(REG_OK_FOR_BASE_P (X))
#else
/* Nonzero if X is a hard reg that can be used as a base reg. */
......@@ -908,7 +914,7 @@ extern int current_function_anonymous_args;
REGNO_OK_FOR_INDEX_P (REGNO (X))
#define REG_OK_FOR_PRE_POST_P(X) \
(REGNO_OK_FOR_INDEX_P (REGNO (X)))
(REGNO_OK_FOR_BASE_P (REGNO (X)))
#endif
/* The Q is a pc relative load operand */
......@@ -1039,7 +1045,7 @@ extern int current_function_anonymous_args;
/* Define this if the tablejump instruction expects the table
to contain offsets from the address of the table.
Do not define this if the table should contain absolute addresses. */
#define CASE_VECTOR_PC_RELATIVE
/*#define CASE_VECTOR_PC_RELATIVE */
/* Specify the tree operation to be used to convert reals to integers. */
#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
......@@ -1053,6 +1059,9 @@ extern int current_function_anonymous_args;
/* The type of size_t unsigned int. */
#define SIZE_TYPE "unsigned int"
#define WCHAR_TYPE "short unsigned int"
#define WCHAR_TYPE_SIZE 16
/* Don't cse the address of the function being compiled. */
/*#define NO_RECURSIVE_FUNCTION_CSE 1*/
......@@ -1197,11 +1206,12 @@ extern int current_function_anonymous_args;
#define TEXT_SECTION_ASM_OP "\t.text"
#define DATA_SECTION_ASM_OP "\t.data"
#define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rdata\n"
#define CTORS_SECTION_ASM_OP "\t.section\t.ctors\n"
#define DTORS_SECTION_ASM_OP "\t.section\t.dtors\n"
#define INIT_SECTION_ASM_OP "\t.section\t.init\n"
#define EXTRA_SECTIONS in_ctors, in_dtors
#define EXTRA_SECTIONS in_ctors, in_dtors, in_rdata
#define READONLY_DATA_SECTION rdata_section
#define EXTRA_SECTION_FUNCTIONS \
void \
ctors_section() \
......@@ -1220,6 +1230,15 @@ dtors_section() \
fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \
in_section = in_dtors; \
} \
} \
void \
rdata_section() \
{ \
if (in_section != in_rdata) \
{ \
fprintf (asm_out_file, "%s\n", READONLY_DATA_SECTION_ASM_OP); \
in_section = in_rdata; \
} \
}
/* Assemble generic sections.
......@@ -1462,7 +1481,7 @@ extern char *output_far_jump();
#define TARGET_MEM_FUNCTIONS
#define HANDLE_PRAGMA(finput) handle_pragma (finput)
#define HANDLE_PRAGMA(finput) return handle_pragma (finput)
/* Set when processing a function with pragma interrupt turned on. */
......
......@@ -158,12 +158,15 @@
(cond [(eq_attr "type" "cbranch") (const_string "no")
(eq_attr "type" "jump") (const_string "no")
(eq_attr "type" "pload") (const_string "no")
(eq_attr "type" "pcloadsi") (const_string "no")
(eq_attr "type" "pcloadhi") (const_string "no")
(eq_attr "type" "return") (const_string "no")
(eq_attr "length" "2") (const_string "yes")
(eq_attr "length" "4,6,8,10,12") (const_string "no")
] (const_string "yes")))
;; -------------------------------------------------------------------------
;; SImode signed integer comparisons
;; -------------------------------------------------------------------------
......@@ -259,18 +262,21 @@
;; Addition instructions
;; -------------------------------------------------------------------------
(define_insn "addc"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
(plus:SI (reg:SI 18)
(plus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
(match_operand:SI 2 "arith_reg_operand" "r"))))
(set (reg:SI 18) (gt:SI (match_dup 1) (match_dup 0)))]
""
"addc %2,%0")
;; this should be a define split.
(define_insn "addc"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
(plus:SI (match_dup 0)
(plus:SI (match_operand:SI 1 "arith_reg_operand" "r")
(reg:SI 18))))
(clobber (reg:SI 18))]
""
"addc %1,%0")
(define_expand "adddi3"
[(set (match_operand:DI 0 "register_operand" "")
(plus:DI (match_operand:DI 1 "register_operand" "")
......@@ -278,17 +284,20 @@
""
"
{
rtx low_a = gen_rtx (SUBREG, SImode, operands[1], 1);
rtx low_b = gen_rtx (SUBREG, SImode, operands[2], 1);
rtx low_s = gen_rtx (SUBREG, SImode, operands[0], 1);
rtx low_a = operand_subword (operands[1], 1, 1, DImode);
rtx low_b = operand_subword (operands[2], 1, 1, DImode);
rtx low_s = operand_subword (operands[0], 1, 1, DImode);
rtx high_a = gen_rtx (SUBREG, SImode, operands[1], 0);
rtx high_b = gen_rtx (SUBREG, SImode, operands[2], 0);
rtx high_s = gen_rtx (SUBREG, SImode, operands[0], 0);
rtx high_a = operand_subword (operands[1], 0, 1, DImode);
rtx high_b = operand_subword (operands[2], 0, 1, DImode);
rtx high_s = operand_subword (operands[0], 0, 1, DImode);
emit_insn (gen_clrt ());
emit_insn (gen_addc (low_s, low_a, low_b));
emit_insn (gen_addc (high_s, high_a, high_b));
emit_move_insn (low_s, low_a);
emit_insn (gen_addc (low_s, low_b));
emit_move_insn (high_s, high_a);
emit_insn (gen_addc (high_s, high_b));
DONE;
}")
......@@ -314,16 +323,37 @@
;; Subtraction instructions
;; -------------------------------------------------------------------------
(define_insn "subdi3"
[(set (match_operand:DI 0 "arith_reg_operand" "=r")
(minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
(match_operand:DI 2 "arith_reg_operand" "r")))
(define_insn "subc"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
(minus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
(plus:SI (match_operand:SI 2 "arith_reg_operand" "r")
(reg:SI 18))))
(clobber (reg:SI 18))]
""
"clrt\;subc %R2,%R0\;subc %2,%0"
[(set_attr "length" "6")
(set_attr "in_delay_slot" "no")
(set_attr "type" "arith")])
"subc %2,%0")
(define_expand "subdi3"
[(set (match_operand:DI 0 "register_operand" "")
(plus:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "register_operand" "")))]
""
"
{
rtx low_a = operand_subword (operands[1], 1, 1, DImode);
rtx low_b = operand_subword (operands[2], 1, 1, DImode);
rtx low_s = operand_subword (operands[0], 1, 1, DImode);
rtx high_a = operand_subword (operands[1], 0, 1, DImode);
rtx high_b = operand_subword (operands[2], 0, 1, DImode);
rtx high_s = operand_subword (operands[0], 0, 1, DImode);
emit_insn (gen_clrt ());
emit_insn (gen_subc (low_s, low_a, low_b));
emit_insn (gen_subc (high_s, high_a, high_b));
DONE;
}")
(define_insn "subsi3"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
......@@ -504,14 +534,7 @@
(set (match_operand:SI 0 "arith_reg_operand" "=r")
(reg:SI 21))]
"TARGET_SH2"
"
{
if (!TARGET_SH2)
{
emit_insn (gen_mulsi3_call (operands[0], operands[1], operands[2]));
DONE;
}
}")
"")
(define_insn ""
[(set (reg:DI 20)
......@@ -769,7 +792,7 @@
(define_insn "ashldi3_k"
[(set (match_operand:DI 0 "arith_reg_operand" "=r")
(ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
(match_operand:DI 2 "immediate_operand" "I")))
(const_int 1)))
(clobber (reg:SI 18))]
""
"shll %R0\;rotcl %0"
......@@ -788,7 +811,7 @@
(define_insn "lshrdi3_k"
[(set (match_operand:DI 0 "arith_reg_operand" "=r")
(lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
(match_operand:DI 2 "immediate_operand" "I")))
(const_int 1)))
(clobber (reg:SI 18))]
""
"shlr %0\;rotcr %R0"
......@@ -806,7 +829,7 @@
(define_insn "ashrdi3_k"
[(set (match_operand:DI 0 "arith_reg_operand" "=r")
(ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
(match_operand:DI 2 "immediate_operand" "")))
(const_int 1)))
(clobber (reg:SI 18))]
""
"shar %0\;rotcr %R0"
......@@ -826,15 +849,35 @@
;; Unary arithmetic
;; -------------------------------------------------------------------------
(define_insn "negdi2"
[(set (match_operand:DI 0 "arith_reg_operand" "=&r")
(neg:DI (match_operand:DI 1 "arith_reg_operand" "0")))
(clobber (reg:SI 18))]
(define_insn "negc"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
(neg:SI (plus:SI (reg:SI 18) (match_operand:SI 1 "arith_reg_operand" "r"))))]
""
"clrt\;negc %R1,%R0\;negc %1,%0"
[(set_attr "length" "6")
"negc %1,%0"
[(set_attr "length" "2")
(set_attr "type" "arith")])
(define_expand "negdi2"
[(set (match_operand:DI 0 "arith_reg_operand" "=r")
(neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))
(clobber (reg:SI 18))]
""
"{
rtx low_src = operand_subword (operands[1], 1, 0, DImode);
rtx high_src = operand_subword (operands[1], 0, 0, DImode);
rtx low_dst = operand_subword (operands[0], 1, 1, DImode);
rtx high_dst = operand_subword (operands[0], 0, 1, DImode);
emit_insn (gen_clrt ());
emit_insn (gen_negc (low_dst, low_src));
emit_insn (gen_negc (high_dst, high_src));
DONE;
}
")
(define_insn "negsi2"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
(neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
......@@ -982,32 +1025,19 @@
[(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,r,<m,<,xl,xl,t,r")
(match_operand:SI 1 "general_movsrc_operand" "Q,rI,>m,xl,t,r,xl,r,>,r,i"))]
""
"*
{
switch (which_alternative)
{
case 0:
switch (get_attr_length(insn))
{
case 2:
return \"mov.l %1,%0\";
case 12:
return \"mov.l TA%*,%0\;bra TB%*\;mov.l @%0,%0\;.align 2\;TA%*: .long %1\;TB%*:%^\";
}
case 1: return \"mov %1,%0\";
case 2: return \"mov.l %1,%0\";
case 3: return \"sts %1,%0\";
case 4: return \"movt %0\";
case 5: return \"mov.l %1,%0\";
case 6: return \"sts.l %1,%0\";
case 7: return \"lds %1,%0\";
case 8: return \"lds.l %1,%0\";
case 9: return \"tst %1,%1\;bt T%*\;bra F%*\;sett\;T%*:clrt\;F%*:%^\";
case 10: return \"fake %1,%0\";
}
}"
[(set_attr "length" "*,2,2,2,2,2,2,2,2,6,2")
(set_attr "type" "pcloadsi,move,load,move,store,store,move,load,move,move,move")])
"@
mov.l %1,%0
mov %1,%0
mov.l %1,%0
sts %1,%0
movt %0
mov.l %1,%0
sts.l %1,%0
lds %1,%0
lds.l %1,%0
tst %1,%1\;bt T%*\;bra F%*\;sett\;T%*:clrt\;F%*:%^
fake %1,%0"
[(set_attr "type" "pcloadsi,move,load,move,store,store,move,load,move,move,move")])
(define_expand "movsi"
[(set (match_operand:SI 0 "general_movdst_operand" "")
......@@ -1042,27 +1072,15 @@
[(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,<m,r,r,l")
(match_operand:HI 1 "general_movsrc_operand" "Q,rI,>m,t,r,i,l,r"))]
""
"*
{
switch (which_alternative)
{
case 0:
switch (get_attr_length(insn))
{
case 2:
return \"mov.w %1,%0\";
case 12:
return \"mov.l TA%*,%0\;bra TB%*\;mov.w @%0,%0\;.align 2\;TA%*: .long %1\;TB%*:%^\";
}
case 1: return \"mov %1,%0\";
case 2: return \"mov.w %1,%0\";
case 3: return \"movt %0\";
case 4: return \"mov.w %1,%0\";
case 5: return \"fake %1,%0\";
case 6: return \"sts %1,%0\";
case 7: return \"lds %1,%0\";
}
}"
"@
mov.w %1,%0
mov %1,%0
mov.w %1,%0
movt %0
mov.w %1,%0
fake %1,%0
sts %1,%0
lds %1,%0"
[(set_attr "length" "*,2,2,2,2,2,2,2")
(set_attr "type" "pcloadhi,move,load,move,store,move,move,move")])
......@@ -1089,6 +1107,43 @@
[(set_attr "length" "*,4,4,4,4")
(set_attr "type" "pcloadsi,move,load,store,move")])
;; If the output is a register and the input is memory, we have to be careful
;; and see which word needs to be loaded first.
;;
(define_split
[(set (match_operand:DI 0 "general_movdst_operand" "")
(match_operand:DI 1 "general_movsrc_operand" ""))]
"! (GET_CODE (operands[0]) == REG
&& REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
&& ! (GET_CODE (operands[1]) == REG
&& REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
&& ! (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
&& ! reload_completed
&& reg_overlap_mentioned_p (operands[0], operands[1]))"
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 5))]
"
{ if (GET_CODE (operands[0]) != REG
|| ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
operands[1], 0))
{
operands[2] = operand_subword (operands[0], 0, 0, DImode);
operands[3] = operand_subword (operands[1], 0, 0, DImode);
operands[4] = operand_subword (operands[0], 1, 0, DImode);
operands[5] = operand_subword (operands[1], 1, 0, DImode);
}
else
{
operands[2] = operand_subword (operands[0], 1, 0, DImode);
operands[3] = operand_subword (operands[1], 1, 0, DImode);
operands[4] = operand_subword (operands[0], 0, 0, DImode);
operands[5] = operand_subword (operands[1], 0, 0, DImode);
}
if (operands[2] == 0 || operands[3] == 0
|| operands[4] == 0 || operands[5] == 0)
FAIL;
}")
(define_expand "movdi"
......@@ -1114,6 +1169,45 @@
[(set_attr "length" "4")
(set_attr "type" "move,load,store")])
;; If the output is a register and the input is memory, we have to be careful
;; and see which word needs to be loaded first.
;;
(define_split
[(set (match_operand:DF 0 "general_movdst_operand" "")
(match_operand:DF 1 "general_movsrc_operand" ""))]
"! (GET_CODE (operands[0]) == REG
&& REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
&& ! (GET_CODE (operands[1]) == REG
&& REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
&& ! (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
&& ! reload_completed
&& reg_overlap_mentioned_p (operands[0], operands[1]))"
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 5))]
"
{ if (GET_CODE (operands[0]) != REG
|| ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
operands[1], 0))
{
operands[2] = operand_subword (operands[0], 0, 0, DFmode);
operands[3] = operand_subword (operands[1], 0, 0, DFmode);
operands[4] = operand_subword (operands[0], 1, 0, DFmode);
operands[5] = operand_subword (operands[1], 1, 0, DFmode);
}
else
{
operands[2] = operand_subword (operands[0], 1, 0, DFmode);
operands[3] = operand_subword (operands[1], 1, 0, DFmode);
operands[4] = operand_subword (operands[0], 0, 0, DFmode);
operands[5] = operand_subword (operands[1], 0, 0, DFmode);
}
if (operands[2] == 0 || operands[3] == 0
|| operands[4] == 0 || operands[5] == 0)
FAIL;
}")
(define_expand "movdf"
[(set (match_operand:DF 0 "general_movdst_operand" "")
(match_operand:DF 1 "general_movsrc_operand" ""))]
......@@ -1443,12 +1537,15 @@
(const_int 1))
(label_ref (match_operand 4 "" ""))
(pc)))
(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 5)))
(parallel[(set (match_dup 5) (ashift:SI (match_dup 5) (const_int 2)))
(clobber (reg:SI 18))])
(set (reg:SI 0) (label_ref (match_operand 3 "" "")))
(parallel[(set (reg:SI 0) (plus:SI (reg:SI 0)
(mem:HI (plus:SI (reg:SI 0)
(match_dup 6)))))
(set (match_dup 6) (mem:HI (plus:SI (reg:SI 0) (match_dup 6))))])
(set (reg:SI 0) (mem:SI (plus:SI (reg:SI 0) (match_dup 5))))
;; (parallel[(set (reg:SI 0) (plus:SI (reg:SI 0)
;; (mem:HI (plus:SI (reg:SI 0)
;; (match_dup 5)))))
;; (set (match_dup 6) (mem:HI (plus:SI (reg:SI 0) (match_dup 6))))])
(set (pc) (reg:SI 0))]
""
"
......@@ -1456,7 +1553,7 @@
operands[1] = copy_to_mode_reg (SImode, operands[1]);
operands[2] = copy_to_mode_reg (SImode, operands[2]);
operands[5] = gen_reg_rtx (SImode);
operands[6] = gen_reg_rtx (SImode);
}")
(define_insn "casesi_worker"
......@@ -1470,7 +1567,7 @@
"mov.w @(r0,%0),%0\;add %0,r0"
[(set_attr "needs_delay_slot" "no")
(set_attr "in_delay_slot" "no")
(set_attr "length" "6")])
(set_attr "length" "4")])
(define_insn "return"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment