Working local variables.

Next up: multiple function parameters..
This commit is contained in:
Curle 2020-11-30 20:01:00 +00:00
parent 384f46054a
commit 39ee1b6028
Signed by: TheCurle
GPG Key ID: 5942F13718443F79
3 changed files with 43 additions and 28 deletions

View File

@ -110,15 +110,17 @@ int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) {
return Node->RVal ? AsDeref(LeftVal, Node->Left->ExprType) : LeftVal;
case OP_ASSIGN:
printf("Calculating for assignment..\r\n");
printf("Preparing for assignment..\r\n");
if(Node->Right == NULL)
Die("Fault in assigning a null rvalue");
printf("\tCalculating assignment for target %s:%d\r\n", Symbols[Node->Right->Value.ID].Name, Node->Right->Value.ID);
switch(Node->Right->Operation) {
case REF_IDENT:
if(Symbols[Node->Value.ID].Storage == SC_LOCAL)
return AsStrLocalVar(Node->Value.ID, Node->Operation);
if(Symbols[Node->Right->Value.ID].Storage == SC_LOCAL)
return AsStrLocalVar(LeftVal, Node->Right->Value.ID);
else
return AsStrGlobalVar(Node->Value.ID, Node->Operation);
return AsStrGlobalVar(LeftVal, Node->Right->Value.ID);
case OP_DEREF: return AsStrDeref(LeftVal, RightVal, Node->Right->ExprType);
default: DieDecimal("Can't ASSIGN in AssembleTree: ", Node->Operation);
@ -570,18 +572,18 @@ int AsLdLocalVar(int ID, int Operation) {
case RET_CHAR:
switch(Operation) {
case OP_PREINC:
fprintf(OutputFile, "\tincb\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break;
fprintf(OutputFile, "\tincb\t%d(\%%rbp)\n", Symbols[ID].SinkOffset); break;
case OP_PREDEC:
fprintf(OutputFile, "\tdecb\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break;
fprintf(OutputFile, "\tdecb\t%d(\%%rbp)\n", Symbols[ID].SinkOffset); break;
}
fprintf(OutputFile, "\tmovzbq\t%d(\%%rip), %s\n", Symbols[ID].SinkOffset, Registers[Reg]);
fprintf(OutputFile, "\tmovzbq\t%d(\%%rbp), %s\n", Symbols[ID].SinkOffset, Registers[Reg]);
switch(Operation) {
case OP_POSTINC:
fprintf(OutputFile, "\tincb\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break;
fprintf(OutputFile, "\tincb\t%d(\%%rbp)\n", Symbols[ID].SinkOffset); break;
case OP_POSTDEC:
fprintf(OutputFile, "\tdecb\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break;
fprintf(OutputFile, "\tdecb\t%d(\%%rbp)\n", Symbols[ID].SinkOffset); break;
}
break;
@ -589,18 +591,18 @@ int AsLdLocalVar(int ID, int Operation) {
case RET_INT:
switch(Operation) {
case OP_PREINC:
fprintf(OutputFile, "\tincl\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break;
fprintf(OutputFile, "\tincl\t%d(\%%rbp)\n", Symbols[ID].SinkOffset); break;
case OP_PREDEC:
fprintf(OutputFile, "\tdecl\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break;
fprintf(OutputFile, "\tdecl\t%d(\%%rbp)\n", Symbols[ID].SinkOffset); break;
}
fprintf(OutputFile, "\tmovslq\t%d(\%%rip), %s\n", Symbols[ID].SinkOffset, Registers[Reg]);
fprintf(OutputFile, "\tmovslq\t%d(\%%rbp), %s\n", Symbols[ID].SinkOffset, Registers[Reg]);
switch(Operation) {
case OP_POSTINC:
fprintf(OutputFile, "\tincl\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break;
fprintf(OutputFile, "\tincl\t%d(\%%rbp)\n", Symbols[ID].SinkOffset); break;
case OP_POSTDEC:
fprintf(OutputFile, "\tdecl\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break;
fprintf(OutputFile, "\tdecl\t%d(\%%rbp)\n", Symbols[ID].SinkOffset); break;
}
break;
@ -611,18 +613,18 @@ int AsLdLocalVar(int ID, int Operation) {
case PTR_VOID:
switch(Operation) {
case OP_PREINC:
fprintf(OutputFile, "\tincq\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break;
fprintf(OutputFile, "\tincq\t%d(\%%rbp)\n", Symbols[ID].SinkOffset); break;
case OP_PREDEC:
fprintf(OutputFile, "\tdecq\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break;
fprintf(OutputFile, "\tdecq\t%d(\%%rbp)\n", Symbols[ID].SinkOffset); break;
}
fprintf(OutputFile, "\tmovq\t%d(\%%rip), %s\n", Symbols[ID].SinkOffset, Registers[Reg]);
fprintf(OutputFile, "\tmovq\t%d(\%%rbp), %s\n", Symbols[ID].SinkOffset, Registers[Reg]);
switch(Operation) {
case OP_POSTINC:
fprintf(OutputFile, "\tincq\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break;
fprintf(OutputFile, "\tincq\t%d(\%%rbp)\n", Symbols[ID].SinkOffset); break;
case OP_POSTDEC:
fprintf(OutputFile, "\tdecq\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break;
fprintf(OutputFile, "\tdecq\t%d(\%%rbp)\n", Symbols[ID].SinkOffset); break;
}
break;
@ -640,11 +642,11 @@ int AsStrLocalVar(int Register, int ID) {
switch(Symbols[ID].Type) {
case RET_CHAR:
// movzbq zeroes, then moves a byte into the quad register
fprintf(OutputFile, "\tmovb\t%s, %d(\%%rip)\n", ByteRegisters[Register], Symbols[ID].SinkOffset);
fprintf(OutputFile, "\tmovb\t%s, %d(\%%rbp)\n", ByteRegisters[Register], Symbols[ID].SinkOffset);
break;
case RET_INT:
fprintf(OutputFile, "\tmovl\t%s, %d(\%%rip)\n", DoubleRegisters[Register], Symbols[ID].SinkOffset);
fprintf(OutputFile, "\tmovl\t%s, %d(\%%rbp)\n", DoubleRegisters[Register], Symbols[ID].SinkOffset);
break;
case RET_LONG:
@ -652,7 +654,7 @@ int AsStrLocalVar(int Register, int ID) {
case PTR_INT:
case PTR_LONG:
case PTR_VOID:
fprintf(OutputFile, "\tmovq\t%s, %d(%%rip)\n", Registers[Register], Symbols[ID].SinkOffset);
fprintf(OutputFile, "\tmovq\t%s, %d(%%rbp)\n", Registers[Register], Symbols[ID].SinkOffset);
break;
default:
@ -886,7 +888,7 @@ void AssemblerPreamble() {
void AsFunctionPreamble(int FunctionID) {
char* Name = Symbols[FunctionID].Name;
StackFrameOffset = (LocalVarOffset + 15) & ~15;
StackFrameOffset = (LocalVarOffset + 31) & ~31;
fprintf(OutputFile,
"\t.text\n"
@ -895,7 +897,7 @@ void AsFunctionPreamble(int FunctionID) {
"%s:\n"
"\tpushq\t%%rbp\n"
"\tmovq\t%%rsp, %%rbp\n"
"\taddq\t%d, %%rsp\n", Name, Name, Name, -StackFrameOffset);
"\taddq\t$%d, %%rsp\n", Name, Name, Name, -StackFrameOffset);
//PECOFF requires we call the global initialisers
if(!strcmp(Name, "main"))
@ -906,8 +908,8 @@ void AsFunctionEpilogue(int FunctionID) {
AsLabel(Symbols[FunctionID].EndLabel);
fprintf(OutputFile,
"\tpopq\t%rbp\n"
"\taddq\t%d, %rsp\n"
"\tpopq\t%%rbp\n"
"\taddq\t$%d, %%rsp\n"
"\tret\n",
StackFrameOffset);
}

View File

@ -106,9 +106,7 @@ int AddSymbol(char* Name, int Type, int Structure, int Storage, int EndLabel, in
// we can use this switch to avoid duplicated code.
switch(Storage) {
case SC_GLOBAL:
printf("\tCreating new global symbol %s\r\n", Name);
TableSlot = NewGlobalSymbol();
AsGlobalSymbol(TableSlot);
break;
case SC_LOCAL:
printf("\tCreating new local symbol %s\r\n", Name);
@ -124,6 +122,19 @@ int AddSymbol(char* Name, int Type, int Structure, int Storage, int EndLabel, in
Symbols[TableSlot].Length = Length;
Symbols[TableSlot].SinkOffset = SinkOffset;
// NOTE: Generating global symbol names must happen AFTER the name and type are declared.
switch(Storage) {
case SC_GLOBAL:
printf("\tCreating new global symbol %s into slot %d\r\n", Name, TableSlot);
if(Structure != ST_FUNC) {
printf("\t\tGenerating data symbol.\r\n");
AsGlobalSymbol(TableSlot);
}
break;
case SC_LOCAL:
break;
}
//printf("Adding new variable %s of type %s to the table at %d\n", CurrentIdentifier, Types[Type], TableSlot);
return TableSlot;
}

View File

@ -6,5 +6,7 @@ int :: main()
x= 10; y= 20; z= 30;
a= 5; b= 15; c= 25;
PrintInteger(y);
return(0);
}