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