* src/vm/jit/m68k/codegen.c: Boilerplate added.
[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 #if defined(ENABLE_THREADS)
45 # include "threads/native/lock.h"
46 #endif
47
48 #include "vm/builtin.h"
49 #include "vm/exceptions.h"
50 #include "vm/global.h"
51 #include "vm/stringlocal.h"
52 #include "vm/vm.h"
53
54 #include "vm/jit/asmpart.h"
55 #include "vm/jit/codegen-common.h"
56 #include "vm/jit/dseg.h"
57 #include "vm/jit/emit-common.h"
58 #include "vm/jit/jit.h"
59 #include "vm/jit/parse.h"
60 #include "vm/jit/patcher.h"
61 #include "vm/jit/reg.h"
62 #include "vm/jit/replace.h"
63 #include "vm/jit/stacktrace.h"
64 #include "vm/jit/md.h"
65
66 #include "vmcore/loader.h"
67 #include "vmcore/options.h"
68 #include "vmcore/utf8.h"
69
70
71 bool codegen_emit(jitdata *jd) 
72 {       
73         methodinfo         *m;
74         codeinfo           *code;
75         codegendata        *cd;
76         registerdata       *rd;
77         s4                  len, s1, s2, s3, d, disp;
78         ptrint              a;
79         varinfo            *var;
80         basicblock         *bptr;
81         instruction        *iptr;
82         exception_entry    *ex;
83         u2                  currentline;
84         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
85         unresolved_method  *um;
86         builtintable_entry *bte;
87         methoddesc         *md;
88         s4                  fieldtype;
89         s4                  varindex;
90         unresolved_field   *uf;
91         fieldinfo          *fi;
92
93         /* get required compiler data */
94
95         m    = jd->m;
96         code = jd->code;
97         cd   = jd->cd;
98         rd   = jd->rd;
99
100         /* prevent compiler warnings */
101
102         d = 0;
103         lm = NULL;
104         bte = NULL;
105
106         {
107                 s4 i, p, t, l;
108                 /* save calle saved registers */
109                 s4 savedregs_num = 0;
110
111                 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
112                 savedregs_num += (ADR_SAV_CNT - rd->savadrreguse);
113                 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
114
115                 cd->stackframesize = rd->memuse + savedregs_num;
116 #if defined(ENABLE_THREADS)
117                 assert(0);
118 #endif
119         
120                 /* create method header */
121                 (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
122                 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
123 #if defined(ENABLE_THREADS)
124                 if (checksync && (m->flags & ACC_SYNCHRONIZED))
125                         (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4);/* IsSync         */
126                 else
127 #endif
128                         (void) dseg_add_unique_s4(cd, 0);                  /* IsSync          */
129                 (void) dseg_add_unique_s4(cd, jd->isleafmethod);       /* IsLeaf          */
130                 (void) dseg_add_unique_s4(cd, 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
477                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
478                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
479                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
480                         emit_arithmetic_check(cd, iptr, s2);
481
482                         M_INTMOVE(s1, REG_ITMP1);
483                         M_IDIV(s2, REG_ITMP1);
484                         M_INTMOVE(REG_ITMP1, d);
485
486                         emit_store_dst(jd, iptr, d);
487                         break;
488
489                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
490
491                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
492                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
493                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
494                         emit_arithmetic_check(cd, iptr, s2);
495
496                         M_IREM(s2, s1, REG_ITMP3);
497                         M_INTMOVE(REG_ITMP3, d);
498
499                         emit_store_dst(jd, iptr, d);
500                         break;
501
502                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
503                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
504
505                         bte = iptr->sx.s23.s3.bte;
506                         md  = bte->md;
507
508                         s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
509                         M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
510                         M_IOR(GET_HIGH_REG(s2), REG_ITMP3);
511                         /* XXX could be optimized */
512                         emit_arithmetic_check(cd, iptr, REG_ITMP3);
513
514                         M_LST(s2, REG_SP, 2 * 4);
515                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
516                         M_LST(s1, REG_SP, 0 * 4);
517
518                         M_JSR_IMM(bte->fp);
519
520                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
521                         M_LNGMOVE(REG_RESULT_PACKED, d);
522                         emit_store_dst(jd, iptr, d);
523                         break;
524
525                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
526
527                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
528                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
529                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
530                         M_INTMOVE(s2, REG_ITMP2);
531                         M_IMUL(s1, REG_ITMP2);
532                         M_INTMOVE(REG_ITMP2, d);
533                         emit_store_dst(jd, iptr, d);
534                         break;
535
536                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
537                                       /* sx.val.i = constant                          */
538                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
539                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
540                         M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
541                         M_IMUL(s1, REG_ITMP2);
542                         M_INTMOVE(REG_ITMP2, d);
543                         emit_store_dst(jd, iptr, d);
544                         break;
545
546                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
547
548                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
549                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
550                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
551                         M_INTMOVE(s1, REG_ITMP1);
552                         M_INTMOVE(s2, REG_ITMP2);
553                         M_IAND_IMM(0x1f, REG_ITMP2);
554                         M_ISSL(REG_ITMP2, REG_ITMP1);
555                         M_INTMOVE(REG_ITMP1, d);
556                         emit_store_dst(jd, iptr, d);
557                         break;
558
559                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
560                                       /* sx.val.i = constant                          */
561
562                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
563                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
564                         M_INTMOVE(s1, REG_ITMP1)
565                         M_ISSL_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
566                         M_INTMOVE(REG_ITMP1, d);
567                         emit_store_dst(jd, iptr, d);
568                         break;
569
570                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
571
572                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
573                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
574                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
575                         M_INTMOVE(s1, REG_ITMP1);
576                         M_INTMOVE(s2, REG_ITMP2);
577                         M_IAND_IMM(0x1f, REG_ITMP2);
578                         M_ISSR(REG_ITMP2, REG_ITMP1);
579                         M_INTMOVE(REG_ITMP1, d);
580                         emit_store_dst(jd, iptr, d);
581                         break;
582
583                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
584                                       /* sx.val.i = constant                          */
585
586                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
587                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
588                         M_INTMOVE(s1, REG_ITMP1)
589                         M_ISSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
590                         M_INTMOVE(REG_ITMP1, d);
591                         emit_store_dst(jd, iptr, d);
592                         break;
593
594                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
595
596                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
597                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
598                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
599                         M_INTMOVE(s1, REG_ITMP1);
600                         M_INTMOVE(s2, REG_ITMP2);
601                         M_IAND_IMM(0x1f, REG_ITMP2);
602                         M_IUSR(REG_ITMP2, REG_ITMP1);
603                         M_INTMOVE(REG_ITMP1, d);
604                         emit_store_dst(jd, iptr, d);
605                         break;
606
607                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
608                                       /* sx.val.i = constant                          */
609                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
610                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
611                         M_INTMOVE(s1, REG_ITMP1)
612                         M_IUSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
613                         M_INTMOVE(REG_ITMP1, d);
614                         emit_store_dst(jd, iptr, d);
615                         break;
616
617                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
618
619                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
620                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
621                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
622                         M_INTMOVE(s2, REG_ITMP2);
623                         M_IAND(s1, REG_ITMP2);
624                         M_INTMOVE(REG_ITMP2, d);
625                         emit_store_dst(jd, iptr, d);
626                         break;
627
628                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
629                                       /* sx.val.i = constant                          */
630
631                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
632                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
633                         M_INTMOVE(s1, REG_ITMP1);
634                         M_IAND_IMM(iptr->sx.val.i, REG_ITMP1);
635                         M_INTMOVE(REG_ITMP1, d);
636                         emit_store_dst(jd, iptr, d);
637                         break;
638
639
640
641
642                 /* load/store/copy/move operations ************************************/
643
644                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
645                 case ICMD_ALOAD:      /* s1 = local variable                          */
646                 case ICMD_LLOAD:
647                 case ICMD_FLOAD:  
648                 case ICMD_DLOAD:  
649                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
650                 case ICMD_LSTORE:
651                 case ICMD_FSTORE:
652                 case ICMD_DSTORE: 
653                 case ICMD_COPY:
654                 case ICMD_MOVE:
655                         emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
656                         break;
657
658                 case ICMD_ASTORE:
659                         if (!(iptr->flags.bits & INS_FLAG_RETADDR))
660                                 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
661                         break;
662
663
664                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
665                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
666
667                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
668                                 constant_classref *cr = iptr->sx.val.c.ref;;
669                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, cr, 0);
670                                 M_AMOV_IMM(0, d);
671                         } else {
672                                 M_AMOV_IMM(iptr->sx.val.anyptr, d);
673                         }
674                         emit_store_dst(jd, iptr, d);
675                         break;
676                 /* BRANCH *************************************************************/
677
678                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
679
680                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
681                         M_ADRMOVE(s1, REG_ATMP1_XPTR);
682
683 #ifdef ENABLE_VERIFIER
684                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
685                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
686
687                                 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
688                         }
689 #endif /* ENABLE_VERIFIER */
690                         M_JSR_PCREL(2);                         /* get current PC */
691                         M_APOP(REG_ATMP2);              
692
693                         M_AMOV_IMM(asm_handle_exception, REG_ATMP3);
694                         M_JMP(REG_ATMP3);
695                         ALIGNCODENOP;
696                         break;
697
698                 case ICMD_GOTO:         /* ... ==> ...                                */
699                 case ICMD_RET:          /* ... ==> ...                                */
700
701                         emit_br(cd, iptr->dst.block);
702                         ALIGNCODENOP;
703                         break;
704
705                 case ICMD_JSR:          /* ... ==> ...                                */
706
707                         emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
708                         ALIGNCODENOP;
709                         break;
710
711
712
713                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
714                 case ICMD_IFNONNULL:
715                         assert(IS_ADR_TYPE(VAROP(iptr->s1)->type));
716                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
717                         M_ATST(s1);
718                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
719                         break;
720
721                 case ICMD_IFLT:
722                 case ICMD_IFLE:
723                 case ICMD_IFNE:
724                 case ICMD_IFGT:
725                 case ICMD_IFGE:
726                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
727
728                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
729                         assert (VAROP(iptr->s1)->type == TYPE_INT);
730                         M_ICMP_IMM(iptr->sx.val.i, s1); 
731                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
732                         break;
733
734                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
735                 case ICMD_IF_ICMPNE:
736                 case ICMD_IF_ICMPLT:
737                 case ICMD_IF_ICMPGT:
738                 case ICMD_IF_ICMPLE:
739                 case ICMD_IF_ICMPGE:
740
741                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
742                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
743                         M_ICMP(s2, s1);
744                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
745                         break;
746
747                 case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
748                 case ICMD_IF_ACMPNE:
749
750                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
751                         s2 = emit_load_s2(jd, iptr, REG_ATMP2);
752                         M_ACMP(s1, s2);
753                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
754                         break;
755
756
757                 /* MEMORY *************************************************************/
758                 case ICMD_GETSTATIC:
759                         if (INSTRUCTION_IS_UNRESOLVED(iptr))    {
760                                 assert(0);
761                         } else  {
762                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
763
764                                 fieldtype = fi->type;
765                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
766                                         codegen_addpatchref(cd, PATCHER_initialize_class, fi->class, disp);
767                                 }
768
769                                 disp = (ptrint) &(fi->value);
770                         }
771                         M_AMOV_IMM(disp, REG_ATMP1);
772                         switch (fieldtype) {
773 #if defined(ENABLE_SOFTFLOAT)
774                         case TYPE_FLT:
775 #endif
776                         case TYPE_INT:
777                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
778                                 M_ILD(d, REG_ATMP1, 0);
779                                 break;
780                         case TYPE_ADR:
781                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
782                                 M_ALD(d, REG_ATMP1, 0);
783                                 break;
784 #if defined(ENABLE_SOFTFLOAT)
785                         case TYPE_DBL:
786 #endif
787                         case TYPE_LNG:
788                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
789                                 M_LLD(d, REG_ATMP1, 0);
790                                 break;
791 #if !defined(ENABLE_SOFTFLOAT)
792                         case TYPE_FLT:
793                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
794                                 M_FLD(d, REG_ATMP1, 0);
795                                 break;
796                         case TYPE_DBL:                          
797                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
798                                 M_DLD(d, REG_ATMP1, 0);
799                                 break;
800 #endif
801                         }
802                         emit_store_dst(jd, iptr, d);
803                         break;
804
805                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
806
807                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
808                                 uf        = iptr->sx.s23.s3.uf;
809                                 fieldtype = uf->fieldref->parseddesc.fd->type;
810
811                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
812                         } else {
813                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
814                                 fieldtype = fi->type;
815                                 disp      = &(fi->value);
816
817                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
818                                         codegen_addpatchref(cd, PATCHER_initialize_class, fi->class, 0);
819                         }
820                 
821                         M_AMOV_IMM(disp, REG_ATMP1);
822                         switch (fieldtype) {
823 #if defined(ENABLE_SOFTFLOAT)
824                         case TYPE_FLT:
825 #endif
826                         case TYPE_INT:
827                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
828                                 M_IST(s1, REG_ATMP1, 0);
829                                 break;
830 #if defined(ENABLE_SOFTFLOAT)
831                         case TYPE_DBL:
832 #endif
833                         case TYPE_LNG:
834                                 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
835                                 M_LST(s1, REG_ATMP1, 0);
836                                 break;
837                         case TYPE_ADR:
838                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
839                                 M_AST(s1, REG_ATMP1, 0);
840                                 break;
841 #if !defined(ENABLE_SOFTFLOAT)
842                         case TYPE_FLT:
843                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
844                                 M_FST(s1, REG_ATMP1, 0);
845                                 break;
846                         case TYPE_DBL:
847                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
848                                 M_DST(s1, REG_ATMP1, 0);
849                                 break;
850 #endif
851                         default: assert(0);
852                         }
853                         break;
854
855                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
856
857                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
858
859                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
860                                 uf        = iptr->sx.s23.s3.uf;
861                                 fieldtype = uf->fieldref->parseddesc.fd->type;
862                                 disp      = 0;
863
864                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
865                         }
866                         else {
867                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
868                                 fieldtype = fi->type;
869                                 disp      = fi->offset;
870                         }
871
872                         /* implicit null-pointer check */
873                         switch (fieldtype) {
874 #if defined(ENABLE_SOFTFLOAT)
875                         case TYPE_FLT:
876 #endif
877                         case TYPE_INT:
878                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
879                                 M_ILD(d, s1, disp);
880                                 break;
881 #if defined(ENABLE_SOFTFLOAT)
882                         case TYPE_DBL:
883 #endif
884                         case TYPE_LNG:
885                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
886                                 if (GET_HIGH_REG(d) == s1) {
887                                         M_ILD(GET_LOW_REG(d), s1, disp + 4);
888                                         M_ILD(GET_HIGH_REG(d), s1, disp);
889                                 } else {
890                                         M_ILD(GET_HIGH_REG(d), s1, disp);
891                                         M_ILD(GET_LOW_REG(d), s1, disp + 4);
892                                 }
893                                 break;
894                         case TYPE_ADR:
895                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
896                                 M_ALD(d, s1, disp);
897                                 break;
898 #if !defined(ENABLE_SOFTFLOAT)
899                         case TYPE_FLT:
900                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
901                                 M_FLD(d, s1, disp);
902                                 break;
903                         case TYPE_DBL:                          
904                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
905                                 M_DLD(d, s1, disp);
906                                 break;
907 #endif
908                         }
909                         emit_store_dst(jd, iptr, d);
910                         break;
911
912                 case ICMD_PUTFIELD:   /* ..., value  ==> ...                          */
913
914                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
915
916                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
917                                 uf        = iptr->sx.s23.s3.uf;
918                                 fieldtype = uf->fieldref->parseddesc.fd->type;
919                                 disp      = 0;
920                         }
921                         else {
922                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
923                                 fieldtype = fi->type;
924                                 disp      = fi->offset;
925                         }
926
927                         if (IS_INT_LNG_TYPE(fieldtype)) {
928                                 if (IS_2_WORD_TYPE(fieldtype)) {
929                                         s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
930                                 } else {
931                                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
932                                 }
933                         } else {
934                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
935                         }
936
937                         if (INSTRUCTION_IS_UNRESOLVED(iptr))
938                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
939
940                         /* implicit null-pointer check */
941                         switch (fieldtype) {
942 #if defined(ENABLE_SOFTFLOAT)
943                         case TYPE_FLT:
944 #endif
945                         case TYPE_INT:
946                                 M_IST(s2, s1, disp);
947                                 break;
948
949 #if defined(ENABLE_SOFTFLOAT)
950                         case TYPE_DBL:
951 #endif
952                         case TYPE_LNG:
953                                 M_IST(GET_LOW_REG(s2), s1, disp + 4);      /* keep this order */
954                                 M_IST(GET_HIGH_REG(s2), s1, disp);         /* keep this order */
955                                 break;
956                         case TYPE_ADR:
957                                 M_AST(s2, s1, disp);
958                                 break;
959 #if !defined(ENABLE_SOFTFLOAT)
960                         case TYPE_FLT:
961                                 M_FST(s2, s1, disp);
962                                 break;
963                         case TYPE_DBL:
964                                 M_DST(s2, s1, disp);
965                                 break;
966 #endif
967                         }
968                         break;
969
970                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
971
972                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
973                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
974                         /* implicit null-pointer check */
975                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
976                         emit_store_dst(jd, iptr, d);
977                         break;
978
979                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
980
981                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
982                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
983                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
984                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
985                         M_INTMOVE(s2, REG_ITMP2);
986                         M_IADD_IMM(OFFSET(java_bytearray, data[0]), REG_ITMP2);
987                         M_ADRMOVE(s1, REG_ATMP1);
988                         M_AADDINT(REG_ITMP2, REG_ATMP1);
989                         /* implicit null-pointer check */
990                         M_LBZX(REG_ATMP1, d);
991                         M_BSEXT(d, d);
992                         emit_store_dst(jd, iptr, d);
993                         break;                  
994
995                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
996
997                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
998                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
999                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1000                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1001                         M_INTMOVE(s2, REG_ITMP2);
1002                         M_ISSL_IMM(1, REG_ITMP2);
1003                         M_IADD_IMM(OFFSET(java_chararray, data[0]), REG_ITMP2);
1004                         M_ADRMOVE(s1, REG_ATMP1);
1005                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1006                         /* implicit null-pointer check */
1007                         M_LHZX(REG_ATMP1, d);
1008                         /*M_CZEXT(d, d);*/
1009                         emit_store_dst(jd, iptr, d);
1010                         break;
1011
1012                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1013
1014                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1015                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1016                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1017                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1018                         M_INTMOVE(s2, REG_ITMP2);
1019                         M_ISSL_IMM(1, REG_ITMP2);
1020                         M_IADD_IMM(OFFSET(java_shortarray, data[0]), REG_ITMP2);
1021                         M_ADRMOVE(s1, REG_ATMP1);
1022                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1023                 
1024                         /* implicit null-pointer check */
1025                         M_LHZX(REG_ATMP1, d);
1026                         M_HSEXT(d, d);
1027                         emit_store_dst(jd, iptr, d);
1028                         break;
1029
1030                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1031
1032                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1033                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1034                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1035                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1036                         M_INTMOVE(s2, REG_ITMP2);
1037                         M_ISSL_IMM(2, REG_ITMP2);
1038                         M_IADD_IMM(OFFSET(java_intarray, data[0]), REG_ITMP2);
1039                         M_ADRMOVE(s1, REG_ATMP1);
1040                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1041         
1042                         /* implicit null-pointer check */
1043                         M_LWZX(REG_ATMP1, d);
1044                         emit_store_dst(jd, iptr, d);
1045                         break;
1046
1047 #if 0
1048                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1049                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1050                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1051                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1052                         /* implicit null-pointer check */
1053                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1054                         M_SLL_IMM(s2, 3, REG_ITMP2);
1055                         M_IADD(s1, REG_ITMP2, REG_ITMP2);
1056                         M_LLD_INTERN(d, REG_ITMP2, OFFSET(java_longarray, data[0]));
1057                         emit_store_dst(jd, iptr, d);
1058                         break;
1059
1060                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1061                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1062                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1063                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1064                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1065                         M_SLL_IMM(s2, 2, REG_ITMP2);
1066                         M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1067                         /* implicit null-pointer check */
1068                         M_LFSX(d, s1, REG_ITMP2);
1069                         emit_store_dst(jd, iptr, d);
1070                         break;
1071
1072                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1073                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1074                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1075                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1076                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1077                         M_SLL_IMM(s2, 3, REG_ITMP2);
1078                         M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1079                         /* implicit null-pointer check */
1080                         M_LFDX(d, s1, REG_ITMP2);
1081                         emit_store_dst(jd, iptr, d);
1082                         break;
1083                 #endif
1084
1085                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1086
1087                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1088                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1089                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1090                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1091                         M_INTMOVE(s2, REG_ITMP2);
1092                         M_ISSL_IMM(2, REG_ITMP2);
1093                         M_IADD_IMM(OFFSET(java_objectarray, data[0]), REG_ITMP2);
1094                         M_ADRMOVE(s1, REG_ATMP1);
1095                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1096         
1097                         /* implicit null-pointer check */
1098                         M_LAX(REG_ATMP1, d);
1099                         emit_store_dst(jd, iptr, d);
1100                         break;
1101
1102
1103                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1104
1105                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1106                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1107                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1108                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1109                         M_INTMOVE(s2, REG_ITMP2);
1110                         M_IADD_IMM(OFFSET(java_bytearray, data[0]), REG_ITMP2);
1111                         M_ADRMOVE(s1, REG_ATMP1);
1112                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1113         
1114                         /* implicit null-pointer check */
1115                         M_STBX(REG_ATMP1, s3);
1116                         break;
1117
1118                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1119
1120                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1121                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1122                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1123                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1124                         M_INTMOVE(s2, REG_ITMP2);
1125                         M_ISSL_IMM(1, REG_ITMP2);
1126                         M_IADD_IMM(OFFSET(java_chararray, data[0]), REG_ITMP2); 
1127                         M_ADRMOVE(s1, REG_ATMP1);
1128                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1129                         /* implicit null-pointer check */
1130                         M_STHX(REG_ATMP1, s3);
1131                         break;
1132
1133                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1134
1135                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1136                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1137                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1138                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1139                         M_INTMOVE(s2, REG_ITMP2);
1140                         M_ISSL_IMM(1, REG_ITMP2);
1141                         M_IADD_IMM(OFFSET(java_shortarray, data[0]), REG_ITMP2);
1142                         M_ADRMOVE(s1, REG_ATMP1);
1143                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1144                         /* implicit null-pointer check */
1145                         M_STHX(REG_ATMP1, s3);
1146                         break;
1147
1148                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1149
1150                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1151                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1152                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1153                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1154                         M_INTMOVE(s2, REG_ITMP2);
1155                         M_ISSL_IMM(1, REG_ITMP2);
1156                         M_IADD_IMM(OFFSET(java_intarray, data[0]), REG_ITMP2);
1157                         M_ADRMOVE(s1, REG_ATMP1);
1158                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1159                         /* implicit null-pointer check */
1160                         M_STWX(REG_ATMP1, s3);
1161                         break;
1162
1163 #if 0
1164                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1165                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1166                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1167                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1168                         s3 = emit_load_s3_high(jd, iptr, REG_ITMP3);
1169                         M_INTMOVE(s2, REG_ITMP2);
1170                         M_IADD_IMM(OFFSET(java_bytearray, data[0]), REG_ITMP2);
1171                         M_ISSL_IMM(1, REG_ITMP2);
1172                         M_ADRMOVE(s1, REG_ATMP1);
1173                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1174                         /* implicit null-pointer check */
1175                         M_STWX(s3, s1, REG_ITMP2);
1176                         M_IADD_IMM(REG_ITMP2, 4, REG_ITMP2);
1177                         s3 = emit_load_s3_low(jd, iptr, REG_ITMP3);
1178                         M_STWX(s3, s1, REG_ITMP2);
1179                         break;
1180
1181                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1182                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1183                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1184                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1185                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1186                         M_SLL_IMM(s2, 2, REG_ITMP2);
1187                         M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1188                         /* implicit null-pointer check */
1189                         M_STFSX(s3, s1, REG_ITMP2);
1190                         break;
1191
1192                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1193                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1194                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1195                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1196                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1197                         M_SLL_IMM(s2, 3, REG_ITMP2);
1198                         M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1199                         /* implicit null-pointer check */
1200                         M_STFDX(s3, s1, REG_ITMP2);
1201                         break;
1202
1203         #endif
1204                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1205
1206                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1207                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1208                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1209                         s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1210
1211                         /* XXX what if array is NULL */
1212                         disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1213
1214                         M_AST(s1, REG_SP, 0*4);
1215                         M_AST(s3, REG_SP, 1*4);
1216                         M_JSR_IMM(BUILTIN_canstore);    
1217                         emit_exception_check_ireg(cd, iptr);
1218
1219                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1220                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1221                         s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1222                         M_INTMOVE(s2, REG_ITMP1);
1223                         M_ISSL_IMM(2, REG_ITMP1);
1224                         M_IADD_IMM(OFFSET(java_objectarray, data[0]), REG_ITMP1);
1225                         M_INTMOVE(s1, REG_ATMP1);
1226                         M_AADDINT(REG_ITMP1, REG_ATMP1);
1227                         /* implicit null-pointer check */
1228                         M_STAX(REG_ATMP1, s3);
1229                         break;
1230
1231
1232
1233                 /* METHOD INVOCATION *********************************************************/
1234                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
1235                         bte = iptr->sx.s23.s3.bte;
1236                         md  = bte->md;
1237                         goto gen_method;
1238
1239                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
1240                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1241                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
1242                 case ICMD_INVOKEINTERFACE:
1243                         REPLACEMENT_POINT_INVOKE(cd, iptr);
1244
1245                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1246                                 lm = NULL;
1247                                 um = iptr->sx.s23.s3.um;
1248                                 md = um->methodref->parseddesc.md;
1249                         }
1250                         else {
1251                                 lm = iptr->sx.s23.s3.fmiref->p.method;
1252                                 um = NULL;
1253                                 md = lm->parseddesc;
1254                         }
1255         gen_method:
1256                         s3 = md->paramcount;
1257         
1258                         MCODECHECK((s3 << 1) + 64);
1259
1260                         /* copy arguments to stack */
1261                         for (s3 = s3 - 1; s3 >= 0; s3--)        {
1262                                 var = VAR(iptr->sx.s23.s2.args[s3]);
1263                                 /* already preallocated */
1264                                 if (var->flags & PREALLOC) continue;
1265                 
1266                                 if (!md->params[s3].inmemory) assert(0);
1267
1268                                 switch (var->type)      {
1269 #if defined(ENABLE_SOFTFLOAT)
1270                                         case TYPE_DBL:
1271 #endif
1272                                         case TYPE_LNG:
1273                                                 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
1274                                                 M_LST(d, REG_SP, md->params[s3].regoff*4);
1275                                                 break;
1276 #if defined(ENABLE_SOFTFLOAT)
1277                                         case TYPE_FLT:
1278 #endif
1279                                         case TYPE_INT:
1280                                                 d = emit_load(jd, iptr, var, REG_ITMP1);
1281                                                 M_IST(d, REG_SP, md->params[s3].regoff*4);
1282                                                 break;
1283                                         case TYPE_ADR:
1284                                                 d = emit_load(jd, iptr, var, REG_ATMP1);
1285                                                 M_AST(d, REG_SP, md->params[s3].regoff*4);
1286                                                 break;
1287 #if !defined(ENABLE_SOFTFLOAT)
1288                                         case TYPE_FLT:
1289                                         case TYPE_DBL:
1290 #endif
1291                                         default:
1292                                                 assert(0);
1293                                 }
1294                         }
1295
1296                         /* arguments in place now */
1297                         switch(iptr->opc)       {
1298                                 case ICMD_BUILTIN: 
1299                                         disp = (ptrint) bte->fp;
1300                                         d = md->returntype.type;
1301                                         M_JSR_IMM(disp);
1302
1303                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1304                                         /*emit_exception_check(cd, iptr); TODO */
1305                                         break;
1306
1307                                 case ICMD_INVOKESPECIAL: 
1308                                         /* adress register for sure */
1309                                         M_ALD(REG_ATMP1, REG_SP, 0);
1310                                         emit_nullpointer_check(cd, iptr, REG_ATMP1);
1311                                         /* fall through */
1312                                 case ICMD_INVOKESTATIC: 
1313                                         if (lm == NULL) {
1314                                                 codegen_addpatchref(cd, PATCHER_invokestatic_special, um, 0);
1315                                                 disp = 0;
1316                                                 M_AMOV_IMM(disp, REG_ATMP1);
1317                                         } else  {
1318                                                 disp = lm->stubroutine;
1319                                                 M_AMOV_IMM(disp, REG_ATMP1);
1320                                         }
1321
1322                                         /* generate the actual call */
1323                                         M_JSR(REG_ATMP1);
1324                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1325                                         break;
1326
1327
1328                                 case ICMD_INVOKEVIRTUAL:
1329                                         if (lm == NULL) {
1330                                                 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
1331                                                 s1 = 0;
1332                                         } else {
1333                                                 s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
1334                                         }
1335                                         /* load object pointer (==argument 0) */
1336                                         M_ALD(REG_ATMP1, REG_SP, 0);
1337                                         /* implicit null-pointer check */
1338                                         M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_objectheader, vftbl));
1339                                         M_ALD(REG_ATMP1, REG_METHODPTR, s1);
1340                                         /* generate the actual call */
1341                                         M_JSR(REG_ATMP1);
1342                                         break;
1343                                 case ICMD_INVOKEINTERFACE: 
1344                                         if (lm == NULL) {
1345                                                 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
1346
1347                                                 s1 = 0;
1348                                                 s2 = 0;
1349                                         } else {
1350                                                 s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->class->index;
1351                                                 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1352                                         }
1353                                         /* load object pointer (==argument 0) */
1354                                         M_ALD(REG_ATMP1, REG_SP, 0);
1355
1356                                         /* implicit null-pointer check */
1357                                         M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_objectheader, vftbl));
1358                                         M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
1359                                         M_ALD(REG_ATMP1, REG_METHODPTR, s2);
1360
1361                                         /* generate the actual call */
1362                                         M_JSR(REG_ATMP1);
1363                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1364                                         break;
1365
1366                                 default: assert(0);
1367                                 }       /* switch (iptr->opc) */
1368
1369                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1370                                 
1371                                 /* store return value */
1372                                 d = md->returntype.type;
1373
1374                                 switch (d)      {
1375                                         case TYPE_VOID: break;
1376 #if defined(ENABLE_SOFTFLOAT)
1377                                         case TYPE_FLT:
1378 #endif
1379                                         case TYPE_INT:
1380                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1381                                                 M_INTMOVE(REG_RESULT, s1);
1382                                                 break;
1383 #if defined(ENABLE_SOFTFLOAT)
1384                                         case TYPE_DBL:
1385 #endif
1386                                         case TYPE_LNG:
1387                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1388                                                 M_LNGMOVE(REG_RESULT_PACKED, s1);
1389                                                 break;
1390                                         case TYPE_ADR:
1391                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_ATMP1);
1392                                                 /* all stuff is returned in %d0 */
1393                                                 M_INT2ADRMOVE(REG_RESULT, s1);
1394                                                 break;
1395 #if !defined(ENABLE_SOFTFLOAT)
1396                                         case TYPE_FLT:
1397                                         case TYPE_DBL:
1398 #endif
1399                                         default:
1400                                                 assert(0);
1401                                 }
1402                                 if (d != TYPE_VOID) emit_store_dst(jd, iptr, s1);
1403                         break; /* ICMD_INVOKE* */
1404
1405 #if defined(ENABLE_SOFTFLOAT)
1406                 case ICMD_FRETURN:
1407 #endif
1408                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
1409
1410                         REPLACEMENT_POINT_RETURN(cd, iptr);
1411                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
1412                         M_INTMOVE(s1, REG_RESULT);
1413                         goto nowperformreturn;
1414
1415                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
1416
1417                         REPLACEMENT_POINT_RETURN(cd, iptr);
1418                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
1419                         assert(VAROP(iptr->s1)->type == TYPE_ADR);
1420                         M_ADR2INTMOVE(s1, REG_RESULT);
1421
1422 #ifdef ENABLE_VERIFIER
1423                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1424                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
1425
1426                                 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
1427                         }
1428 #endif /* ENABLE_VERIFIER */
1429                         goto nowperformreturn;
1430
1431 #if defined(ENABLE_SOFTFLOAT)
1432                 case ICMD_DRETURN:
1433 #endif
1434                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
1435
1436                         REPLACEMENT_POINT_RETURN(cd, iptr);
1437                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
1438                         M_LNGMOVE(s1, REG_RESULT_PACKED);
1439                         goto nowperformreturn;
1440
1441 #if !defined(ENABLE_SOFTFLOAT)
1442                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
1443                 case ICMD_DRETURN:
1444
1445                         REPLACEMENT_POINT_RETURN(cd, iptr);
1446                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1447                         M_FLTMOVE(s1, REG_FRESULT);
1448                         goto nowperformreturn;
1449 #endif
1450
1451                 case ICMD_RETURN:      /* ...  ==> ...                                */
1452
1453                         REPLACEMENT_POINT_RETURN(cd, iptr);
1454
1455 nowperformreturn:
1456                         {
1457                         s4 i, p;
1458                         
1459                         p = cd->stackframesize;
1460
1461                         /* call trace function */
1462 #if !defined(NDEBUG)
1463                         emit_verbosecall_exit(jd);
1464 #endif
1465
1466 #if defined(ENABLE_THREADS)
1467                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1468                                 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
1469                                 M_ALD(REG_ITMP3, REG_PV, disp);
1470                                 M_MTCTR(REG_ITMP3);
1471
1472                                 /* we need to save the proper return value */
1473
1474                                 switch (iptr->opc) {
1475                                 case ICMD_LRETURN:
1476                                         M_IST(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
1477                                         /* fall through */
1478                                 case ICMD_IRETURN:
1479                                 case ICMD_ARETURN:
1480                                         M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
1481                                         break;
1482                                 case ICMD_FRETURN:
1483                                         M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
1484                                         break;
1485                                 case ICMD_DRETURN:
1486                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
1487                                         break;
1488                                 }
1489
1490                                 M_ALD(REG_A0, REG_SP, rd->memuse * 4);
1491                                 M_JSR;
1492
1493                                 /* and now restore the proper return value */
1494
1495                                 switch (iptr->opc) {
1496                                 case ICMD_LRETURN:
1497                                         M_ILD(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
1498                                         /* fall through */
1499                                 case ICMD_IRETURN:
1500                                 case ICMD_ARETURN:
1501                                         M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
1502                                         break;
1503                                 case ICMD_FRETURN:
1504                                         M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
1505                                         break;
1506                                 case ICMD_DRETURN:
1507                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
1508                                         break;
1509                                 }
1510                         }
1511 #endif
1512
1513
1514                         /* restore return address                                         */
1515 #if 0
1516                         if (!jd->isleafmethod) {
1517                                 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
1518                                    may have a displacement overflow. */
1519
1520                                 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
1521                                 M_MTLR(REG_ITMP1);
1522                         }
1523 #endif
1524                         /* restore saved registers                                        */
1525
1526                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
1527                                 p--; M_ILD(rd->savintregs[i], REG_SP, p * 4);
1528                         }
1529                         for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
1530                                 p--; M_ALD(rd->savadrregs[i], REG_SP, p*4);
1531                         }
1532 #if !defined(ENABLE_SOFTFLOAT)
1533                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
1534                                 p -= 2; M_DLD(rd->savfltregs[i], REG_SP, p * 4);
1535                         }
1536 #endif
1537                         /* deallocate stack                                               */
1538                         M_AADD_IMM(cd->stackframesize*4, REG_SP);
1539                         M_RET;
1540                         }
1541                         break;
1542
1543                 /* the evil ones */
1544                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
1545                                       /* val.a: (classinfo*) superclass               */
1546
1547                         /*  superclass is an interface:
1548                          *
1549                          *  return (sub != NULL) &&
1550                          *         (sub->vftbl->interfacetablelength > super->index) &&
1551                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
1552                          *
1553                          *  superclass is a class:
1554                          *
1555                          *  return ((sub != NULL) && (0
1556                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1557                          *          super->vftbl->diffvall));
1558                          */
1559
1560                         {
1561                         classinfo *super;
1562                         s4         superindex;
1563
1564                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1565                                 super      = NULL;
1566                                 superindex = 0;
1567                         }
1568                         else {
1569                                 super      = iptr->sx.s23.s3.c.cls;
1570                                 superindex = super->index;
1571                         }
1572                         
1573 #if defined(ENABLE_THREADS)
1574                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
1575 #endif
1576                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1577                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1578
1579                         assert(VAROP(iptr->s1 )->type == TYPE_ADR);
1580                         assert(VAROP(iptr->dst)->type == TYPE_INT);
1581
1582                         M_ICLR(d);
1583
1584                         /* if class is not resolved, check which code to call */
1585
1586                         if (super == NULL) {
1587                                 M_ATST(s1);
1588                                 emit_label_beq(cd, BRANCH_LABEL_1);
1589
1590                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
1591
1592                                 M_IMOV_IMM32(0, REG_ITMP3);
1593                                 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
1594                                 emit_label_beq(cd, BRANCH_LABEL_2);
1595                         }
1596
1597                         /* interface instanceof code */
1598
1599                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1600                                 if (super == NULL) {
1601                                         codegen_addpatchref(cd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
1602                                 } else {
1603                                         M_ATST(s1);
1604                                         emit_label_beq(cd, BRANCH_LABEL_3);
1605                                 }
1606
1607                                 M_ALD(REG_ATMP1, s1, OFFSET(java_objectheader, vftbl));
1608                                 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
1609                                 M_IADD_IMM(-superindex, REG_ITMP3);     /* -superindex may be patched patched */
1610                                 M_ITST(REG_ITMP3);
1611                                 M_BLE(10);
1612                                 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patch here too! */
1613                                 M_ATST(REG_ATMP1);
1614                                 M_BEQ(2);
1615                                 M_IMOV_IMM(1, d);
1616
1617                                 if (super == NULL)
1618                                         emit_label_br(cd, BRANCH_LABEL_4);
1619                                 else
1620                                         emit_label(cd, BRANCH_LABEL_3);
1621                         }
1622
1623                         /* class instanceof code */
1624
1625                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
1626                                 if (super == NULL) {
1627                                         emit_label(cd, BRANCH_LABEL_2);
1628
1629                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
1630                                         M_AMOV_IMM(0, REG_ATMP2);
1631                                 } else {
1632                                         M_AMOV_IMM(super->vftbl, REG_ATMP2);
1633                                         M_ATST(s1);
1634                                         emit_label_beq(cd, BRANCH_LABEL_5);
1635                                 }
1636
1637                                 M_ALD(REG_ATMP1, s1, OFFSET(java_objectheader, vftbl));
1638 #if defined(ENABLE_THREADS)
1639                                 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
1640 #endif
1641                                 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
1642                                 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
1643                                 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
1644 #if defined(ENABLE_THREADS)
1645                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
1646 #endif
1647                                 M_ISUB(REG_ITMP3, REG_ITMP1);
1648                                 M_ICMP(REG_ITMP1, REG_ITMP2);
1649                                 M_BGT(4);
1650                                 M_IMOV_IMM(1, d);
1651                                 M_TPFW;                 /* overlaps next instruction */
1652                                 M_ICLR(d);
1653
1654                                 if (super != NULL)
1655                                         emit_label(cd, BRANCH_LABEL_5);
1656                         }
1657
1658                         if (super == NULL) {
1659                                 emit_label(cd, BRANCH_LABEL_1);
1660                                 emit_label(cd, BRANCH_LABEL_4);
1661                         }
1662
1663                         emit_store_dst(jd, iptr, d);
1664                         }
1665                         break;
1666
1667                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
1668                                       /* val.a: (classinfo*) superclass               */
1669
1670                         /*  superclass is an interface:
1671                          *
1672                          *  OK if ((sub == NULL) ||
1673                          *         (sub->vftbl->interfacetablelength > super->index) &&
1674                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
1675                          *
1676                          *  superclass is a class:
1677                          *
1678                          *  OK if ((sub == NULL) || (0
1679                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1680                          *         super->vftbl->diffvall));
1681                          */
1682
1683                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
1684                                 /* object type cast-check */
1685
1686                                 classinfo *super;
1687                                 s4         superindex;
1688
1689                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1690                                         super      = NULL;
1691                                         superindex = 0;
1692                                 }
1693                                 else {
1694                                         super      = iptr->sx.s23.s3.c.cls;
1695                                         superindex = super->index;
1696                                 }
1697
1698 #if defined(ENABLE_THREADS)
1699                                 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
1700 #endif
1701
1702                                 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1703                                 assert(VAROP(iptr->s1)->type == TYPE_ADR);
1704
1705                                 /* if class is not resolved, check which code to call */
1706
1707                                 if (super == NULL) {
1708                                         M_ATST(s1);
1709                                         emit_label_beq(cd, BRANCH_LABEL_1);
1710
1711                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
1712                         
1713                                         M_IMOV_IMM32(0, REG_ITMP2);
1714                                         M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
1715                                         emit_label_beq(cd, BRANCH_LABEL_2);
1716                                 }
1717
1718                                 /* interface checkcast code */
1719
1720                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1721                                         if (super == NULL) {
1722                                                 codegen_addpatchref(cd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
1723                                         } else {
1724                                                 M_ATST(s1);
1725                                                 emit_label_beq(cd, BRANCH_LABEL_3);
1726                                         }
1727
1728                                         M_ALD(REG_ATMP2, s1, OFFSET(java_objectheader, vftbl));
1729                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
1730         
1731                                         M_IADD_IMM(-superindex, REG_ITMP3);     /* superindex patched */
1732                                         M_ITST(REG_ITMP3);
1733                                         emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
1734
1735                                         M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patched*/
1736                                         M_ATST(REG_ATMP3);
1737                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
1738
1739                                         if (super == NULL)
1740                                                 emit_label_br(cd, BRANCH_LABEL_4);
1741                                         else
1742                                                 emit_label(cd, BRANCH_LABEL_3);
1743                                 }
1744
1745                                 /* class checkcast code */
1746
1747                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
1748                                         if (super == NULL) {
1749                                                 emit_label(cd, BRANCH_LABEL_2);
1750
1751                                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
1752                                                 M_AMOV_IMM(0, REG_ATMP3);
1753                                         } else {
1754                                                 M_AMOV_IMM(super->vftbl, REG_ATMP3);
1755                                                 M_ATST(s1);
1756                                                 emit_label_beq(cd, BRANCH_LABEL_5);
1757                                         }
1758
1759                                         M_ALD(REG_ATMP2, s1, OFFSET(java_objectheader, vftbl));
1760 #if defined(ENABLE_THREADS)
1761                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
1762 #endif
1763                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));  /* REG_ITMP3 == sub->vftbl->baseval */
1764 #if 0
1765                                         if (s1 != REG_ATMP1) {
1766 #endif
1767                                                 M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
1768                                                 M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
1769 #if defined(ENABLE_THREADS)
1770                                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
1771 #endif
1772                                                 M_ISUB(REG_ITMP1, REG_ITMP3);
1773                                                 M_ICMP(REG_ITMP2, REG_ITMP1);   /* XXX was CMPU */
1774 #if 0                                   
1775                                         } else {
1776                                                 assert(0);
1777                                                 M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, baseval));
1778                                                 M_ISUB(REG_ITMP3, REG_ITMP2);
1779                                                 M_ILD(REG_ITMP3, REG_ATMP3, OFFSET(vftbl_t, diffval));
1780                                                 M_ICMP(REG_ITMP2, REG_ITMP3);   /* XXX was CMPU */
1781 #if defined(ENABLE_THREADS)
1782                                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
1783 #endif
1784                                         }
1785 #endif
1786                                         emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
1787
1788                                         if (super != NULL)
1789                                                 emit_label(cd, BRANCH_LABEL_5);
1790                                 }
1791
1792                                 if (super == NULL) {
1793                                         emit_label(cd, BRANCH_LABEL_1);
1794                                         emit_label(cd, BRANCH_LABEL_4);
1795                                 }
1796
1797                                 d = codegen_reg_of_dst(jd, iptr, s1);
1798                         } else {
1799                                 /* array type cast-check */
1800
1801                                 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
1802
1803                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1804                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
1805                                         M_AMOV_IMM(0, REG_ATMP1);
1806                                 } else {
1807                                         M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
1808                                 }
1809         
1810                                 M_APUSH(s1);
1811                                 M_APUSH(REG_ATMP1);
1812                                 M_JSR_IMM(BUILTIN_arraycheckcast);
1813                                 M_AADD_IMM(2*4, REG_SP);                /* pop arguments off stack */
1814                                 M_ITST(REG_RESULT);
1815                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
1816
1817                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1818                                 d = codegen_reg_of_dst(jd, iptr, s1);
1819                         }
1820                         assert(VAROP(iptr->dst)->type == TYPE_ADR);
1821                         M_ADRMOVE(s1, d);
1822                         emit_store_dst(jd, iptr, d);
1823                         break;
1824
1825                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
1826                         {
1827                         s4 i, l;
1828                         branch_target_t *table;
1829
1830                         table = iptr->dst.table;
1831
1832                         l = iptr->sx.s23.s2.tablelow;
1833                         i = iptr->sx.s23.s3.tablehigh;
1834                         
1835                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1836                         M_INTMOVE(s1, REG_ITMP1);
1837                         if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
1838
1839                         i = i - l + 1;
1840
1841                         /* range check */
1842                         M_ICMP_IMM(i - 1, REG_ITMP1);
1843                         emit_bugt(cd, table[0].block);
1844
1845                         /* build jump table top down and use address of lowest entry */
1846                         table += i;
1847
1848                         while (--i >= 0) {
1849                                 dseg_add_target(cd, table->block); 
1850                                 --table;
1851                         }
1852
1853                         /* length of dataseg after last dseg_add_target is used by load */
1854                         M_AMOV_IMM(0, REG_ATMP2);
1855                         dseg_adddata(cd);
1856
1857                         M_ISSL_IMM(2, REG_ITMP1);                       /* index * 4 == offset in table */
1858                         M_AADDINT(REG_ITMP1, REG_ATMP2);                /* offset in table */
1859                         M_AADD_IMM(-(cd->dseglen), REG_ATMP2);          /* start of table in dseg */
1860                         M_ALD(REG_ATMP1, REG_ATMP2, 0);
1861
1862                         M_JMP(REG_ATMP1);
1863                         ALIGNCODENOP;
1864                         }
1865                         break;
1866
1867                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
1868                         {
1869                         s4 i;
1870                         lookup_target_t *lookup;
1871
1872                         lookup = iptr->dst.lookup;
1873
1874                         i = iptr->sx.s23.s2.lookupcount;
1875                         
1876                         MCODECHECK((i<<2)+8);
1877                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1878
1879                         while (--i >= 0) {
1880                                 M_ICMP_IMM(lookup->value, s1);
1881                                 emit_beq(cd, lookup->target.block);
1882                                 lookup++;
1883                         }
1884
1885                         emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
1886                         ALIGNCODENOP;
1887                         break;
1888                         }
1889
1890
1891                 default:
1892                         printf("UNKNOWN OPCODE %d\n", iptr->opc);
1893                         exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc);
1894                         return false;
1895         } /* switch */
1896         M_TPF;
1897         } /* for each instruction */
1898         } /* if (btpre->flags >= BBREACHED) */
1899         } /* for each basic block */
1900
1901         dseg_createlinenumbertable(cd);
1902
1903         /* generate stubs */
1904         emit_patcher_stubs(jd);
1905         REPLACEMENT_EMIT_STUBS(jd);
1906
1907         return true;
1908 }
1909
1910
1911 /* codegen_emit_stub_compiler **************************************************
1912
1913    Emits a stub routine which calls the compiler.
1914         
1915 *******************************************************************************/
1916
1917 void codegen_emit_stub_compiler(jitdata *jd)
1918 {
1919         methodinfo  *m;
1920         codegendata *cd;
1921
1922         /* get required compiler data */
1923
1924         m  = jd->m;
1925         cd = jd->cd;
1926
1927         /* code for the stub */
1928
1929         M_AMOV_IMM(m, REG_ATMP1);
1930         M_AMOV_IMM(asm_call_jit_compiler, REG_ATMP3);
1931         M_JMP_IMM(asm_call_jit_compiler);
1932         M_RET;
1933 }
1934
1935
1936 /* codegen_emit_stub_native ****************************************************
1937
1938    Emits a stub routine which calls a native method.
1939
1940 *******************************************************************************/
1941
1942 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
1943 {
1944         methodinfo   *m;
1945         codeinfo     *code;
1946         codegendata  *cd;
1947         registerdata *rd;
1948         methoddesc   *md;
1949         s4 nativeparams, i, j, t, s1, s2;
1950         
1951         /* get required compiler data */
1952
1953         m    = jd->m;
1954         code = jd->code;
1955         cd   = jd->cd;
1956         rd   = jd->rd;
1957
1958         md = m->parseddesc;
1959         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
1960
1961         /* calc stackframe size */
1962         cd->stackframesize =    sizeof(stackframeinfo) / SIZEOF_VOID_P +
1963                                 sizeof(localref_table) / SIZEOF_VOID_P +
1964                                 nmd->memuse +
1965                                 4 +                                             /* %d0,%d1,%a0,%a1*/
1966                                 2 * 2 +                                         /* %f0,%f1 */
1967                                 1 +                                             /* functionptr */
1968                                 4;                                              /* args for codegen_start_native_call */
1969
1970         /* create method header */
1971         (void) dseg_add_unique_address(cd, code);                      /* CodeinfoPointer */
1972         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4);         /* FrameSize       */
1973         (void) dseg_add_unique_s4(cd, 0);                              /* IsSync          */
1974         (void) dseg_add_unique_s4(cd, 0);                              /* IsLeaf          */
1975         (void) dseg_add_unique_s4(cd, 0);                              /* IntSave         */
1976         (void) dseg_add_unique_s4(cd, 0);                              /* FltSave         */
1977         (void) dseg_addlinenumbertablesize(cd);
1978         (void) dseg_add_unique_s4(cd, 0);                              /* ExTableSize     */
1979
1980         /* print call trace */
1981 #if !defined(NDEBUG)
1982         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
1983                 emit_verbosecall_enter(jd);
1984         }
1985 #endif
1986
1987         /* generate code */
1988         M_AADD_IMM(-(cd->stackframesize*4), REG_SP);
1989
1990         /* get function address (this must happen before the stackframeinfo) */
1991 #if !defined(WITH_STATIC_CLASSPATH)
1992         if (f == NULL)  {
1993                 codegen_addpatchref(cd, PATCHER_resolve_native_function, m, 0);
1994                 /*M_AMOV_IMM(0, REG_ATMP2);*/
1995         }
1996 #endif
1997         M_AMOV_IMM(f, REG_ATMP2); /* do not move this line, the patcher is needed */
1998
1999         M_AST(REG_ATMP2, REG_SP, 4 * 4);
2000
2001         /* save integer and float temp registers */
2002         /*
2003         M_IST(REG_D0, REG_SP, 4*4 + 2*8 + 3*4);
2004         M_IST(REG_D1, REG_SP, 4*4 + 2*8 + 2*4);
2005         M_AST(REG_A0, REG_SP, 4*4 + 2*8 + 1*4);
2006         M_AST(REG_A1, REG_SP, 4*4 + 2*8 + 0*4);
2007         */
2008
2009         /* TODO */
2010         /* store %f0, %f1 */
2011
2012         /* put arguments for codegen_start_native_call onto stack */
2013         /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
2014         
2015         M_AMOV(REG_SP, REG_ATMP1);
2016         M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1);
2017
2018         M_ALD(REG_ATMP3, REG_ATMP1, 0 * 4);
2019         M_AST(REG_ATMP3, REG_SP, 3 * 4);                /* ra */
2020
2021         M_AST(REG_ATMP1, REG_SP, 0 * 4);                /* datasp */
2022
2023         M_AADD_IMM(1 * 4 , REG_ATMP1);                  
2024         M_AST(REG_ATMP1, REG_SP, 2 * 4);                /* sp */
2025
2026         M_AMOV_IMM(0, REG_ATMP2);                       /* 0 needs to patched */
2027         dseg_adddata(cd);                               /* this patches it */
2028
2029         M_AST(REG_ATMP2, REG_SP, 1 * 4);                /* pv */
2030
2031         M_JSR_IMM(codegen_start_native_call);
2032
2033         /* load function pointer */
2034         M_ALD(REG_ATMP2, REG_SP, 4 * 4);
2035
2036         /* copy arguments into stackframe */
2037         for (i = md->paramcount -1, j = i + nativeparams; i >= 0; --i, --j)     {
2038                 t = md->paramtypes[i].type;
2039                 /* all arguments via stack */
2040                 assert(md->params[i].inmemory);                                         
2041
2042                 s1 = (md->params[i].regoff + cd->stackframesize + 1) * 4;
2043                 s2 = nmd->params[j].regoff * 4;
2044
2045                 /* simply copy argument stack */
2046                 M_ILD(REG_ITMP1, REG_SP, s1);
2047                 M_IST(REG_ITMP1, REG_SP, s2);
2048                 if (IS_2_WORD_TYPE(t))  {
2049                         M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2050                         M_IST(REG_ITMP1, REG_SP, s2 + 4);
2051                 }
2052         }
2053
2054         /* for static function class as second arg */
2055         if (m->flags & ACC_STATIC)      {
2056                 M_AMOV_IMM(m->class, REG_ATMP1);
2057                 M_AST(REG_ATMP1, REG_SP, 1 * 4);
2058         }
2059         /* env ist first argument */
2060         M_AMOV_IMM(_Jv_env, REG_ATMP1);
2061         M_AST(REG_ATMP1, REG_SP, 0 * 4);
2062
2063         /* call the native function */
2064         M_JSR(REG_ATMP2);
2065
2066         /* save return value */
2067         switch (md->returntype.type)    {
2068                 case TYPE_VOID: break;
2069
2070 #if defined(ENABLE_SOFTFLOAT)
2071                 case TYPE_DBL:
2072 #endif
2073                 case TYPE_LNG:
2074                         M_IST(REG_D1, REG_SP, 2 * 4);
2075                         /* fall through */
2076
2077 #if defined(ENABLE_SOFTFLOAT)
2078                 case TYPE_FLT:
2079 #endif
2080                 case TYPE_INT:
2081                 case TYPE_ADR:
2082                         M_IST(REG_D0, REG_SP, 1 * 4);
2083                         break;
2084
2085 #if !defined(ENABLE_SOFTFLOAT)
2086                 case TYPE_FLT:
2087                 case TYPE_DBL:  /* FIXME */
2088 #endif
2089                 default: assert(0);
2090         }
2091         
2092         /* print call trace */
2093 #if ! defined(NDEBUG)
2094         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2095                 emit_verbosecall_exit(jd);
2096         }
2097 #endif
2098         /* remove native stackframe info */
2099         /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
2100
2101         M_AMOV(REG_SP, REG_ATMP3);
2102         M_AADD_IMM(cd->stackframesize * 4, REG_ATMP3);
2103         M_AST(REG_ATMP3, REG_SP, 0 * 4);                        /* datasp */
2104         M_JSR_IMM(codegen_finish_native_call);
2105         
2106         M_INT2ADRMOVE(REG_RESULT, REG_ATMP3);
2107         /* restore return value */
2108         switch (md->returntype.type)    {
2109                 case TYPE_VOID: break;
2110
2111 #if defined(ENABLE_SOFTFLOAT)
2112                 case TYPE_DBL:
2113 #endif
2114                 case TYPE_LNG:
2115                         M_ILD(REG_D1, REG_SP, 2 * 4);
2116                         /* fall through */
2117 #if defined(ENABLE_SOFTFLOAT)
2118                 case TYPE_FLT:
2119 #endif
2120                 case TYPE_INT:
2121                 case TYPE_ADR:
2122                         M_ILD(REG_D0, REG_SP, 1 * 4);
2123                         break;
2124
2125 #if !defined(ENABLE_SOFTFLOAT)
2126                 case TYPE_FLT:
2127                 case TYPE_DBL:  /* FIXME */
2128 #endif
2129                 default: assert(0);
2130         }
2131         /* restore saved registers */
2132
2133         M_AADD_IMM(cd->stackframesize*4, REG_SP);
2134         /* check for exception */
2135         M_ATST(REG_ATMP3);
2136         M_BNE(2);
2137         M_RET;
2138
2139         /* handle exception */
2140         M_JSR_IMM(0);   /* FIXME */
2141
2142
2143         /* generate patcher stub call code */
2144         emit_patcher_stubs(jd);
2145 }
2146
2147
2148 /*
2149  * These are local overrides for various environment variables in Emacs.
2150  * Please do not remove this and leave it at the end of the file, where
2151  * Emacs will automagically detect them.
2152  * ---------------------------------------------------------------------
2153  * Local variables:
2154  * mode: c
2155  * indent-tabs-mode: t
2156  * c-basic-offset: 4
2157  * tab-width: 4
2158  * End:
2159  * vim:noexpandtab:sw=4:ts=4:
2160  */