0
|
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
|