| ... | ... | @@ -400,7 +400,7 @@ fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { |
| 400 | 400 | return result; |
| 401 | 401 | } |
| 402 | 402 | |
| 403 | | fn asmSetCCRegister(self: *Self, reg: Register, cc: bits.Condition) !void { |
| 403 | fn asmSetccRegister(self: *Self, reg: Register, cc: bits.Condition) !void { |
| 404 | 404 | _ = try self.addInst(.{ |
| 405 | 405 | .tag = .setcc, |
| 406 | 406 | .ops = .r_c, |
| ... | ... | @@ -411,7 +411,7 @@ fn asmSetCCRegister(self: *Self, reg: Register, cc: bits.Condition) !void { |
| 411 | 411 | }); |
| 412 | 412 | } |
| 413 | 413 | |
| 414 | | fn asmCmovCCRegisterRegister(self: *Self, reg1: Register, reg2: Register, cc: bits.Condition) !void { |
| 414 | fn asmCmovccRegisterRegister(self: *Self, reg1: Register, reg2: Register, cc: bits.Condition) !void { |
| 415 | 415 | _ = try self.addInst(.{ |
| 416 | 416 | .tag = .cmovcc, |
| 417 | 417 | .ops = .rr_c, |
| ... | ... | @@ -1369,7 +1369,7 @@ fn airMin(self: *Self, inst: Air.Inst.Index) !void { |
| 1369 | 1369 | .unsigned => .b, |
| 1370 | 1370 | .signed => .l, |
| 1371 | 1371 | }; |
| 1372 | | try self.asmCmovCCRegisterRegister(dst_mcv.register, lhs_reg, cc); |
| 1372 | try self.asmCmovccRegisterRegister(dst_mcv.register, lhs_reg, cc); |
| 1373 | 1373 | |
| 1374 | 1374 | break :result dst_mcv; |
| 1375 | 1375 | }; |
| ... | ... | @@ -1569,7 +1569,7 @@ fn genSetStackTruncatedOverflowCompare( |
| 1569 | 1569 | .signed => .o, |
| 1570 | 1570 | .unsigned => .c, |
| 1571 | 1571 | }; |
| 1572 | | try self.asmSetCCRegister(overflow_reg.to8(), cc); |
| 1572 | try self.asmSetccRegister(overflow_reg.to8(), cc); |
| 1573 | 1573 | |
| 1574 | 1574 | const scratch_reg = temp_regs[1]; |
| 1575 | 1575 | try self.genSetReg(extended_ty, scratch_reg, .{ .register = reg }); |
| ... | ... | @@ -1582,7 +1582,7 @@ fn genSetStackTruncatedOverflowCompare( |
| 1582 | 1582 | ); |
| 1583 | 1583 | |
| 1584 | 1584 | const eq_reg = temp_regs[2]; |
| 1585 | | try self.asmSetCCRegister(eq_reg.to8(), .ne); |
| 1585 | try self.asmSetccRegister(eq_reg.to8(), .ne); |
| 1586 | 1586 | try self.genBinOpMir( |
| 1587 | 1587 | .@"or", |
| 1588 | 1588 | Type.u8, |
| ... | ... | @@ -1725,26 +1725,10 @@ fn genIntMulDivOpMir( |
| 1725 | 1725 | try self.genSetReg(ty, .rax, lhs); |
| 1726 | 1726 | } |
| 1727 | 1727 | |
| 1728 | | _ = signedness; |
| 1729 | | // switch (signedness) { |
| 1730 | | // .signed => { |
| 1731 | | // _ = try self.addInst(.{ |
| 1732 | | // .tag = .cwd, |
| 1733 | | // .ops = Mir.Inst.Ops.encode(.{ .flags = 0b11 }), |
| 1734 | | // .data = undefined, |
| 1735 | | // }); |
| 1736 | | // }, |
| 1737 | | // .unsigned => { |
| 1738 | | // _ = try self.addInst(.{ |
| 1739 | | // .tag = .xor, |
| 1740 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 1741 | | // .reg1 = .rdx, |
| 1742 | | // .reg2 = .rdx, |
| 1743 | | // }), |
| 1744 | | // .data = undefined, |
| 1745 | | // }); |
| 1746 | | // }, |
| 1747 | | // } |
| 1728 | switch (signedness) { |
| 1729 | .signed => try self.asmNone(.cqo), |
| 1730 | .unsigned => try self.asmRegisterRegister(.xor, .rdx, .rdx), |
| 1731 | } |
| 1748 | 1732 | |
| 1749 | 1733 | const factor = switch (rhs) { |
| 1750 | 1734 | .register => rhs, |
| ... | ... | @@ -1754,35 +1738,28 @@ fn genIntMulDivOpMir( |
| 1754 | 1738 | break :blk MCValue{ .register = reg }; |
| 1755 | 1739 | }, |
| 1756 | 1740 | }; |
| 1757 | | _ = factor; |
| 1758 | | _ = tag; |
| 1759 | | |
| 1760 | | // switch (factor) { |
| 1761 | | // .register => |reg| { |
| 1762 | | // _ = try self.addInst(.{ |
| 1763 | | // .tag = tag, |
| 1764 | | // .ops = Mir.Inst.Ops.encode(.{ .reg1 = reg }), |
| 1765 | | // .data = undefined, |
| 1766 | | // }); |
| 1767 | | // }, |
| 1768 | | // .stack_offset => |off| { |
| 1769 | | // _ = try self.addInst(.{ |
| 1770 | | // .tag = tag, |
| 1771 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 1772 | | // .reg2 = .rbp, |
| 1773 | | // .flags = switch (abi_size) { |
| 1774 | | // 1 => 0b00, |
| 1775 | | // 2 => 0b01, |
| 1776 | | // 4 => 0b10, |
| 1777 | | // 8 => 0b11, |
| 1778 | | // else => unreachable, |
| 1779 | | // }, |
| 1780 | | // }), |
| 1781 | | // .data = .{ .disp = -off }, |
| 1782 | | // }); |
| 1783 | | // }, |
| 1784 | | // else => unreachable, |
| 1785 | | // } |
| 1741 | |
| 1742 | switch (factor) { |
| 1743 | .register => |reg| try self.asmRegister(tag, reg), |
| 1744 | .stack_offset => |off| { |
| 1745 | _ = off; |
| 1746 | // _ = try self.addInst(.{ |
| 1747 | // .tag = tag, |
| 1748 | // .ops = Mir.Inst.Ops.encode(.{ |
| 1749 | // .reg2 = .rbp, |
| 1750 | // .flags = switch (abi_size) { |
| 1751 | // 1 => 0b00, |
| 1752 | // 2 => 0b01, |
| 1753 | // 4 => 0b10, |
| 1754 | // 8 => 0b11, |
| 1755 | // else => unreachable, |
| 1756 | // }, |
| 1757 | // }), |
| 1758 | // .data = .{ .disp = -off }, |
| 1759 | // }); |
| 1760 | }, |
| 1761 | else => unreachable, |
| 1762 | } |
| 1786 | 1763 | } |
| 1787 | 1764 | |
| 1788 | 1765 | /// Always returns a register. |
| ... | ... | @@ -1808,31 +1785,10 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa |
| 1808 | 1785 | .unsigned => .div, |
| 1809 | 1786 | }, Type.isize, signedness, .{ .register = dividend }, .{ .register = divisor }); |
| 1810 | 1787 | |
| 1811 | | // _ = try self.addInst(.{ |
| 1812 | | // .tag = .xor, |
| 1813 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 1814 | | // .reg1 = divisor.to64(), |
| 1815 | | // .reg2 = dividend.to64(), |
| 1816 | | // }), |
| 1817 | | // .data = undefined, |
| 1818 | | // }); |
| 1819 | | // _ = try self.addInst(.{ |
| 1820 | | // .tag = .sar, |
| 1821 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 1822 | | // .reg1 = divisor.to64(), |
| 1823 | | // .flags = 0b10, |
| 1824 | | // }), |
| 1825 | | // .data = .{ .imm = 63 }, |
| 1826 | | // }); |
| 1827 | | // _ = try self.addInst(.{ |
| 1828 | | // .tag = .@"test", |
| 1829 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 1830 | | // .reg1 = .rdx, |
| 1831 | | // .reg2 = .rdx, |
| 1832 | | // }), |
| 1833 | | // .data = undefined, |
| 1834 | | // }); |
| 1835 | | try self.asmCmovCCRegisterRegister(divisor.to64(), .rdx, .e); |
| 1788 | try self.asmRegisterRegister(.xor, divisor.to64(), dividend.to64()); |
| 1789 | try self.asmRegisterImmediate(.sar, divisor.to64(), Immediate.u(63)); |
| 1790 | try self.asmRegisterRegister(.@"test", .rdx, .rdx); |
| 1791 | try self.asmCmovccRegisterRegister(divisor.to64(), .rdx, .e); |
| 1836 | 1792 | try self.genBinOpMir(.add, Type.isize, .{ .register = divisor }, .{ .register = .rax }); |
| 1837 | 1793 | return MCValue{ .register = divisor }; |
| 1838 | 1794 | } |
| ... | ... | @@ -2877,7 +2833,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2877 | 2833 | const overflow_bit_ty = value_ty.structFieldType(1); |
| 2878 | 2834 | const overflow_bit_offset = value_ty.structFieldOffset(1, self.target.*); |
| 2879 | 2835 | const tmp_reg = try self.register_manager.allocReg(null, gp); |
| 2880 | | try self.asmSetCCRegister(tmp_reg.to8(), ro.eflags); |
| 2836 | try self.asmSetccRegister(tmp_reg.to8(), ro.eflags); |
| 2881 | 2837 | try self.genInlineMemcpyRegisterRegister( |
| 2882 | 2838 | overflow_bit_ty, |
| 2883 | 2839 | reg, |
| ... | ... | @@ -3151,14 +3107,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3151 | 3107 | }; |
| 3152 | 3108 | const field_size = @intCast(u32, struct_field_ty.abiSize(self.target.*)); |
| 3153 | 3109 | if (signedness == .signed and field_size < 8) { |
| 3154 | | // _ = try self.addInst(.{ |
| 3155 | | // .tag = .mov_sign_extend, |
| 3156 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 3157 | | // .reg1 = dst_mcv.register, |
| 3158 | | // .reg2 = registerAlias(dst_mcv.register, field_size), |
| 3159 | | // }), |
| 3160 | | // .data = undefined, |
| 3161 | | // }); |
| 3110 | try self.asmRegisterRegister( |
| 3111 | .movsx, |
| 3112 | dst_mcv.register, |
| 3113 | registerAlias(dst_mcv.register, field_size), |
| 3114 | ); |
| 3162 | 3115 | } |
| 3163 | 3116 | |
| 3164 | 3117 | break :result dst_mcv; |
| ... | ... | @@ -3175,7 +3128,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3175 | 3128 | defer self.register_manager.unlockReg(reg_lock); |
| 3176 | 3129 | |
| 3177 | 3130 | const dst_reg = try self.register_manager.allocReg(inst, gp); |
| 3178 | | try self.asmSetCCRegister(dst_reg.to8(), ro.eflags); |
| 3131 | try self.asmSetccRegister(dst_reg.to8(), ro.eflags); |
| 3179 | 3132 | break :result MCValue{ .register = dst_reg.to8() }; |
| 3180 | 3133 | }, |
| 3181 | 3134 | else => unreachable, |
| ... | ... | @@ -3211,25 +3164,7 @@ fn genShiftBinOpMir(self: *Self, tag: Mir.Inst.Tag, ty: Type, reg: Register, shi |
| 3211 | 3164 | switch (shift) { |
| 3212 | 3165 | .immediate => |imm| switch (imm) { |
| 3213 | 3166 | 0 => return, |
| 3214 | | 1 => { |
| 3215 | | // _ = try self.addInst(.{ |
| 3216 | | // .tag = tag, |
| 3217 | | // .ops = Mir.Inst.Ops.encode(.{ .reg1 = registerAlias(reg, abi_size) }), |
| 3218 | | // .data = undefined, |
| 3219 | | // }); |
| 3220 | | return; |
| 3221 | | }, |
| 3222 | | else => { |
| 3223 | | // _ = try self.addInst(.{ |
| 3224 | | // .tag = tag, |
| 3225 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 3226 | | // .reg1 = registerAlias(reg, abi_size), |
| 3227 | | // .flags = 0b10, |
| 3228 | | // }), |
| 3229 | | // .data = .{ .imm = @intCast(u8, imm) }, |
| 3230 | | // }); |
| 3231 | | return; |
| 3232 | | }, |
| 3167 | else => return self.asmRegisterImmediate(tag, registerAlias(reg, abi_size), Immediate.u(imm)), |
| 3233 | 3168 | }, |
| 3234 | 3169 | .register => |shift_reg| { |
| 3235 | 3170 | if (shift_reg == .rcx) break :blk; |
| ... | ... | @@ -3240,16 +3175,8 @@ fn genShiftBinOpMir(self: *Self, tag: Mir.Inst.Tag, ty: Type, reg: Register, shi |
| 3240 | 3175 | try self.register_manager.getReg(.rcx, null); |
| 3241 | 3176 | try self.genSetReg(Type.u8, .rcx, shift); |
| 3242 | 3177 | } |
| 3243 | | _ = abi_size; |
| 3244 | 3178 | |
| 3245 | | // _ = try self.addInst(.{ |
| 3246 | | // .tag = tag, |
| 3247 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 3248 | | // .reg1 = registerAlias(reg, abi_size), |
| 3249 | | // .flags = 0b01, |
| 3250 | | // }), |
| 3251 | | // .data = undefined, |
| 3252 | | // }); |
| 3179 | try self.asmRegisterRegister(tag, registerAlias(reg, abi_size), .cl); |
| 3253 | 3180 | } |
| 3254 | 3181 | |
| 3255 | 3182 | /// Result is always a register. |
| ... | ... | @@ -3620,43 +3547,38 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu |
| 3620 | 3547 | .register => |src_reg| switch (dst_ty.zigTypeTag()) { |
| 3621 | 3548 | .Float => { |
| 3622 | 3549 | if (intrinsicsAllowed(self.target.*, dst_ty)) { |
| 3623 | | // const actual_tag: Mir.Inst.Tag = switch (dst_ty.tag()) { |
| 3624 | | // .f32 => switch (mir_tag) { |
| 3625 | | // .add => Mir.Inst.Tag.add_f32, |
| 3626 | | // .cmp => Mir.Inst.Tag.cmp_f32, |
| 3627 | | // else => return self.fail("TODO genBinOpMir for f32 register-register with MIR tag {}", .{mir_tag}), |
| 3628 | | // }, |
| 3629 | | // .f64 => switch (mir_tag) { |
| 3630 | | // .add => Mir.Inst.Tag.add_f64, |
| 3631 | | // .cmp => Mir.Inst.Tag.cmp_f64, |
| 3632 | | // else => return self.fail("TODO genBinOpMir for f64 register-register with MIR tag {}", .{mir_tag}), |
| 3633 | | // }, |
| 3634 | | // else => return self.fail("TODO genBinOpMir for float register-register and type {}", .{dst_ty.fmtDebug()}), |
| 3635 | | // }; |
| 3636 | | // _ = try self.addInst(.{ |
| 3637 | | // .tag = actual_tag, |
| 3638 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 3639 | | // .reg1 = dst_reg.to128(), |
| 3640 | | // .reg2 = src_reg.to128(), |
| 3641 | | // }), |
| 3642 | | // .data = undefined, |
| 3643 | | // }); |
| 3644 | | return; |
| 3550 | const actual_tag: Mir.Inst.Tag = switch (dst_ty.tag()) { |
| 3551 | .f32 => switch (mir_tag) { |
| 3552 | .add => .addss, |
| 3553 | .cmp => .cmpss, |
| 3554 | else => return self.fail( |
| 3555 | "TODO genBinOpMir for f32 register-register with MIR tag {}", |
| 3556 | .{mir_tag}, |
| 3557 | ), |
| 3558 | }, |
| 3559 | .f64 => switch (mir_tag) { |
| 3560 | .add => .addsd, |
| 3561 | .cmp => .cmpsd, |
| 3562 | else => return self.fail( |
| 3563 | "TODO genBinOpMir for f64 register-register with MIR tag {}", |
| 3564 | .{mir_tag}, |
| 3565 | ), |
| 3566 | }, |
| 3567 | else => return self.fail( |
| 3568 | "TODO genBinOpMir for float register-register and type {}", |
| 3569 | .{dst_ty.fmtDebug()}, |
| 3570 | ), |
| 3571 | }; |
| 3572 | try self.asmRegisterRegister(actual_tag, dst_reg.to128(), src_reg.to128()); |
| 3645 | 3573 | } |
| 3646 | 3574 | |
| 3647 | 3575 | return self.fail("TODO genBinOpMir for float register-register and no intrinsics", .{}); |
| 3648 | 3576 | }, |
| 3649 | | else => { |
| 3650 | | _ = src_reg; |
| 3651 | | // _ = try self.addInst(.{ |
| 3652 | | // .tag = mir_tag, |
| 3653 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 3654 | | // .reg1 = registerAlias(dst_reg, abi_size), |
| 3655 | | // .reg2 = registerAlias(src_reg, abi_size), |
| 3656 | | // }), |
| 3657 | | // .data = undefined, |
| 3658 | | // }); |
| 3659 | | }, |
| 3577 | else => try self.asmRegisterRegister( |
| 3578 | mir_tag, |
| 3579 | registerAlias(dst_reg, abi_size), |
| 3580 | registerAlias(src_reg, abi_size), |
| 3581 | ), |
| 3660 | 3582 | }, |
| 3661 | 3583 | .immediate => |imm| { |
| 3662 | 3584 | _ = imm; |
| ... | ... | @@ -3777,7 +3699,6 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu |
| 3777 | 3699 | /// Does not support byte-size operands. |
| 3778 | 3700 | fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void { |
| 3779 | 3701 | const abi_size = @intCast(u32, dst_ty.abiSize(self.target.*)); |
| 3780 | | _ = abi_size; |
| 3781 | 3702 | switch (dst_mcv) { |
| 3782 | 3703 | .none => unreachable, |
| 3783 | 3704 | .undef => unreachable, |
| ... | ... | @@ -3792,18 +3713,11 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 3792 | 3713 | .dead, .unreach => unreachable, |
| 3793 | 3714 | .ptr_stack_offset => unreachable, |
| 3794 | 3715 | .register_overflow => unreachable, |
| 3795 | | .register => |src_reg| { |
| 3796 | | _ = src_reg; |
| 3797 | | // register, register |
| 3798 | | // _ = try self.addInst(.{ |
| 3799 | | // .tag = .imul_complex, |
| 3800 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 3801 | | // .reg1 = registerAlias(dst_reg, abi_size), |
| 3802 | | // .reg2 = registerAlias(src_reg, abi_size), |
| 3803 | | // }), |
| 3804 | | // .data = undefined, |
| 3805 | | // }); |
| 3806 | | }, |
| 3716 | .register => |src_reg| try self.asmRegisterRegister( |
| 3717 | .imul, |
| 3718 | registerAlias(dst_reg, abi_size), |
| 3719 | registerAlias(src_reg, abi_size), |
| 3720 | ), |
| 3807 | 3721 | .immediate => |imm| { |
| 3808 | 3722 | // TODO take into account the type's ABI size when selecting the register alias |
| 3809 | 3723 | // register, immediate |
| ... | ... | @@ -3992,20 +3906,12 @@ fn genVarDbgInfo( |
| 3992 | 3906 | } |
| 3993 | 3907 | |
| 3994 | 3908 | fn airTrap(self: *Self) !void { |
| 3995 | | // _ = try self.addInst(.{ |
| 3996 | | // .tag = .ud, |
| 3997 | | // .ops = Mir.Inst.Ops.encode(.{}), |
| 3998 | | // .data = undefined, |
| 3999 | | // }); |
| 3909 | try self.asmNone(.ud2); |
| 4000 | 3910 | return self.finishAirBookkeeping(); |
| 4001 | 3911 | } |
| 4002 | 3912 | |
| 4003 | 3913 | fn airBreakpoint(self: *Self) !void { |
| 4004 | | // _ = try self.addInst(.{ |
| 4005 | | // .tag = .interrupt, |
| 4006 | | // .ops = Mir.Inst.Ops.encode(.{}), |
| 4007 | | // .data = undefined, |
| 4008 | | // }); |
| 3914 | try self.asmNone(.int3); |
| 4009 | 3915 | return self.finishAirBookkeeping(); |
| 4010 | 3916 | } |
| 4011 | 3917 | |
| ... | ... | @@ -4117,13 +4023,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4117 | 4023 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| 4118 | 4024 | const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl); |
| 4119 | 4025 | const atom = elf_file.getAtom(atom_index); |
| 4120 | | const got_addr = @intCast(i32, atom.getOffsetTableAddress(elf_file)); |
| 4121 | | _ = got_addr; |
| 4122 | | // _ = try self.addInst(.{ |
| 4123 | | // .tag = .call, |
| 4124 | | // .ops = Mir.Inst.Ops.encode(.{ .flags = 0b01 }), |
| 4125 | | // .data = .{ .disp = got_addr }, |
| 4126 | | // }); |
| 4026 | const got_addr = atom.getOffsetTableAddress(elf_file); |
| 4027 | try self.asmImmediate(.call, Immediate.s(@intCast(i32, got_addr))); |
| 4127 | 4028 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| 4128 | 4029 | const atom_index = try coff_file.getOrCreateAtomForDecl(func.owner_decl); |
| 4129 | 4030 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; |
| ... | ... | @@ -4133,14 +4034,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4133 | 4034 | .sym_index = sym_index, |
| 4134 | 4035 | }, |
| 4135 | 4036 | }); |
| 4136 | | // _ = try self.addInst(.{ |
| 4137 | | // .tag = .call, |
| 4138 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 4139 | | // .reg1 = .rax, |
| 4140 | | // .flags = 0b01, |
| 4141 | | // }), |
| 4142 | | // .data = undefined, |
| 4143 | | // }); |
| 4037 | try self.asmRegister(.call, .rax); |
| 4144 | 4038 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 4145 | 4039 | const atom_index = try macho_file.getOrCreateAtomForDecl(func.owner_decl); |
| 4146 | 4040 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; |
| ... | ... | @@ -4150,14 +4044,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4150 | 4044 | .sym_index = sym_index, |
| 4151 | 4045 | }, |
| 4152 | 4046 | }); |
| 4153 | | // _ = try self.addInst(.{ |
| 4154 | | // .tag = .call, |
| 4155 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 4156 | | // .reg1 = .rax, |
| 4157 | | // .flags = 0b01, |
| 4158 | | // }), |
| 4159 | | // .data = undefined, |
| 4160 | | // }); |
| 4047 | try self.asmRegister(.call, .rax); |
| 4161 | 4048 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { |
| 4162 | 4049 | const decl_block_index = try p9.seeDecl(func.owner_decl); |
| 4163 | 4050 | const decl_block = p9.getDeclBlock(decl_block_index); |
| ... | ... | @@ -4166,12 +4053,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4166 | 4053 | const got_addr = p9.bases.data; |
| 4167 | 4054 | const got_index = decl_block.got_index.?; |
| 4168 | 4055 | const fn_got_addr = got_addr + got_index * ptr_bytes; |
| 4169 | | _ = fn_got_addr; |
| 4170 | | // _ = try self.addInst(.{ |
| 4171 | | // .tag = .call, |
| 4172 | | // .ops = Mir.Inst.Ops.encode(.{ .flags = 0b01 }), |
| 4173 | | // .data = .{ .disp = @intCast(i32, fn_got_addr) }, |
| 4174 | | // }); |
| 4056 | try self.asmImmediate(.call, Immediate.s(@intCast(i32, fn_got_addr))); |
| 4175 | 4057 | } else unreachable; |
| 4176 | 4058 | } else if (func_value.castTag(.extern_fn)) |func_payload| { |
| 4177 | 4059 | const extern_fn = func_payload.data; |
| ... | ... | @@ -4191,14 +4073,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4191 | 4073 | .sym_index = sym_index, |
| 4192 | 4074 | }, |
| 4193 | 4075 | }); |
| 4194 | | // _ = try self.addInst(.{ |
| 4195 | | // .tag = .call, |
| 4196 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 4197 | | // .reg1 = .rax, |
| 4198 | | // .flags = 0b01, |
| 4199 | | // }), |
| 4200 | | // .data = undefined, |
| 4201 | | // }); |
| 4076 | try self.asmRegister(.call, .rax); |
| 4202 | 4077 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 4203 | 4078 | const sym_index = try macho_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); |
| 4204 | 4079 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); |
| ... | ... | @@ -4223,23 +4098,12 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4223 | 4098 | assert(ty.zigTypeTag() == .Pointer); |
| 4224 | 4099 | const mcv = try self.resolveInst(callee); |
| 4225 | 4100 | try self.genSetReg(Type.initTag(.usize), .rax, mcv); |
| 4226 | | // _ = try self.addInst(.{ |
| 4227 | | // .tag = .call, |
| 4228 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 4229 | | // .reg1 = .rax, |
| 4230 | | // .flags = 0b01, |
| 4231 | | // }), |
| 4232 | | // .data = undefined, |
| 4233 | | // }); |
| 4101 | try self.asmRegister(.call, .rax); |
| 4234 | 4102 | } |
| 4235 | 4103 | |
| 4236 | 4104 | if (info.stack_byte_count > 0) { |
| 4237 | 4105 | // Readjust the stack |
| 4238 | | // _ = try self.addInst(.{ |
| 4239 | | // .tag = .add, |
| 4240 | | // .ops = Mir.Inst.Ops.encode(.{ .reg1 = .rsp }), |
| 4241 | | // .data = .{ .imm = info.stack_byte_count }, |
| 4242 | | // }); |
| 4106 | try self.asmRegisterImmediate(.add, .rsp, Immediate.u(info.stack_byte_count)); |
| 4243 | 4107 | } |
| 4244 | 4108 | |
| 4245 | 4109 | const result: MCValue = result: { |
| ... | ... | @@ -4296,12 +4160,12 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4296 | 4160 | // TODO when implementing defer, this will need to jump to the appropriate defer expression. |
| 4297 | 4161 | // TODO optimization opportunity: figure out when we can emit this as a 2 byte instruction |
| 4298 | 4162 | // which is available if the jump is 127 bytes or less forward. |
| 4299 | | // const jmp_reloc = try self.addInst(.{ |
| 4300 | | // .tag = .jmp, |
| 4301 | | // .ops = Mir.Inst.Ops.encode(.{}), |
| 4302 | | // .data = .{ .inst = undefined }, |
| 4303 | | // }); |
| 4304 | | // try self.exitlude_jump_relocs.append(self.gpa, jmp_reloc); |
| 4163 | const jmp_reloc = try self.addInst(.{ |
| 4164 | .tag = .jmp, |
| 4165 | .ops = .inst, |
| 4166 | .data = .{ .inst = undefined }, |
| 4167 | }); |
| 4168 | try self.exitlude_jump_relocs.append(self.gpa, jmp_reloc); |
| 4305 | 4169 | return self.finishAir(inst, .dead, .{ un_op, .none, .none }); |
| 4306 | 4170 | } |
| 4307 | 4171 | |
| ... | ... | @@ -4332,12 +4196,12 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 4332 | 4196 | // TODO when implementing defer, this will need to jump to the appropriate defer expression. |
| 4333 | 4197 | // TODO optimization opportunity: figure out when we can emit this as a 2 byte instruction |
| 4334 | 4198 | // which is available if the jump is 127 bytes or less forward. |
| 4335 | | // const jmp_reloc = try self.addInst(.{ |
| 4336 | | // .tag = .jmp, |
| 4337 | | // .ops = Mir.Inst.Ops.encode(.{}), |
| 4338 | | // .data = .{ .inst = undefined }, |
| 4339 | | // }); |
| 4340 | | // try self.exitlude_jump_relocs.append(self.gpa, jmp_reloc); |
| 4199 | const jmp_reloc = try self.addInst(.{ |
| 4200 | .tag = .jmp, |
| 4201 | .ops = .inst, |
| 4202 | .data = .{ .inst = undefined }, |
| 4203 | }); |
| 4204 | try self.exitlude_jump_relocs.append(self.gpa, jmp_reloc); |
| 4341 | 4205 | return self.finishAir(inst, .dead, .{ un_op, .none, .none }); |
| 4342 | 4206 | } |
| 4343 | 4207 | |
| ... | ... | @@ -4872,13 +4736,12 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void { |
| 4872 | 4736 | const loop = self.air.extraData(Air.Block, ty_pl.payload); |
| 4873 | 4737 | const body = self.air.extra[loop.end..][0..loop.data.body_len]; |
| 4874 | 4738 | const jmp_target = @intCast(u32, self.mir_instructions.len); |
| 4875 | | _ = jmp_target; |
| 4876 | 4739 | try self.genBody(body); |
| 4877 | | // _ = try self.addInst(.{ |
| 4878 | | // .tag = .jmp, |
| 4879 | | // .ops = Mir.Inst.Ops.encode(.{}), |
| 4880 | | // .data = .{ .inst = jmp_target }, |
| 4881 | | // }); |
| 4740 | _ = try self.addInst(.{ |
| 4741 | .tag = .jmp, |
| 4742 | .ops = .inst, |
| 4743 | .data = .{ .inst = jmp_target }, |
| 4744 | }); |
| 4882 | 4745 | return self.finishAirBookkeeping(); |
| 4883 | 4746 | } |
| 4884 | 4747 | |
| ... | ... | @@ -4923,25 +4786,16 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u |
| 4923 | 4786 | .none => unreachable, |
| 4924 | 4787 | .undef => unreachable, |
| 4925 | 4788 | .dead, .unreach => unreachable, |
| 4926 | | .immediate => |imm| { |
| 4927 | | _ = imm; |
| 4928 | | // _ = try self.addInst(.{ |
| 4929 | | // .tag = .xor, |
| 4930 | | // .ops = Mir.Inst.Ops.encode(.{ .reg1 = registerAlias(cond_reg, abi_size) }), |
| 4931 | | // .data = .{ .imm = @intCast(u32, imm) }, |
| 4932 | | // }); |
| 4933 | | }, |
| 4934 | | .register => |reg| { |
| 4935 | | _ = reg; |
| 4936 | | // _ = try self.addInst(.{ |
| 4937 | | // .tag = .xor, |
| 4938 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 4939 | | // .reg1 = registerAlias(cond_reg, abi_size), |
| 4940 | | // .reg2 = registerAlias(reg, abi_size), |
| 4941 | | // }), |
| 4942 | | // .data = undefined, |
| 4943 | | // }); |
| 4944 | | }, |
| 4789 | .immediate => |imm| try self.asmRegisterImmediate( |
| 4790 | .xor, |
| 4791 | registerAlias(cond_reg, abi_size), |
| 4792 | Immediate.u(imm), |
| 4793 | ), |
| 4794 | .register => |reg| try self.asmRegisterRegister( |
| 4795 | .xor, |
| 4796 | registerAlias(cond_reg, abi_size), |
| 4797 | registerAlias(reg, abi_size), |
| 4798 | ), |
| 4945 | 4799 | .stack_offset => { |
| 4946 | 4800 | if (abi_size <= 8) { |
| 4947 | 4801 | const reg = try self.copyToTmpRegister(ty, case); |
| ... | ... | @@ -5223,12 +5077,12 @@ fn brVoid(self: *Self, block: Air.Inst.Index) !void { |
| 5223 | 5077 | // Emit a jump with a relocation. It will be patched up after the block ends. |
| 5224 | 5078 | try block_data.relocs.ensureUnusedCapacity(self.gpa, 1); |
| 5225 | 5079 | // Leave the jump offset undefined |
| 5226 | | // const jmp_reloc = try self.addInst(.{ |
| 5227 | | // .tag = .jmp, |
| 5228 | | // .ops = Mir.Inst.Ops.encode(.{}), |
| 5229 | | // .data = .{ .inst = undefined }, |
| 5230 | | // }); |
| 5231 | | // block_data.relocs.appendAssumeCapacity(jmp_reloc); |
| 5080 | const jmp_reloc = try self.addInst(.{ |
| 5081 | .tag = .jmp, |
| 5082 | .ops = .inst, |
| 5083 | .data = .{ .inst = undefined }, |
| 5084 | }); |
| 5085 | block_data.relocs.appendAssumeCapacity(jmp_reloc); |
| 5232 | 5086 | } |
| 5233 | 5087 | |
| 5234 | 5088 | fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| ... | ... | @@ -5463,11 +5317,15 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 5463 | 5317 | switch (ty.zigTypeTag()) { |
| 5464 | 5318 | .Float => { |
| 5465 | 5319 | if (intrinsicsAllowed(self.target.*, ty)) { |
| 5466 | | // const tag: Mir.Inst.Tag = switch (ty.tag()) { |
| 5467 | | // .f32 => Mir.Inst.Tag.mov_f32, |
| 5468 | | // .f64 => Mir.Inst.Tag.mov_f64, |
| 5469 | | // else => return self.fail("TODO genSetStackArg for register for type {}", .{ty.fmtDebug()}), |
| 5470 | | // }; |
| 5320 | const tag: Mir.Inst.Tag = switch (ty.tag()) { |
| 5321 | .f32 => .movss, |
| 5322 | .f64 => .movsd, |
| 5323 | else => return self.fail( |
| 5324 | "TODO genSetStackArg for register for type {}", |
| 5325 | .{ty.fmtDebug()}, |
| 5326 | ), |
| 5327 | }; |
| 5328 | _ = tag; |
| 5471 | 5329 | _ = reg; |
| 5472 | 5330 | // _ = try self.addInst(.{ |
| 5473 | 5331 | // .tag = tag, |
| ... | ... | @@ -5550,7 +5408,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 5550 | 5408 | const overflow_bit_ty = ty.structFieldType(1); |
| 5551 | 5409 | const overflow_bit_offset = ty.structFieldOffset(1, self.target.*); |
| 5552 | 5410 | const tmp_reg = try self.register_manager.allocReg(null, gp); |
| 5553 | | try self.asmSetCCRegister(tmp_reg.to8(), ro.eflags); |
| 5411 | try self.asmSetccRegister(tmp_reg.to8(), ro.eflags); |
| 5554 | 5412 | |
| 5555 | 5413 | return self.genSetStack( |
| 5556 | 5414 | overflow_bit_ty, |
| ... | ... | @@ -6039,7 +5897,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 6039 | 5897 | } |
| 6040 | 5898 | }, |
| 6041 | 5899 | .eflags => |cc| { |
| 6042 | | return self.asmSetCCRegister(reg.to8(), cc); |
| 5900 | return self.asmSetccRegister(reg.to8(), cc); |
| 6043 | 5901 | }, |
| 6044 | 5902 | .immediate => |x| { |
| 6045 | 5903 | if (x == 0) { |
| ... | ... | @@ -6069,63 +5927,38 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 6069 | 5927 | .Int => switch (ty.intInfo(self.target.*).signedness) { |
| 6070 | 5928 | .signed => { |
| 6071 | 5929 | if (abi_size <= 4) { |
| 6072 | | // _ = try self.addInst(.{ |
| 6073 | | // .tag = .mov_sign_extend, |
| 6074 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 6075 | | // .reg1 = reg.to64(), |
| 6076 | | // .reg2 = registerAlias(src_reg, abi_size), |
| 6077 | | // }), |
| 6078 | | // .data = undefined, |
| 6079 | | // }); |
| 6080 | | return; |
| 5930 | return self.asmRegisterRegister( |
| 5931 | .movsx, |
| 5932 | reg.to64(), |
| 5933 | registerAlias(src_reg, abi_size), |
| 5934 | ); |
| 6081 | 5935 | } |
| 6082 | 5936 | }, |
| 6083 | 5937 | .unsigned => { |
| 6084 | 5938 | if (abi_size <= 2) { |
| 6085 | | // _ = try self.addInst(.{ |
| 6086 | | // .tag = .mov_zero_extend, |
| 6087 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 6088 | | // .reg1 = reg.to64(), |
| 6089 | | // .reg2 = registerAlias(src_reg, abi_size), |
| 6090 | | // }), |
| 6091 | | // .data = undefined, |
| 6092 | | // }); |
| 6093 | | return; |
| 5939 | return self.asmRegisterRegister( |
| 5940 | .movzx, |
| 5941 | reg.to64(), |
| 5942 | registerAlias(src_reg, abi_size), |
| 5943 | ); |
| 6094 | 5944 | } |
| 6095 | 5945 | }, |
| 6096 | 5946 | }, |
| 6097 | 5947 | .Float => { |
| 6098 | 5948 | if (intrinsicsAllowed(self.target.*, ty)) { |
| 6099 | | // const tag: Mir.Inst.Tag = switch (ty.tag()) { |
| 6100 | | // .f32 => Mir.Inst.Tag.mov_f32, |
| 6101 | | // .f64 => Mir.Inst.Tag.mov_f64, |
| 6102 | | // else => return self.fail("TODO genSetReg from register for {}", .{ty.fmtDebug()}), |
| 6103 | | // }; |
| 6104 | | // _ = try self.addInst(.{ |
| 6105 | | // .tag = tag, |
| 6106 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 6107 | | // .reg1 = reg.to128(), |
| 6108 | | // .reg2 = src_reg.to128(), |
| 6109 | | // .flags = 0b10, |
| 6110 | | // }), |
| 6111 | | // .data = undefined, |
| 6112 | | // }); |
| 6113 | | return; |
| 5949 | const tag: Mir.Inst.Tag = switch (ty.tag()) { |
| 5950 | .f32 => .movss, |
| 5951 | .f64 => .movsd, |
| 5952 | else => return self.fail("TODO genSetReg from register for {}", .{ty.fmtDebug()}), |
| 5953 | }; |
| 5954 | return self.asmRegisterRegister(tag, reg.to128(), src_reg.to128()); |
| 6114 | 5955 | } |
| 6115 | | |
| 6116 | 5956 | return self.fail("TODO genSetReg from register for float with no intrinsics", .{}); |
| 6117 | 5957 | }, |
| 6118 | 5958 | else => {}, |
| 6119 | 5959 | } |
| 6120 | 5960 | |
| 6121 | | // _ = try self.addInst(.{ |
| 6122 | | // .tag = .mov, |
| 6123 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 6124 | | // .reg1 = registerAlias(reg, abi_size), |
| 6125 | | // .reg2 = registerAlias(src_reg, abi_size), |
| 6126 | | // }), |
| 6127 | | // .data = undefined, |
| 6128 | | // }); |
| 5961 | try self.asmRegisterRegister(.mov, registerAlias(reg, abi_size), registerAlias(src_reg, abi_size)); |
| 6129 | 5962 | }, |
| 6130 | 5963 | .linker_load => { |
| 6131 | 5964 | switch (ty.zigTypeTag()) { |
| ... | ... | @@ -6214,7 +6047,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 6214 | 6047 | } else { |
| 6215 | 6048 | // If this is RAX, we can use a direct load. |
| 6216 | 6049 | // Otherwise, we need to load the address, then indirectly load the value. |
| 6217 | | if (reg.id() == 0) { |
| 6050 | if (reg.to64() == .rax) { |
| 6218 | 6051 | // movabs rax, ds:moffs64 |
| 6219 | 6052 | // const payload = try self.addExtra(Mir.Imm64.encode(x)); |
| 6220 | 6053 | // _ = try self.addInst(.{ |