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