Skip to content

Commit 03274e2

Browse files
committed
windows backend
1 parent 181e9af commit 03274e2

File tree

4 files changed

+118
-1
lines changed

4 files changed

+118
-1
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,5 @@ test.cal
2121
out.c
2222
out
2323
out.o
24+
out.exe
25+
out*

source/app.d

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import callisto.language;
1010
import callisto.optimiser;
1111
import callisto.preprocessor;
1212
import callisto.backends.rm86;
13+
import callisto.backends.win64;
1314
import callisto.backends.linux86;
1415

1516
const static string usage = "
@@ -30,6 +31,7 @@ Flags:
3031
Backends:
3132
rm86 - Real mode x86 and MS-DOS
3233
linux86 - Linux for 64-bit x86
34+
win64 - Windows for 64-bit x86 (Work in progress)
3335
";
3436

3537
int main(string[] args) {
@@ -130,6 +132,11 @@ int main(string[] args) {
130132
backend = new BackendLinux86();
131133
break;
132134
}
135+
case "win64": {
136+
stderr.writeln("WARNING: Unstable backend");
137+
backend = new BackendWin64();
138+
break;
139+
}
133140
default: {
134141
stderr.writefln("Unknown backend '%s'", args[i]);
135142
}

source/backends/linux86.d

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ class BackendLinux86 : CompilerBackend {
126126
format("mv %s %s.asm", compiler.outFile, compiler.outFile),
127127
useDebug?
128128
format(
129-
"nasm -f elf64 %s.asm -o %s.o -F dwarf -g", compiler.outFile, compiler.outFile
129+
"nasm -f elf64 %s.asm -o %s.o -F dwarf -g", compiler.outFile,
130+
compiler.outFile
130131
) :
131132
format("nasm -f elf64 %s.asm -o %s.o", compiler.outFile, compiler.outFile),
132133
format("ld %s.o -o %s", compiler.outFile, compiler.outFile),

source/backends/win64.d

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
module callisto.backends.win64;
2+
3+
import std.conv;
4+
import std.stdio;
5+
import std.range;
6+
import std.format;
7+
import std.algorithm;
8+
import callisto.util;
9+
import callisto.error;
10+
import callisto.parser;
11+
import callisto.compiler;
12+
import callisto.language;
13+
import callisto.backends.linux86;
14+
15+
class BackendWin64 : BackendLinux86 {
16+
this() {
17+
super();
18+
}
19+
20+
override string[] GetVersions() => ["Win64", "Windows"];
21+
22+
version (Windows) {
23+
override string[] FinalCommands() => [
24+
format("mv %s %s.asm", compiler.outFile, compiler.outFile),
25+
format("nasm -f win64 %s.asm -o %s.obj", compiler.outFile, compiler.outFile),
26+
format(
27+
"link %s.obj /subsystem:console /entry:main /out:%s", compiler.outFile,
28+
compiler.outFile
29+
)
30+
];
31+
}
32+
else {
33+
override string[] FinalCommands() => [
34+
format("mv %s %s.asm", compiler.outFile, compiler.outFile),
35+
format("nasm -f win64 %s.asm -o %s.obj", compiler.outFile, compiler.outFile),
36+
format(
37+
"x86_64-w64-mingw32-gcc %s.obj -o %s -nostdlib -lkernel32",
38+
compiler.outFile, compiler.outFile
39+
)
40+
];
41+
}
42+
43+
override void Init() {
44+
output ~= "extern ExitProcess\n";
45+
output ~= "global _start\n";
46+
output ~= "section .text\n";
47+
output ~= "_start:\n";
48+
49+
// allocate data stack
50+
output ~= "sub rsp, 4096\n"; // 512 cells
51+
output ~= "mov r15, rsp\n";
52+
53+
// copy static array constants
54+
output ~= "call __copy_arrays\n";
55+
56+
// jump to main
57+
output ~= "jmp __calmain\n";
58+
}
59+
60+
override void End() {
61+
output ~= "xor rax, rax\n";
62+
output ~= "call ExitProcess\n";
63+
64+
// create copy arrays function
65+
output ~= "__copy_arrays:\n";
66+
67+
foreach (i, ref array ; arrays) {
68+
output ~= format("mov rsi, __array_src_%d\n", i);
69+
output ~= format("mov rdi, __array_%d\n", i);
70+
output ~= format("mov rcx, %d\n", array.Size());
71+
output ~= "rep movsb\n";
72+
}
73+
74+
output ~= "ret\n";
75+
76+
// create global variables
77+
output ~= "section .bss\n";
78+
79+
foreach (name, var ; globals) {
80+
output ~= format("__global_%s: resb %d\n", name.Sanitise(), var.Size());
81+
}
82+
83+
foreach (i, ref array ; arrays) {
84+
output ~= format("__array_%d: resb %d\n", i, array.Size());
85+
}
86+
87+
// create array source
88+
output ~= "section .text\n";
89+
foreach (i, ref array ; arrays) {
90+
output ~= format("__array_src_%d: ", i);
91+
92+
switch (array.type.size) {
93+
case 1: output ~= "db "; break;
94+
case 2: output ~= "dw "; break;
95+
case 4: output ~= "dd "; break;
96+
case 8: output ~= "dq "; break;
97+
default: assert(0);
98+
}
99+
100+
foreach (j, ref element ; array.values) {
101+
output ~= element ~ (j == array.values.length - 1? "" : ", ");
102+
}
103+
104+
output ~= '\n';
105+
}
106+
}
107+
}

0 commit comments

Comments
 (0)