1 (define (linearize-and-cleanup cfg)
3 (define bbs-vector (cfg->vector cfg))
8 (set! todo (cons bb todo)))
13 (set! rev-code (cons instr rev-code)))
16 (emit (list 'movlw val)))
19 (emit (list 'movwf adr)))
22 (emit (list 'movfw adr)))
25 (emit (list 'clrf adr)))
28 (emit (list 'setf adr)))
31 (emit (list 'incf adr)))
34 (emit (list 'decf adr)))
37 (emit (list 'addwf adr)))
40 (emit (list 'addwfc adr)))
43 (emit (list 'subwf adr)))
46 (emit (list 'subwfb adr)))
49 (emit (list 'cpfseq adr)))
52 (emit (list 'cpfslt adr)))
55 (emit (list 'cpfsgt adr)))
58 (emit (list 'bra label)))
61 (emit (list 'rcall label)))
64 (if (and #f (and (not (null? rev-code))
65 (eq? (caar rev-code) 'rcall)))
66 (let ((label (cadar rev-code)))
67 (set! rev-code (cdr rev-code))
69 (emit (list 'return))))
72 (if (and #f (and (not (null? rev-code))
73 (eq? (caar rev-code) 'bra)
74 (eq? (cadar rev-code) lab)))
76 (set! rev-code (cdr rev-code))
78 (emit (list 'label lab))))
83 (define (move-reg src dst)
93 (define (bb-linearize bb)
94 (let ((label-num (bb-label-num bb)))
95 (let ((bb (vector-ref bbs-vector label-num)))
97 (define (move-lit n adr)
106 (define (dump-instr instr)
107 (cond ((call-instr? instr)
108 (let* ((def-proc (call-instr-def-proc instr))
109 (entry (def-procedure-entry def-proc)))
113 (let ((label (bb-label entry)))
116 ((return-instr? instr)
119 (let ((src1 (instr-src1 instr))
120 (src2 (instr-src2 instr))
121 (dst (instr-dst instr)))
122 (if (and (or (not (byte-cell? dst))
124 (or (not (byte-cell? src1))
125 (byte-cell-adr src1))
126 (or (not (byte-cell? src2))
127 (byte-cell-adr src2)))
128 (case (instr-id instr)
131 (let ((n (byte-lit-val src1))
132 (z (byte-cell-adr dst)))
134 (let ((x (byte-cell-adr src1))
135 (z (byte-cell-adr dst)))
139 (let ((n (byte-lit-val src2))
140 (z (byte-cell-adr dst)))
142 (move-lit (byte-lit-val src1) z)
143 (move-reg (byte-cell-adr src1) z))
144 (case (instr-id instr)
167 (let ((x (byte-cell-adr src1))
168 (y (byte-cell-adr src2))
169 (z (byte-cell-adr dst)))
170 (cond ((and (not (= x y)) (= y z))
172 (case (instr-id instr)
181 (else (error "..."))))
185 (case (instr-id instr)
194 (else (error "..."))))))))
196 (let* ((succs (bb-succs bb))
198 (bra (bb-label dest))
201 (let* ((succs (bb-succs bb))
202 (dest-true (car succs))
203 (dest-false (cadr succs)))
205 (define (compare flip adr)
206 (case (instr-id instr)
207 ((x<y) (if flip (cpfsgt adr) (cpfslt adr)))
208 ((x>y) (if flip (cpfslt adr) (cpfsgt adr)))
210 (bra (bb-label dest-false))
211 (bra (bb-label dest-true))
212 (add-todo dest-false)
213 (add-todo dest-true))
215 (cond ((byte-lit? src1)
216 (let ((n (byte-lit-val src1))
217 (y (byte-cell-adr src2)))
218 (if #f #;(and (or (= n 0) (= n 1) (= n #xff))
219 (eq? (instr-id instr) 'x==y))
220 (special-compare-eq-lit n x)
225 (let ((x (byte-cell-adr src1))
226 (n (byte-lit-val src2)))
227 (if #f #;(and (or (= n 0) (= n 1) (= n #xff))
228 (eq? (instr-id instr) 'x==y))
229 (special-compare-eq-lit n x) ;; TODO does not exist. the only way apart from cpfseq I see would be to load w, do a subtraction, then conditional branch, but would be larger and would take 1-2 cycles more
234 (let ((x (byte-cell-adr src1))
235 (y (byte-cell-adr src2)))
240 (emit (list (instr-id instr))))))))))
244 (vector-set! bbs-vector label-num #f)
245 (label (bb-label bb))
246 (for-each dump-instr (reverse (bb-rev-instrs bb)))
247 (for-each add-todo (bb-succs bb)))))))
249 (let ((prog-label (asm-make-label 'PROG)))
254 (add-todo (vector-ref bbs-vector 0))
259 (let ((bb (car todo)))
260 (set! todo (cdr todo))
265 (define (assembler-gen filename cfg)
270 (movlw (cadr instr)))
272 (movwf (cadr instr)))
274 (movf (cadr instr) 'w))
284 (addwf (cadr instr)))
286 (addwfc (cadr instr)))
288 (subwf (cadr instr)))
290 (subwfb (cadr instr)))
292 (cpfseq (cadr instr)))
294 (cpfslt (cadr instr)))
296 (cpfsgt (cadr instr)))
300 (rcall (cadr instr)))
305 (string-append (symbol->string (asm-label-id (cadr instr))) ":"))
306 (asm-label (cadr instr)))
310 ' (error "unknown instruction" instr))))
316 (let ((code (linearize-and-cleanup cfg)))
317 ; (pretty-print code)
322 '(display "------------------ GENERATED CODE\n")
324 (asm-display-listing (current-output-port))
326 (asm-write-hex-file (string-append filename ".hex")) ;; TODO move to main ?
330 (define (code-gen filename cfg)
331 (allocate-registers cfg)
332 (assembler-gen filename cfg)
334 ; (pretty-print (reverse (bb-rev-instrs bb))) ;; TODO what ? there are no bbs here...