⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perimeter.asm

📁 ADI BF DSP的几种常用的图象滤波汇编优化后的代码
💻 ASM
字号:
/*******************************************************************************
Copyright(c) 2000 - 2002 Analog Devices. All Rights Reserved.
Developed by Joint Development Software Application Team, IPDC, Bangalore, India
for Blackfin DSPs  ( Micro Signal Architecture 1.0 specification).

By using this module you agree to the terms of the Analog Devices License
Agreement for DSP Software. 
********************************************************************************
Module name     : perimeter.asm
Label name      : __perimeter
Version         :   1.3
Change History  :

                Version     Date          Author        Comments
                1.3         11/18/2002    Swarnalatha   Tested with VDSP++ 3.0
                                                        compiler 6.2.2 on 
                                                        ADSP-21535 Rev.0.2
                1.2         11/13/2002    Swarnalatha   Tested with VDSP++ 3.0
                                                        on ADSP-21535 Rev. 0.2
                1.1         01/28/2002    Raghavendra   Modified to match 
                                                        silicon cycle count
                1.0         07/06/2001    Raghavendra   Original 

Description     : This function produces the boundary of a binary image.
                  Detection of boundary is done by examining the neighboring 
                  pixels. The pixels used for calculations are 

                                        p_top
                          p_left     p_boundary     p_right
                                       p_bottom

                   if p_boundary ==1 and any of neighbor pixel under 
                  consideration is zero then output==1
                   else output==0;

                    Equivalent  C code is as follows;

                    if (((p_top==0)|| (p_left==0) || (p_right==0) || 
                        (p_bottom==0) ) & (p_boundary==1))
                       output=1;
                    else 
                       output=0;
                    
                   This is implemented  using a mask  | 0   1   0 |
                                                      | 1   -4  1 |
                                                      | 0   1   0 |
                   and comparing the result for nonzero value. 
                   In output image, first row ,last row ,first column and last 
                   columns are same as input.

Assumption      : Number of columns of input image is even  AND  aligned to 4 
                  byte or 2 byte boundary 
              
Prototype       : void _perimeter(unsigned char* in, int row, int col, 
                                  unsigned char *out );
               
                   in   ->  It is pointer to the input image.
                   row  ->  It is number of rows of input image.
                   col  ->  It is number of columns of input image.
                   out  ->  It is pointer the output buffer.

Registers used  : A0, A1, R0-R3, R5-R7, M0, M1, P0-P5, LC0, LC1.
 
Performance     : 
             Code size      : 180 bytes
             Cycle count    : 433 cycles for 8x8 input image
     first row and last row : 2*col
        Middle row          :
          Inner loop        : 8.5*(Col-2)
          Outer loop        : 9*(Row -2)
*******************************************************************************/
 .section   L1_code;
.global    __perimeter;
.align      8;
    
__perimeter:

    [--SP]=(R7:5,P5:3);
    P4=[SP+36];             // address of output array
    P5=R0;                  // Address of input array
    M0=R0;
    P1=R2;                  // Number of columns
    M1=R2;                  // Number of columns
    P0=R2;
    P3=R2;
    P2=R1;                  // Number of rows
    R7=1;                   // Initialize to 1
    R5.H=-4; 
    R5.L=1;                 // Initialize to mask element
    P3+=-1;
//////////////////// First Row  ///////////////////////////////////////////////

    LSETUP(FIRST_ROW_ST,FIRST_ROW_END)LC0=P1;
FIRST_ROW_ST:
        R0=B[P5++](Z);
                            // fetch input 
FIRST_ROW_END:
        B[P4++]=R0;
                            // store input as output 
    
    P5=M0;                  // Address of input
    R3=R2<<1 ||R0=B[P5++](Z);
                            // fetch first input 
    R3+=-1;                 // 2*col-1
    P1+=-2;                 // Col-2
    P2+=-2;                 // ROW-2;
    P0+=-3;                 // COL-3
    
//////////////// Middle loop ///////////////////////////////////////
    LSETUP(ROW_ST,ROW_END)LC0=P2;
                            // loop counter == ROW-2 (M-2) 
    P2=R3;                  // 2*col
    NOP;
ROW_ST: B[P4++]=R0;
                            // store input as output 
        R0=B[P5++](Z);      // fetch x01
        LSETUP(COL_ST,COL_END)LC1=P1>>1;
                            // loop counter ==(COL-2)/2 
COL_ST:     A1=R0.L * R5.L (IS)||R1=B[P5](z);
                            // A1=x01,fetch x02 
            R2=R1-R1(NS)||R0=W[P5++P1](Z);
                            // clear r2 and increment pointer to next row 
            A0=R1.L * R5.L (IS) || R0=B[P5++](Z);
                            // A1=x02, fetch x10 
            A1+=R0.L * R5.L(IS)||  R0=B[P5++](z);
                            // A1+=x10,fetch x11 
            A1+=R0.L * R5.H,A0+=R0.L * R5.L(IS)||R0=B[P5++](z);
                            // A1+=-4*x11, a0+=x11,fetch x12 
            A1+=R0.L * R5.L,A0+= R0.L *R5.H(IS)||R0=B[P5++](z);
                            // A1+=x12,A0+=-4*x12,fetch x13 
            R3=R1-R1(NS)||R1=W[P5++P0](Z);
                            // clear r3 and increment pointer to next row 
            A0+=R0.L *R5.L(IS) || R0=B[P5++](z);
                            // A0+=x13,fetch x21 
            R1=(A1+=R0.L *R5.L)(IS) || R0=B[P5](Z);
                            //R1= first result, fetch x22 
            CC=R1<0;        // check if r1 <0
            P5-=P2;         // decrement pointer to first row
            R6=(A0+=R0.L*R5.L)(IS)||R0=B[p5++](Z);
                            // A0+=x22 
            IF CC R3=R7;    // if true output ==1
            B[P4++]=R3;     // store first result
            CC=R6<0;        // check for send output
            IF CC R2=R7;    // if true output ==1
COL_END:    B[P4++]=R2;
                            // store second output 
        P5=P5+P3;
        R0=B[P5++](Z);
        B[P4++]=R0;         // store  last element as zero
        R0=B[P5++](Z);      // fetch first element of next row
        P5-=P3;
ROW_END:R1=B[P5--](Z);
                            // dummy fetch to decrement the pointer 
////////////////////  LAST ROW   //////////////////////////////////////////////
    P0=M1;     
    p5=p5+p3;
    LSETUP(LAST_ROW_ST,LAST_ROW_END)LC0=P0;
LAST_ROW_ST:
        R0=B[P5++](z);         
LAST_ROW_END:
        B[P4++]=R0 ;
                            // store last row output as input 
    
    (R7:5,P5:3)=[SP++];     // POP r7-5 and P5-3
    RTS;
    NOP;                    // To avoid one stall if LINK or UNLINK happens to 
                            // be the  next instruction in the memory.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -