我的板子是c6740,编写测试程序想把两个数组对应的数相乘存到第三个数组中,主文件是:
#include <stdio.h>
int MPY_1(int *m, int *n, int *result, int count);
void main()
{
int n[10] = {1,2,3,4,5,6,7,8,9,10};
int m[10] = {11,12,13,14,15,16,17,18,19,20};
int tmp,i;
int *result;
result = (int *)malloc(10*sizeof(int));
tmp = MPY_1(m,n,result,10);
for(i=0;i<10;i++)
printf("m=%d,n=%d,result=%d,d=%d
",m,n,result,tmp);
}
/**************调用汇编函数文件****************/
.text
.global _MPY_1
_MPY_1:
.asg A4, p_m
.asg B4, p_n
.asg A6, p_result
.asg B6, B_count
.asg A1, A_m
.asg B1, B_n
.asg A3, A_loopcount
.asg A7, A_s
* ================= LOOP PROLOG ============================ *
MV .S1 B6, A_loopcount
|| MV .L1 A4,B4
|| MV .L2 A5,B5
SUB .S1 A_loopcount, 1,A_loopcount
* ===================== LOOP KERNEL ============================== *
loop:
LDW .D1 *A5++[1], A_m ;A_m = *m
|| LDW .D2 *B5++[1], B_n ;A_n = *n
MPY .M1 A_m,B_n,A_s ; A_S = m * n
NOP 1
STW .D1 A_s,*A6++[1] ; result = A_S
||[A_loopcount] B .S2 loop ; branch ,Illegal register for conditional
||[A_loopcount]SUB .S1 A_loopcount, 1,A_loopcount
* ===================== LOOP EPILOG ============================== *
B .S2 B3 ;return
MVK .S1 1,A4 ;return 1
nop 1
.end
这程序编译没通过,在||[A_loopcount] B .S2 loop 这条语句下报错Illegal register for conditional。
第一次写汇编循环,请大侠帮看下这个程序哪些地方出错了?需要怎么改才能实现所想要的功能,谢谢!
[
本帖最后由 breeze505 于 2012-4-27 14:35 编辑 ]
此帖出自
小平头技术问答
原来是3次移位,2次加法,改成1次乘法1次移位,可能会省一些。
但是如果使用打包指令,需要额外使用两个寄存器来保存常数19和6,以便使用MPY2和SHR2指令
cnst1_reg: 0x00130013
cnst2_reg: 0x00060006
所以需要综合考虑算法优化和寄存器资源的限制,各个表达式所需使用的常数是否能共用,以此基础来考虑拆分合并各个表达式。
1.你的思路太好了!我怎么没想到做这种改变,哈~~
但是,只需要保存用作乘数的19,位移操作6为什么需要保存寄存器啊?
SHR .S1 A_r, 6, A_r 指令就可实现位移吧?
其实这里我有个疑问,我在看指令集文档的时候,SHR指令部分里的示例,我不明白为什么有时候SHR移位操作后,原寄存器的高位应该为0的却被补成F,而有时候没有。。。
2. 我汇编的RGB转换编好了(只用位移,没做打包的版本),在调试时我这边遇到个怪问题:
计算Rgb2YCbCr(RgbDataBuffer,8,pYBuffer,pCbBuffer,pCrBuffer,8,8);没问题,输出的3个数组全是正确的
但计算Rgb2YCbCr(RgbDataBuffer,64,pYBuffer,pCbBuffer,pCrBuffer,64,64);就出问题了,输出的pYBuffer正常,但pCbBuffer全为0,pCrBuffer全为128.
我的主文件如下:
BYTE RgbDataBuffer[64*64*3] = {....};
void Rgb2YCbCr(BYTE *pSrcRGB, short BytesPerRow, BYTE *pYBuffer, BYTE *pCbBuffer, BYTE *pCrBuffer, int CompressBlockWidth, int CompressBlockHeight);
void main()
{
BYTE *pYBuffer = (BYTE*)malloc(4096);
BYTE *pCbBuffer = (BYTE*)malloc(4096);
BYTE *pCrBuffer = (BYTE*)malloc(4096);
Rgb2YCbCr(RgbDataBuffer,64,pYBuffer,pCbBuffer,pCrBuffer,64,64);
for(i=0;i<9;i++)
printf(“y=%d,cb=%d,cr=%d ",pYBuffer,pCbBuffer,pCrBuffer);
Rgb2YCbCr汇编文件不知道哪里出了问题,计算8*8像素数据时怎么是正确的..
是不是汇编对传入的数组指针有限制,指向太长的数组就不认识了? 想不明白是什么原因,求教..
我的cmd文件里定义了128K的堆,够用
-heap 0x20000
-stack 0x4000
而且我在主函数main中,换成调用C程序Rgb2YCbCr,输出的3个数组就正确了。
[ 本帖最后由 breeze505 于 2012-5-4 08:59 编辑 ]SHR是带符号右移,移位时高位填0或1是由原操作数是正数还是负数来决定的。
2. 需要单步调试汇编代码,特别注意地址寄存器是否指向正确的地址。
cb = 128 - ((r >> 3) + (r >> 5) + (r >> 7)) - ((g >> 2) + (g >> 4) + (g >> 6)) + (b >> 1) ;
pCbBuffer全为0,说明((r >> 3) + (r >> 5) + (r >> 7)) - ((g >> 2) + (g >> 4) + (g >> 6)) + (b >> 1)的计算结果是128;在调试时只要看第一个像素的计算过程,与实际的差别在什么地方。
一周热门 更多>