Mercurial > projects > ldc
comparison gen/tollvm.cpp @ 104:4d1e9eb001e0 trunk
[svn r108] Now basic suppport for complex types. =,+,-,*,/ are supported.
author | lindquist |
---|---|
date | Mon, 19 Nov 2007 02:58:58 +0100 |
parents | 855adfdb8d38 |
children | 5b5194b25f33 |
comparison
equal
deleted
inserted
replaced
103:855adfdb8d38 | 104:4d1e9eb001e0 |
---|---|
16 #include "gen/dvalue.h" | 16 #include "gen/dvalue.h" |
17 #include "gen/functions.h" | 17 #include "gen/functions.h" |
18 #include "gen/structs.h" | 18 #include "gen/structs.h" |
19 #include "gen/classes.h" | 19 #include "gen/classes.h" |
20 #include "gen/typeinf.h" | 20 #include "gen/typeinf.h" |
21 #include "gen/complex.h" | |
21 | 22 |
22 bool DtoIsPassedByRef(Type* type) | 23 bool DtoIsPassedByRef(Type* type) |
23 { | 24 { |
24 TY t = DtoDType(type)->ty; | 25 Type* typ = DtoDType(type); |
25 return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray); | 26 TY t = typ->ty; |
27 return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray || typ->iscomplex()); | |
26 } | 28 } |
27 | 29 |
28 Type* DtoDType(Type* t) | 30 Type* DtoDType(Type* t) |
29 { | 31 { |
30 if (t->ty == Ttypedef) { | 32 if (t->ty == Ttypedef) { |
70 case Timaginary80: | 72 case Timaginary80: |
71 return llvm::Type::DoubleTy; | 73 return llvm::Type::DoubleTy; |
72 | 74 |
73 // complex | 75 // complex |
74 case Tcomplex32: | 76 case Tcomplex32: |
75 return DtoComplexType(llvm::Type::FloatTy); | |
76 case Tcomplex64: | 77 case Tcomplex64: |
77 case Tcomplex80: | 78 case Tcomplex80: |
78 return DtoComplexType(llvm::Type::DoubleTy); | 79 return DtoComplexType(t); |
79 | 80 |
80 // pointers | 81 // pointers |
81 case Tpointer: { | 82 case Tpointer: { |
82 assert(t->next); | 83 assert(t->next); |
83 if (t->next->ty == Tvoid) | 84 if (t->next->ty == Tvoid) |
189 const llvm::Type* funcptr = llvm::PointerType::get(func); | 190 const llvm::Type* funcptr = llvm::PointerType::get(func); |
190 | 191 |
191 std::vector<const llvm::Type*> types; | 192 std::vector<const llvm::Type*> types; |
192 types.push_back(i8ptr); | 193 types.push_back(i8ptr); |
193 types.push_back(funcptr); | 194 types.push_back(funcptr); |
194 return llvm::StructType::get(types); | |
195 } | |
196 | |
197 ////////////////////////////////////////////////////////////////////////////////////////// | |
198 | |
199 const llvm::StructType* DtoComplexType(const llvm::Type* base) | |
200 { | |
201 std::vector<const llvm::Type*> types; | |
202 types.push_back(base); | |
203 types.push_back(base); | |
204 return llvm::StructType::get(types); | 195 return llvm::StructType::get(types); |
205 } | 196 } |
206 | 197 |
207 ////////////////////////////////////////////////////////////////////////////////////////// | 198 ////////////////////////////////////////////////////////////////////////////////////////// |
208 | 199 |
900 // regular class ref -> class ref assignment | 891 // regular class ref -> class ref assignment |
901 else { | 892 else { |
902 DtoStore(rhs->getRVal(), lhs->getLVal()); | 893 DtoStore(rhs->getRVal(), lhs->getLVal()); |
903 } | 894 } |
904 } | 895 } |
896 else if (t->iscomplex()) { | |
897 assert(!lhs->isComplex()); | |
898 if (DComplexValue* cx = rhs->isComplex()) { | |
899 DtoComplexSet(lhs->getRVal(), cx->re, cx->im); | |
900 } | |
901 else { | |
902 DtoComplexAssign(lhs->getRVal(), rhs->getRVal()); | |
903 } | |
904 } | |
905 else { | 905 else { |
906 llvm::Value* r = rhs->getRVal(); | 906 llvm::Value* r = rhs->getRVal(); |
907 llvm::Value* l = lhs->getLVal(); | 907 llvm::Value* l = lhs->getLVal(); |
908 Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; | 908 Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; |
909 const llvm::Type* lit = l->getType()->getContainedType(0); | 909 const llvm::Type* lit = l->getType()->getContainedType(0); |
988 return new DImValue(to, rval); | 988 return new DImValue(to, rval); |
989 } | 989 } |
990 | 990 |
991 DValue* DtoCastFloat(DValue* val, Type* to) | 991 DValue* DtoCastFloat(DValue* val, Type* to) |
992 { | 992 { |
993 if (val->getType() == to) | |
994 return val; | |
995 | |
993 const llvm::Type* tolltype = DtoType(to); | 996 const llvm::Type* tolltype = DtoType(to); |
994 | 997 |
995 Type* totype = DtoDType(to); | 998 Type* totype = DtoDType(to); |
996 Type* fromtype = DtoDType(val->getType()); | 999 Type* fromtype = DtoDType(val->getType()); |
997 assert(fromtype->isfloating()); | 1000 assert(fromtype->isfloating()); |
999 size_t fromsz = fromtype->size(); | 1002 size_t fromsz = fromtype->size(); |
1000 size_t tosz = totype->size(); | 1003 size_t tosz = totype->size(); |
1001 | 1004 |
1002 llvm::Value* rval; | 1005 llvm::Value* rval; |
1003 | 1006 |
1004 if (totype->isfloating()) { | 1007 if (totype->iscomplex()) { |
1008 assert(0); | |
1009 //return new DImValue(to, DtoComplex(to, val)); | |
1010 } | |
1011 else if (totype->isfloating()) { | |
1005 if ((fromtype->ty == Tfloat80 || fromtype->ty == Tfloat64) && (totype->ty == Tfloat80 || totype->ty == Tfloat64)) { | 1012 if ((fromtype->ty == Tfloat80 || fromtype->ty == Tfloat64) && (totype->ty == Tfloat80 || totype->ty == Tfloat64)) { |
1006 rval = val->getRVal(); | 1013 rval = val->getRVal(); |
1007 } | 1014 } |
1008 else if (fromsz < tosz) { | 1015 else if (fromsz < tosz) { |
1009 rval = new llvm::FPExtInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); | 1016 rval = new llvm::FPExtInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); |
1026 else { | 1033 else { |
1027 assert(0 && "bad float cast"); | 1034 assert(0 && "bad float cast"); |
1028 } | 1035 } |
1029 | 1036 |
1030 return new DImValue(to, rval); | 1037 return new DImValue(to, rval); |
1038 } | |
1039 | |
1040 DValue* DtoCastComplex(DValue* val, Type* _to) | |
1041 { | |
1042 Type* to = DtoDType(_to); | |
1043 llvm::Value* v = val->getRVal(); | |
1044 if (to->iscomplex()) { | |
1045 assert(0); | |
1046 } | |
1047 else if (to->isimaginary()) { | |
1048 DImValue* im = new DImValue(to, gIR->ir->CreateExtractElement(v, DtoConstUint(1), "im")); | |
1049 return DtoCastFloat(im, to); | |
1050 } | |
1051 else if (to->isfloating()) { | |
1052 DImValue* re = new DImValue(to, gIR->ir->CreateExtractElement(v, DtoConstUint(0), "re")); | |
1053 return DtoCastFloat(re, to); | |
1054 } | |
1055 else | |
1056 assert(0); | |
1031 } | 1057 } |
1032 | 1058 |
1033 DValue* DtoCastClass(DValue* val, Type* _to) | 1059 DValue* DtoCastClass(DValue* val, Type* _to) |
1034 { | 1060 { |
1035 const llvm::Type* tolltype = DtoType(_to); | 1061 const llvm::Type* tolltype = DtoType(_to); |
1043 { | 1069 { |
1044 Type* fromtype = DtoDType(val->getType()); | 1070 Type* fromtype = DtoDType(val->getType()); |
1045 if (fromtype->isintegral()) { | 1071 if (fromtype->isintegral()) { |
1046 return DtoCastInt(val, to); | 1072 return DtoCastInt(val, to); |
1047 } | 1073 } |
1074 else if (fromtype->iscomplex()) { | |
1075 return DtoCastComplex(val, to); | |
1076 } | |
1048 else if (fromtype->isfloating()) { | 1077 else if (fromtype->isfloating()) { |
1049 return DtoCastFloat(val, to); | 1078 return DtoCastFloat(val, to); |
1050 } | 1079 } |
1051 else if (fromtype->ty == Tclass) { | 1080 else if (fromtype->ty == Tclass) { |
1052 return DtoCastClass(val, to); | 1081 return DtoCastClass(val, to); |
1078 } | 1107 } |
1079 llvm::Constant* DtoConstBool(bool b) | 1108 llvm::Constant* DtoConstBool(bool b) |
1080 { | 1109 { |
1081 return llvm::ConstantInt::get(llvm::Type::Int1Ty, b, false); | 1110 return llvm::ConstantInt::get(llvm::Type::Int1Ty, b, false); |
1082 } | 1111 } |
1112 | |
1113 llvm::ConstantFP* DtoConstFP(Type* t, long double value) | |
1114 { | |
1115 TY ty = DtoDType(t)->ty; | |
1116 if (ty == Tfloat32 || ty == Timaginary32) | |
1117 return llvm::ConstantFP::get(llvm::Type::FloatTy, float(value)); | |
1118 else if (ty == Tfloat64 || ty == Timaginary64 || ty == Tfloat80 || ty == Timaginary80) | |
1119 return llvm::ConstantFP::get(llvm::Type::DoubleTy, double(value)); | |
1120 } | |
1121 | |
1083 | 1122 |
1084 ////////////////////////////////////////////////////////////////////////////////////////// | 1123 ////////////////////////////////////////////////////////////////////////////////////////// |
1085 | 1124 |
1086 llvm::Constant* DtoConstString(const char* str) | 1125 llvm::Constant* DtoConstString(const char* str) |
1087 { | 1126 { |
1163 return ptr->getType()->getContainedType(0)->isFirstClassType(); | 1202 return ptr->getType()->getContainedType(0)->isFirstClassType(); |
1164 } | 1203 } |
1165 return false; | 1204 return false; |
1166 } | 1205 } |
1167 | 1206 |
1207 ////////////////////////////////////////////////////////////////////////////////////////// | |
1208 | |
1168 llvm::Value* DtoBitCast(llvm::Value* v, const llvm::Type* t) | 1209 llvm::Value* DtoBitCast(llvm::Value* v, const llvm::Type* t) |
1169 { | 1210 { |
1170 if (v->getType() == t) | 1211 if (v->getType() == t) |
1171 return v; | 1212 return v; |
1172 return gIR->ir->CreateBitCast(v, t, "tmp"); | 1213 return gIR->ir->CreateBitCast(v, t, "tmp"); |
1173 } | 1214 } |
1215 | |
1216 ////////////////////////////////////////////////////////////////////////////////////////// | |
1174 | 1217 |
1175 const llvm::PointerType* isaPointer(llvm::Value* v) | 1218 const llvm::PointerType* isaPointer(llvm::Value* v) |
1176 { | 1219 { |
1177 return llvm::dyn_cast<llvm::PointerType>(v->getType()); | 1220 return llvm::dyn_cast<llvm::PointerType>(v->getType()); |
1178 } | 1221 } |