-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlife-wasm.wat
190 lines (190 loc) · 12.9 KB
/
life-wasm.wat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
(module
(import "js" "log" (func $log (param i32) (param i32)))
(import "js" "callback" (func $callback (param i32) (param i32) (param i32) (param i32) (param i32) (result i32)))
(memory (import "js" "mem") 1)
(global $g_count (mut i32) (i32.const 0))
(global $hash_rand i32 (i32.const 179424673))
(global $g_hash (mut i32) (i32.const 0))
(func $life_prepare (param $cells i32) (param $X i32) (param $Y i32)
(local $cnt i32)
(local $hash i32)
(local $y i32)
(local $x i32)
(local $idx i32)
(local $dx i32)
(local $dy i32)
(local $didx i32)
(set_local $cnt (i32.const 0))
(set_local $hash (i32.const 0))
(block $@block_1_break
(set_local $y (i32.const 0))
(loop $@block_1_continue
(br_if $@block_1_break (i32.ge_s (get_local $y) (get_local $Y)))
(block $@block_1_1_break
(set_local $x (i32.const 0))
(loop $@block_1_1_continue
(br_if $@block_1_1_break (i32.ge_s (get_local $x) (get_local $X)))
(set_local $idx (i32.add (i32.mul (get_local $X) (get_local $y)) (get_local $x)))
(if (i32.eq (i32.load (i32.add (get_local $cells) (i32.mul (get_local $idx) (i32.const 4)))) (i32.const 1))
(then
(set_local $cnt (i32.add (get_local $cnt) (i32.const 1)))
(set_local $hash (i32.xor (get_local $hash) (i32.mul (get_local $idx) (global.get $hash_rand))))
(block $@block_1_1_1_break
(set_local $dx (i32.const -1))
(loop $@block_1_1_1_continue
(br_if $@block_1_1_1_break (i32.gt_s (get_local $dx) (i32.const 1)))
(block $@block_1_1_1_1_break
(set_local $dy (i32.const -1))
(loop $@block_1_1_1_1_continue
(br_if $@block_1_1_1_1_break (i32.gt_s (get_local $dy) (i32.const 1)))
(set_local $didx (i32.add (i32.mul (get_local $X) (i32.rem_s (i32.add (i32.add (get_local $y) (get_local $dy)) (get_local $Y)) (get_local $Y))) (i32.rem_s (i32.add (i32.add (get_local $x) (get_local $dx)) (get_local $X)) (get_local $X))))
(if (i32.eqz (i32.load (i32.add (get_local $cells) (i32.mul (get_local $didx) (i32.const 4)))))
(then
(i32.store (i32.add (get_local $cells) (i32.mul (get_local $didx) (i32.const 4))) (i32.const 2))))
(set_local $dy (i32.add (get_local $dy) (i32.const 1)))
(br $@block_1_1_1_1_continue)))
(set_local $dx (i32.add (get_local $dx) (i32.const 1)))
(br $@block_1_1_1_continue)))))
(set_local $x (i32.add (get_local $x) (i32.const 1)))
(br $@block_1_1_continue)))
(set_local $y (i32.add (get_local $y) (i32.const 1)))
(br $@block_1_continue)))
(global.set $g_count (get_local $cnt))
(global.set $g_hash (get_local $hash)))
(func $life_step (param $cells i32) (param $cellsnew i32) (param $X i32) (param $Y i32)
(local $x i32)
(local $y i32)
(local $n i32)
(local $newv i32)
(local $n00 i32)
(local $n01 i32)
(local $n02 i32)
(local $n10 i32)
(local $n12 i32)
(local $n20 i32)
(local $n21 i32)
(local $n22 i32)
(local $v00 i32)
(local $v01 i32)
(local $v02 i32)
(local $v10 i32)
(local $v11 i32)
(local $v12 i32)
(local $v20 i32)
(local $v21 i32)
(local $v22 i32)
(local $cnt i32)
(local $hash i32)
(local $p i32)
(local $ind i32)
(set_local $cnt (i32.const 0))
(set_local $hash (i32.const 0))
(set_local $p (i32.sub (get_local $cells) (i32.const 4)))
(set_local $ind (i32.const -1))
(memory.fill (get_local $cellsnew) (i32.const 0) (i32.mul (i32.mul (get_local $X) (get_local $Y)) (i32.const 4)))
(loop $@block_1_continue
(loop $@block_1_1_continue
(set_local $p (i32.add (get_local $p) (i32.const 4)))
(set_local $ind (i32.add (get_local $ind) (i32.const 1)))
(if (i32.eq (get_local $ind) (i32.mul (get_local $X) (get_local $Y)))
(then
(global.set $g_count (get_local $cnt))
(global.set $g_hash (get_local $hash))
(return)))
(br_if $@block_1_1_continue (i32.eqz (i32.load (get_local $p)))))
(set_local $y (i32.div_s (get_local $ind) (get_local $X)))
(set_local $x (i32.sub (get_local $ind) (i32.mul (get_local $y) (get_local $X))))
(if (i32.and (i32.and (i32.and (i32.gt_s (get_local $x) (i32.const 0)) (i32.lt_s (get_local $x) (i32.sub (get_local $X) (i32.const 1)))) (i32.gt_s (get_local $y) (i32.const 0))) (i32.lt_s (get_local $y) (i32.sub (get_local $Y) (i32.const 1))))
(then
(set_local $n00 (i32.add (i32.mul (get_local $X) (i32.sub (get_local $y) (i32.const 1))) (i32.sub (get_local $x) (i32.const 1))))
(set_local $n01 (i32.add (get_local $n00) (i32.const 1)))
(set_local $n02 (i32.add (get_local $n01) (i32.const 1)))
(set_local $n10 (i32.sub (get_local $ind) (i32.const 1)))
(set_local $n12 (i32.add (get_local $ind) (i32.const 1)))
(set_local $n20 (i32.add (get_local $n10) (get_local $X)))
(set_local $n21 (i32.add (get_local $n20) (i32.const 1)))
(set_local $n22 (i32.add (get_local $n21) (i32.const 1))))
(else
(set_local $n00 (i32.add (i32.mul (get_local $X) (i32.rem_s (i32.add (i32.add (get_local $y) (i32.const -1)) (get_local $Y)) (get_local $Y))) (i32.rem_s (i32.add (i32.add (get_local $x) (i32.const -1)) (get_local $X)) (get_local $X))))
(set_local $n01 (i32.add (i32.mul (get_local $X) (i32.rem_s (i32.add (i32.add (get_local $y) (i32.const -1)) (get_local $Y)) (get_local $Y))) (i32.rem_s (i32.add (get_local $x) (get_local $X)) (get_local $X))))
(set_local $n02 (i32.add (i32.mul (get_local $X) (i32.rem_s (i32.add (i32.add (get_local $y) (i32.const -1)) (get_local $Y)) (get_local $Y))) (i32.rem_s (i32.add (i32.add (get_local $x) (i32.const 1)) (get_local $X)) (get_local $X))))
(set_local $n10 (i32.add (i32.mul (get_local $X) (i32.rem_s (i32.add (get_local $y) (get_local $Y)) (get_local $Y))) (i32.rem_s (i32.add (i32.add (get_local $x) (i32.const -1)) (get_local $X)) (get_local $X))))
(set_local $n12 (i32.add (i32.mul (get_local $X) (i32.rem_s (i32.add (get_local $y) (get_local $Y)) (get_local $Y))) (i32.rem_s (i32.add (i32.add (get_local $x) (i32.const 1)) (get_local $X)) (get_local $X))))
(set_local $n20 (i32.add (i32.mul (get_local $X) (i32.rem_s (i32.add (i32.add (get_local $y) (i32.const 1)) (get_local $Y)) (get_local $Y))) (i32.rem_s (i32.add (i32.add (get_local $x) (i32.const -1)) (get_local $X)) (get_local $X))))
(set_local $n21 (i32.add (i32.mul (get_local $X) (i32.rem_s (i32.add (i32.add (get_local $y) (i32.const 1)) (get_local $Y)) (get_local $Y))) (i32.rem_s (i32.add (get_local $x) (get_local $X)) (get_local $X))))
(set_local $n22 (i32.add (i32.mul (get_local $X) (i32.rem_s (i32.add (i32.add (get_local $y) (i32.const 1)) (get_local $Y)) (get_local $Y))) (i32.rem_s (i32.add (i32.add (get_local $x) (i32.const 1)) (get_local $X)) (get_local $X))))))
(set_local $v00 (i32.eq (i32.const 1) (i32.load (i32.add (get_local $cells) (i32.mul (get_local $n00) (i32.const 4))))))
(set_local $v01 (i32.eq (i32.const 1) (i32.load (i32.add (get_local $cells) (i32.mul (get_local $n01) (i32.const 4))))))
(set_local $v02 (i32.eq (i32.const 1) (i32.load (i32.add (get_local $cells) (i32.mul (get_local $n02) (i32.const 4))))))
(set_local $v10 (i32.eq (i32.const 1) (i32.load (i32.add (get_local $cells) (i32.mul (get_local $n10) (i32.const 4))))))
(set_local $v11 (i32.eq (i32.const 1) (i32.load (get_local $p))))
(set_local $v12 (i32.eq (i32.const 1) (i32.load (i32.add (get_local $cells) (i32.mul (get_local $n12) (i32.const 4))))))
(set_local $v20 (i32.eq (i32.const 1) (i32.load (i32.add (get_local $cells) (i32.mul (get_local $n20) (i32.const 4))))))
(set_local $v21 (i32.eq (i32.const 1) (i32.load (i32.add (get_local $cells) (i32.mul (get_local $n21) (i32.const 4))))))
(set_local $v22 (i32.eq (i32.const 1) (i32.load (i32.add (get_local $cells) (i32.mul (get_local $n22) (i32.const 4))))))
(set_local $n (i32.add (i32.add (i32.add (i32.add (i32.add (i32.add (i32.add (get_local $v00) (get_local $v01)) (get_local $v02)) (get_local $v10)) (get_local $v12)) (get_local $v20)) (get_local $v21)) (get_local $v22)))
(set_local $newv (i32.or (i32.eq (get_local $n) (i32.const 3)) (i32.and (i32.eq (get_local $n) (i32.const 2)) (get_local $v11))))
(if (get_local $newv)
(then
(set_local $cnt (i32.add (get_local $cnt) (i32.const 1)))
(set_local $hash (i32.xor (get_local $hash) (i32.mul (get_local $ind) (global.get $hash_rand))))
(i32.store (i32.add (get_local $cellsnew) (i32.mul (get_local $ind) (i32.const 4))) (get_local $newv))
(if (i32.ne (i32.load (i32.add (get_local $cellsnew) (i32.mul (get_local $n00) (i32.const 4)))) (i32.const 1))
(then
(i32.store (i32.add (get_local $cellsnew) (i32.mul (get_local $n00) (i32.const 4))) (i32.const 2))))
(if (i32.ne (i32.load (i32.add (get_local $cellsnew) (i32.mul (get_local $n01) (i32.const 4)))) (i32.const 1))
(then
(i32.store (i32.add (get_local $cellsnew) (i32.mul (get_local $n01) (i32.const 4))) (i32.const 2))))
(if (i32.ne (i32.load (i32.add (get_local $cellsnew) (i32.mul (get_local $n02) (i32.const 4)))) (i32.const 1))
(then
(i32.store (i32.add (get_local $cellsnew) (i32.mul (get_local $n02) (i32.const 4))) (i32.const 2))))
(if (i32.ne (i32.load (i32.add (get_local $cellsnew) (i32.mul (get_local $n10) (i32.const 4)))) (i32.const 1))
(then
(i32.store (i32.add (get_local $cellsnew) (i32.mul (get_local $n10) (i32.const 4))) (i32.const 2))))
(if (i32.ne (i32.load (i32.add (get_local $cellsnew) (i32.mul (get_local $n12) (i32.const 4)))) (i32.const 1))
(then
(i32.store (i32.add (get_local $cellsnew) (i32.mul (get_local $n12) (i32.const 4))) (i32.const 2))))
(if (i32.ne (i32.load (i32.add (get_local $cellsnew) (i32.mul (get_local $n20) (i32.const 4)))) (i32.const 1))
(then
(i32.store (i32.add (get_local $cellsnew) (i32.mul (get_local $n20) (i32.const 4))) (i32.const 2))))
(if (i32.ne (i32.load (i32.add (get_local $cellsnew) (i32.mul (get_local $n21) (i32.const 4)))) (i32.const 1))
(then
(i32.store (i32.add (get_local $cellsnew) (i32.mul (get_local $n21) (i32.const 4))) (i32.const 2))))
(if (i32.ne (i32.load (i32.add (get_local $cellsnew) (i32.mul (get_local $n22) (i32.const 4)))) (i32.const 1))
(then
(i32.store (i32.add (get_local $cellsnew) (i32.mul (get_local $n22) (i32.const 4))) (i32.const 2))))))
(br $@block_1_continue)))
(func $run (export "run") (param $X i32) (param $Y i32) (param $N i32) (result i32)
(local $pos_0 i32)
(local $pos_1 i32)
(local $hash_1 i32)
(local $hash_2 i32)
(local $hash_3 i32)
(local $hash_4 i32)
(local $i i32)
(set_local $pos_0 (i32.const 0))
(set_local $pos_1 (i32.add (get_local $pos_0) (i32.mul (i32.mul (get_local $X) (get_local $Y)) (i32.const 4))))
(set_local $hash_4 (tee_local $hash_3 (tee_local $hash_2 (tee_local $hash_1 (i32.const 0)))))
(call $life_prepare (get_local $pos_0) (get_local $X) (get_local $Y))
(block $@block_1_break
(set_local $i (i32.const 0))
(loop $@block_1_continue
(br_if $@block_1_break (i32.ge_s (get_local $i) (get_local $N)))
(if (i32.eqz (i32.rem_s (get_local $i) (i32.const 2)))
(then
(call $life_step (get_local $pos_0) (get_local $pos_1) (get_local $X) (get_local $Y)))
(else
(call $life_step (get_local $pos_1) (get_local $pos_0) (get_local $X) (get_local $Y))))
(if (i32.eq (i32.const 1) (call $callback (get_local $X) (get_local $Y) (i32.add (get_local $i) (i32.const 1)) (global.get $g_count) (global.get $g_hash)))
(then
(return (i32.add (get_local $i) (i32.const 1)))))
(if (block $@block_1_1_break (result i32) (drop (br_if $@block_1_1_break (i32.const 1) (i32.eq (global.get $g_hash) (get_local $hash_1)))) (drop (br_if $@block_1_1_break (i32.const 1) (i32.eq (global.get $g_hash) (get_local $hash_2)))) (drop (br_if $@block_1_1_break (i32.const 1) (i32.eq (global.get $g_hash) (get_local $hash_3)))) (drop (br_if $@block_1_1_break (i32.const 1) (i32.eq (global.get $g_hash) (get_local $hash_4)))) (i32.const 0))
(then
(return (i32.add (get_local $i) (i32.const 1)))))
(set_local $hash_1 (get_local $hash_2))
(set_local $hash_2 (get_local $hash_3))
(set_local $hash_3 (get_local $hash_4))
(set_local $hash_4 (global.get $g_hash))
(set_local $i (i32.add (get_local $i) (i32.const 1)))
(br $@block_1_continue)))
(get_local $N)))