Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
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
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
bac922c6
Commit
bac922c6
authored
Mar 31, 2009
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
move portable code generation (basic statements) to gc.
R=ken OCL=26929 CL=26929
parent
79b55e22
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
624 additions
and
43 deletions
+624
-43
align.c
src/cmd/6g/align.c
+0
-2
gen.c
src/cmd/6g/gen.c
+0
-0
gg.h
src/cmd/6g/gg.h
+0
-25
gsubr.c
src/cmd/6g/gsubr.c
+18
-0
Makefile
src/cmd/gc/Makefile
+1
-0
align.c
src/cmd/gc/align.c
+32
-0
gen.c
src/cmd/gc/gen.c
+505
-0
go.h
src/cmd/gc/go.h
+64
-15
lex.c
src/cmd/gc/lex.c
+4
-1
No files found.
src/cmd/6g/align.c
View file @
bac922c6
...
...
@@ -30,7 +30,5 @@ betypeinit(void)
zprog
.
from
.
scale
=
0
;
zprog
.
to
=
zprog
.
from
;
symstringo
=
lookup
(
".stringo"
);
// strings
listinit
();
}
src/cmd/6g/gen.c
View file @
bac922c6
This diff is collapsed.
Click to expand it.
src/cmd/6g/gg.h
View file @
bac922c6
...
...
@@ -13,7 +13,6 @@
#define EXTERN extern
#endif
typedef
struct
Prog
Prog
;
typedef
struct
Addr
Addr
;
struct
Addr
...
...
@@ -41,7 +40,6 @@ struct Prog
Prog
*
link
;
// next instruction in this func
void
*
reg
;
// pointer to containing Reg struct
};
#define P ((Prog*)0)
typedef
struct
Plist
Plist
;
struct
Plist
...
...
@@ -53,22 +51,6 @@ struct Plist
Plist
*
link
;
};
typedef
struct
Label
Label
;
struct
Label
{
uchar
op
;
// OGOTO/OLABEL
Sym
*
sym
;
Prog
*
label
;
// pointer to code
Prog
*
breakpc
;
// pointer to code
Prog
*
continpc
;
// pointer to code
Label
*
link
;
};
#define L ((Label*)0)
EXTERN
Prog
*
continpc
;
EXTERN
Prog
*
breakpc
;
EXTERN
Prog
*
pc
;
EXTERN
Prog
*
firstpc
;
EXTERN
Plist
*
plist
;
EXTERN
Plist
*
plast
;
EXTERN
Biobuf
*
bout
;
...
...
@@ -79,8 +61,6 @@ EXTERN String emptystring;
extern
char
*
anames
[];
EXTERN
Hist
*
hist
;
EXTERN
Prog
zprog
;
EXTERN
Label
*
labellist
;
EXTERN
Label
*
findlab
(
Sym
*
);
EXTERN
Node
*
curfn
;
EXTERN
Node
*
newproc
;
EXTERN
Node
*
deferproc
;
...
...
@@ -96,9 +76,6 @@ void proglist(void);
void
gen
(
Node
*
);
Node
*
lookdot
(
Node
*
,
Node
*
,
int
);
void
cgen_as
(
Node
*
,
Node
*
);
void
cgen_asop
(
Node
*
);
void
cgen_ret
(
Node
*
);
void
cgen_call
(
Node
*
,
int
);
void
cgen_callmeth
(
Node
*
,
int
);
void
cgen_callinter
(
Node
*
,
Node
*
,
int
);
void
cgen_proc
(
Node
*
,
int
);
...
...
@@ -116,7 +93,6 @@ void ginscall(Node*, int);
/*
* cgen
*/
void
cgen
(
Node
*
,
Node
*
);
void
agen
(
Node
*
,
Node
*
);
void
igen
(
Node
*
,
Node
*
,
Node
*
);
vlong
fieldoffset
(
Type
*
,
Node
*
);
...
...
@@ -134,7 +110,6 @@ void cgen_aret(Node*, Node*);
void
clearp
(
Prog
*
);
void
proglist
(
void
);
Prog
*
gbranch
(
int
,
Type
*
);
void
patch
(
Prog
*
,
Prog
*
);
Prog
*
prog
(
int
);
void
gaddoffset
(
Node
*
);
void
gconv
(
int
,
int
);
...
...
src/cmd/6g/gsubr.c
View file @
bac922c6
...
...
@@ -1927,3 +1927,21 @@ no:
sudoclean
();
return
0
;
}
void
gused
(
Node
*
n
)
{
gins
(
ANOP
,
n
,
N
);
// used
}
Prog
*
gjmp
(
Prog
*
to
)
{
Prog
*
p
;
p
=
gbranch
(
AJMP
,
T
);
if
(
to
!=
P
)
patch
(
p
,
to
);
return
p
;
}
src/cmd/gc/Makefile
View file @
bac922c6
...
...
@@ -30,6 +30,7 @@ OFILES=\
compat.
$O
\
bits.
$O
\
align.
$O
\
gen.
$O
\
$(LIB)
:
$(OFILES)
ar rsc
$(LIB)
$(OFILES)
...
...
src/cmd/gc/align.c
View file @
bac922c6
...
...
@@ -349,3 +349,35 @@ typeinit(int lex)
Array_cap
=
rnd
(
Array_nel
+
types
[
TUINT32
]
->
width
,
types
[
TUINT32
]
->
width
);
sizeof_Array
=
rnd
(
Array_cap
+
types
[
TUINT32
]
->
width
,
maxround
);
}
/*
* compute total size of f's in/out arguments.
*/
int
argsize
(
Type
*
t
)
{
Iter
save
;
Type
*
fp
;
int
w
,
x
;
w
=
0
;
fp
=
structfirst
(
&
save
,
getoutarg
(
t
));
while
(
fp
!=
T
)
{
x
=
fp
->
width
+
fp
->
type
->
width
;
if
(
x
>
w
)
w
=
x
;
fp
=
structnext
(
&
save
);
}
fp
=
funcfirst
(
&
save
,
t
);
while
(
fp
!=
T
)
{
x
=
fp
->
width
+
fp
->
type
->
width
;
if
(
x
>
w
)
w
=
x
;
fp
=
funcnext
(
&
save
);
}
w
=
(
w
+
7
)
&
~
7
;
return
w
;
}
src/cmd/gc/gen.c
0 → 100644
View file @
bac922c6
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
* portable half of code generator.
* mainly statements and control flow.
*/
#include "go.h"
Node
*
sysfunc
(
char
*
name
)
{
Node
*
n
;
n
=
newname
(
pkglookup
(
name
,
"sys"
));
n
->
class
=
PFUNC
;
return
n
;
}
void
allocparams
(
void
)
{
Dcl
*
d
;
Node
*
n
;
uint32
w
;
/*
* allocate (set xoffset) the stack
* slots for all automatics.
* allocated starting at -w down.
*/
for
(
d
=
autodcl
;
d
!=
D
;
d
=
d
->
forw
)
{
if
(
d
->
op
!=
ONAME
)
continue
;
n
=
d
->
dnode
;
if
(
n
->
class
!=
PAUTO
)
continue
;
dowidth
(
n
->
type
);
w
=
n
->
type
->
width
;
if
(
n
->
class
&
PHEAP
)
w
=
widthptr
;
stksize
+=
w
;
stksize
=
rnd
(
stksize
,
w
);
n
->
xoffset
=
-
stksize
;
}
}
void
newlab
(
int
op
,
Sym
*
s
)
{
Label
*
lab
;
lab
=
mal
(
sizeof
(
*
lab
));
lab
->
link
=
labellist
;
labellist
=
lab
;
lab
->
sym
=
s
;
lab
->
op
=
op
;
lab
->
label
=
pc
;
}
void
checklabels
(
void
)
{
Label
*
l
,
*
m
;
Sym
*
s
;
// // print the label list
// for(l=labellist; l!=L; l=l->link) {
// print("lab %O %S\n", l->op, l->sym);
// }
for
(
l
=
labellist
;
l
!=
L
;
l
=
l
->
link
)
{
switch
(
l
->
op
)
{
case
OFOR
:
case
OLABEL
:
// these are definitions -
s
=
l
->
sym
;
for
(
m
=
labellist
;
m
!=
L
;
m
=
m
->
link
)
{
if
(
m
->
sym
!=
s
)
continue
;
switch
(
m
->
op
)
{
case
OFOR
:
case
OLABEL
:
// these are definitions -
// look for redefinitions
if
(
l
!=
m
)
yyerror
(
"label %S redefined"
,
s
);
break
;
case
OGOTO
:
// these are references -
// patch to definition
patch
(
m
->
label
,
l
->
label
);
m
->
sym
=
S
;
// mark done
break
;
}
}
}
}
// diagnostic for all undefined references
for
(
l
=
labellist
;
l
!=
L
;
l
=
l
->
link
)
if
(
l
->
op
==
OGOTO
&&
l
->
sym
!=
S
)
yyerror
(
"label %S not defined"
,
l
->
sym
);
}
Label
*
findlab
(
Sym
*
s
)
{
Label
*
l
;
for
(
l
=
labellist
;
l
!=
L
;
l
=
l
->
link
)
{
if
(
l
->
sym
!=
s
)
continue
;
if
(
l
->
op
!=
OFOR
)
continue
;
return
l
;
}
return
L
;
}
/*
* compile statements
*/
void
gen
(
Node
*
n
)
{
int32
lno
;
Prog
*
scontin
,
*
sbreak
;
Prog
*
p1
,
*
p2
,
*
p3
;
Label
*
lab
;
lno
=
setlineno
(
n
);
loop:
if
(
n
==
N
)
goto
ret
;
p3
=
pc
;
// save pc for loop labels
if
(
n
->
ninit
)
gen
(
n
->
ninit
);
setlineno
(
n
);
switch
(
n
->
op
)
{
default:
fatal
(
"gen: unknown op %N"
,
n
);
break
;
case
OLIST
:
gen
(
n
->
left
);
n
=
n
->
right
;
goto
loop
;
case
OCASE
:
case
OFALL
:
case
OXCASE
:
case
OXFALL
:
case
OEMPTY
:
break
;
case
OLABEL
:
newlab
(
OLABEL
,
n
->
left
->
sym
);
break
;
case
OGOTO
:
newlab
(
OGOTO
,
n
->
left
->
sym
);
gjmp
(
P
);
break
;
case
OBREAK
:
if
(
n
->
left
!=
N
)
{
for
(
lab
=
labellist
;
lab
!=
L
;
lab
=
lab
->
link
)
{
if
(
lab
->
breakpc
!=
P
)
{
gjmp
(
lab
->
breakpc
);
break
;
}
}
if
(
lab
==
L
)
yyerror
(
"break label not defined: %S"
,
n
->
left
->
sym
);
break
;
}
if
(
breakpc
==
P
)
{
yyerror
(
"break is not in a loop"
);
break
;
}
gjmp
(
breakpc
);
break
;
case
OCONTINUE
:
if
(
n
->
left
!=
N
)
{
for
(
lab
=
labellist
;
lab
!=
L
;
lab
=
lab
->
link
)
{
if
(
lab
->
continpc
!=
P
)
{
gjmp
(
lab
->
continpc
);
break
;
}
}
if
(
lab
==
L
)
yyerror
(
"break label not defined: %S"
,
n
->
left
->
sym
);
break
;
}
if
(
continpc
==
P
)
{
yyerror
(
"gen: continue is not in a loop"
);
break
;
}
gjmp
(
continpc
);
break
;
case
OFOR
:
sbreak
=
breakpc
;
p1
=
gjmp
(
P
);
// goto test
breakpc
=
gjmp
(
P
);
// break: goto done
scontin
=
continpc
;
continpc
=
pc
;
// define break and cotinue labels
for
(
lab
=
labellist
;
lab
!=
L
;
lab
=
lab
->
link
)
{
if
(
lab
->
label
!=
p3
)
break
;
if
(
lab
->
op
==
OLABEL
)
{
lab
->
breakpc
=
breakpc
;
lab
->
continpc
=
continpc
;
}
}
gen
(
n
->
nincr
);
// contin: incr
patch
(
p1
,
pc
);
// test:
if
(
n
->
ntest
!=
N
)
if
(
n
->
ntest
->
ninit
!=
N
)
gen
(
n
->
ntest
->
ninit
);
bgen
(
n
->
ntest
,
0
,
breakpc
);
// if(!test) goto break
gen
(
n
->
nbody
);
// body
gjmp
(
continpc
);
patch
(
breakpc
,
pc
);
// done:
continpc
=
scontin
;
breakpc
=
sbreak
;
break
;
case
OIF
:
p1
=
gjmp
(
P
);
// goto test
p2
=
gjmp
(
P
);
// p2: goto else
patch
(
p1
,
pc
);
// test:
if
(
n
->
ntest
!=
N
)
if
(
n
->
ntest
->
ninit
!=
N
)
gen
(
n
->
ntest
->
ninit
);
bgen
(
n
->
ntest
,
0
,
p2
);
// if(!test) goto p2
gen
(
n
->
nbody
);
// then
p3
=
gjmp
(
P
);
// goto done
patch
(
p2
,
pc
);
// else:
gen
(
n
->
nelse
);
// else
patch
(
p3
,
pc
);
// done:
break
;
case
OSWITCH
:
sbreak
=
breakpc
;
p1
=
gjmp
(
P
);
// goto test
breakpc
=
gjmp
(
P
);
// break: goto done
// define break label
for
(
lab
=
labellist
;
lab
!=
L
;
lab
=
lab
->
link
)
{
if
(
lab
->
label
!=
p3
)
break
;
if
(
lab
->
op
==
OLABEL
)
{
lab
->
breakpc
=
breakpc
;
}
}
patch
(
p1
,
pc
);
// test:
gen
(
n
->
nbody
);
// switch(test) body
patch
(
breakpc
,
pc
);
// done:
breakpc
=
sbreak
;
break
;
case
OSELECT
:
sbreak
=
breakpc
;
p1
=
gjmp
(
P
);
// goto test
breakpc
=
gjmp
(
P
);
// break: goto done
// define break label
for
(
lab
=
labellist
;
lab
!=
L
;
lab
=
lab
->
link
)
{
if
(
lab
->
label
!=
p3
)
break
;
if
(
lab
->
op
==
OLABEL
)
{
lab
->
breakpc
=
breakpc
;
}
}
patch
(
p1
,
pc
);
// test:
gen
(
n
->
nbody
);
// select() body
patch
(
breakpc
,
pc
);
// done:
breakpc
=
sbreak
;
break
;
case
OASOP
:
cgen_asop
(
n
);
break
;
case
ODCL
:
cgen_dcl
(
n
->
left
);
break
;
case
OAS
:
cgen_as
(
n
->
left
,
n
->
right
);
break
;
case
OCALLMETH
:
cgen_callmeth
(
n
,
0
);
break
;
case
OCALLINTER
:
cgen_callinter
(
n
,
N
,
0
);
break
;
case
OCALL
:
cgen_call
(
n
,
0
);
break
;
case
OPROC
:
cgen_proc
(
n
,
1
);
break
;
case
ODEFER
:
cgen_proc
(
n
,
2
);
break
;
case
ORETURN
:
cgen_ret
(
n
);
break
;
}
ret:
lineno
=
lno
;
}
/*
* generate call to non-interface method
* proc=0 normal call
* proc=1 goroutine run in new proc
* proc=2 defer call save away stack
*/
void
cgen_callmeth
(
Node
*
n
,
int
proc
)
{
Node
*
l
;
// generate a rewrite for method call
// (p.f)(...) goes to (f)(p,...)
l
=
n
->
left
;
if
(
l
->
op
!=
ODOTMETH
)
fatal
(
"cgen_callmeth: not dotmethod: %N"
);
n
->
op
=
OCALL
;
n
->
left
=
n
->
left
->
right
;
n
->
left
->
type
=
l
->
type
;
if
(
n
->
left
->
op
==
ONAME
)
n
->
left
->
class
=
PFUNC
;
cgen_call
(
n
,
proc
);
}
/*
* generate code to start new proc running call n.
*/
void
cgen_proc
(
Node
*
n
,
int
proc
)
{
switch
(
n
->
left
->
op
)
{
default:
fatal
(
"cgen_proc: unknown call %O"
,
n
->
left
->
op
);
case
OCALLMETH
:
cgen_callmeth
(
n
->
left
,
proc
);
break
;
case
OCALLINTER
:
cgen_callinter
(
n
->
left
,
N
,
proc
);
break
;
case
OCALL
:
cgen_call
(
n
->
left
,
proc
);
break
;
}
}
/*
* generate declaration.
* nothing to do for on-stack automatics,
* but might have to allocate heap copy
* for escaped variables.
*/
void
cgen_dcl
(
Node
*
n
)
{
if
(
debug
[
'g'
])
dump
(
"
\n
cgen-dcl"
,
n
);
if
(
n
->
op
!=
ONAME
)
{
dump
(
"cgen_dcl"
,
n
);
fatal
(
"cgen_dcl"
);
}
if
(
!
(
n
->
class
&
PHEAP
))
return
;
cgen_as
(
n
->
heapaddr
,
n
->
alloc
);
}
/*
* generate assignment:
* nl = nr
* nr == N means zero nl.
*/
void
cgen_as
(
Node
*
nl
,
Node
*
nr
)
{
Node
nc
;
Type
*
tl
;
int
iszer
;
if
(
nl
==
N
)
return
;
if
(
debug
[
'g'
])
{
dump
(
"cgen_as"
,
nl
);
dump
(
"cgen_as = "
,
nr
);
}
iszer
=
0
;
if
(
nr
==
N
||
isnil
(
nr
))
{
if
(
nl
->
op
==
OLIST
)
{
cgen_as
(
nl
->
left
,
nr
);
cgen_as
(
nl
->
right
,
nr
);
return
;
}
tl
=
nl
->
type
;
if
(
tl
==
T
)
return
;
if
(
isfat
(
tl
))
{
clearfat
(
nl
);
goto
ret
;
}
/* invent a "zero" for the rhs */
iszer
=
1
;
nr
=
&
nc
;
memset
(
nr
,
0
,
sizeof
(
*
nr
));
switch
(
simtype
[
tl
->
etype
])
{
default:
fatal
(
"cgen_as: tl %T"
,
tl
);
break
;
case
TINT8
:
case
TUINT8
:
case
TINT16
:
case
TUINT16
:
case
TINT32
:
case
TUINT32
:
case
TINT64
:
case
TUINT64
:
nr
->
val
.
u
.
xval
=
mal
(
sizeof
(
*
nr
->
val
.
u
.
xval
));
mpmovecfix
(
nr
->
val
.
u
.
xval
,
0
);
nr
->
val
.
ctype
=
CTINT
;
break
;
case
TFLOAT32
:
case
TFLOAT64
:
case
TFLOAT80
:
nr
->
val
.
u
.
fval
=
mal
(
sizeof
(
*
nr
->
val
.
u
.
fval
));
mpmovecflt
(
nr
->
val
.
u
.
fval
,
0
.
0
);
nr
->
val
.
ctype
=
CTFLT
;
break
;
case
TBOOL
:
nr
->
val
.
u
.
bval
=
0
;
nr
->
val
.
ctype
=
CTBOOL
;
break
;
case
TPTR32
:
case
TPTR64
:
nr
->
val
.
ctype
=
CTNIL
;
break
;
}
nr
->
op
=
OLITERAL
;
nr
->
type
=
tl
;
nr
->
addable
=
1
;
ullmancalc
(
nr
);
}
tl
=
nl
->
type
;
if
(
tl
==
T
)
return
;
cgen
(
nr
,
nl
);
if
(
iszer
&&
nl
->
addable
)
gused
(
nl
);
ret:
;
}
src/cmd/gc/go.h
View file @
bac922c6
...
...
@@ -937,26 +937,12 @@ int smallintconst(Node*);
int
consttype
(
Node
*
);
int
isconst
(
Node
*
,
int
);
/*
* gen.c/gsubr.c/obj.c
*/
void
betypeinit
(
void
);
vlong
convvtox
(
vlong
,
int
);
void
compile
(
Node
*
);
void
proglist
(
void
);
int
optopop
(
int
);
void
dumpobj
(
void
);
void
dowidth
(
Type
*
);
void
argspace
(
int32
);
Node
*
nodarg
(
Type
*
,
int
);
Type
*
deep
(
Type
*
);
Type
*
shallow
(
Type
*
);
/*
* align.c
*/
uint32
rnd
(
uint32
,
uint32
);
void
dowidth
(
Type
*
);
int
argsize
(
Type
*
);
/*
* bits.c
...
...
@@ -972,3 +958,66 @@ int bset(Bits, uint);
int
Qconv
(
Fmt
*
fp
);
int
bitno
(
int32
);
/*
* gen.c
*/
typedef
struct
Prog
Prog
;
#define P ((Prog*)0)
typedef
struct
Label
Label
;
struct
Label
{
uchar
op
;
// OGOTO/OLABEL
Sym
*
sym
;
Prog
*
label
;
// pointer to code
Prog
*
breakpc
;
// pointer to code
Prog
*
continpc
;
// pointer to code
Label
*
link
;
};
#define L ((Label*)0)
EXTERN
Label
*
labellist
;
EXTERN
Label
*
findlab
(
Sym
*
);
EXTERN
Prog
*
continpc
;
EXTERN
Prog
*
breakpc
;
EXTERN
Prog
*
pc
;
EXTERN
Prog
*
firstpc
;
void
allocparams
(
void
);
void
cgen_as
(
Node
*
nl
,
Node
*
nr
);
void
cgen_callmeth
(
Node
*
n
,
int
proc
);
void
cgen_dcl
(
Node
*
n
);
void
cgen_proc
(
Node
*
n
,
int
proc
);
void
checklabels
(
void
);
Label
*
findlab
(
Sym
*
s
);
void
gen
(
Node
*
n
);
void
newlab
(
int
op
,
Sym
*
s
);
Node
*
sysfunc
(
char
*
name
);
/*
* gen.c/gsubr.c/obj.c
*/
void
betypeinit
(
void
);
vlong
convvtox
(
vlong
,
int
);
void
compile
(
Node
*
);
void
proglist
(
void
);
int
optopop
(
int
);
void
dumpobj
(
void
);
void
dowidth
(
Type
*
);
void
argspace
(
int32
);
Node
*
nodarg
(
Type
*
,
int
);
Type
*
deep
(
Type
*
);
Type
*
shallow
(
Type
*
);
Prog
*
gjmp
(
Prog
*
);
void
patch
(
Prog
*
,
Prog
*
);
void
bgen
(
Node
*
n
,
int
true
,
Prog
*
to
);
void
cgen_asop
(
Node
*
n
);
void
cgen_call
(
Node
*
n
,
int
proc
);
void
cgen_callinter
(
Node
*
n
,
Node
*
res
,
int
proc
);
void
cgen_ret
(
Node
*
n
);
int
isfat
(
Type
*
);
void
clearfat
(
Node
*
n
);
void
cgen
(
Node
*
,
Node
*
);
void
gused
(
Node
*
);
src/cmd/gc/lex.c
View file @
bac922c6
...
...
@@ -66,6 +66,8 @@ main(int argc, char *argv[])
lexinit
();
typeinit
(
LBASETYPE
);
symstringo
=
lookup
(
".stringo"
);
// strings
lineno
=
1
;
block
=
1
;
blockgen
=
1
;
...
...
@@ -336,7 +338,8 @@ cannedimports(char *file, char *cp)
}
int
isfrog
(
int
c
)
{
isfrog
(
int
c
)
{
// complain about possibly invisible control characters
if
(
c
<
0
)
return
1
;
...
...
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