Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b192a49

Browse files
authoredMar 8, 2021
Reduce monomophic versions of bswap in DataView (#1717)
1 parent 72de26d commit b192a49

File tree

5 files changed

+33
-149
lines changed

5 files changed

+33
-149
lines changed
 

‎std/assembly/dataview.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,15 @@ export class DataView {
5757
(byteOffset >>> 31) | i32(byteOffset + 2 > this.byteLength)
5858
) throw new RangeError(E_INDEXOUTOFRANGE);
5959
var result: i16 = load<i16>(this.dataStart + <usize>byteOffset);
60-
return littleEndian ? result : bswap<i16>(result);
60+
return littleEndian ? result : bswap<u16>(result);
6161
}
6262

6363
getInt32(byteOffset: i32, littleEndian: bool = false): i32 {
6464
if (
6565
(byteOffset >>> 31) | i32(byteOffset + 4 > this.byteLength)
6666
) throw new RangeError(E_INDEXOUTOFRANGE);
6767
var result: i32 = load<i32>(this.dataStart + <usize>byteOffset);
68-
return littleEndian ? result : bswap<i32>(result);
68+
return littleEndian ? result : bswap<u32>(result);
6969
}
7070

7171
getUint8(byteOffset: i32): u8 {
@@ -114,14 +114,14 @@ export class DataView {
114114
if (
115115
(byteOffset >>> 31) | i32(byteOffset + 2 > this.byteLength)
116116
) throw new RangeError(E_INDEXOUTOFRANGE);
117-
store<i16>(this.dataStart + <usize>byteOffset, littleEndian ? value : bswap<i16>(value));
117+
store<i16>(this.dataStart + <usize>byteOffset, littleEndian ? value : bswap<u16>(value));
118118
}
119119

120120
setInt32(byteOffset: i32, value: i32, littleEndian: bool = false): void {
121121
if (
122122
(byteOffset >>> 31) | i32(byteOffset + 4 > this.byteLength)
123123
) throw new RangeError(E_INDEXOUTOFRANGE);
124-
store<i32>(this.dataStart + <usize>byteOffset, littleEndian ? value : bswap<i32>(value));
124+
store<i32>(this.dataStart + <usize>byteOffset, littleEndian ? value : bswap<u32>(value));
125125
}
126126

127127
setUint8(byteOffset: i32, value: u8): void {
@@ -150,7 +150,7 @@ export class DataView {
150150
(byteOffset >>> 31) | i32(byteOffset + 8 > this.byteLength)
151151
) throw new RangeError(E_INDEXOUTOFRANGE);
152152
var result: i64 = load<i64>(this.dataStart + <usize>byteOffset);
153-
return littleEndian ? result : bswap<i64>(result);
153+
return littleEndian ? result : bswap<u64>(result);
154154
}
155155

156156
getUint64(byteOffset: i32, littleEndian: bool = false): u64 {
@@ -165,7 +165,7 @@ export class DataView {
165165
if (
166166
(byteOffset >>> 31) | i32(byteOffset + 8 > this.byteLength)
167167
) throw new RangeError(E_INDEXOUTOFRANGE);
168-
store<i64>(this.dataStart + <usize>byteOffset, littleEndian ? value : bswap<i64>(value));
168+
store<i64>(this.dataStart + <usize>byteOffset, littleEndian ? value : bswap<u64>(value));
169169
}
170170

171171
setUint64(byteOffset: i32, value: u64, littleEndian: bool = false): void {

‎std/assembly/polyfills.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
export function bswap<T extends number>(value: T): T {
22
if (isInteger<T>()) {
33
if (sizeof<T>() == 2) {
4-
return <T>((value << 8) | ((value >> 8) & <T>0x00FF));
4+
return <T>((value << 8) | ((value >>> 8) & <T>0x00FF));
55
}
66
if (sizeof<T>() == 4) {
77
return <T>(
8-
rotl<u32>(<u32>value & 0xFF00FF00, 8) |
9-
rotr<u32>(<u32>value & 0x00FF00FF, 8)
8+
rotl<u32>(value & 0xFF00FF00, 8) |
9+
rotr<u32>(value & 0x00FF00FF, 8)
1010
);
1111
}
1212
if (sizeof<T>() == 8) {
@@ -28,9 +28,9 @@ export function bswap<T extends number>(value: T): T {
2828
export function bswap16<T extends number>(value: T): T {
2929
if (isInteger<T>() && sizeof<T>() <= 4) {
3030
if (sizeof<T>() == 2) {
31-
return <T>((value << 8) | ((value >> 8) & <T>0x00FF));
31+
return <T>((value << 8) | ((value >>> 8) & <T>0x00FF));
3232
} else if (sizeof<T>() == 4) {
33-
return <T>(((value << 8) & <T>0xFF00) | ((value >> 8) & <T>0x00FF) | (value & <T>0xFFFF0000));
33+
return <T>(((value << 8) & <T>0xFF00) | ((value >>> 8) & <T>0x00FF) | (value & <T>0xFFFF0000));
3434
}
3535
return value;
3636
}

‎tests/compiler/std/dataview.optimized.wat

+8-21
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
(type $none_=>_none (func))
55
(type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))
66
(type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32)))
7-
(type $i32_=>_i32 (func (param i32) (result i32)))
87
(type $i32_=>_none (func (param i32)))
8+
(type $i32_=>_i32 (func (param i32) (result i32)))
99
(type $i32_i64_i32_=>_none (func (param i32 i64 i32)))
1010
(type $i32_i32_=>_i64 (func (param i32 i32) (result i64)))
1111
(type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32)))
@@ -1939,17 +1939,15 @@
19391939
i32.add
19401940
i32.load8_s
19411941
)
1942-
(func $~lib/polyfills/bswap<i16> (param $0 i32) (result i32)
1942+
(func $~lib/polyfills/bswap<u16> (param $0 i32) (result i32)
19431943
local.get $0
1944-
i32.const 16
1944+
i32.const 8
19451945
i32.shl
1946-
i32.const 24
1947-
i32.shr_s
1948-
i32.const 255
1949-
i32.and
19501946
local.get $0
1947+
i32.const 65535
1948+
i32.and
19511949
i32.const 8
1952-
i32.shl
1950+
i32.shr_u
19531951
i32.or
19541952
)
19551953
(func $~lib/dataview/DataView#getInt16 (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
@@ -1982,7 +1980,7 @@
19821980
local.get $0
19831981
else
19841982
local.get $0
1985-
call $~lib/polyfills/bswap<i16>
1983+
call $~lib/polyfills/bswap<u16>
19861984
end
19871985
)
19881986
(func $~lib/dataview/DataView#getInt32 (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
@@ -2063,17 +2061,6 @@
20632061
i32.add
20642062
i32.load8_u
20652063
)
2066-
(func $~lib/polyfills/bswap<u16> (param $0 i32) (result i32)
2067-
local.get $0
2068-
i32.const 8
2069-
i32.shl
2070-
local.get $0
2071-
i32.const 65535
2072-
i32.and
2073-
i32.const 8
2074-
i32.shr_u
2075-
i32.or
2076-
)
20772064
(func $~lib/dataview/DataView#getUint16 (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
20782065
local.get $1
20792066
i32.const 31
@@ -2242,7 +2229,7 @@
22422229
local.get $1
22432230
else
22442231
local.get $1
2245-
call $~lib/polyfills/bswap<i16>
2232+
call $~lib/polyfills/bswap<u16>
22462233
end
22472234
i32.store16
22482235
)

‎tests/compiler/std/dataview.untouched.wat

+11-114
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
(type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32)))
1010
(type $i32_i32_i64_i32_=>_none (func (param i32 i32 i64 i32)))
1111
(type $i32_i32_i32_i32_=>_i32 (func (param i32 i32 i32 i32) (result i32)))
12-
(type $i64_=>_i64 (func (param i64) (result i64)))
1312
(type $i32_i32_i32_=>_i64 (func (param i32 i32 i32) (result i64)))
1413
(type $i32_i32_f32_i32_=>_none (func (param i32 i32 f32 i32)))
1514
(type $i32_i32_f64_i32_=>_none (func (param i32 i32 f64 i32)))
1615
(type $none_=>_i32 (func (result i32)))
16+
(type $i64_=>_i64 (func (param i64) (result i64)))
1717
(type $i32_i32_i32_=>_f32 (func (param i32 i32 i32) (result f32)))
1818
(type $i32_i32_i32_=>_f64 (func (param i32 i32 i32) (result f64)))
1919
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
@@ -2672,7 +2672,7 @@
26722672
i32.add
26732673
i32.load8_s
26742674
)
2675-
(func $~lib/polyfills/bswap<i16> (param $0 i32) (result i32)
2675+
(func $~lib/polyfills/bswap<u16> (param $0 i32) (result i32)
26762676
i32.const 1
26772677
drop
26782678
i32.const 2
@@ -2685,14 +2685,12 @@
26852685
i32.and
26862686
i32.shl
26872687
local.get $0
2688-
i32.const 16
2689-
i32.shl
2690-
i32.const 16
2691-
i32.shr_s
2688+
i32.const 65535
2689+
i32.and
26922690
i32.const 8
26932691
i32.const 15
26942692
i32.and
2695-
i32.shr_s
2693+
i32.shr_u
26962694
i32.const 255
26972695
i32.and
26982696
i32.or
@@ -2729,33 +2727,9 @@
27292727
local.get $3
27302728
else
27312729
local.get $3
2732-
call $~lib/polyfills/bswap<i16>
2730+
call $~lib/polyfills/bswap<u16>
27332731
end
27342732
)
2735-
(func $~lib/polyfills/bswap<i32> (param $0 i32) (result i32)
2736-
i32.const 1
2737-
drop
2738-
i32.const 4
2739-
i32.const 2
2740-
i32.eq
2741-
drop
2742-
i32.const 4
2743-
i32.const 4
2744-
i32.eq
2745-
drop
2746-
local.get $0
2747-
i32.const -16711936
2748-
i32.and
2749-
i32.const 8
2750-
i32.rotl
2751-
local.get $0
2752-
i32.const 16711935
2753-
i32.and
2754-
i32.const 8
2755-
i32.rotr
2756-
i32.or
2757-
return
2758-
)
27592733
(func $~lib/dataview/DataView#getInt32 (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
27602734
(local $3 i32)
27612735
local.get $1
@@ -2787,62 +2761,9 @@
27872761
local.get $3
27882762
else
27892763
local.get $3
2790-
call $~lib/polyfills/bswap<i32>
2764+
call $~lib/polyfills/bswap<u32>
27912765
end
27922766
)
2793-
(func $~lib/polyfills/bswap<i64> (param $0 i64) (result i64)
2794-
(local $1 i64)
2795-
(local $2 i64)
2796-
(local $3 i64)
2797-
i32.const 1
2798-
drop
2799-
i32.const 8
2800-
i32.const 2
2801-
i32.eq
2802-
drop
2803-
i32.const 8
2804-
i32.const 4
2805-
i32.eq
2806-
drop
2807-
i32.const 8
2808-
i32.const 8
2809-
i32.eq
2810-
drop
2811-
local.get $0
2812-
i64.const 8
2813-
i64.shr_u
2814-
i64.const 71777214294589695
2815-
i64.and
2816-
local.set $1
2817-
local.get $0
2818-
i64.const 71777214294589695
2819-
i64.and
2820-
i64.const 8
2821-
i64.shl
2822-
local.set $2
2823-
local.get $1
2824-
local.get $2
2825-
i64.or
2826-
local.set $3
2827-
local.get $3
2828-
i64.const 16
2829-
i64.shr_u
2830-
i64.const 281470681808895
2831-
i64.and
2832-
local.set $1
2833-
local.get $3
2834-
i64.const 281470681808895
2835-
i64.and
2836-
i64.const 16
2837-
i64.shl
2838-
local.set $2
2839-
local.get $1
2840-
local.get $2
2841-
i64.or
2842-
i64.const 32
2843-
i64.rotr
2844-
return
2845-
)
28462767
(func $~lib/dataview/DataView#getInt64 (param $0 i32) (param $1 i32) (param $2 i32) (result i64)
28472768
(local $3 i64)
28482769
local.get $1
@@ -2874,7 +2795,7 @@
28742795
local.get $3
28752796
else
28762797
local.get $3
2877-
call $~lib/polyfills/bswap<i64>
2798+
call $~lib/polyfills/bswap<u64>
28782799
end
28792800
)
28802801
(func $~lib/dataview/DataView#getUint8 (param $0 i32) (param $1 i32) (result i32)
@@ -2896,30 +2817,6 @@
28962817
i32.add
28972818
i32.load8_u
28982819
)
2899-
(func $~lib/polyfills/bswap<u16> (param $0 i32) (result i32)
2900-
i32.const 1
2901-
drop
2902-
i32.const 2
2903-
i32.const 2
2904-
i32.eq
2905-
drop
2906-
local.get $0
2907-
i32.const 8
2908-
i32.const 15
2909-
i32.and
2910-
i32.shl
2911-
local.get $0
2912-
i32.const 65535
2913-
i32.and
2914-
i32.const 8
2915-
i32.const 15
2916-
i32.and
2917-
i32.shr_u
2918-
i32.const 255
2919-
i32.and
2920-
i32.or
2921-
return
2922-
)
29232820
(func $~lib/dataview/DataView#getUint16 (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
29242821
(local $3 i32)
29252822
local.get $1
@@ -3146,7 +3043,7 @@
31463043
local.get $2
31473044
else
31483045
local.get $2
3149-
call $~lib/polyfills/bswap<i16>
3046+
call $~lib/polyfills/bswap<u16>
31503047
end
31513048
i32.store16
31523049
)
@@ -3178,7 +3075,7 @@
31783075
local.get $2
31793076
else
31803077
local.get $2
3181-
call $~lib/polyfills/bswap<i32>
3078+
call $~lib/polyfills/bswap<u32>
31823079
end
31833080
i32.store
31843081
)
@@ -3210,7 +3107,7 @@
32103107
local.get $2
32113108
else
32123109
local.get $2
3213-
call $~lib/polyfills/bswap<i64>
3110+
call $~lib/polyfills/bswap<u64>
32143111
end
32153112
i64.store
32163113
)

‎tests/compiler/std/polyfills.untouched.wat

+3-3
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
i32.const 8
9393
i32.const 15
9494
i32.and
95-
i32.shr_s
95+
i32.shr_u
9696
i32.const 255
9797
i32.and
9898
i32.or
@@ -400,7 +400,7 @@
400400
i32.const 8
401401
i32.const 15
402402
i32.and
403-
i32.shr_s
403+
i32.shr_u
404404
i32.const 255
405405
i32.and
406406
i32.or
@@ -466,7 +466,7 @@
466466
i32.and
467467
local.get $0
468468
i32.const 8
469-
i32.shr_s
469+
i32.shr_u
470470
i32.const 255
471471
i32.and
472472
i32.or

0 commit comments

Comments
 (0)
Failed to load comments.