comparison gen/toir.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
93 // do nothing 93 // do nothing
94 } 94 }
95 // unsupported declaration 95 // unsupported declaration
96 else 96 else
97 { 97 {
98 error("Only Var/Struct-Declaration is supported for DeclarationExp"); 98 error("Unimplemented DeclarationExp type");
99 assert(0); 99 assert(0);
100 } 100 }
101 return 0; 101 return 0;
102 } 102 }
103 103
1339 { 1339 {
1340 Logger::print("CastExp::toElem: %s | %s\n", toChars(), type->toChars()); 1340 Logger::print("CastExp::toElem: %s | %s\n", toChars(), type->toChars());
1341 LOG_SCOPE; 1341 LOG_SCOPE;
1342 1342
1343 DValue* u = e1->toElem(p); 1343 DValue* u = e1->toElem(p);
1344 1344 DValue* v = DtoCast(u, to);
1345 const llvm::Type* tolltype = DtoType(to); 1345
1346 Type* fromtype = DtoDType(e1->type); 1346 if (v->isSlice())
1347 Type* totype = DtoDType(to); 1347 return v;
1348 int lsz = fromtype->size(); 1348 else if (u->isLValueCast() || (u->isVar() && u->isVar()->lval))
1349 int rsz = totype->size(); 1349 return new DLValueCast(to, u->getLVal(), v->getRVal());
1350 1350 else if (gIR->topexp() && gIR->topexp()->e1 == this) {
1351 // this makes sure the strange lvalue casts don't screw things up
1352 llvm::Value* rval = 0;
1353 llvm::Value* rval2 = 0;
1354 bool isslice = false;
1355
1356 if (fromtype->isintegral()) {
1357 if (totype->isintegral()) {
1358 if (lsz < rsz) {
1359 Logger::cout() << "cast to: " << *tolltype << '\n';
1360 if (fromtype->isunsigned() || fromtype->ty == Tbool) {
1361 rval = new llvm::ZExtInst(u->getRVal(), tolltype, "tmp", p->scopebb());
1362 } else {
1363 rval = new llvm::SExtInst(u->getRVal(), tolltype, "tmp", p->scopebb());
1364 }
1365 }
1366 else if (lsz > rsz) {
1367 rval = new llvm::TruncInst(u->getRVal(), tolltype, "tmp", p->scopebb());
1368 }
1369 else {
1370 rval = new llvm::BitCastInst(u->getRVal(), tolltype, "tmp", p->scopebb());
1371 }
1372 }
1373 else if (totype->isfloating()) {
1374 if (fromtype->isunsigned()) {
1375 rval = new llvm::UIToFPInst(u->getRVal(), tolltype, "tmp", p->scopebb());
1376 }
1377 else {
1378 rval = new llvm::SIToFPInst(u->getRVal(), tolltype, "tmp", p->scopebb());
1379 }
1380 }
1381 else if (totype->ty == Tpointer) {
1382 rval = p->ir->CreateIntToPtr(u->getRVal(), tolltype, "tmp");
1383 }
1384 else {
1385 assert(0);
1386 }
1387 }
1388 else if (fromtype->isfloating()) {
1389 if (totype->isfloating()) {
1390 if ((fromtype->ty == Tfloat80 || fromtype->ty == Tfloat64) && (totype->ty == Tfloat80 || totype->ty == Tfloat64)) {
1391 rval = u->getRVal();
1392 }
1393 else if (lsz < rsz) {
1394 rval = new llvm::FPExtInst(u->getRVal(), tolltype, "tmp", p->scopebb());
1395 }
1396 else if (lsz > rsz) {
1397 rval = new llvm::FPTruncInst(u->getRVal(), tolltype, "tmp", p->scopebb());
1398 }
1399 else {
1400 assert(0);
1401 }
1402 }
1403 else if (totype->isintegral()) {
1404 if (totype->isunsigned()) {
1405 rval = new llvm::FPToUIInst(u->getRVal(), tolltype, "tmp", p->scopebb());
1406 }
1407 else {
1408 rval = new llvm::FPToSIInst(u->getRVal(), tolltype, "tmp", p->scopebb());
1409 }
1410 }
1411 else {
1412 assert(0);
1413 }
1414 }
1415 else if (fromtype->ty == Tclass) {
1416 //assert(to->ty == Tclass);
1417 rval = new llvm::BitCastInst(u->getRVal(), tolltype, "tmp", p->scopebb());
1418 }
1419 else if (fromtype->ty == Tarray || fromtype->ty == Tsarray) {
1420 Logger::cout() << "from array or sarray" << '\n';
1421 if (totype->ty == Tpointer) {
1422 Logger::cout() << "to pointer" << '\n';
1423 assert(fromtype->next == totype->next || totype->next->ty == Tvoid);
1424 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
1425 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
1426 llvm::Value* ptr = DtoGEP(u->getRVal(),zero,one,"tmp",p->scopebb());
1427 rval = new llvm::LoadInst(ptr, "tmp", p->scopebb());
1428 if (fromtype->next != totype->next)
1429 rval = p->ir->CreateBitCast(rval, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp");
1430 }
1431 else if (totype->ty == Tarray) {
1432 Logger::cout() << "to array" << '\n';
1433 const llvm::Type* ptrty = DtoType(totype->next);
1434 if (ptrty == llvm::Type::VoidTy)
1435 ptrty = llvm::Type::Int8Ty;
1436 ptrty = llvm::PointerType::get(ptrty);
1437
1438 const llvm::Type* ety = DtoType(fromtype->next);
1439 if (ety == llvm::Type::VoidTy)
1440 ety = llvm::Type::Int8Ty;
1441
1442 if (DSliceValue* usl = u->isSlice()) {
1443 rval = new llvm::BitCastInst(usl->ptr, ptrty, "tmp", p->scopebb());
1444 if (fromtype->next->size() == totype->next->size())
1445 rval2 = usl->len;
1446 else
1447 rval2 = DtoArrayCastLength(usl->len, ety, ptrty->getContainedType(0));
1448 }
1449 else {
1450 llvm::Value* uval = u->getRVal();
1451 if (fromtype->ty == Tsarray) {
1452 Logger::cout() << "uvalTy = " << *uval->getType() << '\n';
1453 assert(isaPointer(uval->getType()));
1454 const llvm::ArrayType* arrty = isaArray(uval->getType()->getContainedType(0));
1455 rval2 = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false);
1456 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
1457 rval = new llvm::BitCastInst(uval, ptrty, "tmp", p->scopebb());
1458 }
1459 else {
1460 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
1461 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
1462 rval2 = DtoGEP(uval,zero,zero,"tmp",p->scopebb());
1463 rval2 = new llvm::LoadInst(rval2, "tmp", p->scopebb());
1464 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
1465
1466 rval = DtoGEP(uval,zero,one,"tmp",p->scopebb());
1467 rval = new llvm::LoadInst(rval, "tmp", p->scopebb());
1468 //Logger::cout() << *e->mem->getType() << '|' << *ptrty << '\n';
1469 rval = new llvm::BitCastInst(rval, ptrty, "tmp", p->scopebb());
1470 }
1471 }
1472 isslice = true;
1473 }
1474 else if (totype->ty == Tsarray) {
1475 Logger::cout() << "to sarray" << '\n';
1476 assert(0);
1477 }
1478 else {
1479 assert(0);
1480 }
1481 }
1482 else if (fromtype->ty == Tpointer) {
1483 if (totype->ty == Tpointer || totype->ty == Tclass) {
1484 llvm::Value* src = u->getRVal();
1485 Logger::cout() << "src: " << *src << "to type: " << *tolltype << '\n';
1486 rval = new llvm::BitCastInst(src, tolltype, "tmp", p->scopebb());
1487 }
1488 else if (totype->isintegral()) {
1489 rval = new llvm::PtrToIntInst(u->getRVal(), tolltype, "tmp", p->scopebb());
1490 }
1491 else
1492 assert(0);
1493 }
1494 else {
1495 assert(0);
1496 }
1497
1498 if (isslice) {
1499 return new DSliceValue(type, rval2, rval);
1500 }
1501 else if (u->isLValueCast() || (u->isVar() && u->isVar()->lval)) {
1502 return new DLValueCast(type, u->getLVal(), rval);
1503 }
1504 else if (p->topexp() && p->topexp()->e1 == this) {
1505 llvm::Value* lval = u->getLVal(); 1351 llvm::Value* lval = u->getLVal();
1352 llvm::Value* rval = v->getRVal();
1506 Logger::cout() << "lval: " << *lval << "rval: " << *rval << '\n'; 1353 Logger::cout() << "lval: " << *lval << "rval: " << *rval << '\n';
1507 return new DLValueCast(type, lval, rval); 1354 return new DLValueCast(to, lval, rval);
1508 } 1355 }
1509 else { 1356
1510 Logger::cout() << "im rval: " << *rval << '\n'; 1357 return v;
1511 return new DImValue(type, rval);
1512 }
1513 } 1358 }
1514 1359
1515 ////////////////////////////////////////////////////////////////////////////////////////// 1360 //////////////////////////////////////////////////////////////////////////////////////////
1516 1361
1517 DValue* SymOffExp::toElem(IRState* p) 1362 DValue* SymOffExp::toElem(IRState* p)