LLVM: include/llvm/IR/FixedPointBuilder.h Source File (original) (raw)

33 IRBuilderTy &B;

34

37 unsigned SrcWidth = SrcSema.getWidth();

38 unsigned DstWidth = DstSema.getWidth();

39 unsigned SrcScale = SrcSema.getScale();

40 unsigned DstScale = DstSema.getScale();

41 bool SrcIsSigned = SrcSema.isSigned();

42 bool DstIsSigned = DstSema.isSigned();

43

45

46 Value *Result = Src;

47 unsigned ResultWidth = SrcWidth;

48

49

50 if (DstScale < SrcScale) {

51

52

53

54 if (DstIsInteger && SrcIsSigned) {

56 Value *IsNegative = B.CreateICmpSLT(Result, Zero);

57 Value *LowBits = ConstantInt::get(

59 Value *Rounded = B.CreateAdd(Result, LowBits);

60 Result = B.CreateSelect(IsNegative, Rounded, Result);

61 }

62

63 Result = SrcIsSigned

64 ? B.CreateAShr(Result, SrcScale - DstScale, "downscale")

65 : B.CreateLShr(Result, SrcScale - DstScale, "downscale");

66 }

67

69

70 Result = B.CreateIntCast(Result, DstIntTy, SrcIsSigned, "resize");

71

72

73 if (DstScale > SrcScale)

74 Result = B.CreateShl(Result, DstScale - SrcScale, "upscale");

75 } else {

76

77 if (DstScale > SrcScale) {

78

79 ResultWidth = std::max(SrcWidth + DstScale - SrcScale, DstWidth);

81 Result = B.CreateIntCast(Result, UpscaledTy, SrcIsSigned, "resize");

82 Result = B.CreateShl(Result, DstScale - SrcScale, "upscale");

83 }

84

85

87 if (LessIntBits) {

88 Value *Max = ConstantInt::get(

89 B.getContext(),

91 Value *TooHigh = SrcIsSigned ? B.CreateICmpSGT(Result, Max)

92 : B.CreateICmpUGT(Result, Max);

93 Result = B.CreateSelect(TooHigh, Max, Result, "satmax");

94 }

95

96

97 if (SrcIsSigned && (LessIntBits || !DstIsSigned)) {

98 Value *Min = ConstantInt::get(

99 B.getContext(),

101 Value *TooLow = B.CreateICmpSLT(Result, Min);

102 Result = B.CreateSelect(TooLow, Min, Result, "satmin");

103 }

104

105

106 if (ResultWidth != DstWidth)

107 Result = B.CreateIntCast(Result, DstIntTy, SrcIsSigned, "resize");

108 }

109 return Result;

110 }

111

112

113

118 bool BothPadded =

121 C.getWidth() + (unsigned)(BothPadded && C.isSaturated()), C.getScale(),

122 C.isSigned(), C.isSaturated(), BothPadded);

123 }

124

125

126

127

129 const fltSemantics *FloatSema = &Ty->getFltSemantics();

133 }

134

135public:

137

138

139

140

141

142

145 return Convert(Src, SrcSema, DstSema, false);

146 }

147

148

149

150

151

152

153

155 unsigned DstWidth, bool DstIsSigned) {

156 return Convert(

157 Src, SrcSema,

159 }

160

161

162

163

164

165

168 return Convert(Src,

170 Src->getType()->getScalarSizeInBits(), SrcIsSigned),

171 DstSema, false);

172 }

173

175 Type *DstTy) {

177 Type *OpTy = getAccommodatingFloatType(DstTy, SrcSema);

178

179

180 Result = SrcSema.isSigned() ? B.CreateSIToFP(Src, OpTy)

181 : B.CreateUIToFP(Src, OpTy);

182

183

184 Result = B.CreateFMul(Result,

185 ConstantFP::get(OpTy, std::pow(2, -(int)SrcSema.getScale())));

186 if (OpTy != DstTy)

187 Result = B.CreateFPTrunc(Result, DstTy);

188 return Result;

189 }

190

193 Value *Result = Src;

194 Type *OpTy = getAccommodatingFloatType(Src->getType(), DstSema);

195 if (OpTy != Src->getType())

196 Result = B.CreateFPExt(Result, OpTy);

197

198

199 Result = B.CreateFMul(Result,

200 ConstantFP::get(OpTy, std::pow(2, DstSema.getScale())));

201

205 UseSigned ? Intrinsic::fptosi_sat : Intrinsic::fptoui_sat;

