Skip to content

Commit 1188b8a

Browse files
authored
feat: Implement nontrapping-f2i proposal (AssemblyScript#1651)
1 parent b204216 commit 1188b8a

File tree

7 files changed

+242
-9
lines changed

7 files changed

+242
-9
lines changed

cli/asc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@
210210
"Enables WebAssembly features being disabled by default.",
211211
"",
212212
" sign-extension Sign-extension operations",
213+
" nontrapping-f2i Non-trapping float to integer ops.",
213214
" bulk-memory Bulk memory operations.",
214215
" simd SIMD types and operations.",
215216
" threads Threading and atomic operations.",
@@ -218,7 +219,6 @@
218219
""
219220
],
220221
"TODO_doesNothingYet": [
221-
" nontrapping-f2i Non-trapping float to integer ops.",
222222
" exception-handling Exception handling.",
223223
" tail-calls Tail call operations.",
224224
" multi-value Multi value types.",

src/compiler.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3603,16 +3603,18 @@ export class Compiler extends DiagnosticEmitter {
36033603
if (toType.isBooleanValue) {
36043604
expr = this.makeIsTrueish(expr, Type.f32, reportNode);
36053605
} else if (toType.isSignedIntegerValue) {
3606+
let saturating = this.options.hasFeature(Feature.NONTRAPPING_F2I);
36063607
if (toType.isLongIntegerValue) {
3607-
expr = module.unary(UnaryOp.TruncF32ToI64, expr);
3608+
expr = module.unary(saturating ? UnaryOp.TruncF32ToI64Sat : UnaryOp.TruncF32ToI64, expr);
36083609
} else {
3609-
expr = module.unary(UnaryOp.TruncF32ToI32, expr);
3610+
expr = module.unary(saturating ? UnaryOp.TruncF32ToI32Sat : UnaryOp.TruncF32ToI32, expr);
36103611
}
36113612
} else {
3613+
let saturating = this.options.hasFeature(Feature.NONTRAPPING_F2I);
36123614
if (toType.isLongIntegerValue) {
3613-
expr = module.unary(UnaryOp.TruncF32ToU64, expr);
3615+
expr = module.unary(saturating ? UnaryOp.TruncF32ToU64Sat : UnaryOp.TruncF32ToU64, expr);
36143616
} else {
3615-
expr = module.unary(UnaryOp.TruncF32ToU32, expr);
3617+
expr = module.unary(saturating ? UnaryOp.TruncF32ToU32Sat : UnaryOp.TruncF32ToU32, expr);
36163618
}
36173619
}
36183620

@@ -3621,16 +3623,18 @@ export class Compiler extends DiagnosticEmitter {
36213623
if (toType.isBooleanValue) {
36223624
expr = this.makeIsTrueish(expr, Type.f64, reportNode);
36233625
} else if (toType.isSignedIntegerValue) {
3626+
let saturating = this.options.hasFeature(Feature.NONTRAPPING_F2I);
36243627
if (toType.isLongIntegerValue) {
3625-
expr = module.unary(UnaryOp.TruncF64ToI64, expr);
3628+
expr = module.unary(saturating ? UnaryOp.TruncF64ToI64Sat : UnaryOp.TruncF64ToI64, expr);
36263629
} else {
3627-
expr = module.unary(UnaryOp.TruncF64ToI32, expr);
3630+
expr = module.unary(saturating ? UnaryOp.TruncF64ToI32Sat : UnaryOp.TruncF64ToI32, expr);
36283631
}
36293632
} else {
3633+
let saturating = this.options.hasFeature(Feature.NONTRAPPING_F2I);
36303634
if (toType.isLongIntegerValue) {
3631-
expr = module.unary(UnaryOp.TruncF64ToU64, expr);
3635+
expr = module.unary(saturating ? UnaryOp.TruncF64ToU64Sat : UnaryOp.TruncF64ToU64, expr);
36323636
} else {
3633-
expr = module.unary(UnaryOp.TruncF64ToU32, expr);
3637+
expr = module.unary(saturating ? UnaryOp.TruncF64ToU32Sat : UnaryOp.TruncF64ToU32, expr);
36343638
}
36353639
}
36363640
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"features": [
3+
"nontrapping-f2i"
4+
],
5+
"asc_flags": [
6+
"--explicitStart"
7+
]
8+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
(module
2+
(type $none_=>_none (func))
3+
(memory $0 0)
4+
(global $~started (mut i32) (i32.const 0))
5+
(export "memory" (memory $0))
6+
(export "_start" (func $~start))
7+
(func $~start
8+
global.get $~started
9+
if
10+
return
11+
end
12+
i32.const 1
13+
global.set $~started
14+
)
15+
)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// f32->i32
2+
assert(<i32>f32.MAX_VALUE == i32.MAX_VALUE);
3+
assert(<i32>-f32.MAX_VALUE == i32.MIN_VALUE);
4+
assert(<i32>f32.NaN == 0);
5+
6+
// f32->i64
7+
assert(<i64>f32.MAX_VALUE == i64.MAX_VALUE);
8+
assert(<i64>-f32.MAX_VALUE == i64.MIN_VALUE);
9+
assert(<i64>f32.NaN == 0);
10+
11+
// f32->u32
12+
assert(<u32>f32.MAX_VALUE == u32.MAX_VALUE);
13+
assert(<u32>-f32.MAX_VALUE == u32.MIN_VALUE);
14+
assert(<u32>f32.NaN == 0);
15+
16+
// f32->u64
17+
assert(<u64>f32.MAX_VALUE == u64.MAX_VALUE);
18+
assert(<u64>-f32.MAX_VALUE == u64.MIN_VALUE);
19+
assert(<u64>f32.NaN == 0);
20+
21+
// f64->i32
22+
assert(<i32>f64.MAX_VALUE == i32.MAX_VALUE);
23+
assert(<i32>-f64.MAX_VALUE == i32.MIN_VALUE);
24+
assert(<i32>f64.NaN == 0);
25+
26+
// f64->i64
27+
assert(<i64>f64.MAX_VALUE == i64.MAX_VALUE);
28+
assert(<i64>-f64.MAX_VALUE == i64.MIN_VALUE);
29+
assert(<i64>f64.NaN == 0);
30+
31+
// f64->u32
32+
assert(<u32>f64.MAX_VALUE == u32.MAX_VALUE);
33+
assert(<u32>-f64.MAX_VALUE == u32.MIN_VALUE);
34+
assert(<u32>f64.NaN == 0);
35+
36+
// f64->u64
37+
assert(<u64>f64.MAX_VALUE == u64.MAX_VALUE);
38+
assert(<u64>-f64.MAX_VALUE == u64.MIN_VALUE);
39+
assert(<u64>f64.NaN == 0);
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
(module
2+
(type $none_=>_none (func))
3+
(memory $0 0)
4+
(table $0 1 funcref)
5+
(global $~lib/builtins/f32.MAX_VALUE f32 (f32.const 3402823466385288598117041e14))
6+
(global $~lib/builtins/i32.MAX_VALUE i32 (i32.const 2147483647))
7+
(global $~lib/builtins/i32.MIN_VALUE i32 (i32.const -2147483648))
8+
(global $~lib/builtins/f32.NaN f32 (f32.const nan:0x400000))
9+
(global $~lib/builtins/i64.MAX_VALUE i64 (i64.const 9223372036854775807))
10+
(global $~lib/builtins/i64.MIN_VALUE i64 (i64.const -9223372036854775808))
11+
(global $~lib/builtins/u32.MAX_VALUE i32 (i32.const -1))
12+
(global $~lib/builtins/u32.MIN_VALUE i32 (i32.const 0))
13+
(global $~lib/builtins/u64.MAX_VALUE i64 (i64.const -1))
14+
(global $~lib/builtins/u64.MIN_VALUE i64 (i64.const 0))
15+
(global $~lib/builtins/f64.MAX_VALUE f64 (f64.const 1797693134862315708145274e284))
16+
(global $~lib/builtins/f64.NaN f64 (f64.const nan:0x8000000000000))
17+
(global $~lib/memory/__data_end i32 (i32.const 8))
18+
(global $~lib/memory/__stack_pointer (mut i32) (i32.const 16392))
19+
(global $~lib/memory/__heap_base i32 (i32.const 16392))
20+
(global $~started (mut i32) (i32.const 0))
21+
(export "memory" (memory $0))
22+
(export "_start" (func $~start))
23+
(func $start:features/nontrapping-f2i
24+
global.get $~lib/builtins/f32.MAX_VALUE
25+
i32.trunc_sat_f32_s
26+
global.get $~lib/builtins/i32.MAX_VALUE
27+
i32.eq
28+
drop
29+
global.get $~lib/builtins/f32.MAX_VALUE
30+
f32.neg
31+
i32.trunc_sat_f32_s
32+
global.get $~lib/builtins/i32.MIN_VALUE
33+
i32.eq
34+
drop
35+
global.get $~lib/builtins/f32.NaN
36+
i32.trunc_sat_f32_s
37+
i32.const 0
38+
i32.eq
39+
drop
40+
global.get $~lib/builtins/f32.MAX_VALUE
41+
i64.trunc_sat_f32_s
42+
global.get $~lib/builtins/i64.MAX_VALUE
43+
i64.eq
44+
drop
45+
global.get $~lib/builtins/f32.MAX_VALUE
46+
f32.neg
47+
i64.trunc_sat_f32_s
48+
global.get $~lib/builtins/i64.MIN_VALUE
49+
i64.eq
50+
drop
51+
global.get $~lib/builtins/f32.NaN
52+
i64.trunc_sat_f32_s
53+
i64.const 0
54+
i64.eq
55+
drop
56+
global.get $~lib/builtins/f32.MAX_VALUE
57+
i32.trunc_sat_f32_u
58+
global.get $~lib/builtins/u32.MAX_VALUE
59+
i32.eq
60+
drop
61+
global.get $~lib/builtins/f32.MAX_VALUE
62+
f32.neg
63+
i32.trunc_sat_f32_u
64+
global.get $~lib/builtins/u32.MIN_VALUE
65+
i32.eq
66+
drop
67+
global.get $~lib/builtins/f32.NaN
68+
i32.trunc_sat_f32_u
69+
i32.const 0
70+
i32.eq
71+
drop
72+
global.get $~lib/builtins/f32.MAX_VALUE
73+
i64.trunc_sat_f32_u
74+
global.get $~lib/builtins/u64.MAX_VALUE
75+
i64.eq
76+
drop
77+
global.get $~lib/builtins/f32.MAX_VALUE
78+
f32.neg
79+
i64.trunc_sat_f32_u
80+
global.get $~lib/builtins/u64.MIN_VALUE
81+
i64.eq
82+
drop
83+
global.get $~lib/builtins/f32.NaN
84+
i64.trunc_sat_f32_u
85+
i64.const 0
86+
i64.eq
87+
drop
88+
global.get $~lib/builtins/f64.MAX_VALUE
89+
i32.trunc_sat_f64_s
90+
global.get $~lib/builtins/i32.MAX_VALUE
91+
i32.eq
92+
drop
93+
global.get $~lib/builtins/f64.MAX_VALUE
94+
f64.neg
95+
i32.trunc_sat_f64_s
96+
global.get $~lib/builtins/i32.MIN_VALUE
97+
i32.eq
98+
drop
99+
global.get $~lib/builtins/f64.NaN
100+
i32.trunc_sat_f64_s
101+
i32.const 0
102+
i32.eq
103+
drop
104+
global.get $~lib/builtins/f64.MAX_VALUE
105+
i64.trunc_sat_f64_s
106+
global.get $~lib/builtins/i64.MAX_VALUE
107+
i64.eq
108+
drop
109+
global.get $~lib/builtins/f64.MAX_VALUE
110+
f64.neg
111+
i64.trunc_sat_f64_s
112+
global.get $~lib/builtins/i64.MIN_VALUE
113+
i64.eq
114+
drop
115+
global.get $~lib/builtins/f64.NaN
116+
i64.trunc_sat_f64_s
117+
i64.const 0
118+
i64.eq
119+
drop
120+
global.get $~lib/builtins/f64.MAX_VALUE
121+
i32.trunc_sat_f64_u
122+
global.get $~lib/builtins/u32.MAX_VALUE
123+
i32.eq
124+
drop
125+
global.get $~lib/builtins/f64.MAX_VALUE
126+
f64.neg
127+
i32.trunc_sat_f64_u
128+
global.get $~lib/builtins/u32.MIN_VALUE
129+
i32.eq
130+
drop
131+
global.get $~lib/builtins/f64.NaN
132+
i32.trunc_sat_f64_u
133+
i32.const 0
134+
i32.eq
135+
drop
136+
global.get $~lib/builtins/f64.MAX_VALUE
137+
i64.trunc_sat_f64_u
138+
global.get $~lib/builtins/u64.MAX_VALUE
139+
i64.eq
140+
drop
141+
global.get $~lib/builtins/f64.MAX_VALUE
142+
f64.neg
143+
i64.trunc_sat_f64_u
144+
global.get $~lib/builtins/u64.MIN_VALUE
145+
i64.eq
146+
drop
147+
global.get $~lib/builtins/f64.NaN
148+
i64.trunc_sat_f64_u
149+
i64.const 0
150+
i64.eq
151+
drop
152+
)
153+
(func $~start
154+
global.get $~started
155+
if
156+
return
157+
end
158+
i32.const 1
159+
global.set $~started
160+
call $start:features/nontrapping-f2i
161+
)
162+
)

tests/features.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
{
22
"mutable-globals": {
33
},
4+
"nontrapping-f2i": {
5+
"asc_flags": [
6+
"--enable nontrapping-f2i"
7+
]
8+
},
49
"simd": {
510
"asc_flags": [
611
"--enable simd"

0 commit comments

Comments
 (0)