📄 perimeter.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 + -