mirror of https://github.com/tinygo-org/tinygo.git
wasmstm32webassemblymicrocontrollerarmavrspiwasiadafruitarduinocircuitplayground-expressgpioi2cllvmmicrobitnrf51nrf52nrf52840samd21tinygo
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
65 lines
2.4 KiB
65 lines
2.4 KiB
package compiler
|
|
|
|
// This file defines alias functions for functions that are normally defined in
|
|
// Go assembly.
|
|
//
|
|
// The Go toolchain defines many performance critical functions in assembly
|
|
// instead of plain Go. This is a problem for TinyGo as it currently (as of
|
|
// august 2021) is not able to compile these assembly files and even if it
|
|
// could, it would not be able to make use of them for many targets that are
|
|
// supported by TinyGo (baremetal RISC-V, AVR, etc). Therefore, many of these
|
|
// functions are aliased to their generic Go implementation.
|
|
// This results in slower than possible implementations, but at least they are
|
|
// usable.
|
|
|
|
import "tinygo.org/x/go-llvm"
|
|
|
|
var stdlibAliases = map[string]string{
|
|
// crypto packages
|
|
"crypto/ed25519/internal/edwards25519/field.feMul": "crypto/ed25519/internal/edwards25519/field.feMulGeneric",
|
|
"crypto/internal/edwards25519/field.feSquare": "crypto/ed25519/internal/edwards25519/field.feSquareGeneric",
|
|
"crypto/md5.block": "crypto/md5.blockGeneric",
|
|
"crypto/sha1.block": "crypto/sha1.blockGeneric",
|
|
"crypto/sha1.blockAMD64": "crypto/sha1.blockGeneric",
|
|
"crypto/sha256.block": "crypto/sha256.blockGeneric",
|
|
"crypto/sha512.blockAMD64": "crypto/sha512.blockGeneric",
|
|
|
|
// AES
|
|
"crypto/aes.decryptBlockAsm": "crypto/aes.decryptBlock",
|
|
"crypto/aes.encryptBlockAsm": "crypto/aes.encryptBlock",
|
|
|
|
// math package
|
|
"math.archHypot": "math.hypot",
|
|
"math.archMax": "math.max",
|
|
"math.archMin": "math.min",
|
|
"math.archModf": "math.modf",
|
|
}
|
|
|
|
// createAlias implements the function (in the builder) as a call to the alias
|
|
// function.
|
|
func (b *builder) createAlias(alias llvm.Value) {
|
|
b.llvmFn.SetVisibility(llvm.HiddenVisibility)
|
|
b.llvmFn.SetUnnamedAddr(true)
|
|
|
|
if b.Debug {
|
|
if b.fn.Syntax() != nil {
|
|
// Create debug info file if present.
|
|
b.difunc = b.attachDebugInfo(b.fn)
|
|
}
|
|
pos := b.program.Fset.Position(b.fn.Pos())
|
|
b.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), b.difunc, llvm.Metadata{})
|
|
}
|
|
entryBlock := b.ctx.AddBasicBlock(b.llvmFn, "entry")
|
|
b.SetInsertPointAtEnd(entryBlock)
|
|
if b.llvmFn.Type() != alias.Type() {
|
|
b.addError(b.fn.Pos(), "alias function should have the same type as aliasee "+alias.Name())
|
|
b.CreateUnreachable()
|
|
return
|
|
}
|
|
result := b.CreateCall(alias.GlobalValueType(), alias, b.llvmFn.Params(), "")
|
|
if result.Type().TypeKind() == llvm.VoidTypeKind {
|
|
b.CreateRetVoid()
|
|
} else {
|
|
b.CreateRet(result)
|
|
}
|
|
}
|
|
|