arm.md (cbranchsi4): Correct calculation of branch ranges.
authorRichard Earnshaw <rearnsha@arm.com>
Mon, 15 Jan 2001 16:17:08 +0000 (16:17 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Mon, 15 Jan 2001 16:17:08 +0000 (16:17 +0000)
* arm.md (cbranchsi4): Correct calculation of branch ranges.
(negated_cbranchsi4): Likewise.

From-SVN: r39039

gcc/ChangeLog
gcc/config/arm/arm.md

index 1fb8a66..c70dc0a 100644 (file)
@@ -1,5 +1,10 @@
 2001-01-15  Richard Earnshaw  <rearnsha@arm.com>
 
+       * arm.md (cbranchsi4): Correct calculation of branch ranges.
+       (negated_cbranchsi4): Likewise.
+
+2001-01-15  Richard Earnshaw  <rearnsha@arm.com>
+
        * config/arm/semi.h (SUBTARGET_EXTRA_SPECS): Define.
        (SUBTARGET_EXTRA_ASM_SPEC): Define to empty string.
        (ASM_SPEC): Call subtarget_extra_asm_spec.  Don't
index f7d4e6d..103d5ad 100644 (file)
 
 \f
 
-;; Comapre & branch insns
+;; Compare & branch insns
+;; The range calcualations are based as follows:
+;; For forward branches, the address calculation returns the address of
+;; the next instruction.  This is 2 beyond the branch instruction.
+;; For backward branches, the address calculation returns the address of
+;; the first instruction in this pattern (cmp).  This is 2 before the branch
+;; instruction for the shortest sequence, and 4 before the branch instruction
+;; if we have to jump around an unconditional branch.
+;; To the basic branch range the PC offset must be added (this is +4).
+;; So for forward branches we have 
+;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
+;; And for backward branches we have 
+;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
+;;
+;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
+;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
 
 (define_insn "cbranchsi4"
   [(set (pc)
            (const_int 4)
            (if_then_else
                (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
-                    (le (minus (match_dup 3) (pc)) (const_int 2054)))
+                    (le (minus (match_dup 3) (pc)) (const_int 2048)))
                (const_int 6)
                (const_int 8))))]
 )
    (set (attr "length") 
         (if_then_else
            (and (ge (minus (match_dup 3) (pc)) (const_int -250))
-                (le (minus (match_dup 3) (pc)) (const_int 254)))
+                (le (minus (match_dup 3) (pc)) (const_int 256)))
            (const_int 4)
            (if_then_else
-               (and (ge (minus (match_dup 3) (pc)) (const_int -2044))
-                    (le (minus (match_dup 3) (pc)) (const_int 2044)))
+               (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
+                    (le (minus (match_dup 3) (pc)) (const_int 2048)))
                (const_int 6)
                (const_int 8))))]
 )