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
f5a1b0d2
Commit
f5a1b0d2
authored
Feb 22, 1999
by
Nick Clifton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Apply ARM/Linux patches.
Rework cpu/architecture command line parsing. From-SVN: r25380
parent
956662b2
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
525 additions
and
323 deletions
+525
-323
gcc/ChangeLog
+64
-0
gcc/config/arm/arm.c
+304
-198
gcc/config/arm/arm.h
+46
-56
gcc/config/arm/arm.md
+32
-31
gcc/config/arm/elf.h
+6
-8
gcc/config/arm/linux-elf.h
+22
-1
gcc/config/arm/linux-gas.h
+15
-19
gcc/config/arm/t-arm-elf
+7
-5
gcc/config/arm/t-linux
+4
-2
gcc/invoke.texi
+25
-3
No files found.
gcc/ChangeLog
View file @
f5a1b0d2
1999
-
02
-
22
Nick
Clifton
<
nickc
@cygnus
.
com
>
*
config
/
arm
/
arm
.
h
:
Add
TARGET_CPU_strongarm1100
.
Add
-
mno
-
sched
command
line
switch
to
disable
scheduling
of
instructions
into
the
function
'
s
prologue
.
(
enum
processor_type
)
:
Remove
.
(
TARGET_OPTIONS
)
:
Add
"fpe="
option
to
match
documentation
.
(
struct
arm_cpu_select
)
:
Replace
'
set_tune_p
'
and
'
set_arch_p
'
fields
with
'
processors
'
field
.
(
CONDITIONAL_REGISTER_USAGE
)
:
Allow
r10
to
be
used
if
stack
checking
is
not
enabled
.
(
RETURN_IN_MEMORY
)
:
Always
call
arm_return_in_memory
.
*
config
/
arm
/
arm
.
c
:
(
arm_cpu
)
:
Remove
.
(
tune_flags
)
:
Remove
.
(
arm_is_strong
)
:
New
variable
:
true
iff
the
target
processor
is
a
StrongARM
.
(
arm_is_6_or_7
)
:
New
variable
:
true
iff
the
target
processor
is
an
ARM6
or
and
ARM7
.
(
arm_select
)
:
Fields
reorganised
.
(
struct
processors
)
:
processor_type
field
removed
.
(
all_procs
)
:
Remove
.
(
all_cores
)
:
New
array
:
Definitions
of
all
known
ARM
cpu
cores
.
(
all_architectures
)
:
New
array
:
Definitions
of
all
known
ARM
architectures
.
(
streq
)
:
New
macro
.
(
FL_SCHED
)
:
New
processor
flag
:
processor
required
load
scheduling
.
(
FL_STRONG
)
:
New
processor
flag
:
processor
is
a
StrongARM
.
(
arm_override_options
)
:
Reorganised
to
make
code
clearer
.
(
use_return_insn
)
:
Test
for
"not (TARGET_APCS and
frame_pointer_needed)"
.
(
arm_return_in_memory
)
:
Improve
handling
of
structures
.
*
config
/
arm
/
arm
.
md
:
Remove
"cpu"
attribute
.
Replace
with
"is_strongarm"
and
"is_arm_6_or_7"
attributes
.
(
zero_extendhisi2
)
:
Check
for
TARGET_SHORT_BY_BYTES
before
arm_arch4
.
(
extendhisi2
)
:
Check
for
TARGET_SHORT_BY_BYTES
before
arm_arch4
.
*
invoke
.
texi
(
ARM
Options
)
:
Document
-
mtune
=
and
-
mfp
=
options
.
1999
-
02
-
22
Philip
Blundell
<
philb
@gnu
.
org
>
*
config
/
arm
/
linux
-
gas
.
h
(
INITIALIZE_TRAMPOLINE
)
:
Replace
default
definition
with
one
including
cache
synchronisation
.
(
CLEAR_INSN_CACHE
)
:
Correct
syscall
number
and
enable
definition
.
Move
definition
of
inhibit_libc
to
...
*
config
/
arm
/
xm
-
linux
.
h
:
...
here
.
*
config
/
arm
/
t
-
linux
:
Disable
multilib
configurations
since
the
only
effect
for
most
people
is
to
cause
builds
to
fail
.
*
config
/
arm
/
elf
.
h
(
ASM_FILE_START
)
:
Add
.
file
directive
.
(
ASM_SPEC
)
:
Translate
-
mapcs
-
float
to
-
mfloat
for
the
assembler
.
*
config
/
arm
/
linux
-
elf
.
h
(
DEFAULT_VTABLE_THUNKS
)
:
Define
.
(
HANDLE_SYSV_PRAGMA
)
:
Likewise
.
(
LIB_SPEC
)
:
Copy
definition
from
generic
Linux
files
.
(
LIBGCC_SPEC
)
:
Include
-
lfloat
if
-
msoft
-
float
was
given
.
(
FP_DEFAULT
)
:
Set
to
SOFT3
on
32
-
bit
targets
.
(
DWARF2_DEBUGGING_INFO
)
:
Define
.
(
PREFERRED_DEBUGGING_TYPE
)
:
Define
as
DBX_DEBUG
.
Mon
Feb
22
16
:
54
:
18
EST
1999
Andrew
MacLeod
<
amacleod
@cygnus
.
com
>
*
loop
.
c
(
libcall_other_regs
)
:
Make
extern
.
...
...
gcc/config/arm/arm.c
View file @
f5a1b0d2
...
...
@@ -42,8 +42,8 @@ Boston, MA 02111-1307, USA. */
possible. */
static
int
max_insns_skipped
=
5
;
extern
FILE
*
asm_out_file
;
/* Some function declarations. */
extern
FILE
*
asm_out_file
;
static
HOST_WIDE_INT
int_log2
PROTO
((
HOST_WIDE_INT
));
static
char
*
output_multi_immediate
PROTO
((
rtx
*
,
char
*
,
char
*
,
int
,
...
...
@@ -74,9 +74,6 @@ static enum arm_cond_code get_arm_condition_code PROTO ((rtx));
rtx
arm_compare_op0
,
arm_compare_op1
;
int
arm_compare_fp
;
/* What type of cpu are we compiling for? */
enum
processor_type
arm_cpu
;
/* What type of floating point are we tuning for? */
enum
floating_point_type
arm_fpu
;
...
...
@@ -87,7 +84,7 @@ enum floating_point_type arm_fpu_arch;
enum
prog_mode_type
arm_prgmode
;
/* Set by the -mfp=... option */
char
*
target_fp_name
=
NULL
;
char
*
target_fp_name
=
NULL
;
/* Used to parse -mstructure_size_boundary command line option. */
char
*
structure_size_string
=
NULL
;
...
...
@@ -99,8 +96,14 @@ int arm_fast_multiply = 0;
/* Nonzero if this chip supports the ARM Architecture 4 extensions */
int
arm_arch4
=
0
;
/* Set to the features we should tune the code for (multiply speed etc). */
int
tune_flags
=
0
;
/* Nonzero if this chip can benefit from laod scheduling. */
int
arm_ld_sched
=
0
;
/* Nonzero if this chip is a StrongARM. */
int
arm_is_strong
=
0
;
/* Nonzero if this chip is a an ARM6 or an ARM7. */
int
arm_is_6_or_7
=
0
;
/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
must report the mode of the memory reference from PRINT_OPERAND to
...
...
@@ -134,7 +137,7 @@ rtx arm_target_insn;
int
arm_target_label
;
/* The condition codes of the ARM, and the inverse function. */
char
*
arm_condition_codes
[]
=
char
*
arm_condition_codes
[]
=
{
"eq"
,
"ne"
,
"cs"
,
"cc"
,
"mi"
,
"pl"
,
"vs"
,
"vc"
,
"hi"
,
"ls"
,
"ge"
,
"lt"
,
"gt"
,
"le"
,
"al"
,
"nv"
...
...
@@ -142,84 +145,90 @@ char *arm_condition_codes[] =
static
enum
arm_cond_code
get_arm_condition_code
();
#define streq(string1, string2) (strcmp (string1, string2) == 0)
/* Initialization code */
struct
arm_cpu_select
arm_select
[
4
]
=
{
/* switch name, tune arch */
{
(
char
*
)
0
,
"--with-cpu="
,
1
,
1
},
{
(
char
*
)
0
,
"-mcpu="
,
1
,
1
},
{
(
char
*
)
0
,
"-march="
,
0
,
1
},
{
(
char
*
)
0
,
"-mtune="
,
1
,
0
},
};
#define FL_CO_PROC 0x01
/* Has external co-processor bus */
#define FL_FAST_MULT 0x02
/* Fast multiply */
#define FL_MODE26 0x04
/* 26-bit mode support */
#define FL_MODE32 0x08
/* 32-bit mode support */
#define FL_ARCH4 0x10
/* Architecture rel 4 */
#define FL_THUMB 0x20
/* Thumb aware */
#define FL_LDSCHED 0x40
/* Load scheduling necessary */
#define FL_STRONG 0x80
/* StrongARM */
struct
processors
{
char
*
name
;
enum
processor_type
type
;
char
*
name
;
unsigned
int
flags
;
};
/* Not all of these give usefully different compilation alternatives,
but there is no simple way of generalizing them. */
static
struct
processors
all_procs
[]
=
static
struct
processors
all_cores
[]
=
{
/* ARM Cores */
{
"arm2"
,
FL_CO_PROC
|
FL_MODE26
},
{
"arm250"
,
FL_CO_PROC
|
FL_MODE26
},
{
"arm3"
,
FL_CO_PROC
|
FL_MODE26
},
{
"arm6"
,
FL_CO_PROC
|
FL_MODE26
|
FL_MODE32
},
{
"arm60"
,
FL_CO_PROC
|
FL_MODE26
|
FL_MODE32
},
{
"arm600"
,
FL_CO_PROC
|
FL_MODE26
|
FL_MODE32
},
{
"arm610"
,
FL_MODE26
|
FL_MODE32
},
{
"arm620"
,
FL_CO_PROC
|
FL_MODE26
|
FL_MODE32
},
{
"arm7"
,
FL_CO_PROC
|
FL_MODE26
|
FL_MODE32
},
{
"arm7m"
,
FL_CO_PROC
|
FL_MODE26
|
FL_MODE32
|
FL_FAST_MULT
},
/* arm7m doesn't exist on its own, */
{
"arm7d"
,
FL_CO_PROC
|
FL_MODE26
|
FL_MODE32
},
/* but only with D, (and I), */
{
"arm7dm"
,
FL_CO_PROC
|
FL_MODE26
|
FL_MODE32
|
FL_FAST_MULT
},
/* but those don't alter the code, */
{
"arm7di"
,
FL_CO_PROC
|
FL_MODE26
|
FL_MODE32
},
/* so arm7m is sometimes used. */
{
"arm7dmi"
,
FL_CO_PROC
|
FL_MODE26
|
FL_MODE32
|
FL_FAST_MULT
},
{
"arm70"
,
FL_CO_PROC
|
FL_MODE26
|
FL_MODE32
},
{
"arm700"
,
FL_CO_PROC
|
FL_MODE26
|
FL_MODE32
},
{
"arm700i"
,
FL_CO_PROC
|
FL_MODE26
|
FL_MODE32
},
{
"arm710"
,
FL_MODE26
|
FL_MODE32
},
{
"arm710c"
,
FL_MODE26
|
FL_MODE32
},
{
"arm7100"
,
FL_MODE26
|
FL_MODE32
},
{
"arm7500"
,
FL_MODE26
|
FL_MODE32
},
{
"arm7500fe"
,
FL_CO_PROC
|
FL_MODE26
|
FL_MODE32
},
/* Doesn't really have an external co-proc, but does have embedded fpu. */
{
"arm7tdmi"
,
FL_CO_PROC
|
FL_MODE32
|
FL_FAST_MULT
|
FL_ARCH4
|
FL_THUMB
},
{
"arm8"
,
FL_MODE26
|
FL_MODE32
|
FL_FAST_MULT
|
FL_ARCH4
|
FL_LDSCHED
},
{
"arm810"
,
FL_MODE26
|
FL_MODE32
|
FL_FAST_MULT
|
FL_ARCH4
|
FL_LDSCHED
},
{
"arm9"
,
FL_MODE32
|
FL_FAST_MULT
|
FL_ARCH4
|
FL_THUMB
|
FL_LDSCHED
},
{
"arm9tdmi"
,
FL_MODE32
|
FL_FAST_MULT
|
FL_ARCH4
|
FL_THUMB
|
FL_LDSCHED
},
{
"strongarm"
,
FL_MODE26
|
FL_MODE32
|
FL_FAST_MULT
|
FL_ARCH4
|
FL_LDSCHED
|
FL_STRONG
},
{
"strongarm110"
,
FL_MODE26
|
FL_MODE32
|
FL_FAST_MULT
|
FL_ARCH4
|
FL_LDSCHED
|
FL_STRONG
},
{
"strongarm1100"
,
FL_MODE26
|
FL_MODE32
|
FL_FAST_MULT
|
FL_ARCH4
|
FL_LDSCHED
|
FL_STRONG
},
{
NULL
,
0
}
};
static
struct
processors
all_architectures
[]
=
{
{
"arm2"
,
PROCESSOR_ARM2
,
FL_CO_PROC
|
FL_MODE26
},
{
"arm250"
,
PROCESSOR_ARM2
,
FL_CO_PROC
|
FL_MODE26
},
{
"arm3"
,
PROCESSOR_ARM2
,
FL_CO_PROC
|
FL_MODE26
},
{
"arm6"
,
PROCESSOR_ARM6
,
FL_CO_PROC
|
FL_MODE32
|
FL_MODE26
},
{
"arm600"
,
PROCESSOR_ARM6
,
FL_CO_PROC
|
FL_MODE32
|
FL_MODE26
},
{
"arm610"
,
PROCESSOR_ARM6
,
FL_MODE32
|
FL_MODE26
},
{
"arm7"
,
PROCESSOR_ARM7
,
FL_CO_PROC
|
FL_MODE32
|
FL_MODE26
},
/* arm7m doesn't exist on its own, only in conjunction with D, (and I), but
those don't alter the code, so it is sometimes known as the arm7m */
{
"arm7m"
,
PROCESSOR_ARM7
,
(
FL_CO_PROC
|
FL_FAST_MULT
|
FL_MODE32
|
FL_MODE26
)},
{
"arm7dm"
,
PROCESSOR_ARM7
,
(
FL_CO_PROC
|
FL_FAST_MULT
|
FL_MODE32
|
FL_MODE26
)},
{
"arm7dmi"
,
PROCESSOR_ARM7
,
(
FL_CO_PROC
|
FL_FAST_MULT
|
FL_MODE32
|
FL_MODE26
)},
{
"arm700"
,
PROCESSOR_ARM7
,
FL_CO_PROC
|
FL_MODE32
|
FL_MODE26
},
{
"arm710"
,
PROCESSOR_ARM7
,
FL_MODE32
|
FL_MODE26
},
{
"arm7100"
,
PROCESSOR_ARM7
,
FL_MODE32
|
FL_MODE26
},
{
"arm7500"
,
PROCESSOR_ARM7
,
FL_MODE32
|
FL_MODE26
},
/* Doesn't really have an external co-proc, but does have embedded fpu */
{
"arm7500fe"
,
PROCESSOR_ARM7
,
FL_CO_PROC
|
FL_MODE32
|
FL_MODE26
},
{
"arm7tdmi"
,
PROCESSOR_ARM7
,
(
FL_CO_PROC
|
FL_FAST_MULT
|
FL_MODE32
|
FL_ARCH4
|
FL_THUMB
)},
{
"arm8"
,
PROCESSOR_ARM8
,
(
FL_FAST_MULT
|
FL_MODE32
|
FL_MODE26
|
FL_ARCH4
)},
{
"arm810"
,
PROCESSOR_ARM8
,
(
FL_FAST_MULT
|
FL_MODE32
|
FL_MODE26
|
FL_ARCH4
)},
/* The next two are the same, but arm9 only exists in the thumb variant */
{
"arm9"
,
PROCESSOR_ARM9
,
(
FL_FAST_MULT
|
FL_MODE32
|
FL_ARCH4
|
FL_THUMB
)},
{
"arm9tdmi"
,
PROCESSOR_ARM9
,
(
FL_FAST_MULT
|
FL_MODE32
|
FL_ARCH4
|
FL_THUMB
)},
{
"strongarm"
,
PROCESSOR_STARM
,
(
FL_FAST_MULT
|
FL_MODE32
|
FL_MODE26
|
FL_ARCH4
)},
{
"strongarm110"
,
PROCESSOR_STARM
,
(
FL_FAST_MULT
|
FL_MODE32
|
FL_MODE26
|
FL_ARCH4
)},
{
"armv2"
,
PROCESSOR_NONE
,
FL_CO_PROC
|
FL_MODE26
},
{
"armv2a"
,
PROCESSOR_NONE
,
FL_CO_PROC
|
FL_MODE26
},
{
"armv3"
,
PROCESSOR_NONE
,
FL_CO_PROC
|
FL_MODE32
|
FL_MODE26
},
{
"armv3m"
,
PROCESSOR_NONE
,
(
FL_CO_PROC
|
FL_FAST_MULT
|
FL_MODE32
|
FL_MODE26
)},
{
"armv4"
,
PROCESSOR_NONE
,
(
FL_CO_PROC
|
FL_FAST_MULT
|
FL_MODE32
|
FL_MODE26
|
FL_ARCH4
)},
/* ARM Architectures */
{
"armv2"
,
FL_CO_PROC
|
FL_MODE26
},
{
"armv2a"
,
FL_CO_PROC
|
FL_MODE26
},
{
"armv3"
,
FL_CO_PROC
|
FL_MODE26
|
FL_MODE32
},
{
"armv3m"
,
FL_CO_PROC
|
FL_MODE26
|
FL_MODE32
|
FL_FAST_MULT
},
{
"armv4"
,
FL_CO_PROC
|
FL_MODE26
|
FL_MODE32
|
FL_FAST_MULT
|
FL_ARCH4
},
/* Strictly, FL_MODE26 is a permitted option for v4t, but there are no
implementations that support it, so we will leave it out for now. */
{
"armv4t"
,
PROCESSOR_NONE
,
(
FL_CO_PROC
|
FL_FAST_MULT
|
FL_MODE32
|
FL_ARCH4
)},
{
NULL
,
0
,
0
}
{
"armv4t"
,
FL_CO_PROC
|
FL_MODE32
|
FL_FAST_MULT
|
FL_ARCH4
|
FL_THUMB
},
{
NULL
,
0
}
};
/* This is a magic stucture. The 'string' field is magically filled in
with a pointer to the value specified by the user on the command line
assuming that the user has specified such a value. */
struct
arm_cpu_select
arm_select
[]
=
{
/* string name processors */
{
NULL
,
"-mcpu="
,
all_cores
},
{
NULL
,
"-march="
,
all_architectures
},
{
NULL
,
"-mtune="
,
all_cores
}
};
/* Fix up any incompatible options that the user has specified.
...
...
@@ -227,10 +236,84 @@ static struct processors all_procs[] =
void
arm_override_options
()
{
int
arm_thumb_aware
=
0
;
int
flags
=
0
;
unsigned
int
flags
=
0
;
unsigned
i
;
struct
arm_cpu_select
*
ptr
;
/* Set up the flags based on the cpu/architecture selected by the user. */
for
(
i
=
sizeof
(
arm_select
)
/
sizeof
(
arm_select
[
0
]);
i
--
;)
{
struct
arm_cpu_select
*
ptr
=
arm_select
+
i
;
if
(
ptr
->
string
!=
NULL
&&
ptr
->
string
[
0
]
!=
'\0'
)
{
struct
processors
*
sel
;
for
(
sel
=
ptr
->
processors
;
sel
->
name
!=
NULL
;
sel
++
)
if
(
streq
(
ptr
->
string
,
sel
->
name
))
{
if
(
flags
!=
0
)
{
/* We scan the arm_select array in the order:
tune -> arch -> cpu
So if we have been asked to tune for, say, an ARM8,
but we are told that the cpu is only an ARM6, then
we have problems. We detect this by seeing if the
flags bits accumulated so far can be supported by the
cpu/architecture type now being parsed. If they can,
then OR in any new bits. If they cannot then report
an error. */
if
((
flags
&
sel
->
flags
)
!=
flags
)
error
(
"switch %s%s overridden by another switch"
,
ptr
->
string
,
sel
->
name
);
}
flags
=
sel
->
flags
;
break
;
}
if
(
sel
->
name
==
NULL
)
error
(
"bad value (%s) for %s switch"
,
ptr
->
string
,
ptr
->
name
);
}
}
/* If the user did not specify a processor, choose one for them. */
if
(
flags
==
0
)
{
struct
processors
*
sel
;
int
sought
=
0
;
if
(
TARGET_THUMB_INTERWORK
)
{
sought
|=
FL_THUMB
;
/* Force apcs-32 to be used for Thumb targets. */
target_flags
|=
ARM_FLAG_APCS_32
;
}
if
(
TARGET_APCS_32
)
sought
|=
FL_MODE32
;
else
sought
|=
FL_MODE26
;
if
(
sought
!=
0
)
{
for
(
sel
=
all_cores
;
sel
->
name
!=
NULL
;
sel
++
)
if
((
sel
->
flags
&
sought
)
==
sought
)
{
flags
=
sel
->
flags
;
break
;
}
if
(
sel
->
name
==
NULL
)
fatal
(
"Unable to select a cpu that matches command line specification"
);
}
else
{
/* The user did not specify any command line switches that require
a certain kind of CPU. Use TARGET_CPU_DEFAULT instead. */
static
struct
cpu_default
{
int
cpu
;
...
...
@@ -241,56 +324,82 @@ arm_override_options ()
{
TARGET_CPU_arm2
,
"arm2"
},
{
TARGET_CPU_arm6
,
"arm6"
},
{
TARGET_CPU_arm610
,
"arm610"
},
{
TARGET_CPU_arm7dm
,
"arm7d
m"
},
{
TARGET_CPU_arm7m
,
"arm7
m"
},
{
TARGET_CPU_arm7500fe
,
"arm7500fe"
},
{
TARGET_CPU_arm7tdmi
,
"arm7tdmi"
},
{
TARGET_CPU_arm8
,
"arm8"
},
{
TARGET_CPU_arm810
,
"arm810"
},
{
TARGET_CPU_arm9
,
"arm9"
},
{
TARGET_CPU_strongarm
,
"strongarm"
},
{
TARGET_CPU_generic
,
"arm"
},
{
0
,
0
}
};
struct
cpu_default
*
def
;
struct
cpu_default
*
def
;
/* Set
the default. */
for
(
def
=
&
cpu_defaults
[
0
];
def
->
name
;
++
def
)
/* Find
the default. */
for
(
def
=
cpu_defaults
;
def
->
name
;
def
++
)
if
(
def
->
cpu
==
TARGET_CPU_DEFAULT
)
break
;
if
(
!
def
->
name
)
if
(
def
->
name
==
NULL
)
abort
();
arm_select
[
0
].
string
=
def
->
name
;
/* Find the default CPU's flags. */
for
(
sel
=
all_cores
;
sel
->
name
!=
NULL
;
sel
++
)
if
(
streq
(
def
->
name
,
sel
->
name
))
break
;
for
(
i
=
0
;
i
<
sizeof
(
arm_select
)
/
sizeof
(
arm_select
[
0
]);
i
++
)
if
(
sel
->
name
==
NULL
)
abort
();
flags
=
sel
->
flags
;
}
}
/* Cope with some redundant flags. */
if
(
TARGET_6
)
{
ptr
=
&
arm_select
[
i
];
if
(
ptr
->
string
!=
(
char
*
)
0
&&
ptr
->
string
[
0
]
!=
'\0'
)
warning
(
"Option '-m6' deprecated. Use: '-mapcs-32' or -mcpu=<proc>"
);
target_flags
|=
ARM_FLAG_APCS_32
;
}
if
(
TARGET_3
)
{
struct
processors
*
sel
;
warning
(
"Option '-m3' deprecated. Use: '-mapcs-26' or -mcpu=<proc>"
);
target_flags
&=
~
ARM_FLAG_APCS_32
;
}
for
(
sel
=
all_procs
;
sel
->
name
!=
NULL
;
sel
++
)
if
(
!
strcmp
(
ptr
->
string
,
sel
->
name
))
/* Make sure that the processor choice does not conflict with any of the
other command line choices. */
if
(
TARGET_APCS_32
&&
!
(
flags
&
FL_MODE32
))
{
/* -march= is the only flag that can take an architecture
type, so if we match when the tune bit is set, the
option was invalid. */
if
(
ptr
->
set_tune_p
)
warning
(
"target CPU does not support APCS-32"
);
target_flags
&=
~
ARM_FLAG_APCS_32
;
}
else
if
(
!
TARGET_APCS_32
&&
!
(
flags
&
FL_MODE26
)
)
{
if
(
sel
->
type
==
PROCESSOR_NONE
)
continue
;
/* Its an architecture, not a cpu */
arm_cpu
=
sel
->
type
;
tune_flags
=
sel
->
flags
;
warning
(
"target CPU does not support APCS-26"
);
target_flags
|=
ARM_FLAG_APCS_32
;
}
if
(
ptr
->
set_arch_p
)
flags
=
sel
->
flags
;
break
;
if
(
TARGET_THUMB_INTERWORK
&&
!
(
flags
&
FL_THUMB
)
)
{
warning
(
"target CPU does not support interworking"
);
target_flags
&=
~
ARM_FLAG_THUMB
;
}
if
(
sel
->
name
==
NULL
)
error
(
"bad value (%s) for %s switch"
,
ptr
->
string
,
ptr
->
name
);
/* If interworking is enabled then APCS-32 must be selected as well. */
if
(
TARGET_THUMB_INTERWORK
)
{
if
(
!
TARGET_APCS_32
)
warning
(
"interworking forces APCS-32 to be used"
);
target_flags
|=
ARM_FLAG_APCS_32
;
}
if
(
TARGET_APCS_STACK
&&
!
TARGET_APCS
)
{
warning
(
"-mapcs-stack-check incompatible with -mno-apcs-frame"
);
target_flags
|=
ARM_FLAG_APCS_FRAME
;
}
if
(
write_symbols
!=
NO_DEBUG
&&
flag_omit_frame_pointer
)
...
...
@@ -299,17 +408,11 @@ arm_override_options ()
if
(
TARGET_POKE_FUNCTION_NAME
)
target_flags
|=
ARM_FLAG_APCS_FRAME
;
if
(
TARGET_6
)
warning
(
"Option '-m6' deprecated. Use: '-mapcs-32' or -mcpu=<proc>"
);
if
(
TARGET_3
)
warning
(
"Option '-m3' deprecated. Use: '-mapcs-26' or -mcpu=<proc>"
);
if
(
TARGET_APCS_REENT
&&
flag_pic
)
fatal
(
"-fpic and -mapcs-reent are incompatible"
);
if
(
TARGET_APCS_REENT
)
warning
(
"APCS reentrant code not supported."
);
warning
(
"APCS reentrant code not supported.
Ignored
"
);
/* If stack checking is disabled, we can use r10 as the PIC register,
which keeps r9 available. */
...
...
@@ -326,93 +429,45 @@ arm_override_options ()
if
(
TARGET_APCS_FLOAT
)
warning
(
"Passing floating point arguments in fp regs not yet supported"
);
if
(
TARGET_APCS_STACK
&&
!
TARGET_APCS
)
{
warning
(
"-mapcs-stack-check incompatible with -mno-apcs-frame"
)
;
target_flags
|=
ARM_FLAG_APCS_FRAME
;
}
/* Initialise booleans used elsewhere in this file, and in arm.md */
arm_fast_multiply
=
(
flags
&
FL_FAST_MULT
)
!=
0
;
arm_arch4
=
(
flags
&
FL_ARCH4
)
!=
0
;
arm_ld_sched
=
(
flags
&
FL_LDSCHED
)
!=
0
;
arm_is_strong
=
(
flags
&
FL_STRONG
);
/*
Default is to tune for an FPA
*/
arm_
fpu
=
FP_HARD
;
/*
The arm.md file needs to know if theprocessor is an ARM6 or an ARM7
*/
arm_
is_6_or_7
=
((
flags
&
(
FL_MODE26
|
FL_MODE32
))
&&
!
(
flags
&
FL_ARCH4
))
;
/* Default value for floating point code... if no co-processor
bus, then schedule for emulated floating point. Otherwise,
assume the user has an FPA.
Note: this does not prevent use of floating point instructions,
-msoft-float does that. */
if
((
tune_
flags
&
FL_CO_PROC
)
==
0
)
if
((
flags
&
FL_CO_PROC
)
==
0
)
arm_fpu
=
FP_SOFT3
;
arm_fast_multiply
=
(
flags
&
FL_FAST_MULT
)
!=
0
;
arm_arch4
=
(
flags
&
FL_ARCH4
)
!=
0
;
arm_thumb_aware
=
(
flags
&
FL_THUMB
)
!=
0
;
else
arm_fpu
=
FP_HARD
;
if
(
target_fp_name
)
{
if
(
str
cmp
(
target_fp_name
,
"2"
)
==
0
)
if
(
str
eq
(
target_fp_name
,
"2"
)
)
arm_fpu_arch
=
FP_SOFT2
;
else
if
(
str
cmp
(
target_fp_name
,
"3"
)
==
0
)
arm_fpu_arch
=
FP_
HARD
;
else
if
(
str
eq
(
target_fp_name
,
"3"
)
)
arm_fpu_arch
=
FP_
SOFT3
;
else
fatal
(
"Invalid floating point emulation option: -mfpe
=
%s"
,
fatal
(
"Invalid floating point emulation option: -mfpe
-
%s"
,
target_fp_name
);
}
else
arm_fpu_arch
=
FP_DEFAULT
;
if
(
TARGET_THUMB_INTERWORK
&&
!
arm_thumb_aware
)
{
warning
(
"This processor variant does not support Thumb interworking"
);
target_flags
&=
~
ARM_FLAG_THUMB
;
}
if
(
TARGET_FPE
&&
arm_fpu
==
FP_HARD
)
arm_fpu
=
FP_SOFT3
;
/* If optimizing for space, don't synthesize constants */
if
(
optimize_size
)
arm_constant_limit
=
1
;
if
(
TARGET_FPE
&&
arm_fpu
!=
FP_HARD
)
arm_fpu
=
FP_SOFT2
;
/* Override a few things based on the tuning pararmeters. */
switch
(
arm_cpu
)
{
case
PROCESSOR_ARM2
:
case
PROCESSOR_ARM3
:
/* For arm2/3 there is no need to do any scheduling if there is
only a floating point emulator, or we are doing software
floating-point. */
if
(
TARGET_SOFT_FLOAT
||
arm_fpu
!=
FP_HARD
)
/* For arm2/3 there is no need to do any scheduling if there is only
a floating point emulator, or we are doing software floating-point. */
if
((
TARGET_SOFT_FLOAT
||
arm_fpu
!=
FP_HARD
)
&&
(
flags
&
FL_MODE32
)
==
0
)
flag_schedule_insns
=
flag_schedule_insns_after_reload
=
0
;
break
;
case
PROCESSOR_ARM6
:
case
PROCESSOR_ARM7
:
break
;
case
PROCESSOR_ARM8
:
case
PROCESSOR_ARM9
:
/* For these processors, it never costs more than 2 cycles to load a
constant, and the load scheduler may well reduce that to 1. */
arm_constant_limit
=
1
;
break
;
case
PROCESSOR_STARM
:
/* Same as above */
arm_constant_limit
=
1
;
/* StrongARM has early execution of branches, a sequence that is worth
skipping is shorter. */
max_insns_skipped
=
3
;
break
;
default:
fatal
(
"Unknown cpu type selected"
);
break
;
}
/* If optimizing for size, bump the number of instructions that we
are prepared to conditionally execute (even on a StrongARM). */
if
(
optimize_size
)
max_insns_skipped
=
6
;
arm_prog_mode
=
TARGET_APCS_32
?
PROG_MODE_PROG32
:
PROG_MODE_PROG26
;
...
...
@@ -425,6 +480,21 @@ arm_override_options ()
else
warning
(
"Structure size boundary can only be set to 8 or 32"
);
}
/* If optimizing for space, don't synthesize constants.
For processors with load scheduling, it never costs more than 2 cycles
to load a constant, and the load scheduler may well reduce that to 1. */
if
(
optimize_size
||
(
flags
&
FL_LDSCHED
))
arm_constant_limit
=
1
;
/* If optimizing for size, bump the number of instructions that we
are prepared to conditionally execute (even on a StrongARM).
Otherwise for the StrongARM, which has early execution of branches,
a sequence that is worth skipping is shorter. */
if
(
optimize_size
)
max_insns_skipped
=
6
;
else
if
(
arm_is_strong
)
max_insns_skipped
=
3
;
}
/* Return 1 if it is possible to return using a single instruction */
...
...
@@ -435,18 +505,19 @@ use_return_insn (iscond)
{
int
regno
;
if
(
!
reload_completed
||
current_function_pretend_args_size
if
(
!
reload_completed
||
current_function_pretend_args_size
||
current_function_anonymous_args
||
((
get_frame_size
()
+
current_function_outgoing_args_size
!=
0
)
&&
!
(
TARGET_APCS
||
frame_pointer_needed
)))
&&
!
(
TARGET_APCS
&&
frame_pointer_needed
)))
return
0
;
/* Can't be done if interworking with Thumb, and any registers have been
stacked. Similarly, on StrongARM, conditional returns are expensive
if they aren't taken and registers have been stacked. */
if
(
iscond
&&
arm_
cpu
==
PROCESSOR_STARM
&&
frame_pointer_needed
)
if
(
iscond
&&
arm_
is_strong
&&
frame_pointer_needed
)
return
0
;
else
if
((
iscond
&&
arm_cpu
==
PROCESSOR_STARM
)
if
((
iscond
&&
arm_is_strong
)
||
TARGET_THUMB_INTERWORK
)
for
(
regno
=
0
;
regno
<
16
;
regno
++
)
if
(
regs_ever_live
[
regno
]
&&
!
call_used_regs
[
regno
])
...
...
@@ -1193,23 +1264,54 @@ arm_canonicalize_comparison (code, op1)
return
code
;
}
/* Handle aggregates that are not laid out in a BLKmode element.
This is a sub-element of
RETURN_IN_MEMORY. */
/* Decide whether a type should be returned in memory (true)
or in a register (false). This is called by the macro
RETURN_IN_MEMORY. */
int
arm_return_in_memory
(
type
)
tree
type
;
{
if
(
TREE_CODE
(
type
)
==
RECORD_TYPE
)
if
(
!
AGGREGATE_TYPE_P
(
type
))
{
/* All simple types are returned in registers. */
return
0
;
}
else
if
(
int_size_in_bytes
(
type
)
>
4
)
{
/* All structures/unions bigger than one word are returned in memory. */
return
1
;
}
else
if
(
TREE_CODE
(
type
)
==
RECORD_TYPE
)
{
tree
field
;
/* For a struct, we can return in a register if every element was a
bit-field. */
for
(
field
=
TYPE_FIELDS
(
type
);
field
;
field
=
TREE_CHAIN
(
field
))
if
(
TREE_CODE
(
field
)
!=
FIELD_DECL
||
!
DECL_BIT_FIELD_TYPE
(
field
))
/* For a struct the APCS says that we must return in a register if
every addressable element has an offset of zero. For practical
purposes this means that the structure can have at most one non
bit-field element and that this element must be the first one in
the structure. */
/* Find the first field, ignoring non FIELD_DECL things which will
have been created by C++. */
for
(
field
=
TYPE_FIELDS
(
type
);
field
&&
TREE_CODE
(
field
)
!=
FIELD_DECL
;
field
=
TREE_CHAIN
(
field
))
continue
;
if
(
field
==
NULL
)
return
0
;
/* An empty structure. Allowed by an extension to ANSI C. */
/* Now check the remaining fields, if any. */
for
(
field
=
TREE_CHAIN
(
field
);
field
;
field
=
TREE_CHAIN
(
field
))
{
if
(
TREE_CODE
(
field
)
!=
FIELD_DECL
)
continue
;
if
(
!
DECL_BIT_FIELD_TYPE
(
field
))
return
1
;
}
return
0
;
}
...
...
@@ -1219,16 +1321,20 @@ arm_return_in_memory (type)
/* Unions can be returned in registers if every element is
integral, or can be returned in an integer register. */
for
(
field
=
TYPE_FIELDS
(
type
);
field
;
field
=
TREE_CHAIN
(
field
))
for
(
field
=
TYPE_FIELDS
(
type
);
field
;
field
=
TREE_CHAIN
(
field
))
{
if
(
TREE_CODE
(
field
)
!=
FIELD_DECL
||
(
AGGREGATE_TYPE_P
(
TREE_TYPE
(
field
))
&&
RETURN_IN_MEMORY
(
TREE_TYPE
(
field
)))
||
FLOAT_TYPE_P
(
TREE_TYPE
(
field
)))
if
(
TREE_CODE
(
field
)
!=
FIELD_DECL
)
continue
;
if
(
RETURN_IN_MEMORY
(
TREE_TYPE
(
field
)))
return
1
;
}
return
0
;
}
/* XXX Not sure what should be done for other aggregates, so put them in
memory. */
return
1
;
...
...
@@ -1570,7 +1676,7 @@ arm_rtx_costs (x, code, outer_code)
int
add_cost
=
const_ok_for_arm
(
i
)
?
4
:
8
;
int
j
;
/* Tune as appropriate */
int
booth_unit_size
=
(
(
tune_flags
&
FL_FAST_MULT
)
?
8
:
2
);
int
booth_unit_size
=
(
arm_fast_multiply
?
8
:
2
);
for
(
j
=
0
;
i
&&
j
<
32
;
j
+=
booth_unit_size
)
{
...
...
@@ -1581,7 +1687,7 @@ arm_rtx_costs (x, code, outer_code)
return
add_cost
;
}
return
((
(
tune_flags
&
FL_FAST_MULT
)
?
8
:
30
)
return
((
arm_fast_multiply
?
8
:
30
)
+
(
REG_OR_SUBREG_REG
(
XEXP
(
x
,
0
))
?
0
:
4
)
+
(
REG_OR_SUBREG_REG
(
XEXP
(
x
,
1
))
?
0
:
4
));
...
...
@@ -2595,9 +2701,7 @@ load_multiple_sequence (operands, nops, regs, base, load_offset)
/* For ARM8,9 & StrongARM, 2 ldr instructions are faster than an ldm if
the offset isn't small enough */
if
(
nops
==
2
&&
(
arm_cpu
==
PROCESSOR_ARM8
||
arm_cpu
==
PROCESSOR_ARM9
||
arm_cpu
==
PROCESSOR_STARM
))
if
(
nops
==
2
&&
arm_ld_sched
)
return
0
;
/* Can't do it without setting up the offset, only do this if it takes
...
...
@@ -5074,7 +5178,7 @@ output_func_epilogue (f, frame_size)
if
(
use_return_insn
(
FALSE
)
&&
return_used_this_function
)
{
if
((
frame_size
+
current_function_outgoing_args_size
)
!=
0
&&
!
(
frame_pointer_needed
||
TARGET_APCS
))
&&
!
(
frame_pointer_needed
&&
TARGET_APCS
))
abort
();
goto
epilogue_done
;
}
...
...
@@ -5217,8 +5321,10 @@ output_func_epilogue (f, frame_size)
if
(
TARGET_THUMB_INTERWORK
)
{
if
(
!
lr_save_eliminated
)
print_multi_reg
(
f
,
"ldmfd
\t
%ssp!"
,
live_regs_mask
|
0x4000
,
FALSE
);
live_regs_mask
|=
0x4000
;
if
(
live_regs_mask
!=
0
)
print_multi_reg
(
f
,
"ldmfd
\t
%ssp!"
,
live_regs_mask
,
FALSE
);
fprintf
(
f
,
"
\t
bx
\t
%slr
\n
"
,
REGISTER_PREFIX
);
}
...
...
@@ -5329,7 +5435,6 @@ emit_sfm (base_reg, count)
gen_rtvec
(
1
,
gen_rtx_REG
(
XFmode
,
base_reg
++
)),
2
));
for
(
i
=
1
;
i
<
count
;
i
++
)
XVECEXP
(
par
,
0
,
i
)
=
gen_rtx_USE
(
VOIDmode
,
gen_rtx_REG
(
XFmode
,
base_reg
++
));
...
...
@@ -5443,8 +5548,9 @@ arm_expand_prologue ()
}
/* If we are profiling, make sure no instructions are scheduled before
the call to mcount. */
if
(
profile_flag
||
profile_block_flag
)
the call to mcount. Similarly if the user has requested no
scheduling in the prolog. */
if
(
profile_flag
||
profile_block_flag
||
TARGET_NO_SCHED_PRO
)
emit_insn
(
gen_blockage
());
}
...
...
gcc/config/arm/arm.h
View file @
f5a1b0d2
/* Definitions of target machine for GNU compiler, for A
corn RISC Machine
.
/* Definitions of target machine for GNU compiler, for A
RM
.
Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
and Martin Simmons (@harleqn.co.uk).
...
...
@@ -53,6 +53,7 @@ Boston, MA 02111-1307, USA. */
#define TARGET_CPU_arm810 0x0020
#define TARGET_CPU_strongarm 0x0040
#define TARGET_CPU_strongarm110 0x0040
#define TARGET_CPU_strongarm1100 0x0040
#define TARGET_CPU_arm9 0x0080
#define TARGET_CPU_arm9tdmi 0x0080
/* Configure didn't specify */
...
...
@@ -146,6 +147,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{march=arm9tdmi:-D__ARM_ARCH_4T__} \
%{march=strongarm:-D__ARM_ARCH_4__} \
%{march=strongarm110:-D__ARM_ARCH_4__} \
%{march=strongarm1100:-D__ARM_ARCH_4__} \
%{march=armv2:-D__ARM_ARCH_2__} \
%{march=armv2a:-D__ARM_ARCH_2__} \
%{march=armv3:-D__ARM_ARCH_3__} \
...
...
@@ -175,6 +177,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{mcpu=arm9tdmi:-D__ARM_ARCH_4T__} \
%{mcpu=strongarm:-D__ARM_ARCH_4__} \
%{mcpu=strongarm110:-D__ARM_ARCH_4__} \
%{mcpu=strongarm1100:-D__ARM_ARCH_4__} \
%{!mcpu*:%{!m6:%{!m2:%{!m3:%(cpp_cpu_arch_default)}}}}} \
"
...
...
@@ -258,7 +261,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
extern
int
target_flags
;
/* The floating point instruction architecture, can be 2 or 3 */
extern
char
*
target_fp_name
;
extern
char
*
target_fp_name
;
/* Nonzero if the function prologue (and epilogue) should obey
the ARM Procedure Call Standard. */
...
...
@@ -318,6 +321,9 @@ extern char *target_fp_name;
big-endian (for backwards compatibility with older versions of GCC). */
#define ARM_FLAG_LITTLE_WORDS (0x2000)
/* Nonzero if we need to protect the prolog from scheduling */
#define ARM_FLAG_NO_SCHED_PRO (0x4000)
/* Nonzero if a call to abort should be generated if a noreturn
function tries to return. */
#define ARM_FLAG_ABORT_NORETURN (0x8000)
...
...
@@ -337,6 +343,7 @@ function tries to return. */
#define TARGET_BIG_END (target_flags & ARM_FLAG_BIG_END)
#define TARGET_THUMB_INTERWORK (target_flags & ARM_FLAG_THUMB)
#define TARGET_LITTLE_WORDS (target_flags & ARM_FLAG_LITTLE_WORDS)
#define TARGET_NO_SCHED_PRO (target_flags & ARM_FLAG_NO_SCHED_PRO)
#define TARGET_ABORT_NORETURN (target_flags & ARM_FLAG_ABORT_NORETURN)
/* SUBTARGET_SWITCHES is used to add flags on a per-config basis.
...
...
@@ -391,68 +398,39 @@ function tries to return. */
{"abort-on-noreturn", ARM_FLAG_ABORT_NORETURN, \
"Generate a call to abort if a noreturn function returns"}, \
{"no-abort-on-noreturn", -ARM_FLAG_ABORT_NORETURN, ""}, \
{"sched-prolog", -ARM_FLAG_NO_SCHED_PRO, \
"Do not move instructions into a function's prologue" }, \
{"no-sched-prolog", ARM_FLAG_NO_SCHED_PRO, "" }, \
SUBTARGET_SWITCHES \
{"", TARGET_DEFAULT } \
}
#define TARGET_OPTIONS \
{ \
{"cpu=", \
&arm_select[1].string, \
"Specify the name of the target CPU"}, \
{"arch=", \
&arm_select[2].string, \
"Specify the name of the target architecture"}, \
{"tune=", \
&arm_select[3].string, \
"Order instructions for best performance on this CPU"}, \
{"fp=", \
&target_fp_name, \
"Specify the version of the floating point emulator"}, \
{"structure-size-boundary=", \
&structure_size_string, \
"Specify the minumum bit alignment of structures"} \
{"cpu=", & arm_select[0].string, \
"Specify the name of the target CPU" }, \
{"arch=", & arm_select[1].string, \
"Specify the name of the target architecture" }, \
{"tune=", & arm_select[2].string, "" }, \
{"fpe=", & target_fp_name, "" }, \
{"fp=", & target_fp_name, \
"Specify the version of the floating point emulator" }, \
{ "structure-size-boundary=", & structure_size_string, \
"Specify the minumum bit alignment of structures" } \
}
/* arm_select[0] is reserved for the default cpu. */
struct
arm_cpu_select
{
char
*
string
;
char
*
name
;
int
set_tune_p
;
int
set_arch_p
;
char
*
string
;
char
*
name
;
struct
processors
*
processors
;
};
/* This is a magic array. If the user specifies a command line switch
which matches one of the entries in TARGET_OPTIONS then the corresponding
string pointer will be set to the value specified by the user. */
extern
struct
arm_cpu_select
arm_select
[];
#ifndef PROCESSOR_DEFAULT
#define PROCESSOR_DEFAULT PROCESSOR_ARM2
#endif
#ifndef TARGET_CPU_DEFAULT
#define TARGET_CPU_DEFAULT ((char *) 0)
#endif
/* Which processor we are running on, for instruction scheduling
purposes. */
enum
processor_type
{
PROCESSOR_ARM2
,
PROCESSOR_ARM3
,
PROCESSOR_ARM6
,
PROCESSOR_ARM7
,
PROCESSOR_ARM8
,
PROCESSOR_ARM9
,
PROCESSOR_STARM
,
PROCESSOR_NONE
/* NOTE: This must be last, since it doesn't
appear in the attr_cpu list */
};
/* Recast the cpu class to be the cpu attribute. */
#define arm_cpu_attr ((enum attr_cpu)arm_cpu)
extern
enum
processor_type
arm_cpu
;
enum
prog_mode_type
{
prog_mode26
,
...
...
@@ -493,6 +471,15 @@ extern int arm_fast_multiply;
/* Nonzero if this chip supports the ARM Architecture 4 extensions */
extern
int
arm_arch4
;
/* Nonzero if this chip can benefit from load scheduling. */
extern
int
arm_ld_sched
;
/* Nonzero if this chip is a StrongARM. */
extern
int
arm_is_strong
;
/* Nonzero if this chip is a an ARM6 or an ARM7. */
extern
int
arm_is_6_or_7
;
#ifndef TARGET_DEFAULT
#define TARGET_DEFAULT 0
#endif
...
...
@@ -635,7 +622,7 @@ extern char * structure_size_string;
r4-r8 S register variable
r9 S (rfp) register variable (real frame pointer)
r10 F S (sl) stack limit (
not currently used
)
r10 F S (sl) stack limit (
used by -mapcs-stack-check
)
r11 F S (fp) argument pointer
r12 (ip) temp workspace
r13 F S (sp) lower end of current stack frame
...
...
@@ -730,6 +717,11 @@ extern char * structure_size_string;
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 0; \
} \
else if (! TARGET_APCS_STACK) \
{ \
fixed_regs[10] = 0; \
call_used_regs[10] = 0; \
} \
}
/* Return number of consecutive hard regs needed starting at reg REGNO
...
...
@@ -1062,9 +1054,7 @@ do { \
/* How large values are returned */
/* A C expression which can inhibit the returning of certain function values
in registers, based on the type of value. */
#define RETURN_IN_MEMORY(TYPE) \
(TYPE_MODE ((TYPE)) == BLKmode || \
(AGGREGATE_TYPE_P ((TYPE)) && arm_return_in_memory ((TYPE))))
#define RETURN_IN_MEMORY(TYPE) arm_return_in_memory (TYPE)
/* Define DEFAULT_PCC_STRUCT_RETURN to 1 if all structure and union return
values must be in memory. On the ARM, they need only do so if larger
...
...
@@ -1779,8 +1769,8 @@ extern int arm_pic_register;
#define FINALIZE_PIC arm_finalize_pic ()
/* We can't directly access anything that contains a symbol,
nor can
we indirect via the constant pool
*/
/* We can't directly access anything that contains a symbol,
nor can we indirect via the constant pool.
*/
#define LEGITIMATE_PIC_OPERAND_P(X) \
(! symbol_mentioned_p (X) \
&& (! CONSTANT_POOL_ADDRESS_P (X) \
...
...
gcc/config/arm/arm.md
View file @
f5a1b0d2
...
...
@@ -45,10 +45,7 @@
; by the -mapcs-{32,26} flag, and possibly the -mcpu=... option.
(define_attr "prog_mode" "prog26,prog32" (const (symbol_ref "arm_prog_mode")))
; CPU attribute is used to determine the best instruction mix for performance
; on the named processor.
(define_attr "cpu" "arm2,arm3,arm6,arm7,arm8,arm9,st_arm"
(const (symbol_ref "arm_cpu_attr")))
(define_attr "is_strongarm" "no,yes" (const (symbol_ref "arm_is_strong")))
; Floating Point Unit. If we only have floating point emulation, then there
; is no point in scheduling the floating point insns. (Well, for best
...
...
@@ -100,11 +97,9 @@
"normal,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4"
(const_string "normal"))
; Load scheduling, set from the cpu characteristic
(define_attr "ldsched" "no,yes"
(if_then_else (eq_attr "cpu" "arm8,arm9,st_arm")
(const_string "yes")
(const_string "no")))
; Load scheduling, set from the arm_ld_sched variable
; initialised by arm_override_options()
(define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
; condition codes: this one is used by final_prescan_insn to speed up
; conditionalizing instructions. It saves having to scan the rtl to see if
...
...
@@ -137,10 +132,7 @@
; have one. Later ones, such as StrongARM, have write-back caches, so don't
; suffer blockages enough to warrent modelling this (and it can adversely
; affect the schedule).
(define_attr "model_wbuf" "no,yes"
(if_then_else (eq_attr "cpu" "arm6,arm7")
(const_string "yes")
(const_string "no")))
(define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_is_6_or_7")))
(define_attr "write_conflict" "no,yes"
(if_then_else (eq_attr "type"
...
...
@@ -267,13 +259,15 @@
(and (eq_attr "fpu" "fpa") (eq_attr "type" "f_mem_r")) 7 7)
(define_function_unit "core" 1 0
(and (eq_attr "
cpu" "!arm8,st_arm
") (eq_attr "type" "mult")) 16 16)
(and (eq_attr "
ldsched" "no
") (eq_attr "type" "mult")) 16 16)
(define_function_unit "core" 1 0
(and (eq_attr "cpu" "arm8") (eq_attr "type" "mult")) 4 4)
(and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "no"))
(eq_attr "type" "mult")) 4 4)
(define_function_unit "core" 1 0
(and (eq_attr "cpu" "st_arm") (eq_attr "type" "mult")) 3 2)
(and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "yes"))
(eq_attr "type" "mult")) 3 2)
(define_function_unit "core" 1 0 (eq_attr "type" "store2") 3 3)
...
...
@@ -1209,7 +1203,7 @@
(const_int 0)))
(clobber (match_scratch:QI 3 "=r"))]
"INTVAL (operands
[
2
]
) >= 0 && INTVAL (operands
[
1
]
) > 0
&& (
INTVAL (operands
[
2
]
) + INTVAL (operands
[
1
]
) <= 8)"
&& (
(INTVAL (operands
[
2
]
) + INTVAL (operands
[
1
]
)
) <= 8)"
"
*
operands
[
1
]
= GEN_INT (((1 << INTVAL (operands
[
1
]
)) - 1)
<< INTVAL (operands
[
2
]
));
...
...
@@ -2173,17 +2167,21 @@
""
"
{
if (
arm_arch4 &&
GET_CODE (operands
[
1
]
) == MEM)
if (GET_CODE (operands
[
1
]
) == MEM)
{
emit_insn (gen_rtx_SET (VOIDmode, operands
[
0
]
,
gen_rtx_ZERO_EXTEND (SImode, operands
[
1
]
)));
if (TARGET_SHORT_BY_BYTES)
{
emit_insn (gen_movhi_bytes (operands
[
0
]
, operands
[
1
]
));
DONE;
}
if (TARGET_SHORT_BY_BYTES && GET_CODE (operands
[
1
]
) == MEM
)
else if (arm_arch4
)
{
emit_insn (gen_movhi_bytes (operands
[
0
]
, operands
[
1
]
));
emit_insn (gen_rtx_SET (VOIDmode,
operands
[
0
]
,
gen_rtx_ZERO_EXTEND (SImode, operands
[
1
]
)));
DONE;
}
}
if (! s_register_operand (operands
[
1
]
, HImode))
operands
[
1
]
= copy_to_mode_reg (HImode, operands
[
1
]
);
operands
[
1
]
= gen_lowpart (SImode, operands
[
1
]
);
...
...
@@ -2275,18 +2273,20 @@
""
"
{
if (
arm_arch4 &&
GET_CODE (operands
[
1
]
) == MEM)
if (GET_CODE (operands
[
1
]
) == MEM)
{
emit_insn (gen_rtx_SET (VOIDmode, operands
[
0
]
,
gen_rtx_SIGN_EXTEND (SImode, operands
[
1
]
)));
if (TARGET_SHORT_BY_BYTES)
{
emit_insn (gen_extendhisi2_mem (operands
[
0
]
, operands
[
1
]
));
DONE;
}
if (TARGET_SHORT_BY_BYTES && GET_CODE (operands
[
1
]
) == MEM)
else if (arm_arch4)
{
emit_insn (gen_extendhisi2_mem (operands
[
0
]
, operands
[
1
]
));
emit_insn (gen_rtx_SET (VOIDmode, operands
[
0
]
,
gen_rtx_SIGN_EXTEND (SImode, operands
[
1
]
)));
DONE;
}
}
if (! s_register_operand (operands
[
1
]
, HImode))
operands
[
1
]
= copy_to_mode_reg (HImode, operands
[
1
]
);
operands
[
1
]
= gen_lowpart (SImode, operands
[
1
]
);
...
...
@@ -2381,7 +2381,8 @@
{
if (arm_arch4 && GET_CODE (operands
[
1
]
) == MEM)
{
emit_insn (gen_rtx_SET (VOIDmode, operands
[
0
]
,
emit_insn (gen_rtx_SET (VOIDmode,
operands
[
0
]
,
gen_rtx_SIGN_EXTEND (HImode, operands
[
1
]
)));
DONE;
}
...
...
@@ -2454,7 +2455,8 @@
{
if (arm_arch4 && GET_CODE (operands
[
1
]
) == MEM)
{
emit_insn (gen_rtx_SET (VOIDmode, operands
[
0
]
,
emit_insn (gen_rtx_SET (VOIDmode,
operands
[
0
]
,
gen_rtx_SIGN_EXTEND (SImode, operands
[
1
]
)));
DONE;
}
...
...
@@ -6136,7 +6138,6 @@
}
")
;; The next two patterns occur when an AND operation is followed by a
;; scc insn sequence
...
...
gcc/config/arm/elf.h
View file @
f5a1b0d2
/* Definitions of target machine for GNU compiler,
for ARM with ELF obj format.
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Copyright (C) 1995, 1996, 1997, 1998
, 1999
Free Software Foundation, Inc.
Contributed by Philip Blundell <philb@gnu.org> and
Catherine Moore <clm@cygnus.com>
...
...
@@ -100,7 +100,7 @@ Boston, MA 02111-1307, USA. */
by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \
do { \
char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
char *
name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \
&& ! AT_END && TOP_LEVEL \
&& DECL_INITIAL (DECL) == error_mark_node \
...
...
@@ -143,7 +143,7 @@ do { \
#ifndef ASM_SPEC
#define ASM_SPEC "%{mbig-endian:-EB} %{mcpu=*:-m%*} %{march=*:-m%*} \
%{mapcs-*:-mapcs-%*} %{mthumb-interwork:-mthumb-interwork}"
%{mapcs-*:-mapcs-%*} %{mthumb-interwork:-mthumb-interwork}
%{mapcs-float:mfloat}
"
#endif
#ifndef LINK_SPEC
...
...
@@ -198,9 +198,10 @@ arm_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
#ifndef ASM_FILE_START
#define ASM_FILE_START(STREAM) \
do { \
extern char *version_string; \
extern char *
version_string; \
fprintf (STREAM, "%s Generated by gcc %s for ARM/elf\n", \
ASM_COMMENT_START, version_string); \
output_file_directive ((STREAM), main_input_filename); \
} while (0)
#endif
...
...
@@ -209,7 +210,7 @@ do { \
#define ASM_OUTPUT_INTERNAL_LABEL(STREAM, PREFIX, NUM) \
do \
{ \
char *
s = (char *) alloca (40 + strlen (PREFIX));
\
char *
s = (char *) alloca (40 + strlen (PREFIX));
\
extern int arm_target_label, arm_ccfsm_state; \
extern rtx arm_target_insn; \
\
...
...
@@ -332,6 +333,3 @@ do { \
fputc ('\n', FILE); } while (0)
#include "arm/aout.h"
gcc/config/arm/linux-elf.h
View file @
f5a1b0d2
...
...
@@ -34,8 +34,20 @@ Boston, MA 02111-1307, USA. */
" %{mapcs-26:-mapcs-26} %(!mapcs-26:-mapcs-32}"
#endif
/* This was defined in linux.h. Define it here also. */
#undef DEFAULT_VTABLE_THUNKS
#define DEFAULT_VTABLE_THUNKS 1
/* Handle #pragma weak and #pragma pack. */
#define HANDLE_SYSV_PRAGMA
/* Now we define the strings used to build the spec file. */
#define LIB_SPEC "%{!shared:%{!symbolic:-lc}}"
#define LIB_SPEC \
"%{shared: -lc} \
%{!shared: %{pthread:-lpthread} \
%{profile:-lc_p} %{!profile: -lc}}"
#define LIBGCC_SPEC "%{msoft-float:-lfloat} -lgcc"
/* Add the compiler's crtend, and the library's crtn. */
#define ENDFILE_SPEC "%{!shared:crtend.o%s} %{shared:crtendS.o%s} \
...
...
@@ -64,6 +76,10 @@ Boston, MA 02111-1307, USA. */
#ifndef SUBTARGET_DEFAULT_APCS26
#undef CPP_APCS_PC_DEFAULT_SPEC
#define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__"
/* On 32-bit machine it is always safe to assume we have the "new"
floating point system. */
#undef FP_DEFAULT
#define FP_DEFAULT FP_SOFT3
#endif
/* Allow #sccs in preprocessor. */
...
...
@@ -201,5 +217,10 @@ const_section () \
assemble_name (FILE, NAME2); \
fputc ('\n', FILE); } while (0)
/* Make DWARF2 an option, but keep DBX as the default for now.
Use -gdwarf2 to turn on DWARF2. */
#define DWARF2_DEBUGGING_INFO
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
#include "arm/elf.h"
#include "arm/linux-gas.h"
gcc/config/arm/linux-gas.h
View file @
f5a1b0d2
/* Definitions of target machine for GNU compiler.
ARM Linux-based GNU systems version.
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
Copyright (C) 1997, 1998
, 1999
Free Software Foundation, Inc.
Contributed by Russell King <rmk92@ecs.soton.ac.uk>.
This file is part of GNU CC.
...
...
@@ -59,29 +59,25 @@ Boston, MA 02111-1307, USA. */
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE BITS_PER_WORD
#if 0 /* not yet */
/* Emit code to set up a trampoline and synchronise the caches. */
#undef INITIALIZE_TRAMPOLINE
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
{ \
emit_move_insn (gen_rtx (MEM, SImode, plus_constant ((TRAMP), 8)), \
(CXT)); \
emit_move_insn (gen_rtx (MEM, SImode, plus_constant ((TRAMP), 12)), \
(FNADDR)); \
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"), \
0, VOIDmode, 2, TRAMP, Pmode, \
plus_constant (TRAMP, TRAMPOLINE_SIZE), Pmode); \
}
/* Clear the instruction cache from `beg' to `end'. This makes an
inline system call to SYS_cacheflush. The arguments are as
follows:
cacheflush (start, end, flags)
*/
inline system call to SYS_cacheflush. */
#define CLEAR_INSN_CACHE(BEG, END) \
{ \
register unsigned long _beg __asm ("a1") = (unsigned long) (BEG); \
register unsigned long _end __asm ("a2") = (unsigned long) (END); \
register unsigned long _flg __asm ("a3") = 0; \
__asm __volatile ("swi 0x9
000b8
"); \
__asm __volatile ("swi 0x9
f0002
"); \
}
#endif
/* If cross-compiling, don't require stdio.h etc to build libgcc.a. */
#ifdef CROSS_COMPILE
#ifndef inhibit_libc
#define inhibit_libc
#endif
#endif
gcc/config/arm/t-arm-elf
View file @
f5a1b0d2
...
...
@@ -23,9 +23,11 @@ dp-bit.c: $(srcdir)/config/fp-bit.c
echo '#endif' >> dp-bit.c
cat $(srcdir)/config/fp-bit.c >> dp-bit.c
MULTILIB_OPTIONS = mlittle-endian/mbig-endian mhard-float/msoft-float mapcs-32/mapcs-26 fno-leading-underscore/fleading-underscore
MULTILIB_DIRNAMES = le be fpu soft 32bit 26bit elf under
MULTILIB_MATCHES =
#
MULTILIB_OPTIONS = mlittle-endian/mbig-endian mhard-float/msoft-float mapcs-32/mapcs-26 fno-leading-underscore/fleading-underscore
#
MULTILIB_DIRNAMES = le be fpu soft 32bit 26bit elf under
#
MULTILIB_MATCHES =
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
# LIBGCC = stmp-multilib
# INSTALL_LIBGCC = install-multilib
TARGET_LIBGCC2_CFLAGS = -Dinhibit_libc
gcc/config/arm/t-linux
View file @
f5a1b0d2
...
...
@@ -13,8 +13,10 @@ LIBGCC1 = libgcc1-asm.a
LIB1ASMSRC = arm/lib1funcs.asm
LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx
MULTILIB_OPTIONS = mapcs-32
MULTILIB_DIRNAMES = apcs-32
# If you want to build both APCS variants as multilib options this is how
# to do it.
#MULTILIB_OPTIONS = mapcs-32/apcs-26
#MULTILIB_DIRNAMES = apcs-32 apcs-26
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
gcc/invoke.texi
View file @
f5a1b0d2
...
...
@@ -170,7 +170,7 @@ in the following sections.
-
idirafter
@var
{
dir
}
-
include
@var
{
file
}
-
imacros
@var
{
file
}
-
iprefix
@var
{
file
}
-
iwithprefix
@var
{
dir
}
-
iwithprefixbefore
@var
{
dir
}
-
isystem
@var
{
dir
}
-
iwithprefixbefore
@var
{
dir
}
-
isystem
@var
{
dir
}
-
isystem
-
c
++
@var
{
dir
}
-
M
-
MD
-
MM
-
MMD
-
MG
-
nostdinc
-
P
-
trigraphs
-
undef
-
U
@var
{
macro
}
-
Wp
,
@var
{
option
}
@end
smallexample
...
...
@@ -259,6 +259,8 @@ in the following sections.
-
mcpu
=
-
march
=
-
mfpe
=
-
mstructure
-
size
-
boundary
=
-
mbsd
-
mxopen
-
mno
-
symrename
-
mabort
-
on
-
noreturn
-
mno
-
sched
-
prolog
@emph
{
Thumb
Options
}
-
mtpcs
-
frame
-
mno
-
tpcs
-
frame
...
...
@@ -1155,6 +1157,11 @@ offsets for adjusting the @samp{this} pointer at the call site. Newer
implementations
store
a
single
pointer
to
a
@samp
{
thunk
}
function
which
does
any
necessary
adjustment
and
then
calls
the
target
function
.
This
option
also
enables
a
heuristic
for
controlling
emission
of
vtables
;
if
a
class
has
any
non
-
inline
virtual
functions
,
the
vtable
will
be
emitted
in
the
translation
unit
containing
the
first
one
of
those
.
Like
all
options
that
change
the
ABI
,
all
C
++
code
,
@emph
{
including
libgcc
.
a
}
must
be
built
with
the
same
setting
of
this
option
.
...
...
@@ -3796,13 +3803,17 @@ suppresses this pass. The post-processor is never run when the
compiler
is
built
for
cross
-
compilation
.
@item
-
mcpu
=<
name
>
@item
-
mtune
=<
name
>
@kindex
-
mcpu
=
@kindex
-
mtune
=
This
specifies
the
name
of
the
target
ARM
processor
.
GCC
uses
this
name
to
determine
what
kind
of
instructions
it
can
use
when
generating
assembly
code
.
Permissable
names
are
:
arm2
,
arm250
,
arm3
,
arm6
,
arm60
,
arm600
,
arm610
,
arm620
,
arm7
,
arm7m
,
arm7d
,
arm7dm
,
arm7di
,
arm7dmi
,
arm70
,
arm700
,
arm700i
,
arm710
,
arm710c
,
arm7100
,
arm7500
,
arm7500fe
,
arm7tdmi
,
arm8
,
strongarm
,
strongarm110
arm7tdmi
,
arm8
,
strongarm
,
strongarm110
,
strongarm1100
,
arm8
,
arm810
,
arm9
,
arm9tdmi
.
@samp
{
-
mtune
=
}
is
a
synonym
for
@samp
{
-
mcpue
=
}
to
support
older
versions
of
GCC
.
@item
-
march
=<
name
>
@kindex
-
march
=
...
...
@@ -3813,9 +3824,12 @@ of the @samp{-mcpu=} option. Permissable names are: armv2, armv2a,
armv3
,
armv3m
,
armv4
,
armv4t
@item
-
mfpe
=<
number
>
@item
-
mfp
=<
number
>
@kindex
-
mfpe
=
@kindex
-
mfp
=
This
specifes
the
version
of
the
floating
point
emulation
available
on
the
target
.
Permissable
values
are
2
and
3
.
the
target
.
Permissable
values
are
2
and
3
.
@samp
{
-
mfp
=
}
is
a
synonym
for
@samp
{
-
mfpe
=
}
to
support
older
versions
of
GCC
.
@item
-
mstructure
-
size
-
boundary
=<
n
>
@kindex
-
mstructure
-
size
-
boundary
...
...
@@ -3830,6 +3844,12 @@ libraries compiled with the other value, if they exchange information
using
structures
or
unions
.
Programmers
are
encouraged
to
use
the
32
value
as
future
versions
of
the
toolchain
may
default
to
this
value
.
@item
-
mabort
-
on
-
noreturn
@kindex
-
mabort
-
on
-
noreturn
@kindex
-
mnoabort
-
on
-
noreturn
Generate
a
call
to
the
function
abort
at
the
end
of
a
noreturn
function
.
It
will
be
executed
if
the
function
tries
to
return
.
@end
table
@node
Thumb
Options
...
...
@@ -4666,7 +4686,9 @@ All modules should be compiled with the same @samp{-G @var{num}} value.
@itemx
-
mno
-
regnames
On
System
V
.
4
and
embedded
PowerPC
systems
do
(
do
not
)
emit
register
names
in
the
assembly
language
output
using
symbolic
forms
.
@end
table
@node
RT
Options
@subsection
IBM
RT
Options
@cindex
RT
options
...
...
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