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".

Attachment: signature.asc
Description: Digital signature

_______________________________________________
openwrt-devel mailing list
[email protected]
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to