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