Merge pull request #368 from xushiwei/q
builtin: real/imag/complex; c/math/cmplx; patch: math/cmplx
This commit is contained in:
@@ -206,8 +206,9 @@ Here are the Go packages that can be imported correctly:
|
|||||||
* [unicode](https://pkg.go.dev/unicode)
|
* [unicode](https://pkg.go.dev/unicode)
|
||||||
* [unicode/utf8](https://pkg.go.dev/unicode/utf8)
|
* [unicode/utf8](https://pkg.go.dev/unicode/utf8)
|
||||||
* [unicode/utf16](https://pkg.go.dev/unicode/utf16)
|
* [unicode/utf16](https://pkg.go.dev/unicode/utf16)
|
||||||
* [math/bits](https://pkg.go.dev/math/bits)
|
|
||||||
* [math](https://pkg.go.dev/math)
|
* [math](https://pkg.go.dev/math)
|
||||||
|
* [math/bits](https://pkg.go.dev/math/bits)
|
||||||
|
* [math/cmplx](https://pkg.go.dev/math/cmplx)
|
||||||
* [syscall](https://pkg.go.dev/syscall) (partially)
|
* [syscall](https://pkg.go.dev/syscall) (partially)
|
||||||
* [sync](https://pkg.go.dev/sync) (partially)
|
* [sync](https://pkg.go.dev/sync) (partially)
|
||||||
* [sync/atomic](https://pkg.go.dev/sync/atomic) (partially)
|
* [sync/atomic](https://pkg.go.dev/sync/atomic) (partially)
|
||||||
@@ -217,8 +218,8 @@ Here are the Go packages that can be imported correctly:
|
|||||||
|
|
||||||
- [Go 1.20+](https://go.dev) (build only)
|
- [Go 1.20+](https://go.dev) (build only)
|
||||||
- [LLVM 17](https://llvm.org)
|
- [LLVM 17](https://llvm.org)
|
||||||
- [Clang 17](https://clang.llvm.org)
|
|
||||||
- [LLD 17](https://lld.llvm.org)
|
- [LLD 17](https://lld.llvm.org)
|
||||||
|
- [Clang 17](https://clang.llvm.org)
|
||||||
- [pkg-config 0.29+](https://www.freedesktop.org/wiki/Software/pkg-config/)
|
- [pkg-config 0.29+](https://www.freedesktop.org/wiki/Software/pkg-config/)
|
||||||
- [bdwgc/libgc 8.0+](https://www.hboehm.info/gc/)
|
- [bdwgc/libgc 8.0+](https://www.hboehm.info/gc/)
|
||||||
- [cJSON 1.7+](https://github.com/DaveGamble/cJSON) (optional, for [`github.com/goplus/llgo/c/cjson`](https://pkg.go.dev/github.com/goplus/llgo/c/cjson))
|
- [cJSON 1.7+](https://github.com/DaveGamble/cJSON) (optional, for [`github.com/goplus/llgo/c/cjson`](https://pkg.go.dev/github.com/goplus/llgo/c/cjson))
|
||||||
|
|||||||
9
_demo/complex/cmplx.go
Normal file
9
_demo/complex/cmplx.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/cmplx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println("abs(3+4i):", cmplx.Abs(3+4i))
|
||||||
|
}
|
||||||
151
c/math/cmplx/complex.go
Normal file
151
c/math/cmplx/complex.go
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cmplx
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoPackage = "decl"
|
||||||
|
)
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//go:linkname Abs C.cabs
|
||||||
|
func Abs(z complex128) float64
|
||||||
|
|
||||||
|
//go:linkname Acos C.cacos
|
||||||
|
func Acos(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Acosh C.cacosh
|
||||||
|
func Acosh(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Asin C.casin
|
||||||
|
func Asin(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Asinh C.casinh
|
||||||
|
func Asinh(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Atan C.catan
|
||||||
|
func Atan(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Atanh C.catanh
|
||||||
|
func Atanh(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Cos C.ccos
|
||||||
|
func Cos(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Cosh C.ccosh
|
||||||
|
func Cosh(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Exp C.cexp
|
||||||
|
func Exp(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Log C.clog
|
||||||
|
func Log(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Log10 C.clog10
|
||||||
|
func Log10(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Arg C.carg
|
||||||
|
func Arg(z complex128) float64
|
||||||
|
|
||||||
|
//go:linkname Phase C.carg
|
||||||
|
func Phase(z complex128) float64
|
||||||
|
|
||||||
|
//go:linkname Pow C.cpow
|
||||||
|
func Pow(x, y complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Sin C.csin
|
||||||
|
func Sin(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Sinh C.csinh
|
||||||
|
func Sinh(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Sqrt C.csqrt
|
||||||
|
func Sqrt(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Tan C.ctan
|
||||||
|
func Tan(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Tanh C.ctanh
|
||||||
|
func Tanh(z complex128) complex128
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//go:linkname Absf C.cabsf
|
||||||
|
func Absf(z complex64) float32
|
||||||
|
|
||||||
|
//go:linkname Acosf C.cacosf
|
||||||
|
func Acosf(z complex64) complex64
|
||||||
|
|
||||||
|
//go:linkname Acoshf C.cacoshf
|
||||||
|
func Acoshf(z complex64) complex64
|
||||||
|
|
||||||
|
//go:linkname Asinf C.casinf
|
||||||
|
func Asinf(z complex64) complex64
|
||||||
|
|
||||||
|
//go:linkname Asinhf C.casinhf
|
||||||
|
func Asinhf(z complex64) complex64
|
||||||
|
|
||||||
|
//go:linkname Atanf C.catanf
|
||||||
|
func Atanf(z complex64) complex64
|
||||||
|
|
||||||
|
//go:linkname Atanhf C.catanhf
|
||||||
|
func Atanhf(z complex64) complex64
|
||||||
|
|
||||||
|
//go:linkname Cosf C.ccosf
|
||||||
|
func Cosf(z complex64) complex64
|
||||||
|
|
||||||
|
//go:linkname Coshf C.ccoshf
|
||||||
|
func Coshf(z complex64) complex64
|
||||||
|
|
||||||
|
//go:linkname Expf C.cexpf
|
||||||
|
func Expf(z complex64) complex64
|
||||||
|
|
||||||
|
//go:linkname Logf C.clogf
|
||||||
|
func Logf(z complex64) complex64
|
||||||
|
|
||||||
|
//go:linkname Log10f C.clog10f
|
||||||
|
func Log10f(z complex64) complex64
|
||||||
|
|
||||||
|
//go:linkname Argf C.cargf
|
||||||
|
func Argf(z complex64) float32
|
||||||
|
|
||||||
|
//go:linkname Phasef C.cargf
|
||||||
|
func Phasef(z complex64) float32
|
||||||
|
|
||||||
|
//go:linkname Powf C.cpowf
|
||||||
|
func Powf(x, y complex64) complex64
|
||||||
|
|
||||||
|
//go:linkname Sinf C.csinf
|
||||||
|
func Sinf(z complex64) complex64
|
||||||
|
|
||||||
|
//go:linkname Sinhf C.csinhf
|
||||||
|
func Sinhf(z complex64) complex64
|
||||||
|
|
||||||
|
//go:linkname Sqrtf C.csqrtf
|
||||||
|
func Sqrtf(z complex64) complex64
|
||||||
|
|
||||||
|
//go:linkname Tanf C.ctanf
|
||||||
|
func Tanf(z complex64) complex64
|
||||||
|
|
||||||
|
//go:linkname Tanhf C.ctanhf
|
||||||
|
func Tanhf(z complex64) complex64
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
12
cl/_testlibc/complex/in.go
Normal file
12
cl/_testlibc/complex/in.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c/math/cmplx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
re := float32(3.0)
|
||||||
|
im := float32(4.0)
|
||||||
|
c := complex(re, im)
|
||||||
|
println("abs(3+4i):", cmplx.Absf(c))
|
||||||
|
}
|
||||||
59
cl/_testlibc/complex/out.ll
Normal file
59
cl/_testlibc/complex/out.ll
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
; ModuleID = 'main'
|
||||||
|
source_filename = "main"
|
||||||
|
|
||||||
|
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
|
||||||
|
|
||||||
|
@"main.init$guard" = global i1 false, align 1
|
||||||
|
@__llgo_argc = global i32 0, align 4
|
||||||
|
@__llgo_argv = global ptr null, align 8
|
||||||
|
@0 = private unnamed_addr constant [10 x i8] c"abs(3+4i):", align 1
|
||||||
|
|
||||||
|
define void @main.init() {
|
||||||
|
_llgo_0:
|
||||||
|
%0 = load i1, ptr @"main.init$guard", align 1
|
||||||
|
br i1 %0, label %_llgo_2, label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_0
|
||||||
|
store i1 true, ptr @"main.init$guard", align 1
|
||||||
|
br label %_llgo_2
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @main(i32 %0, ptr %1) {
|
||||||
|
_llgo_0:
|
||||||
|
store i32 %0, ptr @__llgo_argc, align 4
|
||||||
|
store ptr %1, ptr @__llgo_argv, align 8
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
call void @main.init()
|
||||||
|
%2 = alloca { float, float }, align 8
|
||||||
|
%3 = getelementptr inbounds { float, float }, ptr %2, i32 0, i32 0
|
||||||
|
store float 3.000000e+00, ptr %3, align 4
|
||||||
|
%4 = getelementptr inbounds { float, float }, ptr %2, i32 0, i32 1
|
||||||
|
store float 4.000000e+00, ptr %4, align 4
|
||||||
|
%5 = load { float, float }, ptr %2, align 4
|
||||||
|
%6 = call float @cabsf({ float, float } %5)
|
||||||
|
%7 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%8 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %7, i32 0, i32 0
|
||||||
|
store ptr @0, ptr %8, align 8
|
||||||
|
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %7, i32 0, i32 1
|
||||||
|
store i64 10, ptr %9, align 4
|
||||||
|
%10 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %7, align 8
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %10)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
|
||||||
|
%11 = fpext float %6 to double
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double %11)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
|
||||||
|
declare float @cabsf({ float, float })
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String")
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8)
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double)
|
||||||
12
cl/_testlibgo/complex/in.go
Normal file
12
cl/_testlibgo/complex/in.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/cmplx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
re := 3.0
|
||||||
|
im := 4.0
|
||||||
|
c := complex(re, im)
|
||||||
|
println("abs(3+4i):", cmplx.Abs(c))
|
||||||
|
}
|
||||||
61
cl/_testlibgo/complex/out.ll
Normal file
61
cl/_testlibgo/complex/out.ll
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
; ModuleID = 'main'
|
||||||
|
source_filename = "main"
|
||||||
|
|
||||||
|
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
|
||||||
|
|
||||||
|
@"main.init$guard" = global i1 false, align 1
|
||||||
|
@__llgo_argc = global i32 0, align 4
|
||||||
|
@__llgo_argv = global ptr null, align 8
|
||||||
|
@0 = private unnamed_addr constant [10 x i8] c"abs(3+4i):", align 1
|
||||||
|
|
||||||
|
define void @main.init() {
|
||||||
|
_llgo_0:
|
||||||
|
%0 = load i1, ptr @"main.init$guard", align 1
|
||||||
|
br i1 %0, label %_llgo_2, label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_0
|
||||||
|
store i1 true, ptr @"main.init$guard", align 1
|
||||||
|
call void @"math/cmplx.init"()
|
||||||
|
br label %_llgo_2
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @main(i32 %0, ptr %1) {
|
||||||
|
_llgo_0:
|
||||||
|
store i32 %0, ptr @__llgo_argc, align 4
|
||||||
|
store ptr %1, ptr @__llgo_argv, align 8
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
call void @main.init()
|
||||||
|
%2 = alloca { double, double }, align 8
|
||||||
|
%3 = getelementptr inbounds { double, double }, ptr %2, i32 0, i32 0
|
||||||
|
store double 3.000000e+00, ptr %3, align 8
|
||||||
|
%4 = getelementptr inbounds { double, double }, ptr %2, i32 0, i32 1
|
||||||
|
store double 4.000000e+00, ptr %4, align 8
|
||||||
|
%5 = load { double, double }, ptr %2, align 8
|
||||||
|
%6 = call double @"math/cmplx.Abs"({ double, double } %5)
|
||||||
|
%7 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%8 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %7, i32 0, i32 0
|
||||||
|
store ptr @0, ptr %8, align 8
|
||||||
|
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %7, i32 0, i32 1
|
||||||
|
store i64 10, ptr %9, align 4
|
||||||
|
%10 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %7, align 8
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %10)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double %6)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @"math/cmplx.init"()
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
|
||||||
|
declare double @"math/cmplx.Abs"({ double, double })
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String")
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8)
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double)
|
||||||
@@ -742,6 +742,7 @@ var hasAltPkg = map[string]none{
|
|||||||
"io": {},
|
"io": {},
|
||||||
"io/fs": {},
|
"io/fs": {},
|
||||||
"math": {},
|
"math": {},
|
||||||
|
"math/cmplx": {},
|
||||||
"sync": {},
|
"sync": {},
|
||||||
"sync/atomic": {},
|
"sync/atomic": {},
|
||||||
"syscall": {},
|
"syscall": {},
|
||||||
|
|||||||
86
internal/lib/math/cmplx/cmplx.go
Normal file
86
internal/lib/math/cmplx/cmplx.go
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cmplx
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoPackage = true
|
||||||
|
)
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//go:linkname Abs C.cabs
|
||||||
|
func Abs(z complex128) float64
|
||||||
|
|
||||||
|
//go:linkname Acos C.cacos
|
||||||
|
func Acos(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Acosh C.cacosh
|
||||||
|
func Acosh(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Asin C.casin
|
||||||
|
func Asin(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Asinh C.casinh
|
||||||
|
func Asinh(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Atan C.catan
|
||||||
|
func Atan(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Atanh C.catanh
|
||||||
|
func Atanh(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Cos C.ccos
|
||||||
|
func Cos(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Cosh C.ccosh
|
||||||
|
func Cosh(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Exp C.cexp
|
||||||
|
func Exp(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Log C.clog
|
||||||
|
func Log(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Log10 C.clog10
|
||||||
|
func Log10(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Phase C.carg
|
||||||
|
func Phase(z complex128) float64
|
||||||
|
|
||||||
|
//go:linkname Pow C.cpow
|
||||||
|
func Pow(x, y complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Sin C.csin
|
||||||
|
func Sin(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Sinh C.csinh
|
||||||
|
func Sinh(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Sqrt C.csqrt
|
||||||
|
func Sqrt(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Tan C.ctan
|
||||||
|
func Tan(z complex128) complex128
|
||||||
|
|
||||||
|
//go:linkname Tanh C.ctanh
|
||||||
|
func Tanh(z complex128) complex128
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
@@ -29,6 +29,10 @@ func init() {
|
|||||||
ssa.SetDebug(ssa.DbgFlagAll)
|
ssa.SetDebug(ssa.DbgFlagAll)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFromTestlibgo(t *testing.T) {
|
||||||
|
cltest.FromDir(t, "", "../cl/_testlibgo", false)
|
||||||
|
}
|
||||||
|
|
||||||
func TestFromTestgo(t *testing.T) {
|
func TestFromTestgo(t *testing.T) {
|
||||||
cltest.FromDir(t, "", "../cl/_testgo", false)
|
cltest.FromDir(t, "", "../cl/_testgo", false)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,6 +66,21 @@ func (b Builder) getField(x Expr, idx int) Expr {
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
func (b Builder) Complex(r, i Expr) Expr {
|
||||||
|
if debugInstr {
|
||||||
|
log.Printf("Complex %v, %v\n", r.impl, i.impl)
|
||||||
|
}
|
||||||
|
prog := b.Prog
|
||||||
|
var t Type
|
||||||
|
switch kind := r.raw.Type.Underlying().(*types.Basic).Kind(); kind {
|
||||||
|
case types.Float64:
|
||||||
|
t = prog.Complex128()
|
||||||
|
case types.Float32:
|
||||||
|
t = prog.Complex64()
|
||||||
|
}
|
||||||
|
return b.aggregateValue(t, r.impl, i.impl)
|
||||||
|
}
|
||||||
|
|
||||||
// MakeString creates a new string from a C string pointer and length.
|
// MakeString creates a new string from a C string pointer and length.
|
||||||
func (b Builder) MakeString(cstr Expr, n ...Expr) (ret Expr) {
|
func (b Builder) MakeString(cstr Expr, n ...Expr) (ret Expr) {
|
||||||
if debugInstr {
|
if debugInstr {
|
||||||
|
|||||||
22
ssa/expr.go
22
ssa/expr.go
@@ -168,11 +168,20 @@ func (p Program) IntVal(v uint64, t Type) Expr {
|
|||||||
return Expr{ret, t}
|
return Expr{ret, t}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FloatVal returns a float constant expression.
|
||||||
func (p Program) FloatVal(v float64, t Type) Expr {
|
func (p Program) FloatVal(v float64, t Type) Expr {
|
||||||
ret := llvm.ConstFloat(t.ll, v)
|
ret := llvm.ConstFloat(t.ll, v)
|
||||||
return Expr{ret, t}
|
return Expr{ret, t}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ComplexVal returns a complex constant expression.
|
||||||
|
func (p Program) ComplexVal(v complex128, t Type) Expr {
|
||||||
|
flt := p.Field(t, 0)
|
||||||
|
re := p.FloatVal(real(v), flt)
|
||||||
|
im := p.FloatVal(imag(v), flt)
|
||||||
|
return Expr{llvm.ConstStruct([]llvm.Value{re.impl, im.impl}, false), t}
|
||||||
|
}
|
||||||
|
|
||||||
// Val returns a constant expression.
|
// Val returns a constant expression.
|
||||||
func (p Program) Val(v interface{}) Expr {
|
func (p Program) Val(v interface{}) Expr {
|
||||||
switch v := v.(type) {
|
switch v := v.(type) {
|
||||||
@@ -211,11 +220,16 @@ func (b Builder) Const(v constant.Value, typ Type) Expr {
|
|||||||
if v, exact := constant.Uint64Val(v); exact {
|
if v, exact := constant.Uint64Val(v); exact {
|
||||||
return prog.IntVal(v, typ)
|
return prog.IntVal(v, typ)
|
||||||
}
|
}
|
||||||
case kind == types.Float32 || kind == types.Float64:
|
case kind == types.Float64 || kind == types.Float32:
|
||||||
v, _ := constant.Float64Val(v)
|
v, _ := constant.Float64Val(v)
|
||||||
return prog.FloatVal(v, typ)
|
return prog.FloatVal(v, typ)
|
||||||
case kind == types.String:
|
case kind == types.String:
|
||||||
return Expr{b.Str(constant.StringVal(v)).impl, typ}
|
return Expr{b.Str(constant.StringVal(v)).impl, typ}
|
||||||
|
case kind == types.Complex128 || kind == types.Complex64:
|
||||||
|
v = constant.ToComplex(v)
|
||||||
|
re, _ := constant.Float64Val(constant.Real(v))
|
||||||
|
im, _ := constant.Float64Val(constant.Imag(v))
|
||||||
|
return prog.ComplexVal(complex(re, im), typ)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panic(fmt.Sprintf("unsupported Const: %v, %v", v, raw))
|
panic(fmt.Sprintf("unsupported Const: %v, %v", v, raw))
|
||||||
@@ -941,6 +955,12 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
|
|||||||
return b.Recover()
|
return b.Recover()
|
||||||
case "print", "println":
|
case "print", "println":
|
||||||
return b.PrintEx(fn == "println", args...)
|
return b.PrintEx(fn == "println", args...)
|
||||||
|
case "complex":
|
||||||
|
return b.Complex(args[0], args[1])
|
||||||
|
case "real":
|
||||||
|
return b.getField(args[0], 0)
|
||||||
|
case "imag":
|
||||||
|
return b.getField(args[0], 1)
|
||||||
case "String": // unsafe.String
|
case "String": // unsafe.String
|
||||||
return b.unsafeString(args[0].impl, args[1].impl)
|
return b.unsafeString(args[0].impl, args[1].impl)
|
||||||
case "Slice": // unsafe.Slice
|
case "Slice": // unsafe.Slice
|
||||||
|
|||||||
@@ -125,15 +125,16 @@ type aProgram struct {
|
|||||||
voidType llvm.Type
|
voidType llvm.Type
|
||||||
voidPtrTy llvm.Type
|
voidPtrTy llvm.Type
|
||||||
|
|
||||||
|
c64Type llvm.Type
|
||||||
|
c128Type llvm.Type
|
||||||
|
|
||||||
rtStringTy llvm.Type
|
rtStringTy llvm.Type
|
||||||
rtEfaceTy llvm.Type
|
rtEfaceTy llvm.Type
|
||||||
rtIfaceTy llvm.Type
|
rtIfaceTy llvm.Type
|
||||||
rtSliceTy llvm.Type
|
rtSliceTy llvm.Type
|
||||||
rtMapTy llvm.Type
|
rtMapTy llvm.Type
|
||||||
|
|
||||||
anyTy Type
|
anyTy Type
|
||||||
//anyPtr Type
|
|
||||||
//anyPPtr Type
|
|
||||||
voidTy Type
|
voidTy Type
|
||||||
voidPtr Type
|
voidPtr Type
|
||||||
voidPPtr Type
|
voidPPtr Type
|
||||||
@@ -147,6 +148,8 @@ type aProgram struct {
|
|||||||
uintTy Type
|
uintTy Type
|
||||||
f64Ty Type
|
f64Ty Type
|
||||||
f32Ty Type
|
f32Ty Type
|
||||||
|
c128Ty Type
|
||||||
|
c64Ty Type
|
||||||
byteTy Type
|
byteTy Type
|
||||||
i32Ty Type
|
i32Ty Type
|
||||||
u32Ty Type
|
u32Ty Type
|
||||||
@@ -284,6 +287,24 @@ func (p Program) rtString() llvm.Type {
|
|||||||
return p.rtStringTy
|
return p.rtStringTy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p Program) tyComplex64() llvm.Type {
|
||||||
|
if p.c64Type.IsNil() {
|
||||||
|
ctx := p.ctx
|
||||||
|
f32 := ctx.FloatType()
|
||||||
|
p.c64Type = ctx.StructType([]llvm.Type{f32, f32}, false)
|
||||||
|
}
|
||||||
|
return p.c64Type
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Program) tyComplex128() llvm.Type {
|
||||||
|
if p.c128Type.IsNil() {
|
||||||
|
ctx := p.ctx
|
||||||
|
f64 := ctx.DoubleType()
|
||||||
|
p.c128Type = ctx.StructType([]llvm.Type{f64, f64}, false)
|
||||||
|
}
|
||||||
|
return p.c128Type
|
||||||
|
}
|
||||||
|
|
||||||
// NewPackage creates a new package.
|
// NewPackage creates a new package.
|
||||||
func (p Program) NewPackage(name, pkgPath string) Package {
|
func (p Program) NewPackage(name, pkgPath string) Package {
|
||||||
mod := p.ctx.NewModule(pkgPath)
|
mod := p.ctx.NewModule(pkgPath)
|
||||||
@@ -394,24 +415,6 @@ func (p Program) String() Type {
|
|||||||
return p.stringTy
|
return p.stringTy
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// AnyPtrPtr returns **any type.
|
|
||||||
func (p Program) AnyPtrPtr() Type {
|
|
||||||
if p.anyPPtr == nil {
|
|
||||||
p.anyPPtr = p.Pointer(p.AnyPtr())
|
|
||||||
}
|
|
||||||
return p.anyPPtr
|
|
||||||
}
|
|
||||||
|
|
||||||
// AnyPtr returns *any type.
|
|
||||||
func (p Program) AnyPtr() Type {
|
|
||||||
if p.anyPtr == nil {
|
|
||||||
p.anyPtr = p.Pointer(p.Any())
|
|
||||||
}
|
|
||||||
return p.anyPtr
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Any returns the any (empty interface) type.
|
// Any returns the any (empty interface) type.
|
||||||
func (p Program) Any() Type {
|
func (p Program) Any() Type {
|
||||||
if p.anyTy == nil {
|
if p.anyTy == nil {
|
||||||
@@ -484,6 +487,22 @@ func (p Program) Float32() Type {
|
|||||||
return p.f32Ty
|
return p.f32Ty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Complex128 returns complex128 type.
|
||||||
|
func (p Program) Complex128() Type {
|
||||||
|
if p.c128Ty == nil {
|
||||||
|
p.c128Ty = p.rawType(types.Typ[types.Complex128])
|
||||||
|
}
|
||||||
|
return p.c128Ty
|
||||||
|
}
|
||||||
|
|
||||||
|
// Complex64 returns complex64 type.
|
||||||
|
func (p Program) Complex64() Type {
|
||||||
|
if p.c64Ty == nil {
|
||||||
|
p.c64Ty = p.rawType(types.Typ[types.Complex64])
|
||||||
|
}
|
||||||
|
return p.c64Ty
|
||||||
|
}
|
||||||
|
|
||||||
// Byte returns byte type.
|
// Byte returns byte type.
|
||||||
func (p Program) Byte() Type {
|
func (p Program) Byte() Type {
|
||||||
if p.byteTy == nil {
|
if p.byteTy == nil {
|
||||||
|
|||||||
10
ssa/type.go
10
ssa/type.go
@@ -214,6 +214,14 @@ func (p Program) Field(typ Type, i int) Type {
|
|||||||
switch t := typ.raw.Type.(type) {
|
switch t := typ.raw.Type.(type) {
|
||||||
case *types.Tuple:
|
case *types.Tuple:
|
||||||
fld = t.At(i)
|
fld = t.At(i)
|
||||||
|
case *types.Basic:
|
||||||
|
switch t.Kind() {
|
||||||
|
case types.Complex128:
|
||||||
|
return p.Float64()
|
||||||
|
case types.Complex64:
|
||||||
|
return p.Float32()
|
||||||
|
}
|
||||||
|
panic("Field: basic type doesn't have fields")
|
||||||
default:
|
default:
|
||||||
fld = t.Underlying().(*types.Struct).Field(i)
|
fld = t.Underlying().(*types.Struct).Field(i)
|
||||||
}
|
}
|
||||||
@@ -330,7 +338,9 @@ func (p Program) toType(raw types.Type) Type {
|
|||||||
case types.Float64:
|
case types.Float64:
|
||||||
return &aType{p.ctx.DoubleType(), typ, vkFloat}
|
return &aType{p.ctx.DoubleType(), typ, vkFloat}
|
||||||
case types.Complex64:
|
case types.Complex64:
|
||||||
|
return &aType{p.tyComplex64(), typ, vkComplex}
|
||||||
case types.Complex128:
|
case types.Complex128:
|
||||||
|
return &aType{p.tyComplex128(), typ, vkComplex}
|
||||||
case types.String:
|
case types.String:
|
||||||
return &aType{p.rtString(), typ, vkString}
|
return &aType{p.rtString(), typ, vkString}
|
||||||
case types.UnsafePointer:
|
case types.UnsafePointer:
|
||||||
|
|||||||
Reference in New Issue
Block a user