diff --git a/README.md b/README.md
index c144f4b1..87ed8d82 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,8 @@ A few early examples to get an idea:
[source](./tests/compiler/memcpy.ts) - [wast](./tests/compiler/memcpy.optimized.wast)
* **Conway's Game of Life** as seen on [dcode.io](http://dcode.io)
[source](./tests/compiler/game-of-life.ts) - [wast](./tests/compiler/game-of-life.optimized.wast) - [html](./tests/compiler/game-of-life.html)
+* **i64 polyfill** using 32-bit integers
+ [source](./tests/compiler/i64.ts) - [wast](./tests/compiler/i64.optimized.wast)
Getting started
---------------
@@ -32,7 +34,7 @@ $> cd next
$> npm install
```
-Author your module in AssemblyScript ([definitions](./assembly.d.ts), [base config](./assembly.json)) or portable AssemblyScript ([definitions](./portable.d.ts), [base config](./portable.json) and run:
+Author your module in AssemblyScript ([definitions](./assembly.d.ts), [base config](./assembly.json)) or portable AssemblyScript ([definitions](./portable.d.ts), [base config](./portable.json)) and run:
```
$> node bin\asc yourModule.ts
diff --git a/src/compiler.ts b/src/compiler.ts
index 6ae29ac2..b044b644 100644
--- a/src/compiler.ts
+++ b/src/compiler.ts
@@ -1206,7 +1206,7 @@ export class Compiler extends DiagnosticEmitter {
// i64 to i32
if (!toType.isLongInteger) {
losesInformation = true;
- expr = mod.createUnary(UnaryOp.WrapI64, expr);
+ expr = mod.createUnary(UnaryOp.WrapI64, expr); // discards upper bits
if (toType.isSmallInteger) {
if (toType.isSignedInteger) {
expr = mod.createBinary(BinaryOp.ShlI32, expr, mod.createI32(toType.smallIntegerShift));
diff --git a/tests/compiler/i64.optimized.wast b/tests/compiler/i64.optimized.wast
index fc53cf4a..76f88806 100644
--- a/tests/compiler/i64.optimized.wast
+++ b/tests/compiler/i64.optimized.wast
@@ -1,8 +1,16 @@
(module
+ (type $i (func (result i32)))
+ (type $iiv (func (param i32 i32)))
(type $iiiiv (func (param i32 i32 i32 i32)))
(global $i64/lo (mut i32) (i32.const 0))
(global $i64/hi (mut i32) (i32.const 0))
(memory $0 1)
+ (export "getLo" (func $i64/getLo))
+ (export "getHi" (func $i64/getHi))
+ (export "clz" (func $i64/clz_))
+ (export "ctz" (func $i64/ctz_))
+ (export "popcnt" (func $i64/popcnt_))
+ (export "eqz" (func $i64/eqz))
(export "add" (func $i64/add))
(export "sub" (func $i64/sub))
(export "mul" (func $i64/mul))
@@ -10,30 +18,140 @@
(export "div_u" (func $i64/div_u))
(export "rem_s" (func $i64/rem_s))
(export "rem_u" (func $i64/rem_u))
+ (export "and" (func $i64/and))
+ (export "or" (func $i64/or))
+ (export "xor" (func $i64/xor))
+ (export "shl" (func $i64/shl))
+ (export "shr_u" (func $i64/shr_u))
+ (export "shr_s" (func $i64/shr_s))
+ (export "rotl" (func $i64/rotl_))
+ (export "rotr" (func $i64/rotr_))
+ (export "eq" (func $i64/eq))
+ (export "ne" (func $i64/ne))
+ (export "lt_s" (func $i64/lt_s))
+ (export "lt_u" (func $i64/lt_u))
+ (export "le_s" (func $i64/le_s))
+ (export "le_u" (func $i64/le_u))
+ (export "gt_s" (func $i64/gt_s))
+ (export "gt_u" (func $i64/gt_u))
+ (export "ge_s" (func $i64/ge_s))
+ (export "ge_u" (func $i64/ge_u))
(export "memory" (memory $0))
- (func $i64/add (; 0 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (func $i64/getLo (; 0 ;) (type $i) (result i32)
+ (get_global $i64/lo)
+ )
+ (func $i64/getHi (; 1 ;) (type $i) (result i32)
+ (get_global $i64/hi)
+ )
+ (func $i64/clz_ (; 2 ;) (type $iiv) (param $0 i32) (param $1 i32)
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (i64.clz
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/ctz_ (; 3 ;) (type $iiv) (param $0 i32) (param $1 i32)
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (i64.ctz
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/popcnt_ (; 4 ;) (type $iiv) (param $0 i32) (param $1 i32)
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (i64.popcnt
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/eqz (; 5 ;) (type $iiv) (param $0 i32) (param $1 i32)
+ (set_global $i64/lo
+ (i64.eqz
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/add (; 6 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
(local $4 i64)
(set_global $i64/lo
(i32.wrap/i64
(tee_local $4
(i64.add
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $0)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $1)
)
(i64.const 32)
)
)
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $2)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $3)
)
(i64.const 32)
@@ -52,29 +170,29 @@
)
)
)
- (func $i64/sub (; 1 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (func $i64/sub (; 7 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
(local $4 i64)
(set_global $i64/lo
(i32.wrap/i64
(tee_local $4
(i64.sub
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $0)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $1)
)
(i64.const 32)
)
)
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $2)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $3)
)
(i64.const 32)
@@ -93,29 +211,29 @@
)
)
)
- (func $i64/mul (; 2 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (func $i64/mul (; 8 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
(local $4 i64)
(set_global $i64/lo
(i32.wrap/i64
(tee_local $4
(i64.mul
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $0)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $1)
)
(i64.const 32)
)
)
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $2)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $3)
)
(i64.const 32)
@@ -134,29 +252,29 @@
)
)
)
- (func $i64/div_s (; 3 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (func $i64/div_s (; 9 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
(local $4 i64)
(set_global $i64/lo
(i32.wrap/i64
(tee_local $4
(i64.div_s
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $0)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $1)
)
(i64.const 32)
)
)
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $2)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $3)
)
(i64.const 32)
@@ -175,7 +293,7 @@
)
)
)
- (func $i64/div_u (; 4 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (func $i64/div_u (; 10 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
(local $4 i64)
(set_global $i64/lo
(i32.wrap/i64
@@ -216,29 +334,29 @@
)
)
)
- (func $i64/rem_s (; 5 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (func $i64/rem_s (; 11 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
(local $4 i64)
(set_global $i64/lo
(i32.wrap/i64
(tee_local $4
(i64.rem_s
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $0)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $1)
)
(i64.const 32)
)
)
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $2)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $3)
)
(i64.const 32)
@@ -257,7 +375,7 @@
)
)
)
- (func $i64/rem_u (; 6 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (func $i64/rem_u (; 12 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
(local $4 i64)
(set_global $i64/lo
(i32.wrap/i64
@@ -298,4 +416,642 @@
)
)
)
+ (func $i64/and (; 13 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i64)
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (tee_local $4
+ (i64.and
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.wrap/i64
+ (i64.shr_u
+ (get_local $4)
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (func $i64/or (; 14 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i64)
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (tee_local $4
+ (i64.or
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.wrap/i64
+ (i64.shr_u
+ (get_local $4)
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (func $i64/xor (; 15 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i64)
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (tee_local $4
+ (i64.xor
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.wrap/i64
+ (i64.shr_u
+ (get_local $4)
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (func $i64/shl (; 16 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i64)
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (tee_local $4
+ (i64.shl
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.wrap/i64
+ (i64.shr_u
+ (get_local $4)
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (func $i64/shr_u (; 17 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i64)
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (tee_local $4
+ (i64.shr_u
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.wrap/i64
+ (i64.shr_u
+ (get_local $4)
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (func $i64/shr_s (; 18 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i64)
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (tee_local $4
+ (i64.shr_s
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.wrap/i64
+ (i64.shr_u
+ (get_local $4)
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (func $i64/rotl_ (; 19 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i64)
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (tee_local $4
+ (i64.rotl
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.wrap/i64
+ (i64.shr_u
+ (get_local $4)
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (func $i64/rotr_ (; 20 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i64)
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (tee_local $4
+ (i64.rotr
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.wrap/i64
+ (i64.shr_u
+ (get_local $4)
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (func $i64/eq (; 21 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (set_global $i64/lo
+ (i64.eq
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/ne (; 22 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (set_global $i64/lo
+ (i64.ne
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/lt_s (; 23 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (set_global $i64/lo
+ (i64.lt_s
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/lt_u (; 24 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (set_global $i64/lo
+ (i64.lt_u
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/le_s (; 25 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (set_global $i64/lo
+ (i64.le_s
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/le_u (; 26 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (set_global $i64/lo
+ (i64.le_u
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/gt_s (; 27 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (set_global $i64/lo
+ (i64.gt_s
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/gt_u (; 28 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (set_global $i64/lo
+ (i64.gt_u
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/ge_s (; 29 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (set_global $i64/lo
+ (i64.ge_s
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/ge_u (; 30 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (set_global $i64/lo
+ (i64.ge_u
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
)
diff --git a/tests/compiler/i64.ts b/tests/compiler/i64.ts
index fb4cc374..c5cc4cc6 100644
--- a/tests/compiler/i64.ts
+++ b/tests/compiler/i64.ts
@@ -1,40 +1,75 @@
let lo: u32;
let hi: u32;
-export function add(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
- const ret: i64 = (loLeft | hiLeft << 32) + (loRight | hiRight << 32);
+export function getLo(): u32 {
+ return lo;
+}
+
+export function getHi(): u32 {
+ return hi;
+}
+
+function clz_(loLeft: u32, hiLeft: u32): void {
+ const ret: u64 = clz(loLeft | hiLeft << 32);
lo = ret;
- hi = (ret >>> 32);
+ hi = 0;
+}
+export { clz_ as clz };
+
+function ctz_(loLeft: u32, hiLeft: u32): void {
+ const ret: u64 = ctz(loLeft | hiLeft << 32);
+ lo = ret;
+ hi = 0;
+}
+export { ctz_ as ctz };
+
+function popcnt_(loLeft: u32, hiLeft: u32): void {
+ const ret: u64 = popcnt(loLeft | hiLeft << 32);
+ lo = ret;
+ hi = 0;
+}
+export { popcnt_ as popcnt };
+
+export function eqz(loLeft: u32, hiLeft: u32): void {
+ const ret: bool = !(loLeft | hiLeft << 32);
+ lo = ret;
+ hi = 0;
+}
+
+export function add(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: u64 = (loLeft | hiLeft << 32) + (loRight | hiRight << 32);
+ lo = ret;
+ hi = (ret >> 32);
}
export function sub(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
- const ret: i64 = (loLeft | hiLeft << 32) - (loRight | hiRight << 32);
+ const ret: u64 = (loLeft | hiLeft << 32) - (loRight | hiRight << 32);
lo = ret;
- hi = (ret >>> 32);
+ hi = (ret >> 32);
}
export function mul(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
- const ret: i64 = (loLeft | hiLeft << 32) * (loRight | hiRight << 32);
+ const ret: u64 = (loLeft | hiLeft << 32) * (loRight | hiRight << 32);
lo = ret;
- hi = (ret >>> 32);
+ hi = (ret >> 32);
}
export function div_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
- const ret: i64 = (loLeft | hiLeft << 32) / (loRight | hiRight << 32);
+ const ret: u64 = ((loLeft | hiLeft << 32) / (loRight | hiRight << 32));
lo = ret;
- hi = (ret >>> 32);
+ hi = (ret >> 32);
}
export function div_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
const ret: u64 = (loLeft | hiLeft << 32) / (loRight | hiRight << 32);
lo = ret;
- hi = (ret >>> 32);
+ hi = (ret >> 32);
}
export function rem_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
- const ret: i64 = (loLeft | hiLeft << 32) % (loRight | hiRight << 32);
+ const ret: u64 = ((loLeft | hiLeft << 32) % (loRight | hiRight << 32));
lo = ret;
- hi = (ret >>> 32);
+ hi = (ret >> 32);
}
export function rem_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
@@ -42,3 +77,113 @@ export function rem_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): voi
lo = ret;
hi = (ret >>> 32);
}
+
+export function and(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: u64 = (loLeft | hiLeft << 32) & (loRight | hiRight << 32);
+ lo = ret;
+ hi = (ret >>> 32);
+}
+
+export function or(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: u64 = (loLeft | hiLeft << 32) | (loRight | hiRight << 32);
+ lo = ret;
+ hi = (ret >>> 32);
+}
+
+export function xor(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: u64 = (loLeft | hiLeft << 32) ^ (loRight | hiRight << 32);
+ lo = ret;
+ hi = (ret >>> 32);
+}
+
+export function shl(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: u64 = (loLeft | hiLeft << 32) << (loRight | hiRight << 32);
+ lo = ret;
+ hi = (ret >>> 32);
+}
+
+export function shr_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: u64 = (loLeft | hiLeft << 32) >> (loRight | hiRight << 32);
+ lo = ret;
+ hi = (ret >>> 32);
+}
+
+export function shr_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: u64 = ((loLeft | hiLeft << 32) >> (loRight | hiRight << 32));
+ lo = ret;
+ hi = (ret >>> 32);
+}
+
+function rotl_(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: u64 = rotl(loLeft | hiLeft << 32, loRight | hiRight << 32);
+ lo = ret;
+ hi = (ret >>> 32);
+}
+export { rotl_ as rotl };
+
+function rotr_(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: u64 = rotr(loLeft | hiLeft << 32, loRight | hiRight << 32);
+ lo = ret;
+ hi = (ret >>> 32);
+}
+export { rotr_ as rotr };
+
+export function eq(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: bool = (loLeft | hiLeft << 32) == (loRight | hiRight << 32);
+ lo = ret;
+ hi = 0;
+}
+
+export function ne(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: bool = (loLeft | hiLeft << 32) != (loRight | hiRight << 32);
+ lo = ret;
+ hi = 0;
+}
+
+export function lt_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: bool = (loLeft | hiLeft << 32) < (loRight | hiRight << 32);
+ lo = ret;
+ hi = 0;
+}
+
+export function lt_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: bool = (loLeft | hiLeft << 32) < (loRight | hiRight << 32);
+ lo = ret;
+ hi = 0;
+}
+
+export function le_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: bool = (loLeft | hiLeft << 32) <= (loRight | hiRight << 32);
+ lo = ret;
+ hi = 0;
+}
+
+export function le_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: bool = (loLeft | hiLeft << 32) <= (loRight | hiRight << 32);
+ lo = ret;
+ hi = 0;
+}
+
+export function gt_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: bool = (loLeft | hiLeft << 32) > (loRight | hiRight << 32);
+ lo = ret;
+ hi = 0;
+}
+
+export function gt_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: bool = (loLeft | hiLeft << 32) > (loRight | hiRight << 32);
+ lo = ret;
+ hi = 0;
+}
+
+export function ge_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: bool = (loLeft | hiLeft << 32) >= (loRight | hiRight << 32);
+ lo = ret;
+ hi = 0;
+}
+
+export function ge_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
+ const ret: bool = (loLeft | hiLeft << 32) >= (loRight | hiRight << 32);
+ lo = ret;
+ hi = 0;
+}
diff --git a/tests/compiler/i64.wast b/tests/compiler/i64.wast
index 901224e5..5f171edf 100644
--- a/tests/compiler/i64.wast
+++ b/tests/compiler/i64.wast
@@ -1,9 +1,17 @@
(module
+ (type $i (func (result i32)))
+ (type $iiv (func (param i32 i32)))
(type $iiiiv (func (param i32 i32 i32 i32)))
(global $i64/lo (mut i32) (i32.const 0))
(global $i64/hi (mut i32) (i32.const 0))
(global $HEAP_START i32 (i32.const 4))
(memory $0 1)
+ (export "getLo" (func $i64/getLo))
+ (export "getHi" (func $i64/getHi))
+ (export "clz" (func $i64/clz_))
+ (export "ctz" (func $i64/ctz_))
+ (export "popcnt" (func $i64/popcnt_))
+ (export "eqz" (func $i64/eqz))
(export "add" (func $i64/add))
(export "sub" (func $i64/sub))
(export "mul" (func $i64/mul))
@@ -11,29 +19,167 @@
(export "div_u" (func $i64/div_u))
(export "rem_s" (func $i64/rem_s))
(export "rem_u" (func $i64/rem_u))
+ (export "and" (func $i64/and))
+ (export "or" (func $i64/or))
+ (export "xor" (func $i64/xor))
+ (export "shl" (func $i64/shl))
+ (export "shr_u" (func $i64/shr_u))
+ (export "shr_s" (func $i64/shr_s))
+ (export "rotl" (func $i64/rotl_))
+ (export "rotr" (func $i64/rotr_))
+ (export "eq" (func $i64/eq))
+ (export "ne" (func $i64/ne))
+ (export "lt_s" (func $i64/lt_s))
+ (export "lt_u" (func $i64/lt_u))
+ (export "le_s" (func $i64/le_s))
+ (export "le_u" (func $i64/le_u))
+ (export "gt_s" (func $i64/gt_s))
+ (export "gt_u" (func $i64/gt_u))
+ (export "ge_s" (func $i64/ge_s))
+ (export "ge_u" (func $i64/ge_u))
(export "memory" (memory $0))
- (func $i64/add (; 0 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (func $i64/getLo (; 0 ;) (type $i) (result i32)
+ (return
+ (get_global $i64/lo)
+ )
+ )
+ (func $i64/getHi (; 1 ;) (type $i) (result i32)
+ (return
+ (get_global $i64/hi)
+ )
+ )
+ (func $i64/clz_ (; 2 ;) (type $iiv) (param $0 i32) (param $1 i32)
+ (local $2 i64)
+ (block
+ (set_local $2
+ (i64.clz
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (get_local $2)
+ )
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/ctz_ (; 3 ;) (type $iiv) (param $0 i32) (param $1 i32)
+ (local $2 i64)
+ (block
+ (set_local $2
+ (i64.ctz
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (get_local $2)
+ )
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/popcnt_ (; 4 ;) (type $iiv) (param $0 i32) (param $1 i32)
+ (local $2 i64)
+ (block
+ (set_local $2
+ (i64.popcnt
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (get_local $2)
+ )
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/eqz (; 5 ;) (type $iiv) (param $0 i32) (param $1 i32)
+ (local $2 i32)
+ (block
+ (set_local $2
+ (i64.eqz
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (get_local $2)
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/add (; 6 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
(local $4 i64)
(block
(set_local $4
(i64.add
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $0)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $1)
)
(i64.const 32)
)
)
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $2)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $3)
)
(i64.const 32)
@@ -56,28 +202,28 @@
)
)
)
- (func $i64/sub (; 1 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (func $i64/sub (; 7 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
(local $4 i64)
(block
(set_local $4
(i64.sub
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $0)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $1)
)
(i64.const 32)
)
)
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $2)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $3)
)
(i64.const 32)
@@ -100,28 +246,28 @@
)
)
)
- (func $i64/mul (; 2 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (func $i64/mul (; 8 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
(local $4 i64)
(block
(set_local $4
(i64.mul
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $0)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $1)
)
(i64.const 32)
)
)
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $2)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $3)
)
(i64.const 32)
@@ -144,28 +290,28 @@
)
)
)
- (func $i64/div_s (; 3 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (func $i64/div_s (; 9 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
(local $4 i64)
(block
(set_local $4
(i64.div_s
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $0)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $1)
)
(i64.const 32)
)
)
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $2)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $3)
)
(i64.const 32)
@@ -188,7 +334,7 @@
)
)
)
- (func $i64/div_u (; 4 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (func $i64/div_u (; 10 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
(local $4 i64)
(block
(set_local $4
@@ -232,28 +378,28 @@
)
)
)
- (func $i64/rem_s (; 5 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (func $i64/rem_s (; 11 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
(local $4 i64)
(block
(set_local $4
(i64.rem_s
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $0)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $1)
)
(i64.const 32)
)
)
(i64.or
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $2)
)
(i64.shl
- (i64.extend_s/i32
+ (i64.extend_u/i32
(get_local $3)
)
(i64.const 32)
@@ -276,7 +422,7 @@
)
)
)
- (func $i64/rem_u (; 6 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (func $i64/rem_u (; 12 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
(local $4 i64)
(block
(set_local $4
@@ -320,6 +466,728 @@
)
)
)
+ (func $i64/and (; 13 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i64)
+ (block
+ (set_local $4
+ (i64.and
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (get_local $4)
+ )
+ )
+ (set_global $i64/hi
+ (i32.wrap/i64
+ (i64.shr_u
+ (get_local $4)
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (func $i64/or (; 14 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i64)
+ (block
+ (set_local $4
+ (i64.or
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (get_local $4)
+ )
+ )
+ (set_global $i64/hi
+ (i32.wrap/i64
+ (i64.shr_u
+ (get_local $4)
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (func $i64/xor (; 15 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i64)
+ (block
+ (set_local $4
+ (i64.xor
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (get_local $4)
+ )
+ )
+ (set_global $i64/hi
+ (i32.wrap/i64
+ (i64.shr_u
+ (get_local $4)
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (func $i64/shl (; 16 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i64)
+ (block
+ (set_local $4
+ (i64.shl
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (get_local $4)
+ )
+ )
+ (set_global $i64/hi
+ (i32.wrap/i64
+ (i64.shr_u
+ (get_local $4)
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (func $i64/shr_u (; 17 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i64)
+ (block
+ (set_local $4
+ (i64.shr_u
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (get_local $4)
+ )
+ )
+ (set_global $i64/hi
+ (i32.wrap/i64
+ (i64.shr_u
+ (get_local $4)
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (func $i64/shr_s (; 18 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i64)
+ (block
+ (set_local $4
+ (i64.shr_s
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (get_local $4)
+ )
+ )
+ (set_global $i64/hi
+ (i32.wrap/i64
+ (i64.shr_u
+ (get_local $4)
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (func $i64/rotl_ (; 19 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i64)
+ (block
+ (set_local $4
+ (i64.rotl
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (get_local $4)
+ )
+ )
+ (set_global $i64/hi
+ (i32.wrap/i64
+ (i64.shr_u
+ (get_local $4)
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (func $i64/rotr_ (; 20 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i64)
+ (block
+ (set_local $4
+ (i64.rotr
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (i32.wrap/i64
+ (get_local $4)
+ )
+ )
+ (set_global $i64/hi
+ (i32.wrap/i64
+ (i64.shr_u
+ (get_local $4)
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ (func $i64/eq (; 21 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i32)
+ (block
+ (set_local $4
+ (i64.eq
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (get_local $4)
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/ne (; 22 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i32)
+ (block
+ (set_local $4
+ (i64.ne
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (get_local $4)
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/lt_s (; 23 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i32)
+ (block
+ (set_local $4
+ (i64.lt_s
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (get_local $4)
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/lt_u (; 24 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i32)
+ (block
+ (set_local $4
+ (i64.lt_u
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (get_local $4)
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/le_s (; 25 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i32)
+ (block
+ (set_local $4
+ (i64.le_s
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (get_local $4)
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/le_u (; 26 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i32)
+ (block
+ (set_local $4
+ (i64.le_u
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (get_local $4)
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/gt_s (; 27 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i32)
+ (block
+ (set_local $4
+ (i64.gt_s
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (get_local $4)
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/gt_u (; 28 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i32)
+ (block
+ (set_local $4
+ (i64.gt_u
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (get_local $4)
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/ge_s (; 29 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i32)
+ (block
+ (set_local $4
+ (i64.ge_s
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (get_local $4)
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
+ (func $i64/ge_u (; 30 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ (local $4 i32)
+ (block
+ (set_local $4
+ (i64.ge_u
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $0)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.const 32)
+ )
+ )
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $3)
+ )
+ (i64.const 32)
+ )
+ )
+ )
+ )
+ )
+ (set_global $i64/lo
+ (get_local $4)
+ )
+ (set_global $i64/hi
+ (i32.const 0)
+ )
+ )
)
(;
[program.elements]
@@ -351,6 +1219,12 @@
assert
i64/lo
i64/hi
+ i64/getLo
+ i64/getHi
+ i64/clz_
+ i64/ctz_
+ i64/popcnt_
+ i64/eqz
i64/add
i64/sub
i64/mul
@@ -358,7 +1232,31 @@
i64/div_u
i64/rem_s
i64/rem_u
+ i64/and
+ i64/or
+ i64/xor
+ i64/shl
+ i64/shr_u
+ i64/shr_s
+ i64/rotl_
+ i64/rotr_
+ i64/eq
+ i64/ne
+ i64/lt_s
+ i64/lt_u
+ i64/le_s
+ i64/le_u
+ i64/gt_s
+ i64/gt_u
+ i64/ge_s
+ i64/ge_u
[program.exports]
+ i64/getLo
+ i64/getHi
+ i64/clz
+ i64/ctz
+ i64/popcnt
+ i64/eqz
i64/add
i64/sub
i64/mul
@@ -366,4 +1264,22 @@
i64/div_u
i64/rem_s
i64/rem_u
+ i64/and
+ i64/or
+ i64/xor
+ i64/shl
+ i64/shr_u
+ i64/shr_s
+ i64/rotl
+ i64/rotr
+ i64/eq
+ i64/ne
+ i64/lt_s
+ i64/lt_u
+ i64/le_s
+ i64/le_u
+ i64/gt_s
+ i64/gt_u
+ i64/ge_s
+ i64/ge_u
;)
diff --git a/tests/compiler/memcpy.optimized.wast b/tests/compiler/memcpy.optimized.wast
index c17d2aca..549bd57e 100644
--- a/tests/compiler/memcpy.optimized.wast
+++ b/tests/compiler/memcpy.optimized.wast
@@ -1,7 +1,7 @@
(module
(type $iiii (func (param i32 i32 i32) (result i32)))
(type $v (func))
- (global $memcpy/dst (mut i32) (i32.const 0))
+ (global $memcpy/dest (mut i32) (i32.const 0))
(memory $0 1)
(export "memcpy" (func $memcpy/memcpy))
(export "memory" (memory $0))
@@ -1588,7 +1588,7 @@
(i32.const 32)
(i64.const 4919131752989213764)
)
- (set_global $memcpy/dst
+ (set_global $memcpy/dest
(call $memcpy/memcpy
(i32.const 9)
(i32.const 24)
@@ -1597,7 +1597,7 @@
)
(if
(i32.ne
- (get_global $memcpy/dst)
+ (get_global $memcpy/dest)
(i32.const 9)
)
(unreachable)
@@ -1611,7 +1611,7 @@
)
(unreachable)
)
- (set_global $memcpy/dst
+ (set_global $memcpy/dest
(call $memcpy/memcpy
(i32.const 8)
(i32.const 8)
@@ -1620,7 +1620,7 @@
)
(if
(i32.ne
- (get_global $memcpy/dst)
+ (get_global $memcpy/dest)
(i32.const 8)
)
(unreachable)
@@ -1661,7 +1661,7 @@
)
(unreachable)
)
- (set_global $memcpy/dst
+ (set_global $memcpy/dest
(call $memcpy/memcpy
(i32.const 13)
(i32.const 36)
@@ -1677,7 +1677,7 @@
)
(unreachable)
)
- (set_global $memcpy/dst
+ (set_global $memcpy/dest
(call $memcpy/memcpy
(i32.const 16)
(i32.const 24)
diff --git a/tests/compiler/memcpy.ts b/tests/compiler/memcpy.ts
index 253e4b8a..985105e1 100644
--- a/tests/compiler/memcpy.ts
+++ b/tests/compiler/memcpy.ts
@@ -9,7 +9,7 @@ export function memcpy(dest: usize, src: usize, n: usize): usize {
n--;
}
- // if dst is aligned to 4 bytes as well, copy 4 bytes each
+ // if dest is aligned to 4 bytes as well, copy 4 bytes each
if (d % 4 == 0) {
while (n >= 16) {
store(d , load(s ));
@@ -27,7 +27,7 @@ export function memcpy(dest: usize, src: usize, n: usize): usize {
store(d, load(s));
d += 4; s += 4;
}
- if (n & 2) { // drop to 2 bytes each
+ if (n & 2) { // drop to 2 bytes
store(d, load(s));
d += 2; s += 2;
}
@@ -37,7 +37,7 @@ export function memcpy(dest: usize, src: usize, n: usize): usize {
return dest;
}
- // if dst is not aligned to 4 bytes, use alternating shifts to copy 4 bytes each
+ // if dest is not aligned to 4 bytes, use alternating shifts to copy 4 bytes each
// doing shifts if faster when copying enough bytes (here: 32 or more)
if (n >= 32) {
switch (d % 4) {
@@ -147,22 +147,22 @@ store(base + 8 , 0x2222222222222222);
store(base + 16, 0x3333333333333333);
store(base + 24, 0x4444444444444444);
-let dst: usize;
-dst = memcpy(base + 1, base + 16, 4);
-assert(dst == base + 1);
+let dest: usize;
+dest = memcpy(base + 1, base + 16, 4);
+assert(dest == base + 1);
assert(load(base) == 0x1111113333333311);
-dst = memcpy(base, base, 32);
-assert(dst == base);
+dest = memcpy(base, base, 32);
+assert(dest == base);
assert(load(base) == 0x1111113333333311);
assert(load(base + 8) == 0x2222222222222222);
assert(load(base + 16) == 0x3333333333333333);
assert(load(base + 24) == 0x4444444444444444);
-dst = memcpy(base + 5, base + 28, 3);
+dest = memcpy(base + 5, base + 28, 3);
assert(load(base) == 0x4444443333333311);
-dst = memcpy(base + 8, base + 16, 15);
+dest = memcpy(base + 8, base + 16, 15);
assert(load(base) == 0x4444443333333311);
assert(load(base + 8) == 0x3333333333333333);
assert(load(base + 16) == 0x3344444444444444);
diff --git a/tests/compiler/memcpy.wast b/tests/compiler/memcpy.wast
index 4e17cfd0..f73c111a 100644
--- a/tests/compiler/memcpy.wast
+++ b/tests/compiler/memcpy.wast
@@ -2,7 +2,7 @@
(type $iiii (func (param i32 i32 i32) (result i32)))
(type $v (func))
(global $memcpy/base i32 (i32.const 8))
- (global $memcpy/dst (mut i32) (i32.const 0))
+ (global $memcpy/dest (mut i32) (i32.const 0))
(global $HEAP_START i32 (i32.const 4))
(memory $0 1)
(export "memcpy" (func $memcpy/memcpy))
@@ -1936,7 +1936,7 @@
)
(i64.const 4919131752989213764)
)
- (set_global $memcpy/dst
+ (set_global $memcpy/dest
(call $memcpy/memcpy
(i32.add
(i32.const 8)
@@ -1952,7 +1952,7 @@
(if
(i32.eqz
(i32.eq
- (get_global $memcpy/dst)
+ (get_global $memcpy/dest)
(i32.add
(i32.const 8)
(i32.const 1)
@@ -1972,7 +1972,7 @@
)
(unreachable)
)
- (set_global $memcpy/dst
+ (set_global $memcpy/dest
(call $memcpy/memcpy
(i32.const 8)
(i32.const 8)
@@ -1982,7 +1982,7 @@
(if
(i32.eqz
(i32.eq
- (get_global $memcpy/dst)
+ (get_global $memcpy/dest)
(i32.const 8)
)
)
@@ -2041,7 +2041,7 @@
)
(unreachable)
)
- (set_global $memcpy/dst
+ (set_global $memcpy/dest
(call $memcpy/memcpy
(i32.add
(i32.const 8)
@@ -2065,7 +2065,7 @@
)
(unreachable)
)
- (set_global $memcpy/dst
+ (set_global $memcpy/dest
(call $memcpy/memcpy
(i32.add
(i32.const 8)
@@ -2163,7 +2163,7 @@
assert
memcpy/memcpy
memcpy/base
- memcpy/dst
+ memcpy/dest
[program.exports]
memcpy/memcpy
;)