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