Skip to content

Commit a32cead

Browse files
authored
[std] Improve bswap (AssemblyScript#2077)
1 parent 2fe8ad5 commit a32cead

File tree

5 files changed

+98
-67
lines changed

5 files changed

+98
-67
lines changed

std/assembly/polyfills.ts

+22-15
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,46 @@
11
export function bswap<T extends number>(value: T): T {
22
if (isInteger<T>()) {
3+
if (sizeof<T>() == 1) {
4+
return value;
5+
}
36
if (sizeof<T>() == 2) {
4-
return <T>((value << 8) | ((value >>> 8) & <T>0x00FF));
7+
return <T>(<u16>value << 8 | (<u16>value >> 8));
58
}
69
if (sizeof<T>() == 4) {
710
return <T>(
8-
rotl<u32>(value & 0xFF00FF00, 8) |
9-
rotr<u32>(value & 0x00FF00FF, 8)
11+
rotl(<u32>value & 0xFF00FF00, 8) |
12+
rotr(<u32>value & 0x00FF00FF, 8)
1013
);
1114
}
1215
if (sizeof<T>() == 8) {
1316
let a = (<u64>value >> 8) & 0x00FF00FF00FF00FF;
1417
let b = (<u64>value & 0x00FF00FF00FF00FF) << 8;
1518
let v = a | b;
1619

17-
a = (v >> 16) & 0x0000FFFF0000FFFF;
20+
a = (v >>> 16) & 0x0000FFFF0000FFFF;
1821
b = (v & 0x0000FFFF0000FFFF) << 16;
1922

20-
return <T>rotr<u64>(a | b, 32);
23+
return <T>rotr(a | b, 32);
2124
}
22-
return value;
2325
}
24-
assert(false);
25-
return value;
26+
ERROR("Unsupported generic type");
2627
}
2728

2829
export function bswap16<T extends number>(value: T): T {
29-
if (isInteger<T>() && sizeof<T>() <= 4) {
30+
if (isInteger<T>()) {
31+
if (sizeof<T>() == 1) {
32+
return value;
33+
}
3034
if (sizeof<T>() == 2) {
31-
return <T>((value << 8) | ((value >>> 8) & <T>0x00FF));
32-
} else if (sizeof<T>() == 4) {
33-
return <T>(((value << 8) & <T>0xFF00) | ((value >>> 8) & <T>0x00FF) | (value & <T>0xFFFF0000));
35+
return <T>(<u16>value << 8 | (<u16>value >> 8));
36+
}
37+
if (sizeof<T>() == 4) {
38+
return <T>(
39+
(((<u32>value & 0xFF) << 8)) |
40+
((<u32>value >> 8) & 0xFF) |
41+
(<u32>value & 0xFFFF0000)
42+
);
3443
}
35-
return value;
3644
}
37-
assert(false);
38-
return value;
45+
ERROR("Unsupported generic type");
3946
}

tests/compiler/std/array.untouched.wat

+4
Original file line numberDiff line numberDiff line change
@@ -5179,6 +5179,10 @@
51795179
i32.const 1
51805180
drop
51815181
i32.const 8
5182+
i32.const 1
5183+
i32.eq
5184+
drop
5185+
i32.const 8
51825186
i32.const 2
51835187
i32.eq
51845188
drop

tests/compiler/std/dataview.untouched.wat

+12-2
Original file line numberDiff line numberDiff line change
@@ -2498,6 +2498,10 @@
24982498
i32.const 1
24992499
drop
25002500
i32.const 4
2501+
i32.const 1
2502+
i32.eq
2503+
drop
2504+
i32.const 4
25012505
i32.const 2
25022506
i32.eq
25032507
drop
@@ -2561,6 +2565,10 @@
25612565
i32.const 1
25622566
drop
25632567
i32.const 8
2568+
i32.const 1
2569+
i32.eq
2570+
drop
2571+
i32.const 8
25642572
i32.const 2
25652573
i32.eq
25662574
drop
@@ -2666,6 +2674,10 @@
26662674
i32.const 1
26672675
drop
26682676
i32.const 2
2677+
i32.const 1
2678+
i32.eq
2679+
drop
2680+
i32.const 2
26692681
i32.const 2
26702682
i32.eq
26712683
drop
@@ -2681,8 +2693,6 @@
26812693
i32.const 15
26822694
i32.and
26832695
i32.shr_u
2684-
i32.const 255
2685-
i32.and
26862696
i32.or
26872697
return
26882698
)

tests/compiler/std/polyfills.untouched.wat

+56-50
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,7 @@
1717
i32.const 1
1818
drop
1919
i32.const 1
20-
i32.const 2
21-
i32.eq
22-
drop
2320
i32.const 1
24-
i32.const 4
25-
i32.eq
26-
drop
27-
i32.const 1
28-
i32.const 8
2921
i32.eq
3022
drop
3123
local.get $0
@@ -35,15 +27,7 @@
3527
i32.const 1
3628
drop
3729
i32.const 1
38-
i32.const 2
39-
i32.eq
40-
drop
4130
i32.const 1
42-
i32.const 4
43-
i32.eq
44-
drop
45-
i32.const 1
46-
i32.const 8
4731
i32.eq
4832
drop
4933
local.get $0
@@ -53,6 +37,10 @@
5337
i32.const 1
5438
drop
5539
i32.const 2
40+
i32.const 1
41+
i32.eq
42+
drop
43+
i32.const 2
5644
i32.const 2
5745
i32.eq
5846
drop
@@ -68,15 +56,17 @@
6856
i32.const 15
6957
i32.and
7058
i32.shr_u
71-
i32.const 255
72-
i32.and
7359
i32.or
7460
return
7561
)
7662
(func $~lib/polyfills/bswap<i16> (param $0 i32) (result i32)
7763
i32.const 1
7864
drop
7965
i32.const 2
66+
i32.const 1
67+
i32.eq
68+
drop
69+
i32.const 2
8070
i32.const 2
8171
i32.eq
8272
drop
@@ -86,20 +76,23 @@
8676
i32.and
8777
i32.shl
8878
local.get $0
89-
i32.extend16_s
79+
i32.const 65535
80+
i32.and
9081
i32.const 8
9182
i32.const 15
9283
i32.and
9384
i32.shr_u
94-
i32.const 255
95-
i32.and
9685
i32.or
9786
return
9887
)
9988
(func $~lib/polyfills/bswap<u32> (param $0 i32) (result i32)
10089
i32.const 1
10190
drop
10291
i32.const 4
92+
i32.const 1
93+
i32.eq
94+
drop
95+
i32.const 4
10396
i32.const 2
10497
i32.eq
10598
drop
@@ -124,6 +117,10 @@
124117
i32.const 1
125118
drop
126119
i32.const 4
120+
i32.const 1
121+
i32.eq
122+
drop
123+
i32.const 4
127124
i32.const 2
128125
i32.eq
129126
drop
@@ -151,6 +148,10 @@
151148
i32.const 1
152149
drop
153150
i32.const 8
151+
i32.const 1
152+
i32.eq
153+
drop
154+
i32.const 8
154155
i32.const 2
155156
i32.eq
156157
drop
@@ -204,6 +205,10 @@
204205
i32.const 1
205206
drop
206207
i32.const 8
208+
i32.const 1
209+
i32.eq
210+
drop
211+
i32.const 8
207212
i32.const 2
208213
i32.eq
209214
drop
@@ -254,6 +259,10 @@
254259
i32.const 1
255260
drop
256261
i32.const 4
262+
i32.const 1
263+
i32.eq
264+
drop
265+
i32.const 4
257266
i32.const 2
258267
i32.eq
259268
drop
@@ -278,6 +287,10 @@
278287
i32.const 1
279288
drop
280289
i32.const 4
290+
i32.const 1
291+
i32.eq
292+
drop
293+
i32.const 4
281294
i32.const 2
282295
i32.eq
283296
drop
@@ -300,40 +313,30 @@
300313
)
301314
(func $~lib/polyfills/bswap16<u8> (param $0 i32) (result i32)
302315
i32.const 1
303-
i32.const 4
304-
i32.le_u
305316
drop
306317
i32.const 1
307-
i32.const 2
308-
i32.eq
309-
drop
310318
i32.const 1
311-
i32.const 4
312319
i32.eq
313320
drop
314321
local.get $0
315322
return
316323
)
317324
(func $~lib/polyfills/bswap16<i8> (param $0 i32) (result i32)
318325
i32.const 1
319-
i32.const 4
320-
i32.le_u
321326
drop
322327
i32.const 1
323-
i32.const 2
324-
i32.eq
325-
drop
326328
i32.const 1
327-
i32.const 4
328329
i32.eq
329330
drop
330331
local.get $0
331332
return
332333
)
333334
(func $~lib/polyfills/bswap16<u16> (param $0 i32) (result i32)
335+
i32.const 1
336+
drop
334337
i32.const 2
335-
i32.const 4
336-
i32.le_u
338+
i32.const 1
339+
i32.eq
337340
drop
338341
i32.const 2
339342
i32.const 2
@@ -351,15 +354,15 @@
351354
i32.const 15
352355
i32.and
353356
i32.shr_u
354-
i32.const 255
355-
i32.and
356357
i32.or
357358
return
358359
)
359360
(func $~lib/polyfills/bswap16<i16> (param $0 i32) (result i32)
361+
i32.const 1
362+
drop
360363
i32.const 2
361-
i32.const 4
362-
i32.le_u
364+
i32.const 1
365+
i32.eq
363366
drop
364367
i32.const 2
365368
i32.const 2
@@ -371,20 +374,21 @@
371374
i32.and
372375
i32.shl
373376
local.get $0
374-
i32.extend16_s
377+
i32.const 65535
378+
i32.and
375379
i32.const 8
376380
i32.const 15
377381
i32.and
378382
i32.shr_u
379-
i32.const 255
380-
i32.and
381383
i32.or
382384
return
383385
)
384386
(func $~lib/polyfills/bswap16<u32> (param $0 i32) (result i32)
387+
i32.const 1
388+
drop
385389
i32.const 4
386-
i32.const 4
387-
i32.le_u
390+
i32.const 1
391+
i32.eq
388392
drop
389393
i32.const 4
390394
i32.const 2
@@ -395,10 +399,10 @@
395399
i32.eq
396400
drop
397401
local.get $0
402+
i32.const 255
403+
i32.and
398404
i32.const 8
399405
i32.shl
400-
i32.const 65280
401-
i32.and
402406
local.get $0
403407
i32.const 8
404408
i32.shr_u
@@ -412,9 +416,11 @@
412416
return
413417
)
414418
(func $~lib/polyfills/bswap16<i32> (param $0 i32) (result i32)
419+
i32.const 1
420+
drop
415421
i32.const 4
416-
i32.const 4
417-
i32.le_u
422+
i32.const 1
423+
i32.eq
418424
drop
419425
i32.const 4
420426
i32.const 2
@@ -425,10 +431,10 @@
425431
i32.eq
426432
drop
427433
local.get $0
434+
i32.const 255
435+
i32.and
428436
i32.const 8
429437
i32.shl
430-
i32.const 65280
431-
i32.and
432438
local.get $0
433439
i32.const 8
434440
i32.shr_u

0 commit comments

Comments
 (0)