Analog Devices EE128 Application Notes

a
a
aa
Phone: (800) ANALOG-D, FAX: (781) 461-3010, EMAIL: dsp.support@analog.com, FTP: ftp.analog.com, WEB: www.analog.com/dsp
Engineer To Engineer Note EE-128
Technical Notes on using Analog Devices’ DSP components and development tools
compiler where it modifies the name of a
DSP in C++ : Calling Assembly Class Member Functions From C++
member function to include information about its input and output parameters. There are a number of reasons why this happens but the primary reason is so the compiler can differentiate between different member
Submitted by DL 12/2000
When using a high-level language (i.e. C or C++) to develop DSP code, it is often desirable to hand-code time-critical sections in assembly code to achieve optimal performance. These assembly routines, however, must be callable from that higher-level language. When developing with C, this is a straightforward process (see the VisualDSP++ C Compiler Guide, page 2-58), but in C++, where we now have to deal with things like inheritance and name-mangling, it becomes much more complex from an assembly standpoint.
This application note presents a basic scheme to preserve the simplicity of performing standard C calls from a C++ environment.
The material requires a basic understanding of the C++ language and an object-oriented programming environment. For some good resources, see the References Section at the end of this application note.
How is the class information passed to class functions?
There are two major challenges that one meets when trying to write C++ callable assembly code, or more specifically, when one tries to write a member function in assembly.
The first problem is name mangling. Name
functions with the same name. Member functions of a class may have the same name as long as the parameters they take are different. For example, in the class listing below, there are two constructors with the same name. The compiler will append a text string to the labels of each constructor to represent the parameters they take.
class cDelay { public: float * Buffer; float * Ptr; int Length; float Input, Output;
Delay( float input ); Delay( ); }
A function called Delay from the class cDelay, which takes a single float as a parameter and returns a single float, will receive the following label from the compiler:
_Delay__9cDelay_STq2dmFv
Hence the mangled names... The problem here is that unless you have some software to mangle your names for you, it is extremely tedious to manually determine what a mangled name is going to be based on its parameters. If you wish to interface a function to assembly, you must know what this mangled name will be. As we will see further on, there is a nice way to bypass this whole process.
mangling is an operation performed by the C++
Copyright 2001, Analog Devices, Inc. All rights reserved. Analog Devices assumes no responsibility for customer product design or the use or application of customers’ prod ucts or for any infringements of patents or rights of others which may result from Analog Devices assistance. All trademarks and logos are property of their respective holders. Information furnished by Analog Devices Applications and Development Tools Engineers is believed to be accurate and reliable, however no responsibility is as sumed by Analog Devices regarding the technical accuracy of the content provided in all Analog Devices’ Engineer-to-Engineer Notes.
Now that we understand that name mangling is something we want to avoid, if possible, let’s address the second issue : how do we access the information in an instance of a class from a member function of that class. When a
function is called in C++, the first argument passed is the this pointer, or rather, the pointer to the top of the class structure. This
passage is transparent to the programmer (unless, of course, the programmer is trying to program an assembly language function, which we’ll get to soon).
In order to review how function parameters are passed, we will first start with a C example. When a C function is called, the parameters are passed as follows:
1st parameter - R4 register 2nd parameter - R8 register 3rd parameter - R12 register 4th parameter - 1st location of stack 5th parameter - 2nd location of stack
For example, say we have a C function called add whose prototype might look something like this :
float add( float x, float y);
When we call Add, the x parameter is placed in the R4 register and the y parameter is placed in the R8 register.
From a C++ member function, the parameter passing is slightly different. Instead of the first parameter being passed in the R4 register, the this pointer is passed in the R4 register and any other parameters are passed in the same fashion as is true for C, starting in the R8 register :
this (ptr to instance) R4 register 1st parameter - R8 register
2nd parameter - R12 register 3rd parameter - 1st location of stack 4th parameter - 2nd location of stack
Let’s start with the following class as an example. In this example, the Add function will add a real and an imaginary component to its own Real and Imag variables. It will then return the real sum.
Cplx_float.h
Class Complex_Float { private : float Real, Imag; public : Complex_Float(); // constructors Complex_Float( float real, float imag ); float Add( float real, float imag ); };
If we declared a new instance of a Complex_Float and called the Add function, the parameters would be passed as follows :
R4 - pointer to the current instance of
Complex_Float R8 - real parameter R12 - imag parameter
For both C and C++, the return argument of a function is always placed in the R0 register.
Now suppose we wanted to hand-code the complex Add routine that we just defined in assembly code.
Add_.asm
#include <asm_sprt.h> .segment /pm seg_pmco;
// function name is arbitrary
_AsmAdd: .global _AsmAdd;
// r4 contains a pointer to the // instance
i4 = r4;
EE-128 Page 2
Technical Notes on using Analog Devices’ DSP components and development tools
Phone: (800) ANALOG-D, FAX: (781)461-3010, EMAIL: dsp.support@analog.com, FTP: ftp.analog.com, WEB: www.analog.com/dsp
Loading...
+ 3 hidden pages