public override void Generate(CodeGenerator codeGenerator, FunctionGenerator fgen) { IType target = Lhs.ResultType.GetMostComplexType(Rhs.ResultType); LLVMValueRef lhsValue = Lhs.GetRef(codeGenerator, target); LLVMValueRef rhsValue = Rhs.GetRef(codeGenerator, target); switch (Operation) { case OperationType.LessThan: SetRef(codeGenerator, PrimitiveType.Boolean, fgen.CompareInts(LLVMIntPredicate.LLVMIntSLT, lhsValue, rhsValue)); break; case OperationType.LessThanUnsigned: SetRef(codeGenerator, PrimitiveType.Boolean, fgen.CompareInts(LLVMIntPredicate.LLVMIntULT, lhsValue, rhsValue)); break; case OperationType.LessThanOrEqual: SetRef(codeGenerator, PrimitiveType.Boolean, fgen.CompareInts(LLVMIntPredicate.LLVMIntSLE, lhsValue, rhsValue)); break; case OperationType.LessThanOrEqualUnsigned: SetRef(codeGenerator, PrimitiveType.Boolean, fgen.CompareInts(LLVMIntPredicate.LLVMIntULE, lhsValue, rhsValue)); break; case OperationType.GreaterThan: SetRef(codeGenerator, PrimitiveType.Boolean, fgen.CompareInts(LLVMIntPredicate.LLVMIntSGT, lhsValue, rhsValue)); break; case OperationType.GreaterThanUnsigned: SetRef(codeGenerator, PrimitiveType.Boolean, fgen.CompareInts(LLVMIntPredicate.LLVMIntUGT, lhsValue, rhsValue)); break; case OperationType.GreaterThanOrEqual: SetRef(codeGenerator, PrimitiveType.Boolean, fgen.CompareInts(LLVMIntPredicate.LLVMIntSGE, lhsValue, rhsValue)); break; case OperationType.GreaterThanOrEqualUnsigned: SetRef(codeGenerator, PrimitiveType.Boolean, fgen.CompareInts(LLVMIntPredicate.LLVMIntUGE, lhsValue, rhsValue)); break; case OperationType.Equal: SetRef(codeGenerator, PrimitiveType.Boolean, fgen.CompareInts(LLVMIntPredicate.LLVMIntEQ, lhsValue, rhsValue)); break; default: throw new NotImplementedException("Unknown operationType " + Operation); } }
public override void Generate(CodeGenerator codeGenerator, FunctionGenerator fgen) { IType lhs = Lhs.ResultType; if (lhs is EnumType) { lhs = ((EnumType)lhs).UnderlyingType; } LLVMValueRef lhsValue = Lhs.GetRef(codeGenerator, lhs); IType target = lhs; if (Operation == OperationType.Not) { SetRef(codeGenerator, target, LLVM.BuildNot(codeGenerator.Builder, lhsValue, "")); return; } else if (Operation == OperationType.Negate) { SetRef(codeGenerator, target, LLVM.BuildNeg(codeGenerator.Builder, lhsValue, "")); return; } IType rhs = Rhs.ResultType; if (rhs is EnumType) { rhs = ((EnumType)rhs).UnderlyingType; } LLVMValueRef rhsValue = Rhs.GetRef(codeGenerator, target); if (!lhs.IsStackCompatible(rhs)) { throw new NotImplementedException("Numeric ops on different types not implemented yet"); } switch (Operation) { case OperationType.Add: SetRef(codeGenerator, target, LLVM.BuildAdd(codeGenerator.Builder, lhsValue, rhsValue, "")); break; case OperationType.Subtract: SetRef(codeGenerator, target, LLVM.BuildSub(codeGenerator.Builder, lhsValue, rhsValue, "")); break; case OperationType.Multiply: SetRef(codeGenerator, target, LLVM.BuildMul(codeGenerator.Builder, lhsValue, rhsValue, "")); break; case OperationType.Divide: SetRef(codeGenerator, target, LLVM.BuildSDiv(codeGenerator.Builder, lhsValue, rhsValue, "")); break; case OperationType.DivideUnsigned: SetRef(codeGenerator, target, LLVM.BuildUDiv(codeGenerator.Builder, lhsValue, rhsValue, "")); break; case OperationType.Remainder: SetRef(codeGenerator, target, LLVM.BuildSRem(codeGenerator.Builder, lhsValue, rhsValue, "")); break; case OperationType.RemainderUnsigned: SetRef(codeGenerator, target, LLVM.BuildURem(codeGenerator.Builder, lhsValue, rhsValue, "")); break; case OperationType.ShiftLeft: SetRef(codeGenerator, target, LLVM.BuildShl(codeGenerator.Builder, lhsValue, rhsValue, "")); break; case OperationType.ShiftRight: SetRef(codeGenerator, target, LLVM.BuildAShr(codeGenerator.Builder, lhsValue, rhsValue, "")); break; case OperationType.ShiftRightUnsigned: SetRef(codeGenerator, target, LLVM.BuildLShr(codeGenerator.Builder, lhsValue, rhsValue, "")); break; case OperationType.And: SetRef(codeGenerator, target, LLVM.BuildAnd(codeGenerator.Builder, lhsValue, rhsValue, "")); break; case OperationType.Or: SetRef(codeGenerator, target, LLVM.BuildOr(codeGenerator.Builder, lhsValue, rhsValue, "")); break; case OperationType.XOr: SetRef(codeGenerator, target, LLVM.BuildXor(codeGenerator.Builder, lhsValue, rhsValue, "")); break; default: throw new NotImplementedException("Unknown operationType " + Operation); } }