1c7831631f76964fadf62b883ef9a173d5100beb
[cacao.git] / src / vm / jit / powerpc64 / codegen.c
1 /* src/vm/jit/powerpc64/codegen.c - machine code generator for 64-bit PowerPC
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29 #include <stdint.h>
30 #include <stdio.h>
31 #include <signal.h>
32
33 #include "vm/types.h"
34
35 #include "md-abi.h"
36
37 #include "vm/jit/powerpc64/arch.h"
38 #include "vm/jit/powerpc64/codegen.h"
39
40 #include "mm/memory.hpp"
41
42 #include "native/localref.hpp"
43 #include "native/native.hpp"
44
45 #include "threads/lock.hpp"
46
47 #include "vm/jit/builtin.hpp"
48 #include "vm/exceptions.hpp"
49 #include "vm/global.h"
50 #include "vm/loader.hpp"
51 #include "vm/options.h"
52 #include "vm/vm.hpp"
53
54 #include "vm/jit/abi.h"
55 #include "vm/jit/abi-asm.h"
56 #include "vm/jit/asmpart.h"
57 #include "vm/jit/codegen-common.hpp"
58 #include "vm/jit/dseg.h"
59 #include "vm/jit/emit-common.hpp"
60 #include "vm/jit/jit.hpp"
61 #include "vm/jit/linenumbertable.hpp"
62 #include "vm/jit/parse.hpp"
63 #include "vm/jit/patcher-common.hpp"
64 #include "vm/jit/reg.h"
65 #include "vm/jit/replace.hpp"
66 #include "vm/jit/stacktrace.hpp"
67 #include "vm/jit/trap.hpp"
68
69 #if defined(ENABLE_LSRA)
70 # include "vm/jit/allocator/lsra.h"
71 #endif
72
73
74 /* codegen_emit ****************************************************************
75
76    Generates machine code.
77
78 *******************************************************************************/
79
80 bool codegen_emit(jitdata *jd)
81 {
82         methodinfo         *m;
83         codeinfo           *code;
84         codegendata        *cd;
85         registerdata       *rd;
86         s4                  len, s1, s2, s3, d, disp;
87         ptrint              a;
88         varinfo            *var;
89         basicblock         *bptr;
90         instruction        *iptr;
91         u2                  currentline;
92         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
93         unresolved_method  *um;
94         builtintable_entry *bte;
95         methoddesc         *md;
96         s4                  fieldtype;
97         s4                  varindex;
98         unresolved_field   *uf;
99         fieldinfo          *fi;
100
101         /* get required compiler data */
102
103         m    = jd->m;
104         code = jd->code;
105         cd   = jd->cd;
106         rd   = jd->rd;
107
108         /* prevent compiler warnings */
109
110         d   = 0;
111         lm  = NULL;
112         um  = NULL;
113         bte = NULL;
114         uf  = NULL;
115
116         {
117         s4 i, p, t, l;
118         s4 savedregs_num;
119
120         savedregs_num = 0;
121
122         /* space to save used callee saved registers */
123
124         savedregs_num += (INT_SAV_CNT - rd->savintreguse);
125         savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
126
127         cd->stackframesize = rd->memuse + savedregs_num;
128
129 #if defined(ENABLE_THREADS)
130         /* space to save argument of monitor_enter and Return Values to survive */
131     /* monitor_exit. The stack position for the argument can not be shared  */
132         /* with place to save the return register on PPC64, since both values     */
133         /* reside in R3 */
134         if (checksync && code_is_synchronized(code)) {
135                 /* reserve 2 slots for long/double return values for monitorexit */
136                 cd->stackframesize += 2;
137         }
138
139 #endif
140
141         /* create method header */
142
143         /* align stack to 16-bytes */
144
145 /* FIXME */
146 /*      if (!m->isleafmethod || opt_verbosecall) */
147 /*              stackframesize = (stackframesize + 3) & ~3;
148 */
149 /*      else if (m->isleafmethod && (stackframesize == LA_WORD_SIZE)) */
150 /*              stackframesize = 0; */
151
152         (void) dseg_add_unique_address(cd, code);                      /* CodeinfoPointer */
153         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8);             /* FrameSize       */
154
155         code->synchronizedoffset = rd->memuse * 8;
156
157         /* REMOVEME: We still need it for exception handling in assembler. */
158
159         if (code_is_leafmethod(code))
160                 (void) dseg_add_unique_s4(cd, 1);
161         else
162                 (void) dseg_add_unique_s4(cd, 0);
163
164         (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave         */
165         (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave         */
166
167         /* create stack frame (if necessary) */
168
169         if (!code_is_leafmethod(code)) {
170                 M_MFLR(REG_ZERO);
171                 M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET);
172         }
173
174         if (cd->stackframesize)
175                 M_STDU(REG_SP, REG_SP, -cd->stackframesize * 8);
176
177         /* save return address and used callee saved registers */
178
179         p = cd->stackframesize;
180         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
181                 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
182         }
183         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
184                 p --; M_DST(rd->savfltregs[i], REG_SP, p * 8);
185         }
186
187         /* take arguments out of register or stack frame */
188
189         md = m->parseddesc;
190
191         for (p = 0, l = 0; p < md->paramcount; p++) {
192                 t = md->paramtypes[p].type;
193                 varindex = jd->local_map[l*5 + t];
194                 l++;
195                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
196                         l++;
197                 if (varindex == UNUSED)
198                         continue;
199
200                 var = VAR(varindex);
201                 s1  = md->params[p].regoff;
202
203                 if (IS_INT_LNG_TYPE(t)) {
204                         if (!md->params[p].inmemory) {
205                                 if (!IS_INMEMORY(var->flags))
206                                         M_INTMOVE(s1, var->vv.regoff);
207                                 else
208                                         M_LST(s1, REG_SP, var->vv.regoff);
209                         }
210                         else {
211                                 if (!IS_INMEMORY(var->flags))
212                                         M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
213                                 else
214                                         var->vv.regoff = cd->stackframesize * 8 + s1;
215                         }
216                 }
217                 else {
218                         if (!md->params[p].inmemory) {
219                                 if (!IS_INMEMORY(var->flags))
220                                         M_FLTMOVE(s1, var->vv.regoff);
221                                 else
222                                         M_DST(s1, REG_SP, var->vv.regoff);
223                         }
224                         else {
225                                 if (!(var->flags & INMEMORY)) {
226                                         if (IS_2_WORD_TYPE(t))
227                                                 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
228                                         else
229                                                 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
230                                 }
231                                 else
232                                         var->vv.regoff = cd->stackframesize * 8 + s1;
233                         }
234                 }
235         }
236
237         /* save monitorenter argument */
238
239 #if defined(ENABLE_THREADS)
240
241         if (checksync && code_is_synchronized(code)) {
242
243                 /* stackoffset for argument used for LOCK_monitor_exit */
244                 s1 = rd->memuse;
245
246 #if !defined (NDEBUG)
247                 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
248                         M_AADD_IMM(REG_SP, -((LA_SIZE_IN_POINTERS + PA_SIZE_IN_POINTERS + ARG_CNT) * 8), REG_SP);
249
250                         for (p = 0; p < INT_ARG_CNT; p++)
251                                 M_LST(abi_registers_integer_argument[p], REG_SP, LA_SIZE + PA_SIZE + p * 8);
252
253                         for (p = 0; p < FLT_ARG_CNT; p++)
254                                 M_DST(abi_registers_float_argument[p], REG_SP, LA_SIZE + PA_SIZE + (INT_ARG_CNT + p) * 8);
255
256                         /* used for LOCK_monitor_exit, adopt size because we created another stackframe */
257                         s1 += (LA_SIZE_IN_POINTERS + PA_SIZE_IN_POINTERS + ARG_CNT);
258                 }
259 #endif
260
261                 p = dseg_add_functionptr(cd, LOCK_monitor_enter);
262                 M_ALD(REG_ITMP3, REG_PV, p);
263                 M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
264                 M_MTCTR(REG_ITMP3);
265
266                 /* get or test the lock object */
267
268                 if (m->flags & ACC_STATIC) {
269                         p = dseg_add_address(cd, &m->clazz->object.header);
270                         M_ALD(REG_A0, REG_PV, p);
271                 }
272                 else {
273                         M_TST(REG_A0);
274                         M_BNE(1);
275                         M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
276                 }
277
278                 M_AST(REG_A0, REG_SP, s1 * 8);                      /* rd->memuse * 8 */
279                 M_JSR;
280
281 #if !defined(NDEBUG)
282                 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
283                         for (p = 0; p < INT_ARG_CNT; p++)
284                                 M_LLD(abi_registers_integer_argument[p], REG_SP, LA_SIZE + PA_SIZE + p * 8);
285
286                         for (p = 0; p < FLT_ARG_CNT; p++)
287                                 M_DLD(abi_registers_float_argument[p], REG_SP, LA_SIZE + PA_SIZE + (INT_ARG_CNT + p) * 8);
288
289                         M_AADD_IMM(REG_SP, (LA_SIZE_IN_POINTERS + PA_SIZE_IN_POINTERS + ARG_CNT) * 8, REG_SP);
290                 }
291 #endif
292         }
293 #endif
294
295         /* call trace function */
296 #if !defined (NDEBUG)
297         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
298                 emit_verbosecall_enter(jd);
299 #endif
300
301         }
302
303         /* end of header generation */
304
305         /* create replacement points */
306          
307         REPLACEMENT_POINTS_INIT(cd, jd);
308
309         /* walk through all basic blocks */
310
311         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
312
313                 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
314
315                 if (bptr->flags >= BBREACHED) {
316
317                 /* branch resolving */
318                 codegen_resolve_branchrefs(cd, bptr);
319
320                 /* handle replacement points */
321
322                 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
323
324                 /* copy interface registers to their destination */
325
326                 len = bptr->indepth;
327                 MCODECHECK(128+len);
328
329 #if defined(ENABLE_LSRA)
330                 if (opt_lsra) {
331                         while (len) {
332                                 len--;
333                                 var = VAR(bptr->invars[len]);
334                                 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
335                                         /* d = reg_of_var(m, var, REG_ITMP1); */
336                                         if (!(var->flags & INMEMORY))
337                                                 d = var->vv.regoff;
338                                         else
339                                                 d = REG_ITMP1;
340                                         M_INTMOVE(REG_ITMP1, d);
341                                         emit_store(jd, NULL, var, d);
342                                 }
343                         }
344                 } else {
345 #endif
346                 while (len) {
347                         len--;
348                         var = VAR(bptr->invars[len]);
349                         if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
350                                 d = codegen_reg_of_var(0, var, REG_ITMP1);
351                                 M_INTMOVE(REG_ITMP1, d);
352                                 emit_store(jd, NULL, var, d);
353                         } 
354                         else {
355                                 assert((var->flags & INOUT));
356                         }
357                 }
358
359 #if defined(ENABLE_LSRA)
360                 }
361 #endif
362                 /* walk through all instructions */
363                 
364                 len = bptr->icount;
365                 currentline = 0;
366                         
367                 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
368                         if (iptr->line != currentline) {
369                                 linenumbertable_list_entry_add(cd, iptr->line);
370                                 currentline = iptr->line;
371                         }
372
373                         MCODECHECK(128);   /* an instruction usually needs < 64 words      */
374
375                 switch (iptr->opc) {
376                 case ICMD_NOP:        /* ...  ==> ...                                 */
377                 case ICMD_POP:        /* ..., value  ==> ...                          */
378                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
379                         break;
380
381                 case ICMD_INLINE_START:
382
383                         REPLACEMENT_POINT_INLINE_START(cd, iptr);
384                         break;
385
386                 case ICMD_INLINE_BODY:
387          
388                         REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
389                         linenumbertable_list_entry_add_inline_start(cd, iptr);
390                         linenumbertable_list_entry_add(cd, iptr->line);
391                         break;
392
393                 case ICMD_INLINE_END:
394
395                         linenumbertable_list_entry_add_inline_end(cd, iptr);
396                         linenumbertable_list_entry_add(cd, iptr->line);
397                         break;
398
399                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
400
401                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
402                         M_TST(s1);
403                         M_BEQ(0);
404                         emit_nullpointer_check(cd, iptr, s1);
405                         break;
406
407                 /* constant operations ************************************************/
408
409                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
410
411                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
412                         ICONST(d, iptr->sx.val.i);
413                         emit_store_dst(jd, iptr, d);
414                         break;
415
416                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
417
418                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
419                         LCONST(d, iptr->sx.val.l);
420                         emit_store_dst(jd, iptr, d);
421                         break;
422
423                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
424
425                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
426                         a = dseg_add_float(cd, iptr->sx.val.f);
427                         M_FLD(d, REG_PV, a);
428                         emit_store_dst(jd, iptr, d);
429                         break;
430                         
431                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
432
433                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
434                         a = dseg_add_double(cd, iptr->sx.val.d);
435                         M_DLD(d, REG_PV, a);
436                         emit_store_dst(jd, iptr, d);
437                         break;
438
439                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
440
441                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
442
443                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
444                                 disp = dseg_add_unique_address(cd, iptr->sx.val.c.ref);
445                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
446                                                                         iptr->sx.val.c.ref,
447                                                                     disp);
448                         } else  {
449                                 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
450                         }
451                         M_ALD(d, REG_PV, disp);
452                         emit_store_dst(jd, iptr, d);
453                         break;
454
455
456                 /* load/store/copy/move operations ************************************/
457
458                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
459                 case ICMD_ALOAD:      /* s1.localindex = local variable               */
460                 case ICMD_LLOAD:
461                 case ICMD_FLOAD:
462                 case ICMD_DLOAD:
463                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
464                 case ICMD_LSTORE:
465                 case ICMD_FSTORE:
466                 case ICMD_DSTORE:
467                 case ICMD_COPY:
468                 case ICMD_MOVE:
469
470                         emit_copy(jd, iptr);
471                         break;
472
473                 case ICMD_ASTORE:
474                         if (!(iptr->flags.bits & INS_FLAG_RETADDR))
475                                 emit_copy(jd, iptr);
476                         break;
477
478
479                 /* integer operations *************************************************/
480
481                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
482                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
483                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
484                         M_NEG(s1, d);
485                         M_EXTSW(d, d);
486                         emit_store_dst(jd, iptr, d);
487                         break;
488
489                 case ICMD_LNEG:    
490                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
491                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
492                         M_NEG(s1, d);
493                         emit_store_dst(jd, iptr, d);
494                         break;
495
496
497                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
498
499                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
500                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
501                         M_INTMOVE(s1, d);
502                         emit_store_dst(jd, iptr, d);
503                         break;
504
505                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
506
507                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
508                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
509                         M_ISEXT(s1, d); 
510                         emit_store_dst(jd, iptr, d);
511                         break;
512
513                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
514
515                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
516                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
517                         M_BSEXT(s1, d);
518                         emit_store_dst(jd, iptr, d);
519                         break;
520
521                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
522
523                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
524                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
525                         M_CZEXT(s1, d);
526                         emit_store_dst(jd, iptr, d);
527                         break;
528
529                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
530
531                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
532                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
533                         M_SSEXT(s1, d);
534                         emit_store_dst(jd, iptr, d);
535                         break;
536
537
538                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
539
540                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
541                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
542                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
543                         M_IADD(s1, s2, d);
544                         M_EXTSW(d,d);
545                         emit_store_dst(jd, iptr, d);
546                         break;
547
548                 case ICMD_IINC:
549                 case ICMD_IADDCONST:
550
551                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
552                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
553                         if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
554                                 M_IADD_IMM(s1, iptr->sx.val.i, d);
555                         } else {
556                                 ICONST(REG_ITMP2, iptr->sx.val.i);
557                                 M_IADD(s1, REG_ITMP2, d);
558                         }
559                         M_EXTSW(d,d);
560                         emit_store_dst(jd, iptr, d);
561                         break;
562
563                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
564
565                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
566                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
567                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
568                         M_LADD(s1, s2, d);
569                         emit_store_dst(jd, iptr, d);
570                         break;
571
572                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
573                                       /* sx.val.l = constant                          */
574
575                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
576                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
577                         /* XXX check me */
578                         if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
579                                 M_LADD_IMM(s1, iptr->sx.val.l, d);
580                         } else {
581                                 LCONST(REG_ITMP2, iptr->sx.val.l);
582                                 M_LADD(s1, REG_ITMP2, d);
583                         }
584                         emit_store_dst(jd, iptr, d);
585                         break;
586
587                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
588
589                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
590                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
591                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
592                         M_SUB(s1, s2, d);
593                         M_EXTSW(d, d);
594                         emit_store_dst(jd, iptr, d);
595                         break;
596
597                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
598                                       /* sx.val.i = constant                          */
599
600                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
601                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
602                         if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768)) {
603                                 M_IADD_IMM(s1, -iptr->sx.val.i, d);
604                         } else {
605                                 ICONST(REG_ITMP2, iptr->sx.val.i);
606                                 M_SUB(s1, REG_ITMP2, d);
607                         }
608                         M_EXTSW(d, d);
609                         emit_store_dst(jd, iptr, d);
610                         break;
611
612                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
613
614                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
615                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
616                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
617                         M_SUB(s1, s2, d);
618                         emit_store_dst(jd, iptr, d);
619                         break;
620
621                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
622                                       /* sx.val.l = constant                          */
623
624                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
625                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
626                         /* XXX check me */
627                         if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32767)) {
628                                 M_LADD_IMM(s1, -iptr->sx.val.l, d);
629                         } else {
630                                 LCONST(REG_ITMP2, iptr->sx.val.l);
631                                 M_SUB(s1, REG_ITMP2, d);
632                         }
633                         emit_store_dst(jd, iptr, d);
634                         break;
635
636                 case ICMD_IDIV:
637                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
638                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
639                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
640                         emit_arithmetic_check(cd, iptr, s2);
641
642                         M_DIV(s1, s2, d);
643                         M_EXTSW(d, d);
644                         emit_store_dst(jd, iptr, d);
645                         break;
646
647                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
648
649                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
650                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
651                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
652                         emit_arithmetic_check(cd, iptr, s2);
653
654                         M_DIV(s1, s2, d);
655                         /* we need to test if divident was 0x8000000000000, bit OV is set in XER in this case */
656                         /* we only need to check this if we did a LDIV, not for IDIV */
657                         M_MFXER(REG_ITMP2);
658                         M_ANDIS(REG_ITMP2, 0x4000, REG_ITMP2);  /* test OV */
659                         M_BLE(1);
660                         M_MOV(s1, d);                           /* java specs says result == dividend */
661                         emit_store_dst(jd, iptr, d);
662                         break;
663
664                 case ICMD_IREM:
665                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
666                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
667                         emit_arithmetic_check(cd, iptr, s2);
668
669                         M_DIV(s1, s2,  REG_ITMP3);      
670                         M_MUL(REG_ITMP3, s2, REG_ITMP2);
671                         M_SUB(s1, REG_ITMP2,  REG_ITMP3);
672                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
673
674                         M_MOV(REG_ITMP3, d);
675                         emit_store_dst(jd, iptr, d);
676                         break;
677
678
679                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
680                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
681                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
682                         emit_arithmetic_check(cd, iptr, s2);
683
684                         M_DIV(s1, s2,  REG_ITMP3);      
685                         /* we need to test if divident was 0x8000000000000, bit OV is set in XER in this case */
686                         /* we only need to check this if we did a LDIV, not for IDIV */
687                         M_MFXER(REG_ITMP2);
688                         M_ANDIS(REG_ITMP2, 0x4000, REG_ITMP2);  /* test OV */
689                         M_BLE(2); 
690                         LCONST(REG_ITMP3, 0);                   /* result == 0 in this case */
691                         M_BR(2 + (s2==REG_ITMP2));
692                         /* might require a reload */
693                         emit_load_s2(jd, iptr, REG_ITMP2);
694                         M_MUL(REG_ITMP3, s2, REG_ITMP2);
695                         M_SUB(s1, REG_ITMP2,  REG_ITMP3);
696                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
697
698                         M_MOV(REG_ITMP3, d);
699                         emit_store_dst(jd, iptr, d);
700                         break;
701
702                 
703                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
704                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
705                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
706                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
707                         M_MUL(s1, s2, d);
708                         M_EXTSW(d, d);
709                         emit_store_dst(jd, iptr, d);
710                         break;
711
712                 case ICMD_LMUL:
713                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
714                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
715                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
716                         M_MUL(s1, s2, d);
717                         emit_store_dst(jd, iptr, d);
718                         break;
719
720                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
721                                       /* sx.val.i = constant                          */
722
723                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
724                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
725                         if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
726                                 M_MUL_IMM(s1, iptr->sx.val.i, d);
727                         else {
728                                 ICONST(REG_ITMP3, iptr->sx.val.i);
729                                 M_MUL(s1, REG_ITMP3, d);
730                         }
731                         M_EXTSW(d, d);
732                         emit_store_dst(jd, iptr, d);
733                         break;
734                 case ICMD_LMULCONST:
735                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
736                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
737                         if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32767))
738                                 M_MUL_IMM(s1, iptr->sx.val.l, d);
739                         else {
740                                 LCONST(REG_ITMP3, iptr->sx.val.l);
741                                 M_MUL(s1, REG_ITMP3, d);
742                         }
743                         emit_store_dst(jd, iptr, d);
744                         break;
745
746                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value << constant       */
747                       
748                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
749                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
750                         M_SRA_IMM(s1, iptr->sx.val.i, d);
751                         M_ADDZE(d, d);
752                         M_EXTSW(d, d);
753                         emit_store_dst(jd, iptr, d);
754                         break;
755
756                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
757
758                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
759                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
760                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
761                         M_AND_IMM(s2, 0x1f, REG_ITMP3);
762                         M_SLL(s1, REG_ITMP3, d);
763                         M_EXTSW(d, d);
764                         emit_store_dst(jd, iptr, d);
765                         break;
766
767                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
768                                       /* sx.val.i = constant                             */
769
770                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
771                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
772                         M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
773                         M_EXTSW(d,d);
774                         emit_store_dst(jd, iptr, d);
775                         break;
776
777                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
778
779                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
780                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
781                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
782                         M_AND_IMM(s2, 0x1f, REG_ITMP3);
783                         M_SRA(s1, REG_ITMP3, d);
784                         emit_store_dst(jd, iptr, d);
785                         break;
786
787                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
788                                       /* sx.val.i = constant                             */
789
790                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
791                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
792                         M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
793                         emit_store_dst(jd, iptr, d);
794                         break;
795
796                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
797
798                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
799                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
800                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
801                         M_AND_IMM(s2, 0x1f, REG_ITMP2);
802                         M_MOV(s1, REG_ITMP1);
803                         M_CLR_HIGH(REG_ITMP1);
804                         M_SRL(REG_ITMP1, REG_ITMP2, d);
805                         M_EXTSW(d,d);   /* for the case it was shift 0 bits */
806                         emit_store_dst(jd, iptr, d);
807                         break;
808
809                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
810                                       /* sx.val.i = constant                             */
811
812                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
813                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
814                         if (iptr->sx.val.i & 0x1f) {
815                                 M_MOV(s1, REG_ITMP1);
816                                 M_CLR_HIGH(REG_ITMP1);
817                                 M_SRA_IMM(REG_ITMP1, iptr->sx.val.i & 0x1f, d);
818                         } else {
819                                 M_INTMOVE(s1, d);
820                         }
821                         emit_store_dst(jd, iptr, d);
822                         break;
823         
824                 case ICMD_LSHLCONST:
825                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
826                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
827                         M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
828                         emit_store_dst(jd, iptr, d);
829                         break;
830                 case ICMD_LSHL:
831                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
832                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
833                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
834                         M_AND_IMM(s2, 0x3f, REG_ITMP2);
835                         M_SLL(s1, REG_ITMP2, d);
836                         emit_store_dst(jd, iptr, d);
837                         break;
838                 case ICMD_LSHRCONST:
839                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
840                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
841                         M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
842                         emit_store_dst(jd, iptr, d);
843                         break;
844                 case ICMD_LSHR:
845                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
846                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
847                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
848                         M_AND_IMM(s2, 0x3f, REG_ITMP2);
849                         M_SRA(s1, REG_ITMP2, d);
850                         emit_store_dst(jd, iptr, d);
851                         break;
852                 case ICMD_LUSHRCONST:
853                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
854                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
855                         M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
856                         emit_store_dst(jd, iptr, d);
857                         break;
858                 case ICMD_LUSHR:
859                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
860                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
861                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
862                         M_AND_IMM(s2, 0x3f, REG_ITMP2);
863                         M_SRL(s1, REG_ITMP2, d);
864                         emit_store_dst(jd, iptr, d);
865                         break;
866
867                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
868                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
869                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
870                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
871                         M_AND(s1, s2, d);
872 /*                      M_EXTSW(d, d);*/
873                         emit_store_dst(jd, iptr, d);
874                         break;
875
876                 case ICMD_LAND:
877                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
878                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
879                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
880                         M_AND(s1, s2, d);
881                         emit_store_dst(jd, iptr, d);
882                         break;
883
884                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
885                                       /* sx.val.i = constant                          */
886
887                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
888                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
889                         if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535)) {
890                                 M_AND_IMM(s1, iptr->sx.val.i, d);
891                                 }
892                         /*
893                         else if (iptr->sx.val.i == 0xffffff) {
894                                 M_RLWINM(s1, 0, 8, 31, d);
895                                 }
896                         */
897                         else {
898                                 ICONST(REG_ITMP3, iptr->sx.val.i);
899                                 M_AND(s1, REG_ITMP3, d);
900                         }
901                         emit_store_dst(jd, iptr, d);
902                         break;
903
904                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
905                                       /* sx.val.l = constant                          */
906
907                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
908                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
909                         if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 65535))
910                                 M_AND_IMM(s1, iptr->sx.val.l, d);
911                         /*
912                         else if (iptr->sx.val.l == 0xffffff) {
913                                 M_RLWINM(s1, 0, 8, 31, d);
914                                 }
915                         */
916                         else {
917                                 LCONST(REG_ITMP3, iptr->sx.val.l);
918                                 M_AND(s1, REG_ITMP3, d);
919                         }
920                         emit_store_dst(jd, iptr, d);
921                         break;
922
923                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
924                                       /* sx.val.i = constant                             */
925                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
926                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
927 #if 0
928                         /* fast division, result in REG_ITMP3) */
929                         M_SRA_IMM(s1, iptr->sx.val.i, REG_ITMP3);
930                         M_ADDZE(REG_ITMP3, REG_ITMP3);
931
932                         M_SUB(s1, REG_ITMP3, d);
933                         M_EXTSW(d, d);
934                         emit_store_dst(jd, iptr, d);
935                         break;
936 #else
937                         
938                         M_MOV(s1, REG_ITMP2);
939                         M_CMPI(s1, 0);
940                         M_BGE(1 + 3*(iptr->sx.val.i >= 32768));
941                         if (iptr->sx.val.i >= 32768) {
942                                 M_ADDIS(REG_ZERO, iptr->sx.val.i >> 16, REG_ITMP2);
943                                 M_EXTSW(REG_ITMP2, REG_ITMP2);
944                                 M_OR_IMM(REG_ITMP2, iptr->sx.val.i, REG_ITMP2);
945                                 M_IADD(s1, REG_ITMP2, REG_ITMP2);
946                         } else {
947                                 M_IADD_IMM(s1, iptr->sx.val.i, REG_ITMP2);
948                         }
949                         {
950                                 int b=0, m = iptr->sx.val.i;
951                                 while (m >>= 1)
952                                         ++b;
953                                 M_RLWINM(REG_ITMP2, 0, 0, 30-b, REG_ITMP2);
954                         }
955                         M_SUB(s1, REG_ITMP2, d);
956                         M_EXTSW(d, d);
957                         emit_store_dst(jd, iptr, d);
958                         break;
959 #endif
960
961                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
962                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
963                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
964                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
965                         M_OR(s1, s2, d);
966 /*                      M_EXTSW(d,d);*/
967                         emit_store_dst(jd, iptr, d);
968                         break;
969
970                 case ICMD_LOR:
971
972                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
973                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
974                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
975                         M_OR(s1, s2, d);
976                         emit_store_dst(jd, iptr, d);
977                         break;
978
979                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
980                                       /* sx.val.i = constant                          */
981
982                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
983                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
984                         if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
985                                 M_OR_IMM(s1, iptr->sx.val.i, d);
986                         else {
987                                 ICONST(REG_ITMP3, iptr->sx.val.i);
988                                 M_OR(s1, REG_ITMP3, d);
989                         }
990                         emit_store_dst(jd, iptr, d);
991                         break;
992
993                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
994                                       /* sx.val.l = constant                          */
995
996                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
997                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
998                         if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 65535))
999                                 M_OR_IMM(s1, iptr->sx.val.l, d);
1000                         else {
1001                                 LCONST(REG_ITMP3, iptr->sx.val.l);
1002                                 M_OR(s1, REG_ITMP3, d);
1003                         }
1004                         emit_store_dst(jd, iptr, d);
1005                         break;
1006
1007
1008                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1009                 case ICMD_LXOR:
1010
1011                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1012                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1013                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1014                         M_XOR(s1, s2, d);
1015                         emit_store_dst(jd, iptr, d);
1016                         break;
1017
1018                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1019                                       /* sx.val.i = constant                          */
1020
1021                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1022                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1023                         if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
1024                                 M_XOR_IMM(s1, iptr->sx.val.i, d);
1025                         else {
1026                                 ICONST(REG_ITMP3, iptr->sx.val.i);
1027                                 M_XOR(s1, REG_ITMP3, d);
1028                         }
1029                         emit_store_dst(jd, iptr, d);
1030                         break;
1031
1032                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1033                                       /* sx.val.l = constant                          */
1034
1035                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1036                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1037                         if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 65535))
1038                                 M_XOR_IMM(s1, iptr->sx.val.l, d);
1039                         else {
1040                                 LCONST(REG_ITMP3, iptr->sx.val.l);
1041                                 M_XOR(s1, REG_ITMP3, d);
1042                         }
1043                         emit_store_dst(jd, iptr, d);
1044                         break;
1045
1046                 case ICMD_LCMP:       /* ..., val1, val2  ==> ..., val1 cmp val2      */
1047
1048                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1049                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1050                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1051                         /* XXX implement me!!! */
1052                         vm_abort("codegen: implement ICMD_LCMP!");
1053                         emit_store_dst(jd, iptr, d);
1054                         break;
1055                         break;
1056
1057
1058                 /* floating operations ************************************************/
1059
1060                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
1061
1062                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1063                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1064                         M_FMOVN(s1, d);
1065                         emit_store_dst(jd, iptr, d);
1066                         break;
1067
1068                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
1069
1070                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1071                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1072                         M_FMOVN(s1, d);
1073                         emit_store_dst(jd, iptr, d);
1074                         break;
1075
1076                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1077
1078                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1079                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1080                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1081                         M_FADD(s1, s2, d);
1082                         emit_store_dst(jd, iptr, d);
1083                         break;
1084
1085                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1086
1087                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1088                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1089                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1090                         M_DADD(s1, s2, d);
1091                         emit_store_dst(jd, iptr, d);
1092                         break;
1093
1094                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1095
1096                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1097                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1098                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1099                         M_FSUB(s1, s2, d);
1100                         emit_store_dst(jd, iptr, d);
1101                         break;
1102
1103                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1104
1105                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1106                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1107                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1108                         M_DSUB(s1, s2, d);
1109                         emit_store_dst(jd, iptr, d);
1110                         break;
1111
1112                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1113
1114                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1115                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1116                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1117                         M_FMUL(s1, s2, d);
1118                         emit_store_dst(jd, iptr, d);
1119                         break;
1120
1121                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1122
1123                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1124                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1125                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1126                         M_DMUL(s1, s2, d);
1127                         emit_store_dst(jd, iptr, d);
1128                         break;
1129
1130                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1131
1132                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1133                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1134                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1135                         M_FDIV(s1, s2, d);
1136                         emit_store_dst(jd, iptr, d);
1137                         break;
1138
1139                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1140
1141                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1142                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1143                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1144                         M_DDIV(s1, s2, d);
1145                         emit_store_dst(jd, iptr, d);
1146                         break;
1147                 
1148                 case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
1149                 case ICMD_D2I:
1150
1151                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1152                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1153                         M_CLR(d);
1154                         disp = dseg_add_float(cd, 0.0);
1155                         M_FLD(REG_FTMP2, REG_PV, disp);
1156                         M_FCMPU(s1, REG_FTMP2);
1157                         M_BNAN(4);
1158                         disp = dseg_add_unique_s4(cd, 0);
1159                         M_CVTDL_C(s1, REG_FTMP1);
1160                         M_LDA(REG_ITMP1, REG_PV, disp);
1161                         M_STFIWX(REG_FTMP1, 0, REG_ITMP1);
1162                         M_ILD(d, REG_PV, disp);
1163                         emit_store_dst(jd, iptr, d);
1164                         break;
1165                 
1166                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1167
1168                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1169                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1170                         M_FLTMOVE(s1, d);
1171                         emit_store_dst(jd, iptr, d);
1172                         break;
1173                                         
1174                 case ICMD_D2F:       /* ..., value  ==> ..., (double) value           */
1175
1176                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1177                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1178                         M_CVTDF(s1, d);
1179                         emit_store_dst(jd, iptr, d);
1180                         break;
1181                 
1182                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1183                 case ICMD_DCMPL:      /* == => 0, < => 1, > => -1                     */
1184
1185                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1186                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1187                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1188                         M_FCMPU(s2, s1);
1189                         M_IADD_IMM(REG_ZERO, -1, d);
1190                         M_BNAN(4);
1191                         M_BGT(3);
1192                         M_IADD_IMM(REG_ZERO, 0, d);
1193                         M_BGE(1);
1194                         M_IADD_IMM(REG_ZERO, 1, d);
1195                         emit_store_dst(jd, iptr, d);
1196                         break;
1197
1198                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1199                 case ICMD_DCMPG:      /* == => 0, < => 1, > => -1                     */
1200
1201                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1202                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1203                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1204                         M_FCMPU(s1, s2);
1205                         M_IADD_IMM(REG_ZERO, 1, d);
1206                         M_BNAN(4);
1207                         M_BGT(3);
1208                         M_IADD_IMM(REG_ZERO, 0, d);
1209                         M_BGE(1);
1210                         M_IADD_IMM(REG_ZERO, -1, d);
1211                         emit_store_dst(jd, iptr, d);
1212                         break;
1213
1214                         
1215                 /* memory operations **************************************************/
1216
1217                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1218
1219                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1220                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1221                         emit_nullpointer_check(cd, iptr, s1);
1222                         M_ILD(d, s1, OFFSET(java_array_t, size));
1223                         emit_store_dst(jd, iptr, d);
1224                         break;
1225
1226                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1227
1228                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1229                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1230                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1231                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1232                         M_IADD_IMM(s2, OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1233                         /* implicit null-pointer check */
1234                         M_LBZX(d, s1, REG_ITMP2);
1235                         M_BSEXT(d, d);
1236                         emit_store_dst(jd, iptr, d);
1237                         break;                  
1238
1239                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1240
1241                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1242                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1243                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1244                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1245                         M_SLL_IMM(s2, 1, REG_ITMP2);
1246                         M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1247                         /* implicit null-pointer check */
1248                         M_LHZX(d, s1, REG_ITMP2);
1249                         emit_store_dst(jd, iptr, d);
1250                         break;
1251
1252                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1253
1254                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1255                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1256                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1257                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1258                         M_SLL_IMM(s2, 1, REG_ITMP2);
1259                         M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1260                         /* implicit null-pointer check */
1261                         M_LHAX(d, s1, REG_ITMP2);
1262                         emit_store_dst(jd, iptr, d);
1263                         break;
1264
1265                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1266
1267                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1268                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1269                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1270                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1271                         M_SLL_IMM(s2, 2, REG_ITMP2);
1272                         M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1273                         /* implicit null-pointer check */
1274                         M_LWAX(d, s1, REG_ITMP2);
1275                         emit_store_dst(jd, iptr, d);
1276                         break;
1277
1278                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1279
1280                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1281                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1282                         d = codegen_reg_of_dst(jd, iptr, PACK_REGS(REG_ITMP2, REG_ITMP1));
1283                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1284                         M_SLL_IMM(s2, 3, REG_ITMP2);
1285                         M_IADD(s1, REG_ITMP2, REG_ITMP2);
1286                         /* implicit null-pointer check */
1287                         M_LLD_INTERN(d, REG_ITMP2, OFFSET(java_longarray_t, data[0]));
1288                         emit_store_dst(jd, iptr, d);
1289                         break;
1290
1291                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1292
1293                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1294                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1295                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1296                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1297                         M_SLL_IMM(s2, 2, REG_ITMP2);
1298                         M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1299                         /* implicit null-pointer check */
1300                         M_LFSX(d, s1, REG_ITMP2);
1301                         emit_store_dst(jd, iptr, d);
1302                         break;
1303
1304                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1305
1306                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1307                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1308                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1309                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1310                         M_SLL_IMM(s2, 3, REG_ITMP2);
1311                         M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1312                         /* implicit null-pointer check */
1313                         M_LFDX(d, s1, REG_ITMP2);
1314                         emit_store_dst(jd, iptr, d);
1315                         break;
1316
1317                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1318
1319                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1320                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1321                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1322                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1323                         M_SLL_IMM(s2, 3, REG_ITMP2);
1324                         M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1325                         /* implicit null-pointer check */
1326                         M_ALDX(d, s1, REG_ITMP2);
1327                         emit_store_dst(jd, iptr, d);
1328                         break;
1329
1330
1331                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1332
1333                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1334                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1335                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1336                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1337                         M_IADD_IMM(s2, OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1338                         /* implicit null-pointer check */
1339                         M_STBX(s3, s1, REG_ITMP2);
1340                         break;
1341
1342                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1343
1344                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1345                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1346                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1347                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1348                         M_SLL_IMM(s2, 1, REG_ITMP2);
1349                         M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1350                         /* implicit null-pointer check */
1351                         M_STHX(s3, s1, REG_ITMP2);
1352                         break;
1353
1354                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1355
1356                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1357                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1358                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1359                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1360                         M_SLL_IMM(s2, 1, REG_ITMP2);
1361                         M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1362                         M_STHX(s3, s1, REG_ITMP2);
1363                         break;
1364
1365                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1366
1367                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1368                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1369                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1370                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1371                         M_SLL_IMM(s2, 2, REG_ITMP2);
1372                         M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1373                         /* implicit null-pointer check */
1374                         M_STWX(s3, s1, REG_ITMP2);
1375                         break;
1376
1377                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1378
1379                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1380                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1381                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1382                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1383                         M_SLL_IMM(s2, 3, REG_ITMP2);
1384                         M_IADD_IMM(REG_ITMP2, OFFSET(java_longarray_t, data[0]), REG_ITMP2);
1385                         /* implicit null-pointer check */
1386                         M_LSTX(s3, s1, REG_ITMP2);
1387                         break;
1388
1389                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1390
1391                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1392                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1393                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1394                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1395                         M_SLL_IMM(s2, 2, REG_ITMP2);
1396                         M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1397                         /* implicit null-pointer check */
1398                         M_STFSX(s3, s1, REG_ITMP2);
1399                         break;
1400
1401                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1402
1403                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1404                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1405                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1406                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1407                         M_SLL_IMM(s2, 3, REG_ITMP2);
1408                         M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1409                         /* implicit null-pointer check */
1410                         M_STFDX(s3, s1, REG_ITMP2);
1411                         break;
1412
1413                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1414
1415                         s1 = emit_load_s1(jd, iptr, REG_A0);
1416                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1417                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1418                         s3 = emit_load_s3(jd, iptr, REG_A1);
1419
1420                         disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1421                         M_ALD(REG_ITMP3, REG_PV, disp);
1422                         M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
1423                         M_MTCTR(REG_ITMP3);
1424
1425                         M_INTMOVE(s1, REG_A0);
1426                         M_INTMOVE(s3, REG_A1);
1427
1428                         M_JSR;
1429                         emit_arraystore_check(cd, iptr);
1430
1431                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1432                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1433                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1434                         M_SLL_IMM(s2, 3, REG_ITMP2);
1435                         M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1436                         /* implicit null-pointer check */
1437                         M_ASTX(s3, s1, REG_ITMP2);
1438                         break;
1439
1440
1441                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1442
1443                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1444                                 uf        = iptr->sx.s23.s3.uf;
1445                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1446                                 disp      = dseg_add_unique_address(cd, NULL);
1447
1448                                 patcher_add_patch_ref(jd, PATCHER_get_putstatic,
1449                                                                         iptr->sx.s23.s3.uf, disp);
1450
1451                         }
1452                         else {
1453                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1454                                 fieldtype = fi->type;
1455                                 disp      = dseg_add_address(cd, fi->value);
1456
1457                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1458                                         patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, disp);
1459                                 }
1460                         }
1461
1462                         M_ALD(REG_ITMP1, REG_PV, disp);
1463                         switch (fieldtype) {
1464                         case TYPE_INT:
1465                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1466                                 M_ILD_INTERN(d, REG_ITMP1, 0);
1467                                 break;
1468                         case TYPE_LNG:
1469                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1470                                 M_LLD(d, REG_ITMP1, 0);
1471                                 break;
1472                         case TYPE_ADR:
1473                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1474                                 M_ALD_INTERN(d, REG_ITMP1, 0);
1475                                 break;
1476                         case TYPE_FLT:
1477                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1478                                 M_FLD_INTERN(d, REG_ITMP1, 0);
1479                                 break;
1480                         case TYPE_DBL:                          
1481                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1482                                 M_DLD_INTERN(d, REG_ITMP1, 0);
1483                                 break;
1484                         }
1485                         emit_store_dst(jd, iptr, d);
1486                         break;
1487
1488                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
1489
1490
1491                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1492                                 uf        = iptr->sx.s23.s3.uf;
1493                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1494                                 disp      = dseg_add_unique_address(cd, NULL);
1495
1496                                 patcher_add_patch_ref(jd, PATCHER_get_putstatic,
1497                                                                         iptr->sx.s23.s3.uf, disp);
1498                         }
1499                         else {
1500                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1501                                 fieldtype = fi->type;
1502                                 disp      = dseg_add_address(cd, fi->value);
1503
1504                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1505                                         patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, disp);
1506                                 }
1507                         }
1508
1509                         M_ALD(REG_ITMP1, REG_PV, disp);
1510                         switch (fieldtype) {
1511                         case TYPE_INT:
1512                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1513                                 M_IST_INTERN(s1, REG_ITMP1, 0);
1514                                 break;
1515                         case TYPE_LNG:
1516                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1517                                 M_LST_INTERN(s1, REG_ITMP1, 0);
1518                                 break;
1519                         case TYPE_ADR:
1520                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1521                                 M_AST_INTERN(s1, REG_ITMP1, 0);
1522                                 break;
1523                         case TYPE_FLT:
1524                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1525                                 M_FST_INTERN(s1, REG_ITMP1, 0);
1526                                 break;
1527                         case TYPE_DBL:
1528                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1529                                 M_DST_INTERN(s1, REG_ITMP1, 0);
1530                                 break;
1531                         }
1532                         break;
1533
1534
1535                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
1536
1537                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1538
1539                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1540                                 uf        = iptr->sx.s23.s3.uf;
1541                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1542                                 disp      = 0;
1543
1544                                 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1545                         }
1546                         else {
1547                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1548                                 fieldtype = fi->type;
1549                                 disp      = fi->offset;
1550                         }
1551
1552                         /* implicit null-pointer check */
1553                         switch (fieldtype) {
1554                         case TYPE_INT:
1555                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1556                                 M_ILD(d, s1, disp);
1557                                 break;
1558                         case TYPE_LNG:
1559                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1560                                 M_LLD(d, s1, disp);
1561                                 break;
1562                         case TYPE_ADR:
1563                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1564                                 M_ALD(d, s1, disp);
1565                                 break;
1566                         case TYPE_FLT:
1567                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1568                                 M_FLD(d, s1, disp);
1569                                 break;
1570                         case TYPE_DBL:                          
1571                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1572                                 M_DLD(d, s1, disp);
1573                                 break;
1574                         }
1575                         emit_store_dst(jd, iptr, d);
1576                         break;
1577
1578                 case ICMD_PUTFIELD:   /* ..., value  ==> ...                          */
1579
1580                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1581
1582                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1583                                 uf        = iptr->sx.s23.s3.uf;
1584                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1585                                 disp      = 0;
1586                         }
1587                         else {
1588                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1589                                 fieldtype = fi->type;
1590                                 disp      = fi->offset;
1591                         }
1592
1593                         if (IS_INT_LNG_TYPE(fieldtype)) {
1594                                 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1595                         }
1596                         else
1597                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1598
1599                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1600                                 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1601                         }
1602
1603
1604                         /* implicit null-pointer check */
1605                         switch (fieldtype) {
1606                         case TYPE_INT:
1607                                 M_IST(s2, s1, disp);
1608                                 break;
1609                         case TYPE_LNG:
1610                                 M_LST(s2, s1, disp);
1611                                 break;
1612                         case TYPE_ADR:
1613                                 M_AST(s2, s1, disp);
1614                                 break;
1615                         case TYPE_FLT:
1616                                 M_FST(s2, s1, disp);
1617                                 break;
1618                         case TYPE_DBL:
1619                                 M_DST(s2, s1, disp);
1620                                 break;
1621                         }
1622                         break;
1623
1624
1625                 /* branch operations **************************************************/
1626
1627                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
1628
1629                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1630                         M_LNGMOVE(s1, REG_ITMP1_XPTR);
1631
1632 #ifdef ENABLE_VERIFIER
1633                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1634                                 patcher_add_patch_ref(jd, PATCHER_resolve_class,
1635                                                                         iptr->sx.s23.s2.uc, 0);
1636                         }
1637 #endif /* ENABLE_VERIFIER */
1638
1639                         disp = dseg_add_functionptr(cd, asm_handle_exception);
1640                         M_ALD(REG_ITMP2, REG_PV, disp);
1641                         M_MTCTR(REG_ITMP2);
1642
1643                         if (code_is_leafmethod(code))
1644                                 M_MFLR(REG_ITMP3);                          /* save LR        */
1645
1646                         M_BL(0);                                        /* get current PC */
1647                         M_MFLR(REG_ITMP2_XPC);
1648
1649                         if (code_is_leafmethod(code))
1650                                 M_MTLR(REG_ITMP3);                          /* restore LR     */
1651
1652                         M_RTS;                                          /* jump to CTR    */
1653                         ALIGNCODENOP;
1654                         break;
1655
1656                 case ICMD_GOTO:         /* ... ==> ...                                */
1657                 case ICMD_RET:          /* ... ==> ...                                */
1658
1659                         emit_br(cd, iptr->dst.block);
1660                         ALIGNCODENOP;
1661                         break;
1662
1663                 case ICMD_JSR:          /* ... ==> ...                                */
1664
1665                         emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1666                         ALIGNCODENOP;
1667                         break;
1668
1669                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
1670
1671                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1672                         M_TST(s1);
1673                         emit_beq(cd, iptr->dst.block);
1674                         break;
1675
1676                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
1677
1678                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1679                         M_TST(s1);
1680                         emit_bne(cd, iptr->dst.block);
1681                         break;
1682
1683                 case ICMD_IFLT:
1684                 case ICMD_IFLE:
1685                 case ICMD_IFNE:
1686                 case ICMD_IFGT:
1687                 case ICMD_IFGE:
1688                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
1689
1690                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1691                         if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
1692                                 M_CMPI(s1, iptr->sx.val.i);
1693                         else {
1694                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1695                                 M_CMP(s1, REG_ITMP2);
1696                         }
1697                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
1698                         break;
1699                         
1700                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
1701                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1702                         LCONST(REG_ITMP2, iptr->sx.val.l);
1703                         M_CMP(s1, REG_ITMP2);
1704                         emit_beq(cd, iptr->dst.block);
1705                         break;
1706                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
1707                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1708                         LCONST(REG_ITMP2, iptr->sx.val.l);
1709                         M_CMP(s1, REG_ITMP2);
1710                         emit_blt(cd, iptr->dst.block);
1711                         break;
1712                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
1713                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1714                         LCONST(REG_ITMP2, iptr->sx.val.l);
1715                         M_CMP(s1, REG_ITMP2);
1716                         emit_ble(cd, iptr->dst.block);
1717                         break;
1718
1719                 case ICMD_IF_LNE:       /* ..., value ==> ... */
1720                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1721                         LCONST(REG_ITMP2, iptr->sx.val.l);
1722                         M_CMP(s1, REG_ITMP2);
1723                         emit_bne(cd, iptr->dst.block);
1724                         break;
1725                 case ICMD_IF_LGE:       /* ..., value ==> ... */
1726                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1727                         LCONST(REG_ITMP2, iptr->sx.val.l);
1728                         M_CMP(s1, REG_ITMP2);
1729                         emit_bge(cd, iptr->dst.block);
1730                         break;
1731                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
1732                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1733                         LCONST(REG_ITMP2, iptr->sx.val.l);
1734                         M_CMP(s1, REG_ITMP2);
1735                         emit_bgt(cd, iptr->dst.block);
1736                         break;
1737                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
1738                 case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
1739                 case ICMD_IF_LCMPEQ: 
1740
1741                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1742                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1743                         M_CMP(s1, s2);
1744                         emit_beq(cd, iptr->dst.block);
1745                         break;
1746
1747                 case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
1748                 case ICMD_IF_ACMPNE:    /* op1 = target JavaVM pc                     */
1749                 case ICMD_IF_LCMPNE:  
1750
1751                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1752                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1753                         M_CMP(s1, s2);
1754                         emit_bne(cd, iptr->dst.block);
1755                         break;
1756
1757
1758                 case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
1759                 case ICMD_IF_LCMPLT:
1760
1761                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1762                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1763                         M_CMP(s1, s2);
1764                         emit_blt(cd, iptr->dst.block);
1765                         break;
1766
1767                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
1768                 case ICMD_IF_LCMPGT:
1769
1770                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1771                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1772                         M_CMP(s1, s2);
1773                         emit_bgt(cd, iptr->dst.block);
1774                         break;
1775
1776                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
1777                 case ICMD_IF_LCMPLE:
1778
1779                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1780                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1781                         M_CMP(s1, s2);
1782                         emit_ble(cd, iptr->dst.block);
1783                         break;
1784
1785                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
1786                 case ICMD_IF_LCMPGE:
1787
1788                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1789                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1790                         M_CMP(s1, s2);
1791                         emit_bge(cd, iptr->dst.block);
1792                         break;
1793
1794
1795                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
1796                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
1797
1798                         REPLACEMENT_POINT_RETURN(cd, iptr);
1799                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
1800                         M_LNGMOVE(s1, REG_RESULT);
1801                         goto nowperformreturn;
1802
1803                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
1804
1805                         REPLACEMENT_POINT_RETURN(cd, iptr);
1806                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
1807                         M_LNGMOVE(s1, REG_RESULT);
1808
1809 #ifdef ENABLE_VERIFIER
1810                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1811                                 patcher_add_patch_ref(jd, PATCHER_resolve_class,
1812                                                                         iptr->sx.s23.s2.uc, 0);
1813                         }
1814 #endif /* ENABLE_VERIFIER */
1815
1816                         goto nowperformreturn;
1817
1818                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
1819                 case ICMD_DRETURN:
1820
1821                         REPLACEMENT_POINT_RETURN(cd, iptr);
1822                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1823                         M_FLTMOVE(s1, REG_FRESULT);
1824                         goto nowperformreturn;
1825
1826                 case ICMD_RETURN:      /* ...  ==> ...                                */
1827
1828                         REPLACEMENT_POINT_RETURN(cd, iptr);
1829
1830 nowperformreturn:
1831                         {
1832                         s4 i, p;
1833                         
1834                         p = cd->stackframesize;
1835
1836                         /* call trace function */
1837
1838 #if !defined(NDEBUG)
1839                         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
1840                                 emit_verbosecall_exit(jd);
1841 #endif          
1842
1843 #if defined(ENABLE_THREADS)
1844                         if (checksync && code_is_synchronized(code)) {
1845                                 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
1846                                 M_ALD(REG_ITMP3, REG_PV, disp);
1847                                 M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
1848                                 M_MTCTR(REG_ITMP3);
1849
1850                                 /* we need to save the proper return value */
1851
1852                                 switch (iptr->opc) {
1853                                 case ICMD_LRETURN:
1854                                 case ICMD_IRETURN:
1855                                 case ICMD_ARETURN:
1856                                         /* fall through */
1857                                         M_LST(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1858                                         break;
1859                                 case ICMD_FRETURN:
1860                                         M_FST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1861                                         break;
1862                                 case ICMD_DRETURN:
1863                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1864                                         break;
1865                                 }
1866
1867                                 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
1868                                 M_JSR;
1869
1870                                 /* and now restore the proper return value */
1871
1872                                 switch (iptr->opc) {
1873                                 case ICMD_LRETURN:
1874                                 case ICMD_IRETURN:
1875                                 case ICMD_ARETURN:
1876                                         /* fall through */
1877                                         M_LLD(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1878                                         break;
1879                                 case ICMD_FRETURN:
1880                                         M_FLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1881                                         break;
1882                                 case ICMD_DRETURN:
1883                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1884                                         break;
1885                                 }
1886                         }
1887 #endif
1888
1889                         /* restore return address                                         */
1890
1891                         if (!code_is_leafmethod(code)) {
1892                                 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
1893                                    may have a displacement overflow. */
1894
1895                                 M_ALD(REG_ITMP1, REG_SP, p * 8 + LA_LR_OFFSET);
1896                                 M_MTLR(REG_ITMP1);
1897                         }
1898
1899                         /* restore saved registers                                        */
1900
1901                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
1902                                 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
1903                         }
1904                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
1905                                 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
1906                         }
1907
1908                         /* deallocate stack                                               */
1909
1910                         if (cd->stackframesize)
1911                                 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
1912
1913                         M_RET;
1914                         ALIGNCODENOP;
1915                         }
1916                         break;
1917
1918
1919                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
1920                         {
1921                         s4 i, l;
1922                         branch_target_t *table;
1923
1924                         table = iptr->dst.table;
1925
1926                         l = iptr->sx.s23.s2.tablelow;
1927                         i = iptr->sx.s23.s3.tablehigh;
1928
1929                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1930                         if (l == 0) {
1931                                 M_INTMOVE(s1, REG_ITMP1);
1932                         } else if (l <= 32768) {
1933                                 M_LDA(REG_ITMP1, s1, -l);
1934                         } else {
1935                                 ICONST(REG_ITMP2, l);
1936                                 M_SUB(s1, REG_ITMP2, REG_ITMP1);
1937                         }
1938
1939                         /* number of targets */
1940                         i = i - l + 1;
1941
1942                         /* range check */
1943
1944                         M_CMPUI(REG_ITMP1, i - 1);
1945                         emit_bgt(cd, table[0].block);
1946
1947                         /* build jump table top down and use address of lowest entry */
1948
1949                         table += i;
1950
1951                         while (--i >= 0) {
1952                                 dseg_add_target(cd, table->block); 
1953                                 --table;
1954                         }
1955
1956                         /* length of dataseg after last dseg_add_unique_target is used by load */
1957
1958                         M_SLL_IMM(REG_ITMP1, 3, REG_ITMP1);
1959                         M_IADD(REG_ITMP1, REG_PV, REG_ITMP2);
1960                         M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
1961                         M_MTCTR(REG_ITMP2);
1962                         M_RTS;
1963                         ALIGNCODENOP;
1964                         }
1965                         break;
1966
1967
1968                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
1969                         {
1970                         s4 i, val;
1971                         lookup_target_t *lookup;
1972
1973                         lookup = iptr->dst.lookup;
1974
1975                         i = iptr->sx.s23.s2.lookupcount;
1976                         
1977                         MCODECHECK((i<<3)+8);
1978                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1979                         while (--i >= 0) {
1980                                 val = lookup->value;
1981                                 if ((val >= -32768) && (val <= 32767)) {
1982                                         M_CMPI(s1, val);
1983                         
1984                                 } else {
1985                                         a = dseg_add_s4(cd, val);
1986                                         M_ILD(REG_ITMP2, REG_PV, a);
1987                                         M_CMP(s1, REG_ITMP2);
1988                                 }
1989                                 emit_beq(cd, lookup->target.block);
1990                                 ++lookup;
1991                         }
1992
1993                         emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
1994
1995                         ALIGNCODENOP;
1996                         break;
1997                         }
1998
1999
2000                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
2001
2002                         bte = iptr->sx.s23.s3.bte;
2003                         md = bte->md;
2004                         goto gen_method;
2005
2006                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
2007                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2008                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
2009                 case ICMD_INVOKEINTERFACE:
2010
2011                         REPLACEMENT_POINT_INVOKE(cd, iptr);
2012
2013                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2014                                 lm = NULL;
2015                                 um = iptr->sx.s23.s3.um;
2016                                 md = um->methodref->parseddesc.md;
2017                         }
2018                         else {
2019                                 lm = iptr->sx.s23.s3.fmiref->p.method;
2020                                 um = NULL;
2021                                 md = lm->parseddesc;
2022                         }
2023
2024 gen_method:
2025                         s3 = md->paramcount;
2026
2027                         MCODECHECK((s3 << 2) + 128);
2028
2029                         /* copy arguments to registers or stack location */
2030
2031                         for (s3 = s3 - 1; s3 >= 0; s3--) {
2032                                 var = VAR(iptr->sx.s23.s2.args[s3]);
2033                                 d   = md->params[s3].regoff;
2034
2035                                 if (var->flags & PREALLOC)
2036                                         continue;
2037
2038                                 if (IS_INT_LNG_TYPE(var->type)) {
2039                                         if (!md->params[s3].inmemory) {
2040                                                 s1 = emit_load(jd, iptr, var, d);
2041                                                 M_LNGMOVE(s1, d);
2042                                         }
2043                                         else {
2044                                                 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2045                                                 M_LST(s1, REG_SP, d);
2046                                         }
2047                                 }
2048                                 else {
2049                                         if (!md->params[s3].inmemory) {
2050                                                 s1 = emit_load(jd, iptr, var, d);
2051                                                 M_FLTMOVE(s1, d);
2052                                         }
2053                                         else {
2054                                                 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2055                                                 M_DST(s1, REG_SP, d);
2056                                         }
2057                                 }
2058                         }
2059
2060                         switch (iptr->opc) {
2061                         case ICMD_BUILTIN:
2062                                 if (bte->stub == NULL) {
2063                                         disp = dseg_add_functionptr(cd, bte->fp);
2064                                         M_ALD(REG_PV, REG_PV, disp);
2065                                         M_ALD(REG_PV, REG_PV, 0);       /* TOC */
2066                                 }
2067                                 else {
2068                                         disp = dseg_add_functionptr(cd, bte->stub);
2069                                         M_ALD(REG_PV, REG_PV, disp);
2070                                 }
2071
2072                                 /* generate the actual call */
2073                                 M_MTCTR(REG_PV);
2074                                 M_JSR;
2075                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2076                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2077                                 M_MFLR(REG_ITMP1);
2078                                 M_LDA(REG_PV, REG_ITMP1, -disp);
2079                                 break;
2080
2081                         case ICMD_INVOKESPECIAL:
2082                                 emit_nullpointer_check(cd, iptr, REG_A0);
2083                                 /* fall through */
2084
2085                         case ICMD_INVOKESTATIC:
2086                                 if (lm == NULL) {
2087                                         disp = dseg_add_unique_address(cd, um);
2088
2089                                         patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2090                                                                                 um, disp);
2091                                 } else {
2092                                         disp = dseg_add_address(cd, lm->stubroutine);
2093                                 }
2094                                 M_ALD(REG_PV, REG_PV, disp);
2095
2096                                 /* generate the actual call */
2097
2098                                 M_MTCTR(REG_PV);
2099                                 M_JSR;
2100                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2101                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2102                                 M_MFLR(REG_ITMP1);
2103                                 M_LDA(REG_PV, REG_ITMP1, -disp);
2104                                 break;
2105
2106                         case ICMD_INVOKEVIRTUAL:
2107                                 if (lm == NULL) {
2108                                         patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2109                                         s1 = 0;
2110                                 } else {
2111                                         s1 = OFFSET(vftbl_t, table[0]) +
2112                                                 sizeof(methodptr) * lm->vftblindex;
2113                                 }
2114
2115                                 /* implicit null-pointer check */
2116                                 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2117                                 M_ALD(REG_PV, REG_METHODPTR, s1);
2118
2119                                 /* generate the actual call */
2120
2121                                 M_MTCTR(REG_PV);
2122                                 M_JSR;
2123                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2124                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2125                                 M_MFLR(REG_ITMP1);
2126                                 M_LDA(REG_PV, REG_ITMP1, -disp);
2127                                 break;
2128
2129                         case ICMD_INVOKEINTERFACE:
2130                                 if (lm == NULL) {
2131                                         patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2132
2133                                         s1 = 0;
2134                                         s2 = 0;
2135
2136                                 } else {
2137                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
2138                                                 sizeof(methodptr*) * lm->clazz->index;
2139
2140                                         s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2141                                 }
2142
2143                                 /* implicit null-pointer check */
2144                                 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));    
2145                                 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2146                                 M_ALD(REG_PV, REG_METHODPTR, s2);
2147
2148                                 /* generate the actual call */
2149
2150                                 M_MTCTR(REG_PV);
2151                                 M_JSR;
2152                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2153                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2154                                 M_MFLR(REG_ITMP1);
2155                                 M_LDA(REG_PV, REG_ITMP1, -disp);
2156
2157                                 break;
2158                         }
2159                         /* store return value */
2160
2161                         d = md->returntype.type;
2162
2163                         if (d != TYPE_VOID) {
2164                                 if (IS_INT_LNG_TYPE(d)) {
2165                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2166                                         M_MOV(REG_RESULT, s1);
2167                                 }
2168                                 else {
2169                                         s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2170                                         M_FLTMOVE(REG_FRESULT, s1);
2171                                 }
2172                                 emit_store_dst(jd, iptr, s1);
2173                         }
2174                         break;
2175
2176                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2177                                       /* val.a: (classinfo*) superclass               */
2178
2179                         /*  superclass is an interface:
2180                          *
2181                          *  OK if ((sub == NULL) ||
2182                          *         (sub->vftbl->interfacetablelength > super->index) &&
2183                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
2184                          *
2185                          *  superclass is a class:
2186                          *
2187                          *  OK if ((sub == NULL) || (0
2188                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2189                          *         super->vftbl->diffvall));
2190                          */
2191
2192                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2193                                 /* object type cast-check */
2194
2195                                 classinfo *super;
2196                                 s4         superindex;
2197
2198                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2199                                         super      = NULL;
2200                                         superindex = 0;
2201                                 }
2202                                 else {
2203                                         super      = iptr->sx.s23.s3.c.cls;
2204                                         superindex = super->index;
2205                                 }
2206                 
2207                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2208
2209                                 /* if class is not resolved, check which code to call */
2210
2211                                 if (super == NULL) {
2212                                         M_TST(s1);
2213                                         emit_label_beq(cd, BRANCH_LABEL_1);
2214                                         disp = dseg_add_unique_s4(cd, 0);                     /* super->flags */
2215
2216                                         patcher_add_patch_ref(jd,
2217                                                                                 PATCHER_resolve_classref_to_flags,
2218                                                                                 iptr->sx.s23.s3.c.ref,
2219                                                                                 disp);
2220
2221                                         M_ILD(REG_ITMP2, REG_PV, disp);
2222                                         M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2223
2224                                         emit_label_beq(cd, BRANCH_LABEL_2);
2225                                 }
2226
2227                                 /* interface checkcast code */
2228
2229                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2230                                         if (super == NULL) {
2231                                                 patcher_add_patch_ref(jd,
2232                                                                                         PATCHER_checkcast_interface,
2233                                                                                         iptr->sx.s23.s3.c.ref,
2234                                                                                         0);
2235                                         } else {
2236                                                 M_TST(s1);
2237                                                 emit_label_beq(cd, BRANCH_LABEL_3);
2238                                         }
2239
2240                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2241                                         M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2242                                         M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
2243                                         emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2244                                         M_ALD(REG_ITMP3, REG_ITMP2,
2245                                                   OFFSET(vftbl_t, interfacetable[0]) -
2246                                                   superindex * sizeof(methodptr*));
2247                                         M_TST(REG_ITMP3);
2248                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2249
2250                                         if (super == NULL)      {
2251                                                 emit_label_br(cd, BRANCH_LABEL_4);
2252                                         } else  {
2253                                                 emit_label(cd, BRANCH_LABEL_3);
2254                                         }
2255                                 }
2256
2257                                 /* class checkcast code */
2258
2259                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2260                                         if (super == NULL) {
2261                                                 emit_label(cd, BRANCH_LABEL_2);
2262
2263                                                 disp = dseg_add_unique_address(cd, NULL);
2264                                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2265                                                                                         iptr->sx.s23.s3.c.ref,
2266                                                                                         disp);
2267                                         } else {
2268                                                 disp = dseg_add_address(cd, super->vftbl);
2269                                                 M_TST(s1);
2270                                                 emit_label_beq(cd, BRANCH_LABEL_5);
2271                                         }
2272
2273                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2274                                         M_ALD(REG_ITMP3, REG_PV, disp);
2275
2276                                         if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2277                                                 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2278                                                 M_LADD(REG_ITMP1, REG_ITMP2, REG_ITMP1);
2279                                                 M_ALD(REG_ITMP1, REG_ITMP1, 0);
2280                                                 M_CMP(REG_ITMP1, REG_ITMP3);
2281                                                 emit_label_beq(cd, BRANCH_LABEL_6);  /* good */
2282
2283                                                 if (super == NULL) {
2284                                                         M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2285                                                         M_CMPI(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]));
2286                                                         emit_label_bne(cd, BRANCH_LABEL_10);  /* throw */
2287                                                 }
2288
2289                                                 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2290                                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
2291                                                 M_CMP(REG_ITMP1, REG_ITMP3);
2292                                                 emit_label_bgt(cd, BRANCH_LABEL_9);  /* throw */
2293                                                 /* reload */
2294                                                 M_ALD(REG_ITMP3, REG_PV, disp);
2295                                                 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2296
2297                                                 M_SLL_IMM(REG_ITMP1, 3, REG_ITMP1);
2298                                                 M_IADD_IMM(REG_ITMP2, -DISPLAY_SIZE*8, REG_ITMP2);
2299                                                 M_ALDX(REG_ITMP1, REG_ITMP2, REG_ITMP1);
2300                                                 M_CMP(REG_ITMP1, REG_ITMP3);
2301                                                 emit_label_beq(cd, BRANCH_LABEL_7);  /* good */
2302
2303                                                 emit_label(cd, BRANCH_LABEL_9);
2304                                                 if (super == NULL)
2305                                                         emit_label(cd, BRANCH_LABEL_10);
2306
2307                                                 /* reload s1, might have been destroyed */
2308                                                 emit_load_s1(jd, iptr, REG_ITMP1);
2309                                                 M_LWZ(s1, REG_ZERO, TRAP_ClassCastException);
2310
2311                                                 emit_label(cd, BRANCH_LABEL_7);
2312                                                 emit_label(cd, BRANCH_LABEL_6);
2313                                                 /* reload s1, might have been destroyed */
2314                                                 emit_load_s1(jd, iptr, REG_ITMP1);
2315                                         }
2316                                         else {
2317                                                 M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
2318                                                 M_CMP(REG_ITMP2, REG_ITMP3);
2319                                                 emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP2, s1);
2320                                         }
2321
2322                                         if (super != NULL)
2323                                                 emit_label(cd, BRANCH_LABEL_5);
2324                                 }
2325
2326                                 if (super == NULL) {
2327                                         emit_label(cd, BRANCH_LABEL_1);
2328                                         emit_label(cd, BRANCH_LABEL_4);
2329                                 }
2330                                 d = codegen_reg_of_dst(jd, iptr, s1);
2331
2332                         } else {
2333                                 /* array type cast-check */
2334
2335                                 s1 = emit_load_s1(jd, iptr, REG_A0);
2336                                 M_INTMOVE(s1, REG_A0);
2337
2338
2339                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2340                                         disp = dseg_add_unique_address(cd, NULL);
2341                                         patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2342                                                                                 iptr->sx.s23.s3.c.ref,
2343                                                                                 disp);
2344                                 } else {
2345                                         disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2346                                 }
2347
2348                                 M_ALD(REG_A1, REG_PV, disp);
2349                                 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2350                                 M_ALD(REG_ITMP2, REG_PV, disp);
2351                                 M_ALD(REG_ITMP2, REG_ITMP2, 0); /* TOC */
2352                                 M_MTCTR(REG_ITMP2);
2353                                 M_JSR;
2354                                 M_TST(REG_RESULT);
2355                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2356                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2357
2358                                 d = codegen_reg_of_dst(jd, iptr, s1);
2359                         }
2360                         M_INTMOVE(s1, d);
2361                         emit_store_dst(jd, iptr, d);
2362                         break;
2363
2364
2365                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
2366                                       /* val.a: (classinfo*) superclass               */
2367
2368                         /*  superclass is an interface:
2369                          *
2370                          *  return (sub != NULL) &&
2371                          *         (sub->vftbl->interfacetablelength > super->index) &&
2372                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
2373                          *
2374                          *  superclass is a class:
2375                          *
2376                          *  return ((sub != NULL) && (0
2377                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2378                          *          super->vftbl->diffvall));
2379                          */
2380
2381                         {
2382                         classinfo *super;
2383                         s4         superindex;
2384
2385                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2386                                 super      = NULL;
2387                                 superindex = 0;
2388                         }
2389                         else {
2390                                 super      = iptr->sx.s23.s3.c.cls;
2391                                 superindex = super->index;
2392                         }
2393                         
2394                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2395                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2396                         if (s1 == d) {
2397                                 M_MOV(s1, REG_ITMP1);
2398                                 s1 = REG_ITMP1;
2399                         }
2400
2401                         /* if class is not resolved, check which code to call */
2402
2403                         if (super == NULL) {
2404                                 M_TST(s1);
2405                                 M_CLR(d);
2406                                 emit_label_beq(cd, BRANCH_LABEL_1);
2407                                 disp = dseg_add_unique_s4(cd, 0);                     /* super->flags */
2408
2409                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2410                                                                         iptr->sx.s23.s3.c.ref, disp);
2411
2412                                 M_ILD(REG_ITMP3, REG_PV, disp);
2413                                 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2414                                 emit_label_beq(cd, BRANCH_LABEL_2);
2415                         }
2416
2417                         /* interface instanceof code */
2418
2419                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2420                                 if (super == NULL) {
2421                                         /* If d == REG_ITMP2, then it's destroyed in check
2422                                            code above. */
2423                                         if (d == REG_ITMP2)
2424                                                 M_CLR(d);
2425
2426                                         patcher_add_patch_ref(jd,
2427                                                                                 PATCHER_instanceof_interface,
2428                                                                                 iptr->sx.s23.s3.c.ref, 0);
2429
2430                                 } else {
2431                                         M_TST(s1);
2432                                         M_CLR(d);
2433                                         emit_label_beq(cd, BRANCH_LABEL_3);
2434                                 }
2435
2436                                 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2437                                 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2438                                 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
2439                                 M_BLE(3);
2440                                 M_ALD(REG_ITMP1, REG_ITMP1,
2441                                           OFFSET(vftbl_t, interfacetable[0]) -
2442                                           superindex * sizeof(methodptr*));
2443                                 /* This seems to be the canonical sequence to emulate
2444                                  * the Alpha instruction M_CMPULT(zero,x) (check for non-null). */
2445                                 M_ADDIC(REG_ITMP1, -1, d);
2446                                 M_SUBE(REG_ITMP1, d, d);
2447
2448                                 if (super == NULL)      {
2449                                         emit_label_br(cd, BRANCH_LABEL_4);
2450                                 } else  {
2451                                         emit_label(cd, BRANCH_LABEL_3);
2452                                 }
2453                         }
2454
2455                         /* class instanceof code */
2456
2457                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2458
2459                                 if (super == NULL) {
2460                                         emit_label(cd, BRANCH_LABEL_2);
2461
2462                                         disp = dseg_add_unique_address(cd, NULL);
2463                                         patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2464                                                                                 iptr->sx.s23.s3.c.ref,
2465                                                                                 disp);
2466
2467                                 } else {
2468                                         disp = dseg_add_address(cd, super->vftbl);
2469
2470                                         M_TST(s1);
2471                                         M_CLR(d);
2472                                         emit_label_beq(cd, BRANCH_LABEL_5);
2473                                 }
2474
2475                                 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2476                                 M_ALD(REG_ITMP3, REG_PV, disp);
2477
2478                                 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2479                                         M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2480                                         M_LADD(REG_ITMP1, REG_ITMP2, REG_ITMP1);
2481                                         M_ALD(REG_ITMP1, REG_ITMP1, 0);
2482                                         M_CMP(REG_ITMP1, REG_ITMP3);
2483                                         emit_label_bne(cd, BRANCH_LABEL_8);
2484                                         ICONST(d, 1);
2485                                         emit_label_br(cd, BRANCH_LABEL_6);  /* true */
2486                                         emit_label(cd, BRANCH_LABEL_8);
2487
2488                                         if (super == NULL) {
2489                                                 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2490                                                 M_CMPI(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]));
2491                                                 emit_label_bne(cd, BRANCH_LABEL_10);  /* false */
2492                                         }
2493
2494                                         M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2495
2496                                         M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
2497                                         M_CMP(REG_ITMP1, REG_ITMP3);
2498                                         emit_label_bgt(cd, BRANCH_LABEL_9);  /* false */
2499                                         /* reload */
2500                                         M_ALD(REG_ITMP3, REG_PV, disp);
2501                                         M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2502
2503                                         M_SLL_IMM(REG_ITMP1, 3, REG_ITMP1);
2504                                         M_IADD_IMM(REG_ITMP2, -DISPLAY_SIZE*8, REG_ITMP2);
2505                                         M_ALDX(REG_ITMP1, REG_ITMP2, REG_ITMP1);
2506                                         /* This seems to be the canonical sequence to emulate
2507                                          * the Alpha instruction M_CMPEQ. */
2508                                         M_XOR(REG_ITMP1, REG_ITMP3, d);
2509                                         M_CNTLZ(d, d);
2510                                         M_RLDICL(d, 58, 6, d);
2511
2512                                         if (d == REG_ITMP2)
2513                                                 emit_label_br(cd, BRANCH_LABEL_7);
2514                                         emit_label(cd, BRANCH_LABEL_9);
2515                                         if (super == NULL)
2516                                                 emit_label(cd, BRANCH_LABEL_10);
2517                                         if (d == REG_ITMP2) {
2518                                                 M_CLR(d);
2519
2520                                                 emit_label(cd, BRANCH_LABEL_7);
2521                                         }
2522                                         emit_label(cd, BRANCH_LABEL_6);
2523                                 }
2524                                 else {
2525                                         M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
2526                                         M_XOR(REG_ITMP2, REG_ITMP3, d);
2527                                         M_CNTLZ(d, d);
2528                                         M_RLDICL(d, 58, 6, d);
2529                                 }
2530
2531                                 if (super != NULL)
2532                                         emit_label(cd, BRANCH_LABEL_5);
2533                         }
2534
2535                         if (super == NULL) {
2536                                 emit_label(cd, BRANCH_LABEL_1);
2537                                 emit_label(cd, BRANCH_LABEL_4);
2538                         }
2539
2540                         emit_store_dst(jd, iptr, d);
2541                         }
2542                         break;
2543
2544                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
2545
2546                         /* check for negative sizes and copy sizes to stack if necessary  */
2547
2548                         MCODECHECK((iptr->s1.argcount << 2) + 128);
2549
2550                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2551
2552                                 var = VAR(iptr->sx.s23.s2.args[s1]);
2553
2554                                 /* copy SAVEDVAR sizes to stack */
2555
2556                                 if (!(var->flags & PREALLOC)) {
2557                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
2558 #if defined(__DARWIN__)
2559                                         M_LST(s2, REG_SP, LA_SIZE + (s1 + INT_ARG_CNT) * 8);
2560 #else
2561                                         M_LST(s2, REG_SP, LA_SIZE + (s1 + 3) * 8);
2562 #endif
2563                                 }
2564                         }
2565
2566                         /* a0 = dimension count */
2567
2568                         ICONST(REG_A0, iptr->s1.argcount);
2569
2570                         /* is patcher function set? */
2571
2572                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2573                                 disp = dseg_add_unique_address(cd, NULL);
2574
2575                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2576                                                                         iptr->sx.s23.s3.c.ref, disp);
2577                         } else {
2578                                 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2579                         }
2580
2581                         /* a1 = arraydescriptor */
2582
2583                         M_ALD(REG_A1, REG_PV, disp);
2584
2585                         /* a2 = pointer to dimensions = stack pointer */
2586
2587 #if defined(__DARWIN__)
2588                         M_LDA(REG_A2, REG_SP, LA_SIZE + INT_ARG_CNT * 8);
2589 #else
2590                         M_LDA(REG_A2, REG_SP, LA_SIZE + 3 * 8);
2591 #endif
2592
2593                         disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2594                         M_ALD(REG_ITMP3, REG_PV, disp);
2595                         M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
2596                         M_MTCTR(REG_ITMP3);
2597                         M_JSR;
2598
2599                         /* check for exception before result assignment */
2600                         emit_exception_check(cd, iptr);
2601
2602                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2603                         M_INTMOVE(REG_RESULT, d);
2604                         emit_store_dst(jd, iptr, d);
2605                         break;
2606
2607                 default:
2608                         exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2609                                                                                    iptr->opc);
2610                         return false;
2611         } /* switch */
2612                 
2613         } /* for instruction */
2614                 
2615         } /* if (bptr -> flags >= BBREACHED) */
2616         } /* for basic block */
2617
2618         /* generate traps */
2619
2620         emit_patcher_traps(jd);
2621
2622         /* everything's ok */
2623
2624         return true;
2625 }
2626
2627
2628 /* codegen_emit_stub_native ****************************************************
2629
2630    Emits a stub routine which calls a native method.
2631
2632 *******************************************************************************/
2633
2634 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2635 {
2636         methodinfo  *m;
2637         codeinfo    *code;
2638         codegendata *cd;
2639         methoddesc  *md;
2640         s4           i, j;
2641         s4           t;
2642         int          s1, s2;
2643         int          disp;
2644
2645         /* get required compiler data */
2646
2647         m    = jd->m;
2648         code = jd->code;
2649         cd   = jd->cd;
2650
2651         /* Sanity check. */
2652
2653         assert(!code_is_leafmethod(code));
2654
2655         /* set some variables */
2656
2657         md = m->parseddesc;
2658
2659         /* calculate stackframe size */
2660
2661         cd->stackframesize =
2662                 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2663                 sizeof(localref_table) / SIZEOF_VOID_P +
2664                 4 +                            /* 4 stackframeinfo arguments (darwin)*/
2665                 nmd->paramcount  + 
2666                 nmd->memuse;
2667
2668 /*      cd->stackframesize = (cd->stackframesize + 3) & ~3;*/ /* keep stack 16-byte aligned */
2669
2670         /* create method header */
2671
2672         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
2673         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
2674         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
2675         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
2676         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
2677
2678         /* generate code */
2679
2680         M_MFLR(REG_ZERO);
2681         M_AST_INTERN(REG_ZERO, REG_SP, LA_LR_OFFSET);
2682         M_STDU(REG_SP, REG_SP, -(cd->stackframesize * 8));
2683
2684         /* save integer and float argument registers */
2685
2686         for (i = 0; i < md->paramcount; i++) {
2687                 if (!md->params[i].inmemory) {
2688                         s1 = md->params[i].regoff;
2689
2690                         switch (md->paramtypes[i].type) {
2691                         case TYPE_INT:
2692                         case TYPE_LNG:
2693                         case TYPE_ADR:
2694                                 M_LST(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + i * 8);
2695                                 break;
2696                         case TYPE_FLT:
2697                         case TYPE_DBL:
2698                                 M_DST(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + i * 8);
2699                                 break;
2700                         }
2701                 }
2702         }
2703
2704         /* create native stack info */
2705
2706         M_MOV(REG_SP, REG_A0);
2707         M_MOV(REG_PV, REG_A1);
2708         disp = dseg_add_functionptr(cd, codegen_start_native_call);
2709         M_ALD(REG_ITMP1, REG_PV, disp);
2710         M_ALD(REG_ITMP1, REG_ITMP1, 0);         /* TOC */
2711         M_MTCTR(REG_ITMP1);
2712         M_JSR;
2713
2714         /* remember class argument */
2715
2716         if (m->flags & ACC_STATIC)
2717                 M_MOV(REG_RESULT, REG_ITMP3);
2718
2719         /* restore integer and float argument registers */
2720
2721         for (i = 0; i < md->paramcount; i++) {
2722                 if (!md->params[i].inmemory) {
2723                         s1 = md->params[i].regoff;
2724
2725                         switch (md->paramtypes[i].type) {
2726                         case TYPE_INT:
2727                         case TYPE_LNG:
2728                         case TYPE_ADR:
2729                                 M_LLD(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + i * 8);
2730                                 break;
2731                         case TYPE_FLT:
2732                         case TYPE_DBL:
2733                                 M_DLD(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + i * 8);
2734                                 break;
2735                         }
2736                 }
2737         }
2738         
2739         /* copy or spill arguments to new locations */
2740
2741         for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
2742                 t = md->paramtypes[i].type;
2743
2744                 if (IS_INT_LNG_TYPE(t)) {
2745                         if (!md->params[i].inmemory) {
2746                                 s1 = md->params[i].regoff;
2747                                 s2 = nmd->params[j].regoff;
2748
2749                                 if (!nmd->params[j].inmemory)
2750                                         M_INTMOVE(s1, s2);
2751                                 else
2752                                         M_LST(s1, REG_SP, s2);
2753                         }
2754                         else {
2755                                 s1 = md->params[i].regoff + cd->stackframesize * 8;
2756                                 s2 = nmd->params[j].regoff;
2757
2758                                 M_LLD(REG_ITMP1, REG_SP, s1);
2759                                 M_LST(REG_ITMP1, REG_SP, s2);
2760                         }
2761                 }
2762                 else {
2763                         /* We only copy spilled float arguments, as the float
2764                            argument registers keep unchanged. */
2765
2766                         if (md->params[i].inmemory) {
2767                                 s1 = md->params[i].regoff + cd->stackframesize * 8;
2768                                 s2 = nmd->params[j].regoff;
2769
2770                                 M_DLD(REG_FTMP1, REG_SP, s1);
2771
2772                                 if (IS_2_WORD_TYPE(t))
2773                                         M_DST(REG_FTMP1, REG_SP, s2);
2774                                 else
2775                                         M_FST(REG_FTMP1, REG_SP, s2 + 4);
2776                         }
2777                 }
2778         }
2779
2780         /* Handle native Java methods. */
2781
2782         if (m->flags & ACC_NATIVE) {
2783                 /* put class into second argument register */
2784
2785                 if (m->flags & ACC_STATIC)
2786                         M_MOV(REG_ITMP3, REG_A1);
2787
2788                 /* put env into first argument register */
2789
2790                 disp = dseg_add_unique_address(cd, VM_get_jnienv());
2791                 M_ALD(REG_A0, REG_PV, disp);
2792         }
2793
2794         /* Call the native function. */
2795         /* native functions have a different TOC for sure */
2796
2797         M_AST(REG_TOC, REG_SP, 40);     /* save old TOC */
2798         disp = dseg_add_functionptr(cd, f);
2799         M_ALD(REG_ITMP3, REG_PV, disp);
2800         M_ALD(REG_TOC, REG_ITMP3, 8);   /* load TOC from func. descriptor */
2801         M_ALD(REG_ITMP3, REG_ITMP3, 0);         
2802         M_MTCTR(REG_ITMP3);
2803         M_JSR;
2804         M_ALD(REG_TOC, REG_SP, 40);     /* restore TOC */
2805
2806         /* save return value */
2807
2808         if (md->returntype.type != TYPE_VOID) {
2809                 if (IS_INT_LNG_TYPE(md->returntype.type)) {
2810                         M_LST(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 2 * 8);
2811                 }
2812                 else {
2813                         M_DST(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 2 * 8);
2814                 }
2815         }
2816
2817         /* remove native stackframe info */
2818
2819         M_MOV(REG_SP, REG_A0);
2820         M_MOV(REG_PV, REG_A1);
2821         disp = dseg_add_functionptr(cd, codegen_finish_native_call);
2822         M_ALD(REG_ITMP1, REG_PV, disp);
2823         M_ALD(REG_ITMP1, REG_ITMP1, 0); /* XXX what about TOC? */
2824         M_MTCTR(REG_ITMP1);
2825         M_JSR;
2826         M_MOV(REG_RESULT, REG_ITMP1_XPTR);
2827
2828         /* restore return value */
2829
2830         if (md->returntype.type != TYPE_VOID) {
2831                 if (IS_INT_LNG_TYPE(md->returntype.type)) {
2832                         M_LLD(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 2 * 8);
2833                 }
2834                 else {
2835                         M_DLD(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 2 * 8);
2836                 }
2837         }
2838
2839         M_ALD(REG_ITMP2_XPC, REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET);
2840         M_MTLR(REG_ITMP2_XPC);
2841         M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* remove stackframe           */
2842
2843         /* check for exception */
2844
2845         M_TST(REG_ITMP1_XPTR);
2846         M_BNE(1);                           /* if no exception then return        */
2847
2848         M_RET;
2849
2850         /* handle exception */
2851
2852         M_LADD_IMM(REG_ITMP2_XPC, -4, REG_ITMP2_XPC);  /* exception address       */
2853
2854         disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
2855         M_ALD(REG_ITMP3, REG_PV, disp);
2856         M_MTCTR(REG_ITMP3);
2857         M_RTS;
2858 }
2859
2860
2861 /*
2862  * These are local overrides for various environment variables in Emacs.
2863  * Please do not remove this and leave it at the end of the file, where
2864  * Emacs will automagically detect them.
2865  * ---------------------------------------------------------------------
2866  * Local variables:
2867  * mode: c
2868  * indent-tabs-mode: t
2869  * c-basic-offset: 4
2870  * tab-width: 4
2871  * End:
2872  * vim:noexpandtab:sw=4:ts=4:
2873  */