Skip to content

Commit 5cf3784

Browse files
committed
x86_64
1 parent 4ec8c43 commit 5cf3784

File tree

2 files changed

+128
-68
lines changed

2 files changed

+128
-68
lines changed

source/backends/x86_64.d

Lines changed: 124 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -407,64 +407,77 @@ class BackendX86_64 : CompilerBackend {
407407
}
408408
}
409409

410-
void PushGlobalValue(Node node, Global var, size_t size = 0, size_t offset = 0, bool member = false) {
410+
void PushGlobalValue(
411+
Node node, Global var, size_t size = 0, size_t offset = 0, bool member = false,
412+
bool deref = false
413+
) {
411414
if (size == 0) {
412-
size = var.type.size;
415+
size = var.type.Size();
413416
}
414417

415418
if (size != 8) {
416419
output ~= "xor rax, rax\n";
417420
}
418421

419-
if (var.type.isStruct && !member) {
420-
Error(node.error, "Can't push value of struct");
421-
}
422-
423422
string symbol = format("__global_%s", var.name.Sanitise());
424423

425-
switch (size) {
426-
case 1: output ~= format("mov al, [%s", symbol); break;
427-
case 2: output ~= format("mov ax, [%s", symbol); break;
428-
case 4: output ~= format("mov eax, [%s", symbol); break;
429-
case 8: output ~= format("mov rax, [%s", symbol); break;
430-
default: Error(node.error, "Bad variable type size");
431-
}
424+
if (deref) {
425+
output ~= format("mov rbx, [%s]\n", symbol);
432426

433-
if (offset == 0) output ~= "]\n";
434-
else output ~= format(" + %d]\n", offset);
427+
switch (size) {
428+
case 1: output ~= format("mov al, [rbx + %d]\n", offset); break;
429+
case 2: output ~= format("mov ax, [rbx + %d]\n", offset); break;
430+
case 4: output ~= format("mov eax, [rbx + %d]\n", offset); break;
431+
case 8: output ~= format("mov rax, [rbx + %d]\n", offset); break;
432+
default: Error(node.error, "Bad variable type size");
433+
}
434+
}
435+
else {
436+
switch (size) {
437+
case 1: output ~= format("mov al, [%s + %d]\n", symbol, offset); break;
438+
case 2: output ~= format("mov ax, [%s + %d]\n", symbol, offset); break;
439+
case 4: output ~= format("mov eax, [%s + %d]\n", symbol, offset); break;
440+
case 8: output ~= format("mov rax, [%s + %d]\n", symbol, offset); break;
441+
default: Error(node.error, "Bad variable type size");
442+
}
443+
}
435444

436445
output ~= "mov [r15], rax\n";
437446
output ~= "add r15, 8\n";
438447
}
439448

440-
void PushVariableValue(Node node, Variable var, size_t size = 0, size_t offset = 0, bool member = false) {
449+
void PushVariableValue(
450+
Node node, Variable var, size_t size = 0, size_t offset = 0, bool member = false,
451+
bool deref = false
452+
) {
441453
if (size == 0) {
442-
size = var.type.size;
443-
}
444-
445-
output ~= "mov rdi, rsp\n";
446-
if (var.offset > 0) {
447-
output ~= format("add rdi, %d\n", var.offset);
448-
}
449-
450-
if (var.type.isStruct && !member) {
451-
Error(node.error, "Can't push value of struct");
454+
size = var.type.Size();
452455
}
453456

454457
if (size != 8) {
455458
output ~= "xor rax, rax\n";
456459
}
457460

458-
switch (size) {
459-
case 1: output ~= format("mov al, [rdi"); break;
460-
case 2: output ~= format("mov ax, [rdi"); break;
461-
case 4: output ~= format("mov eax, [rdi"); break;
462-
case 8: output ~= format("mov rax, [rdi"); break;
463-
default: Error(node.error, "Bad variable type size");
464-
}
461+
if (deref) {
462+
output ~= format("mov rbx, [rsp + %d]\n", var.offset);
465463

466-
if (offset == 0) output ~= "]\n";
467-
else output ~= format(" + %d]\n", offset);
464+
switch (size) {
465+
case 1: output ~= format("mov al, [rbx + %d]\n", offset); break;
466+
case 2: output ~= format("mov ax, [rbx + %d]\n", offset); break;
467+
case 4: output ~= format("mov eax, [rbx + %d]\n", offset); break;
468+
case 8: output ~= format("mov rax, [rbx + %d]\n", offset); break;
469+
default: Error(node.error, "Bad variable type size");
470+
}
471+
}
472+
else {
473+
switch (size) {
474+
case 1: output ~= format("mov al, [rsp + %d]\n", offset + var.offset); break;
475+
case 2: output ~= format("mov ax, [rsp + %d]\n", offset + var.offset); break;
476+
case 4: output ~= format("mov eax, [rsp + %d]\n", offset + var.offset); break;
477+
case 8: output ~= format("mov rax, [rsp + %d]\n", offset + var.offset); break;
478+
default: Error(node.error, "Bad variable type size");
479+
}
480+
}
468481

469482
output ~= "mov [r15], rax\n";
470483
output ~= "add r15, 8\n";
@@ -609,10 +622,18 @@ class BackendX86_64 : CompilerBackend {
609622
auto structVar = GetStructVariable(node, node.name);
610623

611624
if (GlobalExists(name)) {
612-
PushGlobalValue(node, GetGlobal(name), structVar.size, structVar.offset, true);
625+
auto var = GetGlobal(name);
626+
627+
PushGlobalValue(
628+
node, var, structVar.size, structVar.offset, true, var.type.ptr
629+
);
613630
}
614631
else if (VariableExists(name)) {
615-
PushVariableValue(node, GetVariable(name), structVar.size, structVar.offset, true);
632+
auto var = GetVariable(name);
633+
634+
PushVariableValue(
635+
node, var, structVar.size, structVar.offset, true, var.type.ptr
636+
);
616637
}
617638
}
618639
else if (node.name in consts) {
@@ -1247,74 +1268,110 @@ class BackendX86_64 : CompilerBackend {
12471268
variables = [];
12481269
}
12491270

1250-
void SetVariable(Node node, Variable var, size_t size = 0, size_t offset = 0, bool member = false) {
1271+
void SetVariable(
1272+
Node node, Variable var, size_t size = 0, size_t offset = 0, bool member = false,
1273+
bool deref = false
1274+
) {
12511275
if (size == 0) {
1252-
size = var.type.size;
1276+
size = var.type.Size();
12531277
}
12541278

12551279
output ~= "sub r15, 8\n";
12561280
output ~= "mov rax, [r15]\n";
12571281

1258-
if (var.type.isStruct && !member) {
1259-
Error(node.error, "Can't set struct value");
1260-
}
1282+
if (deref) {
1283+
output ~= format("mov rbx, [rsp + %d]\n", var.offset);
12611284

1262-
switch (size) {
1263-
case 1: output ~= format("mov [rsp + %d], al\n", var.offset + offset); break;
1264-
case 2: output ~= format("mov [rsp + %d], ax\n", var.offset + offset); break;
1265-
case 4: output ~= format("mov [rsp + %d], eax\n", var.offset + offset); break;
1266-
case 8: output ~= format("mov [rsp + %d], rax\n", var.offset + offset); break;
1267-
default: Error(node.error, "Bad variable type size");
1285+
switch (size) {
1286+
case 1: output ~= format("mov [rbx + %d], al\n", offset); break;
1287+
case 2: output ~= format("mov [rbx + %d], ax\n", offset); break;
1288+
case 4: output ~= format("mov [rbx + %d], eax\n", offset); break;
1289+
case 8: output ~= format("mov [rbx + %d], rax\n", offset); break;
1290+
default: Error(node.error, "Bad variable type size");
1291+
}
1292+
}
1293+
else {
1294+
switch (size) {
1295+
case 1: output ~= format("mov [rsp + %d], al\n", var.offset + offset); break;
1296+
case 2: output ~= format("mov [rsp + %d], ax\n", var.offset + offset); break;
1297+
case 4: output ~= format("mov [rsp + %d], eax\n", var.offset + offset); break;
1298+
case 8: output ~= format("mov [rsp + %d], rax\n", var.offset + offset); break;
1299+
default: Error(node.error, "Bad variable type size");
1300+
}
12681301
}
12691302
}
12701303

12711304
void SetGlobal(
12721305
Node node, Global global, size_t size = 0, size_t offset = 0,
1273-
bool member = false
1306+
bool member = false, bool deref = false
12741307
) {
12751308
if (size == 0) {
1276-
size = global.type.size;
1309+
size = global.type.Size();
12771310
}
12781311

12791312
output ~= "sub r15, 8\n";
12801313
output ~= "mov rax, [r15]\n";
12811314

1282-
if (global.type.isStruct && !member) {
1283-
Error(node.error, "Can't set struct value");
1284-
}
1285-
12861315
string symbol = format("__global_%s", global.name.Sanitise());
12871316

1288-
if (size != 8) {
1289-
output ~= "xor rbx, rbx\n";
1290-
output ~= format("mov [%s + %d], rbx\n", symbol, offset);
1291-
}
1317+
if (deref) {
1318+
output ~= format("mov rbx, [%s]\n", symbol);
12921319

1293-
switch (size) {
1294-
case 1: output ~= format("mov [%s + %d], al\n", symbol, offset); break;
1295-
case 2: output ~= format("mov [%s + %d], ax\n", symbol, offset); break;
1296-
case 4: output ~= format("mov [%s + %d], eax\n", symbol, offset); break;
1297-
case 8: output ~= format("mov [%s + %d], rax\n", symbol, offset); break;
1298-
default: Error(node.error, "Bad variable type size");
1320+
switch (size) {
1321+
case 1: output ~= format("mov [rbx + %d], al\n", offset); break;
1322+
case 2: output ~= format("mov [rbx + %d], ax\n", offset); break;
1323+
case 4: output ~= format("mov [rbx + %d], eax\n", offset); break;
1324+
case 8: output ~= format("mov [rbx + %d], rax\n", offset); break;
1325+
default: Error(node.error, "Bad variable type size");
1326+
}
1327+
}
1328+
else {
1329+
switch (size) {
1330+
case 1: output ~= format("mov [%s + %d], al\n", symbol, offset); break;
1331+
case 2: output ~= format("mov [%s + %d], ax\n", symbol, offset); break;
1332+
case 4: output ~= format("mov [%s + %d], eax\n", symbol, offset); break;
1333+
case 8: output ~= format("mov [%s + %d], rax\n", symbol, offset); break;
1334+
default: Error(node.error, "Bad variable type size");
1335+
}
12991336
}
13001337
}
13011338

13021339
override void CompileSet(SetNode node) {
13031340
if (VariableExists(node.var)) {
1304-
SetVariable(node, GetVariable(node.var));
1341+
auto var = GetVariable(node.var);
1342+
1343+
if (var.type.isStruct && !var.type.ptr) {
1344+
Error(node.error, "Can't set struct value");
1345+
}
1346+
1347+
SetVariable(node, var);
13051348
}
13061349
else if (GlobalExists(node.var)) {
1350+
auto var = GetGlobal(node.var);
1351+
1352+
if (var.type.isStruct && !var.type.ptr) {
1353+
Error(node.error, "Can't set struct value");
1354+
}
1355+
13071356
SetGlobal(node, GetGlobal(node.var));
13081357
}
13091358
else if (IsStructMember(node.var)) {
13101359
string name = node.var[0 .. node.var.countUntil(".")];
13111360
auto structVar = GetStructVariable(node, node.var);
13121361

13131362
if (VariableExists(name)) {
1314-
SetVariable(node, GetVariable(name), structVar.size, structVar.offset, true);
1363+
auto var = GetVariable(name);
1364+
1365+
SetVariable(
1366+
node, var, structVar.size, structVar.offset, true, var.type.ptr
1367+
);
13151368
}
13161369
else if (GlobalExists(name)) {
1317-
SetGlobal(node, GetGlobal(name), structVar.size, structVar.offset, true);
1370+
auto var = GetGlobal(name);
1371+
1372+
SetGlobal(
1373+
node, var, structVar.size, structVar.offset, true, var.type.ptr
1374+
);
13181375
}
13191376
}
13201377
else {

source/stackCheck.d

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,10 @@ class StackChecker {
118118
Pop(node, word.effect.pop);
119119
Push(node, word.effect.push);
120120
}
121-
else if (identifiers.canFind(node.name)) {
121+
else if (
122+
identifiers.canFind(node.name) ||
123+
identifiers.canFind(node.name.split('.')[0])
124+
) {
122125
Push(node, 1);
123126
}
124127
else {

0 commit comments

Comments
 (0)