public void Translate(IRInstruction instr, ILTranslator tr) { tr.PushOperand(instr.Operand1); tr.PushOperand(instr.Operand2); var type = TypeInference.InferBinaryOp(instr.Operand1.Type, instr.Operand2.Type); switch (type) { case ASTType.I4: tr.Instructions.Add(new ILInstruction(ILOpCode.REM_DWORD)); break; case ASTType.I8: case ASTType.Ptr: tr.Instructions.Add(new ILInstruction(ILOpCode.REM_QWORD)); break; case ASTType.R4: tr.Instructions.Add(new ILInstruction(ILOpCode.REM_R32)); break; case ASTType.R8: tr.Instructions.Add(new ILInstruction(ILOpCode.REM_R64)); break; default: throw new NotSupportedException(); } tr.PopOperand(instr.Operand1); }
private static ASTType?InferPush1(ILASTExpression expr) { switch (expr.ILCode) { case Code.Add: case Code.Add_Ovf: case Code.Add_Ovf_Un: case Code.Sub: case Code.Sub_Ovf: case Code.Sub_Ovf_Un: case Code.Mul: case Code.Mul_Ovf: case Code.Mul_Ovf_Un: case Code.Div: case Code.Div_Un: case Code.Rem: case Code.Rem_Un: Debug.Assert(expr.Arguments.Length == 2); Debug.Assert(expr.Arguments[0].Type != null && expr.Arguments[1].Type != null); return(TypeInference.InferBinaryOp(expr.Arguments[0].Type.Value, expr.Arguments[1].Type.Value)); case Code.Xor: case Code.And: case Code.Or: Debug.Assert(expr.Arguments.Length == 2); Debug.Assert(expr.Arguments[0].Type != null && expr.Arguments[1].Type != null); return(TypeInference.InferIntegerOp(expr.Arguments[0].Type.Value, expr.Arguments[1].Type.Value)); case Code.Not: Debug.Assert(expr.Arguments.Length == 1 && expr.Arguments[0].Type != null); if (expr.Arguments[0].Type != ASTType.I4 && expr.Arguments[0].Type != ASTType.I8 && expr.Arguments[0].Type != ASTType.Ptr) { throw new ArgumentException("Invalid Not Operand Types."); } return(expr.Arguments[0].Type); case Code.Neg: Debug.Assert(expr.Arguments.Length == 1 && expr.Arguments[0].Type != null); if (expr.Arguments[0].Type != ASTType.I4 && expr.Arguments[0].Type != ASTType.I8 && expr.Arguments[0].Type != ASTType.R4 && expr.Arguments[0].Type != ASTType.R8 && expr.Arguments[0].Type != ASTType.Ptr) { throw new ArgumentException("Invalid Not Operand Types."); } return(expr.Arguments[0].Type); case Code.Shr: case Code.Shl: case Code.Shr_Un: Debug.Assert(expr.Arguments.Length == 2); Debug.Assert(expr.Arguments[0].Type != null && expr.Arguments[1].Type != null); return(TypeInference.InferShiftOp(expr.Arguments[0].Type.Value, expr.Arguments[1].Type.Value)); case Code.Mkrefany: return(ASTType.O); case Code.Ldarg: return(TypeInference.ToASTType(((Parameter)expr.Operand).Type)); case Code.Ldloc: return(TypeInference.ToASTType(((Local)expr.Operand).Type)); case Code.Unbox_Any: case Code.Ldelem: case Code.Ldobj: return(TypeInference.ToASTType(((ITypeDefOrRef)expr.Operand).ToTypeSig())); case Code.Ldfld: case Code.Ldsfld: return(TypeInference.ToASTType(((IField)expr.Operand).FieldSig.Type)); default: throw new NotSupportedException(expr.ILCode.ToString()); } }