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