Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 140 additions & 32 deletions compiler/template.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,7 @@ plus:
mov rbx, rsi
GET_TAG_BITS rbx ; type of arg
GET_TAG_BITS rax ; type of arg
add rax, rbx
; cmp rax, 0 ; both integerss?
add rax, rbx ; both integers? == 0
jz plus_integer

; Okay the values are either:
Expand All @@ -298,7 +297,7 @@ plus:
.arg_one_float:
UNTAG_REG rdi ; get the float-ptr
movq xmm0, [rdi] ; load
jmp .arg_two
; jmp .arg_two ; fall through

.arg_two:
mov rcx, rsi
Expand All @@ -323,7 +322,7 @@ plus:
addsd xmm0, xmm1 ; add
mov rax, [heap_ptr] ; allocate
add qword [heap_ptr],8
movq [rax], xmm0 ; store
movq [rax], xmm0 ; store
TAG_FLOAT_REG rax ; type
ret ; return

Expand Down Expand Up @@ -369,7 +368,7 @@ minus:
.arg_one_float:
UNTAG_REG rdi ; get the float-ptr
movq xmm0, [rdi] ; load
jmp .arg_two
; jmp .arg_two ; fall through

.arg_two:
mov rcx, rsi
Expand Down Expand Up @@ -442,7 +441,7 @@ divide:
.arg_one_float:
UNTAG_REG rdi ; get the float-ptr
movq xmm0, [rdi] ; load
jmp .arg_two
; jmp .arg_two ; fall-through

.arg_two:
mov rcx, rsi
Expand Down Expand Up @@ -542,7 +541,7 @@ multiply:
.arg_one_float:
UNTAG_REG rdi ; get the float-ptr
movq xmm0, [rdi] ; load
jmp .arg_two
; jmp .arg_two

.arg_two:
mov rcx, rsi
Expand Down Expand Up @@ -636,12 +635,75 @@ equals:

section .text.lte,"ax",@progbits

;; <=

;; <= - Work with either integers, floats, or both.
;;
;; Note: The result of this function is inverted for ">".
;;
lt_equals:
mov rax, rdi
mov rbx, rsi
GET_TAG_BITS rbx ; type of arg
GET_TAG_BITS rax ; type of arg
add rax, rbx ; both integers? == 0
jz lte_integer


; Okay the values are either:
; float + float
; float + int
; int + float
;
; We have to test each argument and work it out.
; the end result of our addition will be a float.
mov rcx, rdi
GET_TAG_BITS rcx
cmp rcx, TAG_ID_FLOAT
jz .arg_one_float
cmp rcx, TAG_ID_INTEGER
jz .arg_one_int
jmp type_error

.arg_one_int:
UNTAG_REG rdi ; get the int
cvtsi2sd xmm0, rdi ; convert to float
jmp .arg_two

.arg_one_float:
UNTAG_REG rdi ; get the float-ptr
movq xmm0, [rdi] ; load
; jmp .arg_two ; fall through

.arg_two:
mov rcx, rsi
GET_TAG_BITS rcx
cmp rcx, TAG_ID_FLOAT
jz .arg_two_float
cmp rcx, TAG_ID_INTEGER
jz .arg_two_int
jmp type_error

.arg_two_int:
UNTAG_REG rsi ; get the int
cvtsi2sd xmm1, rsi ; convert to float
jmp .got_args_lte

.arg_two_float:
UNTAG_REG rsi ; get the float-ptr
movq xmm1, [rsi] ; load
; jmp .got_args_lte ; fall-through

.got_args_lte:
ucomisd xmm0, xmm1
jbe lte_integer.true
jmp lte_integer.false

lte_integer:
UNTAG_REG rdi
UNTAG_REG rsi
cmp rdi, rsi
jle .true
.false:
xor rax, rax
TAG_NIL_REG rax
ret
Expand All @@ -654,10 +716,68 @@ section .text.gte,"ax",@progbits

;; >=
gt_equals:
mov rax, rdi
mov rbx, rsi
GET_TAG_BITS rbx ; type of arg
GET_TAG_BITS rax ; type of arg
add rax, rbx ; both integers? == 0
jz gte_integer

