/// <summary> /// Emits a rem instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement value2 = context.CurrentStack.Pop(); StackElement value1 = context.CurrentStack.Pop(); if (TypeHelper.IsFloatingPoint(value1) || TypeHelper.IsFloatingPoint(value2)) { ValueRef result = LLVM.BuildFRem(builder, value1.Value, value2.Value, "remfp"); context.CurrentStack.Push(new StackElement(result, value1.ILType, value1.Type)); } else { CastHelper.HelpIntCast(builder, ref value1, ref value2); ValueRef result; if (instruction.OpCode.Code == Code.Rem) { result = LLVM.BuildSRem(builder, value1.Value, value2.Value, "remsi"); } else /* Rem_Un */ { result = LLVM.BuildURem(builder, value1.Value, value2.Value, "remui"); } context.CurrentStack.Push(new StackElement(result, value1.ILType, value1.Type)); } }
/// <summary> /// Emits an add instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement value2 = context.CurrentStack.Pop(); StackElement value1 = context.CurrentStack.Pop(); if (TypeHelper.IsFloatingPoint(value1) || TypeHelper.IsFloatingPoint(value2)) { ValueRef result = LLVM.BuildFAdd(builder, value1.Value, value2.Value, "addfp"); context.CurrentStack.Push(new StackElement(result, value1.ILType, value1.Type)); } else { bool isPtrVal1, isPtrVal2; CastHelper.HelpPossiblePtrCast(builder, ref value1, ref value2, out isPtrVal1, out isPtrVal2, "addcast"); // If one of the two values is a pointer, then the result will be a pointer as well. if (isPtrVal1 || isPtrVal2) { ValueRef result = LLVM.BuildAdd(builder, value1.Value, value2.Value, "addptr"); TypeRef resultingType = (isPtrVal1 ? value1.Type : value2.Type); TypeReference resultingILType = (isPtrVal1 ? value1.ILType : value2.ILType); ValueRef ptr = LLVM.BuildIntToPtr(builder, result, resultingType, "ptr"); context.CurrentStack.Push(new StackElement(ptr, resultingILType, resultingType)); } // Cast to different int size. else { CastHelper.HelpIntCast(builder, ref value1, ref value2); ValueRef result = LLVM.BuildAdd(builder, value1.Value, value2.Value, "addi"); context.CurrentStack.Push(new StackElement(result, value1.ILType, value1.Type)); } } }
/// <summary> /// Emits an shr_un instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement value2 = context.CurrentStack.Pop(); StackElement value1 = context.CurrentStack.Pop(); CastHelper.HelpIntCast(builder, ref value1, ref value2); ValueRef result = LLVM.BuildLShr(builder, value1.Value, value2.Value, "shrun"); context.CurrentStack.Push(new StackElement(result, value1.ILType, value1.Type)); }
/// <summary> /// Emits a mul instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement value2 = context.CurrentStack.Pop(); StackElement value1 = context.CurrentStack.Pop(); if (TypeHelper.IsFloatingPoint(value1) || TypeHelper.IsFloatingPoint(value2)) { ValueRef result = LLVM.BuildFMul(builder, value1.Value, value2.Value, "mulfp"); context.CurrentStack.Push(new StackElement(result, value1.ILType, value1.Type)); } else { CastHelper.HelpIntCast(builder, ref value1, ref value2); ValueRef result = LLVM.BuildMul(builder, value1.Value, value2.Value, "muli"); context.CurrentStack.Push(new StackElement(result, value1.ILType, value1.Type)); } }
/// <summary> /// Emits a branch on compare instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement value2 = context.CurrentStack.Pop(); StackElement value1 = context.CurrentStack.Pop(); ValueRef ret; if (TypeHelper.IsFloatingPoint(value2) || TypeHelper.IsFloatingPoint(value1)) { ret = LLVM.BuildFCmp(builder, PredicateHelper.GetRealPredicateFromCode(instruction.OpCode.Code), value1.Value, value2.Value, "fbrcmp"); } else { CastHelper.HelpIntCast(builder, ref value1, ref value2); ret = LLVM.BuildICmp(builder, PredicateHelper.GetIntPredicateFromCode(instruction.OpCode.Code), value1.Value, value2.Value, "ibrcmp"); } Instruction onFalse = instruction.Next; Instruction onTrue = (Instruction)instruction.Operand; LLVM.BuildCondBr(builder, ret, context.GetBlockOf(onTrue), context.GetBlockOf(onFalse)); }