1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
/* bug #21955: pgm_read_xxxx() does not use enhanced LPM instruction
$Id: bug-21955.c,v 1.1.2.2 2008/01/13 00:53:31 dmix Exp $
Idea is to force 'region text is full': pgm_read_word() takes 5 words
in case of classic LPM, and takes 2 words with enhanced LPM. */
#ifndef __AVR__
/* There are not sense to check host computer. */
int main ()
{
return 0;
}
#else
#include <avr/io.h>
#include <avr/pgmspace.h>
/* avr-gcc 4.1.2, Avr-libc 1.6.1, main() contains only 1 line with
pgm_read_word, bytes:
MIN_SIZE == 90 --> Fault
MIN_SIZE == 100 --> OK
So, for 50 lines it would:
100 + 8*49 = 492 for enhanced
100 + 14*49 = 786 for enhanced
No use __AVR_HAVE_LPMX__ for preprocessing. */
#if (__AVR_ARCH__ == 2) || (__AVR_ARCH__ == 3)
# define MIN_SIZE 940
#else
# define MIN_SIZE 640
#endif
#define NWORDS ((FLASHEND - _VECTORS_SIZE - MIN_SIZE)/2)
void very_big_function (void)
{
asm volatile (
".rept (%0)*256 + %1 \n\t"
"nop \n\t"
".endr "
:: "M" (NWORDS / 256),
"M" (NWORDS % 256)
);
}
int main ()
{
volatile int rslt;
int addr = 0;
/* 10*4 words with enhanced LPM
10*7 words with classic LPM */
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF; /* 10 */
/* 10*4 words with enhanced LPM
10*7 words with classic LPM */
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF; /* 20 */
/* 10*4 words with enhanced LPM
10*7 words with classic LPM */
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF; /* 30 */
/* 10*4 words with enhanced LPM
10*7 words with classic LPM */
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF; /* 40 */
/* 10*4 words with enhanced LPM
10*7 words with classic LPM */
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF;
addr = pgm_read_word (addr) & 0x7FF; /* 50 */
rslt = (int)addr;
return 0;
}
#endif /* __AVR__ */
|