This is the mail archive of the gcc@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]

gcc-3.2 asm troubles on m68k/ColdFire


I'm trying to use 'bclr' in an asm statement where the ColdFire can't
use an 'm' constraint since the instruction doesn't support (R+R)
addressing, so instead I use 'Q' which indicates register indirect
addressing. 

Here's the code:

extern __inline__ int __constant_coldfire_test_and_clear_bit(int nr, volatile void * vaddr)
{
  char retval;
  __asm__ __volatile__
    ("bclr %2,%1; sne %0"
     : "=d" (retval), "+QU" (((volatile char *)vaddr)[(nr^31) >> 3])
     : "di" (nr & 7));
  return retval;
}

volatile unsigned long state;

void tasklet_action(void)
{
  if (!__constant_coldfire_test_and_clear_bit(0, &state))
    do { asm volatile("illegal"); } while (0);
}

When run through gcc-3.2 configured for m68k-elf, it aborts with:
/tmp/test.c: In function `tasklet_action':
/tmp/test.c:12: inconsistent operand constraints in an `asm'


The problem is that the rtl for the asm statement is: (from
test.c.00.rtl):

(insn 21 20 22 (parallel[ 
            (set (reg/v:QI 32)
                (asm_operands/v:QI ("bclr %2,%1; sne %0") ("=d") 0[ 
                        (reg:SI 35)
                        (mem/v:QI (plus:SI (reg/v/f:SI 30)
                                (reg:SI 34)) [0 S1 A8])
                    ] 
                    [ 
                        (asm_input:SI ("di"))
                        (asm_input:QI ("1"))
                    ]  ("/tmp/test.c") 12))
            (set (mem/v:QI (plus:SI (reg/v/f:SI 30)
                        (reg:SI 34)) [0 S1 A8])
                (asm_operands/v:QI ("bclr %2,%1; sne %0") ("=QU") 1[ 
                        (reg:SI 35)
                        (mem/v:QI (plus:SI (reg/v/f:SI 30)
                                (reg:SI 34)) [0 S1 A8])
                    ] 
                    [ 
                        (asm_input:SI ("di"))
                        (asm_input:QI ("1"))
                    ]  ("/tmp/test.c") 12))
        ] ) -1 (nil)
    (nil))

At this point  (mem/v:QI (plus:SI (reg/v/f:SI 30) (reg:SI 34)) [0 S1 A8])
is illegal rtl for ColdFire since the bclr instruction doesn't support
this addressing mode when %2 is a constant (which just happens to be
(asm_input:QI ("1")). 

The problem is that the expression (plus:SI (reg/v/f:SI 30) (reg:SI 34)) 
is valid for most instructions, but not this asm statement.
I could modify GO_IF_LEGITIMATE_ADDRESS to reject all (R+R)
addressing, but that destroys the performance of (R+R) addressing mode
for all other instructions.... 

What is the best way(if any) to handle this type of construct?  There
must be other chips out that are supported by gcc whose addressing
modes are limited for certain classes of instructions, and if so, how
is this type of problem handled?

This isn't a problme in general RTL constructions since the predicates
can be used to control the generation of valid RTL, but the asm
statements don't have this luxury.  Perhaps the asm statement code
could be converted to wade over the constraints of each operand and
decide if the operand is valid.  If not valid for any constraint, then
it could use LEGITIMIZE_ADDRESS to clean it up(and in this case I'd
modify LEGITIMIZE_ADDRESS to turn (R+R) addressing into R1=R+R; (R)).

Any comments?

-- 
Peter Barada                                   Peter.Barada@motorola.com
Wizard                                         781-852-2768 (direct)
WaveMark Solutions(wholly owned by Motorola)   781-270-0193 (fax)


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