When developing an OS for the smallest Atmels (ATtiny861/461/21)
i observed a strange effect. Sometimes, depending on the optimization
choosen by gcc, the compiler generates code which cannot be correct
(in my  view). Most of the time the code is not functional too.

The problem is that use of the instructions "std Y+1,rX" and
"ldd rX,Y+1" is made, but that de corresponding registers are
never properly initialized. The result is that the value is
stored somewhere in RAM or is retrieved from that (random?)
place. That may or may not hurt, but it seems wrong anyhow.

Below you can see an piece of code generated by GCC (v4.2.3)
 78c:   99 83           std     Y+1, r25    ; 0x01
 78e:   46 de           rcall   .-884       ; 0x41c <privOperateSlotStack>
 790:   99 81           ldd     r25, Y+1    ; 0x01
(From the methode below)
The point is nowhere in that method the registers r28 and r29 are used
neither are they set in the called methods. (see below)

In practice this effect indeed results in non functional code
which can most of the time be easily circumvented by inlining
some methods or hooking some variables up to fixed registers.
GCC is then forced to alter the output somewhat and often
the error disappears.

BTW, it seems that the compiler actually meant to do something
like this:
 78c:   79 2e           mov     r7, r25     ; 0x01
 78e:   46 de           rcall   .-884       ; 0x41c <privOperateSlotStack>
 790:   97 2d           mov     r25, r7     ; 0x01
where r7 can be any free register, since if you substitute
that (in the raw hex file for example) the code turns fully
functional.

I have observed the effect also at GCC 4.2.1 and GCC 4.3.0,
although beit not with exactly the same code. The effect is
reproducible, but depends critically on the choose optimizations
and structure of the code. These are my compiler options

avr-gcc -c -save-temps -mmcu=attiny861 -mint8 -Wall -Wno-main         \
  -Winline -Wundef -gdwarf-2 -Os -funsigned-char -fomit-frame-pointer \
  -fpack-struct -fshort-enums 

OK, it would take to much space to include enough details here
for you to be able to reproduce the problem. I made a zip which
can be downloaded from:
  http://www.femtoos.org/gcc_effect.zip
which should make this possible. (includes source code, and a
compiler script, you need avr-gcc 4.2.3 on your system, other
versions will no reproduce the error in this particular example)

regards,
Ruud

