| ... | @@ -2097,11 +2097,11 @@ fn gen(self: *CodeGen) InnerError!void { | ... | @@ -2097,11 +2097,11 @@ fn gen(self: *CodeGen) InnerError!void { |
| 2097 | // The address where to store the return value for the caller is in a | 2097 | // The address where to store the return value for the caller is in a |
| 2098 | // register which the callee is free to clobber. Therefore, we purposely | 2098 | // register which the callee is free to clobber. Therefore, we purposely |
| 2099 | // spill it to stack immediately. | 2099 | // spill it to stack immediately. |
| 2100 | const frame_index = try self.allocFrameIndex(.initSpill(Type.usize, zcu)); | 2100 | const frame_index = try self.allocFrameIndex(.initSpill(.usize, zcu)); |
| 2101 | try self.genSetMem( | 2101 | try self.genSetMem( |
| 2102 | .{ .frame = frame_index }, | 2102 | .{ .frame = frame_index }, |
| 2103 | 0, | 2103 | 0, |
| 2104 | Type.usize, | 2104 | .usize, |
| 2105 | self.ret_mcv.long.address().offset(-self.ret_mcv.short.indirect.off), | 2105 | self.ret_mcv.long.address().offset(-self.ret_mcv.short.indirect.off), |
| 2106 | .{}, | 2106 | .{}, |
| 2107 | ); | 2107 | ); |
| ... | @@ -2122,13 +2122,7 @@ fn gen(self: *CodeGen) InnerError!void { | ... | @@ -2122,13 +2122,7 @@ fn gen(self: *CodeGen) InnerError!void { |
| 2122 | info.reg_save_area = .{ .index = reg_save_area_fi }; | 2122 | info.reg_save_area = .{ .index = reg_save_area_fi }; |
| 2123 | | 2123 | |
| 2124 | for (abi.SysV.c_abi_int_param_regs[info.gp_count..], info.gp_count..) |reg, reg_i| | 2124 | for (abi.SysV.c_abi_int_param_regs[info.gp_count..], info.gp_count..) |reg, reg_i| |
| 2125 | try self.genSetMem( | 2125 | try self.genSetMem(.{ .frame = reg_save_area_fi }, @intCast(reg_i * 8), .usize, .{ .register = reg }, .{}); |
| 2126 | .{ .frame = reg_save_area_fi }, | | |
| 2127 | @intCast(reg_i * 8), | | |
| 2128 | Type.usize, | | |
| 2129 | .{ .register = reg }, | | |
| 2130 | .{}, | | |
| 2131 | ); | | |
| 2132 | | 2126 | |
| 2133 | try self.asmRegisterImmediate(.{ ._, .cmp }, .al, .u(info.fp_count)); | 2127 | try self.asmRegisterImmediate(.{ ._, .cmp }, .al, .u(info.fp_count)); |
| 2134 | const skip_sse_reloc = try self.asmJccReloc(.na, undefined); | 2128 | const skip_sse_reloc = try self.asmJccReloc(.na, undefined); |
| ... | @@ -2556,6 +2550,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2556,6 +2550,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2556 | .{ .ops = &.{ .xmm, .xmm, .{ .implicit = 0 } } }, | 2550 | .{ .ops = &.{ .xmm, .xmm, .{ .implicit = 0 } } }, |
| 2557 | }, | 2551 | }, |
| 2558 | }, | 2552 | }, |
| | 2553 | .{ |
| | 2554 | .required_features = &.{.sse}, |
| | 2555 | .mir_tag = .{ ._ps, mir_tag }, |
| | 2556 | .patterns = &.{ |
| | 2557 | .{ .ops = &.{ .xmm, .{ .implicit = 0 }, .mem } }, |
| | 2558 | .{ .ops = &.{ .xmm, .mem, .{ .implicit = 0 } } }, |
| | 2559 | .{ .ops = &.{ .xmm, .{ .implicit = 0 }, .xmm } }, |
| | 2560 | .{ .ops = &.{ .xmm, .xmm, .{ .implicit = 0 } } }, |
| | 2561 | }, |
| | 2562 | }, |
| 2559 | .{ | 2563 | .{ |
| 2560 | .required_features = &.{.mmx}, | 2564 | .required_features = &.{.mmx}, |
| 2561 | .mir_tag = .{ .p_, mir_tag }, | 2565 | .mir_tag = .{ .p_, mir_tag }, |
| ... | @@ -2615,6 +2619,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2615,6 +2619,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2615 | .{ .ops = &.{ .xmm_limb, .{ .implicit = 0 }, .xmm_limb } }, | 2619 | .{ .ops = &.{ .xmm_limb, .{ .implicit = 0 }, .xmm_limb } }, |
| 2616 | }, | 2620 | }, |
| 2617 | }, | 2621 | }, |
| | 2622 | .{ |
| | 2623 | .required_features = &.{.sse}, |
| | 2624 | .loop = .bitwise, |
| | 2625 | .mir_tag = .{ ._ps, mir_tag }, |
| | 2626 | .patterns = &.{ |
| | 2627 | .{ .ops = &.{ .xmm_limb, .{ .implicit = 0 }, .mem_limb } }, |
| | 2628 | .{ .ops = &.{ .xmm_limb, .mem_limb, .{ .implicit = 0 } } }, |
| | 2629 | .{ .ops = &.{ .xmm_limb, .{ .implicit = 0 }, .xmm_limb } }, |
| | 2630 | }, |
| | 2631 | }, |
| 2618 | .{ | 2632 | .{ |
| 2619 | .required_features = &.{.mmx}, | 2633 | .required_features = &.{.mmx}, |
| 2620 | .loop = .bitwise, | 2634 | .loop = .bitwise, |
| ... | @@ -3070,11 +3084,58 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -3070,11 +3084,58 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 3070 | .{ .ops = &.{ .gpr_limb, .{ .implicit = 0 }, .gpr_limb } }, | 3084 | .{ .ops = &.{ .gpr_limb, .{ .implicit = 0 }, .gpr_limb } }, |
| 3071 | }, | 3085 | }, |
| 3072 | }, | 3086 | }, |
| 3073 | }, .{ .invert_result = switch (cmp_op) { | 3087 | .{ |
| 3074 | .eq => false, | 3088 | .scalar = .{ .any_int = .byte }, |
| 3075 | .neq => true, | 3089 | .clobbers = .{ .eflags = true }, |
| 3076 | else => unreachable, | 3090 | .loop = .elementwise, |
| 3077 | } }), | 3091 | .mir_tag = .{ ._, .cmp }, |
| | 3092 | .patterns = &.{ |
| | 3093 | .{ .ops = &.{ .cc_mask_limb, .mem_limb, .gpr_limb } }, |
| | 3094 | .{ .ops = &.{ .cc_mask_limb, .gpr_limb, .mem_limb } }, |
| | 3095 | .{ .ops = &.{ .cc_mask_limb, .gpr_limb, .gpr_limb } }, |
| | 3096 | }, |
| | 3097 | }, |
| | 3098 | .{ |
| | 3099 | .scalar = .{ .any_int = .word }, |
| | 3100 | .clobbers = .{ .eflags = true }, |
| | 3101 | .loop = .elementwise, |
| | 3102 | .mir_tag = .{ ._, .cmp }, |
| | 3103 | .patterns = &.{ |
| | 3104 | .{ .ops = &.{ .cc_mask_limb, .mem_limb, .gpr_limb } }, |
| | 3105 | .{ .ops = &.{ .cc_mask_limb, .gpr_limb, .mem_limb } }, |
| | 3106 | .{ .ops = &.{ .cc_mask_limb, .gpr_limb, .gpr_limb } }, |
| | 3107 | }, |
| | 3108 | }, |
| | 3109 | .{ |
| | 3110 | .scalar = .{ .any_int = .dword }, |
| | 3111 | .clobbers = .{ .eflags = true }, |
| | 3112 | .loop = .elementwise, |
| | 3113 | .mir_tag = .{ ._, .cmp }, |
| | 3114 | .patterns = &.{ |
| | 3115 | .{ .ops = &.{ .cc_mask_limb, .mem_limb, .gpr_limb } }, |
| | 3116 | .{ .ops = &.{ .cc_mask_limb, .gpr_limb, .mem_limb } }, |
| | 3117 | .{ .ops = &.{ .cc_mask_limb, .gpr_limb, .gpr_limb } }, |
| | 3118 | }, |
| | 3119 | }, |
| | 3120 | .{ |
| | 3121 | .scalar = .{ .any_int = .qword }, |
| | 3122 | .clobbers = .{ .eflags = true }, |
| | 3123 | .loop = .elementwise, |
| | 3124 | .mir_tag = .{ ._, .cmp }, |
| | 3125 | .patterns = &.{ |
| | 3126 | .{ .ops = &.{ .cc_mask_limb, .mem_limb, .gpr_limb } }, |
| | 3127 | .{ .ops = &.{ .cc_mask_limb, .gpr_limb, .mem_limb } }, |
| | 3128 | .{ .ops = &.{ .cc_mask_limb, .gpr_limb, .gpr_limb } }, |
| | 3129 | }, |
| | 3130 | }, |
| | 3131 | }, .{ |
| | 3132 | .cc = .e, |
| | 3133 | .invert_result = switch (cmp_op) { |
| | 3134 | .eq => false, |
| | 3135 | .neq => true, |
| | 3136 | else => unreachable, |
| | 3137 | }, |
| | 3138 | }), |
| 3078 | .gte => unreachable, | 3139 | .gte => unreachable, |
| 3079 | .gt => unreachable, | 3140 | .gt => unreachable, |
| 3080 | } | 3141 | } |
| ... | @@ -3242,7 +3303,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -3242,7 +3303,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 3242 | const opt_child_ty = opt_ty.optionalChild(zcu); | 3303 | const opt_child_ty = opt_ty.optionalChild(zcu); |
| 3243 | const opt_child_abi_size: i32 = @intCast(opt_child_ty.abiSize(zcu)); | 3304 | const opt_child_abi_size: i32 = @intCast(opt_child_ty.abiSize(zcu)); |
| 3244 | try ops[0].toOffset(opt_child_abi_size, cg); | 3305 | try ops[0].toOffset(opt_child_abi_size, cg); |
| 3245 | var has_value = try cg.tempFromValue(Type.bool, .{ .immediate = 1 }); | 3306 | var has_value = try cg.tempFromValue(.bool, .{ .immediate = 1 }); |
| 3246 | try ops[0].store(&has_value, cg); | 3307 | try ops[0].store(&has_value, cg); |
| 3247 | try has_value.die(cg); | 3308 | try has_value.die(cg); |
| 3248 | try ops[0].toOffset(-opt_child_abi_size, cg); | 3309 | try ops[0].toOffset(-opt_child_abi_size, cg); |
| ... | @@ -3426,7 +3487,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -3426,7 +3487,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 3426 | .array_to_slice => if (use_old) try cg.airArrayToSlice(inst) else { | 3487 | .array_to_slice => if (use_old) try cg.airArrayToSlice(inst) else { |
| 3427 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; | 3488 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; |
| 3428 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); | 3489 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); |
| 3429 | var len = try cg.tempFromValue(Type.usize, .{ | 3490 | var len = try cg.tempFromValue(.usize, .{ |
| 3430 | .immediate = cg.typeOf(ty_op.operand).childType(zcu).arrayLen(zcu), | 3491 | .immediate = cg.typeOf(ty_op.operand).childType(zcu).arrayLen(zcu), |
| 3431 | }); | 3492 | }); |
| 3432 | try ops[0].toPair(&len, cg); | 3493 | try ops[0].toPair(&len, cg); |
| ... | @@ -3510,17 +3571,11 @@ fn genLazy(self: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void { | ... | @@ -3510,17 +3571,11 @@ fn genLazy(self: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 3510 | try self.genSetMem( | 3571 | try self.genSetMem( |
| 3511 | .{ .reg = ret_reg }, | 3572 | .{ .reg = ret_reg }, |
| 3512 | 0, | 3573 | 0, |
| 3513 | Type.usize, | 3574 | .usize, |
| 3514 | .{ .register_offset = .{ .reg = data_reg, .off = data_off } }, | 3575 | .{ .register_offset = .{ .reg = data_reg, .off = data_off } }, |
| 3515 | .{}, | 3576 | .{}, |
| 3516 | ); | 3577 | ); |
| 3517 | try self.genSetMem( | 3578 | try self.genSetMem(.{ .reg = ret_reg }, 8, .usize, .{ .immediate = tag_name_len }, .{}); |
| 3518 | .{ .reg = ret_reg }, | | |
| 3519 | 8, | | |
| 3520 | Type.usize, | | |
| 3521 | .{ .immediate = tag_name_len }, | | |
| 3522 | .{}, | | |
| 3523 | ); | | |
| 3524 | | 3579 | |
| 3525 | exitlude_jump_reloc.* = try self.asmJmpReloc(undefined); | 3580 | exitlude_jump_reloc.* = try self.asmJmpReloc(undefined); |
| 3526 | self.performReloc(skip_reloc); | 3581 | self.performReloc(skip_reloc); |
| ... | @@ -4495,8 +4550,8 @@ fn airIntCast(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -4495,8 +4550,8 @@ fn airIntCast(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 4495 | high_mcv.getReg().? | 4550 | high_mcv.getReg().? |
| 4496 | else | 4551 | else |
| 4497 | try self.copyToTmpRegister(switch (src_int_info.signedness) { | 4552 | try self.copyToTmpRegister(switch (src_int_info.signedness) { |
| 4498 | .signed => Type.isize, | 4553 | .signed => .isize, |
| 4499 | .unsigned => Type.usize, | 4554 | .unsigned => .usize, |
| 4500 | }, high_mcv); | 4555 | }, high_mcv); |
| 4501 | const high_lock = self.register_manager.lockRegAssumeUnused(high_reg); | 4556 | const high_lock = self.register_manager.lockRegAssumeUnused(high_reg); |
| 4502 | defer self.register_manager.unlockReg(high_lock); | 4557 | defer self.register_manager.unlockReg(high_lock); |
| ... | @@ -4504,7 +4559,7 @@ fn airIntCast(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -4504,7 +4559,7 @@ fn airIntCast(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 4504 | const high_bits = src_int_info.bits % 64; | 4559 | const high_bits = src_int_info.bits % 64; |
| 4505 | if (high_bits > 0) { | 4560 | if (high_bits > 0) { |
| 4506 | try self.truncateRegister(src_ty, high_reg); | 4561 | try self.truncateRegister(src_ty, high_reg); |
| 4507 | const high_ty = if (dst_int_info.bits >= 64) Type.usize else dst_ty; | 4562 | const high_ty: Type = if (dst_int_info.bits >= 64) .usize else dst_ty; |
| 4508 | try self.genCopy(high_ty, high_mcv, .{ .register = high_reg }, .{}); | 4563 | try self.genCopy(high_ty, high_mcv, .{ .register = high_reg }, .{}); |
| 4509 | } | 4564 | } |
| 4510 | | 4565 | |
| ... | @@ -4513,13 +4568,7 @@ fn airIntCast(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -4513,13 +4568,7 @@ fn airIntCast(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 4513 | switch (extend) { | 4568 | switch (extend) { |
| 4514 | .signed => extend: { | 4569 | .signed => extend: { |
| 4515 | const extend_mcv = MCValue{ .register = high_reg }; | 4570 | const extend_mcv = MCValue{ .register = high_reg }; |
| 4516 | try self.genShiftBinOpMir( | 4571 | try self.genShiftBinOpMir(.{ ._r, .sa }, .isize, extend_mcv, .u8, .{ .immediate = 63 }); |
| 4517 | .{ ._r, .sa }, | | |
| 4518 | Type.isize, | | |
| 4519 | extend_mcv, | | |
| 4520 | Type.u8, | | |
| 4521 | .{ .immediate = 63 }, | | |
| 4522 | ); | | |
| 4523 | break :extend extend_mcv; | 4572 | break :extend extend_mcv; |
| 4524 | }, | 4573 | }, |
| 4525 | .unsigned => .{ .immediate = 0 }, | 4574 | .unsigned => .{ .immediate = 0 }, |
| ... | @@ -4621,7 +4670,7 @@ fn airTrunc(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -4621,7 +4670,7 @@ fn airTrunc(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 4621 | const splat_mcv = try self.genTypedValue(.fromInterned(splat_val)); | 4670 | const splat_mcv = try self.genTypedValue(.fromInterned(splat_val)); |
| 4622 | const splat_addr_mcv: MCValue = switch (splat_mcv) { | 4671 | const splat_addr_mcv: MCValue = switch (splat_mcv) { |
| 4623 | .memory, .indirect, .load_frame => splat_mcv.address(), | 4672 | .memory, .indirect, .load_frame => splat_mcv.address(), |
| 4624 | else => .{ .register = try self.copyToTmpRegister(Type.usize, splat_mcv.address()) }, | 4673 | else => .{ .register = try self.copyToTmpRegister(.usize, splat_mcv.address()) }, |
| 4625 | }; | 4674 | }; |
| 4626 | | 4675 | |
| 4627 | const dst_reg = dst_mcv.getReg().?; | 4676 | const dst_reg = dst_mcv.getReg().?; |
| ... | @@ -4837,7 +4886,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -4837,7 +4886,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 4837 | state: State, | 4886 | state: State, |
| 4838 | reloc: Mir.Inst.Index, | 4887 | reloc: Mir.Inst.Index, |
| 4839 | } = if (signed and tag == .div_floor) state: { | 4888 | } = if (signed and tag == .div_floor) state: { |
| 4840 | const frame_index = try self.allocFrameIndex(.initType(Type.usize, zcu)); | 4889 | const frame_index = try self.allocFrameIndex(.initType(.usize, zcu)); |
| 4841 | try self.asmMemoryImmediate( | 4890 | try self.asmMemoryImmediate( |
| 4842 | .{ ._, .mov }, | 4891 | .{ ._, .mov }, |
| 4843 | .{ .base = .{ .frame = frame_index }, .mod = .{ .rm = .{ .size = .qword } } }, | 4892 | .{ .base = .{ .frame = frame_index }, .mod = .{ .rm = .{ .size = .qword } } }, |
| ... | @@ -4852,7 +4901,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -4852,7 +4901,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 4852 | const mat_lhs_mcv = switch (lhs_mcv) { | 4901 | const mat_lhs_mcv = switch (lhs_mcv) { |
| 4853 | .load_symbol => mat_lhs_mcv: { | 4902 | .load_symbol => mat_lhs_mcv: { |
| 4854 | // TODO clean this up! | 4903 | // TODO clean this up! |
| 4855 | const addr_reg = try self.copyToTmpRegister(Type.usize, lhs_mcv.address()); | 4904 | const addr_reg = try self.copyToTmpRegister(.usize, lhs_mcv.address()); |
| 4856 | break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; | 4905 | break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; |
| 4857 | }, | 4906 | }, |
| 4858 | else => lhs_mcv, | 4907 | else => lhs_mcv, |
| ... | @@ -4876,7 +4925,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -4876,7 +4925,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 4876 | const mat_rhs_mcv = switch (rhs_mcv) { | 4925 | const mat_rhs_mcv = switch (rhs_mcv) { |
| 4877 | .load_symbol => mat_rhs_mcv: { | 4926 | .load_symbol => mat_rhs_mcv: { |
| 4878 | // TODO clean this up! | 4927 | // TODO clean this up! |
| 4879 | const addr_reg = try self.copyToTmpRegister(Type.usize, rhs_mcv.address()); | 4928 | const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address()); |
| 4880 | break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; | 4929 | break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; |
| 4881 | }, | 4930 | }, |
| 4882 | else => rhs_mcv, | 4931 | else => rhs_mcv, |
| ... | @@ -4975,7 +5024,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -4975,7 +5024,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 4975 | const mat_rhs_mcv = switch (rhs_mcv) { | 5024 | const mat_rhs_mcv = switch (rhs_mcv) { |
| 4976 | .load_symbol => mat_rhs_mcv: { | 5025 | .load_symbol => mat_rhs_mcv: { |
| 4977 | // TODO clean this up! | 5026 | // TODO clean this up! |
| 4978 | const addr_reg = try self.copyToTmpRegister(Type.usize, rhs_mcv.address()); | 5027 | const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address()); |
| 4979 | break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; | 5028 | break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; |
| 4980 | }, | 5029 | }, |
| 4981 | else => rhs_mcv, | 5030 | else => rhs_mcv, |
| ... | @@ -5062,22 +5111,10 @@ fn airAddSat(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -5062,22 +5111,10 @@ fn airAddSat(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 5062 | const reg_extra_bits = self.regExtraBits(ty); | 5111 | const reg_extra_bits = self.regExtraBits(ty); |
| 5063 | const cc: Condition = if (ty.isSignedInt(zcu)) cc: { | 5112 | const cc: Condition = if (ty.isSignedInt(zcu)) cc: { |
| 5064 | if (reg_extra_bits > 0) { | 5113 | if (reg_extra_bits > 0) { |
| 5065 | try self.genShiftBinOpMir( | 5114 | try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .u8, .{ .immediate = reg_extra_bits }); |
| 5066 | .{ ._l, .sa }, | | |
| 5067 | ty, | | |
| 5068 | dst_mcv, | | |
| 5069 | Type.u8, | | |
| 5070 | .{ .immediate = reg_extra_bits }, | | |
| 5071 | ); | | |
| 5072 | } | 5115 | } |
| 5073 | try self.genSetReg(limit_reg, ty, dst_mcv, .{}); | 5116 | try self.genSetReg(limit_reg, ty, dst_mcv, .{}); |
| 5074 | try self.genShiftBinOpMir( | 5117 | try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .u8, .{ .immediate = reg_bits - 1 }); |
| 5075 | .{ ._r, .sa }, | | |
| 5076 | ty, | | |
| 5077 | limit_mcv, | | |
| 5078 | Type.u8, | | |
| 5079 | .{ .immediate = reg_bits - 1 }, | | |
| 5080 | ); | | |
| 5081 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ | 5118 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ |
| 5082 | .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, | 5119 | .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, |
| 5083 | }); | 5120 | }); |
| ... | @@ -5087,13 +5124,7 @@ fn airAddSat(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -5087,13 +5124,7 @@ fn airAddSat(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 5087 | const shifted_rhs_lock = self.register_manager.lockRegAssumeUnused(shifted_rhs_reg); | 5124 | const shifted_rhs_lock = self.register_manager.lockRegAssumeUnused(shifted_rhs_reg); |
| 5088 | defer self.register_manager.unlockReg(shifted_rhs_lock); | 5125 | defer self.register_manager.unlockReg(shifted_rhs_lock); |
| 5089 | | 5126 | |
| 5090 | try self.genShiftBinOpMir( | 5127 | try self.genShiftBinOpMir(.{ ._l, .sa }, ty, shifted_rhs_mcv, .u8, .{ .immediate = reg_extra_bits }); |
| 5091 | .{ ._l, .sa }, | | |
| 5092 | ty, | | |
| 5093 | shifted_rhs_mcv, | | |
| 5094 | Type.u8, | | |
| 5095 | .{ .immediate = reg_extra_bits }, | | |
| 5096 | ); | | |
| 5097 | try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, shifted_rhs_mcv); | 5128 | try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, shifted_rhs_mcv); |
| 5098 | } else try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv); | 5129 | } else try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv); |
| 5099 | break :cc .o; | 5130 | break :cc .o; |
| ... | @@ -5117,13 +5148,8 @@ fn airAddSat(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -5117,13 +5148,8 @@ fn airAddSat(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 5117 | registerAlias(limit_reg, cmov_abi_size), | 5148 | registerAlias(limit_reg, cmov_abi_size), |
| 5118 | ); | 5149 | ); |
| 5119 | | 5150 | |
| 5120 | if (reg_extra_bits > 0 and ty.isSignedInt(zcu)) try self.genShiftBinOpMir( | 5151 | if (reg_extra_bits > 0 and ty.isSignedInt(zcu)) |
| 5121 | .{ ._r, .sa }, | 5152 | try self.genShiftBinOpMir(.{ ._r, .sa }, ty, dst_mcv, .u8, .{ .immediate = reg_extra_bits }); |
| 5122 | ty, | | |
| 5123 | dst_mcv, | | |
| 5124 | Type.u8, | | |
| 5125 | .{ .immediate = reg_extra_bits }, | | |
| 5126 | ); | | |
| 5127 | | 5153 | |
| 5128 | return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none }); | 5154 | return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 5129 | } | 5155 | } |
| ... | @@ -5163,22 +5189,10 @@ fn airSubSat(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -5163,22 +5189,10 @@ fn airSubSat(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 5163 | const reg_extra_bits = self.regExtraBits(ty); | 5189 | const reg_extra_bits = self.regExtraBits(ty); |
| 5164 | const cc: Condition = if (ty.isSignedInt(zcu)) cc: { | 5190 | const cc: Condition = if (ty.isSignedInt(zcu)) cc: { |
| 5165 | if (reg_extra_bits > 0) { | 5191 | if (reg_extra_bits > 0) { |
| 5166 | try self.genShiftBinOpMir( | 5192 | try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .u8, .{ .immediate = reg_extra_bits }); |
| 5167 | .{ ._l, .sa }, | | |
| 5168 | ty, | | |
| 5169 | dst_mcv, | | |
| 5170 | Type.u8, | | |
| 5171 | .{ .immediate = reg_extra_bits }, | | |
| 5172 | ); | | |
| 5173 | } | 5193 | } |
| 5174 | try self.genSetReg(limit_reg, ty, dst_mcv, .{}); | 5194 | try self.genSetReg(limit_reg, ty, dst_mcv, .{}); |
| 5175 | try self.genShiftBinOpMir( | 5195 | try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .u8, .{ .immediate = reg_bits - 1 }); |
| 5176 | .{ ._r, .sa }, | | |
| 5177 | ty, | | |
| 5178 | limit_mcv, | | |
| 5179 | Type.u8, | | |
| 5180 | .{ .immediate = reg_bits - 1 }, | | |
| 5181 | ); | | |
| 5182 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ | 5196 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ |
| 5183 | .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, | 5197 | .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, |
| 5184 | }); | 5198 | }); |
| ... | @@ -5188,13 +5202,7 @@ fn airSubSat(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -5188,13 +5202,7 @@ fn airSubSat(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 5188 | const shifted_rhs_lock = self.register_manager.lockRegAssumeUnused(shifted_rhs_reg); | 5202 | const shifted_rhs_lock = self.register_manager.lockRegAssumeUnused(shifted_rhs_reg); |
| 5189 | defer self.register_manager.unlockReg(shifted_rhs_lock); | 5203 | defer self.register_manager.unlockReg(shifted_rhs_lock); |
| 5190 | | 5204 | |
| 5191 | try self.genShiftBinOpMir( | 5205 | try self.genShiftBinOpMir(.{ ._l, .sa }, ty, shifted_rhs_mcv, .u8, .{ .immediate = reg_extra_bits }); |
| 5192 | .{ ._l, .sa }, | | |
| 5193 | ty, | | |
| 5194 | shifted_rhs_mcv, | | |
| 5195 | Type.u8, | | |
| 5196 | .{ .immediate = reg_extra_bits }, | | |
| 5197 | ); | | |
| 5198 | try self.genBinOpMir(.{ ._, .sub }, ty, dst_mcv, shifted_rhs_mcv); | 5206 | try self.genBinOpMir(.{ ._, .sub }, ty, dst_mcv, shifted_rhs_mcv); |
| 5199 | } else try self.genBinOpMir(.{ ._, .sub }, ty, dst_mcv, rhs_mcv); | 5207 | } else try self.genBinOpMir(.{ ._, .sub }, ty, dst_mcv, rhs_mcv); |
| 5200 | break :cc .o; | 5208 | break :cc .o; |
| ... | @@ -5211,13 +5219,8 @@ fn airSubSat(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -5211,13 +5219,8 @@ fn airSubSat(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 5211 | registerAlias(limit_reg, cmov_abi_size), | 5219 | registerAlias(limit_reg, cmov_abi_size), |
| 5212 | ); | 5220 | ); |
| 5213 | | 5221 | |
| 5214 | if (reg_extra_bits > 0 and ty.isSignedInt(zcu)) try self.genShiftBinOpMir( | 5222 | if (reg_extra_bits > 0 and ty.isSignedInt(zcu)) |
| 5215 | .{ ._r, .sa }, | 5223 | try self.genShiftBinOpMir(.{ ._r, .sa }, ty, dst_mcv, .u8, .{ .immediate = reg_extra_bits }); |
| 5216 | ty, | | |
| 5217 | dst_mcv, | | |
| 5218 | Type.u8, | | |
| 5219 | .{ .immediate = reg_extra_bits }, | | |
| 5220 | ); | | |
| 5221 | | 5224 | |
| 5222 | return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none }); | 5225 | return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 5223 | } | 5226 | } |
| ... | @@ -5230,14 +5233,14 @@ fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -5230,14 +5233,14 @@ fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 5230 | | 5233 | |
| 5231 | const result = result: { | 5234 | const result = result: { |
| 5232 | if (ty.toIntern() == .i128_type) { | 5235 | if (ty.toIntern() == .i128_type) { |
| 5233 | const ptr_c_int = try pt.singleMutPtrType(Type.c_int); | 5236 | const ptr_c_int = try pt.singleMutPtrType(.c_int); |
| 5234 | const overflow = try self.allocTempRegOrMem(Type.c_int, false); | 5237 | const overflow = try self.allocTempRegOrMem(.c_int, false); |
| 5235 | | 5238 | |
| 5236 | const dst_mcv = try self.genCall(.{ .lib = .{ | 5239 | const dst_mcv = try self.genCall(.{ .lib = .{ |
| 5237 | .return_type = .i128_type, | 5240 | .return_type = .i128_type, |
| 5238 | .param_types = &.{ .i128_type, .i128_type, ptr_c_int.toIntern() }, | 5241 | .param_types = &.{ .i128_type, .i128_type, ptr_c_int.toIntern() }, |
| 5239 | .callee = "__muloti4", | 5242 | .callee = "__muloti4", |
| 5240 | } }, &.{ Type.i128, Type.i128, ptr_c_int }, &.{ | 5243 | } }, &.{ .i128, .i128, ptr_c_int }, &.{ |
| 5241 | .{ .air_ref = bin_op.lhs }, | 5244 | .{ .air_ref = bin_op.lhs }, |
| 5242 | .{ .air_ref = bin_op.rhs }, | 5245 | .{ .air_ref = bin_op.rhs }, |
| 5243 | overflow.address(), | 5246 | overflow.address(), |
| ... | @@ -5253,7 +5256,7 @@ fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -5253,7 +5256,7 @@ fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 5253 | const mat_lhs_mcv = switch (lhs_mcv) { | 5256 | const mat_lhs_mcv = switch (lhs_mcv) { |
| 5254 | .load_symbol => mat_lhs_mcv: { | 5257 | .load_symbol => mat_lhs_mcv: { |
| 5255 | // TODO clean this up! | 5258 | // TODO clean this up! |
| 5256 | const addr_reg = try self.copyToTmpRegister(Type.usize, lhs_mcv.address()); | 5259 | const addr_reg = try self.copyToTmpRegister(.usize, lhs_mcv.address()); |
| 5257 | break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; | 5260 | break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; |
| 5258 | }, | 5261 | }, |
| 5259 | else => lhs_mcv, | 5262 | else => lhs_mcv, |
| ... | @@ -5277,7 +5280,7 @@ fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -5277,7 +5280,7 @@ fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 5277 | const mat_rhs_mcv = switch (rhs_mcv) { | 5280 | const mat_rhs_mcv = switch (rhs_mcv) { |
| 5278 | .load_symbol => mat_rhs_mcv: { | 5281 | .load_symbol => mat_rhs_mcv: { |
| 5279 | // TODO clean this up! | 5282 | // TODO clean this up! |
| 5280 | const addr_reg = try self.copyToTmpRegister(Type.usize, rhs_mcv.address()); | 5283 | const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address()); |
| 5281 | break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; | 5284 | break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; |
| 5282 | }, | 5285 | }, |
| 5283 | else => rhs_mcv, | 5286 | else => rhs_mcv, |
| ... | @@ -5339,13 +5342,7 @@ fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -5339,13 +5342,7 @@ fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 5339 | const cc: Condition = if (ty.isSignedInt(zcu)) cc: { | 5342 | const cc: Condition = if (ty.isSignedInt(zcu)) cc: { |
| 5340 | try self.genSetReg(limit_reg, ty, lhs_mcv, .{}); | 5343 | try self.genSetReg(limit_reg, ty, lhs_mcv, .{}); |
| 5341 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, rhs_mcv); | 5344 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, rhs_mcv); |
| 5342 | try self.genShiftBinOpMir( | 5345 | try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .u8, .{ .immediate = reg_bits - 1 }); |
| 5343 | .{ ._r, .sa }, | | |
| 5344 | ty, | | |
| 5345 | limit_mcv, | | |
| 5346 | Type.u8, | | |
| 5347 | .{ .immediate = reg_bits - 1 }, | | |
| 5348 | ); | | |
| 5349 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ | 5346 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ |
| 5350 | .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, | 5347 | .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, |
| 5351 | }); | 5348 | }); |
| ... | @@ -5410,7 +5407,7 @@ fn airAddSubWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -5410,7 +5407,7 @@ fn airAddSubWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 5410 | try self.genSetMem( | 5407 | try self.genSetMem( |
| 5411 | .{ .frame = frame_index }, | 5408 | .{ .frame = frame_index }, |
| 5412 | @intCast(tuple_ty.structFieldOffset(1, zcu)), | 5409 | @intCast(tuple_ty.structFieldOffset(1, zcu)), |
| 5413 | Type.u1, | 5410 | .u1, |
| 5414 | .{ .eflags = cc }, | 5411 | .{ .eflags = cc }, |
| 5415 | .{}, | 5412 | .{}, |
| 5416 | ); | 5413 | ); |
| ... | @@ -5558,12 +5555,7 @@ fn genSetFrameTruncatedOverflowCompare( | ... | @@ -5558,12 +5555,7 @@ fn genSetFrameTruncatedOverflowCompare( |
| 5558 | const eq_reg = temp_regs[2]; | 5555 | const eq_reg = temp_regs[2]; |
| 5559 | if (overflow_cc) |_| { | 5556 | if (overflow_cc) |_| { |
| 5560 | try self.asmSetccRegister(.ne, eq_reg.to8()); | 5557 | try self.asmSetccRegister(.ne, eq_reg.to8()); |
| 5561 | try self.genBinOpMir( | 5558 | try self.genBinOpMir(.{ ._, .@"or" }, .u8, .{ .register = overflow_reg }, .{ .register = eq_reg }); |
| 5562 | .{ ._, .@"or" }, | | |
| 5563 | Type.u8, | | |
| 5564 | .{ .register = overflow_reg }, | | |
| 5565 | .{ .register = eq_reg }, | | |
| 5566 | ); | | |
| 5567 | } | 5559 | } |
| 5568 | | 5560 | |
| 5569 | const payload_off: i32 = @intCast(tuple_ty.structFieldOffset(0, zcu)); | 5561 | const payload_off: i32 = @intCast(tuple_ty.structFieldOffset(0, zcu)); |
| ... | @@ -5743,13 +5735,13 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -5743,13 +5735,13 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 5743 | if (src_bits > 64 and src_bits <= 128 and | 5735 | if (src_bits > 64 and src_bits <= 128 and |
| 5744 | dst_info.bits > 64 and dst_info.bits <= 128) switch (dst_info.signedness) { | 5736 | dst_info.bits > 64 and dst_info.bits <= 128) switch (dst_info.signedness) { |
| 5745 | .signed => { | 5737 | .signed => { |
| 5746 | const ptr_c_int = try pt.singleMutPtrType(Type.c_int); | 5738 | const ptr_c_int = try pt.singleMutPtrType(.c_int); |
| 5747 | const overflow = try self.allocTempRegOrMem(Type.c_int, false); | 5739 | const overflow = try self.allocTempRegOrMem(.c_int, false); |
| 5748 | const result = try self.genCall(.{ .lib = .{ | 5740 | const result = try self.genCall(.{ .lib = .{ |
| 5749 | .return_type = .i128_type, | 5741 | .return_type = .i128_type, |
| 5750 | .param_types = &.{ .i128_type, .i128_type, ptr_c_int.toIntern() }, | 5742 | .param_types = &.{ .i128_type, .i128_type, ptr_c_int.toIntern() }, |
| 5751 | .callee = "__muloti4", | 5743 | .callee = "__muloti4", |
| 5752 | } }, &.{ Type.i128, Type.i128, ptr_c_int }, &.{ | 5744 | } }, &.{ .i128, .i128, ptr_c_int }, &.{ |
| 5753 | .{ .air_ref = bin_op.lhs }, | 5745 | .{ .air_ref = bin_op.lhs }, |
| 5754 | .{ .air_ref = bin_op.rhs }, | 5746 | .{ .air_ref = bin_op.rhs }, |
| 5755 | overflow.address(), | 5747 | overflow.address(), |
| ... | @@ -5765,7 +5757,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -5765,7 +5757,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 5765 | ); | 5757 | ); |
| 5766 | try self.asmMemoryImmediate( | 5758 | try self.asmMemoryImmediate( |
| 5767 | .{ ._, .cmp }, | 5759 | .{ ._, .cmp }, |
| 5768 | try overflow.mem(self, .{ .size = self.memSize(Type.c_int) }), | 5760 | try overflow.mem(self, .{ .size = self.memSize(.c_int) }), |
| 5769 | .s(0), | 5761 | .s(0), |
| 5770 | ); | 5762 | ); |
| 5771 | try self.genSetMem( | 5763 | try self.genSetMem( |
| ... | @@ -5794,7 +5786,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -5794,7 +5786,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 5794 | const mat_lhs_mcv = switch (lhs_mcv) { | 5786 | const mat_lhs_mcv = switch (lhs_mcv) { |
| 5795 | .load_symbol => mat_lhs_mcv: { | 5787 | .load_symbol => mat_lhs_mcv: { |
| 5796 | // TODO clean this up! | 5788 | // TODO clean this up! |
| 5797 | const addr_reg = try self.copyToTmpRegister(Type.usize, lhs_mcv.address()); | 5789 | const addr_reg = try self.copyToTmpRegister(.usize, lhs_mcv.address()); |
| 5798 | break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; | 5790 | break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; |
| 5799 | }, | 5791 | }, |
| 5800 | else => lhs_mcv, | 5792 | else => lhs_mcv, |
| ... | @@ -5807,7 +5799,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -5807,7 +5799,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 5807 | const mat_rhs_mcv = switch (rhs_mcv) { | 5799 | const mat_rhs_mcv = switch (rhs_mcv) { |
| 5808 | .load_symbol => mat_rhs_mcv: { | 5800 | .load_symbol => mat_rhs_mcv: { |
| 5809 | // TODO clean this up! | 5801 | // TODO clean this up! |
| 5810 | const addr_reg = try self.copyToTmpRegister(Type.usize, rhs_mcv.address()); | 5802 | const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address()); |
| 5811 | break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; | 5803 | break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; |
| 5812 | }, | 5804 | }, |
| 5813 | else => rhs_mcv, | 5805 | else => rhs_mcv, |
| ... | @@ -6100,7 +6092,7 @@ fn airShlShrBinOp(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -6100,7 +6092,7 @@ fn airShlShrBinOp(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 6100 | defer self.register_manager.unlockReg(tmp_lock); | 6092 | defer self.register_manager.unlockReg(tmp_lock); |
| 6101 | | 6093 | |
| 6102 | const lhs_bits: u31 = @intCast(lhs_ty.bitSize(zcu)); | 6094 | const lhs_bits: u31 = @intCast(lhs_ty.bitSize(zcu)); |
| 6103 | const tmp_ty = if (lhs_bits > 64) Type.usize else lhs_ty; | 6095 | const tmp_ty: Type = if (lhs_bits > 64) .usize else lhs_ty; |
| 6104 | const off = frame_addr.off + (lhs_bits - 1) / 64 * 8; | 6096 | const off = frame_addr.off + (lhs_bits - 1) / 64 * 8; |
| 6105 | try self.genSetReg( | 6097 | try self.genSetReg( |
| 6106 | tmp_reg, | 6098 | tmp_reg, |
| ... | @@ -6283,13 +6275,12 @@ fn airShlShrBinOp(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -6283,13 +6275,12 @@ fn airShlShrBinOp(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 6283 | const mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{ | 6275 | const mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 6284 | .ty = mask_ty.toIntern(), | 6276 | .ty = mask_ty.toIntern(), |
| 6285 | .storage = .{ .elems = &([1]InternPool.Index{ | 6277 | .storage = .{ .elems = &([1]InternPool.Index{ |
| 6286 | (try rhs_ty.childType(zcu).maxIntScalar(pt, Type.u8)).toIntern(), | 6278 | (try rhs_ty.childType(zcu).maxIntScalar(pt, .u8)).toIntern(), |
| 6287 | } ++ [1]InternPool.Index{ | 6279 | } ++ [1]InternPool.Index{ |
| 6288 | (try pt.intValue(Type.u8, 0)).toIntern(), | 6280 | (try pt.intValue(.u8, 0)).toIntern(), |
| 6289 | } ** 15) }, | 6281 | } ** 15) }, |
| 6290 | } }))); | 6282 | } }))); |
| 6291 | const mask_addr_reg = | 6283 | const mask_addr_reg = try self.copyToTmpRegister(.usize, mask_mcv.address()); |
| 6292 | try self.copyToTmpRegister(Type.usize, mask_mcv.address()); | | |
| 6293 | const mask_addr_lock = self.register_manager.lockRegAssumeUnused(mask_addr_reg); | 6284 | const mask_addr_lock = self.register_manager.lockRegAssumeUnused(mask_addr_reg); |
| 6294 | defer self.register_manager.unlockReg(mask_addr_lock); | 6285 | defer self.register_manager.unlockReg(mask_addr_lock); |
| 6295 | | 6286 | |
| ... | @@ -6423,7 +6414,7 @@ fn airOptionalPayloadPtrSet(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -6423,7 +6414,7 @@ fn airOptionalPayloadPtrSet(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 6423 | try self.genSetMem( | 6414 | try self.genSetMem( |
| 6424 | .{ .reg = dst_mcv.getReg().? }, | 6415 | .{ .reg = dst_mcv.getReg().? }, |
| 6425 | pl_abi_size, | 6416 | pl_abi_size, |
| 6426 | Type.bool, | 6417 | .bool, |
| 6427 | .{ .immediate = 1 }, | 6418 | .{ .immediate = 1 }, |
| 6428 | .{}, | 6419 | .{}, |
| 6429 | ); | 6420 | ); |
| ... | @@ -6462,9 +6453,9 @@ fn airUnwrapErrUnionErr(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -6462,9 +6453,9 @@ fn airUnwrapErrUnionErr(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 6462 | .{ ._r, .sh }, | 6453 | .{ ._r, .sh }, |
| 6463 | err_union_ty, | 6454 | err_union_ty, |
| 6464 | result, | 6455 | result, |
| 6465 | Type.u8, | 6456 | .u8, |
| 6466 | .{ .immediate = @as(u6, @intCast(err_off * 8)) }, | 6457 | .{ .immediate = @as(u6, @intCast(err_off * 8)) }, |
| 6467 | ) else try self.truncateRegister(Type.anyerror, result.register); | 6458 | ) else try self.truncateRegister(.anyerror, result.register); |
| 6468 | break :result result; | 6459 | break :result result; |
| 6469 | }, | 6460 | }, |
| 6470 | .load_frame => |frame_addr| break :result .{ .load_frame = .{ | 6461 | .load_frame => |frame_addr| break :result .{ .load_frame = .{ |
| ... | @@ -6623,7 +6614,7 @@ fn genUnwrapErrUnionPayloadMir( | ... | @@ -6623,7 +6614,7 @@ fn genUnwrapErrUnionPayloadMir( |
| 6623 | .{ ._r, .sh }, | 6614 | .{ ._r, .sh }, |
| 6624 | err_union_ty, | 6615 | err_union_ty, |
| 6625 | result_mcv, | 6616 | result_mcv, |
| 6626 | Type.u8, | 6617 | .u8, |
| 6627 | .{ .immediate = @as(u6, @intCast(payload_off * 8)) }, | 6618 | .{ .immediate = @as(u6, @intCast(payload_off * 8)) }, |
| 6628 | ) else try self.truncateRegister(payload_ty, result_mcv.register); | 6619 | ) else try self.truncateRegister(payload_ty, result_mcv.register); |
| 6629 | break :result if (payload_in_gp) | 6620 | break :result if (payload_in_gp) |
| ... | @@ -6929,7 +6920,7 @@ fn genSliceElemPtr(self: *CodeGen, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValu | ... | @@ -6929,7 +6920,7 @@ fn genSliceElemPtr(self: *CodeGen, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValu |
| 6929 | defer self.register_manager.unlockReg(offset_reg_lock); | 6920 | defer self.register_manager.unlockReg(offset_reg_lock); |
| 6930 | | 6921 | |
| 6931 | const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); | 6922 | const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 6932 | try self.genSetReg(addr_reg, Type.usize, slice_mcv, .{}); | 6923 | try self.genSetReg(addr_reg, .usize, slice_mcv, .{}); |
| 6933 | // TODO we could allocate register here, but need to expect addr register and potentially | 6924 | // TODO we could allocate register here, but need to expect addr register and potentially |
| 6934 | // offset register. | 6925 | // offset register. |
| 6935 | try self.genBinOpMir(.{ ._, .add }, slice_ptr_field_type, .{ .register = addr_reg }, .{ | 6926 | try self.genBinOpMir(.{ ._, .add }, slice_ptr_field_type, .{ .register = addr_reg }, .{ |
| ... | @@ -7064,7 +7055,7 @@ fn airArrayElemVal(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -7064,7 +7055,7 @@ fn airArrayElemVal(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 7064 | .{ ._, .bt }, | 7055 | .{ ._, .bt }, |
| 7065 | .{ | 7056 | .{ |
| 7066 | .base = .{ | 7057 | .base = .{ |
| 7067 | .reg = try self.copyToTmpRegister(Type.usize, array_mat_mcv.address()), | 7058 | .reg = try self.copyToTmpRegister(.usize, array_mat_mcv.address()), |
| 7068 | }, | 7059 | }, |
| 7069 | .mod = .{ .rm = .{ .size = .qword } }, | 7060 | .mod = .{ .rm = .{ .size = .qword } }, |
| 7070 | }, | 7061 | }, |
| ... | @@ -7074,7 +7065,7 @@ fn airArrayElemVal(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -7074,7 +7065,7 @@ fn airArrayElemVal(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 7074 | .{ ._, .bt }, | 7065 | .{ ._, .bt }, |
| 7075 | .{ | 7066 | .{ |
| 7076 | .base = .{ | 7067 | .base = .{ |
| 7077 | .reg = try self.copyToTmpRegister(Type.usize, array_mat_mcv.address()), | 7068 | .reg = try self.copyToTmpRegister(.usize, array_mat_mcv.address()), |
| 7078 | }, | 7069 | }, |
| 7079 | .mod = .{ .rm = .{ .size = .qword } }, | 7070 | .mod = .{ .rm = .{ .size = .qword } }, |
| 7080 | }, | 7071 | }, |
| ... | @@ -7122,7 +7113,7 @@ fn airArrayElemVal(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -7122,7 +7113,7 @@ fn airArrayElemVal(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 7122 | .load_direct, | 7113 | .load_direct, |
| 7123 | .load_got, | 7114 | .load_got, |
| 7124 | .load_tlv, | 7115 | .load_tlv, |
| 7125 | => try self.genSetReg(addr_reg, Type.usize, array_mcv.address(), .{}), | 7116 | => try self.genSetReg(addr_reg, .usize, array_mcv.address(), .{}), |
| 7126 | .lea_symbol, .lea_direct, .lea_tlv => unreachable, | 7117 | .lea_symbol, .lea_direct, .lea_tlv => unreachable, |
| 7127 | else => return self.fail("TODO airArrayElemVal_val for {s} of {}", .{ | 7118 | else => return self.fail("TODO airArrayElemVal_val for {s} of {}", .{ |
| 7128 | @tagName(array_mcv), array_ty.fmt(pt), | 7119 | @tagName(array_mcv), array_ty.fmt(pt), |
| ... | @@ -7136,12 +7127,7 @@ fn airArrayElemVal(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -7136,12 +7127,7 @@ fn airArrayElemVal(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 7136 | // TODO we could allocate register here, but need to expect addr register and potentially | 7127 | // TODO we could allocate register here, but need to expect addr register and potentially |
| 7137 | // offset register. | 7128 | // offset register. |
| 7138 | const dst_mcv = try self.allocRegOrMem(inst, false); | 7129 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 7139 | try self.genBinOpMir( | 7130 | try self.genBinOpMir(.{ ._, .add }, .usize, .{ .register = addr_reg }, .{ .register = offset_reg }); |
| 7140 | .{ ._, .add }, | | |
| 7141 | Type.usize, | | |
| 7142 | .{ .register = addr_reg }, | | |
| 7143 | .{ .register = offset_reg }, | | |
| 7144 | ); | | |
| 7145 | try self.genCopy(elem_ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } }, .{}); | 7131 | try self.genCopy(elem_ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } }, .{}); |
| 7146 | break :result dst_mcv; | 7132 | break :result dst_mcv; |
| 7147 | }; | 7133 | }; |
| ... | @@ -7329,13 +7315,7 @@ fn airGetUnionTag(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -7329,13 +7315,7 @@ fn airGetUnionTag(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 7329 | .register => { | 7315 | .register => { |
| 7330 | const shift: u6 = @intCast(layout.tagOffset() * 8); | 7316 | const shift: u6 = @intCast(layout.tagOffset() * 8); |
| 7331 | const result = try self.copyToRegisterWithInstTracking(inst, union_ty, operand); | 7317 | const result = try self.copyToRegisterWithInstTracking(inst, union_ty, operand); |
| 7332 | try self.genShiftBinOpMir( | 7318 | try self.genShiftBinOpMir(.{ ._r, .sh }, .usize, result, .u8, .{ .immediate = shift }); |
| 7333 | .{ ._r, .sh }, | | |
| 7334 | Type.usize, | | |
| 7335 | result, | | |
| 7336 | Type.u8, | | |
| 7337 | .{ .immediate = shift }, | | |
| 7338 | ); | | |
| 7339 | break :blk MCValue{ | 7319 | break :blk MCValue{ |
| 7340 | .register = registerAlias(result.register, @intCast(layout.tag_size)), | 7320 | .register = registerAlias(result.register, @intCast(layout.tag_size)), |
| 7341 | }; | 7321 | }; |
| ... | @@ -7444,7 +7424,7 @@ fn airClz(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -7444,7 +7424,7 @@ fn airClz(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 7444 | if (src_bits <= 8) { | 7424 | if (src_bits <= 8) { |
| 7445 | const wide_reg = try self.copyToTmpRegister(src_ty, mat_src_mcv); | 7425 | const wide_reg = try self.copyToTmpRegister(src_ty, mat_src_mcv); |
| 7446 | try self.truncateRegister(src_ty, wide_reg); | 7426 | try self.truncateRegister(src_ty, wide_reg); |
| 7447 | try self.genBinOpMir(.{ ._, .lzcnt }, Type.u32, dst_mcv, .{ .register = wide_reg }); | 7427 | try self.genBinOpMir(.{ ._, .lzcnt }, .u32, dst_mcv, .{ .register = wide_reg }); |
| 7448 | try self.genBinOpMir( | 7428 | try self.genBinOpMir( |
| 7449 | .{ ._, .sub }, | 7429 | .{ ._, .sub }, |
| 7450 | dst_ty, | 7430 | dst_ty, |
| ... | @@ -7464,25 +7444,15 @@ fn airClz(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -7464,25 +7444,15 @@ fn airClz(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 7464 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 7444 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 7465 | defer self.register_manager.unlockReg(tmp_lock); | 7445 | defer self.register_manager.unlockReg(tmp_lock); |
| 7466 | | 7446 | |
| 7467 | try self.genBinOpMir( | 7447 | try self.genBinOpMir(.{ ._, .lzcnt }, .u64, dst_mcv, if (mat_src_mcv.isBase()) |
| 7468 | .{ ._, .lzcnt }, | 7448 | mat_src_mcv |
| 7469 | Type.u64, | 7449 | else |
| 7470 | dst_mcv, | 7450 | .{ .register = mat_src_mcv.register_pair[0] }); |
| 7471 | if (mat_src_mcv.isBase()) | | |
| 7472 | mat_src_mcv | | |
| 7473 | else | | |
| 7474 | .{ .register = mat_src_mcv.register_pair[0] }, | | |
| 7475 | ); | | |
| 7476 | try self.genBinOpMir(.{ ._, .add }, dst_ty, dst_mcv, .{ .immediate = 64 }); | 7451 | try self.genBinOpMir(.{ ._, .add }, dst_ty, dst_mcv, .{ .immediate = 64 }); |
| 7477 | try self.genBinOpMir( | 7452 | try self.genBinOpMir(.{ ._, .lzcnt }, .u64, tmp_mcv, if (mat_src_mcv.isBase()) |
| 7478 | .{ ._, .lzcnt }, | 7453 | mat_src_mcv.address().offset(8).deref() |
| 7479 | Type.u64, | 7454 | else |
| 7480 | tmp_mcv, | 7455 | .{ .register = mat_src_mcv.register_pair[1] }); |
| 7481 | if (mat_src_mcv.isBase()) | | |
| 7482 | mat_src_mcv.address().offset(8).deref() | | |
| 7483 | else | | |
| 7484 | .{ .register = mat_src_mcv.register_pair[1] }, | | |
| 7485 | ); | | |
| 7486 | try self.asmCmovccRegisterRegister(.nc, dst_reg.to32(), tmp_reg.to32()); | 7456 | try self.asmCmovccRegisterRegister(.nc, dst_reg.to32(), tmp_reg.to32()); |
| 7487 | | 7457 | |
| 7488 | if (src_bits < 128) try self.genBinOpMir( | 7458 | if (src_bits < 128) try self.genBinOpMir( |
| ... | @@ -7510,7 +7480,7 @@ fn airClz(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -7510,7 +7480,7 @@ fn airClz(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 7510 | defer self.register_manager.unlockReg(wide_lock); | 7480 | defer self.register_manager.unlockReg(wide_lock); |
| 7511 | | 7481 | |
| 7512 | try self.truncateRegister(src_ty, wide_reg); | 7482 | try self.truncateRegister(src_ty, wide_reg); |
| 7513 | try self.genBinOpMir(.{ ._, .bsr }, Type.u16, dst_mcv, .{ .register = wide_reg }); | 7483 | try self.genBinOpMir(.{ ._, .bsr }, .u16, dst_mcv, .{ .register = wide_reg }); |
| 7514 | } else try self.genBinOpMir(.{ ._, .bsr }, src_ty, dst_mcv, mat_src_mcv); | 7484 | } else try self.genBinOpMir(.{ ._, .bsr }, src_ty, dst_mcv, mat_src_mcv); |
| 7515 | | 7485 | |
| 7516 | try self.asmCmovccRegisterRegister( | 7486 | try self.asmCmovccRegisterRegister( |
| ... | @@ -7534,7 +7504,7 @@ fn airClz(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -7534,7 +7504,7 @@ fn airClz(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 7534 | try self.truncateRegister(src_ty, wide_reg); | 7504 | try self.truncateRegister(src_ty, wide_reg); |
| 7535 | try self.genBinOpMir( | 7505 | try self.genBinOpMir( |
| 7536 | .{ ._, .bsr }, | 7506 | .{ ._, .bsr }, |
| 7537 | if (src_bits <= 8) Type.u16 else src_ty, | 7507 | if (src_bits <= 8) .u16 else src_ty, |
| 7538 | dst_mcv, | 7508 | dst_mcv, |
| 7539 | .{ .register = wide_reg }, | 7509 | .{ .register = wide_reg }, |
| 7540 | ); | 7510 | ); |
| ... | @@ -7645,7 +7615,7 @@ fn airCtz(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -7645,7 +7615,7 @@ fn airCtz(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 7645 | break :result dst_mcv; | 7615 | break :result dst_mcv; |
| 7646 | } | 7616 | } |
| 7647 | | 7617 | |
| 7648 | const wide_ty = if (src_bits <= 8) Type.u16 else src_ty; | 7618 | const wide_ty: Type = if (src_bits <= 8) .u16 else src_ty; |
| 7649 | if (has_bmi) { | 7619 | if (has_bmi) { |
| 7650 | if (src_bits <= 64) { | 7620 | if (src_bits <= 64) { |
| 7651 | const extra_bits = self.regExtraBits(src_ty) + @as(u64, if (src_bits <= 8) 8 else 0); | 7621 | const extra_bits = self.regExtraBits(src_ty) + @as(u64, if (src_bits <= 8) 8 else 0); |
| ... | @@ -7682,18 +7652,18 @@ fn airCtz(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -7682,18 +7652,18 @@ fn airCtz(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 7682 | else | 7652 | else |
| 7683 | .{ .register = mat_src_mcv.register_pair[1] }; | 7653 | .{ .register = mat_src_mcv.register_pair[1] }; |
| 7684 | const masked_mcv = if (src_bits < 128) masked: { | 7654 | const masked_mcv = if (src_bits < 128) masked: { |
| 7685 | try self.genCopy(Type.u64, dst_mcv, hi_mat_src_mcv, .{}); | 7655 | try self.genCopy(.u64, dst_mcv, hi_mat_src_mcv, .{}); |
| 7686 | try self.genBinOpMir( | 7656 | try self.genBinOpMir( |
| 7687 | .{ ._, .@"or" }, | 7657 | .{ ._, .@"or" }, |
| 7688 | Type.u64, | 7658 | .u64, |
| 7689 | dst_mcv, | 7659 | dst_mcv, |
| 7690 | .{ .immediate = @as(u64, std.math.maxInt(u64)) << @intCast(src_bits - 64) }, | 7660 | .{ .immediate = @as(u64, std.math.maxInt(u64)) << @intCast(src_bits - 64) }, |
| 7691 | ); | 7661 | ); |
| 7692 | break :masked dst_mcv; | 7662 | break :masked dst_mcv; |
| 7693 | } else hi_mat_src_mcv; | 7663 | } else hi_mat_src_mcv; |
| 7694 | try self.genBinOpMir(.{ ._, .tzcnt }, Type.u64, dst_mcv, masked_mcv); | 7664 | try self.genBinOpMir(.{ ._, .tzcnt }, .u64, dst_mcv, masked_mcv); |
| 7695 | try self.genBinOpMir(.{ ._, .add }, dst_ty, dst_mcv, .{ .immediate = 64 }); | 7665 | try self.genBinOpMir(.{ ._, .add }, dst_ty, dst_mcv, .{ .immediate = 64 }); |
| 7696 | try self.genBinOpMir(.{ ._, .tzcnt }, Type.u64, tmp_mcv, lo_mat_src_mcv); | 7666 | try self.genBinOpMir(.{ ._, .tzcnt }, .u64, tmp_mcv, lo_mat_src_mcv); |
| 7697 | try self.asmCmovccRegisterRegister(.nc, dst_reg.to32(), tmp_reg.to32()); | 7667 | try self.asmCmovccRegisterRegister(.nc, dst_reg.to32(), tmp_reg.to32()); |
| 7698 | } | 7668 | } |
| 7699 | break :result dst_mcv; | 7669 | break :result dst_mcv; |
| ... | @@ -7766,7 +7736,7 @@ fn airPopCount(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -7766,7 +7736,7 @@ fn airPopCount(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 7766 | const tmp_locks = self.register_manager.lockRegsAssumeUnused(2, tmp_regs); | 7736 | const tmp_locks = self.register_manager.lockRegsAssumeUnused(2, tmp_regs); |
| 7767 | defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock); | 7737 | defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock); |
| 7768 | | 7738 | |
| 7769 | try self.genPopCount(tmp_regs[0], Type.usize, if (mat_src_mcv.isBase()) | 7739 | try self.genPopCount(tmp_regs[0], .usize, if (mat_src_mcv.isBase()) |
| 7770 | mat_src_mcv | 7740 | mat_src_mcv |
| 7771 | else | 7741 | else |
| 7772 | .{ .register = mat_src_mcv.register_pair[0] }, false); | 7742 | .{ .register = mat_src_mcv.register_pair[0] }, false); |
| ... | @@ -7794,7 +7764,7 @@ fn genPopCount( | ... | @@ -7794,7 +7764,7 @@ fn genPopCount( |
| 7794 | const src_abi_size: u32 = @intCast(src_ty.abiSize(pt.zcu)); | 7764 | const src_abi_size: u32 = @intCast(src_ty.abiSize(pt.zcu)); |
| 7795 | if (self.hasFeature(.popcnt)) return self.genBinOpMir( | 7765 | if (self.hasFeature(.popcnt)) return self.genBinOpMir( |
| 7796 | .{ ._, .popcnt }, | 7766 | .{ ._, .popcnt }, |
| 7797 | if (src_abi_size > 1) src_ty else Type.u32, | 7767 | if (src_abi_size > 1) src_ty else .u32, |
| 7798 | .{ .register = dst_reg }, | 7768 | .{ .register = dst_reg }, |
| 7799 | if (src_abi_size > 1) src_mcv else src: { | 7769 | if (src_abi_size > 1) src_mcv else src: { |
| 7800 | if (!dst_contains_src) try self.genSetReg(dst_reg, src_ty, src_mcv, .{}); | 7770 | if (!dst_contains_src) try self.genSetReg(dst_reg, src_ty, src_mcv, .{}); |
| ... | @@ -8057,7 +8027,7 @@ fn airByteSwap(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -8057,7 +8027,7 @@ fn airByteSwap(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 8057 | } }, | 8027 | } }, |
| 8058 | src_ty, | 8028 | src_ty, |
| 8059 | dst_mcv, | 8029 | dst_mcv, |
| 8060 | if (src_bits > 256) Type.u16 else Type.u8, | 8030 | if (src_bits > 256) .u16 else .u8, |
| 8061 | .{ .immediate = src_ty.abiSize(zcu) * 8 - src_bits }, | 8031 | .{ .immediate = src_ty.abiSize(zcu) * 8 - src_bits }, |
| 8062 | ); | 8032 | ); |
| 8063 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); | 8033 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); |
| ... | @@ -8181,7 +8151,7 @@ fn airBitReverse(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -8181,7 +8151,7 @@ fn airBitReverse(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 8181 | if (extra_bits > 0) try self.genShiftBinOpMir(switch (signedness) { | 8151 | if (extra_bits > 0) try self.genShiftBinOpMir(switch (signedness) { |
| 8182 | .signed => .{ ._r, .sa }, | 8152 | .signed => .{ ._r, .sa }, |
| 8183 | .unsigned => .{ ._r, .sh }, | 8153 | .unsigned => .{ ._r, .sh }, |
| 8184 | }, src_ty, dst_mcv, Type.u8, .{ .immediate = extra_bits }); | 8154 | }, src_ty, dst_mcv, .u8, .{ .immediate = extra_bits }); |
| 8185 | | 8155 | |
| 8186 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); | 8156 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); |
| 8187 | } | 8157 | } |
| ... | @@ -8252,7 +8222,7 @@ fn floatSign(self: *CodeGen, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Ty | ... | @@ -8252,7 +8222,7 @@ fn floatSign(self: *CodeGen, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Ty |
| 8252 | try sign_mcv.mem(self, .{ .size = .fromSize(abi_size) }) | 8222 | try sign_mcv.mem(self, .{ .size = .fromSize(abi_size) }) |
| 8253 | else | 8223 | else |
| 8254 | .{ | 8224 | .{ |
| 8255 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, sign_mcv.address()) }, | 8225 | .base = .{ .reg = try self.copyToTmpRegister(.usize, sign_mcv.address()) }, |
| 8256 | .mod = .{ .rm = .{ .size = .fromSize(abi_size) } }, | 8226 | .mod = .{ .rm = .{ .size = .fromSize(abi_size) } }, |
| 8257 | }; | 8227 | }; |
| 8258 | | 8228 | |
| ... | @@ -8947,9 +8917,9 @@ fn packedLoad(self: *CodeGen, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) | ... | @@ -8947,9 +8917,9 @@ fn packedLoad(self: *CodeGen, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) |
| 8947 | defer self.register_manager.unlockReg(tmp_lock); | 8917 | defer self.register_manager.unlockReg(tmp_lock); |
| 8948 | | 8918 | |
| 8949 | const hi_mcv = dst_mcv.address().offset(@intCast(val_bit_size / 64 * 8)).deref(); | 8919 | const hi_mcv = dst_mcv.address().offset(@intCast(val_bit_size / 64 * 8)).deref(); |
| 8950 | try self.genSetReg(tmp_reg, Type.usize, hi_mcv, .{}); | 8920 | try self.genSetReg(tmp_reg, .usize, hi_mcv, .{}); |
| 8951 | try self.truncateRegister(val_ty, tmp_reg); | 8921 | try self.truncateRegister(val_ty, tmp_reg); |
| 8952 | try self.genCopy(Type.usize, hi_mcv, .{ .register = tmp_reg }, .{}); | 8922 | try self.genCopy(.usize, hi_mcv, .{ .register = tmp_reg }, .{}); |
| 8953 | } | 8923 | } |
| 8954 | } | 8924 | } |
| 8955 | return; | 8925 | return; |
| ... | @@ -9104,13 +9074,13 @@ fn airLoad(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -9104,13 +9074,13 @@ fn airLoad(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 9104 | const high_reg = if (high_mcv.isRegister()) | 9074 | const high_reg = if (high_mcv.isRegister()) |
| 9105 | high_mcv.getReg().? | 9075 | high_mcv.getReg().? |
| 9106 | else | 9076 | else |
| 9107 | try self.copyToTmpRegister(Type.usize, high_mcv); | 9077 | try self.copyToTmpRegister(.usize, high_mcv); |
| 9108 | const high_lock = self.register_manager.lockReg(high_reg); | 9078 | const high_lock = self.register_manager.lockReg(high_reg); |
| 9109 | defer if (high_lock) |lock| self.register_manager.unlockReg(lock); | 9079 | defer if (high_lock) |lock| self.register_manager.unlockReg(lock); |
| 9110 | | 9080 | |
| 9111 | try self.truncateRegister(elem_ty, high_reg); | 9081 | try self.truncateRegister(elem_ty, high_reg); |
| 9112 | if (!high_mcv.isRegister()) try self.genCopy( | 9082 | if (!high_mcv.isRegister()) try self.genCopy( |
| 9113 | if (elem_size <= 8) elem_ty else Type.usize, | 9083 | if (elem_size <= 8) elem_ty else .usize, |
| 9114 | high_mcv, | 9084 | high_mcv, |
| 9115 | .{ .register = high_reg }, | 9085 | .{ .register = high_reg }, |
| 9116 | .{}, | 9086 | .{}, |
| ... | @@ -9183,14 +9153,14 @@ fn packedStore(self: *CodeGen, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) | ... | @@ -9183,14 +9153,14 @@ fn packedStore(self: *CodeGen, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) |
| 9183 | .{ ._l, .sh }, | 9153 | .{ ._l, .sh }, |
| 9184 | limb_ty, | 9154 | limb_ty, |
| 9185 | tmp_mcv, | 9155 | tmp_mcv, |
| 9186 | Type.u8, | 9156 | .u8, |
| 9187 | .{ .immediate = src_bit_off }, | 9157 | .{ .immediate = src_bit_off }, |
| 9188 | ), | 9158 | ), |
| 9189 | 1 => try self.genShiftBinOpMir( | 9159 | 1 => try self.genShiftBinOpMir( |
| 9190 | .{ ._r, .sh }, | 9160 | .{ ._r, .sh }, |
| 9191 | limb_ty, | 9161 | limb_ty, |
| 9192 | tmp_mcv, | 9162 | tmp_mcv, |
| 9193 | Type.u8, | 9163 | .u8, |
| 9194 | .{ .immediate = limb_abi_bits - src_bit_off }, | 9164 | .{ .immediate = limb_abi_bits - src_bit_off }, |
| 9195 | ), | 9165 | ), |
| 9196 | else => unreachable, | 9166 | else => unreachable, |
| ... | @@ -9355,7 +9325,10 @@ fn airStructFieldVal(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -9355,7 +9325,10 @@ fn airStructFieldVal(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 9355 | const src_mcv = try self.resolveInst(operand); | 9325 | const src_mcv = try self.resolveInst(operand); |
| 9356 | const field_off: u32 = switch (container_ty.containerLayout(zcu)) { | 9326 | const field_off: u32 = switch (container_ty.containerLayout(zcu)) { |
| 9357 | .auto, .@"extern" => @intCast(container_ty.structFieldOffset(extra.field_index, zcu) * 8), | 9327 | .auto, .@"extern" => @intCast(container_ty.structFieldOffset(extra.field_index, zcu) * 8), |
| 9358 | .@"packed" => if (zcu.typeToStruct(container_ty)) |struct_obj| pt.structPackedFieldBitOffset(struct_obj, extra.field_index) else 0, | 9328 | .@"packed" => if (zcu.typeToStruct(container_ty)) |struct_obj| |
| | 9329 | pt.structPackedFieldBitOffset(struct_obj, extra.field_index) |
| | 9330 | else |
| | 9331 | 0, |
| 9359 | }; | 9332 | }; |
| 9360 | | 9333 | |
| 9361 | switch (src_mcv) { | 9334 | switch (src_mcv) { |
| ... | @@ -9370,20 +9343,14 @@ fn airStructFieldVal(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -9370,20 +9343,14 @@ fn airStructFieldVal(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 9370 | else if (field_off == 0) | 9343 | else if (field_off == 0) |
| 9371 | (try self.copyToRegisterWithInstTracking(inst, field_ty, src_mcv)).register | 9344 | (try self.copyToRegisterWithInstTracking(inst, field_ty, src_mcv)).register |
| 9372 | else | 9345 | else |
| 9373 | try self.copyToTmpRegister(Type.usize, .{ .register = src_reg }); | 9346 | try self.copyToTmpRegister(.usize, .{ .register = src_reg }); |
| 9374 | const dst_mcv: MCValue = .{ .register = dst_reg }; | 9347 | const dst_mcv: MCValue = .{ .register = dst_reg }; |
| 9375 | const dst_lock = self.register_manager.lockReg(dst_reg); | 9348 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 9376 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); | 9349 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 9377 | | 9350 | |
| 9378 | if (field_off > 0) { | 9351 | if (field_off > 0) { |
| 9379 | try self.spillEflagsIfOccupied(); | 9352 | try self.spillEflagsIfOccupied(); |
| 9380 | try self.genShiftBinOpMir( | 9353 | try self.genShiftBinOpMir(.{ ._r, .sh }, .usize, dst_mcv, .u8, .{ .immediate = field_off }); |
| 9381 | .{ ._r, .sh }, | | |
| 9382 | Type.usize, | | |
| 9383 | dst_mcv, | | |
| 9384 | Type.u8, | | |
| 9385 | .{ .immediate = field_off }, | | |
| 9386 | ); | | |
| 9387 | } | 9354 | } |
| 9388 | if (abi.RegisterClass.gp.isSet(RegisterManager.indexOfRegIntoTracked(dst_reg).?) and | 9355 | if (abi.RegisterClass.gp.isSet(RegisterManager.indexOfRegIntoTracked(dst_reg).?) and |
| 9389 | container_ty.abiSize(zcu) * 8 > field_ty.bitSize(zcu)) | 9356 | container_ty.abiSize(zcu) * 8 > field_ty.bitSize(zcu)) |
| ... | @@ -9421,13 +9388,7 @@ fn airStructFieldVal(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -9421,13 +9388,7 @@ fn airStructFieldVal(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 9421 | | 9388 | |
| 9422 | if (field_off > 0) { | 9389 | if (field_off > 0) { |
| 9423 | try self.spillEflagsIfOccupied(); | 9390 | try self.spillEflagsIfOccupied(); |
| 9424 | try self.genShiftBinOpMir( | 9391 | try self.genShiftBinOpMir(.{ ._r, .sh }, .u128, dst_mcv, .u8, .{ .immediate = field_off }); |
| 9425 | .{ ._r, .sh }, | | |
| 9426 | Type.u128, | | |
| 9427 | dst_mcv, | | |
| 9428 | Type.u8, | | |
| 9429 | .{ .immediate = field_off }, | | |
| 9430 | ); | | |
| 9431 | } | 9392 | } |
| 9432 | | 9393 | |
| 9433 | if (field_bit_size <= 64) { | 9394 | if (field_bit_size <= 64) { |
| ... | @@ -9451,20 +9412,14 @@ fn airStructFieldVal(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -9451,20 +9412,14 @@ fn airStructFieldVal(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 9451 | try self.copyToRegisterWithInstTracking(inst, field_ty, dst_mcv); | 9412 | try self.copyToRegisterWithInstTracking(inst, field_ty, dst_mcv); |
| 9452 | }; | 9413 | }; |
| 9453 | | 9414 | |
| 9454 | const dst_reg = try self.copyToTmpRegister(Type.usize, .{ .register = src_reg }); | 9415 | const dst_reg = try self.copyToTmpRegister(.usize, .{ .register = src_reg }); |
| 9455 | const dst_mcv = MCValue{ .register = dst_reg }; | 9416 | const dst_mcv = MCValue{ .register = dst_reg }; |
| 9456 | const dst_lock = self.register_manager.lockReg(dst_reg); | 9417 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 9457 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); | 9418 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 9458 | | 9419 | |
| 9459 | if (field_off % 64 > 0) { | 9420 | if (field_off % 64 > 0) { |
| 9460 | try self.spillEflagsIfOccupied(); | 9421 | try self.spillEflagsIfOccupied(); |
| 9461 | try self.genShiftBinOpMir( | 9422 | try self.genShiftBinOpMir(.{ ._r, .sh }, .usize, dst_mcv, .u8, .{ .immediate = field_off % 64 }); |
| 9462 | .{ ._r, .sh }, | | |
| 9463 | Type.usize, | | |
| 9464 | dst_mcv, | | |
| 9465 | Type.u8, | | |
| 9466 | .{ .immediate = field_off % 64 }, | | |
| 9467 | ); | | |
| 9468 | } | 9423 | } |
| 9469 | if (self.regExtraBits(field_ty) > 0) try self.truncateRegister(field_ty, dst_reg); | 9424 | if (self.regExtraBits(field_ty) > 0) try self.truncateRegister(field_ty, dst_reg); |
| 9470 | | 9425 | |
| ... | @@ -9479,11 +9434,7 @@ fn airStructFieldVal(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -9479,11 +9434,7 @@ fn airStructFieldVal(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 9479 | 0 => if (self.reuseOperand(inst, extra.struct_operand, 0, src_mcv)) { | 9434 | 0 => if (self.reuseOperand(inst, extra.struct_operand, 0, src_mcv)) { |
| 9480 | self.eflags_inst = null; // actually stop tracking the overflow part | 9435 | self.eflags_inst = null; // actually stop tracking the overflow part |
| 9481 | break :result .{ .register = ro.reg }; | 9436 | break :result .{ .register = ro.reg }; |
| 9482 | } else break :result try self.copyToRegisterWithInstTracking( | 9437 | } else break :result try self.copyToRegisterWithInstTracking(inst, .usize, .{ .register = ro.reg }), |
| 9483 | inst, | | |
| 9484 | Type.usize, | | |
| 9485 | .{ .register = ro.reg }, | | |
| 9486 | ), | | |
| 9487 | // Get overflow bit. | 9438 | // Get overflow bit. |
| 9488 | 1 => if (self.reuseOperandAdvanced(inst, extra.struct_operand, 0, src_mcv, null)) { | 9439 | 1 => if (self.reuseOperandAdvanced(inst, extra.struct_operand, 0, src_mcv, null)) { |
| 9489 | self.eflags_inst = inst; // actually keep tracking the overflow part | 9440 | self.eflags_inst = inst; // actually keep tracking the overflow part |
| ... | @@ -9541,9 +9492,9 @@ fn airStructFieldVal(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -9541,9 +9492,9 @@ fn airStructFieldVal(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 9541 | | 9492 | |
| 9542 | const hi_mcv = | 9493 | const hi_mcv = |
| 9543 | dst_mcv.address().offset(@intCast(field_bit_size / 64 * 8)).deref(); | 9494 | dst_mcv.address().offset(@intCast(field_bit_size / 64 * 8)).deref(); |
| 9544 | try self.genSetReg(tmp_reg, Type.usize, hi_mcv, .{}); | 9495 | try self.genSetReg(tmp_reg, .usize, hi_mcv, .{}); |
| 9545 | try self.truncateRegister(field_ty, tmp_reg); | 9496 | try self.truncateRegister(field_ty, tmp_reg); |
| 9546 | try self.genCopy(Type.usize, hi_mcv, .{ .register = tmp_reg }, .{}); | 9497 | try self.genCopy(.usize, hi_mcv, .{ .register = tmp_reg }, .{}); |
| 9547 | } | 9498 | } |
| 9548 | break :result dst_mcv; | 9499 | break :result dst_mcv; |
| 9549 | } | 9500 | } |
| ... | @@ -9684,8 +9635,8 @@ fn genUnOp(self: *CodeGen, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_a | ... | @@ -9684,8 +9635,8 @@ fn genUnOp(self: *CodeGen, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_a |
| 9684 | switch (tag) { | 9635 | switch (tag) { |
| 9685 | .not => { | 9636 | .not => { |
| 9686 | const limb_abi_size: u16 = @min(abi_size, 8); | 9637 | const limb_abi_size: u16 = @min(abi_size, 8); |
| 9687 | const int_info = if (src_ty.ip_index == .bool_type) | 9638 | const int_info: InternPool.Key.IntType = if (src_ty.ip_index == .bool_type) |
| 9688 | std.builtin.Type.Int{ .signedness = .unsigned, .bits = 1 } | 9639 | .{ .signedness = .unsigned, .bits = 1 } |
| 9689 | else | 9640 | else |
| 9690 | src_ty.intInfo(zcu); | 9641 | src_ty.intInfo(zcu); |
| 9691 | var byte_off: i32 = 0; | 9642 | var byte_off: i32 = 0; |
| ... | @@ -9718,9 +9669,9 @@ fn genUnOp(self: *CodeGen, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_a | ... | @@ -9718,9 +9669,9 @@ fn genUnOp(self: *CodeGen, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_a |
| 9718 | defer self.register_manager.unlockReg(tmp_lock); | 9669 | defer self.register_manager.unlockReg(tmp_lock); |
| 9719 | | 9670 | |
| 9720 | const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref(); | 9671 | const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref(); |
| 9721 | try self.genSetReg(tmp_reg, Type.usize, hi_mcv, .{}); | 9672 | try self.genSetReg(tmp_reg, .usize, hi_mcv, .{}); |
| 9722 | try self.truncateRegister(src_ty, tmp_reg); | 9673 | try self.truncateRegister(src_ty, tmp_reg); |
| 9723 | try self.genCopy(Type.usize, hi_mcv, .{ .register = tmp_reg }, .{}); | 9674 | try self.genCopy(.usize, hi_mcv, .{ .register = tmp_reg }, .{}); |
| 9724 | } | 9675 | } |
| 9725 | } | 9676 | } |
| 9726 | }, | 9677 | }, |
| ... | @@ -9759,7 +9710,7 @@ fn genUnOpMir(self: *CodeGen, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: | ... | @@ -9759,7 +9710,7 @@ fn genUnOpMir(self: *CodeGen, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: |
| 9759 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 9710 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 9760 | defer self.register_manager.unlockReg(addr_reg_lock); | 9711 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 9761 | | 9712 | |
| 9762 | try self.genSetReg(addr_reg, Type.usize, dst_mcv.address(), .{}); | 9713 | try self.genSetReg(addr_reg, .usize, dst_mcv.address(), .{}); |
| 9763 | try self.asmMemory(mir_tag, .{ .base = .{ .reg = addr_reg }, .mod = .{ .rm = .{ | 9714 | try self.asmMemory(mir_tag, .{ .base = .{ .reg = addr_reg }, .mod = .{ .rm = .{ |
| 9764 | .size = .fromSize(abi_size), | 9715 | .size = .fromSize(abi_size), |
| 9765 | } } }); | 9716 | } } }); |
| ... | @@ -10495,7 +10446,7 @@ fn genMulDivBinOp( | ... | @@ -10495,7 +10446,7 @@ fn genMulDivBinOp( |
| 10495 | const mat_lhs_mcv = switch (lhs_mcv) { | 10446 | const mat_lhs_mcv = switch (lhs_mcv) { |
| 10496 | .load_symbol => mat_lhs_mcv: { | 10447 | .load_symbol => mat_lhs_mcv: { |
| 10497 | // TODO clean this up! | 10448 | // TODO clean this up! |
| 10498 | const addr_reg = try self.copyToTmpRegister(Type.usize, lhs_mcv.address()); | 10449 | const addr_reg = try self.copyToTmpRegister(.usize, lhs_mcv.address()); |
| 10499 | break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; | 10450 | break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; |
| 10500 | }, | 10451 | }, |
| 10501 | else => lhs_mcv, | 10452 | else => lhs_mcv, |
| ... | @@ -10508,7 +10459,7 @@ fn genMulDivBinOp( | ... | @@ -10508,7 +10459,7 @@ fn genMulDivBinOp( |
| 10508 | const mat_rhs_mcv = switch (rhs_mcv) { | 10459 | const mat_rhs_mcv = switch (rhs_mcv) { |
| 10509 | .load_symbol => mat_rhs_mcv: { | 10460 | .load_symbol => mat_rhs_mcv: { |
| 10510 | // TODO clean this up! | 10461 | // TODO clean this up! |
| 10511 | const addr_reg = try self.copyToTmpRegister(Type.usize, rhs_mcv.address()); | 10462 | const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address()); |
| 10512 | break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; | 10463 | break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; |
| 10513 | }, | 10464 | }, |
| 10514 | else => rhs_mcv, | 10465 | else => rhs_mcv, |
| ... | @@ -10696,7 +10647,7 @@ fn genMulDivBinOp( | ... | @@ -10696,7 +10647,7 @@ fn genMulDivBinOp( |
| 10696 | manyptr_u32_ty, | 10647 | manyptr_u32_ty, |
| 10697 | manyptr_const_u32_ty, | 10648 | manyptr_const_u32_ty, |
| 10698 | manyptr_const_u32_ty, | 10649 | manyptr_const_u32_ty, |
| 10699 | Type.usize, | 10650 | .usize, |
| 10700 | }, &.{ | 10651 | }, &.{ |
| 10701 | dst_mcv.address(), | 10652 | dst_mcv.address(), |
| 10702 | lhs_mcv.address(), | 10653 | lhs_mcv.address(), |
| ... | @@ -12493,7 +12444,7 @@ fn genBinOp( | ... | @@ -12493,7 +12444,7 @@ fn genBinOp( |
| 12493 | try not_mcv.mem(self, .{ .size = .fromSize(abi_size) }) | 12444 | try not_mcv.mem(self, .{ .size = .fromSize(abi_size) }) |
| 12494 | else | 12445 | else |
| 12495 | .{ .base = .{ | 12446 | .{ .base = .{ |
| 12496 | .reg = try self.copyToTmpRegister(Type.usize, not_mcv.address()), | 12447 | .reg = try self.copyToTmpRegister(.usize, not_mcv.address()), |
| 12497 | }, .mod = .{ .rm = .{ .size = .fromSize(abi_size) } } }; | 12448 | }, .mod = .{ .rm = .{ .size = .fromSize(abi_size) } } }; |
| 12498 | switch (mir_tag[0]) { | 12449 | switch (mir_tag[0]) { |
| 12499 | .vp_b, .vp_d, .vp_q, .vp_w => try self.asmRegisterRegisterMemory( | 12450 | .vp_b, .vp_d, .vp_q, .vp_w => try self.asmRegisterRegisterMemory( |
| ... | @@ -12757,7 +12708,7 @@ fn genBinOpMir( | ... | @@ -12757,7 +12708,7 @@ fn genBinOpMir( |
| 12757 | const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg); | 12708 | const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg); |
| 12758 | errdefer self.register_manager.unlockReg(dst_addr_lock); | 12709 | errdefer self.register_manager.unlockReg(dst_addr_lock); |
| 12759 | | 12710 | |
| 12760 | try self.genSetReg(dst_addr_reg, Type.usize, dst_mcv.address(), .{}); | 12711 | try self.genSetReg(dst_addr_reg, .usize, dst_mcv.address(), .{}); |
| 12761 | break :dst .{ .addr_reg = dst_addr_reg, .addr_lock = dst_addr_lock }; | 12712 | break :dst .{ .addr_reg = dst_addr_reg, .addr_lock = dst_addr_lock }; |
| 12762 | }, | 12713 | }, |
| 12763 | .load_frame => null, | 12714 | .load_frame => null, |
| ... | @@ -12808,7 +12759,7 @@ fn genBinOpMir( | ... | @@ -12808,7 +12759,7 @@ fn genBinOpMir( |
| 12808 | const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); | 12759 | const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); |
| 12809 | errdefer self.register_manager.unlockReg(src_addr_lock); | 12760 | errdefer self.register_manager.unlockReg(src_addr_lock); |
| 12810 | | 12761 | |
| 12811 | try self.genSetReg(src_addr_reg, Type.usize, resolved_src_mcv.address(), .{}); | 12762 | try self.genSetReg(src_addr_reg, .usize, resolved_src_mcv.address(), .{}); |
| 12812 | break :src .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock }; | 12763 | break :src .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock }; |
| 12813 | }, | 12764 | }, |
| 12814 | }; | 12765 | }; |
| ... | @@ -12816,9 +12767,9 @@ fn genBinOpMir( | ... | @@ -12816,9 +12767,9 @@ fn genBinOpMir( |
| 12816 | | 12767 | |
| 12817 | const ty_signedness = | 12768 | const ty_signedness = |
| 12818 | if (ty.isAbiInt(zcu)) ty.intInfo(zcu).signedness else .unsigned; | 12769 | if (ty.isAbiInt(zcu)) ty.intInfo(zcu).signedness else .unsigned; |
| 12819 | const limb_ty = if (abi_size <= 8) ty else switch (ty_signedness) { | 12770 | const limb_ty: Type = if (abi_size <= 8) ty else switch (ty_signedness) { |
| 12820 | .signed => Type.usize, | 12771 | .signed => .usize, |
| 12821 | .unsigned => Type.isize, | 12772 | .unsigned => .isize, |
| 12822 | }; | 12773 | }; |
| 12823 | var limb_i: usize = 0; | 12774 | var limb_i: usize = 0; |
| 12824 | var off: i32 = 0; | 12775 | var off: i32 = 0; |
| ... | @@ -13310,13 +13261,13 @@ fn genLocalDebugInfo( | ... | @@ -13310,13 +13261,13 @@ fn genLocalDebugInfo( |
| 13310 | | 13261 | |
| 13311 | fn airRetAddr(self: *CodeGen, inst: Air.Inst.Index) !void { | 13262 | fn airRetAddr(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 13312 | const dst_mcv = try self.allocRegOrMem(inst, true); | 13263 | const dst_mcv = try self.allocRegOrMem(inst, true); |
| 13313 | try self.genCopy(Type.usize, dst_mcv, .{ .load_frame = .{ .index = .ret_addr } }, .{}); | 13264 | try self.genCopy(.usize, dst_mcv, .{ .load_frame = .{ .index = .ret_addr } }, .{}); |
| 13314 | return self.finishAir(inst, dst_mcv, .{ .none, .none, .none }); | 13265 | return self.finishAir(inst, dst_mcv, .{ .none, .none, .none }); |
| 13315 | } | 13266 | } |
| 13316 | | 13267 | |
| 13317 | fn airFrameAddress(self: *CodeGen, inst: Air.Inst.Index) !void { | 13268 | fn airFrameAddress(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 13318 | const dst_mcv = try self.allocRegOrMem(inst, true); | 13269 | const dst_mcv = try self.allocRegOrMem(inst, true); |
| 13319 | try self.genCopy(Type.usize, dst_mcv, .{ .lea_frame = .{ .index = .base_ptr } }, .{}); | 13270 | try self.genCopy(.usize, dst_mcv, .{ .lea_frame = .{ .index = .base_ptr } }, .{}); |
| 13320 | return self.finishAir(inst, dst_mcv, .{ .none, .none, .none }); | 13271 | return self.finishAir(inst, dst_mcv, .{ .none, .none, .none }); |
| 13321 | } | 13272 | } |
| 13322 | | 13273 | |
| ... | @@ -13461,13 +13412,10 @@ fn genCall(self: *CodeGen, info: union(enum) { | ... | @@ -13461,13 +13412,10 @@ fn genCall(self: *CodeGen, info: union(enum) { |
| 13461 | defer self.register_manager.unlockReg(index_lock); | 13412 | defer self.register_manager.unlockReg(index_lock); |
| 13462 | | 13413 | |
| 13463 | const src_mem: Memory = if (src_arg.isBase()) try src_arg.mem(self, .{ .size = .dword }) else .{ | 13414 | const src_mem: Memory = if (src_arg.isBase()) try src_arg.mem(self, .{ .size = .dword }) else .{ |
| 13464 | .base = .{ .reg = try self.copyToTmpRegister( | 13415 | .base = .{ .reg = try self.copyToTmpRegister(.usize, switch (src_arg) { |
| 13465 | Type.usize, | 13416 | else => src_arg, |
| 13466 | switch (src_arg) { | 13417 | .air_ref => |src_ref| try self.resolveInst(src_ref), |
| 13467 | else => src_arg, | 13418 | }.address()) }, |
| 13468 | .air_ref => |src_ref| try self.resolveInst(src_ref), | | |
| 13469 | }.address(), | | |
| 13470 | ) }, | | |
| 13471 | .mod = .{ .rm = .{ .size = .dword } }, | 13419 | .mod = .{ .rm = .{ .size = .dword } }, |
| 13472 | }; | 13420 | }; |
| 13473 | const src_lock = switch (src_mem.base) { | 13421 | const src_lock = switch (src_mem.base) { |
| ... | @@ -13519,7 +13467,7 @@ fn genCall(self: *CodeGen, info: union(enum) { | ... | @@ -13519,7 +13467,7 @@ fn genCall(self: *CodeGen, info: union(enum) { |
| 13519 | .indirect => |reg_off| { | 13467 | .indirect => |reg_off| { |
| 13520 | const ret_ty: Type = .fromInterned(fn_info.return_type); | 13468 | const ret_ty: Type = .fromInterned(fn_info.return_type); |
| 13521 | const frame_index = try self.allocFrameIndex(.initSpill(ret_ty, zcu)); | 13469 | const frame_index = try self.allocFrameIndex(.initSpill(ret_ty, zcu)); |
| 13522 | try self.genSetReg(reg_off.reg, Type.usize, .{ | 13470 | try self.genSetReg(reg_off.reg, .usize, .{ |
| 13523 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, | 13471 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, |
| 13524 | }, .{}); | 13472 | }, .{}); |
| 13525 | call_info.return_value.short = .{ .load_frame = .{ .index = frame_index } }; | 13473 | call_info.return_value.short = .{ .load_frame = .{ .index = frame_index } }; |
| ... | @@ -13548,13 +13496,13 @@ fn genCall(self: *CodeGen, info: union(enum) { | ... | @@ -13548,13 +13496,13 @@ fn genCall(self: *CodeGen, info: union(enum) { |
| 13548 | }, | 13496 | }, |
| 13549 | }, | 13497 | }, |
| 13550 | .register_pair => try self.genCopy(arg_ty, dst_arg, src_arg, .{}), | 13498 | .register_pair => try self.genCopy(arg_ty, dst_arg, src_arg, .{}), |
| 13551 | .indirect => |reg_off| try self.genSetReg(reg_off.reg, Type.usize, .{ | 13499 | .indirect => |reg_off| try self.genSetReg(reg_off.reg, .usize, .{ |
| 13552 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, | 13500 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, |
| 13553 | }, .{}), | 13501 | }, .{}), |
| 13554 | .elementwise_regs_then_frame => |regs_frame_addr| { | 13502 | .elementwise_regs_then_frame => |regs_frame_addr| { |
| 13555 | const src_mem: Memory = if (src_arg.isBase()) try src_arg.mem(self, .{ .size = .dword }) else .{ | 13503 | const src_mem: Memory = if (src_arg.isBase()) try src_arg.mem(self, .{ .size = .dword }) else .{ |
| 13556 | .base = .{ .reg = try self.copyToTmpRegister( | 13504 | .base = .{ .reg = try self.copyToTmpRegister( |
| 13557 | Type.usize, | 13505 | .usize, |
| 13558 | switch (src_arg) { | 13506 | switch (src_arg) { |
| 13559 | else => src_arg, | 13507 | else => src_arg, |
| 13560 | .air_ref => |src_ref| try self.resolveInst(src_ref), | 13508 | .air_ref => |src_ref| try self.resolveInst(src_ref), |
| ... | @@ -13604,7 +13552,7 @@ fn genCall(self: *CodeGen, info: union(enum) { | ... | @@ -13604,7 +13552,7 @@ fn genCall(self: *CodeGen, info: union(enum) { |
| 13604 | } else if (self.bin_file.cast(.coff)) |coff_file| { | 13552 | } else if (self.bin_file.cast(.coff)) |coff_file| { |
| 13605 | const atom = try coff_file.getOrCreateAtomForNav(func.owner_nav); | 13553 | const atom = try coff_file.getOrCreateAtomForNav(func.owner_nav); |
| 13606 | const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; | 13554 | const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; |
| 13607 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }, .{}); | 13555 | try self.genSetReg(.rax, .usize, .{ .lea_got = sym_index }, .{}); |
| 13608 | try self.asmRegister(.{ ._, .call }, .rax); | 13556 | try self.asmRegister(.{ ._, .call }, .rax); |
| 13609 | } else if (self.bin_file.cast(.macho)) |macho_file| { | 13557 | } else if (self.bin_file.cast(.macho)) |macho_file| { |
| 13610 | const zo = macho_file.getZigObject().?; | 13558 | const zo = macho_file.getZigObject().?; |
| ... | @@ -13644,7 +13592,7 @@ fn genCall(self: *CodeGen, info: union(enum) { | ... | @@ -13644,7 +13592,7 @@ fn genCall(self: *CodeGen, info: union(enum) { |
| 13644 | } | 13592 | } |
| 13645 | } else { | 13593 | } else { |
| 13646 | assert(self.typeOf(callee).zigTypeTag(zcu) == .pointer); | 13594 | assert(self.typeOf(callee).zigTypeTag(zcu) == .pointer); |
| 13647 | try self.genSetReg(.rax, Type.usize, .{ .air_ref = callee }, .{}); | 13595 | try self.genSetReg(.rax, .usize, .{ .air_ref = callee }, .{}); |
| 13648 | try self.asmRegister(.{ ._, .call }, .rax); | 13596 | try self.asmRegister(.{ ._, .call }, .rax); |
| 13649 | }, | 13597 | }, |
| 13650 | .lib => |lib| if (self.bin_file.cast(.elf)) |elf_file| { | 13598 | .lib => |lib| if (self.bin_file.cast(.elf)) |elf_file| { |
| ... | @@ -13676,7 +13624,7 @@ fn airRet(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -13676,7 +13624,7 @@ fn airRet(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { |
| 13676 | const lock = self.register_manager.lockRegAssumeUnused(reg_off.reg); | 13624 | const lock = self.register_manager.lockRegAssumeUnused(reg_off.reg); |
| 13677 | defer self.register_manager.unlockReg(lock); | 13625 | defer self.register_manager.unlockReg(lock); |
| 13678 | | 13626 | |
| 13679 | try self.genSetReg(reg_off.reg, Type.usize, self.ret_mcv.long, .{}); | 13627 | try self.genSetReg(reg_off.reg, .usize, self.ret_mcv.long, .{}); |
| 13680 | try self.genSetMem( | 13628 | try self.genSetMem( |
| 13681 | .{ .reg = reg_off.reg }, | 13629 | .{ .reg = reg_off.reg }, |
| 13682 | reg_off.off, | 13630 | reg_off.off, |
| ... | @@ -13775,7 +13723,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v | ... | @@ -13775,7 +13723,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v |
| 13775 | floatCompilerRtAbiName(float_bits), | 13723 | floatCompilerRtAbiName(float_bits), |
| 13776 | }) catch unreachable, | 13724 | }) catch unreachable, |
| 13777 | } }, &.{ ty, ty }, &.{ .{ .air_ref = bin_op.lhs }, .{ .air_ref = bin_op.rhs } }); | 13725 | } }, &.{ ty, ty }, &.{ .{ .air_ref = bin_op.lhs }, .{ .air_ref = bin_op.rhs } }); |
| 13778 | try self.genBinOpMir(.{ ._, .@"test" }, Type.i32, ret, ret); | 13726 | try self.genBinOpMir(.{ ._, .@"test" }, .i32, ret, ret); |
| 13779 | break :result switch (op) { | 13727 | break :result switch (op) { |
| 13780 | .eq => .e, | 13728 | .eq => .e, |
| 13781 | .neq => .ne, | 13729 | .neq => .ne, |
| ... | @@ -13938,12 +13886,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v | ... | @@ -13938,12 +13886,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v |
| 13938 | self.register_manager.lockRegAssumeUnused(dst_addr_reg); | 13886 | self.register_manager.lockRegAssumeUnused(dst_addr_reg); |
| 13939 | errdefer self.register_manager.unlockReg(dst_addr_lock); | 13887 | errdefer self.register_manager.unlockReg(dst_addr_lock); |
| 13940 | | 13888 | |
| 13941 | try self.genSetReg( | 13889 | try self.genSetReg(dst_addr_reg, .usize, resolved_dst_mcv.address(), .{}); |
| 13942 | dst_addr_reg, | | |
| 13943 | Type.usize, | | |
| 13944 | resolved_dst_mcv.address(), | | |
| 13945 | .{}, | | |
| 13946 | ); | | |
| 13947 | break :dst .{ | 13890 | break :dst .{ |
| 13948 | .addr_reg = dst_addr_reg, | 13891 | .addr_reg = dst_addr_reg, |
| 13949 | .addr_lock = dst_addr_lock, | 13892 | .addr_lock = dst_addr_lock, |
| ... | @@ -14000,12 +13943,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v | ... | @@ -14000,12 +13943,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v |
| 14000 | self.register_manager.lockRegAssumeUnused(src_addr_reg); | 13943 | self.register_manager.lockRegAssumeUnused(src_addr_reg); |
| 14001 | errdefer self.register_manager.unlockReg(src_addr_lock); | 13944 | errdefer self.register_manager.unlockReg(src_addr_lock); |
| 14002 | | 13945 | |
| 14003 | try self.genSetReg( | 13946 | try self.genSetReg(src_addr_reg, .usize, resolved_src_mcv.address(), .{}); |
| 14004 | src_addr_reg, | | |
| 14005 | Type.usize, | | |
| 14006 | resolved_src_mcv.address(), | | |
| 14007 | .{}, | | |
| 14008 | ); | | |
| 14009 | break :src .{ | 13947 | break :src .{ |
| 14010 | .addr_reg = src_addr_reg, | 13948 | .addr_reg = src_addr_reg, |
| 14011 | .addr_lock = src_addr_lock, | 13949 | .addr_lock = src_addr_lock, |
| ... | @@ -14026,7 +13964,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v | ... | @@ -14026,7 +13964,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v |
| 14026 | const off = limb_i * 8; | 13964 | const off = limb_i * 8; |
| 14027 | const tmp_reg = regs[@min(limb_i, 1)].to64(); | 13965 | const tmp_reg = regs[@min(limb_i, 1)].to64(); |
| 14028 | | 13966 | |
| 14029 | try self.genSetReg(tmp_reg, Type.usize, if (dst_info) |info| .{ | 13967 | try self.genSetReg(tmp_reg, .usize, if (dst_info) |info| .{ |
| 14030 | .indirect = .{ .reg = info.addr_reg, .off = off }, | 13968 | .indirect = .{ .reg = info.addr_reg, .off = off }, |
| 14031 | } else switch (resolved_dst_mcv) { | 13969 | } else switch (resolved_dst_mcv) { |
| 14032 | inline .register_pair, | 13970 | inline .register_pair, |
| ... | @@ -14049,7 +13987,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v | ... | @@ -14049,7 +13987,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v |
| 14049 | | 13987 | |
| 14050 | try self.genBinOpMir( | 13988 | try self.genBinOpMir( |
| 14051 | .{ ._, .xor }, | 13989 | .{ ._, .xor }, |
| 14052 | Type.usize, | 13990 | .usize, |
| 14053 | .{ .register = tmp_reg }, | 13991 | .{ .register = tmp_reg }, |
| 14054 | if (src_info) |info| .{ | 13992 | if (src_info) |info| .{ |
| 14055 | .indirect = .{ .reg = info.addr_reg, .off = off }, | 13993 | .indirect = .{ .reg = info.addr_reg, .off = off }, |
| ... | @@ -14244,7 +14182,7 @@ fn genTry( | ... | @@ -14244,7 +14182,7 @@ fn genTry( |
| 14244 | else | 14182 | else |
| 14245 | try self.isErr(null, operand_ty, operand_mcv); | 14183 | try self.isErr(null, operand_ty, operand_mcv); |
| 14246 | | 14184 | |
| 14247 | const reloc = try self.genCondBrMir(Type.anyerror, is_err_mcv); | 14185 | const reloc = try self.genCondBrMir(.anyerror, is_err_mcv); |
| 14248 | | 14186 | |
| 14249 | if (self.liveness.operandDies(inst, 0)) { | 14187 | if (self.liveness.operandDies(inst, 0)) { |
| 14250 | if (operand.toIndex()) |operand_inst| try self.processDeath(operand_inst); | 14188 | if (operand.toIndex()) |operand_inst| try self.processDeath(operand_inst); |
| ... | @@ -14406,7 +14344,7 @@ fn isNull(self: *CodeGen, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) | ... | @@ -14406,7 +14344,7 @@ fn isNull(self: *CodeGen, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) |
| 14406 | const some_info: struct { off: u31, ty: Type } = if (opt_ty.optionalReprIsPayload(zcu)) | 14344 | const some_info: struct { off: u31, ty: Type } = if (opt_ty.optionalReprIsPayload(zcu)) |
| 14407 | .{ .off = 0, .ty = if (pl_ty.isSlice(zcu)) pl_ty.slicePtrFieldType(zcu) else pl_ty } | 14345 | .{ .off = 0, .ty = if (pl_ty.isSlice(zcu)) pl_ty.slicePtrFieldType(zcu) else pl_ty } |
| 14408 | else | 14346 | else |
| 14409 | .{ .off = @intCast(pl_ty.abiSize(zcu)), .ty = Type.bool }; | 14347 | .{ .off = @intCast(pl_ty.abiSize(zcu)), .ty = .bool }; |
| 14410 | | 14348 | |
| 14411 | self.eflags_inst = inst; | 14349 | self.eflags_inst = inst; |
| 14412 | switch (opt_mcv) { | 14350 | switch (opt_mcv) { |
| ... | @@ -14481,7 +14419,7 @@ fn isNull(self: *CodeGen, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) | ... | @@ -14481,7 +14419,7 @@ fn isNull(self: *CodeGen, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) |
| 14481 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 14419 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 14482 | defer self.register_manager.unlockReg(addr_reg_lock); | 14420 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 14483 | | 14421 | |
| 14484 | try self.genSetReg(addr_reg, Type.usize, opt_mcv.address(), .{}); | 14422 | try self.genSetReg(addr_reg, .usize, opt_mcv.address(), .{}); |
| 14485 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(zcu)); | 14423 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(zcu)); |
| 14486 | try self.asmMemoryImmediate( | 14424 | try self.asmMemoryImmediate( |
| 14487 | .{ ._, .cmp }, | 14425 | .{ ._, .cmp }, |
| ... | @@ -14536,7 +14474,7 @@ fn isNullPtr(self: *CodeGen, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValu | ... | @@ -14536,7 +14474,7 @@ fn isNullPtr(self: *CodeGen, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValu |
| 14536 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(zcu)) | 14474 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(zcu)) |
| 14537 | .{ .off = 0, .ty = if (pl_ty.isSlice(zcu)) pl_ty.slicePtrFieldType(zcu) else pl_ty } | 14475 | .{ .off = 0, .ty = if (pl_ty.isSlice(zcu)) pl_ty.slicePtrFieldType(zcu) else pl_ty } |
| 14538 | else | 14476 | else |
| 14539 | .{ .off = @intCast(pl_ty.abiSize(zcu)), .ty = Type.bool }; | 14477 | .{ .off = @intCast(pl_ty.abiSize(zcu)), .ty = .bool }; |
| 14540 | | 14478 | |
| 14541 | const ptr_reg = switch (ptr_mcv) { | 14479 | const ptr_reg = switch (ptr_mcv) { |
| 14542 | .register => |reg| reg, | 14480 | .register => |reg| reg, |
| ... | @@ -14582,22 +14520,17 @@ fn isErr(self: *CodeGen, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCVal | ... | @@ -14582,22 +14520,17 @@ fn isErr(self: *CodeGen, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCVal |
| 14582 | .{ ._r, .sh }, | 14520 | .{ ._r, .sh }, |
| 14583 | eu_ty, | 14521 | eu_ty, |
| 14584 | .{ .register = tmp_reg }, | 14522 | .{ .register = tmp_reg }, |
| 14585 | Type.u8, | 14523 | .u8, |
| 14586 | .{ .immediate = @as(u6, @intCast(err_off * 8)) }, | 14524 | .{ .immediate = @as(u6, @intCast(err_off * 8)) }, |
| 14587 | ); | 14525 | ); |
| 14588 | } else { | 14526 | } else { |
| 14589 | try self.truncateRegister(Type.anyerror, tmp_reg); | 14527 | try self.truncateRegister(.anyerror, tmp_reg); |
| 14590 | } | 14528 | } |
| 14591 | try self.genBinOpMir( | 14529 | try self.genBinOpMir(.{ ._, .cmp }, .anyerror, .{ .register = tmp_reg }, .{ .immediate = 0 }); |
| 14592 | .{ ._, .cmp }, | | |
| 14593 | Type.anyerror, | | |
| 14594 | .{ .register = tmp_reg }, | | |
| 14595 | .{ .immediate = 0 }, | | |
| 14596 | ); | | |
| 14597 | }, | 14530 | }, |
| 14598 | .load_frame => |frame_addr| try self.genBinOpMir( | 14531 | .load_frame => |frame_addr| try self.genBinOpMir( |
| 14599 | .{ ._, .cmp }, | 14532 | .{ ._, .cmp }, |
| 14600 | Type.anyerror, | 14533 | .anyerror, |
| 14601 | .{ .load_frame = .{ | 14534 | .{ .load_frame = .{ |
| 14602 | .index = frame_addr.index, | 14535 | .index = frame_addr.index, |
| 14603 | .off = frame_addr.off + err_off, | 14536 | .off = frame_addr.off + err_off, |
| ... | @@ -14633,7 +14566,7 @@ fn isErrPtr(self: *CodeGen, maybe_inst: ?Air.Inst.Index, ptr_ty: Type, ptr_mcv: | ... | @@ -14633,7 +14566,7 @@ fn isErrPtr(self: *CodeGen, maybe_inst: ?Air.Inst.Index, ptr_ty: Type, ptr_mcv: |
| 14633 | .{ | 14566 | .{ |
| 14634 | .base = .{ .reg = ptr_reg }, | 14567 | .base = .{ .reg = ptr_reg }, |
| 14635 | .mod = .{ .rm = .{ | 14568 | .mod = .{ .rm = .{ |
| 14636 | .size = self.memSize(Type.anyerror), | 14569 | .size = self.memSize(.anyerror), |
| 14637 | .disp = err_off, | 14570 | .disp = err_off, |
| 14638 | } }, | 14571 | } }, |
| 14639 | }, | 14572 | }, |
| ... | @@ -15200,7 +15133,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -15200,7 +15133,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 15200 | .register, .register_offset, .lea_frame => break :arg ptr_mcv.deref(), | 15133 | .register, .register_offset, .lea_frame => break :arg ptr_mcv.deref(), |
| 15201 | else => {}, | 15134 | else => {}, |
| 15202 | } | 15135 | } |
| 15203 | break :arg .{ .indirect = .{ .reg = try self.copyToTmpRegister(Type.usize, ptr_mcv) } }; | 15136 | break :arg .{ .indirect = .{ .reg = try self.copyToTmpRegister(.usize, ptr_mcv) } }; |
| 15204 | }; | 15137 | }; |
| 15205 | }; | 15138 | }; |
| 15206 | if (arg_mcv.getReg()) |reg| if (RegisterManager.indexOfRegIntoTracked(reg)) |_| { | 15139 | if (arg_mcv.getReg()) |reg| if (RegisterManager.indexOfRegIntoTracked(reg)) |_| { |
| ... | @@ -15262,7 +15195,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -15262,7 +15195,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 15262 | try self.genCopy(ty, temp_mcv, input_mcv, .{}); | 15195 | try self.genCopy(ty, temp_mcv, input_mcv, .{}); |
| 15263 | break :arg temp_mcv; | 15196 | break :arg temp_mcv; |
| 15264 | }; | 15197 | }; |
| 15265 | try self.genSetReg(addr_reg, Type.usize, input_mcv.address(), .{}); | 15198 | try self.genSetReg(addr_reg, .usize, input_mcv.address(), .{}); |
| 15266 | break :arg .{ .indirect = .{ .reg = addr_reg } }; | 15199 | break :arg .{ .indirect = .{ .reg = addr_reg } }; |
| 15267 | } else if (std.mem.eql(u8, constraint, "g") or | 15200 | } else if (std.mem.eql(u8, constraint, "g") or |
| 15268 | std.mem.eql(u8, constraint, "rm") or std.mem.eql(u8, constraint, "mr") or | 15201 | std.mem.eql(u8, constraint, "rm") or std.mem.eql(u8, constraint, "mr") or |
| ... | @@ -15539,11 +15472,11 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -15539,11 +15472,11 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 15539 | else | 15472 | else |
| 15540 | return self.fail("invalid modifier: '{s}'", .{modifier}), | 15473 | return self.fail("invalid modifier: '{s}'", .{modifier}), |
| 15541 | .lea_got => |sym_index| if (std.mem.eql(u8, modifier, "P")) | 15474 | .lea_got => |sym_index| if (std.mem.eql(u8, modifier, "P")) |
| 15542 | .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .lea_got = sym_index }) } | 15475 | .{ .reg = try self.copyToTmpRegister(.usize, .{ .lea_got = sym_index }) } |
| 15543 | else | 15476 | else |
| 15544 | return self.fail("invalid modifier: '{s}'", .{modifier}), | 15477 | return self.fail("invalid modifier: '{s}'", .{modifier}), |
| 15545 | .lea_symbol => |sym_off| if (std.mem.eql(u8, modifier, "P")) | 15478 | .lea_symbol => |sym_off| if (std.mem.eql(u8, modifier, "P")) |
| 15546 | .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .lea_symbol = sym_off }) } | 15479 | .{ .reg = try self.copyToTmpRegister(.usize, .{ .lea_symbol = sym_off }) } |
| 15547 | else | 15480 | else |
| 15548 | return self.fail("invalid modifier: '{s}'", .{modifier}), | 15481 | return self.fail("invalid modifier: '{s}'", .{modifier}), |
| 15549 | else => return self.fail("invalid constraint: '{s}'", .{op_str}), | 15482 | else => return self.fail("invalid constraint: '{s}'", .{op_str}), |
| ... | @@ -16099,7 +16032,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C | ... | @@ -16099,7 +16032,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C |
| 16099 | const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); | 16032 | const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); |
| 16100 | errdefer self.register_manager.unlockReg(src_addr_lock); | 16033 | errdefer self.register_manager.unlockReg(src_addr_lock); |
| 16101 | | 16034 | |
| 16102 | try self.genSetReg(src_addr_reg, Type.usize, src_mcv.address(), opts); | 16035 | try self.genSetReg(src_addr_reg, .usize, src_mcv.address(), opts); |
| 16103 | break :src .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock }; | 16036 | break :src .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock }; |
| 16104 | }, | 16037 | }, |
| 16105 | .air_ref => |src_ref| return self.genCopy( | 16038 | .air_ref => |src_ref| return self.genCopy( |
| ... | @@ -16146,7 +16079,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C | ... | @@ -16146,7 +16079,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C |
| 16146 | else => unreachable, | 16079 | else => unreachable, |
| 16147 | } | 16080 | } |
| 16148 | | 16081 | |
| 16149 | const addr_reg = try self.copyToTmpRegister(Type.usize, dst_mcv.address()); | 16082 | const addr_reg = try self.copyToTmpRegister(.usize, dst_mcv.address()); |
| 16150 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 16083 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 16151 | defer self.register_manager.unlockReg(addr_lock); | 16084 | defer self.register_manager.unlockReg(addr_lock); |
| 16152 | | 16085 | |
| ... | @@ -16445,7 +16378,7 @@ fn genSetReg( | ... | @@ -16445,7 +16378,7 @@ fn genSetReg( |
| 16445 | else => unreachable, | 16378 | else => unreachable, |
| 16446 | } | 16379 | } |
| 16447 | | 16380 | |
| 16448 | const addr_reg = try self.copyToTmpRegister(Type.usize, src_mcv.address()); | 16381 | const addr_reg = try self.copyToTmpRegister(.usize, src_mcv.address()); |
| 16449 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 16382 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 16450 | defer self.register_manager.unlockReg(addr_lock); | 16383 | defer self.register_manager.unlockReg(addr_lock); |
| 16451 | | 16384 | |
| ... | @@ -16656,7 +16589,7 @@ fn genSetMem( | ... | @@ -16656,7 +16589,7 @@ fn genSetMem( |
| 16656 | try self.genSetMem( | 16589 | try self.genSetMem( |
| 16657 | base, | 16590 | base, |
| 16658 | disp + @as(i32, @intCast(child_ty.abiSize(zcu))), | 16591 | disp + @as(i32, @intCast(child_ty.abiSize(zcu))), |
| 16659 | Type.bool, | 16592 | .bool, |
| 16660 | .{ .eflags = ro.eflags }, | 16593 | .{ .eflags = ro.eflags }, |
| 16661 | opts, | 16594 | opts, |
| 16662 | ); | 16595 | ); |
| ... | @@ -16732,9 +16665,9 @@ fn genSetMem( | ... | @@ -16732,9 +16665,9 @@ fn genSetMem( |
| 16732 | | 16665 | |
| 16733 | fn genInlineMemcpy(self: *CodeGen, dst_ptr: MCValue, src_ptr: MCValue, len: MCValue) InnerError!void { | 16666 | fn genInlineMemcpy(self: *CodeGen, dst_ptr: MCValue, src_ptr: MCValue, len: MCValue) InnerError!void { |
| 16734 | try self.spillRegisters(&.{ .rsi, .rdi, .rcx }); | 16667 | try self.spillRegisters(&.{ .rsi, .rdi, .rcx }); |
| 16735 | try self.genSetReg(.rsi, Type.usize, src_ptr, .{}); | 16668 | try self.genSetReg(.rsi, .usize, src_ptr, .{}); |
| 16736 | try self.genSetReg(.rdi, Type.usize, dst_ptr, .{}); | 16669 | try self.genSetReg(.rdi, .usize, dst_ptr, .{}); |
| 16737 | try self.genSetReg(.rcx, Type.usize, len, .{}); | 16670 | try self.genSetReg(.rcx, .usize, len, .{}); |
| 16738 | try self.asmOpOnly(.{ .@"rep _sb", .mov }); | 16671 | try self.asmOpOnly(.{ .@"rep _sb", .mov }); |
| 16739 | } | 16672 | } |
| 16740 | | 16673 | |
| ... | @@ -16746,9 +16679,9 @@ fn genInlineMemset( | ... | @@ -16746,9 +16679,9 @@ fn genInlineMemset( |
| 16746 | opts: CopyOptions, | 16679 | opts: CopyOptions, |
| 16747 | ) InnerError!void { | 16680 | ) InnerError!void { |
| 16748 | try self.spillRegisters(&.{ .rdi, .al, .rcx }); | 16681 | try self.spillRegisters(&.{ .rdi, .al, .rcx }); |
| 16749 | try self.genSetReg(.rdi, Type.usize, dst_ptr, .{}); | 16682 | try self.genSetReg(.rdi, .usize, dst_ptr, .{}); |
| 16750 | try self.genSetReg(.al, Type.u8, value, opts); | 16683 | try self.genSetReg(.al, .u8, value, opts); |
| 16751 | try self.genSetReg(.rcx, Type.usize, len, .{}); | 16684 | try self.genSetReg(.rcx, .usize, len, .{}); |
| 16752 | try self.asmOpOnly(.{ .@"rep _sb", .sto }); | 16685 | try self.asmOpOnly(.{ .@"rep _sb", .sto }); |
| 16753 | } | 16686 | } |
| 16754 | | 16687 | |
| ... | @@ -16791,10 +16724,10 @@ fn genLazySymbolRef( | ... | @@ -16791,10 +16724,10 @@ fn genLazySymbolRef( |
| 16791 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); | 16724 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 16792 | if (self.mod.pic) { | 16725 | if (self.mod.pic) { |
| 16793 | switch (tag) { | 16726 | switch (tag) { |
| 16794 | .lea, .call => try self.genSetReg(reg, Type.usize, .{ | 16727 | .lea, .call => try self.genSetReg(reg, .usize, .{ |
| 16795 | .lea_symbol = .{ .sym_index = sym_index }, | 16728 | .lea_symbol = .{ .sym_index = sym_index }, |
| 16796 | }, .{}), | 16729 | }, .{}), |
| 16797 | .mov => try self.genSetReg(reg, Type.usize, .{ | 16730 | .mov => try self.genSetReg(reg, .usize, .{ |
| 16798 | .load_symbol = .{ .sym_index = sym_index }, | 16731 | .load_symbol = .{ .sym_index = sym_index }, |
| 16799 | }, .{}), | 16732 | }, .{}), |
| 16800 | else => unreachable, | 16733 | else => unreachable, |
| ... | @@ -16844,8 +16777,8 @@ fn genLazySymbolRef( | ... | @@ -16844,8 +16777,8 @@ fn genLazySymbolRef( |
| 16844 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); | 16777 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 16845 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; | 16778 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; |
| 16846 | switch (tag) { | 16779 | switch (tag) { |
| 16847 | .lea, .call => try self.genSetReg(reg, Type.usize, .{ .lea_got = sym_index }, .{}), | 16780 | .lea, .call => try self.genSetReg(reg, .usize, .{ .lea_got = sym_index }, .{}), |
| 16848 | .mov => try self.genSetReg(reg, Type.usize, .{ .load_got = sym_index }, .{}), | 16781 | .mov => try self.genSetReg(reg, .usize, .{ .load_got = sym_index }, .{}), |
| 16849 | else => unreachable, | 16782 | else => unreachable, |
| 16850 | } | 16783 | } |
| 16851 | switch (tag) { | 16784 | switch (tag) { |
| ... | @@ -16859,10 +16792,10 @@ fn genLazySymbolRef( | ... | @@ -16859,10 +16792,10 @@ fn genLazySymbolRef( |
| 16859 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); | 16792 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 16860 | const sym = zo.symbols.items[sym_index]; | 16793 | const sym = zo.symbols.items[sym_index]; |
| 16861 | switch (tag) { | 16794 | switch (tag) { |
| 16862 | .lea, .call => try self.genSetReg(reg, Type.usize, .{ | 16795 | .lea, .call => try self.genSetReg(reg, .usize, .{ |
| 16863 | .lea_symbol = .{ .sym_index = sym.nlist_idx }, | 16796 | .lea_symbol = .{ .sym_index = sym.nlist_idx }, |
| 16864 | }, .{}), | 16797 | }, .{}), |
| 16865 | .mov => try self.genSetReg(reg, Type.usize, .{ | 16798 | .mov => try self.genSetReg(reg, .usize, .{ |
| 16866 | .load_symbol = .{ .sym_index = sym.nlist_idx }, | 16799 | .load_symbol = .{ .sym_index = sym.nlist_idx }, |
| 16867 | }, .{}), | 16800 | }, .{}), |
| 16868 | else => unreachable, | 16801 | else => unreachable, |
| ... | @@ -16932,7 +16865,7 @@ fn airBitCast(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -16932,7 +16865,7 @@ fn airBitCast(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 16932 | const bit_size = dst_ty.bitSize(zcu); | 16865 | const bit_size = dst_ty.bitSize(zcu); |
| 16933 | if (abi_size * 8 <= bit_size or dst_ty.isVector(zcu)) break :result dst_mcv; | 16866 | if (abi_size * 8 <= bit_size or dst_ty.isVector(zcu)) break :result dst_mcv; |
| 16934 | | 16867 | |
| 16935 | const dst_limbs_len = std.math.divCeil(i32, @intCast(bit_size), 64) catch unreachable; | 16868 | const dst_limbs_len = std.math.divCeil(u31, @intCast(bit_size), 64) catch unreachable; |
| 16936 | const high_mcv: MCValue = switch (dst_mcv) { | 16869 | const high_mcv: MCValue = switch (dst_mcv) { |
| 16937 | .register => |dst_reg| .{ .register = dst_reg }, | 16870 | .register => |dst_reg| .{ .register = dst_reg }, |
| 16938 | .register_pair => |dst_regs| .{ .register = dst_regs[1] }, | 16871 | .register_pair => |dst_regs| .{ .register = dst_regs[1] }, |
| ... | @@ -16941,17 +16874,43 @@ fn airBitCast(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -16941,17 +16874,43 @@ fn airBitCast(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 16941 | const high_reg = if (high_mcv.isRegister()) | 16874 | const high_reg = if (high_mcv.isRegister()) |
| 16942 | high_mcv.getReg().? | 16875 | high_mcv.getReg().? |
| 16943 | else | 16876 | else |
| 16944 | try self.copyToTmpRegister(Type.usize, high_mcv); | 16877 | try self.copyToTmpRegister(.usize, high_mcv); |
| 16945 | const high_lock = self.register_manager.lockReg(high_reg); | 16878 | const high_lock = self.register_manager.lockReg(high_reg); |
| 16946 | defer if (high_lock) |lock| self.register_manager.unlockReg(lock); | 16879 | defer if (high_lock) |lock| self.register_manager.unlockReg(lock); |
| 16947 | | | |
| 16948 | try self.truncateRegister(dst_ty, high_reg); | 16880 | try self.truncateRegister(dst_ty, high_reg); |
| 16949 | if (!high_mcv.isRegister()) try self.genCopy( | 16881 | if (!high_mcv.isRegister()) try self.genCopy( |
| 16950 | if (abi_size <= 8) dst_ty else Type.usize, | 16882 | if (abi_size <= 8) dst_ty else .usize, |
| 16951 | high_mcv, | 16883 | high_mcv, |
| 16952 | .{ .register = high_reg }, | 16884 | .{ .register = high_reg }, |
| 16953 | .{}, | 16885 | .{}, |
| 16954 | ); | 16886 | ); |
| | 16887 | var offset = dst_limbs_len * 8; |
| | 16888 | if (offset < abi_size) { |
| | 16889 | const dst_signedness: std.builtin.Signedness = if (dst_ty.isAbiInt(zcu)) |
| | 16890 | dst_ty.intInfo(zcu).signedness |
| | 16891 | else |
| | 16892 | .unsigned; |
| | 16893 | const ext_mcv: MCValue = ext_mcv: switch (dst_signedness) { |
| | 16894 | .signed => { |
| | 16895 | try self.asmRegisterImmediate(.{ ._r, .sa }, high_reg, .u(63)); |
| | 16896 | break :ext_mcv .{ .register = high_reg }; |
| | 16897 | }, |
| | 16898 | .unsigned => .{ .immediate = 0 }, |
| | 16899 | }; |
| | 16900 | while (offset < abi_size) : (offset += 8) { |
| | 16901 | const limb_mcv: MCValue = switch (dst_mcv) { |
| | 16902 | .register => |dst_reg| .{ .register = dst_reg }, |
| | 16903 | .register_pair => |dst_regs| .{ .register = dst_regs[@divExact(offset, 8)] }, |
| | 16904 | else => dst_mcv.address().offset(offset).deref(), |
| | 16905 | }; |
| | 16906 | const limb_lock = if (limb_mcv.isRegister()) |
| | 16907 | self.register_manager.lockReg(limb_mcv.getReg().?) |
| | 16908 | else |
| | 16909 | null; |
| | 16910 | defer if (limb_lock) |lock| self.register_manager.unlockReg(lock); |
| | 16911 | try self.genCopy(.usize, limb_mcv, ext_mcv, .{}); |
| | 16912 | } |
| | 16913 | } |
| 16955 | break :result dst_mcv; | 16914 | break :result dst_mcv; |
| 16956 | }; | 16915 | }; |
| 16957 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 16916 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| ... | @@ -16973,7 +16932,7 @@ fn airArrayToSlice(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -16973,7 +16932,7 @@ fn airArrayToSlice(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 16973 | try self.genSetMem( | 16932 | try self.genSetMem( |
| 16974 | .{ .frame = frame_index }, | 16933 | .{ .frame = frame_index }, |
| 16975 | @intCast(ptr_ty.abiSize(zcu)), | 16934 | @intCast(ptr_ty.abiSize(zcu)), |
| 16976 | Type.usize, | 16935 | .usize, |
| 16977 | .{ .immediate = array_len }, | 16936 | .{ .immediate = array_len }, |
| 16978 | .{}, | 16937 | .{}, |
| 16979 | ); | 16938 | ); |
| ... | @@ -17151,28 +17110,28 @@ fn airCmpxchg(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -17151,28 +17110,28 @@ fn airCmpxchg(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 17151 | if (val_abi_size > 8) { | 17110 | if (val_abi_size > 8) { |
| 17152 | const exp_addr_mcv: MCValue = switch (exp_mcv) { | 17111 | const exp_addr_mcv: MCValue = switch (exp_mcv) { |
| 17153 | .memory, .indirect, .load_frame => exp_mcv.address(), | 17112 | .memory, .indirect, .load_frame => exp_mcv.address(), |
| 17154 | else => .{ .register = try self.copyToTmpRegister(Type.usize, exp_mcv.address()) }, | 17113 | else => .{ .register = try self.copyToTmpRegister(.usize, exp_mcv.address()) }, |
| 17155 | }; | 17114 | }; |
| 17156 | const exp_addr_lock = | 17115 | const exp_addr_lock = |
| 17157 | if (exp_addr_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; | 17116 | if (exp_addr_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; |
| 17158 | defer if (exp_addr_lock) |lock| self.register_manager.unlockReg(lock); | 17117 | defer if (exp_addr_lock) |lock| self.register_manager.unlockReg(lock); |
| 17159 | | 17118 | |
| 17160 | try self.genSetReg(.rax, Type.usize, exp_addr_mcv.deref(), .{}); | 17119 | try self.genSetReg(.rax, .usize, exp_addr_mcv.deref(), .{}); |
| 17161 | try self.genSetReg(.rdx, Type.usize, exp_addr_mcv.offset(8).deref(), .{}); | 17120 | try self.genSetReg(.rdx, .usize, exp_addr_mcv.offset(8).deref(), .{}); |
| 17162 | } else try self.genSetReg(.rax, val_ty, exp_mcv, .{}); | 17121 | } else try self.genSetReg(.rax, val_ty, exp_mcv, .{}); |
| 17163 | | 17122 | |
| 17164 | const new_mcv = try self.resolveInst(extra.new_value); | 17123 | const new_mcv = try self.resolveInst(extra.new_value); |
| 17165 | const new_reg = if (val_abi_size > 8) new: { | 17124 | const new_reg = if (val_abi_size > 8) new: { |
| 17166 | const new_addr_mcv: MCValue = switch (new_mcv) { | 17125 | const new_addr_mcv: MCValue = switch (new_mcv) { |
| 17167 | .memory, .indirect, .load_frame => new_mcv.address(), | 17126 | .memory, .indirect, .load_frame => new_mcv.address(), |
| 17168 | else => .{ .register = try self.copyToTmpRegister(Type.usize, new_mcv.address()) }, | 17127 | else => .{ .register = try self.copyToTmpRegister(.usize, new_mcv.address()) }, |
| 17169 | }; | 17128 | }; |
| 17170 | const new_addr_lock = | 17129 | const new_addr_lock = |
| 17171 | if (new_addr_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; | 17130 | if (new_addr_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; |
| 17172 | defer if (new_addr_lock) |lock| self.register_manager.unlockReg(lock); | 17131 | defer if (new_addr_lock) |lock| self.register_manager.unlockReg(lock); |
| 17173 | | 17132 | |
| 17174 | try self.genSetReg(.rbx, Type.usize, new_addr_mcv.deref(), .{}); | 17133 | try self.genSetReg(.rbx, .usize, new_addr_mcv.deref(), .{}); |
| 17175 | try self.genSetReg(.rcx, Type.usize, new_addr_mcv.offset(8).deref(), .{}); | 17134 | try self.genSetReg(.rcx, .usize, new_addr_mcv.offset(8).deref(), .{}); |
| 17176 | break :new null; | 17135 | break :new null; |
| 17177 | } else try self.copyToTmpRegister(val_ty, new_mcv); | 17136 | } else try self.copyToTmpRegister(val_ty, new_mcv); |
| 17178 | const new_lock = if (new_reg) |reg| self.register_manager.lockRegAssumeUnused(reg) else null; | 17137 | const new_lock = if (new_reg) |reg| self.register_manager.lockRegAssumeUnused(reg) else null; |
| ... | @@ -17213,9 +17172,9 @@ fn airCmpxchg(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -17213,9 +17172,9 @@ fn airCmpxchg(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 17213 | } | 17172 | } |
| 17214 | | 17173 | |
| 17215 | const dst_mcv = try self.allocRegOrMem(inst, false); | 17174 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 17216 | try self.genCopy(Type.usize, dst_mcv, .{ .register = .rax }, .{}); | 17175 | try self.genCopy(.usize, dst_mcv, .{ .register = .rax }, .{}); |
| 17217 | try self.genCopy(Type.usize, dst_mcv.address().offset(8).deref(), .{ .register = .rdx }, .{}); | 17176 | try self.genCopy(.usize, dst_mcv.address().offset(8).deref(), .{ .register = .rdx }, .{}); |
| 17218 | try self.genCopy(Type.bool, dst_mcv.address().offset(16).deref(), .{ .eflags = .ne }, .{}); | 17177 | try self.genCopy(.bool, dst_mcv.address().offset(16).deref(), .{ .eflags = .ne }, .{}); |
| 17219 | break :result dst_mcv; | 17178 | break :result dst_mcv; |
| 17220 | }; | 17179 | }; |
| 17221 | return self.finishAir(inst, result, .{ extra.ptr, extra.expected_value, extra.new_value }); | 17180 | return self.finishAir(inst, result, .{ extra.ptr, extra.expected_value, extra.new_value }); |
| ... | @@ -17488,7 +17447,7 @@ fn atomicOp( | ... | @@ -17488,7 +17447,7 @@ fn atomicOp( |
| 17488 | const val_mem_mcv: MCValue = switch (val_mcv) { | 17447 | const val_mem_mcv: MCValue = switch (val_mcv) { |
| 17489 | .memory, .indirect, .load_frame => val_mcv, | 17448 | .memory, .indirect, .load_frame => val_mcv, |
| 17490 | else => .{ .indirect = .{ | 17449 | else => .{ .indirect = .{ |
| 17491 | .reg = try self.copyToTmpRegister(Type.usize, val_mcv.address()), | 17450 | .reg = try self.copyToTmpRegister(.usize, val_mcv.address()), |
| 17492 | } }, | 17451 | } }, |
| 17493 | }; | 17452 | }; |
| 17494 | const val_lo_mem = try val_mem_mcv.mem(self, .{ .size = .qword }); | 17453 | const val_lo_mem = try val_mem_mcv.mem(self, .{ .size = .qword }); |
| ... | @@ -17545,7 +17504,7 @@ fn atomicOp( | ... | @@ -17545,7 +17504,7 @@ fn atomicOp( |
| 17545 | }, | 17504 | }, |
| 17546 | }; | 17505 | }; |
| 17547 | | 17506 | |
| 17548 | const tmp_reg = try self.copyToTmpRegister(Type.usize, .{ .register = .rcx }); | 17507 | const tmp_reg = try self.copyToTmpRegister(.usize, .{ .register = .rcx }); |
| 17549 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 17508 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 17550 | defer self.register_manager.unlockReg(tmp_lock); | 17509 | defer self.register_manager.unlockReg(tmp_lock); |
| 17551 | | 17510 | |
| ... | @@ -17719,7 +17678,7 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -17719,7 +17678,7 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { |
| 17719 | const len_lock = self.register_manager.lockRegAssumeUnused(len_reg); | 17678 | const len_lock = self.register_manager.lockRegAssumeUnused(len_reg); |
| 17720 | defer self.register_manager.unlockReg(len_lock); | 17679 | defer self.register_manager.unlockReg(len_lock); |
| 17721 | | 17680 | |
| 17722 | try self.genSetReg(len_reg, Type.usize, len, .{}); | 17681 | try self.genSetReg(len_reg, .usize, len, .{}); |
| 17723 | try self.asmRegisterRegister(.{ ._, .@"test" }, len_reg, len_reg); | 17682 | try self.asmRegisterRegister(.{ ._, .@"test" }, len_reg, len_reg); |
| 17724 | | 17683 | |
| 17725 | const skip_reloc = try self.asmJccReloc(.z, undefined); | 17684 | const skip_reloc = try self.asmJccReloc(.z, undefined); |
| ... | @@ -17732,12 +17691,12 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -17732,12 +17691,12 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { |
| 17732 | self.register_manager.lockRegAssumeUnused(second_elem_ptr_reg); | 17691 | self.register_manager.lockRegAssumeUnused(second_elem_ptr_reg); |
| 17733 | defer self.register_manager.unlockReg(second_elem_ptr_lock); | 17692 | defer self.register_manager.unlockReg(second_elem_ptr_lock); |
| 17734 | | 17693 | |
| 17735 | try self.genSetReg(second_elem_ptr_reg, Type.usize, .{ .register_offset = .{ | 17694 | try self.genSetReg(second_elem_ptr_reg, .usize, .{ .register_offset = .{ |
| 17736 | .reg = try self.copyToTmpRegister(Type.usize, dst_ptr), | 17695 | .reg = try self.copyToTmpRegister(.usize, dst_ptr), |
| 17737 | .off = elem_abi_size, | 17696 | .off = elem_abi_size, |
| 17738 | } }, .{}); | 17697 | } }, .{}); |
| 17739 | | 17698 | |
| 17740 | try self.genBinOpMir(.{ ._, .sub }, Type.usize, len_mcv, .{ .immediate = 1 }); | 17699 | try self.genBinOpMir(.{ ._, .sub }, .usize, len_mcv, .{ .immediate = 1 }); |
| 17741 | try self.asmRegisterRegisterImmediate( | 17700 | try self.asmRegisterRegisterImmediate( |
| 17742 | .{ .i_, .mul }, | 17701 | .{ .i_, .mul }, |
| 17743 | len_reg, | 17702 | len_reg, |
| ... | @@ -17763,8 +17722,8 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -17763,8 +17722,8 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { |
| 17763 | self.register_manager.lockRegAssumeUnused(second_elem_ptr_reg); | 17722 | self.register_manager.lockRegAssumeUnused(second_elem_ptr_reg); |
| 17764 | defer self.register_manager.unlockReg(second_elem_ptr_lock); | 17723 | defer self.register_manager.unlockReg(second_elem_ptr_lock); |
| 17765 | | 17724 | |
| 17766 | try self.genSetReg(second_elem_ptr_reg, Type.usize, .{ .register_offset = .{ | 17725 | try self.genSetReg(second_elem_ptr_reg, .usize, .{ .register_offset = .{ |
| 17767 | .reg = try self.copyToTmpRegister(Type.usize, dst), | 17726 | .reg = try self.copyToTmpRegister(.usize, dst), |
| 17768 | .off = elem_abi_size, | 17727 | .off = elem_abi_size, |
| 17769 | } }, .{}); | 17728 | } }, .{}); |
| 17770 | | 17729 | |
| ... | @@ -17886,7 +17845,7 @@ fn airTagName(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -17886,7 +17845,7 @@ fn airTagName(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 17886 | const param_regs = abi.getCAbiIntParamRegs(resolved_cc); | 17845 | const param_regs = abi.getCAbiIntParamRegs(resolved_cc); |
| 17887 | | 17846 | |
| 17888 | const dst_mcv = try self.allocRegOrMem(inst, false); | 17847 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 17889 | try self.genSetReg(param_regs[0], Type.usize, dst_mcv.address(), .{}); | 17848 | try self.genSetReg(param_regs[0], .usize, dst_mcv.address(), .{}); |
| 17890 | | 17849 | |
| 17891 | const operand = try self.resolveInst(un_op); | 17850 | const operand = try self.resolveInst(un_op); |
| 17892 | try self.genSetReg(param_regs[1], enum_ty, operand, .{}); | 17851 | try self.genSetReg(param_regs[1], enum_ty, operand, .{}); |
| ... | @@ -18415,7 +18374,7 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -18415,7 +18374,7 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 18415 | mask_alias, | 18374 | mask_alias, |
| 18416 | if (pred_mcv.isBase()) try pred_mcv.mem(self, .{ .size = .byte }) else .{ | 18375 | if (pred_mcv.isBase()) try pred_mcv.mem(self, .{ .size = .byte }) else .{ |
| 18417 | .base = .{ .reg = (try self.copyToTmpRegister( | 18376 | .base = .{ .reg = (try self.copyToTmpRegister( |
| 18418 | Type.usize, | 18377 | .usize, |
| 18419 | pred_mcv.address(), | 18378 | pred_mcv.address(), |
| 18420 | )).to64() }, | 18379 | )).to64() }, |
| 18421 | .mod = .{ .rm = .{ .size = .byte } }, | 18380 | .mod = .{ .rm = .{ .size = .byte } }, |
| ... | @@ -18478,7 +18437,7 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -18478,7 +18437,7 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 18478 | .storage = .{ .elems = mask_elems[0..vec_len] }, | 18437 | .storage = .{ .elems = mask_elems[0..vec_len] }, |
| 18479 | } }))); | 18438 | } }))); |
| 18480 | const mask_mem: Memory = .{ | 18439 | const mask_mem: Memory = .{ |
| 18481 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, mask_mcv.address()) }, | 18440 | .base = .{ .reg = try self.copyToTmpRegister(.usize, mask_mcv.address()) }, |
| 18482 | .mod = .{ .rm = .{ .size = self.memSize(ty) } }, | 18441 | .mod = .{ .rm = .{ .size = self.memSize(ty) } }, |
| 18483 | }; | 18442 | }; |
| 18484 | if (has_avx) try self.asmRegisterRegisterMemory( | 18443 | if (has_avx) try self.asmRegisterRegisterMemory( |
| ... | @@ -18503,7 +18462,7 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -18503,7 +18462,7 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 18503 | .storage = .{ .elems = mask_elems[0..vec_len] }, | 18462 | .storage = .{ .elems = mask_elems[0..vec_len] }, |
| 18504 | } }))); | 18463 | } }))); |
| 18505 | const mask_mem: Memory = .{ | 18464 | const mask_mem: Memory = .{ |
| 18506 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, mask_mcv.address()) }, | 18465 | .base = .{ .reg = try self.copyToTmpRegister(.usize, mask_mcv.address()) }, |
| 18507 | .mod = .{ .rm = .{ .size = self.memSize(ty) } }, | 18466 | .mod = .{ .rm = .{ .size = self.memSize(ty) } }, |
| 18508 | }; | 18467 | }; |
| 18509 | if (has_avx) { | 18468 | if (has_avx) { |
| ... | @@ -19380,7 +19339,7 @@ fn airShuffle(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -19380,7 +19339,7 @@ fn airShuffle(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 19380 | .storage = .{ .elems = lhs_mask_elems[0..max_abi_size] }, | 19339 | .storage = .{ .elems = lhs_mask_elems[0..max_abi_size] }, |
| 19381 | } }))); | 19340 | } }))); |
| 19382 | const lhs_mask_mem: Memory = .{ | 19341 | const lhs_mask_mem: Memory = .{ |
| 19383 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, lhs_mask_mcv.address()) }, | 19342 | .base = .{ .reg = try self.copyToTmpRegister(.usize, lhs_mask_mcv.address()) }, |
| 19384 | .mod = .{ .rm = .{ .size = .fromSize(@max(max_abi_size, 16)) } }, | 19343 | .mod = .{ .rm = .{ .size = .fromSize(@max(max_abi_size, 16)) } }, |
| 19385 | }; | 19344 | }; |
| 19386 | if (has_avx) try self.asmRegisterRegisterMemory( | 19345 | if (has_avx) try self.asmRegisterRegisterMemory( |
| ... | @@ -19414,7 +19373,7 @@ fn airShuffle(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -19414,7 +19373,7 @@ fn airShuffle(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 19414 | .storage = .{ .elems = rhs_mask_elems[0..max_abi_size] }, | 19373 | .storage = .{ .elems = rhs_mask_elems[0..max_abi_size] }, |
| 19415 | } }))); | 19374 | } }))); |
| 19416 | const rhs_mask_mem: Memory = .{ | 19375 | const rhs_mask_mem: Memory = .{ |
| 19417 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, rhs_mask_mcv.address()) }, | 19376 | .base = .{ .reg = try self.copyToTmpRegister(.usize, rhs_mask_mcv.address()) }, |
| 19418 | .mod = .{ .rm = .{ .size = .fromSize(@max(max_abi_size, 16)) } }, | 19377 | .mod = .{ .rm = .{ .size = .fromSize(@max(max_abi_size, 16)) } }, |
| 19419 | }; | 19378 | }; |
| 19420 | if (has_avx) try self.asmRegisterRegisterMemory( | 19379 | if (has_avx) try self.asmRegisterRegisterMemory( |
| ... | @@ -19634,7 +19593,7 @@ fn airAggregateInit(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -19634,7 +19593,7 @@ fn airAggregateInit(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 19634 | .{ ._l, .sh }, | 19593 | .{ ._l, .sh }, |
| 19635 | elem_ty, | 19594 | elem_ty, |
| 19636 | .{ .register = temp_alias }, | 19595 | .{ .register = temp_alias }, |
| 19637 | Type.u8, | 19596 | .u8, |
| 19638 | .{ .immediate = elem_bit_off }, | 19597 | .{ .immediate = elem_bit_off }, |
| 19639 | ); | 19598 | ); |
| 19640 | try self.genBinOpMir( | 19599 | try self.genBinOpMir( |
| ... | @@ -19657,7 +19616,7 @@ fn airAggregateInit(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -19657,7 +19616,7 @@ fn airAggregateInit(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 19657 | .{ ._r, .sh }, | 19616 | .{ ._r, .sh }, |
| 19658 | elem_ty, | 19617 | elem_ty, |
| 19659 | .{ .register = temp_reg }, | 19618 | .{ .register = temp_reg }, |
| 19660 | Type.u8, | 19619 | .u8, |
| 19661 | .{ .immediate = elem_abi_bits - elem_bit_off }, | 19620 | .{ .immediate = elem_abi_bits - elem_bit_off }, |
| 19662 | ); | 19621 | ); |
| 19663 | try self.genBinOpMir( | 19622 | try self.genBinOpMir( |
| ... | @@ -19984,7 +19943,7 @@ fn airVaStart(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -19984,7 +19943,7 @@ fn airVaStart(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 19984 | const pt = self.pt; | 19943 | const pt = self.pt; |
| 19985 | const zcu = pt.zcu; | 19944 | const zcu = pt.zcu; |
| 19986 | const va_list_ty = self.air.instructions.items(.data)[@intFromEnum(inst)].ty; | 19945 | const va_list_ty = self.air.instructions.items(.data)[@intFromEnum(inst)].ty; |
| 19987 | const ptr_anyopaque_ty = try pt.singleMutPtrType(Type.anyopaque); | 19946 | const ptr_anyopaque_ty = try pt.singleMutPtrType(.anyopaque); |
| 19988 | | 19947 | |
| 19989 | const result: MCValue = switch (abi.resolveCallingConvention( | 19948 | const result: MCValue = switch (abi.resolveCallingConvention( |
| 19990 | self.fn_type.fnCallingConvention(zcu), | 19949 | self.fn_type.fnCallingConvention(zcu), |
| ... | @@ -19998,7 +19957,7 @@ fn airVaStart(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -19998,7 +19957,7 @@ fn airVaStart(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 19998 | try self.genSetMem( | 19957 | try self.genSetMem( |
| 19999 | .{ .frame = dst_fi }, | 19958 | .{ .frame = dst_fi }, |
| 20000 | field_off, | 19959 | field_off, |
| 20001 | Type.c_uint, | 19960 | .c_uint, |
| 20002 | .{ .immediate = info.gp_count * 8 }, | 19961 | .{ .immediate = info.gp_count * 8 }, |
| 20003 | .{}, | 19962 | .{}, |
| 20004 | ); | 19963 | ); |
| ... | @@ -20007,7 +19966,7 @@ fn airVaStart(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -20007,7 +19966,7 @@ fn airVaStart(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 20007 | try self.genSetMem( | 19966 | try self.genSetMem( |
| 20008 | .{ .frame = dst_fi }, | 19967 | .{ .frame = dst_fi }, |
| 20009 | field_off, | 19968 | field_off, |
| 20010 | Type.c_uint, | 19969 | .c_uint, |
| 20011 | .{ .immediate = abi.SysV.c_abi_int_param_regs.len * 8 + info.fp_count * 16 }, | 19970 | .{ .immediate = abi.SysV.c_abi_int_param_regs.len * 8 + info.fp_count * 16 }, |
| 20012 | .{}, | 19971 | .{}, |
| 20013 | ); | 19972 | ); |
| ... | @@ -20044,7 +20003,7 @@ fn airVaArg(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -20044,7 +20003,7 @@ fn airVaArg(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 20044 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 20003 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 20045 | const ty = self.typeOfIndex(inst); | 20004 | const ty = self.typeOfIndex(inst); |
| 20046 | const promote_ty = self.promoteVarArg(ty); | 20005 | const promote_ty = self.promoteVarArg(ty); |
| 20047 | const ptr_anyopaque_ty = try pt.singleMutPtrType(Type.anyopaque); | 20006 | const ptr_anyopaque_ty = try pt.singleMutPtrType(.anyopaque); |
| 20048 | const unused = self.liveness.isUnused(inst); | 20007 | const unused = self.liveness.isUnused(inst); |
| 20049 | | 20008 | |
| 20050 | const result: MCValue = switch (abi.resolveCallingConvention( | 20009 | const result: MCValue = switch (abi.resolveCallingConvention( |
| ... | @@ -20083,7 +20042,7 @@ fn airVaArg(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -20083,7 +20042,7 @@ fn airVaArg(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 20083 | .integer => { | 20042 | .integer => { |
| 20084 | assert(classes.len == 1); | 20043 | assert(classes.len == 1); |
| 20085 | | 20044 | |
| 20086 | try self.genSetReg(offset_reg, Type.c_uint, gp_offset, .{}); | 20045 | try self.genSetReg(offset_reg, .c_uint, gp_offset, .{}); |
| 20087 | try self.asmRegisterImmediate(.{ ._, .cmp }, offset_reg, .u( | 20046 | try self.asmRegisterImmediate(.{ ._, .cmp }, offset_reg, .u( |
| 20088 | abi.SysV.c_abi_int_param_regs.len * 8, | 20047 | abi.SysV.c_abi_int_param_regs.len * 8, |
| 20089 | )); | 20048 | )); |
| ... | @@ -20104,7 +20063,7 @@ fn airVaArg(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -20104,7 +20063,7 @@ fn airVaArg(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 20104 | .disp = 8, | 20063 | .disp = 8, |
| 20105 | } }, | 20064 | } }, |
| 20106 | }); | 20065 | }); |
| 20107 | try self.genCopy(Type.c_uint, gp_offset, .{ .register = offset_reg }, .{}); | 20066 | try self.genCopy(.c_uint, gp_offset, .{ .register = offset_reg }, .{}); |
| 20108 | const done_reloc = try self.asmJmpReloc(undefined); | 20067 | const done_reloc = try self.asmJmpReloc(undefined); |
| 20109 | | 20068 | |
| 20110 | self.performReloc(mem_reloc); | 20069 | self.performReloc(mem_reloc); |
| ... | @@ -20131,7 +20090,7 @@ fn airVaArg(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -20131,7 +20090,7 @@ fn airVaArg(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 20131 | .sse => { | 20090 | .sse => { |
| 20132 | assert(classes.len == 1); | 20091 | assert(classes.len == 1); |
| 20133 | | 20092 | |
| 20134 | try self.genSetReg(offset_reg, Type.c_uint, fp_offset, .{}); | 20093 | try self.genSetReg(offset_reg, .c_uint, fp_offset, .{}); |
| 20135 | try self.asmRegisterImmediate(.{ ._, .cmp }, offset_reg, .u( | 20094 | try self.asmRegisterImmediate(.{ ._, .cmp }, offset_reg, .u( |
| 20136 | abi.SysV.c_abi_int_param_regs.len * 8 + abi.SysV.c_abi_sse_param_regs.len * 16, | 20095 | abi.SysV.c_abi_int_param_regs.len * 8 + abi.SysV.c_abi_sse_param_regs.len * 16, |
| 20137 | )); | 20096 | )); |
| ... | @@ -20152,7 +20111,7 @@ fn airVaArg(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -20152,7 +20111,7 @@ fn airVaArg(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 20152 | .disp = 16, | 20111 | .disp = 16, |
| 20153 | } }, | 20112 | } }, |
| 20154 | }); | 20113 | }); |
| 20155 | try self.genCopy(Type.c_uint, fp_offset, .{ .register = offset_reg }, .{}); | 20114 | try self.genCopy(.c_uint, fp_offset, .{ .register = offset_reg }, .{}); |
| 20156 | const done_reloc = try self.asmJmpReloc(undefined); | 20115 | const done_reloc = try self.asmJmpReloc(undefined); |
| 20157 | | 20116 | |
| 20158 | self.performReloc(mem_reloc); | 20117 | self.performReloc(mem_reloc); |
| ... | @@ -20277,7 +20236,7 @@ fn resolveInst(self: *CodeGen, ref: Air.Inst.Ref) InnerError!MCValue { | ... | @@ -20277,7 +20236,7 @@ fn resolveInst(self: *CodeGen, ref: Air.Inst.Ref) InnerError!MCValue { |
| 20277 | try self.genSetMem( | 20236 | try self.genSetMem( |
| 20278 | .{ .frame = frame_index }, | 20237 | .{ .frame = frame_index }, |
| 20279 | 0, | 20238 | 0, |
| 20280 | Type.usize, | 20239 | .usize, |
| 20281 | .{ .lea_symbol = .{ .sym_index = tlv_sym } }, | 20240 | .{ .lea_symbol = .{ .sym_index = tlv_sym } }, |
| 20282 | .{}, | 20241 | .{}, |
| 20283 | ); | 20242 | ); |
| ... | @@ -20318,7 +20277,7 @@ fn limitImmediateType(self: *CodeGen, operand: Air.Inst.Ref, comptime T: type) ! | ... | @@ -20318,7 +20277,7 @@ fn limitImmediateType(self: *CodeGen, operand: Air.Inst.Ref, comptime T: type) ! |
| 20318 | // This immediate is unsigned. | 20277 | // This immediate is unsigned. |
| 20319 | const U = std.meta.Int(.unsigned, ti.bits - @intFromBool(ti.signedness == .signed)); | 20278 | const U = std.meta.Int(.unsigned, ti.bits - @intFromBool(ti.signedness == .signed)); |
| 20320 | if (imm >= std.math.maxInt(U)) { | 20279 | if (imm >= std.math.maxInt(U)) { |
| 20321 | return MCValue{ .register = try self.copyToTmpRegister(Type.usize, mcv) }; | 20280 | return MCValue{ .register = try self.copyToTmpRegister(.usize, mcv) }; |
| 20322 | } | 20281 | } |
| 20323 | }, | 20282 | }, |
| 20324 | else => {}, | 20283 | else => {}, |
| ... | @@ -20764,7 +20723,7 @@ fn splitType(self: *CodeGen, comptime parts_len: usize, ty: Type) ![parts_len]Ty | ... | @@ -20764,7 +20723,7 @@ fn splitType(self: *CodeGen, comptime parts_len: usize, ty: Type) ![parts_len]Ty |
| 20764 | if (classes.len == parts_len) for (&parts, classes, 0..) |*part, class, part_i| { | 20723 | if (classes.len == parts_len) for (&parts, classes, 0..) |*part, class, part_i| { |
| 20765 | part.* = switch (class) { | 20724 | part.* = switch (class) { |
| 20766 | .integer => if (part_i < parts_len - 1) | 20725 | .integer => if (part_i < parts_len - 1) |
| 20767 | Type.u64 | 20726 | .u64 |
| 20768 | else part: { | 20727 | else part: { |
| 20769 | const elem_size = ty.abiAlignment(zcu).minStrict(.@"8").toByteUnits().?; | 20728 | const elem_size = ty.abiAlignment(zcu).minStrict(.@"8").toByteUnits().?; |
| 20770 | const elem_ty = try pt.intType(.unsigned, @intCast(elem_size * 8)); | 20729 | const elem_ty = try pt.intType(.unsigned, @intCast(elem_size * 8)); |
| ... | @@ -20773,9 +20732,9 @@ fn splitType(self: *CodeGen, comptime parts_len: usize, ty: Type) ![parts_len]Ty | ... | @@ -20773,9 +20732,9 @@ fn splitType(self: *CodeGen, comptime parts_len: usize, ty: Type) ![parts_len]Ty |
| 20773 | else => |array_len| try pt.arrayType(.{ .len = array_len, .child = elem_ty.toIntern() }), | 20732 | else => |array_len| try pt.arrayType(.{ .len = array_len, .child = elem_ty.toIntern() }), |
| 20774 | }; | 20733 | }; |
| 20775 | }, | 20734 | }, |
| 20776 | .float => Type.f32, | 20735 | .float => .f32, |
| 20777 | .float_combine => try pt.arrayType(.{ .len = 2, .child = .f32_type }), | 20736 | .float_combine => try pt.arrayType(.{ .len = 2, .child = .f32_type }), |
| 20778 | .sse => Type.f64, | 20737 | .sse => .f64, |
| 20779 | else => break, | 20738 | else => break, |
| 20780 | }; | 20739 | }; |
| 20781 | } else { | 20740 | } else { |
| ... | @@ -20791,7 +20750,7 @@ fn splitType(self: *CodeGen, comptime parts_len: usize, ty: Type) ![parts_len]Ty | ... | @@ -20791,7 +20750,7 @@ fn splitType(self: *CodeGen, comptime parts_len: usize, ty: Type) ![parts_len]Ty |
| 20791 | fn truncateRegister(self: *CodeGen, ty: Type, reg: Register) !void { | 20750 | fn truncateRegister(self: *CodeGen, ty: Type, reg: Register) !void { |
| 20792 | const pt = self.pt; | 20751 | const pt = self.pt; |
| 20793 | const zcu = pt.zcu; | 20752 | const zcu = pt.zcu; |
| 20794 | const int_info = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else std.builtin.Type.Int{ | 20753 | const int_info: InternPool.Key.IntType = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else .{ |
| 20795 | .signedness = .unsigned, | 20754 | .signedness = .unsigned, |
| 20796 | .bits = @intCast(ty.bitSize(zcu)), | 20755 | .bits = @intCast(ty.bitSize(zcu)), |
| 20797 | }; | 20756 | }; |
| ... | @@ -20799,38 +20758,16 @@ fn truncateRegister(self: *CodeGen, ty: Type, reg: Register) !void { | ... | @@ -20799,38 +20758,16 @@ fn truncateRegister(self: *CodeGen, ty: Type, reg: Register) !void { |
| 20799 | try self.spillEflagsIfOccupied(); | 20758 | try self.spillEflagsIfOccupied(); |
| 20800 | switch (int_info.signedness) { | 20759 | switch (int_info.signedness) { |
| 20801 | .signed => { | 20760 | .signed => { |
| 20802 | try self.genShiftBinOpMir( | 20761 | try self.genShiftBinOpMir(.{ ._l, .sa }, .isize, .{ .register = reg }, .u8, .{ .immediate = shift }); |
| 20803 | .{ ._l, .sa }, | 20762 | try self.genShiftBinOpMir(.{ ._r, .sa }, .isize, .{ .register = reg }, .u8, .{ .immediate = shift }); |
| 20804 | Type.isize, | | |
| 20805 | .{ .register = reg }, | | |
| 20806 | Type.u8, | | |
| 20807 | .{ .immediate = shift }, | | |
| 20808 | ); | | |
| 20809 | try self.genShiftBinOpMir( | | |
| 20810 | .{ ._r, .sa }, | | |
| 20811 | Type.isize, | | |
| 20812 | .{ .register = reg }, | | |
| 20813 | Type.u8, | | |
| 20814 | .{ .immediate = shift }, | | |
| 20815 | ); | | |
| 20816 | }, | 20763 | }, |
| 20817 | .unsigned => { | 20764 | .unsigned => { |
| 20818 | const mask = ~@as(u64, 0) >> shift; | 20765 | const mask = ~@as(u64, 0) >> shift; |
| 20819 | if (int_info.bits <= 32) { | 20766 | if (int_info.bits <= 32) { |
| 20820 | try self.genBinOpMir( | 20767 | try self.genBinOpMir(.{ ._, .@"and" }, .u32, .{ .register = reg }, .{ .immediate = mask }); |
| 20821 | .{ ._, .@"and" }, | | |
| 20822 | Type.u32, | | |
| 20823 | .{ .register = reg }, | | |
| 20824 | .{ .immediate = mask }, | | |
| 20825 | ); | | |
| 20826 | } else { | 20768 | } else { |
| 20827 | const tmp_reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = mask }); | 20769 | const tmp_reg = try self.copyToTmpRegister(.usize, .{ .immediate = mask }); |
| 20828 | try self.genBinOpMir( | 20770 | try self.genBinOpMir(.{ ._, .@"and" }, .usize, .{ .register = reg }, .{ .register = tmp_reg }); |
| 20829 | .{ ._, .@"and" }, | | |
| 20830 | Type.usize, | | |
| 20831 | .{ .register = reg }, | | |
| 20832 | .{ .register = tmp_reg }, | | |
| 20833 | ); | | |
| 20834 | } | 20771 | } |
| 20835 | }, | 20772 | }, |
| 20836 | } | 20773 | } |
| ... | @@ -20911,7 +20848,7 @@ fn floatCompilerRtAbiName(float_bits: u32) u8 { | ... | @@ -20911,7 +20848,7 @@ fn floatCompilerRtAbiName(float_bits: u32) u8 { |
| 20911 | fn floatCompilerRtAbiType(self: *CodeGen, ty: Type, other_ty: Type) Type { | 20848 | fn floatCompilerRtAbiType(self: *CodeGen, ty: Type, other_ty: Type) Type { |
| 20912 | if (ty.toIntern() == .f16_type and | 20849 | if (ty.toIntern() == .f16_type and |
| 20913 | (other_ty.toIntern() == .f32_type or other_ty.toIntern() == .f64_type) and | 20850 | (other_ty.toIntern() == .f32_type or other_ty.toIntern() == .f64_type) and |
| 20914 | self.target.isDarwin()) return Type.u16; | 20851 | self.target.isDarwin()) return .u16; |
| 20915 | return ty; | 20852 | return ty; |
| 20916 | } | 20853 | } |
| 20917 | | 20854 | |
| ... | @@ -20943,9 +20880,9 @@ fn promoteInt(self: *CodeGen, ty: Type) Type { | ... | @@ -20943,9 +20880,9 @@ fn promoteInt(self: *CodeGen, ty: Type) Type { |
| 20943 | else => if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else return ty, | 20880 | else => if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else return ty, |
| 20944 | }; | 20881 | }; |
| 20945 | for ([_]Type{ | 20882 | for ([_]Type{ |
| 20946 | Type.c_int, Type.c_uint, | 20883 | .c_int, .c_uint, |
| 20947 | Type.c_long, Type.c_ulong, | 20884 | .c_long, .c_ulong, |
| 20948 | Type.c_longlong, Type.c_ulonglong, | 20885 | .c_longlong, .c_ulonglong, |
| 20949 | }) |promote_ty| { | 20886 | }) |promote_ty| { |
| 20950 | const promote_info = promote_ty.intInfo(zcu); | 20887 | const promote_info = promote_ty.intInfo(zcu); |
| 20951 | if (int_info.signedness == .signed and promote_info.signedness == .unsigned) continue; | 20888 | if (int_info.signedness == .signed and promote_info.signedness == .unsigned) continue; |
| ... | @@ -20958,10 +20895,10 @@ fn promoteInt(self: *CodeGen, ty: Type) Type { | ... | @@ -20958,10 +20895,10 @@ fn promoteInt(self: *CodeGen, ty: Type) Type { |
| 20958 | fn promoteVarArg(self: *CodeGen, ty: Type) Type { | 20895 | fn promoteVarArg(self: *CodeGen, ty: Type) Type { |
| 20959 | if (!ty.isRuntimeFloat()) return self.promoteInt(ty); | 20896 | if (!ty.isRuntimeFloat()) return self.promoteInt(ty); |
| 20960 | switch (ty.floatBits(self.target.*)) { | 20897 | switch (ty.floatBits(self.target.*)) { |
| 20961 | 32, 64 => return Type.f64, | 20898 | 32, 64 => return .f64, |
| 20962 | else => |float_bits| { | 20899 | else => |float_bits| { |
| 20963 | assert(float_bits == self.target.cTypeBitSize(.longdouble)); | 20900 | assert(float_bits == self.target.cTypeBitSize(.longdouble)); |
| 20964 | return Type.c_longdouble; | 20901 | return .c_longdouble; |
| 20965 | }, | 20902 | }, |
| 20966 | } | 20903 | } |
| 20967 | } | 20904 | } |
| ... | @@ -21036,7 +20973,7 @@ const Temp = struct { | ... | @@ -21036,7 +20973,7 @@ const Temp = struct { |
| 21036 | | 20973 | |
| 21037 | fn getOffset(temp: Temp, off: i32, cg: *CodeGen) !Temp { | 20974 | fn getOffset(temp: Temp, off: i32, cg: *CodeGen) !Temp { |
| 21038 | const new_temp_index = cg.next_temp_index; | 20975 | const new_temp_index = cg.next_temp_index; |
| 21039 | cg.temp_type[@intFromEnum(new_temp_index)] = Type.usize; | 20976 | cg.temp_type[@intFromEnum(new_temp_index)] = .usize; |
| 21040 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); | 20977 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); |
| 21041 | switch (temp.tracking(cg).short) { | 20978 | switch (temp.tracking(cg).short) { |
| 21042 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), | 20979 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), |
| ... | @@ -21141,7 +21078,7 @@ const Temp = struct { | ... | @@ -21141,7 +21078,7 @@ const Temp = struct { |
| 21141 | | 21078 | |
| 21142 | fn getLimb(temp: Temp, limb_index: u28, cg: *CodeGen) !Temp { | 21079 | fn getLimb(temp: Temp, limb_index: u28, cg: *CodeGen) !Temp { |
| 21143 | const new_temp_index = cg.next_temp_index; | 21080 | const new_temp_index = cg.next_temp_index; |
| 21144 | cg.temp_type[@intFromEnum(new_temp_index)] = Type.usize; | 21081 | cg.temp_type[@intFromEnum(new_temp_index)] = .usize; |
| 21145 | switch (temp.tracking(cg).short) { | 21082 | switch (temp.tracking(cg).short) { |
| 21146 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), | 21083 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), |
| 21147 | .immediate => |imm| { | 21084 | .immediate => |imm| { |
| ... | @@ -21220,7 +21157,7 @@ const Temp = struct { | ... | @@ -21220,7 +21157,7 @@ const Temp = struct { |
| 21220 | else => {}, | 21157 | else => {}, |
| 21221 | .register, .lea_symbol, .lea_frame => { | 21158 | .register, .lea_symbol, .lea_frame => { |
| 21222 | assert(limb_index == 0); | 21159 | assert(limb_index == 0); |
| 21223 | cg.temp_type[@intFromEnum(temp_index)] = Type.usize; | 21160 | cg.temp_type[@intFromEnum(temp_index)] = .usize; |
| 21224 | return; | 21161 | return; |
| 21225 | }, | 21162 | }, |
| 21226 | .register_pair => |regs| { | 21163 | .register_pair => |regs| { |
| ... | @@ -21232,7 +21169,7 @@ const Temp = struct { | ... | @@ -21232,7 +21169,7 @@ const Temp = struct { |
| 21232 | for (regs, 0..) |reg, reg_index| if (reg_index != limb_index) | 21169 | for (regs, 0..) |reg, reg_index| if (reg_index != limb_index) |
| 21233 | cg.register_manager.freeReg(reg); | 21170 | cg.register_manager.freeReg(reg); |
| 21234 | temp_tracking.* = .init(.{ .register = regs[limb_index] }); | 21171 | temp_tracking.* = .init(.{ .register = regs[limb_index] }); |
| 21235 | cg.temp_type[@intFromEnum(temp_index)] = Type.usize; | 21172 | cg.temp_type[@intFromEnum(temp_index)] = .usize; |
| 21236 | return; | 21173 | return; |
| 21237 | }, | 21174 | }, |
| 21238 | .load_symbol => |sym_off| { | 21175 | .load_symbol => |sym_off| { |
| ... | @@ -21241,7 +21178,7 @@ const Temp = struct { | ... | @@ -21241,7 +21178,7 @@ const Temp = struct { |
| 21241 | .sym_index = sym_off.sym_index, | 21178 | .sym_index = sym_off.sym_index, |
| 21242 | .off = sym_off.off + @as(u31, limb_index) * 8, | 21179 | .off = sym_off.off + @as(u31, limb_index) * 8, |
| 21243 | } }); | 21180 | } }); |
| 21244 | cg.temp_type[@intFromEnum(temp_index)] = Type.usize; | 21181 | cg.temp_type[@intFromEnum(temp_index)] = .usize; |
| 21245 | return; | 21182 | return; |
| 21246 | }, | 21183 | }, |
| 21247 | .load_frame => |frame_addr| if (!frame_addr.index.isNamed()) { | 21184 | .load_frame => |frame_addr| if (!frame_addr.index.isNamed()) { |
| ... | @@ -21250,7 +21187,7 @@ const Temp = struct { | ... | @@ -21250,7 +21187,7 @@ const Temp = struct { |
| 21250 | .index = frame_addr.index, | 21187 | .index = frame_addr.index, |
| 21251 | .off = frame_addr.off + @as(u31, limb_index) * 8, | 21188 | .off = frame_addr.off + @as(u31, limb_index) * 8, |
| 21252 | } }); | 21189 | } }); |
| 21253 | cg.temp_type[@intFromEnum(temp_index)] = Type.usize; | 21190 | cg.temp_type[@intFromEnum(temp_index)] = .usize; |
| 21254 | return; | 21191 | return; |
| 21255 | }, | 21192 | }, |
| 21256 | } | 21193 | } |
| ... | @@ -21339,7 +21276,7 @@ const Temp = struct { | ... | @@ -21339,7 +21276,7 @@ const Temp = struct { |
| 21339 | const result_temp: Temp = .{ .index = result_temp_index.toIndex() }; | 21276 | const result_temp: Temp = .{ .index = result_temp_index.toIndex() }; |
| 21340 | assert(cg.reuseTemp(result_temp.index, first_temp.index, first_temp_tracking)); | 21277 | assert(cg.reuseTemp(result_temp.index, first_temp.index, first_temp_tracking)); |
| 21341 | assert(cg.reuseTemp(result_temp.index, second_temp.index, second_temp_tracking)); | 21278 | assert(cg.reuseTemp(result_temp.index, second_temp.index, second_temp_tracking)); |
| 21342 | cg.temp_type[@intFromEnum(result_temp_index)] = Type.slice_const_u8; | 21279 | cg.temp_type[@intFromEnum(result_temp_index)] = .slice_const_u8; |
| 21343 | result_temp_index.tracking(cg).* = .init(result); | 21280 | result_temp_index.tracking(cg).* = .init(result); |
| 21344 | first_temp.* = result_temp; | 21281 | first_temp.* = result_temp; |
| 21345 | } | 21282 | } |
| ... | @@ -21405,7 +21342,7 @@ const Temp = struct { | ... | @@ -21405,7 +21342,7 @@ const Temp = struct { |
| 21405 | cg.temp_type[@intFromEnum(new_temp_index)] = temp.typeOf(cg); | 21342 | cg.temp_type[@intFromEnum(new_temp_index)] = temp.typeOf(cg); |
| 21406 | const new_reg = | 21343 | const new_reg = |
| 21407 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | 21344 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| 21408 | try cg.genSetReg(new_reg, Type.usize, temp_tracking.short.address(), .{}); | 21345 | try cg.genSetReg(new_reg, .usize, temp_tracking.short.address(), .{}); |
| 21409 | new_temp_index.tracking(cg).* = .init(.{ .indirect = .{ .reg = new_reg } }); | 21346 | new_temp_index.tracking(cg).* = .init(.{ .indirect = .{ .reg = new_reg } }); |
| 21410 | try temp.die(cg); | 21347 | try temp.die(cg); |
| 21411 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); | 21348 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); |
| ... | @@ -21430,8 +21367,8 @@ const Temp = struct { | ... | @@ -21430,8 +21367,8 @@ const Temp = struct { |
| 21430 | } | 21367 | } |
| 21431 | }, | 21368 | }, |
| 21432 | .load_frame => |val_frame_addr| { | 21369 | .load_frame => |val_frame_addr| { |
| 21433 | var val_ptr = try cg.tempFromValue(Type.usize, .{ .lea_frame = val_frame_addr }); | 21370 | var val_ptr = try cg.tempFromValue(.usize, .{ .lea_frame = val_frame_addr }); |
| 21434 | var len = try cg.tempFromValue(Type.usize, .{ .immediate = val_abi_size }); | 21371 | var len = try cg.tempFromValue(.usize, .{ .immediate = val_abi_size }); |
| 21435 | try val_ptr.memcpy(ptr, &len, cg); | 21372 | try val_ptr.memcpy(ptr, &len, cg); |
| 21436 | try val_ptr.die(cg); | 21373 | try val_ptr.die(cg); |
| 21437 | try len.die(cg); | 21374 | try len.die(cg); |
| ... | @@ -21668,11 +21605,12 @@ fn tempFromOperand( | ... | @@ -21668,11 +21605,12 @@ fn tempFromOperand( |
| 21668 | inst: Air.Inst.Index, | 21605 | inst: Air.Inst.Index, |
| 21669 | op_index: Liveness.OperandInt, | 21606 | op_index: Liveness.OperandInt, |
| 21670 | op_ref: Air.Inst.Ref, | 21607 | op_ref: Air.Inst.Ref, |
| | 21608 | ignore_death: bool, |
| 21671 | ) !Temp { | 21609 | ) !Temp { |
| 21672 | const zcu = cg.pt.zcu; | 21610 | const zcu = cg.pt.zcu; |
| 21673 | const ip = &zcu.intern_pool; | 21611 | const ip = &zcu.intern_pool; |
| 21674 | | 21612 | |
| 21675 | if (!cg.liveness.operandDies(inst, op_index)) { | 21613 | if (ignore_death or !cg.liveness.operandDies(inst, op_index)) { |
| 21676 | if (op_ref.toIndex()) |op_inst| return .{ .index = op_inst }; | 21614 | if (op_ref.toIndex()) |op_inst| return .{ .index = op_inst }; |
| 21677 | const val = op_ref.toInterned().?; | 21615 | const val = op_ref.toInterned().?; |
| 21678 | const gop = try cg.const_tracking.getOrPut(cg.gpa, val); | 21616 | const gop = try cg.const_tracking.getOrPut(cg.gpa, val); |
| ... | @@ -21693,7 +21631,7 @@ fn tempFromOperand( | ... | @@ -21693,7 +21631,7 @@ fn tempFromOperand( |
| 21693 | try cg.genSetMem( | 21631 | try cg.genSetMem( |
| 21694 | .{ .frame = frame_index }, | 21632 | .{ .frame = frame_index }, |
| 21695 | 0, | 21633 | 0, |
| 21696 | Type.usize, | 21634 | .usize, |
| 21697 | .{ .lea_symbol = .{ .sym_index = tlv_sym } }, | 21635 | .{ .lea_symbol = .{ .sym_index = tlv_sym } }, |
| 21698 | .{}, | 21636 | .{}, |
| 21699 | ); | 21637 | ); |
| ... | @@ -21721,7 +21659,9 @@ fn tempFromOperand( | ... | @@ -21721,7 +21659,9 @@ fn tempFromOperand( |
| 21721 | inline fn tempsFromOperands(cg: *CodeGen, inst: Air.Inst.Index, op_refs: anytype) ![op_refs.len]Temp { | 21659 | inline fn tempsFromOperands(cg: *CodeGen, inst: Air.Inst.Index, op_refs: anytype) ![op_refs.len]Temp { |
| 21722 | var temps: [op_refs.len]Temp = undefined; | 21660 | var temps: [op_refs.len]Temp = undefined; |
| 21723 | inline for (&temps, 0.., op_refs) |*temp, op_index, op_ref| { | 21661 | inline for (&temps, 0.., op_refs) |*temp, op_index, op_ref| { |
| 21724 | temp.* = try cg.tempFromOperand(inst, op_index, op_ref); | 21662 | temp.* = try cg.tempFromOperand(inst, op_index, op_ref, inline for (0..op_index) |prev_op_index| { |
| | 21663 | if (op_ref == op_refs[prev_op_index]) break true; |
| | 21664 | } else false); |
| 21725 | } | 21665 | } |
| 21726 | return temps; | 21666 | return temps; |
| 21727 | } | 21667 | } |
| ... | @@ -21776,6 +21716,8 @@ const Pattern = struct { | ... | @@ -21776,6 +21716,8 @@ const Pattern = struct { |
| 21776 | implicit: u8, | 21716 | implicit: u8, |
| 21777 | /// repeat another operand | 21717 | /// repeat another operand |
| 21778 | explicit: u8, | 21718 | explicit: u8, |
| | 21719 | /// a condition code |
| | 21720 | cc, |
| 21779 | /// any general purpose register | 21721 | /// any general purpose register |
| 21780 | gpr, | 21722 | gpr, |
| 21781 | /// any 64-bit mmx register | 21723 | /// any 64-bit mmx register |
| ... | @@ -21808,6 +21750,8 @@ const Pattern = struct { | ... | @@ -21808,6 +21750,8 @@ const Pattern = struct { |
| 21808 | ymm_limb, | 21750 | ymm_limb, |
| 21809 | /// a limb stored in memory | 21751 | /// a limb stored in memory |
| 21810 | mem_limb, | 21752 | mem_limb, |
| | 21753 | /// a limb stored in a condition code |
| | 21754 | cc_mask_limb, |
| 21811 | /// a limb stored in a 64-bit mmx register mask | 21755 | /// a limb stored in a 64-bit mmx register mask |
| 21812 | mm_mask_limb, | 21756 | mm_mask_limb, |
| 21813 | /// a limb stored in a 128-bit sse register masuk | 21757 | /// a limb stored in a 128-bit sse register masuk |
| ... | @@ -21829,7 +21773,7 @@ const Pattern = struct { | ... | @@ -21829,7 +21773,7 @@ const Pattern = struct { |
| 21829 | | 21773 | |
| 21830 | fn matches(op: Op, is_mut: bool, temp: Temp, cg: *CodeGen) bool { | 21774 | fn matches(op: Op, is_mut: bool, temp: Temp, cg: *CodeGen) bool { |
| 21831 | switch (op) { | 21775 | switch (op) { |
| 21832 | .implicit, .explicit => unreachable, | 21776 | .implicit, .explicit, .cc, .cc_mask_limb => unreachable, |
| 21833 | else => {}, | 21777 | else => {}, |
| 21834 | // temp is undefined | 21778 | // temp is undefined |
| 21835 | .umax_gpr, .umax_mm, .umax_xmm, .umax_ymm => return true, | 21779 | .umax_gpr, .umax_mm, .umax_xmm, .umax_ymm => return true, |
| ... | @@ -21837,7 +21781,7 @@ const Pattern = struct { | ... | @@ -21837,7 +21781,7 @@ const Pattern = struct { |
| 21837 | const temp_ty = temp.typeOf(cg); | 21781 | const temp_ty = temp.typeOf(cg); |
| 21838 | const abi_size = temp_ty.abiSize(cg.pt.zcu); | 21782 | const abi_size = temp_ty.abiSize(cg.pt.zcu); |
| 21839 | return switch (op) { | 21783 | return switch (op) { |
| 21840 | .implicit, .explicit, .umax_gpr, .umax_mm, .umax_xmm, .umax_ymm => unreachable, | 21784 | .implicit, .explicit, .cc, .cc_mask_limb, .umax_gpr, .umax_mm, .umax_xmm, .umax_ymm => unreachable, |
| 21841 | .gpr => abi_size <= 8 and switch (temp.tracking(cg).short) { | 21785 | .gpr => abi_size <= 8 and switch (temp.tracking(cg).short) { |
| 21842 | .register => |reg| reg.class() == .general_purpose, | 21786 | .register => |reg| reg.class() == .general_purpose, |
| 21843 | .register_offset => |reg_off| reg_off.reg.class() == .general_purpose and | 21787 | .register_offset => |reg_off| reg_off.reg.class() == .general_purpose and |
| ... | @@ -21861,9 +21805,7 @@ const Pattern = struct { | ... | @@ -21861,9 +21805,7 @@ const Pattern = struct { |
| 21861 | }, | 21805 | }, |
| 21862 | .mem, .mem_limb => (!is_mut or temp.isMut(cg)) and temp.tracking(cg).short.isMemory(), | 21806 | .mem, .mem_limb => (!is_mut or temp.isMut(cg)) and temp.tracking(cg).short.isMemory(), |
| 21863 | .gpr_limb => abi_size > 8 and switch (temp.tracking(cg).short) { | 21807 | .gpr_limb => abi_size > 8 and switch (temp.tracking(cg).short) { |
| 21864 | inline .register_pair, .register_triple, .register_quadruple => |regs| for (regs) |reg| { | 21808 | .register, .register_pair, .register_triple, .register_quadruple => true, |
| 21865 | if (reg.class() != .general_purpose) break false; | | |
| 21866 | } else true, | | |
| 21867 | else => |mcv| mcv.isMemory(), | 21809 | else => |mcv| mcv.isMemory(), |
| 21868 | }, | 21810 | }, |
| 21869 | .mm_limb, .mm_mask_limb => abi_size > 8 and switch (temp.tracking(cg).short) { | 21811 | .mm_limb, .mm_mask_limb => abi_size > 8 and switch (temp.tracking(cg).short) { |
| ... | @@ -21897,6 +21839,7 @@ const Pattern = struct { | ... | @@ -21897,6 +21839,7 @@ const Pattern = struct { |
| 21897 | }; | 21839 | }; |
| 21898 | }; | 21840 | }; |
| 21899 | const SelectOptions = struct { | 21841 | const SelectOptions = struct { |
| | 21842 | cc: ?Condition = null, |
| 21900 | invert_result: bool = false, | 21843 | invert_result: bool = false, |
| 21901 | }; | 21844 | }; |
| 21902 | fn select( | 21845 | fn select( |
| ... | @@ -21914,6 +21857,7 @@ fn select( | ... | @@ -21914,6 +21857,7 @@ fn select( |
| 21914 | limb_reloc: Mir.Inst.Index, | 21857 | limb_reloc: Mir.Inst.Index, |
| 21915 | limb_offset: Offset, | 21858 | limb_offset: Offset, |
| 21916 | limb_size: ?u8, | 21859 | limb_size: ?u8, |
| | 21860 | shuffle_temp: ?Temp, |
| 21917 | mask_limb_temp: ?Temp, | 21861 | mask_limb_temp: ?Temp, |
| 21918 | mask_limb_offset: Offset, | 21862 | mask_limb_offset: Offset, |
| 21919 | mask_limb_offset_lock: ?RegisterLock, | 21863 | mask_limb_offset_lock: ?RegisterLock, |
| ... | @@ -21935,6 +21879,7 @@ fn select( | ... | @@ -21935,6 +21879,7 @@ fn select( |
| 21935 | .limb_reloc = undefined, | 21879 | .limb_reloc = undefined, |
| 21936 | .limb_offset = .unused, | 21880 | .limb_offset = .unused, |
| 21937 | .limb_size = null, | 21881 | .limb_size = null, |
| | 21882 | .shuffle_temp = null, |
| 21938 | .mask_limb_temp = null, | 21883 | .mask_limb_temp = null, |
| 21939 | .mask_limb_offset = .unused, | 21884 | .mask_limb_offset = .unused, |
| 21940 | .mask_limb_offset_lock = null, | 21885 | .mask_limb_offset_lock = null, |
| ... | @@ -21992,12 +21937,23 @@ fn select( | ... | @@ -21992,12 +21937,23 @@ fn select( |
| 21992 | if (!ref_src_op.matches(is_mut, src_temp, cg)) continue :patterns; | 21937 | if (!ref_src_op.matches(is_mut, src_temp, cg)) continue :patterns; |
| 21993 | } | 21938 | } |
| 21994 | | 21939 | |
| | 21940 | for (pattern.ops) |op| switch (op) { |
| | 21941 | else => {}, |
| | 21942 | .cc_mask_limb, |
| | 21943 | .mm_mask_limb, |
| | 21944 | .xmm_mask_limb, |
| | 21945 | .ymm_mask_limb, |
| | 21946 | => if (loop.mask_limb_offset_lock == null and !cg.hasFeature(.bmi2)) { |
| | 21947 | try cg.register_manager.getKnownReg(.rcx, null); |
| | 21948 | loop.mask_limb_offset_lock = cg.register_manager.lockKnownRegAssumeUnused(.rcx); |
| | 21949 | }, |
| | 21950 | }; |
| 21995 | while (true) for (src_temps, pattern.ops[dst_temps.len..]) |*src_temp, src_op| { | 21951 | while (true) for (src_temps, pattern.ops[dst_temps.len..]) |*src_temp, src_op| { |
| 21996 | if (changed: switch (switch (src_op) { | 21952 | if (switch (switch (src_op) { |
| 21997 | .implicit, .explicit => |linked_index| pattern.ops[linked_index], | 21953 | .implicit, .explicit => |linked_index| pattern.ops[linked_index], |
| 21998 | else => src_op, | 21954 | else => src_op, |
| 21999 | }) { | 21955 | }) { |
| 22000 | .implicit, .explicit => unreachable, | 21956 | .implicit, .explicit, .cc, .cc_mask_limb => unreachable, |
| 22001 | .gpr => try src_temp.toRegClass(.general_purpose, cg), | 21957 | .gpr => try src_temp.toRegClass(.general_purpose, cg), |
| 22002 | .mm, .mm_mask, .mm_sign_mask => try src_temp.toRegClass(.mmx, cg), | 21958 | .mm, .mm_mask, .mm_sign_mask => try src_temp.toRegClass(.mmx, cg), |
| 22003 | .xmm, | 21959 | .xmm, |
| ... | @@ -22015,23 +21971,22 @@ fn select( | ... | @@ -22015,23 +21971,22 @@ fn select( |
| 22015 | .ymm_limb, | 21971 | .ymm_limb, |
| 22016 | .mem_limb, | 21972 | .mem_limb, |
| 22017 | => switch (src_temp.tracking(cg).short) { | 21973 | => switch (src_temp.tracking(cg).short) { |
| 22018 | .register_pair, .register_triple, .register_quadruple => false, | 21974 | .register, .register_pair, .register_triple, .register_quadruple => false, |
| 22019 | else => try src_temp.toBase(cg), | 21975 | else => try src_temp.toBase(cg), |
| 22020 | }, | 21976 | }, |
| 22021 | .mm_mask_limb, | 21977 | .mm_mask_limb, .xmm_mask_limb, .ymm_mask_limb => false, |
| 22022 | .xmm_mask_limb, | | |
| 22023 | .ymm_mask_limb, | | |
| 22024 | => if (!cg.hasFeature(.bmi2) and !cg.register_manager.isKnownRegFree(.rcx)) { | | |
| 22025 | try cg.register_manager.getKnownReg(.rcx, null); | | |
| 22026 | loop.mask_limb_offset_lock = cg.register_manager.lockKnownRegAssumeUnused(.rcx); | | |
| 22027 | break :changed true; | | |
| 22028 | } else false, | | |
| 22029 | .umax_gpr, .umax_mm, .umax_xmm, .umax_ymm => false, | 21978 | .umax_gpr, .umax_mm, .umax_xmm, .umax_ymm => false, |
| 22030 | }) break; | 21979 | }) break; |
| 22031 | } else break; | 21980 | } else break; |
| 22032 | | 21981 | |
| | 21982 | const invert_result = opts.invert_result != pattern_set.invert_result; |
| 22033 | var dst_is_linked: std.StaticBitSet(4) = .initEmpty(); | 21983 | var dst_is_linked: std.StaticBitSet(4) = .initEmpty(); |
| 22034 | var mir_ops_len = dst_temps.len; | 21984 | var mir_ops_len: usize = 0; |
| | 21985 | for (pattern.ops[0..dst_temps.len]) |dst_op| switch (dst_op) { |
| | 21986 | else => mir_ops_len += 1, |
| | 21987 | .cc, .cc_mask_limb => {}, |
| | 21988 | }; |
| | 21989 | const dst_mir_ops_len = mir_ops_len; |
| 22035 | for (src_temps, pattern.ops[dst_temps.len..]) |src_temp, src_op| { | 21990 | for (src_temps, pattern.ops[dst_temps.len..]) |src_temp, src_op| { |
| 22036 | defer mir_ops_len += @intFromBool(src_op != .implicit); | 21991 | defer mir_ops_len += @intFromBool(src_op != .implicit); |
| 22037 | const linked_src_op, const extra_temp = op: switch (src_op) { | 21992 | const linked_src_op, const extra_temp = op: switch (src_op) { |
| ... | @@ -22046,13 +22001,17 @@ fn select( | ... | @@ -22046,13 +22001,17 @@ fn select( |
| 22046 | }; | 22001 | }; |
| 22047 | const limb_size: u8, const rc = switch (linked_src_op) { | 22002 | const limb_size: u8, const rc = switch (linked_src_op) { |
| 22048 | else => continue, | 22003 | else => continue, |
| 22049 | .gpr_limb => .{ 8, abi.RegisterClass.gp }, | 22004 | .gpr_limb => .{ @intCast(@divExact(@as(Memory.Size, switch (pattern_set.scalar) { |
| | 22005 | .any => .qword, |
| | 22006 | .bool => unreachable, |
| | 22007 | .float, .any_int, .signed_int, .unsigned_int, .any_float_or_int => |size| size, |
| | 22008 | }).bitSize(), 8)), abi.RegisterClass.gp }, |
| 22050 | .mm_limb, .mm_mask_limb => .{ 8, @panic("TODO") }, | 22009 | .mm_limb, .mm_mask_limb => .{ 8, @panic("TODO") }, |
| 22051 | .xmm_limb, .xmm_mask_limb => .{ 16, abi.RegisterClass.sse }, | 22010 | .xmm_limb, .xmm_mask_limb => .{ 16, abi.RegisterClass.sse }, |
| 22052 | .ymm_limb, .ymm_mask_limb => .{ 32, abi.RegisterClass.sse }, | 22011 | .ymm_limb, .ymm_mask_limb => .{ 32, abi.RegisterClass.sse }, |
| 22053 | .umax_gpr, .umax_mm, .umax_xmm, .umax_ymm => { | 22012 | .umax_gpr, .umax_mm, .umax_xmm, .umax_ymm => { |
| 22054 | assert(extra_temp.* == null); | 22013 | assert(extra_temp.* == null); |
| 22055 | extra_temp.* = try cg.tempAllocReg(Type.usize, switch (linked_src_op) { | 22014 | extra_temp.* = try cg.tempAllocReg(.noreturn, switch (linked_src_op) { |
| 22056 | else => unreachable, | 22015 | else => unreachable, |
| 22057 | .umax_gpr => abi.RegisterClass.gp, | 22016 | .umax_gpr => abi.RegisterClass.gp, |
| 22058 | .umax_mm => @panic("TODO"), | 22017 | .umax_mm => @panic("TODO"), |
| ... | @@ -22064,10 +22023,18 @@ fn select( | ... | @@ -22064,10 +22023,18 @@ fn select( |
| 22064 | assert(loop.limb_size == null or loop.limb_size == limb_size); | 22023 | assert(loop.limb_size == null or loop.limb_size == limb_size); |
| 22065 | loop.limb_size = limb_size; | 22024 | loop.limb_size = limb_size; |
| 22066 | loop.remaining_size = loop.remaining_size orelse src_temp.typeOf(cg).abiSize(cg.pt.zcu); | 22025 | loop.remaining_size = loop.remaining_size orelse src_temp.typeOf(cg).abiSize(cg.pt.zcu); |
| 22067 | switch (src_temp.tracking(cg).short) { | 22026 | const src_mcv = src_temp.tracking(cg).short; |
| 22068 | .register_pair, .register_triple, .register_quadruple => switch (loop.limb_offset) { | 22027 | switch (src_mcv) { |
| 22069 | .unused, .temp => loop.limb_offset = .{ .known = 0 }, | 22028 | .register, .register_pair, .register_triple, .register_quadruple => { |
| 22070 | .known => {}, | 22029 | switch (loop.limb_offset) { |
| | 22030 | .unused, .temp => loop.limb_offset = .{ .known = 0 }, |
| | 22031 | .known => {}, |
| | 22032 | } |
| | 22033 | if (!rc.isSet(RegisterManager.indexOfRegIntoTracked(src_mcv.getRegs()[0]).?)) { |
| | 22034 | if (loop.shuffle_temp == null) loop.shuffle_temp = try cg.tempAllocReg(.noreturn, abi.RegisterClass.sse); |
| | 22035 | assert(extra_temp.* == null); |
| | 22036 | extra_temp.* = try cg.tempAllocReg(.usize, rc); |
| | 22037 | } |
| 22071 | }, | 22038 | }, |
| 22072 | else => { | 22039 | else => { |
| 22073 | switch (loop.limb_offset) { | 22040 | switch (loop.limb_offset) { |
| ... | @@ -22075,7 +22042,7 @@ fn select( | ... | @@ -22075,7 +22042,7 @@ fn select( |
| 22075 | .known, .temp => {}, | 22042 | .known, .temp => {}, |
| 22076 | } | 22043 | } |
| 22077 | assert(extra_temp.* == null); | 22044 | assert(extra_temp.* == null); |
| 22078 | extra_temp.* = try cg.tempAllocReg(Type.usize, rc); | 22045 | extra_temp.* = try cg.tempAllocReg(.usize, rc); |
| 22079 | }, | 22046 | }, |
| 22080 | } | 22047 | } |
| 22081 | } | 22048 | } |
| ... | @@ -22090,13 +22057,17 @@ fn select( | ... | @@ -22090,13 +22057,17 @@ fn select( |
| 22090 | dst_temp.* = dst_temp: switch (dst_op) { | 22057 | dst_temp.* = dst_temp: switch (dst_op) { |
| 22091 | .implicit => unreachable, | 22058 | .implicit => unreachable, |
| 22092 | .explicit => |linked_index| dst_temps[linked_index], | 22059 | .explicit => |linked_index| dst_temps[linked_index], |
| | 22060 | .cc => try cg.tempFromValue(.bool, .{ .eflags = switch (invert_result) { |
| | 22061 | false => opts.cc.?, |
| | 22062 | true => opts.cc.?.negate(), |
| | 22063 | } }), |
| 22093 | .gpr => try cg.tempAllocReg(dst_ty, abi.RegisterClass.gp), | 22064 | .gpr => try cg.tempAllocReg(dst_ty, abi.RegisterClass.gp), |
| 22094 | .mm, .mm_mask, .mm_sign_mask => @panic("TODO"), | 22065 | .mm, .mm_mask, .mm_sign_mask => @panic("TODO"), |
| 22095 | .xmm, .xmm_mask, .xmm_sign_mask => try cg.tempAllocReg(dst_ty, abi.RegisterClass.sse), | 22066 | .xmm, .xmm_mask, .xmm_sign_mask => try cg.tempAllocReg(dst_ty, abi.RegisterClass.sse), |
| 22096 | .ymm, .ymm_mask, .ymm_sign_mask => try cg.tempAllocReg(dst_ty, abi.RegisterClass.sse), | 22067 | .ymm, .ymm_mask, .ymm_sign_mask => try cg.tempAllocReg(dst_ty, abi.RegisterClass.sse), |
| 22097 | .mem => @panic("TODO"), | 22068 | .mem => @panic("TODO"), |
| 22098 | .gpr_limb, .mm_limb, .xmm_limb, .ymm_limb => { | 22069 | .gpr_limb, .mm_limb, .xmm_limb, .ymm_limb => { |
| 22099 | if (extra_temp.* == null) extra_temp.* = try cg.tempAllocReg(Type.usize, switch (dst_op) { | 22070 | if (extra_temp.* == null) extra_temp.* = try cg.tempAllocReg(.noreturn, switch (dst_op) { |
| 22100 | else => unreachable, | 22071 | else => unreachable, |
| 22101 | .gpr_limb => abi.RegisterClass.gp, | 22072 | .gpr_limb => abi.RegisterClass.gp, |
| 22102 | .mm_limb => @panic("TODO"), | 22073 | .mm_limb => @panic("TODO"), |
| ... | @@ -22105,11 +22076,11 @@ fn select( | ... | @@ -22105,11 +22076,11 @@ fn select( |
| 22105 | break :dst_temp try cg.tempAlloc(dst_ty); | 22076 | break :dst_temp try cg.tempAlloc(dst_ty); |
| 22106 | }, | 22077 | }, |
| 22107 | .mem_limb => try cg.tempAlloc(dst_ty), | 22078 | .mem_limb => try cg.tempAlloc(dst_ty), |
| 22108 | .mm_mask_limb, .xmm_mask_limb, .ymm_mask_limb => unreachable, // already checked | 22079 | .cc_mask_limb, .mm_mask_limb, .xmm_mask_limb, .ymm_mask_limb => unreachable, // already checked |
| 22109 | .imm, .simm32, .umax_gpr, .umax_mm, .umax_xmm, .umax_ymm => unreachable, // unmodifiable destination | 22080 | .imm, .simm32, .umax_gpr, .umax_mm, .umax_xmm, .umax_ymm => unreachable, // unmodifiable destination |
| 22110 | }; | 22081 | }; |
| 22111 | }, | 22082 | }, |
| 22112 | .mm_mask_limb, .xmm_mask_limb, .ymm_mask_limb => { | 22083 | .cc_mask_limb, .mm_mask_limb, .xmm_mask_limb, .ymm_mask_limb => { |
| 22113 | const scalar_size = @divExact(switch (pattern_set.scalar) { | 22084 | const scalar_size = @divExact(switch (pattern_set.scalar) { |
| 22114 | .any, .bool => unreachable, | 22085 | .any, .bool => unreachable, |
| 22115 | .float, .any_int, .signed_int, .unsigned_int, .any_float_or_int => |size| size, | 22086 | .float, .any_int, .signed_int, .unsigned_int, .any_float_or_int => |size| size, |
| ... | @@ -22131,14 +22102,17 @@ fn select( | ... | @@ -22131,14 +22102,17 @@ fn select( |
| 22131 | assert(loop.mask_store_bit_size == null or loop.mask_store_bit_size == mask_store_bit_size); | 22102 | assert(loop.mask_store_bit_size == null or loop.mask_store_bit_size == mask_store_bit_size); |
| 22132 | loop.mask_store_bit_size = mask_store_bit_size; | 22103 | loop.mask_store_bit_size = mask_store_bit_size; |
| 22133 | loop.mask_limb_offset = loop.limb_offset; | 22104 | loop.mask_limb_offset = loop.limb_offset; |
| 22134 | if (extra_temp.* == null) extra_temp.* = try cg.tempAllocReg(Type.usize, switch (dst_op) { | 22105 | if (loop.mask_limb_temp == null) { |
| 22135 | else => unreachable, | 22106 | loop.mask_limb_temp = try cg.tempAllocReg(.usize, abi.RegisterClass.gp); |
| 22136 | .mm_mask_limb => @panic("TODO"), | 22107 | if (dst_op == .cc_mask_limb and mask_store_bit_size > 8) { |
| 22137 | .xmm_mask_limb, .ymm_mask_limb => abi.RegisterClass.sse, | 22108 | // setcc only clears 8 bits |
| 22138 | }); | 22109 | const mask_limb_alias = loop.mask_limb_temp.?.tracking(cg).short.register.to32(); |
| 22139 | if (loop.mask_limb_temp == null) loop.mask_limb_temp = try cg.tempAllocReg(Type.usize, abi.RegisterClass.gp); | 22110 | try cg.spillEflagsIfOccupied(); |
| | 22111 | try cg.asmRegisterRegister(.{ ._, .xor }, mask_limb_alias, mask_limb_alias); |
| | 22112 | } |
| | 22113 | } |
| 22140 | if (mask_limb_bit_size < mask_store_bit_size and loop.mask_store_reg == null) { | 22114 | if (mask_limb_bit_size < mask_store_bit_size and loop.mask_store_reg == null) { |
| 22141 | loop.mask_store_temp = try cg.tempAllocReg(Type.usize, abi.RegisterClass.gp); | 22115 | loop.mask_store_temp = try cg.tempAllocReg(.usize, abi.RegisterClass.gp); |
| 22142 | loop.mask_store_reg = loop.mask_store_temp.?.tracking(cg).short.register; | 22116 | loop.mask_store_reg = loop.mask_store_temp.?.tracking(cg).short.register; |
| 22143 | } | 22117 | } |
| 22144 | dst_temp.* = if (mask_store_bit_size < mask_bit_size) | 22118 | dst_temp.* = if (mask_store_bit_size < mask_bit_size) |
| ... | @@ -22152,28 +22126,26 @@ fn select( | ... | @@ -22152,28 +22126,26 @@ fn select( |
| 22152 | switch (loop.mask_limb_offset) { | 22126 | switch (loop.mask_limb_offset) { |
| 22153 | .unused, .known => {}, | 22127 | .unused, .known => {}, |
| 22154 | .temp => |*mask_limb_offset| { | 22128 | .temp => |*mask_limb_offset| { |
| 22155 | if (cg.hasFeature(.bmi2)) { | 22129 | mask_limb_offset.* = if (cg.hasFeature(.bmi2)) |
| 22156 | assert(loop.mask_limb_offset_lock == null); | 22130 | try cg.tempAllocReg(.usize, abi.RegisterClass.gp) |
| 22157 | mask_limb_offset.* = try cg.tempAllocReg(Type.usize, abi.RegisterClass.gp); | 22131 | else if (loop.mask_limb_offset_lock != null) |
| 22158 | } else { | 22132 | try cg.tempFromValue(.usize, .{ .register = .rcx }) |
| 22159 | if (loop.mask_limb_offset_lock) |lock| cg.register_manager.unlockReg(lock); | 22133 | else |
| 22160 | loop.mask_limb_offset_lock = null; | 22134 | unreachable; |
| 22161 | mask_limb_offset.* = try cg.tempFromValue(Type.usize, .{ .register = .rcx }); | | |
| 22162 | } | | |
| 22163 | if (loop.mask_store_reg) |mask_store_reg| { | 22135 | if (loop.mask_store_reg) |mask_store_reg| { |
| 22164 | const mask_store_alias = registerAlias( | 22136 | const mask_store_alias = |
| 22165 | mask_store_reg, | 22137 | if (loop.mask_store_bit_size.? > 8) mask_store_reg.to32() else mask_store_reg.to8(); |
| 22166 | @min(std.math.divCeil(u7, loop.mask_store_bit_size.?, 8) catch unreachable, 4), | | |
| 22167 | ); | | |
| 22168 | try cg.spillEflagsIfOccupied(); | 22138 | try cg.spillEflagsIfOccupied(); |
| 22169 | try cg.asmRegisterRegister(.{ ._, .xor }, mask_store_alias, mask_store_alias); | 22139 | try cg.asmRegisterRegister(.{ ._, .xor }, mask_store_alias, mask_store_alias); |
| 22170 | } | 22140 | } |
| 22171 | }, | 22141 | }, |
| 22172 | } | 22142 | } |
| | 22143 | if (loop.mask_limb_offset_lock) |lock| cg.register_manager.unlockReg(lock); |
| | 22144 | loop.mask_limb_offset_lock = null; |
| 22173 | switch (loop.element_offset) { | 22145 | switch (loop.element_offset) { |
| 22174 | .unused, .known => {}, | 22146 | .unused, .known => {}, |
| 22175 | .temp => |*element_offset| { | 22147 | .temp => |*element_offset| { |
| 22176 | element_offset.* = try cg.tempAllocReg(Type.usize, abi.RegisterClass.gp); | 22148 | element_offset.* = try cg.tempAllocReg(.usize, abi.RegisterClass.gp); |
| 22177 | const element_offset_reg = element_offset.tracking(cg).short.register; | 22149 | const element_offset_reg = element_offset.tracking(cg).short.register; |
| 22178 | try cg.spillEflagsIfOccupied(); | 22150 | try cg.spillEflagsIfOccupied(); |
| 22179 | try cg.asmRegisterRegister(.{ ._, .xor }, element_offset_reg.to32(), element_offset_reg.to32()); | 22151 | try cg.asmRegisterRegister(.{ ._, .xor }, element_offset_reg.to32(), element_offset_reg.to32()); |
| ... | @@ -22182,7 +22154,7 @@ fn select( | ... | @@ -22182,7 +22154,7 @@ fn select( |
| 22182 | } | 22154 | } |
| 22183 | switch (loop.limb_offset) { | 22155 | switch (loop.limb_offset) { |
| 22184 | .unused, .known => {}, | 22156 | .unused, .known => {}, |
| 22185 | .temp => |*limb_offset| limb_offset.* = try cg.tempAllocReg(Type.usize, abi.RegisterClass.gp), | 22157 | .temp => |*limb_offset| limb_offset.* = try cg.tempAllocReg(.usize, abi.RegisterClass.gp), |
| 22186 | } | 22158 | } |
| 22187 | while (true) { | 22159 | while (true) { |
| 22188 | switch (loop.mask_limb_offset) { | 22160 | switch (loop.mask_limb_offset) { |
| ... | @@ -22204,7 +22176,7 @@ fn select( | ... | @@ -22204,7 +22176,7 @@ fn select( |
| 22204 | } | 22176 | } |
| 22205 | while (true) { | 22177 | while (true) { |
| 22206 | var mir_ops: [4]Operand = @splat(.none); | 22178 | var mir_ops: [4]Operand = @splat(.none); |
| 22207 | mir_ops_len = dst_temps.len; | 22179 | mir_ops_len = dst_mir_ops_len; |
| 22208 | for (src_temps, pattern.ops[dst_temps.len..]) |src_temp, src_op| { | 22180 | for (src_temps, pattern.ops[dst_temps.len..]) |src_temp, src_op| { |
| 22209 | defer mir_ops_len += @intFromBool(src_op != .implicit); | 22181 | defer mir_ops_len += @intFromBool(src_op != .implicit); |
| 22210 | const mir_op, const linked_src_op, const extra_temp = switch (src_op) { | 22182 | const mir_op, const linked_src_op, const extra_temp = switch (src_op) { |
| ... | @@ -22217,35 +22189,146 @@ fn select( | ... | @@ -22217,35 +22189,146 @@ fn select( |
| 22217 | // src_temp is undefined | 22189 | // src_temp is undefined |
| 22218 | .umax_gpr, .umax_mm, .umax_xmm, .umax_ymm => extra_temp.?, | 22190 | .umax_gpr, .umax_mm, .umax_xmm, .umax_ymm => extra_temp.?, |
| 22219 | }.tracking(cg).short; | 22191 | }.tracking(cg).short; |
| 22220 | copy_limb: switch (src_mcv) { | 22192 | switch (linked_src_op) { |
| 22221 | .register_pair, .register_triple, .register_quadruple => {}, | 22193 | else => {}, |
| 22222 | else => try cg.asmRegisterMemory( | 22194 | .gpr_limb, |
| 22223 | switch (linked_src_op) { | 22195 | .mm_limb, |
| 22224 | else => break :copy_limb, | 22196 | .xmm_limb, |
| 22225 | .gpr_limb => .{ ._, .mov }, | 22197 | .ymm_limb, |
| 22226 | .mm_limb, .mm_mask_limb => .{ ._q, .mov }, | 22198 | .mm_mask_limb, |
| 22227 | .xmm_limb, | 22199 | .xmm_mask_limb, |
| 22228 | .ymm_limb, | 22200 | .ymm_mask_limb, |
| 22229 | .xmm_mask_limb, | 22201 | => if (extra_temp) |limb_temp| switch (src_mcv) { |
| 22230 | .ymm_mask_limb, | 22202 | .register, .register_pair, .register_triple, .register_quadruple => { |
| 22231 | => .{ if (cg.hasFeature(.avx)) .v_ else ._, .movdqu }, | 22203 | const limb_reg = registerAlias(limb_temp.tracking(cg).short.register, loop.limb_size.?); |
| | 22204 | const src_regs = src_mcv.getRegs(); |
| | 22205 | const src_reg_size: u32 = @intCast(switch (src_mcv) { |
| | 22206 | .register => src_temp.typeOf(cg).abiSize(cg.pt.zcu), |
| | 22207 | else => @divExact(src_regs[0].bitSize(), 8), |
| | 22208 | }); |
| | 22209 | const src_reg = src_regs[loop.limb_offset.known / src_reg_size]; |
| | 22210 | assert(src_mcv == .register or src_reg.bitSize() == 8 * src_reg_size); |
| | 22211 | switch (src_reg.class()) { |
| | 22212 | else => unreachable, |
| | 22213 | .general_purpose => try cg.asmRegisterRegister( |
| | 22214 | .{ ._, .mov }, |
| | 22215 | limb_reg, |
| | 22216 | registerAlias(src_reg, src_reg_size), |
| | 22217 | ), |
| | 22218 | .sse => { |
| | 22219 | assert(src_reg_size == 16); |
| | 22220 | const limb_alias_size = @max(loop.limb_size.?, 4); |
| | 22221 | const limb_alias = registerAlias(limb_reg, limb_alias_size); |
| | 22222 | const src_reg_offset = loop.limb_offset.known % src_reg_size; |
| | 22223 | switch (limb_reg_offset: { |
| | 22224 | extr: { |
| | 22225 | const limb_size = if (cg.hasFeature(.sse4_1)) loop.limb_size.? else 2; |
| | 22226 | if (loop.limb_size.? > limb_size) break :extr; |
| | 22227 | const limb_offset = src_reg_offset / limb_size; |
| | 22228 | if (limb_offset == 0) break :extr; |
| | 22229 | try cg.asmRegisterRegisterImmediate(.{ switch (limb_size) { |
| | 22230 | else => unreachable, |
| | 22231 | 1 => if (cg.hasFeature(.avx)) .vp_b else .p_b, |
| | 22232 | 2 => if (cg.hasFeature(.avx)) .vp_w else .p_w, |
| | 22233 | 4 => if (cg.hasFeature(.avx)) .vp_d else .p_d, |
| | 22234 | 8 => if (cg.hasFeature(.avx)) .vp_q else .p_q, |
| | 22235 | }, .extr }, limb_alias, src_reg.to128(), .u(limb_offset)); |
| | 22236 | break :limb_reg_offset src_reg_offset % limb_size; |
| | 22237 | } |
| | 22238 | try cg.asmRegisterRegister( |
| | 22239 | .{ switch (limb_alias_size) { |
| | 22240 | else => unreachable, |
| | 22241 | 4 => ._d, |
| | 22242 | 8 => ._q, |
| | 22243 | }, .mov }, |
| | 22244 | limb_alias, |
| | 22245 | if (src_reg_offset < limb_alias_size) src_reg.to128() else shuffle_reg: { |
| | 22246 | const shuffle_reg = loop.shuffle_temp.?.tracking(cg).short.register.to128(); |
| | 22247 | const mir_fixes: Mir.Inst.Fixes = if (cg.hasFeature(.sse2)) |
| | 22248 | if (src_temp.typeOf(cg).scalarType(cg.pt.zcu).isRuntimeFloat()) switch (limb_alias_size) { |
| | 22249 | else => unreachable, |
| | 22250 | 4 => if (cg.hasFeature(.avx)) .v_ps else ._ps, |
| | 22251 | 8 => if (cg.hasFeature(.avx)) .v_pd else ._pd, |
| | 22252 | } else if (cg.hasFeature(.avx)) .vp_d else .p_d |
| | 22253 | else |
| | 22254 | ._ps; |
| | 22255 | try cg.asmRegisterRegisterImmediate( |
| | 22256 | .{ mir_fixes, .shuf }, |
| | 22257 | shuffle_reg, |
| | 22258 | src_reg: switch (mir_fixes) { |
| | 22259 | else => unreachable, |
| | 22260 | ._ps, ._pd => { |
| | 22261 | try cg.asmRegisterRegister(.{ mir_fixes, .mova }, shuffle_reg, src_reg.to128()); |
| | 22262 | break :src_reg shuffle_reg; |
| | 22263 | }, |
| | 22264 | .p_d => src_reg.to128(), |
| | 22265 | }, |
| | 22266 | .u(switch (mir_fixes) { |
| | 22267 | else => unreachable, |
| | 22268 | .v_ps, ._ps, .vp_d, .p_d => switch (limb_alias_size) { |
| | 22269 | else => unreachable, |
| | 22270 | 4 => switch (src_reg_offset) { |
| | 22271 | else => unreachable, |
| | 22272 | 4...7 => 0b01_01_01_01, |
| | 22273 | 8...11 => 0b10_10_10_10, |
| | 22274 | 12...15 => 0b11_11_11_11, |
| | 22275 | }, |
| | 22276 | 8 => switch (src_reg_offset) { |
| | 22277 | else => unreachable, |
| | 22278 | 8...15 => 0b11_10_11_10, |
| | 22279 | }, |
| | 22280 | }, |
| | 22281 | .v_pd, ._pd => switch (limb_alias_size) { |
| | 22282 | else => unreachable, |
| | 22283 | 8 => switch (src_reg_offset) { |
| | 22284 | else => unreachable, |
| | 22285 | 8...15 => 0b1_1, |
| | 22286 | }, |
| | 22287 | }, |
| | 22288 | }), |
| | 22289 | ); |
| | 22290 | break :shuffle_reg shuffle_reg; |
| | 22291 | }, |
| | 22292 | ); |
| | 22293 | break :limb_reg_offset src_reg_offset % limb_alias_size; |
| | 22294 | }) { |
| | 22295 | 0 => {}, |
| | 22296 | else => |limb_reg_offset| { |
| | 22297 | try cg.spillEflagsIfOccupied(); |
| | 22298 | try cg.asmRegisterImmediate(.{ ._r, .sh }, limb_alias, .u(limb_reg_offset * 8)); |
| | 22299 | }, |
| | 22300 | } |
| | 22301 | }, |
| | 22302 | } |
| 22232 | }, | 22303 | }, |
| 22233 | registerAlias(extra_temp.?.tracking(cg).short.register, loop.limb_size.?), | 22304 | else => try cg.asmRegisterMemory( |
| 22234 | try src_mcv.mem(cg, switch (loop.limb_offset) { | 22305 | switch (linked_src_op) { |
| 22235 | .unused => unreachable, | 22306 | else => unreachable, |
| 22236 | .known => |limb_offset| .{ | 22307 | .gpr_limb => .{ ._, .mov }, |
| 22237 | .size = .fromSize(loop.limb_size.?), | 22308 | .mm_limb, .mm_mask_limb => .{ ._q, .mov }, |
| 22238 | .disp = limb_offset, | 22309 | .xmm_limb, |
| 22239 | }, | 22310 | .ymm_limb, |
| 22240 | .temp => |limb_offset| .{ | 22311 | .xmm_mask_limb, |
| 22241 | .size = .fromSize(loop.limb_size.?), | 22312 | .ymm_mask_limb, |
| 22242 | .index = limb_offset.tracking(cg).short.register.to64(), | 22313 | => .{ if (cg.hasFeature(.avx)) .v_ else ._, .movdqu }, |
| 22243 | }, | 22314 | }, |
| 22244 | }), | 22315 | registerAlias(limb_temp.tracking(cg).short.register, loop.limb_size.?), |
| 22245 | ), | 22316 | try src_mcv.mem(cg, switch (loop.limb_offset) { |
| | 22317 | .unused => unreachable, |
| | 22318 | .known => |limb_offset| .{ |
| | 22319 | .size = .fromSize(loop.limb_size.?), |
| | 22320 | .disp = limb_offset, |
| | 22321 | }, |
| | 22322 | .temp => |limb_offset| .{ |
| | 22323 | .size = .fromSize(loop.limb_size.?), |
| | 22324 | .index = limb_offset.tracking(cg).short.register.to64(), |
| | 22325 | }, |
| | 22326 | }), |
| | 22327 | ), |
| | 22328 | }, |
| 22246 | } | 22329 | } |
| 22247 | mir_op.* = switch (linked_src_op) { | 22330 | mir_op.* = switch (linked_src_op) { |
| 22248 | .implicit, .explicit => unreachable, | 22331 | .implicit, .explicit, .cc, .cc_mask_limb => unreachable, |
| 22249 | .gpr => .{ .reg = registerAlias( | 22332 | .gpr => .{ .reg = registerAlias( |
| 22250 | src_mcv.register, | 22333 | src_mcv.register, |
| 22251 | @intCast(src_temp.typeOf(cg).abiSize(cg.pt.zcu)), | 22334 | @intCast(src_temp.typeOf(cg).abiSize(cg.pt.zcu)), |
| ... | @@ -22262,25 +22345,12 @@ fn select( | ... | @@ -22262,25 +22345,12 @@ fn select( |
| 22262 | .mm_mask_limb, | 22345 | .mm_mask_limb, |
| 22263 | .xmm_mask_limb, | 22346 | .xmm_mask_limb, |
| 22264 | .ymm_mask_limb, | 22347 | .ymm_mask_limb, |
| 22265 | => switch (src_mcv) { | 22348 | => .{ .reg = registerAlias(if (extra_temp) |limb_temp| |
| 22266 | inline .register_pair, | 22349 | limb_temp.tracking(cg).short.register |
| 22267 | .register_triple, | 22350 | else |
| 22268 | .register_quadruple, | 22351 | src_mcv.getRegs()[@divExact(loop.limb_offset.known, loop.limb_size.?)], loop.limb_size.?) }, |
| 22269 | => |src_regs| switch (loop.limb_offset) { | | |
| 22270 | .unused => unreachable, | | |
| 22271 | .known => |limb_offset| .{ .reg = registerAlias( | | |
| 22272 | src_regs[@divExact(limb_offset, loop.limb_size.?)], | | |
| 22273 | loop.limb_size.?, | | |
| 22274 | ) }, | | |
| 22275 | .temp => unreachable, | | |
| 22276 | }, | | |
| 22277 | else => .{ .reg = registerAlias( | | |
| 22278 | extra_temp.?.tracking(cg).short.register, | | |
| 22279 | loop.limb_size.?, | | |
| 22280 | ) }, | | |
| 22281 | }, | | |
| 22282 | .mem_limb => .{ .mem = switch (src_mcv) { | 22352 | .mem_limb => .{ .mem = switch (src_mcv) { |
| 22283 | .register_pair, .register_triple, .register_quadruple => unreachable, | 22353 | .register, .register_pair, .register_triple, .register_quadruple => unreachable, |
| 22284 | else => switch (loop.limb_offset) { | 22354 | else => switch (loop.limb_offset) { |
| 22285 | .unused => unreachable, | 22355 | .unused => unreachable, |
| 22286 | .known => |limb_offset| try src_mcv.mem(cg, .{ | 22356 | .known => |limb_offset| try src_mcv.mem(cg, .{ |
| ... | @@ -22316,15 +22386,15 @@ fn select( | ... | @@ -22316,15 +22386,15 @@ fn select( |
| 22316 | } | 22386 | } |
| 22317 | } | 22387 | } |
| 22318 | for ( | 22388 | for ( |
| 22319 | mir_ops[0..dst_temps.len], | 22389 | mir_ops[0..dst_mir_ops_len], |
| 22320 | pattern.ops[0..dst_temps.len], | 22390 | pattern.ops[0..dst_mir_ops_len], |
| 22321 | dst_temps, | 22391 | dst_temps[0..dst_mir_ops_len], |
| 22322 | dst_tys, | 22392 | dst_tys[0..dst_mir_ops_len], |
| 22323 | extra_temps[0..dst_temps.len], | 22393 | extra_temps[0..dst_mir_ops_len], |
| 22324 | ) |*mir_op, dst_op, dst_temp, dst_ty, extra_temp| { | 22394 | ) |*mir_op, dst_op, dst_temp, dst_ty, extra_temp| { |
| 22325 | if (mir_op.* != .none) continue; | 22395 | if (mir_op.* != .none) continue; |
| 22326 | mir_op.* = switch (dst_op) { | 22396 | mir_op.* = switch (dst_op) { |
| 22327 | .implicit => unreachable, | 22397 | .implicit, .cc, .cc_mask_limb => unreachable, |
| 22328 | .explicit => |linked_index| mir_ops[linked_index], | 22398 | .explicit => |linked_index| mir_ops[linked_index], |
| 22329 | .gpr => .{ .reg = registerAlias( | 22399 | .gpr => .{ .reg = registerAlias( |
| 22330 | dst_temp.tracking(cg).short.register, | 22400 | dst_temp.tracking(cg).short.register, |
| ... | @@ -22334,7 +22404,14 @@ fn select( | ... | @@ -22334,7 +22404,14 @@ fn select( |
| 22334 | .xmm, .xmm_mask, .xmm_sign_mask => .{ .reg = dst_temp.tracking(cg).short.register.to128() }, | 22404 | .xmm, .xmm_mask, .xmm_sign_mask => .{ .reg = dst_temp.tracking(cg).short.register.to128() }, |
| 22335 | .ymm, .ymm_mask, .ymm_sign_mask => .{ .reg = dst_temp.tracking(cg).short.register.to256() }, | 22405 | .ymm, .ymm_mask, .ymm_sign_mask => .{ .reg = dst_temp.tracking(cg).short.register.to256() }, |
| 22336 | .mem => @panic("TODO"), | 22406 | .mem => @panic("TODO"), |
| 22337 | .gpr_limb => .{ .reg = extra_temp.?.tracking(cg).short.register.to64() }, | 22407 | .gpr_limb => .{ .reg = registerAlias( |
| | 22408 | extra_temp.?.tracking(cg).short.register, |
| | 22409 | @intCast(@divExact(@as(Memory.Size, switch (pattern_set.scalar) { |
| | 22410 | .any => .qword, |
| | 22411 | .bool => unreachable, |
| | 22412 | .float, .any_int, .signed_int, .unsigned_int, .any_float_or_int => |size| size, |
| | 22413 | }).bitSize(), 8)), |
| | 22414 | ) }, |
| 22338 | .mm_limb => .{ .reg = extra_temp.?.tracking(cg).short.register }, | 22415 | .mm_limb => .{ .reg = extra_temp.?.tracking(cg).short.register }, |
| 22339 | .xmm_limb => .{ .reg = extra_temp.?.tracking(cg).short.register.to128() }, | 22416 | .xmm_limb => .{ .reg = extra_temp.?.tracking(cg).short.register.to128() }, |
| 22340 | .ymm_limb => .{ .reg = extra_temp.?.tracking(cg).short.register.to256() }, | 22417 | .ymm_limb => .{ .reg = extra_temp.?.tracking(cg).short.register.to256() }, |
| ... | @@ -22376,7 +22453,6 @@ fn select( | ... | @@ -22376,7 +22453,6 @@ fn select( |
| 22376 | }, | 22453 | }, |
| 22377 | else => |e| return e, | 22454 | else => |e| return e, |
| 22378 | }; | 22455 | }; |
| 22379 | const invert_result = opts.invert_result != pattern_set.invert_result; | | |
| 22380 | for ( | 22456 | for ( |
| 22381 | extra_temps[0..dst_temps.len], | 22457 | extra_temps[0..dst_temps.len], |
| 22382 | pattern.ops[0..dst_temps.len], | 22458 | pattern.ops[0..dst_temps.len], |
| ... | @@ -22410,21 +22486,15 @@ fn select( | ... | @@ -22410,21 +22486,15 @@ fn select( |
| 22410 | .any, .bool => unreachable, | 22486 | .any, .bool => unreachable, |
| 22411 | .float, .any_int, .signed_int, .unsigned_int, .any_float_or_int => |size| size, | 22487 | .float, .any_int, .signed_int, .unsigned_int, .any_float_or_int => |size| size, |
| 22412 | }, cg), | 22488 | }, cg), |
| 22413 | .gpr_limb, .mm_limb, .xmm_limb, .ymm_limb => if (extra_temp) |limb_temp| | 22489 | .gpr_limb, .mm_limb, .xmm_limb, .ymm_limb => if (extra_temp) |limb_temp| { |
| 22414 | switch (dst_temp.tracking(cg).short) { | 22490 | const dst_mcv = dst_temp.tracking(cg).short; |
| 22415 | inline .register_pair, | 22491 | switch (dst_mcv) { |
| 22416 | .register_triple, | 22492 | .register_pair, .register_triple, .register_quadruple => try cg.asmRegisterRegister( |
| 22417 | .register_quadruple, | 22493 | .{ ._, .mov }, |
| 22418 | => |dst_regs| switch (loop.limb_offset) { | 22494 | dst_mcv.getRegs()[@divExact(loop.limb_offset.known, loop.limb_size.?)].to64(), |
| 22419 | .unused => unreachable, | 22495 | limb_temp.tracking(cg).short.register.to64(), |
| 22420 | .known => |limb_offset| try cg.asmRegisterRegister( | 22496 | ), |
| 22421 | .{ ._, .mov }, | 22497 | else => try cg.asmMemoryRegister( |
| 22422 | dst_regs[@divExact(limb_offset, loop.limb_size.?)].to64(), | | |
| 22423 | limb_temp.tracking(cg).short.register.to64(), | | |
| 22424 | ), | | |
| 22425 | .temp => unreachable, | | |
| 22426 | }, | | |
| 22427 | else => |dst_mcv| try cg.asmMemoryRegister( | | |
| 22428 | switch (dst_op) { | 22498 | switch (dst_op) { |
| 22429 | else => unreachable, | 22499 | else => unreachable, |
| 22430 | .gpr_limb => .{ ._, .mov }, | 22500 | .gpr_limb => .{ ._, .mov }, |
| ... | @@ -22444,57 +22514,66 @@ fn select( | ... | @@ -22444,57 +22514,66 @@ fn select( |
| 22444 | }), | 22514 | }), |
| 22445 | registerAlias(limb_temp.tracking(cg).short.register, loop.limb_size.?), | 22515 | registerAlias(limb_temp.tracking(cg).short.register, loop.limb_size.?), |
| 22446 | ), | 22516 | ), |
| 22447 | }, | 22517 | } |
| 22448 | .mm_mask_limb, .xmm_mask_limb, .ymm_mask_limb => { | 22518 | }, |
| | 22519 | .cc_mask_limb, .mm_mask_limb, .xmm_mask_limb, .ymm_mask_limb => { |
| 22449 | const scalar_size = switch (pattern_set.scalar) { | 22520 | const scalar_size = switch (pattern_set.scalar) { |
| 22450 | .any, .bool => unreachable, | 22521 | .any, .bool => unreachable, |
| 22451 | .float, .any_int, .signed_int, .unsigned_int, .any_float_or_int => |size| size, | 22522 | .float, .any_int, .signed_int, .unsigned_int, .any_float_or_int => |size| size, |
| 22452 | }; | 22523 | }; |
| 22453 | switch (scalar_size) { | | |
| 22454 | else => {}, | | |
| 22455 | .word => if (cg.hasFeature(.avx)) try cg.asmRegisterRegisterRegister( | | |
| 22456 | .{ .vp_b, .ackssw }, | | |
| 22457 | mir_op.reg, | | |
| 22458 | mir_op.reg, | | |
| 22459 | mir_op.reg, | | |
| 22460 | ) else try cg.asmRegisterRegister( | | |
| 22461 | .{ .p_b, .ackssw }, | | |
| 22462 | mir_op.reg, | | |
| 22463 | mir_op.reg, | | |
| 22464 | ), | | |
| 22465 | } | | |
| 22466 | const mask_store_size: u4 = | 22524 | const mask_store_size: u4 = |
| 22467 | @intCast(std.math.divCeil(u7, loop.mask_store_bit_size.?, 8) catch unreachable); | 22525 | @intCast(std.math.divCeil(u7, loop.mask_store_bit_size.?, 8) catch unreachable); |
| 22468 | const mask_limb_reg = registerAlias( | 22526 | const known_shl_count = if (loop.mask_store_reg) |_| switch (loop.mask_limb_offset) { |
| 22469 | loop.mask_limb_temp.?.tracking(cg).short.register, | 22527 | .unused => unreachable, |
| 22470 | mask_store_size, | 22528 | .known => |mask_limb_offset| mask_limb_offset & (loop.mask_store_bit_size.? - 1), |
| 22471 | ); | 22529 | .temp => null, |
| 22472 | try cg.asmRegisterRegister(switch (scalar_size) { | 22530 | } else null; |
| | 22531 | const mask_limb_reg = registerAlias(if (known_shl_count != 0) |
| | 22532 | loop.mask_limb_temp.?.tracking(cg).short.register |
| | 22533 | else |
| | 22534 | loop.mask_store_reg.?, mask_store_size); |
| | 22535 | switch (dst_op) { |
| 22473 | else => unreachable, | 22536 | else => unreachable, |
| 22474 | .byte, .word => .{ if (cg.hasFeature(.avx)) .vp_b else .p_b, .movmsk }, | 22537 | .cc_mask_limb => try cg.asmSetccRegister(switch (invert_result) { |
| 22475 | .dword => .{ if (cg.hasFeature(.avx)) .v_ps else ._ps, .movmsk }, | 22538 | false => opts.cc.?, |
| 22476 | .qword => .{ if (cg.hasFeature(.avx)) .v_pd else ._pd, .movmsk }, | 22539 | true => opts.cc.?.negate(), |
| 22477 | }, mask_limb_reg.to32(), mir_op.reg); | 22540 | }, mask_limb_reg.to8()), |
| 22478 | if (invert_result) if (loop.mask_store_reg) |_| { | 22541 | .mm_mask_limb, .xmm_mask_limb, .ymm_mask_limb => { |
| 22479 | try cg.spillEflagsIfOccupied(); | 22542 | if (scalar_size == .word) if (cg.hasFeature(.avx)) try cg.asmRegisterRegisterRegister( |
| 22480 | try cg.asmRegisterImmediate( | 22543 | .{ .vp_b, .ackssw }, |
| 22481 | .{ ._, .xor }, | 22544 | mir_op.reg, |
| 22482 | registerAlias(mask_limb_reg, @min(mask_store_size, 4)), | 22545 | mir_op.reg, |
| 22483 | .u((@as(u32, 1) << @intCast(loop.mask_limb_bit_size.?)) - 1), | 22546 | mir_op.reg, |
| 22484 | ); | 22547 | ) else try cg.asmRegisterRegister( |
| 22485 | } else try cg.asmRegister(.{ ._, .not }, mask_limb_reg); | 22548 | .{ .p_b, .ackssw }, |
| | 22549 | mir_op.reg, |
| | 22550 | mir_op.reg, |
| | 22551 | ); |
| | 22552 | try cg.asmRegisterRegister(switch (scalar_size) { |
| | 22553 | else => unreachable, |
| | 22554 | .byte, .word => .{ if (cg.hasFeature(.avx)) .vp_b else .p_b, .movmsk }, |
| | 22555 | .dword => .{ if (cg.hasFeature(.avx)) .v_ps else ._ps, .movmsk }, |
| | 22556 | .qword => .{ if (cg.hasFeature(.avx)) .v_pd else ._pd, .movmsk }, |
| | 22557 | }, mask_limb_reg.to32(), mir_op.reg); |
| | 22558 | if (invert_result) if (loop.mask_store_reg) |_| { |
| | 22559 | try cg.spillEflagsIfOccupied(); |
| | 22560 | try cg.asmRegisterImmediate( |
| | 22561 | .{ ._, .xor }, |
| | 22562 | registerAlias(mask_limb_reg, @min(mask_store_size, 4)), |
| | 22563 | .u((@as(u32, 1) << @intCast(loop.mask_limb_bit_size.?)) - 1), |
| | 22564 | ); |
| | 22565 | } else try cg.asmRegister(.{ ._, .not }, mask_limb_reg); |
| | 22566 | }, |
| | 22567 | } |
| 22486 | if (loop.mask_store_reg) |mask_store_reg| { | 22568 | if (loop.mask_store_reg) |mask_store_reg| { |
| 22487 | const mask_store_alias = registerAlias(mask_store_reg, mask_store_size); | 22569 | const mask_store_alias = registerAlias(mask_store_reg, mask_store_size); |
| 22488 | switch (loop.mask_limb_offset) { | 22570 | switch (loop.mask_limb_offset) { |
| 22489 | .unused => unreachable, | 22571 | .unused => unreachable, |
| 22490 | .known => |mask_limb_offset| switch (mask_limb_offset & (loop.mask_store_bit_size.? - 1)) { | 22572 | .known => if (known_shl_count.? != 0) { |
| 22491 | 0 => try cg.asmRegisterRegister(.{ ._, .mov }, mask_store_alias, mask_limb_reg), | 22573 | try cg.spillEflagsIfOccupied(); |
| 22492 | else => |shl_count| { | 22574 | try cg.asmRegisterImmediate(.{ ._l, .sh }, mask_limb_reg, .u(known_shl_count.?)); |
| 22493 | try cg.spillEflagsIfOccupied(); | 22575 | try cg.spillEflagsIfOccupied(); |
| 22494 | try cg.asmRegisterImmediate(.{ ._l, .sh }, mask_limb_reg, .u(shl_count)); | 22576 | try cg.asmRegisterRegister(.{ ._, .@"or" }, mask_store_alias, mask_limb_reg); |
| 22495 | try cg.spillEflagsIfOccupied(); | | |
| 22496 | try cg.asmRegisterRegister(.{ ._, .@"or" }, mask_store_alias, mask_limb_reg); | | |
| 22497 | }, | | |
| 22498 | }, | 22577 | }, |
| 22499 | .temp => |mask_limb_offset| { | 22578 | .temp => |mask_limb_offset| { |
| 22500 | if (cg.hasFeature(.bmi2)) { | 22579 | if (cg.hasFeature(.bmi2)) { |
| ... | @@ -22524,23 +22603,23 @@ fn select( | ... | @@ -22524,23 +22603,23 @@ fn select( |
| 22524 | .unused => unreachable, | 22603 | .unused => unreachable, |
| 22525 | .known => |*mask_limb_offset| { | 22604 | .known => |*mask_limb_offset| { |
| 22526 | mask_limb_offset.* += loop.mask_limb_bit_size.?; | 22605 | mask_limb_offset.* += loop.mask_limb_bit_size.?; |
| 22527 | if (mask_limb_offset.* & (loop.mask_store_bit_size.? - 1) == 0) { | 22606 | if (mask_limb_offset.* & (loop.mask_store_bit_size.? - 1) == 0) switch (dst_mcv) { |
| 22528 | switch (dst_mcv) { | 22607 | .register => {}, |
| 22529 | .register => {}, | 22608 | else => { |
| 22530 | else => try cg.asmMemoryRegister( | 22609 | try cg.asmMemoryRegister( |
| 22531 | .{ ._, .mov }, | 22610 | .{ ._, .mov }, |
| 22532 | try dst_mcv.mem(cg, .{ | 22611 | try dst_mcv.mem(cg, .{ |
| 22533 | .size = .fromSize(mask_store_size), | 22612 | .size = .fromSize(mask_store_size), |
| 22534 | .disp = @divExact(mask_limb_offset.*, 8) - mask_store_size, | 22613 | .disp = @divExact(mask_limb_offset.*, 8) - mask_store_size, |
| 22535 | }), | 22614 | }), |
| 22536 | registerAlias(loop.mask_store_reg orelse mask_limb_reg, mask_store_size), | 22615 | registerAlias(loop.mask_store_reg orelse mask_limb_reg, mask_store_size), |
| 22537 | ), | 22616 | ); |
| 22538 | } | 22617 | if (loop.mask_store_reg) |mask_store_reg| { |
| 22539 | if (loop.mask_store_reg) |mask_store_reg| { | 22618 | const mask_store_alias = registerAlias(mask_store_reg, @min(mask_store_size, 4)); |
| 22540 | const mask_store_alias = registerAlias(mask_store_reg, @min(mask_store_size, 4)); | 22619 | try cg.asmRegisterRegister(.{ ._, .xor }, mask_store_alias, mask_store_alias); |
| 22541 | try cg.asmRegisterRegister(.{ ._, .xor }, mask_store_alias, mask_store_alias); | 22620 | } |
| 22542 | } | 22621 | }, |
| 22543 | } | 22622 | }; |
| 22544 | }, | 22623 | }, |
| 22545 | .temp => |mask_limb_offset| { | 22624 | .temp => |mask_limb_offset| { |
| 22546 | const mask_limb_offset_reg = mask_limb_offset.tracking(cg).short.register.to32(); | 22625 | const mask_limb_offset_reg = mask_limb_offset.tracking(cg).short.register.to32(); |
| ... | @@ -22641,6 +22720,7 @@ fn select( | ... | @@ -22641,6 +22720,7 @@ fn select( |
| 22641 | }, | 22720 | }, |
| 22642 | } | 22721 | } |
| 22643 | } | 22722 | } |
| | 22723 | if (loop.shuffle_temp) |shuffle_temp| try shuffle_temp.die(cg); |
| 22644 | if (loop.mask_limb_temp) |mask_limb_temp| try mask_limb_temp.die(cg); | 22724 | if (loop.mask_limb_temp) |mask_limb_temp| try mask_limb_temp.die(cg); |
| 22645 | if (loop.mask_store_temp) |mask_store_temp| try mask_store_temp.die(cg); | 22725 | if (loop.mask_store_temp) |mask_store_temp| try mask_store_temp.die(cg); |
| 22646 | switch (loop.mask_limb_offset) { | 22726 | switch (loop.mask_limb_offset) { |