| ... | @@ -3514,8 +3514,14 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -3514,8 +3514,14 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 3514 | else => return self.fail("TODO implement args on stack for {} with abi size > 8", .{mcv}), | 3514 | else => return self.fail("TODO implement args on stack for {} with abi size > 8", .{mcv}), |
| 3515 | } | 3515 | } |
| 3516 | }, | 3516 | }, |
| | 3517 | .embedded_in_code => { |
| | 3518 | if (abi_size <= 8) { |
| | 3519 | const reg = try self.copyToTmpRegister(ty, mcv); |
| | 3520 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); |
| | 3521 | } |
| | 3522 | return self.fail("TODO implement args on stack for {} with abi size > 8", .{mcv}); |
| | 3523 | }, |
| 3517 | .memory, | 3524 | .memory, |
| 3518 | .embedded_in_code, | | |
| 3519 | .direct_load, | 3525 | .direct_load, |
| 3520 | .got_load, | 3526 | .got_load, |
| 3521 | => { | 3527 | => { |
| ... | @@ -3523,7 +3529,58 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -3523,7 +3529,58 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 3523 | const reg = try self.copyToTmpRegister(ty, mcv); | 3529 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 3524 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); | 3530 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); |
| 3525 | } | 3531 | } |
| 3526 | return self.fail("TODO implement memcpy for setting args on stack from {}", .{mcv}); | 3532 | |
| | 3533 | self.register_manager.freezeRegs(&.{ .rax, .rcx }); |
| | 3534 | defer self.register_manager.unfreezeRegs(&.{ .rax, .rcx }); |
| | 3535 | |
| | 3536 | const addr_reg: Register = blk: { |
| | 3537 | switch (mcv) { |
| | 3538 | .got_load, |
| | 3539 | .direct_load, |
| | 3540 | => |sym_index| { |
| | 3541 | const flags: u2 = switch (mcv) { |
| | 3542 | .got_load => 0b00, |
| | 3543 | .direct_load => 0b01, |
| | 3544 | else => unreachable, |
| | 3545 | }; |
| | 3546 | const addr_reg = try self.register_manager.allocReg(null); |
| | 3547 | _ = try self.addInst(.{ |
| | 3548 | .tag = .lea_pie, |
| | 3549 | .ops = (Mir.Ops{ |
| | 3550 | .reg1 = addr_reg.to64(), |
| | 3551 | .flags = flags, |
| | 3552 | }).encode(), |
| | 3553 | .data = .{ .linker_sym_index = sym_index }, |
| | 3554 | }); |
| | 3555 | break :blk addr_reg; |
| | 3556 | }, |
| | 3557 | .memory => |addr| { |
| | 3558 | const addr_reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = addr }); |
| | 3559 | break :blk addr_reg; |
| | 3560 | }, |
| | 3561 | else => unreachable, |
| | 3562 | } |
| | 3563 | }; |
| | 3564 | |
| | 3565 | self.register_manager.freezeRegs(&.{addr_reg}); |
| | 3566 | defer self.register_manager.unfreezeRegs(&.{addr_reg}); |
| | 3567 | |
| | 3568 | const regs = try self.register_manager.allocRegs(2, .{ null, null }); |
| | 3569 | const count_reg = regs[0]; |
| | 3570 | const tmp_reg = regs[1]; |
| | 3571 | |
| | 3572 | try self.register_manager.getReg(.rax, null); |
| | 3573 | try self.register_manager.getReg(.rcx, null); |
| | 3574 | |
| | 3575 | // TODO allow for abi_size to be u64 |
| | 3576 | try self.genSetReg(Type.u32, count_reg, .{ .immediate = @intCast(u32, abi_size) }); |
| | 3577 | try self.genInlineMemcpy( |
| | 3578 | -(stack_offset + @intCast(i32, abi_size)), |
| | 3579 | .rsp, |
| | 3580 | addr_reg.to64(), |
| | 3581 | count_reg.to64(), |
| | 3582 | tmp_reg.to8(), |
| | 3583 | ); |
| 3527 | }, | 3584 | }, |
| 3528 | .register => |reg| { | 3585 | .register => |reg| { |
| 3529 | _ = try self.addInst(.{ | 3586 | _ = try self.addInst(.{ |
| ... | @@ -4488,6 +4545,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa | ... | @@ -4488,6 +4545,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa |
| 4488 | } | 4545 | } |
| 4489 | | 4546 | |
| 4490 | fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue { | 4547 | fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue { |
| | 4548 | log.debug("lowerUnnamedConst: ty = {}, val = {}", .{ tv.ty, tv.val }); |
| 4491 | const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| { | 4549 | const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| { |
| 4492 | return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)}); | 4550 | return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)}); |
| 4493 | }; | 4551 | }; |
| ... | @@ -4520,23 +4578,20 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { | ... | @@ -4520,23 +4578,20 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { |
| 4520 | switch (typed_value.ty.zigTypeTag()) { | 4578 | switch (typed_value.ty.zigTypeTag()) { |
| 4521 | .Pointer => switch (typed_value.ty.ptrSize()) { | 4579 | .Pointer => switch (typed_value.ty.ptrSize()) { |
| 4522 | .Slice => { | 4580 | .Slice => { |
| 4523 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 4581 | return self.lowerUnnamedConst(typed_value); |
| 4524 | const ptr_type = typed_value.ty.slicePtrFieldType(&buf); | | |
| 4525 | const ptr_mcv = try self.genTypedValue(.{ .ty = ptr_type, .val = typed_value.val }); | | |
| 4526 | const slice_len = typed_value.val.sliceLen(); | | |
| 4527 | // Codegen can't handle some kinds of indirection. If the wrong union field is accessed here it may mean | | |
| 4528 | // the Sema code needs to use anonymous Decls or alloca instructions to store data. | | |
| 4529 | const ptr_imm = ptr_mcv.memory; | | |
| 4530 | _ = slice_len; | | |
| 4531 | _ = ptr_imm; | | |
| 4532 | // We need more general support for const data being stored in memory to make this work. | | |
| 4533 | return self.fail("TODO codegen for const slices", .{}); | | |
| 4534 | }, | 4582 | }, |
| 4535 | else => { | 4583 | else => { |
| 4536 | if (typed_value.val.tag() == .int_u64) { | 4584 | switch (typed_value.val.tag()) { |
| 4537 | return MCValue{ .immediate = typed_value.val.toUnsignedInt() }; | 4585 | .int_u64 => { |
| | 4586 | return MCValue{ .immediate = typed_value.val.toUnsignedInt() }; |
| | 4587 | }, |
| | 4588 | .slice => { |
| | 4589 | return self.lowerUnnamedConst(typed_value); |
| | 4590 | }, |
| | 4591 | else => { |
| | 4592 | return self.fail("TODO codegen more kinds of const pointers: {}", .{typed_value.val.tag()}); |
| | 4593 | }, |
| 4538 | } | 4594 | } |
| 4539 | return self.fail("TODO codegen more kinds of const pointers: {}", .{typed_value.val.tag()}); | | |
| 4540 | }, | 4595 | }, |
| 4541 | }, | 4596 | }, |
| 4542 | .Int => { | 4597 | .Int => { |