public override void CalcAndSaveDouble(CGenState state) { state.FSUB(1, 0); state.FSTL(0, Reg.ECX); }
public override Reg CGenValue(CGenState state) { // 1. %eax = &left this.Left.CGenAddress(state); // 2. push %eax Int32 pos = state.CGenPushLong(Reg.EAX); Reg ret = this.Right.CGenValue(state); switch (this.Left.Type.Kind) { case ExprTypeKind.CHAR: case ExprTypeKind.UCHAR: // pop %ebx // now %ebx = %Left state.CGenPopLong(pos, Reg.EBX); // *%ebx = %al state.MOVB(Reg.AL, 0, Reg.EBX); return Reg.EAX; case ExprTypeKind.SHORT: case ExprTypeKind.USHORT: // pop %ebx // now %ebx = %Left state.CGenPopLong(pos, Reg.EBX); // *%ebx = %al state.MOVW(Reg.AX, 0, Reg.EBX); return Reg.EAX; case ExprTypeKind.LONG: case ExprTypeKind.ULONG: case ExprTypeKind.POINTER: // pop %ebx // now %ebx = &Left state.CGenPopLong(pos, Reg.EBX); // *%ebx = %al state.MOVL(Reg.EAX, 0, Reg.EBX); return Reg.EAX; case ExprTypeKind.FLOAT: // pop %ebx // now %ebx = &Left state.CGenPopLong(pos, Reg.EBX); // *%ebx = %st(0) state.FSTS(0, Reg.EBX); return Reg.ST0; case ExprTypeKind.DOUBLE: // pop %ebx // now %ebx = &Left state.CGenPopLong(pos, Reg.EBX); // *%ebx = %st(0) state.FSTL(0, Reg.EBX); return Reg.ST0; case ExprTypeKind.STRUCT_OR_UNION: // pop %edi // now %edi = &Left state.CGenPopLong(pos, Reg.EDI); // %esi = &Right state.MOVL(Reg.EAX, Reg.ESI); // %ecx = nbytes state.MOVL(this.Left.Type.SizeOf, Reg.ECX); state.CGenMemCpy(); // %eax = &Left state.MOVL(Reg.EDI, Reg.EAX); return Reg.EAX; case ExprTypeKind.FUNCTION: case ExprTypeKind.VOID: case ExprTypeKind.ARRAY: case ExprTypeKind.INCOMPLETE_ARRAY: default: throw new InvalidProgramException("cannot assign to a " + this.Type.Kind); } }