Merged revisions 7797-7917 via svnmerge from
[cacao.git] / src / vm / jit / powerpc / codegen.c
1 /* src/vm/jit/powerpc/codegen.c - machine code generator for 32-bit PowerPC
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 7918 2007-05-20 20:42:18Z michi $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33 #include <stdio.h>
34 #include <signal.h>
35
36 #include "vm/types.h"
37
38 #include "md-abi.h"
39
40 #include "vm/jit/powerpc/arch.h"
41 #include "vm/jit/powerpc/codegen.h"
42
43 #include "mm/memory.h"
44
45 #include "native/native.h"
46
47 #include "threads/lock-common.h"
48
49 #include "vm/builtin.h"
50 #include "vm/exceptions.h"
51 #include "vm/global.h"
52 #include "vm/stringlocal.h"
53 #include "vm/vm.h"
54
55 #include "vm/jit/abi.h"
56 #include "vm/jit/abi-asm.h"
57 #include "vm/jit/asmpart.h"
58 #include "vm/jit/codegen-common.h"
59 #include "vm/jit/dseg.h"
60 #include "vm/jit/emit-common.h"
61 #include "vm/jit/jit.h"
62 #include "vm/jit/md.h"
63 #include "vm/jit/methodheader.h"
64 #include "vm/jit/parse.h"
65 #include "vm/jit/patcher.h"
66 #include "vm/jit/reg.h"
67 #include "vm/jit/replace.h"
68 #include "vm/jit/stacktrace.h"
69
70 #if defined(ENABLE_LSRA)
71 # include "vm/jit/allocator/lsra.h"
72 #endif
73
74 #include "vmcore/loader.h"
75 #include "vmcore/options.h"
76
77
78 /* codegen *********************************************************************
79
80    Generates machine code.
81
82 *******************************************************************************/
83
84 bool codegen_emit(jitdata *jd)
85 {
86         methodinfo         *m;
87         codeinfo           *code;
88         codegendata        *cd;
89         registerdata       *rd;
90         s4                  len, s1, s2, s3, d, disp;
91         ptrint              a;
92         varinfo            *var;
93         basicblock         *bptr;
94         instruction        *iptr;
95         exception_entry    *ex;
96         u2                  currentline;
97         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
98         unresolved_method  *um;
99         builtintable_entry *bte;
100         methoddesc         *md;
101         fieldinfo          *fi;
102         unresolved_field   *uf;
103         s4                  fieldtype;
104         s4                 varindex;
105
106         /* get required compiler data */
107
108         m    = jd->m;
109         code = jd->code;
110         cd   = jd->cd;
111         rd   = jd->rd;
112
113         /* prevent compiler warnings */
114
115         d         = 0;
116         fieldtype = 0;
117         lm        = NULL;
118         um        = NULL;
119         uf        = NULL;
120         bte       = NULL;
121
122         {
123         s4 i, p, t, l;
124         s4 savedregs_num;
125
126         savedregs_num = 0;
127
128         /* space to save used callee saved registers */
129
130         savedregs_num += (INT_SAV_CNT - rd->savintreguse);
131         savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
132
133         cd->stackframesize = rd->memuse + savedregs_num;
134
135 #if defined(ENABLE_THREADS)
136         /* Space to save argument of monitor_enter and Return Values to
137            survive monitor_exit. The stack position for the argument can
138            not be shared with place to save the return register on PPC,
139            since both values reside in R3. */
140
141         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
142                 /* reserve 2 slots for long/double return values for monitorexit */
143
144                 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type))
145                         cd->stackframesize += 3;
146                 else
147                         cd->stackframesize += 2;
148         }
149
150 #endif
151
152         /* create method header */
153
154         /* align stack to 16-bytes */
155
156         if (!jd->isleafmethod || JITDATA_HAS_FLAG_VERBOSECALL(jd))
157                 cd->stackframesize = (cd->stackframesize + 3) & ~3;
158
159         else if (jd->isleafmethod && (cd->stackframesize == LA_SIZE_IN_POINTERS))
160                 cd->stackframesize = 0;
161
162         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
163         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
164
165 #if defined(ENABLE_THREADS)
166         /* IsSync contains the offset relative to the stack pointer for the
167            argument of monitor_exit used in the exception handler. Since the
168            offset could be zero and give a wrong meaning of the flag it is
169            offset by one.
170         */
171
172         if (checksync && (m->flags & ACC_SYNCHRONIZED))
173                 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4);/* IsSync         */
174         else
175 #endif
176                 (void) dseg_add_unique_s4(cd, 0);                  /* IsSync          */
177                                                
178         (void) dseg_add_unique_s4(cd, jd->isleafmethod);       /* IsLeaf          */
179         (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
180         (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
181
182         dseg_addlinenumbertablesize(cd);
183
184         (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize   */
185
186         /* create exception table */
187
188         for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
189                 dseg_add_target(cd, ex->start);
190                 dseg_add_target(cd, ex->end);
191                 dseg_add_target(cd, ex->handler);
192                 (void) dseg_add_unique_address(cd, ex->catchtype.any);
193         }
194
195 #if defined(ENABLE_PROFILING)
196         /* generate method profiling code */
197
198         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
199                 /* count frequency */
200
201                 M_ALD(REG_ITMP1, REG_PV, CodeinfoPointer);
202                 M_ALD(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
203                 M_IADD_IMM(REG_ITMP2, 1, REG_ITMP2);
204                 M_AST(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
205
206 /*              PROFILE_CYCLE_START; */
207         }
208 #endif
209
210         /* create stack frame (if necessary) */
211
212         if (!jd->isleafmethod) {
213                 M_MFLR(REG_ZERO);
214                 M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET);
215         }
216
217         if (cd->stackframesize)
218                 M_STWU(REG_SP, REG_SP, -(cd->stackframesize * 4));
219
220         /* save return address and used callee saved registers */
221
222         p = cd->stackframesize;
223         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
224                 p--; M_IST(rd->savintregs[i], REG_SP, p * 4);
225         }
226         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
227                 p -= 2; M_DST(rd->savfltregs[i], REG_SP, p * 4);
228         }
229
230         /* take arguments out of register or stack frame */
231
232         md = m->parseddesc;
233
234         for (p = 0, l = 0; p < md->paramcount; p++) {
235                 t = md->paramtypes[p].type;
236                 varindex = jd->local_map[l * 5 + t];
237
238                 l++;
239                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
240                         l++;
241
242                 if (varindex == UNUSED)
243                         continue;
244
245                 var = VAR(varindex);
246                 s1  = md->params[p].regoff;
247
248                 if (IS_INT_LNG_TYPE(t)) {
249                         if (!md->params[p].inmemory) {
250                                 if (!IS_INMEMORY(var->flags)) {
251                                         if (IS_2_WORD_TYPE(t))
252                                                 M_LNGMOVE(s1, var->vv.regoff);
253                                         else
254                                                 M_INTMOVE(s1, var->vv.regoff);
255                                 }
256                                 else {
257                                         if (IS_2_WORD_TYPE(t))
258                                                 M_LST(s1, REG_SP, var->vv.regoff * 4);
259                                         else
260                                                 M_IST(s1, REG_SP, var->vv.regoff * 4);
261                                 }
262                         }
263                         else {
264                                 if (!IS_INMEMORY(var->flags)) {
265                                         if (IS_2_WORD_TYPE(t))
266                                                 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
267                                         else
268                                                 M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
269                                 }
270                                 else {
271 #if 1
272                                         M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4);
273                                         M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4);
274                                         if (IS_2_WORD_TYPE(t)) {
275                                                 M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4 +4);
276                                                 M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4 + 4);
277                                         }
278 #else
279                                         /* Reuse Memory Position on Caller Stack */
280                                         var->vv.regoff = cd->stackframesize + s1;
281 #endif
282                                 }
283                         }
284                 }
285                 else {
286                         if (!md->params[p].inmemory) {
287                                 if (!IS_INMEMORY(var->flags))
288                                         M_FLTMOVE(s1, var->vv.regoff);
289                                 else {
290                                         if (IS_2_WORD_TYPE(t))
291                                                 M_DST(s1, REG_SP, var->vv.regoff * 4);
292                                         else
293                                                 M_FST(s1, REG_SP, var->vv.regoff * 4);
294                                 }
295                         }
296                         else {
297                                 if (!IS_INMEMORY(var->flags)) {
298                                         if (IS_2_WORD_TYPE(t))
299                                                 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
300                                         else
301                                                 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
302                                 }
303                                 else {
304 #if 1
305                                         if (IS_2_WORD_TYPE(t)) {
306                                                 M_DLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
307                                                 M_DST(REG_FTMP1, REG_SP, var->vv.regoff * 4);
308                                                 var->vv.regoff = cd->stackframesize + s1;
309
310                                         } else {
311                                                 M_FLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
312                                                 M_FST(REG_FTMP1, REG_SP, var->vv.regoff * 4);
313                                         }
314 #else
315                                         /* Reuse Memory Position on Caller Stack */
316                                         var->vv.regoff = cd->stackframesize + s1;
317 #endif
318                                 }
319                         }
320                 }
321         }
322
323 #if defined(ENABLE_THREADS)
324         /* call monitorenter function */
325
326         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
327                 /* stack offset for monitor argument */
328
329                 s1 = rd->memuse;
330
331 # if !defined(NDEBUG)
332                 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
333                         M_AADD_IMM(REG_SP, -((LA_SIZE_IN_POINTERS + ARG_CNT) * 8), REG_SP);
334
335                         for (p = 0; p < INT_ARG_CNT; p++)
336                                 M_IST(abi_registers_integer_argument[p], REG_SP, LA_SIZE + p * 8);
337
338                         for (p = 0; p < FLT_ARG_CNT; p++)
339                                 M_DST(abi_registers_float_argument[p], REG_SP, LA_SIZE + (INT_ARG_CNT + p) * 8);
340
341                         /* ATTENTION: We multiply here with 2, because we use * 8
342                            above for simplicity and below * 4! */
343
344                         s1 += (LA_SIZE_IN_POINTERS + ARG_CNT) * 2;
345                 }
346 # endif
347
348                 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
349                 M_ALD(REG_ITMP3, REG_PV, disp);
350                 M_MTCTR(REG_ITMP3);
351
352                 /* get or test the lock object */
353
354                 if (m->flags & ACC_STATIC) {
355                         disp = dseg_add_address(cd, &m->class->object.header);
356                         M_ALD(REG_A0, REG_PV, disp);
357                 }
358                 else {
359                         M_TST(REG_A0);
360                         M_BNE(1);
361                         M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
362                 }
363
364                 M_AST(REG_A0, REG_SP, s1 * 4);
365                 M_JSR;
366
367 # if !defined(NDEBUG)
368                 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
369                         for (p = 0; p < INT_ARG_CNT; p++)
370                                 M_ILD(abi_registers_integer_argument[p], REG_SP, LA_SIZE + p * 8);
371
372                         for (p = 0; p < FLT_ARG_CNT; p++)
373                                 M_DLD(abi_registers_float_argument[p], REG_SP, LA_SIZE + (INT_ARG_CNT + p) * 8);
374
375                         M_AADD_IMM(REG_SP, (LA_SIZE_IN_POINTERS + ARG_CNT) * 8, REG_SP);
376                 }
377 # endif
378         }
379 #endif /* defined(ENABLE_THREADS) */
380
381         /* call trace function */
382
383         emit_verbosecall_enter(jd);
384         }
385
386         /* end of header generation */
387
388         /* create replacement points */
389
390         REPLACEMENT_POINTS_INIT(cd, jd);
391
392         /* walk through all basic blocks */
393
394         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
395
396                 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
397
398                 if (bptr->flags >= BBREACHED) {
399                 /* branch resolving */
400
401                 codegen_resolve_branchrefs(cd, bptr);
402
403                 /* handle replacement points */
404
405                 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
406
407 #if defined(ENABLE_PROFILING)
408                 /* generate basicblock profiling code */
409
410                 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
411                         /* count frequency */
412
413                         disp = dseg_add_address(cd, code->bbfrequency);
414                         M_ALD(REG_ITMP2, REG_PV, disp);
415                         M_ALD(REG_ITMP3, REG_ITMP2, bptr->nr * 4);
416                         M_IADD_IMM(REG_ITMP3, 1, REG_ITMP3);
417                         M_AST(REG_ITMP3, REG_ITMP2, bptr->nr * 4);
418
419                         /* if this is an exception handler, start profiling again */
420
421 /*                      if (bptr->type == BBTYPE_EXH) */
422 /*                              PROFILE_CYCLE_START; */
423                 }
424 #endif
425
426                 /* copy interface registers to their destination */
427
428                 len = bptr->indepth;
429                 MCODECHECK(64+len);
430
431 #if defined(ENABLE_LSRA)
432                 if (opt_lsra) {
433                         while (src != NULL) {
434                                 len--;
435                                 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
436                                         /* d = reg_of_var(m, src, REG_ITMP1); */
437                                         if (!IS_INMEMORY(src->flags))
438                                                 d = src->vv.regoff;
439                                         else
440                                                 d = REG_ITMP1;
441                                         M_INTMOVE(REG_ITMP1, d);
442                                         emit_store(jd, NULL, src, d);
443                                 }
444                                 src = src->prev;
445                         }
446                 } else {
447 #endif
448                 while (len > 0) {
449                         len--;
450                         var = VAR(bptr->invars[len]);
451                         if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
452                                 d = codegen_reg_of_var(0, var, REG_ITMP1);
453                                 M_INTMOVE(REG_ITMP1, d);
454                                 emit_store(jd, NULL, var, d);
455                         }
456                         else {
457                                 assert((var->flags & INOUT));
458                         }
459                 }
460
461 #if defined(ENABLE_LSRA)
462                 }
463 #endif
464                 /* walk through all instructions */
465                 
466                 len = bptr->icount;
467                 currentline = 0;
468
469                 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
470                         if (iptr->line != currentline) {
471                                 dseg_addlinenumber(cd, iptr->line);
472                                 currentline = iptr->line;
473                         }
474
475                         MCODECHECK(64);   /* an instruction usually needs < 64 words      */
476
477                 switch (iptr->opc) {
478                 case ICMD_NOP:        /* ...  ==> ...                                 */
479                 case ICMD_POP:        /* ..., value  ==> ...                          */
480                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
481                         break;
482
483                 case ICMD_INLINE_START:
484
485                         REPLACEMENT_POINT_INLINE_START(cd, iptr);
486                         break;
487
488                 case ICMD_INLINE_BODY:
489
490                         REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
491                         dseg_addlinenumber_inline_start(cd, iptr);
492                         dseg_addlinenumber(cd, iptr->line);
493                         break;
494
495                 case ICMD_INLINE_END:
496
497                         dseg_addlinenumber_inline_end(cd, iptr);
498                         dseg_addlinenumber(cd, iptr->line);
499                         break;
500
501                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
502
503                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
504                         emit_nullpointer_check(cd, iptr, s1);
505                         break;
506
507                 /* constant operations ************************************************/
508
509                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
510
511                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
512                         ICONST(d, iptr->sx.val.i);
513                         emit_store_dst(jd, iptr, d);
514                         break;
515
516                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
517
518                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
519                         LCONST(d, iptr->sx.val.l);
520                         emit_store_dst(jd, iptr, d);
521                         break;
522
523                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
524
525                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
526                         a = dseg_add_float(cd, iptr->sx.val.f);
527                         M_FLD(d, REG_PV, a);
528                         emit_store_dst(jd, iptr, d);
529                         break;
530                         
531                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
532
533                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
534                         a = dseg_add_double(cd, iptr->sx.val.d);
535                         M_DLD(d, REG_PV, a);
536                         emit_store_dst(jd, iptr, d);
537                         break;
538
539                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
540
541                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
542
543                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
544                                 constant_classref *cr = iptr->sx.val.c.ref;;
545
546                                 disp = dseg_add_unique_address(cd, cr);
547
548                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
549                                                                         cr, disp);
550                         }
551                         else
552                                 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
553
554                         M_ALD(d, REG_PV, disp);
555                         emit_store_dst(jd, iptr, d);
556                         break;
557
558
559                 /* load/store/copy/move operations ************************************/
560
561                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
562                 case ICMD_ALOAD:      /* s1 = local variable                          */
563                 case ICMD_LLOAD:
564                 case ICMD_FLOAD:  
565                 case ICMD_DLOAD:  
566                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
567                 case ICMD_LSTORE:
568                 case ICMD_FSTORE:
569                 case ICMD_DSTORE: 
570                 case ICMD_COPY:
571                 case ICMD_MOVE:
572                         
573                         emit_copy(jd, iptr);
574                         break;
575         
576                 case ICMD_ASTORE:
577
578                         if (!(iptr->flags.bits & INS_FLAG_RETADDR))
579                                 emit_copy(jd, iptr);
580                         break;
581
582
583                 /* integer operations *************************************************/
584
585                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
586
587                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
588                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
589                         M_NEG(s1, d);
590                         emit_store_dst(jd, iptr, d);
591                         break;
592
593                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
594
595                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
596                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
597                         M_SUBFIC(GET_LOW_REG(s1), 0, GET_LOW_REG(d));
598                         M_SUBFZE(GET_HIGH_REG(s1), GET_HIGH_REG(d));
599                         emit_store_dst(jd, iptr, d);
600                         break;
601
602                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
603
604                         s1 = emit_load_s1(jd, iptr, REG_ITMP2);
605                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
606                         M_INTMOVE(s1, GET_LOW_REG(d));
607                         M_SRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
608                         emit_store_dst(jd, iptr, d);
609                         break;
610
611                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
612
613                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
614                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
615                         M_INTMOVE(s1, d);
616                         emit_store_dst(jd, iptr, d);
617                         break;
618
619                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
620
621                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
622                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
623                         M_BSEXT(s1, d);
624                         emit_store_dst(jd, iptr, d);
625                         break;
626
627                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
628
629                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
630                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
631                         M_CZEXT(s1, d);
632                         emit_store_dst(jd, iptr, d);
633                         break;
634
635                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
636
637                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
638                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
639                         M_SSEXT(s1, d);
640                         emit_store_dst(jd, iptr, d);
641                         break;
642
643
644                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
645
646                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
647                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
648                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
649                         M_IADD(s1, s2, d);
650                         emit_store_dst(jd, iptr, d);
651                         break;
652
653                                       /* s1.localindex = variable, sx.val.i = constant*/
654
655                 case ICMD_IINC:
656                 case ICMD_IADDCONST:
657
658                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
659                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
660                         if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
661                                 M_IADD_IMM(s1, iptr->sx.val.i, d);
662                         } else {
663                                 ICONST(REG_ITMP2, iptr->sx.val.i);
664                                 M_IADD(s1, REG_ITMP2, d);
665                         }
666                         /* XXX the old code for ICMD_IINC was as follows:
667                         {
668                                 u4 m = iptr->sx.val.i;
669                                 if (m & 0x8000)
670                                         m += 65536;
671                                 if (m & 0xffff0000)
672                                         M_ADDIS(s1, m >> 16, d);
673                                 if (m & 0xffff)
674                                         M_IADD_IMM(s1, m & 0xffff, d);
675                         }
676                         */
677                         emit_store_dst(jd, iptr, d);
678                         break;
679
680                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
681
682                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
683                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
684                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
685                         M_ADDC(s1, s2, GET_LOW_REG(d));
686                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
687                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
688                         M_ADDE(s1, s2, GET_HIGH_REG(d));
689                         emit_store_dst(jd, iptr, d);
690                         break;
691
692                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
693                                       /* sx.val.l = constant                          */
694
695                         s3 = iptr->sx.val.l & 0xffffffff;
696                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
697                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
698                         if ((s3 >= -32768) && (s3 <= 32767))
699                                 M_ADDIC(s1, s3, GET_LOW_REG(d));
700                         else {
701                                 ICONST(REG_ITMP2, s3);
702                                 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
703                         }
704                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
705                         s3 = iptr->sx.val.l >> 32;
706                         if (s3 == -1)
707                                 M_ADDME(s1, GET_HIGH_REG(d));
708                         else if (s3 == 0)
709                                 M_ADDZE(s1, GET_HIGH_REG(d));
710                         else {
711                                 ICONST(REG_ITMP3, s3);                 /* don't use REG_ITMP2 */
712                                 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
713                         }
714                         emit_store_dst(jd, iptr, d);
715                         break;
716
717                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
718
719                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
720                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
721                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
722                         M_ISUB(s1, s2, d);
723                         emit_store_dst(jd, iptr, d);
724                         break;
725
726                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
727                                       /* sx.val.i = constant                          */
728
729                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
730                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
731                         if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
732                                 M_IADD_IMM(s1, -iptr->sx.val.i, d);
733                         else {
734                                 ICONST(REG_ITMP2, iptr->sx.val.i);
735                                 M_ISUB(s1, REG_ITMP2, d);
736                         }
737                         emit_store_dst(jd, iptr, d);
738                         break;
739
740                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
741
742                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
743                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
744                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
745                         M_SUBC(s1, s2, GET_LOW_REG(d));
746                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
747                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
748                         M_SUBE(s1, s2, GET_HIGH_REG(d));
749                         emit_store_dst(jd, iptr, d);
750                         break;
751
752                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
753                                       /* sx.val.l = constant                          */
754
755                         s3 = (-iptr->sx.val.l) & 0xffffffff;
756                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
757                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
758                         if ((s3 >= -32768) && (s3 <= 32767)) {
759                                 M_ADDIC(s1, s3, GET_LOW_REG(d));
760                         } else {
761                                 ICONST(REG_ITMP2, s3);
762                                 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
763                         }
764                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
765                         s3 = (-iptr->sx.val.l) >> 32;
766                         if (s3 == -1)
767                                 M_ADDME(s1, GET_HIGH_REG(d));
768                         else if (s3 == 0)
769                                 M_ADDZE(s1, GET_HIGH_REG(d));
770                         else {
771                                 ICONST(REG_ITMP3, s3);                 /* don't use REG_ITMP2 */
772                                 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
773                         }
774                         emit_store_dst(jd, iptr, d);
775                         break;
776
777                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
778
779                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
780                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
781                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
782                         emit_arithmetic_check(cd, iptr, s2);
783                         M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
784                         M_CMP(REG_ITMP3, s1);
785                         M_BNE(3 + (s1 != d));
786                         M_CMPI(s2, -1);
787                         M_BNE(1 + (s1 != d));
788                         M_INTMOVE(s1, d);
789                         M_BR(1);
790                         M_IDIV(s1, s2, d);
791                         emit_store_dst(jd, iptr, d);
792                         break;
793
794                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
795
796                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
797                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
798                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
799                         emit_arithmetic_check(cd, iptr, s2);
800                         M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
801                         M_CMP(REG_ITMP3, s1);
802                         M_BNE(4);
803                         M_CMPI(s2, -1);
804                         M_BNE(2);
805                         M_CLR(d);
806                         M_BR(3);
807                         M_IDIV(s1, s2, REG_ITMP3);
808                         M_IMUL(REG_ITMP3, s2, REG_ITMP3);
809                         M_ISUB(s1, REG_ITMP3, d);
810                         emit_store_dst(jd, iptr, d);
811                         break;
812
813                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
814                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
815
816                         s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
817                         s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
818
819                         /* XXX TODO: only do this if arithmetic check is really done! */
820                         M_OR_TST(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
821                         /* XXX could be optimized */
822                         emit_arithmetic_check(cd, iptr, REG_ITMP3);
823
824                         bte = iptr->sx.s23.s3.bte;
825                         disp = dseg_add_functionptr(cd, bte->fp);
826                         M_ALD(REG_ITMP3, REG_PV, disp);
827                         M_MTCTR(REG_ITMP3);
828
829                         M_LNGMOVE(s1, REG_A0_A1_PACKED);
830                         M_LNGMOVE(s2, REG_A2_A3_PACKED);
831
832                         M_JSR;
833
834                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
835                         M_LNGMOVE(REG_RESULT_PACKED, d);
836                         emit_store_dst(jd, iptr, d);
837                         break;
838
839                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
840
841                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
842                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
843                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
844                         M_IMUL(s1, s2, d);
845                         emit_store_dst(jd, iptr, d);
846                         break;
847
848                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
849                                       /* sx.val.i = constant                          */
850
851                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
852                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
853                         if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
854                                 M_IMUL_IMM(s1, iptr->sx.val.i, d);
855                         else {
856                                 ICONST(REG_ITMP3, iptr->sx.val.i);
857                                 M_IMUL(s1, REG_ITMP3, d);
858                         }
859                         emit_store_dst(jd, iptr, d);
860                         break;
861
862                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value << constant       */
863                                       
864                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
865                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
866                         M_SRA_IMM(s1, iptr->sx.val.i, d);
867                         M_ADDZE(d, d);
868                         emit_store_dst(jd, iptr, d);
869                         break;
870
871                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
872
873                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
874                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
875                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
876                         M_AND_IMM(s2, 0x1f, REG_ITMP3);
877                         M_SLL(s1, REG_ITMP3, d);
878                         emit_store_dst(jd, iptr, d);
879                         break;
880
881                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
882                                       /* sx.val.i = constant                          */
883
884                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
885                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
886                         M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
887                         emit_store_dst(jd, iptr, d);
888                         break;
889
890                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
891
892                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
893                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
894                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
895                         M_AND_IMM(s2, 0x1f, REG_ITMP3);
896                         M_SRA(s1, REG_ITMP3, d);
897                         emit_store_dst(jd, iptr, d);
898                         break;
899
900                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
901                                       /* sx.val.i = constant                          */
902
903                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
904                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
905                         M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
906                         emit_store_dst(jd, iptr, d);
907                         break;
908
909                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
910
911                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
912                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
913                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
914                         M_AND_IMM(s2, 0x1f, REG_ITMP2);
915                         M_SRL(s1, REG_ITMP2, d);
916                         emit_store_dst(jd, iptr, d);
917                         break;
918
919                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
920                                       /* sx.val.i = constant                          */
921
922                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
923                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
924                         if (iptr->sx.val.i & 0x1f)
925                                 M_SRL_IMM(s1, iptr->sx.val.i & 0x1f, d);
926                         else {
927                                 M_INTMOVE(s1, d);
928                         }
929                         emit_store_dst(jd, iptr, d);
930                         break;
931
932                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
933
934                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
935                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
936                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
937                         M_AND(s1, s2, d);
938                         emit_store_dst(jd, iptr, d);
939                         break;
940
941                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
942                                       /* sx.val.i = constant                          */
943
944                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
945                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
946                         if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
947                                 M_AND_IMM(s1, iptr->sx.val.i, d);
948                         /*
949                         else if (iptr->sx.val.i == 0xffffff) {
950                                 M_RLWINM(s1, 0, 8, 31, d);
951                                 }
952                         */
953                         else {
954                                 ICONST(REG_ITMP3, iptr->sx.val.i);
955                                 M_AND(s1, REG_ITMP3, d);
956                         }
957                         emit_store_dst(jd, iptr, d);
958                         break;
959
960                 case ICMD_LAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
961
962                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
963                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
964                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
965                         M_AND(s1, s2, GET_LOW_REG(d));
966                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
967                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
968                         M_AND(s1, s2, GET_HIGH_REG(d));
969                         emit_store_dst(jd, iptr, d);
970                         break;
971
972                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
973                                       /* sx.val.l = constant                          */
974
975                         s3 = iptr->sx.val.l & 0xffffffff;
976                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
977                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
978                         if ((s3 >= 0) && (s3 <= 65535))
979                                 M_AND_IMM(s1, s3, GET_LOW_REG(d));
980                         else {
981                                 ICONST(REG_ITMP3, s3);
982                                 M_AND(s1, REG_ITMP3, GET_LOW_REG(d));
983                         }
984                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
985                         s3 = iptr->sx.val.l >> 32;
986                         if ((s3 >= 0) && (s3 <= 65535))
987                                 M_AND_IMM(s1, s3, GET_HIGH_REG(d));
988                         else {
989                                 ICONST(REG_ITMP3, s3);                 /* don't use REG_ITMP2 */
990                                 M_AND(s1, REG_ITMP3, GET_HIGH_REG(d));
991                         }
992                         emit_store_dst(jd, iptr, d);
993                         break;
994
995                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
996                                       /* sx.val.i = constant                          */
997
998                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
999                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1000                         M_MOV(s1, REG_ITMP2);
1001                         M_CMPI(s1, 0);
1002                         M_BGE(1 + 2*(iptr->sx.val.i >= 32768));
1003                         if (iptr->sx.val.i >= 32768) {
1004                                 M_ADDIS(REG_ZERO, iptr->sx.val.i >> 16, REG_ITMP2);
1005                                 M_OR_IMM(REG_ITMP2, iptr->sx.val.i, REG_ITMP2);
1006                                 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1007                         }
1008                         else {
1009                                 M_IADD_IMM(s1, iptr->sx.val.i, REG_ITMP2);
1010                         }
1011                         {
1012                                 int b=0, m = iptr->sx.val.i;
1013                                 while (m >>= 1)
1014                                         ++b;
1015                                 M_RLWINM(REG_ITMP2, 0, 0, 30-b, REG_ITMP2);
1016                         }
1017                         M_ISUB(s1, REG_ITMP2, d);
1018                         emit_store_dst(jd, iptr, d);
1019                         break;
1020
1021                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1022
1023                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1024                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1025                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1026                         M_OR(s1, s2, d);
1027                         emit_store_dst(jd, iptr, d);
1028                         break;
1029
1030                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
1031                                       /* sx.val.i = constant                          */
1032
1033                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1034                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1035                         if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
1036                                 M_OR_IMM(s1, iptr->sx.val.i, d);
1037                         else {
1038                                 ICONST(REG_ITMP3, iptr->sx.val.i);
1039                                 M_OR(s1, REG_ITMP3, d);
1040                         }
1041                         emit_store_dst(jd, iptr, d);
1042                         break;
1043
1044                 case ICMD_LOR:       /* ..., val1, val2  ==> ..., val1 | val2        */
1045
1046                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1047                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1048                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1049                         M_OR(s1, s2, GET_LOW_REG(d));
1050                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1051                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
1052                         M_OR(s1, s2, GET_HIGH_REG(d));
1053                         emit_store_dst(jd, iptr, d);
1054                         break;
1055
1056                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
1057                                       /* sx.val.l = constant                          */
1058
1059                         s3 = iptr->sx.val.l & 0xffffffff;
1060                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1061                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1062                         if ((s3 >= 0) && (s3 <= 65535))
1063                                 M_OR_IMM(s1, s3, GET_LOW_REG(d));
1064                         else {
1065                                 ICONST(REG_ITMP3, s3);
1066                                 M_OR(s1, REG_ITMP3, GET_LOW_REG(d));
1067                         }
1068                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1069                         s3 = iptr->sx.val.l >> 32;
1070                         if ((s3 >= 0) && (s3 <= 65535))
1071                                 M_OR_IMM(s1, s3, GET_HIGH_REG(d));
1072                         else {
1073                                 ICONST(REG_ITMP3, s3);                 /* don't use REG_ITMP2 */
1074                                 M_OR(s1, REG_ITMP3, GET_HIGH_REG(d));
1075                         }
1076                         emit_store_dst(jd, iptr, d);
1077                         break;
1078
1079                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1080
1081                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1082                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1083                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1084                         M_XOR(s1, s2, d);
1085                         emit_store_dst(jd, iptr, d);
1086                         break;
1087
1088                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1089                                       /* sx.val.i = constant                          */
1090
1091                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1092                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1093                         if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
1094                                 M_XOR_IMM(s1, iptr->sx.val.i, d);
1095                         else {
1096                                 ICONST(REG_ITMP3, iptr->sx.val.i);
1097                                 M_XOR(s1, REG_ITMP3, d);
1098                         }
1099                         emit_store_dst(jd, iptr, d);
1100                         break;
1101
1102                 case ICMD_LXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1103
1104                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1105                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1106                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1107                         M_XOR(s1, s2, GET_LOW_REG(d));
1108                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1109                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
1110                         M_XOR(s1, s2, GET_HIGH_REG(d));
1111                         emit_store_dst(jd, iptr, d);
1112                         break;
1113
1114                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1115                                       /* sx.val.l = constant                          */
1116
1117                         s3 = iptr->sx.val.l & 0xffffffff;
1118                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1119                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1120                         if ((s3 >= 0) && (s3 <= 65535))
1121                                 M_XOR_IMM(s1, s3, GET_LOW_REG(d));
1122                         else {
1123                                 ICONST(REG_ITMP3, s3);
1124                                 M_XOR(s1, REG_ITMP3, GET_LOW_REG(d));
1125                         }
1126                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1127                         s3 = iptr->sx.val.l >> 32;
1128                         if ((s3 >= 0) && (s3 <= 65535))
1129                                 M_XOR_IMM(s1, s3, GET_HIGH_REG(d));
1130                         else {
1131                                 ICONST(REG_ITMP3, s3);                 /* don't use REG_ITMP2 */
1132                                 M_XOR(s1, REG_ITMP3, GET_HIGH_REG(d));
1133                         }
1134                         emit_store_dst(jd, iptr, d);
1135                         break;
1136
1137                 case ICMD_LCMP:       /* ..., val1, val2  ==> ..., val1 cmp val2      */
1138
1139                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1140                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1141                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1142                         vm_abort("codegen: implement ICMD_LCMP!");
1143                         emit_store_dst(jd, iptr, d);
1144                         break;
1145
1146
1147                 /* floating operations ************************************************/
1148
1149                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
1150
1151                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1152                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1153                         M_FMOVN(s1, d);
1154                         emit_store_dst(jd, iptr, d);
1155                         break;
1156
1157                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
1158
1159                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1160                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1161                         M_FMOVN(s1, d);
1162                         emit_store_dst(jd, iptr, d);
1163                         break;
1164
1165                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1166
1167                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1168                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1169                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1170                         M_FADD(s1, s2, d);
1171                         emit_store_dst(jd, iptr, d);
1172                         break;
1173
1174                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1175
1176                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1177                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1178                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1179                         M_DADD(s1, s2, d);
1180                         emit_store_dst(jd, iptr, d);
1181                         break;
1182
1183                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1184
1185                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1186                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1187                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1188                         M_FSUB(s1, s2, d);
1189                         emit_store_dst(jd, iptr, d);
1190                         break;
1191
1192                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1193
1194                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1195                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1196                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1197                         M_DSUB(s1, s2, d);
1198                         emit_store_dst(jd, iptr, d);
1199                         break;
1200
1201                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1202
1203                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1204                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1205                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1206                         M_FMUL(s1, s2, d);
1207                         emit_store_dst(jd, iptr, d);
1208                         break;
1209
1210                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1211
1212                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1213                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1214                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1215                         M_DMUL(s1, s2, d);
1216                         emit_store_dst(jd, iptr, d);
1217                         break;
1218
1219                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1220
1221                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1222                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1223                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1224                         M_FDIV(s1, s2, d);
1225                         emit_store_dst(jd, iptr, d);
1226                         break;
1227
1228                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1229
1230                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1231                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1232                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1233                         M_DDIV(s1, s2, d);
1234                         emit_store_dst(jd, iptr, d);
1235                         break;
1236                 
1237                 case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
1238                 case ICMD_D2I:
1239
1240                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1241                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1242                         M_CLR(d);
1243                         disp = dseg_add_float(cd, 0.0);
1244                         M_FLD(REG_FTMP2, REG_PV, disp);
1245                         M_FCMPU(s1, REG_FTMP2);
1246                         M_BNAN(4);
1247                         disp = dseg_add_unique_s4(cd, 0);
1248                         M_CVTDL_C(s1, REG_FTMP1);
1249                         M_LDA(REG_ITMP1, REG_PV, disp);
1250                         M_STFIWX(REG_FTMP1, 0, REG_ITMP1);
1251                         M_ILD(d, REG_PV, disp);
1252                         emit_store_dst(jd, iptr, d);
1253                         break;
1254                 
1255                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1256
1257                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1258                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1259                         M_FLTMOVE(s1, d);
1260                         emit_store_dst(jd, iptr, d);
1261                         break;
1262                                         
1263                 case ICMD_D2F:       /* ..., value  ==> ..., (double) value           */
1264
1265                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1266                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1267                         M_CVTDF(s1, d);
1268                         emit_store_dst(jd, iptr, d);
1269                         break;
1270                 
1271                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1272                 case ICMD_DCMPL:      /* == => 0, < => 1, > => -1                     */
1273
1274
1275                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1276                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1277                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1278                         M_FCMPU(s2, s1);
1279                         M_IADD_IMM(REG_ZERO, -1, d);
1280                         M_BNAN(4);
1281                         M_BGT(3);
1282                         M_IADD_IMM(REG_ZERO, 0, d);
1283                         M_BGE(1);
1284                         M_IADD_IMM(REG_ZERO, 1, d);
1285                         emit_store_dst(jd, iptr, d);
1286                         break;
1287
1288                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1289                 case ICMD_DCMPG:      /* == => 0, < => 1, > => -1                     */
1290
1291                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1292                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1293                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1294                         M_FCMPU(s1, s2);
1295                         M_IADD_IMM(REG_ZERO, 1, d);
1296                         M_BNAN(4);
1297                         M_BGT(3);
1298                         M_IADD_IMM(REG_ZERO, 0, d);
1299                         M_BGE(1);
1300                         M_IADD_IMM(REG_ZERO, -1, d);
1301                         emit_store_dst(jd, iptr, d);
1302                         break;
1303                         
1304                 case ICMD_IF_FCMPEQ:    /* ..., value, value ==> ...                  */
1305                 case ICMD_IF_DCMPEQ:
1306
1307                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1308                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1309                         M_FCMPU(s1, s2);
1310                         M_BNAN(1);
1311                         emit_beq(cd, iptr->dst.block);
1312                         break;
1313
1314                 case ICMD_IF_FCMPNE:    /* ..., value, value ==> ...                  */
1315                 case ICMD_IF_DCMPNE:
1316
1317                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1318                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1319                         M_FCMPU(s1, s2);
1320                         emit_bnan(cd, iptr->dst.block);
1321                         emit_bne(cd, iptr->dst.block);
1322                         break;
1323
1324
1325                 case ICMD_IF_FCMPL_LT:  /* ..., value, value ==> ...                  */
1326                 case ICMD_IF_DCMPL_LT:
1327
1328                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1329                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1330                         M_FCMPU(s1, s2);
1331                         emit_bnan(cd, iptr->dst.block);
1332                         emit_blt(cd, iptr->dst.block);
1333                         break;
1334
1335                 case ICMD_IF_FCMPL_GT:  /* ..., value, value ==> ...                  */
1336                 case ICMD_IF_DCMPL_GT:
1337
1338                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1339                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1340                         M_FCMPU(s1, s2);
1341                         M_BNAN(1);
1342                         emit_bgt(cd, iptr->dst.block);
1343                         break;
1344
1345                 case ICMD_IF_FCMPL_LE:  /* ..., value, value ==> ...                  */
1346                 case ICMD_IF_DCMPL_LE:
1347
1348                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1349                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1350                         M_FCMPU(s1, s2);
1351                         emit_bnan(cd, iptr->dst.block);
1352                         emit_ble(cd, iptr->dst.block);
1353                         break;
1354
1355                 case ICMD_IF_FCMPL_GE:  /* ..., value, value ==> ...                  */
1356                 case ICMD_IF_DCMPL_GE:
1357
1358                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1359                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1360                         M_FCMPU(s1, s2);
1361                         M_BNAN(1);
1362                         emit_bge(cd, iptr->dst.block);
1363                         break;
1364
1365                 case ICMD_IF_FCMPG_LT:  /* ..., value, value ==> ...                  */
1366                 case ICMD_IF_DCMPG_LT:
1367
1368                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1369                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1370                         M_FCMPU(s1, s2);
1371                         M_BNAN(1);
1372                         emit_blt(cd, iptr->dst.block);
1373                         break;
1374
1375                 case ICMD_IF_FCMPG_GT:  /* ..., value, value ==> ...                  */
1376                 case ICMD_IF_DCMPG_GT:
1377
1378                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1379                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1380                         M_FCMPU(s1, s2);
1381                         emit_bnan(cd, iptr->dst.block);
1382                         emit_bgt(cd, iptr->dst.block);
1383                         break;
1384
1385                 case ICMD_IF_FCMPG_LE:  /* ..., value, value ==> ...                  */
1386                 case ICMD_IF_DCMPG_LE:
1387
1388                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1389                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1390                         M_FCMPU(s1, s2);
1391                         M_BNAN(1);
1392                         emit_ble(cd, iptr->dst.block);
1393                         break;
1394
1395                 case ICMD_IF_FCMPG_GE:  /* ..., value, value ==> ...                  */
1396                 case ICMD_IF_DCMPG_GE:
1397
1398                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1399                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1400                         M_FCMPU(s1, s2);
1401                         emit_bnan(cd, iptr->dst.block);
1402                         emit_bge(cd, iptr->dst.block);
1403                         break;
1404
1405
1406                 /* memory operations **************************************************/
1407
1408                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1409
1410                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1411                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1412                         /* implicit null-pointer check */
1413                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
1414                         emit_store_dst(jd, iptr, d);
1415                         break;
1416
1417                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1418
1419                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1420                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1421                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1422                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1423                         M_IADD_IMM(s2, OFFSET(java_bytearray, data[0]), REG_ITMP2);
1424                         /* implicit null-pointer check */
1425                         M_LBZX(d, s1, REG_ITMP2);
1426                         M_BSEXT(d, d);
1427                         emit_store_dst(jd, iptr, d);
1428                         break;                  
1429
1430                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1431
1432                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1433                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1434                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1435                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1436                         M_SLL_IMM(s2, 1, REG_ITMP2);
1437                         M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1438                         /* implicit null-pointer check */
1439                         M_LHZX(d, s1, REG_ITMP2);
1440                         emit_store_dst(jd, iptr, d);
1441                         break;
1442
1443                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1444
1445                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1446                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1447                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1448                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1449                         M_SLL_IMM(s2, 1, REG_ITMP2);
1450                         M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
1451                         /* implicit null-pointer check */
1452                         M_LHAX(d, s1, REG_ITMP2);
1453                         emit_store_dst(jd, iptr, d);
1454                         break;
1455
1456                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1457
1458                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1459                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1460                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1461                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1462                         M_SLL_IMM(s2, 2, REG_ITMP2);
1463                         M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1464                         /* implicit null-pointer check */
1465                         M_LWZX(d, s1, REG_ITMP2);
1466                         emit_store_dst(jd, iptr, d);
1467                         break;
1468
1469                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1470
1471                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1472                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1473                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1474                         /* implicit null-pointer check */
1475                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1476                         M_SLL_IMM(s2, 3, REG_ITMP2);
1477                         M_IADD(s1, REG_ITMP2, REG_ITMP2);
1478                         M_LLD_INTERN(d, REG_ITMP2, OFFSET(java_longarray, data[0]));
1479                         emit_store_dst(jd, iptr, d);
1480                         break;
1481
1482                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1483
1484                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1485                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1486                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1487                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1488                         M_SLL_IMM(s2, 2, REG_ITMP2);
1489                         M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1490                         /* implicit null-pointer check */
1491                         M_LFSX(d, s1, REG_ITMP2);
1492                         emit_store_dst(jd, iptr, d);
1493                         break;
1494
1495                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1496
1497                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1498                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1499                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1500                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1501                         M_SLL_IMM(s2, 3, REG_ITMP2);
1502                         M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1503                         /* implicit null-pointer check */
1504                         M_LFDX(d, s1, REG_ITMP2);
1505                         emit_store_dst(jd, iptr, d);
1506                         break;
1507
1508                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1509
1510                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1511                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1512                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1513                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1514                         M_SLL_IMM(s2, 2, REG_ITMP2);
1515                         M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2);
1516                         /* implicit null-pointer check */
1517                         M_LWZX(d, s1, REG_ITMP2);
1518                         emit_store_dst(jd, iptr, d);
1519                         break;
1520
1521
1522                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1523
1524                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1525                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1526                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1527                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1528                         M_IADD_IMM(s2, OFFSET(java_bytearray, data[0]), REG_ITMP2);
1529                         /* implicit null-pointer check */
1530                         M_STBX(s3, s1, REG_ITMP2);
1531                         break;
1532
1533                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1534
1535                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1536                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1537                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1538                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1539                         M_SLL_IMM(s2, 1, REG_ITMP2);
1540                         M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1541                         /* implicit null-pointer check */
1542                         M_STHX(s3, s1, REG_ITMP2);
1543                         break;
1544
1545                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1546
1547                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1548                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1549                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1550                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1551                         M_SLL_IMM(s2, 1, REG_ITMP2);
1552                         M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
1553                         /* implicit null-pointer check */
1554                         M_STHX(s3, s1, REG_ITMP2);
1555                         break;
1556
1557                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1558
1559                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1560                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1561                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1562                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1563                         M_SLL_IMM(s2, 2, REG_ITMP2);
1564                         M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1565                         /* implicit null-pointer check */
1566                         M_STWX(s3, s1, REG_ITMP2);
1567                         break;
1568
1569                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1570
1571                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1572                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1573                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1574                         s3 = emit_load_s3_high(jd, iptr, REG_ITMP3);
1575                         M_SLL_IMM(s2, 3, REG_ITMP2);
1576                         M_IADD_IMM(REG_ITMP2, OFFSET(java_longarray, data[0]), REG_ITMP2);
1577                         /* implicit null-pointer check */
1578                         M_STWX(s3, s1, REG_ITMP2);
1579                         M_IADD_IMM(REG_ITMP2, 4, REG_ITMP2);
1580                         s3 = emit_load_s3_low(jd, iptr, REG_ITMP3);
1581                         M_STWX(s3, s1, REG_ITMP2);
1582                         break;
1583
1584                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1585
1586                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1587                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1588                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1589                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1590                         M_SLL_IMM(s2, 2, REG_ITMP2);
1591                         M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1592                         /* implicit null-pointer check */
1593                         M_STFSX(s3, s1, REG_ITMP2);
1594                         break;
1595
1596                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1597
1598                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1599                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1600                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1601                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1602                         M_SLL_IMM(s2, 3, REG_ITMP2);
1603                         M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1604                         /* implicit null-pointer check */
1605                         M_STFDX(s3, s1, REG_ITMP2);
1606                         break;
1607
1608                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1609
1610                         s1 = emit_load_s1(jd, iptr, REG_A0);
1611                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1612                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1613                         s3 = emit_load_s3(jd, iptr, REG_A1);
1614
1615                         /* XXX what if array is NULL */
1616                         disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1617                         M_ALD(REG_ITMP3, REG_PV, disp);
1618                         M_MTCTR(REG_ITMP3);
1619
1620                         M_INTMOVE(s1, REG_A0);
1621                         M_INTMOVE(s3, REG_A1);
1622
1623                         M_JSR;
1624                         emit_exception_check(cd, iptr);
1625
1626                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1627                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1628                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1629                         M_SLL_IMM(s2, 2, REG_ITMP2);
1630                         M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2);
1631                         /* implicit null-pointer check */
1632                         M_STWX(s3, s1, REG_ITMP2);
1633                         break;
1634
1635
1636                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1637
1638                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1639                                 uf        = iptr->sx.s23.s3.uf;
1640                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1641                                 disp      = dseg_add_unique_address(cd, uf);
1642
1643                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1644                         }
1645                         else {
1646                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1647                                 fieldtype = fi->type;
1648                                 disp      = dseg_add_address(cd, &(fi->value));
1649
1650                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1651                                         codegen_addpatchref(cd, PATCHER_initialize_class,
1652                                                                                 fi->class, disp);
1653                         }
1654
1655                         M_ALD(REG_ITMP1, REG_PV, disp);
1656                         switch (fieldtype) {
1657                         case TYPE_INT:
1658                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1659                                 M_ILD_INTERN(d, REG_ITMP1, 0);
1660                                 break;
1661                         case TYPE_LNG:
1662                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1663                                 M_ILD_INTERN(GET_LOW_REG(d), REG_ITMP1, 4);/* keep this order */
1664                                 M_ILD_INTERN(GET_HIGH_REG(d), REG_ITMP1, 0);/*keep this order */
1665                                 break;
1666                         case TYPE_ADR:
1667                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1668                                 M_ALD_INTERN(d, REG_ITMP1, 0);
1669                                 break;
1670                         case TYPE_FLT:
1671                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1672                                 M_FLD_INTERN(d, REG_ITMP1, 0);
1673                                 break;
1674                         case TYPE_DBL:                          
1675                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1676                                 M_DLD_INTERN(d, REG_ITMP1, 0);
1677                                 break;
1678                         }
1679                         emit_store_dst(jd, iptr, d);
1680                         break;
1681
1682                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
1683
1684                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1685                                 uf        = iptr->sx.s23.s3.uf;
1686                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1687                                 disp      = dseg_add_unique_address(cd, uf);
1688
1689                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1690                         }
1691                         else {
1692                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1693                                 fieldtype = fi->type;
1694                                 disp      = dseg_add_address(cd, &(fi->value));
1695
1696                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1697                                         codegen_addpatchref(cd, PATCHER_initialize_class,
1698                                                                                 fi->class, disp);
1699                         }
1700
1701                         M_ALD(REG_ITMP1, REG_PV, disp);
1702                         switch (fieldtype) {
1703                         case TYPE_INT:
1704                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1705                                 M_IST_INTERN(s1, REG_ITMP1, 0);
1706                                 break;
1707                         case TYPE_LNG:
1708                                 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1709                                 M_LST_INTERN(s1, REG_ITMP1, 0);
1710                                 break;
1711                         case TYPE_ADR:
1712                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1713                                 M_AST_INTERN(s1, REG_ITMP1, 0);
1714                                 break;
1715                         case TYPE_FLT:
1716                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1717                                 M_FST_INTERN(s1, REG_ITMP1, 0);
1718                                 break;
1719                         case TYPE_DBL:
1720                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1721                                 M_DST_INTERN(s1, REG_ITMP1, 0);
1722                                 break;
1723                         }
1724                         break;
1725
1726
1727                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
1728
1729                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1730
1731                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1732                                 uf        = iptr->sx.s23.s3.uf;
1733                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1734                                 disp      = 0;
1735
1736                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1737                         }
1738                         else {
1739                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1740                                 fieldtype = fi->type;
1741                                 disp      = fi->offset;
1742                         }
1743
1744                         /* implicit null-pointer check */
1745                         switch (fieldtype) {
1746                         case TYPE_INT:
1747                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1748                                 M_ILD(d, s1, disp);
1749                                 break;
1750                         case TYPE_LNG:
1751                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1752                                 if (GET_HIGH_REG(d) == s1) {
1753                                         M_ILD(GET_LOW_REG(d), s1, disp + 4);
1754                                         M_ILD(GET_HIGH_REG(d), s1, disp);
1755                                 }
1756                                 else {
1757                                         M_ILD(GET_HIGH_REG(d), s1, disp);
1758                                         M_ILD(GET_LOW_REG(d), s1, disp + 4);
1759                                 }
1760                                 break;
1761                         case TYPE_ADR:
1762                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1763                                 M_ALD(d, s1, disp);
1764                                 break;
1765                         case TYPE_FLT:
1766                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1767                                 M_FLD(d, s1, disp);
1768                                 break;
1769                         case TYPE_DBL:                          
1770                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1771                                 M_DLD(d, s1, disp);
1772                                 break;
1773                         }
1774                         emit_store_dst(jd, iptr, d);
1775                         break;
1776
1777                 case ICMD_PUTFIELD:   /* ..., value  ==> ...                          */
1778
1779                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1780
1781                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1782                                 uf        = iptr->sx.s23.s3.uf;
1783                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1784                                 disp      = 0;
1785                         }
1786                         else {
1787                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1788                                 fieldtype = fi->type;
1789                                 disp      = fi->offset;
1790                         }
1791
1792                         if (IS_INT_LNG_TYPE(fieldtype)) {
1793                                 if (IS_2_WORD_TYPE(fieldtype))
1794                                         s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1795                                 else
1796                                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1797                         }
1798                         else
1799                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1800
1801                         if (INSTRUCTION_IS_UNRESOLVED(iptr))
1802                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1803
1804                         /* implicit null-pointer check */
1805                         switch (fieldtype) {
1806                         case TYPE_INT:
1807                                 M_IST(s2, s1, disp);
1808                                 break;
1809                         case TYPE_LNG:
1810                                 M_IST(GET_LOW_REG(s2), s1, disp + 4);      /* keep this order */
1811                                 M_IST(GET_HIGH_REG(s2), s1, disp);         /* keep this order */
1812                                 break;
1813                         case TYPE_ADR:
1814                                 M_AST(s2, s1, disp);
1815                                 break;
1816                         case TYPE_FLT:
1817                                 M_FST(s2, s1, disp);
1818                                 break;
1819                         case TYPE_DBL:
1820                                 M_DST(s2, s1, disp);
1821                                 break;
1822                         }
1823                         break;
1824
1825
1826                 /* branch operations **************************************************/
1827
1828                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
1829
1830                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1831                         M_INTMOVE(s1, REG_ITMP1_XPTR);
1832
1833 #ifdef ENABLE_VERIFIER
1834                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1835                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
1836
1837                                 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
1838                         }
1839 #endif /* ENABLE_VERIFIER */
1840
1841                         disp = dseg_add_functionptr(cd, asm_handle_exception);
1842                         M_ALD(REG_ITMP2, REG_PV, disp);
1843                         M_MTCTR(REG_ITMP2);
1844
1845                         if (jd->isleafmethod)
1846                                 M_MFLR(REG_ITMP3);                          /* save LR        */
1847
1848                         M_BL(0);                                        /* get current PC */
1849                         M_MFLR(REG_ITMP2_XPC);
1850
1851                         if (jd->isleafmethod)
1852                                 M_MTLR(REG_ITMP3);                          /* restore LR     */
1853
1854                         M_RTS;                                          /* jump to CTR    */
1855                         ALIGNCODENOP;
1856                         break;
1857
1858                 case ICMD_GOTO:         /* ... ==> ...                                */
1859                 case ICMD_RET:          /* ... ==> ...                                */
1860
1861                         emit_br(cd, iptr->dst.block);
1862                         ALIGNCODENOP;
1863                         break;
1864
1865                 case ICMD_JSR:          /* ... ==> ...                                */
1866
1867                         emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1868                         ALIGNCODENOP;
1869                         break;
1870
1871                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
1872                 case ICMD_IFNONNULL:
1873
1874                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1875                         M_TST(s1);
1876                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
1877                         break;
1878
1879                 case ICMD_IFLT:
1880                 case ICMD_IFLE:
1881                 case ICMD_IFNE:
1882                 case ICMD_IFGT:
1883                 case ICMD_IFGE:
1884                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
1885
1886                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1887                         if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
1888                                 M_CMPI(s1, iptr->sx.val.i);
1889                         else {
1890                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1891                                 M_CMP(s1, REG_ITMP2);
1892                         }
1893                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
1894                         break;
1895
1896
1897                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
1898
1899                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1900                         s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1901                         if (iptr->sx.val.l == 0) {
1902                                 M_OR_TST(s1, s2, REG_ITMP3);
1903                         }
1904                         else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1905                                 M_XOR_IMM(s2, 0, REG_ITMP2);
1906                                 M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
1907                                 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
1908                         }
1909                         else {
1910                                 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1911                                 M_XOR(s1, REG_ITMP3, REG_ITMP1);
1912                                 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1913                                 M_XOR(s2, REG_ITMP3, REG_ITMP2);
1914                                 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
1915                         }
1916                         emit_beq(cd, iptr->dst.block);
1917                         break;
1918                         
1919                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
1920
1921                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1922                         s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1923                         if (iptr->sx.val.l == 0) {
1924                                 /* if high word is less than zero, the whole long is too */
1925                                 M_CMPI(s2, 0);
1926                                 emit_blt(cd, iptr->dst.block);
1927                         }
1928                         else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1929                                 M_CMPI(s2, 0);
1930                                 emit_blt(cd, iptr->dst.block);
1931                                 emit_label_bgt(cd, BRANCH_LABEL_1);
1932                                 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
1933                                 emit_blt(cd, iptr->dst.block);
1934                                 emit_label(cd, BRANCH_LABEL_1);
1935                         }
1936                         else {
1937                                 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1938                                 M_CMP(s2, REG_ITMP3);
1939                                 emit_blt(cd, iptr->dst.block);
1940                                 emit_label_bgt(cd, BRANCH_LABEL_1);
1941                                 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1942                                 M_CMPU(s1, REG_ITMP3);
1943                                 emit_blt(cd, iptr->dst.block);
1944                                 emit_label(cd, BRANCH_LABEL_1);
1945                         }
1946                         break;
1947                         
1948                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
1949
1950                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1951                         s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1952 /*                      if (iptr->sx.val.l == 0) { */
1953 /*                              M_OR(s1, s2, REG_ITMP3); */
1954 /*                              M_CMPI(REG_ITMP3, 0); */
1955
1956 /*                      } else  */
1957                         if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1958                                 M_CMPI(s2, 0);
1959                                 emit_blt(cd, iptr->dst.block);
1960                                 emit_label_bgt(cd, BRANCH_LABEL_1);
1961                                 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
1962                         }
1963                         else {
1964                                 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1965                                 M_CMP(s2, REG_ITMP3);
1966                                 emit_blt(cd, iptr->dst.block);
1967                                 emit_label_bgt(cd, BRANCH_LABEL_1);
1968                                 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1969                                 M_CMPU(s1, REG_ITMP3);
1970                         }
1971                         emit_ble(cd, iptr->dst.block);
1972                         emit_label(cd, BRANCH_LABEL_1);
1973                         break;
1974                         
1975                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
1976
1977                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1978                         s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1979                         if (iptr->sx.val.l == 0) {
1980                                 M_OR_TST(s1, s2, REG_ITMP3);
1981                         }
1982                         else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1983                                 M_XOR_IMM(s2, 0, REG_ITMP2);
1984                                 M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
1985                                 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
1986                         }
1987                         else {
1988                                 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1989                                 M_XOR(s1, REG_ITMP3, REG_ITMP1);
1990                                 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1991                                 M_XOR(s2, REG_ITMP3, REG_ITMP2);
1992                                 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
1993                         }
1994                         emit_bne(cd, iptr->dst.block);
1995                         break;
1996                         
1997                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
1998
1999                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2000                         s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2001 /*                      if (iptr->sx.val.l == 0) { */
2002 /*                              M_OR(s1, s2, REG_ITMP3); */
2003 /*                              M_CMPI(REG_ITMP3, 0); */
2004
2005 /*                      } else  */
2006                         if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2007                                 M_CMPI(s2, 0);
2008                                 emit_bgt(cd, iptr->dst.block);
2009                                 emit_label_blt(cd, BRANCH_LABEL_1);
2010                                 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
2011                         }
2012                         else {
2013                                 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2014                                 M_CMP(s2, REG_ITMP3);
2015                                 emit_bgt(cd, iptr->dst.block);
2016                                 emit_label_blt(cd, BRANCH_LABEL_1);
2017                                 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2018                                 M_CMPU(s1, REG_ITMP3);
2019                         }
2020                         emit_bgt(cd, iptr->dst.block);
2021                         emit_label(cd, BRANCH_LABEL_1);
2022                         break;
2023                         
2024                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2025
2026                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2027                         s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2028                         if (iptr->sx.val.l == 0) {
2029                                 /* if high word is greater equal zero, the whole long is too */
2030                                 M_CMPI(s2, 0);
2031                                 emit_bge(cd, iptr->dst.block);
2032                         }
2033                         else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2034                                 M_CMPI(s2, 0);
2035                                 emit_bgt(cd, iptr->dst.block);
2036                                 emit_label_blt(cd, BRANCH_LABEL_1);
2037                                 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
2038                                 emit_bge(cd, iptr->dst.block);
2039                                 emit_label(cd, BRANCH_LABEL_1);
2040                         }
2041                         else {
2042                                 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2043                                 M_CMP(s2, REG_ITMP3);
2044                                 emit_bgt(cd, iptr->dst.block);
2045                                 emit_label_blt(cd, BRANCH_LABEL_1);
2046                                 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2047                                 M_CMPU(s1, REG_ITMP3);
2048                                 emit_bge(cd, iptr->dst.block);
2049                                 emit_label(cd, BRANCH_LABEL_1);
2050                         }
2051                         break;
2052
2053                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
2054                 case ICMD_IF_ICMPNE:
2055                 case ICMD_IF_ICMPLT:
2056                 case ICMD_IF_ICMPGT:
2057                 case ICMD_IF_ICMPLE:
2058                 case ICMD_IF_ICMPGE:
2059
2060                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2061                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2062                         M_CMP(s1, s2);
2063                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2064                         break;
2065
2066                 case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
2067                 case ICMD_IF_ACMPNE:
2068
2069                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2070                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2071                         M_CMP(s1, s2);
2072                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2073                         break;
2074
2075                 case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
2076
2077                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2078                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2079                         M_CMP(s1, s2);
2080                         emit_label_bne(cd, BRANCH_LABEL_1);
2081                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2082                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2083                         M_CMP(s1, s2);
2084                         emit_beq(cd, iptr->dst.block);
2085                         emit_label(cd, BRANCH_LABEL_1);
2086                         break;
2087
2088                 case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
2089
2090                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2091                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2092                         M_CMP(s1, s2);
2093                         emit_bne(cd, iptr->dst.block);
2094                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2095                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2096                         M_CMP(s1, s2);
2097                         emit_bne(cd, iptr->dst.block);
2098                         break;
2099
2100                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
2101
2102                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2103                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2104                         M_CMP(s1, s2);
2105                         emit_blt(cd, iptr->dst.block);
2106                         emit_label_bgt(cd, BRANCH_LABEL_1);
2107                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2108                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2109                         M_CMPU(s1, s2);
2110                         emit_blt(cd, iptr->dst.block);
2111                         emit_label(cd, BRANCH_LABEL_1);
2112                         break;
2113
2114                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
2115
2116                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2117                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2118                         M_CMP(s1, s2);
2119                         emit_bgt(cd, iptr->dst.block);
2120                         emit_label_blt(cd, BRANCH_LABEL_1);
2121                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2122                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2123                         M_CMPU(s1, s2);
2124                         emit_bgt(cd, iptr->dst.block);
2125                         emit_label(cd, BRANCH_LABEL_1);
2126                         break;
2127
2128                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
2129
2130                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2131                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2132                         M_CMP(s1, s2);
2133                         emit_blt(cd, iptr->dst.block);
2134                         emit_label_bgt(cd, BRANCH_LABEL_1);
2135                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2136                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2137                         M_CMPU(s1, s2);
2138                         emit_ble(cd, iptr->dst.block);
2139                         emit_label(cd, BRANCH_LABEL_1);
2140                         break;
2141
2142                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
2143
2144                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2145                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2146                         M_CMP(s1, s2);
2147                         emit_bgt(cd, iptr->dst.block);
2148                         emit_label_blt(cd, BRANCH_LABEL_1);
2149                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2150                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2151                         M_CMPU(s1, s2);
2152                         emit_bge(cd, iptr->dst.block);
2153                         emit_label(cd, BRANCH_LABEL_1);
2154                         break;
2155
2156                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2157
2158                         REPLACEMENT_POINT_RETURN(cd, iptr);
2159                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2160                         M_INTMOVE(s1, REG_RESULT);
2161                         goto nowperformreturn;
2162
2163                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2164
2165                         REPLACEMENT_POINT_RETURN(cd, iptr);
2166                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2167                         M_INTMOVE(s1, REG_RESULT);
2168
2169 #ifdef ENABLE_VERIFIER
2170                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2171                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
2172
2173                                 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
2174                         }
2175 #endif /* ENABLE_VERIFIER */
2176                         goto nowperformreturn;
2177
2178                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
2179
2180                         REPLACEMENT_POINT_RETURN(cd, iptr);
2181                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2182                         M_LNGMOVE(s1, REG_RESULT_PACKED);
2183                         goto nowperformreturn;
2184
2185                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2186                 case ICMD_DRETURN:
2187
2188                         REPLACEMENT_POINT_RETURN(cd, iptr);
2189                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2190                         M_FLTMOVE(s1, REG_FRESULT);
2191                         goto nowperformreturn;
2192
2193                 case ICMD_RETURN:      /* ...  ==> ...                                */
2194
2195                         REPLACEMENT_POINT_RETURN(cd, iptr);
2196
2197 nowperformreturn:
2198                         {
2199                         s4 i, p;
2200                         
2201                         p = cd->stackframesize;
2202
2203                         /* call trace function */
2204
2205                         emit_verbosecall_exit(jd);
2206
2207 #if defined(ENABLE_THREADS)
2208                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2209                                 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2210                                 M_ALD(REG_ITMP3, REG_PV, disp);
2211                                 M_MTCTR(REG_ITMP3);
2212
2213                                 /* we need to save the proper return value */
2214
2215                                 switch (iptr->opc) {
2216                                 case ICMD_LRETURN:
2217                                         M_IST(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2218                                         /* fall through */
2219                                 case ICMD_IRETURN:
2220                                 case ICMD_ARETURN:
2221                                         M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2222                                         break;
2223                                 case ICMD_FRETURN:
2224                                         M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2225                                         break;
2226                                 case ICMD_DRETURN:
2227                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2228                                         break;
2229                                 }
2230
2231                                 M_ALD(REG_A0, REG_SP, rd->memuse * 4);
2232                                 M_JSR;
2233
2234                                 /* and now restore the proper return value */
2235
2236                                 switch (iptr->opc) {
2237                                 case ICMD_LRETURN:
2238                                         M_ILD(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2239                                         /* fall through */
2240                                 case ICMD_IRETURN:
2241                                 case ICMD_ARETURN:
2242                                         M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2243                                         break;
2244                                 case ICMD_FRETURN:
2245                                         M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2246                                         break;
2247                                 case ICMD_DRETURN:
2248                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2249                                         break;
2250                                 }
2251                         }
2252 #endif
2253
2254                         /* restore return address                                         */
2255
2256                         if (!jd->isleafmethod) {
2257                                 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
2258                                    may have a displacement overflow. */
2259
2260                                 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
2261                                 M_MTLR(REG_ITMP1);
2262                         }
2263
2264                         /* restore saved registers                                        */
2265
2266                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2267                                 p--; M_ILD(rd->savintregs[i], REG_SP, p * 4);
2268                         }
2269                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2270                                 p -= 2; M_DLD(rd->savfltregs[i], REG_SP, p * 4);
2271                         }
2272
2273                         /* deallocate stack                                               */
2274
2275                         if (cd->stackframesize)
2276                                 M_LDA(REG_SP, REG_SP, cd->stackframesize * 4);
2277
2278                         M_RET;
2279                         ALIGNCODENOP;
2280                         }
2281                         break;
2282
2283
2284                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2285                         {
2286                         s4 i, l;
2287                         branch_target_t *table;
2288
2289                         table = iptr->dst.table;
2290
2291                         l = iptr->sx.s23.s2.tablelow;
2292                         i = iptr->sx.s23.s3.tablehigh;
2293                         
2294                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2295                         if (l == 0)
2296                                 M_INTMOVE(s1, REG_ITMP1);
2297                         else if (l <= 32768)
2298                                 M_LDA(REG_ITMP1, s1, -l);
2299                         else {
2300                                 ICONST(REG_ITMP2, l);
2301                                 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2302                         }
2303
2304                         i = i - l + 1;
2305
2306                         /* range check */
2307
2308                         M_CMPUI(REG_ITMP1, i - 1);
2309                         emit_bgt(cd, table[0].block);
2310
2311                         /* build jump table top down and use address of lowest entry */
2312
2313                         table += i;
2314
2315                         while (--i >= 0) {
2316                                 dseg_add_target(cd, table->block); 
2317                                 --table;
2318                         }
2319
2320                         /* length of dataseg after last dseg_add_target is used by load */
2321
2322                         M_SLL_IMM(REG_ITMP1, 2, REG_ITMP1);
2323                         M_IADD(REG_ITMP1, REG_PV, REG_ITMP2);
2324                         M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2325                         M_MTCTR(REG_ITMP2);
2326                         M_RTS;
2327                         ALIGNCODENOP;
2328                         }
2329                         break;
2330
2331
2332                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2333                         {
2334                         s4 i;
2335                         lookup_target_t *lookup;
2336
2337                         lookup = iptr->dst.lookup;
2338
2339                         i = iptr->sx.s23.s2.lookupcount;
2340                         
2341                         MCODECHECK((i<<2)+8);
2342                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2343
2344                         while (--i >= 0) {
2345                                 if ((lookup->value >= -32768) && (lookup->value <= 32767)) {
2346                                         M_CMPI(s1, lookup->value);
2347                                 }
2348                                 else {
2349                                         disp = dseg_add_s4(cd, lookup->value);
2350                                         M_ILD(REG_ITMP2, REG_PV, disp);
2351                                         M_CMP(s1, REG_ITMP2);
2352                                 }
2353                                 emit_beq(cd, lookup->target.block);
2354                                 lookup++;
2355                         }
2356
2357                         emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2358                         ALIGNCODENOP;
2359                         break;
2360                         }
2361
2362
2363                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
2364
2365                         bte = iptr->sx.s23.s3.bte;
2366                         md  = bte->md;
2367                         goto gen_method;
2368
2369                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
2370
2371                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2372                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
2373                 case ICMD_INVOKEINTERFACE:
2374
2375                         REPLACEMENT_POINT_INVOKE(cd, iptr);
2376
2377                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2378                                 lm = NULL;
2379                                 um = iptr->sx.s23.s3.um;
2380                                 md = um->methodref->parseddesc.md;
2381                         }
2382                         else {
2383                                 lm = iptr->sx.s23.s3.fmiref->p.method;
2384                                 um = NULL;
2385                                 md = lm->parseddesc;
2386                         }
2387
2388 gen_method:
2389                         s3 = md->paramcount;
2390
2391                         MCODECHECK((s3 << 1) + 64);
2392
2393                         /* copy arguments to registers or stack location */
2394
2395                         for (s3 = s3 - 1; s3 >= 0; s3--) {
2396                                 var = VAR(iptr->sx.s23.s2.args[s3]);
2397                                 d   = md->params[s3].regoff;
2398
2399                                 /* Already Preallocated? */
2400                                 if (var->flags & PREALLOC)
2401                                         continue;
2402
2403                                 if (IS_INT_LNG_TYPE(var->type)) {
2404                                         if (!md->params[s3].inmemory) {
2405                                                 if (IS_2_WORD_TYPE(var->type)) {
2406                                                         s1 = emit_load(jd, iptr, var, d);
2407                                                         M_LNGMOVE(s1, d);
2408                                                 }
2409                                                 else {
2410                                                         s1 = emit_load(jd, iptr, var, d);
2411                                                         M_INTMOVE(s1, d);
2412                                                 }
2413                                         }
2414                                         else {
2415                                                 if (IS_2_WORD_TYPE(var->type)) {
2416                                                         s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
2417                                                         M_LST(s1, REG_SP, d * 4);
2418                                                 }
2419                                                 else {
2420                                                         s1 = emit_load(jd, iptr, var, REG_ITMP1);
2421                                                         M_IST(s1, REG_SP, d * 4);
2422                                                 }
2423                                         }
2424                                 }
2425                                 else {
2426                                         if (!md->params[s3].inmemory) {
2427                                                 s1 = emit_load(jd, iptr, var, d);
2428                                                 M_FLTMOVE(s1, d);
2429                                         }
2430                                         else {
2431                                                 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2432                                                 if (IS_2_WORD_TYPE(var->type))
2433                                                         M_DST(s1, REG_SP, d * 4);
2434                                                 else
2435                                                         M_FST(s1, REG_SP, d * 4);
2436                                         }
2437                                 }
2438                         }
2439
2440                         switch (iptr->opc) {
2441                         case ICMD_BUILTIN:
2442                                 disp = dseg_add_functionptr(cd, bte->fp);
2443
2444                                 M_ALD(REG_PV, REG_PV, disp);  /* pointer to built-in-function */
2445
2446                                 /* generate the actual call */
2447
2448                                 M_MTCTR(REG_PV);
2449                                 M_JSR;
2450                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2451                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2452                                 M_MFLR(REG_ITMP1);
2453                                 M_LDA(REG_PV, REG_ITMP1, -disp);
2454
2455                                 emit_exception_check(cd, iptr);
2456                                 break;
2457
2458                         case ICMD_INVOKESPECIAL:
2459                                 emit_nullpointer_check(cd, iptr, REG_A0);
2460                                 /* fall-through */
2461
2462                         case ICMD_INVOKESTATIC:
2463                                 if (lm == NULL) {
2464                                         disp = dseg_add_unique_address(cd, um);
2465
2466                                         codegen_addpatchref(cd, PATCHER_invokestatic_special,
2467                                                                                 um, disp);
2468                                 }
2469                                 else
2470                                         disp = dseg_add_address(cd, lm->stubroutine);
2471
2472                                 M_ALD(REG_PV, REG_PV, disp);
2473
2474                                 /* generate the actual call */
2475
2476                                 M_MTCTR(REG_PV);
2477                                 M_JSR;
2478                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2479                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2480                                 M_MFLR(REG_ITMP1);
2481                                 M_LDA(REG_PV, REG_ITMP1, -disp);
2482                                 break;
2483
2484                         case ICMD_INVOKEVIRTUAL:
2485                                 if (lm == NULL) {
2486                                         codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2487
2488                                         s1 = 0;
2489                                 }
2490                                 else {
2491                                         s1 = OFFSET(vftbl_t, table[0]) +
2492                                                 sizeof(methodptr) * lm->vftblindex;
2493                                 }
2494
2495                                 /* implicit null-pointer check */
2496                                 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2497                                 M_ALD(REG_PV, REG_METHODPTR, s1);
2498
2499                                 /* generate the actual call */
2500
2501                                 M_MTCTR(REG_PV);
2502                                 M_JSR;
2503                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2504                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2505                                 M_MFLR(REG_ITMP1);
2506                                 M_LDA(REG_PV, REG_ITMP1, -disp);
2507                                 break;
2508
2509                         case ICMD_INVOKEINTERFACE:
2510                                 if (lm == NULL) {
2511                                         codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2512
2513                                         s1 = 0;
2514                                         s2 = 0;
2515                                 }
2516                                 else {
2517                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
2518                                                 sizeof(methodptr*) * lm->class->index;
2519
2520                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
2521                                 }
2522
2523                                 /* implicit null-pointer check */
2524                                 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2525                                 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2526                                 M_ALD(REG_PV, REG_METHODPTR, s2);
2527
2528                                 /* generate the actual call */
2529
2530                                 M_MTCTR(REG_PV);
2531                                 M_JSR;
2532                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2533                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2534                                 M_MFLR(REG_ITMP1);
2535                                 M_LDA(REG_PV, REG_ITMP1, -disp);
2536                                 break;
2537                         }
2538
2539                         /* store return value */
2540
2541                         d = md->returntype.type;
2542
2543                         if (d != TYPE_VOID) {
2544                                 if (IS_INT_LNG_TYPE(d)) {
2545                                         if (IS_2_WORD_TYPE(d)) {
2546                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
2547                                                 M_LNGMOVE(REG_RESULT_PACKED, s1);
2548                                         }
2549                                         else {
2550                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2551                                                 M_INTMOVE(REG_RESULT, s1);
2552                                         }
2553                                 }
2554                                 else {
2555                                         s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2556                                         M_FLTMOVE(REG_FRESULT, s1);
2557                                 }
2558                                 emit_store_dst(jd, iptr, s1);
2559                         }
2560                         break;
2561
2562
2563                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2564
2565                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2566                                 /* object type cast-check */
2567
2568                                 classinfo *super;
2569                                 s4         superindex;
2570
2571                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2572                                         super      = NULL;
2573                                         superindex = 0;
2574                                 }
2575                                 else {
2576                                         super      = iptr->sx.s23.s3.c.cls;
2577                                         superindex = super->index;
2578                                 }
2579
2580                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2581                                         CODEGEN_CRITICAL_SECTION_NEW;
2582
2583                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2584
2585                                 /* if class is not resolved, check which code to call */
2586
2587                                 if (super == NULL) {
2588                                         M_TST(s1);
2589                                         emit_label_beq(cd, BRANCH_LABEL_1);
2590
2591                                         disp = dseg_add_unique_s4(cd, 0);         /* super->flags */
2592
2593                                         codegen_addpatchref(cd,
2594                                                                                 PATCHER_resolve_classref_to_flags,
2595                                                                                 iptr->sx.s23.s3.c.ref,
2596                                                                                 disp);
2597
2598                                         M_ILD(REG_ITMP2, REG_PV, disp);
2599                                         M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2600                                         emit_label_beq(cd, BRANCH_LABEL_2);
2601                                 }
2602
2603                                 /* interface checkcast code */
2604
2605                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2606                                         if (super == NULL) {
2607                                                 codegen_addpatchref(cd,
2608                                                                                         PATCHER_checkcast_interface,
2609                                                                                         iptr->sx.s23.s3.c.ref,
2610                                                                                         0);
2611                                         }
2612                                         else {
2613                                                 M_TST(s1);
2614                                                 emit_label_beq(cd, BRANCH_LABEL_3);
2615                                         }
2616
2617                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2618                                         M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2619                                         M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
2620                                         emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2621
2622                                         M_ALD(REG_ITMP3, REG_ITMP2,
2623                                                   OFFSET(vftbl_t, interfacetable[0]) -
2624                                                   superindex * sizeof(methodptr*));
2625                                         M_TST(REG_ITMP3);
2626                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2627
2628                                         if (super == NULL)
2629                                                 emit_label_br(cd, BRANCH_LABEL_4);
2630                                         else
2631                                                 emit_label(cd, BRANCH_LABEL_3);
2632                                 }
2633
2634                                 /* class checkcast code */
2635
2636                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2637                                         if (super == NULL) {
2638                                                 emit_label(cd, BRANCH_LABEL_2);
2639
2640                                                 disp = dseg_add_unique_address(cd, NULL);
2641
2642                                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl,
2643                                                                                         iptr->sx.s23.s3.c.ref,
2644                                                                                         disp);
2645                                         }
2646                                         else {
2647                                                 disp = dseg_add_address(cd, super->vftbl);
2648
2649                                                 M_TST(s1);
2650                                                 emit_label_beq(cd, BRANCH_LABEL_5);
2651                                         }
2652
2653                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2654
2655                                         CODEGEN_CRITICAL_SECTION_START;
2656
2657                                         M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2658                                         M_ALD(REG_ITMP2, REG_PV, disp);
2659                                         if (s1 != REG_ITMP1) {
2660                                                 M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, baseval));
2661                                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2662
2663                                                 CODEGEN_CRITICAL_SECTION_END;
2664
2665                                                 M_ISUB(REG_ITMP3, REG_ITMP1, REG_ITMP3);
2666                                         }
2667                                         else {
2668                                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2669                                                 M_ISUB(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2670                                                 M_ALD(REG_ITMP2, REG_PV, disp);
2671                                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2672
2673                                                 CODEGEN_CRITICAL_SECTION_END;
2674                                         }
2675                                         M_CMPU(REG_ITMP3, REG_ITMP2);
2676                                         emit_classcast_check(cd, iptr, BRANCH_GT, REG_ITMP3, s1);
2677
2678                                         if (super != NULL)
2679                                                 emit_label(cd, BRANCH_LABEL_5);
2680                                 }
2681
2682                                 if (super == NULL) {
2683                                         emit_label(cd, BRANCH_LABEL_1);
2684                                         emit_label(cd, BRANCH_LABEL_4);
2685                                 }
2686
2687                                 d = codegen_reg_of_dst(jd, iptr, s1);
2688                         }
2689                         else {
2690                                 /* array type cast-check */
2691
2692                                 s1 = emit_load_s1(jd, iptr, REG_A0);
2693                                 M_INTMOVE(s1, REG_A0);
2694
2695                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2696                                         disp = dseg_add_unique_address(cd, NULL);
2697
2698                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
2699                                                                                 iptr->sx.s23.s3.c.ref,
2700                                                                                 disp);
2701                                 }
2702                                 else
2703                                         disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2704
2705                                 M_ALD(REG_A1, REG_PV, disp);
2706                                 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2707                                 M_ALD(REG_ITMP2, REG_PV, disp);
2708                                 M_MTCTR(REG_ITMP2);
2709                                 M_JSR;
2710                                 M_TST(REG_RESULT);
2711                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2712
2713                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2714                                 d = codegen_reg_of_dst(jd, iptr, s1);
2715                         }
2716                         M_INTMOVE(s1, d);
2717                         emit_store_dst(jd, iptr, d);
2718                         break;
2719
2720                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
2721
2722                         {
2723                         classinfo *super;
2724                         s4         superindex;
2725
2726                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2727                                 super      = NULL;
2728                                 superindex = 0;
2729                         }
2730                         else {
2731                                 super      = iptr->sx.s23.s3.c.cls;
2732                                 superindex = super->index;
2733                         }
2734                         
2735                         if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2736                                 CODEGEN_CRITICAL_SECTION_NEW;
2737
2738                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2739
2740                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2741                         if (s1 == d) {
2742                                 M_MOV(s1, REG_ITMP1);
2743                                 s1 = REG_ITMP1;
2744                         }
2745
2746                         M_CLR(d);
2747
2748                         /* if class is not resolved, check which code to call */
2749
2750                         if (super == NULL) {
2751                                 M_TST(s1);
2752                                 emit_label_beq(cd, BRANCH_LABEL_1);
2753
2754                                 disp = dseg_add_unique_s4(cd, 0);             /* super->flags */
2755
2756                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags,
2757                                                                         iptr->sx.s23.s3.c.ref, disp);
2758
2759                                 M_ILD(REG_ITMP3, REG_PV, disp);
2760                                 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2761                                 emit_label_beq(cd, BRANCH_LABEL_2);
2762                         }
2763
2764                         /* interface instanceof code */
2765
2766                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2767                                 if (super == NULL) {
2768                                         codegen_addpatchref(cd,
2769                                                                                 PATCHER_instanceof_interface,
2770                                                                                 iptr->sx.s23.s3.c.ref, 0);
2771                                 }
2772                                 else {
2773                                         M_TST(s1);
2774                                         emit_label_beq(cd, BRANCH_LABEL_3);
2775                                 }
2776
2777                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2778                                 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2779                                 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
2780                                 M_BLE(4);
2781                                 M_ALD(REG_ITMP1, REG_ITMP1,
2782                                           OFFSET(vftbl_t, interfacetable[0]) -
2783                                           superindex * sizeof(methodptr*));
2784                                 M_TST(REG_ITMP1);
2785                                 M_BEQ(1);
2786                                 M_IADD_IMM(REG_ZERO, 1, d);
2787
2788                                 if (super == NULL)
2789                                         emit_label_br(cd, BRANCH_LABEL_4);
2790                                 else
2791                                         emit_label(cd, BRANCH_LABEL_3);
2792                         }
2793
2794                         /* class instanceof code */
2795
2796                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2797                                 if (super == NULL) {
2798                                         emit_label(cd, BRANCH_LABEL_2);
2799
2800                                         disp = dseg_add_unique_address(cd, NULL);
2801
2802                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl,
2803                                                                                 iptr->sx.s23.s3.c.ref,
2804                                                                                 disp);
2805                                 }
2806                                 else {
2807                                         disp = dseg_add_address(cd, super->vftbl);
2808
2809                                         M_TST(s1);
2810                                         emit_label_beq(cd, BRANCH_LABEL_5);
2811                                 }
2812
2813                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2814                                 M_ALD(REG_ITMP2, REG_PV, disp);
2815
2816                                 CODEGEN_CRITICAL_SECTION_START;
2817
2818                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2819                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2820                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2821
2822                                 CODEGEN_CRITICAL_SECTION_END;
2823
2824                                 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2825                                 M_CMPU(REG_ITMP1, REG_ITMP2);
2826                                 M_CLR(d);
2827                                 M_BGT(1);
2828                                 M_IADD_IMM(REG_ZERO, 1, d);
2829
2830                                 if (super != NULL)
2831                                         emit_label(cd, BRANCH_LABEL_5);
2832                         }
2833
2834                         if (super == NULL) {
2835                                 emit_label(cd, BRANCH_LABEL_1);
2836                                 emit_label(cd, BRANCH_LABEL_4);
2837                         }
2838
2839                         emit_store_dst(jd, iptr, d);
2840                         }
2841                         break;
2842
2843                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
2844
2845                         /* check for negative sizes and copy sizes to stack if necessary  */
2846
2847                         MCODECHECK((iptr->s1.argcount << 1) + 64);
2848
2849                         for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2850                                 var = VAR(iptr->sx.s23.s2.args[s1]);
2851
2852                                 /* copy SAVEDVAR sizes to stack */
2853
2854                                 /* Already Preallocated? */
2855                                 if (!(var->flags & PREALLOC)) {
2856                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
2857 #if defined(__DARWIN__)
2858                                         M_IST(s2, REG_SP, LA_SIZE + (s1 + INT_ARG_CNT) * 4);
2859 #else
2860                                         M_IST(s2, REG_SP, LA_SIZE + (s1 + 3) * 4);
2861 #endif
2862                                 }
2863                         }
2864
2865                         /* a0 = dimension count */
2866
2867                         ICONST(REG_A0, iptr->s1.argcount);
2868
2869                         /* is patcher function set? */
2870
2871                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2872                                 disp = dseg_add_unique_address(cd, NULL);
2873
2874                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
2875                                                                         iptr->sx.s23.s3.c.ref, disp);
2876                         }
2877                         else
2878                                 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2879
2880                         /* a1 = arraydescriptor */
2881
2882                         M_ALD(REG_A1, REG_PV, disp);
2883
2884                         /* a2 = pointer to dimensions = stack pointer */
2885
2886 #if defined(__DARWIN__)
2887                         M_LDA(REG_A2, REG_SP, LA_SIZE + INT_ARG_CNT * 4);
2888 #else
2889                         M_LDA(REG_A2, REG_SP, LA_SIZE + 3 * 4);
2890 #endif
2891
2892                         disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2893                         M_ALD(REG_ITMP3, REG_PV, disp);
2894                         M_MTCTR(REG_ITMP3);
2895                         M_JSR;
2896
2897                         /* check for exception before result assignment */
2898
2899                         emit_exception_check(cd, iptr);
2900
2901                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2902                         M_INTMOVE(REG_RESULT, d);
2903                         emit_store_dst(jd, iptr, d);
2904                         break;
2905
2906                 default:
2907                         exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2908                                                                                    iptr->opc);
2909                         return false;
2910         } /* switch */
2911                 
2912         } /* for instruction */
2913                 
2914         } /* if (bptr -> flags >= BBREACHED) */
2915         } /* for basic block */
2916
2917         dseg_createlinenumbertable(cd);
2918
2919         /* generate stubs */
2920
2921         emit_patcher_stubs(jd);
2922         REPLACEMENT_EMIT_STUBS(jd);
2923
2924         /* everything's ok */
2925
2926         return true;
2927 }
2928
2929
2930 /* codegen_emit_stub_compiler **************************************************
2931
2932    Emits a stub routine which calls the compiler.
2933         
2934 *******************************************************************************/
2935
2936 void codegen_emit_stub_compiler(jitdata *jd)
2937 {
2938         methodinfo  *m;
2939         codegendata *cd;
2940
2941         /* get required compiler data */
2942
2943         m  = jd->m;
2944         cd = jd->cd;
2945
2946         /* code for the stub */
2947
2948         M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P);
2949         M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P);
2950         M_MTCTR(REG_PV);
2951         M_RTS;
2952 }
2953
2954
2955 /* codegen_emit_stub_native ****************************************************
2956
2957    Emits a stub routine which calls a native method.
2958
2959 *******************************************************************************/
2960
2961 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
2962 {
2963         methodinfo  *m;
2964         codeinfo    *code;
2965         codegendata *cd;
2966         methoddesc  *md;
2967         s4           nativeparams;
2968         s4           i, j;                 /* count variables                    */
2969         s4           t;
2970         s4           s1, s2, disp;
2971         s4           funcdisp;
2972
2973         /* get required compiler data */
2974
2975         m    = jd->m;
2976         code = jd->code;
2977         cd   = jd->cd;
2978
2979         /* set some variables */
2980
2981         md = m->parseddesc;
2982         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
2983
2984         /* calculate stackframe size */
2985
2986         cd->stackframesize =
2987                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
2988                 sizeof(localref_table) / SIZEOF_VOID_P +
2989                 4 +                             /* 4 stackframeinfo arguments (darwin)*/
2990                 nmd->paramcount * 2 +           /* assume all arguments are doubles   */
2991                 nmd->memuse;
2992
2993         /* keep stack 16-byte aligned */
2994
2995         cd->stackframesize = (cd->stackframesize + 3) & ~3;
2996
2997         /* create method header */
2998
2999         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
3000         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
3001         (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
3002         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
3003         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
3004         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
3005         (void) dseg_addlinenumbertablesize(cd);
3006         (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
3007
3008         /* generate code */
3009
3010         M_MFLR(REG_ZERO);
3011         M_AST_INTERN(REG_ZERO, REG_SP, LA_LR_OFFSET);
3012         M_STWU(REG_SP, REG_SP, -(cd->stackframesize * 4));
3013
3014         /* get function address (this must happen before the stackframeinfo) */
3015
3016         funcdisp = dseg_add_functionptr(cd, f);
3017
3018 #if !defined(WITH_STATIC_CLASSPATH)
3019         if (f == NULL)
3020                 codegen_addpatchref(cd, PATCHER_resolve_native_function, m, funcdisp);
3021 #endif
3022
3023         /* emit trace code */
3024
3025         emit_verbosecall_enter(jd);
3026
3027 #if defined(ENABLE_GC_CACAO)
3028         /* Save callee saved integer registers in stackframeinfo (GC may
3029            need to recover them during a collection). */
3030
3031         disp = cd->stackframesize * 4 - sizeof(stackframeinfo) +
3032                 OFFSET(stackframeinfo, intregs);
3033
3034         for (i = 0; i < INT_SAV_CNT; i++)
3035                 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3036 #endif
3037
3038         /* save integer and float argument registers */
3039
3040         j = 0;
3041
3042         for (i = 0; i < md->paramcount; i++) {
3043                 t = md->paramtypes[i].type;
3044
3045                 if (IS_INT_LNG_TYPE(t)) {
3046                         if (!md->params[i].inmemory) {
3047                                 s1 = md->params[i].regoff;
3048
3049                                 if (IS_2_WORD_TYPE(t)) {
3050                                         M_IST(GET_HIGH_REG(s1), REG_SP, LA_SIZE + 4 * 4 + j * 4);
3051                                         j++;
3052                                         M_IST(GET_LOW_REG(s1), REG_SP, LA_SIZE + 4 * 4 + j * 4);
3053                                 }
3054                                 else
3055                                         M_IST(s1, REG_SP, LA_SIZE + 4 * 4 + j * 4);
3056
3057                                 j++;
3058                         }
3059                 }
3060         }
3061
3062         for (i = 0; i < md->paramcount; i++) {
3063                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3064                         if (!md->params[i].inmemory) {
3065                                 s1 = md->params[i].regoff;
3066                                 M_DST(s1, REG_SP, LA_SIZE + 4 * 4 + j * 8);
3067                                 j++;
3068                         }
3069                 }
3070         }
3071
3072         /* create native stack info */
3073
3074         M_AADD_IMM(REG_SP, cd->stackframesize * 4, REG_A0);
3075         M_MOV(REG_PV, REG_A1);
3076         M_AADD_IMM(REG_SP, cd->stackframesize * 4, REG_A2);
3077         M_ALD(REG_A3, REG_SP, cd->stackframesize * 4 + LA_LR_OFFSET);
3078         disp = dseg_add_functionptr(cd, codegen_start_native_call);
3079         M_ALD(REG_ITMP1, REG_PV, disp);
3080         M_MTCTR(REG_ITMP1);
3081         M_JSR;
3082
3083         /* restore integer and float argument registers */
3084
3085         j = 0;
3086
3087         for (i = 0; i < md->paramcount; i++) {
3088                 t = md->paramtypes[i].type;
3089
3090                 if (IS_INT_LNG_TYPE(t)) {
3091                         if (!md->params[i].inmemory) {
3092                                 s1 = md->params[i].regoff;
3093
3094                                 if (IS_2_WORD_TYPE(t)) {
3095                                         M_ILD(GET_HIGH_REG(s1), REG_SP, LA_SIZE + 4 * 4 + j * 4);
3096                                         j++;
3097                                         M_ILD(GET_LOW_REG(s1), REG_SP, LA_SIZE + 4 * 4 + j * 4);
3098                                 }
3099                                 else
3100                                         M_ILD(s1, REG_SP, LA_SIZE + 4 * 4 + j * 4);
3101
3102                                 j++;
3103                         }
3104                 }
3105         }
3106
3107         for (i = 0; i < md->paramcount; i++) {
3108                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3109                         if (!md->params[i].inmemory) {
3110                                 s1 = md->params[i].regoff;
3111                                 M_DLD(s1, REG_SP, LA_SIZE + 4 * 4 + j * 8);
3112                                 j++;
3113                         }
3114                 }
3115         }
3116         
3117         /* copy or spill arguments to new locations */
3118
3119         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3120                 t = md->paramtypes[i].type;
3121
3122                 if (IS_INT_LNG_TYPE(t)) {
3123                         if (!md->params[i].inmemory) {
3124                                 s1 = md->params[i].regoff;
3125                                 s2 = nmd->params[j].regoff;
3126
3127                                 if (!nmd->params[j].inmemory) {
3128                                         if (IS_2_WORD_TYPE(t))
3129                                                 M_LNGMOVE(s1, s2);
3130                                         else
3131                                                 M_INTMOVE(s1, s2);
3132                                 }
3133                                 else {
3134                                         if (IS_2_WORD_TYPE(t))
3135                                                 M_LST(s1, REG_SP, s2 * 4);
3136                                         else
3137                                                 M_IST(s1, REG_SP, s2 * 4);
3138                                 }
3139                         }
3140                         else {
3141                                 s1 = md->params[i].regoff + cd->stackframesize;
3142                                 s2 = nmd->params[j].regoff;
3143
3144                                 M_ILD(REG_ITMP1, REG_SP, s1 * 4);
3145                                 if (IS_2_WORD_TYPE(t))
3146                                         M_ILD(REG_ITMP2, REG_SP, s1 * 4 + 4);
3147
3148                                 M_IST(REG_ITMP1, REG_SP, s2 * 4);
3149                                 if (IS_2_WORD_TYPE(t))
3150                                         M_IST(REG_ITMP2, REG_SP, s2 * 4 + 4);
3151                         }
3152                 }
3153                 else {
3154                         /* We only copy spilled float arguments, as the float
3155                            argument registers keep unchanged. */
3156
3157                         if (md->params[i].inmemory) {
3158                                 s1 = md->params[i].regoff + cd->stackframesize;
3159                                 s2 = nmd->params[j].regoff;
3160
3161                                 if (IS_2_WORD_TYPE(t)) {
3162                                         M_DLD(REG_FTMP1, REG_SP, s1 * 4);
3163                                         M_DST(REG_FTMP1, REG_SP, s2 * 4);
3164                                 }
3165                                 else {
3166                                         M_FLD(REG_FTMP1, REG_SP, s1 * 4);
3167                                         M_FST(REG_FTMP1, REG_SP, s2 * 4);
3168                                 }
3169                         }
3170                 }
3171         }
3172
3173         /* put class into second argument register */
3174
3175         if (m->flags & ACC_STATIC) {
3176                 disp = dseg_add_address(cd, m->class);
3177                 M_ALD(REG_A1, REG_PV, disp);
3178         }
3179
3180         /* put env into first argument register */
3181
3182         disp = dseg_add_address(cd, _Jv_env);
3183         M_ALD(REG_A0, REG_PV, disp);
3184
3185         /* generate the actual native call */
3186
3187         M_ALD(REG_ITMP3, REG_PV, funcdisp);
3188         M_MTCTR(REG_ITMP3);
3189         M_JSR;
3190
3191         /* print call trace */
3192
3193         emit_verbosecall_exit(jd);
3194
3195         /* save return value */
3196
3197         switch (md->returntype.type) {
3198         case TYPE_INT:
3199         case TYPE_ADR:
3200                 M_IST(REG_RESULT, REG_SP, LA_SIZE + 1 * 4);
3201                 break;
3202         case TYPE_LNG:
3203                 M_LST(REG_RESULT_PACKED, REG_SP, LA_SIZE + 1 * 4);
3204                 break;
3205         case TYPE_FLT:
3206                 M_FST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3207                 break;
3208         case TYPE_DBL:
3209                 M_DST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3210                 break;
3211         case TYPE_VOID:
3212                 break;
3213         }
3214
3215         /* remove native stackframe info */
3216
3217         M_AADD_IMM(REG_SP, cd->stackframesize * 4, REG_A0);
3218         disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3219         M_ALD(REG_ITMP1, REG_PV, disp);
3220         M_MTCTR(REG_ITMP1);
3221         M_JSR;
3222         M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3223
3224         /* restore return value */
3225
3226         switch (md->returntype.type) {
3227         case TYPE_INT:
3228         case TYPE_ADR:
3229                 M_ILD(REG_RESULT, REG_SP, LA_SIZE + 1 * 4);
3230                 break;
3231         case TYPE_LNG:
3232                 M_LLD(REG_RESULT_PACKED, REG_SP, LA_SIZE + 1 * 4);
3233                 break;
3234         case TYPE_FLT:
3235                 M_FLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3236                 break;
3237         case TYPE_DBL:
3238                 M_DLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3239                 break;
3240         case TYPE_VOID:
3241                 break;
3242         }
3243
3244 #if defined(ENABLE_GC_CACAO)
3245         /* Restore callee saved integer registers from stackframeinfo (GC
3246            might have modified them during a collection). */
3247          
3248         disp = cd->stackframesize * 4 - sizeof(stackframeinfo) +
3249                 OFFSET(stackframeinfo, intregs);
3250
3251         for (i = 0; i < INT_SAV_CNT; i++)
3252                 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3253 #endif
3254
3255         M_ALD(REG_ITMP2_XPC, REG_SP, cd->stackframesize * 4 + LA_LR_OFFSET);
3256         M_MTLR(REG_ITMP2_XPC);
3257         M_LDA(REG_SP, REG_SP, cd->stackframesize * 4); /* remove stackframe       */
3258
3259         /* check for exception */
3260
3261         M_TST(REG_ITMP1_XPTR);
3262         M_BNE(1);                           /* if no exception then return        */
3263
3264         M_RET;
3265
3266         /* handle exception */
3267
3268         M_IADD_IMM(REG_ITMP2_XPC, -4, REG_ITMP2_XPC);  /* exception address       */
3269
3270         disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3271         M_ALD(REG_ITMP3, REG_PV, disp);
3272         M_MTCTR(REG_ITMP3);
3273         M_RTS;
3274
3275         /* generate patcher stubs */
3276
3277         emit_patcher_stubs(jd);
3278 }
3279
3280
3281 /*
3282  * These are local overrides for various environment variables in Emacs.
3283  * Please do not remove this and leave it at the end of the file, where
3284  * Emacs will automagically detect them.
3285  * ---------------------------------------------------------------------
3286  * Local variables:
3287  * mode: c
3288  * indent-tabs-mode: t
3289  * c-basic-offset: 4
3290  * tab-width: 4
3291  * End:
3292  * vim:noexpandtab:sw=4:ts=4:
3293  */