| 335 | } |
| 336 | |
| 337 | Status DecimalIR::BuildSubtract() { |
| 338 | // Create fn prototype : |
| 339 | // int128_t |
| 340 | // subtract_decimal128_decimal128(int128_t x_value, int32_t x_precision, int32_t |
| 341 | // x_scale, |
| 342 | // int128_t y_value, int32_t y_precision, int32_t y_scale |
| 343 | // int32_t out_precision, int32_t out_scale) |
| 344 | auto i32 = types()->i32_type(); |
| 345 | auto i128 = types()->i128_type(); |
| 346 | auto function = BuildFunction(kSubtractFunction, i128, |
| 347 | { |
| 348 | {"x_value", i128}, |
| 349 | {"x_precision", i32}, |
| 350 | {"x_scale", i32}, |
| 351 | {"y_value", i128}, |
| 352 | {"y_precision", i32}, |
| 353 | {"y_scale", i32}, |
| 354 | {"out_precision", i32}, |
| 355 | {"out_scale", i32}, |
| 356 | }); |
| 357 | |
| 358 | auto entry = llvm::BasicBlock::Create(*context(), "entry", function); |
| 359 | ir_builder()->SetInsertPoint(entry); |
| 360 | |
| 361 | // reuse add function after negating y_value. i.e |
| 362 | // add(x_value, x_precision, x_scale, -y_value, y_precision, y_scale, |
| 363 | // out_precision, out_scale) |
| 364 | std::vector<llvm::Value*> args; |
| 365 | int i = 0; |
| 366 | for (auto& in_arg : function->args()) { |
| 367 | if (i == 3) { |
| 368 | auto y_neg_value = ir_builder()->CreateNeg(&in_arg); |
| 369 | args.push_back(y_neg_value); |
| 370 | } else { |
| 371 | args.push_back(&in_arg); |
| 372 | } |
| 373 | ++i; |
| 374 | } |
| 375 | auto value = ir_builder()->CreateCall(module()->getFunction(kAddFunction), args); |
| 376 | |
| 377 | // store result to out |
| 378 | ir_builder()->CreateRet(value); |
| 379 | return Status::OK(); |
| 380 | } |
| 381 | |
| 382 | Status DecimalIR::BuildCompare(const std::string& function_name, |
| 383 | llvm::ICmpInst::Predicate cmp_instruction) { |
no test coverage detected