1 /* src/vm/jit/emit-common.c - common code emitter functions
3 Copyright (C) 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
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.
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.
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
36 #include "vm/options.h"
37 #include "vm/statistics.h"
39 #include "vm/jit/emit-common.h"
40 #include "vm/jit/jit.hpp"
41 #include "vm/jit/patcher-common.h"
44 /* emit_load_s1 ****************************************************************
46 Emits a possible load of the first source operand.
48 *******************************************************************************/
50 s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg)
55 src = VAROP(iptr->s1);
57 reg = emit_load(jd, iptr, src, tempreg);
63 /* emit_load_s2 ****************************************************************
65 Emits a possible load of the second source operand.
67 *******************************************************************************/
69 s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg)
74 src = VAROP(iptr->sx.s23.s2);
76 reg = emit_load(jd, iptr, src, tempreg);
82 /* emit_load_s3 ****************************************************************
84 Emits a possible load of the third source operand.
86 *******************************************************************************/
88 s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg)
93 src = VAROP(iptr->sx.s23.s3);
95 reg = emit_load(jd, iptr, src, tempreg);
101 /* emit_load_s1_low ************************************************************
103 Emits a possible load of the low 32-bits of the first long source
106 *******************************************************************************/
108 #if SIZEOF_VOID_P == 4
109 s4 emit_load_s1_low(jitdata *jd, instruction *iptr, s4 tempreg)
114 src = VAROP(iptr->s1);
116 reg = emit_load_low(jd, iptr, src, tempreg);
123 /* emit_load_s2_low ************************************************************
125 Emits a possible load of the low 32-bits of the second long source
128 *******************************************************************************/
130 #if SIZEOF_VOID_P == 4
131 s4 emit_load_s2_low(jitdata *jd, instruction *iptr, s4 tempreg)
136 src = VAROP(iptr->sx.s23.s2);
138 reg = emit_load_low(jd, iptr, src, tempreg);
145 /* emit_load_s3_low ************************************************************
147 Emits a possible load of the low 32-bits of the third long source
150 *******************************************************************************/
152 #if SIZEOF_VOID_P == 4
153 s4 emit_load_s3_low(jitdata *jd, instruction *iptr, s4 tempreg)
158 src = VAROP(iptr->sx.s23.s3);
160 reg = emit_load_low(jd, iptr, src, tempreg);
167 /* emit_load_s1_high ***********************************************************
169 Emits a possible load of the high 32-bits of the first long source
172 *******************************************************************************/
174 #if SIZEOF_VOID_P == 4
175 s4 emit_load_s1_high(jitdata *jd, instruction *iptr, s4 tempreg)
180 src = VAROP(iptr->s1);
182 reg = emit_load_high(jd, iptr, src, tempreg);
189 /* emit_load_s2_high ***********************************************************
191 Emits a possible load of the high 32-bits of the second long source
194 *******************************************************************************/
196 #if SIZEOF_VOID_P == 4
197 s4 emit_load_s2_high(jitdata *jd, instruction *iptr, s4 tempreg)
202 src = VAROP(iptr->sx.s23.s2);
204 reg = emit_load_high(jd, iptr, src, tempreg);
211 /* emit_load_s3_high ***********************************************************
213 Emits a possible load of the high 32-bits of the third long source
216 *******************************************************************************/
218 #if SIZEOF_VOID_P == 4
219 s4 emit_load_s3_high(jitdata *jd, instruction *iptr, s4 tempreg)
224 src = VAROP(iptr->sx.s23.s3);
226 reg = emit_load_high(jd, iptr, src, tempreg);
233 /* emit_store_dst **************************************************************
235 This function generates the code to store the result of an
236 operation back into a spilled pseudo-variable. If the
237 pseudo-variable has not been spilled in the first place, this
238 function will generate nothing.
240 *******************************************************************************/
242 void emit_store_dst(jitdata *jd, instruction *iptr, s4 d)
244 emit_store(jd, iptr, VAROP(iptr->dst), d);
248 /* emit_patcher_traps **********************************************************
250 Generates the code for the patcher traps.
252 *******************************************************************************/
254 void emit_patcher_traps(jitdata *jd)
263 /* get required compiler data */
268 /* generate patcher traps code */
270 for (pr = list_first(code->patchers); pr != NULL; pr = list_next(code->patchers, pr)) {
272 /* Calculate the patch position where the original machine
273 code is located and the trap should be placed. */
275 tmpmcodeptr = (u1 *) (cd->mcodebase + pr->mpc);
277 /* Patch in the trap to call the signal handler (done at
280 savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
281 cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
283 mcode = emit_trap(cd);
285 cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
287 /* Remember the original machine code which is patched
288 back in later (done at runtime). */
295 /* emit_bccz *******************************************************************
297 Emit conditional and unconditional branch instructions on integer
300 *******************************************************************************/
302 void emit_bccz(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options)
307 /* Target basic block already has an PC, so we can generate the
308 branch immediately. */
310 if ((target->mpc >= 0)) {
311 STATISTICS(count_branches_resolved++);
313 /* calculate the mpc of the branch instruction */
315 branchmpc = cd->mcodeptr - cd->mcodebase;
316 disp = target->mpc - branchmpc;
318 #if defined(ENABLE_STATISTICS)
320 if ((int8_t)disp == disp) count_emit_branch_8bit++;
321 else if ((int16_t)disp == disp) count_emit_branch_16bit++;
322 else if ((int32_t)disp == disp) count_emit_branch_32bit++;
323 # if SIZEOF_VOID_P == 8
324 else if ((int64_t)disp == disp) count_emit_branch_64bit++;
328 emit_branch(cd, disp, condition, reg, options);
331 /* current mcodeptr is the correct position,
332 afterwards emit the NOPs */
334 codegen_add_branch_ref(cd, target, condition, reg, options);
336 /* generate NOPs as placeholder for branch code */
343 /* emit_bcc ********************************************************************
345 Emit conditional and unconditional branch instructions on condition
348 *******************************************************************************/
350 void emit_bcc(codegendata *cd, basicblock *target, s4 condition, u4 options)
352 emit_bccz(cd, target, condition, -1, options);
356 /* emit_br *********************************************************************
358 Wrapper for unconditional branches.
360 *******************************************************************************/
362 void emit_br(codegendata *cd, basicblock *target)
364 emit_bcc(cd, target, BRANCH_UNCONDITIONAL, BRANCH_OPT_NONE);
368 /* emit_bxxz *******************************************************************
370 Wrappers for branches on one integer register.
372 *******************************************************************************/
374 #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
376 void emit_beqz(codegendata *cd, basicblock *target, s4 reg)
378 emit_bccz(cd, target, BRANCH_EQ, reg, BRANCH_OPT_NONE);
381 void emit_bnez(codegendata *cd, basicblock *target, s4 reg)
383 emit_bccz(cd, target, BRANCH_NE, reg, BRANCH_OPT_NONE);
386 void emit_bltz(codegendata *cd, basicblock *target, s4 reg)
388 emit_bccz(cd, target, BRANCH_LT, reg, BRANCH_OPT_NONE);
391 void emit_bgez(codegendata *cd, basicblock *target, s4 reg)
393 emit_bccz(cd, target, BRANCH_GE, reg, BRANCH_OPT_NONE);
396 void emit_bgtz(codegendata *cd, basicblock *target, s4 reg)
398 emit_bccz(cd, target, BRANCH_GT, reg, BRANCH_OPT_NONE);
401 void emit_blez(codegendata *cd, basicblock *target, s4 reg)
403 emit_bccz(cd, target, BRANCH_LE, reg, BRANCH_OPT_NONE);
406 #endif /* SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER */
409 /* emit_bxx ********************************************************************
411 Wrappers for branches on two integer registers.
413 We use PACK_REGS here, so we don't have to change the branchref
414 data structure and the emit_bccz function.
416 *******************************************************************************/
418 #if SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS
420 void emit_beq(codegendata *cd, basicblock *target, s4 s1, s4 s2)
422 emit_bccz(cd, target, BRANCH_EQ, PACK_REGS(s1, s2), BRANCH_OPT_NONE);
425 void emit_bne(codegendata *cd, basicblock *target, s4 s1, s4 s2)
427 emit_bccz(cd, target, BRANCH_NE, PACK_REGS(s1, s2), BRANCH_OPT_NONE);
430 #endif /* SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS */
433 /* emit_bxx ********************************************************************
435 Wrappers for branches on condition codes.
437 *******************************************************************************/
439 #if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER
441 void emit_beq(codegendata *cd, basicblock *target)
443 emit_bcc(cd, target, BRANCH_EQ, BRANCH_OPT_NONE);
446 void emit_bne(codegendata *cd, basicblock *target)
448 emit_bcc(cd, target, BRANCH_NE, BRANCH_OPT_NONE);
451 void emit_blt(codegendata *cd, basicblock *target)
453 emit_bcc(cd, target, BRANCH_LT, BRANCH_OPT_NONE);
456 void emit_bge(codegendata *cd, basicblock *target)
458 emit_bcc(cd, target, BRANCH_GE, BRANCH_OPT_NONE);
461 void emit_bgt(codegendata *cd, basicblock *target)
463 emit_bcc(cd, target, BRANCH_GT, BRANCH_OPT_NONE);
466 void emit_ble(codegendata *cd, basicblock *target)
468 emit_bcc(cd, target, BRANCH_LE, BRANCH_OPT_NONE);
471 #if SUPPORT_BRANCH_CONDITIONAL_UNSIGNED_CONDITIONS
472 void emit_bult(codegendata *cd, basicblock *target)
474 emit_bcc(cd, target, BRANCH_ULT, BRANCH_OPT_NONE);
477 void emit_bule(codegendata *cd, basicblock *target)
479 emit_bcc(cd, target, BRANCH_ULE, BRANCH_OPT_NONE);
482 void emit_buge(codegendata *cd, basicblock *target)
484 emit_bcc(cd, target, BRANCH_UGE, BRANCH_OPT_NONE);
487 void emit_bugt(codegendata *cd, basicblock *target)
489 emit_bcc(cd, target, BRANCH_UGT, BRANCH_OPT_NONE);
493 #if defined(__POWERPC__) || defined(__POWERPC64__)
494 void emit_bnan(codegendata *cd, basicblock *target)
496 emit_bcc(cd, target, BRANCH_NAN, BRANCH_OPT_NONE);
500 #endif /* SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER */
503 /* emit_label_bccz *************************************************************
505 Emit a branch to a label. Possibly emit the branch, if it is a
508 *******************************************************************************/
510 void emit_label_bccz(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
513 branch_label_ref_t *br;
517 /* get the label list */
519 list = cd->brancheslabel;
521 /* search if the label is already in the list */
523 for (br = list_first(list); br != NULL; br = list_next(list, br)) {
524 /* is this entry the correct label? */
526 if (br->label == label)
531 /* current mcodeptr is the correct position,
532 afterwards emit the NOPs */
534 codegen_branch_label_add(cd, label, condition, reg, options);
536 /* generate NOPs as placeholder for branch code */
542 /* Branch reference was found. */
544 /* calculate the mpc of the branch instruction */
546 mpc = cd->mcodeptr - cd->mcodebase;
547 disp = br->mpc - mpc;
549 #if defined(ENABLE_STATISTICS)
551 if ((int8_t)disp == disp) count_emit_branch_8bit++;
552 else if ((int16_t)disp == disp) count_emit_branch_16bit++;
553 else if ((int32_t)disp == disp) count_emit_branch_32bit++;
554 # if SIZEOF_VOID_P == 8
555 else if ((int64_t)disp == disp) count_emit_branch_64bit++;
559 emit_branch(cd, disp, condition, reg, options);
561 /* now remove the branch reference */
563 list_remove(list, br);
567 /* emit_label ******************************************************************
569 Emit a label for a branch. Possibly emit the branch, if it is a
572 *******************************************************************************/
574 void emit_label(codegendata *cd, s4 label)
577 branch_label_ref_t *br;
582 /* get the label list */
584 list = cd->brancheslabel;
586 /* search if the label is already in the list */
588 for (br = list_first(list); br != NULL; br = list_next(list, br)) {
589 /* is this entry the correct label? */
591 if (br->label == label)
596 /* No branch reference found, add the label to the list (use
597 invalid values for condition and register). */
599 codegen_branch_label_add(cd, label, -1, -1, BRANCH_OPT_NONE );
603 /* Branch reference was found. */
605 /* calculate the mpc of the branch instruction */
607 mpc = cd->mcodeptr - cd->mcodebase;
608 disp = mpc - br->mpc;
610 /* temporary set the mcodeptr */
612 mcodeptr = cd->mcodeptr;
613 cd->mcodeptr = cd->mcodebase + br->mpc;
615 #if defined(ENABLE_STATISTICS)
617 if ((int8_t)disp == disp) count_emit_branch_8bit++;
618 else if ((int16_t)disp == disp) count_emit_branch_16bit++;
619 else if ((int32_t)disp == disp) count_emit_branch_32bit++;
620 # if SIZEOF_VOID_P == 8
621 else if ((int64_t)disp == disp) count_emit_branch_64bit++;
625 emit_branch(cd, disp, br->condition, br->reg, br->options);
627 /* restore mcodeptr */
629 cd->mcodeptr = mcodeptr;
631 /* now remove the branch reference */
633 list_remove(list, br);
637 /* emit_label_bcc **************************************************************
639 Emit conditional and unconditional label-branch instructions on
642 *******************************************************************************/
644 void emit_label_bcc(codegendata *cd, s4 label, s4 condition, u4 options)
646 emit_label_bccz(cd, label, condition, -1, options);
650 /* emit_label_br ***************************************************************
652 Wrapper for unconditional label-branches.
654 *******************************************************************************/
656 void emit_label_br(codegendata *cd, s4 label)
658 emit_label_bcc(cd, label, BRANCH_UNCONDITIONAL, BRANCH_OPT_NONE);
662 /* emit_label_bxxz *************************************************************
664 Wrappers for label-branches on one integer register.
666 *******************************************************************************/
668 #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
670 void emit_label_beqz(codegendata *cd, s4 label, s4 reg)
672 emit_label_bccz(cd, label, BRANCH_EQ, reg, BRANCH_OPT_NONE);
675 #endif /* SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER */
678 /* emit_label_bxx **************************************************************
680 Wrappers for label-branches on condition codes.
682 *******************************************************************************/
684 #if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER
686 void emit_label_beq(codegendata *cd, s4 label)
688 emit_label_bcc(cd, label, BRANCH_EQ, BRANCH_OPT_NONE);
691 void emit_label_bne(codegendata *cd, s4 label)
693 emit_label_bcc(cd, label, BRANCH_NE, BRANCH_OPT_NONE);
696 void emit_label_blt(codegendata *cd, s4 label)
698 emit_label_bcc(cd, label, BRANCH_LT, BRANCH_OPT_NONE);
701 void emit_label_bge(codegendata *cd, s4 label)
703 emit_label_bcc(cd, label, BRANCH_GE, BRANCH_OPT_NONE);
706 void emit_label_bgt(codegendata *cd, s4 label)
708 emit_label_bcc(cd, label, BRANCH_GT, BRANCH_OPT_NONE);
711 void emit_label_ble(codegendata *cd, s4 label)
713 emit_label_bcc(cd, label, BRANCH_LE, BRANCH_OPT_NONE);
716 #endif /* SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER */
720 * These are local overrides for various environment variables in Emacs.
721 * Please do not remove this and leave it at the end of the file, where
722 * Emacs will automagically detect them.
723 * ---------------------------------------------------------------------
726 * indent-tabs-mode: t
730 * vim:noexpandtab:sw=4:ts=4: