@@ -573,17 +573,21 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
573
573
// sub sp, sp, #reloc
574
574
mem .writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .push (.al , .{ .fp , .lr }).toU32 ());
575
575
mem .writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .mov (.al , .fp , Instruction .Operand .reg (.sp , Instruction .Operand .Shift .none )).toU32 ());
576
- // TODO: prepare stack for local variables
577
- // const backpatch_reloc = try self.code.addManyAsArray( 4);
576
+ const backpatch_reloc = self . code . items . len ;
577
+ try self .code .resize ( backpatch_reloc + 4 );
578
578
579
579
try self .dbgSetPrologueEnd ();
580
580
581
581
try self .genBody (self .mod_fn .analysis .success );
582
582
583
583
// Backpatch stack offset
584
- // const stack_end = self.max_end_stack;
585
- // const aligned_stack_end = mem.alignForward(stack_end, self.stack_align);
586
- // mem.writeIntLittle(u32, backpatch_reloc, Instruction.sub(.al, .sp, .sp, Instruction.Operand.imm()));
584
+ const stack_end = self .max_end_stack ;
585
+ const aligned_stack_end = mem .alignForward (stack_end , self .stack_align );
586
+ if (Instruction .Operand .fromU32 (@intCast (u32 , aligned_stack_end ))) | op | {
587
+ mem .writeIntLittle (u32 , self .code .items [backpatch_reloc .. ][0.. 4], Instruction .sub (.al , .sp , .sp , op ).toU32 ());
588
+ } else {
589
+ return self .fail (self .src , "TODO ARM: allow larger stacks" , .{});
590
+ }
587
591
588
592
try self .dbgSetEpilogueBegin ();
589
593
@@ -2196,6 +2200,58 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2196
2200
2197
2201
fn genSetStack (self : * Self , src : usize , ty : Type , stack_offset : u32 , mcv : MCValue ) InnerError ! void {
2198
2202
switch (arch ) {
2203
+ .arm = > switch (mcv ) {
2204
+ .dead = > unreachable ,
2205
+ .ptr_stack_offset = > unreachable ,
2206
+ .ptr_embedded_in_code = > unreachable ,
2207
+ .unreach , .none = > return , // Nothing to do.
2208
+ .undef = > {
2209
+ if (! self .wantSafety ())
2210
+ return ; // The already existing value will do just fine.
2211
+ // TODO Upgrade this to a memset call when we have that available.
2212
+ switch (ty .abiSize (self .target .* )) {
2213
+ 1 = > return self .genSetStack (src , ty , stack_offset , .{ .immediate = 0xaa }),
2214
+ 2 = > return self .genSetStack (src , ty , stack_offset , .{ .immediate = 0xaaaa }),
2215
+ 4 = > return self .genSetStack (src , ty , stack_offset , .{ .immediate = 0xaaaaaaaa }),
2216
+ 8 = > return self .genSetStack (src , ty , stack_offset , .{ .immediate = 0xaaaaaaaaaaaaaaaa }),
2217
+ else = > return self .fail (src , "TODO implement memset" , .{}),
2218
+ }
2219
+ },
2220
+ .compare_flags_unsigned = > | op | {
2221
+ return self .fail (src , "TODO implement set stack variable with compare flags value (unsigned)" , .{});
2222
+ },
2223
+ .compare_flags_signed = > | op | {
2224
+ return self .fail (src , "TODO implement set stack variable with compare flags value (signed)" , .{});
2225
+ },
2226
+ .immediate = > {
2227
+ const reg = try self .copyToTmpRegister (src , mcv );
2228
+ return self .genSetStack (src , ty , stack_offset , MCValue { .register = reg });
2229
+ },
2230
+ .embedded_in_code = > | code_offset | {
2231
+ return self .fail (src , "TODO implement set stack variable from embedded_in_code" , .{});
2232
+ },
2233
+ .register = > | reg | {
2234
+ // TODO: strb, strh
2235
+ if (stack_offset <= math .maxInt (u12 )) {
2236
+ mem .writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .str (.al , reg , .fp , .{
2237
+ .offset = Instruction .Offset .imm (@intCast (u12 , stack_offset )),
2238
+ .positive = false ,
2239
+ }).toU32 ());
2240
+ } else {
2241
+ return self .fail (src , "TODO genSetStack with larger offsets" , .{});
2242
+ }
2243
+ },
2244
+ .memory = > | vaddr | {
2245
+ return self .fail (src , "TODO implement set stack variable from memory vaddr" , .{});
2246
+ },
2247
+ .stack_offset = > | off | {
2248
+ if (stack_offset == off )
2249
+ return ; // Copy stack variable to itself; nothing to do.
2250
+
2251
+ const reg = try self .copyToTmpRegister (src , mcv );
2252
+ return self .genSetStack (src , ty , stack_offset , MCValue { .register = reg });
2253
+ },
2254
+ },
2199
2255
.x86_64 = > switch (mcv ) {
2200
2256
.dead = > unreachable ,
2201
2257
.ptr_stack_offset = > unreachable ,
@@ -2352,6 +2408,18 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2352
2408
try self .genSetReg (src , reg , .{ .immediate = addr });
2353
2409
mem .writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .ldr (.al , reg , reg , .{ .offset = Instruction .Offset .none }).toU32 ());
2354
2410
},
2411
+ .stack_offset = > | unadjusted_off | {
2412
+ // TODO: ldrb, ldrh
2413
+ // TODO: maybe addressing from sp instead of fp
2414
+ if (unadjusted_off <= math .maxInt (u12 )) {
2415
+ mem .writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .ldr (.al , reg , .fp , .{
2416
+ .offset = Instruction .Offset .imm (@intCast (u12 , unadjusted_off )),
2417
+ .positive = false ,
2418
+ }).toU32 ());
2419
+ } else {
2420
+ return self .fail (src , "TODO genSetReg with larger stack offset" , .{});
2421
+ }
2422
+ },
2355
2423
else = > return self .fail (src , "TODO implement getSetReg for arm {}" , .{mcv }),
2356
2424
},
2357
2425
.riscv64 = > switch (mcv ) {
0 commit comments