Compare commits

...

3 Commits

Author SHA1 Message Date
Enrico Lumetti 595f8a9db4 Add select-instructions pass 2021-05-05 20:55:32 +02:00
Enrico Lumetti ced273944b Add conclusion and rename _main to start 2021-05-05 20:55:19 +02:00
Enrico Lumetti 44a453a062 Avoid having (read) as an atom in Cvar language 2021-05-05 20:55:00 +02:00
7 changed files with 171 additions and 14 deletions

View File

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

View File

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

View File

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

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

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

View File

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

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