| ... | @@ -783,7 +783,7 @@ fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue { | ... | @@ -783,7 +783,7 @@ fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue { |
| 783 | | 783 | |
| 784 | pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void { | 784 | pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void { |
| 785 | const stack_mcv = try self.allocRegOrMem(inst, false); | 785 | const stack_mcv = try self.allocRegOrMem(inst, false); |
| 786 | log.debug("spilling {d} to stack mcv {any}", .{ inst, stack_mcv }); | 786 | log.debug("spilling {} (%{d}) to stack mcv {any}", .{ reg, inst, stack_mcv }); |
| 787 | const reg_mcv = self.getResolvedInstValue(inst); | 787 | const reg_mcv = self.getResolvedInstValue(inst); |
| 788 | assert(reg == reg_mcv.register); | 788 | assert(reg == reg_mcv.register); |
| 789 | const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; | 789 | const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; |
| ... | @@ -1591,28 +1591,54 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1591,28 +1591,54 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void { |
| 1591 | fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) !void { | 1591 | fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1592 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 1592 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 1593 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; | 1593 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 1594 | return self.structFieldPtr(extra.struct_operand, ty_pl.ty, extra.field_index); | 1594 | const result = try self.structFieldPtr(inst, extra.struct_operand, extra.field_index); |
| | 1595 | return self.finishAir(inst, result, .{ extra.struct_operand, .none, .none }); |
| 1595 | } | 1596 | } |
| 1596 | | 1597 | |
| 1597 | fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { | 1598 | fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { |
| 1598 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 1599 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1599 | return self.structFieldPtr(ty_op.operand, ty_op.ty, index); | 1600 | const result = try self.structFieldPtr(inst, ty_op.operand, index); |
| | 1601 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1600 | } | 1602 | } |
| 1601 | fn structFieldPtr(self: *Self, operand: Air.Inst.Ref, ty: Air.Inst.Ref, index: u32) !void { | 1603 | |
| 1602 | _ = self; | 1604 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 1603 | _ = operand; | 1605 | return if (self.liveness.isUnused(inst)) .dead else result: { |
| 1604 | _ = ty; | 1606 | const mcv = try self.resolveInst(operand); |
| 1605 | _ = index; | 1607 | const struct_ty = self.air.typeOf(operand).childType(); |
| 1606 | return self.fail("TODO implement codegen struct_field_ptr", .{}); | 1608 | const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*)); |
| 1607 | //return self.finishAir(inst, result, .{ extra.struct_ptr, .none, .none }); | 1609 | const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*)); |
| | 1610 | const struct_field_ty = struct_ty.structFieldType(index); |
| | 1611 | const struct_field_size = @intCast(u32, struct_field_ty.abiSize(self.target.*)); |
| | 1612 | switch (mcv) { |
| | 1613 | .ptr_stack_offset => |off| { |
| | 1614 | break :result MCValue{ .ptr_stack_offset = off + struct_size - struct_field_offset - struct_field_size }; |
| | 1615 | }, |
| | 1616 | else => return self.fail("TODO implement codegen struct_field_ptr for {}", .{mcv}), |
| | 1617 | } |
| | 1618 | }; |
| 1608 | } | 1619 | } |
| 1609 | | 1620 | |
| 1610 | fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | 1621 | fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1611 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 1622 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 1612 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; | 1623 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 1613 | _ = extra; | 1624 | const operand = extra.struct_operand; |
| 1614 | return self.fail("TODO implement codegen struct_field_val", .{}); | 1625 | const index = extra.field_index; |
| 1615 | //return self.finishAir(inst, result, .{ extra.struct_ptr, .none, .none }); | 1626 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| | 1627 | const mcv = try self.resolveInst(operand); |
| | 1628 | const struct_ty = self.air.typeOf(operand); |
| | 1629 | const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*)); |
| | 1630 | const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*)); |
| | 1631 | const struct_field_ty = struct_ty.structFieldType(index); |
| | 1632 | const struct_field_size = @intCast(u32, struct_field_ty.abiSize(self.target.*)); |
| | 1633 | switch (mcv) { |
| | 1634 | .stack_offset => |off| { |
| | 1635 | break :result MCValue{ .stack_offset = off + struct_size - struct_field_offset - struct_field_size }; |
| | 1636 | }, |
| | 1637 | else => return self.fail("TODO implement codegen struct_field_val for {}", .{mcv}), |
| | 1638 | } |
| | 1639 | }; |
| | 1640 | |
| | 1641 | return self.finishAir(inst, result, .{ extra.struct_operand, .none, .none }); |
| 1616 | } | 1642 | } |
| 1617 | | 1643 | |
| 1618 | fn armOperandShouldBeRegister(self: *Self, mcv: MCValue) !bool { | 1644 | fn armOperandShouldBeRegister(self: *Self, mcv: MCValue) !bool { |
| ... | @@ -1985,11 +2011,11 @@ fn genArmMulConstant(self: *Self, inst: Air.Inst.Index, op: Air.Inst.Ref, op_ind | ... | @@ -1985,11 +2011,11 @@ fn genArmMulConstant(self: *Self, inst: Air.Inst.Index, op: Air.Inst.Ref, op_ind |
| 1985 | // Allocate 1 or 2 registers | 2011 | // Allocate 1 or 2 registers |
| 1986 | if (lhs_is_register) { | 2012 | if (lhs_is_register) { |
| 1987 | // Move RHS to register | 2013 | // Move RHS to register |
| 1988 | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{mcv.register}) }; | 2014 | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(null, &.{mcv.register}) }; |
| 1989 | rhs_mcv = dst_mcv; | 2015 | rhs_mcv = dst_mcv; |
| 1990 | } else { | 2016 | } else { |
| 1991 | // Move LHS and RHS to register | 2017 | // Move LHS and RHS to register |
| 1992 | const regs = try self.register_manager.allocRegs(2, .{ inst, null }, &.{}); | 2018 | const regs = try self.register_manager.allocRegs(2, .{ null, null }, &.{}); |
| 1993 | lhs_mcv = MCValue{ .register = regs[0] }; | 2019 | lhs_mcv = MCValue{ .register = regs[0] }; |
| 1994 | rhs_mcv = MCValue{ .register = regs[1] }; | 2020 | rhs_mcv = MCValue{ .register = regs[1] }; |
| 1995 | dst_mcv = lhs_mcv; | 2021 | dst_mcv = lhs_mcv; |
| ... | @@ -2401,16 +2427,22 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -2401,16 +2427,22 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 2401 | if (rhs_should_be_register) { | 2427 | if (rhs_should_be_register) { |
| 2402 | if (!lhs_is_register and !rhs_is_register) { | 2428 | if (!lhs_is_register and !rhs_is_register) { |
| 2403 | const regs = try self.register_manager.allocRegs(2, .{ | 2429 | const regs = try self.register_manager.allocRegs(2, .{ |
| 2404 | Air.refToIndex(bin_op.rhs).?, Air.refToIndex(bin_op.lhs).?, | 2430 | Air.refToIndex(bin_op.lhs).?, Air.refToIndex(bin_op.rhs).?, |
| 2405 | }, &.{}); | 2431 | }, &.{}); |
| 2406 | lhs_mcv = MCValue{ .register = regs[0] }; | 2432 | lhs_mcv = MCValue{ .register = regs[0] }; |
| 2407 | rhs_mcv = MCValue{ .register = regs[1] }; | 2433 | rhs_mcv = MCValue{ .register = regs[1] }; |
| 2408 | } else if (!rhs_is_register) { | 2434 | } else if (!rhs_is_register) { |
| 2409 | rhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(bin_op.rhs).?, &.{}) }; | 2435 | const track_inst = if (self.liveness.operandDies(inst, 1)) null else Air.refToIndex(bin_op.rhs).?; |
| | 2436 | rhs_mcv = MCValue{ .register = try self.register_manager.allocReg(track_inst, &.{}) }; |
| | 2437 | } else if (!lhs_is_register) { |
| | 2438 | const track_inst = if (self.liveness.operandDies(inst, 0)) null else Air.refToIndex(bin_op.lhs).?; |
| | 2439 | lhs_mcv = MCValue{ .register = try self.register_manager.allocReg(track_inst, &.{}) }; |
| | 2440 | } |
| | 2441 | } else { |
| | 2442 | if (!lhs_is_register) { |
| | 2443 | const track_inst = if (self.liveness.operandDies(inst, 0)) null else Air.refToIndex(bin_op.lhs).?; |
| | 2444 | lhs_mcv = MCValue{ .register = try self.register_manager.allocReg(track_inst, &.{}) }; |
| 2410 | } | 2445 | } |
| 2411 | } | | |
| 2412 | if (!lhs_is_register) { | | |
| 2413 | lhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(bin_op.lhs).?, &.{}) }; | | |
| 2414 | } | 2446 | } |
| 2415 | | 2447 | |
| 2416 | // Move the operands to the newly allocated registers | 2448 | // Move the operands to the newly allocated registers |