1 /* src/vm/jit/alpha/codegen.c - machine code generator for Alpha
3 Copyright (C) 1996-2005, 2006, 2007, 2008, 2009
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
36 #include "vm/jit/alpha/arch.h"
37 #include "vm/jit/alpha/codegen.h"
39 #include "mm/memory.hpp"
41 #include "native/localref.hpp"
42 #include "native/native.hpp"
44 #include "threads/lock.hpp"
46 #include "vm/jit/builtin.hpp"
47 #include "vm/exceptions.hpp"
48 #include "vm/global.h"
49 #include "vm/loader.hpp"
50 #include "vm/options.h"
53 #include "vm/jit/abi.h"
54 #include "vm/jit/asmpart.h"
55 #include "vm/jit/codegen-common.hpp"
56 #include "vm/jit/dseg.h"
57 #include "vm/jit/emit-common.hpp"
58 #include "vm/jit/jit.hpp"
59 #include "vm/jit/linenumbertable.hpp"
60 #include "vm/jit/parse.hpp"
61 #include "vm/jit/patcher-common.hpp"
62 #include "vm/jit/reg.h"
63 #include "vm/jit/stacktrace.hpp"
64 #include "vm/jit/trap.hpp"
68 * Generates machine code for the method prolog.
70 void codegen_emit_prolog(jitdata* jd)
79 // Get required compiler data.
80 methodinfo* m = jd->m;
81 codeinfo* code = jd->code;
82 codegendata* cd = jd->cd;
83 registerdata* rd = jd->rd;
85 /* create stack frame (if necessary) */
87 if (cd->stackframesize)
88 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
90 /* save return address and used callee saved registers */
92 p = cd->stackframesize;
93 if (!code_is_leafmethod(code)) {
94 p--; M_AST(REG_RA, REG_SP, p * 8);
96 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
97 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
99 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
100 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
103 /* take arguments out of register or stack frame */
107 for (p = 0, l = 0; p < md->paramcount; p++) {
108 t = md->paramtypes[p].type;
110 varindex = jd->local_map[l * 5 + t];
113 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
116 if (varindex == UNUSED)
121 s1 = md->params[p].regoff;
123 if (IS_INT_LNG_TYPE(t)) { /* integer args */
124 if (!md->params[p].inmemory) { /* register arguments */
125 if (!IS_INMEMORY(var->flags))
126 M_INTMOVE(s1, var->vv.regoff);
128 M_LST(s1, REG_SP, var->vv.regoff);
130 else { /* stack arguments */
131 if (!IS_INMEMORY(var->flags))
132 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
134 var->vv.regoff = cd->stackframesize * 8 + s1;
137 else { /* floating args */
138 if (!md->params[p].inmemory) { /* register arguments */
139 if (!IS_INMEMORY(var->flags))
140 emit_fmove(cd, s1, var->vv.regoff);
142 M_DST(s1, REG_SP, var->vv.regoff);
144 else { /* stack arguments */
145 if (!(var->flags & INMEMORY))
146 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
148 var->vv.regoff = cd->stackframesize * 8 + s1;
156 * Generates machine code for the method epilog.
158 void codegen_emit_epilog(jitdata* jd)
163 // Get required compiler data.
164 codeinfo* code = jd->code;
165 codegendata* cd = jd->cd;
166 registerdata* rd = jd->rd;
168 p = cd->stackframesize;
170 /* restore return address */
172 if (!code_is_leafmethod(code)) {
173 p--; M_LLD(REG_RA, REG_SP, p * 8);
176 /* restore saved registers */
178 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
179 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
181 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
182 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
185 /* deallocate stack */
187 if (cd->stackframesize)
188 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
190 M_RET(REG_ZERO, REG_RA);
195 * Generates machine code for one ICMD.
197 void codegen_emit_instruction(jitdata* jd, instruction* iptr)
200 builtintable_entry* bte;
201 methodinfo* lm; // Local methodinfo for ICMD_INVOKE*.
202 unresolved_method* um;
204 unresolved_field* uf;
206 int32_t s1, s2, s3, d;
209 // Get required compiler data.
210 codegendata* cd = jd->cd;
214 /* constant operations ************************************************/
216 case ICMD_FCONST: /* ... ==> ..., constant */
218 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
219 disp = dseg_add_float(cd, iptr->sx.val.f);
220 M_FLD(d, REG_PV, disp);
221 emit_store_dst(jd, iptr, d);
224 case ICMD_DCONST: /* ... ==> ..., constant */
226 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
227 disp = dseg_add_double(cd, iptr->sx.val.d);
228 M_DLD(d, REG_PV, disp);
229 emit_store_dst(jd, iptr, d);
232 case ICMD_ACONST: /* ... ==> ..., constant */
234 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
236 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
237 constant_classref *cr = iptr->sx.val.c.ref;
239 disp = dseg_add_unique_address(cd, cr);
241 /* XXX Only add the patcher, if this position needs to
242 be patched. If there was a previous position which
243 resolved the same class, the returned displacement
244 of dseg_add_address is ok to use. */
246 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
249 M_ALD(d, REG_PV, disp);
252 if (iptr->sx.val.anyptr == NULL)
253 M_INTMOVE(REG_ZERO, d);
255 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
256 M_ALD(d, REG_PV, disp);
259 emit_store_dst(jd, iptr, d);
263 /* integer operations *************************************************/
265 case ICMD_INEG: /* ..., value ==> ..., - value */
267 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
268 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
269 M_ISUB(REG_ZERO, s1, d);
270 emit_store_dst(jd, iptr, d);
273 case ICMD_LNEG: /* ..., value ==> ..., - value */
275 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
276 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
277 M_LSUB(REG_ZERO, s1, d);
278 emit_store_dst(jd, iptr, d);
281 case ICMD_I2L: /* ..., value ==> ..., value */
283 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
284 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
286 emit_store_dst(jd, iptr, d);
289 case ICMD_L2I: /* ..., value ==> ..., value */
291 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
292 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
293 M_IADD(s1, REG_ZERO, d);
294 emit_store_dst(jd, iptr, d);
297 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
299 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
300 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
301 if (has_ext_instr_set) {
304 M_SLL_IMM(s1, 56, d);
305 M_SRA_IMM( d, 56, d);
307 emit_store_dst(jd, iptr, d);
310 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
312 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
313 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
315 emit_store_dst(jd, iptr, d);
318 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
320 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
321 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
322 if (has_ext_instr_set) {
325 M_SLL_IMM(s1, 48, d);
326 M_SRA_IMM( d, 48, d);
328 emit_store_dst(jd, iptr, d);
332 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
334 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
335 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
336 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
338 emit_store_dst(jd, iptr, d);
342 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
343 /* sx.val.i = constant */
345 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
346 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
347 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
348 M_IADD_IMM(s1, iptr->sx.val.i, d);
349 } else if ((iptr->sx.val.i > -256) && (iptr->sx.val.i < 0)) {
350 M_ISUB_IMM(s1, (-iptr->sx.val.i), d);
352 /* XXX maybe use M_LDA? */
353 ICONST(REG_ITMP2, iptr->sx.val.i);
354 M_IADD(s1, REG_ITMP2, d);
356 emit_store_dst(jd, iptr, d);
359 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
361 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
362 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
363 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
365 emit_store_dst(jd, iptr, d);
368 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
369 /* sx.val.l = constant */
371 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
372 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
373 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
374 M_LADD_IMM(s1, iptr->sx.val.l, d);
376 LCONST(REG_ITMP2, iptr->sx.val.l);
377 M_LADD(s1, REG_ITMP2, d);
379 emit_store_dst(jd, iptr, d);
382 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
384 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
385 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
386 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
388 emit_store_dst(jd, iptr, d);
391 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
392 /* sx.val.i = constant */
394 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
395 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
396 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
397 M_ISUB_IMM(s1, iptr->sx.val.i, d);
399 ICONST(REG_ITMP2, iptr->sx.val.i);
400 M_ISUB(s1, REG_ITMP2, d);
402 emit_store_dst(jd, iptr, d);
405 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
407 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
408 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
409 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
411 emit_store_dst(jd, iptr, d);
414 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
415 /* sx.val.l = constant */
417 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
418 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
419 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
420 M_LSUB_IMM(s1, iptr->sx.val.l, d);
422 LCONST(REG_ITMP2, iptr->sx.val.l);
423 M_LSUB(s1, REG_ITMP2, d);
425 emit_store_dst(jd, iptr, d);
428 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
430 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
431 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
432 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
434 emit_store_dst(jd, iptr, d);
437 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
438 /* sx.val.i = constant */
440 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
441 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
442 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
443 M_IMUL_IMM(s1, iptr->sx.val.i, d);
445 ICONST(REG_ITMP2, iptr->sx.val.i);
446 M_IMUL(s1, REG_ITMP2, d);
448 emit_store_dst(jd, iptr, d);
451 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
453 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
454 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
455 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
457 emit_store_dst(jd, iptr, d);
460 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
461 /* sx.val.l = constant */
463 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
464 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
465 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
466 M_LMUL_IMM(s1, iptr->sx.val.l, d);
468 LCONST(REG_ITMP2, iptr->sx.val.l);
469 M_LMUL(s1, REG_ITMP2, d);
471 emit_store_dst(jd, iptr, d);
474 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
475 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
477 s1 = emit_load_s1(jd, iptr, REG_A0);
478 s2 = emit_load_s2(jd, iptr, REG_A1);
479 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
480 emit_arithmetic_check(cd, iptr, s2);
482 M_INTMOVE(s1, REG_A0);
483 M_INTMOVE(s2, REG_A1);
484 bte = iptr->sx.s23.s3.bte;
485 disp = dseg_add_functionptr(cd, bte->fp);
486 M_ALD(REG_PV, REG_PV, disp);
487 M_JSR(REG_RA, REG_PV);
488 disp = (s4) (cd->mcodeptr - cd->mcodebase);
489 M_LDA(REG_PV, REG_RA, -disp);
491 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
492 emit_store_dst(jd, iptr, d);
495 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
496 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
498 s1 = emit_load_s1(jd, iptr, REG_A0);
499 s2 = emit_load_s2(jd, iptr, REG_A1);
500 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
501 emit_arithmetic_check(cd, iptr, s2);
503 M_INTMOVE(s1, REG_A0);
504 M_INTMOVE(s2, REG_A1);
505 bte = iptr->sx.s23.s3.bte;
506 disp = dseg_add_functionptr(cd, bte->fp);
507 M_ALD(REG_PV, REG_PV, disp);
508 M_JSR(REG_RA, REG_PV);
509 disp = (s4) (cd->mcodeptr - cd->mcodebase);
510 M_LDA(REG_PV, REG_RA, -disp);
512 M_INTMOVE(REG_RESULT, d);
513 emit_store_dst(jd, iptr, d);
516 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
517 case ICMD_LDIVPOW2: /* val.i = constant */
519 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
520 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
521 if (iptr->sx.val.i <= 15) {
522 M_LDA(REG_ITMP2, s1, (1 << iptr->sx.val.i) -1);
523 M_CMOVGE(s1, s1, REG_ITMP2);
525 M_SRA_IMM(s1, 63, REG_ITMP2);
526 M_SRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
527 M_LADD(s1, REG_ITMP2, REG_ITMP2);
529 M_SRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
530 emit_store_dst(jd, iptr, d);
533 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
535 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
536 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
537 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
538 M_AND_IMM(s2, 0x1f, REG_ITMP3);
539 M_SLL(s1, REG_ITMP3, d);
540 M_IADD(d, REG_ZERO, d);
541 emit_store_dst(jd, iptr, d);
544 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
545 /* sx.val.i = constant */
547 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
548 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
549 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
550 M_IADD(d, REG_ZERO, d);
551 emit_store_dst(jd, iptr, d);
554 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
556 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
557 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
558 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
559 M_AND_IMM(s2, 0x1f, REG_ITMP3);
560 M_SRA(s1, REG_ITMP3, d);
561 emit_store_dst(jd, iptr, d);
564 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
565 /* sx.val.i = constant */
567 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
568 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
569 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
570 emit_store_dst(jd, iptr, d);
573 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
575 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
576 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
577 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
578 M_AND_IMM(s2, 0x1f, REG_ITMP3);
580 M_SRL(d, REG_ITMP3, d);
581 M_IADD(d, REG_ZERO, d);
582 emit_store_dst(jd, iptr, d);
585 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
586 /* sx.val.i = constant */
588 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
589 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
591 M_SRL_IMM(d, iptr->sx.val.i & 0x1f, d);
592 M_IADD(d, REG_ZERO, d);
593 emit_store_dst(jd, iptr, d);
596 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
598 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
599 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
600 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
602 emit_store_dst(jd, iptr, d);
605 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
606 /* sx.val.i = constant */
608 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
609 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
610 M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
611 emit_store_dst(jd, iptr, d);
614 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
616 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
617 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
618 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
620 emit_store_dst(jd, iptr, d);
623 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
624 /* sx.val.i = constant */
626 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
627 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
628 M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
629 emit_store_dst(jd, iptr, d);
632 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
634 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
635 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
636 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
638 emit_store_dst(jd, iptr, d);
641 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
642 /* sx.val.i = constant */
644 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
645 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
646 M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
647 emit_store_dst(jd, iptr, d);
650 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
653 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
654 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
655 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
657 emit_store_dst(jd, iptr, d);
660 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
661 /* sx.val.i = constant */
663 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
664 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
665 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
666 M_AND_IMM(s1, iptr->sx.val.i, d);
667 } else if (iptr->sx.val.i == 0xffff) {
669 } else if (iptr->sx.val.i == 0xffffff) {
670 M_ZAPNOT_IMM(s1, 0x07, d);
672 ICONST(REG_ITMP2, iptr->sx.val.i);
673 M_AND(s1, REG_ITMP2, d);
675 emit_store_dst(jd, iptr, d);
678 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
679 /* sx.val.i = constant */
681 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
682 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
684 M_MOV(s1, REG_ITMP1);
687 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
688 M_AND_IMM(s1, iptr->sx.val.i, d);
690 M_ISUB(REG_ZERO, s1, d);
691 M_AND_IMM(d, iptr->sx.val.i, d);
692 } else if (iptr->sx.val.i == 0xffff) {
695 M_ISUB(REG_ZERO, s1, d);
697 } else if (iptr->sx.val.i == 0xffffff) {
698 M_ZAPNOT_IMM(s1, 0x07, d);
700 M_ISUB(REG_ZERO, s1, d);
701 M_ZAPNOT_IMM(d, 0x07, d);
703 ICONST(REG_ITMP3, iptr->sx.val.i);
704 M_AND(s1, REG_ITMP3, d);
706 M_ISUB(REG_ZERO, s1, d);
707 M_AND(d, REG_ITMP3, d);
709 M_ISUB(REG_ZERO, d, d);
710 emit_store_dst(jd, iptr, d);
713 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
714 /* sx.val.l = constant */
716 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
717 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
718 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
719 M_AND_IMM(s1, iptr->sx.val.l, d);
720 } else if (iptr->sx.val.l == 0xffffL) {
722 } else if (iptr->sx.val.l == 0xffffffL) {
723 M_ZAPNOT_IMM(s1, 0x07, d);
724 } else if (iptr->sx.val.l == 0xffffffffL) {
726 } else if (iptr->sx.val.l == 0xffffffffffL) {
727 M_ZAPNOT_IMM(s1, 0x1f, d);
728 } else if (iptr->sx.val.l == 0xffffffffffffL) {
729 M_ZAPNOT_IMM(s1, 0x3f, d);
730 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
731 M_ZAPNOT_IMM(s1, 0x7f, d);
733 LCONST(REG_ITMP2, iptr->sx.val.l);
734 M_AND(s1, REG_ITMP2, d);
736 emit_store_dst(jd, iptr, d);
739 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
740 /* sx.val.l = constant */
742 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
743 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
745 M_MOV(s1, REG_ITMP1);
748 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
749 M_AND_IMM(s1, iptr->sx.val.l, d);
751 M_LSUB(REG_ZERO, s1, d);
752 M_AND_IMM(d, iptr->sx.val.l, d);
753 } else if (iptr->sx.val.l == 0xffffL) {
756 M_LSUB(REG_ZERO, s1, d);
758 } else if (iptr->sx.val.l == 0xffffffL) {
759 M_ZAPNOT_IMM(s1, 0x07, d);
761 M_LSUB(REG_ZERO, s1, d);
762 M_ZAPNOT_IMM(d, 0x07, d);
763 } else if (iptr->sx.val.l == 0xffffffffL) {
766 M_LSUB(REG_ZERO, s1, d);
768 } else if (iptr->sx.val.l == 0xffffffffffL) {
769 M_ZAPNOT_IMM(s1, 0x1f, d);
771 M_LSUB(REG_ZERO, s1, d);
772 M_ZAPNOT_IMM(d, 0x1f, d);
773 } else if (iptr->sx.val.l == 0xffffffffffffL) {
774 M_ZAPNOT_IMM(s1, 0x3f, d);
776 M_LSUB(REG_ZERO, s1, d);
777 M_ZAPNOT_IMM(d, 0x3f, d);
778 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
779 M_ZAPNOT_IMM(s1, 0x7f, d);
781 M_LSUB(REG_ZERO, s1, d);
782 M_ZAPNOT_IMM(d, 0x7f, d);
784 LCONST(REG_ITMP3, iptr->sx.val.l);
785 M_AND(s1, REG_ITMP3, d);
787 M_LSUB(REG_ZERO, s1, d);
788 M_AND(d, REG_ITMP3, d);
790 M_LSUB(REG_ZERO, d, d);
791 emit_store_dst(jd, iptr, d);
794 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
797 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
798 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
799 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
801 emit_store_dst(jd, iptr, d);
804 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
805 /* sx.val.i = constant */
807 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
808 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
809 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
810 M_OR_IMM(s1, iptr->sx.val.i, d);
812 ICONST(REG_ITMP2, iptr->sx.val.i);
813 M_OR(s1, REG_ITMP2, d);
815 emit_store_dst(jd, iptr, d);
818 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
819 /* sx.val.l = constant */
821 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
822 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
823 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
824 M_OR_IMM(s1, iptr->sx.val.l, d);
826 LCONST(REG_ITMP2, iptr->sx.val.l);
827 M_OR(s1, REG_ITMP2, d);
829 emit_store_dst(jd, iptr, d);
832 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
835 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
836 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
837 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
839 emit_store_dst(jd, iptr, d);
842 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
843 /* sx.val.i = constant */
845 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
846 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
847 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
848 M_XOR_IMM(s1, iptr->sx.val.i, d);
850 ICONST(REG_ITMP2, iptr->sx.val.i);
851 M_XOR(s1, REG_ITMP2, d);
853 emit_store_dst(jd, iptr, d);
856 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
857 /* sx.val.l = constant */
859 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
860 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
861 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
862 M_XOR_IMM(s1, iptr->sx.val.l, d);
864 LCONST(REG_ITMP2, iptr->sx.val.l);
865 M_XOR(s1, REG_ITMP2, d);
867 emit_store_dst(jd, iptr, d);
871 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
873 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
874 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
875 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
876 M_CMPLT(s1, s2, REG_ITMP3);
877 M_CMPLT(s2, s1, REG_ITMP1);
878 M_LSUB(REG_ITMP1, REG_ITMP3, d);
879 emit_store_dst(jd, iptr, d);
883 /* floating operations ************************************************/
885 case ICMD_FNEG: /* ..., value ==> ..., - value */
887 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
888 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
890 emit_store_dst(jd, iptr, d);
893 case ICMD_DNEG: /* ..., value ==> ..., - value */
895 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
896 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
898 emit_store_dst(jd, iptr, d);
901 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
903 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
904 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
905 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
906 if (d == s1 || d == s2) {
907 M_FADDS(s1, s2, REG_FTMP3);
909 M_FMOV(REG_FTMP3, d);
914 emit_store_dst(jd, iptr, d);
917 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
919 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
920 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
921 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
922 if (d == s1 || d == s2) {
923 M_DADDS(s1, s2, REG_FTMP3);
925 M_FMOV(REG_FTMP3, d);
930 emit_store_dst(jd, iptr, d);
933 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
935 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
936 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
937 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
938 if (d == s1 || d == s2) {
939 M_FSUBS(s1, s2, REG_FTMP3);
941 M_FMOV(REG_FTMP3, d);
946 emit_store_dst(jd, iptr, d);
949 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
951 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
952 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
953 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
954 if (d == s1 || d == s2) {
955 M_DSUBS(s1, s2, REG_FTMP3);
957 M_FMOV(REG_FTMP3, d);
962 emit_store_dst(jd, iptr, d);
965 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
967 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
968 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
969 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
970 if (d == s1 || d == s2) {
971 M_FMULS(s1, s2, REG_FTMP3);
973 M_FMOV(REG_FTMP3, d);
978 emit_store_dst(jd, iptr, d);
981 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
983 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
984 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
985 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
986 if (d == s1 || d == s2) {
987 M_DMULS(s1, s2, REG_FTMP3);
989 M_FMOV(REG_FTMP3, d);
994 emit_store_dst(jd, iptr, d);
997 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
999 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1000 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1001 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1002 if (d == s1 || d == s2) {
1003 M_FDIVS(s1, s2, REG_FTMP3);
1005 M_FMOV(REG_FTMP3, d);
1010 emit_store_dst(jd, iptr, d);
1013 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1015 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1016 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1017 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1018 if (d == s1 || d == s2) {
1019 M_DDIVS(s1, s2, REG_FTMP3);
1021 M_FMOV(REG_FTMP3, d);
1026 emit_store_dst(jd, iptr, d);
1029 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1031 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1032 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1033 disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1034 M_LST(s1, REG_PV, disp);
1035 M_DLD(d, REG_PV, disp);
1037 emit_store_dst(jd, iptr, d);
1040 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1042 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1043 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1044 disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1045 M_LST(s1, REG_PV, disp);
1046 M_DLD(d, REG_PV, disp);
1048 emit_store_dst(jd, iptr, d);
1051 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1053 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1054 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1055 disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1056 M_CVTDL_C(s1, REG_FTMP2);
1057 M_CVTLI(REG_FTMP2, REG_FTMP3);
1058 M_DST(REG_FTMP3, REG_PV, disp);
1059 M_ILD(d, REG_PV, disp);
1060 emit_store_dst(jd, iptr, d);
1063 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1065 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1066 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1067 disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1068 M_CVTDL_C(s1, REG_FTMP2);
1069 M_DST(REG_FTMP2, REG_PV, disp);
1070 M_LLD(d, REG_PV, disp);
1071 emit_store_dst(jd, iptr, d);
1074 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1076 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1077 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1080 emit_store_dst(jd, iptr, d);
1083 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1085 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1086 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1089 emit_store_dst(jd, iptr, d);
1092 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1094 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1095 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1096 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1097 M_LSUB_IMM(REG_ZERO, 1, d);
1098 M_FCMPEQS(s1, s2, REG_FTMP3);
1100 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1102 M_FCMPLTS(s2, s1, REG_FTMP3);
1104 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1105 M_LADD_IMM(REG_ZERO, 1, d);
1106 emit_store_dst(jd, iptr, d);
1109 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1111 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1112 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1113 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1114 M_LADD_IMM(REG_ZERO, 1, d);
1115 M_FCMPEQS(s1, s2, REG_FTMP3);
1117 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1119 M_FCMPLTS(s1, s2, REG_FTMP3);
1121 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1122 M_LSUB_IMM(REG_ZERO, 1, d);
1123 emit_store_dst(jd, iptr, d);
1127 /* memory operations **************************************************/
1129 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1131 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1132 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1133 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1134 /* implicit null-pointer check */
1135 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1136 if (has_ext_instr_set) {
1137 M_LADD(s2, s1, REG_ITMP1);
1138 M_BLDU(d, REG_ITMP1, OFFSET (java_bytearray_t, data[0]));
1142 M_LADD(s2, s1, REG_ITMP1);
1143 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1144 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0])+1);
1145 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1146 M_SRA_IMM(d, 56, d);
1148 emit_store_dst(jd, iptr, d);
1151 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1153 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1154 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1155 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1156 /* implicit null-pointer check */
1157 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1158 if (has_ext_instr_set) {
1159 M_LADD(s2, s1, REG_ITMP1);
1160 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1161 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1164 M_LADD (s2, s1, REG_ITMP1);
1165 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1166 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1167 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1168 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1170 emit_store_dst(jd, iptr, d);
1173 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1175 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1176 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1177 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1178 /* implicit null-pointer check */
1179 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1180 if (has_ext_instr_set) {
1181 M_LADD(s2, s1, REG_ITMP1);
1182 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1183 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray_t, data[0]));
1186 M_LADD(s2, s1, REG_ITMP1);
1187 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1188 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1189 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0])+2);
1190 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1191 M_SRA_IMM(d, 48, d);
1193 emit_store_dst(jd, iptr, d);
1196 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1198 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1199 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1200 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1201 /* implicit null-pointer check */
1202 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1203 M_S4ADDQ(s2, s1, REG_ITMP1);
1204 M_ILD(d, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1205 emit_store_dst(jd, iptr, d);
1208 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1210 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1211 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1212 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1213 /* implicit null-pointer check */
1214 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1215 M_S8ADDQ(s2, s1, REG_ITMP1);
1216 M_LLD(d, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1217 emit_store_dst(jd, iptr, d);
1220 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1222 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1223 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1224 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1225 /* implicit null-pointer check */
1226 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1227 M_S4ADDQ(s2, s1, REG_ITMP1);
1228 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1229 emit_store_dst(jd, iptr, d);
1232 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1234 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1235 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1236 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1237 /* implicit null-pointer check */
1238 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1239 M_S8ADDQ(s2, s1, REG_ITMP1);
1240 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1241 emit_store_dst(jd, iptr, d);
1244 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1246 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1247 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1248 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1249 /* implicit null-pointer check */
1250 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1251 M_SAADDQ(s2, s1, REG_ITMP1);
1252 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1253 emit_store_dst(jd, iptr, d);
1257 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1259 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1260 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1261 /* implicit null-pointer check */
1262 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1263 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1264 if (has_ext_instr_set) {
1265 M_LADD(s2, s1, REG_ITMP1);
1266 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1269 M_LADD(s2, s1, REG_ITMP1);
1270 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1271 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1272 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1273 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1274 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1275 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1279 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1281 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1282 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1283 /* implicit null-pointer check */
1284 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1285 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1286 if (has_ext_instr_set) {
1287 M_LADD(s2, s1, REG_ITMP1);
1288 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1289 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1292 M_LADD(s2, s1, REG_ITMP1);
1293 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1294 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1295 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1296 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1297 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1298 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1299 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1303 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1305 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1306 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1307 /* implicit null-pointer check */
1308 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1309 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1310 if (has_ext_instr_set) {
1311 M_LADD(s2, s1, REG_ITMP1);
1312 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1313 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1316 M_LADD(s2, s1, REG_ITMP1);
1317 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1318 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1319 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1320 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1321 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1322 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1323 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1327 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1329 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1330 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1331 /* implicit null-pointer check */
1332 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1333 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1334 M_S4ADDQ(s2, s1, REG_ITMP1);
1335 M_IST(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1338 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1340 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1341 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1342 /* implicit null-pointer check */
1343 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1344 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1345 M_S8ADDQ(s2, s1, REG_ITMP1);
1346 M_LST(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1349 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1351 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1352 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1353 /* implicit null-pointer check */
1354 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1355 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1356 M_S4ADDQ(s2, s1, REG_ITMP1);
1357 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1360 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1362 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1363 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1364 /* implicit null-pointer check */
1365 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1366 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1367 M_S8ADDQ(s2, s1, REG_ITMP1);
1368 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1371 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1373 s1 = emit_load_s1(jd, iptr, REG_A0);
1374 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1375 /* implicit null-pointer check */
1376 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1377 s3 = emit_load_s3(jd, iptr, REG_A1);
1379 M_INTMOVE(s1, REG_A0);
1380 M_INTMOVE(s3, REG_A1);
1382 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1383 M_ALD(REG_PV, REG_PV, disp);
1384 M_JSR(REG_RA, REG_PV);
1385 disp = (s4) (cd->mcodeptr - cd->mcodebase);
1386 M_LDA(REG_PV, REG_RA, -disp);
1387 emit_arraystore_check(cd, iptr);
1389 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1390 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1391 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1392 M_SAADDQ(s2, s1, REG_ITMP1);
1393 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1397 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1399 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1400 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1401 /* implicit null-pointer check */
1402 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1403 if (has_ext_instr_set) {
1404 M_LADD(s2, s1, REG_ITMP1);
1405 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1408 M_LADD(s2, s1, REG_ITMP1);
1409 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1410 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1411 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1412 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1413 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1414 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1418 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1420 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1421 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1422 /* implicit null-pointer check */
1423 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1424 if (has_ext_instr_set) {
1425 M_LADD(s2, s1, REG_ITMP1);
1426 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1427 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1430 M_LADD(s2, s1, REG_ITMP1);
1431 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1432 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1433 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1434 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1435 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1436 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1437 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1441 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1443 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1444 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1445 /* implicit null-pointer check */
1446 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1447 if (has_ext_instr_set) {
1448 M_LADD(s2, s1, REG_ITMP1);
1449 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1450 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1453 M_LADD(s2, s1, REG_ITMP1);
1454 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1455 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1456 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1457 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1458 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1459 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1460 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1464 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1466 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1467 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1468 /* implicit null-pointer check */
1469 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1470 M_S4ADDQ(s2, s1, REG_ITMP1);
1471 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1474 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1476 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1477 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1478 /* implicit null-pointer check */
1479 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1480 M_S8ADDQ(s2, s1, REG_ITMP1);
1481 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1484 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1486 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1487 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1488 /* implicit null-pointer check */
1489 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1490 M_SAADDQ(s2, s1, REG_ITMP1);
1491 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1494 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1495 /* val = value (in current instruction) */
1496 /* following NOP) */
1498 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1499 uf = iptr->sx.s23.s3.uf;
1500 fieldtype = uf->fieldref->parseddesc.fd->type;
1501 disp = dseg_add_unique_address(cd, uf);
1503 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1506 fi = iptr->sx.s23.s3.fmiref->p.field;
1507 fieldtype = fi->type;
1508 disp = dseg_add_address(cd, fi->value);
1510 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1511 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
1515 M_ALD(REG_ITMP1, REG_PV, disp);
1516 switch (fieldtype) {
1518 M_IST(REG_ZERO, REG_ITMP1, 0);
1521 M_LST(REG_ZERO, REG_ITMP1, 0);
1524 M_AST(REG_ZERO, REG_ITMP1, 0);
1527 M_FST(REG_ZERO, REG_ITMP1, 0);
1530 M_DST(REG_ZERO, REG_ITMP1, 0);
1536 case ICMD_GETFIELD: /* ... ==> ..., value */
1538 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1540 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1541 uf = iptr->sx.s23.s3.uf;
1542 fieldtype = uf->fieldref->parseddesc.fd->type;
1545 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1548 fi = iptr->sx.s23.s3.fmiref->p.field;
1549 fieldtype = fi->type;
1553 /* implicit null-pointer check */
1554 switch (fieldtype) {
1556 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1560 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1564 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1568 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1572 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1576 emit_store_dst(jd, iptr, d);
1579 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1581 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1583 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1584 uf = iptr->sx.s23.s3.uf;
1585 fieldtype = uf->fieldref->parseddesc.fd->type;
1590 fi = iptr->sx.s23.s3.fmiref->p.field;
1591 fieldtype = fi->type;
1595 if (IS_INT_LNG_TYPE(fieldtype))
1596 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1598 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1600 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1601 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1603 /* implicit null-pointer check */
1604 switch (fieldtype) {
1606 M_IST(s2, s1, disp);
1609 M_LST(s2, s1, disp);
1612 M_AST(s2, s1, disp);
1615 M_FST(s2, s1, disp);
1618 M_DST(s2, s1, disp);
1623 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1624 /* val = value (in current instruction) */
1625 /* following NOP) */
1627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1629 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1630 uf = iptr->sx.s23.s3.uf;
1631 fieldtype = uf->fieldref->parseddesc.fd->type;
1634 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1637 fi = iptr->sx.s23.s3.fmiref->p.field;
1638 fieldtype = fi->type;
1642 /* implicit null-pointer check */
1643 switch (fieldtype) {
1645 M_IST(REG_ZERO, s1, disp);
1648 M_LST(REG_ZERO, s1, disp);
1651 M_AST(REG_ZERO, s1, disp);
1654 M_FST(REG_ZERO, s1, disp);
1657 M_DST(REG_ZERO, s1, disp);
1663 /* branch operations **************************************************/
1665 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1667 disp = dseg_add_functionptr(cd, asm_handle_exception);
1668 M_ALD(REG_ITMP2, REG_PV, disp);
1669 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
1670 M_NOP; /* nop ensures that XPC is less than the end */
1671 /* of basic block */
1674 case ICMD_IFEQ: /* ..., value ==> ... */
1676 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1677 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
1678 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
1680 ICONST(REG_ITMP2, iptr->sx.val.i);
1681 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
1683 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1686 case ICMD_IFLT: /* ..., value ==> ... */
1688 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1689 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
1690 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
1692 ICONST(REG_ITMP2, iptr->sx.val.i);
1693 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
1695 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1698 case ICMD_IFLE: /* ..., value ==> ... */
1700 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1701 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
1702 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
1704 ICONST(REG_ITMP2, iptr->sx.val.i);
1705 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
1707 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1710 case ICMD_IFNE: /* ..., value ==> ... */
1712 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1713 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
1714 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
1716 ICONST(REG_ITMP2, iptr->sx.val.i);
1717 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
1719 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1722 case ICMD_IFGT: /* ..., value ==> ... */
1724 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1725 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
1726 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
1728 ICONST(REG_ITMP2, iptr->sx.val.i);
1729 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
1731 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1734 case ICMD_IFGE: /* ..., value ==> ... */
1736 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1737 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
1738 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
1740 ICONST(REG_ITMP2, iptr->sx.val.i);
1741 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
1743 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1746 case ICMD_IF_LEQ: /* ..., value ==> ... */
1748 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1749 if (iptr->sx.val.l == 0)
1750 emit_beqz(cd, iptr->dst.block, s1);
1752 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
1753 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
1755 LCONST(REG_ITMP2, iptr->sx.val.l);
1756 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
1758 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1762 case ICMD_IF_LLT: /* ..., value ==> ... */
1764 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1765 if (iptr->sx.val.l == 0)
1766 emit_bltz(cd, iptr->dst.block, s1);
1768 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
1769 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
1771 LCONST(REG_ITMP2, iptr->sx.val.l);
1772 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
1774 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1778 case ICMD_IF_LLE: /* ..., value ==> ... */
1780 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1781 if (iptr->sx.val.l == 0)
1782 emit_blez(cd, iptr->dst.block, s1);
1784 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
1785 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
1787 LCONST(REG_ITMP2, iptr->sx.val.l);
1788 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
1790 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1794 case ICMD_IF_LNE: /* ..., value ==> ... */
1796 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1797 if (iptr->sx.val.l == 0)
1798 emit_bnez(cd, iptr->dst.block, s1);
1800 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
1801 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
1803 LCONST(REG_ITMP2, iptr->sx.val.l);
1804 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
1806 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1810 case ICMD_IF_LGT: /* ..., value ==> ... */
1812 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1813 if (iptr->sx.val.l == 0)
1814 emit_bgtz(cd, iptr->dst.block, s1);
1816 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
1817 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
1819 LCONST(REG_ITMP2, iptr->sx.val.l);
1820 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
1822 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1826 case ICMD_IF_LGE: /* ..., value ==> ... */
1828 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1829 if (iptr->sx.val.l == 0)
1830 emit_bgez(cd, iptr->dst.block, s1);
1832 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
1833 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
1835 LCONST(REG_ITMP2, iptr->sx.val.l);
1836 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
1838 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1842 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1843 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
1845 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1846 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1847 M_CMPEQ(s1, s2, REG_ITMP1);
1848 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1851 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
1852 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
1854 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1855 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1856 M_CMPEQ(s1, s2, REG_ITMP1);
1857 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1860 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
1861 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
1863 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1864 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1865 M_CMPLT(s1, s2, REG_ITMP1);
1866 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1869 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
1870 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
1872 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1873 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1874 M_CMPLE(s1, s2, REG_ITMP1);
1875 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1878 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
1879 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
1881 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1882 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1883 M_CMPLE(s1, s2, REG_ITMP1);
1884 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1887 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
1888 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
1890 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1891 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1892 M_CMPLT(s1, s2, REG_ITMP1);
1893 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1896 case ICMD_TABLESWITCH: /* ..., index ==> ... */
1899 branch_target_t *table;
1901 table = iptr->dst.table;
1903 l = iptr->sx.s23.s2.tablelow;
1904 i = iptr->sx.s23.s3.tablehigh;
1906 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1908 M_INTMOVE(s1, REG_ITMP1);
1909 } else if (l <= 32768) {
1910 M_LDA(REG_ITMP1, s1, -l);
1912 ICONST(REG_ITMP2, l);
1913 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
1916 /* number of targets */
1922 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
1924 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
1925 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
1927 emit_beqz(cd, table[0].block, REG_ITMP2);
1929 /* build jump table top down and use address of lowest entry */
1934 dseg_add_target(cd, table->block);
1939 /* length of dataseg after last dseg_add_target is used by load */
1941 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
1942 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
1943 M_JMP(REG_ZERO, REG_ITMP2);
1947 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
1948 bte = iptr->sx.s23.s3.bte;
1949 if (bte->stub == NULL)
1950 disp = dseg_add_functionptr(cd, bte->fp);
1952 disp = dseg_add_functionptr(cd, bte->stub);
1954 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
1956 /* generate the actual call */
1958 M_JSR(REG_RA, REG_PV);
1961 case ICMD_INVOKESPECIAL:
1962 emit_nullpointer_check(cd, iptr, REG_A0);
1965 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1966 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1967 um = iptr->sx.s23.s3.um;
1968 disp = dseg_add_unique_address(cd, um);
1970 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
1974 lm = iptr->sx.s23.s3.fmiref->p.method;
1975 disp = dseg_add_address(cd, lm->stubroutine);
1978 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
1980 /* generate the actual call */
1982 M_JSR(REG_RA, REG_PV);
1985 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1986 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1987 um = iptr->sx.s23.s3.um;
1988 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
1993 lm = iptr->sx.s23.s3.fmiref->p.method;
1994 s1 = OFFSET(vftbl_t, table[0]) +
1995 sizeof(methodptr) * lm->vftblindex;
1998 /* implicit null-pointer check */
1999 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2000 M_ALD(REG_PV, REG_METHODPTR, s1);
2002 /* generate the actual call */
2004 M_JSR(REG_RA, REG_PV);
2007 case ICMD_INVOKEINTERFACE:
2008 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2009 um = iptr->sx.s23.s3.um;
2010 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2016 lm = iptr->sx.s23.s3.fmiref->p.method;
2017 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2018 sizeof(methodptr*) * lm->clazz->index;
2020 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2023 /* implicit null-pointer check */
2024 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2025 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2026 M_ALD(REG_PV, REG_METHODPTR, s2);
2028 /* generate the actual call */
2030 M_JSR(REG_RA, REG_PV);
2033 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2035 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2036 /* object type cast-check */
2041 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2046 super = iptr->sx.s23.s3.c.cls;
2047 superindex = super->index;
2050 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2052 /* if class is not resolved, check which code to call */
2054 if (super == NULL) {
2055 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2057 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2059 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2060 iptr->sx.s23.s3.c.ref,
2063 M_ILD(REG_ITMP2, REG_PV, disp);
2064 disp = dseg_add_s4(cd, ACC_INTERFACE);
2065 M_ILD(REG_ITMP3, REG_PV, disp);
2066 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2067 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2070 /* interface checkcast code */
2072 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2073 if (super == NULL) {
2074 patcher_add_patch_ref(jd,
2075 PATCHER_checkcast_interface,
2076 iptr->sx.s23.s3.c.ref,
2080 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2082 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2083 M_ILD(REG_ITMP3, REG_ITMP2,
2084 OFFSET(vftbl_t, interfacetablelength));
2085 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2086 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2088 M_ALD(REG_ITMP3, REG_ITMP2,
2089 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2090 superindex * sizeof(methodptr*)));
2091 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2094 emit_label_br(cd, BRANCH_LABEL_4);
2096 emit_label(cd, BRANCH_LABEL_3);
2099 /* class checkcast code */
2101 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2102 if (super == NULL) {
2103 emit_label(cd, BRANCH_LABEL_2);
2105 disp = dseg_add_unique_address(cd, NULL);
2107 patcher_add_patch_ref(jd,
2108 PATCHER_resolve_classref_to_vftbl,
2109 iptr->sx.s23.s3.c.ref,
2113 disp = dseg_add_address(cd, super->vftbl);
2115 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2118 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2119 M_ALD(REG_ITMP3, REG_PV, disp);
2121 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2122 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2123 M_LADD(REG_ITMP1, REG_ITMP2, REG_ITMP1);
2124 M_ALD(REG_ITMP1, REG_ITMP1, 0);
2125 M_CMPEQ(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2126 emit_label_bnez(cd, BRANCH_LABEL_6, REG_ITMP1); /* good */
2128 if (super == NULL) {
2129 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2130 M_CMPEQ_IMM(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2131 emit_label_beqz(cd, BRANCH_LABEL_10, REG_ITMP1); /* throw */
2134 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2135 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
2136 M_CMPLE(REG_ITMP1, REG_ITMP3, REG_ITMP3);
2137 emit_label_beqz(cd, BRANCH_LABEL_9, REG_ITMP3); /* throw */
2139 M_ALD(REG_ITMP3, REG_PV, disp);
2140 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2141 M_S8ADDQ(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2142 M_ALD(REG_ITMP1, REG_ITMP2, -DISPLAY_SIZE*8);
2143 M_CMPEQ(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2144 emit_label_bnez(cd, BRANCH_LABEL_7, REG_ITMP1); /* good */
2146 emit_label(cd, BRANCH_LABEL_9);
2148 emit_label(cd, BRANCH_LABEL_10);
2150 /* reload s1, might have been destroyed */
2151 emit_load_s1(jd, iptr, REG_ITMP1);
2152 M_ALD_INTERN(s1, REG_ZERO, TRAP_ClassCastException);
2154 emit_label(cd, BRANCH_LABEL_7);
2155 emit_label(cd, BRANCH_LABEL_6);
2156 /* reload s1, might have been destroyed */
2157 emit_load_s1(jd, iptr, REG_ITMP1);
2160 M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
2161 M_CMPEQ(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2162 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP2, s1);
2166 emit_label(cd, BRANCH_LABEL_5);
2169 if (super == NULL) {
2170 emit_label(cd, BRANCH_LABEL_1);
2171 emit_label(cd, BRANCH_LABEL_4);
2174 d = codegen_reg_of_dst(jd, iptr, s1);
2177 /* array type cast-check */
2179 s1 = emit_load_s1(jd, iptr, REG_A0);
2180 M_INTMOVE(s1, REG_A0);
2182 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2183 disp = dseg_add_unique_address(cd, NULL);
2185 patcher_add_patch_ref(jd,
2186 PATCHER_resolve_classref_to_classinfo,
2187 iptr->sx.s23.s3.c.ref,
2191 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2193 M_ALD(REG_A1, REG_PV, disp);
2194 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2195 M_ALD(REG_PV, REG_PV, disp);
2196 M_JSR(REG_RA, REG_PV);
2197 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2198 M_LDA(REG_PV, REG_RA, -disp);
2200 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2201 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2203 d = codegen_reg_of_dst(jd, iptr, s1);
2207 emit_store_dst(jd, iptr, d);
2210 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2214 vftbl_t *supervftbl;
2217 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2223 super = iptr->sx.s23.s3.c.cls;
2224 superindex = super->index;
2225 supervftbl = super->vftbl;
2228 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2229 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2232 M_MOV(s1, REG_ITMP1);
2236 /* if class is not resolved, check which code to call */
2238 if (super == NULL) {
2240 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2242 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2244 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2245 iptr->sx.s23.s3.c.ref, disp);
2247 M_ILD(REG_ITMP3, REG_PV, disp);
2249 disp = dseg_add_s4(cd, ACC_INTERFACE);
2250 M_ILD(REG_ITMP2, REG_PV, disp);
2251 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2252 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2255 /* interface instanceof code */
2257 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2258 if (super == NULL) {
2259 /* If d == REG_ITMP2, then it's destroyed in check
2264 patcher_add_patch_ref(jd,
2265 PATCHER_instanceof_interface,
2266 iptr->sx.s23.s3.c.ref, 0);
2270 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2273 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2274 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2275 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2276 M_BLEZ(REG_ITMP3, 2);
2277 M_ALD(REG_ITMP1, REG_ITMP1,
2278 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2279 superindex * sizeof(methodptr*)));
2280 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2283 emit_label_br(cd, BRANCH_LABEL_4);
2285 emit_label(cd, BRANCH_LABEL_3);
2288 /* class instanceof code */
2290 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2291 if (super == NULL) {
2292 emit_label(cd, BRANCH_LABEL_2);
2294 disp = dseg_add_unique_address(cd, NULL);
2296 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2297 iptr->sx.s23.s3.c.ref,
2301 disp = dseg_add_address(cd, supervftbl);
2304 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2307 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2308 M_ALD(REG_ITMP3, REG_PV, disp);
2310 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2311 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2312 M_LADD(REG_ITMP1, REG_ITMP2, REG_ITMP1);
2313 M_ALD(REG_ITMP1, REG_ITMP1, 0);
2314 M_CMPEQ(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2315 emit_label_beqz(cd, BRANCH_LABEL_8, REG_ITMP1);
2317 emit_label_br(cd, BRANCH_LABEL_6); /* true */
2318 emit_label(cd, BRANCH_LABEL_8);
2320 if (super == NULL) {
2321 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2322 M_CMPEQ_IMM(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2323 emit_label_beqz(cd, BRANCH_LABEL_10, REG_ITMP1); /* false */
2326 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2328 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
2329 M_CMPLE(REG_ITMP1, REG_ITMP3, REG_ITMP3);
2330 emit_label_beqz(cd, BRANCH_LABEL_9, REG_ITMP3); /* false */
2332 M_ALD(REG_ITMP3, REG_PV, disp);
2333 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2334 M_S8ADDQ(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2335 M_ALD(REG_ITMP1, REG_ITMP2, -DISPLAY_SIZE*8);
2336 M_CMPEQ(REG_ITMP1, REG_ITMP3, d);
2339 emit_label_br(cd, BRANCH_LABEL_7);
2340 emit_label(cd, BRANCH_LABEL_9);
2342 emit_label(cd, BRANCH_LABEL_10);
2343 if (d == REG_ITMP2) {
2346 emit_label(cd, BRANCH_LABEL_7);
2348 emit_label(cd, BRANCH_LABEL_6);
2351 M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
2352 M_CMPEQ(REG_ITMP2, REG_ITMP3, d);
2356 emit_label(cd, BRANCH_LABEL_5);
2359 if (super == NULL) {
2360 emit_label(cd, BRANCH_LABEL_1);
2361 emit_label(cd, BRANCH_LABEL_4);
2364 emit_store_dst(jd, iptr, d);
2368 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2370 /* check for negative sizes and copy sizes to stack if necessary */
2372 MCODECHECK((iptr->s1.argcount << 1) + 64);
2374 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2376 var = VAR(iptr->sx.s23.s2.args[s1]);
2378 /* copy SAVEDVAR sizes to stack */
2380 /* Already Preallocated? */
2382 if (!(var->flags & PREALLOC)) {
2383 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2384 M_LST(s2, REG_SP, s1 * 8);
2388 /* a0 = dimension count */
2390 ICONST(REG_A0, iptr->s1.argcount);
2392 /* is patcher function set? */
2394 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2395 disp = dseg_add_unique_address(cd, 0);
2397 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2398 iptr->sx.s23.s3.c.ref,
2402 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2404 /* a1 = arraydescriptor */
2406 M_ALD(REG_A1, REG_PV, disp);
2408 /* a2 = pointer to dimensions = stack pointer */
2410 M_INTMOVE(REG_SP, REG_A2);
2412 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2413 M_ALD(REG_PV, REG_PV, disp);
2414 M_JSR(REG_RA, REG_PV);
2415 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2416 M_LDA(REG_PV, REG_RA, -disp);
2418 /* check for exception before result assignment */
2420 emit_exception_check(cd, iptr);
2422 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2423 M_INTMOVE(REG_RESULT, d);
2424 emit_store_dst(jd, iptr, d);
2428 vm_abort("Unknown ICMD %d during code generation", iptr->opc);
2433 /* codegen_emit_stub_native ****************************************************
2435 Emits a stub routine which calls a native method.
2437 *******************************************************************************/
2439 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2450 /* get required compiler data */
2456 /* initialize variables */
2460 /* calculate stack frame size */
2462 cd->stackframesize =
2463 1 + /* return address */
2464 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2465 sizeof(localref_table) / SIZEOF_VOID_P +
2466 1 + /* methodinfo for call trace */
2470 /* create method header */
2472 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2473 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2474 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2475 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2476 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2478 /* generate stub code */
2480 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
2481 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
2483 #if defined(ENABLE_GC_CACAO)
2484 /* Save callee saved integer registers in stackframeinfo (GC may
2485 need to recover them during a collection). */
2487 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo_t) +
2488 OFFSET(stackframeinfo_t, intregs);
2490 for (i = 0; i < INT_SAV_CNT; i++)
2491 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2494 /* save integer and float argument registers */
2496 for (i = 0; i < md->paramcount; i++) {
2497 if (!md->params[i].inmemory) {
2498 s1 = md->params[i].regoff;
2500 switch (md->paramtypes[i].type) {
2504 M_LST(s1, REG_SP, i * 8);
2507 M_FST(s1, REG_SP, i * 8);
2510 M_DST(s1, REG_SP, i * 8);
2516 /* prepare data structures for native function call */
2518 M_MOV(REG_SP, REG_A0);
2519 M_MOV(REG_PV, REG_A1);
2520 disp = dseg_add_functionptr(cd, codegen_start_native_call);
2521 M_ALD(REG_PV, REG_PV, disp);
2522 M_JSR(REG_RA, REG_PV);
2523 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2524 M_LDA(REG_PV, REG_RA, -disp);
2526 /* remember class argument */
2528 if (m->flags & ACC_STATIC)
2529 M_MOV(REG_RESULT, REG_ITMP3);
2531 /* restore integer and float argument registers */
2533 for (i = 0; i < md->paramcount; i++) {
2534 if (!md->params[i].inmemory) {
2535 s1 = md->params[i].regoff;
2537 switch (md->paramtypes[i].type) {
2541 M_LLD(s1, REG_SP, i * 8);
2544 M_FLD(s1, REG_SP, i * 8);
2547 M_DLD(s1, REG_SP, i * 8);
2553 /* copy or spill arguments to new locations */
2555 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
2556 t = md->paramtypes[i].type;
2558 if (IS_INT_LNG_TYPE(t)) {
2559 if (!md->params[i].inmemory) {
2560 s1 = md->params[i].regoff;
2561 s2 = nmd->params[j].regoff;
2563 if (!nmd->params[j].inmemory)
2566 M_LST(s1, REG_SP, s2);
2569 s1 = md->params[i].regoff + cd->stackframesize * 8;
2570 s2 = nmd->params[j].regoff;
2571 M_LLD(REG_ITMP1, REG_SP, s1);
2572 M_LST(REG_ITMP1, REG_SP, s2);
2576 if (!md->params[i].inmemory) {
2577 s1 = md->params[i].regoff;
2578 s2 = nmd->params[j].regoff;
2580 if (!nmd->params[j].inmemory)
2581 emit_fmove(cd, s1, s2);
2583 if (IS_2_WORD_TYPE(t))
2584 M_DST(s1, REG_SP, s2);
2586 M_FST(s1, REG_SP, s2);
2590 s1 = md->params[i].regoff + cd->stackframesize * 8;
2591 s2 = nmd->params[j].regoff;
2592 M_DLD(REG_FTMP1, REG_SP, s1);
2593 if (IS_2_WORD_TYPE(t))
2594 M_DST(REG_FTMP1, REG_SP, s2);
2596 M_FST(REG_FTMP1, REG_SP, s2);
2601 /* Handle native Java methods. */
2603 if (m->flags & ACC_NATIVE) {
2604 /* put class into second argument register */
2606 if (m->flags & ACC_STATIC)
2607 M_MOV(REG_ITMP3, REG_A1);
2609 /* put env into first argument register */
2611 disp = dseg_add_address(cd, VM_get_jnienv());
2612 M_ALD(REG_A0, REG_PV, disp);
2615 /* Call the native function. */
2617 disp = dseg_add_functionptr(cd, f);
2618 M_ALD(REG_PV, REG_PV, disp);
2619 M_JSR(REG_RA, REG_PV); /* call native method */
2620 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2621 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
2623 /* save return value */
2625 switch (md->returntype.type) {
2629 M_LST(REG_RESULT, REG_SP, 0 * 8);
2632 M_FST(REG_FRESULT, REG_SP, 0 * 8);
2635 M_DST(REG_FRESULT, REG_SP, 0 * 8);
2641 /* remove native stackframe info */
2643 M_MOV(REG_SP, REG_A0);
2644 M_MOV(REG_PV, REG_A1);
2645 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
2646 M_ALD(REG_PV, REG_PV, disp);
2647 M_JSR(REG_RA, REG_PV);
2648 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2649 M_LDA(REG_PV, REG_RA, -disp);
2650 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
2652 /* restore return value */
2654 switch (md->returntype.type) {
2658 M_LLD(REG_RESULT, REG_SP, 0 * 8);
2661 M_FLD(REG_FRESULT, REG_SP, 0 * 8);
2664 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
2670 #if defined(ENABLE_GC_CACAO)
2671 /* Restore callee saved integer registers from stackframeinfo (GC
2672 might have modified them during a collection). */
2674 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo_t) +
2675 OFFSET(stackframeinfo_t, intregs);
2677 for (i = 0; i < INT_SAV_CNT; i++)
2678 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2681 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* get RA */
2682 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2684 /* check for exception */
2686 M_BNEZ(REG_ITMP1_XPTR, 1); /* if no exception then return */
2687 M_RET(REG_ZERO, REG_RA); /* return to caller */
2689 /* handle exception */
2691 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address */
2693 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
2694 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
2695 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
2700 * These are local overrides for various environment variables in Emacs.
2701 * Please do not remove this and leave it at the end of the file, where
2702 * Emacs will automagically detect them.
2703 * ---------------------------------------------------------------------
2706 * indent-tabs-mode: t
2710 * vim:noexpandtab:sw=4:ts=4: