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