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
c27ba912
Commit
c27ba912
authored
Feb 29, 2000
by
Dmitri Makarov
Committed by
Nick Clifton
Feb 29, 2000
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Apply Dimitri Makarov's patch to import attribute short_call and #pragma
long_calls, no_long_calls. From-SVN: r32248
parent
8aacf016
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
405 additions
and
108 deletions
+405
-108
gcc/ChangeLog
+69
-0
gcc/config/arm/arm-protos.h
+4
-0
gcc/config/arm/arm.c
+190
-72
gcc/config/arm/arm.h
+70
-4
gcc/config/arm/arm.md
+18
-12
gcc/config/arm/elf.h
+1
-0
gcc/config/arm/pe.c
+5
-6
gcc/config/arm/pe.h
+10
-14
gcc/extend.texi
+11
-0
gcc/invoke.texi
+27
-0
No files found.
gcc/ChangeLog
View file @
c27ba912
2000
-
02
-
28
Dmitri
Makarov
<
dim
@windriver
.
com
>
*
extend
.
texi
:
Document
ARM
'
s
support
for
long
/
short
calls
.
*
invoke
.
texi
:
Document
ARM
'
s
-
mlong
-
calls
command
line
switch
.
*
config
/
arm
/
arm
-
protos
.
h
(
arm_is_longcall_p
)
:
Add
prototype
.
(
arm_encode_call_attribute
)
:
Add
prototype
.
(
arm_set_default_type_attribute
)
:
Add
prototype
.
(
arm_strip_name_encoding
)
:
Add
prototype
.
*
config
/
arm
/
arm
.
c
(
arm_init_cumulative_args
)
:
replace
initialisation
og
'
long_calls
'
field
with
initialisation
of
'
call_cookie
'
field
.
(
enum
arm_pragma_enum
)
:
New
enum
.
(
arm_pragma_long_calls
)
:
New
static
variable
.
(
arm_process_pragma
)
:
Also
process
"#pragma long_calls_off"
.
(
arm_valid_type_attribute_p
)
:
Accept
short_call
attribute
.
(
arm_comp_type_attributes
)
:
Check
long
/
short
call
attributes
.
(
arm_encode_call_attribute
)
:
New
function
:
Encode
long_call
or
short_call
attribute
in
function
name
.
(
arm_set_default_type_attributes
)
:
New
function
:
Assign
default
attributes
to
newly
defined
type
.
(
current_file_function_operand
)
:
New
function
:
Return
true
if
the
symbol
is
a
function
which
has
already
been
compiled
.
(
arm_is_longcall_p
)
:
New
function
:
Return
true
if
the
indicated
function
should
be
called
via
a
long
call
.
(
arm_get_strip_length
)
:
New
function
.
Returns
number
of
prefix
characters
to
be
stripped
from
a
function
'
s
name
.
(
arm_strip_name_encoding
)
:
New
function
.
Strip
prefix
characters
from
a
function
'
s
name
.
*
config
/
arm
/
arm
.
h
(
CUMULATIVE_ARGS
)
:
Replace
'
long_call
'
field
with
'
call_cookie
'
.
(
SHORT_CALL_FAG_CHAR
)
:
Define
.
(
LONG_CALL_FAG_CHAR
)
:
Define
.
(
ENCODED_SHORT_CALL_ATTR_P
)
:
Define
.
(
ENCODED_LONG_CALL_ATTR_P
)
:
Define
.
(
ARM_NAME_ENCODING_LENGTHS
)
:
Define
.
(
STRIP_NAME_ENCODING
)
:
Define
.
(
ASM_OUTPUT_LABELREF
)
:
Define
,
and
use
to
strip
name
encoding
.
(
ARM_ENCODE_CALL_TYPE
)
:
Define
.
(
ENCODE_SECTION
)
:
Invoke
ARM_ENCODE_CALL_TYPE
.
(
ARM_DECLARE_FUNCTION_SIZE
)
:
Define
.
(
SET_DEFAULT_TYPE_ATTRIBUTES
)
:
Define
.
*
config
/
arm
/
arm
.
md
(
call
)
:
Call
arm_is_longcall_p
to
decide
if
a
long
call
is
needed
.
(
call_value
)
:
Ditto
.
(
call_symbol
)
:
Ditto
.
*
config
/
arm
/
elf
.
h
(
ASM_DECLARE_FUNCTION_SIZE
)
:
Add
invocation
of
ARM_DECLARE_FUNCTION_SIZE
.
*
config
/
arm
/
pe
.
h
(
ARM_PE_FLAG_CHAR
)
:
Define
.
(
SUBTARGET_NAME_ENCODING_LENGTHS
)
:
Define
.
(
ARM_STRIP_NAME_ENCODING
)
:
Undefine
.
(
STRIP_NAME_ENCODING
)
:
Undefine
.
(
ASM_OUTPUT_LABELREF
)
:
Use
arm_strip_name_encoding
.
(
ASM_DECLARE_FUNCTION_NAME
)
:
Ditto
.
(
ASM_OUTPUT_COMMON
)
:
Ditto
.
(
ASM_DECLARE_OBJECT_NAME
)
:
Ditto
.
*
config
/
arm
/
pe
.
c
(
arm_dllexport_name_p
)
:
Check
for
ARM_PE_FLAG_CHAR
.
(
arm_dllimport_name_p
)
:
Ditto
.
(
arm_mark_dllexport
)
:
Use
ARM_PE_FLAG_CHAR
.
(
arm_mark_dllimport
)
:
Ditto
.
Mon
Feb
28
22
:
11
:
12
2000
J
"orn Rennecke <amylaar@cygnus.co.uk>
* sh.h (DWARF_LINE_MIN_INSTR_LENGTH): Define.
...
...
gcc/config/arm/arm-protos.h
View file @
c27ba912
...
...
@@ -34,6 +34,7 @@ extern void output_ascii_pseudo_op PARAMS ((FILE *, unsigned char *, int));
extern
void
output_func_epilogue
PARAMS
((
int
));
extern
void
output_func_prologue
PARAMS
((
FILE
*
,
int
));
extern
int
use_return_insn
PARAMS
((
int
));
extern
const
char
*
arm_strip_name_encoding
PARAMS
((
const
char
*
));
#if defined AOF_ASSEMBLER
extern
void
aof_add_import
PARAMS
((
char
*
));
extern
char
*
aof_data_section
PARAMS
((
void
));
...
...
@@ -62,6 +63,9 @@ extern void arm_pe_encode_section_info PARAMS ((tree));
extern
tree
arm_pe_merge_machine_decl_attributes
PARAMS
((
tree
,
tree
));
extern
void
arm_pe_unique_section
PARAMS
((
tree
,
int
));
extern
int
arm_pe_valid_machine_decl_attribute
PARAMS
((
tree
,
tree
,
tree
,
tree
));
extern
void
arm_set_default_type_attributes
PARAMS
((
tree
));
extern
void
arm_encode_call_attribute
PARAMS
((
tree
,
char
));
extern
int
arm_pe_return_in_memory
PARAMS
((
tree
));
#endif
#ifdef RTX_CODE
...
...
gcc/config/arm/arm.c
View file @
c27ba912
...
...
@@ -40,19 +40,13 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
#include "recog.h"
#include "ggc.h"
#include "arm-protos.h"
/* The maximum number of insns skipped which will be conditionalised if
possible. */
static
int
max_insns_skipped
=
5
;
extern
FILE
*
asm_out_file
;
/* Some function declarations. */
#include "tm_p.h"
#ifndef Mmode
#define Mmode enum machine_mode
#endif
/* Some function declarations. */
static
HOST_WIDE_INT
int_log2
PARAMS
((
HOST_WIDE_INT
));
static
char
*
output_multi_immediate
PARAMS
((
rtx
*
,
char
*
,
char
*
,
int
,
HOST_WIDE_INT
));
static
int
arm_gen_constant
PARAMS
((
enum
rtx_code
,
Mmode
,
HOST_WIDE_INT
,
rtx
,
rtx
,
int
,
int
));
...
...
@@ -76,6 +70,12 @@ static enum arm_cond_code get_arm_condition_code PARAMS ((rtx));
static
int
const_ok_for_op
PARAMS
((
HOST_WIDE_INT
,
enum
rtx_code
));
static
void
arm_add_gc_roots
PARAMS
((
void
));
/* The maximum number of insns skipped which will be conditionalised if
possible. */
static
int
max_insns_skipped
=
5
;
extern
FILE
*
asm_out_file
;
/* True if we are currently building a constant table. */
int
making_const_table
;
...
...
@@ -1487,9 +1487,8 @@ arm_init_cumulative_args (pcum, fntype, libname, indirect)
int
indirect
ATTRIBUTE_UNUSED
;
{
/* On the ARM, the offset starts at 0. */
pcum
->
nregs
=
((
fntype
&&
aggregate_value_p
(
TREE_TYPE
(
fntype
)))
?
1
:
0
);
pcum
->
nregs
=
((
fntype
&&
aggregate_value_p
(
TREE_TYPE
(
fntype
)))
?
1
:
0
);
pcum
->
call_cookie
=
CALL_NORMAL
;
if
(
TARGET_LONG_CALLS
)
...
...
@@ -1534,73 +1533,37 @@ arm_function_arg (pcum, mode, type, named)
return
gen_rtx_REG
(
mode
,
pcum
->
nregs
);
}
/* Return 1 if the operand is a SYMBOL_REF for a function
known to be defined in the current compilation unit. */
static
int
current_file_function_operand
(
sym_ref
)
rtx
sym_ref
;
/* Encode the current state of the #pragma [no_]long_calls. */
typedef
enum
{
/* XXX FIXME - we need some way to determine if SYMREF has already been
compiled. We wanted to used SYMBOL_REF_FLAG but this is already in use
by the constant pool generation code. */
return
GET_CODE
(
sym_ref
)
==
SYMBOL_REF
&&
sym_ref
==
XEXP
(
DECL_RTL
(
current_function_decl
),
0
)
&&
!
DECL_WEAK
(
current_function_decl
);
}
/* Return non-zero if a 32 bit "long call" should be generated for this
call.
OFF
,
/* No #pramgma [no_]long_calls is in effect. */
LONG
,
/* #pragma long_calls is in effect. */
SHORT
/* #pragma no_long_calls is in effect. */
}
arm_pragma_enum
;
We generate a long call if the function is not declared
__attribute__ ((short_call),
static
arm_pragma_enum
arm_pragma_long_calls
=
OFF
;
AND:
(1) the function is declared __attribute__ ((long_call))
OR
(2) -mlong-calls is enabled and we don't know whether the target
function is declared in this file.
This function will typically be called by C fragments in the machine
description file. CALL_REF is the matched rtl operand. CALL_COOKIE
describes the value of the long_call and short_call attributes for
the called functiion. CALL_SYMBOL is used to distinguish between
two different callers of the function. It is set to 1 in the "call_symbol"
and "call_symbol_value" patterns in arm.md and to 0 in the "call" and
"call_value" patterns. This is because of the difference of SYM_REFs passed
from "call_symbol" and "call" patterns. */
/* Handle pragmas for compatibility with Intel's compilers.
FIXME: This is incomplete, since it does not handle all
the pragmas that the Intel compilers understand. */
int
arm_is_longcall_p
(
sym_ref
,
call_cookie
,
call_symbol
)
rtx
sym_ref
;
int
call_cookie
;
int
call_symbol
;
{
if
(
!
call_symbol
)
{
if
(
GET_CODE
(
sym_ref
)
!=
MEM
)
return
0
;
sym_ref
=
XEXP
(
sym_ref
,
0
);
}
if
(
GET_CODE
(
sym_ref
)
!=
SYMBOL_REF
)
return
0
;
if
(
call_cookie
&
CALL_SHORT
)
return
0
;
if
(
TARGET_LONG_CALLS
&&
flag_function_sections
)
return
1
;
if
(
current_file_function_operand
(
sym_ref
,
VOIDmode
))
arm_process_pragma
(
p_getc
,
p_ungetc
,
pname
)
int
(
*
p_getc
)
PARAMS
((
void
))
ATTRIBUTE_UNUSED
;
void
(
*
p_ungetc
)
PARAMS
((
int
))
ATTRIBUTE_UNUSED
;
char
*
pname
;
{
/* Should be pragma 'far' or equivalent for callx/balx here. */
if
(
strcmp
(
pname
,
"long_calls"
)
==
0
)
arm_pragma_long_calls
=
LONG
;
else
if
(
strcmp
(
pname
,
"no_long_calls"
)
==
0
)
arm_pragma_long_calls
=
SHORT
;
else
if
(
strcmp
(
pname
,
"long_calls_off"
)
==
0
)
arm_pragma_long_calls
=
OFF
;
else
return
0
;
return
(
call_cookie
&
CALL_LONG
)
||
TARGET_LONG_CALLS
;
return
1
;
}
/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
...
...
@@ -1624,7 +1587,7 @@ arm_valid_type_attribute_p (type, attributes, identifier, args)
call. */
if
(
is_attribute_p
(
"long_call"
,
identifier
))
return
(
args
==
NULL_TREE
);
/* Whereas these functions are always known to reside within the 26 bit
addressing range. */
if
(
is_attribute_p
(
"short_call"
,
identifier
))
...
...
@@ -1668,6 +1631,136 @@ arm_comp_type_attributes (type1, type2)
return
1
;
}
/* Encode long_call or short_call attribute by prefixing
symbol name in DECL with a special character FLAG. */
void
arm_encode_call_attribute
(
decl
,
flag
)
tree
decl
;
char
flag
;
{
char
*
str
=
XSTR
(
XEXP
(
DECL_RTL
(
decl
),
0
),
0
);
int
len
=
strlen
(
str
);
char
*
newstr
;
if
(
TREE_CODE
(
decl
)
!=
FUNCTION_DECL
)
return
;
/* Do not allow weak functions to be treated as short call. */
if
(
DECL_WEAK
(
decl
)
&&
flag
==
SHORT_CALL_FLAG_CHAR
)
return
;
if
(
ggc_p
)
newstr
=
ggc_alloc_string
(
NULL
,
len
+
2
);
else
newstr
=
permalloc
(
len
+
2
);
sprintf
(
newstr
,
"%c%s"
,
flag
,
str
);
XSTR
(
XEXP
(
DECL_RTL
(
decl
),
0
),
0
)
=
newstr
;
}
/* Assigns default attributes to newly defined type. This is used to
set short_call/long_call attributes for function types of
functions defined inside corresponding #pragma scopes. */
void
arm_set_default_type_attributes
(
type
)
tree
type
;
{
/* Add __attribute__ ((long_call)) to all functions, when
inside #pragma long_calls or __attribute__ ((short_call)),
when inside #pragma no_long_calls. */
if
(
TREE_CODE
(
type
)
==
FUNCTION_TYPE
||
TREE_CODE
(
type
)
==
METHOD_TYPE
)
{
tree
type_attr_list
,
attr_name
;
type_attr_list
=
TYPE_ATTRIBUTES
(
type
);
if
(
arm_pragma_long_calls
==
LONG
)
attr_name
=
get_identifier
(
"long_call"
);
else
if
(
arm_pragma_long_calls
==
SHORT
)
attr_name
=
get_identifier
(
"short_call"
);
else
return
;
type_attr_list
=
tree_cons
(
attr_name
,
NULL_TREE
,
type_attr_list
);
TYPE_ATTRIBUTES
(
type
)
=
type_attr_list
;
}
}
/* Return 1 if the operand is a SYMBOL_REF for a function known to be
defined within the current compilation unit. If this caanot be
determined, then 0 is returned. */
static
int
current_file_function_operand
(
sym_ref
)
rtx
sym_ref
;
{
/* This is a bit of a fib. A function will have a short call flag
applied to its name if it has the short call attribute, or it has
already been defined within the current compilation unit. */
if
(
ENCODED_SHORT_CALL_ATTR_P
(
XSTR
(
sym_ref
,
0
)))
return
1
;
/* The current funciton is always defined within the current compilation
unit. if it s a weak defintion however, then this may not be the real
defintion of the function, and so we have to say no. */
if
(
sym_ref
==
XEXP
(
DECL_RTL
(
current_function_decl
),
0
)
&&
!
DECL_WEAK
(
current_function_decl
))
return
1
;
/* We cannot make the determination - default to returning 0. */
return
0
;
}
/* Return non-zero if a 32 bit "long_call" should be generated for
this call. We generate a long_call if the function:
a. has an __attribute__((long call))
or b. is within the scope of a #pragma long_calls
or c. the -mlong-calls command line switch has been specified
However we do not generate a long call if the function:
d. has an __attribute__ ((short_call))
or e. is inside the scope of a #pragma no_long_calls
or f. has an __attribute__ ((section))
or g. is defined within the current compilation unit.
This function will be called by C fragments contained in the machine
description file. CALL_REF and CALL_COOKIE correspond to the matched
rtl operands. CALL_SYMBOL is used to distinguish between
two different callers of the function. It is set to 1 in the
"call_symbol" and "call_symbol_value" patterns and to 0 in the "call"
and "call_value" patterns. This is because of the difference in the
SYM_REFs passed by these patterns. */
int
arm_is_longcall_p
(
sym_ref
,
call_cookie
,
call_symbol
)
rtx
sym_ref
;
int
call_cookie
;
int
call_symbol
;
{
if
(
!
call_symbol
)
{
if
(
GET_CODE
(
sym_ref
)
!=
MEM
)
return
0
;
sym_ref
=
XEXP
(
sym_ref
,
0
);
}
if
(
GET_CODE
(
sym_ref
)
!=
SYMBOL_REF
)
return
0
;
if
(
call_cookie
&
CALL_SHORT
)
return
0
;
if
(
TARGET_LONG_CALLS
&&
flag_function_sections
)
return
1
;
if
(
current_file_function_operand
(
sym_ref
,
VOIDmode
))
return
0
;
return
(
call_cookie
&
CALL_LONG
)
||
ENCODED_LONG_CALL_ATTR_P
(
XSTR
(
sym_ref
,
0
))
||
TARGET_LONG_CALLS
;
}
int
legitimate_pic_operand_p
(
x
)
...
...
@@ -6988,6 +7081,31 @@ arm_final_prescan_insn (insn)
}
}
/* Return the length of a function name prefix
that starts with the character 'c'. */
static
int
arm_get_strip_length
(
char
c
)
{
switch
(
c
)
{
ARM_NAME_ENCODING_LENGTHS
default
:
return
0
;
}
}
/* Return a pointer to a function's name with any
and all prefix encodings stripped from it. */
const
char
*
arm_strip_name_encoding
(
const
char
*
name
)
{
int
skip
;
while
((
skip
=
arm_get_strip_length
(
*
name
)))
name
+=
skip
;
return
name
;
}
#ifdef AOF_ASSEMBLER
/* Special functions only needed when producing AOF syntax assembler. */
...
...
gcc/config/arm/arm.h
View file @
c27ba912
...
...
@@ -397,7 +397,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
"Do not load the PIC register in function prologues" }, \
{"no-single-pic-base", -ARM_FLAG_SINGLE_PIC_BASE, "" }, \
{"long-calls", ARM_FLAG_LONG_CALLS, \
"Generate
all call instructions as indirect calls
"}, \
"Generate
call insns as indirect calls, if necessary
"}, \
{"no-long-calls", -ARM_FLAG_LONG_CALLS, ""}, \
SUBTARGET_SWITCHES \
{"", TARGET_DEFAULT, "" } \
...
...
@@ -1037,7 +1037,7 @@ enum reg_class
else \
break; \
\
high = ((((val - low) & 0xffffffff
) ^ 0x80000000) - 0x80000000);
\
high = ((((val - low) & 0xffffffff
UL) ^ 0x80000000UL) - 0x80000000UL);
\
/* Check for overflow or zero */
\
if (low == 0 || high == 0 || (high + low != val)) \
break; \
...
...
@@ -1452,6 +1452,55 @@ CUMULATIVE_ARGS;
When generating pic allow anything. */
#define LEGITIMATE_CONSTANT_P(X) (flag_pic || ! label_mentioned_p (X))
/* Special characters prefixed to function names
in order to encode attribute like information.
Note, '@' and '*' have already been taken. */
#define SHORT_CALL_FLAG_CHAR '^'
#define LONG_CALL_FLAG_CHAR '#'
#define ENCODED_SHORT_CALL_ATTR_P(SYMBOL_NAME) \
(*(SYMBOL_NAME) == SHORT_CALL_FLAG_CHAR)
#define ENCODED_LONG_CALL_ATTR_P(SYMBOL_NAME) \
(*(SYMBOL_NAME) == LONG_CALL_FLAG_CHAR)
#ifndef SUBTARGET_NAME_ENCODING_LENGTHS
#define SUBTARGET_NAME_ENCODING_LENGTHS
#endif
/* This is a C fragement for the inside of a switch statement.
Each case label should return the number of characters to
be stripped from the start of a function's name, if that
name starts with the indicated character. */
#define ARM_NAME_ENCODING_LENGTHS \
case SHORT_CALL_FLAG_CHAR: return 1; \
case LONG_CALL_FLAG_CHAR: return 1; \
case '*': return 1; \
SUBTARGET_NAME_ENCODING_LENGTHS
/* This has to be handled by a function because more than part of the
ARM backend uses funciton name prefixes to encode attributes. */
#define STRIP_NAME_ENCODING(VAR, SYMBOL_NAME) \
(VAR) = arm_strip_name_encoding (SYMBOL_NAME)
/* This is how to output a reference to a user-level label named NAME.
`assemble_name' uses this. */
#define ASM_OUTPUT_LABELREF(FILE, NAME) \
fprintf (FILE, "%s%s", USER_LABEL_PREFIX, arm_strip_name_encoding (NAME))
/* If we are referencing a function that is weak then encode a long call
flag in the function name, otherwise if the function is static or
or known to be defined in this file then encode a short call flag.
This macro is used inside the ENCODE_SECTION macro. */
#define ARM_ENCODE_CALL_TYPE(decl) \
if (TREE_CODE (decl) == FUNCTION_DECL) \
{ \
if (DECL_WEAK (decl)) \
arm_encode_call_attribute (decl, LONG_CALL_FLAG_CHAR); \
else if (! TREE_PUBLIC (decl)) \
arm_encode_call_attribute (decl, SHORT_CALL_FLAG_CHAR); \
} \
/* Symbols in the text segment can be accessed without indirecting via the
constant pool; it may take an extra binary operation, but this is still
...
...
@@ -1470,9 +1519,18 @@ CUMULATIVE_ARGS;
? TREE_CST_RTL (decl) : DECL_RTL (decl)); \
SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1; \
} \
ARM_ENCODE_CALL_TYPE (decl) \
}
#else
#define ENCODE_SECTION_INFO(decl) \
{ \
ARM_ENCODE_CALL_TYPE (decl) \
}
#endif
#define ARM_DECLARE_FUNCTION_SIZE(STREAM, NAME, DECL) \
arm_encode_call_attribute (DECL, SHORT_CALL_FLAG_CHAR)
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
We have two alternate definitions for each of them.
...
...
@@ -1892,8 +1950,8 @@ extern const char * arm_pic_register_string;
( ! symbol_mentioned_p (X) \
&& ! label_mentioned_p (X) \
&& (! CONSTANT_POOL_ADDRESS_P (X) \
|| ( ! symbol_mentioned_p (get_pool_constant (X))
)
\
&& ! label_mentioned_p (get_pool_constant (X))))
|| ( ! symbol_mentioned_p (get_pool_constant (X)) \
&& ! label_mentioned_p (get_pool_constant (X))))
)
/* We need to know when we are making a constant pool; this determines
whether data needs to be in the GOT or can be referenced via a GOT
...
...
@@ -1912,6 +1970,14 @@ extern int making_const_table;
generated). */
#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \
(arm_comp_type_attributes (TYPE1, TYPE2))
/* If defined, a C statement that assigns default attributes to newly
defined TYPE. */
#define SET_DEFAULT_TYPE_ATTRIBUTES(TYPE) \
arm_set_default_type_attributes (TYPE)
/* Handle pragmas for compatibility with Intel's compilers. */
#define HANDLE_PRAGMA(GET, UNGET, NAME) arm_process_pragma (GET, UNGET, NAME)
/* Condition code information. */
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
...
...
gcc/config/arm/arm.md
View file @
c27ba912
...
...
@@ -4514,18 +4514,24 @@
""
"
{
rtx callee
= XEXP (operands
[
0
]
, 0)
;
rtx callee;
/
*
Decide if we need to generate an indirect call by loading the 32 bit
address of the callee into a register and then jumping to the contents
of that register. operands
[
2
]
contains the long_call / short_call
attribute. The third parameter to arm_is_longcall_p tells it that it
is being passed a (MEM) and not a SYMREF().
*
/
/
* In an untyped call, we can get NULL for operand 2. *
/
if (operands
[
2
]
== NULL_RTX)
operands
[
2
]
= const0_rtx;
/
*
This is to decide if we should generate indirect calls by loading the
32 bit address of the callee into a register before performing the
branch and link. operand
[
2
]
encodes the long_call/short_call
attribute of the function being called. This attribute is set whenever
__attribute__((long_call/short_call)) or #pragma long_call/no_long_call
is used, and the short_call attribute can also be set if function is
declared as static or if it has already been defined in the current
compilation unit. See arm.c and arm.h for info about this. The third
parameter to arm_is_longcall_p is used to tell it which pattern
invoked it.
*
/
callee = XEXP (operands
[
0
]
, 0);
if (GET_CODE (callee) != REG
&& arm_is_longcall_p (operands
[
0
]
, INTVAL (operands
[
2
]
), 0))
XEXP (operands
[
0
]
, 0) = force_reg (Pmode, callee);
...
...
@@ -4575,7 +4581,7 @@
/
* See the comment in define_expand \"call\". *
/
if (GET_CODE (callee) != REG
&& arm_is_longcall_p (operands
[
1
]
, INTVAL (operands
[
3
]
), 0))
XEXP (operands
[
1
]
, 0) = force_reg (Pmode, callee);
XEXP (operands
[
1
]
, 0) = force_reg (Pmode, callee);
}"
)
...
...
@@ -4613,8 +4619,8 @@
(match_operand:SI 1 "general_operand" "g"))
(use (match_operand 2 "" ""))
(clobber (reg:SI 14))]
"
! arm_is_longcall_p (operands
[
0
]
, INTVAL (operands
[
2
]
), 1
)
&&
GET_CODE (operands
[
0
]
) == SYMBOL_REF
"
"
(GET_CODE (operands
[
0
]
) == SYMBOL_REF
)
&&
! arm_is_longcall_p (operands
[
0
]
, INTVAL (operands
[
2
]
), 1)
"
"
*
{
return NEED_PLT_RELOC ?
\"
bl%?
\\
t%a0(PLT)
\"
:
\"
bl%?
\\
t%a0
\"
;
...
...
@@ -4627,8 +4633,8 @@
(match_operand:SI 2 "general_operand" "g")))
(use (match_operand 3 "" ""))
(clobber (reg:SI 14))]
"
! arm_is_longcall_p (operands
[
1
]
, INTVAL (operands
[
3
]
), 1
)
&&
GET_CODE (operands
[
1
]
) == SYMBOL_REF
"
"
(GET_CODE (operands
[
1
]
) == SYMBOL_REF
)
&&
! arm_is_longcall_p (operands
[
1
]
, INTVAL (operands
[
3
]
), 1)
"
"
*
{
return NEED_PLT_RELOC ?
\"
bl%?
\\
t%a1(PLT)
\"
:
\"
bl%?
\\
t%a1
\"
;
...
...
gcc/config/arm/elf.h
View file @
c27ba912
...
...
@@ -127,6 +127,7 @@ Boston, MA 02111-1307, USA. */
#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
do \
{ \
ARM_DECLARE_FUNCTION_SIZE (FILE, FNAME, DECL); \
if (!flag_inhibit_size_directive) \
{ \
char label[256]; \
...
...
gcc/config/arm/pe.c
View file @
c27ba912
...
...
@@ -19,9 +19,8 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <stdio.h>
#include <string.h>
#include "config.h"
#include "system.h"
#include "rtl.h"
#include "output.h"
#include "flags.h"
...
...
@@ -240,7 +239,7 @@ int
arm_dllexport_name_p
(
symbol
)
char
*
symbol
;
{
return
symbol
[
0
]
==
'@'
&&
symbol
[
1
]
==
'e'
&&
symbol
[
2
]
==
'.'
;
return
symbol
[
0
]
==
ARM_PE_FLAG_CHAR
&&
symbol
[
1
]
==
'e'
&&
symbol
[
2
]
==
'.'
;
}
/* Return non-zero if SYMBOL is marked as being dllimport'd. */
...
...
@@ -249,7 +248,7 @@ int
arm_dllimport_name_p
(
symbol
)
char
*
symbol
;
{
return
symbol
[
0
]
==
'@'
&&
symbol
[
1
]
==
'i'
&&
symbol
[
2
]
==
'.'
;
return
symbol
[
0
]
==
ARM_PE_FLAG_CHAR
&&
symbol
[
1
]
==
'i'
&&
symbol
[
2
]
==
'.'
;
}
/* Mark a DECL as being dllexport'd.
...
...
@@ -278,7 +277,7 @@ arm_mark_dllexport (decl)
return
;
/* already done */
newname
=
alloca
(
strlen
(
oldname
)
+
4
);
sprintf
(
newname
,
"
@e.%s"
,
oldname
);
sprintf
(
newname
,
"
%ce.%s"
,
ARM_PE_FLAG_CHAR
,
oldname
);
/* We pass newname through get_identifier to ensure it has a unique
address. RTL processing can sometimes peek inside the symbol ref
...
...
@@ -349,7 +348,7 @@ arm_mark_dllimport (decl)
}
newname
=
alloca
(
strlen
(
oldname
)
+
11
);
sprintf
(
newname
,
"
@i.__imp_%s"
,
oldname
);
sprintf
(
newname
,
"
%ci.__imp_%s"
,
ARM_PE_FLAG_CHAR
,
oldname
);
/* We pass newname through get_identifier to ensure it has a unique
address. RTL processing can sometimes peek inside the symbol ref
...
...
gcc/config/arm/pe.h
View file @
c27ba912
...
...
@@ -19,6 +19,12 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#define ARM_PE_FLAG_CHAR '@'
/* Ensure that @x. will be stripped from the function name. */
#define SUBTARGET_NAME_ENCODING_LENGTHS \
case ARM_PE_FLAG_CHAR: return 3;
#include "arm/coff.h"
#undef USER_LABEL_PREFIX
...
...
@@ -123,16 +129,6 @@ Boston, MA 02111-1307, USA. */
#define REDO_SECTION_INFO_P(DECL) 1
#endif
/* Utility used only in this file. */
#define ARM_STRIP_NAME_ENCODING(SYM_NAME) \
((SYM_NAME) + ((SYM_NAME)[0] == '@' ? 3 : 0))
/* Strip any text from SYM_NAME added by ENCODE_SECTION_INFO and store
the result in VAR. */
#undef STRIP_NAME_ENCODING
#define STRIP_NAME_ENCODING(VAR, SYM_NAME) \
(VAR) = ARM_STRIP_NAME_ENCODING (SYM_NAME)
/* Define this macro if in some cases global symbols from one translation
unit may not be bound to undefined symbols in another translation unit
without user intervention. For instance, under Microsoft Windows
...
...
@@ -184,7 +180,7 @@ Boston, MA 02111-1307, USA. */
/* Output a reference to a label. */
#undef ASM_OUTPUT_LABELREF
#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
fprintf (STREAM, "%s%s", USER_LABEL_PREFIX,
ARM_STRIP_NAME_ENCODING
(NAME))
fprintf (STREAM, "%s%s", USER_LABEL_PREFIX,
arm_strip_name_encoding
(NAME))
/* Output a function definition label. */
#undef ASM_DECLARE_FUNCTION_NAME
...
...
@@ -195,7 +191,7 @@ Boston, MA 02111-1307, USA. */
{ \
drectve_section (); \
fprintf (STREAM, "\t.ascii \" -export:%s\"\n",\
ARM_STRIP_NAME_ENCODING
(NAME)); \
arm_strip_name_encoding
(NAME)); \
function_section (DECL); \
} \
if (TARGET_POKE_FUNCTION_NAME) \
...
...
@@ -213,7 +209,7 @@ Boston, MA 02111-1307, USA. */
{ \
drectve_section (); \
fprintf ((STREAM), "\t.ascii \" -export:%s\"\n",\
ARM_STRIP_NAME_ENCODING
(NAME)); \
arm_strip_name_encoding
(NAME)); \
} \
if (! arm_dllimport_name_p (NAME)) \
{ \
...
...
@@ -235,7 +231,7 @@ Boston, MA 02111-1307, USA. */
enum in_section save_section = in_section; \
drectve_section (); \
fprintf (STREAM, "\t.ascii \" -export:%s\"\n",\
ARM_STRIP_NAME_ENCODING
(NAME)); \
arm_strip_name_encoding
(NAME)); \
switch_to_section (save_section, (DECL)); \
} \
ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
...
...
gcc/extend.texi
View file @
c27ba912
...
...
@@ -1613,6 +1613,17 @@ compiler to always call the function via a pointer, so that functions
which reside further than 64 megabytes (67,108,864 bytes) from the
current location can be called.
@item long_call/short_call
@cindex indirect calls on ARM
This attribute allows to specify how to call a particular function on
ARM. Both attributes override the @code{-mlong-calls} (@pxref{ARM Options})
command line switch and @code{#pragma long_calls} settings. The
@code{long_call} attribute causes the compiler to always call the
function by first loading its address into a register and then using the
contents of that register. The @code{short_call} attribute always places
the offset to the function from the call site into the @samp{BL}
instruction directly.
@item dllimport
@cindex functions which are imported from a dll on PowerPC Windows NT
On the PowerPC running Windows NT, the @code{dllimport} attribute causes
...
...
gcc/invoke.texi
View file @
c27ba912
...
...
@@ -269,6 +269,7 @@ in the following sections.
-mstructure-size-boundary=
-mbsd -mxopen -mno-symrename
-mabort-on-noreturn
-mlong-calls -mno-long-calls
-mnop-fun-dllimport -mno-nop-fun-dllimport
-msingle-pic-base -mno-single-pic-base
-mpic-register=
...
...
@@ -4608,6 +4609,32 @@ value as future versions of the toolchain may default to this value.
Generate a call to the function abort at the end of a noreturn function.
It will be executed if the function tries to return.
@item -mlong-calls
@itemx -mno-long-calls
Tells the compiler to perform function calls by first loading the
address of the function into a register and then performing a subroutine
call on this register. This switch is needed if the target function
will lie outside of the 64 megabyte addressing range of the offset based
version of subroutine call instruction.
Even if this switch is enabled, not all function calls will be turned
into long calls. The heuristic is that static functions, functions
which have the @samp{short-call} attribute, functions that are inside
the scope of a @samp{#pragma no_long_calls} directive and functions whose
definitions have already been compiled within the current compilation
unit, will not be turned into long calls. The exception to this rule is
that weak function defintions, functions with the @samp{long-call}
attribute or the @samp{section} attribute, and functions that are within
the scope of a @samp{#pragma long_calls} directive, will always be
turned into long calls.
This feature is not enabled by default. Specifying
@samp{--no-long-calls} will restore the default behaviour, as will
placing the function calls within the scope of a @samp{#pragma
long_calls_off} directive. Note these switches have no effect on how
the compiler generates code to handle function calls via function
pointers.
@item -mnop-fun-dllimport
@kindex -mnop-fun-dllimport
Disable the support for the @emph{dllimport} attribute.
...
...
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