CACAO
emit.cpp
Go to the documentation of this file.
1 /* src/vm/jit/alpha/emit.cpp - Alpha code emitter functions
2 
3  Copyright (C) 1996-2014
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 #include "vm/types.hpp"
28 
29 #include <cassert>
30 #include <stdint.h>
31 
32 #include "md-abi.hpp"
33 
34 #include "vm/jit/alpha/codegen.hpp"
35 
36 #include "mm/memory.hpp"
37 
38 #include "threads/lock.hpp"
39 
40 #include "vm/descriptor.hpp" // for typedesc, methoddesc, etc
41 #include "vm/options.hpp"
42 
43 #include "vm/jit/abi.hpp"
44 #include "vm/jit/abi-asm.hpp"
45 #include "vm/jit/asmpart.hpp"
46 #include "vm/jit/builtin.hpp"
47 #include "vm/jit/code.hpp"
49 #include "vm/jit/dseg.hpp"
50 #include "vm/jit/emit-common.hpp"
51 #include "vm/jit/jit.hpp"
53 #include "vm/jit/replace.hpp"
54 #include "vm/jit/trace.hpp"
55 #include "vm/jit/trap.hpp"
56 
58 
59 
60 /* emit_load *******************************************************************
61 
62  Emits a possible load of an operand.
63 
64 *******************************************************************************/
65 
66 s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
67 {
68  codegendata *cd;
69  s4 disp;
70  s4 reg;
71 
72  /* get required compiler data */
73 
74  cd = jd->cd;
75 
76  if (IS_INMEMORY(src->flags)) {
78 
79  disp = src->vv.regoff;
80 
81  switch (src->type) {
82  case TYPE_INT:
83  case TYPE_LNG:
84  case TYPE_ADR:
85  M_LLD(tempreg, REG_SP, disp);
86  break;
87  case TYPE_FLT:
88  M_FLD(tempreg, REG_SP, disp);
89  break;
90  case TYPE_DBL:
91  M_DLD(tempreg, REG_SP, disp);
92  break;
93  default:
94  vm_abort("emit_load: unknown type %d", src->type);
95  break;
96  }
97 
98  reg = tempreg;
99  }
100  else
101  reg = src->vv.regoff;
102 
103  return reg;
104 }
105 
106 
107 /* emit_store ******************************************************************
108 
109  Emit a possible store for the given variable.
110 
111 *******************************************************************************/
112 
113 void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
114 {
115  codegendata *cd;
116  s4 disp;
117 
118  /* get required compiler data */
119 
120  cd = jd->cd;
121 
122  if (IS_INMEMORY(dst->flags)) {
123  COUNT_SPILLS;
124 
125  disp = dst->vv.regoff;
126 
127  switch (dst->type) {
128  case TYPE_INT:
129  case TYPE_LNG:
130  case TYPE_ADR:
131  M_LST(d, REG_SP, disp);
132  break;
133  case TYPE_FLT:
134  M_FST(d, REG_SP, disp);
135  break;
136  case TYPE_DBL:
137  M_DST(d, REG_SP, disp);
138  break;
139  default:
140  vm_abort("emit_store: unknown type %d", dst->type);
141  break;
142  }
143  }
144 }
145 
146 
147 /* emit_copy *******************************************************************
148 
149  Generates a register/memory to register/memory copy.
150 
151 *******************************************************************************/
152 
153 void emit_copy(jitdata *jd, instruction *iptr)
154 {
155  codegendata *cd;
156  varinfo *src;
157  varinfo *dst;
158  s4 s1, d;
159 
160  /* get required compiler data */
161 
162  cd = jd->cd;
163 
164  /* get source and destination variables */
165 
166  src = VAROP(iptr->s1);
167  dst = VAROP(iptr->dst);
168 
169  if ((src->vv.regoff != dst->vv.regoff) ||
170  ((src->flags ^ dst->flags) & INMEMORY)) {
171 
172  if ((src->type == TYPE_RET) || (dst->type == TYPE_RET)) {
173  /* emit nothing, as the value won't be used anyway */
174  return;
175  }
176 
177  /* If one of the variables resides in memory, we can eliminate
178  the register move from/to the temporary register with the
179  order of getting the destination register and the load. */
180 
181  if (IS_INMEMORY(src->flags)) {
182  d = codegen_reg_of_var(iptr->opc, dst, REG_IFTMP);
183  s1 = emit_load(jd, iptr, src, d);
184  }
185  else {
186  s1 = emit_load(jd, iptr, src, REG_IFTMP);
187  d = codegen_reg_of_var(iptr->opc, dst, s1);
188  }
189 
190  if (s1 != d) {
191  switch (src->type) {
192  case TYPE_INT:
193  case TYPE_LNG:
194  case TYPE_ADR:
195  M_MOV(s1, d);
196  break;
197  case TYPE_FLT:
198  case TYPE_DBL:
199  M_FMOV(s1, d);
200  break;
201  default:
202  vm_abort("emit_copy: unknown type %d", src->type);
203  break;
204  }
205  }
206 
207  emit_store(jd, iptr, dst, d);
208  }
209 }
210 
211 
212 /* emit_iconst *****************************************************************
213 
214  XXX
215 
216 *******************************************************************************/
217 
218 void emit_iconst(codegendata *cd, s4 d, s4 value)
219 {
220  s4 disp;
221 
222  if ((value >= -32768) && (value <= 32767))
223  M_LDA_INTERN(d, REG_ZERO, value);
224  else {
225  disp = dseg_add_s4(cd, value);
226  M_ILD(d, REG_PV, disp);
227  }
228 }
229 
230 
231 /* emit_lconst *****************************************************************
232 
233  XXX
234 
235 *******************************************************************************/
236 
237 void emit_lconst(codegendata *cd, s4 d, s8 value)
238 {
239  s4 disp;
240 
241  if ((value >= -32768) && (value <= 32767))
242  M_LDA_INTERN(d, REG_ZERO, value);
243  else {
244  disp = dseg_add_s8(cd, value);
245  M_LLD(d, REG_PV, disp);
246  }
247 }
248 
249 
250 /**
251  * Emits code comparing one integer register to an immediate value.
252  */
253 void emit_icmpeq_imm(codegendata* cd, int reg, int32_t value, int d)
254 {
255  int32_t disp;
256 
257  if ((value >= 0) && (value <= 255)) {
258  M_CMPEQ_IMM(reg, value, d);
259  } else {
260  assert(reg != REG_ITMP2);
261  if ((value >= -32768) && (value <= 32767)) {
262  M_LDA(REG_ITMP2, REG_ZERO, value);
263  } else {
264  disp = dseg_add_s4(cd, value);
265  M_ILD(REG_ITMP2, REG_PV, disp);
266  }
267  M_CMPEQ(reg, REG_ITMP2, d);
268  }
269 }
270 
271 
272 /* emit_branch *****************************************************************
273 
274  Emits the code for conditional and unconditional branchs.
275 
276 *******************************************************************************/
277 
278 void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 opt)
279 {
280  s4 checkdisp;
281  s4 branchdisp;
282 
283  /* calculate the different displacements */
284 
285  checkdisp = (disp - 4);
286  branchdisp = (disp - 4) >> 2;
287 
288  /* check which branch to generate */
289 
290  if (condition == BRANCH_UNCONDITIONAL) {
291  /* check displacement for overflow */
292 
293  if ((checkdisp < (s4) 0xffe00000) || (checkdisp > (s4) 0x001fffff)) {
294  /* if the long-branches flag isn't set yet, do it */
295 
297  log_println("setting error");
298  cd->flags |= (CODEGENDATA_FLAG_ERROR |
300  }
301 
302  vm_abort("emit_branch: emit unconditional long-branch code");
303  }
304  else {
305  M_BR(branchdisp);
306  }
307  }
308  else {
309  /* and displacement for overflow */
310 
311  if ((checkdisp < (s4) 0xffe00000) || (checkdisp > (s4) 0x001fffff)) {
312  /* if the long-branches flag isn't set yet, do it */
313 
315  log_println("setting error");
316  cd->flags |= (CODEGENDATA_FLAG_ERROR |
318  }
319 
320  vm_abort("emit_branch: emit conditional long-branch code");
321  }
322  else {
323  switch (condition) {
324  case BRANCH_EQ:
325  M_BEQZ(reg, branchdisp);
326  break;
327  case BRANCH_NE:
328  M_BNEZ(reg, branchdisp);
329  break;
330  case BRANCH_LT:
331  M_BLTZ(reg, branchdisp);
332  break;
333  case BRANCH_GE:
334  M_BGEZ(reg, branchdisp);
335  break;
336  case BRANCH_GT:
337  M_BGTZ(reg, branchdisp);
338  break;
339  case BRANCH_LE:
340  M_BLEZ(reg, branchdisp);
341  break;
342  default:
343  vm_abort("emit_branch: unknown condition %d", condition);
344  break;
345  }
346  }
347  }
348 }
349 
350 
351 /* emit_arithmetic_check *******************************************************
352 
353  Emit an ArithmeticException check.
354 
355 *******************************************************************************/
356 
358 {
359  if (INSTRUCTION_MUST_CHECK(iptr)) {
360  M_BNEZ(reg, 1);
361  /* Destination register must not be REG_ZERO, because then no
362  SIGSEGV is thrown. */
364  }
365 }
366 
367 
368 /* emit_arrayindexoutofbounds_check ********************************************
369 
370  Emit an ArrayIndexOutOfBoundsException check.
371 
372 *******************************************************************************/
373 
375 {
376  if (INSTRUCTION_MUST_CHECK(iptr)) {
379  M_BNEZ(REG_ITMP3, 1);
381  }
382 }
383 
384 
385 /* emit_arraystore_check *******************************************************
386 
387  Emit an ArrayStoreException check.
388 
389 *******************************************************************************/
390 
392 {
393  if (INSTRUCTION_MUST_CHECK(iptr)) {
394  M_BNEZ(REG_RESULT, 1);
395  /* Destination register must not be REG_ZERO, because then no
396  SIGSEGV is thrown. */
398  }
399 }
400 
401 
402 /* emit_classcast_check ********************************************************
403 
404  Emit a ClassCastException check.
405 
406 *******************************************************************************/
407 
408 void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1)
409 {
410  if (INSTRUCTION_MUST_CHECK(iptr)) {
411  switch (condition) {
412  case BRANCH_EQ:
413  M_BNEZ(reg, 1);
414  break;
415  case BRANCH_LE:
416  M_BGTZ(reg, 1);
417  break;
418  default:
419  vm_abort("emit_classcast_check: unknown condition %d", condition);
420  break;
421  }
423  }
424 }
425 
426 
427 /* emit_nullpointer_check ******************************************************
428 
429  Emit a NullPointerException check.
430 
431 *******************************************************************************/
432 
434 {
435  if (INSTRUCTION_MUST_CHECK(iptr)) {
436  M_BNEZ(reg, 1);
437  /* Destination register must not be REG_ZERO, because then no
438  SIGSEGV is thrown. */
440  }
441 }
442 
443 
444 /* emit_exception_check ********************************************************
445 
446  Emit an Exception check.
447 
448 *******************************************************************************/
449 
451 {
452  if (INSTRUCTION_MUST_CHECK(iptr)) {
453  M_BNEZ(REG_RESULT, 1);
454  /* Destination register must not be REG_ZERO, because then no
455  SIGSEGV is thrown. */
457  }
458 }
459 
460 
461 /* emit_trap_compiler **********************************************************
462 
463  Emit a trap instruction which calls the JIT compiler.
464 
465 *******************************************************************************/
466 
468 {
470 }
471 
473 {
475 }
476 
477 
478 /* emit_trap *******************************************************************
479 
480  Emit a trap instruction and return the original machine code.
481 
482 *******************************************************************************/
483 
484 uint32_t emit_trap(codegendata *cd)
485 {
486  uint32_t mcode;
487 
488  /* Get machine code which is patched back in later. The
489  trap is 1 instruction word long. */
490 
491  mcode = *((uint32_t*) cd->mcodeptr);
492 
493  // Generate a SIGILL.
494  M_UNDEFINED;
495 
496  return mcode;
497 }
498 
499 
500 /**
501  * Emit code to recompute the procedure vector.
502  */
504 {
505  int32_t disp = (int32_t) (cd->mcodeptr - cd->mcodebase);
506 
507  M_LDA(REG_PV, REG_RA, -disp);
508 }
509 
510 
511 /**
512  * Generates synchronization code to enter a monitor.
513  */
514 void emit_monitor_enter(jitdata* jd, int32_t syncslot_offset)
515 {
516  int32_t p;
517  int32_t disp;
518 
519  // Get required compiler data.
520  methodinfo* m = jd->m;
521  codegendata* cd = jd->cd;
522 
523 #if !defined(NDEBUG)
526 
527  for (p = 0; p < INT_ARG_CNT; p++)
529 
530  for (p = 0; p < FLT_ARG_CNT; p++)
531  M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
532 
533  syncslot_offset += (INT_ARG_CNT + FLT_ARG_CNT) * 8;
534  }
535 #endif /* !defined(NDEBUG) */
536 
537  /* decide which monitor enter function to call */
538 
539  if (m->flags & ACC_STATIC) {
540  disp = dseg_add_address(cd, &m->clazz->object.header);
541  M_ALD(REG_A0, REG_PV, disp);
542  }
543  else {
544  M_BNEZ(REG_A0, 1);
546  }
547 
548  M_AST(REG_A0, REG_SP, syncslot_offset);
550  M_ALD(REG_PV, REG_PV, disp);
551  M_JSR(REG_RA, REG_PV);
552  emit_recompute_pv(cd);
553 
554 #if !defined(NDEBUG)
556  for (p = 0; p < INT_ARG_CNT; p++)
558 
559  for (p = 0; p < FLT_ARG_CNT; p++)
560  M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
561 
562  M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
563  }
564 #endif
565 }
566 
567 
568 /**
569  * Generates synchronization code to leave a monitor.
570  */
571 void emit_monitor_exit(jitdata* jd, int32_t syncslot_offset)
572 {
573  int32_t disp;
574 
575  // Get required compiler data.
576  methodinfo* m = jd->m;
577  codegendata* cd = jd->cd;
578 
579  M_ALD(REG_A0, REG_SP, syncslot_offset);
580 
581  methoddesc* md = m->parseddesc;
582 
583  switch (md->returntype.type) {
584  case TYPE_INT:
585  case TYPE_LNG:
586  case TYPE_ADR:
587  M_LST(REG_RESULT, REG_SP, syncslot_offset);
588  break;
589  case TYPE_FLT:
590  case TYPE_DBL:
591  M_DST(REG_FRESULT, REG_SP, syncslot_offset);
592  break;
593  case TYPE_VOID:
594  break;
595  default:
596  assert(false);
597  break;
598  }
599 
601  M_ALD(REG_PV, REG_PV, disp);
602  M_JSR(REG_RA, REG_PV);
603  emit_recompute_pv(cd);
604 
605  switch (md->returntype.type) {
606  case TYPE_INT:
607  case TYPE_LNG:
608  case TYPE_ADR:
609  M_LLD(REG_RESULT, REG_SP, syncslot_offset);
610  break;
611  case TYPE_FLT:
612  case TYPE_DBL:
613  M_DLD(REG_FRESULT, REG_SP, syncslot_offset);
614  break;
615  case TYPE_VOID:
616  break;
617  default:
618  assert(false);
619  break;
620  }
621 }
622 
623 
624 /* emit_verbosecall_enter ******************************************************
625 
626  Generates the code for the call trace.
627 
628 *******************************************************************************/
629 
630 #if !defined(NDEBUG)
632 {
633  methodinfo *m;
634  codeinfo *code;
635  codegendata *cd;
636  registerdata *rd;
637  methoddesc *md;
638  int32_t stackframesize;
639  s4 disp;
640  s4 i, j, s;
641 
642  /* get required compiler data */
643 
644  m = jd->m;
645  code = jd->code;
646  cd = jd->cd;
647  rd = jd->rd;
648 
649  md = m->parseddesc;
650 
651  /* mark trace code */
652 
653  M_NOP;
654 
655  stackframesize = ARG_CNT + TMP_CNT + md->paramcount + 1;
656 
657  M_LDA(REG_SP, REG_SP, -(stackframesize * 8));
658  M_AST(REG_RA, REG_SP, 0 * 8);
659 
660  /* save all argument and temporary registers for leaf methods */
661 
662  if (code_is_leafmethod(code)) {
663  j = 1 + md->paramcount;
664 
665  for (i = 0; i < INT_ARG_CNT; i++, j++)
667 
668  for (i = 0; i < FLT_ARG_CNT; i++, j++)
670 
671  for (i = 0; i < INT_TMP_CNT; i++, j++)
672  M_LST(rd->tmpintregs[i], REG_SP, j * 8);
673 
674  for (i = 0; i < FLT_TMP_CNT; i++, j++)
675  M_DST(rd->tmpfltregs[i], REG_SP, j * 8);
676  }
677 
678  /* save argument registers */
679 
680  for (i = 0; i < md->paramcount; i++) {
681  if (!md->params[i].inmemory) {
682  s = md->params[i].regoff;
683 
684  switch (md->paramtypes[i].type) {
685  case TYPE_ADR:
686  case TYPE_INT:
687  case TYPE_LNG:
688  M_LST(s, REG_SP, (1 + i) * 8);
689  break;
690  case TYPE_FLT:
691  case TYPE_DBL:
692  M_DST(s, REG_SP, (1 + i) * 8);
693  break;
694  default:
695  assert(false);
696  break;
697  }
698  }
699  }
700 
701  disp = dseg_add_address(cd, m);
702  M_ALD(REG_A0, REG_PV, disp);
703  M_AADD_IMM(REG_SP, 1 * 8, REG_A1);
704  M_LDA(REG_A2, REG_SP, stackframesize * 8 + cd->stackframesize * 8);
705 
707  M_ALD(REG_PV, REG_PV, disp);
708  M_JSR(REG_RA, REG_PV);
709  disp = (s4) (cd->mcodeptr - cd->mcodebase);
710  M_LDA(REG_PV, REG_RA, -disp);
711  M_ALD(REG_RA, REG_SP, 0 * 8);
712 
713  /* restore argument registers */
714 
715  for (i = 0; i < md->paramcount; i++) {
716  if (!md->params[i].inmemory) {
717  s = md->params[i].regoff;
718 
719  switch (md->paramtypes[i].type) {
720  case TYPE_ADR:
721  case TYPE_INT:
722  case TYPE_LNG:
723  M_LLD(s, REG_SP, (1 + i) * 8);
724  break;
725  case TYPE_FLT:
726  case TYPE_DBL:
727  M_DLD(s, REG_SP, (1 + i) * 8);
728  break;
729  default:
730  assert(false);
731  break;
732  }
733  }
734  }
735 
736  /* restore all argument and temporary registers for leaf methods */
737 
738  if (code_is_leafmethod(code)) {
739  j = 1 + md->paramcount;
740 
741  for (i = 0; i < INT_ARG_CNT; i++, j++)
743 
744  for (i = 0; i < FLT_ARG_CNT; i++, j++)
746 
747  for (i = 0; i < INT_TMP_CNT; i++, j++)
748  M_LLD(rd->tmpintregs[i], REG_SP, j * 8);
749 
750  for (i = 0; i < FLT_TMP_CNT; i++, j++)
751  M_DLD(rd->tmpfltregs[i], REG_SP, j * 8);
752  }
753 
754  M_LDA(REG_SP, REG_SP, stackframesize * 8);
755 
756  /* mark trace code */
757 
758  M_NOP;
759 }
760 #endif /* !defined(NDEBUG) */
761 
762 
763 /* emit_verbosecall_exit *******************************************************
764 
765  Generates the code for the call trace.
766 
767 *******************************************************************************/
768 
769 #if !defined(NDEBUG)
771 {
772  methodinfo *m;
773  codegendata *cd;
774  registerdata *rd;
775  methoddesc *md;
776  s4 disp;
777 
778  /* get required compiler data */
779 
780  m = jd->m;
781  cd = jd->cd;
782  rd = jd->rd;
783 
784  md = m->parseddesc;
785 
786  /* mark trace code */
787 
788  M_NOP;
789 
790  M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
791  M_AST(REG_RA, REG_SP, 0 * 8);
792 
793  /* save return value */
794 
795  switch (md->returntype.type) {
796  case TYPE_ADR:
797  case TYPE_INT:
798  case TYPE_LNG:
799  M_LST(REG_RESULT, REG_SP, 1 * 8);
800  break;
801  case TYPE_FLT:
802  case TYPE_DBL:
803  M_DST(REG_FRESULT, REG_SP, 1 * 8);
804  break;
805  case TYPE_VOID:
806  break;
807  default:
808  assert(false);
809  break;
810  }
811 
812  disp = dseg_add_address(cd, m);
813  M_ALD(REG_A0, REG_PV, disp);
814  M_AADD_IMM(REG_SP, 1 * 8, REG_A1);
815 
817  M_ALD(REG_PV, REG_PV, disp);
818  M_JSR(REG_RA, REG_PV);
819  disp = (cd->mcodeptr - cd->mcodebase);
820  M_LDA(REG_PV, REG_RA, -disp);
821 
822  /* restore return value */
823 
824  switch (md->returntype.type) {
825  case TYPE_ADR:
826  case TYPE_INT:
827  case TYPE_LNG:
828  M_LLD(REG_RESULT, REG_SP, 1 * 8);
829  break;
830  case TYPE_FLT:
831  case TYPE_DBL:
832  M_DLD(REG_FRESULT, REG_SP, 1 * 8);
833  break;
834  case TYPE_VOID:
835  break;
836  default:
837  assert(false);
838  break;
839  }
840 
841  M_ALD(REG_RA, REG_SP, 0 * 8);
842  M_AADD_IMM(REG_SP, 2 * 8, REG_SP);
843 
844  /* mark trace code */
845 
846  M_NOP;
847 }
848 #endif /* !defined(NDEBUG) */
849 
850 
851 /*
852  * These are local overrides for various environment variables in Emacs.
853  * Please do not remove this and leave it at the end of the file, where
854  * Emacs will automagically detect them.
855  * ---------------------------------------------------------------------
856  * Local variables:
857  * mode: c++
858  * indent-tabs-mode: t
859  * c-basic-offset: 4
860  * tab-width: 4
861  * End:
862  * vim:noexpandtab:sw=4:ts=4:
863  */
const s4 abi_registers_float_argument[]
Definition: md-abi.cpp:107
#define REG_SP
Definition: md-abi.hpp:53
#define CODEGENDATA_FLAG_ERROR
java_object_t header
Definition: class.hpp:73
union varinfo::@19 vv
#define REG_PV
Definition: md-abi.hpp:42
#define M_JSR(a, b)
Definition: codegen.hpp:260
dummy_java_lang_Class object
Definition: class.hpp:88
#define M_ALD(a, b, disp)
Definition: codegen.hpp:345
#define M_BGTZ(a, disp)
Definition: codegen.hpp:257
#define REG_A1
Definition: md-abi.hpp:36
Definition: jit.hpp:126
void emit_monitor_exit(jitdata *jd, int32_t syncslot_offset)
Generates synchronization code to leave a monitor.
Definition: emit.cpp:565
#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 BRANCH_LE
#define JITDATA_HAS_FLAG_VERBOSECALL(jd)
Definition: jit.hpp:227
#define M_ILD(a, b, disp)
Definition: codegen.hpp:347
#define BRANCH_NE
#define M_LDA(a, b, disp)
Definition: codegen.hpp:163
#define BRANCH_GT
void emit_monitor_enter(jitdata *jd, int32_t syncslot_offset)
Generates synchronization code to enter a monitor.
Definition: emit.cpp:507
#define BRANCH_EQ
const s4 abi_registers_integer_argument[]
Definition: md-abi.cpp:64
#define M_AADD_IMM(a, b, c)
Definition: codegen.hpp:277
s4 dseg_add_address(codegendata *cd, void *value)
Definition: dseg.cpp:542
codeinfo * code
Definition: jit.hpp:128
#define M_BEQZ(a, disp)
Definition: codegen.hpp:252
#define REG_FRESULT
Definition: md-abi.hpp:59
s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
#define BRANCH_UNCONDITIONAL
#define dseg_add_functionptr(cd, value)
Definition: dseg.hpp:39
#define M_CMPEQ(a, b, c)
Definition: codegen.hpp:280
codegendata * cd
Definition: jit.hpp:129
#define REG_A2
Definition: md-abi.hpp:37
int * tmpfltregs
Definition: reg.hpp:72
void emit_arraystore_check(codegendata *cd, instruction *iptr)
Definition: emit.cpp:380
#define M_FST(a, b, disp)
Definition: codegen.hpp:357
#define M_FLD(a, b, disp)
Definition: codegen.hpp:354
#define COUNT_SPILLS
Definition: jit.hpp:108
void trace_java_call_exit(methodinfo *m, uint64_t *return_regs)
Definition: trace.cpp:240
Type type
Definition: reg.hpp:44
#define CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)
int64_t s8
Definition: types.hpp:48
void log_println(const char *text,...)
Definition: logging.cpp:193
#define CODEGENDATA_FLAG_LONGBRANCHES
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
Definition: reg.hpp:43
void emit_recompute_pv(codegendata *cd)
Emit code to recompute the procedure vector.
Definition: emit.cpp:495
void emit_abstractmethoderror_trap(codegendata *cd)
Definition: emit.cpp:468
static int code_is_leafmethod(codeinfo *code)
Definition: code.hpp:151
#define M_FMOV(b, c)
Definition: codegen.hpp:341
#define REG_IFTMP
Definition: md-abi.hpp:69
s4 dseg_add_s4(codegendata *cd, s4 value)
Definition: dseg.cpp:246
void vm_abort(const char *text,...)
Definition: vm.cpp:2586
s4 regoff
Definition: reg.hpp:47
#define M_BGEZ(a, disp)
Definition: codegen.hpp:256
void emit_verbosecall_enter(jitdata *jd)
Definition: emit.cpp:625
typedesc paramtypes[1]
Definition: descriptor.hpp:167
void emit_exception_check(codegendata *cd, instruction *iptr)
Definition: emit.cpp:447
#define M_CMPULT(a, b, c)
Definition: codegen.hpp:285
void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
Definition: trace.cpp:149
#define FLT_TMP_CNT
Definition: md-abi.hpp:82
void emit_lconst(codegendata *cd, s4 d, s8 value)
Definition: emit.cpp:233
dst_operand_t dst
#define LOCK_monitor_enter
Definition: builtin.hpp:124
classinfo * clazz
Definition: method.hpp:80
#define ARG_CNT
Definition: abi-asm.hpp:41
#define BRANCH_GE
#define M_ALD_INTERN(a, b, disp)
Definition: codegen.hpp:207
#define M_BLEZ(a, disp)
Definition: codegen.hpp:254
#define INT_ARG_CNT
Definition: md-abi.hpp:74
void emit_trap_compiler(codegendata *cd)
Definition: emit.cpp:463
#define M_ASUB_IMM(a, b, c)
Definition: codegen.hpp:278
void emit_trap(codegendata *cd, u1 Xd, int type)
Definition: emit-asm.hpp:563
MIIterator i
s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
Definition: emit.cpp:66
typedesc returntype
Definition: descriptor.hpp:166
int32_t s4
Definition: types.hpp:45
void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
Definition: emit.cpp:113
registerdata * rd
Definition: jit.hpp:130
#define M_AST(a, b, disp)
Definition: codegen.hpp:350
#define REG_RA
Definition: md-abi.hpp:41
void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
Definition: emit.cpp:346
#define LOCK_monitor_exit
Definition: builtin.hpp:132
#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_copy(jitdata *jd, instruction *iptr)
Definition: emit.cpp:153
s1_operand_t s1
#define TMP_CNT
Definition: abi-asm.hpp:42
uint32_t u4
Definition: types.hpp:46
#define BRANCH_LT
#define INT_TMP_CNT
Definition: md-abi.hpp:75
methoddesc * parseddesc
Definition: method.hpp:78
void emit_icmpeq_imm(codegendata *cd, int reg, int32_t value, int d)
Emits code comparing one integer register to an immediate value.
Definition: emit.cpp:253
#define VAROP(v)
Definition: jit.hpp:251
int * tmpintregs
Definition: reg.hpp:70
methodinfo * m
Definition: jit.hpp:127
static bool IS_INMEMORY(s4 flags)
Definition: stack.hpp:51
#define FLT_ARG_CNT
Definition: md-abi.hpp:81
s4 flags
Definition: reg.hpp:45
void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1)
Definition: emit.cpp:396
#define REG_METHODPTR
Definition: md-abi.hpp:43
#define M_CMPEQ_IMM(a, b, c)
Definition: codegen.hpp:287
void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 opt)
Definition: emit.cpp:263
int8_t s1
Definition: types.hpp:39
s4 dseg_add_s8(codegendata *cd, s8 value)
Definition: dseg.cpp:319
int16_t s2
Definition: types.hpp:42
#define M_DST(a, b, disp)
Definition: codegen.hpp:356
#define REG_ZERO
Definition: md-abi.hpp:54
void emit_iconst(codegendata *cd, s4 d, s4 value)
Definition: emit.cpp:220
#define M_LDA_INTERN(a, b, disp)
Definition: codegen.hpp:161
#define M_LLD(a, b, disp)
Definition: codegen.hpp:344
#define REG_ITMP3
Definition: md-abi.hpp:48
s4 flags
Definition: method.hpp:70
#define M_NOP
Definition: codegen.hpp:338
void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
Definition: emit.cpp:362
#define M_DLD(a, b, disp)
Definition: codegen.hpp:353
void emit_verbosecall_exit(jitdata *jd)
Definition: emit.cpp:766
uint32_t regoff
Definition: descriptor.hpp:153
#define M_BNEZ(a, disp)
Definition: codegen.hpp:255
#define OFFSET(s, el)
Definition: memory.hpp:90
#define INSTRUCTION_MUST_CHECK(iptr)
#define M_BR(disp)
Definition: codegen.hpp:250
#define REG_RESULT
Definition: md-abi.hpp:33
void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
Definition: emit.cpp:431
#define M_BLTZ(a, disp)
Definition: codegen.hpp:253
#define M_UNDEFINED
Definition: codegen.hpp:518