@@ -96,6 +96,9 @@ class BackendARM64 : CompilerBackend {
9696 version (linux ) {
9797 defaultOS = " linux" ;
9898 }
99+ version (OSX ) {
100+ defaultOS = " osx" ;
101+ }
99102 else {
100103 defaultOS = " bare-metal" ;
101104 WarnNoInfo(" Default operating system, defaulting to bare-metal OS" );
@@ -198,6 +201,10 @@ class BackendARM64 : CompilerBackend {
198201 ret ~= [" Linux" , " IO" , " File" , " Args" , " Time" , " Heap" , " Exit" ];
199202 break ;
200203 }
204+ case " osx" : {
205+ ret ~= [" OSX" , " IO" , " Args" , " Exit" ];
206+ break ;
207+ }
201208 default : break ;
202209 }
203210
@@ -286,7 +293,7 @@ class BackendARM64 : CompilerBackend {
286293 // call constructors
287294 foreach (name, global ; globals) {
288295 if (global.type.hasInit) {
289- output ~= format( " ldr x9, = __global_%s\n " , name.Sanitise());
296+ LoadAddress( " x9 " , format( " __global_%s" , name.Sanitise() ));
290297 output ~= " str x9, [x19], #8\n " ;
291298 output ~= format(" bl __type_init_%s\n " , global.type.name.Sanitise());
292299 }
@@ -313,7 +320,7 @@ class BackendARM64 : CompilerBackend {
313320 }
314321
315322 override void Init () {
316- string [] oses = [" linux" , " bare-metal" ];
323+ string [] oses = [" linux" , " osx " , " bare-metal" ];
317324 if (! oses.canFind(os)) {
318325 ErrorNoInfo(" Backend doesn't support operating system '%s'" , os);
319326 }
@@ -322,6 +329,9 @@ class BackendARM64 : CompilerBackend {
322329 if (useLibc) {
323330 output ~= " .global main\n " ;
324331 output ~= " main:\n " ;
332+ } else if (os == " osx" ) {
333+ output ~= " .global _main\n " ;
334+ output ~= " _main:\n " ;
325335 } else {
326336 output ~= " .global _start\n " ;
327337 output ~= " _start:\n " ;
@@ -355,7 +365,7 @@ class BackendARM64 : CompilerBackend {
355365 // call destructors
356366 foreach (name, global ; globals) {
357367 if (global.type.hasDeinit) {
358- output ~= format( " ldr x9, = __global_%s\n " , name.Sanitise());
368+ LoadAddress( " x9 " , format( " __global_%s" , name.Sanitise() ));
359369 output ~= " str x9, [x19], #8\n " ;
360370 output ~= format(" bl __type_deinit_%s\n " , global.type.name.Sanitise());
361371 }
@@ -395,6 +405,7 @@ class BackendARM64 : CompilerBackend {
395405 // create arrays
396406 output ~= " .data\n " ;
397407 foreach (i, ref array ; arrays) {
408+ output ~= " .align 8\n " ;
398409 if (exportSymbols) {
399410 output ~= format(" .global __array_%d\n " , i);
400411 }
@@ -416,6 +427,7 @@ class BackendARM64 : CompilerBackend {
416427 output ~= ' \n ' ;
417428
418429 if (array.global) {
430+ output ~= " .align 8\n " ;
419431 output ~= format(
420432 " __array_%d_meta: .8byte %d, %d, __array_%d\n " , i,
421433 array.values .length,
@@ -486,8 +498,7 @@ class BackendARM64 : CompilerBackend {
486498 Error(node.error, " Can't push value of struct" );
487499 }
488500
489- string symbol = format(" __global_%s" , node.name.Sanitise());
490- output ~= format(" ldr x9, =%s\n " , symbol);
501+ LoadAddress(" x9" , format(" __global_%s" , node.name.Sanitise()));
491502
492503 switch (var.type.size) {
493504 case 1 : output ~= " ldrb w9, [x9]\n " ; break ;
@@ -798,14 +809,14 @@ class BackendARM64 : CompilerBackend {
798809 arrays ~= array;
799810
800811 if (! inScope || node.constant) {
801- output ~= format( " ldr x9, = __array_%d_meta\n " , arrays.length - 1 );
812+ LoadAddress( " x9 " , format( " __array_%d_meta" , arrays.length - 1 ) );
802813 output ~= " str x9, [x19], #8\n " ;
803814 }
804815 else {
805816 // allocate a copy of this array
806817 OffsetLocalsStack(array.Size(), true );
807818 output ~= " mov x9, x20\n " ;
808- output ~= format( " ldr x10, = __array_%d\n " , arrays.length - 1 );
819+ LoadAddress( " x10" , format( " __array_%d" , arrays.length - 1 ) );
809820 output ~= format(" ldr x11, =%d\n " , array.Size());
810821 output ~= " 1:\n " ;
811822 output ~= " ldrb w12, [x10], #1\n " ;
@@ -1077,13 +1088,13 @@ class BackendARM64 : CompilerBackend {
10771088 string symbol = word.type == WordType.Callisto?
10781089 format(" __func__%s" , node.func.Sanitise()) : node.func;
10791090
1080- output ~= format( " ldr x9, =%s \n " , symbol);
1091+ LoadAddress( " x9 " , symbol);
10811092 output ~= " str x9, [x19], #8\n " ;
10821093 }
10831094 else if (node.func in globals) {
10841095 auto var = globals[node.func];
10851096
1086- output ~= format( " ldr x9, = __global_%s\n " , node.func.Sanitise());
1097+ LoadAddress( " x9 " , format( " __global_%s" , node.func.Sanitise() ));
10871098 output ~= " str x9, [x19], #8\n " ;
10881099 }
10891100 else if (VariableExists(node.func)) {
@@ -1184,8 +1195,7 @@ class BackendARM64 : CompilerBackend {
11841195 Error(node.error, " Can't set struct value" );
11851196 }
11861197
1187- string symbol = format(" __global_%s" , node.var.Sanitise());
1188- output ~= format(" ldr x10, =%s\n " , symbol);
1198+ LoadAddress(" x10" , format(" __global_%s" , node.var.Sanitise()));
11891199
11901200 switch (global.type.size) {
11911201 case 1 : output ~= " strb w9, [x10]\n " ; break ;
@@ -1200,12 +1210,21 @@ class BackendARM64 : CompilerBackend {
12001210 }
12011211 }
12021212
1203- void OffsetLocalsStack (size_t offset, bool sub) {
1213+ private void OffsetLocalsStack (size_t offset, bool sub) {
12041214 if (offset >= 4096 ) {
12051215 output ~= format(" mov x9, #%d\n " , offset);
12061216 output ~= format(" %s x20, x20, x9\n " , sub ? " sub" : " add" );
12071217 } else {
12081218 output ~= format(" %s x20, x20, #%d\n " , sub ? " sub" : " add" , offset);
12091219 }
12101220 }
1221+
1222+ private void LoadAddress (string reg, string symbol) {
1223+ if (os == " osx" ) {
1224+ output ~= format(" adrp %s, %s@PAGE\n " , reg, symbol);
1225+ output ~= format(" add %s, %s, %s@PAGEOFF\n " , reg, reg, symbol);
1226+ } else {
1227+ output ~= format(" ldr %s, =%s\n " , reg, symbol);
1228+ }
1229+ }
12111230}
0 commit comments