| ... | ... | @@ -2856,10 +2856,14 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2856 | 2856 | .immediate => |imm| { |
| 2857 | 2857 | switch (abi_size) { |
| 2858 | 2858 | 1, 2, 4 => { |
| 2859 | const immediate = if (value_ty.isSignedInt()) |
| 2860 | Immediate.s(@intCast(i32, @bitCast(i64, imm))) |
| 2861 | else |
| 2862 | Immediate.u(@truncate(u32, imm)); |
| 2859 | 2863 | try self.asmMemoryImmediate(.mov, Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ |
| 2860 | 2864 | .base = reg.to64(), |
| 2861 | 2865 | .disp = 0, |
| 2862 | | }), Immediate.u(@truncate(u32, imm))); |
| 2866 | }), immediate); |
| 2863 | 2867 | }, |
| 2864 | 2868 | 8 => { |
| 2865 | 2869 | // TODO: optimization: if the imm is only using the lower |
| ... | ... | @@ -3580,7 +3584,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu |
| 3580 | 3584 | const actual_tag: Mir.Inst.Tag = switch (dst_ty.tag()) { |
| 3581 | 3585 | .f32 => switch (mir_tag) { |
| 3582 | 3586 | .add => .addss, |
| 3583 | | .cmp => .cmpss, |
| 3587 | .cmp => .ucomiss, |
| 3584 | 3588 | else => return self.fail( |
| 3585 | 3589 | "TODO genBinOpMir for f32 register-register with MIR tag {}", |
| 3586 | 3590 | .{mir_tag}, |
| ... | ... | @@ -3588,7 +3592,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu |
| 3588 | 3592 | }, |
| 3589 | 3593 | .f64 => switch (mir_tag) { |
| 3590 | 3594 | .add => .addsd, |
| 3591 | | .cmp => .cmpsd, |
| 3595 | .cmp => .ucomisd, |
| 3592 | 3596 | else => return self.fail( |
| 3593 | 3597 | "TODO genBinOpMir for f64 register-register with MIR tag {}", |
| 3594 | 3598 | .{mir_tag}, |
| ... | ... | @@ -3599,7 +3603,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu |
| 3599 | 3603 | .{dst_ty.fmtDebug()}, |
| 3600 | 3604 | ), |
| 3601 | 3605 | }; |
| 3602 | | try self.asmRegisterRegister(actual_tag, dst_reg.to128(), src_reg.to128()); |
| 3606 | return self.asmRegisterRegister(actual_tag, dst_reg.to128(), src_reg.to128()); |
| 3603 | 3607 | } |
| 3604 | 3608 | |
| 3605 | 3609 | return self.fail("TODO genBinOpMir for float register-register and no intrinsics", .{}); |
| ... | ... | @@ -5255,11 +5259,14 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 5255 | 5259 | // TODO |
| 5256 | 5260 | // We have a positive stack offset value but we want a twos complement negative |
| 5257 | 5261 | // offset from rbp, which is at the top of the stack frame. |
| 5258 | | // mov [rbp+offset], immediate |
| 5262 | const immediate = if (ty.isSignedInt()) |
| 5263 | Immediate.s(@intCast(i32, @bitCast(i64, imm))) |
| 5264 | else |
| 5265 | Immediate.u(@intCast(u32, imm)); |
| 5259 | 5266 | try self.asmMemoryImmediate(.mov, Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ |
| 5260 | 5267 | .base = .rsp, |
| 5261 | 5268 | .disp = -stack_offset, |
| 5262 | | }), Immediate.u(@intCast(u32, imm))); |
| 5269 | }), immediate); |
| 5263 | 5270 | }, |
| 5264 | 5271 | 8 => { |
| 5265 | 5272 | const reg = try self.copyToTmpRegister(ty, mcv); |
| ... | ... | @@ -5340,10 +5347,19 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 5340 | 5347 | if (!self.wantSafety()) |
| 5341 | 5348 | return; // The already existing value will do just fine. |
| 5342 | 5349 | // TODO Upgrade this to a memset call when we have that available. |
| 5343 | | switch (ty.abiSize(self.target.*)) { |
| 5344 | | 1 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaa }, opts), |
| 5345 | | 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }, opts), |
| 5346 | | 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }, opts), |
| 5350 | switch (abi_size) { |
| 5351 | 1, 2, 4 => { |
| 5352 | const value: u64 = switch (abi_size) { |
| 5353 | 1 => 0xaa, |
| 5354 | 2 => 0xaaaa, |
| 5355 | 4 => 0xaaaaaaaa, |
| 5356 | else => unreachable, |
| 5357 | }; |
| 5358 | return self.asmMemoryImmediate(.mov, Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ |
| 5359 | .base = opts.dest_stack_base orelse .rbp, |
| 5360 | .disp = -stack_offset, |
| 5361 | }), Immediate.u(value)); |
| 5362 | }, |
| 5347 | 5363 | 8 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaaaaaaaaaa }, opts), |
| 5348 | 5364 | else => |x| return self.genInlineMemset( |
| 5349 | 5365 | .{ .stack_offset = stack_offset }, |
| ... | ... | @@ -5385,13 +5401,17 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 5385 | 5401 | try self.asmMemoryImmediate(.mov, Memory.sib(.byte, .{ |
| 5386 | 5402 | .base = base_reg, |
| 5387 | 5403 | .disp = -stack_offset, |
| 5388 | | }), Immediate.u(@truncate(u32, x_big))); |
| 5404 | }), Immediate.u(@truncate(u8, x_big))); |
| 5389 | 5405 | }, |
| 5390 | 5406 | 1, 2, 4 => { |
| 5407 | const immediate = if (ty.isSignedInt()) |
| 5408 | Immediate.s(@truncate(i32, @bitCast(i64, x_big))) |
| 5409 | else |
| 5410 | Immediate.u(@intCast(u32, x_big)); |
| 5391 | 5411 | try self.asmMemoryImmediate(.mov, Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ |
| 5392 | 5412 | .base = base_reg, |
| 5393 | 5413 | .disp = -stack_offset, |
| 5394 | | }), Immediate.u(@truncate(u32, x_big))); |
| 5414 | }), immediate); |
| 5395 | 5415 | }, |
| 5396 | 5416 | 8 => { |
| 5397 | 5417 | // 64 bit write to memory would take two mov's anyways so we |
| ... | ... | @@ -5777,12 +5797,15 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5777 | 5797 | // register is the fastest way to zero a register. |
| 5778 | 5798 | return self.asmRegisterRegister(.xor, reg.to32(), reg.to32()); |
| 5779 | 5799 | } |
| 5780 | | if (ty.isSignedInt() and x <= math.maxInt(i32)) { |
| 5781 | | return self.asmRegisterImmediate( |
| 5782 | | .mov, |
| 5783 | | registerAlias(reg, abi_size), |
| 5784 | | Immediate.s(@intCast(i32, @bitCast(i64, x))), |
| 5785 | | ); |
| 5800 | if (ty.isSignedInt()) { |
| 5801 | const signed_x = @bitCast(i64, x); |
| 5802 | if (math.minInt(i32) <= signed_x and signed_x <= math.maxInt(i32)) { |
| 5803 | return self.asmRegisterImmediate( |
| 5804 | .mov, |
| 5805 | registerAlias(reg, abi_size), |
| 5806 | Immediate.s(@intCast(i32, signed_x)), |
| 5807 | ); |
| 5808 | } |
| 5786 | 5809 | } |
| 5787 | 5810 | return self.asmRegisterImmediate( |
| 5788 | 5811 | .mov, |