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