From 9a0dadd77c908217c34c8e5c010812a5d1d1da20 Mon Sep 17 00:00:00 2001 From: Vedanth Padmaraman Date: Tue, 4 Jun 2024 17:33:04 +0530 Subject: [PATCH 1/7] Support floating-point arithmetic and comparison + add test `float` --- src/backend/brilisp.scm | 2 +- src/backend/llvm.py | 29 ++++++++++++++++++++++++++++ src/backend/runtime.c | 5 +++++ src/backend/tests/brilisp/float.out | 3 +++ src/backend/tests/brilisp/float.sexp | 20 +++++++++++++++++++ 5 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 src/backend/tests/brilisp/float.out create mode 100644 src/backend/tests/brilisp/float.sexp diff --git a/src/backend/brilisp.scm b/src/backend/brilisp.scm index da1f9bb..001f8ed 100644 --- a/src/backend/brilisp.scm +++ b/src/backend/brilisp.scm @@ -62,7 +62,7 @@ (define (value? instr) (and (eq? (first instr) 'set) (memq (first (third instr)) - '(add mul sub div eq lt gt le ge not and or alloc load ptradd id)))) + '(add mul sub div eq lt gt le ge not and or alloc load ptradd id fadd fsub fmul fdiv)))) (define (gen-value-instr instr) (let ((to (second instr)) diff --git a/src/backend/llvm.py b/src/backend/llvm.py index 5b73357..6a3b2e5 100644 --- a/src/backend/llvm.py +++ b/src/backend/llvm.py @@ -56,6 +56,8 @@ def gen_type(self, type): return ir.VoidType() elif type == "bool": return ir.IntType(1) + elif type == "float": + return ir.DoubleType() else: raise CodegenError(f"Unknown type {type}") @@ -81,6 +83,10 @@ def gen_instructions(self, instrs): "not": "not_", "and": "and_", "or": "or_", + "fadd": "fadd", + "fsub": "fsub", + "fmul": "fmul", + "fdiv": "fdiv", } cmp_ops = { @@ -92,6 +98,15 @@ def gen_instructions(self, instrs): "neq": "!=", } + fcmp_ops = { + "feq": "==", + "flt": "<", + "fgt": ">", + "fle": "<=", + "fge": ">=", + "fneq": "!=", + } + def gen_label(instr): old_bb = self.builder.block new_bb = self.gen_label(instr.label) @@ -149,6 +164,18 @@ def gen_value(instr): llvm_instr(*[self.gen_var(arg) for arg in instr.args], name=instr.dest), ) + def gen_fcomp(instr): + self.declare_var(self.gen_type(instr.type), instr.dest) + self.gen_symbol_store( + instr.dest, + self.builder.fcmp_ordered( + cmpop=fcmp_ops[instr.op], + lhs=self.gen_var(instr.args[0]), + rhs=self.gen_var(instr.args[1]), + name=instr.dest, + ), + ) + def gen_comp(instr): self.declare_var(self.gen_type(instr.type), instr.dest) self.gen_symbol_store( @@ -226,6 +253,8 @@ def gen_id(instr): gen_value(instr) elif instr.op in cmp_ops: gen_comp(instr) + elif instr.op in fcmp_ops: + gen_fcomp(instr) else: raise CodegenError(f"Unknown op in the instruction: {dict(instr)}") except Exception as e: diff --git a/src/backend/runtime.c b/src/backend/runtime.c index e9dffd1..0dad445 100644 --- a/src/backend/runtime.c +++ b/src/backend/runtime.c @@ -4,3 +4,8 @@ int print(int x){ printf("%d\n", x); return x; } + +double fprint(double x) { + printf("%.17f\n", x); + return x; +} diff --git a/src/backend/tests/brilisp/float.out b/src/backend/tests/brilisp/float.out new file mode 100644 index 0000000..31ca8e8 --- /dev/null +++ b/src/backend/tests/brilisp/float.out @@ -0,0 +1,3 @@ +-0.45000000000000001 +0.30000000000000004 +0.30000000000000004 diff --git a/src/backend/tests/brilisp/float.sexp b/src/backend/tests/brilisp/float.sexp new file mode 100644 index 0000000..197cd93 --- /dev/null +++ b/src/backend/tests/brilisp/float.sexp @@ -0,0 +1,20 @@ +(brilisp + (bril-define ((fprint float) (n float))) + + (bril-define ((main void)) + (set (v0 float) (const 9.0)) + (set (v1 float) (const -20.0)) + (set (res float) (fdiv v0 v1)) + (set (tmp float) (call fprint res)) + + (set (v2 float) (const .1)) + (set (v3 float) (const 0.1)) + (set (add1 float) (fadd v2 v3)) + (set (dres float) (fadd add1 v2)) + (set (tmp float) (call fprint dres)) + + (set (v4 float) (const .1)) + (set (add2 float) (fadd v4 v4)) + (set (fres float) (fadd add2 v4)) + (set (tmp float) (call fprint fres)) + (ret))) From 1a99b9885dcf2c425ce33aa234a5680248ac39a1 Mon Sep 17 00:00:00 2001 From: Vedanth Padmaraman Date: Tue, 4 Jun 2024 17:44:06 +0530 Subject: [PATCH 2/7] Add comparison operations --- src/backend/brilisp.scm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/brilisp.scm b/src/backend/brilisp.scm index 001f8ed..ca66ce7 100644 --- a/src/backend/brilisp.scm +++ b/src/backend/brilisp.scm @@ -62,7 +62,7 @@ (define (value? instr) (and (eq? (first instr) 'set) (memq (first (third instr)) - '(add mul sub div eq lt gt le ge not and or alloc load ptradd id fadd fsub fmul fdiv)))) + '(add mul sub div eq lt gt le ge not and or alloc load ptradd id fadd fsub fmul fdiv feq flt fgt fle fge)))) (define (gen-value-instr instr) (let ((to (second instr)) From 8d04004cbe14a33f6326e7a73b705e81a0f69af5 Mon Sep 17 00:00:00 2001 From: Vedanth Padmaraman Date: Wed, 5 Jun 2024 10:15:17 +0530 Subject: [PATCH 3/7] Add tests: `float_zero_cmp` and `float_divide_by_zero` --- .../tests/brilisp/float_divide_by_zero.out | 3 +++ .../tests/brilisp/float_divide_by_zero.sexp | 14 ++++++++++++++ src/backend/tests/brilisp/float_zero_cmp.out | 1 + src/backend/tests/brilisp/float_zero_cmp.sexp | 17 +++++++++++++++++ 4 files changed, 35 insertions(+) create mode 100644 src/backend/tests/brilisp/float_divide_by_zero.out create mode 100644 src/backend/tests/brilisp/float_divide_by_zero.sexp create mode 100644 src/backend/tests/brilisp/float_zero_cmp.out create mode 100644 src/backend/tests/brilisp/float_zero_cmp.sexp diff --git a/src/backend/tests/brilisp/float_divide_by_zero.out b/src/backend/tests/brilisp/float_divide_by_zero.out new file mode 100644 index 0000000..d0ea4fa --- /dev/null +++ b/src/backend/tests/brilisp/float_divide_by_zero.out @@ -0,0 +1,3 @@ +-inf +inf +nan diff --git a/src/backend/tests/brilisp/float_divide_by_zero.sexp b/src/backend/tests/brilisp/float_divide_by_zero.sexp new file mode 100644 index 0000000..6ee18bc --- /dev/null +++ b/src/backend/tests/brilisp/float_divide_by_zero.sexp @@ -0,0 +1,14 @@ +(brilisp + (bril-define ((fprint float) (n float))) + + (bril-define ((main void)) + (set (v0 float) (const -1.0)) + (set (v1 float) (const 1.0)) + (set (zero float) (const 0.0)) + (set (res float) (fdiv v0 zero)) + (set (tmp float) (call fprint res)) + (set (res float) (fdiv v1 zero)) + (set (tmp float) (call fprint res)) + (set (res float) (fdiv zero zero)) + (set (tmp float) (call fprint res)) + (ret))) diff --git a/src/backend/tests/brilisp/float_zero_cmp.out b/src/backend/tests/brilisp/float_zero_cmp.out new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/src/backend/tests/brilisp/float_zero_cmp.out @@ -0,0 +1 @@ +1 diff --git a/src/backend/tests/brilisp/float_zero_cmp.sexp b/src/backend/tests/brilisp/float_zero_cmp.sexp new file mode 100644 index 0000000..d21d8d4 --- /dev/null +++ b/src/backend/tests/brilisp/float_zero_cmp.sexp @@ -0,0 +1,17 @@ +(brilisp + (bril-define ((print int) (n int))) + + (bril-define ((main void)) + (set (v0 float) (const 0.0)) + (set (v1 float) (const -0.0)) + (set (res bool) (feq v0 v1)) + (br res l_true l_false) + + (label l_true) + (set (out int) (const 1)) + (jmp out) + (label l_false) + (set (out int) (const 0)) + (label out) + (set (tmp int) (call print out)) + (ret))) From 96d683e7e013e8cf336f5a7289277dd32677024d Mon Sep 17 00:00:00 2001 From: Vedanth Padmaraman Date: Wed, 5 Jun 2024 11:02:33 +0530 Subject: [PATCH 4/7] Add tes: `float_nan_detect` --- src/backend/tests/brilisp/float_nan_detect.out | 1 + src/backend/tests/brilisp/float_nan_detect.sexp | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 src/backend/tests/brilisp/float_nan_detect.out create mode 100644 src/backend/tests/brilisp/float_nan_detect.sexp diff --git a/src/backend/tests/brilisp/float_nan_detect.out b/src/backend/tests/brilisp/float_nan_detect.out new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/src/backend/tests/brilisp/float_nan_detect.out @@ -0,0 +1 @@ +1 diff --git a/src/backend/tests/brilisp/float_nan_detect.sexp b/src/backend/tests/brilisp/float_nan_detect.sexp new file mode 100644 index 0000000..1cee9ed --- /dev/null +++ b/src/backend/tests/brilisp/float_nan_detect.sexp @@ -0,0 +1,10 @@ +(brilisp + (bril-define ((print bool) (b bool))) + + (bril-define ((main void)) + (set (zero float) (const 0.0)) + (set (nan float) (fdiv zero zero)) + (set (res bool) (feq nan nan)) + (set (res bool) (not res)) + (set (tmp bool) (call print res)) + (ret))) From d854b127e22d4b92d1dd23647daac84957699fe7 Mon Sep 17 00:00:00 2001 From: Vedanth Padmaraman Date: Wed, 5 Jun 2024 11:43:58 +0530 Subject: [PATCH 5/7] Add tests for comparisons + non-equality instructios --- src/backend/brilisp.scm | 2 +- src/backend/llvm.py | 4 ++-- src/backend/tests/brilisp/float_compare.out | 6 +++++ src/backend/tests/brilisp/float_compare.sexp | 25 ++++++++++++++++++++ src/backend/tests/brilisp/int_compare.out | 6 +++++ src/backend/tests/brilisp/int_compare.sexp | 25 ++++++++++++++++++++ 6 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 src/backend/tests/brilisp/float_compare.out create mode 100644 src/backend/tests/brilisp/float_compare.sexp create mode 100644 src/backend/tests/brilisp/int_compare.out create mode 100644 src/backend/tests/brilisp/int_compare.sexp diff --git a/src/backend/brilisp.scm b/src/backend/brilisp.scm index ca66ce7..3ff8707 100644 --- a/src/backend/brilisp.scm +++ b/src/backend/brilisp.scm @@ -62,7 +62,7 @@ (define (value? instr) (and (eq? (first instr) 'set) (memq (first (third instr)) - '(add mul sub div eq lt gt le ge not and or alloc load ptradd id fadd fsub fmul fdiv feq flt fgt fle fge)))) + '(add mul sub div eq ne lt gt le ge not and or alloc load ptradd id fadd fsub fmul fdiv feq fne flt fgt fle fge)))) (define (gen-value-instr instr) (let ((to (second instr)) diff --git a/src/backend/llvm.py b/src/backend/llvm.py index 6a3b2e5..a63a960 100644 --- a/src/backend/llvm.py +++ b/src/backend/llvm.py @@ -95,7 +95,7 @@ def gen_instructions(self, instrs): "gt": ">", "le": "<=", "ge": ">=", - "neq": "!=", + "ne": "!=", } fcmp_ops = { @@ -104,7 +104,7 @@ def gen_instructions(self, instrs): "fgt": ">", "fle": "<=", "fge": ">=", - "fneq": "!=", + "fne": "!=", } def gen_label(instr): diff --git a/src/backend/tests/brilisp/float_compare.out b/src/backend/tests/brilisp/float_compare.out new file mode 100644 index 0000000..1a2946b --- /dev/null +++ b/src/backend/tests/brilisp/float_compare.out @@ -0,0 +1,6 @@ +0 +1 +0 +1 +0 +1 diff --git a/src/backend/tests/brilisp/float_compare.sexp b/src/backend/tests/brilisp/float_compare.sexp new file mode 100644 index 0000000..799dc20 --- /dev/null +++ b/src/backend/tests/brilisp/float_compare.sexp @@ -0,0 +1,25 @@ +(brilisp + (bril-define ((print bool) (b bool))) + + (bril-define ((main void)) + (set (v1 float) (const 50.0)) + (set (v2 float) (const 50.1)) + + (set (res bool) (feq v1 v2)) + (set (tmp bool) (call print res)) + + (set (res bool) (fne v1 v2)) + (set (tmp bool) (call print res)) + + (set (res bool) (fge v1 v2)) + (set (tmp bool) (call print res)) + + (set (res bool) (fle v1 v2)) + (set (tmp bool) (call print res)) + + (set (res bool) (fgt v1 v2)) + (set (tmp bool) (call print res)) + + (set (res bool) (flt v1 v2)) + (set (tmp bool) (call print res)) + (ret))) diff --git a/src/backend/tests/brilisp/int_compare.out b/src/backend/tests/brilisp/int_compare.out new file mode 100644 index 0000000..1a2946b --- /dev/null +++ b/src/backend/tests/brilisp/int_compare.out @@ -0,0 +1,6 @@ +0 +1 +0 +1 +0 +1 diff --git a/src/backend/tests/brilisp/int_compare.sexp b/src/backend/tests/brilisp/int_compare.sexp new file mode 100644 index 0000000..ce460a0 --- /dev/null +++ b/src/backend/tests/brilisp/int_compare.sexp @@ -0,0 +1,25 @@ +(brilisp + (bril-define ((print bool) (b bool))) + + (bril-define ((main void)) + (set (v1 int) (const 50)) + (set (v2 int) (const 51)) + + (set (res bool) (eq v1 v2)) + (set (tmp bool) (call print res)) + + (set (res bool) (ne v1 v2)) + (set (tmp bool) (call print res)) + + (set (res bool) (ge v1 v2)) + (set (tmp bool) (call print res)) + + (set (res bool) (le v1 v2)) + (set (tmp bool) (call print res)) + + (set (res bool) (gt v1 v2)) + (set (tmp bool) (call print res)) + + (set (res bool) (lt v1 v2)) + (set (tmp bool) (call print res)) + (ret))) From a6b822ff20a854fa701fd0d719cbb8a3e68922eb Mon Sep 17 00:00:00 2001 From: Vedanth Padmaraman Date: Wed, 5 Jun 2024 12:02:37 +0530 Subject: [PATCH 6/7] Use 32-bit floating point --- src/backend/llvm.py | 2 +- src/backend/runtime.c | 4 ++-- src/backend/tests/brilisp/float.out | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/backend/llvm.py b/src/backend/llvm.py index a63a960..ecccd97 100644 --- a/src/backend/llvm.py +++ b/src/backend/llvm.py @@ -57,7 +57,7 @@ def gen_type(self, type): elif type == "bool": return ir.IntType(1) elif type == "float": - return ir.DoubleType() + return ir.FloatType() else: raise CodegenError(f"Unknown type {type}") diff --git a/src/backend/runtime.c b/src/backend/runtime.c index 0dad445..fad045b 100644 --- a/src/backend/runtime.c +++ b/src/backend/runtime.c @@ -5,7 +5,7 @@ int print(int x){ return x; } -double fprint(double x) { - printf("%.17f\n", x); +float fprint(float x) { + printf("%f\n", x); return x; } diff --git a/src/backend/tests/brilisp/float.out b/src/backend/tests/brilisp/float.out index 31ca8e8..257d2ad 100644 --- a/src/backend/tests/brilisp/float.out +++ b/src/backend/tests/brilisp/float.out @@ -1,3 +1,3 @@ --0.45000000000000001 -0.30000000000000004 -0.30000000000000004 +-0.450000 +0.300000 +0.300000 From 05ab16fd9ec81170d1f6cccc93d527807cd6e89a Mon Sep 17 00:00:00 2001 From: Vedanth Padmaraman Date: Wed, 5 Jun 2024 15:24:56 +0530 Subject: [PATCH 7/7] Move runtime.c and run.sh to tests folder --- src/backend/{ => tests/brilisp}/run.sh | 0 src/backend/{ => tests/brilisp}/runtime.c | 0 src/backend/tests/brilisp/turnt.toml | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) rename src/backend/{ => tests/brilisp}/run.sh (100%) rename src/backend/{ => tests/brilisp}/runtime.c (100%) diff --git a/src/backend/run.sh b/src/backend/tests/brilisp/run.sh similarity index 100% rename from src/backend/run.sh rename to src/backend/tests/brilisp/run.sh diff --git a/src/backend/runtime.c b/src/backend/tests/brilisp/runtime.c similarity index 100% rename from src/backend/runtime.c rename to src/backend/tests/brilisp/runtime.c diff --git a/src/backend/tests/brilisp/turnt.toml b/src/backend/tests/brilisp/turnt.toml index cd5e746..fa84802 100644 --- a/src/backend/tests/brilisp/turnt.toml +++ b/src/backend/tests/brilisp/turnt.toml @@ -1 +1 @@ -command = "guile ../../brilisp.scm < {filename} | python ../../llvm.py | bash ../../run.sh " +command = "guile ../../brilisp.scm < {filename} | python ../../llvm.py | bash run.sh "