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