1 /*
2 * Copyright (c) 1993-2019, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 /**
19 \file
20 \brief ILI utility module
21 */
22
23 #include "iliutil.h"
24 #include "exputil.h"
25 #include "expreg.h"
26 #include "regutil.h"
27 #include "machreg.h"
28 #define EXPANDER_DECLARE_INTERNAL
29 #include "expand.h"
30 #include "machar.h"
31 #include "outliner.h"
32 #include "assem.h"
33 #include "x86.h"
34 #include "dtypeutl.h"
35 #include "llutil.h"
36 #include "llassem.h"
37 #include "llmputil.h"
38 #include "expsmp.h"
39 #include "verify.h"
40 #if DEBUG
41 #include "nme.h"
42 #endif
43 #include <stdarg.h>
44 #include "scutil.h"
45 #include "symfun.h"
46
47 #if defined(OMP_OFFLOAD_PGI) || defined(OMP_OFFLOAD_LLVM)
48 #include "ompaccel.h"
49 #endif
50
51 /*
52 * MTH, FMTH, ... names
53 */
54 #include "mth.h"
55
56 /** Union used to encode ATOMIC_INFO as an int or decode it. The union
57 contains a compacted version of ATOMIC_INFO using bitfields. The bitfields
58 are unsigned rather than the proper enum type so that the values aren't
59 sign extended when extracted. */
60 union ATOMIC_ENCODER {
61 struct {
62 unsigned msz : 8;
63 unsigned op : 8;
64 unsigned origin : 2;
65 unsigned scope : 1;
66 } info;
67 int encoding;
68 };
69
70 #define IL_spfunc IL_DFRSP
71 #define IL_dpfunc IL_DFRDP
72
73 bool share_proc_ili = false;
74 bool share_qjsr_ili = false;
75 extern bool ishft;
76
77 static int addarth(ILI *);
78 static int red_iadd(int, INT);
79 static int red_kadd(int, INT[2]);
80 static int red_eiadd(int, INT[2]);
81 static int red_aadd(int, SPTR, ISZ_T, int);
82 static int red_damv(int, int, int);
83 static int red_minmax(ILI_OP, int, int);
84 static int red_negate(int, ILI_OP, int, int);
85 static int addbran(ILI *);
86 static int addother(ILI *);
87 static INT icmp(INT, INT);
88 static INT cmp_to_log(INT, int);
89 static bool isub_ovf(INT, INT, INT *);
90 static bool iadd_ovf(INT, INT, INT *);
91 static int get_ili(ILI *);
92 static int new_ili(ILI *);
93 static int ad1altili(ILI_OP, int, int);
94 static int ad2altili(ILI_OP, int, int, int);
95 static int ad3altili(ILI_OP, int, int, int, int);
96 static int ad2func_int(ILI_OP, char *, int, int);
97 static int gen_sincos(ILI_OP, int, ILI_OP, ILI_OP, MTH_FN, DTYPE, ILI_OP);
98 static int _newton_fdiv(int, int);
99 static bool do_newton_sqrt(void);
100 static int _pwr2(INT, int);
101 static int _kpwr2(INT, INT, int);
102 static int _ipowi(int, int);
103 static int _xpowi(int, int, ILI_OP);
104 static int _frsqrt(int);
105 static int _mkfunc(char *);
106 static int DblIsSingle(SPTR dd);
107 static int _lshift_one(int);
108 static int cmpz_of_cmp(int, CC_RELATION);
109 static bool is_zero_one(int);
110 static bool _is_nanf(int);
111 static INT value_of_irlnk_operand(int ilix, int default_value);
112
113 #if defined(TARGET_WIN_X8664)
114 static void insert_argrsrv(ILI *);
115 #endif
116
117 // FIXME: mk_prototype_llvm should return an SPTR
118 #define mk_prototype (SPTR) mk_prototype_llvm
119
120 #define ILTABSZ 5
121 #define ILHSHSZ 173
122 #define MAXILIS 67108864
123
124 static int ilhsh[ILTABSZ][ILHSHSZ];
125 static bool safe_qjsr = false;
126
127 #define GARB_UNREACHABLE 0
128 #define GARB_VISITED 1
129
130 #ifdef __cplusplus
CCRelationILIOpnd(ILI * p,int n)131 inline CC_RELATION CCRelationILIOpnd(ILI *p, int n) {
132 return static_cast<CC_RELATION>(p->opnd[n]);
133 }
DTypeILIOpnd(ILI * p,int n)134 inline DTYPE DTypeILIOpnd(ILI *p, int n) {
135 return static_cast<DTYPE>(p->opnd[n]);
136 }
ConvertMSZ(int n)137 inline MSZ ConvertMSZ(int n) {
138 return static_cast<MSZ>(n);
139 }
ConvertATOMIC_RMW_OP(int n)140 inline ATOMIC_RMW_OP ConvertATOMIC_RMW_OP(int n) {
141 return static_cast<ATOMIC_RMW_OP>(n);
142 }
sptrGetILI(ILI * p)143 inline SPTR sptrGetILI(ILI *p) {
144 return static_cast<SPTR>(get_ili(p));
145 }
146 #else
147 #define CCRelationILIOpnd(p,n) (p)->opnd[n]
148 #define DTypeILIOpnd(p,n) (p)->opnd[n]
149 #define ConvertMSZ(n) (n)
150 #define ConvertATOMIC_RMW_OP(n) (n)
151 #define sptrGetILI get_ili
152 #endif
153
154 /**
155 \brief initialize ili area
156 */
157 void
ili_init(void)158 ili_init(void)
159 {
160 int *p, cnt;
161 static int firstcall = 1;
162
163 STG_ALLOC(ilib, 2048);
164 STG_SET_FREELINK(ilib, ILI, hshlnk);
165 cnt = ILHSHSZ * ILTABSZ;
166
167 if (firstcall) {
168 firstcall = 0;
169 } else {
170 p = (int *)ilhsh;
171 do {
172 *p++ = 0;
173 } while (--cnt > 0);
174 }
175 /* reserve ili index 1 to be the NULL ili. done so that a traversal
176 * which uses the ILI_VISIT field as a thread can use an ili (#1) to
177 * terminate the threaded list
178 */
179 ad1ili(IL_NULL, 0);
180 }
181
182 void
ili_cleanup(void)183 ili_cleanup(void)
184 {
185 STG_DELETE(ilib);
186 }
187
188 /**
189 \brief principle add ili routine
190 */
191 int
addili(ILI * ilip)192 addili(ILI *ilip)
193 {
194 ILI_OP opc; /* opcode of ili */
195 int ilix; /* ili area index where ili was added */
196 int tmp; /* temporary */
197 int cons1;
198 INT numi[2];
199
200 opc = ilip->opc;
201 switch (IL_TYPE(opc)) {
202
203 case ILTY_ARTH:
204 ilix = addarth(ilip);
205 break;
206
207 case ILTY_CONS:
208 case ILTY_LOAD:
209 case ILTY_STORE:
210 case ILTY_DEFINE:
211 ilix = get_ili(ilip);
212 break;
213 case ILTY_PROC:
214 #if defined(TARGET_WIN_X8664)
215 insert_argrsrv(ilip);
216 #endif
217 if (opc == IL_QJSR && share_qjsr_ili) {
218 /*
219 * normally (while expanding), we want qjsr's to be shared.
220 * in other cases (vectorizer), the qjsr's created may have
221 * side-effects (i.e., streamin) so we don't to share these
222 * (expand brackets its use with true, false).
223 */
224 ilix = get_ili(ilip);
225 if (!safe_qjsr)
226 expb.qjsr_flag = true;
227 break;
228 }
229 if (share_proc_ili)
230 ilix = get_ili(ilip); /* share proc ili if option requested */
231 else
232 ilix = new_ili(ilip); /* o.w., ensure unique ili for proc */
233 if (opc == IL_QJSR) {
234 if (!safe_qjsr)
235 expb.qjsr_flag = true;
236 iltb.qjsrfg = true;
237 BIH_QJSR(expb.curbih) = 1;
238 }
239 break;
240
241 case ILTY_MOVE:
242 switch (opc) {
243 int op1, op2;
244 case IL_KIMV:
245 if (ILI_OPC(op1 = ilip->opnd[0]) == IL_KCON) {
246 ilix = ad_icon(CONVAL2G(ILI_OPND(op1, 1)));
247 } else if (ILI_OPC(ilip->opnd[0]) == IL_IKMV)
248 ilix = ILI_OPND(op1, 1);
249 else
250 ilix = get_ili(ilip);
251 break;
252 case IL_IKMV:
253 switch (ILI_OPC(op1 = ilip->opnd[0])) {
254 case IL_ICON:
255 ilix = ad_kconi(CONVAL2G(ILI_OPND(op1, 1)));
256 break;
257 case IL_IADD:
258 op2 = ILI_OPND(op1, 2);
259 if (ILI_OPC(op2) == IL_ICON) {
260 op2 = ad_kconi(CONVAL2G(ILI_OPND(op2, 1)));
261 op1 = ad1ili(IL_IKMV, ILI_OPND(op1, 1));
262 ilix = ad2ili(IL_KADD, op1, op2);
263 } else
264 ilix = get_ili(ilip);
265 break;
266 case IL_ISUB:
267 op2 = ILI_OPND(op1, 2);
268 op1 = ILI_OPND(op1, 1);
269 if (ILI_OPC(op2) == IL_ICON) {
270 op2 = ad_kconi(CONVAL2G(ILI_OPND(op2, 1)));
271 op1 = ad1ili(IL_IKMV, op1);
272 ilix = ad2ili(IL_KSUB, op1, op2);
273 } else if (ILI_OPC(op1) == IL_ICON) {
274 op1 = ad_kconi(CONVAL2G(ILI_OPND(op1, 1)));
275 op2 = ad1ili(IL_IKMV, op2);
276 ilix = ad2ili(IL_KSUB, op1, op2);
277 } else
278 ilix = get_ili(ilip);
279 break;
280 default:
281 ilix = get_ili(ilip);
282 }
283 break;
284 case IL_UIKMV:
285 if (ILI_OPC(op1 = ilip->opnd[0]) == IL_ICON) {
286 numi[0] = CONVAL1G(op1 = ILI_OPND(op1, 1));
287 numi[1] = CONVAL2G(op1);
288 ilix = ad1ili(IL_KCON, getcon(numi, DT_INT8));
289 } else
290 ilix = get_ili(ilip);
291 break;
292 case IL_MVKR:
293 case IL_MVIR:
294 case IL_MVSP:
295 #ifdef IL_MVSPSP
296 case IL_MVSPSP:
297 #endif
298 case IL_MVQ: /*m128*/
299 case IL_MV256: /*m256*/
300 case IL_MVDP:
301 case IL_MVAR:
302 #ifdef LONG_DOUBLE_FLOAT128
303 case IL_FLOAT128RETURN:
304 #endif
305 if (ilip->opnd[1] == -1)
306 ilix = ilip->opnd[0];
307 else
308 ilix = get_ili(ilip);
309 break;
310
311 #ifdef IL_MVSPX87
312 case IL_MVSPX87:
313 case IL_MVDPX87:
314 ilix = get_ili(ilip);
315 break;
316 #endif
317
318 case IL_IAMV:
319 if (ILI_OPC(tmp = ilip->opnd[0]) == IL_ICON)
320 ilix = ad_aconi(CONVAL2G(ILI_OPND(tmp, 1)));
321 else if (ILI_OPC(tmp) == IL_AIMV)
322 ilix = ILI_OPND(tmp, 1);
323 else
324 ilix = get_ili(ilip);
325 break;
326
327 case IL_KAMV:
328 if (ILI_OPC(tmp = ilip->opnd[0]) == IL_KCON) {
329 cons1 = ILI_OPND(tmp, 1);
330 ilix = ad_aconk(CONVAL1G(cons1), ACONOFFG(cons1));
331 return ilix;
332 }
333 tmp = ilip->opnd[0];
334 if (ILI_OPC(tmp) == IL_AKMV)
335 ilix = ILI_OPND(tmp, 1);
336 else
337 ilix = get_ili(ilip);
338 break;
339
340 case IL_AIMV:
341 if ((ILI_OPC(tmp = ilip->opnd[0]) == IL_ACON) &&
342 (CONVAL1G((tmp = ILI_OPND(tmp, 1))) == 0)) {
343 ilix = ad_icon(CONVAL2G(tmp));
344 } else if (ILI_OPC(tmp = ilip->opnd[0]) == IL_IAMV)
345 ilix = ILI_OPND(tmp, 1);
346 else
347 ilix = get_ili(ilip);
348 break;
349
350 case IL_AKMV:
351 if ((ILI_OPC(tmp = ilip->opnd[0]) == IL_ACON) &&
352 (CONVAL1G((tmp = ILI_OPND(tmp, 1))) == 0)) {
353 ISZ_2_INT64(ACONOFFG(tmp), numi);
354 ilix = ad1ili(IL_KCON, getcon(numi, DT_INT8));
355 } else if (ILI_OPC(tmp = ilip->opnd[0]) == IL_KAMV)
356 ilix = ILI_OPND(tmp, 1);
357 else
358 ilix = get_ili(ilip);
359 break;
360
361 case IL_RETURN:
362 ilix = get_ili(ilip);
363 break;
364 default:
365 assert(false, "addili: unrec move opcode:", opc, ERR_Severe);
366 }
367 break;
368
369 case ILTY_BRANCH:
370 ilix = addbran(ilip);
371 break;
372
373 case ILTY_OTHER:
374 #ifdef ILTY_PSTORE
375 case ILTY_PSTORE:
376 #endif
377 #ifdef ILTY_PLOAD
378 case ILTY_PLOAD:
379 #endif
380 ilix = addother(ilip);
381 break;
382 #if DEBUG
383 default:
384 interr("addili: illegal IL_TYPE(opc)", IL_TYPE(opc), ERR_Fatal);
385 break;
386 #endif
387 }
388
389 #if DEBUG
390 if (DBGBIT(10, 32)) {
391 if (ilix)
392 dump_ili(gbl.dbgfil, ilix);
393 }
394 if (ilix)
395 verify_ili(ilix, VERIFY_ILI_SHALLOW);
396 #endif
397 return ilix;
398 }
399
400 /**
401 \brief add ili with one operand
402 */
403 int
ad1ili(ILI_OP opc,int opn1)404 ad1ili(ILI_OP opc, int opn1)
405 {
406 ILI newili;
407
408 newili.opc = opc;
409 newili.opnd[0] = opn1;
410 newili.opnd[1] = 0; /* cause some FREE ili have two opnds (target dep)*/
411 newili.opnd[2] = 0;
412 newili.opnd[3] = 0;
413 newili.opnd[4] = 0;
414 return addili(&newili);
415 }
416
417 /** \brief add an ili with one operand which has an alternate
418 *
419 * The routine is static -- only addili should create ALT ili.
420 */
421 static int
ad1altili(ILI_OP opc,int opn1,int alt)422 ad1altili(ILI_OP opc, int opn1, int alt)
423 {
424 ILI newili;
425 int ilix;
426
427 newili.opc = opc;
428 newili.opnd[0] = opn1;
429 newili.opnd[1] = 0; /* cause some FREE ili have two opnds (target dep)*/
430 newili.opnd[2] = 0;
431 newili.opnd[3] = 0;
432 newili.opnd[4] = 0;
433 ilix = get_ili(&newili);
434 if (ILI_ALT(ilix) == 0)
435 ILI_ALT(ilix) = alt;
436 return ilix;
437 }
438
439 /**
440 \brief add ili with two operands
441 */
442 int
ad2ili(ILI_OP opc,int opn1,int opn2)443 ad2ili(ILI_OP opc, int opn1, int opn2)
444 {
445 ILI newili;
446
447 newili.opc = opc;
448 newili.opnd[0] = opn1;
449 newili.opnd[1] = opn2;
450 newili.opnd[2] = 0;
451 newili.opnd[3] = 0;
452 newili.opnd[4] = 0;
453 return addili(&newili);
454 }
455
456 /** \brief Add an ili with two operands which has an alternate
457 *
458 * The routine isstatic -- only addili should create ALT ili.
459 */
460 static int
ad2altili(ILI_OP opc,int opn1,int opn2,int alt)461 ad2altili(ILI_OP opc, int opn1, int opn2, int alt)
462 {
463 ILI newili;
464 int ilix;
465
466 newili.opc = opc;
467 newili.opnd[0] = opn1;
468 newili.opnd[1] = opn2;
469 newili.opnd[2] = 0;
470 newili.opnd[3] = 0;
471 newili.opnd[4] = 0;
472 ilix = get_ili(&newili);
473 if (ILI_ALT(ilix) == 0)
474 ILI_ALT(ilix) = alt;
475 return ilix;
476 }
477
478 /** \brief Add func call with 2 integer arguments returning integer value
479 *
480 * \param opc must be a function call ili opcode: QJSR, JSR
481 */
482 static int
ad2func_int(ILI_OP opc,char * name,int opn1,int opn2)483 ad2func_int(ILI_OP opc, char *name, int opn1, int opn2)
484 {
485 int tmp, tmp1, tmp2;
486 tmp1 = ad1ili(IL_NULL, 0);
487 tmp1 = ad2ili(IL_ARGIR, opn2, tmp1);
488 tmp2 = ad2ili(IL_ARGIR, opn1, tmp1);
489 tmp = ad2ili(opc, _mkfunc(name), tmp2);
490 return ad2ili(IL_DFRIR, tmp, IR_RETVAL);
491 }
492
493 /** \brief Add func call with 1 complex argument returning complex value
494 *
495 * Note that a double complex value will be presented as a packed argument,
496 * i.e., a double complex vector of length 1
497 *
498 * \param opc must be a function call ili opcode: QJSR, JSR
499 */
500 static int
ad1func_cmplx(ILI_OP opc,char * name,int opn1)501 ad1func_cmplx(ILI_OP opc, char *name, int opn1)
502 {
503 int tmp, tmp1, tmp2;
504
505 tmp1 = ad1ili(IL_NULL, 0);
506 if (IL_RES(ILI_OPC(opn1)) == ILIA_CS) {
507 tmp2 = ad3ili(IL_DACS, opn1, DP(0), tmp1);
508 tmp = ad2ili(opc, _mkfunc(name), tmp2);
509 return ad2ili(IL_DFRCS, tmp, CS_RETVAL);
510 }
511 tmp2 = ad3ili(IL_DACD, opn1, DP(0), tmp1);
512 tmp = ad2ili(opc, _mkfunc(name), tmp2);
513 return ad2ili(IL_DFRCD, tmp, CD_RETVAL);
514 }
515
516 /** \brief Add func call with 2 arguments returning complex value
517 *
518 * The 2 arguments could be double complex or the 1st argument is double
519 * complex and the 2nd argument is integer.
520 *
521 * A double complex value will be presented as a packed argument, i.e.,
522 * a double complex vector of length 1
523 *
524 * \param opc must be a function call ili opcode: QJSR, JSR
525 */
526 static int
ad2func_cmplx(ILI_OP opc,char * name,int opn1,int opn2)527 ad2func_cmplx(ILI_OP opc, char *name, int opn1, int opn2)
528 {
529 int tmp, tmp1, tmp2;
530 int ireg; /* for integer pow argument just in case */
531
532 #if !defined(TARGET_WIN)
533 ireg = IR(0);
534 #else
535 ireg = IR(1); /* positional on windows */
536 #endif
537 tmp1 = ad1ili(IL_NULL, 0);
538 switch (IL_RES(ILI_OPC(opn2))) {
539 case ILIA_CS:
540 tmp1 = ad3ili(IL_DACS, opn2, DP(1), tmp1);
541 break;
542 case ILIA_CD:
543 tmp1 = ad3ili(IL_DACD, opn2, DP(1), tmp1);
544 break;
545 case ILIA_IR:
546 #if defined(TARGET_X8664)
547 tmp1 = ad3ili(IL_DAIR, opn2, ireg, tmp1);
548 #else
549 tmp1 = ad3ili(IL_ARGIR, opn2, tmp1, 0);
550 #endif
551 break;
552 case ILIA_KR:
553 #if defined(TARGET_X8664)
554 tmp1 = ad3ili(IL_DAKR, opn2, ireg, tmp1);
555 #else
556 tmp1 = ad3ili(IL_ARGKR, opn2, tmp1, 0);
557 #endif
558 break;
559 default:
560 interr("ad2func_cmplx: illegal ILIA arg2", opn2, ERR_unused);
561 tmp1 = ad1ili(IL_NULL, 0);
562 }
563 if (IL_RES(ILI_OPC(opn1)) == ILIA_CS) {
564 tmp2 = ad3ili(IL_DACS, opn1, DP(0), tmp1);
565 tmp = ad2ili(opc, _mkfunc(name), tmp2);
566 return ad2ili(IL_DFRCS, tmp, CS_RETVAL);
567 }
568 tmp2 = ad3ili(IL_DACD, opn1, DP(0), tmp1);
569 tmp = ad2ili(opc, _mkfunc(name), tmp2);
570 return ad2ili(IL_DFRCD, tmp, CD_RETVAL);
571 }
572
573 /** \brief Add func call with 1 complex argument returning complex value
574 *
575 * The C ABI is used here. A complex will be treated as if it's a struct
576 * 2 parts. On x64, a complex double will be passed as 2 arguments; the
577 * vector abi will pass the complex double packed in a single register or
578 * memory unit.
579 *
580 * \param opc must be a function call ili opcode: QJSR, JSR
581 */
582 static int
ad1func_cmplx_abi(ILI_OP opc,char * name,int opn1)583 ad1func_cmplx_abi(ILI_OP opc, char *name, int opn1)
584 {
585 int tmp, tmp1, tmp2;
586
587 tmp1 = ad1ili(IL_NULL, 0);
588 if (IL_RES(ILI_OPC(opn1)) == ILIA_CS) {
589 tmp2 = ad3ili(IL_DACS, opn1, DP(0), tmp1);
590 tmp = ad2ili(opc, _mkfunc(name), tmp2);
591 return ad2ili(IL_DFRCS, tmp, CS_RETVAL);
592 }
593 tmp2 = ad3ili(IL_DACD, opn1, DP(0), tmp1);
594 tmp = ad2ili(opc, _mkfunc(name), tmp2);
595 return ad2ili(IL_DFRCD, tmp, CD_RETVAL);
596 }
597
598 /** \brief Add func call with 2 arguments returning complex value
599 *
600 * The 2 arguments could be double complex or the 1st argument is double
601 * complex and the 2nd argument is integer.
602 * The C ABI is used here. A complex will be treated as if it's a struct
603 * 2 parts. On x64, a complex double will be passed as 2 arguments; the
604 * vector abi will pass the complex double packed in a single register or
605 * memory unit.
606 *
607 * \param opc must be a function call ili opcode: QJSR, JSR
608 */
609 static int
ad2func_cmplx_abi(ILI_OP opc,char * name,int opn1,int opn2)610 ad2func_cmplx_abi(ILI_OP opc, char *name, int opn1, int opn2)
611 {
612 int tmp, tmp1, tmp2;
613 int ireg; /* for integer pow argument just in case */
614
615 #if !defined(TARGET_WIN)
616 ireg = IR(0);
617 #else
618 ireg = IR(1); /* positional on windows */
619 #endif
620 tmp1 = ad1ili(IL_NULL, 0);
621 switch (IL_RES(ILI_OPC(opn2))) {
622 case ILIA_CS:
623 tmp1 = ad3ili(IL_DACS, opn2, DP(1), tmp1);
624 break;
625 case ILIA_CD:
626 tmp1 = ad3ili(IL_DACD, opn2, DP(1), tmp1);
627 break;
628 case ILIA_IR:
629 #if defined(TARGET_X8664)
630 tmp1 = ad3ili(IL_DAIR, opn2, ireg, tmp1);
631 #else
632 tmp1 = ad3ili(IL_ARGIR, opn2, tmp1, 0);
633 #endif
634 break;
635 case ILIA_KR:
636 #if defined(TARGET_X8664)
637 tmp1 = ad3ili(IL_DAKR, opn2, ireg, tmp1);
638 #else
639 tmp1 = ad3ili(IL_ARGKR, opn2, tmp1, 0);
640 #endif
641 break;
642 default:
643 interr("ad2func_cmplx: illegal ILIA arg2", opn2, ERR_unused);
644 tmp1 = ad1ili(IL_NULL, 0);
645 }
646 if (IL_RES(ILI_OPC(opn1)) == ILIA_CS) {
647 tmp2 = ad3ili(IL_DACS, opn1, DP(0), tmp1);
648 tmp = ad2ili(opc, _mkfunc(name), tmp2);
649 return ad2ili(IL_DFRCS, tmp, CS_RETVAL);
650 }
651 tmp2 = ad3ili(IL_DACD, opn1, DP(0), tmp1);
652 tmp = ad2ili(opc, _mkfunc(name), tmp2);
653 return ad2ili(IL_DFRCD, tmp, CD_RETVAL);
654 }
655
656 /** \brief Add func call with 1 complex argument returning complex value
657 *
658 * Assumes the new (as defined by make_math) naming scheme. For passing
659 * complex and returning types, we can either follow the C ABI which says
660 * complex is the same as a struct of two parts; or, we can follow the vector
661 * ABI which views a complex scalar as a vector complex vector of length 1,
662 * i.e., the complex is 'packed'. For now, we use the C abi'.
663 *
664 * \param opc must be a function call ili opcode: QJSR, JSR
665 */
666 static int
ad1mathfunc_cmplx(MTH_FN fn,ILI_OP opc,int op1,DTYPE res_dt,DTYPE arg1_dt)667 ad1mathfunc_cmplx(MTH_FN fn, ILI_OP opc, int op1, DTYPE res_dt, DTYPE arg1_dt)
668 {
669 char *fname;
670 int ilix;
671
672 fname = make_math(fn, NULL, 1, false, res_dt, 1, arg1_dt);
673 if (!XBIT_VECTORABI_FOR_SCALAR)
674 ilix = ad1func_cmplx_abi(IL_QJSR, fname, op1);
675 else
676 ilix = ad1func_cmplx(IL_QJSR, fname, op1);
677 ilix = ad1altili(opc, op1, ilix);
678 return ilix;
679 }
680
681 /** \brief Add func call with 2 complex arguments returning complex value
682 *
683 * Assumes the new (as defined by make_math) naming scheme. For passing
684 * complex and returning types, we can either follow the C ABI which says
685 * complex is the same as a struct of two parts; or, we can follow the vector
686 * ABI which views a complex scalar as a vector complex vector of length 1,
687 * i.e., the complex is 'packed'. For now, we use the 'vector abi'.
688 *
689 * \param opc must be a function call ili opcode: QJSR, JSR
690 */
691 static int
ad2mathfunc_cmplx(MTH_FN fn,ILI_OP opc,int op1,int op2,DTYPE res_dt,DTYPE arg1_dt,DTYPE arg2_dt)692 ad2mathfunc_cmplx(MTH_FN fn, ILI_OP opc, int op1, int op2, DTYPE res_dt,
693 DTYPE arg1_dt, DTYPE arg2_dt)
694 {
695 char *fname;
696 int ilix;
697
698 fname = make_math(fn, NULL, 1, false, res_dt, 2, arg1_dt, arg2_dt);
699 if (!XBIT_VECTORABI_FOR_SCALAR)
700 ilix = ad2func_cmplx_abi(IL_QJSR, fname, op1, op2);
701 else
702 ilix = ad2func_cmplx(IL_QJSR, fname, op1, op2);
703 ilix = ad2altili(opc, op1, op2, ilix);
704 return ilix;
705 }
706
707 /*
708 * WARNING - the arguments to ad_func are in lexical order
709 */
710 static int
ad_func(ILI_OP result_opc,ILI_OP call_opc,char * func_name,int nargs,...)711 ad_func(ILI_OP result_opc, ILI_OP call_opc, char *func_name, int nargs, ...)
712 {
713 va_list vargs;
714 int rg;
715 int irg;
716 int frg;
717 int func;
718 int argl;
719 int ilix;
720 int pos;
721 int n, i;
722 struct {
723 ILI_OP opc;
724 int arg;
725 int reg;
726 int is_argili;
727 } args[6];
728
729 va_start(vargs, nargs);
730 #if DEBUG
731 assert(nargs <= sizeof(args) / sizeof(args[0]),
732 "iliutil.c:ad_func, increase the size of args[]",
733 sizeof(args) / sizeof(args[0]), ERR_unused);
734 #endif
735 rg = 0;
736 irg = 0;
737 frg = 0;
738 argl = ad1ili(IL_NULL, 0);
739
740 BZERO(args, char, sizeof(args));
741 for (i = 0; i < nargs; i++) {
742 args[i].arg = va_arg(vargs, int);
743 if (IL_VECT(ILI_OPC(args[i].arg))) {
744 args[i].opc = IL_GARG;
745 args[i].is_argili = 1;
746 } else
747 switch (IL_RES(ILI_OPC(args[i].arg))) {
748 case ILIA_AR:
749 #if defined(TARGET_X8664)
750 args[i].opc = IL_DAAR;
751 args[i].reg = ARG_IR(irg);
752 #else
753 args[i].opc = IL_ARGAR;
754 args[i].is_argili = 1;
755 #endif
756 rg++;
757 irg++;
758 break;
759 case ILIA_IR:
760 #if defined(TARGET_X8664)
761 args[i].opc = IL_DAIR;
762 args[i].reg = IR(irg);
763 #else
764 args[i].opc = IL_ARGIR;
765 args[i].is_argili = 1;
766 #endif
767 rg++;
768 irg++;
769 break;
770 case ILIA_SP:
771 args[i].opc = IL_DASP;
772 args[i].reg = SP(frg);
773 rg++;
774 frg++;
775 break;
776 case ILIA_DP:
777 args[i].opc = IL_DADP;
778 args[i].reg = DP(frg);
779 rg++;
780 frg++;
781 break;
782 case ILIA_CS:
783 args[i].opc = IL_DACS;
784 args[i].reg = DP(frg);
785 rg++;
786 frg++;
787 break;
788 case ILIA_CD:
789 args[i].opc = IL_DACD; /* assumed to be packed when passed */
790 args[i].reg = DP(frg);
791 rg++;
792 frg++;
793 break;
794 case ILIA_KR:
795 #if defined(TARGET_X8664)
796 args[i].opc = IL_DAKR;
797 args[i].reg = IR(irg);
798 rg++;
799 irg++;
800 #else
801 args[i].opc = IL_ARGKR;
802 args[i].is_argili = 1;
803 rg += 2;
804 #endif
805 break;
806 #ifdef LONG_DOUBLE_FLOAT128
807 case ILIA_FLOAT128:
808 args[i].opc = IL_FLOAT128ARG;
809 args[i].is_argili = 1;
810 rg++;
811 break;
812 #endif
813 default:
814 interr("ad_func: illegal arg", args[i].arg, ERR_Severe);
815 args[i].opc = IL_ARGIR;
816 args[i].is_argili = 1;
817 break;
818 }
819 #if defined(TARGET_WIN_X8664)
820 irg = rg; /* on win64, register # is positional */
821 frg = rg; /* on win64, register # is positional */
822 #endif
823 }
824
825 for (i = nargs - 1; i >= 0; i--) {
826 if (!args[i].is_argili) {
827 argl = ad3ili(args[i].opc, args[i].arg, args[i].reg, argl);
828 } else {
829 if (IL_VECT(ILI_OPC(args[i].arg))) {
830 int arg_dtype, dtype_slot, arg_nme;
831 switch (IL_TYPE(ILI_OPC(args[i].arg))) {
832 case ILTY_CONS:
833 arg_nme = 0;
834 arg_dtype = DTYPEG(ILI_OPND(args[i].arg, 1));
835 break;
836 case ILTY_LOAD:
837 arg_nme = ILI_OPND(args[i].arg, 2);
838 arg_dtype = ILI_OPND(args[i].arg, 3);
839 break;
840 case ILTY_ARTH:
841 case ILTY_OTHER:
842 arg_nme = 0;
843 dtype_slot = IL_OPRS(ILI_OPC(args[i].arg));
844 arg_dtype = ILI_OPND(args[i].arg, dtype_slot);
845
846 break;
847 default:
848 assert(false, "ad_func(): unhandled vect ILI type",
849 IL_TYPE(ILI_OPC(args[i].arg)), ERR_Fatal);
850 }
851 argl = ad4ili(args[i].opc, args[i].arg, argl, arg_dtype, arg_nme);
852 } else
853 /* the 3rd argument is for dttype for an IL_ARGAR */
854 argl = ad3ili(args[i].opc, args[i].arg, argl, 0);
855 }
856 }
857
858 func = _mkfunc(func_name);
859 ilix = call_opc == IL_GJSR ? ad3ili(IL_GJSR, func, argl, 0)
860 : ad2ili(call_opc, func, argl);
861 switch (result_opc) {
862 case IL_NONE:
863 break; /* no return value */
864 case IL_DFRAR:
865 ilix = ad2ili(result_opc, ilix, AR_RETVAL);
866 break;
867 case IL_DFRIR:
868 ilix = ad2ili(result_opc, ilix, IR_RETVAL);
869 break;
870 case IL_DFRKR:
871 ilix = ad2ili(result_opc, ilix, KR_RETVAL);
872 break;
873 case IL_DFRSP:
874 ilix = ad2ili(result_opc, ilix, SP_RETVAL);
875 break;
876 case IL_DFRDP:
877 ilix = ad2ili(result_opc, ilix, DP_RETVAL);
878 break;
879 case IL_DFRCS:
880 ilix = ad2ili(result_opc, ilix, CS_RETVAL);
881 break;
882 #ifdef IL_DFRSPX87
883 case IL_DFRSPX87:
884 ilix = ad1ili(result_opc, ilix);
885 break;
886 #endif
887 #ifdef IL_DFRDPX87
888 case IL_DFRDPX87:
889 ilix = ad1ili(result_opc, ilix);
890 break;
891 #endif
892 default:
893 interr("ad_func: illegal result_opc", result_opc, ERR_Severe);
894 }
895 va_end(vargs);
896 return ilix;
897 }
898
899 static char *
fmth_name(char * root)900 fmth_name(char *root)
901 {
902 static char bf[64];
903 char *suf;
904 suf = "";
905 if (TEST_MACH(MACH_AMD_GH)) {
906 suf = "_gh";
907 }
908 sprintf(bf, "%s%s", root, suf);
909 return bf;
910 }
911 /*
912 * fast math naming convention:
913 * __g[sv][sdcz]_BASE[L]
914 * [sv] - scalar vector
915 * [sdcz] - single/double/singlecomplex/doublecomplex
916 * [L] - vector length, i.e., 2, 4, 8, 16
917 */
918 char *
gnr_math(char * root,int widthc,int typec,char * oldname,int masked)919 gnr_math(char *root, int widthc, int typec, char *oldname, int masked)
920 {
921 static char bf[32];
922 /*
923 * widthc - 's' (scalar), 'v' (vector)
924 * N (vector length` N) (2, 4, 8, 16, ...)
925 * typec - 's' (single), 'd' (double),
926 * 'c'( single complex), 'z' (double complex)
927 * oldname - old 'mth' name (only if scalar)
928 */
929 #if defined(TARGET_OSX) || defined(TARGET_WIN)
930 return oldname;
931 #else
932 if (widthc == 's' || widthc == 'v')
933 sprintf(bf, "__g%c%c_%s", widthc, typec, root);
934 else {
935 const char *mk;
936 mk = !masked ? "" : "_mask";
937 sprintf(bf, "__g%c%c_%s%d%s", 'v', typec, root, widthc, mk);
938 }
939 return bf;
940 #endif
941 }
942
943 static char *
vect_math(MTH_FN fn,char * root,int nargs,DTYPE vdt,int vopc,int vdt1,int vdt2,bool mask)944 vect_math(MTH_FN fn, char *root, int nargs, DTYPE vdt, int vopc, int vdt1,
945 int vdt2, bool mask)
946 {
947 int typec;
948 int num_elem;
949 DTYPE vdt_mask = DT_NONE;
950 int func;
951 char *func_name;
952 char oldname[32];
953
954 /*
955 * determine type/precision (single,double, ...) and
956 * construct the names for the lowest common denominator architecture
957 * on x86 - MACH_AMD_K8 or MACH_INTEL without SSE3
958 */
959 if (DTY(vdt) != TY_VECT) {
960 interr("vect_math: dtype is not vector", vdt, ERR_Severe);
961 vdt = get_vector_dtype(DT_DBLE, 2);
962 }
963 if (XBIT_NEW_MATH_NAMES && fn != MTH_mod) {
964 /*
965 * DTY(vdt+1) -- res_dt
966 * DTY(vdt+2) -- vect_len
967 */
968 func_name =
969 make_math_name(fn, DTyVecLength(vdt), mask, DTySeqTyElement(vdt));
970 } else {
971 switch (DTY(DTySeqTyElement(vdt))) {
972 case TY_FLOAT:
973 typec = 's';
974 sprintf(oldname, "__fvs_%s", root);
975 break;
976 case TY_DBLE:
977 typec = 'd';
978 sprintf(oldname, "__fvd_%s", root);
979 break;
980 default:
981 interr("vect_math: unexpected element dtype", DTySeqTyElement(vdt),
982 ERR_Severe);
983 typec = 'd';
984 break;
985 }
986 #if defined(TARGET_LINUX_X8664)
987 if (XBIT_NEW_RELAXEDMATH) {
988 switch (vopc) {
989 case IL_VEXP:
990 func_name = relaxed_math(root, 'v', typec, oldname);
991 goto llvm_hk;
992 case IL_VTAN:
993 case IL_VPOW:
994 /*
995 * a vector double relaxed math version of pow & tan does not exist
996 * so continue to selection of a fast or generic version.
997 */
998 if (typec != 'd') {
999 func_name = relaxed_math(root, 'v', typec, oldname);
1000 goto llvm_hk;
1001 }
1002 break;
1003 }
1004 }
1005 switch (vopc) {
1006 case IL_VPOW:
1007 case IL_VEXP:
1008 case IL_VLOG:
1009 case IL_VATAN:
1010 func_name = gnr_math(root, DTyVecLength(vdt), typec, oldname, 0);
1011 break;
1012 default:
1013 func_name = fast_math(root, DTyVecLength(vdt), typec, oldname);
1014 break;
1015 }
1016 llvm_hk:;
1017 #else
1018 func_name = gnr_math(root, DTyVecLength(vdt), typec, oldname, 0);
1019 #endif
1020 }
1021
1022 if (XBIT_NEW_MATH_NAMES && mask) {
1023 /* dtype of mask is int or int8 */
1024 num_elem = DTyVecLength(vdt);
1025
1026 switch (DTySeqTyElement(vdt)) {
1027 case DT_FLOAT:
1028 case DT_INT:
1029 vdt_mask = DT_INT;
1030 break;
1031 case DT_DBLE:
1032 case DT_INT8:
1033 vdt_mask = DT_INT8;
1034 break;
1035 default:
1036 assert(0, "vect_math, unexpected dtype", DTySeqTyElement(vdt), ERR_Fatal);
1037 }
1038
1039 vdt_mask = get_vector_dtype(vdt_mask, num_elem);
1040 }
1041
1042 switch (nargs) {
1043 case 1:
1044 func = mk_prototype(func_name, "f pure", vdt, 1, vdt);
1045 break;
1046 case 2:
1047 if (vdt1 && vdt2)
1048 func = mk_prototype(func_name, "f pure", vdt, 2, vdt1, vdt2);
1049 else if (vdt_mask)
1050 func = mk_prototype(func_name, "f pure", vdt, 2, vdt, vdt_mask);
1051 else
1052 func = mk_prototype(func_name, "f pure", vdt, 2, vdt, vdt);
1053 break;
1054 case 3:
1055 if (vdt1 && vdt2)
1056 func = mk_prototype(func_name, "f pure", vdt, 3, vdt1, vdt2, vdt);
1057 else if (vdt_mask)
1058 func = mk_prototype(func_name, "f pure", vdt, 3, vdt, vdt, vdt_mask);
1059 else
1060 func = mk_prototype(func_name, "f pure", vdt, 3, vdt, vdt, vdt);
1061 break;
1062 default:
1063 interr("vect_math: unexpected number of args", nargs, ERR_Severe);
1064 func = mk_prototype(func_name, "f pure", vdt, 1, vdt);
1065 break;
1066 }
1067 #ifdef AVXP
1068 // FIXME: looks like a bug: DTY(aVectorLength)?
1069 if ((typec == 's' && DTY((DTYPE)DTyVecLength(vdt)) >= 8) ||
1070 (typec == 'd' && DTY((DTYPE)DTyVecLength(vdt)) >= 4)) {
1071 AVXP(func, 1); /* inhibit veroupper */
1072 }
1073 #endif
1074 return func_name;
1075 }
1076
1077 #if !defined(TARGET_POWER)
1078 /*
1079 * fast math naming convention:
1080 * __f[sv][sd]_BASE[_suf]
1081 *
1082 * NOTE that the naming convention will become
1083 * __g[sv][sdcz]_BASE
1084 * [sv] - scalar vector
1085 * [sdcz] - single/double/singlecomplex/doublecomplex
1086 * [L] - vector length, i.e., 2, 4, 8, 16
1087 */
1088 char *
fast_math(char * root,int widthc,int typec,char * oldname)1089 fast_math(char *root, int widthc, int typec, char *oldname)
1090 {
1091 /*
1092 * widthc - width indicator: 's' (scalar), 'v' (vector),
1093 * or a vector length (2, 4, 8, ..); if length
1094 * is passed, 'v' is used.
1095 * typec - 's' (single), 'd' (double)
1096 * oldname - old 'fastmath' name
1097 */
1098 static char bf[32];
1099 char *suf;
1100 int avxp;
1101 suf = "";
1102 avxp = 0;
1103 if (XBIT(15, 0x4000000)) {
1104 /*
1105 * Use the old fastmath names.
1106 */
1107 if (TEST_MACH(MACH_AMD_GH)) {
1108 suf = "_gh";
1109 }
1110 sprintf(bf, "%s%s", oldname, suf);
1111 } else {
1112 char *simdw;
1113 simdw = "";
1114 if ((typec == 's' && widthc == 8) || (typec == 'd' && widthc == 4))
1115 simdw = "_256";
1116 if (TEST_MACH(MACH_INTEL_SANDYBRIDGE)) {
1117 suf = "_vex";
1118 avxp = 1;
1119 } else if (TEST_MACH(MACH_AMD_BULLDOZER)) {
1120 if (TEST_FEATURE(FEATURE_FMA4))
1121 suf = "_fma4";
1122 else
1123 suf = "_vex"; /* -nofma */
1124 avxp = 1;
1125 } else if (TEST_FEATURE(FEATURE_SSE3)) {
1126 ;
1127 } else {
1128 /*** MACH_AMD_K8 or MACH_INTEL without SSE3 ***/
1129 sprintf(bf, "%s%s", oldname, suf);
1130 return bf;
1131 }
1132 if (widthc != 's' && widthc != 'v')
1133 widthc = 'v'; /* vector length is passed */
1134 sprintf(bf, "__f%c%c_%s%s%s", widthc, typec, root, suf, simdw);
1135 }
1136 return bf;
1137 }
1138 #else
1139 /*
1140 * fast math naming convention:
1141 * __g[sv][sdcz]_BASEL
1142 * [sv] - scalar vector
1143 * [sdcz] - single/double/singlecomplex/doublecomplex
1144 * [L] - vector length, i.e., 2, 4, 8, 16
1145 */
1146 char *
fast_math(char * root,int widthc,int typec,char * oldname)1147 fast_math(char *root, int widthc, int typec, char *oldname)
1148 {
1149 static char bf[32];
1150 /*
1151 * widthc - 's' (scalar), 'v' (vector)
1152 * N (vector length` N) (2, 4, 8, 16, ...)
1153 * typec - 's' (single), 'd' (double),
1154 * 'c'( single complex), 'z' (double complex)
1155 * oldname - old 'mth' name (at this time, not used)
1156 */
1157
1158 return gnr_math(root, widthc, typec, oldname, 0);
1159 }
1160 #endif
1161
1162 /** \brief Called if and only if there exists the possiblity of a
1163 * -Mfprelaxed=intrinsic version of the routine.
1164 */
1165 char *
relaxed_math(char * root,int widthc,int typec,char * oldname)1166 relaxed_math(char *root, int widthc, int typec, char *oldname)
1167 {
1168 static char bf[32];
1169 /*
1170 * widthc - width indicator: 's' (scalar), 'v' (vector)
1171 */
1172 char *suf;
1173 int avxp;
1174
1175 avxp = 0;
1176 if (!XBIT_NEW_RELAXEDMATH)
1177 return fast_math(root, widthc, typec, oldname);
1178 suf = "";
1179 if (TEST_MACH(MACH_INTEL_SANDYBRIDGE)) {
1180 suf = "_vex";
1181 if (widthc == 'v' && !TEST_FEATURE(FEATURE_SIMD128)) {
1182 suf = "_vex_256";
1183 }
1184 avxp = 1;
1185 } else if (TEST_MACH(MACH_AMD_BULLDOZER)) {
1186 if (TEST_FEATURE(FEATURE_FMA4)) {
1187 suf = "_fma4";
1188 if (widthc == 'v' && !TEST_FEATURE(FEATURE_SIMD128)) {
1189 suf = "_fma4_256";
1190 }
1191 } else {
1192 suf = "_vex"; /* -nofma */
1193 if (widthc == 'v' && !TEST_FEATURE(FEATURE_SIMD128)) {
1194 suf = "_vex_256";
1195 }
1196 }
1197 avxp = 1;
1198 } else
1199 return fast_math(root, widthc, typec, oldname);
1200 sprintf(bf, "__r%c%c_%s%s", widthc, typec, root, suf);
1201 return bf;
1202 }
1203
1204 /** \brief Add func call with 2 integer*8 arguments returning integer*8 value
1205 *
1206 * \param opc must be a function call ili opcode: QJSR, JSR
1207 */
1208 int
ad2func_kint(ILI_OP opc,char * name,int opn1,int opn2)1209 ad2func_kint(ILI_OP opc, char *name, int opn1, int opn2)
1210 {
1211 int tmp, tmp1, tmp2;
1212 tmp1 = ad1ili(IL_NULL, 0);
1213 tmp1 = ad2ili(IL_ARGKR, opn2, tmp1);
1214 tmp2 = ad2ili(IL_ARGKR, opn1, tmp1);
1215 tmp = ad2ili(opc, _mkfunc(name), tmp2);
1216 return ad2ili(IL_DFRKR, tmp, KR_RETVAL);
1217 }
1218
1219 int
ad3ili(ILI_OP opc,int opn1,int opn2,int opn3)1220 ad3ili(ILI_OP opc, int opn1, int opn2, int opn3)
1221 {
1222 ILI newili;
1223
1224 newili.opc = opc;
1225 newili.opnd[0] = opn1;
1226 newili.opnd[1] = opn2;
1227 newili.opnd[2] = opn3;
1228 newili.opnd[3] = 0;
1229 newili.opnd[4] = 0;
1230 return addili(&newili);
1231 }
1232
1233 /** \brief Add an ili with three operands which has an alternate
1234 *
1235 * The routine isstatic -- only addili should create ALT ili.
1236 */
1237 static int
ad3altili(ILI_OP opc,int opn1,int opn2,int opn3,int alt)1238 ad3altili(ILI_OP opc, int opn1, int opn2, int opn3, int alt)
1239 {
1240 ILI newili;
1241 int ilix;
1242
1243 newili.opc = opc;
1244 newili.opnd[0] = opn1;
1245 newili.opnd[1] = opn2;
1246 newili.opnd[2] = opn3;
1247 newili.opnd[3] = 0;
1248 newili.opnd[4] = 0;
1249 ilix = get_ili(&newili);
1250 if (ILI_ALT(ilix) == 0)
1251 ILI_ALT(ilix) = alt;
1252 return ilix;
1253 }
1254
1255 int
ad4ili(ILI_OP opc,int opn1,int opn2,int opn3,int opn4)1256 ad4ili(ILI_OP opc, int opn1, int opn2, int opn3, int opn4)
1257 {
1258 ILI newili;
1259
1260 newili.opc = opc;
1261 newili.opnd[0] = opn1;
1262 newili.opnd[1] = opn2;
1263 newili.opnd[2] = opn3;
1264 newili.opnd[3] = opn4;
1265 newili.opnd[4] = 0;
1266 return addili(&newili);
1267 }
1268
1269 static int
ad4altili(ILI_OP opc,int opn1,int opn2,int opn3,int opn4,int alt)1270 ad4altili(ILI_OP opc, int opn1, int opn2, int opn3, int opn4, int alt)
1271 {
1272 ILI newili;
1273 int ilix;
1274
1275 newili.opc = opc;
1276 newili.opnd[0] = opn1;
1277 newili.opnd[1] = opn2;
1278 newili.opnd[2] = opn3;
1279 newili.opnd[3] = opn4;
1280 newili.opnd[4] = 0;
1281 ilix = get_ili(&newili);
1282 if (ILI_ALT(ilix) == 0)
1283 ILI_ALT(ilix) = alt;
1284 return ilix;
1285 }
1286
1287 int
ad5ili(ILI_OP opc,int opn1,int opn2,int opn3,int opn4,int opn5)1288 ad5ili(ILI_OP opc, int opn1, int opn2, int opn3, int opn4, int opn5)
1289 {
1290 ILI newili;
1291
1292 newili.opc = opc;
1293 newili.opnd[0] = opn1;
1294 newili.opnd[1] = opn2;
1295 newili.opnd[2] = opn3;
1296 newili.opnd[3] = opn4;
1297 newili.opnd[4] = opn5;
1298 return addili(&newili);
1299 }
1300
1301 int
ad_icon(INT val)1302 ad_icon(INT val)
1303 {
1304 static INT ival[] = {0, 0};
1305 ival[1] = val;
1306 return ad1ili(IL_ICON, getcon(ival, DT_INT));
1307 }
1308
1309 int
ad_kcon(INT m32,INT l32)1310 ad_kcon(INT m32, INT l32)
1311 {
1312 INT ival[2];
1313
1314 ival[0] = m32;
1315 ival[1] = l32;
1316 return ad1ili(IL_KCON, getcon(ival, DT_INT8));
1317 }
1318
1319 int
ad_kconi(ISZ_T v)1320 ad_kconi(ISZ_T v)
1321 {
1322 INT num[2];
1323 int s;
1324
1325 ISZ_2_INT64(v, num);
1326 s = getcon(num, DT_INT8);
1327 return ad1ili(IL_KCON, s);
1328 }
1329
1330 int
ad_aconi(ISZ_T val)1331 ad_aconi(ISZ_T val)
1332 {
1333 return ad1ili(IL_ACON, get_acon(SPTR_NULL, val));
1334 }
1335
1336 int
ad_aconk(INT m32,INT l32)1337 ad_aconk(INT m32, INT l32)
1338 {
1339 INT ival[2];
1340 ISZ_T v;
1341
1342 ival[0] = m32;
1343 ival[1] = l32;
1344 INT64_2_ISZ(ival, v);
1345 return ad1ili(IL_ACON, get_acon(SPTR_NULL, v));
1346 }
1347
1348 int
ad_acon(SPTR sym,ISZ_T val)1349 ad_acon(SPTR sym, ISZ_T val)
1350 {
1351 return ad1ili(IL_ACON, get_acon(sym, val));
1352 }
1353
1354 int
ad_cse(int ilix)1355 ad_cse(int ilix)
1356 {
1357 switch (IL_RES(ILI_OPC(ilix))) {
1358 case ILIA_IR:
1359 ilix = ad1ili(IL_CSEIR, ilix);
1360 break;
1361 case ILIA_KR:
1362 ilix = ad1ili(IL_CSEKR, ilix);
1363 break;
1364 case ILIA_AR:
1365 ilix = ad1ili(IL_CSEAR, ilix);
1366 break;
1367 case ILIA_SP:
1368 ilix = ad1ili(IL_CSESP, ilix);
1369 break;
1370 case ILIA_DP:
1371 ilix = ad1ili(IL_CSEDP, ilix);
1372 break;
1373 #ifdef ILIA_CS
1374 case ILIA_CS:
1375 ilix = ad1ili(IL_CSECS, ilix);
1376 break;
1377 case ILIA_CD:
1378 ilix = ad1ili(IL_CSECD, ilix);
1379 break;
1380 #endif
1381 #ifdef LONG_DOUBLE_FLOAT128
1382 case ILIA_FLOAT128:
1383 ilix = ad1ili(IL_FLOAT128CSE, ilix);
1384 break;
1385 #endif
1386 case ILIA_LNK:
1387 if (ili_get_vect_dtype(ilix)) {
1388 ilix = ad1ili(IL_CSE, ilix);
1389 break;
1390 }
1391 default:
1392 interr("ad_cse: bad IL_RES", ilix, ERR_Severe);
1393 break;
1394 }
1395 return ilix;
1396 }
1397
1398 int
ad_load(int stx)1399 ad_load(int stx)
1400 {
1401 int nme;
1402 int base;
1403 int load;
1404
1405 nme = ILI_OPND(stx, 3);
1406 base = ILI_OPND(stx, 2);
1407 load = 0;
1408 switch (ILI_OPC(stx)) {
1409 case IL_ST:
1410 load = ad3ili(IL_LD, base, nme, ILI_OPND(stx, 4));
1411 break;
1412 case IL_STKR:
1413 load = ad3ili(IL_LDKR, base, nme, MSZ_I8);
1414 break;
1415 case IL_STA:
1416 load = ad2ili(IL_LDA, base, nme);
1417 break;
1418 case IL_STSP:
1419 load = ad3ili(IL_LDSP, base, nme, MSZ_F4);
1420 break;
1421 case IL_STDP:
1422 load = ad3ili(IL_LDDP, base, nme, MSZ_F8);
1423 break;
1424 case IL_STSCMPLX:
1425 load = ad3ili(IL_LDSCMPLX, base, nme, MSZ_F8);
1426 break;
1427 case IL_STDCMPLX:
1428 load = ad3ili(IL_LDDCMPLX, base, nme, MSZ_F16);
1429 break;
1430 case IL_STQ:
1431 load = ad3ili(IL_LDQ, base, nme, MSZ_F16);
1432 break;
1433 case IL_ST256:
1434 load = ad3ili(IL_LD256, base, nme, MSZ_F32);
1435 break;
1436 case IL_VST:
1437 load = ad3ili(IL_VLD, base, nme, ILI_OPND(stx, 4));
1438 break;
1439 case IL_VSTU:
1440 load = ad3ili(IL_VLDU, base, nme, ILI_OPND(stx, 4));
1441 break;
1442 #ifdef LONG_DOUBLE_FLOAT128
1443 case IL_FLOAT128ST:
1444 load = ad3ili(IL_FLOAT128LD, base, nme, MSZ_F16);
1445 break;
1446 #endif /* LONG_DOUBLE_FLOAT128 */
1447 default:
1448 break;
1449 }
1450 return load;
1451 }
1452
1453 int
ad_free(int ilix)1454 ad_free(int ilix)
1455 {
1456 ILI_OP opc;
1457 ILIA_RESULT r = IL_RES(ILI_OPC(ilix));
1458 switch (r) {
1459 default:
1460 interr("ad_free: not yet implemented for this result type", r, ERR_Fatal);
1461 case ILIA_IR:
1462 opc = IL_FREEIR;
1463 break;
1464 case ILIA_AR:
1465 opc = IL_FREEAR;
1466 break;
1467 case ILIA_SP:
1468 opc = IL_FREESP;
1469 break;
1470 case ILIA_DP:
1471 opc = IL_FREEDP;
1472 break;
1473 #ifdef ILIA_CS
1474 case ILIA_CS:
1475 opc = IL_FREECS;
1476 break;
1477 case ILIA_CD:
1478 opc = IL_FREECD;
1479 break;
1480 #endif
1481 case ILIA_KR:
1482 opc = IL_FREEKR;
1483 break;
1484 #ifdef LONG_DOUBLE_FLOAT128
1485 case ILIA_FLOAT128:
1486 opc = IL_FLOAT128FREE;
1487 break;
1488 #endif /* LONG_DOUBLE_FLOAT128 */
1489 }
1490 return ad1ili(opc, ilix);
1491 }
1492
1493 int
ili_opnd(int ilix,int n)1494 ili_opnd(int ilix, int n)
1495 {
1496 ilix = ILI_OPND(ilix, n);
1497
1498 if (ILI_OPC(ilix) == IL_CSEAR || ILI_OPC(ilix) == IL_CSEIR ||
1499 ILI_OPC(ilix) == IL_CSEKR)
1500 return ILI_OPND(ilix, 1);
1501 return ilix;
1502 } /* ili_opnd */
1503
1504 /** \brief Given a store opc, return a corresponding load opc.
1505 */
1506 ILI_OP
ldopc_from_stopc(ILI_OP stopc)1507 ldopc_from_stopc(ILI_OP stopc)
1508 {
1509 ILI_OP ldopc = IL_NONE;
1510 switch (stopc) {
1511 case IL_ST:
1512 ldopc = IL_LD;
1513 break;
1514 case IL_STKR:
1515 ldopc = IL_LDKR;
1516 break;
1517 case IL_STSP:
1518 ldopc = IL_LDSP;
1519 break;
1520 case IL_STDP:
1521 ldopc = IL_LDDP;
1522 break;
1523 case IL_STSCMPLX:
1524 ldopc = IL_LDSCMPLX;
1525 break;
1526 case IL_STDCMPLX:
1527 ldopc = IL_LDDCMPLX;
1528 break;
1529 case IL_STQ:
1530 ldopc = IL_LDQ;
1531 break;
1532 case IL_ST256:
1533 ldopc = IL_LD256;
1534 break;
1535 case IL_VST:
1536 ldopc = IL_VLD;
1537 break;
1538 case IL_VSTU:
1539 ldopc = IL_VLDU;
1540 break;
1541 case IL_STA:
1542 ldopc = IL_LDA;
1543 break;
1544 #ifdef IL_DOUBLEDOUBLEST
1545 case IL_DOUBLEDOUBLEST:
1546 ldopc = IL_DOUBLEDOUBLELD;
1547 break;
1548 #endif
1549 default:
1550 break;
1551 }
1552 return ldopc;
1553 }
1554
1555 void
ldst_msz(DTYPE dtype,ILI_OP * ld,ILI_OP * st,MSZ * siz)1556 ldst_msz(DTYPE dtype, ILI_OP *ld, ILI_OP *st, MSZ *siz)
1557 {
1558 *ld = IL_LD;
1559 *st = IL_ST;
1560
1561 switch (DTY(dtype)) {
1562 case TY_BINT:
1563 case TY_CHAR:
1564 *siz = MSZ_SBYTE;
1565 break;
1566 case TY_SINT:
1567 case TY_NCHAR:
1568 *siz = MSZ_SHWORD;
1569 break;
1570 case TY_FLOAT:
1571 *siz = MSZ_F4;
1572 *ld = IL_LDSP;
1573 *st = IL_STSP;
1574 break;
1575 case TY_CMPLX:
1576 *siz = MSZ_F8;
1577 *ld = IL_LDSCMPLX;
1578 *st = IL_STSCMPLX;
1579 return;
1580 case TY_INT8:
1581 *siz = MSZ_I8;
1582 *ld = IL_LDKR;
1583 *st = IL_STKR;
1584 return;
1585 case TY_QUAD:
1586 case TY_DBLE:
1587 *siz = MSZ_F8;
1588 *ld = IL_LDDP;
1589 *st = IL_STDP;
1590 break;
1591 case TY_DCMPLX:
1592 *siz = MSZ_F16;
1593 *ld = IL_LDDCMPLX;
1594 *st = IL_STDCMPLX;
1595 break;
1596 case TY_PTR:
1597 *siz = MSZ_PTR;
1598 *ld = IL_LDA;
1599 *st = IL_STA;
1600 break;
1601 case TY_STRUCT:
1602 switch (DTyAlgTySize(dtype)) {
1603 case 1:
1604 *siz = MSZ_BYTE;
1605 break;
1606 case 2:
1607 *siz = MSZ_SHWORD;
1608 break;
1609 case 8:
1610 *siz = MSZ_F8;
1611 break;
1612 case 16:
1613 *siz = MSZ_F16;
1614 break;
1615 case 4:
1616 default:
1617 *siz = MSZ_WORD;
1618 break;
1619 }
1620 break;
1621 case TY_INT:
1622 default:
1623 *siz = MSZ_WORD;
1624 break;
1625 }
1626 switch (*siz) {
1627 case MSZ_FWORD:
1628 *ld = IL_LDSP;
1629 *st = IL_STSP;
1630 break;
1631 case MSZ_DFLWORD:
1632 *ld = IL_LDDP;
1633 *st = IL_STDP;
1634 break;
1635 default:
1636 break;
1637 }
1638 }
1639
1640 #if defined(TARGET_WIN_X8664)
1641 /** \brief Insert an ARGRSRV ili between the last register arg and the first
1642 * memory arg or null.
1643 *
1644 * \param ilip represents a procedure
1645 */
1646 static void
insert_argrsrv(ILI * ilip)1647 insert_argrsrv(ILI *ilip)
1648 {
1649 int arg_ilix;
1650 int prev_ilix;
1651 ILI_OP opc;
1652
1653 opc = ilip->opc;
1654 if (opc == IL_GJSR)
1655 return;
1656 if (opc == IL_GJSRA)
1657 return;
1658 #if DEBUG
1659 if (opc != IL_QJSR && opc != IL_JSR && opc != IL_JSRA)
1660 interr("insert_argrsrv: unexpected proc", opc, ERR_Severe);
1661 #endif
1662
1663 /* do not insert IL_ARGRSRV for routines that depend on the
1664 * organization of the stack (i.e., _mp routines)
1665 */
1666 if (opc != IL_JSRA && NOPADG(ilip->opnd[0]))
1667 return;
1668
1669 prev_ilix = 0;
1670 arg_ilix = ilip->opnd[1];
1671
1672 /* no args */
1673 if (ILI_OPC(arg_ilix) == IL_NULL) {
1674 ilip->opnd[1] = ad2ili(IL_ARGRSRV, MR_MAX_ARGRSRV, arg_ilix);
1675 return;
1676 }
1677
1678 /* one or more args */
1679 while (ILI_OPC(arg_ilix) != IL_NULL && ILI_OPC(arg_ilix) != IL_ARGRSRV) {
1680 switch (ILI_OPC(arg_ilix)) {
1681 case IL_DAIR:
1682 case IL_DASP:
1683 case IL_DASPSP:
1684 case IL_DADP:
1685 #ifdef IL_DA128
1686 case IL_DA128:
1687 #endif
1688 #ifdef IL_DA256
1689 case IL_DA256:
1690 #endif
1691 case IL_DACD:
1692 case IL_DACS:
1693 case IL_DAAR:
1694 case IL_DAKR:
1695 case IL_PSARG:
1696 case IL_PDARG:
1697 prev_ilix = arg_ilix;
1698 arg_ilix = ILI_OPND(arg_ilix, 3);
1699 if (ILI_OPC(arg_ilix) == IL_NULL) {
1700 int argrsrv = ad2ili(IL_ARGRSRV, MR_MAX_ARGRSRV, arg_ilix);
1701 ILI_OPND(prev_ilix, 3) = argrsrv;
1702 }
1703 break;
1704 case IL_ARGIR:
1705 case IL_ARGSP:
1706 case IL_ARGDP:
1707 case IL_ARGAR:
1708 case IL_ARGKR:
1709 #ifdef LONG_DOUBLE_FLOAT128
1710 case IL_FLOAT128ARG:
1711 #endif
1712 /* this path taken only with the first mem arg, after reg args */
1713 arg_ilix = ad2ili(IL_ARGRSRV, MR_MAX_ARGRSRV, arg_ilix);
1714 #if DEBUG
1715 assert(prev_ilix, "insert_argrsrv: no reg args", ilip->opnd[0],
1716 ERR_Severe);
1717 #endif
1718 ILI_OPND(prev_ilix, 3) = arg_ilix;
1719 break;
1720 default:
1721 interr("insert_argrsrv: unexpected arg ili", ILI_OPC(arg_ilix),
1722 ERR_Severe);
1723 }
1724 }
1725 }
1726 #endif
1727
1728 /** \brief Return i such that 2**i > |n| >= 2**(i+1)
1729 *
1730 * Use reciprocal division to compute n/d where d is a compile-time constant.
1731 * See PLDI '94, "Division by invariant integers using multiplication"
1732 * by Granlund and Montgomery.
1733 */
1734 static int
lg(unsigned d)1735 lg(unsigned d)
1736 {
1737 int i = 0;
1738 unsigned int twoi = 1, dd;
1739 dd = d;
1740 while (dd > twoi) {
1741 ++i;
1742 twoi = twoi << 1;
1743 }
1744 return i;
1745 } /* lg */
1746
1747 static int
lg64(DBLUINT64 d)1748 lg64(DBLUINT64 d)
1749 {
1750 int i = 0;
1751 DBLUINT64 twoi = {0x0, 0x1};
1752 DBLUINT64 dd;
1753
1754 dd[0] = d[0];
1755 dd[1] = d[1];
1756 while (ucmp64(dd, twoi) > 0) {
1757 i++;
1758 ushf64(twoi, 1, twoi);
1759 }
1760 return i;
1761 }
1762
1763 /*
1764 * find reciprocal approximation, shift distance,
1765 * set 'alt' for which code alternative to generate.
1766 * We compute 2**(N+l)/d as ((2**N * (2**(l)-d))/d) + 2**N
1767 * This since l can be as big as N, so we prevent overflow in the numerator
1768 * (don't want 2**(2*N))
1769 */
1770 static int shpost;
1771 static DBLINT64 mrecip;
1772 static DBLINT64 twon, twonm1;
1773
1774 void
choose_multiplier(int N,unsigned dd,int prec)1775 choose_multiplier(int N, unsigned dd, int prec)
1776 {
1777 DBLINT64 mlow, mhigh, d, mlow2, mhigh2;
1778 int l;
1779
1780 l = lg(dd); /* ceiling(lg(d)) */
1781 shpost = l;
1782
1783 d[0] = 0;
1784 d[1] = dd; /* DBLINT64 copy of d */
1785
1786 twon[0] = 0; /* twon is 2**N, used for comparisons */
1787 twon[1] = 1;
1788 shf64(twon, N, twon);
1789 twonm1[0] = 0; /* twonm1 is 2**(N-1), used for comparisons */
1790 twonm1[1] = 1;
1791 shf64(twonm1, N - 1, twonm1);
1792
1793 mlow[0] = 0; /* mlow = 1 */
1794 mlow[1] = 1;
1795 mhigh[0] = 0; /* mhigh = 1 */
1796 mhigh[1] = 1;
1797 shf64(mlow, l, mlow); /* mlow = 2**l */
1798 shf64(mhigh, l + N - prec, mhigh); /* mhigh = 2**(N+l-prec) */
1799 sub64(mlow, d, mlow); /* mlow = 2**l - d */
1800 mul64(mlow, twon, mlow); /* mlow = 2**N * (2**l - d) */
1801 add64(mhigh, mlow, mhigh); /* 2**N * (2**l - d + 2**(l-prec)) */
1802 div64(mlow, d, mlow); /* mlow = (2**N * (2**l - d))/d */
1803 div64(mhigh, d, mhigh); /* (2**N * (2**l - d + 2**(l-prec))) */
1804 add64(mlow, twon, mlow); /* mlow = (2**N * 2**l)/d */
1805 add64(mhigh, twon, mhigh); /* (2**N * (2**l + 2**(l-prec)))/d */
1806
1807 /* here, mlow = floor(2**(N+l)/d); mhigh = floor(2**(N+l-prec)/d) */
1808
1809 while (shpost > 0) {
1810 shf64(mlow, -1, mlow2);
1811 shf64(mhigh, -1, mhigh2);
1812 if (cmp64(mlow2, mhigh2) >= 0)
1813 break;
1814 mlow[0] = mlow2[0];
1815 mlow[1] = mlow2[1];
1816 mhigh[0] = mhigh2[0];
1817 mhigh[1] = mhigh2[1];
1818 --shpost;
1819 }
1820 mrecip[0] = mhigh[0];
1821 mrecip[1] = mhigh[1];
1822 } /* choose_multiplier */
1823
1824 static INT128 mrecip_128;
1825 static INT128 twon_128, twonm1_128;
1826
1827 void
choose_multiplier_64(int N,DBLUINT64 dd,int prec)1828 choose_multiplier_64(int N, DBLUINT64 dd, int prec)
1829 {
1830 INT128 mlow, mhigh, d, mlow2, mhigh2;
1831 int l;
1832
1833 l = lg64(dd); /* ceiling(lg(d)) */
1834 shpost = l;
1835
1836 d[0] = 0;
1837 d[1] = 0;
1838 d[2] = dd[0];
1839 d[3] = dd[1]; /* DBLINT64 copy of d */
1840
1841 /* twon is 2**N, used for comparisons */
1842 twon_128[0] = 0;
1843 twon_128[1] = 0;
1844 twon_128[2] = 0;
1845 twon_128[3] = 1;
1846
1847 shf128(twon_128, N, twon_128);
1848
1849 twonm1_128[0] = 0; /* twonm1 is 2**(N-1), used for comparisons */
1850 twonm1_128[1] = 0;
1851 twonm1_128[2] = 0;
1852 twonm1_128[3] = 1;
1853 shf128(twonm1_128, N - 1, twonm1_128);
1854
1855 mlow[0] = 0; /* mlow = 1 */
1856 mlow[1] = 0;
1857 mlow[2] = 0;
1858 mlow[3] = 1;
1859
1860 mhigh[0] = 0; /* mhigh = 1 */
1861 mhigh[1] = 0;
1862 mhigh[2] = 0;
1863 mhigh[3] = 1;
1864
1865 shf128(mlow, l, mlow); /* mlow = 2**l */
1866 shf128(mhigh, l + N - prec, mhigh); /* mhigh = 2**(N+l-prec) */
1867 sub128(mlow, d, mlow); /* mlow = 2**l - d */
1868 mul128l(mlow, twon_128, mlow); /* mlow = 2**N * (2**l - d) */
1869 add128(mhigh, mlow, mhigh); /* 2**N * (2**l - d + 2**(l-prec)) */
1870 div128(mlow, d, mlow); /* mlow = (2**N * (2**l - d))/d */
1871 div128(mhigh, d, mhigh); /* (2**N * (2**l - d + 2**(l-prec))) */
1872 add128(mlow, twon_128, mlow); /* mlow = (2**N * 2**l)/d */
1873 add128(mhigh, twon_128, mhigh); /* (2**N * (2**l + 2**(l-prec)))/d */
1874
1875 /* here, mlow = floor(2**(N+l)/d); mhigh = floor(2**(N+l-prec)/d) */
1876
1877 while (shpost > 0) {
1878 shf128(mlow, -1, mlow2);
1879 shf128(mhigh, -1, mhigh2);
1880
1881 if (cmp128(mlow2, mhigh2) >= 0)
1882 break;
1883
1884 mlow[0] = mlow2[0];
1885 mlow[1] = mlow2[1];
1886 mlow[2] = mlow2[2];
1887 mlow[3] = mlow2[3];
1888
1889 mhigh[0] = mhigh2[0];
1890 mhigh[1] = mhigh2[1];
1891 mhigh[2] = mhigh2[2];
1892 mhigh[3] = mhigh2[3];
1893 --shpost;
1894 }
1895
1896 mrecip_128[0] = mhigh[0];
1897 mrecip_128[1] = mhigh[1];
1898 mrecip_128[2] = mhigh[2];
1899 mrecip_128[3] = mhigh[3];
1900 } /* choose_multiplier_64 */
1901
1902 static int
ICON(INT v)1903 ICON(INT v)
1904 {
1905 INT r[2], ilix, recipsym;
1906 r[0] = 0;
1907 r[1] = v;
1908 recipsym = getcon(r, DT_INT);
1909 ilix = ad1ili(IL_ICON, recipsym);
1910 return ilix;
1911 } /* ICON */
1912
1913 static int
KCON(INT v)1914 KCON(INT v)
1915 {
1916 INT r[2], ilix, recipsym;
1917 r[0] = 0;
1918 r[1] = v;
1919 recipsym = getcon(r, DT_INT8);
1920 ilix = ad1ili(IL_KCON, recipsym);
1921 return ilix;
1922 } /* KCON */
1923
1924 static int
MULSH(int ilix,int iliy)1925 MULSH(int ilix, int iliy)
1926 {
1927 /* copied from the intrinsic function __muln */
1928 int t1, t2, t3, t4, t5, t6, t7, t8, t9;
1929
1930 t1 = ad2ili(IL_KMUL, ilix, iliy);
1931 t2 = ICON(32);
1932 t3 = ad2ili(IL_KURSHIFT, t1, t2);
1933 return t3;
1934 } /* MULSH */
1935
1936 static int
KMULSH(int ilix,int iliy)1937 KMULSH(int ilix, int iliy)
1938 {
1939 /* copied from the intrinsic function __muln */
1940 int t1, t2, t3, t4, t5, t6, t7, t8, t9;
1941
1942 t1 = ad2ili(IL_KMULH, ilix, iliy);
1943 return t1;
1944 } /* MULSH */
1945
1946 static int
KMULUH(int ilix,int iliy)1947 KMULUH(int ilix, int iliy)
1948 {
1949 int t1;
1950
1951 t1 = ad2ili(IL_UKMULH, ilix, iliy);
1952 return t1;
1953 } /* KMULUH */
1954
1955 static int
MULUH(int ilix,int iliy)1956 MULUH(int ilix, int iliy)
1957 {
1958 /* copied from the intrinsic function __muln */
1959 int t1, t2, t3, t4, t5, t6, t7, t8, t9;
1960
1961 t1 = ad2ili(IL_UKMUL, ilix, iliy);
1962 t2 = ICON(32);
1963 t3 = ad2ili(IL_KURSHIFT, t1, t2);
1964
1965 return t3;
1966 } /* MULUH */
1967
1968 static int
MULU(int ilix,int iliy)1969 MULU(int ilix, int iliy)
1970 {
1971 /* copied from the intrinsic function __muln */
1972 int t1, t2, t3, t4, t5, t6, t7, t8, t9;
1973
1974 t1 = ad2ili(IL_UIMUL, ilix, iliy);
1975
1976 return t1;
1977 } /* MULU */
1978
1979 static int
MUL(int ilix,int iliy)1980 MUL(int ilix, int iliy)
1981 {
1982 /* copied from the intrinsic function __muln */
1983 int t1, t2, t3, t4, t5, t6, t7, t8, t9;
1984
1985 t1 = ad2ili(IL_IMUL, ilix, iliy);
1986
1987 return t1;
1988 } /* MUL */
1989
1990 static int
KMUL(int ilix,int iliy)1991 KMUL(int ilix, int iliy)
1992 {
1993 /* copied from the intrinsic function __muln */
1994 int t1;
1995
1996 t1 = ad2ili(IL_KMUL, ilix, iliy);
1997
1998 return t1;
1999 } /* MUL */
2000
2001 static int
XSIGN(int ilix,int N)2002 XSIGN(int ilix, int N)
2003 {
2004 int t, t1;
2005 t1 = ICON(N - 1);
2006 t = ad2ili(IL_ARSHIFT, ilix, t1); /* XSIGN(n) in the paper */
2007 return t;
2008 } /* XSIGN */
2009
2010 static int
KXSIGN(int ilix,int N)2011 KXSIGN(int ilix, int N)
2012 {
2013 int t, t1;
2014 t1 = ICON(N - 1);
2015 t = ad2ili(IL_KARSHIFT, ilix, t1); /* XSIGN(n) in the paper */
2016 return t;
2017 } /* XSIGN */
2018
2019 #define WSIZE 32
2020
2021 static void
mod_decompose(int d,int * d0,int * k)2022 mod_decompose(int d, int *d0, int *k)
2023 {
2024 int i;
2025
2026 i = 1;
2027
2028 do {
2029 if ((d >> i) & 0x1) {
2030 *d0 = d >> i;
2031 *k = i;
2032 return;
2033 }
2034 i++;
2035 } while (i <= 32);
2036 }
2037
2038 /* From the book "Hacker's Delight", Henry S. Warren */
2039 static int
test_mod_zero(int n,int d,int sgnd,int cc)2040 test_mod_zero(int n, int d, int sgnd, int cc)
2041 {
2042 int d0, k;
2043 int M, N, fl;
2044 int q0, t0, t1, t2, t3;
2045
2046 N = 32;
2047
2048 if (!sgnd) {
2049 if (d & 0x1) { /* divisor is odd */
2050 return 0;
2051 } else {
2052 mod_decompose(d, &d0, &k);
2053 choose_multiplier(n, d0, N);
2054 fl = 0xfffffffe / d;
2055 t1 = ICON(k);
2056 t0 = KCON(mrecip[1]);
2057 t2 = ad1ili(IL_IKMV, n);
2058 q0 = MULU(t2, t0);
2059 q0 = ad1ili(IL_KIMV, q0);
2060 q0 = ad2ili(IL_ROTR, q0, t1);
2061 t1 = ICON(fl);
2062 t1 = ad3ili(IL_ICMP, q0, t1, (cc == CC_EQ) ? CC_LE : CC_GT);
2063 return t1;
2064 }
2065
2066 } else {
2067 return 0;
2068 }
2069 }
2070
2071 static int
reciprocal_division(int n,INT divisor,int sgnd)2072 reciprocal_division(int n, INT divisor, int sgnd)
2073 {
2074 int l, mp, sh, N;
2075 int t1, t2, q0, q3, q, recipsym;
2076 unsigned udiv;
2077
2078 /* edge case, doesn't work */
2079 if (divisor == 0)
2080 return 0;
2081 if (divisor == (int)(0x80000000))
2082 return 0;
2083 if (!sgnd && divisor < 0)
2084 return 0;
2085 /* cases where divisor == 1 and divisor == 2**N are already handled */
2086
2087 N = 32; /* hopefully, we can determine when 16 bits are enough */
2088
2089 if (sgnd && divisor < 0) {
2090 udiv = -divisor;
2091 } else {
2092 udiv = divisor;
2093 }
2094
2095 if (sgnd) {
2096 choose_multiplier(N, udiv, N - 1);
2097 } else {
2098 choose_multiplier(N, udiv, N);
2099 }
2100
2101 if (sgnd) {
2102 if (cmp64(mrecip, twonm1) < 0) {
2103 /* m < 2**(N-1) */
2104 t1 = ad1ili(IL_IKMV, n);
2105 q0 = MULSH(ad_kcon(mrecip[0], mrecip[1]), t1);
2106 q0 = ad1ili(IL_KIMV, q0);
2107 if (shpost > 0) {
2108 t1 = ICON(shpost); /* SRA */
2109 q0 = ad2ili(IL_ARSHIFT, q0, t1); /* SRA */
2110 }
2111 q3 = XSIGN(n, N);
2112 q = ad2ili(IL_ISUB, q0, q3);
2113 } else {
2114 sub64(mrecip, twon, mrecip);
2115 t1 = ad1ili(IL_IKMV, n);
2116 q0 = MULSH(ad_kcon(mrecip[0], mrecip[1]), t1);
2117 q0 = ad1ili(IL_KIMV, q0);
2118 q0 = ad2ili(IL_IADD, n, q0);
2119 if (shpost > 0) {
2120 t1 = ICON(shpost);
2121 q0 = ad2ili(IL_ARSHIFT, q0, t1); /* SRA */
2122 }
2123 q3 = XSIGN(n, N);
2124 q = ad2ili(IL_ISUB, q0, q3);
2125 }
2126 if (divisor < 0) {
2127 q = ad1ili(IL_INEG, q);
2128 }
2129 } else {
2130 DBLINT64 twol;
2131 int shpre = 0;
2132 DBLINT64 one_64 = {0x0, 0x1};
2133 DBLINT64 divisor64 = {0x0, (int)udiv};
2134 const int l = lg(udiv);
2135
2136 shf64(one_64, l, twol);
2137 if (cmp64(divisor64, twol) == 0) {
2138 /* d == 2**l, where: 'd' is the divisor, 'l' is log2(d) */
2139 return ad2ili(IL_URSHIFT, n, ICON(l)); /* Return n>>l */
2140 }
2141
2142 if (cmp64(mrecip, twon) >= 0) {
2143 /* loop until udiv is odd */
2144 shpre = 0;
2145 while ((udiv & 0x01) == 0) {
2146 ++shpre;
2147 udiv = udiv >> 1;
2148 }
2149 if (shpre) {
2150 choose_multiplier(N, udiv, N - shpre);
2151 }
2152 }
2153 if (cmp64(mrecip, twon) >= 0) {
2154 /* shpre must be zero */
2155 sub64(mrecip, twon, mrecip);
2156 t1 = ad1ili(IL_UIKMV, n);
2157 t1 = MULUH(ad_kcon(mrecip[0], mrecip[1]), t1);
2158 t1 = ad1ili(IL_KIMV, t1);
2159 q0 = ad2ili(IL_ISUB, n, t1);
2160 t2 = ICON(1);
2161 q0 = ad2ili(IL_URSHIFT, q0, t2);
2162 q = ad2ili(IL_UIADD, t1, q0);
2163 if (shpost > 1) {
2164 t1 = ICON(shpost - 1);
2165 q = ad2ili(IL_URSHIFT, q, t1);
2166 }
2167 } else {
2168 q = n;
2169 if (shpre > 0) {
2170 t1 = ICON(shpre);
2171 q = ad2ili(IL_URSHIFT, n, t1);
2172 }
2173 t1 = ad1ili(IL_UIKMV, q);
2174 q = MULUH(ad_kcon(mrecip[0], mrecip[1]), t1);
2175 q = ad1ili(IL_KIMV, q);
2176 if (shpost > 0) {
2177 t1 = ICON(shpost);
2178 q = ad2ili(IL_URSHIFT, q, t1);
2179 }
2180 }
2181 }
2182 return q;
2183 }
2184
2185 static int
reciprocal_division_64(int n,DBLINT64 divisor,int sgnd)2186 reciprocal_division_64(int n, DBLINT64 divisor, int sgnd)
2187 {
2188
2189 /* TBD: 64-bit divides */
2190
2191 int l, mp, sh, N;
2192 int t1, t2, q0, q3, q, recipsym;
2193 /*unsigned udiv;*/
2194 DBLUINT64 udiv;
2195 DBLINT64 tmp_64;
2196 static DBLINT64 zero_64 = {0, 0}, one_64 = {0x0, 0x1};
2197 static DBLINT64 min_neg_64 = {(INT)0x80000000, 0x0};
2198
2199 /* edge case, doesn't work */
2200 if (cmp64(divisor, zero_64) == 0)
2201 return 0;
2202 if (cmp64(divisor, min_neg_64) == 0)
2203 return 0;
2204 if (!sgnd && (cmp64(divisor, zero_64) < 0))
2205 return 0;
2206
2207 /* cases where divisor == 1 and divisor == 2**N are already handled */
2208
2209 N = 64; /* hopefully, we can determine when 16 bits are enough */
2210
2211 if (sgnd && (cmp64(divisor, zero_64) < 0)) {
2212 /*udiv = -divisor; */
2213 neg64(divisor, (INT *)udiv);
2214 } else {
2215 /*udiv = divisor; */
2216 udiv[0] = divisor[0];
2217 udiv[1] = divisor[1];
2218 }
2219 if (sgnd) {
2220 choose_multiplier_64(N, udiv, N - 1);
2221 /*choose_multiplier( N, udiv[1], N-1 ); */
2222 } else {
2223 choose_multiplier_64(N, udiv, N);
2224 /*choose_multiplier( N, udiv[1], N );*/
2225 }
2226
2227 if (sgnd) {
2228 if (cmp128(mrecip_128, twonm1_128) < 0) {
2229 /* m < 2**(N-1) */
2230 q0 = KMULSH(ad_kcon(mrecip_128[2], mrecip_128[3]), n);
2231 if (shpost > 0) {
2232 t1 = ICON(shpost); /* SRA */
2233 q0 = ad2ili(IL_KARSHIFT, q0, t1); /* SRA */
2234 }
2235 q3 = KXSIGN(n, N);
2236 q = ad2ili(IL_KSUB, q0, q3);
2237 } else {
2238 sub128(mrecip_128, twon_128, mrecip_128);
2239 q0 = KMULSH(ad_kcon(mrecip_128[2], mrecip_128[3]), n);
2240 q0 = ad2ili(IL_KADD, n, q0);
2241 if (shpost > 0) {
2242 t1 = ICON(shpost);
2243 q0 = ad2ili(IL_KARSHIFT, q0, t1);
2244 }
2245 q3 = KXSIGN(n, N);
2246 q = ad2ili(IL_KSUB, q0, q3);
2247 }
2248 if (cmp64(divisor, zero_64) < 0) {
2249 q = ad1ili(IL_KNEG, q);
2250 }
2251 } else {
2252 DBLINT64 twol;
2253 int shpre = 0;
2254 const int l = lg64(udiv);
2255
2256 shf64(one_64, l, twol);
2257 if (cmp64(divisor, twol) == 0) {
2258 /* d == 2**l, where: 'd' is the divisor, 'l' is log2(d) */
2259 return ad2ili(IL_KURSHIFT, n, ICON(l)); /* Return n>>l */
2260 }
2261
2262 if (cmp128(mrecip_128, twon_128) >= 0) {
2263 /* loop until udiv is odd */
2264 shpre = 0;
2265 while (and64((INT *)udiv, one_64, tmp_64),
2266 (cmp64(tmp_64, zero_64) == 0)) {
2267 ++shpre;
2268 ushf64(udiv, -1, udiv);
2269 }
2270 if (shpre) {
2271 choose_multiplier_64(N, udiv, N - shpre);
2272 }
2273 }
2274
2275 if (cmp128(mrecip_128, twon_128) >= 0) {
2276 /* shpre must be zero */
2277 sub128(mrecip_128, twon_128, mrecip_128);
2278 t1 = KMULUH(ad_kcon(mrecip_128[2], mrecip_128[3]), n);
2279 q0 = ad2ili(IL_KSUB, n, t1);
2280 t2 = ICON(1);
2281 q0 = ad2ili(IL_KURSHIFT, q0, t2);
2282 q = ad2ili(IL_UKADD, t1, q0);
2283 if (shpost > 1) {
2284 t1 = ICON(shpost - 1);
2285 q = ad2ili(IL_KURSHIFT, q, t1);
2286 }
2287 } else {
2288 q = n;
2289 if (shpre > 0) {
2290 t1 = ICON(shpre);
2291 q = ad2ili(IL_KURSHIFT, n, t1);
2292 }
2293 q = KMULUH(ad_kcon(mrecip_128[2], mrecip_128[3]), q);
2294 if (shpost > 0) {
2295 t1 = ICON(shpost);
2296 q = ad2ili(IL_KURSHIFT, q, t1);
2297 }
2298 }
2299 }
2300 return q;
2301 }
2302
2303 static int
reciprocal_mod(int n,int d,int sgnd)2304 reciprocal_mod(int n, int d, int sgnd)
2305 {
2306 int div;
2307 int mul, sub, t0;
2308
2309 div = reciprocal_division(n, d, sgnd);
2310 if (div == 0)
2311 return 0;
2312
2313 mul = MUL(ICON(d), div);
2314 if (sgnd) {
2315 sub = ad2ili(IL_ISUB, n, mul);
2316 } else {
2317 sub = ad2ili(IL_UISUB, n, mul);
2318 }
2319
2320 return sub;
2321 }
2322
2323 static int
reciprocal_mod_64(int n,DBLINT64 d,int sgnd)2324 reciprocal_mod_64(int n, DBLINT64 d, int sgnd)
2325 {
2326 int div, kcon;
2327 int mul, sub, t0;
2328
2329 /*
2330 * d[0] MSW
2331 * d[1] LSW
2332 */
2333 div = reciprocal_division_64(n, d, sgnd);
2334 if (div == 0)
2335 return 0;
2336
2337 kcon = ad_kcon(d[0], d[1]);
2338 mul = KMUL(kcon, div);
2339 if (sgnd) {
2340 sub = ad2ili(IL_KSUB, n, mul);
2341 } else {
2342 sub = ad2ili(IL_UKSUB, n, mul);
2343 }
2344
2345 return sub;
2346 }
2347
2348 #ifdef __cplusplus
IS_FLT0(int x)2349 inline bool IS_FLT0(int x)
2350 {
2351 return is_flt0(static_cast<SPTR>(x));
2352 }
2353
IS_DBL0(int x)2354 inline bool IS_DBL0(int x)
2355 {
2356 return is_dbl0(static_cast<SPTR>(x));
2357 }
2358 #else
2359 #define IS_FLT0 is_flt0
2360 #define IS_DBL0 is_dbl0
2361 #endif
2362
2363 /**
2364 * \brief adds arithmetic ili
2365 */
2366 static int
addarth(ILI * ilip)2367 addarth(ILI *ilip)
2368 {
2369 ILI newili; /* space for a new ili */
2370
2371 ILI_OP opc, /* opcode of ilip */
2372 opc1, /* opcode operand one */
2373 opc2; /* opcode operand two */
2374 int op1, /* operand one of ilip */
2375 op2; /* operand two of ilip */
2376 SPTR cons1; /* constant ST one */
2377 SPTR cons2; /* constant ST two */
2378 int con1v1, /* constant ST one conval1g */
2379 con1v2, /* constant ST one conval2g */
2380 con2v1, /* constant ST two conval1g */
2381 con2v2; /* constant ST two conval2g */
2382 int ncons, /* number of constants */
2383 /* 0 => no constants */
2384 /* 1 => first operand is */
2385 /* 2 => second operand is */
2386 /* 3 => both are constants */
2387 ilix, /* ili result */
2388 mask_ili, /* for potential mask with vector intrinsics */
2389 rshfct, /* rt. shft. cnt. for shift c.f. */
2390 vdt1, vdt2; /* data types of args 1 & 2 for VPOW[I,K] intrinsics */
2391
2392 ISZ_T aconoff1v, /* constant ST one aconoff */
2393 aconoff2v; /* constant ST two aconoff */
2394
2395 int is_int, pw;
2396
2397 int i, tmp, tmp1; /* temporary */
2398
2399 union { /* constant value structure */
2400 INT numi[2];
2401 UINT numu[2];
2402 DBLE numd;
2403 } res, num1, num2;
2404 CC_RELATION cond;
2405 char *root;
2406 char *fname;
2407 SPTR funcsptr;
2408 MTH_FN mth_fn;
2409
2410 #define GETVAL64(a, b) \
2411 { \
2412 a.numd[0] = CONVAL1G(b); \
2413 a.numd[1] = CONVAL2G(b); \
2414 }
2415 #define GETVALI64(a, b) \
2416 { \
2417 a.numi[0] = CONVAL1G(b); \
2418 a.numi[1] = CONVAL2G(b); \
2419 }
2420
2421 ncons = 0;
2422 opc = ilip->opc;
2423 op1 = ilip->opnd[0];
2424 opc1 = ILI_OPC(op1);
2425 if (IL_TYPE(opc1) == ILTY_CONS) {
2426 aconoff1v = 0;
2427 if (IL_OPRFLAG(opc1, 1) == ILIO_STC) {
2428 ncons = 1;
2429 con1v1 = 0;
2430 con1v2 = ILI_OPND(op1, 1);
2431 cons1 = (SPTR)-2147483647; /* get an error if used */
2432 } else if (IL_OPRFLAG(opc1, 1) == ILIO_SYM) {
2433 ncons = 1;
2434 cons1 = ILI_SymOPND(op1, 1);
2435 con1v1 = CONVAL1G(cons1);
2436 if (opc1 == IL_ACON) {
2437 aconoff1v = ACONOFFG(cons1);
2438 con1v2 = aconoff1v;
2439 } else
2440 con1v2 = CONVAL2G(cons1);
2441 }
2442 }
2443 op2 = 0; /* prevent UMR if op2 is refd and #operands is 1 */
2444 if (ilis[opc].oprs > 1) {
2445 op2 = ilip->opnd[1];
2446 if (IL_ISLINK(opc, 2)) {
2447 opc2 = ILI_OPC(op2);
2448 if (IL_TYPE(opc2) == ILTY_CONS) {
2449 aconoff2v = 0;
2450 if (IL_OPRFLAG(opc2, 1) == ILIO_STC) {
2451 ncons |= 2;
2452 con2v1 = 0;
2453 con2v2 = ILI_OPND(op2, 1);
2454 cons2 = (SPTR)-2147483647; /* get an error if used */
2455 } else if (IL_OPRFLAG(opc2, 1) == ILIO_SYM) {
2456 ncons |= 2;
2457 cons2 = ILI_SymOPND(op2, 1);
2458 con2v1 = CONVAL1G(cons2);
2459 if (opc2 == IL_ACON) {
2460 aconoff2v = ACONOFFG(cons2);
2461 con2v2 = aconoff2v;
2462 } else
2463 con2v2 = CONVAL2G(cons2);
2464 }
2465 }
2466 if (IL_COMM(opc) != 0)
2467 {
2468 if (ncons == 1) {
2469 ncons = 2;
2470 cons2 = cons1;
2471 con2v1 = con1v1;
2472 con2v2 = con1v2;
2473 aconoff2v = aconoff1v;
2474 tmp = op1;
2475 op1 = op2;
2476 op2 = tmp;
2477 opc1 = ILI_OPC(op1);
2478 opc2 = ILI_OPC(op2);
2479 } else if (ncons == 0 && op1 > op2) {
2480 tmp = op1;
2481 op1 = op2;
2482 op2 = tmp;
2483 opc1 = ILI_OPC(op1);
2484 opc2 = ILI_OPC(op2);
2485 }
2486 }
2487 }
2488 }
2489 switch (opc) {
2490 case IL_UITOI:
2491 case IL_ITOUI:
2492 break;
2493 case IL_IR2SP:
2494 break;
2495 case IL_KR2SP:
2496 if (ncons == 1) {
2497 res.numi[1] = con1v2;
2498 goto add_rcon;
2499 }
2500 break;
2501 case IL_KR2DP:
2502 break;
2503 case IL_KR2CS:
2504 break;
2505 case IL_SP2IR:
2506 if (ncons == 1) {
2507 res.numi[1] = con1v2;
2508 goto add_icon;
2509 }
2510 break;
2511 case IL_SP2KR:
2512 if (ncons == 1) {
2513 res.numi[1] = con1v2;
2514 goto add_kcon;
2515 }
2516 break;
2517 case IL_DP2KR:
2518 break;
2519 case IL_CS2KR:
2520 break;
2521
2522 case IL_ISIGN:
2523 if (ncons & 2) {
2524 /* second operand is constant */
2525 ilix = ad1ili(IL_IABS, op1);
2526 if (con2v2 < 0)
2527 ilix = ad1ili(IL_INEG, ilix);
2528 return ilix;
2529 }
2530 break;
2531 case IL_NINT:
2532 /* add constant folding later */
2533 ilix = ad_func(IL_DFRIR, IL_QJSR, MTH_I_NINT, 1, op1);
2534 ilix = ad1altili(opc, op1, ilix);
2535 return ilix;
2536 #ifdef IL_KNINT
2537 case IL_KNINT:
2538 /* add constant folding later */
2539 ilix = ad_func(IL_DFRKR, IL_QJSR, MTH_I_KNINT, 1, op1);
2540 ilix = ad1altili(opc, op1, ilix);
2541 return ilix;
2542 #endif
2543 case IL_IDNINT:
2544 /* add constant folding later */
2545 ilix = ad_func(IL_DFRIR, IL_QJSR, MTH_I_IDNINT, 1, op1);
2546 ilix = ad1altili(opc, op1, ilix);
2547 return ilix;
2548 #ifdef IL_KIDNINT
2549 case IL_KIDNINT:
2550 /* add constant folding later */
2551 ilix = ad_func(IL_DFRKR, IL_QJSR, MTH_I_KIDNINT, 1, op1);
2552 ilix = ad1altili(opc, op1, ilix);
2553 return ilix;
2554 #endif
2555 case IL_IDIM:
2556 case IL_FDIM:
2557 case IL_DDIM:
2558 /* add constant folding later */
2559 break;
2560
2561 case IL_FSQRT:
2562 if (ncons == 1) {
2563 xfsqrt(con1v2, &res.numi[1]);
2564 goto add_rcon;
2565 }
2566 if (!flg.ieee) {
2567 if (XBIT(15, 0x20000000)) {
2568 int zero;
2569 int x0;
2570 /*
2571 * Just use the approximating reciprocal sqrt instruction
2572 * to compute sqrt:
2573 * x0 = rsqrtss(x) & (cmpness(x, 0.0))
2574 * x1 = x*x0;
2575 */
2576 zero = ad1ili(IL_FCON, stb.flt0);
2577 tmp = ad2ili(IL_CMPNEQSS, op1, zero);
2578 x0 = ad1ili(IL_RSQRTSS, op1); /* x0 */
2579 x0 = ad2ili(IL_FAND, x0, tmp);
2580 ilix = ad2ili(IL_FMUL, op1, x0);
2581 return ad2altili(opc, op1, op2, ilix); /* keep sqrt visible */
2582 }
2583 if (do_newton_sqrt()) {
2584 int three;
2585 int mhalf;
2586 int zero;
2587 int x0;
2588 /*
2589 * Newton's appx for sqrt:
2590 * x1 = (3.0*x0 - x*x0**3)/2.0
2591 * or
2592 * x1 = (3.0 - x*x0*x0)*x0*.5
2593 * or
2594 * x1 = (x*x0*x0 - 3.0)*x0*(-.5)
2595 *
2596 * For just sqrt:
2597 * x0 = rsqrtss(x) & (cmpness(x, 0.0))
2598 * A = x*x0
2599 * x1 = (A*x0 - 3.0)*A*(-.5)
2600 */
2601 num1.numi[0] = 0;
2602 num1.numi[1] = 0x40400000;
2603 three = ad1ili(IL_FCON, getcon(num1.numi, DT_FLOAT));
2604 num1.numi[1] = 0xbf000000;
2605 mhalf = ad1ili(IL_FCON, getcon(num1.numi, DT_FLOAT));
2606 zero = ad1ili(IL_FCON, stb.flt0);
2607 tmp = ad2ili(IL_CMPNEQSS, op1, zero);
2608 x0 = ad1ili(IL_RSQRTSS, op1); /* x0 */
2609 x0 = ad2ili(IL_FAND, x0, tmp);
2610 tmp = ad2ili(IL_FMUL, x0, op1);
2611 tmp1 = ad2ili(IL_FMUL, x0, tmp);
2612 tmp1 = ad2ili(IL_FSUB, tmp1, three);
2613 tmp1 = ad2ili(IL_FMUL, tmp1, tmp);
2614 ilix = ad2ili(IL_FMUL, tmp1, mhalf);
2615 return ad2altili(opc, op1, op2, ilix); /* keep sqrt visible */
2616 }
2617 }
2618 break;
2619 case IL_DSQRT:
2620 if (ncons == 1) {
2621 GETVAL64(num1, cons1);
2622 xdsqrt(num1.numd, res.numd);
2623 goto add_dcon;
2624 }
2625 break;
2626
2627 #ifdef IL_FRSQRT
2628 case IL_FRSQRT:
2629 #if !defined(TARGET_LLVM_ARM)
2630 if (XBIT(183, 0x10000)) {
2631 if (ncons == 1) {
2632 xfsqrt(con1v2, &res.numi[1]);
2633 xfdiv(CONVAL2G(stb.flt1), res.numi[1], &res.numi[1]);
2634 goto add_rcon;
2635 }
2636 return _frsqrt(op1);
2637 }
2638 break;
2639 #else
2640 break;
2641 #endif
2642 #endif
2643
2644 case IL_RCPSS:
2645 break;
2646 case IL_RSQRTSS:
2647 break;
2648 case IL_FAND:
2649 break;
2650 case IL_CMPNEQSS:
2651 break;
2652
2653 case IL_INEG:
2654 case IL_UINEG:
2655 if (ncons == 1) {
2656 res.numi[1] = -con1v2;
2657 goto add_icon;
2658 }
2659 if (ILI_OPC(op1) == opc)
2660 return ILI_OPND(op1, 1);
2661 if (ILI_OPC(op1) == IL_ISUB)
2662 return ad2ili(IL_ISUB, ILI_OPND(op1, 2), ILI_OPND(op1, 1));
2663 if (opc == IL_INEG && ILI_OPC(op1) == IL_IMUL) {
2664 ilix = red_negate(op1, IL_INEG, IL_IMUL, IL_IDIV);
2665 if (ilix != op1)
2666 return ilix;
2667 }
2668 break;
2669
2670 case IL_IABS:
2671 if (ncons == 1) {
2672 res.numi[1] = con1v2 > 0 ? con1v2 : -con1v2;
2673 goto add_icon;
2674 }
2675 /* expand iabs as follows:
2676 * t0 = (int)op1 >> 31;
2677 * t1 = op1 ^ t0;
2678 * res = (unsigned)t1 - (unsigned) t0
2679 * NOTE: need to buffer op1 and t0 with CSE (assume postorder traversal
2680 * by scheduler).
2681 */
2682 /* assertion: no need for cse since sched treats multiple uses of
2683 * the same function ili as one call.
2684 */
2685 tmp = ad2ili(IL_ARSHIFT, op1, ad_icon((INT)31));
2686 tmp1 = ad2ili(IL_XOR, op1, tmp);
2687 ilix = ad2ili(IL_UISUB, tmp1, tmp);
2688 return ilix;
2689
2690 case IL_KABS:
2691 if (ncons == 1) {
2692 GETVALI64(num1, cons1);
2693 GETVALI64(num2, stb.k0);
2694 if (cmp64(num1.numi, num2.numi) == -1) {
2695 neg64(num1.numi, res.numi);
2696 goto add_kcon;
2697 }
2698 return op1;
2699 }
2700 tmp = ad2ili(IL_KARSHIFT, op1, ad_icon((INT)63));
2701 tmp1 = ad2ili(IL_KXOR, op1, tmp);
2702 ilix = ad2ili(IL_UKSUB, tmp1, tmp);
2703 return ilix;
2704
2705 case IL_FABS:
2706 if (ncons == 1) {
2707 xfabsv(con1v2, &res.numi[1]);
2708 goto add_rcon;
2709 }
2710 break;
2711
2712 case IL_DABS:
2713 if (ncons == 1) {
2714 GETVAL64(num1, cons1);
2715 xdabsv(num1.numd, res.numd);
2716 goto add_dcon;
2717 }
2718 break;
2719
2720 case IL_KNEG:
2721 case IL_UKNEG:
2722 if (ncons == 1) {
2723 GETVALI64(num1, cons1);
2724 GETVALI64(num2, stb.k0);
2725 sub64(num2.numi, num1.numi, res.numi);
2726 goto add_kcon;
2727 }
2728 if (ILI_OPC(op1) == opc)
2729 return ILI_OPND(op1, 1);
2730 if (ILI_OPC(op1) == IL_KSUB)
2731 return ad2ili(IL_KSUB, ILI_OPND(op1, 2), ILI_OPND(op1, 1));
2732 if (opc == IL_KNEG && ILI_OPC(op1) == IL_KMUL) {
2733 ilix = red_negate(op1, IL_KNEG, IL_KMUL, IL_KDIV);
2734 if (ilix != op1)
2735 return ilix;
2736 }
2737 break;
2738
2739 case IL_FNEG:
2740 if (ncons == 1) {
2741 xfneg(con1v2, &res.numi[1]);
2742 goto add_rcon;
2743 }
2744 if (!flg.ieee && ILI_OPC(op1) == IL_FSUB) {
2745 /* -(a - b) --> b - a */
2746 op2 = ILI_OPND(op1, 1);
2747 op1 = ILI_OPND(op1, 2);
2748 return ad2ili(IL_FSUB, op1, op2);
2749 }
2750 if (ILI_OPC(op1) == IL_FMUL) {
2751 ilix = red_negate(op1, IL_FNEG, IL_FMUL, IL_FDIV);
2752 if (ilix != op1)
2753 return ilix;
2754 }
2755 break;
2756
2757 case IL_SCMPLXCMP:
2758 break;
2759 case IL_DCMPLXCMP:
2760 break;
2761 case IL_SCMPLXCONJG:
2762 if (ncons == 1) {
2763 res.numi[0] = con1v1;
2764 xfneg(con1v2, &res.numi[1]);
2765 return ad1ili(IL_SCMPLXCON, getcon(res.numi, DT_CMPLX));
2766 }
2767 break;
2768 case IL_DCMPLXCONJG:
2769 if (ncons == 1) {
2770 GETVAL64(num2, con1v2);
2771 xdneg(num2.numd, res.numd);
2772 cons2 = getcon(res.numd, DT_DBLE);
2773 res.numi[0] = con1v1;
2774 res.numi[1] = cons2;
2775 return ad1ili(IL_DCMPLXCON, getcon(res.numi, DT_DCMPLX));
2776 }
2777 break;
2778
2779 case IL_SCMPLXNEG:
2780 if (ncons == 1) {
2781 xfneg(con1v1, &res.numi[0]);
2782 xfneg(con1v2, &res.numi[1]);
2783 return ad1ili(IL_SCMPLXCON, getcon(res.numi, DT_CMPLX));
2784 }
2785 if (!flg.ieee && ILI_OPC(op1) == IL_SCMPLXSUB) {
2786 /* -(a - b) --> b - a */
2787 op2 = ILI_OPND(op1, 1);
2788 op1 = ILI_OPND(op1, 2);
2789 return ad2ili(IL_SCMPLXSUB, op1, op2);
2790 }
2791 break;
2792
2793 case IL_DNEG:
2794 if (ncons == 1) {
2795 GETVAL64(num2, cons1);
2796 xdneg(num2.numd, res.numd);
2797 goto add_dcon;
2798 }
2799 if (!flg.ieee && ILI_OPC(op1) == IL_DSUB) {
2800 /* -(a - b) --> b - a */
2801 op2 = ILI_OPND(op1, 1);
2802 op1 = ILI_OPND(op1, 2);
2803 return ad2ili(IL_DSUB, op1, op2);
2804 }
2805 if (ILI_OPC(op1) == IL_DMUL) {
2806 ilix = red_negate(op1, IL_DNEG, IL_DMUL, IL_DDIV);
2807 if (ilix != op1)
2808 return ilix;
2809 }
2810 break;
2811
2812 case IL_DCMPLXNEG:
2813 if (ncons == 1) {
2814 GETVAL64(num1, con1v1);
2815 GETVAL64(num2, con1v2);
2816 xdneg(num1.numd, res.numd);
2817 cons1 = getcon(res.numd, DT_DBLE);
2818 xdneg(num2.numd, res.numd);
2819 cons2 = getcon(res.numd, DT_DBLE);
2820 res.numi[0] = cons1;
2821 res.numi[1] = cons2;
2822 return ad1ili(IL_DCMPLXCON, getcon(res.numi, DT_DCMPLX));
2823 }
2824 if (!flg.ieee && ILI_OPC(op1) == IL_DCMPLXSUB) {
2825 /* -(a - b) --> b - a */
2826 op2 = ILI_OPND(op1, 1);
2827 op1 = ILI_OPND(op1, 2);
2828 return ad2ili(IL_DCMPLXSUB, op1, op2);
2829 }
2830 break;
2831
2832 case IL_FIX:
2833 if (ncons == 1) {
2834 xfix(con1v2, &res.numi[1]);
2835 goto add_icon;
2836 }
2837 break;
2838
2839 case IL_UFIX:
2840 if (ncons == 1) {
2841 xfixu(con1v2, &res.numu[1]);
2842 goto add_icon;
2843 }
2844 break;
2845
2846 case IL_FIXK:
2847 case IL_FIXUK:
2848 if (ncons == 1) {
2849 xfix64(con1v2, res.numi);
2850 goto add_kcon;
2851 }
2852 break;
2853
2854 case IL_DFIX:
2855 if (ncons == 1) {
2856 GETVAL64(num1, cons1);
2857 xdfix(num1.numd, &res.numi[1]);
2858 goto add_icon;
2859 }
2860 break;
2861
2862 case IL_DFIXU:
2863 if (ncons == 1) {
2864 GETVAL64(num1, cons1);
2865 xdfixu(num1.numd, &res.numu[1]);
2866 goto add_icon;
2867 }
2868 break;
2869
2870 case IL_DFIXK:
2871 case IL_DFIXUK:
2872 if (ncons == 1) {
2873 GETVAL64(num1, cons1);
2874 xdfix64(num1.numi, res.numi);
2875 goto add_kcon;
2876 }
2877 break;
2878
2879 case IL_FLOAT:
2880 if (ncons == 1) {
2881 xffloat(con1v2, &res.numi[1]);
2882 goto add_rcon;
2883 }
2884 break;
2885
2886 case IL_FLOATU:
2887 if (ncons == 1) {
2888 xffloatu(con1v2, &res.numi[1]);
2889 goto add_rcon;
2890 }
2891 break;
2892
2893 case IL_FLOATK:
2894 if (ncons == 1) {
2895 GETVALI64(num1, cons1);
2896 xflt64(num1.numi, &res.numi[1]);
2897 goto add_rcon;
2898 }
2899 break;
2900
2901 case IL_FLOATUK:
2902 if (ncons == 1) {
2903 GETVALI64(num1, cons1);
2904 xfltu64(num1.numu, &res.numi[1]);
2905 goto add_rcon;
2906 }
2907 break;
2908
2909 case IL_DFLOATK:
2910 if (ncons == 1) {
2911 GETVALI64(num1, cons1);
2912 xdflt64(num1.numi, res.numi);
2913 goto add_dcon;
2914 }
2915 break;
2916
2917 case IL_DFLOATUK:
2918 if (ncons == 1) {
2919 GETVALI64(num1, cons1);
2920 xdfltu64(num1.numu, res.numi);
2921 goto add_dcon;
2922 }
2923 break;
2924
2925 case IL_DFLOAT:
2926 if (ncons == 1) {
2927 xdfloat(con1v2, res.numd);
2928 goto add_dcon;
2929 }
2930 break;
2931
2932 case IL_DFLOATU:
2933 if (ncons == 1) {
2934 xdfloatu(con1v2, res.numd);
2935 goto add_dcon;
2936 }
2937 break;
2938
2939 case IL_SNGL:
2940 if (ncons == 1) {
2941 GETVAL64(res, cons1);
2942 xsngl(res.numd, &res.numi[1]);
2943 goto add_rcon;
2944 }
2945 break;
2946
2947 case IL_DBLE:
2948 if (ncons == 1) {
2949 xdble(con1v2, res.numd);
2950 goto add_dcon;
2951 }
2952 break;
2953
2954 case IL_UNOT:
2955 case IL_NOT:
2956 if (ncons == 1) {
2957 res.numi[1] = ~con1v2;
2958 goto add_icon;
2959 }
2960 goto involution;
2961 break;
2962
2963 case IL_UKNOT:
2964 case IL_KNOT:
2965 if (ncons == 1) {
2966 res.numi[0] = ~con1v1;
2967 res.numi[1] = ~con1v2;
2968 goto add_kcon;
2969 }
2970 involution:
2971 if ((opc == opc1) && (opc1 == IL_NOT || opc1 == IL_UNOT ||
2972 opc1 == IL_KNOT || opc1 == IL_UKNOT)) {
2973 /* Involution expression: ~~A = A */
2974 return ILI_OPND(op1, 1);
2975 }
2976 break;
2977
2978 case IL_ICMPZ:
2979 if (ncons == 1) {
2980 res.numi[1] = cmp_to_log(icmp(con1v2, (INT)0), op2);
2981 goto add_icon;
2982 }
2983 if (ILI_OPC(op1) == IL_ISUB)
2984 return ad3ili(IL_ICMP, (int)ILI_OPND(op1, 1), (int)ILI_OPND(op1, 2), op2);
2985 break;
2986
2987 case IL_UICMPZ:
2988 if (ncons == 1) {
2989 res.numi[1] = cmp_to_log(xucmp(con1v2, (INT)0), op2);
2990 goto add_icon;
2991 }
2992 switch (op2) {
2993 default:
2994 break;
2995 case CC_LT: /* < 0 becomes false */
2996 if (func_in(op1))
2997 break;
2998 res.numi[1] = 0;
2999 goto add_icon;
3000 case CC_GE: /* >= 0 becomes true */
3001 if (func_in(op1))
3002 break;
3003 res.numi[1] = 1;
3004 goto add_icon;
3005 case CC_LE: /* <= 0 becomes eq */
3006 op2 = CC_EQ;
3007 opc = IL_ICMPZ;
3008 break;
3009 case CC_GT: /* > 0 becomes ne */
3010 op2 = CC_NE;
3011 opc = IL_ICMPZ;
3012 break;
3013 }
3014 break;
3015
3016 case IL_KCMP:
3017 newili.opnd[2] = ilip->opnd[2];
3018 if (ncons == 1 && con1v1 == 0 && con1v2 == 0)
3019 return ad3ili(IL_KCMP, op2, op1, commute_cc(CCRelationILIOpnd(ilip, 2)));
3020 if (ncons == 3) {
3021 GETVALI64(num1, cons1);
3022 GETVALI64(num2, cons2);
3023 res.numi[1] = cmp_to_log(cmp64(num1.numi, num2.numi), ilip->opnd[2]);
3024 goto add_icon;
3025 } else if (op1 == op2 && !func_in(op1)) {
3026 res.numi[1] = cmp_to_log(0, ilip->opnd[2]);
3027 goto add_icon;
3028 }
3029 break;
3030
3031 case IL_UKCMP:
3032 newili.opnd[2] = ilip->opnd[2];
3033 if (ncons == 1 && con1v1 == 0 && con1v2 == 0)
3034 return ad3ili(IL_UKCMP, op2, op1,
3035 commute_cc(CCRelationILIOpnd(ilip, 2)));
3036 if (ncons == 3) {
3037 GETVALI64(num1, cons1);
3038 GETVALI64(num2, cons2);
3039 res.numi[1] = cmp_to_log(ucmp64(num1.numu, num2.numu), ilip->opnd[2]);
3040 goto add_icon;
3041 } else if (op1 == op2 && !func_in(op1)) {
3042 res.numi[1] = cmp_to_log(0, ilip->opnd[2]);
3043 goto add_icon;
3044 }
3045 break;
3046
3047 case IL_KCMPZ:
3048 if (ncons == 1) {
3049 GETVALI64(num1, cons1);
3050 num2.numi[0] = num2.numi[1] = 0;
3051 res.numi[1] = cmp_to_log(cmp64(num1.numi, num2.numi), op2);
3052 goto add_icon;
3053 }
3054 if (ILI_OPC(op1) == IL_KSUB)
3055 return ad3ili(IL_KCMP, (int)ILI_OPND(op1, 1), (int)ILI_OPND(op1, 2), op2);
3056 return ad3ili(IL_KCMP, op1, ad1ili(IL_KCON, stb.k0), op2);
3057
3058 case IL_UKCMPZ:
3059 if (ncons == 1) {
3060 GETVALI64(num1, cons1);
3061 num2.numi[0] = num2.numi[1] = 0;
3062 res.numi[1] = cmp_to_log(ucmp64(num1.numu, num2.numu), op2);
3063 goto add_icon;
3064 }
3065 switch (op2) {
3066 default:
3067 return ad3ili(IL_UKCMP, op1, ad1ili(IL_KCON, stb.k0), op2);
3068 case CC_LT: /* < 0 becomes false */
3069 if (func_in(op1))
3070 break;
3071 res.numi[1] = 0;
3072 goto add_icon;
3073 case CC_GE: /* >= 0 becomes true */
3074 if (func_in(op1))
3075 break;
3076 res.numi[1] = 1;
3077 goto add_icon;
3078 case CC_LE: /* <= 0 becomes eq */
3079 op2 = CC_EQ;
3080 opc = IL_KCMPZ;
3081 break;
3082 case CC_GT: /* > 0 becomes ne */
3083 op2 = CC_NE;
3084 opc = IL_KCMPZ;
3085 break;
3086 }
3087 break;
3088
3089 case IL_FCMPZ:
3090 if (ncons == 1) {
3091 res.numi[1] = cmp_to_log(xfcmp(con1v2, CONVAL2G(stb.flt0)), op2);
3092 goto add_icon;
3093 }
3094 if (!IEEE_CMP && ILI_OPC(op1) == IL_FSUB)
3095 return ad3ili(IL_FCMP, (int)ILI_OPND(op1, 1), (int)ILI_OPND(op1, 2), op2);
3096 #ifndef TM_FCMPZ
3097 tmp = ad1ili(IL_FCON, stb.flt0);
3098 return ad3ili(IL_FCMP, op1, tmp, op2);
3099 #endif
3100 break;
3101
3102 case IL_DCMPZ:
3103 if (ncons == 1) {
3104 GETVAL64(num1, cons1);
3105 GETVAL64(num2, stb.dbl0);
3106 res.numi[1] = cmp_to_log(xdcmp(num1.numd, num2.numd), op2);
3107 goto add_icon;
3108 }
3109 if (!IEEE_CMP && ILI_OPC(op1) == IL_DSUB)
3110 return ad3ili(IL_DCMP, (int)ILI_OPND(op1, 1), (int)ILI_OPND(op1, 2), op2);
3111 if (ILI_OPC(op1) == IL_DBLE && !XBIT(15, 0x80))
3112 return ad2ili(IL_FCMPZ, ILI_OPND(op1, 1), op2);
3113 #ifndef TM_DCMPZ
3114 tmp = ad1ili(IL_DCON, stb.dbl0);
3115 return ad3ili(IL_DCMP, op1, tmp, op2);
3116 #endif
3117 break;
3118
3119 case IL_ACMPZ:
3120 if (ncons == 1) {
3121 int sym;
3122 sym = con1v1;
3123 if (sym == 0) {
3124 res.numi[1] = cmp_to_log(icmp(con1v2, (INT)0), op2);
3125 goto add_icon;
3126 }
3127 /* comparing an address with NULL */
3128 switch (op2) {
3129 case CC_LT:
3130 res.numi[1] = 0;
3131 goto add_icon;
3132 case CC_EQ:
3133 case CC_LE:
3134 if (IS_LCL_OR_DUM(sym) || CCSYMG(sym)) {
3135 res.numi[1] = 0;
3136 goto add_icon;
3137 }
3138 break;
3139 case CC_GE:
3140 res.numi[1] = 1;
3141 goto add_icon;
3142 default:
3143 if (IS_LCL_OR_DUM(sym) || CCSYMG(sym)) {
3144 res.numi[1] = 1;
3145 goto add_icon;
3146 }
3147 break;
3148 }
3149 }
3150 switch (op2) {
3151 default:
3152 break;
3153 case CC_LT: /* < 0 becomes false */
3154 res.numi[1] = 0;
3155 goto add_icon;
3156 case CC_GE: /* >= 0 becomes true */
3157 res.numi[1] = 1;
3158 goto add_icon;
3159 case CC_LE: /* <= 0 becomes eq */
3160 op2 = CC_EQ;
3161 break;
3162 case CC_GT: /* > 0 becomes ne */
3163 op2 = CC_NE;
3164 break;
3165 }
3166 break;
3167
3168 case IL_IMAX:
3169 if (ncons == 3) {
3170 if (con1v2 > con2v2)
3171 return op1;
3172 return op2;
3173 }
3174 return red_minmax(opc, op1, op2);
3175
3176 case IL_IMIN:
3177 if (ncons == 3) {
3178 if (con1v2 < con2v2)
3179 return op1;
3180 return op2;
3181 }
3182 return red_minmax(opc, op1, op2);
3183 case IL_UIMAX:
3184 if (ncons == 3) {
3185 if (xucmp((UINT)con1v2, (UINT)con2v2) > 0)
3186 return op1;
3187 return op2;
3188 }
3189 if (ncons == 1 && cons1 == stb.i0) {
3190 return op2;
3191 }
3192 if (ncons == 2 && cons2 == stb.i0) {
3193 return op1;
3194 }
3195 return red_minmax(opc, op1, op2);
3196 case IL_UIMIN:
3197 if (ncons == 3) {
3198 if (xucmp((UINT)con1v2, (UINT)con2v2) < 0)
3199 return op1;
3200 return op2;
3201 }
3202 if (ncons == 1 && cons1 == stb.i0 && !func_in(op2)) {
3203 return op1;
3204 }
3205 if (ncons == 2 && cons2 == stb.i0 && !func_in(op1)) {
3206 return op2;
3207 }
3208 return red_minmax(opc, op1, op2);
3209 case IL_KMAX:
3210 if (ncons == 3) {
3211 GETVALI64(num1, cons1);
3212 GETVALI64(num2, cons2);
3213 if (cmp64(num1.numi, num2.numi) > 0)
3214 return op1;
3215 return op2;
3216 }
3217 ilix = red_minmax(opc, op1, op2);
3218 return ilix;
3219 case IL_KMIN:
3220 if (ncons == 3) {
3221 GETVALI64(num1, cons1);
3222 GETVALI64(num2, cons2);
3223 if (cmp64(num1.numi, num2.numi) < 0)
3224 return op1;
3225 return op2;
3226 }
3227 ilix = red_minmax(opc, op1, op2);
3228 return ilix;
3229 case IL_UKMAX:
3230 if (ncons == 1 && con1v1 == 0 && con1v2 == 0)
3231 return op2;
3232 else if (ncons == 2 && con2v1 == 0 && con2v2 == 0)
3233 return op1;
3234 else if (ncons == 3) {
3235 GETVALI64(num1, cons1);
3236 GETVALI64(num2, cons2);
3237 if (ucmp64(num1.numu, num2.numu) > 0)
3238 return op1;
3239 return op2;
3240 }
3241 return red_minmax(opc, op1, op2);
3242 case IL_UKMIN:
3243 if (ncons == 1 && con1v1 == 0 && con1v2 == 0 && !func_in(op2))
3244 return op1;
3245 else if (ncons == 2 && con2v1 == 0 && con2v2 == 0 && !func_in(op1))
3246 return op2;
3247 else if (ncons == 3) {
3248 GETVALI64(num1, cons1);
3249 GETVALI64(num2, cons2);
3250 if (ucmp64(num1.numu, num2.numu) < 0)
3251 return op1;
3252 return op2;
3253 }
3254 return red_minmax(opc, op1, op2);
3255 case IL_IADD:
3256 if (ILI_OPC(op2) == IL_INEG)
3257 return ad2ili(IL_ISUB, op1, (int)ILI_OPND(op2, 1));
3258 if (ILI_OPC(op1) == IL_INEG)
3259 return ad2ili(IL_ISUB, op2, (int)ILI_OPND(op1, 1));
3260 goto add_shared;
3261 case IL_UIADD:
3262 if (ILI_OPC(op2) == IL_UINEG)
3263 return ad2ili(IL_UISUB, op1, (int)ILI_OPND(op2, 1));
3264 if (ILI_OPC(op1) == IL_UINEG)
3265 return ad2ili(IL_UISUB, op2, (int)ILI_OPND(op1, 1));
3266 add_shared:
3267 if (ncons == 0)
3268 break;
3269 if ((res.numi[1] = con2v2) == 0)
3270 return op1;
3271 tmp = red_iadd(op1, res.numi[1]);
3272 if (tmp)
3273 return tmp;
3274 if (opc == IL_IADD && (res.numi[1] < 0 && res.numi[1] != 0x80000000))
3275 return ad2ili(IL_ISUB, op1, ad_icon(-res.numi[1]));
3276 break;
3277 case IL_KADD:
3278 if (ILI_OPC(op2) == IL_KNEG)
3279 return ad2ili(IL_KSUB, op1, (int)ILI_OPND(op2, 1));
3280 if (ILI_OPC(op1) == IL_KNEG)
3281 return ad2ili(IL_KSUB, op2, (int)ILI_OPND(op1, 1));
3282 goto kadd_shared;
3283 case IL_UKADD:
3284 if (ILI_OPC(op2) == IL_UKNEG)
3285 return ad2ili(IL_UKSUB, op1, (int)ILI_OPND(op2, 1));
3286 if (ILI_OPC(op1) == IL_UKNEG)
3287 return ad2ili(IL_UKSUB, op2, (int)ILI_OPND(op1, 1));
3288 kadd_shared:
3289 if (ncons == 0) {
3290 break;
3291 }
3292 GETVALI64(res, cons2);
3293 if (res.numi[0] == 0 && res.numi[1] == 0)
3294 return op1;
3295 if (ncons == 3) {
3296 GETVALI64(num1, cons1);
3297 add64(num1.numi, res.numi, res.numi);
3298 goto add_kcon;
3299 }
3300 tmp = red_kadd(op1, res.numi);
3301 if (tmp)
3302 return tmp;
3303 if (opc == IL_KADD && res.numi[0] < 0 &&
3304 !(res.numi[0] == 0x80000000 && res.numi[1] == 0)) {
3305 neg64(res.numi, res.numi);
3306 op2 = ad1ili(IL_KCON, getcon(res.numi, DT_INT8));
3307 return ad2ili(IL_KSUB, op1, op2);
3308 }
3309 break;
3310
3311 case IL_FADD:
3312 if (ncons == 2 && is_flt0(cons2))
3313 return op1;
3314 like_fadd:
3315 if (!flg.ieee && ncons == 3) {
3316 xfadd(con1v2, con2v2, &res.numi[1]);
3317 goto add_rcon;
3318 }
3319 if (ILI_OPC(op1) == IL_FNEG) {
3320 /* -a + b --> b - a */
3321 opc = IL_FSUB;
3322 tmp = op2;
3323 op2 = ILI_OPND(op1, 1);
3324 op1 = tmp;
3325 } else if (ILI_OPC(op2) == IL_FNEG) {
3326 /* a + -b --> a - b */
3327 opc = IL_FSUB;
3328 op2 = ILI_OPND(op2, 1);
3329 }
3330 break;
3331
3332 case IL_DADD:
3333 if (ncons == 2 && is_dbl0(cons2))
3334 return op1;
3335 like_dadd:
3336 if (!flg.ieee && ncons == 3) {
3337 GETVAL64(num1, cons1);
3338 GETVAL64(num2, cons2);
3339 xdadd(num1.numd, num2.numd, res.numd);
3340 goto add_dcon;
3341 }
3342 if (ILI_OPC(op1) == IL_DNEG) {
3343 /* -a + b --> b - a */
3344 opc = IL_DSUB;
3345 tmp = op2;
3346 op2 = ILI_OPND(op1, 1);
3347 op1 = tmp;
3348 } else if (ILI_OPC(op2) == IL_DNEG) {
3349 /* a + -b --> a - b */
3350 opc = IL_DSUB;
3351 op2 = ILI_OPND(op2, 1);
3352 }
3353 break;
3354 case IL_SCMPLXADD:
3355 if (ncons == 2 && IS_FLT0(con2v1) && IS_FLT0(con2v2))
3356 return op1;
3357 like_scmplxadd:
3358 if (!flg.ieee && ncons == 3) {
3359 xfadd(con1v1, con2v1, &res.numi[0]);
3360 xfadd(con1v2, con2v2, &res.numi[1]);
3361 return ad1ili(IL_SCMPLXCON, getcon(res.numi, DT_CMPLX));
3362 }
3363 if (ILI_OPC(op1) == IL_SCMPLXNEG) {
3364 opc = IL_SCMPLXSUB;
3365 tmp = op2;
3366 op2 = ILI_OPND(op1, 1);
3367 op1 = tmp;
3368 } else if (ILI_OPC(op2) == IL_SCMPLXNEG) {
3369 opc = IL_SCMPLXSUB;
3370 op2 = ILI_OPND(op2, 1);
3371 }
3372 break;
3373 case IL_DCMPLXADD:
3374 if (ncons == 2 && IS_DBL0(con2v1) && IS_DBL0(con2v2))
3375 return op1;
3376 like_dcmplxadd:
3377 if (!flg.ieee && ncons == 3) {
3378 GETVAL64(num1, con1v1);
3379 GETVAL64(num2, con2v1)
3380 xdadd(num1.numd, num2.numd, res.numd);
3381 cons1 = getcon(res.numd, DT_DBLE);
3382 GETVAL64(num1, con1v2);
3383 GETVAL64(num2, con2v2);
3384 xdadd(num1.numd, num2.numd, res.numd);
3385 cons2 = getcon(res.numd, DT_DBLE);
3386 res.numi[0] = cons1;
3387 res.numi[1] = cons2;
3388 return ad1ili(IL_DCMPLXCON, getcon(res.numi, DT_DCMPLX));
3389 }
3390 if (ILI_OPC(op1) == IL_DCMPLXNEG) {
3391 opc = IL_DCMPLXSUB;
3392 tmp = op2;
3393 op2 = ILI_OPND(op1, 1);
3394 op1 = tmp;
3395 } else if (ILI_OPC(op2) == IL_DCMPLXNEG) {
3396 opc = IL_DCMPLXSUB;
3397 op2 = ILI_OPND(op2, 1);
3398 }
3399 break;
3400
3401 case IL_AADD:
3402 newili.opnd[2] = ilip->opnd[2]; /* save away scale factor */
3403 #define RED_DAMV (!XBIT(15, 0x100))
3404 if (ncons == 0) {
3405 if (RED_DAMV) {
3406 if (ILI_OPC(op2) == IL_IAMV) {
3407 tmp = red_damv(op1, op2, (int)ilip->opnd[2]);
3408 if (tmp)
3409 return tmp;
3410 } else if (ILI_OPC(op1) == IL_IAMV) {
3411 tmp = red_damv(op2, op1, (int)ilip->opnd[2]);
3412 if (tmp)
3413 return tmp;
3414 } else if (ILI_OPC(op2) == IL_KAMV) {
3415 tmp = red_damv(op1, op2, (int)ilip->opnd[2]);
3416 if (tmp)
3417 return tmp;
3418 } else if (ILI_OPC(op1) == IL_KAMV) {
3419 tmp = red_damv(op2, op1, (int)ilip->opnd[2]);
3420 if (tmp)
3421 return tmp;
3422 }
3423 }
3424 break;
3425 }
3426 if (ncons == 1) { /* only the left operand is a constant */
3427 if (ilip->opnd[2] == 0 && con1v1 == 0 && con1v2 == 0)
3428 return op2;
3429 break;
3430 }
3431 like_aadd: {
3432 SPTR sptr_con2v1;
3433 if (con2v1 == 0 && aconoff2v == 0)
3434 return op1;
3435 sptr_con2v1 = (SPTR)con2v1;
3436 tmp = red_aadd(op1, sptr_con2v1, aconoff2v, ilip->opnd[2]);
3437 if (tmp)
3438 return tmp;
3439 } break;
3440
3441 case IL_ISUB:
3442 if (ILI_OPC(op2) == IL_INEG)
3443 return ad2ili(IL_IADD, op1, ILI_OPND(op2, 1));
3444 goto sub_shared;
3445 case IL_UISUB:
3446 if (ILI_OPC(op2) == IL_UINEG)
3447 return ad2ili(IL_UIADD, op1, ILI_OPND(op2, 1));
3448 sub_shared:
3449 if (op1 == op2) {
3450 if (func_in(op1))
3451 break;
3452 res.numi[1] = 0;
3453 goto add_icon;
3454 }
3455 if (ncons == 0)
3456 break;
3457 if (ncons == 1) {
3458 if (cons1 == stb.i0)
3459 return ad1ili(IL_INEG, op2);
3460 break;
3461 }
3462 if ((res.numi[1] = con2v2) == 0)
3463 return op1;
3464 if (res.numi[1] == 0x80000000)
3465 break;
3466 tmp = red_iadd(op1, -res.numi[1]);
3467 if (tmp)
3468 return tmp;
3469 if ((opc == IL_ISUB) && (res.numi[1] < 0))
3470 return ad2ili(IL_IADD, op1, ad_icon(-res.numi[1]));
3471 break;
3472
3473 case IL_KSUB:
3474 if (ILI_OPC(op2) == IL_KNEG)
3475 return ad2ili(IL_KADD, op1, (int)ILI_OPND(op2, 1));
3476 goto ksub_shared;
3477 case IL_UKSUB:
3478 if (ILI_OPC(op2) == IL_UKNEG)
3479 return ad2ili(IL_UKADD, op1, (int)ILI_OPND(op2, 1));
3480 ksub_shared:
3481 if (op1 == op2) {
3482 if (func_in(op1))
3483 break;
3484 GETVALI64(res, stb.k0);
3485 goto add_kcon;
3486 }
3487 if (ncons == 0) {
3488 break;
3489 }
3490 if (ncons == 1) {
3491 if (cons1 == stb.k0)
3492 return ad1ili(IL_KNEG, op2);
3493 break;
3494 }
3495 if (cons2 == stb.k0)
3496 return op1;
3497 GETVALI64(res, cons2);
3498 if (res.numi[0] == 0x80000000 && res.numi[1] == 0) {
3499 break;
3500 }
3501 neg64(res.numi, num2.numi);
3502 tmp = red_kadd(op1, num2.numi);
3503 if (tmp)
3504 return tmp;
3505 if (ncons == 3) {
3506 GETVALI64(num1, cons1);
3507 GETVALI64(num2, cons2);
3508 sub64(num1.numi, num2.numi, res.numi);
3509 goto add_kcon;
3510 }
3511 if (res.numi[0] < 0) {
3512 neg64(res.numi, res.numi);
3513 op2 = ad1ili(IL_KCON, getcon(res.numi, DT_INT8));
3514 return ad2ili(IL_KADD, op1, op2);
3515 }
3516 break;
3517
3518 case IL_FSUB:
3519 #ifdef FPSUB2ADD
3520 if (!flg.ieee && ncons >= 2) {
3521 xfsub((INT)0, con2v2, &res.numi[1]);
3522 res.numi[0] = 0;
3523 cons2 = getcon(res.numi, DT_FLOAT);
3524 op2 = ad1ili(IL_FCON, cons2);
3525 opc = IL_FADD;
3526 goto like_fadd;
3527 }
3528 #else
3529 if (!flg.ieee && ncons == 3) {
3530 xfsub(con1v2, con2v2, &res.numi[1]);
3531 goto add_rcon;
3532 }
3533 if (ncons == 2 && is_flt0(cons2))
3534 return op1;
3535 #endif
3536 if (ncons == 1 && is_flt0(cons1))
3537 return ad1ili(IL_FNEG, op2);
3538 if (ILI_OPC(op2) == IL_FNEG) {
3539 /* a - -b --> a + b */
3540 opc = IL_FADD;
3541 op2 = ILI_OPND(op2, 1);
3542 }
3543 break;
3544
3545 case IL_DSUB:
3546 #ifdef FPSUB2ADD
3547 if (!flg.ieee && ncons >= 2) {
3548 GETVAL64(num1, stb.dbl0);
3549 GETVAL64(num2, cons2);
3550 xdsub(num1.numd, num2.numd, res.numd);
3551 cons2 = getcon(res.numi, DT_DBLE);
3552 op2 = ad1ili(IL_DCON, cons2);
3553 opc = IL_DADD;
3554 goto like_dadd;
3555 }
3556 #else
3557 if (!flg.ieee && ncons == 3) {
3558 GETVAL64(num1, cons1);
3559 GETVAL64(num2, cons2);
3560 xdsub(num1.numd, num2.numd, res.numd);
3561 goto add_dcon;
3562 }
3563 if (ncons == 2 && is_dbl0(cons2))
3564 return op1;
3565 #endif
3566 if (ncons == 1 && is_dbl0(cons1))
3567 return ad1ili(IL_DNEG, op2);
3568 if (ILI_OPC(op2) == IL_DNEG) {
3569 /* a - -b --> a + b */
3570 opc = IL_DADD;
3571 op2 = ILI_OPND(op2, 1);
3572 }
3573 break;
3574 case IL_SCMPLXSUB:
3575 #ifdef FPSUB2ADD
3576 if (!flg.ieee && ncons >= 2) {
3577 xfsub(0, con2v1, &res.numi[0]);
3578 xfsub(0, con2v2, &res.numi[1]);
3579 op2 = ad1ili(IL_SCMPLXCON, getcon(res.numi, DT_CMPLX));
3580 opc = IL_SCMPLXADD;
3581 goto like_scmplxadd;
3582 }
3583 #else
3584 if (!flg.ieee && ncons == 3) {
3585 xfsub(con1v1, con2v1, &res.numi[0]);
3586 xfsub(con1v2, con2v2, &res.numi[1]);
3587 op2 = ad1ili(IL_SCMPLXCON, getcon(res.numi, DT_CMPLX));
3588 return op2;
3589 }
3590 if (ncons == 2 && IS_FLT0(con2v1) && IS_FLT0(con2v2))
3591 return op1;
3592 #endif
3593 if (ncons == 1 && IS_FLT0(con1v1) && IS_FLT0(con1v2))
3594 return ad1ili(IL_SCMPLXNEG, op2);
3595 if (ILI_OPC(op2) == IL_SCMPLXNEG) {
3596 opc = IL_SCMPLXADD;
3597 op2 = ILI_OPND(op2, 1);
3598 }
3599 break;
3600 case IL_DCMPLXSUB:
3601 #ifdef FPSUB2ADD
3602 if (!flg.ieee && ncons >= 2) {
3603 GETVAL64(num1, stb.dbl0);
3604 GETVAL64(num2, con2v1);
3605 xdsub(num1.numd, num2.numd, res.numd);
3606 cons1 = getcon(res.numi, DT_DBLE);
3607 GETVAL64(num1, stb.dbl0);
3608 GETVAL64(num2, con2v2);
3609 xdsub(num1.numd, num2.numd, res.numd);
3610 cons2 = getcon(res.numi, DT_DBLE);
3611 res.numi[0] = cons1;
3612 res.numi[1] = cons2;
3613 op2 = ad1ili(IL_DCMPLXCON, getcon(res.numi, DT_DCMPLX));
3614 opc = IL_DCMPLXADD;
3615 goto like_dcmplxadd;
3616 }
3617 #else
3618 if (!flg.ieee && ncons == 3) {
3619 GETVAL64(num1, con1v1);
3620 GETVAL64(num2, con2v1);
3621 xdsub(num1.numd, num2.numd, res.numd);
3622 cons1 = getcon(res.numd, DT_DBLE);
3623 GETVAL64(num1, con1v2);
3624 GETVAL64(num2, con2v2);
3625 xdsub(num1.numd, num2.numd, res.numd);
3626 cons2 = getcon(res.numd, DT_DBLE);
3627 res.numi[0] = cons1;
3628 res.numi[1] = cons2;
3629 op2 = ad1ili(IL_DCMPLXCON, getcon(res.numi, DT_DCMPLX));
3630 return op2;
3631 }
3632 if (ncons == 2 && IS_DBL0(con2v1) && IS_DBL0(con2v2))
3633 return op1;
3634 #endif
3635 if (ncons == 1 && IS_DBL0(con1v1) && IS_DBL0(con1v2))
3636 return ad1ili(IL_DCMPLXNEG, op2);
3637 if (ILI_OPC(op2) == IL_DCMPLXNEG) {
3638 opc = IL_DCMPLXADD;
3639 op2 = ILI_OPND(op2, 1);
3640 }
3641 break;
3642
3643 case IL_ASUB:
3644 /* (p + <x>) - p -> <x> */
3645 if (ilip->opnd[2] == 0 && ILI_OPC(op1) == IL_AADD &&
3646 ILI_OPND(op1, 3) == 0) {
3647 if (op2 == ILI_OPND(op1, 1) && !func_in(op2))
3648 return ILI_OPND(op1, 2);
3649 }
3650 newili.opnd[2] = ilip->opnd[2];
3651 if (ncons >= 2 && con2v1 == 0) {
3652 con2v1 = SPTR_NULL;
3653 aconoff2v = -aconoff2v;
3654 cons2 = get_acon(SPTR_NULL, aconoff2v);
3655 op2 = ad1ili(IL_ACON, cons2);
3656 opc = IL_AADD;
3657 goto like_aadd;
3658 }
3659 break;
3660
3661 case IL_IMUL:
3662 case IL_UIMUL:
3663 if (ncons == 2) {
3664 if (cons2 == stb.i0 && !func_in(op1))
3665 return op2;
3666 if (cons2 == stb.i1)
3667 return op1;
3668 if (ILI_OPC(op1) == opc && ILI_OPC(ilix = ILI_OPND(op1, 2)) == IL_ICON) {
3669 /* (i * c1) * c2 ---> i * (c1*c2) */
3670 res.numi[0] = con2v2 * CONVAL2G(ILI_OPND(ilix, 1));
3671 op2 = ad_icon(res.numi[0]);
3672 ilix = ad2ili(opc, (int)ILI_OPND(op1, 1), op2);
3673 return ilix;
3674 }
3675 if (ILI_OPC(op1) == IL_INEG || ILI_OPC(op1) == IL_UINEG) {
3676 /* (-i) * c ---> i * (-c) */
3677 res.numi[0] = -con2v2;
3678 op2 = ad_icon(res.numi[0]);
3679 ilix = ad2ili(opc, (int)ILI_OPND(op1, 1), op2);
3680 return ilix;
3681 }
3682 if (opc == IL_IMUL && con2v2 == -1)
3683 return ad1ili(IL_INEG, op1);
3684 } else if (ncons == 3) {
3685 res.numi[1] = con1v2 * con2v2;
3686 goto add_icon;
3687 }
3688 break;
3689
3690 case IL_KMUL:
3691 case IL_UKMUL:
3692 if (ncons == 2) {
3693 if (cons2 == stb.k0 && !func_in(op1))
3694 return op2;
3695 if (cons2 == stb.k1)
3696 return op1;
3697 if (con2v1 == 0 && con2v2 == 2)
3698 /* assertion: no need for cse since sched treats multiple uses of
3699 * the same function ili as one call.
3700 */
3701 return ad2ili(IL_KADD, op1, op1);
3702 if (ILI_OPC(op1) == opc && ILI_OPC(ilix = ILI_OPND(op1, 2)) == IL_KCON) {
3703 /* (i * c1) * c2 ---> i * (c1*c2) */
3704 GETVALI64(num1, ILI_OPND(ilix, 1));
3705 GETVALI64(num2, cons2);
3706 if (opc == IL_KMUL)
3707 mul64(num1.numi, num2.numi, res.numi);
3708 else
3709 umul64(num1.numu, num2.numu, res.numu);
3710 op2 = ad1ili(IL_KCON, getcon(res.numi, DT_INT8));
3711 ilix = ad2ili(opc, (int)ILI_OPND(op1, 1), op2);
3712 return ilix;
3713 }
3714 if (ILI_OPC(op1) == IL_KNEG || ILI_OPC(op1) == IL_UKNEG) {
3715 /* (-i) * c ---> i * (-c) */
3716 GETVALI64(num2, cons2);
3717 neg64(num2.numi, res.numi);
3718 op2 = ad1ili(IL_KCON, getcon(res.numi, DT_INT8));
3719 ilix = ad2ili(opc, (int)ILI_OPND(op1, 1), op2);
3720 return ilix;
3721 }
3722 if (opc == IL_KMUL && con2v1 == -1 && con2v2 == 0xffffffff)
3723 return ad1ili(IL_KNEG, op1);
3724 } else if (ncons == 3) {
3725 GETVALI64(num1, cons1);
3726 GETVALI64(num2, cons2);
3727 if (opc == IL_KMUL)
3728 mul64(num1.numi, num2.numi, res.numi);
3729 else
3730 umul64(num1.numu, num2.numu, res.numu);
3731 goto add_kcon;
3732 }
3733 /* KMUL KNEG x, y --> KNEG KMUL x,y */
3734 if (ILI_OPC(op1) == IL_KNEG && ILI_OPC(op2) == IL_KNEG) {
3735 op1 = ILI_OPND(op1, 1);
3736 op2 = ILI_OPND(op2, 1);
3737 break;
3738 }
3739 if (ILI_OPC(op1) == IL_KNEG) {
3740 return ad1ili(IL_KNEG, ad2ili(IL_KMUL, ILI_OPND(op1, 1), op2));
3741 }
3742 if (ILI_OPC(op2) == IL_KNEG) {
3743 return ad1ili(IL_KNEG, ad2ili(IL_KMUL, op1, ILI_OPND(op2, 1)));
3744 }
3745 break;
3746
3747 case IL_FMUL:
3748 if (!flg.ieee) {
3749 if (ncons == 2) {
3750 if (is_flt0(cons2) && !func_in(op1))
3751 return op2;
3752 if (cons2 == stb.flt1)
3753 return op1;
3754 if (cons2 == stb.flt2) {
3755 /* assertion: no need for cse since sched treats multiple uses
3756 * of the same function ili as one call.
3757 */
3758 return ad2ili(IL_FADD, op1, op1);
3759 }
3760 } else if (ncons == 3) {
3761 xfmul(con1v2, con2v2, &res.numi[1]);
3762 /* don't constant fold if error occurred */
3763 if (gbl.fperror_status)
3764 break;
3765 goto add_rcon;
3766 }
3767 }
3768 /* FMUL FNEG x, FNEG y --> FMUL x,y */
3769 if (ILI_OPC(op1) == IL_FNEG && ILI_OPC(op2) == IL_FNEG) {
3770 op1 = ILI_OPND(op1, 1);
3771 op2 = ILI_OPND(op2, 1);
3772 break;
3773 }
3774 /* FMUL FNEG x, y --> FNEG FMUL x,y */
3775 if (ILI_OPC(op1) == IL_FNEG) {
3776 return ad1ili(IL_FNEG, ad2ili(IL_FMUL, ILI_OPND(op1, 1), op2));
3777 }
3778 /* FMUL x, FNEG y --> FNEG FMUL x,y */
3779 if (ILI_OPC(op2) == IL_FNEG) {
3780 return ad1ili(IL_FNEG, ad2ili(IL_FMUL, op1, ILI_OPND(op2, 1)));
3781 }
3782 break;
3783
3784 case IL_DMUL:
3785 if (!flg.ieee) {
3786 if (ncons == 2) {
3787 if (is_dbl0(cons2) && !func_in(op1))
3788 return op2;
3789 if (cons2 == stb.dbl1)
3790 return op1;
3791 if (cons2 == stb.dbl2) {
3792 /* assertion: no need for cse since sched treats multiple uses
3793 * of the same function ili as one call.
3794 */
3795 return ad2ili(IL_DADD, op1, op1);
3796 }
3797 } else if (ncons == 3) {
3798 GETVAL64(num1, cons1);
3799 GETVAL64(num2, cons2);
3800 xdmul(num1.numd, num2.numd, res.numd);
3801 /* don't constant fold if error occurred */
3802 if (gbl.fperror_status)
3803 break;
3804 goto add_dcon;
3805 }
3806 }
3807 /* DMUL DNEG x, y --> DNEG DMUL x,y */
3808 if (ILI_OPC(op1) == IL_DNEG && ILI_OPC(op2) == IL_DNEG) {
3809 op1 = ILI_OPND(op1, 1);
3810 op2 = ILI_OPND(op2, 1);
3811 break;
3812 }
3813 if (ILI_OPC(op1) == IL_DNEG) {
3814 return ad1ili(IL_DNEG, ad2ili(IL_DMUL, ILI_OPND(op1, 1), op2));
3815 }
3816 if (ILI_OPC(op2) == IL_DNEG) {
3817 return ad1ili(IL_DNEG, ad2ili(IL_DMUL, op1, ILI_OPND(op2, 1)));
3818 }
3819 break;
3820 case IL_SCMPLXMUL:
3821 if (ncons == 1 && IS_FLT0(con1v1) && IS_FLT0(con1v2) && !func_in(op2))
3822 return op1;
3823 if (ncons == 2 && IS_FLT0(con2v1) && IS_FLT0(con2v2) && !func_in(op1))
3824 return op2;
3825 else if (ncons == 3) { /* should be done by front end already */
3826 if (IS_FLT0(con1v1) && IS_FLT0(con1v2))
3827 return op1;
3828 if (IS_FLT0(con2v1) && IS_FLT0(con2v2))
3829 return op2;
3830 } else {
3831 op1 = ilip->opnd[0];
3832 op2 = ilip->opnd[1];
3833 if (ILI_OPC(op1) == IL_SPSP2SCMPLXI0 &&
3834 ILI_OPC(op2) == IL_SPSP2SCMPLXI0) {
3835 int ilir;
3836 ilir = ad2ili(IL_FMUL, ILI_OPND(op1, 1), ILI_OPND(op2, 1));
3837 return ad1ili(IL_SPSP2SCMPLXI0, ilir);
3838 }
3839 }
3840 break;
3841 case IL_DCMPLXMUL:
3842 /* check if any is of complex is 0 then 0*/
3843 if (ncons == 1 && IS_DBL0(con1v1) && IS_DBL0(con1v2) && !func_in(op2))
3844 return op1;
3845 else if (ncons == 2 && IS_DBL0(con2v1) && IS_DBL0(con2v2) && !func_in(op1))
3846 return op2;
3847 else if (ncons == 3) { /* should be done by front end already */
3848 if (IS_DBL0(con1v1) && IS_DBL0(con1v2))
3849 return op1;
3850 if (IS_DBL0(con2v1) && IS_DBL0(con2v2))
3851 return op2;
3852 } else {
3853 op1 = ilip->opnd[0];
3854 op2 = ilip->opnd[1];
3855 if (ILI_OPC(op1) == IL_DPDP2DCMPLXI0 &&
3856 ILI_OPC(op2) == IL_DPDP2DCMPLXI0) {
3857 int ilir;
3858 ilir = ad2ili(IL_DMUL, ILI_OPND(op1, 1), ILI_OPND(op2, 1));
3859 return ad1ili(IL_DPDP2DCMPLXI0, ilir);
3860 }
3861 }
3862
3863 break;
3864
3865 case IL_FSINCOS:
3866 case IL_DSINCOS:
3867 case IL_FNSIN:
3868 case IL_FNCOS:
3869 case IL_DNSIN:
3870 case IL_DNCOS:
3871 break;
3872 case IL_QUOREM:
3873 case IL_NIDIV:
3874 case IL_NUIDIV:
3875 case IL_NMOD:
3876 case IL_NUIMOD:
3877 break;
3878 case IL_KQUOREM:
3879 case IL_NKDIV:
3880 case IL_NUKDIV:
3881 case IL_NKMOD:
3882 case IL_NUKMOD:
3883 break;
3884 case IL_IDIV:
3885 if (ncons == 3 && con2v2 != 0) {
3886 if (con1v2 == 0x80000000 && con2v2 == -1)
3887 res.numi[1] = 0x80000000;
3888 else
3889 res.numi[1] = con1v2 / con2v2;
3890 goto add_icon;
3891 }
3892 if (ncons == 2) {
3893 if (cons2 == stb.i1)
3894 return op1;
3895 if (ILI_OPC(op1) == IL_IMUL && ILI_OPND(op1, 2) == op2)
3896 return ILI_OPND(op1, 1);
3897 if ((res.numi[0] = con2v2) == -1)
3898 return ad1ili(IL_INEG, op1);
3899 if (res.numi[0] > 0) {
3900 /*
3901 * dividing by a constant which may be a power of 2.
3902 * if it is, call a different routine which is faster than
3903 * the ordinary divide. The possible powers are 2 thru 30.
3904 */
3905 i = _pwr2(res.numi[0], 30);
3906 if (i) {
3907 #ifndef TM_IDIV2
3908 /* expand idiv2 as follows:
3909 * t0 = (int)op1 >> (n - 1)
3910 * t0 = (unsigned)t0 >> (32 - n)
3911 * t0 = t0 + op1
3912 * res = (int)t0 >> n
3913 * NOTE: need to buffer op1 with cse -- assumes
3914 * postorder traversal by scheduler. Consequently,
3915 * if op1 is a INEG the scheduler will see a
3916 * cse of op1 before it sees op1 ('t0 + -i' is
3917 * transformed into 't0 - i'). Although this is
3918 * not harmful under the current sched scheme,
3919 * handle INEG so that that an internal error
3920 * message is not issued.
3921 */
3922 if (ILI_OPC(op1) == IL_INEG) {
3923 tmp = ad2ili(IL_ARSHIFT, op1, ad_icon((INT)(i - 1)));
3924 tmp = ad2ili(IL_URSHIFT, tmp, ad_icon((INT)(32 - i)));
3925 tmp = ad2ili(IL_ISUB, tmp, (int)ILI_OPND(op1, 1));
3926 } else {
3927 /* assertion: no need for cse since sched treats
3928 * multiple uses of the same function ili as one call.
3929 */
3930 tmp = ad2ili(IL_ARSHIFT, op1, ad_icon((INT)(i - 1)));
3931 tmp = ad2ili(IL_URSHIFT, tmp, ad_icon((INT)(32 - i)));
3932 tmp = ad2ili(IL_IADD, op1, tmp);
3933 }
3934 ilix = ad2ili(IL_ARSHIFT, tmp, ad_icon((INT)i));
3935 return ad2altili(opc, op1, op2, ilix);
3936
3937 #else /* defined(TM_IDIV2) */
3938 ilix = ad2ili(IL_IDIV2, op1, i);
3939 return ad2altili(opc, op1, op2, ilix);
3940 #endif /* #ifndef TM_IDIV2 */
3941 }
3942 }
3943 if (!XBIT(87, 0x1) && !XBIT(6, 0x400)) {
3944 ilix = reciprocal_division(op1, res.numi[0], 1);
3945 if (ilix)
3946 return ad2altili(opc, op1, op2, ilix);
3947 }
3948 }
3949 #ifndef TM_IDIV
3950 /* divide-by-constant is handled by reciprocal division */
3951 #ifdef ALT_I_IDIV
3952 if (XBIT(122, 0x80))
3953 ilix = ad2func_int(IL_QJSR, ALT_I_IDIV, op1, op2);
3954 else
3955 #endif
3956 ilix = ad2func_int(IL_QJSR, MTH_I_IDIV, op1, op2);
3957 return ilix;
3958 #endif
3959
3960 #ifdef TM_IDIV
3961 break;
3962 #endif
3963
3964 case IL_IDIVZR:
3965 if (ncons == 2) {
3966 if (cons2 == stb.i1)
3967 return op1;
3968 if (ILI_OPC(op1) == IL_IMUL && ILI_OPND(op1, 2) == op2)
3969 return ILI_OPND(op1, 1);
3970 if (con2v2 > 0) {
3971 /*
3972 * dividing by a constant which may be a power of 2.
3973 * if it is, call a different routine which is faster than
3974 * the ordinary divide. The possible powers are 2 thru 30.
3975 */
3976 i = _pwr2(con2v2, 30);
3977 if (i) {
3978 /* expand idiv2 as
3979 * res = (int)t0 >> n
3980 */
3981 ilix = ad2ili(IL_ARSHIFT, op1, ad_icon((INT)i));
3982 return ilix;
3983 }
3984 }
3985 }
3986 ilix = ad2ili(IL_IDIV, op1, op2);
3987 return ilix;
3988
3989 #ifdef TM_IDIV2
3990 case IL_IDIV2:
3991 break;
3992 #endif
3993
3994 case IL_UIDIV:
3995 if (ncons == 3 && con2v2 != 0) {
3996 tmp = xudiv(con1v2, con2v2, &res.numu[0]);
3997 return ad_icon((INT)res.numu[0]);
3998 }
3999 if (ncons == 2) {
4000 if (cons2 == stb.i1)
4001 return op1;
4002 res.numi[0] = con2v2;
4003 /*
4004 * dividing by a constant which may be a power of 2. if
4005 * it is, call a different routine which is faster than the
4006 * ordinary divide. The possible powers are 2 through 31.
4007 */
4008 i = _pwr2(res.numi[0], 31);
4009 if (i) {
4010 ilix = ad2ili(IL_URSHIFT, op1, ad_icon((INT)i));
4011 return ilix;
4012 }
4013 if (!XBIT(87, 0x1) && !XBIT(6, 0x400)) {
4014 ilix = reciprocal_division(op1, res.numi[0], 0);
4015 if (ilix)
4016 return ad2altili(opc, op1, op2, ilix);
4017 }
4018 }
4019 /*
4020 * if the divisor is shifting 1 left, then replace the divide
4021 * with an unsigned right shift.
4022 */
4023 ilix = _lshift_one(op2);
4024 if (ilix)
4025 return ad2ili(IL_URSHIFT, op1, ilix);
4026
4027 #ifdef TM_UIDIV
4028 break;
4029 #else /* #ifndef TM_UIDIV */
4030 #ifdef ALT_I_UIDIV
4031 if (XBIT(122, 0x80))
4032 ilix = ad2func_int(IL_QJSR, ALT_I_UIDIV, op1, op2);
4033 else
4034 #endif
4035 ilix = ad2func_int(IL_QJSR, MTH_I_UIDIV, op1, op2);
4036 return ilix;
4037 #endif
4038
4039 case IL_KDIV:
4040 if (ncons == 3 && cons2 != stb.k0) {
4041 GETVALI64(num1, cons1);
4042 GETVALI64(num2, cons2);
4043 div64(num1.numi, num2.numi, res.numi);
4044 goto add_kcon;
4045 }
4046 if (ncons == 2) {
4047 if (cons2 == stb.k1 || (con2v1 == 0 && con2v2 == 1))
4048 return op1;
4049 if (ILI_OPC(op1) == IL_KMUL && ILI_OPND(op1, 2) == op2)
4050 return ILI_OPND(op1, 1);
4051 if (con2v1 == -1 && con2v2 == 0xffffffff)
4052 return ad1ili(IL_KNEG, op1);
4053 if (con2v1 >= 0) {
4054 /*
4055 * dividing by a constant which may be a power of 2.
4056 * if it is, call a different routine which is faster than
4057 * the ordinary divide. The possible powers are 2 thru 62.
4058 */
4059 i = _kpwr2(con2v1, con2v2, 62);
4060 if (i) {
4061 /* expand kdiv2 as follows:
4062 * t0 = op1 >> (n - 1)
4063 * t0 = (unsigned)t0 >> (64 - n)
4064 * t0 = t0 + op1
4065 * res = t0 >> n
4066 */
4067 if (ILI_OPC(op1) == IL_KNEG) {
4068 tmp = ad2ili(IL_KARSHIFT, op1, ad_icon((INT)(i - 1)));
4069 tmp = ad2ili(IL_KURSHIFT, tmp, ad_icon((INT)(64 - i)));
4070 tmp = ad2ili(IL_KSUB, tmp, (int)ILI_OPND(op1, 1));
4071 } else {
4072 /* assertion: no need for cse since sched treats
4073 * multiple uses of the same function ili as one call.
4074 */
4075 tmp = ad2ili(IL_KARSHIFT, op1, ad_icon((INT)(i - 1)));
4076 tmp = ad2ili(IL_KURSHIFT, tmp, ad_icon((INT)(64 - i)));
4077 tmp = ad2ili(IL_KADD, op1, tmp);
4078 }
4079 ilix = ad2ili(IL_KARSHIFT, tmp, ad_icon((INT)i));
4080 return ad2altili(opc, op1, op2, ilix);
4081 }
4082 }
4083
4084 if (!XBIT(87, 0x1) && !XBIT(6, 0x400)) {
4085 res.numi[0] = con2v1;
4086 res.numi[1] = con2v2;
4087 ilix = reciprocal_division_64(op1, res.numi, 1);
4088 if (ilix)
4089 return ad2altili(opc, op1, op2, ilix);
4090 }
4091 }
4092 break;
4093
4094 case IL_KDIVZR:
4095 /*
4096 * 64-bit signed integer divide when it's known that the remainder
4097 * is zero, such as the divide performed for a pointer subtract.
4098 */
4099 if (ncons == 2) {
4100 if (cons2 == stb.k1)
4101 return op1;
4102 if (ILI_OPC(op1) == IL_KMUL && ILI_OPND(op1, 2) == op2)
4103 return ILI_OPND(op1, 1);
4104 if (con2v1 >= 0) {
4105 /*
4106 * dividing by a constant which may be a power of 2.
4107 * if it is just shift the dividend. The possible powers
4108 * are 2 thru 62.
4109 */
4110 i = _kpwr2(con2v1, con2v2, 62);
4111 if (i) {
4112 /* expand as
4113 * res = op1 >> n
4114 */
4115 ilix = ad2ili(IL_KARSHIFT, op1, ad_icon((INT)i));
4116 return ilix;
4117 }
4118 }
4119 }
4120 ilix = ad2ili(IL_KDIV, op1, op2);
4121 return ilix;
4122
4123 case IL_UKDIV:
4124 if (ncons == 3 && cons2 != stb.k0) {
4125 GETVALI64(num1, cons1);
4126 GETVALI64(num2, cons2);
4127 udiv64(num1.numu, num2.numu, res.numu);
4128 goto add_kcon;
4129 }
4130 if (ncons == 2) {
4131 /* if (cons2 == stb.k1)*/
4132 if (cons2 == stb.k1 || (con2v1 == 0 && con2v2 == 1))
4133 return op1;
4134 if (ILI_OPC(op1) == IL_UKMUL && ILI_OPND(op1, 2) == op2)
4135 return ILI_OPND(op1, 1);
4136 #if defined(TARGET_X8664)
4137 /*
4138 * dividing by a constant which may be a power of 2. if
4139 * it is, call a different routine which is faster than the
4140 * ordinary divide. The possible powers are 2 through 63.
4141 */
4142 i = _kpwr2(con2v1, con2v2, 63);
4143 if (i) {
4144 ilix = ad2ili(IL_KURSHIFT, op1, ad_icon((INT)i));
4145 return ilix;
4146 }
4147 if (!XBIT(87, 0x1) && !XBIT(6, 0x400)) {
4148 res.numi[0] = con2v1;
4149 res.numi[1] = con2v2;
4150 ilix = reciprocal_division_64(op1, res.numi, 0);
4151 if (ilix)
4152 return ad2altili(opc, op1, op2, ilix);
4153 }
4154 #endif
4155 } /* ncons == 2 */
4156 /*
4157 * if the divisor is shifting 1 left, then replace the divide
4158 * with an unsigned right shift.
4159 */
4160 ilix = _lshift_one(op2);
4161 if (ilix)
4162 return ad2ili(IL_KURSHIFT, op1, ilix);
4163 break;
4164
4165 case IL_FDIV:
4166 #ifdef TM_FDIV /*{ hardware divide */
4167 /* hardware divide present */
4168 if (ncons == 3 && !is_flt0(cons2)) {
4169 xfdiv(con1v2, con2v2, &res.numi[1]);
4170 goto add_rcon;
4171 }
4172 if (!flg.ieee) {
4173 if (XBIT(15, 0x1) && (ncons & 2) && !is_flt0(cons2)) {
4174 /* x / y --> x * (1 / y) */
4175 res.numi[0] = 0;
4176 xfdiv(CONVAL2G(stb.flt1), con2v2, &res.numi[1]);
4177 ilix = ad1ili(IL_FCON, getcon(res.numi, DT_FLOAT));
4178 return ad2ili(IL_FMUL, ilix, op1);
4179 }
4180 if (XBIT(15, 0x4) && (!((ncons & 1) && (cons1 == stb.flt1)))) {
4181 /* x / y --> x * (1 / y) */
4182 ilix = ad2ili(IL_FDIV, ad1ili(IL_FCON, stb.flt1), op2);
4183 return ad2ili(IL_FMUL, ilix, op1);
4184 }
4185 #if defined(TARGET_X8664) || defined(TARGET_POWER)
4186 if (XBIT(183, 0x10000)) {
4187 if (XBIT(15, 0x40000000) && ILI_OPC(op2) == IL_FSQRT) {
4188 /*
4189 * Just use the approximating reciprocal sqrt instruction
4190 * for computing rsqrt:
4191 * y/x -> y * rqsrt(x)
4192 */
4193 tmp1 = ILI_OPND(op2, 1); /* x */
4194 tmp1 = ad1ili(IL_RSQRTSS, tmp1);
4195 ilix = ad2ili(IL_FMUL, op1, tmp1);
4196 return ilix;
4197 }
4198 if (XBIT(15, 0x10000000)) {
4199 /*
4200 * Just multiply the first operand by the approximating
4201 * reciprocal instruction
4202 */
4203 tmp1 = ad1ili(IL_RCPSS, op2);
4204 ilix = ad2ili(IL_FMUL, op1, tmp1);
4205 return ilix;
4206 }
4207 if (XBIT(15, 0x10)) {
4208 int x0;
4209 if (!XBIT(15, 0x20000) && ILI_OPC(op2) == IL_FSQRT) {
4210 /*
4211 * Newton's appx for recip sqrt:
4212 * x1 = (3.0*x0 - x*x0**3)/2.0
4213 * or
4214 * x1 = (3.0 - x*x0*x0)*x0*.5
4215 * or
4216 * x1 = (x*x0*x0 - 3.0)*x0*(-.5)
4217 */
4218 tmp1 = _frsqrt(ILI_OPND(op2, 1));
4219 ilix = ad2ili(IL_FMUL, op1, tmp1);
4220 return ilix;
4221 }
4222 if (!XBIT(15, 0x40000)) {
4223 ilix = _newton_fdiv(op1, op2);
4224 return ilix;
4225 }
4226 }
4227 }
4228 #endif /* defined(TARGET_X8664) || defined(TARGET_POWER) */
4229 }
4230 break;
4231 #endif /*} hardware divide */
4232 #ifndef TM_FDIV /*{ no hardware divide */
4233 #ifdef TM_FRCP /*{ mult - recip */
4234 /* perform divide by reciprocal approximation */
4235 if (flg.ieee) {
4236 if (ncons == 3 && !is_flt0(cons2)) {
4237 fdiv(con1v2, con2v2, res.numi[1]);
4238 goto add_rcon;
4239 }
4240 op1 = ad3ili(IL_DASP, op1, SP(0), ad1ili(IL_NULL, 0));
4241 op2 = ad3ili(IL_DASP, op2, SP(1), op1);
4242 ilix = ad2ili(IL_QJSR, _mkfunc(MTH_I_RDIV), op2);
4243 ilix = ad2ili(IL_DFRSP, ilix, SP(0));
4244 return ilix;
4245 }
4246 /* WARNING: since op2 must be cse'd, the ili must be generated
4247 * so that the scheduler sees op2 before its cse use. Currently,
4248 * the scheduler performs a postorder traversal.
4249 */
4250 tmp1 = ad1ili(IL_FCON, stb.flt2);
4251 /* assertion: no need for cse since sched treats multiple uses of
4252 * the same function ili as one call.
4253 */
4254 ilix = ad1ili(IL_FRCP, op2);
4255
4256 tmp = ad2ili(IL_FMUL, op2, ilix);
4257 tmp = ad2ili(IL_FSUB, tmp1, tmp);
4258 ilix = ad2ili(IL_FMUL, ilix, tmp);
4259
4260 tmp = ad2ili(IL_FMUL, op2, ilix);
4261 tmp = ad2ili(IL_FSUB, tmp1, tmp);
4262 ilix = ad3ili(IL_FNEWT, (int)ilip->opnd[1], tmp, ilix);
4263 ilix = ad2ili(IL_FMUL, op1, ilix);
4264 return ilix;
4265
4266 case IL_FNEWT:
4267 /* since constant folding of the frcp instruction is not performed,
4268 * the 2nd & 3rd operands are never constants
4269 */
4270 if (ncons == 1) {
4271 frcp(con1v2, res.numi[1]);
4272 goto add_rcon;
4273 }
4274 newili.opnd[2] = ilip->opnd[2]; /* get 3rd operand */
4275 break;
4276 #else /*} end: mult - recip */
4277
4278 op1 = ad3ili(IL_DASP, op1, SP(0), ad1ili(IL_NULL, 0));
4279 op2 = ad3ili(IL_DASP, op2, SP(1), op1);
4280 ilix = ad2ili(IL_QJSR, _mkfunc(MTH_I_RDIV), op2);
4281 ilix = ad2ili(IL_DFRSP, ilix, SP(0));
4282 return ilix;
4283 #endif
4284 #endif /*} end: no hardware divide */
4285
4286 case IL_DDIV:
4287 #ifdef TM_DDIV /*{ hardware divide present */
4288 if (ncons == 3 && !is_dbl0(cons2)) {
4289 GETVAL64(num1, cons1);
4290 GETVAL64(num2, cons2);
4291 xddiv(num1.numd, num2.numd, res.numd);
4292 goto add_dcon;
4293 }
4294 if (!flg.ieee) {
4295 if (XBIT(15, 0x1) && (ncons & 2) && !is_dbl0(cons2)) {
4296 /* x / y --> x * (1 / y) */
4297 GETVAL64(num1, stb.dbl1);
4298 GETVAL64(num2, cons2);
4299 xddiv(num1.numd, num2.numd, res.numd);
4300 ilix = ad1ili(IL_DCON, getcon(res.numi, DT_DBLE));
4301 return ad2ili(IL_DMUL, ilix, op1);
4302 } else if (XBIT(15, 0x4) && (!((ncons & 1) && (cons1 == stb.dbl1)))) {
4303 /* x / y --> x * (1 / y) */
4304 ilix = ad2ili(IL_DDIV, ad1ili(IL_DCON, stb.dbl1), op2);
4305 return ad2ili(IL_DMUL, ilix, op1);
4306 }
4307 }
4308 break;
4309 #endif /*} hardware divide */
4310
4311 #ifndef TM_DDIV /*{ no hardware divide */
4312 #ifdef TM_DRCP /*{ mult - recip */
4313 /* perform divide by reciprocal approximation */
4314 if (flg.ieee) {
4315 if (ncons == 3 && !is_dbl0(cons2)) {
4316 GETVAL64(num1, cons1);
4317 GETVAL64(num2, cons2);
4318 ddiv(num1.numd, num2.numd, res.numd);
4319 goto add_dcon;
4320 }
4321 op1 = ad3ili(IL_DADP, op1, DP(0), ad1ili(IL_NULL, 0));
4322 op2 = ad3ili(IL_DADP, op2, DP(1), op1);
4323 ilix = ad2ili(IL_QJSR, _mkfunc(MTH_I_DDIV), op2);
4324 ilix = ad2ili(IL_DFRDP, ilix, DP(0));
4325 return ilix;
4326 }
4327 tmp1 = ad1ili(IL_DCON, stb.dbl2);
4328 /* assertion: no need for cse since sched treats multiple uses of
4329 * the same function ili as one call.
4330 */
4331 ilix = ad1ili(IL_DRCP, op2);
4332 for (i = 2; i > 0; i--) {
4333 tmp = ad2ili(IL_DMUL, op2, ilix);
4334 tmp = ad2ili(IL_DSUB, tmp1, tmp);
4335 ilix = ad2ili(IL_DMUL, ilix, tmp);
4336 }
4337 tmp = ad2ili(IL_DMUL, op2, ilix);
4338 tmp = ad2ili(IL_DSUB, tmp1, tmp);
4339 ilix = ad3ili(IL_DNEWT, (int)ilip->opnd[1], tmp, ilix);
4340 ilix = ad2ili(IL_DMUL, op1, ilix);
4341 return ilix;
4342
4343 case IL_DNEWT:
4344 /* since constant folding of the drcp instruction is not performed,
4345 * the 2nd & 3rd operands are never constants
4346 */
4347 if (ncons == 1) {
4348 /* TBD - need to constant fold by recip(cons1) */
4349 GETVAL64(num2, cons1);
4350 drcp(num2.numd, res.numd);
4351 goto add_dcon;
4352 }
4353 newili.opnd[2] = ilip->opnd[2]; /* get 3rd operand */
4354 break;
4355 #else /*} end: mult - recip */
4356
4357 op1 = ad3ili(IL_DADP, op1, DP(0), ad1ili(IL_NULL, 0));
4358 op2 = ad3ili(IL_DADP, op2, DP(1), op1);
4359 ilix = ad2ili(IL_QJSR, _mkfunc(MTH_I_DDIV), op2);
4360 ilix = ad2ili(IL_DFRDP, ilix, DP(0));
4361 return ilix;
4362 #endif
4363 #endif /*} no hardware divide */
4364
4365 #if defined(TARGET_X8664)
4366 case IL_SCMPLXDIV:
4367 ilix = ad2func_cmplx(IL_QJSR, fast_math("div", 's', 'c', FMTH_I_CSDIV), op1,
4368 op2);
4369 return ad2altili(opc, op1, op2, ilix);
4370 case IL_DCMPLXDIV:
4371 ilix = ad2func_cmplx(IL_QJSR, fast_math("div", 's', 'z', FMTH_I_CDDIV), op1,
4372 op2);
4373 return ad2altili(opc, op1, op2, ilix);
4374 #endif
4375 case IL_MOD:
4376 if (ncons == 3 && con2v2 != 0) {
4377 if (con1v2 == 0x80000000 && con2v2 == -1)
4378 res.numi[1] = 0;
4379 else
4380 res.numi[1] = con1v2 % con2v2;
4381 goto add_icon;
4382 }
4383 if (ncons == 2) {
4384 if (cons2 == stb.i1)
4385 return ad1ili(IL_ICON, stb.i0);
4386
4387 /* a % con = a - (a / cons) * cons; catch power of two
4388 * optimization.
4389 */
4390 res.numi[0] = con2v2;
4391 if (res.numi[0] > 0 && _pwr2(res.numi[0], 30)) {
4392 tmp = ad2ili(IL_IDIV, op1, op2);
4393 tmp = ad2ili(IL_IMUL, tmp, op2);
4394 ilix = ad2ili(IL_ISUB, op1, tmp);
4395 return ilix;
4396 }
4397 }
4398 #ifndef TM_IMOD
4399 ilix = ad2func_int(IL_QJSR, MTH_I_IMOD, op1, op2);
4400 return ilix;
4401 #else
4402 if (ncons == 2 && !XBIT(6, 0x400)) {
4403 ilix = reciprocal_mod(op1, res.numi[0], 1);
4404 if (ilix)
4405 return ad2altili(opc, op1, op2, ilix);
4406 }
4407 break;
4408 #endif
4409
4410 case IL_KMOD:
4411 tmp = ad2ili(IL_KDIV, op1, op2);
4412 tmp = ad2ili(IL_KMUL, tmp, op2);
4413 ilix = ad2ili(IL_KSUB, op1, tmp);
4414 return ilix;
4415
4416 case IL_UIMOD:
4417 if (ncons == 3) {
4418 tmp = xumod(con1v2, con2v2, &res.numu[0]);
4419 return ad_icon((INT)res.numu[0]);
4420 }
4421 if (ncons == 2) {
4422 if (cons2 == stb.i1)
4423 return ad1ili(IL_ICON, stb.i0);
4424
4425 if ((res.numi[0] = con2v2) > 0) {
4426 /*
4427 * mod by a constant which may be a power of 2.
4428 * if it is, generate an and operation. The possible powers
4429 * are 2 through 30.
4430 */
4431 i = _pwr2(res.numi[0], 30);
4432 if (i) {
4433 /* expand uimod as follows:
4434 * res = op1 & (con - 1)
4435 */
4436 ilix = ad2ili(IL_AND, op1, ad_icon(res.numi[0] - 1));
4437 return ilix;
4438 }
4439 }
4440 }
4441 /*
4442 * if the divisor is shifting 1 left, then replace the mod
4443 * with an and.
4444 */
4445 if (_lshift_one(op2)) {
4446 op2 = ad2ili(IL_ISUB, op2, ILI_OPND(op2, 1));
4447 return ad2ili(IL_AND, op1, op2);
4448 }
4449 #ifndef TM_UIMOD
4450 #error TM_UIMOD undefined
4451 ilix = ad2func_int(IL_QJSR, MTH_I_UIMOD, op1, op2);
4452 return ilix;
4453 #else
4454 if (ncons == 2 && !XBIT(6, 0x400)) {
4455 ilix = reciprocal_mod(op1, res.numi[0], 0);
4456 if (ilix)
4457 return ad2altili(opc, op1, op2, ilix);
4458 }
4459 break;
4460 #endif
4461 case IL_KUMOD:
4462 if (ncons == 2) {
4463 if (cons2 == stb.k1)
4464 return ad1ili(IL_KCON, stb.k0);
4465
4466 if (((res.numu[0] = con2v2) > 0) && (res.numu[1] = con2v1) == 0) {
4467 /*
4468 * mod by a constant which may be a power of 2.
4469 * if it is, generate an and operation. The possible powers
4470 * are 2 through 31.
4471 */
4472 i = _kpwr2(con2v1, con2v2, 31);
4473 if (i) {
4474 /* expand uimod as follows:
4475 * res = op1 & (con - 1)
4476 */
4477 ilix = ad2ili(IL_KAND, op1, ad_kcon(res.numu[1], res.numu[0] - 1));
4478 return ilix;
4479 }
4480 }
4481 if (!XBIT(6, 0x400)) {
4482 res.numi[0] = con2v1;
4483 res.numi[1] = con2v2;
4484 ilix = reciprocal_mod_64(op1, (res.numi), 0);
4485 if (ilix)
4486 return ad2altili(opc, op1, op2, ilix);
4487 }
4488 }
4489 /*
4490 * if the divisor is shifting 1 left, then replace the mod
4491 * with an and.
4492 */
4493 if (_lshift_one(op2)) {
4494 op2 = ad2ili(IL_KSUB, op2, ILI_OPND(op2, 1));
4495 return ad2ili(IL_KAND, op1, op2);
4496 }
4497 tmp = ad2ili(IL_UKDIV, op1, op2);
4498 tmp = ad2ili(IL_UKMUL, tmp, op2);
4499 ilix = ad2ili(IL_UKSUB, op1, tmp);
4500 return ilix;
4501
4502 #ifdef TM_FRCP
4503 case IL_FRCP:
4504 /* Can't constant fold until there is a utility routine */
4505 break;
4506 #endif
4507 #ifdef TM_DRCP
4508 case IL_DRCP:
4509 /* Can't constant fold until there is a utility routine */
4510 break;
4511 #endif
4512
4513 case IL_FMOD:
4514 #if defined(TARGET_X8664)
4515 if (!flg.ieee) {
4516 (void)mk_prototype(fast_math("mod", 's', 's', FMTH_I_AMOD), "f pure",
4517 DT_FLOAT, 2, DT_FLOAT, DT_FLOAT);
4518 ilix = ad_func(IL_DFRSP, IL_QJSR, fast_math("mod", 's', 's', FMTH_I_AMOD),
4519 2, op1, op2);
4520 } else {
4521 (void)mk_prototype(MTH_I_AMOD, "f pure", DT_FLOAT, 2, DT_FLOAT, DT_FLOAT);
4522 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_AMOD, 2, op1, op2);
4523 }
4524 ilix = ad2altili(opc, op1, op2, ilix);
4525 return ilix;
4526 #endif
4527 (void)mk_prototype(MTH_I_AMOD, "f pure", DT_FLOAT, 2, DT_FLOAT, DT_FLOAT);
4528 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_AMOD, 2, op1, op2);
4529 ilix = ad2altili(opc, op1, op2, ilix);
4530 return ilix;
4531 break;
4532 case IL_DMOD:
4533 if (!flg.ieee) {
4534 #ifdef TARGET_X8664
4535 (void)mk_prototype(fast_math("mod", 's', 'd', FMTH_I_DMOD), "f pure",
4536 DT_DBLE, 2, DT_DBLE, DT_DBLE);
4537 #else
4538 (void)mk_prototype(MTH_I_DMOD, "f pure", DT_DBLE, 2, DT_DBLE, DT_DBLE);
4539 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DMOD, 2, op1, op2);
4540 ilix = ad2altili(opc, op1, op2, ilix);
4541 return ilix;
4542 #endif
4543 ilix = ad_func(IL_DFRDP, IL_QJSR, fast_math("mod", 's', 'd', FMTH_I_DMOD),
4544 2, op1, op2);
4545 } else {
4546 (void)mk_prototype(MTH_I_DMOD, "f pure", DT_DBLE, 2, DT_DBLE, DT_DBLE);
4547 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DMOD, 2, op1, op2);
4548 }
4549 ilix = ad2altili(opc, op1, op2, ilix);
4550 return ilix;
4551
4552 case IL_FSINH:
4553 if (XBIT_NEW_MATH_NAMES) {
4554 fname = make_math(MTH_sinh, &funcsptr, 1, false, DT_FLOAT, 1, DT_FLOAT);
4555 ilix = ad_func(IL_spfunc, IL_QJSR, fname, 1, op1);
4556 ilix = ad1altili(opc, op1, ilix);
4557 return ilix;
4558 }
4559 if (!flg.ieee) {
4560 #ifdef TARGET_X8664
4561 (void)mk_prototype(fast_math("sinh", 's', 's', FMTH_I_SINH), "f pure",
4562 DT_FLOAT, 1, DT_FLOAT);
4563 #else
4564 (void)mk_prototype(MTH_I_SINH, "f pure", DT_FLOAT, 1, DT_FLOAT);
4565 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_SINH, 1, op1);
4566 ilix = ad1altili(opc, op1, ilix);
4567 return ilix;
4568
4569 #endif
4570 ilix = ad_func(IL_DFRSP, IL_QJSR,
4571 fast_math("sinh", 's', 's', FMTH_I_SINH), 1, op1);
4572 } else {
4573 (void)mk_prototype(MTH_I_SINH, "f pure", DT_FLOAT, 1, DT_FLOAT);
4574 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_SINH, 1, op1);
4575 }
4576 ilix = ad1altili(opc, op1, ilix);
4577 return ilix;
4578
4579 case IL_DSINH:
4580 if (XBIT_NEW_MATH_NAMES) {
4581 fname = make_math(MTH_sinh, &funcsptr, 1, false, DT_DBLE, 1, DT_DBLE);
4582 ilix = ad_func(IL_dpfunc, IL_QJSR, fname, 1, op1);
4583 ilix = ad1altili(opc, op1, ilix);
4584 return ilix;
4585 }
4586 if (!flg.ieee) {
4587 #ifdef TARGET_X8664
4588 (void)mk_prototype(fast_math("sinh", 's', 'd', FMTH_I_DSINH), "f pure",
4589 DT_DBLE, 1, DT_DBLE);
4590 #else
4591 (void)mk_prototype(MTH_I_DSINH, "f pure", DT_DBLE, 1, DT_DBLE);
4592 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DSINH, 1, op1);
4593 ilix = ad1altili(opc, op1, ilix);
4594 return ilix;
4595 #endif
4596 ilix = ad_func(IL_DFRDP, IL_QJSR,
4597 fast_math("sinh", 's', 'd', FMTH_I_DSINH), 1, op1);
4598 } else {
4599 (void)mk_prototype(MTH_I_DSINH, "f pure", DT_DBLE, 1, DT_DBLE);
4600 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DSINH, 1, op1);
4601 }
4602 ilix = ad1altili(opc, op1, ilix);
4603 return ilix;
4604
4605 case IL_FCOSH:
4606 if (XBIT_NEW_MATH_NAMES) {
4607 fname = make_math(MTH_cosh, &funcsptr, 1, false, DT_FLOAT, 1, DT_FLOAT);
4608 ilix = ad_func(IL_spfunc, IL_QJSR, fname, 1, op1);
4609 ilix = ad1altili(opc, op1, ilix);
4610 return ilix;
4611 }
4612 if (!flg.ieee) {
4613 #ifdef TARGET_X8664
4614 (void)mk_prototype(fast_math("cosh", 's', 's', FMTH_I_COSH), "f pure",
4615 DT_FLOAT, 1, DT_FLOAT);
4616 #else
4617 (void)mk_prototype(MTH_I_COSH, "f pure", DT_FLOAT, 1, DT_FLOAT);
4618 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_COSH, 1, op1);
4619 ilix = ad1altili(opc, op1, ilix);
4620 return ilix;
4621 #endif
4622 ilix = ad_func(IL_DFRSP, IL_QJSR,
4623 fast_math("cosh", 's', 's', FMTH_I_COSH), 1, op1);
4624 } else {
4625 (void)mk_prototype(MTH_I_COSH, "f pure", DT_FLOAT, 1, DT_FLOAT);
4626 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_COSH, 1, op1);
4627 }
4628 ilix = ad1altili(opc, op1, ilix);
4629 return ilix;
4630
4631 case IL_DCOSH:
4632 if (XBIT_NEW_MATH_NAMES) {
4633 fname = make_math(MTH_cosh, &funcsptr, 1, false, DT_DBLE, 1, DT_DBLE);
4634 ilix = ad_func(IL_dpfunc, IL_QJSR, fname, 1, op1);
4635 ilix = ad1altili(opc, op1, ilix);
4636 return ilix;
4637 }
4638 if (!flg.ieee) {
4639 #ifdef TARGET_X8664
4640 (void)mk_prototype(fast_math("cosh", 's', 'd', FMTH_I_DCOSH), "f pure",
4641 DT_DBLE, 1, DT_DBLE);
4642 #else
4643 (void)mk_prototype(MTH_I_DCOSH, "f pure", DT_DBLE, 1, DT_DBLE);
4644 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DCOSH, 1, op1);
4645 ilix = ad1altili(opc, op1, ilix);
4646 return ilix;
4647 #endif
4648 ilix = ad_func(IL_DFRDP, IL_QJSR,
4649 fast_math("cosh", 's', 'd', FMTH_I_DCOSH), 1, op1);
4650 } else {
4651 (void)mk_prototype(MTH_I_DCOSH, "f pure", DT_DBLE, 1, DT_DBLE);
4652 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DCOSH, 1, op1);
4653 }
4654 ilix = ad1altili(opc, op1, ilix);
4655 return ilix;
4656
4657 case IL_FTANH:
4658 if (XBIT_NEW_MATH_NAMES) {
4659 fname = make_math(MTH_tanh, &funcsptr, 1, false, DT_FLOAT, 1, DT_FLOAT);
4660 ilix = ad_func(IL_spfunc, IL_QJSR, fname, 1, op1);
4661 ilix = ad1altili(opc, op1, ilix);
4662 return ilix;
4663 }
4664 (void)mk_prototype(MTH_I_TANH, "pure", DT_FLOAT, 1, DT_FLOAT);
4665 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_TANH, 1, op1);
4666 ilix = ad1altili(opc, op1, ilix);
4667 return ilix;
4668
4669 case IL_DTANH:
4670 if (XBIT_NEW_MATH_NAMES) {
4671 fname = make_math(MTH_tanh, &funcsptr, 1, false, DT_DBLE, 1, DT_DBLE);
4672 ilix = ad_func(IL_dpfunc, IL_QJSR, fname, 1, op1);
4673 ilix = ad1altili(opc, op1, ilix);
4674 return ilix;
4675 }
4676 (void)mk_prototype(MTH_I_DTANH, "pure", DT_DBLE, 1, DT_DBLE);
4677 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DTANH, 1, op1);
4678 ilix = ad1altili(opc, op1, ilix);
4679 return ilix;
4680
4681 case IL_ICMP:
4682 newili.opnd[2] = ilip->opnd[2];
4683 cond = CCRelationILIOpnd(ilip, 2);
4684 if (ncons == 1) {
4685 if (ILI_OPC(op2) == IL_IADD &&
4686 ILI_OPC(tmp = ILI_OPND(op2, 2)) == IL_ICON) {
4687
4688 /* c1 :: i + c2 --> c1 - c2 :: i */
4689
4690 if (isub_ovf(con1v2, CONVAL2G(ILI_OPND(tmp, 1)), &res.numi[1]))
4691 break;
4692 return ad3ili(IL_ICMP, ad_icon(res.numi[1]), ILI_OPND(op2, 1), cond);
4693 }
4694 if (ILI_OPC(op2) == IL_ISUB &&
4695 ILI_OPC(tmp = ILI_OPND(op2, 2)) == IL_ICON) {
4696
4697 /* c1 :: i - c2 --> c1 + c2 :: i */
4698
4699 if (iadd_ovf(con1v2, CONVAL2G(ILI_OPND(tmp, 1)), &res.numi[1]))
4700 break;
4701 return ad3ili(IL_ICMP, ad_icon(res.numi[1]), ILI_OPND(op2, 1), cond);
4702 }
4703 if (cons1 == stb.i0)
4704 /* 0 :: i --> i rev(::) 0 */
4705 return ad2ili(IL_ICMPZ, op2, commute_cc(cond));
4706 if (cons1 == stb.i1) {
4707 if (cond == CC_LE)
4708 /* 1 LE x --> x GT z */
4709 return ad2ili(IL_ICMPZ, op2, CC_GT);
4710 if (cond == CC_GT)
4711 /* 1 GT x --> x LE z */
4712 return ad2ili(IL_ICMPZ, op2, CC_LE);
4713 }
4714 if (con1v2 >= 1 && is_zero_one(op2)) {
4715 /* low-quality range analysis */
4716 switch (cond) {
4717 case CC_EQ:
4718 case CC_LE:
4719 if (con1v2 > 1) {
4720 /* 2 <= x is false */
4721 if (func_in(op2))
4722 break;
4723 return ad1ili(IL_ICON, stb.i0);
4724 }
4725 return op2; /* 1 <= x becomes x */
4726 case CC_NE:
4727 case CC_GT:
4728 if (con1v2 > 1) {
4729 /* 2 > x is true */
4730 if (func_in(op2))
4731 break;
4732 return ad1ili(IL_ICON, stb.i1);
4733 }
4734 /* 1 > x becomes x == 0 */
4735 return ad2ili(IL_ICMPZ, op2, CC_EQ);
4736 case CC_LT: /* 1 < x always false */
4737 if (func_in(op2))
4738 break;
4739 return ad1ili(IL_ICON, stb.i0);
4740 case CC_GE: /* 1 >= x always true */
4741 if (func_in(op2))
4742 break;
4743 return ad1ili(IL_ICON, stb.i1);
4744 }
4745 }
4746 } else if (ncons == 2) {
4747 if (ILI_OPC(op1) == IL_IADD &&
4748 ILI_OPC(tmp = ILI_OPND(op1, 2)) == IL_ICON) {
4749
4750 /* i + c1 :: c2 --> i :: c2 - c1 */
4751
4752 if (isub_ovf(con2v2, CONVAL2G(ILI_OPND(tmp, 1)), &res.numi[1]))
4753 break;
4754 return ad3ili(IL_ICMP, ILI_OPND(op1, 1), ad_icon(res.numi[1]), cond);
4755 }
4756 if (ILI_OPC(op1) == IL_ISUB &&
4757 ILI_OPC(tmp = ILI_OPND(op1, 2)) == IL_ICON) {
4758
4759 /* i - c1 :: c2 --> i :: c2 + c1 */
4760
4761 if (iadd_ovf(con2v2, CONVAL2G(ILI_OPND(tmp, 1)), &res.numi[1]))
4762 break;
4763 return ad3ili(IL_ICMP, ILI_OPND(op1, 1), ad_icon(res.numi[1]), cond);
4764 }
4765 if (cons2 == stb.i0)
4766 return ad2ili(IL_ICMPZ, op1, cond);
4767 if (cons2 == stb.i1) {
4768 if (cond == CC_GE)
4769 /* x GE 1 --> x GT z */
4770 return ad2ili(IL_ICMPZ, op1, CC_GT);
4771 if (cond == CC_LT)
4772 /* x LT 1 --> x LE z */
4773 return ad2ili(IL_ICMPZ, op1, CC_LE);
4774 }
4775 if (con2v2 >= 1 && is_zero_one(op1)) {
4776 /* low-quality range analysis */
4777 switch (cond) {
4778 case CC_EQ:
4779 case CC_GE:
4780 if (con2v2 > 1) {
4781 /* x >= 2 is false */
4782 if (func_in(op1))
4783 break;
4784 return ad1ili(IL_ICON, stb.i0);
4785 }
4786 return op1; /* x >= 1 becomes x */
4787 case CC_NE:
4788 case CC_LT:
4789 if (con2v2 > 1) {
4790 /* x < 2 is true */
4791 if (func_in(op1))
4792 break;
4793 return ad1ili(IL_ICON, stb.i1);
4794 }
4795 /* x < 1 becomes x == 0 */
4796 return ad2ili(IL_ICMPZ, op1, CC_EQ);
4797 case CC_GT: /* x > 1 always false */
4798 if (func_in(op1))
4799 break;
4800 return ad1ili(IL_ICON, stb.i0);
4801 case CC_LE: /* x <= 1 always true */
4802 if (func_in(op1))
4803 break;
4804 return ad1ili(IL_ICON, stb.i1);
4805 }
4806 }
4807 } else if (ncons == 3) {
4808 res.numi[1] = cmp_to_log(icmp(con1v2, con2v2), cond);
4809 goto add_icon;
4810 } else if (op1 == op2 && !func_in(op1)) {
4811 res.numi[1] = cmp_to_log((INT)0, cond);
4812 goto add_icon;
4813 }
4814 break;
4815
4816 case IL_FMAX:
4817 if (ncons == 3) {
4818 if (xfcmp(con1v2, con2v2) > 0)
4819 return op1;
4820 return op2;
4821 }
4822 if (!flg.ieee)
4823 return red_minmax(opc, op1, op2);
4824 break;
4825 case IL_FMIN:
4826 if (ncons == 3) {
4827 if (xfcmp(con1v2, con2v2) < 0)
4828 return op1;
4829 return op2;
4830 }
4831 if (!flg.ieee)
4832 return red_minmax(opc, op1, op2);
4833 break;
4834
4835 case IL_FCMP:
4836 newili.opnd[2] = ilip->opnd[2];
4837 #ifdef TM_FCMPZ
4838 if (ncons == 2 && is_flt0(cons2))
4839 return ad2ili(IL_FCMPZ, op1, (int)ilip->opnd[2]);
4840 if (ncons == 1 && is_flt0(cons1))
4841 return ad2ili(IL_FCMPZ, op2, commute_cc(ilip->opnd[2]));
4842 #else
4843 if (ncons == 1 && is_flt0(cons1))
4844 return ad3ili(IL_FCMP, op2, op1,
4845 commute_cc(CCRelationILIOpnd(ilip, 2)));
4846 #endif
4847 if (!flg.ieee) {
4848 if (ncons == 3) {
4849 res.numi[1] = cmp_to_log(xfcmp(con1v2, con2v2), ilip->opnd[2]);
4850 goto add_icon;
4851 }
4852 if (op1 == op2 && !func_in(op1)) {
4853 res.numi[1] = cmp_to_log(0, ilip->opnd[2]);
4854 goto add_icon;
4855 }
4856 }
4857 break;
4858
4859 case IL_DMAX:
4860 if (ncons == 3) {
4861 GETVAL64(num1, cons1);
4862 GETVAL64(num2, cons2);
4863 if (xdcmp(num1.numd, num2.numd) > 0)
4864 return op1;
4865 return op2;
4866 }
4867 if (!flg.ieee)
4868 return red_minmax(opc, op1, op2);
4869 break;
4870 case IL_DMIN:
4871 if (ncons == 3) {
4872 GETVAL64(num1, cons1);
4873 GETVAL64(num2, cons2);
4874 if (xdcmp(num1.numd, num2.numd) < 0)
4875 return op1;
4876 return op2;
4877 }
4878 if (!flg.ieee)
4879 return red_minmax(opc, op1, op2);
4880 break;
4881
4882 case IL_DCMP:
4883 newili.opnd[2] = ilip->opnd[2];
4884 #ifdef TM_DCMPZ
4885 if (ncons == 2 && is_dbl0(cons2))
4886 return ad2ili(IL_DCMPZ, op1, (int)ilip->opnd[2]);
4887 if (ncons == 1 && is_dbl0(cons1))
4888 return ad2ili(IL_DCMPZ, op2, commute_cc(ilip->opnd[2]));
4889 #else
4890 if (ncons == 1 && is_dbl0(cons1))
4891 return ad3ili(IL_DCMP, op2, op1,
4892 commute_cc(CCRelationILIOpnd(ilip, 2)));
4893 #endif
4894 if (ncons == 2 && ILI_OPC(op1) == IL_DBLE) {
4895 ilix = DblIsSingle(cons2);
4896 if (ilix) {
4897 return ad3ili(IL_FCMP, ILI_OPND(op1, 1), ilix, ilip->opnd[2]);
4898 }
4899 }
4900 if (!flg.ieee) {
4901 if (ncons == 3) {
4902 GETVAL64(num1, cons1);
4903 GETVAL64(num2, cons2);
4904 res.numi[1] =
4905 cmp_to_log(xdcmp(num1.numd, num2.numd), (int)ilip->opnd[2]);
4906 goto add_icon;
4907 }
4908 if (op1 == op2 && !func_in(op1)) {
4909 res.numi[1] = cmp_to_log((INT)0, (int)ilip->opnd[2]);
4910 goto add_icon;
4911 }
4912 }
4913 break;
4914
4915 case IL_ACMP:
4916 newili.opnd[2] = ilip->opnd[2];
4917 if (ncons == 2 && con2v2 == 0 && con2v1 == 0) {
4918 return ad2ili(IL_ACMPZ, op1, ilip->opnd[2]);
4919 } else if (op1 == op2 && !func_in(op1)) {
4920 res.numi[1] = cmp_to_log(0, ilip->opnd[2]);
4921 goto add_icon;
4922 }
4923 break;
4924
4925 case IL_UICMP:
4926 if (ncons == 3) {
4927 res.numi[1] =
4928 cmp_to_log(xucmp((UINT)con1v2, (UINT)con2v2), (int)ilip->opnd[2]);
4929 goto add_icon;
4930 }
4931
4932 #ifndef TM_UICMP
4933 /*
4934 * An out-of-line call is generated for those machines which
4935 * do not have an unsigned compare instruction. The result
4936 * of this routine is:
4937 * -1, if op1 < op2,
4938 * 0, if op1 = op2, or
4939 * 1, if op1 > op2.
4940 * This result is compared against zero to complete the code
4941 * sequence.
4942 */
4943 expb.uicmp = _mkfunc(MTH_I_UICMP);
4944 ilix = ad2func_int(IL_QJSR, MTH_I_UICMP, op1, op2);
4945 ilix = ad2ili(IL_ICMPZ, ilix, (int)ilip->opnd[2]);
4946 return ilix;
4947 #endif
4948 #ifdef TM_UICMP
4949 newili.opnd[2] = ilip->opnd[2];
4950 /*
4951 * The simplifications performed for signed int conditionals cannot
4952 * be performed for unsigned conditionals; e.g.,
4953 * i + c1 :: c2
4954 * isn't always equivalent to
4955 * i :: c2 - c1
4956 * Overflow may occur for 'i + c1', but the result is defined to be
4957 * congruent mod 2^32.
4958 * Example:
4959 * unsigned i = 0xffffff80;
4960 * if (i + 0x80 < 0x100) ...
4961 * The 'if' evaluates true since the result of the add is defined and
4962 * is 0. However,
4963 * if (i < 0x80) ...
4964 * evaluates false.
4965 */
4966 if (ncons == 1) {
4967 if (cons1 == stb.i0)
4968 /* 0 :: i --> i rev(::) 0 */
4969 return ad2ili(IL_UICMPZ, op2,
4970 commute_cc(CCRelationILIOpnd(ilip, 2)));
4971 } else if (ncons == 2) {
4972 if (cons2 == stb.i0)
4973 return ad2ili(IL_UICMPZ, op1, CCRelationILIOpnd(ilip, 2));
4974 } else if (op1 == op2 && !func_in(op1)) {
4975 res.numi[1] = cmp_to_log(0, ilip->opnd[2]);
4976 goto add_icon;
4977 }
4978 break;
4979 #endif
4980
4981 case IL_AND:
4982 if (ncons == 2) {
4983 if (cons2 == stb.i0 && !func_in(op1))
4984 return op2;
4985 if (con2v2 == (INT)(-1))
4986 return op1;
4987 if (opc1 == IL_AND && ILI_OPC(ILI_OPND(op1, 2)) == IL_ICON) {
4988 op2 = ad2ili(IL_AND, ILI_OPND(op1, 2), op2);
4989 op1 = ILI_OPND(op1, 1);
4990 return ad2ili(IL_AND, op1, op2);
4991 }
4992 }
4993 if (ncons == 3) {
4994 res.numi[1] = con1v2 & con2v2;
4995 goto add_icon;
4996 }
4997 if ((opc1 == IL_NOT || opc1 == IL_UNOT) && ILI_OPND(op1, 1) == op2) {
4998 /* Complement expression: A & ~A = 0 */
4999 res.numi[0] = res.numi[1] = 0;
5000 goto add_icon;
5001 }
5002 if ((opc2 == IL_NOT || opc2 == IL_UNOT) && ILI_OPND(op2, 1) == op1) {
5003 /* Complement expression: A & ~A = 0 */
5004 res.numi[0] = res.numi[1] = 0;
5005 goto add_icon;
5006 }
5007 goto idempotent_and_or;
5008
5009 case IL_KAND:
5010 if (ncons == 2) {
5011 if (con2v1 == 0 && con2v2 == 0 && !func_in(op1))
5012 return op2;
5013 if ((con2v1 == (INT)(-1)) && con2v2 == (INT)(-1))
5014 return op1;
5015 if (opc1 == IL_KAND && ILI_OPC(ILI_OPND(op1, 2)) == IL_KCON) {
5016 op2 = ad2ili(IL_KAND, ILI_OPND(op1, 2), op2);
5017 op1 = ILI_OPND(op1, 1);
5018 return ad2ili(IL_KAND, op1, op2);
5019 }
5020 }
5021 if (ncons == 3) {
5022 GETVALI64(num1, cons1);
5023 GETVALI64(num2, cons2);
5024 and64(num1.numi, num2.numi, res.numi);
5025 goto add_kcon;
5026 }
5027 if ((opc1 == IL_KNOT || opc1 == IL_UKNOT) && ILI_OPND(op1, 1) == op2) {
5028 /* Complement expression: A & ~A = 0 */
5029 res.numi[0] = res.numi[1] = 0;
5030 goto add_kcon;
5031 }
5032 if ((opc2 == IL_KNOT || opc2 == IL_UKNOT) && ILI_OPND(op2, 1) == op1) {
5033 /* Complement expression: A & ~A = 0 */
5034 res.numi[0] = res.numi[1] = 0;
5035 goto add_kcon;
5036 }
5037 goto idempotent_and_or;
5038
5039 case IL_ROTL:
5040 break;
5041
5042 case IL_OR:
5043 if (ncons == 2) {
5044 if (cons2 == stb.i0)
5045 return op1;
5046 if (con2v2 == (INT)(-1) && !func_in(op1))
5047 return op2;
5048 } else if (ncons == 3) {
5049 res.numi[1] = con1v2 | con2v2;
5050 goto add_icon;
5051 }
5052 if ((opc1 == IL_NOT || opc1 == IL_UNOT) && ILI_OPND(op1, 1) == op2) {
5053 /* Complement expression: A | ~A = ~0 */
5054 res.numi[0] = 0;
5055 res.numi[1] = ~0;
5056 goto add_icon;
5057 }
5058 if ((opc2 == IL_NOT || opc2 == IL_UNOT) && ILI_OPND(op2, 1) == op1) {
5059 /* Complement expression: A | ~A = ~0 */
5060 res.numi[0] = 0;
5061 res.numi[1] = ~0;
5062 goto add_icon;
5063 }
5064 goto idempotent_and_or;
5065
5066 case IL_KOR:
5067 if (ncons == 2) {
5068 if (con2v1 == 0 && con2v2 == 0)
5069 return op1;
5070 if ((con2v1 == (INT)(-1)) && con2v2 == (INT)(-1) && !func_in(op1))
5071 return op2;
5072 }
5073 if ((opc1 == IL_KNOT || opc1 == IL_UKNOT) && ILI_OPND(op1, 1) == op2) {
5074 /* Complement expression: A | ~A = ~0 */
5075 res.numi[0] = res.numi[1] = ~0;
5076 goto add_kcon;
5077 }
5078 if ((opc2 == IL_KNOT || opc2 == IL_UKNOT) && ILI_OPND(op2, 1) == op1) {
5079 /* Complement expression: A | ~A = ~0 */
5080 res.numi[0] = res.numi[1] = ~0;
5081 goto add_kcon;
5082 }
5083 /* FALL THRU to idempotent_and_or */
5084 idempotent_and_or:
5085 if (op1 == op2) {
5086 /* Idempotent expression: A & A = A
5087 * A | A = A
5088 */
5089 return op1;
5090 }
5091 /* Check to see if we can apply DeMorgan's Law:
5092 * ~A | ~B = ~(A & B)
5093 * ~A & ~B = ~(A | B)
5094 */
5095 if (opc1 == opc2 && (opc1 == IL_NOT || opc1 == IL_UNOT || opc1 == IL_KNOT ||
5096 opc1 == IL_UKNOT)) {
5097
5098 /* Can apply DeMorgan's Law */
5099
5100 int tmp, demorgans_opc;
5101
5102 switch (opc) {
5103 case IL_AND:
5104 demorgans_opc = IL_OR;
5105 break;
5106 case IL_KAND:
5107 demorgans_opc = IL_KOR;
5108 break;
5109 case IL_OR:
5110 demorgans_opc = IL_AND;
5111 break;
5112 case IL_KOR:
5113 demorgans_opc = IL_KAND;
5114 break;
5115 default:
5116 assert(0, "addarth: unexpected opcode DeMorgans ", opc, ERR_Fatal);
5117 break;
5118 }
5119
5120 tmp = ad2ili((ILI_OP)demorgans_opc, //???
5121 ILI_OPND(op1, 1), ILI_OPND(op2, 1));
5122 return ad1ili(opc1, tmp);
5123 }
5124 goto distributive;
5125
5126 case IL_XOR:
5127 if (ncons == 3) {
5128 res.numi[1] = con1v2 ^ con2v2;
5129 goto add_icon;
5130 }
5131 if (ncons == 2) {
5132 /* Idempotent expression: A ^ 0 = A */
5133 if (con2v1 == 0 && con2v2 == 0)
5134 return op1;
5135 }
5136 if (op1 == op2) {
5137 /* Idempotent expression: A ^ A = 0 */
5138 res.numi[0] = res.numi[1] = 0;
5139 goto add_icon;
5140 }
5141 if ((opc1 == IL_NOT || opc1 == IL_UNOT) && ILI_OPND(op1, 1) == op2) {
5142 /* Complement expression: A ^ ~A = ~0 */
5143 res.numi[0] = 0;
5144 res.numi[1] = ~0;
5145 goto add_icon;
5146 }
5147 if ((opc2 == IL_NOT || opc2 == IL_UNOT) && ILI_OPND(op2, 1) == op1) {
5148 /* Complement expression: A ^ ~A = ~0 */
5149 res.numi[0] = 0;
5150 res.numi[1] = ~0;
5151 goto add_icon;
5152 }
5153 if (opc1 == IL_AND)
5154 goto distributive;
5155 break;
5156
5157 case IL_KXOR:
5158 if (ncons == 3) {
5159 res.numi[0] = con1v1 ^ con2v1;
5160 res.numi[1] = con1v2 ^ con2v2;
5161 goto add_kcon;
5162 }
5163 if (ncons == 2) {
5164 /* Idempotent expression: A ^ 0 = A */
5165 if (con2v1 == 0 && con2v2 == 0)
5166 return op1;
5167 }
5168 if (op1 == op2) {
5169 /* Idempotent expression: A ^ A = 0 */
5170 res.numi[0] = res.numi[1] = 0;
5171 goto add_kcon;
5172 }
5173 if ((opc1 == IL_KNOT || opc1 == IL_UKNOT) && ILI_OPND(op1, 1) == op2) {
5174 /* Complement expression: A ^ ~A = ~0 */
5175 res.numi[0] = res.numi[1] = ~0;
5176 goto add_kcon;
5177 }
5178 if ((opc2 == IL_KNOT || opc2 == IL_UKNOT) && ILI_OPND(op2, 1) == op1) {
5179 /* Complement expression: A ^ ~A = ~0 */
5180 res.numi[0] = res.numi[1] = ~0;
5181 goto add_kcon;
5182 }
5183 if (opc1 != IL_KAND)
5184 break;
5185 /* else FALL THRU to distributive */
5186 distributive:
5187 /* Check to see if we can apply distributive law:
5188 * (A | B) & (A | C) = A | (B & C)
5189 * (A & B) | (A & C) = A & (B | C)
5190 * (A & B) ^ (A & C) = A & (B ^ C)
5191 */
5192 switch (opc1) {
5193 case IL_AND:
5194 case IL_OR:
5195 case IL_KAND:
5196 case IL_KOR:
5197 if (opc2 == opc1) {
5198 /* Look for a common factor */
5199
5200 int tmp, factor;
5201 int nonfactor1, nonfactor2;
5202
5203 if (ILI_OPND(op1, 1) == ILI_OPND(op2, 1)) {
5204 factor = 1;
5205 nonfactor1 = nonfactor2 = 2;
5206 } else if (ILI_OPND(op1, 2) == ILI_OPND(op2, 2)) {
5207 factor = 2;
5208 nonfactor1 = nonfactor2 = 1;
5209 } else if (ILI_OPND(op1, 1) == ILI_OPND(op2, 2)) {
5210 nonfactor2 = factor = 1;
5211 nonfactor1 = 2;
5212 } else if (ILI_OPND(op1, 2) == ILI_OPND(op2, 1)) {
5213 nonfactor2 = factor = 2;
5214 nonfactor1 = 1;
5215 } else {
5216 goto no_distribute; /* No common factor */
5217 }
5218 tmp = ad2ili(opc, ILI_OPND(op1, nonfactor1), ILI_OPND(op2, nonfactor2));
5219 return ad2ili(opc1, ILI_OPND(op1, factor), tmp);
5220 }
5221 break;
5222 default:
5223 break;
5224 }
5225 no_distribute:
5226 break;
5227
5228 case IL_JISHFT:
5229 if (ncons >= 2) {
5230 if ((tmp = con2v2) >= 0) {
5231 if (tmp >= 32) {
5232 res.numi[1] = 0;
5233 goto add_icon;
5234 }
5235 return ad2ili(IL_ULSHIFT, op1, op2);
5236 }
5237 if (tmp <= -32) {
5238 res.numi[1] = 0;
5239 goto add_icon;
5240 }
5241 op2 = ad_icon(-tmp);
5242 return ad2ili(IL_URSHIFT, op1, op2);
5243 }
5244 ilix = ad2func_int(IL_JSR, "ftn_i_jishft", op1, op2);
5245 ilix = ad2altili(opc, op1, op2, ilix);
5246 return ilix;
5247 break;
5248
5249 #ifdef IL_KISHFT
5250 case IL_KISHFT:
5251 op2 = ad1ili(IL_KIMV, op2);
5252 if (ILI_OPC(op2) == IL_ICON) {
5253 con2v2 = SymConval2(ILI_SymOPND(op2, 1));
5254 if (con2v2 >= 64 || con2v2 <= -64) {
5255 res.numi[0] = res.numi[1] = ~0;
5256 goto add_kcon;
5257 }
5258 if (con2v2 >= 0)
5259 return ad2ili(IL_KLSHIFT, op1, op2);
5260 op2 = ad_icon((INT)-con2v2);
5261 return ad2ili(IL_KURSHIFT, op1, op2);
5262 }
5263 tmp1 = ad1ili(IL_NULL, 0);
5264 tmp1 = ad3ili(IL_DAIR, op2, IR(1), tmp1);
5265 tmp1 = ad3ili(IL_DAKR, op1, IR(0), tmp1);
5266 tmp = ad2ili(
5267 IL_JSR,
5268 mk_prototype("ftn_i_kishft", "pure", DT_INT8, 2, DT_INT8, DT_INT),
5269 tmp1);
5270 ilix = ad2ili(IL_DFRKR, tmp, KR_RETVAL);
5271 return ilix;
5272 #endif /* #ifdef IL_KISHFT */
5273
5274 case IL_USHIFT:
5275 break;
5276
5277 case IL_LSHIFT:
5278 if (ncons & 2) {
5279 con2v2 = con2v2 & 31;
5280 if (con2v2 == 0)
5281 return op1;
5282 }
5283 if (ncons == 2) {
5284 if (cons2 == stb.i0)
5285 return op1;
5286 } else if (ncons == 3) {
5287 tmp = con2v2;
5288 if (SHIFTOK(tmp)) {
5289 res.numi[1] = LSHIFT(con1v2, tmp);
5290 goto add_icon;
5291 }
5292 }
5293 #ifdef TM_SHIFTAR
5294 opc = IL_LSHIFTA;
5295 op2 = ad1ili(IL_IAMV, op2);
5296 #endif
5297 break;
5298
5299 case IL_RSHIFT:
5300 if (ncons & 2) {
5301 con2v2 = con2v2 & 31;
5302 if (con2v2 == 0)
5303 return op1;
5304 }
5305 if (ncons == 2) {
5306 if (cons2 == stb.i0)
5307 return op1;
5308 } else if (ncons == 3) {
5309 tmp = con2v2;
5310 if (SHIFTOK(tmp)) {
5311 res.numi[1] = RSHIFT(con1v2, tmp);
5312 goto add_icon;
5313 }
5314 }
5315 #ifdef TM_SHIFTAR
5316 opc = IL_RSHIFTA;
5317 op2 = ad1ili(IL_IAMV, op2);
5318 #endif
5319 break;
5320 #ifdef TM_SHIFTAR
5321 case IL_SHIFTA:
5322 break;
5323 #endif
5324
5325 case IL_ULSHIFT:
5326 if (ncons & 2) {
5327 con2v2 = con2v2 & 31;
5328 if (con2v2 == 0)
5329 return op1;
5330 }
5331 if (ncons == 2) {
5332 if (cons2 == stb.i0)
5333 return op1;
5334 } else if (ncons == 3) {
5335 tmp = con2v2;
5336 if (SHIFTOK(tmp)) {
5337 res.numi[1] = ULSHIFT(con1v2, tmp);
5338 goto add_icon;
5339 }
5340 }
5341 #ifdef TM_SHIFTAR
5342 opc = IL_ULSHIFTA;
5343 op2 = ad1ili(IL_IAMV, op2);
5344 #endif
5345 break;
5346
5347 case IL_URSHIFT:
5348 if (ncons & 2) {
5349 con2v2 = con2v2 & 31;
5350 if (con2v2 == 0)
5351 return op1;
5352 }
5353 if (ncons == 2) {
5354 if (cons2 == stb.i0)
5355 return op1;
5356 } else if (ncons == 3) {
5357 tmp = con2v2;
5358 if (SHIFTOK(tmp)) {
5359 if (ishft) {
5360 res.numi[1] = ARSHIFT(con1v2, tmp);
5361 } else {
5362 res.numi[1] = URSHIFT(con1v2, tmp);
5363 }
5364 goto add_icon;
5365 }
5366 }
5367 #ifdef TM_SHIFTAR
5368 opc = IL_URSHIFTA;
5369 op2 = ad1ili(IL_IAMV, op2);
5370 #endif
5371 break;
5372 #ifdef TM_SHIFTAR
5373 case IL_USHIFTA:
5374 break;
5375 #endif
5376 case IL_ARSHIFT:
5377 if (ncons & 2) {
5378 con2v2 = con2v2 & 31;
5379 if (con2v2 == 0)
5380 return op1;
5381 }
5382 if (ncons == 2) {
5383 if (cons2 == stb.i0)
5384 return op1;
5385 } else if (ncons == 3) {
5386 tmp = con2v2;
5387 if (SHIFTOK(tmp)) {
5388 res.numi[1] = ARSHIFT(con1v2, tmp);
5389 goto add_icon;
5390 }
5391 }
5392 #ifdef TM_SHIFTAR
5393 opc = IL_ARSHIFTA;
5394 op2 = ad1ili(IL_IAMV, op2);
5395 #endif
5396 break;
5397
5398 case IL_KLSHIFT:
5399 if (ncons & 2) {
5400 con2v2 = con2v2 & 63;
5401 if (con2v2 == 0)
5402 return op1;
5403 }
5404 if ((ncons & 2) && cons2 == stb.i0)
5405 return op1;
5406 if (ncons == 3) {
5407 tmp = con2v2;
5408 GETVALI64(num1, cons1);
5409 ushf64(num1.numu, tmp, res.numu);
5410 goto add_kcon;
5411 }
5412 break;
5413
5414 case IL_KARSHIFT:
5415 if (ncons & 2) {
5416 con2v2 = con2v2 & 63;
5417 if (con2v2 == 0)
5418 return op1;
5419 }
5420 if (ncons == 2 && cons2 == stb.i0)
5421 return op1;
5422 if (ncons == 3) {
5423 tmp = con2v2;
5424 GETVALI64(num1, cons1);
5425 shf64(num1.numi, -tmp, res.numi);
5426 goto add_kcon;
5427 }
5428 break;
5429
5430 case IL_KURSHIFT:
5431 if (ncons & 2) {
5432 con2v2 = con2v2 & 63;
5433 if (con2v2 == 0)
5434 return op1;
5435 }
5436 if (ncons == 2 && cons2 == stb.i0)
5437 return op1;
5438 if (ncons == 3) {
5439 tmp = con2v2;
5440 GETVALI64(num1, cons1);
5441 ushf64(num1.numu, -tmp, res.numu);
5442 goto add_kcon;
5443 }
5444 break;
5445
5446 case IL_CSE: {
5447 static int csecnt = 0;
5448
5449 if (op2 == 0)
5450 return ad2ili(IL_CSE, op1, ++csecnt);
5451 if (ncons == 1 || ILI_OPC(op1) == opc)
5452 return op1;
5453 break;
5454 }
5455
5456 case IL_CSEKR:
5457 case IL_CSEIR:
5458 case IL_CSESP:
5459 case IL_CSEDP:
5460 case IL_CSEAR:
5461 case IL_CSECS:
5462 case IL_CSECD:
5463 #ifdef LONG_DOUBLE_FLOAT128
5464 case IL_FLOAT128CSE:
5465 #endif
5466 if (ncons == 1 || ILI_OPC(op1) == opc)
5467 return op1;
5468 break;
5469
5470 #ifdef TM_FIELD_INST
5471 case IL_MERGE:
5472 newili.opnd[3] = ilip->opnd[3];
5473 case IL_EXTRACT:
5474 newili.opnd[2] = ilip->opnd[2];
5475 break;
5476 #endif
5477
5478 case IL_FSIN:
5479 if (ncons == 1 && is_flt0(cons1)) {
5480 return op1;
5481 }
5482 if (XBIT_NEW_MATH_NAMES) {
5483 ilix = gen_sincos(opc, op1, IL_FSINCOS, IL_FNSIN, MTH_sin, DT_FLOAT,
5484 IL_spfunc);
5485 return ilix;
5486 }
5487 #if defined(PGOCL) || defined(TARGET_LLVM_ARM)
5488 break;
5489 #else
5490 if (flg.ieee) {
5491 (void)mk_prototype(MTH_I_SIN, "f pure", DT_FLOAT, 1, DT_FLOAT);
5492 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_SIN, 1, op1);
5493 return ad1altili(opc, op1, ilix);
5494 }
5495 #if defined(TARGET_LLVM_X8664)
5496 mk_prototype(fast_math("sin", 's', 's', FMTH_I_SIN), "f pure", DT_FLOAT, 1,
5497 DT_FLOAT);
5498 ilix = ad_func(IL_DFRSP, IL_QJSR, fast_math("sin", 's', 's', FMTH_I_SIN), 1,
5499 op1);
5500 ilix = ad1altili(opc, op1, ilix);
5501 return ilix;
5502 #elif defined(TARGET_POWER)
5503 mk_prototype(fast_math("sin", 's', 's', MTH_I_SIN), "f pure", DT_FLOAT, 1,
5504 DT_FLOAT);
5505 ilix = ad_func(IL_DFRSP, IL_QJSR, fast_math("sin", 's', 's', MTH_I_SIN), 1,
5506 op1);
5507 return ad1altili(opc, op1, ilix);
5508 #else
5509 (void)mk_prototype(MTH_I_SIN, "f pure", DT_FLOAT, 1, DT_FLOAT);
5510 ilix = ad_func(IL_spfunc, IL_QJSR, MTH_I_SIN, 1, op1);
5511 return ad1altili(opc, op1, ilix);
5512 #endif
5513 #endif
5514 break;
5515
5516 case IL_DSIN:
5517 if (ncons == 1 && is_dbl0(cons1)) {
5518 return op1;
5519 }
5520 if (XBIT_NEW_MATH_NAMES) {
5521 ilix = gen_sincos(opc, op1, IL_DSINCOS, IL_DNSIN, MTH_sin, DT_DBLE,
5522 IL_dpfunc);
5523 return ilix;
5524 }
5525 #if defined(PGOCL) || defined(TARGET_LLVM_ARM)
5526 break;
5527 #else
5528 if (flg.ieee) {
5529 (void)mk_prototype(MTH_I_DSIN, "f pure", DT_DBLE, 1, DT_DBLE);
5530 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DSIN, 1, op1);
5531 return ad1altili(opc, op1, ilix);
5532 }
5533 #if defined(TARGET_LLVM_X8664)
5534 mk_prototype(fast_math("sin", 's', 'd', FMTH_I_DSIN), "f pure", DT_DBLE, 1,
5535 DT_DBLE);
5536 ilix = ad_func(IL_DFRDP, IL_QJSR, fast_math("sin", 's', 'd', FMTH_I_DSIN),
5537 1, op1);
5538 return ad1altili(opc, op1, ilix);
5539 #elif defined(TARGET_POWER)
5540 mk_prototype(fast_math("sin", 's', 'd', MTH_I_DSIN), "f pure", DT_DBLE, 1,
5541 DT_DBLE);
5542 ilix = ad_func(IL_DFRDP, IL_QJSR, fast_math("sin", 's', 'd', MTH_I_DSIN), 1,
5543 op1);
5544 return ad1altili(opc, op1, ilix);
5545 #else
5546 (void)mk_prototype(MTH_I_DSIN, "f pure", DT_DBLE, 1, DT_DBLE);
5547 ilix = ad_func(IL_dpfunc, IL_QJSR, MTH_I_DSIN, 1, op1);
5548 return ad1altili(opc, op1, ilix);
5549 #endif
5550 #endif
5551 break;
5552
5553 case IL_FCOS:
5554 if (ncons == 1 && is_flt0(cons1)) {
5555 return ad1ili(IL_FCON, stb.flt1);
5556 }
5557 if (XBIT_NEW_MATH_NAMES) {
5558 ilix = gen_sincos(opc, op1, IL_FSINCOS, IL_FNCOS, MTH_cos, DT_FLOAT,
5559 IL_spfunc);
5560 return ilix;
5561 }
5562 #if defined(PGOCL) || defined(TARGET_LLVM_ARM)
5563 break;
5564 #else
5565 if (flg.ieee) {
5566 (void)mk_prototype(MTH_I_COS, "f pure", DT_FLOAT, 1, DT_FLOAT);
5567 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_COS, 1, op1);
5568 return ad1altili(opc, op1, ilix);
5569 }
5570 #if defined(TARGET_LLVM_X8664)
5571 mk_prototype(fast_math("cos", 's', 's', FMTH_I_COS), "f pure", DT_FLOAT, 1,
5572 DT_FLOAT);
5573 ilix = ad_func(IL_DFRSP, IL_QJSR, fast_math("cos", 's', 's', FMTH_I_COS), 1,
5574 op1);
5575 return ad1altili(opc, op1, ilix);
5576 return ilix;
5577 #elif defined(TARGET_POWER)
5578 mk_prototype(fast_math("cos", 's', 's', MTH_I_COS), "f pure", DT_FLOAT, 1,
5579 DT_FLOAT);
5580 ilix = ad_func(IL_DFRSP, IL_QJSR, fast_math("cos", 's', 's', MTH_I_COS), 1,
5581 op1);
5582 return ad1altili(opc, op1, ilix);
5583 #else
5584 (void)mk_prototype(MTH_I_COS, "f pure", DT_FLOAT, 1, DT_FLOAT);
5585 ilix = ad_func(IL_spfunc, IL_QJSR, MTH_I_COS, 1, op1);
5586 return ad1altili(opc, op1, ilix);
5587 #endif
5588 #endif
5589 break;
5590
5591 case IL_DCOS:
5592 if (ncons == 1 && is_dbl0(cons1)) {
5593 return ad1ili(IL_DCON, stb.dbl1);
5594 }
5595 if (XBIT_NEW_MATH_NAMES) {
5596 ilix = gen_sincos(opc, op1, IL_DSINCOS, IL_DNCOS, MTH_cos, DT_DBLE,
5597 IL_dpfunc);
5598 return ilix;
5599 }
5600 #if defined(PGOCL) || defined(TARGET_LLVM_ARM)
5601 break;
5602 #else
5603 if (flg.ieee) {
5604 (void)mk_prototype(MTH_I_DCOS, "f pure", DT_DBLE, 1, DT_DBLE);
5605 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DCOS, 1, op1);
5606 return ad1altili(opc, op1, ilix);
5607 }
5608 #if defined(TARGET_POWER)
5609 mk_prototype(fast_math("cos", 's', 'd', MTH_I_DCOS), "f pure", DT_DBLE, 1,
5610 DT_DBLE);
5611 ilix = ad_func(IL_DFRDP, IL_QJSR, fast_math("cos", 's', 'd', MTH_I_DCOS), 1,
5612 op1);
5613 return ad1altili(opc, op1, ilix);
5614 #else
5615 (void)mk_prototype(MTH_I_DCOS, "f pure", DT_DBLE, 1, DT_DBLE);
5616 ilix = ad_func(IL_dpfunc, IL_QJSR, MTH_I_DCOS, 1, op1);
5617 return ad1altili(opc, op1, ilix);
5618 #endif
5619 #endif
5620 break;
5621
5622 case IL_FTAN:
5623 if (XBIT_NEW_MATH_NAMES) {
5624 fname = make_math(MTH_tan, &funcsptr, 1, false, DT_FLOAT, 1, DT_FLOAT);
5625 ilix = ad_func(IL_spfunc, IL_QJSR, fname, 1, op1);
5626 ilix = ad1altili(opc, op1, ilix);
5627 return ilix;
5628 }
5629 #if defined(TARGET_X8664)
5630 if (!flg.ieee && TEST_FEATURE(FEATURE_AVX)) {
5631 (void)mk_prototype(relaxed_math("tan", 's', 's', MTH_I_TAN), "f pure",
5632 DT_FLOAT, 1, DT_FLOAT);
5633 ilix = ad_func(IL_DFRSP, IL_QJSR,
5634 relaxed_math("tan", 's', 's', MTH_I_TAN), 1, op1);
5635 ilix = ad1altili(opc, op1, ilix);
5636 return ilix;
5637 }
5638 #endif
5639 #if defined(TARGET_POWER)
5640 if (flg.ieee) {
5641 (void)mk_prototype(MTH_I_TAN, "f pure", DT_FLOAT, 1, DT_FLOAT);
5642 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_TAN, 1, op1);
5643 } else {
5644 (void)mk_prototype(fast_math("tan", 's', 's', MTH_I_TAN), "f pure",
5645 DT_FLOAT, 1, DT_FLOAT);
5646 ilix = ad_func(IL_DFRSP, IL_QJSR, fast_math("tan", 's', 's', MTH_I_TAN),
5647 1, op1);
5648 }
5649 return ad1altili(opc, op1, ilix);
5650 #else
5651 (void)mk_prototype(MTH_I_TAN, "f pure", DT_FLOAT, 1, DT_FLOAT);
5652 ilix = ad_func(IL_spfunc, IL_QJSR, MTH_I_TAN, 1, op1);
5653 return ad1altili(opc, op1, ilix);
5654 #endif
5655
5656 case IL_DTAN:
5657 if (XBIT_NEW_MATH_NAMES) {
5658 fname = make_math(MTH_tan, &funcsptr, 1, false, DT_DBLE, 1, DT_DBLE);
5659 ilix = ad_func(IL_dpfunc, IL_QJSR, fname, 1, op1);
5660 ilix = ad1altili(opc, op1, ilix);
5661 return ilix;
5662 }
5663 #if defined(TARGET_X8664)
5664 if (!flg.ieee && TEST_FEATURE(FEATURE_AVX)) {
5665 if (!XBIT(36, 0x04)) {
5666 (void)mk_prototype(fast_math("tan", 's', 'd', MTH_I_DTAN), "f pure",
5667 DT_DBLE, 1, DT_DBLE);
5668 ilix = ad_func(IL_DFRDP, IL_QJSR,
5669 fast_math("tan", 's', 'd', MTH_I_DTAN), 1, op1);
5670 } else {
5671 (void)mk_prototype(relaxed_math("tan", 's', 'd', MTH_I_DTAN), "f pure",
5672 DT_DBLE, 1, DT_DBLE);
5673 ilix = ad_func(IL_DFRDP, IL_QJSR,
5674 relaxed_math("tan", 's', 'd', MTH_I_DTAN), 1, op1);
5675 }
5676 ilix = ad1altili(opc, op1, ilix);
5677 return ilix;
5678 }
5679 #endif
5680 #if defined(TARGET_POWER)
5681 if (flg.ieee) {
5682 (void)mk_prototype(MTH_I_DTAN, "f pure", DT_DBLE, 1, DT_DBLE);
5683 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DTAN, 1, op1);
5684 } else {
5685 (void)mk_prototype(fast_math("tan", 's', 'd', MTH_I_DTAN), "f pure",
5686 DT_DBLE, 1, DT_DBLE);
5687 ilix = ad_func(IL_DFRDP, IL_QJSR, fast_math("tan", 's', 'd', MTH_I_DTAN),
5688 1, op1);
5689 }
5690 return ad1altili(opc, op1, ilix);
5691 #else
5692 (void)mk_prototype(MTH_I_DTAN, "f pure", DT_DBLE, 1, DT_DBLE);
5693 ilix = ad_func(IL_dpfunc, IL_QJSR, MTH_I_DTAN, 1, op1);
5694 return ad1altili(opc, op1, ilix);
5695 #endif
5696
5697 case IL_FATAN:
5698 if (ncons == 1) {
5699 xfatan(con1v2, &res.numi[1]);
5700 goto add_rcon;
5701 }
5702 if (XBIT_NEW_MATH_NAMES) {
5703 fname = make_math(MTH_atan, &funcsptr, 1, false, DT_FLOAT, 1, DT_FLOAT);
5704 ilix = ad_func(IL_spfunc, IL_QJSR, fname, 1, op1);
5705 ilix = ad1altili(opc, op1, ilix);
5706 return ilix;
5707 }
5708 #if defined(TARGET_X8664)
5709 if (!flg.ieee) {
5710 (void)mk_prototype(gnr_math("atan", 's', 's', MTH_I_ATAN, 0), "f pure",
5711 DT_FLOAT, 1, DT_FLOAT);
5712 ilix = ad_func(IL_DFRSP, IL_QJSR,
5713 gnr_math("atan", 's', 's', MTH_I_ATAN, 0), 1, op1);
5714 ilix = ad1altili(opc, op1, ilix);
5715 return ilix;
5716 }
5717 #endif
5718 #if defined(TARGET_POWER)
5719 if (flg.ieee) {
5720 (void)mk_prototype(MTH_I_ATAN, "f pure", DT_FLOAT, 1, DT_FLOAT);
5721 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_ATAN, 1, op1);
5722 } else {
5723 (void)mk_prototype(fast_math("atan", 's', 's', MTH_I_ATAN), "f pure",
5724 DT_FLOAT, 1, DT_FLOAT);
5725 ilix = ad_func(IL_DFRSP, IL_QJSR, fast_math("atan", 's', 's', MTH_I_ATAN),
5726 1, op1);
5727 }
5728 return ad1altili(opc, op1, ilix);
5729 #endif
5730 (void)mk_prototype(MTH_I_ATAN, "f pure", DT_FLOAT, 1, DT_FLOAT);
5731 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_ATAN, 1, op1);
5732 return ad1altili(opc, op1, ilix);
5733 break;
5734
5735 case IL_DATAN:
5736 if (ncons == 1) {
5737 GETVAL64(num1, cons1);
5738 xdatan(num1.numd, res.numd);
5739 goto add_dcon;
5740 }
5741 if (XBIT_NEW_MATH_NAMES) {
5742 fname = make_math(MTH_atan, &funcsptr, 1, false, DT_DBLE, 1, DT_DBLE);
5743 ilix = ad_func(IL_dpfunc, IL_QJSR, fname, 1, op1);
5744 ilix = ad1altili(opc, op1, ilix);
5745 return ilix;
5746 }
5747 #if defined(TARGET_X8664)
5748 if (!flg.ieee) {
5749 (void)mk_prototype(gnr_math("atan", 's', 'd', MTH_I_DATAN, 0), "f pure",
5750 DT_DBLE, 1, DT_DBLE);
5751 ilix = ad_func(IL_DFRDP, IL_QJSR,
5752 gnr_math("atan", 's', 'd', MTH_I_DATAN, 0), 1, op1);
5753 ilix = ad1altili(opc, op1, ilix);
5754 return ilix;
5755 }
5756 #endif
5757 #if defined(TARGET_POWER)
5758 if (flg.ieee) {
5759 (void)mk_prototype(MTH_I_DATAN, "f pure", DT_DBLE, 1, DT_DBLE);
5760 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DATAN, 1, op1);
5761 } else {
5762 (void)mk_prototype(fast_math("atan", 's', 'd', MTH_I_DATAN), "f pure",
5763 DT_DBLE, 1, DT_DBLE);
5764 ilix = ad_func(IL_DFRDP, IL_QJSR,
5765 fast_math("atan", 's', 'd', MTH_I_DATAN), 1, op1);
5766 }
5767 return ad1altili(opc, op1, ilix);
5768 #else
5769 (void)mk_prototype(MTH_I_DATAN, "f pure", DT_DBLE, 1, DT_DBLE);
5770 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DATAN, 1, op1);
5771 return ad1altili(opc, op1, ilix);
5772 #endif
5773 break;
5774
5775 case IL_FACOS:
5776 if (XBIT_NEW_MATH_NAMES) {
5777 fname = make_math(MTH_acos, &funcsptr, 1, false, DT_FLOAT, 1, DT_FLOAT);
5778 ilix = ad_func(IL_spfunc, IL_QJSR, fname, 1, op1);
5779 ilix = ad1altili(opc, op1, ilix);
5780 return ilix;
5781 }
5782 (void)mk_prototype(MTH_I_ACOS, "f pure", DT_FLOAT, 1, DT_FLOAT);
5783 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_ACOS, 1, op1);
5784 return ad1altili(opc, op1, ilix);
5785 break;
5786
5787 case IL_FASIN:
5788 if (XBIT_NEW_MATH_NAMES) {
5789 fname = make_math(MTH_asin, &funcsptr, 1, false, DT_FLOAT, 1, DT_FLOAT);
5790 ilix = ad_func(IL_spfunc, IL_QJSR, fname, 1, op1);
5791 ilix = ad1altili(opc, op1, ilix);
5792 return ilix;
5793 }
5794 (void)mk_prototype(MTH_I_ASIN, "f pure", DT_FLOAT, 1, DT_FLOAT);
5795 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_ASIN, 1, op1);
5796 return ad1altili(opc, op1, ilix);
5797 break;
5798
5799 case IL_FATAN2:
5800 if (XBIT_NEW_MATH_NAMES) {
5801 fname = make_math(MTH_atan2, &funcsptr, 1, false, DT_FLOAT, 2, DT_FLOAT,
5802 DT_FLOAT);
5803 ilix = ad_func(IL_spfunc, IL_QJSR, fname, 2, op1, op2);
5804 ilix = ad2altili(opc, op1, op2, ilix);
5805 return ilix;
5806 }
5807 (void)mk_prototype(MTH_I_ATAN2, "f pure", DT_FLOAT, 2, DT_FLOAT, DT_FLOAT);
5808 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_ATAN2, 2, op1, op2);
5809 return ad2altili(opc, op1, op2, ilix);
5810 break;
5811
5812 case IL_DACOS:
5813 if (XBIT_NEW_MATH_NAMES) {
5814 fname = make_math(MTH_acos, &funcsptr, 1, false, DT_DBLE, 1, DT_DBLE);
5815 ilix = ad_func(IL_dpfunc, IL_QJSR, fname, 1, op1);
5816 ilix = ad1altili(opc, op1, ilix);
5817 return ilix;
5818 }
5819 (void)mk_prototype(MTH_I_DACOS, "f pure", DT_DBLE, 1, DT_DBLE);
5820 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DACOS, 1, op1);
5821 return ad1altili(opc, op1, ilix);
5822 break;
5823
5824 case IL_DASIN:
5825 if (XBIT_NEW_MATH_NAMES) {
5826 fname = make_math(MTH_asin, &funcsptr, 1, false, DT_DBLE, 2, DT_DBLE,
5827 DT_DBLE);
5828 ilix = ad_func(IL_dpfunc, IL_QJSR, fname, 1, op1);
5829 ilix = ad1altili(opc, op1, ilix);
5830 return ilix;
5831 }
5832 (void)mk_prototype(MTH_I_DASIN, "f pure", DT_DBLE, 1, DT_DBLE);
5833 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DASIN, 1, op1);
5834 return ad1altili(opc, op1, ilix);
5835 break;
5836
5837 case IL_DATAN2:
5838 if (XBIT_NEW_MATH_NAMES) {
5839 fname = make_math(MTH_atan2, &funcsptr, 1, false, DT_DBLE, 2, DT_DBLE,
5840 DT_DBLE);
5841 ilix = ad_func(IL_dpfunc, IL_QJSR, fname, 2, op1, op2);
5842 ilix = ad2altili(opc, op1, op2, ilix);
5843 return ilix;
5844 }
5845 (void)mk_prototype(MTH_I_DATAN2, "f pure", DT_DBLE, 2, DT_DBLE, DT_DBLE);
5846 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DATAN2, 2, op1, op2);
5847 return ad2altili(opc, op1, op2, ilix);
5848 break;
5849
5850 case IL_FLOG:
5851 if (XBIT_NEW_MATH_NAMES) {
5852 fname = make_math(MTH_log, &funcsptr, 1, false, DT_FLOAT, 1, DT_FLOAT);
5853 ilix = ad_func(IL_spfunc, IL_QJSR, fname, 1, op1);
5854 ilix = ad1altili(opc, op1, ilix);
5855 return ilix;
5856 }
5857 #if defined(TARGET_X8664)
5858 if (!flg.ieee) {
5859 (void)mk_prototype(gnr_math("log", 's', 's', FMTH_I_ALOG, 0), "f pure",
5860 DT_FLOAT, 1, DT_FLOAT);
5861 ilix = ad_func(IL_DFRSP, IL_QJSR,
5862 gnr_math("log", 's', 's', FMTH_I_ALOG, 0), 1, op1);
5863 } else {
5864 (void)mk_prototype(MTH_I_ALOG, "f pure", DT_FLOAT, 1, DT_FLOAT);
5865 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_ALOG, 1, op1);
5866 }
5867 ilix = ad1altili(opc, op1, ilix);
5868 return ilix;
5869 #endif
5870 #if !defined(PGOCL) && !defined(TARGET_LLVM_ARM)
5871 #if defined(TARGET_POWER)
5872 if (flg.ieee) {
5873 (void)mk_prototype(MTH_I_LOG, "f pure", DT_FLOAT, 1, DT_FLOAT);
5874 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_LOG, 1, op1);
5875 } else {
5876 (void)mk_prototype(fast_math("log", 's', 's', MTH_I_LOG), "f pure",
5877 DT_FLOAT, 1, DT_FLOAT);
5878 ilix = ad_func(IL_DFRSP, IL_QJSR, fast_math("log", 's', 's', MTH_I_LOG),
5879 1, op1);
5880 }
5881 return ad1altili(opc, op1, ilix);
5882 #else
5883 (void)mk_prototype(MTH_I_ALOG, "f pure", DT_FLOAT, 1, DT_FLOAT);
5884 ilix = ad_func(IL_spfunc, IL_QJSR, MTH_I_ALOG, 1, op1);
5885 ilix = ad1altili(opc, op1, ilix);
5886 return ilix;
5887 #endif
5888 #endif /*if !defined(PGOCL) && !defined(TARGET_LLVM_ARM) */
5889 break;
5890
5891 case IL_DLOG:
5892 if (XBIT_NEW_MATH_NAMES) {
5893 fname = make_math(MTH_log, &funcsptr, 1, false, DT_DBLE, 1, DT_DBLE);
5894 ilix = ad_func(IL_dpfunc, IL_QJSR, fname, 1, op1);
5895 ilix = ad1altili(opc, op1, ilix);
5896 return ilix;
5897 }
5898 #if defined(TARGET_X8664)
5899 if (!flg.ieee) {
5900 (void)mk_prototype(gnr_math("log", 's', 'd', FMTH_I_DLOG, 0), "f pure",
5901 DT_DBLE, 1, DT_DBLE);
5902 ilix = ad_func(IL_DFRDP, IL_QJSR,
5903 gnr_math("log", 's', 'd', FMTH_I_DLOG, 0), 1, op1);
5904 } else {
5905 (void)mk_prototype(MTH_I_DLOG, "f pure", DT_DBLE, 1, DT_DBLE);
5906 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DLOG, 1, op1);
5907 }
5908 ilix = ad1altili(opc, op1, ilix);
5909 return ilix;
5910 #endif
5911 #if !defined(PGOCL) && !defined(TARGET_LLVM_ARM)
5912 #if defined(TARGET_POWER)
5913 if (flg.ieee) {
5914 (void)mk_prototype(MTH_I_DLOG, "f pure", DT_DBLE, 1, DT_DBLE);
5915 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DLOG, 1, op1);
5916 } else {
5917 (void)mk_prototype(fast_math("log", 's', 'd', MTH_I_DLOG), "f pure",
5918 DT_DBLE, 1, DT_DBLE);
5919 ilix = ad_func(IL_DFRDP, IL_QJSR, fast_math("log", 's', 'd', MTH_I_DLOG),
5920 1, op1);
5921 }
5922 return ad1altili(opc, op1, ilix);
5923 #else
5924 (void)mk_prototype(MTH_I_DLOG, "f pure", DT_DBLE, 1, DT_DBLE);
5925 ilix = ad_func(IL_dpfunc, IL_QJSR, MTH_I_DLOG, 1, op1);
5926 ilix = ad1altili(opc, op1, ilix);
5927 return ilix;
5928 #endif
5929 #endif /*if !defined(PGOCL) && !defined(TARGET_LLVM_ARM) */
5930 break;
5931
5932 case IL_FLOG10:
5933 if (XBIT_NEW_MATH_NAMES) {
5934 fname = make_math(MTH_log10, &funcsptr, 1, false, DT_FLOAT, 1, DT_FLOAT);
5935 ilix = ad_func(IL_spfunc, IL_QJSR, fname, 1, op1);
5936 ilix = ad1altili(opc, op1, ilix);
5937 return ilix;
5938 }
5939 #if defined(TARGET_X8664)
5940 if (!flg.ieee) {
5941 (void)mk_prototype(fast_math("log10", 's', 's', FMTH_I_ALOG10), "f pure",
5942 DT_FLOAT, 1, DT_FLOAT);
5943 ilix = ad_func(IL_DFRSP, IL_QJSR,
5944 fast_math("log10", 's', 's', FMTH_I_ALOG10), 1, op1);
5945 } else {
5946 (void)mk_prototype(MTH_I_ALOG10, "f pure", DT_FLOAT, 1, DT_FLOAT);
5947 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_ALOG10, 1, op1);
5948 }
5949 ilix = ad1altili(opc, op1, ilix);
5950 return ilix;
5951 #endif
5952 #if defined(TARGET_LLVM) && !defined(PGOCL) && !defined(TARGET_LLVM_ARM)
5953 (void)mk_prototype(MTH_I_ALOG10, "f pure", DT_FLOAT, 1, DT_FLOAT);
5954 ilix = ad_func(IL_spfunc, IL_QJSR, MTH_I_ALOG10, 1, op1);
5955 ilix = ad1altili(opc, op1, ilix);
5956 return ilix;
5957 #endif /*if TARGET_LLVM && !PGOCL && !TARGET_LLVM_ARM */
5958 break;
5959 case IL_DLOG10:
5960 if (XBIT_NEW_MATH_NAMES) {
5961 fname = make_math(MTH_log10, &funcsptr, 1, false, DT_DBLE, 1, DT_DBLE);
5962 ilix = ad_func(IL_dpfunc, IL_QJSR, fname, 1, op1);
5963 ilix = ad1altili(opc, op1, ilix);
5964 return ilix;
5965 }
5966 #if defined(TARGET_X8664)
5967 if (!flg.ieee) {
5968 (void)mk_prototype(fast_math("log10", 's', 'd', FMTH_I_DLOG10), "f pure",
5969 DT_DBLE, 1, DT_DBLE);
5970 ilix = ad_func(IL_DFRDP, IL_QJSR,
5971 fast_math("log10", 's', 'd', FMTH_I_DLOG10), 1, op1);
5972 } else {
5973 (void)mk_prototype(MTH_I_DLOG10, "f pure", DT_DBLE, 1, DT_DBLE);
5974 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DLOG10, 1, op1);
5975 }
5976 ilix = ad1altili(opc, op1, ilix);
5977 return ilix;
5978 #endif
5979 #if defined(TARGET_LLVM) && !defined(PGOCL) && !defined(TARGET_LLVM_ARM)
5980 (void)mk_prototype(MTH_I_DLOG10, "f pure", DT_DBLE, 1, DT_DBLE);
5981 ilix = ad_func(IL_dpfunc, IL_QJSR, MTH_I_DLOG10, 1, op1);
5982 ilix = ad1altili(opc, op1, ilix);
5983 return ilix;
5984 #endif /*if TARGET_LLVM && !PGOCL && !TARGET_LLVM_ARM */
5985 break;
5986
5987 case IL_FEXP:
5988 if (ncons == 1 && is_flt0(cons1)) {
5989 res.numi[1] = CONVAL2G(stb.flt1);
5990 goto add_rcon;
5991 }
5992 if (XBIT_NEW_MATH_NAMES) {
5993 fname = make_math(MTH_exp, &funcsptr, 1, false, DT_FLOAT, 1, DT_FLOAT);
5994 ilix = ad_func(IL_spfunc, IL_QJSR, fname, 1, op1);
5995 ilix = ad1altili(opc, op1, ilix);
5996 return ilix;
5997 }
5998 #if defined(TARGET_X8664)
5999 if (!flg.ieee) {
6000 if (XBIT_NEW_RELAXEDMATH) {
6001 (void)mk_prototype(relaxed_math("exp", 's', 's', FMTH_I_EXP), "f pure",
6002 DT_FLOAT, 1, DT_FLOAT);
6003 ilix = ad_func(IL_DFRSP, IL_QJSR,
6004 relaxed_math("exp", 's', 's', FMTH_I_EXP), 1, op1);
6005 } else {
6006 (void)mk_prototype(gnr_math("exp", 's', 's', FMTH_I_EXP, 0), "f pure",
6007 DT_FLOAT, 1, DT_FLOAT);
6008 ilix = ad_func(IL_DFRSP, IL_QJSR,
6009 gnr_math("exp", 's', 's', FMTH_I_EXP, 0), 1, op1);
6010 }
6011 } else {
6012 (void)mk_prototype(MTH_I_EXP, "f pure", DT_FLOAT, 1, DT_FLOAT);
6013 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_EXP, 1, op1);
6014 }
6015 ilix = ad1altili(opc, op1, ilix);
6016 return ilix;
6017 #endif
6018 #if !defined(PGOCL) && !defined(TARGET_LLVM_ARM)
6019 #if defined(TARGET_POWER)
6020 if (flg.ieee) {
6021 (void)mk_prototype(MTH_I_EXP, "f pure", DT_FLOAT, 1, DT_FLOAT);
6022 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_EXP, 1, op1);
6023 } else {
6024 (void)mk_prototype(fast_math("exp", 's', 's', MTH_I_EXP), "f pure",
6025 DT_FLOAT, 1, DT_FLOAT);
6026 ilix = ad_func(IL_DFRSP, IL_QJSR, fast_math("exp", 's', 's', MTH_I_EXP),
6027 1, op1);
6028 }
6029 return ad1altili(opc, op1, ilix);
6030 #else
6031 (void)mk_prototype(MTH_I_EXP, "f pure", DT_FLOAT, 1, DT_FLOAT);
6032 ilix = ad_func(IL_spfunc, IL_QJSR, MTH_I_EXP, 1, op1);
6033 ilix = ad1altili(opc, op1, ilix);
6034 return ilix;
6035 #endif
6036 #endif /*if !defined(PGOCL) && !defined(TARGET_LLVM_ARM) */
6037 break;
6038
6039 case IL_DEXP:
6040 if (ncons == 1 && is_dbl0(cons1)) {
6041 GETVAL64(res, stb.dbl1);
6042 goto add_dcon;
6043 }
6044 if (XBIT_NEW_MATH_NAMES) {
6045 fname = make_math(MTH_exp, &funcsptr, 1, false, DT_DBLE, 1, DT_DBLE);
6046 ilix = ad_func(IL_dpfunc, IL_QJSR, fname, 1, op1);
6047 ilix = ad1altili(opc, op1, ilix);
6048 return ilix;
6049 }
6050 #if defined(TARGET_X8664)
6051 if (!flg.ieee) {
6052 if (XBIT_NEW_RELAXEDMATH) {
6053 (void)mk_prototype(relaxed_math("exp", 's', 'd', FMTH_I_DEXP), "f pure",
6054 DT_DBLE, 1, DT_DBLE);
6055 ilix = ad_func(IL_DFRDP, IL_QJSR,
6056 relaxed_math("exp", 's', 'd', FMTH_I_DEXP), 1, op1);
6057 } else {
6058 /*
6059 * try the new naming convention -- only for exp
6060 */
6061 (void)mk_prototype(gnr_math("exp", 's', 'd', FMTH_I_DEXP, 0), "f pure",
6062 DT_DBLE, 1, DT_DBLE);
6063 ilix = ad_func(IL_DFRDP, IL_QJSR,
6064 gnr_math("exp", 's', 'd', FMTH_I_DEXP, 0), 1, op1);
6065 }
6066 } else {
6067 (void)mk_prototype(MTH_I_DEXP, "f pure", DT_DBLE, 1, DT_DBLE);
6068 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DEXP, 1, op1);
6069 }
6070 ilix = ad1altili(opc, op1, ilix);
6071 return ilix;
6072 #endif
6073 #if !defined(PGOCL) && !defined(TARGET_LLVM_ARM)
6074 #if defined(TARGET_POWER)
6075 if (flg.ieee) {
6076 (void)mk_prototype(MTH_I_DEXP, "f pure", DT_DBLE, 1, DT_DBLE);
6077 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DEXP, 1, op1);
6078 } else {
6079 (void)mk_prototype(fast_math("exp", 's', 'd', MTH_I_DEXP), "f pure",
6080 DT_DBLE, 1, DT_DBLE);
6081 ilix = ad_func(IL_DFRDP, IL_QJSR, fast_math("exp", 's', 'd', MTH_I_DEXP),
6082 1, op1);
6083 }
6084 return ad1altili(opc, op1, ilix);
6085 #else
6086 (void)mk_prototype(MTH_I_DEXP, "f pure", DT_DBLE, 1, DT_DBLE);
6087 ilix = ad_func(IL_dpfunc, IL_QJSR, MTH_I_DEXP, 1, op1);
6088 ilix = ad1altili(opc, op1, ilix);
6089 return ilix;
6090 #endif
6091 #endif /*if !defined(PGOCL) && !defined(TARGET_LLVM_ARM) */
6092 break;
6093
6094 /*
6095 * getting here for the ensuing cmplex intrinsics means XBIT_NEW_MATH_NAMES
6096 * is set
6097 */
6098 case IL_SCMPLXEXP:
6099 ilix = ad1mathfunc_cmplx(MTH_exp, opc, op1, DT_CMPLX, DT_CMPLX);
6100 return ilix;
6101
6102 case IL_SCMPLXCOS:
6103 ilix = ad1mathfunc_cmplx(MTH_cos, opc, op1, DT_CMPLX, DT_CMPLX);
6104 return ilix;
6105
6106 case IL_SCMPLXSIN:
6107 ilix = ad1mathfunc_cmplx(MTH_sin, opc, op1, DT_CMPLX, DT_CMPLX);
6108 return ilix;
6109
6110 case IL_SCMPLXTAN:
6111 ilix = ad1mathfunc_cmplx(MTH_tan, opc, op1, DT_CMPLX, DT_CMPLX);
6112 return ilix;
6113
6114 case IL_SCMPLXACOS:
6115 ilix = ad1mathfunc_cmplx(MTH_acos, opc, op1, DT_CMPLX, DT_CMPLX);
6116 return ilix;
6117
6118 case IL_SCMPLXASIN:
6119 ilix = ad1mathfunc_cmplx(MTH_asin, opc, op1, DT_CMPLX, DT_CMPLX);
6120 return ilix;
6121
6122 case IL_SCMPLXATAN:
6123 ilix = ad1mathfunc_cmplx(MTH_atan, opc, op1, DT_CMPLX, DT_CMPLX);
6124 return ilix;
6125
6126 case IL_SCMPLXCOSH:
6127 ilix = ad1mathfunc_cmplx(MTH_cosh, opc, op1, DT_CMPLX, DT_CMPLX);
6128 return ilix;
6129
6130 case IL_SCMPLXSINH:
6131 ilix = ad1mathfunc_cmplx(MTH_sinh, opc, op1, DT_CMPLX, DT_CMPLX);
6132 return ilix;
6133
6134 case IL_SCMPLXTANH:
6135 ilix = ad1mathfunc_cmplx(MTH_tanh, opc, op1, DT_CMPLX, DT_CMPLX);
6136 return ilix;
6137
6138 case IL_SCMPLXLOG:
6139 ilix = ad1mathfunc_cmplx(MTH_log, opc, op1, DT_CMPLX, DT_CMPLX);
6140 return ilix;
6141
6142 case IL_SCMPLXSQRT:
6143 ilix = ad1mathfunc_cmplx(MTH_sqrt, opc, op1, DT_CMPLX, DT_CMPLX);
6144 return ilix;
6145
6146 case IL_SCMPLXPOW:
6147 ilix =
6148 ad2mathfunc_cmplx(MTH_pow, opc, op1, op2, DT_CMPLX, DT_CMPLX, DT_CMPLX);
6149 return ilix;
6150
6151 case IL_SCMPLXPOWI:
6152 /**** ad2mathfunc_cmplx needs WORK for the integer argument ****/
6153 ilix =
6154 ad2mathfunc_cmplx(MTH_powi, opc, op1, op2, DT_CMPLX, DT_CMPLX, DT_INT);
6155 return ilix;
6156
6157 case IL_SCMPLXPOWK:
6158 /**** ad2mathfunc_cmplx needs WORK for the integer argument ****/
6159 ilix =
6160 ad2mathfunc_cmplx(MTH_powk, opc, op1, op2, DT_CMPLX, DT_CMPLX, DT_INT8);
6161 return ilix;
6162
6163 case IL_DCMPLXEXP:
6164 ilix = ad1mathfunc_cmplx(MTH_exp, opc, op1, DT_DCMPLX, DT_DCMPLX);
6165 return ilix;
6166
6167 case IL_DCMPLXCOS:
6168 ilix = ad1mathfunc_cmplx(MTH_cos, opc, op1, DT_DCMPLX, DT_DCMPLX);
6169 return ilix;
6170
6171 case IL_DCMPLXSIN:
6172 ilix = ad1mathfunc_cmplx(MTH_sin, opc, op1, DT_DCMPLX, DT_DCMPLX);
6173 return ilix;
6174
6175 case IL_DCMPLXTAN:
6176 ilix = ad1mathfunc_cmplx(MTH_tan, opc, op1, DT_DCMPLX, DT_DCMPLX);
6177 return ilix;
6178
6179 case IL_DCMPLXACOS:
6180 ilix = ad1mathfunc_cmplx(MTH_acos, opc, op1, DT_DCMPLX, DT_DCMPLX);
6181 return ilix;
6182
6183 case IL_DCMPLXASIN:
6184 ilix = ad1mathfunc_cmplx(MTH_asin, opc, op1, DT_DCMPLX, DT_DCMPLX);
6185 return ilix;
6186
6187 case IL_DCMPLXATAN:
6188 ilix = ad1mathfunc_cmplx(MTH_atan, opc, op1, DT_DCMPLX, DT_DCMPLX);
6189 return ilix;
6190
6191 case IL_DCMPLXCOSH:
6192 ilix = ad1mathfunc_cmplx(MTH_cosh, opc, op1, DT_DCMPLX, DT_DCMPLX);
6193 return ilix;
6194
6195 case IL_DCMPLXSINH:
6196 ilix = ad1mathfunc_cmplx(MTH_sinh, opc, op1, DT_DCMPLX, DT_DCMPLX);
6197 return ilix;
6198
6199 case IL_DCMPLXTANH:
6200 ilix = ad1mathfunc_cmplx(MTH_tanh, opc, op1, DT_DCMPLX, DT_DCMPLX);
6201 return ilix;
6202
6203 case IL_DCMPLXLOG:
6204 ilix = ad1mathfunc_cmplx(MTH_log, opc, op1, DT_DCMPLX, DT_DCMPLX);
6205 return ilix;
6206
6207 case IL_DCMPLXSQRT:
6208 ilix = ad1mathfunc_cmplx(MTH_sqrt, opc, op1, DT_DCMPLX, DT_DCMPLX);
6209 return ilix;
6210
6211 case IL_DCMPLXPOW:
6212 ilix = ad2mathfunc_cmplx(MTH_pow, opc, op1, op2, DT_DCMPLX, DT_DCMPLX,
6213 DT_DCMPLX);
6214 return ilix;
6215
6216 case IL_DCMPLXPOWI:
6217 /**** ad2mathfunc_cmplx needs WORK for the integer argument ****/
6218 ilix = ad2mathfunc_cmplx(MTH_powi, opc, op1, op2, DT_DCMPLX, DT_DCMPLX,
6219 DT_INT);
6220 return ilix;
6221
6222 case IL_DCMPLXPOWK:
6223 /**** ad2mathfunc_cmplx needs WORK for the integer argument ****/
6224 ilix = ad2mathfunc_cmplx(MTH_powk, opc, op1, op2, DT_DCMPLX, DT_DCMPLX,
6225 DT_INT8);
6226 return ilix;
6227
6228 case IL_JN:
6229 (void)mk_prototype(MTH_I_JN, "f pure", DT_FLOAT, 2, DT_INT, DT_FLOAT);
6230 ilix = ad_func(IL_spfunc, IL_QJSR, MTH_I_JN, 2, op1, op2);
6231 return ilix;
6232 break;
6233
6234 case IL_DJN:
6235 (void)mk_prototype(MTH_I_DJN, "f pure", DT_DBLE, 2, DT_INT, DT_DBLE);
6236 ilix = ad_func(IL_dpfunc, IL_QJSR, MTH_I_DJN, 2, op1, op2);
6237 return ilix;
6238 break;
6239
6240 case IL_YN:
6241 (void)mk_prototype(MTH_I_YN, "f pure", DT_FLOAT, 2, DT_INT, DT_FLOAT);
6242 ilix = ad_func(IL_spfunc, IL_QJSR, MTH_I_YN, 2, op1, op2);
6243 return ilix;
6244 break;
6245
6246 case IL_DYN:
6247 (void)mk_prototype(MTH_I_DYN, "f pure", DT_DBLE, 2, DT_INT, DT_DBLE);
6248 ilix = ad_func(IL_dpfunc, IL_QJSR, MTH_I_DYN, 2, op1, op2);
6249 return ilix;
6250 break;
6251
6252 case IL_IPOWI:
6253 if (ncons == 3) {
6254 res.numi[1] = _ipowi(con1v2, con2v2);
6255 goto add_icon;
6256 }
6257 if (ncons == 1 && con1v2 == 2) {
6258 tmp1 = ad_icon(1);
6259 tmp1 = ad2ili(IL_LSHIFT, tmp1, op2);
6260 /* generate ili which computes (((1)<<i) & ~((i)>>31)) */
6261 tmp = ad_icon(31);
6262 tmp = ad2ili(IL_ARSHIFT, op2, tmp);
6263 tmp = ad1ili(IL_NOT, tmp);
6264 ilix = ad2ili(IL_AND, tmp1, tmp);
6265 ilix = ad2altili(opc, op1, op2, ilix);
6266 return ilix;
6267 }
6268 ilix = ad_func(IL_DFRIR, IL_QJSR, MTH_I_IPOWI, 2, op1, op2);
6269 ilix = ad2altili(opc, op1, op2, ilix);
6270 return ilix;
6271 break;
6272
6273 #ifdef IL_KPOWI
6274 case IL_KPOWI:
6275 if (ncons == 1 && con1v1 == 0 && con1v2 == 2) {
6276 tmp1 = ad_kcon(0, 1);
6277 tmp1 = ad2ili(IL_KLSHIFT, tmp1, op2);
6278 #if defined(TARGET_X8664)
6279 /* use select ili to compute ( (i)>=0 ? 1<<(i) : 0 ) */
6280 ilix = ad2ili(IL_ICMPZ, op2, CC_LT);
6281 tmp = ad_kcon(0, 0);
6282 ilix = ad3ili(IL_KSELECT, ilix, tmp1, tmp);
6283 #else
6284 /* generate ili which computes (((1)<<i) & ~((i)>>63)) */
6285 tmp = ad_icon(63);
6286 tmp = ad2ili(IL_KARSHIFT, ad1ili(IL_IKMV, op2), tmp);
6287 tmp = ad1ili(IL_KNOT, tmp);
6288 ilix = ad2ili(IL_KAND, tmp1, tmp);
6289 ilix = ad2altili(opc, op1, op2, ilix);
6290 #endif
6291 return ilix;
6292 }
6293 (void)mk_prototype(MTH_I_KPOWI, "pure", DT_INT8, 2, DT_INT8, DT_INT);
6294 ilix = ad_func(IL_DFRKR, IL_QJSR, MTH_I_KPOWI, 2, op1, op2);
6295 ilix = ad2altili(opc, op1, op2, ilix);
6296 return ilix;
6297 #endif
6298
6299 #ifdef IL_KPOWK
6300 case IL_KPOWK:
6301 if (ncons == 1 && con1v1 == 0 && con1v2 == 2) {
6302 tmp1 = ad_kcon(0, 1);
6303 tmp1 = ad2ili(IL_KLSHIFT, tmp1, ad1ili(IL_KIMV, op2));
6304 #if defined(TARGET_X8664)
6305 /* use select ili to compute ( (i)>=0 ? 1<<(i) : 0 ) */
6306 ilix = ad2ili(IL_KCMPZ, op2, CC_LT);
6307 tmp = ad_kcon(0, 0);
6308 ilix = ad3ili(IL_KSELECT, ilix, tmp1, tmp);
6309 #else
6310 /* generate ili which computes (((1)<<i) & ~((i)>>63)) */
6311 tmp = ad_icon(63);
6312 tmp = ad2ili(IL_KARSHIFT, op2, tmp);
6313 tmp = ad1ili(IL_KNOT, tmp);
6314 ilix = ad2ili(IL_KAND, tmp1, tmp);
6315 ilix = ad2altili(opc, op1, op2, ilix);
6316 #endif
6317 return ilix;
6318 }
6319 (void)mk_prototype(MTH_I_KPOWK, "pure", DT_INT8, 2, DT_INT8, DT_INT8);
6320 ilix = ad_func(IL_DFRKR, IL_QJSR, MTH_I_KPOWK, 2, op1, op2);
6321 ilix = ad2altili(opc, op1, op2, ilix);
6322 return ilix;
6323 #endif
6324
6325 case IL_FPOWI:
6326 #define __MAXPOW 10
6327 /* Even with -Kieee OK to make 1 multiply and get exact answer,
6328 * instead of making an intrinsic call to pow(). Big performance gain.
6329 * That is why we check specifically for the power of 2 below.
6330 */
6331 if ((!flg.ieee || con2v2 == 1 || con2v2 == 2) &&
6332 ncons >= 2 && !XBIT(124, 0x200)) {
6333 if (con2v2 == 1)
6334 return op1;
6335 if (con2v2 > 1 && con2v2 <= __MAXPOW) {
6336 ilix = _xpowi(op1, con2v2, IL_FMUL);
6337 return ilix;
6338 }
6339 }
6340 if (XBIT_NEW_MATH_NAMES) {
6341 fname = make_math(MTH_powi, &funcsptr, 1, false, DT_FLOAT, 2, DT_FLOAT,
6342 DT_INT);
6343 ilix = ad_func(IL_spfunc, IL_QJSR, fname, 2, op1, op2);
6344 ilix = ad2altili(opc, op1, op2, ilix);
6345 return ilix;
6346 }
6347 (void)mk_prototype(MTH_I_RPOWI, "f pure", DT_FLOAT, 2, DT_FLOAT, DT_INT);
6348 ilix = ad_func(IL_spfunc, IL_QJSR, MTH_I_RPOWI, 2, op1, op2);
6349 ilix = ad2altili(opc, op1, op2, ilix);
6350 return ilix;
6351 case IL_FPOWK:
6352 if ((!flg.ieee || con2v2 == 1 || con2v2 == 2) &&
6353 ncons >= 2 && !XBIT(124, 0x200) && con2v1 == 0) {
6354 if (con2v2 == 1)
6355 return op1;
6356 if (con2v2 > 1 && con2v2 <= __MAXPOW) {
6357 ilix = _xpowi(op1, con2v2, IL_FMUL);
6358 return ilix;
6359 }
6360 }
6361 if (XBIT_NEW_MATH_NAMES) {
6362 fname = make_math(MTH_powk, &funcsptr, 1, false, DT_FLOAT, 2, DT_FLOAT,
6363 DT_INT8);
6364 ilix = ad_func(IL_spfunc, IL_QJSR, fname, 2, op1, op2);
6365 ilix = ad2altili(opc, op1, op2, ilix);
6366 return ilix;
6367 }
6368 (void)mk_prototype(MTH_I_RPOWK, "f pure", DT_FLOAT, 2, DT_FLOAT, DT_INT8);
6369 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_RPOWK, 2, op1, op2);
6370 ilix = ad2altili(opc, op1, op2, ilix);
6371 return ilix;
6372 case IL_FPOWF:
6373 if (!flg.ieee && ncons >= 2) {
6374 if (con2v2 == 0x3e800000) {
6375 /* x ** .25 -> sqrt(sqrt(x)) */
6376 ilix = ad1ili(IL_FSQRT, op1);
6377 ilix = ad1ili(IL_FSQRT, ilix);
6378 return ilix;
6379 }
6380 if (con2v2 == 0x3f000000) {
6381 /* x ** 0.5 -> sqrt(x) */
6382 ilix = ad1ili(IL_FSQRT, op1);
6383 return ilix;
6384 }
6385 if (!do_newton_sqrt() && con2v2 == 0x3f400000) {
6386 /* x ** .75 -> sqrt(x) * sqrt(sqrt(x)) */
6387 ilix = ad1ili(IL_FSQRT, op1);
6388 op2 = ad1ili(IL_FSQRT, ilix);
6389 ilix = ad2ili(IL_FMUL, ilix, op2);
6390 return ilix;
6391 }
6392 if (con2v2 == 0x40200000) {
6393 /* x ** 2.5 -> x * x * sqrt(x)) */
6394 ilix = ad2ili(IL_FMUL, op1, op1);
6395 op2 = ad1ili(IL_FSQRT, op1);
6396 ilix = ad2ili(IL_FMUL, ilix, op2);
6397 return ilix;
6398 }
6399 if (con2v2 == 0x3fc00000) {
6400 /* x ** 1.5 -> sqrt(x)*x */
6401 ilix = ad1ili(IL_FSQRT, op1);
6402 ilix = ad2ili(IL_FMUL, op1, ilix);
6403 return ilix;
6404 }
6405 #if defined(TARGET_X8664)
6406 if (con2v2 == 0x3eaaaaab && XBIT(15, 0x80000000)) {
6407 /* x ** (1./3.) */
6408 ilix = ad_func(IL_DFRSP, IL_QJSR, fmth_name(FMTH_I_CBRT), 1, op1);
6409 ilix = ad2altili(opc, op1, op2, ilix);
6410 return ilix;
6411 }
6412 #endif
6413 }
6414 is_int = xfisint(con2v2, &pw);
6415 if ((!flg.ieee || pw == 1 || pw == 2) &&
6416 ncons >= 2 && is_int && !XBIT(124, 0x40000)) {
6417 ilix = ad2ili(IL_FPOWI, op1, ad_icon(pw));
6418 return ilix;
6419 }
6420 if (XBIT_NEW_MATH_NAMES) {
6421 fname = make_math(MTH_pow, &funcsptr, 1, false, DT_FLOAT, 2, DT_FLOAT,
6422 DT_FLOAT);
6423 ilix = ad_func(IL_spfunc, IL_QJSR, fname, 2, op1, op2);
6424 ilix = ad2altili(opc, op1, op2, ilix);
6425 return ilix;
6426 }
6427 #if defined(TARGET_X8664)
6428 if (!flg.ieee) {
6429 if (XBIT_NEW_RELAXEDMATH) {
6430 (void)mk_prototype(relaxed_math("pow", 's', 's', FMTH_I_RPOWF),
6431 "f pure", DT_FLOAT, 2, DT_FLOAT, DT_FLOAT);
6432 ilix =
6433 ad_func(IL_DFRSP, IL_QJSR,
6434 relaxed_math("pow", 's', 's', FMTH_I_RPOWF), 2, op1, op2);
6435 } else {
6436 (void)mk_prototype(gnr_math("pow", 's', 's', FMTH_I_RPOWF, 0), "f_pure",
6437 DT_FLOAT, 2, DT_FLOAT, DT_FLOAT);
6438 ilix = ad_func(IL_DFRSP, IL_QJSR,
6439 gnr_math("pow", 's', 's', FMTH_I_RPOWF, 0), 2, op1, op2);
6440 }
6441 } else
6442 #endif
6443 {
6444 #if defined(TARGET_POWER)
6445 if (flg.ieee) {
6446 mk_prototype(MTH_I_RPOWF, "f_pure", DT_FLOAT, 2, DT_FLOAT, DT_FLOAT);
6447 ilix = ad_func(IL_DFRSP, IL_QJSR, MTH_I_RPOWF, 2, op1, op2);
6448 } else {
6449 (void)mk_prototype(fast_math("pow", 's', 's', MTH_I_RPOWF), "f pure",
6450 DT_FLOAT, 2, DT_FLOAT, DT_FLOAT);
6451 ilix = ad_func(IL_DFRSP, IL_QJSR,
6452 fast_math("pow", 's', 's', MTH_I_RPOWF), 2, op1, op2);
6453 }
6454 #else
6455 mk_prototype(MTH_I_RPOWF, "f pure", DT_FLOAT, 2, DT_FLOAT, DT_FLOAT);
6456 ilix = ad_func(IL_spfunc, IL_QJSR, MTH_I_RPOWF, 2, op1, op2);
6457 #endif
6458 }
6459 ilix = ad2altili(opc, op1, op2, ilix);
6460 return ilix;
6461
6462 case IL_DPOWI:
6463 if ((!flg.ieee || con2v2 == 1 || con2v2 == 2)
6464 && ncons >= 2 && !XBIT(124, 0x200)) {
6465 if (con2v2 == 1)
6466 return op1;
6467 if (con2v2 > 1 && con2v2 <= __MAXPOW) {
6468 ilix = _xpowi(op1, con2v2, IL_DMUL);
6469 return ilix;
6470 }
6471 }
6472 if (XBIT_NEW_MATH_NAMES) {
6473 fname =
6474 make_math(MTH_powi, &funcsptr, 1, false, DT_DBLE, 2, DT_DBLE, DT_INT);
6475 ilix = ad_func(IL_dpfunc, IL_QJSR, fname, 2, op1, op2);
6476 ilix = ad2altili(opc, op1, op2, ilix);
6477 return ilix;
6478 }
6479 (void)mk_prototype(MTH_I_DPOWI, "f pure", DT_DBLE, 2, DT_DBLE, DT_INT);
6480 ilix = ad_func(IL_dpfunc, IL_QJSR, MTH_I_DPOWI, 2, op1, op2);
6481 ilix = ad2altili(opc, op1, op2, ilix);
6482 return ilix;
6483 case IL_DPOWK:
6484 if ((!flg.ieee || con2v2 == 1 || con2v2 == 2)
6485 && ncons >= 2 && !XBIT(124, 0x200) && con2v1 == 0) {
6486 if (con2v2 == 1)
6487 return op1;
6488 if (con2v2 > 1 && con2v2 <= __MAXPOW) {
6489 ilix = _xpowi(op1, con2v2, IL_DMUL);
6490 return ilix;
6491 }
6492 }
6493 if (XBIT_NEW_MATH_NAMES) {
6494 fname = make_math(MTH_powk, &funcsptr, 1, false, DT_DBLE, 2, DT_DBLE,
6495 DT_INT8);
6496 ilix = ad_func(IL_dpfunc, IL_QJSR, fname, 2, op1, op2);
6497 ilix = ad2altili(opc, op1, op2, ilix);
6498 return ilix;
6499 }
6500 (void)mk_prototype(MTH_I_DPOWK, "f pure", DT_DBLE, 2, DT_DBLE, DT_INT8);
6501 ilix = ad_func(IL_dpfunc, IL_QJSR, MTH_I_DPOWK, 2, op1, op2);
6502 ilix = ad2altili(opc, op1, op2, ilix);
6503 return ilix;
6504
6505 case IL_DPOWD:
6506 if (!flg.ieee && ncons >= 2 && con2v2 == 0) {
6507 if (con2v1 == 0x3fd00000) {
6508 /* x ** .25 -> sqrt(sqrt(x)) */
6509 ilix = ad1ili(IL_DSQRT, op1);
6510 ilix = ad1ili(IL_DSQRT, ilix);
6511 return ilix;
6512 }
6513 if (con2v1 == 0x3fe00000) {
6514 /* x ** 0.5 -> sqrt(x) */
6515 ilix = ad1ili(IL_DSQRT, op1);
6516 return ilix;
6517 }
6518 if (con2v1 == 0x3fe80000) {
6519 /* && !do_newton_sqrt() if newton's is possible for DSQRT */
6520 /* x ** .75 -> sqrt(x) * sqrt(sqrt(x)) */
6521 ilix = ad1ili(IL_DSQRT, op1);
6522 op2 = ad1ili(IL_DSQRT, ilix);
6523 ilix = ad2ili(IL_DMUL, ilix, op2);
6524 return ilix;
6525 }
6526 if (con2v1 == 0x40040000) {
6527 /* x ** 2.5 -> x * x * sqrt(x)) */
6528 ilix = ad2ili(IL_DMUL, op1, op1);
6529 op2 = ad1ili(IL_DSQRT, op1);
6530 ilix = ad2ili(IL_DMUL, ilix, op2);
6531 return ilix;
6532 }
6533 if (con2v1 == 0x3ff80000) {
6534 /* x ** 1.5 -> sqrt(x)*x */
6535 ilix = ad1ili(IL_DSQRT, op1);
6536 ilix = ad2ili(IL_DMUL, op1, ilix);
6537 return ilix;
6538 }
6539 }
6540 is_int = 0;
6541 pw = 0;
6542 if( ncons >= 2 && !XBIT(124, 0x40000) )
6543 {
6544 GETVAL64(num2, cons2);
6545 is_int = xdisint(num2.numd, &pw);
6546 }
6547 if ((!flg.ieee || pw == 1 || pw == 2) &&
6548 ncons >= 2 && is_int && !XBIT(124, 0x40000)) {
6549 ilix = ad2ili(IL_DPOWI, op1, ad_icon(pw));
6550 return ilix;
6551 }
6552 if (XBIT_NEW_MATH_NAMES) {
6553 fname =
6554 make_math(MTH_pow, &funcsptr, 1, false, DT_DBLE, 2, DT_DBLE, DT_DBLE);
6555 ilix = ad_func(IL_dpfunc, IL_QJSR, fname, 2, op1, op2);
6556 ilix = ad2altili(opc, op1, op2, ilix);
6557 return ilix;
6558 }
6559 #if defined(TARGET_X8664)
6560 if (!flg.ieee) {
6561 (void)mk_prototype(gnr_math("pow", 's', 'd', FMTH_I_DPOWD, 0), "f pure",
6562 DT_DBLE, 2, DT_DBLE, DT_DBLE);
6563 ilix = ad_func(IL_DFRDP, IL_QJSR,
6564 gnr_math("pow", 's', 'd', FMTH_I_DPOWD, 0), 2, op1, op2);
6565 } else
6566 #endif
6567 {
6568 #if defined(TARGET_POWER)
6569 if (flg.ieee) {
6570 (void)mk_prototype(MTH_I_DPOWD, "f pure", DT_DBLE, 2, DT_DBLE, DT_DBLE);
6571 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DPOWD, 2, op1, op2);
6572 } else {
6573 (void)mk_prototype(fast_math("pow", 's', 'd', MTH_I_DPOWD), "f pure",
6574 DT_DBLE, 2, DT_DBLE, DT_DBLE);
6575 ilix = ad_func(IL_DFRDP, IL_QJSR,
6576 fast_math("pow", 's', 'd', MTH_I_DPOWD), 2, op1, op2);
6577 }
6578 #else
6579 (void)mk_prototype(MTH_I_DPOWD, "f pure", DT_DBLE, 2, DT_DBLE, DT_DBLE);
6580 ilix = ad_func(IL_dpfunc, IL_QJSR, MTH_I_DPOWD, 2, op1, op2);
6581 #endif
6582 }
6583 ilix = ad2altili(opc, op1, op2, ilix);
6584 return ilix;
6585
6586 case IL_SIGN:
6587 if (1) {
6588 /*
6589 * There is a performance degradation when calling a routine.
6590 * For the non-vector version of zeusmp, there's roughly a 50%
6591 * penalty on the test dataset. The degradation when compiling
6592 * -Mvect is huge given that IL_SIGN & IL_DSIGN are now blockers
6593 * to vectorization.
6594 * For now, just use the original ILI sequence, but define it here
6595 * rather than messing with the ilmtp.n files.
6596 */
6597 ilix = ad2ili(IL_FCMPZ, op2, CC_LT);
6598 tmp = ad1ili(IL_FABS, op1);
6599 tmp1 = ad1ili(IL_FNEG, tmp);
6600 ilix = ad3ili(IL_FSELECT, ilix, tmp, tmp1);
6601 return ilix;
6602 }
6603 #if defined(TARGET_POWER)
6604 (void)mk_prototype(MTH_I_FSIGN, "f pure", DT_FLOAT, 2, DT_FLOAT, DT_FLOAT);
6605 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_FSIGN, 2, op1, op2);
6606 #else
6607 (void)mk_prototype(MTH_I_FSIGN, "f pure", DT_FLOAT, 2, DT_FLOAT, DT_FLOAT);
6608 ilix = ad_func(IL_dpfunc, IL_QJSR, MTH_I_FSIGN, 2, op1, op2);
6609 #endif
6610 ilix = ad2altili(opc, op1, op2, ilix);
6611 return ilix;
6612
6613 case IL_DSIGN:
6614 if (1) {
6615 /*
6616 * There is a performance degradation when calling a routine.
6617 * For the non-vector version of zeusmp, there's roughly a 50%
6618 * penalty on the test dataset. The degradation when compiling
6619 * -Mvect is huge given that IL_SIGN & IL_DSIGN are now blockers
6620 * to vectorization.
6621 * For now, just use the original ILI sequence, but define it here
6622 * rather than messing with the ilmtp.n files.
6623 */
6624 ilix = ad2ili(IL_DCMPZ, op2, CC_LT);
6625 tmp = ad1ili(IL_DABS, op1);
6626 tmp1 = ad1ili(IL_DNEG, tmp);
6627 ilix = ad3ili(IL_DSELECT, ilix, tmp, tmp1);
6628 return ilix;
6629 }
6630 #if defined(TARGET_POWER)
6631 (void)mk_prototype(MTH_I_DSIGN, "f pure", DT_DBLE, 2, DT_DBLE, DT_DBLE);
6632 ilix = ad_func(IL_DFRDP, IL_QJSR, MTH_I_DSIGN, 2, op1, op2);
6633 #else
6634 (void)mk_prototype(MTH_I_DSIGN, "f pure", DT_DBLE, 2, DT_DBLE, DT_DBLE);
6635 ilix = ad_func(IL_dpfunc, IL_QJSR, MTH_I_DSIGN, 2, op1, op2);
6636 #endif
6637 ilix = ad2altili(opc, op1, op2, ilix);
6638 return ilix;
6639
6640 case IL_ILEADZI:
6641 op2 = ad_icon(_ipowi(2, op2));
6642 ilix = ad_func(IL_DFRIR, IL_QJSR, MTH_I_ILEADZI, 2, op1, op2);
6643 ilix = ad2altili(opc, op1, op2, ilix);
6644 return ilix;
6645 case IL_ILEADZ:
6646 ilix = ad_func(IL_DFRIR, IL_QJSR, MTH_I_ILEADZ, 1, op1);
6647 ilix = ad1altili(opc, op1, ilix);
6648 return ilix;
6649 case IL_KLEADZ:
6650 ilix = ad_func(IL_DFRKR, IL_QJSR, MTH_I_KLEADZ, 1, op1);
6651 ilix = ad1altili(opc, op1, ilix);
6652 return ilix;
6653
6654 case IL_IPOPCNTI:
6655 op2 = ad_icon(_ipowi(2, op2));
6656 ilix = ad_func(IL_DFRIR, IL_QJSR, MTH_I_IPOPCNTI, 2, op1, op2);
6657 ilix = ad2altili(opc, op1, op2, ilix);
6658 return ilix;
6659 case IL_IPOPCNT:
6660 ilix = ad_func(IL_DFRIR, IL_QJSR, MTH_I_IPOPCNT, 1, op1);
6661 ilix = ad1altili(opc, op1, ilix);
6662 return ilix;
6663 case IL_KPOPCNT:
6664 ilix = ad_func(IL_DFRKR, IL_QJSR, MTH_I_KPOPCNT, 1, op1);
6665 ilix = ad1altili(opc, op1, ilix);
6666 return ilix;
6667
6668 case IL_IPOPPARI:
6669 op2 = ad_icon(_ipowi(2, op2));
6670 ilix = ad_func(IL_DFRIR, IL_QJSR, MTH_I_IPOPPARI, 2, op1, op2);
6671 ilix = ad2altili(opc, op1, op2, ilix);
6672 return ilix;
6673 case IL_IPOPPAR:
6674 if (TEST_FEATURE2(FEATURE_ABM, FEATURE_SSE42)) {
6675 ilix = ad1ili(IL_IPOPCNT, op1);
6676 ilix = ad2ili(IL_AND, ilix, ad_icon((INT)1));
6677 } else {
6678 ilix = ad_func(IL_DFRIR, IL_QJSR, MTH_I_IPOPPAR, 1, op1);
6679 }
6680 ilix = ad1altili(opc, op1, ilix);
6681 return ilix;
6682 case IL_KPOPPAR:
6683 ilix = ad_func(IL_DFRKR, IL_QJSR, MTH_I_KPOPPAR, 1, op1);
6684 ilix = ad1altili(opc, op1, ilix);
6685 return ilix;
6686
6687 case IL_LEQV:
6688 tmp = ad2ili(IL_XOR, op1, op2);
6689 tmp = ad1ili(IL_NOT, tmp);
6690 return ad2altili(opc, op1, op2, tmp);
6691
6692 case IL_ALLOC:
6693 ilix = new_ili(ilip); /* Can't allow sharing; use new_ili() */
6694 #if defined(TARGET_X8664)
6695 if (IL_RES(ILI_OPC(op1)) != ILIA_KR) {
6696 op1 = ad1ili(IL_IKMV, op1);
6697 ILI_OPND(ilix, 1) = op1;
6698 }
6699 #endif
6700 return ilix;
6701
6702 case IL_VA_ARG:
6703 ilix = new_ili(ilip); /* Can't allow sharing; use new_ili() */
6704 return ilix;
6705
6706 case IL_APURE: /* call a pure function, no arguments, returning AR */
6707 case IL_IPURE: /* call a pure function, no arguments, returning IR */
6708 ilix = ilip->opnd[1];
6709 ilix = ad1altili(opc, op1, ilix);
6710 return ilix;
6711
6712 case IL_APUREA: /* call a pure function, one AR argument, returning AR */
6713 case IL_APUREI: /* call a pure function, one IR argument, returning AR */
6714 case IL_IPUREA: /* call a pure function, one AR argument, returning IR */
6715 case IL_IPUREI: /* call a pure function, one IR argument, returning IR */
6716 ilix = ilip->opnd[2];
6717 ilix = ad2altili(opc, op1, op2, ilix);
6718 return ilix;
6719 case IL_ALLOCA:
6720 break;
6721 case IL_VDIV:
6722 if (ILI_OPC(ilip->opnd[2]) != IL_NULL) /* in a conditonal branch */
6723 {
6724 root = "div";
6725 mth_fn = MTH_div;
6726 goto do_vect2;
6727 }
6728 break;
6729 case IL_VSQRT:
6730 if (ILI_OPC(ilip->opnd[1]) != IL_NULL) /* in a conditonal branch */
6731 {
6732 root = "sqrt";
6733 mth_fn = MTH_sqrt;
6734 goto do_vect1;
6735 }
6736 break;
6737 case IL_VRSQRT:
6738 case IL_VRCP:
6739 case IL_VNEG:
6740 case IL_VADD:
6741 case IL_VSUB:
6742 case IL_VMUL:
6743 case IL_VDIVZ:
6744 break;
6745 case IL_VMOD:
6746 if (ILI_OPC(ilip->opnd[2]) != IL_NULL) /* in a conditonal branch */
6747 {
6748 root = "mod";
6749 mth_fn = MTH_mod;
6750 goto do_vect2;
6751 }
6752 break;
6753 case IL_VMODZ:
6754 case IL_VCVTV:
6755 break;
6756 case IL_VCVTS:
6757 if (ncons == 1) {
6758 switch (ILI_OPC(op1)) {
6759 case IL_ICON:
6760 case IL_FCON:
6761 ilix = ad1ili(IL_VCON,
6762 get_vcon_scalar(CONVAL2G(ILI_OPND(op1, 1)), (DTYPE)op2));
6763 return ilix;
6764 case IL_KCON:
6765 case IL_DCON:
6766 ilix = ad1ili(IL_VCON, get_vcon_scalar(ILI_OPND(op1, 1), (DTYPE)op2));
6767 return ilix;
6768 default:
6769 break;
6770 }
6771 }
6772 break;
6773 /***** { do not forget to update ili_get_vect_dtype() { *****/
6774 case IL_VNOT:
6775 case IL_VAND:
6776 case IL_VOR:
6777 case IL_VXOR:
6778 case IL_VLSHIFTV:
6779 case IL_VRSHIFTV:
6780 case IL_VLSHIFTS:
6781 case IL_VRSHIFTS:
6782 case IL_VURSHIFTS:
6783 case IL_VMIN:
6784 case IL_VMAX:
6785 case IL_VABS:
6786 case IL_VCMP:
6787 case IL_VCMPNEQ:
6788 case IL_VFMA1:
6789 case IL_VFMA2:
6790 case IL_VFMA3:
6791 case IL_VFMA4:
6792 break;
6793 case IL_VCOS:
6794 root = "cos";
6795 mth_fn = MTH_cos;
6796 goto do_vect1;
6797 case IL_VSIN:
6798 root = "sin";
6799 mth_fn = MTH_sin;
6800 goto do_vect1;
6801 case IL_VACOS:
6802 root = "acos";
6803 mth_fn = MTH_acos;
6804 goto do_vect1;
6805 case IL_VASIN:
6806 root = "asin";
6807 mth_fn = MTH_asin;
6808 goto do_vect1;
6809 case IL_VTAN:
6810 root = "tan";
6811 mth_fn = MTH_tan;
6812 goto do_vect1;
6813 case IL_VSINCOS:
6814 break;
6815 case IL_VSINH:
6816 root = "sinh";
6817 mth_fn = MTH_sinh;
6818 goto do_vect1;
6819 case IL_VCOSH:
6820 root = "cosh";
6821 mth_fn = MTH_cosh;
6822 goto do_vect1;
6823 case IL_VTANH:
6824 root = "tanh";
6825 mth_fn = MTH_tanh;
6826 goto do_vect1;
6827 case IL_VATAN:
6828 root = "atan";
6829 mth_fn = MTH_atan;
6830 goto do_vect1;
6831 case IL_VEXP:
6832 root = "exp";
6833 mth_fn = MTH_exp;
6834 goto do_vect1;
6835 case IL_VLOG:
6836 root = "log";
6837 mth_fn = MTH_log;
6838 goto do_vect1;
6839 case IL_VLOG10:
6840 root = "log10";
6841 mth_fn = MTH_log10;
6842 goto do_vect1;
6843 case IL_VFLOOR:
6844 root = "floor";
6845 mth_fn = MTH_floor;
6846 goto do_vect1;
6847 case IL_VCEIL:
6848 root = "ceil";
6849 mth_fn = MTH_ceil;
6850 goto do_vect1;
6851 case IL_VAINT:
6852 root = "aint";
6853 mth_fn = MTH_aint;
6854 goto do_vect1;
6855 do_vect1:
6856 mask_ili = ilip->opnd[1];
6857 if (ILI_OPC(mask_ili) == IL_NULL) /* no mask */
6858 {
6859 ilix = ad_func(IL_NONE, IL_GJSR,
6860 vect_math(mth_fn, root, 1, DTypeILIOpnd(ilip, 2), opc, 0, 0, false),
6861 1, op1);
6862 } else /* need to generate call to mask version */
6863 {
6864 ilix = ad_func(IL_NONE, IL_GJSR,
6865 vect_math(mth_fn, root, 2, DTypeILIOpnd(ilip, 2), opc, 0, 0, true),
6866 2, op1, mask_ili);
6867 }
6868 return ad3altili(opc, op1, mask_ili, ilip->opnd[2], ilix);
6869 case IL_VATAN2:
6870 root = "atan2";
6871 mth_fn = MTH_atan2;
6872 goto do_vect2;
6873 case IL_VPOW:
6874 root = "pow";
6875 mth_fn = MTH_pow;
6876 goto do_vect2;
6877 do_vect2:
6878 mask_ili = ilip->opnd[2];
6879 if (ILI_OPC(mask_ili) == IL_NULL)
6880 {
6881 /* no mask */
6882 ilix = ad_func(IL_NONE, IL_GJSR,
6883 vect_math(mth_fn, root, 2, DTypeILIOpnd(ilip, 3), opc, 0, 0, false),
6884 2, op1, op2);
6885 } else
6886 {
6887 /* need to generate call to mask version */
6888 ilix = ad_func(IL_NONE, IL_GJSR,
6889 vect_math(mth_fn, root, 3, DTypeILIOpnd(ilip, 3), opc, 0, 0, true),
6890 3, op1, op2, mask_ili);
6891 }
6892 return ad4altili(opc, op1, op2, mask_ili, ilip->opnd[3], ilix);
6893 case IL_VPOWI:
6894 case IL_VPOWK:
6895 case IL_VPOWIS:
6896 case IL_VPOWKS:
6897 case IL_VFPOWK:
6898 case IL_VDPOWI:
6899 case IL_VFPOWKS:
6900 case IL_VDPOWIS:
6901 switch (opc) {
6902 case IL_VPOWI:
6903 case IL_VDPOWI:
6904 root = "powi";
6905 mth_fn = MTH_powi;
6906 break;
6907 case IL_VPOWK:
6908 case IL_VFPOWK:
6909 root = "powk";
6910 mth_fn = MTH_powk;
6911 break;
6912 case IL_VPOWIS:
6913 case IL_VDPOWIS:
6914 root = "powi1";
6915 mth_fn = MTH_powi1;
6916 break;
6917 case IL_VPOWKS:
6918 case IL_VFPOWKS:
6919 root = "powk1";
6920 mth_fn = MTH_powk1;
6921 break;
6922 default:
6923 break;
6924 }
6925 assert(IL_VECT(ILI_OPC(op1)), "addarth():expected vector opc", ILI_OPC(op1),
6926 ERR_Fatal);
6927 vdt1 = ili_get_vect_dtype(op1);
6928 if (IL_VECT(ILI_OPC(op2))) {
6929 vdt2 = ili_get_vect_dtype(op2);
6930 } else if (IL_TYPE(ILI_OPC(op2)) == ILTY_LOAD) {
6931 if (ILI_OPC(op2) == IL_LD)
6932 vdt2 = DT_INT;
6933 else if (ILI_OPC(op2) == IL_LDKR)
6934 vdt2 = DT_INT8;
6935 else {
6936 #if DEBUG
6937 assert(0, "addarth(): unrecognized load type", ILI_OPC(op2), ERR_Fatal);
6938 #endif
6939 vdt2 = DT_INT;
6940 }
6941 } else if (IL_TYPE(ILI_OPC(op2)) == ILTY_CONS) {
6942 if (ILI_OPC(op2) == IL_ICON)
6943 vdt2 = DT_INT;
6944 else if (ILI_OPC(op2) == IL_KCON)
6945 vdt2 = DT_INT8;
6946 else {
6947 #if DEBUG
6948 assert(0, "addarth(): unrecognized constant type", ILI_OPC(op2),
6949 ERR_Fatal);
6950 #endif
6951 vdt2 = DT_INT;
6952 }
6953 } else if (IL_TYPE(ILI_OPC(op2)) == ILTY_ARTH) {
6954 if (IL_RES(ILI_OPC(op2)) == ILIA_IR)
6955 vdt2 = DT_INT;
6956 else if (IL_RES(ILI_OPC(op2)) == ILIA_KR)
6957 vdt2 = DT_INT8;
6958 else {
6959 #if DEBUG
6960 assert(0, "addarth(): unrecognized arth type", IL_TYPE(ILI_OPC(op2)),
6961 ERR_Fatal);
6962 #endif
6963 vdt2 = DT_INT;
6964 }
6965 } else if (IL_TYPE(ILI_OPC(op2)) == ILTY_MOVE) {
6966 switch(IL_RES(ILI_OPC(op2)))
6967 {
6968 case ILIA_IR:
6969 vdt2 = DT_INT;
6970 break;
6971 case ILIA_KR:
6972 vdt2 = DT_INT8;
6973 break;
6974 default:
6975 assert(0, "addarth(): bad move result for operand 2",
6976 IL_RES(ILI_OPC(op2)), ERR_Fatal);
6977 }
6978 } else
6979 assert(0, "addarth(): bad type for operand 2", IL_TYPE(ILI_OPC(op2)),
6980 ERR_Fatal);
6981 mask_ili = ilip->opnd[2];
6982 if (ILI_OPC(mask_ili) == IL_NULL) /* no mask */
6983 {
6984 ilix = ad_func(IL_NONE, IL_GJSR,
6985 vect_math(mth_fn, root, 2, DTypeILIOpnd(ilip, 3), opc, vdt1, vdt2, false),
6986 2, op1, op2);
6987 } else /* need to generate call to mask version */
6988 {
6989 ilix = ad_func(IL_NONE, IL_GJSR,
6990 vect_math(mth_fn, root, 3, DTypeILIOpnd(ilip, 3), opc, vdt1, vdt2, true),
6991 3, op1, op2, mask_ili);
6992 }
6993 return ad4altili(opc, op1, op2, mask_ili, ilip->opnd[3], ilix);
6994 /***** } do not forget to update ili_get_vect_dtype() } *****/
6995 break;
6996
6997 #ifdef LONG_DOUBLE_FLOAT128
6998 case IL_FLOAT128ABS:
6999 case IL_FLOAT128CHS:
7000 case IL_FLOAT128RNDINT:
7001 case IL_FLOAT128TO:
7002 case IL_FLOAT128FROM:
7003 case IL_FLOAT128ADD:
7004 case IL_FLOAT128SUB:
7005 case IL_FLOAT128MUL:
7006 case IL_FLOAT128DIV:
7007 case IL_FLOAT128CMP:
7008 break;
7009 #endif /* LONG_DOUBLE_FLOAT128 */
7010
7011 case IL_FCEIL:
7012 if (XBIT_NEW_MATH_NAMES) {
7013 fname = make_math(MTH_ceil, &funcsptr, 1, false, DT_FLOAT, 1, DT_FLOAT);
7014 ilix = ad_func(IL_spfunc, IL_QJSR, fname, 1, op1);
7015 ilix = ad1altili(opc, op1, ilix);
7016 return ilix;
7017 }
7018 #if defined(TARGET_LLVM_ARM) || defined(TARGET_WIN)
7019 else {
7020 (void)mk_prototype(MTH_I_FCEIL, "f pure", DT_FLOAT, 1, DT_FLOAT);
7021 ilix = ad_func(IL_spfunc, IL_QJSR, MTH_I_FCEIL, 1, op1);
7022 return ad1altili(opc, op1, ilix);
7023 }
7024 #else
7025 else
7026 interr("addarth: old math name for ili not handled",
7027 opc, ERR_Informational);
7028 #endif
7029 break;
7030
7031 case IL_DCEIL:
7032 if (XBIT_NEW_MATH_NAMES) {
7033 fname = make_math(MTH_ceil, &funcsptr, 1, false, DT_DBLE, 1, DT_DBLE);
7034 ilix = ad_func(IL_dpfunc, IL_QJSR, fname, 1, op1);
7035 ilix = ad1altili(opc, op1, ilix);
7036 return ilix;
7037 }
7038 #if defined(TARGET_LLVM_ARM) || defined(TARGET_WIN)
7039 else {
7040 (void)mk_prototype(MTH_I_DCEIL, "f pure", DT_DBLE, 1, DT_DBLE);
7041 ilix = ad_func(IL_dpfunc, IL_QJSR, MTH_I_DCEIL, 1, op1);
7042 return ad1altili(opc, op1, ilix);
7043 }
7044 #else
7045 else
7046 interr("addarth: old math name for ili not handled",
7047 opc, ERR_Informational);
7048 #endif
7049 break;
7050
7051 case IL_FFLOOR:
7052 if (XBIT_NEW_MATH_NAMES) {
7053 fname = make_math(MTH_floor, &funcsptr, 1, false, DT_FLOAT, 1, DT_FLOAT);
7054 ilix = ad_func(IL_spfunc, IL_QJSR, fname, 1, op1);
7055 ilix = ad1altili(opc, op1, ilix);
7056 return ilix;
7057 }
7058 #if defined(TARGET_LLVM_ARM) || defined(TARGET_WIN)
7059 else {
7060 (void)mk_prototype(MTH_I_FFLOOR, "f pure", DT_FLOAT, 1, DT_FLOAT);
7061 ilix = ad_func(IL_spfunc, IL_QJSR, MTH_I_FFLOOR, 1, op1);
7062 return ad1altili(opc, op1, ilix);
7063 }
7064 #else
7065 else
7066 interr("addarth: old math name for ili not handled",
7067 opc, ERR_Informational);
7068 #endif
7069 break;
7070
7071 case IL_DFLOOR:
7072 if (XBIT_NEW_MATH_NAMES) {
7073 fname = make_math(MTH_floor, &funcsptr, 1, false, DT_DBLE, 1, DT_DBLE);
7074 ilix = ad_func(IL_dpfunc, IL_QJSR, fname, 1, op1);
7075 ilix = ad1altili(opc, op1, ilix);
7076 return ilix;
7077 }
7078 #if defined(TARGET_LLVM_ARM) || defined(TARGET_WIN)
7079 else {
7080 (void)mk_prototype(MTH_I_DFLOOR, "f pure", DT_DBLE, 1, DT_DBLE);
7081 ilix = ad_func(IL_dpfunc, IL_QJSR, MTH_I_DFLOOR, 1, op1);
7082 return ad1altili(opc, op1, ilix);
7083 }
7084 #else
7085 else
7086 interr("addarth: old math name for ili not handled",
7087 opc, ERR_Informational);
7088 #endif
7089 break;
7090
7091 case IL_AINT:
7092 if (XBIT_NEW_MATH_NAMES) {
7093 fname = make_math(MTH_aint, &funcsptr, 1, false, DT_FLOAT, 1, DT_FLOAT);
7094 ilix = ad_func(IL_spfunc, IL_QJSR, fname, 1, op1);
7095 ilix = ad1altili(opc, op1, ilix);
7096 return ilix;
7097 }
7098 #if defined(TARGET_LLVM_ARM) || defined(TARGET_WIN)
7099 else {
7100 (void)mk_prototype(MTH_I_AINT, "f pure", DT_FLOAT, 1, DT_FLOAT);
7101 ilix = ad_func(IL_spfunc, IL_QJSR, MTH_I_AINT, 1, op1);
7102 return ad1altili(opc, op1, ilix);
7103 }
7104 #else
7105 else
7106 interr("addarth: old math name for ili not handled",
7107 opc, ERR_Informational);
7108 #endif
7109 break;
7110
7111 case IL_DINT:
7112 if (XBIT_NEW_MATH_NAMES) {
7113 fname = make_math(MTH_aint, &funcsptr, 1, false, DT_DBLE, 1, DT_DBLE);
7114 ilix = ad_func(IL_dpfunc, IL_QJSR, fname, 1, op1);
7115 ilix = ad1altili(opc, op1, ilix);
7116 return ilix;
7117 }
7118 #if defined(TARGET_LLVM_ARM) || defined(TARGET_WIN)
7119 else {
7120 (void)mk_prototype(MTH_I_DINT, "f pure", DT_DBLE, 1, DT_DBLE);
7121 ilix = ad_func(IL_dpfunc, IL_QJSR, MTH_I_DINT, 1, op1);
7122 return ad1altili(opc, op1, ilix);
7123 }
7124 #else
7125 else
7126 interr("addarth: old math name for ili not handled",
7127 opc, ERR_Informational);
7128 #endif
7129 break;
7130
7131 default:
7132
7133 #if DEBUG
7134 interr("addarth:ili not handled", opc, ERR_Informational);
7135 #endif
7136 break;
7137 }
7138
7139 newili.opc = opc;
7140 newili.opnd[0] = op1;
7141 newili.opnd[1] = op2;
7142 for (i = 2; i < IL_OPRS(opc); ++i)
7143 newili.opnd[i] = ilip->opnd[i];
7144 return get_ili(&newili);
7145
7146 add_icon:
7147 return ad_icon(res.numi[1]);
7148
7149 add_kcon:
7150 return ad1ili(IL_KCON, getcon(res.numi, DT_INT8));
7151
7152 add_rcon:
7153 res.numi[0] = 0;
7154 return ad1ili(IL_FCON, getcon(res.numi, DT_FLOAT));
7155
7156 add_dcon:
7157 return ad1ili(IL_DCON, getcon(res.numi, DT_DBLE));
7158 }
7159
7160 static int
gen_sincos(ILI_OP opc,int op1,ILI_OP sincos_opc,ILI_OP fopc,MTH_FN fn,DTYPE dt,ILI_OP dfr_opc)7161 gen_sincos(ILI_OP opc, int op1, ILI_OP sincos_opc, ILI_OP fopc, MTH_FN fn,
7162 DTYPE dt, ILI_OP dfr_opc)
7163 {
7164 int ilix;
7165 char *fname;
7166
7167 #if defined(TARGET_X8664) || defined(TARGET_POWER)
7168 /* only if using new names */
7169 if (XBIT(164, 0x800000))
7170 if (!XBIT(15, 0x08)) {
7171 ilix = ad1ili(sincos_opc, op1);
7172 ilix = ad1ili(fopc, ilix);
7173 return ilix;
7174 }
7175 #endif
7176 fname = make_math(fn, NULL, 1, false, dt, 1, dt);
7177 ilix = ad_func(dfr_opc, IL_QJSR, fname, 1, op1);
7178 ilix = ad1altili(opc, op1, ilix);
7179 return ilix;
7180 }
7181
7182 static int
_newton_fdiv(int op1,int op2)7183 _newton_fdiv(int op1, int op2)
7184 {
7185 int i, x0, tmp1, ilix;
7186 /*
7187 * Newton's appx for recip:
7188 * x1 = (2.0 - x * x0) * x0
7189 */
7190 i = ad1ili(IL_FCON, stb.flt2);
7191 x0 = ad1ili(IL_RCPSS, op2);
7192 tmp1 = ad2ili(IL_FMUL, op2, x0);
7193 tmp1 = ad2ili(IL_FSUB, i, tmp1);
7194 tmp1 = ad2ili(IL_FMUL, tmp1, x0);
7195 ilix = ad2ili(IL_FMUL, op1, tmp1);
7196 return ilix;
7197 }
7198
7199 static bool
do_newton_sqrt(void)7200 do_newton_sqrt(void)
7201 {
7202 #if !defined(TARGET_LLVM_ARM)
7203 if (!flg.ieee && !XBIT(15, 0x20000000) /* not -Mfpapprox */
7204 && XBIT(15, 0x10) && !XBIT(15, 0x10000) &&
7205 (XBIT(15, 0x20) || TEST_MACH(MACH_INTEL_PENTIUM4)))
7206 return true;
7207 #endif
7208 return false;
7209 }
7210
7211 /** \brief Determine if 'val' is a power of 2; the range of the powers is 1 ...
7212 * max_pwr, inclusive.
7213 */
7214 static int
_pwr2(INT val,int max_pwr)7215 _pwr2(INT val, int max_pwr)
7216 {
7217 int i;
7218 INT v;
7219 v = 2; /* a single bit representing the powers of 2 */
7220 for (i = 1; i <= max_pwr; i++) {
7221 if ((v & val) == 0)
7222 v <<= 1; /* slide the bit over */
7223 else if (v == val)
7224 return i;
7225 }
7226 return 0;
7227 }
7228
7229 /** \brief Determine if the 64-bit value represented by (cv1<<32)+cv2 is a
7230 * power of 2; the range of the powers is 1 ... max_pwr, inclusive.
7231 */
7232 static int
_kpwr2(INT cv1,INT cv2,int max_pwr)7233 _kpwr2(INT cv1, INT cv2, int max_pwr)
7234 {
7235 int i;
7236 INT v;
7237 int mp;
7238
7239 if (max_pwr > 31)
7240 mp = 31;
7241 else
7242 mp = max_pwr;
7243 if (cv1 == 0) {
7244 return _pwr2(cv2, mp);
7245 }
7246 if (cv2)
7247 return 0;
7248 if (max_pwr < 32)
7249 return 0;
7250 if (cv1 == 1)
7251 return 32;
7252 i = _pwr2(cv1, max_pwr - 32);
7253 if (i)
7254 return i + 32;
7255 return 0;
7256 }
7257
7258 /**
7259 * \brief constant folds the integer add ili (iadd)
7260 */
7261 static int
red_iadd(int ilix,INT con)7262 red_iadd(int ilix, INT con)
7263 {
7264 int lop, rop, New;
7265 ILI_OP opc;
7266 static INT val;
7267 static ILI newili;
7268
7269 opc = ILI_OPC(ilix);
7270 switch (opc) {
7271
7272 case IL_ICON:
7273 return ad_icon(CONVAL2G(ILI_OPND(ilix, 1)) + con);
7274
7275 case IL_IADD:
7276 case IL_UIADD:
7277 lop = ILI_OPND(ilix, 1);
7278 rop = ILI_OPND(ilix, 2);
7279 New = red_iadd(rop, con);
7280 if (New != 0) {
7281 newili.opc = opc;
7282 newili.opnd[0] = lop;
7283 newili.opnd[1] = New;
7284 if (ILI_OPC(New) == IL_ICON) {
7285 val = CONVAL2G(ILI_OPND(New, 1));
7286 if (val == 0)
7287 return lop;
7288 if ((opc == IL_IADD) && (val < 0 && val != 0x80000000)) {
7289 newili.opc = IL_ISUB;
7290 newili.opnd[1] = ad_icon(-val);
7291 }
7292 } else if (lop > New) {
7293 newili.opnd[0] = New;
7294 newili.opnd[1] = lop;
7295 }
7296 return get_ili(&newili);
7297 }
7298 New = red_iadd(lop, con);
7299 if (New != 0) {
7300 newili.opc = opc;
7301 if (New > rop) {
7302 newili.opnd[0] = rop;
7303 newili.opnd[1] = New;
7304 } else {
7305 newili.opnd[0] = New;
7306 newili.opnd[1] = rop;
7307 }
7308 return get_ili(&newili);
7309 }
7310 break;
7311
7312 case IL_ISUB:
7313 case IL_UISUB:
7314 lop = ILI_OPND(ilix, 1);
7315 rop = ILI_OPND(ilix, 2);
7316 New = red_iadd(lop, con);
7317 if (New != 0) {
7318 if (ILI_OPC(New) == IL_ICON && ILI_OPND(New, 1) == stb.i0)
7319 return ad1ili(IL_INEG, rop);
7320 newili.opc = opc;
7321 newili.opnd[0] = New;
7322 newili.opnd[1] = rop;
7323 return get_ili(&newili);
7324 }
7325 if (opc == IL_ISUB && con > 0 && ILI_OPC(rop) == IL_ICON) {
7326 UINT uv = CONVAL2G(ILI_OPND(rop, 1));
7327 if ((uv + (UINT)con) > 0x80000000U) {
7328 /*
7329 * (rop + -con) can be smaller than INT_MIN on 64-bit; e.g.,
7330 * in mp_correct clmp, an induction init expression is
7331 * presented as (iistart - INT_MIN) + 1 and becomes
7332 * iistart - (INT_MIN - 1) (obviously, an invalid re-association)
7333 */
7334 break;
7335 }
7336 }
7337 New = red_iadd(rop, -con);
7338 if (New != 0) {
7339 newili.opc = opc;
7340 newili.opnd[0] = lop;
7341 newili.opnd[1] = New;
7342 if (ILI_OPC(New) == IL_ICON) {
7343 val = CONVAL2G(ILI_OPND(New, 1));
7344 if (val == 0)
7345 return lop;
7346 if ((opc == IL_ISUB) && (val < 0 && val != 0x80000000)) {
7347 newili.opc = IL_IADD;
7348 newili.opnd[1] = ad_icon(-val);
7349 }
7350 }
7351 return get_ili(&newili);
7352 }
7353 break;
7354 default:;
7355 } /***** end of switch(ILI_OPC(ilix)) *****/
7356
7357 return 0;
7358 }
7359
7360 /**
7361 * \brief constant folds the integer*8 add ili (kadd)
7362 */
7363 static int
red_kadd(int ilix,INT con[2])7364 red_kadd(int ilix, INT con[2])
7365 {
7366 int lop, rop, New;
7367 ILI_OP opc;
7368 INT tmp[2];
7369 static INT val[2];
7370 static ILI newili;
7371
7372 opc = ILI_OPC(ilix);
7373 switch (opc) {
7374
7375 case IL_KCON:
7376 val[0] = CONVAL1G(ILI_OPND(ilix, 1));
7377 val[1] = CONVAL2G(ILI_OPND(ilix, 1));
7378 add64(val, con, val);
7379 return ad1ili(IL_KCON, getcon(val, DT_INT8));
7380
7381 case IL_KADD:
7382 case IL_UKADD:
7383 lop = ILI_OPND(ilix, 1);
7384 rop = ILI_OPND(ilix, 2);
7385 New = red_kadd(rop, con);
7386 if (New != 0) {
7387 newili.opc = opc;
7388 newili.opnd[0] = lop;
7389 newili.opnd[1] = New;
7390 if (ILI_OPC(New) == IL_KCON) {
7391 val[0] = CONVAL1G(ILI_OPND(New, 1));
7392 val[1] = CONVAL2G(ILI_OPND(New, 1));
7393 if (val[0] == 0 && val[1] == 0)
7394 return lop;
7395 if (opc == IL_KADD && val[0] < 0 &&
7396 !(val[0] == 0x80000000 && val[1] == 0)) {
7397 newili.opc = IL_KSUB;
7398 neg64(val, val);
7399 newili.opnd[1] = ad1ili(IL_KCON, getcon(val, DT_INT8));
7400 }
7401 } else if (lop > New) {
7402 newili.opnd[0] = New;
7403 newili.opnd[1] = lop;
7404 }
7405 return get_ili(&newili);
7406 }
7407 New = red_kadd(lop, con);
7408 if (New != 0) {
7409 newili.opc = opc;
7410 if (New > rop) {
7411 newili.opnd[0] = rop;
7412 newili.opnd[1] = New;
7413 } else {
7414 newili.opnd[0] = New;
7415 newili.opnd[1] = rop;
7416 }
7417 return get_ili(&newili);
7418 }
7419 break;
7420
7421 case IL_KSUB:
7422 case IL_UKSUB:
7423 lop = ILI_OPND(ilix, 1);
7424 rop = ILI_OPND(ilix, 2);
7425 New = red_kadd(lop, con);
7426 if (New != 0) {
7427 if (ILI_OPC(New) == IL_KCON && ILI_OPND(New, 1) == stb.k0)
7428 return ad1ili(IL_KNEG, rop);
7429 newili.opc = opc;
7430 newili.opnd[0] = New;
7431 newili.opnd[1] = rop;
7432 return get_ili(&newili);
7433 }
7434 neg64(con, tmp);
7435 New = red_kadd(rop, tmp);
7436 if (New != 0) {
7437 newili.opc = opc;
7438 newili.opnd[0] = lop;
7439 newili.opnd[1] = New;
7440 if (ILI_OPC(New) == IL_KCON) {
7441 val[0] = CONVAL1G(ILI_OPND(New, 1));
7442 val[1] = CONVAL2G(ILI_OPND(New, 1));
7443 if (val[0] == 0 && val[1] == 0)
7444 return lop;
7445 if (opc == IL_KSUB && val[0] < 0 &&
7446 !(val[0] == 0x80000000 && val[1] == 0)) {
7447 newili.opc = IL_KADD;
7448 neg64(val, val);
7449 newili.opnd[1] = ad1ili(IL_KCON, getcon(val, DT_INT8));
7450 }
7451 }
7452 return get_ili(&newili);
7453 }
7454 break;
7455 } /***** end of switch(ILI_OPC(ilix)) *****/
7456
7457 return 0;
7458 }
7459
7460 /**
7461 * \brief constant folds the extended int add ili (eiadd)
7462 */
7463 static int
red_eiadd(int ilix,INT con[2])7464 red_eiadd(int ilix, INT con[2])
7465 {
7466 return 0;
7467 }
7468
7469 /**
7470 * \brief constant folds the address add ili (aadd)
7471 */
7472 static int
red_aadd(int ilix,SPTR sym,ISZ_T off,int scale)7473 red_aadd(int ilix, SPTR sym, ISZ_T off, int scale)
7474 {
7475 SPTR lop;
7476 int rop, New, oldsc;
7477 SPTR vsym;
7478 ISZ_T voff;
7479 static ILI newili;
7480
7481 switch (ILI_OPC(ilix)) {
7482 default:
7483 break;
7484 case IL_ACON:
7485 lop = ILI_SymOPND(ilix, 1);
7486 vsym = SymConval1(lop);
7487 if (scale >= 0)
7488 off <<= scale;
7489 else
7490 off = (double)off / ((INT)1 << (-scale));
7491 voff = ACONOFFG(lop) + off;
7492 if (sym == vsym) {
7493 if (sym == 0)
7494 return ad_aconi(voff);
7495 return ad_acon(vsym, voff);
7496 } else if (vsym == 0) {
7497 vsym = sym;
7498 return ad_acon(vsym, voff);
7499 } else if (sym == 0)
7500 return ad_acon(vsym, voff);
7501 break;
7502
7503 case IL_AADD:
7504 lop = ILI_SymOPND(ilix, 1);
7505 rop = ILI_OPND(ilix, 2);
7506 oldsc = ILI_OPND(ilix, 3);
7507 New = red_aadd(lop, sym, off, scale);
7508 if (New != 0) {
7509 newili.opc = IL_AADD;
7510 newili.opnd[0] = New;
7511 newili.opnd[1] = rop;
7512 newili.opnd[2] = oldsc;
7513 return get_ili(&newili);
7514 }
7515 if (scale < oldsc)
7516 break;
7517 New = red_aadd(rop, sym, off, scale - oldsc);
7518 if (New != 0) {
7519 newili.opc = IL_AADD;
7520 if (ILI_OPC(New) == IL_ACON && ACONOFFG(ILI_OPND(New, 1)) == 0 &&
7521 CONVAL1G(ILI_OPND(New, 1)) == 0)
7522 return lop;
7523 newili.opnd[0] = lop;
7524 newili.opnd[1] = New;
7525 newili.opnd[2] = oldsc;
7526 return get_ili(&newili);
7527 }
7528 switch (ILI_OPC(rop)) {
7529 default:
7530 break;
7531 case IL_IAMV:
7532 case IL_KAMV:
7533 /*
7534 * Push the constant below the AADD of the IAMV/KAMV.
7535 */
7536 New = ad_acon(sym, off);
7537 newili.opc = IL_AADD;
7538 newili.opnd[0] = lop;
7539 newili.opnd[1] = New;
7540 newili.opnd[2] = scale;
7541 lop = sptrGetILI(&newili);
7542 newili.opnd[0] = lop;
7543 newili.opnd[1] = rop;
7544 newili.opnd[2] = oldsc;
7545 return get_ili(&newili);
7546 }
7547 break;
7548
7549 case IL_ASUB:
7550 lop = ILI_SymOPND(ilix, 1);
7551 rop = ILI_OPND(ilix, 2);
7552 oldsc = ILI_OPND(ilix, 3);
7553 New = red_aadd(lop, sym, off, scale);
7554 if (New != 0) {
7555 newili.opc = IL_ASUB;
7556 newili.opnd[0] = New;
7557 newili.opnd[1] = rop;
7558 newili.opnd[2] = oldsc;
7559 return get_ili(&newili);
7560 }
7561 if (scale < oldsc)
7562 break;
7563 if (sym == 0) {
7564 New = red_aadd(rop, SPTR_NULL, -off, scale - oldsc);
7565 if (New != 0) {
7566 newili.opc = IL_ASUB;
7567 newili.opnd[0] = lop;
7568 newili.opnd[1] = New;
7569 newili.opnd[2] = oldsc;
7570 return get_ili(&newili);
7571 }
7572 }
7573 break;
7574
7575 } /***** end of switch(ILI_OPC(ilix)) *****/
7576
7577 return 0;
7578 }
7579
7580 /**
7581 * \brief combines the operand of damv's in an aadd expr
7582 *
7583 * Routine which simplifies an aadd expression where one of the operands is a
7584 * damv ILI. This routine combines the operand of the damv with any other
7585 * damv's in opr by performing an iadd followed by a damv.
7586 *
7587 * \param opr locates expression of an aadd
7588 * \param damv damv ILI
7589 * \param scale scale of aadd - if >= 0 scale operand of damv, if < 0
7590 * - scale operand of opr if damv
7591 */
7592 static int
red_damv(int opr,int damv,int scale)7593 red_damv(int opr, int damv, int scale)
7594 {
7595 int tmp, oldsc;
7596 int o1;
7597
7598 switch (ILI_OPC(opr)) {
7599 default:
7600 break;
7601 case IL_IAMV:
7602 if (scale >= 0) {
7603 o1 = ILI_OPND(damv, 1);
7604 if (IL_RES(ILI_OPC(o1)) != ILIA_KR) {
7605 tmp = ad2ili(IL_IMUL, o1, ad_icon((INT)(1 << scale)));
7606 return ad1ili(IL_IAMV, ad2ili(IL_IADD, (int)ILI_OPND(opr, 1), tmp));
7607 }
7608 tmp = ad2ili(IL_KMUL, o1, ad_kconi((INT)(1 << scale)));
7609 o1 = ad1ili(IL_IKMV, ILI_OPND(opr, 1));
7610 return ad1ili(IL_KAMV, ad2ili(IL_KADD, o1, tmp));
7611 }
7612 tmp = ad2ili(IL_IMUL, (int)ILI_OPND(opr, 1), ad_icon((INT)(1 << (-scale))));
7613 return ad1ili(IL_IAMV, ad2ili(IL_IADD, (int)ILI_OPND(damv, 1), tmp));
7614
7615 case IL_KAMV:
7616 if (scale >= 0) {
7617 o1 = ILI_OPND(damv, 1);
7618 if (IL_RES(ILI_OPC(o1)) == ILIA_IR)
7619 o1 = ad1ili(IL_IKMV, o1);
7620 tmp = ad2ili(IL_KMUL, o1, ad_kconi((INT)(1 << scale)));
7621 return ad1ili(IL_KAMV, ad2ili(IL_KADD, (int)ILI_OPND(opr, 1), tmp));
7622 }
7623 tmp =
7624 ad2ili(IL_KMUL, (int)ILI_OPND(opr, 1), ad_kconi((INT)(1 << (-scale))));
7625 return ad1ili(IL_KAMV, ad2ili(IL_KADD, (int)ILI_OPND(damv, 1), tmp));
7626
7627 case IL_AADD:
7628 /*
7629 * the case looked for is <acon> <+> <rop>
7630 */
7631 oldsc = ILI_OPND(opr, 3);
7632 tmp = red_damv((int)ILI_OPND(opr, 2), damv, scale - oldsc);
7633 if (tmp) {
7634 if (oldsc <= scale) {
7635 return ad3ili(IL_AADD, (int)ILI_OPND(opr, 1), tmp, oldsc);
7636 }
7637 return ad3ili(IL_AADD, (int)ILI_OPND(opr, 1), tmp, scale);
7638 }
7639 break;
7640
7641 case IL_ASUB:
7642 /*
7643 * the case looked for is <lop> <-> <acon>
7644 */
7645 oldsc = ILI_OPND(opr, 3);
7646 tmp = red_damv((int)ILI_OPND(opr, 1), damv, scale - oldsc);
7647 if (tmp) {
7648 if (oldsc <= scale) {
7649 return ad3ili(IL_ASUB, tmp, (int)ILI_OPND(opr, 2), oldsc);
7650 }
7651 return ad3ili(IL_ASUB, tmp, (int)ILI_OPND(opr, 2), scale);
7652 }
7653 break;
7654 }
7655 return 0;
7656 }
7657
7658 /**
7659 * Simplify
7660 * <pre>
7661 * max( max(x, y), y )
7662 * max( y, max(x, y) )
7663 * </pre>
7664 * as
7665 * <pre>
7666 * max(x, y)
7667 * </pre>
7668 */
7669 static int
red_minmax(ILI_OP opc,int op1,int op2)7670 red_minmax(ILI_OP opc, int op1, int op2)
7671 {
7672 ILI newili;
7673
7674 if (op1 == op2)
7675 return op1; /* max(x,x) == x */
7676 if (opc == ILI_OPC(op1)) {
7677 if (ILI_OPND(op1, 2) == op2)
7678 return op1;
7679 } else if (opc == ILI_OPC(op2)) {
7680 if (ILI_OPND(op2, 2) == op1)
7681 return op2;
7682 }
7683 newili.opc = opc;
7684 newili.opnd[0] = op1;
7685 newili.opnd[1] = op2;
7686 return get_ili(&newili);
7687 }
7688
7689 /** \brief Transform -(c<OP>x<OP>y) into (-c)<OP>x<OP>y; OP is a mult or divide
7690 */
7691 static int
red_negate(int old,ILI_OP neg_opc,int mult_opc,int div_opc)7692 red_negate(int old, ILI_OP neg_opc, int mult_opc, int div_opc)
7693 {
7694 int op1, op2;
7695 int New;
7696 op1 = ILI_OPND(old, 1);
7697 op2 = ILI_OPND(old, 2);
7698 if (IL_TYPE(ILI_OPC(op2)) == ILTY_CONS) {
7699 op2 = ad1ili(neg_opc, op2);
7700 return ad2ili(ILI_OPC(old), op1, op2); /* could be mult or divide */
7701 }
7702 if (IL_TYPE(ILI_OPC(op1)) == ILTY_CONS) {
7703 if (!XBIT(15, 0x4) ||
7704 (div_opc != IL_FDIV && div_opc != IL_DDIV)) {
7705 /* don't do if mult by recip enabled */
7706 op1 = ad1ili(neg_opc, op1);
7707 return ad2ili(ILI_OPC(old), op1, op2); /* should only be a divide */
7708 }
7709 }
7710 if (ILI_OPC(op2) == mult_opc) {
7711 New = red_negate(op2, neg_opc, mult_opc, div_opc);
7712 if (New != op2) {
7713 return ad2ili(ILI_OPC(old), op1, New); /* could be mult or divide */
7714 }
7715 }
7716 if (ILI_OPC(op2) == div_opc) {
7717 New = red_negate(op2, neg_opc, mult_opc, div_opc);
7718 if (New != op2) {
7719 return ad2ili(ILI_OPC(old), op1, New); /* could be mult or divide */
7720 }
7721 }
7722 if (ILI_OPC(op1) == mult_opc) {
7723 New = red_negate(op1, neg_opc, mult_opc, div_opc);
7724 if (New != op1) {
7725 return ad2ili(ILI_OPC(old), New, op2); /* could be mult or divide */
7726 }
7727 }
7728 if (ILI_OPC(op1) == div_opc) {
7729 New = red_negate(op1, neg_opc, mult_opc, div_opc);
7730 if (New != op1) {
7731 return ad2ili(ILI_OPC(old), New, op2); /* could be mult or divide */
7732 }
7733 }
7734 return old;
7735 }
7736
7737 static bool
_is_nand(SPTR sptr)7738 _is_nand(SPTR sptr)
7739 {
7740 int v, e, m;
7741 /*
7742 * our fp cannoical form (big endian IEEE):
7743 * struct {
7744 * unsigned int ml;
7745 * unsigned int mh:20;
7746 * unsigned int e:11;
7747 * unsigned int s:1;
7748 * };
7749 * A NaN has an exponent field of all one's and a non-zero mantissa.
7750 */
7751 v = CONVAL1G(sptr);
7752 e = (v >> 20) & 0x7ff;
7753 if (e == 0x7ff) {
7754 m = v & 0xfffff;
7755 if (m || CONVAL2G(sptr))
7756 return true;
7757 }
7758 return false;
7759 }
7760
7761 static int
addother(ILI * ilip)7762 addother(ILI *ilip)
7763 {
7764 int ilix;
7765 int ncons;
7766 ILI_OP opc, opc1, opc2;
7767 int op1, cons1, con1v1, con1v2;
7768 int op2, cons2, con2v1, con2v2;
7769 opc = ilip->opc;
7770 ncons = 0;
7771 switch (opc) {
7772 case IL_ISELECT:
7773 case IL_ASELECT:
7774 case IL_KSELECT:
7775 case IL_FSELECT:
7776 case IL_DSELECT:
7777 case IL_CSSELECT:
7778 case IL_CDSELECT:
7779 op1 = ilip->opnd[0];
7780 opc1 = ILI_OPC(op1);
7781 if (IL_TYPE(opc1) == ILTY_CONS) {
7782 cons2 = ILI_OPND(op1, 1);
7783 con2v2 = CONVAL2G(cons2);
7784 if (con2v2 == 0)
7785 return ilip->opnd[1];
7786 return ilip->opnd[2];
7787 }
7788 if (ilip->opnd[1] == ilip->opnd[2]) {
7789 if (!func_in(op1))
7790 return ilip->opnd[1];
7791 }
7792 if (opc1 == IL_ICMPZ) {
7793 int new_op1 = cmpz_of_cmp(ILI_OPND(op1, 1), CC_ILI_OPND(op1, 2));
7794 if (new_op1 >= 0)
7795 return ad3ili(opc, new_op1, ilip->opnd[1], ilip->opnd[2]);
7796 }
7797 break;
7798 case IL_DEALLOC:
7799 ilix = new_ili(ilip); /* Can't allow sharing; use new_ili() */
7800 op1 = ad_func(IL_NONE, IL_JSR, "_mp_free", 1, ilip->opnd[0]);
7801 ILI_ALT(ilix) = op1;
7802 iltb.callfg = 1;
7803 return ilix;
7804 case IL_DPDP2DCMPLXI0:
7805 op1 = ilip->opnd[0];
7806 if (ILI_OPC(op1) == IL_DCON) {
7807 INT numi[2];
7808 numi[0] = ILI_OPND(op1, 1);
7809 numi[1] = stb.dbl0;
7810 return ad1ili(IL_DCMPLXCON, getcon(numi, DT_DCMPLX));
7811 }
7812 break;
7813 case IL_DPDP2DCMPLX:
7814 op1 = ilip->opnd[0];
7815 op2 = ilip->opnd[1];
7816 if (ILI_OPC(op1) == IL_DCON && ILI_OPC(op2) == IL_DCON) {
7817 INT numi[2];
7818 numi[0] = ILI_OPND(op1, 1);
7819 numi[1] = ILI_OPND(op2, 1);
7820 return ad1ili(IL_DCMPLXCON, getcon(numi, DT_DCMPLX));
7821 }
7822 break;
7823 case IL_SPSP2SCMPLXI0:
7824 op1 = ilip->opnd[0];
7825 if (ILI_OPC(op1) == IL_FCON) {
7826 INT numi[2];
7827 numi[0] = CONVAL2G(ILI_OPND(op1, 1));
7828 numi[1] = 0;
7829 return ad1ili(IL_SCMPLXCON, getcon(numi, DT_CMPLX));
7830 }
7831 break;
7832 case IL_SPSP2SCMPLX:
7833 op1 = ilip->opnd[0];
7834 op2 = ilip->opnd[1];
7835 if (ILI_OPC(op1) == IL_FCON && ILI_OPC(op2) == IL_FCON) {
7836 INT numi[2];
7837 numi[0] = CONVAL2G(ILI_OPND(op1, 1));
7838 numi[1] = CONVAL2G(ILI_OPND(op2, 1));
7839 return ad1ili(IL_SCMPLXCON, getcon(numi, DT_CMPLX));
7840 }
7841 break;
7842 case IL_DCMPLX2REAL:
7843 op1 = ilip->opnd[0];
7844 if (ILI_OPC(op1) == IL_DPDP2DCMPLX || ILI_OPC(op1) == IL_DPDP2DCMPLXI0) {
7845 return ILI_OPND(op1, 1);
7846 } else if (ILI_OPC(op1) == IL_DCMPLXCON) {
7847 return ad1ili(IL_DCON, CONVAL1G(ILI_OPND(op1, 1)));
7848 }
7849 break;
7850 case IL_DCMPLX2IMAG:
7851 op1 = ilip->opnd[0];
7852 if (ILI_OPC(op1) == IL_DPDP2DCMPLX) {
7853 return ILI_OPND(op1, 2);
7854 } else if (ILI_OPC(op1) == IL_DPDP2DCMPLXI0) {
7855 return ad1ili(IL_DCON, stb.dbl0);
7856 } else if (ILI_OPC(op1) == IL_DCMPLXCON) {
7857 return ad1ili(IL_DCON, CONVAL2G(ILI_OPND(op1, 1)));
7858 }
7859 break;
7860 case IL_SCMPLX2REAL:
7861 op1 = ilip->opnd[0];
7862 if (ILI_OPC(op1) == IL_SPSP2SCMPLX || ILI_OPC(op1) == IL_SPSP2SCMPLXI0) {
7863 return ILI_OPND(op1, 1);
7864 } else if (ILI_OPC(op1) == IL_SCMPLXCON) {
7865 INT numi[2];
7866 numi[0] = 0;
7867 numi[1] = CONVAL1G(ILI_OPND(op1, 1));
7868 return ad1ili(IL_FCON, getcon(numi, DT_FLOAT));
7869 }
7870 break;
7871 case IL_SCMPLX2IMAG:
7872 op1 = ilip->opnd[0];
7873 if (ILI_OPC(op1) == IL_SPSP2SCMPLX) {
7874 return ILI_OPND(op1, 2);
7875 } else if (ILI_OPC(op1) == IL_SPSP2SCMPLXI0) {
7876 return ad1ili(IL_FCON, stb.flt0);
7877 } else if (ILI_OPC(op1) == IL_SCMPLXCON) {
7878 INT numi[2];
7879 numi[0] = 0;
7880 numi[1] = CONVAL2G(ILI_OPND(op1, 1));
7881 return ad1ili(IL_FCON, getcon(numi, DT_FLOAT));
7882 }
7883 break;
7884
7885 /* Use IL_ATOMICRMWI to detect atomic support. */
7886 case IL_CMPXCHGI:
7887 case IL_CMPXCHGKR:
7888 case IL_CMPXCHGA:
7889 case IL_ATOMICRMWI:
7890 case IL_ATOMICRMWKR:
7891 case IL_ATOMICRMWA:
7892 case IL_ATOMICRMWSP:
7893 case IL_ATOMICRMWDP:
7894 /* Can't allow sharing; use new_ili() */
7895 ilix = new_ili(ilip);
7896 return ilix;
7897 case IL_FENCE:
7898 if (value_of_irlnk_operand(ilip->opnd[1], MO_SEQ_CST) == MO_RELAXED) {
7899 /* Fence has no effect. */
7900 return ad_free(ilip->opnd[1]);
7901 }
7902 break;
7903 default:
7904 break;
7905 }
7906
7907 /* default return */
7908 return get_ili(ilip);
7909
7910 } /* addother */
7911
7912 /**
7913 * \brief adds branch ili
7914 */
7915 static int
addbran(ILI * ilip)7916 addbran(ILI *ilip)
7917 {
7918 int op1, op2;
7919 CC_RELATION cc_op2;
7920 CC_RELATION new_cond;
7921 CC_RELATION cond;
7922 int lab, cmp_val;
7923 int tmp;
7924
7925 union { /* constant value structure */
7926 INT numi[2];
7927 UINT numu[2];
7928 DBLE numd;
7929 } num1, num2;
7930
7931 op1 = ilip->opnd[0];
7932 if (ilip->opc != IL_JMP) {
7933 /* purify UMR: second operand isn't set for IL_JMP */
7934 op2 = ilip->opnd[1];
7935 cc_op2 = (CC_RELATION) op2;
7936 }
7937 switch (ilip->opc) {
7938
7939 case IL_LCJMPZ:
7940 /*
7941 * Fortran logical compare and jump:
7942 * op2 = 1 (EQ), jump if op1 is false
7943 * op2 = 2 (NE), jump if op1 is true
7944 */
7945 assert(cc_op2 == CC_EQ || cc_op2 == CC_NE, "addbran:bad stc of LCJMPZ", op2,
7946 ERR_Severe);
7947 switch (ILI_OPC(op1)) {
7948
7949 case IL_ICON:
7950 if (cc_op2 == CC_EQ) {
7951 if ((CONVAL2G(ILI_OPND(op1, 1)) & 1) == 0)
7952 return ad1ili(IL_JMP, (int)ilip->opnd[2]);
7953 } else { /* NE constant optimization */
7954 if (CONVAL2G(ILI_OPND(op1, 1)))
7955 return ad1ili(IL_JMP, (int)ilip->opnd[2]);
7956 }
7957 RFCNTD(ilip->opnd[2]);
7958 return 0;
7959
7960 case IL_ICMPZ: /* if the operand being tested is a compare */
7961 case IL_FCMPZ: /* ILI, switch to the ILI which does the */
7962 case IL_DCMPZ: /* integer compare with zero and branches */
7963 case IL_ACMPZ: /* if the condition is met */
7964 case IL_ICMP:
7965 case IL_FCMP:
7966 case IL_DCMP:
7967 case IL_ACMP:
7968 #if defined(TARGET_X8664)
7969 case IL_KCMPZ:
7970 case IL_KCMP:
7971 #endif
7972 return ad3ili(IL_ICJMPZ, op1, op2, ilip->opnd[2]);
7973
7974 case IL_NOT: /* remove the NOT and negate the condition */
7975 new_cond = (cc_op2 == CC_EQ) ? CC_NE : CC_EQ;
7976 return ad3ili(IL_LCJMPZ, (int)ILI_OPND(op1, 1), new_cond, ilip->opnd[2]);
7977
7978 default:
7979 break;
7980
7981 } /***** end of switch(ILI_OPC(op1)) *****/
7982
7983 /* generate sequence of AND and ICJMPZ ili */
7984 if (IL_RES(ILI_OPC(op1)) == ILIA_KR) {
7985 #if defined(TARGET_X8664)
7986 tmp = ad_kcon(0, 1);
7987 op1 = ad2ili(IL_KAND, op1, tmp);
7988 return ad3ili(IL_KCJMPZ, op1, op2, ilip->opnd[2]);
7989 #else
7990 op1 = ad1ili(IL_KIMV, op1);
7991 #endif
7992 }
7993 op1 = ad2ili(IL_AND, op1, ad_icon(1));
7994 return ad3ili(IL_ICJMPZ, op1, op2, ilip->opnd[2]);
7995
7996 case IL_ICJMPZ:
7997 switch (ILI_OPC(op1)) {
7998 default:
7999 break;
8000 case IL_ICON:
8001 cond = cc_op2;
8002 lab = ilip->opnd[2];
8003 cmp_val = icmp(CONVAL2G(ILI_OPND(op1, 1)), 0);
8004 goto fold_jmp;
8005
8006 case IL_ICMPZ:
8007 new_cond = combine_int_ccs(CC_ILI_OPND(op1, 2), cc_op2);
8008 if (new_cond == 0)
8009 break;
8010 return ad3ili(IL_ICJMPZ, ILI_OPND(op1, 1), new_cond, ilip->opnd[2]);
8011
8012 case IL_UICMPZ:
8013 new_cond = combine_int_ccs(CC_ILI_OPND(op1, 2), cc_op2);
8014 if (new_cond == 0)
8015 break;
8016 return ad3ili(IL_UICJMPZ, ILI_OPND(op1, 1), new_cond, ilip->opnd[2]);
8017
8018 case IL_KCMPZ:
8019 /*
8020 * Make sure the original condition is still used when
8021 * referencing the alternate (a ICMPZ) ili. Cannot fold
8022 * the condition twice!!!!
8023 */
8024 new_cond = combine_int_ccs(CC_ILI_OPND(op1, 2), cc_op2);
8025 if (new_cond == CC_EQ || new_cond == CC_NE) {
8026 return ad3ili(IL_KCJMPZ, ILI_OPND(op1, 1), new_cond, ilip->opnd[2]);
8027 }
8028 return ad3ili(IL_ICJMPZ, ILI_ALT(op1), op2, ilip->opnd[2]);
8029 case IL_UKCMPZ:
8030 new_cond = combine_int_ccs(CC_ILI_OPND(op1, 2), cc_op2);
8031 if (new_cond == 0)
8032 break;
8033 return ad3ili(IL_UKCJMPZ, ILI_OPND(op1, 1), new_cond, ilip->opnd[2]);
8034
8035 case IL_FCMPZ:
8036 new_cond = combine_int_ccs(CC_ILI_OPND(op1, 2), cc_op2);
8037 if (new_cond == 0)
8038 break;
8039 return ad3ili(IL_FCJMPZ, ILI_OPND(op1, 1), new_cond, ilip->opnd[2]);
8040
8041 case IL_DCMPZ:
8042 new_cond = combine_int_ccs(CC_ILI_OPND(op1, 2), cc_op2);
8043 if (new_cond == 0)
8044 break;
8045 return ad3ili(IL_DCJMPZ, ILI_OPND(op1, 1), new_cond, ilip->opnd[2]);
8046
8047 case IL_ACMPZ:
8048 new_cond = combine_int_ccs(CC_ILI_OPND(op1, 2), cc_op2);
8049 if (new_cond == 0)
8050 break;
8051 return ad3ili(IL_ACJMPZ, ILI_OPND(op1, 1), new_cond, ilip->opnd[2]);
8052
8053 case IL_ICMP:
8054 new_cond = combine_int_ccs(CC_ILI_OPND(op1, 3), cc_op2);
8055 if (new_cond == 0)
8056 break;
8057 return ad4ili(IL_ICJMP, ILI_OPND(op1, 1), ILI_OPND(op1, 2), new_cond,
8058 ilip->opnd[2]);
8059
8060 case IL_UICMP:
8061 new_cond = combine_int_ccs(CC_ILI_OPND(op1, 3), cc_op2);
8062 if (new_cond == 0)
8063 break;
8064 return ad4ili(IL_UICJMP, ILI_OPND(op1, 1), ILI_OPND(op1, 2), new_cond,
8065 ilip->opnd[2]);
8066 case IL_UKCMP:
8067 new_cond = combine_int_ccs(CC_ILI_OPND(op1, 3), cc_op2);
8068 if (new_cond == 0)
8069 break;
8070 return ad4ili(IL_UKCJMP, ILI_OPND(op1, 1), ILI_OPND(op1, 2), new_cond,
8071 ilip->opnd[2]);
8072 case IL_KCMP:
8073 new_cond = combine_int_ccs(CC_ILI_OPND(op1, 3), cc_op2);
8074 if (new_cond == 0)
8075 break;
8076 return ad4ili(IL_KCJMP, ILI_OPND(op1, 1), ILI_OPND(op1, 2), new_cond,
8077 ilip->opnd[2]);
8078
8079 case IL_FCMP:
8080 new_cond =
8081 (!IEEE_CMP)
8082 ? combine_int_ccs(CC_ILI_OPND(op1, 3), cc_op2)
8083 : combine_ieee_ccs(CC_ILI_OPND(op1, 3), cc_op2);
8084 if (new_cond == 0)
8085 break;
8086 return ad4ili(IL_FCJMP, ILI_OPND(op1, 1), ILI_OPND(op1, 2), new_cond,
8087 ilip->opnd[2]);
8088
8089 case IL_DCMP:
8090 new_cond = (!IEEE_CMP)
8091 ? combine_int_ccs(CC_ILI_OPND(op1, 3), cc_op2)
8092 : combine_ieee_ccs(CC_ILI_OPND(op1, 3), cc_op2);
8093 if (new_cond == 0)
8094 break;
8095 return ad4ili(IL_DCJMP, ILI_OPND(op1, 1), ILI_OPND(op1, 2), new_cond,
8096 ilip->opnd[2]);
8097
8098 case IL_ACMP:
8099 if ((new_cond = combine_int_ccs(CC_ILI_OPND(op1, 3), cc_op2)) ==
8100 0)
8101 break;
8102 return ad4ili(IL_ACJMP, ILI_OPND(op1, 1), ILI_OPND(op1, 2), new_cond,
8103 ilip->opnd[2]);
8104
8105 } /***** end of switch(ILI_OPC(op1)) *****/
8106
8107 break;
8108
8109 case IL_ICJMP:
8110
8111 /* 0/1 <rel> i --> i <rev(rel)>z */
8112
8113 cond = CCRelationILIOpnd(ilip, 2);
8114 if (ILI_OPC(op1) == IL_ICON) {
8115 if (ILI_OPND(op1, 1) == stb.i0)
8116 return ad3ili(IL_ICJMPZ, op2, commute_cc(cond), ilip->opnd[3]);
8117 if (ILI_OPND(op1, 1) == stb.i1) {
8118 if (cond == CC_LE)
8119 /* 1 LE x --> x GT z */
8120 return ad3ili(IL_ICJMPZ, op2, CC_GT, ilip->opnd[3]);
8121 if (cond == CC_GT)
8122 /* 1 GT x --> x LE z */
8123 return ad3ili(IL_ICJMPZ, op2, CC_LE, ilip->opnd[3]);
8124 }
8125 if (CONVAL2G(ILI_OPND(op1, 1)) >= 1 && is_zero_one(op2)) {
8126 /* low-quality range analysis */
8127 switch (cond) {
8128 case CC_EQ:
8129 case CC_LE:
8130 if (CONVAL2G(ILI_OPND(op1, 1)) > 1) {
8131 /* 2 <= x is false */
8132 if (func_in(op2))
8133 break;
8134 RFCNTD(ilip->opnd[3]);
8135 return 0;
8136 }
8137 /* 1 <= x becomes x != 0 */
8138 return ad3ili(IL_ICJMPZ, op2, CC_NE, ilip->opnd[3]);
8139 case CC_NE:
8140 case CC_GT:
8141 if (CONVAL2G(ILI_OPND(op1, 1)) > 1) {
8142 /* 2 > x is true */
8143 if (func_in(op2))
8144 break;
8145 return ad1ili(IL_JMP, ilip->opnd[3]);
8146 }
8147 /* 1 > x becomes x == 0 */
8148 return ad3ili(IL_ICJMPZ, op2, CC_EQ, ilip->opnd[3]);
8149 case CC_LT: /* 1 < x never true */
8150 if (func_in(op2))
8151 break;
8152 RFCNTD(ilip->opnd[3]);
8153 return 0;
8154 case CC_GE: /* 1 >= x always true */
8155 if (func_in(op2))
8156 break;
8157 return ad1ili(IL_JMP, ilip->opnd[3]);
8158 }
8159 }
8160
8161 /* constant <rel> constant ---> constant fold */
8162 if (ILI_OPC(op2) == IL_ICON) {
8163 lab = ilip->opnd[3];
8164 cmp_val = icmp(CONVAL2G(ILI_OPND(op1, 1)), CONVAL2G(ILI_OPND(op2, 1)));
8165 goto fold_jmp;
8166 }
8167 }
8168
8169 /* i <rel> 0/1 --> i <rel>z */
8170
8171 if (ILI_OPC(op2) == IL_ICON) {
8172 if (ILI_OPND(op2, 1) == stb.i0)
8173 return ad3ili(IL_ICJMPZ, op1, cond, (int)ilip->opnd[3]);
8174 if (ILI_OPND(op2, 1) == stb.i1) {
8175 if (cond == CC_GE)
8176 /* x GE 1 --> x GT z */
8177 return ad3ili(IL_ICJMPZ, op1, CC_GT, (int)ilip->opnd[3]);
8178 if (cond == CC_LT)
8179 /* x LT 1 --> x LE z */
8180 return ad3ili(IL_ICJMPZ, op1, CC_LE, (int)ilip->opnd[3]);
8181 }
8182 if (CONVAL2G(ILI_OPND(op2, 1)) >= 1 && is_zero_one(op1)) {
8183 /* low-quality range analysis */
8184 switch (cond) {
8185 case CC_EQ:
8186 case CC_GE:
8187 if (CONVAL2G(ILI_OPND(op2, 1)) > 1) {
8188 /* x >= 2 is false */
8189 if (func_in(op1))
8190 break;
8191 RFCNTD(ilip->opnd[3]);
8192 return 0;
8193 }
8194 /* x >= 1 becomes x != 0 */
8195 return ad3ili(IL_ICJMPZ, op1, CC_NE, ilip->opnd[3]);
8196 case CC_NE:
8197 case CC_LT:
8198 if (CONVAL2G(ILI_OPND(op2, 1)) > 1) {
8199 /* x < 2 is true */
8200 if (func_in(op1))
8201 break;
8202 return ad1ili(IL_JMP, ilip->opnd[3]);
8203 }
8204 /* x < 1 becomes x == 0 */
8205 return ad3ili(IL_ICJMPZ, op1, CC_EQ, ilip->opnd[3]);
8206 case CC_GT: /* x > 1 never true */
8207 if (func_in(op1))
8208 break;
8209 RFCNTD(ilip->opnd[3]);
8210 return 0;
8211 case CC_LE: /* x <= 1 always true */
8212 if (func_in(op1))
8213 break;
8214 return ad1ili(IL_JMP, ilip->opnd[3]);
8215 }
8216 }
8217 }
8218 goto cjmp_2; /* check if operands are identical */
8219
8220 case IL_UICJMPZ:
8221 switch (ILI_OPC(op1)) {
8222 case IL_ICON:
8223 cond = cc_op2;
8224 lab = ilip->opnd[2];
8225 cmp_val = xucmp(CONVAL2G(ILI_OPND(op1, 1)), (INT)0);
8226 goto fold_jmp;
8227
8228 default:
8229 switch (op2) {
8230 case CC_EQ:
8231 break;
8232
8233 case CC_NE:
8234 break;
8235
8236 case CC_LT:
8237 if (func_in(op1))
8238 break;
8239 RFCNTD(ilip->opnd[2]);
8240 return 0;
8241
8242 case CC_GE:
8243 if (func_in(op1))
8244 break;
8245 return ad1ili(IL_JMP, (int)ilip->opnd[2]);
8246
8247 case CC_LE:
8248 ilip->opnd[1] = CC_EQ;
8249 break;
8250
8251 case CC_GT:
8252 ilip->opnd[1] = CC_NE;
8253 break;
8254 }
8255 break;
8256
8257 } /***** end of switch(ILI_OPC(op1)) *****/
8258
8259 break;
8260
8261 case IL_UICJMP:
8262
8263 /* 0 <rel> i --> i <rev(rel)>z */
8264
8265 if (ILI_OPC(op1) == IL_ICON) {
8266 if (ILI_OPND(op1, 1) == stb.i0)
8267 return ad3ili(IL_UICJMPZ, op2, commute_cc(CCRelationILIOpnd(ilip, 2)),
8268 (int)ilip->opnd[3]);
8269
8270 /* constant <rel> constant ---> constant fold */
8271 if (ILI_OPC(op2) == IL_ICON) {
8272 cond = CCRelationILIOpnd(ilip, 2);
8273 lab = ilip->opnd[3];
8274 cmp_val = xucmp(CONVAL2G(ILI_OPND(op1, 1)), CONVAL2G(ILI_OPND(op2, 1)));
8275 goto fold_jmp;
8276 }
8277 }
8278
8279 /* i <rel> 0 --> i <rel>z */
8280
8281 if (ILI_OPC(op2) == IL_ICON && ILI_OPND(op2, 1) == stb.i0)
8282 return ad3ili(IL_UICJMPZ, op1, (int)ilip->opnd[2], (int)ilip->opnd[3]);
8283 goto cjmp_2; /* check if operands are identical */
8284
8285 case IL_KCJMPZ:
8286 if (ILI_OPC(op1) == IL_KCON) {
8287 cond = cc_op2;
8288 lab = ilip->opnd[2];
8289 GETVALI64(num1, ILI_OPND(op1, 1));
8290 GETVALI64(num2, stb.k0);
8291 cmp_val = cmp64(num1.numi, num2.numi);
8292 goto fold_jmp;
8293 }
8294 break;
8295 case IL_KCJMP:
8296 /* 0 <rel> i --> i <rev(rel)>z */
8297 if (ILI_OPC(op1) == IL_KCON) {
8298 if (ILI_OPND(op1, 1) == stb.k0)
8299 return ad3ili(IL_KCJMPZ, op2, commute_cc(CCRelationILIOpnd(ilip, 2)),
8300 ilip->opnd[3]);
8301
8302 /* constant <rel> constant ---> constant fold */
8303 if (ILI_OPC(op2) == IL_KCON) {
8304 cond = CCRelationILIOpnd(ilip, 2);
8305 lab = ilip->opnd[3];
8306 GETVALI64(num1, ILI_OPND(op1, 1));
8307 GETVALI64(num2, ILI_OPND(op2, 1));
8308 cmp_val = cmp64(num1.numi, num2.numi);
8309 goto fold_jmp;
8310 }
8311 }
8312
8313 /* i <rel> 0 --> i <rel>z */
8314 if (ILI_OPC(op2) == IL_KCON && ILI_OPND(op2, 1) == stb.k0)
8315 return ad3ili(IL_KCJMPZ, op1, (int)ilip->opnd[2], (int)ilip->opnd[3]);
8316 goto cjmp_2; /* check if operands are identical */
8317 case IL_UKCJMPZ:
8318 switch (ILI_OPC(op1)) {
8319 case IL_KCON:
8320 cond = cc_op2;
8321 lab = ilip->opnd[2];
8322 GETVALI64(num1, ILI_OPND(op1, 1));
8323 GETVALI64(num2, stb.k0);
8324 cmp_val = ucmp64(num1.numu, num2.numu);
8325 goto fold_jmp;
8326 default:
8327 switch (op2) {
8328 case CC_EQ:
8329 break;
8330 case CC_NE:
8331 break;
8332 case CC_LT:
8333 if (func_in(op1))
8334 break;
8335 RFCNTD(ilip->opnd[2]);
8336 return 0;
8337 case CC_GE:
8338 if (func_in(op1))
8339 break;
8340 return ad1ili(IL_JMP, (int)ilip->opnd[2]);
8341 case CC_LE:
8342 ilip->opnd[1] = CC_EQ;
8343 break;
8344 case CC_GT:
8345 ilip->opnd[1] = CC_NE;
8346 break;
8347 }
8348 break;
8349
8350 } /***** IL_UKCJMPZ: end of switch(ILI_OPC(op1)) *****/
8351 break;
8352 case IL_UKCJMP:
8353 /* 0 <rel> i --> i <rev(rel)>z */
8354 if (ILI_OPC(op1) == IL_KCON) {
8355 if (ILI_OPND(op1, 1) == stb.k0)
8356 return ad3ili(IL_UKCJMPZ, op2,
8357 commute_cc(CCRelationILIOpnd(ilip, 2)),
8358 ilip->opnd[3]);
8359
8360 /* constant <rel> constant ---> constant fold */
8361 if (ILI_OPC(op2) == IL_KCON) {
8362 cond = CCRelationILIOpnd(ilip, 2);
8363 lab = ilip->opnd[3];
8364 GETVALI64(num1, ILI_OPND(op1, 1));
8365 GETVALI64(num2, ILI_OPND(op2, 1));
8366 cmp_val = ucmp64(num1.numu, num2.numu);
8367 goto fold_jmp;
8368 }
8369 }
8370 /* i <rel> 0 --> i <rel>z */
8371 if (ILI_OPC(op2) == IL_KCON && ILI_OPND(op2, 1) == stb.k0)
8372 return ad3ili(IL_UKCJMPZ, op1, (int)ilip->opnd[2], (int)ilip->opnd[3]);
8373 goto cjmp_2; /* check if operands are identical */
8374
8375 case IL_FCJMPZ:
8376 if (ILI_OPC(op1) == IL_FCON && IS_FLT0(ILI_OPND(op1, 1))) {
8377 if (op2 == CC_EQ || op2 == CC_GE || op2 == CC_LE || op2 == CC_NOTNE ||
8378 op2 == CC_NOTLT || op2 == CC_NOTGT)
8379 return ad1ili(IL_JMP, (int)ilip->opnd[2]);
8380 RFCNTD(ilip->opnd[2]);
8381 return 0;
8382 }
8383 #if defined(TARGET_X86) && !defined(TARGET_LLVM_ARM)
8384 if (mach.feature[FEATURE_SCALAR_SSE]) { /* scalar sse code gen. don't use
8385 FCJMPZ */
8386 tmp = ad1ili(IL_FCON, stb.flt0);
8387 return ad4ili(IL_FCJMP, op1, tmp, op2, (int)ilip->opnd[2]);
8388 }
8389 #endif
8390 #ifndef TM_FCJMPZ
8391 tmp = ad1ili(IL_FCON, stb.flt0);
8392 return ad4ili(IL_FCJMP, op1, tmp, op2, (int)ilip->opnd[2]);
8393 #endif
8394 break;
8395
8396 case IL_FCJMP:
8397 #if defined(TARGET_X86)
8398 if (mach.feature[FEATURE_SCALAR_SSE]) {
8399 /* scalar sse code gen. don't use FCJMPZ; it costs less to
8400 * 'compute' 0.0 rather than fetch from memory
8401 */
8402 goto nogen_fcjmpz;
8403 }
8404 #endif
8405 #ifdef TM_FCJMPZ
8406 if (ILI_OPC(op1) == IL_FCON && IS_FLT0(ILI_OPND(op1, 1)))
8407 return ad3ili(IL_FCJMPZ, op2,
8408 commute_cc(CCRelationILIOpnd(ilip, 2)),
8409 ilip->opnd[3]);
8410 if (ILI_OPC(op2) == IL_FCON && IS_FLT0(ILI_OPND(op2, 1)))
8411 return ad3ili(IL_FCJMPZ, op1, ilip->opnd[2], ilip->opnd[3]);
8412 #endif
8413 nogen_fcjmpz:
8414 if (op1 == op2 && ILI_OPC(op2) == IL_FCON && !_is_nanf(ILI_OPND(op2, 1))) {
8415 cond = CCRelationILIOpnd(ilip, 2);
8416 if (cond == CC_EQ || cond == CC_GE || cond == CC_LE || cond == CC_NOTNE ||
8417 cond == CC_NOTLT || cond == CC_NOTGT)
8418 return ad1ili(IL_JMP, (int)ilip->opnd[3]);
8419 RFCNTD(ilip->opnd[3]);
8420 return 0;
8421 }
8422 if (!IEEE_CMP)
8423 goto cjmp_2; /* check if operands are identical */
8424 break;
8425
8426 case IL_DCJMPZ:
8427 if (ILI_OPC(op1) == IL_DCON && IS_DBL0(ILI_OPND(op1, 1))) {
8428 if (op2 == CC_EQ || op2 == CC_GE || op2 == CC_LE || op2 == CC_NOTNE ||
8429 op2 == CC_NOTLT || op2 == CC_NOTGT)
8430 return ad1ili(IL_JMP, ilip->opnd[2]);
8431 RFCNTD(ilip->opnd[2]);
8432 return 0;
8433 }
8434 #if defined(TARGET_X86)
8435 if (mach.feature[FEATURE_SCALAR_SSE]) {
8436 /* scalar sse code gen. don't use DCJMPZ */
8437 tmp = ad1ili(IL_DCON, stb.dbl0);
8438 return ad4ili(IL_DCJMP, op1, tmp, op2, (int)ilip->opnd[2]);
8439 }
8440 #endif
8441 #ifndef TM_DCJMPZ
8442 tmp = ad1ili(IL_DCON, stb.dbl0);
8443 return ad4ili(IL_DCJMP, op1, tmp, op2, (int)ilip->opnd[2]);
8444 #endif
8445 break;
8446
8447 case IL_DCJMP:
8448 #if defined(TARGET_X86)
8449 if (mach.feature[FEATURE_SCALAR_SSE]) {
8450 /* scalar sse code gen. don't use DCJMPZ; it costs less to
8451 * 'compute' 0.0 rather than fetch from memory
8452 */
8453 goto nogen_dcjmpz;
8454 }
8455 #endif
8456 #ifdef TM_DCJMPZ
8457 if (ILI_OPC(op1) == IL_DCON && IS_DBL0(ILI_OPND(op1, 1)))
8458 return ad3ili(IL_DCJMPZ, op2, commute_cc(CCRelationILIOpnd(ilip, 2)),
8459 ilip->opnd[3]);
8460 if (ILI_OPC(op2) == IL_DCON && IS_DBL0(ILI_OPND(op2, 1)))
8461 return ad3ili(IL_DCJMPZ, op1, ilip->opnd[2], ilip->opnd[3]);
8462 #endif
8463 nogen_dcjmpz:
8464 if (op1 == op2 && (ILI_OPC(op2) == IL_DCON) &&
8465 !_is_nand(ILI_SymOPND(op2, 1))) {
8466 cond = CCRelationILIOpnd(ilip, 2);
8467 if (cond == CC_EQ || cond == CC_GE || cond == CC_LE || cond == CC_NOTNE ||
8468 cond == CC_NOTLT || cond == CC_NOTGT)
8469 return ad1ili(IL_JMP, (int)ilip->opnd[3]);
8470 RFCNTD(ilip->opnd[3]);
8471 return 0;
8472 }
8473 if (!IEEE_CMP)
8474 goto cjmp_2; /* check if operands are identical */
8475 break;
8476
8477 case IL_ACJMPZ:
8478 if (ILI_OPC(op1) == IL_ACON) {
8479 int sym;
8480 sym = CONVAL1G(ILI_OPND(op1, 1));
8481 if (sym == 0) {
8482 INT v;
8483 v = CONVAL2G(ILI_OPND(op1, 1));
8484 switch (op2) {
8485 case CC_EQ:
8486 case CC_LE:
8487 tmp = v == 0;
8488 break;
8489 case CC_NE:
8490 case CC_GT:
8491 tmp = v != 0;
8492 break;
8493 case CC_LT:
8494 tmp = 0;
8495 break;
8496 case CC_GE:
8497 tmp = 1;
8498 break;
8499 }
8500 if (tmp)
8501 return ad1ili(IL_JMP, ilip->opnd[2]);
8502 RFCNTD(ilip->opnd[2]);
8503 return 0;
8504 }
8505 /* comparing an address with NULL */
8506 switch (op2) {
8507 case CC_LT:
8508 RFCNTD(ilip->opnd[2]);
8509 return 0;
8510 case CC_EQ:
8511 case CC_LE:
8512 if (IS_LCL_OR_DUM(sym) || CCSYMG(sym)) {
8513 RFCNTD(ilip->opnd[2]);
8514 return 0;
8515 }
8516 break;
8517 case CC_GE:
8518 return ad1ili(IL_JMP, ilip->opnd[2]);
8519 default:
8520 if (IS_LCL_OR_DUM(sym) || CCSYMG(sym))
8521 return ad1ili(IL_JMP, ilip->opnd[2]);
8522 break;
8523 }
8524 }
8525 break;
8526
8527 case IL_ACJMP:
8528 if (ILI_OPC(op1) == IL_ACON && CONVAL1G(ILI_OPND(op1, 1)) == 0 &&
8529 CONVAL2G(ILI_OPND(op1, 1)) == 0)
8530 return ad3ili(IL_ACJMPZ, op2,
8531 commute_cc(CCRelationILIOpnd(ilip, 2)), ilip->opnd[3]);
8532 if (ILI_OPC(op2) == IL_ACON && CONVAL1G(ILI_OPND(op2, 1)) == 0 &&
8533 CONVAL2G(ILI_OPND(op2, 1)) == 0)
8534 return ad3ili(IL_ACJMPZ, op1, ilip->opnd[2], ilip->opnd[3]);
8535 cjmp_2:
8536 if (op1 == op2 && !func_in(op1)) {
8537 /* i <rel> i --> jmp or fall thru */
8538 cond = CCRelationILIOpnd(ilip, 2);
8539 if (cond == CC_EQ || cond == CC_GE || cond == CC_LE)
8540 return ad1ili(IL_JMP, ilip->opnd[3]);
8541 RFCNTD(ilip->opnd[3]);
8542 return 0;
8543 }
8544 break;
8545
8546 case IL_JMPM:
8547
8548 /* not cased for JMPMs in C because:
8549 * 1. JMPM ili does not provide enough information to associate jump
8550 * table value with the case label (more than 1 JMPM can be generated
8551 * for a single C switch; lower bound is not provided). For Fortran,
8552 * the range is simply [0, n-1]; precisely one JMPM is generated for
8553 * a computed goto.
8554 * 2. fortran is well-behaved wrt completeness of the jump table
8555 * (table in C may have holes),
8556 * 3. for fortran, default case is next block (default label is 4th
8557 * operand).
8558 */
8559 if (ILI_OPC(op1) == IL_ICON) {
8560 int swarr; /* cc sym representing table of labels */
8561 int n; /* number of cases in JMPM */
8562 int tv; /* constant index value for jmp */
8563 int v; /* current index value of jmpm label */
8564 int lab; /* eventual target of JMPM; 0 => default */
8565 SWEL *swel; /* curr SWEL ptr - linear for fortran */
8566
8567 swarr = ilip->opnd[2];
8568 #if DEBUG
8569 assert(ilip->opnd[3], "addbranJMPM 4th opnd zero", swarr, ERR_Severe);
8570 assert(ILI_OPC(op2) == IL_ICON, "addbranJMPM, range not icon", op2,
8571 ERR_Severe);
8572 #endif
8573 n = CONVAL2G(ILI_OPND(op2, 1));
8574 tv = CONVAL2G(ILI_OPND(op1, 1));
8575 lab = 0;
8576 RFCNTD(ilip->opnd[3]); /* no need for default */
8577 swel = switch_base + SWELG(swarr);
8578 for (v = 0; v < n; v++, swel++) {
8579 RFCNTD(swel->clabel);
8580 if (v == tv)
8581 lab = swel->clabel;
8582 };
8583 if (lab) {
8584 RFCNTI(lab);
8585 return ad1ili(IL_JMP, lab);
8586 }
8587 return 0;
8588 }
8589 break;
8590
8591 } /***** end of switch(ilip->opc) *****/
8592
8593 return get_ili(ilip);
8594
8595 fold_jmp:
8596 switch (cond) {
8597 case CC_EQ:
8598 if (cmp_val == 0)
8599 return ad1ili(IL_JMP, lab);
8600 break;
8601 case CC_NE:
8602 if (cmp_val != 0)
8603 return ad1ili(IL_JMP, lab);
8604 break;
8605 case CC_LT:
8606 if (cmp_val < 0)
8607 return ad1ili(IL_JMP, lab);
8608 break;
8609 case CC_GE:
8610 if (cmp_val >= 0)
8611 return ad1ili(IL_JMP, lab);
8612 break;
8613 case CC_LE:
8614 if (cmp_val <= 0)
8615 return ad1ili(IL_JMP, lab);
8616 break;
8617 case CC_GT:
8618 if (cmp_val > 0)
8619 return ad1ili(IL_JMP, lab);
8620 break;
8621 }
8622 RFCNTD(lab);
8623 return 0;
8624 }
8625
8626 bool is_floating_comparison_opcode(ILI_OP opc);
8627
8628 /** \brief adds a branch ili by complementing the condition
8629 *
8630 * This routine adds a branch ili whose condition is the complement of the
8631 * condition specified by the ili ilix. lbl is the target of the branch. The
8632 * complement is defined by the following: (Z, NZ), (LT, GE), LE, GT)
8633 */
8634 int
compl_br(int ilix,int lbl)8635 compl_br(int ilix, int lbl)
8636 {
8637 ILI New;
8638 int i;
8639 ILI_OP opc;
8640
8641 opc = ILI_OPC(ilix);
8642 i = ilis[opc].oprs;
8643 New.opc = opc;
8644 New.opnd[--i] = lbl;
8645 if (is_floating_comparison_opcode(opc)) {
8646 New.opnd[i - 1] = complement_ieee_cc(CC_ILI_OPND(ilix, i));
8647 } else {
8648 New.opnd[i - 1] = complement_int_cc(CC_ILI_OPND(ilix, i));
8649 }
8650 while (--i > 0)
8651 New.opnd[i - 1] = ILI_OPND(ilix, i);
8652 return addili((ILI *)&New);
8653 }
8654
8655 /**
8656 * \brief compare two INTs
8657 */
8658 static INT
icmp(INT v1,INT v2)8659 icmp(INT v1, INT v2)
8660 {
8661 if (v1 < v2)
8662 return -1;
8663 if (v1 > v2)
8664 return 1;
8665 return 0;
8666 }
8667
8668 /**
8669 * \brief convert a compare value to a logical value for a relation
8670 *
8671 * Converts the result (val) of comparison to a logical value based on the
8672 * relation rel. The possible values of a comparison and their meanings are:
8673 * <pre>
8674 * -1 - op1 < op2
8675 * 0 - op1 = op2
8676 * 1 - op1 > op2
8677 * </pre>
8678 * The values of rel and their meanings are enumerated in the switch
8679 * statement.
8680 */
8681 static INT
cmp_to_log(INT val,int rel)8682 cmp_to_log(INT val, int rel)
8683 {
8684 INT logval;
8685
8686 switch (rel) {
8687 case CC_EQ:
8688 case CC_NOTNE:
8689 logval = (val & 1) ^ 1;
8690 break;
8691 case CC_NE:
8692 case CC_NOTEQ:
8693 logval = val & 1;
8694 break;
8695 case CC_LT:
8696 case CC_NOTGE:
8697 logval = ((unsigned)val) >> 31;
8698 break;
8699 case CC_GE:
8700 case CC_NOTLT:
8701 logval = (((unsigned)val) >> 31) ^ 1;
8702 break;
8703 case CC_LE:
8704 case CC_NOTGT:
8705 logval = icmp((INT)1, val);
8706 break;
8707 case CC_GT:
8708 case CC_NOTLE:
8709 logval = icmp((INT)1, val) ^ 1;
8710 break;
8711 default:
8712 interr("cmp_to_log: bad relation", rel, ERR_Severe);
8713 return 0;
8714 }
8715 /*
8716 * At this point, logval's value is either 1 or 0 (C's definition of
8717 * logical value); watch for fortran ...
8718 */
8719 logval = logval ? SCFTN_TRUE : SCFTN_FALSE;
8720 return logval;
8721 }
8722
8723 /** \brief Subtract two integers and check for overflow */
8724 static bool
isub_ovf(INT c1,INT c2,INT * r)8725 isub_ovf(INT c1, INT c2, INT *r)
8726 {
8727 *r = c1 - c2;
8728 /* overflow if signs of c1 and c2 are different and the sign of the
8729 * result is different than the sign of c1.
8730 */
8731 if (((c1 ^ c2) >> 31) && ((c1 ^ *r) >> 31))
8732 return true;
8733 return false;
8734 }
8735
8736 /** \brief Add two integers and check for overflow */
8737 static bool
iadd_ovf(INT c1,INT c2,INT * r)8738 iadd_ovf(INT c1, INT c2, INT *r)
8739 {
8740 *r = c1 + c2;
8741 /* overflow if signs of c1 and c2 are the same and the sign of the
8742 * result is different.
8743 */
8744 if (((c1 ^ c2) >> 31) == 0 && ((c1 ^ *r) >> 31))
8745 return true;
8746 return false;
8747 }
8748
8749 /**
8750 * \brief enter ili into ILI area by attempting to share
8751 */
8752 static int
get_ili(ILI * ilip)8753 get_ili(ILI *ilip)
8754 {
8755 int i, p;
8756 int indx, tab;
8757 ILI_OP opc = ilip->opc;
8758 int val = opc;
8759 int noprs = ilis[opc].oprs;
8760
8761 /* compute the hash index for this ILI */
8762
8763 for (i = 0; i < noprs; i++)
8764 val ^= (ilip->opnd[i] >> (i * 4));
8765 indx = val % ILHSHSZ;
8766 /*
8767 * calculate which hash table to use which is based on the number of
8768 * operands
8769 */
8770
8771 assert(noprs <= ILTABSZ, "get_ili: noprs > ILTABSZ", opc, ERR_Severe);
8772 tab = (noprs == 0) ? 0 : noprs - 1;
8773 /* search the hash links for this ILI */
8774
8775 for (p = ilhsh[tab][indx]; p != 0; p = ILI_HSHLNK(p)) {
8776 if (opc == ILI_OPC(p)) {
8777 for (i = 1; i <= noprs; i++)
8778 if (ilip->opnd[i - 1] != ILI_OPND(p, i))
8779 goto next;
8780 return p; /* F O U N D */
8781 }
8782 next:;
8783 }
8784
8785 /*
8786 * NOT FOUND -- if no more storage is available, check for zero use
8787 * counts. If one does not exist, get more storage
8788 */
8789
8790 p = STG_NEXT_FREELIST(ilib);
8791
8792 /*
8793 * NEW ENTRY - add the ili to the ili area and to its hash chain
8794 */
8795 BZERO(&ilib.stg_base[p], ILI, 1);
8796 ILI_OPCP(p, opc);
8797 for (i = 1; i <= noprs; i++)
8798 ILI_OPND(p, i) = ilip->opnd[i - 1];
8799 for (i = noprs + 1; i <= MAX_OPNDS; i++)
8800 ILI_OPND(p, i) = 0;
8801 #if DEBUG
8802 for (i = 1; i <= noprs; ++i) {
8803 if (IL_ISLINK(opc, i)) {
8804 int opnd;
8805 opnd = ILI_OPND(p, i);
8806 if (opnd < 0 || opnd >= ilib.stg_size ||
8807 ILI_OPC(opnd) == GARB_COLLECTED) {
8808 interr("bad ili link in get_ili", opc, ERR_Severe);
8809 }
8810 }
8811 }
8812 #endif
8813
8814 ILI_HSHLNK(p) = ilhsh[tab][indx];
8815 ilhsh[tab][indx] = p;
8816 /*
8817 * Initialize nonzero fields of the ili - (here and in new_ili()).
8818 */
8819 return p;
8820 }
8821
8822 /* wrapper of new_ili for external reference. */
8823
8824 int
get_ili_ns(ILI * ilip)8825 get_ili_ns(ILI *ilip)
8826 {
8827 return new_ili(ilip);
8828 }
8829
8830 /**
8831 \brief enter ili into ILI area (no sharing)
8832 */
8833 static int
new_ili(ILI * ilip)8834 new_ili(ILI *ilip)
8835 {
8836 int i, p;
8837 ILI_OP opc;
8838 int noprs;
8839
8840 opc = ilip->opc;
8841 noprs = ilis[opc].oprs;
8842
8843 #if DEBUG
8844 assert(noprs <= ILTABSZ, "new_ili: noprs > ILTABSZ", opc, ERR_Severe);
8845 #endif
8846
8847 /* NEW ENTRY */
8848 p = STG_NEXT_FREELIST(ilib);
8849
8850 BZERO(&ilib.stg_base[p], ILI, 1);
8851 ILI_OPCP(p, opc);
8852 for (i = 1; i <= noprs; i++)
8853 ILI_OPND(p, i) = ilip->opnd[i - 1];
8854 for (i = noprs + 1; i <= MAX_OPNDS; i++)
8855 ILI_OPND(p, i) = 0;
8856
8857 ILI_HSHLNK(p) = 0;
8858 /*
8859 * Initialize nonzero fields of the ili - (here and in get_ili()).
8860 */
8861 return p;
8862 }
8863
8864 /* GARBAGE COLLECTION */
8865
8866 static void mark_ili(int);
8867
8868 /** \brief Sort the free list
8869 *
8870 * Sorting the free list removes a source of indeterminacy from the
8871 * compiler's intermediate representation that would otherwise be
8872 * introduced by hashing the ILIs.
8873 */
8874 static int
sort_free_list(int head)8875 sort_free_list(int head)
8876 {
8877 int last, split[2];
8878
8879 /* Split the list into two lists via alternation */
8880 split[0] = split[1] = 0;
8881 for (last = 0; head; last ^= 1) {
8882 int next = ILI_HSHLNK(head);
8883 ILI_HSHLNK(head) = split[last];
8884 split[last] = head;
8885 head = next;
8886 }
8887
8888 /* Recursively sort the split lists */
8889 if (!split[1])
8890 return split[0];
8891 split[0] = sort_free_list(split[0]);
8892 split[1] = sort_free_list(split[1]);
8893
8894 /* Merge the sorted split lists */
8895 for (last = 0; split[0] && split[1];) {
8896 int which = split[1] < split[0];
8897 int at = split[which];
8898 split[which] = ILI_HSHLNK(at);
8899 if (last)
8900 ILI_HSHLNK(last) = at;
8901 else
8902 head = at;
8903 last = at;
8904 }
8905 ILI_HSHLNK(last) = split[split[1] > 0];
8906 return head;
8907 }
8908
8909 void
garbage_collect(void (* mark_function)(int))8910 garbage_collect(void (*mark_function)(int))
8911 {
8912 int i, j, p, q, t;
8913
8914 /* first, go through and mark all the ili that are reachable from
8915 * the ILT. Then, call mark_function to mark any ILI that may not
8916 * be reachable from the ILT.
8917 */
8918 if (DBGBIT(10, 2048))
8919 return;
8920 #if DEBUG
8921 if (DBGBIT(10, 1024)) {
8922 fprintf(gbl.dbgfil, "garbage: before collect: avail: %d, free: %d\n",
8923 ilib.stg_avail, ilib.stg_free);
8924 }
8925 #endif
8926 mark_ili(GARB_VISITED);
8927 if (mark_function != 0)
8928 (*mark_function)(GARB_VISITED);
8929
8930 /* ILI #0, #1 is special */
8931 ILI_VISIT(0) = ILI_VISIT(1) = GARB_VISITED;
8932 /* next, go through the hash chains and delete anything that wasn't
8933 * marked reachable, putting the freed ili on the linked list.
8934 */
8935 for (i = 0; i < ILTABSZ; ++i)
8936 for (j = 0; j < ILHSHSZ; ++j) {
8937 q = 0;
8938 for (p = ilhsh[i][j]; p != 0;) {
8939 if (ILI_VISIT(p) == GARB_UNREACHABLE) {
8940 /* unreachable */
8941 if (q == 0)
8942 ilhsh[i][j] = ILI_HSHLNK(p);
8943 else
8944 ILI_HSHLNK(q) = ILI_HSHLNK(p);
8945 t = p;
8946 p = ILI_HSHLNK(p);
8947 STG_ADD_FREELIST(ilib, t);
8948 ILI_OPCP(t, GARB_COLLECTED);
8949 ILI_VISIT(t) = GARB_COLLECTED;
8950 } else {
8951 /* reachable */
8952 q = p;
8953 p = ILI_HSHLNK(p);
8954 }
8955 }
8956 }
8957 /* finally, go through all the ILI. Those that have been collected
8958 * should be marked GARB_COLLECTED. Those that are reachable should
8959 * be marked GARB_VISITED. Those marked GARB_UNREACHABLE are
8960 * collected, they weren't originally in the hash chains */
8961 for (i = 0; i < ilib.stg_avail; ++i) {
8962 if (ILI_VISIT(i) == GARB_UNREACHABLE) {
8963 if (ILI_OPC(i) == GARB_COLLECTED) {
8964 /* this was put on the list in a previous garbage collect;
8965 * we don't want to put it on again. */
8966 ILI_VISIT(i) = 0;
8967 continue;
8968 }
8969 assert(ILI_HSHLNK(i) == 0, "garbage_collection: bad hashlnk", i,
8970 ERR_Fatal);
8971 STG_ADD_FREELIST(ilib, i);
8972 ILI_OPCP(i, GARB_COLLECTED);
8973 } else if (ILI_VISIT(i) == GARB_VISITED) {
8974 assert(ILI_OPC(i) != GARB_COLLECTED,
8975 "garbage_collection: bad opc for reachable ili", i, ERR_Fatal);
8976 ILI_VISIT(i) = 0;
8977 } else {
8978 /* this was collected */
8979 assert(ILI_VISIT(i) == GARB_COLLECTED,
8980 "garbage_collection: bad visit field", i, ERR_Fatal);
8981 assert(ILI_OPC(i) == GARB_COLLECTED,
8982 "garbage_collection: bad opc for collected ili", i, ERR_Fatal);
8983 ILI_VISIT(i) = 0;
8984 }
8985 }
8986 #if DEBUG
8987 if (DBGBIT(10, 1024)) {
8988 fprintf(gbl.dbgfil, "garbage: after collect: avail: %d, freelist: %d\n",
8989 ilib.stg_avail, ilib.stg_free);
8990 }
8991 /* Do a check -- every ili should either have a valid opcode or should
8992 be on the free list */
8993 j = 0;
8994 for (q = ilib.stg_free; q != 0; q = ILI_HSHLNK(q)) {
8995 assert(ILI_OPC(q) == GARB_COLLECTED,
8996 "garbage_collection: bad opc for avail ili", i, ERR_Fatal);
8997 ++ILI_VISIT(q);
8998 ++j;
8999 }
9000
9001 for (i = 0; i < ilib.stg_avail; ++i) {
9002 if (ILI_VISIT(i) == 0)
9003 assert(ILI_OPC(i) != GARB_COLLECTED,
9004 "garbage_collection: collected ILI not on free list", i,
9005 ERR_Fatal);
9006 else if (ILI_VISIT(i) == 1)
9007 assert(ILI_OPC(i) == GARB_COLLECTED,
9008 "garbage_collection: free ILI not marked collected", i, ERR_Fatal);
9009 else {
9010 interr("garbage_collection: ILI on free list more than once", i,
9011 ERR_Fatal);
9012 }
9013 ILI_VISIT(i) = 0;
9014 }
9015 #endif
9016
9017 if (!XBIT(15, 0x1000))
9018 ilib.stg_free = sort_free_list(ilib.stg_free);
9019 }
9020
9021 static void mark_nme(int, int);
9022 static void
mark_ilitree(int ili,int val)9023 mark_ilitree(int ili, int val)
9024 {
9025 int i;
9026 ILI_OP opc;
9027 int noprs;
9028
9029 if (ILI_VISIT(ili)) {
9030 assert(ILI_VISIT(ili) == val, "mark_ilitree: visit != val", ili, ERR_Fatal);
9031 return;
9032 }
9033 opc = ILI_OPC(ili);
9034 noprs = ilis[opc].oprs;
9035
9036 ILI_VISIT(ili) = val;
9037 for (i = 1; i <= noprs; i++) {
9038 if (IL_ISLINK(opc, i))
9039 mark_ilitree(ILI_OPND(ili, i), val);
9040 else if (IL_OPRFLAG(opc, i) == ILIO_NME)
9041 mark_nme(ILI_OPND(ili, i), val);
9042 }
9043 if (opc == IL_SMOVE)
9044 mark_nme(ILI_OPND(ili, 4), val);
9045 if (ILI_ALT(ili))
9046 mark_ilitree(ILI_ALT(ili), val);
9047 }
9048
9049 static void
mark_nme(int nme,int val)9050 mark_nme(int nme, int val)
9051 {
9052 int sub, n1, n2;
9053
9054 for (; nme; nme = NME_NM(nme)) {
9055 if (NME_TYPE(nme) == NT_ARR && NME_SUB(nme))
9056 mark_ilitree(NME_SUB(nme), val);
9057 else if (NME_TYPE(nme) == NT_IND && NME_SUB(nme))
9058 mark_ilitree(NME_SUB(nme), val);
9059 }
9060 }
9061
9062 static void
mark_ili(int val)9063 mark_ili(int val)
9064 {
9065 /* mark all the ili */
9066 int bihx, iltx;
9067 int ii;
9068
9069 for (ii = 1; ii < ilib.stg_avail; ii++)
9070 ILI_VISIT(ii) = 0;
9071
9072 for (bihx = gbl.entbih; bihx != 0; bihx = BIH_NEXT(bihx))
9073 for (iltx = BIH_ILTFIRST(bihx); iltx != 0; iltx = ILT_NEXT(iltx)) {
9074 int ilix = (int)ILT_ILIP(iltx);
9075 mark_ilitree(ilix, val);
9076 }
9077 }
9078
9079 /** \brief Search the ili subtree located by ilix for functions. */
9080 bool
func_in(int ilix)9081 func_in(int ilix)
9082 {
9083 int noprs, /* number of lnk operands in ilix */
9084 i; /* index variable */
9085 ILI_OP opc; /* ili opcode of ilix */
9086
9087 if ((opc = ILI_OPC(ilix)) == IL_JSR || opc == IL_JSRA)
9088 return true;
9089 noprs = ilis[opc].oprs;
9090 for (i = 1; i <= noprs; i++) {
9091 if (IL_ISLINK(opc, i))
9092 if (func_in(ILI_OPND(ilix, i)))
9093 return true;
9094 }
9095 return false;
9096 }
9097
9098 /** \brief Search the ili subtree located by ilix for QJSRs.
9099 *
9100 * This routine is used instead of ili_traverse of qjrsearch when the
9101 * visit_list is already being used (ili_traverse needs the visit_list).
9102 */
9103 bool
qjsr_in(int ilix)9104 qjsr_in(int ilix)
9105 {
9106 int noprs, /* number of lnk operands in ilix */
9107 i; /* index variable */
9108 ILI_OP opc; /* ili opcode of ilix */
9109
9110 opc = ILI_OPC(ilix);
9111 if (opc == IL_QJSR)
9112 return true;
9113 switch (ILI_OPC(ilix)) {
9114 default:
9115 break;
9116 case IL_FSINCOS:
9117 case IL_DSINCOS:
9118 return true;
9119 }
9120 if (ILI_ALT(ilix) && qjsr_in(ILI_ALT(ilix)))
9121 return true;
9122 noprs = ilis[opc].oprs;
9123 for (i = 1; i <= noprs; i++) {
9124 if (IL_ISLINK(opc, i))
9125 if (qjsr_in(ILI_OPND(ilix, i)))
9126 return true;
9127 }
9128 return false;
9129 }
9130
9131 static int visit_list = 0;
9132
9133 bool
_find_ili(int ilix,int find_this)9134 _find_ili(int ilix, int find_this)
9135 {
9136 ILI_OP opc;
9137 int noprs, j;
9138 if (ilix == find_this) {
9139 ILI_VLIST(ilix) = -visit_list;
9140 visit_list = ilix;
9141 return true;
9142 }
9143 if (ILI_VLIST(ilix)) {
9144 if (ILI_VISIT(ilix) < 0)
9145 return true;
9146 return false;
9147 }
9148 opc = ILI_OPC(ilix);
9149 noprs = IL_OPRS(opc);
9150 for (j = 1; j <= noprs; ++j) {
9151 int opnd;
9152 if (IL_ISLINK(opc, j)) {
9153 opnd = ILI_OPND(ilix, j);
9154 if (_find_ili(opnd, find_this)) {
9155 ILI_VLIST(ilix) = -visit_list;
9156 visit_list = ilix;
9157 return true;
9158 }
9159 }
9160 }
9161 ILI_VLIST(ilix) = visit_list;
9162 visit_list = ilix;
9163 return false;
9164 } /* _find_ili */
9165
9166 /**
9167 \brief determine if an ili occurs in an ili subtree
9168 */
9169 bool
find_ili(int tree,int it)9170 find_ili(int tree, int it)
9171 {
9172 bool res;
9173 int v, nxt;
9174 visit_list = 1;
9175 ILI_VLIST(1) = 0;
9176 res = _find_ili(tree, it);
9177 for (v = visit_list; v; v = nxt) {
9178 nxt = ILI_VLIST(v);
9179 ILI_VLIST(v) = 0;
9180 if (nxt < 0)
9181 nxt = -nxt;
9182 }
9183 return res;
9184 } /* find_ili */
9185
9186 /*
9187 * general ili rewrite mechanism which saves for each ili traversed, its
9188 * rewritten ili in the visit field (ILI_VISIT). This mechanism uses
9189 * ILI_VISIT to short circuit traversal and to ensure that if a proc ili
9190 * has been rewritten, multiple uses of that proc ili are replaced with
9191 * the same ili (share_proc_ili is false during this process). Note that
9192 * rewr_ili saves the index to the tree that's rewritten; rewr_cln_ili
9193 * retrieves the index to clean up the visit fields (several trees can be
9194 * rewritten before a clean-up occurs).
9195 *
9196 * WARNING: there exists one slight flaw with using the visit field to save
9197 * the rewritten ili. addili, when it sees a branch with constant operands,
9198 * may return a value of 0 (also ==> the ili is not visited). rewr_cln_ili
9199 * uses the visit flag to determine if it must traverse!!! Solve this slight
9200 * problem by setting the visit flag of each root in rewr_cln_ili since this
9201 * only happens for a terminal (branch).
9202 *
9203 * int rewr_ili() - routine to setup rewriting (rewr_)
9204 * int rewr_ili_nme() - modified routine to change an ili and an nme
9205 * static int rewr_() - postorder rewrite routine
9206 * static int rewr_nm() - recursive rewrite routine for nmes
9207 * static bool has_nme() - check if nme has any ref to nme to replace
9208 * void rewr_cln_ili() - routine to setup clearing ILI_VISIT
9209 * void rewr_cln() - recursively clean up ILI_VISIT
9210 */
9211
9212 static int rewr_(int);
9213 static int rewr_nm(int);
9214 static bool has_nme(int);
9215 static void rewr_cln(int);
9216 static void rewr_cln_nm(int);
9217 static int rewr_old, rewr_new, rewr_old_nme, rewr_new_nme;
9218 static int rewr_use = 1, rewr_def = 1;
9219 static int need_to_rename = 0;
9220 static int rewrite_nme_indirect = 0;
9221
9222 /* save list of ILI being rewritten */
9223 static struct {
9224 int *base;
9225 int size;
9226 int cnt;
9227 } rewrb = {NULL, 0, 0};
9228
9229 /* save old/new ILI pairs for rewriting */
9230 typedef struct rewrtstruct {
9231 int oldili, newili, oldnme, newnme;
9232 } rewrtstruct;
9233
9234 static struct {
9235 rewrtstruct *base;
9236 int size, cnt, all_acon;
9237 } rewrt = {NULL, 0, 0, 0};
9238
9239 /*
9240 * save an old/new ILI for subsequent rewrite
9241 */
9242 void
rewr_these_ili(int oldili,int newili)9243 rewr_these_ili(int oldili, int newili)
9244 {
9245 if (rewrt.size == 0) {
9246 rewrt.size = 16;
9247 NEW(rewrt.base, rewrtstruct, rewrt.size);
9248 rewrt.cnt = 0;
9249 } else {
9250 NEED(rewrt.cnt + 2, rewrt.base, rewrtstruct, rewrt.size, rewrt.size + 16);
9251 }
9252
9253 rewrt.base[rewrt.cnt].oldili = oldili;
9254 rewrt.base[rewrt.cnt].newili = newili;
9255 rewrt.base[rewrt.cnt].oldnme = 0;
9256 rewrt.base[rewrt.cnt].newnme = 0;
9257 ++rewrt.cnt;
9258 } /* rewr_these_ili */
9259
9260 /*
9261 * save an old/new ILI/NME for subsequent rewrite
9262 */
9263 void
rewr_these_ili_nme(int oldili,int newili,int oldnme,int newnme)9264 rewr_these_ili_nme(int oldili, int newili, int oldnme, int newnme)
9265 {
9266 if (rewrt.size == 0) {
9267 rewrt.size = 16;
9268 NEW(rewrt.base, rewrtstruct, rewrt.size);
9269 rewrt.cnt = 0;
9270 } else {
9271 NEED(rewrt.cnt + 2, rewrt.base, rewrtstruct, rewrt.size, rewrt.size + 16);
9272 }
9273
9274 rewrt.base[rewrt.cnt].oldili = oldili;
9275 rewrt.base[rewrt.cnt].newili = newili;
9276 rewrt.base[rewrt.cnt].oldnme = oldnme;
9277 rewrt.base[rewrt.cnt].newnme = newnme;
9278 ++rewrt.cnt;
9279 } /* rewr_these_ili_nme */
9280
9281 /*
9282 * get most recent 'newnme' for the 'oldnme' given
9283 */
9284 int
get_rewr_new_nme(int nmex)9285 get_rewr_new_nme(int nmex)
9286 {
9287 int j;
9288 for (j = rewrt.cnt; j > 0; --j) {
9289 if (nmex == rewrt.base[j - 1].oldnme)
9290 return rewrt.base[j - 1].newnme;
9291 }
9292 return 0;
9293 } /* get_rewr_new_nme */
9294
9295 /*
9296 * save/restore rewrite count
9297 */
9298 int
save_rewr_count(void)9299 save_rewr_count(void)
9300 {
9301 return rewrt.cnt;
9302 } /* save_rewr_count */
9303
9304 void
restore_rewr_count(int c)9305 restore_rewr_count(int c)
9306 {
9307 rewrt.cnt = c;
9308 } /* restore_rewr_count */
9309
9310 /*
9311 * rewrites the ili tree 'tree', changing 'old' into 'New'
9312 * saves 'tree' in 'rewrb'
9313 * must be followed by a call to rewr_cln_ili
9314 */
9315 int
rewr_ili(int tree,int old,int New)9316 rewr_ili(int tree, int old, int New)
9317 {
9318 int save_proc, save_all_acon;
9319
9320 #if DEBUG
9321 assert(tree > 0, "rewr_ili, bad tree", 0, ERR_Severe);
9322 #endif
9323 if (rewrb.size == 0) {
9324 rewrb.size = 16;
9325 NEW(rewrb.base, int, rewrb.size);
9326 rewrb.cnt = 0;
9327 } else
9328 NEED(rewrb.cnt + 1, rewrb.base, int, rewrb.size, rewrb.size + 16);
9329
9330 rewrb.base[rewrb.cnt++] = tree;
9331
9332 save_proc = share_proc_ili;
9333 share_proc_ili = false;
9334 rewr_old = old;
9335 rewr_new = New;
9336 need_to_rename = 0;
9337 rewrite_nme_indirect = 0;
9338 rewr_old_nme = 0;
9339 rewr_new_nme = 0;
9340 if (old >= 1 && ILI_OPC(old) == IL_LDA) {
9341 rewr_old_nme = ILI_OPND(old, 2);
9342 need_to_rename = 1;
9343 }
9344 save_all_acon = rewrt.all_acon;
9345 if (old == -2) {
9346 rewrt.all_acon = 1;
9347 } else {
9348 rewrt.all_acon = 0;
9349 }
9350 New = rewr_(tree);
9351 share_proc_ili = save_proc;
9352 rewrt.all_acon = save_all_acon;
9353 need_to_rename = 0;
9354 rewrite_nme_indirect = 0;
9355 rewr_old_nme = 0;
9356 rewr_new_nme = 0;
9357
9358 return New;
9359 }
9360
9361 /** Rewrites the ili tree 'tree', changing 'oldili' into 'newili' and
9362 * the nme 'oldnme' into 'newnme'; saves 'tree' in 'rewrb'.
9363 *
9364 * Must be followed by a call to rewr_cln_ili.
9365 */
9366 int
rewr_ili_nme(int tree,int oldili,int newili,int oldnme,int newnme,int douse,int dodef)9367 rewr_ili_nme(int tree, int oldili, int newili, int oldnme, int newnme,
9368 int douse, int dodef)
9369 {
9370 int save_proc, New;
9371
9372 #if DEBUG
9373 assert(tree > 0, "rewr_ili_nme, bad tree", 0, ERR_Severe);
9374 #endif
9375 if (rewrb.size) {
9376 NEED(rewrb.cnt + 1, rewrb.base, int, rewrb.size, rewrb.size + 16);
9377 } else {
9378 rewrb.size = 16;
9379 NEW(rewrb.base, int, rewrb.size);
9380 rewrb.cnt = 0;
9381 }
9382 rewrb.base[rewrb.cnt++] = tree;
9383
9384 save_proc = share_proc_ili;
9385 share_proc_ili = false;
9386 rewr_old = oldili;
9387 rewr_new = newili;
9388 rewr_old_nme = oldnme;
9389 rewr_new_nme = newnme;
9390 rewrite_nme_indirect = 0;
9391 rewr_use = douse;
9392 rewr_def = dodef;
9393 rewrt.all_acon = 0;
9394 New = rewr_(tree);
9395 share_proc_ili = save_proc;
9396 rewr_use = 1;
9397 rewr_def = 1;
9398 rewrite_nme_indirect = 0;
9399 return New;
9400 } /* rewr_ili_nme */
9401
9402 static int
rewr_indirect_nme(int nmex)9403 rewr_indirect_nme(int nmex)
9404 {
9405 int new_nmex;
9406 if (NME_TYPE(nmex) == NT_IND && NME_NM(nmex) == NME_NM(rewr_old_nme)) {
9407 if (NME_SUB(nmex)) {
9408 new_nmex =
9409 add_arrnme(NT_ARR, NME_NULL, rewr_new_nme, 0, NME_SUB(nmex), 0);
9410 } else {
9411 new_nmex = rewr_new_nme;
9412 }
9413 return new_nmex;
9414 }
9415 switch (NME_TYPE(nmex)) {
9416 case NT_MEM:
9417 new_nmex = rewr_indirect_nme(NME_NM(nmex));
9418 if (new_nmex != NME_NM(nmex))
9419 nmex = addnme(NME_TYPE(nmex), NME_SYM(nmex), new_nmex, NME_CNST(nmex));
9420 break;
9421 case NT_IND:
9422 new_nmex = rewr_indirect_nme(NME_NM(nmex));
9423 if (new_nmex != NME_NM(nmex)) {
9424 nmex = add_arrnme(NT_IND, NME_SYM(nmex), new_nmex, NME_CNST(nmex),
9425 NME_SUB(nmex), NME_INLARR(nmex));
9426 }
9427 break;
9428 case NT_ARR:
9429 new_nmex = rewr_indirect_nme(NME_NM(nmex));
9430 if (new_nmex != NME_NM(nmex)) {
9431 nmex = add_arrnme(NT_ARR, NME_SYM(nmex), new_nmex, NME_CNST(nmex),
9432 NME_SUB(nmex), NME_INLARR(nmex));
9433 }
9434 break;
9435 case NT_VAR:
9436 case NT_UNK:
9437 break;
9438 case NT_SAFE:
9439 new_nmex = rewr_indirect_nme(NME_NM(nmex));
9440 if (new_nmex != NME_NM(nmex))
9441 nmex = addnme(NT_SAFE, SPTR_NULL, new_nmex, 0);
9442 break;
9443 default:
9444 #if DEBUG
9445 interr("rewr_indirect_nme: unexpected nme", nmex, ERR_Severe);
9446 #endif
9447 break;
9448 }
9449
9450 return nmex;
9451 } /* rewr_indirect_nme */
9452
9453 /*
9454 * Given the ILI by which we replace the address of a symbol,
9455 * and the offset to the base of that symbol, build a tree for the offset
9456 * applied to the ILI
9457 */
9458 static int
build_pointer_tree(int ilix,ISZ_T offset)9459 build_pointer_tree(int ilix, ISZ_T offset)
9460 {
9461 return ad3ili(IL_AADD, ilix, ad_aconi(offset), 0);
9462 } /* build_pointer_tree */
9463
9464 static int
rewr_(int tree)9465 rewr_(int tree)
9466 {
9467 ILI_OP opc;
9468 int noprs;
9469 int opnd;
9470 int i, j, dontdef, dontuse;
9471 ILI newili;
9472 bool changes;
9473
9474 #if DEBUG
9475 assert(tree > 0, "rewr_, bad tree", 0, ERR_Severe);
9476 #endif
9477 if (ILI_VISIT(tree))
9478 return ILI_VISIT(tree);
9479 if (rewrt.cnt == 0) {
9480 if (tree == rewr_old) {
9481 ILI_VISIT(tree) = rewr_new;
9482 return rewr_new;
9483 }
9484 } else {
9485 /* look through the entire table of 'old' */
9486 for (j = rewrt.cnt; j > 0; --j) {
9487 if (tree == rewrt.base[j - 1].oldili) {
9488 ILI_VISIT(tree) = rewrt.base[j - 1].newili;
9489 return ILI_VISIT(tree);
9490 }
9491 }
9492 }
9493 opc = ILI_OPC(tree);
9494 noprs = IL_OPRS(opc);
9495 changes = false;
9496 /* first, look for matching NMEs */
9497 dontdef = dontuse = 0;
9498 if (rewrt.all_acon && rewrt.cnt && opc == IL_ACON) {
9499 /* see if we are supposed to rewrite an IL_ACON based on the same symbol */
9500 /* if we have a rewrite IL_ACON(ST_CONST(symbol,0)) => IL_LDA(foo), then
9501 * when we see IL_ACON(ST_CONST(symbol,4)), we want to create
9502 * IL_LDA(foo)+4 */
9503 int acon, sptr;
9504 acon = ILI_OPND(tree, 1);
9505 sptr = CONVAL1G(acon);
9506 for (j = rewrt.cnt; j > 0; --j) {
9507 int oldtree = rewrt.base[j - 1].oldili;
9508 if (ILI_OPC(oldtree) == opc) {
9509 int oldacon;
9510 oldacon = ILI_OPND(oldtree, 1);
9511 if (CONVAL1G(oldacon) == sptr && ACONOFFG(oldacon) == 0) {
9512 int newtree =
9513 build_pointer_tree(rewrt.base[j - 1].newili, ACONOFFG(acon));
9514 ILI_VISIT(tree) = newtree;
9515 return newtree;
9516 }
9517 }
9518 }
9519 }
9520 if (!rewr_use || !rewr_def) {
9521 if (IL_TYPE(opc) == ILTY_STORE) {
9522 dontdef = !rewr_def;
9523 }
9524 if (IL_TYPE(opc) == ILTY_LOAD) {
9525 dontuse = !rewr_use;
9526 }
9527 }
9528 newili.alt = 0;
9529 for (i = 1; i <= noprs; i++) {
9530 opnd = ILI_OPND(tree, i);
9531 if (IL_ISLINK(opc, i)) {
9532 int newopnd;
9533 if (dontuse && opnd == rewr_old) {
9534 newopnd = opnd;
9535 } else if (dontdef && opnd == rewr_old) {
9536 newopnd = opnd;
9537 } else {
9538 newopnd = rewr_(opnd);
9539 if (newopnd != opnd && IL_RES(ILI_OPC(opnd)) == ILIA_AR) {
9540 /* The problem is Fortran Cray pointers, where integer-valued
9541 * expressions are stored into integer pointers, which are then
9542 * used as pointer values. The integer-valued pointer is often
9543 * converted from an address-valued expression (ACON or the like)
9544 * and here we want the address-valued expression or to move it
9545 * to an address-valued expression */
9546 if (ILI_OPC(newopnd) == IL_AKMV || ILI_OPC(newopnd) == IL_AIMV) {
9547 newopnd = ILI_OPND(newopnd, 1); /* get the address value */
9548 } else if (IL_RES(ILI_OPC(newopnd)) == ILIA_KR) {
9549 newopnd = ad1ili(IL_KAMV, newopnd);
9550 } else if (IL_RES(ILI_OPC(newopnd)) == ILIA_IR) {
9551 newopnd = ad1ili(IL_IAMV, newopnd);
9552 }
9553 }
9554 }
9555 newili.opnd[i - 1] = newopnd;
9556 if (newopnd != opnd)
9557 changes = true;
9558 } else if (IL_OPRFLAG(opc, i) == ILIO_NME) {
9559 if (rewrt.cnt) {
9560 newili.opnd[i - 1] = opnd;
9561 for (j = rewrt.cnt; j > 0; --j) {
9562 if (opnd == rewrt.base[j - 1].oldnme) {
9563 newili.opnd[i - 1] = rewrt.base[j - 1].newnme;
9564 break;
9565 }
9566 }
9567 if (j == 0)
9568 newili.opnd[i - 1] = rewr_nm(opnd);
9569 } else if (dontuse && opnd == rewr_old_nme) {
9570 newili.opnd[i - 1] = opnd;
9571 } else if (dontdef && opnd == rewr_old_nme) {
9572 newili.opnd[i - 1] = opnd;
9573 } else {
9574 newili.opnd[i - 1] = opnd;
9575 if (need_to_rename) {
9576 if ((IL_TYPE(opc) == ILTY_STORE || IL_TYPE(opc) == ILTY_LOAD) &&
9577 has_nme(opnd)) {
9578 int opr_i_1;
9579
9580 opr_i_1 = newili.opnd[i - 2];
9581 rewr_new_nme = 0;
9582 switch (ILI_OPC(opr_i_1)) {
9583 case IL_ACON:
9584 rewr_new_nme = build_sym_nme(SymConval1(ILI_SymOPND(opr_i_1, 1)),
9585 ACONOFFG(ILI_OPND(opr_i_1, 1)),
9586 (opc == IL_LDA || opc == IL_STA));
9587 break;
9588 case IL_LDA:
9589 rewr_new_nme = ILI_OPND(opr_i_1, 2);
9590 if (rewr_new_nme)
9591 rewr_new_nme =
9592 build_sym_nme(basesym_of(rewr_new_nme), 0, (opc == IL_LDA || opc == IL_STA));
9593 break;
9594 default:
9595 break;
9596 }
9597 if ((!opnd && rewr_new_nme) ||
9598 (DTY(dt_nme(opnd)) == DTY(dt_nme(rewr_new_nme))))
9599 newili.opnd[i - 1] = rewr_new_nme;
9600 rewr_new_nme = 0;
9601 }
9602 } else {
9603 if (opnd == rewr_old_nme) {
9604 opnd = rewr_new_nme;
9605 } else if (rewrite_nme_indirect) {
9606 opnd = rewr_indirect_nme(opnd);
9607 }
9608 newili.opnd[i - 1] = rewr_nm(opnd);
9609 }
9610 }
9611 if (newili.opnd[i - 1] != opnd)
9612 changes = true;
9613 } else {
9614 newili.opnd[i - 1] = opnd;
9615 }
9616 }
9617 /*
9618 * if a rewr_ili() is passed an old_tree of 1 (=> IL_NULL), any
9619 * proc ili are rewritten even if their operands did not change.
9620 * situation which could occur is when ili are duplicated, incorrect
9621 * cse'ing could occur due to the sharing of proc ili.
9622 */
9623 if (changes || (IL_TYPE(opc) == ILTY_PROC && rewr_old == 1)) {
9624 int index;
9625 int newalt;
9626 newili.opc = opc;
9627 index = addili(&newili);
9628 /* if we're selectively changing loads/stores, don't set ILI_VISIT for
9629 * load/store */
9630 ILI_VISIT(tree) = index;
9631 /* addarth will add alt field */
9632 if (ILI_ALT(tree) && !ILI_ALT(index)) {
9633 index = new_ili(&newili);
9634 newalt = rewr_(ILI_ALT(tree));
9635 if (newalt != index)
9636 ILI_ALT(index) = newalt;
9637 ILI_VISIT(tree) = index;
9638 }
9639
9640 if ((IL_TYPE(opc) == ILTY_PROC || IL_TYPE(opc) == ILTY_DEFINE) &&
9641 ILI_ALT(tree) && !ILI_ALT(index)) {
9642 /* the old tree had an ALT field, the new one doesn't,
9643 * rewrite the old one and fill in the ILI_ALT field of the
9644 * new one */
9645 newalt = rewr_(ILI_ALT(tree));
9646 ILI_ALT(index) = newalt;
9647 if (ILI_ALT(index) == index)
9648 ILI_ALT(index) = 0;
9649 } else {
9650 switch (opc) {
9651 case IL_APURE: /* pure function, no arguments, returning AR */
9652 case IL_IPURE: /* pure function, no arguments, returning IR */
9653 case IL_APUREA: /* pure function, one AR argument, returning AR */
9654 case IL_APUREI: /* pure function, one IR argument, returning AR */
9655 case IL_IPUREA: /* pure function, one AR argument, returning IR */
9656 case IL_IPUREI: /* pure function, one IR argument, returning IR */
9657 newalt = rewr_(ILI_ALT(tree));
9658 ILI_ALT(index) = newalt;
9659 break;
9660 default:
9661 break;
9662 }
9663 }
9664 } else {
9665 ILI_VISIT(tree) = tree;
9666 }
9667
9668 return ILI_VISIT(tree);
9669 }
9670
9671 static bool
has_nme(int nme)9672 has_nme(int nme)
9673 {
9674 if (nme == 0)
9675 #if OPT_ZNME
9676 return true;
9677 #else
9678 return false;
9679 #endif
9680 if (nme == rewr_old_nme)
9681 return true;
9682 switch (NME_TYPE(nme)) {
9683 case NT_MEM:
9684 case NT_IND:
9685 case NT_ARR:
9686 return has_nme(NME_NM(nme));
9687 case NT_VAR:
9688 case NT_UNK:
9689 case NT_SAFE:
9690 break;
9691 }
9692 return false;
9693 }
9694
9695 static int
rewr_nm(int nme)9696 rewr_nm(int nme)
9697 {
9698 int new_nm, new_sub, j;
9699 #if DEBUG
9700 if (nme < 0 || nme >= nmeb.stg_size) {
9701 interr("rewr_nm:bad names ptr", nme, ERR_Severe);
9702 return nme;
9703 }
9704 #endif
9705 for (j = rewrt.cnt; j > 0; --j) {
9706 if (nme == rewrt.base[j - 1].oldnme) {
9707 return rewrt.base[j - 1].newnme;
9708 }
9709 }
9710
9711 switch (NME_TYPE(nme)) {
9712 case NT_MEM:
9713 new_nm = rewr_nm((int)NME_NM(nme));
9714 if (new_nm != NME_NM(nme))
9715 return addnme(NME_TYPE(nme), NME_SYM(nme), new_nm, NME_CNST(nme));
9716 break;
9717 case NT_IND:
9718 new_nm = rewr_nm((int)NME_NM(nme));
9719 if (NME_SUB(nme))
9720 new_sub = rewr_((int)NME_SUB(nme));
9721 else
9722 new_sub = 0;
9723 if (new_nm != NME_NM(nme) || new_sub != NME_SUB(nme)) {
9724 nme = add_arrnme(NT_IND, NME_SYM(nme), new_nm, NME_CNST(nme), new_sub,
9725 (int)NME_INLARR(nme));
9726 }
9727 break;
9728 case NT_ARR:
9729 new_nm = rewr_nm((int)NME_NM(nme));
9730 if (NME_SUB(nme))
9731 new_sub = rewr_((int)NME_SUB(nme));
9732 else
9733 new_sub = 0;
9734 if (new_nm != NME_NM(nme) || new_sub != NME_SUB(nme)) {
9735 const ILI_OP opc = ILI_OPC(new_sub);
9736 if (new_sub && IL_TYPE(opc) == ILTY_CONS) {
9737 ISZ_T off;
9738 if (IL_RES(opc) != ILIA_KR)
9739 off = CONVAL2G(ILI_OPND(new_sub, 1));
9740 else
9741 off = ACONOFFG(ILI_OPND(new_sub, 1));
9742 nme = add_arrnme(NT_ARR, SPTR_NULL, new_nm, off, new_sub,
9743 (int)NME_INLARR(nme));
9744 } else if (new_sub == 0 && NME_CNST(nme)) {
9745 nme = add_arrnme(NT_ARR, NME_SYM(nme), new_nm, NME_CNST(nme), new_sub,
9746 NME_INLARR(nme));
9747 } else {
9748 nme = add_arrnme(NT_ARR, NME_SYM(nme), new_nm, 0, new_sub,
9749 NME_INLARR(nme));
9750 }
9751 return nme;
9752 }
9753 break;
9754 case NT_VAR:
9755 case NT_UNK:
9756 break;
9757 case NT_SAFE:
9758 new_nm = rewr_nm((int)NME_NM(nme));
9759 if (new_nm != NME_NM(nme))
9760 return addnme(NT_SAFE, SPTR_NULL, new_nm, 0);
9761 break;
9762 default:
9763 #if DEBUG
9764 interr("rewr_nm:unexp. nme", nme, ERR_Severe);
9765 #endif
9766 break;
9767 }
9768
9769 return nme;
9770 }
9771
9772 /*
9773 * reset the ILI_VISIT field that was set by calls to rewr_ili
9774 */
9775 void
rewr_cln_ili(void)9776 rewr_cln_ili(void)
9777 {
9778 int i;
9779 int tree;
9780
9781 #if DEBUG
9782 assert(rewrb.cnt, "rewr_cln_ili: cnt is zero", 0, ERR_Severe);
9783 #endif
9784
9785 for (i = 0; i < rewrb.cnt; i++) {
9786 ILI_VISIT(rewrb.base[i]) = 1; /* solve '0' as the new ili problem */
9787 rewr_cln(rewrb.base[i]);
9788 }
9789
9790 FREE(rewrb.base);
9791 rewrb.base = NULL;
9792 rewrb.size = rewrb.cnt = 0;
9793
9794 #if defined(MY_SCN) || defined(DEW)
9795 for (i = 1; i < ilib.stg_avail; i++)
9796 if (ILI_VISIT(i))
9797 interr("rewr_cln_ili: visit not zero", i, ERR_Severe);
9798 #endif
9799 if (rewrt.base) {
9800 FREE(rewrt.base);
9801 rewrt.base = NULL;
9802 rewrt.size = rewrt.cnt = 0;
9803 }
9804 }
9805
9806 static void
rewr_cln(int tree)9807 rewr_cln(int tree)
9808 {
9809 ILI_OP opc;
9810 int noprs;
9811 int i;
9812
9813 #if DEBUG
9814 assert(tree > 0, "rewr_cln, bad tree", 0, ERR_Severe);
9815 #endif
9816 if (ILI_VISIT(tree)) {
9817 ILI_VISIT(tree) = 0;
9818 opc = ILI_OPC(tree);
9819 noprs = IL_OPRS(opc);
9820 for (i = 1; i <= noprs; i++) {
9821 if (IL_ISLINK(opc, i))
9822 rewr_cln((int)ILI_OPND(tree, i));
9823 else if (IL_OPRFLAG(opc, i) == ILIO_NME)
9824 rewr_cln_nm((int)ILI_OPND(tree, i));
9825 }
9826 if (ILI_ALT(tree)) {
9827 rewr_cln(ILI_ALT(tree));
9828 }
9829 }
9830 }
9831
9832 static void
rewr_cln_nm(int nme)9833 rewr_cln_nm(int nme)
9834 {
9835 #if DEBUG
9836 if (nme < 0 || nme >= nmeb.stg_size) {
9837 interr("rewr_cln_nm:bad names ptr", nme, ERR_Severe);
9838 return;
9839 }
9840 #endif
9841
9842 switch (NME_TYPE(nme)) {
9843 case NT_MEM:
9844 case NT_SAFE:
9845 rewr_cln_nm((int)NME_NM(nme));
9846 break;
9847 case NT_IND:
9848 case NT_ARR:
9849 rewr_cln_nm((int)NME_NM(nme));
9850 if (NME_SUB(nme))
9851 rewr_cln((int)NME_SUB(nme));
9852 break;
9853 case NT_VAR:
9854 case NT_UNK:
9855 break;
9856 default:
9857 #if DEBUG
9858 interr("rewr_cln_nm:unexp. nme", nme, ERR_Severe);
9859 #endif
9860 break;
9861 }
9862 }
9863
9864 static void
prsym(int sym,FILE * ff)9865 prsym(int sym, FILE *ff)
9866 {
9867 char *p;
9868 p = getprint((int)sym);
9869 fprintf(ff, "%s", p);
9870 if (strncmp("..inline", p, 8) == 0)
9871 fprintf(ff, "%d", sym);
9872 }
9873
9874 static ILI_OP
opc_comp_zero_one(int cmp_ili,int * invert_cc,int * label_op)9875 opc_comp_zero_one(int cmp_ili, int *invert_cc, int *label_op)
9876 {
9877 int icon_ili;
9878 ILI_OP opc;
9879 int cc;
9880
9881 *invert_cc = 0;
9882 opc = ILI_OPC(cmp_ili);
9883 switch (opc) {
9884 case IL_ICMP:
9885 case IL_ICJMP:
9886 cc = ILI_OPND(cmp_ili, 3);
9887 if (cc != CC_EQ && cc != CC_NE)
9888 return IL_NONE;
9889 icon_ili = ILI_OPND(cmp_ili, 2);
9890 if (ILI_OPC(icon_ili) != IL_ICON)
9891 return IL_NONE;
9892 if (ILI_OPND(icon_ili, 1) != stb.i1)
9893 return IL_NONE;
9894 *invert_cc = (cc == CC_NE);
9895 if (opc == IL_ICJMP)
9896 *label_op = ILI_OPND(cmp_ili, 4);
9897 break;
9898 case IL_ICMPZ:
9899 case IL_ICJMPZ:
9900 cc = ILI_OPND(cmp_ili, 2);
9901 if (cc != CC_EQ && cc != CC_NE)
9902 return IL_NONE;
9903 *invert_cc = (cc == CC_EQ);
9904 if (opc == IL_ICJMPZ)
9905 *label_op = ILI_OPND(cmp_ili, 3);
9906 break;
9907 default:
9908 return IL_NONE;
9909 }
9910 return opc;
9911 }
9912
9913 /**
9914 * \brief returns simplified version of comparison ili
9915 * \param cmp_ili Comparison ILI
9916 *
9917 * <pre>
9918 * simplify following eight cases:
9919 * (1)
9920 * X = IL_xxCMP A, B, cmp_op
9921 * Y = IL_ICMP X, 1, eq
9922 * =>
9923 * Y = IL_xxCMP A, B, cmp_op
9924 * (2)
9925 * X = IL_xxCMPZ A, cmp_op
9926 * Y = IL_ICMP X, 1, eq
9927 * =>
9928 * Y = IL_xxCMPZ A, cmp_op
9929 * (3)
9930 * X = IL_xxCMP A, B, cmp_op
9931 * Y = IL_ICMP X, 1, ne
9932 * =>
9933 * Y = IL_xxCMP A, B, ~cmp_op
9934 * (4)
9935 * X = IL_xxCMPZ A, cmp_op
9936 * Y = IL_ICMP X, 1, ne
9937 * =>
9938 * Y = IL_xxCMPZ A, ~cmp_op
9939 * (5)
9940 * X = IL_xxCMP A, B, cmp_op
9941 * Y = IL_ICMPZ X, eq
9942 * =>
9943 * Y = IL_xxCMP A, B, ~cmp_op
9944 * (6)
9945 * X = IL_xxCMPZ A, cmp_op
9946 * Y = IL_ICMPZ X, eq
9947 * =>
9948 * Y = IL_xxCMPZ A, ~cmp_op
9949 * (7)
9950 * X = IL_xxCMP A, B, cmp_op
9951 * Y = IL_ICMPZ X, ne
9952 * =>
9953 * Y = IL_xxCMP A, B, cmp_op
9954 * (8)
9955 * X = IL_xxCMPZ A, cmp_op
9956 * Y = IL_ICMPZ X, ne
9957 * =>
9958 * Y = IL_xxCMPZ A, cmp_op
9959 * </pre>
9960 * This algorithm is applied recursively to simplify chains of comparison to one
9961 * and zero
9962 */
9963 int
simplified_cmp_ili(int cmp_ili)9964 simplified_cmp_ili(int cmp_ili)
9965 {
9966 ILI_OP opc, new_opc, jump_opc;
9967 int new_ili, icon_ili;
9968 CC_RELATION new_cc;
9969 int invert_cc;
9970 int label_op;
9971
9972 while ((
9973 opc = opc_comp_zero_one(cmp_ili, &invert_cc, &label_op))) {
9974 new_ili = ILI_OPND(cmp_ili, 1);
9975 new_opc = ILI_OPC(new_ili);
9976 switch (new_opc) {
9977 case IL_ACMP:
9978 jump_opc = IL_ACJMP;
9979 goto shared_bin_cmp;
9980 case IL_FCMP:
9981 jump_opc = IL_FCJMP;
9982 goto shared_bin_cmp;
9983 case IL_DCMP:
9984 jump_opc = IL_DCJMP;
9985 goto shared_bin_cmp;
9986 case IL_ICMP:
9987 jump_opc = IL_ICJMP;
9988 goto shared_bin_cmp;
9989 case IL_KCMP:
9990 jump_opc = IL_KCJMP;
9991 goto shared_bin_cmp;
9992 case IL_UICMP:
9993 jump_opc = IL_UICJMP;
9994 goto shared_bin_cmp;
9995 case IL_UKCMP:
9996 jump_opc = IL_UKCJMP;
9997 shared_bin_cmp:
9998 new_cc = CC_ILI_OPND(new_ili, 3);
9999 if (invert_cc) {
10000 if (is_floating_comparison_opcode(new_opc))
10001 new_cc = complement_ieee_cc(new_cc);
10002 else
10003 new_cc = complement_int_cc(new_cc);
10004 }
10005 if (opc == IL_ICJMP || opc == IL_ICJMPZ)
10006 cmp_ili = ad4ili(jump_opc, (int)ILI_OPND(new_ili, 1),
10007 (int)ILI_OPND(new_ili, 2), (int)new_cc, (int)label_op);
10008 else
10009 cmp_ili = ad3ili(new_opc, (int)ILI_OPND(new_ili, 1),
10010 (int)ILI_OPND(new_ili, 2), (int)new_cc);
10011 break;
10012 case IL_ACMPZ:
10013 jump_opc = IL_ACJMPZ;
10014 goto shared_una_cmp;
10015 case IL_FCMPZ:
10016 jump_opc = IL_FCJMPZ;
10017 goto shared_una_cmp;
10018 case IL_DCMPZ:
10019 jump_opc = IL_DCJMPZ;
10020 goto shared_una_cmp;
10021 case IL_ICMPZ:
10022 jump_opc = IL_ICJMPZ;
10023 goto shared_una_cmp;
10024 case IL_KCMPZ:
10025 jump_opc = IL_KCJMPZ;
10026 goto shared_una_cmp;
10027 case IL_UICMPZ:
10028 jump_opc = IL_UICJMPZ;
10029 goto shared_una_cmp;
10030 case IL_UKCMPZ:
10031 jump_opc = IL_UKCJMPZ;
10032 shared_una_cmp:
10033 new_cc = CC_ILI_OPND(new_ili, 2);
10034 if (invert_cc) {
10035 if (is_floating_comparison_opcode(new_opc))
10036 new_cc = complement_ieee_cc(new_cc);
10037 else
10038 new_cc = complement_int_cc(new_cc);
10039 }
10040 if (opc == IL_ICJMP || opc == IL_ICJMPZ)
10041 cmp_ili = ad3ili(jump_opc, (int)ILI_OPND(new_ili, 1), (int)new_cc,
10042 (int)label_op);
10043 else
10044 cmp_ili = ad2ili(new_opc, (int)ILI_OPND(new_ili, 1), (int)new_cc);
10045 break;
10046 default:
10047 return cmp_ili;
10048 }
10049 }
10050 return cmp_ili;
10051 }
10052
10053 char *
dump_msz(MSZ ms)10054 dump_msz(MSZ ms)
10055 {
10056 char *msz;
10057 switch (ms) {
10058 case MSZ_SBYTE:
10059 msz = "sb";
10060 break;
10061 case MSZ_SHWORD:
10062 msz = "sh";
10063 break;
10064 case MSZ_WORD:
10065 msz = "wd";
10066 break;
10067 case MSZ_SLWORD:
10068 msz = "sl";
10069 break;
10070 case MSZ_BYTE:
10071 msz = "bt";
10072 break;
10073 case MSZ_UHWORD:
10074 msz = "uh";
10075 break;
10076 case MSZ_PTR:
10077 msz = "pt";
10078 break;
10079 case MSZ_ULWORD:
10080 msz = "ul";
10081 break;
10082 case MSZ_DBLE:
10083 msz = "db";
10084 break;
10085 #ifdef MSZ_I8
10086 case MSZ_I8:
10087 msz = "i8";
10088 break;
10089 #endif
10090 case MSZ_UWORD:
10091 msz = "uw";
10092 break;
10093 #ifdef MSZ_F10
10094 case MSZ_F10:
10095 msz = "ep";
10096 break;
10097 #endif /* MSZ_F10 */
10098 default:
10099 interr("Bad msz to LD/ST", ms, ERR_Severe);
10100 msz = "??";
10101 }
10102 return msz;
10103 }
10104
10105 /** Return print name of an ATOMIC_ORIGIN value */
10106 static const char *
atomic_origin_name(ATOMIC_ORIGIN origin)10107 atomic_origin_name(ATOMIC_ORIGIN origin)
10108 {
10109 switch (origin) {
10110 case AORG_CPLUS:
10111 return "C";
10112 case AORG_OPENMP:
10113 return "openmp";
10114 case AORG_OPENACC:
10115 return "openacc";
10116 default:
10117 return "<bad origin>";
10118 }
10119 }
10120
10121 static const char *
atomic_rmw_op_name(ATOMIC_RMW_OP op)10122 atomic_rmw_op_name(ATOMIC_RMW_OP op)
10123 {
10124 switch (op) {
10125 case AOP_XCHG:
10126 return "xchg";
10127 case AOP_ADD:
10128 return "add";
10129 case AOP_SUB:
10130 return "sub";
10131 case AOP_AND:
10132 return "and";
10133 case AOP_OR:
10134 return "or";
10135 case AOP_XOR:
10136 return "xor";
10137 default:
10138 return "<bad ATOMIC_RMW_OP>";
10139 }
10140 }
10141
10142 void
dump_atomic_info(FILE * f,ATOMIC_INFO info)10143 dump_atomic_info(FILE *f, ATOMIC_INFO info)
10144 {
10145 const char *s;
10146 if (f == NULL)
10147 f = stderr;
10148 fprintf(f, "{");
10149 fprintf(f, "%s", dump_msz(info.msz));
10150 if (info.scope == SS_SINGLETHREAD)
10151 fprintf(f, " singlethread");
10152 fprintf(f, " %s", atomic_origin_name(info.origin));
10153 fprintf(f, "}");
10154 }
10155
10156 void
dump_ili(FILE * f,int i)10157 dump_ili(FILE *f, int i)
10158 {
10159 int j, noprs;
10160 ILI_OP opc;
10161 static char *cond[] = {"eq", "ne", "lt", "ge", "le", "gt",
10162 "noteq", "notne", "notlt", "notge", "notle", "notgt"};
10163 static char *msz;
10164
10165 if (f == NULL)
10166 f = stderr;
10167 opc = ILI_OPC(i);
10168 if (opc == GARB_COLLECTED) {
10169 fprintf(f, "%-4u **DELETED**\n", i);
10170 return;
10171 }
10172 assert(opc > 0 && opc < N_ILI, "dump_ili: bad opc", i, ERR_Severe);
10173 noprs = ilis[opc].oprs;
10174 fprintf(f, "%-4u %-9s ", i, ilis[opc].name);
10175 for (j = 1; j <= noprs; j++) {
10176 int opn = ILI_OPND(i, j);
10177 switch (IL_OPRFLAG(opc, j)) {
10178 case ILIO_SYM:
10179 case ILIO_OFF:
10180 if (opn <= 0) {
10181 /* Special values permitted in a few cases. */
10182 bool okay;
10183 switch (opc) {
10184 case IL_ACCCOPYIN:
10185 case IL_ACCCOPY:
10186 case IL_ACCCOPYOUT:
10187 case IL_ACCCREATE:
10188 case IL_ACCDELETE:
10189 case IL_ACCPDELETE:
10190 case IL_ACCPCREATE:
10191 case IL_ACCPCOPY:
10192 case IL_ACCPCOPYIN:
10193 case IL_ACCPCOPYOUT:
10194 case IL_ACCPRESENT:
10195 case IL_ACCUSEDEVICE:
10196 case IL_ACCUSEDEVICEIFP:
10197 okay = true;
10198 break;
10199 case IL_GJSR:
10200 case IL_GJSRA:
10201 /* last operand is symbol that can be -1, 0, or label */
10202 okay = j == noprs && opn >= -1;
10203 break;
10204 case IL_ACCDEVICEPTR:
10205 /* last operand sym is unused and can be 0 */
10206 okay = j == noprs && opn == 0;
10207 break;
10208 default:
10209 okay = false;
10210 }
10211 if (!okay)
10212 interr("dump_ili:bad symbol table ptr", i, ERR_Fatal);
10213 }
10214 fprintf(f, " %5u~", opn);
10215 if (opn > 0) {
10216 if (opc != IL_ACON) {
10217 fprintf(f, "<");
10218 prsym(opn, f);
10219 fprintf(f, ">");
10220 } else {
10221 if (CONVAL1G(opn)) {
10222 fprintf(f, "<");
10223 prsym(CONVAL1G(opn), f);
10224 } else
10225 fprintf(f, "<%d", CONVAL1G(opn));
10226 fprintf(f, ",%" ISZ_PF "d>", ACONOFFG(opn));
10227 }
10228 }
10229 break;
10230 case ILIO_NME:
10231 dumpname(opn);
10232 break;
10233 case ILIO_STC:
10234 switch (opc) {
10235 case IL_ICMP:
10236 case IL_FCMP:
10237 case IL_DCMP:
10238 case IL_ACMP:
10239 case IL_ICMPZ:
10240 case IL_FCMPZ:
10241 case IL_DCMPZ:
10242 case IL_ACMPZ:
10243 case IL_ICJMP:
10244 case IL_FCJMP:
10245 case IL_DCJMP:
10246 case IL_ACJMP:
10247 case IL_ICJMPZ:
10248 case IL_FCJMPZ:
10249 case IL_DCJMPZ:
10250 case IL_ACJMPZ:
10251 #ifdef TM_LPCMP
10252 case IL_ICLOOP:
10253 case IL_FCLOOP:
10254 case IL_DCLOOP:
10255 case IL_ACLOOP:
10256 case IL_ICLOOPZ:
10257 case IL_FCLOOPZ:
10258 case IL_DCLOOPZ:
10259 case IL_ACLOOPZ:
10260 #endif
10261 case IL_UICMP:
10262 case IL_UICMPZ:
10263 case IL_UICJMP:
10264 case IL_UICJMPZ:
10265 case IL_KCJMP:
10266 case IL_KCJMPZ:
10267 case IL_KCMP:
10268 case IL_KCMPZ:
10269 case IL_UKCJMP:
10270 case IL_UKCJMPZ:
10271 case IL_UKCMP:
10272 case IL_UKCMPZ:
10273 case IL_LCJMPZ:
10274 #ifdef IL_X87CMP
10275 case IL_X87CMP:
10276 #endif
10277 #ifdef IL_DOUBLEDOUBLECMP
10278 case IL_DOUBLEDOUBLECMP:
10279 #endif
10280 fprintf(f, " %5s ", cond[opn - 1]);
10281 break;
10282 case IL_LD:
10283 case IL_ST:
10284 case IL_LDKR:
10285 case IL_STKR:
10286 msz = dump_msz(ConvertMSZ(opn));
10287 fprintf(f, " %5s ", msz);
10288 break;
10289 case IL_ATOMICRMWI:
10290 case IL_ATOMICRMWA:
10291 case IL_ATOMICRMWKR:
10292 case IL_ATOMICRMWSP:
10293 case IL_ATOMICRMWDP:
10294 if (j == 4)
10295 dump_atomic_info(f, atomic_info(i));
10296 else if (j == 5)
10297 fprintf(f, " %s", atomic_rmw_op_name(ConvertATOMIC_RMW_OP(opn)));
10298 else
10299 fprintf(f, " %d", (int)((short)opn));
10300 break;
10301 default:
10302 fprintf(f, " %6d", (int)((short)opn));
10303 }
10304 break;
10305 case ILIO_LNK:
10306 assert(opn > 0 && opn < ilib.stg_size, "dump_ili: bad ili lnk", i,
10307 ERR_Severe);
10308 switch (ILI_OPC(opn)) {
10309 case IL_KERNELNEST:
10310 break;
10311 case IL_KERNELBLOCK:
10312 break;
10313 case IL_KERNELGRID:
10314 break;
10315 case IL_KERNELSTREAM:
10316 break;
10317 case IL_KERNELDEVICE:
10318 break;
10319 default:
10320 assert(IL_RES(ILI_OPC(opn)) != ILIA_TRM, "dump_ili: any link exp", i,
10321 ERR_Severe);
10322 }
10323 fprintf(f, " %5u^", opn);
10324 break;
10325 case ILIO_IRLNK:
10326 assert(opn > 0 && opn < ilib.stg_size, "dump_ili: bad ili lnk", i,
10327 ERR_Severe);
10328 assert(IL_RES(ILI_OPC(opn)) == ILIA_IR, "dump_ili: ir link exp", i,
10329 ERR_Severe);
10330 fprintf(f, " %5u^", opn);
10331 break;
10332 case ILIO_KRLNK:
10333 assert(opn > 0 && opn < ilib.stg_size, "dump_ili: bad ili lnk", i,
10334 ERR_Severe);
10335 assert(IL_RES(ILI_OPC(opn)) == ILIA_KR, "dump_ili: kr link exp", i,
10336 ERR_Severe);
10337 fprintf(f, " %5u^", opn);
10338 break;
10339 #ifdef ILIO_PPLNK
10340 case ILIO_PPLNK:
10341 assert(opn > 0 && opn < ilib.stg_size, "dump_ili: bad ili lnk", i,
10342 ERR_Severe);
10343 assert(IL_RES(ILI_OPC(opn)) == ILIA_PR, "dump_ili: pr link exp", i,
10344 ERR_Severe);
10345 fprintf(f, " %5u^", opn);
10346 break;
10347 #endif
10348 case ILIO_ARLNK:
10349 assert(opn > 0 && opn < ilib.stg_size, "dump_ili: bad ili lnk", i,
10350 ERR_Severe);
10351 assert(IL_RES(ILI_OPC(opn)) == ILIA_AR, "dump_ili: ar link exp", i,
10352 ERR_Severe);
10353 fprintf(f, " %5u^", opn);
10354 break;
10355 case ILIO_SPLNK:
10356 assert(opn > 0 && opn < ilib.stg_size, "dump_ili: bad ili lnk", i,
10357 ERR_Severe);
10358 assert(IL_RES(ILI_OPC(opn)) == ILIA_SP, "dump_ili: sp link exp", i,
10359 ERR_Severe);
10360 fprintf(f, " %5u^", opn);
10361 break;
10362 case ILIO_DPLNK:
10363 assert(opn > 0 && opn < ilib.stg_size, "dump_ili: bad ili lnk", i,
10364 ERR_Severe);
10365 #ifdef IL_DASPSP
10366 if (opc != IL_DASPSP || IL_RES(ILI_OPC(opn)) != ILIA_CS) {
10367 #endif
10368 assert(IL_RES(ILI_OPC(opn)) == ILIA_DP, "dump_ili: dp link exp", i,
10369 ERR_Severe);
10370 #ifdef IL_DASPSP
10371 }
10372 #endif
10373 fprintf(f, " %5u^", opn);
10374 break;
10375 #ifdef ILIO_CSLNK
10376 case ILIO_QPLNK:
10377 assert(opn > 0 && opn < ilib.stg_size, "dump_ili: bad ili lnk", i,
10378 ERR_Severe);
10379 assert(IL_RES(ILI_OPC(opn)) == ILIA_QP, "dump_ili: qp link exp", i,
10380 ERR_Severe);
10381 fprintf(f, " %5u^", opn);
10382 break;
10383 case ILIO_CSLNK:
10384 assert(opn > 0 && opn < ilib.stg_size, "dump_ili: bad ili lnk", i,
10385 ERR_Severe);
10386 assert(IL_RES(ILI_OPC(opn)) == ILIA_CS, "dump_ili: cs link exp", i,
10387 ERR_Severe);
10388 fprintf(f, " %5u^", opn);
10389 break;
10390 case ILIO_CDLNK:
10391 assert(opn > 0 && opn < ilib.stg_size, "dump_ili: bad ili lnk", i,
10392 ERR_Severe);
10393 assert(IL_RES(ILI_OPC(opn)) == ILIA_CD, "dump_ili: cd link exp", i,
10394 ERR_Severe);
10395 fprintf(f, " %5u^", opn);
10396 break;
10397 case ILIO_CQLNK:
10398 assert(opn > 0 && opn < ilib.stg_size, "dump_ili: bad ili lnk", i,
10399 ERR_Severe);
10400 assert(IL_RES(ILI_OPC(opn)) == ILIA_CQ, "dump_ili: cq link exp", i,
10401 ERR_Severe);
10402 fprintf(f, " %5u^", opn);
10403 break;
10404 case ILIO_128LNK:
10405 assert(opn > 0 && opn < ilib.stg_size, "dump_ili: bad ili lnk", i,
10406 ERR_Severe);
10407 assert(IL_RES(ILI_OPC(opn)) == ILIA_128, "dump_ili: 128 link exp", i,
10408 ERR_Severe);
10409 fprintf(f, " %5u^", opn);
10410 break;
10411 case ILIO_256LNK:
10412 assert(opn > 0 && opn < ilib.stg_size, "dump_ili: bad ili lnk", i,
10413 ERR_Severe);
10414 assert(IL_RES(ILI_OPC(opn)) == ILIA_256, "dump_ili: 256 link exp", i,
10415 ERR_Severe);
10416 fprintf(f, " %5u^", opn);
10417 break;
10418 case ILIO_512LNK:
10419 assert(opn > 0 && opn < ilib.stg_size, "dump_ili: bad ili lnk", i,
10420 ERR_Severe);
10421 assert(IL_RES(ILI_OPC(opn)) == ILIA_512, "dump_ili: 512 link exp", i,
10422 ERR_Severe);
10423 fprintf(f, " %5u^", opn);
10424 break;
10425 #ifdef LONG_DOUBLE_FLOAT128
10426 case ILIO_FLOAT128LNK:
10427 assert(opn > 0 && opn < ilib.stg_size, "dump_ili: bad ili lnk", i,
10428 ERR_Severe);
10429 assert(IL_RES(ILI_OPC(opn)) == ILIA_FLOAT128,
10430 "dump_ili: doubledouble link exp", i, ERR_Severe);
10431 fprintf(f, " %5u^", opn);
10432 break;
10433 #endif
10434 #endif
10435
10436 case ILIO_IR:
10437 fprintf(f, " ir(%2d)", opn);
10438 break;
10439 case ILIO_KR:
10440 #if defined(TARGET_X8664)
10441 fprintf(f, " kr(%2d)", opn);
10442 #else
10443 fprintf(f, " kr(%d,%d)", KR_MSH(opn), KR_LSH(opn));
10444 #endif
10445 break;
10446 case ILIO_AR:
10447 fprintf(f, " ar(%2d)", opn);
10448 break;
10449 case ILIO_SP:
10450 fprintf(f, " sp(%2d)", opn);
10451 break;
10452 case ILIO_DP:
10453 fprintf(f, " dp(%2d)", opn);
10454 break;
10455 case ILIO_CS:
10456 fprintf(f, " cs(%2d)", opn);
10457 break;
10458 case ILIO_CD:
10459 fprintf(f, " cd(%2d)", opn);
10460 break;
10461 case ILIO_XMM:
10462 fprintf(f, " xmm%d", opn);
10463 break;
10464 }
10465 }
10466 if (ILI_ALT(i))
10467 fprintf(f, " %5u^-alt", ILI_ALT(i));
10468 fprintf(f, "\n");
10469 }
10470
10471 /* ****************************************************************** */
10472 static void
dilitree(int i)10473 dilitree(int i)
10474 {
10475 int k, j, opn, noprs;
10476 ILI_OP opc;
10477 static int indent = 0;
10478
10479 indent += 3;
10480 opc = ILI_OPC(i);
10481 noprs = ilis[opc].oprs;
10482
10483 for (j = 1; j <= noprs; j++) {
10484 opn = ILI_OPND(i, j);
10485 switch (IL_OPRFLAG(opc, j)) {
10486 case ILIO_LNK:
10487 if (indent > 3) {
10488 indent -= 3;
10489 dilitree(opn);
10490 indent += 3;
10491 break;
10492 }
10493 case ILIO_IRLNK:
10494 case ILIO_KRLNK:
10495 case ILIO_ARLNK:
10496 case ILIO_SPLNK:
10497 case ILIO_DPLNK:
10498 #ifdef ILIO_CSLNK
10499 case ILIO_QPLNK:
10500 case ILIO_CSLNK:
10501 case ILIO_CDLNK:
10502 case ILIO_CQLNK:
10503 case ILIO_128LNK:
10504 case ILIO_256LNK:
10505 case ILIO_512LNK:
10506 #ifdef LONG_DOUBLE_FLOAT128
10507 case ILIO_FLOAT128LNK:
10508 #endif
10509 #endif
10510 #ifdef ILIO_PPLNK
10511 case ILIO_PPLNK:
10512 #endif
10513 assert(opn > 0 && opn < ilib.stg_size, "dilitree: bad ili lnk", i,
10514 ERR_Severe);
10515 dilitree(opn);
10516 break;
10517 default:
10518 break;
10519 }
10520 }
10521 for (k = 1; k < indent; k++)
10522 fprintf(gbl.dbgfil, " ");
10523
10524 #if DEBUG
10525 dump_ili(gbl.dbgfil, i);
10526 #endif
10527
10528 indent -= 3;
10529 }
10530
10531 /**
10532 * \brief ILI dump routine
10533 */
10534 void
dmpili(void)10535 dmpili(void)
10536 {
10537 int i, j, tmp, opn;
10538
10539 if (gbl.dbgfil == NULL)
10540 gbl.dbgfil = stderr;
10541
10542 fprintf(gbl.dbgfil, "\n\n***** ILI Area Dump *****\n\n");
10543 for (i = 1; i < ilib.stg_avail; i++) {
10544 dump_ili(gbl.dbgfil, i);
10545 }
10546 if (DBGBIT(10, 1))
10547 for (i = 0; i < ILTABSZ; i++) {
10548 fprintf(gbl.dbgfil, "\n\n***** ILI Hash Table%2d *****\n", i);
10549 for (j = 0; j < ILHSHSZ; j++)
10550 if ((opn = ilhsh[i][j]) != 0) {
10551 tmp = 0;
10552 fprintf(gbl.dbgfil, "%3d.", j);
10553 for (; opn != 0; opn = ILI_HSHLNK(opn)) {
10554 fprintf(gbl.dbgfil, " %5u^", opn);
10555 if ((++tmp) == 6) {
10556 tmp = 0;
10557 fprintf(gbl.dbgfil, "\n ");
10558 }
10559 }
10560 if (tmp != 0)
10561 fprintf(gbl.dbgfil, "\n");
10562 }
10563 }
10564 }
10565
10566 #if DEBUG
10567 #define OT_UNARY 1
10568 #define OT_BINARY 2
10569 #define OT_LEAF 3
10570
10571 static void
prnme(int opn,int ili)10572 prnme(int opn, int ili)
10573 {
10574
10575 switch (NME_TYPE(opn)) {
10576 case NT_VAR:
10577 prsym(NME_SYM(opn), gbl.dbgfil);
10578 break;
10579 case NT_MEM:
10580 prnme((int)NME_NM(opn), ili);
10581 if (NME_SYM(opn) == 0) {
10582 fprintf(gbl.dbgfil, ".real");
10583 break;
10584 }
10585 if (NME_SYM(opn) == 1) {
10586 fprintf(gbl.dbgfil, ".imag");
10587 break;
10588 }
10589 fprintf(gbl.dbgfil, "->%s", getprint((int)NME_SYM(opn)));
10590 break;
10591 case NT_IND:
10592 fprintf(gbl.dbgfil, "*(");
10593 prnme((int)NME_NM(opn), ili);
10594 if (NME_SYM(opn) == 0)
10595 if (NME_CNST(opn))
10596 fprintf(gbl.dbgfil, "%+" ISZ_PF "d)", NME_CNST(opn));
10597 else
10598 fprintf(gbl.dbgfil, ")");
10599 else {
10600 fprintf(gbl.dbgfil, "<");
10601 prilitree(ili);
10602 fprintf(gbl.dbgfil, ">");
10603 }
10604 if (NME_SUB(opn)) {
10605 fprintf(gbl.dbgfil, "[");
10606 prilitree(NME_SUB(opn));
10607 fprintf(gbl.dbgfil, "]");
10608 }
10609 break;
10610 case NT_ARR:
10611 prnme((int)NME_NM(opn), ili);
10612 fprintf(gbl.dbgfil, "[");
10613 if (NME_SYM(opn) == 0)
10614 fprintf(gbl.dbgfil, "%" ISZ_PF "d]", NME_CNST(opn));
10615 else if (NME_SUB(opn)) {
10616 prilitree(NME_SUB(opn));
10617 fprintf(gbl.dbgfil, "]");
10618 } else
10619 fprintf(gbl.dbgfil, "i]");
10620 break;
10621 case NT_SAFE:
10622 fprintf(gbl.dbgfil, "safe(");
10623 prnme((int)NME_NM(opn), ili);
10624 fprintf(gbl.dbgfil, ")");
10625 break;
10626 case NT_UNK:
10627 if (NME_SYM(opn))
10628 fprintf(gbl.dbgfil, "?vol");
10629 else
10630 fprintf(gbl.dbgfil, "?");
10631 break;
10632 }
10633 }
10634
10635 static void
prcon(int sptr)10636 prcon(int sptr)
10637 {
10638 char *p;
10639 for (p = getprint(sptr); *p == ' '; p++)
10640 ;
10641 fprintf(gbl.dbgfil, "%s", p);
10642 }
10643
10644 static int
optype(ILI_OP opc)10645 optype(ILI_OP opc)
10646 {
10647 switch (opc) {
10648 case IL_INEG:
10649 case IL_UINEG:
10650 case IL_KNEG:
10651 case IL_UKNEG:
10652 case IL_SCMPLXNEG:
10653 case IL_DCMPLXNEG:
10654 case IL_FNEG:
10655 case IL_DNEG:
10656 return OT_UNARY;
10657 case IL_LD:
10658 case IL_LDKR:
10659 case IL_LDSP:
10660 case IL_LDDP:
10661 case IL_LDSCMPLX:
10662 case IL_LDDCMPLX:
10663 case IL_LDA:
10664 case IL_ICON:
10665 case IL_KCON:
10666 case IL_DCON:
10667 case IL_FCON:
10668 case IL_ACON:
10669 return OT_LEAF;
10670 default:
10671 return OT_BINARY;
10672 }
10673 }
10674
10675 void
prilitree(int i)10676 prilitree(int i)
10677 {
10678 int k, j, opn, noprs, o;
10679 ILI_OP opc;
10680 int n;
10681 char *opval;
10682 static char *ccval[] = {
10683 "??", "==", "!=", "<", ">=", "<=", ">",
10684 "noteq", "notne", "notlt", "notge", "notle", "notgt"};
10685
10686 opc = ILI_OPC(i);
10687 noprs = ilis[opc].oprs;
10688 switch (opc) {
10689 case IL_IADD:
10690 case IL_KADD:
10691 case IL_UKADD:
10692 case IL_FADD:
10693 case IL_DADD:
10694 case IL_SCMPLXADD:
10695 case IL_DCMPLXADD:
10696 case IL_UIADD:
10697 case IL_AADD:
10698 opval = "+";
10699 goto binop;
10700 case IL_DSUB:
10701 opval = "-";
10702 goto binop;
10703 case IL_ISUB:
10704 case IL_KSUB:
10705 case IL_UKSUB:
10706 case IL_FSUB:
10707 case IL_SCMPLXSUB:
10708 case IL_DCMPLXSUB:
10709 case IL_UISUB:
10710 case IL_ASUB:
10711 opval = "-";
10712 goto binop;
10713 case IL_IMUL:
10714 case IL_KMUL:
10715 case IL_UKMUL:
10716 case IL_FMUL:
10717 case IL_DMUL:
10718 case IL_UIMUL:
10719 case IL_SCMPLXMUL:
10720 case IL_DCMPLXMUL:
10721 opval = "*";
10722 goto binop;
10723 case IL_SCMPLXDIV:
10724 case IL_DCMPLXDIV:
10725 case IL_DDIV:
10726 case IL_KDIV:
10727 case IL_FDIV:
10728 case IL_IDIV:
10729 opval = "/";
10730 goto binop;
10731 case IL_UIDIV:
10732 opval = "/_u";
10733 goto binop;
10734 case IL_UKDIV:
10735 opval = "/_u";
10736 goto binop;
10737 case IL_IDIVZ:
10738 opval = "/";
10739 goto binop;
10740 case IL_UIDIVZ:
10741 opval = "/_u";
10742 goto binop;
10743 case IL_KDIVZ:
10744 opval = "/";
10745 goto binop;
10746 case IL_UKDIVZ:
10747 opval = "/_u";
10748 goto binop;
10749 case IL_KAND:
10750 case IL_AND:
10751 opval = "&";
10752 goto binop;
10753 case IL_KOR:
10754 case IL_OR:
10755 opval = "|";
10756 goto binop;
10757 case IL_KXOR:
10758 case IL_XOR:
10759 opval = "^";
10760 goto binop;
10761 case IL_KMOD:
10762 case IL_MOD:
10763 opval = "%";
10764 goto binop;
10765 case IL_UIMOD:
10766 opval = "%_u";
10767 goto binop;
10768 case IL_MODZ:
10769 opval = "%";
10770 goto binop;
10771 case IL_UIMODZ:
10772 opval = "%_u";
10773 goto binop;
10774 case IL_KMODZ:
10775 opval = "%";
10776 goto binop;
10777 case IL_KUMODZ:
10778 opval = "%_u";
10779 goto binop;
10780 case IL_FMOD:
10781 n = 2;
10782 opval = "amod";
10783 goto intrinsic;
10784 case IL_DMOD:
10785 n = 2;
10786 opval = "dmod";
10787 goto intrinsic;
10788 case IL_LSHIFT:
10789 case IL_ULSHIFT:
10790 case IL_KLSHIFT:
10791 opval = "<<";
10792 goto binop;
10793 case IL_RSHIFT:
10794 case IL_URSHIFT:
10795 case IL_KURSHIFT:
10796 opval = ">>";
10797 goto binop;
10798 case IL_ARSHIFT:
10799 case IL_KARSHIFT:
10800 opval = "a>>";
10801 goto binop;
10802
10803 case IL_IPOWI:
10804 #ifdef IL_KPOWI
10805 case IL_KPOWI:
10806 #endif
10807 #ifdef IL_KPOWK
10808 case IL_KPOWK:
10809 #endif
10810 case IL_DPOWK:
10811 case IL_DPOWD:
10812 case IL_DPOWI:
10813 case IL_FPOWF:
10814 case IL_FPOWI:
10815 case IL_FPOWK:
10816 case IL_SCMPLXPOW:
10817 case IL_DCMPLXPOW:
10818 case IL_SCMPLXPOWI:
10819 case IL_DCMPLXPOWI:
10820 case IL_SCMPLXPOWK:
10821 case IL_DCMPLXPOWK:
10822 opval = "**";
10823 goto binop;
10824
10825 case IL_KCMP:
10826 case IL_UKCMP:
10827 case IL_DCMPLXCMP:
10828 case IL_SCMPLXCMP:
10829 case IL_ICMP:
10830 case IL_FCMP:
10831 case IL_DCMP:
10832 case IL_ACMP:
10833 case IL_UICMP:
10834 #ifdef IL_X87CMP
10835 case IL_X87CMP:
10836 #endif
10837 #ifdef IL_DOUBLEDOUBLECMP
10838 case IL_DOUBLEDOUBLECMP:
10839 #endif
10840 opval = ccval[ILI_OPND(i, 3)];
10841 binop:
10842 if ((o = optype(ILI_OPC(ILI_OPND(i, 1)))) != OT_UNARY && o != OT_LEAF) {
10843 fputc('(', gbl.dbgfil);
10844 prilitree(ILI_OPND(i, 1));
10845 fputc(')', gbl.dbgfil);
10846 } else
10847 prilitree(ILI_OPND(i, 1));
10848 fprintf(gbl.dbgfil, "%s", opval);
10849 if ((o = optype(ILI_OPC(ILI_OPND(i, 2)))) != OT_UNARY && o != OT_LEAF) {
10850 fputc('(', gbl.dbgfil);
10851 prilitree(ILI_OPND(i, 2));
10852 fputc(')', gbl.dbgfil);
10853 } else
10854 prilitree(ILI_OPND(i, 2));
10855 break;
10856
10857 case IL_INEG:
10858 case IL_KNEG:
10859 case IL_UKNEG:
10860 case IL_SCMPLXNEG:
10861 case IL_DCMPLXNEG:
10862 case IL_DNEG:
10863 case IL_UINEG:
10864 case IL_FNEG:
10865 opval = "-";
10866 goto unop;
10867 case IL_NOT:
10868 case IL_UNOT:
10869 case IL_KNOT:
10870 case IL_UKNOT:
10871 opval = "!";
10872 unop:
10873 fprintf(gbl.dbgfil, "%s", opval);
10874 if ((o = optype(ILI_OPC(ILI_OPND(i, 1)))) != OT_UNARY && o != OT_LEAF) {
10875 fputc('(', gbl.dbgfil);
10876 prilitree(ILI_OPND(i, 1));
10877 fputc(')', gbl.dbgfil);
10878 } else
10879 prilitree(ILI_OPND(i, 1));
10880 break;
10881 case IL_ICMPZ:
10882 case IL_KCMPZ:
10883 case IL_FCMPZ:
10884 case IL_DCMPZ:
10885 case IL_ACMPZ:
10886 case IL_UICMPZ:
10887 opval = ccval[ILI_OPND(i, 2)];
10888 if ((o = optype(ILI_OPC(ILI_OPND(i, 1)))) != OT_UNARY && o != OT_LEAF) {
10889 fputc('(', gbl.dbgfil);
10890 prilitree(ILI_OPND(i, 1));
10891 fputc(')', gbl.dbgfil);
10892 } else
10893 prilitree(ILI_OPND(i, 1));
10894 fprintf(gbl.dbgfil, "%s0", opval);
10895 break;
10896
10897 case IL_HFMAX:
10898 case IL_FMAX:
10899 case IL_DMAX:
10900 case IL_KMAX:
10901 case IL_IMAX:
10902 n = 2;
10903 opval = "max";
10904 goto intrinsic;
10905 case IL_HFMIN:
10906 case IL_FMIN:
10907 case IL_DMIN:
10908 case IL_KMIN:
10909 case IL_IMIN:
10910 n = 2;
10911 opval = "min";
10912 goto intrinsic;
10913 case IL_DBLE:
10914 n = 1;
10915 opval = "dble";
10916 goto intrinsic;
10917 case IL_SNGL:
10918 n = 1;
10919 opval = "sngl";
10920 goto intrinsic;
10921 case IL_SCMPLX2IMAG:
10922 n = 1;
10923 opval = "imag";
10924 goto intrinsic;
10925 break;
10926 case IL_DCMPLX2IMAG:
10927 n = 1;
10928 opval = "dimag";
10929 goto intrinsic;
10930 break;
10931 case IL_SCMPLX2REAL:
10932 n = 1;
10933 opval = "real";
10934 goto intrinsic;
10935 break;
10936 case IL_DCMPLX2REAL:
10937 n = 1;
10938 opval = "dreal";
10939 goto intrinsic;
10940 break;
10941 case IL_SPSP2SCMPLX:
10942 n = 2;
10943 opval = "cmplx";
10944 goto intrinsic;
10945 break;
10946 case IL_SPSP2SCMPLXI0:
10947 n = 1;
10948 opval = "cmplx";
10949 goto intrinsic;
10950 break;
10951 case IL_DPDP2DCMPLX:
10952 n = 2;
10953 opval = "dcmplx";
10954 goto intrinsic;
10955 break;
10956 case IL_DPDP2DCMPLXI0:
10957 n = 1;
10958 opval = "dcmplx";
10959 goto intrinsic;
10960 break;
10961 case IL_SCMPLXCONJG:
10962 n = 1;
10963 opval = "conjg";
10964 goto intrinsic;
10965 break;
10966 case IL_DCMPLXCONJG:
10967 n = 1;
10968 opval = "conjg";
10969 goto intrinsic;
10970 break;
10971 case IL_SCMPLXEXP:
10972 n = 1;
10973 opval = "cexp";
10974 goto intrinsic;
10975 break;
10976 case IL_DCMPLXEXP:
10977 n = 1;
10978 opval = "cdexp";
10979 goto intrinsic;
10980 break;
10981 case IL_SCMPLXCOS:
10982 n = 1;
10983 opval = "cexp";
10984 goto intrinsic;
10985 break;
10986 case IL_DCMPLXCOS:
10987 n = 1;
10988 opval = "cdexp";
10989 goto intrinsic;
10990 break;
10991 case IL_SCMPLXSIN:
10992 n = 1;
10993 opval = "csin";
10994 goto intrinsic;
10995 break;
10996 case IL_DCMPLXSIN:
10997 n = 1;
10998 opval = "cdsin";
10999 goto intrinsic;
11000 break;
11001 case IL_SCMPLXTAN:
11002 n = 1;
11003 opval = "ctan";
11004 goto intrinsic;
11005 break;
11006 case IL_DCMPLXTAN:
11007 n = 1;
11008 opval = "cdtan";
11009 goto intrinsic;
11010 break;
11011 case IL_SCMPLXACOS:
11012 n = 1;
11013 opval = "cacos";
11014 goto intrinsic;
11015 break;
11016 case IL_DCMPLXACOS:
11017 n = 1;
11018 opval = "cdacos";
11019 goto intrinsic;
11020 break;
11021 case IL_SCMPLXASIN:
11022 n = 1;
11023 opval = "casin";
11024 goto intrinsic;
11025 break;
11026 case IL_DCMPLXASIN:
11027 n = 1;
11028 opval = "cdasin";
11029 goto intrinsic;
11030 break;
11031 case IL_SCMPLXATAN:
11032 n = 1;
11033 opval = "catan";
11034 goto intrinsic;
11035 break;
11036 case IL_DCMPLXATAN:
11037 n = 1;
11038 opval = "cdatan";
11039 goto intrinsic;
11040 break;
11041 case IL_SCMPLXCOSH:
11042 n = 1;
11043 opval = "ccosh";
11044 goto intrinsic;
11045 break;
11046 case IL_DCMPLXCOSH:
11047 n = 1;
11048 opval = "cdcosh";
11049 goto intrinsic;
11050 break;
11051 case IL_SCMPLXSINH:
11052 n = 1;
11053 opval = "csinh";
11054 goto intrinsic;
11055 break;
11056 case IL_DCMPLXSINH:
11057 n = 1;
11058 opval = "cdsinh";
11059 goto intrinsic;
11060 break;
11061 case IL_SCMPLXTANH:
11062 n = 1;
11063 opval = "ctanh";
11064 goto intrinsic;
11065 break;
11066 case IL_DCMPLXTANH:
11067 n = 1;
11068 opval = "cdtanh";
11069 goto intrinsic;
11070 break;
11071 case IL_SCMPLXLOG:
11072 n = 1;
11073 opval = "clog";
11074 goto intrinsic;
11075 break;
11076 case IL_DCMPLXLOG:
11077 n = 1;
11078 opval = "cdlog";
11079 goto intrinsic;
11080 break;
11081 case IL_SCMPLXSQRT:
11082 n = 1;
11083 opval = "csqrt";
11084 goto intrinsic;
11085 break;
11086 case IL_DCMPLXSQRT:
11087 n = 1;
11088 opval = "cdsqrt";
11089 goto intrinsic;
11090 break;
11091 case IL_FIX:
11092 case IL_FIXK:
11093 case IL_FIXUK:
11094 n = 1;
11095 opval = "fix";
11096 goto intrinsic;
11097 case IL_DFIXK:
11098 case IL_DFIXUK:
11099 n = 1;
11100 opval = "dfix";
11101 goto intrinsic;
11102 case IL_UFIX:
11103 n = 1;
11104 opval = "fix";
11105 goto intrinsic;
11106 case IL_DFIX:
11107 case IL_DFIXU:
11108 n = 1;
11109 opval = "dfix";
11110 goto intrinsic;
11111 case IL_FLOAT:
11112 n = 1;
11113 opval = "float";
11114 goto intrinsic;
11115 case IL_FLOATK:
11116 n = 1;
11117 opval = "floatk";
11118 goto intrinsic;
11119 case IL_FLOATU:
11120 n = 1;
11121 opval = "floatu";
11122 goto intrinsic;
11123 case IL_FLOATUK:
11124 n = 1;
11125 opval = "floatuk";
11126 goto intrinsic;
11127 case IL_DEXP:
11128 n = 1;
11129 opval = "dexp";
11130 goto intrinsic;
11131 case IL_DFLOAT:
11132 n = 1;
11133 opval = "dfloat";
11134 goto intrinsic;
11135 case IL_DFLOATU:
11136 n = 1;
11137 opval = "dfloatu";
11138 goto intrinsic;
11139 case IL_DFLOATK:
11140 n = 1;
11141 opval = "dfloatk";
11142 goto intrinsic;
11143 case IL_DFLOATUK:
11144 n = 1;
11145 opval = "dfloatuk";
11146 goto intrinsic;
11147 case IL_DNEWT:
11148 case IL_FNEWT:
11149 n = 1;
11150 opval = "recip";
11151 goto intrinsic;
11152 case IL_NINT:
11153 n = 1;
11154 opval = "nint";
11155 goto intrinsic;
11156 #ifdef IL_KNINT
11157 case IL_KNINT:
11158 n = 1;
11159 opval = "knint";
11160 goto intrinsic;
11161 #endif
11162 case IL_IDNINT:
11163 n = 1;
11164 opval = "idnint";
11165 goto intrinsic;
11166 #ifdef IL_KIDNINT
11167 case IL_KIDNINT:
11168 n = 1;
11169 opval = "kidnint";
11170 goto intrinsic;
11171 #endif
11172 case IL_DABS:
11173 n = 1;
11174 opval = "abs";
11175 goto intrinsic;
11176 case IL_FABS:
11177 n = 1;
11178 opval = "abs";
11179 goto intrinsic;
11180 case IL_KABS:
11181 n = 1;
11182 opval = "abs";
11183 goto intrinsic;
11184 case IL_IABS:
11185 n = 1;
11186 opval = "abs";
11187 goto intrinsic;
11188 case IL_FSQRT:
11189 n = 1;
11190 opval = "sqrt";
11191 goto intrinsic;
11192 case IL_SIGN:
11193 n = 2;
11194 opval = "sign";
11195 goto intrinsic;
11196 case IL_RCPSS:
11197 n = 1;
11198 opval = "rcpss";
11199 goto intrinsic;
11200 case IL_RSQRTSS:
11201 n = 1;
11202 opval = "rsqrtss";
11203 goto intrinsic;
11204 case IL_DSQRT:
11205 n = 1;
11206 opval = "dsqrt";
11207 goto intrinsic;
11208 case IL_DSIGN:
11209 n = 2;
11210 opval = "dsign";
11211 goto intrinsic;
11212 #ifdef IL_FRSQRT
11213 case IL_FRSQRT:
11214 n = 1;
11215 opval = "frsqrt";
11216 goto intrinsic;
11217 #endif
11218 case IL_FAND:
11219 n = 2;
11220 opval = "andps";
11221 goto intrinsic;
11222 case IL_ILEADZI:
11223 n = 2;
11224 opval = "leadz";
11225 goto intrinsic;
11226 case IL_ILEADZ:
11227 case IL_KLEADZ:
11228 n = 1;
11229 opval = "leadz";
11230 goto intrinsic;
11231 case IL_IPOPCNTI:
11232 n = 2;
11233 opval = "popcnt";
11234 goto intrinsic;
11235 case IL_IPOPCNT:
11236 case IL_KPOPCNT:
11237 n = 1;
11238 opval = "popcnt";
11239 goto intrinsic;
11240 case IL_IPOPPARI:
11241 n = 2;
11242 opval = "poppar";
11243 goto intrinsic;
11244 case IL_IPOPPAR:
11245 case IL_KPOPPAR:
11246 n = 1;
11247 opval = "poppar";
11248 goto intrinsic;
11249 case IL_CMPNEQSS:
11250 n = 2;
11251 opval = "cmpneqss";
11252 goto intrinsic;
11253 case IL_VA_ARG:
11254 n = 1;
11255 opval = IL_NAME(opc);
11256 goto intrinsic;
11257 case IL_ALLOC:
11258 case IL_DEALLOC:
11259 n = 1;
11260 opval = IL_NAME(opc);
11261 goto intrinsic;
11262 intrinsic:
11263 fprintf(gbl.dbgfil, "%s(", opval);
11264 for (j = 1; j <= n; ++j) {
11265 prilitree(ILI_OPND(i, j));
11266 if (j != n)
11267 fprintf(gbl.dbgfil, ",");
11268 }
11269 fprintf(gbl.dbgfil, ")");
11270 break;
11271
11272 case IL_JMP:
11273 fprintf(gbl.dbgfil, "goto %d[bih%d]\n", ILI_OPND(i, 1),
11274 ILIBLKG(ILI_OPND(i, 1)));
11275 break;
11276
11277 case IL_UKCJMP:
11278 case IL_KCJMP:
11279 case IL_ICJMP:
11280 case IL_FCJMP:
11281 case IL_DCJMP:
11282 case IL_ACJMP:
11283 case IL_UICJMP:
11284 prilitree(ILI_OPND(i, 1));
11285 fprintf(gbl.dbgfil, " %s ", ccval[ILI_OPND(i, 3)]);
11286 prilitree(ILI_OPND(i, 2));
11287 fprintf(gbl.dbgfil, " goto %d[bih%d]\n", ILI_OPND(i, 4),
11288 ILIBLKG(ILI_OPND(i, 4)));
11289 break;
11290 case IL_KCJMPZ:
11291 case IL_UKCJMPZ:
11292 case IL_ICJMPZ:
11293 case IL_FCJMPZ:
11294 case IL_DCJMPZ:
11295 case IL_ACJMPZ:
11296 case IL_UICJMPZ:
11297 prilitree(ILI_OPND(i, 1));
11298 fprintf(gbl.dbgfil, " %s 0", ccval[ILI_OPND(i, 2)]);
11299 fprintf(gbl.dbgfil, " goto %d[bih%d]\n", ILI_OPND(i, 3),
11300 ILIBLKG(ILI_OPND(i, 3)));
11301 break;
11302
11303 case IL_DFRKR:
11304 case IL_DFRIR:
11305 case IL_DFRSP:
11306 case IL_DFRDP:
11307 case IL_DFRCS:
11308 case IL_DFRAR:
11309 prilitree(ILI_OPND(i, 1));
11310 break;
11311
11312 case IL_JSRA:
11313 case IL_GJSRA:
11314 fprintf(gbl.dbgfil, "*(");
11315 prilitree(ILI_OPND(i, 1));
11316 fprintf(gbl.dbgfil, ")(");
11317 goto like_jsr;
11318 case IL_QJSR:
11319 case IL_JSR:
11320 case IL_GJSR:
11321 fprintf(gbl.dbgfil, "%s(", getprint(ILI_OPND(i, 1)));
11322 like_jsr:
11323 j = ILI_OPND(i, 2);
11324 k = 0;
11325 while (ILI_OPC(j) != 0) {
11326 if (k)
11327 fprintf(gbl.dbgfil, ", ");
11328 switch (ILI_OPC(j)) {
11329 case IL_DAKR:
11330 case IL_DAAR:
11331 case IL_DADP:
11332 #ifdef IL_DA128
11333 case IL_DA128:
11334 #endif
11335 #ifdef IL_DA256
11336 case IL_DA256:
11337 #endif
11338 case IL_DASP:
11339 case IL_DAIR:
11340 #ifdef IL_DASPSP
11341 case IL_DASPSP:
11342 case IL_DACS:
11343 case IL_DACD:
11344 #endif
11345 prilitree(ILI_OPND(j, 1));
11346 j = ILI_OPND(j, 3);
11347 break;
11348 #ifdef IL_ARGRSRV
11349 case IL_ARGRSRV:
11350 fprintf(gbl.dbgfil, "%%%d", ILI_OPND(j, 1));
11351 j = ILI_OPND(j, 2);
11352 break;
11353 #endif
11354 case IL_ARGKR:
11355 case IL_ARGIR:
11356 case IL_ARGSP:
11357 case IL_ARGDP:
11358 case IL_ARGAR:
11359 #ifdef LONG_DOUBLE_FLOAT128
11360 case IL_FLOAT128ARG:
11361 #endif
11362 case IL_GARG:
11363 case IL_GARGRET:
11364 prilitree(ILI_OPND(j, 1));
11365 j = ILI_OPND(j, 2);
11366 break;
11367 default:
11368 goto done;
11369 }
11370 k = 1;
11371 }
11372 done:
11373 fprintf(gbl.dbgfil, ")\n");
11374 break;
11375
11376 case IL_MVKR:
11377 opval = "MVKR";
11378 fprintf(gbl.dbgfil, "%s(%d,%d) = ", opval, KR_MSH(ILI_OPND(i, 2)),
11379 KR_LSH(ILI_OPND(i, 2)));
11380 prilitree(ILI_OPND(i, 1));
11381 fprintf(gbl.dbgfil, "\n");
11382 break;
11383 case IL_MVIR:
11384 opval = "MVIR";
11385 goto mv_reg;
11386 case IL_MVSP:
11387 opval = "MVSP";
11388 goto mv_reg;
11389 case IL_MVDP:
11390 opval = "MVDP";
11391 goto mv_reg;
11392 case IL_MVAR:
11393 opval = "MVAR";
11394 goto mv_reg;
11395 mv_reg:
11396 fprintf(gbl.dbgfil, "%s(%2d) = ", opval, ILI_OPND(i, 2));
11397 prilitree(ILI_OPND(i, 1));
11398 fprintf(gbl.dbgfil, "\n");
11399 break;
11400 case IL_KRDF:
11401 opval = "KRDF";
11402 fprintf(gbl.dbgfil, "%s(%d,%d)", opval, KR_MSH(ILI_OPND(i, 1)),
11403 KR_LSH(ILI_OPND(i, 1)));
11404 break;
11405 case IL_IRDF:
11406 opval = "IRDF";
11407 goto df_reg;
11408 case IL_SPDF:
11409 opval = "SPDF";
11410 goto df_reg;
11411 case IL_DPDF:
11412 opval = "DPDF";
11413 goto df_reg;
11414 case IL_ARDF:
11415 opval = "ARDF";
11416 goto df_reg;
11417 df_reg:
11418 fprintf(gbl.dbgfil, "%s(%2d)", opval, ILI_OPND(i, 1));
11419 break;
11420 case IL_IAMV:
11421 case IL_AIMV:
11422 case IL_KAMV:
11423 case IL_AKMV:
11424 prilitree(ILI_OPND(i, 1));
11425 break;
11426 case IL_KIMV:
11427 fprintf(gbl.dbgfil, "_K2I(");
11428 prilitree(ILI_OPND(i, 1));
11429 fprintf(gbl.dbgfil, ")");
11430 break;
11431 case IL_IKMV:
11432 fprintf(gbl.dbgfil, "_I2K(");
11433 prilitree(ILI_OPND(i, 1));
11434 fprintf(gbl.dbgfil, ")");
11435 break;
11436 case IL_UIKMV:
11437 fprintf(gbl.dbgfil, "_UI2K(");
11438 prilitree(ILI_OPND(i, 1));
11439 fprintf(gbl.dbgfil, ")");
11440 break;
11441
11442 case IL_CSE:
11443 case IL_CSEKR:
11444 case IL_CSEIR:
11445 case IL_CSESP:
11446 case IL_CSEDP:
11447 case IL_CSEAR:
11448 case IL_CSECS:
11449 case IL_CSECD:
11450 #ifdef LONG_DOUBLE_FLOAT128
11451 case IL_FLOAT128CSE:
11452 #endif
11453 fprintf(gbl.dbgfil, "#<");
11454 prilitree(ILI_OPND(i, 1));
11455 fprintf(gbl.dbgfil, ">#");
11456 break;
11457 case IL_FREEKR:
11458 opval = "FREEKR";
11459 goto pscomm;
11460 case IL_FREECS:
11461 opval = "FREECS";
11462 goto pscomm;
11463 case IL_FREECD:
11464 opval = "FREECD";
11465 goto pscomm;
11466 case IL_FREEDP:
11467 opval = "FREEDP";
11468 goto pscomm;
11469 case IL_FREESP:
11470 opval = "FREESP";
11471 goto pscomm;
11472 case IL_FREEAR:
11473 opval = "FREEAR";
11474 goto pscomm;
11475 case IL_FREEIR:
11476 opval = "FREEIR";
11477 goto pscomm;
11478 case IL_FREE:
11479 opval = "FREE";
11480 goto pscomm;
11481 #ifdef LONG_DOUBLE_FLOAT128
11482 case IL_FLOAT128FREE:
11483 opval = "FLOAT128FR";
11484 goto pscomm;
11485 #endif /* LONG_DOUBLE_FLOAT128 */
11486 pscomm:
11487 fprintf(gbl.dbgfil, "%s = ", opval);
11488 prilitree(ILI_OPND(i, 1));
11489 fprintf(gbl.dbgfil, ";\n");
11490 break;
11491
11492 case IL_KCON:
11493 case IL_ICON:
11494 case IL_FCON:
11495 case IL_DCON:
11496 case IL_SCMPLXCON:
11497 case IL_DCMPLXCON:
11498 prcon(ILI_OPND(i, 1));
11499 break;
11500
11501 case IL_ACON:
11502 j = ILI_OPND(i, 1);
11503 if (CONVAL1G(j)) {
11504 fprintf(gbl.dbgfil, "<");
11505 prsym(CONVAL1G(j), gbl.dbgfil);
11506 } else
11507 fprintf(gbl.dbgfil, "<%d", CONVAL1G(j));
11508 fprintf(gbl.dbgfil, ",%" ISZ_PF "d>", ACONOFFG(j));
11509 break;
11510
11511 case IL_LD:
11512 case IL_LDSP:
11513 case IL_LDDP:
11514 case IL_LDSCMPLX:
11515 case IL_LDDCMPLX:
11516 case IL_LDKR:
11517 case IL_LDA:
11518 prnme(ILI_OPND(i, 2), ILI_OPND(i, 1));
11519 if (DBGBIT(10, 4096)) {
11520 fprintf(gbl.dbgfil, "<*");
11521 prilitree(ILI_OPND(i, 1));
11522 fprintf(gbl.dbgfil, "*>");
11523 }
11524 break;
11525 case IL_VLD:
11526 case IL_VLDU:
11527 prnme(ILI_OPND(i, 2), ILI_OPND(i, 1));
11528 fprintf(gbl.dbgfil, "(V%d) ", ILI_OPND(i, 3));
11529 if (DBGBIT(10, 4096)) {
11530 fprintf(gbl.dbgfil, "<*");
11531 prilitree(ILI_OPND(i, 1));
11532 fprintf(gbl.dbgfil, "*>");
11533 }
11534 break;
11535
11536 case IL_STKR:
11537 case IL_ST:
11538 case IL_STDP:
11539 case IL_STSP:
11540 case IL_STSCMPLX:
11541 case IL_STDCMPLX:
11542 case IL_DSTS_SCALAR:
11543 case IL_SSTS_SCALAR:
11544 case IL_STA:
11545 prnme(ILI_OPND(i, 3), ILI_OPND(i, 2));
11546 if (DBGBIT(10, 4096)) {
11547 fprintf(gbl.dbgfil, "<*");
11548 prilitree(ILI_OPND(i, 2));
11549 fprintf(gbl.dbgfil, "*>");
11550 }
11551 fprintf(gbl.dbgfil, " = ");
11552 prilitree(ILI_OPND(i, 1));
11553 fprintf(gbl.dbgfil, ";\n");
11554 break;
11555 case IL_VST:
11556 case IL_VSTU:
11557 prnme(ILI_OPND(i, 3), ILI_OPND(i, 2));
11558 fprintf(gbl.dbgfil, "(V%d) ", ILI_OPND(i, 4));
11559 if (DBGBIT(10, 4096)) {
11560 fprintf(gbl.dbgfil, "<*");
11561 prilitree(ILI_OPND(i, 2));
11562 fprintf(gbl.dbgfil, "*>");
11563 }
11564 fprintf(gbl.dbgfil, " = ");
11565 prilitree(ILI_OPND(i, 1));
11566 fprintf(gbl.dbgfil, ";\n");
11567 break;
11568
11569 case IL_PREFETCHNTA:
11570 case IL_PREFETCHT0:
11571 case IL_PREFETCHW:
11572 case IL_PREFETCH:
11573 fprintf(gbl.dbgfil, "%s ", IL_MNEMONIC(opc));
11574 prilitree(ILI_OPND(i, 1));
11575 if (ILI_OPND(i, 3)) {
11576 dumpname(ILI_OPND(i, 3));
11577 }
11578 fprintf(gbl.dbgfil, ";\n");
11579 break;
11580 case IL_PDMV_LOWH:
11581 case IL_PDMV_HIGHH:
11582 case IL_PSLD_LOWH:
11583 case IL_PSLD_HIGHH:
11584 case IL_PSST_LOWH:
11585 case IL_PSST_HIGHH:
11586 case IL_PDLD_LOWH:
11587 case IL_PDLD_HIGHH:
11588 case IL_PDST_LOWH:
11589 case IL_PDLD:
11590 case IL_PDST:
11591 case IL_PDMUL:
11592 case IL_PDST_HIGHH:
11593 fprintf(gbl.dbgfil, "%s( ", IL_NAME(opc));
11594 prilitree(ILI_OPND(i, 1));
11595 fprintf(gbl.dbgfil, ", xmm%d", ILI_OPND(i, 2));
11596 fprintf(gbl.dbgfil, " )");
11597 if (ILI_OPND(i, 3)) {
11598 dumpname(ILI_OPND(i, 3));
11599 }
11600 fprintf(gbl.dbgfil, "\n");
11601 break;
11602
11603 case IL_ISELECT:
11604 case IL_ASELECT:
11605 case IL_KSELECT:
11606 case IL_FSELECT:
11607 case IL_DSELECT:
11608 case IL_CSSELECT:
11609 case IL_CDSELECT:
11610 fprintf(gbl.dbgfil, "%s(", IL_NAME(opc));
11611 prilitree(ILI_OPND(i, 1));
11612 fprintf(gbl.dbgfil, " : ");
11613 prilitree(ILI_OPND(i, 2));
11614 fprintf(gbl.dbgfil, " : ");
11615 prilitree(ILI_OPND(i, 3));
11616 fprintf(gbl.dbgfil, ")\n");
11617 break;
11618
11619 default:
11620 dilitree(i);
11621 break;
11622 }
11623 }
11624 #endif
11625
11626 void
dmpilitree(int i)11627 dmpilitree(int i)
11628 {
11629 #if DEBUG
11630 assert(i > 0, "dmpilitree: invalid value for ili pointer:", i, ERR_Severe);
11631 if (DBGBIT(10, 512))
11632 prilitree(i);
11633 else
11634 dilitree(i);
11635 #endif
11636 }
11637
11638 #if DEBUG
11639 void
ddilitree(int i,int flag)11640 ddilitree(int i, int flag)
11641 {
11642 FILE *f = gbl.dbgfil;
11643 assert(i > 0, "ddilitree: invalid value for ili pointer:", i, ERR_Severe);
11644 gbl.dbgfil = stderr;
11645 if (flag) {
11646 prilitree(i);
11647 fprintf(gbl.dbgfil, "\n");
11648 } else
11649 dilitree(i);
11650 gbl.dbgfil = f;
11651 }
11652
11653 void
_ddilitree(int i,int flag)11654 _ddilitree(int i, int flag)
11655 {
11656 FILE *f = gbl.dbgfil;
11657 assert(i > 0, "_ddilitree: invalid value for ili pointer:", i, ERR_Severe);
11658 if (f == NULL)
11659 gbl.dbgfil = stderr;
11660 if (flag) {
11661 prilitree(i);
11662 fprintf(gbl.dbgfil, "\n");
11663 } else
11664 dilitree(i);
11665 gbl.dbgfil = f;
11666 }
11667 #endif
11668
11669 static int
get_encl_function(int sptr)11670 get_encl_function(int sptr)
11671 {
11672 int enclsptr = ENCLFUNCG(sptr);
11673 while (enclsptr &&
11674 STYPEG(enclsptr) != ST_ENTRY
11675 ) {
11676 assert(enclsptr != ENCLFUNCG(enclsptr),
11677 "Invalid ENCLFUNC, cannot be recursive", sptr, ERR_Fatal);
11678 enclsptr = ENCLFUNCG(enclsptr);
11679 }
11680 return enclsptr;
11681 }
11682
11683 /**
11684 * \brief Finds the corresponding host function of the device outlined function.
11685
11686 */
11687 static SPTR
find_host_function()11688 find_host_function() {
11689 SPTR current_function = GBL_CURRFUNC;
11690 return current_function;
11691 }
11692
11693 bool
is_llvm_local_private(int sptr)11694 is_llvm_local_private(int sptr) {
11695 const int enclsptr = get_encl_function(sptr);
11696 const SPTR current_function = find_host_function();
11697 if (enclsptr && !OUTLINEDG(enclsptr))
11698 return false;
11699 /* Some compiler generated private variables does not have ENCLFUNC set
11700 * especially if
11701 * generated in the back end i.e., by optimizer - assumed locally defined in
11702 * function.
11703 */
11704 if (!enclsptr && SCG(sptr) == SC_PRIVATE && OUTLINEDG(GBL_CURRFUNC))
11705 return true;
11706 return enclsptr && (SC_PRIVATE == SCG(sptr)) && (enclsptr == current_function);
11707 }
11708
11709 bool
is_llvm_local(int sptr,int funcsptr)11710 is_llvm_local(int sptr, int funcsptr)
11711 {
11712 const int enclsptr = get_encl_function(sptr);
11713 if (enclsptr && !OUTLINEDG(enclsptr))
11714 return false;
11715 if (!enclsptr && SCG(sptr) == SC_PRIVATE && OUTLINEDG(GBL_CURRFUNC))
11716 return true;
11717 return enclsptr && (SC_PRIVATE == SCG(sptr)) && (enclsptr == GBL_CURRFUNC);
11718 }
11719
11720 static int
ll_internref_ili(SPTR sptr)11721 ll_internref_ili(SPTR sptr)
11722 {
11723 int mem, homeval, ili, nme, off;
11724 INT zoff;
11725 SPTR asym;
11726 int anme;
11727
11728 off = 0;
11729 mem = get_sptr_uplevel_address(sptr);
11730 zoff = ADDRESSG(mem);
11731
11732 if (SCG(aux.curr_entry->display) == SC_DUMMY) {
11733 asym = mk_argasym(aux.curr_entry->display);
11734 nme = addnme(NT_VAR, asym, 0, 0);
11735 ili = ad_acon(asym, 0);
11736 ili = ad2ili(IL_LDA, ili, nme);
11737 } else {
11738 nme = addnme(NT_VAR, aux.curr_entry->display, 0, (INT)0);
11739 ili = ad_acon(aux.curr_entry->display, (INT)0);
11740 ili = ad2ili(IL_LDA, ili, nme); /* load display struct */
11741 }
11742 nme = addnme(NT_VAR, aux.curr_entry->display, 0, (INT)0);
11743
11744 if (zoff) {
11745 off = ad_aconi(zoff);
11746 ili = ad3ili(IL_AADD, ili, off, 0); /* add offset of sptr to display */
11747 }
11748 if (PASSBYVALG(sptr)) {
11749 return ili;
11750 }
11751 nme = addnme(NT_VAR, sptr, 0, 0);
11752 ili = ad2ili(IL_LDA, ili, nme); /* load sptr addr from display struct */
11753 ADDRCAND(ili, nme);
11754 return ili;
11755 }
11756
11757 static int
ll_taskprivate_inhost_ili(SPTR sptr)11758 ll_taskprivate_inhost_ili(SPTR sptr)
11759 {
11760 int ilix, offset, basenm;
11761
11762 /* This access happens only we copy into firstprivate data for task
11763 * in the host routine
11764 */
11765 SPTR taskAllocSptr = llTaskAllocSptr();
11766 if (taskAllocSptr != SPTR_NULL) {
11767 if (!ADDRESSG(sptr) && SCG(sptr) == SC_PRIVATE && TASKG(sptr)) {
11768 /* There are certain compiler generated temp variable that
11769 * is created much later such as forall loop variable when
11770 * we transform array assignment to loop or temp var
11771 * to hold temp value for array bounds. We would want to
11772 * make is local to a routine.
11773 * Reasons:
11774 * 1) if host routine is not outlined function,
11775 * compiler will give error.
11776 * 2) it should be private for taskdup routine so that
11777 * it does not share with other task.
11778 */
11779 return ad_acon(sptr, 0);
11780 }
11781 basenm = addnme(NT_VAR, taskAllocSptr, 0, 0);
11782 ilix = ad2ili(IL_LDA, ad_acon(taskAllocSptr, 0), basenm);
11783 ilix = ad3ili(IL_AADD, ilix, ad_aconi(ADDRESSG(sptr)), 0);
11784 return ilix;
11785 } else {
11786 offset = ll_get_uplevel_offset(sptr);
11787 ilix = ad_acon(aux.curr_entry->uplevel, 0);
11788 basenm = addnme(NT_VAR, aux.curr_entry->uplevel, 0, 0);
11789 ilix = ad2ili(IL_LDA, ilix, basenm);
11790 }
11791 return ilix;
11792 }
11793
11794 static int
ll_uplevel_addr_ili(SPTR sptr,bool is_task_priv)11795 ll_uplevel_addr_ili(SPTR sptr, bool is_task_priv)
11796 {
11797 int ilix, basenm, offset, homeval, device_sptr;
11798 bool isLocalPriv;
11799
11800 isLocalPriv = is_llvm_local_private(sptr);
11801 if (flg.smp) {
11802 if (!is_task_priv && isLocalPriv) {
11803 return ad_acon(sptr, (INT)0);
11804 }
11805 }
11806
11807 /* Certain variable: SC_STATIC is set in the backend but PARREF flag may
11808 * have been set in the front end already.
11809 */
11810 if (SCG(sptr) == SC_STATIC && !THREADG(sptr)
11811 )
11812 return ad_acon(sptr, (INT)0);
11813 if (SCG(aux.curr_entry->uplevel) == SC_DUMMY) {
11814 SPTR asym = mk_argasym(aux.curr_entry->uplevel);
11815 int anme = addnme(NT_VAR, asym, 0, (INT)0);
11816 ilix = ad_acon(asym, 0);
11817 ilix = ad2ili(IL_LDA, ilix, anme);
11818 basenm = addnme(NT_VAR, aux.curr_entry->uplevel, 0, 0);
11819 if (TASKFNG(GBL_CURRFUNC) || ISTASKDUPG(GBL_CURRFUNC)) {
11820 int nme = addnme(NT_IND, aux.curr_entry->uplevel, basenm, 0);
11821 ilix = ad2ili(IL_LDA, ilix, nme); /* task[0] */
11822 }
11823 } else {
11824 /* aux.curr_entry->uplevel is local ptr = shared ptr address */
11825 ilix = ad_acon(aux.curr_entry->uplevel, 0);
11826 basenm = addnme(NT_VAR, aux.curr_entry->uplevel, 0, 0);
11827 ilix = ad2ili(IL_LDA, ilix, basenm);
11828 }
11829 if (TASKFNG(GBL_CURRFUNC) || ISTASKDUPG(GBL_CURRFUNC)) {
11830 if (TASKG(sptr)) {
11831 if (is_task_priv) {
11832 if (ISTASKDUPG(GBL_CURRFUNC)) {
11833 SPTR arg = ll_get_hostprog_arg(GBL_CURRFUNC, 1);
11834 ilix = ad_acon(arg, 0);
11835 basenm = addnme(NT_VAR, arg, 0, 0);
11836 } else {
11837 SPTR arg = ll_get_shared_arg(GBL_CURRFUNC);
11838 ilix = ad_acon(arg, 0);
11839 basenm = addnme(NT_VAR, arg, 0, 0);
11840 }
11841 offset = ADDRESSG(sptr);
11842 } else {
11843 if (ISTASKDUPG(GBL_CURRFUNC)) {
11844 SPTR arg;
11845 offset = llmp_task_get_privoff(
11846 sptr, llGetTask(OUTLINEDG(TASKDUPG(GBL_CURRFUNC))));
11847 if (offset) {
11848 arg = ll_get_hostprog_arg(GBL_CURRFUNC, 2);
11849 ilix = ad_acon(arg, 0);
11850 basenm = addnme(NT_VAR, arg, 0, 0);
11851 }
11852 } else
11853 return ad_acon(sptr, (INT)0);
11854 }
11855 } else {
11856 if (ISTASKDUPG(GBL_CURRFUNC)) {
11857 offset = llmp_task_get_privoff(sptr,
11858 llGetTask(OUTLINEDG(TASKDUPG(GBL_CURRFUNC))));
11859 if (!offset)
11860 offset = ll_get_uplevel_offset(sptr);
11861 } else
11862 offset = ll_get_uplevel_offset(sptr);
11863 }
11864 }
11865 else if (OMPTEAMPRIVATEG(sptr)) {
11866 offset = ADDRESSG(sptr);
11867 }
11868 else {
11869 offset = ll_get_uplevel_offset(sptr);
11870 }
11871 ilix = ad3ili(IL_AADD, ilix, ad_aconi(offset), 0);
11872 ilix = ad2ili(IL_LDA, ilix, addnme(NT_IND, sptr, basenm, 0));
11873 return ilix;
11874 }
11875
11876 int
mk_charlen_parref_sptr(SPTR sptr)11877 mk_charlen_parref_sptr(SPTR sptr)
11878 {
11879 int ilix, basenm;
11880 INT offset;
11881 if (is_llvm_local_private(sptr)) {
11882 return ad_acon(sptr, 0);
11883 }
11884 ilix = ad_acon(aux.curr_entry->uplevel, 0);
11885 basenm = addnme(NT_VAR, aux.curr_entry->uplevel, 0, 0);
11886 ilix = ad2ili(IL_LDA, ilix, basenm);
11887 offset = ll_get_uplevel_offset(sptr);
11888 offset += 8;
11889 ilix = ad3ili(IL_AADD, ilix, ad_aconi(offset), 0);
11890 return ilix;
11891 }
11892
11893 /**
11894 * \brief create ili representing the address of a variable
11895 */
11896 int
mk_address(SPTR sptr)11897 mk_address(SPTR sptr)
11898 {
11899 LLTask *task;
11900 bool is_task_priv;
11901
11902 if (UPLEVELG(sptr) && (SCG(sptr) == SC_LOCAL || SCG(sptr) == SC_DUMMY)) {
11903 int ili;
11904 int nme;
11905 INT zoff;
11906 int off;
11907 int addr;
11908
11909 if (INTERNREFG(sptr) && gbl.internal > 1) {
11910 return ll_internref_ili(sptr);
11911 }
11912 }
11913
11914 /* call to ll_taskprivate_inhost_ili should happen only when
11915 * we copy and allocate firstprivate data onto taskalloc ptr
11916 * in the host routine. Firstprivate initialization must be
11917 * done before the construct(Note that for native compiler,
11918 * we do it inside task and that may or may not cause problem
11919 * in the future).
11920 */
11921 if (flg.smp && TASKG(sptr) && !ISTASKDUPG(GBL_CURRFUNC) &&
11922 (!TASKFNG(GBL_CURRFUNC) || !is_llvm_local_private(sptr))) {
11923 return ll_taskprivate_inhost_ili(sptr);
11924 }
11925
11926 /* Determine if sptr is a firstprivate variable in a task */
11927 if (ISTASKDUPG(GBL_CURRFUNC)) {
11928 int taskfn = TASKDUPG(GBL_CURRFUNC);
11929 task = llmp_task_get_by_fnsptr(taskfn);
11930 is_task_priv = task && !!llmp_task_get_private(task, sptr, taskfn);
11931 } else {
11932 task = TASKFNG(GBL_CURRFUNC) ? llmp_task_get_by_fnsptr(GBL_CURRFUNC) : NULL;
11933 is_task_priv = task && !!llmp_task_get_private(task, sptr, GBL_CURRFUNC);
11934 }
11935
11936 /* Make an address for an outlined function variable */
11937 #ifdef OMP_OFFLOAD_LLVM
11938 if(!(gbl.outlined && flg.omptarget && gbl.ompaccel_intarget))
11939 #endif
11940 if ((PARREFG(sptr) || TASKG(sptr)) &&
11941 (gbl.outlined || ISTASKDUPG(GBL_CURRFUNC)))
11942 {
11943 /* If it's a host function, we skip loading from uplevel and load them directly */
11944 if(((SCG(sptr) != SC_EXTERN && SCG(sptr) != SC_STATIC)) || THREADG(sptr))
11945 return ll_uplevel_addr_ili(sptr, is_task_priv);
11946 }
11947 if (SCG(sptr) == SC_DUMMY && !REDUCG(sptr)) {
11948 SPTR asym = mk_argasym(sptr);
11949 return ad_acon(asym, 0);
11950 }
11951 #ifdef VLAG
11952 if ((VLAG(sptr) || SCG(sptr) == SC_BASED) && MIDNUMG(sptr)) {
11953 return ad2ili(IL_LDA, ad_acon(MIDNUMG(sptr), (INT)0),
11954 addnme(NT_VAR, MIDNUMG(sptr), 0, (INT)0));
11955 }
11956 #endif
11957 return ad_acon(sptr, (INT)0);
11958 }
11959
11960 int
compute_address(SPTR sptr)11961 compute_address(SPTR sptr)
11962 {
11963 int addr;
11964 addr = mk_address(sptr);
11965 if (SCG(sptr) == SC_DUMMY) {
11966 SPTR asym = mk_argasym(sptr);
11967 int anme = addnme(NT_VAR, asym, 0, 0);
11968 addr = ad2ili(IL_LDA, addr, anme);
11969 }
11970 return addr;
11971 }
11972
11973 /*
11974 * General ili traversal routines; a list is used to keep track of
11975 * the ili which have been visited (located by visit_list).
11976 */
11977
11978 /** \brief Initialize for a traversal and call the traversal routine.
11979 *
11980 * The traversal routine sets the ILI_VISIT & ILI_VLIST fields.
11981 */
11982 int
ili_traverse(int (* visit_f)(int),int ilix)11983 ili_traverse(int (*visit_f)(int), int ilix)
11984 {
11985 visit_list = 1;
11986 ILI_VLIST(1) = 0;
11987 if (visit_f == NULL)
11988 /* initializing only; the visit routine is explicitly called */
11989 return 0;
11990 return (*visit_f)(ilix);
11991 }
11992
11993 /** \brief Add an ili to visit_list and set its VISIT field.
11994 */
11995 void
ili_visit(int ilix,int v)11996 ili_visit(int ilix, int v)
11997 {
11998 ILI_VISIT(ilix) = v;
11999 if (ILI_VLIST(ilix) == 0) {
12000 ILI_VLIST(ilix) = visit_list;
12001 visit_list = ilix;
12002 }
12003 }
12004
12005 /** \brief Clear the VISIT & VLIST fields of the ili in the visit_list.
12006 */
12007 void
ili_unvisit(void)12008 ili_unvisit(void)
12009 {
12010 int v, nxt;
12011
12012 for (v = visit_list; v;) {
12013 nxt = ILI_VLIST(v);
12014 ILI_VLIST(v) = 0;
12015 ILI_VISIT(v) = 0;
12016 v = nxt;
12017 }
12018 visit_list = 0;
12019 }
12020
12021 /** \brief Look for 'JSR' in this tree
12022 */
12023 static int
_jsrsearch(int ilix)12024 _jsrsearch(int ilix)
12025 {
12026 ILI_OP opc;
12027 int noprs, j;
12028 opc = ILI_OPC(ilix);
12029 switch (opc) {
12030 case IL_JSR:
12031 case IL_JSRA:
12032 ili_visit(ilix, 1);
12033 iltb.callfg = 1;
12034 return 1;
12035 default:
12036 break;
12037 }
12038 if (ILI_VISIT(ilix)) {
12039 return (ILI_VISIT(ilix) == 1);
12040 }
12041 noprs = IL_OPRS(opc);
12042 for (j = 1; j <= noprs; ++j) {
12043 if (IL_ISLINK(opc, j)) {
12044 const int opnd = ILI_OPND(ilix, j);
12045 if (_jsrsearch(opnd)) {
12046 ili_visit(ilix, 1);
12047 return 1;
12048 }
12049 }
12050 }
12051 ili_visit(ilix, 2);
12052 return 0;
12053 }
12054
12055 /** \brief Search for "jsrs"
12056 */
12057 int
jsrsearch(int ilix)12058 jsrsearch(int ilix)
12059 {
12060 iltb.callfg = 0;
12061 return _jsrsearch(ilix);
12062 } /* jsrsearch */
12063
12064 int
alt_qjsr(int ilix)12065 alt_qjsr(int ilix)
12066 {
12067 int altx, j, noprs;
12068 ILI_OP opc;
12069
12070 if (ILI_ALT(ilix)) {
12071 altx = ILI_ALT(ilix);
12072 opc = ILI_OPC(altx);
12073 if (IL_TYPE(opc) == ILTY_DEFINE)
12074 return 1;
12075
12076 /* In a few cases a QJSR's result ILI (namely a 'define' ILI such
12077 * as IL_DFRDP, etc) is not 'altx' itself but rather an operand of
12078 * 'altx'. For example, if the C99 ABI is used on x86 then a
12079 * complex*16 function result is returned in a pair of registers,
12080 * %xmm0 and %xmm1, and the ILI 'altx' is
12081 * IL_DPDP2DCMPLX( IL_DFRDP(...), IL_DFRDP(...) ). Also on x86-32
12082 * a 64-bit condition such as:
12083 *
12084 * if (i8 .gt. 0)
12085 *
12086 * gives rise to ILIs such as:
12087 *
12088 * 49 QJSR 342~<__mth_i_kcmpz> 48^
12089 * 50 DFRIR 49^ ir( 1)
12090 * 51 ICMPZ 50^ gt
12091 * 52 KCMPZ 47^ gt 51^-alt
12092 *
12093 * The solution for now is to check whether any operand of 'altx'
12094 * is a define ILI.
12095 *
12096 * This deals with the cases that we're currently aware of, but if
12097 * a situation arises in which the define ILI is more deeply
12098 * nested in 'altx's ILI tree then we'll have to implement a
12099 * complete fix, e.g. by calling 'qjsr_in()'. Note, if this
12100 * function fails to detect a QJSR ILI that is present in 'altx's
12101 * ILI tree then the x86 native CG may indicate this by generating
12102 * the warning ICE "gen_lilis: BIH_QJSR needs to be set for bih
12103 * <bih_number>".
12104 */
12105 noprs = IL_OPRS(opc);
12106 for (j = 1; j <= noprs; ++j) {
12107 if (IL_ISLINK(opc, j) &&
12108 IL_TYPE(ILI_OPC(ILI_OPND(altx, j))) == ILTY_DEFINE) {
12109 return 1;
12110 }
12111 }
12112 }
12113
12114 switch (ILI_OPC(ilix)) {
12115 case IL_FSINCOS:
12116 case IL_DSINCOS:
12117 return 1;
12118 default:
12119 break;
12120 }
12121 return 0;
12122 } /* end alt_qjsr(int ilix) */
12123
12124 /** \brief Look for 'QJSR' in this tree
12125 */
12126 int
qjsrsearch(int ilix)12127 qjsrsearch(int ilix)
12128 {
12129 ILI_OP opc;
12130 int noprs, j;
12131 opc = ILI_OPC(ilix);
12132 switch (opc) {
12133 case IL_QJSR:
12134 ili_visit(ilix, 1);
12135 return 1;
12136 default:;
12137 }
12138 if (alt_qjsr(ilix)) {
12139 ili_visit(ilix, 1);
12140 return 1;
12141 }
12142 if (ILI_VISIT(ilix)) {
12143 if (ILI_VISIT(ilix) == 1)
12144 return 1;
12145 return 0;
12146 }
12147 noprs = IL_OPRS(opc);
12148 for (j = 1; j <= noprs; ++j) {
12149 int opnd;
12150 if (IL_ISLINK(opc, j)) {
12151 opnd = ILI_OPND(ilix, j);
12152 if (qjsrsearch(opnd)) {
12153 ili_visit(ilix, 1);
12154 return 1;
12155 }
12156 }
12157 }
12158 ili_visit(ilix, 2);
12159 return 0;
12160 }
12161
12162 /** \brief If a VECT ili, return its dtype, 0 otherwise.
12163 */
12164
12165 int
ili_get_vect_arg_count(int ilix)12166 ili_get_vect_arg_count(int ilix)
12167 {
12168 if (ILI_OPC(ilix) == IL_CSE)
12169 return ili_get_vect_arg_count(ILI_OPND(ilix, 1));
12170 if (IL_VECT(ILI_OPC(ilix))) {
12171 switch (ILI_OPC(ilix)) {
12172 case IL_VNEG:
12173 case IL_VCVTV:
12174 case IL_VCVTS:
12175 case IL_VNOT:
12176 case IL_VABS:
12177 return 2;
12178 case IL_VSQRT:
12179 case IL_VCOS:
12180 case IL_VSIN:
12181 case IL_VACOS:
12182 case IL_VASIN:
12183 case IL_VSINCOS:
12184 case IL_VTAN:
12185 case IL_VSINH:
12186 case IL_VCOSH:
12187 case IL_VTANH:
12188 case IL_VATAN:
12189 case IL_VEXP:
12190 case IL_VLOG:
12191 case IL_VLOG10:
12192 case IL_VRCP:
12193 case IL_VRSQRT:
12194 case IL_VLD:
12195 case IL_VLDU:
12196 case IL_VADD:
12197 case IL_VSUB:
12198 case IL_VMUL:
12199 case IL_VAND:
12200 case IL_VOR:
12201 case IL_VXOR:
12202 case IL_VCMPNEQ:
12203 case IL_VLSHIFTV:
12204 case IL_VRSHIFTV:
12205 case IL_VLSHIFTS:
12206 case IL_VRSHIFTS:
12207 case IL_VURSHIFTS:
12208 case IL_VMIN:
12209 case IL_VMAX:
12210 return 3;
12211 case IL_VDIV:
12212 case IL_VDIVZ:
12213 case IL_VMOD:
12214 case IL_VMODZ:
12215 case IL_VPOW:
12216 case IL_VPOWI:
12217 case IL_VPOWK:
12218 case IL_VPOWIS:
12219 case IL_VPOWKS:
12220 case IL_VFPOWK:
12221 case IL_VDPOWI:
12222 case IL_VFPOWKS:
12223 case IL_VDPOWIS:
12224 case IL_VATAN2:
12225 case IL_VST:
12226 case IL_VSTU:
12227 case IL_VFMA1:
12228 case IL_VFMA2:
12229 case IL_VFMA3:
12230 case IL_VFMA4:
12231 case IL_VPERMUTE:
12232 case IL_VCMP:
12233 case IL_VBLEND:
12234 return 4;
12235 default:
12236 break;
12237 }
12238 }
12239 return 0;
12240 }
12241
12242 DTYPE
ili_get_vect_dtype(int ilix)12243 ili_get_vect_dtype(int ilix)
12244 {
12245 if (ILI_OPC(ilix) == IL_CSE)
12246 return ili_get_vect_dtype(ILI_OPND(ilix, 1));
12247 if (!IL_VECT(ILI_OPC(ilix)))
12248 return DT_NONE;
12249 switch (ILI_OPC(ilix)) {
12250 case IL_VCON:
12251 return DTYPEG(ILI_OPND(ilix, 1));
12252 case IL_VNEG:
12253 case IL_VCVTV:
12254 case IL_VCVTS:
12255 case IL_VCVTR:
12256 case IL_VNOT:
12257 case IL_VABS:
12258 return DT_ILI_OPND(ilix, 2);
12259 case IL_VSQRT:
12260 case IL_VCOS:
12261 case IL_VSIN:
12262 case IL_VACOS:
12263 case IL_VASIN:
12264 case IL_VSINCOS:
12265 case IL_VTAN:
12266 case IL_VSINH:
12267 case IL_VCOSH:
12268 case IL_VTANH:
12269 case IL_VATAN:
12270 case IL_VEXP:
12271 case IL_VLOG:
12272 case IL_VLOG10:
12273 case IL_VRCP:
12274 case IL_VRSQRT:
12275 case IL_VFLOOR:
12276 case IL_VCEIL:
12277 case IL_VAINT:
12278 case IL_VLD:
12279 case IL_VLDU:
12280 case IL_VADD:
12281 case IL_VSUB:
12282 case IL_VMUL:
12283 case IL_VAND:
12284 case IL_VOR:
12285 case IL_VXOR:
12286 case IL_VCMPNEQ:
12287 case IL_VLSHIFTV:
12288 case IL_VRSHIFTV:
12289 case IL_VLSHIFTS:
12290 case IL_VRSHIFTS:
12291 case IL_VURSHIFTS:
12292 case IL_VMIN:
12293 case IL_VMAX:
12294 return DT_ILI_OPND(ilix, 3);
12295 case IL_VDIV:
12296 case IL_VDIVZ:
12297 case IL_VMOD:
12298 case IL_VMODZ:
12299 case IL_VPOW:
12300 case IL_VPOWI:
12301 case IL_VPOWK:
12302 case IL_VPOWIS:
12303 case IL_VPOWKS:
12304 case IL_VFPOWK:
12305 case IL_VDPOWI:
12306 case IL_VFPOWKS:
12307 case IL_VDPOWIS:
12308 case IL_VATAN2:
12309 case IL_VST:
12310 case IL_VSTU:
12311 case IL_VFMA1:
12312 case IL_VFMA2:
12313 case IL_VFMA3:
12314 case IL_VFMA4:
12315 case IL_VPERMUTE:
12316 case IL_VCMP:
12317 case IL_VBLEND:
12318 return DT_ILI_OPND(ilix, 4);
12319 default:
12320 interr("ili_get_vect_dtype missing case for ili opc", ILI_OPC(ilix),
12321 ERR_Severe);
12322 }
12323 return DT_NONE;
12324 }
12325
12326 /** \brief Return MSZ_ for each datatype, or -1 if an aggregate type.
12327 *
12328 * Result is the memory reference size, not including padding.
12329 * For example, TY_X87 on x86 targets maps to F10.
12330 *
12331 * The logic is custom to each target.
12332 */
12333 MSZ
mem_size(TY_KIND ty)12334 mem_size(TY_KIND ty)
12335 {
12336 MSZ msz = MSZ_UNDEF;
12337 switch (ty) {
12338 case TY_PTR:
12339 msz = MSZ_PTR;
12340 break;
12341 case TY_INT8:
12342 msz = MSZ_I8;
12343 break;
12344 case TY_UINT8:
12345 msz = MSZ_I8;
12346 break;
12347 case TY_INT:
12348 msz = MSZ_WORD;
12349 break;
12350 case TY_FLOAT:
12351 msz = MSZ_F4;
12352 break;
12353 case TY_QUAD:
12354 DEBUG_ASSERT(size_of(DT_QUAD) == 8, "TY_QUAD assumed to be 8 bytes");
12355 msz = MSZ_F8;
12356 break;
12357 case TY_DBLE:
12358 msz = MSZ_F8;
12359 break;
12360 case TY_CMPLX:
12361 msz = MSZ_F8;
12362 break;
12363 case TY_DCMPLX:
12364 msz = MSZ_F16;
12365 break;
12366 case TY_LOG:
12367 msz = MSZ_WORD;
12368 break;
12369
12370 case TY_UINT:
12371 msz = MSZ_WORD;
12372 break;
12373
12374 case TY_SINT:
12375 msz = MSZ_SHWORD;
12376 break;
12377 case TY_SLOG:
12378 msz = MSZ_SHWORD;
12379 break;
12380 case TY_USINT:
12381 msz = MSZ_UHWORD;
12382 break;
12383 case TY_FLOAT128:
12384 msz = MSZ_F16;
12385 break;
12386 case TY_128:
12387 msz = MSZ_F16;
12388 break;
12389 default:
12390 msz = MSZ_UNDEF;
12391 }
12392 return msz;
12393 } /* mem_size */
12394
12395 static int
_ipowi(int x,int i)12396 _ipowi(int x, int i)
12397 {
12398 int f;
12399
12400 /* special cases */
12401
12402 if (i < 0) {
12403 if (x == 1)
12404 return 1;
12405 if (x == -1) {
12406 if (i & 1)
12407 return -1;
12408 return 1;
12409 }
12410 return 0;
12411 }
12412
12413 if (i == 0)
12414 return 1;
12415 f = 1;
12416 while (1) {
12417 if (i & 1)
12418 f *= x;
12419 i >>= 1;
12420 if (i == 0)
12421 return f;
12422 x *= x;
12423 }
12424 }
12425
12426 /** Raising an operand to a constant power >= 1. generate ILI which maximize
12427 * cse's (i.e., generate a balanced tree).
12428 *
12429 * - opn -- operand (ILI) raised to power 'pwd'
12430 * - pwr -- power (constant)
12431 * - opc -- mult ILI opcode
12432 */
12433 static int
_xpowi(int opn,int pwr,ILI_OP opc)12434 _xpowi(int opn, int pwr, ILI_OP opc)
12435 {
12436 int res;
12437 int p2; /* largest power of 2 such that 2**p2 <= opn**pwr */
12438 int n;
12439
12440 if (pwr >= 2) {
12441 p2 = 0;
12442 n = pwr;
12443 while ((n >>= 1) > 0)
12444 p2++;
12445
12446 n = 1 << p2; /* 2**p2 */
12447 res = opn;
12448 /* generate a balanced multiply tree whose height is p2 */
12449 while (p2-- > 0)
12450 res = ad2ili(opc, res, res);
12451
12452 /* residual */
12453 n = pwr - n;
12454 if (n > 0) {
12455 int right;
12456 right = _xpowi(opn, n, opc);
12457 res = ad2ili(opc, res, right);
12458 }
12459
12460 return res;
12461 }
12462 return opn;
12463 }
12464
12465 #if defined(TARGET_X8664) || defined(TARGET_POWER) || defined(TARGET_ARM64)
12466 static int
_frsqrt(int x)12467 _frsqrt(int x)
12468 {
12469 int three;
12470 int mhalf;
12471 int x0, ilix;
12472 INT num[2];
12473 /*
12474 * Newton's appx for recip sqrt:
12475 * x1 = (3.0*x0 - x*x0**3))/2.0
12476 * or
12477 * x1 = (3.0 - x*x0*x0)*x0*.5
12478 * or
12479 * x1 = (x*x0*x0 - 3.0)*x0*(-.5)
12480 */
12481 num[0] = 0;
12482 num[1] = 0x40400000;
12483 three = ad1ili(IL_FCON, getcon(num, DT_FLOAT));
12484 num[1] = 0xbf000000;
12485 mhalf = ad1ili(IL_FCON, getcon(num, DT_FLOAT));
12486 x0 = ad1ili(IL_RSQRTSS, x);
12487 ilix = ad2ili(IL_FMUL, x0, x0);
12488 ilix = ad2ili(IL_FMUL, x, ilix);
12489 ilix = ad2ili(IL_FSUB, ilix, three);
12490 ilix = ad2ili(IL_FMUL, ilix, x0);
12491 ilix = ad2ili(IL_FMUL, ilix, mhalf);
12492 #if defined(IL_FRSQRT)
12493 ilix = ad1altili(IL_FRSQRT, x, ilix);
12494 #endif
12495 return ilix;
12496 }
12497 #endif
12498
12499 ISZ_T
get_isz_conili(int ili)12500 get_isz_conili(int ili)
12501 {
12502 if (ILI_OPC(ili) == IL_KCON) {
12503 ISZ_T ii;
12504 ii = get_isz_cval(ILI_OPND(ili, 1));
12505 return ii;
12506 }
12507 #if DEBUG
12508 assert(ILI_OPC(ili) == IL_ICON, "get_isz_conili, unexpected const ILI",
12509 ILI_OPC(ili), ERR_unused);
12510 #endif
12511 return CONVAL2G(ILI_OPND(ili, 1));
12512 }
12513
12514 /** \brief Select an integer constant ili, ICON or KCON.
12515 */
12516 int
sel_icnst(ISZ_T val,int isi8)12517 sel_icnst(ISZ_T val, int isi8)
12518 {
12519 if (isi8) {
12520 return ad_kconi(val);
12521 }
12522 return ad_icon(val);
12523 }
12524
12525 /** \brief Select an integer conversion: IR/KR to IR, or IR/KR to KR
12526 */
12527 int
sel_iconv(int ili,int isi8)12528 sel_iconv(int ili, int isi8)
12529 {
12530 if (isi8) {
12531 if (IL_RES(ILI_OPC(ili)) != ILIA_KR) {
12532 return ad1ili(IL_IKMV, ili);
12533 }
12534 return ili;
12535 }
12536 if (IL_RES(ILI_OPC(ili)) == ILIA_KR)
12537 return ad1ili(IL_KIMV, ili);
12538 return ili;
12539 }
12540
12541 /** \brief Select an IR or KR substract by 1
12542 */
12543 int
sel_decr(int ili,int isi8)12544 sel_decr(int ili, int isi8)
12545 {
12546 if (isi8)
12547 return ad2ili(IL_KSUB, ili, ad_kcon(0, 1));
12548 return ad2ili(IL_ISUB, ili, ad_icon((INT)1));
12549 }
12550
12551 /** \brief Select an IR or KR conversion to AR
12552 */
12553 int
sel_aconv(int ili)12554 sel_aconv(int ili)
12555 {
12556 if (IL_RES(ILI_OPC(ili)) == ILIA_KR)
12557 return ad1ili(IL_KAMV, ili);
12558 return ad1ili(IL_IAMV, ili);
12559 }
12560
12561 /*
12562 * The following routines replace code which relied on the ordering of
12563 * certain ili and a defined relationship between ILIA_MAX & ILI_AR, e.g.,
12564 * opc >= IL_CSEIR && opc <= (IL_CSEAR+(ILIA_MAX-ILIA_AR)
12565 */
12566
12567 int
is_argili_opcode(ILI_OP opc)12568 is_argili_opcode(ILI_OP opc)
12569 {
12570 switch (opc) {
12571 case IL_ARGIR:
12572 case IL_ARGSP:
12573 case IL_ARGDP:
12574 case IL_ARGAR:
12575 case IL_ARGKR:
12576 case IL_GARG:
12577 case IL_GARGRET:
12578 #ifdef LONG_DOUBLE_FLOAT128
12579 case IL_FLOAT128ARG:
12580 #endif
12581 return 1;
12582 default:
12583 return 0;
12584 }
12585 }
12586
12587 int
is_cseili_opcode(ILI_OP opc)12588 is_cseili_opcode(ILI_OP opc)
12589 {
12590 switch (opc) {
12591 case IL_CSE:
12592 case IL_CSEIR:
12593 case IL_CSESP:
12594 case IL_CSEDP:
12595 case IL_CSEAR:
12596 case IL_CSECS:
12597 case IL_CSECD:
12598 case IL_CSEKR:
12599 #ifdef LONG_DOUBLE_FLOAT128
12600 case IL_FLOAT128CSE:
12601 #endif
12602 return 1;
12603 default:
12604 return 0;
12605 }
12606 }
12607
12608 int
is_freeili_opcode(ILI_OP opc)12609 is_freeili_opcode(ILI_OP opc)
12610 {
12611 switch (opc) {
12612 case IL_FREEIR:
12613 case IL_FREESP:
12614 case IL_FREEDP:
12615 case IL_FREECS:
12616 case IL_FREECD:
12617 case IL_FREEAR:
12618 case IL_FREEKR:
12619 case IL_FREE:
12620 #ifdef LONG_DOUBLE_FLOAT128
12621 case IL_FLOAT128FREE:
12622 #endif
12623 return 1;
12624 default:
12625 break;
12626 }
12627 return 0;
12628 }
12629
12630 int
is_mvili_opcode(ILI_OP opc)12631 is_mvili_opcode(ILI_OP opc)
12632 {
12633 switch (opc) {
12634 case IL_MVIR:
12635 case IL_MVSP:
12636 case IL_MVDP:
12637 case IL_MVAR:
12638 case IL_MVKR:
12639 #ifdef IL_MVSPX87
12640 case IL_MVSPX87:
12641 case IL_MVDPX87:
12642 #endif
12643 #ifdef LONG_DOUBLE_FLOAT128
12644 case IL_FLOAT128RETURN:
12645 #endif
12646 case IL_MVQ:
12647 case IL_MV256:
12648 return 1;
12649 default:
12650 break;
12651 }
12652 return 0;
12653 }
12654
12655 int
is_rgdfili_opcode(ILI_OP opc)12656 is_rgdfili_opcode(ILI_OP opc)
12657 {
12658 switch (opc) {
12659 case IL_IRDF:
12660 case IL_SPDF:
12661 case IL_DPDF:
12662 case IL_ARDF:
12663 case IL_KRDF:
12664 return 1;
12665 default:
12666 break;
12667 }
12668 return 0;
12669 }
12670
12671 int
is_daili_opcode(ILI_OP opc)12672 is_daili_opcode(ILI_OP opc)
12673 {
12674 switch (opc) {
12675 case IL_DAIR:
12676 case IL_DASP:
12677 case IL_DADP:
12678 #ifdef IL_DA128
12679 case IL_DA128:
12680 #endif
12681 #ifdef IL_DA256
12682 case IL_DA256:
12683 #endif
12684 case IL_DAAR:
12685 case IL_DAKR:
12686 case IL_DACS:
12687 case IL_DACD:
12688 #ifdef LONG_DOUBLE_FLOAT128
12689 case IL_FLOAT128ARG:
12690 #endif
12691 return 1;
12692 default:
12693 break;
12694 }
12695 return 0;
12696 }
12697
12698 int
is_dfrili_opcode(ILI_OP opc)12699 is_dfrili_opcode(ILI_OP opc)
12700 {
12701 switch (opc) {
12702 case IL_DFRIR:
12703 case IL_DFRSP:
12704 case IL_DFRDP:
12705 case IL_DFRAR:
12706 case IL_DFRCS:
12707 case IL_DFRKR:
12708 case IL_DFRCD:
12709 #ifdef LONG_DOUBLE_FLOAT128
12710 case IL_FLOAT128RESULT:
12711 #endif
12712 #ifdef IL_DFRDPX87
12713 case IL_DFRDPX87:
12714 case IL_DFRSPX87:
12715 #endif
12716 case IL_DFR128:
12717 case IL_DFR256:
12718 return 1;
12719 default:
12720 break;
12721 }
12722 return 0;
12723 }
12724
12725 bool
is_integer_comparison_opcode(ILI_OP opc)12726 is_integer_comparison_opcode(ILI_OP opc)
12727 {
12728 switch (opc) {
12729 case IL_ICMP:
12730 case IL_ICMPZ:
12731 case IL_UICMP:
12732 case IL_UICMPZ:
12733 case IL_KCMP:
12734 case IL_KCMPZ:
12735 case IL_UKCMP:
12736 case IL_UKCMPZ:
12737 case IL_ACMP:
12738 case IL_ACMPZ:
12739 case IL_FCMP:
12740 case IL_FCMPZ:
12741 case IL_DCMP:
12742 case IL_DCMPZ:
12743 case IL_SCMPLXCMP:
12744 case IL_DCMPLXCMP:
12745 #ifdef LONG_DOUBLE_FLOAT128
12746 case IL_FLOAT128CMP:
12747 #endif
12748 case IL_ICJMP:
12749 case IL_ICJMPZ:
12750 case IL_UICJMP:
12751 case IL_UICJMPZ:
12752 case IL_KCJMP:
12753 case IL_KCJMPZ:
12754 case IL_UKCJMP:
12755 case IL_UKCJMPZ:
12756 case IL_ACJMP:
12757 case IL_ACJMPZ:
12758 return true;
12759 default:
12760 return false;
12761 }
12762 }
12763
12764 bool
is_floating_comparison_opcode(ILI_OP opc)12765 is_floating_comparison_opcode(ILI_OP opc)
12766 {
12767 switch (opc) {
12768 case IL_FCMP:
12769 case IL_FCMPZ:
12770 case IL_DCMP:
12771 case IL_DCMPZ:
12772 case IL_SCMPLXCMP:
12773 case IL_DCMPLXCMP:
12774 #ifdef LONG_DOUBLE_FLOAT128
12775 case IL_FLOAT128CMP:
12776 #endif
12777 case IL_FCJMP:
12778 case IL_FCJMPZ:
12779 case IL_DCJMP:
12780 case IL_DCJMPZ:
12781 return true;
12782 default:
12783 return false;
12784 }
12785 }
12786
12787 bool
is_unsigned_opcode(ILI_OP opc)12788 is_unsigned_opcode(ILI_OP opc)
12789 {
12790 switch (opc) {
12791 case IL_UINEG:
12792 case IL_UKNEG:
12793 case IL_UNOT:
12794 case IL_UKNOT:
12795 case IL_UFIX:
12796 case IL_UIADD:
12797 case IL_UKADD:
12798 case IL_UISUB:
12799 case IL_UKSUB:
12800 case IL_UIMUL:
12801 case IL_UKMUL:
12802 case IL_UIMULH:
12803 case IL_UKMULH:
12804 case IL_UIDIV:
12805 case IL_UKDIV:
12806 case IL_UIMOD:
12807 case IL_UIMIN:
12808 case IL_UKMIN:
12809 case IL_UIMAX:
12810 case IL_UKMAX:
12811 case IL_UICMP:
12812 case IL_UICMPZ:
12813 case IL_UKCMP:
12814 case IL_UKCMPZ:
12815 case IL_UICJMP:
12816 case IL_UICJMPZ:
12817 case IL_UKCJMP:
12818 case IL_UKCJMPZ:
12819 return true;
12820 default:
12821 return false;
12822 }
12823 }
12824
12825 int
has_cse(int ilix)12826 has_cse(int ilix)
12827 {
12828 ILI_OP opc;
12829 int i;
12830
12831 opc = ILI_OPC(ilix);
12832 if (is_cseili_opcode(opc))
12833 return 1;
12834
12835 for (i = 1; i <= ilis[opc].oprs; i++) {
12836 if (IL_ISLINK(opc, i) && has_cse(ILI_OPND(ilix, i)))
12837 return 1;
12838 }
12839 return 0;
12840 }
12841
12842 #if DEBUG && defined(TARGET_64BIT)
12843 /*
12844 * recursive depth-first postorder traversal of the ili tree
12845 * look for calls to various MULH routines
12846 * KMULH - turn into IL_KMULH
12847 * UKMULH - turn into IL_UKMULH
12848 * IMULH - turn into upper-part of i32 multipy
12849 * UIMULH - turn into upper-part of unsigned i32 multipy
12850 */
12851 static int
mulhsearch(int ilix,int ilt)12852 mulhsearch(int ilix, int ilt)
12853 {
12854 int ret, jsr, mulh, arg1, arg2;
12855 ILI_OP opc;
12856 if (ilix <= 1)
12857 return ilix;
12858 if (ILI_REPL(ilix) && ILI_VISIT(ilix) == ilt) {
12859 /* we have a replacement for this ilt */
12860 ret = ILI_REPL(ilix);
12861 return ret;
12862 }
12863 opc = ILI_OPC(ilix);
12864 ili_visit(ilix, ilt);
12865 if (opc >= IL_CSEIR && opc <= IL_CSEKR) {
12866 int link;
12867 link = ILI_OPND(ilix, 1);
12868 if (ILI_REPL(link)) {
12869 /* just insert IL_CSE.. to this link */
12870 ILI New;
12871 if (ILI_REPL(link) == link) {
12872 ILI_REPL(ilix) = ilix;
12873 return ilix;
12874 }
12875 BZERO(&New, ILI, 1);
12876 New.opc = opc;
12877 New.opnd[0] = ILI_REPL(link);
12878 ret = ILI_REPL(ilix) = addili(&New);
12879 return ret;
12880 }
12881 }
12882 mulh = 0;
12883 if (opc == IL_DFRKR) {
12884 /* is this a call to KMULH */
12885 jsr = ILI_OPND(ilix, 1);
12886 if (ILI_OPC(jsr) == IL_JSR) {
12887 int sym;
12888 sym = ILI_OPND(jsr, 1);
12889 if (strcmp(SYMNAME(sym), "KMULH") == 0) {
12890 arg1 = ILI_OPND(jsr, 2);
12891 if (arg1) {
12892 arg2 = ILI_OPND(arg1, 3);
12893 if (arg2) {
12894 mulh = 1;
12895 }
12896 }
12897 } else if (strcmp(SYMNAME(sym), "UKMULH") == 0) {
12898 arg1 = ILI_OPND(jsr, 2);
12899 if (arg1) {
12900 arg2 = ILI_OPND(arg1, 3);
12901 if (arg2) {
12902 mulh = 2;
12903 }
12904 }
12905 }
12906 }
12907 }
12908 if (opc == IL_DFRIR) {
12909 /* is this a call to MULH */
12910 jsr = ILI_OPND(ilix, 1);
12911 if (ILI_OPC(jsr) == IL_JSR) {
12912 int sym;
12913 sym = ILI_OPND(jsr, 1);
12914 if (strcmp(SYMNAME(sym), "IMULH") == 0) {
12915 arg1 = ILI_OPND(jsr, 2);
12916 if (arg1) {
12917 arg2 = ILI_OPND(arg1, 3);
12918 if (arg2) {
12919 mulh = 3;
12920 }
12921 }
12922 } else if (strcmp(SYMNAME(sym), "UIMULH") == 0) {
12923 arg1 = ILI_OPND(jsr, 2);
12924 if (arg1) {
12925 arg2 = ILI_OPND(arg1, 3);
12926 if (arg2) {
12927 mulh = 4;
12928 }
12929 }
12930 }
12931 }
12932 }
12933 if (mulh == 1) {
12934 ret = KMULSH(ILI_OPND(arg1, 1), ILI_OPND(arg2, 1));
12935 ILI_REPL(ilix) = ret;
12936 } else if (mulh == 2) {
12937 ret = KMULUH(ILI_OPND(arg1, 1), ILI_OPND(arg2, 1));
12938 ILI_REPL(ilix) = ret;
12939 } else if (mulh == 3) {
12940 int op1, op2;
12941 op1 = ad1ili(IL_IKMV, ILI_OPND(arg1, 1));
12942 op2 = ad1ili(IL_IKMV, ILI_OPND(arg2, 1));
12943 ret = MULSH(op1, op2);
12944 ILI_REPL(ilix) = ret;
12945 } else if (mulh == 4) {
12946 int op1, op2;
12947 op1 = ad1ili(IL_UIKMV, ILI_OPND(arg1, 1));
12948 op2 = ad1ili(IL_UIKMV, ILI_OPND(arg2, 1));
12949 ret = MULUH(op1, op2);
12950 ILI_REPL(ilix) = ret;
12951 } else {
12952 int noprs, j, changes, newalt;
12953 ILI New;
12954 BZERO(&New, ILI, 1);
12955 noprs = IL_OPRS(opc);
12956 New.opc = opc;
12957 changes = 0;
12958 for (j = 1; j <= noprs; ++j) {
12959 int opnd;
12960 opnd = ILI_OPND(ilix, j);
12961 if (!IL_ISLINK(opc, j)) {
12962 New.opnd[j - 1] = opnd;
12963 } else {
12964 New.opnd[j - 1] = mulhsearch(opnd, ilt);
12965 if (New.opnd[j - 1] != opnd)
12966 ++changes;
12967 }
12968 }
12969 newalt = New.alt = 0;
12970 if (ILI_ALT(ilix)) {
12971 int alt;
12972 alt = ILI_ALT(ilix);
12973 newalt = mulhsearch(alt, ilt);
12974 New.alt = alt; /* old alt here; new alt to be replaced later */
12975 }
12976 if (changes == 0) {
12977 ret = ilix;
12978 } else {
12979 ret = addili(&New);
12980 ILI_ALT(ret) = New.alt;
12981 }
12982 }
12983 return ret;
12984 } /* mulhsearch */
12985
12986 /* turn KMULH call into IL_KMULH ili */
12987 void
inline_mulh(void)12988 inline_mulh(void)
12989 {
12990 int block, ili, callfg;
12991 bool save_share_proc_ili;
12992 for (ili = 0; ili < ilib.stg_avail; ++ili) {
12993 ILI_VISIT(ili) = ILI_REPL(ili) = 0;
12994 }
12995 save_share_proc_ili = share_proc_ili;
12996 share_proc_ili = false;
12997
12998 (void)ili_traverse(NULL, 0);
12999
13000 callfg = 0;
13001 for (block = gbl.entbih; block; block = BIH_NEXT(block)) {
13002 int ilt;
13003 rdilts(block);
13004 gbl.lineno = BIH_LINENO(block);
13005 gbl.findex = BIH_FINDEX(block);
13006 bihb.callfg = 0;
13007 iltb.callfg = 0;
13008 for (ilt = BIH_ILTFIRST(block); ilt; ilt = ILT_NEXT(ilt)) {
13009 ili_visit(1, 1);
13010 ILT_ILIP(ilt) = mulhsearch(ILT_ILIP(ilt), ilt);
13011 ili_unvisit();
13012 if (ILT_EX(ilt)) {
13013 /* jsrsearch() sets iltb.callfg to 0 or 1 */
13014 ili_visit(1, 1);
13015 ILT_EX(ilt) = jsrsearch(ILT_ILIP(ilt));
13016 ili_unvisit();
13017 }
13018 bihb.callfg |= iltb.callfg;
13019 }
13020 BIH_EX(block) = bihb.callfg;
13021 callfg |= bihb.callfg;
13022 wrilts(block);
13023 if (BIH_LAST(block))
13024 break;
13025 }
13026
13027 BIH_EX(gbl.entbih) = callfg;
13028
13029 share_proc_ili = save_share_proc_ili;
13030 for (ili = 0; ili < ilib.stg_avail; ++ili) {
13031 ILI_VISIT(ili) = ILI_REPL(ili) = 0;
13032 }
13033 } /* inline_mulh */
13034 #endif
13035
13036 int
mkfunc_avx(char * nmptr,int avxp)13037 mkfunc_avx(char *nmptr, int avxp)
13038 {
13039 int sptr;
13040 sptr = _mkfunc(nmptr);
13041 #ifdef AVXP
13042 /*
13043 * AVXP(sptr,avxp) ought to be sufficient, but am concerned
13044 * about clearing the AVX field for an existing 'avx' routine.
13045 */
13046 if (avxp) {
13047 AVXP(sptr, 1);
13048 }
13049 #endif
13050 return sptr;
13051 }
13052
13053 static int
_mkfunc(char * name)13054 _mkfunc(char *name)
13055 {
13056 int ss;
13057 if (!XBIT(15, 0x40))
13058 ss = mkfunc_cncall(name);
13059 else
13060 ss = mkfunc(name);
13061 return ss;
13062 }
13063
13064 static int
DblIsSingle(SPTR dd)13065 DblIsSingle(SPTR dd)
13066 {
13067 INT num[2];
13068
13069 if (XBIT(15, 0x80))
13070 return 0;
13071 if (is_dbl0(dd)) {
13072 return ad1ili(IL_FCON, stb.flt0);
13073 }
13074 num[0] = CONVAL1G(dd);
13075 num[1] = CONVAL2G(dd);
13076 if ((num[1] & 0x1fffffff) == 0) {
13077 /* the mantissa does not exceed the mantissa of a single
13078 * precision value
13079 */
13080 unsigned uu;
13081 int de; /* exponent of double value */
13082 uu = num[0];
13083 de = (int)((uu >> 20) & 0x7ff) - 1023;
13084 if (de >= -126 && de <= 127) {
13085 /*
13086 * exponent is within the Emin & Emax for single precision.
13087 */
13088 unsigned ds, dm; /* sign, mantissa of dble value */
13089 int se; /* exponent of single value */
13090 unsigned ss, sm; /* sign, mantissa of single value */
13091 INT v;
13092
13093 uu = num[0];
13094 ds = uu >> 31;
13095 dm = (uu & 0xfffff);
13096 uu = num[1] >> 29;
13097 dm = (dm << 3) | uu;
13098
13099 xsngl(num, &v);
13100 uu = v;
13101 ss = uu >> 31;
13102 se = (int)((uu >> 23) & 0xff) - 127;
13103 sm = uu & 0x7fffff;
13104
13105 if (ss == ds && se == de && sm == dm) {
13106 static INT numi[2];
13107 numi[1] = v;
13108 return ad1ili(IL_FCON, getcon(numi, DT_FLOAT));
13109 }
13110 }
13111 }
13112 return 0;
13113 }
13114
13115 /** \brief Check if the expression is shifting one left; if so, return its the
13116 * shift count.
13117 */
13118 static int
_lshift_one(int ili)13119 _lshift_one(int ili)
13120 {
13121 int op1;
13122
13123 switch (ILI_OPC(ili)) {
13124 case IL_LSHIFT:
13125 case IL_ULSHIFT:
13126 op1 = ILI_OPND(ili, 1);
13127 if (ILI_OPC(op1) != IL_ICON)
13128 return 0;
13129 break;
13130 case IL_KLSHIFT:
13131 op1 = ILI_OPND(ili, 1);
13132 if (ILI_OPC(op1) != IL_KCON)
13133 return 0;
13134 break;
13135 default:
13136 return 0;
13137 }
13138
13139 if (get_isz_conili(op1) == 1)
13140 return ILI_OPND(ili, 2);
13141
13142 return 0;
13143 }
13144
13145 /* If a new IL_(U)ICMPZ would test the result of another comparison,
13146 * it would be redundant. Returns a nonnegative ILI index if the
13147 * proposed IL_(U)ICMPZ is not needed, or -1 otherwise.
13148 */
13149 static int
cmpz_of_cmp(int op1,CC_RELATION cmpz_relation)13150 cmpz_of_cmp(int op1, CC_RELATION cmpz_relation)
13151 {
13152 int relation;
13153
13154 /* IL_(U)ICMPZ of IL_(U)ICMPZ can be collapsed */
13155 while (ILI_OPC(op1) == IL_ICMPZ || ILI_OPC(op1) == IL_UICMPZ) {
13156 cmpz_relation = combine_int_ccs(CC_ILI_OPND(op1, 2), cmpz_relation);
13157 if (cmpz_relation == 0)
13158 return -1;
13159 op1 = ILI_OPND(op1, 1);
13160 }
13161
13162 switch (ILI_OPC(op1)) {
13163 default:
13164 break;
13165 case IL_ICMP:
13166 case IL_UICMP:
13167 case IL_KCMP:
13168 case IL_UKCMP:
13169 case IL_ACMP:
13170 relation = combine_int_ccs(CC_ILI_OPND(op1, 3), cmpz_relation);
13171 if (relation == 0)
13172 break;
13173 return ad3ili(ILI_OPC(op1), ILI_OPND(op1, 1), ILI_OPND(op1, 2), relation);
13174 case IL_ICMPZ:
13175 case IL_UICMPZ:
13176 case IL_KCMPZ:
13177 case IL_UKCMPZ:
13178 case IL_ACMPZ:
13179 relation = combine_int_ccs(CC_ILI_OPND(op1, 2), cmpz_relation);
13180 if (relation == 0)
13181 break;
13182 return ad2ili(ILI_OPC(op1), ILI_OPND(op1, 1), relation);
13183 case IL_FCMP:
13184 case IL_DCMP:
13185 case IL_SCMPLXCMP:
13186 case IL_DCMPLXCMP:
13187 #ifdef LONG_DOUBLE_FLOAT128
13188 case IL_FLOAT128CMP:
13189 #endif
13190 if (IEEE_CMP)
13191 relation = combine_ieee_ccs(CC_ILI_OPND(op1, 3), cmpz_relation);
13192 else
13193 relation = combine_int_ccs(CC_ILI_OPND(op1, 3), cmpz_relation);
13194 if (relation == 0)
13195 break;
13196 return ad3ili(ILI_OPC(op1), ILI_OPND(op1, 1), ILI_OPND(op1, 2), relation);
13197 case IL_FCMPZ:
13198 case IL_DCMPZ:
13199 if (IEEE_CMP)
13200 relation = combine_ieee_ccs(CC_ILI_OPND(op1, 2), cmpz_relation);
13201 else
13202 relation = combine_int_ccs(CC_ILI_OPND(op1, 2), cmpz_relation);
13203 if (relation == 0)
13204 break;
13205 return ad2ili(ILI_OPC(op1), ILI_OPND(op1, 1), relation);
13206 }
13207 return -1;
13208 }
13209
13210 /* Predicate: does an ILI produce a value 0 <= x <= 1 only? */
13211 static bool
is_zero_one(int ili)13212 is_zero_one(int ili)
13213 {
13214 return false;
13215 }
13216
13217 int
ili_subscript(int sub)13218 ili_subscript(int sub)
13219 {
13220 if (ILI_OPC(sub) == IL_KCON) {
13221 int cst = ILI_OPND(sub, 1);
13222 if (CONVAL2G(cst) >= 0) {
13223 if (CONVAL1G(cst) == 0)
13224 sub = ad_icon(CONVAL2G(cst));
13225 } else if (CONVAL1G(cst) == 0xffffffffu)
13226 sub = ad_icon(CONVAL2G(cst));
13227 }
13228 return sub;
13229 }
13230
13231 int
ili_isdeleted(int ili)13232 ili_isdeleted(int ili)
13233 {
13234 if (ILI_OPC(ili) == GARB_COLLECTED) {
13235 return 1;
13236 }
13237 return 0;
13238 }
13239
13240 typedef struct {
13241 int ili, nme, dtype;
13242 } argtype;
13243 static argtype *args;
13244 static int nargs, argsize;
13245
13246 void
initcallargs(int count)13247 initcallargs(int count)
13248 {
13249 extern void init_arg_ili(int);
13250 NEW(args, argtype, count);
13251 nargs = 0;
13252 init_arg_ili(count);
13253 argsize = count;
13254 } /* initcallargs */
13255
13256 void
addcallarg(int ili,int nme,int dtype)13257 addcallarg(int ili, int nme, int dtype)
13258 {
13259 if (nargs >= argsize)
13260 interr("too many arguments in addcallarg", nargs, ERR_Fatal);
13261 args[nargs].ili = ili;
13262 args[nargs].nme = nme;
13263 args[nargs].dtype = dtype;
13264 ++nargs;
13265 } /* addcallarg */
13266
13267 int
gencallargs(void)13268 gencallargs(void)
13269 {
13270 extern void add_arg_ili(int, int, int);
13271 extern int gen_arg_ili(void);
13272 extern void end_arg_ili(void);
13273 int i;
13274 for (i = 0; i < nargs; ++i) {
13275 add_arg_ili(args[i].ili, args[i].nme, args[i].dtype);
13276 }
13277 i = gen_arg_ili();
13278 FREE(args);
13279 args = NULL;
13280 argsize = 0;
13281 end_arg_ili();
13282 return i;
13283 } /* gencallargs */
13284
13285 /*
13286 * generate the return DFR ILI
13287 */
13288 int
genretvalue(int ilix,ILI_OP resultopc)13289 genretvalue(int ilix, ILI_OP resultopc)
13290 {
13291 switch (resultopc) {
13292 case IL_NONE:
13293 break; /* no return value */
13294 case IL_DFRAR:
13295 ilix = ad2ili(resultopc, ilix, AR_RETVAL);
13296 break;
13297 case IL_DFRIR:
13298 ilix = ad2ili(resultopc, ilix, IR_RETVAL);
13299 break;
13300 case IL_DFRKR:
13301 ilix = ad2ili(resultopc, ilix, KR_RETVAL);
13302 break;
13303 case IL_DFRSP:
13304 ilix = ad2ili(resultopc, ilix, SP_RETVAL);
13305 break;
13306 case IL_DFRDP:
13307 ilix = ad2ili(resultopc, ilix, DP_RETVAL);
13308 break;
13309 case IL_DFRCS:
13310 ilix = ad2ili(resultopc, ilix, CS_RETVAL);
13311 break;
13312 default:
13313 interr("genretvalue: illegal resultopc", resultopc, ERR_Severe);
13314 }
13315 return ilix;
13316 } /* genretvalue */
13317
13318 #define SIZEOF(array) (sizeof(array) / sizeof(char *))
13319
13320 /* stc-kind: kind zero (normal)
13321 * kind one, comparison condition.
13322 * kind two, memory size
13323 */
13324 int
ilstckind(ILI_OP opc,int opnum)13325 ilstckind(ILI_OP opc, int opnum)
13326 {
13327 switch (opc) {
13328 case IL_ICMP:
13329 case IL_FCMP:
13330 case IL_DCMP:
13331 case IL_ACMP:
13332 case IL_ICMPZ:
13333 case IL_FCMPZ:
13334 case IL_DCMPZ:
13335 case IL_ACMPZ:
13336 case IL_ICJMP:
13337 case IL_FCJMP:
13338 case IL_DCJMP:
13339 case IL_ACJMP:
13340 case IL_ICJMPZ:
13341 case IL_FCJMPZ:
13342 case IL_DCJMPZ:
13343 case IL_ACJMPZ:
13344 #ifdef TM_LPCMP
13345 case IL_ICLOOP:
13346 case IL_FCLOOP:
13347 case IL_DCLOOP:
13348 case IL_ACLOOP:
13349 case IL_ICLOOPZ:
13350 case IL_FCLOOPZ:
13351 case IL_DCLOOPZ:
13352 case IL_ACLOOPZ:
13353 #endif
13354 case IL_UICMP:
13355 case IL_UICMPZ:
13356 case IL_UICJMP:
13357 case IL_UICJMPZ:
13358 case IL_KCJMP:
13359 case IL_KCJMPZ:
13360 case IL_KCMP:
13361 case IL_KCMPZ:
13362 case IL_UKCMP:
13363 case IL_UKCMPZ:
13364 case IL_UKCJMP:
13365 case IL_UKCJMPZ:
13366 case IL_SCMPLXCMP:
13367 case IL_DCMPLXCMP:
13368 case IL_LCJMPZ:
13369 #ifdef LONG_DOUBLE_FLOAT128
13370 case IL_FLOAT128CMP:
13371 #endif
13372 return 1;
13373 case IL_LD:
13374 case IL_ST:
13375 case IL_LDKR:
13376 case IL_STKR:
13377 case IL_LDSP:
13378 case IL_STSP:
13379 case IL_SSTS_SCALAR:
13380 case IL_LDDP:
13381 case IL_STDP:
13382 case IL_LDSCMPLX:
13383 case IL_LDDCMPLX:
13384 case IL_STSCMPLX:
13385 case IL_STDCMPLX:
13386 case IL_DSTS_SCALAR:
13387
13388 #ifdef LONG_DOUBLE_FLOAT128
13389 case IL_FLOAT128LD:
13390 case IL_FLOAT128ST:
13391 #endif
13392 return 2;
13393 default:
13394 return 0;
13395 }
13396 } /* ilstckind */
13397
13398 char *
scond(int c)13399 scond(int c)
13400 {
13401 static char *cond[] = {"..", "eq", "ne", "lt", "ge", "le", "gt",
13402 "neq", "nne", "nlt", "nge", "nle", "ngt"};
13403 static char B[15];
13404 if (c <= 0 || c >= SIZEOF(cond)) {
13405 snprintf(B, 15, "%d", c);
13406 return B;
13407 } else {
13408 return cond[c];
13409 }
13410 } /* scond */
13411
13412 /*
13413 * move, if necessary, from I to K register
13414 */
13415 int
ikmove(int ilix)13416 ikmove(int ilix)
13417 {
13418 if (ILI_OPC(ilix) == IL_KIMV)
13419 return ILI_OPND(ilix, 1);
13420 if (IL_RES(ILI_OPC(ilix)) == ILIA_IR) {
13421 ilix = ad1ili(IL_IKMV, ilix);
13422 }
13423 return ilix;
13424 } /* ikmove */
13425
13426 /*
13427 * move, if necessary, from I to K register
13428 */
13429 int
uikmove(int ilix)13430 uikmove(int ilix)
13431 {
13432 if (ILI_OPC(ilix) == IL_KIMV)
13433 return ILI_OPND(ilix, 1);
13434 if (IL_RES(ILI_OPC(ilix)) == ILIA_IR) {
13435 ilix = ad1ili(IL_UIKMV, ilix);
13436 }
13437 return ilix;
13438 } /* uikmove */
13439
13440 /*
13441 * move, if necessary, from K to I register
13442 */
13443 int
kimove(int ilix)13444 kimove(int ilix)
13445 {
13446 if (ILI_OPC(ilix) == IL_IKMV)
13447 return ILI_OPND(ilix, 1);
13448 if (IL_RES(ILI_OPC(ilix)) == ILIA_KR) {
13449 ilix = ad1ili(IL_KIMV, ilix);
13450 }
13451 return ilix;
13452 } /* kimove */
13453
13454 /*
13455 * Condition code operations
13456 */
13457 CC_RELATION
complement_int_cc(CC_RELATION cc)13458 complement_int_cc(CC_RELATION cc)
13459 {
13460 switch (cc) {
13461 case CC_EQ:
13462 return CC_NE;
13463 case CC_NE:
13464 return CC_EQ;
13465 case CC_LT:
13466 return CC_GE;
13467 case CC_GE:
13468 return CC_LT;
13469 case CC_LE:
13470 return CC_GT;
13471 case CC_GT:
13472 return CC_LE;
13473 default:
13474 interr("bad cc", cc, ERR_Severe);
13475 return CC_None;
13476 }
13477 }
13478
13479 CC_RELATION
complement_ieee_cc(CC_RELATION cc)13480 complement_ieee_cc(CC_RELATION cc)
13481 {
13482 if (IEEE_CMP) {
13483 switch (cc) {
13484 case CC_EQ:
13485 return CC_NE;
13486 case CC_NE:
13487 return CC_EQ;
13488 case CC_LT:
13489 return CC_NOTLT;
13490 case CC_GE:
13491 return CC_NOTGE;
13492 case CC_LE:
13493 return CC_NOTLE;
13494 case CC_GT:
13495 return CC_NOTGT;
13496 case CC_NOTEQ:
13497 return CC_EQ;
13498 case CC_NOTNE:
13499 return CC_NE;
13500 case CC_NOTLT:
13501 return CC_LT;
13502 case CC_NOTGE:
13503 return CC_GE;
13504 case CC_NOTLE:
13505 return CC_LE;
13506 case CC_NOTGT:
13507 return CC_GT;
13508 default:
13509 interr("bad cc", cc, ERR_Severe);
13510 return CC_None;
13511 }
13512 }
13513 return complement_int_cc(cc);
13514 }
13515
13516 CC_RELATION
commute_cc(CC_RELATION cc)13517 commute_cc(CC_RELATION cc)
13518 {
13519 switch (cc) {
13520 case CC_EQ:
13521 return CC_EQ;
13522 case CC_NE:
13523 return CC_NE;
13524 case CC_LT:
13525 return CC_GT;
13526 case CC_GE:
13527 return CC_LE;
13528 case CC_LE:
13529 return CC_GE;
13530 case CC_GT:
13531 return CC_LT;
13532 case CC_NOTEQ:
13533 return CC_NOTEQ;
13534 case CC_NOTNE:
13535 return CC_NOTNE;
13536 case CC_NOTLT:
13537 return CC_NOTGT;
13538 case CC_NOTGE:
13539 return CC_NOTLE;
13540 case CC_NOTLE:
13541 return CC_NOTGE;
13542 case CC_NOTGT:
13543 return CC_NOTLT;
13544 default:
13545 interr("bad cc", cc, ERR_Severe);
13546 return CC_None;
13547 }
13548 }
13549
13550 CC_RELATION
combine_int_ccs(CC_RELATION binary_cc,CC_RELATION zero_cc)13551 combine_int_ccs(CC_RELATION binary_cc, CC_RELATION zero_cc)
13552 {
13553 if (SCFTN_TRUE < 0) {
13554 zero_cc = commute_cc(zero_cc);
13555 }
13556 switch (zero_cc) {
13557 case CC_LT: /* {0,1} < 0: always false */
13558 case CC_GE: /* {0,1} >= 0: always true */
13559 /* don't fold, make jump unconditional or fall-through */
13560 return CC_None;
13561 case CC_NE:
13562 case CC_GT:
13563 switch (binary_cc) {
13564 case CC_EQ:
13565 case CC_NE:
13566 case CC_LT:
13567 case CC_GE:
13568 case CC_LE:
13569 case CC_GT:
13570 break;
13571 default:
13572 interr("bad binary_cc", binary_cc, ERR_Severe);
13573 }
13574 return binary_cc;
13575 case CC_EQ:
13576 case CC_LE:
13577 return complement_int_cc(binary_cc);
13578 default:
13579 interr("bad zero_cc", zero_cc, ERR_Severe);
13580 return CC_None;
13581 }
13582 }
13583
13584 CC_RELATION
combine_ieee_ccs(CC_RELATION binary_cc,CC_RELATION zero_cc)13585 combine_ieee_ccs(CC_RELATION binary_cc, CC_RELATION zero_cc)
13586 {
13587 if (SCFTN_TRUE < 0)
13588 zero_cc = commute_cc(zero_cc);
13589 switch (zero_cc) {
13590 case CC_LT: /* {0,1} < 0: always false */
13591 case CC_GE: /* {0,1} >= 0: always true */
13592 /* don't fold, make jump unconditional or fall-through */
13593 return CC_None;
13594 case CC_NE:
13595 case CC_GT:
13596 switch (binary_cc) {
13597 case CC_EQ:
13598 case CC_NE:
13599 case CC_LT:
13600 case CC_GE:
13601 case CC_LE:
13602 case CC_GT:
13603 case CC_NOTEQ:
13604 case CC_NOTNE:
13605 case CC_NOTLT:
13606 case CC_NOTGE:
13607 case CC_NOTLE:
13608 case CC_NOTGT:
13609 break;
13610 default:
13611 interr("bad binary_cc", binary_cc, ERR_Severe);
13612 }
13613 return binary_cc;
13614 case CC_EQ:
13615 case CC_LE:
13616 return complement_ieee_cc(binary_cc);
13617 default:
13618 interr("bad zero_cc", zero_cc, ERR_Severe);
13619 return CC_None;
13620 }
13621 }
13622
13623 bool
cc_includes_equality(CC_RELATION cc)13624 cc_includes_equality(CC_RELATION cc)
13625 {
13626 switch (cc) {
13627 case CC_EQ:
13628 case CC_GE:
13629 case CC_LE:
13630 return true;
13631 case CC_NE:
13632 case CC_LT:
13633 case CC_GT:
13634 return false;
13635 case CC_NOTEQ:
13636 case CC_NOTGE:
13637 case CC_NOTLE:
13638 return false;
13639 case CC_NOTNE:
13640 case CC_NOTLT:
13641 case CC_NOTGT:
13642 return false;
13643 default:
13644 interr("bad cc", cc, ERR_Severe);
13645 return false;
13646 }
13647 }
13648
13649 bool
ccs_are_complementary(CC_RELATION cc1,CC_RELATION cc2)13650 ccs_are_complementary(CC_RELATION cc1, CC_RELATION cc2)
13651 {
13652 switch (cc1) {
13653 case CC_EQ:
13654 return cc2 == CC_NE || cc2 == CC_NOTEQ;
13655 case CC_NE:
13656 return cc2 == CC_EQ || cc2 == CC_NOTNE;
13657 case CC_LT:
13658 return cc2 == CC_GE || cc2 == CC_NOTLT;
13659 case CC_GE:
13660 return cc2 == CC_LT || cc2 == CC_NOTGE;
13661 case CC_LE:
13662 return cc2 == CC_GT || cc2 == CC_NOTLE;
13663 case CC_GT:
13664 return cc2 == CC_LE || cc2 == CC_NOTGT;
13665 case CC_NOTEQ:
13666 return cc2 == CC_EQ;
13667 case CC_NOTNE:
13668 return cc2 == CC_NE;
13669 case CC_NOTLT:
13670 return cc2 == CC_LT;
13671 case CC_NOTGE:
13672 return cc2 == CC_GE;
13673 case CC_NOTLE:
13674 return cc2 == CC_LE;
13675 case CC_NOTGT:
13676 return cc2 == CC_GT;
13677 default:
13678 return false;
13679 }
13680 }
13681
13682 /* TODO: replace ll_ad_outlined_func with ad_func everywhere */
13683 int
ll_ad_outlined_func(ILI_OP result_opc,ILI_OP call_opc,char * func_name,int narg,int arg1,int arg2,int arg3)13684 ll_ad_outlined_func(ILI_OP result_opc, ILI_OP call_opc, char *func_name,
13685 int narg, int arg1, int arg2, int arg3)
13686 {
13687 return ad_func(result_opc, call_opc, func_name, narg, arg1, arg1, arg3);
13688 }
13689
13690 static bool
_is_nanf(int sptr)13691 _is_nanf(int sptr)
13692 {
13693 int v, e, m;
13694 /*
13695 * our fp cannoical form (big endian IEEE):
13696 * struct {
13697 * unsigned int s:1;
13698 * unsigned int e:8;
13699 * unsigned int m:23;
13700 * };
13701 * A NaN has an exponent field of all one's and a non-zero mantissa.
13702 */
13703 v = CONVAL2G(sptr);
13704 e = (v >> 23) & 0xff;
13705 if (e == 0xff) {
13706 m = v & 0x7fffff;
13707 if (m)
13708 return true;
13709 }
13710 return false;
13711 }
13712
13713 /* For an given ILI that calls a function, or stores a value,
13714 determine if the call can throw an exception, or if the store
13715 stores the result of call that can throw an exception.
13716 If so, determine to where control goes if an exception is thrown.
13717
13718 The possible return values are:
13719 0: never throws
13720 -1: might throw, but there are no associated cleanup actions in the
13721 caller.
13722 positive integer: index of a label symbol. */
13723 int
ili_throw_label(int ilix)13724 ili_throw_label(int ilix)
13725 {
13726 ILI_OP opc = ILI_OPC(ilix);
13727 if (IL_TYPE(opc) == ILTY_STORE) {
13728 /* See if it's a store of a function result. */
13729 ilix = ILI_OPND(ilix, 1);
13730 if (!is_dfrili_opcode(ILI_OPC(ilix)))
13731 return 0;
13732 ilix = ILI_OPND(ilix, 1);
13733 if (IL_TYPE(ILI_OPC(ilix)) != ILTY_PROC)
13734 return 0;
13735 }
13736 opc = ILI_OPC(ilix);
13737 DEBUG_ASSERT(IL_TYPE(opc) == ILTY_PROC,
13738 "ili_throw_label: not a store or proc");
13739 /* Look at the function call. Extract the "alt" if not a GJSR/GJSRA */
13740 switch (opc) {
13741 default:
13742 interr("ili_throw_label: not a call", ILI_OPC(ilix), ERR_Fatal);
13743 case IL_QJSR:
13744 /* QJSR never throws */
13745 return 0;
13746 case IL_JSR:
13747 case IL_JSRA:
13748 ilix = ILI_ALT(ilix);
13749 if (!ilix)
13750 /* Call must have "alt" if it can throw */
13751 return 0;
13752 break;
13753 case IL_GJSR:
13754 case IL_GJSRA:
13755 break;
13756 }
13757 /* Now looking at the GJSR/GJSRA call, which will have the throw label. */
13758 opc = ILI_OPC(ilix);
13759 switch (opc) {
13760 default:
13761 interr("ili_throw_label: unexpected alt", opc, ERR_Fatal);
13762 case IL_GJSR:
13763 return ILI_OPND(ilix, 3);
13764 case IL_GJSRA:
13765 return ILI_OPND(ilix, 5);
13766 }
13767 }
13768
13769 static char
dt_to_mthtype(char mtype)13770 dt_to_mthtype(char mtype)
13771 {
13772 switch (mtype) {
13773 default:
13774 break;
13775 case DT_FLOAT:
13776 return 's';
13777 case DT_DBLE:
13778 return 'd';
13779 case DT_CMPLX:
13780 return 'c';
13781 case DT_DCMPLX:
13782 return 'z';
13783 }
13784 interr("iliutil.c:dt_to_mthtype, unexpected mtype", mtype, ERR_Severe);
13785 return '?';
13786 }
13787
13788 /**
13789 \brief LLVM wrapper for make_math_name()
13790 \param buff (output), must be preallocated, should have a size > 32
13791 */
13792 void
llmk_math_name(char * buff,int fn,int vectlen,bool mask,DTYPE res_dt)13793 llmk_math_name(char *buff, int fn, int vectlen, bool mask, DTYPE res_dt)
13794 {
13795 DEBUG_ASSERT(buff, "buffer must not be null");
13796 buff[0] = '@';
13797 strcpy(buff + 1, make_math_name((MTH_FN)fn, vectlen, mask, res_dt));
13798 }
13799
13800 static bool override_abi = false;
13801
13802 char *
make_math_name(MTH_FN fn,int vectlen,bool mask,DTYPE res_dt)13803 make_math_name(MTH_FN fn, int vectlen, bool mask, DTYPE res_dt)
13804 {
13805 static char name[32]; /* return buffer */
13806 static char *fn2str[] = {"acos", "asin", "atan", "atan2", "cos", "cosh",
13807 "div", "exp", "log", "log10", "pow", "powi",
13808 "powk", "powi1", "powk1", "sin", "sincos", "sinh",
13809 "sqrt", "tan", "tanh", "mod", "floor", "ceil",
13810 "aint"};
13811 char *fstr;
13812 char ftype = 'f';
13813 if (flg.ieee)
13814 ftype = 'p';
13815 else if (XBIT_NEW_RELAXEDMATH)
13816 ftype = 'r';
13817 fstr = "__%c%c_%s_%d%s";
13818 if (vectlen == 1 && (override_abi || XBIT_VECTORABI_FOR_SCALAR))
13819 /* use vector ABI for scalar routines */
13820 fstr = "__%c%c_%s_%dv%s";
13821 sprintf(name, fstr, ftype, dt_to_mthtype(res_dt), fn2str[fn], vectlen,
13822 mask ? "m" : "");
13823 return name;
13824 }
13825
13826 char *
make_math_name_vabi(MTH_FN fn,int vectlen,bool mask,DTYPE res_dt)13827 make_math_name_vabi(MTH_FN fn, int vectlen, bool mask, DTYPE res_dt)
13828 {
13829 char *name;
13830 /*
13831 * Need an override for llvect since it may emit its own calls to the
13832 * scalar routines rather than emitting the corresponding scalar ILI.
13833 * For now, restrict the override to double complex!!!
13834 */
13835 ;
13836 if (res_dt == DT_DCMPLX)
13837 override_abi = true;
13838 name = make_math_name(fn, vectlen, mask, res_dt);
13839 override_abi = false;
13840 return name;
13841 }
13842
13843 char *
make_math(MTH_FN fn,SPTR * fptr,int vectlen,bool mask,DTYPE res_dt,int nargs,int arg1_dt,...)13844 make_math(MTH_FN fn, SPTR *fptr, int vectlen, bool mask, DTYPE res_dt,
13845 int nargs, int arg1_dt, ...)
13846 {
13847 va_list vargs;
13848 char *fname;
13849 SPTR func;
13850
13851 /* Note: standard says it is undefined behavior to pass an enum to va_start */
13852 va_start(vargs, arg1_dt);
13853 fname = make_math_name(fn, vectlen, mask, res_dt);
13854
13855 // NB: we must pass argX_dt as an int, because passing an enum (DTYPE) via
13856 // varargs is undefined behavior
13857 if (nargs == 1) {
13858 func = mk_prototype(fname, "f pure", res_dt, 1, arg1_dt);
13859 } else {
13860 const int arg2_dt = va_arg(vargs, int);
13861 func = mk_prototype(fname, "f pure", res_dt, 2, arg1_dt, arg2_dt);
13862 }
13863 if (fptr)
13864 *fptr = func;
13865 va_end(vargs);
13866 return fname;
13867 }
13868
13869 static int
atomic_encode_aux(MSZ msz,SYNC_SCOPE scope,ATOMIC_ORIGIN origin,ATOMIC_RMW_OP op)13870 atomic_encode_aux(MSZ msz, SYNC_SCOPE scope, ATOMIC_ORIGIN origin,
13871 ATOMIC_RMW_OP op)
13872 {
13873 union ATOMIC_ENCODER u;
13874 DEBUG_ASSERT(sizeof(u.info) <= sizeof(int),
13875 "need to reimplement atomic_encode");
13876 DEBUG_ASSERT((unsigned)origin <= (unsigned)AORG_MAX_DEF,
13877 "atomic_encode_ld_st: bad origin");
13878 DEBUG_ASSERT(scope == SS_SINGLETHREAD || scope == SS_PROCESS,
13879 "atomic_encode_ld_st: bad scope");
13880 u.encoding = 0;
13881 u.info.msz = msz;
13882 u.info.scope = scope;
13883 u.info.origin = origin;
13884 u.info.op = op;
13885 DEBUG_ASSERT((u.encoding & 0xFF) == msz,
13886 "ILI_MSZ_OF_LD and ILI_MSZ_OF_ST won't work");
13887 return u.encoding;
13888 }
13889
13890 /** Encode the given information into an int that can be used
13891 as the operand for a ATOMICLDx, ATOMICSTx, or CMPXCHGx. */
13892 int
atomic_encode(MSZ msz,SYNC_SCOPE scope,ATOMIC_ORIGIN origin)13893 atomic_encode(MSZ msz, SYNC_SCOPE scope, ATOMIC_ORIGIN origin)
13894 {
13895 return atomic_encode_aux(msz, scope, origin, AOP_UNDEF);
13896 }
13897
13898 /** Encode atomic info for an ATOMICRMW instruction. */
13899 int
atomic_encode_rmw(MSZ msz,SYNC_SCOPE scope,ATOMIC_ORIGIN origin,ATOMIC_RMW_OP op)13900 atomic_encode_rmw(MSZ msz, SYNC_SCOPE scope, ATOMIC_ORIGIN origin,
13901 ATOMIC_RMW_OP op)
13902 {
13903 DEBUG_ASSERT((unsigned)op <= (unsigned)AOP_MAX_DEF,
13904 "atomic_encode_ld_st: bad origin");
13905 return atomic_encode_aux(msz, scope, origin, op);
13906 }
13907
13908 /* Routines atomic_decode and atomic_info_index are provided for sake of LILI
13909 clients. ILI clients should use the more abstract routine atomic_info. */
13910
13911 /** Decode ATOMIC_INFO from an int that was created with atomic_encode
13912 or atomic_encode_rmw. */
13913 ATOMIC_INFO
atomic_decode(int encoding)13914 atomic_decode(int encoding)
13915 {
13916 ATOMIC_INFO result;
13917 union ATOMIC_ENCODER u;
13918 u.encoding = encoding;
13919 result.msz = (MSZ) u.info.msz;
13920 result.op = (ATOMIC_RMW_OP) u.info.op;
13921 result.origin = (ATOMIC_ORIGIN) u.info.origin;
13922 result.scope = (SYNC_SCOPE) u.info.scope;
13923 return result;
13924 }
13925
13926 /** Get index of ATOMIC_INFO operand for a given ILI instruction. */
13927 int
atomic_info_index(ILI_OP opc)13928 atomic_info_index(ILI_OP opc)
13929 {
13930 /* Get index of operand that encodes the ATOMIC_INFO. */
13931 switch (opc) {
13932 default:
13933 assert(false, "atomic_info: not an atomic op", opc, ERR_Severe);
13934 case IL_CMPXCHGI:
13935 case IL_CMPXCHGKR:
13936 case IL_CMPXCHGA:
13937 case IL_ATOMICRMWI:
13938 case IL_ATOMICRMWKR:
13939 case IL_ATOMICRMWA:
13940 case IL_ATOMICRMWSP:
13941 case IL_ATOMICRMWDP:
13942 case IL_ATOMICSTI:
13943 case IL_ATOMICSTKR:
13944 case IL_ATOMICSTA:
13945 case IL_ATOMICSTSP:
13946 case IL_ATOMICSTDP:
13947 return 4;
13948 case IL_ATOMICLDI:
13949 case IL_ATOMICLDKR:
13950 case IL_ATOMICLDA:
13951 case IL_ATOMICLDSP:
13952 case IL_ATOMICLDDP:
13953 return 3;
13954 case IL_FENCE:
13955 return 1;
13956 }
13957 }
13958
13959 /** Get ATOMIC_INFO associated with a given ILI instruction */
13960 ATOMIC_INFO
atomic_info(int ilix)13961 atomic_info(int ilix)
13962 {
13963 return atomic_decode(ILI_OPND(ilix, atomic_info_index(ILI_OPC(ilix))));
13964 }
13965
13966 /** Return value of irlnk operand if its value is known, otherwise return
13967 * default_value. */
13968 static INT
value_of_irlnk_operand(int ilix,int default_value)13969 value_of_irlnk_operand(int ilix, int default_value)
13970 {
13971 ILI_OP opc = ILI_OPC(ilix);
13972 DEBUG_ASSERT(IL_RES(opc) == ILIA_IR, "irlnk expected");
13973 if (opc == IL_ICON) {
13974 INT value = CONVAL2G(ILI_OPND(ilix, 1));
13975 return value;
13976 }
13977 return default_value;
13978 }
13979
13980 /** Given an ILI expression for a memory order, return a MEMORY_ORDER
13981 at least as strong as what the expression specifies. */
13982 static MEMORY_ORDER
memory_order_from_operand(int ilix)13983 memory_order_from_operand(int ilix)
13984 {
13985 INT k = value_of_irlnk_operand(ilix, MO_SEQ_CST);
13986 if ((unsigned)k <= MO_MAX_DEF)
13987 return (MEMORY_ORDER)k;
13988 /* Behavior is undefined. Be conservative and return strongest ordering. */
13989 return MO_SEQ_CST;
13990 }
13991
13992 /**
13993 \brief add ili for CMPXCHGx
13994
13995 Actually two ilis are created, one for the CMPXCHGx and a CMPXCHG_DST to hold
13996 the operands that won't fit.
13997
13998 \param opc an IL_CMPXCHGx opcode
13999 \param ilix_val ILI expression for value to be stored if operation succeeds
14000 \param ilix_loc ILI address expression for location to be updated.
14001 \param nme NME for destination.
14002 \param stc_atomic_info information packed by routine atomic_encode.
14003 \param ilix_comparand value to compare against
14004 \param ilix_is_weak if 1 then operation is allowed to spuriously fail
14005 occasionally.
14006 Should be 0 otherwise.
14007 \param ilix_success ILI expression for memory order on success
14008 \param ilix_failure ILI expression for memory order on failure
14009
14010 */
14011 int
ad_cmpxchg(ILI_OP opc,int ilix_val,int ilix_loc,int nme,int stc_atomic_info,int ilix_comparand,int ilix_is_weak,int ilix_success,int ilix_failure)14012 ad_cmpxchg(ILI_OP opc, int ilix_val, int ilix_loc, int nme, int stc_atomic_info,
14013 int ilix_comparand, int ilix_is_weak, int ilix_success,
14014 int ilix_failure)
14015 {
14016 int dst;
14017 DEBUG_ASSERT(IL_IS_CMPXCHG(opc), "ad_cmpxchg: opc must be a CMPXCHGx");
14018 dst = ad4ili(IL_CMPXCHG_DST, ilix_loc, ilix_is_weak, ilix_success,
14019 ilix_failure);
14020 return ad5ili(opc, ilix_val, dst, nme, stc_atomic_info, ilix_comparand);
14021 }
14022
14023 /** Get the IL_CMPXCHG_DST instruction underlying a IL_CMPXCHGx instruction. */
14024 static int
get_dst_of_cmpxchg(int ilix)14025 get_dst_of_cmpxchg(int ilix)
14026 {
14027 int iliy;
14028 DEBUG_ASSERT(IL_IS_CMPXCHG(ILI_OPC(ilix)),
14029 "get_dst_of_cmpxchg: not a CMPXCHGx");
14030 iliy = ILI_OPND(ilix, 2);
14031 DEBUG_ASSERT(ILI_OPC(iliy) == IL_CMPXCHG_DST,
14032 "get_dst_of_cmpxchg: IL_CMPXCHG_DST expected");
14033 return iliy;
14034 }
14035
14036 /** For a IL_CMPXCHGx operation, return true if it is allowed to
14037 spuriously fail occcasionally. Returns false when in doubt. */
14038 bool
cmpxchg_is_weak(int ilix)14039 cmpxchg_is_weak(int ilix)
14040 {
14041 int iliy = get_dst_of_cmpxchg(ilix);
14042 return value_of_irlnk_operand(ILI_OPND(iliy, 2), 0) == 0;
14043 }
14044
14045 /** For an IL_CMPXCHGx instruction, return address expression of location. */
14046 int
cmpxchg_loc(int ilix)14047 cmpxchg_loc(int ilix)
14048 {
14049 int iliy = get_dst_of_cmpxchg(ilix);
14050 return ILI_OPND(iliy, 1);
14051 }
14052
14053 /* clang-format off */
14054
14055 /** \brief Table used by cmpxchg_memory_order.
14056
14057 Indexed by [succ][fail], it returns an weakened value for failure
14058 per rules in C++11 standard and LLVM. The weakenings guarantee that
14059 the failure value is no stronger than the succ value and has
14060 no "release" aspect to it.
14061
14062 Element type is char to save space.
14063
14064 this table is also used by accelerator CG, so DON'T make it as static
14065 */
14066 char memory_order_fail_table[MO_MAX_DEF + 1][MO_MAX_DEF + 1] = {
14067 /* succ==relaxed */
14068 {MO_RELAXED, MO_RELAXED, MO_RELAXED, MO_RELAXED, MO_RELAXED, MO_RELAXED},
14069 /* succ==consume */
14070 {MO_RELAXED, MO_CONSUME, MO_CONSUME, MO_RELAXED, MO_CONSUME, MO_CONSUME},
14071 /* succ==acquire */
14072 {MO_RELAXED, MO_CONSUME, MO_ACQUIRE, MO_RELAXED, MO_ACQUIRE, MO_ACQUIRE},
14073 /* succ==release */
14074 {MO_RELAXED, MO_RELAXED, MO_RELAXED, MO_RELAXED, MO_RELAXED, MO_RELAXED},
14075 /* succ==acq_rel */
14076 {MO_RELAXED, MO_CONSUME, MO_ACQUIRE, MO_RELAXED, MO_ACQUIRE, MO_ACQUIRE},
14077 /* succ==seq_cst */
14078 {MO_RELAXED, MO_CONSUME, MO_ACQUIRE, MO_RELAXED, MO_ACQUIRE, MO_SEQ_CST},
14079 };
14080
14081 /* clang-format on */
14082
14083 /** For an IL_CMPXCHGx instruction, return memory orders for
14084 success and failure cases. */
14085 CMPXCHG_MEMORY_ORDER
cmpxchg_memory_order(int ilix)14086 cmpxchg_memory_order(int ilix)
14087 {
14088 CMPXCHG_MEMORY_ORDER result;
14089 MEMORY_ORDER succ, fail;
14090 int dst = get_dst_of_cmpxchg(ilix);
14091 succ = memory_order_from_operand(ILI_OPND(dst, 3));
14092 fail = memory_order_from_operand(ILI_OPND(dst, 4));
14093 DEBUG_ASSERT((unsigned)succ <= (unsigned)MO_MAX_DEF,
14094 "max_memory_order: bad mo1");
14095 DEBUG_ASSERT((unsigned)fail <= (unsigned)MO_MAX_DEF,
14096 "max_memory_order: bad mo2");
14097 result.success = succ;
14098 result.failure = (MEMORY_ORDER)memory_order_fail_table[succ][fail];
14099 return result;
14100 }
14101
14102 /** Get MEMORY_ORDER associated with given ILI instruction.
14103 If the memory order operand is not a constant, require
14104 a conservative bound. If there are different memory
14105 orders for success/failure, return an upper bound.
14106
14107 For IL_CMPXCHGx instructions, the memory order is always
14108 the "success" order, since the "failure" order is not allowed
14109 to be stronger. */
14110 MEMORY_ORDER
memory_order(int ilix)14111 memory_order(int ilix)
14112 {
14113 int i;
14114 ILI_OP opc = ILI_OPC(ilix);
14115 DEBUG_ASSERT(IL_HAS_FENCE(opc), "opc missing fence attribute");
14116 switch (opc) {
14117 default:
14118 assert(false, "memory_order: unimplemented op", opc, ERR_Severe);
14119 case IL_CMPXCHGI:
14120 case IL_CMPXCHGKR:
14121 case IL_CMPXCHGA: {
14122 /** The "failure" order cannot be stronger than the "success" order,
14123 so return the success order. */
14124 int dst = get_dst_of_cmpxchg(ilix);
14125 return memory_order_from_operand(ILI_OPND(dst, 3));
14126 }
14127 case IL_ATOMICRMWI:
14128 case IL_ATOMICRMWKR:
14129 case IL_ATOMICRMWA:
14130 case IL_ATOMICRMWSP:
14131 case IL_ATOMICRMWDP:
14132 case IL_ATOMICSTI:
14133 case IL_ATOMICSTKR:
14134 case IL_ATOMICSTA:
14135 case IL_ATOMICSTSP:
14136 case IL_ATOMICSTDP:
14137 i = 5;
14138 break;
14139 case IL_ATOMICLDI:
14140 case IL_ATOMICLDKR:
14141 case IL_ATOMICLDA:
14142 case IL_ATOMICLDSP:
14143 case IL_ATOMICLDDP:
14144 i = 4;
14145 break;
14146 case IL_FENCE:
14147 i = 2;
14148 break;
14149 }
14150 return memory_order_from_operand(ILI_OPND(ilix, i));
14151 }
14152
14153 bool
is_omp_atomic_ld(int ilix)14154 is_omp_atomic_ld(int ilix)
14155 {
14156 ATOMIC_INFO info;
14157 switch (ILI_OPC(ilix)) {
14158 case IL_ATOMICLDI:
14159 case IL_ATOMICLDKR:
14160 case IL_ATOMICLDA:
14161 case IL_ATOMICLDSP:
14162 case IL_ATOMICLDDP:
14163 break;
14164 default:
14165 return false;
14166 }
14167 info = atomic_info(ilix);
14168
14169 if (info.origin == AORG_OPENMP)
14170 return true;
14171 return false;
14172 }
14173
14174 bool
is_omp_atomic_st(int ilix)14175 is_omp_atomic_st(int ilix)
14176 {
14177 ATOMIC_INFO info;
14178 switch (ILI_OPC(ilix)) {
14179 case IL_ATOMICSTI:
14180 case IL_ATOMICSTKR:
14181 case IL_ATOMICSTA:
14182 case IL_ATOMICSTSP:
14183 case IL_ATOMICSTDP:
14184 break;
14185 default:
14186 return false;
14187 }
14188 info = atomic_info(ilix);
14189
14190 if (info.origin == AORG_OPENMP)
14191 return true;
14192 return false;
14193 }
14194
14195 /*
14196 * a set of functions to create integer expressions,
14197 * that automatically detect long (KR) operands and adjust appropriately
14198 * if an ilix index is zero, treat it as a missing operand
14199 */
14200
14201 static int
ivconst(ISZ_T valconst)14202 ivconst(ISZ_T valconst)
14203 {
14204 ISZ_T valbig, valhigh;
14205 int ilix;
14206 valbig = 0xffffffff00000000LL;
14207 valhigh = valbig & valconst; /* high order bits */
14208 if (valhigh == 0 || valhigh == valbig) {
14209 ilix = ad_icon(valconst);
14210 } else {
14211 ilix = ad_kconi(valconst);
14212 }
14213 return ilix;
14214 } /* ivconst */
14215
14216 /*
14217 * imul_const_ili(con, ilix), detect when con == 0 or con == 1
14218 * return 0 if the value would be the constant zero
14219 * if ilix==0, return the constant, either as a 4- or 8-byte int
14220 */
14221 int
imul_const_ili(ISZ_T valconst,int valilix)14222 imul_const_ili(ISZ_T valconst, int valilix)
14223 {
14224 int ilix;
14225 if (valconst == 0)
14226 return 0;
14227 if (valconst == 1)
14228 return valilix;
14229 if (valilix == 0) {
14230 ilix = ivconst(valconst);
14231 } else if (IL_RES(ILI_OPC(valilix)) == ILIA_KR) {
14232 ilix = ad_kconi(valconst);
14233 ilix = ad2ili(IL_KMUL, ilix, valilix);
14234 } else {
14235 ilix = ad_icon(valconst);
14236 ilix = ad2ili(IL_IMUL, ilix, valilix);
14237 }
14238 return ilix;
14239 } /* imul_const_ili */
14240
14241 int
imul_ili_ili(int leftx,int rightx)14242 imul_ili_ili(int leftx, int rightx)
14243 {
14244 int ilix;
14245 if (IL_RES(ILI_OPC(leftx)) == ILIA_KR || IL_RES(ILI_OPC(rightx)) == ILIA_KR) {
14246 ilix = ad2ili(IL_KMUL, ikmove(leftx), ikmove(rightx));
14247 } else {
14248 ilix = ad2ili(IL_IMUL, leftx, rightx);
14249 }
14250 return ilix;
14251 } /* imul_ili_ili */
14252
14253 /*
14254 * if valilix==0, return valconst
14255 */
14256 int
iadd_const_ili(ISZ_T valconst,int valilix)14257 iadd_const_ili(ISZ_T valconst, int valilix)
14258 {
14259 int ilix;
14260 if (valconst == 0)
14261 return valilix;
14262 if (valilix == 0) {
14263 ilix = ivconst(valconst);
14264 }
14265 if (IL_RES(ILI_OPC(valilix)) == ILIA_KR) {
14266 if (!valilix) {
14267 ilix = ad_kconi(valconst);
14268 } else if (valconst > 0) {
14269 ilix = ad_kconi(valconst);
14270 ilix = ad2ili(IL_KADD, ilix, valilix);
14271 } else {
14272 ilix = ad_kconi(-valconst);
14273 ilix = ad2ili(IL_KSUB, valilix, ilix);
14274 }
14275 } else {
14276 if (!valilix) {
14277 ilix = ad_icon(valconst);
14278 } else if (valconst > 0) {
14279 ilix = ad_icon(valconst);
14280 ilix = ad2ili(IL_IADD, ilix, valilix);
14281 } else {
14282 /* -c + i ==> i-c */
14283 ilix = ad_icon(-valconst);
14284 ilix = ad2ili(IL_ISUB, valilix, ilix);
14285 }
14286 }
14287 return ilix;
14288 } /* iadd_const_ili */
14289
14290 int
iadd_ili_ili(int leftx,int rightx)14291 iadd_ili_ili(int leftx, int rightx)
14292 {
14293 int ilix;
14294 if (leftx < 0 || rightx < 0)
14295 interr("iadd_ili_ili argument error", 0, ERR_Fatal);
14296 if (leftx == 0)
14297 return rightx;
14298 if (rightx == 0)
14299 return leftx;
14300 if (IL_RES(ILI_OPC(leftx)) == IL_RES(ILI_OPC(rightx))) {
14301 /* both KR or both IR */
14302 /* look for trivial simplifications */
14303 if (ILI_OPC(rightx) == IL_KNEG || ILI_OPC(rightx) == IL_INEG) {
14304 /* a + (-b) */
14305 return isub_ili_ili(leftx, ILI_OPND(rightx, 1));
14306 }
14307 if (ILI_OPC(leftx) == IL_KNEG || ILI_OPC(leftx) == IL_INEG) {
14308 /* (-a) + b */
14309 return isub_ili_ili(rightx, ILI_OPND(leftx, 1));
14310 }
14311 if (ILI_OPC(leftx) == IL_KSUB || ILI_OPC(leftx) == IL_ISUB ||
14312 ILI_OPC(leftx) == IL_UKSUB || ILI_OPC(leftx) == IL_UISUB) {
14313 if (ILI_OPND(leftx, 2) == rightx) {
14314 /* (a-b) + b */
14315 return ILI_OPND(leftx, 1);
14316 }
14317 }
14318 if (ILI_OPC(rightx) == IL_KSUB || ILI_OPC(rightx) == IL_ISUB ||
14319 ILI_OPC(rightx) == IL_UKSUB || ILI_OPC(rightx) == IL_UISUB) {
14320 if (ILI_OPND(rightx, 2) == rightx) {
14321 /* b + (a-b) */
14322 return ILI_OPND(rightx, 1);
14323 }
14324 }
14325 if (IL_RES(ILI_OPC(leftx)) == ILIA_KR) {
14326 ilix = ad2ili(IL_KADD, leftx, rightx);
14327 } else {
14328 ilix = ad2ili(IL_IADD, leftx, rightx);
14329 }
14330 } else {
14331 /* either one KR, move to KR */
14332 ilix = ad2ili(IL_KADD, ikmove(leftx), ikmove(rightx));
14333 }
14334 return ilix;
14335 } /* iadd_ili_ili */
14336
14337 int
isub_ili_ili(int leftx,int rightx)14338 isub_ili_ili(int leftx, int rightx)
14339 {
14340 int ilix;
14341 if (leftx < 0 || rightx < 0)
14342 interr("isub_ili_ili argument error", 0, ERR_Fatal);
14343 if (rightx == 0)
14344 return leftx;
14345 if (leftx == 0) {
14346 /* negate */
14347 if (ILI_OPC(rightx) == IL_KNEG || ILI_OPC(rightx) == IL_INEG)
14348 return ILI_OPND(rightx, 1);
14349 if (IL_RES(ILI_OPC(rightx)) == ILIA_KR) {
14350 return ad1ili(IL_KNEG, rightx);
14351 } else {
14352 return ad1ili(IL_INEG, rightx);
14353 }
14354 }
14355 if (leftx == rightx)
14356 /* a - b */
14357 return 0;
14358 if (IL_RES(ILI_OPC(leftx)) == IL_RES(ILI_OPC(rightx))) {
14359 /* look for trivial simplifications */
14360 if (ILI_OPC(rightx) == IL_KNEG || ILI_OPC(rightx) == IL_INEG) {
14361 /* a - (-b) */
14362 return iadd_ili_ili(leftx, ILI_OPND(rightx, 1));
14363 }
14364 if (ILI_OPC(leftx) == IL_KADD || ILI_OPC(leftx) == IL_IADD ||
14365 ILI_OPC(leftx) == IL_UKADD || ILI_OPC(leftx) == IL_UIADD) {
14366 if (ILI_OPND(leftx, 2) == rightx) {
14367 /* (a+b) - b */
14368 return ILI_OPND(leftx, 1);
14369 }
14370 if (ILI_OPND(leftx, 1) == rightx) {
14371 /* (a+b) - a */
14372 return ILI_OPND(leftx, 2);
14373 }
14374 }
14375 if (ILI_OPC(leftx) == IL_KSUB || ILI_OPC(leftx) == IL_ISUB ||
14376 ILI_OPC(leftx) == IL_UKSUB || ILI_OPC(leftx) == IL_UISUB) {
14377 if (ILI_OPND(leftx, 1) == rightx) {
14378 /* (a-b) - a */
14379 return isub_ili_ili(0, ILI_OPND(leftx, 2));
14380 }
14381 }
14382 if (ILI_OPC(rightx) == IL_KADD || ILI_OPC(rightx) == IL_IADD ||
14383 ILI_OPC(rightx) == IL_UKADD || ILI_OPC(rightx) == IL_UIADD) {
14384 if (ILI_OPND(rightx, 1) == leftx) {
14385 /* a - (a+b) */
14386 return isub_ili_ili(0, ILI_OPND(rightx, 2));
14387 }
14388 if (ILI_OPND(rightx, 2) == leftx) {
14389 /* a - (b+a) */
14390 return isub_ili_ili(0, ILI_OPND(rightx, 1));
14391 }
14392 }
14393 if (ILI_OPC(rightx) == IL_KSUB || ILI_OPC(rightx) == IL_ISUB ||
14394 ILI_OPC(rightx) == IL_UKSUB || ILI_OPC(rightx) == IL_UISUB) {
14395 if (ILI_OPND(rightx, 1) == leftx) {
14396 /* a - (a-b) */
14397 return ILI_OPND(rightx, 2);
14398 }
14399 }
14400 if (IL_RES(ILI_OPC(leftx)) == ILIA_KR) {
14401 ilix = ad2ili(IL_KSUB, leftx, rightx);
14402 } else {
14403 ilix = ad2ili(IL_ISUB, leftx, rightx);
14404 }
14405 } else {
14406 /* either one KR, move both to KR */
14407 ilix = ad2ili(IL_KSUB, ikmove(leftx), ikmove(rightx));
14408 }
14409 return ilix;
14410 } /* isub_ili_ili */
14411
14412 /*
14413 * ilix / const
14414 */
14415 int
idiv_ili_const(int valilix,ISZ_T valconst)14416 idiv_ili_const(int valilix, ISZ_T valconst)
14417 {
14418 int ilix;
14419 if (valconst == 1)
14420 return valilix;
14421 if (valilix < 0)
14422 interr("div_ili_const argument error", 0, ERR_Fatal);
14423 if (valconst == -1)
14424 return isub_ili_ili(0, valilix);
14425 if (IL_RES(ILI_OPC(valilix)) == ILIA_KR) {
14426 ilix = ad_kconi(valconst);
14427 ilix = ad2ili(IL_KDIV, valilix, ilix);
14428 } else {
14429 ilix = ad_icon(valconst);
14430 ilix = ad2ili(IL_IDIV, valilix, ilix);
14431 }
14432 return ilix;
14433 } /* idiv_ili_const */
14434
14435 int
idiv_ili_ili(int leftx,int rightx)14436 idiv_ili_ili(int leftx, int rightx)
14437 {
14438 int ilix;
14439 if (leftx < 0 || rightx < 0)
14440 interr("div_ili_ili argument error", 0, ERR_Fatal);
14441 if (IL_RES(ILI_OPC(leftx)) == ILIA_KR || IL_RES(ILI_OPC(rightx)) == ILIA_KR) {
14442 ilix = ad2ili(IL_KDIV, ikmove(leftx), ikmove(rightx));
14443 } else {
14444 ilix = ad2ili(IL_IDIV, leftx, rightx);
14445 }
14446 return ilix;
14447 } /* idiv_ili_ili */
14448
14449 int
imax_ili_ili(int leftx,int rightx)14450 imax_ili_ili(int leftx, int rightx)
14451 {
14452 int ilix;
14453 if (leftx < 0 || rightx < 0)
14454 interr("max_ili_ili argument error", 0, ERR_Fatal);
14455 if (IL_RES(ILI_OPC(leftx)) == ILIA_KR || IL_RES(ILI_OPC(rightx)) == ILIA_KR) {
14456 ilix = ad2ili(IL_KMAX, ikmove(leftx), ikmove(rightx));
14457 } else {
14458 ilix = ad2ili(IL_IMAX, leftx, rightx);
14459 }
14460 return ilix;
14461 } /* imax_ili_ili */
14462
14463 int
imin_ili_ili(int leftx,int rightx)14464 imin_ili_ili(int leftx, int rightx)
14465 {
14466 int ilix;
14467 if (leftx < 0 || rightx < 0)
14468 interr("min_ili_ili argument error", 0, ERR_Fatal);
14469 if (IL_RES(ILI_OPC(leftx)) == ILIA_KR || IL_RES(ILI_OPC(rightx)) == ILIA_KR) {
14470 ilix = ad2ili(IL_KMIN, ikmove(leftx), ikmove(rightx));
14471 } else {
14472 ilix = ad2ili(IL_IMIN, leftx, rightx);
14473 }
14474 return ilix;
14475 } /* imin_ili_ili */
14476
14477