-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathgeo3x3.ll
253 lines (186 loc) · 5.67 KB
/
geo3x3.ll
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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
declare dso_local i64 @strlen(i8*)
define dso_local i32 @encode(double %lat, double %lng, i8 %level, i8* %buff, i64 %buff.len) {
%pret = alloca i32
%pc.begin = getelementptr i8, i8* %buff, i8 0
%level.64 = zext i8 %level to i64
%cmp.levela = icmp ult i8 %level, 1 ;; when level too small
%cmp.levelb = icmp uge i64 %level.64, %buff.len ;; when %buff.len not enough
%cmp.level = or i1 %cmp.levela, %cmp.levelb
br i1 %cmp.level, label %level.ng, label %level.ok
level.ng:
store i8 0, i8* %pc.begin ;; terminate string
store i32 1, i32* %pret ;; return 1
br label %exit
level.ok:
%plat = alloca double
%plng = alloca double
%punit = alloca double
%lat0 = fadd double %lat, 90.0
store double %lat0, double* %plat
store double %lng, double* %plng
store double 180.0, double* %punit
%cmp.ew = fcmp oge double %lng, 0.0
br i1 %cmp.ew, label %ew.east, label %ew.west
ew.east:
store i8 69, i8* %pc.begin ;; 'E'
br label %loop.init
ew.west:
%lng0 = load double, double* %plng
%lng1 = fadd double %lng0, 180.0
store double %lng1, double* %plng
store i8 87, i8* %pc.begin ;; 'W'
br label %loop.init
loop.init:
%pi = alloca i8
store i8 1, i8* %pi
br label %loop.main
loop.main:
%i = load i8, i8* %pi
%clat = load double, double* %plat
%clng = load double, double* %plng
%cunit = load double, double* %punit
%nunit = fdiv double %cunit, 3.0
%x0 = fdiv double %clng, %nunit
%y0 = fdiv double %clat, %nunit
%x = fptoui double %x0 to i8 ;; floor
%y = fptoui double %y0 to i8 ;; floor
%c0 = add i8 48, %x ;; '0'
%ym = mul i8 %y, 3
%c1 = add i8 %c0, %ym
%c = add i8 %c1, 1
%pc = getelementptr i8, i8* %buff, i8 %i
store i8 %c, i8* %pc
%x1 = uitofp i8 %x to double
%y1 = uitofp i8 %y to double
%lng2 = fmul double %x1, %nunit
%lat2 = fmul double %y1, %nunit
%nlng = fsub double %clng, %lng2
%nlat = fsub double %clat, %lat2
store double %nunit, double* %punit
store double %nlng, double* %plng
store double %nlat, double* %plat
%ni = add i8 %i, 1
store i8 %ni, i8* %pi
%cmp.i = icmp ult i8 %ni, %level
br i1 %cmp.i, label %loop.main, label %loop.term
loop.term:
%pc.end = getelementptr i8, i8* %buff, i8 %ni
store i8 0, i8* %pc.end
store i32 0, i32* %pret
br label %exit
exit:
%ret = load i32, i32* %pret
ret i32 %ret
}
define dso_local i32 @decode(i8* %code,
double* %plat, double* %plng, i8* %plevel, double* %punit) {
%pret = alloca i32
%code.len = call i64 @strlen(i8* %code)
%cmp.code = icmp eq i64 %code.len, 0
br i1 %cmp.code, label %code.ng, label %code.ok
code.ng:
store double 0.0, double* %plat
store double 0.0, double* %plng
store i8 0, i8* %plevel
store double 0.0, double* %punit
store i32 1, i32* %pret ;; return 1
br label %exit
code.ok:
%pbegin = alloca i64
%pflg = alloca i1
store i64 0, i64* %pbegin
store i1 0, i1* %pflg
%pc.begin = getelementptr i8, i8* %code, i8 0
%c.begin = load i8, i8* %pc.begin
br label %check.west
check.west:
%eq.minus = icmp eq i8 %c.begin, 45 ;;'-'
%eq.w = icmp eq i8 %c.begin, 87 ;;'W'
%cmp.west = or i1 %eq.minus, %eq.w
br i1 %cmp.west, label %ew.west, label %check.east
check.east:
%eq.plus = icmp eq i8 %c.begin, 43 ;;'+'
%eq.e = icmp eq i8 %c.begin, 69 ;;'E'
%cmp.east = or i1 %eq.plus, %eq.e
br i1 %cmp.east, label %ew.east, label %loop.init
ew.west:
store i64 1, i64* %pbegin
store i1 1, i1* %pflg
br label %loop.init
ew.east:
store i64 1, i64* %pbegin
br label %loop.init
loop.init:
store double 180.0, double* %punit
store double 0.0, double* %plat
store double 0.0, double* %plng
store i8 1, i8* %plevel
%pi = alloca i64
%begin = load i64, i64* %pbegin
store i64 %begin, i64* %pi
br label %loop.main
loop.main:
%i = load i64, i64* %pi
%pc = getelementptr i8, i8* %code, i64 %i
%c = load i8, i8* %pc
%n = sub i8 %c, 48 ;; '0'
%n.lt.one = icmp ult i8 %n, 1
%n.gt.nine = icmp ugt i8 %n, 9
%cmp.n = or i1 %n.lt.one, %n.gt.nine
br i1 %cmp.n, label %loop.break, label %loop.continue
loop.break:
store double 0.0, double* %plat
store double 0.0, double* %plng
store i8 0, i8* %plevel
store double 0.0, double* %punit
store i32 2, i32* %pret ;; return 2
br label %exit
loop.continue:
%cunit = load double, double* %punit
%clat = load double, double* %plat
%clng = load double, double* %plng
%clevel = load i8, i8* %plevel
%n1 = sub i8 %n, 1
%nmod.i8 = urem i8 %n1, 3
%ndiv.i8 = udiv i8 %n1, 3
%nmod = uitofp i8 %nmod.i8 to double
%ndiv = uitofp i8 %ndiv.i8 to double
%nunit = fdiv double %cunit, 3.0
store double %nunit, double* %punit
%nmod1 = fmul double %nmod, %nunit
%nlng = fadd double %clng, %nmod1
store double %nlng, double* %plng
%ndiv1 = fmul double %ndiv, %nunit
%nlat = fadd double %clat, %ndiv1
store double %nlat, double* %plat
%nlevel = add i8 %clevel, 1
store i8 %nlevel, i8* %plevel
%ni = add i64 %i, 1
store i64 %ni, i64* %pi
%cmp.i = icmp ult i64 %ni, %code.len
br i1 %cmp.i, label %loop.main, label %loop.term
loop.term:
%unit0 = load double, double* %punit
%lat0 = load double, double* %plat
%lng0 = load double, double* %plng
%unit1 = fdiv double %unit0, 2.0
%lat1 = fadd double %lat0, %unit1
%lng1 = fadd double %lng0, %unit1
%lat2 = fsub double %lat1, 90.0
store double %lat2, double* %plat
store double %lng1, double* %plng
%flg = load i1, i1* %pflg
br i1 %flg, label %flg.true, label %flg.false
flg.true:
%lng2 = fsub double %lng1, 180.0
store double %lng2, double* %plng
br label %flg.term
flg.false:
br label %flg.term
flg.term:
store i32 0, i32* %pret
br label %exit
exit:
%ret = load i32, i32* %pret
ret i32 %ret
}