; Okay the values are either:
; float + float
; float + int
; int + float
;
; We have to test each argument and work it out.
; the end result of our addition will be a float.
mov rcx, rdi
GET_TAG_BITS rcx
cmp rcx, TAG_ID_FLOAT
jz .arg_one_float
cmp rcx, TAG_ID_INTEGER
jz .arg_one_int
jmp type_error

.arg_one_int:
UNTAG_REG rdi ; get the int
cvtsi2sd xmm0, rdi ; convert to float
jmp .arg_two

.arg_one_float:
UNTAG_REG rdi ; get the float-ptr
movq xmm0, [rdi] ; load
; jmp .arg_two ; fall through

.arg_two:
mov rcx, rsi
GET_TAG_BITS rcx
cmp rcx, TAG_ID_FLOAT
jz .arg_two_float
cmp rcx, TAG_ID_INTEGER
jz .arg_two_int
jmp type_error

.arg_two_int:
UNTAG_REG rsi ; get the int
cvtsi2sd xmm1, rsi ; convert to float
jmp .got_args_gte

.arg_two_float:
UNTAG_REG rsi ; get the float-ptr
movq xmm1, [rsi] ; load
; jmp .got_args_gte ; fall-through

.got_args_gte:
ucomisd xmm0, xmm1
jb gte_integer.false
jmp gte_integer.true

gte_integer:
UNTAG_REG rdi
UNTAG_REG rsi
cmp rdi, rsi
jge .true
.false:
xor rax, rax
TAG_NIL_REG rax
ret
Expand All @@ -666,40 +786,27 @@ gt_equals:
TAG_INTEGER_REG rax
ret


section .text.lt,"ax",@progbits

;; <

;; < - this is the inverse of >=
lt:
UNTAG_REG rdi
UNTAG_REG rsi
cmp rdi, rsi
jl .true
xor rax, rax
TAG_NIL_REG rax
ret
.true:
mov rax, 1
TAG_INTEGER_REG rax
call gt_equals
mov rdi, rax
call fn_not
ret


section .text.gt,"ax",@progbits

;; >
;; > - this is the inverse of <=
gt:
UNTAG_REG rdi
UNTAG_REG rsi
cmp rdi, rsi
jg .true
xor rax, rax
TAG_NIL_REG rax
ret
.true:
mov rax, 1
TAG_INTEGER_REG rax
call lt_equals
mov rdi, rax
call fn_not
ret



section .text.printfloat,"ax",@progbits

;; Print a float
Expand Down Expand Up @@ -1011,6 +1118,7 @@ type_error:
mov rdi, type_error_msg
TAG_STRING_REG rdi
call fn_printstr
mov rdi, 1 ; exit-code
jmp fn_exit

section .data
Expand Down
20 changes: 20 additions & 0 deletions test/compare.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@
(print (>= 34 4))
(newline)

; floats
(print "(>= 33.3 4):")
(print (>= 33.3 4))
(print " (>= 4 6.5):")
(print (>= 4 6.5))
(print " (>= 3.25 3.0):")
(print (>= 3.25 3.0))
(newline)

(print "(<= 3 4):")
(print (<= 3 4))
(print " (<= 4 4):")
Expand All @@ -29,6 +38,17 @@
(print (<= 34 4))
(newline)

; floats
(print "(<= 33.3 4):")
(print (<= 33.3 4))
(print "(<= 3.75 4):")
(print (<= 3.75 4))
(print " (<= 4.5 6.5):")
(print (<= 4.5 6.5))
(print " (<= 3.25 3.0):")
(print (<= 3.25 3.0))
(newline)

(print "(= 3 3): ")
(print (= 3 3))
(print " (= 3 4): ")
Expand Down
2 changes: 2 additions & 0 deletions test/compare.test.expected
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
(< 3 4):1 (< 4 4):<nil>
(> 3 4):<nil> (> 34 4):1
(>= 3 4):<nil> (>= 4 4):1 (>= 34 4):1
(>= 33.3 4):1 (>= 4 6.5):<nil> (>= 3.25 3.0):1
(<= 3 4):1 (<= 4 4):1 (<= 34 4):<nil>
(<= 33.3 4):<nil>(<= 3.75 4):1 (<= 4.5 6.5):1 (<= 3.25 3.0):<nil>
(= 3 3): 1 (= 3 4): <nil>
(= a a): 1 (= a b): <nil>
Loading