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, ColdFire, inconsistant operand constraints in an `asm'


I'm in the midst of trying to use gcc-3.2 to build Linux for
ColdFire v4e, and I have the following asm instruction:

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), "+Q" (((volatile char *)vaddr)[(nr^31) >> 3])
	     : "di" (nr & 7));

	return retval;
}

Where 'nr' is known to be constant.  The ColdFire can not accept (R+R)
addressing mode for this instructions, so the 'm' constraint is
replaced with 'Q' which indicates register indirect addressing mode.
It blows up in find_reloads with: 

Breakpoint 4, error_for_asm (insn=0x403979e0, 
    msgid=0x81f94c0 "inconsistent operand constraints in an `asm'")
    at /home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2/gcc/rtl-error.c:94
(gdb) up 
#1  0x08125954 in find_reloads (insn=0x403979e0, replace=0, ind_levels=0, 
    live_known=1, reload_reg_p=0x82239a0)
    at /home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2/gcc/reload.c:3577
(gdb) call debug_rtx(insn)

(insn 86 84 87 (parallel[ 
            (set (reg/v:QI 1 %d1 [45])
                (asm_operands/v:QI ("bclr %2,%1; sne %0") ("=d") 0[ 
                        (reg:SI 1 %d1 [41])
                        (mem/v:QI (plus:SI (reg/v/f:SI 8 %a0 [43])
                                (reg:SI 0 %d0 [47])) [0 S1 A8])
                    ] 
                    [ 
                        (asm_input:SI ("di"))
                        (asm_input:QI ("1"))
                    ]  ("/tmp/softirq.c") 982))
            (set (mem/v:QI (plus:SI (reg/v/f:SI 8 %a0 [43])
                        (reg:SI 0 %d0 [47])) [0 S1 A8])
                (asm_operands/v:QI ("bclr %2,%1; sne %0") ("=Q") 1[ 
                        (reg:SI 1 %d1 [41])
                        (mem/v:QI (plus:SI (reg/v/f:SI 8 %a0 [43])
                                (reg:SI 0 %d0 [47])) [0 S1 A8])
                    ] 
                    [ 
                        (asm_input:SI ("di"))
                        (asm_input:QI ("1"))
                    ]  ("/tmp/softirq.c") 982))
        ] ) -1 (insn_list 78 (insn_list 84 (nil)))
    (expr_list:REG_DEAD (reg/v/f:SI 8 %a0 [43])
        (expr_list:REG_DEAD (reg:SI 0 %d0 [47])
            (expr_list:REG_DEAD (reg:SI 1 %d1 [41])
                (nil)))))
(gdb) 

Which shows that its trying to use bclr with:

   (mem/v:QI (plus:SI (reg/v/f:SI 8 %a0 [43])
      (reg:SI 0 %d0 [47])) [0 S1 A8])

as the arg, which won't match the 'Q' constraint.

My main question is if LEGITIMIZE_ADDRESS() is invoked with only
illegitimate addresses, either those that fail constraints, or that
GO_IF_LEGITIMATE_ADDRESS() rejected.

If this is true, then in LEGITIMIZE_ADDRESS(), I could reject all (R+R)
and use force_operand (R+R) thereby giving a register indirect
addressing mode. 

If LEGITIMIZE_ADDRESS is invoked with legitimate addresses, then what
is the best way of solving this problem?

All help is appreciated.

-- 
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]