aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-11-03 15:08:48 +0100
committerBad Diode <bd@badd10de.dev>2021-11-03 15:08:48 +0100
commit9c8022b286993ea4123211005878681bd207fa0c (patch)
tree1f9952a927b152c0e47b2e415b36a2efa6a0dcaa
parent889e34d0ca986f03de77dfa383c12f4980e746ee (diff)
downloadbdl-9c8022b286993ea4123211005878681bd207fa0c.tar.gz
bdl-9c8022b286993ea4123211005878681bd207fa0c.zip
Fix behaviour of numerical comparisons
-rw-r--r--src/compiler.h48
1 files changed, 19 insertions, 29 deletions
diff --git a/src/compiler.h b/src/compiler.h
index e511b7c..ff2c6e0 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -189,13 +189,8 @@ void
189compile_cmp_list(OpType op, Object* args) { 189compile_cmp_list(OpType op, Object* args) {
190 printf(" ;; --> compile_cmp_list\n"); 190 printf(" ;; --> compile_cmp_list\n");
191 compile_object(args->head); 191 compile_object(args->head);
192 192 char *lab_false = generate_label();
193 // TODO: Make sure to stop evaluating if the condition is not met. 193 char *lab_exit = generate_label();
194 // FIXME: Only working for two argument lists right now because we can't
195 // accumulate the bool and compare it with an int. We can fix it by passing
196 // two values on the stack (previous value and current result) or by only
197 // passing a previous value and having a conditional jump (need labels for
198 // that).
199 args = args->tail; 194 args = args->tail;
200 while (args != NULL) { 195 while (args != NULL) {
201 compile_object(args->head); 196 compile_object(args->head);
@@ -203,37 +198,32 @@ compile_cmp_list(OpType op, Object* args) {
203 198
204 // Current value. 199 // Current value.
205 printf(" pop rcx\n"); 200 printf(" pop rcx\n");
206 printf(" sar rcx, %d\n", FIXNUM_SHIFT);
207 201
208 // Previous value. 202 // Previous value.
209 printf(" pop rax\n"); 203 printf(" pop rax\n");
210 printf(" sar rax, %d\n", FIXNUM_SHIFT);
211 204
205 // Comparison.
212 printf(" cmp rax, rcx\n"); 206 printf(" cmp rax, rcx\n");
213 printf(" mov rax, 0\n");
214
215 switch (op) { 207 switch (op) {
216 case OP_EQUAL: { 208 case OP_EQUAL: { printf(" jne %s\n", lab_false); } break;
217 printf(" sete al\n"); 209 case OP_GREATER: { printf(" jle %s\n", lab_false); } break;
218 } break; 210 case OP_LESS: { printf(" jge %s\n", lab_false); } break;
219 case OP_GREATER: { 211 case OP_GREATER_EQ: { printf(" jl %s\n", lab_false); } break;
220 printf(" setg al\n"); 212 case OP_LESS_EQ: { printf(" jg %s\n", lab_false); } break;
221 } break;
222 case OP_LESS: {
223 printf(" setl al\n");
224 } break;
225 case OP_GREATER_EQ: {
226 printf(" setge al\n");
227 } break;
228 case OP_LESS_EQ: {
229 printf(" setle al\n");
230 } break;
231 default: break; 213 default: break;
232 } 214 }
233 printf(" shl rax, %d\n", BOOL_SHIFT); 215 printf(" push rcx\n");
234 printf(" or rax, %d\n", BOOL_TAG);
235 printf(" push rax\n");
236 } 216 }
217 printf(" pop rcx\n");
218 printf(" mov rax, %d\n", TRUE_VAL);
219 printf(" push rax\n");
220 printf(" jmp %s\n", lab_exit);
221 printf("%s:\n", lab_false);
222 printf(" mov rax, %d\n", FALSE_VAL);
223 printf(" push rax\n");
224 printf("%s:\n", lab_exit);
225 free(lab_false);
226 free(lab_exit);
237 printf(" ;; <-- compile_cmp_list\n"); 227 printf(" ;; <-- compile_cmp_list\n");
238} 228}
239 229