dsp浮点数运算程序(精)
DSP中浮点转定点运算--举例及编程中的心得

DSP中浮点转定点运算--举例及编程中的⼼得5.举例及编程中的⼼得5.1举例 “第3章 DSP芯⽚的定点运算.doc”这篇⽂章中给了⼀个很简单有能说明问题的例⼦,不想动⼤脑了,直接引⽤过来如下。
这是⼀个对语⾳信号(0.3kHz~3.4kHz)进⾏低通滤波的C语⾔程序,低通滤波的截⽌频率为800Hz,滤波器采⽤19点的有限冲击响应FIR滤波。
语⾳信号的采样频率为8kHz,每个语⾳样值按16位整型数存放在insp.dat⽂件中。
例3.7 语⾳信号800Hz 19点FIR低通滤波C语⾔浮点程序复制代码代码如下:#include <stdio.h>const int length = 180 /*语⾳帧长为180点=22.5ms@8kHz采样*/void filter(int xin[ ],int xout[ ],int n,float h[ ]); /*滤波⼦程序说明*//*19点滤波器系数*/static float h[19]={0.01218354,-0.009012882,-0.02881839,-0.04743239,-0.04584568,-0.008692503,0.06446265,0.1544655,0.2289794,0.257883,0.2289794,0.1544655,0.06446265,-0.008692503,-0.04584568,-0.04743239,-0.02881839,-0.009012882,0.01218354};static int x1[length+20];/*低通滤波浮点⼦程序*/void filter(int xin[ ],int xout[ ],int n,float h[ ]){int i,j;float sum;for(i=0;i<length;i++) x1[n+i-1]=xin[i];for (i=0;i<length;i++){sum=0.0;for(j=0;j<n;j++) sum+=h[j]*x1[i-j+n-1];xout[i]=(int)sum;}for(i=0;i<(n-1);i++) x1[n-i-2]=xin[length-1-i];}/*主程序*/void main( ){FILE *fp1,*fp2;int frame,indata[length],outdata[length];fp1=fopen(insp.dat,"rb"); /*输⼊语⾳⽂件*/fp2=fopen(outsp.dat,"wb"); /*滤波后语⾳⽂件*/frame=0;while(feof(fp1)==0){frame++;printf("frame=%d/n",frame);for(i=0;i<length;i++) indata[i]=getw(fp1); /*取⼀帧语⾳数据*/filter(indata,outdata,19,h); /*调⽤低通滤波⼦程序*/for(i=0;i<length;i++) putw(outdata[i],fp2); /*将滤波后的样值写⼊⽂件*/}fcloseall( ); /*关闭⽂件*/return(0);}例3.8 语⾳信号800Hz 19点FIR低通滤波C语⾔定点程序复制代码代码如下:#include <stdio.h>const int length=180;void filter(int xin[ ],int xout[ ],int n,int h[ ]);static int h[19]={399,-296,-945,-1555,-1503,-285,2112,5061,7503,8450,7503,5061,2112,-285,-1503,-1555,-945,-296,399}; /*Q15*/static int x1[length+20];/*低通滤波定点⼦程序*/void filter(int xin[ ],int xout[ ],int n,int h[ ]){int i,j;long sum;for(i=0;i<length;i++) x1[n+i-1]=xin[i];for (i=0;i<length;i++){sum=0;for(j=0;j<n;j++) sum+=(long)h[j]*x1[i-j+n-1];xout[i]=sum>>15;}for(i=0;i<(n-1);i++) x1[n-i-2]=xin[length-i-1];}主程序与浮点的完全⼀样。
FFT浮点的DSP实现精

