comparison gen/tollvm.cpp @ 97:c4e161556a21 trunk

[svn r101] Split up CastExp into several smaller utility functions.
author lindquist
date Wed, 14 Nov 2007 20:18:01 +0100
parents ce7ed8f59b99
children 6789050b5ad1
comparison
equal deleted inserted replaced
96:ce7ed8f59b99 97:c4e161556a21
1303 gIR->ir->CreateStore(r, l); 1303 gIR->ir->CreateStore(r, l);
1304 } 1304 }
1305 } 1305 }
1306 1306
1307 ////////////////////////////////////////////////////////////////////////////////////////// 1307 //////////////////////////////////////////////////////////////////////////////////////////
1308 DValue* DtoCastInt(DValue* val, Type* _to)
1309 {
1310 const llvm::Type* tolltype = DtoType(_to);
1311
1312 Type* to = DtoDType(_to);
1313 Type* from = DtoDType(val->getType());
1314 assert(from->isintegral());
1315
1316 size_t fromsz = from->size();
1317 size_t tosz = to->size();
1318
1319 llvm::Value* rval;
1320
1321 if (to->isintegral()) {
1322 if (fromsz < tosz) {
1323 Logger::cout() << "cast to: " << *tolltype << '\n';
1324 if (from->isunsigned() || from->ty == Tbool) {
1325 rval = new llvm::ZExtInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
1326 } else {
1327 rval = new llvm::SExtInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
1328 }
1329 }
1330 else if (fromsz > tosz) {
1331 rval = new llvm::TruncInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
1332 }
1333 else {
1334 rval = new llvm::BitCastInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
1335 }
1336 }
1337 else if (to->isfloating()) {
1338 if (from->isunsigned()) {
1339 rval = new llvm::UIToFPInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
1340 }
1341 else {
1342 rval = new llvm::SIToFPInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
1343 }
1344 }
1345 else if (to->ty == Tpointer) {
1346 rval = gIR->ir->CreateIntToPtr(val->getRVal(), tolltype, "tmp");
1347 }
1348 else {
1349 assert(0 && "bad int cast");
1350 }
1351
1352 return new DImValue(_to, rval);
1353 }
1354
1355 DValue* DtoCastPtr(DValue* val, Type* to)
1356 {
1357 const llvm::Type* tolltype = DtoType(to);
1358
1359 Type* totype = DtoDType(to);
1360 Type* fromtype = DtoDType(val->getType());
1361 assert(fromtype->ty == Tpointer);
1362
1363 llvm::Value* rval;
1364
1365 if (totype->ty == Tpointer || totype->ty == Tclass) {
1366 llvm::Value* src = val->getRVal();
1367 Logger::cout() << "src: " << *src << "to type: " << *tolltype << '\n';
1368 rval = new llvm::BitCastInst(src, tolltype, "tmp", gIR->scopebb());
1369 }
1370 else if (totype->isintegral()) {
1371 rval = new llvm::PtrToIntInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
1372 }
1373 else {
1374 assert(0);
1375 }
1376
1377 return new DImValue(to, rval);
1378 }
1379
1380 DValue* DtoCastFloat(DValue* val, Type* to)
1381 {
1382 const llvm::Type* tolltype = DtoType(to);
1383
1384 Type* totype = DtoDType(to);
1385 Type* fromtype = DtoDType(val->getType());
1386 assert(fromtype->isfloating());
1387
1388 size_t fromsz = fromtype->size();
1389 size_t tosz = totype->size();
1390
1391 llvm::Value* rval;
1392
1393 if (totype->isfloating()) {
1394 if ((fromtype->ty == Tfloat80 || fromtype->ty == Tfloat64) && (totype->ty == Tfloat80 || totype->ty == Tfloat64)) {
1395 rval = val->getRVal();
1396 }
1397 else if (fromsz < tosz) {
1398 rval = new llvm::FPExtInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
1399 }
1400 else if (fromsz > tosz) {
1401 rval = new llvm::FPTruncInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
1402 }
1403 else {
1404 assert(0 && "bad float cast");
1405 }
1406 }
1407 else if (totype->isintegral()) {
1408 if (totype->isunsigned()) {
1409 rval = new llvm::FPToUIInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
1410 }
1411 else {
1412 rval = new llvm::FPToSIInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
1413 }
1414 }
1415 else {
1416 assert(0 && "bad float cast");
1417 }
1418
1419 return new DImValue(to, rval);
1420 }
1421
1422 DValue* DtoCastClass(DValue* val, Type* _to)
1423 {
1424 const llvm::Type* tolltype = DtoType(_to);
1425 Type* to = DtoDType(_to);
1426 assert(to->ty == Tclass);
1427 llvm::Value* rval = new llvm::BitCastInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
1428 return new DImValue(_to, rval);
1429 }
1430
1431 DValue* DtoCastArray(DValue* u, Type* to)
1432 {
1433 const llvm::Type* tolltype = DtoType(to);
1434
1435 Type* totype = DtoDType(to);
1436 Type* fromtype = DtoDType(u->getType());
1437 assert(fromtype->ty == Tarray || fromtype->ty == Tsarray);
1438
1439 llvm::Value* rval;
1440 llvm::Value* rval2;
1441 bool isslice = false;
1442
1443 Logger::cout() << "from array or sarray" << '\n';
1444 if (totype->ty == Tpointer) {
1445 Logger::cout() << "to pointer" << '\n';
1446 assert(fromtype->next == totype->next || totype->next->ty == Tvoid);
1447 llvm::Value* ptr = DtoGEPi(u->getRVal(),0,1,"tmp",gIR->scopebb());
1448 rval = new llvm::LoadInst(ptr, "tmp", gIR->scopebb());
1449 if (fromtype->next != totype->next)
1450 rval = gIR->ir->CreateBitCast(rval, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp");
1451 }
1452 else if (totype->ty == Tarray) {
1453 Logger::cout() << "to array" << '\n';
1454 const llvm::Type* ptrty = DtoType(totype->next);
1455 if (ptrty == llvm::Type::VoidTy)
1456 ptrty = llvm::Type::Int8Ty;
1457 ptrty = llvm::PointerType::get(ptrty);
1458
1459 const llvm::Type* ety = DtoType(fromtype->next);
1460 if (ety == llvm::Type::VoidTy)
1461 ety = llvm::Type::Int8Ty;
1462
1463 if (DSliceValue* usl = u->isSlice()) {
1464 Logger::println("from slice");
1465 rval = new llvm::BitCastInst(usl->ptr, ptrty, "tmp", gIR->scopebb());
1466 if (fromtype->next->size() == totype->next->size())
1467 rval2 = usl->len;
1468 else
1469 rval2 = DtoArrayCastLength(usl->len, ety, ptrty->getContainedType(0));
1470 }
1471 else {
1472 llvm::Value* uval = u->getRVal();
1473 if (fromtype->ty == Tsarray) {
1474 Logger::cout() << "uvalTy = " << *uval->getType() << '\n';
1475 assert(isaPointer(uval->getType()));
1476 const llvm::ArrayType* arrty = isaArray(uval->getType()->getContainedType(0));
1477 rval2 = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false);
1478 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
1479 rval = new llvm::BitCastInst(uval, ptrty, "tmp", gIR->scopebb());
1480 }
1481 else {
1482 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
1483 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
1484 rval2 = DtoGEP(uval,zero,zero,"tmp",gIR->scopebb());
1485 rval2 = new llvm::LoadInst(rval2, "tmp", gIR->scopebb());
1486 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
1487
1488 rval = DtoGEP(uval,zero,one,"tmp",gIR->scopebb());
1489 rval = new llvm::LoadInst(rval, "tmp", gIR->scopebb());
1490 //Logger::cout() << *e->mem->getType() << '|' << *ptrty << '\n';
1491 rval = new llvm::BitCastInst(rval, ptrty, "tmp", gIR->scopebb());
1492 }
1493 }
1494 isslice = true;
1495 }
1496 else if (totype->ty == Tsarray) {
1497 Logger::cout() << "to sarray" << '\n';
1498 assert(0);
1499 }
1500 else {
1501 assert(0);
1502 }
1503
1504 if (isslice) {
1505 Logger::println("isslice");
1506 return new DSliceValue(to, rval2, rval);
1507 }
1508
1509 return new DImValue(to, rval);
1510 }
1511
1512 DValue* DtoCast(DValue* val, Type* to)
1513 {
1514 Type* fromtype = DtoDType(val->getType());
1515 if (fromtype->isintegral()) {
1516 return DtoCastInt(val, to);
1517 }
1518 else if (fromtype->isfloating()) {
1519 return DtoCastFloat(val, to);
1520 }
1521 else if (fromtype->ty == Tclass) {
1522 return DtoCastClass(val, to);
1523 }
1524 else if (fromtype->ty == Tarray || fromtype->ty == Tsarray) {
1525 return DtoCastArray(val, to);
1526 }
1527 else if (fromtype->ty == Tpointer) {
1528 return DtoCastPtr(val, to);
1529 }
1530 else {
1531 assert(0);
1532 }
1533 }
1534
1535 //////////////////////////////////////////////////////////////////////////////////////////
1308 1536
1309 llvm::ConstantInt* DtoConstSize_t(size_t i) 1537 llvm::ConstantInt* DtoConstSize_t(size_t i)
1310 { 1538 {
1311 return llvm::ConstantInt::get(DtoSize_t(), i, false); 1539 return llvm::ConstantInt::get(DtoSize_t(), i, false);
1312 } 1540 }