DSP编程中使用的预编译指令
- 格式:doc
- 大小:36.00 KB
- 文档页数:10
DSP应用中编译选项的智能选择作者:CEVA公司编译器项目经理Eran Balaish摘要随着DSP处理器的能力越来越强大,可采用C编译器的代码部分在不断增加。
不过,没有编程人员的协助,编译器是无法生成最优化的代码。
为了最大地提高性能,编程人员必须利用各种编译选项功能来调节编译器。
不幸的是,在DSP应用里,没有充分利用编译器调节能力的现象相当普遍。
整个应用过程中,往往只利用一组相同的编译选项来进行编译。
这种方法忽略了每一项功能的特殊需求。
编译选项的智能选择可以大幅提高性能,例如可以大大减少代码量。
在评估产品成本时,代码量通常是主要考虑因素,因为这对所需存储量有直接的影响。
本文将介绍如何减少代码的使用量以及其它重要资源的消耗量。
在指令周期数和代码量之间进行权衡,满足功能级的特殊要求为了更好地了解如何利用编译选项的智能选择来节省代码量,必须熟悉指令周期数与代码量之间的权衡取舍,这方面的实例是循环展开 (loop-unrolling) 和软件流水(SWP) 的常用编译器优化技术。
这种技术通过循环体的复制来进行循环展开,利用从循环语句内部到循环语句外部的某些指令的拷贝来实现SWP。
当使用带有深度管线的多事件超长指令字 (VLIW)处理器时,该技术显得非常有用。
这时,SWP可中断循环语句内部的许多依赖关系,而循环展开能够大幅提高指令间并行性 (ILP)。
这里给出了简单的乘法与累加 (mac) 循环语句,以阐释循环展开和SWP。
for (i = 0; i < 960; i++){sum += src1[i] * src2[i];}图1. 基本的C语言级mac循环语句下面摘选了一段效率相对低的简单汇编代码,是在为代码量最小化而调节CEVA-X1641™ DSP内核编译器时产生的。
它使用了SWP,但没有循环展开。
这个循环语句的执行需要使用大约959*2 = 1918个指令周期,所需代码量小于20个字节。
LS0.ld {w} (r3)+#2, a3lLS0.ld {w} (r4)+#2, a2lSQ.bkrep {ds1} #958nop{nopA.S.mac a2l, a3l, a0|| LS0.ld {w} (r3)+#2, a3l|| LS1.ld {w} (r4)+#2, a2l}图2. CEVA-X1641编译器产生的mac循环语句中的简单但效率较低的汇编实现方案相反地,当为指令周期数最小化而调节时,CEVA-X1641编译器产生的结果截然不同。
预编译指令#pragma详解#pragma详解在#Pragma是预处理指令它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。
#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。
依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。
其格式一般为:#Pragma Para其中Para为参数,下面来看一些常用的参数。
(1)message参数。
Message参数是我最喜欢的一个参数,它能够在编译信息输出窗口中输出相应的信息,这对于源代码信息的控制是非常重要的。
其使用方法为:#Pragma message(“消息文本”)当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。
当我们在程序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设置这些宏,此时我们可以用这条指令在编译的时候就进行检查。
假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏可以用下面的方法#ifdef_X86#Pragma message(“_X86macro activated!”)#endif当我们定义了_X86这个宏以后,应用程序在编译时就会在编译输出窗口里显示“_X86macro activated!”。
我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了。
(2)另一个使用得比较多的pragma参数是code_seg。
格式如:#pragma code_seg([\section-name\[,\section-class\]])它能够设置程序中函数代码存放的代码段,使用没有section-name字符串的#pragmacode_seg可在编译开始时将其复位,当我们开发驱动程序的时候就会使用到它。
(3)#pragma once(比较常用)只要在头文件的最开始加入这条指令就能够保证头文件被编译一次,这条指令实际上在VC6中就已经有了,但是考虑到兼容性并没有太多的使用它。
附录6 TMS320C54x 指令系统一览表(按指令功能排列) 一、算术运算指令二、逻辑运算指令三、程序控制指令6.注:?条件“真”,§条件“假”,※延迟指令。
四、加载和存储指令4.6.7.五.伪指令2.初始化常数(数据和存储器)的伪指令3.调整段程序计数器伪指令(SPC).align 把SPC调整到页边界.even 把SPC调整到偶数字边界4.控制输出列表格式化伪指令5.条件汇编伪指令.break [well-defined expression] 如果条件真结束.loop汇编,.break结构是可选项.else 如果.if条件为假,汇编代码块.else结构是可选项.elseif well-defined expression——如果if条件为假且.elseif条件为真,汇编代码块.else结构是可选项.endif 结束.if代码块.endloop 结束.1oop代码块.if well-defined expression 如果条件为真则汇编代码块.loop [well-defined expression] 开始代码块的重复汇编6. 汇编符号.asg [”] character string [”],substitution symbol——把字符串赋予替代的符号..endstruct 结束结构定义.equ 使值和符号相等.eval well-defined expression,substitution symbol 根据数字替代符号完成运算.newblock 取消局部标号.set 使数值和符号相等.struct 开始结构定义.tag 把结构属性赋予标号7.宏指令宏定义:Macname .macro[参数1],[…],[参数n]宏调用:[标号][:] macname [参数1],[…],[参数n]8.编译软件指令①汇编器:asm500.exeasm500[input file[object file [listing file] [-options]]-c—使汇编语言文件中大小没有区别。
DSP汇编指令总结DSP汇编指令总结⼀、寻址⽅式:1、⽴即寻址:短⽴即寻址(单指令字)长⽴即数寻址(双指令字)第⼀指令字第⼆指令字16位常数=16384=4000h2、直接寻址ARU 辅助寄存器更新代码,决定当前辅助寄存器是否和如何进⾏增或减。
N规定是否改变ARP值,(N=0,不变)4.3.1、算术逻辑指令(28条)4.3.1.1、加法指令(4条);4.3.1.2、减法指令(5条);4.3.1.3、乘法指令(2条);4.3.1.4、乘加与乘减指令(6条);4.3.1.5、其它算数指令(3条);4.3.1.6、移位和循环移位指令(4条);4.3.1.7、逻辑运算指令(4条);4.3.2、寄存器操作指令(35条)4.3.2.1、累加器操作指令(6条)4.3.2.2、临时寄存器指令(5条)4.3.2.3、乘积寄存器指令(6条)4.3.2.4、辅助寄存器指令(5条)4.3.2.5、状态寄存器指令(9条)4.3.2.6、堆栈操作指令(4条)4.3.3、存储器与I/O操作指令(8条)4.3.3.1、数据移动指令(4条)4.3.3.2、程序存储器读写指令(2条)4.3.3.3、I/O操作指令(2条)4.3.4、程序控制指令(15条)4.3.4.1、程序分⽀或调⽤指令(7条)4.3.4.2、中断指令(3条)4.3.4.3、返回指令(2条)4.3.4.4、其它控制指令(3条)4.3.1、算术逻辑指令(28条)4.3.1.1、加法指令(4条);▲ADD▲ADDC(带进位加法指令)▲ADDS(抑制符号扩展加法指令)▲ADDT(移位次数由TREG指定的加法指令)4.3.1.2、减法指令(5条);★SUB(带移位的减法指令)★SUBB(带借位的减法指令)★SUBC(条件减法指令)★SUBS(减法指令)★SUBT(带移位的减法指令,TREG决定移位次数)4.3.1.3、乘法指令(2条);★MPY(带符号乘法指令)★MPYU(⽆符号乘法指令)4.3.1.4、乘加与乘减指令(6条);★MAC(累加前次积并乘)(字数2,周期3)★MAC(累加前次积并乘)★MPYA(累加-乘指令)★MPYS(减-乘指令)★SQRA(累加平⽅值指令)★SQRS(累减并平⽅指令)4.3.1.5、其它算数指令(3条);★ABS(累加器取绝对值指令)★NEG(累加器取补码指令)★NORM(累加器规格化指令)返回4.3.1.6、移位和循环移位指令(4条);▲ SFL(累加器内容左移指令)▲ SFR(累加器内容右移指令)▲ROL(累加器内容循环左移指令)▲ROR(累加器内容循环右移指令)返回4.3.1.7、逻辑运算指令(4条);▲ AND(逻辑与指令)▲ OR(逻辑或指令)▲ XOR(逻辑异或指令)▲ CMPL(累加器取反指令)返回4.3.2、寄存器操作指令(35条)4.3.2.1、累加器操作指令(6条)▲ LACC(装载累加器指令)▲ LACT(装载累加器)*按TREG低4位指定的次数移位▲ LACL(装载累加器低16位指令)▲ ZALR(装载累加器指令)▲ SACL(移位并存储累加器低半部)▲ SACH(移位并存储累加器⾼半部)返回4.3.2.2、临时寄存器指令(5条)▲ LT(装载TREG指令)▲ LTA(装载TREG并累加上次乘积指令)▲ LTS (装载TREG并减去上次乘积指令)▲ LTD(装载TREG并累加上次乘积及数据移动指令)▲LTP(装载TREG和累加器指令)返回4.3.2.3、乘积寄存器指令(6条)▲ PAC (乘积寄存器内容载⼊累加器)▲ APAC (PREG与累加器相加)▲ SPAC(累加器和乘积寄存器相减)▲ LPH(装载PREG⾼16位指令)▲ SPL(存储PREG低16位指令)▲ SPH(存储PREG⾼16位指令)返回4.3.2.4、辅助寄存器指令(5条)★LAR(装载当前辅助寄存器AR)★SAR(存储辅助寄存器指令)★MAR(修改当前辅助寄存器)★SBRK(从当前辅助寄存器减去短⽴即数)返回4.3.2.5、状态寄存器指令(9条)★LST(装载状态寄存器)★SST(存储状态寄存器)★SETC(控制位置“1”指令)★SETC(控制位置“1”指令)★LDP(装载数据指针DP指令)★BIT(位测试指令)★BITT(测试由TREG指定bit code指令)★CMPR(⽐较当前辅助寄存器AR和AR0)返回4.3.2.6、堆栈操作指令(4条)★PUSH(累加器低16位进栈指令)★POP(栈顶内容弹出⾄累加器低16位指令)★POP(栈顶内容弹出⾄累加器低16位指令)★POPD(弹栈⾄数据存储器指令)返回4.3.3、存储器与I/O操作指令(8条)4.3.3.1、数据移动指令(4条)▲DMOV(数据存储器内部数据移动指令)▲SPLK(存储长⽴即数⾄数据存储器指令)▲BLDD(数据存储器内部的数据块移动)▲ BLPD(从程序存储器到数据存储器的数据块传送)4.3.3.2、程序存储器读写指令(2条)★TBLR(读程序存储器数据到数据存储器)★TBLW(写程序存储器)4.3.3.3、I/O操作指令(2条)★IN(数据输⼊指令)★OUT(数据输出指令)4.3.4、程序控制指令(15条)4.3.4.1、程序分⽀或调⽤指令(7条)★B(⽆条件转移指令)★BANZ(辅助寄存器内容不等于零转移)★CALL(⽆条件⼦程序调⽤指令)★BACC(按累加器内容转移指令)★CALA(由累加器指定地址的⼦程序调⽤指令)★CC(条件调⽤指令)4.3.4.2、中断指令(3条)★INTR(软中断指令)★TRAP(软件陷阱中断)★NMI(⾮屏蔽中断)4.3.4.3、返回指令(2条)★RET(⽆条件从⼦程序或中断返回)★RETC(条件返回指令)4.3.4.4、其它控制指令(3条)★RPT(重复执⾏下条指令)★NOP(空操作)★IDEL(暂停)返回。
DSP编程中使用的预编译指令 #pragma(2008-12-10 10:55:09)转载▼标签:杂谈【原创】转载请注明出处**** TypeWritter: Li Hui*** Start Time: Nov.19.2008*** Version 1.3**** use word to instead 2 * 16bit short data's access ** void vecsum4(short *restrict sum, restrict short *in1, restrict short *in2, unsigned int N){int i;#pragma MUST_ITERATE(10);for(i=0;i<(N/2);i++)_amem4(&sum[i]) =add2(_amem4_const(&in1[i]),_amem4_const(&in2[i])); }** near variable's access **LDW *dp(_address),a1** far variables' access **MVKL _address,a1MVKH _address,a1LDW *a1,a0** far function call **MVKL _func,a1MVKH _func,a1B a1** default is near type **** if you use -mr1 option, all the func are 'far' if you don't use -mr1, default is 'near'if you use -mr0, then all the array or matrix are 'far', program is 'near'if you use -mr1, then all the array or matrix are 'near', program is 'far'if you use -mr2, then all the array, matrix, program are 'far'if you use -mr3, then all data and program are 'far'**** not-related **void foo(int * restrict a, int * restrict b)void foo(int c[restrict], int d[restrict])** difference of const-pointer and point to const**int * const p = &x; ** a const pointer who point to a variable named x **const int * p = &x; ** a pointer who point to a const named x, the pointer can point another variable **** volatile - to guarantee a variable can not be optimized by optimizer **unsigned int *ctrl;while(*ctrl !=0xFF)...** optimizer will treat ctrl a const **** so we should specify the ctrl's type is 'volatile' ** volatile unsigned int * ctrl;** That's ok **** Embedded the assembly language into the .C file **asm(" Assembly Language... ");** Useful Pragma Directive **** (1) CODE_SECTION **** Allocate space for symbol in the section named "section name" **#pragma CODE_SECTION(symbol,"section name"); // in C language** (2) DATA_ALIGN **** align symbol to the column edge specfied by the constant ** #pragma DATA_ALIGN(symbol,constant); // constant must be power of 2eg1:#pragma DATA_ALIGN(inputArray,8);// when you use DSPLIB FFT functions** (3) DATA_MEM_BANK **** align the symbol and variables to the page edge specified by the constant **** avoid the data's overlapped storage **#pragma DATA_MEM_BANK(symbol,constant); ** C64 : constant must be 0-15 and must be even **** (4) DATA_SECTION **** Allocate space for symbol in the section named "section name" **** 4-1 C Language **#pragma DATA_SECTION(symbol,"section name");** 4-2 C++ Language **#pragma DATA_SECTION("section name");** 4-3 Assembly Language **.global _bufferA.bss _bufferA,512,4.global _bufferB_bufferB .usect "section name",512,4** (5) FUNC_CANNOT_INLINE **** this function can not be inline, even the function is defined 'inline' **#pragma FUNC_CANNOT_INLINE(func);** (6) FUNC_EXT_CALLED **** if you add -pm options in the compile period, the compiler will erase the function which haven't beencalled by main, but acturally, the function may be called by .asm file. **#pragma FUNC_EXT_CALLED(func);** restriction: func can not be _c_int00 **** (7) FUNC_INTERRUPT_THRESHOLD **#pragma FUNC_INTERRUPT_THRESHOLD(func,threshold);eg1:#pragma FUNC_INTERRUPT_THRESHOLD(func1,2000);** the period between the func1's interrupts must lager than 2000 clock cycle **eg2:#pragma FUNC_INTERRUPT_THRESHOLD(func2,1);** the func2 can always be interrupted **eg3:#pragma FUNC_INTERRUPT_THRESHOLD(func3,-1);** the func2 can not be interrupted **** (8) FUNC_IS_PURE **** This function has no side-effect, if you do not need the value returned by func, you can delete its' callyou can delete the copy of the func**#pragma FUNC_IS_PURE(func);** (9) FUNC_IS_SYSTEM **** this function has the ANSI standard operation, the directive must be used for ANSI standard function **** for example: memcpy, strcmp and so on **#pragma FUNC_IS_SYSTEM(func);** (10) FUNC_NEVER_RETURNS **** this function never returns, so compiler can not terminate this function or free stack and so on **#pragma FUNC_NEVER_RETURNS(func);** (11) FUNC_NO_GLOBAL_ASG **** this function will not assign global variables and not contains .asm sentences **#pragma FUNC_NO_GLOBAL_ASG(func);** (12) FUNC_NO_IND_ASG **** this function will not allocate space via pointer and not contains .asm sentences **#pragma FUNC_NO_IND_ASG(func);** (13) INTERRUPT **** you can use the function to handle the DSP's interrupt ** #pragma INTERRUPT(func);** (14) MUST_ITERATE **** Specify the cycle's minimum times, maximun times and the times must be multiple of 'multiple' **#pragma MUST_ITERATE(min,max,multiple);** (15) NMI_INTERRUPT **** you can use the function to handle the Non Maskable Interrupt(NMI) **#pragma NMI_INTERRUPT(func);** (16) PROB_ITERATE **** Specify the cycle's minimum times, maximun times **#pragma PROB_ITERATE(min,max);** (17) STRUCT_ALIGN **** Like to DATA_ALIGN, using for defination of struct and class **#pragma STRUCT_ALIGN(type,constact expression);eg:typedef strct st_tag{int a;short b;}st_typedef;#pragma STRUCT_ALIGN(st_tag,128);** (18) UNROLL **** Specify which number of cycle times can not be unfolded ** #pragma UNROLL(n);。
预编译指令常见用法很多优秀的代码,都会借用预编译指令来完善代码,今天就来讲讲关于预编译指令的内容。
常见的预处理指令如下:1.#指令,无任何效果2.#include含一个源代码文件3.#define义宏4.#undef消已定义的宏5.#if果给定条件为真,则编译下面代码6.#ifdef果宏已经定义,则编译下面代码7.#ifndef果宏没有定义,则编译下面代码8.#elif果前面的if定条件不为真,当前条件为真,则编译下面代码9.#endif束一个if……#else件编译块10.#error止编译并显示错误信息本来只是想了解一下#ifdef,#ifndef,#endif的,没想到查出来这么多的预处理指令,上面的多数都是常见的,但是平时没有怎么注意预处理这方面的内容,所以这里梳理一下知识吧。
同时有什么不妥的地方,或者遗漏了什么内容,还请留言指出。
什么是预处理指令?预处理指令是以#号开头的代码行。
#号必须是该行除了任何空白字符外的第一个字符。
#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。
整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换。
预处理指令是在编译器进行编译之前进行的操作,对其进行初步的转换,产生新的源代码提供给编译器。
可见预处理过程先于编译器对源代码进行处理。
在很多编程语言中,并没有任何内在的机制来完成如下一些功能:在编译时包含其他源文件、定义宏、根据条件决定编译时是否包含某些代码(防止重复包含某些文件)。
要完成这些工作,就需要使用预处理程序。
尽管在目前绝大多数编译器都包含了预处理程序,但通常认为它们是独立于编译器的。
预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行响应的转换。
预处理过程还会删除程序中的注释和多余的空白字符。
#include包含一个源代码文件这个预处理指令,我想是见得最多的一个,简单说一下;1.第一种方法是用尖括号把头文件括起来。
C2的指令集C2xx DSP中共有汇编语言指令88条,分成6类:①累加器、算术和逻辑指令26条如:ADD、LACC、AND②辅助寄存器和数据页面指针指令7条如:MAR、LAR等③TREG、PREG和乘法指令20条如:LT、MTY、PAC等④分支、调用指令12条如:B、BCND、INTR等⑤控制指令15条如:SPM、POP、BIT等⑥存储器和I/O操作指令8条如:BLDD、SPLK、TBLR等注:有些指令助记符是增强性指令,对应于几条简单指令(机器码),如:ADD 可完成ADD,ADDH,ADDK和ADLK等功能,这样做可使程序更简洁并易读。
累加器,算术与逻辑指令助记符指令描述指令的中英文指令字周期ABSACC的绝对值Absolute Value of Accumulator(累加器内容取绝对值11ADD 加给ACC,带0~15-bit移位,直接或间接Add to Accumulator(加入累加器)11加给ACC,带0~15-bit移位,长立即数22加给ACC,带16-bit移位,直接或间接1 1加给ACC,短立即数1 1ADDC 加给ACC,带进位,直接或间接Add to Accumulator With Carry(带进位位加至累加器)1 1ADDS加给ACC低段,带符号展开抑制,直接或间接Add to Accumulator With Sign ExtensionSuppressed(抑制符号扩展加至累加器)1 1ADDT加给ACC,由TREG决定移位,直接或间接Add to Accumulator With Shift Specifiedby TREG(按TREG寄存器内容移位后加至累加器)1 1AND ACC与数据值,直接或间接AND With Accumulator(和累加器逻辑“与”)1 1ACC与长立即数,带0~15-bit移位2 2ACC与长立即数,带16-bit移位2 2CMPLACC取补Complement Accumulator(累加器求反(补)1 1LACC 带移位0~15-bit装入ACC,直接或间接Load Accumulator With Shift(数据左移后装入累加器)1 1带移位0~15-bit装入ACC,长立即数2 2带移位16-bit装入ACC,直接或间接1 1LACL 装入ACC的低段,直接或间接Load Low Accumulator and Clear HighAccumulator(装载累加器低位并清累加器高位)1 1装入ACC的低段,短立即数1 1LACT 装入ACC,由TREG低4位(0~3bit)决定移位(0~15bit),直接或间接Load Accumulator With Shift Specifiedby TREG(按TREG规定的移位后装入累加器)1 1NEG ACC取负Negate Accumulator(累加器求负) 1 1NORMACC内容归一化,间接Normalize Contents of Accumulator(规格化累加器)1 1OR ACC或数据值,直接或间接OR With Accumulator(与累加器逻辑“或” )1 1ACC或长立即数,带0~15-bit移位2 2ACC或长立即数,带16-bit移位2 2ROLACC循环左移Rotate Accumulator Left(累加器逻辑循环左移)1 1RORACC循环右移Rotate Accumulator Right(累加器逻辑循环右移)1 1SACH 存高段ACC,带移位0~7-bit,直接或间接Store High Accumulator With Shift(移位并存储累加器高位)1 1SACL 存低段段ACC,带移位0~7-bit,直接或间接Store Low Accumulator With Shift(移位并存储累加器低位)1 1SFLACC左移Shift Accumulator Left(累加器算术左移)1 1SFRACC右移Shift Accumulator Right(累加器算术右移)1 1SUB 从ACC减,带移位0~15 - bit,直接或间接Subtract From Accumulator (从累加器减 1 1从ACC减,带移位 0~15-bit,长立即数2 2从ACC减,带移位 16- bit,1 1直接或间接从ACC减,短立即数1 1SUBB 从ACC带借位减,直接或间接Subtract From Accumulator With Borrow(带借位从累加器减1 1SUBC 条件减,直接或间接Conditional Subtract(条件减法 1 1SUBS从ACC减,抑制符号展开,直接或间接Subtract From Accumulator With SignExtension Suppressed (抑制符号扩展从累加器减1 1SUBT 从ACC减,由 TREG决定的移位( 0~15-bit),直接或间接Subtract From Accumulator With ShiftSpecified by TREG (按TREG指定的值进行移位后从累加器减1 1XOR ACC异或数据值,直接或间接Exclusive OR With Accumulator (与累加器逻辑“异或”1 1ACC异或长立即数,带0~15-bit移位2 2ACC异或长立即数,带16-bit移位2 2ZALR ACC低段置0,舎入后装入ACC高段,直接或间接Zero Low Accumulator and Load HighAccumulator With Rounding(累加器低位清零并四舍五入装载累加器高位1 1辅助寄存器指令助记符指令描述指令的中英文指令字周期ADRK 常数加给AR,短立即数Add Short-Immediate Value toAuxiliary Register(短立即数加至当前辅助寄存器1 1BANZ 当前AR非0转移,间接Branch on Auxiliary RegisterNot Zero(辅助寄存器不等于2 2零转移CMPR 当前AR与AR0比较Compare Auxiliary RegisterWith AR0 (比较当前辅助寄存器和AR0,并把比较结果放在ST1的TC位1 1LAR 从指定的数据位置装入指定的AR,直接或间接Load Auxiliary Register(装载辅助寄存器1 2常数装入指定的AR,短立即数1 2常数装入指定的AR,长立即数2 2MAR 修改当前AR和/或ARP,间接(直接时无操作)Modify Auxiliary Register(修改辅助寄存器1 1SAR 存指定的AR至指定位置,直接或间接Store Auxiliary Register(存储辅助寄存器1 1SBRK 从当前AR减去常数,短立即数Subtract Short-ImmediateValue From AuxiliaryRegister(从当前辅助寄存器减去短立即数1 1暂时寄存器(TREG)、乘积寄存器(PREG)和乘法指令助记符指令描述指令的中英文指令字周期APAC PREG加到ACC Add PREG to Accumulator(P寄存器加至累加器1 1LPH 装入PREG高位Load Product Register HighWord(装载乘积寄存器高位1 1LT 装入TREG,直接或间接Load TREG(装载TREG寄存器1 1LTA 装入TREG,累加前次乘积,直接或间接Load TREG and AccumulatePrevious Product(装载TREG寄存器并累加前次乘积1 1LTD 装入TREG,累加前次乘积,搬移数据,直接或间接Load TREG, AccumulatePrevious Product, and MoveData(装载TREG寄存器、累加前次乘积并移动数据1 1LTP 装入TREG,存PREG入ACC,直接或间接Load TREG and Store PREG inAccumulator(装载TREG寄存器并存储PREG寄存器到累计器1 1LTS 装入TREG,减去前次乘积,直接或间接Load TREG and SubtractPrevious Product(装载TREG寄存器并减去前次乘积1 1MAC 乘且累加,直接或间接Multiply and Accumulate(乘且累加2 3MACD 乘且累加,数据转移,直接或间接Multiply and Accumulate WithData Move(乘且累加并带数据移动2 3MPY TREG乘数据值,直接或间接Multiply(乘 1 1TREG乘13-bit常数,短立即数1 1MPYA 乘且累加前次乘积,直接或间接Multiply and AccumulatePrevious Product(乘且累加前次乘积1 1MPYS 乘且减去前次乘积,直接或间接Multiply and Subtract PreviousProduct(乘且减去前次乘积 1 1MPYU 乘无符号数,直接或间接Multiply Unsigned(无符号乘法 1 1 PAC PREG装入ACC Load Accumulator With ProductRegister(将乘积寄存器装入累加器1 1SPAC 从ACC减去PREG Subtract PREG FromAccumulator(从累加器减去PREG寄存器1 1 SPH 存高段PREG,直接或间接Store High PREG(存储PREG 1 1高位SPL 存高段PREG,直接或间接Store Low PREG(存储PREG低位1 1SPM 设置乘积移位方式Set PREG Output ShiftMode(设置PREG移位方式1 1SQRA 平方且累加前次乘积,直接或间接Square Value and AccumulatePrevious Product(平方并累加前次乘积1 1SQRS 平方且减去前次乘积,直接或间接Square Value and SubtractPrevious Product(平方并减去前次乘积1 1转移指令助记符指令描述指令的中英文指令字周期B 无条件转移,间接Branch Unconditionally(无条件转移 2 4 BACC 转移至ACC指定的地址Branch to Location Specified byAccumulator(按累加器内容转移1 4BANZ 当前AR非0时转移,间接;判断(AR,(AR-1→(ARBranch on Auxiliary Register NotZero(当前辅助寄存器不等于零转移 2 4BCND 条件转移Branch Conditionally(条件转移 2 4CALA 调用ACC指定位置的子程序,间接Call Subroutine at Location Specifiedby Accumulator(调用累加器低16位指定地址处的子程序2 4CALL 调用子程序,间接Call Unconditionally(无条件调用指令2 4 CC 条件调用Call Conditionally(条件转移指令 2 4 INTR 软中断Software Interrupt(软中断 1 4NMI 不可禁止的中断Nonmaskable Interrupt(不可屏蔽中断转移到程序存储器1 4 RET 从子程序返回Return From Subroutine(子程序返回 1 4 RETC 条件返回Return Conditionally(条件返回 1 4 TRAP 软件中断Software Interrupt(软件陷阱中断 1 4 控制指令助记符指令描述指令的中英文指令字周期BIT 位测试,直接或间接Test Bit(位测试 1BITT 由TREG指定的位测试,直接或间接Test Bit Specified byTREG(测试TREG寄存器规定的位1CLRC 清除C位Clear Control Bit(状态位清零1清除INTM位 1 1 清除OVM位 1 1 清除SXM位 1 1 清除TC位 1 1 清除XF位 1 1IDLE 停止执行,直至中断Idle Until Interrupt(空闲直至中断发生1LDP 装入数据页指针,直接或间接Load Data PagePointer(装载数据页指针 1装入数据页指针,短立即数1 2LST 装入状态寄存器ST0,直接或间接Load Status Register(装载状态寄存器1装入状态寄存器ST0,直接或间接1 2NOP 无操作No Operation(空操作 1POP 将堆栈顶弹出至ACC低段Pop Top of Stack to Low Accumulator(栈顶弹出至累加器的低位1POPD 将堆栈顶弹出至数据存储器,直接或间接Pop Top of Stack to DataMemory(栈顶弹出至数据存储器1PSHD 将数据存储器的值压入堆栈,直接或间接Push Data-Memory ValueOnto Stack(数据存储器值进栈1PUSH 将ACC低段压入堆栈Push Low AccumulatorOnto Stack(累加器低位进栈1RPT 重复执行下一条指令,直接或间接Repeat NextInstruction(重复执行下条指令1重复执行下一条指令,短立即数1 1SETC 设置SXM位Set Control Bit(置位 1 设置TC位 1 1设置XF位 1 1设置C位 1 1设置CNF位 1 1设置INTM位 1 1设置OVM位 1 1SPM 设置乘积移位模式Set PREG Output ShiftMode(设置PREG移位输出方式1SST 存状态寄存器ST0,直接或间接Store Status Register(存储状态寄存器1存状态寄存器ST1,直接或间接1 1I/O和存储器指令助记符指令描述指令的中英文指令字周期BLDD 数据块从数据存储器搬移至数据存储器,直接或间接,长立即数作源存储器地址Block Move From Data Memory toData Memory(数据存储器到数据存储器的块传送2 3BLPD 数据块从程序存储器搬移至数据存储器,直接或间接,长立即数作源存储器地址Block Move From Program Memoryto Data Memory(程序存储器到数据存储器的块传2 3DMOV 数据在数据存储器中搬移,直接或间接Data Move in Data Memory(在数据存储器内传送数据1 1IN 从I/O输入数据,直接或间接Input Data From Port(端口地址送数据地址总线2 2OUT 输出数据至口,直接或间接Output Data to Port(端口地址送数据地址总线2 3SPLK 存长立即数至数据存储器,直接或间接Store Long-Immediate Value to DataMemory(存储长立即数值至数据存储器2 2TBLR 读数据表,直接或间接Table Read(读表 1 3TBLW 写数据表,直接或间接 Table Write(写数据表 1 31. 指令格式(即语法)不带进位加法指令格式: ADD dma [,shift] ;直接寻址 ADD dma ,16 ;16位左移直接寻址 ADD ind [,shift [,ARn ] ] ;间接寻址 ADD ind ,16[,ARn ] ;16位左移的间接寻址 ADD #k ;短立即寻址ADD #lk [,shift ] ;长立即寻址2.操作数dma;直接寻址时,数据存储器地址低7位shift:;左移值从0 到 15(默认值为0)n;指示下一个辅助寄存器n= 0~ 7 k: ;8位短立即数值lk: ;16位短立即数值ind;选择下列7种间接寻址方式中的一种* *+ *- *0+ *0- *BR0+ *BR0-3.操作码.执行4(1 (Smem+(src→src(2 (Smem<<(TS)+(src)→src(3 (Smem<<16+(src)→dst(4 (Smem[ <<SHIFT]+(src)→dst(5 (Xmem <<SHIFT+(src)→src(6( (Xmem+ (Ymem <<16→dst(7 lk<<SHFT+(src)→dst(8 lk<<16+(src)→dst(9 (src or[dst]+(src)<<SHIFT→dst(10 (src or[dst]+(src)<<ASM→dst5.状态位指令执行受SXM和OVM的影响,指令执行结果影响C和OV 6.说明把一个16位的数加到选定的累加器中,或一个采用双数据存储器操作数寻址的操作数Xmen。
DSP编程技巧之18---不得不看的编译指示编译指示(Pragma Directives)可能是所有的预处理指令中最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。
#pragma指令对编译器给出了如何处理特定的函数、对象和代码段的方法,在保持与C/C++语言完全兼容的情况下,给出主机(比如C28x)或操作系统(比如DSP/BIOS)专有的特征。
这些编译指示的使用较为复杂,但是我们还必须要了解它们,因为它们是程序中必不可少的东西,例如#pragma DATA_SECTION ( symbol , " section name ");这样的。
但是往往讲解它们的资料又不多(因为大部分资料集中在入门指南上面),所以在此我们就总结一下针对C28x编译器的pragma指令,再遇到它们的时候就不会一头雾水了。
本文引用地址:/article/256731.htm1. CHECK_MISRA它的作用与在编译器选项中使用--check_misra是相同的,都是对特定源文件使能MISRA-C:2004规则检查(汽车工业软件可靠性联会),使用方法是:#pragma CHECK_MISRA ("{all|required|advisory|none|rulespec} ");其中的rulespec是具体MISRA中的规则,使用方法请参考DSP编程技巧之12-揭开编译器神秘面纱之代码规范MISRA-C。
2. CLINKCLINK指令可用于某段代码或者某个数据符号,使用之后会在包含被作用符号的段中产生一个.clink指示,表明在条件链接的情况下,如果这个段没有被其它任何段引用的话,这个段可以被移除,从而减小链接输出文件的尺寸。
使用方法是:#pragma CLINK (symbol )3. CODE_ALIGNCODE_ALIGN用来沿着特定的对齐参数constant来对齐函数(从而可以让CPU更快寻址,更快执行指令)。
DSP指令大全(最全)附录6 TMS320C54x 指令系统一览表(按指令功能排列) 一、算术运算指令二、逻辑运算指令三、程序控制指令6.注:?条件―真‖,§条件―假‖,※延迟指令。
四、加载和存储指令4.6.7.五.伪指令2.初始化常数(数据和存储器)的伪指令3.调整段程序计数器伪指令(SPC).align 把SPC调整到页边界.even 把SPC调整到偶数字边界4.控制输出列表格式化伪指令5.条件汇编伪指令.break [well-defined expression] 如果条件真结束.loop汇编,.break结构是可选项.else 如果.if条件为假,汇编代码块.else结构是可选项.elseif well-defined expression——如果if条件为假且.elseif 条件为真,汇编代码块.else结构是可选项.endif 结束.if代码块.endloop 结束.1oop代码块.if well-defined expression 如果条件为真则汇编代码块.loop [well-defined expression] 开始代码块的重复汇编6. 汇编符号.asg [”] character string [”],substitution symbol——把字符串赋予替代的符号..endstruct 结束结构定义.equ 使值和符号相等.eval well-defined expression,substitution symbol 根据数字替代符号完成运算.newblock 取消局部标号.set 使数值和符号相等.struct 开始结构定义.tag 把结构属性赋予标号7.宏指令宏定义:Macname .macro[参数1],[…],[参数n]宏调用:[标号][:] macname [参数1],[…],[参数n]8.编译软件指令①汇编器:asm500.exeasm500[input file[object file [listing file] [-options]]-c—使汇编语言文件中大小没有区别。
DSP编程中使用的预编译指令 #pragma(2008-12-10 10:55:09)转载▼标签:杂谈【原创】转载请注明出处**** TypeWritter: Li Hui*** Start Time: Nov.19.2008*** Version 1.3**** use word to instead 2 * 16bit short data's access ** void vecsum4(short *restrict sum, restrict short *in1, restrict short *in2, unsigned int N){int i;#pragma MUST_ITERATE(10);for(i=0;i<(N/2);i++)_amem4(&sum[i]) =add2(_amem4_const(&in1[i]),_amem4_const(&in2[i])); }** near variable's access **LDW *dp(_address),a1** far variables' access **MVKL _address,a1MVKH _address,a1LDW *a1,a0** far function call **MVKL _func,a1MVKH _func,a1B a1** default is near type **** if you use -mr1 option, all the func are 'far' if you don't use -mr1, default is 'near'if you use -mr0, then all the array or matrix are 'far', program is 'near'if you use -mr1, then all the array or matrix are 'near', program is 'far'if you use -mr2, then all the array, matrix, program are 'far'if you use -mr3, then all data and program are 'far'**** not-related **void foo(int * restrict a, int * restrict b)void foo(int c[restrict], int d[restrict])** difference of const-pointer and point to const**int * const p = &x; ** a const pointer who point to a variable named x **const int * p = &x; ** a pointer who point to a const named x, the pointer can point another variable **** volatile - to guarantee a variable can not be optimized by optimizer **unsigned int *ctrl;while(*ctrl !=0xFF)...** optimizer will treat ctrl a const **** so we should specify the ctrl's type is 'volatile' ** volatile unsigned int * ctrl;** That's ok **** Embedded the assembly language into the .C file **asm(" Assembly Language... ");** Useful Pragma Directive **** (1) CODE_SECTION **** Allocate space for symbol in the section named "section name" **#pragma CODE_SECTION(symbol,"section name"); // in C language** (2) DATA_ALIGN **** align symbol to the column edge specfied by the constant ** #pragma DATA_ALIGN(symbol,constant); // constant must be power of 2eg1:#pragma DATA_ALIGN(inputArray,8);// when you use DSPLIB FFT functions** (3) DATA_MEM_BANK **** align the symbol and variables to the page edge specified by the constant **** avoid the data's overlapped storage **#pragma DATA_MEM_BANK(symbol,constant); ** C64 : constant must be 0-15 and must be even **** (4) DATA_SECTION **** Allocate space for symbol in the section named "section name" **** 4-1 C Language **#pragma DATA_SECTION(symbol,"section name");** 4-2 C++ Language **#pragma DATA_SECTION("section name");** 4-3 Assembly Language **.global _bufferA.bss _bufferA,512,4.global _bufferB_bufferB .usect "section name",512,4** (5) FUNC_CANNOT_INLINE **** this function can not be inline, even the function is defined 'inline' **#pragma FUNC_CANNOT_INLINE(func);** (6) FUNC_EXT_CALLED **** if you add -pm options in the compile period, the compiler will erase the function which haven't beencalled by main, but acturally, the function may be called by .asm file. **#pragma FUNC_EXT_CALLED(func);** restriction: func can not be _c_int00 **** (7) FUNC_INTERRUPT_THRESHOLD **#pragma FUNC_INTERRUPT_THRESHOLD(func,threshold);eg1:#pragma FUNC_INTERRUPT_THRESHOLD(func1,2000);** the period between the func1's interrupts must lager than 2000 clock cycle **eg2:#pragma FUNC_INTERRUPT_THRESHOLD(func2,1);** the func2 can always be interrupted **eg3:#pragma FUNC_INTERRUPT_THRESHOLD(func3,-1);** the func2 can not be interrupted **** (8) FUNC_IS_PURE **** This function has no side-effect, if you do not need the value returned by func, you can delete its' callyou can delete the copy of the func**#pragma FUNC_IS_PURE(func);** (9) FUNC_IS_SYSTEM **** this function has the ANSI standard operation, the directive must be used for ANSI standard function **** for example: memcpy, strcmp and so on **#pragma FUNC_IS_SYSTEM(func);** (10) FUNC_NEVER_RETURNS **** this function never returns, so compiler can not terminate this function or free stack and so on **#pragma FUNC_NEVER_RETURNS(func);** (11) FUNC_NO_GLOBAL_ASG **** this function will not assign global variables and not contains .asm sentences **#pragma FUNC_NO_GLOBAL_ASG(func);** (12) FUNC_NO_IND_ASG **** this function will not allocate space via pointer and not contains .asm sentences **#pragma FUNC_NO_IND_ASG(func);** (13) INTERRUPT **** you can use the function to handle the DSP's interrupt ** #pragma INTERRUPT(func);** (14) MUST_ITERATE **** Specify the cycle's minimum times, maximun times and the times must be multiple of 'multiple' **#pragma MUST_ITERATE(min,max,multiple);** (15) NMI_INTERRUPT **** you can use the function to handle the Non Maskable Interrupt(NMI) **#pragma NMI_INTERRUPT(func);** (16) PROB_ITERATE **** Specify the cycle's minimum times, maximun times **#pragma PROB_ITERATE(min,max);** (17) STRUCT_ALIGN **** Like to DATA_ALIGN, using for defination of struct and class **#pragma STRUCT_ALIGN(type,constact expression);eg:typedef strct st_tag{int a;short b;}st_typedef;#pragma STRUCT_ALIGN(st_tag,128);** (18) UNROLL **** Specify which number of cycle times can not be unfolded ** #pragma UNROLL(n);。