Mercurial > projects > ldc
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 } |