@@ -236,6 +236,11 @@ const InnerError = error{
236236};
237237
238238fn Function (comptime arch : std.Target.Cpu.Arch ) type {
239+ const writeInt = switch (arch .endian ()) {
240+ .Little = > mem .writeIntLittle ,
241+ .Big = > mem .writeIntBig ,
242+ };
243+
239244 return struct {
240245 gpa : * Allocator ,
241246 bin_file : * link.File ,
@@ -565,14 +570,14 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
565570 try self .dbgSetEpilogueBegin ();
566571 }
567572 },
568- .arm = > {
573+ .arm , .armeb = > {
569574 const cc = self .fn_type .fnCallingConvention ();
570575 if (cc != .Naked ) {
571576 // push {fp, lr}
572577 // mov fp, sp
573578 // sub sp, sp, #reloc
574- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .push (.al , .{ .fp , .lr }).toU32 ());
575- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .mov (.al , .fp , Instruction .Operand .reg (.sp , Instruction .Operand .Shift .none )).toU32 ());
579+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .push (.al , .{ .fp , .lr }).toU32 ());
580+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .mov (.al , .fp , Instruction .Operand .reg (.sp , Instruction .Operand .Shift .none )).toU32 ());
576581 const backpatch_reloc = self .code .items .len ;
577582 try self .code .resize (backpatch_reloc + 4 );
578583
@@ -584,7 +589,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
584589 const stack_end = self .max_end_stack ;
585590 const aligned_stack_end = mem .alignForward (stack_end , self .stack_align );
586591 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 ());
592+ writeInt (u32 , self .code .items [backpatch_reloc .. ][0.. 4], Instruction .sub (.al , .sp , .sp , op ).toU32 ());
588593 } else {
589594 return self .fail (self .src , "TODO ARM: allow larger stacks" , .{});
590595 }
@@ -607,10 +612,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
607612 // the space because there may be
608613 // other jumps we already relocated to
609614 // the address. Instead, insert a nop
610- mem . writeIntLittle (u32 , self .code .items [jmp_reloc .. ][0.. 4], Instruction .nop ().toU32 ());
615+ writeInt (u32 , self .code .items [jmp_reloc .. ][0.. 4], Instruction .nop ().toU32 ());
611616 } else {
612617 if (math .cast (i26 , amt )) | offset | {
613- mem . writeIntLittle (u32 , self .code .items [jmp_reloc .. ][0.. 4], Instruction .b (.al , offset ).toU32 ());
618+ writeInt (u32 , self .code .items [jmp_reloc .. ][0.. 4], Instruction .b (.al , offset ).toU32 ());
614619 } else | err | {
615620 return self .fail (self .src , "exitlude jump is too large" , .{});
616621 }
@@ -619,8 +624,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
619624
620625 // mov sp, fp
621626 // pop {fp, pc}
622- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .mov (.al , .sp , Instruction .Operand .reg (.fp , Instruction .Operand .Shift .none )).toU32 ());
623- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .pop (.al , .{ .fp , .pc }).toU32 ());
627+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .mov (.al , .sp , Instruction .Operand .reg (.fp , Instruction .Operand .Shift .none )).toU32 ());
628+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .pop (.al , .{ .fp , .pc }).toU32 ());
624629 } else {
625630 try self .dbgSetPrologueEnd ();
626631 try self .genBody (self .mod_fn .analysis .success );
@@ -1372,11 +1377,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
13721377 var instr = Instruction { .condition = .always , .input0 = .zero , .input1 = .zero , .modify_flags = false , .output = .discard , .command = .undefined1 };
13731378 mem .writeIntLittle (u16 , self .code .items [self .code .items .len - 2 .. ][0.. 2], @bitCast (u16 , instr ));
13741379 },
1375- .arm = > {
1376- mem .writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .bkpt (0 ).toU32 ());
1377- },
1378- .armeb = > {
1379- mem .writeIntBig (u32 , try self .code .addManyAsArray (4 ), Instruction .bkpt (0 ).toU32 ());
1380+ .arm , .armeb = > {
1381+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .bkpt (0 ).toU32 ());
13801382 },
13811383 else = > return self .fail (src , "TODO implement @breakpoint() for {}" , .{self .target .cpu .arch }),
13821384 }
@@ -1520,7 +1522,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
15201522 return self .fail (inst .base .src , "TODO implement calling runtime known function pointer" , .{});
15211523 }
15221524 },
1523- .arm = > {
1525+ .arm , .armeb = > {
15241526 for (info .args ) | mc_arg , arg_i | {
15251527 const arg = inst .args [arg_i ];
15261528 const arg_mcv = try self .resolveInst (inst .args [arg_i ]);
@@ -1569,10 +1571,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
15691571 // TODO: add Instruction.supportedOn
15701572 // function for ARM
15711573 if (Target .arm .featureSetHas (self .target .cpu .features , .has_v5t )) {
1572- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .blx (.al , .lr ).toU32 ());
1574+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .blx (.al , .lr ).toU32 ());
15731575 } else {
1574- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .mov (.al , .lr , Instruction .Operand .reg (.pc , Instruction .Operand .Shift .none )).toU32 ());
1575- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .bx (.al , .lr ).toU32 ());
1576+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .mov (.al , .lr , Instruction .Operand .reg (.pc , Instruction .Operand .Shift .none )).toU32 ());
1577+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .bx (.al , .lr ).toU32 ());
15761578 }
15771579 } else {
15781580 return self .fail (inst .base .src , "TODO implement calling bitcasted functions" , .{});
@@ -1692,7 +1694,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
16921694 .riscv64 = > {
16931695 mem .writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .jalr (.zero , 0 , .ra ).toU32 ());
16941696 },
1695- .arm = > {
1697+ .arm , .armeb = > {
16961698 // Just add space for an instruction, patch this later
16971699 try self .code .resize (self .code .items .len + 4 );
16981700 try self .exitlude_jump_relocs .append (self .gpa , self .code .items .len - 4 );
@@ -1961,9 +1963,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
19611963 mem .writeIntLittle (i32 , self .code .addManyAsArrayAssumeCapacity (4 ), delta );
19621964 }
19631965 },
1964- .arm = > {
1966+ .arm , .armeb = > {
19651967 if (math .cast (i26 , @intCast (i32 , index ) - @intCast (i32 , self .code .items .len ))) | delta | {
1966- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .b (.al , delta ).toU32 ());
1968+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .b (.al , delta ).toU32 ());
19671969 } else | err | {
19681970 return self .fail (src , "TODO: enable larger branch offset" , .{});
19691971 }
@@ -2082,7 +2084,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
20822084 return self .fail (inst .base .src , "TODO implement support for more SPU II assembly instructions" , .{});
20832085 }
20842086 },
2085- .arm = > {
2087+ .arm , .armeb = > {
20862088 for (inst .inputs ) | input , i | {
20872089 if (input .len < 3 or input [0 ] != '{' or input [input .len - 1 ] != '}' ) {
20882090 return self .fail (inst .base .src , "unrecognized asm input constraint: '{}'" , .{input });
@@ -2095,7 +2097,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
20952097 }
20962098
20972099 if (mem .eql (u8 , inst .asm_source , "svc #0" )) {
2098- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .svc (.al , 0 ).toU32 ());
2100+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .svc (.al , 0 ).toU32 ());
20992101 } else {
21002102 return self .fail (inst .base .src , "TODO implement support for more arm assembly instructions" , .{});
21012103 }
@@ -2224,7 +2226,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
22242226
22252227 fn genSetStack (self : * Self , src : usize , ty : Type , stack_offset : u32 , mcv : MCValue ) InnerError ! void {
22262228 switch (arch ) {
2227- .arm = > switch (mcv ) {
2229+ .arm , .armeb = > switch (mcv ) {
22282230 .dead = > unreachable ,
22292231 .ptr_stack_offset = > unreachable ,
22302232 .ptr_embedded_in_code = > unreachable ,
@@ -2257,7 +2259,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
22572259 .register = > | reg | {
22582260 // TODO: strb, strh
22592261 if (stack_offset <= math .maxInt (u12 )) {
2260- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .str (.al , reg , .fp , .{
2262+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .str (.al , reg , .fp , .{
22612263 .offset = Instruction .Offset .imm (@intCast (u12 , stack_offset )),
22622264 .positive = false ,
22632265 }).toU32 ());
@@ -2371,7 +2373,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
23712373
23722374 fn genSetReg (self : * Self , src : usize , reg : Register , mcv : MCValue ) InnerError ! void {
23732375 switch (arch ) {
2374- .arm = > switch (mcv ) {
2376+ .arm , .armeb = > switch (mcv ) {
23752377 .dead = > unreachable ,
23762378 .ptr_stack_offset = > unreachable ,
23772379 .ptr_embedded_in_code = > unreachable ,
@@ -2386,15 +2388,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
23862388 if (x > math .maxInt (u32 )) return self .fail (src , "ARM registers are 32-bit wide" , .{});
23872389
23882390 if (Instruction .Operand .fromU32 (@intCast (u32 , x ))) | op | {
2389- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .mov (.al , reg , op ).toU32 ());
2391+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .mov (.al , reg , op ).toU32 ());
23902392 } else if (Instruction .Operand .fromU32 (~ @intCast (u32 , x ))) | op | {
2391- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .mvn (.al , reg , op ).toU32 ());
2393+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .mvn (.al , reg , op ).toU32 ());
23922394 } else if (x <= math .maxInt (u16 )) {
23932395 if (Target .arm .featureSetHas (self .target .cpu .features , .has_v7 )) {
2394- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .movw (.al , reg , @intCast (u16 , x )).toU32 ());
2396+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .movw (.al , reg , @intCast (u16 , x )).toU32 ());
23952397 } else {
2396- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .mov (.al , reg , Instruction .Operand .imm (@truncate (u8 , x ), 0 )).toU32 ());
2397- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .orr (.al , reg , reg , Instruction .Operand .imm (@truncate (u8 , x >> 8 ), 12 )).toU32 ());
2398+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .mov (.al , reg , Instruction .Operand .imm (@truncate (u8 , x ), 0 )).toU32 ());
2399+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .orr (.al , reg , reg , Instruction .Operand .imm (@truncate (u8 , x >> 8 ), 12 )).toU32 ());
23982400 }
23992401 } else {
24002402 // TODO write constant to code and load
@@ -2403,18 +2405,18 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
24032405 // immediate: 0xaaaabbbb
24042406 // movw reg, #0xbbbb
24052407 // movt reg, #0xaaaa
2406- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .movw (.al , reg , @truncate (u16 , x )).toU32 ());
2407- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .movt (.al , reg , @truncate (u16 , x >> 16 )).toU32 ());
2408+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .movw (.al , reg , @truncate (u16 , x )).toU32 ());
2409+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .movt (.al , reg , @truncate (u16 , x >> 16 )).toU32 ());
24082410 } else {
24092411 // immediate: 0xaabbccdd
24102412 // mov reg, #0xaa
24112413 // orr reg, reg, #0xbb, 24
24122414 // orr reg, reg, #0xcc, 16
24132415 // orr reg, reg, #0xdd, 8
2414- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .mov (.al , reg , Instruction .Operand .imm (@truncate (u8 , x ), 0 )).toU32 ());
2415- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .orr (.al , reg , reg , Instruction .Operand .imm (@truncate (u8 , x >> 8 ), 12 )).toU32 ());
2416- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .orr (.al , reg , reg , Instruction .Operand .imm (@truncate (u8 , x >> 16 ), 8 )).toU32 ());
2417- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .orr (.al , reg , reg , Instruction .Operand .imm (@truncate (u8 , x >> 24 ), 4 )).toU32 ());
2416+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .mov (.al , reg , Instruction .Operand .imm (@truncate (u8 , x ), 0 )).toU32 ());
2417+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .orr (.al , reg , reg , Instruction .Operand .imm (@truncate (u8 , x >> 8 ), 12 )).toU32 ());
2418+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .orr (.al , reg , reg , Instruction .Operand .imm (@truncate (u8 , x >> 16 ), 8 )).toU32 ());
2419+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .orr (.al , reg , reg , Instruction .Operand .imm (@truncate (u8 , x >> 24 ), 4 )).toU32 ());
24182420 }
24192421 }
24202422 },
@@ -2424,19 +2426,19 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
24242426 return ;
24252427
24262428 // mov reg, src_reg
2427- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .mov (.al , reg , Instruction .Operand .reg (src_reg , Instruction .Operand .Shift .none )).toU32 ());
2429+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .mov (.al , reg , Instruction .Operand .reg (src_reg , Instruction .Operand .Shift .none )).toU32 ());
24282430 },
24292431 .memory = > | addr | {
24302432 // The value is in memory at a hard-coded address.
24312433 // If the type is a pointer, it means the pointer address is at this memory location.
24322434 try self .genSetReg (src , reg , .{ .immediate = addr });
2433- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .ldr (.al , reg , reg , .{ .offset = Instruction .Offset .none }).toU32 ());
2435+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .ldr (.al , reg , reg , .{ .offset = Instruction .Offset .none }).toU32 ());
24342436 },
24352437 .stack_offset = > | unadjusted_off | {
24362438 // TODO: ldrb, ldrh
24372439 // TODO: maybe addressing from sp instead of fp
24382440 if (unadjusted_off <= math .maxInt (u12 )) {
2439- mem . writeIntLittle (u32 , try self .code .addManyAsArray (4 ), Instruction .ldr (.al , reg , .fp , .{
2441+ writeInt (u32 , try self .code .addManyAsArray (4 ), Instruction .ldr (.al , reg , .fp , .{
24402442 .offset = Instruction .Offset .imm (@intCast (u12 , unadjusted_off )),
24412443 .positive = false ,
24422444 }).toU32 ());
@@ -2898,7 +2900,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
28982900 else = > return self .fail (src , "TODO implement function parameters for {} on x86_64" , .{cc }),
28992901 }
29002902 },
2901- .arm = > {
2903+ .arm , .armeb = > {
29022904 switch (cc ) {
29032905 .Naked = > {
29042906 assert (result .args .len == 0 );
@@ -2965,7 +2967,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
29652967 },
29662968 else = > return self .fail (src , "TODO implement function return values for {}" , .{cc }),
29672969 },
2968- .arm = > switch (cc ) {
2970+ .arm , .armeb = > switch (cc ) {
29692971 .Naked = > unreachable ,
29702972 .Unspecified , .C = > {
29712973 const ret_ty_size = @intCast (u32 , ret_ty .abiSize (self .target .* ));
@@ -3004,8 +3006,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
30043006 .x86_64 = > @import ("codegen/x86_64.zig" ),
30053007 .riscv64 = > @import ("codegen/riscv64.zig" ),
30063008 .spu_2 = > @import ("codegen/spu-mk2.zig" ),
3007- .arm = > @import ("codegen/arm.zig" ),
3008- .armeb = > @import ("codegen/arm.zig" ),
3009+ .arm , .armeb = > @import ("codegen/arm.zig" ),
30093010 else = > struct {
30103011 pub const Register = enum {
30113012 dummy ,
@@ -3019,7 +3020,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
30193020 };
30203021
30213022 /// An integer whose bits represent all the registers and whether they are free.
3022- const FreeRegInt = @Type (.{ .Int = .{ . is_signed = false , . bits = callee_preserved_regs .len } } );
3023+ const FreeRegInt = std . meta .Int ( .unsigned , callee_preserved_regs .len );
30233024
30243025 fn parseRegName (name : []const u8 ) ? Register {
30253026 if (@hasDecl (Register , "parseRegName" )) {
0 commit comments