Skip to content

Commit 3bdfdd6

Browse files
committed
WIP gas support (incomplete) + assembly macros
1 parent 98b7b78 commit 3bdfdd6

File tree

7 files changed

+104
-34
lines changed

7 files changed

+104
-34
lines changed

source/app.d

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ int main(string[] args) {
329329
if (backend is null) {
330330
ErrorNoInfo("No backend selected");
331331
}
332+
backend.output.outFile = outFile;
332333

333334
if (os == "DEFAULT") {
334335
os = backend.defaultOS;
@@ -355,7 +356,7 @@ int main(string[] args) {
355356
}
356357
}
357358

358-
backend.output = header ~ '\n';
359+
backend.output ~= header ~ '\n';
359360

360361
if (file == "") {
361362
stderr.writeln("No source files");
@@ -445,7 +446,8 @@ int main(string[] args) {
445446
compiler.Compile(nodes);
446447
if (!compiler.success) return 1;
447448

448-
std.file.write(outFile, compiler.backend.output);
449+
// std.file.write(outFile, compiler.backend.output);
450+
compiler.backend.output.Finish();
449451

450452
if (runFinal) {
451453
compiler.outFile = outFile;

source/backends/arm64.d

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import std.process;
1010
import std.algorithm;
1111
import callisto.util;
1212
import callisto.error;
13+
import callisto.output;
1314
import callisto.parser;
1415
import callisto.compiler;
1516
import callisto.language;
@@ -44,6 +45,8 @@ class BackendARM64 : CompilerBackend {
4445
bool useLibc;
4546

4647
this() {
48+
output = new Output();
49+
4750
addrSize = 8;
4851

4952
version (linux) {

source/backends/lua.d

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import std.algorithm;
1010
import callisto.util;
1111
import callisto.error;
1212
import callisto.parser;
13+
import callisto.output;
1314
import callisto.compiler;
1415
import callisto.language;
1516
import callisto.preprocessor;
@@ -48,6 +49,8 @@ class BackendLua : CompilerBackend {
4849
ulong arrayStack = 524287;
4950

5051
this() {
52+
output = new Output();
53+
5154
addrSize = 1;
5255

5356
// built in integer types

source/backends/rm86.d

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import std.algorithm;
88
import callisto.util;
99
import callisto.error;
1010
import callisto.parser;
11+
import callisto.output;
1112
import callisto.compiler;
1213
import callisto.language;
1314
import callisto.preprocessor;
@@ -35,6 +36,8 @@ class BackendRM86 : CompilerBackend {
3536
uint tempLabelNum;
3637

3738
this() {
39+
output = new Output();
40+
3841
addrSize = 2;
3942
defaultOS = "dos";
4043

source/backends/uxn.d

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import std.algorithm;
88
import callisto.util;
99
import callisto.error;
1010
import callisto.parser;
11+
import callisto.output;
1112
import callisto.compiler;
1213
import callisto.language;
1314
import callisto.preprocessor;
@@ -30,6 +31,8 @@ class BackendUXN : CompilerBackend {
3031
uint tempLabelNum;
3132

3233
this() {
34+
output = new Output();
35+
3336
addrSize = 2;
3437

3538
types ~= Type("u8", 1);

source/backends/x86_64.d

Lines changed: 85 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import std.algorithm;
1010
import callisto.util;
1111
import callisto.error;
1212
import callisto.parser;
13+
import callisto.output;
1314
import callisto.compiler;
1415
import callisto.language;
1516
import callisto.preprocessor;
@@ -51,6 +52,12 @@ class BackendX86_64 : CompilerBackend {
5152
bool useFramePtr = true;
5253

5354
this() {
55+
output = new Output();
56+
output.macros["QWORD"] = useGas? "qword ptr" : "qword";
57+
output.macros["DWORD"] = useGas? "dword ptr" : "dword";
58+
output.macros["WORD"] = useGas? "word ptr" : "word";
59+
output.macros["BYTE"] = useGas? "byte ptr" : "byte";
60+
5461
addrSize = 8;
5562

5663
version (linux) {
@@ -250,6 +257,10 @@ class BackendX86_64 : CompilerBackend {
250257
useFramePtr = true;
251258
return true;
252259
}
260+
case "use-gas": {
261+
useGas = true;
262+
return true;
263+
}
253264
default: return false;
254265
}
255266
}
@@ -295,19 +306,41 @@ class BackendX86_64 : CompilerBackend {
295306
ErrorNoInfo("Backend doesn't support operating system '%s'", os);
296307
}
297308

298-
output ~= "section .text\n";
309+
if (useGas) {
310+
output ~= ".intel_syntax noprefix\n";
311+
output ~= ".section .text\n";
312+
}
313+
else {
314+
output ~= "section .text\n";
315+
}
299316

300317
if (os == "osx") {
318+
if (useGas) {
319+
ErrorNoInfo("Cannot use GNU Assembler on x86_64 macOS");
320+
}
321+
301322
output ~= "default rel\n";
302323
output ~= "global _main\n";
303324
output ~= "_main:\n";
304325
}
305326
else if (useLibc) {
306-
output ~= "global main\n";
327+
if (useGas) {
328+
output ~= ".global main\n";
329+
}
330+
else {
331+
output ~= "global main\n";
332+
}
333+
307334
output ~= "main:\n";
308335
}
309336
else {
310-
output ~= "global _start\n";
337+
if (useGas) {
338+
output ~= ".global _start\n";
339+
}
340+
else {
341+
output ~= "global _start\n";
342+
}
343+
311344
output ~= "_start:\n";
312345
}
313346

@@ -325,8 +358,8 @@ class BackendX86_64 : CompilerBackend {
325358

326359
// create functions for interop
327360
if (exportSymbols) {
328-
output ~= "
329-
global cal_push
361+
output ~= format("
362+
%sglobal cal_push
330363
cal_push:
331364
mov [r15], rdi
332365
add r15, 8
@@ -335,7 +368,7 @@ class BackendX86_64 : CompilerBackend {
335368
sub r15, 8
336369
mov rax, [r15]
337370
ret
338-
";
371+
", useGas? "." : "");
339372
}
340373
}
341374

@@ -362,8 +395,8 @@ class BackendX86_64 : CompilerBackend {
362395
output ~= "__copy_arrays:\n";
363396

364397
foreach (i, ref array ; arrays) {
365-
output ~= format("mov rsi, __array_src_%d\n", i);
366-
output ~= format("mov rdi, __array_%d\n", i);
398+
output ~= format("lea rsi, __array_src_%d\n", i);
399+
output ~= format("lea rdi, __array_%d\n", i);
367400
output ~= format("mov rcx, %d\n", array.Size());
368401
output ~= "rep movsb\n";
369402
}
@@ -381,21 +414,42 @@ class BackendX86_64 : CompilerBackend {
381414
output ~= "ret\n";
382415

383416
// create global variables
384-
output ~= "section .bss\n";
417+
if (useGas) {
418+
output ~= ".section .bss\n";
419+
}
420+
else {
421+
output ~= "section .bss\n";
422+
}
385423

386424
foreach (var ; globals) {
387-
output ~= format("__global_%s: resb %d\n", var.name.Sanitise(), var.Size());
425+
if (useGas) {
426+
output ~= format(
427+
"__global_%s: .skip %d\n", var.name.Sanitise(), var.Size()
428+
);
429+
}
430+
else {
431+
output ~= format(
432+
"__global_%s: resb %d\n", var.name.Sanitise(), var.Size()
433+
);
434+
}
388435

389436
if (exportSymbols) {
390-
output ~= format("global __global_%s\n", var.name.Sanitise());
437+
output ~= format(
438+
"%sglobal __global_%s\n", useGas? "." : "", var.name.Sanitise()
439+
);
391440
}
392441
}
393442

394443
foreach (i, ref array ; arrays) {
395-
output ~= format("__array_%d: resb %d\n", i, array.Size());
444+
if (useGas) {
445+
output ~= format("__array_%d: skip %d\n", i, array.Size());
446+
}
447+
else {
448+
output ~= format("__array_%d: resb %d\n", i, array.Size());
449+
}
396450

397451
if (exportSymbols) {
398-
output ~= format("global __array_%d\n", i);
452+
output ~= format("%sglobal __array_%d\n", useGas? "." : "", i);
399453
}
400454
}
401455

@@ -405,10 +459,10 @@ class BackendX86_64 : CompilerBackend {
405459
output ~= format("__array_src_%d: ", i);
406460

407461
switch (array.type.size) {
408-
case 1: output ~= "db "; break;
409-
case 2: output ~= "dw "; break;
410-
case 4: output ~= "dd "; break;
411-
case 8: output ~= "dq "; break;
462+
case 1: output ~= useGas? ".byte " : "db "; break;
463+
case 2: output ~= useGas? ".word " : "dw "; break;
464+
case 4: output ~= useGas? ".long " : "dd "; break;
465+
case 8: output ~= useGas? ".quad " : "dq "; break;
412466
default: assert(0);
413467
}
414468

@@ -420,7 +474,8 @@ class BackendX86_64 : CompilerBackend {
420474

421475
if (array.global) {
422476
output ~= format(
423-
"__array_%d_meta: dq %d, %d, __array_%d\n", i,
477+
"__array_%d_meta: %s %d, %d, __array_%d\n", i,
478+
useGas? ".quad" : "dq",
424479
array.values.length,
425480
array.type.size,
426481
i
@@ -617,7 +672,7 @@ class BackendX86_64 : CompilerBackend {
617672
}
618673

619674
if (crash) {
620-
output ~= format("mov rax, __global_%s\n", Sanitise("_cal_exception"));
675+
output ~= format("lea rax, __global_%s\n", Sanitise("_cal_exception"));
621676
output ~= "cmp qword [rax], 0\n";
622677
output ~= format("jne __func__%s\n", Sanitise("__x86_64_exception"));
623678
}
@@ -691,7 +746,7 @@ class BackendX86_64 : CompilerBackend {
691746
output ~= "mov [r15], r14\n";
692747
}
693748
else {
694-
output ~= format("mov qword [r15], %d\n", node.value);
749+
output ~= format("mov qword [r15], qword %d\n", node.value);
695750
}
696751
output ~= "add r15, 8\n";
697752
}
@@ -718,7 +773,7 @@ class BackendX86_64 : CompilerBackend {
718773

719774
if (node.inline) {
720775
if (node.errors) {
721-
output ~= format("mov rax, __global_%s\n", Sanitise("_cal_exception"));
776+
output ~= format("lea rax, __global_%s\n", Sanitise("_cal_exception"));
722777
output ~= "mov [rax], 0\n";
723778
}
724779

@@ -750,7 +805,7 @@ class BackendX86_64 : CompilerBackend {
750805
}
751806

752807
if (node.errors) {
753-
output ~= format("mov rax, __global_%s\n", Sanitise("_cal_exception"));
808+
output ~= format("lea rax, __global_%s\n", Sanitise("_cal_exception"));
754809
output ~= "mov qword [rax], qword 0\n";
755810
}
756811

@@ -1039,15 +1094,15 @@ class BackendX86_64 : CompilerBackend {
10391094
arrays ~= array;
10401095

10411096
if (!inScope || node.constant) {
1042-
output ~= format("mov rax, __array_%d_meta\n", arrays.length - 1);
1097+
output ~= format("lea rax, __array_%d_meta\n", arrays.length - 1);
10431098
output ~= "mov qword [r15], rax\n";
10441099
output ~= "add r15, 8\n";
10451100
}
10461101
else {
10471102
// allocate a copy of this array
10481103
output ~= format("sub rsp, %d\n", array.Size());
10491104
output ~= "mov rax, rsp\n";
1050-
output ~= format("mov rsi, __array_%d\n", arrays.length - 1);
1105+
output ~= format("lea rsi, __array_%d\n", arrays.length - 1);
10511106
output ~= "mov rdi, rax\n";
10521107
output ~= format("mov rcx, %d\n", array.Size());
10531108
output ~= format("rep movsb\n");
@@ -1077,8 +1132,8 @@ class BackendX86_64 : CompilerBackend {
10771132

10781133
output ~= "mov rax, rsp\n";
10791134
output ~= format("sub rsp, %d\n", 8 * 3); // size of Array structure
1080-
output ~= format("mov qword [rsp], %d\n", array.values.length); // length
1081-
output ~= format("mov qword [rsp + 8], %d\n", array.type.size); // member size
1135+
output ~= format("mov qword [rsp], qword %d\n", array.values.length); // length
1136+
output ~= format("mov qword [rsp + 8], qword %d\n", array.type.size); // member size
10821137
output ~= "mov [rsp + 16], rax\n"; // elements
10831138

10841139
// push metadata address
@@ -1188,7 +1243,7 @@ class BackendX86_64 : CompilerBackend {
11881243
}
11891244

11901245
if (word.type != WordType.Callisto) {
1191-
output ~= format("extern %s\n", ExternSymbol(node.func));
1246+
output ~= format("%sextern %s\n", useGas? "." : "", ExternSymbol(node.func));
11921247
}
11931248

11941249
words[funcName] = word;
@@ -1206,7 +1261,7 @@ class BackendX86_64 : CompilerBackend {
12061261
string symbol = word.type == WordType.Callisto?
12071262
format("__func__%s", node.func.Sanitise()) : ExternSymbol(node.func);
12081263

1209-
output ~= format("mov rax, %s\n", symbol);
1264+
output ~= format("lea rax, %s\n", symbol);
12101265
output ~= "mov [r15], rax\n";
12111266
output ~= "add r15, 8\n";
12121267
}
@@ -1505,7 +1560,7 @@ class BackendX86_64 : CompilerBackend {
15051560

15061561
++ blockCounter;
15071562

1508-
output ~= format("mov rax, __global_%s\n", Sanitise("_cal_exception"));
1563+
output ~= format("lea rax, __global_%s\n", Sanitise("_cal_exception"));
15091564
output ~= "cmp qword [rax], 0\n";
15101565
output ~= format("je __catch_%d_end\n", blockCounter);
15111566

@@ -1547,7 +1602,7 @@ class BackendX86_64 : CompilerBackend {
15471602
}
15481603

15491604
// set exception error
1550-
output ~= format("mov rbx, __global_%s\n", Sanitise("_cal_exception"));
1605+
output ~= format("lea rbx, __global_%s\n", Sanitise("_cal_exception"));
15511606
output ~= "mov rax, 0xFFFFFFFFFFFFFFFF\n";
15521607
output ~= "mov [rbx], rax\n";
15531608

0 commit comments

Comments
 (0)