comparison gen/llvmhelpers.cpp @ 1079:4e388d9d0e25

Intrinsics overhaul: - More error checking for pragma(intrinsic) - Properly handle templating for real (use actual nr of bits, not .sizeof * 8) - Template all .i* and .f* intrinsics - The old names are deprecated aliases now I also added a preliminary patch to make tango.math.Math use the new versions. (I think it looks a lot nicer now)
author Frits van Bommel <fvbommel wxs.nl>
date Tue, 10 Mar 2009 04:45:32 +0100
parents 7ce8355fbcc6
children a08983bf972e
comparison
equal deleted inserted replaced
1077:bb57632d27ea 1079:4e388d9d0e25
1514 1514
1515 // for now use the size in bits of the first template param in the instance 1515 // for now use the size in bits of the first template param in the instance
1516 assert(ti->tdtypes.dim == 1); 1516 assert(ti->tdtypes.dim == 1);
1517 Type* T = (Type*)ti->tdtypes.data[0]; 1517 Type* T = (Type*)ti->tdtypes.data[0];
1518 1518
1519 char tmp[10]; 1519 char prefix = T->isreal() ? 'f' : T->isintegral() ? 'i' : 0;
1520 if (T->toBasetype()->ty == Tbool) // otherwise we'd get a mismatch 1520 if (!prefix) {
1521 sprintf(tmp, "1"); 1521 ti->error("has invalid template parameter for intrinsic: %s", T->toChars());
1522 else 1522 fatal(); // or LLVM asserts
1523 sprintf(tmp, "%lu", T->size()*8); 1523 }
1524
1525 char tmp[21]; // probably excessive, but covers a uint64_t
1526 sprintf(tmp, "%lu", gTargetData->getTypeSizeInBits(DtoType(T)));
1524 1527
1525 // replace # in name with bitsize 1528 // replace # in name with bitsize
1526 name = td->intrinsicName; 1529 name = td->intrinsicName;
1527 1530
1528 std::string needle("#"); 1531 std::string needle("#");
1529 size_t pos; 1532 size_t pos;
1530 while(std::string::npos != (pos = name.find(needle))) 1533 while(std::string::npos != (pos = name.find(needle))) {
1531 name.replace(pos, 1, tmp); 1534 if (pos > 0 && name[pos-1] == prefix) {
1535 // Properly prefixed, insert bitwidth.
1536 name.replace(pos, 1, tmp);
1537 } else {
1538 if (pos && (name[pos-1] == 'i' || name[pos-1] == 'f')) {
1539 // Wrong type character.
1540 ti->error("has invalid parameter type for intrinsic %s: %s is not a%s type",
1541 name.c_str(), T->toChars(),
1542 (name[pos-1] == 'i' ? "n integral" : " floating-point"));
1543 } else {
1544 // Just plain wrong.
1545 ti->error("has an invalid intrinsic name: %s", name.c_str());
1546 }
1547 fatal(); // or LLVM asserts
1548 }
1549 }
1532 1550
1533 Logger::println("final intrinsic name: %s", name.c_str()); 1551 Logger::println("final intrinsic name: %s", name.c_str());
1534 } 1552 }
1535 1553
1536 ////////////////////////////////////////////////////////////////////////////////////////// 1554 //////////////////////////////////////////////////////////////////////////////////////////