On Sat, Apr 27, 2013 at 02:09:22AM -0300, Luiz Angelo Daros de Luca wrote: > The usage of sign-extension might be cause. The problem is that all these > variables are sector_t, which as far as I know, is a u64. > Even if it was using signed variable, all of them are 64bit and using > values much lower that 2^63. > > As mips is not a 64-bit processor, the compiler must do it by parts. So, > where is this problem from? Compiler? Kernel?
Seems that at least gcc-4.6-linaro from AA (mips-openwrt-linux-gcc
(Linaro GCC 4.6-2012.02) 4.6.3 20120201 (prerelease),
PKG_MD5SUM:=2b7887846f8e5ac1ca58fe4dfaabf5a6) is buggy. Here is a
self-contained test case:
madd.c:
=============================================================================
typedef unsigned long long u64;
typedef unsigned long u32;
typedef unsigned char u8;
static inline u32 get_unaligned_le32(const u8 *p)
{
return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
}
static inline u64 my_get_le32(const void *p)
{
return (u64)get_unaligned_le32(p);
}
u64 test_fn(u64 arg1, void *arg2, void *arg3)
{
return arg1 + my_get_le32(arg2)*my_get_le32(arg3);
}
=============================================================================
When I compile this file with:
$STAGING_DIR/bin/mips-openwrt-linux-gcc -march=mips32r2 -S -O2 -Wall -W madd.c
I get the following output in madd.s:
=============================================================================
.file 1 "madd.c"
.section .mdebug.abi32
.previous
.gnu_attribute 4, 3
.abicalls
.option pic0
.text
.align 2
.globl test_fn
.set nomips16
.ent test_fn
.type test_fn, @function
test_fn:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
.set noreorder
.set nomacro
lbu $11,1($6)
lbu $2,2($6)
lbu $3,2($7)
lbu $12,1($7)
lbu $10,0($6)
lbu $9,3($6)
lbu $8,0($7)
lbu $6,3($7)
sll $11,$11,8
sll $7,$12,8
sll $2,$2,16
sll $3,$3,16
or $2,$11,$2
or $3,$7,$3
or $2,$2,$10
sll $7,$9,24
or $3,$3,$8
sll $6,$6,24
mtlo $5
or $2,$2,$7
or $3,$3,$6
mthi $4
madd $3,$2
mflo $3
j $31
mfhi $2
.set macro
.set reorder
.end test_fn
.size test_fn, .-test_fn
.ident "GCC: (Linaro GCC 4.6-2012.02) 4.6.3 20120201 (prerelease)"
=============================================================================
The "madd $3,$2" command here is incorrect - it performs sign
extension of its arguments; it should be "maddu $3,$2".
signature.asc
Description: Digital signature
_______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/mailman/listinfo/openwrt-devel
