implement lea for globals and argument tweaks
This commit is contained in:
parent
8755c32aff
commit
da07fd5ca4
@ -2137,59 +2137,67 @@ pub const MIR = struct {
|
|||||||
switch (ir_instruction.*) {
|
switch (ir_instruction.*) {
|
||||||
.ret => |ir_ret_index| {
|
.ret => |ir_ret_index| {
|
||||||
const ir_ret = mir.ir.returns.get(ir_ret_index);
|
const ir_ret = mir.ir.returns.get(ir_ret_index);
|
||||||
const value_type = resolveType(getIrType(mir.ir, ir_ret.instruction));
|
switch (ir_ret.instruction.invalid) {
|
||||||
const source_register = try instruction_selection.getRegisterForValue(mir, ir_ret.instruction);
|
true => {
|
||||||
|
const ret = try mir.buildInstruction(instruction_selection, .ret, &.{});
|
||||||
|
try instruction_selection.instruction_cache.append(mir.allocator, ret);
|
||||||
|
},
|
||||||
|
false => {
|
||||||
|
const value_type = resolveType(getIrType(mir.ir, ir_ret.instruction));
|
||||||
|
const source_register = try instruction_selection.getRegisterForValue(mir, ir_ret.instruction);
|
||||||
|
|
||||||
const register_class = register_classes.get(value_type);
|
const register_class = register_classes.get(value_type);
|
||||||
|
|
||||||
const physical_register = Register{
|
const physical_register = Register{
|
||||||
.index = .{
|
.index = .{
|
||||||
.physical = switch (register_class) {
|
.physical = switch (register_class) {
|
||||||
.gp32 => .eax,
|
.gp32 => .eax,
|
||||||
.gp64 => .rax,
|
.gp64 => .rax,
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const operand_id: Operand.Id = switch (register_class) {
|
||||||
|
.gp32 => .gp32,
|
||||||
|
.gp64 => .gp64,
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
},
|
};
|
||||||
},
|
|
||||||
};
|
|
||||||
const operand_id: Operand.Id = switch (register_class) {
|
|
||||||
.gp32 => .gp32,
|
|
||||||
.gp64 => .gp64,
|
|
||||||
else => unreachable,
|
|
||||||
};
|
|
||||||
|
|
||||||
const copy = try mir.buildInstruction(instruction_selection, .copy, &.{
|
const copy = try mir.buildInstruction(instruction_selection, .copy, &.{
|
||||||
Operand{
|
Operand{
|
||||||
.id = operand_id,
|
.id = operand_id,
|
||||||
.u = .{
|
.u = .{
|
||||||
.register = physical_register,
|
.register = physical_register,
|
||||||
},
|
},
|
||||||
.flags = .{
|
.flags = .{
|
||||||
.type = .def,
|
.type = .def,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Operand{
|
Operand{
|
||||||
.id = operand_id,
|
.id = operand_id,
|
||||||
.u = .{
|
.u = .{
|
||||||
.register = source_register,
|
.register = source_register,
|
||||||
},
|
},
|
||||||
.flags = .{},
|
.flags = .{},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
try instruction_selection.instruction_cache.append(mir.allocator, copy);
|
try instruction_selection.instruction_cache.append(mir.allocator, copy);
|
||||||
|
|
||||||
const ret = try mir.buildInstruction(instruction_selection, .ret, &.{
|
const ret = try mir.buildInstruction(instruction_selection, .ret, &.{
|
||||||
Operand{
|
Operand{
|
||||||
.id = operand_id,
|
.id = operand_id,
|
||||||
.u = .{
|
.u = .{
|
||||||
.register = physical_register,
|
.register = physical_register,
|
||||||
},
|
},
|
||||||
.flags = .{
|
.flags = .{
|
||||||
.implicit = true,
|
.implicit = true,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
try instruction_selection.instruction_cache.append(mir.allocator, ret);
|
||||||
},
|
},
|
||||||
});
|
}
|
||||||
try instruction_selection.instruction_cache.append(mir.allocator, ret);
|
|
||||||
},
|
},
|
||||||
.load_integer => try instruction_selection.materializeInteger(mir, ir_instruction_index),
|
.load_integer => try instruction_selection.materializeInteger(mir, ir_instruction_index),
|
||||||
.@"unreachable" => try instruction_selection.instruction_cache.append(mir.allocator, try mir.buildInstruction(instruction_selection, .ud2, &.{})),
|
.@"unreachable" => try instruction_selection.instruction_cache.append(mir.allocator, try mir.buildInstruction(instruction_selection, .ud2, &.{})),
|
||||||
@ -2238,6 +2246,7 @@ pub const MIR = struct {
|
|||||||
const last_block_instruction = mir.ir.instructions.get(ir_block.instructions.items[ir_block.instructions.items.len - 1]);
|
const last_block_instruction = mir.ir.instructions.get(ir_block.instructions.items[ir_block.instructions.items.len - 1]);
|
||||||
break :blk switch (last_block_instruction.*) {
|
break :blk switch (last_block_instruction.*) {
|
||||||
.@"unreachable" => false,
|
.@"unreachable" => false,
|
||||||
|
.ret => true,
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -2468,12 +2477,16 @@ pub const MIR = struct {
|
|||||||
},
|
},
|
||||||
.call => |ir_call_index| {
|
.call => |ir_call_index| {
|
||||||
const ir_call = mir.ir.calls.get(ir_call_index);
|
const ir_call = mir.ir.calls.get(ir_call_index);
|
||||||
for (ir_call.arguments, 0..) |ir_argument_index, index| {
|
var argument_index = ir_call.arguments.len;
|
||||||
|
while (argument_index > 0) {
|
||||||
|
argument_index -= 1;
|
||||||
|
|
||||||
|
const ir_argument_index = ir_call.arguments[argument_index];
|
||||||
// print("index: {}", .{index});
|
// print("index: {}", .{index});
|
||||||
const source_register = try instruction_selection.getRegisterForValue(mir, ir_argument_index);
|
const source_register = try instruction_selection.getRegisterForValue(mir, ir_argument_index);
|
||||||
const source_value_type = resolveType(getIrType(mir.ir, ir_argument_index));
|
const source_value_type = resolveType(getIrType(mir.ir, ir_argument_index));
|
||||||
const source_register_class = register_classes.get(source_value_type);
|
const source_register_class = register_classes.get(source_value_type);
|
||||||
const argument_register = calling_convention.argument_registers.get(source_register_class)[index];
|
const argument_register = calling_convention.argument_registers.get(source_register_class)[argument_index];
|
||||||
// print("Argument register: {}", .{argument_register});
|
// print("Argument register: {}", .{argument_register});
|
||||||
|
|
||||||
const destination_register = Register{
|
const destination_register = Register{
|
||||||
@ -2487,6 +2500,7 @@ pub const MIR = struct {
|
|||||||
.gp64 => .gp64,
|
.gp64 => .gp64,
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
|
|
||||||
const source_operand = Operand{
|
const source_operand = Operand{
|
||||||
.id = operand_id,
|
.id = operand_id,
|
||||||
.u = .{
|
.u = .{
|
||||||
@ -2494,6 +2508,7 @@ pub const MIR = struct {
|
|||||||
},
|
},
|
||||||
.flags = .{},
|
.flags = .{},
|
||||||
};
|
};
|
||||||
|
|
||||||
const destination_operand = Operand{
|
const destination_operand = Operand{
|
||||||
.id = operand_id,
|
.id = operand_id,
|
||||||
.u = .{
|
.u = .{
|
||||||
@ -2577,6 +2592,39 @@ pub const MIR = struct {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.load_string_literal => |ir_load_string_literal_index| {
|
||||||
|
const virtual_register = try instruction_selection.getRegisterForValue(mir, ir_instruction_index);
|
||||||
|
const virtual_operand = Operand{
|
||||||
|
.id = .gp64,
|
||||||
|
.u = .{
|
||||||
|
.register = virtual_register,
|
||||||
|
},
|
||||||
|
.flags = .{ .type = .def },
|
||||||
|
};
|
||||||
|
const source_operand = Operand{
|
||||||
|
.id = .lea64mem,
|
||||||
|
.u = .{
|
||||||
|
.lea64mem = .{
|
||||||
|
.gp64 = null,
|
||||||
|
.scale = 1,
|
||||||
|
.scale_reg = null,
|
||||||
|
.displacement = Operand.PCRelative{
|
||||||
|
.string_literal = ir_load_string_literal_index,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.flags = .{},
|
||||||
|
};
|
||||||
|
|
||||||
|
const lea = try mir.buildInstruction(instruction_selection, .lea64r, &.{
|
||||||
|
virtual_operand,
|
||||||
|
source_operand,
|
||||||
|
});
|
||||||
|
|
||||||
|
try instruction_selection.instruction_cache.append(mir.allocator, lea);
|
||||||
|
|
||||||
|
try instruction_selection.updateValueMap(mir.allocator, ir_instruction_index, virtual_register, false);
|
||||||
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4070,11 +4118,17 @@ pub const MIR = struct {
|
|||||||
{
|
{
|
||||||
if (instruction != .copy) {
|
if (instruction != .copy) {
|
||||||
const descriptor = instruction_descriptors.getPtrConst(instruction);
|
const descriptor = instruction_descriptors.getPtrConst(instruction);
|
||||||
if (descriptor.operands.len != operands.len) unreachable;
|
if (descriptor.operands.len == operands.len) {
|
||||||
for (descriptor.operands, operands) |descriptor_operand, operand| {
|
for (descriptor.operands, operands) |descriptor_operand, operand| {
|
||||||
switch (descriptor_operand.id) {
|
switch (descriptor_operand.id) {
|
||||||
.unknown => {},
|
.unknown => {},
|
||||||
else => if (descriptor_operand.id != operand.id) unreachable,
|
else => if (descriptor_operand.id != operand.id) unreachable,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (instruction) {
|
||||||
|
.ret => {},
|
||||||
|
else => unreachable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user