Mercurial > projects > ddmd
annotate dmd/CastExp.d @ 135:af1bebfd96a4 dmd2037
dmd 2.038
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Mon, 13 Sep 2010 22:19:42 +0100 |
parents | 60bb0fe4563e |
children | e3afd1303184 |
rev | line source |
---|---|
72 | 1 module dmd.CastExp; |
2 | |
114 | 3 import dmd.common; |
72 | 4 import dmd.Expression; |
129 | 5 import dmd.GlobalExpressions; |
72 | 6 import dmd.TY; |
7 import dmd.TypeStruct; | |
73 | 8 import dmd.ErrorExp; |
72 | 9 import dmd.TypeExp; |
10 import dmd.DotIdExp; | |
11 import dmd.CallExp; | |
12 import dmd.Global; | |
13 import dmd.Id; | |
14 import dmd.Identifier; | |
15 import dmd.BinExp; | |
16 import dmd.UnaExp; | |
17 import dmd.VarExp; | |
18 import dmd.Token; | |
19 import dmd.VarDeclaration; | |
20 import dmd.InterState; | |
21 import dmd.MATCH; | |
22 import dmd.Type; | |
23 import dmd.OutBuffer; | |
24 import dmd.Loc; | |
25 import dmd.Scope; | |
26 import dmd.IntRange; | |
27 import dmd.IRState; | |
28 import dmd.ArrayTypes; | |
29 import dmd.HdrGenState; | |
30 import dmd.MOD; | |
31 import dmd.TOK; | |
32 import dmd.WANT; | |
33 import dmd.ClassDeclaration; | |
34 | |
35 import dmd.Optimize; | |
36 import dmd.PREC; | |
37 import dmd.Cast; | |
38 | |
79 | 39 import dmd.codegen.Util; |
40 import dmd.backend.elem; | |
41 import dmd.backend.mTY; | |
72 | 42 import dmd.backend.Util; |
43 import dmd.backend.TYM; | |
44 import dmd.backend.OPER; | |
45 import dmd.backend.RTLSYM; | |
79 | 46 import dmd.expression.Util; |
72 | 47 |
0 | 48 class CastExp : UnaExp |
49 { | |
72 | 50 // Possible to cast to one type while painting to another type |
0 | 51 Type to; // type to cast to |
52 MOD mod; // MODxxxxx | |
53 | |
54 this(Loc loc, Expression e, Type t) | |
55 { | |
72 | 56 super(loc, TOK.TOKcast, CastExp.sizeof, e); |
57 to = t; | |
0 | 58 this.mod = cast(MOD)~0; |
59 } | |
60 | |
61 this(Loc loc, Expression e, MOD mod) | |
72 | 62 { |
63 super(loc, TOK.TOKcast, CastExp.sizeof, e); | |
64 to = null; | |
0 | 65 this.mod = mod; |
66 } | |
67 | |
72 | 68 override Expression syntaxCopy() |
0 | 69 { |
72 | 70 return to ? new CastExp(loc, e1.syntaxCopy(), to.syntaxCopy()) |
0 | 71 : new CastExp(loc, e1.syntaxCopy(), mod); |
72 } | |
73 | |
72 | 74 override Expression semantic(Scope sc) |
0 | 75 { |
72 | 76 Expression e; |
77 BinExp b; | |
78 UnaExp u; | |
79 | |
80 version (LOGSEMANTIC) { | |
81 printf("CastExp.semantic('%s')\n", toChars()); | |
82 } | |
83 | |
84 //static int x; assert(++x < 10); | |
85 | |
86 if (type) | |
87 return this; | |
88 super.semantic(sc); | |
89 if (e1.type) // if not a tuple | |
90 { | |
73 | 91 e1 = resolveProperties(sc, e1); |
92 | |
93 if (!to) | |
94 { | |
95 /* Handle cast(const) and cast(immutable), etc. | |
96 */ | |
97 to = e1.type.castMod(mod); | |
98 } | |
99 else | |
100 to = to.semantic(loc, sc); | |
101 | |
102 if (!to.equals(e1.type)) | |
103 { | |
104 e = op_overload(sc); | |
105 if (e) | |
106 { | |
107 return e.implicitCastTo(sc, to); | |
108 } | |
109 } | |
72 | 110 |
109 | 111 if (e1.op == TOKtemplate) |
112 { | |
113 error("cannot cast template %s to type %s", e1.toChars(), to.toChars()); | |
114 return new ErrorExp(); | |
115 } | |
116 | |
73 | 117 Type t1b = e1.type.toBasetype(); |
118 Type tob = to.toBasetype(); | |
119 if (tob.ty == TY.Tstruct && | |
120 !tob.equals(t1b) && | |
121 (cast(TypeStruct)tob).sym.search(Loc(0), Id.call, 0) | |
122 ) | |
123 { | |
124 /* Look to replace: | |
125 * cast(S)t | |
126 * with: | |
127 * S(t) | |
128 */ | |
72 | 129 |
73 | 130 // Rewrite as to.call(e1) |
131 e = new TypeExp(loc, to); | |
132 e = new DotIdExp(loc, e, Id.call); | |
133 e = new CallExp(loc, e, e1); | |
134 e = e.semantic(sc); | |
135 return e; | |
136 } | |
137 | |
138 // Struct casts are possible only when the sizes match | |
139 if (tob.ty == Tstruct || t1b.ty == Tstruct) | |
72 | 140 { |
73 | 141 size_t fromsize = cast(size_t)t1b.size(loc); |
142 size_t tosize = cast(size_t)tob.size(loc); | |
143 if (fromsize != tosize) | |
144 { | |
145 error("cannot cast from %s to %s", e1.type.toChars(), to.toChars()); | |
146 return new ErrorExp(); | |
147 } | |
72 | 148 } |
149 } | |
150 else if (!to) | |
73 | 151 { |
152 error("cannot cast tuple"); | |
153 to = Type.terror; | |
72 | 154 } |
155 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
156 //static if (true) { |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
157 if (sc.func && sc.func.isSafe() && !sc.intypeof) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
158 //} else { |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
159 // if (global.params.safe && !sc.module_.safe && !sc.intypeof) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
160 //} |
72 | 161 { // Disallow unsafe casts |
162 Type tob = to.toBasetype(); | |
163 Type t1b = e1.type.toBasetype(); | |
164 if (!t1b.isMutable() && tob.isMutable()) | |
165 { // Cast not mutable to mutable | |
166 Lunsafe: | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
167 error("cast from %s to %s not allowed in safe code", e1.type.toChars(), to.toChars()); |
72 | 168 } |
169 else if (t1b.isShared() && !tob.isShared()) | |
170 // Cast away shared | |
171 goto Lunsafe; | |
172 else if (tob.ty == TY.Tpointer) | |
173 { if (t1b.ty != TY.Tpointer) | |
174 goto Lunsafe; | |
175 Type tobn = tob.nextOf().toBasetype(); | |
176 Type t1bn = t1b.nextOf().toBasetype(); | |
177 | |
178 if (!t1bn.isMutable() && tobn.isMutable()) | |
179 // Cast away pointer to not mutable | |
180 goto Lunsafe; | |
181 | |
182 if (t1bn.isShared() && !tobn.isShared()) | |
183 // Cast away pointer to shared | |
184 goto Lunsafe; | |
185 | |
135 | 186 if (t1bn.isWild() && !tobn.isConst() && !tobn.isWild()) |
187 // Cast wild to anything but const | wild | |
188 goto Lunsafe; | |
189 | |
72 | 190 if (tobn.isTypeBasic() && tobn.size() < t1bn.size()) { |
191 // Allow things like casting a long* to an int* | |
192 ; | |
193 } else if (tobn.ty != TY.Tvoid) { | |
194 // Cast to a pointer other than void* | |
195 goto Lunsafe; | |
196 } | |
197 } | |
198 | |
199 // BUG: Check for casting array types, such as void[] to int*[] | |
200 } | |
201 | |
202 e = e1.castTo(sc, to); | |
0 | 203 return e; |
204 } | |
205 | |
72 | 206 override MATCH implicitConvTo(Type t) |
0 | 207 { |
72 | 208 static if (false) { |
209 printf("CastExp::implicitConvTo(this=%s, type=%s, t=%s)\n", toChars(), type.toChars(), t.toChars()); | |
210 } | |
211 MATCH result = type.implicitConvTo(t); | |
212 | |
213 if (result == MATCHnomatch) | |
214 { | |
215 if (t.isintegral() && | |
216 e1.type.isintegral() && | |
217 e1.implicitConvTo(t) != MATCHnomatch) | |
218 result = MATCHconvert; | |
219 else | |
220 result = Expression.implicitConvTo(t); | |
221 } | |
0 | 222 return result; |
223 } | |
224 | |
72 | 225 override IntRange getIntRange() |
0 | 226 { |
72 | 227 IntRange ir; |
228 ir = e1.getIntRange(); | |
229 // Do sign extension | |
230 switch (e1.type.toBasetype().ty) | |
231 { | |
232 case Tint8: | |
233 if (ir.imax & 0x80) | |
234 ir.imax |= 0xFFFFFFFFFFFFFF00UL; | |
235 break; | |
236 case Tint16: | |
237 if (ir.imax & 0x8000) | |
238 ir.imax |= 0xFFFFFFFFFFFF0000UL; | |
239 break; | |
240 case Tint32: | |
241 if (ir.imax & 0x80000000) | |
242 ir.imax |= 0xFFFFFFFF00000000UL; | |
243 break; | |
244 default: | |
245 } | |
73 | 246 |
247 if (type.isintegral()) | |
248 { | |
249 ir.imin &= type.sizemask(); | |
250 ir.imax &= type.sizemask(); | |
251 } | |
252 | |
253 //printf("CastExp: imin = x%llx, imax = x%llx\n", ir.imin, ir.imax); | |
53 | 254 return ir; |
0 | 255 } |
256 | |
72 | 257 override Expression optimize(int result) |
258 { | |
259 //printf("CastExp.optimize(result = %d) %s\n", result, toChars()); | |
260 //printf("from %s to %s\n", type.toChars(), to.toChars()); | |
261 //printf("from %s\n", type.toChars()); | |
262 //printf("e1.type %s\n", e1.type.toChars()); | |
263 //printf("type = %p\n", type); | |
264 assert(type); | |
265 TOK op1 = e1.op; | |
266 | |
267 Expression e1old = e1; | |
268 e1 = e1.optimize(result); | |
269 e1 = fromConstInitializer(result, e1); | |
270 | |
271 if (e1 == e1old && | |
272 e1.op == TOK.TOKarrayliteral && | |
273 type.toBasetype().ty == TY.Tpointer && | |
274 e1.type.toBasetype().ty != TY.Tsarray) | |
275 { | |
276 // Casting this will result in the same expression, and | |
277 // infinite loop because of Expression.implicitCastTo() | |
278 return this; // no change | |
279 } | |
280 | |
281 if ((e1.op == TOK.TOKstring || e1.op == TOK.TOKarrayliteral) && | |
282 (type.ty == TY.Tpointer || type.ty == TY.Tarray) && | |
283 e1.type.nextOf().size() == type.nextOf().size() | |
284 ) | |
285 { | |
286 Expression e = e1.castTo(null, type); | |
287 | |
288 static if (false) { | |
289 printf(" returning1 %s\n", e.toChars()); | |
290 } | |
291 return e; | |
292 } | |
293 | |
294 if (e1.op == TOK.TOKstructliteral && | |
295 e1.type.implicitConvTo(type) >= MATCH.MATCHconst) | |
296 { | |
297 e1.type = type; | |
298 static if (false) { | |
299 printf(" returning2 %s\n", e1.toChars()); | |
300 } | |
301 return e1; | |
302 } | |
303 | |
304 /* The first test here is to prevent infinite loops | |
305 */ | |
306 if (op1 != TOK.TOKarrayliteral && e1.op == TOK.TOKarrayliteral) | |
307 return e1.castTo(null, to); | |
308 if (e1.op == TOK.TOKnull && | |
309 (type.ty == TY.Tpointer || type.ty == TY.Tclass || type.ty == TY.Tarray)) | |
310 { | |
311 e1.type = type; | |
312 static if (false) { | |
313 printf(" returning3 %s\n", e1.toChars()); | |
314 } | |
315 return e1; | |
316 } | |
317 | |
318 if (result & WANT.WANTflags && type.ty == TY.Tclass && e1.type.ty == TY.Tclass) | |
319 { | |
320 // See if we can remove an unnecessary cast | |
321 ClassDeclaration cdfrom; | |
322 ClassDeclaration cdto; | |
323 int offset; | |
324 | |
325 cdfrom = e1.type.isClassHandle(); | |
326 cdto = type.isClassHandle(); | |
327 if (cdto.isBaseOf(cdfrom, &offset) && offset == 0) | |
328 { | |
329 e1.type = type; | |
330 static if (false) { | |
331 printf(" returning4 %s\n", e1.toChars()); | |
332 } | |
333 return e1; | |
334 } | |
335 } | |
336 | |
337 // We can convert 'head const' to mutable | |
338 if (to.constOf().equals(e1.type.constOf())) | |
339 // if (to.constConv(e1.type) >= MATCHconst) | |
340 { | |
341 e1.type = type; | |
342 static if (false) { | |
343 printf(" returning5 %s\n", e1.toChars()); | |
344 } | |
345 return e1; | |
346 } | |
347 | |
348 Expression e; | |
349 | |
350 if (e1.isConst()) | |
351 { | |
352 if (e1.op == TOK.TOKsymoff) | |
353 { | |
354 if (type.size() == e1.type.size() && | |
355 type.toBasetype().ty != TY.Tsarray) | |
356 { | |
357 e1.type = type; | |
358 return e1; | |
359 } | |
360 return this; | |
361 } | |
362 if (to.toBasetype().ty == TY.Tvoid) | |
363 e = this; | |
364 else | |
365 e = Cast(type, to, e1); | |
366 } | |
367 else | |
368 e = this; | |
369 static if (false) { | |
370 printf(" returning6 %s\n", e.toChars()); | |
371 } | |
0 | 372 return e; |
373 } | |
374 | |
72 | 375 override Expression interpret(InterState istate) |
0 | 376 { |
129 | 377 Expression e; |
378 Expression e1; | |
379 | |
380 version (LOG) { | |
381 printf("CastExp.interpret() %.*s\n", toChars()); | |
382 } | |
383 e1 = this.e1.interpret(istate); | |
384 if (e1 is EXP_CANT_INTERPRET) | |
385 goto Lcant; | |
386 return Cast(type, to, e1); | |
387 | |
388 Lcant: | |
389 version (LOG) { | |
390 printf("CastExp.interpret() %.*s CANT\n", toChars()); | |
391 } | |
392 return EXP_CANT_INTERPRET; | |
0 | 393 } |
394 | |
72 | 395 override bool checkSideEffect(int flag) |
0 | 396 { |
123 | 397 /* if not: |
398 * cast(void) | |
399 * cast(classtype)func() | |
400 */ | |
401 if (!to.equals(Type.tvoid) && !(to.ty == Tclass && e1.op == TOKcall && e1.type.ty == Tclass)) | |
402 return Expression.checkSideEffect(flag); | |
403 | |
404 return true; | |
0 | 405 } |
406 | |
72 | 407 override void checkEscape() |
0 | 408 { |
72 | 409 Type tb = type.toBasetype(); |
410 if (tb.ty == TY.Tarray && e1.op == TOK.TOKvar && e1.type.toBasetype().ty ==TY.Tsarray) | |
411 { | |
412 VarExp ve = cast(VarExp)e1; | |
413 VarDeclaration v = ve.var.isVarDeclaration(); | |
414 if (v) | |
415 { | |
416 if (!v.isDataseg() && !v.isParameter()) | |
417 error("escaping reference to local %s", v.toChars()); | |
418 } | |
0 | 419 } |
420 } | |
421 | |
72 | 422 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 423 { |
72 | 424 buf.writestring("cast("); |
425 version (DMDV1) { | |
426 to.toCBuffer(buf, null, hgs); | |
427 } else { | |
428 if (to) | |
429 to.toCBuffer(buf, null, hgs); | |
430 else | |
431 { | |
135 | 432 MODtoBuffer(buf, mod); |
72 | 433 } |
434 } | |
435 buf.writeByte(')'); | |
0 | 436 expToCBuffer(buf, hgs, e1, precedence[op]); |
437 } | |
438 | |
72 | 439 override void buildArrayIdent(OutBuffer buf, Expressions arguments) |
0 | 440 { |
72 | 441 Type tb = type.toBasetype(); |
442 if (tb.ty == Tarray || tb.ty == Tsarray) | |
443 { | |
444 e1.buildArrayIdent(buf, arguments); | |
445 } | |
446 else | |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
447 Expression.buildArrayIdent(buf, arguments); |
0 | 448 } |
449 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
450 override Expression buildArrayLoop(Parameters fparams) |
0 | 451 { |
72 | 452 Type tb = type.toBasetype(); |
453 if (tb.ty == Tarray || tb.ty == Tsarray) | |
454 { | |
455 return e1.buildArrayLoop(fparams); | |
456 } | |
457 else | |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
458 return Expression.buildArrayLoop(fparams); |
72 | 459 } |
460 | |
461 static int X(int fty, int tty) { | |
462 return ((fty) * TY.TMAX + (tty)); | |
0 | 463 } |
464 | |
72 | 465 override elem* toElem(IRState* irs) |
0 | 466 { |
72 | 467 TY fty; |
468 TY tty; | |
469 tym_t ftym; | |
470 tym_t ttym; | |
471 OPER eop; | |
472 | |
79 | 473 static if (false) |
474 { | |
72 | 475 printf("CastExp::toElem()\n"); |
476 print(); | |
477 printf("\tfrom: %s\n", e1.type.toChars()); | |
478 printf("\tto : %s\n", to.toChars()); | |
479 } | |
480 | |
79 | 481 elem* e = e1.toElem(irs); |
482 Type tfrom = e1.type.toBasetype(); | |
483 Type t = to.toBasetype(); // skip over typedef's | |
72 | 484 if (t.equals(tfrom)) |
485 goto Lret; | |
486 | |
487 fty = tfrom.ty; | |
488 //printf("fty = %d\n", fty); | |
489 tty = t.ty; | |
490 | |
491 if (tty == TY.Tpointer && fty == TY.Tarray | |
492 ///static if (false) { | |
493 /// && (t.next.ty == Tvoid || t.next.equals(e1.type.next)) | |
494 ///} | |
495 ) | |
496 { | |
497 if (e.Eoper == OPER.OPvar) | |
498 { | |
499 // e1 . *(&e1 + 4) | |
500 e = el_una(OPER.OPaddr, TYM.TYnptr, e); | |
501 e = el_bin(OPER.OPadd, TYM.TYnptr, e, el_long(TYM.TYint, 4)); | |
502 e = el_una(OPER.OPind, t.totym(),e); | |
503 } | |
504 else | |
505 { | |
506 // e1 . (unsigned)(e1 >> 32) | |
507 e = el_bin(OPER.OPshr, TYM.TYullong, e, el_long(TYM.TYint, 32)); | |
508 e = el_una(OPER.OP64_32, t.totym(), e); | |
509 } | |
510 goto Lret; | |
511 } | |
512 | |
513 if (tty == TY.Tpointer && fty == TY.Tsarray | |
514 ///static if (false) { | |
515 /// && (t.next.ty == Tvoid || t.next.equals(e1.type.next)) | |
516 ///} | |
517 ) | |
518 { | |
519 // e1 . &e1 | |
520 e = el_una(OPER.OPaddr, TYM.TYnptr, e); | |
521 goto Lret; | |
522 } | |
523 | |
524 // Convert from static array to dynamic array | |
525 if (tty == TY.Tarray && fty == TY.Tsarray) | |
526 { | |
527 e = sarray_toDarray(loc, tfrom, t, e); | |
528 goto Lret; | |
529 } | |
530 | |
531 // Convert from dynamic array to dynamic array | |
532 if (tty == TY.Tarray && fty == TY.Tarray) | |
533 { | |
534 uint fsize = cast(uint)tfrom.nextOf().size(); | |
535 uint tsize = cast(uint)t.nextOf().size(); | |
536 | |
537 if (fsize != tsize) | |
538 { | |
539 elem* ep = el_params(e, el_long(TYM.TYint, fsize), el_long(TYM.TYint, tsize), null); | |
540 e = el_bin(OPER.OPcall, type.totym(), el_var(rtlsym[RTLSYM.RTLSYM_ARRAYCAST]), ep); | |
541 } | |
542 goto Lret; | |
543 } | |
544 | |
79 | 545 static if (false) |
546 { | |
72 | 547 // Convert from dynamic array string literal to static array |
548 if (tty == TY.Tsarray && fty == TY.Tarray && e1.op == TOK.TOKstring) | |
549 { | |
550 goto Lret; // treat as a 'paint' | |
551 } | |
552 } | |
553 | |
554 // Casting from base class to derived class requires a runtime check | |
555 if (fty == TY.Tclass && tty == TY.Tclass) | |
556 { | |
557 // Casting from derived class to base class is a no-op | |
558 ClassDeclaration cdfrom; | |
559 ClassDeclaration cdto; | |
560 int offset; | |
561 int rtl = RTLSYM.RTLSYM_DYNAMIC_CAST; | |
562 | |
563 cdfrom = tfrom.isClassHandle(); | |
564 cdto = t.isClassHandle(); | |
565 if (cdfrom.isInterfaceDeclaration()) | |
566 { | |
567 rtl = RTLSYM.RTLSYM_INTERFACE_CAST; | |
568 if (cdfrom.isCPPinterface()) | |
569 { | |
570 if (cdto.isCPPinterface()) | |
571 { | |
572 /* Casting from a C++ interface to a C++ interface | |
573 * is always a 'paint' operation | |
574 */ | |
575 goto Lret; // no-op | |
576 } | |
577 | |
578 /* Casting from a C++ interface to a class | |
579 * always results in null because there is no runtime | |
580 * information available to do it. | |
581 * | |
582 * Casting from a C++ interface to a non-C++ interface | |
583 * always results in null because there's no way one | |
584 * can be derived from the other. | |
585 */ | |
586 e = el_bin(OPER.OPcomma, TYM.TYnptr, e, el_long(TYM.TYnptr, 0)); | |
587 goto Lret; | |
588 } | |
589 } | |
590 if (cdto.isBaseOf(cdfrom, &offset) && offset != OFFSET_RUNTIME) | |
591 { | |
592 /* The offset from cdfrom=>cdto is known at compile time. | |
593 */ | |
594 | |
595 //printf("offset = %d\n", offset); | |
596 if (offset) | |
597 { | |
598 /* Rewrite cast as (e ? e + offset : null) | |
599 */ | |
600 elem* etmp; | |
601 elem* ex; | |
602 | |
603 if (e1.op == TOK.TOKthis) | |
604 { | |
605 // Assume 'this' is never null, so skip null check | |
606 e = el_bin(OPER.OPadd, TYM.TYnptr, e, el_long(TYM.TYint, offset)); | |
607 } | |
608 else | |
609 { | |
610 etmp = el_same(&e); | |
611 ex = el_bin(OPER.OPadd, TYM.TYnptr, etmp, el_long(TYM.TYint, offset)); | |
612 ex = el_bin(OPER.OPcolon, TYM.TYnptr, ex, el_long(TYM.TYnptr, 0)); | |
613 e = el_bin(OPER.OPcond, TYM.TYnptr, e, ex); | |
614 } | |
615 } | |
616 goto Lret; // no-op | |
617 } | |
618 | |
619 /* The offset from cdfrom=>cdto can only be determined at runtime. | |
620 */ | |
621 elem* ep; | |
622 | |
623 ep = el_param(el_ptr(cdto.toSymbol()), e); | |
624 e = el_bin(OPER.OPcall, TYM.TYnptr, el_var(rtlsym[rtl]), ep); | |
625 goto Lret; | |
626 } | |
627 | |
79 | 628 ftym = tybasic(e.Ety); |
629 ttym = tybasic(t.totym()); | |
72 | 630 if (ftym == ttym) |
631 goto Lret; | |
632 | |
633 switch (tty) | |
634 { | |
635 case TY.Tpointer: | |
636 if (fty == TY.Tdelegate) | |
637 goto Lpaint; | |
638 tty = TY.Tuns32; | |
639 break; | |
640 | |
641 case TY.Tchar: | |
642 tty = TY.Tuns8; | |
643 break; | |
644 case TY.Twchar: | |
645 tty = TY.Tuns16; | |
646 break; | |
647 case TY.Tdchar: | |
648 tty = TY.Tuns32; | |
649 break; | |
650 case TY.Tvoid: | |
651 goto Lpaint; | |
652 | |
653 case TY.Tbool: | |
654 { | |
655 // Construct e?true:false | |
656 elem* eq; | |
657 | |
658 e = el_una(OPER.OPbool, ttym, e); | |
659 goto Lret; | |
660 } | |
661 | |
662 default: | |
663 break; /// | |
664 } | |
665 | |
666 switch (fty) | |
667 { | |
668 case TY.Tpointer: fty = TY.Tuns32; break; | |
669 case TY.Tchar: fty = TY.Tuns8; break; | |
670 case TY.Twchar: fty = TY.Tuns16; break; | |
671 case TY.Tdchar: fty = TY.Tuns32; break; | |
672 default: break; /// | |
673 } | |
674 | |
675 Lagain: | |
676 switch (X(fty,tty)) | |
677 { | |
79 | 678 static if (false) |
679 { | |
72 | 680 case X(TY.Tbit,TY.Tint8): |
681 case X(TY.Tbit,TY.Tuns8): | |
682 goto Lpaint; | |
683 case X(TY.Tbit,TY.Tint16): | |
684 case X(TY.Tbit,TY.Tuns16): | |
685 case X(TY.Tbit,TY.Tint32): | |
686 case X(TY.Tbit,TY.Tuns32): | |
687 eop = OPu8_16; | |
688 goto Leop; | |
689 case X(TY.Tbit,TY.Tint64): | |
690 case X(TY.Tbit,TY.Tuns64): | |
691 case X(TY.Tbit,TY.Tfloat32): | |
692 case X(TY.Tbit,TY.Tfloat64): | |
693 case X(TY.Tbit,TY.Tfloat80): | |
694 case X(TY.Tbit,TY.Tcomplex32): | |
695 case X(TY.Tbit,TY.Tcomplex64): | |
696 case X(TY.Tbit,TY.Tcomplex80): | |
697 e = el_una(OPER.OPu8_16, TYM.TYuint, e); | |
698 fty = TY.Tuns32; | |
699 goto Lagain; | |
700 case X(Tbit,Timaginary32): | |
701 case X(Tbit,Timaginary64): | |
702 case X(Tbit,Timaginary80): | |
703 goto Lzero; | |
704 } | |
705 /* ============================= */ | |
706 | |
707 case X(TY.Tbool,TY.Tint8): | |
708 case X(TY.Tbool,TY.Tuns8): | |
709 goto Lpaint; | |
710 case X(TY.Tbool,TY.Tint16): | |
711 case X(TY.Tbool,TY.Tuns16): | |
712 case X(TY.Tbool,TY.Tint32): | |
713 case X(TY.Tbool,TY.Tuns32): | |
714 eop = OPER.OPu8_16; | |
715 goto Leop; | |
716 case X(TY.Tbool,TY.Tint64): | |
717 case X(TY.Tbool,TY.Tuns64): | |
718 case X(TY.Tbool,TY.Tfloat32): | |
719 case X(TY.Tbool,TY.Tfloat64): | |
720 case X(TY.Tbool,TY.Tfloat80): | |
721 case X(TY.Tbool,TY.Tcomplex32): | |
722 case X(TY.Tbool,TY.Tcomplex64): | |
723 case X(TY.Tbool,TY.Tcomplex80): | |
724 e = el_una(OPER.OPu8_16, TYM.TYuint, e); | |
725 fty = TY.Tuns32; | |
726 goto Lagain; | |
727 case X(TY.Tbool,TY.Timaginary32): | |
728 case X(TY.Tbool,TY.Timaginary64): | |
729 case X(TY.Tbool,TY.Timaginary80): | |
730 goto Lzero; | |
731 | |
732 /* ============================= */ | |
733 | |
734 case X(TY.Tint8,TY.Tuns8): | |
735 goto Lpaint; | |
736 case X(TY.Tint8,TY.Tint16): | |
737 case X(TY.Tint8,TY.Tuns16): | |
738 case X(TY.Tint8,TY.Tint32): | |
739 case X(TY.Tint8,TY.Tuns32): | |
740 eop = OPER.OPs8_16; | |
741 goto Leop; | |
742 case X(TY.Tint8,TY.Tint64): | |
743 case X(TY.Tint8,TY.Tuns64): | |
744 case X(TY.Tint8,TY.Tfloat32): | |
745 case X(TY.Tint8,TY.Tfloat64): | |
746 case X(TY.Tint8,TY.Tfloat80): | |
747 case X(TY.Tint8,TY.Tcomplex32): | |
748 case X(TY.Tint8,TY.Tcomplex64): | |
749 case X(TY.Tint8,TY.Tcomplex80): | |
750 e = el_una(OPER.OPs8_16, TYM.TYint, e); | |
751 fty = TY.Tint32; | |
752 goto Lagain; | |
753 case X(TY.Tint8,TY.Timaginary32): | |
754 case X(TY.Tint8,TY.Timaginary64): | |
755 case X(TY.Tint8,TY.Timaginary80): | |
756 goto Lzero; | |
757 | |
758 /* ============================= */ | |
759 | |
760 case X(TY.Tuns8,TY.Tint8): | |
761 goto Lpaint; | |
762 case X(TY.Tuns8,TY.Tint16): | |
763 case X(TY.Tuns8,TY.Tuns16): | |
764 case X(TY.Tuns8,TY.Tint32): | |
765 case X(TY.Tuns8,TY.Tuns32): | |
766 eop = OPER.OPu8_16; | |
767 goto Leop; | |
768 case X(TY.Tuns8,TY.Tint64): | |
769 case X(TY.Tuns8,TY.Tuns64): | |
770 case X(TY.Tuns8,TY.Tfloat32): | |
771 case X(TY.Tuns8,TY.Tfloat64): | |
772 case X(TY.Tuns8,TY.Tfloat80): | |
773 case X(TY.Tuns8,TY.Tcomplex32): | |
774 case X(TY.Tuns8,TY.Tcomplex64): | |
775 case X(TY.Tuns8,TY.Tcomplex80): | |
776 e = el_una(OPER.OPu8_16, TYM.TYuint, e); | |
777 fty = TY.Tuns32; | |
778 goto Lagain; | |
779 case X(TY.Tuns8,TY.Timaginary32): | |
780 case X(TY.Tuns8,TY.Timaginary64): | |
781 case X(TY.Tuns8,TY.Timaginary80): | |
782 goto Lzero; | |
783 | |
784 /* ============================= */ | |
785 | |
786 case X(TY.Tint16,TY.Tint8): | |
787 case X(TY.Tint16,TY.Tuns8): | |
788 eop = OPER.OP16_8; | |
789 goto Leop; | |
790 case X(TY.Tint16,TY.Tuns16): | |
791 goto Lpaint; | |
792 case X(TY.Tint16,TY.Tint32): | |
793 case X(TY.Tint16,TY.Tuns32): | |
794 eop = OPER.OPs16_32; | |
795 goto Leop; | |
796 case X(TY.Tint16,TY.Tint64): | |
797 case X(TY.Tint16,TY.Tuns64): | |
798 e = el_una(OPER.OPs16_32, TYM.TYint, e); | |
799 fty = TY.Tint32; | |
800 goto Lagain; | |
801 case X(TY.Tint16,TY.Tfloat32): | |
802 case X(TY.Tint16,TY.Tfloat64): | |
803 case X(TY.Tint16,TY.Tfloat80): | |
804 case X(TY.Tint16,TY.Tcomplex32): | |
805 case X(TY.Tint16,TY.Tcomplex64): | |
806 case X(TY.Tint16,TY.Tcomplex80): | |
807 e = el_una(OPER.OPs16_d, TYM.TYdouble, e); | |
808 fty = TY.Tfloat64; | |
809 goto Lagain; | |
810 case X(TY.Tint16,TY.Timaginary32): | |
811 case X(TY.Tint16,TY.Timaginary64): | |
812 case X(TY.Tint16,TY.Timaginary80): | |
813 goto Lzero; | |
814 | |
815 /* ============================= */ | |
816 | |
817 case X(TY.Tuns16,TY.Tint8): | |
818 case X(TY.Tuns16,TY.Tuns8): | |
819 eop = OPER.OP16_8; | |
820 goto Leop; | |
821 case X(TY.Tuns16,TY.Tint16): | |
822 goto Lpaint; | |
823 case X(TY.Tuns16,TY.Tint32): | |
824 case X(TY.Tuns16,TY.Tuns32): | |
825 eop = OPER.OPu16_32; | |
826 goto Leop; | |
827 case X(TY.Tuns16,TY.Tint64): | |
828 case X(TY.Tuns16,TY.Tuns64): | |
829 case X(TY.Tuns16,TY.Tfloat64): | |
830 case X(TY.Tuns16,TY.Tfloat32): | |
831 case X(TY.Tuns16,TY.Tfloat80): | |
832 case X(TY.Tuns16,TY.Tcomplex32): | |
833 case X(TY.Tuns16,TY.Tcomplex64): | |
834 case X(TY.Tuns16,TY.Tcomplex80): | |
835 e = el_una(OPER.OPu16_32, TYM.TYuint, e); | |
836 fty = TY.Tuns32; | |
837 goto Lagain; | |
838 case X(TY.Tuns16,TY.Timaginary32): | |
839 case X(TY.Tuns16,TY.Timaginary64): | |
840 case X(TY.Tuns16,TY.Timaginary80): | |
841 goto Lzero; | |
842 | |
843 /* ============================= */ | |
844 | |
845 case X(TY.Tint32,TY.Tint8): | |
846 case X(TY.Tint32,TY.Tuns8): | |
847 e = el_una(OPER.OP32_16, TYM.TYshort, e); | |
848 fty = TY.Tint16; | |
849 goto Lagain; | |
850 case X(TY.Tint32,TY.Tint16): | |
851 case X(TY.Tint32,TY.Tuns16): | |
852 eop = OPER.OP32_16; | |
853 goto Leop; | |
854 case X(TY.Tint32,TY.Tuns32): | |
855 goto Lpaint; | |
856 case X(TY.Tint32,TY.Tint64): | |
857 case X(TY.Tint32,TY.Tuns64): | |
858 eop = OPER.OPs32_64; | |
859 goto Leop; | |
860 case X(TY.Tint32,TY.Tfloat32): | |
861 case X(TY.Tint32,TY.Tfloat64): | |
862 case X(TY.Tint32,TY.Tfloat80): | |
863 case X(TY.Tint32,TY.Tcomplex32): | |
864 case X(TY.Tint32,TY.Tcomplex64): | |
865 case X(TY.Tint32,TY.Tcomplex80): | |
866 e = el_una(OPER.OPs32_d, TYM.TYdouble, e); | |
867 fty = TY.Tfloat64; | |
868 goto Lagain; | |
869 case X(TY.Tint32,TY.Timaginary32): | |
870 case X(TY.Tint32,TY.Timaginary64): | |
871 case X(TY.Tint32,TY.Timaginary80): | |
872 goto Lzero; | |
873 | |
874 /* ============================= */ | |
875 | |
876 case X(TY.Tuns32,TY.Tint8): | |
877 case X(TY.Tuns32,TY.Tuns8): | |
878 e = el_una(OPER.OP32_16, TYM.TYshort, e); | |
879 fty = TY.Tuns16; | |
880 goto Lagain; | |
881 case X(TY.Tuns32,TY.Tint16): | |
882 case X(TY.Tuns32,TY.Tuns16): | |
883 eop = OPER.OP32_16; | |
884 goto Leop; | |
885 case X(TY.Tuns32,TY.Tint32): | |
886 goto Lpaint; | |
887 case X(TY.Tuns32,TY.Tint64): | |
888 case X(TY.Tuns32,TY.Tuns64): | |
889 eop = OPER.OPu32_64; | |
890 goto Leop; | |
891 case X(TY.Tuns32,TY.Tfloat32): | |
892 case X(TY.Tuns32,TY.Tfloat64): | |
893 case X(TY.Tuns32,TY.Tfloat80): | |
894 case X(TY.Tuns32,TY.Tcomplex32): | |
895 case X(TY.Tuns32,TY.Tcomplex64): | |
896 case X(TY.Tuns32,TY.Tcomplex80): | |
897 e = el_una(OPER.OPu32_d, TYM.TYdouble, e); | |
898 fty = TY.Tfloat64; | |
899 goto Lagain; | |
900 case X(TY.Tuns32,TY.Timaginary32): | |
901 case X(TY.Tuns32,TY.Timaginary64): | |
902 case X(TY.Tuns32,TY.Timaginary80): | |
903 goto Lzero; | |
904 | |
905 /* ============================= */ | |
906 | |
907 case X(TY.Tint64,TY.Tint8): | |
908 case X(TY.Tint64,TY.Tuns8): | |
909 case X(TY.Tint64,TY.Tint16): | |
910 case X(TY.Tint64,TY.Tuns16): | |
911 e = el_una(OPER.OP64_32, TYM.TYint, e); | |
912 fty = TY.Tint32; | |
913 goto Lagain; | |
914 case X(TY.Tint64,TY.Tint32): | |
915 case X(TY.Tint64,TY.Tuns32): | |
916 eop = OPER.OP64_32; | |
917 goto Leop; | |
918 case X(TY.Tint64,TY.Tuns64): | |
919 goto Lpaint; | |
920 case X(TY.Tint64,TY.Tfloat32): | |
921 case X(TY.Tint64,TY.Tfloat64): | |
922 case X(TY.Tint64,TY.Tfloat80): | |
923 case X(TY.Tint64,TY.Tcomplex32): | |
924 case X(TY.Tint64,TY.Tcomplex64): | |
925 case X(TY.Tint64,TY.Tcomplex80): | |
926 e = el_una(OPER.OPs64_d, TYM.TYdouble, e); | |
927 fty = TY.Tfloat64; | |
928 goto Lagain; | |
929 case X(TY.Tint64,TY.Timaginary32): | |
930 case X(TY.Tint64,TY.Timaginary64): | |
931 case X(TY.Tint64,TY.Timaginary80): | |
932 goto Lzero; | |
933 | |
934 /* ============================= */ | |
935 | |
936 case X(TY.Tuns64,TY.Tint8): | |
937 case X(TY.Tuns64,TY.Tuns8): | |
938 case X(TY.Tuns64,TY.Tint16): | |
939 case X(TY.Tuns64,TY.Tuns16): | |
940 e = el_una(OPER.OP64_32, TYM.TYint, e); | |
941 fty = TY.Tint32; | |
942 goto Lagain; | |
943 case X(TY.Tuns64,TY.Tint32): | |
944 case X(TY.Tuns64,TY.Tuns32): | |
945 eop = OPER.OP64_32; | |
946 goto Leop; | |
947 case X(TY.Tuns64,TY.Tint64): | |
948 goto Lpaint; | |
949 case X(TY.Tuns64,TY.Tfloat32): | |
950 case X(TY.Tuns64,TY.Tfloat64): | |
951 case X(TY.Tuns64,TY.Tfloat80): | |
952 case X(TY.Tuns64,TY.Tcomplex32): | |
953 case X(TY.Tuns64,TY.Tcomplex64): | |
954 case X(TY.Tuns64,TY.Tcomplex80): | |
955 e = el_una(OPER.OPu64_d, TYM.TYdouble, e); | |
956 fty = TY.Tfloat64; | |
957 goto Lagain; | |
958 case X(TY.Tuns64,TY.Timaginary32): | |
959 case X(TY.Tuns64,TY.Timaginary64): | |
960 case X(TY.Tuns64,TY.Timaginary80): | |
961 goto Lzero; | |
962 | |
963 /* ============================= */ | |
964 | |
965 case X(TY.Tfloat32,TY.Tint8): | |
966 case X(TY.Tfloat32,TY.Tuns8): | |
967 case X(TY.Tfloat32,TY.Tint16): | |
968 case X(TY.Tfloat32,TY.Tuns16): | |
969 case X(TY.Tfloat32,TY.Tint32): | |
970 case X(TY.Tfloat32,TY.Tuns32): | |
971 case X(TY.Tfloat32,TY.Tint64): | |
972 case X(TY.Tfloat32,TY.Tuns64): | |
973 case X(TY.Tfloat32,TY.Tfloat80): | |
974 e = el_una(OPER.OPf_d, TYM.TYdouble, e); | |
975 fty = TY.Tfloat64; | |
976 goto Lagain; | |
977 case X(TY.Tfloat32,TY.Tfloat64): | |
978 eop = OPER.OPf_d; | |
979 goto Leop; | |
980 case X(TY.Tfloat32,TY.Timaginary32): | |
981 goto Lzero; | |
982 case X(TY.Tfloat32,TY.Timaginary64): | |
983 goto Lzero; | |
984 case X(TY.Tfloat32,TY.Timaginary80): | |
985 goto Lzero; | |
986 case X(TY.Tfloat32,TY.Tcomplex32): | |
987 case X(TY.Tfloat32,TY.Tcomplex64): | |
988 case X(TY.Tfloat32,TY.Tcomplex80): | |
989 e = el_bin(OPER.OPadd,TYM.TYcfloat,el_long(TYM.TYifloat,0),e); | |
990 fty = TY.Tcomplex32; | |
991 goto Lagain; | |
992 | |
993 /* ============================= */ | |
994 | |
995 case X(TY.Tfloat64,TY.Tint8): | |
996 case X(TY.Tfloat64,TY.Tuns8): | |
997 e = el_una(OPER.OPd_s16, TYM.TYshort, e); | |
998 fty = TY.Tint16; | |
999 goto Lagain; | |
1000 case X(TY.Tfloat64,TY.Tint16): | |
1001 eop = OPER.OPd_s16; | |
1002 goto Leop; | |
1003 case X(TY.Tfloat64,TY.Tuns16): | |
1004 eop = OPER.OPd_u16; | |
1005 goto Leop; | |
1006 case X(TY.Tfloat64,TY.Tint32): | |
1007 eop = OPER.OPd_s32; | |
1008 goto Leop; | |
1009 case X(TY.Tfloat64,TY.Tuns32): | |
1010 eop = OPER.OPd_u32; | |
1011 goto Leop; | |
1012 case X(TY.Tfloat64,TY.Tint64): | |
1013 eop = OPER.OPd_s64; | |
1014 goto Leop; | |
1015 case X(TY.Tfloat64,TY.Tuns64): | |
1016 eop = OPER.OPd_u64; | |
1017 goto Leop; | |
1018 case X(TY.Tfloat64,TY.Tfloat32): | |
1019 eop = OPER.OPd_f; | |
1020 goto Leop; | |
1021 case X(TY.Tfloat64,TY.Tfloat80): | |
1022 eop = OPER.OPd_ld; | |
1023 goto Leop; | |
1024 case X(TY.Tfloat64,TY.Timaginary32): | |
1025 goto Lzero; | |
1026 case X(TY.Tfloat64,TY.Timaginary64): | |
1027 goto Lzero; | |
1028 case X(TY.Tfloat64,TY.Timaginary80): | |
1029 goto Lzero; | |
1030 case X(TY.Tfloat64,TY.Tcomplex32): | |
1031 case X(TY.Tfloat64,TY.Tcomplex64): | |
1032 case X(TY.Tfloat64,TY.Tcomplex80): | |
1033 e = el_bin(OPER.OPadd,TYM.TYcfloat,el_long(TYM.TYidouble,0),e); | |
1034 fty = TY.Tcomplex64; | |
1035 goto Lagain; | |
1036 | |
1037 /* ============================= */ | |
1038 | |
1039 case X(TY.Tfloat80,TY.Tint8): | |
1040 case X(TY.Tfloat80,TY.Tuns8): | |
1041 case X(TY.Tfloat80,TY.Tint16): | |
1042 case X(TY.Tfloat80,TY.Tuns16): | |
1043 case X(TY.Tfloat80,TY.Tint32): | |
1044 case X(TY.Tfloat80,TY.Tuns32): | |
1045 case X(TY.Tfloat80,TY.Tint64): | |
1046 case X(TY.Tfloat80,TY.Tfloat32): | |
1047 e = el_una(OPER.OPld_d, TYM.TYdouble, e); | |
1048 fty = TY.Tfloat64; | |
1049 goto Lagain; | |
1050 case X(TY.Tfloat80,TY.Tuns64): | |
1051 eop = OPER.OPld_u64; | |
1052 goto Leop; | |
1053 case X(TY.Tfloat80,TY.Tfloat64): | |
1054 eop = OPER.OPld_d; | |
1055 goto Leop; | |
1056 case X(TY.Tfloat80,TY.Timaginary32): | |
1057 goto Lzero; | |
1058 case X(TY.Tfloat80,TY.Timaginary64): | |
1059 goto Lzero; | |
1060 case X(TY.Tfloat80,TY.Timaginary80): | |
1061 goto Lzero; | |
1062 case X(TY.Tfloat80,TY.Tcomplex32): | |
1063 case X(TY.Tfloat80,TY.Tcomplex64): | |
1064 case X(TY.Tfloat80,TY.Tcomplex80): | |
1065 e = el_bin(OPER.OPadd,TYM.TYcldouble,e,el_long(TYM.TYildouble,0)); | |
1066 fty = TY.Tcomplex80; | |
1067 goto Lagain; | |
1068 | |
1069 /* ============================= */ | |
1070 | |
1071 case X(TY.Timaginary32,TY.Tint8): | |
1072 case X(TY.Timaginary32,TY.Tuns8): | |
1073 case X(TY.Timaginary32,TY.Tint16): | |
1074 case X(TY.Timaginary32,TY.Tuns16): | |
1075 case X(TY.Timaginary32,TY.Tint32): | |
1076 case X(TY.Timaginary32,TY.Tuns32): | |
1077 case X(TY.Timaginary32,TY.Tint64): | |
1078 case X(TY.Timaginary32,TY.Tuns64): | |
1079 case X(TY.Timaginary32,TY.Tfloat32): | |
1080 case X(TY.Timaginary32,TY.Tfloat64): | |
1081 case X(TY.Timaginary32,TY.Tfloat80): | |
1082 goto Lzero; | |
1083 case X(TY.Timaginary32,TY.Timaginary64): | |
1084 eop = OPER.OPf_d; | |
1085 goto Leop; | |
1086 case X(TY.Timaginary32,TY.Timaginary80): | |
1087 e = el_una(OPER.OPf_d, TYM.TYidouble, e); | |
1088 fty = TY.Timaginary64; | |
1089 goto Lagain; | |
1090 case X(TY.Timaginary32,TY.Tcomplex32): | |
1091 case X(TY.Timaginary32,TY.Tcomplex64): | |
1092 case X(TY.Timaginary32,TY.Tcomplex80): | |
1093 e = el_bin(OPER.OPadd,TYM.TYcfloat,el_long(TYM.TYfloat,0),e); | |
1094 fty = TY.Tcomplex32; | |
1095 goto Lagain; | |
1096 | |
1097 /* ============================= */ | |
1098 | |
1099 case X(TY.Timaginary64,TY.Tint8): | |
1100 case X(TY.Timaginary64,TY.Tuns8): | |
1101 case X(TY.Timaginary64,TY.Tint16): | |
1102 case X(TY.Timaginary64,TY.Tuns16): | |
1103 case X(TY.Timaginary64,TY.Tint32): | |
1104 case X(TY.Timaginary64,TY.Tuns32): | |
1105 case X(TY.Timaginary64,TY.Tint64): | |
1106 case X(TY.Timaginary64,TY.Tuns64): | |
1107 case X(TY.Timaginary64,TY.Tfloat32): | |
1108 case X(TY.Timaginary64,TY.Tfloat64): | |
1109 case X(TY.Timaginary64,TY.Tfloat80): | |
1110 goto Lzero; | |
1111 case X(TY.Timaginary64,TY.Timaginary32): | |
1112 eop = OPER.OPd_f; | |
1113 goto Leop; | |
1114 case X(TY.Timaginary64,TY.Timaginary80): | |
1115 eop = OPER.OPd_ld; | |
1116 goto Leop; | |
1117 case X(TY.Timaginary64,TY.Tcomplex32): | |
1118 case X(TY.Timaginary64,TY.Tcomplex64): | |
1119 case X(TY.Timaginary64,TY.Tcomplex80): | |
1120 e = el_bin(OPER.OPadd, TYM.TYcdouble, el_long(TYM.TYdouble,0), e); | |
1121 fty = TY.Tcomplex64; | |
1122 goto Lagain; | |
1123 | |
1124 /* ============================= */ | |
1125 | |
1126 case X(TY.Timaginary80,TY.Tint8): | |
1127 case X(TY.Timaginary80,TY.Tuns8): | |
1128 case X(TY.Timaginary80,TY.Tint16): | |
1129 case X(TY.Timaginary80,TY.Tuns16): | |
1130 case X(TY.Timaginary80,TY.Tint32): | |
1131 case X(TY.Timaginary80,TY.Tuns32): | |
1132 case X(TY.Timaginary80,TY.Tint64): | |
1133 case X(TY.Timaginary80,TY.Tuns64): | |
1134 case X(TY.Timaginary80,TY.Tfloat32): | |
1135 case X(TY.Timaginary80,TY.Tfloat64): | |
1136 case X(TY.Timaginary80,TY.Tfloat80): | |
1137 goto Lzero; | |
1138 case X(TY.Timaginary80,TY.Timaginary32): | |
1139 e = el_una(OPER.OPf_d, TYM.TYidouble, e); | |
1140 fty = TY.Timaginary64; | |
1141 goto Lagain; | |
1142 case X(TY.Timaginary80,TY.Timaginary64): | |
1143 eop = OPER.OPld_d; | |
1144 goto Leop; | |
1145 case X(TY.Timaginary80,TY.Tcomplex32): | |
1146 case X(TY.Timaginary80,TY.Tcomplex64): | |
1147 case X(TY.Timaginary80,TY.Tcomplex80): | |
1148 e = el_bin(OPER.OPadd, TYM.TYcldouble, el_long(TYM.TYldouble,0), e); | |
1149 fty = TY.Tcomplex80; | |
1150 goto Lagain; | |
1151 | |
1152 /* ============================= */ | |
1153 | |
1154 case X(TY.Tcomplex32,TY.Tint8): | |
1155 case X(TY.Tcomplex32,TY.Tuns8): | |
1156 case X(TY.Tcomplex32,TY.Tint16): | |
1157 case X(TY.Tcomplex32,TY.Tuns16): | |
1158 case X(TY.Tcomplex32,TY.Tint32): | |
1159 case X(TY.Tcomplex32,TY.Tuns32): | |
1160 case X(TY.Tcomplex32,TY.Tint64): | |
1161 case X(TY.Tcomplex32,TY.Tuns64): | |
1162 case X(TY.Tcomplex32,TY.Tfloat32): | |
1163 case X(TY.Tcomplex32,TY.Tfloat64): | |
1164 case X(TY.Tcomplex32,TY.Tfloat80): | |
1165 e = el_una(OPER.OPc_r, TYM.TYfloat, e); | |
1166 fty = TY.Tfloat32; | |
1167 goto Lagain; | |
1168 case X(TY.Tcomplex32,TY.Timaginary32): | |
1169 case X(TY.Tcomplex32,TY.Timaginary64): | |
1170 case X(TY.Tcomplex32,TY.Timaginary80): | |
1171 e = el_una(OPER.OPc_i, TYM.TYifloat, e); | |
1172 fty = TY.Timaginary32; | |
1173 goto Lagain; | |
1174 case X(TY.Tcomplex32,TY.Tcomplex64): | |
1175 case X(TY.Tcomplex32,TY.Tcomplex80): | |
1176 e = el_una(OPER.OPf_d, TYM.TYcdouble, e); | |
1177 fty = TY.Tcomplex64; | |
1178 goto Lagain; | |
1179 | |
1180 /* ============================= */ | |
1181 | |
1182 case X(TY.Tcomplex64,TY.Tint8): | |
1183 case X(TY.Tcomplex64,TY.Tuns8): | |
1184 case X(TY.Tcomplex64,TY.Tint16): | |
1185 case X(TY.Tcomplex64,TY.Tuns16): | |
1186 case X(TY.Tcomplex64,TY.Tint32): | |
1187 case X(TY.Tcomplex64,TY.Tuns32): | |
1188 case X(TY.Tcomplex64,TY.Tint64): | |
1189 case X(TY.Tcomplex64,TY.Tuns64): | |
1190 case X(TY.Tcomplex64,TY.Tfloat32): | |
1191 case X(TY.Tcomplex64,TY.Tfloat64): | |
1192 case X(TY.Tcomplex64,TY.Tfloat80): | |
1193 e = el_una(OPER.OPc_r, TYM.TYdouble, e); | |
1194 fty = TY.Tfloat64; | |
1195 goto Lagain; | |
1196 case X(TY.Tcomplex64,TY.Timaginary32): | |
1197 case X(TY.Tcomplex64,TY.Timaginary64): | |
1198 case X(TY.Tcomplex64,TY.Timaginary80): | |
1199 e = el_una(OPER.OPc_i, TYM.TYidouble, e); | |
1200 fty = TY.Timaginary64; | |
1201 goto Lagain; | |
1202 case X(TY.Tcomplex64,TY.Tcomplex32): | |
1203 eop = OPER.OPd_f; | |
1204 goto Leop; | |
1205 case X(TY.Tcomplex64,TY.Tcomplex80): | |
1206 eop = OPER.OPd_ld; | |
1207 goto Leop; | |
1208 | |
1209 /* ============================= */ | |
1210 | |
1211 case X(TY.Tcomplex80,TY.Tint8): | |
1212 case X(TY.Tcomplex80,TY.Tuns8): | |
1213 case X(TY.Tcomplex80,TY.Tint16): | |
1214 case X(TY.Tcomplex80,TY.Tuns16): | |
1215 case X(TY.Tcomplex80,TY.Tint32): | |
1216 case X(TY.Tcomplex80,TY.Tuns32): | |
1217 case X(TY.Tcomplex80,TY.Tint64): | |
1218 case X(TY.Tcomplex80,TY.Tuns64): | |
1219 case X(TY.Tcomplex80,TY.Tfloat32): | |
1220 case X(TY.Tcomplex80,TY.Tfloat64): | |
1221 case X(TY.Tcomplex80,TY.Tfloat80): | |
1222 e = el_una(OPER.OPc_r, TYM.TYldouble, e); | |
1223 fty = TY.Tfloat80; | |
1224 goto Lagain; | |
1225 case X(TY.Tcomplex80,TY.Timaginary32): | |
1226 case X(TY.Tcomplex80,TY.Timaginary64): | |
1227 case X(TY.Tcomplex80,TY.Timaginary80): | |
1228 e = el_una(OPER.OPc_i, TYM.TYildouble, e); | |
1229 fty = TY.Timaginary80; | |
1230 goto Lagain; | |
1231 case X(TY.Tcomplex80,TY.Tcomplex32): | |
1232 case X(TY.Tcomplex80,TY.Tcomplex64): | |
1233 e = el_una(OPER.OPld_d, TYM.TYcdouble, e); | |
1234 fty = TY.Tcomplex64; | |
1235 goto Lagain; | |
1236 | |
1237 /* ============================= */ | |
1238 | |
1239 default: | |
1240 if (fty == tty) | |
1241 goto Lpaint; | |
1242 //dump(0); | |
79 | 1243 //writef("fty = %d, tty = %d, %d\n", fty, tty, t.ty); |
1244 error("e2ir: cannot cast %s of type %s to type %s", e1.toChars(), e1.type.toChars(), t.toChars()); | |
72 | 1245 goto Lzero; |
1246 | |
1247 Lzero: | |
1248 e = el_long(ttym, 0); | |
1249 break; | |
1250 | |
1251 Lpaint: | |
1252 e.Ety = ttym; | |
1253 break; | |
1254 | |
1255 Leop: | |
1256 e = el_una(eop, ttym, e); | |
1257 break; | |
1258 } | |
1259 Lret: | |
1260 // Adjust for any type paints | |
1261 t = type.toBasetype(); | |
1262 e.Ety = t.totym(); | |
1263 | |
1264 el_setLoc(e,loc); | |
0 | 1265 return e; |
1266 } | |
1267 | |
72 | 1268 override Identifier opId() |
0 | 1269 { |
1270 return Id.cast_; | |
1271 } | |
1272 } | |
1273 |