a function could be placed in ram by assigning the __ram switch. How to do this for assembler functions?
//********************************************************************* // 32*32 bit signed/unsigned multiply in ARM Assembler // Returns 64 bit result in R0,R1 //********************************************************************* AREA ?C?bla, CODE, READONLY, ALIGN=2 PUBLIC S_MUL32x32?A S_MUL32x32?A PROC CODE32 SMULL R2,R0,R1,R0 ; R0,R2 := R1*R0 mov R1,R2 bx lr ENDP PUBLIC U_MUL32x32?A U_MUL32x32?A PROC CODE32 UMULL R2,R0,R1,R0 ; R0,R2 := R1*R0 mov R1,R2 bx lr ENDP END //*********************************************************************
maybe there is a chance in the red line. i'm not sure i just copied this line from an example-programm...
You need to use the scatterloader and load the whole module into RAM (that is if you are using the RealView compiler, the __ram switch is old)
It will look something like this
RW_IRAM1 0x20000000 0x00010000 { ; RW data assembly.o (+RO) * (+RW +ZI) }
Hello thanks for reply :-) But sorry, i dont use the realview-compiler, i use CARM, this was recommended by the getting-started-guide of my evalution-board.
This is my C-code, but how to tell the compiler, that i want the assembler code to place in ram to get a little speed up. This is just an example to develop the method.
Maybee there are several methods to speed up: __inline attribute __ram attribute __task attribute
#include<ADuC7026.H> #include<STDIO.H> void PLL_init(void); void RS232_init(void); extern unsigned long long U_MUL32x32(unsigned int,unsigned int); extern unsigned long long S_MUL32x32(unsigned int,unsigned int); //*************************************************************************** union xyz { unsigned int i[2]; unsigned long long l; }; //*************************************************************************** int main (void) { PLL_init(); RS232_init(); while(1) { union xyz zz; zz.l=U_MUL32x32(0x88888888,0x22222222); printf("%#.8X ",zz.i[0]); printf("%#.8X\n",zz.i[1]); zz.l=S_MUL32x32(0x88888888,0x22222222); printf("%#.8X ",zz.i[0]); printf("%#.8X\n",zz.i[1]); printf("\nPress a key\n"); scanf("%*c"); } } //*************************************************************************** __inline void RS232_init(void) { GP1CON = 0x011; // Setup tx & rx pins on P1.0 and P1.1 // Start setting up UART at 115200bps COMCON0 = 0x080; // Setting DLAB COMDIV0 = 0x00B; // Setting DIV0 and DIV1 to DL calculated COMDIV1 = 0x000; COMCON0 = 0x007; // Clearing DLAB } //*************************************************************************** __inline void PLL_init(void) { unsigned int n; PLLKEY1=0xAA; PLLCON=0x01; //clear Bit5 OSEL => External 32.768kHz crystal PLLKEY2=0x55; for(n=0;n<1000000;n++){} //wait for PLL run proper } //***************************************************************************
Your Assembler functions as they exist (as I have seen in previous postings), are fully relocatable.
You may copy them to as section of RAM and call them by function pointer. I think they would be 12 bytes long each (if the UMULL/SMULL fit in 32 bits)
u32 UMULL_EXT[3]; u32 SMULL_EXT[3];
typedef unsigned long long (*RAM_MULL_CALL)(u32 a, u32 b);
for (i = 0; i < 3; i++) { UMULL_EXT[i] = ((u32 *) &UMULL_32x32)[i]; SMULL_EXT[i] = ((u32 *) &SMULL_32x32)[i]; }
to call
zz = ((RAM_MULL_CALL) &UMULL_EXT)(number1, number2); zz = ((RAM_MULL_CALL) &SMULL_EXT)(number1, number2);