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
2d0ff3f1
Commit
2d0ff3f1
authored
Apr 09, 2010
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support cgo export on amd64.
R=rsc CC=golang-dev
https://golang.org/cl/857045
parent
bc2d977d
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
160 additions
and
6 deletions
+160
-6
src/libcgo/amd64.S
src/libcgo/amd64.S
+36
-0
src/libcgo/darwin_amd64.c
src/libcgo/darwin_amd64.c
+32
-0
src/libcgo/freebsd_amd64.c
src/libcgo/freebsd_amd64.c
+25
-0
src/libcgo/linux_amd64.c
src/libcgo/linux_amd64.c
+25
-0
src/pkg/runtime/amd64/asm.s
src/pkg/runtime/amd64/asm.s
+42
-6
No files found.
src/libcgo/amd64.S
View file @
2d0ff3f1
...
...
@@ -43,3 +43,39 @@ EXT(crosscall_amd64):
popq
%
rbp
popq
%
rbx
ret
/*
*
void
crosscall2
(
void
(*
fn
)(
void
*,
int32
),
void
*
arg
,
int32
argsize
)
*
*
Save
registers
and
call
fn
with
two
arguments
.
fn
is
a
Go
function
*
which
takes
parameters
on
the
stack
rather
than
in
registers
.
*/
.
globl
EXT
(
crosscall2
)
EXT
(
crosscall2
):
subq
$
0x58
,
%
rsp
/*
keeps
stack
pointer
32
-
byte
aligned
*/
movq
%
rbx
,
0x10
(%
rsp
)
movq
%
rbp
,
0x18
(%
rsp
)
movq
%
r12
,
0x20
(%
rsp
)
movq
%
r13
,
0x28
(%
rsp
)
movq
%
r14
,
0x30
(%
rsp
)
movq
%
r15
,
0x38
(%
rsp
)
movq
%
rdi
,
%
r12
/*
fn
*/
movq
%
rsi
,
0
(%
rsp
)
/*
arg
*/
movq
%
rdx
,
8
(%
rsp
)
/*
argsize
(
includes
padding
)
*/
leaq
0x40
(%
rsp
),
%
rdi
call
EXT
(
libcgo_get_scheduler
)
movq
0x40
(%
rsp
),
%
r14
/*
m
*/
movq
0x48
(%
rsp
),
%
r15
/*
g
*/
call
*%
r12
movq
0x10
(%
rsp
),
%
rbx
movq
0x18
(%
rsp
),
%
rbp
movq
0x20
(%
rsp
),
%
r12
movq
0x28
(%
rsp
),
%
r13
movq
0x30
(%
rsp
),
%
r14
movq
0x38
(%
rsp
),
%
r15
addq
$
0x58
,
%
rsp
ret
src/libcgo/darwin_amd64.c
View file @
2d0ff3f1
...
...
@@ -7,9 +7,19 @@
static
void
*
threadentry
(
void
*
);
static
pthread_key_t
km
,
kg
;
void
initcgo
(
void
)
{
if
(
pthread_key_create
(
&
km
,
nil
)
<
0
)
{
fprintf
(
stderr
,
"libcgo: pthread_key_create failed
\n
"
);
abort
();
}
if
(
pthread_key_create
(
&
kg
,
nil
)
<
0
)
{
fprintf
(
stderr
,
"libcgo: pthread_key_create failed
\n
"
);
abort
();
}
}
void
...
...
@@ -44,3 +54,25 @@ threadentry(void *v)
crosscall_amd64
(
ts
.
m
,
ts
.
g
,
ts
.
fn
);
return
nil
;
}
void
libcgo_set_scheduler
(
void
*
m
,
void
*
g
)
{
pthread_setspecific
(
km
,
m
);
pthread_setspecific
(
kg
,
g
);
}
struct
get_scheduler_args
{
void
*
m
;
void
*
g
;
};
void
libcgo_get_scheduler
(
struct
get_scheduler_args
*
)
__attribute__
((
visibility
(
"hidden"
)));
void
libcgo_get_scheduler
(
struct
get_scheduler_args
*
p
)
{
p
->
m
=
pthread_getspecific
(
km
);
p
->
g
=
pthread_getspecific
(
kg
);
}
src/libcgo/freebsd_amd64.c
View file @
2d0ff3f1
...
...
@@ -47,3 +47,28 @@ threadentry(void *v)
crosscall_amd64
(
ts
.
m
,
ts
.
g
,
ts
.
fn
);
return
nil
;
}
static
__thread
void
*
libcgo_m
;
static
__thread
void
*
libcgo_g
;
void
libcgo_set_scheduler
(
void
*
m
,
void
*
g
)
{
libcgo_m
=
m
;
libcgo_g
=
g
;
}
struct
get_scheduler_args
{
void
*
m
;
void
*
g
;
};
void
libcgo_get_scheduler
(
struct
get_scheduler_args
*
)
__attribute__
((
visibility
(
"hidden"
)));
void
libcgo_get_scheduler
(
struct
get_scheduler_args
*
p
)
{
p
->
m
=
libcgo_m
;
p
->
g
=
libcgo_g
;
}
src/libcgo/linux_amd64.c
View file @
2d0ff3f1
...
...
@@ -44,3 +44,28 @@ threadentry(void *v)
crosscall_amd64
(
ts
.
m
,
ts
.
g
,
ts
.
fn
);
return
nil
;
}
static
__thread
void
*
libcgo_m
;
static
__thread
void
*
libcgo_g
;
void
libcgo_set_scheduler
(
void
*
m
,
void
*
g
)
{
libcgo_m
=
m
;
libcgo_g
=
g
;
}
struct
get_scheduler_args
{
void
*
m
;
void
*
g
;
};
void
libcgo_get_scheduler
(
struct
get_scheduler_args
*
)
__attribute__
((
visibility
(
"hidden"
)));
void
libcgo_get_scheduler
(
struct
get_scheduler_args
*
p
)
{
p
->
m
=
libcgo_m
;
p
->
g
=
libcgo_g
;
}
src/pkg/runtime/amd64/asm.s
View file @
2d0ff3f1
...
...
@@ -276,14 +276,13 @@ TEXT jmpdefer(SB), 7, $0
//
Save
g
and
m
across
the
call
,
//
since
the
foreign
code
might
reuse
them
.
TEXT
runcgo
(
SB
),7,$32
//
Save
old
registers
.
MOVQ
fn
+
0
(
FP
),
AX
MOVQ
arg
+
8
(
FP
),
DI
//
DI
=
first
argument
in
AMD64
ABI
MOVQ
fn
+
0
(
FP
),
R12
MOVQ
arg
+
8
(
FP
),
R13
MOVQ
SP
,
CX
//
Figure
out
if
we
need
to
switch
to
m
->
g0
stack
.
MOVQ
m_g0
(
m
),
R8
CMPQ
R8
,
g
MOVQ
m_g0
(
m
),
SI
CMPQ
SI
,
g
JEQ
2
(
PC
)
MOVQ
(
m_sched
+
gobuf_sp
)(
m
),
SP
...
...
@@ -293,7 +292,17 @@ TEXT runcgo(SB),7,$32
MOVQ
g
,
24
(
SP
)
//
save
old
g
,
m
,
SP
MOVQ
m
,
16
(
SP
)
MOVQ
CX
,
8
(
SP
)
CALL
AX
//
Save
g
and
m
values
for
a
potential
callback
.
The
callback
//
will
start
running
with
on
the
g0
stack
and
as
such
should
//
have
g
set
to
m
->
g0
.
MOVQ
m
,
DI
//
DI
=
first
argument
in
AMD64
ABI
//
SI
,
second
argument
,
set
above
MOVQ
libcgo_set_scheduler
(
SB
),
BX
CALL
BX
MOVQ
R13
,
DI
//
DI
=
first
argument
in
AMD64
ABI
CALL
R12
//
Restore
registers
,
stack
pointer
.
MOVQ
16
(
SP
),
m
...
...
@@ -301,6 +310,32 @@ TEXT runcgo(SB),7,$32
MOVQ
8
(
SP
),
SP
RET
//
runcgocallback
(
G
*
g1
,
void
*
sp
,
void
(*
fn
)(
void
))
//
Switch
to
g1
and
sp
,
call
fn
,
switch
back
.
fn
's arguments are on
//
the
new
stack
.
TEXT
runcgocallback
(
SB
),7,$48
MOVQ
g1
+
0
(
FP
),
DX
MOVQ
sp
+
8
(
FP
),
AX
MOVQ
fp
+
16
(
FP
),
BX
MOVQ
DX
,
g
//
We
are
running
on
m
's scheduler stack. Save current SP
//
into
m
->
sched
.
sp
so
that
a
recursive
call
to
runcgo
doesn
't
//
clobber
our
stack
,
and
also
so
that
we
can
restore
//
the
SP
when
the
call
finishes
.
Reusing
m
->
sched
.
sp
//
for
this
purpose
depends
on
the
fact
that
there
is
only
//
one
possible
gosave
of
m
->
sched
.
MOVQ
SP
,
(
m_sched
+
gobuf_sp
)(
m
)
//
Set
new
SP
,
call
fn
MOVQ
AX
,
SP
CALL
BX
//
Restore
old
SP
,
return
MOVQ
(
m_sched
+
gobuf_sp
)(
m
),
SP
RET
//
check
that
SP
is
in
range
[
g
->
stackbase
,
g
->
stackguard
)
TEXT
stackcheck
(
SB
),
7
,
$
0
CMPQ
g_stackbase
(
g
),
SP
...
...
@@ -337,3 +372,4 @@ TEXT getcallersp(SB),7,$0
MOVQ
sp
+
0
(
FP
),
AX
RET
GLOBL
libcgo_set_scheduler
(
SB
),
$
8
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