* configure.ac: New switch for disabling -O2 (--disable-optimizations).
[cacao.git] / src / vm / jit / m68k / codegen.c
1 /* src/vm/jit/m68k/codegen.c - machine code generator for m68k
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
31 #include "md-abi.h"
32
33 #include "vm/types.h"
34 #include "vm/jit/m68k/codegen.h"
35 #include "vm/jit/m68k/emit.h"
36
37 #include "mm/memory.hpp"
38
39 #include "native/localref.hpp"
40 #include "native/native.hpp"
41
42 #include "threads/lock.hpp"
43
44 #include "vm/jit/builtin.hpp"
45 #include "vm/exceptions.hpp"
46 #include "vm/global.h"
47 #include "vm/loader.hpp"
48 #include "vm/options.h"
49 #include "vm/utf8.h"
50 #include "vm/vm.hpp"
51
52 #include "vm/jit/asmpart.h"
53 #include "vm/jit/codegen-common.hpp"
54 #include "vm/jit/patcher-common.hpp"
55 #include "vm/jit/dseg.h"
56 #include "vm/jit/linenumbertable.hpp"
57 #include "vm/jit/emit-common.hpp"
58 #include "vm/jit/jit.hpp"
59 #include "vm/jit/abi.h"
60 #include "vm/jit/parse.hpp"
61 #include "vm/jit/reg.h"
62 #include "vm/jit/stacktrace.hpp"
63 #include "vm/jit/trap.hpp"
64
65
66 /**
67  * Generates machine code for the method prolog.
68  */
69 void codegen_emit_prolog(jitdata* jd)
70 {
71         varinfo*    var;
72         methoddesc* md;
73         int32_t     s1;
74         int32_t     p, t, l;
75         int32_t     varindex;
76         int         i;
77
78         // Get required compiler data.
79         methodinfo*   m    = jd->m;
80         codeinfo*     code = jd->code;
81         codegendata*  cd   = jd->cd;
82         registerdata* rd   = jd->rd;
83
84         // XXX XXX
85         // XXX Fix the below stuff, cd->stackframesize is a slot counter
86         //     and not a byte counter!!!
87         // XXX XXX
88
89         /* create stack frame */
90         M_AADD_IMM(-(cd->stackframesize), REG_SP);
91
92         /* save used callee saved registers */
93         p = cd->stackframesize;
94         for (i=INT_SAV_CNT-1; i>=rd->savintreguse; --i) {
95                 p-=8; M_IST(rd->savintregs[i], REG_SP, p);
96         }
97         for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
98                 p-=8; M_AST(rd->savadrregs[i], REG_SP, p);
99         }
100 #if !defined(ENABLE_SOFTFLOAT)
101         for (i=FLT_SAV_CNT-1; i>=rd->savfltreguse; --i) {
102                 p-=8; M_FSTORE(rd->savfltregs[i], REG_SP, p);
103         }       
104 #else
105         assert(FLT_SAV_CNT == 0);
106         assert(rd->savfltreguse == 0);
107 #endif
108         /* take arguments out of stack frame */
109         md = m->parseddesc;
110         for (p = 0, l = 0; p < md->paramcount; p++) {
111                 t = md->paramtypes[p].type;
112                 varindex = jd->local_map[l * 5 + t];
113
114                         l++;
115                         if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
116                                 l++;
117
118                 if (varindex == UNUSED)
119                         continue;
120
121                 var = VAR(varindex);
122
123                 s1 = md->params[p].regoff;
124                 assert(md->params[p].inmemory);                 /* all args are on stack */
125
126                 switch (t)      {
127 #if defined(ENABLE_SOFTFLOAT)
128                 case TYPE_FLT:
129                 case TYPE_DBL:
130 #endif
131                 case TYPE_LNG:
132                 case TYPE_INT:
133                         if (!IS_INMEMORY(var->flags)) {      /* stack arg -> register */
134                                 if (IS_2_WORD_TYPE(t))  {
135                                         M_LLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
136                                 } else {
137                                         M_ILD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
138                                 }
139                         } else {                             /* stack arg -> spilled  */
140                                         M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4);
141                                         M_IST(REG_ITMP1, REG_SP, var->vv.regoff);
142                                 if (IS_2_WORD_TYPE(t)) {
143                                         M_ILD(REG_ITMP1, REG_SP, cd->stackframesize  + s1 + 4 + 4);
144                                         M_IST(REG_ITMP1, REG_SP, var->vv.regoff + 4);
145                                 }
146                         } 
147                         break;
148 #if !defined(ENABLE_SOFTFLOAT)
149                 case TYPE_FLT:
150                 case TYPE_DBL:
151                                 if (!IS_INMEMORY(var->flags)) {      /* stack-arg -> register */
152                                 if (IS_2_WORD_TYPE(t))  {
153                                         M_DLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
154                                 } else {
155                                         M_FLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
156                                 }
157                                 } else {                             /* stack-arg -> spilled  */
158                                 if (IS_2_WORD_TYPE(t)) {
159                                         M_DLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
160                                         M_DST(REG_FTMP1, REG_SP, var->vv.regoff);
161                                 } else {
162                                         M_FLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
163                                         M_FST(REG_FTMP1, REG_SP, var->vv.regoff);
164                                 }
165                         }
166                         break;
167 #endif /* SOFTFLOAT */
168                 case TYPE_ADR:
169                                 if (!IS_INMEMORY(var->flags)) {      /* stack-arg -> register */
170                                 M_ALD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
171                                 } else {                             /* stack-arg -> spilled  */
172                                 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + s1 + 4);
173                                 M_AST(REG_ATMP1, REG_SP, var->vv.regoff);
174                         }
175                         break;
176                 default: assert(0);
177                 }
178         } /* end for argument out of stack*/
179 }
180
181
182 /**
183  * Generates machine code for the method epilog.
184  */
185 void codegen_emit_epilog(jitdata* jd)
186 {
187         int32_t p;
188         int i;
189
190         // Get required compiler data.
191         codeinfo*     code = jd->code;
192         codegendata*  cd   = jd->cd;
193         registerdata* rd   = jd->rd;
194
195         p = cd->stackframesize;
196
197         /* restore return address */
198
199 #if 0
200         if (!code_is_leafmethod(code)) {
201                 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
202                    may have a displacement overflow. */
203
204                 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
205                 M_MTLR(REG_ITMP1);
206         }
207 #endif
208
209         /* restore saved registers */
210
211         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
212                 p-=8; M_ILD(rd->savintregs[i], REG_SP, p);
213         }
214         for (i = ADR_SAV_CNT - 1; i >= rd->savadrreguse; --i) {
215                 p-=8; M_ALD(rd->savadrregs[i], REG_SP, p);
216         }
217 #if !defined(ENABLE_SOFTFLOAT)
218         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
219                 p-=8; M_FLOAD(rd->savfltregs[i], REG_SP, p);
220         }
221 #endif
222
223         /* deallocate stack */
224         M_AADD_IMM(cd->stackframesize, REG_SP);
225         M_RET;
226 }
227
228
229 /**
230  * Generates machine code for one ICMD.
231  */
232 void codegen_emit_instruction(jitdata* jd, instruction* iptr)
233 {
234         varinfo*            var;
235         builtintable_entry* bte;
236         methodinfo*         lm;             // Local methodinfo for ICMD_INVOKE*.
237         unresolved_method*  um;
238         fieldinfo*          fi;
239         unresolved_field*   uf;
240         int32_t             fieldtype;
241         int32_t             s1, s2, s3, d;
242         int32_t             disp;
243
244         // Get required compiler data.
245         codeinfo*     code = jd->code;
246         codegendata*  cd   = jd->cd;
247
248         switch (iptr->opc) {
249
250                 /* CONST **************************************************************/
251
252                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
253
254 #if defined(ENABLE_SOFTFLOAT)
255                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
256                         M_IMOV_IMM(iptr->sx.val.i, d);
257                         emit_store_dst(jd, iptr, d);
258 #else
259                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
260                         FCONST(iptr->sx.val.i, d);
261                         emit_store_dst(jd, iptr, d);
262 #endif
263                         break;
264
265                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
266
267 #if defined(ENABLE_SOFTFLOAT)
268                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
269                         LCONST(iptr->sx.val.l, d);
270                         emit_store_dst(jd, iptr, d);
271 #else
272                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
273                         disp = dseg_add_double(cd, iptr->sx.val.d);
274                         M_AMOV_IMM(0, REG_ATMP1);
275                         dseg_adddata(cd);
276                         M_DLD(d, REG_ATMP1, disp);
277                         emit_store_dst(jd, iptr, d);
278 #endif
279                         break;
280
281
282                 /* some long operations *********************************************/
283                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
284                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
285                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
286                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
287                         M_INTMOVE(s2, REG_ITMP1);
288                         M_IADD(s1, REG_ITMP1);                  /* low word */
289                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
290                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
291                         M_INTMOVE(s2, REG_ITMP2);
292                         M_IADDX(s1, REG_ITMP2);                 /* high word */
293                         emit_store_dst(jd, iptr, d);
294                         break;
295                         
296                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
297                                       /* sx.val.l = constant                          */
298                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
299                         s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
300                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
301                         
302                         M_IMOV_IMM(iptr->sx.val.l >> 32, REG_ITMP3);
303
304                         s3 = iptr->sx.val.l & 0xffffffff;
305                         M_INTMOVE(s1, REG_ITMP1);
306                         M_IADD_IMM(s3, REG_ITMP1);              /* lower word in REG_ITMP1 now */
307
308                         M_IADDX(REG_ITMP3, REG_ITMP2);  /* high word in REG_ITMP2 now */
309                         M_LNGMOVE(REG_ITMP12_PACKED, d);
310                         emit_store_dst(jd, iptr, d);
311                         break;
312
313                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
314                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
315                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
316                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
317                         M_INTMOVE(s1, REG_ITMP1);
318                         M_ISUB(s2, REG_ITMP1);                  /* low word */
319                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
320                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
321                         M_INTMOVE(s1, REG_ITMP2);
322                         M_ISUBX(s2, REG_ITMP2);                 /* high word */
323                         emit_store_dst(jd, iptr, d);
324                         break;
325
326                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
327                                       /* sx.val.l = constant                          */
328                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
329                         s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
330                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
331                         
332                         M_IMOV_IMM( (-iptr->sx.val.l) >> 32, REG_ITMP3);
333
334                         s3 = (-iptr->sx.val.l) & 0xffffffff;
335                         M_INTMOVE(s1, REG_ITMP1);
336                         M_IADD_IMM(s3, REG_ITMP1);              /* lower word in REG_ITMP1 now */
337
338                         M_IADDX(REG_ITMP3, REG_ITMP2);  /* high word in REG_ITMP2 now */
339                         M_LNGMOVE(REG_ITMP12_PACKED, d);
340                         emit_store_dst(jd, iptr, d);
341                         break;
342
343                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
344                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
345                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
346                         M_LNGMOVE(s1, REG_ITMP12_PACKED);
347                         M_INEG(GET_LOW_REG(REG_ITMP12_PACKED));
348                         M_INEGX(GET_HIGH_REG(REG_ITMP12_PACKED));
349                         M_LNGMOVE(REG_ITMP12_PACKED, d);
350                         emit_store_dst(jd, iptr, d);
351                         break;
352
353                 /* integer operations ************************************************/
354                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
355
356                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
357                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
358                         M_INTMOVE(s1, REG_ITMP1);
359                         M_INEG(REG_ITMP1);
360                         M_INTMOVE(REG_ITMP1, d);
361                         emit_store_dst(jd, iptr, d);
362                         break;
363
364                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
365
366                         s1 = emit_load_s1(jd, iptr, REG_ITMP3);
367                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
368                         M_IMOV(s1, GET_LOW_REG(d));                             /* sets negativ bit */
369                         M_BPL(4);
370                         M_ISET(GET_HIGH_REG(d));
371                         M_TPFW;
372                         M_ICLR(GET_HIGH_REG(d));
373
374                         emit_store_dst(jd, iptr, d);
375                         break;
376
377                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
378
379                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
380                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
381                         M_INTMOVE(s1, d);
382                         emit_store_dst(jd, iptr, d);
383                         break;
384                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
385
386                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
387                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
388                         M_BSEXT(s1, d);
389                         emit_store_dst(jd, iptr, d);
390                         break;
391
392                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
393
394                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
395                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
396                         M_CZEXT(s1, d);
397                         emit_store_dst(jd, iptr, d);
398                         break;
399
400                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
401
402                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
403                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
404                         M_SSEXT(s1, d);
405                         emit_store_dst(jd, iptr, d);
406                         break;
407
408
409
410                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
411
412                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
413                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
414                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
415                         M_INTMOVE(s2, REG_ITMP2);
416                         M_IADD(s1, REG_ITMP2);
417                         M_INTMOVE(REG_ITMP2, d);
418                         emit_store_dst(jd, iptr, d);
419                         break;
420
421                                       /* s1.localindex = variable, sx.val.i = constant*/
422
423                 case ICMD_IINC:
424                 case ICMD_IADDCONST:
425
426                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
427                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
428                         M_INTMOVE(s1, REG_ITMP1);
429                         M_IADD_IMM(iptr->sx.val.i, REG_ITMP1);
430                         M_INTMOVE(REG_ITMP1, d);
431                         emit_store_dst(jd, iptr, d);
432                         break;
433
434                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
435
436                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
437                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
438                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
439                         M_INTMOVE(s1, REG_ITMP1);
440                         M_ISUB(s2, REG_ITMP1);
441                         M_INTMOVE(REG_ITMP1, d);
442                         emit_store_dst(jd, iptr, d);
443                         break;
444
445                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
446                                       /* sx.val.i = constant                          */
447
448                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
449                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
450                         M_INTMOVE(s1, REG_ITMP1);
451                         M_IADD_IMM(-iptr->sx.val.i, REG_ITMP1);
452                         M_INTMOVE(REG_ITMP1, d);
453                         emit_store_dst(jd, iptr, d);
454                         break;
455
456                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
457                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
458                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
459                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
460                         emit_arithmetic_check(cd, iptr, s2);
461                         M_INTMOVE(s1, REG_ITMP1);
462                         M_IDIV(s2, REG_ITMP1);
463                         M_INTMOVE(REG_ITMP1, d);
464                         emit_store_dst(jd, iptr, d);
465                         break;
466
467                 case ICMD_IDIVPOW2:             /* ..., value  ==> ..., value << constant       */
468                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
469                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
470                         M_INTMOVE(s1, REG_ITMP1);
471
472                         M_ITST(REG_ITMP1);
473                         M_BPL(6);
474                         M_IADD_IMM((1 << iptr->sx.val.i) - 1, REG_ITMP1);
475
476                         M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
477                         M_ISSR(REG_ITMP2, REG_ITMP1);
478                         M_INTMOVE(REG_ITMP1, d);
479                         emit_store_dst(jd, iptr, d);
480                         break;
481
482                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
483                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
484                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
485                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
486                         emit_arithmetic_check(cd, iptr, s2);
487
488                         M_ICMP_IMM(0x80000000, s1);
489                         M_BNE(4+8);
490                         M_ICMP_IMM(-1, s2);
491                         M_BNE(4);
492                         M_ICLR(REG_ITMP3);
493                         M_TPFL;                                 /* hides the next instruction */
494                         M_IREM(s2, s1, REG_ITMP3);
495
496                         M_INTMOVE(REG_ITMP3, d);
497
498                         emit_store_dst(jd, iptr, d);
499                         break;
500
501                 case ICMD_IREMPOW2:             /* ..., value  ==> ..., value << constant       */
502                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
503                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
504                         if (s1 == d) {
505                                 M_IMOV(s1, REG_ITMP1);
506                                 s1 = REG_ITMP1;
507                         } 
508                         M_INTMOVE(s1, d);
509                         M_IAND_IMM(iptr->sx.val.i, d);
510                         M_ITST(s1);
511                         M_BGE(2 + 2 + 6 + 2);
512                         M_IMOV(s1, d);  /* don't use M_INTMOVE, so we know the jump offset */
513                         M_INEG(d);
514                         M_IAND_IMM(iptr->sx.val.i, d);     /* use 32-bit for jump offset */
515                         M_INEG(d);
516
517                         emit_store_dst(jd, iptr, d);
518                         break;
519
520
521                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
522                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
523
524                         bte = iptr->sx.s23.s3.bte;
525                         md  = bte->md;
526
527                         s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
528                         M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
529                         M_IOR(GET_HIGH_REG(s2), REG_ITMP3);
530                         /* XXX could be optimized */
531                         emit_arithmetic_check(cd, iptr, REG_ITMP3);
532
533                         M_LST(s2, REG_SP, 2 * 4);
534                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
535                         M_LST(s1, REG_SP, 0 * 4);
536
537                         M_JSR_IMM(bte->fp);
538
539                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
540                         M_LNGMOVE(REG_RESULT_PACKED, d);
541                         emit_store_dst(jd, iptr, d);
542                         break;
543
544                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
545
546                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
547                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
548                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
549                         M_INTMOVE(s2, REG_ITMP2);
550                         M_IMUL(s1, REG_ITMP2);
551                         M_INTMOVE(REG_ITMP2, d);
552                         emit_store_dst(jd, iptr, d);
553                         break;
554
555                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
556                                       /* sx.val.i = constant                          */
557                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
558                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
559                         M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
560                         M_IMUL(s1, REG_ITMP2);
561                         M_INTMOVE(REG_ITMP2, d);
562                         emit_store_dst(jd, iptr, d);
563                         break;
564
565                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
566
567                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
568                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
569                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
570                         M_INTMOVE(s1, REG_ITMP1);
571                         M_INTMOVE(s2, REG_ITMP2);
572                         M_IAND_IMM(0x1f, REG_ITMP2);
573                         M_ISSL(REG_ITMP2, REG_ITMP1);
574                         M_INTMOVE(REG_ITMP1, d);
575                         emit_store_dst(jd, iptr, d);
576                         break;
577
578                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
579                                       /* sx.val.i = constant                          */
580
581                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
582                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
583                         if (iptr->sx.val.i & 0x1f)      {
584                                 M_INTMOVE(s1, REG_ITMP1)
585                                 if ((iptr->sx.val.i & 0x1f) <= 7)       {
586                                         M_ISSL_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
587                                 } else  {
588                                         M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
589                                         M_ISSL(REG_ITMP2, REG_ITMP1);
590                                 }
591                                 M_INTMOVE(REG_ITMP1, d);
592                         } else  {
593                                 M_INTMOVE(s1, d);
594                         }
595                         emit_store_dst(jd, iptr, d);
596                         break;
597
598                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
599
600                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
601                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
602                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
603                         M_INTMOVE(s1, REG_ITMP1);
604                         M_INTMOVE(s2, REG_ITMP2);
605                         M_IAND_IMM(0x1f, REG_ITMP2);
606                         M_ISSR(REG_ITMP2, REG_ITMP1);
607                         M_INTMOVE(REG_ITMP1, d);
608                         emit_store_dst(jd, iptr, d);
609                         break;
610
611                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
612                                       /* sx.val.i = constant                          */
613
614                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
615                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
616                         if (iptr->sx.val.i & 0x1f)      {
617                                 M_INTMOVE(s1, REG_ITMP1)
618                                 if ((iptr->sx.val.i & 0x1f) <= 7)       {
619                                         M_ISSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
620                                 } else  {
621                                         M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
622                                         M_ISSR(REG_ITMP2, REG_ITMP1);
623                                 }
624                                 M_INTMOVE(REG_ITMP1, d);
625                         } else  {
626                                 M_INTMOVE(s1, d);
627                         }
628                         emit_store_dst(jd, iptr, d);
629                         break;
630
631                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
632
633                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
634                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
635                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
636                         M_INTMOVE(s1, REG_ITMP1);
637                         M_INTMOVE(s2, REG_ITMP2);
638                         M_IAND_IMM(0x1f, REG_ITMP2);
639                         M_IUSR(REG_ITMP2, REG_ITMP1);
640                         M_INTMOVE(REG_ITMP1, d);
641                         emit_store_dst(jd, iptr, d);
642                         break;
643
644                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
645                                       /* sx.val.i = constant                          */
646                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
647                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
648                         if (iptr->sx.val.i & 0x1f)      {
649                                 M_INTMOVE(s1, REG_ITMP1)
650                                 if ((iptr->sx.val.i & 0x1f) <= 7)       {
651                                         M_IUSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
652                                 } else  {
653                                         M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
654                                         M_IUSR(REG_ITMP2, REG_ITMP1);
655                                 }
656                                 M_INTMOVE(REG_ITMP1, d);
657                         } else  {
658                                 M_INTMOVE(s1, d);
659                         }
660                         emit_store_dst(jd, iptr, d);
661                         break;
662
663                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
664
665                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
666                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
667                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
668                         M_INTMOVE(s2, REG_ITMP2);
669                         M_IAND(s1, REG_ITMP2);
670                         M_INTMOVE(REG_ITMP2, d);
671                         emit_store_dst(jd, iptr, d);
672                         break;
673
674                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
675                                       /* sx.val.i = constant                          */
676
677                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
678                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
679                         M_INTMOVE(s1, REG_ITMP1);
680                         M_IAND_IMM(iptr->sx.val.i, REG_ITMP1);
681                         M_INTMOVE(REG_ITMP1, d);
682                         emit_store_dst(jd, iptr, d);
683                         break;
684
685                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
686                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
687                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
688                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
689                         M_INTMOVE(s2, REG_ITMP2);
690                         M_IOR(s1, REG_ITMP2);
691                         M_INTMOVE(REG_ITMP2, d);
692                         emit_store_dst(jd, iptr, d);
693                         break;
694
695                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
696                                       /* sx.val.i = constant                          */
697                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
698                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
699                         M_INTMOVE(s1, REG_ITMP1);
700                         M_IOR_IMM(iptr->sx.val.i, REG_ITMP1);
701                         M_INTMOVE(REG_ITMP1, d);
702                         emit_store_dst(jd, iptr, d);
703                         break;
704
705                 case ICMD_IXOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
706                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
707                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
708                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
709                         M_INTMOVE(s2, REG_ITMP2);
710                         M_IXOR(s1, REG_ITMP2);
711                         M_INTMOVE(REG_ITMP2, d);
712                         emit_store_dst(jd, iptr, d);
713                         break;
714
715                 case ICMD_IXORCONST:   /* ..., value  ==> ..., value | constant        */
716                                       /* sx.val.i = constant                          */
717                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
718                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
719                         M_INTMOVE(s1, REG_ITMP1);
720                         M_IXOR_IMM(iptr->sx.val.i, REG_ITMP1);
721                         M_INTMOVE(REG_ITMP1, d);
722                         emit_store_dst(jd, iptr, d);
723                         break;
724
725                 /* floating point operations ******************************************/
726                 #if !defined(ENABLE_SOFTFLOAT)
727                 case ICMD_FCMPL:                /* ..., val1, val2  ==> ..., val1 fcmpl val2  */
728                 case ICMD_DCMPL:
729                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
730                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
731                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
732                         M_IMOV_IMM(-1, d);
733                         M_FCMP(s1, s2);
734                         M_BFUN(14);     /* result is -1, branch to end */
735                         M_BFLT(10);     /* result is -1, branch to end */
736                         M_IMOV_IMM(0, d);
737                         M_BFEQ(4)       /* result is 0, branch to end */
738                         M_IMOV_IMM(1, d);
739                         emit_store_dst(jd, iptr, d);
740                         break;
741
742                 case ICMD_FCMPG:                /* ..., val1, val2  ==> ..., val1 fcmpg val2  */
743                 case ICMD_DCMPG:
744                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
745                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
746                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
747                         M_IMOV_IMM(1, d);
748                         M_FCMP(s1, s2);
749                         M_BFUN(16);     /* result is +1, branch to end */
750                         M_BFGT(14);     /* result is +1, branch to end */
751                         M_IMOV_IMM(0, d);
752                         M_BFEQ(8)       /* result is 0, branch to end */
753                         M_IMOV_IMM(-1, d);
754                         emit_store_dst(jd, iptr, d);
755                         break;
756
757                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
758                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
759                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
760                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
761                         emit_fmove(cd, s2, REG_FTMP2);
762                         M_FMUL(s1, REG_FTMP2);
763                         emit_fmove(cd, REG_FTMP2, d);
764                         emit_store_dst(jd, iptr, d);
765                         break;
766
767                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
768                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
769                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
770                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
771                         emit_dmove(cd, s2, REG_FTMP2);
772                         M_DMUL(s1, REG_FTMP2);
773                         emit_dmove(cd, REG_FTMP2, d);
774                         emit_store_dst(jd, iptr, d);
775                         break;
776
777                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
778                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
779                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
780                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
781                         emit_fmove(cd, s1, REG_FTMP1);
782                         M_FDIV(s2, REG_FTMP1);
783                         emit_fmove(cd, REG_FTMP1, d);
784                         emit_store_dst(jd, iptr, d);
785                         break;
786
787                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
788                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
789                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
790                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
791                         emit_dmove(cd, s1, REG_FTMP1);
792                         M_DDIV(s2, REG_FTMP1);
793                         emit_dmove(cd, REG_FTMP1, d);
794                         emit_store_dst(jd, iptr, d);
795                         break;
796
797                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
798                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
799                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
800                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
801                         emit_fmove(cd, s2, REG_FTMP2);
802                         M_FADD(s1, REG_FTMP2);
803                         emit_fmove(cd, REG_FTMP2, d);
804                         emit_store_dst(jd, iptr, d);
805                         break;
806
807                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
808                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
809                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
810                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
811                         emit_dmove(cd, s2, REG_FTMP2);
812                         M_DADD(s1, REG_FTMP2);
813                         emit_dmove(cd, REG_FTMP2, d);
814                         emit_store_dst(jd, iptr, d);
815                         break;
816
817                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
818                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
819                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
820                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
821                         emit_fmove(cd, s1, REG_FTMP1);
822                         M_FSUB(s2, REG_FTMP1);
823                         emit_fmove(cd, REG_FTMP1, d);
824                         emit_store_dst(jd, iptr, d);
825                         break;
826
827                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
828                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
829                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
830                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
831                         emit_dmove(cd, s1, REG_FTMP1);
832                         M_DSUB(s2, REG_FTMP1);
833                         emit_dmove(cd, REG_FTMP1, d);
834                         emit_store_dst(jd, iptr, d);
835                         break;
836
837                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
838                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
839                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
840                         M_F2D(s1, d);
841                         emit_store_dst(jd, iptr, d);
842                         break;
843
844                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value           */
845                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
846                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
847                         M_D2F(s1, d);
848                         emit_store_dst(jd, iptr, d);
849                         break;
850
851                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
852                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
853                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
854                         M_FNEG(s1, d);
855                         emit_store_dst(jd, iptr, d);
856                         break;
857
858                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
859                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
860                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
861                         M_DNEG(s1, d);
862                         emit_store_dst(jd, iptr, d);
863                         break;
864
865                 #endif
866
867
868                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
869                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
870
871                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
872                                 constant_classref *cr = iptr->sx.val.c.ref;;
873                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, cr, 0);
874                                 M_AMOV_IMM(0, d);
875                         } else {
876                                 M_AMOV_IMM(iptr->sx.val.anyptr, d);
877                         }
878                         emit_store_dst(jd, iptr, d);
879                         break;
880                 /* BRANCH *************************************************************/
881
882                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
883
884                         M_JSR_PCREL(2);                         /* get current PC */
885                         M_APOP(REG_ATMP2);              
886
887                         M_AMOV_IMM(asm_handle_exception, REG_ATMP3);
888                         M_JMP(REG_ATMP3);
889                         break;
890
891                 /* MEMORY *************************************************************/
892
893                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
894
895                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
896                                 uf        = iptr->sx.s23.s3.uf;
897                                 fieldtype = uf->fieldref->parseddesc.fd->type;
898                                 disp      = 0;
899
900                                 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
901                         }
902                         else {
903                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
904                                 fieldtype = fi->type;
905                                 disp      = (intptr_t) fi->value;
906
907                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
908                                         patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
909                                                                                 0);
910                                 }
911                         }
912
913                         M_AMOV_IMM(disp, REG_ATMP1);
914                         switch (fieldtype) {
915 #if defined(ENABLE_SOFTFLOAT)
916                         case TYPE_FLT:
917 #endif
918                         case TYPE_INT:
919                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
920                                 M_ILD(d, REG_ATMP1, 0);
921                                 break;
922                         case TYPE_ADR:
923                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
924                                 M_ALD(d, REG_ATMP1, 0);
925                                 break;
926 #if defined(ENABLE_SOFTFLOAT)
927                         case TYPE_DBL:
928 #endif
929                         case TYPE_LNG:
930                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
931                                 M_LLD(d, REG_ATMP1, 0);
932                                 break;
933 #if !defined(ENABLE_SOFTFLOAT)
934                         case TYPE_FLT:
935                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
936                                 M_FLD(d, REG_ATMP1, 0);
937                                 break;
938                         case TYPE_DBL:                          
939                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
940                                 M_DLD(d, REG_ATMP1, 0);
941                                 break;
942 #endif
943                         }
944                         emit_store_dst(jd, iptr, d);
945                         break;
946
947                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
948
949                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
950                                 uf        = iptr->sx.s23.s3.uf;
951                                 fieldtype = uf->fieldref->parseddesc.fd->type;
952                                 disp      = 0;
953
954                                 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
955                         }
956                         else {
957                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
958                                 fieldtype = fi->type;
959                                 disp      = (intptr_t) fi->value;
960
961                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
962                                         patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
963                                                                                 0);
964                         }
965                 
966                         M_AMOV_IMM(disp, REG_ATMP1);
967                         switch (fieldtype) {
968 #if defined(ENABLE_SOFTFLOAT)
969                         case TYPE_FLT:
970 #endif
971                         case TYPE_INT:
972                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
973                                 M_IST(s1, REG_ATMP1, 0);
974                                 break;
975 #if defined(ENABLE_SOFTFLOAT)
976                         case TYPE_DBL:
977 #endif
978                         case TYPE_LNG:
979                                 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
980                                 M_LST(s1, REG_ATMP1, 0);
981                                 break;
982                         case TYPE_ADR:
983                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
984                                 M_AST(s1, REG_ATMP1, 0);
985                                 break;
986 #if !defined(ENABLE_SOFTFLOAT)
987                         case TYPE_FLT:
988                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
989                                 M_FST(s1, REG_ATMP1, 0);
990                                 break;
991                         case TYPE_DBL:
992                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
993                                 M_DST(s1, REG_ATMP1, 0);
994                                 break;
995 #endif
996                         default: assert(0);
997                         }
998                         break;
999
1000                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
1001
1002                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1003
1004                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1005                                 uf        = iptr->sx.s23.s3.uf;
1006                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1007                                 disp      = 0;
1008
1009                                 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1010                         }
1011                         else {
1012                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1013                                 fieldtype = fi->type;
1014                                 disp      = fi->offset;
1015                         }
1016
1017                         /* implicit null-pointer check */
1018                         switch (fieldtype) {
1019 #if defined(ENABLE_SOFTFLOAT)
1020                         case TYPE_FLT:
1021 #endif
1022                         case TYPE_INT:
1023                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1024                                 M_ILD(d, s1, disp);
1025                                 break;
1026 #if defined(ENABLE_SOFTFLOAT)
1027                         case TYPE_DBL:
1028 #endif
1029                         case TYPE_LNG:
1030                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1031                                 M_LLD(d, s1, disp);
1032                                 break;
1033                         case TYPE_ADR:
1034                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1035                                 M_ALD(d, s1, disp);
1036                                 break;
1037 #if !defined(ENABLE_SOFTFLOAT)
1038                         case TYPE_FLT:
1039                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1040                                 M_FLD(d, s1, disp);
1041                                 break;
1042                         case TYPE_DBL:                          
1043                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1044                                 M_DLD(d, s1, disp);
1045                                 break;
1046 #endif
1047                         }
1048                         emit_store_dst(jd, iptr, d);
1049                         break;
1050
1051                 case ICMD_PUTFIELD:   /* ..., value  ==> ...                          */
1052
1053                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1054
1055                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1056                                 uf        = iptr->sx.s23.s3.uf;
1057                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1058                                 disp      = 0;
1059                         }
1060                         else {
1061                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1062                                 fieldtype = fi->type;
1063                                 disp      = fi->offset;
1064                         }
1065
1066                         if (IS_INT_LNG_TYPE(fieldtype)) {
1067                                 if (IS_2_WORD_TYPE(fieldtype)) {
1068                                         s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1069                                 } else {
1070                                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1071                                 }
1072                         } else {
1073                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1074                         }
1075
1076                         if (INSTRUCTION_IS_UNRESOLVED(iptr))
1077                                 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1078
1079                         /* implicit null-pointer check */
1080                         switch (fieldtype) {
1081 #if defined(ENABLE_SOFTFLOAT)
1082                         case TYPE_FLT:
1083 #endif
1084                         case TYPE_INT:
1085                                 M_IST(s2, s1, disp);
1086                                 break;
1087
1088 #if defined(ENABLE_SOFTFLOAT)
1089                         case TYPE_DBL:
1090 #endif
1091                         case TYPE_LNG:
1092                                 M_LST(s2, s1, disp);  
1093                                 break;
1094                         case TYPE_ADR:
1095                                 M_AST(s2, s1, disp);
1096                                 break;
1097 #if !defined(ENABLE_SOFTFLOAT)
1098                         case TYPE_FLT:
1099                                 M_FST(s2, s1, disp);
1100                                 break;
1101                         case TYPE_DBL:
1102                                 M_DST(s2, s1, disp);
1103                                 break;
1104 #endif
1105                         }
1106                         break;
1107
1108                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1109
1110                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1111                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1112                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1113                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1114                         M_INTMOVE(s2, REG_ITMP2);
1115                         M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1116                         M_ADRMOVE(s1, REG_ATMP1);
1117                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1118                         /* implicit null-pointer check */
1119                         M_LBZX(REG_ATMP1, d);
1120                         M_BSEXT(d, d);
1121                         emit_store_dst(jd, iptr, d);
1122                         break;                  
1123
1124                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1125
1126                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1127                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1128                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1129                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1130                         M_INTMOVE(s2, REG_ITMP2);
1131                         M_ISSL_IMM(1, REG_ITMP2);
1132                         M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1133                         M_ADRMOVE(s1, REG_ATMP1);
1134                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1135                         /* implicit null-pointer check */
1136                         M_LHZX(REG_ATMP1, d);
1137                         M_CZEXT(d, d);
1138                         emit_store_dst(jd, iptr, d);
1139                         break;
1140
1141                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1142
1143                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1144                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1145                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1146                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1147                         M_INTMOVE(s2, REG_ITMP2);
1148                         M_ISSL_IMM(1, REG_ITMP2);
1149                         M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1150                         M_ADRMOVE(s1, REG_ATMP1);
1151                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1152                 
1153                         /* implicit null-pointer check */
1154                         M_LHZX(REG_ATMP1, d);
1155                         M_SSEXT(d, d);
1156                         emit_store_dst(jd, iptr, d);
1157                         break;
1158
1159                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1160
1161                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1162                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1163                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1164                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1165                         M_INTMOVE(s2, REG_ITMP2);
1166                         M_ISSL_IMM(2, REG_ITMP2);
1167                         M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1168                         M_ADRMOVE(s1, REG_ATMP1);
1169                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1170                         /* implicit null-pointer check */
1171                         M_LWZX(REG_ATMP1, d);
1172                         emit_store_dst(jd, iptr, d);
1173                         break;
1174
1175                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1176                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1177                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1178                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1179                         /* implicit null-pointer check */
1180                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1181                         M_INTMOVE(s2, REG_ITMP1);
1182                         M_ISSL_IMM(3, REG_ITMP1);
1183                         M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1184                         M_ADRMOVE(s1, REG_ATMP1);
1185                         M_AADDINT(REG_ITMP1, REG_ATMP1);
1186                         /* implicit null-pointer check */
1187                         M_LLD(d, REG_ATMP1, 0);
1188                         emit_store_dst(jd, iptr, d);
1189                         break;
1190
1191                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1192                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1193                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1194                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1195                         M_INTMOVE(s2, REG_ITMP2);
1196                         M_ISSL_IMM(2, REG_ITMP2);
1197                         M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1198                         M_ADRMOVE(s1, REG_ATMP1);
1199                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1200                         /* implicit null-pointer check */
1201 #if !defined(ENABLE_SOFTFLOAT)
1202                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1203                         M_FLD(d, REG_ATMP1, 0);
1204 #else
1205                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1206                         M_LWZX(REG_ATMP1, d);
1207 #endif
1208                         emit_store_dst(jd, iptr, d);
1209                         break;
1210
1211                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1212                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1213                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1214                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1215                         M_INTMOVE(s2, REG_ITMP2);
1216                         M_ISSL_IMM(3, REG_ITMP2);
1217                         M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1218                         M_ADRMOVE(s1, REG_ATMP1);
1219                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1220                         /* implicit null-pointer check */
1221 #if !defined(ENABLE_SOFTFLOAT)
1222                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1223                         M_DLD(d, REG_ATMP1, 0);
1224 #else
1225                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1226                         M_LLD(d, REG_ATMP1, 0);
1227 #endif
1228                         emit_store_dst(jd, iptr, d);
1229                         break;
1230
1231                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1232                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1233                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1234                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1235                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1236                         M_INTMOVE(s2, REG_ITMP2);
1237                         M_ISSL_IMM(2, REG_ITMP2);
1238                         M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1239                         M_ADRMOVE(s1, REG_ATMP1);
1240                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1241         
1242                         /* implicit null-pointer check */
1243                         M_LAX(REG_ATMP1, d);
1244                         emit_store_dst(jd, iptr, d);
1245                         break;
1246
1247
1248                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1249                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1250                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1251                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1252                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1253                         M_INTMOVE(s2, REG_ITMP2);
1254                         M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1255                         M_ADRMOVE(s1, REG_ATMP1);
1256                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1257                         /* implicit null-pointer check */
1258                         M_STBX(REG_ATMP1, s3);
1259                         break;
1260
1261                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1262                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1263                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1264                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1265                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1266                         M_INTMOVE(s2, REG_ITMP2);
1267                         M_ISSL_IMM(1, REG_ITMP2);
1268                         M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2); 
1269                         M_ADRMOVE(s1, REG_ATMP1);
1270                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1271                         /* implicit null-pointer check */
1272                         M_STHX(REG_ATMP1, s3);
1273                         break;
1274
1275                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1276                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1277                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1278                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1279                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1280                         M_INTMOVE(s2, REG_ITMP2);
1281                         M_ISSL_IMM(1, REG_ITMP2);
1282                         M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1283                         M_ADRMOVE(s1, REG_ATMP1);
1284                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1285                         /* implicit null-pointer check */
1286                         M_STHX(REG_ATMP1, s3);
1287                         break;
1288
1289                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1290                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1291                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1292                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1293                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1294                         M_INTMOVE(s2, REG_ITMP2);
1295                         M_ISSL_IMM(2, REG_ITMP2);
1296                         M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1297                         M_ADRMOVE(s1, REG_ATMP1);
1298                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1299                         /* implicit null-pointer check */
1300                         M_STWX(REG_ATMP1, s3);
1301                         break;
1302
1303                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1304                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1305                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1306                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1307
1308                         M_INTMOVE(s2, REG_ITMP1);
1309                         M_ISSL_IMM(3, REG_ITMP1);
1310                         M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1311                         M_ADRMOVE(s1, REG_ATMP1);
1312                         M_AADDINT(REG_ITMP1, REG_ATMP1);
1313                         /* implicit null-pointer check */
1314                         s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1315                         M_LST(s3, REG_ATMP1, 0);
1316                         break;
1317
1318                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1319                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1320                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1321                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1322                         M_INTMOVE(s2, REG_ITMP2);
1323                         M_ISSL_IMM(2, REG_ITMP2);
1324                         M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1325                         M_ADRMOVE(s1, REG_ATMP1);
1326                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1327                         /* implicit null-pointer check */
1328 #if !defined(ENABLE_SOFTFLOAT)
1329                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1330                         M_FST(s3, REG_ATMP1, 0);
1331 #else
1332                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1333                         M_STWX(REG_ATMP1, s3);
1334 #endif
1335                         break;
1336
1337                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1338                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1339                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1340                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1341                         M_INTMOVE(s2, REG_ITMP2);
1342                         M_ISSL_IMM(3, REG_ITMP2);
1343                         M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1344                         M_ADRMOVE(s1, REG_ATMP1);
1345                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1346                         /* implicit null-pointer check */
1347 #if !defined(ENABLE_SOFTFLOAT)
1348                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1349                         M_DST(s3, REG_ATMP1, 0);
1350 #else
1351                         s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1352                         /* implicit null-pointer check */
1353                         M_LST(s3, REG_ATMP1, 0);
1354 #endif
1355                         break;
1356
1357                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1358
1359                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1360                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1361                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1362                         s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1363
1364                         /* XXX what if array is NULL */
1365                         disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1366
1367                         M_AST(s1, REG_SP, 0*4);
1368                         M_AST(s3, REG_SP, 1*4);
1369                         M_JSR_IMM(BUILTIN_FAST_canstore);
1370                         emit_arraystore_check(cd, iptr);
1371
1372                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1373                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1374                         s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1375                         M_INTMOVE(s2, REG_ITMP1);
1376                         M_ISSL_IMM(2, REG_ITMP1);
1377                         M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP1);
1378                         M_ADRMOVE(s1, REG_ATMP1);
1379                         M_AADDINT(REG_ITMP1, REG_ATMP1);
1380                         /* implicit null-pointer check */
1381                         M_STAX(REG_ATMP1, s3);
1382                         break;
1383
1384
1385
1386                 /* METHOD INVOCATION *********************************************************/
1387                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
1388                         bte = iptr->sx.s23.s3.bte;
1389                         if (bte->stub == NULL)
1390                                 disp = (ptrint) bte->fp;
1391                         else
1392                                 disp = (ptrint) bte->stub;
1393                         M_JSR_IMM(disp);
1394                         break;
1395
1396                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1397                         /* adress register for sure */
1398                         M_ALD(REG_ATMP1, REG_SP, 0);
1399                         emit_nullpointer_check(cd, iptr, REG_ATMP1);
1400                         /* fall through */
1401
1402                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
1403                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1404                                 um = iptr->sx.s23.s3.um;
1405                                 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um, 0);
1406                                 disp = 0;
1407                                 M_AMOV_IMM(disp, REG_ATMP1);
1408                         } else  {
1409                                 lm = iptr->sx.s23.s3.fmiref->p.method;
1410                                 disp = lm->stubroutine;
1411                                 M_AMOV_IMM(disp, REG_ATMP1);
1412                         }
1413
1414                         /* generate the actual call */
1415                         M_JSR(REG_ATMP1);
1416                         break;
1417
1418                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
1419                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1420                                 um = iptr->sx.s23.s3.um;
1421                                 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
1422                                 s1 = 0;
1423                         } else {
1424                                 lm = iptr->sx.s23.s3.fmiref->p.method;
1425                                 s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
1426                         }
1427                         /* load object pointer (==argument 0) */
1428                         M_ALD(REG_ATMP1, REG_SP, 0);
1429                         /* implicit null-pointer check */
1430                         M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1431                         M_ALD(REG_ATMP3, REG_METHODPTR, s1);
1432                         /* generate the actual call */
1433                         M_JSR(REG_ATMP3);
1434                         break;
1435
1436                 case ICMD_INVOKEINTERFACE:
1437                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1438                                 um = iptr->sx.s23.s3.um;
1439                                 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
1440
1441                                 s1 = 0;
1442                                 s2 = 0;
1443                         } else {
1444                                 lm = iptr->sx.s23.s3.fmiref->p.method;
1445                                 s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->clazz->index;
1446                                 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
1447                         }
1448                         /* load object pointer (==argument 0) */
1449                         M_ALD(REG_ATMP1, REG_SP, 0);
1450
1451                         /* implicit null-pointer check */
1452                         M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1453                         M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
1454                         M_ALD(REG_ATMP3, REG_METHODPTR, s2);
1455
1456                         /* generate the actual call */
1457                         M_JSR(REG_ATMP3);
1458                         break;
1459
1460 XXXXXX
1461
1462                                 switch (d)      {
1463                                         case TYPE_ADR:
1464                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_ATMP1);
1465                                                 /* all stuff is returned in %d0 */
1466                                                 M_INT2ADRMOVE(REG_RESULT, s1);
1467                                                 break;
1468 #if !defined(ENABLE_SOFTFLOAT)
1469                                         /*
1470                                          *      for BUILTINS float values are returned in %d0,%d1
1471                                          *      within cacao we use %fp0 for that.
1472                                          */
1473                                         case TYPE_FLT:
1474                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1475                                                 if (iptr->opc == ICMD_BUILTIN)  {
1476                                                         M_INT2FLTMOVE(REG_FRESULT, s1);
1477                                                 } else  {
1478                                                         emit_fmove(cd, REG_FRESULT, s1);
1479                                                 }
1480                                                 break;
1481                                         case TYPE_DBL:
1482                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1483                                                 if (iptr->opc == ICMD_BUILTIN)  {
1484                                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
1485                                                         M_DLD(s1, REG_SP, rd->memuse * 4 + 4);
1486                                                 } else  {
1487                                                         emit_dmove(cd, REG_FRESULT, s1);
1488                                                 }
1489                                                 break;
1490 #endif
1491                                 }
1492
1493 XXXXXXX
1494
1495                 /* the evil ones */
1496                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
1497                                       /* val.a: (classinfo*) superclass               */
1498
1499                         /*  superclass is an interface:
1500                          *
1501                          *  return (sub != NULL) &&
1502                          *         (sub->vftbl->interfacetablelength > super->index) &&
1503                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
1504                          *
1505                          *  superclass is a class:
1506                          *
1507                          *  return ((sub != NULL) && (0
1508                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1509                          *          super->vftbl->diffvall));
1510                          */
1511
1512                         {
1513                         classinfo *super;
1514                         s4         superindex;
1515
1516                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1517                                 super      = NULL;
1518                                 superindex = 0;
1519                         }
1520                         else {
1521                                 super      = iptr->sx.s23.s3.c.cls;
1522                                 superindex = super->index;
1523                         }
1524                         
1525                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1526                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1527
1528                         assert(VAROP(iptr->s1 )->type == TYPE_ADR);
1529                         assert(VAROP(iptr->dst)->type == TYPE_INT);
1530
1531                         M_ICLR(d);
1532
1533                         /* if class is not resolved, check which code to call */
1534
1535                         if (super == NULL) {
1536                                 M_ATST(s1);
1537                                 emit_label_beq(cd, BRANCH_LABEL_1);
1538
1539                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
1540
1541                                 M_IMOV_IMM32(0, REG_ITMP3);
1542                                 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
1543                                 emit_label_beq(cd, BRANCH_LABEL_2);
1544                         }
1545
1546                         /* interface instanceof code */
1547
1548                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1549                                 if (super == NULL) {
1550                                         patcher_add_patch_ref(jd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
1551                                 } else {
1552                                         M_ATST(s1);
1553                                         emit_label_beq(cd, BRANCH_LABEL_3);
1554                                 }
1555
1556                                 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
1557                                 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
1558                                 M_IADD_IMM(-superindex, REG_ITMP3);     /* -superindex may be patched patched */
1559                                 M_ITST(REG_ITMP3);
1560                                 M_BLE(10);
1561                                 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patch here too! */
1562                                 M_ATST(REG_ATMP1);
1563                                 M_BEQ(2);
1564                                 M_IMOV_IMM(1, d);
1565
1566                                 if (super == NULL)
1567                                         emit_label_br(cd, BRANCH_LABEL_4);
1568                                 else
1569                                         emit_label(cd, BRANCH_LABEL_3);
1570                         }
1571
1572                         /* class instanceof code */
1573
1574                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
1575                                 if (super == NULL) {
1576                                         emit_label(cd, BRANCH_LABEL_2);
1577
1578                                         patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
1579                                         M_AMOV_IMM(0, REG_ATMP2);
1580                                 } else {
1581                                         M_AMOV_IMM(super->vftbl, REG_ATMP2);
1582                                         M_ATST(s1);
1583                                         emit_label_beq(cd, BRANCH_LABEL_5);
1584                                 }
1585
1586                                 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
1587
1588                                 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
1589                                 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
1590                                 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
1591
1592                                 M_ISUB(REG_ITMP3, REG_ITMP1);
1593                                 M_ICMP(REG_ITMP2, REG_ITMP1);
1594                                 M_BHI(4);
1595                                 M_IMOV_IMM(1, d);
1596                                 M_TPFW;                 /* overlaps next instruction */
1597                                 M_ICLR(d);
1598
1599                                 if (super != NULL)
1600                                         emit_label(cd, BRANCH_LABEL_5);
1601                         }
1602
1603                         if (super == NULL) {
1604                                 emit_label(cd, BRANCH_LABEL_1);
1605                                 emit_label(cd, BRANCH_LABEL_4);
1606                         }
1607
1608                         emit_store_dst(jd, iptr, d);
1609                         }
1610                         break;
1611
1612                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
1613                                       /* val.a: (classinfo*) superclass               */
1614
1615                         /*  superclass is an interface:
1616                          *
1617                          *  OK if ((sub == NULL) ||
1618                          *         (sub->vftbl->interfacetablelength > super->index) &&
1619                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
1620                          *
1621                          *  superclass is a class:
1622                          *
1623                          *  OK if ((sub == NULL) || (0
1624                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1625                          *         super->vftbl->diffvall));
1626                          */
1627
1628                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
1629                                 /* object type cast-check */
1630
1631                                 classinfo *super;
1632                                 s4         superindex;
1633
1634                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1635                                         super      = NULL;
1636                                         superindex = 0;
1637                                 }
1638                                 else {
1639                                         super      = iptr->sx.s23.s3.c.cls;
1640                                         superindex = super->index;
1641                                 }
1642
1643                                 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1644                                 assert(VAROP(iptr->s1)->type == TYPE_ADR);
1645
1646                                 /* if class is not resolved, check which code to call */
1647
1648                                 if (super == NULL) {
1649                                         M_ATST(s1);
1650                                         emit_label_beq(cd, BRANCH_LABEL_1);
1651
1652                                         patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
1653                         
1654                                         M_IMOV_IMM32(0, REG_ITMP2);
1655                                         M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
1656                                         emit_label_beq(cd, BRANCH_LABEL_2);
1657                                 }
1658
1659                                 /* interface checkcast code */
1660
1661                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1662                                         if (super == NULL) {
1663                                                 patcher_add_patch_ref(jd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
1664                                         } else {
1665                                                 M_ATST(s1);
1666                                                 emit_label_beq(cd, BRANCH_LABEL_3);
1667                                         }
1668
1669                                         M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
1670                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
1671         
1672                                         M_IADD_IMM(-superindex, REG_ITMP3);     /* superindex patched */
1673                                         M_ITST(REG_ITMP3);
1674                                         emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
1675
1676                                         M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patched*/
1677                                         M_ATST(REG_ATMP3);
1678                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
1679
1680                                         if (super == NULL)
1681                                                 emit_label_br(cd, BRANCH_LABEL_4);
1682                                         else
1683                                                 emit_label(cd, BRANCH_LABEL_3);
1684                                 }
1685
1686                                 /* class checkcast code */
1687
1688                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
1689                                         if (super == NULL) {
1690                                                 emit_label(cd, BRANCH_LABEL_2);
1691
1692                                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
1693                                                 M_AMOV_IMM(0, REG_ATMP3);
1694                                         } else {
1695                                                 M_AMOV_IMM(super->vftbl, REG_ATMP3);
1696                                                 M_ATST(s1);
1697                                                 emit_label_beq(cd, BRANCH_LABEL_5);
1698                                         }
1699
1700                                         M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
1701
1702                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));  /* REG_ITMP3 == sub->vftbl->baseval */
1703                                         M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
1704                                         M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
1705
1706                                         M_ISUB(REG_ITMP1, REG_ITMP3);
1707                                         M_ICMP(REG_ITMP2, REG_ITMP3);   /* XXX was CMPU */
1708
1709                                         emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
1710
1711                                         if (super != NULL)
1712                                                 emit_label(cd, BRANCH_LABEL_5);
1713                                 }
1714
1715                                 if (super == NULL) {
1716                                         emit_label(cd, BRANCH_LABEL_1);
1717                                         emit_label(cd, BRANCH_LABEL_4);
1718                                 }
1719
1720                                 d = codegen_reg_of_dst(jd, iptr, s1);
1721                         } else {
1722                                 /* array type cast-check */
1723
1724                                 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
1725
1726                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1727                                         patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
1728                                         M_AMOV_IMM(0, REG_ATMP1);
1729                                 } else {
1730                                         M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
1731                                 }
1732         
1733                                 M_APUSH(REG_ATMP1);
1734                                 M_APUSH(s1);
1735                                 M_JSR_IMM(BUILTIN_arraycheckcast);
1736                                 M_AADD_IMM(2*4, REG_SP);                /* pop arguments off stack */
1737                                 M_ITST(REG_RESULT);
1738                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
1739
1740                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1741                                 d = codegen_reg_of_dst(jd, iptr, s1);
1742                         }
1743                         assert(VAROP(iptr->dst)->type == TYPE_ADR);
1744                         M_ADRMOVE(s1, d);
1745                         emit_store_dst(jd, iptr, d);
1746                         break;
1747
1748                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
1749                         {
1750                         s4 i, l;
1751                         branch_target_t *table;
1752
1753                         table = iptr->dst.table;
1754
1755                         l = iptr->sx.s23.s2.tablelow;
1756                         i = iptr->sx.s23.s3.tablehigh;
1757                         
1758                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1759                         M_INTMOVE(s1, REG_ITMP1);
1760                         if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
1761
1762                         i = i - l + 1;
1763
1764                         /* range check */
1765                         M_ICMP_IMM(i - 1, REG_ITMP1);
1766                         emit_bugt(cd, table[0].block);
1767
1768                         /* build jump table top down and use address of lowest entry */
1769                         table += i;
1770
1771                         while (--i >= 0) {
1772                                 dseg_add_target(cd, table->block); 
1773                                 --table;
1774                         }
1775
1776                         /* length of dataseg after last dseg_add_target is used by load */
1777                         M_AMOV_IMM(0, REG_ATMP2);
1778                         dseg_adddata(cd);
1779
1780                         M_ISSL_IMM(2, REG_ITMP1);                       /* index * 4 == offset in table */
1781                         M_AADDINT(REG_ITMP1, REG_ATMP2);                /* offset in table */
1782                         M_AADD_IMM(-(cd->dseglen), REG_ATMP2);          /* start of table in dseg */
1783                         M_ALD(REG_ATMP1, REG_ATMP2, 0);
1784
1785                         M_JMP(REG_ATMP1);
1786                         ALIGNCODENOP;
1787                         }
1788                         break;
1789
1790                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
1791
1792                         /* check for negative sizes and copy sizes to stack if necessary  */
1793                         MCODECHECK((iptr->s1.argcount << 1) + 64);
1794
1795                         for (s1 = iptr->s1.argcount; --s1 >= 0;) {
1796                                 var = VAR(iptr->sx.s23.s2.args[s1]);
1797
1798                                 /* Already Preallocated? */
1799                                 if (!(var->flags & PREALLOC)) {
1800                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
1801                                         M_IST(s2, REG_SP, (s1 + 3) * 4);
1802                                 }
1803                         }
1804
1805                         /* a0 = dimension count */
1806                         M_IMOV_IMM(iptr->s1.argcount, REG_ITMP1);
1807                         M_IST(REG_ITMP1, REG_SP, 0*4);
1808
1809                         /* a1 = arraydescriptor */
1810                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1811                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
1812                                 M_AMOV_IMM(0, REG_ATMP1);
1813                         } else  {
1814                                 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
1815                         }
1816                         M_AST(REG_ATMP1, REG_SP, 1*4);
1817
1818                         /* a2 = pointer to dimensions = stack pointer */
1819                         M_AMOV(REG_SP, REG_ATMP1);
1820                         M_AADD_IMM(3*4, REG_ATMP1);
1821                         M_AST(REG_ATMP1, REG_SP, 2*4);
1822
1823                         M_JSR_IMM(BUILTIN_multianewarray);
1824
1825                         /* check for exception before result assignment */
1826                         emit_exception_check(cd, iptr);
1827
1828                         assert(VAROP(iptr->dst)->type == TYPE_ADR);
1829                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1830                         M_INT2ADRMOVE(REG_RESULT, d);
1831                         emit_store_dst(jd, iptr, d);
1832                         break;
1833
1834
1835
1836                 default:
1837                         vm_abort("Unknown ICMD %d during code generation", iptr->opc);
1838         } /* switch */
1839 }
1840
1841
1842 /* codegen_emit_stub_native ****************************************************
1843
1844    Emits a stub routine which calls a native method.
1845
1846 *******************************************************************************/
1847
1848 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
1849 {
1850         methodinfo   *m;
1851         codeinfo     *code;
1852         codegendata  *cd;
1853         registerdata *rd;
1854         methoddesc   *md;
1855         s4 i, j, t, s1, s2;
1856         
1857         /* get required compiler data */
1858
1859         m    = jd->m;
1860         code = jd->code;
1861         cd   = jd->cd;
1862         rd   = jd->rd;
1863
1864         md = m->parseddesc;
1865
1866         /* calc stackframe size */
1867         cd->stackframesize =
1868                 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
1869                 sizeof(localref_table) / SIZEOF_VOID_P +
1870                 nmd->memuse +
1871                 1 +                                             /* functionptr */
1872                 4;                                              /* args for codegen_start_native_call */
1873
1874         /* create method header */
1875         (void) dseg_add_unique_address(cd, code);                      /* CodeinfoPointer */
1876         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8);         /* FrameSize       */
1877         (void) dseg_add_unique_s4(cd, 0);                              /* IsLeaf          */
1878         (void) dseg_add_unique_s4(cd, 0);                              /* IntSave         */
1879         (void) dseg_add_unique_s4(cd, 0);                              /* FltSave         */
1880
1881         /* generate code */
1882         M_AADD_IMM(-(cd->stackframesize*8), REG_SP);
1883
1884         /* put arguments for codegen_start_native_call onto stack */
1885         /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
1886         
1887         M_AMOV(REG_SP, REG_ATMP1);
1888         M_AST(REG_ATMP1, REG_SP, 0 * 4);                /* currentsp */
1889
1890         M_AMOV_IMM(0, REG_ATMP2);                       /* 0 needs to patched */
1891         dseg_adddata(cd);                                   /* this patches it */
1892
1893         M_AST(REG_ATMP2, REG_SP, 1 * 4);                /* pv */
1894
1895         M_JSR_IMM(codegen_start_native_call);
1896
1897         /* remember class argument */
1898         if (m->flags & ACC_STATIC)
1899                 M_INT2ADRMOVE(REG_RESULT, REG_ATMP3);
1900
1901         /* copy arguments into stackframe */
1902         for (i = md->paramcount -1, j = i + skipparams; i >= 0; --i, --j)       {
1903                 t = md->paramtypes[i].type;
1904                 /* all arguments via stack */
1905                 assert(md->params[i].inmemory);                                         
1906
1907                 s1 = md->params[i].regoff + cd->stackframesize * 8 + 4;
1908                 s2 = nmd->params[j].regoff;
1909
1910                 /* simply copy argument stack */
1911                 M_ILD(REG_ITMP1, REG_SP, s1);
1912                 M_IST(REG_ITMP1, REG_SP, s2);
1913                 if (IS_2_WORD_TYPE(t))  {
1914                         M_ILD(REG_ITMP1, REG_SP, s1 + 4);
1915                         M_IST(REG_ITMP1, REG_SP, s2 + 4);
1916                 }
1917         }
1918
1919         /* builtins are not invoked like natives, environemtn and clazz are only needed for natives */
1920         if (m->flags & ACC_NATIVE)      {
1921                 /* for static function class as second arg */
1922                 if (m->flags & ACC_STATIC)
1923                         M_AST(REG_ATMP3, REG_SP, 1 * 4);
1924
1925                 /* env ist first argument */
1926                 M_AMOV_IMM(VM_get_jnienv(), REG_ATMP1);
1927                 M_AST(REG_ATMP1, REG_SP, 0 * 4);
1928         }
1929
1930         /* call the native function */
1931         M_AMOV_IMM(f, REG_ATMP2);
1932         M_JSR(REG_ATMP2);
1933
1934         /* save return value */
1935         switch (md->returntype.type)    {
1936                 case TYPE_VOID: break;
1937
1938                 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
1939                 case TYPE_DBL:
1940                 case TYPE_LNG:
1941                         M_IST(REG_D1, REG_SP, 2 * 8);
1942                         /* fall through */
1943
1944                 case TYPE_FLT:
1945                 case TYPE_INT:
1946                 case TYPE_ADR:
1947                         M_IST(REG_D0, REG_SP, 2 * 8);   /* XXX can this be correct ? */
1948                         break;
1949
1950                 default: assert(0);
1951         }
1952
1953         /* remove native stackframe info */
1954         /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
1955
1956         M_AMOV(REG_SP, REG_ATMP1);
1957         M_AST(REG_ATMP1, REG_SP, 0 * 4);                /* currentsp */
1958
1959         M_AMOV_IMM(0, REG_ATMP2);                       /* 0 needs to patched */
1960         dseg_adddata(cd);                                   /* this patches it */
1961
1962         M_AST(REG_ATMP2, REG_SP, 1 * 4);                /* pv */
1963
1964         M_JSR_IMM(codegen_finish_native_call);
1965         
1966         M_INT2ADRMOVE(REG_RESULT, REG_ATMP1);
1967         /* restore return value */
1968         switch (md->returntype.type)    {
1969                 case TYPE_VOID: break;
1970
1971                 case TYPE_DBL:
1972                 case TYPE_LNG:          M_ILD(REG_D1, REG_SP, 2 * 8);
1973                         /* fall through */
1974                 case TYPE_FLT:
1975                 case TYPE_INT:
1976                 case TYPE_ADR:
1977                         M_ILD(REG_D0, REG_SP, 2 * 8);   /* XXX */
1978                         break;
1979
1980                 default: assert(0);
1981         }
1982 #if !defined(ENABLE_SOFTFLOAT)
1983                 /* additionally load values into floating points registers
1984                  * as cacao jit code expects them there */
1985         switch (md->returntype.type)    {
1986                 case TYPE_FLT:
1987                         M_FLD(REG_D0, REG_SP, 2 * 8);
1988                         break;
1989                 case TYPE_DBL:  
1990                         M_DLD(REG_D0, REG_SP, 2 * 8);   /* XXX */
1991                         break;
1992         }
1993 #endif
1994         /* restore saved registers */
1995
1996         M_AADD_IMM(cd->stackframesize*8, REG_SP);
1997         /* check for exception */
1998         M_ATST(REG_ATMP1);
1999         M_BNE(2);
2000         M_RET;
2001
2002         /* handle exception, REG_ATMP1 already contains exception object, REG_ATMP2 holds address */
2003         
2004         M_ALD(REG_ATMP2_XPC, REG_SP, 0);                /* take return address as faulting instruction */
2005         M_AADD_IMM(-2, REG_ATMP2_XPC);                  /* which is off by 2 */
2006         M_JMP_IMM(asm_handle_nat_exception);
2007
2008         /* should never be reached from within jit code*/
2009         M_JSR_IMM(0);
2010 }
2011
2012
2013 /*
2014  * These are local overrides for various environment variables in Emacs.
2015  * Please do not remove this and leave it at the end of the file, where
2016  * Emacs will automagically detect them.
2017  * ---------------------------------------------------------------------
2018  * Local variables:
2019  * mode: c
2020  * indent-tabs-mode: t
2021  * c-basic-offset: 4
2022  * tab-width: 4
2023  * End:
2024  * vim:noexpandtab:sw=4:ts=4:
2025  */