This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/10733] Modulus bug


------- Additional Comments From ericw at evcohs dot com  2004-08-30 18:47 -------
In comment #5 the inline assembly at the end of the preprocessed source comes
from an old version of avr-libc (the Standard C library for AVR GCC)
<http://savannah.nongnu.org/projects/avr-libc/>, which comes from the outp()
macros. In the later versions of avr-libc, the implementation of outp() was
changed and is now deprecated. This is also the reason why Kazu Hirata wrote the
reduction found in comment #8.

The test case in comment #4 can be changed to:

--------- bug10733a.c -------------
#include <avr/io.h>
 
int main(void)
{
    unsigned char t1;
    
    t1=40;
    t1=(t1 + 2)%30;
    
    DDRB = 0xff;
    PORTB = t1;
    
    return(0);
}
------------------------------

Using avr-gcc 3.3.2 gives the following preprocessed source:
------------------------------
# 1 "bug10733a.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "bug10733a.c"
# 1 "c:/WinAVR/avr/include/avr/io.h" 1 3
# 81 "c:/WinAVR/avr/include/avr/io.h" 3
# 1 "c:/WinAVR/avr/include/avr/sfr_defs.h" 1 3
# 121 "c:/WinAVR/avr/include/avr/sfr_defs.h" 3
# 1 "c:/WinAVR/avr/include/inttypes.h" 1 3
# 67 "c:/WinAVR/avr/include/inttypes.h" 3
typedef signed char int8_t;




typedef unsigned char uint8_t;
# 90 "c:/WinAVR/avr/include/inttypes.h" 3
typedef int int16_t;




typedef unsigned int uint16_t;
# 106 "c:/WinAVR/avr/include/inttypes.h" 3
typedef long int32_t;




typedef unsigned long uint32_t;
# 124 "c:/WinAVR/avr/include/inttypes.h" 3
typedef long long int64_t;




typedef unsigned long long uint64_t;
# 141 "c:/WinAVR/avr/include/inttypes.h" 3
typedef int16_t intptr_t;




typedef uint16_t uintptr_t;
# 122 "c:/WinAVR/avr/include/avr/sfr_defs.h" 2 3
# 82 "c:/WinAVR/avr/include/avr/io.h" 2 3
# 189 "c:/WinAVR/avr/include/avr/io.h" 3
# 1 "c:/WinAVR/avr/include/avr/io8535.h" 1 3
# 190 "c:/WinAVR/avr/include/avr/io.h" 2 3
# 229 "c:/WinAVR/avr/include/avr/io.h" 3
# 1 "c:/WinAVR/avr/include/avr/portpins.h" 1 3
# 230 "c:/WinAVR/avr/include/avr/io.h" 2 3
# 2 "bug10733a.c" 2

int main(void)
{
    unsigned char t1;

    t1=40;
    t1=(t1 + 2)%30;

    (*(volatile uint8_t *)((0x17) + 0x20)) = 0xff;
    (*(volatile uint8_t *)((0x18) + 0x20)) = t1;

    return(0);
}
------------------------------

and also compiles to (mixed C and assembly listing):
------------------------------
   3:bug10733a.c   **** int main(void)
   4:bug10733a.c   **** {
  61               	.LM1:
  62               	/* prologue: frame size=0 */
  63 0000 C0E0      		ldi r28,lo8(__stack - 0)
  64 0002 D0E0      		ldi r29,hi8(__stack - 0)
  65 0004 DEBF      		out __SP_H__,r29
  66 0006 CDBF      		out __SP_L__,r28
  67               	/* prologue end (size=4) */
   5:bug10733a.c   ****     unsigned char t1;
   6:bug10733a.c   ****     
   7:bug10733a.c   ****     t1=40;
   8:bug10733a.c   ****     t1=(t1 + 2)%30;
  69               	.LM2:
  70               	.LBB2:
  71 0008 8AE2      		ldi r24,lo8(42)
  72 000a 90E0      		ldi r25,hi8(42)
  73 000c 6EE1      		ldi r22,lo8(30)
  74 000e 70E0      		ldi r23,hi8(30)
  75 0010 00D0      		rcall __divmodhi4
  76 0012 282F      		mov r18,r24
  77 0014 392F      		mov r19,r25
   9:bug10733a.c   ****     
  10:bug10733a.c   ****     DDRB = 0xff;
  79               	.LM3:
  80 0016 8FEF      		ldi r24,lo8(-1)
  81 0018 87BB      		out 55-0x20,r24
  11:bug10733a.c   ****     PORTB = t1;
  83               	.LM4:
  84 001a 28BB      		out 56-0x20,r18
  12:bug10733a.c   ****     
  13:bug10733a.c   ****     return(0);
  14:bug10733a.c   **** }
  86               	.LM5:
  87               	.LBE2:
  88 001c 80E0      		ldi r24,lo8(0)
  89 001e 90E0      		ldi r25,hi8(0)
  90               	/* epilogue: frame size=0 */
  91 0020 00C0      		rjmp exit
  92               	/* epilogue end (size=1) */
