Compare commits
3 Commits
ec8e75232e
...
595f8a9db4
| Author | SHA1 | Date |
|---|---|---|
|
|
595f8a9db4 | |
|
|
ced273944b | |
|
|
44a453a062 |
|
|
@ -1,5 +1,6 @@
|
||||||
.global _main
|
.global start
|
||||||
|
|
||||||
_main:
|
start:
|
||||||
mov x0, 42 // exit code
|
mov x0, 1
|
||||||
ret
|
add x0, x0, 41
|
||||||
|
b conclusion
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@
|
||||||
|
|
||||||
; remove complex sub-expression
|
; remove complex sub-expression
|
||||||
; the resulting code is either
|
; the resulting code is either
|
||||||
; - (read)
|
|
||||||
; - a number literal
|
; - a number literal
|
||||||
; - a symbol
|
; - a symbol
|
||||||
; the three above are called in the following "simple terms"
|
; the three above are called in the following "simple terms"
|
||||||
|
; - (read)
|
||||||
; - (- x) where x is a simple term
|
; - (- x) where x is a simple term
|
||||||
; - (+ x y) where x and y are simple terms
|
; - (+ x y) where x and y are simple terms
|
||||||
; - (let ([var y]) z) where y and z are expressions
|
; - (let ([var y]) z) where y and z are expressions
|
||||||
|
|
@ -61,7 +61,13 @@
|
||||||
(match exp
|
(match exp
|
||||||
[(? fixnum?) (values exp '() tmpcount)]
|
[(? fixnum?) (values exp '() tmpcount)]
|
||||||
[(? symbol?) (values exp '() tmpcount)]
|
[(? symbol?) (values exp '() tmpcount)]
|
||||||
[`(read) (values exp '() tmpcount)]
|
[`(read)
|
||||||
|
(begin
|
||||||
|
(define new-tmpcount (+ tmpcount 1))
|
||||||
|
(define tmpname (get-unique-symbol new-tmpcount))
|
||||||
|
(values tmpname
|
||||||
|
(list `(,tmpname (read)))
|
||||||
|
new-tmpcount))]
|
||||||
[`(- ,e)
|
[`(- ,e)
|
||||||
(begin
|
(begin
|
||||||
(define-values (new-exp assoc-list exp-tmpcount) (rco-arg e tmpcount))
|
(define-values (new-exp assoc-list exp-tmpcount) (rco-arg e tmpcount))
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
.global main
|
.global main, conclusion
|
||||||
main:
|
main:
|
||||||
bl _main
|
b start
|
||||||
|
|
||||||
|
conclusion:
|
||||||
mov x8, 93 // sys_exit() is at index 93 in kernel functions table
|
mov x8, 93 // sys_exit() is at index 93 in kernel functions table
|
||||||
svc #0 // generate kernel call sys_exit(123);
|
svc #0 // generate kernel call sys_exit(123);
|
||||||
|
|
|
||||||
|
|
@ -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)))
|
||||||
|
|
@ -19,8 +19,6 @@
|
||||||
|
|
||||||
`(program () (+ (let ([x (+ (- 1) 2)]) (+ x 2)) (+ 4 5)))))
|
`(program () (+ (let ([x (+ (- 1) 2)]) (+ x 2)) (+ 4 5)))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(define (pass program) (explicate-control (remove-complex-opera* program)))
|
(define (pass program) (explicate-control (remove-complex-opera* program)))
|
||||||
|
|
||||||
(test-eq
|
(test-eq
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,21 @@
|
||||||
`(program () (let ([x (let ([x 1]) x)]) (+ 2 x)))
|
`(program () (let ([x (let ([x 1]) x)]) (+ 2 x)))
|
||||||
`(program ()
|
`(program ()
|
||||||
(let ([y (let ([x 20])
|
(let ([y (let ([x 20])
|
||||||
(+ x (let ([x 22]) x)))]) y))))
|
(+ x (let ([x 22]) x)))]) y))
|
||||||
|
`(program ()
|
||||||
|
(+ (read) (read)))))
|
||||||
|
|
||||||
(for ([program programs] [env (build-list (length programs) (lambda (_) '()))])
|
(define inputs
|
||||||
(test-eq ((interp-R1 env) program)
|
(let ([empty-inputs (build-list (length programs) (lambda (_) ""))])
|
||||||
((interp-R1 env) (remove-complex-opera* program))))
|
(list-set empty-inputs 13 "2\n3")))
|
||||||
|
|
||||||
|
(for ([program programs]
|
||||||
|
[env (build-list (length programs) (lambda (_) '()))]
|
||||||
|
[input-string inputs])
|
||||||
|
(test-eq (with-input-from-string input-string
|
||||||
|
(lambda () ((interp-R1 env) program)))
|
||||||
|
(with-input-from-string input-string
|
||||||
|
(lambda () ((interp-R1 env) (remove-complex-opera* program))))))
|
||||||
|
|
||||||
(test-eq
|
(test-eq
|
||||||
(remove-complex-opera* (list-ref programs 0))
|
(remove-complex-opera* (list-ref programs 0))
|
||||||
|
|
@ -95,3 +105,7 @@
|
||||||
(test-eq
|
(test-eq
|
||||||
(remove-complex-opera* (list-ref programs 12))
|
(remove-complex-opera* (list-ref programs 12))
|
||||||
`(program () (let ((y.1 (let ((x.1 20)) (let ((x.2 22)) (+ x.1 x.2))))) y.1)))
|
`(program () (let ((y.1 (let ((x.1 20)) (let ((x.2 22)) (+ x.1 x.2))))) y.1)))
|
||||||
|
|
||||||
|
(test-eq
|
||||||
|
(remove-complex-opera* (list-ref programs 13))
|
||||||
|
`(program () (let ((tmp.1 (read))) (let ((tmp.2 (read))) (+ tmp.1 tmp.2)))))
|
||||||
|
|
|
||||||
|
|
@ -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