206 Result = B.CreateIntrinsic(IID, {ResultTy, OpTy}, {Result});

207 } else {

208 Result = UseSigned ? B.CreateFPToSI(Result, ResultTy)

209 : B.CreateFPToUI(Result, ResultTy);

210 }

211

212

213

216 Result =

217 B.CreateSelect(B.CreateICmpSLT(Result, Zero), Zero, Result, "satmin");

218 }

219

220 return Result;

221 }

222

223

224

225

226

227

230 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);

231 bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();

232

235

237 if (CommonSema.isSaturated()) {

238 Intrinsic::ID IID = UseSigned ? Intrinsic::sadd_sat : Intrinsic::uadd_sat;

239 Result = B.CreateBinaryIntrinsic(IID, WideLHS, WideRHS);

240 } else {

241 Result = B.CreateAdd(WideLHS, WideRHS);

242 }

243

246 }

247

248

249

250

251

252

253

256 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);

257 bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();

258

261

263 if (CommonSema.isSaturated()) {

264 Intrinsic::ID IID = UseSigned ? Intrinsic::ssub_sat : Intrinsic::usub_sat;

265 Result = B.CreateBinaryIntrinsic(IID, WideLHS, WideRHS);

266 } else {

267 Result = B.CreateSub(WideLHS, WideRHS);

268 }

269

270

271

272 if (CommonSema.isSaturated() && CommonSema.hasUnsignedPadding()) {

274 Result =

275 B.CreateSelect(B.CreateICmpSLT(Result, Zero), Zero, Result, "satmin");

276 }

277

280 }

281

282

283

284

285

286

287

290 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);

291 bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();

292

295

297 if (CommonSema.isSaturated()) {

298 IID = UseSigned ? Intrinsic::smul_fix_sat : Intrinsic::umul_fix_sat;

299 } else {

300 IID = UseSigned ? Intrinsic::smul_fix : Intrinsic::umul_fix;

301 }

302 Value *Result = B.CreateIntrinsic(

303 IID, {WideLHS->getType()},

304 {WideLHS, WideRHS, B.getInt32(CommonSema.getScale())});

305

308 }

309

310

311

312

313

314

315

318 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);

319 bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();

320

323

325 if (CommonSema.isSaturated()) {

326 IID = UseSigned ? Intrinsic::sdiv_fix_sat : Intrinsic::udiv_fix_sat;

327 } else {

328 IID = UseSigned ? Intrinsic::sdiv_fix : Intrinsic::udiv_fix;

329 }

330 Value *Result = B.CreateIntrinsic(

331 IID, {WideLHS->getType()},

332 {WideLHS, WideRHS, B.getInt32(CommonSema.getScale())});

333

336 }

337

338

339

340

341

342

345

346 RHS = B.CreateIntCast(RHS, LHS->getType(), false);

347

350 Intrinsic::ID IID = UseSigned ? Intrinsic::sshl_sat : Intrinsic::ushl_sat;

351 Result = B.CreateBinaryIntrinsic(IID, LHS, RHS);

352 } else {

353 Result = B.CreateShl(LHS, RHS);

354 }

355

356 return Result;

357 }

358

359

360

361

362

363

365 RHS = B.CreateIntCast(RHS, LHS->getType(), false);

366

368 }

369

370

371

372

373

374

377 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);

378

381

382 return B.CreateICmpEQ(WideLHS, WideRHS);

383 }

384

385

386

387

388

389

392 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);

393

396

397 return B.CreateICmpNE(WideLHS, WideRHS);

398 }

399

400

401

402

403

404

407 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);

408

411

412 return CommonSema.isSigned() ? B.CreateICmpSLT(WideLHS, WideRHS)

413 : B.CreateICmpULT(WideLHS, WideRHS);

414 }

415

416

417

418

419

420

423 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);

424

427

428 return CommonSema.isSigned() ? B.CreateICmpSLE(WideLHS, WideRHS)

429 : B.CreateICmpULE(WideLHS, WideRHS);

430 }

431

432

433

434

435

436

439 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);

440

443

444 return CommonSema.isSigned() ? B.CreateICmpSGT(WideLHS, WideRHS)

445 : B.CreateICmpUGT(WideLHS, WideRHS);

446 }

447

448

449

450

451

452

455 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);

456

459

460 return CommonSema.isSigned() ? B.CreateICmpSGE(WideLHS, WideRHS)

461 : B.CreateICmpUGE(WideLHS, WideRHS);

462 }

463};