CACAO
codegen.cpp
Go to the documentation of this file.
1 /* src/vm/jit/sparc64/codegen.cpp - machine code generator for Sparc
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 
26 #include "config.h"
27 
28 #include <cassert>
29 #include <stdint.h>
30 #include <stdio.h>
31 
32 #include "vm/types.hpp"
33 
34 #include "md-abi.hpp"
35 
36 // #include "vm/jit/sparc64/arch.hpp"
38 #include "vm/jit/sparc64/emit.hpp"
39 
40 #include "mm/memory.hpp"
41 
42 #include "native/localref.hpp"
43 #include "native/native.hpp"
44 
45 #include "vm/descriptor.hpp"
46 #include "vm/exceptions.hpp"
47 #include "vm/field.hpp"
48 #include "vm/global.hpp"
49 #include "vm/loader.hpp"
50 #include "vm/options.hpp"
51 
52 #include "vm/jit/abi.hpp"
53 #include "vm/jit/asmpart.hpp"
54 #include "vm/jit/builtin.hpp"
56 #include "vm/jit/dseg.hpp"
57 #include "vm/jit/emit-common.hpp"
58 #include "vm/jit/jit.hpp"
60 #include "vm/jit/parse.hpp"
61 #include "vm/jit/patcher.hpp"
62 #include "vm/jit/reg.hpp"
63 #include "vm/jit/stacktrace.hpp"
64 
66 
67 #define BUILTIN_FLOAT_ARGS 1
68 
69 /* XXX use something like this for window control ?
70  * #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
71  */
72 #define REG_PV REG_PV_CALLEE
73 
74 bool fits_13(s4 disp)
75 {
76  /*
77  if ((disp < -4096) || (disp > 4095))
78  printf("disp %d\n", disp);
79  */
80 
81  return (disp >= -4096) && (disp <= 4095);
82 }
83 
85 {
86  s4 lodisp;
87 
88  if (disp > 0)
89  lodisp = setlo_part(disp);
90  else {
91  if (setlo_part(disp) == 0)
92  lodisp = 0;
93  else
94  lodisp = setlo_part(disp) | 0x1c00;
95  }
96 
97  return lodisp;
98 }
99 
100 #ifndef NDEBUG
102 {
103  s4 sign = (imm >> 12) & 0x1;
104 
105  if (sign == 0) {
106  if ((imm & ~0xfff) == 0) return true; /* pos imm. */
107  }
108  else
109  if ((imm & ~0xfff) + 0xfff == -1) return true; /* neg imm. */
110 
111  printf("immediate out-of-bounds: %ld\n", imm);
112  return false;
113 }
114 #endif
115 
116 
117 /* codegen_emit ****************************************************************
118 
119  Generates machine code.
120 
121 *******************************************************************************/
122 
124 {
125 
126  s4 savedregs_num;
127  s4 framesize_disp;
128 
129 #if 0 /* no leaf optimization yet */
130  savedregs_num = (code_is_leafmethod(code)) ? 0 : 1; /* space to save the RA */
131 #endif
132  savedregs_num = WINSAVE_CNT + ABIPARAMS_CNT; /* register-window save area */
133 
134 
135 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
136  if (checksync && code_is_synchronized(code))
137  cd->stackframesize++;
138 #endif
139 
140  /* keep stack 16-byte aligned (ABI requirement) */
141 
142  if (cd->stackframesize & 1)
143  cd->stackframesize++;
144 
145 
146 
147 
148 
149 
150 
151 
152 
153 
154 
155 /**
156  * Generates machine code for the method prolog.
157  */
159 {
160  varinfo* var;
161  methoddesc* md;
162  int32_t s1;
163  int32_t p, t, l;
164  int32_t varindex;
165  int i;
166 
167  // Get required compiler data.
168  methodinfo* m = jd->m;
169  codeinfo* code = jd->code;
170  codegendata* cd = jd->cd;
171  registerdata* rd = jd->rd;
172 
173  /* save register window and create stack frame (if necessary) */
174 
175  if (cd->stackframesize) {
176  if (cd->stackframesize <= 4095)
177  M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
178  else {
179  M_ILD_INTERN(REG_ITMP3, REG_PV_CALLER, framesize_disp);
182  }
183  }
184 
185  /* save callee saved float registers (none right now) */
186 #if 0
187  p = cd->stackframesize;
188  for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
189  p--; M_DST(rd->savfltregs[i], REG_SP, USESTACK + (p * 8));
190  }
191 #endif
192 
193  /* take arguments out of register or stack frame */
194 
195  md = m->parseddesc;
196 
197  for (p = 0, l = 0; p < md->paramcount; p++) {
198  t = md->paramtypes[p].type;
199 
200  varindex = jd->local_map[l * 5 + t];
201 
202  l++;
203  if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
204  l++;
205 
206  if (varindex == UNUSED)
207  continue;
208 
209  var = VAR(varindex);
210  s1 = md->params[p].regoff;
211 
212  if (IS_INT_LNG_TYPE(t)) { /* integer args */
213 
214  s2 = var->vv.regoff;
215 
216  if (!md->params[p].inmemory) { /* register arguments */
217  s1 = REG_WINDOW_TRANSPOSE(s1);
218 
219  if (!(var->flags & INMEMORY)) { /* reg arg -> register */
220 
221  /* the register allocator does not know about the window. */
222  /* avoid copying the locals from save to save regs by */
223  /* swapping variables. */
224 
225  {
226  int old_dest = var->vv.regoff;
227  int new_dest = p + 24;
228 
229  /* run through all variables */
230 
231  for (i = 0; i < jd->varcount; i++) {
232  varinfo* uvar = VAR(i);
233 
234  if (IS_FLT_DBL_TYPE(uvar->type) || IS_INMEMORY(uvar->flags))
235  continue;
236 
237  s2 = uvar->vv.regoff;
238 
239  /* free the in reg by moving all other references */
240 
241  if (s2 == new_dest) {
242  uvar->vv.regoff = old_dest;
243  /*printf("p%d-var[%d]: moved %d -> %d (to free save reg)\n", p, i, s2, old_dest);*/
244  }
245 
246  /* move all variables to the in reg */
247 
248  if (s2 == old_dest) {
249  uvar->vv.regoff = new_dest;
250  /*printf("p%d-var[%d]: moved %d -> %d (to avoid copy)\n", p, i, s2, new_dest);*/
251  }
252  }
253  }
254 
255 
256 
257  }
258  else { /* reg arg -> spilled */
259  M_STX(s1, REG_SP, JITSTACK + var->vv.regoff);
260  }
261 
262  } else { /* stack arguments */
263  if (!(var->flags & INMEMORY)) { /* stack arg -> register */
264  M_LDX(var->vv.regoff, REG_FP, JITSTACK + s1);
265 
266  } else { /* stack arg -> spilled */
267  /* add the callers window save registers */
268  var->vv.regoff = cd->stackframesize * 8 + s1;
269  }
270  }
271 
272  } else { /* floating args */
273  if (!md->params[p].inmemory) { /* register arguments */
274  if (!(var->flags & INMEMORY)) { /* reg arg -> register */
275  emit_fmove(cd, s1, var->vv.regoff);
276 
277  } else { /* reg arg -> spilled */
278  M_DST(s1, REG_SP, JITSTACK + var->vv.regoff);
279  }
280 
281  } else { /* stack arguments */
282  if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
283  M_DLD(var->vv.regoff, REG_FP, JITSTACK + s1);
284 
285  } else { /* stack-arg -> spilled */
286  var->vv.regoff = cd->stackframesize * 8 + s1;
287  }
288  }
289  }
290  } /* end for */
291 }
292 
293 
294 /**
295  * Generates machine code for the method epilog.
296  */
298 {
299  M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
300  M_NOP;
301 }
302 
303 
304 /**
305  * Generates machine code for one ICMD.
306  */
308 {
309  varinfo* var;
310  builtintable_entry* bte;
311  methodinfo* lm; // Local methodinfo for ICMD_INVOKE*.
312  unresolved_method* um;
313  fieldinfo* fi;
314  unresolved_field* uf;
315  int32_t fieldtype;
316  int32_t s1, s2, s3, d;
317  int32_t disp;
318 
319  // Get required compiler data.
320  codeinfo* code = jd->code;
321  codegendata* cd = jd->cd;
322 
323  switch (iptr->opc) {
324 
325  /* constant operations ************************************************/
326 
327  case ICMD_LCONST: /* ... ==> ..., constant */
328 
329  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
330  LCONST(d, iptr->sx.val.l);
331  emit_store_dst(jd, iptr, d);
332  break;
333 
334  case ICMD_FCONST: /* ... ==> ..., constant */
335 
336  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
337  disp = dseg_add_float(cd, iptr->sx.val.f);
338  M_FLD(d, REG_PV, disp);
339  emit_store_dst(jd, iptr, d);
340  break;
341 
342  case ICMD_DCONST: /* ... ==> ..., constant */
343 
344  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
345  disp = dseg_add_double(cd, iptr->sx.val.d);
346  M_DLD(d, REG_PV, disp);
347  emit_store_dst(jd, iptr, d);
348  break;
349 
350  case ICMD_ACONST: /* ... ==> ..., constant */
351 
352  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
353 
354  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
355  constant_classref *cr = iptr->sx.val.c.ref;
356  disp = dseg_add_unique_address(cd, cr);
357 
358  codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
359 
360  M_ALD(d, REG_PV, disp);
361 
362  }
363  else {
364  if (iptr->sx.val.anyptr == NULL) {
365  M_INTMOVE(REG_ZERO, d);
366  }
367  else {
368  disp = dseg_add_address(cd, iptr->sx.val.anyptr);
369  M_ALD(d, REG_PV, disp);
370  }
371  }
372  emit_store_dst(jd, iptr, d);
373  break;
374 
375 
376  /* integer operations *************************************************/
377 
378  case ICMD_INEG: /* ..., value ==> ..., - value */
379  case ICMD_LNEG:
380 
381  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
382  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
383  M_SUB(REG_ZERO, s1, d);
384  emit_store_dst(jd, iptr, d);
385  break;
386 
387  case ICMD_I2L: /* ..., value ==> ..., value */
388 
389  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
390  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
391  M_INTMOVE(s1, d);
392  emit_store_dst(jd, iptr, d);
393  break;
394 
395  case ICMD_L2I: /* ..., value ==> ..., value */
396 
397  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
398  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
399  M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
400  emit_store_dst(jd, iptr, d);
401  break;
402 
403  case ICMD_INT2BYTE: /* ..., value ==> ..., value */
404 
405  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
406  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
407  M_SLLX_IMM(s1, 56, d);
408  M_SRAX_IMM( d, 56, d);
409  emit_store_dst(jd, iptr, d);
410  break;
411 
412  case ICMD_INT2CHAR: /* ..., value ==> ..., value */
413 
414  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
415  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
416  M_SLLX_IMM(s1, 48, d);
417  M_SRLX_IMM( d, 48, d);
418  emit_store_dst(jd, iptr, d);
419  break;
420 
421  case ICMD_INT2SHORT: /* ..., value ==> ..., value */
422 
423  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
424  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
425  M_SLLX_IMM(s1, 48, d);
426  M_SRAX_IMM( d, 48, d);
427  emit_store_dst(jd, iptr, d);
428  break;
429 
430  case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
431  case ICMD_LADD:
432 
433  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
434  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
435  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
436  M_ADD(s1, s2, d);
437  emit_store_dst(jd, iptr, d);
438  break;
439 
440  case ICMD_IINC:
441  case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
442  /* sx.val.i = constant */
443 
444  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
445  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
446  if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
447  M_ADD_IMM(s1, iptr->sx.val.i, d);
448  } else {
449  ICONST(REG_ITMP2, iptr->sx.val.i);
450  M_ADD(s1, REG_ITMP2, d);
451  }
452  emit_store_dst(jd, iptr, d);
453  break;
454 
455  case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
456  /* sx.val.l = constant */
457 
458  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
459  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
460  if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
461  M_ADD_IMM(s1, iptr->sx.val.l, d);
462  } else {
463  LCONST(REG_ITMP2, iptr->sx.val.l);
464  M_ADD(s1, REG_ITMP2, d);
465  }
466  emit_store_dst(jd, iptr, d);
467  break;
468 
469  case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
470  case ICMD_LSUB:
471 
472  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
473  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
474  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
475  M_SUB(s1, s2, d);
476  emit_store_dst(jd, iptr, d);
477  break;
478 
479  case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
480  /* sx.val.i = constant */
481 
482  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
483  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
484  if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
485  M_SUB_IMM(s1, iptr->sx.val.i, d);
486  } else {
487  ICONST(REG_ITMP2, iptr->sx.val.i);
488  M_SUB(s1, REG_ITMP2, d);
489  }
490  emit_store_dst(jd, iptr, d);
491  break;
492 
493  case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
494  /* sx.val.l = constant */
495 
496  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
497  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
498  if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
499  M_SUB_IMM(s1, iptr->sx.val.l, d);
500  } else {
501  LCONST(REG_ITMP2, iptr->sx.val.l);
502  M_SUB(s1, REG_ITMP2, d);
503  }
504  emit_store_dst(jd, iptr, d);
505  break;
506 
507  case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
508  case ICMD_LMUL:
509 
510  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
511  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
512  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
513  M_MULX(s1, s2, d);
514  emit_store_dst(jd, iptr, d);
515  break;
516 
517  case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
518  /* sx.val.i = constant */
519 
520  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
521  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
522  if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
523  M_MULX_IMM(s1, iptr->sx.val.i, d);
524  } else {
525  ICONST(REG_ITMP2, iptr->sx.val.i);
526  M_MULX(s1, REG_ITMP2, d);
527  }
528  emit_store_dst(jd, iptr, d);
529  break;
530 
531  case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
532  /* sx.val.l = constant */
533 
534  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
535  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
536  if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
537  M_MULX_IMM(s1, iptr->sx.val.l, d);
538  } else {
539  LCONST(REG_ITMP2, iptr->sx.val.l);
540  M_MULX(s1, REG_ITMP2, d);
541  }
542  emit_store_dst(jd, iptr, d);
543  break;
544 
545  case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
546 /* XXX could also clear Y and use 32bit div */
547  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
548  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
549  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
550  emit_arithmetic_check(cd, iptr, s2);
551  M_ISEXT(s1, s1);
552  /* XXX trim s2 like s1 ? */
553  M_DIVX(s1, s2, d);
554  emit_store_dst(jd, iptr, d);
555  break;
556 
557  case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
558 
559  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
560  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
561  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
562  emit_arithmetic_check(cd, iptr, s2);
563  M_DIVX(s1, s2, d);
564  emit_store_dst(jd, iptr, d);
565  break;
566 
567  case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
568 
569  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
570  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
571  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
572  emit_arithmetic_check(cd, iptr, s2);
573  M_ISEXT(s1, s1);
574  /* XXX trim s2 like s1 ? */
575  M_DIVX(s1, s2, REG_ITMP3);
576  M_MULX(s2, REG_ITMP3, REG_ITMP3);
577  M_SUB(s1, REG_ITMP3, d);
578  emit_store_dst(jd, iptr, d);
579  break;
580 
581  case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
582 
583  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
584  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
585  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
586  emit_arithmetic_check(cd, iptr, s2);
587  M_DIVX(s1, s2, REG_ITMP3);
588  M_MULX(s2, REG_ITMP3, REG_ITMP3);
589  M_SUB(s1, REG_ITMP3, d);
590  emit_store_dst(jd, iptr, d);
591  break;
592 
593  case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
594  case ICMD_LDIVPOW2: /* val.i = constant */
595 
596  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
597  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
598  M_SRAX_IMM(s1, 63, REG_ITMP2);
599  M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
600  M_ADD(s1, REG_ITMP2, REG_ITMP2);
601  M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
602  emit_store_dst(jd, iptr, d);
603  break;
604 
605  case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
606 
607  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
608  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
609  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
610  M_SLL(s1, s2, d);
611  emit_store_dst(jd, iptr, d);
612  break;
613 
614  case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
615 
616  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
617  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
618  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
619  M_SLLX(s1, s2, d);
620  emit_store_dst(jd, iptr, d);
621  break;
622 
623  case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
624  /* val.i = constant */
625 
626  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
627  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
628  M_SLL_IMM(s1, iptr->sx.val.i, d);
629  emit_store_dst(jd, iptr, d);
630  break;
631 
632  case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
633  /* val.i = constant */
634 
635  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
636  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
637  M_SLLX_IMM(s1, iptr->sx.val.i, d);
638  emit_store_dst(jd, iptr, d);
639  break;
640 
641  case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
642 
643  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
644  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
645  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
646  M_SRA(s1, s2, d);
647  emit_store_dst(jd, iptr, d);
648  break;
649 
650  case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
651  /* sx.val.i = constant */
652 
653  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
654  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
655  M_SRA_IMM(s1, iptr->sx.val.i, d);
656  emit_store_dst(jd, iptr, d);
657  break;
658 
659  case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
660 
661  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
662  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
663  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
664  M_SRL(s1, s2, d);
665  emit_store_dst(jd, iptr, d);
666  break;
667 
668  case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
669  /* sx.val.i = constant */
670 
671  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
672  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
673  M_SRL_IMM(s1, iptr->sx.val.i, d);
674  emit_store_dst(jd, iptr, d);
675  break;
676 
677  case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
678 
679  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
680  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
681  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
682  M_SRAX(s1, s2, d);
683  emit_store_dst(jd, iptr, d);
684  break;
685 
686  case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
687  /* sx.val.i = constant */
688 
689  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
690  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
691  M_SRAX_IMM(s1, iptr->sx.val.i, d);
692  emit_store_dst(jd, iptr, d);
693  break;
694 
695  case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
696 
697  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
698  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
699  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
700  M_SRLX(s1, s2, d);
701  emit_store_dst(jd, iptr, d);
702  break;
703 
704  case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
705  /* sx.val.i = constant */
706 
707  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
708  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
709  M_SRLX_IMM(s1, iptr->sx.val.i, d);
710  emit_store_dst(jd, iptr, d);
711  break;
712 
713  case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
714  case ICMD_LAND:
715 
716  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
717  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
718  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
719  M_AND(s1, s2, d);
720  emit_store_dst(jd, iptr, d);
721  break;
722 
723  case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
724  /* sx.val.i = constant */
725 
726  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
727  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
728  if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
729  M_AND_IMM(s1, iptr->sx.val.i, d);
730  } else {
731  ICONST(REG_ITMP2, iptr->sx.val.i);
732  M_AND(s1, REG_ITMP2, d);
733  }
734  emit_store_dst(jd, iptr, d);
735  break;
736 
737  case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
738  /* sx.val.i = constant */
739  /* constant is actually constant - 1 */
740 
741  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
742  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
743  if (s1 == d) {
744  M_MOV(s1, REG_ITMP1);
745  s1 = REG_ITMP1;
746  }
747  M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
748  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 4095)) {
749  M_AND_IMM(s1, iptr->sx.val.i, d);
750  M_BGEZ(s1, 5);
751  M_NOP;
752  M_SUB(REG_ZERO, s1, d);
753  M_AND_IMM(d, iptr->sx.val.i, d);
754  } else {
755  ICONST(REG_ITMP2, iptr->sx.val.i);
756  M_AND(s1, REG_ITMP2, d);
757  M_BGEZ(s1, 5);
758  M_NOP;
759  M_SUB(REG_ZERO, s1, d);
760  M_AND(d, REG_ITMP2, d);
761  }
762  M_SUB(REG_ZERO, d, d);
763  emit_store_dst(jd, iptr, d);
764  break;
765 
766  case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
767  /* sx.val.l = constant */
768 
769  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
770  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
771  if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
772  M_AND_IMM(s1, iptr->sx.val.l, d);
773  } else {
774  LCONST(REG_ITMP2, iptr->sx.val.l);
775  M_AND(s1, REG_ITMP2, d);
776  }
777  emit_store_dst(jd, iptr, d);
778  break;
779 
780  case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
781  /* sx.val.l = constant */
782 
783  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
784  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
785  if (s1 == d) {
786  M_MOV(s1, REG_ITMP1);
787  s1 = REG_ITMP1;
788  }
789  if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
790  M_AND_IMM(s1, iptr->sx.val.l, d);
791  M_BGEZ(s1, 4);
792  M_NOP;
793  M_SUB(REG_ZERO, s1, d);
794  M_AND_IMM(d, iptr->sx.val.l, d);
795  } else {
796  LCONST(REG_ITMP2, iptr->sx.val.l);
797  M_AND(s1, REG_ITMP2, d);
798  M_BGEZ(s1, 4);
799  M_NOP;
800  M_SUB(REG_ZERO, s1, d);
801  M_AND(d, REG_ITMP2, d);
802  }
803  M_SUB(REG_ZERO, d, d);
804  emit_store_dst(jd, iptr, d);
805  break;
806 
807  case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
808  case ICMD_LOR:
809 
810  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
811  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
812  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
813  M_OR(s1,s2, d);
814  emit_store_dst(jd, iptr, d);
815  break;
816 
817  case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
818  /* sx.val.i = constant */
819 
820  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
821  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
822  if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
823  M_OR_IMM(s1, iptr->sx.val.i, d);
824  } else {
825  ICONST(REG_ITMP2, iptr->sx.val.i);
826  M_OR(s1, REG_ITMP2, d);
827  }
828  emit_store_dst(jd, iptr, d);
829  break;
830 
831  case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
832  /* sx.val.l = constant */
833 
834  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
835  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
836  if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
837  M_OR_IMM(s1, iptr->sx.val.l, d);
838  } else {
839  LCONST(REG_ITMP2, iptr->sx.val.l);
840  M_OR(s1, REG_ITMP2, d);
841  }
842  emit_store_dst(jd, iptr, d);
843  break;
844 
845  case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
846  case ICMD_LXOR:
847 
848  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
849  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
850  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
851  M_XOR(s1, s2, d);
852  emit_store_dst(jd, iptr, d);
853  break;
854 
855  case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
856  /* sx.val.i = constant */
857 
858  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
859  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
860  if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
861  M_XOR_IMM(s1, iptr->sx.val.i, d);
862  } else {
863  ICONST(REG_ITMP2, iptr->sx.val.i);
864  M_XOR(s1, REG_ITMP2, d);
865  }
866  emit_store_dst(jd, iptr, d);
867  break;
868 
869  case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
870  /* sx.val.l = constant */
871 
872  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
873  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
874  if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
875  M_XOR_IMM(s1, iptr->sx.val.l, d);
876  } else {
877  LCONST(REG_ITMP2, iptr->sx.val.l);
878  M_XOR(s1, REG_ITMP2, d);
879  }
880  emit_store_dst(jd, iptr, d);
881  break;
882 
883 
884  case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
885 
886  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
887  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
888  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
889  M_CMP(s1, s2);
890  M_MOV(REG_ZERO, d);
891  M_XCMOVLT_IMM(-1, d);
892  M_XCMOVGT_IMM(1, d);
893  emit_store_dst(jd, iptr, d);
894  break;
895 
896 
897  /* floating operations ************************************************/
898 
899  case ICMD_FNEG: /* ..., value ==> ..., - value */
900 
901  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
902  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
903  M_FNEG(s1, d);
904  emit_store_dst(jd, iptr, d);
905  break;
906 
907  case ICMD_DNEG: /* ..., value ==> ..., - value */
908 
909  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
910  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
911  M_DNEG(s1, d);
912  emit_store_dst(jd, iptr, d);
913  break;
914 
915  case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
916 
917  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
918  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
919  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
920  M_FADD(s1, s2, d);
921  emit_store_dst(jd, iptr, d);
922  break;
923 
924  case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
925 
926  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
927  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
928  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
929  M_DADD(s1, s2, d);
930  emit_store_dst(jd, iptr, d);
931  break;
932 
933  case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
934 
935  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
936  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
937  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
938  M_FSUB(s1, s2, d);
939  emit_store_dst(jd, iptr, d);
940  break;
941 
942  case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
943 
944  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
945  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
946  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
947  M_DSUB(s1, s2, d);
948  emit_store_dst(jd, iptr, d);
949  break;
950 
951  case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
952 
953  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
954  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
955  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
956  M_FMUL(s1, s2, d);
957  emit_store_dst(jd, iptr, d);
958  break;
959 
960  case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
961 
962  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
963  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
964  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
965  M_DMUL(s1, s2, d);
966  emit_store_dst(jd, iptr, d);
967  break;
968 
969  case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
970 
971  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
972  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
973  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
974  M_FDIV(s1, s2, d);
975  emit_store_dst(jd, iptr, d);
976  break;
977 
978  case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
979 
980  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
981  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
982  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
983  M_DDIV(s1, s2, d);
984  emit_store_dst(jd, iptr, d);
985  break;
986 
987  case ICMD_I2F:
988  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
989  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
990  disp = dseg_add_unique_float(cd, 0.0);
991  M_IST (s1, REG_PV_CALLEE, disp);
992  M_FLD (d, REG_PV_CALLEE, disp);
993  M_CVTIF (d, d); /* rd gets translated to double target register */
994  emit_store_dst(jd, iptr, d);
995  break;
996 
997  case ICMD_I2D:
998  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
999  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1000  disp = dseg_add_unique_float(cd, 0.0);
1001  M_IST(s1, REG_PV_CALLEE, disp);
1002  M_FLD(REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1003  M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1004  emit_store_dst(jd, iptr, d);
1005  break;
1006 
1007  case ICMD_L2F:
1008  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1009  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1010  disp = dseg_add_unique_double(cd, 0.0);
1011  M_STX(s1, REG_PV_CALLEE, disp);
1012  M_DLD(REG_FTMP3, REG_PV_CALLEE, disp);
1013  M_CVTLF(REG_FTMP3, d);
1014  emit_store_dst(jd, iptr, d);
1015  break;
1016 
1017  case ICMD_L2D:
1018  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1019  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1020  disp = dseg_add_unique_double(cd, 0.0);
1021  M_STX(s1, REG_PV_CALLEE, disp);
1022  M_DLD(d, REG_PV_CALLEE, disp);
1023  M_CVTLD(d, d);
1024  emit_store_dst(jd, iptr, d);
1025  break;
1026 
1027  case ICMD_F2I: /* ..., value ==> ..., (int) value */
1028  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1029  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1030  disp = dseg_add_unique_float(cd, 0.0);
1031 
1032  /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1033  M_FCMP(s1, s1);
1034  M_FBU(5);
1035  M_MOV(REG_ZERO, d); /* delay slot */
1036 
1037  M_CVTFI(s1, REG_FTMP2);
1038  M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1039  M_ILD(d, REG_PV, disp);
1040  emit_store_dst(jd, iptr, d);
1041  break;
1042 
1043 
1044  case ICMD_D2I: /* ..., value ==> ..., (int) value */
1045  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1046  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1047  disp = dseg_add_unique_float(cd, 0.0);
1048 
1049  /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1050  M_DCMP(s1, s1);
1051  M_FBU(5);
1052  M_MOV(REG_ZERO, d); /* delay slot */
1053 
1054  M_CVTDI(s1, REG_FTMP2);
1055  M_FST(REG_FTMP2, REG_PV, disp);
1056  M_ILD(d, REG_PV, disp);
1057  emit_store_dst(jd, iptr, d);
1058  break;
1059 
1060  case ICMD_F2L: /* ..., value ==> ..., (long) value */
1061  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1062  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1063  disp = dseg_add_unique_double(cd, 0.0);
1064 
1065  /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1066  M_FCMP(s1, s1);
1067  M_FBU(5);
1068  M_MOV(REG_ZERO, d); /* delay slot */
1069 
1070  M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1071  M_DST(REG_FTMP2, REG_PV, disp);
1072  M_LDX(d, REG_PV, disp);
1073  emit_store_dst(jd, iptr, d);
1074  break;
1075 
1076  case ICMD_D2L: /* ..., value ==> ..., (long) value */
1077  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1078  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1079  disp = dseg_add_unique_double(cd, 0.0);
1080 
1081  /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1082  M_DCMP(s1, s1);
1083  M_FBU(5);
1084  M_MOV(REG_ZERO, d); /* delay slot */
1085 
1086  M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1087  M_DST(REG_FTMP2, REG_PV, disp);
1088  M_LDX(d, REG_PV, disp);
1089  emit_store_dst(jd, iptr, d);
1090  break;
1091 
1092  case ICMD_F2D: /* ..., value ==> ..., (double) value */
1093 
1094  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1095  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1096  M_CVTFD(s1, d);
1097  emit_store_dst(jd, iptr, d);
1098  break;
1099 
1100  case ICMD_D2F: /* ..., value ==> ..., (float) value */
1101 
1102  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1103  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1104  M_CVTDF(s1, d);
1105  emit_store_dst(jd, iptr, d);
1106  break;
1107 
1108  /* XXX merge F/D versions? only compare instr. is different */
1109  case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1110 
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_FCMP(s1,s2);
1115  M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1116  M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1117  M_CMOVFGT_IMM(1, d); /* 1 if greater */
1118  emit_store_dst(jd, iptr, d);
1119  break;
1120 
1121  case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1122 
1123  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1124  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1125  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1126  M_DCMP(s1,s2);
1127  M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1128  M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1129  M_CMOVFGT_IMM(1, d); /* 1 if greater */
1130  emit_store_dst(jd, iptr, d);
1131  break;
1132 
1133  case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1134 
1135  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1136  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1137  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1138  M_FCMP(s1,s2);
1139  M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1140  M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1141  M_CMOVFLT_IMM(-1, d); /* -1 if less */
1142  emit_store_dst(jd, iptr, d);
1143  break;
1144 
1145  case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1146 
1147  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1148  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1149  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1150  M_DCMP(s1,s2);
1151  M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1152  M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1153  M_CMOVFLT_IMM(-1, d); /* -1 if less */
1154  emit_store_dst(jd, iptr, d);
1155  break;
1156 
1157 
1158  /* memory operations **************************************************/
1159 
1160  case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1161 
1162  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1163  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1164  emit_nullpointer_check(cd, iptr, s1);
1165  M_ILD(d, s1, OFFSET(java_array_t, size));
1166  emit_store_dst(jd, iptr, d);
1167  break;
1168 
1169  case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1170 
1171  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1172  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1173  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1174  /* implicit null-pointer check */
1175  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1176  M_AADD(s2, s1, REG_ITMP3);
1177  M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1178  emit_store_dst(jd, iptr, d);
1179  break;
1180 
1181  case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1182 
1183  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1184  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1185  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1186  /* implicit null-pointer check */
1187  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1188  M_AADD(s2, s1, REG_ITMP3);
1189  M_AADD(s2, REG_ITMP3, REG_ITMP3);
1190  M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1191  emit_store_dst(jd, iptr, d);
1192  break;
1193 
1194  case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1195 
1196  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1197  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1198  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1199  /* implicit null-pointer check */
1200  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1201  M_AADD(s2, s1, REG_ITMP3);
1202  M_AADD(s2, REG_ITMP3, REG_ITMP3);
1203  M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1204  emit_store_dst(jd, iptr, d);
1205  break;
1206 
1207  case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1208 
1209  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1210  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1211  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1212  /* implicit null-pointer check */
1213  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1214  M_ASLL_IMM(s2, 2, REG_ITMP3);
1215  M_AADD(REG_ITMP3, s1, REG_ITMP3);
1216  M_ILD(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
1217  emit_store_dst(jd, iptr, d);
1218  break;
1219 
1220  case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1221 
1222  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1223  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1224  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1225  /* implicit null-pointer check */
1226  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1227  M_ASLL_IMM(s2, 3, REG_ITMP3);
1228  M_AADD(REG_ITMP3, s1, REG_ITMP3);
1229  M_LDX(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
1230  emit_store_dst(jd, iptr, d);
1231  break;
1232 
1233  case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1234 
1235  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1236  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1237  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1238  /* implicit null-pointer check */
1239  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1240  M_ASLL_IMM(s2, 2, REG_ITMP3);
1241  M_AADD(REG_ITMP3, s1, REG_ITMP3);
1242  M_FLD(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
1243  emit_store_dst(jd, iptr, d);
1244  break;
1245 
1246  case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1247 
1248  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1249  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1250  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1251  /* implicit null-pointer check */
1252  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1253  M_ASLL_IMM(s2, 3, REG_ITMP3);
1254  M_AADD(REG_ITMP3, s1, REG_ITMP3);
1255  M_DLD(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
1256  emit_store_dst(jd, iptr, d);
1257  break;
1258 
1259  case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1260 
1261  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1262  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1263  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1264  /* implicit null-pointer check */
1265  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1267  M_AADD(REG_ITMP3, s1, REG_ITMP3);
1268  M_ALD(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
1269  emit_store_dst(jd, iptr, d);
1270  break;
1271 
1272 
1273  case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1274 
1275  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1276  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1277  /* implicit null-pointer check */
1278  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1279  M_AADD(s2, s1, REG_ITMP1);
1280  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1281  M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1282  break;
1283 
1284  case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1285  case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1286 
1287  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1288  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1289  /* implicit null-pointer check */
1290  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1291  M_AADD(s2, s1, REG_ITMP1);
1292  M_AADD(s2, REG_ITMP1, REG_ITMP1);
1293  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1294  M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1295  break;
1296 
1297  case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1298 
1299  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1300  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1301  /* implicit null-pointer check */
1302  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1303  M_ASLL_IMM(s2, 2, REG_ITMP2);
1304  M_AADD(REG_ITMP2, s1, REG_ITMP1);
1305  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1306  M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1307  break;
1308 
1309  case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1310 
1311  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1312  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1313  /* implicit null-pointer check */
1314  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1315  M_ASLL_IMM(s2, 3, REG_ITMP2);
1316  M_AADD(REG_ITMP2, s1, REG_ITMP1);
1317  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1319  break;
1320 
1321  case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1322 
1323  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1324  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1325  /* implicit null-pointer check */
1326  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1327  M_ASLL_IMM(s2, 2, REG_ITMP2);
1328  M_AADD(REG_ITMP2, s1, REG_ITMP1);
1329  s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1331  break;
1332 
1333  case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1334 
1335  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1336  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1337  /* implicit null-pointer check */
1338  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1339  M_ASLL_IMM(s2, 3, REG_ITMP2);
1340  M_AADD(REG_ITMP2, s1, REG_ITMP1);
1341  s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1343  break;
1344 
1345 
1346  case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1347 
1348  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1349  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1350  /* implicit null-pointer check */
1351  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1352  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1353 
1354  M_MOV(s1, REG_OUT0);
1355  M_MOV(s3, REG_OUT1);
1357  M_ALD(REG_ITMP3, REG_PV, disp);
1359  M_NOP;
1360  emit_arraystore_check(cd, iptr);
1361 
1362  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1363  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1365  M_AADD(REG_ITMP2, s1, REG_ITMP1);
1366  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1367  /* implicit null-pointer check */
1369  break;
1370 
1371 
1372  case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1373 
1374  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1375  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1376  /* implicit null-pointer check */
1377  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1378  M_AADD(s2, s1, REG_ITMP1);
1380  break;
1381 
1382  case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1383  case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1384 
1385  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1386  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1387  /* implicit null-pointer check */
1388  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1389  M_AADD(s2, s1, REG_ITMP1);
1390  M_AADD(s2, REG_ITMP1, REG_ITMP1);
1392  break;
1393 
1394  case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1395 
1396  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1397  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1398  /* implicit null-pointer check */
1399  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1400  M_ASLL_IMM(s2, 2, REG_ITMP2);
1401  M_AADD(REG_ITMP2, s1, REG_ITMP1);
1403  break;
1404 
1405  case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1406 
1407  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1408  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1409  /* implicit null-pointer check */
1410  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1411  M_ASLL_IMM(s2, 3, REG_ITMP2);
1412  M_AADD(REG_ITMP2, s1, REG_ITMP1);
1414  break;
1415 
1416  case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1417 
1418  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1419  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1420  /* implicit null-pointer check */
1421  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1423  M_AADD(REG_ITMP2, s1, REG_ITMP1);
1425  break;
1426 
1427 
1428  case ICMD_GETSTATIC: /* ... ==> ..., value */
1429 
1430  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1431  uf = iptr->sx.s23.s3.uf;
1432  fieldtype = uf->fieldref->parseddesc.fd->type;
1433  disp = dseg_add_unique_address(cd, uf);
1434 
1435  codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1436  }
1437  else {
1438  fi = iptr->sx.s23.s3.fmiref->p.field;
1439  fieldtype = fi->type;
1440  disp = dseg_add_address(cd, fi->value);
1441 
1443  codegen_add_patch_ref(cd, PATCHER_clinit, fi->clazz, disp);
1444  }
1445 
1446  M_ALD(REG_ITMP1, REG_PV, disp);
1447 
1448  switch (fieldtype) {
1449  case TYPE_INT:
1450  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1451  M_ILD_INTERN(d, REG_ITMP1, 0);
1452  break;
1453  case TYPE_LNG:
1454  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1455  M_LDX_INTERN(d, REG_ITMP1, 0);
1456  break;
1457  case TYPE_ADR:
1458  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1459  M_ALD_INTERN(d, REG_ITMP1, 0);
1460  break;
1461  case TYPE_FLT:
1462  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1463  M_FLD_INTERN(d, REG_ITMP1, 0);
1464  break;
1465  case TYPE_DBL:
1466  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1467  M_DLD_INTERN(d, REG_ITMP1, 0);
1468  break;
1469  default:
1470  assert(false);
1471  break;
1472  }
1473  emit_store_dst(jd, iptr, d);
1474  break;
1475 
1476  case ICMD_PUTSTATIC: /* ..., value ==> ... */
1477 
1478  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1479  uf = iptr->sx.s23.s3.uf;
1480  fieldtype = uf->fieldref->parseddesc.fd->type;
1481  disp = dseg_add_unique_address(cd, uf);
1482 
1483  codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1484  }
1485  else {
1486  fi = iptr->sx.s23.s3.fmiref->p.field;
1487  fieldtype = fi->type;
1488  disp = dseg_add_address(cd, fi->value);
1489 
1491  codegen_add_patch_ref(cd, PATCHER_clinit, fi->clazz, disp);
1492  }
1493 
1494  M_ALD(REG_ITMP1, REG_PV, disp);
1495 
1496  switch (fieldtype) {
1497  case TYPE_INT:
1498  s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1499  M_IST_INTERN(s1, REG_ITMP1, 0);
1500  break;
1501  case TYPE_LNG:
1502  s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1503  M_STX_INTERN(s1, REG_ITMP1, 0);
1504  break;
1505  case TYPE_ADR:
1506  s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1507  M_AST_INTERN(s1, REG_ITMP1, 0);
1508  break;
1509  case TYPE_FLT:
1510  s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1511  M_FST_INTERN(s1, REG_ITMP1, 0);
1512  break;
1513  case TYPE_DBL:
1514  s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1515  M_DST_INTERN(s1, REG_ITMP1, 0);
1516  break;
1517  default:
1518  assert(false);
1519  break;
1520  }
1521  break;
1522 
1523  case ICMD_PUTSTATICCONST: /* ... ==> ... */
1524  /* val = value (in current instruction) */
1525  /* following NOP) */
1526 
1527  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1528  uf = iptr->sx.s23.s3.uf;
1529  fieldtype = uf->fieldref->parseddesc.fd->type;
1530  disp = dseg_add_unique_address(cd, uf);
1531 
1532  codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1533  }
1534  else {
1535  fi = iptr->sx.s23.s3.fmiref->p.field;
1536  fieldtype = fi->type;
1537  disp = dseg_add_address(cd, fi->value);
1538 
1540  codegen_add_patch_ref(cd, PATCHER_clinit, fi->clazz, disp);
1541  }
1542 
1543  M_ALD(REG_ITMP1, REG_PV, disp);
1544 
1545  switch (fieldtype) {
1546  case TYPE_INT:
1548  break;
1549  case TYPE_LNG:
1551  break;
1552  case TYPE_ADR:
1554  break;
1555  case TYPE_FLT:
1557  break;
1558  case TYPE_DBL:
1560  break;
1561  default:
1562  assert(false);
1563  break;
1564  }
1565  break;
1566 
1567 
1568  case ICMD_GETFIELD: /* ... ==> ..., value */
1569 
1570  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1571  emit_nullpointer_check(cd, iptr, s1);
1572 
1573  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1574  uf = iptr->sx.s23.s3.uf;
1575 
1576  fieldtype = uf->fieldref->parseddesc.fd->type;
1577  disp = 0;
1578 
1579  codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1580  }
1581  else {
1582  fi = iptr->sx.s23.s3.fmiref->p.field;
1583  fieldtype = fi->type;
1584  disp = fi->offset;
1585  }
1586 
1587  switch (fieldtype) {
1588  case TYPE_INT:
1589  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1590  M_ILD(d, s1, disp);
1591  break;
1592  case TYPE_LNG:
1593  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1594  M_LDX(d, s1, disp);
1595  break;
1596  case TYPE_ADR:
1597  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1598  M_ALD(d, s1, disp);
1599  break;
1600  case TYPE_FLT:
1601  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1602  M_FLD(d, s1, disp);
1603  break;
1604  case TYPE_DBL:
1605  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1606  M_DLD(d, s1, disp);
1607  break;
1608  default:
1609  assert(false);
1610  break;
1611  }
1612  emit_store_dst(jd, iptr, d);
1613  break;
1614 
1615  case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1616 
1617  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1618  emit_nullpointer_check(cd, iptr, s1);
1619 
1620  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1621  uf = iptr->sx.s23.s3.uf;
1622  fieldtype = uf->fieldref->parseddesc.fd->type;
1623  disp = 0;
1624  }
1625  else {
1626  uf = NULL;
1627  fi = iptr->sx.s23.s3.fmiref->p.field;
1628  fieldtype = fi->type;
1629  disp = fi->offset;
1630  }
1631 
1632  if (IS_INT_LNG_TYPE(fieldtype))
1633  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1634  else
1635  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1636 
1637  if (INSTRUCTION_IS_UNRESOLVED(iptr))
1638  codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1639 
1640  switch (fieldtype) {
1641  case TYPE_INT:
1642  M_IST(s2, s1, disp);
1643  break;
1644  case TYPE_LNG:
1645  M_STX(s2, s1, disp);
1646  break;
1647  case TYPE_ADR:
1648  M_AST(s2, s1, disp);
1649  break;
1650  case TYPE_FLT:
1651  M_FST(s2, s1, disp);
1652  break;
1653  case TYPE_DBL:
1654  M_DST(s2, s1, disp);
1655  break;
1656  default:
1657  assert(false);
1658  break;
1659  }
1660  break;
1661 
1662  case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1663  /* val = value (in current instruction) */
1664  /* following NOP) */
1665 
1666  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1667  emit_nullpointer_check(cd, iptr, s1);
1668 
1669  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1670  unresolved_field *uf = iptr->sx.s23.s3.uf;
1671 
1672  fieldtype = uf->fieldref->parseddesc.fd->type;
1673 
1674  codegen_addpatchref(cd, PATCHER_get_putfield,
1675  uf, 0);
1676 
1677  if (opt_showdisassemble) {
1678  M_NOP; M_NOP;
1679  }
1680 
1681  disp = 0;
1682 
1683  } else {
1684  {
1685  fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1686 
1687  fieldtype = fi->type;
1688  disp = fi->offset;
1689  }
1690 
1691  }
1692 
1693  switch (fieldtype) {
1694  case TYPE_INT:
1695  M_IST(REG_ZERO, s1, disp);
1696  break;
1697  case TYPE_LNG:
1698  M_STX(REG_ZERO, s1, disp);
1699  break;
1700  case TYPE_ADR:
1701  M_AST(REG_ZERO, s1, disp);
1702  break;
1703  case TYPE_FLT:
1704  M_FST(REG_ZERO, s1, disp);
1705  break;
1706  case TYPE_DBL:
1707  M_DST(REG_ZERO, s1, disp);
1708  break;
1709  default:
1710  assert(false);
1711  break;
1712  }
1713  break;
1714 
1715 
1716  /* branch operations **************************************************/
1717 
1718  case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1719 
1721  M_ALD(REG_ITMP1, REG_PV, disp);
1723  M_NOP;
1724  M_NOP; /* nop ensures that XPC is less than the end */
1725  /* of basic block */
1726  break;
1727 
1728  case ICMD_IF_LEQ: /* ..., value ==> ... */
1729 
1730  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1731  if (iptr->sx.val.l == 0)
1732  emit_beqz(cd, iptr->dst.block, s1);
1733  else {
1734  if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1735  M_CMP_IMM(s1, iptr->sx.val.l);
1736  }
1737  else {
1738  LCONST(REG_ITMP2, iptr->sx.val.l);
1739  M_CMP(s1, REG_ITMP2);
1740  }
1741  emit_beq_xcc(cd, iptr->dst.block);
1742  }
1743  break;
1744 
1745  case ICMD_IF_LLT: /* ..., value ==> ... */
1746 
1747  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1748  if (iptr->sx.val.l == 0)
1749  emit_bltz(cd, iptr->dst.block, s1);
1750  else {
1751  if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1752  M_CMP_IMM(s1, iptr->sx.val.l);
1753  }
1754  else {
1755  LCONST(REG_ITMP2, iptr->sx.val.l);
1756  M_CMP(s1, REG_ITMP2);
1757  }
1758  emit_blt_xcc(cd, iptr->dst.block);
1759  }
1760  break;
1761 
1762  case ICMD_IF_LLE: /* ..., value ==> ... */
1763 
1764  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1765  if (iptr->sx.val.l == 0)
1766  emit_blez(cd, iptr->dst.block, s1);
1767  else {
1768  if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1769  M_CMP_IMM(s1, iptr->sx.val.l);
1770  }
1771  else {
1772  LCONST(REG_ITMP2, iptr->sx.val.l);
1773  M_CMP(s1, REG_ITMP2);
1774  }
1775  emit_ble_xcc(cd, iptr->dst.block);
1776  }
1777  break;
1778 
1779  case ICMD_IF_LNE: /* ..., value ==> ... */
1780 
1781  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1782  if (iptr->sx.val.l == 0)
1783  emit_bnez(cd, iptr->dst.block, s1);
1784  else {
1785  if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1786  M_CMP_IMM(s1, iptr->sx.val.l);
1787  }
1788  else {
1789  LCONST(REG_ITMP2, iptr->sx.val.l);
1790  M_CMP(s1, REG_ITMP2);
1791  }
1792  emit_bne_xcc(cd, iptr->dst.block);
1793  }
1794  break;
1795 
1796  case ICMD_IF_LGT: /* ..., value ==> ... */
1797 
1798  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1799  if (iptr->sx.val.l == 0)
1800  emit_bgtz(cd, iptr->dst.block, s1);
1801  else {
1802  if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1803  M_CMP_IMM(s1, iptr->sx.val.l);
1804  }
1805  else {
1806  LCONST(REG_ITMP2, iptr->sx.val.l);
1807  M_CMP(s1, REG_ITMP2);
1808  }
1809  emit_bgt_xcc(cd, iptr->dst.block);
1810  }
1811  break;
1812 
1813  case ICMD_IF_LGE: /* ..., value ==> ... */
1814 
1815  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1816  if (iptr->sx.val.l == 0)
1817  emit_bgez(cd, iptr->dst.block, s1);
1818  else {
1819  if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1820  M_CMP_IMM(s1, iptr->sx.val.l);
1821  }
1822  else {
1823  LCONST(REG_ITMP2, iptr->sx.val.l);
1824  M_CMP(s1, REG_ITMP2);
1825  }
1826  emit_bge_xcc(cd, iptr->dst.block);
1827  }
1828  break;
1829 
1830 
1831  case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
1832  case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
1833 
1834  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1835  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1836  M_CMP(s1, s2);
1837  emit_beq_xcc(cd, iptr->dst.block);
1838  break;
1839 
1840  case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
1841  case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
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  emit_bne_xcc(cd, iptr->dst.block);
1847  break;
1848 
1849  case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
1850 
1851  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1852  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1853  M_CMP(s1, s2);
1854  emit_blt_xcc(cd, iptr->dst.block);
1855  break;
1856 
1857  case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
1858 
1859  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1860  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1861  M_CMP(s1, s2);
1862  emit_bgt_xcc(cd, iptr->dst.block);
1863  break;
1864 
1865  case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
1866 
1867  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1868  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1869  M_CMP(s1, s2);
1870  emit_ble_xcc(cd, iptr->dst.block);
1871  break;
1872 
1873  case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
1874 
1875  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1876  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1877  M_CMP(s1, s2);
1878  emit_bge_xcc(cd, iptr->dst.block);
1879  break;
1880 
1881  case ICMD_TABLESWITCH: /* ..., index ==> ... */
1882  {
1883  s4 i, l;
1884  branch_target_t *table;
1885 
1886  table = iptr->dst.table;
1887 
1888  l = iptr->sx.s23.s2.tablelow;
1889  i = iptr->sx.s23.s3.tablehigh;
1890 
1891  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1892  if (l == 0) {
1893  M_INTMOVE(s1, REG_ITMP1);
1894  }
1895  else if (-l >= 4096 && -l <= 4095) {
1896  M_ADD_IMM(s1, -l, REG_ITMP1);
1897  }
1898  else {
1899  ICONST(REG_ITMP2, l);
1900  M_SUB(s1, REG_ITMP2, REG_ITMP1);
1901  }
1902 
1903  i = i - l + 1; /* number of targets (>0) */
1904 
1905 
1906  /* range check */
1907 
1908  if (i <= 4095) {
1909  M_CMP_IMM(REG_ITMP1, i - 1);
1910  }
1911  else {
1912  ICONST(REG_ITMP2, i - 1);
1914  }
1915  emit_bugt(cd, table[0].block); /* default target */
1916 
1917  /* build jump table top down and use address of lowest entry */
1918 
1919  table += i;
1920 
1921  while (--i >= 0) {
1922  dseg_add_target(cd, table->block);
1923  --table;
1924  }
1925  }
1926 
1927  /* length of dataseg after last dseg_addtarget is used by load */
1928 
1931  M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
1933  M_NOP;
1934  ALIGNCODENOP;
1935  break;
1936 
1937  // XXX This is the old builtin invocation containing some
1938  // special argument handling code, port me!
1939  case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
1940 
1941  bte = iptr->sx.s23.s3.bte;
1942  md = bte->md;
1943 
1944  /* XXX: builtin calling with stack arguments not implemented */
1945  assert(md->paramcount <= 5 && md->argfltreguse <= 16);
1946 
1947  s3 = md->paramcount;
1948 
1949  MCODECHECK((s3 << 1) + 64);
1950 
1951 #ifdef BUILTIN_FLOAT_ARGS /* float args for builtins disabled */
1952 
1953  /* copy float arguments according to ABI convention */
1954 
1955  int num_fltregargs = 0;
1956  int fltregarg_inswap[16];
1957 
1958  for (s3 = s3 - 1; s3 >= 0; s3--) {
1959  var = VAR(iptr->sx.s23.s2.args[s3]);
1960 
1961  if (IS_FLT_DBL_TYPE(var->type)) {
1962  if (!md->params[s3].inmemory) {
1963  s1 = s3; /*native flt args use argument index directly*/
1964  d = emit_load(jd, iptr, var, REG_FTMP1);
1965 
1966  M_DMOV(d, s1 + 16);
1967  fltregarg_inswap[num_fltregargs] = s1;
1968  num_fltregargs++;
1969  /*printf("builtin: flt arg swap to %d\n", s1 + 16);*/
1970  }
1971  else {
1972  assert(0);
1973  }
1974  }
1975  }
1976 
1977  int i;
1978  /* move swapped float args to target regs */
1979  for (i = 0; i < num_fltregargs; i++) {
1980  s1 = fltregarg_inswap[i];
1981  M_DMOV(s1 + 16, s1);
1982  /*printf("builtin float arg to target reg: %d ==> %d\n", s1+16, s1);*/
1983  }
1984 
1985 #else
1986  assert(md->argfltreguse == 0);
1987 #endif
1988 
1989 
1990 
1991 
1992 XXXXXX
1993  if (IS_INT_LNG_TYPE(var->type)) {
1994  if (!md->params[s3].inmemory) {
1995  s1 = emit_load(jd, iptr, var, d);
1996  M_INTMOVE(s1, d);
1997  }
1998  else {
1999  s1 = emit_load(jd, iptr, var, REG_ITMP1);
2000  M_STX(s1, REG_SP, JITSTACK + d);
2001  }
2002  }
2003  }
2004 XXXXXX
2005 
2006  case ICMD_BUILTIN:
2007  bte = iptr->sx.s23.s3.bte;
2008  if (bte->stub == NULL) {
2009  disp = dseg_add_functionptr(cd, bte->fp);
2010  }
2011  else {
2012  disp = dseg_add_functionptr(cd, bte->stub);
2013  }
2014 
2015  M_ALD(REG_PV_CALLER, REG_PV, disp); /* built-in-function pointer */
2016 
2017  /* XXX jit-c-call */
2018  /* generate the actual call */
2019 
2021  M_NOP;
2022 
2023  if (md->returntype.type == TYPE_FLT) {
2024  /* special handling for float return value in %f0 */
2025  M_FMOV_INTERN(0,1);
2026  }
2027  break;
2028 
2029  case ICMD_INVOKESPECIAL:
2030  emit_nullpointer_check(cd, iptr, REG_OUT0);
2031  /* fall-through */
2032 
2033  case ICMD_INVOKESTATIC:
2034  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2035  um = iptr->sx.s23.s3.um;
2036  disp = dseg_add_unique_address(cd, NULL);
2037 
2038  codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2039  um, disp);
2040  }
2041  else {
2042  lm = iptr->sx.s23.s3.fmiref->p.method;
2043  disp = dseg_add_address(cd, lm->stubroutine);
2044  }
2045 
2046  M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in pv */
2047 
2048  /* generate the actual call */
2049 
2051  M_NOP;
2052  break;
2053 
2054  case ICMD_INVOKEVIRTUAL:
2055  emit_nullpointer_check(cd, iptr, REG_OUT0);
2056 
2057  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2058  um = iptr->sx.s23.s3.um;
2059  codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2060 
2061  s1 = 0;
2062  }
2063  else {
2064  lm = iptr->sx.s23.s3.fmiref->p.method;
2065  s1 = OFFSET(vftbl_t, table[0]) +
2066  sizeof(methodptr) * lm->vftblindex;
2067  }
2068 
2069  /* implicit null-pointer check */
2072 
2073  /* generate the actual call */
2074 
2076  M_NOP;
2077  break;
2078 
2079  case ICMD_INVOKEINTERFACE:
2080  emit_nullpointer_check(cd, iptr, REG_OUT0);
2081 
2082  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2083  um = iptr->sx.s23.s3.um;
2084  codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2085 
2086  s1 = 0;
2087  s2 = 0;
2088  }
2089  else {
2090  lm = iptr->sx.s23.s3.fmiref->p.method;
2091  s1 = OFFSET(vftbl_t, interfacetable[0]) -
2092  sizeof(methodptr*) * lm->clazz->index;
2093 
2094  s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2095  }
2096 
2097  /* implicit null-pointer check */
2101 
2102  /* generate the actual call */
2103 
2105  M_NOP;
2106  break;
2107 
2108 XXXXXX
2109  /* store return value */
2110  else {
2111  s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2112  if (IS_2_WORD_TYPE(d)) {
2113  emit_dmove(cd, REG_FRESULT, s1);
2114  } else {
2115  emit_fmove(cd, REG_FRESULT, s1);
2116  }
2117  }
2118 XXXXX
2119 
2120  case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2121  /* val.a: (classinfo*) superclass */
2122 
2123  /* superclass is an interface:
2124  *
2125  * OK if ((sub == NULL) ||
2126  * (sub->vftbl->interfacetablelength > super->index) &&
2127  * (sub->vftbl->interfacetable[-super->index] != NULL));
2128  *
2129  * superclass is a class:
2130  *
2131  * OK if ((sub == NULL) || (0
2132  * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2133  * super->vftbl->diffvall));
2134  */
2135 
2136  if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2137  classinfo *super;
2138  s4 superindex;
2139 
2140  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2141  super = NULL;
2142  superindex = 0;
2143  }
2144  else {
2145  super = iptr->sx.s23.s3.c.cls;
2146  superindex = super->index;
2147  }
2148 
2149  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2150 
2151  /* if class is not resolved, check which code to call */
2152 
2153  if (super == NULL) {
2154  emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2155 
2156  constant_classref *cr = iptr->sx.s23.s3.c.ref;
2157  disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2158 
2159  codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2160  cr, disp);
2161 
2162  M_ILD(REG_ITMP2, REG_PV, disp);
2164  emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2165  }
2166 
2167  /* interface checkcast code */
2168 
2169  if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2170  if (super == NULL) {
2171  constant_classref *cr = iptr->sx.s23.s3.c.ref;
2172 
2173  codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2174  cr, 0);
2175  }
2176  else {
2177  emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2178  }
2179 
2180  M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2182  OFFSET(vftbl_t, interfacetablelength));
2183  M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2184  emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2185 
2187  OFFSET(vftbl_t, interfacetable[0]) -
2188  superindex * sizeof(methodptr*));
2189  emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2190 
2191  if (super == NULL)
2193  else
2195  }
2196 
2197  /* class checkcast code */
2198 
2199  if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2200  if (super == NULL) {
2202 
2203  constant_classref *cr = iptr->sx.s23.s3.c.ref;
2204  disp = dseg_add_unique_address(cd, NULL);
2205 
2206  codegen_add_patch_ref(cd,
2207  PATCHER_checkcast_instanceof_class,
2208  cr, disp);
2209  }
2210  else {
2211  disp = dseg_add_address(cd, super->vftbl);
2212 
2213  emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2214  }
2215 
2216  M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2217  M_ALD(REG_ITMP3, REG_PV, disp);
2218 
2219  M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2220  M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2222  M_ALD(REG_ITMP3, REG_PV, disp);
2223  M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2224 
2225  /* } */
2227  emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
2228 
2229  if (super != NULL)
2231  }
2232 
2233  if (super == NULL) {
2236  }
2237 
2238  d = codegen_reg_of_dst(jd, iptr, s1);
2239  }
2240  else {
2241  /* array type cast-check */
2242 
2243  s1 = emit_load_s1(jd, iptr, REG_OUT0);
2244  M_INTMOVE(s1, REG_OUT0);
2245 
2246  disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2247 
2248  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2249  constant_classref *cr = iptr->sx.s23.s3.c.ref;
2250  disp = dseg_add_unique_address(cd, NULL);
2251 
2252  codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2253  cr, disp);
2254  }
2255  else
2256  disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2257 
2258  M_ALD(REG_OUT1, REG_PV, disp);
2260  M_ALD(REG_ITMP3, REG_PV, disp);
2261  /* XXX jit-c-call */
2263  M_NOP;
2264 
2265  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2267 
2268  d = codegen_reg_of_dst(jd, iptr, s1);
2269  }
2270 
2271  M_INTMOVE(s1, d);
2272  emit_store_dst(jd, iptr, d);
2273  break;
2274 
2275  case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2276  /* val.a: (classinfo*) superclass */
2277 
2278  /* superclass is an interface:
2279  *
2280  * return (sub != NULL) &&
2281  * (sub->vftbl->interfacetablelength > super->index) &&
2282  * (sub->vftbl->interfacetable[-super->index] != NULL);
2283  *
2284  * superclass is a class:
2285  *
2286  * return ((sub != NULL) && (0
2287  * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2288  * super->vftbl->diffvall));
2289  */
2290 
2291  {
2292  classinfo *super;
2293  vftbl_t *supervftbl;
2294  s4 superindex;
2295 
2296  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2297  super = NULL;
2298  superindex = 0;
2299  supervftbl = NULL;
2300 
2301  } else {
2302  super = iptr->sx.s23.s3.c.cls;
2303  superindex = super->index;
2304  supervftbl = super->vftbl;
2305  }
2306 
2307  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2308  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2309  if (s1 == d) {
2310  M_MOV(s1, REG_ITMP1);
2311  s1 = REG_ITMP1;
2312  }
2313 
2314  M_CLR(d);
2315 
2316  /* if class is not resolved, check which code to call */
2317 
2318  if (super == NULL) {
2319  emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2320 
2321  constant_classref *cr = iptr->sx.s23.s3.c.ref;
2322  disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2323 
2324  codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2325  cr, disp);
2326 
2327  M_ILD(REG_ITMP3, REG_PV, disp);
2329  emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2330  }
2331 
2332  /* interface instanceof code */
2333 
2334  if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2335  if (super == NULL) {
2336  constant_classref *cr = iptr->sx.s23.s3.c.ref;
2337 
2338  codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2339  cr, 0);
2340  }
2341  else {
2342  emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2343  }
2344 
2345  M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2346  M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2347  M_CMP_IMM(REG_ITMP3, superindex);
2348  M_BLE(4);
2349  M_NOP;
2351  (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2352  superindex * sizeof(methodptr*)));
2353  M_CMOVRNE_IMM(REG_ITMP1, 1, d); /* REG_ITMP1 != 0 */
2354 
2355  if (super == NULL)
2357  else
2359  }
2360 
2361  /* class instanceof code */
2362 
2363  if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2364  if (super == NULL) {
2366 
2367  constant_classref *cr = iptr->sx.s23.s3.c.ref;
2368  disp = dseg_add_unique_address(cd, NULL);
2369 
2370  codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2371  cr, disp);
2372  }
2373  else {
2374  disp = dseg_add_address(cd, supervftbl);
2375 
2376  emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2377  }
2378 
2379  M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2380  M_ALD(REG_ITMP2, REG_PV, disp);
2381 
2382  M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2383  M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2384  M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2385 
2388  M_XCMOVULE_IMM(1, d);
2389 
2390  if (super != NULL)
2392  }
2393 
2394  if (super == NULL) {
2397  }
2398 
2399  emit_store_dst(jd, iptr, d);
2400  }
2401  break;
2402 
2403  case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2404 
2405  /* check for negative sizes and copy sizes to stack if necessary */
2406 
2407  MCODECHECK((iptr->s1.argcount << 1) + 64);
2408 
2409  for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2410 
2411  var = VAR(iptr->sx.s23.s2.args[s1]);
2412 
2413  /* copy SAVEDVAR sizes to stack */
2414 
2415  /* Already Preallocated? */
2416 
2417  if (!(var->flags & PREALLOC)) {
2418  s2 = emit_load(jd, iptr, var, REG_ITMP1);
2419  M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2420  }
2421  }
2422 
2423  /* arg 0 = dimension count */
2424 
2425  ICONST(REG_OUT0, iptr->s1.argcount);
2426 
2427  /* is patcher function set? */
2428 
2429  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2430  disp = dseg_add_unique_address(cd, 0);
2431 
2432  codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2433  iptr->sx.s23.s3.c.ref,
2434  disp);
2435  }
2436  else
2437  disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2438 
2439  /* arg 1 = arraydescriptor */
2440 
2441  M_ALD(REG_OUT1, REG_PV, disp);
2442 
2443  /* arg 2 = pointer to dimensions = stack pointer (absolute) */
2444 
2446 
2447  /* XXX c abi call */
2449  M_ALD(REG_ITMP3, REG_PV, disp);
2451  M_NOP;
2452 
2453  /* check for exception before result assignment */
2454 
2455  emit_exception_check(cd, iptr);
2456 
2457  d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2459  emit_store_dst(jd, iptr, d);
2460  break;
2461 
2462  default:
2463  vm_abort("Unknown ICMD %d during code generation", iptr->opc);
2464  } /* switch */
2465 }
2466 
2467 
2468 /* codegen_emit_stub_compiler **************************************************
2469 
2470  Emits a stub routine which calls the compiler.
2471 
2472 *******************************************************************************/
2473 
2475 {
2476  methodinfo *m;
2477  codegendata *cd;
2478 
2479  /* get required compiler data */
2480 
2481  m = jd->m;
2482  cd = jd->cd;
2483 
2484  /* code for the stub */
2485 
2486  /* no window save yet, user caller's PV */
2487  M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
2488  M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
2489  M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
2490  M_NOP;
2491 }
2492 
2493 
2494 /* codegen_emit_stub_builtin ***************************************************
2495 
2496  Creates a stub routine which calls a builtin function.
2497 
2498 *******************************************************************************/
2499 
2501 {
2502  codeinfo *code;
2503  codegendata *cd;
2504  methoddesc *md;
2505  s4 i;
2506  s4 disp;
2507  s4 s1, s2;
2508 
2509  /* get required compiler data */
2510  code = jd->code;
2511  cd = jd->cd;
2512 
2513  /* set some variables */
2514  md = bte->md;
2515 
2516  /* calculate stack frame size */
2517  cd->stackframesize =
2518  WINSAVE_CNT +
2519  ABIPARAMS_CNT +
2520  FLT_ARG_CNT +
2521  sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2522  4; /* 4 arguments or return value */
2523 
2524 
2525  /* keep stack 16-byte aligned (ABI requirement) */
2526 
2527  if (cd->stackframesize & 1)
2528  cd->stackframesize++;
2529 
2530  /* create method header */
2531  (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2532  (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
2533  (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2534  (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2535  (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2536 
2537  /* generate stub code */
2538  M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
2539 
2540 #if defined(ENABLE_GC_CACAO)
2541  /* Save callee saved integer registers in stackframeinfo (GC may
2542  need to recover them during a collection). */
2543 
2544  disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2545  OFFSET(stackframeinfo_t, intregs) + BIAS;
2546 
2547  for (i = 0; i < INT_SAV_CNT; i++)
2548  M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2549 #endif
2550 
2551  for (i = 0; i < md->paramcount; i++) {
2552  s1 = md->params[i].regoff;
2553 
2554  switch (md->paramtypes[i].type) {
2555  case TYPE_INT:
2556  case TYPE_LNG:
2557  case TYPE_ADR:
2558  break;
2559  case TYPE_FLT:
2560  case TYPE_DBL:
2561  M_DST(s1, REG_SP, JITSTACK + i * 8);
2562  break;
2563  default:
2564  assert(false);
2565  break;
2566  }
2567  }
2568 
2569  /* create dynamic stack info */
2570 
2571  M_AADD_IMM(REG_SP, BIAS + cd->stackframesize * 8, REG_OUT0); /* data sp*/
2572  M_MOV(REG_PV_CALLEE, REG_OUT1); /* PV */
2573  M_MOV(REG_FP, REG_OUT2); /* java sp */
2574  M_MOV(REG_RA_CALLEE, REG_OUT3); /* ra */
2575 
2576  disp = dseg_add_functionptr(cd, codegen_stub_builtin_enter);
2577  M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
2579  M_NOP; /* XXX fill me! */
2580 
2581 
2582  /* builtins are allowed to have 5 arguments max */
2583 
2584  assert(md->paramcount <= 5);
2585 
2586  /* copy arguments into position */
2587 
2588  for (i = 0; i < md->paramcount; i++) {
2589  assert(!md->params[i].inmemory);
2590 
2591  s1 = md->params[i].regoff;
2592 
2593  switch (md->paramtypes[i].type) {
2594  case TYPE_INT:
2595  case TYPE_LNG:
2596  case TYPE_ADR:
2598  break;
2599  case TYPE_FLT:
2600  case TYPE_DBL:
2601  M_DLD(s1, REG_SP, JITSTACK + i * 8);
2602  break;
2603  default:
2604  assert(false);
2605  break;
2606  }
2607 
2608  }
2609 
2610  /* call the builtin function */
2611 
2612  disp = dseg_add_functionptr(cd, bte->fp);
2613  M_ALD(REG_ITMP3, REG_PV_CALLEE, disp); /* load adress of builtin */
2614  M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call builtin */
2615  M_NOP; /* delay slot */
2616 
2617 
2618  /* save return value */
2619 
2620  if (md->returntype.type != TYPE_VOID) {
2621  if (IS_INT_LNG_TYPE(md->returntype.type))
2623  else
2625  }
2626 
2627 
2628  /* remove native stackframe info */
2629 
2630  M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
2631  disp = dseg_add_functionptr(cd, codegen_stub_builtin_exit);
2632  M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
2634  M_NOP;
2635 
2636  /* restore float return value, int return value already in our return reg */
2637 
2638  if (md->returntype.type != TYPE_VOID) {
2639  if (IS_FLT_DBL_TYPE(md->returntype.type)) {
2640  if (IS_2_WORD_TYPE(md->returntype.type))
2642  else
2644  }
2645  }
2646 
2647 
2648 #if defined(ENABLE_GC_CACAO)
2649  /* Restore callee saved integer registers from stackframeinfo (GC
2650  might have modified them during a collection). */
2651 
2652  disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2653  OFFSET(stackframeinfo_t, intregs) + BIAS;
2654 
2655  for (i = 0; i < INT_SAV_CNT; i++)
2656  M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2657 #endif
2658 
2659  /* return */
2660  M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2661  M_NOP;
2662 
2663  /* assert(0); */
2664 }
2665 
2666 
2667 /* codegen_emit_stub_native ****************************************************
2668 
2669  Emits a stub routine which calls a native method.
2670 
2671 *******************************************************************************/
2672 
2674 {
2675  methodinfo *m;
2676  codeinfo *code;
2677  codegendata *cd;
2678  methoddesc *md;
2679  s4 nativeparams;
2680  s4 i, j; /* count variables */
2681  s4 t;
2682  s4 s1, s2, disp;
2683  s4 funcdisp; /* displacement of the function */
2684  s4 fltregarg_offset[FLT_ARG_CNT];
2685 
2686  /* get required compiler data */
2687 
2688  m = jd->m;
2689  code = jd->code;
2690  cd = jd->cd;
2691 
2692  /* initialize variables */
2693 
2694  md = m->parseddesc;
2695  nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
2696 
2697  /* calculate stack frame size */
2698 
2699  cd->stackframesize =
2700  sizeof(stackframeinfo) / SIZEOF_VOID_P +
2701  sizeof(localref_table) / SIZEOF_VOID_P +
2702  md->paramcount + /* for saving arguments over calls */
2703  nmd->memuse + /* nmd->memuse includes the (6) abi params */
2704  WINSAVE_CNT;
2705 
2706 
2707  /* keep stack 16-byte aligned (ABI requirement) */
2708 
2709  if (cd->stackframesize & 1)
2710  cd->stackframesize++;
2711 
2712  /* create method header */
2713 
2714  (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2715  (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2716  (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2717  (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2718  (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2719 
2720  /* generate stub code */
2721 
2722  M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
2723 
2724 #if !defined(NDEBUG)
2727 #endif
2728 
2729  /* get function address (this must happen before the stackframeinfo) */
2730 
2731  funcdisp = dseg_add_functionptr(cd, f);
2732 
2733  if (f == NULL)
2734  codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
2735 
2736  /* save float argument registers */
2737 
2738  assert(ABIPARAMS_CNT >= FLT_ARG_CNT);
2739 
2740  for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
2741  if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
2742  s1 = WINSAVE_CNT + nmd->memuse + j;
2744  fltregarg_offset[i] = s1; /* remember stack offset */
2745  j++;
2746  }
2747  }
2748 
2749  /* prepare data structures for native function call */
2750 
2751  M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute, ie. + BIAS) */
2753  M_MOV(REG_FP, REG_OUT2); /* java sp */
2756  M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
2758  M_NOP; /* XXX fill me! */
2759 
2760  /* remember class argument */
2761 
2762  if (m->flags & ACC_STATIC)
2764 
2765  /* keep float arguments on stack */
2766 #if 0
2767  for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
2768  if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
2770  j++;
2771  }
2772  }
2773 #endif
2774 
2775  /* copy or spill arguments to new locations */
2776 
2777  for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
2778  t = md->paramtypes[i].type;
2779 
2780  if (IS_INT_LNG_TYPE(t)) {
2781 
2782  /* integral types */
2783 
2784  if (!md->params[i].inmemory) {
2785  s1 = md->params[i].regoff;
2786  /* s1 refers to the old window, transpose */
2787  s1 = REG_WINDOW_TRANSPOSE(s1);
2788 
2789  if (!nmd->params[j].inmemory) {
2790  s2 = nmd->params[j].regoff;
2791  M_INTMOVE(s1, s2);
2792  } else {
2793  /* nmd's regoff is relative to the start of the param array */
2794  s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
2795  M_AST(s1, REG_SP, s2);
2796  }
2797 
2798  } else {
2799  if (!nmd->params[j].inmemory) {
2800  /* JIT stack arg -> NAT reg arg */
2801 
2802  /* Due to the Env pointer that is always passed, the 6th JIT arg */
2803  /* is the 7th (or 8th w/ class ptr) NAT arg, and goes to the stack */
2804 
2805  assert(false); /* path never taken */
2806  }
2807 
2808  s1 = md->params[i].regoff + cd->stackframesize * 8;
2809  s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
2810  M_ALD(REG_ITMP1, REG_SP, CSTACK + s1);
2811  M_AST(REG_ITMP1, REG_SP, s2);
2812  }
2813 
2814  } else {
2815 
2816  /* floating point types */
2817 
2818  if (!md->params[i].inmemory) {
2819  s1 = md->params[i].regoff;
2820 
2821  if (!nmd->params[j].inmemory) {
2822 
2823  /* no mapping to regs needed, native flt args use regoff */
2824  s2 = nmd->params[j].regoff;
2825 
2826  /* JIT float regs are still on the stack */
2827  M_DLD(s2, REG_SP, BIAS + (fltregarg_offset[i] * 8));
2828  }
2829  else {
2830  /* not supposed to happen with 16 NAT flt args */
2831  assert(false);
2832  /*
2833  s2 = nmd->params[j].regoff;
2834  if (IS_2_WORD_TYPE(t))
2835  M_DST(s1, REG_SP, CSTACK + (s2 * 8));
2836  else
2837  M_FST(s1, REG_SP, CSTACK + (s2 * 8));
2838  */
2839  }
2840 
2841  }
2842  else {
2843  s1 = md->params[i].regoff;
2844 
2845  if (!nmd->params[j].inmemory) {
2846 
2847  /* JIT stack -> NAT reg */
2848 
2849  s2 = nmd->params[j].regoff;
2850  M_DLD(s2, REG_FP, JITSTACK + s1);
2851  }
2852  else {
2853 
2854  /* JIT stack -> NAT stack */
2855 
2856  s2 = WINSAVE_CNT * 8 + nmd->params[j].regoff;
2857 
2858  /* The FTMP register may already be loaded with args */
2859  /* we know $f0 is unused because of the env pointer */
2860  M_DLD(REG_F0, REG_FP, JITSTACK + s1);
2861  M_DST(REG_F0, REG_SP, BIAS + s2);
2862  }
2863  }
2864  }
2865  }
2866 
2867 
2868  /* put class into second argument register */
2869 
2870  if (m->flags & ACC_STATIC)
2872 
2873  /* put env into first argument register */
2874 
2875  disp = dseg_add_address(cd, VM::get_current()->get_jnienv());
2876  M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
2877 
2878  /* do the native function call */
2879 
2880  M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method */
2881  M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method */
2882  M_NOP; /* delay slot */
2883 
2884  /* save return value */
2885 
2886  if (md->returntype.type != TYPE_VOID) {
2887  if (IS_INT_LNG_TYPE(md->returntype.type))
2889  else
2891  }
2892 
2893  /* Note: native functions return float values in %f0 (see ABI) */
2894  /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
2895 
2896 #if !defined(NDEBUG)
2897  /* But for the trace function we need to put a flt result into %f1 */
2898  if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2899  if (!IS_2_WORD_TYPE(md->returntype.type))
2902  }
2903 #endif
2904 
2905  /* remove native stackframe info */
2906 
2907  M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
2909  M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
2911  M_NOP; /* XXX fill me! */
2913 
2914  /* restore float return value, int return value already in our return reg */
2915 
2916  if (md->returntype.type != TYPE_VOID) {
2917  if (IS_FLT_DBL_TYPE(md->returntype.type)) {
2918  if (IS_2_WORD_TYPE(md->returntype.type))
2920  else
2922  }
2923  }
2924 
2925  /* check for exception */
2926  M_BNEZ(REG_ITMP2_XPTR, 4); /* if no exception then return */
2927  M_NOP;
2928 
2929  M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2930  M_NOP;
2931 
2932  /* handle exception */
2933 
2935  M_ALD(REG_ITMP1, REG_PV, disp); /* load asm exception handler address */
2936  M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address */
2937  M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler */
2938  M_RESTORE(REG_ZERO, 0, REG_ZERO); /* restore callers window (DELAY) */
2939 
2940  /* generate patcher stubs */
2941 
2942  emit_patcher_stubs(jd);
2943 }
2944 
2945 /*
2946  * These are local overrides for various environment variables in Emacs.
2947  * Please do not remove this and leave it at the end of the file, where
2948  * Emacs will automagically detect them.
2949  * ---------------------------------------------------------------------
2950  * Local variables:
2951  * mode: c++
2952  * indent-tabs-mode: t
2953  * c-basic-offset: 4
2954  * tab-width: 4
2955  * End:
2956  * vim:noexpandtab:sw=4:ts=4:
2957  */
void codegen_emit_instruction(jitdata *jd, instruction *iptr)
Generates machine code for one ICMD.
Definition: codegen.cpp:217
const s4 abi_registers_float_argument[]
Definition: md-abi.cpp:107
s4 dseg_add_double(codegendata *cd, double value)
Definition: dseg.cpp:465
#define REG_SP
Definition: md-abi.hpp:53
val_operand_t val
#define BUILTIN_FAST_canstore
Definition: builtin.hpp:153
s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg)
#define M_SRA(a, b, c)
Definition: codegen.hpp:307
#define REG_RESULT_CALLEE
Definition: md-abi.hpp:38
basicblock * block
union varinfo::@19 vv
bool opt_showdisassemble
Definition: options.cpp:85
#define REG_RA_CALLER
Definition: md-abi.hpp:42
s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg)
Definition: emit-common.cpp:63
#define M_ALD(a, b, disp)
Definition: codegen.hpp:345
#define M_CVTDI(a, d)
Definition: codegen.hpp:725
#define REG_WINDOW_TRANSPOSE(reg)
Definition: md-abi.hpp:123
#define M_DMUL(a, b, c)
Definition: codegen.hpp:378
#define M_SRAX_IMM(rs1, rs2, rd)
Definition: codegen.hpp:300
#define M_SRLX_IMM(rs1, rs2, rd)
Definition: codegen.hpp:296
#define REG_F0
Definition: md-abi.hpp:82
#define PATCHER_invokeinterface
Definition: jit.hpp:126
#define M_CMOVFEQ_IMM(rs, rd)
Definition: codegen.hpp:348
paramdesc * params
Definition: descriptor.hpp:164
#define M_SLL(a, b, c)
Definition: codegen.hpp:306
void emit_ble_xcc(codegendata *cd, basicblock *target)
Definition: emit.cpp:469
#define M_CVTFD(a, b)
Definition: codegen.hpp:721
#define JITDATA_HAS_FLAG_VERBOSECALL(jd)
Definition: jit.hpp:227
methoddesc * md
Definition: builtin.hpp:71
#define REG_OUT3
Definition: md-abi.hpp:66
void emit_bne_xcc(codegendata *cd, basicblock *target)
Definition: emit.cpp:449
#define M_ILD(a, b, disp)
Definition: codegen.hpp:347
s4 dseg_add_unique_address(codegendata *cd, void *value)
Definition: dseg.cpp:525
#define M_DNEG(a, d)
Definition: codegen.hpp:715
methodinfo * methods
Definition: class.hpp:113
#define M_ISEXT(a, b)
Definition: codegen.hpp:344
#define BUILTIN_multianewarray
Definition: builtin.hpp:201
#define M_CMP(a, b)
Definition: codegen.hpp:430
#define IS_INT_LNG_TYPE(a)
Definition: global.hpp:130
#define M_AND(a, b, c)
Definition: codegen.hpp:294
#define M_IST(a, b, disp)
Definition: codegen.hpp:351
#define M_FCMP(a, b)
Definition: codegen.hpp:717
#define ICONST(d, c)
Definition: codegen.hpp:53
#define M_SRL(a, b, c)
Definition: codegen.hpp:308
#define M_FNEG(a, d)
Definition: codegen.hpp:714
#define PATCHER_get_putfield
const s4 abi_registers_integer_argument[]
Definition: md-abi.cpp:64
#define M_FLD_INTERN(a, b, disp)
Definition: codegen.hpp:314
#define M_AADD_IMM(a, b, c)
Definition: codegen.hpp:277
#define M_ADD_IMM(d, a, i)
Definition: codegen.hpp:437
void emit_bgt_xcc(codegendata *cd, basicblock *target)
Definition: emit.cpp:464
#define REG_OUT0
Definition: md-abi.hpp:63
s4 dseg_add_address(codegendata *cd, void *value)
Definition: dseg.cpp:542
codeinfo * code
Definition: jit.hpp:128
#define M_OR_IMM(a, b, c)
Definition: codegen.hpp:299
s4 dseg_add_unique_double(codegendata *cd, double value)
Definition: dseg.cpp:448
#define BRANCH_LABEL_5
Definition: emit-common.hpp:51
#define REG_FRESULT
Definition: md-abi.hpp:59
int32_t argcount
Definition: instruction.hpp:64
s4 dseg_add_unique_float(codegendata *cd, float value)
Definition: dseg.cpp:375
#define dseg_add_functionptr(cd, value)
Definition: dseg.hpp:39
#define M_IST_INTERN(a, b, disp)
Definition: codegen.hpp:214
codegendata * cd
Definition: jit.hpp:129
void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
Definition: codegen.cpp:2010
#define BIAS
Definition: md-abi.hpp:107
typedef void(JNICALL *jvmtiEventSingleStep)(jvmtiEnv *jvmti_env
#define M_SLLX(rs1, rs2, rd)
Definition: codegen.hpp:291
#define REG_PV_CALLER
Definition: md-abi.hpp:45
#define REG_OUT2
Definition: md-abi.hpp:65
#define M_STX_INTERN(rd, rs, disp)
Definition: codegen.hpp:464
#define POINTERSHIFT
Definition: codegen.hpp:571
#define M_STX(rd, rs, disp)
Definition: codegen.hpp:465
void emit_patcher_stubs(jitdata *jd)
Definition: emit.cpp:741
void emit_arraystore_check(codegendata *cd, instruction *iptr)
Definition: emit.cpp:380
#define M_FST(a, b, disp)
Definition: codegen.hpp:357
constant_classref * ref
Definition: references.hpp:62
#define M_FLD(a, b, disp)
Definition: codegen.hpp:354
#define REG_FP
Definition: md-abi.hpp:60
void dseg_add_target(codegendata *cd, basicblock *target)
Definition: dseg.cpp:565
#define M_LDX(rd, rs, disp)
Definition: codegen.hpp:432
u1 * methodptr
Definition: global.hpp:40
Type type
Definition: reg.hpp:44
java_object_t * codegen_finish_native_call(u1 *sp, u1 *pv)
u1 * stub
Definition: builtin.hpp:64
int64_t s8
Definition: types.hpp:48
#define M_SRAX(rs1, rs2, rd)
Definition: codegen.hpp:299
#define M_CVTDL(b, c)
Definition: codegen.hpp:394
const s4 abi_registers_integer_saved[]
Definition: md-abi.cpp:75
#define M_OR(a, b, c)
Definition: codegen.hpp:295
#define M_CMOVFGT_IMM(rs, rd)
Definition: codegen.hpp:346
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
#define VAR(i)
Definition: jit.hpp:252
Definition: reg.hpp:43
#define M_CVTLD(b, c)
Definition: codegen.hpp:393
void emit_bge_xcc(codegendata *cd, basicblock *target)
Definition: emit.cpp:459
#define M_CMOVRNE_IMM(rs1, rs2, rd)
Definition: codegen.hpp:364
#define PATCHER_get_putstatic
static int code_is_leafmethod(codeinfo *code)
Definition: code.hpp:151
#define BUILTIN_arraycheckcast
Definition: builtin.hpp:148
#define M_MULX(rs1, rs2, rd)
Definition: codegen.hpp:311
#define M_CVTLF(b, c)
Definition: codegen.hpp:392
void emit_blt_xcc(codegendata *cd, basicblock *target)
Definition: emit.cpp:454
void vm_abort(const char *text,...)
Definition: vm.cpp:2586
#define ALIGNCODENOP
Definition: codegen.hpp:47
s4 regoff
Definition: reg.hpp:47
void(* functionptr)(void)
Definition: global.hpp:39
s4 varcount
Definition: jit.hpp:151
#define M_SAVE(rs1, rs2, rd)
Definition: codegen.hpp:538
#define M_BGEZ(a, disp)
Definition: codegen.hpp:256
void emit_verbosecall_enter(jitdata *jd)
Definition: emit.cpp:625
typedesc paramtypes[1]
Definition: descriptor.hpp:167
#define INT_SAV_CNT
Definition: md-abi.hpp:73
java_handle_t * codegen_start_native_call(u1 *sp, u1 *pv)
#define PATCHER_instanceof_interface
#define IS_2_WORD_TYPE(a)
Definition: global.hpp:132
#define M_CMP_IMM(a, i)
Definition: codegen.hpp:446
void emit_exception_check(codegendata *cd, instruction *iptr)
Definition: emit.cpp:447
s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
BeginInst *& block
#define M_FSUB(a, b, c)
Definition: codegen.hpp:375
#define M_CVTID(a, d)
Definition: codegen.hpp:723
classref_or_classinfo c
#define REG_ITMP3_XPC
Definition: md-abi.hpp:57
#define setlo_part(x)
Definition: codegen.hpp:381
#define CSTACK
Definition: md-abi.hpp:118
u1 * stubroutine
Definition: method.hpp:102
s4 vftblindex
Definition: method.hpp:81
#define REG_RA_CALLEE
Definition: md-abi.hpp:41
dst_operand_t dst
#define M_CVTFI(a, d)
Definition: codegen.hpp:724
flags_operand_t flags
#define M_XOR_IMM(a, b, c)
Definition: codegen.hpp:300
#define M_XOR(a, b, c)
Definition: codegen.hpp:296
#define M_SST(a, b, disp)
Definition: codegen.hpp:212
#define M_DIVX(rs1, rs2, rd)
Definition: codegen.hpp:313
constant_FMIref * fieldref
Definition: resolve.hpp:88
int32_t offset
Definition: field.hpp:66
classinfo * clazz
Definition: method.hpp:80
#define M_CVTFL(a, c)
Definition: codegen.hpp:525
#define M_JMP(a, b)
Definition: codegen.hpp:259
void emit_label_br(codegendata *cd, s4 label)
#define M_CMOVFLT_IMM(rs, rd)
Definition: codegen.hpp:347
#define REG_ITMP2_XPTR
Definition: md-abi.hpp:56
#define BRANCH_LABEL_3
Definition: emit-common.hpp:49
s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg)
Definition: emit-common.cpp:82
bool checksync
Definition: options.cpp:90
imm_union * value
Definition: field.hpp:67
#define IS_FLT_DBL_TYPE(a)
Definition: global.hpp:131
void emit_beq_xcc(codegendata *cd, basicblock *target)
Definition: emit.cpp:444
#define M_ALD_INTERN(a, b, disp)
Definition: codegen.hpp:207
#define M_DCMP(a, b)
Definition: codegen.hpp:718
#define M_FADD(a, b, c)
Definition: codegen.hpp:373
s4 flags
Definition: class.hpp:90
typedesc * fd
Definition: references.hpp:74
s4 * local_map
Definition: jit.hpp:153
#define M_SRL_IMM(a, b, c)
Definition: codegen.hpp:312
#define REG_FTMP2
Definition: md-abi.hpp:66
#define M_MULX_IMM(rs1, rs2, rd)
Definition: codegen.hpp:312
#define REG_RESULT_CALLER
Definition: md-abi.hpp:39
MIIterator i
#define M_SLLX_IMM(rs1, rs2, rd)
Definition: codegen.hpp:292
s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
Definition: emit.cpp:66
typedesc returntype
Definition: descriptor.hpp:166
#define M_XCMOVGT_IMM(rs, rd)
Definition: codegen.hpp:341
s4 get_lopart_disp(disp)
Definition: codegen.cpp:84
#define BRANCH_LABEL_4
Definition: emit-common.hpp:50
int32_t s4
Definition: types.hpp:45
s4 dseg_add_unique_s4(codegendata *cd, s4 value)
Definition: dseg.cpp:229
int * savfltregs
Definition: reg.hpp:73
classinfo * clazz
Definition: field.hpp:55
registerdata * rd
Definition: jit.hpp:130
#define M_AST(a, b, disp)
Definition: codegen.hpp:350
s4 index
Definition: class.hpp:116
#define JITSTACK
Definition: md-abi.hpp:117
#define M_CVTIF(a, d)
Definition: codegen.hpp:722
union instruction::@12 sx
void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
Definition: emit.cpp:346
#define REG_PV
Definition: codegen.cpp:72
#define ABIPARAMS_CNT
Definition: md-abi.hpp:112
#define M_SUB_IMM(d, a, i)
Definition: codegen.hpp:439
void asm_handle_exception(void)
#define PATCHER_checkcast_interface
#define M_ASLL_IMM(a, b, c)
Definition: codegen.hpp:581
int savfltreguse
Definition: reg.hpp:91
#define M_MOV(a, b)
Definition: codegen.hpp:340
bool inmemory
Definition: descriptor.hpp:151
#define M_RETURN(rs1, imm)
Definition: codegen.hpp:548
#define REG_ITMP2
Definition: md-abi.hpp:47
void emit_store_dst(jitdata *jd, instruction *iptr, s4 d)
s1_operand_t s1
basicblock * block
Definition: instruction.hpp:50
#define PATCHER_invokestatic_special
#define M_BST(a, b, disp)
Definition: codegen.hpp:211
#define FLT_SAV_CNT
Definition: md-abi.hpp:80
#define BRANCH_LABEL_1
Definition: emit-common.hpp:47
#define M_FMOV_INTERN(rs, rd)
Definition: codegen.hpp:556
vftbl_t * vftbl
Definition: class.hpp:121
void codegen_emit_stub_compiler(jitdata *jd)
Definition: codegen.cpp:2474
#define M_FST_INTERN(a, b, disp)
Definition: codegen.hpp:341
methoddesc * parseddesc
Definition: method.hpp:78
#define M_SRA_IMM(a, b, c)
Definition: codegen.hpp:311
#define M_FDIV(a, b, c)
Definition: codegen.hpp:379
#define REG_FTMP1
Definition: md-abi.hpp:65
#define M_AND_IMM(a, b, c)
Definition: codegen.hpp:298
#define PATCHER_invokevirtual
Definition: builtin.hpp:60
#define M_SLL_IMM(a, b, c)
Definition: codegen.hpp:310
#define M_DSUB(a, b, c)
Definition: codegen.hpp:376
methodinfo * m
Definition: jit.hpp:127
static bool IS_INMEMORY(s4 flags)
Definition: stack.hpp:51
s4 type
Definition: field.hpp:60
void codegen_emit_epilog(jitdata *jd)
Generates machine code for the method epilog.
Definition: codegen.cpp:174
#define s3
Definition: md-asm.hpp:71
#define M_AST_INTERN(a, b, c)
Definition: codegen.hpp:1167
#define FLT_ARG_CNT
Definition: md-abi.hpp:81
s4 flags
Definition: reg.hpp:45
void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1)
Definition: emit.cpp:396
#define REG_METHODPTR
Definition: md-abi.hpp:43
#define M_FMUL(a, b, c)
Definition: codegen.hpp:377
#define M_LDX_INTERN(rd, rs, disp)
Definition: codegen.hpp:431
void asm_handle_nat_exception(void)
#define M_BLDS(a, b, disp)
Definition: codegen.hpp:149
#define M_DLD_INTERN(a, b, disp)
Definition: codegen.hpp:315
int8_t s1
Definition: types.hpp:39
#define LCONST(d, c)
Definition: codegen.hpp:54
static bool class_is_or_almost_initialized(classinfo *c)
Definition: class.hpp:433
static int code_is_synchronized(codeinfo *code)
Definition: code.hpp:173
int16_t s2
Definition: types.hpp:42
#define M_RESTORE(rs1, rs2, rd)
Definition: codegen.hpp:540
#define M_DST(a, b, disp)
Definition: codegen.hpp:356
#define INSTRUCTION_IS_UNRESOLVED(iptr)
struct instruction::@12::@13 s23
bool fits_13(s4 disp)
Definition: codegen.cpp:74
#define M_XCMOVULE_IMM(rs, rd)
Definition: codegen.hpp:342
#define REG_ZERO
Definition: md-abi.hpp:54
void codegen_emit_prolog(jitdata *jd)
Generates machine code for the method prolog.
Definition: codegen.cpp:73
#define REG_FTMP3
Definition: md-abi.hpp:67
#define BRANCH_ULT
const parseddesc_t parseddesc
Definition: references.hpp:105
static void emit_fmove(codegendata *cd, int s, int d)
Generates a float-move from register s to d.
#define M_XCMOVLT_IMM(rs, rd)
Definition: codegen.hpp:338
#define REG_ITMP3
Definition: md-abi.hpp:48
#define M_ADD(d, a, b)
Definition: codegen.hpp:421
#define MCODECHECK(icnt)
Definition: codegen.hpp:40
#define BRANCH_LABEL_2
Definition: emit-common.hpp:48
#define M_SUB(d, a, b)
Definition: codegen.hpp:423
functionptr fp
Definition: builtin.hpp:63
#define M_BLE(off)
Definition: codegen.hpp:487
#define M_SRLX(rs1, rs2, rd)
Definition: codegen.hpp:295
void emit_label(codegendata *cd, s4 label)
#define WINSAVE_CNT
Definition: md-abi.hpp:111
#define M_CLR(c)
Definition: codegen.hpp:303
s4 flags
Definition: method.hpp:70
#define M_SLDU(a, b, disp)
Definition: codegen.hpp:178
#define REG_PV_CALLEE
Definition: md-abi.hpp:44
bool check_13bit_imm(s8 imm)
Definition: codegen.cpp:101
#define M_NOP
Definition: codegen.hpp:338
#define M_FBU(disp)
Definition: codegen.hpp:531
#define M_CVTDF(b, c)
Definition: codegen.hpp:391
void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
Definition: emit.cpp:362
static void emit_dmove(codegendata *cd, int s, int d)
Generates an double-move from register s to d.
#define M_DLD(a, b, disp)
Definition: codegen.hpp:353
#define M_DDIV(a, b, c)
Definition: codegen.hpp:380
void emit_verbosecall_exit(jitdata *jd)
Definition: emit.cpp:766
uint32_t regoff
Definition: descriptor.hpp:153
#define M_SAVE_REG(rs1, rs2, rd)
Definition: codegen.hpp:539
#define M_AADD(a, b, c)
Definition: codegen.hpp:578
s4 dseg_add_float(codegendata *cd, float value)
Definition: dseg.cpp:392
#define M_BNEZ(a, disp)
Definition: codegen.hpp:255
#define OFFSET(s, el)
Definition: memory.hpp:90
#define printf(...)
Definition: ssa2.cpp:40
#define M_SLDS(a, b, disp)
Definition: codegen.hpp:151
branch_target_t * table
#define REG_OUT1
Definition: md-abi.hpp:64
void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
Definition: codegen.cpp:2500
bool codegen_emit(jitdata *jd)
Generates machine code.
#define M_INTMOVE(a, b)
void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
Definition: emit.cpp:431
#define REG_ITMP1
Definition: md-abi.hpp:46
#define M_DMOV(b, c)
Definition: codegen.hpp:342
static VM * get_current()
Definition: vm.hpp:99
#define M_DST_INTERN(a, b, disp)
Definition: codegen.hpp:342
#define M_ILD_INTERN(a, b, disp)
Definition: codegen.hpp:180
#define M_DADD(a, b, c)
Definition: codegen.hpp:374