Add select-instructions pass

This commit is contained in:
Enrico Lumetti 2021-05-05 20:55:32 +02:00
parent ced273944b
commit 595f8a9db4
2 changed files with 136 additions and 0 deletions

65
select-instructions.rkt Normal file
View File

@ -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)))

View File

@ -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))))))