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