From 595f8a9db4a533377fdef320a146c0f85662eefa Mon Sep 17 00:00:00 2001 From: Enrico Lumetti Date: Wed, 5 May 2021 20:55:32 +0200 Subject: [PATCH] Add select-instructions pass --- select-instructions.rkt | 65 +++++++++++++++++++++++++++++++++ test-select-instructions.rkt | 71 ++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 select-instructions.rkt create mode 100644 test-select-instructions.rkt diff --git a/select-instructions.rkt b/select-instructions.rkt new file mode 100644 index 0000000..b7c6529 --- /dev/null +++ b/select-instructions.rkt @@ -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))) diff --git a/test-select-instructions.rkt b/test-select-instructions.rkt new file mode 100644 index 0000000..22a7b15 --- /dev/null +++ b/test-select-instructions.rkt @@ -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))))))