diff options
author | Ayke van Laethem <[email protected]> | 2023-03-29 18:33:24 +0200 |
---|---|---|
committer | Ron Evans <[email protected]> | 2023-03-29 20:55:09 +0200 |
commit | 464ebc4fe1122085a60f0a376189281b2e391eba (patch) | |
tree | b39fa9c11698bab7ab50f6634c28406f47c37837 /compiler/llvm.go | |
parent | 568c2a4363199f5075fb50e8d43643b5f4059ec6 (diff) | |
download | tinygo-464ebc4fe1122085a60f0a376189281b2e391eba.tar.gz tinygo-464ebc4fe1122085a60f0a376189281b2e391eba.zip |
compiler: implement most math/bits functions
These functions can be implemented more efficiently using LLVM
intrinsics. That makes them the Go equivalent of functions like
__builtin_clz which are also implemented using these LLVM intrinsics.
I believe the Go compiler does something very similar: IIRC it converts
calls to these functions into optimal instructions for the given
architecture.
I tested these by running `tinygo test math/bits` after uncommenting the
tests that would always fail (the *PanicZero and *PanicOverflow tests).
Diffstat (limited to 'compiler/llvm.go')
-rw-r--r-- | compiler/llvm.go | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/compiler/llvm.go b/compiler/llvm.go index 33c6603e3..0d33ab564 100644 --- a/compiler/llvm.go +++ b/compiler/llvm.go @@ -464,6 +464,19 @@ func (b *builder) readStackPointer() llvm.Value { return b.CreateCall(stacksave.GlobalValueType(), stacksave, nil, "") } +// createZExtOrTrunc lets the input value fit in the output type bits, by zero +// extending or truncating the integer. +func (b *builder) createZExtOrTrunc(value llvm.Value, t llvm.Type) llvm.Value { + valueBits := value.Type().IntTypeWidth() + resultBits := t.IntTypeWidth() + if valueBits > resultBits { + value = b.CreateTrunc(value, t, "") + } else if valueBits < resultBits { + value = b.CreateZExt(value, t, "") + } + return value +} + // Reverse a slice of bytes. From the wiki: // https://github.com/golang/go/wiki/SliceTricks#reversing func reverseBytes(buf []byte) { |