/// <summary> /// flds addr /// </summary> public override Reg CGenValue(CGenState state) { byte[] bytes = BitConverter.GetBytes(this.Value); Int32 intval = BitConverter.ToInt32(bytes, 0); String name = state.CGenLongConst(intval); state.FLDS(name); return(Reg.ST0); }
public override Reg CGenValue(Env env, CGenState state) { Env.Entry entry = env.Find(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 (type.kind) { case ExprType.Kind.LONG: case ExprType.Kind.ULONG: case ExprType.Kind.POINTER: // %eax = offset(%ebp) state.MOVL(offset, Reg.EBP, Reg.EAX); return Reg.EAX; case ExprType.Kind.FLOAT: // %st(0) = offset(%ebp) state.FLDS(offset, Reg.EBP); return Reg.ST0; case ExprType.Kind.DOUBLE: // %st(0) = offset(%ebp) state.FLDL(offset, Reg.EBP); return Reg.ST0; case ExprType.Kind.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 ExprType.Kind.VOID: throw new InvalidProgramException("How could a variable be void?"); // %eax = $0 // state.MOVL(0, Reg.EAX); // return Reg.EAX; case ExprType.Kind.FUNCTION: throw new InvalidProgramException("How could a variable be a function designator?"); // %eax = function_name // state.MOVL(name, Reg.EAX); // return Reg.EAX; case ExprType.Kind.CHAR: // %eax = [char -> long](off(%ebp)) state.MOVSBL(offset, Reg.EBP, Reg.EAX); return Reg.EAX; case ExprType.Kind.UCHAR: // %eax = [uchar -> ulong](off(%ebp)) state.MOVZBL(offset, Reg.EBP, Reg.EAX); return Reg.EAX; case ExprType.Kind.SHORT: // %eax = [short -> long](off(%ebp)) state.MOVSWL(offset, Reg.EBP, Reg.EAX); return Reg.EAX; case ExprType.Kind.USHORT: // %eax = [ushort -> ulong](off(%ebp)) state.MOVZWL(offset, Reg.EBP, Reg.EAX); return Reg.EAX; case ExprType.Kind.ARRAY: // %eax = (off(%ebp)) state.LEA(offset, Reg.EBP, Reg.EAX); // source address return Reg.EAX; default: throw new InvalidOperationException($"Cannot get value of {type.kind}"); } case Env.EntryKind.GLOBAL: switch (type.kind) { case ExprType.Kind.CHAR: state.MOVSBL(name, Reg.EAX); return Reg.EAX; case ExprType.Kind.UCHAR: state.MOVZBL(name, Reg.EAX); return Reg.EAX; case ExprType.Kind.SHORT: state.MOVSWL(name, Reg.EAX); return Reg.EAX; case ExprType.Kind.USHORT: state.MOVZWL(name, Reg.EAX); return Reg.EAX; case ExprType.Kind.LONG: case ExprType.Kind.ULONG: case ExprType.Kind.POINTER: state.MOVL(name, Reg.EAX); return Reg.EAX; case ExprType.Kind.FUNCTION: state.MOVL("$" + name, Reg.EAX); return Reg.EAX; case ExprType.Kind.FLOAT: state.FLDS(name); return Reg.ST0; case ExprType.Kind.DOUBLE: state.FLDL(name); return Reg.ST0; case ExprType.Kind.STRUCT_OR_UNION: state.MOVL($"${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 ExprType.Kind.VOID: throw new InvalidProgramException("How could a variable be void?"); //state.MOVL(0, Reg.EAX); //return Reg.EAX; case ExprType.Kind.ARRAY: state.MOVL($"${name}", Reg.EAX); return Reg.EAX; default: throw new InvalidProgramException("cannot get the value of a " + type.kind.ToString()); } case Env.EntryKind.TYPEDEF: default: throw new InvalidProgramException("cannot get the value of a " + entry.kind.ToString()); } }
public override Reg CGenValue(Env env, CGenState state) { Reg ret = expr.CGenValue(env, state); if (ret != Reg.EAX) { throw new InvalidProgramException(); } if (expr.type.kind != ExprType.Kind.POINTER) { throw new InvalidProgramException(); } ExprType type = ((TPointer)expr.type).ref_t; switch (type.kind) { case ExprType.Kind.ARRAY: case ExprType.Kind.FUNCTION: return Reg.EAX; case ExprType.Kind.CHAR: state.MOVSBL(0, Reg.EAX, Reg.EAX); return Reg.EAX; case ExprType.Kind.UCHAR: state.MOVZBL(0, Reg.EAX, Reg.EAX); return Reg.EAX; case ExprType.Kind.SHORT: state.MOVSWL(0, Reg.EAX, Reg.EAX); return Reg.EAX; case ExprType.Kind.USHORT: state.MOVZWL(0, Reg.EAX, Reg.EAX); return Reg.EAX; case ExprType.Kind.LONG: case ExprType.Kind.ULONG: case ExprType.Kind.POINTER: state.MOVL(0, Reg.EAX, Reg.EAX); return Reg.EAX; case ExprType.Kind.FLOAT: state.FLDS(0, Reg.EAX); return Reg.ST0; case ExprType.Kind.DOUBLE: state.FLDL(0, Reg.EAX); return Reg.ST0; case ExprType.Kind.STRUCT_OR_UNION: //// %esi = src address //state.MOVL(Reg.EAX, Reg.ESI); //// %edi = dst address //state.CGenExpandStackBy(Utils.RoundUp(type.SizeOf, 4)); //state.LEA(0, Reg.ESP, Reg.EDI); //// %ecx = nbytes //state.MOVL(type.SizeOf, Reg.ECX); //state.CGenMemCpy(); //return Reg.STACK; return Reg.EAX; case ExprType.Kind.VOID: default: throw new InvalidProgramException(); } }
public override Reg CGenValue(Env env, CGenState state) { // %eax is the address of the struct/union if (expr.CGenValue(env, state) != Reg.EAX) { throw new InvalidProgramException(); } if (expr.type.kind != ExprType.Kind.STRUCT_OR_UNION) { throw new InvalidProgramException(); } // size of the struct or union Int32 struct_size = expr.type.SizeOf; // offset inside the pack Int32 attrib_offset = ((TStructOrUnion)expr.type) .Attribs .First(_ => _.name == name) .offset; // can't be a function designator. switch (type.kind) { case ExprType.Kind.ARRAY: case ExprType.Kind.STRUCT_OR_UNION: state.ADDL(attrib_offset, Reg.EAX); return Reg.EAX; case ExprType.Kind.CHAR: state.MOVSBL(attrib_offset, Reg.EAX, Reg.EAX); return Reg.EAX; case ExprType.Kind.UCHAR: state.MOVZBL(attrib_offset, Reg.EAX, Reg.EAX); return Reg.EAX; case ExprType.Kind.SHORT: state.MOVSWL(attrib_offset, Reg.EAX, Reg.EAX); return Reg.EAX; case ExprType.Kind.USHORT: state.MOVZWL(attrib_offset, Reg.EAX, Reg.EAX); return Reg.EAX; case ExprType.Kind.LONG: case ExprType.Kind.ULONG: case ExprType.Kind.POINTER: state.MOVL(attrib_offset, Reg.EAX, Reg.EAX); return Reg.EAX; case ExprType.Kind.FLOAT: state.FLDS(attrib_offset, Reg.EAX); return Reg.ST0; case ExprType.Kind.DOUBLE: state.FLDL(attrib_offset, Reg.EAX); return Reg.ST0; default: throw new InvalidProgramException(); } }
public override Reg CGenValue(CGenState state) { Reg ret = this.Expr.CGenValue(state); if (ret != Reg.EAX) { throw new InvalidProgramException(); } if (this.Expr.Type.Kind != ExprTypeKind.POINTER) { throw new InvalidProgramException(); } ExprType type = ((PointerType)this.Expr.Type).RefType; switch (type.Kind) { case ExprTypeKind.ARRAY: case ExprTypeKind.FUNCTION: return(Reg.EAX); case ExprTypeKind.CHAR: state.MOVSBL(0, Reg.EAX, Reg.EAX); return(Reg.EAX); case ExprTypeKind.UCHAR: state.MOVZBL(0, Reg.EAX, Reg.EAX); return(Reg.EAX); case ExprTypeKind.SHORT: state.MOVSWL(0, Reg.EAX, Reg.EAX); return(Reg.EAX); case ExprTypeKind.USHORT: state.MOVZWL(0, Reg.EAX, Reg.EAX); return(Reg.EAX); case ExprTypeKind.LONG: case ExprTypeKind.ULONG: case ExprTypeKind.POINTER: state.MOVL(0, Reg.EAX, Reg.EAX); return(Reg.EAX); case ExprTypeKind.FLOAT: state.FLDS(0, Reg.EAX); return(Reg.ST0); case ExprTypeKind.DOUBLE: state.FLDL(0, Reg.EAX); return(Reg.ST0); case ExprTypeKind.STRUCT_OR_UNION: //// %esi = src address //state.MOVL(Reg.EAX, Reg.ESI); //// %edi = dst address //state.CGenExpandStackBy(Utils.RoundUp(Type.SizeOf, 4)); //state.LEA(0, Reg.ESP, Reg.EDI); //// %ecx = nbytes //state.MOVL(Type.SizeOf, Reg.ECX); //state.CGenMemCpy(); //return Reg.STACK; return(Reg.EAX); case ExprTypeKind.VOID: default: throw new InvalidProgramException(); } }
public override Reg CGenValue(CGenState state) { // %eax is the address of the struct/union if (this.Expr.CGenValue(state) != Reg.EAX) { throw new InvalidProgramException(); } if (this.Expr.Type.Kind != ExprTypeKind.STRUCT_OR_UNION) { throw new InvalidProgramException(); } // size of the struct or union Int32 struct_size = this.Expr.Type.SizeOf; // offset inside the pack Int32 attrib_offset = ((StructOrUnionType)this.Expr.Type) .Attribs .First(_ => _.name == this.Name) .offset; // can't be a function designator. switch (this.Type.Kind) { case ExprTypeKind.ARRAY: case ExprTypeKind.STRUCT_OR_UNION: state.ADDL(attrib_offset, Reg.EAX); return(Reg.EAX); case ExprTypeKind.CHAR: state.MOVSBL(attrib_offset, Reg.EAX, Reg.EAX); return(Reg.EAX); case ExprTypeKind.UCHAR: state.MOVZBL(attrib_offset, Reg.EAX, Reg.EAX); return(Reg.EAX); case ExprTypeKind.SHORT: state.MOVSWL(attrib_offset, Reg.EAX, Reg.EAX); return(Reg.EAX); case ExprTypeKind.USHORT: state.MOVZWL(attrib_offset, Reg.EAX, Reg.EAX); return(Reg.EAX); case ExprTypeKind.LONG: case ExprTypeKind.ULONG: case ExprTypeKind.POINTER: state.MOVL(attrib_offset, Reg.EAX, Reg.EAX); return(Reg.EAX); case ExprTypeKind.FLOAT: state.FLDS(attrib_offset, Reg.EAX); return(Reg.ST0); case ExprTypeKind.DOUBLE: state.FLDL(attrib_offset, Reg.EAX); return(Reg.ST0); default: throw new InvalidProgramException(); } }
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); } }