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 }