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
a84dbde7
Commit
a84dbde7
authored
Sep 27, 2013
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
reflect: Implement MakeFunc for 386.
From-SVN: r202993
parent
ea89b248
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
264 additions
and
5 deletions
+264
-5
libgo/Makefile.am
+7
-0
libgo/Makefile.in
+9
-3
libgo/go/reflect/all_test.go
+1
-1
libgo/go/reflect/makefunc.go
+1
-1
libgo/go/reflect/makefunc_386.S
+111
-0
libgo/go/reflect/makefuncgo_386.go
+135
-0
No files found.
libgo/Makefile.am
View file @
a84dbde7
...
@@ -901,10 +901,17 @@ go_reflect_makefunc_file = \
...
@@ -901,10 +901,17 @@ go_reflect_makefunc_file = \
go_reflect_makefunc_s_file
=
\
go_reflect_makefunc_s_file
=
\
go/reflect/makefunc_amd64.S
go/reflect/makefunc_amd64.S
else
else
if
LIBGO_IS_386
go_reflect_makefunc_file
=
\
go/reflect/makefuncgo_386.go
go_reflect_makefunc_s_file
=
\
go/reflect/makefunc_386.S
else
go_reflect_makefunc_file
=
go_reflect_makefunc_file
=
go_reflect_makefunc_s_file
=
\
go_reflect_makefunc_s_file
=
\
go/reflect/makefunc_dummy.c
go/reflect/makefunc_dummy.c
endif
endif
endif
go_reflect_files
=
\
go_reflect_files
=
\
go/reflect/deepequal.go
\
go/reflect/deepequal.go
\
...
...
libgo/Makefile.in
View file @
a84dbde7
...
@@ -1087,12 +1087,18 @@ go_path_files = \
...
@@ -1087,12 +1087,18 @@ go_path_files = \
go/path/match.go
\
go/path/match.go
\
go/path/path.go
go/path/path.go
@LIBGO_IS_X86_64_FALSE@
go_reflect_makefunc_file
=
@LIBGO_IS_386_FALSE@@LIBGO_IS_X86_64_FALSE@
go_reflect_makefunc_file
=
@LIBGO_IS_386_TRUE@@LIBGO_IS_X86_64_FALSE@
go_reflect_makefunc_file
=
\
@LIBGO_IS_386_TRUE@@LIBGO_IS_X86_64_FALSE@ go/reflect/makefuncgo_386.go
@LIBGO_IS_X86_64_TRUE@
go_reflect_makefunc_file
=
\
@LIBGO_IS_X86_64_TRUE@
go_reflect_makefunc_file
=
\
@LIBGO_IS_X86_64_TRUE@ go/reflect/makefuncgo_amd64.go
@LIBGO_IS_X86_64_TRUE@ go/reflect/makefuncgo_amd64.go
@LIBGO_IS_X86_64_FALSE@
go_reflect_makefunc_s_file
=
\
@LIBGO_IS_386_FALSE@@LIBGO_IS_X86_64_FALSE@
go_reflect_makefunc_s_file
=
\
@LIBGO_IS_X86_64_FALSE@ go/reflect/makefunc_dummy.c
@LIBGO_IS_386_FALSE@@LIBGO_IS_X86_64_FALSE@ go/reflect/makefunc_dummy.c
@LIBGO_IS_386_TRUE@@LIBGO_IS_X86_64_FALSE@
go_reflect_makefunc_s_file
=
\
@LIBGO_IS_386_TRUE@@LIBGO_IS_X86_64_FALSE@ go/reflect/makefunc_386.S
@LIBGO_IS_X86_64_TRUE@
go_reflect_makefunc_s_file
=
\
@LIBGO_IS_X86_64_TRUE@
go_reflect_makefunc_s_file
=
\
@LIBGO_IS_X86_64_TRUE@ go/reflect/makefunc_amd64.S
@LIBGO_IS_X86_64_TRUE@ go/reflect/makefunc_amd64.S
...
...
libgo/go/reflect/all_test.go
View file @
a84dbde7
...
@@ -1432,7 +1432,7 @@ func TestFunc(t *testing.T) {
...
@@ -1432,7 +1432,7 @@ func TestFunc(t *testing.T) {
func
TestMakeFunc
(
t
*
testing
.
T
)
{
func
TestMakeFunc
(
t
*
testing
.
T
)
{
switch
runtime
.
GOARCH
{
switch
runtime
.
GOARCH
{
case
"amd64"
:
case
"amd64"
,
"386"
:
default
:
default
:
t
.
Skip
(
"MakeFunc not implemented for "
+
runtime
.
GOARCH
)
t
.
Skip
(
"MakeFunc not implemented for "
+
runtime
.
GOARCH
)
}
}
...
...
libgo/go/reflect/makefunc.go
View file @
a84dbde7
...
@@ -47,7 +47,7 @@ func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value {
...
@@ -47,7 +47,7 @@ func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value {
}
}
switch
runtime
.
GOARCH
{
switch
runtime
.
GOARCH
{
case
"amd64"
:
case
"amd64"
,
"386"
:
default
:
default
:
panic
(
"reflect.MakeFunc not implemented for "
+
runtime
.
GOARCH
)
panic
(
"reflect.MakeFunc not implemented for "
+
runtime
.
GOARCH
)
}
}
...
...
libgo/go/reflect/makefunc_386.S
0 → 100644
View file @
a84dbde7
# Copyright 2013 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.
# MakeFunc 386 assembly code.
.global reflect.makeFuncStub
#ifdef __ELF__
.type reflect.makeFuncStub,@function
#endif
reflect.makeFuncStub:
.cfi_startproc
# Go does not provide any equivalent to the regparm function
# attribute, so on Go we do not need to worry about passing
# parameters in registers. We just pass a pointer to the
# arguments on the stack.
#
# We do need to pick up the return values, though, so we pass
# a pointer to a struct that looks like this.
# struct {
# esp uint32 // 0x0
# eax uint32 // 0x4
# st0 uint64 // 0x8
# }
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset %ebp, -8
movl %esp, %ebp
.cfi_def_cfa_register %ebp
pushl %ebx # In case this is PIC.
subl $36, %esp # Enough for args and to align stack.
.cfi_offset %ebx, -12
#ifdef __PIC__
call __x86.get_pc_thunk.bx
addl $_GLOBAL_OFFSET_TABLE_, %ebx
#endif
leal 8(%ebp), %eax # Set esp field in struct.
movl %eax, -24(%ebp)
#ifdef __PIC__
call __go_get_closure@PLT
#else
call __go_get_closure
#endif
movl %eax, 4(%esp)
leal -24(%ebp), %eax
movl %eax, (%esp)
#ifdef __PIC__
call reflect.MakeFuncStubGo@PLT
#else
call reflect.MakeFuncStubGo
#endif
# Set return registers.
movl -20(%ebp), %eax
fldl -16(%ebp)
#ifdef __SSE2__
# In case we are compiling with -msseregparm. This won't work
# correctly if only SSE1 is supported, but that seems unlikely.
movsd -16(%ebp), %xmm0
#endif
addl $36, %esp
popl %ebx
.cfi_restore %ebx
popl %ebp
.cfi_restore %ebp
.cfi_def_cfa %esp, 4
ret
.cfi_endproc
#ifdef __ELF__
.size reflect.makeFuncStub, . - reflect.makeFuncStub
#endif
#ifdef __PIC__
.section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
.globl __x86.get_pc_thunk.bx
.hidden __x86.get_pc_thunk.bx
#ifdef __ELF__
.type __x86.get_pc_thunk.bx, @function
#endif
__x86.get_pc_thunk.bx:
.cfi_startproc
movl (%esp), %ebx
ret
.cfi_endproc
#ifdef __ELF__
.size __x86.get_pc_thunk.bx, . - __x86.get_pc_thunk.bx
#endif
#endif
#ifdef __ELF__
.section .note.GNU-stack,"",@progbits
.section .note.GNU-split-stack,"",@progbits
.section .note.GNU-no-split-stack,"",@progbits
#endif
libgo/go/reflect/makefuncgo_386.go
0 → 100644
View file @
a84dbde7
// Copyright 2013 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.
// MakeFunc 386 implementation.
package
reflect
import
"unsafe"
// The assembler stub will pass a pointer to this structure. We
// assume that no parameters are passed in registers--that is, we do
// not support the -mregparm option. On return we will set the
// registers that might hold result values.
type
i386Regs
struct
{
esp
uint32
eax
uint32
// Value to return in %eax.
st0
uint64
// Value to return in %st(0).
}
// MakeFuncStubGo implements the 386 calling convention for MakeFunc.
// This should not be called. It is exported so that assembly code
// can call it.
func
MakeFuncStubGo
(
regs
*
i386Regs
,
c
*
makeFuncImpl
)
{
ftyp
:=
c
.
typ
// See if the result requires a struct. If it does, the first
// parameter is a pointer to the struct.
retStruct
:=
false
retEmpty
:=
false
switch
len
(
ftyp
.
out
)
{
case
0
:
retEmpty
=
true
case
1
:
if
ftyp
.
out
[
0
]
.
size
==
0
{
retEmpty
=
true
}
else
{
switch
ftyp
.
out
[
0
]
.
Kind
()
{
case
Complex64
,
Complex128
,
Array
,
Interface
,
Slice
,
String
,
Struct
:
retStruct
=
true
}
}
default
:
size
:=
uintptr
(
0
)
for
_
,
typ
:=
range
ftyp
.
out
{
size
+=
typ
.
size
}
if
size
==
0
{
retEmpty
=
true
}
else
{
retStruct
=
true
}
}
in
:=
make
([]
Value
,
0
,
len
(
ftyp
.
in
))
ap
:=
uintptr
(
regs
.
esp
)
var
retPtr
unsafe
.
Pointer
if
retStruct
{
retPtr
=
*
(
*
unsafe
.
Pointer
)(
unsafe
.
Pointer
(
ap
))
ap
+=
ptrSize
}
for
_
,
rt
:=
range
ftyp
.
in
{
ap
=
align
(
ap
,
ptrSize
)
// We have to copy the argument onto the heap in case
// the function hangs on the reflect.Value we pass it.
p
:=
unsafe_New
(
rt
)
memmove
(
p
,
unsafe
.
Pointer
(
ap
),
rt
.
size
)
v
:=
Value
{
rt
,
p
,
flag
(
rt
.
Kind
()
<<
flagKindShift
)
|
flagIndir
}
in
=
append
(
in
,
v
)
ap
+=
rt
.
size
}
// Call the real function.
out
:=
c
.
fn
(
in
)
if
len
(
out
)
!=
len
(
ftyp
.
out
)
{
panic
(
"reflect: wrong return count from function created by MakeFunc"
)
}
for
i
,
typ
:=
range
ftyp
.
out
{
v
:=
out
[
i
]
if
v
.
typ
!=
typ
{
panic
(
"reflect: function created by MakeFunc using "
+
funcName
(
c
.
fn
)
+
" returned wrong type: have "
+
out
[
i
]
.
typ
.
String
()
+
" for "
+
typ
.
String
())
}
if
v
.
flag
&
flagRO
!=
0
{
panic
(
"reflect: function created by MakeFunc using "
+
funcName
(
c
.
fn
)
+
" returned value obtained from unexported field"
)
}
}
if
retEmpty
{
return
}
if
retStruct
{
off
:=
uintptr
(
0
)
for
i
,
typ
:=
range
ftyp
.
out
{
v
:=
out
[
i
]
off
=
align
(
off
,
uintptr
(
typ
.
fieldAlign
))
addr
:=
unsafe
.
Pointer
(
uintptr
(
retPtr
)
+
off
)
if
v
.
flag
&
flagIndir
==
0
&&
(
v
.
kind
()
==
Ptr
||
v
.
kind
()
==
UnsafePointer
)
{
storeIword
(
addr
,
iword
(
v
.
val
),
typ
.
size
)
}
else
{
memmove
(
addr
,
v
.
val
,
typ
.
size
)
}
off
+=
typ
.
size
}
regs
.
eax
=
uint32
(
uintptr
(
retPtr
))
return
}
if
len
(
ftyp
.
out
)
!=
1
{
panic
(
"inconsistency"
)
}
v
:=
out
[
0
]
w
:=
v
.
iword
()
if
v
.
Kind
()
!=
Ptr
&&
v
.
Kind
()
!=
UnsafePointer
{
w
=
loadIword
(
unsafe
.
Pointer
(
w
),
v
.
typ
.
size
)
}
switch
v
.
Kind
()
{
case
Float32
,
Float64
:
regs
.
st0
=
uint64
(
uintptr
(
w
))
default
:
regs
.
eax
=
uint32
(
uintptr
(
w
))
}
}
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