From 09cbad6ede3746ad38ce5945ea6a600e739a5e47 Mon Sep 17 00:00:00 2001 From: dcodeIO Date: Mon, 11 Dec 2017 22:04:30 +0100 Subject: [PATCH] Add i64 polyfill example --- README.md | 4 +- src/compiler.ts | 2 +- tests/compiler/i64.optimized.wast | 810 +++++++++++++++++++++- tests/compiler/i64.ts | 169 ++++- tests/compiler/i64.wast | 970 ++++++++++++++++++++++++++- tests/compiler/memcpy.optimized.wast | 14 +- tests/compiler/memcpy.ts | 20 +- tests/compiler/memcpy.wast | 16 +- 8 files changed, 1912 insertions(+), 93 deletions(-) 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 ;)