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