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