Christian Becker

Coldfire V1+ Inline Assembly (MCF51QM) for EMAC in Codewarrior V10.4

Discussion created by Christian Becker on Aug 6, 2013
Latest reply on Aug 6, 2013 by Jim Donelson

Hi everyone,


I´m trying to implement a assembly function which uses the EMAC Unit to multply over 2 32-bit Fields. I`ve started with a marcro described in CFLMOPM (EMAC / MAC Library) but it didnt work out of the box.

So I rewrite this macro to a Statement-level inline assembly according to Statement-level in MCU_Coldfire_Compiler.pdf.


Unfortunately after calling the function the cpu traps in ISR(Cpu_ivViinstr).


My question is: Do I  maybe have to save and restore registers I`ve used in this inline assembly function? And if yes, how can I do this?


The original source was:

/* Save registers */\

        lea -60(a7),a7          

       movem.l d0-d7/a0-a5,(a7) 


and at the end


/* Restore registers */  \

     movem.l (a7),d0-d7/a0-a5 

     lea 60(a7),a7    


But I guess this won`t work anymore becaus of the register abi calling convention?!


Ive also tried different settings in coldfire compiler - processor -properties but it didnt help




Another question: Do I need the "rts" statement at the end?




Here`s my source code



void emac_mul (unsigned long * d,    unsigned long * s2,    unsigned long *s1, unsigned long n)


     asm {


              /* Initialize MACSR register for unsigned operations */

            move.l #0x40,d0            ;

            move.l d0,MACSR            ;

            moveq.l %16,d0            ;

            /* Load function variables */

            move.l d,a0            ;

            move.l s1,a1            ;

            move.l s2,a2            ;

            move.l n,d1            ;

            /* Load counter */

            move.l d1,d2            ;

            /* Load in d1 number of 4 operations */

            asr.l %2,d1            ;

            beq *+72            ;

            /* Initialize eMAC accumulators */

            move.l #0,ACC0            ;

            move.l #0,ACC1            ;

            move.l #0,ACC2            ;

            move.l #0,ACC3            ;

            /* Perform 4 by 4 operations as MUL */

            movem.l (a1),d7/a3-a5        ;

            add.l d0,a1            ;

            movem.l (a2),d3-d6        ;

            macl.l d7,d3,(a1)+,d7,ACC0    ;

            macl.l a3,d4,(a1)+,a3,ACC1    ;

            macl.l a4,d5,(a1)+,a4,ACC2    ;

            macl.l a5,d6,(a1)+,a5,ACC3    ;

            /* Store results and clear accumulators */

            movclr.l ACC0,d3        ;

            movclr.l ACC1,d4        ;

            movclr.l ACC2,d5        ;

            movclr.l ACC3,d6        ;

            movem.l d3-d6,(a0)        ;

            add.l d0,a2            ;

            add.l d0,a0            ;

            subq.l %1,d1            ;

            bne *-38            ;

            /* Load in d2 number of operations Left */

            and.l %3,d2            ;

            beq *+16            ;

            sub.l d0,a1            ;

            /* Perform last operations as MUL */

            move.l (a6)+,d3            ;

            mulu.l (a1)+,d3            ;

            move.l d3,(a0)+            ;

            subq.l %1,d2            ;

            bne *-10            ;

            rts            ;





Maybe anyone has an idea or there`s a little hint to get this working.


Thanks for help