Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
00f8ff66
Commit
00f8ff66
authored
Nov 24, 1994
by
Steve Chamberlain
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
*** empty log message ***
From-SVN: r8563
parent
43d826d9
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
255 additions
and
100 deletions
+255
-100
gcc/config/sh/sh.c
+116
-20
gcc/config/sh/sh.h
+61
-34
gcc/config/sh/sh.md
+73
-46
gcc/config/sh/t-sh
+5
-0
No files found.
gcc/config/sh/sh.c
View file @
00f8ff66
...
...
@@ -38,6 +38,10 @@
#include "obstack.h"
#include "expr.h"
#define MSW (TARGET_LITTLE_ENDIAN ? 1 : 0)
#define LSW (TARGET_LITTLE_ENDIAN ? 0 : 1)
static
rtx
add_constant
();
int
pragma_interrupt
;
...
...
@@ -52,6 +56,12 @@ static rtx shiftsyms[32];
struct
rtx_def
*
table_lab
;
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. */
/* Saved operands from the last compare to use when we generate an scc
...
...
@@ -338,8 +348,9 @@ print_operand_address (stream, x)
'!' dump the constant table
'#' output a nop if there is nothing to put in the delay slot
'@' print rte or rts depending upon pragma interruptness
'R' print the next register or memory location along, ie the lsw in
a double word value
'R' print the LSW of a dp value - changes if in little endian
'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 #
'M' print a constant as its negative
'N' print insides of a @++ or @-- o */
...
...
@@ -385,14 +396,38 @@ print_operand (stream, x, code)
fputs
(
reg_names
[
REGNO
(
XEXP
(
XEXP
(
x
,
0
),
0
))],
(
stream
));
break
;
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
))
{
case
REG
:
fputs
(
reg_names
[
REGNO
(
x
)
+
1
],
(
stream
));
break
;
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
;
...
...
@@ -829,13 +864,13 @@ output_movedouble (insn, operands, mode)
&&
GET_CODE
(
XEXP
(
dst
,
0
))
==
POST_INC
)
{
operands
[
0
]
=
XEXP
(
XEXP
(
dst
,
0
),
0
);
return
"mov.l %
R
1,@(4,%0)
\n\t
mov.l %1,@%0
\n\t
add #8,%0"
;
return
"mov.l %
T
1,@(4,%0)
\n\t
mov.l %1,@%0
\n\t
add #8,%0"
;
}
if
(
register_operand
(
dst
,
mode
)
&&
register_operand
(
src
,
mode
))
{
if
(
REGNO
(
src
)
==
MACH_REG
)
return
"sts mach,%0
\n\t
sts macl,%R0"
;
return
"sts mach,%
S
0
\n\t
sts macl,%R0"
;
/*
when mov.d r1,r2 do r2->r3 then r1->r2
...
...
@@ -843,24 +878,26 @@ output_movedouble (insn, operands, mode)
*/
if
(
REGNO
(
src
)
+
1
==
REGNO
(
dst
))
return
"mov %
R1,%R
0
\n\t
mov %1,%0 ! cra"
;
return
"mov %
T1,%T
0
\n\t
mov %1,%0 ! cra"
;
else
return
"mov %1,%0
\n\t
mov %
R1,%R
0 ! crb"
;
return
"mov %1,%0
\n\t
mov %
T1,%T
0 ! crb"
;
}
else
if
(
GET_CODE
(
src
)
==
CONST_INT
)
{
HOST_WIDE_INT
val
=
INTVAL
(
src
);
int
rn
=
REGNO
(
operands
[
0
]);
int
msw
=
rn
+
MSW
;
int
lsw
=
rn
+
LSW
;
if
(
val
<
0
)
{
fprintf
(
asm_out_file
,
"
\t
mov #-1,r%d
\n
"
,
rn
);
fprintf
(
asm_out_file
,
"
\t
mov #-1,r%d
\n
"
,
msw
);
}
else
{
fprintf
(
asm_out_file
,
"
\t
mov #0,r%d
\n
"
,
rn
);
fprintf
(
asm_out_file
,
"
\t
mov #0,r%d
\n
"
,
msw
);
}
fprintf
(
asm_out_file
,
"
\t
mov #%d,r%d
\n
"
,
val
,
rn
+
1
);
fprintf
(
asm_out_file
,
"
\t
mov #%d,r%d
\n
"
,
val
,
lsw
);
return
""
;
}
else
if
(
GET_CODE
(
src
)
==
MEM
)
...
...
@@ -885,11 +922,11 @@ output_movedouble (insn, operands, mode)
}
else
if
(
GET_CODE
(
inside
)
==
LABEL_REF
)
{
return
"mov.l %1,%0
\n\t
mov.l %1+4,%
R
0"
;
return
"mov.l %1,%0
\n\t
mov.l %1+4,%
T
0"
;
}
else
if
(
GET_CODE
(
inside
)
==
POST_INC
)
{
return
"mov.l %1,%0
\n\t
mov.l %1,%
R
0 !mdi
\n
"
;
return
"mov.l %1,%0
\n\t
mov.l %1,%
T
0 !mdi
\n
"
;
}
else
abort
();
...
...
@@ -936,11 +973,11 @@ output_movedouble (insn, operands, mode)
if
(
dreg
==
ptrreg1
)
{
/* Copy into the second half first */
return
"mov.l %
R1,%R
0
\n\t
mov.l %1,%0 ! cr"
;
return
"mov.l %
T1,%T
0
\n\t
mov.l %1,%0 ! cr"
;
}
}
return
"mov.l %1,%0
\n\t
mov.l %
R1,%R
0"
;
return
"mov.l %1,%0
\n\t
mov.l %
T1,%T
0"
;
}
/* Emit assembly to shift reg by k bits */
...
...
@@ -1372,6 +1409,9 @@ output_options (file, f_options, f_len, W_options, W_len,
fprintf
(
file
,
term
);
fprintf
(
file
,
"! %d %d
\n
"
,
max_count_si
,
max_count_hi
);
if
(
TARGET_LITTLE_ENDIAN
)
fprintf
(
file
,
"
\t
.little
\n
"
);
}
void
...
...
@@ -1390,12 +1430,36 @@ output_file_start (file, f_options, f_len, W_options, W_len)
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
,
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 */
...
...
@@ -1404,14 +1468,16 @@ shiftcosts (RTX)
rtx
RTX
;
{
/* If shift by a non constant, then this will be expensive. */
if
(
GET_CODE
(
XEXP
(
RTX
,
1
))
!=
CONST_INT
)
return
20
;
if
(
GET_CODE
(
XEXP
(
RTX
,
1
))
!=
CONST_INT
)
{
return
20
;
}
/* otherwise, it will be very cheap if by one of the constants
we can cope with. */
if
(
CONST_OK_FOR_K
(
INTVAL
(
XEXP
(
RTX
,
1
))))
return
1
;
/* 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
one shift which has to be emitted as a bunch anyway - breaking scheduling */
...
...
@@ -1541,10 +1607,12 @@ gen_shifty_op (code, operands)
rtx
wrk
=
gen_reg_rtx
(
SImode
);
rtx
t
;
char
*
func
;
if
(
GET_CODE
(
operands
[
2
])
==
CONST_INT
)
{
int
value
=
INTVAL
(
operands
[
2
]);
top
:
switch
(
code
)
{
case
ASHIFTRT
:
...
...
@@ -1554,7 +1622,20 @@ gen_shifty_op (code, operands)
value
=
-
value
;
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 */
if
(
value
<=
5
)
{
...
...
@@ -1626,6 +1707,7 @@ gen_shifty_op (code, operands)
}
}
return
0
;
}
...
...
@@ -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. */
int
...
...
@@ -2515,6 +2608,8 @@ sh_function_arg_partial_nregs (CUM, MODE, TYPE, NAMED)
return
0
;
}
/* Turn this on to recognise shift insns which aren't supported in the
hardware. This will allow the combiner to notice more patterns,
but the down side is that the asm outputter will have to emit
...
...
@@ -2525,3 +2620,4 @@ int fake_shift()
{
return
0
;
}
gcc/config/sh/sh.h
View file @
00f8ff66
...
...
@@ -41,8 +41,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define SDB_DELIM ";"
#define CPP_SPEC "%{ml:-D__LITTLE_ENDIAN__}"
#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. */
#define CAN_DEBUG_WITHOUT_FP
...
...
@@ -93,6 +99,7 @@ extern int target_flags;
#define BSR_BIT (1<<26)
#define SHORTADDR_BIT (1<<27)
#define PACKSTRUCT_BIT (1<<28)
#define LITTLE_ENDIAN_BIT (1<<29)
/* Nonzero if we should generate code using type 0 insns */
#define TARGET_SH0 (target_flags & SH0_BIT)
...
...
@@ -160,40 +167,49 @@ extern int target_flags;
/* 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) }, \
{"space", ( SPACE_BIT) }, \
{"0", ( SH0_BIT) }, \
{"1", ( SH1_BIT) }, \
{"2", ( SH2_BIT) }, \
{"3", ( SH3_BIT) }, \
{"ac", ( MAC_BIT) }, \
{"dalign", ( DALIGN_BIT) }, \
{"c", ( C_BIT) }, \
{"r", ( RTL_BIT) }, \
{"bigtable", ( BIGTABLE_BIT)}, \
{"try-r0", ( TRYR0_BIT)}, \
{"R", ( R_BIT) }, \
{"nosave", ( NOSAVE_BIT) }, \
{"clen3", ( CONSTLEN_3_BIT) }, \
{"clen0", ( CONSTLEN_0_BIT) }, \
{"smallcall", ( SMALLCALL_BIT) }, \
{"hitachi", ( HITACHI_BIT) }, \
{"paranoid", ( PARANOID_BIT) }, \
{"r2", ( RETR2_BIT) }, \
{"shortaddr", ( SHORTADDR_BIT) }, \
{"bsr", ( BSR_BIT) }, \
{"packstruct",( PACKSTRUCT_BIT) }, \
{"", TARGET_DEFAULT} \
#define TARGET_LITTLE_ENDIAN (target_flags & LITTLE_ENDIAN_BIT)
#define TARGET_SWITCHES \
{ {"0", (SH0_BIT) }, \
{"1", (SH1_BIT) }, \
{"2", (SH2_BIT) }, \
{"3", (SH3_BIT) }, \
{"3l", (SH3_BIT|LITTLE_ENDIAN_BIT)}, \
{"R", (R_BIT) }, \
{"ac", (MAC_BIT) }, \
{"b", (-LITTLE_ENDIAN_BIT) }, \
{"bigtable", (BIGTABLE_BIT)}, \
{"bsr", (BSR_BIT) }, \
{"c", (C_BIT) }, \
{"clen0", (CONSTLEN_0_BIT) }, \
{"clen3", (CONSTLEN_3_BIT) }, \
{"dalign", (DALIGN_BIT) }, \
{"hitachi", (HITACHI_BIT) }, \
{"isize", (ISIZE_BIT) }, \
{"l", (LITTLE_ENDIAN_BIT) }, \
{"nosave", (NOSAVE_BIT) }, \
{"packstruct",(PACKSTRUCT_BIT) }, \
{"paranoid", (PARANOID_BIT) }, \
{"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)
/* Macro to define table for command options with values. */
#define TARGET_OPTIONS \
{ { "maxsi-", &max_si}, \
{ "maxhi-", &max_hi} }
#define OVERRIDE_OPTIONS \
do { \
sh_cpu = CPU_SH0; \
...
...
@@ -201,8 +217,8 @@ do { \
sh_cpu = CPU_SH1; \
if (TARGET_SH2) \
sh_cpu = CPU_SH2; \
if (TARGET_SH3) \
sh_cpu = CPU_SH3
;
\
if (TARGET_SH3) \
sh_cpu = CPU_SH3
|CPU_SH2;
\
\
/* We *MUST* always define optimize since we *HAVE* to run \
shorten branches to get correct code. */
\
...
...
@@ -234,14 +250,25 @@ do { \
/* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields. */
#define BITS_BIG_ENDIAN 0
/* 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
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 */
#define BITS_PER_UNIT 8
...
...
@@ -1156,7 +1183,7 @@ extern int current_function_anonymous_args;
case UDIV: \
case MOD: \
case UMOD: \
return COSTS_N_INSNS (
10
0); \
return COSTS_N_INSNS (
2
0); \
case FLOAT: \
case FIX: \
return 100;
...
...
@@ -1492,7 +1519,7 @@ extern char *output_far_jump();
extern
int
pragma_interrupt
;
#define MOVE_RATIO (TARGET_SMALLCODE ? 4 : 16)
char
*
max_si
;
char
*
max_hi
;
int
max_count_si
;
int
max_count_hi
;
extern
char
*
max_si
;
extern
char
*
max_hi
;
extern
int
max_count_si
;
extern
int
max_count_hi
;
gcc/config/sh/sh.md
View file @
00f8ff66
...
...
@@ -33,8 +33,8 @@
;; %
*
-- print a local label
;; %^ -- increment the local label number
;; %# -- 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
;;
a double word valu
e
;; %R -- print the
lsw arg of a double,
;;
%S -- print the msw arg of a doubl
e
;; %O -- print a constant without the #
;; %M -- print a constant as its negative
;;
...
...
@@ -128,9 +128,9 @@
;; (define_function_unit {name} {num-units} {n-users} {test}
;; {ready-delay} {issue-delay}
[
{conflict-list}
]
)
(define_function_unit "memory" 1 0 (eq_attr "type" "load,pcloadsi,pcloadhi") 2
0
)
(define_function_unit "mpy" 1 0 (eq_attr "type" "smpy")
3 0
)
(define_function_unit "mpy" 1 0 (eq_attr "type" "dmpy")
5 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")
7 7
)
(define_function_unit "mpy" 1 0 (eq_attr "type" "dmpy")
9 9
)
(define_attr "needs_delay_slot" "yes,no"
(cond
[
(eq_attr "type" "jump") (const_string "yes")
...
...
@@ -151,7 +151,7 @@
(define_delay
(and (eq_attr "type" "cbranch")
(eq_attr "cpu" "sh2"))
(eq_attr "cpu" "sh2
,sh3
"))
[
(eq_attr "in_delay_slot" "yes") (nil) (nil)
]
)
(define_attr "in_delay_slot" "maybe,yes,no"
...
...
@@ -270,7 +270,7 @@
(match_operand:DI 2 "register_operand" "r")))
(clobber (reg:SI 18))]
""
"clrt
\;
addc %R2,%R0
\;
addc %
2,%
0"
"clrt
\;
addc %R2,%R0
\;
addc %
S2,%S
0"
[
(set_attr "length" "6")
]
)
...
...
@@ -302,7 +302,7 @@
(match_operand:DI 2 "register_operand" "r")))
(clobber (reg:SI 18))]
""
"clrt
\;
subc %R2,%R0
\;
subc %
2,%
0"
"clrt
\;
subc %R2,%R0
\;
subc %
S2,%S
0"
[
(set_attr "length" "6")
]
)
(define_insn "subsi3"
...
...
@@ -488,11 +488,12 @@
"TARGET_SH2"
"")
(define_insn ""
[
(set (reg:DI 20)
(mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
(sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
"
TARGET_SH2
"
"
(TARGET_SH2) && 0
"
"dmuls.l %2,%1"
[
(set_attr "type" "dmpy")
]
)
...
...
@@ -502,14 +503,14 @@
(sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
(set (match_operand:DI 0 "arith_reg_operand" "=r")
(reg:DI 20))]
"
TARGET_SH2
"
"
(TARGET_SH2) && 0
"
"")
(define_insn ""
[
(set (reg:DI 20)
(mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
(zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
"
TARGET_SH2
"
"
(TARGET_SH2) && 0
"
"dmulu.l %2,%1"
[
(set_attr "type" "dmpy")
]
)
...
...
@@ -519,7 +520,7 @@
(zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
(set (match_operand:DI 0 "arith_reg_operand" "=r")
(reg:DI 20))]
"
TARGET_SH2
"
"
(TARGET_SH2) && 0
"
"")
...
...
@@ -614,6 +615,8 @@
;;
;; shift left
(define_insn "ashlsi3_k"
[
(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
(ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0")
...
...
@@ -643,7 +646,7 @@
(define_expand "ashlsi3"
[
(parallel
[
(set (match_operand:SI 0 "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))])]
""
"if (gen_shifty_op (ASHIFT, operands)) DONE; else FAIL;")
...
...
@@ -661,15 +664,6 @@
"shar %0"
[
(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
; sign extend
...
...
@@ -685,6 +679,25 @@
; (set (match_dup 0) (sign_extend:SI (subreg:HI (match_dup 3) 0)))]
; "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"
[
(set (reg:SI 4)
(ashiftrt:SI (reg:SI 4)
...
...
@@ -710,6 +723,7 @@
; logical shift right
;
(define_insn "lshrsi3_k"
[
(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
(lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0,0")
...
...
@@ -736,7 +750,7 @@
(define_expand "lshrsi3"
[
(parallel
[
(set (match_operand:SI 0 "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))])]
""
"if (gen_shifty_op (LSHIFTRT, operands)) DONE; else FAIL;")
...
...
@@ -747,7 +761,7 @@
(const_int 1)))
(clobber (reg:SI 18))]
""
"shll %R0
\;
rotcl %0"
"shll %R0
\;
rotcl %
S
0"
[
(set_attr "length" "4")
]
)
(define_expand "ashldi3"
...
...
@@ -766,7 +780,7 @@
(const_int 1)))
(clobber (reg:SI 18))]
""
"shlr %0
\;
rotcr %R0"
"shlr %
S
0
\;
rotcr %R0"
[
(set_attr "length" "4")
]
)
(define_expand "lshrdi3"
...
...
@@ -784,7 +798,7 @@
(const_int 1)))
(clobber (reg:SI 18))]
""
"shar %0
\;
rotcr %R0"
"shar %
S
0
\;
rotcr %R0"
[
(set_attr "length" "4")
]
)
(define_expand "ashrdi3"
...
...
@@ -876,18 +890,16 @@
;; -------------------------------------------------------------------------
(define_insn "extendsidi2"
[
(set (match_operand:DI 0 "arith_reg_operand" "=r
,r
")
(sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "
0,
r")))
[
(set (match_operand:DI 0 "arith_reg_operand" "=r")
(sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
(clobber (reg:SI 18))]
""
"@
mov %1,%0
\;
shll %0
\;
subc %0,%0 ! b sidi2
mov %1,%0
\;
mov %1,%R0
\;
shll %0
\;
subc %0,%0 ! a sidi2"
[
(set_attr "length" "6,8")
]
)
"mov %1,%S0
\;
mov %1,%R0
\;
shll %S0
\;
subc %S0,%S0 ! a sidi2"
[
(set_attr "length" "8")
]
)
(define_insn "extendhisi2"
[
(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
...
...
@@ -1046,7 +1058,7 @@
[
(set (match_operand:DI 0 "push_operand" "=<")
(match_operand:DI 1 "arith_reg_operand" "r"))]
""
"mov.l %
R1,%0
\;
mov.l %
1,%0"
"mov.l %
T1,%0
\;
mov.l %0
1,%0"
[
(set_attr "length" "4")
(set_attr "type" "store")])
...
...
@@ -1109,7 +1121,7 @@
[
(set (match_operand:DF 0 "push_operand" "=<")
(match_operand:DF 1 "arith_reg_operand" "r"))]
""
"mov.l %
R
1,%0
\;
mov.l %1,%0"
"mov.l %
T
1,%0
\;
mov.l %1,%0"
[
(set_attr "length" "4")
(set_attr "type" "store")])
...
...
@@ -1434,17 +1446,17 @@
;; Misc insns
;; ------------------------------------------------------------------------
(define_insn "dect"
[
(parallel
[
(set (reg:SI 18
)
(eq:SI (match_operand:SI 0 "register_operand" "=r"
)
(const_int
1)))
(set (match_dup 0
)
(plus:SI (match_dup 0
)
(const_int -1
)))])]
"TARGET_SH2"
"dt %0")
;
(define_insn "dect"
;
[
(parallel
[
; (set (match_dup 0
)
; (plus:SI (match_dup 0
)
; (const_int -
1)))
;
; (set (reg:SI 18
)
; (eq:SI (match_operand:SI 0 "register_operand" "=r"
)
; (const_int 0
)))])]
;
"TARGET_SH2"
;
"dt %0")
(define_insn "nop"
[
(const_int 0)
]
...
...
@@ -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")
gcc/config/sh/t-sh
View file @
00f8ff66
...
...
@@ -26,3 +26,8 @@ fp-bit.c: $(srcdir)/config/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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment