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
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
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
160 additions
and
6 deletions
+160
-6
amd64.S
src/libcgo/amd64.S
+36
-0
darwin_amd64.c
src/libcgo/darwin_amd64.c
+32
-0
freebsd_amd64.c
src/libcgo/freebsd_amd64.c
+25
-0
linux_amd64.c
src/libcgo/linux_amd64.c
+25
-0
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):
...
@@ -43,3 +43,39 @@ EXT(crosscall_amd64):
popq %rbp
popq %rbp
popq %rbx
popq %rbx
ret
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 @@
...
@@ -7,9 +7,19 @@
static
void
*
threadentry
(
void
*
);
static
void
*
threadentry
(
void
*
);
static
pthread_key_t
km
,
kg
;
void
void
initcgo
(
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
void
...
@@ -44,3 +54,25 @@ threadentry(void *v)
...
@@ -44,3 +54,25 @@ threadentry(void *v)
crosscall_amd64
(
ts
.
m
,
ts
.
g
,
ts
.
fn
);
crosscall_amd64
(
ts
.
m
,
ts
.
g
,
ts
.
fn
);
return
nil
;
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)
...
@@ -47,3 +47,28 @@ threadentry(void *v)
crosscall_amd64
(
ts
.
m
,
ts
.
g
,
ts
.
fn
);
crosscall_amd64
(
ts
.
m
,
ts
.
g
,
ts
.
fn
);
return
nil
;
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)
...
@@ -44,3 +44,28 @@ threadentry(void *v)
crosscall_amd64
(
ts
.
m
,
ts
.
g
,
ts
.
fn
);
crosscall_amd64
(
ts
.
m
,
ts
.
g
,
ts
.
fn
);
return
nil
;
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
...
@@ -276,14 +276,13 @@ TEXT jmpdefer(SB), 7, $0
// Save g and m across the call,
// Save g and m across the call,
// since the foreign code might reuse them.
// since the foreign code might reuse them.
TEXT runcgo(SB),7,$32
TEXT runcgo(SB),7,$32
// Save old registers.
MOVQ fn+0(FP), R12
MOVQ fn+0(FP),AX
MOVQ arg+8(FP), R13
MOVQ arg+8(FP),DI // DI = first argument in AMD64 ABI
MOVQ SP, CX
MOVQ SP, CX
// Figure out if we need to switch to m->g0 stack.
// Figure out if we need to switch to m->g0 stack.
MOVQ m_g0(m),
R8
MOVQ m_g0(m),
SI
CMPQ
R8
, g
CMPQ
SI
, g
JEQ 2(PC)
JEQ 2(PC)
MOVQ (m_sched+gobuf_sp)(m), SP
MOVQ (m_sched+gobuf_sp)(m), SP
...
@@ -293,7 +292,17 @@ TEXT runcgo(SB),7,$32
...
@@ -293,7 +292,17 @@ TEXT runcgo(SB),7,$32
MOVQ g, 24(SP) // save old g, m, SP
MOVQ g, 24(SP) // save old g, m, SP
MOVQ m, 16(SP)
MOVQ m, 16(SP)
MOVQ CX, 8(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.
// Restore registers, stack pointer.
MOVQ 16(SP), m
MOVQ 16(SP), m
...
@@ -301,6 +310,32 @@ TEXT runcgo(SB),7,$32
...
@@ -301,6 +310,32 @@ TEXT runcgo(SB),7,$32
MOVQ 8(SP), SP
MOVQ 8(SP), SP
RET
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)
// check that SP is in range [g->stackbase, g->stackguard)
TEXT stackcheck(SB), 7, $0
TEXT stackcheck(SB), 7, $0
CMPQ g_stackbase(g), SP
CMPQ g_stackbase(g), SP
...
@@ -337,3 +372,4 @@ TEXT getcallersp(SB),7,$0
...
@@ -337,3 +372,4 @@ TEXT getcallersp(SB),7,$0
MOVQ sp+0(FP), AX
MOVQ sp+0(FP), AX
RET
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