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;
|
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);
|
||||||
}
|
}
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user