CACAO
emit.cpp
Go to the documentation of this file.
1 /* src/vm/jit/powerpc64/emit.cpp - PowerPC64 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 
28 #include <cassert>
29 
30 #include "vm/types.hpp"
31 
32 #include "mm/memory.hpp"
33 
34 #include "md-abi.hpp"
36 
37 #include "threads/lock.hpp"
38 
39 #include "vm/descriptor.hpp" // for typedesc, methoddesc, etc
40 #include "vm/options.hpp"
41 #include "vm/vm.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 (src->flags & INMEMORY) {
78 
79  disp = src->vv.regoff;
80 
81  if (IS_FLT_DBL_TYPE(src->type)) {
82  if (IS_2_WORD_TYPE(src->type))
83  M_DLD(tempreg, REG_SP, disp);
84  else
85  M_FLD(tempreg, REG_SP, disp);
86  }
87  else {
88  M_LLD(tempreg, REG_SP, disp);
89  }
90 
91  reg = tempreg;
92  }
93  else
94  reg = src->vv.regoff;
95 
96  return reg;
97 }
98 
99 
100 /* emit_store ******************************************************************
101 
102  Emits a possible store to a variable.
103 
104 *******************************************************************************/
105 
106 void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
107 {
108  codegendata *cd;
109 
110  /* get required compiler data */
111 
112  cd = jd->cd;
113 
114  if (dst->flags & INMEMORY) {
115  COUNT_SPILLS;
116 
117  if (IS_FLT_DBL_TYPE(dst->type)) {
118  if (IS_2_WORD_TYPE(dst->type))
119  M_DST(d, REG_SP, dst->vv.regoff);
120  else
121  M_FST(d, REG_SP, dst->vv.regoff);
122  }
123  else {
124  M_LST(d, REG_SP, dst->vv.regoff);
125  }
126  }
127 }
128 
129 
130 /* emit_copy *******************************************************************
131 
132  Generates a register/memory to register/memory copy.
133 
134 *******************************************************************************/
135 
136 void emit_copy(jitdata *jd, instruction *iptr)
137 {
138  codegendata *cd;
139  varinfo *src;
140  varinfo *dst;
141  s4 s1, d;
142 
143  /* get required compiler data */
144 
145  cd = jd->cd;
146 
147  /* get source and destination variables */
148 
149  src = VAROP(iptr->s1);
150  dst = VAROP(iptr->dst);
151 
152  if ((src->vv.regoff != dst->vv.regoff) ||
153  ((src->flags ^ dst->flags) & INMEMORY)) {
154 
155  if ((src->type == TYPE_RET) || (dst->type == TYPE_RET)) {
156  /* emit nothing, as the value won't be used anyway */
157  return;
158  }
159 
160  /* If one of the variables resides in memory, we can eliminate
161  the register move from/to the temporary register with the
162  order of getting the destination register and the load. */
163 
164  if (IS_INMEMORY(src->flags)) {
165  d = codegen_reg_of_var(iptr->opc, dst, REG_IFTMP);
166  s1 = emit_load(jd, iptr, src, d);
167  }
168  else {
169  s1 = emit_load(jd, iptr, src, REG_IFTMP);
170  d = codegen_reg_of_var(iptr->opc, dst, s1);
171  }
172 
173  if (s1 != d) {
174  if (IS_FLT_DBL_TYPE(src->type))
175  M_FMOV(s1, d);
176  else
177  M_MOV(s1, d);
178  }
179 
180  emit_store(jd, iptr, dst, d);
181  }
182 }
183 
184 
185 /* emit_iconst *****************************************************************
186 
187  XXX
188 
189 *******************************************************************************/
190 
191 void emit_iconst(codegendata *cd, s4 d, s4 value)
192 {
193  s4 disp;
194 
195  if ((value >= -32768) && (value <= 32767)) {
196  M_LDA_INTERN(d, REG_ZERO, value);
197  } else {
198  disp = dseg_add_s4(cd, value);
199  M_ILD(d, REG_PV, disp);
200  }
201 }
202 
203 void emit_lconst(codegendata *cd, s4 d, s8 value)
204 {
205  s4 disp;
206  if ((value >= -32768) && (value <= 32767)) {
207  M_LDA_INTERN(d, REG_ZERO, value);
208  } else {
209  disp = dseg_add_s8(cd, value);
210  M_LLD(d, REG_PV, disp);
211  }
212 }
213 
214 
215 /**
216  * Emits code updating the condition register by comparing one integer
217  * register to an immediate integer value.
218  */
219 void emit_icmp_imm(codegendata* cd, int reg, int32_t value)
220 {
221  int32_t disp;
222 
223  if ((value >= -32768) && (value <= 32767)) {
224  M_CMPI(reg, value);
225  } else {
226  assert(reg != REG_ITMP2);
227  disp = dseg_add_s4(cd, value);
228  M_ILD(REG_ITMP2, REG_PV, disp);
229  M_CMP(reg, REG_ITMP2);
230  }
231 }
232 
233 
234 /**
235  * Generates synchronization code to enter a monitor.
236  */
237 void emit_monitor_enter(jitdata* jd, int32_t syncslot_offset)
238 {
239  int32_t p;
240 
241  // Get required compiler data.
242  methodinfo* m = jd->m;
243  codegendata* cd = jd->cd;
244 
245 #if !defined (NDEBUG)
248 
249  for (p = 0; p < INT_ARG_CNT; p++)
251 
252  for (p = 0; p < FLT_ARG_CNT; p++)
253  M_DST(abi_registers_float_argument[p], REG_SP, LA_SIZE + PA_SIZE + (INT_ARG_CNT + p) * 8);
254 
255  /* used for LOCK_monitor_exit, adopt size because we created another stackframe */
256  syncslot_offset += (LA_SIZE_IN_POINTERS + PA_SIZE_IN_POINTERS + ARG_CNT) * 8;
257  }
258 #endif
259 
261  M_ALD(REG_ITMP3, REG_PV, p);
262  M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
264 
265  /* get or test the lock object */
266 
267  if (m->flags & ACC_STATIC) {
268  p = dseg_add_address(cd, &m->clazz->object.header);
269  M_ALD(REG_A0, REG_PV, p);
270  }
271  else {
272  M_TST(REG_A0);
273  M_BNE(1);
275  }
276 
277  M_AST(REG_A0, REG_SP, syncslot_offset);
278  M_JSR;
279 
280 #if !defined(NDEBUG)
282  for (p = 0; p < INT_ARG_CNT; p++)
284 
285  for (p = 0; p < FLT_ARG_CNT; p++)
286  M_DLD(abi_registers_float_argument[p], REG_SP, LA_SIZE + PA_SIZE + (INT_ARG_CNT + p) * 8);
287 
289  }
290 #endif
291 }
292 
293 
294 /**
295  * Generates synchronization code to leave a monitor.
296  */
297 void emit_monitor_exit(jitdata* jd, int32_t syncslot_offset)
298 {
299  int32_t disp;
300 
301  // Get required compiler data.
302  methodinfo* m = jd->m;
303  codegendata* cd = jd->cd;
304 
306  M_ALD(REG_ITMP3, REG_PV, disp);
307  M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
309 
310  /* we need to save the proper return value */
311 
312  methoddesc* md = m->parseddesc;
313 
314  switch (md->returntype.type) {
315  case TYPE_LNG:
316  case TYPE_INT:
317  case TYPE_ADR:
318  /* fall through */
319  M_LST(REG_RESULT , REG_SP, syncslot_offset + 8);
320  break;
321  case TYPE_FLT:
322  M_FST(REG_FRESULT, REG_SP, syncslot_offset + 8);
323  break;
324  case TYPE_DBL:
325  M_DST(REG_FRESULT, REG_SP, syncslot_offset + 8);
326  break;
327  case TYPE_VOID:
328  break;
329  default:
330  assert(false);
331  break;
332  }
333 
334  M_ALD(REG_A0, REG_SP, syncslot_offset);
335  M_JSR;
336 
337  /* and now restore the proper return value */
338 
339  switch (md->returntype.type) {
340  case TYPE_LNG:
341  case TYPE_INT:
342  case TYPE_ADR:
343  /* fall through */
344  M_LLD(REG_RESULT , REG_SP, syncslot_offset + 8);
345  break;
346  case TYPE_FLT:
347  M_FLD(REG_FRESULT, REG_SP, syncslot_offset + 8);
348  break;
349  case TYPE_DBL:
350  M_DLD(REG_FRESULT, REG_SP, syncslot_offset + 8);
351  break;
352  case TYPE_VOID:
353  break;
354  default:
355  assert(false);
356  break;
357  }
358 }
359 
360 
361 /* emit_verbosecall_enter ******************************************************
362 
363  Generates the code for the call trace.
364 
365 *******************************************************************************/
366 
367 #if !defined(NDEBUG)
369 {
370  methodinfo *m;
371  codegendata *cd;
372  methoddesc *md;
373  int32_t paramcount;
374  int32_t stackframesize;
375  s4 disp;
376  s4 i, s;
377 
378  /* get required compiler data */
379 
380  m = jd->m;
381  cd = jd->cd;
382 
383  md = m->parseddesc;
384 
385  /* mark trace code */
386 
387  M_NOP;
388 
389  /* align stack to 16-bytes */
390 
391  paramcount = md->paramcount;
392  ALIGN_2(paramcount);
393  stackframesize = LA_SIZE + PA_SIZE + md->paramcount * 8;
394 
395  M_MFLR(REG_ZERO);
397  M_STDU(REG_SP, REG_SP, -stackframesize);
398 
399 #if defined(__DARWIN__)
400  #warning "emit_verbosecall_enter not implemented"
401 #else
402  /* save argument registers */
403 
404  for (i = 0; i < md->paramcount; i++) {
405  if (!md->params[i].inmemory) {
406  s = md->params[i].regoff;
407 
408  switch (md->paramtypes[i].type) {
409  case TYPE_ADR:
410  case TYPE_INT:
411  case TYPE_LNG:
412  M_LST(s, REG_SP, LA_SIZE+PA_SIZE+i*8);
413  break;
414  case TYPE_FLT:
415  case TYPE_DBL:
416  M_DST(s, REG_SP, LA_SIZE+PA_SIZE+i*8);
417  break;
418  default:
419  assert(false);
420  break;
421  }
422  }
423  }
424 #endif
425 
426  disp = dseg_add_address(cd, m);
427  M_ALD(REG_A0, REG_PV, disp);
429  M_AADD_IMM(REG_SP, stackframesize + cd->stackframesize * 8, REG_A2);
430  /* call via function descriptor, XXX: what about TOC? */
432  M_ALD(REG_ITMP2, REG_PV, disp);
435  M_JSR;
436 
437 #if defined(__DARWIN__)
438  #warning "emit_verbosecall_enter not implemented"
439 #else
440  /* restore argument registers */
441 
442  for (i = 0; i < md->paramcount; i++) {
443  if (!md->params[i].inmemory) {
444  s = md->params[i].regoff;
445 
446  switch (md->paramtypes[i].type) {
447  case TYPE_ADR:
448  case TYPE_INT:
449  case TYPE_LNG:
450  M_LLD(s, REG_SP, LA_SIZE+PA_SIZE+i*8);
451  break;
452  case TYPE_FLT:
453  case TYPE_DBL:
454  M_DLD(s, REG_SP, LA_SIZE+PA_SIZE+i*8);
455  break;
456  default:
457  assert(false);
458  break;
459  }
460  }
461  }
462 #endif
463 
464  M_ALD(REG_ZERO, REG_SP, stackframesize + LA_LR_OFFSET);
465  M_MTLR(REG_ZERO);
466  M_LDA(REG_SP, REG_SP, stackframesize);
467 
468  /* mark trace code */
469 
470  M_NOP;
471 }
472 #endif
473 
474 
475 /* emit_verbosecall_exit ******************************************************
476 
477  Generates the code for the call trace.
478 
479 *******************************************************************************/
480 
481 #if !defined(NDEBUG)
483 {
484  methodinfo *m;
485  codegendata *cd;
486  methoddesc *md;
487  s4 disp;
488 
489  /* get required compiler data */
490 
491  m = jd->m;
492  cd = jd->cd;
493 
494  md = m->parseddesc;
495 
496  /* mark trace code */
497 
498  M_NOP;
499 
500  M_MFLR(REG_ZERO);
501  M_LDA(REG_SP, REG_SP, -(LA_SIZE+PA_SIZE+10*8));
503 
504  /* save return value */
505 
506  switch (md->returntype.type) {
507  case TYPE_ADR:
508  case TYPE_INT:
509  case TYPE_LNG:
511  break;
512  case TYPE_FLT:
513  case TYPE_DBL:
515  break;
516  case TYPE_VOID:
517  break;
518  default:
519  assert(false);
520  break;
521  }
522 
523  disp = dseg_add_address(cd, m);
524  M_ALD(REG_A0, REG_PV, disp);
526 
528  /* call via function descriptor, XXX: what about TOC ? */
529  M_ALD(REG_ITMP2, REG_PV, disp);
532  M_JSR;
533 
534  /* restore return value */
535 
536  switch (md->returntype.type) {
537  case TYPE_ADR:
538  case TYPE_INT:
539  case TYPE_LNG:
541  break;
542  case TYPE_FLT:
543  case TYPE_DBL:
545  break;
546  case TYPE_VOID:
547  break;
548  default:
549  assert(false);
550  break;
551  }
552 
555  M_MTLR(REG_ZERO);
556 
557  /* mark trace code */
558 
559  M_NOP;
560 }
561 #endif
562 
563 
564 /* emit_branch *****************************************************************
565 
566  Emits the code for conditional and unconditional branchs.
567 
568 *******************************************************************************/
569 
570 void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 opt)
571 {
572  s4 checkdisp;
573  s4 branchdisp;
574 
575  /* calculate the different displacements */
576 
577  checkdisp = disp + 4;
578  branchdisp = (disp - 4) >> 2;
579 
580  /* check which branch to generate */
581 
582  if (condition == BRANCH_UNCONDITIONAL) {
583  /* check displacement for overflow */
584 
585  if ((checkdisp < (s4) 0xfe000000) || (checkdisp > (s4) 0x01fffffc)) {
586  /* if the long-branches flag isn't set yet, do it */
587 
589  cd->flags |= (CODEGENDATA_FLAG_ERROR |
591  }
592 
593  vm_abort("emit_branch: emit unconditional long-branch code");
594  }
595  else {
596  M_BR(branchdisp);
597  }
598  }
599  else {
600  /* and displacement for overflow */
601 
602  if ((checkdisp < (s4) 0xffff8000) || (checkdisp > (s4) 0x00007fff)) {
603  /* if the long-branches flag isn't set yet, do it */
604 
606  cd->flags |= (CODEGENDATA_FLAG_ERROR |
608  }
609 
610  // Subtract 1 instruction from the displacement as the
611  // actual branch is the second instruction.
612  checkdisp = checkdisp - 4;
613  branchdisp = branchdisp - 1;
614 
615  if ((checkdisp < (int32_t) 0xfe000000) || (checkdisp > (int32_t) 0x01fffffc)) {
616  vm_abort("emit_branch: emit conditional long-branch code");
617  }
618  else {
619  switch (condition) {
620  case BRANCH_EQ:
621  M_BNE(1);
622  M_BR(branchdisp);
623  break;
624  case BRANCH_NE:
625  M_BEQ(1);
626  M_BR(branchdisp);
627  break;
628  case BRANCH_LT:
629  M_BGE(1);
630  M_BR(branchdisp);
631  break;
632  case BRANCH_GE:
633  M_BLT(1);
634  M_BR(branchdisp);
635  break;
636  case BRANCH_GT:
637  M_BLE(1);
638  M_BR(branchdisp);
639  break;
640  case BRANCH_LE:
641  M_BGT(1);
642  M_BR(branchdisp);
643  break;
644  case BRANCH_NAN:
645  vm_abort("emit_branch: long BRANCH_NAN");
646  break;
647  default:
648  vm_abort("emit_branch: unknown condition %d", condition);
649  break;
650  }
651  }
652  }
653  else {
654  switch (condition) {
655  case BRANCH_EQ:
656  M_BEQ(branchdisp);
657  break;
658  case BRANCH_NE:
659  M_BNE(branchdisp);
660  break;
661  case BRANCH_LT:
662  M_BLT(branchdisp);
663  break;
664  case BRANCH_GE:
665  M_BGE(branchdisp);
666  break;
667  case BRANCH_GT:
668  M_BGT(branchdisp);
669  break;
670  case BRANCH_LE:
671  M_BLE(branchdisp);
672  break;
673  case BRANCH_NAN:
674  M_BNAN(branchdisp);
675  break;
676  default:
677  vm_abort("emit_branch: unknown condition %d", condition);
678  break;
679  }
680  }
681  }
682 }
683 
684 /* emit_arrayindexoutofbounds_check ********************************************
685 
686  Emit a ArrayIndexOutOfBoundsException check.
687 
688 *******************************************************************************/
689 
691 {
692  if (checkbounds) {
694  M_CMPU(s2, REG_ITMP3);
695  M_BLT(1);
696  /* ALD is 4 byte aligned, ILD 2, onyl LWZ is byte aligned */
698  }
699 }
700 
701 
702 /* emit_arraystore_check *******************************************************
703 
704  Emit an ArrayStoreException check.
705 
706 *******************************************************************************/
707 
709 {
710  if (INSTRUCTION_MUST_CHECK(iptr)) {
711  M_TST(REG_RESULT);
712  M_BNE(1);
713  /* ALD is 4 byte aligned, ILD 2, onyl LWZ is byte aligned */
715  }
716 }
717 
718 
719 /* emit_arithmetic_check *******************************************************
720 
721  Emit an ArithmeticException check.
722 
723 *******************************************************************************/
724 
726 {
727  if (INSTRUCTION_MUST_CHECK(iptr)) {
728  M_TST(reg);
729  M_BNE(1);
730  /* ALD is 4 byte aligned, ILD 2, onyl LWZ is byte aligned */
732  }
733 }
734 
735 
736 /* emit_classcast_check ********************************************************
737 
738  Emit a ClassCastException check.
739 
740 *******************************************************************************/
741 
742 void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1)
743 {
744  if (INSTRUCTION_MUST_CHECK(iptr)) {
745  switch(condition) {
746  case BRANCH_LE:
747  M_BGT(1);
748  break;
749  case BRANCH_EQ:
750  M_BNE(1);
751  break;
752  case BRANCH_NE:
753  M_BEQ(1);
754  break;
755  case BRANCH_GT:
756  M_BLE(1);
757  break;
758  default:
759  vm_abort("emit_classcast_check: unknown condition %d", condition);
760  break;
761  }
762 
763  /* ALD is 4 byte aligned, ILD 2, onyl LWZ is byte aligned */
765  }
766 }
767 
768 
769 /* emit_nullpointer_check ******************************************************
770 
771  Emit a NullPointerException check.
772 
773 *******************************************************************************/
774 
776 {
777  if (INSTRUCTION_MUST_CHECK(iptr)) {
778  M_TST(reg);
779  M_BNE(1);
780  /* ALD is 4 byte aligned, ILD 2, onyl LWZ is byte aligned */
782  }
783 }
784 
785 /* emit_exception_check ********************************************************
786 
787  Emit an Exception check.
788 
789 *******************************************************************************/
790 
792 {
793  if (INSTRUCTION_MUST_CHECK(iptr)) {
794  M_TST(REG_RESULT);
795  M_BNE(1);
796  /* ALD is 4 byte aligned, ILD 2, onyl LWZ is byte aligned */
798  }
799 }
800 
801 
802 /* emit_trap_compiler **********************************************************
803 
804  Emit a trap instruction which calls the JIT compiler.
805 
806 *******************************************************************************/
807 
809 {
811 }
812 
814 {
816 }
817 
818 
819 /* emit_trap *******************************************************************
820 
821  Emit a trap instruction and return the original machine code.
822 
823 *******************************************************************************/
824 
825 uint32_t emit_trap(codegendata *cd)
826 {
827  // Get machine code which is patched back in later. The trap is 1
828  // instruction word long.
829  uint32_t mcode = *((uint32_t*) cd->mcodeptr);
830 
831  M_ILLEGAL;
832 
833  return mcode;
834 }
835 
836 
837 /**
838  * Emit code to recompute the procedure vector.
839  */
841 {
842  int32_t disp = (int32_t) (cd->mcodeptr - cd->mcodebase);
843 
844  M_MFLR(REG_ITMP1);
845  M_LDA(REG_PV, REG_ITMP1, -disp);
846 }
847 
848 
849 /*
850  * These are local overrides for various environment variables in Emacs.
851  * Please do not remove this and leave it at the end of the file, where
852  * Emacs will automagically detect them.
853  * ---------------------------------------------------------------------
854  * Local variables:
855  * mode: c++
856  * indent-tabs-mode: t
857  * c-basic-offset: 4
858  * tab-width: 4
859  * End:
860  * vim:noexpandtab:sw=4:ts=4:
861  */
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
#define M_CMPU(a, b)
Definition: codegen.hpp:209
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 ALIGN_2(a)
Definition: global.hpp:72
#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_BEQ(off)
Definition: codegen.hpp:482
#define M_ILD(a, b, disp)
Definition: codegen.hpp:347
#define M_CMP(a, b)
Definition: codegen.hpp:430
#define BRANCH_NE
#define M_BNE(off)
Definition: codegen.hpp:483
#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
#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
codegendata * cd
Definition: jit.hpp:129
#define PA_SIZE_IN_POINTERS
Definition: md-abi.hpp:88
#define M_CMPI(a, b)
Definition: codegen.hpp:208
#define LA_LR_OFFSET
Definition: md-abi.hpp:97
#define REG_A2
Definition: md-abi.hpp:37
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
#define M_TST(a, b)
Definition: codegen.hpp:428
#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
#define M_ILLEGAL
Definition: codegen.hpp:176
#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
void emit_verbosecall_enter(jitdata *jd)
Definition: emit.cpp:625
typedesc paramtypes[1]
Definition: descriptor.hpp:167
#define IS_2_WORD_TYPE(a)
Definition: global.hpp:132
void emit_exception_check(codegendata *cd, instruction *iptr)
Definition: emit.cpp:447
#define M_MFLR(a)
Definition: codegen.hpp:224
void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
Definition: trace.cpp:149
#define M_BNAN(a)
Definition: codegen.hpp:202
void emit_lconst(codegendata *cd, s4 d, s8 value)
Definition: emit.cpp:233
#define M_LWZ(a, b, disp)
Definition: codegen.hpp:265
#define LA_SIZE
Definition: md-abi.hpp:93
dst_operand_t dst
#define PA_SIZE
Definition: md-abi.hpp:147
#define M_STDU(a, b, disp)
Definition: codegen.hpp:216
bool checkbounds
Definition: options.cpp:89
#define LOCK_monitor_enter
Definition: builtin.hpp:124
classinfo * clazz
Definition: method.hpp:80
#define M_MTLR(a)
Definition: codegen.hpp:227
#define M_MTCTR(a)
Definition: codegen.hpp:226
#define ARG_CNT
Definition: abi-asm.hpp:41
#define BRANCH_GE
#define IS_FLT_DBL_TYPE(a)
Definition: global.hpp:131
#define M_ALD_INTERN(a, b, disp)
Definition: codegen.hpp:207
#define INT_ARG_CNT
Definition: md-abi.hpp:74
void emit_trap_compiler(codegendata *cd)
Definition: emit.cpp:463
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
#define M_BGE(off)
Definition: codegen.hpp:484
int32_t s4
Definition: types.hpp:45
void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
Definition: emit.cpp:113
#define M_AST(a, b, disp)
Definition: codegen.hpp:350
#define BRANCH_NAN
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_icmp_imm(codegendata *cd, int reg, int32_t value)
Emits code comparing a single register.
Definition: emit.cpp:243
void emit_copy(jitdata *jd, instruction *iptr)
Definition: emit.cpp:153
s1_operand_t s1
uint32_t u4
Definition: types.hpp:46
#define BRANCH_LT
#define M_BGT(off)
Definition: codegen.hpp:485
methoddesc * parseddesc
Definition: method.hpp:78
#define VAROP(v)
Definition: jit.hpp:251
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
#define M_BLT(off)
Definition: codegen.hpp:486
void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1)
Definition: emit.cpp:396
#define REG_METHODPTR
Definition: md-abi.hpp:43
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
#define M_BLE(off)
Definition: codegen.hpp:487
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 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
#define LA_SIZE_IN_POINTERS
Definition: md-abi.hpp:95
void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
Definition: emit.cpp:431
#define REG_ITMP1
Definition: md-abi.hpp:46