![]() |
|
||||||||||||||
| | 首页 | 新闻 | 文库 | 方案 | 技术 | 独家 | 座谈 | 下载 | 图库 | 开发板 | 仿真器 | 邮购 | VIP会员 | 芯片代购 | 客户评价 | | ||
|
||
|
|||||
| uclinux-2008R1-RC8(bf561)到VDSP5的移植(48): __cmpxchg的问题 | |||||
作者:快乐虾 文章来源:http://blog.csdn.net/lights_joy 点击数: 更新时间:2008-7-1 ![]() |
|||||
|
在include/asm/system.h下有一个__cmpxchg函数:
/*
* Atomic compare and exchange. Compare OLD with MEM, if identical,
* store NEW in MEM. Return the initial value in MEM. Success is
* indicated by comparing RETURN with OLD.
*/
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
unsigned long new, int size)
{
unsigned long tmp = 0;
unsigned long flags = 0;
local_irq_save(flags);
switch (size) {
case 1:
__asm__ __volatile__
("%0 = b%3 (z);\n\t"
"CC = %1 == %0;\n\t"
"IF !CC JUMP 1f;\n\t"
"b%3 = %2;\n\t"
"1:\n\t"
: "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory");
break;
case 2:
__asm__ __volatile__
("%0 = w%3 (z);\n\t"
"CC = %1 == %0;\n\t"
"IF !CC JUMP 1f;\n\t"
"w%3 = %2;\n\t"
"1:\n\t"
: "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory");
break;
case 4:
__asm__ __volatile__
("%0 = %3;\n\t"
"CC = %1 == %0;\n\t"
"IF !CC JUMP 1f;\n\t"
"%3 = %2;\n\t"
"1:\n\t"
: "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory");
break;
}
local_irq_restore(flags);
return tmp;
}
在VDSP下编译将产生如下语法错误:
"..\..\include\asm/system.h", line 209: cc1101: error: invalid constraint in
asm statement
: "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory");
^
"..\..\include\asm/system.h", line 209: cc1155: error: gnu asm operand
requires integral or pointer type
: "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory");
^
"..\..\include\asm/system.h", line 218: cc1101: error: invalid constraint in
asm statement
: "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory");
^
"..\..\include\asm/system.h", line 218: cc1155: error: gnu asm operand
requires integral or pointer type
: "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory");
^
"..\..\include\asm/system.h", line 227: cc1101: error: invalid constraint in
asm statement
: "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory");
^
"..\..\include\asm/system.h", line 227: cc1155: error: gnu asm operand
requires integral or pointer type
: "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory");
^
6 errors detected in the compilation of "..\..\fs\sysfs\dir.c".
cc3089: fatal error: Compilation failed
首先,VDSP的嵌入汇编不支持”m”这个constraint,但是可以用”a”来替换。
其次,VDSP的嵌入汇编不支持"a" (*__xg(ptr))结构体的传递,可以直接使用"a" (ptr),所得到的结果和GCC的相一致。
在改正完上面两个错误后,还有更奇怪的问题:
[Error ea5003] "c:\temp\acc01786adb000\acc01786adb001.s":138 Semantic Error in instruction :
IF !CC JUMP 1f;
Operands don't fit instruction template 'IF BANG CC JUMP expr'.
Check for an out of range immediate value or an illegal register.
[Error ea5004] "c:\temp\acc01786adb000\acc01786adb001.s":138 Syntax Error in :
IF !CC JUMP 1f;
syntax error is at or near text 'f'.
Attempting error recovery by ignoring text until the ';'
[Error ea5004] "c:\temp\acc01786adb000\acc01786adb001.s":139 Syntax Error in :
wP1 = R1;
syntax error is at or near text '='.
Attempting error recovery by ignoring text until the ';'
[Error ea5007] "c:\temp\acc01786adb000\acc01786adb001.s":140 The label "1:" is illegal because it begins with a digit. If this is GNU assembly source, rewrite to a local temporary name of your choosing. If the GNU assembly code was generated from a macro, the VisualDSP++ preprocessing label auto-generation feature ("?") can be used to generate a unique local label.
[Error ea5003] "c:\temp\acc01786adb000\acc01786adb001.s":158 Semantic Error in instruction :
IF !CC JUMP 1f;
Operands don't fit instruction template 'IF BANG CC JUMP expr'.
Check for an out of range immediate value or an illegal register.
[Error ea5004] "c:\temp\acc01786adb000\acc01786adb001.s":158 Syntax Error in :
IF !CC JUMP 1f;
syntax error is at or near text 'f'.
Attempting error recovery by ignoring text until the ';'
[Error ea5007] "c:\temp\acc01786adb000\acc01786adb001.s":160 The label "1:" is illegal because it begins with a digit. If this is GNU assembly source, rewrite to a local temporary name of your choosing. If the GNU assembly code was generated from a macro, the VisualDSP++ preprocessing label auto-generation feature ("?") can be used to generate a unique local label.
Previous errors prevent assembly
Assembler totals: 7 error(s) and 0 warning(s)
cc3089: fatal error: Assembler failed
如果不是刚改完此函数,几乎无法知道错误的来源在哪里!
根据提示检查上述汇编代码,修改jump 1f之类的跳转后OK。
而对于wP1 = R1;这样的错误则改为w[%3]之类的。
修改完后的函数如下:
/*
* Atomic compare and exchange. Compare OLD with MEM, if identical,
* store NEW in MEM. Return the initial value in MEM. Success is
* indicated by comparing RETURN with OLD.
*/
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
unsigned long new, int size)
{
unsigned long tmp = 0;
unsigned long flags = 0;
local_irq_save(flags);
switch (size) {
case 1:
__asm__ __volatile__
("%0 = b[%3] (z);\n\t"
"CC = %1 == %0;\n\t"
"IF !CC JUMP __cmpxchg_size_1;\n\t"
"b[%3] = %2;\n\t"
"__cmpxchg_size_1:\n\t"
: "=&d" (tmp) : "d" (old), "d" (new), "a" (ptr) : "memory");
break;
case 2:
__asm__ __volatile__
("%0 = w[%3] (z);\n\t"
"CC = %1 == %0;\n\t"
"IF !CC JUMP __cmpxchg_size_2;\n\t"
"w[%3] = %2;\n\t"
"__cmpxchg_size_2:\n\t"
: "=&d" (tmp) : "d" (old), "d" (new), "a" (ptr) : "memory");
break;
case 4:
__asm__ __volatile__
("%0 = %3;\n\t"
"CC = %1 == %0;\n\t"
"IF !CC JUMP __cmpxchg_size_4;\n\t"
"%3 = %2;\n\t"
"__cmpxchg_size_4:\n\t"
: "=&d" (tmp) : "d" (old), "d" (new), "a" (ptr) : "memory");
break;
}
local_irq_restore(flags);
return tmp;
}
|
|||||
| 文章录入:admin 责任编辑:admin | |||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | |||||
| 最新热点 | 最新推荐 | 相关文章 | ||
| 基于DDS芯片AD9851的精密跳频 基于Blackfin DSP的函数_任意 DSP芯片外围电路典型设计 放大器输入保护的利与弊 隔离式电压/电流传感器1B21的 仪表放大器:怎样构建与何时 AD8369,10,7M 两级AD8369做1 请教一个关于AD8310功耗的问 差错和不足:ADI《仪表放大器 Analog Devices Blackfin处理 |
| 网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |
| | 本站介绍 | 合作联络 | 欢迎投稿 | 广告业务 | 网站地图 | 设为首页 | 加入收藏 | 友情链接 | 网站公告 | 联系我们 | | |||
|