14 #ifndef LLVM_IR_FIXEDPOINTBUILDER_H
15 #define LLVM_IR_FIXEDPOINTBUILDER_H
35 unsigned SrcWidth = SrcSema.
getWidth();
36 unsigned DstWidth = DstSema.
getWidth();
37 unsigned SrcScale = SrcSema.
getScale();
38 unsigned DstScale = DstSema.
getScale();
39 bool SrcIsSigned = SrcSema.
isSigned();
40 bool DstIsSigned = DstSema.
isSigned();
42 Type *DstIntTy =
B.getIntNTy(DstWidth);
45 unsigned ResultWidth = SrcWidth;
48 if (DstScale < SrcScale) {
52 if (DstIsInteger && SrcIsSigned) {
54 Value *IsNegative =
B.CreateICmpSLT(Result, Zero);
57 Value *Rounded =
B.CreateAdd(Result, LowBits);
58 Result =
B.CreateSelect(IsNegative, Rounded, Result);
62 ?
B.CreateAShr(Result, SrcScale - DstScale,
"downscale")
63 :
B.CreateLShr(Result, SrcScale - DstScale,
"downscale");
68 Result =
B.CreateIntCast(Result, DstIntTy, SrcIsSigned,
"resize");
71 if (DstScale > SrcScale)
72 Result =
B.CreateShl(Result, DstScale - SrcScale,
"upscale");
75 if (DstScale > SrcScale) {
77 ResultWidth =
std::max(SrcWidth + DstScale - SrcScale, DstWidth);
78 Type *UpscaledTy =
B.getIntNTy(ResultWidth);
79 Result =
B.CreateIntCast(Result, UpscaledTy, SrcIsSigned,
"resize");
80 Result =
B.CreateShl(Result, DstScale - SrcScale,
"upscale");
89 Value *TooHigh = SrcIsSigned ?
B.CreateICmpSGT(Result, Max)
90 :
B.CreateICmpUGT(Result, Max);
91 Result =
B.CreateSelect(TooHigh, Max, Result,
"satmax");
95 if (SrcIsSigned && (LessIntBits || !DstIsSigned)) {
99 Value *TooLow =
B.CreateICmpSLT(Result, Min);
100 Result =
B.CreateSelect(TooLow, Min, Result,
"satmin");
104 if (ResultWidth != DstWidth)
105 Result =
B.CreateIntCast(Result, DstIntTy, SrcIsSigned,
"resize");
119 C.getWidth() + (
unsigned)(BothPadded &&
C.isSaturated()),
C.getScale(),
120 C.isSigned(),
C.isSaturated(), BothPadded);
143 return Convert(Src, SrcSema, DstSema,
false);
153 unsigned DstWidth,
bool DstIsSigned) {
175 Type *OpTy = getAccommodatingFloatType(DstTy, SrcSema);
178 Result = SrcSema.
isSigned() ?
B.CreateSIToFP(Src, OpTy)
179 :
B.CreateUIToFP(Src, OpTy);
182 Result =
B.CreateFMul(Result,
185 Result =
B.CreateFPTrunc(Result, DstTy);
192 Type *OpTy = getAccommodatingFloatType(Src->
getType(), DstSema);
194 Result =
B.CreateFPExt(Result, OpTy);
197 Result =
B.CreateFMul(Result,
203 UseSigned ? Intrinsic::fptosi_sat : Intrinsic::fptoui_sat;
204 Result =
B.CreateIntrinsic(IID, {ResultTy, OpTy}, {Result});
206 Result = UseSigned ?
B.CreateFPToSI(Result, ResultTy)
207 :
B.CreateFPToUI(Result, ResultTy);
215 B.CreateSelect(
B.CreateICmpSLT(Result, Zero), Zero, Result,
"satmin");
228 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
229 bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();
235 if (CommonSema.isSaturated()) {
236 Intrinsic::ID IID = UseSigned ? Intrinsic::sadd_sat : Intrinsic::uadd_sat;
237 Result =
B.CreateBinaryIntrinsic(IID, WideLHS, WideRHS);
239 Result =
B.CreateAdd(WideLHS, WideRHS);
254 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
255 bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();
261 if (CommonSema.isSaturated()) {
262 Intrinsic::ID IID = UseSigned ? Intrinsic::ssub_sat : Intrinsic::usub_sat;
263 Result =
B.CreateBinaryIntrinsic(IID, WideLHS, WideRHS);
265 Result =
B.CreateSub(WideLHS, WideRHS);
270 if (CommonSema.isSaturated() && CommonSema.hasUnsignedPadding()) {
273 B.CreateSelect(
B.CreateICmpSLT(Result, Zero), Zero, Result,
"satmin");
288 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
289 bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();
295 if (CommonSema.isSaturated()) {
296 IID = UseSigned ? Intrinsic::smul_fix_sat : Intrinsic::umul_fix_sat;
298 IID = UseSigned ? Intrinsic::smul_fix : Intrinsic::umul_fix;
300 Value *Result =
B.CreateIntrinsic(
302 {WideLHS, WideRHS,
B.getInt32(CommonSema.getScale())});
316 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
317 bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();
323 if (CommonSema.isSaturated()) {
324 IID = UseSigned ? Intrinsic::sdiv_fix_sat : Intrinsic::udiv_fix_sat;
326 IID = UseSigned ? Intrinsic::sdiv_fix : Intrinsic::udiv_fix;
328 Value *Result =
B.CreateIntrinsic(
330 {WideLHS, WideRHS,
B.getInt32(CommonSema.getScale())});
344 RHS =
B.CreateIntCast(RHS, LHS->
getType(),
false);
348 Intrinsic::ID IID = UseSigned ? Intrinsic::sshl_sat : Intrinsic::ushl_sat;
349 Result =
B.CreateBinaryIntrinsic(IID, LHS, RHS);
351 Result =
B.CreateShl(LHS, RHS);
363 RHS =
B.CreateIntCast(RHS, LHS->
getType(),
false);
365 return LHSSema.
isSigned() ?
B.CreateAShr(LHS, RHS) :
B.CreateLShr(LHS, RHS);
375 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
380 return B.CreateICmpEQ(WideLHS, WideRHS);
390 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
395 return B.CreateICmpNE(WideLHS, WideRHS);
405 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
410 return CommonSema.isSigned() ?
B.CreateICmpSLT(WideLHS, WideRHS)
411 :
B.CreateICmpULT(WideLHS, WideRHS);
421 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
426 return CommonSema.isSigned() ?
B.CreateICmpSLE(WideLHS, WideRHS)
427 :
B.CreateICmpULE(WideLHS, WideRHS);
437 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
442 return CommonSema.isSigned() ?
B.CreateICmpSGT(WideLHS, WideRHS)
443 :
B.CreateICmpUGT(WideLHS, WideRHS);
453 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
458 return CommonSema.isSigned() ?
B.CreateICmpSGE(WideLHS, WideRHS)
459 :
B.CreateICmpUGE(WideLHS, WideRHS);
465 #endif // LLVM_IR_FIXEDPOINTBUILDER_H