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
6a4cee5f
Commit
6a4cee5f
authored
Mar 04, 1996
by
Michael Meissner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add attribute((longcall)) support
From-SVN: r11416
parent
de3a68a1
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
124 additions
and
71 deletions
+124
-71
gcc/config/rs6000/rs6000.c
+44
-6
gcc/config/rs6000/rs6000.h
+7
-8
gcc/config/rs6000/rs6000.md
+73
-57
No files found.
gcc/config/rs6000/rs6000.c
View file @
6a4cee5f
...
...
@@ -939,6 +939,10 @@ init_cumulative_args (cum, fntype, libname, incoming)
&&
lookup_attribute
(
"dllimport"
,
TYPE_ATTRIBUTES
(
fntype
)))
cum
->
call_cookie
=
CALL_NT_DLLIMPORT
;
/* Also check for longcall's */
else
if
(
fntype
&&
lookup_attribute
(
"longcall"
,
TYPE_ATTRIBUTES
(
fntype
)))
cum
->
call_cookie
=
CALL_LONG
;
if
(
TARGET_DEBUG_ARG
)
{
fprintf
(
stderr
,
"
\n
init_cumulative_args:"
);
...
...
@@ -952,9 +956,12 @@ init_cumulative_args (cum, fntype, libname, incoming)
if
(
abi
==
ABI_V4
&&
incoming
)
fprintf
(
stderr
,
" varargs = %d, "
,
cum
->
varargs_offset
);
if
(
cum
->
call_cookie
==
CALL_NT_DLLIMPORT
)
if
(
cum
->
call_cookie
&
CALL_NT_DLLIMPORT
)
fprintf
(
stderr
,
" dllimport,"
);
if
(
cum
->
call_cookie
&
CALL_LONG
)
fprintf
(
stderr
,
" longcall,"
);
fprintf
(
stderr
,
" proto = %d, nargs = %d
\n
"
,
cum
->
prototype
,
cum
->
nargs_prototype
);
}
...
...
@@ -1089,12 +1096,10 @@ function_arg (cum, mode, type, named)
&&
cum
->
nargs_prototype
<
0
&&
type
&&
(
cum
->
prototype
||
TARGET_NO_PROTOTYPE
))
{
if
(
cum
->
call_cookie
!=
CALL_NORMAL
)
abort
();
return
GEN_INT
((
cum
->
fregno
==
FP_ARG_MIN_REG
)
return
GEN_INT
(
cum
->
call_cookie
|
((
cum
->
fregno
==
FP_ARG_MIN_REG
)
?
CALL_V4_SET_FP_ARGS
:
CALL_V4_CLEAR_FP_ARGS
);
:
CALL_V4_CLEAR_FP_ARGS
)
);
}
return
GEN_INT
(
cum
->
call_cookie
);
...
...
@@ -4248,6 +4253,11 @@ rs6000_valid_type_attribute_p (type, attributes, identifier, args)
&&
TREE_CODE
(
type
)
!=
TYPE_DECL
)
return
0
;
/* Longcall attribute says that the function is not within 2**26 bytes
of the current function, and to do an indirect call. */
if
(
is_attribute_p
(
"longcall"
,
identifier
))
return
(
args
==
NULL_TREE
);
if
(
DEFAULT_ABI
==
ABI_NT
)
{
/* Stdcall attribute says callee is responsible for popping arguments
...
...
@@ -4324,6 +4334,34 @@ rs6000_dll_import_ref (call_ref)
return
reg2
;
}
/* Return a reference suitable for calling a function with the longcall attribute. */
struct
rtx_def
*
rs6000_longcall_ref
(
call_ref
)
rtx
call_ref
;
{
char
*
call_name
;
int
len
;
char
*
p
;
rtx
reg1
,
reg2
;
tree
node
;
if
(
GET_CODE
(
call_ref
)
!=
SYMBOL_REF
)
return
call_ref
;
/* System V adds '.' to the internal name, so skip them. */
call_name
=
XSTR
(
call_ref
,
0
);
if
(
*
call_name
==
'.'
)
{
while
(
*
call_name
==
'.'
)
call_name
++
;
node
=
get_identifier
(
call_name
);
call_ref
=
gen_rtx
(
SYMBOL_REF
,
VOIDmode
,
IDENTIFIER_POINTER
(
node
));
}
return
force_reg
(
Pmode
,
call_ref
);
}
/* A C statement or statements to switch to the appropriate section
for output of RTX in mode MODE. You can assume that RTX is some
...
...
gcc/config/rs6000/rs6000.h
View file @
6a4cee5f
...
...
@@ -1246,13 +1246,11 @@ extern int rs6000_sysv_varargs_p;
#define FP_ARG_RETURN FP_ARG_MIN_REG
/* Flags for the call/call_value rtl operations set up by function_arg */
enum
rs6000_call_cookie
{
CALL_V4_SET_FP_ARGS
=
-
1
,
/* V4, FP args passed */
CALL_NORMAL
=
0
,
/* no special processing */
CALL_V4_CLEAR_FP_ARGS
=
1
,
/* V4, no FP args passed */
CALL_NT_DLLIMPORT
=
2
/* NT, this is a DLL import call */
};
#define CALL_NORMAL 0x00000000
/* no special processing */
#define CALL_NT_DLLIMPORT 0x00000001
/* NT, this is a DLL import call */
#define CALL_V4_CLEAR_FP_ARGS 0x00000002
/* V.4, no FP args passed */
#define CALL_V4_SET_FP_ARGS 0x00000004
/* V.4, FP args were passed */
#define CALL_LONG 0x00000008
/* always call indirect */
/* Define cutoff for using external functions to save floating point */
#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63)
...
...
@@ -1293,7 +1291,7 @@ typedef struct rs6000_args
int
orig_nargs
;
/* Original value of nargs_prototype */
int
varargs_offset
;
/* offset of the varargs save area */
int
prototype
;
/* Whether a prototype was defined */
enum
rs6000_call_cookie
call_cookie
;
/* Do special things for this call */
int
call_cookie
;
/* Do special things for this call */
}
CUMULATIVE_ARGS
;
/* Define intermediate macro to compute the size (in registers) of an argument
...
...
@@ -2879,3 +2877,4 @@ extern int rs6000_valid_decl_attribute_p ();
extern
int
rs6000_valid_type_attribute_p
();
extern
void
rs6000_set_default_type_attributes
();
extern
struct
rtx_def
*
rs6000_dll_import_ref
();
extern
struct
rtx_def
*
rs6000_longcall_ref
();
gcc/config/rs6000/rs6000.md
View file @
6a4cee5f
...
...
@@ -6541,27 +6541,29 @@
(define_insn "call_indirect_aix"
[
(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
(match_operand 1 "const_int_operand" "n"))
(use (match_operand 2 "const_int_operand" "
O
"))
(use (match_operand 2 "const_int_operand" "
n
"))
(use (match_operand 3 "offsettable_addr_operand" "p"))
(use (match_operand 4 "register_operand" "r"))
(clobber (match_operand 5 "register_operand" "=r"))
(clobber (match_scratch:SI 6 "=&r"))
(clobber (match_scratch:SI 7 "=l"))]
"DEFAULT_ABI == ABI_AIX"
"{st|stw} %4,%a3
\;
{l|lwz} %6,0(%0)
\;
{l|lwz} %4,4(%0);
\;
mt%7 %6
\;
{l|lwz} %5,8(%0)
\;
{brl|blrl}
\;
{l|lwz} %4,%a3"
"DEFAULT_ABI == ABI_AIX
&& (INTVAL (operands
[
2
]
) == CALL_NORMAL || (INTVAL (operands
[
2
]
) & CALL_LONG) != 0)"
"{st|stw} %4,%a3
\;
{l|lwz} %6,0(%0)
\;
{l|lwz} %4,4(%0)
\;
mt%7 %6
\;
{l|lwz} %5,8(%0)
\;
{brl|blrl}
\;
{l|lwz} %4,%a3"
[
(set_attr "length" "28")
]
)
(define_insn "call_value_indirect_aix"
[
(set (match_operand 0 "register_operand" "fg")
(call (mem:SI (match_operand:SI 1 "register_operand" "b"))
(match_operand 2 "const_int_operand" "n")))
(use (match_operand 3 "const_int_operand" "
O
"))
(use (match_operand 3 "const_int_operand" "
n
"))
(use (match_operand 4 "offsettable_addr_operand" "p"))
(use (match_operand 5 "register_operand" "r"))
(clobber (match_operand 6 "register_operand" "=r"))
(clobber (match_scratch:SI 7 "=&r"))
(clobber (match_scratch:SI 8 "=l"))]
"DEFAULT_ABI == ABI_AIX"
"DEFAULT_ABI == ABI_AIX
&& (INTVAL (operands
[
3
]
) == CALL_NORMAL || (INTVAL (operands
[
3
]
) & CALL_LONG) != 0)"
"{st|stw} %5,%a4
\;
{l|lwz} %7,0(%1)
\;
{l|lwz} %5,4(%1);
\;
mt%8 %7
\;
{l|lwz} %6,8(%1)
\;
{brl|blrl}
\;
{l|lwz} %5,%a4"
[
(set_attr "length" "28")
]
)
...
...
@@ -6582,12 +6584,13 @@
(define_insn "call_indirect_nt"
[
(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
(match_operand 1 "const_int_operand" "n"))
(use (match_operand 2 "const_int_operand" "
O
"))
(use (match_operand 2 "const_int_operand" "
n
"))
(use (match_operand 3 "offsettable_addr_operand" "p"))
(use (match_operand 4 "register_operand" "r"))
(clobber (match_scratch:SI 5 "=&r"))
(clobber (match_scratch:SI 6 "=l"))]
"DEFAULT_ABI == ABI_NT"
"DEFAULT_ABI == ABI_NT
&& (INTVAL (operands
[
2
]
) == CALL_NORMAL || (INTVAL (operands
[
2
]
) & CALL_LONG) != 0)"
"{st|stw} %4,%a3
\;
{l|lwz} %5,0(%0)
\;
{l|lwz} %4,4(%0)
\;
mt%6 %5
\;
{brl|blrl}
\;
{l|lwz} %4,%a3"
[
(set_attr "length" "24")
]
)
...
...
@@ -6595,12 +6598,13 @@
[
(set (match_operand 0 "register_operand" "fg")
(call (mem:SI (match_operand:SI 1 "register_operand" "b"))
(match_operand 2 "const_int_operand" "n")))
(use (match_operand 3 "const_int_operand" "
O
"))
(use (match_operand 3 "const_int_operand" "
n
"))
(use (match_operand 4 "offsettable_addr_operand" "p"))
(use (match_operand 5 "register_operand" "r"))
(clobber (match_scratch:SI 6 "=&r"))
(clobber (match_scratch:SI 7 "=l"))]
"DEFAULT_ABI == ABI_NT"
"DEFAULT_ABI == ABI_NT
&& (INTVAL (operands
[
3
]
) == CALL_NORMAL || (INTVAL (operands
[
3
]
) & CALL_LONG) != 0)"
"{st|stw} %5,%a4
\;
{l|lwz} %6,0(%1)
\;
{l|lwz} %5,4(%1)
\;
mt%7 %6
\;
{brl|blrl}
\;
{l|lwz} %5,%a4"
[
(set_attr "length" "24")
]
)
...
...
@@ -6617,11 +6621,11 @@
"DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC"
"
*
{
if (INTVAL (operands
[
2
]
)
> 0
)
return
\"
creqv 6,6,6
\;
{brl|blrl}
\"
;
if (INTVAL (operands
[
2
]
)
& CALL_V4_SET_FP_ARGS
)
output_asm_insn (
\"
crxor 6,6,6
\"
, operands)
;
else if (INTVAL (operands
[
2
]
)
< 0
)
return
\"
crxor 6,6,6
\;
{brl|blrl}
\"
;
else if (INTVAL (operands
[
2
]
)
& CALL_V4_CLEAR_FP_ARGS
)
output_asm_insn (
\"
creqv 6,6,6
\"
, operands)
;
return
\"
{brl|blrl}
\"
;
}"
...
...
@@ -6636,11 +6640,11 @@
"DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC"
"
*
{
if (INTVAL (operands
[
3
]
)
> 0
)
return
\"
creqv 6,6,6
\;
{brl|blrl}
\"
;
if (INTVAL (operands
[
3
]
)
& CALL_V4_SET_FP_ARGS
)
output_asm_insn (
\"
crxor 6,6,6
\"
, operands)
;
else if (INTVAL (operands
[
3
]
)
< 0
)
return
\"
crxor 6,6,6
\;
{brl|blrl}
\"
;
else if (INTVAL (operands
[
3
]
)
& CALL_V4_CLEAR_FP_ARGS
)
output_asm_insn (
\"
creqv 6,6,6
\"
, operands)
;
return
\"
{brl|blrl}
\"
;
}"
...
...
@@ -6662,14 +6666,18 @@
/
* Convert NT DLL imports into an indirect call. *
/
if (GET_CODE (operands
[
0
]
) == SYMBOL_REF
&&
INTVAL (operands
[
2
]
) == (int)CALL_NT_DLLIMPORT
)
&&
(INTVAL (operands
[
2
]
) & CALL_NT_DLLIMPORT) != 0
)
{
operands
[
0
]
= rs6000_dll_import_ref (operands
[
0
]
);
operands
[
2
]
= GEN_INT ((int)CALL_NORMAL);
}
if (GET_CODE (operands
[
0
]
) != SYMBOL_REF)
if (GET_CODE (operands
[
0
]
) != SYMBOL_REF
|| (INTVAL (operands
[
2
]
) & CALL_LONG) != 0)
{
if (INTVAL (operands
[
2
]
) & CALL_LONG)
operands
[
0
]
= rs6000_longcall_ref (operands
[
0
]
);
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC)
emit_call_insn (gen_call_indirect_sysv (force_reg (Pmode, operands[0]),
operands[1], operands[2]));
...
...
@@ -6717,14 +6725,18 @@
/
* Convert NT DLL imports into an indirect call. *
/
if (GET_CODE (operands
[
1
]
) == SYMBOL_REF
&&
INTVAL (operands
[
3
]
) == (int)CALL_NT_DLLIMPORT
)
&&
(INTVAL (operands
[
3
]
) & CALL_NT_DLLIMPORT) != 0
)
{
operands
[
1
]
= rs6000_dll_import_ref (operands
[
1
]
);
operands
[
3
]
= GEN_INT ((int)CALL_NORMAL);
}
if (GET_CODE (operands
[
1
]
) != SYMBOL_REF)
if (GET_CODE (operands
[
1
]
) != SYMBOL_REF
|| (INTVAL (operands
[
3
]
) & CALL_LONG) != 0)
{
if (INTVAL (operands
[
2
]
) & CALL_LONG)
operands
[
1
]
= rs6000_longcall_ref (operands
[
1
]
);
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC)
emit_call_insn (gen_call_value_indirect_sysv (operands[0], operands[1],
operands[2], operands[3]));
...
...
@@ -6769,14 +6781,14 @@
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
""
"
INTVAL (operands
[
2
]
) != CALL_LONG
"
"
*
{
switch ((enum rs6000_call_cookie)INTVAL (operands
[
2
]
)
)
{
case CALL_V4_SET_FP_ARGS: output_asm_insn (
\"
crxor 6,6,6
\"
, operands); break;
case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (
\"
creqv 6,6,6
\"
, operands); break;
}
if (INTVAL (operands
[
2
]
) & CALL_V4_SET_FP_ARGS
)
output_asm_insn (
\"
crxor 6,6,6
\"
, operands);
else if (INTVAL (operands
[
2
]
) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn (
\"
creqv 6,6,6
\"
, operands);
return
\"
bl %z0
\"
;
}"
...
...
@@ -6794,18 +6806,19 @@
(match_operand 1 "" "fg,fg"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
"DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT"
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
&& INTVAL (operands
[
2
]
) != CALL_LONG"
"
*
{
/
* Indirect calls should go through call_indirect *
/
if (GET_CODE (operands
[
0
]
) == REG)
abort ();
switch ((enum rs6000_call_cookie)INTVAL (operands
[
2
]
)
)
{
case CALL_V4_SET_FP_ARGS: output_asm_insn (
\"
crxor 6,6,6
\"
, operands); break;
case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (
\"
creqv 6,6,6
\"
, operands); break;
}
if (INTVAL (operands
[
2
]
) & CALL_V4_SET_FP_ARGS
)
output_asm_insn (
\"
crxor 6,6,6
\"
, operands);
else if (INTVAL (operands
[
2
]
) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn (
\"
creqv 6,6,6
\"
, operands);
return (TARGET_WINDOWS_NT) ?
\"
bl %z0
\;
.znop %z0
\"
:
\"
bl %z0
\;
%.
\"
;
}"
...
...
@@ -6816,18 +6829,19 @@
(match_operand 1 "" "fg,fg"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
"DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4"
"(DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4)
&& INTVAL (operands
[
2
]
) != CALL_LONG"
"
*
{
/
* Indirect calls should go through call_indirect *
/
if (GET_CODE (operands
[
0
]
) == REG)
abort ();
switch ((enum rs6000_call_cookie)INTVAL (operands
[
2
]
)
)
{
case CALL_V4_SET_FP_ARGS: output_asm_insn (
\"
crxor 6,6,6
\"
, operands); break;
case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (
\"
creqv 6,6,6
\"
, operands); break;
}
if (INTVAL (operands
[
2
]
) & CALL_V4_SET_FP_ARGS
)
output_asm_insn (
\"
crxor 6,6,6
\"
, operands);
else if (INTVAL (operands
[
2
]
) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn (
\"
creqv 6,6,6
\"
, operands);
return
\"
bl %z0
\"
;
}"
...
...
@@ -6839,14 +6853,14 @@
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
""
"
INTVAL (operands
[
3
]
) != CALL_LONG
"
"
*
{
switch ((enum rs6000_call_cookie)INTVAL (operands
[
3
]
)
)
{
case CALL_V4_SET_FP_ARGS: output_asm_insn (
\"
crxor 6,6,6
\"
, operands); break;
case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (
\"
creqv 6,6,6
\"
, operands); break;
}
if (INTVAL (operands
[
3
]
) & CALL_V4_SET_FP_ARGS
)
output_asm_insn (
\"
crxor 6,6,6
\"
, operands);
else if (INTVAL (operands
[
3
]
) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn (
\"
creqv 6,6,6
\"
, operands);
return
\"
bl %z1
\"
;
}"
...
...
@@ -6858,18 +6872,19 @@
(match_operand 2 "" "fg,fg")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
"DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT"
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
&& INTVAL (operands
[
3
]
) != CALL_LONG"
"
*
{
/
* This should be handled by call_value_indirect *
/
if (GET_CODE (operands
[
1
]
) == REG)
abort ();
switch ((enum rs6000_call_cookie)INTVAL (operands
[
3
]
)
)
{
case CALL_V4_SET_FP_ARGS: output_asm_insn (
\"
crxor 6,6,6
\"
, operands); break;
case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (
\"
creqv 6,6,6
\"
, operands); break;
}
if (INTVAL (operands
[
3
]
) & CALL_V4_SET_FP_ARGS
)
output_asm_insn (
\"
crxor 6,6,6
\"
, operands);
else if (INTVAL (operands
[
3
]
) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn (
\"
creqv 6,6,6
\"
, operands);
return (TARGET_WINDOWS_NT) ?
\"
bl %z1
\;
.znop %z1
\"
:
\"
bl %z1
\;
%.
\"
;
}"
...
...
@@ -6881,18 +6896,19 @@
(match_operand 2 "" "fg,fg")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
"DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4"
"(DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4)
&& INTVAL (operands
[
3
]
) != CALL_LONG"
"
*
{
/
* This should be handled by call_value_indirect *
/
if (GET_CODE (operands
[
1
]
) == REG)
abort ();
switch ((enum rs6000_call_cookie)INTVAL (operands
[
3
]
)
)
{
case CALL_V4_SET_FP_ARGS: output_asm_insn (
\"
crxor 6,6,6
\"
, operands); break;
case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (
\"
creqv 6,6,6
\"
, operands); break;
}
if (INTVAL (operands
[
3
]
) & CALL_V4_SET_FP_ARGS
)
output_asm_insn (
\"
crxor 6,6,6
\"
, operands);
else if (INTVAL (operands
[
3
]
) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn (
\"
creqv 6,6,6
\"
, operands);
return
\"
bl %z1
\"
;
}"
...
...
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