diff --git a/std/assembly/polyfills.ts b/std/assembly/polyfills.ts index 919ff472..77228ec3 100644 --- a/std/assembly/polyfills.ts +++ b/std/assembly/polyfills.ts @@ -1,33 +1,40 @@ export function bswap(value: T): T { - assert(sizeof() == 1 || sizeof() == 2 || sizeof() == 4 || sizeof() == 8); + if (isInteger()) { + if (sizeof() == 2) { + return ((value << 8) | ((value >> 8) & 0x00FF)); + } + if (sizeof() == 4) { + return ( + rotl(value & 0xFF00FF00, 8) | + rotr(value & 0x00FF00FF, 8) + ); + } + if (sizeof() == 8) { + let a = (value >> 8) & 0x00FF00FF00FF00FF; + let b = (value & 0x00FF00FF00FF00FF) << 8; + let v = a | b; - if (sizeof() == 2) { - return bswap16(value); - } - if (sizeof() == 4) { - return ( - rotl(value & 0xFF00FF00, 8) | - rotr(value & 0x00FF00FF, 8) - ); - } - if (sizeof() == 8) { - let a: u64 = (value >> 8) & 0x00FF00FF00FF00FF; - let b: u64 = (value & 0x00FF00FF00FF00FF) << 8; - let v: u64 = a | b; + a = (v >> 16) & 0x0000FFFF0000FFFF; + b = (v & 0x0000FFFF0000FFFF) << 16; - a = (v >> 16) & 0x0000FFFF0000FFFF; - b = (v & 0x0000FFFF0000FFFF) << 16; - - return rotr(a | b, 32); + return rotr(a | b, 32); + } + return value; } + assert(false); return value; } +@inline export function bswap16(value: T): T { - assert(sizeof() == 1 || sizeof() == 2 || sizeof() == 4); - - if (sizeof() == 2 || sizeof() == 4) { - return (((value << 8) & 0xFF00) | ((value >> 8) & 0x00FF) | (value & 0xFFFF0000)); + if (isInteger() && sizeof() <= 4) { + if (sizeof() == 2) { + return ((value << 8) | ((value >> 8) & 0x00FF)); + } else if (sizeof() == 4) { + return (((value << 8) & 0xFF00) | ((value >> 8) & 0x00FF) | (value & 0xFFFF0000)); + } + return value; } + assert(false); return value; } diff --git a/tests/compiler/std/polyfills.optimized.wat b/tests/compiler/std/polyfills.optimized.wat index 1f970123..e21dfcae 100644 --- a/tests/compiler/std/polyfills.optimized.wat +++ b/tests/compiler/std/polyfills.optimized.wat @@ -1,159 +1,12 @@ (module - (type $ii (func (param i32) (result i32))) - (type $iiiiv (func (param i32 i32 i32 i32))) (type $v (func)) - (import "env" "abort" (func $~lib/env/abort (param i32 i32 i32 i32))) (memory $0 1) - (data (i32.const 8) "\11\00\00\00~\00l\00i\00b\00/\00p\00o\00l\00y\00f\00i\00l\00l\00s\00.\00t\00s") - (data (i32.const 48) "\10\00\00\00s\00t\00d\00/\00p\00o\00l\00y\00f\00i\00l\00l\00s\00.\00t\00s") + (data (i32.const 8) "\10\00\00\00s\00t\00d\00/\00p\00o\00l\00y\00f\00i\00l\00l\00s\00.\00t\00s") (table $0 1 anyfunc) - (elem (i32.const 0) $null) + (elem (i32.const 0) $start) (export "memory" (memory $0)) (export "table" (table $0)) - (start $start) - (func $~lib/polyfills/bswap16 (; 1 ;) (type $ii) (param $0 i32) (result i32) - (local $1 i32) - i32.const 1 - tee_local $1 - i32.eqz - if - i32.const 0 - set_local $1 - end - get_local $1 - i32.eqz - if - i32.const 0 - i32.const 8 - i32.const 27 - i32.const 2 - call $~lib/env/abort - unreachable - end - i32.const 1 - tee_local $1 - if - get_local $0 - i32.const 8 - i32.shl - i32.const 65280 - i32.and - get_local $0 - i32.const 65535 - i32.and - i32.const 8 - i32.shr_u - i32.or - get_local $0 - i32.const -65536 - i32.and - i32.or - return - end - get_local $0 - ) - (func $~lib/polyfills/bswap16 (; 2 ;) (type $ii) (param $0 i32) (result i32) - (local $1 i32) - i32.const 1 - tee_local $1 - i32.eqz - if - i32.const 0 - set_local $1 - end - get_local $1 - i32.eqz - if - i32.const 0 - i32.const 8 - i32.const 27 - i32.const 2 - call $~lib/env/abort - unreachable - end - i32.const 1 - tee_local $1 - if - get_local $0 - i32.const 8 - i32.shl - i32.const 65280 - i32.and - get_local $0 - i32.const 16 - i32.shl - i32.const 24 - i32.shr_s - i32.const 255 - i32.and - i32.or - get_local $0 - i32.const -65536 - i32.and - i32.or - return - end - get_local $0 - ) - (func $start (; 3 ;) (type $v) - i32.const 43707 - call $~lib/polyfills/bswap16 - i32.const 65535 - i32.and - i32.const 48042 - i32.ne - if - i32.const 0 - i32.const 48 - i32.const 4 - i32.const 0 - call $~lib/env/abort - unreachable - end - i32.const 43707 - call $~lib/polyfills/bswap16 - i32.const 65535 - i32.and - i32.const 48042 - i32.ne - if - i32.const 0 - i32.const 48 - i32.const 5 - i32.const 0 - call $~lib/env/abort - unreachable - end - i32.const 43707 - call $~lib/polyfills/bswap16 - i32.const 65535 - i32.and - i32.const 48042 - i32.ne - if - i32.const 0 - i32.const 48 - i32.const 20 - i32.const 0 - call $~lib/env/abort - unreachable - end - i32.const 43707 - call $~lib/polyfills/bswap16 - i32.const 65535 - i32.and - i32.const 48042 - i32.ne - if - i32.const 0 - i32.const 48 - i32.const 21 - i32.const 0 - call $~lib/env/abort - unreachable - end - ) - (func $null (; 4 ;) (type $v) + (func $start (; 0 ;) (type $v) nop ) ) diff --git a/tests/compiler/std/polyfills.ts b/tests/compiler/std/polyfills.ts index 24a0a10a..c19a05bd 100644 --- a/tests/compiler/std/polyfills.ts +++ b/tests/compiler/std/polyfills.ts @@ -1,5 +1,9 @@ // bswap / bswap16 tests +// check bswap for i8/u8 +assert(bswap(0xaa) == 0xaa); +assert(bswap(0xaa) == 0xaa); + // check bswap for i16/u16 assert(bswap(0xaabb) == 0xbbaa); assert(bswap(0xaabb) == 0xbbaa); @@ -16,6 +20,10 @@ assert(bswap(0x00112233aabbccdd) == 0xddccbbaa33221100); assert(bswap(0xaabbccdd) == 0xddccbbaa); assert(bswap(0xaabbccdd) == 0xddccbbaa); +// check bswap16 for i8/u8 +assert(bswap16(0xaa) == 0xaa); +assert(bswap16(0xaa) == 0xaa); + // check bswap16 for i16/u16 assert(bswap16(0xaabb) == 0xbbaa); assert(bswap16(0xaabb) == 0xbbaa); diff --git a/tests/compiler/std/polyfills.untouched.wat b/tests/compiler/std/polyfills.untouched.wat index 4d39ef52..9c4fa2ac 100644 --- a/tests/compiler/std/polyfills.untouched.wat +++ b/tests/compiler/std/polyfills.untouched.wat @@ -5,264 +5,52 @@ (type $v (func)) (import "env" "abort" (func $~lib/env/abort (param i32 i32 i32 i32))) (memory $0 1) - (data (i32.const 8) "\11\00\00\00~\00l\00i\00b\00/\00p\00o\00l\00y\00f\00i\00l\00l\00s\00.\00t\00s\00") - (data (i32.const 48) "\10\00\00\00s\00t\00d\00/\00p\00o\00l\00y\00f\00i\00l\00l\00s\00.\00t\00s\00") + (data (i32.const 8) "\10\00\00\00s\00t\00d\00/\00p\00o\00l\00y\00f\00i\00l\00l\00s\00.\00t\00s\00") (table $0 1 anyfunc) (elem (i32.const 0) $null) - (global $HEAP_BASE i32 (i32.const 84)) + (global $HEAP_BASE i32 (i32.const 44)) (export "memory" (memory $0)) (export "table" (table $0)) (start $start) - (func $~lib/polyfills/bswap16 (; 1 ;) (type $ii) (param $0 i32) (result i32) - (local $1 i32) - i32.const 2 - i32.const 1 - i32.eq - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 2 - i32.const 2 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 2 - i32.const 4 - i32.eq - end - i32.eqz - if - i32.const 0 - i32.const 8 - i32.const 27 - i32.const 2 - call $~lib/env/abort - unreachable - end - i32.const 2 - i32.const 2 - i32.eq - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 2 - i32.const 4 - i32.eq - end - if - get_local $0 - i32.const 8 - i32.shl - i32.const 65280 - i32.and - get_local $0 - i32.const 65535 - i32.and - i32.const 8 - i32.shr_u - i32.const 255 - i32.and - i32.or - get_local $0 - i32.const -65536 - i32.and - i32.or - return - end + (func $~lib/polyfills/bswap (; 1 ;) (type $ii) (param $0 i32) (result i32) get_local $0 - ) - (func $~lib/polyfills/bswap (; 2 ;) (type $ii) (param $0 i32) (result i32) - (local $1 i32) - i32.const 2 - i32.const 1 - i32.eq - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 2 - i32.const 2 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 2 - i32.const 4 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 2 - i32.const 8 - i32.eq - end - i32.eqz - if - i32.const 0 - i32.const 8 - i32.const 2 - i32.const 2 - call $~lib/env/abort - unreachable - end - get_local $0 - call $~lib/polyfills/bswap16 return ) - (func $~lib/polyfills/bswap16 (; 3 ;) (type $ii) (param $0 i32) (result i32) - (local $1 i32) - i32.const 2 - i32.const 1 - i32.eq - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 2 - i32.const 2 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 2 - i32.const 4 - i32.eq - end - i32.eqz - if - i32.const 0 - i32.const 8 - i32.const 27 - i32.const 2 - call $~lib/env/abort - unreachable - end - i32.const 2 - i32.const 2 - i32.eq - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 2 - i32.const 4 - i32.eq - end - if - get_local $0 - i32.const 8 - i32.shl - i32.const 65280 - i32.and - get_local $0 - i32.const 16 - i32.shl - i32.const 16 - i32.shr_s - i32.const 8 - i32.shr_s - i32.const 255 - i32.and - i32.or - get_local $0 - i32.const -65536 - i32.and - i32.or - return - end + (func $~lib/polyfills/bswap (; 2 ;) (type $ii) (param $0 i32) (result i32) get_local $0 + return + ) + (func $~lib/polyfills/bswap (; 3 ;) (type $ii) (param $0 i32) (result i32) + get_local $0 + i32.const 8 + i32.shl + get_local $0 + i32.const 65535 + i32.and + i32.const 8 + i32.shr_u + i32.const 255 + i32.and + i32.or + return ) (func $~lib/polyfills/bswap (; 4 ;) (type $ii) (param $0 i32) (result i32) - (local $1 i32) - i32.const 2 - i32.const 1 - i32.eq - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 2 - i32.const 2 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 2 - i32.const 4 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 2 - i32.const 8 - i32.eq - end - i32.eqz - if - i32.const 0 - i32.const 8 - i32.const 2 - i32.const 2 - call $~lib/env/abort - unreachable - end get_local $0 - call $~lib/polyfills/bswap16 + i32.const 8 + i32.shl + get_local $0 + i32.const 16 + i32.shl + i32.const 16 + i32.shr_s + i32.const 8 + i32.shr_s + i32.const 255 + i32.and + i32.or return ) (func $~lib/polyfills/bswap (; 5 ;) (type $ii) (param $0 i32) (result i32) - (local $1 i32) - i32.const 4 - i32.const 1 - i32.eq - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 2 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 4 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 8 - i32.eq - end - i32.eqz - if - i32.const 0 - i32.const 8 - i32.const 2 - i32.const 2 - call $~lib/env/abort - unreachable - end get_local $0 i32.const -16711936 i32.and @@ -277,43 +65,6 @@ return ) (func $~lib/polyfills/bswap (; 6 ;) (type $ii) (param $0 i32) (result i32) - (local $1 i32) - i32.const 4 - i32.const 1 - i32.eq - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 2 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 4 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 8 - i32.eq - end - i32.eqz - if - i32.const 0 - i32.const 8 - i32.const 2 - i32.const 2 - call $~lib/env/abort - unreachable - end get_local $0 i32.const -16711936 i32.and @@ -328,195 +79,84 @@ return ) (func $~lib/polyfills/bswap (; 7 ;) (type $II) (param $0 i64) (result i64) - (local $1 i32) + (local $1 i64) (local $2 i64) (local $3 i64) - (local $4 i64) - i32.const 8 - i32.const 1 - i32.eq - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 8 - i32.const 2 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 8 - i32.const 4 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 8 - i32.const 8 - i32.eq - end - i32.eqz - if - i32.const 0 - i32.const 8 - i32.const 2 - i32.const 2 - call $~lib/env/abort - unreachable - end get_local $0 i64.const 8 i64.shr_u i64.const 71777214294589695 i64.and - set_local $2 + set_local $1 get_local $0 i64.const 71777214294589695 i64.and i64.const 8 i64.shl - set_local $3 + set_local $2 + get_local $1 get_local $2 - get_local $3 i64.or - set_local $4 - get_local $4 + set_local $3 + get_local $3 i64.const 16 i64.shr_u i64.const 281470681808895 i64.and - set_local $2 - get_local $4 + set_local $1 + get_local $3 i64.const 281470681808895 i64.and i64.const 16 i64.shl - set_local $3 + set_local $2 + get_local $1 get_local $2 - get_local $3 i64.or i64.const 32 i64.rotr return ) (func $~lib/polyfills/bswap (; 8 ;) (type $II) (param $0 i64) (result i64) - (local $1 i32) + (local $1 i64) (local $2 i64) (local $3 i64) - (local $4 i64) - i32.const 8 - i32.const 1 - i32.eq - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 8 - i32.const 2 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 8 - i32.const 4 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 8 - i32.const 8 - i32.eq - end - i32.eqz - if - i32.const 0 - i32.const 8 - i32.const 2 - i32.const 2 - call $~lib/env/abort - unreachable - end get_local $0 i64.const 8 i64.shr_u i64.const 71777214294589695 i64.and - set_local $2 + set_local $1 get_local $0 i64.const 71777214294589695 i64.and i64.const 8 i64.shl - set_local $3 + set_local $2 + get_local $1 get_local $2 - get_local $3 i64.or - set_local $4 - get_local $4 + set_local $3 + get_local $3 i64.const 16 i64.shr_u i64.const 281470681808895 i64.and - set_local $2 - get_local $4 + set_local $1 + get_local $3 i64.const 281470681808895 i64.and i64.const 16 i64.shl - set_local $3 + set_local $2 + get_local $1 get_local $2 - get_local $3 i64.or i64.const 32 i64.rotr return ) (func $~lib/polyfills/bswap (; 9 ;) (type $ii) (param $0 i32) (result i32) - (local $1 i32) - i32.const 4 - i32.const 1 - i32.eq - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 2 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 4 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 8 - i32.eq - end - i32.eqz - if - i32.const 0 - i32.const 8 - i32.const 2 - i32.const 2 - call $~lib/env/abort - unreachable - end get_local $0 i32.const -16711936 i32.and @@ -531,43 +171,6 @@ return ) (func $~lib/polyfills/bswap (; 10 ;) (type $ii) (param $0 i32) (result i32) - (local $1 i32) - i32.const 4 - i32.const 1 - i32.eq - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 2 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 4 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 8 - i32.eq - end - i32.eqz - if - i32.const 0 - i32.const 8 - i32.const 2 - i32.const 2 - call $~lib/env/abort - unreachable - end get_local $0 i32.const -16711936 i32.and @@ -581,129 +184,44 @@ i32.or return ) - (func $~lib/polyfills/bswap16 (; 11 ;) (type $ii) (param $0 i32) (result i32) - (local $1 i32) - i32.const 4 - i32.const 1 + (func $start (; 11 ;) (type $v) + (local $0 i32) + i32.const 170 + call $~lib/polyfills/bswap + i32.const 255 + i32.and + i32.const 170 i32.eq - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 2 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 4 - i32.eq - end i32.eqz if i32.const 0 i32.const 8 - i32.const 27 - i32.const 2 + i32.const 4 + i32.const 0 call $~lib/env/abort unreachable end - i32.const 4 - i32.const 2 + i32.const 170 + call $~lib/polyfills/bswap + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.const 170 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s i32.eq - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 4 - i32.eq - end - if - get_local $0 - i32.const 8 - i32.shl - i32.const 65280 - i32.and - get_local $0 - i32.const 8 - i32.shr_u - i32.const 255 - i32.and - i32.or - get_local $0 - i32.const -65536 - i32.and - i32.or - return - end - get_local $0 - ) - (func $~lib/polyfills/bswap16 (; 12 ;) (type $ii) (param $0 i32) (result i32) - (local $1 i32) - i32.const 4 - i32.const 1 - i32.eq - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 2 - i32.eq - end - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 4 - i32.eq - end i32.eqz if i32.const 0 i32.const 8 - i32.const 27 - i32.const 2 + i32.const 5 + i32.const 0 call $~lib/env/abort unreachable end - i32.const 4 - i32.const 2 - i32.eq - tee_local $1 - if (result i32) - get_local $1 - else - i32.const 4 - i32.const 4 - i32.eq - end - if - get_local $0 - i32.const 8 - i32.shl - i32.const 65280 - i32.and - get_local $0 - i32.const 8 - i32.shr_s - i32.const 255 - i32.and - i32.or - get_local $0 - i32.const -65536 - i32.and - i32.or - return - end - get_local $0 - ) - (func $start (; 13 ;) (type $v) i32.const 43707 call $~lib/polyfills/bswap i32.const 65535 @@ -713,8 +231,8 @@ i32.eqz if i32.const 0 - i32.const 48 - i32.const 4 + i32.const 8 + i32.const 8 i32.const 0 call $~lib/env/abort unreachable @@ -734,8 +252,8 @@ i32.eqz if i32.const 0 - i32.const 48 - i32.const 5 + i32.const 8 + i32.const 9 i32.const 0 call $~lib/env/abort unreachable @@ -747,8 +265,8 @@ i32.eqz if i32.const 0 - i32.const 48 i32.const 8 + i32.const 12 i32.const 0 call $~lib/env/abort unreachable @@ -760,8 +278,8 @@ i32.eqz if i32.const 0 - i32.const 48 - i32.const 9 + i32.const 8 + i32.const 13 i32.const 0 call $~lib/env/abort unreachable @@ -773,8 +291,8 @@ i32.eqz if i32.const 0 - i32.const 48 - i32.const 12 + i32.const 8 + i32.const 16 i32.const 0 call $~lib/env/abort unreachable @@ -786,8 +304,8 @@ i32.eqz if i32.const 0 - i32.const 48 - i32.const 13 + i32.const 8 + i32.const 17 i32.const 0 call $~lib/env/abort unreachable @@ -799,8 +317,8 @@ i32.eqz if i32.const 0 - i32.const 48 - i32.const 16 + i32.const 8 + i32.const 20 i32.const 0 call $~lib/env/abort unreachable @@ -812,14 +330,70 @@ i32.eqz if i32.const 0 - i32.const 48 - i32.const 17 + i32.const 8 + i32.const 21 i32.const 0 call $~lib/env/abort unreachable end - i32.const 43707 - call $~lib/polyfills/bswap16 + block $~lib/polyfills/bswap16|inlined.0 (result i32) + i32.const 170 + set_local $0 + get_local $0 + br $~lib/polyfills/bswap16|inlined.0 + end + i32.const 255 + i32.and + i32.const 170 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 24 + i32.const 0 + call $~lib/env/abort + unreachable + end + block $~lib/polyfills/bswap16|inlined.0 (result i32) + i32.const 170 + set_local $0 + get_local $0 + br $~lib/polyfills/bswap16|inlined.0 + end + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.const 170 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 25 + i32.const 0 + call $~lib/env/abort + unreachable + end + block $~lib/polyfills/bswap16|inlined.0 (result i32) + i32.const 43707 + set_local $0 + get_local $0 + i32.const 8 + i32.shl + get_local $0 + i32.const 8 + i32.shr_u + i32.const 255 + i32.and + i32.or + br $~lib/polyfills/bswap16|inlined.0 + end i32.const 65535 i32.and i32.const 48042 @@ -827,14 +401,30 @@ i32.eqz if i32.const 0 - i32.const 48 - i32.const 20 + i32.const 8 + i32.const 28 i32.const 0 call $~lib/env/abort unreachable end - i32.const 43707 - call $~lib/polyfills/bswap16 + block $~lib/polyfills/bswap16|inlined.0 (result i32) + i32.const 43707 + set_local $0 + get_local $0 + i32.const 8 + i32.shl + get_local $0 + i32.const 16 + i32.shl + i32.const 16 + i32.shr_s + i32.const 8 + i32.shr_s + i32.const 255 + i32.and + i32.or + br $~lib/polyfills/bswap16|inlined.0 + end i32.const 16 i32.shl i32.const 16 @@ -848,39 +438,75 @@ i32.eqz if i32.const 0 - i32.const 48 - i32.const 21 + i32.const 8 + i32.const 29 i32.const 0 call $~lib/env/abort unreachable end - i32.const -7820613 - call $~lib/polyfills/bswap16 + block $~lib/polyfills/bswap16|inlined.0 (result i32) + i32.const -7820613 + set_local $0 + get_local $0 + i32.const 8 + i32.shl + i32.const 65280 + i32.and + get_local $0 + i32.const 8 + i32.shr_u + i32.const 255 + i32.and + i32.or + get_local $0 + i32.const -65536 + i32.and + i32.or + br $~lib/polyfills/bswap16|inlined.0 + end i32.const -7816278 i32.eq i32.eqz if i32.const 0 - i32.const 48 - i32.const 24 + i32.const 8 + i32.const 32 i32.const 0 call $~lib/env/abort unreachable end - i32.const -7820613 - call $~lib/polyfills/bswap16 + block $~lib/polyfills/bswap16|inlined.0 (result i32) + i32.const -7820613 + set_local $0 + get_local $0 + i32.const 8 + i32.shl + i32.const 65280 + i32.and + get_local $0 + i32.const 8 + i32.shr_s + i32.const 255 + i32.and + i32.or + get_local $0 + i32.const -65536 + i32.and + i32.or + br $~lib/polyfills/bswap16|inlined.0 + end i32.const -7816278 i32.eq i32.eqz if i32.const 0 - i32.const 48 - i32.const 25 + i32.const 8 + i32.const 33 i32.const 0 call $~lib/env/abort unreachable end ) - (func $null (; 14 ;) (type $v) + (func $null (; 12 ;) (type $v) ) ) diff --git a/tests/compiler/std/typedarray.optimized.wat b/tests/compiler/std/typedarray.optimized.wat index 3ed11aba..e4ff89a2 100644 --- a/tests/compiler/std/typedarray.optimized.wat +++ b/tests/compiler/std/typedarray.optimized.wat @@ -58,6 +58,10 @@ (global $std/typedarray/sub8 (mut i32) (i32.const 0)) (global $std/typedarray/arr32 (mut i32) (i32.const 0)) (global $std/typedarray/sub32 (mut i32) (i32.const 0)) + (global $std/typedarray/multisubarr (mut i32) (i32.const 0)) + (global $std/typedarray/multisubarr1 (mut i32) (i32.const 0)) + (global $std/typedarray/multisubarr2 (mut i32) (i32.const 0)) + (global $std/typedarray/multisubarr3 (mut i32) (i32.const 0)) (export "memory" (memory $0)) (export "table" (table $0)) (start $start) @@ -1103,9 +1107,12 @@ i32.load i32.store get_local $2 + get_local $0 + i32.load offset=4 get_local $3 i32.const 2 i32.shl + i32.add i32.store offset=4 get_local $2 get_local $1 @@ -1178,9 +1185,12 @@ i32.load i32.store get_local $1 + get_local $0 + i32.load offset=4 get_local $2 i32.const 3 i32.shl + i32.add i32.store offset=4 get_local $1 get_local $3 @@ -1955,47 +1965,64 @@ get_local $3 call $~lib/internal/typedarray/TypedArray#fill ) - (func $~lib/typedarray/Int8Array#subarray (; 26 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) - (local $1 i32) + (func $~lib/typedarray/Int8Array#subarray (; 26 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) i32.const 1 get_local $0 i32.load offset=8 - tee_local $1 + tee_local $2 i32.const 1 - get_local $1 - i32.lt_s - select - set_local $2 - i32.const 4 - get_local $1 - i32.const 4 - get_local $1 - i32.lt_s - select - tee_local $1 get_local $2 - get_local $1 - get_local $2 - i32.gt_s + i32.lt_s select set_local $3 + get_local $1 + i32.const 0 + i32.lt_s + if (result i32) + get_local $2 + get_local $1 + i32.add + tee_local $2 + get_local $3 + get_local $2 + get_local $3 + i32.gt_s + select + else + get_local $1 + get_local $2 + get_local $1 + get_local $2 + i32.lt_s + select + tee_local $2 + get_local $3 + get_local $2 + get_local $3 + i32.gt_s + select + end + set_local $1 i32.const 12 call $~lib/allocator/arena/__memory_allocate - tee_local $1 + tee_local $2 get_local $0 i32.load i32.store - get_local $1 get_local $2 + get_local $0 + i32.load offset=4 + get_local $3 + i32.add i32.store offset=4 + get_local $2 get_local $1 get_local $3 - get_local $2 i32.sub i32.store offset=8 - get_local $1 + get_local $2 ) (func $~lib/internal/typedarray/TypedArray#fill (; 27 ;) (type $iiiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (local $4 i32) @@ -2647,6 +2674,7 @@ unreachable end get_global $std/typedarray/arr8 + i32.const 4 call $~lib/typedarray/Int8Array#subarray set_global $std/typedarray/sub8 i32.const 1 @@ -2907,6 +2935,198 @@ i32.const 134217727 call $~lib/internal/typedarray/TypedArray#constructor drop + i32.const 6 + call $~lib/internal/typedarray/TypedArray#constructor + set_global $std/typedarray/multisubarr + get_global $std/typedarray/multisubarr + i32.const 0 + i32.const 1 + call $~lib/internal/typedarray/TypedArray#__set + get_global $std/typedarray/multisubarr + i32.const 1 + i32.const 2 + call $~lib/internal/typedarray/TypedArray#__set + get_global $std/typedarray/multisubarr + i32.const 2 + i32.const 3 + call $~lib/internal/typedarray/TypedArray#__set + get_global $std/typedarray/multisubarr + i32.const 3 + i32.const 4 + call $~lib/internal/typedarray/TypedArray#__set + get_global $std/typedarray/multisubarr + i32.const 4 + i32.const 5 + call $~lib/internal/typedarray/TypedArray#__set + get_global $std/typedarray/multisubarr + i32.const 5 + i32.const 6 + call $~lib/internal/typedarray/TypedArray#__set + get_global $std/typedarray/multisubarr + i32.const 6 + call $~lib/typedarray/Int8Array#subarray + set_global $std/typedarray/multisubarr1 + get_global $std/typedarray/multisubarr1 + i32.const 0 + call $~lib/internal/typedarray/TypedArray#__get + i32.const 255 + i32.and + i32.const 2 + i32.ne + if + i32.const 0 + i32.const 8 + i32.const 212 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr1 + i32.load offset=8 + i32.const 5 + i32.ne + if + i32.const 0 + i32.const 8 + i32.const 213 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr1 + i32.load offset=4 + i32.const 1 + i32.ne + if + i32.const 0 + i32.const 8 + i32.const 214 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr1 + i32.load offset=8 + i32.const 5 + i32.ne + if + i32.const 0 + i32.const 8 + i32.const 215 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr1 + i32.const 5 + call $~lib/typedarray/Int8Array#subarray + set_global $std/typedarray/multisubarr2 + get_global $std/typedarray/multisubarr2 + i32.const 0 + call $~lib/internal/typedarray/TypedArray#__get + i32.const 255 + i32.and + i32.const 3 + i32.ne + if + i32.const 0 + i32.const 8 + i32.const 218 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr2 + i32.load offset=8 + i32.const 4 + i32.ne + if + i32.const 0 + i32.const 8 + i32.const 219 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr2 + i32.load offset=4 + i32.const 2 + i32.ne + if + i32.const 0 + i32.const 8 + i32.const 220 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr2 + i32.load offset=8 + i32.const 4 + i32.ne + if + i32.const 0 + i32.const 8 + i32.const 221 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr2 + i32.const 4 + call $~lib/typedarray/Int8Array#subarray + set_global $std/typedarray/multisubarr3 + get_global $std/typedarray/multisubarr3 + i32.const 0 + call $~lib/internal/typedarray/TypedArray#__get + i32.const 255 + i32.and + i32.const 4 + i32.ne + if + i32.const 0 + i32.const 8 + i32.const 224 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr3 + i32.load offset=8 + i32.const 3 + i32.ne + if + i32.const 0 + i32.const 8 + i32.const 225 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr3 + i32.load offset=4 + i32.const 3 + i32.ne + if + i32.const 0 + i32.const 8 + i32.const 226 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr3 + i32.load offset=8 + i32.const 3 + i32.ne + if + i32.const 0 + i32.const 8 + i32.const 227 + i32.const 0 + call $~lib/env/abort + unreachable + end ) (func $null (; 31 ;) (type $v) nop