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