instruction encoding
This commit is contained in:
parent
c7bcfa1de9
commit
d391898b95
@ -303,6 +303,7 @@ pub const Module = struct {
|
||||
calls: BlockList(Call) = .{},
|
||||
argument_list: BlockList(ArgumentList) = .{},
|
||||
returns: BlockList(Return) = .{},
|
||||
entry_point: ?u32 = null,
|
||||
|
||||
pub const Descriptor = struct {
|
||||
main_package_path: []const u8,
|
||||
|
@ -27,7 +27,7 @@ pub const Result = struct {
|
||||
},
|
||||
entry_point: u32 = 0,
|
||||
|
||||
fn create() !Result {
|
||||
pub fn create() !Result {
|
||||
return Result{
|
||||
.sections = .{
|
||||
.text = .{ .content = try mmap(page_size, .{ .executable = true }) },
|
||||
@ -82,14 +82,6 @@ pub const Result = struct {
|
||||
image.sections.text.index += 1;
|
||||
}
|
||||
|
||||
// fn appendOnlyOpcodeSkipInstructionBytes(image: *Result, instruction: Instruction) void {
|
||||
// const instruction_descriptor = instruction_descriptors.get(instruction);
|
||||
// assert(instruction_descriptor.opcode_byte_count == instruction_descriptor.operand_offset);
|
||||
// image.appendCode(instruction_descriptor.getOpcode());
|
||||
//
|
||||
// image.sections.text.index += instruction_descriptor.size - instruction_descriptor.opcode_byte_count;
|
||||
// }
|
||||
|
||||
fn getEntryPoint(image: *const Result, comptime FunctionType: type) *const FunctionType {
|
||||
comptime {
|
||||
assert(@typeInfo(FunctionType) == .Fn);
|
||||
@ -127,79 +119,13 @@ pub fn get(comptime arch: std.Target.Cpu.Arch) type {
|
||||
.x86_64 => @import("x86_64.zig"),
|
||||
else => @compileError("Architecture not supported"),
|
||||
};
|
||||
const Instruction = backend.Instruction;
|
||||
_ = Instruction;
|
||||
|
||||
return struct {
|
||||
pub fn initialize(allocator: Allocator, intermediate: *ir.Result) !void {
|
||||
var result = try Result.create();
|
||||
std.debug.print("Entry point: {}\n", .{intermediate.entry_point});
|
||||
var mir = try backend.MIR.generate(allocator, intermediate);
|
||||
try mir.allocateRegisters(allocator, intermediate);
|
||||
// var function_iterator = intermediate.functions.iterator();
|
||||
// const IS = InstructionSelector(Instruction);
|
||||
// var instruction_selector = IS{
|
||||
// .functions = try ArrayList(IS.Function).initCapacity(allocator, intermediate.functions.len),
|
||||
// .allocator = allocator,
|
||||
// };
|
||||
//
|
||||
// while (function_iterator.next()) |ir_function| {
|
||||
// const function = instruction_selector.functions.addOneAssumeCapacity();
|
||||
// function.* = .{};
|
||||
// try function.block_map.ensureTotalCapacity(allocator, @intCast(ir_function.blocks.items.len));
|
||||
// for (ir_function.blocks.items, 0..) |block_index, index| {
|
||||
// function.block_map.putAssumeCapacity(block_index, @intCast(index));
|
||||
// }
|
||||
//
|
||||
// for (ir_function.blocks.items) |block_index| {
|
||||
// const block = intermediate.blocks.get(block_index);
|
||||
// for (block.instructions.items) |instruction_index| {
|
||||
// const instruction = intermediate.instructions.get(instruction_index).*;
|
||||
// try backend.selectInstruction(&instruction_selector, function, intermediate, instruction);
|
||||
// }
|
||||
//
|
||||
// // function.block_byte_counts.appendAssumeCapacity(function.block_byte_count);
|
||||
// // function.byte_count += function.block_byte_count;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for (instruction_selector.functions.items) |function| {
|
||||
// for (function.instructions.items) |instruction| backend.emitInstruction(&result, instruction, intermediate);
|
||||
// }
|
||||
|
||||
// for (instruction_selector.functions.items) |function| {
|
||||
// var fix_size: bool = false;
|
||||
// _ = fix_size;
|
||||
// for (function.relocations.items) |instruction_index| {
|
||||
// const instruction = function.instructions.items[instruction_index];
|
||||
// const relative = instruction.jmp_rel_8;
|
||||
// const source_block = relative.source;
|
||||
// const destination_block = relative.destination;
|
||||
// const source_offset = function.block_offsets.items[source_block];
|
||||
// const destination_offset = function.block_offsets.items[destination_block];
|
||||
// std.debug.print("Source offset: {}. Destination: {}\n", .{ source_offset, destination_offset });
|
||||
// const instruction_descriptor = instruction_descriptors.get(relative.instruction);
|
||||
// const instruction_offset = source_offset + relative.block_offset;
|
||||
// const really_source_offset = instruction_offset + instruction_descriptor.size;
|
||||
// const displacement = @as(i64, destination_offset) - @as(i64, really_source_offset);
|
||||
//
|
||||
// const operands = instruction_descriptor.getOperands();
|
||||
// switch (operands.len) {
|
||||
// 1 => switch (operands[0].size) {
|
||||
// @sizeOf(u8) => {
|
||||
// if (displacement >= std.math.minInt(i8) and displacement <= std.math.maxInt(i8)) {
|
||||
// const writer_index = instruction_offset + instruction_descriptor.operand_offset;
|
||||
// std.debug.print("Instruction offset: {}. Operand offset: {}. Writer index: {}. displacement: {}\n", .{ instruction_offset, instruction_descriptor.operand_offset, writer_index, displacement });
|
||||
// result.sections.text.content[writer_index] = @bitCast(@as(i8, @intCast(displacement)));
|
||||
// } else {
|
||||
// unreachable;
|
||||
// }
|
||||
// },
|
||||
// else => unreachable,
|
||||
// },
|
||||
// else => unreachable,
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
const result = try mir.encode(intermediate);
|
||||
|
||||
const text_section = result.sections.text.content[0..result.sections.text.index];
|
||||
for (text_section) |byte| {
|
||||
|
@ -25,6 +25,7 @@ pub const Result = struct {
|
||||
syscalls: BlockList(Syscall) = .{},
|
||||
values: BlockList(Value) = .{},
|
||||
stack_references: BlockList(StackReference) = .{},
|
||||
entry_point: u32 = 0,
|
||||
};
|
||||
|
||||
pub fn initialize(compilation: *Compilation, module: *Module, package: *Package, main_file: Compilation.Type.Index) !Result {
|
||||
@ -38,6 +39,8 @@ pub fn initialize(compilation: *Compilation, module: *Module, package: *Package,
|
||||
.module = module,
|
||||
};
|
||||
|
||||
builder.ir.entry_point = module.entry_point orelse unreachable;
|
||||
|
||||
while (function_iterator.next()) |sema_function| {
|
||||
const function_index = try builder.buildFunction(sema_function);
|
||||
try builder.optimizeFunction(function_index);
|
||||
@ -284,10 +287,29 @@ pub const Builder = struct {
|
||||
for (basic_block.instructions.items) |instruction_index| {
|
||||
did_something = did_something or try builder.removeUnreachablePhis(reachable_blocks, instruction_index);
|
||||
did_something = did_something or try builder.removeTrivialPhis(instruction_index);
|
||||
did_something = did_something or try builder.removeCopies(instruction_index);
|
||||
const copy = try builder.removeCopyReferences(instruction_index);
|
||||
did_something = did_something or copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var instructions_to_delete = ArrayList(u32){};
|
||||
for (reachable_blocks) |basic_block_index| {
|
||||
instructions_to_delete.clearRetainingCapacity();
|
||||
const basic_block = builder.ir.blocks.get(basic_block_index);
|
||||
for (basic_block.instructions.items, 0..) |instruction_index, index| {
|
||||
const instruction = builder.ir.instructions.get(instruction_index);
|
||||
switch (instruction.*) {
|
||||
.copy => try instructions_to_delete.append(builder.allocator, @intCast(index)),
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
var deleted_instruction_count: usize = 0;
|
||||
for (instructions_to_delete.items) |instruction_to_delete| {
|
||||
_ = basic_block.instructions.orderedRemove(instruction_to_delete - deleted_instruction_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn removeUnreachablePhis(builder: *Builder, reachable_blocks: []const BasicBlock.Index, instruction_index: Instruction.Index) !bool {
|
||||
@ -367,7 +389,7 @@ pub const Builder = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn removeCopies(builder: *Builder, instruction_index: Instruction.Index) !bool {
|
||||
fn removeCopyReferences(builder: *Builder, instruction_index: Instruction.Index) !bool {
|
||||
const instruction = builder.ir.instructions.get(instruction_index);
|
||||
return switch (instruction.*) {
|
||||
.copy => false,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -518,37 +518,6 @@ const Analyzer = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn analyzeDeclaration(analyzer: *Analyzer, scope_index: Scope.Index, declaration: *Declaration) !Value.Index {
|
||||
_ = scope_index;
|
||||
_ = declaration;
|
||||
_ = analyzer;
|
||||
// switch (declaration.*) {
|
||||
// .unresolved => |node_index| {
|
||||
// const declaration_node = analyzer.nodes[node_index.unwrap()];
|
||||
// return switch (declaration_node.id) {
|
||||
// .simple_variable_declaration => blk: {
|
||||
// const expect_type = switch (declaration_node.left.valid) {
|
||||
// true => unreachable,
|
||||
// false => @unionInit(ExpectType, "none", {}),
|
||||
// };
|
||||
//
|
||||
// const initialization_expression = try analyzer.expression(scope, expect_type, declaration_node.right);
|
||||
// const value = analyzer.module.values.get(initialization_expression);
|
||||
// if (value.is_comptime and value.is_const) {
|
||||
// break :blk initialization_expression;
|
||||
// }
|
||||
//
|
||||
// unreachable;
|
||||
// },
|
||||
// else => |t| @panic(@tagName(t)),
|
||||
// };
|
||||
// },
|
||||
// .struct_type => unreachable,
|
||||
// }
|
||||
|
||||
@panic("TODO: analyzeDeclaration");
|
||||
}
|
||||
|
||||
fn structType(analyzer: *Analyzer, value: *Value, parent_scope_index: Scope.Index, index: Node.Index, file_index: File.Index) !Type.Index {
|
||||
var node_buffer: [2]Node.Index = undefined;
|
||||
// We have the file because this might be the first file
|
||||
@ -892,7 +861,23 @@ pub fn initialize(compilation: *Compilation, module: *Module, package: *Package,
|
||||
},
|
||||
});
|
||||
|
||||
return analyzeExistingPackage(value_allocation.ptr, compilation, module, package);
|
||||
const result = analyzeExistingPackage(value_allocation.ptr, compilation, module, package);
|
||||
|
||||
var decl_iterator = module.declarations.iterator();
|
||||
while (decl_iterator.nextPointer()) |decl| {
|
||||
if (equal(u8, decl.name, "_start")) {
|
||||
const value = module.values.get(decl.init_value);
|
||||
module.entry_point = switch (value.*) {
|
||||
.function => |function_index| function_index.uniqueInteger(),
|
||||
else => |t| @panic(@tagName(t)),
|
||||
};
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@panic("Entry point not found");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn analyzeExistingPackage(value: *Value, compilation: *Compilation, module: *Module, package: *Package) !Type.Index {
|
||||
|
Loading…
x
Reference in New Issue
Block a user