[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] error with optimized boolean logic in gcc
From: |
Georg-Johann Lay |
Subject: |
Re: [avr-gcc-list] error with optimized boolean logic in gcc |
Date: |
Fri, 25 Nov 2011 11:18:17 +0100 |
User-agent: |
Mozilla Thunderbird 1.0.7 (Windows/20050923) |
Sean D'Epagnier schrieb:
I have had some issues compiling source code with the latest gcc in svn.
The following program fails me:
#include <avr/io.h>
int main(void) {
DDRB |= _BV(DDB5);
}
avr-gcc -mmcu=at90usb1287 -c test.c -o test.o -O2
/tmp/ccqKOBv9.s: Assembler messages:
/tmp/ccqKOBv9.s:16: Error: number must be positive and less than 32
make: *** [all] Error 1
The assembly produced for main:
.global main
.type main, @function
main:
/* prologue: function */
/* frame size = 0 */
/* stack size = 0 */
.L__stack_usage = 0
sbi 36,5
ret
.size main, .-main
.ident "GCC: (GNU) 4.7.0 20111123 (experimental)"
The sbi instruction needs values 0-31, 36 is too high.
The instruction in avr.md which generates this is *sbi, only
enabled with optimizations. I think this is a new optimization
added, but 0x20 needs to be subtracted from the memory location.
In avr.md I changed:
return "sbi %i0,%2";
to
return "sbi %i0-0x20,%2";
It fixed the problem. I think this needs to be done all over the place
This is an incorrect fix, the problem must be somewhere else.
%i shall subtract avr_current_arch->sfr_offset which is 0x20 for all
architectures. The reason to use %i and not %m is to avoid magic
numbers 0x20 all over the place, see top of following changeset and %i
implementation in avr.c:print_operand()
http://gcc.gnu.org/viewcvs?view=revision&revision=181552
+ else if (code == 'i')
+ {
+ if (!io_address_operand (addr, GET_MODE (x)))
+ fatal_insn ("bad address, not an I/O address:", addr);
+
+ switch (INTVAL (addr))
+ {
+ case RAMPZ_ADDR: fprintf (file, "__RAMPZ__"); break;
+ case SREG_ADDR: fprintf (file, "__SREG__"); break;
+ case SP_ADDR: fprintf (file, "__SP_L__"); break;
+ case SP_ADDR+1: fprintf (file, "__SP_H__"); break;
+
+ default:
+ fprintf (file, HOST_WIDE_INT_PRINT_HEX,
+ UINTVAL (addr) - avr_current_arch->sfr_offset);
+ break;
+ }
+ }
for sbi and cbi, as well as for in and out. There might be a better
way to more elegantly output the subtracted value so the assembler doesn't
need to do the subtraction. Does anyone know who made the changes?
I am using the latest version in svn.
Sean
Johann