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
3f1f8d8c
Commit
3f1f8d8c
authored
Dec 18, 1992
by
Michael Meissner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Pass QI/HI structures like the MIPS compiler; define SIZE_TYPE to be int by default.
From-SVN: r2893
parent
d4582025
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
188 additions
and
78 deletions
+188
-78
gcc/config/mips/mips.c
+106
-56
gcc/config/mips/mips.h
+19
-4
gcc/config/mips/mips.md
+63
-18
No files found.
gcc/config/mips/mips.c
View file @
3f1f8d8c
...
...
@@ -2413,6 +2413,7 @@ init_cumulative_args (cum, fntype, libname)
tree
fntype
;
/* tree ptr for function decl */
rtx
libname
;
/* SYMBOL_REF of library name or 0 */
{
static
CUMULATIVE_ARGS
zero_cum
;
tree
param
,
next_param
;
if
(
TARGET_DEBUG_E_MODE
)
...
...
@@ -2430,9 +2431,7 @@ init_cumulative_args (cum, fntype, libname)
}
}
cum
->
gp_reg_found
=
0
;
cum
->
arg_number
=
0
;
cum
->
arg_words
=
0
;
*
cum
=
zero_cum
;
/* Determine if this function has variable arguments. This is
indicated by the last argument being 'void_type_mode' if there
...
...
@@ -2461,7 +2460,7 @@ function_arg_advance (cum, mode, type, named)
{
if
(
TARGET_DEBUG_E_MODE
)
fprintf
(
stderr
,
"function_adv( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d )
\n
"
,
"function_adv( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d )
\n
\n
"
,
cum
->
gp_reg_found
,
cum
->
arg_number
,
cum
->
arg_words
,
GET_MODE_NAME
(
mode
),
type
,
named
);
...
...
@@ -2512,8 +2511,12 @@ function_arg (cum, mode, type, named)
tree
type
;
/* type of the argument or 0 if lib support */
int
named
;
/* != 0 for normal args, == 0 for ... args */
{
rtx
ret
;
int
regbase
=
-
1
;
int
bias
=
0
;
int
struct_p
=
((
type
!=
(
tree
)
0
)
&&
(
TREE_CODE
(
type
)
==
RECORD_TYPE
||
TREE_CODE
(
type
)
==
UNION_TYPE
));
if
(
TARGET_DEBUG_E_MODE
)
fprintf
(
stderr
,
...
...
@@ -2567,18 +2570,42 @@ function_arg (cum, mode, type, named)
if
(
cum
->
arg_words
>=
MAX_ARGS_IN_REGISTERS
)
{
if
(
TARGET_DEBUG_E_MODE
)
fprintf
(
stderr
,
"<stack>
\n
"
);
fprintf
(
stderr
,
"<stack>
%s
\n
"
,
struct_p
?
", [struct]"
:
"
"
);
ret
urn
0
;
ret
=
(
rtx
)
0
;
}
else
{
if
(
regbase
==
-
1
)
abort
();
if
(
regbase
==
-
1
)
abort
();
ret
=
gen_rtx
(
REG
,
mode
,
regbase
+
cum
->
arg_words
+
bias
);
if
(
TARGET_DEBUG_E_MODE
)
fprintf
(
stderr
,
"%s
\n
"
,
reg_names
[
regbase
+
cum
->
arg_words
+
bias
]);
if
(
TARGET_DEBUG_E_MODE
)
fprintf
(
stderr
,
"%s%s
\n
"
,
reg_names
[
regbase
+
cum
->
arg_words
+
bias
],
struct_p
?
", [struct]"
:
""
);
/* The following is a hack in order to pass 1 byte structures
the same way that the MIPS compiler does (namely by passing
the structure in the high byte or half word of the register).
This also makes varargs work. If we have such a structure,
we save the adjustment RTL, and the call define expands will
emit them. For the VOIDmode argument (argument after the
last real argument, pass back a parallel vector holding each
of the adjustments. */
if
(
struct_p
&&
(
mode
==
QImode
||
mode
==
HImode
))
{
rtx
amount
=
GEN_INT
(
BITS_PER_WORD
-
GET_MODE_BITSIZE
(
mode
));
rtx
reg
=
gen_rtx
(
REG
,
SImode
,
regbase
+
cum
->
arg_words
+
bias
);
cum
->
adjust
[
cum
->
num_adjusts
++
]
=
gen_ashlsi3
(
reg
,
reg
,
amount
);
}
}
if
(
mode
==
VOIDmode
&&
cum
->
num_adjusts
>
0
)
ret
=
gen_rtx
(
PARALLEL
,
VOIDmode
,
gen_rtvec_v
(
cum
->
num_adjusts
,
cum
->
adjust
));
return
gen_rtx
(
REG
,
mode
,
regbase
+
cum
->
arg_words
+
bias
)
;
return
ret
;
}
...
...
@@ -4237,20 +4264,56 @@ mips_expand_prologue ()
{
int
regno
;
long
tsize
;
tree
fndecl
=
current_function_decl
;
/* current... is tooo long */
tree
fntype
=
TREE_TYPE
(
fndecl
);
tree
fnargs
=
(
TREE_CODE
(
fntype
)
!=
METHOD_TYPE
)
rtx
tmp_rtx
=
(
rtx
)
0
;
char
*
arg_name
=
(
char
*
)
0
;
tree
fndecl
=
current_function_decl
;
tree
fntype
=
TREE_TYPE
(
fndecl
);
tree
fnargs
=
(
TREE_CODE
(
fntype
)
!=
METHOD_TYPE
)
?
DECL_ARGUMENTS
(
fndecl
)
:
0
;
rtx
next_arg_reg
;
int
i
;
tree
next_arg
;
tree
cur_arg
;
rtx
tmp_rtx
=
(
rtx
)
0
;
char
*
arg_name
=
(
char
*
)
0
;
CUMULATIVE_ARGS
args_so_far
;
/* Determine the last argument, and get its name. */
INIT_CUMULATIVE_ARGS
(
args_so_far
,
fntype
,
(
rtx
)
0
);
regno
=
GP_ARG_FIRST
;
for
(
cur_arg
=
fnargs
;
cur_arg
!=
(
tree
)
0
;
cur_arg
=
next_arg
)
{
tree
type
=
DECL_ARG_TYPE
(
cur_arg
);
enum
machine_mode
passed_mode
=
TYPE_MODE
(
type
);
rtx
entry_parm
=
FUNCTION_ARG
(
args_so_far
,
passed_mode
,
DECL_ARG_TYPE
(
cur_arg
),
1
);
if
(
entry_parm
)
{
int
words
;
/* passed in a register, so will get homed automatically */
if
(
GET_MODE
(
entry_parm
)
==
BLKmode
)
words
=
(
int_size_in_bytes
(
type
)
+
3
)
/
4
;
else
words
=
(
GET_MODE_SIZE
(
GET_MODE
(
entry_parm
))
+
3
)
/
4
;
regno
=
REGNO
(
entry_parm
)
+
words
-
1
;
}
else
{
regno
=
GP_ARG_LAST
+
1
;
break
;
}
FUNCTION_ARG_ADVANCE
(
args_so_far
,
passed_mode
,
DECL_ARG_TYPE
(
cur_arg
),
1
);
next_arg
=
TREE_CHAIN
(
cur_arg
);
if
(
next_arg
==
(
tree
)
0
)
{
...
...
@@ -4261,52 +4324,39 @@ mips_expand_prologue ()
}
}
/* If this function is a varargs function, store any registers that
would normally hold arguments ($4 - $7) on the stack. */
if
((
TYPE_ARG_TYPES
(
fntype
)
!=
0
&&
(
TREE_VALUE
(
tree_last
(
TYPE_ARG_TYPES
(
fntype
)))
!=
void_type_node
))
||
(
arg_name
&&
(
strcmp
(
arg_name
,
"__builtin_va_alist"
)
==
0
||
strcmp
(
arg_name
,
"va_alist"
)
==
0
)))
{
tree
parm
;
/* In order to pass small structures by value in registers
compatibly with the MIPS compiler, we need to shift the value
into the high part of the register. Function_arg has encoded a
PARALLEL rtx, holding a vector of adjustments to be made as the
next_arg_reg variable, so we split up the insns, and emit them
separately. */
regno
=
GP_ARG_FIRST
;
INIT_CUMULATIVE_ARGS
(
args_so_far
,
fntype
,
(
rtx
)
0
);
next_arg_reg
=
FUNCTION_ARG
(
args_so_far
,
VOIDmode
,
void_type_node
,
1
);
if
(
next_arg_reg
!=
(
rtx
)
0
&&
GET_CODE
(
next_arg_reg
)
==
PARALLEL
)
{
rtvec
adjust
=
XVEC
(
next_arg_reg
,
0
);
int
num
=
GET_NUM_ELEM
(
adjust
);
for
(
parm
=
fnargs
;
(
parm
&&
(
regno
<=
GP_ARG_LAST
));
parm
=
TREE_CHAIN
(
parm
)
)
for
(
i
=
0
;
i
<
num
;
i
++
)
{
rtx
entry_parm
;
enum
machine_mode
passed_mode
;
tree
type
;
type
=
DECL_ARG_TYPE
(
parm
);
passed_mode
=
TYPE_MODE
(
type
);
entry_parm
=
FUNCTION_ARG
(
args_so_far
,
passed_mode
,
DECL_ARG_TYPE
(
parm
),
1
);
if
(
entry_parm
)
{
int
words
;
/* passed in a register, so will get homed automatically */
if
(
GET_MODE
(
entry_parm
)
==
BLKmode
)
words
=
(
int_size_in_bytes
(
type
)
+
3
)
/
4
;
else
words
=
(
GET_MODE_SIZE
(
GET_MODE
(
entry_parm
))
+
3
)
/
4
;
regno
=
REGNO
(
entry_parm
)
+
words
-
1
;
}
else
{
regno
=
GP_ARG_LAST
+
1
;
break
;
}
rtx
pattern
=
RTVEC_ELT
(
adjust
,
i
);
if
(
GET_CODE
(
pattern
)
!=
SET
||
GET_CODE
(
SET_SRC
(
pattern
))
!=
ASHIFT
)
abort_with_insn
(
pattern
,
"Insn is not a shift"
);
FUNCTION_ARG_ADVANCE
(
args_so_far
,
passed_mode
,
DECL_ARG_TYPE
(
parm
),
1
);
PUT_CODE
(
SET_SRC
(
pattern
),
ASHIFTRT
);
emit_insn
(
pattern
);
}
}
/* If this function is a varargs function, store any registers that
would normally hold arguments ($4 - $7) on the stack. */
if
((
TYPE_ARG_TYPES
(
fntype
)
!=
0
&&
(
TREE_VALUE
(
tree_last
(
TYPE_ARG_TYPES
(
fntype
)))
!=
void_type_node
))
||
(
arg_name
!=
(
char
*
)
0
&&
((
arg_name
[
0
]
==
'_'
&&
strcmp
(
arg_name
,
"__builtin_va_alist"
)
==
0
)
||
(
arg_name
[
0
]
==
'v'
&&
strcmp
(
arg_name
,
"va_alist"
)
==
0
))))
{
for
(;
regno
<=
GP_ARG_LAST
;
regno
++
)
{
rtx
ptr
=
stack_pointer_rtx
;
...
...
gcc/config/mips/mips.h
View file @
3f1f8d8c
...
...
@@ -483,7 +483,7 @@ while (0)
/* Print subsidiary information on the compiler version in use. */
#define MIPS_VERSION "[AL 1.1, MM 3
2
]"
#define MIPS_VERSION "[AL 1.1, MM 3
3
]"
#ifndef MACHINE_TYPE
#define MACHINE_TYPE "BSD Mips"
...
...
@@ -1809,9 +1809,12 @@ extern struct mips_frame_info current_frame_info;
*/
typedef
struct
mips_args
{
int
gp_reg_found
;
int
arg_number
;
int
arg_words
;
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
num_adjusts
;
/* number of adjustments made */
/* Adjustments made to args pass in regs. */
struct
rtx_def
*
adjust
[
MAX_ARGS_IN_REGISTERS
];
}
CUMULATIVE_ARGS
;
/* Initialize a variable CUM of type CUMULATIVE_ARGS
...
...
@@ -3525,3 +3528,15 @@ while (0)
#define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK)
#define MIPS_MARK_STAB(code) ((code)+CODE_MASK)
#define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK)
/* Default definitions for size_t and ptrdiff_t. */
#ifndef SIZE_TYPE
#define SIZE_TYPE "unsigned int"
#endif
#ifndef PTRDIFF_TYPE
#define PTRDIFF_TYPE "int"
#endif
gcc/config/mips/mips.md
View file @
3f1f8d8c
...
...
@@ -4043,17 +4043,41 @@ move\\t%0,%z4\\n\\
(define_expand "call"
[
(parallel
[
(call (match_operand 0 "memory_operand" "m")
(match_operand 1 "" "i"))
(clobber (match_operand 2 "" ""))])] ;; overwrite op2 with $31
(clobber (reg:SI 31))
(use (match_operand 2 "" "")) ;; next_arg_reg
(use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
""
"
{
rtx addr;
operands
[
2
]
= gen_rtx (REG, SImode, GP_REG_FIRST + 31);
if (operands
[
0
]
) /
* eliminate unused code warnings *
/
{
addr = XEXP (operands
[
0
]
, 0);
if (GET_CODE (addr) != REG && !CONSTANT_ADDRESS_P (addr))
XEXP (operands
[
0
]
, 0) = force_reg (FUNCTION_MODE, addr);
/* In order to pass small structures by value in registers
compatibly with the MIPS compiler, we need to shift the value
into the high part of the register. Function_arg has encoded
a PARALLEL rtx, holding a vector of adjustments to be made
as the next_arg_reg variable, so we split up the insns,
and emit them separately. */
if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
{
rtvec adjust = XVEC (operands[2], 0);
int num = GET_NUM_ELEM (adjust);
int i;
for (i = 0; i < num; i++)
emit_insn (RTVEC_ELT (adjust, i));
}
addr = XEXP (operands
[
0
]
, 0);
if (GET_CODE (addr) != REG && !CONSTANT_ADDRESS_P (addr))
XEXP (operands
[
0
]
, 0) = force_reg (FUNCTION_MODE, addr);
emit_call_insn (gen_call_internal (operands[0], operands[1],
gen_rtx (REG, Pmode, GP_REG_FIRST + 31)));
DONE;
}
}")
(define_insn "call_internal"
...
...
@@ -4071,15 +4095,13 @@ move\\t%0,%z4\\n\\
else if (GET_CODE (target) == CONST_INT)
{
operands
[
0
]
= target;
operands
[
1
]
= gen_rtx (REG, SImode, GP_REG_FIRST + 31);
return
\"
%
*
%
[
li\\t%@,%0\\n\\tjal\\t%1,%@%
]
\"
;
return
\"
%
*
%
[
li\\t%@,%0\\n\\tjal\\t%2,%@%
]
\"
;
}
else
{
operands
[
0
]
= target;
operands
[
1
]
= gen_rtx (REG, SImode, GP_REG_FIRST + 31);
return
\"
%
*
jal
\\
t%1,%0
\"
;
return
\"
%
*
jal
\\
t%2,%0
\"
;
}
}"
[
(set_attr "type" "call")
...
...
@@ -4092,17 +4114,42 @@ move\\t%0,%z4\\n\\
[
(parallel
[
(set (match_operand 0 "register_operand" "=df")
(call (match_operand 1 "memory_operand" "m")
(match_operand 2 "" "i")))
(clobber (match_operand 3 "" ""))])] ;; overwrite op3 with $31
(clobber (reg:SI 31))
(use (match_operand 3 "" ""))])] ;; next_arg_reg
""
"
{
rtx addr;
operands
[
3
]
= gen_rtx (REG, SImode, GP_REG_FIRST + 31);
if (operands
[
0
]
) /
* eliminate unused code warning *
/
{
addr = XEXP (operands
[
1
]
, 0);
if (GET_CODE (addr) != REG && !CONSTANT_ADDRESS_P (addr))
XEXP (operands
[
1
]
, 0) = force_reg (FUNCTION_MODE, addr);
/* In order to pass small structures by value in registers
compatibly with the MIPS compiler, we need to shift the value
into the high part of the register. Function_arg has encoded
a PARALLEL rtx, holding a vector of adjustments to be made
as the next_arg_reg variable, so we split up the insns,
and emit them separately. */
if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
{
rtvec adjust = XVEC (operands[3], 0);
int num = GET_NUM_ELEM (adjust);
int i;
for (i = 0; i < num; i++)
emit_insn (RTVEC_ELT (adjust, i));
}
emit_call_insn (gen_call_value_internal (operands[0], operands[1], operands[2],
gen_rtx (REG, Pmode, GP_REG_FIRST + 31)));
DONE;
}
addr = XEXP (operands
[
1
]
, 0);
if (GET_CODE (addr) != REG && !CONSTANT_ADDRESS_P (addr))
XEXP (operands
[
1
]
, 0) = force_reg (FUNCTION_MODE, addr);
}")
(define_insn "call_value_internal"
...
...
@@ -4121,15 +4168,13 @@ move\\t%0,%z4\\n\\
else if (GET_CODE (target) == CONST_INT)
{
operands
[
1
]
= target;
operands
[
2
]
= gen_rtx (REG, SImode, GP_REG_FIRST + 31);
return
\"
%
*
%
[
li\\t%@,%1\\n\\tjal\\t%2,%@%
]
\"
;
return
\"
%
*
%
[
li\\t%@,%1\\n\\tjal\\t%3,%@%
]
\"
;
}
else
{
operands
[
1
]
= target;
operands
[
2
]
= gen_rtx (REG, SImode, GP_REG_FIRST + 31);
return
\"
%
*
jal
\\
t%2,%1
\"
;
return
\"
%
*
jal
\\
t%3,%1
\"
;
}
}"
[
(set_attr "type" "call")
...
...
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