aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>1997-06-08 15:20:21 -0600
committerJeff Law <law@gcc.gnu.org>1997-06-08 15:20:21 -0600
commit4bcb9e3f39582de69f645029ce5d279ac1eff598 (patch)
tree5dd3a034af8c98f23f65255b614429d6c1807bcc /gcc
parent359255a957150238a4517312232c6bd491b9c4a1 (diff)
downloadgcc-4bcb9e3f39582de69f645029ce5d279ac1eff598.zip
gcc-4bcb9e3f39582de69f645029ce5d279ac1eff598.tar.gz
gcc-4bcb9e3f39582de69f645029ce5d279ac1eff598.tar.bz2
pa.md (conditional branch insns): Get length right for branches to targets which can not be reached with a "bl"...
* pa.md (conditional branch insns): Get length right for branches to targets which can not be reached with a "bl" instruction. * pa.c (output_cbranch): Handle branches to targets which can not be reached with a "bl" instruction. From-SVN: r14172
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/pa/pa.c62
-rw-r--r--gcc/config/pa/pa.md26
2 files changed, 80 insertions, 8 deletions
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 0eae0b1..75c1021 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -4390,6 +4390,68 @@ output_cbranch (operands, nullify, length, negated, insn)
}
break;
+ case 20:
+ /* Very long branch. Right now we only handle these when not
+ optimizing. See "jump" pattern in pa.md for details. */
+ if (optimize)
+ abort ();
+
+ /* Create a reversed conditional branch which branches around
+ the following insns. */
+ if (negated)
+ strcpy (buf, "com%I2b,%S3,n %2,%1,.+20");
+ else
+ strcpy (buf, "com%I2b,%B3,n %2,%1,.+20");
+ output_asm_insn (buf, operands);
+
+ /* Output an insn to save %r1. */
+ output_asm_insn ("stw %%r1,-16(%%r30)", operands);
+
+ /* Now output a very long branch to the original target. */
+ output_asm_insn ("ldil L'%l0,%%r1\n\tbe R'%l0(%%sr4,%%r1)", operands);
+
+ /* Now restore the value of %r1 in the delay slot. We're not
+ optimizing so we know nothing else can be in the delay slot. */
+ return "ldw -16(%%r30),%%r1";
+
+ case 28:
+ /* Very long branch when generating PIC code. Right now we only
+ handle these when not optimizing. See "jump" pattern in pa.md
+ for details. */
+ if (optimize)
+ abort ();
+
+ /* Create a reversed conditional branch which branches around
+ the following insns. */
+ if (negated)
+ strcpy (buf, "com%I2b,%S3,n %2,%1,.+28");
+ else
+ strcpy (buf, "com%I2b,%B3,n %2,%1,.+28");
+ output_asm_insn (buf, operands);
+
+ /* Output an insn to save %r1. */
+ output_asm_insn ("stw %%r1,-16(%%r30)", operands);
+
+ /* Now output a very long PIC branch to the original target. */
+ {
+ rtx xoperands[5];
+
+ xoperands[0] = operands[0];
+ xoperands[1] = operands[1];
+ xoperands[2] = operands[2];
+ xoperands[3] = operands[3];
+ xoperands[4] = gen_label_rtx ();
+
+ output_asm_insn ("bl .+8,%%r1\n\taddil L'%l0-%l4,%%r1", xoperands);
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
+ CODE_LABEL_NUMBER (xoperands[4]));
+ output_asm_insn ("ldo R'%l0-%l4(%%r1),%%r1\n\tbv 0(%%r1)", xoperands);
+ }
+
+ /* Now restore the value of %r1 in the delay slot. We're not
+ optimizing so we know nothing else can be in the delay slot. */
+ return "ldw -16(%%r30),%%r1";
+
default:
abort();
}
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 9a4165c..3551974 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -1034,10 +1034,15 @@
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
+ (const_int 8184))
+ (const_int 4)
+ (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
+ (const_int 262100))
+ (const_int 8)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
;; Match the negated branch.
@@ -1057,10 +1062,15 @@
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
+ (const_int 8184))
+ (const_int 4)
+ (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
+ (const_int 262100))
+ (const_int 8)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
;; Branch on Bit patterns.
(define_insn ""