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]

Recog/asm_operands problem with MIPS/gcc3.3


I'm working on a bug filed against GCC 3.3.1 for mips-linux.  Unfortunately,
the changes to the MIPS backend in HEAD mean that it doesn't show up any
more; but I can't find any evidence that it disappeared, so I think it may
still be latent.

Testcase is at the end of this message.  Build a mipsel-linux cc1 and 
run:
 ./gcc/cc1 -o f.s -quiet /big/mvista/bugs/mips-floppy-asm-error/f.i
  -fpreprocessed -quiet -mtune=r5000 -mips2 -mabi=32 -O2

Take a look near the end of f.s; if you see:
#APP
        1:      ll      $3, drive_state(lo)             # set_bit

then you've reproduced it.  lo is not a legitimate base register.


The problem occurs in dbr.  Going in, we have this mess:

(insn:HI 65 118 135 0x403ac680 (parallel [
            (set (reg/v:SI 3 v1 [211])
                (asm_operands/v:SI ("1: ll      %0, %1          # set_bit
        or      %0, %2
        sc      %0, %1
        beqz    %0, 1b") ("=&r") 0 [
                        (const_int 4 [0x4])
                        (mem:SI (plus:SI (reg:SI 2 v0 [204])
                                (symbol_ref:SI ("drive_state"))) [5 S4 A32])
                    ]
                     [
                        (asm_input:SI ("ir"))
                        (asm_input:SI ("m"))
                    ] ("/opt/montavista/pro/devkit/lsp/nec-cmb-vr7701-mips_fp_le/linux-2.4.20_mvl31/include/linux/fd.h") 385))
            (set (mem:SI (plus:SI (reg:SI 2 v0 [204])
                        (symbol_ref:SI ("drive_state"))) [5 S4 A32])
                (asm_operands/v:SI ("1: ll      %0, %1          # set_bit
        or      %0, %2
        sc      %0, %1
        beqz    %0, 1b") ("=m") 1 [
                        (const_int 4 [0x4])
                        (mem:SI (plus:SI (reg:SI 2 v0 [204])
                                (symbol_ref:SI ("drive_state"))) [5 S4 A32])
                    ]
                     [
                        (asm_input:SI ("ir"))
                        (asm_input:SI ("m"))
                    ] ("/opt/montavista/pro/devkit/lsp/nec-cmb-vr7701-mips_fp_le/linux-2.4.20_mvl31/include/linux/fd.h") 385))
        ]) -1 (insn_list:REG_DEP_ANTI 48 (insn_list 50 (insn_list 118 (nil))))
    (expr_list:REG_DEAD (reg:SI 2 v0 [204])
        (expr_list:REG_UNUSED (reg/v:SI 3 v1 [211])
            (nil))))


The important bit for the moment is the second output:
           (mem:SI (plus:SI (reg:SI 2 v0 [204])
                    (symbol_ref:SI ("drive_state"))) [5 S4 A32])

DBR decides to replace v0 with lo, because it thinks that will free up some
more room for it to schedule.  v0 just came from an mflo instruction.  So it
calls validate_replace_rtx to do this.  validate_replace_rtx eventually gets
to recog.c:insn_invalid_p, which calls recog on the updated instruction. 
But recog only validates that the inputs match.  Then we call
check_asm_operands, which eventually calls constrain_operands because
reload_completed is set.  constrain_operands sees the 'm' in the "=m"
constraint, sees that this is indeed a mem, and allows it through.

Obviously something should have rejected it.  memory_address_p would have,
had it ever been called, which it wasn't.  recog.c:apply_change_group()
would have called it if we had ever reached there with object == the MEM,
but we only ever pass object == the INSN containing the MEM.

Where should the revalidatin be happening?  If in constrain_operands, should
it be there always, or should we be passing it an argument requesting this?

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

/* Testcase.  Compile as:
   ./gcc/cc1 -o f.s -quiet /big/mvista/bugs/mips-floppy-asm-error/f.i
     -fpreprocessed -quiet -mtune=r5000 -mips2 -mabi=32 -O2
*/

static unsigned char current_drive;

struct floppy_drive_struct {
        unsigned long flags;




        unsigned long spinup_date;
        unsigned long select_date;
        unsigned long first_read_date;
        short probed_format;
        short track;
        short maxblock;
        short maxtrack;
        int generation;






        int keep_data;


        int fd_ref;
        int fd_device;
        unsigned long last_checked;


        char *dmabuf;
        int bufblocks;
};

struct floppy_raw_cmd {
        unsigned int flags;
# 341 "/opt/montavista/pro/devkit/lsp/nec-cmb-vr7701-mips_fp_le/linux-2.4.20_mvl31/include/linux/fd.h"
        void *data;
        char *kernel_data;
        struct floppy_raw_cmd *next;

        long length;
        long phys_length;
        int buffer_length;

        unsigned char rate;
        unsigned char cmd_count;
        unsigned char cmd[16];
        unsigned char reply_count;
        unsigned char reply[16];
        int track;
        int resultcode;

        int reserved1;
        int reserved2;
};

static struct floppy_drive_struct drive_state[8];
static struct floppy_raw_cmd *raw_cmd;


extern void func();

static int disk_change(int drive)
{
	func();
        return 1;
}



static inline int test_bit(int nr, volatile void *addr)
{
        return 1UL & (((const volatile unsigned long *) addr)[nr >> 5] >> (nr & 31UL));
}

static __inline__ void my_set_bit(int nr, volatile void *addr)
{
        unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
        unsigned long temp;

        __asm__ __volatile__(
                "1:\tll\t%0, %1\t\t# set_bit\n\t"
                "or\t%0, %2\n\t"
                "sc\t%0, %1\n\t"
                "beqz\t%0, 1b"
                : "=&r" (temp), "=m" (*m)
                : "ir" (1UL << (nr & 0x1f)), "m" (*m));
}

static void moo_floppy(void)
{
        int track;

        if (!(test_bit(1, &(&drive_state[current_drive])->flags)) &&
            disk_change(current_drive)) {
                (my_set_bit(2, &(&drive_state[current_drive])->flags));
                return;
        }
        if ((&drive_state[current_drive])->track <= -2){
		func();
                return;
        }
}


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