1 /* jit/parse.c *****************************************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Parser for JavaVM to intermediate code translation
9 Author: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
11 Last Change: $Id: parse.c 467 2003-09-26 01:55:25Z didi $
12 include Rapid Type Analysis parse - 5/2003 - carolyn
15 *******************************************************************************/
18 /* data about the currently parsed method */
20 static classinfo *rt_class; /* class the compiled method belongs to */
21 static methodinfo *rt_method; /* pointer to method info of compiled method */
22 static utf *rt_descriptor; /* type descriptor of compiled method */
23 static int rt_jcodelength; /*length of JavaVM-codes */
24 static u1 *rt_jcode; /* pointer to start of JavaVM-code */
27 /* macros for byte code fetching ***********************************************
29 fetch a byte code of given size from position p in code array jcode
31 *******************************************************************************/
33 #define code_get_u1(p) jcode[p]
34 #define code_get_s1(p) ((s1)jcode[p])
35 #define code_get_u2(p) ((((u2)jcode[p])<<8)+jcode[p+1])
36 #define code_get_s2(p) ((s2)((((u2)jcode[p])<<8)+jcode[p+1]))
37 #define code_get_u4(p) ((((u4)jcode[p])<<24)+(((u4)jcode[p+1])<<16)\
38 +(((u4)jcode[p+2])<<8)+jcode[p+3])
39 #define code_get_s4(p) ((s4)((((u4)jcode[p])<<24)+(((u4)jcode[p+1])<<16)\
40 +(((u4)jcode[p+2])<<8)+jcode[p+3]))
46 //#define debug_writebranch printf("op: %s i: %d label_index[i]: %d\n",icmd_names[opcode], i, label_index[i]);
47 #define debug_writebranch
49 /* functionc compiler_addinitclass *********************************************
51 add class into the list of classes to initialize
53 *******************************************************************************/
55 static void compiler_addinitclass (classinfo *c)
59 if (c->initialized) return;
61 cl = chain_first(uninitializedclasses);
66 cl = chain_next(uninitializedclasses);
72 sprintf(logtext, "compiler_addinitclass: ");
73 utf_sprint(logtext+strlen(logtext), c->name);
76 chain_addlast(uninitializedclasses, c);
81 sprintf(logtext, "compiler_addinitclass: ");
82 utf_sprint(logtext+strlen(logtext), c->name);
85 chain_addbefore(uninitializedclasses, c);
88 cl = chain_next(uninitializedclasses);
93 /* function descriptor2types ***************************************************
95 decodes a already checked method descriptor. The parameter count, the
96 return type and the argument types are stored in the passed methodinfo.
98 *******************************************************************************/
100 static void descriptor2types (methodinfo *m)
106 types = DMNEW (u1, m->descriptor->blength);
109 if (!(m->flags & ACC_STATIC)) {
114 utf_ptr = m->descriptor->text + 1;
116 while ((c = *utf_ptr++) != ')') {
123 case 'Z': *tptr++ = TYPE_INT;
125 case 'J': *tptr++ = TYPE_LNG;
127 case 'F': *tptr++ = TYPE_FLT;
129 case 'D': *tptr++ = TYPE_DBL;
131 case 'L': *tptr++ = TYPE_ADR;
132 while (*utf_ptr++ != ';');
134 case '[': *tptr++ = TYPE_ADR;
138 while (*utf_ptr++ != ';') /* skip */;
140 default: panic ("Ill formed methodtype-descriptor");
144 /* compute return type */
146 switch (*utf_ptr++) {
151 case 'Z': m->returntype = TYPE_INT;
153 case 'J': m->returntype = TYPE_LNG;
155 case 'F': m->returntype = TYPE_FLT;
157 case 'D': m->returntype = TYPE_DBL;
160 case 'L': m->returntype = TYPE_ADR;
162 case 'V': m->returntype = TYPE_VOID;
165 default: panic ("Ill formed methodtype-descriptor");
168 m->paramcount = pcount;
169 m->paramtypes = types;
175 /* function allocate_literals **************************************************
177 Scans the JavaVM code of a method and allocates string literals (in the
178 same order as the old JIT). Needed to generate the same addresses as the
181 *******************************************************************************/
183 static void allocate_literals()
190 for (p = 0; p < jcodelength; p = nextp) {
193 nextp = p + jcommandsize[opcode];
197 if (code_get_u1(p + 1) == JAVA_IINC)
203 case JAVA_LOOKUPSWITCH:
204 nextp = ALIGN((p + 1), 4);
205 num = code_get_u4(nextp + 4);
206 nextp = nextp + 8 + 8 * num;
209 case JAVA_TABLESWITCH:
210 nextp = ALIGN ((p + 1),4);
211 num = code_get_s4(nextp + 4);
212 num = code_get_s4(nextp + 8) - num;
213 nextp = nextp + 16 + 4 * num;
217 i = code_get_u1(p+1);
218 goto pushconstantitem;
221 i = code_get_u2(p + 1);
223 if (class_constanttype(class, i) == CONSTANT_String) {
224 s = class_getconstant(class, i, CONSTANT_String);
225 (void) literalstring_new(s);
234 /*******************************************************************************
236 function 'parse' scans the JavaVM code and generates intermediate code
238 During parsing the block index table is used to store at bit pos 0
239 a flag which marks basic block starts and at position 1 to 31 the
240 intermediate instruction index. After parsing the block index table
241 is scanned, for marked positions a block is generated and the block
242 number is stored in the block index table.
244 *******************************************************************************/
246 /* intermediate code generating macros */
248 #define PINC iptr++;ipc++
249 #define LOADCONST_I(v) iptr->opc=ICMD_ICONST;iptr->op1=0;iptr->val.i=(v);PINC
250 #define LOADCONST_L(v) iptr->opc=ICMD_LCONST;iptr->op1=0;iptr->val.l=(v);PINC
251 #define LOADCONST_F(v) iptr->opc=ICMD_FCONST;iptr->op1=0;iptr->val.f=(v);PINC
252 #define LOADCONST_D(v) iptr->opc=ICMD_DCONST;iptr->op1=0;iptr->val.d=(v);PINC
253 #define LOADCONST_A(v) iptr->opc=ICMD_ACONST;iptr->op1=0;iptr->val.a=(v);PINC
254 #define OP(o) iptr->opc=(o);iptr->op1=0;iptr->val.l=0;PINC
255 #define OP1(o,o1) iptr->opc=(o);iptr->op1=(o1);iptr->val.l=(0);PINC
256 #define OP2I(o,o1,v) iptr->opc=(o);iptr->op1=(o1);iptr->val.i=(v);PINC
257 #define OP2A(o,o1,v) iptr->opc=(o);iptr->op1=(o1);iptr->val.a=(v);PINC
258 #define BUILTIN1(v,t) isleafmethod=false;iptr->opc=ICMD_BUILTIN1;iptr->op1=t;\
260 #define BUILTIN2(v,t) isleafmethod=false;iptr->opc=ICMD_BUILTIN2;iptr->op1=t;\
262 #define BUILTIN3(v,t) isleafmethod=false;iptr->opc=ICMD_BUILTIN3;iptr->op1=t;\
266 /* block generating and checking macros */
268 #define block_insert(i) {if(!(block_index[i]&1))\
269 {b_count++;block_index[i] |= 1;}}
270 #define bound_check(i) {if((i< 0) || (i>=cumjcodelength)) \
271 panic("branch target out of code-boundary");}
272 #define bound_check1(i) {if((i< 0) || (i>cumjcodelength)) \
273 panic("branch target out of code-boundary");}
274 // FIXME really use cumjcodelength for the bound_checkers ?
276 static xtable* fillextable (xtable* extable, exceptiontable *raw_extable, int exceptiontablelength, int *label_index, int *block_count)
280 if (exceptiontablelength == 0)
283 b_count = *block_count;
284 for (i = 0; i < exceptiontablelength; i++) {
286 p = raw_extable[i].startpc;
287 if (label_index != NULL) p = label_index[p];
288 extable[i].startpc = p;
292 p = raw_extable[i].endpc;
293 if (label_index != NULL) p = label_index[p];
294 extable[i].endpc = p;
296 if (p < cumjcodelength)
299 p = raw_extable[i].handlerpc;
300 if (label_index != NULL) p = label_index[p];
301 extable[i].handlerpc = p;
305 extable[i].catchtype = raw_extable[i].catchtype;
307 extable[i].next = NULL;
308 extable[i].down = &extable[i+1];
310 *block_count = b_count;
311 return &extable[i]; /* return the next free xtable* */
316 int p; /* java instruction counter */
317 int nextp; /* start of next java instruction */
318 int opcode; /* java opcode */
319 int i; /* temporary for different uses (counters) */
320 int ipc = 0; /* intermediate instruction counter */
321 int b_count = 0; /* basic block counter */
322 int s_count = 0; /* stack element counter */
323 bool blockend = false; /* true if basic block end has been reached */
324 bool iswide = false; /* true if last instruction was a wide */
325 instruction *iptr; /* current pointer into instruction array */
326 int gp; /* global java instruction counter */
327 /* inlining info for current method */
328 inlining_methodinfo *inlinfo = inlining_rootinfo, *tmpinlinf;
329 int nextgp = -1; /* start of next method to be inlined */
330 int *label_index = NULL; /* label redirection table */
331 int firstlocal = 0; /* first local variable of method */
332 xtable* nextex; /* points next free entry in extable */
340 label_index = inlinfo->label_index;
341 maxstack = cummaxstack;
342 exceptiontablelength=cumextablelength;
345 useinltmp = useinlining; //FIXME remove this after debugging
346 //useinlining = false; // and merge the if-statements
349 cumjcodelength = jcodelength;
351 tmpinlinf = (inlining_methodinfo*) list_first(inlinfo->inlinedmethods);
352 if (tmpinlinf != NULL) nextgp = tmpinlinf->startgp;
355 /*RTAprint*/ if ((opt_rt) && ((pOpcodes == 2) || (pOpcodes == 3)) )
356 /*RTAprint*/ {printf("PARSE method name =");
357 /*RTAprint*/ utf_display(method->class->name);printf(".");
358 /*RTAprint*/ method_display(method); printf(">\n\n");fflush(stdout);}
360 RT_jit_parse(method);
363 if ((opt_xta) && (xta1 == 0)) {
364 /*printf("XTA - not available yet\n"); */
366 XTA_jit_parse(method);
367 /*XTAprint*/ if (((pOpcodes == 1) || (pOpcodes == 3)) && opt_rt)
368 /*XTAprint*/ {printf("XTA PARSE method name =");
369 /*XTAprint*/ utf_display(rt_method->class->name);printf(".");
370 /*XTAprint*/ method_display(rt_method); printf(">\n\n");fflush(stdout);}
377 /* generate the same addresses as the old JIT compiler */
383 /* allocate instruction array and block index table */
385 /* 1 additional for end ipc and 3 for loop unrolling */
387 block_index = DMNEW(int, cumjcodelength + 4);
389 /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
390 /* additional MONITOREXITS are reached by branches which are 3 bytes */
392 iptr = instr = DMNEW(instruction, cumjcodelength + 5);
394 /* initialize block_index table (unrolled four times) */
399 for (i = 0, ip = block_index; i <= cumjcodelength; i += 4, ip += 4) {
407 /* compute branch targets of exception table */
409 extable = DMNEW(xtable, exceptiontablelength + 1);
411 for (i = 0; i < method->exceptiontablelength; i++) {
413 p = extable[i].startpc = raw_extable[i].startpc;
414 if (useinlining) p = label_index[p];
418 p = extable[i].endpc = raw_extable[i].endpc;
419 if (useinlining) p = label_index[p];
421 if (p < cumjcodelength)
424 p = extable[i].handlerpc = raw_extable[i].handlerpc;
428 extable[i].catchtype = raw_extable[i].catchtype;
430 extable[i].next = NULL;
431 extable[i].down = &extable[i+1];
435 nextex = fillextable(extable, raw_extable, method->exceptiontablelength, label_index, &b_count);
437 s_count = 1 + exceptiontablelength; /* initialize stack element counter */
440 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
445 /* scan all java instructions */
447 for (p = 0, gp = 0; p < jcodelength; gp += (nextp - p), p = nextp) {
449 // DEBUG printf("p:%d gp:%d ",p,gp);
452 if ((useinlining) && (gp == nextgp)) {
454 bool *readonly = NULL;
455 bool firstreadonly = true;
457 opcode = code_get_u1 (p);
458 nextp = p += jcommandsize[opcode];
459 tmpinlinf = list_first(inlinfo->inlinedmethods);
460 firstlocal = tmpinlinf->firstlocal;
461 label_index = tmpinlinf->label_index;
462 readonly = tmpinlinf->readonly;
463 for (i=0, tptr=tmpinlinf->method->paramtypes + tmpinlinf->method->paramcount - 1 ; i<tmpinlinf->method->paramcount; i++, tptr--)
467 if ( (i==0) && inlineparamopt) {
468 OP1(ICMD_CLEAR_ARGREN, firstlocal);
471 if ( !inlineparamopt || !readonly[i] )
473 else op = ICMD_READONLY_ARG;
476 OP1(op, firstlocal + tmpinlinf->method->paramcount - 1 - i);
478 // block_index[gp] |= (ipc << 1); //FIXME: necessary ?
480 inlining_save_compiler_variables();
481 inlining_set_compiler_variables(tmpinlinf);
482 if (inlinfo->inlinedmethods == NULL) gp = -1;
484 tmpinlinf = list_first(inlinfo->inlinedmethods);
485 nextgp = (tmpinlinf != NULL) ? tmpinlinf->startgp : -1;
487 if (method->exceptiontablelength > 0)
488 nextex = fillextable(nextex, method->exceptiontable, method->exceptiontablelength, label_index, &b_count);
492 opcode = code_get_u1 (p); /* fetch op code */
495 /*RTAprint*/ if ((opt_rt) && ((pOpcodes == 2) || (pOpcodes == 3)) )
496 /*RTAprint*/ {printf("Parse<%i> p=%i<%i< opcode=<%i> %s\n",
497 /*RTAprint*/ pOpcodes, p,rt_jcodelength,opcode,icmd_names[opcode]);}
500 block_index[gp] |= (ipc << 1); /* store intermediate count */
503 block_insert(gp); /* start new block */
507 nextp = p + jcommandsize[opcode]; /* compute next instruction start */
508 s_count += stackreq[opcode]; /* compute stack element count */
515 /* pushing constants onto the stack p */
518 LOADCONST_I(code_get_s1(p+1));
522 LOADCONST_I(code_get_s2(p+1));
526 i = code_get_u1(p+1);
527 goto pushconstantitem;
530 i = code_get_u2(p + 1);
534 if (i >= class->cpcount)
535 panic ("Attempt to access constant outside range");
537 switch (class->cptags[i]) {
538 case CONSTANT_Integer:
539 LOADCONST_I(((constant_integer*)
540 (class->cpinfos[i]))->value);
543 LOADCONST_L(((constant_long*)
544 (class->cpinfos[i]))->value);
547 LOADCONST_F(((constant_float*)
548 (class->cpinfos[i]))->value);
550 case CONSTANT_Double:
551 LOADCONST_D(((constant_double*)
552 (class->cpinfos[i]))->value);
554 case CONSTANT_String:
555 LOADCONST_A(literalstring_new((utf*)
556 (class->cpinfos[i])));
558 default: panic("Invalid constant type to push");
562 case JAVA_ACONST_NULL:
573 LOADCONST_I(opcode - JAVA_ICONST_0);
578 LOADCONST_L(opcode - JAVA_LCONST_0);
584 LOADCONST_F(opcode - JAVA_FCONST_0);
589 LOADCONST_D(opcode - JAVA_DCONST_0);
592 /* loading variables onto the stack */
600 i = code_get_u1(p+1);
602 i = code_get_u2(p+1);
606 OP1(opcode, i + firstlocal);
613 OP1(ICMD_ILOAD, opcode - JAVA_ILOAD_0 + firstlocal);
620 OP1(ICMD_LLOAD, opcode - JAVA_LLOAD_0 + firstlocal);
627 OP1(ICMD_FLOAD, opcode - JAVA_FLOAD_0 + firstlocal);
634 OP1(ICMD_DLOAD, opcode - JAVA_DLOAD_0 + firstlocal);
641 OP1(ICMD_ALOAD, opcode - JAVA_ALOAD_0 + firstlocal);
644 /* storing stack values into local variables */
652 i = code_get_u1(p+1);
654 i = code_get_u2(p+1);
658 OP1(opcode, i + firstlocal);
665 OP1(ICMD_ISTORE, opcode - JAVA_ISTORE_0 + firstlocal);
672 OP1(ICMD_LSTORE, opcode - JAVA_LSTORE_0 + firstlocal);
679 OP1(ICMD_FSTORE, opcode - JAVA_FSTORE_0 + firstlocal);
686 OP1(ICMD_DSTORE, opcode - JAVA_DSTORE_0 + firstlocal);
693 OP1(ICMD_ASTORE, opcode - JAVA_ASTORE_0 + firstlocal);
701 i = code_get_u1(p + 1);
702 v = code_get_s1(p + 2);
705 i = code_get_u2(p + 1);
706 v = code_get_s2(p + 3);
710 OP2I(opcode, i + firstlocal, v);
714 /* wider index for loading, storing and incrementing */
721 /* managing arrays ************************************************/
724 OP2I(ICMD_CHECKASIZE, 0, 0);
725 switch (code_get_s1(p+1)) {
727 BUILTIN1((functionptr)builtin_newarray_boolean, TYPE_ADR);
730 BUILTIN1((functionptr)builtin_newarray_char, TYPE_ADR);
733 BUILTIN1((functionptr)builtin_newarray_float, TYPE_ADR);
736 BUILTIN1((functionptr)builtin_newarray_double, TYPE_ADR);
739 BUILTIN1((functionptr)builtin_newarray_byte, TYPE_ADR);
742 BUILTIN1((functionptr)builtin_newarray_short, TYPE_ADR);
745 BUILTIN1((functionptr)builtin_newarray_int, TYPE_ADR);
748 BUILTIN1((functionptr)builtin_newarray_long, TYPE_ADR);
750 default: panic("Invalid array-type to create");
755 OP2I(ICMD_CHECKASIZE, 0, 0);
756 i = code_get_u2(p+1);
757 /* array or class type ? */
758 if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
760 LOADCONST_A(class_getconstant(class, i,
761 CONSTANT_Arraydescriptor));
762 #if defined(__I386__)
763 BUILTIN2((functionptr) asm_builtin_newarray_array, TYPE_ADR);
765 BUILTIN2((functionptr)builtin_newarray_array, TYPE_ADR);
769 LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
771 #if defined(__I386__)
772 BUILTIN2((functionptr) asm_builtin_anewarray, TYPE_ADR);
774 BUILTIN2((functionptr)builtin_anewarray, TYPE_ADR);
779 case JAVA_MULTIANEWARRAY:
781 i = code_get_u2(p+1);
783 int v = code_get_u1(p+3);
784 constant_arraydescriptor *desc =
785 class_getconstant (class, i, CONSTANT_Arraydescriptor);
786 OP2A(opcode, v, desc);
808 i = p + code_get_s2(p+1);
820 i = p + code_get_s4(p+1);
833 i = code_get_u1(p+1);
835 i = code_get_u2(p+1);
842 if (isinlinedmethod) {
843 OP1(ICMD_GOTO, inlinfo->stopgp);
847 OP1(opcode, i + firstlocal);
858 if (isinlinedmethod) {
859 /* if (p==jcodelength-1) { //return is at end of inlined method
864 OP1(ICMD_GOTO, inlinfo->stopgp);
878 /* table jumps ********************************/
880 case JAVA_LOOKUPSWITCH:
886 nextp = ALIGN((p + 1), 4);
888 tablep = (s4*)(jcode + nextp);
891 num = code_get_u4(nextp + 4);
892 tablep = DMNEW(s4, num * 2 + 2);
895 OP2A(opcode, 0, tablep);
899 j = p + code_get_s4(nextp);
900 if (useinlining) j = label_index[j];
901 *tablep = j; /* restore for little endian */
907 /* number of pairs */
909 num = code_get_u4(nextp);
914 for (i = 0; i < num; i++) {
918 j = code_get_s4(nextp);
919 *tablep = j; /* restore for little endian */
925 j = p + code_get_s4(nextp);
926 if (useinlining) j = label_index[j];
927 *tablep = j; /* restore for little endian */
938 case JAVA_TABLESWITCH:
944 nextp = ALIGN((p + 1), 4);
946 tablep = (s4*)(jcode + nextp);
949 num = code_get_u4(nextp + 8) - code_get_u4(nextp + 4);
950 tablep = DMNEW(s4, num + 1 + 3);
953 OP2A(opcode, 0, tablep);
957 j = p + code_get_s4(nextp);
958 if (useinlining) j = label_index[j];
959 *tablep = j; /* restore for little endian */
967 j = code_get_s4(nextp);
968 *tablep = j; /* restore for little endian */
974 num = code_get_s4(nextp);
975 *tablep = num; /* restore for little endian */
981 for (i = 0; i <= num; i++) {
982 j = p + code_get_s4(nextp);
983 if (useinlining) j = label_index[j];
984 *tablep = j; /* restore for little endian */
995 /* load and store of object fields *******************/
998 BUILTIN3((functionptr) asm_builtin_aastore, TYPE_VOID);
1001 case JAVA_PUTSTATIC:
1002 case JAVA_GETSTATIC:
1003 i = code_get_u2(p + 1);
1005 constant_FMIref *fr;
1007 fr = class_getconstant (class, i, CONSTANT_Fieldref);
1008 fi = class_findfield (fr->class, fr->name, fr->descriptor);
1009 compiler_addinitclass (fr->class);
1010 OP2A(opcode, fi->type, fi);
1015 i = code_get_u2(p + 1);
1017 constant_FMIref *fr;
1019 fr = class_getconstant (class, i, CONSTANT_Fieldref);
1020 fi = class_findfield (fr->class, fr->name, fr->descriptor);
1021 OP2A(opcode, fi->type, fi);
1026 /* method invocation *****/
1028 case JAVA_INVOKESTATIC:
1029 i = code_get_u2(p + 1);
1031 constant_FMIref *mr;
1034 mr = class_getconstant (class, i, CONSTANT_Methodref);
1035 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1036 /*RTAprint*/ if (((pOpcodes == 2) || (pOpcodes == 3)) && opt_rt)
1037 /*RTAprint*/ {printf(" method name =");
1038 /*RTAprint*/ utf_display(mi->class->name); printf(".");
1039 /*RTAprint*/ utf_display(mi->name);printf("\tINVOKE STATIC\n");
1040 /*RTAprint*/ fflush(stdout);}
1041 if (! (mi->flags & ACC_STATIC))
1042 panic ("Static/Nonstatic mismatch calling static method");
1043 descriptor2types(mi);
1046 OP2A(opcode, mi->paramcount, mi);
1049 case JAVA_INVOKESPECIAL:
1050 case JAVA_INVOKEVIRTUAL:
1051 i = code_get_u2(p + 1);
1053 constant_FMIref *mr;
1056 mr = class_getconstant (class, i, CONSTANT_Methodref);
1057 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1058 /*RTAprint*/ if (((pOpcodes == 2) || (pOpcodes == 3)) && opt_rt)
1059 /*RTAprint*/ {printf(" method name =");
1061 /*RTAprint*/ utf_display(mi->class->name); printf(".");
1062 /*RTAprint*/ utf_display(mi->name);printf("\tINVOKE SPECIAL/VIRTUAL\n");
1063 /*RTAprint*/ fflush(stdout);}
1065 if (mi->flags & ACC_STATIC)
1066 panic ("Static/Nonstatic mismatch calling static method");
1067 descriptor2types(mi);
1069 OP2A(opcode, mi->paramcount, mi);
1072 case JAVA_INVOKEINTERFACE:
1073 i = code_get_u2(p + 1);
1075 constant_FMIref *mr;
1078 mr = class_getconstant (class, i, CONSTANT_InterfaceMethodref);
1079 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1080 if (mi->flags & ACC_STATIC)
1081 panic ("Static/Nonstatic mismatch calling static method");
1082 descriptor2types(mi);
1084 OP2A(opcode, mi->paramcount, mi);
1088 /* miscellaneous object operations *******/
1091 i = code_get_u2 (p+1);
1093 LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
1095 BUILTIN1((functionptr) builtin_new, TYPE_ADR);
1098 case JAVA_CHECKCAST:
1099 i = code_get_u2(p+1);
1101 /* array type cast-check */
1102 if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
1103 LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
1105 BUILTIN2((functionptr) asm_builtin_checkarraycast, TYPE_ADR);
1107 else { /* object type cast-check */
1109 LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
1111 BUILTIN2((functionptr) asm_builtin_checkcast, TYPE_ADR);
1113 OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
1117 case JAVA_INSTANCEOF:
1118 i = code_get_u2(p+1);
1120 /* array type cast-check */
1121 if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
1122 LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
1124 #if defined(__I386__)
1125 BUILTIN2((functionptr) asm_builtin_arrayinstanceof, TYPE_INT);
1127 BUILTIN2((functionptr) builtin_arrayinstanceof, TYPE_INT);
1130 else { /* object type cast-check */
1132 LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
1134 BUILTIN2((functionptr) builtin_instanceof, TYPE_INT);
1136 OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
1140 case JAVA_MONITORENTER:
1143 #ifdef SOFTNULLPTRCHECK
1145 BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
1148 /* BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID); */
1149 BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
1152 BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID);
1158 OP(ICMD_NULLCHECKPOP);
1162 case JAVA_MONITOREXIT:
1165 BUILTIN1((functionptr) builtin_monitorexit, TYPE_VOID);
1174 /* any other basic operation **************************************/
1193 #if defined(__I386__)
1194 /* BUILTIN2((functionptr) asm_builtin_frem, TYPE_FLOAT); */
1197 BUILTIN2((functionptr) builtin_frem, TYPE_FLOAT);
1202 #if defined(__I386__)
1205 BUILTIN2((functionptr) builtin_drem, TYPE_DOUBLE);
1211 BUILTIN1((functionptr) builtin_f2i, TYPE_INT);
1220 BUILTIN1((functionptr) builtin_f2l, TYPE_LONG);
1229 BUILTIN1((functionptr) builtin_d2i, TYPE_INT);
1238 BUILTIN1((functionptr) builtin_d2l, TYPE_LONG);
1245 case JAVA_BREAKPOINT:
1246 panic("Illegal opcode Breakpoint encountered");
1302 printf("Illegal opcode %d at instr %d", opcode, ipc);
1303 panic("encountered");
1314 if ((isinlinedmethod) && (p==jcodelength-1)) { //end of an inlined method
1315 // printf("setting gp from %d to %d\n",gp, inlinfo->stopgp);
1316 gp = inlinfo->stopgp;
1317 inlining_restore_compiler_variables();
1318 list_remove(inlinfo->inlinedmethods, list_first(inlinfo->inlinedmethods));
1319 if (inlinfo->inlinedmethods == NULL) nextgp = -1;
1321 tmpinlinf = list_first(inlinfo->inlinedmethods);
1322 nextgp = (tmpinlinf != NULL) ? tmpinlinf->startgp : -1;
1324 // printf("nextpgp: %d\n", nextgp);
1325 label_index=inlinfo->label_index;
1326 firstlocal = inlinfo->firstlocal;
1330 if (p != jcodelength)
1331 panic("Command-sequence crosses code-boundary");
1334 panic("Code does not end with branch/return/athrow - stmt");
1336 /* adjust block count if target 0 is not first intermediate instruction */
1338 if (!block_index[0] || (block_index[0] > 1))
1341 /* copy local to global variables */
1344 block_count = b_count;
1345 stack_count = s_count + block_count * maxstack;
1347 /* allocate stack table */
1349 stack = DMNEW(stackelement, stack_count);
1354 bptr = block = DMNEW(basicblock, b_count + 1); /* one more for end ipc */
1359 /* additional block if target 0 is not first intermediate instruction */
1361 if (!block_index[0] || (block_index[0] > 1)) {
1362 bptr->iinstr = instr;
1365 bptr->type = BBTYPE_STD;
1366 bptr->branchrefs = NULL;
1367 bptr->pre_count = 0;
1368 bptr->debug_nr = c_debug_nr++;
1371 (bptr - 1)->next = bptr;
1375 /* allocate blocks */
1378 for (p = 0; p < cumjcodelength; p++)
1380 if (block_index[p] & 1) {
1381 bptr->iinstr = instr + (block_index[p] >> 1);
1382 bptr->debug_nr = c_debug_nr++;
1384 (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
1388 bptr->type = BBTYPE_STD;
1389 bptr->branchrefs = NULL;
1390 block_index[p] = b_count;
1391 bptr->pre_count = 0;
1395 (bptr - 1)->next = bptr;
1398 /* allocate additional block at end */
1401 bptr->instack = bptr->outstack = NULL;
1402 bptr->indepth = bptr->outdepth = 0;
1403 bptr->iinstr = NULL;
1404 (bptr - 1)->icount = (instr + instr_count) - (bptr - 1)->iinstr;
1409 bptr->type = BBTYPE_STD;
1410 bptr->branchrefs = NULL;
1411 bptr->pre_count = 0;
1412 bptr->debug_nr = c_debug_nr++;
1414 (bptr - 1)->next = bptr;
1419 if (exceptiontablelength > 0)
1420 extable[exceptiontablelength-1].down = NULL;
1424 for (i = 0; i < exceptiontablelength; ++i) {
1425 p = extable[i].startpc;
1426 extable[i].start = block + block_index[p];
1428 p = extable[i].endpc;
1429 extable[i].end = block + block_index[p];
1431 p = extable[i].handlerpc;
1432 extable[i].handler = block + block_index[p];
1436 if (useinlining) inlining_cleanup();
1437 useinlining = useinltmp;
1440 #include "parseRT.h"
1441 #include "parseXTA.h"
1444 * These are local overrides for various environment variables in Emacs.
1445 * Please do not remove this and leave it at the end of the file, where
1446 * Emacs will automagically detect them.
1447 * ---------------------------------------------------------------------
1450 * indent-tabs-mode: t