------------------------------

Note the call to __divmodhi4 above. This is the same as the original bug report.

In comment #3, the OP gave a workaround as such:

--------- bug10733b.c ------------
#include <avr/io.h>
 
int main(void)
{
    unsigned char t1;
    
    t1=2;
    t1=t1+40;
    t1%=30;

    DDRB = 0xff;
    PORTB = t1;
    
    return(0);
}
------------------------------

Preprocessed source:
------------------------------
# 1 "bug10733b.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "bug10733b.c"
# 1 "c:/WinAVR/avr/include/avr/io.h" 1 3
# 81 "c:/WinAVR/avr/include/avr/io.h" 3
# 1 "c:/WinAVR/avr/include/avr/sfr_defs.h" 1 3
# 121 "c:/WinAVR/avr/include/avr/sfr_defs.h" 3
# 1 "c:/WinAVR/avr/include/inttypes.h" 1 3
# 67 "c:/WinAVR/avr/include/inttypes.h" 3
typedef signed char int8_t;




typedef unsigned char uint8_t;
# 90 "c:/WinAVR/avr/include/inttypes.h" 3
typedef int int16_t;




typedef unsigned int uint16_t;
# 106 "c:/WinAVR/avr/include/inttypes.h" 3
typedef long int32_t;




typedef unsigned long uint32_t;
# 124 "c:/WinAVR/avr/include/inttypes.h" 3
typedef long long int64_t;




typedef unsigned long long uint64_t;
# 141 "c:/WinAVR/avr/include/inttypes.h" 3
typedef int16_t intptr_t;




typedef uint16_t uintptr_t;
# 122 "c:/WinAVR/avr/include/avr/sfr_defs.h" 2 3
# 82 "c:/WinAVR/avr/include/avr/io.h" 2 3
# 189 "c:/WinAVR/avr/include/avr/io.h" 3
# 1 "c:/WinAVR/avr/include/avr/io8535.h" 1 3
# 190 "c:/WinAVR/avr/include/avr/io.h" 2 3
# 229 "c:/WinAVR/avr/include/avr/io.h" 3
# 1 "c:/WinAVR/avr/include/avr/portpins.h" 1 3
# 230 "c:/WinAVR/avr/include/avr/io.h" 2 3
# 2 "bug10733b.c" 2

int main(void)
{
    unsigned char t1;

    t1=2;
    t1=t1+40;
    t1%=30;

    (*(volatile uint8_t *)((0x17) + 0x20)) = 0xff;
    (*(volatile uint8_t *)((0x18) + 0x20)) = t1;

    return(0);
}
------------------------------

And compiled output (mixed C and assembly):
------------------------------
   3:bug10733b.c   **** int main(void)
   4:bug10733b.c   **** {
  61               	.LM1:
  62               	/* prologue: frame size=0 */
  63 0000 C0E0      		ldi r28,lo8(__stack - 0)
  64 0002 D0E0      		ldi r29,hi8(__stack - 0)
  65 0004 DEBF      		out __SP_H__,r29
  66 0006 CDBF      		out __SP_L__,r28
  67               	/* prologue end (size=4) */
   5:bug10733b.c   ****     unsigned char t1;
   6:bug10733b.c   ****     
   7:bug10733b.c   ****     t1=2;
   8:bug10733b.c   ****     t1=t1+40;
   9:bug10733b.c   ****     t1%=30;
  69               	.LM2:
  70               	.LBB2:
  71 0008 8AE2      		ldi r24,lo8(42)
  72 000a 6EE1      		ldi r22,lo8(30)
  73 000c 00D0      		rcall __udivmodqi4
  10:bug10733b.c   **** 
  11:bug10733b.c   ****     DDRB = 0xff;
  75               	.LM3:
  76 000e 8FEF      		ldi r24,lo8(-1)
  77 0010 87BB      		out 55-0x20,r24
  12:bug10733b.c   ****     PORTB = t1;
  79               	.LM4:
  80 0012 98BB      		out 56-0x20,r25
  13:bug10733b.c   ****     
  14:bug10733b.c   ****     return(0);
  15:bug10733b.c   **** }
  82               	.LM5:
  83               	.LBE2:
  84 0014 80E0      		ldi r24,lo8(0)
  85 0016 90E0      		ldi r25,hi8(0)
  86               	/* epilogue: frame size=0 */
  87 0018 00C0      		rjmp exit
  88               	/* epilogue end (size=1) */
------------------------------

Note that this time the modulus is done with a call to __udivmodqi4.

Could this be the problem?

Eric Weddington
WinAVR Admin



-- 


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]