Skip to content

Commit efafe0e

Browse files
committed
modules working on rm86
1 parent d010246 commit efafe0e

File tree

3 files changed

+125
-27
lines changed

3 files changed

+125
-27
lines changed

source/backends/rm86.d

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,6 @@ class BackendRM86 : CompilerBackend {
5959
foreach (ref type ; types) {
6060
NewConst("core", format("%s.sizeOf", type.name), cast(long) type.size);
6161
}
62-
63-
globals ~= Global(
64-
"core", "_cal_exception", UsedType(GetType("Exception"), false), false, 0
65-
);
6662
}
6763

6864
string TempLabel() {
@@ -198,8 +194,6 @@ class BackendRM86 : CompilerBackend {
198194
WarnNoInfo("No program init function available");
199195
}
200196
output ~= "ret\n";
201-
202-
output ~= "__exception: times 8 db 0\n";
203197
}
204198

205199
// end top level code
@@ -230,18 +224,19 @@ class BackendRM86 : CompilerBackend {
230224

231225
if (array.global) {
232226
output ~= format(
233-
"%s: dw %d, %d, __array_%d\n",
227+
"%s: dw %d, %d, %s\n",
234228
Label("__array_", "%d_meta", i),
235229
array.values.length,
236230
array.type.Size(),
237-
i
231+
Label("__array_", "%d", i)
238232
);
239233
}
240234
}
241235
output.FinishSection();
242236

243237
if (output.mode != OutputMode.Module) {
244238
output ~= "__stack: times 512 dw 0\n";
239+
output ~= "__exception: times 8 db 0\n";
245240
}
246241
}
247242

@@ -496,6 +491,14 @@ class BackendRM86 : CompilerBackend {
496491
output.GetModName(), node.name, WordType.Callisto, false,
497492
true, node.nodes, node.errors, params
498493
);
494+
495+
if (output.mode == OutputMode.Module) {
496+
auto sect = output.ThisSection!FuncDefSection();
497+
498+
foreach (ref inode ; node.nodes) {
499+
sect.assembly ~= inode.toString() ~ '\n';
500+
}
501+
}
499502
}
500503
else {
501504
assert(!inScope);
@@ -604,7 +607,9 @@ class BackendRM86 : CompilerBackend {
604607
output ~= "sub si, 2\n";
605608
output ~= "mov ax, [si]\n";
606609
output ~= "cmp ax, 0\n";
607-
output ~= format("je __if_%d_%d\n", blockNum, condCounter + 1);
610+
output ~= format(
611+
"je %s\n", Label("__if_", "%d_%d", blockNum, condCounter + 1)
612+
);
608613

609614
// create scope
610615
auto oldVars = variables.dup;
@@ -633,10 +638,10 @@ class BackendRM86 : CompilerBackend {
633638
}
634639
variables = oldVars;
635640

636-
output ~= format("jmp __if_%d_end\n", blockNum);
641+
output ~= format("jmp %s\n", Label("__if_", "%d_end", blockNum));
637642

638643
++ condCounter;
639-
output ~= format("__if_%d_%d:\n", blockNum, condCounter);
644+
output ~= format("%s:\n", Label("__if_", "%d_%d", blockNum, condCounter));
640645
}
641646

642647
if (node.hasElse) {
@@ -667,17 +672,17 @@ class BackendRM86 : CompilerBackend {
667672
}
668673
variables = oldVars;
669674
}
670-
671-
output ~= format("__if_%d_end:\n", blockNum);
675+
676+
output ~= format("%s:\n", Label("__if_", "%d_end", blockNum));
672677
}
673678

