Skip to content

Commit

Permalink
Fixed minor systemv instruction sel bugs.
Browse files Browse the repository at this point in the history
  • Loading branch information
Goubermouche committed Feb 1, 2024
1 parent e3b43e9 commit 35a1335
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 37 deletions.
1 change: 1 addition & 0 deletions source/compiler/compiler/type_system/semantic_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ namespace sigma {

static u64 counter = 0;
return "f" + std::to_string(counter++);
//return string_table.get(signature.identifier_key);
}

auto calculate_parameter_cast_cost(const function_signature& signature, const std::vector<data_type>& parameter_types) -> u16 {
Expand Down
14 changes: 9 additions & 5 deletions source/compiler/test/main.s
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@
// - set crashes with more than 4(?) parameters
// - implicit returns for non-void functions should be a thing

i32 main() {
u64 a = 100;

printf("value: %lld\n", a);
ret 0;
i32 run(i32 x) {
ret x;
}

i32 test() {
ret 12;
}

i32 main() {
printf("%d\n", run(test()));
ret 0;
}

// THIS CRASHES
// i32 main() {
Expand Down
4 changes: 3 additions & 1 deletion source/intermediate_representation/codegen/instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,9 @@ namespace sigma::ir {

// memory op
INDEXED = 1024,
SPILL = 2048
SPILL = 2048,

RET = 4096
};

struct description {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ namespace sigma::ir {
// add the register to the active set
if (reg.is_valid()) {
interval->assigned = reg;

move_to_active(context, interval);
}
}
Expand Down Expand Up @@ -468,7 +469,10 @@ namespace sigma::ir {
}

it.reg = classified_reg();

it.assigned = reg();
ASSERT(it.assigned != 1, "x");

it.ranges.reserve(4);
it.uses.clear();
it.target = nullptr;
Expand Down Expand Up @@ -580,9 +584,7 @@ namespace sigma::ir {
return new_reg;
}

reg linear_scan_allocator::allocate_free_reg(
codegen_context& context, handle<live_interval> interval
) {
reg linear_scan_allocator::allocate_free_reg(codegen_context& context, handle<live_interval> interval) {
const auto register_class = interval->reg.cl;
constexpr i32 half_free = 1 << 16;

Expand Down Expand Up @@ -677,6 +679,7 @@ namespace sigma::ir {
}

interval = &context.intervals[old_reg];
ASSERT(interval->assigned != 1, "x");
}

if(static_cast<ptr_diff>(interval->get_end()) > free_position) {
Expand Down
6 changes: 3 additions & 3 deletions source/intermediate_representation/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace sigma::ir {
// specify individual optimization passes
const optimization_pass_list optimizations({});
const auto register_allocator = std::make_shared<linear_scan_allocator>();
// utility::string assembly;
//utility::string assembly;

// go through all declared functions and run codegen
for (const handle<function> function : m_functions) {
Expand Down Expand Up @@ -76,7 +76,7 @@ namespace sigma::ir {
// std::cout << '\n';

// DEBUG
// assembly.append(m_codegen.disassemble(bytecode, codegen));
//assembly.append(m_codegen.disassemble(bytecode, codegen));

// finally, emit the compiled function
function->output = {
Expand All @@ -91,7 +91,7 @@ namespace sigma::ir {
}

// DEBUG
// utility::console::print("{}\n", assembly.get_underlying());
//utility::console::print("{}\n", assembly.get_underlying());
}

auto module::generate_object_file() -> utility::byte_buffer {
Expand Down
20 changes: 9 additions & 11 deletions source/intermediate_representation/target/arch/x64/x64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ namespace sigma::ir {
// generate the bytecode for our function
emit_function_prologue(context, bytecode);
emit_function_body(context, bytecode);
emit_function_epilogue(context, bytecode);

// pad the instruction buffer to 16 bytes with nop instructions
emit_nops_to_width(bytecode);
Expand Down Expand Up @@ -186,7 +185,13 @@ namespace sigma::ir {
else if (inst == instruction::type::INLINE) {
NOT_IMPLEMENTED();
}
else if (inst == instruction::type::EPILOGUE) { /*does nothing*/ }
else if (inst == instruction::type::EPILOGUE) {
emit_function_epilogue(context, bytecode);

if(inst->flags & instruction::RET) {
bytecode.append_byte(0xC3);
}
}
else if (inst == instruction::type::LINE) {
NOT_IMPLEMENTED();
}
Expand Down Expand Up @@ -327,7 +332,7 @@ namespace sigma::ir {
}
else if(ternary) {
const handle<instruction_operand> right = context.create_instruction_operand();
resolve_interval(context, inst, resolved_operand_count, right);
resolved_operand_count += resolve_interval(context, inst, resolved_operand_count, right);

if(inst != instruction::type::MOV || (inst == instruction::type::MOV && out->matches(right) == false)) {
emit_instruction_2(context, inst->get_type(), out, right, dt, bytecode);
Expand All @@ -341,7 +346,6 @@ namespace sigma::ir {
ASSERT(context.function->exit_node != nullptr, "no exit node found");

if (context.stack_usage <= 16) {
bytecode.append_byte(0xC3);
return;
}

Expand All @@ -361,13 +365,6 @@ namespace sigma::ir {

// pop RBP
bytecode.append_byte(0x58 + x64::gpr::RBP);

// ret
const handle<node> remote_procedure_call = context.function->exit_node->inputs[2];

if (remote_procedure_call == node::type::PROJECTION && remote_procedure_call->inputs[0] == node::type::ENTRY && remote_procedure_call->get<projection>().index == 2) {
bytecode.append_byte(0xC3);
}
}

auto x64_architecture::get_instruction_table()->std::array<instruction::description, 120> {
Expand Down Expand Up @@ -870,6 +867,7 @@ namespace sigma::ir {
if(interval->spill > 0) {
val->set_type(instruction_operand::type::MEM);
val->reg = static_cast<u8>(x64::gpr::RBP);

val->index = reg::invalid_id;
val->immediate = -interval->spill;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#include "x64.h"
#include "abstract_syntax_tree/node.h"
#include "intermediate_representation/codegen/instruction.h"
#include "intermediate_representation/codegen/instruction.h"
#include "intermediate_representation/codegen/instruction.h"
#include "intermediate_representation/codegen/instruction.h"

#include "intermediate_representation/target/system/systemv/systemv.h"
#include "intermediate_representation/target/system/win/win.h"

namespace sigma::ir {
Expand Down Expand Up @@ -264,9 +263,7 @@ namespace sigma::ir {
case node::type::REGION: break;
case node::type::ENTRY: {
bool is_systemv = context.target.get_abi() == abi::SYSTEMV;
constexpr x64::gpr gpr_params[] = {
x64::gpr::RCX, x64::gpr::RDX, x64::gpr::R8, x64::gpr::R9
};
const x64::gpr* gpr_params = is_systemv ? systemv::g_parameters : win::g_parameters;

u8 gpr_param_count = 4;
u8 xmm_param_count = is_systemv ? 8 : 4;
Expand Down Expand Up @@ -918,9 +915,14 @@ namespace sigma::ir {
// we don't really need a fence if we're about to exit but we do need to mark that
// it's the epilogue to tell the register allocator where callee registers need
// to get restored
context.append_instruction(create_instruction(
context, instruction::type::EPILOGUE, VOID_TYPE, 0, 0, 0)
);
handle<instruction> inst = create_instruction(
context, instruction::type::EPILOGUE, VOID_TYPE, 0, 0, 0);

inst->flags |= instruction::RET;

context.append_instruction(inst);


break;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,13 @@ namespace sigma::ir::systemv {
static_cast<u8>(x64::gpr::R9)
}
};

static constexpr x64::gpr g_parameters[] = {
x64::gpr::RDI,
x64::gpr::RSI,
x64::gpr::RDX,
x64::gpr::RCX,
x64::gpr::R8,
x64::gpr::R9
};
}
7 changes: 7 additions & 0 deletions source/intermediate_representation/target/system/win/win.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,11 @@ namespace sigma::ir::win {
reg::invalid_id
}
};

static constexpr x64::gpr g_parameters[] = {
x64::gpr::RCX,
x64::gpr::RDX,
x64::gpr::R8,
x64::gpr::R9
};
}
10 changes: 5 additions & 5 deletions source/utility/containers/byte_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace utility {
* \param data Data to append
*/
void append_byte(u8 data) {
// ASSERT(data != 0xc7, "x");
// ASSERT(data != 0x4d, "x");
push_back(data);
}

Expand All @@ -52,8 +52,8 @@ namespace utility {
void append_word(u16 data) {
byte bytes[2];
std::memcpy(bytes, &data, sizeof(data));
// ASSERT(bytes[0] != 0xc7, "x");
// ASSERT(bytes[1] != 0xc7, "x");
// ASSERT(data != 0x4d, "x");
// ASSERT(data != 0x4d, "x");
push_back(bytes[0]);
push_back(bytes[1]);
}
Expand All @@ -66,7 +66,7 @@ namespace utility {
byte bytes[4];
std::memcpy(bytes, &data, sizeof(data));
for (int i = 0; i < 4; ++i) {
// ASSERT(bytes[i] != 0xc7, "x");
// ASSERT(bytes[i] != 0x4d, "x");
push_back(bytes[i]);
}
}
Expand All @@ -79,7 +79,7 @@ namespace utility {
byte bytes[8];
std::memcpy(bytes, &data, sizeof(data));
for (int i = 0; i < 8; ++i) {
// ASSERT(bytes[i] != 0xc7, "x");
// ASSERT(bytes[i] != 0x4d, "x");
push_back(bytes[i]);
}
}
Expand Down

0 comments on commit 35a1335

Please sign in to comment.