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