* Merged in twisti-branch.
[cacao.git] / src / vm / jit / m68k / codegen.c
1 /* src/vm/jit/m68k/codegen.c
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: codegen.c 7564 2007-03-23 23:36:17Z twisti $
26 */
27
28
29 #include "config.h"
30
31 #include <assert.h>
32
33 #include "md-abi.h"
34
35 #include "vm/types.h"
36 #include "vm/jit/m68k/codegen.h"
37 #include "vm/jit/m68k/emit.h"
38
39 #include "mm/memory.h"
40 #include "native/jni.h"
41 #include "native/native.h"
42
43 #if defined(ENABLE_THREADS)
44 # include "threads/native/lock.h"
45 #endif
46
47 #include "vm/builtin.h"
48 #include "vm/exceptions.h"
49 #include "vm/global.h"
50 #include "vm/stringlocal.h"
51 #include "vm/vm.h"
52
53 #include "vm/jit/asmpart.h"
54 #include "vm/jit/codegen-common.h"
55 #include "vm/jit/dseg.h"
56 #include "vm/jit/emit-common.h"
57 #include "vm/jit/jit.h"
58 #include "vm/jit/parse.h"
59 #include "vm/jit/patcher.h"
60 #include "vm/jit/reg.h"
61 #include "vm/jit/replace.h"
62 #include "vm/jit/stacktrace.h"
63 #include "vm/jit/md.h"
64
65 #include "vmcore/loader.h"
66 #include "vmcore/options.h"
67 #include "vmcore/utf8.h"
68
69
70 bool codegen_emit(jitdata *jd) 
71 {       
72         methodinfo         *m;
73         codeinfo           *code;
74         codegendata        *cd;
75         registerdata       *rd;
76         s4                  len, s1, s2, s3, d, disp;
77         ptrint              a;
78         varinfo            *var;
79         basicblock         *bptr;
80         instruction        *iptr;
81         exception_entry    *ex;
82         u2                  currentline;
83         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
84         unresolved_method  *um;
85         builtintable_entry *bte;
86         methoddesc         *md;
87         s4                  fieldtype;
88         s4                  varindex;
89         unresolved_field   *uf;
90         fieldinfo          *fi;
91
92         /* get required compiler data */
93
94         m    = jd->m;
95         code = jd->code;
96         cd   = jd->cd;
97         rd   = jd->rd;
98
99         /* prevent compiler warnings */
100
101         d = 0;
102         lm = NULL;
103         bte = NULL;
104
105         {
106                 s4 i, p, t, l;
107                 /* save calle saved registers */
108                 s4 savedregs_num = 0;
109
110                 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
111                 savedregs_num += (ADR_SAV_CNT - rd->savadrreguse);
112                 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
113
114                 cd->stackframesize = rd->memuse + savedregs_num;
115 #if defined(ENABLE_THREADS)
116                 assert(0);
117 #endif
118         
119                 /* create method header */
120                 (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
121                 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
122 #if defined(ENABLE_THREADS)
123                 if (checksync && (m->flags & ACC_SYNCHRONIZED))
124                         (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4);/* IsSync         */
125                 else
126 #endif
127                         (void) dseg_add_unique_s4(cd, 0);                  /* IsSync          */
128                 (void) dseg_add_unique_s4(cd, jd->isleafmethod);       /* IsLeaf          */
129                 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
130                 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
131
132                 dseg_addlinenumbertablesize(cd);
133
134                 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize   */
135
136                 /* create exception table */
137                 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
138                         dseg_add_target(cd, ex->start);
139                         dseg_add_target(cd, ex->end);
140                         dseg_add_target(cd, ex->handler);
141                         (void) dseg_add_unique_address(cd, ex->catchtype.any);
142                 }
143
144 #if defined(ENABLE_PROFILING)
145                 assert(0);
146 #endif
147
148 #if !defined(NDEBUG)
149                 emit_verbosecall_enter(jd);
150 #endif
151                 /* create stack frame */
152                 M_AADD_IMM(-(cd->stackframesize*4), REG_SP);
153
154                 /* save used callee saved registers */
155                 p = cd->stackframesize;
156                 for (i=INT_SAV_CNT-1; i>=rd->savintreguse; --i) {
157                         p--; M_IST(rd->savintregs[i], REG_SP, p*4);
158                 }
159                 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
160                         p--; M_AST(rd->savadrregs[i], REG_SP, p*4);
161                 }
162 #if !defined(ENABLE_SOFTFLOAT)
163                 for (i=FLT_SAV_CNT-1; i>=rd->savfltreguse; --i) {
164                         p-=2; M_FST(rd->savfltregs[i], REG_SP, p*4);    /* FIXME */
165                 }       
166 #else
167                 assert(FLT_SAV_CNT == 0);
168                 assert(rd->savfltreguse == 0);
169 #endif
170                 /* take arguments out of stack frame */
171                 md = m->parseddesc;
172                 for (p = 0, l = 0; p < md->paramcount; p++) {
173                         t = md->paramtypes[p].type;
174                         varindex = jd->local_map[l * 5 + t];
175         
176                         l++;
177                         if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
178                                 l++;
179
180                         if (varindex == UNUSED)
181                                 continue;
182
183                         var = VAR(varindex);
184         
185                         s1 = md->params[p].regoff;
186                         assert(md->params[p].inmemory);                 /* all args are on stack */
187
188                         switch (t)      {
189 #if defined(ENABLE_SOFTFLOAT)
190                         case TYPE_FLT:
191                         case TYPE_DBL:
192 #endif
193                         case TYPE_LNG:
194                         case TYPE_INT:
195                                 if (!IS_INMEMORY(var->flags)) {      /* stack arg -> register */
196                                         if (IS_2_WORD_TYPE(t))  {
197                                                 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4);
198                                         } else {
199                                                 M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4);
200                                         }
201                                 } else {                             /* stack arg -> spilled  */
202 #if 1
203                                         M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4);
204                                         M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4);
205                                         if (IS_2_WORD_TYPE(t)) {
206                                                 M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4 + 4);
207                                                 M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4 + 4);
208                                         }
209 #else
210                                         /* Reuse Memory Position on Caller Stack */
211                                         var->vv.regoff = cd->stackframesize + s1;
212 #endif
213                                 } 
214                                 break;
215 #if !defined(ENABLE_SOFTFLOAT)
216                         case TYPE_FLT:
217                         case TYPE_DBL:
218                                 if (!IS_INMEMORY(var->flags)) {      /* stack-arg -> register */
219                                         if (IS_2_WORD_TYPE(t))  {
220                                                 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4);
221                                         } else {
222                                                 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4);
223                                         }
224                                 } else {                             /* stack-arg -> spilled  */
225 #if 1
226                                         if (IS_2_WORD_TYPE(t)) {
227                                                 M_DLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4);
228                                                 M_DST(REG_FTMP1, REG_SP, var->vv.regoff * 4);
229                                         } else {
230                                                 M_FLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4);
231                                                 M_FST(REG_FTMP1, REG_SP, var->vv.regoff * 4);
232                                         }
233 #else
234                                         /* Reuse Memory Position on Caller Stack */
235                                         var->vv.regoff = cd->stackframesize + s1;
236 #endif
237                                 }
238                                 break;
239 #endif /* SOFTFLOAT */
240                         case TYPE_ADR:
241                                 if (!IS_INMEMORY(var->flags)) {      /* stack-arg -> register */
242                                         M_ALD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4);
243                                 } else {                             /* stack-arg -> spilled  */
244 #if 1
245                                         M_ALD(REG_ATMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4);
246                                         M_AST(REG_ATMP1, REG_SP, var->vv.regoff * 4);
247 #else
248                                 /* Reuse Memory Position on Caller Stack */
249                                 var->vv.regoff = cd->stackframesize + s1;
250 #endif
251                                 }
252                                 break;
253                         default: assert(0);
254                         }
255                 } /* end for argument out of stack*/
256         }
257
258
259
260         /* create replacement points */
261         REPLACEMENT_POINTS_INIT(cd, jd);
262
263         /* foreach basic block */
264         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
265         
266         bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
267
268         if (bptr->flags >= BBREACHED)   {
269         
270         /* branch resolving */
271         codegen_resolve_branchrefs(cd, bptr);
272
273         /* FIXME there are still some constrcuts to copy in here */
274
275         /* walk through all instructions */
276         len = bptr->icount;
277         currentline = 0;
278
279         for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
280                 if (iptr->line != currentline) {
281                         dseg_addlinenumber(cd, iptr->line);
282                         currentline = iptr->line;
283                 }
284
285                 MCODECHECK(1024);                         /* 1kB should be enough */
286
287                 switch (iptr->opc) {
288                 case ICMD_NOP:        /* ...  ==> ...                                 */
289                 case ICMD_POP:        /* ..., value  ==> ...                          */
290                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
291                         break;
292
293                 case ICMD_INLINE_START:
294
295                         REPLACEMENT_POINT_INLINE_START(cd, iptr);
296                         break;
297
298                 case ICMD_INLINE_BODY:
299
300                         REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
301                         dseg_addlinenumber_inline_start(cd, iptr);
302                         dseg_addlinenumber(cd, iptr->line);
303                         break;
304
305                 case ICMD_INLINE_END:
306
307                         dseg_addlinenumber_inline_end(cd, iptr);
308                         dseg_addlinenumber(cd, iptr->line);
309                         break;
310
311                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
312
313                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
314                         assert(VAROP(iptr->s1)->type == TYPE_ADR);
315                         emit_nullpointer_check(cd, iptr, s1);
316                         break;
317
318
319                 /* CONST **************************************************************/
320                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
321                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
322                         M_IMOV_IMM(iptr->sx.val.i, d);
323                         emit_store_dst(jd, iptr, d);
324                         break;
325
326                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
327
328                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
329                         LCONST(iptr->sx.val.l, d);
330                         emit_store_dst(jd, iptr, d);
331                         break;
332
333                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
334
335 #if defined(ENABLE_SOFTFLOAT)
336                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
337                         M_IMOV_IMM(iptr->sx.val.i, d);
338                         emit_store_dst(jd, iptr, d);
339 #else
340                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
341                         FCONST(iptr->sx.val.f, d);
342                         emit_store_dst(jd, iptr, d);
343 #endif
344                         break;
345
346                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
347
348 #if defined(ENABLE_SOFTFLOAT)
349                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
350                         LCONST(iptr->sx.val.l, d);
351                         emit_store_dst(jd, iptr, d);
352 #else
353                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
354                         DCONST(iptr->sx.val.d, d);
355                         emit_store_dst(jd, iptr, d);
356 #endif
357                         break;
358
359
360
361                 /* integer operations ************************************************/
362                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
363
364                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
365                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
366                         M_INTMOVE(s1, REG_ITMP1);
367                         M_INEG(REG_ITMP1);
368                         M_INTMOVE(REG_ITMP1, d);
369                         emit_store_dst(jd, iptr, d);
370                         break;
371
372 #if 0
373                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
374
375                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
376                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
377                         M_SUBFIC(GET_LOW_REG(s1), 0, GET_LOW_REG(d));
378                         M_SUBFZE(GET_HIGH_REG(s1), GET_HIGH_REG(d));
379                         emit_store_dst(jd, iptr, d);
380                         break;
381 #endif
382                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
383
384                         s1 = emit_load_s1(jd, iptr, REG_ITMP2);
385                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
386                         M_INTMOVE(s1, GET_LOW_REG(d));                          /* sets negativ bit */
387                         M_BPL(4);
388                         M_ISET(GET_HIGH_REG(d));
389                         M_TPFW;
390                         M_ICLR(GET_HIGH_REG(d));
391
392                         emit_store_dst(jd, iptr, d);
393                         break;
394
395                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
396
397                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
398                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
399                         M_INTMOVE(s1, d);
400                         emit_store_dst(jd, iptr, d);
401                         break;
402                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
403
404                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
405                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
406                         M_BSEXT(s1, d);
407                         emit_store_dst(jd, iptr, d);
408                         break;
409
410                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
411
412                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
413                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
414                         M_CZEXT(s1, d);
415                         emit_store_dst(jd, iptr, d);
416                         break;
417
418                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
419
420                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
421                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
422                         M_SSEXT(s1, d);
423                         emit_store_dst(jd, iptr, d);
424                         break;
425
426
427
428                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
429
430                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
431                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
432                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
433                         M_INTMOVE(s2, REG_ITMP2);
434                         M_IADD(s1, REG_ITMP2);
435                         M_INTMOVE(REG_ITMP2, d);
436                         emit_store_dst(jd, iptr, d);
437                         break;
438
439                                       /* s1.localindex = variable, sx.val.i = constant*/
440
441                 case ICMD_IINC:
442                 case ICMD_IADDCONST:
443
444                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
445                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
446                         M_INTMOVE(s1, REG_ITMP1);
447                         M_IADD_IMM(iptr->sx.val.i, REG_ITMP1);
448                         M_INTMOVE(REG_ITMP1, d);
449                         emit_store_dst(jd, iptr, d);
450                         break;
451
452                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
453
454                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
455                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
456                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
457                         M_INTMOVE(s1, REG_ITMP1);
458                         M_ISUB(s2, REG_ITMP1);
459                         M_INTMOVE(REG_ITMP1, d);
460                         emit_store_dst(jd, iptr, d);
461                         break;
462
463                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
464                                       /* sx.val.i = constant                          */
465
466                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
467                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
468                         M_INTMOVE(s1, REG_ITMP1);
469                         M_IADD_IMM(-iptr->sx.val.i, REG_ITMP1);
470                         M_INTMOVE(REG_ITMP1, d);
471                         emit_store_dst(jd, iptr, d);
472                         break;
473
474                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
475
476                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
477                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
478                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
479                         emit_arithmetic_check(cd, iptr, s2);
480
481                         M_INTMOVE(s1, REG_ITMP1);
482                         M_IDIV(s2, REG_ITMP1);
483                         M_INTMOVE(REG_ITMP1, d);
484
485                         emit_store_dst(jd, iptr, d);
486                         break;
487
488                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
489
490                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
491                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
492                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
493                         emit_arithmetic_check(cd, iptr, s2);
494
495                         M_IREM(s2, s1, REG_ITMP3);
496                         M_INTMOVE(REG_ITMP3, d);
497
498                         emit_store_dst(jd, iptr, d);
499                         break;
500
501                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
502                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
503
504                         bte = iptr->sx.s23.s3.bte;
505                         md  = bte->md;
506
507                         s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
508                         M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
509                         M_IOR(GET_HIGH_REG(s2), REG_ITMP3);
510                         /* XXX could be optimized */
511                         emit_arithmetic_check(cd, iptr, REG_ITMP3);
512
513                         M_LST(s2, REG_SP, 2 * 4);
514                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
515                         M_LST(s1, REG_SP, 0 * 4);
516
517                         M_JSR_IMM(bte->fp);
518
519                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
520                         M_LNGMOVE(REG_RESULT_PACKED, d);
521                         emit_store_dst(jd, iptr, d);
522                         break;
523
524                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
525
526                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
527                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
528                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
529                         M_INTMOVE(s2, REG_ITMP2);
530                         M_IMUL(s1, REG_ITMP2);
531                         M_INTMOVE(REG_ITMP2, d);
532                         emit_store_dst(jd, iptr, d);
533                         break;
534
535                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
536                                       /* sx.val.i = constant                          */
537                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
538                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
539                         M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
540                         M_IMUL(s1, REG_ITMP2);
541                         M_INTMOVE(REG_ITMP2, d);
542                         emit_store_dst(jd, iptr, d);
543                         break;
544
545                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
546
547                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
548                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
549                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
550                         M_INTMOVE(s1, REG_ITMP1);
551                         M_INTMOVE(s2, REG_ITMP2);
552                         M_IAND_IMM(0x1f, REG_ITMP2);
553                         M_ISSL(REG_ITMP2, REG_ITMP1);
554                         M_INTMOVE(REG_ITMP1, d);
555                         emit_store_dst(jd, iptr, d);
556                         break;
557
558                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
559                                       /* sx.val.i = constant                          */
560
561                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
562                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
563                         M_INTMOVE(s1, REG_ITMP1)
564                         M_ISSL_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
565                         M_INTMOVE(REG_ITMP1, d);
566                         emit_store_dst(jd, iptr, d);
567                         break;
568
569                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
570
571                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
572                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
573                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
574                         M_INTMOVE(s1, REG_ITMP1);
575                         M_INTMOVE(s2, REG_ITMP2);
576                         M_IAND_IMM(0x1f, REG_ITMP2);
577                         M_ISSR(REG_ITMP2, REG_ITMP1);
578                         M_INTMOVE(REG_ITMP1, d);
579                         emit_store_dst(jd, iptr, d);
580                         break;
581
582                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
583                                       /* sx.val.i = constant                          */
584
585                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
586                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
587                         M_INTMOVE(s1, REG_ITMP1)
588                         M_ISSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
589                         M_INTMOVE(REG_ITMP1, d);
590                         emit_store_dst(jd, iptr, d);
591                         break;
592
593                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
594
595                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
596                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
597                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
598                         M_INTMOVE(s1, REG_ITMP1);
599                         M_INTMOVE(s2, REG_ITMP2);
600                         M_IAND_IMM(0x1f, REG_ITMP2);
601                         M_IUSR(REG_ITMP2, REG_ITMP1);
602                         M_INTMOVE(REG_ITMP1, d);
603                         emit_store_dst(jd, iptr, d);
604                         break;
605
606                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
607                                       /* sx.val.i = constant                          */
608                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
609                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
610                         M_INTMOVE(s1, REG_ITMP1)
611                         M_IUSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
612                         M_INTMOVE(REG_ITMP1, d);
613                         emit_store_dst(jd, iptr, d);
614                         break;
615
616                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
617
618                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
619                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
620                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
621                         M_INTMOVE(s2, REG_ITMP2);
622                         M_IAND(s1, REG_ITMP2);
623                         M_INTMOVE(REG_ITMP2, d);
624                         emit_store_dst(jd, iptr, d);
625                         break;
626
627                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
628                                       /* sx.val.i = constant                          */
629
630                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
631                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
632                         M_INTMOVE(s1, REG_ITMP1);
633                         M_IAND_IMM(iptr->sx.val.i, REG_ITMP1);
634                         M_INTMOVE(REG_ITMP1, d);
635                         emit_store_dst(jd, iptr, d);
636                         break;
637
638
639
640
641                 /* load/store/copy/move operations ************************************/
642
643                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
644                 case ICMD_ALOAD:      /* s1 = local variable                          */
645                 case ICMD_LLOAD:
646                 case ICMD_FLOAD:  
647                 case ICMD_DLOAD:  
648                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
649                 case ICMD_LSTORE:
650                 case ICMD_FSTORE:
651                 case ICMD_DSTORE: 
652                 case ICMD_COPY:
653                 case ICMD_MOVE:
654                         emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
655                         break;
656
657                 case ICMD_ASTORE:
658                         if (!(iptr->flags.bits & INS_FLAG_RETADDR))
659                                 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
660                         break;
661
662
663                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
664                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
665
666                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
667                                 constant_classref *cr = iptr->sx.val.c.ref;;
668                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, cr, 0);
669                                 M_AMOV_IMM(0, d);
670                         } else {
671                                 M_AMOV_IMM(iptr->sx.val.anyptr, d);
672                         }
673                         emit_store_dst(jd, iptr, d);
674                         break;
675                 /* BRANCH *************************************************************/
676
677                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
678
679                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
680                         M_ADRMOVE(s1, REG_ATMP1_XPTR);
681
682 #ifdef ENABLE_VERIFIER
683                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
684                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
685
686                                 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
687                         }
688 #endif /* ENABLE_VERIFIER */
689                         M_JSR_PCREL(2);                         /* get current PC */
690                         M_APOP(REG_ATMP2);              
691
692                         M_AMOV_IMM(asm_handle_exception, REG_ATMP3);
693                         M_JMP(REG_ATMP3);
694                         ALIGNCODENOP;
695                         break;
696
697                 case ICMD_GOTO:         /* ... ==> ...                                */
698                 case ICMD_RET:          /* ... ==> ...                                */
699
700                         emit_br(cd, iptr->dst.block);
701                         ALIGNCODENOP;
702                         break;
703
704                 case ICMD_JSR:          /* ... ==> ...                                */
705
706                         emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
707                         ALIGNCODENOP;
708                         break;
709
710
711
712                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
713                 case ICMD_IFNONNULL:
714                         assert(IS_ADR_TYPE(VAROP(iptr->s1)->type));
715                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
716                         M_ATST(s1);
717                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
718                         break;
719
720                 case ICMD_IFLT:
721                 case ICMD_IFLE:
722                 case ICMD_IFNE:
723                 case ICMD_IFGT:
724                 case ICMD_IFGE:
725                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
726
727                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
728                         assert (VAROP(iptr->s1)->type == TYPE_INT);
729                         M_ICMP_IMM(iptr->sx.val.i, s1); 
730                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
731                         break;
732
733                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
734                 case ICMD_IF_ICMPNE:
735                 case ICMD_IF_ICMPLT:
736                 case ICMD_IF_ICMPGT:
737                 case ICMD_IF_ICMPLE:
738                 case ICMD_IF_ICMPGE:
739
740                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
741                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
742                         M_ICMP(s2, s1);
743                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
744                         break;
745
746                 case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
747                 case ICMD_IF_ACMPNE:
748
749                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
750                         s2 = emit_load_s2(jd, iptr, REG_ATMP2);
751                         M_ACMP(s1, s2);
752                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
753                         break;
754
755
756                 /* MEMORY *************************************************************/
757                 case ICMD_GETSTATIC:
758                         if (INSTRUCTION_IS_UNRESOLVED(iptr))    {
759                                 assert(0);
760                         } else  {
761                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
762
763                                 fieldtype = fi->type;
764                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
765                                         codegen_addpatchref(cd, PATCHER_initialize_class, fi->class, disp);
766                                 }
767
768                                 disp = (ptrint) &(fi->value);
769                         }
770                         M_AMOV_IMM(disp, REG_ATMP1);
771                         switch (fieldtype) {
772 #if defined(ENABLE_SOFTFLOAT)
773                         case TYPE_FLT:
774 #endif
775                         case TYPE_INT:
776                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
777                                 M_ILD(d, REG_ATMP1, 0);
778                                 break;
779                         case TYPE_ADR:
780                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
781                                 M_ALD(d, REG_ATMP1, 0);
782                                 break;
783 #if defined(ENABLE_SOFTFLOAT)
784                         case TYPE_DBL:
785 #endif
786                         case TYPE_LNG:
787                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
788                                 M_LLD(d, REG_ATMP1, 0);
789                                 break;
790 #if !defined(ENABLE_SOFTFLOAT)
791                         case TYPE_FLT:
792                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
793                                 M_FLD(d, REG_ATMP1, 0);
794                                 break;
795                         case TYPE_DBL:                          
796                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
797                                 M_DLD(d, REG_ATMP1, 0);
798                                 break;
799 #endif
800                         }
801                         emit_store_dst(jd, iptr, d);
802                         break;
803
804                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
805
806                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
807                                 uf        = iptr->sx.s23.s3.uf;
808                                 fieldtype = uf->fieldref->parseddesc.fd->type;
809
810                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
811                         } else {
812                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
813                                 fieldtype = fi->type;
814                                 disp      = &(fi->value);
815
816                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
817                                         codegen_addpatchref(cd, PATCHER_initialize_class, fi->class, 0);
818                         }
819                 
820                         M_AMOV_IMM(disp, REG_ATMP1);
821                         switch (fieldtype) {
822 #if defined(ENABLE_SOFTFLOAT)
823                         case TYPE_FLT:
824 #endif
825                         case TYPE_INT:
826                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
827                                 M_IST(s1, REG_ATMP1, 0);
828                                 break;
829 #if defined(ENABLE_SOFTFLOAT)
830                         case TYPE_DBL:
831 #endif
832                         case TYPE_LNG:
833                                 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
834                                 M_LST(s1, REG_ATMP1, 0);
835                                 break;
836                         case TYPE_ADR:
837                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
838                                 M_AST(s1, REG_ATMP1, 0);
839                                 break;
840 #if !defined(ENABLE_SOFTFLOAT)
841                         case TYPE_FLT:
842                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
843                                 M_FST(s1, REG_ATMP1, 0);
844                                 break;
845                         case TYPE_DBL:
846                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
847                                 M_DST(s1, REG_ATMP1, 0);
848                                 break;
849 #endif
850                         default: assert(0);
851                         }
852                         break;
853
854                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
855
856                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
857
858                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
859                                 uf        = iptr->sx.s23.s3.uf;
860                                 fieldtype = uf->fieldref->parseddesc.fd->type;
861                                 disp      = 0;
862
863                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
864                         }
865                         else {
866                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
867                                 fieldtype = fi->type;
868                                 disp      = fi->offset;
869                         }
870
871                         /* implicit null-pointer check */
872                         switch (fieldtype) {
873 #if defined(ENABLE_SOFTFLOAT)
874                         case TYPE_FLT:
875 #endif
876                         case TYPE_INT:
877                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
878                                 M_ILD(d, s1, disp);
879                                 break;
880 #if defined(ENABLE_SOFTFLOAT)
881                         case TYPE_DBL:
882 #endif
883                         case TYPE_LNG:
884                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
885                                 if (GET_HIGH_REG(d) == s1) {
886                                         M_ILD(GET_LOW_REG(d), s1, disp + 4);
887                                         M_ILD(GET_HIGH_REG(d), s1, disp);
888                                 } else {
889                                         M_ILD(GET_HIGH_REG(d), s1, disp);
890                                         M_ILD(GET_LOW_REG(d), s1, disp + 4);
891                                 }
892                                 break;
893                         case TYPE_ADR:
894                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
895                                 M_ALD(d, s1, disp);
896                                 break;
897 #if !defined(ENABLE_SOFTFLOAT)
898                         case TYPE_FLT:
899                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
900                                 M_FLD(d, s1, disp);
901                                 break;
902                         case TYPE_DBL:                          
903                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
904                                 M_DLD(d, s1, disp);
905                                 break;
906 #endif
907                         }
908                         emit_store_dst(jd, iptr, d);
909                         break;
910
911                 case ICMD_PUTFIELD:   /* ..., value  ==> ...                          */
912
913                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
914
915                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
916                                 uf        = iptr->sx.s23.s3.uf;
917                                 fieldtype = uf->fieldref->parseddesc.fd->type;
918                                 disp      = 0;
919                         }
920                         else {
921                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
922                                 fieldtype = fi->type;
923                                 disp      = fi->offset;
924                         }
925
926                         if (IS_INT_LNG_TYPE(fieldtype)) {
927                                 if (IS_2_WORD_TYPE(fieldtype)) {
928                                         s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
929                                 } else {
930                                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
931                                 }
932                         } else {
933                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
934                         }
935
936                         if (INSTRUCTION_IS_UNRESOLVED(iptr))
937                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
938
939                         /* implicit null-pointer check */
940                         switch (fieldtype) {
941 #if defined(ENABLE_SOFTFLOAT)
942                         case TYPE_FLT:
943 #endif
944                         case TYPE_INT:
945                                 M_IST(s2, s1, disp);
946                                 break;
947
948 #if defined(ENABLE_SOFTFLOAT)
949                         case TYPE_DBL:
950 #endif
951                         case TYPE_LNG:
952                                 M_IST(GET_LOW_REG(s2), s1, disp + 4);      /* keep this order */
953                                 M_IST(GET_HIGH_REG(s2), s1, disp);         /* keep this order */
954                                 break;
955                         case TYPE_ADR:
956                                 M_AST(s2, s1, disp);
957                                 break;
958 #if !defined(ENABLE_SOFTFLOAT)
959                         case TYPE_FLT:
960                                 M_FST(s2, s1, disp);
961                                 break;
962                         case TYPE_DBL:
963                                 M_DST(s2, s1, disp);
964                                 break;
965 #endif
966                         }
967                         break;
968
969                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
970
971                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
972                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
973                         /* implicit null-pointer check */
974                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
975                         emit_store_dst(jd, iptr, d);
976                         break;
977
978                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
979
980                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
981                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
982                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
983                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
984                         M_INTMOVE(s2, REG_ITMP2);
985                         M_IADD_IMM(OFFSET(java_bytearray, data[0]), REG_ITMP2);
986                         M_ADRMOVE(s1, REG_ATMP1);
987                         M_AADDINT(REG_ITMP2, REG_ATMP1);
988                         /* implicit null-pointer check */
989                         M_LBZX(REG_ATMP1, d);
990                         M_BSEXT(d, d);
991                         emit_store_dst(jd, iptr, d);
992                         break;                  
993
994                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
995
996                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
997                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
998                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
999                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1000                         M_INTMOVE(s2, REG_ITMP2);
1001                         M_ISSL_IMM(1, REG_ITMP2);
1002                         M_IADD_IMM(OFFSET(java_chararray, data[0]), REG_ITMP2);
1003                         M_ADRMOVE(s1, REG_ATMP1);
1004                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1005                         /* implicit null-pointer check */
1006                         M_LHZX(REG_ATMP1, d);
1007                         /*M_CZEXT(d, d);*/
1008                         emit_store_dst(jd, iptr, d);
1009                         break;
1010
1011                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1012
1013                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1014                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1015                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1016                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1017                         M_INTMOVE(s2, REG_ITMP2);
1018                         M_ISSL_IMM(1, REG_ITMP2);
1019                         M_IADD_IMM(OFFSET(java_shortarray, data[0]), REG_ITMP2);
1020                         M_ADRMOVE(s1, REG_ATMP1);
1021                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1022                 
1023                         /* implicit null-pointer check */
1024                         M_LHZX(REG_ATMP1, d);
1025                         M_HSEXT(d, d);
1026                         emit_store_dst(jd, iptr, d);
1027                         break;
1028
1029                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1030
1031                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1032                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1033                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1034                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1035                         M_INTMOVE(s2, REG_ITMP2);
1036                         M_ISSL_IMM(2, REG_ITMP2);
1037                         M_IADD_IMM(OFFSET(java_intarray, data[0]), REG_ITMP2);
1038                         M_ADRMOVE(s1, REG_ATMP1);
1039                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1040         
1041                         /* implicit null-pointer check */
1042                         M_LWZX(REG_ATMP1, d);
1043                         emit_store_dst(jd, iptr, d);
1044                         break;
1045
1046 #if 0
1047                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1048                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1049                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1050                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1051                         /* implicit null-pointer check */
1052                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1053                         M_SLL_IMM(s2, 3, REG_ITMP2);
1054                         M_IADD(s1, REG_ITMP2, REG_ITMP2);
1055                         M_LLD_INTERN(d, REG_ITMP2, OFFSET(java_longarray, data[0]));
1056                         emit_store_dst(jd, iptr, d);
1057                         break;
1058
1059                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1060                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1061                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1062                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1063                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1064                         M_SLL_IMM(s2, 2, REG_ITMP2);
1065                         M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1066                         /* implicit null-pointer check */
1067                         M_LFSX(d, s1, REG_ITMP2);
1068                         emit_store_dst(jd, iptr, d);
1069                         break;
1070
1071                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1072                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1073                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1074                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1075                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1076                         M_SLL_IMM(s2, 3, REG_ITMP2);
1077                         M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1078                         /* implicit null-pointer check */
1079                         M_LFDX(d, s1, REG_ITMP2);
1080                         emit_store_dst(jd, iptr, d);
1081                         break;
1082                 #endif
1083
1084                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1085
1086                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1087                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1088                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1089                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1090                         M_INTMOVE(s2, REG_ITMP2);
1091                         M_ISSL_IMM(2, REG_ITMP2);
1092                         M_IADD_IMM(OFFSET(java_objectarray, data[0]), REG_ITMP2);
1093                         M_ADRMOVE(s1, REG_ATMP1);
1094                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1095         
1096                         /* implicit null-pointer check */
1097                         M_LAX(REG_ATMP1, d);
1098                         emit_store_dst(jd, iptr, d);
1099                         break;
1100
1101
1102                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1103
1104                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1105                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1106                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1107                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1108                         M_INTMOVE(s2, REG_ITMP2);
1109                         M_IADD_IMM(OFFSET(java_bytearray, data[0]), REG_ITMP2);
1110                         M_ADRMOVE(s1, REG_ATMP1);
1111                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1112         
1113                         /* implicit null-pointer check */
1114                         M_STBX(REG_ATMP1, s3);
1115                         break;
1116
1117                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1118
1119                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1120                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1121                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1122                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1123                         M_INTMOVE(s2, REG_ITMP2);
1124                         M_ISSL_IMM(1, REG_ITMP2);
1125                         M_IADD_IMM(OFFSET(java_chararray, data[0]), REG_ITMP2); 
1126                         M_ADRMOVE(s1, REG_ATMP1);
1127                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1128                         /* implicit null-pointer check */
1129                         M_STHX(REG_ATMP1, s3);
1130                         break;
1131
1132                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1133
1134                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1135                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1136                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1137                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1138                         M_INTMOVE(s2, REG_ITMP2);
1139                         M_ISSL_IMM(1, REG_ITMP2);
1140                         M_IADD_IMM(OFFSET(java_shortarray, data[0]), REG_ITMP2);
1141                         M_ADRMOVE(s1, REG_ATMP1);
1142                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1143                         /* implicit null-pointer check */
1144                         M_STHX(REG_ATMP1, s3);
1145                         break;
1146
1147                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1148
1149                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1150                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1151                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1152                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1153                         M_INTMOVE(s2, REG_ITMP2);
1154                         M_ISSL_IMM(1, REG_ITMP2);
1155                         M_IADD_IMM(OFFSET(java_intarray, data[0]), REG_ITMP2);
1156                         M_ADRMOVE(s1, REG_ATMP1);
1157                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1158                         /* implicit null-pointer check */
1159                         M_STWX(REG_ATMP1, s3);
1160                         break;
1161
1162 #if 0
1163                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1164                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1165                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1166                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1167                         s3 = emit_load_s3_high(jd, iptr, REG_ITMP3);
1168                         M_INTMOVE(s2, REG_ITMP2);
1169                         M_IADD_IMM(OFFSET(java_bytearray, data[0]), REG_ITMP2);
1170                         M_ISSL_IMM(1, REG_ITMP2);
1171                         M_ADRMOVE(s1, REG_ATMP1);
1172                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1173                         /* implicit null-pointer check */
1174                         M_STWX(s3, s1, REG_ITMP2);
1175                         M_IADD_IMM(REG_ITMP2, 4, REG_ITMP2);
1176                         s3 = emit_load_s3_low(jd, iptr, REG_ITMP3);
1177                         M_STWX(s3, s1, REG_ITMP2);
1178                         break;
1179
1180                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1181                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1182                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1183                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1184                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1185                         M_SLL_IMM(s2, 2, REG_ITMP2);
1186                         M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1187                         /* implicit null-pointer check */
1188                         M_STFSX(s3, s1, REG_ITMP2);
1189                         break;
1190
1191                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1192                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1193                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1194                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1195                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1196                         M_SLL_IMM(s2, 3, REG_ITMP2);
1197                         M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1198                         /* implicit null-pointer check */
1199                         M_STFDX(s3, s1, REG_ITMP2);
1200                         break;
1201
1202         #endif
1203                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1204
1205                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1206                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1207                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1208                         s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1209
1210                         /* XXX what if array is NULL */
1211                         disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1212
1213                         M_AST(s1, REG_SP, 0*4);
1214                         M_AST(s3, REG_SP, 1*4);
1215                         M_JSR_IMM(BUILTIN_canstore);    
1216                         emit_exception_check_ireg(cd, iptr);
1217
1218                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1219                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1220                         s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1221                         M_INTMOVE(s2, REG_ITMP1);
1222                         M_ISSL_IMM(2, REG_ITMP1);
1223                         M_IADD_IMM(OFFSET(java_objectarray, data[0]), REG_ITMP1);
1224                         M_INTMOVE(s1, REG_ATMP1);
1225                         M_AADDINT(REG_ITMP1, REG_ATMP1);
1226                         /* implicit null-pointer check */
1227                         M_STAX(REG_ATMP1, s3);
1228                         break;
1229
1230
1231
1232                 /* METHOD INVOCATION *********************************************************/
1233                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
1234                         bte = iptr->sx.s23.s3.bte;
1235                         md  = bte->md;
1236                         goto gen_method;
1237
1238                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
1239                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1240                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
1241                 case ICMD_INVOKEINTERFACE:
1242                         REPLACEMENT_POINT_INVOKE(cd, iptr);
1243
1244                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1245                                 lm = NULL;
1246                                 um = iptr->sx.s23.s3.um;
1247                                 md = um->methodref->parseddesc.md;
1248                         }
1249                         else {
1250                                 lm = iptr->sx.s23.s3.fmiref->p.method;
1251                                 um = NULL;
1252                                 md = lm->parseddesc;
1253                         }
1254         gen_method:
1255                         s3 = md->paramcount;
1256         
1257                         MCODECHECK((s3 << 1) + 64);
1258
1259                         /* copy arguments to stack */
1260                         for (s3 = s3 - 1; s3 >= 0; s3--)        {
1261                                 var = VAR(iptr->sx.s23.s2.args[s3]);
1262                                 /* already preallocated */
1263                                 if (var->flags & PREALLOC) continue;
1264                 
1265                                 if (!md->params[s3].inmemory) assert(0);
1266
1267                                 switch (var->type)      {
1268 #if defined(ENABLE_SOFTFLOAT)
1269                                         case TYPE_DBL:
1270 #endif
1271                                         case TYPE_LNG:
1272                                                 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
1273                                                 M_LST(d, REG_SP, md->params[s3].regoff*4);
1274                                                 break;
1275 #if defined(ENABLE_SOFTFLOAT)
1276                                         case TYPE_FLT:
1277 #endif
1278                                         case TYPE_INT:
1279                                                 d = emit_load(jd, iptr, var, REG_ITMP1);
1280                                                 M_IST(d, REG_SP, md->params[s3].regoff*4);
1281                                                 break;
1282                                         case TYPE_ADR:
1283                                                 d = emit_load(jd, iptr, var, REG_ATMP1);
1284                                                 M_AST(d, REG_SP, md->params[s3].regoff*4);
1285                                                 break;
1286 #if !defined(ENABLE_SOFTFLOAT)
1287                                         case TYPE_FLT:
1288                                         case TYPE_DBL:
1289 #endif
1290                                         default:
1291                                                 assert(0);
1292                                 }
1293                         }
1294
1295                         /* arguments in place now */
1296                         switch(iptr->opc)       {
1297                                 case ICMD_BUILTIN: 
1298                                         disp = (ptrint) bte->fp;
1299                                         d = md->returntype.type;
1300                                         M_JSR_IMM(disp);
1301
1302                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1303                                         /*emit_exception_check(cd, iptr); TODO */
1304                                         break;
1305
1306                                 case ICMD_INVOKESPECIAL: 
1307                                         /* adress register for sure */
1308                                         M_ALD(REG_ATMP1, REG_SP, 0);
1309                                         emit_nullpointer_check(cd, iptr, REG_ATMP1);
1310                                         /* fall through */
1311                                 case ICMD_INVOKESTATIC: 
1312                                         if (lm == NULL) {
1313                                                 codegen_addpatchref(cd, PATCHER_invokestatic_special, um, 0);
1314                                                 disp = 0;
1315                                                 M_AMOV_IMM(disp, REG_ATMP1);
1316                                         } else  {
1317                                                 disp = lm->stubroutine;
1318                                                 M_AMOV_IMM(disp, REG_ATMP1);
1319                                         }
1320
1321                                         /* generate the actual call */
1322                                         M_JSR(REG_ATMP1);
1323                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1324                                         break;
1325
1326
1327                                 case ICMD_INVOKEVIRTUAL:
1328                                         if (lm == NULL) {
1329                                                 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
1330                                                 s1 = 0;
1331                                         } else {
1332                                                 s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
1333                                         }
1334                                         /* load object pointer (==argument 0) */
1335                                         M_ALD(REG_ATMP1, REG_SP, 0);
1336                                         /* implicit null-pointer check */
1337                                         M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_objectheader, vftbl));
1338                                         M_ALD(REG_ATMP1, REG_METHODPTR, s1);
1339                                         /* generate the actual call */
1340                                         M_JSR(REG_ATMP1);
1341                                         break;
1342                                 case ICMD_INVOKEINTERFACE: 
1343                                         if (lm == NULL) {
1344                                                 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
1345
1346                                                 s1 = 0;
1347                                                 s2 = 0;
1348                                         } else {
1349                                                 s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->class->index;
1350                                                 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1351                                         }
1352                                         /* load object pointer (==argument 0) */
1353                                         M_ALD(REG_ATMP1, REG_SP, 0);
1354
1355                                         /* implicit null-pointer check */
1356                                         M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_objectheader, vftbl));
1357                                         M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
1358                                         M_ALD(REG_ATMP1, REG_METHODPTR, s2);
1359
1360                                         /* generate the actual call */
1361                                         M_JSR(REG_ATMP1);
1362                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1363                                         break;
1364
1365                                 default: assert(0);
1366                                 }       /* switch (iptr->opc) */
1367
1368                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1369                                 
1370                                 /* store return value */
1371                                 d = md->returntype.type;
1372
1373                                 switch (d)      {
1374                                         case TYPE_VOID: break;
1375 #if defined(ENABLE_SOFTFLOAT)
1376                                         case TYPE_FLT:
1377 #endif
1378                                         case TYPE_INT:
1379                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1380                                                 M_INTMOVE(REG_RESULT, s1);
1381                                                 break;
1382 #if defined(ENABLE_SOFTFLOAT)
1383                                         case TYPE_DBL:
1384 #endif
1385                                         case TYPE_LNG:
1386                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1387                                                 M_LNGMOVE(REG_RESULT_PACKED, s1);
1388                                                 break;
1389                                         case TYPE_ADR:
1390                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_ATMP1);
1391                                                 /* all stuff is returned in %d0 */
1392                                                 M_INT2ADRMOVE(REG_RESULT, s1);
1393                                                 break;
1394 #if !defined(ENABLE_SOFTFLOAT)
1395                                         case TYPE_FLT:
1396                                         case TYPE_DBL:
1397 #endif
1398                                         default:
1399                                                 assert(0);
1400                                 }
1401                                 if (d != TYPE_VOID) emit_store_dst(jd, iptr, s1);
1402                         break; /* ICMD_INVOKE* */
1403
1404 #if defined(ENABLE_SOFTFLOAT)
1405                 case ICMD_FRETURN:
1406 #endif
1407                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
1408
1409                         REPLACEMENT_POINT_RETURN(cd, iptr);
1410                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
1411                         M_INTMOVE(s1, REG_RESULT);
1412                         goto nowperformreturn;
1413
1414                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
1415
1416                         REPLACEMENT_POINT_RETURN(cd, iptr);
1417                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
1418                         assert(VAROP(iptr->s1)->type == TYPE_ADR);
1419                         M_ADR2INTMOVE(s1, REG_RESULT);
1420
1421 #ifdef ENABLE_VERIFIER
1422                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1423                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
1424
1425                                 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
1426                         }
1427 #endif /* ENABLE_VERIFIER */
1428                         goto nowperformreturn;
1429
1430 #if defined(ENABLE_SOFTFLOAT)
1431                 case ICMD_DRETURN:
1432 #endif
1433                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
1434
1435                         REPLACEMENT_POINT_RETURN(cd, iptr);
1436                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
1437                         M_LNGMOVE(s1, REG_RESULT_PACKED);
1438                         goto nowperformreturn;
1439
1440 #if !defined(ENABLE_SOFTFLOAT)
1441                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
1442                 case ICMD_DRETURN:
1443
1444                         REPLACEMENT_POINT_RETURN(cd, iptr);
1445                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1446                         M_FLTMOVE(s1, REG_FRESULT);
1447                         goto nowperformreturn;
1448 #endif
1449
1450                 case ICMD_RETURN:      /* ...  ==> ...                                */
1451
1452                         REPLACEMENT_POINT_RETURN(cd, iptr);
1453
1454 nowperformreturn:
1455                         {
1456                         s4 i, p;
1457                         
1458                         p = cd->stackframesize;
1459
1460                         /* call trace function */
1461 #if !defined(NDEBUG)
1462                         emit_verbosecall_exit(jd);
1463 #endif
1464
1465 #if defined(ENABLE_THREADS)
1466                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1467                                 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
1468                                 M_ALD(REG_ITMP3, REG_PV, disp);
1469                                 M_MTCTR(REG_ITMP3);
1470
1471                                 /* we need to save the proper return value */
1472
1473                                 switch (iptr->opc) {
1474                                 case ICMD_LRETURN:
1475                                         M_IST(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
1476                                         /* fall through */
1477                                 case ICMD_IRETURN:
1478                                 case ICMD_ARETURN:
1479                                         M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
1480                                         break;
1481                                 case ICMD_FRETURN:
1482                                         M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
1483                                         break;
1484                                 case ICMD_DRETURN:
1485                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
1486                                         break;
1487                                 }
1488
1489                                 M_ALD(REG_A0, REG_SP, rd->memuse * 4);
1490                                 M_JSR;
1491
1492                                 /* and now restore the proper return value */
1493
1494                                 switch (iptr->opc) {
1495                                 case ICMD_LRETURN:
1496                                         M_ILD(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
1497                                         /* fall through */
1498                                 case ICMD_IRETURN:
1499                                 case ICMD_ARETURN:
1500                                         M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
1501                                         break;
1502                                 case ICMD_FRETURN:
1503                                         M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
1504                                         break;
1505                                 case ICMD_DRETURN:
1506                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
1507                                         break;
1508                                 }
1509                         }
1510 #endif
1511
1512
1513                         /* restore return address                                         */
1514 #if 0
1515                         if (!jd->isleafmethod) {
1516                                 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
1517                                    may have a displacement overflow. */
1518
1519                                 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
1520                                 M_MTLR(REG_ITMP1);
1521                         }
1522 #endif
1523                         /* restore saved registers                                        */
1524
1525                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
1526                                 p--; M_ILD(rd->savintregs[i], REG_SP, p * 4);
1527                         }
1528                         for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
1529                                 p--; M_ALD(rd->savadrregs[i], REG_SP, p*4);
1530                         }
1531 #if !defined(ENABLE_SOFTFLOAT)
1532                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
1533                                 p -= 2; M_DLD(rd->savfltregs[i], REG_SP, p * 4);
1534                         }
1535 #endif
1536                         /* deallocate stack                                               */
1537                         M_AADD_IMM(cd->stackframesize*4, REG_SP);
1538                         M_RET;
1539                         }
1540                         break;
1541
1542                 /* the evil ones */
1543                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
1544                                       /* val.a: (classinfo*) superclass               */
1545
1546                         /*  superclass is an interface:
1547                          *
1548                          *  return (sub != NULL) &&
1549                          *         (sub->vftbl->interfacetablelength > super->index) &&
1550                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
1551                          *
1552                          *  superclass is a class:
1553                          *
1554                          *  return ((sub != NULL) && (0
1555                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1556                          *          super->vftbl->diffvall));
1557                          */
1558
1559                         {
1560                         classinfo *super;
1561                         s4         superindex;
1562
1563                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1564                                 super      = NULL;
1565                                 superindex = 0;
1566                         }
1567                         else {
1568                                 super      = iptr->sx.s23.s3.c.cls;
1569                                 superindex = super->index;
1570                         }
1571                         
1572 #if defined(ENABLE_THREADS)
1573                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
1574 #endif
1575                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1576                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1577
1578                         assert(VAROP(iptr->s1 )->type == TYPE_ADR);
1579                         assert(VAROP(iptr->dst)->type == TYPE_INT);
1580
1581                         M_ICLR(d);
1582
1583                         /* if class is not resolved, check which code to call */
1584
1585                         if (super == NULL) {
1586                                 M_ATST(s1);
1587                                 emit_label_beq(cd, BRANCH_LABEL_1);
1588
1589                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
1590
1591                                 M_IMOV_IMM32(0, REG_ITMP3);
1592                                 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
1593                                 emit_label_beq(cd, BRANCH_LABEL_2);
1594                         }
1595
1596                         /* interface instanceof code */
1597
1598                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1599                                 if (super == NULL) {
1600                                         codegen_addpatchref(cd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
1601                                 } else {
1602                                         M_ATST(s1);
1603                                         emit_label_beq(cd, BRANCH_LABEL_3);
1604                                 }
1605
1606                                 M_ALD(REG_ATMP1, s1, OFFSET(java_objectheader, vftbl));
1607                                 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
1608                                 M_IADD_IMM(-superindex, REG_ITMP3);     /* -superindex may be patched patched */
1609                                 M_ITST(REG_ITMP3);
1610                                 M_BLE(10);
1611                                 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patch here too! */
1612                                 M_ATST(REG_ATMP1);
1613                                 M_BEQ(2);
1614                                 M_IMOV_IMM(1, d);
1615
1616                                 if (super == NULL)
1617                                         emit_label_br(cd, BRANCH_LABEL_4);
1618                                 else
1619                                         emit_label(cd, BRANCH_LABEL_3);
1620                         }
1621
1622                         /* class instanceof code */
1623
1624                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
1625                                 if (super == NULL) {
1626                                         emit_label(cd, BRANCH_LABEL_2);
1627
1628                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
1629                                         M_AMOV_IMM(0, REG_ATMP2);
1630                                 } else {
1631                                         M_AMOV_IMM(super->vftbl, REG_ATMP2);
1632                                         M_ATST(s1);
1633                                         emit_label_beq(cd, BRANCH_LABEL_5);
1634                                 }
1635
1636                                 M_ALD(REG_ATMP1, s1, OFFSET(java_objectheader, vftbl));
1637 #if defined(ENABLE_THREADS)
1638                                 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
1639 #endif
1640                                 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
1641                                 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
1642                                 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
1643 #if defined(ENABLE_THREADS)
1644                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
1645 #endif
1646                                 M_ISUB(REG_ITMP3, REG_ITMP1);
1647                                 M_ICMP(REG_ITMP1, REG_ITMP2);
1648                                 M_BGT(4);
1649                                 M_IMOV_IMM(1, d);
1650                                 M_TPFW;                 /* overlaps next instruction */
1651                                 M_ICLR(d);
1652
1653                                 if (super != NULL)
1654                                         emit_label(cd, BRANCH_LABEL_5);
1655                         }
1656
1657                         if (super == NULL) {
1658                                 emit_label(cd, BRANCH_LABEL_1);
1659                                 emit_label(cd, BRANCH_LABEL_4);
1660                         }
1661
1662                         emit_store_dst(jd, iptr, d);
1663                         }
1664                         break;
1665
1666                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
1667                                       /* val.a: (classinfo*) superclass               */
1668
1669                         /*  superclass is an interface:
1670                          *
1671                          *  OK if ((sub == NULL) ||
1672                          *         (sub->vftbl->interfacetablelength > super->index) &&
1673                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
1674                          *
1675                          *  superclass is a class:
1676                          *
1677                          *  OK if ((sub == NULL) || (0
1678                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1679                          *         super->vftbl->diffvall));
1680                          */
1681
1682                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
1683                                 /* object type cast-check */
1684
1685                                 classinfo *super;
1686                                 s4         superindex;
1687
1688                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1689                                         super      = NULL;
1690                                         superindex = 0;
1691                                 }
1692                                 else {
1693                                         super      = iptr->sx.s23.s3.c.cls;
1694                                         superindex = super->index;
1695                                 }
1696
1697 #if defined(ENABLE_THREADS)
1698                                 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
1699 #endif
1700
1701                                 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1702                                 assert(VAROP(iptr->s1)->type == TYPE_ADR);
1703
1704                                 /* if class is not resolved, check which code to call */
1705
1706                                 if (super == NULL) {
1707                                         M_ATST(s1);
1708                                         emit_label_beq(cd, BRANCH_LABEL_1);
1709
1710                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
1711                         
1712                                         M_IMOV_IMM32(0, REG_ITMP2);
1713                                         M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
1714                                         emit_label_beq(cd, BRANCH_LABEL_2);
1715                                 }
1716
1717                                 /* interface checkcast code */
1718
1719                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1720                                         if (super == NULL) {
1721                                                 codegen_addpatchref(cd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
1722                                         } else {
1723                                                 M_ATST(s1);
1724                                                 emit_label_beq(cd, BRANCH_LABEL_3);
1725                                         }
1726
1727                                         M_ALD(REG_ATMP2, s1, OFFSET(java_objectheader, vftbl));
1728                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
1729         
1730                                         M_IADD_IMM(-superindex, REG_ITMP3);     /* superindex patched */
1731                                         M_ITST(REG_ITMP3);
1732                                         emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
1733
1734                                         M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patched*/
1735                                         M_ATST(REG_ATMP3);
1736                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
1737
1738                                         if (super == NULL)
1739                                                 emit_label_br(cd, BRANCH_LABEL_4);
1740                                         else
1741                                                 emit_label(cd, BRANCH_LABEL_3);
1742                                 }
1743
1744                                 /* class checkcast code */
1745
1746                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
1747                                         if (super == NULL) {
1748                                                 emit_label(cd, BRANCH_LABEL_2);
1749
1750                                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
1751                                                 M_AMOV_IMM(0, REG_ATMP3);
1752                                         } else {
1753                                                 M_AMOV_IMM(super->vftbl, REG_ATMP3);
1754                                                 M_ATST(s1);
1755                                                 emit_label_beq(cd, BRANCH_LABEL_5);
1756                                         }
1757
1758                                         M_ALD(REG_ATMP2, s1, OFFSET(java_objectheader, vftbl));
1759 #if defined(ENABLE_THREADS)
1760                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
1761 #endif
1762                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));  /* REG_ITMP3 == sub->vftbl->baseval */
1763 #if 0
1764                                         if (s1 != REG_ATMP1) {
1765 #endif
1766                                                 M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
1767                                                 M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
1768 #if defined(ENABLE_THREADS)
1769                                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
1770 #endif
1771                                                 M_ISUB(REG_ITMP1, REG_ITMP3);
1772                                                 M_ICMP(REG_ITMP2, REG_ITMP1);   /* XXX was CMPU */
1773 #if 0                                   
1774                                         } else {
1775                                                 assert(0);
1776                                                 M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, baseval));
1777                                                 M_ISUB(REG_ITMP3, REG_ITMP2);
1778                                                 M_ILD(REG_ITMP3, REG_ATMP3, OFFSET(vftbl_t, diffval));
1779                                                 M_ICMP(REG_ITMP2, REG_ITMP3);   /* XXX was CMPU */
1780 #if defined(ENABLE_THREADS)
1781                                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
1782 #endif
1783                                         }
1784 #endif
1785                                         emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
1786
1787                                         if (super != NULL)
1788                                                 emit_label(cd, BRANCH_LABEL_5);
1789                                 }
1790
1791                                 if (super == NULL) {
1792                                         emit_label(cd, BRANCH_LABEL_1);
1793                                         emit_label(cd, BRANCH_LABEL_4);
1794                                 }
1795
1796                                 d = codegen_reg_of_dst(jd, iptr, s1);
1797                         } else {
1798                                 /* array type cast-check */
1799
1800                                 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
1801
1802                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1803                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
1804                                         M_AMOV_IMM(0, REG_ATMP1);
1805                                 } else {
1806                                         M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
1807                                 }
1808         
1809                                 M_APUSH(s1);
1810                                 M_APUSH(REG_ATMP1);
1811                                 M_JSR_IMM(BUILTIN_arraycheckcast);
1812                                 M_AADD_IMM(2*4, REG_SP);                /* pop arguments off stack */
1813                                 M_ITST(REG_RESULT);
1814                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
1815
1816                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1817                                 d = codegen_reg_of_dst(jd, iptr, s1);
1818                         }
1819                         assert(VAROP(iptr->dst)->type == TYPE_ADR);
1820                         M_ADRMOVE(s1, d);
1821                         emit_store_dst(jd, iptr, d);
1822                         break;
1823
1824                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
1825                         {
1826                         s4 i, l;
1827                         branch_target_t *table;
1828
1829                         table = iptr->dst.table;
1830
1831                         l = iptr->sx.s23.s2.tablelow;
1832                         i = iptr->sx.s23.s3.tablehigh;
1833                         
1834                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1835                         M_INTMOVE(s1, REG_ITMP1);
1836                         if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
1837
1838                         i = i - l + 1;
1839
1840                         /* range check */
1841                         M_ICMP_IMM(i - 1, REG_ITMP1);
1842                         emit_bugt(cd, table[0].block);
1843
1844                         /* build jump table top down and use address of lowest entry */
1845                         table += i;
1846
1847                         while (--i >= 0) {
1848                                 dseg_add_target(cd, table->block); 
1849                                 --table;
1850                         }
1851
1852                         /* length of dataseg after last dseg_add_target is used by load */
1853                         M_AMOV_IMM(0, REG_ATMP2);
1854                         dseg_adddata(cd);
1855
1856                         M_ISSL_IMM(2, REG_ITMP1);                       /* index * 4 == offset in table */
1857                         M_AADDINT(REG_ITMP1, REG_ATMP2);                /* offset in table */
1858                         M_AADD_IMM(-(cd->dseglen), REG_ATMP2);          /* start of table in dseg */
1859                         M_ALD(REG_ATMP1, REG_ATMP2, 0);
1860
1861                         M_JMP(REG_ATMP1);
1862                         ALIGNCODENOP;
1863                         }
1864                         break;
1865
1866                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
1867                         {
1868                         s4 i;
1869                         lookup_target_t *lookup;
1870
1871                         lookup = iptr->dst.lookup;
1872
1873                         i = iptr->sx.s23.s2.lookupcount;
1874                         
1875                         MCODECHECK((i<<2)+8);
1876                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1877
1878                         while (--i >= 0) {
1879                                 M_ICMP_IMM(lookup->value, s1);
1880                                 emit_beq(cd, lookup->target.block);
1881                                 lookup++;
1882                         }
1883
1884                         emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
1885                         ALIGNCODENOP;
1886                         break;
1887                         }
1888
1889
1890                 default:
1891                         printf("UNKNOWN OPCODE %d\n", iptr->opc);
1892                         exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc);
1893                         return false;
1894         } /* switch */
1895         M_TPF;
1896         } /* for each instruction */
1897         } /* if (btpre->flags >= BBREACHED) */
1898         } /* for each basic block */
1899
1900         dseg_createlinenumbertable(cd);
1901
1902         /* generate stubs */
1903         emit_patcher_stubs(jd);
1904         REPLACEMENT_EMIT_STUBS(jd);
1905
1906         return true;
1907 }
1908
1909 /* createnativestub ************************************************************
1910
1911    Creates a stub routine which calls a native method.
1912
1913 *******************************************************************************/
1914 u1* createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) 
1915 {
1916         methodinfo   *m;
1917         codeinfo     *code;
1918         codegendata  *cd;
1919         registerdata *rd;
1920         methoddesc   *md;
1921         s4 nativeparams, i, j, t, s1, s2;
1922         
1923         /* get required compiler data */
1924
1925         m    = jd->m;
1926         code = jd->code;
1927         cd   = jd->cd;
1928         rd   = jd->rd;
1929
1930         md = m->parseddesc;
1931         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
1932
1933         /* calc stackframe size */
1934         cd->stackframesize =    sizeof(stackframeinfo) / SIZEOF_VOID_P +
1935                                 sizeof(localref_table) / SIZEOF_VOID_P +
1936                                 nmd->memuse +
1937                                 4 +                                             /* %d0,%d1,%a0,%a1*/
1938                                 2 * 2 +                                         /* %f0,%f1 */
1939                                 1 +                                             /* functionptr */
1940                                 4;                                              /* args for codegen_start_native_call */
1941
1942         /* create method header */
1943         (void) dseg_add_unique_address(cd, code);                      /* CodeinfoPointer */
1944         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4);         /* FrameSize       */
1945         (void) dseg_add_unique_s4(cd, 0);                              /* IsSync          */
1946         (void) dseg_add_unique_s4(cd, 0);                              /* IsLeaf          */
1947         (void) dseg_add_unique_s4(cd, 0);                              /* IntSave         */
1948         (void) dseg_add_unique_s4(cd, 0);                              /* FltSave         */
1949         (void) dseg_addlinenumbertablesize(cd);
1950         (void) dseg_add_unique_s4(cd, 0);                              /* ExTableSize     */
1951
1952         /* print call trace */
1953 #if !defined(NDEBUG)
1954         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
1955                 emit_verbosecall_enter(jd);
1956         }
1957 #endif
1958
1959         /* generate code */
1960         M_AADD_IMM(-(cd->stackframesize*4), REG_SP);
1961
1962         /* get function address (this must happen before the stackframeinfo) */
1963 #if !defined(WITH_STATIC_CLASSPATH)
1964         if (f == NULL)  {
1965                 codegen_addpatchref(cd, PATCHER_resolve_native_function, m, 0);
1966                 /*M_AMOV_IMM(0, REG_ATMP2);*/
1967         }
1968 #endif
1969         M_AMOV_IMM(f, REG_ATMP2); /* do not move this line, the patcher is needed */
1970
1971         M_AST(REG_ATMP2, REG_SP, 4 * 4);
1972
1973         /* save integer and float temp registers */
1974         /*
1975         M_IST(REG_D0, REG_SP, 4*4 + 2*8 + 3*4);
1976         M_IST(REG_D1, REG_SP, 4*4 + 2*8 + 2*4);
1977         M_AST(REG_A0, REG_SP, 4*4 + 2*8 + 1*4);
1978         M_AST(REG_A1, REG_SP, 4*4 + 2*8 + 0*4);
1979         */
1980
1981         /* TODO */
1982         /* store %f0, %f1 */
1983
1984         /* put arguments for codegen_start_native_call onto stack */
1985         /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
1986         
1987         M_AMOV(REG_SP, REG_ATMP1);
1988         M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1);
1989
1990         M_ALD(REG_ATMP3, REG_ATMP1, 0 * 4);
1991         M_AST(REG_ATMP3, REG_SP, 3 * 4);                /* ra */
1992
1993         M_AST(REG_ATMP1, REG_SP, 0 * 4);                /* datasp */
1994
1995         M_AADD_IMM(1 * 4 , REG_ATMP1);                  
1996         M_AST(REG_ATMP1, REG_SP, 2 * 4);                /* sp */
1997
1998         M_AMOV_IMM(0, REG_ATMP2);                       /* 0 needs to patched */
1999         dseg_adddata(cd);                               /* this patches it */
2000
2001         M_AST(REG_ATMP2, REG_SP, 1 * 4);                /* pv */
2002
2003         M_JSR_IMM(codegen_start_native_call);
2004
2005         /* load function pointer */
2006         M_ALD(REG_ATMP2, REG_SP, 4 * 4);
2007
2008         /* copy arguments into stackframe */
2009         for (i = md->paramcount -1, j = i + nativeparams; i >= 0; --i, --j)     {
2010                 t = md->paramtypes[i].type;
2011                 /* all arguments via stack */
2012                 assert(md->params[i].inmemory);                                         
2013
2014                 s1 = (md->params[i].regoff + cd->stackframesize + 1) * 4;
2015                 s2 = nmd->params[j].regoff * 4;
2016
2017                 /* simply copy argument stack */
2018                 M_ILD(REG_ITMP1, REG_SP, s1);
2019                 M_IST(REG_ITMP1, REG_SP, s2);
2020                 if (IS_2_WORD_TYPE(t))  {
2021                         M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2022                         M_IST(REG_ITMP1, REG_SP, s2 + 4);
2023                 }
2024         }
2025
2026         /* for static function class as second arg */
2027         if (m->flags & ACC_STATIC)      {
2028                 M_AMOV_IMM(m->class, REG_ATMP1);
2029                 M_AST(REG_ATMP1, REG_SP, 1 * 4);
2030         }
2031         /* env ist first argument */
2032         M_AMOV_IMM(_Jv_env, REG_ATMP1);
2033         M_AST(REG_ATMP1, REG_SP, 0 * 4);
2034
2035         /* call the native function */
2036         M_JSR(REG_ATMP2);
2037
2038         /* save return value */
2039         switch (md->returntype.type)    {
2040                 case TYPE_VOID: break;
2041
2042 #if defined(ENABLE_SOFTFLOAT)
2043                 case TYPE_DBL:
2044 #endif
2045                 case TYPE_LNG:
2046                         M_IST(REG_D1, REG_SP, 2 * 4);
2047                         /* fall through */
2048
2049 #if defined(ENABLE_SOFTFLOAT)
2050                 case TYPE_FLT:
2051 #endif
2052                 case TYPE_INT:
2053                 case TYPE_ADR:
2054                         M_IST(REG_D0, REG_SP, 1 * 4);
2055                         break;
2056
2057 #if !defined(ENABLE_SOFTFLOAT)
2058                 case TYPE_FLT:
2059                 case TYPE_DBL:  /* FIXME */
2060 #endif
2061                 default: assert(0);
2062         }
2063         
2064         /* print call trace */
2065 #if ! defined(NDEBUG)
2066         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2067                 emit_verbosecall_exit(jd);
2068         }
2069 #endif
2070         /* remove native stackframe info */
2071         /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
2072
2073         M_AMOV(REG_SP, REG_ATMP3);
2074         M_AADD_IMM(cd->stackframesize * 4, REG_ATMP3);
2075         M_AST(REG_ATMP3, REG_SP, 0 * 4);                        /* datasp */
2076         M_JSR_IMM(codegen_finish_native_call);
2077         
2078         M_INT2ADRMOVE(REG_RESULT, REG_ATMP3);
2079         /* restore return value */
2080         switch (md->returntype.type)    {
2081                 case TYPE_VOID: break;
2082
2083 #if defined(ENABLE_SOFTFLOAT)
2084                 case TYPE_DBL:
2085 #endif
2086                 case TYPE_LNG:
2087                         M_ILD(REG_D1, REG_SP, 2 * 4);
2088                         /* fall through */
2089 #if defined(ENABLE_SOFTFLOAT)
2090                 case TYPE_FLT:
2091 #endif
2092                 case TYPE_INT:
2093                 case TYPE_ADR:
2094                         M_ILD(REG_D0, REG_SP, 1 * 4);
2095                         break;
2096
2097 #if !defined(ENABLE_SOFTFLOAT)
2098                 case TYPE_FLT:
2099                 case TYPE_DBL:  /* FIXME */
2100 #endif
2101                 default: assert(0);
2102         }
2103         /* restore saved registers */
2104
2105         M_AADD_IMM(cd->stackframesize*4, REG_SP);
2106         /* check for exception */
2107         M_ATST(REG_ATMP3);
2108         M_BNE(2);
2109         M_RET;
2110
2111         /* handle exception */
2112         M_JSR_IMM(0);   /* FIXME */
2113
2114
2115         /* generate patcher stub call code */
2116         emit_patcher_stubs(jd);
2117         codegen_finish(jd);
2118
2119         return code->entrypoint;
2120 }
2121
2122 /* createcompilerstub **********************************************************
2123
2124    Creates a stub routine which calls the compiler.
2125         
2126 *******************************************************************************/
2127
2128 #define COMPILERSTUB_DATASIZE (3 * SIZEOF_VOID_P)
2129 #define COMPILERSTUB_CODESIZE (6+6+6+2)
2130 #define COMPILERSTUB_SIZE (COMPILERSTUB_DATASIZE +  COMPILERSTUB_CODESIZE)
2131 u1* createcompilerstub(methodinfo *m) 
2132
2133         u1          *s;
2134         ptrint      *d;
2135         codegendata *cd;
2136         s4          dumpsize;
2137
2138         s = CNEW(u1, COMPILERSTUB_SIZE);
2139         
2140         /* set data and code pointer */
2141         d = (ptrint *)s;
2142         s = s + COMPILERSTUB_DATASIZE;
2143
2144         /* mark start of dump memory area */
2145         dumpsize = dump_size();
2146         cd = DNEW(codegendata);
2147         cd->mcodeptr = s;
2148
2149         /* Store codeinfo pointer in the same place as in the
2150          * methodheader for compiled methods */
2151         d[0] = (ptrint) asm_call_jit_compiler;
2152         d[1] = (ptrint) m;
2153         d[2] = (ptrint) &d[1];          /* fake code->m */
2154
2155         M_AMOV_IMM(m, REG_ATMP1);
2156         M_AMOV_IMM(asm_call_jit_compiler, REG_ATMP3);
2157         M_JMP_IMM(asm_call_jit_compiler);
2158         M_RET;
2159         
2160         md_cacheflush((u1 *) d, COMPILERSTUB_SIZE);
2161 #if defined(ENABLE_STATISTICS)
2162         if (opt_stat)
2163                 count_cstub_len += COMPILERSTUB_SIZE;
2164 #endif
2165
2166         /* release dump area */
2167         dump_release(dumpsize);
2168
2169         return s;
2170 }