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