0000074e <privQueuRequestBody>:
 74e:   08 2f        mov     r16, r24
 750:   c6 2e        mov     r12, r22
 752:   7a 01        movw    r14, r20
 754:   0d de        rcall   .-998      ; 0x370 <privInitOs>
 756:   fb dd        rcall   .-1034     ; 0x34e <tcbCurrent>
 758:   5c 01        movw    r10, r24
 75a:   6c 2d        mov     r22, r12
 75c:   80 2f        mov     r24, r16
 75e:   09 dd        rcall   .-1518     ; 0x172 <privQueuTest>
 760:   98 2f        mov     r25, r24
 762:   1c 14        cp      r1, r12
 764:   24 f4        brge    .+8        ; 0x76e <privQueuRequestBody+0x20>
 766:   8c 15        cp      r24, r12
 768:   08 f4        brcc    .+2        ; 0x76c <privQueuRequestBody+0x1e>
 76a:   57 c0        rjmp    .+174      ; 0x81a <privQueuRequestBody+0xcc>
 76c:   07 c0        rjmp    .+14       ; 0x77c <privQueuRequestBody+0x2e>
 76e:   cc 20        and     r12, r12
 770:   29 f0        breq    .+10         ; 0x77c <privQueuRequestBody+0x2e>
 772:   8c 2d        mov     r24, r12
 774:   81 95        neg     r24
 776:   98 17        cp      r25, r24
 778:   08 f4        brcc    .+2        ; 0x77c <privQueuRequestBody+0x2e>
 77a:   4f c0        rjmp    .+158      ; 0x81a <privQueuRequestBody+0xcc>
 77c:   90 e0        ldi     r25, 0x00  ; 0
 77e:   10 2f        mov     r17, r16
 780:   1f 70        andi    r17, 0x0F  ; 15
 782:   f0 e8        ldi     r31, 0x80  ; 128
 784:   df 2e        mov     r13, r31
 786:   d1 2a        or      r13, r17
 788:   6d 2d        mov     r22, r13
 78a:   89 2f        mov     r24, r25
 78c:   99 83        std     Y+1, r25   ; 0x01
 78e:   46 de        rcall   .-884      ; 0x41c <privOperateSlotStack>
 790:   99 81        ldd     r25, Y+1   ; 0x01
 792:   88 23        and     r24, r24
 794:   31 f0        breq    .+12       ; 0x7a2 <privQueuRequestBody+0x54>
 796:   07 ff        sbrs    r16, 7
 798:   40 c0        rjmp    .+128      ; 0x81a <privQueuRequestBody+0xcc>
 79a:   60 2f        mov     r22, r16
 79c:   89 2f        mov     r24, r25
 79e:   26 de        rcall   .-948      ; 0x3ec <privReleaseTask>
 7a0:   3c c0        rjmp    .+120      ; 0x81a <privQueuRequestBody+0xcc>
 7a2:   9f 5f        subi    r25, 0xFF  ; 255
 7a4:   93 30        cpi     r25, 0x03  ; 3
 7a6:   09 f4        brne    .+2        ; 0x7aa <privQueuRequestBody+0x5c>
 7a8:   77 c0        rjmp    .+238      ; 0x898 <privQueuRequestBody+0x14a>
 7aa:   ee cf        rjmp    .-36       ; 0x788 <privQueuRequestBody+0x3a>
 7ac:   f6 01        movw    r30, r12
 7ae:   81 81        ldd     r24, Z+1   ; 0x01
 7b0:   8f 7d        andi    r24, 0xDF  ; 223
 7b2:   81 83        std     Z+1, r24   ; 0x01
 7b4:   e1 14        cp      r14, r1
 7b6:   f1 04        cpc     r15, r1
 7b8:   49 f1        breq    .+82       ; 0x80c <privQueuRequestBody+0xbe>
 7ba:   bd dd        rcall   .-1158     ; 0x336 <privCheckOsStack>
 7bc:   c8 dd        rcall   .-1136     ; 0x34e <tcbCurrent>
 7be:   8c 01        movw    r16, r24
 7c0:   f0 e0        ldi     r31, 0x00  ; 0
 7c2:   ef 16        cp      r14, r31
 7c4:   ff ef        ldi     r31, 0xFF  ; 255
 7c6:   ff 06        cpc     r15, r31
 7c8:   18 f0        brcs    .+6        ; 0x7d0 <privQueuRequestBody+0x82>
 7ca:   60 e0        ldi     r22, 0x00  ; 0
 7cc:   8f ec        ldi     r24, 0xCF  ; 207
 7ce:   0a dd        rcall   .-1516     ; 0x1e4 <privShowError>
 7d0:   80 91 90 00  lds     r24, 0x0090
 7d4:   20 91 8f 00  lds     r18, 0x008F
 7d8:   99 27        eor     r25, r25
 7da:   98 2f        mov     r25, r24
 7dc:   88 27        eor     r24, r24
 7de:   82 0f        add     r24, r18
 7e0:   91 1d        adc     r25, r1
 7e2:   8e 0d        add     r24, r14
 7e4:   9f 1d        adc     r25, r15
 7e6:   f8 01        movw    r30, r16
 7e8:   82 83        std     Z+2, r24   ; 0x02
 7ea:   89 2f        mov     r24, r25
 7ec:   99 27        eor     r25, r25
 7ee:   83 83        std     Z+3, r24   ; 0x03
 7f0:   93 81        ldd     r25, Z+3   ; 0x03
 7f2:   80 91 90 00  lds     r24, 0x0090
 7f6:   98 17        cp      r25, r24
 7f8:   29 f4        brne    .+10       ; 0x804 <privQueuRequestBody+0xb6>
 7fa:   80 91 b1 00  lds     r24, 0x00B1
 7fe:   80 62        ori     r24, 0x20  ; 32
 800:   80 93 b1 00  sts     0x00B1, r24
 804:   f8 01        movw    r30, r16
 806:   81 81        ldd     r24, Z+1   ; 0x01
 808:   8f 7e        andi    r24, 0xEF  ; 239
 80a:   81 83        std     Z+1, r24   ; 0x01
 80c:   f5 01        movw    r30, r10
 80e:   84 81        ldd     r24, Z+4   ; 0x04
 810:   8c 7f        andi    r24, 0xFC  ; 252
 812:   81 60        ori     r24, 0x01  ; 1
 814:   84 83        std     Z+4, r24   ; 0x04
 816:   80 e0        ldi     r24, 0x00  ; 0
 818:   3d c0        rjmp    .+122      ; 0x894 <privQueuRequestBody+0x146>
 81a:   00 68        ori     r16, 0x80  ; 128
 81c:   98 dd        rcall   .-1232     ; 0x34e <tcbCurrent>
 81e:   4c 01        movw    r8, r24
 820:   0f 70        andi    r16, 0x0F  ; 15
 822:   00 61        ori     r16, 0x10  ; 16
 824:   80 91 b1 00  lds     r24, 0x00B1
 828:   60 2f        mov     r22, r16
 82a:   8f 70        andi    r24, 0x0F  ; 15
 82c:   f7 dd        rcall   .-1042     ; 0x41c <privOperateSlotStack>
 82e:   f4 01        movw    r30, r8
 830:   81 81        ldd     r24, Z+1   ; 0x01
 832:   8f 7d        andi    r24, 0xDF  ; 223
 834:   81 83        std     Z+1, r24   ; 0x01
 836:   e1 14        cp      r14, r1
 838:   f1 04        cpc     r15, r1
 83a:   49 f1        breq    .+82       ; 0x88e <privQueuRequestBody+0x140>
 83c:   7c dd        rcall   .-1288     ; 0x336 <privCheckOsStack>
 83e:   87 dd        rcall   .-1266     ; 0x34e <tcbCurrent>
 840:   8c 01        movw    r16, r24
 842:   f0 e0        ldi     r31, 0x00  ; 0
 844:   ef 16        cp      r14, r31
 846:   ff ef        ldi     r31, 0xFF  ; 255
 848:   ff 06        cpc     r15, r31
 84a:   18 f0        brcs    .+6        ; 0x852 <privQueuRequestBody+0x104>
 84c:   60 e0        ldi     r22, 0x00  ; 0
 84e:   8f ec        ldi     r24, 0xCF  ; 207
 850:   c9 dc        rcall   .-1646     ; 0x1e4 <privShowError>
 852:   80 91 90 00  lds     r24, 0x0090
 856:   20 91 8f 00  lds     r18, 0x008F
 85a:   99 27        eor     r25, r25
 85c:   98 2f        mov     r25, r24
 85e:   88 27        eor     r24, r24
 860:   82 0f        add     r24, r18
 862:   91 1d        adc     r25, r1
 864:   8e 0d        add     r24, r14
 866:   9f 1d        adc     r25, r15
 868:   f8 01        movw    r30, r16
 86a:   82 83        std     Z+2, r24  ; 0x02
 86c:   89 2f        mov     r24, r25
 86e:   99 27        eor     r25, r25
 870:   83 83        std     Z+3, r24  ; 0x03
 872:   93 81        ldd     r25, Z+3  ; 0x03
 874:   80 91 90 00  lds     r24, 0x0090
 878:   98 17        cp      r25, r24
 87a:   29 f4        brne    .+10      ; 0x886 <privQueuRequestBody+0x138>
 87c:   80 91 b1 00  lds     r24, 0x00B1
 880:   80 62        ori     r24, 0x20 ; 32
 882:   80 93 b1 00  sts     0x00B1, r24
 886:   f8 01        movw    r30, r16
 888:   81 81        ldd     r24, Z+1  ; 0x01
 88a:   8f 7e        andi    r24, 0xEF ; 239
 88c:   81 83        std     Z+1, r24  ; 0x01
 88e:   f5 01        movw    r30, r10
 890:   c5 82        std     Z+5, r12  ; 0x05
 892:   81 e0        ldi     r24, 0x01 ; 1
 894:   e0 dd        rcall   .-1088    ; 0x456 <privEnterOS>
 896:   0b c0        rjmp    .+22      ; 0x8ae <portInit>
 898:   5a dd        rcall   .-1356    ; 0x34e <tcbCurrent>
 89a:   6c 01        movw    r12, r24
 89c:   10 61        ori     r17, 0x10 ; 16
 89e:   80 91 b1 00  lds     r24, 0x00B1
 8a2:   61 2f        mov     r22, r17
 8a4:   8f 70        andi    r24, 0x0F ; 15
 8a6:   ba dd        rcall   .-1164    ; 0x41c <privOperateSlotStack>
 8a8:   07 ff        sbrs    r16, 7
 8aa:   b0 cf        rjmp    .-160     ; 0x80c <privQueuRequestBody+0xbe>
 8ac:   7f cf        rjmp    .-258     ; 0x7ac <privQueuRequestBody+0x5e>


-- 
           Summary: Compiler makes use of [std Y+1, rX] instruction without
                    initializing r28,r29
           Product: gcc
           Version: 4.2.3
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: target
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: ruud at betaresearch dot nl
 GCC build triplet: i686-linux-gentoo
  GCC host triplet: i686-linux-gentoo
GCC target triplet: avr-*-*


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35807

Reply via email to