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