3db469a8f57a2d67144d367e5459c2bba15bf1b4
[cacao.git] / src / vm / jit / arm / codegen.c
1 /* src/vm/jit/arm/codegen.c - machine code generator for Arm
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Michael Starzinger
28
29    Changes: Christian Thalinger
30                         Edwin Steiner
31
32    $Id: codegen.c 6591 2007-01-02 19:14:25Z twisti $
33
34 */
35
36
37 #include "config.h"
38
39 #include <assert.h>
40 #include <stdio.h>
41
42 #include "vm/types.h"
43
44 #include "md-abi.h"
45
46 #include "vm/jit/arm/arch.h"
47 #include "vm/jit/arm/codegen.h"
48
49 #include "mm/memory.h"
50 #include "native/native.h"
51
52 #if defined(ENABLE_THREADS)
53 # include "threads/native/lock.h"
54 #endif
55
56 #include "vm/builtin.h"
57 #include "vm/exceptions.h"
58 #include "vm/global.h"
59 #include "vm/loader.h"
60 #include "vm/options.h"
61 #include "vm/stringlocal.h"
62 #include "vm/vm.h"
63 #include "vm/jit/asmpart.h"
64 #include "vm/jit/codegen-common.h"
65 #include "vm/jit/dseg.h"
66 #include "vm/jit/emit-common.h"
67 #include "vm/jit/jit.h"
68 #include "vm/jit/methodheader.h"
69 #include "vm/jit/parse.h"
70 #include "vm/jit/patcher.h"
71 #include "vm/jit/reg.h"
72
73 #if defined(ENABLE_LSRA)
74 #include "vm/jit/allocator/lsra.h"
75 #endif
76
77
78 /* codegen *********************************************************************
79
80    Generates machine code.
81
82 *******************************************************************************/
83
84 bool codegen(jitdata *jd)
85 {
86         methodinfo         *m;
87         codeinfo           *code;
88         codegendata        *cd;
89         registerdata       *rd;
90         s4              i, t, len;
91         s4              s1, s2, s3, d;
92         s4              disp;
93         varinfo        *var;
94         basicblock     *bptr;
95         instruction    *iptr;
96         exception_entry *ex;
97         s4              fieldtype;
98         s4              varindex;
99
100         s4              spilledregs_num;
101         s4              savedregs_num;
102         u2              savedregs_bitmask;
103         u2              currentline;
104
105         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE* */
106         unresolved_method  *um;
107         builtintable_entry *bte;
108         methoddesc         *md;
109
110         /* get required compiler data */
111
112         m    = jd->m;
113         code = jd->code;
114         cd   = jd->cd;
115         rd   = jd->rd;
116
117         /* prevent compiler warnings */
118
119         lm  = NULL;
120         um  = NULL;
121         bte = NULL;
122
123         fieldtype = -1;
124         
125         /* space to save used callee saved registers */
126         savedregs_num = (jd->isleafmethod) ? 0 : 1;       /* space to save the LR */
127         savedregs_num += (INT_SAV_CNT - rd->savintreguse);
128         savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
129         spilledregs_num = rd->memuse;
130
131 #if defined(ENABLE_THREADS)        /* space to save argument of monitor_enter */
132         if (checksync && (m->flags & ACC_SYNCHRONIZED))
133                 spilledregs_num++;
134 #endif
135
136         cd->stackframesize = spilledregs_num + savedregs_num;
137
138         /* SECTION: Method Header */
139         /* create method header */
140
141         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
142         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
143
144 #if defined(ENABLE_THREADS)
145         /* IsSync contains the offset relative to the stack pointer for the
146            argument of monitor_exit used in the exception handler. Since the
147            offset could be zero and give a wrong meaning of the flag it is
148            offset by one.
149         */
150
151         if (checksync && (m->flags & ACC_SYNCHRONIZED))
152                 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4);/* IsSync         */
153         else
154 #endif
155                 (void) dseg_add_unique_s4(cd, 0);                  /* IsSync          */
156
157         (void) dseg_add_unique_s4(cd, jd->isleafmethod);       /* IsLeaf          */
158         (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
159         (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
160         (void) dseg_addlinenumbertablesize(cd);
161         (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize   */
162
163         /* create exception table */
164
165         for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
166                 dseg_add_target(cd, ex->start);
167                 dseg_add_target(cd, ex->end);
168                 dseg_add_target(cd, ex->handler);
169                 (void) dseg_add_unique_address(cd, ex->catchtype.any);
170         }
171
172         /* save return address and used callee saved registers */
173         savedregs_bitmask = 0;
174         if (!jd->isleafmethod)
175                 savedregs_bitmask = (1<<REG_LR);
176         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--)
177                 savedregs_bitmask |= (1<<(rd->savintregs[i]));
178 #if !defined(NDEBUG)
179         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
180                 log_text("!!! CODEGEN: floating-point callee saved registers are not saved to stack (SEVERE! STACK IS MESSED UP!)");
181                 /* TODO: floating-point */
182         }
183 #endif
184         if (savedregs_bitmask) {
185                 M_STMFD(savedregs_bitmask, REG_SP);
186         }
187
188         /* create additional stack frame for spilled variables (if necessary) */
189         if (spilledregs_num) {
190                 M_SUB_IMM_EXT_MUL4(REG_SP, REG_SP, spilledregs_num);
191         }
192
193         /* take arguments out of register or stack frame */
194         md = m->parseddesc;
195         for (i = 0, len = 0; i < md->paramcount; i++) {
196                 s1 = md->params[i].regoff;
197                 t = md->paramtypes[i].type;
198
199                 varindex = jd->local_map[len * 5 + t];
200
201                 len += (IS_2_WORD_TYPE(t)) ? 2 : 1;          /* 2 word type arguments */
202
203                 if (varindex == UNUSED)
204                         continue;
205
206                 var = VAR(varindex);
207
208                 /* ATTENTION: we use interger registers for all arguments (even float) */
209 #if !defined(ENABLE_SOFTFLOAT)
210                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
211 #endif
212                         if (!md->params[i].inmemory) {           /* register arguments    */
213                                 s2 = ARGUMENT_REGS(t, s1);           /* get argument register */
214                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
215                                         if (GET_LOW_REG(var->vv.regoff) == REG_SPLIT || GET_HIGH_REG(var->vv.regoff) == REG_SPLIT) {
216                                                 /* TODO: remove this!!! */
217                                                 dolog("SPLIT in local var: %x>%x (%s.%s)", s2, var->vv.regoff, m->class->name->text, m->name->text);
218                                                 assert(s2 == var->vv.regoff);
219                                         }
220                                         s3 = var->vv.regoff;
221                                         SPLIT_OPEN(t, s2, REG_ITMP1);
222                                         SPLIT_LOAD(t, s2, cd->stackframesize);
223                                         SPLIT_OPEN(t, s3, REG_ITMP1);
224
225                                         if (IS_2_WORD_TYPE(t))
226                                                 M_LNGMOVE(s2, s3);
227                                         else
228                                                 M_INTMOVE(s2, s3);
229
230                                         SPLIT_STORE_AND_CLOSE(t, s3, cd->stackframesize);
231                                 }
232                                 else {                               /* reg arg -> spilled    */
233                                         SPLIT_OPEN(t, s2, REG_ITMP1);
234                                         SPLIT_LOAD(t, s2, cd->stackframesize);
235
236                                         if (IS_2_WORD_TYPE(t))
237                                                 M_LST(s2, REG_SP, var->vv.regoff * 4);
238                                         else
239                                                 M_IST(s2, REG_SP, var->vv.regoff * 4);
240                                         /* no SPLIT_CLOSE here because arg is fully spilled now */
241                                 }
242                         }
243                         else {                                   /* stack arguments       */
244                                 if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
245                                         if (IS_2_WORD_TYPE(t))
246                                                 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
247                                         else
248                                                 M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
249                                 }
250                                 else {                               /* stack arg -> spilled  */
251                                         /* Reuse Memory Position on Caller Stack */
252                                         var->vv.regoff = cd->stackframesize + s1;
253                                 }
254                         }
255 #if !defined(ENABLE_SOFTFLOAT)
256                 } else {                                     /* floating args         */
257                         if (!md->params[i].inmemory) {           /* register arguments    */
258                                 s2 = ARGUMENT_REGS(t, s1);           /* get argument register */
259                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
260                                         SPLIT_OPEN(t, s2, REG_ITMP1);
261                                         SPLIT_LOAD(t, s2, cd->stackframesize);
262                                         M_CAST_INT_TO_FLT_TYPED(t, s2, var->vv.regoff);
263                                 }
264                                 else {                               /* reg arg -> spilled    */
265                                         SPLIT_OPEN(t, s2, REG_ITMP1);
266                                         SPLIT_LOAD(t, s2, cd->stackframesize);
267
268                                         if (IS_2_WORD_TYPE(t))
269                                                 M_LST(s2, REG_SP, var->vv.regoff * 4);
270                                         else
271                                                 M_IST(s2, REG_SP, var->vv.regoff * 4);
272                                         /* no SPLIT_CLOSE here because arg is fully spilled now */
273                                 }
274                         }
275                         else {                                   /* stack arguments       */
276                                 if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
277                                         M_STACK_LOAD_FLT_TYPED(t, var->vv.regoff, cd->stackframesize + s1);
278                                 } else {                             /* stack arg -> spilled  */
279                                         /* Reuse Memory Position on Caller Stack */
280                                         var->vv.regoff = cd->stackframesize + s1;
281                                 }
282                         }
283                 }
284 #endif /* !defined(ENABLE_SOFTFLOAT) */
285         }
286
287 #if defined(ENABLE_THREADS)
288         /* call monitorenter function */
289
290         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
291                 /* stack offset for monitor argument */
292
293                 s1 = rd->memuse;
294
295 # if !defined(NDEBUG)
296                 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
297                         M_STMFD(BITMASK_ARGS, REG_SP);
298                         s1 += 4;
299                 }
300 # endif
301
302                 /* get the correct lock object */
303
304                 if (m->flags & ACC_STATIC) {
305                         disp = dseg_add_address(cd, &m->class->object.header);
306                         M_DSEG_LOAD(REG_A0, disp);
307                 }
308                 else {
309                         M_TST(REG_A0, REG_A0);
310                         M_BEQ(0);
311                         codegen_add_nullpointerexception_ref(cd);
312                 }
313
314                 M_STR(REG_A0, REG_SP, s1 * 4);
315                 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
316                 M_DSEG_BRANCH(disp);
317                 s1 = (s4) (cd->mcodeptr - cd->mcodebase);
318                 M_RECOMPUTE_IP(s1);
319
320 # if !defined(NDEBUG)
321                 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
322                         M_LDMFD(BITMASK_ARGS, REG_SP);
323 # endif
324         }
325 #endif
326
327 #if !defined(NDEBUG)
328         /* call trace function */
329
330         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
331                 emit_verbosecall_enter(jd);
332 #endif
333
334         /* end of header generation */
335
336         /* SECTION: ICMD Code Generation */
337         /* for all basic blocks */
338         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next)
339         {
340                 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
341
342                 /* is this basic block reached? */
343                 if (bptr->flags < BBREACHED)
344                         continue;
345
346                 /* branch resolving */
347                 {
348                 branchref *brefs;
349                 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
350                         gen_resolvebranch(cd->mcodebase + brefs->branchpos, 
351                                           brefs->branchpos, bptr->mpc);
352                 }
353                 }
354
355                 /* copy interface registers to their destination */
356                 len = bptr->indepth;
357
358                 MCODECHECK(64+len);
359
360 #if defined(ENABLE_LSRA)
361                 if (opt_lsra) {
362                 while (len) {
363                         len--;
364                         var = VAR(bptr->invars[len]);
365                         if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
366                                 if (!(var->flags & INMEMORY))
367                                         d= var->vv.regoff;
368                                 else
369                                         d=REG_ITMP1;
370                                 M_INTMOVE(REG_ITMP1, d);
371                                 emit_store(jd, NULL, var, d);   
372                         }
373                 }
374                 } else {
375 #endif
376                 while (len) {
377                         len--;
378                         var = VAR(bptr->invars[len]);
379
380                         if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
381                                 d = codegen_reg_of_var(0, var, REG_ITMP1);
382                                 M_INTMOVE(REG_ITMP1, d);
383                                 emit_store(jd, NULL, var, d);
384                         }
385                         else {
386                                 assert((var->flags & INOUT));
387                         }
388                 }
389 #if defined(ENABLE_LSRA)
390                 }
391 #endif
392
393                 /* for all instructions */
394                 len = bptr->icount;
395                 currentline = 0;
396                 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
397
398                         /* add line number */
399                         if (iptr->line != currentline) {
400                                 dseg_addlinenumber(cd, iptr->line);
401                                 currentline = iptr->line;
402                         }
403
404                         MCODECHECK(64);   /* an instruction usually needs < 64 words      */
405
406                         /* the big switch */
407                         switch (iptr->opc) {
408                 case ICMD_NOP:        /* ... ==> ...                                  */
409                         break;
410
411         /* constant operations ************************************************/
412
413                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
414
415                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
416                         ICONST(d, iptr->sx.val.i);
417                         emit_store_dst(jd, iptr, d);
418                         break;
419
420                 case ICMD_ACONST:     /* ... ==> ..., constant                        */
421
422                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
423                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
424                                 disp = dseg_add_unique_address(cd, NULL);
425
426                                 codegen_addpatchref(cd, PATCHER_aconst,
427                                                     iptr->sx.val.c.ref,
428                                                                         disp);
429
430                                 if (opt_showdisassemble)
431                                         M_NOP;
432
433                                 M_DSEG_LOAD(d, disp);
434                         }
435                         else {
436                                 ICONST(d, (u4) iptr->sx.val.anyptr);
437                         }
438                         emit_store_dst(jd, iptr, d);
439                         break;
440
441                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
442
443                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
444                         LCONST(d, iptr->sx.val.l);
445                         emit_store_dst(jd, iptr, d);
446                         break;
447
448                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
449
450 #if defined(ENABLE_SOFTFLOAT)
451                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
452                         ICONST(d, iptr->sx.val.i);
453                         emit_store_dst(jd, iptr, d);
454 #else
455                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
456                         FCONST(d, iptr->sx.val.f);
457                         emit_store_dst(jd, iptr, d);
458 #endif
459                         break;
460
461                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
462
463 #if defined(ENABLE_SOFTFLOAT)
464                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
465                         LCONST(d, iptr->sx.val.l);
466                         emit_store_dst(jd, iptr, d);
467 #else
468                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
469                         DCONST(d, iptr->sx.val.d);
470                         emit_store_dst(jd, iptr, d);
471 #endif
472                         break;
473
474
475                 /* load/store/copy/move operations ************************************/
476
477                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
478                 case ICMD_ALOAD:      /* op1 = local variable                         */
479                 case ICMD_FLOAD:
480                 case ICMD_LLOAD:
481                 case ICMD_DLOAD:
482                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
483                 case ICMD_FSTORE:
484                 case ICMD_LSTORE:
485                 case ICMD_DSTORE:
486                 case ICMD_COPY:
487                 case ICMD_MOVE:
488
489                         emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
490                         break;
491
492                 case ICMD_ASTORE:
493                         if (!(iptr->flags.bits & INS_FLAG_RETADDR))
494                                 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
495                         break;
496
497                 /* pop operations *****************************************************/
498
499                 /* attention: double and longs are only one entry in CACAO ICMDs      */
500
501                 case ICMD_POP:        /* ..., value  ==> ...                          */
502                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
503
504                         break;
505
506
507                 /* integer operations *************************************************/
508
509                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
510
511                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
512                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
513                         M_MOV(d, REG_LSL(s1, 24));
514                         M_MOV(d, REG_ASR(d, 24));
515                         emit_store_dst(jd, iptr, d);
516                         break;
517
518                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
519
520                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
521                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
522                         M_MOV(d, REG_LSL(s1, 16));
523                         M_MOV(d, REG_LSR(d, 16)); /* ATTENTION: char is unsigned */
524                         emit_store_dst(jd, iptr, d);
525                         break;
526
527                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
528
529                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
530                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
531                         M_MOV(d, REG_LSL(s1, 16));
532                         M_MOV(d, REG_ASR(d, 16));
533                         emit_store_dst(jd, iptr, d);
534                         break;
535
536                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
537
538                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
539                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
540                         M_INTMOVE(s1, GET_LOW_REG(d));
541                         M_MOV(GET_HIGH_REG(d), REG_ASR(s1, 31));
542                         emit_store_dst(jd, iptr, d);
543                         break;
544
545                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
546
547                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
548                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
549                         M_INTMOVE(s1, d);
550                         emit_store_dst(jd, iptr, d);
551                         break;
552
553                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
554
555                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
556                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
557                         M_RSB_IMM(d, s1, 0);
558                         emit_store_dst(jd, iptr, d);
559                         break;
560
561                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
562
563                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
564                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
565                         M_RSB_IMMS(GET_LOW_REG(d), GET_LOW_REG(s1), 0);
566                         M_RSC_IMM(GET_HIGH_REG(d), GET_HIGH_REG(s1), 0);
567                         emit_store_dst(jd, iptr, d);
568                         break;
569
570                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
571
572                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
573                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
574                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
575                         M_ADD(d, s1, s2);
576                         emit_store_dst(jd, iptr, d);
577                         break;
578
579                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
580
581                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
582                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
583                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
584                         M_ADD_S(GET_LOW_REG(d), s1, s2);
585                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
586                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
587                         M_ADC(GET_HIGH_REG(d), s1, s2);
588                         emit_store_dst(jd, iptr, d);
589                         break;
590
591                 case ICMD_IADDCONST:
592                 case ICMD_IINC:
593
594                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
595                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
596
597                         if (IS_IMM(iptr->sx.val.i)) {
598                                 M_ADD_IMM(d, s1, iptr->sx.val.i);
599                         } else if (IS_IMM(-iptr->sx.val.i)) {
600                                 M_SUB_IMM(d, s1, (-iptr->sx.val.i));
601                         } else {
602                                 ICONST(REG_ITMP3, iptr->sx.val.i);
603                                 M_ADD(d, s1, REG_ITMP3);
604                         }
605
606                         emit_store_dst(jd, iptr, d);
607                         break;
608
609                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
610                                       /* sx.val.l = constant                          */
611
612                         s3 = iptr->sx.val.l & 0xffffffff;
613                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
614                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
615                         if (IS_IMM(s3))
616                                 M_ADD_IMMS(GET_LOW_REG(d), s1, s3);
617                         else {
618                                 ICONST(REG_ITMP3, s3);
619                                 M_ADD_S(GET_LOW_REG(d), s1, REG_ITMP3);
620                         }
621                         s3 = iptr->sx.val.l >> 32;
622                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
623                         if (IS_IMM(s3))
624                                 M_ADC_IMM(GET_HIGH_REG(d), s1, s3);
625                         else {
626                                 ICONST(REG_ITMP3, s3);
627                                 M_ADC(GET_HIGH_REG(d), s1, REG_ITMP3);
628                         }
629                         emit_store_dst(jd, iptr, d);
630                         break;
631
632                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
633
634                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
635                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
636                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
637                         M_SUB(d, s1, s2);
638                         emit_store_dst(jd, iptr, d);
639                         break;
640
641                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
642
643                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
644                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
645                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
646                         M_SUB_S(GET_LOW_REG(d), s1, s2);
647                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
648                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
649                         M_SBC(GET_HIGH_REG(d), s1, s2);
650                         emit_store_dst(jd, iptr, d);
651                         break;
652
653                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
654                                       /* sx.val.i = constant                          */
655
656                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
657                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
658                         if (IS_IMM(iptr->sx.val.i))
659                                 M_SUB_IMM(d, s1, iptr->sx.val.i);
660                         else {
661                                 ICONST(REG_ITMP3, iptr->sx.val.i);
662                                 M_SUB(d, s1, REG_ITMP3);
663                         }
664                         emit_store_dst(jd, iptr, d);
665                         break;
666
667                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
668                                       /* sx.val.l = constant                          */
669
670                         s3 = iptr->sx.val.l & 0xffffffff;
671                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
672                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
673                         if (IS_IMM(s3))
674                                 M_SUB_IMMS(GET_LOW_REG(d), s1, s3);
675                         else {
676                                 ICONST(REG_ITMP3, s3);
677                                 M_SUB_S(GET_LOW_REG(d), s1, REG_ITMP3);
678                         }
679                         s3 = iptr->sx.val.l >> 32;
680                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
681                         if (IS_IMM(s3))
682                                 M_SBC_IMM(GET_HIGH_REG(d), s1, s3);
683                         else {
684                                 ICONST(REG_ITMP3, s3);
685                                 M_SBC(GET_HIGH_REG(d), s1, REG_ITMP3);
686                         }
687                         emit_store_dst(jd, iptr, d);
688                         break;
689
690                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
691
692                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
693                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
694                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
695                         M_MUL(d, s1, s2);
696                         emit_store_dst(jd, iptr, d);
697                         break;
698
699                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
700                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
701
702                         s1 = emit_load_s1(jd, iptr, REG_A0);
703                         s2 = emit_load_s2(jd, iptr, REG_A1);
704                         gen_div_check(VAROP(iptr->sx.s23.s2)->type, s2);
705
706                         /* move arguments into argument registers */
707                         M_INTMOVE(s1, REG_A0);
708                         M_INTMOVE(s2, REG_A1);
709
710                         /* call builtin function */
711                         bte = iptr->sx.s23.s3.bte;
712                         disp = dseg_add_functionptr(cd, bte->fp);
713                         M_DSEG_BRANCH(disp);
714
715                         /* recompute ip */
716                         s1 = (s4) (cd->mcodeptr - cd->mcodebase);
717                         M_RECOMPUTE_IP(s1);
718
719                         /* move result into destination register */
720                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
721                         M_INTMOVE(REG_RESULT, d);
722                         emit_store_dst(jd, iptr, d);
723                         break;
724
725                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
726                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
727
728                         /* move arguments into argument registers */
729
730                         s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
731                         M_LNGMOVE(s1, REG_A0_A1_PACKED);
732
733                         s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
734                         M_LNGMOVE(s2, REG_A2_A3_PACKED);
735
736                         gen_div_check(VAROP(iptr->sx.s23.s2)->type, s2);
737
738                         /* call builtin function */
739                         bte = iptr->sx.s23.s3.bte;
740                         disp = dseg_add_functionptr(cd, bte->fp);
741                         M_DSEG_BRANCH(disp);
742
743                         /* recompute ip */
744                         s1 = (s4) (cd->mcodeptr - cd->mcodebase);
745                         M_RECOMPUTE_IP(s1);
746
747                         /* move result into destination register */
748                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
749                         M_LNGMOVE(REG_RESULT_PACKED, d);
750                         emit_store_dst(jd, iptr, d);
751                         break;
752
753                 case ICMD_IMULPOW2:   /* ..., value  ==> ..., value * (2 ^ constant)  */
754                                       /* sx.val.i = constant                          */
755
756                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
757                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
758                         M_MOV(d, REG_LSL(s1, iptr->sx.val.i));
759                         emit_store_dst(jd, iptr, d);
760                         break;
761
762                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value / (2 ^ constant)  */
763                                       /* sx.val.i = constant                          */
764
765                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
766                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
767                         /* this rounds towards 0 as java likes it */
768                         M_MOV(REG_ITMP3, REG_ASR(s1, 31));
769                         M_ADD(REG_ITMP3, s1, REG_LSR(REG_ITMP3, 32 - iptr->sx.val.i));
770                         M_MOV(d, REG_ASR(REG_ITMP3, iptr->sx.val.i));
771                         /* this rounds towards nearest, not java style */
772                         /*M_MOV_S(d, REG_ASR(s1, iptr->sx.val.i));
773                         M_ADCMI_IMM(d, d, 0);*/
774                         emit_store_dst(jd, iptr, d);
775                         break;
776
777                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
778                                       /* sx.val.i = constant [ (2 ^ x) - 1 ]          */
779
780                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
781                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
782                         M_MOV_S(REG_ITMP1, s1);
783                         M_RSBMI_IMM(REG_ITMP1, REG_ITMP1, 0);
784                         if (IS_IMM(iptr->sx.val.i))
785                                 M_AND_IMM(d, REG_ITMP1, iptr->sx.val.i);
786                         else {
787                                 ICONST(REG_ITMP3, iptr->sx.val.i);
788                                 M_AND(d, REG_ITMP1, REG_ITMP3);
789                         }
790                         M_RSBMI_IMM(d, d, 0);
791                         emit_store_dst(jd, iptr, d);
792                         break;
793
794                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
795
796                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
797                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
798                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
799                         M_AND_IMM(REG_ITMP2, s2, 0x1f);
800                         M_MOV(d, REG_LSL_REG(s1, REG_ITMP2));
801                         emit_store_dst(jd, iptr, d);
802                         break;
803
804                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
805
806                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
807                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
808                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
809                         M_AND_IMM(REG_ITMP2, s2, 0x1f);
810                         M_MOV(d, REG_ASR_REG(s1, REG_ITMP2));
811                         emit_store_dst(jd, iptr, d);
812                         break;
813
814                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
815
816                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
817                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
818                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
819                         M_AND_IMM(REG_ITMP2, s2, 0x1f);
820                         M_MOV(d, REG_LSR_REG(s1, REG_ITMP2));
821                         emit_store_dst(jd, iptr, d);
822                         break;
823
824                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
825                                       /* sx.val.i = constant                          */
826
827                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
828                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
829                         M_MOV(d, REG_LSL(s1, iptr->sx.val.i & 0x1f));
830                         emit_store_dst(jd, iptr, d);
831                         break;
832
833                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
834                                       /* sx.val.i = constant                          */
835
836                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
837                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
838                         /* we need to check for zero here because arm interprets it as SHR by 32 */
839                         if ((iptr->sx.val.i & 0x1f) == 0) {
840                                 M_INTMOVE(s1, d);
841                         } else {
842                                 M_MOV(d, REG_ASR(s1, iptr->sx.val.i & 0x1f));
843                         }
844                         emit_store_dst(jd, iptr, d);
845                         break;
846
847                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
848                                       /* sx.val.i = constant                          */
849
850                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
851                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
852                         /* we need to check for zero here because arm interprets it as SHR by 32 */
853                         if ((iptr->sx.val.i & 0x1f) == 0)
854                                 M_INTMOVE(s1, d);
855                         else
856                                 M_MOV(d, REG_LSR(s1, iptr->sx.val.i & 0x1f));
857                         emit_store_dst(jd, iptr, d);
858                         break;
859
860                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
861
862                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
863                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
864                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
865                         M_AND(d, s1, s2);
866                         emit_store_dst(jd, iptr, d);
867                         break;
868
869                 case ICMD_LAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
870
871                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
872                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
873                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
874                         M_AND(GET_LOW_REG(d), s1, s2);
875                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
876                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
877                         M_AND(GET_HIGH_REG(d), s1, s2);
878                         emit_store_dst(jd, iptr, d);
879                         break;
880
881                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
882
883                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
884                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
885                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
886                         M_ORR(d, s1, s2);
887                         emit_store_dst(jd, iptr, d);
888                         break;
889
890                 case ICMD_LOR:       /* ..., val1, val2  ==> ..., val1 | val2        */ 
891
892                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
893                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
894                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
895                         M_ORR(GET_LOW_REG(d), s1, s2);
896                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
897                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
898                         M_ORR(GET_HIGH_REG(d), s1, s2);
899                         emit_store_dst(jd, iptr, d);
900                         break;
901
902                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
903
904                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
905                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
906                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
907                         M_EOR(d, s1, s2);
908                         emit_store_dst(jd, iptr, d);
909                         break;
910
911                 case ICMD_LXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
912
913                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
914                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
915                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
916                         M_EOR(GET_LOW_REG(d), s1, s2);
917                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
918                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
919                         M_EOR(GET_HIGH_REG(d), s1, s2);
920                         emit_store_dst(jd, iptr, d);
921                         break;
922
923
924         /* floating operations ************************************************/
925
926 #if !defined(ENABLE_SOFTFLOAT)
927
928                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
929
930                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
931                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
932                         M_MNFS(d, s1);
933                         emit_store_dst(jd, iptr, d);
934                         break;
935
936                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
937
938                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
939                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
940                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
941                         M_ADFS(d, s1, s2);
942                         emit_store_dst(jd, iptr, d);
943                         break;
944
945                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
946
947                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
948                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
949                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
950                         M_SUFS(d, s1, s2);
951                         emit_store_dst(jd, iptr, d);
952                         break;
953
954                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
955
956                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
957                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
958                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
959                         M_MUFS(d, s1, s2);
960                         emit_store_dst(jd, iptr, d);
961                         break;
962
963                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
964                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
965                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
966                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
967                         M_DVFS(d, s1, s2);
968                         emit_store_dst(jd, iptr, d);
969                         break;
970
971                 /* ATTENTION: Jave does not want IEEE behaviour in FREM, do
972                    not use this */
973
974                 case ICMD_FREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
975
976                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
977                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
978                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
979                         M_RMFS(d, s1, s2);
980                         emit_store_dst(jd, iptr, d);
981                         break;
982
983                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
984
985                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
986                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
987                         M_MNFD(d, s1);
988                         emit_store_dst(jd, iptr, d);
989                         break;
990
991                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
992
993                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
994                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
995                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
996                         M_ADFD(d, s1, s2);
997                         emit_store_dst(jd, iptr, d);
998                         break;
999
1000                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1001
1002                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1003                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1004                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1005                         M_SUFD(d, s1, s2);
1006                         emit_store_dst(jd, iptr, d);
1007                         break;
1008
1009                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1010
1011                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1012                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1013                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1014                         M_MUFD(d, s1, s2);
1015                         emit_store_dst(jd, iptr, d);
1016                         break;
1017
1018                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1019
1020                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1021                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1022                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1023                         M_DVFD(d, s1, s2);
1024                         emit_store_dst(jd, iptr, d);
1025                         break;
1026
1027                 /* ATTENTION: Jave does not want IEEE behaviour in DREM, do
1028                    not use this */
1029
1030                 case ICMD_DREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1031
1032                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1033                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1034                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1035                         M_RMFD(d, s1, s2);
1036                         emit_store_dst(jd, iptr, d);
1037                         break;
1038
1039                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
1040
1041                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1042                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1043                         M_FLTS(d, s1);
1044                         emit_store_dst(jd, iptr, d);
1045                         break;
1046
1047                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
1048
1049                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1050                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1051                         M_FLTD(d, s1);
1052                         emit_store_dst(jd, iptr, d);
1053                         break;
1054
1055                 case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
1056
1057                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1058                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1059                         /* this uses round towards zero, as Java likes it */
1060                         M_FIX(d, s1);
1061                         /* this checks for NaN; to return zero as Java likes it */
1062                         M_CMF(s1, 0x8);
1063                         M_MOVVS_IMM(d, 0);
1064                         emit_store_dst(jd, iptr, d);
1065                         break;
1066
1067                 case ICMD_D2I:       /* ..., value  ==> ..., (int) value              */
1068
1069                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1070                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1071                         /* this uses round towards zero, as Java likes it */
1072                         M_FIX(d, s1);
1073                         /* this checks for NaN; to return zero as Java likes it */
1074                         M_CMF(s1, 0x8);
1075                         M_MOVVS_IMM(d, 0);
1076                         emit_store_dst(jd, iptr, d);
1077                         break;
1078
1079                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value            */
1080
1081                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1082                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1083                         M_MVFS(d,s1);
1084                         emit_store_dst(jd, iptr, d);
1085                         break;
1086
1087                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1088
1089                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1090                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1091                         M_MVFD(d,s1);
1092                         emit_store_dst(jd, iptr, d);
1093                         break;
1094
1095                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1096
1097                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1098                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1099                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1100                         M_CMF(s2, s1);
1101                         M_MOV_IMM(d, 0);
1102                         M_SUBGT_IMM(d, d, 1);
1103                         M_ADDLT_IMM(d, d, 1);
1104                         emit_store_dst(jd, iptr, d);
1105                         break;
1106
1107                 case ICMD_DCMPG:      /* ..., val1, val2  ==> ..., val1 dcmpg val2    */
1108
1109                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1110                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1111                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1112                         M_CMF(s2, s1);
1113                         M_MOV_IMM(d, 0);
1114                         M_SUBGT_IMM(d, d, 1);
1115                         M_ADDLT_IMM(d, d, 1);
1116                         emit_store_dst(jd, iptr, d);
1117                         break;
1118
1119                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1120
1121                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1122                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1123                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1124                         M_CMF(s1, s2);
1125                         M_MOV_IMM(d, 0);
1126                         M_SUBLT_IMM(d, d, 1);
1127                         M_ADDGT_IMM(d, d, 1);
1128                         emit_store_dst(jd, iptr, d);
1129                         break;
1130
1131                 case ICMD_DCMPL:      /* ..., val1, val2  ==> ..., val1 dcmpl val2    */
1132
1133                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1134                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1135                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1136                         M_CMF(s1, s2);
1137                         M_MOV_IMM(d, 0);
1138                         M_SUBLT_IMM(d, d, 1);
1139                         M_ADDGT_IMM(d, d, 1);
1140                         emit_store_dst(jd, iptr, d);
1141                         break;
1142
1143 #endif /* !defined(ENABLE_SOFTFLOAT) */
1144
1145
1146                 /* memory operations **************************************************/
1147
1148                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1149
1150                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1151                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1152                         gen_nullptr_check(s1);
1153                         M_ILD_INTERN(d, s1, OFFSET(java_arrayheader, size));
1154                         emit_store_dst(jd, iptr, d);
1155                         break;
1156
1157                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1158
1159                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1160                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1161                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1162                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1163                                 gen_nullptr_check(s1);
1164                                 gen_bound_check(s1, s2);
1165                         }
1166                         M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */
1167                         M_LDR_INTERN(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1168                         emit_store_dst(jd, iptr, d);
1169                         break;
1170
1171                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1172
1173                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1174                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1175                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1176                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1177                                 gen_nullptr_check(s1);
1178                                 gen_bound_check(s1, s2);
1179                         }
1180                         M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */
1181                         M_ILD_INTERN(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1182                         emit_store_dst(jd, iptr, d);
1183                         break;
1184
1185                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1186
1187                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1188                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1189                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1190                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1191                                 gen_nullptr_check(s1);
1192                                 gen_bound_check(s1, s2);
1193                         }
1194                         M_ADD(REG_ITMP1, s1, s2); /* REG_ITMP1 = s1 + 1 * s2 */
1195                         M_LDRSB(d, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1196                         emit_store_dst(jd, iptr, d);
1197                         break;
1198
1199                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1200
1201                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1202                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1203                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1204                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1205                                 gen_nullptr_check(s1);
1206                                 gen_bound_check(s1, s2);
1207                         }
1208                         M_ADD(REG_ITMP1, s1, REG_LSL(s2, 1)); /* REG_ITMP1 = s1 + 2 * s2 */
1209                         M_LDRH(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1210                         emit_store_dst(jd, iptr, d);
1211                         break;
1212
1213                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1214
1215                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1216                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1217                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1218                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1219                                 gen_nullptr_check(s1);
1220                                 gen_bound_check(s1, s2);
1221                         }
1222                         M_ADD(REG_ITMP1, s1, REG_LSL(s2, 1)); /* REG_ITMP1 = s1 + 2 * s2 */
1223                         M_LDRSH(d, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1224                         emit_store_dst(jd, iptr, d);
1225                         break;
1226
1227                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1228
1229                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1230                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1231                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1232                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1233                                 gen_nullptr_check(s1);
1234                                 gen_bound_check(s1, s2);
1235                         }
1236                         M_ADD(REG_ITMP3, s1, REG_LSL(s2, 3)); /* REG_ITMP3 = s1 + 8 * s2 */
1237                         M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1238                         emit_store_dst(jd, iptr, d);
1239                         break;
1240
1241                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1242
1243                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1244                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1245                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1246                                 gen_nullptr_check(s1);
1247                                 gen_bound_check(s1, s2);
1248                         }
1249                         M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */
1250 #if !defined(ENABLE_SOFTFLOAT)
1251                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1252                         M_FLD_INTERN(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1253 #else
1254                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1255                         M_ILD_INTERN(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1256 #endif
1257                         emit_store_dst(jd, iptr, d);
1258                         break;
1259
1260                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1261
1262                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1263                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1264                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1265                                 gen_nullptr_check(s1);
1266                                 gen_bound_check(s1, s2);
1267                         }
1268                         M_ADD(REG_ITMP3, s1, REG_LSL(s2, 3)); /* REG_ITMP3 = s1 + 8 * s2 */
1269 #if !defined(ENABLE_SOFTFLOAT)
1270                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1271                         M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1272 #else
1273                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1274                         M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1275 #endif
1276                         emit_store_dst(jd, iptr, d);
1277                         break;
1278
1279                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1280
1281                         s1 = emit_load_s1(jd, iptr, REG_A0);
1282                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1283                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1284                                 gen_nullptr_check(s1);
1285                                 gen_bound_check(s1, s2);
1286                         }
1287                         s3 = emit_load_s3(jd, iptr, REG_A1);
1288
1289                         /* move arguments to argument registers */
1290                         M_INTMOVE(s1, REG_A0);
1291                         M_INTMOVE(s3, REG_A1);
1292
1293                         /* call builtin function */
1294                         disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1295                         M_DSEG_BRANCH(disp);
1296
1297                         /* recompute ip */
1298                         s1 = (s4) (cd->mcodeptr - cd->mcodebase);
1299                         M_RECOMPUTE_IP(s1);
1300
1301                         /* check resturn value of builtin */
1302                         M_TST(REG_RESULT, REG_RESULT);
1303                         M_BEQ(0);
1304                         codegen_add_arraystoreexception_ref(cd);
1305
1306                         /* finally store address into array */
1307                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1308                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1309                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1310                         M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */
1311                         M_STR_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1312                         break;
1313
1314                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1315
1316                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1317                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1318                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1319                                 gen_nullptr_check(s1);
1320                                 gen_bound_check(s1, s2);
1321                         }
1322                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1323                         M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */
1324                         M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1325                         break;
1326
1327                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1328
1329                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1330                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1331                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1332                                 gen_nullptr_check(s1);
1333                                 gen_bound_check(s1, s2);
1334                         }
1335                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1336                         M_ADD(REG_ITMP1, s1, s2); /* REG_ITMP1 = s1 + 1 * s2 */
1337                         M_STRB(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1338                         break;
1339
1340                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1341
1342                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1343                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1344                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1345                                 gen_nullptr_check(s1);
1346                                 gen_bound_check(s1, s2);
1347                         }
1348                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1349                         M_ADD(REG_ITMP1, s1, REG_LSL(s2, 1)); /* REG_ITMP1 = s1 + 2 * s2 */
1350                         M_STRH(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1351                         break;
1352
1353                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1354
1355                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1356                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1357                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1358                                 gen_nullptr_check(s1);
1359                                 gen_bound_check(s1, s2);
1360                         }
1361                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1362                         M_ADD(REG_ITMP1, s1, REG_LSL(s2, 1)); /* REG_ITMP1 = s1 + 2 * s2 */
1363                         M_STRH(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1364                         break;
1365
1366                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1367
1368                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1369                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1370                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1371                                 gen_nullptr_check(s1);
1372                                 gen_bound_check(s1, s2);
1373                         }
1374                         M_ADD(REG_ITMP3, s1, REG_LSL(s2, 3)); /* REG_ITMP3 = s1 + 8 * s2 */
1375                         s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1376                         M_LST_INTERN(s3, REG_ITMP3, OFFSET(java_longarray, data[0]));
1377                         break;
1378
1379                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1380
1381                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1382                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1383                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1384                                 gen_nullptr_check(s1);
1385                                 gen_bound_check(s1, s2);
1386                         }
1387                         M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */
1388 #if !defined(ENABLE_SOFTFLOAT)
1389                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1390                         M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1391 #else
1392                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1393                         M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1394 #endif
1395                         break;
1396
1397                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1398
1399                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1400                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1401                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1402                                 gen_nullptr_check(s1);
1403                                 gen_bound_check(s1, s2);
1404                         }
1405                         M_ADD(REG_ITMP1, s1, REG_LSL(s2, 3)); /* REG_ITMP1 = s1 + 8 * s2 */
1406 #if !defined(ENABLE_SOFTFLOAT)
1407                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1408                         M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1409 #else
1410                         s3 = emit_load_s3(jd, iptr, VAROP(iptr->sx.s23.s3), REG_ITMP23_PACKED);
1411                         M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1412 #endif
1413                         break;
1414
1415                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1416
1417                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1418                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
1419
1420                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1421
1422                                 disp = dseg_add_unique_address(cd, NULL);
1423
1424                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1425
1426                                 if (opt_showdisassemble)
1427                                         M_NOP;
1428                         }
1429                         else {
1430                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1431
1432                                 fieldtype = fi->type;
1433
1434                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1435                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1436
1437                                         if (opt_showdisassemble)
1438                                                 M_NOP;
1439                                 }
1440
1441                                 disp = dseg_add_address(cd, &(fi->value));
1442                         }
1443
1444                         M_DSEG_LOAD(REG_ITMP3, disp);
1445                         switch (fieldtype) {
1446                         case TYPE_INT:
1447 #if defined(ENABLE_SOFTFLOAT)
1448                         case TYPE_FLT:
1449 #endif
1450                         case TYPE_ADR:
1451                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1452                                 M_ILD_INTERN(d, REG_ITMP3, 0);
1453                                 break;
1454                         case TYPE_LNG:
1455 #if defined(ENABLE_SOFTFLOAT)
1456                         case TYPE_DBL:
1457 #endif
1458                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1459                                 M_LLD_INTERN(d, REG_ITMP3, 0);
1460                                 break;
1461 #if !defined(ENABLE_SOFTFLOAT)
1462                         case TYPE_FLT:
1463                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1464                                 M_FLD_INTERN(d, REG_ITMP3, 0);
1465                                 break;
1466                         case TYPE_DBL:
1467                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1468                                 M_DLD_INTERN(d, REG_ITMP3, 0);
1469                                 break;
1470 #endif
1471                         default:
1472                                 assert(0);
1473                         }
1474                         emit_store_dst(jd, iptr, d);
1475                         break;
1476
1477                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
1478
1479                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1480                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
1481
1482                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1483
1484                                 disp = dseg_add_unique_address(cd, NULL);
1485
1486                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1487
1488                                 if (opt_showdisassemble)
1489                                         M_NOP;
1490                         }
1491                         else {
1492                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1493
1494                                 fieldtype = fi->type;
1495
1496                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1497                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1498
1499                                         if (opt_showdisassemble)
1500                                                 M_NOP;
1501                                 }
1502
1503                                 disp = dseg_add_address(cd, &(fi->value));
1504                         }
1505
1506                         M_DSEG_LOAD(REG_ITMP3, disp);
1507                         switch (fieldtype) {
1508                         case TYPE_INT:
1509 #if defined(ENABLE_SOFTFLOAT)
1510                         case TYPE_FLT:
1511 #endif
1512                         case TYPE_ADR:
1513                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1514                                 M_IST_INTERN(s1, REG_ITMP3, 0);
1515                                 break;
1516                         case TYPE_LNG:
1517 #if defined(ENABLE_SOFTFLOAT)
1518                         case TYPE_DBL:
1519 #endif
1520                                 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1521                                 M_LST_INTERN(s1, REG_ITMP3, 0);
1522                                 break;
1523 #if !defined(ENABLE_SOFTFLOAT)
1524                         case TYPE_FLT:
1525                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1526                                 M_FST_INTERN(s1, REG_ITMP3, 0);
1527                                 break;
1528                         case TYPE_DBL:
1529                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1530                                 M_DST_INTERN(s1, REG_ITMP3, 0);
1531                                 break;
1532 #endif
1533                         default:
1534                                 assert(0);
1535                         }
1536                         break;
1537
1538                 case ICMD_GETFIELD:   /* ..., objectref, value  ==> ...               */
1539
1540                         s1 = emit_load_s1(jd, iptr, REG_ITMP3);
1541                         gen_nullptr_check(s1);
1542 #if !defined(ENABLE_SOFTFLOAT)
1543                         /* HACK: softnull checks on floats */
1544                         if (!checknull && IS_FLT_DBL_TYPE(fieldtype))
1545                                 gen_nullptr_check_intern(s1);
1546 #endif
1547
1548                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1549                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
1550
1551                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1552
1553                                 codegen_addpatchref(cd, PATCHER_get_putfield,
1554                                                                         iptr->sx.s23.s3.uf, 0);
1555
1556                                 if (opt_showdisassemble)
1557                                         M_NOP;
1558
1559                                 disp = 0;
1560                         }
1561                         else {
1562                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1563
1564                                 fieldtype = fi->type;
1565                                 disp      = fi->offset;
1566                         }
1567
1568                         switch (fieldtype) {
1569                         case TYPE_INT:
1570 #if defined(ENABLE_SOFTFLOAT)
1571                         case TYPE_FLT:
1572 #endif
1573                         case TYPE_ADR:
1574                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1575                                 M_ILD(d, s1, disp);
1576                                 break;
1577                         case TYPE_LNG:
1578 #if defined(ENABLE_SOFTFLOAT)
1579                         case TYPE_DBL:
1580 #endif
1581                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1582                                 M_LLD(d, s1, disp);
1583                                 break;
1584 #if !defined(ENABLE_SOFTFLOAT)
1585                         case TYPE_FLT:
1586                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1587                                 M_FLD(d, s1, disp);
1588                                 break;
1589                         case TYPE_DBL:
1590                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1591                                 M_DLD(d, s1, disp);
1592                                 break;
1593 #endif
1594                         default:
1595                                 assert(0);
1596                         }
1597                         emit_store_dst(jd, iptr, d);
1598                         break;
1599
1600                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
1601
1602                         s1 = emit_load_s1(jd, iptr, REG_ITMP3);
1603                         gen_nullptr_check(s1);
1604
1605 #if !defined(ENABLE_SOFTFLOAT)
1606                         /* HACK: softnull checks on floats */
1607                         if (!checknull && IS_FLT_DBL_TYPE(fieldtype))
1608                                 gen_nullptr_check_intern(s1);
1609 #endif
1610
1611                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1612                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
1613
1614                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1615                         }
1616                         else {
1617                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1618
1619                                 fieldtype = fi->type;
1620                                 disp      = fi->offset;
1621                         }
1622
1623                         switch (fieldtype) {
1624                         case TYPE_INT:
1625 #if defined(ENABLE_SOFTFLOAT)
1626                         case TYPE_FLT:
1627 #endif
1628                         case TYPE_ADR:
1629                                 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1630                                 break;
1631 #if defined(ENABLE_SOFTFLOAT)
1632                         case TYPE_DBL: /* fall through */
1633 #endif
1634                         case TYPE_LNG:
1635                                 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
1636                                 break;
1637 #if !defined(ENABLE_SOFTFLOAT)
1638                         case TYPE_FLT:
1639                         case TYPE_DBL:
1640                                 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
1641                                 break;
1642 #endif
1643                         default:
1644                                 assert(0);
1645                         }
1646
1647                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1648                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
1649
1650                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1651
1652                                 if (opt_showdisassemble)
1653                                         M_NOP;
1654
1655                                 disp = 0;
1656                         }
1657
1658                         switch (fieldtype) {
1659                         case TYPE_INT:
1660 #if defined(ENABLE_SOFTFLOAT)
1661                         case TYPE_FLT:
1662 #endif
1663                         case TYPE_ADR:
1664                                 M_IST(s2, s1, disp);
1665                                 break;
1666                         case TYPE_LNG:
1667 #if defined(ENABLE_SOFTFLOAT)
1668                         case TYPE_DBL:
1669 #endif
1670                                 M_LST(s2, s1, disp);
1671                                 break;
1672 #if !defined(ENABLE_SOFTFLOAT)
1673                         case TYPE_FLT:
1674                                 M_FST(s2, s1, disp);
1675                                 break;
1676                         case TYPE_DBL:
1677                                 M_DST(s2, s1, disp);
1678                                 break;
1679 #endif
1680                         default:
1681                                 assert(0);
1682                         }
1683                         break;
1684
1685
1686                 /* branch operations **************************************************/
1687
1688                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
1689
1690                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1691                         M_INTMOVE(s1, REG_ITMP1_XPTR);
1692                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1693                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
1694                                                                         iptr->sx.s23.s2.uc, 0);
1695
1696                                 if (opt_showdisassemble)
1697                                         M_NOP;
1698                         }
1699                         disp = dseg_add_functionptr(cd, asm_handle_exception);
1700                         M_DSEG_LOAD(REG_ITMP3, disp);
1701                         M_MOV(REG_ITMP2_XPC, REG_PC);
1702                         M_MOV(REG_PC, REG_ITMP3);
1703                         M_NOP;              /* nop ensures that XPC is less than the end  */
1704                                             /* of basic block                             */
1705                         break;
1706
1707                 case ICMD_GOTO:         /* ... ==> ...                                */
1708                 case ICMD_RET:
1709
1710                         M_B(0);
1711                         codegen_addreference(cd, iptr->dst.block);
1712                         break;
1713
1714                 case ICMD_JSR:          /* ... ==> ...                                */
1715
1716                         M_B(0);
1717                         codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
1718                         break;
1719                 
1720                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
1721
1722                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1723                         M_TEQ_IMM(s1, 0);
1724                         M_BEQ(0);
1725                         codegen_addreference(cd, iptr->dst.block);
1726                         break;
1727
1728                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
1729
1730                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1731                         M_TEQ_IMM(s1, 0);
1732                         M_BNE(0);
1733                         codegen_addreference(cd, iptr->dst.block);
1734                         break;
1735
1736                 case ICMD_IFLT:         /* ..., value ==> ...                         */
1737                 case ICMD_IFLE:         /* op1 = target JavaVM pc, val.i = constant   */
1738                 case ICMD_IFGT:
1739                 case ICMD_IFGE:
1740                 case ICMD_IFEQ:
1741                 case ICMD_IFNE:
1742
1743                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1744                         M_COMPARE(s1, iptr->sx.val.i, UNCOND, 0);
1745
1746                         switch(iptr->opc) {
1747                         case ICMD_IFLT:
1748                                 M_BLT(0);
1749                                 break;
1750                         case ICMD_IFLE:
1751                                 M_BLE(0);
1752                                 break;
1753                         case ICMD_IFGT:
1754                                 M_BGT(0);
1755                                 break;
1756                         case ICMD_IFGE:
1757                                 M_BGE(0);
1758                                 break;
1759                         case ICMD_IFEQ:
1760                                 M_BEQ(0);
1761                                 break;
1762                         case ICMD_IFNE:
1763                                 M_BNE(0);
1764                                 break;
1765                         default:
1766                                 assert(0);
1767                         }
1768                         codegen_addreference(cd, iptr->dst.block);
1769                         break;
1770
1771                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
1772                 case ICMD_IF_LLE:       /* op1 = target JavaVM pc, val.l = constant   */
1773                 case ICMD_IF_LGT:
1774                 case ICMD_IF_LGE:
1775                 case ICMD_IF_LEQ:
1776                 case ICMD_IF_LNE:
1777
1778                         /* ATTENTION: compare high words signed and low words unsigned */
1779
1780                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1781                         M_COMPARE(s1, (iptr->sx.val.l >> 32), UNCOND, 0);
1782
1783                         switch(iptr->opc) {
1784                         case ICMD_IF_LLT:
1785                         case ICMD_IF_LLE:
1786                                 M_BLT(0);
1787                                 codegen_addreference(cd, iptr->dst.block);
1788                                 break;
1789                         case ICMD_IF_LGT:
1790                         case ICMD_IF_LGE:
1791                                 M_BGT(0);
1792                                 codegen_addreference(cd, iptr->dst.block);
1793                                 break;
1794                         case ICMD_IF_LEQ: /* EQ and NE are the same for unsigned */
1795                         case ICMD_IF_LNE:
1796                                 break;
1797                         default:
1798                                 assert(0);
1799                         }
1800
1801                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1802
1803                         switch(iptr->opc) {
1804                         case ICMD_IF_LLT:
1805                                 M_COMPARE(s1, (iptr->sx.val.l & 0xffffffff), COND_EQ, 1);
1806                                 M_BLO(0);
1807                                 break;
1808                         case ICMD_IF_LLE:
1809                                 M_COMPARE(s1, (iptr->sx.val.l & 0xffffffff), COND_EQ, 1);
1810                                 M_BLS(0);
1811                                 break;
1812                         case ICMD_IF_LGT:
1813                                 M_COMPARE(s1, (iptr->sx.val.l & 0xffffffff), COND_EQ, 1);
1814                                 M_BHI(0);
1815                                 break;
1816                         case ICMD_IF_LGE:
1817                                 M_COMPARE(s1, (iptr->sx.val.l & 0xffffffff), COND_EQ, 1);
1818                                 M_BHS(0);
1819                                 break;
1820                         case ICMD_IF_LEQ:
1821                                 M_COMPARE(s1, (iptr->sx.val.l & 0xffffffff), COND_EQ, 0);
1822                                 M_BEQ(0);
1823                                 break;
1824                         case ICMD_IF_LNE:
1825                                 M_COMPARE(s1, (iptr->sx.val.l & 0xffffffff), COND_EQ, 0);
1826                                 M_BNE(0);
1827                                 break;
1828                         default:
1829                                 assert(0);
1830                         }
1831                         codegen_addreference(cd, iptr->dst.block);
1832                         break;
1833
1834                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
1835                 case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
1836                 case ICMD_IF_ICMPNE:
1837                 case ICMD_IF_ACMPNE:
1838                 case ICMD_IF_ICMPLT:
1839                 case ICMD_IF_ICMPLE:
1840                 case ICMD_IF_ICMPGT:
1841                 case ICMD_IF_ICMPGE:
1842
1843                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1844                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1845                         M_CMP(s1, s2);
1846                         switch(iptr->opc) {
1847                         case ICMD_IF_ICMPLT:
1848                                 M_BLT(0);
1849                                 break;
1850                         case ICMD_IF_ICMPLE:
1851                                 M_BLE(0);
1852                                 break;
1853                         case ICMD_IF_ICMPGT:
1854                                 M_BGT(0);
1855                                 break;
1856                         case ICMD_IF_ICMPGE:
1857                                 M_BGE(0);
1858                                 break;
1859                         case ICMD_IF_ICMPEQ:
1860                         case ICMD_IF_ACMPEQ:
1861                                 M_BEQ(0);
1862                                 break;
1863                         case ICMD_IF_ICMPNE:
1864                         case ICMD_IF_ACMPNE:
1865                                 M_BNE(0);
1866                                 break;
1867                         default:
1868                                 assert(0);
1869                         }
1870                         codegen_addreference(cd, iptr->dst.block);
1871                         break;
1872
1873                 case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
1874                 case ICMD_IF_LCMPNE:    /* op1 = target JavaVM pc                     */
1875                 case ICMD_IF_LCMPLT:
1876                 case ICMD_IF_LCMPLE:
1877                 case ICMD_IF_LCMPGT:
1878                 case ICMD_IF_LCMPGE:
1879
1880                         /* ATTENTION: compare high words signed and low words unsigned */
1881                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1882                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1883                         M_CMP(s1, s2);
1884
1885                         switch(iptr->opc) {
1886                         case ICMD_IF_LCMPEQ: /* EQ and NE are the same for unsigned */
1887                         case ICMD_IF_LCMPNE:
1888                                 break;
1889                         case ICMD_IF_LCMPLT:
1890                         case ICMD_IF_LCMPLE:
1891                                 M_BLT(0);
1892                                 codegen_addreference(cd, iptr->dst.block);
1893                                 break;
1894                         case ICMD_IF_LCMPGT:
1895                         case ICMD_IF_LCMPGE:
1896                                 M_BGT(0);
1897                                 codegen_addreference(cd, iptr->dst.block);
1898                                 break;
1899                         default:
1900                                 assert(0);
1901                         }
1902
1903                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1904                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1905
1906                         switch(iptr->opc) {
1907                         case ICMD_IF_LCMPEQ:
1908                                 M_DAT(COND_EQ,0x0a,0,s1,1,0,s2);
1909                                 M_BEQ(0);
1910                                 break;
1911                         case ICMD_IF_LCMPNE:
1912                                 M_DAT(COND_EQ,0x0a,0,s1,1,0,s2);
1913                                 M_BNE(0);
1914                                 break;
1915                         case ICMD_IF_LCMPLT:
1916                                 M_BNE(1);
1917                                 M_CMP(s1, s2);
1918                                 M_BLO(0);
1919                                 break;
1920                         case ICMD_IF_LCMPLE:
1921                                 M_BNE(1);
1922                                 M_CMP(s1, s2);
1923                                 M_BLS(0);
1924                                 break;
1925                         case ICMD_IF_LCMPGT:
1926                                 M_BNE(1);
1927                                 M_CMP(s1, s2);
1928                                 M_BHI(0);
1929                                 break;
1930                         case ICMD_IF_LCMPGE:
1931                                 M_BNE(1);
1932                                 M_CMP(s1, s2);
1933                                 M_BHS(0);
1934                                 break;
1935                         default:
1936                                 assert(0);
1937                         }
1938                         codegen_addreference(cd, iptr->dst.block);
1939                         break;
1940
1941                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
1942                         {
1943                         s4 i, l;
1944                         branch_target_t *table;
1945
1946                         table = iptr->dst.table;
1947
1948                         l = iptr->sx.s23.s2.tablelow;
1949                         i = iptr->sx.s23.s3.tablehigh;
1950
1951                         /* calculate new index (index - low) */
1952                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1953                         if (l  == 0) {
1954                                 M_INTMOVE(s1, REG_ITMP1);
1955                         } else if (IS_IMM(l)) {
1956                                 M_SUB_IMM(REG_ITMP1, s1, l);
1957                         } else {
1958                                 ICONST(REG_ITMP2, l);
1959                                 M_SUB(REG_ITMP1, s1, REG_ITMP2);
1960                         }
1961
1962                         /* range check (index <= high-low) */
1963                         i = i - l + 1;
1964                         M_COMPARE(REG_ITMP1, i-1, UNCOND, 0);
1965                         M_BHI(0); /* unsigned greater than */
1966                         codegen_addreference(cd, table[0].block);
1967
1968                         /* build jump table top down and use address of lowest entry */
1969
1970                         table += i;
1971
1972                         while (--i >= 0) {
1973                                 dseg_add_target(cd, table->block);
1974                                 --table;
1975                         }
1976                         }
1977
1978                         /* length of dataseg after last dseg_add_target is used by load */
1979                         /* TODO: this loads from data-segment */
1980                         M_ADD(REG_ITMP2, REG_IP, REG_LSL(REG_ITMP1, 2));
1981                         M_LDR(REG_PC, REG_ITMP2, -(cd->dseglen));
1982                         break;
1983
1984                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
1985                         {
1986                         s4 i;
1987                         lookup_target_t *lookup;
1988
1989                         lookup = iptr->dst.lookup;
1990
1991                         i = iptr->sx.s23.s2.lookupcount;
1992                         
1993                         /* compare keys */
1994                         MCODECHECK((i<<2)+8);
1995                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1996
1997                         while (--i >= 0) {
1998                                 M_COMPARE(s1, lookup->value, UNCOND, 0);
1999                                 M_BEQ(0);
2000                                 codegen_addreference(cd, lookup->target.block);
2001                                 lookup++;
2002                         }
2003
2004                         /* default branch */
2005                         M_B(0);
2006                         codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
2007                         }
2008                         break;
2009
2010                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2011
2012 #if !defined(ENABLE_SOFTFLOAT)
2013                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2014                         M_CAST_FLT_TO_INT_TYPED(VAROP(iptr->s1)->type, s1, REG_RESULT);
2015                         goto ICMD_RETURN_do;
2016 #endif
2017
2018                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2019
2020                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2021                         M_INTMOVE(s1, REG_RESULT);
2022                         goto ICMD_RETURN_do;
2023
2024                 case ICMD_DRETURN:      /* ..., retvalue ==> ...                      */
2025
2026 #if !defined(ENABLE_SOFTFLOAT)
2027                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2028                         M_CAST_FLT_TO_INT_TYPED(VAROP(iptr->s1)->type, s1, REG_RESULT_PACKED);
2029                         goto ICMD_RETURN_do;
2030 #endif
2031
2032                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
2033
2034                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2035                         M_LNGMOVE(s1, REG_RESULT_PACKED);
2036                         goto ICMD_RETURN_do;
2037
2038                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2039
2040                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2041                         M_INTMOVE(s1, REG_RESULT);
2042                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2043                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2044                                                                         iptr->sx.s23.s2.uc, 0);
2045
2046                                 if (opt_showdisassemble)
2047                                         M_NOP;
2048                         }
2049                         goto ICMD_RETURN_do;
2050
2051                 case ICMD_RETURN:       /* ...  ==> ...                               */
2052                         ICMD_RETURN_do:
2053
2054 #if !defined(NDEBUG)
2055                         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2056                                 emit_verbosecall_exit(jd);
2057 #endif
2058
2059 #if defined(ENABLE_THREADS)
2060                         /* call monitorexit function */
2061
2062                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2063                                 /* stack offset for monitor argument */
2064
2065                                 s1 = rd->memuse;
2066
2067                                 /* we need to save the proper return value */
2068
2069                                 switch (iptr->opc) {
2070                                 case ICMD_IRETURN:
2071                                 case ICMD_ARETURN:
2072                                 case ICMD_LRETURN:
2073                                 case ICMD_FRETURN: /* XXX TWISTI: is that correct? */
2074                                 case ICMD_DRETURN:
2075                                         M_STMFD(BITMASK_RESULT, REG_SP);
2076                                         s1 += 2;
2077                                         break;
2078                                 }
2079
2080                                 M_LDR(REG_A0, REG_SP, s1 * 4);
2081                                 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2082                                 M_DSEG_BRANCH(disp);
2083
2084                                 /* we no longer need IP here, no more loading */
2085                                 /*s1 = (s4) (cd->mcodeptr - cd->mcodebase);
2086                                 M_RECOMPUTE_IP(s1);*/
2087
2088                                 switch (iptr->opc) {
2089                                 case ICMD_IRETURN:
2090                                 case ICMD_ARETURN:
2091                                 case ICMD_LRETURN:
2092                                 case ICMD_FRETURN: /* XXX TWISTI: is that correct? */
2093                                 case ICMD_DRETURN:
2094                                         M_LDMFD(BITMASK_RESULT, REG_SP);
2095                                         break;
2096                                 }
2097                         }
2098 #endif
2099
2100                         /* deallocate stackframe for spilled variables */
2101                         if (spilledregs_num) {
2102                                 M_ADD_IMM_EXT_MUL4(REG_SP, REG_SP, spilledregs_num);
2103                         }
2104
2105                         /* restore callee saved registers + do return */
2106                         if (savedregs_bitmask) {
2107                                 if (!jd->isleafmethod) {
2108                                         savedregs_bitmask &= ~(1<<REG_LR);
2109                                         savedregs_bitmask |= (1<<REG_PC);
2110                                 }
2111                                 M_LDMFD(savedregs_bitmask, REG_SP);
2112                         }
2113
2114                         /* if LR was not on stack, we need to return manually */
2115                         if (jd->isleafmethod)
2116                                 M_MOV(REG_PC, REG_LR);
2117                         break;
2118
2119                 case ICMD_BUILTIN:      /* ..., arg1, arg2, arg3 ==> ...              */
2120
2121                         bte = iptr->sx.s23.s3.bte;
2122                         md  = bte->md;
2123                         goto ICMD_INVOKE_do;
2124
2125                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
2126                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2127                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
2128                 case ICMD_INVOKEINTERFACE:
2129
2130                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2131                                 lm = NULL;
2132                                 um = iptr->sx.s23.s3.um;
2133                                 md = um->methodref->parseddesc.md;
2134                         }
2135                         else {
2136                                 lm = iptr->sx.s23.s3.fmiref->p.method;
2137                                 um = NULL;
2138                                 md = lm->parseddesc;
2139                         }
2140
2141                 ICMD_INVOKE_do:
2142                         /* copy arguments to registers or stack location */
2143
2144                         s3 = md->paramcount;
2145
2146                         MCODECHECK((s3 << 1) + 64);
2147
2148                         for (s3 = s3 - 1; s3 >= 0; s3--) {
2149                                 var = VAR(iptr->sx.s23.s2.args[s3]);
2150
2151                                 if (var->flags & PREALLOC) /* argument was precolored? */
2152                                         continue;
2153
2154                                 /* TODO: document me */
2155 #if !defined(ENABLE_SOFTFLOAT)
2156                                 if (IS_INT_LNG_TYPE(var->type)) {
2157 #endif /* !defined(ENABLE_SOFTFLOAT) */
2158                                         if (!md->params[s3].inmemory) {
2159                                                 s1 = ARGUMENT_REGS(var->type, md->params[s3].regoff);
2160                                                 SPLIT_OPEN(var->type, s1, REG_ITMP2);
2161                                                 d = emit_load(jd, iptr, var, s1);
2162
2163                                                 if (IS_2_WORD_TYPE(var->type))
2164                                                         M_LNGMOVE(d, s1);
2165                                                 else
2166                                                         M_INTMOVE(d, s1);
2167
2168                                                 SPLIT_STORE_AND_CLOSE(var->type, s1, 0);
2169                                         }
2170                                         else {
2171                                                 if (IS_2_WORD_TYPE(var->type)) {
2172                                                         d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
2173                                                         M_LST(d, REG_SP, md->params[s3].regoff * 4);
2174                                                 }
2175                                                 else {
2176                                                         d = emit_load(jd, iptr, var, REG_ITMP1);
2177                                                         M_IST(d, REG_SP, md->params[s3].regoff * 4);
2178                                                 }
2179                                         }
2180 #if !defined(ENABLE_SOFTFLOAT)
2181                                 }
2182                                 else {
2183                                         if (!md->params[s3].inmemory) {
2184                                                 s1 = ARGUMENT_REGS(var->type, md->params[s3].regoff);
2185                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
2186                                                 SPLIT_OPEN(var->type, s1, REG_ITMP1);
2187                                                 M_CAST_FLT_TO_INT_TYPED(var->type, d, s1);
2188                                                 SPLIT_STORE_AND_CLOSE(var->type, s1, 0);
2189                                         }
2190                                         else {
2191                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
2192                                                 M_STACK_STORE_FLT_TYPED(var->type, d, md->params[s3].regoff);
2193                                         }
2194                                 }
2195 #endif /* !defined(ENABLE_SOFTFLOAT) */
2196                         }
2197
2198                         switch (iptr->opc) {
2199                         case ICMD_BUILTIN:
2200                                 disp = dseg_add_functionptr(cd, bte->fp);
2201
2202                                 M_DSEG_LOAD(REG_IP, disp); /* Pointer to built-in-function */
2203                                 break;
2204
2205                         case ICMD_INVOKESPECIAL:
2206                                 M_TST(REG_A0, REG_A0);
2207                                 M_BEQ(0);
2208                                 codegen_add_nullpointerexception_ref(cd);
2209                                 /* fall through */
2210
2211                         case ICMD_INVOKESTATIC:
2212                                 if (lm == NULL) {
2213                                         disp = dseg_add_unique_address(cd, NULL);
2214
2215                                         codegen_addpatchref(cd, PATCHER_invokestatic_special,
2216                                                                                 um, disp);
2217
2218                                         if (opt_showdisassemble)
2219                                                 M_NOP;
2220                                 }
2221                                 else
2222                                         disp = dseg_add_address(cd, lm->stubroutine);
2223
2224                                 M_DSEG_LOAD(REG_IP, disp);            /* Pointer to method */
2225                                 break;
2226
2227                         case ICMD_INVOKEVIRTUAL:
2228                                 gen_nullptr_check(REG_A0);
2229
2230                                 if (lm == NULL) {
2231                                         codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2232
2233                                         if (opt_showdisassemble)
2234                                                 M_NOP;
2235
2236                                         s1 = 0;
2237                                 }
2238                                 else
2239                                         s1 = OFFSET(vftbl_t, table[0]) +
2240                                                 sizeof(methodptr) * lm->vftblindex;
2241
2242                                 M_LDR_INTERN(REG_METHODPTR, REG_A0,
2243                                                          OFFSET(java_objectheader, vftbl));
2244                                 M_LDR_INTERN(REG_IP, REG_METHODPTR, s1);
2245                                 break;
2246
2247                         case ICMD_INVOKEINTERFACE:
2248                                 gen_nullptr_check(REG_A0);
2249
2250                                 if (lm == NULL) {
2251                                         codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2252
2253                                         if (opt_showdisassemble)
2254                                                 M_NOP;
2255
2256                                         s1 = 0;
2257                                         s2 = 0;
2258                                 }
2259                                 else {
2260                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
2261                                                 sizeof(methodptr*) * lm->class->index;
2262                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
2263                                 }
2264
2265                                 M_LDR_INTERN(REG_METHODPTR, REG_A0,
2266                                                          OFFSET(java_objectheader, vftbl));
2267                                 M_LDR_INTERN(REG_METHODPTR, REG_METHODPTR, s1);
2268                                 M_LDR_INTERN(REG_IP, REG_METHODPTR, s2);
2269                                 break;
2270                         }
2271
2272                         /* generate the actual call */
2273
2274                         M_MOV(REG_LR, REG_PC);               /* save return address in LR */
2275                         M_MOV(REG_PC, REG_IP);               /* branch to method          */
2276                         s1 = (s4) (cd->mcodeptr - cd->mcodebase);
2277                         M_RECOMPUTE_IP(s1);
2278
2279                         /* actually only used for ICMD_BUILTIN */
2280
2281                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2282                                 M_TST(REG_RESULT, REG_RESULT);
2283                                 M_BEQ(0);
2284                                 codegen_add_fillinstacktrace_ref(cd);
2285                         }
2286
2287                         /* store return value */
2288
2289                         d = md->returntype.type;
2290
2291 #if !defined(__SOFTFP__)
2292                         /* TODO: this is only a hack, since we use R0/R1 for float
2293                            return!  this depends on gcc; it is independent from
2294                            our ENABLE_SOFTFLOAT define */
2295                         if (iptr->opc == ICMD_BUILTIN && d != TYPE_VOID && IS_FLT_DBL_TYPE(d)) {
2296 #if 0 && !defined(NDEBUG)
2297                                 dolog("BUILTIN that returns float or double (%s.%s)", m->class->name->text, m->name->text);
2298 #endif
2299                                 /* we cannot use this macro, since it is not defined
2300                                    in ENABLE_SOFTFLOAT M_CAST_FLT_TO_INT_TYPED(d,
2301                                    REG_FRESULT, REG_RESULT_TYPED(d)); */
2302                                 if (IS_2_WORD_TYPE(d)) {
2303                                         DCD(0xed2d8102); /* stfd    f0, [sp, #-8]! */
2304                                         M_LDRD_UPDATE(REG_RESULT_PACKED, REG_SP, 8);
2305                                 } else {
2306                                         DCD(0xed2d0101); /* stfs    f0, [sp, #-4]!*/
2307                                         M_LDR_UPDATE(REG_RESULT, REG_SP, 4);
2308                                 }
2309                         }
2310 #endif
2311
2312                         if (d != TYPE_VOID) {
2313 #if !defined(ENABLE_SOFTFLOAT)
2314                                 if (IS_INT_LNG_TYPE(d)) {
2315 #endif /* !defined(ENABLE_SOFTFLOAT) */
2316                                         if (IS_2_WORD_TYPE(d)) {
2317                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
2318                                                 M_LNGMOVE(REG_RESULT_PACKED, s1);
2319                                         }
2320                                         else {
2321                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2322                                                 M_INTMOVE(REG_RESULT, s1);
2323                                         }
2324
2325 #if !defined(ENABLE_SOFTFLOAT)
2326                                 } else {
2327                                         s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2328                                         M_CAST_INT_TO_FLT_TYPED(VAROP(iptr->dst)->type, REG_RESULT_TYPED(VAROP(iptr->dst)->type), s1);
2329                                 }
2330 #endif /* !defined(ENABLE_SOFTFLOAT) */
2331
2332                                 emit_store_dst(jd, iptr, s1);
2333                         }
2334                         break;
2335
2336                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2337                                       /* val.a: (classinfo*) superclass               */
2338                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2339                                 /* object type cast-check */
2340
2341                         classinfo *super;
2342                         s4         superindex;
2343                         u1        *branch1 = NULL;
2344                         u1        *branch2 = NULL;
2345                         u1        *branch3 = NULL;
2346
2347                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2348                                 super      = NULL;
2349                                 superindex = 0;
2350                         }
2351                         else {
2352                                 super      = iptr->sx.s23.s3.c.cls;
2353                                 superindex = super->index;
2354                         }
2355
2356 #if defined(ENABLE_THREADS)
2357                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2358 #endif
2359                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2360
2361                         /* if class is not resolved, check which code to call */
2362
2363                         if (super == NULL) {
2364                                 M_TST(s1, s1);
2365                                 M_BEQ(0);
2366                                 branch1 = cd->mcodeptr;
2367
2368                                 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2369                                 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
2370                                                     iptr->sx.s23.s3.c.ref, disp);
2371
2372                                 if (opt_showdisassemble)
2373                                         M_NOP;
2374
2375                                 M_DSEG_LOAD(REG_ITMP2, disp);
2376                                 disp = dseg_add_s4(cd, ACC_INTERFACE);
2377                                 M_DSEG_LOAD(REG_ITMP3, disp);
2378                                 M_TST(REG_ITMP2, REG_ITMP3);
2379                                 M_BEQ(0);
2380                                 branch2 = cd->mcodeptr;
2381                         }
2382
2383                         /* interface checkcast code */
2384
2385                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2386                                 if (super == NULL) {
2387                                         codegen_addpatchref(cd,
2388                                                             PATCHER_checkcast_instanceof_interface,
2389                                                             iptr->sx.s23.s3.c.ref, 0);
2390
2391                                         if (opt_showdisassemble)
2392                                                 M_NOP;
2393                                 }
2394                                 else {
2395                                         M_TST(s1, s1);
2396                                         M_BEQ(0);
2397                                         branch1 = cd->mcodeptr;
2398                                 }
2399
2400                                 M_LDR_INTERN(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2401                                 M_LDR_INTERN(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2402                                 assert(IS_IMM(superindex));
2403                                 M_CMP_IMM(REG_ITMP3, superindex);
2404                                 M_BLE(0);
2405                                 codegen_add_classcastexception_ref(cd, s1);
2406
2407                                 s2 = OFFSET(vftbl_t, interfacetable[0]) -
2408                                         superindex * sizeof(methodptr*);
2409
2410                                 M_LDR_INTERN(REG_ITMP3, REG_ITMP2, s2);
2411                                 M_TST(REG_ITMP3, REG_ITMP3);
2412                                 M_BEQ(0);
2413                                 codegen_add_classcastexception_ref(cd, s1);
2414
2415                                 if (super == NULL) {
2416                                         M_B(0);
2417                                         branch3 = cd->mcodeptr;
2418                                 }
2419                         }
2420
2421                         if (branch2) {
2422                                 gen_resolvebranch(branch2, branch2 - cd->mcodebase,
2423                                                                   cd->mcodeptr - cd->mcodebase);
2424                         }
2425
2426                         /* class checkcast code */
2427
2428
2429                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2430                                 if (super == NULL) {
2431                                         disp = dseg_add_unique_address(cd, NULL);
2432
2433                                         codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
2434                                                             iptr->sx.s23.s3.c.ref,
2435                                                                                 disp);
2436
2437                                         if (opt_showdisassemble)
2438                                                 M_NOP;
2439                                 }
2440                                 else {
2441                                         disp = dseg_add_address(cd, super->vftbl);
2442
2443                                         M_TST(s1, s1);
2444                                         M_BEQ(0);
2445                                         branch1 = cd->mcodeptr;
2446                                 }
2447
2448                                 M_LDR_INTERN(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2449                                 M_DSEG_LOAD(REG_ITMP3, disp);
2450 #if defined(ENABLE_THREADS)
2451                                 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2452 #endif
2453                                 M_LDR_INTERN(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2454                                 M_LDR_INTERN(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2455                                 M_SUB(REG_ITMP2, REG_ITMP2, REG_ITMP3);
2456                                 M_DSEG_LOAD(REG_ITMP3, disp);
2457                                 M_LDR_INTERN(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2458 #if defined(ENABLE_THREADS)
2459                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2460 #endif
2461                                 M_CMP(REG_ITMP2, REG_ITMP3);
2462                                 M_BHI(0);
2463                                 codegen_add_classcastexception_ref(cd, s1);
2464                         }
2465
2466                         if (branch1) {
2467                                 gen_resolvebranch(branch1, branch1 - cd->mcodebase,
2468                                                                   cd->mcodeptr - cd->mcodebase);
2469                         }
2470
2471                         if (branch3) {
2472                                 gen_resolvebranch(branch3, branch3 - cd->mcodebase,
2473                                                                   cd->mcodeptr - cd->mcodebase);
2474                         }
2475
2476                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2477                         }
2478                         else {
2479                                 /* array type cast-check */
2480
2481                                 s1 = emit_load_s1(jd, iptr, REG_A0);
2482                                 M_INTMOVE(s1, REG_A0);
2483
2484                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2485                                         disp = dseg_add_unique_address(cd, NULL);
2486
2487                                         codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
2488                                                                                 iptr->sx.s23.s3.c.ref,
2489                                                                                 disp);
2490
2491                                         if (opt_showdisassemble)
2492                                                 M_NOP;
2493                                 }
2494                                 else
2495                                         disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2496
2497                                 M_DSEG_LOAD(REG_A1, disp);
2498                                 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2499                                 M_DSEG_BRANCH(disp);
2500
2501                                 /* recompute ip */
2502                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2503                                 M_RECOMPUTE_IP(disp);
2504
2505                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2506                                 M_TST(REG_RESULT, REG_RESULT);
2507                                 M_BEQ(0);
2508                                 codegen_add_classcastexception_ref(cd, s1);
2509
2510                                 d = codegen_reg_of_dst(jd, iptr, s1);
2511                         }
2512
2513                         M_INTMOVE(s1, d);
2514                         emit_store_dst(jd, iptr, d);
2515                         break;
2516
2517                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
2518                                       /* val.a: (classinfo*) superclass               */
2519                         {
2520                         classinfo *super;
2521                         s4         superindex;
2522                         u1        *branch1 = NULL;
2523                         u1        *branch2 = NULL;
2524                         u1        *branch3 = NULL;
2525
2526                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2527                                 super      = NULL;
2528                                 superindex = 0;
2529                         }
2530                         else {
2531                                 super      = iptr->sx.s23.s3.c.cls;
2532                                 superindex = super->index;
2533                         }
2534
2535 #if defined(ENABLE_THREADS)
2536                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2537 #endif
2538                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2539                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2540                         if (s1 == d) {
2541                                 M_MOV(REG_ITMP1, s1);
2542                                 s1 = REG_ITMP1;
2543                         }
2544
2545                         /* if class is not resolved, check which code to call */
2546
2547                         if (super == NULL) {
2548                                 M_EOR(d, d, d);
2549                                 M_TST(s1, s1);
2550                                 M_BEQ(0);
2551                                 branch1 = cd->mcodeptr;
2552
2553                                 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2554                                 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
2555                                                     iptr->sx.s23.s3.c.ref, disp);
2556
2557                                 if (opt_showdisassemble)
2558                                         M_NOP;
2559
2560                                 M_DSEG_LOAD(REG_ITMP2, disp);
2561                                 disp = dseg_add_s4(cd, ACC_INTERFACE);
2562                                 M_DSEG_LOAD(REG_ITMP3, disp);
2563                                 M_TST(REG_ITMP2, REG_ITMP3);
2564                                 M_BEQ(0);
2565                                 branch2 = cd->mcodeptr;
2566                         }
2567
2568                         /* interface checkcast code */
2569
2570                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2571                                 if (super == NULL) {
2572                                         /* If d == REG_ITMP2, then it's destroyed in check
2573                                            code above.  */
2574                                         if (d == REG_ITMP2)
2575                                                 M_EOR(d, d, d);
2576
2577                                         codegen_addpatchref(cd,
2578                                                             PATCHER_checkcast_instanceof_interface,
2579                                                             iptr->sx.s23.s3.c.ref, 0);
2580
2581                                         if (opt_showdisassemble)
2582                                                 M_NOP;
2583                                 }
2584                                 else {
2585                                         M_EOR(d, d, d);
2586                                         M_TST(s1, s1);
2587                                         M_BEQ(0);
2588                                         branch1 = cd->mcodeptr;
2589                                 }
2590
2591                                 M_LDR_INTERN(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2592                                 M_LDR_INTERN(REG_ITMP3,
2593                                                          REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2594                                 assert(IS_IMM(superindex));
2595                                 M_CMP_IMM(REG_ITMP3, superindex);
2596                                 M_BLE(2);
2597
2598                                 s2 = OFFSET(vftbl_t, interfacetable[0]) -
2599                                         superindex * sizeof(methodptr*);
2600
2601                                 M_LDR_INTERN(REG_ITMP3, REG_ITMP1, s2);
2602                                 M_TST(REG_ITMP3, REG_ITMP3);
2603                                 M_MOVNE_IMM(d, 1);
2604
2605                                 if (super == NULL) {
2606                                         M_B(0);
2607                                         branch3 = cd->mcodeptr;
2608                                 }
2609                         }
2610
2611                         if (branch2) {
2612                                 gen_resolvebranch(branch2, branch2 - cd->mcodebase,
2613                                                                   cd->mcodeptr - cd->mcodebase);
2614                         }
2615
2616                         /* class checkcast code */
2617
2618                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2619                                 if (super == NULL) {
2620                                         disp = dseg_add_unique_address(cd, NULL);
2621
2622                                         codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
2623                                                             iptr->sx.s23.s3.c.ref,
2624                                                                                 disp);
2625
2626                                         if (opt_showdisassemble)
2627                                                 M_NOP;
2628                                 }
2629                                 else {
2630                                         disp = dseg_add_address(cd, super->vftbl);
2631
2632                                         M_EOR(d, d, d);
2633                                         M_TST(s1, s1);
2634                                         M_BEQ(0);
2635                                         branch1 = cd->mcodeptr;
2636                                 }
2637
2638                                 M_LDR_INTERN(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2639                                 M_DSEG_LOAD(REG_ITMP2, disp);
2640 #if defined(ENABLE_THREADS)
2641                                 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2642 #endif
2643                                 M_LDR_INTERN(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2644                                 M_LDR_INTERN(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2645                                 M_LDR_INTERN(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2646 #if defined(ENABLE_THREADS)
2647                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2648 #endif
2649                                 M_SUB(REG_ITMP1, REG_ITMP1, REG_ITMP3);
2650                                 M_CMP(REG_ITMP1, REG_ITMP2);
2651                                 /* If d == REG_ITMP2, then it's destroyed */
2652                                 if (d == REG_ITMP2)
2653                                         M_EOR(d, d, d);
2654                                 M_MOVLS_IMM(d, 1);
2655                         }
2656
2657                         if (branch1) {
2658                                 gen_resolvebranch(branch1, branch1 - cd->mcodebase,
2659                                                                   cd->mcodeptr - cd->mcodebase);
2660                         }
2661
2662                         if (branch3) {
2663                                 gen_resolvebranch(branch3, branch3 - cd->mcodebase,
2664                                                                   cd->mcodeptr - cd->mcodebase);
2665                         }
2666
2667                         }
2668
2669                         emit_store_dst(jd, iptr, d);
2670                         break;
2671
2672                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
2673
2674                         /* copy sizes to stack if necessary  */
2675
2676                         MCODECHECK((iptr->s1.argcount << 1) + 64);
2677
2678                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2679
2680                                 var = VAR(iptr->sx.s23.s2.args[s1]);
2681         
2682                                 /* copy SAVEDVAR sizes to stack */
2683
2684                                 if (!(var->flags & PREALLOC)) {
2685                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
2686                                         M_STR(s2, REG_SP, s1 * 4);
2687                                 }
2688                         }
2689
2690                         /* a0 = dimension count */
2691
2692                         assert(IS_IMM(iptr->s1.argcount));
2693                         M_MOV_IMM(REG_A0, iptr->s1.argcount);
2694
2695                         /* is patcher function set? */
2696
2697                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2698                                 disp = dseg_add_unique_address(cd, NULL);
2699
2700                                 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
2701                                                                         iptr->sx.s23.s3.c.ref, disp);
2702
2703                                 if (opt_showdisassemble)
2704                                         M_NOP;
2705                         }
2706                         else
2707                                 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2708
2709                         /* a1 = arraydescriptor */
2710
2711                         M_DSEG_LOAD(REG_A1, disp);
2712
2713                         /* a2 = pointer to dimensions = stack pointer */
2714
2715                         M_INTMOVE(REG_SP, REG_A2);
2716
2717                         /* call builtin_multianewarray here */
2718
2719                         disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2720                         M_DSEG_BRANCH(disp);
2721
2722                         /* recompute ip (pv) */
2723
2724                         s1 = (s4) (cd->mcodeptr - cd->mcodebase);
2725                         M_RECOMPUTE_IP(s1);
2726
2727                         /* check for exception before result assignment */
2728
2729                         M_TST(REG_RESULT, REG_RESULT);
2730                         M_BEQ(0);
2731                         codegen_add_fillinstacktrace_ref(cd);
2732
2733                         /* get arrayref */
2734
2735                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2736                         M_INTMOVE(REG_RESULT, d);
2737                         emit_store_dst(jd, iptr, d);
2738                         break;
2739
2740                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
2741
2742                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2743                         M_TST(s1, s1);
2744                         M_BEQ(0);
2745                         codegen_add_nullpointerexception_ref(cd);
2746                         break;
2747
2748                 default:
2749                         *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
2750                         return false;
2751                 } /* the big switch */
2752
2753                 } /* for all instructions */
2754
2755         } /* for all basic blocks */
2756
2757         dseg_createlinenumbertable(cd);
2758
2759
2760         /* generate exception and patcher stubs */
2761
2762         emit_exception_stubs(jd);
2763         emit_patcher_stubs(jd);
2764
2765         codegen_finish(jd);
2766
2767         /* everything's ok */
2768
2769         return true;
2770 }
2771
2772
2773 /* createcompilerstub **********************************************************
2774
2775    creates a stub routine which calls the compiler
2776
2777 *******************************************************************************/
2778
2779 #define COMPILERSTUB_DATASIZE    3 * SIZEOF_VOID_P
2780 #define COMPILERSTUB_CODESIZE    2 * 4
2781
2782 #define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
2783
2784
2785 u1 *createcompilerstub(methodinfo *m)
2786 {
2787         u1          *s;                     /* memory to hold the stub            */
2788         ptrint      *d;
2789         codeinfo    *code;
2790         codegendata *cd;
2791         s4           dumpsize;              /* code generation pointer            */
2792
2793         s = CNEW(u1, COMPILERSTUB_SIZE);
2794
2795         /* set data pointer and code pointer */
2796
2797         d = (ptrint *) s;
2798         s = s + COMPILERSTUB_DATASIZE;
2799
2800         /* mark start of dump memory area */
2801
2802         dumpsize = dump_size();
2803
2804         cd = DNEW(codegendata);
2805         cd->mcodeptr = s;
2806
2807         /* Store the codeinfo pointer in the same place as in the
2808            methodheader for compiled methods. */
2809
2810         code = code_codeinfo_new(m);
2811
2812         d[0] = (ptrint) asm_call_jit_compiler;
2813         d[1] = (ptrint) m;
2814         d[2] = (ptrint) code;
2815
2816         /* code for the stub */
2817
2818         M_LDR_INTERN(REG_ITMP1, REG_PC, -(2 * 4 + 2 * SIZEOF_VOID_P));
2819         M_LDR_INTERN(REG_PC, REG_PC, -(3 * 4 + 3 * SIZEOF_VOID_P));
2820
2821 #if defined(ENABLE_STATISTICS)
2822         if (opt_stat)
2823                 count_cstub_len += COMPILERSTUB_SIZE * 4;
2824 #endif
2825
2826         /* release dump area */
2827
2828         dump_release(dumpsize);
2829
2830         /* synchronize instruction and data cache */
2831
2832         md_cacheflush(s, cd->mcodeptr - (u1 *) d);
2833
2834         return s;
2835 }
2836
2837
2838 /* createnativestub ************************************************************
2839
2840    Creates a stub routine which calls a native method.
2841
2842 *******************************************************************************/
2843
2844 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
2845 {
2846         methodinfo   *m;
2847         codeinfo     *code;
2848         codegendata  *cd;
2849         registerdata *rd;
2850         s4            nativeparams;
2851         methoddesc   *md;
2852         s4            i, j;
2853         s4            t;
2854         s4            disp, funcdisp, s1, s2;
2855
2856         /* get required compiler data */
2857
2858         m    = jd->m;
2859         code = jd->code;
2860         cd   = jd->cd;
2861         rd   = jd->rd;
2862
2863         /* initialize variables */
2864
2865         md = m->parseddesc;
2866         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
2867
2868         /* calculate stackframe size */
2869
2870         cd->stackframesize = 
2871                 1 +                                                /* return address  */
2872                 sizeof(stackframeinfo) / SIZEOF_VOID_P +           /* stackframeinfo  */
2873                 sizeof(localref_table) / SIZEOF_VOID_P +           /* localref_table  */
2874                 nmd->memuse;                                       /* stack arguments */
2875
2876         /* create method header */
2877
2878         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
2879         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
2880         (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
2881         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
2882         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
2883         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
2884         (void) dseg_addlinenumbertablesize(cd);
2885         (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
2886
2887         /* generate stub code */
2888         /* TODO: don't forget ... there is a M_ADD_IMM at the end of this stub!!! */
2889         M_STMFD(1<<REG_LR, REG_SP);
2890         if (cd->stackframesize - 1) {
2891                 M_SUB_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize - 1);
2892         }
2893
2894 #if !defined(NDEBUG)
2895         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2896                 emit_verbosecall_enter(jd);
2897 #endif
2898
2899         /* get function address (this must happen before the stackframeinfo) */
2900
2901         funcdisp = dseg_add_functionptr(cd, f);
2902
2903 #if !defined(WITH_STATIC_CLASSPATH)
2904         if (f == NULL) {
2905                 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
2906
2907                 if (opt_showdisassemble)
2908                         M_NOP;
2909         }
2910 #endif
2911
2912         /* save integer and float argument registers */
2913         M_STMFD(BITMASK_ARGS | (1<<REG_IP), REG_SP);
2914         /* TODO: floating point */
2915
2916         /* create native stackframe info */
2917         assert(IS_IMM(20 + cd->stackframesize * 4));
2918         M_ADD_IMM(REG_A0, REG_SP, 20 + cd->stackframesize * 4 - SIZEOF_VOID_P);
2919         M_MOV(REG_A1, REG_IP);
2920         M_ADD_IMM(REG_A2, REG_SP, 20 + cd->stackframesize * 4);
2921         M_LDR_INTERN(REG_A3, REG_SP, 20 + cd->stackframesize * 4 - SIZEOF_VOID_P);
2922         disp = dseg_add_functionptr(cd, codegen_start_native_call);
2923         M_DSEG_BRANCH(disp);
2924
2925         /* recompute ip */
2926         /*s1 = (s4) (cd->mcodeptr - cd->mcodebase);
2927         M_RECOMPUTE_IP(s1);*/
2928
2929         /* restore integer and float argument registers */
2930         M_LDMFD(BITMASK_ARGS | (1<<REG_IP), REG_SP);
2931         /* TODO: floating point */
2932
2933         /* copy or spill arguments to new locations */
2934         /* ATTENTION: the ARM has only integer argument registers! */
2935
2936         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
2937                 t = md->paramtypes[i].type;
2938
2939                 if (!md->params[i].inmemory) {
2940                         s1 = ARGUMENT_REGS(t, md->params[i].regoff);
2941
2942                         if (!nmd->params[j].inmemory) {
2943                                 s2 = ARGUMENT_REGS(t, nmd->params[j].regoff);
2944                                 SPLIT_OPEN(t, s1, REG_ITMP1);
2945                                 SPLIT_LOAD(t, s1, cd->stackframesize);
2946                                 SPLIT_OPEN(t, s2, REG_ITMP1);
2947
2948                                 if (IS_2_WORD_TYPE(t))
2949                                         M_LNGMOVE(s1, s2);
2950                                 else
2951                                         M_INTMOVE(s1, s2);
2952
2953                                 SPLIT_STORE_AND_CLOSE(t, s2, 0);
2954                         }
2955                         else {
2956                                 s2 = nmd->params[j].regoff;
2957                                 SPLIT_OPEN(t, s1, REG_ITMP1);
2958                                 SPLIT_LOAD(t, s1, cd->stackframesize);
2959
2960                                 if (IS_2_WORD_TYPE(t))
2961                                         M_LST(s1, REG_SP, s2 * 4);
2962                                 else
2963                                         M_IST(s1, REG_SP, s2 * 4);
2964                                 /* no SPLIT_CLOSE here because argument is fully on stack now */
2965                         }
2966                 }
2967                 else {
2968                         s1 = md->params[i].regoff + cd->stackframesize;
2969                         s2 = nmd->params[j].regoff;
2970
2971                         if (IS_2_WORD_TYPE(t)) {
2972                                 M_LLD(REG_ITMP12_PACKED, REG_SP, s1 * 4);
2973                                 M_LST(REG_ITMP12_PACKED, REG_SP, s2 * 4);
2974                         }
2975                         else {
2976                                 M_ILD(REG_ITMP1, REG_SP, s1 * 4);
2977                                 M_IST(REG_ITMP1, REG_SP, s2 * 4);
2978                         }
2979                 }
2980         }
2981
2982         /* put class into second argument register */
2983         if (m->flags & ACC_STATIC) {
2984                 disp = dseg_add_address(cd, m->class);
2985                 M_DSEG_LOAD(REG_A1, disp);
2986         }
2987
2988         /* put env into first argument register */
2989         disp = dseg_add_address(cd, _Jv_env);
2990         M_DSEG_LOAD(REG_A0, disp);
2991
2992         /* do the native function call */
2993         M_DSEG_BRANCH(funcdisp);            /* call native method                 */
2994
2995         /* recompute ip from pc */
2996         /* TODO: this is only needed because of the tracer ... do we
2997            really need it? */
2998         s1 = (s4) (cd->mcodeptr - cd->mcodebase);
2999         M_RECOMPUTE_IP(s1);
3000
3001 #if !defined(__SOFTFP__)
3002         /* TODO: this is only a hack, since we use R0/R1 for float return! */
3003         /* this depends on gcc; it is independent from our ENABLE_SOFTFLOAT define */
3004         if (md->returntype.type != TYPE_VOID && IS_FLT_DBL_TYPE(md->returntype.type)) {
3005 #if 0 && !defined(NDEBUG)
3006                 dolog("NATIVESTUB that returns float or double (%s.%s)", m->class->name->text, m->name->text);
3007 #endif
3008                 /* we cannot use this macro, since it is not defined in ENABLE_SOFTFLOAT */
3009                 /* M_CAST_FLT_TO_INT_TYPED(md->returntype.type, REG_FRESULT, REG_RESULT_TYPED(md->returntype.type)); */
3010                 if (IS_2_WORD_TYPE(md->returntype.type)) {
3011                         DCD(0xed2d8102); /* stfd    f0, [sp, #-8]! */
3012                         M_LDRD_UPDATE(REG_RESULT_PACKED, REG_SP, 8);
3013                 } else {
3014                         DCD(0xed2d0101); /* stfs    f0, [sp, #-4]!*/
3015                         M_LDR_UPDATE(REG_RESULT, REG_SP, 4);
3016                 }
3017         }
3018 #endif
3019
3020 #if !defined(NDEBUG)
3021         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3022                 emit_verbosecall_exit(jd);
3023 #endif
3024
3025         /* remove native stackframe info */
3026         /* TODO: improve this store/load */
3027
3028         M_STMFD(BITMASK_RESULT | (1<<REG_IP), REG_SP);
3029         M_ADD_IMM(REG_A0, REG_SP, 12 + cd->stackframesize * 4 - SIZEOF_VOID_P);
3030         disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3031         M_DSEG_BRANCH(disp);
3032         M_MOV(REG_ITMP1_XPTR, REG_RESULT);
3033         M_LDMFD(BITMASK_RESULT | (1<<REG_IP), REG_SP);
3034
3035         /* finish stub code, but do not yet return to caller */
3036
3037         if (cd->stackframesize - 1)
3038                 M_ADD_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize - 1);
3039
3040         M_LDMFD(1<<REG_LR, REG_SP);
3041
3042         /* check for exception */
3043
3044         M_TST(REG_ITMP1_XPTR, REG_ITMP1_XPTR);
3045         M_MOVEQ(REG_PC, REG_LR);            /* if no exception, return to caller  */
3046
3047         /* handle exception here */
3048
3049         M_SUB_IMM(REG_ITMP2_XPC, REG_LR, 4);/* move fault address into xpc        */
3050
3051         disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3052         M_DSEG_LOAD(REG_ITMP3, disp);       /* load asm exception handler address */
3053         M_MOV(REG_PC, REG_ITMP3);           /* jump to asm exception handler      */
3054
3055         /* generate patcher stubs */
3056
3057         emit_patcher_stubs(jd);
3058
3059         codegen_finish(jd);
3060
3061         return code->entrypoint;
3062 }
3063
3064
3065 /* asm_debug *******************************************************************
3066
3067    Lazy debugger!
3068
3069 *******************************************************************************/
3070
3071 void asm_debug(int a1, int a2, int a3, int a4)
3072 {
3073         printf("===> i am going to exit after this debugging message!\n");
3074         printf("got asm_debug(%p, %p, %p, %p)\n",(void*)a1,(void*)a2,(void*)a3,(void*)a4);
3075         throw_cacao_exception_exit(string_java_lang_InternalError, "leave you now");
3076 }
3077
3078
3079 /*
3080  * These are local overrides for various environment variables in Emacs.
3081  * Please do not remove this and leave it at the end of the file, where
3082  * Emacs will automagically detect them.
3083  * ---------------------------------------------------------------------
3084  * Local variables:
3085  * mode: c
3086  * indent-tabs-mode: t
3087  * c-basic-offset: 4
3088  * tab-width: 4
3089  * End:
3090  * vim:noexpandtab:sw=4:ts=4:
3091  */