@@ -433,7 +433,7 @@ pub fn generate(
433433 .prev_di_pc = 0 ,
434434 .prev_di_line = module_fn .lbrace_line ,
435435 .prev_di_column = module_fn .lbrace_column ,
436- .stack_size = mem . alignForwardGeneric ( u32 , function .max_end_stack , function . stack_align ) ,
436+ .stack_size = function .max_end_stack ,
437437 .saved_regs_stack_space = function .saved_regs_stack_space ,
438438 };
439439 defer emit .deinit ();
@@ -560,6 +560,7 @@ fn gen(self: *Self) !void {
560560 const total_stack_size = self .max_end_stack + self .saved_regs_stack_space ;
561561 const aligned_total_stack_end = mem .alignForwardGeneric (u32 , total_stack_size , self .stack_align );
562562 const stack_size = aligned_total_stack_end - self .saved_regs_stack_space ;
563+ self .max_end_stack = stack_size ;
563564 if (math .cast (u12 , stack_size )) | size | {
564565 self .mir_instructions .set (backpatch_reloc , .{
565566 .tag = .sub_immediate ,
@@ -982,11 +983,16 @@ fn allocMem(
982983 assert (abi_size > 0 );
983984 assert (abi_align > 0 );
984985
985- if (abi_align > self .stack_align )
986- self .stack_align = abi_align ;
986+ // In order to efficiently load and store stack items that fit
987+ // into registers, we bump up the alignment to the next power of
988+ // two.
989+ const adjusted_align = if (abi_size > 8 )
990+ abi_align
991+ else
992+ std .math .ceilPowerOfTwoAssert (u32 , abi_size );
987993
988994 // TODO find a free slot instead of always appending
989- const offset = mem .alignForwardGeneric (u32 , self .next_stack_offset , abi_align ) + abi_size ;
995+ const offset = mem .alignForwardGeneric (u32 , self .next_stack_offset , adjusted_align ) + abi_size ;
990996 self .next_stack_offset = offset ;
991997 self .max_end_stack = @max (self .max_end_stack , self .next_stack_offset );
992998
@@ -5396,15 +5402,15 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void {
53965402}
53975403
53985404fn genSetStack (self : * Self , ty : Type , stack_offset : u32 , mcv : MCValue ) InnerError ! void {
5399- const abi_size = ty .abiSize (self .target .* );
5405+ const abi_size = @intCast ( u32 , ty .abiSize (self .target .* ) );
54005406 switch (mcv ) {
54015407 .dead = > unreachable ,
54025408 .unreach , .none = > return , // Nothing to do.
54035409 .undef = > {
54045410 if (! self .wantSafety ())
54055411 return ; // The already existing value will do just fine.
54065412 // TODO Upgrade this to a memset call when we have that available.
5407- switch (ty . abiSize ( self . target .* ) ) {
5413+ switch (abi_size ) {
54085414 1 = > return self .genSetStack (ty , stack_offset , .{ .immediate = 0xaa }),
54095415 2 = > return self .genSetStack (ty , stack_offset , .{ .immediate = 0xaaaa }),
54105416 4 = > return self .genSetStack (ty , stack_offset , .{ .immediate = 0xaaaaaaaa }),
@@ -5426,6 +5432,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
54265432 .register = > | reg | {
54275433 switch (abi_size ) {
54285434 1 , 2 , 4 , 8 = > {
5435+ assert (std .mem .isAlignedGeneric (u32 , stack_offset , abi_size ));
5436+
54295437 const tag : Mir.Inst.Tag = switch (abi_size ) {
54305438 1 = > .strb_stack ,
54315439 2 = > .strh_stack ,
@@ -5438,7 +5446,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
54385446 .tag = tag ,
54395447 .data = .{ .load_store_stack = .{
54405448 .rt = rt ,
5441- .offset = @intCast ( u32 , stack_offset ) ,
5449+ .offset = stack_offset ,
54425450 } },
54435451 });
54445452 },
@@ -6001,9 +6009,10 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void {
60016009}
60026010
60036011fn airShuffle (self : * Self , inst : Air.Inst.Index ) ! void {
6004- const ty_op = self .air .instructions .items (.data )[inst ].ty_op ;
6012+ const ty_pl = self .air .instructions .items (.data )[inst ].ty_pl ;
6013+ const extra = self .air .extraData (Air .Shuffle , ty_pl .payload ).data ;
60056014 const result : MCValue = if (self .liveness .isUnused (inst )) .dead else return self .fail ("TODO implement airShuffle for {}" , .{self .target .cpu .arch });
6006- return self .finishAir (inst , result , .{ ty_op . operand , .none , .none });
6015+ return self .finishAir (inst , result , .{ extra . a , extra . b , .none });
60076016}
60086017
60096018fn airReduce (self : * Self , inst : Air.Inst.Index ) ! void {
0 commit comments