龙芯开源社区

 找回密码
 注册新用户(newuser)
查看: 6893|回复: 10

貌似 lw 可以访问非对齐的地址

[复制链接]
发表于 2007-5-11 11:04:50 | 显示全部楼层 |阅读模式
测试程序如下:

     1  #include <stdio.h>
     2
     3  unsigned short data[] = {
     4      0x1, 0x2, 0x3, 0x4,
     5      0x55aa, 0x66bb, 0x77cc, 0x0000,
     6  };
     7
     8  inline void unaligned_access(unsigned short * const row)
     9  {
    10      asm volatile
    11          (
    12              ".set mips3\n\t"
    13              ".set noreorder\n\t"
    14
    15               "xor $10, $10\n\t"
    16               "xor $11, $11\n\t"
    17
    18              //"lwr $10, 1(%1)\n\t" /* %1 word aligned, %1+1 word unaligned */
    19              //"lwl $11, 4(%1)\n\t"
    20
    21              "lw  $10, 1(%1)\n\t" /* %1 word aligned, %1+1 word unaligned */
    22
    23              //"or  $10, $11\n\t"
    24              "sw  $10, %0\n\t"
    25
    26              ".set reorder\n\t"
    27              ".set mips0\n\t"
    28              : "=m"(*(row))
    29              : "r"(row+4)
    30              : "$11", "$10", "memory"
    31          );
    32  }
    33
    34  int main()
    35  {
    36      printf("---------------------------------------------------------\n");
    37      printf("  Testing Godson2 unaligned access Instruction \n");
    38      printf("---------------------------------------------------------\n\n");
    39
    40      unaligned_access(data);
    41
    42      printf("result is: 0x%04x %04x %04x %04x\n", data[3], data[2], data[1], data[0]);
    43
    44  }

gdb 跟踪结果data 放在0x440b90处,则21行 lw 访问的地址为 0x440b99,低2位为01,字不对齐。反汇编、跟踪都表明确实执行的是 lw 。

以上程序执行结果,与打开18,19,23 行,注释21行的结果相同。

都为:(32位系统,那位兄弟测一下64位系统的情况)

---------------------------------------------------------
  Testing Godson2 unaligned access Instruction
---------------------------------------------------------

result is: 0x0004 0003 cc66 bb55



是否 lw 实现时对非对齐的访问进行了处理?转化成龙芯内部指令?

[ 本帖最后由 comcat 于 2007-5-11 01:19 PM 编辑 ]
发表于 2007-5-11 11:54:33 | 显示全部楼层
那是否触发异常处理了呢 也许在那里使用了lwr/lwl swr/swl
 楼主| 发表于 2007-5-11 11:59:19 | 显示全部楼层
这个应该不会,ld 访问一个非对齐地址的话,内核直接输出“非法指令”的信息。
发表于 2007-5-11 12:02:23 | 显示全部楼层
这可不一定哦 我看到c mips run上面 甚至可以模拟cpu没有的指令

如果异常处理程序判断出异常是由ld之类的指令引发的 则可以特别处理的

[ 本帖最后由 water 于 2007-5-11 12:03 PM 编辑 ]
 楼主| 发表于 2007-5-11 13:13:48 | 显示全部楼层
真让你说中了,内核里确实有一个异常处理函数负责处理 lw 访问非对齐地址引起的异常。

可惜 ld 的没有,难怪ld 与 lw 访问非对齐地址时行为不一样。

而且在用户空间提供了接口可以关闭之,如在上面的测试程序中 39 行处插入 sysmips(MIPS_FIXADE, 0);

头文件包含 sys/sysmips.h 编译执行则会提示常见的 bus error

谢谢

[ 本帖最后由 comcat 于 2007-5-11 01:15 PM 编辑 ]
发表于 2007-5-11 17:19:13 | 显示全部楼层
呵呵 comcat干脆把ld也加上吧 代码应该和lw的差不多
发表于 2007-5-12 08:50:18 | 显示全部楼层
那内核中的lw可能是开发人员测试用的 大概发现效率不高就放弃继续改ld了
 楼主| 发表于 2007-5-15 18:20:25 | 显示全部楼层
早上看了下,内核里已经有了处理ld的代码(位于arch/mips/kernel/unaligned.c),只是代码的作者比较谨慎,在32位的内核模式下没有打开。

将该文件中原 #ifdef CONFIG_64BIT 换成 #if (defined (CONFIG_64BIT) || defined (CONFIG_CPU_GODSON2) ) 后重新编译之,lwu 访问非对齐地址可以了(原来抛出 "Illegal instruction" ),ld/sd 访问非对齐地址亦正常 而非原来的"Illegal instruction"。

[ 本帖最后由 comcat 于 2007-5-15 06:53 PM 编辑 ]
 楼主| 发表于 2007-5-15 18:59:33 | 显示全部楼层
原代码注释为:

        /* A 32-bit kernel might be running on a 64-bit processor.  But
         * if we're on a 32-bit processor and an i-cache incoherency
         * or race makes us see a 64-bit instruction here the sdl/sdr
         * would blow up, so for now we don't handle unaligned 64-bit
         * instructions on 32-bit kernels.
        */

这个在2e平台上并不存在,因而可以直接引入解决lwu/ld/sd 访问非对齐地址抛出"Illegal instruction"的问题。

给个patch 吧,见附件。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册新用户(newuser)

x
发表于 2007-5-15 19:06:42 | 显示全部楼层

回复 #9 comcat 的帖子

谢谢,我得去看看ralf有没有收入龙梦的patch了

本版积分规则

小黑屋|手机版|Archiver|Lemote Inc.  

GMT+8, 2019-9-20 23:54 , Processed in 0.200512 second(s), 19 queries .

快速回复 返回顶部 返回列表