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