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