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