Working local variables.
Next up: multiple function parameters..
This commit is contained in:
parent
384f46054a
commit
39ee1b6028
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -6,5 +6,7 @@ int :: main()
|
|||
x= 10; y= 20; z= 30;
|
||||
a= 5; b= 15; c= 25;
|
||||
|
||||
PrintInteger(y);
|
||||
|
||||
return(0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user