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