From 3f20646b1678740d4fee863434d12434640e260f Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sat, 17 Mar 2018 12:47:01 -0400 Subject: [PATCH] Fixed pointer arithmatic --- stdlib/bytecode_generator.krak | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/stdlib/bytecode_generator.krak b/stdlib/bytecode_generator.krak index ef7e991..9c60cd1 100644 --- a/stdlib/bytecode_generator.krak +++ b/stdlib/bytecode_generator.krak @@ -590,30 +590,46 @@ obj bytecode_generator (Object) { } var params = parameter_nodes.map(fun(n: *ast_node): int return generate(n);) + var lhs_type = get_ast_type(parameter_nodes[0]) if (name == "+") { - if (params.size == 1) + if (params.size == 1) { return emit_smul(params[0], emit_or(emit_gz(params[0]), emit_smul(emit_lz(params[0]), emit_imm(-1)))) - else - return emit_add(params[0], params[1]) + } else { + if (lhs_type->indirection == 0) { + return emit_add(params[0], params[1]) + } else { + return emit_add(params[0], emit_smul(params[1], emit_imm(type_size(lhs_type->clone_with_decreased_indirection())))) + } + } } else if (name == "-") { - if (params.size == 1) + if (params.size == 1) { return emit_addi(emit_not(params[0]), 1) - else - return emit_add(params[0], emit_addi(emit_not(params[1]), 1)) + } else { + if (lhs_type->indirection == 0) { + return emit_add(params[0], params[1]) + } else { + return emit_add(params[0], emit_addi(emit_not(emit_smul(params[1], emit_imm(type_size(lhs_type->clone_with_decreased_indirection())))), 1)) + } + } } else if (name == "!") { return emit_ez(params[0]) } else if (name == "[]" || (name == "*" && params.size == 1)) { + var derefed_size = type_size(lhs_type->clone_with_decreased_indirection()) if (name == "[]") { + var offset_reg = params[1] + if (derefed_size != 1) + offset_reg = emit_smul(offset_reg, emit_imm(derefed_size)) + var addr_reg = emit_add(params[0], offset_reg) if (lvalue) - return emit_add(params[0], params[1]) + return addr_reg else - return emit_ldr(emit_add(params[0], params[1]), 0, size_to_operand_size(type_size(get_ast_type(parameter_nodes[0])->clone_with_decreased_indirection()))) + return emit_ldr(addr_reg, 0, size_to_operand_size(derefed_size)) } if (name == "*") { if (lvalue) return params[0] else - return emit_ldr(params[0], 0, size_to_operand_size(type_size(get_ast_type(parameter_nodes[0])->clone_with_decreased_indirection()))) + return emit_ldr(params[0], 0, size_to_operand_size(derefed_size)) } } else if (name == "==" || name == "<=" || name == ">=" || name == "!=" || name == "<" || name == ">") { var diff = emit_add(params[0], emit_addi(emit_not(params[1]), 1))