public virtual void CGenPush(Env env, CGenState state) { Reg ret = CGenValue(env, state); switch (type.kind) { case ExprType.Kind.CHAR: case ExprType.Kind.UCHAR: case ExprType.Kind.SHORT: case ExprType.Kind.USHORT: case ExprType.Kind.LONG: case ExprType.Kind.ULONG: // Integral if (ret != Reg.EAX) { throw new InvalidProgramException("Integral values should be returned to %eax"); } state.CGenPushLong(Reg.EAX); break; case ExprType.Kind.FLOAT: // Float if (ret != Reg.ST0) { throw new InvalidProgramException("Floats should be returned to %st(0)"); } state.CGenExpandStackBy4Bytes(); state.FSTS(0, Reg.ESP); break; case ExprType.Kind.DOUBLE: // Double if (ret != Reg.ST0) { throw new InvalidProgramException("Doubles should be returned to %st(0)"); } state.CGenExpandStackBy8Bytes(); state.FSTL(0, Reg.ESP); break; case ExprType.Kind.ARRAY: case ExprType.Kind.FUNCTION: case ExprType.Kind.POINTER: // Pointer if (ret != Reg.EAX) { throw new InvalidProgramException("Pointer values should be returned to %eax"); } state.CGenPushLong(Reg.EAX); break; case ExprType.Kind.INCOMPLETE_ARRAY: case ExprType.Kind.VOID: throw new InvalidProgramException(type.kind.ToString() + " can't be pushed onto the stack"); case ExprType.Kind.STRUCT_OR_UNION: throw new NotImplementedException(); } }