1前言DSP结构可以分为定点和浮点型两种。
其中,定点型DSP可以实现整数、小数和特定的指数运算,它具有运算速度快、占用资源少、成本低等特点;灵活地使用定点型DSP进行浮点运算能够提高运算的效率。
目前对定点DSP结构支持下的浮点需求也在不断增长,主要原因是:实现算法的代码往往是采用C/C++编写,如果其中有标准型的浮点数据处理,又必须采用定点DSP器件,那么就需要将浮点算法转换成定点格式进行运算。
同时,定点DSP结构下的浮点运算有很强的可行性,因为C语言和汇编语言分别具有可移植性强和运算效率高的特点,因此在定点DSP中结合C语言和汇编语言的混合编程技术将大大提高编程的灵活度,以及运算速度。
大多数DSP的开发工具只是在C语言的基础上支持标准的浮点运算,而定点DSP硬件一般都是面向定点的运算,不支持标准的浮点运算,缺乏硬件的支持极大地限制了浮点的应用,因而标准的浮点运算在实际定点DSP应用中并不多见。
C5509是一款16位定点DSP。
在本文中,对C5509输入FTSK信号,用C语言和汇编语言混合编程的方式对输入浮点型的FTSK信号进行相关运算,并输出浮点运算结果。
这里叶变换(FFT是一种高效实现离散傅里叶变换(DFT的快速算法,是数字信号处理中最为重要的工具之一,它在声学,语音,电信和信号处理等领域有着广泛的应用。
2方案设计2.1方案的提出DSP (数字信号处理器与一般的微处理器相比有很大的区别,它所特有的系统结构、指令集合、数据流程方式为解决复杂的数字信号处理问题提供了便利本文选用TMS320C54X作为DSP处理芯片通过对其编程来实现FFT的浮点DSP 实现。
DSP应用系统设计的一般流程如下图所示:■<又热纯tff毎術杯实碣W汎砺九I,山ft也刖FF机来址詞试仃1*1能测试图2.1 DSP系统流程图2.2方案的论证旋转因子W N有如下的特性。
对称性:/2 k k N N N W W +=-周期性:kW W +=利用这些特性,既可以使DFT中有些项合并,减少了乘法积项,又可以将长序列的DFT分解成几个短序列的DFT。
关于dsp中程序定点数和浮点数转换问题(Q15格式)

关于dsp中程序定点数和浮点数转换问题(Q15格式)看ti的逆变器程序,看到采集后的ADBUF数据全部都是《5,这就搞不明白了,为什么要左移5呀?然后看到上面说是兼容Q15,在QQ群里也问了高手,说是用于DSP小数运算,于是在网上找了下Q15的定义,下面把Q15整理下。
许多DSP都是定点DSP,处理定点数据会相当快,但是处理浮点数据就会非常慢。
可以利用Q格式进行浮点数据到定点的转化,节约CPU时间。
实际应用中,浮点运算大都时候都是既有整数部分,也有小数部分的。
所以要选择一个适当的定标格式才能更好的处理运算。
Q格式表示为:Qm.n,表示数据用m比特表示整数部分,n比特表示小数部分,共需要m+n+1位来表示这个数据,多余的一位用作符合位。
假设小数点在n位的左边(从右向左数),从而确定小数的精度例如Q15表示小数部分有15位,一个short型数据,占2个字节,最高位是符号位,后面15位是小数位,就假设小数点在第15位左边,表示的范围是:-1<X<0.9999695 。
浮点数据转化为Q15,将数据乘以2^15;Q15数据转化为浮点数据,将数据除以2^15。
例如:假设数据存储空间为2个字节,0.333×2^15=10911=0x2A9F,0.333的所有运算就可以用0x2A9F 表示,同理10911×2^(-15)=0.332977294921875,可以看出浮点数据通过Q格式转化后是有误差的。
例:两个小数相乘,0.333*0.414=0.1378620.333*2^15=10911=0x2A9F,0.414*2^15=13565=0x34FDshort a = 0x2A9F;short b = 0x34FD;short c = a * b >> 15; //两个Q15格式的数据相乘后为Q30格式数据,因此为了得到Q15的数据结果需要右移15位这样c的结果是0x11A4=0001000110100100,这个数据同样是Q15格式的,它的小数点假设在第15位左边,即为0.001000110100100=0.1378173828125...和实际结果0.137862差距不大。
DSP编程技巧之22详解浮点运算的定点编程

DSP编程技巧之22详解浮点运算的定点编程我们使用的处理器一般情况下,要么直接支持硬件的浮点运算,比如某些带有FPU的器件,要么就只支持定点运算,此时对浮点数的处理需要通过编译器来完成。
在支持硬件浮点处理的器件上,对浮点运算的编程最快捷的方法就是直接使用浮点类型,比如单精度的float来完成。
但是在很多情况下,限于成本、物料等因素,可供我们使用的只有一个定点处理器时,直接使用float类型进行浮点类型的运算会使得编译器产生大量的代码来完成一段看起来十分简单的浮点数学运算,造成的后果是程序的执行时间显著加长,且其占用的资源量也会成倍地增加,这就涉及到了如何在定点处理器上对浮点运算进行高效处理的问题。
本文引用地址:/article/263475.htm 既然是定点处理器,那么其对定点数,或者说字面意义上的“整数”进行处理的效率就会比它处理浮点类型的运算要高的多。
所以在定点处理器上,我们使用定点的整数来代表一个浮点数,并规定整数位数和小数位数,从而方便地对定点数和浮点数进行转换。
以一个32位的定点数为例,假设转换因子为Q,即32位中小数的位数为Q,整数位数则为31-Q(有符号数的情况),则定点数与浮点数的换算关系为:定点数=浮点数×2^Q例如,浮点数-2.0转换到Q为30的定点数时,结果为:定点数=-2×2^30=-2147483648 32位有符号数的表示范围是:-2147483648到2147483647。
如果我们把有符号定点数的最大值2147483647转换为Q为30对应的浮点数,则结果为:浮点数2147483647/2^30=1.999999999 从上面的两个计算例子中也可以看出,在Q30格式的情况下,最大的浮点数只能表示到1.999999999,如果我们想把浮点数2.0转换为Q30的定点数,则产生了溢出,即造成了1e-9的截断误差。
在此我们列出Q0到Q30对应的范围和分辨率如下表所示:如果你嫌自己计算麻烦的话,可以借助Matlab的命令来求取它们的转换,例如,在Matlab的命令窗口中输入:q = quantizer('fixed', 'ceil', 'saturate', [32 30]);FixedNum=bin2dec(num2bin(q,1.999999999)); 回车之后就可以看到1.999999999转成Q30之后的定点数了。
Q格式_dsp定点和浮点数学运算规则

Q格式有符号数的表示法,机器数(出现在电脑的二进位数值)有3个特点,无符号或符号转换成数值来表示,没有+10101这样的资料,而是以010101来表示,只表示单纯的整数或小数,小数点的位置预设在一定的位置而较少变动,它的长度受到电脑硬体的限制,而不能无限增长。
Q格式,就是将一个小数放大若干倍后,用整数来表示小数。
Q格式前提无符号数:当参与运算的数值没有负数且运算的结果也没有负数时,则所有字元都可以表示数值,这种没有符号的数,称为无符号数(如记忆体储存位址),有符号数:数值中有某位数值代表符号,通常最高位作为符号位,0代表正,1代表负。
真值:有符号数所代表的数值,例如:110所代表的值是-2 而非6,有符号数只要去除符号位就可以获得该数的大小,在运算时,它的符号位可参与运算。
但在加减运算时,必须将它分离出来,才能进行运算。
有时,还要确定哪个有符号数的真值比较大,才能确定结果的符号。
为了达到这些功能,电路的设计就相当复杂。
所以很多电脑系统不直接使用有符号数,而使用有符号数的1’s补数或2’s补数表示法作为编码系统正弦脉波宽度调变(SPWM)之控制方法经Q 格式乘法器转换成振幅与频率可变V/F 控制,当成其单相感应马达的输入信号,藉由控制责任周期的大小,以达到变电压相对改变频率的效果。
DSP1.实现数位系统的第一步在自然世界中,所有的物理量包括时间、电压、质量、位移等等,都是类比的、连续的。
可是在数位系统中,讯号是在不连续的时间点取样,物理量或讯号的大小也不再是连续,而是被量化(Quantized)。
在数位系统中,只能用有限字元长度的数字去表示数量的大小,而不能以无限精确的数值(实数)去表示。
为了实现数位系统;使用了定数数与浮点数的表示法。
a)定点数(Fixed Point Number):指一个数字的表示,其小数点是在固定的位置(位元)。
b)浮点数(Floating Point Number):使用假数以及指数两部分来表示数值。
DSP学习笔记(二)——DSP中浮点数与定点数格式与运算处理

DSP学习笔记(⼆)——DSP中浮点数与定点数格式与运算处理DSP学习笔记(⼆)——DSP中浮点数与定点数格式与处理1 DSP中的数据表述DSP中数据通常是有定点数与表⽰,其中可以对字长进⾏相关定义,可以选取字长为16位、24位、32位不同字长使⽤。
⽽格式与字长决定了数据的精度与动态范围,同时也⼀定程度上决定了DSP处理器的功耗、成本与编程难度。
定点数:⼩数点位置为确定的。
浮点数:⼩数点位置可以改变。
定点运算的硬件实现较为简单,功耗较⼩,主要注意的是数据的定标、溢出以及误差。
器减结构较为复杂,但是精度较⾼,⾼级语⾔容易⽀持。
2 定点数的格式与相关运算2.1 定点数格式定点数格式:Q n 格式,n为⼩数位数。
即Q15 ,⼩数点右边有15个⼩数位,如果我们定义了⼀个长度为32位的数字,那么⼩数位为15,1位符号位,16位为整数位。
整数⼩数点固定在最后,定点数⼩数位固定使⽤上⽂的Q n 格式表⽰,两者都使⽤⼆进制补码形式表⽰。
例: Q4格式:01010011b=1·22+1·20+1·2-3+1·2-4=83/24=5.1875对于负数(最⾼位MSB为1),要先把它转化为⽆符号⼆进制数,再进⾏计算,最后加上负号。
图2-1 ⼆进制Q格式表⽰定点数与浮点数转化时需要使⽤2n 的关系进⾏转化。
转化关系如下图:图2-2 定点数与浮点数转化关系浮点数转换为定点数时,由于⼩数点后的位数有限,会产⽣截断误差。
2.2 数值范围与精度Qn 格式,字长为N数值范围: -2N-12n~2N-1-12n精度:12n由于符号位占1位,所以数据位为N-1,n越⼤范围越⼩,但精度越⾼。
图2-3 数值范围与精度2.3 动态范围数据格式中最⼤值与最⼩值之⽐即为动态范围。
N位定点数动态范围:分贝表⽰:dsp⼤多采⽤16位定点数,动态范围为90.3db。
Dsp⼤多采⽤16为定点数,运算硬件实现较为简单,更⼤动态范围应⽤可以使⽤拓展字长⽅式。
定点 DSP 处理浮点数

定点DSP处理浮点数BG6RDFTMS320C5509A是16位定点数处理器,其累加器是32位/40位的。
在定点处理器中处理浮点数需要对定点数进行定标。
下面所说的定点数都是指有符号数。
通常采用的定标有Q15和Q31,分别表示小数点后有二进制15位和二进制16位。
因此16位Q15最大能表示的数是1 2 ,32位Q31最大能表示的数是1 2 。
定标不同的数可以直接相乘,例如Q13*Q15=Q28。
两个定标不同的数不能直接相加,比如Q13+Q15,通常要将Q15右移两位,转换为Q13后再相加,当然这样损失了两位的精度。
DSP进行的乘累加操作常常Q15的数,这样结果为Q30,存储在累加器中。
为了将累加器的结果转换为更为常用的Q31定标,55x系列DSP在状态寄存器ST1_55中设置了FRCT 控制位,FRCT=1时,乘积自动左移一位,这样乘积变成了Q31。
对于累加器中Q31定标的数,直接取累加器中高16位,就能获得结果的Q15定标数。
很多时候Q15不能解决问题,比如IIR滤波器num, den系数中通常有大于等于1的系数,超过了Q15的范围,只能用Q14,Q13等定标。
这时乘累加操作就需要进行修正了,比如IIR滤波器中系数用Qx定标,输入数据和输出数据用Qy定标,Q Q Q ,为获得Qy的输出数据必须将累加器中的乘积右移x位,另外在乘累加操作开始前必须将输入数据在累加器中左移y位,进行对齐后才能进行乘累加。
当然,这种修正都是在没有考虑FRCT 的情况下。
在C5500 DSPLIB中iircas51函数中,FRCT设置为1,输入输出数据采用Q15定标,如果系数也是Q15定标,则程序运行无误,如果系数采用Q14及以下定标则会产生严重的问题。
以下是其代码片段:MOV *AR0+ << #16, AC1 ; HI(AC1) = x(n)||RPTBLOCAL loop2‐1 ;inner loop: process a bi‐quadMPYM *AR1+, AC1, AC0 ; AC0 = b0*x(n)MACM *AR1+, *(AR3+T0), AC0 ; AC0 += b1*x(n‐1)MACM *AR1+, *AR3, AC0 ; AC0 += b2*x(n‐2)MOV HI(AC1), *AR3 ; x(n) replaces x(n‐2)||AADD T1, AR3 ; point to next x(n‐1)MASM *AR1+, *(AR4+T0), AC0 ; AC0 ‐= a0*y(n‐1)MASM *AR1+, *AR4, AC0 ; AC0 ‐= a1*y(n‐2)MOV rnd(HI(AC0)), *AR4 ; y(n) replaces y(n‐2)||AADD T1, AR4 ;point to next y(n‐1)MOV AC0, AC1 ;input to next biquad从代码片段可以看出,累加器AC0为Q31定标,输出数据是累加器高16位。
DSP-定点和浮点数格式解析

① 小数乘小数(n、m≠0,m≤ n) ② 整数乘小数(n≠0、m=0) ③ 整数乘整数(n=m=0)
① 小数乘小数(n、m≠0,m≤ n)
例:两个8位数相加,有溢出 进位位与最高位(MSB)不同 运算结果发生溢出,8位字长已不能正确地表示结果
10110000b( -80) + 10111111b( -65) 非饱和模式:101101111bቤተ መጻሕፍቲ ባይዱ-145)
00101001b( 41) + 01110011b(115) 非饱和模式:010011100b(156)
2)数值范围与精度
给定字长N,采用Qn格式表示小数
2 N 1 2 N 1 1 数值范围: n ~ 2 2n
精
度:
1
2n
16位字长Qn格式的数值范围与精度
Qn格式 Q15 数值范围 -1~0.999969482421875 精度 0.000030517578125
Q14
饱和模式:110000000b(-128)
饱和模式:001111111b(127)
溢出是由于字长有限,运算结果超出数值的表示范围引 起的
饱和模式
定点数减法运算的原理与加法运算相同
2)定点数的乘法运算
DSP处理器都有硬件乘法器和乘法指令,可实现单周期乘 法运算 二进制乘法运算包含一系列的移位和加法运算 定点数乘法运算不要求相乘数有相同的Qn格式 两个相乘数分别为Qn和Qm格式,字长为N,结果为 Q(n+m)格式,字长为2N 根据n和m的不同取值,定点数乘法运算可以分成三种情况
DSP 运算基础
• 1、 DSP的数据表示
• 2、定点数的格式与运算 • 3、浮点数的格式与运算
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
;/*=============================================================== =============*/;/* Copyright (C 2004 YINXING TECHNOLOGY CO., LTD */;/* All Rights Reserved. */;/* ----------------------------------------------------------------------------*/;/*=============================================================== =============*/;---------------------------------------------------------------;; USER Program Demo !; It Start At 0x1800,and interrupt vector don't changed,; At 200h !;; Please Don't modify PMST !;; Some data put in 080h DP=1; SP may use system stack,so user needn't setup SP !;;------------------------------------------------------------------.title "for test user program ... ".mmregs.global _c_int00.ref fs_start,errnoop1valh .set 4140h ;floating point number 12.0op1vall .set 0000hop2valh .set 4140h ;floating point number 12.0op2vall .set 0000hinitst0 .set 1800h ;set st0 initial numberinitst1 .set 2900h ;set st1 initial number.bss rlthm,1 ;result high mantissa,address is 80h .bss rltlm,1 ;result low mantissa,address is 81h.bss rltsign,1 ;ressult sigh,address is 82h.bss rltexp,1 ;result exponent,address is 83h.bss op1hm,1 ;op1 high mantissa,address is 84h.bss op1lm,1 ;op1 low mantissa,address is 85h.bss op1se,1 ;op1 sigh and exp,address is 86h.bss op2se,1 ;op2 sigh and exponent,address is 87h .bss op2hm,1 ;op2 high mantissa,address is 88h.bss op2lm,1 ;op2 low mantissa,address is 89h.bss op1_hsw,1 ;op1 packed high,address is 8ah .bss op1_lsw,1 ;op1 packed low,address is 8bh.bss op2_hsw,1 ;op2 packed high,address is 8ch .bss op2_lsw,1 ;op2 packed low,address is 8dh_c_int00:stm #initst0,st0stm #initst1,st1rsbx C16ld #op1lm,dpld #op1valh,a ;load float numberstl a,op1_hswld #op1vall,astl a,op1_lswld #op2valh,a ;load float numberstl a,op2_hswld #op2vall,astl a,op2_lswnopnopnop ;1st breakpoint in CCS!;----------- conversion of floating point format - unpack ------- dld op1_hsw,a ;load OP1 to acc asfta a,8sfta a,-8bc op1_zero,AEQ ;if op1 is 0,jump to special casesth a,-7,op1se ;store sign and exponent to stackstl a,op1lm ;store low mantissaand #07Fh,16,a ;mask off sign and exp to get high mantissa add #080h,16,a ;add implied 1 to mantissasth a,op1hm ;store mantissa to stackdld op2_hsw,a ;load OP2 to acc asfta a,8sfta a,-8bc op2_zero,AEQ ;if op2 is 0,jump to special casesth a,-7,op2se ;store sign and exponent to stackstl a,op2lm ;store low mantissaand #07Fh,16,a ;mask off sign and exp to get high mantissa add #080h,16,a ;add implied 1 to mantissasth a,op2hm ;store mantissa to stacknopnopnop ;2nd breakpoint in CCS !;---------- judge the sign----------------bitf op1se,#100h ;test the sign bitbc testop2,NTC ;if is not negative jump to testop2ld #0,a ;change the experssion todsub op1hm,adst a,op1hm ;store changed op1testop2:bitf op2se,#100h ;test the sign bitbc compexp,NTC ;if is not negative jump to compexpld #0,a ;change the expression todsub op2hm,adst a,op2hm ;store changed op2;--------- Exponent Comparison ------------compexp:ld op1se,aand #00ffh,a ;mask off the sign bitld op2se,band #00ffh,b ;mask off the sign bitsub a,b ;exp op2-exp op1 -> bbc op1_gt_op2,BLT ;process op1 > op2bc op2_gt_op1,BGT ;process op2 > op1a_eq_bdld op1hm,adadd op2hm,a ;add mantissabc res_zero,AEQ ;if result is zero process special caseld op1se,b ;load exponent in preparation for normalizing normalizesth a,rltsign ;Save signed mantissa on stackabs a ;Create magnitude value of mantissasftl a,6 ;Pre–normalize adjustment of mantissaexp a ;Get amount to adjust exp for normalizationnorm a ;Normalize the resultst t,rltexp ;Store exp adjustment valueadd #1,b ;Increment exp to account for implied carrysub rltexp,b ;Adjust exponent to account for normalization normalizedstl b,rltexp ;Save result exponent on stackbc underflow,BLEQ ;process underflow if occurssub #0ffh,b ;adjust to check for overflowbc overflow,BGEQ ;process overflow if occurssftl a,-7 ;Shift right to place mantissa for splittingstl a,rltlm ;Store low mantissaand #07f00h,8,a ;Eliminate implied onesth a,rlthm ;Save result mantissa on stack;----------- Conversion of Floating Point Format- Pack --------- ld rltsign,9,aand #100h,16,a ;Get the sign valueadd rltexp,16,a ;Add the result exponent togethersftl a,7 ;shift the value to right placedadd rlthm,a ;Add the result mantissa togetherreturn_valuenopnopnopnop ; 3th breakpoint in CCS !b fs_startop1_gt_op2abs b ;if exp OP1 >= exp OP2 + 24 then return OP1sub #24,bbc return_op1,BGEQadd #23,b ;restore exponent difference valuestl b,rltsign ;store exponent difference to be used as RPCdld op2hm,a ;load OP2 mantissarpt rltsign ;normalize OP2 to match OP1sfta a,-1bd normalize ;delayed branch to normalize resultld op1se,b ;load exponentvalue to prep for normalization dadd op1hm,a ;add OP1 to OP2op2_gt_op1sub #24,b ;if exp OP2 >= exp OP1 + 24 then return OP1 bc return_op2,BGEQadd #23,b ;Restore exponent difference valuestl b,rltsign ;Store exponent difference to be used as RPC dld op1hm,a ;Load OP1 mantissarpt rltsign ;Normalize OP1 to match OP2sfta a,-1bd normalize ;Delayed branch to normalize resultld op2se,b ;Load exponent value to prep for normalization dadd op2hm,a ;Add OP2 to OP1op1_zero:return_op2:bd return_valuedld op2_hsw,a ;Put OP2 as result into Aop2_zero:return_op1:dld op1hm,a ;Load signed high mantissa of OP1bc op1_pos,AGT ;If mantissa is negative .neg a ;Negate it to make it a positive valueaddm #100h,op1se ;Place the sign value back into op1_se op1_possub #80h,16,a ;Eliminate implied one from mantissald op1se,16,b ;Put OP1 back together in acc A as a result bd return_valuesftl b,7add b,aoverflowst #2,errno ;load error nold rltsign,16,a ;pack sign of result and #8000,16,aor #0ffffh,a ;result low mantissa bd return_valueadd #07f7fh,16,a ;result exponent underflowst #1,errno ;load error nob return_valueres_zerobd return_valuesub a,anop。