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