1 /*
2 * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 import jdk.incubator.code.Op;
25 import jdk.incubator.code.dialect.core.FunctionType;
26 import jdk.incubator.code.dialect.java.JavaOp;
27 import jdk.incubator.code.dialect.java.MethodRef;
28 import jdk.incubator.code.extern.ExternalizedOp;
29
30 import java.lang.invoke.MethodHandle;
31 import java.lang.invoke.MethodHandles;
32 import java.lang.invoke.MethodType;
33 import java.util.List;
34
35 // This a copy of jdk.incubator.code.internal.ArithmeticAndConvOpImpls, plus methods for converting from boolean to other primitive types
36 // the additional methods are used by the TestBytecodeLift
37 public final class ArithmeticAndConvOpImpls {
38 public static boolean eq(Object a, Object b) {
39 return a == b;
40 }
41
42 public static boolean neq(Object a, Object b) {
43 return a != b;
44 }
45
46
47 public static boolean not(boolean l) {
48 return !l;
49 }
50
51 // int
52
53 public static int neg(int l) {
54 return -l;
55 }
56
57 public static int compl(int l) {
58 return ~l;
59 }
60
61 public static int add(int l, int r) {
62 return l + r;
63 }
64
65 public static int sub(int l, int r) {
66 return l - r;
67 }
68
69 public static int mul(int l, int r) {
70 return l * r;
71 }
72
73 public static int div(int l, int r) {
74 return l / r;
75 }
76
77 public static int mod(int l, int r) {
78 return l % r;
79 }
80
81 public static int or(int l, int r) {
82 return l | r;
83 }
84
85 public static int and(int l, int r) {
86 return l & r;
87 }
88
89 public static int xor(int l, int r) {
90 return l ^ r;
91 }
92
93 public static int lshl(int l, int r) {
94 return l << r;
95 }
96
97 public static int ashr(int l, int r) {
98 return l >> r;
99 }
100
101 public static int lshr(int l, int r) {
102 return l >>> r;
103 }
104
105 public static int lshl(int l, long r) {
106 return l << r;
107 }
108
109 public static int ashr(int l, long r) {
110 return l >> r;
111 }
112
113 public static int lshr(int l, long r) {
114 return l >>> r;
115 }
116
117 public static boolean eq(int l, int r) {
118 return l == r;
119 }
120
121 public static boolean neq(int l, int r) {
122 return l != r;
123 }
124
125 public static boolean gt(int l, int r) {
126 return l > r;
127 }
128
129 public static boolean ge(int l, int r) {
130 return l >= r;
131 }
132
133 public static boolean lt(int l, int r) {
134 return l < r;
135 }
136
137 public static boolean le(int l, int r) {
138 return l <= r;
139 }
140
141 // byte
142
143 public static byte neg(byte l) {
144 return (byte) -l;
145 }
146
147 public static byte compl(byte l) {
148 return (byte) ~l;
149 }
150
151 public static byte add(byte l, byte r) {
152 return (byte) (l + r);
153 }
154
155 public static byte sub(byte l, byte r) {
156 return (byte) (l - r);
157 }
158
159 public static byte mul(byte l, byte r) {
160 return (byte) (l * r);
161 }
162
163 public static byte div(byte l, byte r) {
164 return (byte) (l / r);
165 }
166
167 public static byte mod(byte l, byte r) {
168 return (byte) (l % r);
169 }
170
171 public static byte or(byte l, byte r) {
172 return (byte) (l | r);
173 }
174
175 public static byte and(byte l, byte r) {
176 return (byte) (l & r);
177 }
178
179 public static byte xor(byte l, byte r) {
180 return (byte) (l ^ r);
181 }
182
183 public static byte ashr(byte l, long r) {
184 return (byte) (l >> r);
185 }
186
187 public static byte lshr(byte l, long r) {
188 return (byte) (l >>> r);
189 }
190
191 public static byte lshl(byte l, int r) {
192 return (byte) (l << r);
193 }
194
195 public static byte ashr(byte l, int r) {
196 return (byte) (l >> r);
197 }
198
199 public static byte lshr(byte l, int r) {
200 return (byte) (l >>> r);
201 }
202
203 public static boolean eq(byte l, byte r) {
204 return l == r;
205 }
206
207 public static boolean neq(byte l, byte r) {
208 return l != r;
209 }
210
211 public static boolean gt(byte l, byte r) {
212 return l > r;
213 }
214
215 public static boolean ge(byte l, byte r) {
216 return l >= r;
217 }
218
219 public static boolean lt(byte l, byte r) {
220 return l < r;
221 }
222
223 public static boolean le(byte l, byte r) {
224 return l <= r;
225 }
226
227 // short
228
229 public static short neg(short l) {
230 return (short) -l;
231 }
232
233 public static short compl(short l) {
234 return (short) ~l;
235 }
236
237 public static short add(short l, short r) {
238 return (short) (l + r);
239 }
240
241 public static short sub(short l, short r) {
242 return (short) (l - r);
243 }
244
245 public static short mul(short l, short r) {
246 return (short) (l * r);
247 }
248
249 public static short div(short l, short r) {
250 return (short) (l / r);
251 }
252
253 public static short mod(short l, short r) {
254 return (short) (l % r);
255 }
256
257 public static short or(short l, short r) {
258 return (short) (l | r);
259 }
260
261 public static short and(short l, short r) {
262 return (short) (l & r);
263 }
264
265 public static short xor(short l, short r) {
266 return (short) (l ^ r);
267 }
268
269 public static short ashr(short l, long r) {
270 return (short) (l >> r);
271 }
272
273 public static short lshr(short l, long r) {
274 return (short) (l >>> r);
275 }
276
277 public static short lshl(short l, int r) {
278 return (short) (l << r);
279 }
280
281 public static short ashr(short l, int r) {
282 return (short) (l >> r);
283 }
284
285 public static short lshr(short l, int r) {
286 return (short) (l >>> r);
287 }
288
289 public static boolean eq(short l, short r) {
290 return l == r;
291 }
292
293 public static boolean neq(short l, short r) {
294 return l != r;
295 }
296
297 public static boolean gt(short l, short r) {
298 return l > r;
299 }
300
301 public static boolean ge(short l, short r) {
302 return l >= r;
303 }
304
305 public static boolean lt(short l, short r) {
306 return l < r;
307 }
308
309 public static boolean le(short l, short r) {
310 return l <= r;
311 }
312
313 // char
314
315 public static char neg(char l) {
316 return (char) -l;
317 }
318
319 public static char compl(char l) {
320 return (char) ~l;
321 }
322
323 public static char add(char l, char r) {
324 return (char) (l + r);
325 }
326
327 public static char sub(char l, char r) {
328 return (char) (l - r);
329 }
330
331 public static char mul(char l, char r) {
332 return (char) (l * r);
333 }
334
335 public static char div(char l, char r) {
336 return (char) (l / r);
337 }
338
339 public static char mod(char l, char r) {
340 return (char) (l % r);
341 }
342
343 public static char or(char l, char r) {
344 return (char) (l | r);
345 }
346
347 public static char and(char l, char r) {
348 return (char) (l & r);
349 }
350
351 public static char xor(char l, char r) {
352 return (char) (l ^ r);
353 }
354
355 public static char ashr(char l, long r) {
356 return (char) (l >> r);
357 }
358
359 public static char lshr(char l, long r) {
360 return (char) (l >>> r);
361 }
362
363 public static char lshl(char l, int r) {
364 return (char) (l << r);
365 }
366
367 public static char ashr(char l, int r) {
368 return (char) (l >> r);
369 }
370
371 public static char lshr(char l, int r) {
372 return (char) (l >>> r);
373 }
374
375 public static boolean eq(char l, char r) {
376 return l == r;
377 }
378
379 public static boolean neq(char l, char r) {
380 return l != r;
381 }
382
383 public static boolean gt(char l, char r) {
384 return l > r;
385 }
386
387 public static boolean ge(char l, char r) {
388 return l >= r;
389 }
390
391 public static boolean lt(char l, char r) {
392 return l < r;
393 }
394
395 public static boolean le(char l, char r) {
396 return l <= r;
397 }
398 // long
399
400 public static long neg(long l) {
401 return -l;
402 }
403
404 public static long compl(long l) {
405 return ~l;
406 }
407
408 public static long add(long l, long r) {
409 return l + r;
410 }
411
412 public static long sub(long l, long r) {
413 return l - r;
414 }
415
416 public static long mul(long l, long r) {
417 return l * r;
418 }
419
420 public static long div(long l, long r) {
421 return l / r;
422 }
423
424 public static long mod(long l, long r) {
425 return l % r;
426 }
427
428 public static long or(long l, long r) {
429 return l | r;
430 }
431
432 public static long and(long l, long r) {
433 return l & r;
434 }
435
436 public static long xor(long l, long r) {
437 return l ^ r;
438 }
439
440 public static long lshl(long l, long r) {
441 return l << r;
442 }
443
444 public static long ashr(long l, long r) {
445 return l >> r;
446 }
447
448 public static long lshr(long l, long r) {
449 return l >>> r;
450 }
451
452 public static long lshl(long l, int r) {
453 return l << r;
454 }
455
456 public static long ashr(long l, int r) {
457 return l >> r;
458 }
459
460 public static long lshr(long l, int r) {
461 return l >>> r;
462 }
463
464 public static boolean eq(long l, long r) {
465 return l == r;
466 }
467
468 public static boolean neq(long l, long r) {
469 return l != r;
470 }
471
472 public static boolean gt(long l, long r) {
473 return l > r;
474 }
475
476 public static boolean ge(long l, long r) {
477 return l >= r;
478 }
479
480 public static boolean lt(long l, long r) {
481 return l < r;
482 }
483
484 public static boolean le(long l, long r) {
485 return l <= r;
486 }
487
488
489
490 // float
491
492 public static float neg(float l) {
493 return -l;
494 }
495
496 public static float add(float l, float r) {
497 return l + r;
498 }
499
500 public static float sub(float l, float r) {
501 return l - r;
502 }
503
504 public static float mul(float l, float r) {
505 return l * r;
506 }
507
508 public static float div(float l, float r) {
509 return l / r;
510 }
511
512 public static float mod(float l, float r) {
513 return l % r;
514 }
515
516 public static boolean eq(float l, float r) {
517 return l == r;
518 }
519
520 public static boolean neq(float l, float r) {
521 return l != r;
522 }
523
524 public static boolean gt(float l, float r) {
525 return l > r;
526 }
527
528 public static boolean ge(float l, float r) {
529 return l >= r;
530 }
531
532 public static boolean lt(float l, float r) {
533 return l < r;
534 }
535
536 public static boolean le(float l, float r) {
537 return l <= r;
538 }
539
540
541
542 // double
543
544 public static double neg(double l) {
545 return -l;
546 }
547
548 public static double add(double l, double r) {
549 return l + r;
550 }
551
552 public static double sub(double l, double r) {
553 return l - r;
554 }
555
556 public static double mul(double l, double r) {
557 return l * r;
558 }
559
560 public static double div(double l, double r) {
561 return l / r;
562 }
563
564 public static double mod(double l, double r) {
565 return l % r;
566 }
567
568 public static boolean eq(double l, double r) {
569 return l == r;
570 }
571
572 public static boolean neq(double l, double r) {
573 return l != r;
574 }
575
576 public static boolean gt(double l, double r) {
577 return l > r;
578 }
579
580 public static boolean ge(double l, double r) {
581 return l >= r;
582 }
583
584 public static boolean lt(double l, double r) {
585 return l < r;
586 }
587
588 public static boolean le(double l, double r) {
589 return l <= r;
590 }
591
592
593 // boolean
594
595 public static boolean eq(boolean l, boolean r) {
596 return l == r;
597 }
598
599 public static boolean neq(boolean l, boolean r) {
600 return l != r;
601 }
602
603 public static boolean and(boolean l, boolean r) {
604 return l & r;
605 }
606
607 public static boolean or(boolean l, boolean r) {
608 return l | r;
609 }
610
611 public static boolean xor(boolean l, boolean r) {
612 return l ^ r;
613 }
614
615
616 // Primitive conversions
617
618 // double conversion
619 public static double conv_double(double i) {
620 return i;
621 }
622 public static float conv_float(double i) {
623 return (float) i;
624 }
625 public static long conv_long(double i) {
626 return (long) i;
627 }
628 public static int conv_int(double i) {
629 return (int) i;
630 }
631 public static short conv_short(double i) {
632 return (short) i;
633 }
634 public static char conv_char(double i) {
635 return (char) i;
636 }
637 public static byte conv_byte(double i) {
638 return (byte) i;
639 }
640 public static boolean conv_boolean(double i) {
641 return ((int)i & 1) == 1;
642 }
643
644 // float conversion
645 public static double conv_double(float i) {
646 return i;
647 }
648 public static float conv_float(float i) {
649 return i;
650 }
651 public static long conv_long(float i) {
652 return (long) i;
653 }
654 public static int conv_int(float i) {
655 return (int) i;
656 }
657 public static short conv_short(float i) {
658 return (short) i;
659 }
660 public static char conv_char(float i) {
661 return (char) i;
662 }
663 public static byte conv_byte(float i) {
664 return (byte) i;
665 }
666 public static boolean conv_boolean(float i) {
667 return ((int)i & 1) == 1;
668 }
669
670 // long conversion
671 public static double conv_double(long i) {
672 return (double) i;
673 }
674 public static float conv_float(long i) {
675 return (float) i;
676 }
677 public static long conv_long(long i) {
678 return i;
679 }
680 public static int conv_int(long i) {
681 return (int) i;
682 }
683 public static short conv_short(long i) {
684 return (short) i;
685 }
686 public static char conv_char(long i) {
687 return (char) i;
688 }
689 public static byte conv_byte(long i) {
690 return (byte) i;
691 }
692 public static boolean conv_boolean(long i) {
693 return (i & 1) == 1;
694 }
695
696 // int conversion
697 public static double conv_double(int i) {
698 return (double) i;
699 }
700 public static float conv_float(int i) {
701 return (float) i;
702 }
703 public static long conv_long(int i) {
704 return i;
705 }
706 public static int conv_int(int i) {
707 return i;
708 }
709 public static short conv_short(int i) {
710 return (short) i;
711 }
712 public static char conv_char(int i) {
713 return (char) i;
714 }
715 public static byte conv_byte(int i) {
716 return (byte) i;
717 }
718 public static boolean conv_boolean(int i) {
719 return (i & 1) == 1;
720 }
721
722 // short conversion
723 public static double conv_double(short i) {
724 return i;
725 }
726 public static float conv_float(short i) {
727 return i;
728 }
729 public static long conv_long(short i) {
730 return i;
731 }
732 public static int conv_int(short i) {
733 return i;
734 }
735 public static short conv_short(short i) {
736 return i;
737 }
738 public static char conv_char(short i) {
739 return (char) i;
740 }
741 public static byte conv_byte(short i) {
742 return (byte) i;
743 }
744 public static boolean conv_boolean(short i) {
745 return (i & 1) == 1;
746 }
747
748 // char conversion
749 public static double conv_double(char i) {
750 return i;
751 }
752 public static float conv_float(char i) {
753 return i;
754 }
755 public static long conv_long(char i) {
756 return i;
757 }
758 public static int conv_int(char i) {
759 return i;
760 }
761 public static short conv_short(char i) {
762 return (short) i;
763 }
764 public static char conv_char(char i) {
765 return i;
766 }
767 public static byte conv_byte(char i) {
768 return (byte) i;
769 }
770 public static boolean conv_boolean(char i) {
771 return (i & 1) == 1;
772 }
773
774 // byte conversion
775 public static double conv_double(byte i) {
776 return i;
777 }
778 public static float conv_float(byte i) {
779 return i;
780 }
781 public static long conv_long(byte i) {
782 return i;
783 }
784 public static int conv_int(byte i) {
785 return i;
786 }
787 public static short conv_short(byte i) {
788 return i;
789 }
790 public static char conv_char(byte i) {
791 return (char) i;
792 }
793 public static byte conv_byte(byte i) {
794 return i;
795 }
796 public static boolean conv_boolean(byte i) {
797 return (i & 1) == 1;
798 }
799
800 // boolean conversion
801 public static double conv_double(boolean i) {
802 return i ? 1d : 0d;
803 }
804 public static float conv_float(boolean i) {
805 return i ? 1f : 0f;
806 }
807 public static long conv_long(boolean i) {
808 return i ? 1l : 0l;
809 }
810 public static int conv_int(boolean i) {
811 return i ? 1 : 0;
812 }
813 public static short conv_short(boolean i) {
814 return i ? (short)1 : 0;
815 }
816 public static char conv_char(boolean i) {
817 return i ? (char)1 : 0;
818 }
819 public static byte conv_byte(boolean i) {
820 return i ? (byte)1 : 0;
821 }
822 public static boolean conv_boolean(boolean i) {
823 return i;
824 }
825
826 // resolution
827 private static MethodType resolveToMethodType(FunctionType ft) {
828 try {
829 return MethodRef.toNominalDescriptor(ft).resolveConstantDesc(MethodHandles.publicLookup());
830 } catch (ReflectiveOperationException e) {
831 return null;
832 }
833 }
834
835 private static MethodHandle opHandle(String methodName, FunctionType ft) {
836 MethodType mt = resolveToMethodType(ft);
837 if (mt == null) return null;
838 mt = mt.erase();
839 try {
840 return MethodHandles.lookup().findStatic(ArithmeticAndConvOpImpls.class, methodName, mt);
841 } catch (NoSuchMethodException e) {
842 return null;
843 } catch (IllegalAccessException e) {
844 throw new InternalError("Should not reach here");
845 }
846 }
847
848 public static Object evaluate(Op op, List<Object> evaluatedOperands) throws NonConstantExpression {
849 String mn = (op instanceof ExternalizedOp.Externalizable eop)
850 ? eop.externalizeOpName()
851 : op.getClass().getName();
852 if (op instanceof JavaOp.ConvOp) {
853 mn = mn + "_" + op.resultType();
854 }
855 MethodHandle mh = opHandle(mn, op.opSignature());
856 if (mh == null) {
857 throw new NonConstantExpression();
858 }
859 try {
860 return mh.invokeWithArguments(evaluatedOperands);
861 } catch (Throwable e) {
862 throw new InternalError("Should not reach here", e);
863 }
864 }
865
866 @SuppressWarnings("serial")
867 public static class NonConstantExpression extends RuntimeException {
868 public NonConstantExpression() {}
869 }
870 }