674679
override void CompileWhile(WhileNode node) {
675680
++ blockCounter;
676681
uint blockNum = blockCounter;
677682
currentLoop = blockNum;
678-
679-
output ~= format("jmp __while_%d_condition\n", blockNum);
680-
output ~= format("__while_%d:\n", blockNum);
683+
684+
output ~= format("jmp %s\n", Label("__while_", "%d_condition", blockNum));
685+
output ~= format("%s:\n", Label("__while_", "%d", blockNum));
681686

682687
// make scope
683688
auto oldVars = variables.dup;
@@ -691,7 +696,7 @@ class BackendRM86 : CompilerBackend {
691696
}
692697

693698
// restore scope
694-
output ~= format("__while_%d_next:\n", blockNum);
699+
output ~= format("%s:\n", Label("__while_", "%d_next", blockNum));
695700
foreach (ref var ; variables) {
696701
if (oldVars.canFind(var)) continue;
697702
if (!var.type.hasDeinit || var.type.ptr) continue;
@@ -711,8 +716,8 @@ class BackendRM86 : CompilerBackend {
711716
variables = oldVars;
712717

713718
inWhile = false;
714-
715-
output ~= format("__while_%d_condition:\n", blockNum);
719+
720+
output ~= format("%s:\n", Label("__while_", "%d_condition", blockNum));
716721

717722
foreach (ref inode ; node.condition) {
718723
compiler.CompileNode(inode);
@@ -721,8 +726,8 @@ class BackendRM86 : CompilerBackend {
721726
output ~= "sub si, 2\n";
722727
output ~= "mov ax, [si]\n";
723728
output ~= "cmp ax, 0\n";
724-
output ~= format("jne __while_%d\n", blockNum);
725-
output ~= format("__while_%d_end:\n", blockNum);
729+
output ~= format("jne %s\n", Label("__while_", "%d", blockNum));
730+
output ~= format("%s:\n", Label("__while_", "%d_end", blockNum));
726731
}
727732

728733
override void CompileLet(LetNode node) {
@@ -850,7 +855,7 @@ class BackendRM86 : CompilerBackend {
850855
output ~= format("sub sp, %d\n", array.Size());
851856
output ~= "mov ax, sp\n";
852857
output ~= "push si\n";
853-
output ~= format("mov si, __array_%d\n", arrays.length - 1);
858+
output ~= format("mov si, %s\n", Label("__array_", "%d", arrays.length - 1));
854859
output ~= "mov di, ax\n";
855860
output ~= format("mov cx, %d\n", array.Size());
856861
output ~= "rep movsb\n";
@@ -1276,7 +1281,7 @@ class BackendRM86 : CompilerBackend {
12761281

12771282
output ~= "pop di\n";
12781283

1279-
output ~= format("mov ax, [__global_%s]\n", Sanitise("_cal_exception"));
1284+
output ~= "mov ax, [__exception]\n";
12801285
output ~= "cmp ax, 0\n";
12811286
output ~= format("je __catch_%d_end\n", blockCounter);
12821287
output ~= "mov si, di\n";
@@ -1320,13 +1325,13 @@ class BackendRM86 : CompilerBackend {
13201325
}
13211326

13221327
// set exception error
1323-
output ~= format("mov word [__global_%s], 0xFFFF\n", Sanitise("_cal_exception"));
1328+
output ~= "mov word [__exception], 0xFFFF\n";
13241329

13251330
// copy exception message
13261331
output ~= "sub si, 2\n";
13271332
output ~= "mov bx, si\n";
13281333
output ~= "mov si, [bx]\n";
1329-
output ~= format("lea di, [__global_%s + 2]\n", Sanitise("_cal_exception"));
1334+
output ~= "lea di, [__exception + 2]\n";
13301335
output ~= "mov cx, 3\n";
13311336
output ~= "rep movsw\n";
13321337
output ~= "mov si, bx\n";

source/linker.d

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import callisto.util;
88
import callisto.error;
99
import callisto.mod.mod;
1010
import callisto.mod.sections;
11-
import callisto.linkers.x86_64;
11+
import callisto.linkers.rm86;
1212
import callisto.linkers.arm64;
13+
import callisto.linkers.x86_64;
1314

1415
// NOT an object file linker, this is for linking module files
1516

@@ -234,7 +235,8 @@ int LinkerProgram(string[] args) {
234235

235236
switch (cpu) {
236237
case ModCPU.x86_64: linker = new LinkerX86_64(); break;
237-
case ModCPU.ARM64: linker = new LinkerARM64(); break;
238+
case ModCPU.RM86: linker = new LinkerRM86(); break;
239+
case ModCPU.ARM64: linker = new LinkerARM64(); break;
238240
default: {
239241
stderr.writefln("Unsupported architecture '%s'", cpu);
240242
return 1;

source/linkers/rm86.d

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
module callisto.linkers.rm86;
2+
3+
import std.stdio;
4+
import std.format;
5+
import std.process;
6+
import std.algorithm;
7+
import callisto.util;
8+
import callisto.error;
9+
import callisto.linker;
10+
import callisto.output;
11+
import callisto.mod.mod;
12+
import callisto.compiler;
13+
import callisto.mod.sections;
14+
import callisto.backends.rm86;
15+
16+
// TODO: link time optimisation
17+
class LinkerRM86 : Linker {
18+
bool keepAsm;
19+
20+
override bool HandleOption(string opt) {
21+
switch (opt) {
22+
case "keep-asm": {
23+
keepAsm = true;
24+
return true;
25+
}
26+
default: return false;
27+
}
28+
}
29+
30+
override void Link() {
31+
auto file = File(outFile, "w");
32+
33+
file.writefln("org 0x%.4X\n", 0x100); // TODO: make this replace-able
34+
file.writeln("mov si, __stack\n");
35+
36+
CheckForOneFunc("__rm86_program_init");
37+
file.writefln("call %s", GetFunc("__rm86_program_init").Label());
38+
39+
// run top level code
40+
file.writeln("__calmain:");
41+
file.write(tlcAsm);
42+
43+
// run exit function
44+
CheckForOneFunc("__rm86_program_exit");
45+
file.writefln("call %s", GetFunc("__rm86_program_exit").Label());
46+
47+
// write function assembly
48+
file.write(funcAsm);
49+
50+
// data
51+
file.write(bssAsm);
52+
file.write(dataAsm);
53+
54+
// create exception and stack
55+
file.writeln("__stack: times 512 dw 0");
56+
file.writeln("__exception: times 8 db 0");
57+
58+
file.flush();
59+
file.close();
60+
61+
// run final commands
62+
auto backend = new BackendRM86();
63+
backend.compiler = new Compiler();
64+
backend.compiler.outFile = outFile;
65+
backend.output = new Output("");
66+
backend.keepAssembly = keepAsm;
67+
68+
final switch (os) {
69+
case ModOS.None: backend.os = "bare-metal"; break;
70+
case ModOS.Linux: backend.os = "linux"; break;
71+
case ModOS.macOS: backend.os = "osx"; break;
72+
case ModOS.Windows: backend.os = "windows"; break;
73+
case ModOS.DOS: backend.os = "dos"; break;
74+
case ModOS.FreeBSD: backend.os = "freebsd"; break;
75+
case ModOS.Varvara: backend.os = "varvara"; break;
76+
case ModOS.Fox32OS: backend.os = "fox32os"; break;
77+
}
78+
79+
auto commands = backend.FinalCommands();
80+
81+
foreach (cmd ; commands) {
82+
writeln(cmd);
83+
auto res = executeShell(cmd);
84+
85+
if (res.status != 0) {
86+
stderr.writefln("Error running '%s': %s", cmd, res.output);
87+
exit(1);
88+
}
89+
}
90+
}
91+
}

0 commit comments

Comments
 (0)