@@ -6693,8 +6693,8 @@ pub fn layout(
6693
6693
wip_mir_log.debug("{f}<body>:\n", .{nav.fqn.fmt(ip)});
6694
6694
6695
6695
const stack_size: u24 = @intCast(InternPool.Alignment.@"16".forward(isel.stack_size));
6696
- const stack_size_low : u12 = @truncate(stack_size >> 0);
6697
- const stack_size_high : u12 = @truncate(stack_size >> 12);
6696
+ const stack_size_lo : u12 = @truncate(stack_size >> 0);
6697
+ const stack_size_hi : u12 = @truncate(stack_size >> 12);
6698
6698
6699
6699
var saves_buf: [10 + 8 + 8 + 2 + 8]struct {
6700
6700
class: enum { integer, vector },
@@ -6881,28 +6881,53 @@ pub fn layout(
6881
6881
}
6882
6882
}
6883
6883
6884
+ try isel.emit(.add(.fp, .sp, .{ .immediate = frame_record_offset }));
6884
6885
const scratch_reg: Register = if (isel.stack_align == .@"16")
6885
6886
.sp
6886
- else if (stack_size == 0)
6887
+ else if (stack_size == 0 and frame_record_offset == 0 )
6887
6888
.fp
6888
6889
else
6889
- .x9;
6890
- try isel.emit(.add(.fp, .sp, .{ .immediate = frame_record_offset }));
6891
- if (stack_size_high > 0) try isel.emit(.sub(scratch_reg, .sp, .{
6892
- .shifted_immediate = .{ .immediate = stack_size_high, .lsl = .@"12" },
6893
- }));
6894
- if (stack_size_low > 0) try isel.emit(.sub(
6895
- scratch_reg,
6896
- if (stack_size_high > 0) scratch_reg else .sp,
6897
- .{ .immediate = stack_size_low },
6898
- ));
6899
- if (isel.stack_align != .@"16") {
6900
- try isel.emit(.@"and"(.sp, scratch_reg, .{ .immediate = .{
6901
- .N = .doubleword,
6902
- .immr = -%isel.stack_align.toLog2Units(),
6903
- .imms = ~isel.stack_align.toLog2Units(),
6904
- } }));
6890
+ .ip0;
6891
+ if (mod.stack_check) {
6892
+ if (stack_size_hi > 2) {
6893
+ try isel.movImmediate(.ip1, stack_size_hi);
6894
+ const loop_label = isel.instructions.items.len;
6895
+ try isel.emit(.sub(.sp, .sp, .{
6896
+ .shifted_immediate = .{ .immediate = 1, .lsl = .@"12" },
6897
+ }));
6898
+ try isel.emit(.sub(.ip1, .ip1, .{ .immediate = 1 }));
6899
+ try isel.emit(.ldr(.xzr, .{ .base = .sp }));
6900
+ try isel.emit(.cbnz(.ip1, -@as(i21, @intCast(
6901
+ (isel.instructions.items.len - loop_label) << 2,
6902
+ ))));
6903
+ } else for (0..stack_size_hi) |_| {
6904
+ try isel.emit(.sub(.sp, .sp, .{
6905
+ .shifted_immediate = .{ .immediate = 1, .lsl = .@"12" },
6906
+ }));
6907
+ try isel.emit(.ldr(.xzr, .{ .base = .sp }));
6908
+ }
6909
+ if (stack_size_lo > 0) try isel.emit(.sub(
6910
+ scratch_reg,
6911
+ .sp,
6912
+ .{ .immediate = stack_size_lo },
6913
+ )) else if (scratch_reg.alias == Register.Alias.ip0)
6914
+ try isel.emit(.add(scratch_reg, .sp, .{ .immediate = 0 }));
6915
+ } else {
6916
+ if (stack_size_hi > 0) try isel.emit(.sub(scratch_reg, .sp, .{
6917
+ .shifted_immediate = .{ .immediate = stack_size_hi, .lsl = .@"12" },
6918
+ }));
6919
+ if (stack_size_lo > 0) try isel.emit(.sub(
6920
+ scratch_reg,
6921
+ if (stack_size_hi > 0) scratch_reg else .sp,
6922
+ .{ .immediate = stack_size_lo },
6923
+ )) else if (scratch_reg.alias == Register.Alias.ip0 and stack_size_hi == 0)
6924
+ try isel.emit(.add(scratch_reg, .sp, .{ .immediate = 0 }));
6905
6925
}
6926
+ if (isel.stack_align != .@"16") try isel.emit(.@"and"(.sp, scratch_reg, .{ .immediate = .{
6927
+ .N = .doubleword,
6928
+ .immr = -%isel.stack_align.toLog2Units(),
6929
+ .imms = ~isel.stack_align.toLog2Units(),
6930
+ } }));
6906
6931
wip_mir_log.debug("", .{});
6907
6932
}
6908
6933
@@ -6947,17 +6972,17 @@ pub fn layout(
6947
6972
save_index += 1;
6948
6973
} else save_index += 1;
6949
6974
}
6950
- if (isel.stack_align != .@"16" or (stack_size_low > 0 and stack_size_high > 0)) {
6975
+ if (isel.stack_align != .@"16" or (stack_size_lo > 0 and stack_size_hi > 0)) {
6951
6976
try isel.emit(switch (frame_record_offset) {
6952
6977
0 => .add(.sp, .fp, .{ .immediate = 0 }),
6953
6978
else => |offset| .sub(.sp, .fp, .{ .immediate = offset }),
6954
6979
});
6955
6980
} else {
6956
- if (stack_size_high > 0) try isel.emit(.add(.sp, .sp, .{
6957
- .shifted_immediate = .{ .immediate = stack_size_high , .lsl = .@"12" },
6981
+ if (stack_size_hi > 0) try isel.emit(.add(.sp, .sp, .{
6982
+ .shifted_immediate = .{ .immediate = stack_size_hi , .lsl = .@"12" },
6958
6983
}));
6959
- if (stack_size_low > 0) try isel.emit(.add(.sp, .sp, .{
6960
- .immediate = stack_size_low ,
6984
+ if (stack_size_lo > 0) try isel.emit(.add(.sp, .sp, .{
6985
+ .immediate = stack_size_lo ,
6961
6986
}));
6962
6987
}
6963
6988
wip_mir_log.debug("{f}<epilogue>:\n", .{nav.fqn.fmt(ip)});
0 commit comments