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