Skip to content

Commit 9fbdd1f

Browse files
committed
Add remaining OS functions, add support for libc and extern C to osx
1 parent 59903b0 commit 9fbdd1f

File tree

3 files changed

+92
-58
lines changed

3 files changed

+92
-58
lines changed

source/backends/arm64.d

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ class BackendARM64 : CompilerBackend {
202202
break;
203203
}
204204
case "osx": {
205-
ret ~= ["OSX", "IO", "File", "Args", "Exit"];
205+
ret ~= ["OSX", "IO", "File", "Args", "Time", "Exit"];
206+
if (useLibc) ret ~= "Heap";
206207
break;
207208
}
208209
default: break;
@@ -240,25 +241,31 @@ class BackendARM64 : CompilerBackend {
240241
}
241242

242243
if (useLibc) {
243-
string[] possiblePaths = [
244-
"/usr/aarch64-linux-gnu/lib/crt1.o",
245-
"/usr/lib/crt1.o",
246-
"/usr/lib64/crt1.o",
247-
];
248-
bool crt1;
249-
250-
foreach (ref path ; possiblePaths) {
251-
if (path.exists) {
252-
crt1 = true;
253-
linkCommand ~= format(" %s", path);
254-
linkCommand ~= format(" %s/crti.o", path.dirName);
255-
linkCommand ~= format(" %s/crtn.o", path.dirName);
256-
break;
244+
if (os == "linux") {
245+
string[] possiblePaths = [
246+
"/usr/aarch64-linux-gnu/lib/crt1.o",
247+
"/usr/lib/crt1.o",
248+
"/usr/lib64/crt1.o",
249+
];
250+
bool crt1;
251+
252+
foreach (ref path ; possiblePaths) {
253+
if (path.exists) {
254+
crt1 = true;
255+
linkCommand ~= format(" %s", path);
256+
linkCommand ~= format(" %s/crti.o", path.dirName);
257+
linkCommand ~= format(" %s/crtn.o", path.dirName);
258+
break;
259+
}
257260
}
258-
}
259261

260-
if (!crt1) {
261-
stderr.writeln("WARNING: Failed to find crt1.o, program may behave incorrectly");
262+
if (!crt1) {
263+
stderr.writeln("WARNING: Failed to find crt1.o, program may behave incorrectly");
264+
}
265+
} else if (os == "osx") {
266+
linkCommand ~= " -lSystem -syslibroot `xcrun --sdk macosx --show-sdk-path`";
267+
} else {
268+
WarnNoInfo("Cannot use libc on operating system '%s'", os);
262269
}
263270
}
264271

@@ -309,7 +316,7 @@ class BackendARM64 : CompilerBackend {
309316
}
310317
}
311318
else if (word.type == WordType.Raw) {
312-
output ~= format("bl %s\n", name);
319+
output ~= format("bl %s\n", ExternSymbol(name));
313320
}
314321
else if (word.type == WordType.C) {
315322
assert(0); // TODO: error
@@ -326,12 +333,12 @@ class BackendARM64 : CompilerBackend {
326333
}
327334

328335
output ~= ".text\n";
329-
if (useLibc) {
330-
output ~= ".global main\n";
331-
output ~= "main:\n";
332-
} else if (os == "osx") {
336+
if (os == "osx") {
333337
output ~= ".global _main\n";
334338
output ~= "_main:\n";
339+
} else if (useLibc) {
340+
output ~= ".global main\n";
341+
output ~= "main:\n";
335342
} else {
336343
output ~= ".global _start\n";
337344
output ~= "_start:\n";
@@ -449,7 +456,7 @@ class BackendARM64 : CompilerBackend {
449456
}
450457
else {
451458
if (word.type == WordType.Raw) {
452-
output ~= format("bl %s\n", node.name);
459+
output ~= format("bl %s\n", ExternSymbol(node.name));
453460
}
454461
else if (word.type == WordType.C) {
455462
// TODO: support more of the calling convention (especially structs)
@@ -463,7 +470,7 @@ class BackendARM64 : CompilerBackend {
463470
output ~= format("ldr x%d, [x19, #-8]!\n", reg);
464471
}
465472

466-
output ~= format("bl %s\n", word.symbolName);
473+
output ~= format("bl %s\n", ExternSymbol(word.symbolName));
467474

468475
if (!word.isVoid) {
469476
output ~= "str x0, [x19], #8\n";
@@ -1071,7 +1078,7 @@ class BackendARM64 : CompilerBackend {
10711078
}
10721079

10731080
if (word.type != WordType.Callisto) {
1074-
output ~= format(".extern %s\n", node.func);
1081+
output ~= format(".extern %s\n", ExternSymbol(node.func));
10751082
}
10761083

10771084
words[funcName] = word;
@@ -1086,7 +1093,7 @@ class BackendARM64 : CompilerBackend {
10861093
if (node.func in words) {
10871094
auto word = words[node.func];
10881095
string symbol = word.type == WordType.Callisto?
1089-
format("__func__%s", node.func.Sanitise()) : node.func;
1096+
format("__func__%s", node.func.Sanitise()) : ExternSymbol(node.func);
10901097

10911098
LoadAddress("x9", symbol);
10921099
output ~= "str x9, [x19], #8\n";
@@ -1227,4 +1234,12 @@ class BackendARM64 : CompilerBackend {
12271234
output ~= format("ldr %s, =%s\n", reg, symbol);
12281235
}
12291236
}
1237+
1238+
private string ExternSymbol(string name) {
1239+
if (os == "osx") {
1240+
return "_" ~ name;
1241+
} else {
1242+
return name;
1243+
}
1244+
}
12301245
}

source/backends/x86_64.d

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,8 @@ class BackendX86_64 : CompilerBackend {
208208
break;
209209
}
210210
case "osx": {
211-
ret ~= ["OSX", "IO", "File", "Args", "Exit"];
211+
ret ~= ["OSX", "IO", "Exit", "Time", "File", "Args"];
212+
if (useLibc) ret ~= "Heap";
212213
break;
213214
}
214215
default: break;
@@ -255,29 +256,35 @@ class BackendX86_64 : CompilerBackend {
255256
linkCommand ~= format(" -l%s", lib);
256257
}
257258

258-
if (!link.empty()) {
259+
if (!link.empty() && os == "linux") {
259260
// idk if this is correct on all linux systems but whatever
260261
linkCommand ~= " -dynamic-linker /lib64/ld-linux-x86-64.so.2";
261262
}
262263

263264
if (useLibc) {
264-
string[] possiblePaths = [
265-
"/usr/lib/crt1.o",
266-
"/usr/lib/x86_64-linux-gnu/crt1.o"
267-
];
268-
bool crt1;
269-
270-
foreach (ref path ; possiblePaths) {
271-
if (exists(path)) {
272-
crt1 = true;
273-
linkCommand ~= format(" %s", path);
274-
linkCommand ~= format(" %s/crti.o", path.dirName());
275-
linkCommand ~= format(" %s/crtn.o", path.dirName());
265+
if (os == "linux") {
266+
string[] possiblePaths = [
267+
"/usr/lib/crt1.o",
268+
"/usr/lib/x86_64-linux-gnu/crt1.o"
269+
];
270+
bool crt1;
271+
272+
foreach (ref path ; possiblePaths) {
273+
if (exists(path)) {
274+
crt1 = true;
275+
linkCommand ~= format(" %s", path);
276+
linkCommand ~= format(" %s/crti.o", path.dirName());
277+
linkCommand ~= format(" %s/crtn.o", path.dirName());
278+
}
276279
}
277-
}
278280

279-
if (!crt1) {
280-
stderr.writeln("WARNING: Failed to find crt1.o, program may behave incorrectly");
281+
if (!crt1) {
282+
stderr.writeln("WARNING: Failed to find crt1.o, program may behave incorrectly");
283+
}
284+
} else if (os == "osx") {
285+
linkCommand ~= " -syslibroot `xcrun --sdk macosx --show-sdk-path`";
286+
} else {
287+
WarnNoInfo("Cannot use libc on operating system '%s'", os);
281288
}
282289
}
283290

@@ -331,7 +338,7 @@ class BackendX86_64 : CompilerBackend {
331338
}
332339
}
333340
else if (word.type == WordType.Raw) {
334-
output ~= format("call %s\n", name);
341+
output ~= format("call %s\n", ExternSymbol(name));
335342
}
336343
else if (word.type == WordType.C) {
337344
assert(0); // TODO: error
@@ -347,15 +354,19 @@ class BackendX86_64 : CompilerBackend {
347354
ErrorNoInfo("Backend doesn't support operating system '%s'", os);
348355
}
349356

350-
if (useLibc) output ~= "global main\n";
351-
else if (os == "osx") output ~= "default rel\nglobal _main\n";
352-
else output ~= "global _start\n";
353-
354357
output ~= "section .text\n";
355-
356-
if (useLibc) output ~= "main:\n";
357-
else if (os == "osx") output ~= "_main:\n";
358-
else output ~= "_start:\n";
358+
359+
if (os == "osx") {
360+
output ~= "default rel\n";
361+
output ~= "global _main\n";
362+
output ~= "_main:\n";
363+
} else if (useLibc) {
364+
output ~= "global main\n";
365+
output ~= "main:\n";
366+
} else {
367+
output ~= "global _start\n";
368+
output ~= "_start:\n";
369+
}
359370

360371
output ~= "call __init\n";
361372

@@ -486,7 +497,7 @@ class BackendX86_64 : CompilerBackend {
486497
}
487498
else {
488499
if (word.type == WordType.Raw) {
489-
output ~= format("call %s\n", node.name);
500+
output ~= format("call %s\n", ExternSymbol(node.name));
490501
}
491502
else if (word.type == WordType.C) {
492503
if (word.params.length >= 1) {
@@ -523,7 +534,7 @@ class BackendX86_64 : CompilerBackend {
523534

524535
// TODO: support more than 6 parameters
525536

526-
output ~= format("call %s\n", word.symbolName);
537+
output ~= format("call %s\n", ExternSymbol(word.symbolName));
527538

528539
if (!word.isVoid) {
529540
output ~= "mov [r15], rax\n";
@@ -1157,7 +1168,7 @@ class BackendX86_64 : CompilerBackend {
11571168
}
11581169

11591170
if (word.type != WordType.Callisto) {
1160-
output ~= format("extern %s\n", node.func);
1171+
output ~= format("extern %s\n", ExternSymbol(node.func));
11611172
}
11621173

11631174
words[funcName] = word;
@@ -1173,7 +1184,7 @@ class BackendX86_64 : CompilerBackend {
11731184
if (node.func in words) {
11741185
auto word = words[node.func];
11751186
string symbol = word.type == WordType.Callisto?
1176-
format("__func__%s", node.func.Sanitise()) : node.func;
1187+
format("__func__%s", node.func.Sanitise()) : ExternSymbol(node.func);
11771188

11781189
output ~= format("mov rax, %s\n", symbol);
11791190
output ~= "mov [r15], rax\n";
@@ -1312,4 +1323,12 @@ class BackendX86_64 : CompilerBackend {
13121323
Error(node.error, "Variable '%s' doesn't exist", node.var);
13131324
}
13141325
}
1326+
1327+
private string ExternSymbol(string name) {
1328+
if (os == "osx") {
1329+
return "_" ~ name;
1330+
} else {
1331+
return name;
1332+
}
1333+
}
13151334
}

0 commit comments

Comments
 (0)