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