Merged subtype and current trunk.
[cacao.git] / src / vm / jit / emit-common.cpp
1 /* src/vm/jit/emit-common.cpp - common code emitter functions
2
3    Copyright (C) 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29 #include <stdint.h>
30
31 #include <algorithm>
32
33 #include "vm/types.h"
34
35 #include "arch.h"
36 #include "codegen.h"
37
38 #include "toolbox/list.hpp"
39
40 #include "vm/options.h"
41 #include "vm/statistics.h"
42
43 #include "vm/jit/emit-common.hpp"
44 #include "vm/jit/jit.hpp"
45 #include "vm/jit/patcher-common.hpp"
46
47
48 /* emit_load_s1 ****************************************************************
49
50    Emits a possible load of the first source operand.
51
52 *******************************************************************************/
53
54 s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg)
55 {
56         varinfo *src;
57         s4       reg;
58
59         src = VAROP(iptr->s1);
60
61         reg = emit_load(jd, iptr, src, tempreg);
62
63         return reg;
64 }
65
66
67 /* emit_load_s2 ****************************************************************
68
69    Emits a possible load of the second source operand.
70
71 *******************************************************************************/
72
73 s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg)
74 {
75         varinfo *src;
76         s4       reg;
77
78         src = VAROP(iptr->sx.s23.s2);
79
80         reg = emit_load(jd, iptr, src, tempreg);
81
82         return reg;
83 }
84
85
86 /* emit_load_s3 ****************************************************************
87
88    Emits a possible load of the third source operand.
89
90 *******************************************************************************/
91
92 s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg)
93 {
94         varinfo *src;
95         s4       reg;
96
97         src = VAROP(iptr->sx.s23.s3);
98
99         reg = emit_load(jd, iptr, src, tempreg);
100
101         return reg;
102 }
103
104
105 /* emit_load_s1_low ************************************************************
106
107    Emits a possible load of the low 32-bits of the first long source
108    operand.
109
110 *******************************************************************************/
111
112 #if SIZEOF_VOID_P == 4
113 s4 emit_load_s1_low(jitdata *jd, instruction *iptr, s4 tempreg)
114 {
115         varinfo *src;
116         s4       reg;
117
118         src = VAROP(iptr->s1);
119
120         reg = emit_load_low(jd, iptr, src, tempreg);
121
122         return reg;
123 }
124 #endif
125
126
127 /* emit_load_s2_low ************************************************************
128
129    Emits a possible load of the low 32-bits of the second long source
130    operand.
131
132 *******************************************************************************/
133
134 #if SIZEOF_VOID_P == 4
135 s4 emit_load_s2_low(jitdata *jd, instruction *iptr, s4 tempreg)
136 {
137         varinfo *src;
138         s4       reg;
139
140         src = VAROP(iptr->sx.s23.s2);
141
142         reg = emit_load_low(jd, iptr, src, tempreg);
143
144         return reg;
145 }
146 #endif
147
148
149 /* emit_load_s3_low ************************************************************
150
151    Emits a possible load of the low 32-bits of the third long source
152    operand.
153
154 *******************************************************************************/
155
156 #if SIZEOF_VOID_P == 4
157 s4 emit_load_s3_low(jitdata *jd, instruction *iptr, s4 tempreg)
158 {
159         varinfo *src;
160         s4       reg;
161
162         src = VAROP(iptr->sx.s23.s3);
163
164         reg = emit_load_low(jd, iptr, src, tempreg);
165
166         return reg;
167 }
168 #endif
169
170
171 /* emit_load_s1_high ***********************************************************
172
173    Emits a possible load of the high 32-bits of the first long source
174    operand.
175
176 *******************************************************************************/
177
178 #if SIZEOF_VOID_P == 4
179 s4 emit_load_s1_high(jitdata *jd, instruction *iptr, s4 tempreg)
180 {
181         varinfo *src;
182         s4       reg;
183
184         src = VAROP(iptr->s1);
185
186         reg = emit_load_high(jd, iptr, src, tempreg);
187
188         return reg;
189 }
190 #endif
191
192
193 /* emit_load_s2_high ***********************************************************
194
195    Emits a possible load of the high 32-bits of the second long source
196    operand.
197
198 *******************************************************************************/
199
200 #if SIZEOF_VOID_P == 4
201 s4 emit_load_s2_high(jitdata *jd, instruction *iptr, s4 tempreg)
202 {
203         varinfo *src;
204         s4       reg;
205
206         src = VAROP(iptr->sx.s23.s2);
207
208         reg = emit_load_high(jd, iptr, src, tempreg);
209
210         return reg;
211 }
212 #endif
213
214
215 /* emit_load_s3_high ***********************************************************
216
217    Emits a possible load of the high 32-bits of the third long source
218    operand.
219
220 *******************************************************************************/
221
222 #if SIZEOF_VOID_P == 4
223 s4 emit_load_s3_high(jitdata *jd, instruction *iptr, s4 tempreg)
224 {
225         varinfo *src;
226         s4       reg;
227
228         src = VAROP(iptr->sx.s23.s3);
229
230         reg = emit_load_high(jd, iptr, src, tempreg);
231
232         return reg;
233 }
234 #endif
235
236
237 /* emit_store_dst **************************************************************
238
239    This function generates the code to store the result of an
240    operation back into a spilled pseudo-variable.  If the
241    pseudo-variable has not been spilled in the first place, this
242    function will generate nothing.
243     
244 *******************************************************************************/
245
246 void emit_store_dst(jitdata *jd, instruction *iptr, s4 d)
247 {
248         emit_store(jd, iptr, VAROP(iptr->dst), d);
249 }
250
251
252 /* emit_patcher_traps **********************************************************
253
254    Generates the code for the patcher traps.
255
256 *******************************************************************************/
257
258 void emit_patcher_traps(jitdata *jd)
259 {
260         codegendata *cd;
261         codeinfo    *code;
262         u1          *savedmcodeptr;
263         u1          *tmpmcodeptr;
264         uint32_t     mcode;
265
266         /* get required compiler data */
267
268         cd   = jd->cd;
269         code = jd->code;
270
271         // Generate patcher traps code.
272         for (List<patchref_t>::iterator it = code->patchers->begin(); it != code->patchers->end(); it++) {
273                 patchref_t& pr = *it;
274
275                 /* Calculate the patch position where the original machine
276                    code is located and the trap should be placed. */
277
278                 tmpmcodeptr = (u1 *) (cd->mcodebase + pr.mpc);
279
280                 /* Patch in the trap to call the signal handler (done at
281                    compile time). */
282
283                 savedmcodeptr = cd->mcodeptr;   /* save current mcodeptr          */
284                 cd->mcodeptr  = tmpmcodeptr;    /* set mcodeptr to patch position */
285
286                 mcode = emit_trap(cd);
287
288                 cd->mcodeptr = savedmcodeptr;   /* restore the current mcodeptr   */
289
290                 /* Remember the original machine code which is patched
291                    back in later (done at runtime). */
292
293                 pr.mcode = mcode;
294         }
295 }
296
297
298 /* emit_bccz *******************************************************************
299
300    Emit conditional and unconditional branch instructions on integer
301    regiseters.
302
303 *******************************************************************************/
304
305 void emit_bccz(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options)
306 {
307         s4 branchmpc;
308         s4 disp;
309
310         /* Target basic block already has an PC, so we can generate the
311            branch immediately. */
312
313         if ((target->mpc >= 0)) {
314                 STATISTICS(count_branches_resolved++);
315
316                 /* calculate the mpc of the branch instruction */
317
318                 branchmpc = cd->mcodeptr - cd->mcodebase;
319                 disp      = target->mpc - branchmpc;
320
321 #if defined(ENABLE_STATISTICS)
322                 count_emit_branch++;
323                 if ((int8_t)disp == disp)  count_emit_branch_8bit++; 
324                 else if ((int16_t)disp == disp) count_emit_branch_16bit++;
325                 else if ((int32_t)disp == disp) count_emit_branch_32bit++;
326 # if SIZEOF_VOID_P == 8
327                 else if ((int64_t)disp == disp) count_emit_branch_64bit++;
328 # endif
329 #endif
330
331                 emit_branch(cd, disp, condition, reg, options);
332         }
333         else {
334                 /* current mcodeptr is the correct position,
335                    afterwards emit the NOPs */
336
337                 codegen_add_branch_ref(cd, target, condition, reg, options);
338
339                 /* generate NOPs as placeholder for branch code */
340
341                 BRANCH_NOPS;
342         }
343 }
344
345
346 /* emit_bcc ********************************************************************
347
348    Emit conditional and unconditional branch instructions on condition
349    codes.
350
351 *******************************************************************************/
352
353 void emit_bcc(codegendata *cd, basicblock *target, s4 condition, u4 options)
354 {
355         emit_bccz(cd, target, condition, -1, options);
356 }
357
358
359 /* emit_br *********************************************************************
360
361    Wrapper for unconditional branches.
362
363 *******************************************************************************/
364
365 void emit_br(codegendata *cd, basicblock *target)
366 {
367         emit_bcc(cd, target, BRANCH_UNCONDITIONAL, BRANCH_OPT_NONE);
368 }
369
370
371 /* emit_bxxz *******************************************************************
372
373    Wrappers for branches on one integer register.
374
375 *******************************************************************************/
376
377 #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
378
379 void emit_beqz(codegendata *cd, basicblock *target, s4 reg)
380 {
381         emit_bccz(cd, target, BRANCH_EQ, reg, BRANCH_OPT_NONE);
382 }
383
384 void emit_bnez(codegendata *cd, basicblock *target, s4 reg)
385 {
386         emit_bccz(cd, target, BRANCH_NE, reg, BRANCH_OPT_NONE);
387 }
388
389 void emit_bltz(codegendata *cd, basicblock *target, s4 reg)
390 {
391         emit_bccz(cd, target, BRANCH_LT, reg, BRANCH_OPT_NONE);
392 }
393
394 void emit_bgez(codegendata *cd, basicblock *target, s4 reg)
395 {
396         emit_bccz(cd, target, BRANCH_GE, reg, BRANCH_OPT_NONE);
397 }
398
399 void emit_bgtz(codegendata *cd, basicblock *target, s4 reg)
400 {
401         emit_bccz(cd, target, BRANCH_GT, reg, BRANCH_OPT_NONE);
402 }
403
404 void emit_blez(codegendata *cd, basicblock *target, s4 reg)
405 {
406         emit_bccz(cd, target, BRANCH_LE, reg, BRANCH_OPT_NONE);
407 }
408
409 #endif /* SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER */
410
411
412 /* emit_bxx ********************************************************************
413
414    Wrappers for branches on two integer registers.
415
416    We use PACK_REGS here, so we don't have to change the branchref
417    data structure and the emit_bccz function.
418
419 *******************************************************************************/
420
421 #if SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS
422
423 void emit_beq(codegendata *cd, basicblock *target, s4 s1, s4 s2)
424 {
425         emit_bccz(cd, target, BRANCH_EQ, PACK_REGS(s1, s2), BRANCH_OPT_NONE);
426 }
427
428 void emit_bne(codegendata *cd, basicblock *target, s4 s1, s4 s2)
429 {
430         emit_bccz(cd, target, BRANCH_NE, PACK_REGS(s1, s2), BRANCH_OPT_NONE);
431 }
432
433 #endif /* SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS */
434
435
436 /* emit_bxx ********************************************************************
437
438    Wrappers for branches on condition codes.
439
440 *******************************************************************************/
441
442 #if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER
443
444 void emit_beq(codegendata *cd, basicblock *target)
445 {
446         emit_bcc(cd, target, BRANCH_EQ, BRANCH_OPT_NONE);
447 }
448
449 void emit_bne(codegendata *cd, basicblock *target)
450 {
451         emit_bcc(cd, target, BRANCH_NE, BRANCH_OPT_NONE);
452 }
453
454 void emit_blt(codegendata *cd, basicblock *target)
455 {
456         emit_bcc(cd, target, BRANCH_LT, BRANCH_OPT_NONE);
457 }
458
459 void emit_bge(codegendata *cd, basicblock *target)
460 {
461         emit_bcc(cd, target, BRANCH_GE, BRANCH_OPT_NONE);
462 }
463
464 void emit_bgt(codegendata *cd, basicblock *target)
465 {
466         emit_bcc(cd, target, BRANCH_GT, BRANCH_OPT_NONE);
467 }
468
469 void emit_ble(codegendata *cd, basicblock *target)
470 {
471         emit_bcc(cd, target, BRANCH_LE, BRANCH_OPT_NONE);
472 }
473
474 #if SUPPORT_BRANCH_CONDITIONAL_UNSIGNED_CONDITIONS
475 void emit_bult(codegendata *cd, basicblock *target)
476 {
477         emit_bcc(cd, target, BRANCH_ULT, BRANCH_OPT_NONE);
478 }
479
480 void emit_bule(codegendata *cd, basicblock *target)
481 {
482         emit_bcc(cd, target, BRANCH_ULE, BRANCH_OPT_NONE);
483 }
484
485 void emit_buge(codegendata *cd, basicblock *target)
486 {
487         emit_bcc(cd, target, BRANCH_UGE, BRANCH_OPT_NONE);
488 }
489
490 void emit_bugt(codegendata *cd, basicblock *target)
491 {
492         emit_bcc(cd, target, BRANCH_UGT, BRANCH_OPT_NONE);
493 }
494 #endif
495
496 #if defined(__POWERPC__) || defined(__POWERPC64__)
497 void emit_bnan(codegendata *cd, basicblock *target)
498 {
499         emit_bcc(cd, target, BRANCH_NAN, BRANCH_OPT_NONE);
500 }
501 #endif
502
503 #endif /* SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER */
504
505
506 /* emit_label_bccz *************************************************************
507
508    Emit a branch to a label.  Possibly emit the branch, if it is a
509    backward branch.
510
511 *******************************************************************************/
512
513 void emit_label_bccz(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
514 {
515         // Search if the label is already in the list.
516         DumpList<branch_label_ref_t*>::iterator it;
517         for (it = cd->brancheslabel->begin(); it != cd->brancheslabel->end(); it++) {
518                 branch_label_ref_t* br = *it;
519
520                 /* is this entry the correct label? */
521
522                 if (br->label == label)
523                         break;
524         }
525
526         if (it == cd->brancheslabel->end()) {
527                 /* current mcodeptr is the correct position,
528                    afterwards emit the NOPs */
529
530                 codegen_branch_label_add(cd, label, condition, reg, options);
531
532                 /* generate NOPs as placeholder for branch code */
533
534                 BRANCH_NOPS;
535                 return;
536         }
537
538         // Branch reference was found.
539         branch_label_ref_t* br = *it;
540
541         /* calculate the mpc of the branch instruction */
542
543         int32_t mpc  = cd->mcodeptr - cd->mcodebase;
544         int32_t disp = br->mpc - mpc;
545
546 #if defined(ENABLE_STATISTICS)
547         count_emit_branch++;
548         if ((int8_t)disp == disp)  count_emit_branch_8bit++; 
549         else if ((int16_t)disp == disp) count_emit_branch_16bit++;
550         else if ((int32_t)disp == disp) count_emit_branch_32bit++;
551 # if SIZEOF_VOID_P == 8
552         else if ((int64_t)disp == disp) count_emit_branch_64bit++;
553 # endif
554 #endif
555
556         emit_branch(cd, disp, condition, reg, options);
557
558         // Now remove the branch reference.
559         cd->brancheslabel->remove(br);
560 }
561
562
563 /* emit_label ******************************************************************
564
565    Emit a label for a branch.  Possibly emit the branch, if it is a
566    forward branch.
567
568 *******************************************************************************/
569
570 void emit_label(codegendata *cd, s4 label)
571 {
572         u1* mcodeptr;
573
574         // Search if the label is already in the list.
575         DumpList<branch_label_ref_t*>::iterator it;
576         for (it = cd->brancheslabel->begin(); it != cd->brancheslabel->end(); it++) {
577                 branch_label_ref_t* br = *it;
578
579                 /* is this entry the correct label? */
580
581                 if (br->label == label)
582                         break;
583         }
584
585         if (it == cd->brancheslabel->end()) {
586                 /* No branch reference found, add the label to the list (use
587                    invalid values for condition and register). */
588
589                 codegen_branch_label_add(cd, label, -1, -1, BRANCH_OPT_NONE );
590                 return;
591         }
592
593         // Branch reference was found.
594         branch_label_ref_t* br = *it;
595
596         // Calculate the mpc of the branch instruction.
597         int32_t mpc  = cd->mcodeptr - cd->mcodebase;
598         int32_t disp = mpc - br->mpc;
599
600         /* temporary set the mcodeptr */
601
602         mcodeptr     = cd->mcodeptr;
603         cd->mcodeptr = cd->mcodebase + br->mpc;
604
605 #if defined(ENABLE_STATISTICS)
606         count_emit_branch++;
607         if ((int8_t)disp == disp)  count_emit_branch_8bit++; 
608         else if ((int16_t)disp == disp) count_emit_branch_16bit++;
609         else if ((int32_t)disp == disp) count_emit_branch_32bit++;
610 # if SIZEOF_VOID_P == 8
611         else if ((int64_t)disp == disp) count_emit_branch_64bit++;
612 # endif
613 #endif
614
615         emit_branch(cd, disp, br->condition, br->reg, br->options);
616
617         /* restore mcodeptr */
618
619         cd->mcodeptr = mcodeptr;
620
621         // Now remove the branch reference.
622         cd->brancheslabel->remove(br);
623 }
624
625
626 /* emit_label_bcc **************************************************************
627
628    Emit conditional and unconditional label-branch instructions on
629    condition codes.
630
631 *******************************************************************************/
632
633 void emit_label_bcc(codegendata *cd, s4 label, s4 condition, u4 options)
634 {
635         emit_label_bccz(cd, label, condition, -1, options);
636 }
637
638
639 /* emit_label_br ***************************************************************
640
641    Wrapper for unconditional label-branches.
642
643 *******************************************************************************/
644
645 void emit_label_br(codegendata *cd, s4 label)
646 {
647         emit_label_bcc(cd, label, BRANCH_UNCONDITIONAL, BRANCH_OPT_NONE);
648 }
649
650
651 /* emit_label_bxxz *************************************************************
652
653    Wrappers for label-branches on one integer register.
654
655 *******************************************************************************/
656
657 #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
658
659 void emit_label_beqz(codegendata *cd, s4 label, s4 reg)
660 {
661         emit_label_bccz(cd, label, BRANCH_EQ, reg, BRANCH_OPT_NONE);
662 }
663
664 void emit_label_bnez(codegendata *cd, s4 label, s4 reg)
665 {
666         emit_label_bccz(cd, label, BRANCH_NE, reg, BRANCH_OPT_NONE);
667 }
668
669 #endif /* SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER */
670
671
672 /* emit_label_bxx **************************************************************
673
674    Wrappers for label-branches on condition codes.
675
676 *******************************************************************************/
677
678 #if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER
679
680 void emit_label_beq(codegendata *cd, s4 label)
681 {
682         emit_label_bcc(cd, label, BRANCH_EQ, BRANCH_OPT_NONE);
683 }
684
685 void emit_label_bne(codegendata *cd, s4 label)
686 {
687         emit_label_bcc(cd, label, BRANCH_NE, BRANCH_OPT_NONE);
688 }
689
690 void emit_label_blt(codegendata *cd, s4 label)
691 {
692         emit_label_bcc(cd, label, BRANCH_LT, BRANCH_OPT_NONE);
693 }
694
695 void emit_label_bge(codegendata *cd, s4 label)
696 {
697         emit_label_bcc(cd, label, BRANCH_GE, BRANCH_OPT_NONE);
698 }
699
700 void emit_label_bgt(codegendata *cd, s4 label)
701 {
702         emit_label_bcc(cd, label, BRANCH_GT, BRANCH_OPT_NONE);
703 }
704
705 void emit_label_ble(codegendata *cd, s4 label)
706 {
707         emit_label_bcc(cd, label, BRANCH_LE, BRANCH_OPT_NONE);
708 }
709
710 #endif /* SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER */
711
712
713 /*
714  * These are local overrides for various environment variables in Emacs.
715  * Please do not remove this and leave it at the end of the file, where
716  * Emacs will automagically detect them.
717  * ---------------------------------------------------------------------
718  * Local variables:
719  * mode: c++
720  * indent-tabs-mode: t
721  * c-basic-offset: 4
722  * tab-width: 4
723  * End:
724  * vim:noexpandtab:sw=4:ts=4:
725  */