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
293a36eb
Commit
293a36eb
authored
Oct 16, 1996
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for MIPS EABI
From-SVN: r12967
parent
03f00806
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
307 additions
and
59 deletions
+307
-59
gcc/config/mips/abi64.h
+106
-25
gcc/config/mips/mips.c
+83
-24
gcc/config/mips/mips.h
+13
-6
gcc/ginclude/va-mips.h
+105
-4
No files found.
gcc/config/mips/abi64.h
View file @
293a36eb
...
...
@@ -26,11 +26,14 @@ Boston, MA 02111-1307, USA. */
{ "abi=", &mips_abi_string },
#undef STACK_BOUNDARY
#define STACK_BOUNDARY (mips_abi == ABI_32 ? 64 : 128)
#define STACK_BOUNDARY \
((mips_abi == ABI_32 || mips_abi == ABI_EABI) ? 64 : 128)
#undef MIPS_STACK_ALIGN
#define MIPS_STACK_ALIGN(LOC) \
(mips_abi == ABI_32 ? ((LOC)+7) & ~7 : ((LOC)+15) & ~15)
#define MIPS_STACK_ALIGN(LOC) \
((mips_abi == ABI_32 || mips_abi == ABI_EABI) \
? ((LOC) + 7) & ~7 \
: ((LOC) + 15) & ~15)
#undef GP_ARG_LAST
#define GP_ARG_LAST (mips_abi == ABI_32 ? GP_REG_FIRST + 7 : GP_REG_FIRST + 11)
...
...
@@ -78,13 +81,16 @@ Boston, MA 02111-1307, USA. */
? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
&& int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT))\
: (GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY \
&& (mips_abi == ABI_32 || GET_MODE_CLASS (MODE) == MODE_INT)))\
&& (mips_abi == ABI_32 || mips_abi == ABI_EABI \
|| GET_MODE_CLASS (MODE) == MODE_INT))) \
? downward : upward))
#undef RETURN_IN_MEMORY
#define RETURN_IN_MEMORY(TYPE) \
#define RETURN_IN_MEMORY(TYPE)
\
(mips_abi == ABI_32 \
? TYPE_MODE (TYPE) == BLKmode : int_size_in_bytes (TYPE) > 16)
? TYPE_MODE (TYPE) == BLKmode \
: (int_size_in_bytes (TYPE) \
> (mips_abi == ABI_EABI ? 2 * UNITS_PER_WORD : 16)))
extern
struct
rtx_def
*
mips_function_value
();
#undef FUNCTION_VALUE
...
...
@@ -95,29 +101,78 @@ extern struct rtx_def *mips_function_value ();
For stdarg, we do not need to save the current argument, because it
is a real argument. */
#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
{ if (mips_abi != ABI_32 \
&& ((CUM).arg_words \
< (MAX_ARGS_IN_REGISTERS - ! current_function_varargs))) \
{ int mips_off = (! current_function_varargs) && (! (CUM).last_arg_fp); \
int mips_fp_off = (! current_function_varargs) && ((CUM).last_arg_fp); \
if ((mips_abi != ABI_32 \
&& (CUM).arg_words < MAX_ARGS_IN_REGISTERS - mips_off) \
|| (mips_abi == ABI_EABI \
&& ! TARGET_SOFT_FLOAT \
&& (CUM).fp_arg_words < MAX_ARGS_IN_REGISTERS - mips_fp_off)) \
{ \
PRETEND_SIZE \
= (MAX_ARGS_IN_REGISTERS - (CUM).arg_words \
- ! current_function_varargs) * UNITS_PER_WORD; \
int mips_save_gp_regs = \
MAX_ARGS_IN_REGISTERS - (CUM).arg_words - mips_off; \
int mips_save_fp_regs = \
(mips_abi != ABI_EABI ? 0 \
: MAX_ARGS_IN_REGISTERS - (CUM).fp_arg_words - mips_fp_off); \
\
if (mips_save_gp_regs < 0) \
mips_save_gp_regs = 0; \
if (mips_save_fp_regs < 0) \
mips_save_fp_regs = 0; \
PRETEND_SIZE = ((mips_save_gp_regs * UNITS_PER_WORD) \
+ (mips_save_fp_regs * UNITS_PER_FPREG)); \
\
if (! (NO_RTL)) \
{ \
rtx mem = gen_rtx (MEM, BLKmode, virtual_incoming_args_rtx); \
/* va_arg is an array access in this case, which causes it to \
get MEM_IN_STRUCT_P set. We must set it here so that the \
insn scheduler won't assume that these stores can't \
possibly overlap with the va_arg loads. */
\
if (BYTES_BIG_ENDIAN) \
MEM_IN_STRUCT_P (mem) = 1; \
move_block_from_reg \
((CUM).arg_words + GP_ARG_FIRST + ! current_function_varargs, \
mem, \
(MAX_ARGS_IN_REGISTERS - (CUM).arg_words \
- ! current_function_varargs), \
PRETEND_SIZE); \
if ((CUM).arg_words < MAX_ARGS_IN_REGISTERS - mips_off) \
{ \
rtx ptr, mem; \
if (mips_abi != ABI_EABI) \
ptr = virtual_incoming_args_rtx; \
else \
ptr = plus_constant (virtual_incoming_args_rtx, \
- (mips_save_gp_regs \
* UNITS_PER_WORD)); \
mem = gen_rtx (MEM, BLKmode, ptr); \
/* va_arg is an array access in this case, which causes \
it to get MEM_IN_STRUCT_P set. We must set it here \
so that the insn scheduler won't assume that these \
stores can't possibly overlap with the va_arg loads. */
\
if (mips_abi != ABI_EABI && BYTES_BIG_ENDIAN) \
MEM_IN_STRUCT_P (mem) = 1; \
move_block_from_reg \
((CUM).arg_words + GP_ARG_FIRST + mips_off, \
mem, \
mips_save_gp_regs, \
mips_save_gp_regs * UNITS_PER_WORD); \
} \
if (mips_abi == ABI_EABI \
&& ! TARGET_SOFT_FLOAT \
&& (CUM).fp_arg_words < MAX_ARGS_IN_REGISTERS - mips_fp_off) \
{ \
int off; \
int i; \
/* We can't use move_block_from_reg, because it will use \
the wrong mode. */
\
off = (- (mips_save_gp_regs * UNITS_PER_WORD) \
- (mips_save_fp_regs * UNITS_PER_FPREG)); \
for (i = 0; i < mips_save_fp_regs; i++) \
{ \
rtx tem = \
gen_rtx (MEM, DFmode, \
plus_constant (virtual_incoming_args_rtx, \
(off \
+ i * GET_MODE_SIZE (DFmode)))); \
emit_move_insn (tem, \
gen_rtx (REG, DFmode, \
((CUM).fp_arg_words \
+ FP_ARG_FIRST \
+ i \
+ mips_fp_off))); \
if (! TARGET_FLOAT64) \
++i; \
} \
} \
} \
} \
}
...
...
@@ -125,6 +180,32 @@ extern struct rtx_def *mips_function_value ();
/* ??? Should disable for mips_abi == ABI32. */
#define STRICT_ARGUMENT_NAMING
/* A C expression that indicates when an argument must be passed by
reference. If nonzero for an argument, a copy of that argument is
made in memory and a pointer to the argument is passed instead of the
argument itself. The pointer is passed in whatever way is appropriate
for passing a pointer to that type. */
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
(mips_abi == ABI_EABI \
&& function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED))
/* A C expression that indicates when it is the called function's
responsibility to make a copy of arguments passed by invisible
reference. Normally, the caller makes a copy and passes the
address of the copy to the routine being called. When
FUNCTION_ARG_CALLEE_COPIES is defined and is nonzero, the caller
does not make a copy. Instead, it passes a pointer to the "live"
value. The called function must not modify this value. If it can
be determined that the value won't be modified, it need not make a
copy; otherwise a copy must be made.
??? The MIPS EABI says that the caller should copy in ``K&R mode.''
I don't know how to detect that here, since flag_traditional is not
a back end flag. */
#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \
(mips_abi == ABI_EABI && (NAMED) \
&& FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED))
/* ??? Unimplemented stuff follows. */
/* ??? Add support for 16 byte/128 bit long doubles here when
...
...
gcc/config/mips/mips.c
View file @
293a36eb
...
...
@@ -201,7 +201,7 @@ enum mips_abi_type mips_abi;
/* Strings to hold which cpu and instruction set architecture to use. */
char
*
mips_cpu_string
;
/* for -mcpu=<xxx> */
char
*
mips_isa_string
;
/* for -mips{1,2,3,4} */
char
*
mips_abi_string
;
/* for -mabi={o32,32,n32,n64,64} */
char
*
mips_abi_string
;
/* for -mabi={o32,32,n32,n64,64
,eabi
} */
/* If TRUE, we split addresses into their high and low parts in the RTL. */
int
mips_split_addresses
;
...
...
@@ -500,7 +500,7 @@ mips_const_double_ok (op, mode)
return
TRUE
;
/* ??? li.s does not work right with SGI's Irix 6 assembler. */
if
(
mips_abi
!=
ABI_32
)
if
(
mips_abi
!=
ABI_32
&&
mips_abi
!=
ABI_EABI
)
return
FALSE
;
REAL_VALUE_FROM_CONST_DOUBLE
(
d
,
op
);
...
...
@@ -3031,11 +3031,17 @@ function_arg_advance (cum, mode, type, named)
break
;
case
SFmode
:
cum
->
arg_words
++
;
if
(
mips_abi
==
ABI_EABI
&&
!
TARGET_SOFT_FLOAT
)
cum
->
fp_arg_words
++
;
else
cum
->
arg_words
++
;
break
;
case
DFmode
:
cum
->
arg_words
+=
(
TARGET_64BIT
?
1
:
2
);
if
(
mips_abi
==
ABI_EABI
&&
!
TARGET_SOFT_FLOAT
&&
!
TARGET_SINGLE_FLOAT
)
cum
->
fp_arg_words
+=
(
TARGET_64BIT
?
1
:
2
);
else
cum
->
arg_words
+=
(
TARGET_64BIT
?
1
:
2
);
break
;
case
DImode
:
...
...
@@ -3065,6 +3071,7 @@ function_arg (cum, mode, type, named)
rtx
ret
;
int
regbase
=
-
1
;
int
bias
=
0
;
int
*
arg_words
=
&
cum
->
arg_words
;
int
struct_p
=
((
type
!=
(
tree
)
0
)
&&
(
TREE_CODE
(
type
)
==
RECORD_TYPE
||
TREE_CODE
(
type
)
==
UNION_TYPE
));
...
...
@@ -3075,6 +3082,7 @@ function_arg (cum, mode, type, named)
cum
->
gp_reg_found
,
cum
->
arg_number
,
cum
->
arg_words
,
GET_MODE_NAME
(
mode
),
type
,
named
);
cum
->
last_arg_fp
=
0
;
switch
(
mode
)
{
case
SFmode
:
...
...
@@ -3091,13 +3099,28 @@ function_arg (cum, mode, type, named)
bias
=
1
;
}
}
else
if
(
mips_abi
==
ABI_EABI
&&
!
TARGET_SOFT_FLOAT
)
{
if
(
!
TARGET_64BIT
)
cum
->
fp_arg_words
+=
cum
->
fp_arg_words
&
1
;
cum
->
last_arg_fp
=
1
;
arg_words
=
&
cum
->
fp_arg_words
;
regbase
=
FP_ARG_FIRST
;
}
else
regbase
=
(
TARGET_SOFT_FLOAT
||
!
named
?
GP_ARG_FIRST
:
FP_ARG_FIRST
);
break
;
case
DFmode
:
if
(
!
TARGET_64BIT
)
cum
->
arg_words
+=
(
cum
->
arg_words
&
1
);
{
if
(
mips_abi
==
ABI_EABI
&&
!
TARGET_SOFT_FLOAT
&&
!
TARGET_SINGLE_FLOAT
)
cum
->
fp_arg_words
+=
cum
->
fp_arg_words
&
1
;
else
cum
->
arg_words
+=
cum
->
arg_words
&
1
;
}
if
(
mips_abi
==
ABI_32
)
regbase
=
((
cum
->
gp_reg_found
||
TARGET_SOFT_FLOAT
...
...
@@ -3105,6 +3128,14 @@ function_arg (cum, mode, type, named)
||
cum
->
arg_number
>=
2
)
?
GP_ARG_FIRST
:
FP_ARG_FIRST
);
else
if
(
mips_abi
==
ABI_EABI
&&
!
TARGET_SOFT_FLOAT
&&
!
TARGET_SINGLE_FLOAT
)
{
cum
->
last_arg_fp
=
1
;
arg_words
=
&
cum
->
fp_arg_words
;
regbase
=
FP_ARG_FIRST
;
}
else
regbase
=
(
TARGET_SOFT_FLOAT
||
TARGET_SINGLE_FLOAT
||
!
named
?
GP_ARG_FIRST
:
FP_ARG_FIRST
);
...
...
@@ -3118,9 +3149,8 @@ function_arg (cum, mode, type, named)
/* Drops through. */
case
BLKmode
:
if
(
type
!=
(
tree
)
0
&&
TYPE_ALIGN
(
type
)
>
BITS_PER_WORD
&&
!
TARGET_64BIT
)
&&
!
TARGET_64BIT
&&
mips_abi
!=
ABI_EABI
)
cum
->
arg_words
+=
(
cum
->
arg_words
&
1
);
regbase
=
GP_ARG_FIRST
;
break
;
...
...
@@ -3137,7 +3167,7 @@ function_arg (cum, mode, type, named)
regbase
=
GP_ARG_FIRST
;
}
if
(
cum
->
arg_words
>=
MAX_ARGS_IN_REGISTERS
)
if
(
*
arg_words
>=
MAX_ARGS_IN_REGISTERS
)
{
if
(
TARGET_DEBUG_E_MODE
)
fprintf
(
stderr
,
"<stack>%s
\n
"
,
struct_p
?
", [struct]"
:
""
);
...
...
@@ -3150,8 +3180,8 @@ function_arg (cum, mode, type, named)
abort
();
if
(
!
type
||
TREE_CODE
(
type
)
!=
RECORD_TYPE
||
mips_abi
==
ABI_32
||
!
named
)
ret
=
gen_rtx
(
REG
,
mode
,
regbase
+
cum
->
arg_words
+
bias
);
||
mips_abi
==
ABI_EABI
||
!
named
)
ret
=
gen_rtx
(
REG
,
mode
,
regbase
+
*
arg_words
+
bias
);
else
{
/* The Irix 6 n32/n64 ABIs say that if any 64 bit chunk of the
...
...
@@ -3169,7 +3199,7 @@ function_arg (cum, mode, type, named)
break
;
if
(
!
field
)
ret
=
gen_rtx
(
REG
,
mode
,
regbase
+
cum
->
arg_words
+
bias
);
ret
=
gen_rtx
(
REG
,
mode
,
regbase
+
*
arg_words
+
bias
);
else
{
/* Now handle the special case by returning a PARALLEL
...
...
@@ -3188,15 +3218,15 @@ function_arg (cum, mode, type, named)
backend to allow DImode values in fp registers. */
chunks
=
TREE_INT_CST_LOW
(
TYPE_SIZE
(
type
))
/
BITS_PER_WORD
;
if
(
chunks
+
cum
->
arg_words
+
bias
>
MAX_ARGS_IN_REGISTERS
)
chunks
=
MAX_ARGS_IN_REGISTERS
-
cum
->
arg_words
-
bias
;
if
(
chunks
+
*
arg_words
+
bias
>
MAX_ARGS_IN_REGISTERS
)
chunks
=
MAX_ARGS_IN_REGISTERS
-
*
arg_words
-
bias
;
/* assign_parms checks the mode of ENTRY_PARM, so we must
use the actual mode here. */
ret
=
gen_rtx
(
PARALLEL
,
mode
,
rtvec_alloc
(
chunks
));
bitpos
=
0
;
regno
=
regbase
+
cum
->
arg_words
+
bias
;
regno
=
regbase
+
*
arg_words
+
bias
;
field
=
TYPE_FIELDS
(
type
);
for
(
i
=
0
;
i
<
chunks
;
i
++
)
{
...
...
@@ -3227,7 +3257,7 @@ function_arg (cum, mode, type, named)
}
if
(
TARGET_DEBUG_E_MODE
)
fprintf
(
stderr
,
"%s%s
\n
"
,
reg_names
[
regbase
+
cum
->
arg_words
+
bias
],
fprintf
(
stderr
,
"%s%s
\n
"
,
reg_names
[
regbase
+
*
arg_words
+
bias
],
struct_p
?
", [struct]"
:
""
);
/* The following is a hack in order to pass 1 byte structures
...
...
@@ -3250,11 +3280,11 @@ function_arg (cum, mode, type, named)
calling convention for now. */
if
(
struct_p
&&
int_size_in_bytes
(
type
)
<
UNITS_PER_WORD
&&
!
TARGET_64BIT
)
&&
!
TARGET_64BIT
&&
mips_abi
!=
ABI_EABI
)
{
rtx
amount
=
GEN_INT
(
BITS_PER_WORD
-
int_size_in_bytes
(
type
)
*
BITS_PER_UNIT
);
rtx
reg
=
gen_rtx
(
REG
,
word_mode
,
regbase
+
cum
->
arg_words
+
bias
);
rtx
reg
=
gen_rtx
(
REG
,
word_mode
,
regbase
+
*
arg_words
+
bias
);
if
(
TARGET_64BIT
)
cum
->
adjust
[
cum
->
num_adjusts
++
]
=
gen_ashldi3
(
reg
,
reg
,
amount
);
else
...
...
@@ -3279,7 +3309,8 @@ function_arg_partial_nregs (cum, mode, type, named)
if
((
mode
==
BLKmode
||
GET_MODE_CLASS
(
mode
)
!=
MODE_COMPLEX_INT
||
GET_MODE_CLASS
(
mode
)
!=
MODE_COMPLEX_FLOAT
)
&&
cum
->
arg_words
<
MAX_ARGS_IN_REGISTERS
)
&&
cum
->
arg_words
<
MAX_ARGS_IN_REGISTERS
&&
mips_abi
!=
ABI_EABI
)
{
int
words
;
if
(
mode
==
BLKmode
)
...
...
@@ -3299,7 +3330,8 @@ function_arg_partial_nregs (cum, mode, type, named)
}
else
if
(
mode
==
DImode
&&
cum
->
arg_words
==
MAX_ARGS_IN_REGISTERS
-
1
&&
!
TARGET_64BIT
)
&&
!
TARGET_64BIT
&&
mips_abi
!=
ABI_EABI
)
{
if
(
TARGET_DEBUG_E_MODE
)
fprintf
(
stderr
,
"function_arg_partial_nregs = 1
\n
"
);
...
...
@@ -3402,11 +3434,13 @@ override_options ()
else
if
(
!
strcmp
(
mips_abi_string
,
"64"
)
||
!
strcmp
(
mips_abi_string
,
"n64"
))
mips_abi
=
ABI_64
;
else
if
(
!
strcmp
(
mips_abi_string
,
"eabi"
))
mips_abi
=
ABI_EABI
;
else
error
(
"bad value (%s) for -mabi= switch"
,
mips_abi_string
);
/* A specified ISA defaults the ABI if it was not specified. */
if
(
mips_abi_string
==
0
&&
mips_isa_string
)
if
(
mips_abi_string
==
0
&&
mips_isa_string
&&
mips_abi
!=
ABI_EABI
)
{
if
(
mips_isa
<=
2
)
mips_abi
=
ABI_32
;
...
...
@@ -3414,7 +3448,7 @@ override_options ()
mips_abi
=
ABI_64
;
}
/* A specified ABI defaults the ISA if it was not specified. */
else
if
(
mips_isa_string
==
0
&&
mips_abi_string
)
else
if
(
mips_isa_string
==
0
&&
mips_abi_string
&&
mips_abi
!=
ABI_EABI
)
{
if
(
mips_abi
==
ABI_32
)
mips_isa
=
1
;
...
...
@@ -4506,7 +4540,7 @@ mips_asm_file_start (stream)
/* Start a section, so that the first .popsection directive is guaranteed
to have a previously defined section to pop back to. */
if
(
mips_abi
!=
ABI_32
)
if
(
mips_abi
!=
ABI_32
&&
mips_abi
!=
ABI_EABI
)
fprintf
(
stream
,
"
\t
.section
\t
.text
\n
"
);
/* This code exists so that we can put all externs before all symbol
...
...
@@ -4853,7 +4887,7 @@ compute_frame_size (size)
for leaf routines (total_size == extra_size) to save the gp reg.
The gp reg is callee saved in the 64 bit ABI, so all routines must
save the gp reg. */
if
(
total_size
==
extra_size
&&
mips_abi
==
ABI_32
)
if
(
total_size
==
extra_size
&&
(
mips_abi
==
ABI_32
||
mips_abi
==
ABI_EABI
)
)
total_size
=
extra_size
=
0
;
else
if
(
TARGET_ABICALLS
)
{
...
...
@@ -5857,7 +5891,8 @@ mips_function_value (valtype, func)
/* ??? How should we return complex float? */
if
(
mclass
==
MODE_FLOAT
||
mclass
==
MODE_COMPLEX_FLOAT
)
reg
=
FP_RETURN
;
else
if
(
TREE_CODE
(
valtype
)
==
RECORD_TYPE
&&
mips_abi
!=
ABI_32
)
else
if
(
TREE_CODE
(
valtype
)
==
RECORD_TYPE
&&
mips_abi
!=
ABI_32
&&
mips_abi
!=
ABI_EABI
)
{
/* A struct with only one or two floating point fields is returned in
the floating point registers. */
...
...
@@ -5916,6 +5951,30 @@ mips_function_value (valtype, func)
return
gen_rtx
(
REG
,
mode
,
reg
);
}
/* The implementation of FUNCTION_ARG_PASS_BY_REFERENCE. Return
nonzero when an argument must be passed by reference. */
int
function_arg_pass_by_reference
(
cum
,
mode
,
type
,
named
)
CUMULATIVE_ARGS
*
cum
;
enum
machine_mode
mode
;
tree
type
;
int
named
;
{
int
size
;
if
(
mips_abi
!=
ABI_EABI
)
return
0
;
/* ??? How should SCmode be handled? */
if
(
type
==
NULL_TREE
||
mode
==
DImode
||
mode
==
DFmode
)
return
0
;
size
=
int_size_in_bytes
(
type
);
return
size
==
-
1
||
size
>
UNITS_PER_WORD
;
}
#endif
/* This function returns the register class required for a secondary
...
...
gcc/config/mips/mips.h
View file @
293a36eb
...
...
@@ -82,7 +82,8 @@ enum processor_type {
enum
mips_abi_type
{
ABI_32
,
ABI_N32
,
ABI_64
ABI_64
,
ABI_EABI
};
#ifndef MIPS_ABI_DEFAULT
...
...
@@ -166,6 +167,7 @@ extern void final_prescan_insn ();
extern
struct
rtx_def
*
function_arg
();
extern
void
function_arg_advance
();
extern
int
function_arg_partial_nregs
();
extern
int
function_arg_pass_by_reference
();
extern
void
function_epilogue
();
extern
void
function_prologue
();
extern
void
gen_conditional_branch
();
...
...
@@ -803,6 +805,8 @@ while (0)
%{mgp32:-U__mips64} %{mgp64:-D__mips64} \
%{msingle-float:%{!msoft-float:-D__mips_single_float}} \
%{m4650:%{!msoft-float:-D__mips_single_float}} \
%{msoft-float:-D__mips_soft_float} \
%{mabi=eabi:-D__mips_eabi} \
%{EB:-UMIPSEL -U_MIPSEL -U__MIPSEL -U__MIPSEL__ -D_MIPSEB -D__MIPSEB -D__MIPSEB__ %{!ansi:-DMIPSEB}} \
%{EL:-UMIPSEB -U_MIPSEB -U__MIPSEB -U__MIPSEB__ -D_MIPSEL -D__MIPSEL -D__MIPSEL__ %{!ansi:-DMIPSEL}} \
%(subtarget_cpp_spec) "
...
...
@@ -1914,7 +1918,7 @@ extern struct mips_frame_info current_frame_info;
&& ((TO) == FRAME_POINTER_REGNUM \
|| (TO) == STACK_POINTER_REGNUM)) \
(OFFSET) = (current_frame_info.total_size \
- (
mips_abi != ABI_32
\
- (
(mips_abi != ABI_32 && mips_abi != ABI_EABI)
\
? current_function_pretend_args_size \
: 0)); \
else if ((FROM) == RETURN_ADDRESS_POINTER_REGNUM \
...
...
@@ -2112,6 +2116,8 @@ typedef struct mips_args {
int
gp_reg_found
;
/* whether a gp register was found yet */
int
arg_number
;
/* argument number */
int
arg_words
;
/* # total words the arguments take */
int
fp_arg_words
;
/* # words for FP args (MIPS_EABI only) */
int
last_arg_fp
;
/* nonzero if last arg was FP (EABI only) */
int
num_adjusts
;
/* number of adjustments made */
/* Adjustments made to args pass in regs. */
/* ??? The size is doubled to work around a
...
...
@@ -2507,7 +2513,7 @@ typedef struct mips_args {
/* ??? Reject combining an address with a register for the MIPS \
64 bit ABI, because the SGI assembler can not handle this. */
\
if (!TARGET_DEBUG_A_MODE \
&&
mips_abi == ABI_32
\
&&
(mips_abi == ABI_32 || mips_abi == ABI_EABI)
\
&& CONSTANT_ADDRESS_P (xplus1) \
&& ! mips_split_addresses \
&& (!TARGET_EMBEDDED_PIC \
...
...
@@ -2537,7 +2543,7 @@ typedef struct mips_args {
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \
|| (GET_CODE (X) == CONST \
&& ! (flag_pic && pic_address_needs_scratch (X)) \
&&
mips_abi == ABI_32))
\
&&
(mips_abi == ABI_32 || mips_abi == ABI_EABI)))
\
&& (!HALF_PIC_P () || !HALF_PIC_ADDRESS_P (X)))
/* Define this, so that when PIC, reload won't try to reload invalid
...
...
@@ -2556,7 +2562,8 @@ typedef struct mips_args {
#define LEGITIMATE_CONSTANT_P(X) \
((GET_CODE (X) != CONST_DOUBLE \
|| mips_const_double_ok (X, GET_MODE (X))) \
&& ! (GET_CODE (X) == CONST && mips_abi != ABI_32))
&& ! (GET_CODE (X) == CONST \
&& mips_abi != ABI_32 && mips_abi != ABI_EABI))
/* A C compound statement that attempts to replace X with a valid
memory address for an operand of mode MODE. WIN will be a C
...
...
@@ -2618,7 +2625,7 @@ typedef struct mips_args {
if (GET_CODE (xinsn) == CONST \
&& ((flag_pic && pic_address_needs_scratch (xinsn)) \
/* ??? SGI's Irix 6 assembler can't handle CONST. */
\
||
mips_abi != ABI_32))
\
||
(mips_abi != ABI_32 && mips_abi != ABI_EABI)))
\
{ \
rtx ptr_reg = gen_reg_rtx (Pmode); \
rtx constant = XEXP (XEXP (xinsn, 0), 1); \
...
...
gcc/ginclude/va-mips.h
View file @
293a36eb
...
...
@@ -13,7 +13,51 @@
#ifndef __GNUC_VA_LIST
#define __GNUC_VA_LIST
#if defined (__mips_eabi) && ! defined (__mips_soft_float)
typedef
struct
{
/* Pointer to FP regs. */
char
*
__fp_regs
;
/* Number of FP regs remaining. */
int
__fp_left
;
/* Pointer to GP regs followed by stack parameters. */
char
*
__gp_regs
;
}
__gnuc_va_list
;
#ifdef __mips64
#define __va_reg_size 8
#else
#define __va_reg_size 4
#endif
enum
{
__no_type_class
=
-
1
,
__void_type_class
,
__integer_type_class
,
__char_type_class
,
__enumeral_type_class
,
__boolean_type_class
,
__pointer_type_class
,
__reference_type_class
,
__offset_type_class
,
__real_type_class
,
__complex_type_class
,
__function_type_class
,
__method_type_class
,
__record_type_class
,
__union_type_class
,
__array_type_class
,
__string_type_class
,
__set_type_class
,
__file_type_class
,
__lang_type_class
};
#else
/* ! (defined (__mips_eabi) && ! defined (__mips_soft_float)) */
typedef
char
*
__gnuc_va_list
;
#endif
/* ! (defined (__mips_eabi) && ! defined (__mips_soft_float)) */
#endif
/* not __GNUC_VA_LIST */
/* If this is for internal libc use, don't define anything but
...
...
@@ -43,10 +87,19 @@ typedef char * __gnuc_va_list;
#endif
#ifdef _STDARG_H
#if defined (__mips_eabi) && ! defined (__mips_soft_float)
#define va_start(__AP, __LASTARG) \
(__AP.__gp_regs = ((char *) __builtin_next_arg (__LASTARG) \
- (__builtin_args_info (2) < 8 \
? (8 - __builtin_args_info (2)) * __va_reg_size \
: 0)), \
__AP.__fp_left = 8 - __builtin_args_info (3), \
__AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * __va_reg_size)
#else
/* ! (defined (__mips_eabi) && ! defined (__mips_soft_float)) */
#define va_start(__AP, __LASTARG) \
(__AP = (__gnuc_va_list) __builtin_next_arg (__LASTARG))
#else
#endif
/* ! (defined (__mips_eabi) && ! defined (__mips_soft_float)) */
#else
/* ! _STDARG_H */
#define va_alist __builtin_va_alist
#ifdef __mips64
/* This assumes that `long long int' is always a 64 bit type. */
...
...
@@ -54,21 +107,68 @@ typedef char * __gnuc_va_list;
#else
#define va_dcl int __builtin_va_alist; __va_ellipsis
#endif
#if defined (__mips_eabi) && ! defined (__mips_soft_float)
#define va_start(__AP) \
(__AP.__gp_regs = ((char *) __builtin_next_arg () \
- (__builtin_args_info (2) < 8 \
? (8 - __builtin_args_info (2)) * __va_reg_size \
: 8)), \
__AP.__fp_left = 8 - __builtin_args_info (3), \
__AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * __va_reg_size)
/* Need alternate code for _MIPS_SIM_ABI64. */
#if defined(_MIPS_SIM) && (_MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32)
#
el
if defined(_MIPS_SIM) && (_MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32)
#define va_start(__AP) \
(__AP = (__gnuc_va_list) __builtin_next_arg () \
+ (__builtin_args_info (2) >= 8 ? -8 : 0))
#else
#define va_start(__AP) __AP = (char *) &__builtin_va_alist
#endif
#endif
#endif
/* ! _STDARG_H */
#ifndef va_end
void
va_end
(
__gnuc_va_list
);
/* Defined in libgcc.a */
#endif
#define va_end(__AP) ((void)0)
#if defined (__mips_eabi) && ! defined (__mips_soft_float)
#ifdef __mips64
#define __va_next_addr(__AP, __type) \
((__builtin_classify_type (*(__type *) 0) == __real_type_class \
&& __AP.__fp_left > 0) \
? (--__AP.__fp_left, (__AP.__fp_regs += 8) - 8) \
: (__AP.__gp_regs += __va_reg_size) - __va_reg_size)
#else
#define __va_next_addr(__AP, __type) \
((__builtin_classify_type (*(__type *) 0) == __real_type_class \
&& __AP.__fp_left > 0) \
? (--__AP.__fp_left, (__AP.__fp_regs += 8) - 8) \
: (((__builtin_classify_type (* (__type *) 0) < record_type_class \
&& __alignof__ (__type) > 4) \
? __AP.__gp_regs = (__AP.__gp_regs + 8 - 1) & -8), \
(__AP.__gp_regs += __va_reg_size) - __va_reg_size))
#endif
#ifdef __MIPSEB__
#define va_arg(__AP, __type) \
((__va_rounded_size (__type) <= __va_reg_size) \
? *(__type *) (void *) (__va_next_addr (__AP, __type) \
+ __va_reg_size \
- sizeof (__type)) \
: (__builtin_classify_type (*(__type *) 0) >= __record_type_class \
? **(__type **) (void *) (__va_next_addr (__AP, __type) \
+ __va_reg_size \
- sizeof (char *)) \
: *(__type *) (void *) __va_next_addr (__AP, __type)))
#else
#define va_arg(__AP, __type) \
(__builtin_classify_type (* (__type *) 0) >= __record_type_class \
? **(__type **) (void *) __va_next_addr (__AP, __type) \
: *(__type *) (void *) __va_next_addr (__AP, __type))
#endif
#else
/* ! (defined (__mips_eabi) && ! defined (__mips_soft_float)) */
/* We cast to void * and then to TYPE * because this avoids
a warning about increasing the alignment requirement. */
/* The __mips64 cases are reversed from the 32 bit cases, because the standard
...
...
@@ -106,5 +206,6 @@ void va_end (__gnuc_va_list); /* Defined in libgcc.a */
+ __va_rounded_size(__type))))[-1]
#endif
#endif
#endif
/* ! (defined (__mips_eabi) && ! defined (__mips_soft_float)) */
#endif
/* defined (_STDARG_H) || defined (_VARARGS_H) */
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