This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: sh-unknown-linux-gnu (Support of no fdiv for integer division)
This is unfinished work (yet). Here's the trial to support
-m4-no-fpu, the target not using FPU.
I need to introduce the bit of NO_FPU_BIT not to touch -m4-nofpu behavior.
Changes are rather large than I expected.
We need to handle calling convention of structure passing, and
variable args.
IMO, it is difficult to maintain -m4-no-fpu.
I'd say, I like '-mno-implicit-fp' as William C. Cox suggested.
Index: gcc/config/sh/sh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.c,v
retrieving revision 1.122
diff -c -3 -p -r1.122 sh.c
*** sh.c 2001/09/21 01:27:05 1.122
--- sh.c 2001/10/03 13:23:31
*************** sh_expand_prologue ()
*** 4078,4084 ****
current_function_anonymous_args = 0;
/* This is not used by the SH3E calling convention */
! if (! TARGET_SH3E && ! TARGET_HITACHI)
{
/* Push arg regs as if they'd been provided by caller in stack. */
for (i = 0; i < NPARM_REGS(SImode); i++)
--- 4078,4085 ----
current_function_anonymous_args = 0;
/* This is not used by the SH3E calling convention */
! if (! TARGET_SH3E && ! (TARGET_HARD_SH4 && TARGET_NO_FPU)
! && ! TARGET_HITACHI)
{
/* Push arg regs as if they'd been provided by caller in stack. */
for (i = 0; i < NPARM_REGS(SImode); i++)
*************** sh_build_va_list ()
*** 4335,4341 ****
tree f_next_o, f_next_o_limit, f_next_fp, f_next_fp_limit, f_next_stack;
tree record;
! if ((! TARGET_SH3E && ! TARGET_SH4) || TARGET_HITACHI)
return ptr_type_node;
record = make_node (RECORD_TYPE);
--- 4336,4343 ----
tree f_next_o, f_next_o_limit, f_next_fp, f_next_fp_limit, f_next_stack;
tree record;
! if ((! TARGET_SH3E && ! TARGET_SH4
! && ! (TARGET_HARD_SH4 && TARGET_NO_FPU)) || TARGET_HITACHI)
return ptr_type_node;
record = make_node (RECORD_TYPE);
*************** sh_va_start (stdarg_p, valist, nextarg)
*** 4383,4389 ****
tree t, u;
int nfp, nint;
! if ((! TARGET_SH3E && ! TARGET_SH4) || TARGET_HITACHI)
{
std_expand_builtin_va_start (stdarg_p, valist, nextarg);
return;
--- 4385,4392 ----
tree t, u;
int nfp, nint;
! if ((! TARGET_SH3E && ! TARGET_SH4
! && !(TARGET_HARD_SH4 && TARGET_NO_FPU)) || TARGET_HITACHI)
{
std_expand_builtin_va_start (stdarg_p, valist, nextarg);
return;
*************** sh_va_arg (valist, type)
*** 4461,4467 ****
rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
pptr_type_node = build_pointer_type (ptr_type_node);
! if ((TARGET_SH3E || TARGET_SH4) && ! TARGET_HITACHI)
{
tree f_next_o, f_next_o_limit, f_next_fp, f_next_fp_limit, f_next_stack;
tree next_o, next_o_limit, next_fp, next_fp_limit, next_stack;
--- 4464,4471 ----
rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
pptr_type_node = build_pointer_type (ptr_type_node);
! if ((TARGET_SH3E || TARGET_SH4
! || (TARGET_HARD_SH4 && TARGET_NO_FPU)) && ! TARGET_HITACHI)
{
tree f_next_o, f_next_o_limit, f_next_fp, f_next_fp_limit, f_next_stack;
tree next_o, next_o_limit, next_fp, next_fp_limit, next_stack;
*************** sh_va_arg (valist, type)
*** 4552,4558 ****
emit_barrier ();
emit_label (lab_false);
! if (size > 4 && ! TARGET_SH4)
{
tmp = build (MODIFY_EXPR, ptr_type_node, next_o, next_o_limit);
TREE_SIDE_EFFECTS (tmp) = 1;
--- 4556,4562 ----
emit_barrier ();
emit_label (lab_false);
! if (size > 4 && ! TARGET_SH4 && !(TARGET_HARD_SH4 && TARGET_NO_FPU))
{
tmp = build (MODIFY_EXPR, ptr_type_node, next_o, next_o_limit);
TREE_SIDE_EFFECTS (tmp) = 1;
Index: gcc/config/sh/sh.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.h,v
retrieving revision 1.117
diff -c -3 -p -r1.117 sh.h
*** sh.h 2001/09/21 00:53:28 1.117
--- sh.h 2001/10/03 13:23:31
*************** extern int target_flags;
*** 134,139 ****
--- 134,140 ----
#define HARD_SH4_BIT (1<<5)
#define FPU_SINGLE_BIT (1<<7)
#define SH4_BIT (1<<12)
+ #define NO_FPU_BIT (1<<3)
#define FMOVD_BIT (1<<4)
#define SPACE_BIT (1<<13)
#define BIGTABLE_BIT (1<<14)
*************** extern int target_flags;
*** 176,181 ****
--- 177,185 ----
/* Nonzero if compiling for SH4 hardware (to be used for insn costs etc.) */
#define TARGET_HARD_SH4 (target_flags & HARD_SH4_BIT)
+ /* Nonzero if compiling for -m4-no-fpu */
+ #define TARGET_NO_FPU (target_flags & NO_FPU_BIT)
+
/* Nonzero if the default precision of th FPU is single */
#define TARGET_FPU_SINGLE (target_flags & FPU_SINGLE_BIT)
*************** extern int target_flags;
*** 237,242 ****
--- 241,248 ----
{"4-single-only", SH3E_BIT|SH3_BIT|SH2_BIT|SH1_BIT|HARD_SH4_BIT|FPU_SINGLE_BIT, "" }, \
{"4-single", TARGET_NONE, "" }, \
{"4-single", SH4_BIT|SH3E_BIT|SH3_BIT|SH2_BIT|SH1_BIT|HARD_SH4_BIT|FPU_SINGLE_BIT, "" },\
+ {"4-no-fpu", TARGET_NONE, "" }, \
+ {"4-no-fpu", NO_FPU_BIT|SH3_BIT|SH2_BIT|SH1_BIT|HARD_SH4_BIT, "" },\
{"4-nofpu", TARGET_NONE, "" }, \
{"4-nofpu", SH3_BIT|SH2_BIT|SH1_BIT|HARD_SH4_BIT, "" },\
{"4", TARGET_NONE, "" }, \
*************** struct sh_args {
*** 1126,1132 ****
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
if ((CUM).force_mem) \
(CUM).force_mem = 0; \
! else if (! TARGET_SH4 || PASS_IN_REG_P ((CUM), (MODE), (TYPE))) \
((CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE)] \
= (ROUND_REG ((CUM), (MODE)) \
+ ((MODE) == BLKmode \
--- 1132,1138 ----
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
if ((CUM).force_mem) \
(CUM).force_mem = 0; \
! else if ((!TARGET_SH4 && !TARGET_NO_FPU) || PASS_IN_REG_P ((CUM), (MODE), (TYPE))) \
((CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE)] \
= (ROUND_REG ((CUM), (MODE)) \
+ ((MODE) == BLKmode \
*************** struct sh_args {
*** 1141,1147 ****
|| (! TREE_ADDRESSABLE ((tree)(TYPE)) \
&& (! TARGET_HITACHI || ! AGGREGATE_TYPE_P (TYPE)))) \
&& ! (CUM).force_mem \
! && (TARGET_SH3E \
? ((MODE) == BLKmode \
? (((CUM).arg_count[(int) SH_ARG_INT] * UNITS_PER_WORD \
+ int_size_in_bytes (TYPE)) \
--- 1147,1153 ----
|| (! TREE_ADDRESSABLE ((tree)(TYPE)) \
&& (! TARGET_HITACHI || ! AGGREGATE_TYPE_P (TYPE)))) \
&& ! (CUM).force_mem \
! && ((TARGET_SH3E || (TARGET_HARD_SH4 && TARGET_NO_FPU)) \
? ((MODE) == BLKmode \
? (((CUM).arg_count[(int) SH_ARG_INT] * UNITS_PER_WORD \
+ int_size_in_bytes (TYPE)) \
*************** struct sh_args {
*** 1172,1178 ****
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
((PASS_IN_REG_P ((CUM), (MODE), (TYPE)) \
&& ((NAMED) \
! || (! TARGET_HITACHI && (TARGET_SH3E || ! current_function_varargs)))) \
? gen_rtx_REG ((MODE), \
((BASE_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE))) \
^ ((MODE) == SFmode && TARGET_SH4 \
--- 1178,1186 ----
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
((PASS_IN_REG_P ((CUM), (MODE), (TYPE)) \
&& ((NAMED) \
! || (! TARGET_HITACHI && \
! (TARGET_SH3E || (TARGET_HARD_SH4 && TARGET_NO_FPU) \
! || ! current_function_varargs)))) \
? gen_rtx_REG ((MODE), \
((BASE_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE))) \
^ ((MODE) == SFmode && TARGET_SH4 \
*************** struct sh_args {
*** 1189,1195 ****
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
((PASS_IN_REG_P ((CUM), (MODE), (TYPE)) \
! && ! TARGET_SH4 \
&& (ROUND_REG ((CUM), (MODE)) \
+ ((MODE) != BLKmode \
? ROUND_ADVANCE (GET_MODE_SIZE (MODE)) \
--- 1197,1203 ----
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
((PASS_IN_REG_P ((CUM), (MODE), (TYPE)) \
! && ! TARGET_SH4 && ! TARGET_NO_FPU \
&& (ROUND_REG ((CUM), (MODE)) \
+ ((MODE) != BLKmode \
? ROUND_ADVANCE (GET_MODE_SIZE (MODE)) \
*************** extern int current_function_anonymous_ar
*** 1673,1679 ****
/* Max number of bytes we want move_by_pieces to be able to copy
efficiently. */
! #define MOVE_MAX_PIECES (TARGET_SH4 ? 8 : 4)
/* Define if operations between registers always perform the operation
on the full register even if a narrower mode is specified. */
--- 1681,1687 ----
/* Max number of bytes we want move_by_pieces to be able to copy
efficiently. */
! #define MOVE_MAX_PIECES (TARGET_HARD_SH4 ? 8 : 4)
/* Define if operations between registers always perform the operation
--