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