| ... | @@ -2492,8 +2492,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2492,8 +2492,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2492 | .atomic_store_seq_cst => try cg.airAtomicStore(inst, .seq_cst), | 2492 | .atomic_store_seq_cst => try cg.airAtomicStore(inst, .seq_cst), |
| 2493 | | 2493 | |
| 2494 | .array_elem_val => try cg.airArrayElemVal(inst), | 2494 | .array_elem_val => try cg.airArrayElemVal(inst), |
| 2495 | .slice_elem_val => try cg.airSliceElemVal(inst), | | |
| 2496 | .ptr_elem_val => try cg.airPtrElemVal(inst), | | |
| 2497 | | 2495 | |
| 2498 | .optional_payload => try cg.airOptionalPayload(inst), | 2496 | .optional_payload => try cg.airOptionalPayload(inst), |
| 2499 | .unwrap_errunion_err => try cg.airUnwrapErrUnionErr(inst), | 2497 | .unwrap_errunion_err => try cg.airUnwrapErrUnionErr(inst), |
| ... | @@ -3995,7 +3993,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -3995,7 +3993,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 3995 | var slot = try cg.tempFromValue(cg.typeOfIndex(inst), .{ .load_frame = .{ | 3993 | var slot = try cg.tempFromValue(cg.typeOfIndex(inst), .{ .load_frame = .{ |
| 3996 | .index = .ret_addr, | 3994 | .index = .ret_addr, |
| 3997 | } }); | 3995 | } }); |
| 3998 | while (try slot.toAnyReg(cg)) {} | 3996 | while (try slot.toRegClass(true, .general_purpose, cg)) {} |
| 3999 | try slot.moveTo(inst, cg); | 3997 | try slot.moveTo(inst, cg); |
| 4000 | }, | 3998 | }, |
| 4001 | .frame_addr => if (use_old) try cg.airFrameAddress(inst) else { | 3999 | .frame_addr => if (use_old) try cg.airFrameAddress(inst) else { |
| ... | @@ -9445,7 +9443,111 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9445,7 +9443,111 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9445 | try ops[0].toOffset(0, cg); | 9443 | try ops[0].toOffset(0, cg); |
| 9446 | try ops[0].moveTo(inst, cg); | 9444 | try ops[0].moveTo(inst, cg); |
| 9447 | }, | 9445 | }, |
| 9448 | .slice_elem_ptr, .ptr_elem_ptr => |tag| if (use_old) switch (tag) { | 9446 | .slice_elem_val, .ptr_elem_val => |air_tag| if (use_old) switch (air_tag) { |
| | 9447 | else => unreachable, |
| | 9448 | .slice_elem_val => try cg.airSliceElemVal(inst), |
| | 9449 | .ptr_elem_val => try cg.airPtrElemVal(inst), |
| | 9450 | } else { |
| | 9451 | const bin_op = air_datas[@intFromEnum(inst)].bin_op; |
| | 9452 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); |
| | 9453 | switch (air_tag) { |
| | 9454 | else => unreachable, |
| | 9455 | .slice_elem_val => try ops[0].toLimb(0, cg), |
| | 9456 | .ptr_elem_val => {}, |
| | 9457 | } |
| | 9458 | var res: [1]Temp = undefined; |
| | 9459 | const res_ty = cg.typeOfIndex(inst); |
| | 9460 | cg.select(&res, &.{res_ty}, &ops, comptime &.{ .{ |
| | 9461 | .dst_constraints = .{.{ .int = .byte }}, |
| | 9462 | .patterns = &.{ |
| | 9463 | .{ .src = .{ .to_gpr, .simm32 } }, |
| | 9464 | .{ .src = .{ .to_gpr, .to_gpr } }, |
| | 9465 | }, |
| | 9466 | .dst_temps = .{.{ .rc = .general_purpose }}, |
| | 9467 | .each = .{ .once = &.{ |
| | 9468 | .{ ._, ._, .movzx, .dst0d, .leai(.byte, .src0, .src1), ._, ._ }, |
| | 9469 | } }, |
| | 9470 | }, .{ |
| | 9471 | .dst_constraints = .{.{ .int = .word }}, |
| | 9472 | .patterns = &.{ |
| | 9473 | .{ .src = .{ .to_gpr, .simm32 } }, |
| | 9474 | .{ .src = .{ .to_gpr, .to_gpr } }, |
| | 9475 | }, |
| | 9476 | .dst_temps = .{.{ .rc = .general_purpose }}, |
| | 9477 | .each = .{ .once = &.{ |
| | 9478 | .{ ._, ._, .movzx, .dst0d, .leasi(.word, .src0, .@"2", .src1), ._, ._ }, |
| | 9479 | } }, |
| | 9480 | }, .{ |
| | 9481 | .dst_constraints = .{.{ .int = .dword }}, |
| | 9482 | .patterns = &.{ |
| | 9483 | .{ .src = .{ .to_gpr, .simm32 } }, |
| | 9484 | .{ .src = .{ .to_gpr, .to_gpr } }, |
| | 9485 | }, |
| | 9486 | .dst_temps = .{.{ .rc = .general_purpose }}, |
| | 9487 | .each = .{ .once = &.{ |
| | 9488 | .{ ._, ._, .mov, .dst0d, .leasi(.dword, .src0, .@"4", .src1), ._, ._ }, |
| | 9489 | } }, |
| | 9490 | }, .{ |
| | 9491 | .required_features = .{ .@"64bit", null, null, null }, |
| | 9492 | .dst_constraints = .{.{ .int = .qword }}, |
| | 9493 | .patterns = &.{ |
| | 9494 | .{ .src = .{ .to_gpr, .simm32 } }, |
| | 9495 | .{ .src = .{ .to_gpr, .to_gpr } }, |
| | 9496 | }, |
| | 9497 | .dst_temps = .{.{ .rc = .general_purpose }}, |
| | 9498 | .each = .{ .once = &.{ |
| | 9499 | .{ ._, ._, .mov, .dst0q, .leasi(.qword, .src0, .@"8", .src1), ._, ._ }, |
| | 9500 | } }, |
| | 9501 | } }) catch |err| switch (err) { |
| | 9502 | error.SelectFailed => switch (res_ty.abiSize(zcu)) { |
| | 9503 | 0 => res[0] = try cg.tempFromValue(res_ty, .none), |
| | 9504 | else => |elem_size| { |
| | 9505 | while (true) for (&ops) |*op| { |
| | 9506 | if (try op.toRegClass(true, .general_purpose, cg)) break; |
| | 9507 | } else break; |
| | 9508 | const lhs_reg = ops[0].unwrap(cg).temp.tracking(cg).short.register.to64(); |
| | 9509 | const rhs_reg = ops[1].unwrap(cg).temp.tracking(cg).short.register.to64(); |
| | 9510 | if (!std.math.isPowerOfTwo(elem_size)) { |
| | 9511 | try cg.spillEflagsIfOccupied(); |
| | 9512 | try cg.asmRegisterRegisterImmediate( |
| | 9513 | .{ .i_, .mul }, |
| | 9514 | rhs_reg, |
| | 9515 | rhs_reg, |
| | 9516 | .u(elem_size), |
| | 9517 | ); |
| | 9518 | try cg.asmRegisterMemory(.{ ._, .lea }, lhs_reg, .{ |
| | 9519 | .base = .{ .reg = lhs_reg }, |
| | 9520 | .mod = .{ .rm = .{ .size = .qword, .index = rhs_reg } }, |
| | 9521 | }); |
| | 9522 | } else if (elem_size > 8) { |
| | 9523 | try cg.spillEflagsIfOccupied(); |
| | 9524 | try cg.asmRegisterImmediate( |
| | 9525 | .{ ._l, .sh }, |
| | 9526 | rhs_reg, |
| | 9527 | .u(std.math.log2_int(u64, elem_size)), |
| | 9528 | ); |
| | 9529 | try cg.asmRegisterMemory(.{ ._, .lea }, lhs_reg, .{ |
| | 9530 | .base = .{ .reg = lhs_reg }, |
| | 9531 | .mod = .{ .rm = .{ .size = .qword, .index = rhs_reg } }, |
| | 9532 | }); |
| | 9533 | } else try cg.asmRegisterMemory(.{ ._, .lea }, lhs_reg, .{ |
| | 9534 | .base = .{ .reg = lhs_reg }, |
| | 9535 | .mod = .{ .rm = .{ |
| | 9536 | .size = .qword, |
| | 9537 | .index = rhs_reg, |
| | 9538 | .scale = .fromFactor(@intCast(elem_size)), |
| | 9539 | } }, |
| | 9540 | }); |
| | 9541 | res[0] = try ops[0].load(res_ty, cg); |
| | 9542 | }, |
| | 9543 | }, |
| | 9544 | else => |e| return e, |
| | 9545 | }; |
| | 9546 | if (ops[0].index != res[0].index) try ops[0].die(cg); |
| | 9547 | if (ops[1].index != res[0].index) try ops[1].die(cg); |
| | 9548 | try res[0].moveTo(inst, cg); |
| | 9549 | }, |
| | 9550 | .slice_elem_ptr, .ptr_elem_ptr => |air_tag| if (use_old) switch (air_tag) { |
| 9449 | else => unreachable, | 9551 | else => unreachable, |
| 9450 | .slice_elem_ptr => try cg.airSliceElemPtr(inst), | 9552 | .slice_elem_ptr => try cg.airSliceElemPtr(inst), |
| 9451 | .ptr_elem_ptr => try cg.airPtrElemPtr(inst), | 9553 | .ptr_elem_ptr => try cg.airPtrElemPtr(inst), |
| ... | @@ -9453,7 +9555,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9453,7 +9555,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9453 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; | 9555 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; |
| 9454 | const bin_op = cg.air.extraData(Air.Bin, ty_pl.payload).data; | 9556 | const bin_op = cg.air.extraData(Air.Bin, ty_pl.payload).data; |
| 9455 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); | 9557 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); |
| 9456 | switch (tag) { | 9558 | switch (air_tag) { |
| 9457 | else => unreachable, | 9559 | else => unreachable, |
| 9458 | .slice_elem_ptr => try ops[0].toLimb(0, cg), | 9560 | .slice_elem_ptr => try ops[0].toLimb(0, cg), |
| 9459 | .ptr_elem_ptr => {}, | 9561 | .ptr_elem_ptr => {}, |
| ... | @@ -9463,7 +9565,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9463,7 +9565,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9463 | const elem_size = dst_ty.childType(zcu).abiSize(zcu); | 9565 | const elem_size = dst_ty.childType(zcu).abiSize(zcu); |
| 9464 | if (elem_size == 0) break :zero_offset; | 9566 | if (elem_size == 0) break :zero_offset; |
| 9465 | while (true) for (&ops) |*op| { | 9567 | while (true) for (&ops) |*op| { |
| 9466 | if (try op.toAnyReg(cg)) break; | 9568 | if (try op.toRegClass(true, .general_purpose, cg)) break; |
| 9467 | } else break; | 9569 | } else break; |
| 9468 | const lhs_reg = ops[0].unwrap(cg).temp.tracking(cg).short.register.to64(); | 9570 | const lhs_reg = ops[0].unwrap(cg).temp.tracking(cg).short.register.to64(); |
| 9469 | const rhs_reg = ops[1].unwrap(cg).temp.tracking(cg).short.register.to64(); | 9571 | const rhs_reg = ops[1].unwrap(cg).temp.tracking(cg).short.register.to64(); |
| ... | @@ -27718,6 +27820,7 @@ const Temp = struct { | ... | @@ -27718,6 +27820,7 @@ const Temp = struct { |
| 27718 | }, | 27820 | }, |
| 27719 | }; | 27821 | }; |
| 27720 | const new_temp_index = cg.next_temp_index; | 27822 | const new_temp_index = cg.next_temp_index; |
| | 27823 | try cg.register_manager.getReg(new_reg, new_temp_index.toIndex()); |
| 27721 | cg.temp_type[@intFromEnum(new_temp_index)] = ty; | 27824 | cg.temp_type[@intFromEnum(new_temp_index)] = ty; |
| 27722 | try cg.genSetReg(new_reg, ty, val, .{}); | 27825 | try cg.genSetReg(new_reg, ty, val, .{}); |
| 27723 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); | 27826 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); |
| ... | @@ -27727,27 +27830,6 @@ const Temp = struct { | ... | @@ -27727,27 +27830,6 @@ const Temp = struct { |
| 27727 | return true; | 27830 | return true; |
| 27728 | } | 27831 | } |
| 27729 | | 27832 | |
| 27730 | fn toAnyReg(temp: *Temp, cg: *CodeGen) !bool { | | |
| 27731 | const val, const ty = switch (temp.unwrap(cg)) { | | |
| 27732 | .ref => |ref| .{ temp.tracking(cg).short, cg.typeOf(ref) }, | | |
| 27733 | .temp => |temp_index| val: { | | |
| 27734 | const temp_tracking = temp_index.tracking(cg); | | |
| 27735 | if (temp_tracking.short == .register) return false; | | |
| 27736 | break :val .{ temp_tracking.short, temp_index.typeOf(cg) }; | | |
| 27737 | }, | | |
| 27738 | }; | | |
| 27739 | const new_temp_index = cg.next_temp_index; | | |
| 27740 | cg.temp_type[@intFromEnum(new_temp_index)] = ty; | | |
| 27741 | const new_reg = | | |
| 27742 | try cg.register_manager.allocReg(new_temp_index.toIndex(), cg.regSetForType(ty)); | | |
| 27743 | try cg.genSetReg(new_reg, ty, val, .{}); | | |
| 27744 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); | | |
| 27745 | try temp.die(cg); | | |
| 27746 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); | | |
| 27747 | temp.* = .{ .index = new_temp_index.toIndex() }; | | |
| 27748 | return true; | | |
| 27749 | } | | |
| 27750 | | | |
| 27751 | fn toRegClass(temp: *Temp, mut: bool, rc: Register.Class, cg: *CodeGen) !bool { | 27833 | fn toRegClass(temp: *Temp, mut: bool, rc: Register.Class, cg: *CodeGen) !bool { |
| 27752 | const val = temp.tracking(cg).short; | 27834 | const val = temp.tracking(cg).short; |
| 27753 | if (!mut or temp.isMut(cg)) switch (val) { | 27835 | if (!mut or temp.isMut(cg)) switch (val) { |
| ... | @@ -27769,7 +27851,7 @@ const Temp = struct { | ... | @@ -27769,7 +27851,7 @@ const Temp = struct { |
| 27769 | | 27851 | |
| 27770 | fn toPair(first_temp: *Temp, second_temp: *Temp, cg: *CodeGen) !void { | 27852 | fn toPair(first_temp: *Temp, second_temp: *Temp, cg: *CodeGen) !void { |
| 27771 | while (true) for ([_]*Temp{ first_temp, second_temp }) |part_temp| { | 27853 | while (true) for ([_]*Temp{ first_temp, second_temp }) |part_temp| { |
| 27772 | if (try part_temp.toAnyReg(cg)) break; | 27854 | if (try part_temp.toRegClass(true, .general_purpose, cg)) break; |
| 27773 | } else break; | 27855 | } else break; |
| 27774 | const first_temp_tracking = first_temp.unwrap(cg).temp.tracking(cg); | 27856 | const first_temp_tracking = first_temp.unwrap(cg).temp.tracking(cg); |
| 27775 | const second_temp_tracking = second_temp.unwrap(cg).temp.tracking(cg); | 27857 | const second_temp_tracking = second_temp.unwrap(cg).temp.tracking(cg); |
| ... | @@ -27824,12 +27906,12 @@ const Temp = struct { | ... | @@ -27824,12 +27906,12 @@ const Temp = struct { |
| 27824 | .load_got, | 27906 | .load_got, |
| 27825 | .load_tlv, | 27907 | .load_tlv, |
| 27826 | .load_frame, | 27908 | .load_frame, |
| 27827 | => return temp.toAnyReg(cg), | 27909 | => return temp.toRegClass(true, .general_purpose, cg), |
| 27828 | .lea_symbol => |sym_off| { | 27910 | .lea_symbol => |sym_off| { |
| 27829 | const off = sym_off.off; | 27911 | const off = sym_off.off; |
| 27830 | if (off == 0) return false; | 27912 | if (off == 0) return false; |
| 27831 | try temp.toOffset(-off, cg); | 27913 | try temp.toOffset(-off, cg); |
| 27832 | while (try temp.toAnyReg(cg)) {} | 27914 | while (try temp.toRegClass(true, .general_purpose, cg)) {} |
| 27833 | try temp.toOffset(off, cg); | 27915 | try temp.toOffset(off, cg); |
| 27834 | return true; | 27916 | return true; |
| 27835 | }, | 27917 | }, |
| ... | @@ -27868,24 +27950,16 @@ const Temp = struct { | ... | @@ -27868,24 +27950,16 @@ const Temp = struct { |
| 27868 | } | 27950 | } |
| 27869 | | 27951 | |
| 27870 | fn load(ptr: *Temp, val_ty: Type, cg: *CodeGen) !Temp { | 27952 | fn load(ptr: *Temp, val_ty: Type, cg: *CodeGen) !Temp { |
| 27871 | const val_abi_size: u32 = @intCast(val_ty.abiSize(cg.pt.zcu)); | | |
| 27872 | const val = try cg.tempAlloc(val_ty); | 27953 | const val = try cg.tempAlloc(val_ty); |
| 27873 | switch (val.tracking(cg).short) { | 27954 | switch (val.tracking(cg).short) { |
| 27874 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), | 27955 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), |
| 27875 | .register => |val_reg| { | 27956 | .register => |val_reg| { |
| 27876 | while (try ptr.toLea(cg)) {} | 27957 | while (try ptr.toLea(cg)) {} |
| 27877 | switch (val_reg.class()) { | 27958 | try cg.genSetReg(val_reg, val_ty, ptr.tracking(cg).short.deref(), .{}); |
| 27878 | .general_purpose => try cg.asmRegisterMemory( | | |
| 27879 | .{ ._, .mov }, | | |
| 27880 | registerAlias(val_reg, val_abi_size), | | |
| 27881 | try ptr.tracking(cg).short.deref().mem(cg, .{ .size = cg.memSize(val_ty) }), | | |
| 27882 | ), | | |
| 27883 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), | | |
| 27884 | } | | |
| 27885 | }, | 27959 | }, |
| 27886 | .load_frame => |val_frame_addr| { | 27960 | .load_frame => |val_frame_addr| { |
| 27887 | var val_ptr = try cg.tempFromValue(.usize, .{ .lea_frame = val_frame_addr }); | 27961 | var val_ptr = try cg.tempFromValue(.usize, .{ .lea_frame = val_frame_addr }); |
| 27888 | var len = try cg.tempFromValue(.usize, .{ .immediate = val_abi_size }); | 27962 | var len = try cg.tempFromValue(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) }); |
| 27889 | try val_ptr.memcpy(ptr, &len, cg); | 27963 | try val_ptr.memcpy(ptr, &len, cg); |
| 27890 | try val_ptr.die(cg); | 27964 | try val_ptr.die(cg); |
| 27891 | try len.die(cg); | 27965 | try len.die(cg); |
| ... | @@ -27908,7 +27982,7 @@ const Temp = struct { | ... | @@ -27908,7 +27982,7 @@ const Temp = struct { |
| 27908 | ); | 27982 | ); |
| 27909 | } else continue :val .{ .register = undefined }, | 27983 | } else continue :val .{ .register = undefined }, |
| 27910 | .register => { | 27984 | .register => { |
| 27911 | while (try ptr.toLea(cg) or try val.toAnyReg(cg)) {} | 27985 | while (try ptr.toLea(cg) or try val.toRegClass(true, .general_purpose, cg)) {} |
| 27912 | const val_reg = val.tracking(cg).short.register; | 27986 | const val_reg = val.tracking(cg).short.register; |
| 27913 | switch (val_reg.class()) { | 27987 | switch (val_reg.class()) { |
| 27914 | .general_purpose => try cg.asmMemoryRegister( | 27988 | .general_purpose => try cg.asmMemoryRegister( |
| ... | @@ -28224,6 +28298,7 @@ const Select = struct { | ... | @@ -28224,6 +28298,7 @@ const Select = struct { |
| 28224 | any_int, | 28298 | any_int, |
| 28225 | any_signed_int, | 28299 | any_signed_int, |
| 28226 | any_float, | 28300 | any_float, |
| | 28301 | po2_any, |
| 28227 | bool_vec: Memory.Size, | 28302 | bool_vec: Memory.Size, |
| 28228 | vec: Memory.Size, | 28303 | vec: Memory.Size, |
| 28229 | signed_int_vec: Memory.Size, | 28304 | signed_int_vec: Memory.Size, |
| ... | @@ -28250,15 +28325,17 @@ const Select = struct { | ... | @@ -28250,15 +28325,17 @@ const Select = struct { |
| 28250 | unsigned_or_exact_remainder_int: struct { of: Memory.Size, is: Memory.Size }, | 28325 | unsigned_or_exact_remainder_int: struct { of: Memory.Size, is: Memory.Size }, |
| 28251 | signed_int: Memory.Size, | 28326 | signed_int: Memory.Size, |
| 28252 | unsigned_int: Memory.Size, | 28327 | unsigned_int: Memory.Size, |
| | 28328 | elem_int: Memory.Size, |
| 28253 | | 28329 | |
| 28254 | fn accepts(constraint: Constraint, ty: Type, cg: *CodeGen) bool { | 28330 | fn accepts(constraint: Constraint, ty: Type, cg: *CodeGen) bool { |
| 28255 | const zcu = cg.pt.zcu; | 28331 | const zcu = cg.pt.zcu; |
| 28256 | switch (constraint) { | 28332 | switch (constraint) { |
| 28257 | .any => return true, | 28333 | .any => return true, |
| 28258 | .any_bool_vec => return ty.isVector(zcu) and ty.scalarType(zcu).toIntern() == .bool_type, | 28334 | .any_bool_vec => return ty.isVector(zcu) and ty.childType(zcu).toIntern() == .bool_type, |
| 28259 | .any_int => return ty.toIntern() == .bool_type or ty.isPtrAtRuntime(zcu) or ty.isAbiInt(zcu), | 28335 | .any_int => return ty.toIntern() == .bool_type or ty.isPtrAtRuntime(zcu) or ty.isAbiInt(zcu), |
| 28260 | .any_signed_int => return ty.isAbiInt(zcu) and ty.intInfo(zcu).signedness == .signed, | 28336 | .any_signed_int => return ty.isAbiInt(zcu) and ty.intInfo(zcu).signedness == .signed, |
| 28261 | .any_float => return ty.scalarType(zcu).isRuntimeFloat(), | 28337 | .any_float => return ty.isRuntimeFloat(), |
| | 28338 | .po2_any => return std.math.isPowerOfTwo(ty.abiSize(zcu)), |
| 28262 | .bool_vec => |size| return ty.isVector(zcu) and ty.scalarType(zcu).toIntern() == .bool_type and | 28339 | .bool_vec => |size| return ty.isVector(zcu) and ty.scalarType(zcu).toIntern() == .bool_type and |
| 28263 | size.bitSize(cg.target) >= ty.vectorLen(zcu), | 28340 | size.bitSize(cg.target) >= ty.vectorLen(zcu), |
| 28264 | .vec => |size| return ty.isVector(zcu) and ty.scalarType(zcu).toIntern() != .bool_type and | 28341 | .vec => |size| return ty.isVector(zcu) and ty.scalarType(zcu).toIntern() != .bool_type and |
| ... | @@ -28434,6 +28511,12 @@ const Select = struct { | ... | @@ -28434,6 +28511,12 @@ const Select = struct { |
| 28434 | const int_info = ty.intInfo(zcu); | 28511 | const int_info = ty.intInfo(zcu); |
| 28435 | return int_info.signedness == .unsigned and size.bitSize(cg.target) >= int_info.bits; | 28512 | return int_info.signedness == .unsigned and size.bitSize(cg.target) >= int_info.bits; |
| 28436 | }, | 28513 | }, |
| | 28514 | .elem_int => |size| { |
| | 28515 | const elem_ty = ty.childType(zcu); |
| | 28516 | if (elem_ty.toIntern() == .bool_type) return true; |
| | 28517 | if (elem_ty.isPtrAtRuntime(zcu)) return size.bitSize(cg.target) >= cg.target.ptrBitWidth(); |
| | 28518 | return elem_ty.isAbiInt(zcu) and size.bitSize(cg.target) >= elem_ty.intInfo(zcu).bits; |
| | 28519 | }, |
| 28437 | } | 28520 | } |
| 28438 | } | 28521 | } |
| 28439 | }; | 28522 | }; |
| ... | @@ -29107,7 +29190,14 @@ const Select = struct { | ... | @@ -29107,7 +29190,14 @@ const Select = struct { |
| 29107 | const UnsignedImm = @Type(.{ | 29190 | const UnsignedImm = @Type(.{ |
| 29108 | .int = .{ .signedness = .unsigned, .bits = @typeInfo(SignedImm).int.bits }, | 29191 | .int = .{ .signedness = .unsigned, .bits = @typeInfo(SignedImm).int.bits }, |
| 29109 | }); | 29192 | }); |
| 29110 | return op.imm + @as(i5, op.adjust.factor) * op.adjust.scale.toFactor() * @as(SignedImm, switch (op.adjust.amount) { | 29193 | return switch (op.index.ref) { |
| | 29194 | else => |ref| switch (ref.deref(s).tracking(s.cg).short) { |
| | 29195 | else => unreachable, |
| | 29196 | .immediate => |imm| op.index.scale.toFactor() * @as(i32, @intCast(imm)), |
| | 29197 | .register => 0, |
| | 29198 | }, |
| | 29199 | .none => 0, |
| | 29200 | } + @as(i5, op.adjust.factor) * op.adjust.scale.toFactor() * @as(SignedImm, switch (op.adjust.amount) { |
| 29111 | .none => 0, | 29201 | .none => 0, |
| 29112 | .ptr_size => @divExact(s.cg.target.ptrBitWidth(), 8), | 29202 | .ptr_size => @divExact(s.cg.target.ptrBitWidth(), 8), |
| 29113 | .ptr_bit_size => s.cg.target.ptrBitWidth(), | 29203 | .ptr_bit_size => s.cg.target.ptrBitWidth(), |
| ... | @@ -29120,7 +29210,7 @@ const Select = struct { | ... | @@ -29120,7 +29210,7 @@ const Select = struct { |
| 29120 | op.base.ref.deref(s).typeOf(s.cg).scalarType(s.cg.pt.zcu).abiSize(s.cg.pt.zcu), | 29210 | op.base.ref.deref(s).typeOf(s.cg).scalarType(s.cg.pt.zcu).abiSize(s.cg.pt.zcu), |
| 29121 | @divExact(op.base.size.bitSize(s.cg.target), 8), | 29211 | @divExact(op.base.size.bitSize(s.cg.target), 8), |
| 29122 | )), | 29212 | )), |
| 29123 | .src0_elem_size => @intCast(Select.Operand.Ref.src0.deref(s).typeOf(s.cg).scalarType(s.cg.pt.zcu).abiSize(s.cg.pt.zcu)), | 29213 | .src0_elem_size => @intCast(Select.Operand.Ref.src0.deref(s).typeOf(s.cg).childType(s.cg.pt.zcu).abiSize(s.cg.pt.zcu)), |
| 29124 | .smin => @as(SignedImm, std.math.minInt(SignedImm)) >> @truncate( | 29214 | .smin => @as(SignedImm, std.math.minInt(SignedImm)) >> @truncate( |
| 29125 | -%op.base.ref.deref(s).typeOf(s.cg).scalarType(s.cg.pt.zcu).bitSize(s.cg.pt.zcu), | 29215 | -%op.base.ref.deref(s).typeOf(s.cg).scalarType(s.cg.pt.zcu).bitSize(s.cg.pt.zcu), |
| 29126 | ), | 29216 | ), |
| ... | @@ -29130,7 +29220,7 @@ const Select = struct { | ... | @@ -29130,7 +29220,7 @@ const Select = struct { |
| 29130 | .umax => @bitCast(@as(UnsignedImm, std.math.maxInt(UnsignedImm)) >> @truncate( | 29220 | .umax => @bitCast(@as(UnsignedImm, std.math.maxInt(UnsignedImm)) >> @truncate( |
| 29131 | -%op.base.ref.deref(s).typeOf(s.cg).scalarType(s.cg.pt.zcu).bitSize(s.cg.pt.zcu), | 29221 | -%op.base.ref.deref(s).typeOf(s.cg).scalarType(s.cg.pt.zcu).bitSize(s.cg.pt.zcu), |
| 29132 | )), | 29222 | )), |
| 29133 | }); | 29223 | }) + op.imm; |
| 29134 | } | 29224 | } |
| 29135 | | 29225 | |
| 29136 | fn lower(op: Select.Operand, s: *Select) !CodeGen.Operand { | 29226 | fn lower(op: Select.Operand, s: *Select) !CodeGen.Operand { |
| ... | @@ -29160,7 +29250,11 @@ const Select = struct { | ... | @@ -29160,7 +29250,11 @@ const Select = struct { |
| 29160 | .mod = .{ .rm = .{ | 29250 | .mod = .{ .rm = .{ |
| 29161 | .size = op.base.size, | 29251 | .size = op.base.size, |
| 29162 | .index = switch (op.index.ref) { | 29252 | .index = switch (op.index.ref) { |
| 29163 | else => |ref| registerAlias(ref.deref(s).tracking(s.cg).short.register, @divExact(s.cg.target.ptrBitWidth(), 8)), | 29253 | else => |ref| switch (ref.deref(s).tracking(s.cg).short) { |
| | 29254 | else => unreachable, |
| | 29255 | .immediate => .none, |
| | 29256 | .register => |index_reg| registerAlias(index_reg, @divExact(s.cg.target.ptrBitWidth(), 8)), |
| | 29257 | }, |
| 29164 | .none => .none, | 29258 | .none => .none, |
| 29165 | }, | 29259 | }, |
| 29166 | .scale = op.index.scale, | 29260 | .scale = op.index.scale, |
| ... | @@ -29170,7 +29264,11 @@ const Select = struct { | ... | @@ -29170,7 +29264,11 @@ const Select = struct { |
| 29170 | .mem => .{ .mem = try op.base.ref.deref(s).tracking(s.cg).short.mem(s.cg, .{ | 29264 | .mem => .{ .mem = try op.base.ref.deref(s).tracking(s.cg).short.mem(s.cg, .{ |
| 29171 | .size = op.base.size, | 29265 | .size = op.base.size, |
| 29172 | .index = switch (op.index.ref) { | 29266 | .index = switch (op.index.ref) { |
| 29173 | else => |ref| registerAlias(ref.deref(s).tracking(s.cg).short.register, @divExact(s.cg.target.ptrBitWidth(), 8)), | 29267 | else => |ref| switch (ref.deref(s).tracking(s.cg).short) { |
| | 29268 | else => unreachable, |
| | 29269 | .immediate => .none, |
| | 29270 | .register => |index_reg| registerAlias(index_reg, @divExact(s.cg.target.ptrBitWidth(), 8)), |
| | 29271 | }, |
| 29174 | .none => .none, | 29272 | .none => .none, |
| 29175 | }, | 29273 | }, |
| 29176 | .scale = op.index.scale, | 29274 | .scale = op.index.scale, |