avr-gcc-list
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]