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