The length computation of "branch" flavour insn length attribute computed a length one instruction too short, e.g. in the following test case:

#define N0(N) if (X++ < N) __builtin_avr_nop()

#define N1(N) N0(N);N0(N);N0(N);N0(N);N0(N);N0(N);N0(N);N0(N);N0(N);N0(N)
#define N2(N) N1(N);N1(N);N1(N);N1(N);N1(N);N1(N);N1(N);N1(N);N1(N);N1(N)
#define N3(N) N2(N);N2(N);N2(N);N2(N);N2(N);N2(N);N2(N);N2(N);N2(N);N2(N)
#define N4(N) N3(N);N3(N);N3(N);N3(N);N3(N);N3(N);N3(N);N3(N);N3(N);N3(N)

void bra_63 (unsigned char x)
{
    if (x > 0)
    {
        unsigned X = 0;
        N4 (63);
    }
}

void bra_2045 (unsigned char x)
{
    if (x > 0)
    {
        unsigned X = 0;
        N4 (2045);
    }
}

when compiled for MCU with JMP instruction like -mmcu=atmega168

Ok to apply?

Johann


        * config/avr/avr.md (length) [branch]: Correct insn length
        attribute for forward branches.
Index: config/avr/avr.md
===================================================================
--- config/avr/avr.md	(revision 238871)
+++ config/avr/avr.md	(working copy)
@@ -112,12 +112,12 @@ (define_attr "type" "branch,branch1,arit
 (define_attr "length" ""
   (cond [(eq_attr "type" "branch")
          (if_then_else (and (ge (minus (pc) (match_dup 0))
-                                (const_int -63))
+                                (const_int -62))
                             (le (minus (pc) (match_dup 0))
                                 (const_int 62)))
                        (const_int 1)
                        (if_then_else (and (ge (minus (pc) (match_dup 0))
-                                              (const_int -2045))
+                                              (const_int -2044))
                                           (le (minus (pc) (match_dup 0))
                                               (const_int 2045)))
                                      (const_int 2)

Reply via email to