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