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 }