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