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