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