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