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