Skip to content

Commit 6a2e927

Browse files
committed
Add arm64 macOS support
1 parent a5634ab commit 6a2e927

File tree

2 files changed

+35
-14
lines changed

2 files changed

+35
-14
lines changed

source/backends/arm64.d

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

source/backends/x86_64.d

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,9 @@ class BackendX86_64 : CompilerBackend {
313313
foreach (name, global ; globals) {
314314
if (global.type.hasInit) {
315315
output ~= format(
316-
"mov qword [r15], qword __global_%s\n", name.Sanitise()
316+
"lea rax, qword [__global_%s]\n", name.Sanitise()
317317
);
318+
output ~= "mov [r15], rax\n";
318319
output ~= "add r15, 8\n";
319320
output ~= format("call __type_init_%s\n", global.type.name.Sanitise());
320321
}
@@ -388,7 +389,8 @@ class BackendX86_64 : CompilerBackend {
388389
// call destructors
389390
foreach (name, global ; globals) {
390391
if (global.type.hasDeinit) {
391-
output ~= format("mov qword [r15], qword __global_%s\n", Sanitise(name));
392+
output ~= format("lea rax, qword [__global_%s]\n", Sanitise(name));
393+
output ~= "mov [r15], rax\n";
392394
output ~= "add r15, 8\n";
393395
output ~= format("call __type_deinit_%s\n", Sanitise(global.type.name));
394396
}

0 commit comments

Comments
 (0)