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