Add select-instructions pass
This commit is contained in:
parent
ced273944b
commit
595f8a9db4
|
|
@ -0,0 +1,65 @@
|
|||
#lang racket
|
||||
|
||||
(require racket/list)
|
||||
|
||||
(provide select-instructions)
|
||||
|
||||
(define (select-instructions p)
|
||||
(match p
|
||||
[`(program ,data ,body) `(AArch64VProgram ,data ,(select-instructions-section (car body)))]))
|
||||
|
||||
(define (select-instructions-section sec)
|
||||
(match sec
|
||||
[`(,label . ,statement) `(,label . (Block `() ,(select-instructions-stmt statement)))]))
|
||||
|
||||
(define (select-instructions-stmt stmt)
|
||||
(match stmt
|
||||
[`(return ,exp) (select-instructions-return exp)]
|
||||
[`(seq (assign ,var ,exp) ,next-stmt)
|
||||
(append (select-instructions-assign var exp)
|
||||
(select-instructions-stmt next-stmt))]))
|
||||
|
||||
(define (select-instructions-assign var exp)
|
||||
(match exp
|
||||
[(? symbol?) (list `(Instr mov ((Var ,var) (Var ,exp))))]
|
||||
[(? fixnum?) (list `(Instr mov ((Var ,var) (Imm ,exp))))]
|
||||
[`(read) (select-instructions-read `(Var ,var))]
|
||||
[`(- ,e) (select-instructions-neg e `(Var ,var))]
|
||||
[`(+ ,a ,b) (select-instructions-add a b `(Var ,var))]))
|
||||
|
||||
(define (select-instructions-return exp)
|
||||
(append (match exp
|
||||
[(? symbol?) (list `(Instr mov (x0 (Var ,exp))))]
|
||||
[(? fixnum?) (list `(Instr mov (x0 (Imm ,exp))))]
|
||||
[`(read) (select-instructions-read 'x0)]
|
||||
[`(- ,e) (select-instructions-neg e 'x0)]
|
||||
[`(+ ,a ,b) (select-instructions-add a b 'x0)])
|
||||
`[(Instr b (conclusion))]))
|
||||
|
||||
(define (select-instructions-read dest)
|
||||
(if (eq? dest 'x0)
|
||||
(list `(Instr bl _builtin_read))
|
||||
(list `(Instr bl _builtin_read) `(Instr mov (,dest x0)))))
|
||||
|
||||
(define (select-instructions-neg exp dest)
|
||||
(begin
|
||||
(define var-exp (if (fixnum? exp)
|
||||
`(Imm ,exp)
|
||||
`(Var ,exp)))
|
||||
(list `(Instr neg (,dest ,var-exp)))))
|
||||
|
||||
(define (select-instructions-add a b dest)
|
||||
(begin
|
||||
; if e1 is an imm, swap
|
||||
(define-values (e1 e2) (imm-to-right a b))
|
||||
(define num-imm (count fixnum? (list e1 e2)))
|
||||
(match num-imm
|
||||
[0 (list `(Instr add (,dest (Var ,e1) (Var ,e2))))]
|
||||
[1 (list `(Instr add (,dest (Var ,e1) (Imm ,e2))))]
|
||||
[2 (list `(Instr mov (,dest (Imm ,e1)))
|
||||
`(Instr add (,dest ,dest (Imm ,e2))))])))
|
||||
|
||||
(define (imm-to-right e1 e2)
|
||||
(if (and (fixnum? e1) (not (fixnum? e2)))
|
||||
(values e2 e1)
|
||||
(values e1 e2)))
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
#lang racket
|
||||
|
||||
(require "select-instructions.rkt")
|
||||
(require "test-util.rkt")
|
||||
|
||||
(define programs
|
||||
(list
|
||||
`(program ()
|
||||
((start .
|
||||
(return (+ 2 3)))))
|
||||
`(program ()
|
||||
((start .
|
||||
(seq (assign x 3)
|
||||
(return (+ 2 x))))))
|
||||
`(program ()
|
||||
((start .
|
||||
(seq (assign tmp.1 (read))
|
||||
(return (+ tmp.1 3))))))
|
||||
`(program ()
|
||||
((start .
|
||||
(seq (assign tmp.1 (- 1))
|
||||
(seq (assign x.1 (+ tmp.1 2))
|
||||
(seq (assign tmp.2 (+ x.1 2))
|
||||
(seq (assign tmp.3 (+ 4 5))
|
||||
(return (+ tmp.2 tmp.3)))))))))))
|
||||
|
||||
|
||||
(test-eq (select-instructions (list-ref programs 0))
|
||||
`(AArch64VProgram
|
||||
()
|
||||
(start
|
||||
Block
|
||||
`()
|
||||
((Instr mov (x0 (Imm 2)))
|
||||
(Instr add (x0 x0 (Imm 3)))
|
||||
(Instr b (conclusion))))))
|
||||
|
||||
(test-eq (select-instructions (list-ref programs 1))
|
||||
`(AArch64VProgram
|
||||
()
|
||||
(start
|
||||
Block
|
||||
`()
|
||||
((Instr mov ((Var x) (Imm 3)))
|
||||
(Instr add (x0 (Var x) (Imm 2)))
|
||||
(Instr b (conclusion))))))
|
||||
|
||||
(test-eq (select-instructions (list-ref programs 2))
|
||||
`(AArch64VProgram
|
||||
()
|
||||
(start
|
||||
Block
|
||||
`()
|
||||
((Instr bl _builtin_read)
|
||||
(Instr mov ((Var tmp.1) x0))
|
||||
(Instr add (x0 (Var tmp.1) (Imm 3)))
|
||||
(Instr b (conclusion))))))
|
||||
|
||||
(test-eq (select-instructions (list-ref programs 3))
|
||||
`(AArch64VProgram
|
||||
()
|
||||
(start
|
||||
Block
|
||||
`()
|
||||
((Instr neg ((Var tmp.1) (Imm 1)))
|
||||
(Instr add ((Var x.1) (Var tmp.1) (Imm 2)))
|
||||
(Instr add ((Var tmp.2) (Var x.1) (Imm 2)))
|
||||
(Instr mov ((Var tmp.3) (Imm 4)))
|
||||
(Instr add ((Var tmp.3) (Var tmp.3) (Imm 5)))
|
||||
(Instr add (x0 (Var tmp.2) (Var tmp.3)))
|
||||
(Instr b (conclusion))))))
|
||||
Loading…
Reference in New Issue