Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
cb15bbe7
Commit
cb15bbe7
authored
Apr 10, 2009
by
Ken Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bug in stack size used in
extending segmented stack R=r OCL=27319 CL=27319
parent
78edbfdc
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
1 addition
and
551 deletions
+1
-551
src/cmd/6c/pgen.c
src/cmd/6c/pgen.c
+1
-1
src/cmd/cc/pgen.c
src/cmd/cc/pgen.c
+0
-550
No files found.
src/cmd/6c/pgen.c
View file @
cb15bbe7
...
...
@@ -37,7 +37,7 @@ argsize(void)
int32
s
;
//print("t=%T\n", thisfn);
s
=
0
;
s
=
align
(
0
,
thisfn
->
link
,
Aarg0
)
;
for
(
t
=
thisfn
->
down
;
t
!=
T
;
t
=
t
->
down
)
{
switch
(
t
->
etype
)
{
case
TVOID
:
...
...
src/cmd/cc/pgen.c
deleted
100644 → 0
View file @
78edbfdc
// Inferno utils/6c/sgen.c
// http://code.google.com/p/inferno-os/source/browse/utils/6c/sgen.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include "gc.h"
void
codgen
(
Node
*
n
,
Node
*
nn
)
{
Prog
*
sp
;
Node
*
n1
,
nod
,
nod1
;
cursafe
=
0
;
curarg
=
0
;
maxargsafe
=
0
;
/*
* isolate name
*/
for
(
n1
=
nn
;;
n1
=
n1
->
left
)
{
if
(
n1
==
Z
)
{
diag
(
nn
,
"cant find function name"
);
return
;
}
if
(
n1
->
op
==
ONAME
)
break
;
}
nearln
=
nn
->
lineno
;
gpseudo
(
ATEXT
,
n1
->
sym
,
nodconst
(
stkoff
));
sp
=
p
;
/*
* isolate first argument
*/
if
(
REGARG
)
{
if
(
typecmplx
[
thisfn
->
link
->
etype
])
{
nod1
=
*
nodret
->
left
;
nodreg
(
&
nod
,
&
nod1
,
REGARG
);
gmove
(
&
nod
,
&
nod1
);
}
else
if
(
firstarg
&&
typeword
[
firstargtype
->
etype
])
{
nod1
=
*
nodret
->
left
;
nod1
.
sym
=
firstarg
;
nod1
.
type
=
firstargtype
;
nod1
.
xoffset
=
align
(
0
,
firstargtype
,
Aarg1
);
nod1
.
etype
=
firstargtype
->
etype
;
nodreg
(
&
nod
,
&
nod1
,
REGARG
);
gmove
(
&
nod
,
&
nod1
);
}
}
canreach
=
1
;
warnreach
=
1
;
gen
(
n
);
if
(
canreach
&&
thisfn
->
link
->
etype
!=
TVOID
)
warn
(
Z
,
"no return at end of function: %s"
,
n1
->
sym
->
name
);
noretval
(
3
);
gbranch
(
ORETURN
);
if
(
!
debug
[
'N'
]
||
debug
[
'R'
]
||
debug
[
'P'
])
regopt
(
sp
);
if
(
thechar
==
'6'
||
thechar
==
'7'
)
/* [sic] */
maxargsafe
=
xround
(
maxargsafe
,
8
);
sp
->
to
.
offset
+=
maxargsafe
;
}
void
supgen
(
Node
*
n
)
{
int
owarn
;
int32
spc
;
Prog
*
sp
;
if
(
n
==
Z
)
return
;
suppress
++
;
owarn
=
warnreach
;
warnreach
=
0
;
spc
=
pc
;
sp
=
lastp
;
gen
(
n
);
lastp
=
sp
;
pc
=
spc
;
sp
->
link
=
nil
;
suppress
--
;
warnreach
=
owarn
;
}
void
gen
(
Node
*
n
)
{
Node
*
l
,
nod
;
Prog
*
sp
,
*
spc
,
*
spb
;
Case
*
cn
;
int32
sbc
,
scc
;
int
snbreak
,
sncontin
;
int
f
,
o
,
oldreach
;
loop:
if
(
n
==
Z
)
return
;
nearln
=
n
->
lineno
;
o
=
n
->
op
;
if
(
debug
[
'G'
])
if
(
o
!=
OLIST
)
print
(
"%L %O
\n
"
,
nearln
,
o
);
if
(
!
canreach
)
{
switch
(
o
)
{
case
OLABEL
:
case
OCASE
:
case
OLIST
:
case
OBREAK
:
case
OFOR
:
case
OWHILE
:
case
ODWHILE
:
/* all handled specially - see switch body below */
break
;
default:
if
(
warnreach
)
{
warn
(
n
,
"unreachable code %O"
,
o
);
warnreach
=
0
;
}
}
}
switch
(
o
)
{
default:
complex
(
n
);
cgen
(
n
,
Z
);
break
;
case
OLIST
:
gen
(
n
->
left
);
rloop:
n
=
n
->
right
;
goto
loop
;
case
ORETURN
:
canreach
=
0
;
warnreach
=
!
suppress
;
complex
(
n
);
if
(
n
->
type
==
T
)
break
;
l
=
n
->
left
;
if
(
l
==
Z
)
{
noretval
(
3
);
gbranch
(
ORETURN
);
break
;
}
if
(
typecmplx
[
n
->
type
->
etype
])
{
sugen
(
l
,
nodret
,
n
->
type
->
width
);
noretval
(
3
);
gbranch
(
ORETURN
);
break
;
}
regret
(
&
nod
,
n
);
cgen
(
l
,
&
nod
);
regfree
(
&
nod
);
if
(
typefd
[
n
->
type
->
etype
])
noretval
(
1
);
else
noretval
(
2
);
gbranch
(
ORETURN
);
break
;
case
OLABEL
:
canreach
=
1
;
l
=
n
->
left
;
if
(
l
)
{
l
->
pc
=
pc
;
if
(
l
->
label
)
patch
(
l
->
label
,
pc
);
}
gbranch
(
OGOTO
);
/* prevent self reference in reg */
patch
(
p
,
pc
);
goto
rloop
;
case
OGOTO
:
canreach
=
0
;
warnreach
=
!
suppress
;
n
=
n
->
left
;
if
(
n
==
Z
)
return
;
if
(
n
->
complex
==
0
)
{
diag
(
Z
,
"label undefined: %s"
,
n
->
sym
->
name
);
return
;
}
if
(
suppress
)
return
;
gbranch
(
OGOTO
);
if
(
n
->
pc
)
{
patch
(
p
,
n
->
pc
);
return
;
}
if
(
n
->
label
)
patch
(
n
->
label
,
pc
-
1
);
n
->
label
=
p
;
return
;
case
OCASE
:
canreach
=
1
;
l
=
n
->
left
;
if
(
cases
==
C
)
diag
(
n
,
"case/default outside a switch"
);
if
(
l
==
Z
)
{
cas
();
cases
->
val
=
0
;
cases
->
def
=
1
;
cases
->
label
=
pc
;
cases
->
isv
=
0
;
goto
rloop
;
}
complex
(
l
);
if
(
l
->
type
==
T
)
goto
rloop
;
if
(
l
->
op
==
OCONST
)
if
(
typeword
[
l
->
type
->
etype
]
&&
l
->
type
->
etype
!=
TIND
)
{
cas
();
cases
->
val
=
l
->
vconst
;
cases
->
def
=
0
;
cases
->
label
=
pc
;
cases
->
isv
=
typev
[
l
->
type
->
etype
];
goto
rloop
;
}
diag
(
n
,
"case expression must be integer constant"
);
goto
rloop
;
case
OSWITCH
:
l
=
n
->
left
;
complex
(
l
);
if
(
l
->
type
==
T
)
break
;
if
(
!
typeword
[
l
->
type
->
etype
]
||
l
->
type
->
etype
==
TIND
)
{
diag
(
n
,
"switch expression must be integer"
);
break
;
}
gbranch
(
OGOTO
);
/* entry */
sp
=
p
;
cn
=
cases
;
cases
=
C
;
cas
();
sbc
=
breakpc
;
breakpc
=
pc
;
snbreak
=
nbreak
;
nbreak
=
0
;
gbranch
(
OGOTO
);
spb
=
p
;
gen
(
n
->
right
);
/* body */
if
(
canreach
){
gbranch
(
OGOTO
);
patch
(
p
,
breakpc
);
nbreak
++
;
}
patch
(
sp
,
pc
);
regalloc
(
&
nod
,
l
,
Z
);
/* always signed */
if
(
typev
[
l
->
type
->
etype
])
nod
.
type
=
types
[
TVLONG
];
else
nod
.
type
=
types
[
TLONG
];
cgen
(
l
,
&
nod
);
doswit
(
&
nod
);
regfree
(
&
nod
);
patch
(
spb
,
pc
);
cases
=
cn
;
breakpc
=
sbc
;
canreach
=
nbreak
!=
0
;
if
(
canreach
==
0
)
warnreach
=
!
suppress
;
nbreak
=
snbreak
;
break
;
case
OWHILE
:
case
ODWHILE
:
l
=
n
->
left
;
gbranch
(
OGOTO
);
/* entry */
sp
=
p
;
scc
=
continpc
;
continpc
=
pc
;
gbranch
(
OGOTO
);
spc
=
p
;
sbc
=
breakpc
;
breakpc
=
pc
;
snbreak
=
nbreak
;
nbreak
=
0
;
gbranch
(
OGOTO
);
spb
=
p
;
patch
(
spc
,
pc
);
if
(
n
->
op
==
OWHILE
)
patch
(
sp
,
pc
);
bcomplex
(
l
,
Z
);
/* test */
patch
(
p
,
breakpc
);
if
(
l
->
op
!=
OCONST
||
vconst
(
l
)
==
0
)
nbreak
++
;
if
(
n
->
op
==
ODWHILE
)
patch
(
sp
,
pc
);
gen
(
n
->
right
);
/* body */
gbranch
(
OGOTO
);
patch
(
p
,
continpc
);
patch
(
spb
,
pc
);
continpc
=
scc
;
breakpc
=
sbc
;
canreach
=
nbreak
!=
0
;
if
(
canreach
==
0
)
warnreach
=
!
suppress
;
nbreak
=
snbreak
;
break
;
case
OFOR
:
l
=
n
->
left
;
if
(
!
canreach
&&
l
->
right
->
left
&&
warnreach
)
{
warn
(
n
,
"unreachable code FOR"
);
warnreach
=
0
;
}
gen
(
l
->
right
->
left
);
/* init */
gbranch
(
OGOTO
);
/* entry */
sp
=
p
;
/*
* if there are no incoming labels in the
* body and the top's not reachable, warn
*/
if
(
!
canreach
&&
warnreach
&&
deadheads
(
n
))
{
warn
(
n
,
"unreachable code %O"
,
o
);
warnreach
=
0
;
}
scc
=
continpc
;
continpc
=
pc
;
gbranch
(
OGOTO
);
spc
=
p
;
sbc
=
breakpc
;
breakpc
=
pc
;
snbreak
=
nbreak
;
nbreak
=
0
;
sncontin
=
ncontin
;
ncontin
=
0
;
gbranch
(
OGOTO
);
spb
=
p
;
patch
(
spc
,
pc
);
gen
(
l
->
right
->
right
);
/* inc */
patch
(
sp
,
pc
);
if
(
l
->
left
!=
Z
)
{
/* test */
bcomplex
(
l
->
left
,
Z
);
patch
(
p
,
breakpc
);
if
(
l
->
left
->
op
!=
OCONST
||
vconst
(
l
->
left
)
==
0
)
nbreak
++
;
}
canreach
=
1
;
gen
(
n
->
right
);
/* body */
if
(
canreach
){
gbranch
(
OGOTO
);
patch
(
p
,
continpc
);
ncontin
++
;
}
if
(
!
ncontin
&&
l
->
right
->
right
&&
warnreach
)
{
warn
(
l
->
right
->
right
,
"unreachable FOR inc"
);
warnreach
=
0
;
}
patch
(
spb
,
pc
);
continpc
=
scc
;
breakpc
=
sbc
;
canreach
=
nbreak
!=
0
;
if
(
canreach
==
0
)
warnreach
=
!
suppress
;
nbreak
=
snbreak
;
ncontin
=
sncontin
;
break
;
case
OCONTINUE
:
if
(
continpc
<
0
)
{
diag
(
n
,
"continue not in a loop"
);
break
;
}
gbranch
(
OGOTO
);
patch
(
p
,
continpc
);
ncontin
++
;
canreach
=
0
;
warnreach
=
!
suppress
;
break
;
case
OBREAK
:
if
(
breakpc
<
0
)
{
diag
(
n
,
"break not in a loop"
);
break
;
}
/*
* Don't complain about unreachable break statements.
* There are breaks hidden in yacc's output and some people
* write return; break; in their switch statements out of habit.
* However, don't confuse the analysis by inserting an
* unreachable reference to breakpc either.
*/
if
(
!
canreach
)
break
;
gbranch
(
OGOTO
);
patch
(
p
,
breakpc
);
nbreak
++
;
canreach
=
0
;
warnreach
=
!
suppress
;
break
;
case
OIF
:
l
=
n
->
left
;
if
(
bcomplex
(
l
,
n
->
right
))
{
if
(
typefd
[
l
->
type
->
etype
])
f
=
!
l
->
fconst
;
else
f
=
!
l
->
vconst
;
if
(
debug
[
'c'
])
print
(
"%L const if %s
\n
"
,
nearln
,
f
?
"false"
:
"true"
);
if
(
f
)
{
canreach
=
1
;
supgen
(
n
->
right
->
left
);
oldreach
=
canreach
;
canreach
=
1
;
gen
(
n
->
right
->
right
);
/*
* treat constant ifs as regular ifs for
* reachability warnings.
*/
if
(
!
canreach
&&
oldreach
&&
debug
[
'w'
]
<
2
)
warnreach
=
0
;
}
else
{
canreach
=
1
;
gen
(
n
->
right
->
left
);
oldreach
=
canreach
;
canreach
=
1
;
supgen
(
n
->
right
->
right
);
/*
* treat constant ifs as regular ifs for
* reachability warnings.
*/
if
(
!
oldreach
&&
canreach
&&
debug
[
'w'
]
<
2
)
warnreach
=
0
;
canreach
=
oldreach
;
}
}
else
{
sp
=
p
;
canreach
=
1
;
if
(
n
->
right
->
left
!=
Z
)
gen
(
n
->
right
->
left
);
oldreach
=
canreach
;
canreach
=
1
;
if
(
n
->
right
->
right
!=
Z
)
{
gbranch
(
OGOTO
);
patch
(
sp
,
pc
);
sp
=
p
;
gen
(
n
->
right
->
right
);
}
patch
(
sp
,
pc
);
canreach
=
canreach
||
oldreach
;
if
(
canreach
==
0
)
warnreach
=
!
suppress
;
}
break
;
case
OSET
:
case
OUSED
:
usedset
(
n
->
left
,
o
);
break
;
}
}
void
usedset
(
Node
*
n
,
int
o
)
{
if
(
n
->
op
==
OLIST
)
{
usedset
(
n
->
left
,
o
);
usedset
(
n
->
right
,
o
);
return
;
}
complex
(
n
);
switch
(
n
->
op
)
{
case
OADDR
:
/* volatile */
gins
(
ANOP
,
n
,
Z
);
break
;
case
ONAME
:
if
(
o
==
OSET
)
gins
(
ANOP
,
Z
,
n
);
else
gins
(
ANOP
,
n
,
Z
);
break
;
}
}
int
bcomplex
(
Node
*
n
,
Node
*
c
)
{
complex
(
n
);
if
(
n
->
type
!=
T
)
if
(
tcompat
(
n
,
T
,
n
->
type
,
tnot
))
n
->
type
=
T
;
if
(
n
->
type
==
T
)
{
gbranch
(
OGOTO
);
return
0
;
}
if
(
c
!=
Z
&&
n
->
op
==
OCONST
&&
deadheads
(
c
))
return
1
;
bool64
(
n
);
boolgen
(
n
,
1
,
Z
);
return
0
;
}
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