aboutsummaryrefslogtreecommitdiffhomepage
path: root/compiler/llvm.go
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2023-03-29 18:33:24 +0200
committerRon Evans <[email protected]>2023-03-29 20:55:09 +0200
commit464ebc4fe1122085a60f0a376189281b2e391eba (patch)
treeb39fa9c11698bab7ab50f6634c28406f47c37837 /compiler/llvm.go
parent568c2a4363199f5075fb50e8d43643b5f4059ec6 (diff)
downloadtinygo-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.go13
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) {