Skip to content

Commit a9c815e

Browse files
authored
Merge pull request #32 from soxfox42/Pointers
Pointers on arm64
2 parents a62445b + 7f1c8fd commit a9c815e

File tree

1 file changed

+81
-37
lines changed

1 file changed

+81
-37
lines changed

source/backends/arm64.d

Lines changed: 81 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ class BackendARM64 : CompilerBackend {
4343
bool useLibc;
4444

4545
this() {
46+
addrSize = 8;
47+
4648
version (linux) {
4749
defaultOS = "linux";
4850
}
@@ -363,17 +365,20 @@ class BackendARM64 : CompilerBackend {
363365
}
364366
}
365367

366-
void PushGlobalValue(Node node, Global var, size_t size = 0, size_t offset = 0, bool member = false) {
368+
void PushGlobalValue(
369+
Node node, Global var, size_t size = 0, size_t offset = 0,
370+
bool member = false, bool deref = false
371+
) {
367372
if (size == 0) {
368-
size = var.type.size;
369-
}
370-
371-
if (var.type.isStruct && !member) {
372-
Error(node.error, "Can't push value of struct");
373+
size = var.type.Size();
373374
}
374375

375376
LoadAddress("x9", format("__global_%s", var.name.Sanitise()));
376377

378+
if (deref) {
379+
output ~= "ldr x9, [x9]\n";
380+
}
381+
377382
switch (size) {
378383
case 1: output ~= format("ldrb w9, [x9, #%d]\n", offset); break;
379384
case 2: output ~= format("ldrh w9, [x9, #%d]\n", offset); break;
@@ -385,22 +390,32 @@ class BackendARM64 : CompilerBackend {
385390
output ~= "str x9, [x19], #8\n";
386391
}
387392

388-
void PushVariableValue(Node node, Variable var, size_t size = 0, size_t offset = 0, bool member = false) {
393+
void PushVariableValue(
394+
Node node, Variable var, size_t size = 0, size_t offset = 0,
395+
bool member = false, bool deref = false
396+
) {
389397
if (size == 0) {
390-
size = var.type.size;
398+
size = var.type.Size();
391399
}
392400

393401
if (var.type.isStruct && !member) {
394402
Error(node.error, "Can't push value of struct");
395403
}
396404

397-
offset += var.offset;
405+
string base;
406+
if (deref) {
407+
output ~= format("ldr x9, [x20, #%d]\n", var.offset);
408+
base = "x9";
409+
} else {
410+
offset += var.offset;
411+
base = "x20";
412+
}
398413

399414
switch (size) {
400-
case 1: output ~= format("ldrb w9, [x20, #%d]\n", offset); break;
401-
case 2: output ~= format("ldrh w9, [x20, #%d]\n", offset); break;
402-
case 4: output ~= format("ldr w9, [x20, #%d]\n", offset); break;
403-
case 8: output ~= format("ldr x9, [x20, #%d]\n", offset); break;
415+
case 1: output ~= format("ldrb w9, [%s, #%d]\n", base, offset); break;
416+
case 2: output ~= format("ldrh w9, [%s, #%d]\n", base, offset); break;
417+
case 4: output ~= format("ldr w9, [%s, #%d]\n", base, offset); break;
418+
case 8: output ~= format("ldr x9, [%s, #%d]\n", base, offset); break;
404419
default: Error(node.error, "Bad variable type size");
405420
}
406421

@@ -533,20 +548,30 @@ class BackendARM64 : CompilerBackend {
533548
}
534549
}
535550
else if (VariableExists(node.name)) {
536-
PushVariableValue(node, GetVariable(node.name));
551+
auto var = GetVariable(node.name);
552+
if (var.type.isStruct && !var.type.ptr) {
553+
Error(node.error, "Can't push struct value");
554+
}
555+
PushVariableValue(node, var);
537556
}
538557
else if (GlobalExists(node.name)) {
539-
PushGlobalValue(node, GetGlobal(node.name));
558+
auto var = GetGlobal(node.name);
559+
if (var.type.isStruct && !var.type.ptr) {
560+
Error(node.error, "Can't push struct value");
561+
}
562+
PushGlobalValue(node, var);
540563
}
541564
else if (IsStructMember(node.name)) {
542565
string name = node.name[0 .. node.name.countUntil(".")];
543566
auto structVar = GetStructVariable(node, node.name);
544567

545568
if (GlobalExists(name)) {
546-
PushGlobalValue(node, GetGlobal(name), structVar.size, structVar.offset, true);
569+
auto var = GetGlobal(name);
570+
PushGlobalValue(node, var, structVar.size, structVar.offset, true, var.type.ptr);
547571
}
548572
else if (VariableExists(name)) {
549-
PushVariableValue(node, GetVariable(name), structVar.size, structVar.offset, true);
573+
auto var = GetVariable(name);
574+
PushVariableValue(node, var, structVar.size, structVar.offset, true, var.type.ptr);
550575
}
551576
}
552577
else if (node.name in consts) {
@@ -1157,41 +1182,50 @@ class BackendARM64 : CompilerBackend {
11571182
variables = [];
11581183
}
11591184

1160-
void SetVariable(Node node, Variable var, size_t size = 0, size_t offset = 0, bool member = false) {
1185+
void SetVariable(
1186+
Node node, Variable var, size_t size = 0, size_t offset = 0,
1187+
bool member = false, bool deref = false
1188+
) {
11611189
if (size == 0) {
1162-
size = var.type.size;
1190+
size = var.type.Size();
11631191
}
11641192

11651193
output ~= "ldr x9, [x19, #-8]!\n";
11661194

1167-
if (var.type.isStruct && !member) {
1168-
Error(node.error, "Can't set struct value");
1195+
string base;
1196+
if (deref) {
1197+
output ~= format("ldr x10, [x20, #%d]\n", var.offset);
1198+
base = "x10";
1199+
} else {
1200+
offset += var.offset;
1201+
base = "x20";
11691202
}
11701203

1171-
offset += var.offset;
1172-
11731204
switch (size) {
1174-
case 1: output ~= format("strb w9, [x20, #%d]\n", offset); break;
1175-
case 2: output ~= format("strh w9, [x20, #%d]\n", offset); break;
1176-
case 4: output ~= format("str w9, [x20, #%d]\n", offset); break;
1177-
case 8: output ~= format("str x9, [x20, #%d]\n", offset); break;
1205+
case 1: output ~= format("strb w9, [%s, #%d]\n", base, offset); break;
1206+
case 2: output ~= format("strh w9, [%s, #%d]\n", base, offset); break;
1207+
case 4: output ~= format("str w9, [%s, #%d]\n", base, offset); break;
1208+
case 8: output ~= format("str x9, [%s, #%d]\n", base, offset); break;
11781209
default: Error(node.error, "Bad variable type size");
11791210
}
11801211
}
11811212

1182-
void SetGlobal(Node node, Global global, size_t size = 0, size_t offset = 0, bool member = false) {
1213+
void SetGlobal(
1214+
Node node, Global global, size_t size = 0, size_t offset = 0,
1215+
bool member = false, bool deref = false
1216+
) {
11831217
if (size == 0) {
1184-
size = global.type.size;
1218+
size = global.type.Size();
11851219
}
11861220

11871221
output ~= "ldr x9, [x19, #-8]!\n";
11881222

1189-
if (global.type.isStruct && !member) {
1190-
Error(node.error, "Can't set struct value");
1191-
}
1192-
11931223
LoadAddress("x10", format("__global_%s", global.name.Sanitise()));
11941224

1225+
if (deref) {
1226+
output ~= "ldr x10, [x10]\n";
1227+
}
1228+
11951229
switch (size) {
11961230
case 1: output ~= format("strb w9, [x10, #%d]\n", offset); break;
11971231
case 2: output ~= format("strh w9, [x10, #%d]\n", offset); break;
@@ -1203,20 +1237,30 @@ class BackendARM64 : CompilerBackend {
12031237

12041238
override void CompileSet(SetNode node) {
12051239
if (VariableExists(node.var)) {
1206-
SetVariable(node, GetVariable(node.var));
1240+
auto var = GetVariable(node.var);
1241+
if (var.type.isStruct && !var.type.ptr) {
1242+
Error(node.error, "Can't set struct value");
1243+
}
1244+
SetVariable(node, var);
12071245
}
12081246
else if (GlobalExists(node.var)) {
1209-
SetGlobal(node, GetGlobal(node.var));
1247+
auto var = GetGlobal(node.var);
1248+
if (var.type.isStruct && !var.type.ptr) {
1249+
Error(node.error, "Can't set struct value");
1250+
}
1251+
SetGlobal(node, var);
12101252
}
12111253
else if (IsStructMember(node.var)) {
12121254
string name = node.var[0 .. node.var.countUntil(".")];
12131255
auto structVar = GetStructVariable(node, node.var);
12141256

12151257
if (VariableExists(name)) {
1216-
SetVariable(node, GetVariable(name), structVar.size, structVar.offset, true);
1258+
auto var = GetVariable(name);
1259+
SetVariable(node, var, structVar.size, structVar.offset, true, var.type.ptr);
12171260
}
12181261
else if (GlobalExists(name)) {
1219-
SetGlobal(node, GetGlobal(name), structVar.size, structVar. offset, true);
1262+
auto var = GetGlobal(name);
1263+
SetGlobal(node, var, structVar.size, structVar. offset, true, var.type.ptr);
12201264
}
12211265
}
12221266
else {

0 commit comments

Comments
 (0)