* src/threads/native/lock.h, src/threads/native/lock.c: Tasuki lock
[cacao.git] / src / vm / jit / mips / codegen.c
1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Andreas Krall
28             Reinhard Grafl
29
30    Changes: Christian Thalinger
31             Christian Ullrich
32             Edwin Steiner
33
34    Contains the codegenerator for an MIPS (R4000 or higher) processor.
35    This module generates MIPS machine code for a sequence of
36    intermediate code commands (ICMDs).
37
38    $Id: codegen.c 4937 2006-05-18 14:33:32Z edwin $
39
40 */
41
42
43 #include "config.h"
44
45 #include <assert.h>
46 #include <stdio.h>
47
48 #include "vm/types.h"
49
50 #include "md.h"
51 #include "md-abi.h"
52
53 #include "vm/jit/mips/arch.h"
54 #include "vm/jit/mips/codegen.h"
55
56 #include "native/native.h"
57 #include "vm/builtin.h"
58 #include "vm/class.h"
59 #include "vm/exceptions.h"
60 #include "vm/options.h"
61 #include "vm/stringlocal.h"
62 #include "vm/vm.h"
63 #include "vm/jit/asmpart.h"
64 #include "vm/jit/codegen-common.h"
65 #include "vm/jit/dseg.h"
66 #include "vm/jit/emit.h"
67 #include "vm/jit/jit.h"
68 #include "vm/jit/patcher.h"
69 #include "vm/jit/reg.h"
70 #include "vm/jit/replace.h"
71
72 #if defined(ENABLE_LSRA)
73 # include "vm/jit/allocator/lsra.h"
74 #endif
75
76
77 /* codegen *********************************************************************
78
79    Generates machine code.
80
81 *******************************************************************************/
82
83 bool codegen(jitdata *jd)
84 {
85         methodinfo         *m;
86         codegendata        *cd;
87         registerdata       *rd;
88         s4                  len, s1, s2, s3, d, disp;
89         ptrint              a;
90         s4                  parentargs_base;
91         stackptr            src;
92         varinfo            *var;
93         basicblock         *bptr;
94         instruction        *iptr;
95         exceptiontable     *ex;
96         u2                  currentline;
97         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
98         builtintable_entry *bte;
99         methoddesc         *md;
100         rplpoint           *replacementpoint;
101
102         /* get required compiler data */
103
104         m  = jd->m;
105         cd = jd->cd;
106         rd = jd->rd;
107
108         {
109         s4 i, p, t, l;
110         s4 savedregs_num;
111
112         savedregs_num = (m->isleafmethod) ? 0 : 1;        /* space to save the RA */
113
114         /* space to save used callee saved registers */
115
116         savedregs_num += (INT_SAV_CNT - rd->savintreguse);
117         savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
118
119         parentargs_base = rd->memuse + savedregs_num;
120
121 #if defined(ENABLE_THREADS)
122         /* space to save argument of monitor_enter */
123
124         if (checksync && (m->flags & ACC_SYNCHRONIZED))
125                 parentargs_base++;
126 #endif
127
128         /* adjust frame size for 16 byte alignment */
129
130         if (parentargs_base & 1)
131                 parentargs_base++;
132
133         /* create method header */
134
135 #if SIZEOF_VOID_P == 4
136         (void) dseg_addaddress(cd, m);                          /* Filler         */
137 #endif
138         (void) dseg_addaddress(cd, m);                          /* MethodPointer  */
139         (void) dseg_adds4(cd, parentargs_base * 8);             /* FrameSize      */
140
141 #if defined(ENABLE_THREADS)
142         /* IsSync contains the offset relative to the stack pointer for the
143            argument of monitor_exit used in the exception handler. Since the
144            offset could be zero and give a wrong meaning of the flag it is
145            offset by one.
146         */
147
148         if (checksync && (m->flags & ACC_SYNCHRONIZED))
149                 (void) dseg_adds4(cd, (rd->memuse + 1) * 8);        /* IsSync         */
150         else
151 #endif
152                 (void) dseg_adds4(cd, 0);                           /* IsSync         */
153                                                
154         (void) dseg_adds4(cd, m->isleafmethod);                 /* IsLeaf         */
155         (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse);  /* IntSave        */
156         (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse);  /* FltSave        */
157         dseg_addlinenumbertablesize(cd);
158         (void) dseg_adds4(cd, cd->exceptiontablelength);        /* ExTableSize    */
159
160         /* create exception table */
161
162         for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
163                 dseg_addtarget(cd, ex->start);
164                 dseg_addtarget(cd, ex->end);
165                 dseg_addtarget(cd, ex->handler);
166                 (void) dseg_addaddress(cd, ex->catchtype.cls);
167         }
168         
169         /* create stack frame (if necessary) */
170
171         if (parentargs_base)
172                 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
173
174         /* save return address and used callee saved registers */
175
176         p = parentargs_base;
177         if (!m->isleafmethod) {
178                 p--; M_AST(REG_RA, REG_SP, p * 8);
179         }
180         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
181                 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
182         }
183         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
184                 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
185         }
186
187         /* take arguments out of register or stack frame */
188
189         md = m->parseddesc;
190
191         for (p = 0, l = 0; p < md->paramcount; p++) {
192                 t = md->paramtypes[p].type;
193                 var = &(rd->locals[l][t]);
194                 l++;
195                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
196                         l++;
197                 if (var->type < 0)
198                         continue;
199                 s1 = md->params[p].regoff;
200                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
201                         if (!md->params[p].inmemory) {           /* register arguments    */
202                                 s2 = rd->argintregs[s1];
203                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
204                                         M_INTMOVE(s2, var->regoff);
205                                 } else {                             /* reg arg -> spilled    */
206                                         M_LST(s2, REG_SP, var->regoff * 8);
207                                 }
208
209                         } else {                                 /* stack arguments       */
210                                 if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
211                                         M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
212                                 } else {                             /* stack arg -> spilled  */
213                                         var->regoff = parentargs_base + s1;
214                                 }
215                         }
216
217                 } else {                                     /* floating args         */
218                         if (!md->params[p].inmemory) {           /* register arguments    */
219                                 s2 = rd->argfltregs[s1];
220                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
221                                         if (IS_2_WORD_TYPE(t))
222                                                 M_DMOV(s2, var->regoff);
223                                         else
224                                                 M_FMOV(s2, var->regoff);
225                                 } else {                                         /* reg arg -> spilled    */
226                                         if (IS_2_WORD_TYPE(t))
227                                                 M_DST(s2, REG_SP, var->regoff * 8);
228                                         else
229                                                 M_FST(s2, REG_SP, var->regoff * 8);
230                                 }
231
232                         } else {                                 /* stack arguments       */
233                                 if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
234                                         if (IS_2_WORD_TYPE(t))
235                                                 M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
236                                         else
237                                                 M_FLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
238                                 } else                               /* stack-arg -> spilled  */
239                                         var->regoff = parentargs_base + s1;
240                         }
241                 }
242         } /* end for */
243
244         /* call monitorenter function */
245
246 #if defined(ENABLE_THREADS)
247         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
248                 /* stack offset for monitor argument */
249
250                 s1 = rd->memuse;
251
252                 if (opt_verbosecall) {
253                         M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
254
255                         for (p = 0; p < INT_ARG_CNT; p++)
256                                 M_LST(rd->argintregs[p], REG_SP, p * 8);
257
258                         for (p = 0; p < FLT_ARG_CNT; p++)
259                                 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
260
261                         s1 += INT_ARG_CNT + FLT_ARG_CNT;
262                 }
263
264                 /* decide which monitor enter function to call */
265
266                 if (m->flags & ACC_STATIC) {
267                         p = dseg_addaddress(cd, m->class);
268                         M_ALD(rd->argintregs[0], REG_PV, p);
269                         p = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
270                         M_ALD(REG_ITMP3, REG_PV, p);
271                         M_JSR(REG_RA, REG_ITMP3);
272                         M_AST(rd->argintregs[0], REG_SP, s1 * 8);         /* branch delay */
273
274                 } else {
275                         M_BEQZ(rd->argintregs[0], 0);
276                         codegen_add_nullpointerexception_ref(cd);
277                         p = dseg_addaddress(cd, BUILTIN_monitorenter);
278                         M_ALD(REG_ITMP3, REG_PV, p);
279                         M_JSR(REG_RA, REG_ITMP3);
280                         M_AST(rd->argintregs[0], REG_SP, s1 * 8);         /* branch delay */
281                 }
282
283                 if (opt_verbosecall) {
284                         for (p = 0; p < INT_ARG_CNT; p++)
285                                 M_LLD(rd->argintregs[p], REG_SP, p * 8);
286
287                         for (p = 0; p < FLT_ARG_CNT; p++)
288                                 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
289
290
291                         M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
292                 }
293         }
294 #endif
295
296         /* copy argument registers to stack and call trace function */
297
298         if (opt_verbosecall) {
299                 M_LDA(REG_SP, REG_SP, -(2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
300                 M_AST(REG_RA, REG_SP, 1 * 8);
301
302                 /* save integer argument registers */
303
304                 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
305                         M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
306
307                 /* save and copy float arguments into integer registers */
308
309                 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
310                         t = md->paramtypes[p].type;
311
312                         if (IS_FLT_DBL_TYPE(t)) {
313                                 if (IS_2_WORD_TYPE(t)) {
314                                         M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
315                                         M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
316
317                                 } else {
318                                         M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
319                                         M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
320                                 }
321
322                         } else {
323                                 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
324                         }
325                 }
326
327                 /* save temporary registers for leaf methods */
328
329                 if (m->isleafmethod) {
330                         for (p = 0; p < INT_TMP_CNT; p++)
331                                 M_LST(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
332
333                         for (p = 0; p < FLT_TMP_CNT; p++)
334                                 M_DST(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
335                 }
336
337                 p = dseg_addaddress(cd, m);
338                 M_ALD(REG_ITMP1, REG_PV, p);
339                 M_AST(REG_ITMP1, REG_SP, 0 * 8);
340                 disp = dseg_addaddress(cd, (void *) builtin_trace_args);
341                 M_ALD(REG_ITMP3, REG_PV, disp);
342                 M_JSR(REG_RA, REG_ITMP3);
343                 M_NOP;
344
345                 M_ALD(REG_RA, REG_SP, 1 * 8);
346
347                 /* restore integer argument registers */
348
349                 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
350                         M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
351
352                 /* restore float argument registers */
353
354                 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
355                         t = md->paramtypes[p].type;
356
357                         if (IS_FLT_DBL_TYPE(t)) {
358                                 if (IS_2_WORD_TYPE(t)) {
359                                         M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
360
361                                 } else {
362                                         M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
363                                 }
364
365                         } else {
366                                 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
367                         }
368                 }
369
370                 /* restore temporary registers for leaf methods */
371
372                 if (m->isleafmethod) {
373                         for (p = 0; p < INT_TMP_CNT; p++)
374                                 M_LLD(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
375
376                         for (p = 0; p < FLT_TMP_CNT; p++)
377                                 M_DLD(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
378                 }
379
380                 M_LDA(REG_SP, REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
381         }
382
383         }
384
385         /* end of header generation */
386
387         replacementpoint = jd->code->rplpoints;
388
389         /* walk through all basic blocks */
390
391         for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
392
393                 /* handle replacement points */
394
395                 if (bptr->bitflags & BBFLAG_REPLACEMENT && bptr->flags >= BBREACHED) {
396
397                         /* 8-byte align pc */
398                         if ((ptrint) cd->mcodeptr & 4) {
399                                 M_NOP;
400                         }
401                         
402                         replacementpoint->pc = (u1*)(ptrint) (cd->mcodeptr - cd->mcodebase);
403                         replacementpoint++;
404
405                         assert(cd->lastmcodeptr <= cd->mcodeptr);
406                         cd->lastmcodeptr = cd->mcodeptr + 2 * 4;       /* br + delay slot */
407                 }
408
409                 /* store relative start of block */
410
411                 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
412
413                 if (bptr->flags >= BBREACHED) {
414
415                         /* branch resolving */
416                         {
417                                 branchref *bref;
418                                 for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
419                                         gen_resolvebranch(cd->mcodebase + bref->branchpos, 
420                                                                           bref->branchpos,
421                                                                           bptr->mpc);
422                                 }
423                         }
424
425                 /* copy interface registers to their destination */
426
427                 src = bptr->instack;
428                 len = bptr->indepth;
429                 MCODECHECK(64+len);
430 #if defined(ENABLE_LSRA)
431                 if (opt_lsra) {
432                 while (src != NULL) {
433                         len--;
434                         if ((len == 0) && (bptr->type != BBTYPE_STD)) {
435                                         /*                              d = reg_of_var(m, src, REG_ITMP1); */
436                                         if (!(src->flags & INMEMORY))
437                                                 d= src->regoff;
438                                         else
439                                                 d=REG_ITMP1;
440                                         M_INTMOVE(REG_ITMP1, d);
441                                         emit_store(jd, NULL, src, d);
442                                 }
443                                 src = src->prev;
444                         }
445                 } else {
446 #endif
447                 while (src != NULL) {
448                         len--;
449                         if ((len == 0) && (bptr->type != BBTYPE_STD)) {
450                                 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
451                                 M_INTMOVE(REG_ITMP1, d);
452                                 emit_store(jd, NULL, src, d);
453
454                         } else {
455                                 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
456                                 if ((src->varkind != STACKVAR)) {
457                                         s2 = src->type;
458                                         s1 = rd->interfaces[len][s2].regoff;
459                                         if (IS_FLT_DBL_TYPE(s2)) {
460                                                 if (rd->interfaces[len][s2].flags & INMEMORY) {
461                                                         if (IS_2_WORD_TYPE(s2))
462                                                                 M_DLD(d, REG_SP, s1 * 8);
463                                                         else
464                                                                 M_FLD(d, REG_SP, s1 * 8);
465
466                                                 } else {
467                                                         if (IS_2_WORD_TYPE(s2))
468                                                                 M_DMOV(s1, d);
469                                                         else
470                                                                 M_FMOV(s1, d);
471                                                 }
472
473                                         } else {
474                                                 if (rd->interfaces[len][s2].flags & INMEMORY)
475                                                         M_LLD(d, REG_SP, s1 * 8);
476                                                 else
477                                                         M_INTMOVE(s1,d);
478                                         }
479
480                                         emit_store(jd, NULL, src, d);
481                                 }
482                         }
483                         src = src->prev;
484                 }
485 #if defined(ENABLE_LSRA)
486                 }
487 #endif
488                 /* walk through all instructions */
489                 
490                 src = bptr->instack;
491                 len = bptr->icount;
492                 currentline = 0;
493
494                 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
495                         if (iptr->line != currentline) {
496                                 dseg_addlinenumber(cd, iptr->line);
497                                 currentline = iptr->line;
498                         }
499
500                         MCODECHECK(64);   /* an instruction usually needs < 64 words      */
501
502                         switch (iptr->opc) {
503
504                 case ICMD_NOP:        /* ...  ==> ...                                 */
505                         break;
506
507                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
508
509                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
510                         M_BEQZ(s1, 0);
511                         codegen_add_nullpointerexception_ref(cd);
512                         M_NOP;
513                         break;
514
515                 /* constant operations ************************************************/
516
517                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
518                                       /* op1 = 0, val.i = constant                    */
519
520                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
521                         ICONST(d, iptr->val.i);
522                         emit_store(jd, iptr, iptr->dst, d);
523                         break;
524
525                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
526                                       /* op1 = 0, val.l = constant                    */
527
528                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
529                         LCONST(d, iptr->val.l);
530                         emit_store(jd, iptr, iptr->dst, d);
531                         break;
532
533                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
534                                       /* op1 = 0, val.f = constant                    */
535
536                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
537                         disp = dseg_addfloat(cd, iptr->val.f);
538                         M_FLD(d, REG_PV, disp);
539                         emit_store(jd, iptr, iptr->dst, d);
540                         break;
541                         
542                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
543                                       /* op1 = 0, val.d = constant                    */
544
545                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
546                         disp = dseg_adddouble(cd, iptr->val.d);
547                         M_DLD(d, REG_PV, disp);
548                         emit_store(jd, iptr, iptr->dst, d);
549                         break;
550
551                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
552                                       /* op1 = 0, val.a = constant                    */
553
554                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
555
556                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
557                                 disp = dseg_addaddress(cd, NULL);
558
559                                 codegen_addpatchref(cd, PATCHER_aconst,
560                                                                         ICMD_ACONST_UNRESOLVED_CLASSREF(iptr),
561                                                                     disp);
562
563                                 if (opt_showdisassemble) {
564                                         M_NOP; M_NOP;
565                                 }
566
567                                 M_ALD(d, REG_PV, disp);
568
569                         } else {
570                                 if (iptr->val.a == NULL) {
571                                         M_INTMOVE(REG_ZERO, d);
572                                 } else {
573                                         disp = dseg_addaddress(cd, iptr->val.a);
574                                         M_ALD(d, REG_PV, disp);
575                                 }
576                         }
577                         emit_store(jd, iptr, iptr->dst, d);
578                         break;
579
580
581                 /* load/store operations **********************************************/
582
583                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
584                                       /* op1 = local variable                         */
585
586                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
587                         if ((iptr->dst->varkind == LOCALVAR) &&
588                             (iptr->dst->varnum == iptr->op1))
589                                 break;
590                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
591                         if (var->flags & INMEMORY)
592 #if SIZEOF_VOID_P == 8
593                                 M_LLD(d, REG_SP, var->regoff * 8);
594 #else
595                                 M_ILD(d, REG_SP, var->regoff * 8);
596 #endif
597                         else
598                                 M_INTMOVE(var->regoff,d);
599                         emit_store(jd, iptr, iptr->dst, d);
600                         break;
601
602                 case ICMD_LLOAD:      /* ...  ==> ..., content of local variable      */
603                                       /* op1 = local variable                         */
604
605                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
606                         if ((iptr->dst->varkind == LOCALVAR) &&
607                             (iptr->dst->varnum == iptr->op1))
608                                 break;
609                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
610                         if (var->flags & INMEMORY)
611                                 M_LLD(d, REG_SP, var->regoff * 8);
612                         else
613                                 M_INTMOVE(var->regoff,d);
614                         emit_store(jd, iptr, iptr->dst, d);
615                         break;
616
617                 case ICMD_ALOAD:      /* ...  ==> ..., content of local variable      */
618                                       /* op1 = local variable                         */
619
620                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
621                         if ((iptr->dst->varkind == LOCALVAR) &&
622                             (iptr->dst->varnum == iptr->op1))
623                                 break;
624                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
625                         if (var->flags & INMEMORY)
626                                 M_ALD(d, REG_SP, var->regoff * 8);
627                         else
628                                 M_INTMOVE(var->regoff,d);
629                         emit_store(jd, iptr, iptr->dst, d);
630                         break;
631
632                 case ICMD_FLOAD:      /* ...  ==> ..., content of local variable      */
633                                       /* op1 = local variable                         */
634
635                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
636                         if ((iptr->dst->varkind == LOCALVAR) &&
637                             (iptr->dst->varnum == iptr->op1))
638                                 break;
639                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
640                         if (var->flags & INMEMORY)
641                                 M_FLD(d, REG_SP, var->regoff * 8);
642                         else
643                                 M_FMOV(var->regoff, d);
644                         emit_store(jd, iptr, iptr->dst, d);
645                         break;
646
647                 case ICMD_DLOAD:      /* ...  ==> ..., content of local variable      */
648                                       /* op1 = local variable                         */
649
650                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
651                         if ((iptr->dst->varkind == LOCALVAR) &&
652                             (iptr->dst->varnum == iptr->op1))
653                                 break;
654                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
655                         if (var->flags & INMEMORY)
656                                 M_DLD(d, REG_SP, var->regoff * 8);
657                         else
658                                 M_DMOV(var->regoff, d);
659                         emit_store(jd, iptr, iptr->dst, d);
660                         break;
661
662
663                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
664                                       /* op1 = local variable                         */
665
666                         if ((src->varkind == LOCALVAR) &&
667                             (src->varnum == iptr->op1))
668                                 break;
669                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
670                         if (var->flags & INMEMORY) {
671                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
672 #if SIZEOF_VOID_P == 8
673                                 M_LST(s1, REG_SP, var->regoff * 8);
674 #else
675                                 M_IST(s1, REG_SP, var->regoff * 8);
676 #endif
677                         } else {
678                                 s1 = emit_load_s1(jd, iptr, src, var->regoff);
679                                 M_INTMOVE(s1, var->regoff);
680                         }
681                         break;
682
683                 case ICMD_LSTORE:     /* ..., value  ==> ...                          */
684                                       /* op1 = local variable                         */
685
686                         if ((src->varkind == LOCALVAR) &&
687                             (src->varnum == iptr->op1))
688                                 break;
689                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
690                         if (var->flags & INMEMORY) {
691                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
692                                 M_LST(s1, REG_SP, var->regoff * 8);
693                         } else {
694                                 s1 = emit_load_s1(jd, iptr, src, var->regoff);
695                                 M_INTMOVE(s1, var->regoff);
696                         }
697                         break;
698
699                 case ICMD_ASTORE:     /* ..., value  ==> ...                          */
700                                       /* op1 = local variable                         */
701
702                         if ((src->varkind == LOCALVAR) &&
703                             (src->varnum == iptr->op1))
704                                 break;
705                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
706                         if (var->flags & INMEMORY) {
707                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
708                                 M_AST(s1, REG_SP, var->regoff * 8);
709                         } else {
710                                 s1 = emit_load_s1(jd, iptr, src, var->regoff);
711                                 M_INTMOVE(s1, var->regoff);
712                         }
713                         break;
714
715                 case ICMD_FSTORE:     /* ..., value  ==> ...                          */
716                                       /* op1 = local variable                         */
717
718                         if ((src->varkind == LOCALVAR) &&
719                             (src->varnum == iptr->op1))
720                                 break;
721                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
722                         if (var->flags & INMEMORY) {
723                                 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
724                                 M_FST(s1, REG_SP, var->regoff * 8);
725                         } else {
726                                 s1 = emit_load_s1(jd, iptr, src, var->regoff);
727                                 M_FMOV(s1, var->regoff);
728                         }
729                         break;
730
731                 case ICMD_DSTORE:     /* ..., value  ==> ...                          */
732                                       /* op1 = local variable                         */
733
734                         if ((src->varkind == LOCALVAR) &&
735                             (src->varnum == iptr->op1))
736                                 break;
737                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
738                         if (var->flags & INMEMORY) {
739                                 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
740                                 M_DST(s1, REG_SP, var->regoff * 8);
741                         } else {
742                                 s1 = emit_load_s1(jd, iptr, src, var->regoff);
743                                 M_DMOV(s1, var->regoff);
744                         }
745                         break;
746
747
748                 /* pop/dup/swap operations ********************************************/
749
750                 /* attention: double and longs are only one entry in CACAO ICMDs      */
751
752                 case ICMD_POP:        /* ..., value  ==> ...                          */
753                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
754                         break;
755
756                 case ICMD_DUP:        /* ..., a ==> ..., a, a                         */
757                         M_COPY(src, iptr->dst);
758                         break;
759
760                 case ICMD_DUP_X1:     /* ..., a, b ==> ..., b, a, b                   */
761
762                         M_COPY(src,       iptr->dst);
763                         M_COPY(src->prev, iptr->dst->prev);
764                         M_COPY(iptr->dst, iptr->dst->prev->prev);
765                         break;
766
767                 case ICMD_DUP_X2:     /* ..., a, b, c ==> ..., c, a, b, c             */
768
769                         M_COPY(src,             iptr->dst);
770                         M_COPY(src->prev,       iptr->dst->prev);
771                         M_COPY(src->prev->prev, iptr->dst->prev->prev);
772                         M_COPY(iptr->dst,       iptr->dst->prev->prev->prev);
773                         break;
774
775                 case ICMD_DUP2:       /* ..., a, b ==> ..., a, b, a, b                */
776
777                         M_COPY(src,       iptr->dst);
778                         M_COPY(src->prev, iptr->dst->prev);
779                         break;
780
781                 case ICMD_DUP2_X1:    /* ..., a, b, c ==> ..., b, c, a, b, c          */
782
783                         M_COPY(src,             iptr->dst);
784                         M_COPY(src->prev,       iptr->dst->prev);
785                         M_COPY(src->prev->prev, iptr->dst->prev->prev);
786                         M_COPY(iptr->dst,       iptr->dst->prev->prev->prev);
787                         M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
788                         break;
789
790                 case ICMD_DUP2_X2:    /* ..., a, b, c, d ==> ..., c, d, a, b, c, d    */
791
792                         M_COPY(src,                   iptr->dst);
793                         M_COPY(src->prev,             iptr->dst->prev);
794                         M_COPY(src->prev->prev,       iptr->dst->prev->prev);
795                         M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
796                         M_COPY(iptr->dst,             iptr->dst->prev->prev->prev->prev);
797                         M_COPY(iptr->dst->prev,       iptr->dst->prev->prev->prev->prev->prev);
798                         break;
799
800                 case ICMD_SWAP:       /* ..., a, b ==> ..., b, a                      */
801
802                         M_COPY(src,       iptr->dst->prev);
803                         M_COPY(src->prev, iptr->dst);
804                         break;
805
806
807                 /* integer operations *************************************************/
808
809                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
810
811                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1); 
812                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
813                         M_ISUB(REG_ZERO, s1, d);
814                         emit_store(jd, iptr, iptr->dst, d);
815                         break;
816
817                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
818
819                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
820                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
821                         M_LSUB(REG_ZERO, s1, d);
822                         emit_store(jd, iptr, iptr->dst, d);
823                         break;
824
825                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
826
827                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
828                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
829                         M_INTMOVE(s1, d);
830                         emit_store(jd, iptr, iptr->dst, d);
831                         break;
832
833                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
834
835                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
836                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
837                         M_ISLL_IMM(s1, 0, d );
838                         emit_store(jd, iptr, iptr->dst, d);
839                         break;
840
841                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
842
843                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
844                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
845                         M_LSLL_IMM(s1, 56, d);
846                         M_LSRA_IMM( d, 56, d);
847                         emit_store(jd, iptr, iptr->dst, d);
848                         break;
849
850                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
851
852                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
853                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
854             M_CZEXT(s1, d);
855                         emit_store(jd, iptr, iptr->dst, d);
856                         break;
857
858                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
859
860                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
861                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
862                         M_LSLL_IMM(s1, 48, d);
863                         M_LSRA_IMM( d, 48, d);
864                         emit_store(jd, iptr, iptr->dst, d);
865                         break;
866
867
868                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
869
870                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
871                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
872                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
873                         M_IADD(s1, s2, d);
874                         emit_store(jd, iptr, iptr->dst, d);
875                         break;
876
877                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
878                                       /* val.i = constant                             */
879
880                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
881                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
882                         if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
883                                 M_IADD_IMM(s1, iptr->val.i, d);
884                         } else {
885                                 ICONST(REG_ITMP2, iptr->val.i);
886                                 M_IADD(s1, REG_ITMP2, d);
887                         }
888                         emit_store(jd, iptr, iptr->dst, d);
889                         break;
890
891                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
892
893                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
894                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
895                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
896                         M_LADD(s1, s2, d);
897                         emit_store(jd, iptr, iptr->dst, d);
898                         break;
899
900                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
901                                       /* val.l = constant                             */
902
903                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
904                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
905                         if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
906                                 M_LADD_IMM(s1, iptr->val.l, d);
907                         } else {
908                                 LCONST(REG_ITMP2, iptr->val.l);
909                                 M_LADD(s1, REG_ITMP2, d);
910                         }
911                         emit_store(jd, iptr, iptr->dst, d);
912                         break;
913
914                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
915
916                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
917                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
918                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
919                         M_ISUB(s1, s2, d);
920                         emit_store(jd, iptr, iptr->dst, d);
921                         break;
922
923                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
924                                       /* val.i = constant                             */
925
926                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
927                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
928                         if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
929                                 M_IADD_IMM(s1, -iptr->val.i, d);
930                         } else {
931                                 ICONST(REG_ITMP2, iptr->val.i);
932                                 M_ISUB(s1, REG_ITMP2, d);
933                         }
934                         emit_store(jd, iptr, iptr->dst, d);
935                         break;
936
937                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
938
939                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
940                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
941                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
942                         M_LSUB(s1, s2, d);
943                         emit_store(jd, iptr, iptr->dst, d);
944                         break;
945
946                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
947                                       /* val.l = constant                             */
948
949                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
950                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
951                         if ((iptr->val.l >= -32767) && (iptr->val.l <= 32768)) {
952                                 M_LADD_IMM(s1, -iptr->val.l, d);
953                         } else {
954                                 LCONST(REG_ITMP2, iptr->val.l);
955                                 M_LSUB(s1, REG_ITMP2, d);
956                         }
957                         emit_store(jd, iptr, iptr->dst, d);
958                         break;
959
960                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
961
962                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
963                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
964                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
965                         M_IMUL(s1, s2);
966                         M_MFLO(d);
967                         M_NOP;
968                         M_NOP;
969                         emit_store(jd, iptr, iptr->dst, d);
970                         break;
971
972                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
973                                       /* val.i = constant                             */
974
975                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
976                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
977                         ICONST(REG_ITMP2, iptr->val.i);
978                         M_IMUL(s1, REG_ITMP2);
979                         M_MFLO(d);
980                         M_NOP;
981                         M_NOP;
982                         emit_store(jd, iptr, iptr->dst, d);
983                         break;
984
985                 case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
986
987                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
988                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
989                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
990                         M_LMUL(s1, s2);
991                         M_MFLO(d);
992                         M_NOP;
993                         M_NOP;
994                         emit_store(jd, iptr, iptr->dst, d);
995                         break;
996
997                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
998                                       /* val.l = constant                             */
999
1000                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1001                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1002                         LCONST(REG_ITMP2, iptr->val.l);
1003                         M_LMUL(s1, REG_ITMP2);
1004                         M_MFLO(d);
1005                         M_NOP;
1006                         M_NOP;
1007                         emit_store(jd, iptr, iptr->dst, d);
1008                         break;
1009
1010                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1011
1012                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1013                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1014                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1015                         gen_div_check(s2);
1016                         M_IDIV(s1, s2);
1017                         M_MFLO(d);
1018                         M_NOP;
1019                         M_NOP;
1020                         emit_store(jd, iptr, iptr->dst, d);
1021                         break;
1022
1023                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1024
1025                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1026                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1027                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1028                         gen_div_check(s2);
1029                         M_LDIV(s1, s2);
1030                         M_MFLO(d);
1031                         M_NOP;
1032                         M_NOP;
1033                         emit_store(jd, iptr, iptr->dst, d);
1034                         break;
1035
1036                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1037
1038                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1039                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1040                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1041                         gen_div_check(s2);
1042                         M_IDIV(s1, s2);
1043                         M_MFHI(d);
1044                         M_NOP;
1045                         M_NOP;
1046                         emit_store(jd, iptr, iptr->dst, d);
1047                         break;
1048
1049                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1050
1051                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1052                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1053                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1054                         gen_div_check(s2);
1055                         M_LDIV(s1, s2);
1056                         M_MFHI(d);
1057                         M_NOP;
1058                         M_NOP;
1059                         emit_store(jd, iptr, iptr->dst, d);
1060                         break;
1061
1062                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value << constant       */
1063                 case ICMD_LDIVPOW2:   /* val.i = constant                             */
1064                                       
1065                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1066                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1067                         M_LSRA_IMM(s1, 63, REG_ITMP2);
1068                         M_LSRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1069                         M_LADD(s1, REG_ITMP2, REG_ITMP2);
1070                         M_LSRA_IMM(REG_ITMP2, iptr->val.i, d);
1071                         emit_store(jd, iptr, iptr->dst, d);
1072                         break;
1073
1074                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1075
1076                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1077                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1078                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1079                         M_ISLL(s1, s2, d);
1080                         emit_store(jd, iptr, iptr->dst, d);
1081                         break;
1082
1083                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
1084                                       /* val.i = constant                             */
1085
1086                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1087                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1088                         M_ISLL_IMM(s1, iptr->val.i, d);
1089                         emit_store(jd, iptr, iptr->dst, d);
1090                         break;
1091
1092                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1093
1094                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1095                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1096                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1097                         M_ISRA(s1, s2, d);
1098                         emit_store(jd, iptr, iptr->dst, d);
1099                         break;
1100
1101                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
1102                                       /* val.i = constant                             */
1103
1104                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1105                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1106                         M_ISRA_IMM(s1, iptr->val.i, d);
1107                         emit_store(jd, iptr, iptr->dst, d);
1108                         break;
1109
1110                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1111
1112                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1113                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1114                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1115                         M_ISRL(s1, s2, d);
1116                         emit_store(jd, iptr, iptr->dst, d);
1117                         break;
1118
1119                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1120                                       /* val.i = constant                             */
1121
1122                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1123                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1124                         M_ISRL_IMM(s1, iptr->val.i, d);
1125                         emit_store(jd, iptr, iptr->dst, d);
1126                         break;
1127
1128                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1129
1130                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1131                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1132                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1133                         M_LSLL(s1, s2, d);
1134                         emit_store(jd, iptr, iptr->dst, d);
1135                         break;
1136
1137                 case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
1138                                       /* val.i = constant                             */
1139
1140                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1141                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1142                         M_LSLL_IMM(s1, iptr->val.i, d);
1143                         emit_store(jd, iptr, iptr->dst, d);
1144                         break;
1145
1146                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1147
1148                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1149                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1150                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1151                         M_LSRA(s1, s2, d);
1152                         emit_store(jd, iptr, iptr->dst, d);
1153                         break;
1154
1155                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
1156                                       /* val.i = constant                             */
1157
1158                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1159                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1160                         M_LSRA_IMM(s1, iptr->val.i, d);
1161                         emit_store(jd, iptr, iptr->dst, d);
1162                         break;
1163
1164                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1165
1166                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1167                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1168                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1169                         M_LSRL(s1, s2, d);
1170                         emit_store(jd, iptr, iptr->dst, d);
1171                         break;
1172
1173                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1174                                       /* val.i = constant                             */
1175
1176                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1177                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1178                         M_LSRL_IMM(s1, iptr->val.i, d);
1179                         emit_store(jd, iptr, iptr->dst, d);
1180                         break;
1181
1182                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1183                 case ICMD_LAND:
1184
1185                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1186                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1187                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1188                         M_AND(s1, s2, d);
1189                         emit_store(jd, iptr, iptr->dst, d);
1190                         break;
1191
1192                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
1193                                       /* val.i = constant                             */
1194
1195                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1196                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1197                         if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1198                                 M_AND_IMM(s1, iptr->val.i, d);
1199                         } else {
1200                                 ICONST(REG_ITMP2, iptr->val.i);
1201                                 M_AND(s1, REG_ITMP2, d);
1202                         }
1203                         emit_store(jd, iptr, iptr->dst, d);
1204                         break;
1205
1206                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
1207                                       /* val.i = constant                             */
1208
1209                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1210                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1211                         if (s1 == d) {
1212                                 M_MOV(s1, REG_ITMP1);
1213                                 s1 = REG_ITMP1;
1214                         }
1215                         if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1216                                 M_AND_IMM(s1, iptr->val.i, d);
1217                                 M_BGEZ(s1, 4);
1218                                 M_NOP;
1219                                 M_ISUB(REG_ZERO, s1, d);
1220                                 M_AND_IMM(d, iptr->val.i, d);
1221                         } else {
1222                                 ICONST(REG_ITMP2, iptr->val.i);
1223                                 M_AND(s1, REG_ITMP2, d);
1224                                 M_BGEZ(s1, 4);
1225                                 M_NOP;
1226                                 M_ISUB(REG_ZERO, s1, d);
1227                                 M_AND(d, REG_ITMP2, d);
1228                         }
1229                         M_ISUB(REG_ZERO, d, d);
1230                         emit_store(jd, iptr, iptr->dst, d);
1231                         break;
1232
1233                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
1234                                       /* val.l = constant                             */
1235
1236                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1237                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1238                         if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1239                                 M_AND_IMM(s1, iptr->val.l, d);
1240                         } else {
1241                                 LCONST(REG_ITMP2, iptr->val.l);
1242                                 M_AND(s1, REG_ITMP2, d);
1243                         }
1244                         emit_store(jd, iptr, iptr->dst, d);
1245                         break;
1246
1247                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
1248                                       /* val.l = constant                             */
1249
1250                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1251                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1252                         if (s1 == d) {
1253                                 M_MOV(s1, REG_ITMP1);
1254                                 s1 = REG_ITMP1;
1255                         }
1256                         if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1257                                 M_AND_IMM(s1, iptr->val.l, d);
1258                                 M_BGEZ(s1, 4);
1259                                 M_NOP;
1260                                 M_LSUB(REG_ZERO, s1, d);
1261                                 M_AND_IMM(d, iptr->val.l, d);
1262                         } else {
1263                                 LCONST(REG_ITMP2, iptr->val.l);
1264                                 M_AND(s1, REG_ITMP2, d);
1265                                 M_BGEZ(s1, 4);
1266                                 M_NOP;
1267                                 M_LSUB(REG_ZERO, s1, d);
1268                                 M_AND(d, REG_ITMP2, d);
1269                         }
1270                         M_LSUB(REG_ZERO, d, d);
1271                         emit_store(jd, iptr, iptr->dst, d);
1272                         break;
1273
1274                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1275                 case ICMD_LOR:
1276
1277                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1278                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1279                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1280                         M_OR(s1,s2, d);
1281                         emit_store(jd, iptr, iptr->dst, d);
1282                         break;
1283
1284                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
1285                                       /* val.i = constant                             */
1286
1287                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1288                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1289                         if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1290                                 M_OR_IMM(s1, iptr->val.i, d);
1291                         } else {
1292                                 ICONST(REG_ITMP2, iptr->val.i);
1293                                 M_OR(s1, REG_ITMP2, d);
1294                         }
1295                         emit_store(jd, iptr, iptr->dst, d);
1296                         break;
1297
1298                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
1299                                       /* val.l = constant                             */
1300
1301                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1302                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1303                         if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1304                                 M_OR_IMM(s1, iptr->val.l, d);
1305                         } else {
1306                                 LCONST(REG_ITMP2, iptr->val.l);
1307                                 M_OR(s1, REG_ITMP2, d);
1308                         }
1309                         emit_store(jd, iptr, iptr->dst, d);
1310                         break;
1311
1312                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1313                 case ICMD_LXOR:
1314
1315                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1316                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1317                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1318                         M_XOR(s1, s2, d);
1319                         emit_store(jd, iptr, iptr->dst, d);
1320                         break;
1321
1322                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1323                                       /* val.i = constant                             */
1324
1325                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1326                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1327                         if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1328                                 M_XOR_IMM(s1, iptr->val.i, d);
1329                         } else {
1330                                 ICONST(REG_ITMP2, iptr->val.i);
1331                                 M_XOR(s1, REG_ITMP2, d);
1332                         }
1333                         emit_store(jd, iptr, iptr->dst, d);
1334                         break;
1335
1336                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1337                                       /* val.l = constant                             */
1338
1339                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1340                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1341                         if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1342                                 M_XOR_IMM(s1, iptr->val.l, d);
1343                         } else {
1344                                 LCONST(REG_ITMP2, iptr->val.l);
1345                                 M_XOR(s1, REG_ITMP2, d);
1346                         }
1347                         emit_store(jd, iptr, iptr->dst, d);
1348                         break;
1349
1350
1351                 case ICMD_LCMP:       /* ..., val1, val2  ==> ..., val1 cmp val2      */
1352
1353                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1354                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1355                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1356                         M_CMPLT(s1, s2, REG_ITMP3);
1357                         M_CMPLT(s2, s1, REG_ITMP1);
1358                         M_LSUB(REG_ITMP1, REG_ITMP3, d);
1359                         emit_store(jd, iptr, iptr->dst, d);
1360                         break;
1361
1362
1363                 case ICMD_IINC:       /* ..., value  ==> ..., value + constant        */
1364                                       /* op1 = variable, val.i = constant             */
1365
1366                         var = &(rd->locals[iptr->op1][TYPE_INT]);
1367                         if (var->flags & INMEMORY) {
1368                                 s1 = REG_ITMP1;
1369                                 M_LLD(s1, REG_SP, var->regoff * 8);
1370                         } else
1371                                 s1 = var->regoff;
1372                         M_IADD_IMM(s1, iptr->val.i, s1);
1373                         if (var->flags & INMEMORY)
1374                                 M_LST(s1, REG_SP, var->regoff * 8);
1375                         break;
1376
1377
1378                 /* floating operations ************************************************/
1379
1380                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
1381
1382                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1383                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1384                         M_FNEG(s1, d);
1385                         emit_store(jd, iptr, iptr->dst, d);
1386                         break;
1387
1388                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
1389
1390                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1391                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1392                         M_DNEG(s1, d);
1393                         emit_store(jd, iptr, iptr->dst, d);
1394                         break;
1395
1396                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1397
1398                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1399                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1400                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1401                         M_FADD(s1, s2, d);
1402                         emit_store(jd, iptr, iptr->dst, d);
1403                         break;
1404
1405                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1406
1407                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1408                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1409                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1410                         M_DADD(s1, s2, d);
1411                         emit_store(jd, iptr, iptr->dst, d);
1412                         break;
1413
1414                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1415
1416                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1417                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1418                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1419                         M_FSUB(s1, s2, d);
1420                         emit_store(jd, iptr, iptr->dst, d);
1421                         break;
1422
1423                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1424
1425                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1426                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1427                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1428                         M_DSUB(s1, s2, d);
1429                         emit_store(jd, iptr, iptr->dst, d);
1430                         break;
1431
1432                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1433
1434                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1435                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1436                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1437                         M_FMUL(s1, s2, d);
1438                         emit_store(jd, iptr, iptr->dst, d);
1439                         break;
1440
1441                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 *** val2      */
1442
1443                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1444                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1445                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1446                         M_DMUL(s1, s2, d);
1447                         emit_store(jd, iptr, iptr->dst, d);
1448                         break;
1449
1450                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1451
1452                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1453                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1454                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1455                         M_FDIV(s1, s2, d);
1456                         emit_store(jd, iptr, iptr->dst, d);
1457                         break;
1458
1459                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1460
1461                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1462                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1463                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1464                         M_DDIV(s1, s2, d);
1465                         emit_store(jd, iptr, iptr->dst, d);
1466                         break;
1467
1468 #if 0           
1469                 case ICMD_FREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1470
1471                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1472                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1473                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1474                         M_FDIV(s1,s2, REG_FTMP3);
1475                         M_FLOORFL(REG_FTMP3, REG_FTMP3);
1476                         M_CVTLF(REG_FTMP3, REG_FTMP3);
1477                         M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1478                         M_FSUB(s1, REG_FTMP3, d);
1479                         emit_store(jd, iptr, iptr->dst, d);
1480                     break;
1481
1482                 case ICMD_DREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1483
1484                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1485                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1486                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1487                         M_DDIV(s1,s2, REG_FTMP3);
1488                         M_FLOORDL(REG_FTMP3, REG_FTMP3);
1489                         M_CVTLD(REG_FTMP3, REG_FTMP3);
1490                         M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1491                         M_DSUB(s1, REG_FTMP3, d);
1492                         emit_store(jd, iptr, iptr->dst, d);
1493                     break;
1494 #endif
1495
1496                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
1497                 case ICMD_L2F:
1498                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1499                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1500                         M_MOVLD(s1, d);
1501                         M_CVTLF(d, d);
1502                         emit_store(jd, iptr, iptr->dst, d);
1503                         break;
1504
1505                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
1506                 case ICMD_L2D:
1507                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1508                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1509                         M_MOVLD(s1, d);
1510                         M_CVTLD(d, d);
1511                         emit_store(jd, iptr, iptr->dst, d);
1512                         break;
1513
1514 #if 0
1515                 /* XXX these do not work correctly */
1516
1517                 case ICMD_F2I:       /* ..., (float) value  ==> ..., (int) value      */
1518
1519                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1520                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1521                         M_TRUNCFI(s1, REG_FTMP1);
1522                         M_MOVDI(REG_FTMP1, d);
1523                         M_NOP;
1524                         emit_store(jd, iptr, iptr->dst, d);
1525                         break;
1526                 
1527                 case ICMD_D2I:       /* ..., (double) value  ==> ..., (int) value     */
1528
1529                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1530                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1531                         M_TRUNCDI(s1, REG_FTMP1);
1532                         M_MOVDI(REG_FTMP1, d);
1533                         M_NOP;
1534                         emit_store(jd, iptr, iptr->dst, d);
1535                         break;
1536                 
1537                 case ICMD_F2L:       /* ..., (float) value  ==> ..., (long) value     */
1538
1539                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1540                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1541                         M_TRUNCFL(s1, REG_FTMP1);
1542                         M_MOVDL(REG_FTMP1, d);
1543                         M_NOP;
1544                         emit_store(jd, iptr, iptr->dst, d);
1545                         break;
1546
1547                 case ICMD_D2L:       /* ..., (double) value  ==> ..., (long) value    */
1548
1549                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1550                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1551                         M_TRUNCDL(s1, REG_FTMP1);
1552                         M_MOVDL(REG_FTMP1, d);
1553                         M_NOP;
1554                         emit_store(jd, iptr, iptr->dst, d);
1555                         break;
1556 #endif
1557
1558                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1559
1560                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1561                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1562                         M_CVTFD(s1, d);
1563                         emit_store(jd, iptr, iptr->dst, d);
1564                         break;
1565                                         
1566                 case ICMD_D2F:       /* ..., value  ==> ..., (double) value           */
1567
1568                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1569                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1570                         M_CVTDF(s1, d);
1571                         emit_store(jd, iptr, iptr->dst, d);
1572                         break;
1573                 
1574                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1575
1576                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1577                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1578                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1579                         M_FCMPULEF(s1, s2);
1580                         M_FBT(3);
1581                         M_LADD_IMM(REG_ZERO, 1, d);
1582                         M_BR(4);
1583                         M_NOP;
1584                         M_FCMPEQF(s1, s2);
1585                         M_LSUB_IMM(REG_ZERO, 1, d);
1586                         M_CMOVT(REG_ZERO, d);
1587                         emit_store(jd, iptr, iptr->dst, d);
1588                         break;
1589
1590                 case ICMD_DCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1591
1592                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1593                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1594                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1595                         M_FCMPULED(s1, s2);
1596                         M_FBT(3);
1597                         M_LADD_IMM(REG_ZERO, 1, d);
1598                         M_BR(4);
1599                         M_NOP;
1600                         M_FCMPEQD(s1, s2);
1601                         M_LSUB_IMM(REG_ZERO, 1, d);
1602                         M_CMOVT(REG_ZERO, d);
1603                         emit_store(jd, iptr, iptr->dst, d);
1604                         break;
1605                         
1606                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1607
1608                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1609                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1610                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1611                         M_FCMPOLTF(s1, s2);
1612                         M_FBF(3);
1613                         M_LSUB_IMM(REG_ZERO, 1, d);
1614                         M_BR(4);
1615                         M_NOP;
1616                         M_FCMPEQF(s1, s2);
1617                         M_LADD_IMM(REG_ZERO, 1, d);
1618                         M_CMOVT(REG_ZERO, d);
1619                         emit_store(jd, iptr, iptr->dst, d);
1620                         break;
1621
1622                 case ICMD_DCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1623
1624                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1625                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1626                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1627                         M_FCMPOLTD(s1, s2);
1628                         M_FBF(3);
1629                         M_LSUB_IMM(REG_ZERO, 1, d);
1630                         M_BR(4);
1631                         M_NOP;
1632                         M_FCMPEQD(s1, s2);
1633                         M_LADD_IMM(REG_ZERO, 1, d);
1634                         M_CMOVT(REG_ZERO, d);
1635                         emit_store(jd, iptr, iptr->dst, d);
1636                         break;
1637
1638
1639                 /* memory operations **************************************************/
1640
1641                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1642
1643                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1644                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1645                         gen_nullptr_check(s1);
1646                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
1647                         emit_store(jd, iptr, iptr->dst, d);
1648                         break;
1649
1650                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1651
1652                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1653                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1654                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1655                         if (iptr->op1 == 0) {
1656                                 gen_nullptr_check(s1);
1657                                 gen_bound_check;
1658                         }
1659                         M_AADD(s2, s1, REG_ITMP3);
1660                         M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1661                         emit_store(jd, iptr, iptr->dst, d);
1662                         break;
1663
1664                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1665
1666                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1667                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1668                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1669                         if (iptr->op1 == 0) {
1670                                 gen_nullptr_check(s1);
1671                                 gen_bound_check;
1672                         }
1673                         M_AADD(s2, s1, REG_ITMP3);
1674                         M_AADD(s2, REG_ITMP3, REG_ITMP3);
1675                         M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1676                         emit_store(jd, iptr, iptr->dst, d);
1677                         break;                  
1678
1679                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1680
1681                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1682                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1683                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1684                         if (iptr->op1 == 0) {
1685                                 gen_nullptr_check(s1);
1686                                 gen_bound_check;
1687                         }
1688                         M_AADD(s2, s1, REG_ITMP3);
1689                         M_AADD(s2, REG_ITMP3, REG_ITMP3);
1690                         M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1691                         emit_store(jd, iptr, iptr->dst, d);
1692                         break;
1693
1694                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1695
1696                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1697                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1698                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1699                         if (iptr->op1 == 0) {
1700                                 gen_nullptr_check(s1);
1701                                 gen_bound_check;
1702                         }
1703                         M_ASLL_IMM(s2, 2, REG_ITMP3);
1704                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1705                         M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1706                         emit_store(jd, iptr, iptr->dst, d);
1707                         break;
1708
1709                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1710
1711                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1712                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1713                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1714                         if (iptr->op1 == 0) {
1715                                 gen_nullptr_check(s1);
1716                                 gen_bound_check;
1717                         }
1718                         M_ASLL_IMM(s2, 3, REG_ITMP3);
1719                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1720                         M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1721                         emit_store(jd, iptr, iptr->dst, d);
1722                         break;
1723
1724                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1725
1726                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1727                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1728                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1729                         if (iptr->op1 == 0) {
1730                                 gen_nullptr_check(s1);
1731                                 gen_bound_check;
1732                         }
1733                         M_ASLL_IMM(s2, 2, REG_ITMP3);
1734                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1735                         M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1736                         emit_store(jd, iptr, iptr->dst, d);
1737                         break;
1738
1739                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1740
1741                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1742                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1743                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1744                         if (iptr->op1 == 0) {
1745                                 gen_nullptr_check(s1);
1746                                 gen_bound_check;
1747                         }
1748                         M_ASLL_IMM(s2, 3, REG_ITMP3);
1749                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1750                         M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1751                         emit_store(jd, iptr, iptr->dst, d);
1752                         break;
1753
1754                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1755
1756                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1757                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1758                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1759                         if (iptr->op1 == 0) {
1760                                 gen_nullptr_check(s1);
1761                                 gen_bound_check;
1762                         }
1763                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1764                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1765                         M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1766                         emit_store(jd, iptr, iptr->dst, d);
1767                         break;
1768
1769
1770                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1771
1772                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1773                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1774                         if (iptr->op1 == 0) {
1775                                 gen_nullptr_check(s1);
1776                                 gen_bound_check;
1777                         }
1778                         M_AADD(s2, s1, REG_ITMP1);
1779                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1780                         M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1781                         break;
1782
1783                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1784                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1785
1786                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1787                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1788                         if (iptr->op1 == 0) {
1789                                 gen_nullptr_check(s1);
1790                                 gen_bound_check;
1791                         }
1792                         M_AADD(s2, s1, REG_ITMP1);
1793                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
1794                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1795                         M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1796                         break;
1797
1798                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1799
1800                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1801                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1802                         if (iptr->op1 == 0) {
1803                                 gen_nullptr_check(s1);
1804                                 gen_bound_check;
1805                         }
1806                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1807                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1808                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1809                         M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1810                         break;
1811
1812                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1813
1814                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1815                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1816                         if (iptr->op1 == 0) {
1817                                 gen_nullptr_check(s1);
1818                                 gen_bound_check;
1819                         }
1820                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1821                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1822                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1823                         M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1824                         break;
1825
1826                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1827
1828                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1829                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1830                         if (iptr->op1 == 0) {
1831                                 gen_nullptr_check(s1);
1832                                 gen_bound_check;
1833                         }
1834                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1835                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1836                         s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1837                         M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1838                         break;
1839
1840                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1841
1842                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1843                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1844                         if (iptr->op1 == 0) {
1845                                 gen_nullptr_check(s1);
1846                                 gen_bound_check;
1847                         }
1848                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1849                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1850                         s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1851                         M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1852                         break;
1853
1854
1855                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1856
1857                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1858                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1859                         if (iptr->op1 == 0) {
1860                                 gen_nullptr_check(s1);
1861                                 gen_bound_check;
1862                         }
1863                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1864
1865                         M_MOV(s1, rd->argintregs[0]);
1866                         M_MOV(s3, rd->argintregs[1]);
1867                         disp = dseg_addaddress(cd, BUILTIN_canstore);
1868                         M_ALD(REG_ITMP3, REG_PV, disp);
1869                         M_JSR(REG_RA, REG_ITMP3);
1870                         M_NOP;
1871
1872                         M_BEQZ(REG_RESULT, 0);
1873                         codegen_add_arraystoreexception_ref(cd);
1874                         M_NOP;
1875
1876                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1877                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1878                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1879                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1880                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1881                         M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1882                         break;
1883
1884
1885                 case ICMD_BASTORECONST:   /* ..., arrayref, index  ==> ...            */
1886
1887                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1888                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1889                         if (iptr->op1 == 0) {
1890                                 gen_nullptr_check(s1);
1891                                 gen_bound_check;
1892                         }
1893                         M_AADD(s2, s1, REG_ITMP1);
1894                         M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1895                         break;
1896
1897                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
1898                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
1899
1900                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1901                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1902                         if (iptr->op1 == 0) {
1903                                 gen_nullptr_check(s1);
1904                                 gen_bound_check;
1905                         }
1906                         M_AADD(s2, s1, REG_ITMP1);
1907                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
1908                         M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1909                         break;
1910
1911                 case ICMD_IASTORECONST:   /* ..., arrayref, index  ==> ...            */
1912
1913                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1914                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1915                         if (iptr->op1 == 0) {
1916                                 gen_nullptr_check(s1);
1917                                 gen_bound_check;
1918                         }
1919                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1920                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1921                         M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1922                         break;
1923
1924                 case ICMD_LASTORECONST:   /* ..., arrayref, index  ==> ...            */
1925
1926                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1927                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1928                         if (iptr->op1 == 0) {
1929                                 gen_nullptr_check(s1);
1930                                 gen_bound_check;
1931                         }
1932                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1933                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1934                         M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1935                         break;
1936
1937                 case ICMD_AASTORECONST:   /* ..., arrayref, index  ==> ...            */
1938
1939                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1940                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1941                         if (iptr->op1 == 0) {
1942                                 gen_nullptr_check(s1);
1943                                 gen_bound_check;
1944                         }
1945                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1946                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1947                         M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1948                         break;
1949
1950
1951                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1952                                       /* op1 = type, val.a = field address            */
1953
1954                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1955                                 disp = dseg_addaddress(cd, NULL);
1956
1957                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
1958                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1959
1960                                 if (opt_showdisassemble) {
1961                                         M_NOP; M_NOP;
1962                                 }
1963
1964                         } else {
1965                                 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1966
1967                                 disp = dseg_addaddress(cd, &(fi->value));
1968
1969                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1970                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1971
1972                                         if (opt_showdisassemble) {
1973                                                 M_NOP; M_NOP;
1974                                         }
1975                                 }
1976                         }
1977
1978                         M_ALD(REG_ITMP1, REG_PV, disp);
1979                         switch (iptr->op1) {
1980                         case TYPE_INT:
1981                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1982                                 M_ILD_INTERN(d, REG_ITMP1, 0);
1983                                 emit_store(jd, iptr, iptr->dst, d);
1984                                 break;
1985                         case TYPE_LNG:
1986                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1987                                 M_LLD_INTERN(d, REG_ITMP1, 0);
1988                                 emit_store(jd, iptr, iptr->dst, d);
1989                                 break;
1990                         case TYPE_ADR:
1991                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1992                                 M_ALD_INTERN(d, REG_ITMP1, 0);
1993                                 emit_store(jd, iptr, iptr->dst, d);
1994                                 break;
1995                         case TYPE_FLT:
1996                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1997                                 M_FLD_INTERN(d, REG_ITMP1, 0);
1998                                 emit_store(jd, iptr, iptr->dst, d);
1999                                 break;
2000                         case TYPE_DBL:                          
2001                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2002                                 M_DLD_INTERN(d, REG_ITMP1, 0);
2003                                 emit_store(jd, iptr, iptr->dst, d);
2004                                 break;
2005                         }
2006                         break;
2007
2008                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
2009                                       /* op1 = type, val.a = field address            */
2010
2011                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2012                                 disp = dseg_addaddress(cd, NULL);
2013
2014                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
2015                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
2016
2017                                 if (opt_showdisassemble) {
2018                                         M_NOP; M_NOP;
2019                                 }
2020
2021                         } else {
2022                                 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2023
2024                                 disp = dseg_addaddress(cd, &(fi->value));
2025
2026                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2027                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2028
2029                                         if (opt_showdisassemble) {
2030                                                 M_NOP; M_NOP;
2031                                         }
2032                                 }
2033                         }
2034
2035                         M_ALD(REG_ITMP1, REG_PV, disp);
2036                         switch (iptr->op1) {
2037                         case TYPE_INT:
2038                                 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2039                                 M_IST_INTERN(s2, REG_ITMP1, 0);
2040                                 break;
2041                         case TYPE_LNG:
2042                                 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2043                                 M_LST_INTERN(s2, REG_ITMP1, 0);
2044                                 break;
2045                         case TYPE_ADR:
2046                                 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2047                                 M_AST_INTERN(s2, REG_ITMP1, 0);
2048                                 break;
2049                         case TYPE_FLT:
2050                                 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2051                                 M_FST_INTERN(s2, REG_ITMP1, 0);
2052                                 break;
2053                         case TYPE_DBL:
2054                                 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2055                                 M_DST_INTERN(s2, REG_ITMP1, 0);
2056                                 break;
2057                         }
2058                         break;
2059
2060                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
2061                                           /* val = value (in current instruction)     */
2062                                           /* op1 = type, val.a = field address (in    */
2063                                           /* following NOP)                           */
2064
2065                         if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2066                                 disp = dseg_addaddress(cd, NULL);
2067
2068                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
2069                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), disp);
2070
2071                                 if (opt_showdisassemble) {
2072                                         M_NOP; M_NOP;
2073                                 }
2074
2075                         } else {
2076                                 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
2077
2078                                 disp = dseg_addaddress(cd, &(fi->value));
2079
2080                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2081                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2082
2083                                         if (opt_showdisassemble) {
2084                                                 M_NOP; M_NOP;
2085                                         }
2086                                 }
2087                         }
2088
2089                         M_ALD(REG_ITMP1, REG_PV, disp);
2090                         switch (iptr->op1) {
2091                         case TYPE_INT:
2092                                 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2093                                 break;
2094                         case TYPE_LNG:
2095                                 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2096                                 break;
2097                         case TYPE_ADR:
2098                                 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2099                                 break;
2100                         case TYPE_FLT:
2101                                 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2102                                 break;
2103                         case TYPE_DBL:
2104                                 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2105                                 break;
2106                         }
2107                         break;
2108
2109
2110                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
2111                                       /* op1 = type, val.i = field offset             */
2112
2113                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2114                         gen_nullptr_check(s1);
2115
2116                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2117                                 codegen_addpatchref(cd, PATCHER_get_putfield,
2118                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2119
2120                                 if (opt_showdisassemble) {
2121                                         M_NOP; M_NOP;
2122                                 }
2123
2124                                 a = 0;
2125
2126                         } else {
2127                                 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2128                         }
2129
2130                         switch (iptr->op1) {
2131                         case TYPE_INT:
2132                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2133                                 M_ILD(d, s1, a);
2134                                 emit_store(jd, iptr, iptr->dst, d);
2135                                 break;
2136                         case TYPE_LNG:
2137                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2138                                 M_LLD(d, s1, a);
2139                                 emit_store(jd, iptr, iptr->dst, d);
2140                                 break;
2141                         case TYPE_ADR:
2142                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2143                                 M_ALD(d, s1, a);
2144                                 emit_store(jd, iptr, iptr->dst, d);
2145                                 break;
2146                         case TYPE_FLT:
2147                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2148                                 M_FLD(d, s1, a);
2149                                 emit_store(jd, iptr, iptr->dst, d);
2150                                 break;
2151                         case TYPE_DBL:                          
2152                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2153                                 M_DLD(d, s1, a);
2154                                 emit_store(jd, iptr, iptr->dst, d);
2155                                 break;
2156                         }
2157                         break;
2158
2159                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
2160                                       /* op1 = type, val.a = field address            */
2161
2162                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2163                         gen_nullptr_check(s1);
2164
2165                         if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2166                                 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2167                         } else {
2168                                 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2169                         }
2170
2171                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2172                                 codegen_addpatchref(cd, PATCHER_get_putfield,
2173                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2174
2175                                 if (opt_showdisassemble) {
2176                                         M_NOP; M_NOP;
2177                                 }
2178
2179                                 a = 0;
2180
2181                         } else {
2182                                 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2183                         }
2184
2185                         switch (iptr->op1) {
2186                         case TYPE_INT:
2187                                 M_IST(s2, s1, a);
2188                                 break;
2189                         case TYPE_LNG:
2190                                 M_LST(s2, s1, a);
2191                                 break;
2192                         case TYPE_ADR:
2193                                 M_AST(s2, s1, a);
2194                                 break;
2195                         case TYPE_FLT:
2196                                 M_FST(s2, s1, a);
2197                                 break;
2198                         case TYPE_DBL:
2199                                 M_DST(s2, s1, a);
2200                                 break;
2201                         }
2202                         break;
2203
2204                 case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
2205                                           /* val = value (in current instruction)     */
2206                                           /* op1 = type, val.a = field address (in    */
2207                                           /* following NOP)                           */
2208
2209                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2210                         gen_nullptr_check(s1);
2211
2212                         if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2213                                 codegen_addpatchref(cd, PATCHER_get_putfield,
2214                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
2215
2216                                 if (opt_showdisassemble) {
2217                                         M_NOP; M_NOP;
2218                                 }
2219
2220                                 a = 0;
2221
2222                         } else {
2223                                 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1)->offset;
2224                         }
2225
2226                         switch (iptr[1].op1) {
2227                         case TYPE_INT:
2228                                 M_IST(REG_ZERO, s1, a);
2229                                 break;
2230                         case TYPE_LNG:
2231                                 M_LST(REG_ZERO, s1, a);
2232                                 break;
2233                         case TYPE_ADR:
2234                                 M_AST(REG_ZERO, s1, a);
2235                                 break;
2236                         case TYPE_FLT:
2237                                 M_FST(REG_ZERO, s1, a);
2238                                 break;
2239                         case TYPE_DBL:
2240                                 M_DST(REG_ZERO, s1, a);
2241                                 break;
2242                         }
2243                         break;
2244
2245
2246                 /* branch operations **************************************************/
2247
2248                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
2249
2250                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2251                         M_INTMOVE(s1, REG_ITMP1_XPTR);
2252                         
2253 #ifdef ENABLE_VERIFIER
2254                         if (iptr->val.a) {
2255                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2256                                                                         (unresolved_class *) iptr->val.a, 0);
2257
2258                                 if (opt_showdisassemble) {
2259                                         M_NOP; M_NOP;
2260                                 }
2261                         }
2262 #endif /* ENABLE_VERIFIER */
2263
2264                         disp = dseg_addaddress(cd, asm_handle_exception);
2265                         M_ALD(REG_ITMP2, REG_PV, disp);
2266                         M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2267                         M_NOP;
2268                         M_NOP;              /* nop ensures that XPC is less than the end */
2269                                             /* of basic block                            */
2270                         ALIGNCODENOP;
2271                         break;
2272
2273                 case ICMD_GOTO:         /* ... ==> ...                                */
2274                                         /* op1 = target JavaVM pc                     */
2275                         M_BR(0);
2276                         codegen_addreference(cd, (basicblock *) iptr->target);
2277                         M_NOP;
2278                         ALIGNCODENOP;
2279                         break;
2280
2281                 case ICMD_JSR:          /* ... ==> ...                                */
2282                                         /* op1 = target JavaVM pc                     */
2283
2284                         dseg_addtarget(cd, (basicblock *) iptr->target);
2285                         M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
2286                         M_JSR(REG_ITMP1, REG_ITMP1);        /* REG_ITMP1 = return address */
2287                         M_NOP;
2288                         break;
2289                         
2290                 case ICMD_RET:          /* ... ==> ...                                */
2291                                         /* op1 = local variable                       */
2292                         var = &(rd->locals[iptr->op1][TYPE_ADR]);
2293                         if (var->flags & INMEMORY) {
2294                                 M_ALD(REG_ITMP1, REG_SP, var->regoff * 8);
2295                                 M_RET(REG_ITMP1);
2296                         } else
2297                                 M_RET(var->regoff);
2298                         M_NOP;
2299                         ALIGNCODENOP;
2300                         break;
2301
2302                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
2303                                         /* op1 = target JavaVM pc                     */
2304
2305                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2306                         M_BEQZ(s1, 0);
2307                         codegen_addreference(cd, (basicblock *) iptr->target);
2308                         M_NOP;
2309                         break;
2310
2311                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
2312                                         /* op1 = target JavaVM pc                     */
2313
2314                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2315                         M_BNEZ(s1, 0);
2316                         codegen_addreference(cd, (basicblock *) iptr->target);
2317                         M_NOP;
2318                         break;
2319
2320                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
2321                                         /* op1 = target JavaVM pc, val.i = constant   */
2322
2323                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2324                         if (iptr->val.i == 0) {
2325                                 M_BEQZ(s1, 0);
2326                         } else {
2327                                 ICONST(REG_ITMP2, iptr->val.i);
2328                                 M_BEQ(s1, REG_ITMP2, 0);
2329                         }
2330                         codegen_addreference(cd, (basicblock *) iptr->target);
2331                         M_NOP;
2332                         break;
2333
2334                 case ICMD_IFLT:         /* ..., value ==> ...                         */
2335                                         /* op1 = target JavaVM pc, val.i = constant   */
2336
2337                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2338                         if (iptr->val.i == 0) {
2339                                 M_BLTZ(s1, 0);
2340                         } else {
2341                                 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2342                                         M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2343                                 } else {
2344                                         ICONST(REG_ITMP2, iptr->val.i);
2345                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2346                                 }
2347                                 M_BNEZ(REG_ITMP1, 0);
2348                         }
2349                         codegen_addreference(cd, (basicblock *) iptr->target);
2350                         M_NOP;
2351                         break;
2352
2353                 case ICMD_IFLE:         /* ..., value ==> ...                         */
2354                                         /* op1 = target JavaVM pc, val.i = constant   */
2355
2356                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2357                         if (iptr->val.i == 0) {
2358                                 M_BLEZ(s1, 0);
2359                                 }
2360                         else {
2361                                 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2362                                         M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2363                                         M_BNEZ(REG_ITMP1, 0);
2364                                         }
2365                                 else {
2366                                         ICONST(REG_ITMP2, iptr->val.i);
2367                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2368                                         M_BEQZ(REG_ITMP1, 0);
2369                                         }
2370                                 }
2371                         codegen_addreference(cd, (basicblock *) iptr->target);
2372                         M_NOP;
2373                         break;
2374
2375                 case ICMD_IFNE:         /* ..., value ==> ...                         */
2376                                         /* op1 = target JavaVM pc, val.i = constant   */
2377
2378                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2379                         if (iptr->val.i == 0) {
2380                                 M_BNEZ(s1, 0);
2381                                 }
2382                         else {
2383                                 ICONST(REG_ITMP2, iptr->val.i);
2384                                 M_BNE(s1, REG_ITMP2, 0);
2385                                 }
2386                         codegen_addreference(cd, (basicblock *) iptr->target);
2387                         M_NOP;
2388                         break;
2389
2390                 case ICMD_IFGT:         /* ..., value ==> ...                         */
2391                                         /* op1 = target JavaVM pc, val.i = constant   */
2392
2393                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2394                         if (iptr->val.i == 0) {
2395                                 M_BGTZ(s1, 0);
2396                                 }
2397                         else {
2398                                 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2399                                         M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2400                                         M_BEQZ(REG_ITMP1, 0);
2401                                         }
2402                                 else {
2403                                         ICONST(REG_ITMP2, iptr->val.i);
2404                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2405                                         M_BNEZ(REG_ITMP1, 0);
2406                                         }
2407                                 }
2408                         codegen_addreference(cd, (basicblock *) iptr->target);
2409                         M_NOP;
2410                         break;
2411
2412                 case ICMD_IFGE:         /* ..., value ==> ...                         */
2413                                         /* op1 = target JavaVM pc, val.i = constant   */
2414
2415                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2416                         if (iptr->val.i == 0) {
2417                                 M_BGEZ(s1, 0);
2418                                 }
2419                         else {
2420                                 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2421                                         M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2422                                         }
2423                                 else {
2424                                         ICONST(REG_ITMP2, iptr->val.i);
2425                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2426                                         }
2427                                 M_BEQZ(REG_ITMP1, 0);
2428                                 }
2429                         codegen_addreference(cd, (basicblock *) iptr->target);
2430                         M_NOP;
2431                         break;
2432
2433                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
2434                                         /* op1 = target JavaVM pc, val.l = constant   */
2435
2436                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2437                         if (iptr->val.l == 0) {
2438                                 M_BEQZ(s1, 0);
2439                                 }
2440                         else {
2441                                 LCONST(REG_ITMP2, iptr->val.l);
2442                                 M_BEQ(s1, REG_ITMP2, 0);
2443                                 }
2444                         codegen_addreference(cd, (basicblock *) iptr->target);
2445                         M_NOP;
2446                         break;
2447
2448                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
2449                                         /* op1 = target JavaVM pc, val.l = constant   */
2450
2451                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2452                         if (iptr->val.l == 0) {
2453                                 M_BLTZ(s1, 0);
2454                                 }
2455                         else {
2456                                 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2457                                         M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2458                                         }
2459                                 else {
2460                                         LCONST(REG_ITMP2, iptr->val.l);
2461                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2462                                         }
2463                                 M_BNEZ(REG_ITMP1, 0);
2464                                 }
2465                         codegen_addreference(cd, (basicblock *) iptr->target);
2466                         M_NOP;
2467                         break;
2468
2469                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
2470                                         /* op1 = target JavaVM pc, val.l = constant   */
2471
2472                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2473                         if (iptr->val.l == 0) {
2474                                 M_BLEZ(s1, 0);
2475                                 }
2476                         else {
2477                                 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2478                                         M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2479                                         M_BNEZ(REG_ITMP1, 0);
2480                                         }
2481                                 else {
2482                                         LCONST(REG_ITMP2, iptr->val.l);
2483                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2484                                         M_BEQZ(REG_ITMP1, 0);
2485                                         }
2486                                 }
2487                         codegen_addreference(cd, (basicblock *) iptr->target);
2488                         M_NOP;
2489                         break;
2490
2491                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
2492                                         /* op1 = target JavaVM pc, val.l = constant   */
2493
2494                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2495                         if (iptr->val.l == 0) {
2496                                 M_BNEZ(s1, 0);
2497                                 }
2498                         else {
2499                                 LCONST(REG_ITMP2, iptr->val.l);
2500                                 M_BNE(s1, REG_ITMP2, 0);
2501                                 }
2502                         codegen_addreference(cd, (basicblock *) iptr->target);
2503                         M_NOP;
2504                         break;
2505
2506                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2507                                         /* op1 = target JavaVM pc, val.l = constant   */
2508
2509                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2510                         if (iptr->val.l == 0) {
2511                                 M_BGTZ(s1, 0);
2512                                 }
2513                         else {
2514                                 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2515                                         M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2516                                         M_BEQZ(REG_ITMP1, 0);
2517                                         }
2518                                 else {
2519                                         LCONST(REG_ITMP2, iptr->val.l);
2520                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2521                                         M_BNEZ(REG_ITMP1, 0);
2522                                         }
2523                                 }
2524                         codegen_addreference(cd, (basicblock *) iptr->target);
2525                         M_NOP;
2526                         break;
2527
2528                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2529                                         /* op1 = target JavaVM pc, val.l = constant   */
2530
2531                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2532                         if (iptr->val.l == 0) {
2533                                 M_BGEZ(s1, 0);
2534                                 }
2535                         else {
2536                                 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2537                                         M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2538                                         }
2539                                 else {
2540                                         LCONST(REG_ITMP2, iptr->val.l);
2541                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2542                                         }
2543                                 M_BEQZ(REG_ITMP1, 0);
2544                                 }
2545                         codegen_addreference(cd, (basicblock *) iptr->target);
2546                         M_NOP;
2547                         break;
2548
2549                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
2550                 case ICMD_IF_LCMPEQ:    /* op1 = target JavaVM pc                     */
2551                 case ICMD_IF_ACMPEQ:
2552
2553                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2554                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2555                         M_BEQ(s1, s2, 0);
2556                         codegen_addreference(cd, (basicblock *) iptr->target);
2557                         M_NOP;
2558                         break;
2559
2560                 case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
2561                 case ICMD_IF_LCMPNE:    /* op1 = target JavaVM pc                     */
2562                 case ICMD_IF_ACMPNE:
2563
2564                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2565                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2566                         M_BNE(s1, s2, 0);
2567                         codegen_addreference(cd, (basicblock *) iptr->target);
2568                         M_NOP;
2569                         break;
2570
2571                 case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
2572                 case ICMD_IF_LCMPLT:    /* op1 = target JavaVM pc                     */
2573
2574                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2575                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2576                         M_CMPLT(s1, s2, REG_ITMP1);
2577                         M_BNEZ(REG_ITMP1, 0);
2578                         codegen_addreference(cd, (basicblock *) iptr->target);
2579                         M_NOP;
2580                         break;
2581
2582                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
2583                 case ICMD_IF_LCMPGT:    /* op1 = target JavaVM pc                     */
2584
2585                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2586                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2587                         M_CMPGT(s1, s2, REG_ITMP1);
2588                         M_BNEZ(REG_ITMP1, 0);
2589                         codegen_addreference(cd, (basicblock *) iptr->target);
2590                         M_NOP;
2591                         break;
2592
2593                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
2594                 case ICMD_IF_LCMPLE:    /* op1 = target JavaVM pc                     */
2595
2596                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2597                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2598                         M_CMPGT(s1, s2, REG_ITMP1);
2599                         M_BEQZ(REG_ITMP1, 0);
2600                         codegen_addreference(cd, (basicblock *) iptr->target);
2601                         M_NOP;
2602                         break;
2603
2604                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
2605                 case ICMD_IF_LCMPGE:    /* op1 = target JavaVM pc                     */
2606
2607                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2608                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2609                         M_CMPLT(s1, s2, REG_ITMP1);
2610                         M_BEQZ(REG_ITMP1, 0);
2611                         codegen_addreference(cd, (basicblock *) iptr->target);
2612                         M_NOP;
2613                         break;
2614
2615 #ifdef CONDITIONAL_LOADCONST
2616                 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST                           */
2617
2618                 case ICMD_ELSE_ICONST:  /* handled by IFxx_ICONST                     */
2619                         break;
2620
2621                 case ICMD_IFEQ_ICONST:  /* ..., value ==> ..., constant               */
2622                                         /* val.i = constant                           */
2623
2624                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2625                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2626                         s3 = iptr->val.i;
2627                         if (iptr[1].opc == ICMD_ELSE_ICONST) {
2628                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2629                                         M_CMPEQ(s1, REG_ZERO, d);
2630                                         emit_store(jd, iptr, iptr->dst, d);
2631                                         break;
2632                                 }
2633                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2634                                         M_CMPEQ(s1, REG_ZERO, d);
2635                                         M_XOR_IMM(d, 1, d);
2636                                         emit_store(jd, iptr, iptr->dst, d);
2637                                         break;
2638                                 }
2639                                 if (s1 == d) {
2640                                         M_MOV(s1, REG_ITMP1);
2641                                         s1 = REG_ITMP1;
2642                                 }
2643                                 ICONST(d, iptr[1].val.i);
2644                         }
2645                         if ((s3 >= 0) && (s3 <= 255)) {
2646                                 M_CMOVEQ_IMM(s1, s3, d);
2647                         } else {
2648                                 ICONST(REG_ITMP3, s3);
2649                                 M_CMOVEQ(s1, REG_ITMP3, d);
2650                         }
2651                         emit_store(jd, iptr, iptr->dst, d);
2652                         break;
2653
2654                 case ICMD_IFNE_ICONST:  /* ..., value ==> ..., constant               */
2655                                         /* val.i = constant                           */
2656
2657                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2658                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2659                         s3 = iptr->val.i;
2660                         if (iptr[1].opc == ICMD_ELSE_ICONST) {
2661                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2662                                         M_CMPEQ(s1, REG_ZERO, d);
2663                                         emit_store(jd, iptr, iptr->dst, d);
2664                                         break;
2665                                 }
2666                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2667                                         M_CMPEQ(s1, REG_ZERO, d);
2668                                         M_XOR_IMM(d, 1, d);
2669                                         emit_store(jd, iptr, iptr->dst, d);
2670                                         break;
2671                                 }
2672                                 if (s1 == d) {
2673                                         M_MOV(s1, REG_ITMP1);
2674                                         s1 = REG_ITMP1;
2675                                 }
2676                                 ICONST(d, iptr[1].val.i);
2677                         }
2678                         if ((s3 >= 0) && (s3 <= 255)) {
2679                                 M_CMOVNE_IMM(s1, s3, d);
2680                         } else {
2681                                 ICONST(REG_ITMP3, s3);
2682                                 M_CMOVNE(s1, REG_ITMP3, d);
2683                         }
2684                         emit_store(jd, iptr, iptr->dst, d);
2685                         break;
2686
2687                 case ICMD_IFLT_ICONST:  /* ..., value ==> ..., constant               */
2688                                         /* val.i = constant                           */
2689
2690                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2691                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2692                         s3 = iptr->val.i;
2693                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2694                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2695                                         M_CMPLT(s1, REG_ZERO, d);
2696                                         emit_store(jd, iptr, iptr->dst, d);
2697                                         break;
2698                                 }
2699                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2700                                         M_CMPLE(REG_ZERO, s1, d);
2701                                         emit_store(jd, iptr, iptr->dst, d);
2702                                         break;
2703                                 }
2704                                 if (s1 == d) {
2705                                         M_MOV(s1, REG_ITMP1);
2706                                         s1 = REG_ITMP1;
2707                                 }
2708                                 ICONST(d, iptr[1].val.i);
2709                         }
2710                         if ((s3 >= 0) && (s3 <= 255)) {
2711                                 M_CMOVLT_IMM(s1, s3, d);
2712                         } else {
2713                                 ICONST(REG_ITMP3, s3);
2714                                 M_CMOVLT(s1, REG_ITMP3, d);
2715                         }
2716                         emit_store(jd, iptr, iptr->dst, d);
2717                         break;
2718
2719                 case ICMD_IFGE_ICONST:  /* ..., value ==> ..., constant               */
2720                                         /* val.i = constant                           */
2721
2722                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2723                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2724                         s3 = iptr->val.i;
2725                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2726                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2727                                         M_CMPLE(REG_ZERO, s1, d);
2728                                         emit_store(jd, iptr, iptr->dst, d);
2729                                         break;
2730                                 }
2731                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2732                                         M_CMPLT(s1, REG_ZERO, d);
2733                                         emit_store(jd, iptr, iptr->dst, d);
2734                                         break;
2735                                 }
2736                                 if (s1 == d) {
2737                                         M_MOV(s1, REG_ITMP1);
2738                                         s1 = REG_ITMP1;
2739                                 }
2740                                 ICONST(d, iptr[1].val.i);
2741                         }
2742                         if ((s3 >= 0) && (s3 <= 255)) {
2743                                 M_CMOVGE_IMM(s1, s3, d);
2744                         } else {
2745                                 ICONST(REG_ITMP3, s3);
2746                                 M_CMOVGE(s1, REG_ITMP3, d);
2747                         }
2748                         emit_store(jd, iptr, iptr->dst, d);
2749                         break;
2750
2751                 case ICMD_IFGT_ICONST:  /* ..., value ==> ..., constant               */
2752                                         /* val.i = constant                           */
2753
2754                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2755                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2756                         s3 = iptr->val.i;
2757                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2758                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2759                                         M_CMPLT(REG_ZERO, s1, d);
2760                                         emit_store(jd, iptr, iptr->dst, d);
2761                                         break;
2762                                 }
2763                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2764                                         M_CMPLE(s1, REG_ZERO, d);
2765                                         emit_store(jd, iptr, iptr->dst, d);
2766                                         break;
2767                                 }
2768                                 if (s1 == d) {
2769                                         M_MOV(s1, REG_ITMP1);
2770                                         s1 = REG_ITMP1;
2771                                 }
2772                                 ICONST(d, iptr[1].val.i);
2773                         }
2774                         if ((s3 >= 0) && (s3 <= 255)) {
2775                                 M_CMOVGT_IMM(s1, s3, d);
2776                         } else {
2777                                 ICONST(REG_ITMP3, s3);
2778                                 M_CMOVGT(s1, REG_ITMP3, d);
2779                         }
2780                         emit_store(jd, iptr, iptr->dst, d);
2781                         break;
2782
2783                 case ICMD_IFLE_ICONST:  /* ..., value ==> ..., constant               */
2784                                         /* val.i = constant                           */
2785
2786                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2787                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2788                         s3 = iptr->val.i;
2789                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2790                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2791                                         M_CMPLE(s1, REG_ZERO, d);
2792                                         emit_store(jd, iptr, iptr->dst, d);
2793                                         break;
2794                                 }
2795                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2796                                         M_CMPLT(REG_ZERO, s1, d);
2797                                         emit_store(jd, iptr, iptr->dst, d);
2798                                         break;
2799                                 }
2800                                 if (s1 == d) {
2801                                         M_MOV(s1, REG_ITMP1);
2802                                         s1 = REG_ITMP1;
2803                                 }
2804                                 ICONST(d, iptr[1].val.i);
2805                         }
2806                         if ((s3 >= 0) && (s3 <= 255)) {
2807                                 M_CMOVLE_IMM(s1, s3, d);
2808                         } else {
2809                                 ICONST(REG_ITMP3, s3);
2810                                 M_CMOVLE(s1, REG_ITMP3, d);
2811                         }
2812                         emit_store(jd, iptr, iptr->dst, d);
2813                         break;
2814 #endif
2815
2816
2817                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2818                 case ICMD_LRETURN:
2819
2820                         s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2821                         M_INTMOVE(s1, REG_RESULT);
2822                         goto nowperformreturn;
2823
2824                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2825
2826                         s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2827                         M_INTMOVE(s1, REG_RESULT);
2828
2829 #ifdef ENABLE_VERIFIER
2830                         if (iptr->val.a) {
2831                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2832                                                                         (unresolved_class *) iptr->val.a, 0);
2833
2834                                 if (opt_showdisassemble) {
2835                                         M_NOP; M_NOP;
2836                                 }
2837                         }
2838 #endif /* ENABLE_VERIFIER */
2839                         goto nowperformreturn;
2840
2841             case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2842
2843                         s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2844                         M_FLTMOVE(s1, REG_FRESULT);
2845                         goto nowperformreturn;
2846
2847             case ICMD_DRETURN:      /* ..., retvalue ==> ...                      */
2848
2849                         s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2850                         M_DBLMOVE(s1, REG_FRESULT);
2851                         goto nowperformreturn;
2852
2853                 case ICMD_RETURN:      /* ...  ==> ...                                */
2854
2855 nowperformreturn:
2856                         {
2857                         s4 i, p;
2858                         
2859                         p = parentargs_base;
2860                         
2861                         /* call trace function */
2862
2863                         if (opt_verbosecall) {
2864                                 M_LDA(REG_SP, REG_SP, -3 * 8);
2865                                 M_LST(REG_RA, REG_SP, 0 * 8);
2866                                 M_LST(REG_RESULT, REG_SP, 1 * 8);
2867                                 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2868
2869                                 disp = dseg_addaddress(cd, m);
2870                                 M_ALD(rd->argintregs[0], REG_PV, disp);
2871                                 M_MOV(REG_RESULT, rd->argintregs[1]);
2872                                 M_DMOV(REG_FRESULT, rd->argfltregs[2]);
2873                                 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
2874
2875                                 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2876                                 M_ALD(REG_ITMP3, REG_PV, disp);
2877                                 M_JSR(REG_RA, REG_ITMP3);
2878                                 M_NOP;
2879
2880                                 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2881                                 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2882                                 M_LLD(REG_RA, REG_SP, 0 * 8);
2883                                 M_LDA(REG_SP, REG_SP, 3 * 8);
2884                         }
2885
2886 #if defined(ENABLE_THREADS)
2887                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2888                                 disp = dseg_addaddress(cd, (void *) builtin_monitorexit);
2889                                 M_ALD(REG_ITMP3, REG_PV, disp);
2890
2891                                 /* we need to save the proper return value */
2892
2893                                 switch (iptr->opc) {
2894                                 case ICMD_IRETURN:
2895                                 case ICMD_ARETURN:
2896                                 case ICMD_LRETURN:
2897                                         M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2898                                         M_JSR(REG_RA, REG_ITMP3);
2899                                         M_LST(REG_RESULT, REG_SP, rd->memuse * 8);  /* delay slot */
2900                                         break;
2901                                 case ICMD_FRETURN:
2902                                 case ICMD_DRETURN:
2903                                         M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2904                                         M_JSR(REG_RA, REG_ITMP3);
2905                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2906                                         break;
2907                                 case ICMD_RETURN:
2908                                         M_JSR(REG_RA, REG_ITMP3);
2909                                         M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* delay*/
2910                                         break;
2911                                 }
2912
2913                                 /* and now restore the proper return value */
2914
2915                                 switch (iptr->opc) {
2916                                 case ICMD_IRETURN:
2917                                 case ICMD_ARETURN:
2918                                 case ICMD_LRETURN:
2919                                         M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2920                                         break;
2921                                 case ICMD_FRETURN:
2922                                 case ICMD_DRETURN:
2923                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2924                                         break;
2925                                 }
2926                         }
2927 #endif
2928
2929                         /* restore return address                                         */
2930
2931                         if (!m->isleafmethod) {
2932                                 p--; M_ALD(REG_RA, REG_SP, p * 8);
2933                         }
2934
2935                         /* restore saved registers                                        */
2936
2937                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2938                                 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2939                         }
2940                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2941                                 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2942                         }
2943
2944                         /* deallocate stack and return                                    */
2945
2946                         if (parentargs_base) {
2947                                 s4 lo, hi;
2948
2949                                 disp = parentargs_base * 8;
2950                                 lo = (short) (disp);
2951                                 hi = (short) (((disp) - lo) >> 16);
2952
2953                                 if (hi == 0) {
2954                                         M_RET(REG_RA);
2955                                         M_LADD_IMM(REG_SP, lo, REG_SP);             /* delay slot */
2956                                 } else {
2957                                         M_LUI(REG_ITMP3,hi);
2958                                         M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2959                                         M_RET(REG_RA);
2960                                         M_LADD(REG_ITMP3,REG_SP,REG_SP);            /* delay slot */
2961                                 }
2962
2963                         } else {
2964                                 M_RET(REG_RA);
2965                                 M_NOP;
2966                         }
2967
2968                         ALIGNCODENOP;
2969                         }
2970                         break;
2971
2972
2973                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2974                         {
2975                         s4 i, l, *s4ptr;
2976                         void **tptr;
2977
2978                         tptr = (void **) iptr->target;
2979
2980                         s4ptr = iptr->val.a;
2981                         l = s4ptr[1];                          /* low     */
2982                         i = s4ptr[2];                          /* high    */
2983                         
2984                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2985                         if (l == 0)
2986                                 {M_INTMOVE(s1, REG_ITMP1);}
2987                         else if (l <= 32768) {
2988                                 M_IADD_IMM(s1, -l, REG_ITMP1);
2989                                 }
2990                         else {
2991                                 ICONST(REG_ITMP2, l);
2992                                 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2993                                 }
2994                         i = i - l + 1;
2995
2996                         /* range check */
2997
2998                         M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2999                         M_BEQZ(REG_ITMP2, 0);
3000                         codegen_addreference(cd, (basicblock *) tptr[0]);
3001                         M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);      /* delay slot*/
3002
3003                         /* build jump table top down and use address of lowest entry */
3004
3005                         /* s4ptr += 3 + i; */
3006                         tptr += i;
3007
3008                         while (--i >= 0) {
3009                                 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3010                                 dseg_addtarget(cd, (basicblock *) tptr[0]); 
3011                                 --tptr;
3012                                 }
3013                         }
3014
3015                         /* length of dataseg after last dseg_addtarget is used by load */
3016
3017                         M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
3018                         M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3019                         M_JMP(REG_ITMP2);
3020                         M_NOP;
3021                         ALIGNCODENOP;
3022                         break;
3023
3024
3025                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
3026                         {
3027                         s4 i, /*l, */val, *s4ptr;
3028                         void **tptr;
3029
3030                         tptr = (void **) iptr->target;
3031
3032                         s4ptr = iptr->val.a;
3033                         /*l = s4ptr[0];*/                          /* default  */
3034                         i = s4ptr[1];                          /* count    */
3035                         
3036                         MCODECHECK((i<<2)+8);
3037                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3038                         while (--i >= 0) {
3039                                 s4ptr += 2;
3040                                 ++tptr;
3041
3042                                 val = s4ptr[0];
3043                                 ICONST(REG_ITMP2, val);
3044                                 M_BEQ(s1, REG_ITMP2, 0);
3045                                 codegen_addreference(cd, (basicblock *) tptr[0]); 
3046                                 M_NOP;
3047                         }
3048
3049                         M_BR(0);
3050                         tptr = (void **) iptr->target;
3051                         codegen_addreference(cd, (basicblock *) tptr[0]);
3052                         M_NOP;
3053                         ALIGNCODENOP;
3054                         break;
3055                         }
3056
3057
3058                 case ICMD_BUILTIN:      /* ..., arg1 ==> ...                          */
3059                                         /* op1 = arg count val.a = builtintable entry */
3060
3061                         bte = iptr->val.a;
3062                         md = bte->md;
3063                         goto gen_method;
3064
3065                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
3066                                         /* op1 = arg count, val.a = method pointer    */
3067
3068                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3069                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
3070                 case ICMD_INVOKEINTERFACE:
3071
3072                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3073                                 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
3074                                 lm = NULL;
3075                         }
3076                         else {
3077                                 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
3078                                 md = lm->parseddesc;
3079                         }
3080
3081 gen_method:
3082                         s3 = md->paramcount;
3083
3084                         MCODECHECK((s3 << 1) + 64);
3085
3086                         /* copy arguments to registers or stack location                  */
3087
3088                         for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3089                                 if (src->varkind == ARGVAR)
3090                                         continue;
3091                                 if (IS_INT_LNG_TYPE(src->type)) {
3092                                         if (!md->params[s3].inmemory) {
3093                                                 s1 = rd->argintregs[md->params[s3].regoff];
3094                                                 d = emit_load_s1(jd, iptr, src, s1);
3095                                                 M_INTMOVE(d, s1);
3096                                         } else  {
3097                                                 d = emit_load_s1(jd, iptr, src, REG_ITMP1);
3098                                                 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3099                                         }
3100
3101                                 } else {
3102                                         if (!md->params[s3].inmemory) {
3103                                                 s1 = rd->argfltregs[md->params[s3].regoff];
3104                                                 d = emit_load_s1(jd, iptr, src, s1);
3105                                                 if (IS_2_WORD_TYPE(src->type))
3106                                                         M_DMOV(d, s1);
3107                                                 else
3108                                                         M_FMOV(d, s1);
3109
3110                                         } else {
3111                                                 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
3112                                                 if (IS_2_WORD_TYPE(src->type))
3113                                                         M_DST(d, REG_SP, md->params[s3].regoff * 8);
3114                                                 else
3115                                                         M_FST(d, REG_SP, md->params[s3].regoff * 8);
3116                                         }
3117                                 }
3118                         }
3119
3120                         switch (iptr->opc) {
3121                         case ICMD_BUILTIN:
3122                                 disp = dseg_addaddress(cd, bte->fp);
3123                                 d = md->returntype.type;
3124
3125                                 M_ALD(REG_ITMP3, REG_PV, disp);  /* built-in-function pointer */
3126                                 M_JSR(REG_RA, REG_ITMP3);
3127                                 M_NOP;
3128                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3129                                 M_LDA(REG_PV, REG_RA, -disp);
3130
3131                                 /* if op1 == true, we need to check for an exception */
3132
3133                                 if (iptr->op1 == true) {
3134                                         M_BEQZ(REG_RESULT, 0);
3135                                         codegen_add_fillinstacktrace_ref(cd);
3136                                         M_NOP;
3137                                 }
3138                                 break;
3139
3140                         case ICMD_INVOKESPECIAL:
3141                                 M_BEQZ(rd->argintregs[0], 0);
3142                                 codegen_add_nullpointerexception_ref(cd);
3143                                 M_NOP;
3144                                 /* fall through */
3145
3146                         case ICMD_INVOKESTATIC:
3147                                 if (lm == NULL) {
3148                                         unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3149
3150                                         disp = dseg_addaddress(cd, NULL);
3151
3152                                         codegen_addpatchref(cd, PATCHER_invokestatic_special,
3153                                                                                 um, disp);
3154
3155                                         if (opt_showdisassemble) {
3156                                                 M_NOP; M_NOP;
3157                                         }
3158
3159                                         d = um->methodref->parseddesc.md->returntype.type;
3160
3161                                 } else {
3162                                         disp = dseg_addaddress(cd, lm->stubroutine);
3163                                         d = lm->parseddesc->returntype.type;
3164                                 }
3165
3166                                 M_ALD(REG_PV, REG_PV, disp);          /* method pointer in pv */
3167                                 M_JSR(REG_RA, REG_PV);
3168                                 M_NOP;
3169                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3170                                 M_LDA(REG_PV, REG_RA, -disp);
3171                                 break;
3172
3173                         case ICMD_INVOKEVIRTUAL:
3174                                 gen_nullptr_check(rd->argintregs[0]);
3175
3176                                 if (lm == NULL) {
3177                                         unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3178
3179                                         codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3180
3181                                         if (opt_showdisassemble) {
3182                                                 M_NOP; M_NOP;
3183                                         }
3184
3185                                         s1 = 0;
3186                                         d = um->methodref->parseddesc.md->returntype.type;
3187
3188                                 } else {
3189                                         s1 = OFFSET(vftbl_t, table[0]) +
3190                                                 sizeof(methodptr) * lm->vftblindex;
3191                                         d = lm->parseddesc->returntype.type;
3192                                 }
3193
3194                                 M_ALD(REG_METHODPTR, rd->argintregs[0],
3195                                           OFFSET(java_objectheader, vftbl));
3196                                 M_ALD(REG_PV, REG_METHODPTR, s1);
3197                                 M_JSR(REG_RA, REG_PV);
3198                                 M_NOP;
3199                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3200                                 M_LDA(REG_PV, REG_RA, -disp);
3201                                 break;
3202
3203                         case ICMD_INVOKEINTERFACE:
3204                                 gen_nullptr_check(rd->argintregs[0]);
3205
3206                                 if (lm == NULL) {
3207                                         unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3208
3209                                         codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3210
3211                                         if (opt_showdisassemble) {
3212                                                 M_NOP; M_NOP;
3213                                         }
3214
3215                                         s1 = 0;
3216                                         s2 = 0;
3217                                         d = um->methodref->parseddesc.md->returntype.type;
3218
3219                                 } else {
3220                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
3221                                                 sizeof(methodptr*) * lm->class->index;
3222
3223                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
3224
3225                                         d = lm->parseddesc->returntype.type;
3226                                 }
3227
3228                                 M_ALD(REG_METHODPTR, rd->argintregs[0],
3229                                           OFFSET(java_objectheader, vftbl));
3230                                 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3231                                 M_ALD(REG_PV, REG_METHODPTR, s2);
3232                                 M_JSR(REG_RA, REG_PV);
3233                                 M_NOP;
3234                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3235                                 M_LDA(REG_PV, REG_RA, -disp);
3236                                 break;
3237                         }
3238
3239                         /* d contains return type */
3240
3241                         if (d != TYPE_VOID) {
3242                                 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3243                                         s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3244                                         M_INTMOVE(REG_RESULT, s1);
3245                                 } else {
3246                                         s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FRESULT);
3247                                         if (IS_2_WORD_TYPE(iptr->dst->type))
3248                                                 M_DMOV(REG_FRESULT, s1);
3249                                         else
3250                                                 M_FMOV(REG_FRESULT, s1);
3251                                 }
3252                                 emit_store(jd, iptr, iptr->dst, s1);
3253                         }
3254                         break;
3255
3256
3257                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
3258                                       /* op1:   0 == array, 1 == class                */
3259                                       /* val.a: (classinfo*) superclass               */
3260
3261                         /*  superclass is an interface:
3262                          *
3263                          *  OK if ((sub == NULL) ||
3264                          *         (sub->vftbl->interfacetablelength > super->index) &&
3265                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
3266                          *
3267                          *  superclass is a class:
3268                          *
3269                          *  OK if ((sub == NULL) || (0
3270                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3271                          *         super->vftbl->diffvall));
3272                          */
3273
3274                         if (iptr->op1 == 1) {
3275                                 classinfo *super;
3276                                 vftbl_t   *supervftbl;
3277                                 s4         superindex;
3278
3279                                 super = (classinfo *) iptr->val.a;
3280
3281                                 if (!super) {
3282                                         superindex = 0;
3283                                         supervftbl = NULL;
3284
3285                                 } else {
3286                                         superindex = super->index;
3287                                         supervftbl = super->vftbl;
3288                                 }
3289                         
3290 #if defined(ENABLE_THREADS)
3291                                 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3292 #endif
3293
3294                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3295
3296                                 /* calculate interface checkcast code size */
3297
3298                                 s2 = 8;
3299                                 if (!super)
3300                                         s2 += (opt_showdisassemble ? 2 : 0);
3301
3302                                 /* calculate class checkcast code size */
3303
3304                                 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
3305                                 if (!super)
3306                                         s3 += (opt_showdisassemble ? 2 : 0);
3307
3308                                 /* if class is not resolved, check which code to call */
3309
3310                                 if (!super) {
3311                                         M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3312                                         M_NOP;
3313
3314                                         disp = dseg_adds4(cd, 0);                 /* super->flags */
3315
3316                                         codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3317                                                                                 (constant_classref *) iptr->target,
3318                                                                                 disp);
3319
3320                                         if (opt_showdisassemble) {
3321                                                 M_NOP; M_NOP;
3322                                         }
3323
3324                                         /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3325                                         M_ILD(REG_ITMP2, REG_PV, disp);
3326                                         M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3327                                         M_BEQZ(REG_ITMP2, 1 + s2 + 2);
3328                                         M_NOP;
3329                                 }
3330
3331                                 /* interface checkcast code */
3332
3333                                 if (!super || super->flags & ACC_INTERFACE) {
3334                                         if (super) {
3335                                                 M_BEQZ(s1, 1 + s2);
3336                                                 M_NOP;
3337
3338                                         } else {
3339                                                 codegen_addpatchref(cd,
3340                                                                                         PATCHER_checkcast_instanceof_interface,
3341                                                                                         (constant_classref *) iptr->target,
3342                                                                                         0);
3343
3344                                                 if (opt_showdisassemble) {
3345                                                         M_NOP; M_NOP;
3346                                                 }
3347                                         }
3348
3349                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3350                                         M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3351                                         M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3352                                         M_BLEZ(REG_ITMP3, 0);
3353                                         codegen_add_classcastexception_ref(cd);
3354                                         M_NOP;
3355                                         M_ALD(REG_ITMP3, REG_ITMP2,
3356                                                   OFFSET(vftbl_t, interfacetable[0]) -
3357                                                   superindex * sizeof(methodptr*));
3358                                         M_BEQZ(REG_ITMP3, 0);
3359                                         codegen_add_classcastexception_ref(cd);
3360                                         M_NOP;
3361
3362                                         if (!super) {
3363                                                 M_BR(1 + s3);
3364                                                 M_NOP;
3365                                         }
3366                                 }
3367
3368                                 /* class checkcast code */
3369
3370                                 if (!super || !(super->flags & ACC_INTERFACE)) {
3371                                         disp = dseg_addaddress(cd, (void *) supervftbl);
3372
3373                                         if (super) {
3374                                                 M_BEQZ(s1, 1 + s3);
3375                                                 M_NOP;
3376
3377                                         } else {
3378                                                 codegen_addpatchref(cd,
3379                                                                                         PATCHER_checkcast_instanceof_class,
3380                                                                                         (constant_classref *) iptr->target,
3381                                                                                         disp);
3382
3383                                                 if (opt_showdisassemble) {
3384                                                         M_NOP; M_NOP;
3385                                                 }
3386                                         }
3387
3388                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3389                                         M_ALD(REG_ITMP3, REG_PV, disp);
3390 #if defined(ENABLE_THREADS)
3391                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3392 #endif
3393                                         M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3394                                         /*                              if (s1 != REG_ITMP1) { */
3395                                         /*                                      M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3396                                         /*                                      M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3397                                         /* #if defined(ENABLE_THREADS) */
3398                                         /*                                      codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3399                                         /* #endif */
3400                                         /*                                      M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3401                                         /*                              } else { */
3402                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3403                                         M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2); 
3404                                         M_ALD(REG_ITMP3, REG_PV, disp);
3405                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3406 #if defined(ENABLE_THREADS)
3407                                         codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3408 #endif
3409                                         /*                              } */
3410                                         M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3411                                         M_BNEZ(REG_ITMP3, 0);
3412                                         codegen_add_classcastexception_ref(cd);
3413                                         M_NOP;
3414                                 }
3415                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3416
3417                         } else {
3418                                 s1 = emit_load_s1(jd, iptr, src, rd->argintregs[0]);
3419                                 M_INTMOVE(s1, rd->argintregs[0]);
3420
3421                                 disp = dseg_addaddress(cd, iptr->val.a);
3422
3423                                 if (iptr->val.a == NULL) {
3424                                         codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3425                                                                                 (constant_classref *) iptr->target,
3426                                                                                 disp);
3427
3428                                         if (opt_showdisassemble) {
3429                                                 M_NOP; M_NOP;
3430                                         }
3431                                 }
3432
3433                                 M_ALD(rd->argintregs[1], REG_PV, disp);
3434                                 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3435                                 M_ALD(REG_ITMP3, REG_PV, disp);
3436                                 M_JSR(REG_RA, REG_ITMP3);
3437                                 M_NOP;
3438
3439                                 M_BEQZ(REG_RESULT, 0);
3440                                 codegen_add_classcastexception_ref(cd);
3441                                 M_NOP;
3442
3443                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3444                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3445                         }
3446                         M_INTMOVE(s1, d);
3447                         emit_store(jd, iptr, iptr->dst, d);
3448                         break;
3449
3450                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3451                                       /* op1:   0 == array, 1 == class                */
3452                                       /* val.a: (classinfo*) superclass               */
3453
3454                         /*  superclass is an interface:
3455                          *
3456                          *  return (sub != NULL) &&
3457                          *         (sub->vftbl->interfacetablelength > super->index) &&
3458                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
3459                          *
3460                          *  superclass is a class:
3461                          *
3462                          *  return ((sub != NULL) && (0
3463                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3464                          *          super->vftbl->diffvall));
3465                          */
3466
3467                         {
3468                         classinfo *super;
3469                         vftbl_t   *supervftbl;
3470                         s4         superindex;
3471
3472                         super = (classinfo *) iptr->val.a;
3473
3474                         if (!super) {
3475                                 superindex = 0;
3476                                 supervftbl = NULL;
3477
3478                         } else {
3479                                 superindex = super->index;
3480                                 supervftbl = super->vftbl;
3481                         }
3482                         
3483 #if defined(ENABLE_THREADS)
3484                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3485 #endif
3486
3487                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3488                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3489                         if (s1 == d) {
3490                                 M_MOV(s1, REG_ITMP1);
3491                                 s1 = REG_ITMP1;
3492                         }
3493
3494                         /* calculate interface instanceof code size */
3495
3496                         s2 = 7;
3497                         if (!super)
3498                                 s2 += (opt_showdisassemble ? 2 : 0);
3499
3500                         /* calculate class instanceof code size */
3501
3502                         s3 = 8;
3503                         if (!super)
3504                                 s3 += (opt_showdisassemble ? 2 : 0);
3505
3506                         M_CLR(d);
3507
3508                         /* if class is not resolved, check which code to call */
3509
3510                         if (!super) {
3511                                 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3512                                 M_NOP;
3513
3514                                 disp = dseg_adds4(cd, 0);                     /* super->flags */
3515
3516                                 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3517                                                                         (constant_classref *) iptr->target, disp);
3518
3519                                 if (opt_showdisassemble) {
3520                                         M_NOP; M_NOP;
3521                                 }
3522
3523                                 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3524                                 M_ILD(REG_ITMP3, REG_PV, disp);
3525                                 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3526                                 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
3527                                 M_NOP;
3528                         }
3529
3530                         /* interface instanceof code */
3531
3532                         if (!super || (super->flags & ACC_INTERFACE)) {
3533                                 if (super) {
3534                                         M_BEQZ(s1, 1 + s2);
3535                                         M_NOP;
3536
3537                                 } else {
3538                                         codegen_addpatchref(cd,
3539                                                                                 PATCHER_checkcast_instanceof_interface,
3540                                                                                 (constant_classref *) iptr->target, 0);
3541
3542                                         if (opt_showdisassemble) {
3543                                                 M_NOP; M_NOP;
3544                                         }
3545                                 }
3546
3547                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3548                                 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3549                                 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3550                                 M_BLEZ(REG_ITMP3, 3);
3551                                 M_NOP;
3552                                 M_ALD(REG_ITMP1, REG_ITMP1,
3553                                           OFFSET(vftbl_t, interfacetable[0]) -
3554                                           superindex * sizeof(methodptr*));
3555                                 M_CMPULT(REG_ZERO, REG_ITMP1, d);      /* REG_ITMP1 != 0  */
3556
3557                                 if (!super) {
3558                                         M_BR(1 + s3);
3559                                         M_NOP;
3560                                 }
3561                         }
3562
3563                         /* class instanceof code */
3564
3565                         if (!super || !(super->flags & ACC_INTERFACE)) {
3566                                 disp = dseg_addaddress(cd, supervftbl);
3567
3568                                 if (super) {
3569                                         M_BEQZ(s1, 1 + s3);
3570                                         M_NOP;
3571
3572                                 } else {
3573                                         codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
3574                                                                                 (constant_classref *) iptr->target,
3575                                                                                 disp);
3576
3577                                         if (opt_showdisassemble) {
3578                                                 M_NOP; M_NOP;
3579                                         }
3580                                 }
3581
3582                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3583                                 M_ALD(REG_ITMP2, REG_PV, disp);
3584 #if defined(ENABLE_THREADS)
3585                                 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3586 #endif
3587                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3588                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3589                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3590 #if defined(ENABLE_THREADS)
3591                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3592 #endif
3593                                 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1); 
3594                                 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3595                                 M_XOR_IMM(d, 1, d);
3596                         }
3597                         emit_store(jd, iptr, iptr->dst, d);
3598                         }
3599                         break;
3600
3601                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3602                                       /* op1 = dimension, val.a = class               */
3603
3604                         /* check for negative sizes and copy sizes to stack if necessary  */
3605
3606                         MCODECHECK((iptr->op1 << 1) + 64);
3607
3608                         for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3609                                 /* copy SAVEDVAR sizes to stack */
3610
3611                                 if (src->varkind != ARGVAR) {
3612                                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP1);
3613                                         M_LST(s2, REG_SP, s1 * 8);
3614                                 }
3615                         }
3616
3617                         /* a0 = dimension count */
3618
3619                         ICONST(rd->argintregs[0], iptr->op1);
3620
3621                         /* is patcher function set? */
3622
3623                         if (iptr->val.a == NULL) {
3624                                 disp = dseg_addaddress(cd, NULL);
3625
3626                                 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3627                                                                         (constant_classref *) iptr->target, disp);
3628
3629                                 if (opt_showdisassemble) {
3630                                         M_NOP; M_NOP;
3631                                 }
3632
3633                         } else {
3634                                 disp = dseg_addaddress(cd, iptr->val.a);
3635                         }
3636
3637                         /* a1 = arraydescriptor */
3638
3639                         M_ALD(rd->argintregs[1], REG_PV, disp);
3640
3641                         /* a2 = pointer to dimensions = stack pointer */
3642
3643                         M_INTMOVE(REG_SP, rd->argintregs[2]);
3644
3645                         disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3646                         M_ALD(REG_ITMP3, REG_PV, disp);
3647                         M_JSR(REG_RA, REG_ITMP3);
3648                         M_NOP;
3649
3650                         /* check for exception before result assignment */
3651
3652                         M_BEQZ(REG_RESULT, 0);
3653                         codegen_add_fillinstacktrace_ref(cd);
3654                         M_NOP;
3655
3656                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3657                         M_INTMOVE(REG_RESULT, d);
3658                         emit_store(jd, iptr, iptr->dst, d);
3659                         break;
3660
3661                 default:
3662                         *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3663                         return false;
3664         } /* switch */
3665                 
3666         } /* for instruction */
3667                 
3668         /* copy values to interface registers */
3669
3670         src = bptr->outstack;
3671         len = bptr->outdepth;
3672         MCODECHECK(64+len);
3673 #if defined(ENABLE_LSRA)
3674         if (!opt_lsra) 
3675 #endif
3676         while (src) {
3677                 len--;
3678                 if ((src->varkind != STACKVAR)) {
3679                         s2 = src->type;
3680                         if (IS_FLT_DBL_TYPE(s2)) {
3681                                 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
3682                                 if (rd->interfaces[len][s2].flags & INMEMORY) {
3683                                         if (IS_2_WORD_TYPE(s2))
3684                                                 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3685                                         else
3686                                                 M_FST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3687
3688                                 } else {
3689                                         if (IS_2_WORD_TYPE(s2))
3690                                                 M_DMOV(s1, rd->interfaces[len][s2].regoff);
3691                                         else
3692                                                 M_FMOV(s1, rd->interfaces[len][s2].regoff);
3693                                 }
3694
3695                         } else {
3696                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3697                                 if (rd->interfaces[len][s2].flags & INMEMORY)
3698                                         M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3699                                 else
3700                                         M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3701                         }
3702                 }
3703                 src = src->prev;
3704         }
3705
3706         /* At the end of a basic block we may have to append some nops,
3707            because the patcher stub calling code might be longer than the
3708            actual instruction. So codepatching does not change the
3709            following block unintentionally. */
3710
3711         if (cd->mcodeptr < cd->lastmcodeptr) {
3712                 while (cd->mcodeptr < cd->lastmcodeptr)
3713                         M_NOP;
3714         }
3715
3716         } /* if (bptr -> flags >= BBREACHED) */
3717         } /* for basic block */
3718
3719         dseg_createlinenumbertable(cd);
3720
3721
3722         /* generate exception and patcher stubs */
3723
3724         {
3725                 exceptionref *eref;
3726                 patchref     *pref;
3727                 u8            mcode;
3728                 u1           *savedmcodeptr;
3729                 u1           *tmpmcodeptr;
3730
3731                 savedmcodeptr = NULL;
3732
3733                 /* generate exception stubs */
3734
3735                 for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
3736                         gen_resolvebranch(cd->mcodebase + eref->branchpos, 
3737                                                           eref->branchpos, cd->mcodeptr - cd->mcodebase);
3738
3739                         MCODECHECK(100);
3740
3741                         /* Check if the exception is an
3742                            ArrayIndexOutOfBoundsException.  If so, move index register
3743                            into REG_ITMP1. */
3744
3745                         if (eref->reg != -1)
3746                                 M_MOV(eref->reg, REG_ITMP1);
3747
3748                         /* calcuate exception address */
3749
3750                         M_LDA(REG_ITMP2_XPC, REG_PV, eref->branchpos - 4);
3751
3752                         /* move function to call into REG_ITMP3 */
3753
3754                         disp = dseg_addaddress(cd, eref->function);
3755                         M_ALD(REG_ITMP3, REG_PV, disp);
3756
3757                         if (savedmcodeptr != NULL) {
3758                                 disp = ((u4 *) savedmcodeptr) - (((u4 *) cd->mcodeptr) + 1);
3759                                 M_BR(disp);
3760                                 M_NOP;
3761
3762                         } else {
3763                                 savedmcodeptr = cd->mcodeptr;
3764
3765                                 M_MOV(REG_PV, rd->argintregs[0]);
3766                                 M_MOV(REG_SP, rd->argintregs[1]);
3767
3768                                 if (m->isleafmethod)
3769                                         M_MOV(REG_RA, rd->argintregs[2]);
3770                                 else
3771                                         M_ALD(rd->argintregs[2],
3772                                                   REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3773
3774                                 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3775                                 M_MOV(REG_ITMP1, rd->argintregs[4]);
3776
3777                                 M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3778                                 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3779
3780                                 if (m->isleafmethod)
3781                                         M_AST(REG_RA, REG_SP, 1 * 8);
3782
3783                                 M_JSR(REG_RA, REG_ITMP3);
3784                                 M_NOP;
3785                                 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3786
3787                                 if (m->isleafmethod)
3788                                         M_ALD(REG_RA, REG_SP, 1 * 8);
3789
3790                                 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3791                                 M_AADD_IMM(REG_SP, 2 * 8, REG_SP);
3792
3793                                 a = dseg_addaddress(cd, asm_handle_exception);
3794                                 M_ALD(REG_ITMP3, REG_PV, a);
3795                                 M_JMP(REG_ITMP3);
3796                                 M_NOP;
3797                         }
3798                 }
3799
3800
3801                 /* generate code patching stub call code */
3802
3803                 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
3804                         /* check code segment size */
3805
3806                         MCODECHECK(100);
3807
3808                         /* Get machine code which is patched back in later. The
3809                            call is 2 instruction words long. */
3810
3811                         tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
3812
3813                         /* We need to split this, because an unaligned 8 byte read
3814                            causes a SIGSEGV. */
3815
3816                         mcode = ((u8) ((u4 *) tmpmcodeptr)[1] << 32) +
3817                                 ((u4 *) tmpmcodeptr)[0];
3818
3819                         /* Patch in the call to call the following code (done at
3820                            compile time). */
3821
3822                         savedmcodeptr = cd->mcodeptr;   /* save current mcodeptr          */
3823                         cd->mcodeptr  = tmpmcodeptr;    /* set mcodeptr to patch position */
3824
3825                         disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1);
3826
3827                         if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
3828                                 *exceptionptr =
3829                                         new_internalerror("Jump offset is out of range: %d > +/-%d",
3830                                                                           disp, 0x00007fff);
3831                                 return false;
3832                         }
3833
3834                         M_BR(disp);
3835                         M_NOP;
3836
3837                         cd->mcodeptr = savedmcodeptr;   /* restore the current mcodeptr   */
3838
3839                         /* create stack frame */
3840
3841                         M_ASUB_IMM(REG_SP, 6 * 8, REG_SP);
3842
3843                         /* calculate return address and move it onto the stack */
3844
3845                         M_LDA(REG_ITMP3, REG_PV, pref->branchpos);
3846                         M_AST(REG_ITMP3, REG_SP, 5 * 8);
3847
3848                         /* move pointer to java_objectheader onto stack */
3849
3850 #if defined(ENABLE_THREADS)
3851                         /* create a virtual java_objectheader */
3852
3853                         (void) dseg_addaddress(cd, NULL);                         /* flcword    */
3854                         (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
3855                         disp = dseg_addaddress(cd, NULL);                         /* vftbl      */
3856
3857                         M_LDA(REG_ITMP3, REG_PV, disp);
3858                         M_AST(REG_ITMP3, REG_SP, 4 * 8);
3859 #else
3860                         /* do nothing */
3861 #endif
3862
3863                         /* move machine code onto stack */
3864
3865                         disp = dseg_adds8(cd, mcode);
3866                         M_LLD(REG_ITMP3, REG_PV, disp);
3867                         M_LST(REG_ITMP3, REG_SP, 3 * 8);
3868
3869                         /* move class/method/field reference onto stack */
3870
3871                         disp = dseg_addaddress(cd, pref->ref);
3872                         M_ALD(REG_ITMP3, REG_PV, disp);
3873                         M_AST(REG_ITMP3, REG_SP, 2 * 8);
3874
3875                         /* move data segment displacement onto stack */
3876
3877                         disp = dseg_adds4(cd, pref->disp);
3878                         M_ILD(REG_ITMP3, REG_PV, disp);
3879                         M_IST(REG_ITMP3, REG_SP, 1 * 8);
3880
3881                         /* move patcher function pointer onto stack */
3882
3883                         disp = dseg_addaddress(cd, pref->patcher);
3884                         M_ALD(REG_ITMP3, REG_PV, disp);
3885                         M_AST(REG_ITMP3, REG_SP, 0 * 8);
3886
3887                         disp = dseg_addaddress(cd, asm_wrapper_patcher);
3888                         M_ALD(REG_ITMP3, REG_PV, disp);
3889                         M_JMP(REG_ITMP3);
3890                         M_NOP;
3891                 }
3892
3893                 /* generate replacement-out stubs */
3894
3895                 {
3896                         int i;
3897
3898                         replacementpoint = jd->code->rplpoints;
3899
3900                         for (i = 0; i < jd->code->rplpointcount; ++i, ++replacementpoint) {
3901                                 /* check code segment size */
3902
3903                                 MCODECHECK(100);
3904
3905                                 /* note start of stub code */
3906
3907                                 replacementpoint->outcode = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
3908
3909                                 /* make machine code for patching */
3910
3911                                 savedmcodeptr = cd->mcodeptr;
3912                                 cd->mcodeptr = (u1 *) &(replacementpoint->mcode);
3913
3914                                 disp = (ptrint)((s4*)replacementpoint->outcode - (s4*)replacementpoint->pc) - 1;
3915                                 if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
3916                                         *exceptionptr =
3917                                                 new_internalerror("Jump offset is out of range: %d > +/-%d",
3918                                                                 disp, 0x00007fff);
3919                                         return false;
3920                                 }
3921                                 M_BR(disp);
3922                                 M_NOP; /* delay slot */
3923
3924                                 cd->mcodeptr = savedmcodeptr;
3925
3926                                 /* create stack frame - 16-byte aligned */
3927
3928                                 M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3929
3930                                 /* push address of `rplpoint` struct */
3931
3932                                 disp = dseg_addaddress(cd, replacementpoint);
3933                                 M_ALD(REG_ITMP3, REG_PV, disp);
3934                                 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3935
3936                                 /* jump to replacement function */
3937
3938                                 disp = dseg_addaddress(cd, asm_replacement_out);
3939                                 M_ALD(REG_ITMP3, REG_PV, disp);
3940                                 M_JMP(REG_ITMP3);
3941                                 M_NOP; /* delay slot */
3942                         }
3943                 }
3944         }
3945
3946         codegen_finish(jd);
3947
3948         /* everything's ok */
3949
3950         return true;
3951 }
3952
3953
3954 /* createcompilerstub **********************************************************
3955
3956    Creates a stub routine which calls the compiler.
3957         
3958 *******************************************************************************/
3959
3960 #define COMPILERSTUB_DATASIZE    2 * SIZEOF_VOID_P
3961 #define COMPILERSTUB_CODESIZE    4 * 4
3962
3963 #define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3964
3965
3966 u1 *createcompilerstub(methodinfo *m)
3967 {
3968         u1          *s;                     /* memory to hold the stub            */
3969         ptrint      *d;
3970         codegendata *cd;
3971         s4           dumpsize;
3972
3973         s = CNEW(u1, COMPILERSTUB_SIZE);
3974
3975         /* set data pointer and code pointer */
3976
3977         d = (ptrint *) s;
3978         s = s + COMPILERSTUB_DATASIZE;
3979
3980         /* mark start of dump memory area */
3981
3982         dumpsize = dump_size();
3983
3984         cd = DNEW(codegendata);
3985         cd->mcodeptr = s;
3986
3987         /* Store the methodinfo* in the same place as in the methodheader
3988            for compiled methods. */
3989
3990         d[0] = (ptrint) asm_call_jit_compiler;
3991         d[1] = (ptrint) m;
3992
3993         M_ALD_INTERN(REG_ITMP1, REG_PV, -1 * SIZEOF_VOID_P);    /* method pointer */
3994         M_ALD_INTERN(REG_PV, REG_PV, -2 * SIZEOF_VOID_P);  /* pointer to compiler */
3995         M_JMP(REG_PV);
3996         M_NOP;
3997
3998         md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
3999
4000 #if defined(ENABLE_STATISTICS)
4001         if (opt_stat)
4002                 count_cstub_len += COMPILERSTUB_SIZE;
4003 #endif
4004
4005         /* release dump area */
4006
4007         dump_release(dumpsize);
4008
4009         return s;
4010 }
4011
4012
4013 /* createnativestub ************************************************************
4014
4015    Creates a stub routine which calls a native method.
4016
4017 *******************************************************************************/
4018
4019 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
4020 {
4021         methodinfo   *m;
4022         codegendata  *cd;
4023         registerdata *rd;
4024         s4            stackframesize;       /* size of stackframe if needed       */
4025         methoddesc   *md;
4026         s4            nativeparams;
4027         s4            i, j;                 /* count variables                    */
4028         s4            t;
4029         s4            s1, s2, disp;
4030         s4            funcdisp;             /* displacement of the function       */
4031
4032         /* get required compiler data */
4033
4034         m  = jd->m;
4035         cd = jd->cd;
4036         rd = jd->rd;
4037
4038         /* initialize variables */
4039
4040         md = m->parseddesc;
4041         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4042
4043         /* calculate stack frame size */
4044
4045         stackframesize =
4046                 1 +                             /* return address                     */
4047                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4048                 sizeof(localref_table) / SIZEOF_VOID_P +
4049                 md->paramcount +                /* for saving arguments over calls    */
4050                 1 +                             /* for saving return address          */
4051                 nmd->memuse;
4052
4053         /* create method header */
4054
4055 #if SIZEOF_VOID_P == 4
4056         (void) dseg_addaddress(cd, m);                          /* MethodPointer  */
4057 #endif
4058         (void) dseg_addaddress(cd, m);                          /* MethodPointer  */
4059         (void) dseg_adds4(cd, stackframesize * 8);              /* FrameSize      */
4060         (void) dseg_adds4(cd, 0);                               /* IsSync         */
4061         (void) dseg_adds4(cd, 0);                               /* IsLeaf         */
4062         (void) dseg_adds4(cd, 0);                               /* IntSave        */
4063         (void) dseg_adds4(cd, 0);                               /* FltSave        */
4064         (void) dseg_addlinenumbertablesize(cd);
4065         (void) dseg_adds4(cd, 0);                               /* ExTableSize    */
4066
4067         /* generate stub code */
4068
4069         M_LDA(REG_SP, REG_SP, -stackframesize * 8); /* build up stackframe        */
4070         M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* store ra    */
4071
4072         /* call trace function */
4073
4074         if (opt_verbosecall) {
4075                 M_LDA(REG_SP, REG_SP, -(1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4076
4077                 /* save integer argument registers */
4078
4079                 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4080                         if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4081                                 M_LST(rd->argintregs[i], REG_SP, (1 + i) * 8);
4082
4083                 /* save and copy float arguments into integer registers */
4084
4085                 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4086                         t = md->paramtypes[i].type;
4087
4088                         if (IS_FLT_DBL_TYPE(t)) {
4089                                 if (IS_2_WORD_TYPE(t)) {
4090                                         M_DST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4091                                         M_LLD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4092                                 } else {
4093                                         M_FST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4094                                         M_ILD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4095                                 }
4096                         }
4097                 }
4098
4099                 disp = dseg_addaddress(cd, m);
4100                 M_ALD(REG_ITMP1, REG_PV, disp);
4101                 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4102                 disp = dseg_addaddress(cd, builtin_trace_args);
4103                 M_ALD(REG_ITMP3, REG_PV, disp);
4104                 M_JSR(REG_RA, REG_ITMP3);
4105                 M_NOP;
4106
4107                 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4108                         if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4109                                 M_LLD(rd->argintregs[i], REG_SP, (1 + i) * 8);
4110
4111                 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4112                         t = md->paramtypes[i].type;
4113
4114                         if (IS_FLT_DBL_TYPE(t)) {
4115                                 if (IS_2_WORD_TYPE(t))
4116                                         M_DLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4117                                 else
4118                                         M_FLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4119                         }
4120                 }
4121
4122                 M_LDA(REG_SP, REG_SP, (1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4123         }
4124
4125         /* get function address (this must happen before the stackframeinfo) */
4126
4127         funcdisp = dseg_addaddress(cd, f);
4128
4129 #if !defined(WITH_STATIC_CLASSPATH)
4130         if (f == NULL) {
4131                 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
4132
4133                 if (opt_showdisassemble) {
4134                         M_NOP; M_NOP;
4135                 }
4136         }
4137 #endif
4138
4139         /* save integer and float argument registers */
4140
4141         for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4142                 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4143                         M_LST(rd->argintregs[i], REG_SP, j * 8);
4144                         j++;
4145                 }
4146         }
4147
4148         for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4149                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4150                         M_DST(rd->argfltregs[i], REG_SP, j * 8);
4151                         j++;
4152                 }
4153         }
4154
4155         /* prepare data structures for native function call */
4156
4157         M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4158         M_MOV(REG_PV, rd->argintregs[1]);
4159         M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[2]);
4160         M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4161         disp = dseg_addaddress(cd, codegen_start_native_call);
4162         M_ALD(REG_ITMP3, REG_PV, disp);
4163         M_JSR(REG_RA, REG_ITMP3);
4164         M_NOP; /* XXX fill me! */
4165
4166         /* restore integer and float argument registers */
4167
4168         for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4169                 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4170                         M_LLD(rd->argintregs[i], REG_SP, j * 8);
4171                         j++;
4172                 }
4173         }
4174
4175         for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4176                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4177                         M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4178                         j++;
4179                 }
4180         }
4181
4182         /* copy or spill arguments to new locations */
4183
4184         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4185                 t = md->paramtypes[i].type;
4186
4187                 if (IS_INT_LNG_TYPE(t)) {
4188                         if (!md->params[i].inmemory) {
4189                                 s1 = rd->argintregs[md->params[i].regoff];
4190
4191                                 if (!nmd->params[j].inmemory) {
4192                                         s2 = rd->argintregs[nmd->params[j].regoff];
4193                                         M_INTMOVE(s1, s2);
4194                                 } else {
4195                                         s2 = nmd->params[j].regoff;
4196                                         M_AST(s1, REG_SP, s2 * 8);
4197                                 }
4198
4199                         } else {
4200                                 s1 = md->params[i].regoff + stackframesize;
4201                                 s2 = nmd->params[j].regoff;
4202                                 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
4203                                 M_AST(REG_ITMP1, REG_SP, s2 * 8);
4204                         }
4205
4206                 } else {
4207                         if (!md->params[i].inmemory) {
4208                                 s1 = rd->argfltregs[md->params[i].regoff];
4209
4210                                 if (!nmd->params[j].inmemory) {
4211                                         s2 = rd->argfltregs[nmd->params[j].regoff];
4212                                         if (IS_2_WORD_TYPE(t))
4213                                                 M_DMOV(s1, s2);
4214                                         else
4215                                                 M_FMOV(s1, s2);
4216
4217                                 } else {
4218                                         s2 = nmd->params[j].regoff;
4219                                         if (IS_2_WORD_TYPE(t))
4220                                                 M_DST(s1, REG_SP, s2 * 8);
4221                                         else
4222                                                 M_FST(s1, REG_SP, s2 * 8);
4223                                 }
4224
4225                         } else {
4226                                 s1 = md->params[i].regoff + stackframesize;
4227                                 s2 = nmd->params[j].regoff;
4228                                 if (IS_2_WORD_TYPE(t)) {
4229                                         M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4230                                         M_DST(REG_FTMP1, REG_SP, s2 * 8);
4231                                 } else {
4232                                         M_FLD(REG_FTMP1, REG_SP, s1 * 8);
4233                                         M_FST(REG_FTMP1, REG_SP, s2 * 8);
4234                                 }
4235                         }
4236                 }
4237         }
4238
4239         /* put class into second argument register */
4240
4241         if (m->flags & ACC_STATIC) {
4242                 disp = dseg_addaddress(cd, m->class);
4243                 M_ALD(rd->argintregs[1], REG_PV, disp);
4244         }
4245
4246         /* put env into first argument register */
4247
4248         disp = dseg_addaddress(cd, _Jv_env);
4249         M_ALD(rd->argintregs[0], REG_PV, disp);
4250
4251         /* do the native function call */
4252
4253         M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method       */
4254         M_JSR(REG_RA, REG_ITMP3);           /* call native method                 */
4255         M_NOP;                              /* delay slot                         */
4256
4257         /* save return value */
4258
4259         if (IS_INT_LNG_TYPE(md->returntype.type))
4260                 M_LST(REG_RESULT, REG_SP, 0 * 8);
4261         else
4262                 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4263
4264         /* remove native stackframe info */
4265
4266         M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4267         disp = dseg_addaddress(cd, codegen_finish_native_call);
4268         M_ALD(REG_ITMP3, REG_PV, disp);
4269         M_JSR(REG_RA, REG_ITMP3);
4270         M_NOP; /* XXX fill me! */
4271
4272         /* call finished trace function */
4273
4274         if (opt_verbosecall) {
4275                 if (IS_INT_LNG_TYPE(md->returntype.type))
4276                         M_LLD(REG_RESULT, REG_SP, 0 * 8);
4277                 else
4278                         M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4279
4280                 disp = dseg_addaddress(cd, m);
4281                 M_ALD(rd->argintregs[0], REG_PV, disp);
4282
4283                 M_MOV(REG_RESULT, rd->argintregs[1]);
4284                 M_DMFC1(REG_ITMP1, REG_FRESULT);
4285                 M_DMTC1(REG_ITMP1, rd->argfltregs[2]);
4286                 M_DMTC1(REG_ITMP1, rd->argfltregs[3]);
4287
4288                 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4289                 M_ALD(REG_ITMP3, REG_PV, disp);
4290                 M_JSR(REG_RA, REG_ITMP3);
4291                 M_NOP;
4292         }
4293
4294         /* check for exception */
4295
4296 #if defined(ENABLE_THREADS)
4297         disp = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4298         M_ALD(REG_ITMP3, REG_PV, disp);
4299         M_JSR(REG_RA, REG_ITMP3);
4300         M_NOP;
4301         M_MOV(REG_RESULT, REG_ITMP3);
4302 #else
4303         disp = dseg_addaddress(cd, &_exceptionptr);
4304         M_ALD(REG_ITMP3, REG_PV, disp);     /* get address of exceptionptr        */
4305 #endif
4306         M_ALD(REG_ITMP1, REG_ITMP3, 0);     /* load exception into reg. itmp1     */
4307
4308         M_ALD(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* load ra     */
4309
4310         /* restore return value */
4311
4312         if (IS_INT_LNG_TYPE(md->returntype.type))
4313                 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4314         else
4315                 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4316
4317         M_BNEZ(REG_ITMP1, 2);               /* if no exception then return        */
4318         M_LDA(REG_SP, REG_SP, stackframesize * 8);/* remove stackframe, DELAY SLOT*/
4319
4320         M_RET(REG_RA);                      /* return to caller                   */
4321         M_NOP;                              /* DELAY SLOT                         */
4322
4323         /* handle exception */
4324         
4325         M_AST(REG_ZERO, REG_ITMP3, 0);      /* store NULL into exceptionptr       */
4326
4327         disp = dseg_addaddress(cd, asm_handle_nat_exception);
4328         M_ALD(REG_ITMP3, REG_PV, disp);     /* load asm exception handler address */
4329         M_JMP(REG_ITMP3);                   /* jump to asm exception handler      */
4330         M_LDA(REG_ITMP2, REG_RA, -4);       /* move fault address into reg. itmp2 */
4331                                             /* DELAY SLOT                         */
4332
4333         /* generate static stub call code                                         */
4334
4335         {
4336                 patchref *pref;
4337                 u8        mcode;
4338                 u1       *savedmcodeptr;
4339                 u1       *tmpmcodeptr;
4340
4341                 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4342                         /* Get machine code which is patched back in later. The
4343                            call is 2 instruction words long. */
4344
4345                         tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
4346
4347                         /* We need to split this, because an unaligned 8 byte read
4348                            causes a SIGSEGV. */
4349
4350                         mcode = ((u8) ((u4 *) tmpmcodeptr)[1] << 32) +
4351                                 ((u4 *) tmpmcodeptr)[0];
4352
4353                         /* Patch in the call to call the following code (done at
4354                            compile time). */
4355
4356                         savedmcodeptr = cd->mcodeptr;   /* save current mcodeptr          */
4357                         cd->mcodeptr  = tmpmcodeptr;    /* set mcodeptr to patch position */
4358
4359                         disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1);
4360                         M_BRS(disp);
4361                         M_NOP;                          /* branch delay slot              */
4362
4363                         cd->mcodeptr = savedmcodeptr;   /* restore the current mcodeptr   */
4364
4365                         /* create stack frame                                             */
4366
4367                         M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4368
4369                         /* move return address onto stack */
4370
4371                         M_AST(REG_RA, REG_SP, 5 * 8);
4372
4373                         /* move pointer to java_objectheader onto stack */
4374
4375 #if defined(ENABLE_THREADS)
4376                         /* order reversed because of data segment layout */
4377
4378                         (void) dseg_addaddress(cd, NULL);                         /* flcword    */
4379                         (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
4380                         disp = dseg_addaddress(cd, NULL);                         /* vftbl      */
4381
4382                         M_LDA(REG_ITMP3, REG_PV, disp);
4383                         M_AST(REG_ITMP3, REG_SP, 4 * 8);
4384 #else
4385                         M_AST(REG_ZERO, REG_SP, 4 * 8);
4386 #endif
4387
4388                         /* move machine code onto stack */
4389
4390                         disp = dseg_adds8(cd, mcode);
4391                         M_LLD(REG_ITMP3, REG_PV, disp);
4392                         M_LST(REG_ITMP3, REG_SP, 3 * 8);
4393
4394                         /* move class/method/field reference onto stack */
4395
4396                         disp = dseg_addaddress(cd, pref->ref);
4397                         M_ALD(REG_ITMP3, REG_PV, disp);
4398                         M_AST(REG_ITMP3, REG_SP, 2 * 8);
4399
4400                         /* move data segment displacement onto stack */
4401
4402                         disp = dseg_adds4(cd, pref->disp);
4403                         M_ILD(REG_ITMP3, REG_PV, disp);
4404                         M_IST(REG_ITMP3, REG_SP, 1 * 8);
4405
4406                         /* move patcher function pointer onto stack */
4407
4408                         disp = dseg_addaddress(cd, pref->patcher);
4409                         M_ALD(REG_ITMP3, REG_PV, disp);
4410                         M_AST(REG_ITMP3, REG_SP, 0 * 8);
4411
4412                         disp = dseg_addaddress(cd, asm_wrapper_patcher);
4413                         M_ALD(REG_ITMP3, REG_PV, disp);
4414                         M_JMP(REG_ITMP3);
4415                         M_NOP;
4416                 }
4417         }
4418
4419         codegen_finish(jd);
4420
4421         return jd->code->entrypoint;
4422 }
4423
4424
4425 /*
4426  * These are local overrides for various environment variables in Emacs.
4427  * Please do not remove this and leave it at the end of the file, where
4428  * Emacs will automagically detect them.
4429  * ---------------------------------------------------------------------
4430  * Local variables:
4431  * mode: c
4432  * indent-tabs-mode: t
4433  * c-basic-offset: 4
4434  * tab-width: 4
4435  * End:
4436  * vim:noexpandtab:sw=4:ts=4:
4437  */