Changeset 1001:7a0238db1962
- Timestamp:
- 02/26/09 21:47:06 (16 years ago)
- Files:
-
- gen/functions.cpp (modified) (1 diff)
- gen/tocall.cpp (modified) (1 diff)
- runtime/import/ldc/intrinsics.di (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
gen/functions.cpp
Revision 988:2667e3a145be Revision 1001:7a0238db1962 68 } 68 } 69 // default handling 69 // default handling 70 else 70 else 71 { 71 { 72 assert(rt); 72 assert(rt); 73 if (gABI->returnInArg(rt)) 73 if (f->linkage == LINKintrinsic) 74 { 74 { 75 rettype = getPtrToType(DtoType(rt)); 75 // Intrinsics don't care about ABI 76 actualRettype = LLType::VoidTy; 76 Logger::cout() << "Intrinsic returning " << rt->toChars() << '\n'; 77 f->retInPtr = retinptr = true; 77 actualRettype = rettype = DtoType(rt); 78 Logger::cout() << " (LLVM type: " << *rettype << ")\n"; 78 } 79 } 79 else 80 else 80 { 81 { 81 rettype = DtoType(rt); 82 if (gABI->returnInArg(rt)) 82 // do abi specific transformations 83 { 83 actualRettype = gABI->getRetType(f, rettype); 84 rettype = getPtrToType(DtoType(rt)); 84 } 85 actualRettype = LLType::VoidTy; 85 86 f->retInPtr = retinptr = true; 86 // FIXME: should probably be part of the abi 87 } 87 if (unsigned ea = DtoShouldExtend(rt)) 88 else 88 { 89 { 89 f->retAttrs |= ea; 90 rettype = DtoType(rt); 91 // do abi specific transformations 92 actualRettype = gABI->getRetType(f, rettype); 93 } 94 95 // FIXME: should probably be part of the abi 96 if (unsigned ea = DtoShouldExtend(rt)) 97 { 98 f->retAttrs |= ea; 99 } 90 } 100 } 91 } 101 } 92 102 93 // build up parameter list 103 // build up parameter list 94 if (retinptr) { 104 if (retinptr) { gen/tocall.cpp
Revision 988:2667e3a145be Revision 1001:7a0238db1962 462 CallOrInvoke* call = gIR->CreateCallOrInvoke(callable, args.begin(), args.end(), varname); 462 CallOrInvoke* call = gIR->CreateCallOrInvoke(callable, args.begin(), args.end(), varname); 463 463 464 // get return value 464 // get return value 465 LLValue* retllval = (retinptr) ? args[0] : call->get(); 465 LLValue* retllval = (retinptr) ? args[0] : call->get(); 466 466 467 // do abi specific return value fixups 467 if (tf->linkage == LINKintrinsic) 468 retllval = gABI->getRet(tf, retllval); 468 { 469 // Ignore ABI for intrinsics 470 Type* rettype = tf->next; 471 if (rettype->ty == Tstruct) { 472 // LDC assumes structs are in memory, so put it there. 473 LLValue* mem = DtoAlloca(retllval->getType()); 474 DtoStore(retllval, mem); 475 retllval = mem; 476 } 477 } 478 else 479 { 480 // do abi specific return value fixups 481 retllval = gABI->getRet(tf, retllval); 482 } 469 483 470 // repaint the type if necessary 484 // repaint the type if necessary 471 if (resulttype) 485 if (resulttype) 472 { 486 { 473 Type* rbase = resulttype->toBasetype(); 487 Type* rbase = resulttype->toBasetype(); runtime/import/ldc/intrinsics.di
Revision 741:4ac97ec7c18e Revision 1001:7a0238db1962 330 pragma(intrinsic, "llvm.atomic.load.umax.i#.p0i#") 330 pragma(intrinsic, "llvm.atomic.load.umax.i#.p0i#") 331 T llvm_atomic_load_umax(T)(T* ptr, T val); 331 T llvm_atomic_load_umax(T)(T* ptr, T val); 332 pragma(intrinsic, "llvm.atomic.load.umin.i#.p0i#") 332 pragma(intrinsic, "llvm.atomic.load.umin.i#.p0i#") 333 T llvm_atomic_load_umin(T)(T* ptr, T val); 333 T llvm_atomic_load_umin(T)(T* ptr, T val); 334 334 335 336 // 337 // ARITHMETIC-WITH-OVERFLOW INTRINSICS 338 // 339 340 struct OverflowRet(T) { 341 static assert(is(T : int), T.stringof ~ " is not an integer type!"); 342 T result; 343 bool overflow; 344 } 345 346 // Signed and unsigned addition 347 pragma(intrinsic, "llvm.sadd.with.overflow.i#") 348 OverflowRet!(T) llvm_sadd_with_overflow(T)(T lhs, T rhs); 349 350 pragma(intrinsic, "llvm.uadd.with.overflow.i#") 351 OverflowRet!(T) llvm_uadd_with_overflow(T)(T lhs, T rhs); 352 353 // Signed and unsigned subtraction 354 pragma(intrinsic, "llvm.ssub.with.overflow.i#") 355 OverflowRet!(T) llvm_ssub_with_overflow(T)(T lhs, T rhs); 356 357 pragma(intrinsic, "llvm.usub.with.overflow.i#") 358 OverflowRet!(T) llvm_usub_with_overflow(T)(T lhs, T rhs); 359 360 // Signed and unsigned multiplication 361 pragma(intrinsic, "llvm.smul.with.overflow.i#") 362 OverflowRet!(T) llvm_smul_with_overflow(T)(T lhs, T rhs); 363 364 /* Note: LLVM documentations says: 365 * Warning: 'llvm.umul.with.overflow' is badly broken. 366 * It is actively being fixed, but it should not currently be used! 367 * 368 * See: http://llvm.org/docs/LangRef.html#int_umul_overflow 369 */ 370 pragma(intrinsic, "llvm.umul.with.overflow.i#") 371 OverflowRet!(T) llvm_umul_with_overflow(T)(T lhs, T rhs); 372 373 335 // 374 // 336 // GENERAL INTRINSICS 375 // GENERAL INTRINSICS 337 // 376 // 338 377 339 378

