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