* src/vm/jit/i386/asmpart.S: Made position independent.
[cacao.git] / src / vm / jit / i386 / codegen.c
1 /* src/vm/jit/i386/codegen.c - machine code generator for i386
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 <stdint.h>
30 #include <stdio.h>
31
32 #include "vm/types.h"
33 #include "vm/os.hpp"
34
35 #include "vm/jit/i386/md-abi.h"
36
37 #include "vm/jit/i386/codegen.h"
38 #include "vm/jit/i386/emit.h"
39
40 #include "mm/memory.hpp"
41
42 #include "native/localref.hpp"
43 #include "native/native.hpp"
44
45 #include "threads/lock.hpp"
46
47 #include "vm/jit/builtin.hpp"
48 #include "vm/exceptions.hpp"
49 #include "vm/global.h"
50 #include "vm/loader.hpp"
51 #include "vm/options.h"
52 #include "vm/primitive.hpp"
53 #include "vm/utf8.h"
54 #include "vm/vm.hpp"
55
56 #include "vm/jit/abi.h"
57 #include "vm/jit/asmpart.h"
58 #include "vm/jit/codegen-common.hpp"
59 #include "vm/jit/dseg.h"
60 #include "vm/jit/emit-common.hpp"
61 #include "vm/jit/jit.hpp"
62 #include "vm/jit/linenumbertable.hpp"
63 #include "vm/jit/parse.hpp"
64 #include "vm/jit/patcher-common.hpp"
65 #include "vm/jit/reg.h"
66 #include "vm/jit/stacktrace.hpp"
67 #include "vm/jit/trap.hpp"
68
69
70 /**
71  * Generates machine code for the method prolog.
72  */
73 void codegen_emit_prolog(jitdata* jd)
74 {
75         varinfo*    var;
76         methoddesc* md;
77         int32_t     s1, d;
78         int32_t     p, t, l;
79         int32_t     varindex;
80         int         i;
81         int         align_off;
82
83         // Get required compiler data.
84         methodinfo*   m  = jd->m;
85         codegendata*  cd = jd->cd;
86         registerdata* rd = jd->rd;
87
88         /* create stack frame (if necessary) */
89
90         align_off = cd->stackframesize ? 4 : 0;
91
92         if (cd->stackframesize) {
93                 assert(align_off == 4);
94                 M_ASUB_IMM(cd->stackframesize * 8 + 4, REG_SP);
95         }
96
97         /* save return address and used callee saved registers */
98
99         p = cd->stackframesize;
100         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
101                 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
102         }
103         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
104                 p--; emit_fld_reg(cd, rd->savfltregs[i]); emit_fstpl_membase(cd, REG_SP, p * 8);
105         }
106
107         /* take arguments out of register or stack frame */
108
109         md = m->parseddesc;
110
111         for (p = 0, l = 0; p < md->paramcount; p++) {
112                 t = md->paramtypes[p].type;
113
114                 varindex = jd->local_map[l * 5 + t];
115 #if defined(ENABLE_SSA)
116                 if ( ls != NULL ) {
117                         if (varindex != UNUSED)
118                                 varindex = ls->var_0[varindex];
119                         if ((varindex != UNUSED) && (ls->lifetime[varindex].type == UNUSED))
120                                 varindex = UNUSED;
121                 }
122 #endif
123                 l++;
124                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
125                         l++;
126
127                 if (varindex == UNUSED)
128                         continue;
129
130                 var = VAR(varindex);
131                 s1  = md->params[p].regoff;
132                 d   = var->vv.regoff;
133
134                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
135                         if (!md->params[p].inmemory) {           /* register arguments    */
136                                 log_text("integer register argument");
137                                 assert(0);
138                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
139                                         /* rd->argintregs[md->params[p].regoff -> var->vv.regoff     */
140                                 } 
141                                 else {                               /* reg arg -> spilled    */
142                                         /* rd->argintregs[md->params[p].regoff -> var->vv.regoff * 4 */
143                                 }
144                         } 
145                         else {
146                                 if (!(var->flags & INMEMORY)) {
147                                         M_ILD(d, REG_SP,
148                                                   cd->stackframesize * 8 + 4 + align_off + s1);
149                                 } 
150                                 else {
151                                         if (!IS_2_WORD_TYPE(t)) {
152 #if defined(ENABLE_SSA)
153                                                 /* no copy avoiding by now possible with SSA */
154                                                 if (ls != NULL) {
155                                                         emit_mov_membase_reg(   /* + 4 for return address */
156                                                                 cd, REG_SP,
157                                                                 cd->stackframesize * 8 + s1 + 4 + align_off,
158                                                                 REG_ITMP1);    
159                                                         emit_mov_reg_membase(
160                                                                 cd, REG_ITMP1, REG_SP, var->vv.regoff);
161                                                 }
162                                                 else 
163 #endif /*defined(ENABLE_SSA)*/
164                                                         /* reuse stackslot */
165                                                         var->vv.regoff = cd->stackframesize * 8 + 4 +
166                                                                 align_off + s1;
167
168                                         } 
169                                         else {
170 #if defined(ENABLE_SSA)
171                                                 /* no copy avoiding by now possible with SSA */
172                                                 if (ls != NULL) {
173                                                         emit_mov_membase_reg(  /* + 4 for return address */
174                                                                 cd, REG_SP,
175                                                                 cd->stackframesize * 8 + s1 + 4 + align_off,
176                                                                 REG_ITMP1);
177                                                         emit_mov_reg_membase(
178                                                                 cd, REG_ITMP1, REG_SP, var->vv.regoff);
179                                                         emit_mov_membase_reg(   /* + 4 for return address */
180                                                                 cd, REG_SP,
181                                                                 cd->stackframesize * 8 + s1 + 4 + 4 + align_off,
182                                                                 REG_ITMP1);             
183                                                         emit_mov_reg_membase(
184                                                                 cd, REG_ITMP1, REG_SP, var->vv.regoff + 4);
185                                                 }
186                                                 else
187 #endif /*defined(ENABLE_SSA)*/
188                                                         /* reuse stackslot */
189                                                         var->vv.regoff = cd->stackframesize * 8 + 8 + s1;
190                                         }
191                                 }
192                         }
193                 }
194                 else {                                       /* floating args         */
195                         if (!md->params[p].inmemory) {           /* register arguments    */
196                                 log_text("There are no float argument registers!");
197                                 assert(0);
198                                 if (!(var->flags & INMEMORY)) {  /* reg arg -> register   */
199                                         /* rd->argfltregs[md->params[p].regoff -> var->vv.regoff     */
200                                 } else {                                     /* reg arg -> spilled    */
201                                         /* rd->argfltregs[md->params[p].regoff -> var->vv.regoff * 8 */
202                                 }
203
204                         } 
205                         else {                                   /* stack arguments       */
206                                 if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
207                                         if (t == TYPE_FLT) {
208                                                 emit_flds_membase(
209                             cd, REG_SP,
210                                                         cd->stackframesize * 8 + s1 + 4 + align_off);
211                                                 assert(0);
212 /*                                              emit_fstp_reg(cd, var->vv.regoff + fpu_st_offset); */
213
214                                         } 
215                                         else {
216                                                 emit_fldl_membase(
217                             cd, REG_SP,
218                                                         cd->stackframesize * 8 + s1 + 4 + align_off);
219                                                 assert(0);
220 /*                                              emit_fstp_reg(cd, var->vv.regoff + fpu_st_offset); */
221                                         }
222
223                                 } else {                             /* stack-arg -> spilled  */
224 #if defined(ENABLE_SSA)
225                                         /* no copy avoiding by now possible with SSA */
226                                         if (ls != NULL) {
227                                                 emit_mov_membase_reg(
228                                                         cd, REG_SP,
229                                                         cd->stackframesize * 8 + s1 + 4 + align_off,
230                                                         REG_ITMP1);
231                                                 emit_mov_reg_membase(
232                                                         cd, REG_ITMP1, REG_SP, var->vv.regoff);
233                                                 if (t == TYPE_FLT) {
234                                                         emit_flds_membase(
235                                                                 cd, REG_SP,
236                                                                 cd->stackframesize * 8 + s1 + 4 + align_off);
237                                                         emit_fstps_membase(cd, REG_SP, var->vv.regoff);
238                                                 } 
239                                                 else {
240                                                         emit_fldl_membase(
241                                                                 cd, REG_SP,
242                                                                 cd->stackframesize * 8 + s1 + 4 + align_off);
243                                                         emit_fstpl_membase(cd, REG_SP, var->vv.regoff);
244                                                 }
245                                         }
246                                         else
247 #endif /*defined(ENABLE_SSA)*/
248                                                 /* reuse stackslot */
249                                                 var->vv.regoff = cd->stackframesize * 8 + 4 +
250                                                         align_off + s1;
251                                 }
252                         }
253                 }
254         }
255 }
256
257
258 /**
259  * Generates machine code for the method epilog.
260  */
261 void codegen_emit_epilog(jitdata* jd)
262 {
263         methoddesc* md;
264         int32_t p;
265         int i;
266
267         // Get required compiler data.
268         methodinfo*   m  = jd->m;
269         codegendata*  cd = jd->cd;
270         registerdata* rd = jd->rd;
271
272         p = cd->stackframesize;
273         md = m->parseddesc;
274
275         /* restore saved registers */
276
277         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
278                 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
279         }
280
281         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
282                 p--;
283                 emit_fldl_membase(cd, REG_SP, p * 8);
284                 if (md->returntype.type == TYPE_FLT || md->returntype.type == TYPE_DBL) {
285                         assert(0);
286 /*                      emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */
287                 } else {
288                         assert(0);
289 /*                      emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */
290                 }
291         }
292
293         /* deallocate stack */
294
295         if (cd->stackframesize)
296                 M_AADD_IMM(cd->stackframesize * 8 + 4, REG_SP);
297
298         M_RET;
299 }
300
301
302 /**
303  * Generates machine code for one ICMD.
304  */
305 void codegen_emit_instruction(jitdata* jd, instruction* iptr)
306 {
307         varinfo*            var;
308         varinfo*            var1;
309         builtintable_entry* bte;
310         methodinfo*         lm;             // Local methodinfo for ICMD_INVOKE*.
311         unresolved_method*  um;
312         fieldinfo*          fi;
313         unresolved_field*   uf;
314         int32_t             fieldtype;
315         int32_t             s1, s2, s3, d;
316         int32_t             disp;
317
318         // Get required compiler data.
319         codegendata* cd = jd->cd;
320
321         switch (iptr->opc) {
322
323                 /* constant operations ************************************************/
324
325                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
326
327                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
328                         if (iptr->sx.val.f == 0.0) {
329                                 emit_fldz(cd);
330
331                                 /* -0.0 */
332                                 if (iptr->sx.val.i == 0x80000000) {
333                                         emit_fchs(cd);
334                                 }
335
336                         } else if (iptr->sx.val.f == 1.0) {
337                                 emit_fld1(cd);
338
339                         } else if (iptr->sx.val.f == 2.0) {
340                                 emit_fld1(cd);
341                                 emit_fld1(cd);
342                                 emit_faddp(cd);
343
344                         } else {
345                                 disp = dseg_add_float(cd, iptr->sx.val.f);
346                                 emit_mov_imm_reg(cd, 0, REG_ITMP1);
347                                 dseg_adddata(cd);
348                                 emit_flds_membase(cd, REG_ITMP1, disp);
349                         }
350                         emit_store_dst(jd, iptr, d);
351                         break;
352                 
353                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
354
355                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
356                         if (iptr->sx.val.d == 0.0) {
357                                 emit_fldz(cd);
358
359                                 /* -0.0 */
360                                 if (iptr->sx.val.l == 0x8000000000000000LL) {
361                                         emit_fchs(cd);
362                                 }
363
364                         } else if (iptr->sx.val.d == 1.0) {
365                                 emit_fld1(cd);
366
367                         } else if (iptr->sx.val.d == 2.0) {
368                                 emit_fld1(cd);
369                                 emit_fld1(cd);
370                                 emit_faddp(cd);
371
372                         } else {
373                                 disp = dseg_add_double(cd, iptr->sx.val.d);
374                                 emit_mov_imm_reg(cd, 0, REG_ITMP1);
375                                 dseg_adddata(cd);
376                                 emit_fldl_membase(cd, REG_ITMP1, disp);
377                         }
378                         emit_store_dst(jd, iptr, d);
379                         break;
380
381                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
382
383                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
384
385                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
386                                 patcher_add_patch_ref(jd, PATCHER_aconst,
387                                                                         iptr->sx.val.c.ref, 0);
388
389                                 M_MOV_IMM2(NULL, d);
390
391                         } else {
392                                 if (iptr->sx.val.anyptr == NULL)
393                                         M_CLR(d);
394                                 else
395                                         M_MOV_IMM(iptr->sx.val.anyptr, d);
396                         }
397                         emit_store_dst(jd, iptr, d);
398                         break;
399
400
401                 /* integer operations *************************************************/
402
403                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
404
405                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
406                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
407                         M_INTMOVE(s1, d);
408                         M_NEG(d);
409                         emit_store_dst(jd, iptr, d);
410                         break;
411
412                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
413
414                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
415                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
416                         M_LNGMOVE(s1, d);
417                         M_NEG(GET_LOW_REG(d));
418                         M_IADDC_IMM(0, GET_HIGH_REG(d));
419                         M_NEG(GET_HIGH_REG(d));
420                         emit_store_dst(jd, iptr, d);
421                         break;
422
423                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
424
425                         s1 = emit_load_s1(jd, iptr, EAX);
426                         d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
427                         M_INTMOVE(s1, EAX);
428                         M_CLTD;
429                         M_LNGMOVE(EAX_EDX_PACKED, d);
430                         emit_store_dst(jd, iptr, d);
431                         break;
432
433                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
434
435                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
436                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
437                         M_INTMOVE(s1, d);
438                         emit_store_dst(jd, iptr, d);
439                         break;
440
441                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
442
443                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
444                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
445                         M_INTMOVE(s1, d);
446                         M_SLL_IMM(24, d);
447                         M_SRA_IMM(24, d);
448                         emit_store_dst(jd, iptr, d);
449                         break;
450
451                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
452
453                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
454                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
455                         M_CZEXT(s1, d);
456                         emit_store_dst(jd, iptr, d);
457                         break;
458
459                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
460
461                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
462                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
463                         M_SSEXT(s1, d);
464                         emit_store_dst(jd, iptr, d);
465                         break;
466
467
468                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
469
470                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
471                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
472                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
473                         if (s2 == d)
474                                 M_IADD(s1, d);
475                         else {
476                                 M_INTMOVE(s1, d);
477                                 M_IADD(s2, d);
478                         }
479                         emit_store_dst(jd, iptr, d);
480                         break;
481
482                 case ICMD_IINC:
483                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
484                                       /* sx.val.i = constant                          */
485
486                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
487                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
488                                 
489                         /* `inc reg' is slower on p4's (regarding to ia32
490                            optimization reference manual and benchmarks) and as
491                            fast on athlon's. */
492
493                         M_INTMOVE(s1, d);
494                         M_IADD_IMM(iptr->sx.val.i, d);
495                         emit_store_dst(jd, iptr, d);
496                         break;
497
498                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
499
500                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
501                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
502                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
503                         M_INTMOVE(s1, GET_LOW_REG(d));
504                         M_IADD(s2, GET_LOW_REG(d));
505                         /* don't use REG_ITMP1 */
506                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
507                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
508                         M_INTMOVE(s1, GET_HIGH_REG(d));
509                         M_IADDC(s2, GET_HIGH_REG(d));
510                         emit_store_dst(jd, iptr, d);
511                         break;
512
513                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
514                                       /* sx.val.l = constant                          */
515
516                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
517                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
518                         M_LNGMOVE(s1, d);
519                         M_IADD_IMM(iptr->sx.val.l, GET_LOW_REG(d));
520                         M_IADDC_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
521                         emit_store_dst(jd, iptr, d);
522                         break;
523
524                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
525
526                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
527                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
528                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
529                         if (s2 == d) {
530                                 M_INTMOVE(s1, REG_ITMP1);
531                                 M_ISUB(s2, REG_ITMP1);
532                                 M_INTMOVE(REG_ITMP1, d);
533                         }
534                         else {
535                                 M_INTMOVE(s1, d);
536                                 M_ISUB(s2, d);
537                         }
538                         emit_store_dst(jd, iptr, d);
539                         break;
540
541                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
542                                       /* sx.val.i = constant                             */
543
544                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
545                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
546                         M_INTMOVE(s1, d);
547                         M_ISUB_IMM(iptr->sx.val.i, d);
548                         emit_store_dst(jd, iptr, d);
549                         break;
550
551                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
552
553                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
554                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
555                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
556                         if (s2 == GET_LOW_REG(d)) {
557                                 M_INTMOVE(s1, REG_ITMP1);
558                                 M_ISUB(s2, REG_ITMP1);
559                                 M_INTMOVE(REG_ITMP1, GET_LOW_REG(d));
560                         }
561                         else {
562                                 M_INTMOVE(s1, GET_LOW_REG(d));
563                                 M_ISUB(s2, GET_LOW_REG(d));
564                         }
565                         /* don't use REG_ITMP1 */
566                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
567                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
568                         if (s2 == GET_HIGH_REG(d)) {
569                                 M_INTMOVE(s1, REG_ITMP2);
570                                 M_ISUBB(s2, REG_ITMP2);
571                                 M_INTMOVE(REG_ITMP2, GET_HIGH_REG(d));
572                         }
573                         else {
574                                 M_INTMOVE(s1, GET_HIGH_REG(d));
575                                 M_ISUBB(s2, GET_HIGH_REG(d));
576                         }
577                         emit_store_dst(jd, iptr, d);
578                         break;
579
580                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
581                                       /* sx.val.l = constant                          */
582
583                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
584                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
585                         M_LNGMOVE(s1, d);
586                         M_ISUB_IMM(iptr->sx.val.l, GET_LOW_REG(d));
587                         M_ISUBB_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
588                         emit_store_dst(jd, iptr, d);
589                         break;
590
591                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
592
593                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
594                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
595                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
596                         if (s2 == d)
597                                 M_IMUL(s1, d);
598                         else {
599                                 M_INTMOVE(s1, d);
600                                 M_IMUL(s2, d);
601                         }
602                         emit_store_dst(jd, iptr, d);
603                         break;
604
605                 case ICMD_IMULCONST:  /* ..., 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_IMUL_IMM(s1, iptr->sx.val.i, d);
611                         emit_store_dst(jd, iptr, d);
612                         break;
613
614                 case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
615
616                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
617                         s2 = emit_load_s2_low(jd, iptr, EDX);
618                         d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
619
620                         M_INTMOVE(s1, REG_ITMP2);
621                         M_IMUL(s2, REG_ITMP2);
622
623                         s1 = emit_load_s1_low(jd, iptr, EAX);
624                         s2 = emit_load_s2_high(jd, iptr, EDX);
625                         M_INTMOVE(s2, EDX);
626                         M_IMUL(s1, EDX);
627                         M_IADD(EDX, REG_ITMP2);
628
629                         s1 = emit_load_s1_low(jd, iptr, EAX);
630                         s2 = emit_load_s2_low(jd, iptr, EDX);
631                         M_INTMOVE(s1, EAX);
632                         M_MUL(s2);
633                         M_INTMOVE(EAX, GET_LOW_REG(d));
634                         M_IADD(REG_ITMP2, GET_HIGH_REG(d));
635
636                         emit_store_dst(jd, iptr, d);
637                         break;
638
639                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
640                                       /* sx.val.l = constant                          */
641
642                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
643                         d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
644                         ICONST(EAX, iptr->sx.val.l);
645                         M_MUL(s1);
646                         M_IMUL_IMM(s1, iptr->sx.val.l >> 32, REG_ITMP2);
647                         M_IADD(REG_ITMP2, EDX);
648                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
649                         M_IMUL_IMM(s1, iptr->sx.val.l, REG_ITMP2);
650                         M_IADD(REG_ITMP2, EDX);
651                         M_LNGMOVE(EAX_EDX_PACKED, d);
652                         emit_store_dst(jd, iptr, d);
653                         break;
654
655                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
656
657                         s1 = emit_load_s1(jd, iptr, EAX);
658                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
659                         d = codegen_reg_of_dst(jd, iptr, EAX);
660                         emit_arithmetic_check(cd, iptr, s2);
661
662                         M_INTMOVE(s1, EAX);           /* we need the first operand in EAX */
663
664                         /* check as described in jvm spec */
665
666                         M_CMP_IMM(0x80000000, EAX);
667                         M_BNE(3 + 6);
668                         M_CMP_IMM(-1, s2);
669                         M_BEQ(1 + 2);
670                         M_CLTD;
671                         M_IDIV(s2);
672
673                         M_INTMOVE(EAX, d);           /* if INMEMORY then d is already EAX */
674                         emit_store_dst(jd, iptr, d);
675                         break;
676
677                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
678
679                         s1 = emit_load_s1(jd, iptr, EAX);
680                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
681                         d = codegen_reg_of_dst(jd, iptr, EDX);
682                         emit_arithmetic_check(cd, iptr, s2);
683
684                         M_INTMOVE(s1, EAX);           /* we need the first operand in EAX */
685
686                         /* check as described in jvm spec */
687
688                         M_CMP_IMM(0x80000000, EAX);
689                         M_BNE(2 + 3 + 6);
690                         M_CLR(EDX);
691                         M_CMP_IMM(-1, s2);
692                         M_BEQ(1 + 2);
693                         M_CLTD;
694                         M_IDIV(s2);
695
696                         M_INTMOVE(EDX, d);           /* if INMEMORY then d is already EDX */
697                         emit_store_dst(jd, iptr, d);
698                         break;
699
700                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
701                                       /* sx.val.i = constant                          */
702
703                         /* TODO: optimize for `/ 2' */
704                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
705                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
706                         M_INTMOVE(s1, d);
707                         M_TEST(d);
708                         M_BNS(6);
709                         M_IADD_IMM32((1 << iptr->sx.val.i) - 1, d);/* 32-bit for jump off */
710                         M_SRA_IMM(iptr->sx.val.i, d);
711                         emit_store_dst(jd, iptr, d);
712                         break;
713
714                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
715                                       /* sx.val.i = constant                          */
716
717                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
718                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
719                         if (s1 == d) {
720                                 M_MOV(s1, REG_ITMP1);
721                                 s1 = REG_ITMP1;
722                         } 
723                         M_INTMOVE(s1, d);
724                         M_AND_IMM(iptr->sx.val.i, d);
725                         M_TEST(s1);
726                         M_BGE(2 + 2 + 6 + 2);
727                         M_MOV(s1, d);  /* don't use M_INTMOVE, so we know the jump offset */
728                         M_NEG(d);
729                         M_AND_IMM32(iptr->sx.val.i, d);     /* use 32-bit for jump offset */
730                         M_NEG(d);
731                         emit_store_dst(jd, iptr, d);
732                         break;
733
734                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
735                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
736
737                         s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
738                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
739
740                         M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
741                         M_OR(GET_HIGH_REG(s2), REG_ITMP3);
742                         /* XXX could be optimized */
743                         emit_arithmetic_check(cd, iptr, REG_ITMP3);
744
745                         bte = iptr->sx.s23.s3.bte;
746
747                         M_LST(s2, REG_SP, 2 * 4);
748
749                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
750                         M_LST(s1, REG_SP, 0 * 4);
751
752                         M_MOV_IMM(bte->fp, REG_ITMP3);
753                         M_CALL(REG_ITMP3);
754                         emit_store_dst(jd, iptr, d);
755                         break;
756
757                 case ICMD_LDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
758                                       /* sx.val.i = constant                          */
759
760                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
761                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
762                         M_LNGMOVE(s1, d);
763                         M_TEST(GET_HIGH_REG(d));
764                         M_BNS(6 + 3);
765                         M_IADD_IMM32((1 << iptr->sx.val.i) - 1, GET_LOW_REG(d));
766                         M_IADDC_IMM(0, GET_HIGH_REG(d));
767                         M_SRLD_IMM(iptr->sx.val.i, GET_HIGH_REG(d), GET_LOW_REG(d));
768                         M_SRA_IMM(iptr->sx.val.i, GET_HIGH_REG(d));
769                         emit_store_dst(jd, iptr, d);
770                         break;
771
772 #if 0
773                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
774                                       /* sx.val.l = constant                          */
775
776                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
777                         if (iptr->dst.var->flags & INMEMORY) {
778                                 if (iptr->s1.var->flags & INMEMORY) {
779                                         /* Alpha algorithm */
780                                         disp = 3;
781                                         CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->vv.regoff * 8);
782                                         disp += 3;
783                                         CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->vv.regoff * 8 + 4);
784
785                                         disp += 2;
786                                         disp += 3;
787                                         disp += 2;
788
789                                         /* TODO: hmm, don't know if this is always correct */
790                                         disp += 2;
791                                         CALCIMMEDIATEBYTES(disp, iptr->sx.val.l & 0x00000000ffffffff);
792                                         disp += 2;
793                                         CALCIMMEDIATEBYTES(disp, iptr->sx.val.l >> 32);
794
795                                         disp += 2;
796                                         disp += 3;
797                                         disp += 2;
798
799                                         emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 8, REG_ITMP1);
800                                         emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 8 + 4, REG_ITMP2);
801                                         
802                                         emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
803                                         emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
804                                         emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->s1.var->vv.regoff * 8 + 4);
805                                         emit_jcc(cd, CC_GE, disp);
806
807                                         emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 8, REG_ITMP1);
808                                         emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 8 + 4, REG_ITMP2);
809                                         
810                                         emit_neg_reg(cd, REG_ITMP1);
811                                         emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
812                                         emit_neg_reg(cd, REG_ITMP2);
813                                         
814                                         emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
815                                         emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
816                                         
817                                         emit_neg_reg(cd, REG_ITMP1);
818                                         emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
819                                         emit_neg_reg(cd, REG_ITMP2);
820
821                                         emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst.var->vv.regoff * 8);
822                                         emit_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst.var->vv.regoff * 8 + 4);
823                                 }
824                         }
825
826                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
827                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
828                         M_LNGMOVE(s1, d);
829                         M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));      
830                         M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
831                         M_TEST(GET_LOW_REG(s1));
832                         M_BGE(0);
833                         M_LNGMOVE(s1, d);
834                 break;
835 #endif
836
837                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
838
839                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
840                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
841                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
842                         M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
843                         M_INTMOVE(s1, d);
844                         M_SLL(d);
845                         emit_store_dst(jd, iptr, d);
846                         break;
847
848                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
849                                       /* sx.val.i = constant                          */
850
851                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
852                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
853                         M_INTMOVE(s1, d);
854                         M_SLL_IMM(iptr->sx.val.i, d);
855                         emit_store_dst(jd, iptr, d);
856                         break;
857
858                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
859
860                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
861                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
862                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
863                         M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
864                         M_INTMOVE(s1, d);
865                         M_SRA(d);
866                         emit_store_dst(jd, iptr, d);
867                         break;
868
869                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
870                                       /* sx.val.i = constant                          */
871
872                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
873                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
874                         M_INTMOVE(s1, d);
875                         M_SRA_IMM(iptr->sx.val.i, d);
876                         emit_store_dst(jd, iptr, d);
877                         break;
878
879                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
880
881                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
882                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
883                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
884                         M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
885                         M_INTMOVE(s1, d);
886                         M_SRL(d);
887                         emit_store_dst(jd, iptr, d);
888                         break;
889
890                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
891                                       /* sx.val.i = constant                          */
892
893                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
894                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
895                         M_INTMOVE(s1, d);
896                         M_SRL_IMM(iptr->sx.val.i, d);
897                         emit_store_dst(jd, iptr, d);
898                         break;
899
900                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
901
902                         s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
903                         s2 = emit_load_s2(jd, iptr, ECX);
904                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
905                         M_LNGMOVE(s1, d);
906                         M_INTMOVE(s2, ECX);
907                         M_TEST_IMM(32, ECX);
908                         M_BEQ(2 + 2);
909                         M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
910                         M_CLR(GET_LOW_REG(d));
911                         M_SLLD(GET_LOW_REG(d), GET_HIGH_REG(d));
912                         M_SLL(GET_LOW_REG(d));
913                         emit_store_dst(jd, iptr, d);
914                         break;
915
916         case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
917                                           /* sx.val.i = constant                          */
918
919                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
920                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
921                         M_LNGMOVE(s1, d);
922                         if (iptr->sx.val.i & 0x20) {
923                                 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
924                                 M_CLR(GET_LOW_REG(d));
925                                 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d), 
926                                                    GET_HIGH_REG(d));
927                         }
928                         else {
929                                 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d),
930                                                    GET_HIGH_REG(d));
931                                 M_SLL_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d));
932                         }
933                         emit_store_dst(jd, iptr, d);
934                         break;
935
936                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
937
938                         s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
939                         s2 = emit_load_s2(jd, iptr, ECX);
940                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
941                         M_LNGMOVE(s1, d);
942                         M_INTMOVE(s2, ECX);
943                         M_TEST_IMM(32, ECX);
944                         M_BEQ(2 + 3);
945                         M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
946                         M_SRA_IMM(31, GET_HIGH_REG(d));
947                         M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
948                         M_SRA(GET_HIGH_REG(d));
949                         emit_store_dst(jd, iptr, d);
950                         break;
951
952                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
953                                       /* sx.val.i = constant                          */
954
955                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
956                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
957                         M_LNGMOVE(s1, d);
958                         if (iptr->sx.val.i & 0x20) {
959                                 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
960                                 M_SRA_IMM(31, GET_HIGH_REG(d));
961                                 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
962                                                    GET_LOW_REG(d));
963                         }
964                         else {
965                                 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
966                                                    GET_LOW_REG(d));
967                                 M_SRA_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
968                         }
969                         emit_store_dst(jd, iptr, d);
970                         break;
971
972                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
973
974                         s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
975                         s2 = emit_load_s2(jd, iptr, ECX);
976                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
977                         M_LNGMOVE(s1, d);
978                         M_INTMOVE(s2, ECX);
979                         M_TEST_IMM(32, ECX);
980                         M_BEQ(2 + 2);
981                         M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
982                         M_CLR(GET_HIGH_REG(d));
983                         M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
984                         M_SRL(GET_HIGH_REG(d));
985                         emit_store_dst(jd, iptr, d);
986                         break;
987
988                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
989                                       /* sx.val.l = constant                          */
990
991                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
992                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
993                         M_LNGMOVE(s1, d);
994                         if (iptr->sx.val.i & 0x20) {
995                                 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
996                                 M_CLR(GET_HIGH_REG(d));
997                                 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
998                                                    GET_LOW_REG(d));
999                         }
1000                         else {
1001                                 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
1002                                                    GET_LOW_REG(d));
1003                                 M_SRL_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
1004                         }
1005                         emit_store_dst(jd, iptr, d);
1006                         break;
1007
1008                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1009
1010                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1011                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1012                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1013                         if (s2 == d)
1014                                 M_AND(s1, d);
1015                         else {
1016                                 M_INTMOVE(s1, d);
1017                                 M_AND(s2, d);
1018                         }
1019                         emit_store_dst(jd, iptr, d);
1020                         break;
1021
1022                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
1023                                       /* sx.val.i = constant                          */
1024
1025                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1026                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1027                         M_INTMOVE(s1, d);
1028                         M_AND_IMM(iptr->sx.val.i, d);
1029                         emit_store_dst(jd, iptr, d);
1030                         break;
1031
1032                 case ICMD_LAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1033
1034                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1035                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1036                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1037                         if (s2 == GET_LOW_REG(d))
1038                                 M_AND(s1, GET_LOW_REG(d));
1039                         else {
1040                                 M_INTMOVE(s1, GET_LOW_REG(d));
1041                                 M_AND(s2, GET_LOW_REG(d));
1042                         }
1043                         /* REG_ITMP1 probably contains low 32-bit of destination */
1044                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1045                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1046                         if (s2 == GET_HIGH_REG(d))
1047                                 M_AND(s1, GET_HIGH_REG(d));
1048                         else {
1049                                 M_INTMOVE(s1, GET_HIGH_REG(d));
1050                                 M_AND(s2, GET_HIGH_REG(d));
1051                         }
1052                         emit_store_dst(jd, iptr, d);
1053                         break;
1054
1055                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
1056                                       /* sx.val.l = constant                          */
1057
1058                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1059                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1060                         M_LNGMOVE(s1, d);
1061                         M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1062                         M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1063                         emit_store_dst(jd, iptr, d);
1064                         break;
1065
1066                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1067
1068                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1069                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1070                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1071                         if (s2 == d)
1072                                 M_OR(s1, d);
1073                         else {
1074                                 M_INTMOVE(s1, d);
1075                                 M_OR(s2, d);
1076                         }
1077                         emit_store_dst(jd, iptr, d);
1078                         break;
1079
1080                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
1081                                       /* sx.val.i = constant                          */
1082
1083                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1084                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1085                         M_INTMOVE(s1, d);
1086                         M_OR_IMM(iptr->sx.val.i, d);
1087                         emit_store_dst(jd, iptr, d);
1088                         break;
1089
1090                 case ICMD_LOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1091
1092                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1093                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1094                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1095                         if (s2 == GET_LOW_REG(d))
1096                                 M_OR(s1, GET_LOW_REG(d));
1097                         else {
1098                                 M_INTMOVE(s1, GET_LOW_REG(d));
1099                                 M_OR(s2, GET_LOW_REG(d));
1100                         }
1101                         /* REG_ITMP1 probably contains low 32-bit of destination */
1102                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1103                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1104                         if (s2 == GET_HIGH_REG(d))
1105                                 M_OR(s1, GET_HIGH_REG(d));
1106                         else {
1107                                 M_INTMOVE(s1, GET_HIGH_REG(d));
1108                                 M_OR(s2, GET_HIGH_REG(d));
1109                         }
1110                         emit_store_dst(jd, iptr, d);
1111                         break;
1112
1113                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
1114                                       /* sx.val.l = constant                          */
1115
1116                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1117                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1118                         M_LNGMOVE(s1, d);
1119                         M_OR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1120                         M_OR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1121                         emit_store_dst(jd, iptr, d);
1122                         break;
1123
1124                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1125
1126                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1127                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1128                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1129                         if (s2 == d)
1130                                 M_XOR(s1, d);
1131                         else {
1132                                 M_INTMOVE(s1, d);
1133                                 M_XOR(s2, d);
1134                         }
1135                         emit_store_dst(jd, iptr, d);
1136                         break;
1137
1138                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1139                                       /* sx.val.i = constant                          */
1140
1141                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1142                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1143                         M_INTMOVE(s1, d);
1144                         M_XOR_IMM(iptr->sx.val.i, d);
1145                         emit_store_dst(jd, iptr, d);
1146                         break;
1147
1148                 case ICMD_LXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1149
1150                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1151                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1152                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1153                         if (s2 == GET_LOW_REG(d))
1154                                 M_XOR(s1, GET_LOW_REG(d));
1155                         else {
1156                                 M_INTMOVE(s1, GET_LOW_REG(d));
1157                                 M_XOR(s2, GET_LOW_REG(d));
1158                         }
1159                         /* REG_ITMP1 probably contains low 32-bit of destination */
1160                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1161                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1162                         if (s2 == GET_HIGH_REG(d))
1163                                 M_XOR(s1, GET_HIGH_REG(d));
1164                         else {
1165                                 M_INTMOVE(s1, GET_HIGH_REG(d));
1166                                 M_XOR(s2, GET_HIGH_REG(d));
1167                         }
1168                         emit_store_dst(jd, iptr, d);
1169                         break;
1170
1171                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1172                                       /* sx.val.l = constant                          */
1173
1174                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1175                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1176                         M_LNGMOVE(s1, d);
1177                         M_XOR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1178                         M_XOR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1179                         emit_store_dst(jd, iptr, d);
1180                         break;
1181
1182
1183                 /* floating operations ************************************************/
1184
1185                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
1186
1187                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1188                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1189                         emit_fchs(cd);
1190                         emit_store_dst(jd, iptr, d);
1191                         break;
1192
1193                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
1194
1195                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1196                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1197                         emit_fchs(cd);
1198                         emit_store_dst(jd, iptr, d);
1199                         break;
1200
1201                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1202
1203                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1204                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1205                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1206                         emit_faddp(cd);
1207                         emit_store_dst(jd, iptr, d);
1208                         break;
1209
1210                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1211
1212                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1213                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1214                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1215                         emit_faddp(cd);
1216                         emit_store_dst(jd, iptr, d);
1217                         break;
1218
1219                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1220
1221                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1222                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1223                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1224                         emit_fsubp(cd);
1225                         emit_store_dst(jd, iptr, d);
1226                         break;
1227
1228                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1229
1230                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1231                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1232                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1233                         emit_fsubp(cd);
1234                         emit_store_dst(jd, iptr, d);
1235                         break;
1236
1237                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1238
1239                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1240                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1241                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1242                         emit_fmulp(cd);
1243                         emit_store_dst(jd, iptr, d);
1244                         break;
1245
1246                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1247
1248                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1249                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1250                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1251                         emit_fmulp(cd);
1252                         emit_store_dst(jd, iptr, d);
1253                         break;
1254
1255                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1256
1257                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1258                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1259                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1260                         emit_fdivp(cd);
1261                         emit_store_dst(jd, iptr, d);
1262                         break;
1263
1264                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1265
1266                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1267                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1268                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1269                         emit_fdivp(cd);
1270                         emit_store_dst(jd, iptr, d);
1271                         break;
1272
1273                 case ICMD_FREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1274
1275                         /* exchanged to skip fxch */
1276                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1277                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1278                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1279 /*                      emit_fxch(cd); */
1280                         emit_fprem(cd);
1281                         emit_wait(cd);
1282                         emit_fnstsw(cd);
1283                         emit_sahf(cd);
1284                         emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1285                         emit_store_dst(jd, iptr, d);
1286                         emit_ffree_reg(cd, 0);
1287                         emit_fincstp(cd);
1288                         break;
1289
1290                 case ICMD_DREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1291
1292                         /* exchanged to skip fxch */
1293                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1294                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1295                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1296 /*                      emit_fxch(cd); */
1297                         emit_fprem(cd);
1298                         emit_wait(cd);
1299                         emit_fnstsw(cd);
1300                         emit_sahf(cd);
1301                         emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1302                         emit_store_dst(jd, iptr, d);
1303                         emit_ffree_reg(cd, 0);
1304                         emit_fincstp(cd);
1305                         break;
1306
1307                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
1308                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
1309
1310                         var = VAROP(iptr->s1);
1311                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1312
1313                         if (var->flags & INMEMORY) {
1314                                 emit_fildl_membase(cd, REG_SP, var->vv.regoff);
1315                         } else {
1316                                 /* XXX not thread safe! */
1317                                 disp = dseg_add_unique_s4(cd, 0);
1318                                 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1319                                 dseg_adddata(cd);
1320                                 emit_mov_reg_membase(cd, var->vv.regoff, REG_ITMP1, disp);
1321                                 emit_fildl_membase(cd, REG_ITMP1, disp);
1322                         }
1323
1324                         emit_store_dst(jd, iptr, d);
1325                         break;
1326
1327                 case ICMD_L2F:       /* ..., value  ==> ..., (float) value            */
1328                 case ICMD_L2D:       /* ..., value  ==> ..., (double) value           */
1329
1330                         var = VAROP(iptr->s1);
1331                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1332                         if (var->flags & INMEMORY) {
1333                                 emit_fildll_membase(cd, REG_SP, var->vv.regoff);
1334
1335                         } else {
1336                                 log_text("L2F: longs have to be in memory");
1337                                 assert(0);
1338                         }
1339                         emit_store_dst(jd, iptr, d);
1340                         break;
1341                         
1342                 case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
1343
1344                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1345                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1346
1347                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
1348                         dseg_adddata(cd);
1349
1350                         /* Round to zero, 53-bit mode, exception masked */
1351                         disp = dseg_add_s4(cd, 0x0e7f);
1352                         emit_fldcw_membase(cd, REG_ITMP1, disp);
1353
1354                         var = VAROP(iptr->dst);
1355                         var1 = VAROP(iptr->s1);
1356
1357                         if (var->flags & INMEMORY) {
1358                                 emit_fistpl_membase(cd, REG_SP, var->vv.regoff);
1359
1360                                 /* Round to nearest, 53-bit mode, exceptions masked */
1361                                 disp = dseg_add_s4(cd, 0x027f);
1362                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1363
1364                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, 
1365                                                                          REG_SP, var->vv.regoff);
1366
1367                                 disp = 3;
1368                                 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1369                                 disp += 5 + 2 + 3;
1370                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1371
1372                         } else {
1373                                 /* XXX not thread safe! */
1374                                 disp = dseg_add_unique_s4(cd, 0);
1375                                 emit_fistpl_membase(cd, REG_ITMP1, disp);
1376                                 emit_mov_membase_reg(cd, REG_ITMP1, disp, var->vv.regoff);
1377
1378                                 /* Round to nearest, 53-bit mode, exceptions masked */
1379                                 disp = dseg_add_s4(cd, 0x027f);
1380                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1381
1382                                 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->vv.regoff);
1383
1384                                 disp = 3;
1385                                 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1386                                 disp += 5 + 2 + ((REG_RESULT == var->vv.regoff) ? 0 : 2);
1387                         }
1388
1389                         emit_jcc(cd, CC_NE, disp);
1390
1391                         /* XXX: change this when we use registers */
1392                         emit_flds_membase(cd, REG_SP, var1->vv.regoff);
1393                         emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2i, REG_ITMP1);
1394                         emit_call_reg(cd, REG_ITMP1);
1395
1396                         if (var->flags & INMEMORY) {
1397                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff);
1398
1399                         } else {
1400                                 M_INTMOVE(REG_RESULT, var->vv.regoff);
1401                         }
1402                         break;
1403
1404                 case ICMD_D2I:       /* ..., value  ==> ..., (int) value              */
1405
1406                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1407                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1408
1409                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
1410                         dseg_adddata(cd);
1411
1412                         /* Round to zero, 53-bit mode, exception masked */
1413                         disp = dseg_add_s4(cd, 0x0e7f);
1414                         emit_fldcw_membase(cd, REG_ITMP1, disp);
1415
1416                         var  = VAROP(iptr->dst);
1417                         var1 = VAROP(iptr->s1);
1418
1419                         if (var->flags & INMEMORY) {
1420                                 emit_fistpl_membase(cd, REG_SP, var->vv.regoff);
1421
1422                                 /* Round to nearest, 53-bit mode, exceptions masked */
1423                                 disp = dseg_add_s4(cd, 0x027f);
1424                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1425
1426                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, 
1427                                                                          REG_SP, var->vv.regoff);
1428
1429                                 disp = 3;
1430                                 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1431                                 disp += 5 + 2 + 3;
1432                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1433
1434                         } else {
1435                                 /* XXX not thread safe! */
1436                                 disp = dseg_add_unique_s4(cd, 0);
1437                                 emit_fistpl_membase(cd, REG_ITMP1, disp);
1438                                 emit_mov_membase_reg(cd, REG_ITMP1, disp, var->vv.regoff);
1439
1440                                 /* Round to nearest, 53-bit mode, exceptions masked */
1441                                 disp = dseg_add_s4(cd, 0x027f);
1442                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1443
1444                                 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->vv.regoff);
1445
1446                                 disp = 3;
1447                                 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1448                                 disp += 5 + 2 + ((REG_RESULT == var->vv.regoff) ? 0 : 2);
1449                         }
1450
1451                         emit_jcc(cd, CC_NE, disp);
1452
1453                         /* XXX: change this when we use registers */
1454                         emit_fldl_membase(cd, REG_SP, var1->vv.regoff);
1455                         emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2i, REG_ITMP1);
1456                         emit_call_reg(cd, REG_ITMP1);
1457
1458                         if (var->flags & INMEMORY) {
1459                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff);
1460                         } else {
1461                                 M_INTMOVE(REG_RESULT, var->vv.regoff);
1462                         }
1463                         break;
1464
1465                 case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
1466
1467                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1468                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1469
1470                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
1471                         dseg_adddata(cd);
1472
1473                         /* Round to zero, 53-bit mode, exception masked */
1474                         disp = dseg_add_s4(cd, 0x0e7f);
1475                         emit_fldcw_membase(cd, REG_ITMP1, disp);
1476
1477                         var  = VAROP(iptr->dst);
1478                         var1 = VAROP(iptr->s1);
1479
1480                         if (var->flags & INMEMORY) {
1481                                 emit_fistpll_membase(cd, REG_SP, var->vv.regoff);
1482
1483                                 /* Round to nearest, 53-bit mode, exceptions masked */
1484                                 disp = dseg_add_s4(cd, 0x027f);
1485                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1486
1487                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, 
1488                                                                          REG_SP, var->vv.regoff + 4);
1489
1490                                 disp = 6 + 4;
1491                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1492                                 disp += 3;
1493                                 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1494                                 disp += 5 + 2;
1495                                 disp += 3;
1496                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1497                                 disp += 3;
1498                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff + 4);
1499
1500                                 emit_jcc(cd, CC_NE, disp);
1501
1502                                 emit_alu_imm_membase(cd, ALU_CMP, 0, 
1503                                                                          REG_SP, var->vv.regoff);
1504
1505                                 disp = 3;
1506                                 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1507                                 disp += 5 + 2 + 3;
1508                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1509
1510                                 emit_jcc(cd, CC_NE, disp);
1511
1512                                 /* XXX: change this when we use registers */
1513                                 emit_flds_membase(cd, REG_SP, var1->vv.regoff);
1514                                 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2l, REG_ITMP1);
1515                                 emit_call_reg(cd, REG_ITMP1);
1516                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff);
1517                                 emit_mov_reg_membase(cd, REG_RESULT2, 
1518                                                                          REG_SP, var->vv.regoff + 4);
1519
1520                         } else {
1521                                 log_text("F2L: longs have to be in memory");
1522                                 assert(0);
1523                         }
1524                         break;
1525
1526                 case ICMD_D2L:       /* ..., value  ==> ..., (long) value             */
1527
1528                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1529                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1530
1531                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
1532                         dseg_adddata(cd);
1533
1534                         /* Round to zero, 53-bit mode, exception masked */
1535                         disp = dseg_add_s4(cd, 0x0e7f);
1536                         emit_fldcw_membase(cd, REG_ITMP1, disp);
1537
1538                         var  = VAROP(iptr->dst);
1539                         var1 = VAROP(iptr->s1);
1540
1541                         if (var->flags & INMEMORY) {
1542                                 emit_fistpll_membase(cd, REG_SP, var->vv.regoff);
1543
1544                                 /* Round to nearest, 53-bit mode, exceptions masked */
1545                                 disp = dseg_add_s4(cd, 0x027f);
1546                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1547
1548                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, 
1549                                                                          REG_SP, var->vv.regoff + 4);
1550
1551                                 disp = 6 + 4;
1552                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1553                                 disp += 3;
1554                                 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1555                                 disp += 5 + 2;
1556                                 disp += 3;
1557                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1558                                 disp += 3;
1559                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff + 4);
1560
1561                                 emit_jcc(cd, CC_NE, disp);
1562
1563                                 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, var->vv.regoff);
1564
1565                                 disp = 3;
1566                                 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1567                                 disp += 5 + 2 + 3;
1568                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1569
1570                                 emit_jcc(cd, CC_NE, disp);
1571
1572                                 /* XXX: change this when we use registers */
1573                                 emit_fldl_membase(cd, REG_SP, var1->vv.regoff);
1574                                 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2l, REG_ITMP1);
1575                                 emit_call_reg(cd, REG_ITMP1);
1576                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff);
1577                                 emit_mov_reg_membase(cd, REG_RESULT2, 
1578                                                                          REG_SP, var->vv.regoff + 4);
1579
1580                         } else {
1581                                 log_text("D2L: longs have to be in memory");
1582                                 assert(0);
1583                         }
1584                         break;
1585
1586                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1587
1588                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1589                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1590                         /* nothing to do */
1591                         emit_store_dst(jd, iptr, d);
1592                         break;
1593
1594                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value            */
1595
1596                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1597                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1598                         /* nothing to do */
1599                         emit_store_dst(jd, iptr, d);
1600                         break;
1601
1602                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1603                 case ICMD_DCMPL:
1604
1605                         /* exchanged to skip fxch */
1606                         s2 = emit_load_s1(jd, iptr, REG_FTMP1);
1607                         s1 = emit_load_s2(jd, iptr, REG_FTMP2);
1608                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1609 /*                      emit_fxch(cd); */
1610                         emit_fucompp(cd);
1611                         emit_fnstsw(cd);
1612                         emit_test_imm_reg(cd, 0x400, EAX);    /* unordered treat as GT */
1613                         emit_jcc(cd, CC_E, 6);
1614                         emit_alu_imm_reg(cd, ALU_AND, 0x000000ff, EAX);
1615                         emit_sahf(cd);
1616                         emit_mov_imm_reg(cd, 0, d);    /* does not affect flags */
1617                         emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
1618                         emit_jcc(cd, CC_B, 3 + 5);
1619                         emit_alu_imm_reg(cd, ALU_SUB, 1, d);
1620                         emit_jmp_imm(cd, 3);
1621                         emit_alu_imm_reg(cd, ALU_ADD, 1, d);
1622                         emit_store_dst(jd, iptr, d);
1623                         break;
1624
1625                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1626                 case ICMD_DCMPG:
1627
1628                         /* exchanged to skip fxch */
1629                         s2 = emit_load_s1(jd, iptr, REG_FTMP1);
1630                         s1 = emit_load_s2(jd, iptr, REG_FTMP2);
1631                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1632 /*                      emit_fxch(cd); */
1633                         emit_fucompp(cd);
1634                         emit_fnstsw(cd);
1635                         emit_test_imm_reg(cd, 0x400, EAX);    /* unordered treat as LT */
1636                         emit_jcc(cd, CC_E, 3);
1637                         emit_movb_imm_reg(cd, 1, REG_AH);
1638                         emit_sahf(cd);
1639                         emit_mov_imm_reg(cd, 0, d);    /* does not affect flags */
1640                         emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
1641                         emit_jcc(cd, CC_B, 3 + 5);
1642                         emit_alu_imm_reg(cd, ALU_SUB, 1, d);
1643                         emit_jmp_imm(cd, 3);
1644                         emit_alu_imm_reg(cd, ALU_ADD, 1, d);
1645                         emit_store_dst(jd, iptr, d);
1646                         break;
1647
1648
1649                 /* memory operations **************************************************/
1650
1651                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1652
1653                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1654                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1655                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1656                         /* implicit null-pointer check */
1657                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1658                         emit_movsbl_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]), 
1659                                                                          s1, s2, 0, d);
1660                         emit_store_dst(jd, iptr, d);
1661                         break;
1662
1663                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1664
1665                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1666                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1667                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1668                         /* implicit null-pointer check */
1669                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1670                         emit_movzwl_memindex_reg(cd, OFFSET(java_chararray_t, data[0]), 
1671                                                                          s1, s2, 1, d);
1672                         emit_store_dst(jd, iptr, d);
1673                         break;                  
1674
1675                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1676
1677                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1678                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1679                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1680                         /* implicit null-pointer check */
1681                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1682                         emit_movswl_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]), 
1683                                                                          s1, s2, 1, d);
1684                         emit_store_dst(jd, iptr, d);
1685                         break;
1686
1687                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1688
1689                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1690                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1691                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1692                         /* implicit null-pointer check */
1693                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1694                         emit_mov_memindex_reg(cd, OFFSET(java_intarray_t, data[0]), 
1695                                                                   s1, s2, 2, d);
1696                         emit_store_dst(jd, iptr, d);
1697                         break;
1698
1699                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1700
1701                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1702                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1703                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1704                         /* implicit null-pointer check */
1705                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1706
1707                         var = VAROP(iptr->dst);
1708
1709                         assert(var->flags & INMEMORY);
1710                         emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]), 
1711                                                                   s1, s2, 3, REG_ITMP3);
1712                         emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->vv.regoff);
1713                         emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]) + 4, 
1714                                                                   s1, s2, 3, REG_ITMP3);
1715                         emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->vv.regoff + 4);
1716                         break;
1717
1718                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1719
1720                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1721                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1722                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1723                         /* implicit null-pointer check */
1724                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1725                         emit_flds_memindex(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
1726                         emit_store_dst(jd, iptr, d);
1727                         break;
1728
1729                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1730
1731                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1732                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1733                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1734                         /* implicit null-pointer check */
1735                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1736                         emit_fldl_memindex(cd, OFFSET(java_doublearray_t, data[0]), s1, s2,3);
1737                         emit_store_dst(jd, iptr, d);
1738                         break;
1739
1740                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1741
1742                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1743                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1744                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1745                         /* implicit null-pointer check */
1746                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1747                         emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]),
1748                                                                   s1, s2, 2, d);
1749                         emit_store_dst(jd, iptr, d);
1750                         break;
1751
1752
1753                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1754
1755                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1756                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1757                         /* implicit null-pointer check */
1758                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1759                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1760                         if (s3 >= EBP) { 
1761                                 /* because EBP, ESI, EDI have no xH and xL nibbles */
1762                                 M_INTMOVE(s3, REG_ITMP3);
1763                                 s3 = REG_ITMP3;
1764                         }
1765                         emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]),
1766                                                                    s1, s2, 0);
1767                         break;
1768
1769                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1770
1771                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1772                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1773                         /* implicit null-pointer check */
1774                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1775                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1776                         emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]),
1777                                                                    s1, s2, 1);
1778                         break;
1779
1780                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1781
1782                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1783                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1784                         /* implicit null-pointer check */
1785                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1786                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1787                         emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]),
1788                                                                    s1, s2, 1);
1789                         break;
1790
1791                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1792
1793                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1794                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1795                         /* implicit null-pointer check */
1796                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1797                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1798                         emit_mov_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]),
1799                                                                   s1, s2, 2);
1800                         break;
1801
1802                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1803
1804                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1805                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1806                         /* implicit null-pointer check */
1807                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1808
1809                         var = VAROP(iptr->sx.s23.s3);
1810
1811                         assert(var->flags & INMEMORY);
1812                         emit_mov_membase_reg(cd, REG_SP, var->vv.regoff, REG_ITMP3);
1813                         emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray_t, data[0])
1814                                                                   , s1, s2, 3);
1815                         emit_mov_membase_reg(cd, REG_SP, var->vv.regoff + 4, REG_ITMP3);
1816                         emit_mov_reg_memindex(cd, REG_ITMP3,
1817                                                             OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
1818                         break;
1819
1820                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1821
1822                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1823                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1824                         /* implicit null-pointer check */
1825                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1826                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1827                         emit_fstps_memindex(cd, OFFSET(java_floatarray_t, data[0]), s1, s2,2);
1828                         break;
1829
1830                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1831
1832                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1833                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1834                         /* implicit null-pointer check */
1835                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1836                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1837                         emit_fstpl_memindex(cd, OFFSET(java_doublearray_t, data[0]),
1838                                                                 s1, s2, 3);
1839                         break;
1840
1841                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1842
1843                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1844                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1845                         /* implicit null-pointer check */
1846                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1847                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1848
1849                         M_AST(s1, REG_SP, 0 * 4);
1850                         M_AST(s3, REG_SP, 1 * 4);
1851                         M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
1852                         M_CALL(REG_ITMP1);
1853                         emit_arraystore_check(cd, iptr);
1854
1855                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1856                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1857                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1858                         emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]),
1859                                                                   s1, s2, 2);
1860                         break;
1861
1862                 case ICMD_BASTORECONST: /* ..., arrayref, index  ==> ...              */
1863
1864                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1865                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1866                         /* implicit null-pointer check */
1867                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1868                         emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval,
1869                                                                    OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1870                         break;
1871
1872                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
1873
1874                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1875                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1876                         /* implicit null-pointer check */
1877                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1878                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
1879                                                                    OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1880                         break;
1881
1882                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
1883
1884                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1885                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1886                         /* implicit null-pointer check */
1887                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1888                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
1889                                                                    OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1890                         break;
1891
1892                 case ICMD_IASTORECONST: /* ..., arrayref, index  ==> ...              */
1893
1894                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1895                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1896                         /* implicit null-pointer check */
1897                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1898                         emit_mov_imm_memindex(cd, iptr->sx.s23.s3.constval,
1899                                                                   OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1900                         break;
1901
1902                 case ICMD_LASTORECONST: /* ..., arrayref, index  ==> ...              */
1903
1904                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1905                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1906                         /* implicit null-pointer check */
1907                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1908                         emit_mov_imm_memindex(cd, 
1909                                                    (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff),
1910                                                    OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1911                         emit_mov_imm_memindex(cd, 
1912                                                         ((s4)iptr->sx.s23.s3.constval) >> 31, 
1913                                                         OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
1914                         break;
1915
1916                 case ICMD_AASTORECONST: /* ..., arrayref, index  ==> ...              */
1917
1918                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1919                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1920                         /* implicit null-pointer check */
1921                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1922                         emit_mov_imm_memindex(cd, 0, 
1923                                                                   OFFSET(java_objectarray_t, data[0]), s1, s2, 2);
1924                         break;
1925
1926
1927                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1928
1929                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1930                                 uf        = iptr->sx.s23.s3.uf;
1931                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1932                                 disp      = 0;
1933
1934                                 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
1935
1936                         }
1937                         else {
1938                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1939                                 fieldtype = fi->type;
1940                                 disp      = (intptr_t) fi->value;
1941
1942                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1943                                         patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, 0);
1944                         }
1945
1946                         M_MOV_IMM2(disp, REG_ITMP1);
1947                         switch (fieldtype) {
1948                         case TYPE_INT:
1949                         case TYPE_ADR:
1950                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1951                                 M_ILD(d, REG_ITMP1, 0);
1952                                 break;
1953                         case TYPE_LNG:
1954                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1955                                 M_LLD(d, REG_ITMP1, 0);
1956                                 break;
1957                         case TYPE_FLT:
1958                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1959                                 M_FLD(d, REG_ITMP1, 0);
1960                                 break;
1961                         case TYPE_DBL:                          
1962                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1963                                 M_DLD(d, REG_ITMP1, 0);
1964                                 break;
1965                         }
1966                         emit_store_dst(jd, iptr, d);
1967                         break;
1968
1969                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
1970                         
1971                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1972                                 uf        = iptr->sx.s23.s3.uf;
1973                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1974                                 disp      = 0;
1975
1976                                 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
1977                         }
1978                         else {
1979                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1980                                 fieldtype = fi->type;
1981                                 disp      = (intptr_t) fi->value;
1982
1983                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1984                                         patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, 0);
1985                         }
1986
1987                         M_MOV_IMM2(disp, REG_ITMP1);
1988                         switch (fieldtype) {
1989                         case TYPE_INT:
1990                         case TYPE_ADR:
1991                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1992                                 M_IST(s1, REG_ITMP1, 0);
1993                                 break;
1994                         case TYPE_LNG:
1995                                 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1996                                 M_LST(s1, REG_ITMP1, 0);
1997                                 break;
1998                         case TYPE_FLT:
1999                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2000                                 emit_fstps_membase(cd, REG_ITMP1, 0);
2001                                 break;
2002                         case TYPE_DBL:
2003                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2004                                 emit_fstpl_membase(cd, REG_ITMP1, 0);
2005                                 break;
2006                         }
2007                         break;
2008
2009                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
2010                                           /* val = value (in current instruction)     */
2011                                           /* following NOP)                           */
2012
2013                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2014                                 uf        = iptr->sx.s23.s3.uf;
2015                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2016                                 disp      = 0;
2017
2018                                 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
2019                         }
2020                         else {
2021                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2022                                 fieldtype = fi->type;
2023                                 disp      = (intptr_t) fi->value;
2024
2025                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
2026                                         patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, 0);
2027                         }
2028
2029                         M_MOV_IMM2(disp, REG_ITMP1);
2030                         switch (fieldtype) {
2031                         case TYPE_INT:
2032                         case TYPE_ADR:
2033                                 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2034                                 break;
2035                         case TYPE_LNG:
2036                                 M_IST_IMM(iptr->sx.s23.s2.constval & 0xffffffff, REG_ITMP1, 0);
2037                                 M_IST_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, REG_ITMP1, 4);
2038                                 break;
2039                         default:
2040                                 assert(0);
2041                         }
2042                         break;
2043
2044                 case ICMD_GETFIELD:   /* .., objectref.  ==> ..., value               */
2045
2046                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2047                         emit_nullpointer_check(cd, iptr, s1);
2048
2049 #if defined(ENABLE_ESCAPE_CHECK)
2050                         /*emit_escape_check(cd, s1);*/
2051 #endif
2052
2053                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2054                                 uf        = iptr->sx.s23.s3.uf;
2055                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2056                                 disp      = 0;
2057
2058                                 patcher_add_patch_ref(jd, PATCHER_getfield,
2059                                                                         iptr->sx.s23.s3.uf, 0);
2060                         }
2061                         else {
2062                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2063                                 fieldtype = fi->type;
2064                                 disp      = fi->offset;
2065                         }
2066
2067                         switch (fieldtype) {
2068                         case TYPE_INT:
2069                         case TYPE_ADR:
2070                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2071                                 M_ILD32(d, s1, disp);
2072                                 break;
2073                         case TYPE_LNG:
2074                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2075                                 M_LLD32(d, s1, disp);
2076                                 break;
2077                         case TYPE_FLT:
2078                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2079                                 M_FLD32(d, s1, disp);
2080                                 break;
2081                         case TYPE_DBL:                          
2082                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2083                                 M_DLD32(d, s1, disp);
2084                                 break;
2085                         }
2086                         emit_store_dst(jd, iptr, d);
2087                         break;
2088
2089                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
2090
2091                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2092                         emit_nullpointer_check(cd, iptr, s1);
2093
2094                         /* must be done here because of code patching */
2095
2096                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2097                                 uf        = iptr->sx.s23.s3.uf;
2098                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2099                         }
2100                         else {
2101                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2102                                 fieldtype = fi->type;
2103                         }
2104
2105                         if (!IS_FLT_DBL_TYPE(fieldtype)) {
2106                                 if (IS_2_WORD_TYPE(fieldtype))
2107                                         s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2108                                 else
2109                                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2110                         }
2111                         else
2112                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2113
2114                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2115                                 /* XXX */
2116                                 uf   = iptr->sx.s23.s3.uf;
2117                                 disp = 0;
2118
2119                                 patcher_add_patch_ref(jd, PATCHER_putfield, uf, 0);
2120                         }
2121                         else {
2122                                 /* XXX */
2123                                 fi   = iptr->sx.s23.s3.fmiref->p.field;
2124                                 disp = fi->offset;
2125                         }
2126
2127                         switch (fieldtype) {
2128                         case TYPE_INT:
2129                         case TYPE_ADR:
2130                                 M_IST32(s2, s1, disp);
2131                                 break;
2132                         case TYPE_LNG:
2133                                 M_LST32(s2, s1, disp);
2134                                 break;
2135                         case TYPE_FLT:
2136                                 emit_fstps_membase32(cd, s1, disp);
2137                                 break;
2138                         case TYPE_DBL:
2139                                 emit_fstpl_membase32(cd, s1, disp);
2140                                 break;
2141                         }
2142                         break;
2143
2144                 case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
2145                                           /* val = value (in current instruction)     */
2146                                           /* following NOP)                           */
2147
2148                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2149                         emit_nullpointer_check(cd, iptr, s1);
2150
2151                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2152                                 uf        = iptr->sx.s23.s3.uf;
2153                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2154                                 disp      = 0;
2155
2156                                 patcher_add_patch_ref(jd, PATCHER_putfieldconst,
2157                                                                         uf, 0);
2158                         }
2159                         else {
2160                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2161                                 fieldtype = fi->type;
2162                                 disp      = fi->offset;
2163                         }
2164
2165                         switch (fieldtype) {
2166                         case TYPE_INT:
2167                         case TYPE_ADR:
2168                                 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2169                                 break;
2170                         case TYPE_LNG:
2171                                 M_IST32_IMM(iptr->sx.s23.s2.constval & 0xffffffff, s1, disp);
2172                                 M_IST32_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, s1, disp + 4);
2173                                 break;
2174                         default:
2175                                 assert(0);
2176                         }
2177                         break;
2178
2179
2180                 /* branch operations **************************************************/
2181
2182                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
2183
2184                         M_CALL_IMM(0);                            /* passing exception pc */
2185                         M_POP(REG_ITMP2_XPC);
2186
2187                         M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2188                         M_JMP(REG_ITMP3);
2189                         break;
2190
2191                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
2192
2193                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2194                         if (iptr->sx.val.l == 0) {
2195                                 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2196                                 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2197                         }
2198                         else {
2199                                 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2200                                 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
2201                                 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
2202                                 M_OR(REG_ITMP2, REG_ITMP1);
2203                         }
2204                         emit_beq(cd, iptr->dst.block);
2205                         break;
2206
2207                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
2208
2209                         if (iptr->sx.val.l == 0) {
2210                                 /* If high 32-bit are less than zero, then the 64-bits
2211                                    are too. */
2212                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2213                                 M_CMP_IMM(0, s1);
2214                                 emit_blt(cd, iptr->dst.block);
2215                         }
2216                         else {
2217                                 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2218                                 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2219                                 emit_blt(cd, iptr->dst.block);
2220                                 M_BGT(6 + 6);
2221                                 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2222                                 emit_bult(cd, iptr->dst.block);
2223                         }                       
2224                         break;
2225
2226                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
2227
2228                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2229                         M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2230                         emit_blt(cd, iptr->dst.block);
2231                         M_BGT(6 + 6);
2232                         M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2233                         emit_bule(cd, iptr->dst.block);
2234                         break;
2235
2236                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
2237
2238                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2239                         if (iptr->sx.val.l == 0) {
2240                                 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2241                                 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2242                         }
2243                         else {
2244                                 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2245                                 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
2246                                 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
2247                                 M_OR(REG_ITMP2, REG_ITMP1);
2248                         }
2249                         emit_bne(cd, iptr->dst.block);
2250                         break;
2251
2252                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2253
2254                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2255                         M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2256                         emit_bgt(cd, iptr->dst.block);
2257                         M_BLT(6 + 6);
2258                         M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2259                         emit_bugt(cd, iptr->dst.block);
2260                         break;
2261
2262                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2263
2264                         if (iptr->sx.val.l == 0) {
2265                                 /* If high 32-bit are greater equal zero, then the
2266                                    64-bits are too. */
2267                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2268                                 M_CMP_IMM(0, s1);
2269                                 emit_bge(cd, iptr->dst.block);
2270                         }
2271                         else {
2272                                 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2273                                 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2274                                 emit_bgt(cd, iptr->dst.block);
2275                                 M_BLT(6 + 6);
2276                                 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2277                                 emit_buge(cd, iptr->dst.block);
2278                         }
2279                         break;
2280
2281                 case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
2282
2283                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2284                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2285                         M_INTMOVE(s1, REG_ITMP1);
2286                         M_XOR(s2, REG_ITMP1);
2287                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2288                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
2289                         M_INTMOVE(s1, REG_ITMP2);
2290                         M_XOR(s2, REG_ITMP2);
2291                         M_OR(REG_ITMP1, REG_ITMP2);
2292                         emit_beq(cd, iptr->dst.block);
2293                         break;
2294
2295                 case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
2296
2297                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2298                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2299                         M_INTMOVE(s1, REG_ITMP1);
2300                         M_XOR(s2, REG_ITMP1);
2301                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2302                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
2303                         M_INTMOVE(s1, REG_ITMP2);
2304                         M_XOR(s2, REG_ITMP2);
2305                         M_OR(REG_ITMP1, REG_ITMP2);
2306                         emit_bne(cd, iptr->dst.block);
2307                         break;
2308
2309                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
2310
2311                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2312                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2313                         M_CMP(s2, s1);
2314                         emit_blt(cd, iptr->dst.block);
2315                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2316                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2317                         M_BGT(2 + 6);
2318                         M_CMP(s2, s1);
2319                         emit_bult(cd, iptr->dst.block);
2320                         break;
2321
2322                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
2323
2324                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2325                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2326                         M_CMP(s2, s1);
2327                         emit_bgt(cd, iptr->dst.block);
2328                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2329                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2330                         M_BLT(2 + 6);
2331                         M_CMP(s2, s1);
2332                         emit_bugt(cd, iptr->dst.block);
2333                         break;
2334
2335                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
2336
2337                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2338                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2339                         M_CMP(s2, s1);
2340                         emit_blt(cd, iptr->dst.block);
2341                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2342                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2343                         M_BGT(2 + 6);
2344                         M_CMP(s2, s1);
2345                         emit_bule(cd, iptr->dst.block);
2346                         break;
2347
2348                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
2349
2350                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2351                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2352                         M_CMP(s2, s1);
2353                         emit_bgt(cd, iptr->dst.block);
2354                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2355                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2356                         M_BLT(2 + 6);
2357                         M_CMP(s2, s1);
2358                         emit_buge(cd, iptr->dst.block);
2359                         break;
2360
2361                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2362                         {
2363                                 s4 i, l;
2364                                 branch_target_t *table;
2365
2366                                 table = iptr->dst.table;
2367
2368                                 l = iptr->sx.s23.s2.tablelow;
2369                                 i = iptr->sx.s23.s3.tablehigh;
2370
2371                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2372                                 M_INTMOVE(s1, REG_ITMP1);
2373
2374                                 if (l != 0)
2375                                         M_ISUB_IMM(l, REG_ITMP1);
2376
2377                                 i = i - l + 1;
2378
2379                 /* range check */
2380
2381                                 M_CMP_IMM(i - 1, REG_ITMP1);
2382                                 emit_bugt(cd, table[0].block);
2383
2384                                 /* build jump table top down and use address of lowest entry */
2385
2386                                 table += i;
2387
2388                                 while (--i >= 0) {
2389                                         dseg_add_target(cd, table->block); 
2390                                         --table;
2391                                 }
2392
2393                                 /* length of dataseg after last dseg_addtarget is used
2394                                    by load */
2395
2396                                 M_MOV_IMM(0, REG_ITMP2);
2397                                 dseg_adddata(cd);
2398                                 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
2399                                 M_JMP(REG_ITMP1);
2400                         }
2401                         break;
2402
2403                 case ICMD_BUILTIN:
2404                         bte = iptr->sx.s23.s3.bte;
2405                         if (bte->stub == NULL) {
2406                                 M_MOV_IMM(bte->fp, REG_ITMP1);
2407                         }
2408                         else {
2409                                 M_MOV_IMM(bte->stub, REG_ITMP1);
2410                         }
2411                         M_CALL(REG_ITMP1);
2412
2413 #if defined(ENABLE_ESCAPE_CHECK)
2414                         if (bte->opcode == ICMD_NEW || bte->opcode == ICMD_NEWARRAY) {
2415                                 /*emit_escape_annotate_object(cd, m);*/
2416                         }
2417 #endif
2418                         break;
2419
2420                 case ICMD_INVOKESPECIAL:
2421                         M_ALD(REG_ITMP1, REG_SP, 0 * 8);
2422                         emit_nullpointer_check(cd, iptr, REG_ITMP1);
2423                         /* fall through */
2424
2425                 case ICMD_INVOKESTATIC:
2426                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2427                                 um = iptr->sx.s23.s3.um;
2428
2429                                 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2430                                                                         um, 0);
2431
2432                                 disp = 0;
2433                         }
2434                         else {
2435                                 lm = iptr->sx.s23.s3.fmiref->p.method;
2436                                 disp = (ptrint) lm->stubroutine;
2437                         }
2438
2439                         M_MOV_IMM2(disp, REG_ITMP2);
2440                         M_CALL(REG_ITMP2);
2441                         break;
2442
2443                 case ICMD_INVOKEVIRTUAL:
2444                         M_ALD(REG_ITMP1, REG_SP, 0 * 8);
2445                         emit_nullpointer_check(cd, iptr, s1);
2446
2447                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2448                                 um = iptr->sx.s23.s3.um;
2449
2450                                 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2451
2452                                 s1 = 0;
2453                         }
2454                         else {
2455                                 lm = iptr->sx.s23.s3.fmiref->p.method;
2456                                 s1 = OFFSET(vftbl_t, table[0]) +
2457                                         sizeof(methodptr) * lm->vftblindex;
2458                         }
2459
2460                         M_ALD(REG_METHODPTR, REG_ITMP1,
2461                                   OFFSET(java_object_t, vftbl));
2462                         M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2463                         M_CALL(REG_ITMP3);
2464                         break;
2465
2466                 case ICMD_INVOKEINTERFACE:
2467                         M_ALD(REG_ITMP1, REG_SP, 0 * 8);
2468                         emit_nullpointer_check(cd, iptr, s1);
2469
2470                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2471                                 um = iptr->sx.s23.s3.um;
2472
2473                                 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2474
2475                                 s1 = 0;
2476                                 s2 = 0;
2477                         }
2478                         else {
2479                                 lm = iptr->sx.s23.s3.fmiref->p.method;
2480                                 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2481                                         sizeof(methodptr) * lm->clazz->index;
2482
2483                                 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2484                         }
2485
2486                         M_ALD(REG_METHODPTR, REG_ITMP1,
2487                                   OFFSET(java_object_t, vftbl));
2488                         M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2489                         M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2490                         M_CALL(REG_ITMP3);
2491                         break;
2492
2493                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2494
2495                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2496                                 /* object type cast-check */
2497
2498                                 classinfo *super;
2499                                 vftbl_t   *supervftbl;
2500                                 s4         superindex;
2501
2502                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2503                                         super = NULL;
2504                                         superindex = 0;
2505                                         supervftbl = NULL;
2506                                 }
2507                                 else {
2508                                         super = iptr->sx.s23.s3.c.cls;
2509                                         superindex = super->index;
2510                                         supervftbl = super->vftbl;
2511                                 }
2512                         
2513                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2514
2515                                 /* if class is not resolved, check which code to call */
2516
2517                                 if (super == NULL) {
2518                                         M_TEST(s1);
2519                                         emit_label_beq(cd, BRANCH_LABEL_1);
2520
2521                                         patcher_add_patch_ref(jd, PATCHER_checkcast_instanceof_flags,
2522                                                                                 iptr->sx.s23.s3.c.ref, 0);
2523
2524                                         M_MOV_IMM2(0, REG_ITMP2);                 /* super->flags */
2525                                         M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
2526                                         emit_label_beq(cd, BRANCH_LABEL_2);
2527                                 }
2528
2529                                 /* interface checkcast code */
2530
2531                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2532                                         if (super != NULL) {
2533                                                 M_TEST(s1);
2534                                                 emit_label_beq(cd, BRANCH_LABEL_3);
2535                                         }
2536
2537                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2538
2539                                         if (super == NULL) {
2540                                                 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
2541                                                                                         iptr->sx.s23.s3.c.ref,
2542                                                                                         0);
2543                                         }
2544
2545                                         M_ILD32(REG_ITMP3,
2546                                                         REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2547                                         M_ISUB_IMM32(superindex, REG_ITMP3);
2548                                         /* XXX do we need this one? */
2549                                         M_TEST(REG_ITMP3);
2550                                         emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2551
2552                                         M_ALD32(REG_ITMP3, REG_ITMP2,
2553                                                         OFFSET(vftbl_t, interfacetable[0]) -
2554                                                         superindex * sizeof(methodptr*));
2555                                         M_TEST(REG_ITMP3);
2556                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2557
2558                                         if (super == NULL)
2559                                                 emit_label_br(cd, BRANCH_LABEL_4);
2560                                         else
2561                                                 emit_label(cd, BRANCH_LABEL_3);
2562                                 }
2563
2564                                 /* class checkcast code */
2565
2566                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2567                                         if (super == NULL) {
2568                                                 emit_label(cd, BRANCH_LABEL_2);
2569                                         }
2570                                         else {
2571                                                 M_TEST(s1);
2572                                                 emit_label_beq(cd, BRANCH_LABEL_5);
2573                                         }
2574
2575                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2576                                         if (super == NULL) {
2577                                                 patcher_add_patch_ref(jd, PATCHER_checkcast_class,
2578                                                                                         iptr->sx.s23.s3.c.ref,
2579                                                                                         0);
2580                                         }
2581                                         M_MOV_IMM2(supervftbl, REG_ITMP3);
2582
2583                                         if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2584                                                 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2585                                                 M_CMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3);
2586                                                 emit_label_beq(cd, BRANCH_LABEL_6);  /* good */
2587
2588                                                 if (super == NULL) {
2589                                                         M_ICMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2590                                                         emit_label_bne(cd, BRANCH_LABEL_10);  /* throw */
2591                                                 }
2592
2593                                                 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2594                                                 M_CMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
2595                                                 emit_label_bgt(cd, BRANCH_LABEL_9);  /* throw */
2596
2597                                                 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2598                                                 M_CMP_MEMINDEX(REG_ITMP2, -4*DISPLAY_SIZE, REG_ITMP1, 2, REG_ITMP3);
2599                                                 emit_label_beq(cd, BRANCH_LABEL_7);  /* good */
2600
2601                                                 emit_label(cd, BRANCH_LABEL_9);
2602                                                 if (super == NULL)
2603                                                         emit_label(cd, BRANCH_LABEL_10);
2604
2605                                                 /* reload s1, might have been destroyed */
2606                                                 emit_load_s1(jd, iptr, REG_ITMP1);
2607                                                 M_ALD_MEM(s1, TRAP_ClassCastException);
2608
2609                                                 emit_label(cd, BRANCH_LABEL_7);
2610                                                 emit_label(cd, BRANCH_LABEL_6);
2611                                                 /* reload s1, might have been destroyed */
2612                                                 emit_load_s1(jd, iptr, REG_ITMP1);
2613                                         }
2614                                         else {
2615                                                 M_CMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
2616
2617                                                 emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP3, s1);
2618                                         }
2619
2620                                         if (super != NULL)
2621                                                 emit_label(cd, BRANCH_LABEL_5);
2622                                 }
2623
2624                                 if (super == NULL) {
2625                                         emit_label(cd, BRANCH_LABEL_1);
2626                                         emit_label(cd, BRANCH_LABEL_4);
2627                                 }
2628
2629                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2630                         }
2631                         else {
2632                                 /* array type cast-check */
2633
2634                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2635                                 M_AST(s1, REG_SP, 0 * 4);
2636
2637                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2638                                         patcher_add_patch_ref(jd, PATCHER_builtin_arraycheckcast,
2639                                                                                 iptr->sx.s23.s3.c.ref, 0);
2640                                 }
2641
2642                                 M_AST_IMM(iptr->sx.s23.s3.c.cls, REG_SP, 1 * 4);
2643                                 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
2644                                 M_CALL(REG_ITMP3);
2645
2646                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2647                                 M_TEST(REG_RESULT);
2648                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2649
2650                                 d = codegen_reg_of_dst(jd, iptr, s1);
2651                         }
2652
2653                         M_INTMOVE(s1, d);
2654                         emit_store_dst(jd, iptr, d);
2655                         break;
2656
2657                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
2658
2659                         {
2660                         classinfo *super;
2661                         vftbl_t   *supervftbl;
2662                         s4         superindex;
2663
2664                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2665                                 super = NULL;
2666                                 superindex = 0;
2667                                 supervftbl = NULL;
2668
2669                         } else {
2670                                 super = iptr->sx.s23.s3.c.cls;
2671                                 superindex = super->index;
2672                                 supervftbl = super->vftbl;
2673                         }
2674                         
2675                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2676                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2677
2678                         if (s1 == d) {
2679                                 M_INTMOVE(s1, REG_ITMP1);
2680                                 s1 = REG_ITMP1;
2681                         }
2682
2683                         M_CLR(d);
2684
2685                         /* if class is not resolved, check which code to call */
2686
2687                         if (super == NULL) {
2688                                 M_TEST(s1);
2689                                 emit_label_beq(cd, BRANCH_LABEL_1);
2690
2691                                 patcher_add_patch_ref(jd, PATCHER_checkcast_instanceof_flags,
2692                                                                         iptr->sx.s23.s3.c.ref, 0);
2693
2694                                 M_MOV_IMM2(0, REG_ITMP3);                     /* super->flags */
2695                                 M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
2696                                 emit_label_beq(cd, BRANCH_LABEL_2);
2697                         }
2698
2699                         /* interface instanceof code */
2700
2701                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2702                                 if (super != NULL) {
2703                                         M_TEST(s1);
2704                                         emit_label_beq(cd, BRANCH_LABEL_3);
2705                                 }
2706
2707                                 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2708
2709                                 if (super == NULL) {
2710                                         patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
2711                                                                                 iptr->sx.s23.s3.c.ref, 0);
2712                                 }
2713
2714                                 M_ILD32(REG_ITMP3,
2715                                                 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2716                                 M_ISUB_IMM32(superindex, REG_ITMP3);
2717                                 M_TEST(REG_ITMP3);
2718
2719                                 disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
2720                                                 6 /* jcc */ + 5 /* mov_imm_reg */);
2721
2722                                 M_BLE(disp);
2723                                 M_ALD32(REG_ITMP1, REG_ITMP1,
2724                                                 OFFSET(vftbl_t, interfacetable[0]) -
2725                                                 superindex * sizeof(methodptr*));
2726                                 M_TEST(REG_ITMP1);
2727 /*                                      emit_setcc_reg(cd, CC_A, d); */
2728 /*                                      emit_jcc(cd, CC_BE, 5); */
2729                                 M_BEQ(5);
2730                                 M_MOV_IMM(1, d);
2731
2732                                 if (super == NULL)
2733                                         emit_label_br(cd, BRANCH_LABEL_4);
2734                                 else
2735                                         emit_label(cd, BRANCH_LABEL_3);
2736                         }
2737
2738                         /* class instanceof code */
2739
2740                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2741                                 if (super == NULL) {
2742                                         emit_label(cd, BRANCH_LABEL_2);
2743                                 }
2744                                 else {
2745                                         M_TEST(s1);
2746                                         emit_label_beq(cd, BRANCH_LABEL_5);
2747                                 }
2748
2749                                 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2750                                 if (super == NULL) {
2751                                         patcher_add_patch_ref(jd, PATCHER_instanceof_class,
2752                                                                                 iptr->sx.s23.s3.c.ref, 0);
2753                                 }
2754                                 M_MOV_IMM2(supervftbl, REG_ITMP3);
2755
2756                                 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2757                                         M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2758                                         M_CMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3);
2759                                         emit_label_bne(cd, BRANCH_LABEL_8); /* jump over INC/SETE */
2760                                         if (d == REG_ITMP2) {
2761                                                 M_SETE(d);
2762                                                 M_BSEXT(d, d);
2763                                         } else
2764                                                 M_IINC(d);
2765                                         emit_label_br(cd, BRANCH_LABEL_6);  /* true */
2766                                         emit_label(cd, BRANCH_LABEL_8);
2767
2768                                         if (super == NULL) {
2769                                                 M_ICMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2770                                                 emit_label_bne(cd, BRANCH_LABEL_10);  /* false */
2771                                         }
2772
2773                                         M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2774                                         M_CMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
2775                                         emit_label_bgt(cd, BRANCH_LABEL_9);  /* false */
2776
2777                                         M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2778                                         M_CMP_MEMINDEX(REG_ITMP2, -4*DISPLAY_SIZE, REG_ITMP1, 2, REG_ITMP3);
2779                                         if (d >= 4) {
2780                                                 M_SETE(REG_ITMP1);
2781                                                 M_BSEXT(REG_ITMP1, d);
2782                                         }
2783                                         else {
2784                                                 M_SETE(d);
2785                                                 if (d == REG_ITMP2) {
2786                                                         M_BSEXT(d, d);
2787
2788                                                         emit_label_br(cd, BRANCH_LABEL_7); /* jump over M_CLR */
2789                                                 }
2790                                         }
2791
2792                                         emit_label(cd, BRANCH_LABEL_9);
2793                                         if (super == NULL)
2794                                                 emit_label(cd, BRANCH_LABEL_10);
2795                                         if (d == REG_ITMP2) {
2796                                                 M_CLR(d);
2797
2798                                                 emit_label(cd, BRANCH_LABEL_7);
2799                                         }
2800                                         emit_label(cd, BRANCH_LABEL_6);
2801                                 }
2802                                 else {
2803                                         M_CMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
2804
2805                                         if (d >= 4) {
2806                                                 M_SETE(REG_ITMP1);
2807                                                 M_BSEXT(REG_ITMP1, d);
2808                                         }
2809                                         else {
2810                                                 M_SETE(d);
2811                                                 if (d == REG_ITMP2)
2812                                                         M_BSEXT(d, d);
2813                                         }
2814                                 }
2815
2816                                 if (super != NULL)
2817                                         emit_label(cd, BRANCH_LABEL_5);
2818                         }
2819
2820                         if (super == NULL) {
2821                                 emit_label(cd, BRANCH_LABEL_1);
2822                                 emit_label(cd, BRANCH_LABEL_4);
2823                         }
2824
2825                         emit_store_dst(jd, iptr, d);
2826                         }
2827                         break;
2828
2829                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
2830
2831                         /* check for negative sizes and copy sizes to stack if necessary  */
2832
2833                         MCODECHECK((iptr->s1.argcount << 1) + 64);
2834
2835                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2836                                 /* copy SAVEDVAR sizes to stack */
2837                                 var = VAR(iptr->sx.s23.s2.args[s1]);
2838
2839                                 /* Already Preallocated? */
2840                                 if (!(var->flags & PREALLOC)) {
2841                                         if (var->flags & INMEMORY) {
2842                                                 M_ILD(REG_ITMP1, REG_SP, var->vv.regoff);
2843                                                 M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
2844                                         }
2845                                         else
2846                                                 M_IST(var->vv.regoff, REG_SP, (s1 + 3) * 4);
2847                                 }
2848                         }
2849
2850                         /* is a patcher function set? */
2851
2852                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2853                                 patcher_add_patch_ref(jd, PATCHER_builtin_multianewarray,
2854                                                                         iptr->sx.s23.s3.c.ref, 0);
2855
2856                                 disp = 0;
2857
2858                         }
2859                         else
2860                                 disp = (ptrint) iptr->sx.s23.s3.c.cls;
2861
2862                         /* a0 = dimension count */
2863
2864                         M_IST_IMM(iptr->s1.argcount, REG_SP, 0 * 4);
2865
2866                         /* a1 = arraydescriptor */
2867
2868                         M_IST_IMM(disp, REG_SP, 1 * 4);
2869
2870                         /* a2 = pointer to dimensions = stack pointer */
2871
2872                         M_MOV(REG_SP, REG_ITMP1);
2873                         M_AADD_IMM(3 * 4, REG_ITMP1);
2874                         M_AST(REG_ITMP1, REG_SP, 2 * 4);
2875
2876                         M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2877                         M_CALL(REG_ITMP1);
2878
2879                         /* check for exception before result assignment */
2880
2881                         emit_exception_check(cd, iptr);
2882
2883                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2884                         M_INTMOVE(REG_RESULT, s1);
2885                         emit_store_dst(jd, iptr, s1);
2886                         break;
2887
2888                 default:
2889                         vm_abort("Unknown ICMD %d during code generation", iptr->opc);
2890         } /* switch */
2891 }
2892
2893
2894 /* codegen_emit_stub_native ****************************************************
2895
2896    Emits a stub routine which calls a native method.
2897
2898 *******************************************************************************/
2899
2900 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2901 {
2902         methodinfo  *m;
2903         codeinfo    *code;
2904         codegendata *cd;
2905         methoddesc  *md;
2906         int          i, j;                 /* count variables                    */
2907         int          s1, s2;
2908         int          disp;
2909
2910         /* get required compiler data */
2911
2912         m    = jd->m;
2913         code = jd->code;
2914         cd   = jd->cd;
2915
2916         /* set some variables */
2917
2918         md = m->parseddesc;
2919
2920         /* calculate stackframe size */
2921
2922         cd->stackframesize =
2923                 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2924                 sizeof(localref_table) / SIZEOF_VOID_P +
2925                 4 +                             /* 4 arguments (start_native_call)    */
2926                 nmd->memuse;
2927
2928     /* keep stack 16-byte aligned */
2929
2930         ALIGN_ODD(cd->stackframesize);
2931
2932         /* create method header */
2933
2934         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
2935         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
2936         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
2937         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
2938         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
2939
2940 #if defined(ENABLE_PROFILING)
2941         /* generate native method profiling code */
2942
2943         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
2944                 /* count frequency */
2945
2946                 M_MOV_IMM(code, REG_ITMP1);
2947                 M_IADD_IMM_MEMBASE(1, REG_ITMP1, OFFSET(codeinfo, frequency));
2948         }
2949 #endif
2950
2951         /* calculate stackframe size for native function */
2952
2953         M_ASUB_IMM(cd->stackframesize * 8 + 4, REG_SP);
2954
2955         /* Mark the whole fpu stack as free for native functions (only for saved  */
2956         /* register count == 0).                                                  */
2957
2958         emit_ffree_reg(cd, 0);
2959         emit_ffree_reg(cd, 1);
2960         emit_ffree_reg(cd, 2);
2961         emit_ffree_reg(cd, 3);
2962         emit_ffree_reg(cd, 4);
2963         emit_ffree_reg(cd, 5);
2964         emit_ffree_reg(cd, 6);
2965         emit_ffree_reg(cd, 7);
2966
2967 #if defined(ENABLE_GC_CACAO)
2968         /* remember callee saved int registers in stackframeinfo (GC may need to  */
2969         /* recover them during a collection).                                     */
2970
2971         disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2972                 OFFSET(stackframeinfo_t, intregs);
2973
2974         for (i = 0; i < INT_SAV_CNT; i++)
2975                 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
2976 #endif
2977
2978         /* prepare data structures for native function call */
2979
2980         M_MOV(REG_SP, REG_ITMP1);
2981         M_AST(REG_ITMP1, REG_SP, 0 * 4);
2982         M_IST_IMM(0, REG_SP, 1 * 4);
2983         dseg_adddata(cd);
2984
2985         M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
2986         M_CALL(REG_ITMP1);
2987
2988         /* remember class argument */
2989
2990         if (m->flags & ACC_STATIC)
2991                 M_MOV(REG_RESULT, REG_ITMP3);
2992
2993         /* Copy or spill arguments to new locations. */
2994
2995         for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
2996                 if (!md->params[i].inmemory)
2997                         assert(0);
2998
2999                 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;
3000                 s2 = nmd->params[j].regoff;
3001
3002                 /* float/double in memory can be copied like int/longs */
3003
3004                 switch (md->paramtypes[i].type) {
3005                 case TYPE_INT:
3006                 case TYPE_FLT:
3007                 case TYPE_ADR:
3008                         M_ILD(REG_ITMP1, REG_SP, s1);
3009                         M_IST(REG_ITMP1, REG_SP, s2);
3010                         break;
3011                 case TYPE_LNG:
3012                 case TYPE_DBL:
3013                         M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3014                         M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3015                         break;
3016                 }
3017         }
3018
3019         /* Handle native Java methods. */
3020
3021         if (m->flags & ACC_NATIVE) {
3022                 /* if function is static, put class into second argument */
3023
3024                 if (m->flags & ACC_STATIC)
3025                         M_AST(REG_ITMP3, REG_SP, 1 * 4);
3026
3027                 /* put env into first argument */
3028
3029                 M_AST_IMM(VM_get_jnienv(), REG_SP, 0 * 4);
3030         }
3031
3032         /* Call the native function. */
3033
3034         disp = dseg_add_functionptr(cd, f);
3035         emit_mov_imm_reg(cd, 0, REG_ITMP3);
3036         dseg_adddata(cd);
3037         M_ALD(REG_ITMP1, REG_ITMP3, disp);
3038         M_CALL(REG_ITMP1);
3039
3040         /* save return value */
3041
3042         switch (md->returntype.type) {
3043         case TYPE_INT:
3044         case TYPE_ADR:
3045                 switch (md->returntype.primitivetype) {
3046                 case PRIMITIVETYPE_BOOLEAN:
3047                         M_BZEXT(REG_RESULT, REG_RESULT);
3048                         break;
3049                 case PRIMITIVETYPE_BYTE:
3050                         M_BSEXT(REG_RESULT, REG_RESULT);
3051                         break;
3052                 case PRIMITIVETYPE_CHAR:
3053                         M_CZEXT(REG_RESULT, REG_RESULT);
3054                         break;
3055                 case PRIMITIVETYPE_SHORT:
3056                         M_SSEXT(REG_RESULT, REG_RESULT);
3057                         break;
3058                 }
3059                 M_IST(REG_RESULT, REG_SP, 1 * 8);
3060                 break;
3061         case TYPE_LNG:
3062                 M_LST(REG_RESULT_PACKED, REG_SP, 1 * 8);
3063                 break;
3064         case TYPE_FLT:
3065                 emit_fsts_membase(cd, REG_SP, 1 * 8);
3066                 break;
3067         case TYPE_DBL:
3068                 emit_fstl_membase(cd, REG_SP, 1 * 8);
3069                 break;
3070         case TYPE_VOID:
3071                 break;
3072         }
3073
3074         /* remove native stackframe info */
3075
3076         M_MOV(REG_SP, REG_ITMP1);
3077         M_AST(REG_ITMP1, REG_SP, 0 * 4);
3078         M_IST_IMM(0, REG_SP, 1 * 4);
3079         dseg_adddata(cd);
3080
3081         M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3082         M_CALL(REG_ITMP1);
3083         M_MOV(REG_RESULT, REG_ITMP2);                 /* REG_ITMP3 == REG_RESULT2 */
3084
3085         /* restore return value */
3086
3087         switch (md->returntype.type) {
3088         case TYPE_INT:
3089         case TYPE_ADR:
3090                 M_ILD(REG_RESULT, REG_SP, 1 * 8);
3091                 break;
3092         case TYPE_LNG:
3093                 M_LLD(REG_RESULT_PACKED, REG_SP, 1 * 8);
3094                 break;
3095         case TYPE_FLT:
3096                 emit_flds_membase(cd, REG_SP, 1 * 8);
3097                 break;
3098         case TYPE_DBL:
3099                 emit_fldl_membase(cd, REG_SP, 1 * 8);
3100                 break;
3101         case TYPE_VOID:
3102                 break;
3103         }
3104
3105 #if defined(ENABLE_GC_CACAO)
3106         /* restore callee saved int registers from stackframeinfo (GC might have  */
3107         /* modified them during a collection).                                    */
3108
3109         disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3110                 OFFSET(stackframeinfo_t, intregs);
3111
3112         for (i = 0; i < INT_SAV_CNT; i++)
3113                 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3114 #endif
3115
3116         M_AADD_IMM(cd->stackframesize * 8 + 4, REG_SP);
3117
3118         /* check for exception */
3119
3120         M_TEST(REG_ITMP2);
3121         M_BNE(1);
3122
3123         M_RET;
3124
3125         /* handle exception */
3126
3127         M_MOV(REG_ITMP2, REG_ITMP1_XPTR);
3128         M_ALD(REG_ITMP2_XPC, REG_SP, 0);
3129         M_ASUB_IMM(2, REG_ITMP2_XPC);
3130
3131         M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3132         M_JMP(REG_ITMP3);
3133 }
3134
3135
3136 /*
3137  * These are local overrides for various environment variables in Emacs.
3138  * Please do not remove this and leave it at the end of the file, where
3139  * Emacs will automagically detect them.
3140  * ---------------------------------------------------------------------
3141  * Local variables:
3142  * mode: c
3143  * indent-tabs-mode: t
3144  * c-basic-offset: 4
3145  * tab-width: 4
3146  * End:
3147  * vim:noexpandtab:sw=4:ts=4:
3148  */