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
b6c9286a
Commit
b6c9286a
authored
Nov 30, 1995
by
Michael Meissner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update PowerPC support
From-SVN: r10648
parent
1bad666c
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
1973 additions
and
914 deletions
+1973
-914
gcc/config/rs6000/aix3newas.h
+8
-0
gcc/config/rs6000/aix41.h
+8
-0
gcc/config/rs6000/eabi.asm
+304
-316
gcc/config/rs6000/eabi.h
+7
-46
gcc/config/rs6000/eabiaix.h
+19
-2
gcc/config/rs6000/eabile.h
+19
-2
gcc/config/rs6000/eabilesim.h
+7
-36
gcc/config/rs6000/eabisim.h
+7
-36
gcc/config/rs6000/mach.h
+1
-0
gcc/config/rs6000/netware.h
+3
-2
gcc/config/rs6000/powerpc.h
+5
-1
gcc/config/rs6000/rs6000.c
+713
-149
gcc/config/rs6000/rs6000.h
+116
-42
gcc/config/rs6000/rs6000.md
+456
-147
gcc/config/rs6000/sysv4.h
+269
-128
gcc/config/rs6000/sysv4le.h
+19
-2
gcc/config/rs6000/t-ppc
+2
-0
gcc/config/rs6000/t-ppcgas
+10
-5
No files found.
gcc/config/rs6000/aix3newas.h
View file @
b6c9286a
...
...
@@ -45,6 +45,7 @@ Boston, MA 02111-1307, USA. */
%{mcpu=403: -mppc} \
%{mcpu=601: -m601} \
%{mcpu=603: -mppc} \
%{mcpu=603e: -mppc} \
%{mcpu=604: -mppc}"
/* Define the options for the binder: Start text at 512, align all segments
...
...
@@ -65,10 +66,17 @@ Boston, MA 02111-1307, USA. */
as per README.RS6000. */
#undef LINK_SPEC
#ifndef CROSS_COMPILE
#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\
%{static:-bnso -bI:/lib/syscalls.exp} \
%{mcpu=common: milli.exp%s} \
%{!shared:%{g*:-bexport:/usr/lib/libg.exp}} %{shared:-bM:SRE}"
#else
#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\
%{static:-bnso} \
%{mcpu=common: milli.exp%s} \
%{shared:-bM:SRE}"
#endif
/* These are not necessary when we pass -u to the assembler, and undefining
them saves a great deal of space in object files. */
...
...
gcc/config/rs6000/aix41.h
View file @
b6c9286a
...
...
@@ -43,6 +43,7 @@ Boston, MA 02111-1307, USA. */
%{mcpu=403: -mppc} \
%{mcpu=601: -m601} \
%{mcpu=603: -mppc} \
%{mcpu=603e: -mppc} \
%{mcpu=604: -mppc}"
/* These are not necessary when we pass -u to the assembler, and undefining
...
...
@@ -65,6 +66,13 @@ Boston, MA 02111-1307, USA. */
}
#undef LINK_SPEC
#ifndef CROSS_COMPILE
#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\
%{static:-bnso -bI:/lib/syscalls.exp} %{g*:-bexport:/usr/lib/libg.exp}\
%{shared:-bM:SRE}"
#else
#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\
%{static:-bnso} \
%{shared:-bM:SRE}"
#endif
gcc/config/rs6000/eabi.asm
View file @
b6c9286a
#
File
to
either
setup
register
2
to
point
to
the
GOT
,
or
to
adjust
the
#
pointers
in
the
.
got2
section
to
point
to
their
new
addresses
.
/*
Do
any
initializations
needed
for
the
eabi
environment
*/
.
file
"eabi.asm"
.
section
".text"
.
globl
__eabi
#
include
"ppc-asm.h"
.
section
".got2"
,
"aw"
.
LCTOC1
=
.
#
+
32768
.
LCTOC1
=
.
/*
+
32768
*/
#
Table
of
addresses
/*
Table
of
addresses
*/
.
Ltable
=
.
-
.
LCTOC1
.
long
.
LCTOC1
#
address
we
are
really
at
.
long
.
LCTOC1
/*
address
we
are
really
at
*/
.
Lgot
=
.
-
.
LCTOC1
.
long
_GLOBAL_OFFSET_TABLE_
#
normal
GOT
address
.
long
_GLOBAL_OFFSET_TABLE_
/*
normal
GOT
address
*/
.
Lgots
=
.
-
.
LCTOC1
.
long
_GOT_START_
#
start
of
.
got
section
.
long
_GOT_START_
/*
start
of
.
got
section
*/
.
Lgote
=
.
-
.
LCTOC1
.
long
_GOT_END_
#
end
of
.
got
section
.
long
_GOT_END_
/*
end
of
.
got
section
*/
.
Lgot2s
=
.
-
.
LCTOC1
.
long
_GOT2_START_
#
-
mrelocatable
GOT
pointers
start
.
long
_GOT2_START_
/*
-
mrelocatable
GOT
pointers
start
*/
.
Lgot2e
=
.
-
.
LCTOC1
.
long
_GOT2_END_
#
-
mrelocatable
GOT
pointers
end
.
long
_GOT2_END_
/*
-
mrelocatable
GOT
pointers
end
*/
.
Lfixups
=
.
-
.
LCTOC1
.
long
_FIXUP_START_
#
start
of
.
fixup
section
.
long
_FIXUP_START_
/*
start
of
.
fixup
section
*/
.
Lfixupe
=
.
-
.
LCTOC1
.
long
_FIXUP_END_
#
end
of
.
fixup
section
.
long
_FIXUP_END_
/*
end
of
.
fixup
section
*/
.
text
.
Lptr
:
.
long
.
LCTOC1
-
.
Laddr
#
PC
relative
pointer
to
.
got2
.
long
0x4000
#
traceback
table
.
long
.
LCTOC1
-
.
Laddr
/*
PC
relative
pointer
to
.
got2
*/
__eabi
:
mflr
0
bl
.
Laddr
#
get
current
address
FUNC_START
(
__eabi
)
mflr
0
bl
.
Laddr
/*
get
current
address
*/
.
Laddr
:
mflr
12
#
real
address
of
.
Laddr
lwz
11
,(.
Lptr
-
.
Laddr
)(
12
)
#
linker
generated
address
of
.
LCTOC1
add
11
,
11
,
12
#
correct
to
real
pointer
lwz
12
,.
Ltable
(
11
)
#
get
linker
'
s
idea
of
where
.
Laddr
is
subf
.
12
,
12
,
11
#
calculate
difference
mtlr
0
#
restore
link
register
bc
4
,
2
,.
Lreloc
#
skip
if
we
need
to
relocate
#
Only
load
up
register
2
if
there
is
a
.
got
section
lwz
3
,.
Lgots
(
11
)
#
start
of
.
got
section
lwz
4
,.
Lgote
(
11
)
#
end
of
.
got
section
cmpw
1
,
3
,
4
#
.
got
section
non
-
empty
?
mflr
12
/*
real
address
of
.
Laddr
*/
lwz
11
,(.
Lptr
-
.
Laddr
)(
12
)
/*
linker
generated
address
of
.
LCTOC1
*/
add
11
,
11
,
12
/*
correct
to
real
pointer
*/
lwz
12
,.
Ltable
(
11
)
/*
get
linker
'
s
idea
of
where
.
Laddr
is
*/
subf
.
12
,
12
,
11
/*
calculate
difference
*/
mtlr
0
/*
restore
link
register
*/
bc
4
,
2
,.
Lreloc
/*
skip
if
we
need
to
relocate
*/
/*
Only
load
up
register
2
if
there
is
a
.
got
section
*/
lwz
3
,.
Lgots
(
11
)
/*
start
of
.
got
section
*/
lwz
4
,.
Lgote
(
11
)
/*
end
of
.
got
section
*/
cmpw
1
,
3
,
4
/*
.
got
section
non
-
empty
?
*/
bc
12
,
6
,.
Ldone
#
Normal
program
,
load
up
register
2
/*
Normal
program
,
load
up
register
2
*/
lwz
2
,.
Lgot
(
11
)
#
normal
GOT
address
(
obsolete
in
register
2
)
mr
13
,
2
#
also
same
as
_SDA_BASE_
(
V
.
4
small
data
ptr
)
b
__do_global_ctors
#
do
any
C
++
global
constructors
(
which
returns
to
caller
)
lwz
2
,.
Lgot
(
11
)
/*
normal
GOT
address
(
obsolete
in
register
2
)
*/
mr
13
,
2
/*
also
same
as
_SDA_BASE_
(
V
.
4
small
data
ptr
)
*/
b
FUNC_NAME
(
__do_global_ctors
)
/*
do
any
C
++
global
constructors
(
which
returns
to
caller
)
*/
#
We
need
to
relocate
the
.
got2
pointers
.
Don
'
t
load
register
2
/*
We
need
to
relocate
the
.
got2
pointers
.
Don
'
t
load
register
2
*/
.
Lreloc
:
lwz
3
,.
Lgot2s
(
11
)
#
GOT
pointers
start
lwz
4
,.
Lgot2e
(
11
)
#
GOT
pointers
end
add
3
,
12
,
3
#
adjust
pointers
lwz
3
,.
Lgot2s
(
11
)
/*
GOT
pointers
start
*/
lwz
4
,.
Lgot2e
(
11
)
/*
GOT
pointers
end
*/
add
3
,
12
,
3
/*
adjust
pointers
*/
add
4
,
12
,
4
cmpw
1
,
3
,
4
#
any
pointers
to
adjust
cmpw
1
,
3
,
4
/*
any
pointers
to
adjust
*/
bc
12
,
6
,.
Lfix
.
Lloop
:
lwz
5
,
0
(
3
)
#
next
pointer
add
5
,
5
,
12
#
adjust
lwz
5
,
0
(
3
)
/*
next
pointer
*/
add
5
,
5
,
12
/*
adjust
*/
stw
5
,
0
(
3
)
addi
3
,
3
,
4
#
bump
to
next
word
cmpw
1
,
3
,
4
#
more
pointers
to
adjust
?
addi
3
,
3
,
4
/*
bump
to
next
word
*/
cmpw
1
,
3
,
4
/*
more
pointers
to
adjust
?
*/
bc
4
,
6
,.
Lloop
#
Fixup
any
user
initialized
pointers
now
(
the
compiler
drops
pointers
to
#
each
of
the
relocs
that
it
does
in
the
.
fixup
section
).
Note
,
the
pointers
#
themselves
have
already
been
fixed
up
by
the
previous
loop
.
/*
Fixup
any
user
initialized
pointers
now
(
the
compiler
drops
pointers
to
*/
/*
each
of
the
relocs
that
it
does
in
the
.
fixup
section
).
Note
,
the
pointers
*/
/*
themselves
have
already
been
fixed
up
by
the
previous
loop
.
*/
.
Lfix
:
lwz
3
,.
Lfixups
(
11
)
#
fixup
pointers
start
lwz
4
,.
Lfixupe
(
11
)
#
fixup
pointers
end
lwz
3
,.
Lfixups
(
11
)
/*
fixup
pointers
start
*/
lwz
4
,.
Lfixupe
(
11
)
/*
fixup
pointers
end
*/
cmpw
1
,
3
,
4
#
any
user
pointers
to
adjust
cmpw
1
,
3
,
4
/*
any
user
pointers
to
adjust
*/
bc
12
,
6
,.
Ldone
.
Lfloop
:
lwz
5
,
0
(
3
)
#
next
pointer
lwz
6
,
0
(
5
)
#
get
the
pointer
it
points
to
add
6
,
6
,
12
#
adjust
lwz
5
,
0
(
3
)
/*
next
pointer
*/
lwz
6
,
0
(
5
)
/*
get
the
pointer
it
points
to
*/
add
6
,
6
,
12
/*
adjust
*/
stw
6
,
0
(
5
)
addi
3
,
3
,
4
#
bump
to
next
word
cmpw
1
,
3
,
4
#
more
pointers
to
adjust
?
addi
3
,
3
,
4
/*
bump
to
next
word
*/
cmpw
1
,
3
,
4
/*
more
pointers
to
adjust
?
*/
bc
4
,
6
,.
Lfloop
#
Done
adjusting
pointers
,
return
/*
Done
adjusting
pointers
,
return
*/
.
Ldone
:
b
__do_global_ctors
#
do
any
C
++
global
constructors
(
which
returns
to
caller
)
#
Routines
for
saving
floating
point
registers
,
called
by
the
compiler
.
#
Called
with
r11
pointing
to
the
stack
header
word
of
the
caller
of
the
#
function
,
just
beyond
the
end
of
the
floating
point
save
area
.
.
globl
_savefpr_14
.
globl
_savefpr_15
.
globl
_savefpr_16
.
globl
_savefpr_17
.
globl
_savefpr_18
.
globl
_savefpr_19
.
globl
_savefpr_20
.
globl
_savefpr_21
.
globl
_savefpr_22
.
globl
_savefpr_23
.
globl
_savefpr_24
.
globl
_savefpr_25
.
globl
_savefpr_26
.
globl
_savefpr_27
.
globl
_savefpr_28
.
globl
_savefpr_29
.
globl
_savefpr_30
.
globl
_savefpr_31
.
long
0x00400000
#
traceback
tag
_savefpr_14
:
stfd
14
,
-
144
(
11
)
#
save
fp
registers
_savefpr_15
:
stfd
15
,
-
136
(
11
)
_savefpr_16
:
stfd
16
,
-
128
(
11
)
_savefpr_17
:
stfd
17
,
-
120
(
11
)
_savefpr_18
:
stfd
18
,
-
112
(
11
)
_savefpr_19
:
stfd
19
,
-
104
(
11
)
_savefpr_20
:
stfd
20
,
-
96
(
11
)
_savefpr_21
:
stfd
21
,
-
88
(
11
)
_savefpr_22
:
stfd
22
,
-
80
(
11
)
_savefpr_23
:
stfd
23
,
-
72
(
11
)
_savefpr_24
:
stfd
24
,
-
64
(
11
)
_savefpr_25
:
stfd
25
,
-
56
(
11
)
_savefpr_26
:
stfd
26
,
-
48
(
11
)
_savefpr_27
:
stfd
27
,
-
40
(
11
)
_savefpr_28
:
stfd
28
,
-
32
(
11
)
_savefpr_29
:
stfd
29
,
-
24
(
11
)
_savefpr_30
:
stfd
30
,
-
16
(
11
)
_savefpr_31
:
stfd
31
,
-
8
(
11
)
b
FUNC_NAME
(
__do_global_ctors
)
/*
do
any
C
++
global
constructors
(
which
returns
to
caller
)
*/
FUNC_END
(
__eabi
)
/*
Routines
for
saving
floating
point
registers
,
called
by
the
compiler
.
*/
/*
Called
with
r11
pointing
to
the
stack
header
word
of
the
caller
of
the
*/
/*
function
,
just
beyond
the
end
of
the
floating
point
save
area
.
*/
FUNC_START
(
_savefpr_14
)
stfd
14
,
-
144
(
11
)
/*
save
fp
registers
*/
FUNC_START
(
_savefpr_15
)
stfd
15
,
-
136
(
11
)
FUNC_START
(
_savefpr_16
)
stfd
16
,
-
128
(
11
)
FUNC_START
(
_savefpr_17
)
stfd
17
,
-
120
(
11
)
FUNC_START
(
_savefpr_18
)
stfd
18
,
-
112
(
11
)
FUNC_START
(
_savefpr_19
)
stfd
19
,
-
104
(
11
)
FUNC_START
(
_savefpr_20
)
stfd
20
,
-
96
(
11
)
FUNC_START
(
_savefpr_21
)
stfd
21
,
-
88
(
11
)
FUNC_START
(
_savefpr_22
)
stfd
22
,
-
80
(
11
)
FUNC_START
(
_savefpr_23
)
stfd
23
,
-
72
(
11
)
FUNC_START
(
_savefpr_24
)
stfd
24
,
-
64
(
11
)
FUNC_START
(
_savefpr_25
)
stfd
25
,
-
56
(
11
)
FUNC_START
(
_savefpr_26
)
stfd
26
,
-
48
(
11
)
FUNC_START
(
_savefpr_27
)
stfd
27
,
-
40
(
11
)
FUNC_START
(
_savefpr_28
)
stfd
28
,
-
32
(
11
)
FUNC_START
(
_savefpr_29
)
stfd
29
,
-
24
(
11
)
FUNC_START
(
_savefpr_30
)
stfd
30
,
-
16
(
11
)
FUNC_START
(
_savefpr_31
)
stfd
31
,
-
8
(
11
)
blr
#
Routines
for
saving
integer
registers
,
called
by
the
compiler
.
#
Called
with
r11
pointing
to
the
stack
header
word
of
the
caller
of
the
#
function
,
just
beyond
the
end
of
the
integer
save
area
.
.
globl
_savegpr_14
.
globl
_savegpr_15
.
globl
_savegpr_16
.
globl
_savegpr_17
.
globl
_savegpr_18
.
globl
_savegpr_19
.
globl
_savegpr_20
.
globl
_savegpr_21
.
globl
_savegpr_22
.
globl
_savegpr_23
.
globl
_savegpr_24
.
globl
_savegpr_25
.
globl
_savegpr_26
.
globl
_savegpr_27
.
globl
_savegpr_28
.
globl
_savegpr_29
.
globl
_savegpr_30
.
globl
_savegpr_31
.
long
0x00400000
#
traceback
tag
_savegpr_14
:
stw
14
,
-
72
(
11
)
#
save
gp
registers
_savegpr_15
:
stw
15
,
-
68
(
11
)
_savegpr_16
:
stw
16
,
-
64
(
11
)
_savegpr_17
:
stw
17
,
-
60
(
11
)
_savegpr_18
:
stw
18
,
-
56
(
11
)
_savegpr_19
:
stw
19
,
-
52
(
11
)
_savegpr_20
:
stw
20
,
-
48
(
11
)
_savegpr_21
:
stw
21
,
-
44
(
11
)
_savegpr_22
:
stw
22
,
-
40
(
11
)
_savegpr_23
:
stw
23
,
-
36
(
11
)
_savegpr_24
:
stw
24
,
-
32
(
11
)
_savegpr_25
:
stw
25
,
-
28
(
11
)
_savegpr_26
:
stw
26
,
-
24
(
11
)
_savegpr_27
:
stw
27
,
-
20
(
11
)
_savegpr_28
:
stw
28
,
-
16
(
11
)
_savegpr_29
:
stw
29
,
-
12
(
11
)
_savegpr_30
:
stw
30
,
-
8
(
11
)
_savegpr_31
:
stw
31
,
-
4
(
11
)
FUNC_END
(
_savefpr_31
)
FUNC_END
(
_savefpr_30
)
FUNC_END
(
_savefpr_29
)
FUNC_END
(
_savefpr_28
)
FUNC_END
(
_savefpr_27
)
FUNC_END
(
_savefpr_26
)
FUNC_END
(
_savefpr_25
)
FUNC_END
(
_savefpr_24
)
FUNC_END
(
_savefpr_23
)
FUNC_END
(
_savefpr_22
)
FUNC_END
(
_savefpr_21
)
FUNC_END
(
_savefpr_20
)
FUNC_END
(
_savefpr_19
)
FUNC_END
(
_savefpr_18
)
FUNC_END
(
_savefpr_17
)
FUNC_END
(
_savefpr_16
)
FUNC_END
(
_savefpr_15
)
FUNC_END
(
_savefpr_14
)
/*
Routines
for
saving
integer
registers
,
called
by
the
compiler
.
*/
/*
Called
with
r11
pointing
to
the
stack
header
word
of
the
caller
of
the
*/
/*
function
,
just
beyond
the
end
of
the
integer
save
area
.
*/
FUNC_START
(
_savegpr_14
)
stw
14
,
-
72
(
11
)
/*
save
gp
registers
*/
FUNC_START
(
_savegpr_15
)
stw
15
,
-
68
(
11
)
FUNC_START
(
_savegpr_16
)
stw
16
,
-
64
(
11
)
FUNC_START
(
_savegpr_17
)
stw
17
,
-
60
(
11
)
FUNC_START
(
_savegpr_18
)
stw
18
,
-
56
(
11
)
FUNC_START
(
_savegpr_19
)
stw
19
,
-
52
(
11
)
FUNC_START
(
_savegpr_20
)
stw
20
,
-
48
(
11
)
FUNC_START
(
_savegpr_21
)
stw
21
,
-
44
(
11
)
FUNC_START
(
_savegpr_22
)
stw
22
,
-
40
(
11
)
FUNC_START
(
_savegpr_23
)
stw
23
,
-
36
(
11
)
FUNC_START
(
_savegpr_24
)
stw
24
,
-
32
(
11
)
FUNC_START
(
_savegpr_25
)
stw
25
,
-
28
(
11
)
FUNC_START
(
_savegpr_26
)
stw
26
,
-
24
(
11
)
FUNC_START
(
_savegpr_27
)
stw
27
,
-
20
(
11
)
FUNC_START
(
_savegpr_28
)
stw
28
,
-
16
(
11
)
FUNC_START
(
_savegpr_29
)
stw
29
,
-
12
(
11
)
FUNC_START
(
_savegpr_30
)
stw
30
,
-
8
(
11
)
FUNC_START
(
_savegpr_31
)
stw
31
,
-
4
(
11
)
blr
#
Routines
for
restoring
floating
point
registers
,
called
by
the
compiler
.
#
Called
with
r11
pointing
to
the
stack
header
word
of
the
caller
of
the
#
function
,
just
beyond
the
end
of
the
floating
point
save
area
.
.
globl
_restfpr_14
.
globl
_restfpr_15
.
globl
_restfpr_16
.
globl
_restfpr_17
.
globl
_restfpr_18
.
globl
_restfpr_19
.
globl
_restfpr_20
.
globl
_restfpr_21
.
globl
_restfpr_22
.
globl
_restfpr_23
.
globl
_restfpr_24
.
globl
_restfpr_25
.
globl
_restfpr_26
.
globl
_restfpr_27
.
globl
_restfpr_28
.
globl
_restfpr_29
.
globl
_restfpr_30
.
globl
_restfpr_31
.
long
0x00600000
#
traceback
tag
_restfpr_14
:
lfd
14
,
-
144
(
11
)
#
restore
fp
registers
_restfpr_15
:
lfd
15
,
-
136
(
11
)
_restfpr_16
:
lfd
16
,
-
128
(
11
)
_restfpr_17
:
lfd
17
,
-
120
(
11
)
_restfpr_18
:
lfd
18
,
-
112
(
11
)
_restfpr_19
:
lfd
19
,
-
104
(
11
)
_restfpr_20
:
lfd
20
,
-
96
(
11
)
_restfpr_21
:
lfd
21
,
-
88
(
11
)
_restfpr_22
:
lfd
22
,
-
80
(
11
)
_restfpr_23
:
lfd
23
,
-
72
(
11
)
_restfpr_24
:
lfd
24
,
-
64
(
11
)
_restfpr_25
:
lfd
25
,
-
56
(
11
)
_restfpr_26
:
lfd
26
,
-
48
(
11
)
_restfpr_27
:
lfd
27
,
-
40
(
11
)
_restfpr_28
:
lfd
28
,
-
32
(
11
)
_restfpr_29
:
lfd
29
,
-
24
(
11
)
_restfpr_30
:
lfd
30
,
-
16
(
11
)
_restfpr_31
:
lfd
31
,
-
8
(
11
)
FUNC_END
(
_savegpr_31
)
FUNC_END
(
_savegpr_30
)
FUNC_END
(
_savegpr_29
)
FUNC_END
(
_savegpr_28
)
FUNC_END
(
_savegpr_27
)
FUNC_END
(
_savegpr_26
)
FUNC_END
(
_savegpr_25
)
FUNC_END
(
_savegpr_24
)
FUNC_END
(
_savegpr_23
)
FUNC_END
(
_savegpr_22
)
FUNC_END
(
_savegpr_21
)
FUNC_END
(
_savegpr_20
)
FUNC_END
(
_savegpr_19
)
FUNC_END
(
_savegpr_18
)
FUNC_END
(
_savegpr_17
)
FUNC_END
(
_savegpr_16
)
FUNC_END
(
_savegpr_15
)
FUNC_END
(
_savegpr_14
)
/*
Routines
for
restoring
floating
point
registers
,
called
by
the
compiler
.
*/
/*
Called
with
r11
pointing
to
the
stack
header
word
of
the
caller
of
the
*/
/*
function
,
just
beyond
the
end
of
the
floating
point
save
area
.
*/
FUNC_START
(
_restfpr_14
)
lfd
14
,
-
144
(
11
)
/*
restore
fp
registers
*/
FUNC_START
(
_restfpr_15
)
lfd
15
,
-
136
(
11
)
FUNC_START
(
_restfpr_16
)
lfd
16
,
-
128
(
11
)
FUNC_START
(
_restfpr_17
)
lfd
17
,
-
120
(
11
)
FUNC_START
(
_restfpr_18
)
lfd
18
,
-
112
(
11
)
FUNC_START
(
_restfpr_19
)
lfd
19
,
-
104
(
11
)
FUNC_START
(
_restfpr_20
)
lfd
20
,
-
96
(
11
)
FUNC_START
(
_restfpr_21
)
lfd
21
,
-
88
(
11
)
FUNC_START
(
_restfpr_22
)
lfd
22
,
-
80
(
11
)
FUNC_START
(
_restfpr_23
)
lfd
23
,
-
72
(
11
)
FUNC_START
(
_restfpr_24
)
lfd
24
,
-
64
(
11
)
FUNC_START
(
_restfpr_25
)
lfd
25
,
-
56
(
11
)
FUNC_START
(
_restfpr_26
)
lfd
26
,
-
48
(
11
)
FUNC_START
(
_restfpr_27
)
lfd
27
,
-
40
(
11
)
FUNC_START
(
_restfpr_28
)
lfd
28
,
-
32
(
11
)
FUNC_START
(
_restfpr_29
)
lfd
29
,
-
24
(
11
)
FUNC_START
(
_restfpr_30
)
lfd
30
,
-
16
(
11
)
FUNC_START
(
_restfpr_31
)
lfd
31
,
-
8
(
11
)
blr
#
Routines
for
restoring
integer
registers
,
called
by
the
compiler
.
#
Called
with
r11
pointing
to
the
stack
header
word
of
the
caller
of
the
#
function
,
just
beyond
the
end
of
the
integer
restore
area
.
.
globl
_restgpr_14
.
globl
_restgpr_15
.
globl
_restgpr_16
.
globl
_restgpr_17
.
globl
_restgpr_18
.
globl
_restgpr_19
.
globl
_restgpr_20
.
globl
_restgpr_21
.
globl
_restgpr_22
.
globl
_restgpr_23
.
globl
_restgpr_24
.
globl
_restgpr_25
.
globl
_restgpr_26
.
globl
_restgpr_27
.
globl
_restgpr_28
.
globl
_restgpr_29
.
globl
_restgpr_30
.
globl
_restgpr_31
.
long
0x00600000
#
traceback
tag
_restgpr_14
:
lwz
14
,
-
72
(
11
)
#
rest
gp
registers
_restgpr_15
:
lwz
15
,
-
68
(
11
)
_restgpr_16
:
lwz
16
,
-
64
(
11
)
_restgpr_17
:
lwz
17
,
-
60
(
11
)
_restgpr_18
:
lwz
18
,
-
56
(
11
)
_restgpr_19
:
lwz
19
,
-
52
(
11
)
_restgpr_20
:
lwz
20
,
-
48
(
11
)
_restgpr_21
:
lwz
21
,
-
44
(
11
)
_restgpr_22
:
lwz
22
,
-
40
(
11
)
_restgpr_23
:
lwz
23
,
-
36
(
11
)
_restgpr_24
:
lwz
24
,
-
32
(
11
)
_restgpr_25
:
lwz
25
,
-
28
(
11
)
_restgpr_26
:
lwz
26
,
-
24
(
11
)
_restgpr_27
:
lwz
27
,
-
20
(
11
)
_restgpr_28
:
lwz
28
,
-
16
(
11
)
_restgpr_29
:
lwz
29
,
-
12
(
11
)
_restgpr_30
:
lwz
30
,
-
8
(
11
)
_restgpr_31
:
lwz
31
,
-
4
(
11
)
FUNC_END
(
_restfpr_31
)
FUNC_END
(
_restfpr_30
)
FUNC_END
(
_restfpr_29
)
FUNC_END
(
_restfpr_28
)
FUNC_END
(
_restfpr_27
)
FUNC_END
(
_restfpr_26
)
FUNC_END
(
_restfpr_25
)
FUNC_END
(
_restfpr_24
)
FUNC_END
(
_restfpr_23
)
FUNC_END
(
_restfpr_22
)
FUNC_END
(
_restfpr_21
)
FUNC_END
(
_restfpr_20
)
FUNC_END
(
_restfpr_19
)
FUNC_END
(
_restfpr_18
)
FUNC_END
(
_restfpr_17
)
FUNC_END
(
_restfpr_16
)
FUNC_END
(
_restfpr_15
)
FUNC_END
(
_restfpr_14
)
/*
Routines
for
restoring
integer
registers
,
called
by
the
compiler
.
*/
/*
Called
with
r11
pointing
to
the
stack
header
word
of
the
caller
of
the
*/
/*
function
,
just
beyond
the
end
of
the
integer
restore
area
.
*/
FUNC_START
(
_restgpr_14
)
lwz
14
,
-
72
(
11
)
/*
restore
gp
registers
*/
FUNC_START
(
_restgpr_15
)
lwz
15
,
-
68
(
11
)
FUNC_START
(
_restgpr_16
)
lwz
16
,
-
64
(
11
)
FUNC_START
(
_restgpr_17
)
lwz
17
,
-
60
(
11
)
FUNC_START
(
_restgpr_18
)
lwz
18
,
-
56
(
11
)
FUNC_START
(
_restgpr_19
)
lwz
19
,
-
52
(
11
)
FUNC_START
(
_restgpr_20
)
lwz
20
,
-
48
(
11
)
FUNC_START
(
_restgpr_21
)
lwz
21
,
-
44
(
11
)
FUNC_START
(
_restgpr_22
)
lwz
22
,
-
40
(
11
)
FUNC_START
(
_restgpr_23
)
lwz
23
,
-
36
(
11
)
FUNC_START
(
_restgpr_24
)
lwz
24
,
-
32
(
11
)
FUNC_START
(
_restgpr_25
)
lwz
25
,
-
28
(
11
)
FUNC_START
(
_restgpr_26
)
lwz
26
,
-
24
(
11
)
FUNC_START
(
_restgpr_27
)
lwz
27
,
-
20
(
11
)
FUNC_START
(
_restgpr_28
)
lwz
28
,
-
16
(
11
)
FUNC_START
(
_restgpr_29
)
lwz
29
,
-
12
(
11
)
FUNC_START
(
_restgpr_30
)
lwz
30
,
-
8
(
11
)
FUNC_START
(
_restgpr_31
)
lwz
31
,
-
4
(
11
)
blr
#
Routines
for
restoring
floating
point
registers
,
called
by
the
compiler
.
#
Called
with
r11
pointing
to
the
stack
header
word
of
the
caller
of
the
#
function
,
just
beyond
the
end
of
the
floating
point
save
area
.
#
In
addition
to
restoring
the
fp
registers
,
it
will
return
to
the
caller
'
s
#
caller
.
globl
_restfpr_14_x
.
globl
_restfpr_15_x
.
globl
_restfpr_16_x
.
globl
_restfpr_17_x
.
globl
_restfpr_18_x
.
globl
_restfpr_19_x
.
globl
_restfpr_20_x
.
globl
_restfpr_21_x
.
globl
_restfpr_22_x
.
globl
_restfpr_23_x
.
globl
_restfpr_24_x
.
globl
_restfpr_25_x
.
globl
_restfpr_26_x
.
globl
_restfpr_27_x
.
globl
_restfpr_28_x
.
globl
_restfpr_29_x
.
globl
_restfpr_30_x
.
globl
_restfpr_31_x
.
long
0x00600000
#
traceback
tag
_restfpr_14_x
:
lfd
14
,
-
144
(
11
)
#
restore
fp
registers
_restfpr_15_x
:
lfd
15
,
-
136
(
11
)
_restfpr_16_x
:
lfd
16
,
-
128
(
11
)
_restfpr_17_x
:
lfd
17
,
-
120
(
11
)
_restfpr_18_x
:
lfd
18
,
-
112
(
11
)
_restfpr_19_x
:
lfd
19
,
-
104
(
11
)
_restfpr_20_x
:
lfd
20
,
-
96
(
11
)
_restfpr_21_x
:
lfd
21
,
-
88
(
11
)
_restfpr_22_x
:
lfd
22
,
-
80
(
11
)
_restfpr_23_x
:
lfd
23
,
-
72
(
11
)
_restfpr_24_x
:
lfd
24
,
-
64
(
11
)
_restfpr_25_x
:
lfd
25
,
-
56
(
11
)
_restfpr_26_x
:
lfd
26
,
-
48
(
11
)
_restfpr_27_x
:
lfd
27
,
-
40
(
11
)
_restfpr_28_x
:
lfd
28
,
-
32
(
11
)
_restfpr_29_x
:
lfd
29
,
-
24
(
11
)
_restfpr_30_x
:
lfd
30
,
-
16
(
11
)
_restfpr_31_x
:
lwz
0
,
4
(
11
)
FUNC_END
(
_restgpr_31
)
FUNC_END
(
_restgpr_30
)
FUNC_END
(
_restgpr_29
)
FUNC_END
(
_restgpr_28
)
FUNC_END
(
_restgpr_27
)
FUNC_END
(
_restgpr_26
)
FUNC_END
(
_restgpr_25
)
FUNC_END
(
_restgpr_24
)
FUNC_END
(
_restgpr_23
)
FUNC_END
(
_restgpr_22
)
FUNC_END
(
_restgpr_21
)
FUNC_END
(
_restgpr_20
)
FUNC_END
(
_restgpr_19
)
FUNC_END
(
_restgpr_18
)
FUNC_END
(
_restgpr_17
)
FUNC_END
(
_restgpr_16
)
FUNC_END
(
_restgpr_15
)
FUNC_END
(
_restgpr_14
)
/*
Routines
for
restoring
floating
point
registers
,
called
by
the
compiler
.
*/
/*
Called
with
r11
pointing
to
the
stack
header
word
of
the
caller
of
the
*/
/*
function
,
just
beyond
the
end
of
the
floating
point
save
area
.
*/
/*
In
addition
to
restoring
the
fp
registers
,
it
will
return
to
the
caller
'
s
*/
/*
caller
*/
FUNC_START
(
_restfpr_14_x
)
lfd
14
,
-
144
(
11
)
/*
restore
fp
registers
*/
FUNC_START
(
_restfpr_15_x
)
lfd
15
,
-
136
(
11
)
FUNC_START
(
_restfpr_16_x
)
lfd
16
,
-
128
(
11
)
FUNC_START
(
_restfpr_17_x
)
lfd
17
,
-
120
(
11
)
FUNC_START
(
_restfpr_18_x
)
lfd
18
,
-
112
(
11
)
FUNC_START
(
_restfpr_19_x
)
lfd
19
,
-
104
(
11
)
FUNC_START
(
_restfpr_20_x
)
lfd
20
,
-
96
(
11
)
FUNC_START
(
_restfpr_21_x
)
lfd
21
,
-
88
(
11
)
FUNC_START
(
_restfpr_22_x
)
lfd
22
,
-
80
(
11
)
FUNC_START
(
_restfpr_23_x
)
lfd
23
,
-
72
(
11
)
FUNC_START
(
_restfpr_24_x
)
lfd
24
,
-
64
(
11
)
FUNC_START
(
_restfpr_25_x
)
lfd
25
,
-
56
(
11
)
FUNC_START
(
_restfpr_26_x
)
lfd
26
,
-
48
(
11
)
FUNC_START
(
_restfpr_27_x
)
lfd
27
,
-
40
(
11
)
FUNC_START
(
_restfpr_28_x
)
lfd
28
,
-
32
(
11
)
FUNC_START
(
_restfpr_29_x
)
lfd
29
,
-
24
(
11
)
FUNC_START
(
_restfpr_30_x
)
lfd
30
,
-
16
(
11
)
FUNC_START
(
_restfpr_31_x
)
lwz
0
,
4
(
11
)
lfd
31
,
-
8
(
11
)
mtlr
0
mr
1
,
11
blr
#
Routines
for
restoring
integer
registers
,
called
by
the
compiler
.
#
Called
with
r11
pointing
to
the
stack
header
word
of
the
caller
of
the
#
function
,
just
beyond
the
end
of
the
integer
restore
area
.
.
globl
_restgpr_14_x
.
globl
_restgpr_15_x
.
globl
_restgpr_16_x
.
globl
_restgpr_17_x
.
globl
_restgpr_18_x
.
globl
_restgpr_19_x
.
globl
_restgpr_20_x
.
globl
_restgpr_21_x
.
globl
_restgpr_22_x
.
globl
_restgpr_23_x
.
globl
_restgpr_24_x
.
globl
_restgpr_25_x
.
globl
_restgpr_26_x
.
globl
_restgpr_27_x
.
globl
_restgpr_28_x
.
globl
_restgpr_29_x
.
globl
_restgpr_30_x
.
globl
_restgpr_31_x
.
long
0x00600000
#
traceback
tag
_restgpr_14_x
:
lwz
14
,
-
72
(
11
)
#
rest
gp
registers
_restgpr_15_x
:
lwz
15
,
-
68
(
11
)
_restgpr_16_x
:
lwz
16
,
-
64
(
11
)
_restgpr_17_x
:
lwz
17
,
-
60
(
11
)
_restgpr_18_x
:
lwz
18
,
-
56
(
11
)
_restgpr_19_x
:
lwz
19
,
-
52
(
11
)
_restgpr_20_x
:
lwz
20
,
-
48
(
11
)
_restgpr_21_x
:
lwz
21
,
-
44
(
11
)
_restgpr_22_x
:
lwz
22
,
-
40
(
11
)
_restgpr_23_x
:
lwz
23
,
-
36
(
11
)
_restgpr_24_x
:
lwz
24
,
-
32
(
11
)
_restgpr_25_x
:
lwz
25
,
-
28
(
11
)
_restgpr_26_x
:
lwz
26
,
-
24
(
11
)
_restgpr_27_x
:
lwz
27
,
-
20
(
11
)
_restgpr_28_x
:
lwz
28
,
-
16
(
11
)
_restgpr_29_x
:
lwz
29
,
-
12
(
11
)
_restgpr_30_x
:
lwz
30
,
-
8
(
11
)
_restgpr_31_x
:
lwz
0
,
4
(
11
)
FUNC_END
(
_restfpr_31_x
)
FUNC_END
(
_restfpr_30_x
)
FUNC_END
(
_restfpr_29_x
)
FUNC_END
(
_restfpr_28_x
)
FUNC_END
(
_restfpr_27_x
)
FUNC_END
(
_restfpr_26_x
)
FUNC_END
(
_restfpr_25_x
)
FUNC_END
(
_restfpr_24_x
)
FUNC_END
(
_restfpr_23_x
)
FUNC_END
(
_restfpr_22_x
)
FUNC_END
(
_restfpr_21_x
)
FUNC_END
(
_restfpr_20_x
)
FUNC_END
(
_restfpr_19_x
)
FUNC_END
(
_restfpr_18_x
)
FUNC_END
(
_restfpr_17_x
)
FUNC_END
(
_restfpr_16_x
)
FUNC_END
(
_restfpr_15_x
)
FUNC_END
(
_restfpr_14_x
)
/*
Routines
for
restoring
integer
registers
,
called
by
the
compiler
.
*/
/*
Called
with
r11
pointing
to
the
stack
header
word
of
the
caller
of
the
*/
/*
function
,
just
beyond
the
end
of
the
integer
restore
area
.
*/
FUNC_START
(
_restgpr_14_x
)
lwz
14
,
-
72
(
11
)
/*
restore
gp
registers
*/
FUNC_START
(
_restgpr_15_x
)
lwz
15
,
-
68
(
11
)
FUNC_START
(
_restgpr_16_x
)
lwz
16
,
-
64
(
11
)
FUNC_START
(
_restgpr_17_x
)
lwz
17
,
-
60
(
11
)
FUNC_START
(
_restgpr_18_x
)
lwz
18
,
-
56
(
11
)
FUNC_START
(
_restgpr_19_x
)
lwz
19
,
-
52
(
11
)
FUNC_START
(
_restgpr_20_x
)
lwz
20
,
-
48
(
11
)
FUNC_START
(
_restgpr_21_x
)
lwz
21
,
-
44
(
11
)
FUNC_START
(
_restgpr_22_x
)
lwz
22
,
-
40
(
11
)
FUNC_START
(
_restgpr_23_x
)
lwz
23
,
-
36
(
11
)
FUNC_START
(
_restgpr_24_x
)
lwz
24
,
-
32
(
11
)
FUNC_START
(
_restgpr_25_x
)
lwz
25
,
-
28
(
11
)
FUNC_START
(
_restgpr_26_x
)
lwz
26
,
-
24
(
11
)
FUNC_START
(
_restgpr_27_x
)
lwz
27
,
-
20
(
11
)
FUNC_START
(
_restgpr_28_x
)
lwz
28
,
-
16
(
11
)
FUNC_START
(
_restgpr_29_x
)
lwz
29
,
-
12
(
11
)
FUNC_START
(
_restgpr_30_x
)
lwz
30
,
-
8
(
11
)
FUNC_START
(
_restgpr_31_x
)
lwz
0
,
4
(
11
)
lwz
31
,
-
4
(
11
)
mtlr
0
mr
1
,
11
blr
FUNC_END
(
_restgpr_31_x
)
FUNC_END
(
_restgpr_30_x
)
FUNC_END
(
_restgpr_29_x
)
FUNC_END
(
_restgpr_28_x
)
FUNC_END
(
_restgpr_27_x
)
FUNC_END
(
_restgpr_26_x
)
FUNC_END
(
_restgpr_25_x
)
FUNC_END
(
_restgpr_24_x
)
FUNC_END
(
_restgpr_23_x
)
FUNC_END
(
_restgpr_22_x
)
FUNC_END
(
_restgpr_21_x
)
FUNC_END
(
_restgpr_20_x
)
FUNC_END
(
_restgpr_19_x
)
FUNC_END
(
_restgpr_18_x
)
FUNC_END
(
_restgpr_17_x
)
FUNC_END
(
_restgpr_16_x
)
FUNC_END
(
_restgpr_15_x
)
FUNC_END
(
_restgpr_14_x
)
gcc/config/rs6000/eabi.h
View file @
b6c9286a
...
...
@@ -60,7 +60,6 @@ Boston, MA 02111-1307, USA. */
/* Invoke an initializer function to set up the GOT */
#define NAME__MAIN "__eabi"
#define INVOKE__main 1
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded)");
...
...
@@ -69,57 +68,19 @@ Boston, MA 02111-1307, USA. */
#define CPP_PREDEFINES \
"-DPPC -D__embedded__ -Asystem(embedded) -Acpu(powerpc) -Amachine(powerpc)"
/*
Don't use startfiles or libraries except for libgcc.a
*/
/*
Use the simulator crt0 or mvme and libgloss/newlib libraries if desired
*/
#undef STARTFILE_SPEC
#define STARTFILE_SPEC ""
#define STARTFILE_SPEC "\
%{mmvme: mvme-crt0.o%s} \
%{msim: sim-crt0.o%s}"
#undef LIB_SPEC
#define LIB_SPEC ""
#define LIB_SPEC "\
%{mmvme: -lmvme -lc -lmvme} \
%{msim: -lsim -lc -lsim}"
#undef LIBGCC_SPEC
#define LIBGCC_SPEC "libgcc.a%s"
#undef ENDFILE_SPEC
#define ENDFILE_SPEC ""
/* This is how to output an assembler line defining an `int' constant.
For -mrelocatable, we mark all addresses that need to be fixed up
in the .fixup section. */
#undef ASM_OUTPUT_INT
#define ASM_OUTPUT_INT(FILE,VALUE) \
do { \
static int recurse = 0; \
if (TARGET_RELOCATABLE \
&& in_section != in_toc \
&& in_section != in_text \
&& in_section != in_ctors \
&& in_section != in_dtors \
&& !recurse \
&& GET_CODE (VALUE) != CONST_INT \
&& GET_CODE (VALUE) != CONST_DOUBLE \
&& CONSTANT_P (VALUE)) \
{ \
static int labelno = 0; \
char buf[256], *p; \
\
recurse = 1; \
ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", labelno++); \
STRIP_NAME_ENCODING (p, buf); \
fprintf (FILE, "%s:\n", p); \
fprintf (FILE, "\t.long ("); \
output_addr_const (FILE, (VALUE)); \
fprintf (FILE, ")@fixup\n"); \
fprintf (FILE, "\t.section\t\".fixup\",\"aw\"\n"); \
ASM_OUTPUT_ALIGN (FILE, 2); \
fprintf (FILE, "\t.long\t%s\n", p); \
fprintf (FILE, "\t.previous\n"); \
recurse = 0; \
} \
else \
{ \
fprintf (FILE, "\t.long "); \
output_addr_const (FILE, (VALUE)); \
fprintf (FILE, "\n"); \
} \
} while (0)
gcc/config/rs6000/eabiaix.h
View file @
b6c9286a
...
...
@@ -28,7 +28,9 @@ Boston, MA 02111-1307, USA. */
#define CPP_SPEC "\
%{posix: -D_POSIX_SOURCE} \
%{mrelocatable: -D_RELOCATABLE} \
%{mcall-sysv: -D_CALL_SYSV} %{mcall-aix: -D_CALL_AIX} %{!mcall-sysv: %{!mcall-aix: -D_CALL_AIX}} \
%{mcall-sysv: -D_CALL_SYSV} %{mcall-nt: -D_CALL_NT} \
%{mcall-aix: -D_CALL_AIX} %{mcall-aixdesc: -D_CALL_AIX -D_CALL_AIXDESC} \
%{!mcall-sysv: %{!mcall-aix: %{!mcall-aixdesc: %{!mcall-nt: -D_CALL_AIX}}}} \
%{msoft-float: -D_SOFT_FLOAT} %{mcpu=403: -D_SOFT_FLOAT} \
%{mlittle: -D_LITTLE_ENDIAN -Amachine(littleendian)} \
%{mlittle-endian: -D_LITTLE_ENDIAN -Amachine(littleendian)} \
...
...
@@ -49,5 +51,20 @@ Boston, MA 02111-1307, USA. */
%{mcpu=rsc1: -D_ARCH_PWR} \
%{mcpu=403: -D_ARCH_PPC} \
%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
%{mcpu=602: -D_ARCH_PPC} \
%{mcpu=603: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC}"
%{mcpu=603e: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC} \
%{mcpu=620: -D_ARCH_PPC}"
/* Define this macro as a C expression for the initializer of an
array of string to tell the driver program which options are
defaults for this target and thus do not need to be handled
specially when using `MULTILIB_OPTIONS'.
Do not define this macro if `MULTILIB_OPTIONS' is not defined in
the target makefile fragment or if none of the options listed in
`MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */
#undef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS { "mbig", "mbig-endian", "mcall-aix" }
gcc/config/rs6000/eabile.h
View file @
b6c9286a
...
...
@@ -29,7 +29,9 @@ Boston, MA 02111-1307, USA. */
#define CPP_SPEC "\
%{posix: -D_POSIX_SOURCE} \
%{mrelocatable: -D_RELOCATABLE} \
%{mcall-sysv: -D_CALL_SYSV} %{mcall-aix: -D_CALL_AIX} %{!mcall-sysv: %{!mcall-aix: -D_CALL_SYSV}} \
%{mcall-sysv: -D_CALL_SYSV} %{mcall-nt: -D_CALL_NT} \
%{mcall-aix: -D_CALL_AIX} %{mcall-aixdesc: -D_CALL_AIX -D_CALL_AIXDESC} \
%{!mcall-sysv: %{!mcall-aix: %{!mcall-aixdesc: %{!mcall-nt: -D_CALL_SYSV}}}} \
%{msoft-float: -D_SOFT_FLOAT} %{mcpu=403: -D_SOFT_FLOAT} \
%{mbig: -D_BIG_ENDIAN -Amachine(bigendian)} \
%{mbig-endian: -D_BIG_ENDIAN -Amachine(bigendian)} \
...
...
@@ -50,5 +52,20 @@ Boston, MA 02111-1307, USA. */
%{mcpu=rsc1: -D_ARCH_PWR} \
%{mcpu=403: -D_ARCH_PPC} \
%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
%{mcpu=602: -D_ARCH_PPC} \
%{mcpu=603: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC}"
%{mcpu=603e: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC} \
%{mcpu=620: -D_ARCH_PPC}"
/* Define this macro as a C expression for the initializer of an
array of string to tell the driver program which options are
defaults for this target and thus do not need to be handled
specially when using `MULTILIB_OPTIONS'.
Do not define this macro if `MULTILIB_OPTIONS' is not defined in
the target makefile fragment or if none of the options listed in
`MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */
#undef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS { "mlittle", "mlittle-endian", "mcall-sysv" }
gcc/config/rs6000/eabilesim.h
View file @
b6c9286a
...
...
@@ -22,11 +22,6 @@ Boston, MA 02111-1307, USA. */
#include "rs6000/eabile.h"
/* Right now, the simulator doesn't handle floating point, so disable it
by default. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_LITTLE_ENDIAN | MASK_SOFT_FLOAT)
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Simulated)");
...
...
@@ -34,40 +29,16 @@ Boston, MA 02111-1307, USA. */
#define CPP_PREDEFINES \
"-DPPC -D__embedded__ -D__simulator__ -Asystem(embedded) -Asystem(simulator) -Acpu(powerpc) -Amachine(powerpc)"
#undef CPP_SPEC
#define CPP_SPEC "\
%{posix: -D_POSIX_SOURCE} \
%{mrelocatable: -D_RELOCATABLE} \
%{mcall-sysv: -D_CALL_SYSV} %{mcall-aix: -D_CALL_AIX} %{!mcall-sysv: %{!mcall-aix: -D_CALL_SYSV}} \
%{!mhard-float: -D_SOFT_FLOAT} \
%{mlittle: -D_LITTLE_ENDIAN -Amachine(littleendian)} \
%{mlittle-endian: -D_LITTLE_ENDIAN -Amachine(littleendian)} \
%{!mlittle: %{!mlittle-endian: -D_LITTLE_ENDIAN -Amachine(littleendian)}} \
%{!mcpu*: \
%{mpower: %{!mpower2: -D_ARCH_PWR}} \
%{mpower2: -D_ARCH_PWR2} \
%{mpowerpc*: -D_ARCH_PPC} \
%{mno-powerpc: %{!mpower: %{!mpower2: -D_ARCH_COM}}} \
%{!mno-powerpc: -D_ARCH_PPC}} \
%{mcpu=common: -D_ARCH_COM} \
%{mcpu=power: -D_ARCH_PWR} \
%{mcpu=powerpc: -D_ARCH_PPC} \
%{mcpu=rios: -D_ARCH_PWR} \
%{mcpu=rios1: -D_ARCH_PWR} \
%{mcpu=rios2: -D_ARCH_PWR2} \
%{mcpu=rsc: -D_ARCH_PWR} \
%{mcpu=rsc1: -D_ARCH_PWR} \
%{mcpu=403: -D_ARCH_PPC} \
%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
%{mcpu=603: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC}"
/* Use the simulator crt0 and libgloss/newlib libraries */
/* Use the simulator crt0 or mvme and libgloss/newlib libraries if desired */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "sim-crt0.o%s"
#define STARTFILE_SPEC "\
%{mmvme: mvme-crt0.o%s} \
%{!mmvme: sim-crt0.o%s}"
#undef LIB_SPEC
#define LIB_SPEC "-lsim -lc -lsim"
#define LIB_SPEC "\
%{mmvme: -lmvme -lc -lmvme} \
%{!mmvme: -lsim -lc -lsim}"
#undef LIBGCC_SPEC
#define LIBGCC_SPEC "libgcc.a%s"
...
...
gcc/config/rs6000/eabisim.h
View file @
b6c9286a
...
...
@@ -22,11 +22,6 @@ Boston, MA 02111-1307, USA. */
#include "rs6000/eabi.h"
/* Right now, the simulator doesn't handle floating point, so disable it
by default. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_SOFT_FLOAT)
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Simulated)");
...
...
@@ -34,40 +29,16 @@ Boston, MA 02111-1307, USA. */
#define CPP_PREDEFINES \
"-DPPC -D__embedded__ -D__simulator__ -Asystem(embedded) -Asystem(simulator) -Acpu(powerpc) -Amachine(powerpc)"
#undef CPP_SPEC
#define CPP_SPEC "\
%{posix: -D_POSIX_SOURCE} \
%{mrelocatable: -D_RELOCATABLE} \
%{mcall-sysv: -D_CALL_SYSV} %{mcall-aix: -D_CALL_AIX} %{!mcall-sysv: %{!mcall-aix: -D_CALL_SYSV}} \
%{!mhard-float: -D_SOFT_FLOAT} \
%{mlittle: -D_LITTLE_ENDIAN -Amachine(littleendian)} \
%{mlittle-endian: -D_LITTLE_ENDIAN -Amachine(littleendian)} \
%{!mlittle: %{!mlittle-endian: -D_BIG_ENDIAN -Amachine(bigendian)}} \
%{!mcpu*: \
%{mpower: %{!mpower2: -D_ARCH_PWR}} \
%{mpower2: -D_ARCH_PWR2} \
%{mpowerpc*: -D_ARCH_PPC} \
%{mno-powerpc: %{!mpower: %{!mpower2: -D_ARCH_COM}}} \
%{!mno-powerpc: -D_ARCH_PPC}} \
%{mcpu=common: -D_ARCH_COM} \
%{mcpu=power: -D_ARCH_PWR} \
%{mcpu=powerpc: -D_ARCH_PPC} \
%{mcpu=rios: -D_ARCH_PWR} \
%{mcpu=rios1: -D_ARCH_PWR} \
%{mcpu=rios2: -D_ARCH_PWR2} \
%{mcpu=rsc: -D_ARCH_PWR} \
%{mcpu=rsc1: -D_ARCH_PWR} \
%{mcpu=403: -D_ARCH_PPC} \
%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
%{mcpu=603: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC}"
/* Use the simulator crt0 and libgloss/newlib libraries */
/* Use the simulator crt0 or mvme and libgloss/newlib libraries if desired */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "sim-crt0.o%s"
#define STARTFILE_SPEC "\
%{mmvme: mvme-crt0.o%s} \
%{!mmvme: sim-crt0.o%s}"
#undef LIB_SPEC
#define LIB_SPEC "-lsim -lc -lsim"
#define LIB_SPEC "\
%{mmvme: -lmvme -lc -lmvme} \
%{!mmvme: -lsim -lc -lsim}"
#undef LIBGCC_SPEC
#define LIBGCC_SPEC "libgcc.a%s"
...
...
gcc/config/rs6000/mach.h
View file @
b6c9286a
...
...
@@ -20,6 +20,7 @@ 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 TARGET_AIX 0
#include "rs6000/rs6000.h"
...
...
gcc/config/rs6000/netware.h
View file @
b6c9286a
...
...
@@ -19,6 +19,8 @@ You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define TARGET_AIX 0
#include "rs6000/powerpc.h"
/* Don't generate XCOFF debugging information. */
...
...
@@ -32,8 +34,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* The XCOFF support uses weird symbol suffixes, which we don't want
for ELF. */
#undef RS6000_OUTPUT_BASENAME
#define RS6000_OUTPUT_BASENAME(FILE, NAME) assemble_name (FILE, NAME)
#undef STRIP_NAME_ENCODING
/* Don't bother to output .extern pseudo-ops. They are not needed by
ELF assemblers. */
...
...
gcc/config/rs6000/powerpc.h
View file @
b6c9286a
...
...
@@ -43,6 +43,7 @@ Boston, MA 02111-1307, USA. */
%{mcpu=403: -mppc} \
%{mcpu=601: -m601} \
%{mcpu=603: -mppc} \
%{mcpu=603e: -mppc} \
%{mcpu=604: -mppc}"
#undef CPP_PREDEFINES
...
...
@@ -68,8 +69,11 @@ Boston, MA 02111-1307, USA. */
%{mcpu=rsc1: -D_ARCH_PWR} \
%{mcpu=403: -D_ARCH_PPC} \
%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
%{mcpu=602: -D_ARCH_PPC} \
%{mcpu=603: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC}"
%{mcpu=603e: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC} \
%{mcpu=620: -D_ARCH_PPC}"
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS)
...
...
gcc/config/rs6000/rs6000.c
View file @
b6c9286a
...
...
@@ -74,6 +74,12 @@ int rs6000_pic_labelno;
/* Whether a System V.4 varargs area was created. */
int
rs6000_sysv_varargs_p
;
/* Whether we need to save the TOC register. */
int
rs6000_save_toc_p
;
/* ABI enumeration available for subtarget to use. */
enum
rs6000_abi
rs6000_current_abi
;
/* Temporary memory used to convert integer -> float */
static
rtx
stack_temps
[
NUM_MACHINE_MODES
];
...
...
@@ -223,11 +229,20 @@ rs6000_override_options ()
{
"601"
,
PROCESSOR_PPC601
,
MASK_POWER
|
MASK_POWERPC
|
MASK_NEW_MNEMONICS
|
MASK_MULTIPLE
|
MASK_STRING
,
MASK_POWER2
|
POWERPC_OPT_MASKS
|
MASK_POWERPC64
},
{
"602"
,
PROCESSOR_PPC602
,
MASK_POWER
|
MASK_POWERPC
|
MASK_NEW_MNEMONICS
,
MASK_POWER2
|
POWERPC_OPT_MASKS
|
MASK_POWERPC64
},
{
"603"
,
PROCESSOR_PPC603
,
MASK_POWERPC
|
MASK_PPC_GFXOPT
|
MASK_NEW_MNEMONICS
,
POWER_MASKS
|
MASK_PPC_GPOPT
|
MASK_POWERPC64
},
{
"603e"
,
PROCESSOR_PPC603
,
MASK_POWERPC
|
MASK_PPC_GFXOPT
|
MASK_NEW_MNEMONICS
,
POWER_MASKS
|
MASK_PPC_GPOPT
|
MASK_POWERPC64
},
{
"604"
,
PROCESSOR_PPC604
,
MASK_POWERPC
|
MASK_PPC_GFXOPT
|
MASK_NEW_MNEMONICS
,
POWER_MASKS
|
MASK_PPC_GPOPT
|
MASK_POWERPC64
},
{
"620"
,
PROCESSOR_PPC620
,
MASK_POWERPC
|
MASK_PPC_GFXOPT
|
MASK_NEW_MNEMONICS
,
POWER_MASKS
|
MASK_PPC_GPOPT
|
MASK_POWERPC64
}};
int
ptt_size
=
sizeof
(
processor_target_table
)
/
sizeof
(
struct
ptt
);
...
...
@@ -350,6 +365,23 @@ any_operand (op, mode)
return
1
;
}
/* Returns 1 if op is the count register */
int
count_register_operand
(
op
,
mode
)
register
rtx
op
;
enum
machine_mode
mode
;
{
if
(
GET_CODE
(
op
)
!=
REG
)
return
0
;
if
(
REGNO
(
op
)
==
COUNT_REGISTER_REGNUM
)
return
1
;
if
(
REGNO
(
op
)
>
FIRST_PSEUDO_REGISTER
)
return
1
;
return
0
;
}
/* Return 1 if OP is a constant that can fit in a D field. */
int
...
...
@@ -476,6 +508,10 @@ easy_fp_constant (op, mode)
||
GET_MODE_CLASS
(
mode
)
!=
MODE_FLOAT
)
return
0
;
/* Consider all constants with -msoft-float to be easy */
if
(
TARGET_SOFT_FLOAT
)
return
1
;
high
=
operand_subword
(
op
,
0
,
0
,
mode
);
low
=
operand_subword
(
op
,
1
,
0
,
mode
);
...
...
@@ -486,6 +522,34 @@ easy_fp_constant (op, mode)
||
(
low
!=
0
&&
input_operand
(
low
,
word_mode
)));
}
/* Return 1 if the operand is in volatile memory. Note that during the
RTL generation phase, memory_operand does not return TRUE for
volatile memory references. So this function allows us to
recognize volatile references where its safe. */
int
volatile_mem_operand
(
op
,
mode
)
register
rtx
op
;
enum
machine_mode
mode
;
{
if
(
GET_CODE
(
op
)
!=
MEM
)
return
0
;
if
(
!
MEM_VOLATILE_P
(
op
))
return
0
;
if
(
mode
!=
GET_MODE
(
op
))
return
0
;
if
(
reload_completed
)
return
memory_operand
(
op
,
mode
);
if
(
reload_in_progress
)
return
strict_memory_address_p
(
mode
,
XEXP
(
op
,
0
));
return
memory_address_p
(
mode
,
XEXP
(
op
,
0
));
}
/* Return 1 if the operand is an offsettable memory address. */
int
...
...
@@ -506,6 +570,7 @@ fp_reg_or_mem_operand (op, mode)
enum
machine_mode
mode
;
{
return
(
memory_operand
(
op
,
mode
)
||
volatile_mem_operand
(
op
,
mode
)
||
(
register_operand
(
op
,
mode
)
&&
(
GET_CODE
(
op
)
!=
REG
||
REGNO
(
op
)
>=
FIRST_PSEUDO_REGISTER
...
...
@@ -640,7 +705,9 @@ reg_or_mem_operand (op, mode)
register
rtx
op
;
register
enum
machine_mode
mode
;
{
return
gpc_reg_operand
(
op
,
mode
)
||
memory_operand
(
op
,
mode
);
return
(
gpc_reg_operand
(
op
,
mode
)
||
memory_operand
(
op
,
mode
)
||
volatile_mem_operand
(
op
,
mode
));
}
/* Return 1 if the operand is a general register or memory operand without
...
...
@@ -732,6 +799,12 @@ input_operand (op, mode)
if
(
LEGITIMATE_CONSTANT_POOL_ADDRESS_P
(
op
))
return
1
;
/* Windows NT allows SYMBOL_REFs and LABEL_REFs against the TOC
directly in the instruction stream */
if
(
DEFAULT_ABI
==
ABI_NT
&&
(
GET_CODE
(
op
)
==
SYMBOL_REF
||
GET_CODE
(
op
)
==
LABEL_REF
))
return
1
;
/* Otherwise, we will be doing this SET with an add, so anything valid
for an add will be valid. */
return
add_operand
(
op
,
mode
);
...
...
@@ -796,6 +869,26 @@ init_cumulative_args (cum, fntype, libname, incoming)
}
}
/* If defined, a C expression that gives the alignment boundary, in bits,
of an argument with the specified mode and type. If it is not defined,
PARM_BOUNDARY is used for all arguments.
Windows NT wants anything >= 8 bytes to be double word aligned. */
int
function_arg_boundary
(
mode
,
type
)
enum
machine_mode
mode
;
tree
type
;
{
if
(
DEFAULT_ABI
!=
ABI_NT
||
TARGET_64BIT
)
return
PARM_BOUNDARY
;
if
(
mode
!=
BLKmode
)
return
(
GET_MODE_SIZE
(
mode
))
>=
8
?
64
:
32
;
return
(
int_size_in_bytes
(
type
)
>=
8
)
?
64
:
32
;
}
/* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE.
(TYPE is null for libcalls where that information may not be available.) */
...
...
@@ -807,6 +900,8 @@ function_arg_advance (cum, mode, type, named)
tree
type
;
int
named
;
{
int
align
=
((
cum
->
words
&
1
)
!=
0
&&
function_arg_boundary
(
mode
,
type
)
==
64
)
?
1
:
0
;
cum
->
words
+=
align
;
cum
->
nargs_prototype
--
;
#ifdef TARGET_V4_CALLS
...
...
@@ -846,8 +941,8 @@ function_arg_advance (cum, mode, type, named)
if
(
TARGET_DEBUG_ARG
)
fprintf
(
stderr
,
"function_adv: words = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, named = %d
\n
"
,
cum
->
words
,
cum
->
fregno
,
cum
->
nargs_prototype
,
cum
->
prototype
,
GET_MODE_NAME
(
mode
),
named
);
"function_adv: words = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, named = %d
, align = %d
\n
"
,
cum
->
words
,
cum
->
fregno
,
cum
->
nargs_prototype
,
cum
->
prototype
,
GET_MODE_NAME
(
mode
),
named
,
align
);
}
/* Determine where to put an argument to a function.
...
...
@@ -880,10 +975,13 @@ function_arg (cum, mode, type, named)
tree
type
;
int
named
;
{
int
align
=
((
cum
->
words
&
1
)
!=
0
&&
function_arg_boundary
(
mode
,
type
)
==
64
)
?
1
:
0
;
int
align_words
=
cum
->
words
+
align
;
if
(
TARGET_DEBUG_ARG
)
fprintf
(
stderr
,
"function_arg: words = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, named = %d
\n
"
,
cum
->
words
,
cum
->
fregno
,
cum
->
nargs_prototype
,
cum
->
prototype
,
GET_MODE_NAME
(
mode
),
named
);
"function_arg: words = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, named = %d
, align = %d
\n
"
,
cum
->
words
,
cum
->
fregno
,
cum
->
nargs_prototype
,
cum
->
prototype
,
GET_MODE_NAME
(
mode
),
named
,
align
);
/* Return a marker to indicate whether CR1 needs to set or clear the bit that V.4
uses to say fp args were passed in registers. Assume that we don't need the
...
...
@@ -920,8 +1018,8 @@ function_arg (cum, mode, type, named)
return
gen_rtx
(
REG
,
mode
,
cum
->
fregno
);
return
gen_rtx
(
EXPR_LIST
,
VOIDmode
,
((
cum
->
words
<
GP_ARG_NUM_REG
)
?
gen_rtx
(
REG
,
mode
,
GP_ARG_MIN_REG
+
cum
->
words
)
((
align_
words
<
GP_ARG_NUM_REG
)
?
gen_rtx
(
REG
,
mode
,
GP_ARG_MIN_REG
+
align_
words
)
:
NULL_RTX
),
gen_rtx
(
REG
,
mode
,
cum
->
fregno
));
}
...
...
@@ -929,14 +1027,14 @@ function_arg (cum, mode, type, named)
#ifdef TARGET_V4_CALLS
/* Long longs won't be split between register and stack */
else
if
(
TARGET_V4_CALLS
&&
cum
->
words
+
RS6000_ARG_SIZE
(
mode
,
type
,
named
)
>
GP_ARG_NUM_REG
)
align_
words
+
RS6000_ARG_SIZE
(
mode
,
type
,
named
)
>
GP_ARG_NUM_REG
)
{
return
NULL_RTX
;
}
#endif
else
if
(
cum
->
words
<
GP_ARG_NUM_REG
)
return
gen_rtx
(
REG
,
mode
,
GP_ARG_MIN_REG
+
cum
->
words
);
else
if
(
align_
words
<
GP_ARG_NUM_REG
)
return
gen_rtx
(
REG
,
mode
,
GP_ARG_MIN_REG
+
align_
words
);
return
NULL_RTX
;
}
...
...
@@ -1164,8 +1262,13 @@ expand_block_move_mem (mode, addr, orig_mem)
rtx
orig_mem
;
{
rtx
mem
=
gen_rtx
(
MEM
,
mode
,
addr
);
RTX_UNCHANGING_P
(
mem
)
=
RTX_UNCHANGING_P
(
orig_mem
);
MEM_VOLATILE_P
(
mem
)
=
MEM_VOLATILE_P
(
orig_mem
);
MEM_IN_STRUCT_P
(
mem
)
=
MEM_IN_STRUCT_P
(
orig_mem
);
#ifdef MEM_UNALIGNED_P
MEM_UNALIGNED_P
(
mem
)
=
MEM_UNALIGNED_P
(
orig_mem
);
#endif
return
mem
;
}
...
...
@@ -1183,6 +1286,8 @@ int
expand_block_move
(
operands
)
rtx
operands
[];
{
rtx
orig_dest
=
operands
[
0
];
rtx
orig_src
=
operands
[
1
];
rtx
bytes_rtx
=
operands
[
2
];
rtx
align_rtx
=
operands
[
3
];
int
constp
=
(
GET_CODE
(
bytes_rtx
)
==
CONST_INT
);
...
...
@@ -1224,8 +1329,8 @@ expand_block_move (operands)
return
0
;
/* Move the address into scratch registers. */
dest_reg
=
copy_addr_to_reg
(
XEXP
(
o
perands
[
0
]
,
0
));
src_reg
=
copy_addr_to_reg
(
XEXP
(
o
perands
[
1
],
0
));
dest_reg
=
copy_addr_to_reg
(
XEXP
(
o
rig_dest
,
0
));
src_reg
=
copy_addr_to_reg
(
XEXP
(
o
rig_src
,
0
));
if
(
TARGET_STRING
)
/* string instructions are available */
{
...
...
@@ -1242,8 +1347,8 @@ expand_block_move (operands)
&&
!
fixed_regs
[
12
])
{
move_bytes
=
(
bytes
>
32
)
?
32
:
bytes
;
emit_insn
(
gen_movstrsi_8reg
(
dest_reg
,
src_reg
,
emit_insn
(
gen_movstrsi_8reg
(
expand_block_move_mem
(
BLKmode
,
dest_reg
,
orig_dest
)
,
expand_block_move_mem
(
BLKmode
,
src_reg
,
orig_src
)
,
GEN_INT
((
move_bytes
==
32
)
?
0
:
move_bytes
),
align_rtx
));
}
...
...
@@ -1256,8 +1361,8 @@ expand_block_move (operands)
&&
!
fixed_regs
[
12
])
{
move_bytes
=
(
bytes
>
24
)
?
24
:
bytes
;
emit_insn
(
gen_movstrsi_6reg
(
dest_reg
,
src_reg
,
emit_insn
(
gen_movstrsi_6reg
(
expand_block_move_mem
(
BLKmode
,
dest_reg
,
orig_dest
)
,
expand_block_move_mem
(
BLKmode
,
src_reg
,
orig_src
)
,
GEN_INT
(
move_bytes
),
align_rtx
));
}
...
...
@@ -1268,16 +1373,16 @@ expand_block_move (operands)
&&
!
fixed_regs
[
12
])
{
move_bytes
=
(
bytes
>
16
)
?
16
:
bytes
;
emit_insn
(
gen_movstrsi_4reg
(
dest_reg
,
src_reg
,
emit_insn
(
gen_movstrsi_4reg
(
expand_block_move_mem
(
BLKmode
,
dest_reg
,
orig_dest
)
,
expand_block_move_mem
(
BLKmode
,
src_reg
,
orig_src
)
,
GEN_INT
(
move_bytes
),
align_rtx
));
}
else
if
(
bytes
>
4
&&
!
TARGET_64BIT
)
{
/* move up to 8 bytes at a time */
move_bytes
=
(
bytes
>
8
)
?
8
:
bytes
;
emit_insn
(
gen_movstrsi_2reg
(
dest_reg
,
src_reg
,
emit_insn
(
gen_movstrsi_2reg
(
expand_block_move_mem
(
BLKmode
,
dest_reg
,
orig_dest
)
,
expand_block_move_mem
(
BLKmode
,
src_reg
,
orig_src
)
,
GEN_INT
(
move_bytes
),
align_rtx
));
}
...
...
@@ -1285,28 +1390,28 @@ expand_block_move (operands)
{
/* move 4 bytes */
move_bytes
=
4
;
tmp_reg
=
gen_reg_rtx
(
SImode
);
emit_move_insn
(
tmp_reg
,
gen_rtx
(
MEM
,
SImode
,
src_reg
));
emit_move_insn
(
gen_rtx
(
MEM
,
SImode
,
dest_reg
),
tmp_reg
);
emit_move_insn
(
tmp_reg
,
expand_block_move_mem
(
SImode
,
src_reg
,
orig_src
));
emit_move_insn
(
expand_block_move_mem
(
SImode
,
dest_reg
,
orig_dest
),
tmp_reg
);
}
else
if
(
bytes
==
2
&&
(
align
>=
2
||
!
STRICT_ALIGNMENT
))
{
/* move 2 bytes */
move_bytes
=
2
;
tmp_reg
=
gen_reg_rtx
(
HImode
);
emit_move_insn
(
tmp_reg
,
gen_rtx
(
MEM
,
HImode
,
src_reg
));
emit_move_insn
(
gen_rtx
(
MEM
,
HImode
,
dest_reg
),
tmp_reg
);
emit_move_insn
(
tmp_reg
,
expand_block_move_mem
(
HImode
,
src_reg
,
orig_src
));
emit_move_insn
(
expand_block_move_mem
(
HImode
,
dest_reg
,
orig_dest
),
tmp_reg
);
}
else
if
(
bytes
==
1
)
/* move 1 byte */
{
move_bytes
=
1
;
tmp_reg
=
gen_reg_rtx
(
QImode
);
emit_move_insn
(
tmp_reg
,
gen_rtx
(
MEM
,
QImode
,
src_reg
));
emit_move_insn
(
gen_rtx
(
MEM
,
QImode
,
dest_reg
),
tmp_reg
);
emit_move_insn
(
tmp_reg
,
expand_block_move_mem
(
QImode
,
src_reg
,
orig_src
));
emit_move_insn
(
expand_block_move_mem
(
QImode
,
dest_reg
,
orig_dest
),
tmp_reg
);
}
else
{
/* move up to 4 bytes at a time */
move_bytes
=
(
bytes
>
4
)
?
4
:
bytes
;
emit_insn
(
gen_movstrsi_1reg
(
dest_reg
,
src_reg
,
emit_insn
(
gen_movstrsi_1reg
(
expand_block_move_mem
(
BLKmode
,
dest_reg
,
orig_dest
)
,
expand_block_move_mem
(
BLKmode
,
src_reg
,
orig_src
)
,
GEN_INT
(
move_bytes
),
align_rtx
));
}
...
...
@@ -1337,26 +1442,33 @@ expand_block_move (operands)
}
/* Generate the appropriate load and store, saving the stores for later */
if
(
bytes
>=
4
&&
(
align
>=
4
||
!
STRICT_ALIGNMENT
))
if
(
bytes
>=
8
&&
TARGET_64BIT
&&
(
align
>=
8
||
!
STRICT_ALIGNMENT
))
{
move_bytes
=
8
;
tmp_reg
=
gen_reg_rtx
(
DImode
);
emit_insn
(
gen_movdi
(
tmp_reg
,
expand_block_move_mem
(
DImode
,
src_addr
,
orig_src
)));
stores
[
num_reg
++
]
=
gen_movdi
(
expand_block_move_mem
(
DImode
,
dest_addr
,
orig_dest
),
tmp_reg
);
}
else
if
(
bytes
>=
4
&&
(
align
>=
4
||
!
STRICT_ALIGNMENT
))
{
move_bytes
=
4
;
tmp_reg
=
gen_reg_rtx
(
SImode
);
emit_insn
(
gen_movsi
(
tmp_reg
,
gen_rtx
(
MEM
,
SImode
,
src_addr
)));
stores
[
num_reg
++
]
=
gen_movsi
(
gen_rtx
(
MEM
,
SImode
,
dest_addr
),
tmp_reg
);
emit_insn
(
gen_movsi
(
tmp_reg
,
expand_block_move_mem
(
SImode
,
src_addr
,
orig_src
)));
stores
[
num_reg
++
]
=
gen_movsi
(
expand_block_move_mem
(
SImode
,
dest_addr
,
orig_dest
),
tmp_reg
);
}
else
if
(
bytes
>=
2
&&
(
align
>=
2
||
!
STRICT_ALIGNMENT
))
{
move_bytes
=
2
;
tmp_reg
=
gen_reg_rtx
(
HImode
);
emit_insn
(
gen_mov
hi
(
tmp_reg
,
gen_rtx
(
MEM
,
HImode
,
src_addr
)));
stores
[
num_reg
++
]
=
gen_movhi
(
gen_rtx
(
MEM
,
HImode
,
dest_addr
),
tmp_reg
);
emit_insn
(
gen_mov
si
(
tmp_reg
,
expand_block_move_mem
(
HImode
,
src_addr
,
orig_src
)));
stores
[
num_reg
++
]
=
gen_movhi
(
expand_block_move_mem
(
HImode
,
dest_addr
,
orig_dest
),
tmp_reg
);
}
else
{
move_bytes
=
1
;
tmp_reg
=
gen_reg_rtx
(
QImode
);
emit_insn
(
gen_mov
qi
(
tmp_reg
,
gen_rtx
(
MEM
,
QImode
,
src_addr
)));
stores
[
num_reg
++
]
=
gen_movqi
(
gen_rtx
(
MEM
,
QImode
,
dest_addr
),
tmp_reg
);
emit_insn
(
gen_mov
si
(
tmp_reg
,
expand_block_move_mem
(
QImode
,
src_addr
,
orig_src
)));
stores
[
num_reg
++
]
=
gen_movqi
(
expand_block_move_mem
(
QImode
,
dest_addr
,
orig_dest
),
tmp_reg
);
}
if
(
num_reg
>=
MAX_MOVE_REG
)
...
...
@@ -1367,12 +1479,9 @@ expand_block_move (operands)
}
}
if
(
num_reg
>
0
)
{
for
(
i
=
0
;
i
<
num_reg
;
i
++
)
emit_insn
(
stores
[
i
]);
}
}
return
1
;
}
...
...
@@ -2127,9 +2236,26 @@ print_operand (file, x, code)
if
(
GET_CODE
(
x
)
!=
SYMBOL_REF
)
abort
();
#ifndef USING_SVR4_H
if
(
XSTR
(
x
,
0
)[
0
]
!=
'.'
)
{
switch
(
DEFAULT_ABI
)
{
default
:
abort
();
case
ABI_AIX
:
putc
(
'.'
,
file
);
#endif
break
;
case
ABI_V4
:
case
ABI_AIX_NODESC
:
break
;
case
ABI_NT
:
fputs
(
".."
,
file
);
break
;
}
}
RS6000_OUTPUT_BASENAME
(
file
,
XSTR
(
x
,
0
));
return
;
...
...
@@ -2235,11 +2361,9 @@ first_reg_to_save ()
to 23 to do this. Don't use the frame pointer in reg 31.
For now, save enough room for all of the parameter registers. */
#ifndef USING_SVR4_H
if
(
profile_flag
)
if
(
DEFAULT_ABI
==
ABI_AIX
&&
profile_flag
)
if
(
first_reg
>
23
)
first_reg
=
23
;
#endif
return
first_reg
;
}
...
...
@@ -2333,7 +2457,49 @@ rs6000_makes_calls ()
+---------------------------------------+
old SP->| back chain to caller's caller |
+---------------------------------------+
*/
A PowerPC Windows/NT frame looks like:
SP----> +---------------------------------------+
| back chain to caller | 0
+---------------------------------------+
| reserved | 4
+---------------------------------------+
| reserved | 8
+---------------------------------------+
| reserved | 12
+---------------------------------------+
| reserved | 16
+---------------------------------------+
| reserved | 20
+---------------------------------------+
| Parameter save area (P) | 24
+---------------------------------------+
| Alloca space (A) | 24+P
+---------------------------------------+
| Local variable space (L) | 24+P+A
+---------------------------------------+
| Save area for FP registers (F) | 24+P+A+L
+---------------------------------------+
| Possible alignment area (X) | 24+P+A+L+F
+---------------------------------------+
| Save area for GP registers (G) | 24+P+A+L+F+X
+---------------------------------------+
| Save area for CR (C) | 24+P+A+L+F+X+G
+---------------------------------------+
| Save area for TOC (T) | 24+P+A+L+F+X+G+C
+---------------------------------------+
| Save area for LR (R) | 24+P+A+L+F+X+G+C+T
+---------------------------------------+
old SP->| back chain to caller's caller |
+---------------------------------------+
For NT, there is no specific order to save the registers, but in
order to support __builtin_return_address, the save area for the
link register needs to be in a known place, so we use -4 off of the
old SP. To support calls through pointers, we also allocate a
fixed slot to store the TOC, -8 off the old SP. */
rs6000_stack_t
*
rs6000_stack_info
()
...
...
@@ -2342,19 +2508,13 @@ rs6000_stack_info ()
rs6000_stack_t
*
info_ptr
=
&
info
;
int
reg_size
=
TARGET_64BIT
?
8
:
4
;
enum
rs6000_abi
abi
;
int
total_raw_size
;
/* Zero all fields portably */
info
=
zero_info
;
/* Select which calling sequence */
#ifdef TARGET_V4_CALLS
if
(
TARGET_V4_CALLS
)
abi
=
ABI_V4
;
else
#endif
abi
=
ABI_AIX
;
info_ptr
->
abi
=
abi
;
info_ptr
->
abi
=
abi
=
DEFAULT_ABI
;
/* Calculate which registers need to be saved & save area size */
info_ptr
->
first_gp_reg_save
=
first_reg_to_save
();
...
...
@@ -2366,6 +2526,39 @@ rs6000_stack_info ()
/* Does this function call anything? */
info_ptr
->
calls_p
=
rs6000_makes_calls
();
/* Do we need to allocate space to save the toc? */
if
(
rs6000_save_toc_p
)
{
info_ptr
->
toc_save_p
=
1
;
info_ptr
->
toc_size
=
reg_size
;
}
/* If this is main and we need to call a function to set things up,
save main's arguments around the call. */
if
(
strcmp
(
IDENTIFIER_POINTER
(
DECL_NAME
(
current_function_decl
)),
"main"
)
==
0
)
{
info_ptr
->
main_p
=
1
;
#ifdef NAME__MAIN
if
(
DECL_ARGUMENTS
(
current_function_decl
))
{
int
i
;
tree
arg
;
info_ptr
->
main_save_p
=
1
;
info_ptr
->
main_size
=
0
;
info_ptr
->
calls_p
=
1
;
for
((
i
=
0
),
(
arg
=
DECL_ARGUMENTS
(
current_function_decl
));
arg
!=
NULL_TREE
&&
i
<
8
;
(
arg
=
TREE_CHAIN
(
arg
)),
i
++
)
{
info_ptr
->
main_size
+=
reg_size
;
}
}
#endif
}
/* Determine if we need to save the link register */
if
(
regs_ever_live
[
65
]
||
profile_flag
#ifdef TARGET_RELOCATABLE
...
...
@@ -2378,13 +2571,15 @@ rs6000_stack_info ()
{
info_ptr
->
lr_save_p
=
1
;
regs_ever_live
[
65
]
=
1
;
if
(
abi
==
ABI_NT
)
info_ptr
->
lr_size
=
reg_size
;
}
/* Determine if we need to save the condition code registers */
if
(
regs_ever_live
[
70
]
||
regs_ever_live
[
71
]
||
regs_ever_live
[
72
])
{
info_ptr
->
cr_save_p
=
1
;
if
(
abi
==
ABI_V4
)
if
(
abi
==
ABI_V4
||
abi
==
ABI_NT
)
info_ptr
->
cr_size
=
reg_size
;
}
...
...
@@ -2394,12 +2589,20 @@ rs6000_stack_info ()
info_ptr
->
varargs_size
=
RS6000_VARARGS_AREA
;
info_ptr
->
vars_size
=
ALIGN
(
get_frame_size
(),
8
);
info_ptr
->
parm_size
=
ALIGN
(
current_function_outgoing_args_size
,
8
);
info_ptr
->
save_size
=
ALIGN
(
info_ptr
->
fp_size
+
info_ptr
->
gp_size
+
info_ptr
->
cr_size
,
8
);
info_ptr
->
total_size
=
ALIGN
(
info_ptr
->
vars_size
info_ptr
->
save_size
=
ALIGN
(
info_ptr
->
fp_size
+
info_ptr
->
gp_size
+
info_ptr
->
cr_size
+
info_ptr
->
lr_size
+
info_ptr
->
toc_size
+
info_ptr
->
main_size
,
8
);
total_raw_size
=
(
info_ptr
->
vars_size
+
info_ptr
->
parm_size
+
info_ptr
->
save_size
+
info_ptr
->
varargs_size
+
info_ptr
->
fixed_size
,
STACK_BOUNDARY
/
BITS_PER_UNIT
);
+
info_ptr
->
fixed_size
);
info_ptr
->
total_size
=
ALIGN
(
total_raw_size
,
STACK_BOUNDARY
/
BITS_PER_UNIT
);
/* Determine if we need to allocate any stack frame.
For AIX We need to push the stack if a frame pointer is needed (because
...
...
@@ -2412,8 +2615,8 @@ rs6000_stack_info ()
if
(
info_ptr
->
calls_p
)
info_ptr
->
push_p
=
1
;
else
if
(
abi
==
ABI_V4
)
info_ptr
->
push_p
=
(
info_ptr
->
total
_size
>
info_ptr
->
fixed_size
else
if
(
abi
==
ABI_V4
||
abi
==
ABI_NT
)
info_ptr
->
push_p
=
(
total_raw
_size
>
info_ptr
->
fixed_size
||
info_ptr
->
lr_save_p
);
else
...
...
@@ -2422,19 +2625,41 @@ rs6000_stack_info ()
||
info_ptr
->
total_size
>
220
);
/* Calculate the offsets */
info_ptr
->
fp_save_offset
=
-
info_ptr
->
fp_size
;
info_ptr
->
gp_save_offset
=
info_ptr
->
fp_save_offset
-
info_ptr
->
gp_size
;
switch
(
abi
)
{
case
ABI_NONE
:
default
:
abort
();
case
ABI_AIX
:
case
ABI_AIX_NODESC
:
info_ptr
->
fp_save_offset
=
-
info_ptr
->
fp_size
;
info_ptr
->
gp_save_offset
=
info_ptr
->
fp_save_offset
-
info_ptr
->
gp_size
;
info_ptr
->
main_save_offset
=
info_ptr
->
gp_save_offset
-
info_ptr
->
main_size
;
info_ptr
->
cr_save_offset
=
4
;
info_ptr
->
lr_save_offset
=
8
;
break
;
case
ABI_V4
:
info_ptr
->
fp_save_offset
=
-
info_ptr
->
fp_size
;
info_ptr
->
gp_save_offset
=
info_ptr
->
fp_save_offset
-
info_ptr
->
gp_size
;
info_ptr
->
cr_save_offset
=
info_ptr
->
gp_save_offset
-
reg_size
;
info_ptr
->
toc_save_offset
=
info_ptr
->
cr_save_offset
-
info_ptr
->
cr_size
;
info_ptr
->
main_save_offset
=
info_ptr
->
toc_save_offset
-
info_ptr
->
toc_size
;
info_ptr
->
lr_save_offset
=
reg_size
;
break
;
case
ABI_NT
:
info_ptr
->
lr_save_offset
=
-
4
;
info_ptr
->
toc_save_offset
=
info_ptr
->
lr_save_offset
-
info_ptr
->
lr_size
;
info_ptr
->
cr_save_offset
=
info_ptr
->
toc_save_offset
-
info_ptr
->
toc_size
;
info_ptr
->
gp_save_offset
=
info_ptr
->
cr_save_offset
-
info_ptr
->
cr_size
-
info_ptr
->
gp_size
+
reg_size
;
info_ptr
->
fp_save_offset
=
info_ptr
->
gp_save_offset
-
info_ptr
->
fp_size
;
if
(
info_ptr
->
fp_size
&&
((
-
info_ptr
->
fp_save_offset
)
%
8
)
!=
0
)
info_ptr
->
fp_save_offset
-=
4
;
info_ptr
->
main_save_offset
=
info_ptr
->
fp_save_offset
-
info_ptr
->
main_size
;
break
;
}
/* Zero offsets if we're not saving those registers */
...
...
@@ -2450,6 +2675,12 @@ rs6000_stack_info ()
if
(
!
info_ptr
->
cr_save_p
)
info_ptr
->
cr_save_offset
=
0
;
if
(
!
info_ptr
->
toc_save_p
)
info_ptr
->
toc_save_offset
=
0
;
if
(
!
info_ptr
->
main_save_p
)
info_ptr
->
main_save_offset
=
0
;
return
info_ptr
;
}
...
...
@@ -2472,7 +2703,9 @@ debug_stack_info (info)
default
:
abi_string
=
"Unknown"
;
break
;
case
ABI_NONE
:
abi_string
=
"NONE"
;
break
;
case
ABI_AIX
:
abi_string
=
"AIX"
;
break
;
case
ABI_AIX_NODESC
:
abi_string
=
"AIX"
;
break
;
case
ABI_V4
:
abi_string
=
"V.4"
;
break
;
case
ABI_NT
:
abi_string
=
"NT"
;
break
;
}
fprintf
(
stderr
,
"
\t
ABI = %5s
\n
"
,
abi_string
);
...
...
@@ -2489,12 +2722,21 @@ debug_stack_info (info)
if
(
info
->
cr_save_p
)
fprintf
(
stderr
,
"
\t
cr_save_p = %5d
\n
"
,
info
->
cr_save_p
);
if
(
info
->
toc_save_p
)
fprintf
(
stderr
,
"
\t
toc_save_p = %5d
\n
"
,
info
->
toc_save_p
);
if
(
info
->
push_p
)
fprintf
(
stderr
,
"
\t
push_p = %5d
\n
"
,
info
->
push_p
);
if
(
info
->
calls_p
)
fprintf
(
stderr
,
"
\t
calls_p = %5d
\n
"
,
info
->
calls_p
);
if
(
info
->
main_p
)
fprintf
(
stderr
,
"
\t
main_p = %5d
\n
"
,
info
->
main_p
);
if
(
info
->
main_save_p
)
fprintf
(
stderr
,
"
\t
main_save_p = %5d
\n
"
,
info
->
main_save_p
);
if
(
info
->
gp_save_offset
)
fprintf
(
stderr
,
"
\t
gp_save_offset = %5d
\n
"
,
info
->
gp_save_offset
);
...
...
@@ -2507,9 +2749,15 @@ debug_stack_info (info)
if
(
info
->
cr_save_offset
)
fprintf
(
stderr
,
"
\t
cr_save_offset = %5d
\n
"
,
info
->
cr_save_offset
);
if
(
info
->
toc_save_offset
)
fprintf
(
stderr
,
"
\t
toc_save_offset = %5d
\n
"
,
info
->
toc_save_offset
);
if
(
info
->
varargs_save_offset
)
fprintf
(
stderr
,
"
\t
varargs_save_offset = %5d
\n
"
,
info
->
varargs_save_offset
);
if
(
info
->
main_save_offset
)
fprintf
(
stderr
,
"
\t
main_save_offset = %5d
\n
"
,
info
->
main_save_offset
);
if
(
info
->
total_size
)
fprintf
(
stderr
,
"
\t
total_size = %5d
\n
"
,
info
->
total_size
);
...
...
@@ -2531,9 +2779,18 @@ debug_stack_info (info)
if
(
info
->
fp_size
)
fprintf
(
stderr
,
"
\t
fp_size = %5d
\n
"
,
info
->
fp_size
);
if
(
info
->
lr_size
)
fprintf
(
stderr
,
"
\t
lr_size = %5d
\n
"
,
info
->
cr_size
);
if
(
info
->
cr_size
)
fprintf
(
stderr
,
"
\t
cr_size = %5d
\n
"
,
info
->
cr_size
);
if
(
info
->
toc_size
)
fprintf
(
stderr
,
"
\t
toc_size = %5d
\n
"
,
info
->
toc_size
);
if
(
info
->
main_size
)
fprintf
(
stderr
,
"
\t
main_size = %5d
\n
"
,
info
->
main_size
);
if
(
info
->
save_size
)
fprintf
(
stderr
,
"
\t
save_size = %5d
\n
"
,
info
->
save_size
);
...
...
@@ -2544,65 +2801,6 @@ debug_stack_info (info)
}
#ifdef USING_SVR4_H
/* Write out a System V.4 style traceback table before the prologue
At present, only emit the basic tag table (ie, do not emit tag_types other
than 0, which might use more than 1 tag word).
The first tag word looks like:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0 |ver| tag |e|s| alloca | # fprs | # gprs |s|l|c|f|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
void
svr4_traceback
(
file
,
name
,
decl
)
FILE
*
file
;
tree
name
,
decl
;
{
rs6000_stack_t
*
info
=
rs6000_stack_info
();
long
tag
;
long
version
=
0
;
/* version number */
long
tag_type
=
0
;
/* function type */
long
extended_tag
=
0
;
/* additional tag words needed */
long
spare
=
0
;
/* reserved for future use */
long
fpscr_max
=
0
;
/* 1 if the function has a FPSCR save word */
long
fpr_max
=
64
-
info
->
first_fp_reg_save
;
/* # of floating point registers saved */
long
gpr_max
=
32
-
info
->
first_gp_reg_save
;
/* # of general purpose registers saved */
long
alloca_reg
;
/* stack/frame register */
if
(
frame_pointer_needed
)
alloca_reg
=
31
;
else
if
(
info
->
push_p
!=
0
)
alloca_reg
=
1
;
else
alloca_reg
=
0
;
tag
=
((
version
<<
24
)
|
(
tag_type
<<
21
)
|
(
extended_tag
<<
20
)
|
(
spare
<<
19
)
|
(
alloca_reg
<<
14
)
|
(
fpr_max
<<
9
)
|
(
gpr_max
<<
4
)
|
(
info
->
push_p
<<
3
)
|
(
info
->
lr_save_p
<<
2
)
|
(
info
->
cr_save_p
<<
1
)
|
(
fpscr_max
<<
0
));
fprintf
(
file
,
"
\t
.long 0x%lx
\n
"
,
tag
);
}
#endif
/* USING_SVR4_H */
/* Write function prologue. */
void
output_prolog
(
file
,
size
)
...
...
@@ -2610,19 +2808,30 @@ output_prolog (file, size)
int
size
;
{
rs6000_stack_t
*
info
=
rs6000_stack_info
();
char
*
store_reg
=
(
TARGET_64BIT
)
?
"
\t
std %s,%d(%s)"
:
"
\t
{st|stw} %s,%d(%s)
\n
"
;
int
reg_size
=
info
->
reg_size
;
char
*
store_reg
;
char
*
load_reg
;
if
(
TARGET_64BIT
)
{
store_reg
=
"
\t
std %s,%d(%s)"
;
load_reg
=
"
\t
lld %s,%d(%s)"
;
}
else
{
store_reg
=
"
\t
{st|stw} %s,%d(%s)
\n
"
;
load_reg
=
"
\t
{l|lwz} %s,%d(%s)
\n
"
;
}
if
(
TARGET_DEBUG_STACK
)
debug_stack_info
(
info
);
/* Write .extern for any function we will call to save and restore fp
values. */
#ifndef USING_SVR4_H
if
(
info
->
first_fp_reg_save
<
62
)
if
(
info
->
first_fp_reg_save
<
64
&&
!
FP_SAVE_INLINE
(
info
->
first_fp_reg_save
))
fprintf
(
file
,
"
\t
.extern %s%d%s
\n\t
.extern %s%d%s
\n
"
,
SAVE_FP_PREFIX
,
info
->
first_fp_reg_save
-
32
,
SAVE_FP_SUFFIX
,
RESTORE_FP_PREFIX
,
info
->
first_fp_reg_save
-
32
,
RESTORE_FP_SUFFIX
);
#endif
/* Write .extern for truncation routines, if needed. */
if
(
rs6000_trunc_used
&&
!
trunc_defined
)
...
...
@@ -2672,7 +2881,6 @@ output_prolog (file, size)
{
int
regno
=
info
->
first_gp_reg_save
;
int
loc
=
info
->
gp_save_offset
;
int
reg_size
=
(
TARGET_64BIT
)
?
8
:
4
;
for
(
;
regno
<
32
;
regno
++
,
loc
+=
reg_size
)
asm_fprintf
(
file
,
store_reg
,
reg_names
[
regno
],
loc
,
reg_names
[
1
]);
...
...
@@ -2684,6 +2892,19 @@ output_prolog (file, size)
info
->
gp_save_offset
,
reg_names
[
1
]);
/* Save main's arguments if we need to call a function */
#ifdef NAME__MAIN
if
(
info
->
main_save_p
)
{
int
regno
;
int
loc
=
info
->
main_save_offset
;
int
size
=
info
->
main_size
;
for
(
regno
=
3
;
size
>
0
;
regno
++
,
loc
-=
reg_size
,
size
-=
reg_size
)
asm_fprintf
(
file
,
store_reg
,
reg_names
[
regno
],
loc
,
reg_names
[
1
]);
}
#endif
/* Save lr if we used it. */
if
(
info
->
lr_save_p
)
asm_fprintf
(
file
,
store_reg
,
reg_names
[
0
],
info
->
lr_save_offset
,
reg_names
[
1
]);
...
...
@@ -2692,6 +2913,9 @@ output_prolog (file, size)
if
(
info
->
cr_save_p
)
asm_fprintf
(
file
,
store_reg
,
reg_names
[
12
],
info
->
cr_save_offset
,
reg_names
[
1
]);
if
(
info
->
toc_save_p
)
asm_fprintf
(
file
,
store_reg
,
reg_names
[
2
],
info
->
toc_save_offset
,
reg_names
[
1
]);
/* Update stack and set back pointer. */
if
(
info
->
push_p
)
{
...
...
@@ -2715,13 +2939,62 @@ output_prolog (file, size)
if
(
frame_pointer_needed
)
asm_fprintf
(
file
,
"
\t
mr %s,%s
\n
"
,
reg_names
[
31
],
reg_names
[
1
]);
#ifdef NAME__MAIN
/* If we need to call a function to set things up for main, do so now
before dealing with the TOC. */
if
(
info
->
main_p
)
{
char
*
prefix
=
""
;
switch
(
DEFAULT_ABI
)
{
case
ABI_AIX
:
prefix
=
"."
;
break
;
case
ABI_NT
:
prefix
=
".."
;
break
;
}
fprintf
(
file
,
"
\t
bl %s%s
\n
"
,
prefix
,
NAME__MAIN
);
#ifdef RS6000_CALL_GLUE2
fprintf
(
file
,
"
\t
%s%s%s
\n
"
,
RS6000_CALL_GLUE2
,
prefix
,
NAME_MAIN
);
#else
#ifdef RS6000_CALL_GLUE
if
(
DEFAULT_ABI
==
ABI_AIX
||
DEFAULT_ABI
==
ABI_NT
)
fprintf
(
file
,
"
\t
%s
\n
"
,
RS6000_CALL_GLUE
);
#endif
#endif
if
(
info
->
main_save_p
)
{
int
regno
;
int
loc
;
int
size
=
info
->
main_size
;
if
(
info
->
total_size
<
32767
)
{
loc
=
info
->
total_size
+
info
->
main_save_offset
;
for
(
regno
=
3
;
size
>
0
;
regno
++
,
size
-=
reg_size
,
loc
-=
reg_size
)
asm_fprintf
(
file
,
load_reg
,
reg_names
[
regno
],
loc
,
reg_names
[
1
]);
}
else
{
/* for large frames, reg 0 above contains -frame size */
loc
=
info
->
main_save_offset
;
asm_fprintf
(
file
,
"
\t
{sf|subf} %s,%s,%s
\n
"
,
reg_names
[
0
],
reg_names
[
0
],
reg_names
[
1
]);
for
(
regno
=
3
;
size
>
0
;
regno
++
,
size
-=
reg_size
,
loc
-=
reg_size
)
asm_fprintf
(
file
,
load_reg
,
reg_names
[
regno
],
loc
,
reg_names
[
0
]);
}
}
}
#endif
/* If TARGET_MINIMAL_TOC, and the constant pool is needed, then load the
TOC_TABLE address into register 30. */
if
(
TARGET_TOC
&&
TARGET_MINIMAL_TOC
&&
get_pool_size
()
!=
0
)
{
char
buf
[
256
];
#ifdef
USING_SVR4_H
#ifdef
TARGET_RELOCATABLE
if
(
TARGET_RELOCATABLE
)
{
ASM_GENERATE_INTERNAL_LABEL
(
buf
,
"LCF"
,
rs6000_pic_labelno
);
...
...
@@ -2732,13 +3005,7 @@ output_prolog (file, size)
ASM_OUTPUT_INTERNAL_LABEL
(
file
,
"LCF"
,
rs6000_pic_labelno
);
fprintf
(
file
,
"
\t
mflr %s
\n
"
,
reg_names
[
30
]);
if
(
TARGET_POWERPC64
)
fprintf
(
file
,
"
\t
ld"
);
else
if
(
TARGET_NEW_MNEMONICS
)
fprintf
(
file
,
"
\t
lwz"
);
else
fprintf
(
file
,
"
\t
l"
);
asm_fprintf
(
file
,
TARGET_64BIT
?
"
\t
ld"
:
"
\t
{l|lwz}"
);
fprintf
(
file
,
" %s,("
,
reg_names
[
0
]);
ASM_GENERATE_INTERNAL_LABEL
(
buf
,
"LCL"
,
rs6000_pic_labelno
);
assemble_name
(
file
,
buf
);
...
...
@@ -2750,7 +3017,14 @@ output_prolog (file, size)
reg_names
[
30
],
reg_names
[
0
],
reg_names
[
30
]);
rs6000_pic_labelno
++
;
}
else
if
(
!
TARGET_64BIT
)
else
#endif
switch
(
DEFAULT_ABI
)
{
case
ABI_V4
:
case
ABI_AIX_NODESC
:
if
(
!
TARGET_64BIT
)
{
ASM_GENERATE_INTERNAL_LABEL
(
buf
,
"LCTOC"
,
1
);
asm_fprintf
(
file
,
"
\t
{cau|addis} %s,%s,"
,
reg_names
[
30
],
reg_names
[
0
]);
...
...
@@ -2772,12 +3046,22 @@ output_prolog (file, size)
else
abort
();
#else
/* !USING_SVR4_H */
break
;
case
ABI_NT
:
case
ABI_AIX
:
ASM_GENERATE_INTERNAL_LABEL
(
buf
,
"LCTOC"
,
0
);
asm_fprintf
(
file
,
"
\t
{l|lwz} %s,"
,
reg_names
[
30
]);
assemble_name
(
file
,
buf
);
asm_fprintf
(
file
,
"(%s)
\n
"
,
reg_names
[
2
]);
#endif
/* USING_SVR4_H */
break
;
}
}
if
(
DEFAULT_ABI
==
ABI_NT
)
{
assemble_name
(
file
,
XSTR
(
XEXP
(
DECL_RTL
(
current_function_decl
),
0
),
0
));
fputs
(
".b:
\n
"
,
file
);
}
}
...
...
@@ -2886,14 +3170,16 @@ output_epilog (file, size)
traceback table itself.
System V.4 Powerpc's (and the embedded ABI derived from it) use a
different traceback table located before the prologue. */
#ifndef USING_SVR4_H
if
(
!
flag_inhibit_size_directive
)
different traceback table. */
if
(
DEFAULT_ABI
==
ABI_AIX
&&
!
flag_inhibit_size_directive
)
{
char
*
fname
=
XSTR
(
XEXP
(
DECL_RTL
(
current_function_decl
),
0
),
0
);
int
fixed_parms
,
float_parms
,
parm_info
;
int
i
;
while
(
*
fname
==
'.'
)
/* V.4 encodes . in the name */
fname
++
;
/* Need label immediately before tbtab, so we can compute its offset
from the function start. */
if
(
*
fname
==
'*'
)
...
...
@@ -3065,10 +3351,18 @@ output_epilog (file, size)
if
(
frame_pointer_needed
)
fprintf
(
file
,
"
\t
.byte 31
\n
"
);
}
#endif
/* !USING_SVR4_H */
/* Reset varargs indicator */
/* Reset varargs
and save TOC
indicator */
rs6000_sysv_varargs_p
=
0
;
rs6000_save_toc_p
=
0
;
if
(
DEFAULT_ABI
==
ABI_NT
)
{
RS6000_OUTPUT_BASENAME
(
file
,
XSTR
(
XEXP
(
DECL_RTL
(
current_function_decl
),
0
),
0
));
fputs
(
".e:
\n
FE_MOT_RESVD.."
,
file
);
RS6000_OUTPUT_BASENAME
(
file
,
XSTR
(
XEXP
(
DECL_RTL
(
current_function_decl
),
0
),
0
));
fputs
(
":
\n
"
,
file
);
}
}
/* Output a TOC entry. We derive the entry name from what is
...
...
@@ -3082,6 +3376,7 @@ output_toc (file, x, labelno)
{
char
buf
[
256
];
char
*
name
=
buf
;
char
*
real_name
;
rtx
base
=
x
;
int
offset
=
0
;
...
...
@@ -3098,8 +3393,7 @@ output_toc (file, x, labelno)
}
#ifdef USING_SVR4_H
if
(
TARGET_MINIMAL_TOC
)
if
(
TARGET_ELF
&&
TARGET_MINIMAL_TOC
)
{
ASM_OUTPUT_INTERNAL_LABEL_PREFIX
(
file
,
"LC"
);
fprintf
(
file
,
"%d = .-"
,
labelno
);
...
...
@@ -3107,7 +3401,6 @@ output_toc (file, x, labelno)
fprintf
(
file
,
"1
\n
"
);
}
else
#endif
/* USING_SVR4_H */
ASM_OUTPUT_INTERNAL_LABEL
(
file
,
"LC"
,
labelno
);
/* Handle FP constants specially. Note that if we have a minimal
...
...
@@ -3163,8 +3456,8 @@ output_toc (file, x, labelno)
fprintf
(
file
,
"
\t
.long "
);
else
{
fprintf
(
file
,
"
\t
.tc "
);
RS6000_OUTPUT_BASENAME
(
file
,
name
);
STRIP_NAME_ENCODING
(
real_name
,
name
);
fprintf
(
file
,
"
\t
.tc %s"
,
real_
name
);
if
(
offset
<
0
)
fprintf
(
file
,
".N%d"
,
-
offset
);
...
...
@@ -3309,14 +3602,14 @@ output_function_profiler (file, labelno)
FILE
*
file
;
int
labelno
;
{
#ifdef USING_SVR4_H
abort
();
#else
/* The last used parameter register. */
int
last_parm_reg
;
int
i
,
j
;
char
buf
[
100
];
if
(
DEFAULT_ABI
!=
ABI_AIX
)
abort
();
/* Set up a TOC entry for the profiler label. */
toc_section
();
ASM_OUTPUT_INTERNAL_LABEL
(
file
,
"LPC"
,
labelno
);
...
...
@@ -3363,7 +3656,6 @@ output_function_profiler (file, labelno)
for
(
i
=
3
,
j
=
30
;
i
<=
last_parm_reg
;
i
++
,
j
--
)
fprintf
(
file
,
"
\t
ai %d,%d,0
\n
"
,
i
,
j
);
#endif
}
/* Adjust the cost of a scheduling dependency. Return the new cost of
...
...
@@ -3399,3 +3691,275 @@ rs6000_adjust_cost (insn, link, dep_insn, cost)
return
cost
;
}
/* Return how many instructions the machine can issue per cycle */
int
get_issue_rate
()
{
switch
(
rs6000_cpu_attr
)
{
case
CPU_RIOS1
:
return
3
;
/* ? */
case
CPU_RIOS2
:
return
4
;
case
CPU_PPC601
:
return
3
;
/* ? */
case
CPU_PPC602
:
return
1
;
case
CPU_PPC603
:
return
2
;
case
CPU_PPC604
:
return
4
;
case
CPU_PPC620
:
return
4
;
default
:
return
1
;
}
}
/* Output insns to flush the {data|instruction} caches after building a
trampoline. */
static
void
rs6000_sync_trampoline
(
addr
)
rtx
addr
;
{
enum
machine_mode
pmode
=
Pmode
;
rtx
reg
=
gen_reg_rtx
(
pmode
);
rtx
mem2
;
rtx
mem1
;
int
size
=
rs6000_trampoline_size
();
rtx
(
*
sub_fcn
)
PROTO
((
rtx
,
rtx
,
rtx
));
rtx
(
*
cmp_fcn
)
PROTO
((
rtx
,
rtx
));
rtx
label
;
if
(
TARGET_64BIT
)
{
abort
();
/* no cmpdi function yet */
}
else
{
sub_fcn
=
gen_subsi3
;
cmp_fcn
=
gen_cmpsi
;
}
addr
=
force_reg
(
pmode
,
addr
);
mem2
=
gen_rtx
(
MEM
,
pmode
,
gen_rtx
(
PLUS
,
pmode
,
addr
,
reg
));
mem1
=
gen_rtx
(
MEM
,
pmode
,
addr
);
/* Issue a loop of dcbst's to flush the data cache */
emit_move_insn
(
reg
,
GEN_INT
(
size
-
4
));
label
=
gen_label_rtx
();
emit_label
(
label
);
emit_insn
(
gen_dcbst
(
mem2
,
addr
,
reg
));
emit_insn
((
*
sub_fcn
)
(
reg
,
reg
,
GEN_INT
(
4
)));
emit_insn
((
*
cmp_fcn
)
(
reg
,
const0_rtx
));
emit_jump_insn
(
gen_bgt
(
label
));
/* Issue a sync after the dcbst's to let things settle down */
emit_insn
(
gen_sync
(
mem1
));
/* Issue a loop of icbi's to flush the instruction cache */
emit_move_insn
(
reg
,
GEN_INT
(
size
-
4
));
label
=
gen_label_rtx
();
emit_label
(
label
);
emit_insn
(
gen_icbi
(
mem2
,
addr
,
reg
));
emit_insn
((
*
sub_fcn
)
(
reg
,
reg
,
GEN_INT
(
4
)));
emit_insn
((
*
cmp_fcn
)
(
reg
,
const0_rtx
));
emit_jump_insn
(
gen_bgt
(
label
));
/* Issue a sync after the icbi's to let things settle down */
emit_insn
(
gen_sync
(
mem1
));
/* Finally issue an isync to synchronize the icache */
emit_insn
(
gen_isync
(
mem1
));
}
/* Output assembler code for a block containing the constant parts
of a trampoline, leaving space for the variable parts.
The trampoline should set the static chain pointer to value placed
into the trampoline and should branch to the specified routine. */
void
rs6000_trampoline_template
(
file
)
FILE
*
file
;
{
char
*
sc
=
reg_names
[
STATIC_CHAIN_REGNUM
];
char
*
r0
=
reg_names
[
0
];
switch
(
DEFAULT_ABI
)
{
default
:
abort
();
/* Under AIX, this is not code at all, but merely a data area,
since that is the way all functions are called. The first word is
the address of the function, the second word is the TOC pointer (r2),
and the third word is the static chain value. */
case
ABI_AIX
:
fprintf
(
file
,
"
\t
.long %s
\n
"
,
(
TARGET_64BIT
)
?
"0,0,0,0,0,0"
:
"0,0,0"
);
break
;
/* V.4/eabi function pointers are just a single pointer, so we need to
do the full gory code to load up the static chain. */
case
ABI_V4
:
case
ABI_AIX_NODESC
:
if
(
STATIC_CHAIN_REGNUM
==
0
||
!
TARGET_NEW_MNEMONICS
)
abort
();
if
(
TARGET_64BIT
)
{
fprintf
(
file
,
"
\t
mflr %s
\n
"
,
r0
);
/* offset 0 */
fprintf
(
file
,
"
\t
bl .LTRAMP1
\n
"
);
/* offset 4 */
fprintf
(
file
,
"
\t
.long 0,0,0,0
\n
"
);
/* offset 8 */
fprintf
(
file
,
".LTRAMP1:
\n
"
);
fprintf
(
file
,
"
\t
mflr %s
\n
"
,
sc
);
/* offset 28 */
fprintf
(
file
,
"
\t
mtlr %s
\n
"
,
r0
);
/* offset 32 */
fprintf
(
file
,
"
\t
ld %s,0(%s)
\n
"
,
r0
,
sc
);
/* offset 36 */
fprintf
(
file
,
"
\t
ld %s,8(%s)
\n
"
,
sc
,
sc
);
/* offset 40 */
fprintf
(
file
,
"
\t
mtctr %s
\n
"
,
r0
);
/* offset 44 */
fprintf
(
file
,
"
\t
bctr
\n
"
);
/* offset 48 */
}
else
{
fprintf
(
file
,
"
\t
mflr %s
\n
"
,
r0
);
/* offset 0 */
fprintf
(
file
,
"
\t
bl .LTRAMP1
\n
"
);
/* offset 4 */
fprintf
(
file
,
"
\t
.long 0,0
\n
"
);
/* offset 8 */
fprintf
(
file
,
".LTRAMP1:
\n
"
);
fprintf
(
file
,
"
\t
mflr %s
\n
"
,
sc
);
/* offset 20 */
fprintf
(
file
,
"
\t
mtlr %s
\n
"
,
r0
);
/* offset 24 */
fprintf
(
file
,
"
\t
lwz %s,0(%s)
\n
"
,
r0
,
sc
);
/* offset 28 */
fprintf
(
file
,
"
\t
lwz %s,4(%s)
\n
"
,
sc
,
sc
);
/* offset 32 */
fprintf
(
file
,
"
\t
mtctr %s
\n
"
,
r0
);
/* offset 36 */
fprintf
(
file
,
"
\t
bctr
\n
"
);
/* offset 40 */
}
break
;
/* NT function pointers point to a two word area (real address, TOC)
which unfortunately does not include a static chain field. So we
need to have a 2 word area followed by the code to load up the
static chain. */
case
ABI_NT
:
if
(
STATIC_CHAIN_REGNUM
==
0
||
!
TARGET_NEW_MNEMONICS
||
TARGET_64BIT
)
abort
();
fprintf
(
file
,
"
\t
.ualong 0,0
\n
"
);
/* offset 0 */
fprintf
(
file
,
"
\t
mflr %s
\n
"
,
r0
);
/* offset 8 */
fprintf
(
file
,
"
\t
bl .LTRAMP1
\n
"
);
/* offset 12 */
fprintf
(
file
,
"
\t
.ualong 0,0
\n
"
);
/* offset 16 */
fprintf
(
file
,
".LTRAMP1:
\n
"
);
fprintf
(
file
,
"
\t
mflr %s
\n
"
,
sc
);
/* offset 28 */
fprintf
(
file
,
"
\t
mtlr %s
\n
"
,
r0
);
/* offset 32 */
fprintf
(
file
,
"
\t
lwz %s,0(%s)
\n
"
,
r0
,
sc
);
/* offset 36 */
fprintf
(
file
,
"
\t
lwz %s,4(%s)
\n
"
,
sc
,
sc
);
/* offset 40 */
fprintf
(
file
,
"
\t
mtctr %s
\n
"
,
r0
);
/* offset 44 */
fprintf
(
file
,
"
\t
bctr
\n
"
);
/* offset 48 */
break
;
}
return
;
}
/* Length in units of the trampoline for entering a nested function. */
int
rs6000_trampoline_size
()
{
int
ret
=
0
;
switch
(
DEFAULT_ABI
)
{
default
:
abort
();
case
ABI_AIX
:
ret
=
(
TARGET_64BIT
)
?
24
:
12
;
break
;
case
ABI_V4
:
case
ABI_AIX_NODESC
:
ret
=
(
TARGET_64BIT
?
48
:
40
);
break
;
case
ABI_NT
:
ret
=
52
;
break
;
}
return
ret
;
}
/* Emit RTL insns to initialize the variable parts of a trampoline.
FNADDR is an RTX for the address of the function's pure code.
CXT is an RTX for the static chain value for the function. */
void
rs6000_initialize_trampoline
(
addr
,
fnaddr
,
cxt
)
rtx
addr
;
rtx
fnaddr
;
rtx
cxt
;
{
rtx
reg
,
reg2
,
reg3
;
switch
(
DEFAULT_ABI
)
{
default
:
abort
();
/* Under AIX, just build the 3 word function descriptor */
case
ABI_AIX
:
emit_move_insn
(
gen_rtx
(
MEM
,
SImode
,
memory_address
(
SImode
,
(
addr
))),
gen_rtx
(
MEM
,
SImode
,
memory_address
(
SImode
,
(
fnaddr
))));
emit_move_insn
(
gen_rtx
(
MEM
,
SImode
,
memory_address
(
SImode
,
plus_constant
((
addr
),
4
))),
gen_rtx
(
MEM
,
SImode
,
memory_address
(
SImode
,
plus_constant
((
fnaddr
),
4
))));
emit_move_insn
(
gen_rtx
(
MEM
,
SImode
,
memory_address
(
SImode
,
plus_constant
((
addr
),
8
))),
force_reg
(
SImode
,
(
cxt
)));
break
;
/* Under V.4/eabi, update the two words after the bl to have the real
function address and the static chain. */
case
ABI_V4
:
case
ABI_AIX_NODESC
:
reg
=
gen_reg_rtx
(
Pmode
);
emit_move_insn
(
reg
,
fnaddr
);
emit_move_insn
(
gen_rtx
(
MEM
,
Pmode
,
plus_constant
(
addr
,
8
)),
reg
);
emit_move_insn
(
gen_rtx
(
MEM
,
Pmode
,
plus_constant
(
addr
,
(
TARGET_64BIT
?
16
:
12
))),
cxt
);
rs6000_sync_trampoline
(
addr
);
break
;
/* Under NT, update the first 2 words to look like a normal descriptor, and
then fill in the fields with the function address and static chain after
the bl instruction. */
case
ABI_NT
:
reg
=
gen_reg_rtx
(
Pmode
);
reg2
=
gen_reg_rtx
(
Pmode
);
reg3
=
gen_reg_rtx
(
Pmode
);
emit_move_insn
(
gen_rtx
(
MEM
,
Pmode
,
plus_constant
(
addr
,
4
)),
gen_rtx
(
REG
,
Pmode
,
2
));
emit_move_insn
(
reg
,
fnaddr
);
emit_move_insn
(
reg2
,
gen_rtx
(
MEM
,
Pmode
,
reg
));
emit_move_insn
(
reg3
,
plus_constant
(
addr
,
8
));
emit_move_insn
(
gen_rtx
(
MEM
,
Pmode
,
plus_constant
(
addr
,
16
)),
reg
);
emit_move_insn
(
gen_rtx
(
MEM
,
Pmode
,
addr
),
reg3
);
emit_move_insn
(
gen_rtx
(
MEM
,
Pmode
,
plus_constant
(
addr
,
20
)),
cxt
);
rs6000_sync_trampoline
(
addr
);
break
;
}
return
;
}
gcc/config/rs6000/rs6000.h
View file @
b6c9286a
...
...
@@ -63,8 +63,11 @@ Boston, MA 02111-1307, USA. */
%{mcpu=rsc1: -D_ARCH_PWR} \
%{mcpu=403: -D_ARCH_PPC} \
%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
%{mcpu=602: -D_ARCH_PPC} \
%{mcpu=603: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC}"
%{mcpu=603e: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC} \
%{mcpu=620: -D_ARCH_PPC}"
/* Define the options for the binder: Start text at 512, align all segments
to 512 bytes, and warn if there is text relocation.
...
...
@@ -80,9 +83,15 @@ Boston, MA 02111-1307, USA. */
that to actually build a shared library you will also need to specify an
export list with the -Wl,-bE option. */
#ifndef CROSS_COMPILE
#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\
%{static:-bnso} \
%{shared:-bM:SRE}"
#else
#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\
%{static:-bnso -bI:/lib/syscalls.exp} \
%{!shared:%{g*:-bexport:/usr/lib/libg.exp}} %{shared:-bM:SRE}"
#endif
/* Profiled library versions are used by linking with special directories. */
#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
...
...
@@ -187,6 +196,25 @@ extern int target_flags;
#define TARGET_TOC 1
#endif
/* Pseudo target to say whether this is Windows NT */
#ifndef TARGET_WINDOWS_NT
#define TARGET_WINDOWS_NT 0
#endif
/* Pseudo target to say whether this is MAC */
#ifndef TARGET_MACOS
#define TARGET_MACOS 0
#endif
/* Pseudo target to say whether this is AIX */
#ifndef TARGET_AIX
#if (TARGET_ELF || TARGET_WINDOWS_NT || TARGET_MACOS)
#define TARGET_AIX 0
#else
#define TARGET_AIX 1
#endif
#endif
/* Run-time compilation parameters selecting different hardware subsets.
Macro to define tables used to set the flags.
...
...
@@ -246,6 +274,7 @@ enum processor_type
PROCESSOR_RIOS2
,
PROCESSOR_PPC403
,
PROCESSOR_PPC601
,
PROCESSOR_PPC602
,
PROCESSOR_PPC603
,
PROCESSOR_PPC604
,
PROCESSOR_PPC620
};
...
...
@@ -256,7 +285,7 @@ extern enum processor_type rs6000_cpu;
#define rs6000_cpu_attr ((enum attr_cpu)rs6000_cpu)
/* Define generic processor types based upon current deployment. */
#define PROCESSOR_COMMON PROCESSOR_PPC60
1
#define PROCESSOR_COMMON PROCESSOR_PPC60
4
#define PROCESSOR_POWER PROCESSOR_RIOS1
#define PROCESSOR_POWERPC PROCESSOR_PPC601
...
...
@@ -284,8 +313,16 @@ extern enum processor_type rs6000_cpu;
extern char *m88k_short_data;
#define TARGET_OPTIONS { { "short-data-", &m88k_short_data } } */
/* This is meant to be overriden in target specific files. */
#ifndef SUBTARGET_OPTIONS
#define SUBTARGET_OPTIONS
#endif
#define TARGET_OPTIONS \
{ {"cpu=", &rs6000_cpu_string}}
{ \
{"cpu=", &rs6000_cpu_string} \
SUBTARGET_OPTIONS \
}
extern
char
*
rs6000_cpu_string
;
...
...
@@ -670,6 +707,9 @@ extern char *rs6000_cpu_string;
/* Place to put static chain when calling a function that requires it. */
#define STATIC_CHAIN_REGNUM 11
/* count register number for special purposes */
#define COUNT_REGISTER_REGNUM 66
/* Place that structure value return address is placed.
On the RS/6000, it is passed as an extra parameter. */
...
...
@@ -802,12 +842,16 @@ enum reg_class { NO_REGS, BASE_REGS, GENERAL_REGS, FLOAT_REGS,
/* Optional extra constraints for this machine.
For the RS/6000, `Q' means that this is a memory operand that is just
an offset from a register. */
'Q' means that is a memory operand that is just an offset from a reg.
'R' is for AIX TOC entries.
'S' is for Windows NT SYMBOL_REFs
'T' is for Windows NT LABEL_REFs. */
#define EXTRA_CONSTRAINT(OP, C) \
((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \
: (C) == 'R' ? LEGITIMATE_CONSTANT_POOL_ADDRESS_P (OP) \
: (C) == 'S' ? (TARGET_WINDOWS_NT && DEFAULT_ABI == ABI_NT && GET_CODE (OP) == SYMBOL_REF)\
: (C) == 'T' ? (TARGET_WINDOWS_NT && DEFAULT_ABI == ABI_NT && GET_CODE (OP) == LABEL_REF) \
: 0)
/* Given an rtx X being reloaded into a reg required to be
...
...
@@ -857,32 +901,49 @@ enum reg_class { NO_REGS, BASE_REGS, GENERAL_REGS, FLOAT_REGS,
enum
rs6000_abi
{
ABI_NONE
,
ABI_AIX
,
/* IBM's AIX */
ABI_V4
/* System V.4/eabi */
ABI_AIX_NODESC
,
/* AIX calling sequence minus function descriptors */
ABI_V4
,
/* System V.4/eabi */
ABI_NT
/* Windows/NT */
};
extern
enum
rs6000_abi
rs6000_current_abi
;
/* available for use by subtarget */
/* Default ABI to compile code for */
#ifndef DEFAULT_ABI
#define DEFAULT_ABI ABI_AIX
#endif
/* Structure used to define the rs6000 stack */
typedef
struct
rs6000_stack
{
int
first_gp_reg_save
;
/* first callee saved GP register used */
int
first_fp_reg_save
;
/* first callee saved FP register used */
int
lr_save_p
;
/* true if the link reg needs to be saved */
int
cr_save_p
;
/* true if the CR reg needs to be saved */
int
toc_save_p
;
/* true if the TOC needs to be saved */
int
push_p
;
/* true if we need to allocate stack space */
int
calls_p
;
/* true if the function makes any calls */
int
main_p
;
/* true if this is main */
int
main_save_p
;
/* true if this is main and we need to save args */
enum
rs6000_abi
abi
;
/* which ABI to use */
int
gp_save_offset
;
/* offset to save GP regs from initial SP */
int
fp_save_offset
;
/* offset to save FP regs from initial SP */
int
lr_save_offset
;
/* offset to save LR from initial SP */
int
cr_save_offset
;
/* offset to save CR from initial SP */
int
toc_save_offset
;
/* offset to save the TOC pointer */
int
varargs_save_offset
;
/* offset to save the varargs registers */
int
main_save_offset
;
/* offset to save main's args */
int
reg_size
;
/* register size (4 or 8) */
int
varargs_size
;
/* size to hold V.4 args passed in regs */
int
vars_size
;
/* variable save area size */
int
parm_size
;
/* outgoing parameter size */
int
main_size
;
/* size to hold saving main's args */
int
save_size
;
/* save area size */
int
fixed_size
;
/* fixed size of stack frame */
int
gp_size
;
/* size of saved GP registers */
int
fp_size
;
/* size of saved FP registers */
int
cr_size
;
/* size to hold CR if not in save_size */
int
lr_size
;
/* size to hold LR if not in save_size */
int
toc_size
;
/* size to hold TOC if not in save_size */
int
total_size
;
/* total bytes allocated for stack */
}
rs6000_stack_t
;
...
...
@@ -905,6 +966,12 @@ typedef struct rs6000_stack {
/* Size of the fixed area on the stack */
#define RS6000_SAVE_AREA (TARGET_64BIT ? 48 : 24)
/* Address to save the TOC register */
#define RS6000_SAVE_TOC plus_constant (stack_pointer_rtx, 20)
/* Whether a separate TOC save area is needed */
extern
int
rs6000_save_toc_p
;
/* Size of the V.4 varargs area if needed */
#define RS6000_VARARGS_AREA 0
...
...
@@ -1130,6 +1197,13 @@ typedef struct rs6000_args
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
function_arg_pass_by_reference(&CUM, MODE, TYPE, NAMED)
/* If defined, a C expression that gives the alignment boundary, in bits,
of an argument with the specified mode and type. If it is not defined,
PARM_BOUNDARY is used for all arguments. */
#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
function_arg_boundary (MODE, TYPE)
/* Perform any needed actions needed for a function that is receiving a
variable number of arguments.
...
...
@@ -1202,40 +1276,19 @@ typedef struct rs6000_args
of a trampoline, leaving space for the variable parts.
The trampoline should set the static chain pointer to value placed
into the trampoline and should branch to the specified routine.
On the RS/6000, this is not code at all, but merely a data area,
since that is the way all functions are called. The first word is
the address of the function, the second word is the TOC pointer (r2),
and the third word is the static chain value. */
#define TRAMPOLINE_TEMPLATE(FILE) { fprintf (FILE, "\t.long 0, 0, 0\n"); }
into the trampoline and should branch to the specified routine. */
#define TRAMPOLINE_TEMPLATE(FILE) rs6000_trampoline_template (FILE)
/* Length in units of the trampoline for entering a nested function. */
#define TRAMPOLINE_SIZE
12
#define TRAMPOLINE_SIZE
rs6000_trampoline_size ()
/* Emit RTL insns to initialize the variable parts of a trampoline.
FNADDR is an RTX for the address of the function's pure code.
CXT is an RTX for the static chain value for the function. */
#define INITIALIZE_TRAMPOLINE(ADDR, FNADDR, CXT) \
{ \
emit_move_insn (gen_rtx (MEM, SImode, \
memory_address (SImode, (ADDR))), \
gen_rtx (MEM, SImode, \
memory_address (SImode, (FNADDR)))); \
emit_move_insn (gen_rtx (MEM, SImode, \
memory_address (SImode, \
plus_constant ((ADDR), 4))), \
gen_rtx (MEM, SImode, \
memory_address (SImode, \
plus_constant ((FNADDR), 4)))); \
emit_move_insn (gen_rtx (MEM, SImode, \
memory_address (SImode, \
plus_constant ((ADDR), 8))), \
force_reg (SImode, (CXT))); \
}
rs6000_initialize_trampoline (ADDR, FNADDR, CXT)
/* Definitions for __builtin_return_address and __builtin_frame_address.
__builtin_return_address (0) should give link register (65), enable
...
...
@@ -1247,13 +1300,15 @@ typedef struct rs6000_args
(mrs) */
/* #define RETURN_ADDR_IN_PREVIOUS_FRAME */
/* Number of bytes into the frame return addresses can be found. */
#ifndef TARGET_V4_CALLS
#define RETURN_ADDRESS_OFFSET 8
#else
/* Number of bytes into the frame return addresses can be found. See
rs6000_stack_info in rs6000.c for more information on how the different
abi's store the return address. */
#define RETURN_ADDRESS_OFFSET \
((TARGET_V4_CALLS) ? (TARGET_64BIT ? 8 : 4) : 8)
#endif
((DEFAULT_ABI == ABI_AIX \
|| DEFAULT_ABI == ABI_AIX_NODESC) ? 8 : \
(DEFAULT_ABI == ABI_V4) ? (TARGET_64BIT ? 8 : 4) : \
(DEFAULT_ABI == ABI_NT) ? -4 : \
(fatal ("RETURN_ADDRESS_OFFSET not supported"), 0))
/* The current return address is in link register (65). The return address
of anything farther back is accessed normally at an offset of 8 from the
...
...
@@ -1638,8 +1693,13 @@ typedef struct rs6000_args
.stabs in cc1plus. */
#define FASCIST_ASSEMBLER
#ifndef ASM_OUTPUT_CONSTRUCTOR
#define ASM_OUTPUT_CONSTRUCTOR(file, name)
#endif
#ifndef ASM_OUTPUT_DESTRUCTOR
#define ASM_OUTPUT_DESTRUCTOR(file, name)
#endif
/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
is done just by pretending it is already truncated. */
...
...
@@ -2106,11 +2166,10 @@ toc_section () \
do \
{ \
char *_name = (NAME); \
int _len; \
if (_name[0] == '*') \
(VAR) = _name+1; \
else \
{ \
int _len = strlen (_name); \
_name++; \
_len = strlen (_name); \
if (_name[_len - 1] != ']') \
(VAR) = _name; \
else \
...
...
@@ -2120,7 +2179,6 @@ toc_section () \
(VAR)[_len - 4] = '\0'; \
} \
} \
} \
while (0)
/* Output something to declare an external symbol to the assembler. Most
...
...
@@ -2468,6 +2526,7 @@ do { \
{"easy_fp_constant", {CONST_DOUBLE}}, \
{"reg_or_mem_operand", {SUBREG, MEM, REG}}, \
{"lwa_operand", {SUBREG, MEM, REG}}, \
{"volatile_mem_operand", {MEM}}, \
{"offsettable_addr_operand", {REG, SUBREG, PLUS}}, \
{"fp_reg_or_mem_operand", {SUBREG, MEM, REG}}, \
{"mem_or_easy_const_operand", {SUBREG, MEM, CONST_DOUBLE}}, \
...
...
@@ -2478,6 +2537,7 @@ do { \
{"logical_operand", {SUBREG, REG, CONST_INT}}, \
{"non_logical_cint_operand", {CONST_INT}}, \
{"mask_operand", {CONST_INT}}, \
{"count_register_operand", {REG}}, \
{"call_operand", {SYMBOL_REF, REG}}, \
{"current_file_function_operand", {SYMBOL_REF}}, \
{"input_operand", {SUBREG, MEM, REG, CONST_INT, SYMBOL_REF}}, \
...
...
@@ -2488,6 +2548,16 @@ do { \
{"scc_comparison_operator", {EQ, NE, LE, LT, GE, \
GT, LEU, LTU, GEU, GTU}},
/* uncomment for disabling the corresponding default options */
/* #define MACHINE_no_sched_interblock */
/* #define MACHINE_no_sched_speculative */
/* #define MACHINE_no_sched_speculative_load */
/* indicate that issue rate is defined for this machine
(no need to use the default) */
#define MACHINE_issue_rate
/* Declare functions in rs6000.c */
extern
void
output_options
();
extern
void
rs6000_override_options
();
...
...
@@ -2524,6 +2594,7 @@ extern int current_file_function_operand ();
extern
int
input_operand
();
extern
void
init_cumulative_args
();
extern
void
function_arg_advance
();
extern
int
function_arg_boundary
();
extern
struct
rtx_def
*
function_arg
();
extern
int
function_arg_partial_nregs
();
extern
int
function_arg_pass_by_reference
();
...
...
@@ -2555,3 +2626,6 @@ extern void output_ascii ();
extern
void
rs6000_gen_section_name
();
extern
void
output_function_profiler
();
extern
int
rs6000_adjust_cost
();
extern
void
rs6000_trampoline_template
();
extern
int
rs6000_trampoline_size
();
extern
void
rs6000_initialize_trampoline
();
gcc/config/rs6000/rs6000.md
View file @
b6c9286a
...
...
@@ -40,7 +40,7 @@
;; Processor type -- this attribute must exactly match the processor_type
;; enumeration in rs6000.h.
(define_attr "cpu" "rios1,rios2,ppc403,ppc601,ppc603,ppc604,ppc620"
(define_attr "cpu" "rios1,rios2,ppc403,ppc601,ppc60
2,ppc60
3,ppc604,ppc620"
(const (symbol_ref "rs6000_cpu_attr")))
; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
...
...
@@ -50,39 +50,44 @@
; (POWER and 601 use Integer Unit)
(define_function_unit "lsu" 1 0
(and (eq_attr "type" "load")
(eq_attr "cpu" "
rios
2,ppc603,ppc604,ppc620"))
2
0
)
(eq_attr "cpu" "
ppc60
2,ppc603,ppc604,ppc620"))
2
1
)
(define_function_unit "lsu" 1 0
(and (eq_attr "type" "fpload")
(eq_attr "cpu" "rios2,ppc603,ppc604,ppc620"))
2 0)
(eq_attr "cpu" "ppc604,ppc620"))
3 1)
(define_function_unit "lsu" 1 0
(and (eq_attr "type" "fpload")
(eq_attr "cpu" "ppc602,ppc603"))
2 1)
(define_function_unit "iu" 1 0
(and (eq_attr "type" "load")
(eq_attr "cpu" "rios1,ppc
403,ppc
601"))
2
0
)
(eq_attr "cpu" "rios1,ppc601"))
2
1
)
(define_function_unit "iu" 1 0
(and (eq_attr "type" "fpload")
(eq_attr "cpu" "rios1,ppc601"))
3
0)
2
0)
; Integer Unit (RIOS1, PPC601, PPC603)
; Trivial operations take one cycle which need not be listed here.
(define_function_unit "iu" 1 0
(and (eq_attr "type" "i
mul
")
(eq_attr "cpu" "rios1"))
3 3
)
(and (eq_attr "type" "i
nteger
")
(eq_attr "cpu" "rios1
,ppc601
"))
1 1
)
(define_function_unit "iu" 1 0
(and (eq_attr "type" "imul")
(eq_attr "cpu" "
ppc403
"))
4 4
)
(eq_attr "cpu" "
rios1
"))
3 3
)
(define_function_unit "iu" 1 0
(and (eq_attr "type" "imul")
(eq_attr "cpu" "ppc601,ppc603"))
(eq_attr "cpu" "ppc601,ppc60
2,ppc60
3"))
5 5)
(define_function_unit "iu" 1 0
...
...
@@ -92,45 +97,52 @@
(define_function_unit "iu" 1 0
(and (eq_attr "type" "idiv")
(eq_attr "cpu" "ppc403"))
33 33)
(define_function_unit "iu" 1 0
(and (eq_attr "type" "idiv")
(eq_attr "cpu" "ppc601"))
36 36)
(define_function_unit "iu" 1 0
(and (eq_attr "type" "idiv")
(eq_attr "cpu" "ppc603"))
(eq_attr "cpu" "ppc60
2,ppc60
3"))
37 36)
; RIOS2 has two integer units: a primary one which can perform all
; operations and a secondary one which is fed in lock step with the first
; and can perform "simple" integer operations.
; To catch this we define a 'dummy' imuldiv-unit that is also needed
; for the complex insns.
(define_function_unit "iu2" 2 0
(and (eq_attr "type" "integer")
(eq_attr "cpu" "rios2"))
1 0
[
(eq_attr "type" "imul,idiv")
]
)
1 0)
(define_function_unit "iu2" 2 0
(and (eq_attr "type" "imul")
(eq_attr "cpu" "rios2"))
2 2)
(define_function_unit "iu2" 2 0
(and (eq_attr "type" "idiv")
(eq_attr "cpu" "rios2"))
13 13)
(define_function_unit "imuldiv" 1 0
(and (eq_attr "type" "imul")
(eq_attr "cpu" "rios2"))
2 2
[
(eq_attr "type" "integer")
]
)
2 2
)
(define_function_unit "imuldiv" 1 0
(and (eq_attr "type" "idiv")
(eq_attr "cpu" "rios2"))
13 13
[
(eq_attr "type" "integer")
]
)
13 13)
; PPC604 has three integer units: one primary and two secondary.
(define_function_unit "iu3" 3 0
; PPC604 has two units that perform integer operations
; and one unit for divide/multiply operations (and move
; from/to spr).
(define_function_unit "iu2" 2 0
(and (eq_attr "type" "integer")
(eq_attr "cpu" "ppc604,ppc620"))
1
0
1
1
[
(eq_attr "type" "imul,idiv")
]
)
(define_function_unit "imuldiv" 1 0
...
...
@@ -145,24 +157,65 @@
20 19
[
(eq_attr "type" "integer")
]
)
; Branch Processing Unit
; compare is done on integer unit, but feeds insns which
; execute on the branch unit. Ready-delay of the compare
; on the branch unit is large (3-5 cycles). On the iu/fpu
; it is 1. One drawback is that the compare will also be
; assigned to the bpu, but this inaccuracy is worth for being
; able to fill the compare-branch delay, with insns on iu/fpu.
(define_function_unit "iu" 1 0
(and (eq_attr "type" "compare")
(eq_attr "cpu" "rios1,ppc601"))
1 1)
(define_function_unit "iu2" 2 0
(and (eq_attr "type" "compare")
(eq_attr "cpu" "rios2"))
1 1)
(define_function_unit "bpu" 1 0
(eq_attr "type" "compare")
4 0)
(and (eq_attr "type" "compare")
(eq_attr "cpu" "rios1,rios2,ppc601"))
4 1)
; different machines have different compare timings
; in ppc604, compare is done on the one of the two
; main integer units.
(define_function_unit "iu2" 2 0
(and (eq_attr "type" "compare")
(eq_attr "cpu" "ppc604,ppc620"))
1 1)
(define_function_unit "bpu" 1 0
(eq_attr "type" "delayed_compare")
5 0)
(define_function_unit "bpu" 1 0
; fp compare uses fp unit
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "fpcompare")
(eq_attr "cpu" "rios1
,rios2
"))
8
0
)
(eq_attr "cpu" "rios1"))
8
1
)
(define_function_unit "bpu" 1 0
; rios1 and rios2 have different fpcompare delays
(define_function_unit "fpu2" 2 0
(and (eq_attr "type" "fpcompare")
(eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
4 0)
(eq_attr "cpu" "rios2"))
5 1)
; on ppc601 and ppc603, fpcompare takes also 2 cycles from
; the integer unit
; here we do not define delays, just occupy the unit. The dependencies
; will be signed by the fpcompare definition in the fpu.
(define_function_unit "iu" 1 0
(and (eq_attr "type" "fpcompare")
(eq_attr "cpu" "ppc601,ppc602,ppc603"))
0 2)
; fp compare uses fp unit
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "fpcompare")
(eq_attr "cpu" "ppc601,ppc602,ppc603,ppc604,ppc620"))
5 1)
(define_function_unit "bpu" 1 0
(and (eq_attr "type" "mtjmpr")
...
...
@@ -171,9 +224,18 @@
(define_function_unit "bpu" 1 0
(and (eq_attr "type" "mtjmpr")
(eq_attr "cpu" "ppc
403,ppc601
,ppc603,ppc604,ppc620"))
(eq_attr "cpu" "ppc
601,ppc602
,ppc603,ppc604,ppc620"))
4 0)
; all jumps/branches are executing on the bpu, in 1 cycle, for all machines.
(define_function_unit "bpu" 1 0
(eq_attr "type" "jmpreg")
1 0)
(define_function_unit "bpu" 1 0
(eq_attr "type" "branch")
1 0)
; Floating Point Unit (RIOS1, PPC601, PPC603, PPC604).
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "fp,dmul")
...
...
@@ -187,23 +249,24 @@
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "fp")
(eq_attr "cpu" "ppc603,ppc604,ppc620"))
3
0
)
(eq_attr "cpu" "ppc60
2,ppc60
3,ppc604,ppc620"))
3
1
)
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "dmul")
(eq_attr "cpu" "ppc601"))
5
5
)
5
2
)
; is this true?
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "dmul")
(eq_attr "cpu" "ppc603"))
(eq_attr "cpu" "ppc60
2,ppc60
3"))
4 2)
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "dmul")
(eq_attr "cpu" "ppc604,ppc620"))
3
0
)
3
1
)
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "sdiv,ddiv")
...
...
@@ -217,7 +280,7 @@
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "sdiv")
(eq_attr "cpu" "ppc603,ppc604,ppc620"))
(eq_attr "cpu" "ppc60
2,ppc60
3,ppc604,ppc620"))
18 18)
(define_function_unit "fpu" 1 0
...
...
@@ -227,7 +290,7 @@
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "ddiv")
(eq_attr "cpu" "ppc603"))
(eq_attr "cpu" "ppc60
2,ppc60
3"))
33 33)
(define_function_unit "fpu" 1 0
...
...
@@ -261,6 +324,7 @@
(eq_attr "cpu" "rios2"))
26 26)
;; Start with fixed-point load and store insns. Here we put only the more
;; complex forms. Basic data transfer is done later.
...
...
@@ -1284,12 +1348,11 @@
if (GET_CODE (operands
[
2
]
) == CONST_INT
&& exact_log2 (INTVAL (operands
[
2
]
)) >= 0)
;
else if (TARGET_POWER && ! TARGET_POWERPC)
else if (TARGET_POWERPC)
operands
[
2
]
= force_reg (SImode, operands
[
2
]
);
else if (TARGET_POWER)
FAIL;
else
operands
[
2
]
= force_reg (SImode, operands
[
2
]
);
if (! TARGET_POWER && ! TARGET_POWERPC)
{
emit_move_insn (gen_rtx (REG, SImode, 3), operands
[
1
]
);
emit_move_insn (gen_rtx (REG, SImode, 4), operands
[
2
]
);
...
...
@@ -3898,12 +3961,61 @@
rtx target = (reload_completed || reload_in_progress)
? operands
[
0
]
: gen_reg_rtx (SImode);
/* If this is a function address on -mcall-aixdesc or -mcall-nt,
convert it to the address of the descriptor. */
if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
&& GET_CODE (operands[1]) == SYMBOL_REF
&& XSTR (operands[1], 0)[0] == '.')
{
char *name = XSTR (operands[1], 0);
rtx new_ref;
while (*name == '.')
name++;
new_ref = gen_rtx (SYMBOL_REF, Pmode, name);
CONSTANT_POOL_ADDRESS_P (new_ref) = CONSTANT_POOL_ADDRESS_P (operands[1]);
SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
operands[1] = new_ref;
}
emit_insn (gen_elf_high (target, operands[1]));
emit_insn (gen_elf_low (operands[0], target, operands[1]));
DONE;
}
if (CONSTANT_P (operands
[
1
]
)
if (GET_CODE (operands
[
1
]
) == CONST
&& DEFAULT_ABI == ABI_NT
&& !side_effects_p (operands
[
0
]
))
{
rtx const_term = const0_rtx;
rtx sym = eliminate_constant_term (XEXP (operands
[
1
]
, 0),
&const_term);
if (sym && GET_CODE (const_term) == CONST_INT
&& (GET_CODE (sym) == SYMBOL_REF || GET_CODE (sym) == LABEL_REF))
{
emit_insn (gen_movsi (operands
[
0
]
, sym));
if (INTVAL (const_term) != 0)
{
unsigned HOST_WIDE_INT value = INTVAL (const_term);
if (value + 0x8000 < 0x10000)
emit_insn (gen_addsi3 (operands
[
0
]
, operands
[
0
]
, GEN_INT (value)));
else
{
emit_insn (gen_addsi3 (operands
[
0
]
, operands
[
0
]
,
GEN_INT ((value >> 16) + ((value >> 15) & 1))));
if ((value & 0xffff) != 0)
emit_insn (gen_addsi3 (operands[0], operands[0],
GEN_INT (value & 0xffff)));
}
}
DONE;
}
else
fatal_insn (\"bad address\", operands[1]);
}
if ((!TARGET_WINDOWS_NT || DEFAULT_ABI != ABI_NT)
&& CONSTANT_P (operands
[
1
]
)
&& GET_CODE (operands
[
1
]
) != CONST_INT
&& GET_CODE (operands
[
1
]
) != HIGH
&& ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands
[
1
]
))
...
...
@@ -3949,12 +4061,14 @@
}")
(define_insn ""
[
(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,
*q,*
c
*l,*
h")
(match_operand:SI 1 "input_operand" "r,m,r,I,J,R,
*
h,r,r,0"))]
[
(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,
r,r,
m,r,r,r,r,
*q,*
c
*l,*
h")
(match_operand:SI 1 "input_operand" "r,
S,T,
m,r,I,J,R,
*
h,r,r,0"))]
"gpc_reg_operand (operands
[
0
]
, SImode)
|| gpc_reg_operand (operands
[
1
]
, SImode)"
"@
mr %0,%1
{l|lwz} %0,
[
toc
]
%1(2)
{l|lwz} %0,
[
toc
]
%l1(2)
{l%U1%X1|lwz%U1%X1} %0,%1
{st%U0%X0|stw%U0%X0} %1,%0
{lil|li} %0,%1
...
...
@@ -3964,7 +4078,7 @@
mt%0 %1
mt%0 %1
cror 0,0,0"
[
(set_attr "type" "*,load,*,*,*,*,*,*,mtjmpr,*")
]
)
[
(set_attr "type" "*,load,
load,load,
*,*,*,*,*,*,mtjmpr,*")
]
)
;; Split a load of a large constant into the appropriate two-insn
;; sequence.
...
...
@@ -4823,10 +4937,10 @@
;; Argument 3 is the alignment
(define_expand "movstrsi"
[
(parallel
[
(set (match_operand:BLK 0 "
memory_operand
" "")
(match_operand:BLK 1 "
memory_operand
" ""))
(use (match_operand:SI 2 "
general_operand
" ""))
(use (match_operand:SI 3 "
immediate_operand
" ""))])]
[
(parallel
[
(set (match_operand:BLK 0 "" "")
(match_operand:BLK 1 "" ""))
(use (match_operand:SI 2 "" ""))
(use (match_operand:SI 3 "" ""))])]
""
"
{
...
...
@@ -4839,10 +4953,10 @@
;; Move up to 32 bytes at a time. The fixed registers are needed because the
;; register allocator doesn't have a clue about allocating 8 word registers
(define_expand "movstrsi_8reg"
[
(parallel
[
(set (m
em:BLK (match_operand:SI 0 "register_operand" "")
)
(m
em:BLK (match_operand:SI 1 "register_operand" "")
))
(use (match_operand
:SI 2 "immediate_operand
" ""))
(use (match_operand
:SI 3 "immediate_operand
" ""))
[
(parallel
[
(set (m
atch_operand 0 "" ""
)
(m
atch_operand 1 "" ""
))
(use (match_operand
2 "
" ""))
(use (match_operand
3 "
" ""))
(clobber (reg:SI 5))
(clobber (reg:SI 6))
(clobber (reg:SI 7))
...
...
@@ -4902,10 +5016,10 @@
;; Move up to 24 bytes at a time. The fixed registers are needed because the
;; register allocator doesn't have a clue about allocating 6 word registers
(define_expand "movstrsi_6reg"
[
(parallel
[
(set (m
em:BLK (match_operand:SI 0 "register_operand" "")
)
(m
em:BLK (match_operand:SI 1 "register_operand" "")
))
(use (match_operand
:SI 2 "immediate_operand
" ""))
(use (match_operand
:SI 3 "immediate_operand
" ""))
[
(parallel
[
(set (m
atch_operand 0 "" ""
)
(m
atch_operand 1 "" ""
))
(use (match_operand
2 "
" ""))
(use (match_operand
3 "
" ""))
(clobber (reg:SI 7))
(clobber (reg:SI 8))
(clobber (reg:SI 9))
...
...
@@ -4959,10 +5073,10 @@
;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill problems
;; with TImode
(define_expand "movstrsi_4reg"
[
(parallel
[
(set (m
em:BLK (match_operand:SI 0 "register_operand" "")
)
(m
em:BLK (match_operand:SI 1 "register_operand" "")
))
(use (match_operand
:SI 2 "immediate_operand
" ""))
(use (match_operand
:SI 3 "immediate_operand
" ""))
[
(parallel
[
(set (m
atch_operand 0 "" ""
)
(m
atch_operand 1 "" ""
))
(use (match_operand
2 "
" ""))
(use (match_operand
3 "
" ""))
(clobber (reg:SI 9))
(clobber (reg:SI 10))
(clobber (reg:SI 11))
...
...
@@ -5009,10 +5123,10 @@
;; Move up to 8 bytes at a time.
(define_expand "movstrsi_2reg"
[
(parallel
[
(set (m
em:BLK (match_operand:SI 0 "register_operand" "")
)
(m
em:BLK (match_operand:SI 1 "register_operand" "")
))
(use (match_operand
:SI 2 "immediate_operand
" ""))
(use (match_operand
:SI 3 "immediate_operand
" ""))
[
(parallel
[
(set (m
atch_operand 0 "" ""
)
(m
atch_operand 1 "" ""
))
(use (match_operand
2 "
" ""))
(use (match_operand
3 "
" ""))
(clobber (match_scratch:DI 4 ""))
(clobber (match_scratch:SI 5 ""))])]
"TARGET_STRING && !TARGET_64BIT"
...
...
@@ -5044,10 +5158,10 @@
;; Move up to 4 bytes at a time.
(define_expand "movstrsi_1reg"
[
(parallel
[
(set (m
em:BLK (match_operand:SI 0 "register_operand" "")
)
(m
em:BLK (match_operand:SI 1 "register_operand" "")
))
(use (match_operand
:SI 2 "immediate_operand
" ""))
(use (match_operand
:SI 3 "immediate_operand
" ""))
[
(parallel
[
(set (m
atch_operand 0 "" ""
)
(m
atch_operand 1 "" ""
))
(use (match_operand
2 "
" ""))
(use (match_operand
3 "
" ""))
(clobber (match_scratch:SI 4 ""))
(clobber (match_scratch:SI 5 ""))])]
"TARGET_STRING"
...
...
@@ -5395,32 +5509,132 @@
DONE;
}")
;; A function pointer is a pointer to a data area whose first word contains
;; the actual address of the function, whose second word contains a pointer
;; to its TOC, and whose third word contains a value to place in the static
;; chain register (r11). Note that if we load the static chain, our
;; A function pointer under AIX is a pointer to a data area whose first word
;; contains the actual address of the function, whose second word contains a
;; pointer to its TOC, and whose third word contains a value to place in the
;; static chain register (r11). Note that if we load the static chain, our
;; "trampoline" need not have any executable code.
;;
;; operands
[
0
]
is an SImode pseudo in which we place the address of the
;; function.
;; operands
[
1
]
is the address of data area of the function to call
;; operands
[
0
]
is a register pointing to the 3 word descriptor (aka, the function address)
;; operands
[
1
]
is the stack size to clean up
;; operands
[
2
]
is the value FUNCTION_ARG returns for the VOID argument (must be 0 for AIX)
;; operands
[
3
]
is location to store the TOC
;; operands
[
4
]
is the TOC register
;; operands
[
5
]
is the static chain register
;;
;; We do not break this into separate insns, so that the scheduler will not try
;; to move the load of the new TOC before any loads from the TOC.
(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 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"
[
(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 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"
"{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")
]
)
;; A function pointer undef NT is a pointer to a data area whose first word
;; contains the actual address of the function, whose second word contains a
;; pointer to its TOC. The static chain is not stored under NT, which means
;; that we need a trampoline.
;;
;; operands
[
0
]
is an SImode pseudo in which we place the address of the function.
;; operands
[
1
]
is the stack size to clean up
;; operands
[
2
]
is the value FUNCTION_ARG returns for the VOID argument (must be 0 for NT)
;; operands
[
3
]
is location to store the TOC
;; operands
[
4
]
is the TOC register
;;
;; We do not break this into separate insns, so that the scheduler will not try
;; to move the load of the new TOC before any loads from the TOC.
(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 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"
"{st|stw} %4,%a3
\;
{l|lwz} %6,0(%0)
\;
{l|lwz} %4,4(%0);
\;
mt%6 %5
\;
{brl|blrl}
\;
{l|lwz} %4,%a3"
[
(set_attr "length" "24")
]
)
(define_insn "call_value_indirect_nt"
[
(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 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"
"{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")
]
)
;; A function pointer under System V is just a normal pointer
;; operands
[
0
]
is the function pointer
;; operands
[
1
]
is the stack size to clean up
;; operands
[
2
]
is the value FUNCTION_ARG returns for the VOID argument which indicates how to set cr1
(define_insn "call_indirect_sysv"
[
(call (mem:SI (match_operand:SI 0 "register_operand" "l,l"))
(match_operand 1 "const_int_operand" "n,n"))
(use (match_operand 2 "const_int_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
"DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC"
"
*
{
if (INTVAL (operands
[
2
]
) > 0)
return
\"
creqv 6,6,6
\;
{brl|blrl}
\"
;
(define_expand "call_via_ptr"
[
(set (match_operand:SI 0 "gpc_reg_operand" "")
(mem:SI (match_operand:SI 1 "gpc_reg_operand" "")))
(set (mem:SI (plus:SI (reg:SI 1) (const_int 20)))
(reg:SI 2))
(set (reg:SI 2)
(mem:SI (plus:SI (match_dup 1)
(const_int 4))))
(set (reg:SI 11)
(mem:SI (plus:SI (match_dup 1)
(const_int 8))))
(use (reg:SI 2))
(use (reg:SI 11))]
""
"")
else if (INTVAL (operands
[
2
]
) < 0)
return
\"
crxor 6,6,6
\;
{brl|blrl}
\"
;
return
\"
{brl|blrl}
\"
;
}"
[
(set_attr "length" "4,8")
]
)
(define_insn "call_value_indirect_sysv"
[
(set (match_operand 0 "register_operand" "=fg,fg")
(call (mem:SI (match_operand:SI 1 "register_operand" "l,l"))
(match_operand 2 "const_int_operand" "n,n")))
(use (match_operand 3 "const_int_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
"DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC"
"
*
{
if (INTVAL (operands
[
3
]
) > 0)
return
\"
creqv 6,6,6
\;
{brl|blrl}
\"
;
else if (INTVAL (operands
[
3
]
) < 0)
return
\"
crxor 6,6,6
\;
{brl|blrl}
\"
;
return
\"
{brl|blrl}
\"
;
}"
[
(set_attr "length" "4,8")
]
)
;; Now the definitions for the call and call_value insns
(define_expand "call"
[
(parallel
[
(call (mem:SI (match_operand:SI 0 "address_operand" ""))
(match_operand 1 "" ""))
...
...
@@ -5435,13 +5649,33 @@
operands
[
0
]
= XEXP (operands
[
0
]
, 0);
if (GET_CODE (operands
[
0
]
) != SYMBOL_REF)
{
#ifndef USING_SVR4_H
/
* AIX function pointers are really pointers to a three word area *
/
rtx temp = gen_reg_rtx (SImode);
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
]
));
else
{
rtx toc_reg = gen_rtx (REG, Pmode, 2);
rtx toc_addr = RS6000_SAVE_TOC;
emit_insn (gen_call_via_ptr (temp, force_reg (SImode, operands[0])));
operands[0] = temp;
#endif /* !USING_SVR4_H */
if (DEFAULT_ABI == ABI_AIX)
{
/* AIX function pointers are really pointers to a three word area */
rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
emit_call_insn (gen_call_indirect_aix (force_reg (Pmode, operands[0]),
operands[1], operands[2],
toc_addr, toc_reg, static_chain));
}
else if (DEFAULT_ABI == ABI_NT)
{
/* NT function pointers are really pointers to a two word area */
emit_call_insn (gen_call_indirect_nt (force_reg (Pmode, operands[0]),
operands[1], operands[2],
toc_addr, toc_reg));
}
else
abort ();
}
DONE;
}
}")
...
...
@@ -5460,13 +5694,35 @@
operands
[
1
]
= XEXP (operands
[
1
]
, 0);
if (GET_CODE (operands
[
1
]
) != SYMBOL_REF)
{
#ifndef USING_SVR4_H
/
* AIX function pointers are really pointers to a three word area *
/
rtx temp = gen_reg_rtx (SImode);
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
]
));
else
{
rtx toc_reg = gen_rtx (REG, Pmode, 2);
rtx toc_addr = RS6000_SAVE_TOC;
emit_insn (gen_call_via_ptr (temp, force_reg (SImode, operands[1])));
operands[1] = temp;
#endif /* !USING_SVR4_H */
if (DEFAULT_ABI == ABI_AIX)
{
/* AIX function pointers are really pointers to a three word area */
rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
emit_call_insn (gen_call_value_indirect_aix (operands[0],
force_reg (Pmode, operands[1]),
operands[2], operands[3],
toc_addr, toc_reg, static_chain));
}
else if (DEFAULT_ABI == ABI_NT)
{
/* NT function pointers are really pointers to a two word area */
emit_call_insn (gen_call_value_indirect_nt (operands[0],
force_reg (Pmode, operands[1]),
operands[2], operands[3],
toc_addr, toc_reg));
}
else
abort ();
}
DONE;
}
}")
...
...
@@ -5502,11 +5758,11 @@
;; and < 0 if they were not.
(define_insn ""
[
(call (mem:SI (match_operand:SI 0 "call_operand" "
l,s,l
,s"))
(match_operand 1 "" "fg,fg
,fg,fg
"))
(use (match_operand:SI 2 "immediate_operand" "O,
O,n,
n"))
(clobber (match_scratch:SI 3 "=l,l
,l,l
"))]
""
[
(call (mem:SI (match_operand:SI 0 "call_operand" "
s
,s"))
(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
"
"
*
{
if (INTVAL (operands
[
2
]
) > 0)
...
...
@@ -5515,20 +5771,35 @@
else if (INTVAL (operands
[
2
]
) < 0)
output_asm_insn (
\"
crxor 6,6,6
\"
, operands);
#ifndef USING_SVR4_H
/
* Indirect calls should go through call_indirect *
/
if (GET_CODE (operands
[
0
]
) == REG)
return
\"
{brl|blrl}
\;
{l|lwz} 2,20(1)
\"
;
abort ();
return (TARGET_WINDOWS_NT) ?
\"
bl %z0
\;
.znop %z0
\"
:
\"
bl %z0
\;
%.
\"
;
}"
[
(set_attr "length" "8,12")
]
)
(define_insn ""
[
(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
(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"
"
*
{
if (INTVAL (operands
[
2
]
) > 0)
output_asm_insn (
\"
creqv 6,6,6
\"
, operands);
return
\"
bl %z0
\;
%.
\"
;
else if (INTVAL (operands
[
2
]
) < 0)
output_asm_insn (
\"
crxor 6,6,6
\"
, operands);
#else
/
* Indirect calls should go through call_indirect *
/
if (GET_CODE (operands
[
0
]
) == REG)
return
\"
{brl|blrl}
\"
;
abort ()
;
return
\"
bl %z0
\"
;
#endif
}"
[
(set_attr "length" "
8,8,12,12
")
]
)
[
(set_attr "length" "
4,8
")
]
)
(define_insn ""
[
(set (match_operand 0 "" "=fg,fg")
...
...
@@ -5550,12 +5821,12 @@
[
(set_attr "length" "4,8")
]
)
(define_insn ""
[
(set (match_operand 0 "" "=fg,fg
,fg,fg
")
(call (mem:SI (match_operand:SI 1 "call_operand" "
l,s,l
,s"))
(match_operand 2 "" "fg,fg
,fg,fg
")))
(use (match_operand:SI 3 "immediate_operand" "O,
O,n,
n"))
(clobber (match_scratch:SI 4 "=l,l
,l,l
"))]
""
[
(set (match_operand 0 "" "=fg,fg")
(call (mem:SI (match_operand:SI 1 "call_operand" "
s
,s"))
(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
"
"
*
{
if (INTVAL (operands
[
3
]
) > 0)
...
...
@@ -5564,20 +5835,37 @@
else if (INTVAL (operands
[
3
]
) < 0)
output_asm_insn (
\"
crxor 6,6,6
\"
, operands);
#ifndef USING_SVR4_H
/
* This should be handled by call_value_indirect *
/
if (GET_CODE (operands
[
1
]
) == REG)
return
\"
{brl|blrl}
\;
{l|lwz} 2,20(1)
\"
;
abort ()
;
return
\"
bl %z1
\;
%.
\"
;
return (TARGET_WINDOWS_NT) ?
\"
bl %z1
\;
.znop %z1
\"
:
\"
bl %z1
\;
%.
\"
;
}"
[
(set_attr "length" "8,12")
]
)
#else
(define_insn ""
[
(set (match_operand 0 "" "=fg,fg")
(call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
(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"
"
*
{
if (INTVAL (operands
[
3
]
) > 0)
output_asm_insn (
\"
creqv 6,6,6
\"
, operands);
else if (INTVAL (operands
[
3
]
) < 0)
output_asm_insn (
\"
crxor 6,6,6
\"
, operands);
/
* This should be handled by call_value_indirect *
/
if (GET_CODE (operands
[
1
]
) == REG)
return
\"
{brl|blrl}
\"
;
abort ()
;
return
\"
bl %z1
\"
;
#endif
}"
[
(set_attr "length" "8,8,12,12")
]
)
[
(set_attr "length" "4,8")
]
)
;; Call subroutine returning any type.
...
...
@@ -5616,12 +5904,32 @@
""
"")
;; Synchronize instruction/data caches for V.4 trampolines
(define_insn "sync_isync"
[
(unspec [(match_operand 0 "memory_operand" "=m")
]
1)]
;; Synchronize instructions/data caches for V.4 trampolines
;; The extra memory_operand is to prevent the optimizer from
;; deleting insns with "no" effect.
(define_insn "icbi"
[
(unspec
[
(match_operand 0 "memory_operand" "=m")
(match_operand 1 "register_operand" "b")
(match_operand 2 "register_operand" "r")] 3)]
"TARGET_POWERPC"
"icbi %1,%2")
(define_insn "dcbst"
[
(unspec
[
(match_operand 0 "memory_operand" "=m")
(match_operand 1 "register_operand" "b")
(match_operand 2 "register_operand" "r")] 4)]
"TARGET_POWERPC"
"dcbst %1,%2")
(define_insn "sync"
[
(unspec [(match_operand 0 "memory_operand" "=m")
]
5)]
""
"{dcs|sync}
\;
{ics|isync}"
[
(set_attr "length" "8")
]
)
"{dcs|sync}")
(define_insn "isync"
[
(unspec [(match_operand 0 "memory_operand" "=m")
]
6)]
""
"{ics|isync}")
;; Compare insns are next. Note that the RS/6000 has two types of compares,
...
...
@@ -7285,14 +7593,14 @@
;; Define the subtract-one-and-jump insns, starting with the template
;; so loop.c knows what to generate.
(define_expand "decrement_and_branchsi"
[
(parallel
[
(set (match_operand:SI 0 "register_operand" "")
(plus:SI (match_dup 0)
(const_int -1)))
(set (pc) (if_then_else (ne (match_dup 0)
(define_expand "decrement_and_branch_on_count"
[
(parallel
[
(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "")
(const_int 1))
(label_ref (match_operand 1 "" ""))
(pc)))
(set (match_dup 0)
(plus:SI (match_dup 0)
(const_int -1)))
(clobber (match_scratch:CC 2 ""))
(clobber (match_scratch:SI 3 ""))])]
""
...
...
@@ -7503,3 +7811,4 @@
"
{ operands
[
7
]
= gen_rtx (GET_CODE (operands
[
2
]
), VOIDmode, operands
[
3
]
,
const0_rtx); }")
gcc/config/rs6000/sysv4.h
View file @
b6c9286a
...
...
@@ -25,30 +25,38 @@ Boston, MA 02111-1307, USA. */
#define MASK_NO_BITFIELD_TYPE 0x40000000
/* Set PCC_BITFIELD_TYPE_MATTERS to 0 */
#define MASK_STRICT_ALIGN 0x20000000
/* Set STRICT_ALIGNMENT to 1. */
#define MASK_RELOCATABLE 0x10000000
/* GOT pointers are PC relative */
#define MASK_
NO_TRACEBACK 0x08000000
/* eliminate traceback words
*/
#define MASK_
UNUSED 0x08000000
/* UNUSED, was no-traceback
*/
#define MASK_LITTLE_ENDIAN 0x04000000
/* target is little endian */
#define MASK_
AIX_CALLS 0x02000000
/* Use AIX calling sequence
*/
#define MASK_
CALLS_1 0x02000000
/* First ABI bit (AIX, AIXDESC)
*/
#define MASK_PROTOTYPE 0x01000000
/* Only prototyped fcns pass variable args */
#define MASK_CALLS_2 0x00800000
/* Second ABI bit (NT) */
#define MASK_CALLS (MASK_CALLS_1 | MASK_CALLS_2)
#define MASK_CALLS_V4 0
#define MASK_CALLS_AIX MASK_CALLS_1
#define MASK_CALLS_NT MASK_CALLS_2
#define MASK_CALLS_AIXDESC MASK_CALLS
#define TARGET_NO_BITFIELD_TYPE (target_flags & MASK_NO_BITFIELD_TYPE)
#define TARGET_STRICT_ALIGN (target_flags & MASK_STRICT_ALIGN)
#define TARGET_RELOCATABLE (target_flags & MASK_RELOCATABLE)
#define TARGET_NO_TRACEBACK (target_flags & MASK_NO_TRACEBACK)
#define TARGET_LITTLE_ENDIAN (target_flags & MASK_LITTLE_ENDIAN)
#define TARGET_AIX_CALLS (target_flags & MASK_AIX_CALLS)
#define TARGET_PROTOTYPE (target_flags & MASK_PROTOTYPE)
#define TARGET_TOC (target_flags & (MASK_64BIT \
#define TARGET_TOC (
(
target_flags & (MASK_64BIT \
| MASK_RELOCATABLE \
| MASK_MINIMAL_TOC))
| MASK_MINIMAL_TOC)) \
|| DEFAULT_ABI == ABI_AIX \
|| DEFAULT_ABI == ABI_NT)
#define TARGET_BITFIELD_TYPE (! TARGET_NO_BITFIELD_TYPE)
#define TARGET_TRACEBACK (! TARGET_NO_TRACEBACK)
#define TARGET_BIG_ENDIAN (! TARGET_LITTLE_ENDIAN)
#define TARGET_NO_AIX_CALLS (! TARGET_AIX_CALLS)
#define TARGET_NO_PROTOTYPE (! TARGET_PROTOTYPE)
#define TARGET_NO_TOC (! TARGET_TOC)
#define TARGET_V4_CALLS TARGET_NO_AIX_CALLS
#define TARGET_AIX_CALLS (target_flags & MASK_CALLS_1)
/* either -mcall-aix or -mcall-aixdesc */
#define TARGET_V4_CALLS ((target_flags & MASK_CALLS) == MASK_CALLS_V4)
#define TARGET_NT_CALLS ((target_flags & MASK_CALLS) == MASK_CALLS_NT)
#define TARGET_AIXDESC_CALLS ((target_flags & MASK_CALLS) == MASK_CALLS_AIXDESC)
/* Pseudo target to indicate whether the object format is ELF
(to get around not having conditional compilation in the md file) */
...
...
@@ -64,8 +72,8 @@ Boston, MA 02111-1307, USA. */
{ "no-strict-align", -MASK_STRICT_ALIGN }, \
{ "relocatable", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \
{ "no-relocatable", -MASK_RELOCATABLE }, \
{ "
traceback", -MASK_NO_TRACEBACK },
\
{ "no-
traceback", MASK_NO_TRACEBACK
}, \
{ "
relocatable-lib", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC },
\
{ "no-
relocatable-lib", -MASK_RELOCATABLE
}, \
{ "little-endian", MASK_LITTLE_ENDIAN }, \
{ "little", MASK_LITTLE_ENDIAN }, \
{ "big-endian", -MASK_LITTLE_ENDIAN }, \
...
...
@@ -73,10 +81,19 @@ Boston, MA 02111-1307, USA. */
{ "no-toc", 0 }, \
{ "toc", MASK_MINIMAL_TOC }, \
{ "full-toc", MASK_MINIMAL_TOC }, \
{ "call-aix", MASK_AIX_CALLS }, \
{ "call-sysv", -MASK_AIX_CALLS }, \
{ "call-aix", MASK_CALLS_AIX }, \
{ "call-aix", -MASK_CALLS_NT }, \
{ "call-aixdesc", MASK_CALLS_AIXDESC }, \
{ "call-aixdesc", -MASK_LITTLE_ENDIAN }, \
{ "call-sysv", -MASK_CALLS }, \
{ "call-nt", MASK_CALLS_NT | MASK_LITTLE_ENDIAN }, \
{ "call-nt", -MASK_CALLS_AIX }, \
{ "prototype", MASK_PROTOTYPE }, \
{ "no-prototype", -MASK_PROTOTYPE },
{ "no-prototype", -MASK_PROTOTYPE }, \
{ "no-traceback", 0 }, \
{ "sim", 0 }, \
{ "mvme", 0 }, \
{ "emb", 0 }, \
/* Sometimes certain combinations of command options do not make sense
on a particular target machine. You can define a macro
...
...
@@ -94,8 +111,40 @@ do { \
target_flags |= MASK_MINIMAL_TOC; \
error ("-mrelocatable and -mno-minimal-toc are incompatible."); \
} \
\
if (TARGET_RELOCATABLE && TARGET_AIXDESC_CALLS) \
{ \
target_flags &= ~MASK_RELOCATABLE; \
error ("-mrelocatable and -mcall-aixdesc are incompatible."); \
} \
\
if (TARGET_RELOCATABLE && TARGET_NT_CALLS) \
{ \
target_flags &= ~MASK_MINIMAL_TOC; \
error ("-mrelocatable and -mcall-nt are incompatible."); \
} \
\
if (TARGET_AIXDESC_CALLS && TARGET_LITTLE_ENDIAN) \
{ \
target_flags &= ~MASK_LITTLE_ENDIAN; \
error ("-mcall-aixdesc must be big endian"); \
} \
\
if (TARGET_NT_CALLS && TARGET_BIG_ENDIAN) \
{ \
target_flags |= MASK_LITTLE_ENDIAN; \
error ("-mcall-nt must be little endian"); \
} \
\
rs6000_current_abi = ((TARGET_AIXDESC_CALLS) ? ABI_AIX : \
(TARGET_NT_CALLS) ? ABI_NT : \
(TARGET_AIX_CALLS) ? ABI_AIX_NODESC : \
ABI_V4); \
} while (0)
/* Default ABI to compile code for */
#define DEFAULT_ABI rs6000_current_abi
#include "rs6000/powerpc.h"
/* System V.4 uses register 13 as a pointer to the small data area,
...
...
@@ -152,12 +201,6 @@ do { \
#undef OBJECT_FORMAT_COFF
/* The XCOFF support uses weird symbol suffixes, which we don't want
for ELF. */
#undef RS6000_OUTPUT_BASENAME
#define RS6000_OUTPUT_BASENAME(FILE, NAME) assemble_name (FILE, NAME)
/* Don't bother to output .extern pseudo-ops. They are not needed by
ELF assemblers. */
...
...
@@ -237,6 +280,32 @@ toc_section () \
if (in_section != in_toc) \
{ \
in_section = in_toc; \
if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) \
&& TARGET_MINIMAL_TOC \
&& !TARGET_RELOCATABLE) \
{ \
if (! toc_initialized) \
{ \
toc_initialized = 1; \
fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP); \
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LCTOC", 0); \
fprintf (asm_out_file, "\t.tc "); \
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],"); \
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1"); \
fprintf (asm_out_file, "\n"); \
\
fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); \
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1"); \
fprintf (asm_out_file, " = .+32768\n"); \
} \
else \
fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); \
} \
else if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) \
&& !TARGET_RELOCATABLE) \
fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP); \
else \
{ \
fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); \
if (! toc_initialized) \
{ \
...
...
@@ -245,6 +314,7 @@ toc_section () \
toc_initialized = 1; \
} \
} \
} \
}
#define TOC_SECTION_ASM_OP "\t.section\t\".got\",\"aw\""
...
...
@@ -260,6 +330,30 @@ toc_section () \
const_section (); \
}
/* Return non-zero if this entry is to be written into the constant pool
in a special way. We do so if this is a SYMBOL_REF, LABEL_REF or a CONST
containing one of them. If -mfp-in-toc (the default), we also do
this for floating-point constants. We actually can only do this
if the FP formats of the target and host machines are the same, but
we can't check that since not every file that uses
GO_IF_LEGITIMATE_ADDRESS_P includes real.h.
Unlike AIX, we don't key off of -mmininal-toc, but instead do not
allow floating point constants in the TOC if -mrelocatable. */
#undef ASM_OUTPUT_SPECIAL_POOL_ENTRY_P
#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X) \
(TARGET_TOC \
&& (GET_CODE (X) == SYMBOL_REF \
|| (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS \
&& GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF) \
|| GET_CODE (X) == LABEL_REF \
|| (!TARGET_NO_FP_IN_TOC \
&& !TARGET_RELOCATABLE \
&& GET_CODE (X) == CONST_DOUBLE \
&& GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
&& BITS_PER_WORD == HOST_BITS_PER_INT)))
/* These macros generate the special .type and .size directives which
are used to set the corresponding fields of the linker symbol table
entries in an ELF object file under SVR4. These macros also output
...
...
@@ -269,37 +363,53 @@ toc_section () \
Some svr4 assemblers need to also have something extra said about the
function's return value. We allow for that here. */
extern
void
svr4_traceback
();
extern
int
rs6000_pic_labelno
;
#undef ASM_DECLARE_FUNCTION_NAME
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
do { \
char *orig_name; \
char *init_ptr = (TARGET_64BIT) ? ".quad" : ".long"; \
STRIP_NAME_ENCODING (orig_name, NAME); \
\
if (TARGET_RELOCATABLE && get_pool_size () != 0) \
{ \
char buf[256]
;
\
char buf[256]
, *buf_ptr;
\
\
ASM_OUTPUT_INTERNAL_LABEL (FILE, "LCL", rs6000_pic_labelno); \
\
ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); \
fprintf (FILE, (TARGET_POWERPC64) ? "\t.quad " : "\t.long "); \
assemble_name (FILE, buf); \
putc ('-', FILE); \
STRIP_NAME_ENCODING (buf_ptr, buf); \
fprintf (FILE, "\t%s %s-", init_ptr, buf_ptr); \
\
ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); \
assemble_name (FILE, buf); \
putc ('\n', FILE); \
fprintf (FILE, "%s\n", buf_ptr); \
} \
\
fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \
assemble_name (FILE, NAME); \
putc (',', FILE); \
fprintf (FILE, "\t%s\t %s,", TYPE_ASM_OP, orig_name); \
fprintf (FILE, TYPE_OPERAND_FMT, "function"); \
putc ('\n', FILE); \
if (TARGET_TRACEBACK) \
svr4_traceback (FILE, NAME, DECL); \
ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
ASM_OUTPUT_LABEL(FILE, NAME); \
\
if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) \
{ \
char *desc_name = orig_name; \
\
while (*desc_name == '.') \
desc_name++; \
\
if (TREE_PUBLIC (DECL)) \
fprintf (FILE, "\t.globl %s\n", desc_name); \
\
fprintf (FILE, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); \
fprintf (FILE, "%s:\n", desc_name); \
fprintf (FILE, "\t%s %s\n", init_ptr, orig_name); \
fprintf (FILE, "\t%s _GLOBAL_OFFSET_TABLE_\n", init_ptr); \
if (DEFAULT_ABI == ABI_AIX) \
fprintf (FILE, "\t%s 0\n", init_ptr); \
fprintf (FILE, "\t.previous\n"); \
} \
fprintf (FILE, "%s:\n", orig_name); \
} while (0)
/* How to renumber registers for dbx and gdb. */
...
...
@@ -315,11 +425,30 @@ extern int rs6000_pic_labelno;
/* Pass -mppc to the assembler, since that is what powerpc.h currently
implies. */
#undef ASM_SPEC
#define ASM_SPEC \
"-u \
%{mcpu=601: -m601} %{!mcpu=601: -mppc} \
#define ASM_SPEC "\
-u \
%{!mcpu*: \
%{mpower2: -mpwrx} \
%{mpowerpc*: %{!mpower: -mppc}} \
%{mno-powerpc: %{!mpower: %{!mpower2: -mcom}}} \
%{mno-powerpc: %{mpower: %{!mpower2: -mpwr}}} \
%{!mno-powerpc: %{mpower: -m601}} \
%{!mno-powerpc: %{!mpower: -mppc}}} \
%{mcpu=common: -mcom} \
%{mcpu=power: -mpwr} \
%{mcpu=powerpc: -mppc} \
%{mcpu=rios: -mpwr} \
%{mcpu=rios1: -mpwr} \
%{mcpu=rios2: -mpwrx} \
%{mcpu=rsc: -mpwr} \
%{mcpu=rsc1: -mpwr} \
%{mcpu=403: -mppc} \
%{mcpu=601: -m601} \
%{mcpu=603: -mppc} \
%{mcpu=603e: -mppc} \
%{mcpu=604: -mppc} \
%{V} %{v:%{!V:-V}} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \
%{mrelocatable} \
%{mrelocatable}
%{mrelocatable-lib} %{memb}
\
%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian}"
/* Output .file and comments listing what options there are */
...
...
@@ -330,6 +459,61 @@ do { \
output_file_directive ((FILE), main_input_filename); \
} while (0)
/* This is how to output an assembler line defining an `int' constant.
For -mrelocatable, we mark all addresses that need to be fixed up
in the .fixup section. */
#undef ASM_OUTPUT_INT
#define ASM_OUTPUT_INT(FILE,VALUE) \
do { \
static int recurse = 0; \
if (TARGET_RELOCATABLE \
&& in_section != in_toc \
&& in_section != in_text \
&& in_section != in_ctors \
&& in_section != in_dtors \
&& !recurse \
&& GET_CODE (VALUE) != CONST_INT \
&& GET_CODE (VALUE) != CONST_DOUBLE \
&& CONSTANT_P (VALUE)) \
{ \
static int labelno = 0; \
char buf[256], *p; \
\
recurse = 1; \
ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", labelno++); \
STRIP_NAME_ENCODING (p, buf); \
fprintf (FILE, "%s:\n", p); \
fprintf (FILE, "\t.long ("); \
output_addr_const (FILE, (VALUE)); \
fprintf (FILE, ")@fixup\n"); \
fprintf (FILE, "\t.section\t\".fixup\",\"aw\"\n"); \
ASM_OUTPUT_ALIGN (FILE, 2); \
fprintf (FILE, "\t.long\t%s\n", p); \
fprintf (FILE, "\t.previous\n"); \
recurse = 0; \
} \
/* Remove initial .'s to turn a -mcall-aixdesc or -mcall-nt function \
address into the address of the descriptor, not the function \
itself. */
\
else if (GET_CODE (VALUE) == SYMBOL_REF \
&& XSTR (VALUE, 0)[0] == '.' \
&& (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)) \
{ \
char *name = XSTR (VALUE, 0); \
while (*name == '.') \
name++; \
\
fprintf (FILE, "\t.long %s\n", name); \
} \
else \
{ \
fprintf (FILE, "\t.long "); \
output_addr_const (FILE, (VALUE)); \
fprintf (FILE, "\n"); \
} \
} while (0)
/* This is the end of what might become sysv4.h. */
/* Allow stabs and dwarf, prefer dwarf. */
...
...
@@ -337,6 +521,35 @@ do { \
#define DBX_DEBUGGING_INFO
#define DWARF_DEBUGGING_INFO
/* If we are referencing a function that is static or is known to be
in this file, make the SYMBOL_REF special. We can use this to indicate
that we can branch to this function without emitting a no-op after the
call. For real AIX and NT calling sequences, we also replace the
function name with the real name (1 or 2 leading .'s), rather than
the function descriptor name. This saves a lot of overriding code
to readd the prefixes. */
#undef ENCODE_SECTION_INFO
#define ENCODE_SECTION_INFO(DECL) \
do { \
if (TREE_CODE (DECL) == FUNCTION_DECL) \
{ \
rtx sym_ref = XEXP (DECL_RTL (DECL), 0); \
if (TREE_ASM_WRITTEN (DECL) || ! TREE_PUBLIC (DECL)) \
SYMBOL_REF_FLAG (sym_ref) = 1; \
\
if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) \
{ \
char *prefix = (DEFAULT_ABI == ABI_AIX) ? "." : ".."; \
char *str = permalloc (strlen (prefix) + 1 \
+ strlen (XSTR (sym_ref, 0))); \
strcpy (str, prefix); \
strcat (str, XSTR (sym_ref, 0)); \
XSTR (sym_ref, 0) = str; \
} \
} \
} while (0)
/* This macro gets just the user-specified name
out of the string in a SYMBOL_REF. Discard
a leading * */
...
...
@@ -344,24 +557,6 @@ do { \
#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \
(VAR) = ((SYMBOL_NAME) + ((SYMBOL_NAME)[0] == '*'))
/* Like block addresses, stabs line numbers are relative to the
current function. */
#undef ASM_OUTPUT_SOURCE_LINE
#define ASM_OUTPUT_SOURCE_LINE(file, line) \
do \
{ \
static int sym_lineno = 1; \
char *_p; \
fprintf (file, "\t.stabn 68,0,%d,.LM%d-", \
line, sym_lineno); \
STRIP_NAME_ENCODING (_p, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
assemble_name (file, _p); \
fprintf (file, "\n.LM%d:\n", sym_lineno); \
sym_lineno += 1; \
} \
while (0)
/* But, to make this work, we have to output the stabs for the function
name *first*... */
...
...
@@ -372,77 +567,6 @@ while (0)
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC System V.4)");
/* Output assembler code for a block containing the constant parts
of a trampoline, leaving space for the variable parts.
The trampoline should set the static chain pointer to value placed
into the trampoline and should branch to the specified routine.
Unlike AIX, this needs real code. */
#undef TRAMPOLINE_TEMPLATE
#define TRAMPOLINE_TEMPLATE(FILE) \
do { \
char *sc = reg_names[STATIC_CHAIN_REGNUM]; \
char *r0 = reg_names[0]; \
\
if (STATIC_CHAIN_REGNUM == 0 || !TARGET_NEW_MNEMONICS) \
abort (); \
\
if (TARGET_64BIT) \
{ \
fprintf (FILE, "\tmflr %s\n", r0);
/* offset 0 */
\
fprintf (FILE, "\tbl .LTRAMP1\n");
/* offset 4 */
\
fprintf (FILE, "\t.long 0,0,0,0\n");
/* offset 8 */
\
fprintf (FILE, ".LTRAMP1:\n"); \
fprintf (FILE, "\tmflr %s\n", sc);
/* offset 28 */
\
fprintf (FILE, "\tmtlr %s\n", r0);
/* offset 32 */
\
fprintf (FILE, "\tld %s,0(%s)\n", r0, sc);
/* offset 36 */
\
fprintf (FILE, "\tld %s,8(%s)\n", sc, sc);
/* offset 40 */
\
fprintf (FILE, "\tmtctr %s\n", r0);
/* offset 44 */
\
fprintf (FILE, "\tbctr\n");
/* offset 48 */
\
} \
else \
{ \
fprintf (FILE, "\tmflr %s\n", r0);
/* offset 0 */
\
fprintf (FILE, "\tbl .LTRAMP1\n");
/* offset 4 */
\
fprintf (FILE, "\t.long 0,0\n");
/* offset 8 */
\
fprintf (FILE, ".LTRAMP1:\n"); \
fprintf (FILE, "\tmflr %s\n", sc);
/* offset 20 */
\
fprintf (FILE, "\tmtlr %s\n", r0);
/* offset 24 */
\
fprintf (FILE, "\tlwz %s,0(%s)\n", r0, sc);
/* offset 28 */
\
fprintf (FILE, "\tlwz %s,4(%s)\n", sc, sc);
/* offset 32 */
\
fprintf (FILE, "\tmtctr %s\n", r0);
/* offset 36 */
\
fprintf (FILE, "\tbctr\n");
/* offset 40 */
\
} \
} while (0)
/* Length in units of the trampoline for entering a nested function. */
#undef TRAMPOLINE_SIZE
#define TRAMPOLINE_SIZE (TARGET_64BIT ? 48 : 40)
/* Emit RTL insns to initialize the variable parts of a trampoline.
FNADDR is an RTX for the address of the function's pure code.
CXT is an RTX for the static chain value for the function. */
#undef INITIALIZE_TRAMPOLINE
#define INITIALIZE_TRAMPOLINE(ADDR, FNADDR, CXT) \
{ \
rtx reg = gen_reg_rtx (Pmode); \
\
emit_move_insn (reg, FNADDR); \
emit_move_insn (gen_rtx (MEM, Pmode, \
plus_constant (ADDR, 8)), \
reg); \
emit_move_insn (gen_rtx (MEM, Pmode, \
plus_constant (ADDR, (TARGET_64BIT ? 16 : 12))), \
CXT); \
emit_insn (gen_sync_isync (gen_rtx (MEM, BLKmode, ADDR))); \
}
#undef CPP_PREDEFINES
#define CPP_PREDEFINES \
"-DPPC -Dunix -D__svr4__ -Asystem(unix) -Asystem(svr4) -Acpu(powerpc) -Amachine(powerpc)"
...
...
@@ -482,7 +606,9 @@ do { \
#define CPP_SPEC "\
%{posix: -D_POSIX_SOURCE} \
%{mrelocatable: -D_RELOCATABLE} \
%{mcall-sysv: -D_CALL_SYSV} %{mcall-aix: -D_CALL_AIX} %{!mcall-sysv: %{!mcall-aix: -D_CALL_SYSV}} \
%{mcall-sysv: -D_CALL_SYSV} %{mcall-nt: -D_CALL_NT} \
%{mcall-aix: -D_CALL_AIX} %{mcall-aixdesc: -D_CALL_AIX -D_CALL_AIXDESC} \
%{!mcall-sysv: %{!mcall-aix: %{!mcall-aixdesc: %{!mcall-nt: -D_CALL_SYSV}}}} \
%{msoft-float: -D_SOFT_FLOAT} %{mcpu=403: -D_SOFT_FLOAT} \
%{mlittle: -D_LITTLE_ENDIAN -Amachine(littleendian)} \
%{mlittle-endian: -D_LITTLE_ENDIAN -Amachine(littleendian)} \
...
...
@@ -503,5 +629,20 @@ do { \
%{mcpu=rsc1: -D_ARCH_PWR} \
%{mcpu=403: -D_ARCH_PPC} \
%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
%{mcpu=602: -D_ARCH_PPC} \
%{mcpu=603: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC}"
%{mcpu=603e: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC} \
%{mcpu=620: -D_ARCH_PPC}"
/* Define this macro as a C expression for the initializer of an
array of string to tell the driver program which options are
defaults for this target and thus do not need to be handled
specially when using `MULTILIB_OPTIONS'.
Do not define this macro if `MULTILIB_OPTIONS' is not defined in
the target makefile fragment or if none of the options listed in
`MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */
#undef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS { "mbig", "mbig-endian", "mcall-sysv" }
gcc/config/rs6000/sysv4le.h
View file @
b6c9286a
...
...
@@ -29,7 +29,9 @@ Boston, MA 02111-1307, USA. */
#define CPP_SPEC "\
%{posix: -D_POSIX_SOURCE} \
%{mrelocatable: -D_RELOCATABLE} \
%{mcall-sysv: -D_CALL_SYSV} %{mcall-aix: -D_CALL_AIX} %{!mcall-sysv: %{!mcall-aix: -D_CALL_SYSV}} \
%{mcall-sysv: -D_CALL_SYSV} %{mcall-nt: -D_CALL_NT} \
%{mcall-aix: -D_CALL_AIX} %{mcall-aixdesc: -D_CALL_AIX -D_CALL_AIXDESC} \
%{!mcall-sysv: %{!mcall-aix: %{!mcall-aixdesc: %{!mcall-nt: -D_CALL_SYSV}}}} \
%{msoft-float: -D_SOFT_FLOAT} %{mcpu=403: -D_SOFT_FLOAT} \
%{mbig: -D_BIG_ENDIAN -Amachine(bigendian)} \
%{mbig-endian: -D_BIG_ENDIAN -Amachine(bigendian)} \
...
...
@@ -50,5 +52,20 @@ Boston, MA 02111-1307, USA. */
%{mcpu=rsc1: -D_ARCH_PWR} \
%{mcpu=403: -D_ARCH_PPC} \
%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
%{mcpu=602: -D_ARCH_PPC} \
%{mcpu=603: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC}"
%{mcpu=603e: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC} \
%{mcpu=620: -D_ARCH_PPC}"
/* Define this macro as a C expression for the initializer of an
array of string to tell the driver program which options are
defaults for this target and thus do not need to be handled
specially when using `MULTILIB_OPTIONS'.
Do not define this macro if `MULTILIB_OPTIONS' is not defined in
the target makefile fragment or if none of the options listed in
`MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */
#undef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS { "mlittle", "mlittle-endian", "mcall-sysv" }
gcc/config/rs6000/t-ppc
View file @
b6c9286a
...
...
@@ -2,6 +2,8 @@
LIBGCC1 =
CROSS_LIBGCC1 =
EXTRA_HEADERS = $(srcdir)/ginclude/ppc-asm.h
# These are really part of libgcc1, but this will cause them to be
# built correctly, so... [taken from t-sparclite]
LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
...
...
gcc/config/rs6000/t-ppcgas
View file @
b6c9286a
...
...
@@ -2,6 +2,8 @@
LIBGCC1 =
CROSS_LIBGCC1 =
EXTRA_HEADERS = $(srcdir)/ginclude/ppc-asm.h
# These are really part of libgcc1, but this will cause them to be
# built correctly, so... [taken from t-sparclite]
LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
...
...
@@ -16,15 +18,18 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
# Build libgcc.a with different options.
MULTILIB_OPTIONS = msoft-float \
mlittle
mlittle/mbig \
mcall-sysv/mcall-aix/mcall-aixdesc
MULTILIB_DIRNAMES = soft-float \
little-endian
little big \
sysv aix aixdesc
MULTILIB_MATCHES = mlittle=mlittle-endian \
msoft-float=mcpu?403 \
msoft-float=mcpu?mpc403 \
msoft-float=mcpu?ppc403
mbig=mbig-endian \
msoft-float=mcpu?403
MULTILIB_EXCEPTIONS = *mlittle/*mcall-aixdesc*
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
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