mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 15:12:12 +00:00
Improve bswap implementation (#323)
This commit is contained in:
parent
63b64ba69e
commit
54311fd0ab
@ -1,33 +1,40 @@
|
||||
export function bswap<T>(value: T): T {
|
||||
assert(sizeof<T>() == 1 || sizeof<T>() == 2 || sizeof<T>() == 4 || sizeof<T>() == 8);
|
||||
if (isInteger<T>()) {
|
||||
if (sizeof<T>() == 2) {
|
||||
return <T>((value << 8) | ((value >> 8) & <T>0x00FF));
|
||||
}
|
||||
if (sizeof<T>() == 4) {
|
||||
return <T>(
|
||||
rotl<u32>(<u32>value & 0xFF00FF00, 8) |
|
||||
rotr<u32>(<u32>value & 0x00FF00FF, 8)
|
||||
);
|
||||
}
|
||||
if (sizeof<T>() == 8) {
|
||||
let a = (<u64>value >> 8) & 0x00FF00FF00FF00FF;
|
||||
let b = (<u64>value & 0x00FF00FF00FF00FF) << 8;
|
||||
let v = a | b;
|
||||
|
||||
if (sizeof<T>() == 2) {
|
||||
return bswap16<T>(value);
|
||||
}
|
||||
if (sizeof<T>() == 4) {
|
||||
return <T>(
|
||||
rotl<u32>(<u32>value & 0xFF00FF00, 8) |
|
||||
rotr<u32>(<u32>value & 0x00FF00FF, 8)
|
||||
);
|
||||
}
|
||||
if (sizeof<T>() == 8) {
|
||||
let a: u64 = (<u64>value >> 8) & 0x00FF00FF00FF00FF;
|
||||
let b: u64 = (<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 <T>rotr<u64>(a | b, 32);
|
||||
return <T>rotr<u64>(a | b, 32);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
assert(false);
|
||||
return value;
|
||||
}
|
||||
|
||||
@inline
|
||||
export function bswap16<T>(value: T): T {
|
||||
assert(sizeof<T>() == 1 || sizeof<T>() == 2 || sizeof<T>() == 4);
|
||||
|
||||
if (sizeof<T>() == 2 || sizeof<T>() == 4) {
|
||||
return <T>(((value << 8) & <T>0xFF00) | ((value >> 8) & <T>0x00FF) | (value & <T>0xFFFF0000));
|
||||
if (isInteger<T>() && sizeof<T>() <= 4) {
|
||||
if (sizeof<T>() == 2) {
|
||||
return <T>((value << 8) | ((value >> 8) & <T>0x00FF));
|
||||
} else if (sizeof<T>() == 4) {
|
||||
return <T>(((value << 8) & <T>0xFF00) | ((value >> 8) & <T>0x00FF) | (value & <T>0xFFFF0000));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
assert(false);
|
||||
return value;
|
||||
}
|
||||
|
@ -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<u16> (; 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<i16> (; 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<u16>
|
||||
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<i16>
|
||||
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<u16>
|
||||
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<i16>
|
||||
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
|
||||
)
|
||||
)
|
||||
|
@ -1,5 +1,9 @@
|
||||
// bswap / bswap16 tests
|
||||
|
||||
// check bswap<T> for i8/u8
|
||||
assert(bswap<u8>(<u8>0xaa) == <u8>0xaa);
|
||||
assert(bswap<i8>(<i8>0xaa) == <i8>0xaa);
|
||||
|
||||
// check bswap<T> for i16/u16
|
||||
assert(bswap<u16>(<u16>0xaabb) == <u16>0xbbaa);
|
||||
assert(bswap<i16>(<i16>0xaabb) == <i16>0xbbaa);
|
||||
@ -16,6 +20,10 @@ assert(bswap<i64>(<i64>0x00112233aabbccdd) == <i64>0xddccbbaa33221100);
|
||||
assert(bswap<usize>(<usize>0xaabbccdd) == <usize>0xddccbbaa);
|
||||
assert(bswap<isize>(<isize>0xaabbccdd) == <isize>0xddccbbaa);
|
||||
|
||||
// check bswap16<T> for i8/u8
|
||||
assert(bswap16<u8>(<u8>0xaa) == <u8>0xaa);
|
||||
assert(bswap16<i8>(<i8>0xaa) == <i8>0xaa);
|
||||
|
||||
// check bswap16<T> for i16/u16
|
||||
assert(bswap16<u16>(<u16>0xaabb) == <u16>0xbbaa);
|
||||
assert(bswap16<i16>(<i16>0xaabb) == <i16>0xbbaa);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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<i8,i32>#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<i32,i32>#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<i64,i64>#constructor
|
||||
drop
|
||||
i32.const 6
|
||||
call $~lib/internal/typedarray/TypedArray<i8,i32>#constructor
|
||||
set_global $std/typedarray/multisubarr
|
||||
get_global $std/typedarray/multisubarr
|
||||
i32.const 0
|
||||
i32.const 1
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
get_global $std/typedarray/multisubarr
|
||||
i32.const 1
|
||||
i32.const 2
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
get_global $std/typedarray/multisubarr
|
||||
i32.const 2
|
||||
i32.const 3
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
get_global $std/typedarray/multisubarr
|
||||
i32.const 3
|
||||
i32.const 4
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
get_global $std/typedarray/multisubarr
|
||||
i32.const 4
|
||||
i32.const 5
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
get_global $std/typedarray/multisubarr
|
||||
i32.const 5
|
||||
i32.const 6
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__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<i8,i32>#__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<i8,i32>#__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<i8,i32>#__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
|
||||
|
Loading…
x
Reference in New Issue
Block a user