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