CACAO
codegen.cpp
Go to the documentation of this file.
1 /* src/vm/jit/x86_64/codegen.cpp - machine code generator for x86_64
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 
26 #include "config.h"
27 
28 #include <cassert>
29 #include <cstdio>
30 #include <stdint.h>
31 
32 #include "vm/types.hpp"
33 #include "vm/os.hpp"
34 
35 #include "md-abi.hpp"
36 
38 #include "vm/jit/x86_64/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/options.hpp"
52 #include "vm/primitive.hpp"
53 #include "vm/statistics.hpp"
54 #include "vm/vm.hpp"
55 
56 #include "vm/jit/abi.hpp"
57 #include "vm/jit/asmpart.hpp"
58 #include "vm/jit/builtin.hpp"
59 #include "vm/jit/code.hpp"
61 #include "vm/jit/dseg.hpp"
62 #include "vm/jit/emit-common.hpp"
63 #include "vm/jit/jit.hpp"
65 #include "vm/jit/methodheader.hpp"
66 #include "vm/jit/parse.hpp"
68 #include "vm/jit/reg.hpp"
69 #include "vm/jit/stacktrace.hpp"
70 #include "vm/jit/trap.hpp"
71 
72 
73 /**
74  * Generates machine code for the method prolog.
75  */
77 {
78  varinfo* var;
79  methoddesc* md;
80  int32_t s1;
81  int32_t p, t, l;
82  int32_t varindex;
83  int i;
84 
85  // Get required compiler data.
86  methodinfo* m = jd->m;
87  codegendata* cd = jd->cd;
88  registerdata* rd = jd->rd;
89 
90  /* create stack frame (if necessary) */
91 
92  if (cd->stackframesize)
94 
95  /* save used callee saved registers */
96 
97  p = cd->stackframesize;
98  for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
99  p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
100  }
101  for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
102  p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
103  }
104 
105  /* take arguments out of register or stack frame */
106 
107  md = m->parseddesc;
108 
109  for (p = 0, l = 0; p < md->paramcount; p++) {
110  t = md->paramtypes[p].type;
111 
112  varindex = jd->local_map[l * 5 + t];
113 
114  l++;
115  if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
116  l++;
117 
118  if (varindex == jitdata::UNUSED)
119  continue;
120 
121  var = VAR(varindex);
122 
123  s1 = md->params[p].regoff;
124 
125  if (IS_INT_LNG_TYPE(t)) { /* integer args */
126  if (!md->params[p].inmemory) { /* register arguments */
127  if (!IS_INMEMORY(var->flags))
128  M_INTMOVE(s1, var->vv.regoff);
129  else
130  M_LST(s1, REG_SP, var->vv.regoff);
131  }
132  else { /* stack arguments */
133  if (!IS_INMEMORY(var->flags))
134  /* + 8 for return address */
135  M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
136  else
137  var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
138  }
139  }
140  else { /* floating args */
141  // With SSE, the fst/dld instructions don't actually mean "store a
142  // float/double to memory", but rather "store the lower 32/64 bits
143  // of the register to memory". Therefore we get by with treating
144  // all floating point values the same.
145  if (!md->params[p].inmemory) { /* register arguments */
146  if (!IS_INMEMORY(var->flags))
147  emit_fmove(cd, s1, var->vv.regoff);
148  else
149  M_DST(s1, REG_SP, var->vv.regoff);
150  }
151  else { /* stack arguments */
152  if (!IS_INMEMORY(var->flags))
153  M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
154  else
155  var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
156  }
157  }
158  }
159 }
160 
161 
162 /**
163  * Generates machine code for the method epilog.
164  */
166 {
167  int32_t p;
168  int i;
169 
170  // Get required compiler data.
171  codegendata* cd = jd->cd;
172  registerdata* rd = jd->rd;
173 
174  p = cd->stackframesize;
175 
176  /* restore saved registers */
177 
178  for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
179  p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
180  }
181  for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
182  p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
183  }
184 
185  /* deallocate stack */
186 
187  if (cd->stackframesize)
188  M_AADD_IMM(cd->stackframesize * 8, REG_SP);
189 
190  M_RET;
191 }
192 
193 /**
194  * Generates a memory barrier to be used after volatile writes. It can be
195  * patched out later if the field turns out not to be volatile.
196  */
198 {
199  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
200  /* Align on word boundary */
201  if ((((intptr_t) cd->mcodeptr) & 3) >= 2)
202  emit_nop(cd, 4 - (((intptr_t) cd->mcodeptr) & 3));
203  /* Displacement for patching out MFENCE */
204  pr->disp_mb = (cd->mcodeptr - cd->mcodebase - pr->mpc);
205  }
206  if (INSTRUCTION_IS_UNRESOLVED(iptr) || fi->flags & ACC_VOLATILE)
207  M_MFENCE;
208 }
209 
210 /**
211  * Ensures that the patched location (an int32_t) is aligned.
212  */
213 static void codegen_fixup_alignment(codegendata *cd, patchref_t *pr, u1 *mcodeptr_save)
214 {
215  u1 *codeptr = cd->mcodeptr;
216  int disp = PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 0, sizeof(int32_t));
217  memmove(mcodeptr_save + disp, mcodeptr_save, cd->mcodeptr - mcodeptr_save);
218  pr->patch_align += cd->mcodeptr - mcodeptr_save + disp;
219 
220  cd->mcodeptr = mcodeptr_save;
221  emit_arbitrary_nop(cd, disp);
222  cd->mcodeptr = codeptr + disp;
223 }
224 
225 /**
226  * Generates machine code for one ICMD.
227  */
229 {
230  varinfo* var;
231  varinfo* dst;
232  builtintable_entry* bte;
233  methodinfo* lm; // Local methodinfo for ICMD_INVOKE*.
234  unresolved_method* um;
235  fieldinfo* fi;
236  unresolved_field* uf;
237  patchref_t* pr;
238  int32_t fieldtype;
239  int32_t s1, s2, s3, d;
240  int32_t disp;
241  u1* mcodeptr_save = NULL;
242 
243  // Get required compiler data.
244  codegendata* cd = jd->cd;
245 
246  switch (iptr->opc) {
247 
248  /* constant operations ************************************************/
249 
250  case ICMD_FCONST: /* ... ==> ..., constant */
251 
252  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
253  disp = dseg_add_float(cd, iptr->sx.val.f);
254  emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
255  emit_store_dst(jd, iptr, d);
256  break;
257 
258  case ICMD_DCONST: /* ... ==> ..., constant */
259 
260  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
261  disp = dseg_add_double(cd, iptr->sx.val.d);
262  emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
263  emit_store_dst(jd, iptr, d);
264  break;
265 
266  case ICMD_ACONST: /* ... ==> ..., constant */
267 
268  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
269 
270  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
271  constant_classref *cr = iptr->sx.val.c.ref;
272  disp = dseg_add_unique_address(cd, cr);
273 
274 /* PROFILE_CYCLE_STOP; */
275 
277  cr, disp);
278 
279 /* PROFILE_CYCLE_START; */
280 
281  M_ALD(d, RIP, disp);
282  }
283  else {
284  if (iptr->sx.val.anyptr == 0) {
285  M_CLR(d);
286  }
287  else {
288  disp = dseg_add_address(cd, iptr->sx.val.anyptr);
289  M_ALD(d, RIP, disp);
290  }
291  }
292  emit_store_dst(jd, iptr, d);
293  break;
294 
295 
296  /* integer operations *************************************************/
297 
298  case ICMD_INEG: /* ..., value ==> ..., - value */
299 
300  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
301  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
302  M_INTMOVE(s1, d);
303  M_INEG(d);
304  emit_store_dst(jd, iptr, d);
305  break;
306 
307  case ICMD_LNEG: /* ..., value ==> ..., - value */
308 
309  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
310  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
311  M_INTMOVE(s1, d);
312  M_LNEG(d);
313  emit_store_dst(jd, iptr, d);
314  break;
315 
316  case ICMD_I2L: /* ..., value ==> ..., value */
317 
318  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
319  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
320  M_ISEXT(s1, d);
321  emit_store_dst(jd, iptr, d);
322  break;
323 
324  case ICMD_L2I: /* ..., value ==> ..., value */
325 
326  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
327  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
328  M_IMOV(s1, d);
329  emit_store_dst(jd, iptr, d);
330  break;
331 
332  case ICMD_INT2BYTE: /* ..., value ==> ..., value */
333 
334  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
335  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
336  M_BSEXT(s1, d);
337  emit_store_dst(jd, iptr, d);
338  break;
339 
340  case ICMD_INT2CHAR: /* ..., value ==> ..., value */
341 
342  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
343  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
344  M_CZEXT(s1, d);
345  emit_store_dst(jd, iptr, d);
346  break;
347 
348  case ICMD_INT2SHORT: /* ..., value ==> ..., value */
349 
350  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
351  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
352  M_SSEXT(s1, d);
353  emit_store_dst(jd, iptr, d);
354  break;
355 
356 
357  case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
358 
359  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
360  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
361  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
362  if (s2 == d)
363  M_IADD(s1, d);
364  else {
365  M_INTMOVE(s1, d);
366  M_IADD(s2, d);
367  }
368  emit_store_dst(jd, iptr, d);
369  break;
370 
371  case ICMD_IINC:
372  case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
373  /* sx.val.i = constant */
374 
375  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
376  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
377 
378  /* Using inc and dec is not faster than add (tested with
379  sieve). */
380 
381  M_INTMOVE(s1, d);
382  M_IADD_IMM(iptr->sx.val.i, d);
383  emit_store_dst(jd, iptr, d);
384  break;
385 
386  case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
387 
388  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
389  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
390  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
391  if (s2 == d)
392  M_LADD(s1, d);
393  else {
394  M_INTMOVE(s1, d);
395  M_LADD(s2, d);
396  }
397  emit_store_dst(jd, iptr, d);
398  break;
399 
400  case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
401  /* sx.val.l = constant */
402 
403  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
404  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
405  M_INTMOVE(s1, d);
406  if (IS_IMM32(iptr->sx.val.l))
407  M_LADD_IMM(iptr->sx.val.l, d);
408  else {
409  M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
410  M_LADD(REG_ITMP2, d);
411  }
412  emit_store_dst(jd, iptr, d);
413  break;
414 
415  case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
416 
417  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
418  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
419  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
420  if (s2 == d) {
421  M_INTMOVE(s1, REG_ITMP1);
422  M_ISUB(s2, REG_ITMP1);
423  M_INTMOVE(REG_ITMP1, d);
424  } else {
425  M_INTMOVE(s1, d);
426  M_ISUB(s2, d);
427  }
428  emit_store_dst(jd, iptr, d);
429  break;
430 
431  case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
432  /* sx.val.i = constant */
433 
434  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
435  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
436  M_INTMOVE(s1, d);
437  M_ISUB_IMM(iptr->sx.val.i, d);
438  emit_store_dst(jd, iptr, d);
439  break;
440 
441  case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
442 
443  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
444  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
445  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
446  if (s2 == d) {
447  M_INTMOVE(s1, REG_ITMP1);
448  M_LSUB(s2, REG_ITMP1);
449  M_INTMOVE(REG_ITMP1, d);
450  } else {
451  M_INTMOVE(s1, d);
452  M_LSUB(s2, d);
453  }
454  emit_store_dst(jd, iptr, d);
455  break;
456 
457  case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
458  /* sx.val.l = constant */
459 
460  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
461  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
462  M_INTMOVE(s1, d);
463  if (IS_IMM32(iptr->sx.val.l))
464  M_LSUB_IMM(iptr->sx.val.l, d);
465  else {
466  M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
467  M_LSUB(REG_ITMP2, d);
468  }
469  emit_store_dst(jd, iptr, d);
470  break;
471 
472  case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
473 
474  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
475  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
476  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
477  if (s2 == d)
478  M_IMUL(s1, d);
479  else {
480  M_INTMOVE(s1, d);
481  M_IMUL(s2, d);
482  }
483  emit_store_dst(jd, iptr, d);
484  break;
485 
486  case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
487  /* sx.val.i = constant */
488 
489  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
490  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
491  if (iptr->sx.val.i == 2) {
492  M_INTMOVE(s1, d);
493  M_ISLL_IMM(1, d);
494  } else
495  M_IMUL_IMM(s1, iptr->sx.val.i, d);
496  emit_store_dst(jd, iptr, d);
497  break;
498 
499  case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
500 
501  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
502  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
503  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
504  if (s2 == d)
505  M_LMUL(s1, d);
506  else {
507  M_INTMOVE(s1, d);
508  M_LMUL(s2, d);
509  }
510  emit_store_dst(jd, iptr, d);
511  break;
512 
513  case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
514  /* sx.val.l = constant */
515 
516  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
517  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
518  if (IS_IMM32(iptr->sx.val.l))
519  M_LMUL_IMM(s1, iptr->sx.val.l, d);
520  else {
521  M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
522  M_INTMOVE(s1, d);
523  M_LMUL(REG_ITMP2, d);
524  }
525  emit_store_dst(jd, iptr, d);
526  break;
527 
528  case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
529 
530  s1 = emit_load_s1(jd, iptr, RAX);
531  s2 = emit_load_s2(jd, iptr, REG_ITMP3);
532  d = codegen_reg_of_dst(jd, iptr, RAX);
533 
534  M_INTMOVE(s1, RAX);
535  M_INTMOVE(s2, REG_ITMP3);
536  emit_arithmetic_check(cd, iptr, REG_ITMP3);
537 
538  M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
539 
540  M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
541  M_BNE(4 + 6);
542  M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
543  M_BEQ(1 + 3); /* 6 bytes */
544 
545  emit_cltd(cd); /* 1 byte */
546  emit_idivl_reg(cd, REG_ITMP3); /* 3 bytes */
547 
548  M_INTMOVE(RAX, d);
549  emit_store_dst(jd, iptr, d);
550  dst = VAROP(iptr->dst);
551  if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
552  M_MOV(REG_ITMP2, RDX); /* restore RDX */
553  break;
554 
555  case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
556 
557  s1 = emit_load_s1(jd, iptr, RAX);
558  s2 = emit_load_s2(jd, iptr, REG_ITMP3);
559  d = codegen_reg_of_dst(jd, iptr, RDX);
560 
561  M_INTMOVE(s1, RAX);
562  M_INTMOVE(s2, REG_ITMP3);
563  emit_arithmetic_check(cd, iptr, REG_ITMP3);
564 
565  M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
566 
567  M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
568  M_BNE(3 + 4 + 6);
569  M_CLR(RDX); /* 3 bytes */
570  M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
571  M_BEQ(1 + 3); /* 6 bytes */
572 
573  emit_cltd(cd); /* 1 byte */
574  emit_idivl_reg(cd, REG_ITMP3); /* 3 byte */
575 
576  M_INTMOVE(RDX, d);
577  emit_store_dst(jd, iptr, d);
578  dst = VAROP(iptr->dst);
579  if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
580  M_MOV(REG_ITMP2, RDX); /* restore RDX */
581  break;
582 
583  case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
584  /* sx.val.i = constant */
585 
586  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
587  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
588  M_INTMOVE(s1, REG_ITMP1);
590  emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
593  emit_mov_reg_reg(cd, REG_ITMP1, d);
594  emit_store_dst(jd, iptr, d);
595  break;
596 
597  case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
598  /* sx.val.i = constant */
599 
600  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
601  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
602  M_INTMOVE(s1, REG_ITMP1);
606  emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
608  emit_mov_reg_reg(cd, REG_ITMP1, d);
609  emit_store_dst(jd, iptr, d);
610  break;
611 
612 
613  case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
614 
615  s1 = emit_load_s1(jd, iptr, RAX);
616  s2 = emit_load_s2(jd, iptr, REG_ITMP3);
617  d = codegen_reg_of_dst(jd, iptr, RAX);
618 
619  M_INTMOVE(s1, RAX);
620  M_INTMOVE(s2, REG_ITMP3);
621  emit_arithmetic_check(cd, iptr, REG_ITMP3);
622 
623  M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
624 
625  /* check as described in jvm spec */
626  disp = dseg_add_s8(cd, 0x8000000000000000LL);
627  M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
628  M_BNE(4 + 6);
629  M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
630  M_BEQ(2 + 3); /* 6 bytes */
631 
632  emit_cqto(cd); /* 2 bytes */
633  emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
634 
635  M_INTMOVE(RAX, d);
636  emit_store_dst(jd, iptr, d);
637  dst = VAROP(iptr->dst);
638  if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
639  M_MOV(REG_ITMP2, RDX); /* restore RDX */
640  break;
641 
642  case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
643 
644  s1 = emit_load_s1(jd, iptr, RAX);
645  s2 = emit_load_s2(jd, iptr, REG_ITMP3);
646  d = codegen_reg_of_dst(jd, iptr, RDX);
647 
648  M_INTMOVE(s1, RAX);
649  M_INTMOVE(s2, REG_ITMP3);
650  emit_arithmetic_check(cd, iptr, REG_ITMP3);
651 
652  M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
653 
654  /* check as described in jvm spec */
655  disp = dseg_add_s8(cd, 0x8000000000000000LL);
656  M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
657  M_BNE(3 + 4 + 6);
658  M_LXOR(RDX, RDX); /* 3 bytes */
659  M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
660  M_BEQ(2 + 3); /* 6 bytes */
661 
662  emit_cqto(cd); /* 2 bytes */
663  emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
664 
665  M_INTMOVE(RDX, d);
666  emit_store_dst(jd, iptr, d);
667  dst = VAROP(iptr->dst);
668  if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
669  M_MOV(REG_ITMP2, RDX); /* restore RDX */
670  break;
671 
672  case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
673  /* sx.val.i = constant */
674 
675  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
676  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
677  M_INTMOVE(s1, REG_ITMP1);
679  emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
682  emit_mov_reg_reg(cd, REG_ITMP1, d);
683  emit_store_dst(jd, iptr, d);
684  break;
685 
686  case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
687  /* sx.val.l = constant */
688 
689  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
690  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
691  M_INTMOVE(s1, REG_ITMP1);
695  emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
697  emit_mov_reg_reg(cd, REG_ITMP1, d);
698  emit_store_dst(jd, iptr, d);
699  break;
700 
701  case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
702 
703  d = codegen_reg_of_dst(jd, iptr, REG_NULL);
704  emit_ishift(jd, SHIFT_SHL, iptr);
705  break;
706 
707  case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
708  /* sx.val.i = constant */
709 
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_ISLL_IMM(iptr->sx.val.i, d);
714  emit_store_dst(jd, iptr, d);
715  break;
716 
717  case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
718 
719  d = codegen_reg_of_dst(jd, iptr, REG_NULL);
720  emit_ishift(jd, SHIFT_SAR, iptr);
721  break;
722 
723  case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
724  /* sx.val.i = constant */
725 
726  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
727  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
728  M_INTMOVE(s1, d);
729  M_ISRA_IMM(iptr->sx.val.i, d);
730  emit_store_dst(jd, iptr, d);
731  break;
732 
733  case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
734 
735  d = codegen_reg_of_dst(jd, iptr, REG_NULL);
736  emit_ishift(jd, SHIFT_SHR, iptr);
737  break;
738 
739  case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
740  /* sx.val.i = constant */
741 
742  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
743  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
744  M_INTMOVE(s1, d);
745  M_ISRL_IMM(iptr->sx.val.i, d);
746  emit_store_dst(jd, iptr, d);
747  break;
748 
749  case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
750 
751  d = codegen_reg_of_dst(jd, iptr, REG_NULL);
752  emit_lshift(jd, SHIFT_SHL, iptr);
753  break;
754 
755  case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
756  /* sx.val.i = constant */
757 
758  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
759  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
760  M_INTMOVE(s1, d);
761  M_LSLL_IMM(iptr->sx.val.i, d);
762  emit_store_dst(jd, iptr, d);
763  break;
764 
765  case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
766 
767  d = codegen_reg_of_dst(jd, iptr, REG_NULL);
768  emit_lshift(jd, SHIFT_SAR, iptr);
769  break;
770 
771  case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
772  /* sx.val.i = constant */
773 
774  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
775  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
776  M_INTMOVE(s1, d);
777  M_LSRA_IMM(iptr->sx.val.i, d);
778  emit_store_dst(jd, iptr, d);
779  break;
780 
781  case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
782 
783  d = codegen_reg_of_dst(jd, iptr, REG_NULL);
784  emit_lshift(jd, SHIFT_SHR, iptr);
785  break;
786 
787  case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
788  /* sx.val.l = constant */
789 
790  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
791  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
792  M_INTMOVE(s1, d);
793  M_LSRL_IMM(iptr->sx.val.i, d);
794  emit_store_dst(jd, iptr, d);
795  break;
796 
797  case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
798 
799  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
800  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
801  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
802  if (s2 == d)
803  M_IAND(s1, d);
804  else {
805  M_INTMOVE(s1, d);
806  M_IAND(s2, d);
807  }
808  emit_store_dst(jd, iptr, d);
809  break;
810 
811  case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
812  /* sx.val.i = constant */
813 
814  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
815  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
816  M_INTMOVE(s1, d);
817  M_IAND_IMM(iptr->sx.val.i, d);
818  emit_store_dst(jd, iptr, d);
819  break;
820 
821  case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
822 
823  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
824  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
825  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
826  if (s2 == d)
827  M_LAND(s1, d);
828  else {
829  M_INTMOVE(s1, d);
830  M_LAND(s2, d);
831  }
832  emit_store_dst(jd, iptr, d);
833  break;
834 
835  case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
836  /* sx.val.l = constant */
837 
838  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
839  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
840  M_INTMOVE(s1, d);
841  if (IS_IMM32(iptr->sx.val.l))
842  M_LAND_IMM(iptr->sx.val.l, d);
843  else {
844  M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
845  M_LAND(REG_ITMP2, d);
846  }
847  emit_store_dst(jd, iptr, d);
848  break;
849 
850  case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
851 
852  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
853  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
854  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
855  if (s2 == d)
856  M_IOR(s1, d);
857  else {
858  M_INTMOVE(s1, d);
859  M_IOR(s2, d);
860  }
861  emit_store_dst(jd, iptr, d);
862  break;
863 
864  case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
865  /* sx.val.i = constant */
866 
867  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
868  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
869  M_INTMOVE(s1, d);
870  M_IOR_IMM(iptr->sx.val.i, d);
871  emit_store_dst(jd, iptr, d);
872  break;
873 
874  case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
875 
876  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
877  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
878  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
879  if (s2 == d)
880  M_LOR(s1, d);
881  else {
882  M_INTMOVE(s1, d);
883  M_LOR(s2, d);
884  }
885  emit_store_dst(jd, iptr, d);
886  break;
887 
888  case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
889  /* sx.val.l = constant */
890 
891  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
892  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
893  M_INTMOVE(s1, d);
894  if (IS_IMM32(iptr->sx.val.l))
895  M_LOR_IMM(iptr->sx.val.l, d);
896  else {
897  M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
898  M_LOR(REG_ITMP2, d);
899  }
900  emit_store_dst(jd, iptr, d);
901  break;
902 
903  case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
904 
905  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
906  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
907  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
908  if (s2 == d)
909  M_IXOR(s1, d);
910  else {
911  M_INTMOVE(s1, d);
912  M_IXOR(s2, d);
913  }
914  emit_store_dst(jd, iptr, d);
915  break;
916 
917  case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
918  /* sx.val.i = constant */
919 
920  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
921  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
922  M_INTMOVE(s1, d);
923  M_IXOR_IMM(iptr->sx.val.i, d);
924  emit_store_dst(jd, iptr, d);
925  break;
926 
927  case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
928 
929  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
930  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
931  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
932  if (s2 == d)
933  M_LXOR(s1, d);
934  else {
935  M_INTMOVE(s1, d);
936  M_LXOR(s2, d);
937  }
938  emit_store_dst(jd, iptr, d);
939  break;
940 
941  case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
942  /* sx.val.l = constant */
943 
944  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
945  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
946  M_INTMOVE(s1, d);
947  if (IS_IMM32(iptr->sx.val.l))
948  M_LXOR_IMM(iptr->sx.val.l, d);
949  else {
950  M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
951  M_LXOR(REG_ITMP2, d);
952  }
953  emit_store_dst(jd, iptr, d);
954  break;
955 
956 
957  /* floating operations ************************************************/
958 
959  case ICMD_FNEG: /* ..., value ==> ..., - value */
960 
961  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
962  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
963  disp = dseg_add_s4(cd, 0x80000000);
964  emit_fmove(cd, s1, d);
965  emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
967  emit_store_dst(jd, iptr, d);
968  break;
969 
970  case ICMD_DNEG: /* ..., value ==> ..., - value */
971 
972  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
973  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
974  disp = dseg_add_s8(cd, 0x8000000000000000);
975  emit_fmove(cd, s1, d);
976  emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
978  emit_store_dst(jd, iptr, d);
979  break;
980 
981  case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
982 
983  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
984  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
985  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
986  if (s2 == d)
987  M_FADD(s1, d);
988  else {
989  emit_fmove(cd, s1, d);
990  M_FADD(s2, d);
991  }
992  emit_store_dst(jd, iptr, d);
993  break;
994 
995  case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
996 
997  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
998  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
999  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1000  if (s2 == d)
1001  M_DADD(s1, d);
1002  else {
1003  emit_fmove(cd, s1, d);
1004  M_DADD(s2, d);
1005  }
1006  emit_store_dst(jd, iptr, d);
1007  break;
1008 
1009  case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1010 
1011  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1012  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1013  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1014  if (s2 == d) {
1015  emit_fmove(cd, s2, REG_FTMP2);
1016  s2 = REG_FTMP2;
1017  }
1018  emit_fmove(cd, s1, d);
1019  M_FSUB(s2, d);
1020  emit_store_dst(jd, iptr, d);
1021  break;
1022 
1023  case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1024 
1025  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1026  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1027  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1028  if (s2 == d) {
1029  emit_fmove(cd, s2, REG_FTMP2);
1030  s2 = REG_FTMP2;
1031  }
1032  emit_fmove(cd, s1, d);
1033  M_DSUB(s2, d);
1034  emit_store_dst(jd, iptr, d);
1035  break;
1036 
1037  case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1038 
1039  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1040  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1041  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1042  if (s2 == d)
1043  M_FMUL(s1, d);
1044  else {
1045  emit_fmove(cd, s1, d);
1046  M_FMUL(s2, d);
1047  }
1048  emit_store_dst(jd, iptr, d);
1049  break;
1050 
1051  case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1052 
1053  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1054  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1055  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1056  if (s2 == d)
1057  M_DMUL(s1, d);
1058  else {
1059  emit_fmove(cd, s1, d);
1060  M_DMUL(s2, d);
1061  }
1062  emit_store_dst(jd, iptr, d);
1063  break;
1064 
1065  case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1066 
1067  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1068  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1069  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1070  if (s2 == d) {
1071  emit_fmove(cd, s2, REG_FTMP2);
1072  s2 = REG_FTMP2;
1073  }
1074  emit_fmove(cd, s1, d);
1075  M_FDIV(s2, d);
1076  emit_store_dst(jd, iptr, d);
1077  break;
1078 
1079  case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1080 
1081  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1082  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1083  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1084  if (s2 == d) {
1085  emit_fmove(cd, s2, REG_FTMP2);
1086  s2 = REG_FTMP2;
1087  }
1088  emit_fmove(cd, s1, d);
1089  M_DDIV(s2, d);
1090  emit_store_dst(jd, iptr, d);
1091  break;
1092 
1093  case ICMD_I2F: /* ..., value ==> ..., (float) value */
1094 
1095  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1096  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1097  M_CVTIF(s1, d);
1098  emit_store_dst(jd, iptr, d);
1099  break;
1100 
1101  case ICMD_I2D: /* ..., value ==> ..., (double) value */
1102 
1103  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1104  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1105  M_CVTID(s1, d);
1106  emit_store_dst(jd, iptr, d);
1107  break;
1108 
1109  case ICMD_L2F: /* ..., value ==> ..., (float) value */
1110 
1111  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1112  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1113  M_CVTLF(s1, d);
1114  emit_store_dst(jd, iptr, d);
1115  break;
1116 
1117  case ICMD_L2D: /* ..., value ==> ..., (double) value */
1118 
1119  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1120  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1121  M_CVTLD(s1, d);
1122  emit_store_dst(jd, iptr, d);
1123  break;
1124 
1125  case ICMD_F2I: /* ..., value ==> ..., (int) value */
1126 
1127  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1128  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1129  M_CVTFI(s1, d);
1130  M_ICMP_IMM(0x80000000, d); /* corner cases */
1131  disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1132  ((REG_RESULT == d) ? 0 : 3);
1133  M_BNE(disp);
1134  emit_fmove(cd, s1, REG_FTMP1);
1136  M_CALL(REG_ITMP2);
1137  M_INTMOVE(REG_RESULT, d);
1138  emit_store_dst(jd, iptr, d);
1139  break;
1140 
1141  case ICMD_D2I: /* ..., value ==> ..., (int) value */
1142 
1143  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1144  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1145  M_CVTDI(s1, d);
1146  M_ICMP_IMM(0x80000000, d); /* corner cases */
1147  disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1148  ((REG_RESULT == d) ? 0 : 3);
1149  M_BNE(disp);
1150  emit_fmove(cd, s1, REG_FTMP1);
1152  M_CALL(REG_ITMP2);
1153  M_INTMOVE(REG_RESULT, d);
1154  emit_store_dst(jd, iptr, d);
1155  break;
1156 
1157  case ICMD_F2L: /* ..., value ==> ..., (long) value */
1158 
1159  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1160  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1161  M_CVTFL(s1, d);
1162  M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1163  M_LCMP(REG_ITMP2, d); /* corner cases */
1164  disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1165  ((REG_RESULT == d) ? 0 : 3);
1166  M_BNE(disp);
1167  emit_fmove(cd, s1, REG_FTMP1);
1169  M_CALL(REG_ITMP2);
1170  M_INTMOVE(REG_RESULT, d);
1171  emit_store_dst(jd, iptr, d);
1172  break;
1173 
1174  case ICMD_D2L: /* ..., value ==> ..., (long) value */
1175 
1176  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1177  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1178  M_CVTDL(s1, d);
1179  M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1180  M_LCMP(REG_ITMP2, d); /* corner cases */
1181  disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1182  ((REG_RESULT == d) ? 0 : 3);
1183  M_BNE(disp);
1184  emit_fmove(cd, s1, REG_FTMP1);
1186  M_CALL(REG_ITMP2);
1187  M_INTMOVE(REG_RESULT, d);
1188  emit_store_dst(jd, iptr, d);
1189  break;
1190 
1191  case ICMD_F2D: /* ..., value ==> ..., (double) value */
1192 
1193  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1194  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1195  M_CVTFD(s1, d);
1196  emit_store_dst(jd, iptr, d);
1197  break;
1198 
1199  case ICMD_D2F: /* ..., value ==> ..., (float) value */
1200 
1201  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1202  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1203  M_CVTDF(s1, d);
1204  emit_store_dst(jd, iptr, d);
1205  break;
1206 
1207  case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1208  /* == => 0, < => 1, > => -1 */
1209 
1210  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1211  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1212  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1213  M_CLR(d);
1214  M_MOV_IMM(1, REG_ITMP1);
1215  M_MOV_IMM(-1, REG_ITMP2);
1216  emit_ucomiss_reg_reg(cd, s1, s2);
1217  M_CMOVULT(REG_ITMP1, d);
1218  M_CMOVUGT(REG_ITMP2, d);
1219  M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1220  emit_store_dst(jd, iptr, d);
1221  break;
1222 
1223  case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1224  /* == => 0, < => 1, > => -1 */
1225 
1226  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1227  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1228  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1229  M_CLR(d);
1230  M_MOV_IMM(1, REG_ITMP1);
1231  M_MOV_IMM(-1, REG_ITMP2);
1232  emit_ucomiss_reg_reg(cd, s1, s2);
1233  M_CMOVULT(REG_ITMP1, d);
1234  M_CMOVUGT(REG_ITMP2, d);
1235  M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1236  emit_store_dst(jd, iptr, d);
1237  break;
1238 
1239  case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1240  /* == => 0, < => 1, > => -1 */
1241 
1242  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1243  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1244  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1245  M_CLR(d);
1246  M_MOV_IMM(1, REG_ITMP1);
1247  M_MOV_IMM(-1, REG_ITMP2);
1248  emit_ucomisd_reg_reg(cd, s1, s2);
1249  M_CMOVULT(REG_ITMP1, d);
1250  M_CMOVUGT(REG_ITMP2, d);
1251  M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1252  emit_store_dst(jd, iptr, d);
1253  break;
1254 
1255  case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1256  /* == => 0, < => 1, > => -1 */
1257 
1258  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1259  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1260  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1261  M_CLR(d);
1262  M_MOV_IMM(1, REG_ITMP1);
1263  M_MOV_IMM(-1, REG_ITMP2);
1264  emit_ucomisd_reg_reg(cd, s1, s2);
1265  M_CMOVULT(REG_ITMP1, d);
1266  M_CMOVUGT(REG_ITMP2, d);
1267  M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1268  emit_store_dst(jd, iptr, d);
1269  break;
1270 
1271 
1272  /* memory operations **************************************************/
1273 
1274  case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1275 
1276  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1277  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1278  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1279  /* implicit null-pointer check */
1280  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1281  emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]), s1, s2, 0, d);
1282  emit_store_dst(jd, iptr, d);
1283  break;
1284 
1285  case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1286 
1287  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1288  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1289  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1290  /* implicit null-pointer check */
1291  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1292  emit_movzwq_memindex_reg(cd, OFFSET(java_chararray_t, data[0]), s1, s2, 1, d);
1293  emit_store_dst(jd, iptr, d);
1294  break;
1295 
1296  case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1297 
1298  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1299  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1300  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1301  /* implicit null-pointer check */
1302  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1303  emit_movswq_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]), s1, s2, 1, d);
1304  emit_store_dst(jd, iptr, d);
1305  break;
1306 
1307  case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1308 
1309  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1310  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1311  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1312  /* implicit null-pointer check */
1313  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1314  emit_movl_memindex_reg(cd, OFFSET(java_intarray_t, data[0]), s1, s2, 2, d);
1315  emit_store_dst(jd, iptr, d);
1316  break;
1317 
1318  case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1319 
1320  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1321  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1322  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1323  /* implicit null-pointer check */
1324  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1325  emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]), s1, s2, 3, d);
1326  emit_store_dst(jd, iptr, d);
1327  break;
1328 
1329  case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1330 
1331  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1332  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1333  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1334  /* implicit null-pointer check */
1335  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1336  emit_movss_memindex_reg(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2, d);
1337  emit_store_dst(jd, iptr, d);
1338  break;
1339 
1340  case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1341 
1342  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1343  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1344  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1345  /* implicit null-pointer check */
1346  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1347  emit_movsd_memindex_reg(cd, OFFSET(java_doublearray_t, data[0]), s1, s2, 3, d);
1348  emit_store_dst(jd, iptr, d);
1349  break;
1350 
1351  case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1352 
1353  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1354  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1355  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1356  /* implicit null-pointer check */
1357  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1358  emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]), s1, s2, 3, d);
1359  emit_store_dst(jd, iptr, d);
1360  break;
1361 
1362 
1363  case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1364 
1365  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1366  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1367  /* implicit null-pointer check */
1368  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1369  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1370  emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1371  break;
1372 
1373  case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1374 
1375  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1376  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1377  /* implicit null-pointer check */
1378  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1379  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1380  emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1381  break;
1382 
1383  case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1384 
1385  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1386  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1387  /* implicit null-pointer check */
1388  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1389  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1390  emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1391  break;
1392 
1393  case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1394 
1395  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1396  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1397  /* implicit null-pointer check */
1398  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1399  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1400  emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1401  break;
1402 
1403  case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1404 
1405  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1406  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1407  /* implicit null-pointer check */
1408  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1409  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1410  emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1411  break;
1412 
1413  case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1414 
1415  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1416  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1417  /* implicit null-pointer check */
1418  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1419  s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1420  emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
1421  break;
1422 
1423  case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1424 
1425  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1426  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1427  /* implicit null-pointer check */
1428  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1429  s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1430  emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray_t, data[0]), s1, s2, 3);
1431  break;
1432 
1433  case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1434 
1435  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1436  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1437  /* implicit null-pointer check */
1438  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1439  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1440 
1441  M_MOV(s1, REG_A0);
1442  M_MOV(s3, REG_A1);
1444  M_CALL(REG_ITMP1);
1445  emit_arraystore_check(cd, iptr);
1446 
1447  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1448  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1449  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1450  emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1451  break;
1452 
1453 
1454  case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1455 
1456  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1457  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1458  /* implicit null-pointer check */
1459  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1460  emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1461  break;
1462 
1463  case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1464 
1465  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1466  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1467  /* implicit null-pointer check */
1468  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1469  emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1470  break;
1471 
1472  case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1473 
1474  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1475  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1476  /* implicit null-pointer check */
1477  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1478  emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1479  break;
1480 
1481  case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1482 
1483  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1484  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1485  /* implicit null-pointer check */
1486  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1487  emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1488  break;
1489 
1490  case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1491 
1492  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1493  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1494  /* implicit null-pointer check */
1495  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1496 
1497  if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1498  emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1499  }
1500  else {
1501  emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1502  emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
1503  }
1504  break;
1505 
1506  case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1507 
1508  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1509  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1510  /* implicit null-pointer check */
1511  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1512  emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1513  break;
1514 
1515  case ICMD_PUTSTATICCONST: /* ... ==> ... */
1516  /* val = value (in current instruction) */
1517  /* following NOP) */
1518 
1519  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1520  uf = iptr->sx.s23.s3.uf;
1521  fieldtype = uf->fieldref->parseddesc.fd->type;
1522  disp = dseg_add_unique_address(cd, uf);
1523 
1524 /* PROFILE_CYCLE_STOP; */
1525 
1526  pr = patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1527 
1528 /* PROFILE_CYCLE_START; */
1529 
1530  fi = NULL; /* Silence compiler warning */
1531  }
1532  else {
1533  fi = iptr->sx.s23.s3.fmiref->p.field;
1534  fieldtype = fi->type;
1535  disp = dseg_add_address(cd, fi->value);
1536 
1538  //PROFILE_CYCLE_STOP;
1539 
1541  fi->clazz, 0);
1542 
1543  //PROFILE_CYCLE_START;
1544  }
1545 
1546  pr = NULL; /* Silence compiler warning */
1547  }
1548 
1549  /* This approach is much faster than moving the field
1550  address inline into a register. */
1551 
1552  M_ALD(REG_ITMP1, RIP, disp);
1553 
1554  switch (fieldtype) {
1555  case TYPE_INT:
1556  case TYPE_FLT:
1557  M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1558  break;
1559  case TYPE_LNG:
1560  case TYPE_ADR:
1561  case TYPE_DBL:
1562  if (IS_IMM32(iptr->sx.s23.s2.constval))
1563  M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1564  else {
1565  M_MOV_IMM(iptr->sx.s23.s2.constval, REG_ITMP2);
1566  M_LST(REG_ITMP2, REG_ITMP1, 0);
1567  }
1568  break;
1569  default:
1570  assert(false);
1571  break;
1572  }
1573  codegen_emit_patchable_barrier(iptr, cd, pr, fi);
1574  break;
1575 
1576  case ICMD_GETFIELD: /* ... ==> ..., value */
1577 
1578  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1579 
1580  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1581  uf = iptr->sx.s23.s3.uf;
1582  fieldtype = uf->fieldref->parseddesc.fd->type;
1583  disp = 0;
1584 
1585 /* PROFILE_CYCLE_STOP; */
1586 
1588  mcodeptr_save = cd->mcodeptr;
1589 
1590 /* PROFILE_CYCLE_START; */
1591 
1592  fi = NULL; /* Silence compiler warning */
1593  }
1594  else {
1595  fi = iptr->sx.s23.s3.fmiref->p.field;
1596  fieldtype = fi->type;
1597  disp = fi->offset;
1598 
1599  pr = 0;
1600  }
1601 
1602  /* implicit null-pointer check */
1603  switch (fieldtype) {
1604  case TYPE_INT:
1605  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1606  M_ILD32(d, s1, disp);
1607  break;
1608  case TYPE_LNG:
1609  case TYPE_ADR:
1610  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1611  M_LLD32(d, s1, disp);
1612  break;
1613  case TYPE_FLT:
1614  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1615  M_FLD32(d, s1, disp);
1616  break;
1617  case TYPE_DBL:
1618  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1619  M_DLD32(d, s1, disp);
1620  break;
1621  default:
1622  // Silence compiler warning.
1623  d = 0;
1624  }
1625  if (pr)
1626  codegen_fixup_alignment(cd, pr, mcodeptr_save);
1627  emit_store_dst(jd, iptr, d);
1628  break;
1629 
1630  case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1631 
1632  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1633  s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1634 
1635  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1636  uf = iptr->sx.s23.s3.uf;
1637  fieldtype = uf->fieldref->parseddesc.fd->type;
1638  disp = 0;
1639 
1640 /* PROFILE_CYCLE_STOP; */
1641 
1643  mcodeptr_save = cd->mcodeptr;
1644 
1645 /* PROFILE_CYCLE_START; */
1646 
1647  fi = NULL; /* Silence compiler warning */
1648  }
1649  else {
1650  fi = iptr->sx.s23.s3.fmiref->p.field;
1651  fieldtype = fi->type;
1652  disp = fi->offset;
1653 
1654  pr = NULL; /* Silence compiler warning */
1655  }
1656 
1657  /* implicit null-pointer check */
1658  switch (fieldtype) {
1659  case TYPE_INT:
1660  M_IST32(s2, s1, disp);
1661  break;
1662  case TYPE_LNG:
1663  case TYPE_ADR:
1664  M_LST32(s2, s1, disp);
1665  break;
1666  case TYPE_FLT:
1667  M_FST32(s2, s1, disp);
1668  break;
1669  case TYPE_DBL:
1670  M_DST32(s2, s1, disp);
1671  break;
1672  }
1673  if (pr)
1674  codegen_fixup_alignment(cd, pr, mcodeptr_save);
1675  codegen_emit_patchable_barrier(iptr, cd, pr, fi);
1676  break;
1677 
1678  case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
1679  /* val = value (in current instruction) */
1680  /* following NOP) */
1681 
1682  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1683 
1684  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1685  uf = iptr->sx.s23.s3.uf;
1686  fieldtype = uf->fieldref->parseddesc.fd->type;
1687  disp = 0;
1688 
1689 /* PROFILE_CYCLE_STOP; */
1690 
1691  pr = patcher_add_patch_ref(jd, PATCHER_putfieldconst, uf, 0);
1692  mcodeptr_save = cd->mcodeptr;
1693 
1694 /* PROFILE_CYCLE_START; */
1695 
1696  fi = NULL; /* Silence compiler warning */
1697  }
1698  else {
1699  fi = iptr->sx.s23.s3.fmiref->p.field;
1700  fieldtype = fi->type;
1701  disp = fi->offset;
1702 
1703  pr = NULL; /* Silence compiler warning */
1704  }
1705 
1706  /* implicit null-pointer check */
1707  switch (fieldtype) {
1708  case TYPE_INT:
1709  case TYPE_FLT:
1710  M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
1711  break;
1712  case TYPE_LNG:
1713  case TYPE_ADR:
1714  case TYPE_DBL:
1715  /* XXX why no check for IS_IMM32? -- probably because of the patcher */
1716  M_MOV_IMM(iptr->sx.s23.s2.constval, REG_ITMP2);
1717  if (disp) /* resolved, disp can never be 0 */
1718  M_LST(REG_ITMP2, s1, disp);
1719  else { /* unresolved */
1720  M_LST32(REG_ITMP2, s1, disp);
1721  pr->patch_align = 4;
1722  }
1723  break;
1724  }
1725  if (pr)
1726  codegen_fixup_alignment(cd, pr, mcodeptr_save);
1727  codegen_emit_patchable_barrier(iptr, cd, pr, fi);
1728  break;
1729 
1730 
1731  /* branch operations **************************************************/
1732 
1733  case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1734 
1736  break;
1737 
1738  case ICMD_IF_LEQ: /* ..., value ==> ... */
1739  case ICMD_IF_LNE:
1740  case ICMD_IF_LLT:
1741  case ICMD_IF_LGE:
1742  case ICMD_IF_LGT:
1743  case ICMD_IF_LLE:
1744 
1745  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1746  if (IS_IMM32(iptr->sx.val.l))
1747  M_LCMP_IMM(iptr->sx.val.l, s1);
1748  else {
1749  M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1750  M_LCMP(REG_ITMP2, s1);
1751  }
1752  emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
1753  break;
1754 
1755  case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
1756  case ICMD_IF_LCMPNE:
1757  case ICMD_IF_LCMPLT:
1758  case ICMD_IF_LCMPGE:
1759  case ICMD_IF_LCMPGT:
1760  case ICMD_IF_LCMPLE:
1761 
1762  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1763  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1764  M_LCMP(s2, s1);
1765  emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
1766  break;
1767 
1768  case ICMD_TABLESWITCH: /* ..., index ==> ... */
1769  {
1770  s4 i, l;
1771  branch_target_t *table;
1772 
1773  table = iptr->dst.table;
1774 
1775  l = iptr->sx.s23.s2.tablelow;
1776  i = iptr->sx.s23.s3.tablehigh;
1777 
1778  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1779  M_INTMOVE(s1, REG_ITMP1);
1780 
1781  if (l != 0)
1782  M_ISUB_IMM(l, REG_ITMP1);
1783 
1784  /* number of targets */
1785  i = i - l + 1;
1786 
1787  /* range check */
1788 
1789  M_ICMP_IMM(i - 1, REG_ITMP1);
1790  emit_bugt(cd, table[0].block);
1791 
1792  /* build jump table top down and use address of lowest entry */
1793 
1794  table += i;
1795 
1796  while (--i >= 0) {
1797  dseg_add_target(cd, table->block);
1798  --table;
1799  }
1800 
1801  /* length of dataseg after last dseg_add_target is used
1802  by load */
1803 
1804  M_MOV_IMM(0, REG_ITMP2);
1805  dseg_adddata(cd);
1807  M_JMP(REG_ITMP1);
1808  }
1809  break;
1810 
1811  case ICMD_BUILTIN:
1812  bte = iptr->sx.s23.s3.bte;
1813  if (bte->stub == NULL) {
1814  M_MOV_IMM(bte->fp, REG_ITMP1);
1815  }
1816  else {
1817  M_MOV_IMM(bte->stub, REG_ITMP1);
1818  }
1819  M_CALL(REG_ITMP1);
1820  break;
1821 
1822  case ICMD_INVOKESPECIAL:
1823  emit_nullpointer_check(cd, iptr, REG_A0);
1824  /* fall through */
1825 
1826  case ICMD_INVOKESTATIC:
1827  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1828  um = iptr->sx.s23.s3.um;
1829  disp = dseg_add_unique_address(cd, um);
1830 
1832  um, disp);
1833  }
1834  else {
1835  lm = iptr->sx.s23.s3.fmiref->p.method;
1836  disp = dseg_add_functionptr(cd, lm->stubroutine);
1837  }
1838 
1839  M_ALD(REG_ITMP2, RIP, disp);
1840  M_CALL(REG_ITMP2);
1841  break;
1842 
1843  case ICMD_INVOKEVIRTUAL:
1844  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1845  um = iptr->sx.s23.s3.um;
1847  emit_arbitrary_nop(cd, PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 6, sizeof(int32_t)));
1848 
1849  s1 = 0;
1850  }
1851  else {
1852  lm = iptr->sx.s23.s3.fmiref->p.method;
1853  s1 = OFFSET(vftbl_t, table[0]) +
1854  sizeof(methodptr) * lm->vftblindex;
1855  }
1856 
1857  /* implicit null-pointer check */
1860  M_CALL(REG_ITMP3);
1861  break;
1862 
1863  case ICMD_INVOKEINTERFACE:
1864  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1865  um = iptr->sx.s23.s3.um;
1867  emit_arbitrary_nop(cd, PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 6, sizeof(int32_t)));
1868 
1869  s1 = 0;
1870  s2 = 0;
1871  }
1872  else {
1873  lm = iptr->sx.s23.s3.fmiref->p.method;
1874  s1 = OFFSET(vftbl_t, interfacetable[0]) -
1875  sizeof(methodptr) * lm->clazz->index;
1876 
1877  s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
1878  }
1879 
1880  /* implicit null-pointer check */
1883  if (INSTRUCTION_IS_UNRESOLVED(iptr))
1884  emit_arbitrary_nop(cd, PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 3, sizeof(int32_t)));
1886  M_CALL(REG_ITMP3);
1887  break;
1888 
1889  case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
1890 
1891  if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
1892  /* object type cast-check */
1893 
1894  classinfo *super;
1895  s4 superindex;
1896 
1897  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1898  super = NULL;
1899  superindex = 0;
1900  }
1901  else {
1902  super = iptr->sx.s23.s3.c.cls;
1903  superindex = super->index;
1904  }
1905 
1906  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1907 
1908  /* if class is not resolved, check which code to call */
1909 
1910  if (super == NULL) {
1911  M_TEST(s1);
1912  emit_label_beq(cd, BRANCH_LABEL_1);
1913 
1915  iptr->sx.s23.s3.c.ref, 0);
1916 
1917  emit_arbitrary_nop(cd, PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 2, sizeof(int32_t)));
1918 
1919  M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
1921  emit_label_beq(cd, BRANCH_LABEL_2);
1922  }
1923 
1924  /* interface checkcast code */
1925 
1926  if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1927  if (super != NULL) {
1928  M_TEST(s1);
1929  emit_label_beq(cd, BRANCH_LABEL_3);
1930  }
1931 
1932  M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
1933 
1934  if (super == NULL) {
1936  iptr->sx.s23.s3.c.ref,
1937  0);
1938  emit_arbitrary_nop(cd, PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 10, sizeof(int32_t)));
1939  }
1940 
1942  REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
1943  M_ICMP_IMM32(superindex, REG_ITMP3);
1944  emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
1945 
1946  if (super == NULL)
1947  emit_arbitrary_nop(cd, PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 3, sizeof(int32_t)));
1949  OFFSET(vftbl_t, interfacetable[0]) -
1950  superindex * sizeof(methodptr*));
1951  M_TEST(REG_ITMP3);
1952  emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
1953 
1954  if (super == NULL)
1956  else
1958  }
1959 
1960  /* class checkcast code */
1961 
1962  if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
1963  if (super == NULL) {
1965 
1966  constant_classref *cr = iptr->sx.s23.s3.c.ref;
1967  disp = dseg_add_unique_address(cd, cr);
1968 
1971  cr, disp);
1972  }
1973  else {
1974  M_TEST(s1);
1975  emit_label_beq(cd, BRANCH_LABEL_5);
1976 
1977  disp = dseg_add_address(cd, super->vftbl);
1978  }
1979 
1980  M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
1981  M_ALD(REG_ITMP3, RIP, disp);
1982 
1983  if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
1984  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
1986  emit_label_beq(cd, BRANCH_LABEL_6); /* good */
1987 
1988  if (super == NULL) {
1989  M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
1990  emit_label_bne(cd, BRANCH_LABEL_10); /* throw */
1991  }
1992 
1993  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
1994  M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
1995  emit_label_bgt(cd, BRANCH_LABEL_9); /* throw */
1996 
1997  M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
1998  M_LCMP_MEMINDEX(REG_ITMP2, -8*DISPLAY_SIZE, REG_ITMP1, 3, REG_ITMP3);
1999  emit_label_beq(cd, BRANCH_LABEL_7); /* good */
2000 
2002  if (super == NULL)
2004 
2005  /* reload s1, might have been destroyed */
2006  emit_load_s1(jd, iptr, REG_ITMP1);
2008 
2011  /* reload s1, might have been destroyed */
2012  emit_load_s1(jd, iptr, REG_ITMP1);
2013  }
2014  else {
2015  M_LCMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
2016  emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP3, s1);
2017  }
2018 
2019  if (super != NULL)
2021  }
2022 
2023  if (super == NULL) {
2026  }
2027 
2028  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2029  }
2030  else {
2031  /* array type cast-check */
2032 
2033  s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2034  M_INTMOVE(s1, REG_A0);
2035 
2036  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2037  constant_classref *cr = iptr->sx.s23.s3.c.ref;
2038  disp = dseg_add_unique_address(cd, cr);
2039 
2042  cr, disp);
2043  }
2044  else {
2045  disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2046  }
2047 
2048  M_ALD(REG_A1, RIP, disp);
2050  M_CALL(REG_ITMP1);
2051 
2052  /* s1 may have been destroyed over the function call */
2053  s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2054  M_TEST(REG_RESULT);
2055  emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2056 
2057  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2058  }
2059 
2060  M_INTMOVE(s1, d);
2061  emit_store_dst(jd, iptr, d);
2062  break;
2063 
2064  case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2065 
2066  {
2067  classinfo *super;
2068  s4 superindex;
2069 
2070  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2071  super = NULL;
2072  superindex = 0;
2073  }
2074  else {
2075  super = iptr->sx.s23.s3.c.cls;
2076  superindex = super->index;
2077  }
2078 
2079  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2080  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2081 
2082  if (s1 == d) {
2083  M_INTMOVE(s1, REG_ITMP1);
2084  s1 = REG_ITMP1;
2085  }
2086 
2087  M_CLR(d);
2088 
2089  /* if class is not resolved, check which code to call */
2090 
2091  if (super == NULL) {
2092  M_TEST(s1);
2093  emit_label_beq(cd, BRANCH_LABEL_1);
2094 
2096  iptr->sx.s23.s3.c.ref, 0);
2097 
2098  emit_arbitrary_nop(cd, PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 2, sizeof(int32_t)));
2099 
2100  M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
2102  emit_label_beq(cd, BRANCH_LABEL_2);
2103  }
2104 
2105  /* interface instanceof code */
2106 
2107  if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2108  int nops;
2109  if (super != NULL) {
2110  M_TEST(s1);
2111  emit_label_beq(cd, BRANCH_LABEL_3);
2112  }
2113 
2114  M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2115 
2116  if (super == NULL) {
2118  iptr->sx.s23.s3.c.ref, 0);
2119  emit_arbitrary_nop(cd, PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 10, sizeof(int32_t)));
2120  }
2121 
2123  REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2124  M_ICMP_IMM32(superindex, REG_ITMP3);
2125 
2126  nops = super == NULL ? PATCH_ALIGNMENT((uintptr_t) (cd->mcodeptr + 6), 3, sizeof(int32_t)) : 0;
2127 
2128  int a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */ + nops;
2129 
2130  M_BLE(a);
2131  emit_arbitrary_nop(cd, nops);
2133  OFFSET(vftbl_t, interfacetable[0]) -
2134  superindex * sizeof(methodptr*));
2135  M_TEST(REG_ITMP1);
2136  M_SETNE(d);
2137 
2138  if (super == NULL)
2140  else
2142  }
2143 
2144  /* class instanceof code */
2145 
2146  if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2147  if (super == NULL) {
2149 
2150  constant_classref *cr = iptr->sx.s23.s3.c.ref;
2151  disp = dseg_add_unique_address(cd, cr);
2152 
2155  cr, disp);
2156  }
2157  else {
2158  M_TEST(s1);
2159  emit_label_beq(cd, BRANCH_LABEL_5);
2160 
2161  disp = dseg_add_address(cd, super->vftbl);
2162  }
2163 
2164  M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2165  M_ALD(REG_ITMP3, RIP, disp);
2166 
2167  if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2168  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2170  emit_label_bne(cd, BRANCH_LABEL_8); /* jump over INC/SETE */
2171  if (d == REG_ITMP2) {
2172  M_SETE(d);
2173  M_BSEXT(d, d);
2174  } else
2175  M_LINC(d);
2176  emit_label_br(cd, BRANCH_LABEL_6); /* true */
2178 
2179  if (super == NULL) {
2180  M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2181  emit_label_bne(cd, BRANCH_LABEL_10); /* false */
2182  }
2183 
2184  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2185  M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
2186  emit_label_bgt(cd, BRANCH_LABEL_9); /* false */
2187 
2188  M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2189  M_LCMP_MEMINDEX(REG_ITMP2, -8*DISPLAY_SIZE, REG_ITMP1, 3, REG_ITMP3);
2190  M_SETE(d);
2191  if (d == REG_ITMP2) {
2192  M_BSEXT(d, d);
2193 
2194  emit_label_br(cd, BRANCH_LABEL_7); /* jump over M_CLR */
2195  }
2196 
2198  if (super == NULL)
2200  if (d == REG_ITMP2) {
2201  M_CLR(d);
2202 
2204  }
2206  }
2207  else {
2208  M_LCMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
2209  M_SETE(d);
2210  if (d == REG_ITMP2)
2211  M_BSEXT(d, d);
2212  }
2213 
2214  if (super != NULL)
2216  }
2217 
2218  if (super == NULL) {
2221  }
2222 
2223  emit_store_dst(jd, iptr, d);
2224  }
2225  break;
2226 
2227  case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2228 
2229  /* check for negative sizes and copy sizes to stack if necessary */
2230 
2231  MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
2232 
2233  for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2234 
2235  /* copy SAVEDVAR sizes to stack */
2236  var = VAR(iptr->sx.s23.s2.args[s1]);
2237 
2238  /* Already Preallocated? */
2239  if (!(var->flags & PREALLOC)) {
2240  s2 = emit_load(jd, iptr, var, REG_ITMP1);
2241  M_LST(s2, REG_SP, s1 * 8);
2242  }
2243  }
2244 
2245  /* a0 = dimension count */
2246 
2247  M_MOV_IMM(iptr->s1.argcount, REG_A0);
2248 
2249  /* is a patcher function set? */
2250 
2251  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2252  constant_classref *cr = iptr->sx.s23.s3.c.ref;
2253  disp = dseg_add_unique_address(cd, cr);
2254 
2256  cr, disp);
2257  }
2258  else {
2259  disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2260  }
2261 
2262  /* a1 = classinfo */
2263 
2264  M_ALD(REG_A1, RIP, disp);
2265 
2266  /* a2 = pointer to dimensions = stack pointer */
2267 
2268  M_MOV(REG_SP, REG_A2);
2269 
2271  M_CALL(REG_ITMP1);
2272 
2273  /* check for exception before result assignment */
2274 
2275  emit_exception_check(cd, iptr);
2276 
2277  s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2278  M_INTMOVE(REG_RESULT, s1);
2279  emit_store_dst(jd, iptr, s1);
2280  break;
2281 
2282  default:
2283  vm_abort("Unknown ICMD %d during code generation", iptr->opc);
2284  } /* switch */
2285 }
2286 
2287 
2288 /* codegen_emit_stub_native ****************************************************
2289 
2290  Emits a stub routine which calls a native method.
2291 
2292 *******************************************************************************/
2293 
2294 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2295 {
2296  methodinfo *m;
2297  codeinfo *code;
2298  codegendata *cd;
2299  methoddesc *md;
2300  int i, j;
2301  int s1, s2;
2302  int disp;
2303 
2304  /* Sanity check. */
2305 
2306  assert(f != NULL);
2307 
2308  /* Get required compiler data. */
2309 
2310  m = jd->m;
2311  code = jd->code;
2312  cd = jd->cd;
2313 
2314  /* initialize variables */
2315 
2316  md = m->parseddesc;
2317 
2318  /* calculate stack frame size */
2319 
2320  cd->stackframesize =
2321  sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2322  sizeof(localref_table) / SIZEOF_VOID_P +
2323  md->paramcount +
2324  (md->returntype.type == TYPE_VOID ? 0 : 1) +
2325  nmd->memuse;
2326 
2327  ALIGN_ODD(cd->stackframesize); /* keep stack 16-byte aligned */
2328 
2329  /* create method header */
2330 
2331  (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2332  (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2333  (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2334  (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2335  (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2336 
2337 #if defined(ENABLE_PROFILING)
2338  /* generate native method profiling code */
2339 
2340  if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
2341  /* count frequency */
2342 
2343  M_MOV_IMM(code, REG_ITMP3);
2344  M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
2345  }
2346 #endif
2347 
2348  /* generate stub code */
2349 
2350  M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
2351 
2352 #if defined(ENABLE_GC_CACAO)
2353  /* Save callee saved integer registers in stackframeinfo (GC may
2354  need to recover them during a collection). */
2355 
2356  disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2357  OFFSET(stackframeinfo_t, intregs);
2358 
2359  for (i = 0; i < INT_SAV_CNT; i++)
2360  M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2361 #endif
2362 
2363  /* save integer and float argument registers */
2364 
2365  for (i = 0; i < md->paramcount; i++) {
2366  if (!md->params[i].inmemory) {
2367  s1 = md->params[i].regoff;
2368 
2369  switch (md->paramtypes[i].type) {
2370  case TYPE_INT:
2371  case TYPE_LNG:
2372  case TYPE_ADR:
2373  M_LST(s1, REG_SP, i * 8);
2374  break;
2375  case TYPE_FLT:
2376  case TYPE_DBL:
2377  M_DST(s1, REG_SP, i * 8);
2378  break;
2379  default:
2380  assert(false);
2381  break;
2382  }
2383  }
2384  }
2385 
2386  /* create dynamic stack info */
2387 
2388  M_MOV(REG_SP, REG_A0);
2389  emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
2391  M_CALL(REG_ITMP1);
2392 
2393  /* remember class argument */
2394 
2395  if (m->flags & ACC_STATIC)
2397 
2398  /* restore integer and float argument registers */
2399 
2400  for (i = 0; i < md->paramcount; i++) {
2401  if (!md->params[i].inmemory) {
2402  s1 = md->params[i].regoff;
2403 
2404  switch (md->paramtypes[i].type) {
2405  case TYPE_INT:
2406  case TYPE_LNG:
2407  case TYPE_ADR:
2408  M_LLD(s1, REG_SP, i * 8);
2409  break;
2410  case TYPE_FLT:
2411  case TYPE_DBL:
2412  M_DLD(s1, REG_SP, i * 8);
2413  break;
2414  default:
2415  assert(false);
2416  break;
2417  }
2418  }
2419  }
2420 
2421  /* Copy or spill arguments to new locations. */
2422 
2423  for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
2424  s2 = nmd->params[j].regoff;
2425 
2426  switch (md->paramtypes[i].type) {
2427  case TYPE_INT:
2428  case TYPE_LNG:
2429  case TYPE_ADR:
2430  if (!md->params[i].inmemory) {
2431  s1 = md->params[i].regoff;
2432 
2433  if (!nmd->params[j].inmemory)
2434  M_INTMOVE(s1, s2);
2435  else
2436  M_LST(s1, REG_SP, s2);
2437  }
2438  else {
2439  s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
2440  M_LLD(REG_ITMP1, REG_SP, s1);
2441  M_LST(REG_ITMP1, REG_SP, s2);
2442  }
2443  break;
2444  case TYPE_FLT:
2445  /* We only copy spilled float arguments, as the float
2446  argument registers keep unchanged. */
2447 
2448  if (md->params[i].inmemory) {
2449  s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
2450 
2451  M_FLD(REG_FTMP1, REG_SP, s1);
2452  M_FST(REG_FTMP1, REG_SP, s2);
2453  }
2454  break;
2455  case TYPE_DBL:
2456  if (md->params[i].inmemory) {
2457  s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
2458  M_DLD(REG_FTMP1, REG_SP, s1);
2459  M_DST(REG_FTMP1, REG_SP, s2);
2460  }
2461  break;
2462  default:
2463  assert(false);
2464  break;
2465  }
2466  }
2467 
2468  /* Handle native Java methods. */
2469 
2470  if (m->flags & ACC_NATIVE) {
2471  /* put class into second argument register */
2472 
2473  if (m->flags & ACC_STATIC)
2475 
2476  /* put env into first argument register */
2477 
2478  M_MOV_IMM(VM::get_current()->get_jnienv(), REG_A0);
2479  }
2480 
2481  /* Call the native function. */
2482 
2483  disp = dseg_add_functionptr(cd, f);
2484  M_ALD(REG_ITMP1, RIP, disp);
2485  M_CALL(REG_ITMP1);
2486 
2487  /* save return value */
2488 
2489  switch (md->returntype.type) {
2490  case TYPE_INT:
2491  case TYPE_LNG:
2492  case TYPE_ADR:
2493  switch (md->returntype.primitivetype) {
2494  case PRIMITIVETYPE_BOOLEAN:
2496  break;
2497  case PRIMITIVETYPE_BYTE:
2499  break;
2500  case PRIMITIVETYPE_CHAR:
2502  break;
2503  case PRIMITIVETYPE_SHORT:
2505  break;
2506  default:
2507  break;
2508  }
2509  M_LST(REG_RESULT, REG_SP, 0 * 8);
2510  break;
2511  case TYPE_FLT:
2512  case TYPE_DBL:
2513  M_DST(REG_FRESULT, REG_SP, 0 * 8);
2514  break;
2515  case TYPE_VOID:
2516  break;
2517  default:
2518  assert(false);
2519  break;
2520  }
2521 
2522  /* remove native stackframe info */
2523 
2524  M_MOV(REG_SP, REG_A0);
2525  emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
2527  M_CALL(REG_ITMP1);
2529 
2530  /* restore return value */
2531 
2532  switch (md->returntype.type) {
2533  case TYPE_INT:
2534  case TYPE_LNG:
2535  case TYPE_ADR:
2536  M_LLD(REG_RESULT, REG_SP, 0 * 8);
2537  break;
2538  case TYPE_FLT:
2539  case TYPE_DBL:
2540  M_DLD(REG_FRESULT, REG_SP, 0 * 8);
2541  break;
2542  case TYPE_VOID:
2543  break;
2544  default:
2545  assert(false);
2546  break;
2547  }
2548 
2549 #if defined(ENABLE_GC_CACAO)
2550  /* Restore callee saved integer registers from stackframeinfo (GC
2551  might have modified them during a collection). */
2552 
2553  disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2554  OFFSET(stackframeinfo_t, intregs);
2555 
2556  for (i = 0; i < INT_SAV_CNT; i++)
2557  M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2558 #endif
2559 
2560  /* remove stackframe */
2561 
2562  M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2563 
2564  /* test for exception */
2565 
2566  M_TEST(REG_ITMP3);
2567  M_BNE(1);
2568  M_RET;
2569 
2570  /* handle exception */
2571 
2574 }
2575 
2576 
2577 /*
2578  * These are local overrides for various environment variables in Emacs.
2579  * Please do not remove this and leave it at the end of the file, where
2580  * Emacs will automagically detect them.
2581  * ---------------------------------------------------------------------
2582  * Local variables:
2583  * mode: c++
2584  * indent-tabs-mode: t
2585  * c-basic-offset: 4
2586  * tab-width: 4
2587  * End:
2588  * vim:noexpandtab:sw=4:ts=4:
2589  */
void codegen_emit_instruction(jitdata *jd, instruction *iptr)
Generates machine code for one ICMD.
Definition: codegen.cpp:217
void emit_ucomisd_reg_reg(codegendata *cd, s8 reg, s8 dreg)
Definition: emit.cpp:2640
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 PATCHER_resolve_classref_to_flags
s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg)
basicblock * block
union varinfo::@19 vv
#define M_LST32(a, b, disp)
Definition: codegen.hpp:186
#define M_LMUL_IMM(a, b, c)
Definition: codegen.hpp:275
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_LAND_IMM(a, b)
Definition: codegen.hpp:225
#define M_ALD(a, b, disp)
Definition: codegen.hpp:345
s4 asm_builtin_f2i(float a)
#define CC_LE
Definition: emit.hpp:94
#define M_CVTDI(a, d)
Definition: codegen.hpp:725
#define M_DMUL(a, b, c)
Definition: codegen.hpp:378
#define SHIFT_SHL
Definition: emit.hpp:61
#define BRANCH_OPT_NONE
#define PATCHER_invokeinterface
#define M_ILD32(a, b, disp)
Definition: codegen.hpp:147
#define REG_A1
Definition: md-abi.hpp:36
Definition: jit.hpp:126
#define M_CMOVULT(a, b)
Definition: codegen.hpp:287
#define M_LST(a, b, disp)
Definition: codegen.hpp:349
#define REG_A0
Definition: md-abi.hpp:35
paramdesc * params
Definition: descriptor.hpp:164
#define M_ALD32(a, b, disp)
Definition: codegen.hpp:150
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
#define M_CVTFD(a, b)
Definition: codegen.hpp:721
void emit_ucomiss_reg_reg(codegendata *cd, s8 reg, s8 dreg)
Definition: emit.cpp:2632
#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
s4 dseg_add_unique_address(codegendata *cd, void *value)
Definition: dseg.cpp:525
int * savintregs
Definition: reg.hpp:71
methodinfo * methods
Definition: class.hpp:113
void emit_ishift(jitdata *jd, s4 shift_op, instruction *iptr)
Definition: emit.cpp:988
#define PATCHER_resolve_classref_to_vftbl
#define M_ISEXT(a, b)
Definition: codegen.hpp:344
#define BUILTIN_multianewarray
Definition: builtin.hpp:201
#define IS_INT_LNG_TYPE(a)
Definition: global.hpp:130
#define M_LXOR(a, b)
Definition: codegen.hpp:223
#define BRANCH_NE
static void codegen_fixup_alignment(codegendata *cd, patchref_t *pr, u1 *mcodeptr_save)
Ensures that the patched location (an int32_t) is aligned.
Definition: codegen.cpp:213
void emit_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg)
Definition: emit.cpp:1700
#define M_BNE(off)
Definition: codegen.hpp:483
#define PATCHER_get_putfield
#define BRANCH_EQ
#define M_CZEXT(a, b)
Definition: codegen.hpp:451
#define M_AADD_IMM(a, b, c)
Definition: codegen.hpp:277
#define M_LSLL_IMM(a, b, c)
Definition: codegen.hpp:471
#define M_IOR(a, b, d)
Definition: codegen.hpp:177
s4 dseg_add_address(codegendata *cd, void *value)
Definition: dseg.cpp:542
codeinfo * code
Definition: jit.hpp:128
#define BRANCH_LABEL_5
Definition: emit-common.hpp:51
#define M_IMOV_IMM(a, b)
Definition: codegen.hpp:130
#define M_LNEG(a)
Definition: codegen.hpp:211
#define REG_NULL
Definition: md-abi.hpp:43
#define REG_FRESULT
Definition: md-abi.hpp:59
int32_t argcount
Definition: instruction.hpp:64
void emit_bcc(codegendata *cd, basicblock *target, s4 condition, u4 options)
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
void emit_alu_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
Definition: emit.cpp:1239
#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
void emit_alul_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
Definition: emit.cpp:1627
#define M_IMOV(a, b)
Definition: codegen.hpp:129
#define REG_ITMP1_XPTR
Definition: md-abi.hpp:50
#define M_LXOR_IMM(a, b)
Definition: codegen.hpp:227
#define REG_A2
Definition: md-abi.hpp:37
#define M_LINC(a)
Definition: codegen.hpp:170
void emit_arraystore_check(codegendata *cd, instruction *iptr)
Definition: emit.cpp:380
#define M_IST32_IMM(a, b, disp)
Definition: codegen.hpp:178
#define M_CMOVUGT(a, b)
Definition: codegen.hpp:288
int savintreguse
Definition: reg.hpp:88
#define M_FST(a, b, disp)
Definition: codegen.hpp:357
#define RAX
Definition: md-abi.hpp:32
#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
void emit_arbitrary_nop(codegendata *cd, int disp)
Definition: emit.cpp:1314
#define M_FLD(a, b, disp)
Definition: codegen.hpp:354
uint8_t u1
Definition: types.hpp:40
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_xorps_reg_reg(codegendata *cd, s8 reg, s8 dreg)
Definition: emit.cpp:2649
#define BRANCH_LABEL_6
Definition: emit-common.hpp:52
void emit_idivl_reg(codegendata *cd, s8 reg)
Definition: emit.cpp:1963
java_object_t * codegen_finish_native_call(u1 *sp, u1 *pv)
#define M_CMOVP(a, b)
Definition: codegen.hpp:289
#define M_SETNE(a)
Definition: codegen.hpp:277
u1 * stub
Definition: builtin.hpp:64
#define M_IAND(a, b, d)
Definition: codegen.hpp:174
#define M_MFENCE
Definition: codegen.hpp:344
#define M_CVTDL(b, c)
Definition: codegen.hpp:394
const s4 abi_registers_integer_saved[]
Definition: md-abi.cpp:75
#define VAR(i)
Definition: jit.hpp:252
Definition: reg.hpp:43
#define M_CVTLD(b, c)
Definition: codegen.hpp:393
#define RDX
Definition: md-abi.hpp:34
#define PATCHER_get_putstatic
#define BUILTIN_arraycheckcast
Definition: builtin.hpp:148
#define REG_IFTMP
Definition: md-abi.hpp:69
void emit_movl_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale)
Definition: emit.cpp:1441
void emit_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg)
Definition: emit.cpp:2587
#define M_CVTLF(b, c)
Definition: codegen.hpp:392
void emit_cmovccl_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
Definition: emit.cpp:2128
s4 dseg_add_s4(codegendata *cd, s4 value)
Definition: dseg.cpp:246
void vm_abort(const char *text,...)
Definition: vm.cpp:2586
#define M_LSUB(a, b, c)
Definition: codegen.hpp:266
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
#define CC_G
Definition: emit.hpp:96
java_handle_t * codegen_start_native_call(u1 *sp, u1 *pv)
#define PATCHER_instanceof_interface
#define M_LST_IMM32(a, b, disp)
Definition: codegen.hpp:145
#define IS_2_WORD_TYPE(a)
Definition: global.hpp:132
void emit_exception_check(codegendata *cd, instruction *iptr)
Definition: emit.cpp:447
#define M_MOV_IMM(d, i)
Definition: codegen.hpp:448
s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
#define M_ICMP_IMM32(a, b)
Definition: codegen.hpp:255
BeginInst *& block
#define M_FSUB(a, b, c)
Definition: codegen.hpp:375
#define M_CVTID(a, d)
Definition: codegen.hpp:723
classref_or_classinfo c
#define M_ISRA_IMM(a, b, c)
Definition: codegen.hpp:470
#define M_LCMP_MEMINDEX(a, b, c, d, e)
Definition: codegen.hpp:251
void emit_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale)
Definition: emit.cpp:2569
void emit_movb_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
Definition: emit.cpp:1094
#define M_FST32(a, b, disp)
Definition: codegen.hpp:317
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_IINC_MEMBASE(a, b)
Definition: codegen.hpp:347
#define M_LSRA_IMM(a, b, c)
Definition: codegen.hpp:473
dst_operand_t dst
#define M_CVTFI(a, d)
Definition: codegen.hpp:724
flags_operand_t flags
#define M_LOR(a, b)
Definition: codegen.hpp:222
#define RIP
Definition: md-abi.hpp:31
s8 asm_builtin_f2l(float a)
#define ALU_SUB
Definition: emit.hpp:52
void emit_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale)
Definition: emit.cpp:2560
constant_FMIref * fieldref
Definition: resolve.hpp:88
int16_t disp_mb
int32_t offset
Definition: field.hpp:66
classinfo * clazz
Definition: method.hpp:80
#define M_CVTFL(a, c)
Definition: codegen.hpp:525
#define M_JMP(a, b)
Definition: codegen.hpp:259
void emit_label_br(codegendata *cd, s4 label)
This file contains the statistics framework.
#define BRANCH_LABEL_3
Definition: emit-common.hpp:49
void emit_cqto(codegendata *cd)
Definition: emit.cpp:1842
s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg)
Definition: emit-common.cpp:82
s4 flags
Definition: field.hpp:59
imm_union * value
Definition: field.hpp:67
#define M_BSEXT(b, c)
Definition: codegen.hpp:247
#define M_LSRL_IMM(a, b, c)
Definition: codegen.hpp:472
#define SHIFT_SHR
Definition: emit.hpp:62
#define M_ICMP_IMM(a, b)
Definition: codegen.hpp:297
#define M_FADD(a, b, c)
Definition: codegen.hpp:373
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
typedesc * fd
Definition: references.hpp:74
s4 * local_map
Definition: jit.hpp:153
#define M_DST32(a, b, disp)
Definition: codegen.hpp:318
#define REG_FTMP2
Definition: md-abi.hpp:66
void emit_xorpd_reg_reg(codegendata *cd, s8 reg, s8 dreg)
Definition: emit.cpp:2665
MIIterator i
void emit_movsbq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg)
Definition: emit.cpp:1554
s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
Definition: emit.cpp:66
typedesc returntype
Definition: descriptor.hpp:166
#define M_IST_IMM(a, b, disp)
Definition: codegen.hpp:173
#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
s4 dseg_add_unique_s4(codegendata *cd, s4 value)
Definition: dseg.cpp:229
int * savfltregs
Definition: reg.hpp:73
int16_t patch_align
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
void emit_cltd(codegendata *cd)
Definition: emit.cpp:1837
#define M_CVTIF(a, d)
Definition: codegen.hpp:722
union instruction::@12 sx
#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
#define M_LCMP_MEMBASE(a, b, c)
Definition: codegen.hpp:250
void emit_movl_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg)
Definition: emit.cpp:1427
void emit_mov_reg_reg(codegendata *cd, s4 reg, s4 dreg)
Definition: emit.cpp:1001
#define M_LSUB_IMM(a, b, c)
Definition: codegen.hpp:273
int savfltreguse
Definition: reg.hpp:91
#define M_ICMP_MEMBASE(a, b, c)
Definition: codegen.hpp:257
#define M_MOV(a, b)
Definition: codegen.hpp:340
bool inmemory
Definition: descriptor.hpp:151
#define REG_ITMP2
Definition: md-abi.hpp:47
void emit_store_dst(jitdata *jd, instruction *iptr, s4 d)
#define M_LADD_IMM(a, b, c)
Definition: codegen.hpp:271
s1_operand_t s1
#define M_LADD(a, b, c)
Definition: codegen.hpp:264
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 M_IST32(a, b, disp)
Definition: codegen.hpp:177
basicblock * block
Definition: instruction.hpp:50
#define PATCHER_invokestatic_special
void emit_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg)
Definition: emit.cpp:2578
#define FLT_SAV_CNT
Definition: md-abi.hpp:80
void emit_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
Definition: emit.cpp:2370
#define BRANCH_LABEL_1
Definition: emit-common.hpp:47
#define M_INEG(a, dest)
Definition: codegen.hpp:794
vftbl_t * vftbl
Definition: class.hpp:121
methoddesc * parseddesc
Definition: method.hpp:78
#define M_FDIV(a, b, c)
Definition: codegen.hpp:379
#define REG_FTMP1
Definition: md-abi.hpp:65
#define VAROP(v)
Definition: jit.hpp:251
#define M_IXOR_IMM(a, b)
Definition: codegen.hpp:219
void emit_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
Definition: emit.cpp:1801
#define PATCHER_invokevirtual
#define ALIGN_ODD(a)
Definition: global.hpp:70
Definition: builtin.hpp:60
#define M_IMUL_IMM(a, b, c)
Definition: codegen.hpp:274
#define M_DSUB(a, b, c)
Definition: codegen.hpp:376
#define ALU_CMP
Definition: emit.hpp:54
void emit_nop(codegendata *cd)
Definition: emit-asm.hpp:584
methodinfo * m
Definition: jit.hpp:127
static bool IS_INMEMORY(s4 flags)
Definition: stack.hpp:51
s4 type
Definition: field.hpp:60
#define M_ISRL_IMM(a, b, c)
Definition: codegen.hpp:469
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
void emit_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
Definition: emit.cpp:1219
s4 flags
Definition: reg.hpp:45
#define M_LCMP_IMM(a, b)
Definition: codegen.hpp:248
#define M_LAND(a, b)
Definition: codegen.hpp:221
void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1)
Definition: emit.cpp:396
#define REG_METHODPTR
Definition: md-abi.hpp:43
#define M_FMUL(a, b, c)
Definition: codegen.hpp:377
#define M_ISLL_IMM(a, b, c)
Definition: codegen.hpp:468
int8_t s1
Definition: types.hpp:39
s4 dseg_add_s8(codegendata *cd, s8 value)
Definition: dseg.cpp:319
static bool class_is_or_almost_initialized(classinfo *c)
Definition: class.hpp:433
void emit_cmovcc_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
Definition: emit.cpp:2119
int16_t s2
Definition: types.hpp:42
#define PATCHER_initialize_class
#define M_IADD(a, b, c)
Definition: codegen.hpp:263
#define M_DST(a, b, disp)
Definition: codegen.hpp:356
#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
void emit_shift_imm_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
Definition: emit.cpp:1437
#define M_RET(a, b)
Definition: codegen.hpp:261
void emit_movzwq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg)
Definition: emit.cpp:1562
#define REG_FTMP3
Definition: md-abi.hpp:67
#define M_IAND_IMM(a, b, d)
Definition: codegen.hpp:175
#define M_LLD(a, b, disp)
Definition: codegen.hpp:344
const parseddesc_t parseddesc
Definition: references.hpp:105
static void emit_fmove(codegendata *cd, int s, int d)
Generates a float-move from register s to d.
#define M_IOR_IMM(a, b, d)
Definition: codegen.hpp:178
#define REG_ITMP3
Definition: md-abi.hpp:48
#define PATCHER_resolve_classref_to_classinfo
#define MCODECHECK(icnt)
Definition: codegen.hpp:40
#define M_LCMP(a, b)
Definition: codegen.hpp:247
#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)
#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
void emit_shiftl_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg)
Definition: emit.cpp:2016
#define M_CVTDF(b, c)
Definition: codegen.hpp:391
PrimitiveType primitivetype
Definition: descriptor.hpp:137
void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
Definition: emit.cpp:362
uintptr_t mpc
void emit_lshift(jitdata *jd, s4 shift_op, instruction *iptr)
Definition: emit.cpp:1115
#define M_DLD(a, b, disp)
Definition: codegen.hpp:353
#define M_LMUL(a, b, c)
Definition: codegen.hpp:268
void emit_idiv_reg(codegendata *cd, s4 reg)
Definition: emit.cpp:1419
#define M_DDIV(a, b, c)
Definition: codegen.hpp:380
#define M_CALL(a)
Definition: codegen.hpp:290
#define M_IXOR(a, dest)
Definition: codegen.hpp:763
#define M_LOR_IMM(a, b)
Definition: codegen.hpp:226
uint32_t regoff
Definition: descriptor.hpp:153
void emit_movl_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
Definition: emit.cpp:1579
s4 dseg_add_float(codegendata *cd, float value)
Definition: dseg.cpp:392
#define OFFSET(s, el)
Definition: memory.hpp:90
#define SHIFT_SAR
Definition: emit.hpp:63
void emit_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
Definition: emit.cpp:2482
branch_target_t * table
void emit_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
Definition: emit.cpp:1794
void codegen_emit_patchable_barrier(instruction *iptr, codegendata *cd, patchref_t *pr, fieldinfo *fi)
Generates a memory barrier to be used after volatile writes.
Definition: codegen.cpp:197
#define PATCH_ALIGNMENT(addr, offset, size)
Definition: codegen.hpp:56
#define REG_RESULT
Definition: md-abi.hpp:33
#define M_INTMOVE(a, b)
void emit_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
Definition: emit.cpp:2379
void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
Definition: emit.cpp:431
#define IS_IMM32(c)
Definition: emit-common.hpp:66
#define REG_ITMP1
Definition: md-abi.hpp:46
void emit_movswq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg)
Definition: emit.cpp:1546
static VM * get_current()
Definition: vm.hpp:99
#define M_DADD(a, b, c)
Definition: codegen.hpp:374