From d2364a742a2165a1e5ee329d2316d765c67c600b Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Wed, 31 Mar 1993 01:48:22 -0700 Subject: [PATCH] pa.c (output_cbranch): New function. * pa.c (output_cbranch): New function. Given the operands of the branch, possible nullification, length of the branch, possible branch negation, and the branch insn itself, return the output template for the desired conditional branch. (output_bb): Likewise, but for branch on bit. From-SVN: r3949 --- gcc/config/pa/pa.c | 169 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 04012010807..14142ec717c 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -2913,6 +2913,175 @@ hppa_builtin_saveregs (arglist) offset, 0, 0, OPTAB_LIB_WIDEN)); } +/* This routine handles all the normal conditional branch sequences we + might need to generate. It handles compare immediate vs compare + register, nullification of delay slots, varying length branches, + negated branches, and all combinations of the above. It returns the + output appropriate to emit the branch corresponding to all given + parameters. */ + +char * +output_cbranch (operands, nullify, length, negated, insn) + rtx *operands; + int nullify, length, negated; + rtx insn; +{ + static char buf[100]; + int useskip = 0; + + /* A forward branch over a single nullified insn can be done with a + comclr instruction. This avoids a single cycle penalty due to + mis-predicted branch if we fall through (branch not taken). */ + + if (length == 1 + && JUMP_LABEL (insn) == next_nonnote_insn (NEXT_INSN (insn)) + && nullify) + useskip = 1; + + switch (length) + { + + /* Short conditional branch. May nullify either direction. */ + case 1: + if (useskip) + strcpy (buf, "com%I2clr,"); + else + strcpy (buf, "com%I2b,"); + if (negated) + strcat (buf, "%B3"); + else + strcat (buf, "%S3"); + if (useskip) + strcat (buf, " %2,%1,0"); + else if (nullify) + strcat (buf, ",n %2,%1,%0"); + else + strcat (buf, " %2,%1,%0%#"); + break; + + /* Long conditional branch, possible forward nullification. Also + note all conditional branches have a length of 4 when not + optimizing! */ + case 2: + case 4: + strcpy (buf, "com%I2clr,"); + if (negated) + strcat (buf, "%S3"); + else + strcat (buf, "%B3"); + if (nullify) + strcat (buf, " %2,%1,0\n\tbl,n %0,0"); + else + strcat (buf, " %2,%1,0\n\tbl %0,0%#"); + break; + + /* Long backward conditional branch with nullification. */ + case 3: + strcpy (buf, "com%I2b,"); + if (negated) + strcat (buf, "%S3"); + else + strcat (buf, "%B3"); + strcat (buf, " %2,%1,.+16\n\tnop\n\t bl %0,0"); + break; + + default: + abort(); + } + return buf; +} + +/* This routine handles all the branch-on-bit conditional branch sequences we + might need to generate. It handles nullification of delay slots, + varying length branches, negated branches and all combinations of the + above. it returns the appropriate output template to emit the branch. */ + +char * +output_bb (operands, nullify, length, negated, insn, which) + rtx *operands; + int nullify, length, negated; + rtx insn; + int which; +{ + static char buf[100]; + int useskip = 0; + + /* A forward branch over a single nullified insn can be done with a + extrs instruction. This avoids a single cycle penalty due to + mis-predicted branch if we fall through (branch not taken). */ + + if (length == 1 + && JUMP_LABEL (insn) == next_nonnote_insn (NEXT_INSN (insn)) + && nullify) + useskip = 1; + + switch (length) + { + + /* Short conditional branch. May nullify either direction. */ + case 1: + if (useskip) + strcpy (buf, "extrs,"); + else + strcpy (buf, "bb,"); + if ((which == 0 && negated) + || (which == 1 && ! negated)) + strcat (buf, ">="); + else + strcat (buf, "<"); + if (useskip) + strcat (buf, " %0,%1,1,0"); + else if (nullify && negated) + strcat (buf, ",n %0,%1,%3"); + else if (nullify && ! negated) + strcat (buf, ",n %0,%1,%2"); + else if (! nullify && negated) + strcat (buf, "%0,%1,%3%#"); + else if (! nullify && ! negated) + strcat (buf, " %0,%1,%2%#"); + break; + + /* Long conditional branch, possible forward nullification. Also + note all conditional branches have a length of 4 when not + optimizing! */ + case 2: + case 4: + strcpy (buf, "extrs,"); + if ((which == 0 && negated) + || (which == 1 && ! negated)) + strcat (buf, "<"); + else + strcat (buf, ">="); + if (nullify && negated) + strcat (buf, " %0,%1,1,0\n\tbl,n %3,0"); + else if (nullify && ! negated) + strcat (buf, " %0,%1,1,0\n\tbl,n %2,0"); + else if (! nullify && negated) + strcat (buf, " %0,%1,1,0\n\tbl %3,0%#"); + else if (! nullify && ! negated) + strcat (buf, " %0,%1,1,0\n\tbl %2,0%#"); + break; + + /* Long backward conditional branch with nullification. */ + case 3: + strcpy (buf, "bb,"); + if ((which == 0 && negated) + || (which == 1 && ! negated)) + strcat (buf, "<"); + else + strcat (buf, ">="); + if (negated) + strcat (buf, " %0,%1,.+16\n\tnop\n\t bl %3,0"); + else + strcat (buf, " %0,%1,.+16\n\tnop\n\t bl %2,0"); + break; + + default: + abort(); + } + return buf; +} + extern struct obstack *saveable_obstack; /* In HPUX 8.0's shared library scheme, special relocations are needed -- 2.30.2