509 lines
8.9 KiB
Go
509 lines
8.9 KiB
Go
// Copyright 2017 The go-interpreter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package exec
|
|
|
|
import (
|
|
"math"
|
|
"math/bits"
|
|
)
|
|
|
|
// int32 operators
|
|
|
|
func (vm *VM) i32Clz() {
|
|
vm.pushUint64(uint64(bits.LeadingZeros32(vm.popUint32())))
|
|
}
|
|
|
|
func (vm *VM) i32Ctz() {
|
|
vm.pushUint64(uint64(bits.TrailingZeros32(vm.popUint32())))
|
|
}
|
|
|
|
func (vm *VM) i32Popcnt() {
|
|
vm.pushUint64(uint64(bits.OnesCount32(vm.popUint32())))
|
|
}
|
|
|
|
func (vm *VM) i32Add() {
|
|
vm.pushUint32(vm.popUint32() + vm.popUint32())
|
|
}
|
|
|
|
func (vm *VM) i32Mul() {
|
|
vm.pushUint32(vm.popUint32() * vm.popUint32())
|
|
}
|
|
|
|
func (vm *VM) i32DivS() {
|
|
v2 := vm.popInt32()
|
|
v1 := vm.popInt32()
|
|
vm.pushInt32(v1 / v2)
|
|
}
|
|
|
|
func (vm *VM) i32DivU() {
|
|
v2 := vm.popUint32()
|
|
v1 := vm.popUint32()
|
|
vm.pushUint32(v1 / v2)
|
|
}
|
|
|
|
func (vm *VM) i32RemS() {
|
|
v2 := vm.popInt32()
|
|
v1 := vm.popInt32()
|
|
vm.pushInt32(v1 % v2)
|
|
}
|
|
|
|
func (vm *VM) i32RemU() {
|
|
v2 := vm.popUint32()
|
|
v1 := vm.popUint32()
|
|
vm.pushUint32(v1 % v2)
|
|
}
|
|
|
|
func (vm *VM) i32Sub() {
|
|
v2 := vm.popUint32()
|
|
v1 := vm.popUint32()
|
|
vm.pushUint32(v1 - v2)
|
|
}
|
|
|
|
func (vm *VM) i32And() {
|
|
vm.pushUint32(vm.popUint32() & vm.popUint32())
|
|
}
|
|
|
|
func (vm *VM) i32Or() {
|
|
vm.pushUint32(vm.popUint32() | vm.popUint32())
|
|
}
|
|
|
|
func (vm *VM) i32Xor() {
|
|
vm.pushUint32(vm.popUint32() ^ vm.popUint32())
|
|
}
|
|
|
|
func (vm *VM) i32Shl() {
|
|
v2 := vm.popUint32()
|
|
v1 := vm.popUint32()
|
|
vm.pushUint32(v1 << v2)
|
|
}
|
|
|
|
func (vm *VM) i32ShrU() {
|
|
v2 := vm.popUint32()
|
|
v1 := vm.popUint32()
|
|
vm.pushUint32(v1 >> v2)
|
|
}
|
|
|
|
func (vm *VM) i32ShrS() {
|
|
v2 := vm.popUint32()
|
|
v1 := vm.popInt32()
|
|
vm.pushInt32(v1 >> v2)
|
|
}
|
|
|
|
func (vm *VM) i32Rotl() {
|
|
v2 := vm.popUint32()
|
|
v1 := vm.popUint32()
|
|
vm.pushUint32(bits.RotateLeft32(v1, int(v2)))
|
|
}
|
|
|
|
func (vm *VM) i32Rotr() {
|
|
v2 := vm.popUint32()
|
|
v1 := vm.popUint32()
|
|
vm.pushUint32(bits.RotateLeft32(v1, -int(v2)))
|
|
}
|
|
|
|
func (vm *VM) i32LeS() {
|
|
v2 := vm.popInt32()
|
|
v1 := vm.popInt32()
|
|
vm.pushBool(v1 <= v2)
|
|
}
|
|
|
|
func (vm *VM) i32LeU() {
|
|
v2 := vm.popUint32()
|
|
v1 := vm.popUint32()
|
|
vm.pushBool(v1 <= v2)
|
|
}
|
|
|
|
func (vm *VM) i32LtS() {
|
|
v2 := vm.popInt32()
|
|
v1 := vm.popInt32()
|
|
vm.pushBool(v1 < v2)
|
|
}
|
|
|
|
func (vm *VM) i32LtU() {
|
|
v2 := vm.popUint32()
|
|
v1 := vm.popUint32()
|
|
vm.pushBool(v1 < v2)
|
|
}
|
|
|
|
func (vm *VM) i32GtS() {
|
|
v2 := vm.popInt32()
|
|
v1 := vm.popInt32()
|
|
vm.pushBool(v1 > v2)
|
|
}
|
|
|
|
func (vm *VM) i32GeS() {
|
|
v2 := vm.popInt32()
|
|
v1 := vm.popInt32()
|
|
vm.pushBool(v1 >= v2)
|
|
}
|
|
|
|
func (vm *VM) i32GtU() {
|
|
v2 := vm.popUint32()
|
|
v1 := vm.popUint32()
|
|
vm.pushBool(v1 > v2)
|
|
}
|
|
|
|
func (vm *VM) i32GeU() {
|
|
v2 := vm.popUint32()
|
|
v1 := vm.popUint32()
|
|
vm.pushBool(v1 >= v2)
|
|
}
|
|
|
|
func (vm *VM) i32Eqz() {
|
|
vm.pushBool(vm.popUint32() == 0)
|
|
}
|
|
|
|
func (vm *VM) i32Eq() {
|
|
vm.pushBool(vm.popUint32() == vm.popUint32())
|
|
}
|
|
|
|
func (vm *VM) i32Ne() {
|
|
vm.pushBool(vm.popUint32() != vm.popUint32())
|
|
}
|
|
|
|
// int64 operators
|
|
|
|
func (vm *VM) i64Clz() {
|
|
vm.pushUint64(uint64(bits.LeadingZeros64(vm.popUint64())))
|
|
}
|
|
|
|
func (vm *VM) i64Ctz() {
|
|
vm.pushUint64(uint64(bits.TrailingZeros64(vm.popUint64())))
|
|
}
|
|
|
|
func (vm *VM) i64Popcnt() {
|
|
vm.pushUint64(uint64(bits.OnesCount64(vm.popUint64())))
|
|
}
|
|
|
|
func (vm *VM) i64Add() {
|
|
vm.pushUint64(vm.popUint64() + vm.popUint64())
|
|
}
|
|
|
|
func (vm *VM) i64Sub() {
|
|
v2 := vm.popUint64()
|
|
v1 := vm.popUint64()
|
|
vm.pushUint64(v1 - v2)
|
|
}
|
|
|
|
func (vm *VM) i64Mul() {
|
|
vm.pushUint64(vm.popUint64() * vm.popUint64())
|
|
}
|
|
|
|
func (vm *VM) i64DivS() {
|
|
v2 := vm.popInt64()
|
|
v1 := vm.popInt64()
|
|
vm.pushInt64(v1 / v2)
|
|
}
|
|
|
|
func (vm *VM) i64DivU() {
|
|
v2 := vm.popUint64()
|
|
v1 := vm.popUint64()
|
|
vm.pushUint64(v1 / v2)
|
|
}
|
|
|
|
func (vm *VM) i64RemS() {
|
|
v2 := vm.popInt64()
|
|
v1 := vm.popInt64()
|
|
vm.pushInt64(v1 % v2)
|
|
}
|
|
|
|
func (vm *VM) i64RemU() {
|
|
v2 := vm.popUint64()
|
|
v1 := vm.popUint64()
|
|
vm.pushUint64(v1 % v2)
|
|
}
|
|
|
|
func (vm *VM) i64And() {
|
|
vm.pushUint64(vm.popUint64() & vm.popUint64())
|
|
}
|
|
|
|
func (vm *VM) i64Or() {
|
|
vm.pushUint64(vm.popUint64() | vm.popUint64())
|
|
}
|
|
|
|
func (vm *VM) i64Xor() {
|
|
vm.pushUint64(vm.popUint64() ^ vm.popUint64())
|
|
}
|
|
|
|
func (vm *VM) i64Shl() {
|
|
v2 := vm.popUint64()
|
|
v1 := vm.popUint64()
|
|
vm.pushUint64(v1 << v2)
|
|
}
|
|
|
|
func (vm *VM) i64ShrS() {
|
|
v2 := vm.popUint64()
|
|
v1 := vm.popInt64()
|
|
vm.pushInt64(v1 >> v2)
|
|
}
|
|
|
|
func (vm *VM) i64ShrU() {
|
|
v2 := vm.popUint64()
|
|
v1 := vm.popUint64()
|
|
vm.pushUint64(v1 >> v2)
|
|
}
|
|
|
|
func (vm *VM) i64Rotl() {
|
|
v2 := vm.popInt64()
|
|
v1 := vm.popUint64()
|
|
vm.pushUint64(bits.RotateLeft64(v1, int(v2)))
|
|
}
|
|
|
|
func (vm *VM) i64Rotr() {
|
|
v2 := vm.popInt64()
|
|
v1 := vm.popUint64()
|
|
vm.pushUint64(bits.RotateLeft64(v1, -int(v2)))
|
|
}
|
|
|
|
func (vm *VM) i64Eq() {
|
|
vm.pushBool(vm.popUint64() == vm.popUint64())
|
|
}
|
|
|
|
func (vm *VM) i64Eqz() {
|
|
vm.pushBool(vm.popUint64() == 0)
|
|
}
|
|
|
|
func (vm *VM) i64Ne() {
|
|
vm.pushBool(vm.popUint64() != vm.popUint64())
|
|
}
|
|
|
|
func (vm *VM) i64LtS() {
|
|
v2 := vm.popInt64()
|
|
v1 := vm.popInt64()
|
|
vm.pushBool(v1 < v2)
|
|
}
|
|
|
|
func (vm *VM) i64LtU() {
|
|
v2 := vm.popUint64()
|
|
v1 := vm.popUint64()
|
|
vm.pushBool(v1 < v2)
|
|
}
|
|
|
|
func (vm *VM) i64GtS() {
|
|
v2 := vm.popInt64()
|
|
v1 := vm.popInt64()
|
|
vm.pushBool(v1 > v2)
|
|
}
|
|
|
|
func (vm *VM) i64GtU() {
|
|
v2 := vm.popUint64()
|
|
v1 := vm.popUint64()
|
|
vm.pushBool(v1 > v2)
|
|
}
|
|
|
|
func (vm *VM) i64LeU() {
|
|
v2 := vm.popUint64()
|
|
v1 := vm.popUint64()
|
|
vm.pushBool(v1 <= v2)
|
|
}
|
|
|
|
func (vm *VM) i64LeS() {
|
|
v2 := vm.popInt64()
|
|
v1 := vm.popInt64()
|
|
vm.pushBool(v1 <= v2)
|
|
}
|
|
|
|
func (vm *VM) i64GeS() {
|
|
v2 := vm.popInt64()
|
|
v1 := vm.popInt64()
|
|
vm.pushBool(v1 >= v2)
|
|
}
|
|
|
|
func (vm *VM) i64GeU() {
|
|
v2 := vm.popUint64()
|
|
v1 := vm.popUint64()
|
|
vm.pushBool(v1 >= v2)
|
|
}
|
|
|
|
// float32 operators
|
|
|
|
func (vm *VM) f32Abs() {
|
|
vm.pushFloat32(float32(math.Abs(float64(vm.popFloat32()))))
|
|
}
|
|
|
|
func (vm *VM) f32Neg() {
|
|
vm.pushFloat32(-vm.popFloat32())
|
|
}
|
|
|
|
func (vm *VM) f32Ceil() {
|
|
vm.pushFloat32(float32(math.Ceil(float64(vm.popFloat32()))))
|
|
}
|
|
|
|
func (vm *VM) f32Floor() {
|
|
vm.pushFloat32(float32(math.Floor(float64(vm.popFloat32()))))
|
|
}
|
|
|
|
func (vm *VM) f32Trunc() {
|
|
vm.pushFloat32(float32(math.Trunc(float64(vm.popFloat32()))))
|
|
}
|
|
|
|
func (vm *VM) f32Nearest() {
|
|
f := vm.popFloat32()
|
|
vm.pushFloat32(float32(int32(f + float32(math.Copysign(0.5, float64(f))))))
|
|
}
|
|
|
|
func (vm *VM) f32Sqrt() {
|
|
vm.pushFloat32(float32(math.Sqrt(float64(vm.popFloat32()))))
|
|
}
|
|
|
|
func (vm *VM) f32Add() {
|
|
vm.pushFloat32(vm.popFloat32() + vm.popFloat32())
|
|
}
|
|
|
|
func (vm *VM) f32Sub() {
|
|
v2 := vm.popFloat32()
|
|
v1 := vm.popFloat32()
|
|
vm.pushFloat32(v1 - v2)
|
|
}
|
|
|
|
func (vm *VM) f32Mul() {
|
|
vm.pushFloat32(vm.popFloat32() * vm.popFloat32())
|
|
}
|
|
|
|
func (vm *VM) f32Div() {
|
|
v2 := vm.popFloat32()
|
|
v1 := vm.popFloat32()
|
|
vm.pushFloat32(v1 / v2)
|
|
}
|
|
|
|
func (vm *VM) f32Min() {
|
|
vm.pushFloat32(float32(math.Min(float64(vm.popFloat32()), float64(vm.popFloat32()))))
|
|
}
|
|
|
|
func (vm *VM) f32Max() {
|
|
vm.pushFloat32(float32(math.Max(float64(vm.popFloat32()), float64(vm.popFloat32()))))
|
|
}
|
|
|
|
func (vm *VM) f32Copysign() {
|
|
vm.pushFloat32(float32(math.Copysign(float64(vm.popFloat32()), float64(vm.popFloat32()))))
|
|
}
|
|
|
|
func (vm *VM) f32Eq() {
|
|
vm.pushBool(vm.popFloat32() == vm.popFloat32())
|
|
}
|
|
|
|
func (vm *VM) f32Ne() {
|
|
vm.pushBool(vm.popFloat32() != vm.popFloat32())
|
|
}
|
|
|
|
func (vm *VM) f32Lt() {
|
|
v2 := vm.popFloat32()
|
|
v1 := vm.popFloat32()
|
|
vm.pushBool(v1 < v2)
|
|
}
|
|
|
|
func (vm *VM) f32Gt() {
|
|
v2 := vm.popFloat32()
|
|
v1 := vm.popFloat32()
|
|
vm.pushBool(v1 > v2)
|
|
}
|
|
|
|
func (vm *VM) f32Le() {
|
|
v2 := vm.popFloat32()
|
|
v1 := vm.popFloat32()
|
|
vm.pushBool(v1 <= v2)
|
|
}
|
|
|
|
func (vm *VM) f32Ge() {
|
|
v2 := vm.popFloat32()
|
|
v1 := vm.popFloat32()
|
|
vm.pushBool(v1 >= v2)
|
|
}
|
|
|
|
// float64 operators
|
|
|
|
func (vm *VM) f64Abs() {
|
|
vm.pushFloat64(math.Abs(vm.popFloat64()))
|
|
}
|
|
|
|
func (vm *VM) f64Neg() {
|
|
vm.pushFloat64(-vm.popFloat64())
|
|
}
|
|
|
|
func (vm *VM) f64Ceil() {
|
|
vm.pushFloat64(math.Ceil(vm.popFloat64()))
|
|
}
|
|
|
|
func (vm *VM) f64Floor() {
|
|
vm.pushFloat64(math.Floor(vm.popFloat64()))
|
|
}
|
|
|
|
func (vm *VM) f64Trunc() {
|
|
vm.pushFloat64(math.Trunc(vm.popFloat64()))
|
|
}
|
|
|
|
func (vm *VM) f64Nearest() {
|
|
f := vm.popFloat64()
|
|
vm.pushFloat64(float64(int64(f + math.Copysign(0.5, f))))
|
|
}
|
|
|
|
func (vm *VM) f64Sqrt() {
|
|
vm.pushFloat64(math.Sqrt(vm.popFloat64()))
|
|
}
|
|
|
|
func (vm *VM) f64Add() {
|
|
vm.pushFloat64(vm.popFloat64() + vm.popFloat64())
|
|
}
|
|
|
|
func (vm *VM) f64Sub() {
|
|
v2 := vm.popFloat64()
|
|
v1 := vm.popFloat64()
|
|
vm.pushFloat64(v1 - v2)
|
|
}
|
|
|
|
func (vm *VM) f64Mul() {
|
|
vm.pushFloat64(vm.popFloat64() * vm.popFloat64())
|
|
}
|
|
|
|
func (vm *VM) f64Div() {
|
|
v2 := vm.popFloat64()
|
|
v1 := vm.popFloat64()
|
|
vm.pushFloat64(v1 / v2)
|
|
}
|
|
|
|
func (vm *VM) f64Min() {
|
|
vm.pushFloat64(math.Min(vm.popFloat64(), vm.popFloat64()))
|
|
}
|
|
|
|
func (vm *VM) f64Max() {
|
|
vm.pushFloat64(math.Max(vm.popFloat64(), vm.popFloat64()))
|
|
}
|
|
|
|
func (vm *VM) f64Copysign() {
|
|
vm.pushFloat64(math.Copysign(vm.popFloat64(), vm.popFloat64()))
|
|
}
|
|
|
|
func (vm *VM) f64Eq() {
|
|
vm.pushBool(vm.popFloat64() == vm.popFloat64())
|
|
}
|
|
|
|
func (vm *VM) f64Ne() {
|
|
vm.pushBool(vm.popFloat64() != vm.popFloat64())
|
|
}
|
|
|
|
func (vm *VM) f64Lt() {
|
|
v2 := vm.popFloat64()
|
|
v1 := vm.popFloat64()
|
|
vm.pushBool(v1 < v2)
|
|
}
|
|
|
|
func (vm *VM) f64Gt() {
|
|
v2 := vm.popFloat64()
|
|
v1 := vm.popFloat64()
|
|
vm.pushBool(v1 > v2)
|
|
}
|
|
|
|
func (vm *VM) f64Le() {
|
|
v2 := vm.popFloat64()
|
|
v1 := vm.popFloat64()
|
|
vm.pushBool(v1 <= v2)
|
|
}
|
|
|
|
func (vm *VM) f64Ge() {
|
|
v2 := vm.popFloat64()
|
|
v1 := vm.popFloat64()
|
|
vm.pushBool(v1 >= v2)
|
|
}
|