Fixed pointer arithmatic
This commit is contained in:
@@ -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
|
||||
} 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))
|
||||
|
||||
Reference in New Issue
Block a user