Rev 8097 | Rev 9177 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
7983 | leency | 1 | (* |
2 | BSD 2-Clause License |
||
3 | |||
8859 | leency | 4 | Copyright (c) 2019-2021, Anton Krotov |
7983 | leency | 5 | All rights reserved. |
6 | *) |
||
7 | |||
8 | MODULE THUMB; |
||
9 | |||
10 | IMPORT PROG, LISTS, CHL := CHUNKLISTS, BIN, REG, IL, C := CONSOLE, |
||
11 | UTILS, WR := WRITER, HEX, ERRORS, TARGETS; |
||
12 | |||
13 | |||
14 | CONST |
||
15 | |||
16 | R0 = 0; R1 = 1; R2 = 2; R3 = 3; R4 = 4; |
||
17 | |||
18 | SP = 13; LR = 14; PC = 15; |
||
19 | |||
20 | ACC = R0; |
||
21 | |||
22 | je = 0; jne = 1; jnb = 2; jb = 3; jge = 10; jl = 11; jg = 12; jle = 13; |
||
23 | |||
24 | inf = 7F800000H; |
||
25 | |||
8859 | leency | 26 | minROM* = 16; maxROM* = 65536; |
27 | minRAM* = 4; maxRAM* = 65536; |
||
7983 | leency | 28 | |
29 | maxIVT* = 1023; |
||
30 | |||
8859 | leency | 31 | _THUMB2 = 0; _IT = 1; _SDIV = 2; _CBXZ = 3; |
7983 | leency | 32 | |
8859 | leency | 33 | CortexM0 = {}; |
34 | CortexM1 = {}; |
||
35 | CortexM3 = {_THUMB2, _IT, _SDIV, _CBXZ}; |
||
36 | CortexM23 = {_SDIV, _CBXZ}; |
||
37 | |||
38 | |||
7983 | leency | 39 | TYPE |
40 | |||
41 | COMMAND = IL.COMMAND; |
||
42 | |||
43 | ANYCODE = POINTER TO RECORD (LISTS.ITEM) |
||
44 | |||
45 | offset: INTEGER |
||
46 | |||
47 | END; |
||
48 | |||
49 | CODE = POINTER TO RECORD (ANYCODE) |
||
50 | |||
51 | code: INTEGER |
||
52 | |||
53 | END; |
||
54 | |||
55 | LABEL = POINTER TO RECORD (ANYCODE) |
||
56 | |||
57 | label: INTEGER |
||
58 | |||
59 | END; |
||
60 | |||
61 | JUMP = POINTER TO RECORD (ANYCODE) |
||
62 | |||
63 | label, diff, len, cond: INTEGER; |
||
64 | short: BOOLEAN |
||
65 | |||
66 | END; |
||
67 | |||
68 | JMP = POINTER TO RECORD (JUMP) |
||
69 | |||
70 | END; |
||
71 | |||
72 | JCC = POINTER TO RECORD (JUMP) |
||
73 | |||
74 | END; |
||
75 | |||
76 | CBXZ = POINTER TO RECORD (JUMP) |
||
77 | |||
78 | reg: INTEGER |
||
79 | |||
80 | END; |
||
81 | |||
82 | CALL = POINTER TO RECORD (JUMP) |
||
83 | |||
84 | END; |
||
85 | |||
86 | RELOC = POINTER TO RECORD (ANYCODE) |
||
87 | |||
88 | reg, rel, value: INTEGER |
||
89 | |||
90 | END; |
||
91 | |||
92 | RELOCCODE = ARRAY 7 OF INTEGER; |
||
93 | |||
94 | |||
95 | VAR |
||
96 | |||
97 | R: REG.REGS; |
||
98 | |||
99 | tcount: INTEGER; |
||
100 | |||
101 | CodeList: LISTS.LIST; |
||
102 | |||
103 | program: BIN.PROGRAM; |
||
104 | |||
105 | StkCount: INTEGER; |
||
106 | |||
107 | Target: RECORD |
||
108 | FlashAdr, |
||
109 | SRAMAdr, |
||
110 | IVTLen, |
||
111 | MinStack, |
||
112 | Reserved: INTEGER; |
||
8859 | leency | 113 | InstrSet: SET; |
114 | isNXP: BOOLEAN |
||
7983 | leency | 115 | END; |
116 | |||
117 | IVT: ARRAY maxIVT + 1 OF INTEGER; |
||
118 | |||
119 | sdivProc, trap, genTrap, entry, emptyProc, int0, genInt: INTEGER; |
||
120 | |||
121 | |||
122 | PROCEDURE Code (code: INTEGER); |
||
123 | VAR |
||
124 | c: CODE; |
||
125 | |||
126 | BEGIN |
||
127 | NEW(c); |
||
128 | c.code := code; |
||
129 | LISTS.push(CodeList, c) |
||
130 | END Code; |
||
131 | |||
132 | |||
133 | PROCEDURE Label (label: INTEGER); |
||
134 | VAR |
||
135 | L: LABEL; |
||
136 | |||
137 | BEGIN |
||
138 | NEW(L); |
||
139 | L.label := label; |
||
140 | LISTS.push(CodeList, L) |
||
141 | END Label; |
||
142 | |||
143 | |||
144 | PROCEDURE jcc (cond, label: INTEGER); |
||
145 | VAR |
||
146 | j: JCC; |
||
147 | |||
148 | BEGIN |
||
149 | NEW(j); |
||
150 | j.label := label; |
||
151 | j.cond := cond; |
||
152 | j.short := FALSE; |
||
153 | j.len := 3; |
||
154 | LISTS.push(CodeList, j) |
||
155 | END jcc; |
||
156 | |||
157 | |||
158 | PROCEDURE cbxz (cond, reg, label: INTEGER); |
||
159 | VAR |
||
160 | j: CBXZ; |
||
161 | |||
162 | BEGIN |
||
163 | NEW(j); |
||
164 | j.label := label; |
||
165 | j.cond := cond; |
||
166 | j.reg := reg; |
||
167 | j.short := FALSE; |
||
168 | j.len := 4; |
||
169 | LISTS.push(CodeList, j) |
||
170 | END cbxz; |
||
171 | |||
172 | |||
173 | PROCEDURE jmp (label: INTEGER); |
||
174 | VAR |
||
175 | j: JMP; |
||
176 | |||
177 | BEGIN |
||
178 | NEW(j); |
||
179 | j.label := label; |
||
180 | j.short := FALSE; |
||
181 | j.len := 2; |
||
182 | LISTS.push(CodeList, j) |
||
183 | END jmp; |
||
184 | |||
185 | |||
186 | PROCEDURE call (label: INTEGER); |
||
187 | VAR |
||
188 | c: CALL; |
||
189 | |||
190 | BEGIN |
||
191 | NEW(c); |
||
192 | c.label := label; |
||
193 | c.short := FALSE; |
||
194 | c.len := 2; |
||
195 | LISTS.push(CodeList, c) |
||
196 | END call; |
||
197 | |||
198 | |||
199 | PROCEDURE reloc (reg, rel, value: INTEGER); |
||
200 | VAR |
||
201 | r: RELOC; |
||
202 | |||
203 | BEGIN |
||
204 | NEW(r); |
||
205 | r.reg := reg; |
||
206 | r.rel := rel; |
||
207 | r.value := value; |
||
208 | LISTS.push(CodeList, r) |
||
209 | END reloc; |
||
210 | |||
211 | |||
212 | PROCEDURE NewLabel (): INTEGER; |
||
213 | BEGIN |
||
214 | BIN.NewLabel(program) |
||
215 | RETURN IL.NewLabel() |
||
216 | END NewLabel; |
||
217 | |||
218 | |||
219 | PROCEDURE range (x, n: INTEGER): BOOLEAN; |
||
220 | RETURN (0 <= x) & (x < LSL(1, n)) |
||
221 | END range; |
||
222 | |||
223 | |||
224 | PROCEDURE srange (x, n: INTEGER): BOOLEAN; |
||
225 | RETURN (-LSL(1, n - 1) <= x) & (x < LSL(1, n - 1)) |
||
226 | END srange; |
||
227 | |||
228 | |||
229 | PROCEDURE gen1 (op, imm, rs, rd: INTEGER); |
||
230 | BEGIN |
||
231 | ASSERT(op IN {0..2}); |
||
232 | ASSERT(range(imm, 5)); |
||
233 | ASSERT(range(rs, 3)); |
||
234 | ASSERT(range(rd, 3)); |
||
235 | Code(LSL(op, 11) + LSL(imm, 6) + LSL(rs, 3) + rd) |
||
236 | END gen1; |
||
237 | |||
238 | |||
239 | PROCEDURE gen2 (i, op: BOOLEAN; imm, rs, rd: INTEGER); |
||
240 | BEGIN |
||
241 | ASSERT(range(imm, 3)); |
||
242 | ASSERT(range(rs, 3)); |
||
243 | ASSERT(range(rd, 3)); |
||
244 | Code(1800H + LSL(ORD(i), 10) + LSL(ORD(op), 9) + LSL(imm, 6) + LSL(rs, 3) + rd) |
||
245 | END gen2; |
||
246 | |||
247 | |||
248 | PROCEDURE gen3 (op, rd, imm: INTEGER); |
||
249 | BEGIN |
||
250 | ASSERT(range(op, 2)); |
||
251 | ASSERT(range(rd, 3)); |
||
252 | ASSERT(range(imm, 8)); |
||
253 | Code(2000H + LSL(op, 11) + LSL(rd, 8) + imm) |
||
254 | END gen3; |
||
255 | |||
256 | |||
257 | PROCEDURE gen4 (op, rs, rd: INTEGER); |
||
258 | BEGIN |
||
259 | ASSERT(range(op, 4)); |
||
260 | ASSERT(range(rs, 3)); |
||
261 | ASSERT(range(rd, 3)); |
||
262 | Code(4000H + LSL(op, 6) + LSL(rs, 3) + rd) |
||
263 | END gen4; |
||
264 | |||
265 | |||
266 | PROCEDURE gen5 (op: INTEGER; h1, h2: BOOLEAN; rs, rd: INTEGER); |
||
267 | BEGIN |
||
268 | ASSERT(range(op, 2)); |
||
269 | ASSERT(range(rs, 3)); |
||
270 | ASSERT(range(rd, 3)); |
||
271 | Code(4400H + LSL(op, 8) + LSL(ORD(h1), 7) + LSL(ORD(h2), 6) + LSL(rs, 3) + rd) |
||
272 | END gen5; |
||
273 | |||
274 | |||
275 | PROCEDURE gen7 (l, b: BOOLEAN; ro, rb, rd: INTEGER); |
||
276 | BEGIN |
||
277 | ASSERT(range(ro, 3)); |
||
278 | ASSERT(range(rb, 3)); |
||
279 | ASSERT(range(rd, 3)); |
||
280 | Code(5000H + LSL(ORD(l), 11) + LSL(ORD(b), 10) + LSL(ro, 6) + LSL(rb, 3) + rd) |
||
281 | END gen7; |
||
282 | |||
283 | |||
284 | PROCEDURE gen8 (h, s: BOOLEAN; ro, rb, rd: INTEGER); |
||
285 | BEGIN |
||
286 | ASSERT(range(ro, 3)); |
||
287 | ASSERT(range(rb, 3)); |
||
288 | ASSERT(range(rd, 3)); |
||
289 | Code(5200H + LSL(ORD(h), 11) + LSL(ORD(s), 10) + LSL(ro, 6) + LSL(rb, 3) + rd) |
||
290 | END gen8; |
||
291 | |||
292 | |||
293 | PROCEDURE gen9 (b, l: BOOLEAN; imm, rb, rd: INTEGER); |
||
294 | BEGIN |
||
295 | ASSERT(range(imm, 5)); |
||
296 | ASSERT(range(rb, 3)); |
||
297 | ASSERT(range(rd, 3)); |
||
298 | Code(6000H + LSL(ORD(b), 12) + LSL(ORD(l), 11) + LSL(imm, 6) + LSL(rb, 3) + rd) |
||
299 | END gen9; |
||
300 | |||
301 | |||
302 | PROCEDURE gen10 (l: BOOLEAN; imm, rb, rd: INTEGER); |
||
303 | BEGIN |
||
304 | ASSERT(range(imm, 5)); |
||
305 | ASSERT(range(rb, 3)); |
||
306 | ASSERT(range(rd, 3)); |
||
307 | Code(8000H + LSL(ORD(l), 11) + LSL(imm, 6) + LSL(rb, 3) + rd) |
||
308 | END gen10; |
||
309 | |||
310 | |||
311 | PROCEDURE gen11 (l: BOOLEAN; rd, imm: INTEGER); |
||
312 | BEGIN |
||
313 | ASSERT(range(rd, 3)); |
||
314 | ASSERT(range(imm, 8)); |
||
315 | Code(9000H + LSL(ORD(l), 11) + LSL(rd, 8) + imm) |
||
316 | END gen11; |
||
317 | |||
318 | |||
319 | PROCEDURE gen12 (sp: BOOLEAN; rd, imm: INTEGER); |
||
320 | BEGIN |
||
321 | ASSERT(range(rd, 3)); |
||
322 | ASSERT(range(imm, 8)); |
||
323 | Code(0A000H + LSL(ORD(sp), 11) + LSL(rd, 8) + imm) |
||
324 | END gen12; |
||
325 | |||
326 | |||
327 | PROCEDURE gen14 (l, r: BOOLEAN; rlist: SET); |
||
328 | VAR |
||
329 | i, n: INTEGER; |
||
330 | |||
331 | BEGIN |
||
332 | ASSERT(range(ORD(rlist), 8)); |
||
333 | |||
334 | n := ORD(r); |
||
335 | FOR i := 0 TO 7 DO |
||
336 | IF i IN rlist THEN |
||
337 | INC(n) |
||
338 | END |
||
339 | END; |
||
340 | |||
341 | IF l THEN |
||
342 | n := -n |
||
343 | END; |
||
344 | |||
345 | INC(StkCount, n); |
||
346 | |||
347 | Code(0B400H + LSL(ORD(l), 11) + LSL(ORD(r), 8) + ORD(rlist)) |
||
348 | END gen14; |
||
349 | |||
350 | |||
351 | PROCEDURE split16 (imm16: INTEGER; VAR imm4, imm1, imm3, imm8: INTEGER); |
||
352 | BEGIN |
||
353 | ASSERT(range(imm16, 16)); |
||
354 | imm8 := imm16 MOD 256; |
||
355 | imm4 := LSR(imm16, 12); |
||
356 | imm3 := LSR(imm16, 8) MOD 8; |
||
357 | imm1 := LSR(imm16, 11) MOD 2; |
||
358 | END split16; |
||
359 | |||
360 | |||
361 | PROCEDURE LslImm (r, imm5: INTEGER); |
||
362 | BEGIN |
||
363 | gen1(0, imm5, r, r) |
||
364 | END LslImm; |
||
365 | |||
366 | |||
367 | PROCEDURE LsrImm (r, imm5: INTEGER); |
||
368 | BEGIN |
||
369 | gen1(1, imm5, r, r) |
||
370 | END LsrImm; |
||
371 | |||
372 | |||
373 | PROCEDURE AsrImm (r, imm5: INTEGER); |
||
374 | BEGIN |
||
375 | gen1(2, imm5, r, r) |
||
376 | END AsrImm; |
||
377 | |||
378 | |||
379 | PROCEDURE AddReg (rd, rs, rn: INTEGER); |
||
380 | BEGIN |
||
381 | gen2(FALSE, FALSE, rn, rs, rd) |
||
382 | END AddReg; |
||
383 | |||
384 | |||
385 | PROCEDURE SubReg (rd, rs, rn: INTEGER); |
||
386 | BEGIN |
||
387 | gen2(FALSE, TRUE, rn, rs, rd) |
||
388 | END SubReg; |
||
389 | |||
390 | |||
391 | PROCEDURE AddImm8 (rd, imm8: INTEGER); |
||
392 | BEGIN |
||
393 | IF imm8 # 0 THEN |
||
394 | gen3(2, rd, imm8) |
||
395 | END |
||
396 | END AddImm8; |
||
397 | |||
398 | |||
399 | PROCEDURE SubImm8 (rd, imm8: INTEGER); |
||
400 | BEGIN |
||
401 | IF imm8 # 0 THEN |
||
402 | gen3(3, rd, imm8) |
||
403 | END |
||
404 | END SubImm8; |
||
405 | |||
406 | |||
407 | PROCEDURE AddSubImm12 (r, imm12: INTEGER; sub: BOOLEAN); |
||
408 | VAR |
||
409 | imm4, imm1, imm3, imm8: INTEGER; |
||
410 | |||
411 | BEGIN |
||
412 | split16(imm12, imm4, imm1, imm3, imm8); |
||
413 | Code(0F200H + LSL(imm1, 10) + r + 0A0H * ORD(sub)); (* addw/subw r, r, imm12 *) |
||
414 | Code(LSL(imm3, 12) + LSL(r, 8) + imm8) |
||
415 | END AddSubImm12; |
||
416 | |||
417 | |||
418 | PROCEDURE MovImm8 (rd, imm8: INTEGER); |
||
419 | BEGIN |
||
420 | gen3(0, rd, imm8) |
||
421 | END MovImm8; |
||
422 | |||
423 | |||
424 | PROCEDURE CmpImm8 (rd, imm8: INTEGER); |
||
425 | BEGIN |
||
426 | gen3(1, rd, imm8) |
||
427 | END CmpImm8; |
||
428 | |||
429 | |||
430 | PROCEDURE Neg (r: INTEGER); |
||
431 | BEGIN |
||
432 | gen4(9, r, r) |
||
433 | END Neg; |
||
434 | |||
435 | |||
436 | PROCEDURE Mul (rd, rs: INTEGER); |
||
437 | BEGIN |
||
438 | gen4(13, rs, rd) |
||
439 | END Mul; |
||
440 | |||
441 | |||
442 | PROCEDURE Str32 (rs, rb: INTEGER); |
||
443 | BEGIN |
||
444 | gen9(FALSE, FALSE, 0, rb, rs) |
||
445 | END Str32; |
||
446 | |||
447 | |||
448 | PROCEDURE Ldr32 (rd, rb: INTEGER); |
||
449 | BEGIN |
||
450 | gen9(FALSE, TRUE, 0, rb, rd) |
||
451 | END Ldr32; |
||
452 | |||
453 | |||
454 | PROCEDURE Str16 (rs, rb: INTEGER); |
||
455 | BEGIN |
||
456 | gen10(FALSE, 0, rb, rs) |
||
457 | END Str16; |
||
458 | |||
459 | |||
460 | PROCEDURE Ldr16 (rd, rb: INTEGER); |
||
461 | BEGIN |
||
462 | gen10(TRUE, 0, rb, rd) |
||
463 | END Ldr16; |
||
464 | |||
465 | |||
466 | PROCEDURE Str8 (rs, rb: INTEGER); |
||
467 | BEGIN |
||
468 | gen9(TRUE, FALSE, 0, rb, rs) |
||
469 | END Str8; |
||
470 | |||
471 | |||
472 | PROCEDURE Ldr8 (rd, rb: INTEGER); |
||
473 | BEGIN |
||
474 | gen9(TRUE, TRUE, 0, rb, rd) |
||
475 | END Ldr8; |
||
476 | |||
477 | |||
478 | PROCEDURE Cmp (r1, r2: INTEGER); |
||
479 | BEGIN |
||
480 | gen4(10, r2, r1) |
||
481 | END Cmp; |
||
482 | |||
483 | |||
484 | PROCEDURE Tst (r: INTEGER); |
||
485 | BEGIN |
||
8859 | leency | 486 | gen3(1, r, 0) (* cmp r, 0 *) |
7983 | leency | 487 | END Tst; |
488 | |||
489 | |||
490 | PROCEDURE LdrSp (r, offset: INTEGER); |
||
491 | BEGIN |
||
492 | gen11(TRUE, r, offset) |
||
493 | END LdrSp; |
||
494 | |||
495 | |||
496 | PROCEDURE MovImm32 (r, imm32: INTEGER); |
||
497 | BEGIN |
||
498 | MovImm8(r, LSR(imm32, 24) MOD 256); |
||
499 | LslImm(r, 8); |
||
500 | AddImm8(r, LSR(imm32, 16) MOD 256); |
||
501 | LslImm(r, 8); |
||
502 | AddImm8(r, LSR(imm32, 8) MOD 256); |
||
503 | LslImm(r, 8); |
||
504 | AddImm8(r, imm32 MOD 256) |
||
505 | END MovImm32; |
||
506 | |||
507 | |||
508 | PROCEDURE low (x: INTEGER): INTEGER; |
||
509 | RETURN x MOD 65536 |
||
510 | END low; |
||
511 | |||
512 | |||
513 | PROCEDURE high (x: INTEGER): INTEGER; |
||
514 | RETURN (x DIV 65536) MOD 65536 |
||
515 | END high; |
||
516 | |||
517 | |||
518 | PROCEDURE movwt (r, imm16, t: INTEGER); |
||
519 | VAR |
||
520 | imm1, imm3, imm4, imm8: INTEGER; |
||
521 | |||
522 | BEGIN |
||
523 | ASSERT(range(r, 3)); |
||
524 | ASSERT(range(imm16, 16)); |
||
525 | ASSERT(range(t, 1)); |
||
526 | split16(imm16, imm4, imm1, imm3, imm8); |
||
527 | Code(0F240H + imm1 * 1024 + t * 128 + imm4); |
||
528 | Code(imm3 * 4096 + r * 256 + imm8); |
||
529 | END movwt; |
||
530 | |||
531 | |||
532 | PROCEDURE inv0 (cond: INTEGER): INTEGER; |
||
533 | RETURN ORD(BITS(cond) / {0}) |
||
534 | END inv0; |
||
535 | |||
536 | |||
537 | PROCEDURE fixup (CodeAdr, DataAdr, BssAdr: INTEGER); |
||
538 | VAR |
||
539 | code: ANYCODE; |
||
540 | count: INTEGER; |
||
541 | shorted: BOOLEAN; |
||
542 | jump: JUMP; |
||
543 | |||
544 | reloc, i, diff, len: INTEGER; |
||
545 | |||
546 | RelocCode: RELOCCODE; |
||
547 | |||
548 | |||
549 | PROCEDURE genjcc (cond, offset: INTEGER): INTEGER; |
||
550 | BEGIN |
||
551 | ASSERT(range(cond, 4)); |
||
552 | ASSERT(srange(offset, 8)) |
||
553 | RETURN 0D000H + cond * 256 + offset MOD 256 |
||
554 | END genjcc; |
||
555 | |||
556 | |||
557 | PROCEDURE genjmp (offset: INTEGER): INTEGER; |
||
558 | BEGIN |
||
559 | ASSERT(srange(offset, 11)) |
||
560 | RETURN 0E000H + offset MOD 2048 |
||
561 | END genjmp; |
||
562 | |||
563 | |||
564 | PROCEDURE movwt (r, imm16, t: INTEGER; VAR code: RELOCCODE); |
||
565 | VAR |
||
566 | imm1, imm3, imm4, imm8: INTEGER; |
||
567 | |||
568 | BEGIN |
||
569 | split16(imm16, imm4, imm1, imm3, imm8); |
||
570 | code[t * 2] := 0F240H + imm1 * 1024 + t * 128 + imm4; |
||
571 | code[t * 2 + 1] := imm3 * 4096 + r * 256 + imm8 |
||
572 | END movwt; |
||
573 | |||
574 | |||
575 | PROCEDURE genmovimm32 (r, value: INTEGER; VAR code: RELOCCODE); |
||
576 | BEGIN |
||
8859 | leency | 577 | IF _THUMB2 IN Target.InstrSet THEN |
7983 | leency | 578 | movwt(r, low(value), 0, code); |
579 | movwt(r, high(value), 1, code) |
||
580 | ELSE |
||
8859 | leency | 581 | code[0] := 2000H + r * 256 + UTILS.Byte(value, 3); (* movs r, imm8 *) |
582 | code[1] := 0200H + r * 9; (* lsls r, 8 *) |
||
583 | code[2] := 3000H + r * 256 + UTILS.Byte(value, 2); (* adds r, imm8 *) |
||
584 | code[3] := code[1]; (* lsls r, 8 *) |
||
585 | code[4] := 3000H + r * 256 + UTILS.Byte(value, 1); (* adds r, imm8 *) |
||
586 | code[5] := code[1]; (* lsls r, 8 *) |
||
587 | code[6] := 3000H + r * 256 + UTILS.Byte(value, 0) (* adds r, imm8 *) |
||
7983 | leency | 588 | END |
589 | END genmovimm32; |
||
590 | |||
591 | |||
592 | PROCEDURE PutCode (code: INTEGER); |
||
593 | BEGIN |
||
594 | BIN.PutCode16LE(program, code) |
||
595 | END PutCode; |
||
596 | |||
597 | |||
8859 | leency | 598 | PROCEDURE genlongjmp (offset: INTEGER); |
599 | BEGIN |
||
600 | ASSERT(srange(offset, 22)); |
||
601 | PutCode(0F000H + ASR(offset, 11) MOD 2048); |
||
602 | PutCode(0F800H + offset MOD 2048) |
||
603 | END genlongjmp; |
||
604 | |||
605 | |||
7983 | leency | 606 | PROCEDURE genbc (code: JUMP); |
607 | BEGIN |
||
608 | CASE code.len OF |
||
609 | |1: PutCode(genjcc(code.cond, code.diff)) |
||
610 | |2: PutCode(genjcc(inv0(code.cond), 0)); |
||
611 | PutCode(genjmp(code.diff)) |
||
612 | |3: PutCode(genjcc(inv0(code.cond), 1)); |
||
8859 | leency | 613 | genlongjmp(code.diff) |
7983 | leency | 614 | END |
615 | END genbc; |
||
616 | |||
617 | |||
618 | PROCEDURE SetIV (idx, label, CodeAdr: INTEGER); |
||
619 | VAR |
||
8097 | maxcodehac | 620 | l, h: LISTS.ITEM; |
7983 | leency | 621 | |
622 | BEGIN |
||
8097 | maxcodehac | 623 | l := CodeList.first; |
624 | h := l.next; |
||
7983 | leency | 625 | WHILE idx > 0 DO |
8097 | maxcodehac | 626 | l := h.next; |
627 | h := l.next; |
||
7983 | leency | 628 | DEC(idx) |
629 | END; |
||
630 | label := BIN.GetLabel(program, label) * 2 + CodeAdr + 1; |
||
631 | l(CODE).code := low(label); |
||
632 | h(CODE).code := high(label) |
||
633 | END SetIV; |
||
634 | |||
635 | |||
636 | BEGIN |
||
637 | |||
638 | REPEAT |
||
639 | |||
640 | shorted := FALSE; |
||
641 | count := 0; |
||
642 | |||
643 | code := CodeList.first(ANYCODE); |
||
644 | WHILE code # NIL DO |
||
645 | code.offset := count; |
||
646 | |||
647 | CASE code OF |
||
648 | |CODE: INC(count) |
||
649 | |LABEL: BIN.SetLabel(program, code.label, count) |
||
650 | |JUMP: INC(count, code.len); code.offset := count + ORD(code.short) |
||
8859 | leency | 651 | |RELOC: INC(count, 7 - ORD(_THUMB2 IN Target.InstrSet) * 3 + code.rel MOD 2) |
7983 | leency | 652 | END; |
653 | |||
654 | code := code.next(ANYCODE) |
||
655 | END; |
||
656 | |||
657 | code := CodeList.first(ANYCODE); |
||
658 | WHILE code # NIL DO |
||
659 | |||
660 | IF code IS JUMP THEN |
||
661 | jump := code(JUMP); |
||
662 | jump.diff := BIN.GetLabel(program, jump.label) - jump.offset; |
||
663 | len := jump.len; |
||
664 | diff := jump.diff; |
||
665 | CASE jump OF |
||
666 | |JMP: |
||
667 | IF (len = 2) & srange(diff, 11) THEN |
||
668 | len := 1 |
||
669 | END |
||
670 | |||
671 | |JCC: |
||
672 | CASE len OF |
||
673 | |1: |
||
674 | |2: IF srange(diff, 8) THEN DEC(len) END |
||
675 | |3: IF srange(diff, 11) THEN DEC(len) END |
||
676 | END |
||
677 | |||
678 | |CBXZ: |
||
679 | CASE len OF |
||
680 | |1: |
||
681 | |2: IF range(diff, 6) THEN DEC(len) END |
||
682 | |3: IF srange(diff, 8) THEN DEC(len) END |
||
683 | |4: IF srange(diff, 11) THEN DEC(len) END |
||
684 | END |
||
685 | |||
686 | |CALL: |
||
687 | |||
688 | END; |
||
689 | IF len # jump.len THEN |
||
690 | jump.len := len; |
||
691 | jump.short := TRUE; |
||
692 | shorted := TRUE |
||
693 | END |
||
694 | END; |
||
695 | |||
696 | code := code.next(ANYCODE) |
||
697 | END |
||
698 | |||
699 | UNTIL ~shorted; |
||
700 | |||
701 | FOR i := 1 TO Target.IVTLen - 1 DO |
||
702 | SetIV(i, IVT[i], CodeAdr) |
||
703 | END; |
||
704 | |||
705 | code := CodeList.first(ANYCODE); |
||
706 | WHILE code # NIL DO |
||
707 | |||
708 | CASE code OF |
||
709 | |||
710 | |CODE: BIN.PutCode16LE(program, code.code) |
||
711 | |||
712 | |LABEL: |
||
713 | |||
714 | |JMP: |
||
715 | IF code.len = 1 THEN |
||
716 | PutCode(genjmp(code.diff)) |
||
717 | ELSE |
||
8859 | leency | 718 | genlongjmp(code.diff) |
7983 | leency | 719 | END |
720 | |||
8097 | maxcodehac | 721 | |JCC: genbc(code) |
7983 | leency | 722 | |
723 | |CBXZ: |
||
724 | IF code.len > 1 THEN |
||
8859 | leency | 725 | PutCode(2800H + code.reg * 256); (* cmp code.reg, 0 *) |
7983 | leency | 726 | DEC(code.len); |
727 | genbc(code) |
||
728 | ELSE |
||
729 | (* cb(n)z code.reg, L *) |
||
8859 | leency | 730 | PutCode(0B100H + 800H * ORD(code.cond = jne) + 200H * (code.diff DIV 32) + (code.diff MOD 32) * 8 + code.reg) |
7983 | leency | 731 | END |
732 | |||
8859 | leency | 733 | |CALL: genlongjmp(code.diff) |
7983 | leency | 734 | |
735 | |RELOC: |
||
736 | CASE code.rel OF |
||
737 | |BIN.RCODE, BIN.PICCODE: reloc := BIN.GetLabel(program, code.value) * 2 + CodeAdr |
||
738 | |BIN.RDATA, BIN.PICDATA: reloc := code.value + DataAdr |
||
739 | |BIN.RBSS, BIN.PICBSS: reloc := code.value + BssAdr |
||
740 | END; |
||
741 | IF code.rel IN {BIN.PICCODE, BIN.PICDATA, BIN.PICBSS} THEN |
||
8859 | leency | 742 | DEC(reloc, CodeAdr + 2 * (code.offset - 3 * ORD(_THUMB2 IN Target.InstrSet) + 9)) |
7983 | leency | 743 | END; |
744 | genmovimm32(code.reg, reloc, RelocCode); |
||
8859 | leency | 745 | FOR i := 0 TO 6 - 3 * ORD(_THUMB2 IN Target.InstrSet) DO |
7983 | leency | 746 | PutCode(RelocCode[i]) |
747 | END; |
||
748 | IF code.rel IN {BIN.PICCODE, BIN.PICDATA, BIN.PICBSS} THEN |
||
8859 | leency | 749 | PutCode(4478H + code.reg) (* add code.reg, pc *) |
7983 | leency | 750 | END |
751 | END; |
||
752 | |||
753 | code := code.next(ANYCODE) |
||
754 | END |
||
755 | |||
756 | END fixup; |
||
757 | |||
758 | |||
759 | PROCEDURE push (r: INTEGER); |
||
760 | BEGIN |
||
761 | gen14(FALSE, FALSE, {r}) |
||
762 | END push; |
||
763 | |||
764 | |||
765 | PROCEDURE pop (r: INTEGER); |
||
766 | BEGIN |
||
767 | gen14(TRUE, FALSE, {r}) |
||
768 | END pop; |
||
769 | |||
770 | |||
771 | PROCEDURE mov (r1, r2: INTEGER); |
||
772 | BEGIN |
||
773 | IF (r1 < 8) & (r2 < 8) THEN |
||
774 | gen1(0, 0, r2, r1) |
||
775 | ELSE |
||
776 | gen5(2, r1 >= 8, r2 >= 8, r2 MOD 8, r1 MOD 8) |
||
777 | END |
||
778 | END mov; |
||
779 | |||
780 | |||
781 | PROCEDURE xchg (r1, r2: INTEGER); |
||
782 | BEGIN |
||
8097 | maxcodehac | 783 | push(r1); |
784 | mov(r1, r2); |
||
785 | pop(r2) |
||
7983 | leency | 786 | END xchg; |
787 | |||
788 | |||
789 | PROCEDURE drop; |
||
790 | BEGIN |
||
791 | REG.Drop(R) |
||
792 | END drop; |
||
793 | |||
794 | |||
795 | PROCEDURE GetAnyReg (): INTEGER; |
||
796 | RETURN REG.GetAnyReg(R) |
||
797 | END GetAnyReg; |
||
798 | |||
799 | |||
800 | PROCEDURE UnOp (VAR r: INTEGER); |
||
801 | BEGIN |
||
802 | REG.UnOp(R, r) |
||
803 | END UnOp; |
||
804 | |||
805 | |||
806 | PROCEDURE BinOp (VAR r1, r2: INTEGER); |
||
807 | BEGIN |
||
808 | REG.BinOp(R, r1, r2) |
||
809 | END BinOp; |
||
810 | |||
811 | |||
812 | PROCEDURE PushAll (NumberOfParameters: INTEGER); |
||
813 | BEGIN |
||
814 | REG.PushAll(R); |
||
815 | DEC(R.pushed, NumberOfParameters) |
||
816 | END PushAll; |
||
817 | |||
818 | |||
819 | PROCEDURE cond (op: INTEGER): INTEGER; |
||
820 | VAR |
||
821 | res: INTEGER; |
||
822 | |||
823 | BEGIN |
||
824 | CASE op OF |
||
825 | |IL.opGT, IL.opGTC: res := jg |
||
826 | |IL.opGE, IL.opGEC: res := jge |
||
827 | |IL.opLT, IL.opLTC: res := jl |
||
828 | |IL.opLE, IL.opLEC: res := jle |
||
829 | |IL.opEQ, IL.opEQC: res := je |
||
830 | |IL.opNE, IL.opNEC: res := jne |
||
831 | END |
||
832 | |||
833 | RETURN res |
||
834 | END cond; |
||
835 | |||
836 | |||
837 | PROCEDURE GetRegA; |
||
838 | BEGIN |
||
839 | ASSERT(REG.GetReg(R, ACC)) |
||
840 | END GetRegA; |
||
841 | |||
842 | |||
843 | PROCEDURE MovConst (r, c: INTEGER); |
||
844 | BEGIN |
||
845 | IF (0 <= c) & (c <= 255) THEN |
||
846 | MovImm8(r, c) |
||
847 | ELSIF (-255 <= c) & (c < 0) THEN |
||
848 | MovImm8(r, -c); |
||
849 | Neg(r) |
||
850 | ELSIF UTILS.Log2(c) >= 0 THEN |
||
851 | MovImm8(r, 1); |
||
852 | LslImm(r, UTILS.Log2(c)) |
||
853 | ELSIF c = UTILS.min32 THEN |
||
854 | MovImm8(r, 1); |
||
855 | LslImm(r, 31) |
||
856 | ELSE |
||
8859 | leency | 857 | IF _THUMB2 IN Target.InstrSet THEN |
7983 | leency | 858 | movwt(r, low(c), 0); |
859 | IF (c < 0) OR (c > 65535) THEN |
||
860 | movwt(r, high(c), 1) |
||
861 | END |
||
862 | ELSE |
||
863 | MovImm32(r, c) |
||
864 | END |
||
865 | END |
||
866 | END MovConst; |
||
867 | |||
868 | |||
869 | PROCEDURE CmpConst (r, c: INTEGER); |
||
870 | VAR |
||
871 | r2: INTEGER; |
||
872 | |||
873 | BEGIN |
||
874 | IF (0 <= c) & (c <= 255) THEN |
||
875 | CmpImm8(r, c) |
||
876 | ELSE |
||
877 | r2 := GetAnyReg(); |
||
878 | ASSERT(r2 # r); |
||
879 | MovConst(r2, c); |
||
880 | Cmp(r, r2); |
||
881 | drop |
||
882 | END |
||
883 | END CmpConst; |
||
884 | |||
885 | |||
886 | PROCEDURE LocalOffset (offset: INTEGER): INTEGER; |
||
887 | RETURN offset + StkCount - ORD(offset > 0) |
||
888 | END LocalOffset; |
||
889 | |||
890 | |||
891 | PROCEDURE SetCC (cc, r: INTEGER); |
||
892 | VAR |
||
893 | L1, L2: INTEGER; |
||
894 | |||
895 | BEGIN |
||
8859 | leency | 896 | IF _IT IN Target.InstrSet THEN |
7983 | leency | 897 | Code(0BF00H + cc * 16 + ((cc + 1) MOD 2) * 8 + 4); (* ite cc *) |
898 | MovConst(r, 1); |
||
899 | MovConst(r, 0) |
||
900 | ELSE |
||
901 | L1 := NewLabel(); |
||
902 | L2 := NewLabel(); |
||
903 | jcc(cc, L1); |
||
904 | MovConst(r, 0); |
||
905 | jmp(L2); |
||
906 | Label(L1); |
||
907 | MovConst(r, 1); |
||
908 | Label(L2) |
||
909 | END |
||
910 | END SetCC; |
||
911 | |||
912 | |||
913 | PROCEDURE PushConst (n: INTEGER); |
||
914 | VAR |
||
915 | r: INTEGER; |
||
916 | |||
917 | BEGIN |
||
918 | r := GetAnyReg(); |
||
919 | MovConst(r, n); |
||
920 | push(r); |
||
921 | drop |
||
922 | END PushConst; |
||
923 | |||
924 | |||
925 | PROCEDURE AddConst (r, n: INTEGER); |
||
926 | VAR |
||
927 | r2: INTEGER; |
||
928 | |||
929 | BEGIN |
||
930 | IF n # 0 THEN |
||
931 | IF (-255 <= n) & (n <= 255) THEN |
||
932 | IF n > 0 THEN |
||
933 | AddImm8(r, n) |
||
934 | ELSE |
||
935 | SubImm8(r, -n) |
||
936 | END |
||
8859 | leency | 937 | ELSIF (_THUMB2 IN Target.InstrSet) & (-4095 <= n) & (n <= 4095) THEN |
938 | AddSubImm12(r, ABS(n), n < 0) |
||
7983 | leency | 939 | ELSE |
940 | r2 := GetAnyReg(); |
||
941 | ASSERT(r2 # r); |
||
942 | IF n > 0 THEN |
||
943 | MovConst(r2, n); |
||
944 | AddReg(r, r, r2) |
||
945 | ELSE |
||
946 | MovConst(r2, -n); |
||
947 | SubReg(r, r, r2) |
||
948 | END; |
||
949 | drop |
||
950 | END |
||
951 | END |
||
952 | END AddConst; |
||
953 | |||
954 | |||
955 | PROCEDURE AddHH (r1, r2: INTEGER); |
||
956 | BEGIN |
||
957 | ASSERT((r1 >= 8) OR (r2 >= 8)); |
||
958 | gen5(0, r1 >= 8, r2 >= 8, r2 MOD 8, r1 MOD 8) |
||
959 | END AddHH; |
||
960 | |||
961 | |||
962 | PROCEDURE AddSP (n: INTEGER); |
||
963 | BEGIN |
||
964 | IF n > 0 THEN |
||
965 | IF n < 127 THEN |
||
8859 | leency | 966 | Code(0B000H + n) (* add sp, n*4 *) |
7983 | leency | 967 | ELSE |
968 | ASSERT(R2 IN R.regs); |
||
969 | MovConst(R2, n * 4); |
||
970 | AddHH(SP, R2) |
||
971 | END; |
||
972 | DEC(StkCount, n) |
||
973 | END |
||
974 | END AddSP; |
||
975 | |||
976 | |||
8859 | leency | 977 | PROCEDURE cbxz2 (c, r, label: INTEGER); |
7983 | leency | 978 | BEGIN |
8859 | leency | 979 | IF _CBXZ IN Target.InstrSet THEN |
980 | cbxz(c, r, label) |
||
7983 | leency | 981 | ELSE |
982 | Tst(r); |
||
8859 | leency | 983 | jcc(c, label) |
7983 | leency | 984 | END |
8859 | leency | 985 | END cbxz2; |
986 | |||
987 | |||
988 | PROCEDURE cbz (r, label: INTEGER); |
||
989 | BEGIN |
||
990 | cbxz2(je, r, label) |
||
7983 | leency | 991 | END cbz; |
992 | |||
993 | |||
994 | PROCEDURE cbnz (r, label: INTEGER); |
||
995 | BEGIN |
||
8859 | leency | 996 | cbxz2(jne, r, label) |
7983 | leency | 997 | END cbnz; |
998 | |||
999 | |||
1000 | PROCEDURE Shift (op, r1, r2: INTEGER); |
||
1001 | VAR |
||
1002 | L: INTEGER; |
||
1003 | |||
1004 | BEGIN |
||
1005 | LslImm(r2, 27); |
||
1006 | LsrImm(r2, 27); |
||
1007 | L := NewLabel(); |
||
1008 | cbz(r2, L); |
||
1009 | CASE op OF |
||
1010 | |IL.opLSL, IL.opLSL1: gen4(2, r2, r1) |
||
1011 | |IL.opLSR, IL.opLSR1: gen4(3, r2, r1) |
||
1012 | |IL.opASR, IL.opASR1: gen4(4, r2, r1) |
||
1013 | |IL.opROR, IL.opROR1: gen4(7, r2, r1) |
||
1014 | END; |
||
1015 | Label(L) |
||
1016 | END Shift; |
||
1017 | |||
1018 | |||
1019 | PROCEDURE LocAdr (offs: INTEGER); |
||
1020 | VAR |
||
1021 | r1, n: INTEGER; |
||
1022 | |||
1023 | BEGIN |
||
1024 | r1 := GetAnyReg(); |
||
1025 | n := LocalOffset(offs); |
||
1026 | IF n <= 255 THEN |
||
1027 | gen12(TRUE, r1, n) |
||
1028 | ELSE |
||
1029 | MovConst(r1, n * 4); |
||
1030 | AddHH(r1, SP) |
||
1031 | END |
||
1032 | END LocAdr; |
||
1033 | |||
1034 | |||
1035 | PROCEDURE CallRTL (proc, par: INTEGER); |
||
1036 | BEGIN |
||
1037 | call(IL.codes.rtl[proc]); |
||
1038 | AddSP(par) |
||
1039 | END CallRTL; |
||
1040 | |||
1041 | |||
1042 | PROCEDURE divmod; |
||
1043 | BEGIN |
||
1044 | call(sdivProc); |
||
1045 | AddSP(2) |
||
1046 | END divmod; |
||
1047 | |||
1048 | |||
8859 | leency | 1049 | PROCEDURE cpsid_i; |
1050 | BEGIN |
||
1051 | Code(0B672H) (* cpsid i *) |
||
1052 | END cpsid_i; |
||
1053 | |||
1054 | |||
1055 | PROCEDURE cpsie_i; |
||
1056 | BEGIN |
||
1057 | Code(0B662H) (* cpsie i *) |
||
1058 | END cpsie_i; |
||
1059 | |||
1060 | |||
7983 | leency | 1061 | PROCEDURE translate (pic, stroffs: INTEGER); |
1062 | VAR |
||
1063 | cmd, next: COMMAND; |
||
1064 | opcode, param1, param2: INTEGER; |
||
1065 | |||
1066 | r1, r2, r3: INTEGER; |
||
1067 | |||
1068 | a, n, cc, L, L2: INTEGER; |
||
1069 | |||
1070 | BEGIN |
||
1071 | cmd := IL.codes.commands.first(COMMAND); |
||
1072 | |||
1073 | WHILE cmd # NIL DO |
||
1074 | |||
1075 | param1 := cmd.param1; |
||
1076 | param2 := cmd.param2; |
||
1077 | opcode := cmd.opcode; |
||
1078 | |||
1079 | CASE opcode OF |
||
1080 | |||
1081 | |IL.opJMP: |
||
1082 | jmp(param1) |
||
1083 | |||
1084 | |IL.opLABEL: |
||
1085 | Label(param1) |
||
1086 | |||
1087 | |IL.opHANDLER: |
||
1088 | IF param2 = 0 THEN |
||
1089 | int0 := param1 |
||
1090 | ELSIF param2 = 1 THEN |
||
1091 | trap := param1 |
||
1092 | ELSE |
||
1093 | IVT[param2] := param1 |
||
1094 | END |
||
1095 | |||
1096 | |IL.opCALL: |
||
1097 | call(param1) |
||
1098 | |||
1099 | |IL.opCALLP: |
||
1100 | UnOp(r1); |
||
8097 | maxcodehac | 1101 | AddImm8(r1, 1); (* Thumb mode *) |
7983 | leency | 1102 | gen5(3, TRUE, FALSE, r1, 0); (* blx r1 *) |
1103 | drop; |
||
1104 | ASSERT(R.top = -1) |
||
1105 | |||
1106 | |IL.opENTER: |
||
1107 | ASSERT(R.top = -1); |
||
1108 | |||
1109 | Label(param1); |
||
1110 | |||
8859 | leency | 1111 | gen14(FALSE, TRUE, {}); (* push {lr} *) |
7983 | leency | 1112 | |
1113 | n := param2; |
||
1114 | IF n >= 5 THEN |
||
1115 | MovConst(ACC, 0); |
||
1116 | MovConst(R2, n); |
||
1117 | L := NewLabel(); |
||
1118 | Label(L); |
||
1119 | push(ACC); |
||
1120 | SubImm8(R2, 1); |
||
1121 | Tst(R2); |
||
1122 | jcc(jne, L) |
||
1123 | ELSIF n > 0 THEN |
||
1124 | MovConst(ACC, 0); |
||
1125 | WHILE n > 0 DO |
||
1126 | push(ACC); |
||
1127 | DEC(n) |
||
1128 | END |
||
1129 | END; |
||
1130 | StkCount := param2 |
||
1131 | |||
1132 | |IL.opLEAVE, IL.opLEAVER, IL.opLEAVEF: |
||
1133 | IF opcode # IL.opLEAVE THEN |
||
1134 | UnOp(r1); |
||
1135 | IF r1 # ACC THEN |
||
8859 | leency | 1136 | mov(ACC, r1) |
7983 | leency | 1137 | END; |
1138 | drop |
||
1139 | END; |
||
1140 | |||
1141 | ASSERT(R.top = -1); |
||
1142 | ASSERT(StkCount = param1); |
||
1143 | |||
1144 | AddSP(param1); |
||
8859 | leency | 1145 | gen14(TRUE, TRUE, {}) (* pop {pc} *) |
7983 | leency | 1146 | |
1147 | |IL.opLEAVEC: |
||
8859 | leency | 1148 | gen5(3, FALSE, TRUE, 6, 0) (* bx lr *) |
7983 | leency | 1149 | |
1150 | |IL.opPRECALL: |
||
1151 | PushAll(0) |
||
1152 | |||
1153 | |IL.opPARAM: |
||
1154 | n := param2; |
||
1155 | IF n = 1 THEN |
||
1156 | UnOp(r1); |
||
1157 | push(r1); |
||
1158 | drop |
||
1159 | ELSE |
||
1160 | ASSERT(R.top + 1 <= n); |
||
1161 | PushAll(n) |
||
1162 | END |
||
1163 | |||
1164 | |IL.opCLEANUP: |
||
1165 | AddSP(param2) |
||
1166 | |||
1167 | |IL.opRES, IL.opRESF: |
||
1168 | ASSERT(R.top = -1); |
||
1169 | GetRegA |
||
1170 | |||
1171 | |IL.opPUSHC: |
||
1172 | PushConst(param2) |
||
1173 | |||
1174 | |IL.opONERR: |
||
8859 | leency | 1175 | cpsid_i; |
7983 | leency | 1176 | MovConst(R0, param2); |
1177 | push(R0); |
||
1178 | DEC(StkCount); |
||
1179 | jmp(param1) |
||
1180 | |||
1181 | |IL.opERR: |
||
1182 | call(genTrap) |
||
1183 | |||
8097 | maxcodehac | 1184 | |IL.opNOP, IL.opAND, IL.opOR: |
7983 | leency | 1185 | |
1186 | |IL.opSADR: |
||
1187 | reloc(GetAnyReg(), BIN.RDATA + pic, stroffs + param2) |
||
1188 | |||
1189 | |IL.opGADR: |
||
1190 | reloc(GetAnyReg(), BIN.RBSS + pic, param2) |
||
1191 | |||
1192 | |IL.opLADR: |
||
1193 | LocAdr(param2) |
||
1194 | |||
1195 | |IL.opGLOAD32: |
||
1196 | r1 := GetAnyReg(); |
||
1197 | reloc(r1, BIN.RBSS + pic, param2); |
||
1198 | Ldr32(r1, r1) |
||
1199 | |||
1200 | |IL.opGLOAD16: |
||
1201 | r1 := GetAnyReg(); |
||
1202 | reloc(r1, BIN.RBSS + pic, param2); |
||
1203 | Ldr16(r1, r1) |
||
1204 | |||
1205 | |IL.opGLOAD8: |
||
1206 | r1 := GetAnyReg(); |
||
1207 | reloc(r1, BIN.RBSS + pic, param2); |
||
1208 | Ldr8(r1, r1) |
||
1209 | |||
8859 | leency | 1210 | |IL.opLADR_SAVE: |
1211 | UnOp(r1); |
||
1212 | n := LocalOffset(param2); |
||
1213 | IF n <= 255 THEN |
||
1214 | gen11(FALSE, r1, n) (* str r1, [sp, n*4] *) |
||
1215 | ELSE |
||
1216 | LocAdr(param2); |
||
1217 | BinOp(r1, r2); |
||
1218 | Str32(r1, r2); |
||
1219 | drop |
||
1220 | END; |
||
1221 | drop |
||
1222 | |||
1223 | |IL.opLADR_INCC: |
||
1224 | n := LocalOffset(param1); |
||
1225 | IF n <= 255 THEN |
||
1226 | r1 := GetAnyReg(); |
||
1227 | LdrSp(r1, n); |
||
1228 | AddConst(r1, param2); |
||
1229 | gen11(FALSE, r1, n) (* str r1, [sp, n*4] *) |
||
1230 | ELSE |
||
1231 | LocAdr(param1); |
||
1232 | r1 := GetAnyReg(); |
||
1233 | BinOp(r2, r1); |
||
1234 | Ldr32(r1, r2); |
||
1235 | AddConst(r1, param2); |
||
1236 | BinOp(r2, r1); |
||
1237 | Str32(r1, r2); |
||
1238 | drop |
||
1239 | END; |
||
1240 | drop |
||
1241 | |||
7983 | leency | 1242 | |IL.opLLOAD32, IL.opVADR, IL.opVLOAD32: |
1243 | r1 := GetAnyReg(); |
||
1244 | n := LocalOffset(param2); |
||
1245 | IF n <= 255 THEN |
||
1246 | LdrSp(r1, n) |
||
1247 | ELSE |
||
1248 | drop; |
||
1249 | LocAdr(param2); |
||
1250 | UnOp(r1); |
||
1251 | Ldr32(r1, r1) |
||
1252 | END; |
||
1253 | IF opcode = IL.opVLOAD32 THEN |
||
1254 | Ldr32(r1, r1) |
||
1255 | END |
||
1256 | |||
1257 | |IL.opLLOAD16: |
||
1258 | LocAdr(param2); |
||
1259 | UnOp(r1); |
||
1260 | Ldr16(r1, r1) |
||
1261 | |||
1262 | |IL.opLLOAD8: |
||
1263 | LocAdr(param2); |
||
1264 | UnOp(r1); |
||
1265 | Ldr8(r1, r1) |
||
1266 | |||
1267 | |IL.opLOAD32, IL.opLOADF: |
||
1268 | UnOp(r1); |
||
1269 | Ldr32(r1, r1) |
||
1270 | |||
1271 | |IL.opLOAD16: |
||
1272 | UnOp(r1); |
||
1273 | Ldr16(r1, r1) |
||
1274 | |||
1275 | |IL.opLOAD8: |
||
1276 | UnOp(r1); |
||
1277 | Ldr8(r1, r1) |
||
1278 | |||
1279 | |IL.opVLOAD16: |
||
1280 | LocAdr(param2); |
||
1281 | UnOp(r1); |
||
1282 | Ldr32(r1, r1); |
||
1283 | Ldr16(r1, r1) |
||
1284 | |||
1285 | |IL.opVLOAD8: |
||
1286 | LocAdr(param2); |
||
1287 | UnOp(r1); |
||
1288 | Ldr32(r1, r1); |
||
1289 | Ldr8(r1, r1) |
||
1290 | |||
1291 | |IL.opSBOOL: |
||
1292 | BinOp(r2, r1); |
||
1293 | Tst(r2); |
||
1294 | SetCC(jne, r2); |
||
1295 | Str8(r2, r1); |
||
1296 | drop; |
||
1297 | drop |
||
1298 | |||
1299 | |IL.opSBOOLC: |
||
1300 | UnOp(r1); |
||
1301 | r2 := GetAnyReg(); |
||
1302 | MovConst(r2, ORD(param2 # 0)); |
||
1303 | Str8(r2, r1); |
||
1304 | drop; |
||
1305 | drop |
||
1306 | |||
1307 | |IL.opSAVEC: |
||
1308 | UnOp(r1); |
||
1309 | r2 := GetAnyReg(); |
||
1310 | MovConst(r2, param2); |
||
1311 | Str32(r2, r1); |
||
1312 | drop; |
||
1313 | drop |
||
1314 | |||
1315 | |IL.opSAVE16C: |
||
1316 | UnOp(r1); |
||
1317 | r2 := GetAnyReg(); |
||
1318 | MovConst(r2, low(param2)); |
||
1319 | Str16(r2, r1); |
||
1320 | drop; |
||
1321 | drop |
||
1322 | |||
1323 | |IL.opSAVE8C: |
||
1324 | UnOp(r1); |
||
1325 | r2 := GetAnyReg(); |
||
1326 | MovConst(r2, param2 MOD 256); |
||
1327 | Str8(r2, r1); |
||
1328 | drop; |
||
1329 | drop |
||
1330 | |||
1331 | |IL.opSAVE, IL.opSAVE32, IL.opSAVEF: |
||
1332 | BinOp(r2, r1); |
||
1333 | Str32(r2, r1); |
||
1334 | drop; |
||
1335 | drop |
||
1336 | |||
1337 | |IL.opSAVEFI: |
||
1338 | BinOp(r2, r1); |
||
1339 | Str32(r1, r2); |
||
1340 | drop; |
||
1341 | drop |
||
1342 | |||
1343 | |IL.opSAVE16: |
||
1344 | BinOp(r2, r1); |
||
1345 | Str16(r2, r1); |
||
1346 | drop; |
||
1347 | drop |
||
1348 | |||
1349 | |IL.opSAVE8: |
||
1350 | BinOp(r2, r1); |
||
1351 | Str8(r2, r1); |
||
1352 | drop; |
||
1353 | drop |
||
1354 | |||
1355 | |IL.opSAVEP: |
||
1356 | UnOp(r1); |
||
1357 | r2 := GetAnyReg(); |
||
1358 | reloc(r2, BIN.RCODE + pic, param2); |
||
1359 | Str32(r2, r1); |
||
1360 | drop; |
||
1361 | drop |
||
1362 | |||
1363 | |IL.opPUSHP: |
||
1364 | reloc(GetAnyReg(), BIN.RCODE + pic, param2) |
||
1365 | |||
1366 | |IL.opEQB, IL.opNEB: |
||
1367 | BinOp(r1, r2); |
||
1368 | drop; |
||
1369 | |||
1370 | L := NewLabel(); |
||
1371 | cbz(r1, L); |
||
1372 | MovConst(r1, 1); |
||
1373 | Label(L); |
||
1374 | |||
1375 | L := NewLabel(); |
||
1376 | cbz(r2, L); |
||
1377 | MovConst(r2, 1); |
||
1378 | Label(L); |
||
1379 | |||
1380 | Cmp(r1, r2); |
||
1381 | IF opcode = IL.opEQB THEN |
||
1382 | SetCC(je, r1) |
||
1383 | ELSE |
||
1384 | SetCC(jne, r1) |
||
1385 | END |
||
1386 | |||
1387 | |IL.opDROP: |
||
1388 | UnOp(r1); |
||
1389 | drop |
||
1390 | |||
8097 | maxcodehac | 1391 | |IL.opJNZ1: |
7983 | leency | 1392 | UnOp(r1); |
1393 | cbnz(r1, param1) |
||
1394 | |||
1395 | |IL.opJG: |
||
1396 | UnOp(r1); |
||
1397 | Tst(r1); |
||
1398 | jcc(jg, param1) |
||
1399 | |||
8097 | maxcodehac | 1400 | |IL.opJNZ: |
7983 | leency | 1401 | UnOp(r1); |
1402 | cbnz(r1, param1); |
||
1403 | drop |
||
1404 | |||
8097 | maxcodehac | 1405 | |IL.opJZ: |
7983 | leency | 1406 | UnOp(r1); |
1407 | cbz(r1, param1); |
||
1408 | drop |
||
1409 | |||
1410 | |IL.opSWITCH: |
||
1411 | UnOp(r1); |
||
1412 | IF param2 = 0 THEN |
||
1413 | r2 := ACC |
||
1414 | ELSE |
||
1415 | r2 := R2 |
||
1416 | END; |
||
1417 | IF r1 # r2 THEN |
||
1418 | ASSERT(REG.GetReg(R, r2)); |
||
1419 | ASSERT(REG.Exchange(R, r1, r2)); |
||
1420 | drop |
||
1421 | END; |
||
1422 | drop |
||
1423 | |||
1424 | |IL.opENDSW: |
||
1425 | |||
1426 | |IL.opCASEL: |
||
1427 | GetRegA; |
||
1428 | CmpConst(ACC, param1); |
||
1429 | jcc(jl, param2); |
||
1430 | drop |
||
1431 | |||
1432 | |IL.opCASER: |
||
1433 | GetRegA; |
||
1434 | CmpConst(ACC, param1); |
||
1435 | jcc(jg, param2); |
||
1436 | drop |
||
1437 | |||
1438 | |IL.opCASELR: |
||
1439 | GetRegA; |
||
1440 | CmpConst(ACC, param1); |
||
8859 | leency | 1441 | IF param2 = cmd.param3 THEN |
1442 | jcc(jne, param2) |
||
1443 | ELSE |
||
1444 | jcc(jl, param2); |
||
1445 | jcc(jg, cmd.param3) |
||
1446 | END; |
||
7983 | leency | 1447 | drop |
1448 | |||
1449 | |IL.opCODE: |
||
1450 | Code(param2) |
||
1451 | |||
1452 | |IL.opEQ..IL.opGE, |
||
1453 | IL.opEQC..IL.opGEC: |
||
1454 | IF (IL.opEQ <= opcode) & (opcode <= IL.opGE) THEN |
||
1455 | BinOp(r1, r2); |
||
1456 | Cmp(r1, r2); |
||
1457 | drop |
||
1458 | ELSE |
||
1459 | UnOp(r1); |
||
1460 | CmpConst(r1, param2) |
||
1461 | END; |
||
1462 | |||
1463 | drop; |
||
1464 | cc := cond(opcode); |
||
1465 | next := cmd.next(COMMAND); |
||
1466 | |||
8097 | maxcodehac | 1467 | IF next.opcode = IL.opJNZ THEN |
7983 | leency | 1468 | jcc(cc, next.param1); |
1469 | cmd := next |
||
8097 | maxcodehac | 1470 | ELSIF next.opcode = IL.opJZ THEN |
7983 | leency | 1471 | jcc(inv0(cc), next.param1); |
1472 | cmd := next |
||
1473 | ELSE |
||
1474 | SetCC(cc, GetAnyReg()) |
||
1475 | END |
||
1476 | |||
1477 | |IL.opINCC: |
||
1478 | UnOp(r1); |
||
1479 | r2 := GetAnyReg(); |
||
1480 | Ldr32(r2, r1); |
||
1481 | AddConst(r2, param2); |
||
1482 | Str32(r2, r1); |
||
1483 | drop; |
||
1484 | drop |
||
1485 | |||
1486 | |IL.opINCCB, IL.opDECCB: |
||
1487 | IF opcode = IL.opDECCB THEN |
||
1488 | param2 := -param2 |
||
1489 | END; |
||
1490 | UnOp(r1); |
||
1491 | r2 := GetAnyReg(); |
||
1492 | Ldr8(r2, r1); |
||
1493 | AddConst(r2, param2); |
||
1494 | Str8(r2, r1); |
||
1495 | drop; |
||
1496 | drop |
||
1497 | |||
1498 | |IL.opUMINUS: |
||
1499 | UnOp(r1); |
||
1500 | Neg(r1) |
||
1501 | |||
1502 | |IL.opADD: |
||
1503 | BinOp(r1, r2); |
||
1504 | CASE cmd.next(COMMAND).opcode OF |
||
1505 | |IL.opLOAD32, IL.opLOADF: |
||
1506 | gen7(TRUE, FALSE, r2, r1, r1); (* ldr r1, [r1, r2] *) |
||
1507 | cmd := cmd.next(COMMAND) |
||
1508 | |IL.opLOAD8: |
||
1509 | gen7(TRUE, TRUE, r2, r1, r1); (* ldrb r1, [r1, r2] *) |
||
1510 | cmd := cmd.next(COMMAND) |
||
1511 | |IL.opLOAD16: |
||
1512 | gen8(TRUE, FALSE, r2, r1, r1); (* ldrh r1, [r1, r2] *) |
||
1513 | cmd := cmd.next(COMMAND) |
||
1514 | ELSE |
||
1515 | AddReg(r1, r1, r2) |
||
1516 | END; |
||
1517 | drop |
||
1518 | |||
8097 | maxcodehac | 1519 | |IL.opADDC: |
7983 | leency | 1520 | UnOp(r1); |
1521 | AddConst(r1, param2) |
||
1522 | |||
1523 | |IL.opSUB: |
||
1524 | BinOp(r1, r2); |
||
1525 | SubReg(r1, r1, r2); |
||
1526 | drop |
||
1527 | |||
1528 | |IL.opSUBL, IL.opSUBR: |
||
1529 | UnOp(r1); |
||
1530 | AddConst(r1, -param2); |
||
1531 | IF opcode = IL.opSUBL THEN |
||
1532 | Neg(r1) |
||
1533 | END |
||
1534 | |||
1535 | |IL.opMUL: |
||
1536 | BinOp(r1, r2); |
||
1537 | Mul(r1, r2); |
||
1538 | drop |
||
1539 | |||
1540 | |IL.opMULC: |
||
1541 | UnOp(r1); |
||
1542 | |||
1543 | a := param2; |
||
1544 | IF a > 1 THEN |
||
1545 | n := UTILS.Log2(a) |
||
1546 | ELSIF a < -1 THEN |
||
1547 | n := UTILS.Log2(-a) |
||
1548 | ELSE |
||
1549 | n := -1 |
||
1550 | END; |
||
1551 | |||
1552 | IF a = 1 THEN |
||
1553 | |||
1554 | ELSIF a = -1 THEN |
||
1555 | Neg(r1) |
||
1556 | ELSIF a = 0 THEN |
||
1557 | MovConst(r1, 0) |
||
1558 | ELSE |
||
1559 | IF n > 0 THEN |
||
1560 | IF a < 0 THEN |
||
1561 | Neg(r1) |
||
1562 | END; |
||
1563 | LslImm(r1, n) |
||
1564 | ELSE |
||
1565 | r2 := GetAnyReg(); |
||
1566 | MovConst(r2, a); |
||
1567 | Mul(r1, r2); |
||
1568 | drop |
||
1569 | END |
||
1570 | END |
||
1571 | |||
1572 | |IL.opABS: |
||
1573 | UnOp(r1); |
||
1574 | Tst(r1); |
||
1575 | L := NewLabel(); |
||
1576 | jcc(jge, L); |
||
1577 | Neg(r1); |
||
1578 | Label(L) |
||
1579 | |||
1580 | |IL.opNOT: |
||
1581 | UnOp(r1); |
||
1582 | Tst(r1); |
||
1583 | SetCC(je, r1) |
||
1584 | |||
1585 | |IL.opORD: |
||
1586 | UnOp(r1); |
||
1587 | Tst(r1); |
||
1588 | SetCC(jne, r1) |
||
1589 | |||
1590 | |IL.opCHR: |
||
1591 | UnOp(r1); |
||
8859 | leency | 1592 | Code(0B2C0H + r1 * 9) (* uxtb r1, r1 *) |
7983 | leency | 1593 | |
1594 | |IL.opWCHR: |
||
1595 | UnOp(r1); |
||
8859 | leency | 1596 | Code(0B280H + r1 * 9) (* uxth r1, r1 *) |
7983 | leency | 1597 | |
1598 | |IL.opASR, IL.opROR, IL.opLSL, IL.opLSR: |
||
1599 | BinOp(r1, r2); |
||
1600 | Shift(opcode, r1, r2); |
||
1601 | drop |
||
1602 | |||
1603 | |IL.opASR1, IL.opROR1, IL.opLSL1, IL.opLSR1: |
||
1604 | MovConst(GetAnyReg(), param2); |
||
1605 | BinOp(r2, r1); |
||
1606 | Shift(opcode, r1, r2); |
||
1607 | INCL(R.regs, r2); |
||
1608 | DEC(R.top); |
||
1609 | R.stk[R.top] := r1 |
||
1610 | |||
1611 | |IL.opASR2, IL.opROR2, IL.opLSL2, IL.opLSR2: |
||
1612 | n := param2 MOD 32; |
||
1613 | IF n # 0 THEN |
||
1614 | UnOp(r1); |
||
1615 | CASE opcode OF |
||
1616 | |IL.opASR2: AsrImm(r1, n) |
||
1617 | |IL.opROR2: r2 := GetAnyReg(); MovConst(r2, n); Shift(IL.opROR, r1, r2); drop |
||
1618 | |IL.opLSL2: LslImm(r1, n) |
||
1619 | |IL.opLSR2: LsrImm(r1, n) |
||
1620 | END |
||
1621 | END |
||
1622 | |||
1623 | |IL.opCHKBYTE: |
||
1624 | BinOp(r1, r2); |
||
1625 | CmpConst(r1, 256); |
||
1626 | jcc(jb, param1) |
||
1627 | |||
1628 | |IL.opCHKIDX: |
||
1629 | UnOp(r1); |
||
1630 | CmpConst(r1, param2); |
||
1631 | jcc(jb, param1) |
||
1632 | |||
1633 | |IL.opCHKIDX2: |
||
1634 | BinOp(r1, r2); |
||
1635 | IF param2 # -1 THEN |
||
1636 | Cmp(r2, r1); |
||
1637 | jcc(jb, param1) |
||
1638 | END; |
||
1639 | INCL(R.regs, r1); |
||
1640 | DEC(R.top); |
||
1641 | R.stk[R.top] := r2 |
||
1642 | |||
1643 | |IL.opLEN: |
||
1644 | n := param2; |
||
1645 | UnOp(r1); |
||
1646 | drop; |
||
1647 | EXCL(R.regs, r1); |
||
1648 | |||
1649 | WHILE n > 0 DO |
||
1650 | UnOp(r2); |
||
1651 | drop; |
||
1652 | DEC(n) |
||
1653 | END; |
||
1654 | |||
1655 | INCL(R.regs, r1); |
||
1656 | ASSERT(REG.GetReg(R, r1)) |
||
1657 | |||
1658 | |IL.opINF: |
||
1659 | MovConst(GetAnyReg(), inf) |
||
1660 | |||
1661 | |IL.opPUSHF: |
||
1662 | UnOp(r1); |
||
1663 | push(r1); |
||
1664 | drop |
||
1665 | |||
1666 | |IL.opCONST: |
||
1667 | MovConst(GetAnyReg(), param2) |
||
1668 | |||
1669 | |IL.opEQP, IL.opNEP: |
||
1670 | reloc(GetAnyReg(), BIN.RCODE + pic, param1); |
||
1671 | BinOp(r1, r2); |
||
1672 | Cmp(r1, r2); |
||
1673 | drop; |
||
1674 | IF opcode = IL.opEQP THEN |
||
1675 | SetCC(je, r1) |
||
1676 | ELSE |
||
1677 | SetCC(jne, r1) |
||
1678 | END |
||
1679 | |||
1680 | |IL.opPUSHT: |
||
1681 | UnOp(r1); |
||
1682 | r2 := GetAnyReg(); |
||
1683 | mov(r2, r1); |
||
1684 | SubImm8(r2, 4); |
||
1685 | Ldr32(r2, r2) |
||
1686 | |||
1687 | |IL.opGET, IL.opGETC: |
||
1688 | IF opcode = IL.opGET THEN |
||
1689 | BinOp(r1, r2) |
||
1690 | ELSIF opcode = IL.opGETC THEN |
||
1691 | UnOp(r2); |
||
1692 | r1 := GetAnyReg(); |
||
1693 | MovConst(r1, param1) |
||
1694 | END; |
||
1695 | drop; |
||
1696 | drop; |
||
1697 | |||
1698 | CASE param2 OF |
||
1699 | |1: Ldr8(r1, r1); Str8(r1, r2) |
||
1700 | |2: Ldr16(r1, r1); Str16(r1, r2) |
||
1701 | |4: Ldr32(r1, r1); Str32(r1, r2) |
||
1702 | END |
||
1703 | |||
1704 | |IL.opINC, IL.opDEC: |
||
1705 | BinOp(r2, r1); |
||
1706 | r3 := GetAnyReg(); |
||
1707 | Ldr32(r3, r1); |
||
1708 | IF opcode = IL.opINC THEN |
||
1709 | AddReg(r3, r3, r2) |
||
1710 | ELSE |
||
1711 | SubReg(r3, r3, r2) |
||
1712 | END; |
||
1713 | Str32(r3, r1); |
||
1714 | drop; |
||
1715 | drop; |
||
1716 | drop |
||
1717 | |||
1718 | |IL.opINCB, IL.opDECB: |
||
1719 | BinOp(r2, r1); |
||
1720 | r3 := GetAnyReg(); |
||
1721 | Ldr8(r3, r1); |
||
1722 | IF opcode = IL.opINCB THEN |
||
1723 | AddReg(r3, r3, r2) |
||
1724 | ELSE |
||
1725 | SubReg(r3, r3, r2) |
||
1726 | END; |
||
1727 | Str8(r3, r1); |
||
1728 | drop; |
||
1729 | drop; |
||
1730 | drop |
||
1731 | |||
1732 | |IL.opMIN, IL.opMAX: |
||
1733 | BinOp(r1, r2); |
||
1734 | Cmp(r1, r2); |
||
1735 | L := NewLabel(); |
||
1736 | IF opcode = IL.opMIN THEN |
||
1737 | cc := jle |
||
1738 | ELSE |
||
1739 | cc := jge |
||
1740 | END; |
||
1741 | jcc(cc, L); |
||
1742 | mov(r1, r2); |
||
1743 | Label(L); |
||
1744 | drop |
||
1745 | |||
1746 | |IL.opMINC, IL.opMAXC: |
||
1747 | UnOp(r1); |
||
1748 | CmpConst(r1, param2); |
||
1749 | L := NewLabel(); |
||
1750 | IF opcode = IL.opMINC THEN |
||
1751 | cc := jle |
||
1752 | ELSE |
||
1753 | cc := jge |
||
1754 | END; |
||
1755 | jcc(cc, L); |
||
1756 | MovConst(r1, param2); |
||
1757 | Label(L) |
||
1758 | |||
1759 | |IL.opMULS: |
||
1760 | BinOp(r1, r2); |
||
8859 | leency | 1761 | gen4(0, r2, r1); (* ands r1, r2 *) |
7983 | leency | 1762 | drop |
1763 | |||
1764 | |IL.opMULSC: |
||
1765 | MovConst(GetAnyReg(), param2); |
||
1766 | BinOp(r1, r2); |
||
8859 | leency | 1767 | gen4(0, r2, r1); (* ands r1, r2 *) |
7983 | leency | 1768 | drop |
1769 | |||
1770 | |IL.opDIVS: |
||
1771 | BinOp(r1, r2); |
||
8859 | leency | 1772 | gen4(1, r2, r1); (* eors r1, r2 *) |
7983 | leency | 1773 | drop |
1774 | |||
1775 | |IL.opDIVSC: |
||
1776 | MovConst(GetAnyReg(), param2); |
||
1777 | BinOp(r1, r2); |
||
8859 | leency | 1778 | gen4(1, r2, r1); (* eors r1, r2 *) |
7983 | leency | 1779 | drop |
1780 | |||
1781 | |IL.opADDS: |
||
1782 | BinOp(r1, r2); |
||
8859 | leency | 1783 | gen4(12, r2, r1); (* orrs r1, r2 *) |
7983 | leency | 1784 | drop |
1785 | |||
1786 | |IL.opSUBS: |
||
1787 | BinOp(r1, r2); |
||
8859 | leency | 1788 | gen4(14, r2, r1); (* bics r1, r2 *) |
7983 | leency | 1789 | drop |
1790 | |||
8097 | maxcodehac | 1791 | |IL.opADDSC: |
7983 | leency | 1792 | MovConst(GetAnyReg(), param2); |
1793 | BinOp(r1, r2); |
||
8859 | leency | 1794 | gen4(12, r2, r1); (* orrs r1, r2 *) |
7983 | leency | 1795 | drop |
1796 | |||
1797 | |IL.opSUBSL: |
||
1798 | MovConst(GetAnyReg(), param2); |
||
1799 | BinOp(r1, r2); |
||
8859 | leency | 1800 | gen4(14, r1, r2); (* bics r2, r1 *) |
7983 | leency | 1801 | INCL(R.regs, r1); |
1802 | DEC(R.top); |
||
1803 | R.stk[R.top] := r2 |
||
1804 | |||
1805 | |IL.opSUBSR: |
||
1806 | MovConst(GetAnyReg(), param2); |
||
1807 | BinOp(r1, r2); |
||
8859 | leency | 1808 | gen4(14, r2, r1); (* bics r1, r2 *) |
7983 | leency | 1809 | drop |
1810 | |||
1811 | |IL.opUMINS: |
||
1812 | UnOp(r1); |
||
8859 | leency | 1813 | gen4(15, r1, r1) (* mvns r1, r1 *) |
7983 | leency | 1814 | |
1815 | |IL.opINCL, IL.opEXCL: |
||
1816 | BinOp(r1, r2); |
||
1817 | r3 := GetAnyReg(); |
||
1818 | MovConst(r3, 1); |
||
1819 | CmpConst(r1, 32); |
||
1820 | L := NewLabel(); |
||
1821 | jcc(jnb, L); |
||
8859 | leency | 1822 | gen4(2, r1, r3); (* lsls r3, r1 *) |
7983 | leency | 1823 | Ldr32(r1, r2); |
1824 | IF opcode = IL.opINCL THEN |
||
8859 | leency | 1825 | gen4(12, r3, r1) (* orrs r1, r3 *) |
7983 | leency | 1826 | ELSE |
8859 | leency | 1827 | gen4(14, r3, r1) (* bics r1, r3 *) |
7983 | leency | 1828 | END; |
1829 | Str32(r1, r2); |
||
1830 | Label(L); |
||
1831 | drop; |
||
1832 | drop; |
||
1833 | drop |
||
1834 | |||
1835 | |IL.opINCLC, IL.opEXCLC: |
||
1836 | UnOp(r2); |
||
1837 | r1 := GetAnyReg(); |
||
1838 | r3 := GetAnyReg(); |
||
1839 | MovConst(r3, 1); |
||
1840 | LslImm(r3, param2); |
||
1841 | Ldr32(r1, r2); |
||
1842 | IF opcode = IL.opINCLC THEN |
||
8859 | leency | 1843 | gen4(12, r3, r1) (* orrs r1, r3 *) |
7983 | leency | 1844 | ELSE |
8859 | leency | 1845 | gen4(14, r3, r1) (* bics r1, r3 *) |
7983 | leency | 1846 | END; |
1847 | Str32(r1, r2); |
||
1848 | drop; |
||
1849 | drop; |
||
1850 | drop |
||
1851 | |||
1852 | |IL.opLENGTH: |
||
1853 | PushAll(2); |
||
1854 | CallRTL(IL._length, 2); |
||
1855 | GetRegA |
||
1856 | |||
1857 | |IL.opLENGTHW: |
||
1858 | PushAll(2); |
||
1859 | CallRTL(IL._lengthw, 2); |
||
1860 | GetRegA |
||
1861 | |||
1862 | |IL.opSAVES: |
||
1863 | UnOp(r2); |
||
1864 | REG.PushAll_1(R); |
||
1865 | r1 := GetAnyReg(); |
||
1866 | reloc(r1, BIN.RDATA + pic, stroffs + param2); |
||
1867 | push(r1); |
||
1868 | drop; |
||
1869 | push(r2); |
||
1870 | drop; |
||
1871 | PushConst(param1); |
||
1872 | CallRTL(IL._move, 3) |
||
1873 | |||
1874 | |IL.opEQS .. IL.opGES: |
||
1875 | PushAll(4); |
||
1876 | PushConst(opcode - IL.opEQS); |
||
1877 | CallRTL(IL._strcmp, 5); |
||
1878 | GetRegA |
||
1879 | |||
1880 | |IL.opEQSW .. IL.opGESW: |
||
1881 | PushAll(4); |
||
1882 | PushConst(opcode - IL.opEQSW); |
||
1883 | CallRTL(IL._strcmpw, 5); |
||
1884 | GetRegA |
||
1885 | |||
1886 | |IL.opCOPY: |
||
1887 | PushAll(2); |
||
1888 | PushConst(param2); |
||
1889 | CallRTL(IL._move, 3) |
||
1890 | |||
1891 | |IL.opMOVE: |
||
1892 | PushAll(3); |
||
1893 | CallRTL(IL._move, 3) |
||
1894 | |||
1895 | |IL.opCOPYA: |
||
1896 | PushAll(4); |
||
1897 | PushConst(param2); |
||
1898 | CallRTL(IL._arrcpy, 5); |
||
1899 | GetRegA |
||
1900 | |||
1901 | |IL.opCOPYS: |
||
1902 | PushAll(4); |
||
1903 | PushConst(param2); |
||
1904 | CallRTL(IL._strcpy, 5) |
||
1905 | |||
1906 | |IL.opDIV: |
||
1907 | PushAll(2); |
||
1908 | divmod; |
||
1909 | GetRegA |
||
1910 | |||
1911 | |IL.opDIVL: |
||
1912 | UnOp(r1); |
||
1913 | REG.PushAll_1(R); |
||
1914 | PushConst(param2); |
||
1915 | push(r1); |
||
1916 | drop; |
||
1917 | divmod; |
||
1918 | GetRegA |
||
1919 | |||
1920 | |IL.opDIVR: |
||
1921 | n := UTILS.Log2(param2); |
||
1922 | IF n > 0 THEN |
||
1923 | UnOp(r1); |
||
1924 | AsrImm(r1, n) |
||
1925 | ELSIF n < 0 THEN |
||
1926 | PushAll(1); |
||
1927 | PushConst(param2); |
||
1928 | divmod; |
||
1929 | GetRegA |
||
1930 | END |
||
1931 | |||
1932 | |IL.opMOD: |
||
1933 | PushAll(2); |
||
1934 | divmod; |
||
1935 | mov(R0, R1); |
||
1936 | GetRegA |
||
1937 | |||
1938 | |IL.opMODR: |
||
1939 | n := UTILS.Log2(param2); |
||
1940 | IF n > 0 THEN |
||
1941 | UnOp(r1); |
||
1942 | IF n = 8 THEN |
||
8859 | leency | 1943 | Code(0B2C0H + r1 * 9) (* uxtb r1, r1 *) |
7983 | leency | 1944 | ELSIF n = 16 THEN |
8859 | leency | 1945 | Code(0B280H + r1 * 9) (* uxth r1, r1 *) |
7983 | leency | 1946 | ELSE |
1947 | LslImm(r1, 32 - n); |
||
1948 | LsrImm(r1, 32 - n) |
||
1949 | END |
||
1950 | ELSIF n < 0 THEN |
||
1951 | PushAll(1); |
||
1952 | PushConst(param2); |
||
1953 | divmod; |
||
1954 | mov(R0, R1); |
||
1955 | GetRegA |
||
1956 | ELSE |
||
1957 | UnOp(r1); |
||
1958 | MovConst(r1, 0) |
||
1959 | END |
||
1960 | |||
1961 | |IL.opMODL: |
||
1962 | UnOp(r1); |
||
1963 | REG.PushAll_1(R); |
||
1964 | PushConst(param2); |
||
1965 | push(r1); |
||
1966 | drop; |
||
1967 | divmod; |
||
1968 | mov(R0, R1); |
||
1969 | GetRegA |
||
1970 | |||
1971 | |IL.opIN, IL.opINR: |
||
1972 | IF opcode = IL.opINR THEN |
||
1973 | r2 := GetAnyReg(); |
||
1974 | MovConst(r2, param2) |
||
1975 | END; |
||
1976 | L := NewLabel(); |
||
1977 | L2 := NewLabel(); |
||
1978 | BinOp(r1, r2); |
||
1979 | r3 := GetAnyReg(); |
||
1980 | CmpConst(r1, 32); |
||
1981 | jcc(jb, L); |
||
1982 | MovConst(r1, 0); |
||
1983 | jmp(L2); |
||
1984 | Label(L); |
||
1985 | MovConst(r3, 1); |
||
1986 | Shift(IL.opLSL, r3, r1); |
||
8859 | leency | 1987 | gen4(0, r3, r2); (* ands r2, r3 *) |
7983 | leency | 1988 | SetCC(jne, r1); |
1989 | Label(L2); |
||
1990 | drop; |
||
1991 | drop |
||
1992 | |||
1993 | |IL.opINL: |
||
1994 | UnOp(r1); |
||
1995 | r2 := GetAnyReg(); |
||
1996 | MovConst(r2, LSL(1, param2)); |
||
8859 | leency | 1997 | gen4(0, r2, r1); (* ands r1, r2 *) |
7983 | leency | 1998 | SetCC(jne, r1); |
1999 | drop |
||
2000 | |||
2001 | |IL.opRSET: |
||
2002 | PushAll(2); |
||
2003 | CallRTL(IL._set, 2); |
||
2004 | GetRegA |
||
2005 | |||
2006 | |IL.opRSETR: |
||
2007 | PushAll(1); |
||
2008 | PushConst(param2); |
||
2009 | CallRTL(IL._set, 2); |
||
2010 | GetRegA |
||
2011 | |||
2012 | |IL.opRSETL: |
||
2013 | UnOp(r1); |
||
2014 | REG.PushAll_1(R); |
||
2015 | PushConst(param2); |
||
2016 | push(r1); |
||
2017 | drop; |
||
2018 | CallRTL(IL._set, 2); |
||
2019 | GetRegA |
||
2020 | |||
2021 | |IL.opRSET1: |
||
2022 | PushAll(1); |
||
2023 | CallRTL(IL._set1, 1); |
||
2024 | GetRegA |
||
2025 | |||
2026 | |IL.opCONSTF: |
||
2027 | MovConst(GetAnyReg(), UTILS.d2s(cmd.float)) |
||
2028 | |||
2029 | |IL.opMULF: |
||
2030 | PushAll(2); |
||
2031 | CallRTL(IL._fmul, 2); |
||
2032 | GetRegA |
||
2033 | |||
2034 | |IL.opDIVF: |
||
2035 | PushAll(2); |
||
2036 | CallRTL(IL._fdiv, 2); |
||
2037 | GetRegA |
||
2038 | |||
2039 | |IL.opDIVFI: |
||
2040 | PushAll(2); |
||
2041 | CallRTL(IL._fdivi, 2); |
||
2042 | GetRegA |
||
2043 | |||
8097 | maxcodehac | 2044 | |IL.opADDF: |
7983 | leency | 2045 | PushAll(2); |
2046 | CallRTL(IL._fadd, 2); |
||
2047 | GetRegA |
||
2048 | |||
2049 | |IL.opSUBFI: |
||
2050 | PushAll(2); |
||
2051 | CallRTL(IL._fsubi, 2); |
||
2052 | GetRegA |
||
2053 | |||
2054 | |IL.opSUBF: |
||
2055 | PushAll(2); |
||
2056 | CallRTL(IL._fsub, 2); |
||
2057 | GetRegA |
||
2058 | |||
2059 | |IL.opEQF..IL.opGEF: |
||
2060 | PushAll(2); |
||
2061 | PushConst(opcode - IL.opEQF); |
||
2062 | CallRTL(IL._fcmp, 3); |
||
2063 | GetRegA |
||
2064 | |||
2065 | |IL.opFLOOR: |
||
2066 | PushAll(1); |
||
2067 | CallRTL(IL._floor, 1); |
||
2068 | GetRegA |
||
2069 | |||
2070 | |IL.opFLT: |
||
2071 | PushAll(1); |
||
2072 | CallRTL(IL._flt, 1); |
||
2073 | GetRegA |
||
2074 | |||
2075 | |IL.opUMINF: |
||
2076 | UnOp(r1); |
||
2077 | r2 := GetAnyReg(); |
||
2078 | MovConst(r2, 1); |
||
2079 | LslImm(r2, 31); |
||
8859 | leency | 2080 | gen4(1, r2, r1); (* eors r1, r2 *) |
7983 | leency | 2081 | drop |
2082 | |||
2083 | |IL.opFABS: |
||
2084 | UnOp(r1); |
||
2085 | r2 := GetAnyReg(); |
||
2086 | MovConst(r2, 1); |
||
2087 | LslImm(r2, 31); |
||
8859 | leency | 2088 | gen4(14, r2, r1); (* bics r1, r2 *) |
7983 | leency | 2089 | drop |
2090 | |||
2091 | |IL.opNEW: |
||
8859 | leency | 2092 | cpsid_i; |
7983 | leency | 2093 | PushAll(1); |
8859 | leency | 2094 | n := param2 + 4; |
2095 | ASSERT(UTILS.Align(n, 4)); |
||
7983 | leency | 2096 | PushConst(n); |
2097 | PushConst(param1); |
||
8859 | leency | 2098 | CallRTL(IL._new, 3); |
2099 | cpsie_i |
||
7983 | leency | 2100 | |
2101 | |IL.opTYPEGP: |
||
2102 | UnOp(r1); |
||
2103 | PushAll(0); |
||
2104 | push(r1); |
||
2105 | PushConst(param2); |
||
2106 | CallRTL(IL._guard, 2); |
||
2107 | GetRegA |
||
2108 | |||
2109 | |IL.opIS: |
||
2110 | PushAll(1); |
||
2111 | PushConst(param2); |
||
2112 | CallRTL(IL._is, 2); |
||
2113 | GetRegA |
||
2114 | |||
2115 | |IL.opISREC: |
||
2116 | PushAll(2); |
||
2117 | PushConst(param2); |
||
2118 | CallRTL(IL._guardrec, 3); |
||
2119 | GetRegA |
||
2120 | |||
2121 | |IL.opTYPEGR: |
||
2122 | PushAll(1); |
||
2123 | PushConst(param2); |
||
2124 | CallRTL(IL._guardrec, 2); |
||
2125 | GetRegA |
||
2126 | |||
2127 | |IL.opTYPEGD: |
||
2128 | UnOp(r1); |
||
2129 | PushAll(0); |
||
2130 | SubImm8(r1, 4); |
||
2131 | Ldr32(r1, r1); |
||
2132 | push(r1); |
||
2133 | PushConst(param2); |
||
2134 | CallRTL(IL._guardrec, 2); |
||
2135 | GetRegA |
||
2136 | |||
2137 | |IL.opCASET: |
||
2138 | push(R2); |
||
2139 | push(R2); |
||
2140 | PushConst(param2); |
||
2141 | CallRTL(IL._guardrec, 2); |
||
2142 | pop(R2); |
||
2143 | cbnz(ACC, param1) |
||
2144 | |||
2145 | |IL.opROT: |
||
2146 | PushAll(0); |
||
2147 | mov(R2, SP); |
||
2148 | push(R2); |
||
2149 | PushConst(param2); |
||
2150 | CallRTL(IL._rot, 2) |
||
2151 | |||
2152 | |IL.opPACK: |
||
2153 | PushAll(2); |
||
2154 | CallRTL(IL._pack, 2) |
||
2155 | |||
2156 | |IL.opPACKC: |
||
2157 | PushAll(1); |
||
2158 | PushConst(param2); |
||
2159 | CallRTL(IL._pack, 2) |
||
2160 | |||
2161 | |IL.opUNPK: |
||
2162 | PushAll(2); |
||
2163 | CallRTL(IL._unpk, 2) |
||
2164 | |||
2165 | END; |
||
2166 | |||
2167 | cmd := cmd.next(COMMAND) |
||
2168 | END; |
||
2169 | |||
2170 | ASSERT(R.pushed = 0); |
||
2171 | ASSERT(R.top = -1) |
||
2172 | END translate; |
||
2173 | |||
2174 | |||
8859 | leency | 2175 | PROCEDURE prolog (GlobSize, tcount, pic, sp, ivt_len: INTEGER); |
7983 | leency | 2176 | VAR |
2177 | r1, r2, i, dcount: INTEGER; |
||
2178 | |||
2179 | BEGIN |
||
2180 | entry := NewLabel(); |
||
2181 | emptyProc := NewLabel(); |
||
2182 | genInt := NewLabel(); |
||
2183 | genTrap := NewLabel(); |
||
2184 | sdivProc := NewLabel(); |
||
2185 | |||
2186 | trap := emptyProc; |
||
2187 | int0 := emptyProc; |
||
2188 | |||
2189 | IVT[0] := sp; |
||
2190 | IVT[1] := entry; |
||
2191 | FOR i := 2 TO ivt_len - 1 DO |
||
2192 | IVT[i] := genInt |
||
2193 | END; |
||
2194 | |||
2195 | FOR i := 0 TO ivt_len - 1 DO |
||
2196 | Code(low(IVT[i])); |
||
2197 | Code(high(IVT[i])) |
||
2198 | END; |
||
2199 | |||
2200 | Label(entry); |
||
8859 | leency | 2201 | cpsie_i; |
7983 | leency | 2202 | |
2203 | r1 := GetAnyReg(); |
||
2204 | r2 := GetAnyReg(); |
||
2205 | reloc(r1, BIN.RDATA + pic, 0); |
||
2206 | |||
2207 | FOR i := 0 TO tcount - 1 DO |
||
2208 | MovConst(r2, CHL.GetInt(IL.codes.types, i)); |
||
2209 | Str32(r2, r1); |
||
2210 | AddImm8(r1, 4) |
||
2211 | END; |
||
2212 | |||
2213 | dcount := CHL.Length(IL.codes.data); |
||
2214 | FOR i := 0 TO dcount - 1 BY 4 DO |
||
2215 | MovConst(r2, BIN.get32le(IL.codes.data, i)); |
||
2216 | Str32(r2, r1); |
||
2217 | AddImm8(r1, 4) |
||
2218 | END; |
||
2219 | |||
2220 | drop; |
||
2221 | drop; |
||
2222 | |||
2223 | r1 := GetAnyReg(); |
||
2224 | MovConst(r1, sp); |
||
2225 | mov(SP, r1); |
||
2226 | reloc(r1, BIN.RDATA + pic, 0); |
||
2227 | push(r1); |
||
2228 | reloc(r1, BIN.RBSS + pic, 0); |
||
2229 | r2 := GetAnyReg(); |
||
2230 | MovConst(r2, GlobSize); |
||
2231 | AddReg(r1, r1, r2); |
||
2232 | drop; |
||
2233 | push(r1); |
||
2234 | drop; |
||
2235 | PushConst(tcount); |
||
2236 | CallRTL(IL._init, 3) |
||
2237 | END prolog; |
||
2238 | |||
2239 | |||
2240 | PROCEDURE epilog; |
||
2241 | VAR |
||
2242 | L1, L2, L3, L4: INTEGER; |
||
2243 | |||
2244 | BEGIN |
||
8859 | leency | 2245 | (* L2: *) |
2246 | Code(0E7FEH); (* b L2 *) |
||
7983 | leency | 2247 | |
2248 | Label(genInt); |
||
8859 | leency | 2249 | Code(0F3EFH); Code(08005H); (* mrs r0, ipsr *) |
2250 | gen14(FALSE, TRUE, {R0}); (* push {lr, r0} *) |
||
7983 | leency | 2251 | call(int0); |
8859 | leency | 2252 | gen14(TRUE, TRUE, {R0}); (* pop {pc, r0} *) |
7983 | leency | 2253 | |
2254 | Label(emptyProc); |
||
2255 | Code(04770H); (* bx lr *) |
||
2256 | |||
2257 | Label(genTrap); |
||
2258 | call(trap); |
||
2259 | call(entry); |
||
2260 | |||
2261 | Label(sdivProc); |
||
8859 | leency | 2262 | IF _SDIV IN Target.InstrSet THEN |
2263 | Code(09800H); (* ldr r0, [sp] *) |
||
2264 | Code(09901H); (* ldr r1, [sp, 4] *) |
||
2265 | Code(0FB91H); (* sdiv r2, r1, r0 *) |
||
7983 | leency | 2266 | Code(0F2F0H); |
8859 | leency | 2267 | Code(00013H); (* movs r3, r2 *) |
2268 | Code(04343H); (* muls r3, r0, r3 *) |
||
2269 | Code(01AC9H); (* subs r1, r1, r3 *) |
||
2270 | Code(0DA01H); (* bge L *) |
||
2271 | Code(01809H); (* adds r1, r1, r0 *) |
||
2272 | Code(03A01H); (* subs r2, 1 *) |
||
2273 | (* L: *) |
||
2274 | Code(00010H); (* movs r0, r2 *) |
||
2275 | Code(04770H); (* bx lr *) |
||
7983 | leency | 2276 | ELSE |
2277 | (* a / b; a >= 0 *) |
||
2278 | L1 := NewLabel(); |
||
2279 | L2 := NewLabel(); |
||
2280 | L3 := NewLabel(); |
||
2281 | L4 := NewLabel(); |
||
2282 | |||
2283 | LdrSp(R1, 1); |
||
2284 | LdrSp(R2, 0); |
||
2285 | MovConst(R0, 0); |
||
2286 | push(R4); |
||
2287 | |||
2288 | Label(L4); |
||
2289 | Cmp(R1, R2); |
||
2290 | jcc(jl, L1); |
||
2291 | MovConst(R3, 2); |
||
2292 | mov(R4, R2); |
||
2293 | LslImm(R4, 1); |
||
2294 | Label(L3); |
||
2295 | Cmp(R1, R4); |
||
2296 | jcc(jl, L2); |
||
2297 | CmpConst(R4, 0); |
||
2298 | jcc(jle, L2); |
||
2299 | LslImm(R4, 1); |
||
2300 | LslImm(R3, 1); |
||
2301 | jmp(L3); |
||
2302 | Label(L2); |
||
2303 | LsrImm(R4, 1); |
||
2304 | LsrImm(R3, 1); |
||
2305 | SubReg(R1, R1, R4); |
||
2306 | AddReg(R0, R0, R3); |
||
2307 | jmp(L4); |
||
2308 | Label(L1); |
||
2309 | |||
2310 | (* a / b; a < 0 *) |
||
2311 | L1 := NewLabel(); |
||
2312 | L2 := NewLabel(); |
||
2313 | L3 := NewLabel(); |
||
2314 | L4 := NewLabel(); |
||
2315 | |||
2316 | Label(L4); |
||
2317 | CmpConst(R1, 0); |
||
2318 | jcc(jge, L1); |
||
2319 | MovConst(R3, 2); |
||
2320 | mov(R4, R2); |
||
2321 | LslImm(R4, 1); |
||
2322 | Neg(R1); |
||
2323 | Label(L3); |
||
2324 | Cmp(R1, R4); |
||
2325 | jcc(jl, L2); |
||
2326 | CmpConst(R4, 0); |
||
2327 | jcc(jle, L2); |
||
2328 | LslImm(R4, 1); |
||
2329 | LslImm(R3, 1); |
||
2330 | jmp(L3); |
||
2331 | Label(L2); |
||
2332 | Neg(R1); |
||
2333 | LsrImm(R4, 1); |
||
2334 | LsrImm(R3, 1); |
||
2335 | AddReg(R1, R1, R4); |
||
2336 | SubReg(R0, R0, R3); |
||
2337 | jmp(L4); |
||
2338 | Label(L1); |
||
2339 | |||
2340 | pop(R4); |
||
2341 | Code(04770H); (* bx lr *) |
||
2342 | END |
||
2343 | |||
2344 | END epilog; |
||
2345 | |||
2346 | |||
8859 | leency | 2347 | PROCEDURE SetTarget (FlashStart, SRAMStart: INTEGER; InstrSet: SET; isNXP: BOOLEAN); |
7983 | leency | 2348 | BEGIN |
8859 | leency | 2349 | Target.FlashAdr := FlashStart; |
2350 | Target.SRAMAdr := SRAMStart; |
||
2351 | Target.InstrSet := InstrSet; |
||
2352 | Target.isNXP := isNXP; |
||
2353 | |||
2354 | Target.IVTLen := 256; (* >= 192 *) |
||
7983 | leency | 2355 | Target.Reserved := 0; |
2356 | Target.MinStack := 512; |
||
8859 | leency | 2357 | END SetTarget; |
7983 | leency | 2358 | |
2359 | |||
2360 | PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS); |
||
2361 | VAR |
||
2362 | opt: PROG.OPTIONS; |
||
2363 | |||
8859 | leency | 2364 | ram, rom, i, j: INTEGER; |
7983 | leency | 2365 | |
2366 | DataAdr, BssAdr, DataSize, BssSize, CodeSize: INTEGER; |
||
2367 | |||
2368 | BEGIN |
||
8859 | leency | 2369 | ram := MIN(MAX(options.ram, minRAM), maxRAM) * 1024; |
2370 | rom := MIN(MAX(options.rom, minROM), maxROM) * 1024; |
||
2371 | |||
7983 | leency | 2372 | IF target = TARGETS.STM32CM3 THEN |
8859 | leency | 2373 | SetTarget(08000000H, 20000000H, CortexM3, FALSE) |
7983 | leency | 2374 | END; |
2375 | |||
2376 | tcount := CHL.Length(IL.codes.types); |
||
2377 | |||
2378 | opt := options; |
||
2379 | CodeList := LISTS.create(NIL); |
||
2380 | |||
2381 | program := BIN.create(IL.codes.lcount); |
||
2382 | |||
8859 | leency | 2383 | REG.Init(R, push, pop, mov, xchg, {R0, R1, R2, R3}); |
7983 | leency | 2384 | |
2385 | StkCount := 0; |
||
2386 | |||
2387 | DataAdr := Target.SRAMAdr + Target.Reserved; |
||
2388 | DataSize := CHL.Length(IL.codes.data) + tcount * 4 + Target.Reserved; |
||
2389 | WHILE DataSize MOD 4 # 0 DO |
||
2390 | CHL.PushByte(IL.codes.data, 0); |
||
2391 | INC(DataSize) |
||
2392 | END; |
||
2393 | BssAdr := DataAdr + DataSize - Target.Reserved; |
||
2394 | |||
2395 | IL.set_bss(MAX(IL.codes.bss, MAX(IL.codes.dmin - CHL.Length(IL.codes.data), 4))); |
||
2396 | |||
2397 | BssSize := IL.codes.bss; |
||
2398 | ASSERT(UTILS.Align(BssSize, 4)); |
||
2399 | |||
8859 | leency | 2400 | prolog(BssSize, tcount, ORD(opt.pic), Target.SRAMAdr + ram, Target.IVTLen); |
7983 | leency | 2401 | translate(ORD(opt.pic), tcount * 4); |
2402 | epilog; |
||
2403 | |||
2404 | fixup(Target.FlashAdr, DataAdr, BssAdr); |
||
2405 | |||
2406 | INC(DataSize, BssSize); |
||
2407 | CodeSize := CHL.Length(program.code); |
||
2408 | |||
2409 | IF CodeSize > rom THEN |
||
2410 | ERRORS.Error(203) |
||
2411 | END; |
||
2412 | |||
2413 | IF DataSize > ram - Target.MinStack THEN |
||
2414 | ERRORS.Error(204) |
||
2415 | END; |
||
2416 | |||
8859 | leency | 2417 | IF Target.isNXP THEN |
2418 | BIN.put32le(program.code, 2FCH, 0H); (* code read protection (CRP) *) |
||
2419 | (* NXP checksum *) |
||
2420 | j := 0; |
||
2421 | FOR i := 0 TO 6 DO |
||
2422 | INC(j, BIN.get32le(program.code, i * 4)) |
||
2423 | END; |
||
2424 | BIN.put32le(program.code, 1CH, -j) |
||
2425 | END; |
||
2426 | |||
8097 | maxcodehac | 2427 | WR.Create(outname); |
7983 | leency | 2428 | |
8097 | maxcodehac | 2429 | HEX.Data2(program.code, 0, CodeSize, high(Target.FlashAdr)); |
2430 | HEX.End; |
||
7983 | leency | 2431 | |
8097 | maxcodehac | 2432 | WR.Close; |
7983 | leency | 2433 | |
8859 | leency | 2434 | C.Dashes; |
7983 | leency | 2435 | C.String( " rom: "); C.Int(CodeSize); C.String(" of "); C.Int(rom); C.String(" ("); C.Int(CodeSize * 100 DIV rom); C.StringLn("%)"); |
2436 | C.Ln; |
||
8859 | leency | 2437 | C.String( " ram: "); C.Int(DataSize); C.String(" of "); C.Int(ram); C.String(" ("); C.Int(DataSize * 100 DIV ram); C.StringLn("%)") |
7983 | leency | 2438 | END CodeGen; |
2439 | |||
2440 | |||
2441 | PROCEDURE SetIV* (idx: INTEGER): BOOLEAN; |
||
2442 | VAR |
||
2443 | res: BOOLEAN; |
||
2444 | |||
2445 | BEGIN |
||
2446 | res := IVT[idx] = 0; |
||
2447 | IVT[idx] := 1 |
||
2448 | |||
2449 | RETURN res |
||
2450 | END SetIV; |
||
2451 | |||
2452 | |||
2453 | PROCEDURE init; |
||
2454 | VAR |
||
2455 | i: INTEGER; |
||
2456 | |||
2457 | BEGIN |
||
2458 | FOR i := 0 TO LEN(IVT) - 1 DO |
||
2459 | IVT[i] := 0 |
||
2460 | END |
||
2461 | END init; |
||
2462 | |||
2463 | |||
2464 | BEGIN |
||
2465 | init |
||
2466 | END THUMB.>>>>>=>=>=>=>=>=>=>>>=>=>=>=>=>=>>>=>=>=>>>>=>>=> |