public void CGenDecln(Env env, CGenState state) { // .text // [.globl <func>] // <func>: // pushl %ebp // movl %esp, %ebp // state.TEXT(); Env.Entry entry = env.Find(this.name).Value; state.COMMENT(ToString()); switch (entry.Kind) { case Env.EntryKind.GLOBAL: switch (this.scs) { case StorageClass.AUTO: case StorageClass.EXTERN: state.GLOBL(this.name); break; case StorageClass.STATIC: // static definition break; default: throw new InvalidOperationException(); } break; default: throw new InvalidOperationException(); } state.CGenFuncStart(this.name); state.InFunction(GotoLabelsGrabber.GrabLabels(this.stmt)); this.stmt.CGenStmt(env, state); state.CGenLabel(state.ReturnLabel); state.OutFunction(); // leave // ret state.LEAVE(); state.RET(); state.NEWLINE(); }
public override void CGenAddress(CGenState state) { Env.Entry entry = this.Env.Find(this.Name).Value; Int32 offset = entry.Offset; switch (entry.Kind) { case Env.EntryKind.FRAME: case Env.EntryKind.STACK: state.LEA(offset, Reg.EBP, Reg.EAX); return; case Env.EntryKind.GLOBAL: state.LEA(this.Name, Reg.EAX); return; case Env.EntryKind.ENUM: case Env.EntryKind.TYPEDEF: default: throw new InvalidProgramException("cannot get the address of " + entry.Kind); } }
public override Reg CGenValue(CGenState state) { Env.Entry entry = this.Env.Find(this.Name).Value; Int32 offset = entry.Offset; //if (entry.Kind == Env.EntryKind.STACK) { // offset = -offset; //} switch (entry.Kind) { case Env.EntryKind.ENUM: // 1. If the variable is an enum constant, // return the Value in %eax. state.MOVL(offset, Reg.EAX); return(Reg.EAX); case Env.EntryKind.FRAME: case Env.EntryKind.STACK: // 2. If the variable is a function argument or a local variable, // the address would be offset(%ebp). switch (this.Type.Kind) { case ExprTypeKind.LONG: case ExprTypeKind.ULONG: case ExprTypeKind.POINTER: // %eax = offset(%ebp) state.MOVL(offset, Reg.EBP, Reg.EAX); return(Reg.EAX); case ExprTypeKind.FLOAT: // %st(0) = offset(%ebp) state.FLDS(offset, Reg.EBP); return(Reg.ST0); case ExprTypeKind.DOUBLE: // %st(0) = offset(%ebp) state.FLDL(offset, Reg.EBP); return(Reg.ST0); case ExprTypeKind.STRUCT_OR_UNION: // %eax = address state.LEA(offset, Reg.EBP, Reg.EAX); return(Reg.EAX); //state.LEA(offset, Reg.EBP, Reg.ESI); // source address //state.CGenExpandStackBy(Utils.RoundUp(Type.SizeOf, 4)); //state.LEA(0, Reg.ESP, Reg.EDI); // destination address //state.MOVL(Type.SizeOf, Reg.ECX); // nbytes //state.CGenMemCpy(); //return Reg.STACK; case ExprTypeKind.VOID: throw new InvalidProgramException("How could a variable be void?"); // %eax = $0 // state.MOVL(0, Reg.EAX); // return Reg.EAX; case ExprTypeKind.FUNCTION: throw new InvalidProgramException("How could a variable be a function designator?"); // %eax = function_name // state.MOVL(name, Reg.EAX); // return Reg.EAX; case ExprTypeKind.CHAR: // %eax = [char -> long](off(%ebp)) state.MOVSBL(offset, Reg.EBP, Reg.EAX); return(Reg.EAX); case ExprTypeKind.UCHAR: // %eax = [uchar -> ulong](off(%ebp)) state.MOVZBL(offset, Reg.EBP, Reg.EAX); return(Reg.EAX); case ExprTypeKind.SHORT: // %eax = [short -> long](off(%ebp)) state.MOVSWL(offset, Reg.EBP, Reg.EAX); return(Reg.EAX); case ExprTypeKind.USHORT: // %eax = [ushort -> ulong](off(%ebp)) state.MOVZWL(offset, Reg.EBP, Reg.EAX); return(Reg.EAX); case ExprTypeKind.ARRAY: // %eax = (off(%ebp)) state.LEA(offset, Reg.EBP, Reg.EAX); // source address return(Reg.EAX); default: throw new InvalidOperationException($"Cannot get value of {this.Type.Kind}"); } case Env.EntryKind.GLOBAL: switch (this.Type.Kind) { case ExprTypeKind.CHAR: state.MOVSBL(this.Name, Reg.EAX); return(Reg.EAX); case ExprTypeKind.UCHAR: state.MOVZBL(this.Name, Reg.EAX); return(Reg.EAX); case ExprTypeKind.SHORT: state.MOVSWL(this.Name, Reg.EAX); return(Reg.EAX); case ExprTypeKind.USHORT: state.MOVZWL(this.Name, Reg.EAX); return(Reg.EAX); case ExprTypeKind.LONG: case ExprTypeKind.ULONG: case ExprTypeKind.POINTER: state.MOVL(this.Name, Reg.EAX); return(Reg.EAX); case ExprTypeKind.FUNCTION: state.MOVL("$" + this.Name, Reg.EAX); return(Reg.EAX); case ExprTypeKind.FLOAT: state.FLDS(this.Name); return(Reg.ST0); case ExprTypeKind.DOUBLE: state.FLDL(this.Name); return(Reg.ST0); case ExprTypeKind.STRUCT_OR_UNION: state.MOVL($"${this.Name}", Reg.EAX); return(Reg.EAX); //state.LEA(name, Reg.ESI); // source address //state.CGenExpandStackBy(Utils.RoundUp(Type.SizeOf, 4)); //state.LEA(0, Reg.ESP, Reg.EDI); // destination address //state.MOVL(Type.SizeOf, Reg.ECX); // nbytes //state.CGenMemCpy(); //return Reg.STACK; case ExprTypeKind.VOID: throw new InvalidProgramException("How could a variable be void?"); //state.MOVL(0, Reg.EAX); //return Reg.EAX; case ExprTypeKind.ARRAY: state.MOVL($"${this.Name}", Reg.EAX); return(Reg.EAX); default: throw new InvalidProgramException("cannot get the Value of a " + this.Type.Kind); } case Env.EntryKind.TYPEDEF: default: throw new InvalidProgramException("cannot get the Value of a " + entry.Kind); } }