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