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