diff --git a/src/Assembler.c b/src/Assembler.c index bcd91d7..9357df1 100644 --- a/src/Assembler.c +++ b/src/Assembler.c @@ -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); } \ No newline at end of file diff --git a/src/Symbols.c b/src/Symbols.c index 7b6918e..493c036 100644 --- a/src/Symbols.c +++ b/src/Symbols.c @@ -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; } \ No newline at end of file diff --git a/tests/locals b/tests/locals index 22df4cf..e917cd0 100644 --- a/tests/locals +++ b/tests/locals @@ -6,5 +6,7 @@ int :: main() x= 10; y= 20; z= 30; a= 5; b= 15; c= 25; + PrintInteger(y); + return(0); } \ No newline at end of file