I found that gcc 3.3.4/3.4.1 can not compile this sample code properly. --- k.c --- /* mips-linux-gcc -D__KERNEL__ -O2 -mno-abicalls -fno-pic -I $(KERNEL)/include -S k.c */ #include <asm/uaccess.h> extern char ptr[]; static int func0(int arg0) { return 0; } int func1(int *arg) { int arg0 = arg[0]; int arg1; if (arg0) return -1; arg0 = func0(0); get_user(arg1 , (int*)arg[1]); if (func0(ptr[arg0])) return 0; if (arg1) ptr[arg0] = 0; return 0; } --- k.c end --- The codes around the first calling of func0 are: .set noreorder .set nomacro jal func0 .set macro .set reorder lw $4,4($16) The jal does not have delay slot. Then "lw $4" (part of get_user) executed as the delay slot instruction. I create a sample code with very stripped version of get_user. --- kk.c --- /* mips-linux-gcc -O2 -mno-abicalls -fno-pic -S kk.c */ #define get_user(x,ptr) \ { \ int __gu_val; \ __asm__ ("":"=r" (__gu_val)); \ if (ptr) { \ __asm__ __volatile__( \ "\tlw\t%0,%1\n\t" \ :"=r" (__gu_val) \ :"o" (*(ptr))); \ } \ (x) = __gu_val; \ } extern char ptr[]; static int func0(int arg0) { return 0; } int func1(int *arg) { int arg0 = arg[0]; int arg1; if (arg0) return -1; arg0 = func0(0); get_user(arg1 , (int*)arg[1]); if (func0(ptr[arg0])) return 0; if (arg1) ptr[arg0] = 0; return 0; } --- kk.c end --- And complete output of gcc 3.3.4: .file 1 "kk.c" .section .mdebug.abi32 .previous .text .align 2 .ent func0 .type func0, @function func0: .frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, extra= 0 .mask 0x00000000,0 .fmask 0x00000000,0 .set noreorder .set nomacro j $31 move $2,$0 .set macro .set reorder .end func0 .align 2 .globl func1 .ent func1 .type func1, @function func1: .frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, extra= 0 .mask 0x80030000,-8 .fmask 0x00000000,0 subu $sp,$sp,32 sw $16,16($sp) sw $31,24($sp) move $16,$4 sw $17,20($sp) lw $2,0($16) move $4,$0 .set noreorder .set nomacro bne $2,$0,$L2 li $3,-1 # 0xffffffffffffffff .set macro .set reorder .set noreorder .set nomacro jal func0 .set macro .set reorder lw $4,4($16) #nop beq $4,$0,$L4 #APP lw $17,0($4) #NO_APP $L4: la $16,ptr($2) lb $4,0($16) jal func0 .set noreorder .set nomacro bne $2,$0,$L2 move $3,$0 .set macro .set reorder beq $17,$0,$L2 sb $0,0($16) $L2: lw $31,24($sp) lw $17,20($sp) lw $16,16($sp) move $2,$3 .set noreorder .set nomacro j $31 addu $sp,$sp,32 .set macro .set reorder .end func1 .ident "GCC: (GNU) 3.3.4" Also complete output of gcc 3.4.1: .file 1 "kk.c" .section .mdebug.abi32 .previous .text .align 2 .ent func0 .type func0, @function func0: .frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0 .mask 0x00000000,0 .fmask 0x00000000,0 .set noreorder .set nomacro j $31 move $2,$0 .set macro .set reorder .end func0 .align 2 .globl func1 .ent func1 .type func1, @function func1: .frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0 .mask 0x80030000,-8 .fmask 0x00000000,0 addiu $sp,$sp,-32 sw $16,16($sp) sw $31,24($sp) move $16,$4 sw $17,20($sp) lw $3,0($16) move $4,$0 .set noreorder .set nomacro bne $3,$0,$L2 li $5,-1 # 0xffffffffffffffff .set macro .set reorder .set noreorder .set nomacro jal func0 .set macro .set reorder lw $4,4($16) #nop .set noreorder .set nomacro bne $4,$0,$L8 move $3,$2 .set macro .set reorder lui $2,%hi(ptr) $L9: addiu $2,$2,%lo(ptr) addu $16,$3,$2 lb $4,0($16) jal func0 .set noreorder .set nomacro bne $2,$0,$L2 move $5,$0 .set macro .set reorder beq $17,$0,$L2 sb $0,0($16) $L2: lw $31,24($sp) lw $17,20($sp) lw $16,16($sp) move $2,$5 .set noreorder .set nomacro j $31 addiu $sp,$sp,32 .set macro .set reorder $L8: #APP lw $17,0($4) #NO_APP .set noreorder .set nomacro j $L9 lui $2,%hi(ptr) .set macro .set reorder .end func1 .ident "GCC: (GNU) 3.4.1" Is this a get_user's problem or gcc's? --- Atsushi Nemoto