Commit 00f8ff66 by Steve Chamberlain

*** empty log message ***

From-SVN: r8563
parent 43d826d9
...@@ -38,6 +38,10 @@ ...@@ -38,6 +38,10 @@
#include "obstack.h" #include "obstack.h"
#include "expr.h" #include "expr.h"
#define MSW (TARGET_LITTLE_ENDIAN ? 1 : 0)
#define LSW (TARGET_LITTLE_ENDIAN ? 0 : 1)
static rtx add_constant (); static rtx add_constant ();
int pragma_interrupt; int pragma_interrupt;
...@@ -52,6 +56,12 @@ static rtx shiftsyms[32]; ...@@ -52,6 +56,12 @@ static rtx shiftsyms[32];
struct rtx_def *table_lab; struct rtx_def *table_lab;
enum attr_cpu sh_cpu; /* target cpu */ enum attr_cpu sh_cpu; /* target cpu */
char *max_si;
char *max_hi;
int max_count_si;
int max_count_hi;
/* Global variables for machine-dependent things. */ /* Global variables for machine-dependent things. */
/* Saved operands from the last compare to use when we generate an scc /* Saved operands from the last compare to use when we generate an scc
...@@ -338,8 +348,9 @@ print_operand_address (stream, x) ...@@ -338,8 +348,9 @@ print_operand_address (stream, x)
'!' dump the constant table '!' dump the constant table
'#' output a nop if there is nothing to put in the delay slot '#' output a nop if there is nothing to put in the delay slot
'@' print rte or rts depending upon pragma interruptness '@' print rte or rts depending upon pragma interruptness
'R' print the next register or memory location along, ie the lsw in 'R' print the LSW of a dp value - changes if in little endian
a double word value 'T' print the next word of a dp value - same as 'R' in big endian mode.
'S' print the MSW of a dp value - changes if in little endian
'O' print a constant without the # 'O' print a constant without the #
'M' print a constant as its negative 'M' print a constant as its negative
'N' print insides of a @++ or @-- o */ 'N' print insides of a @++ or @-- o */
...@@ -385,14 +396,38 @@ print_operand (stream, x, code) ...@@ -385,14 +396,38 @@ print_operand (stream, x, code)
fputs (reg_names[REGNO (XEXP (XEXP (x, 0), 0))], (stream)); fputs (reg_names[REGNO (XEXP (XEXP (x, 0), 0))], (stream));
break; break;
case 'R': case 'R':
/* Next location along in memory or register */ /* LSW of a double */
switch (GET_CODE (x))
{
case REG:
fputs (reg_names[REGNO (x) + LSW], (stream));
break;
case MEM:
print_operand_address (stream, XEXP (adj_offsettable_operand (x, LSW *4), 0));
break;
}
break;
case 'T':
/* Next word of a double */
switch (GET_CODE (x)) switch (GET_CODE (x))
{ {
case REG: case REG:
fputs (reg_names[REGNO (x) + 1], (stream)); fputs (reg_names[REGNO (x) + 1], (stream));
break; break;
case MEM: case MEM:
print_operand_address (stream, XEXP (adj_offsettable_operand (x, 4), 0)); print_operand_address (stream, XEXP (adj_offsettable_operand (x,1 *4), 0));
break;
}
break;
case 'S':
/* MSW of a double */
switch (GET_CODE (x))
{
case REG:
fputs (reg_names[REGNO (x) + MSW], (stream));
break;
case MEM:
print_operand_address (stream, XEXP (adj_offsettable_operand (x, MSW *4), 0));
break; break;
} }
break; break;
...@@ -829,13 +864,13 @@ output_movedouble (insn, operands, mode) ...@@ -829,13 +864,13 @@ output_movedouble (insn, operands, mode)
&& GET_CODE (XEXP (dst, 0)) == POST_INC) && GET_CODE (XEXP (dst, 0)) == POST_INC)
{ {
operands[0] = XEXP (XEXP (dst, 0), 0); operands[0] = XEXP (XEXP (dst, 0), 0);
return "mov.l %R1,@(4,%0)\n\tmov.l %1,@%0\n\tadd #8,%0"; return "mov.l %T1,@(4,%0)\n\tmov.l %1,@%0\n\tadd #8,%0";
} }
if (register_operand (dst, mode) if (register_operand (dst, mode)
&& register_operand (src, mode)) && register_operand (src, mode))
{ {
if (REGNO (src) == MACH_REG) if (REGNO (src) == MACH_REG)
return "sts mach,%0\n\tsts macl,%R0"; return "sts mach,%S0\n\tsts macl,%R0";
/* /*
when mov.d r1,r2 do r2->r3 then r1->r2 when mov.d r1,r2 do r2->r3 then r1->r2
...@@ -843,24 +878,26 @@ output_movedouble (insn, operands, mode) ...@@ -843,24 +878,26 @@ output_movedouble (insn, operands, mode)
*/ */
if (REGNO (src) + 1 == REGNO (dst)) if (REGNO (src) + 1 == REGNO (dst))
return "mov %R1,%R0\n\tmov %1,%0 ! cra"; return "mov %T1,%T0\n\tmov %1,%0 ! cra";
else else
return "mov %1,%0\n\tmov %R1,%R0 ! crb"; return "mov %1,%0\n\tmov %T1,%T0 ! crb";
} }
else if (GET_CODE (src) == CONST_INT) else if (GET_CODE (src) == CONST_INT)
{ {
HOST_WIDE_INT val = INTVAL (src); HOST_WIDE_INT val = INTVAL (src);
int rn = REGNO (operands[0]); int rn = REGNO (operands[0]);
int msw = rn + MSW;
int lsw = rn + LSW;
if (val < 0) if (val < 0)
{ {
fprintf (asm_out_file, "\tmov #-1,r%d\n", rn); fprintf (asm_out_file, "\tmov #-1,r%d\n", msw);
} }
else else
{ {
fprintf (asm_out_file, "\tmov #0,r%d\n", rn); fprintf (asm_out_file, "\tmov #0,r%d\n", msw);
} }
fprintf (asm_out_file, "\tmov #%d,r%d\n", val, rn + 1); fprintf (asm_out_file, "\tmov #%d,r%d\n", val, lsw);
return ""; return "";
} }
else if (GET_CODE (src) == MEM) else if (GET_CODE (src) == MEM)
...@@ -885,11 +922,11 @@ output_movedouble (insn, operands, mode) ...@@ -885,11 +922,11 @@ output_movedouble (insn, operands, mode)
} }
else if (GET_CODE (inside) == LABEL_REF) else if (GET_CODE (inside) == LABEL_REF)
{ {
return "mov.l %1,%0\n\tmov.l %1+4,%R0"; return "mov.l %1,%0\n\tmov.l %1+4,%T0";
} }
else if (GET_CODE (inside) == POST_INC) else if (GET_CODE (inside) == POST_INC)
{ {
return "mov.l %1,%0\n\tmov.l %1,%R0 !mdi\n"; return "mov.l %1,%0\n\tmov.l %1,%T0 !mdi\n";
} }
else else
abort (); abort ();
...@@ -936,11 +973,11 @@ output_movedouble (insn, operands, mode) ...@@ -936,11 +973,11 @@ output_movedouble (insn, operands, mode)
if (dreg == ptrreg1) if (dreg == ptrreg1)
{ {
/* Copy into the second half first */ /* Copy into the second half first */
return "mov.l %R1,%R0\n\tmov.l %1,%0 ! cr"; return "mov.l %T1,%T0\n\tmov.l %1,%0 ! cr";
} }
} }
return "mov.l %1,%0\n\tmov.l %R1,%R0"; return "mov.l %1,%0\n\tmov.l %T1,%T0";
} }
/* Emit assembly to shift reg by k bits */ /* Emit assembly to shift reg by k bits */
...@@ -1372,6 +1409,9 @@ output_options (file, f_options, f_len, W_options, W_len, ...@@ -1372,6 +1409,9 @@ output_options (file, f_options, f_len, W_options, W_len,
fprintf (file, term); fprintf (file, term);
fprintf (file, "! %d %d\n", max_count_si, max_count_hi); fprintf (file, "! %d %d\n", max_count_si, max_count_hi);
if (TARGET_LITTLE_ENDIAN)
fprintf (file, "\t.little\n");
} }
void void
...@@ -1390,12 +1430,36 @@ output_file_start (file, f_options, f_len, W_options, W_len) ...@@ -1390,12 +1430,36 @@ output_file_start (file, f_options, f_len, W_options, W_len)
data_section (); data_section ();
pos = fprintf (file, "\n! Hitachi SH cc1 (%s) (release I-1) arguments:", version_string); pos = fprintf (file, "\n! Hitachi SH cc1 (%s) arguments:", version_string);
output_options (file, f_options, f_len, W_options, W_len, output_options (file, f_options, f_len, W_options, W_len,
pos, 75, " ", "\n! ", "\n\n"); pos, 75, " ", "\n! ", "\n\n");
} }
/* Actual number of instructions used to make a shift by N */
char ashiftrt_insns[] = { 0,1,2,3,4,5,8,8,8,8,8,8,8,8,8,8,2,3,4,5,8,8,8,8,8,8,8,8,8,8,8,2};
char lshiftrt_insns[] = { 0,1,1,2,2,3,3,4,1,2,2,3,3,4,4,5,1,2,2,3,3,4,4,5,2,3,3,4,4,5,5,6};
char shift_insns[] = { 0,1,1,2,2,3,3,4,1,2,2,3,3,4,4,5,1,2,2,3,3,4,4,5,2,3,3,4,4,5,5,6};
int
shiftinsns (shift, n)
enum rtx_code shift;
int n;
{
switch (shift)
{
case ASHIFTRT:
return ashiftrt_insns[n];
case LSHIFTRT:
return lshiftrt_insns[n];
case ASHIFT:
return shift_insns[n];
default:
abort();
}
}
/* Return the cost of a shift */ /* Return the cost of a shift */
...@@ -1404,14 +1468,16 @@ shiftcosts (RTX) ...@@ -1404,14 +1468,16 @@ shiftcosts (RTX)
rtx RTX; rtx RTX;
{ {
/* If shift by a non constant, then this will be expensive. */ /* If shift by a non constant, then this will be expensive. */
if (GET_CODE (XEXP (RTX, 1)) != CONST_INT) if (GET_CODE (XEXP (RTX, 1)) != CONST_INT)
return 20; {
return 20;
}
/* otherwise, it will be very cheap if by one of the constants /* otherwise, it will be very cheap if by one of the constants
we can cope with. */ we can cope with. */
if (CONST_OK_FOR_K (INTVAL (XEXP (RTX, 1)))) if (CONST_OK_FOR_K (INTVAL (XEXP (RTX, 1))))
return 1; return 1;
/* otherwise it will be several insns, but we pretend that it will be more than /* otherwise it will be several insns, but we pretend that it will be more than
just the components, so that combine doesn't glue together a load of shifts into just the components, so that combine doesn't glue together a load of shifts into
one shift which has to be emitted as a bunch anyway - breaking scheduling */ one shift which has to be emitted as a bunch anyway - breaking scheduling */
...@@ -1541,10 +1607,12 @@ gen_shifty_op (code, operands) ...@@ -1541,10 +1607,12 @@ gen_shifty_op (code, operands)
rtx wrk = gen_reg_rtx (SImode); rtx wrk = gen_reg_rtx (SImode);
rtx t; rtx t;
char *func; char *func;
if (GET_CODE (operands[2]) == CONST_INT) if (GET_CODE (operands[2]) == CONST_INT)
{ {
int value = INTVAL (operands[2]); int value = INTVAL (operands[2]);
top: top:
switch (code) switch (code)
{ {
case ASHIFTRT: case ASHIFTRT:
...@@ -1554,7 +1622,20 @@ gen_shifty_op (code, operands) ...@@ -1554,7 +1622,20 @@ gen_shifty_op (code, operands)
value = -value; value = -value;
goto top; goto top;
} }
if (value == 31)
{
emit_insn (gen_ashrsi2_31 (operands[0], operands[1]));
return 1;
}
else if (value >= 16 && value <= 19)
{
emit_insn (gen_ashrsi2_16 (wrk, operands[1]));
value -= 16;
while (value --)
gen_ashift (ASHIFTRT,1, wrk);
emit_move_insn (operands[0], wrk);
return 1;
}
/* Expand a short sequence inline, longer call a magic routine */ /* Expand a short sequence inline, longer call a magic routine */
if (value <= 5) if (value <= 5)
{ {
...@@ -1626,6 +1707,7 @@ gen_shifty_op (code, operands) ...@@ -1626,6 +1707,7 @@ gen_shifty_op (code, operands)
} }
} }
return 0; return 0;
} }
...@@ -2413,6 +2495,17 @@ arith_operand (op, mode) ...@@ -2413,6 +2495,17 @@ arith_operand (op, mode)
} }
/* Returns 1 if OP is a valid count operand for a shift operation. */
int
shiftby_operand (op, mode)
rtx op;
enum machine_mode mode;
{
if (immediate_operand (op, mode))
return 1;
return 0;
}
/* Returns 1 if OP is a valid source operand for a logical operation. */ /* Returns 1 if OP is a valid source operand for a logical operation. */
int int
...@@ -2515,6 +2608,8 @@ sh_function_arg_partial_nregs (CUM, MODE, TYPE, NAMED) ...@@ -2515,6 +2608,8 @@ sh_function_arg_partial_nregs (CUM, MODE, TYPE, NAMED)
return 0; return 0;
} }
/* Turn this on to recognise shift insns which aren't supported in the /* Turn this on to recognise shift insns which aren't supported in the
hardware. This will allow the combiner to notice more patterns, hardware. This will allow the combiner to notice more patterns,
but the down side is that the asm outputter will have to emit but the down side is that the asm outputter will have to emit
...@@ -2525,3 +2620,4 @@ int fake_shift() ...@@ -2525,3 +2620,4 @@ int fake_shift()
{ {
return 0; return 0;
} }
...@@ -41,8 +41,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ...@@ -41,8 +41,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define SDB_DELIM ";" #define SDB_DELIM ";"
#define CPP_SPEC "%{ml:-D__LITTLE_ENDIAN__}"
#define CPP_PREDEFINES "-D__sh__ -Acpu(sh) -Amachine(sh)" #define CPP_PREDEFINES "-D__sh__ -Acpu(sh) -Amachine(sh)"
#define ASM_SPEC "%{ml:-little}"
#define LINK_SPEC "%{ml:-m shl}"
/* Show we can debug even without a frame pointer. */ /* Show we can debug even without a frame pointer. */
#define CAN_DEBUG_WITHOUT_FP #define CAN_DEBUG_WITHOUT_FP
...@@ -93,6 +99,7 @@ extern int target_flags; ...@@ -93,6 +99,7 @@ extern int target_flags;
#define BSR_BIT (1<<26) #define BSR_BIT (1<<26)
#define SHORTADDR_BIT (1<<27) #define SHORTADDR_BIT (1<<27)
#define PACKSTRUCT_BIT (1<<28) #define PACKSTRUCT_BIT (1<<28)
#define LITTLE_ENDIAN_BIT (1<<29)
/* Nonzero if we should generate code using type 0 insns */ /* Nonzero if we should generate code using type 0 insns */
#define TARGET_SH0 (target_flags & SH0_BIT) #define TARGET_SH0 (target_flags & SH0_BIT)
...@@ -160,40 +167,49 @@ extern int target_flags; ...@@ -160,40 +167,49 @@ extern int target_flags;
/* Nonzero if packing structures as small as they'll go (incompatible with Hitachi's compiler) */ /* Nonzero if packing structures as small as they'll go (incompatible with Hitachi's compiler) */
#define TARGET_PACKSTRUCT (target_flags & PACKSTRUCT_BIT) #define TARGET_PACKSTRUCT (target_flags & PACKSTRUCT_BIT)
#define TARGET_SWITCHES \
{ {"isize", ( ISIZE_BIT) }, \ #define TARGET_LITTLE_ENDIAN (target_flags & LITTLE_ENDIAN_BIT)
{"space", ( SPACE_BIT) }, \
{"0", ( SH0_BIT) }, \ #define TARGET_SWITCHES \
{"1", ( SH1_BIT) }, \ { {"0", (SH0_BIT) }, \
{"2", ( SH2_BIT) }, \ {"1", (SH1_BIT) }, \
{"3", ( SH3_BIT) }, \ {"2", (SH2_BIT) }, \
{"ac", ( MAC_BIT) }, \ {"3", (SH3_BIT) }, \
{"dalign", ( DALIGN_BIT) }, \ {"3l", (SH3_BIT|LITTLE_ENDIAN_BIT)}, \
{"c", ( C_BIT) }, \ {"R", (R_BIT) }, \
{"r", ( RTL_BIT) }, \ {"ac", (MAC_BIT) }, \
{"bigtable", ( BIGTABLE_BIT)}, \ {"b", (-LITTLE_ENDIAN_BIT) }, \
{"try-r0", ( TRYR0_BIT)}, \ {"bigtable", (BIGTABLE_BIT)}, \
{"R", ( R_BIT) }, \ {"bsr", (BSR_BIT) }, \
{"nosave", ( NOSAVE_BIT) }, \ {"c", (C_BIT) }, \
{"clen3", ( CONSTLEN_3_BIT) }, \ {"clen0", (CONSTLEN_0_BIT) }, \
{"clen0", ( CONSTLEN_0_BIT) }, \ {"clen3", (CONSTLEN_3_BIT) }, \
{"smallcall", ( SMALLCALL_BIT) }, \ {"dalign", (DALIGN_BIT) }, \
{"hitachi", ( HITACHI_BIT) }, \ {"hitachi", (HITACHI_BIT) }, \
{"paranoid", ( PARANOID_BIT) }, \ {"isize", (ISIZE_BIT) }, \
{"r2", ( RETR2_BIT) }, \ {"l", (LITTLE_ENDIAN_BIT) }, \
{"shortaddr", ( SHORTADDR_BIT) }, \ {"nosave", (NOSAVE_BIT) }, \
{"bsr", ( BSR_BIT) }, \ {"packstruct",(PACKSTRUCT_BIT) }, \
{"packstruct",( PACKSTRUCT_BIT) }, \ {"paranoid", (PARANOID_BIT) }, \
{"", TARGET_DEFAULT} \ {"r", (RTL_BIT) }, \
{"r2", (RETR2_BIT) }, \
{"shortaddr", (SHORTADDR_BIT) }, \
{"smallcall", (SMALLCALL_BIT) }, \
{"space", (SPACE_BIT) }, \
{"try-r0", (TRYR0_BIT)}, \
{"", TARGET_DEFAULT} \
} }
#define TARGET_DEFAULT (FAST_BIT) #define TARGET_DEFAULT (FAST_BIT)
/* Macro to define table for command options with values. */ /* Macro to define table for command options with values. */
#define TARGET_OPTIONS \ #define TARGET_OPTIONS \
{ { "maxsi-", &max_si}, \ { { "maxsi-", &max_si}, \
{ "maxhi-", &max_hi} } { "maxhi-", &max_hi} }
#define OVERRIDE_OPTIONS \ #define OVERRIDE_OPTIONS \
do { \ do { \
sh_cpu = CPU_SH0; \ sh_cpu = CPU_SH0; \
...@@ -201,8 +217,8 @@ do { \ ...@@ -201,8 +217,8 @@ do { \
sh_cpu = CPU_SH1; \ sh_cpu = CPU_SH1; \
if (TARGET_SH2) \ if (TARGET_SH2) \
sh_cpu = CPU_SH2; \ sh_cpu = CPU_SH2; \
if (TARGET_SH3) \ if (TARGET_SH3) \
sh_cpu = CPU_SH3; \ sh_cpu = CPU_SH3|CPU_SH2; \
\ \
/* We *MUST* always define optimize since we *HAVE* to run \ /* We *MUST* always define optimize since we *HAVE* to run \
shorten branches to get correct code. */ \ shorten branches to get correct code. */ \
...@@ -234,14 +250,25 @@ do { \ ...@@ -234,14 +250,25 @@ do { \
/* Define this if most significant bit is lowest numbered /* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields. */ in instructions that operate on numbered bit-fields. */
#define BITS_BIG_ENDIAN 0 #define BITS_BIG_ENDIAN 0
/* Define this if most significant byte of a word is the lowest numbered. */ /* Define this if most significant byte of a word is the lowest numbered. */
#define BYTES_BIG_ENDIAN 1 #define BYTES_BIG_ENDIAN (TARGET_LITTLE_ENDIAN == 0)
/* Define this if most significant word of a multiword number is the lowest /* Define this if most significant word of a multiword number is the lowest
numbered. */ numbered. */
#define WORDS_BIG_ENDIAN 1 #define WORDS_BIG_ENDIAN (TARGET_LITTLE_ENDIAN == 0)
/* Define this to set the endianness to use in libgcc2.c, which can
not depend on target_flags. */
#if defined(__LITTLE_ENDIAN__)
#define LIBGCC2_WORDS_BIG_ENDIAN 0
#else
#define LIBGCC2_WORDS_BIG_ENDIAN 1
#endif
/* Number of bits in an addressable storage unit */ /* Number of bits in an addressable storage unit */
#define BITS_PER_UNIT 8 #define BITS_PER_UNIT 8
...@@ -1156,7 +1183,7 @@ extern int current_function_anonymous_args; ...@@ -1156,7 +1183,7 @@ extern int current_function_anonymous_args;
case UDIV: \ case UDIV: \
case MOD: \ case MOD: \
case UMOD: \ case UMOD: \
return COSTS_N_INSNS (100); \ return COSTS_N_INSNS (20); \
case FLOAT: \ case FLOAT: \
case FIX: \ case FIX: \
return 100; return 100;
...@@ -1492,7 +1519,7 @@ extern char *output_far_jump(); ...@@ -1492,7 +1519,7 @@ extern char *output_far_jump();
extern int pragma_interrupt; extern int pragma_interrupt;
#define MOVE_RATIO (TARGET_SMALLCODE ? 4 : 16) #define MOVE_RATIO (TARGET_SMALLCODE ? 4 : 16)
char *max_si; extern char *max_si;
char *max_hi; extern char *max_hi;
int max_count_si; extern int max_count_si;
int max_count_hi; extern int max_count_hi;
...@@ -33,8 +33,8 @@ ...@@ -33,8 +33,8 @@
;; %* -- print a local label ;; %* -- print a local label
;; %^ -- increment the local label number ;; %^ -- increment the local label number
;; %# -- output a nop if there is nothing to put in the delay slot ;; %# -- output a nop if there is nothing to put in the delay slot
;; %R -- print the next register or memory location along, ie the lsw in ;; %R -- print the lsw arg of a double,
;; a double word value ;; %S -- print the msw arg of a double
;; %O -- print a constant without the # ;; %O -- print a constant without the #
;; %M -- print a constant as its negative ;; %M -- print a constant as its negative
;; ;;
...@@ -128,9 +128,9 @@ ...@@ -128,9 +128,9 @@
;; (define_function_unit {name} {num-units} {n-users} {test} ;; (define_function_unit {name} {num-units} {n-users} {test}
;; {ready-delay} {issue-delay} [{conflict-list}]) ;; {ready-delay} {issue-delay} [{conflict-list}])
(define_function_unit "memory" 1 0 (eq_attr "type" "load,pcloadsi,pcloadhi") 2 0) (define_function_unit "memory" 1 0 (eq_attr "type" "load,pcloadsi,pcloadhi") 2 2)
(define_function_unit "mpy" 1 0 (eq_attr "type" "smpy") 3 0) (define_function_unit "mpy" 1 0 (eq_attr "type" "smpy") 7 7)
(define_function_unit "mpy" 1 0 (eq_attr "type" "dmpy") 5 0) (define_function_unit "mpy" 1 0 (eq_attr "type" "dmpy") 9 9)
(define_attr "needs_delay_slot" "yes,no" (define_attr "needs_delay_slot" "yes,no"
(cond [(eq_attr "type" "jump") (const_string "yes") (cond [(eq_attr "type" "jump") (const_string "yes")
...@@ -151,7 +151,7 @@ ...@@ -151,7 +151,7 @@
(define_delay (define_delay
(and (eq_attr "type" "cbranch") (and (eq_attr "type" "cbranch")
(eq_attr "cpu" "sh2")) (eq_attr "cpu" "sh2,sh3"))
[(eq_attr "in_delay_slot" "yes") (nil) (nil)]) [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
(define_attr "in_delay_slot" "maybe,yes,no" (define_attr "in_delay_slot" "maybe,yes,no"
...@@ -270,7 +270,7 @@ ...@@ -270,7 +270,7 @@
(match_operand:DI 2 "register_operand" "r"))) (match_operand:DI 2 "register_operand" "r")))
(clobber (reg:SI 18))] (clobber (reg:SI 18))]
"" ""
"clrt\;addc %R2,%R0\;addc %2,%0" "clrt\;addc %R2,%R0\;addc %S2,%S0"
[(set_attr "length" "6")]) [(set_attr "length" "6")])
...@@ -302,7 +302,7 @@ ...@@ -302,7 +302,7 @@
(match_operand:DI 2 "register_operand" "r"))) (match_operand:DI 2 "register_operand" "r")))
(clobber (reg:SI 18))] (clobber (reg:SI 18))]
"" ""
"clrt\;subc %R2,%R0\;subc %2,%0" "clrt\;subc %R2,%R0\;subc %S2,%S0"
[(set_attr "length" "6")]) [(set_attr "length" "6")])
(define_insn "subsi3" (define_insn "subsi3"
...@@ -488,11 +488,12 @@ ...@@ -488,11 +488,12 @@
"TARGET_SH2" "TARGET_SH2"
"") "")
(define_insn "" (define_insn ""
[(set (reg:DI 20) [(set (reg:DI 20)
(mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")) (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
(sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))] (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
"TARGET_SH2" "(TARGET_SH2) && 0"
"dmuls.l %2,%1" "dmuls.l %2,%1"
[(set_attr "type" "dmpy")]) [(set_attr "type" "dmpy")])
...@@ -502,14 +503,14 @@ ...@@ -502,14 +503,14 @@
(sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r")))) (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
(set (match_operand:DI 0 "arith_reg_operand" "=r") (set (match_operand:DI 0 "arith_reg_operand" "=r")
(reg:DI 20))] (reg:DI 20))]
"TARGET_SH2" "(TARGET_SH2) && 0"
"") "")
(define_insn "" (define_insn ""
[(set (reg:DI 20) [(set (reg:DI 20)
(mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")) (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
(zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))] (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
"TARGET_SH2" "(TARGET_SH2) && 0"
"dmulu.l %2,%1" "dmulu.l %2,%1"
[(set_attr "type" "dmpy")]) [(set_attr "type" "dmpy")])
...@@ -519,7 +520,7 @@ ...@@ -519,7 +520,7 @@
(zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r")))) (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
(set (match_operand:DI 0 "arith_reg_operand" "=r") (set (match_operand:DI 0 "arith_reg_operand" "=r")
(reg:DI 20))] (reg:DI 20))]
"TARGET_SH2" "(TARGET_SH2) && 0"
"") "")
...@@ -614,6 +615,8 @@ ...@@ -614,6 +615,8 @@
;; ;;
;; shift left ;; shift left
(define_insn "ashlsi3_k" (define_insn "ashlsi3_k"
[(set (match_operand:SI 0 "arith_reg_operand" "=r,r") [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
(ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0") (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0")
...@@ -643,7 +646,7 @@ ...@@ -643,7 +646,7 @@
(define_expand "ashlsi3" (define_expand "ashlsi3"
[(parallel[(set (match_operand:SI 0 "arith_reg_operand" "") [(parallel[(set (match_operand:SI 0 "arith_reg_operand" "")
(ashift:SI (match_operand:SI 1 "arith_reg_operand" "") (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
(match_operand:SI 2 "immediate_operand" ""))) (match_operand:SI 2 "shiftby_operand" "")))
(clobber (reg:SI 18))])] (clobber (reg:SI 18))])]
"" ""
"if (gen_shifty_op (ASHIFT, operands)) DONE; else FAIL;") "if (gen_shifty_op (ASHIFT, operands)) DONE; else FAIL;")
...@@ -661,15 +664,6 @@ ...@@ -661,15 +664,6 @@
"shar %0" "shar %0"
[(set_attr "type" "arith")]) [(set_attr "type" "arith")])
(define_insn "ashrsi3_16"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
(ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
(match_operand:SI 2 "immediate_operand" "i")))
(clobber (reg:SI 18))]
"INTVAL(operands[2]) == 16"
"shlr16 %0\;exts.w %0,%0"
[(set_attr "type" "arith")
(set_attr "length" "4")])
; an arithmetic shift right by 16 is better as a logical shift and a ; an arithmetic shift right by 16 is better as a logical shift and a
; sign extend ; sign extend
...@@ -685,6 +679,25 @@ ...@@ -685,6 +679,25 @@
; (set (match_dup 0) (sign_extend:SI (subreg:HI (match_dup 3) 0)))] ; (set (match_dup 0) (sign_extend:SI (subreg:HI (match_dup 3) 0)))]
; "operands[3] = gen_reg_rtx (SImode);") ; "operands[3] = gen_reg_rtx (SImode);")
(define_insn "ashrsi2_16"
[(set (match_operand:SI 0 "register_operand" "=r")
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
(const_int 16)))
(clobber (reg:SI 18))]
""
"shlr16 %0\;exts.w %0,%0"
[(set_attr "length" "4")])
(define_insn "ashrsi2_31"
[(set (match_operand:SI 0 "register_operand" "=r")
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
(const_int 31)))]
""
"shal %0\;subc %0,%0"
[(set_attr "length" "4")])
(define_insn "ashrsi3_n" (define_insn "ashrsi3_n"
[(set (reg:SI 4) [(set (reg:SI 4)
(ashiftrt:SI (reg:SI 4) (ashiftrt:SI (reg:SI 4)
...@@ -710,6 +723,7 @@ ...@@ -710,6 +723,7 @@
; logical shift right ; logical shift right
; ;
(define_insn "lshrsi3_k" (define_insn "lshrsi3_k"
[(set (match_operand:SI 0 "arith_reg_operand" "=r,r") [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
(lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0,0") (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0,0")
...@@ -736,7 +750,7 @@ ...@@ -736,7 +750,7 @@
(define_expand "lshrsi3" (define_expand "lshrsi3"
[(parallel[(set (match_operand:SI 0 "arith_reg_operand" "") [(parallel[(set (match_operand:SI 0 "arith_reg_operand" "")
(lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "") (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
(match_operand:SI 2 "immediate_operand" ""))) (match_operand:SI 2 "shiftby_operand" "")))
(clobber (reg:SI 18))])] (clobber (reg:SI 18))])]
"" ""
"if (gen_shifty_op (LSHIFTRT, operands)) DONE; else FAIL;") "if (gen_shifty_op (LSHIFTRT, operands)) DONE; else FAIL;")
...@@ -747,7 +761,7 @@ ...@@ -747,7 +761,7 @@
(const_int 1))) (const_int 1)))
(clobber (reg:SI 18))] (clobber (reg:SI 18))]
"" ""
"shll %R0\;rotcl %0" "shll %R0\;rotcl %S0"
[(set_attr "length" "4")]) [(set_attr "length" "4")])
(define_expand "ashldi3" (define_expand "ashldi3"
...@@ -766,7 +780,7 @@ ...@@ -766,7 +780,7 @@
(const_int 1))) (const_int 1)))
(clobber (reg:SI 18))] (clobber (reg:SI 18))]
"" ""
"shlr %0\;rotcr %R0" "shlr %S0\;rotcr %R0"
[(set_attr "length" "4")]) [(set_attr "length" "4")])
(define_expand "lshrdi3" (define_expand "lshrdi3"
...@@ -784,7 +798,7 @@ ...@@ -784,7 +798,7 @@
(const_int 1))) (const_int 1)))
(clobber (reg:SI 18))] (clobber (reg:SI 18))]
"" ""
"shar %0\;rotcr %R0" "shar %S0\;rotcr %R0"
[(set_attr "length" "4")]) [(set_attr "length" "4")])
(define_expand "ashrdi3" (define_expand "ashrdi3"
...@@ -876,18 +890,16 @@ ...@@ -876,18 +890,16 @@
;; ------------------------------------------------------------------------- ;; -------------------------------------------------------------------------
(define_insn "extendsidi2" (define_insn "extendsidi2"
[(set (match_operand:DI 0 "arith_reg_operand" "=r,r") [(set (match_operand:DI 0 "arith_reg_operand" "=r")
(sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "0,r"))) (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
(clobber (reg:SI 18))] (clobber (reg:SI 18))]
"" ""
"@ "mov %1,%S0\;mov %1,%R0\;shll %S0\;subc %S0,%S0 ! a sidi2"
mov %1,%0\;shll %0\;subc %0,%0 ! b sidi2 [(set_attr "length" "8")])
mov %1,%0\;mov %1,%R0\;shll %0\;subc %0,%0 ! a sidi2"
[(set_attr "length" "6,8")])
(define_insn "extendhisi2" (define_insn "extendhisi2"
[(set (match_operand:SI 0 "arith_reg_operand" "=r,z,r") [(set (match_operand:SI 0 "arith_reg_operand" "=r,z,r")
(sign_extend:SI (match_operand:HI 1 "arith_operand" "r,u,m")))] (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,u,m")))]
"" ""
"@ "@
exts.w %1,%0 exts.w %1,%0
...@@ -1046,7 +1058,7 @@ ...@@ -1046,7 +1058,7 @@
[(set (match_operand:DI 0 "push_operand" "=<") [(set (match_operand:DI 0 "push_operand" "=<")
(match_operand:DI 1 "arith_reg_operand" "r"))] (match_operand:DI 1 "arith_reg_operand" "r"))]
"" ""
"mov.l %R1,%0\;mov.l %1,%0" "mov.l %T1,%0\;mov.l %01,%0"
[(set_attr "length" "4") [(set_attr "length" "4")
(set_attr "type" "store")]) (set_attr "type" "store")])
...@@ -1109,7 +1121,7 @@ ...@@ -1109,7 +1121,7 @@
[(set (match_operand:DF 0 "push_operand" "=<") [(set (match_operand:DF 0 "push_operand" "=<")
(match_operand:DF 1 "arith_reg_operand" "r"))] (match_operand:DF 1 "arith_reg_operand" "r"))]
"" ""
"mov.l %R1,%0\;mov.l %1,%0" "mov.l %T1,%0\;mov.l %1,%0"
[(set_attr "length" "4") [(set_attr "length" "4")
(set_attr "type" "store")]) (set_attr "type" "store")])
...@@ -1434,17 +1446,17 @@ ...@@ -1434,17 +1446,17 @@
;; Misc insns ;; Misc insns
;; ------------------------------------------------------------------------ ;; ------------------------------------------------------------------------
(define_insn "dect" ;(define_insn "dect"
[(parallel[ ; [(parallel[
(set (reg:SI 18) ; (set (match_dup 0)
(eq:SI (match_operand:SI 0 "register_operand" "=r") ; (plus:SI (match_dup 0)
(const_int 1))) ; (const_int -1)))
;
(set (match_dup 0) ; (set (reg:SI 18)
(plus:SI (match_dup 0) ; (eq:SI (match_operand:SI 0 "register_operand" "=r")
(const_int -1)))])] ; (const_int 0)))])]
"TARGET_SH2" ; "TARGET_SH2"
"dt %0") ; "dt %0")
(define_insn "nop" (define_insn "nop"
[(const_int 0)] [(const_int 0)]
...@@ -1918,3 +1930,18 @@ ...@@ -1918,3 +1930,18 @@
(define_peephole
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (match_dup 0)
(const_int -1)))
(set (reg:SI 18)
(eq:SI (match_dup 0)
(const_int 0)))]
"TARGET_SH2"
"dt %0")
...@@ -26,3 +26,8 @@ fp-bit.c: $(srcdir)/config/fp-bit.c ...@@ -26,3 +26,8 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
cat $(srcdir)/config/fp-bit.c >> fp-bit.c cat $(srcdir)/config/fp-bit.c >> fp-bit.c
MULTILIB_OPTIONS=ml
MULTILIB_DIRNAMES=ml
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
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