public override void CGenAddress(CGenState state) { if (this.Expr.Type.Kind != ExprTypeKind.STRUCT_OR_UNION) { throw new InvalidProgramException(); } // %eax = address of struct or union this.Expr.CGenAddress(state); // offset inside the pack Int32 offset = ((StructOrUnionType)this.Expr.Type) .Attribs .First(_ => _.name == this.Name) .offset; state.ADDL(offset, Reg.EAX); }
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 void CGenAddress(Env env, CGenState state) { if (expr.type.kind != ExprType.Kind.STRUCT_OR_UNION) { throw new InvalidProgramException(); } // %eax = address of struct or union expr.CGenAddress(env, state); // offset inside the pack Int32 offset = ((TStructOrUnion)expr.type) .Attribs .First(_ => _.name == name) .offset; state.ADDL(offset, Reg.EAX); }
public override void CalcAndSaveWord(CGenState state) { state.ADDL(1, Reg.EAX); state.MOVW(Reg.AX, 0, Reg.ECX); }
public override void CalcAndSavePtr(CGenState state) { state.ADDL(expr.type.SizeOf, Reg.EAX); state.MOVL(Reg.EAX, 0, Reg.ECX); }
// Before the actual calculation, the state is set to this. // // regs: // %eax = expr // %ebx = expr // %ecx = &expr // // stack: // +-------+ // | ..... | <- %esp // +-------+ // // Calculate the new value in %eax, and save. // Leave %eax to be the original value. // // regs: // %eax = expr + 1 // %ebx = expr // %ecx = &expr // // stack: // +-------+ // | ..... | <- %esp // +-------+ // public override void CalcAndSaveLong(CGenState state) { state.ADDL(1, Reg.EAX); state.MOVL(Reg.EAX, 0, Reg.ECX); }
public override void CalcAndSaveByte(CGenState state) { state.ADDL(1, Reg.EAX); state.MOVB(Reg.AL, 0, Reg.ECX); }
public override void OperateULong(CGenState state) => state.ADDL(Reg.EBX, Reg.EAX);
public override void OperateULong(CGenState state) { state.ADDL(Reg.EBX, Reg.EAX); }
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 void CalcAndSavePtr(CGenState state) { state.ADDL(this.Expr.Type.SizeOf, Reg.EAX); state.MOVL(Reg.EAX, 0, Reg.ECX); }
public override void CalcAndSaveLong(CGenState state) { state.ADDL(1, Reg.EAX); state.MOVL(Reg.EAX, 0, Reg.ECX); }