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; return Node->RVal ? AsDeref(LeftVal, Node->Left->ExprType) : LeftVal;
case OP_ASSIGN: case OP_ASSIGN:
printf("Calculating for assignment..\r\n"); printf("Preparing for assignment..\r\n");
if(Node->Right == NULL) if(Node->Right == NULL)
Die("Fault in assigning a null rvalue"); 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) { switch(Node->Right->Operation) {
case REF_IDENT: case REF_IDENT:
if(Symbols[Node->Value.ID].Storage == SC_LOCAL) if(Symbols[Node->Right->Value.ID].Storage == SC_LOCAL)
return AsStrLocalVar(Node->Value.ID, Node->Operation); return AsStrLocalVar(LeftVal, Node->Right->Value.ID);
else 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); case OP_DEREF: return AsStrDeref(LeftVal, RightVal, Node->Right->ExprType);
default: DieDecimal("Can't ASSIGN in AssembleTree: ", Node->Operation); default: DieDecimal("Can't ASSIGN in AssembleTree: ", Node->Operation);
@ -570,18 +572,18 @@ int AsLdLocalVar(int ID, int Operation) {
case RET_CHAR: case RET_CHAR:
switch(Operation) { switch(Operation) {
case OP_PREINC: 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: 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) { switch(Operation) {
case OP_POSTINC: 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: 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; break;
@ -589,18 +591,18 @@ int AsLdLocalVar(int ID, int Operation) {
case RET_INT: case RET_INT:
switch(Operation) { switch(Operation) {
case OP_PREINC: 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: 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) { switch(Operation) {
case OP_POSTINC: 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: 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; break;
@ -611,18 +613,18 @@ int AsLdLocalVar(int ID, int Operation) {
case PTR_VOID: case PTR_VOID:
switch(Operation) { switch(Operation) {
case OP_PREINC: 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: 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) { switch(Operation) {
case OP_POSTINC: 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: 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; break;
@ -640,11 +642,11 @@ int AsStrLocalVar(int Register, int ID) {
switch(Symbols[ID].Type) { switch(Symbols[ID].Type) {
case RET_CHAR: case RET_CHAR:
// movzbq zeroes, then moves a byte into the quad register // 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; break;
case RET_INT: 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; break;
case RET_LONG: case RET_LONG:
@ -652,7 +654,7 @@ int AsStrLocalVar(int Register, int ID) {
case PTR_INT: case PTR_INT:
case PTR_LONG: case PTR_LONG:
case PTR_VOID: 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; break;
default: default:
@ -886,7 +888,7 @@ void AssemblerPreamble() {
void AsFunctionPreamble(int FunctionID) { void AsFunctionPreamble(int FunctionID) {
char* Name = Symbols[FunctionID].Name; char* Name = Symbols[FunctionID].Name;
StackFrameOffset = (LocalVarOffset + 15) & ~15; StackFrameOffset = (LocalVarOffset + 31) & ~31;
fprintf(OutputFile, fprintf(OutputFile,
"\t.text\n" "\t.text\n"
@ -895,7 +897,7 @@ void AsFunctionPreamble(int FunctionID) {
"%s:\n" "%s:\n"
"\tpushq\t%%rbp\n" "\tpushq\t%%rbp\n"
"\tmovq\t%%rsp, %%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 //PECOFF requires we call the global initialisers
if(!strcmp(Name, "main")) if(!strcmp(Name, "main"))
@ -906,8 +908,8 @@ void AsFunctionEpilogue(int FunctionID) {
AsLabel(Symbols[FunctionID].EndLabel); AsLabel(Symbols[FunctionID].EndLabel);
fprintf(OutputFile, fprintf(OutputFile,
"\tpopq\t%rbp\n" "\tpopq\t%%rbp\n"
"\taddq\t%d, %rsp\n" "\taddq\t$%d, %%rsp\n"
"\tret\n", "\tret\n",
StackFrameOffset); 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. // we can use this switch to avoid duplicated code.
switch(Storage) { switch(Storage) {
case SC_GLOBAL: case SC_GLOBAL:
printf("\tCreating new global symbol %s\r\n", Name);
TableSlot = NewGlobalSymbol(); TableSlot = NewGlobalSymbol();
AsGlobalSymbol(TableSlot);
break; break;
case SC_LOCAL: case SC_LOCAL:
printf("\tCreating new local symbol %s\r\n", Name); 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].Length = Length;
Symbols[TableSlot].SinkOffset = SinkOffset; 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); //printf("Adding new variable %s of type %s to the table at %d\n", CurrentIdentifier, Types[Type], TableSlot);
return TableSlot; return TableSlot;
} }

View File

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