The 68EZ328 indeed supports a mulu instruction, but you'll notice it is a
16x16 operation. In other words, a mulu.S. You were trying to use a mulu.L,
which is not supported by the EC000 core.

Your original callback uses a global value to locate the multiply code
[move.l [EMAIL PROTECTED](%a5),%a0]. It is found relative to the A5 register,
which is reserved as the globals context register. If the A5 register is not
correct when CallbackPeckAudio() is called, you will not be able to
correctly locate the desired global value. In other words, the calling code
may have it's own globals context, which could mean that the value of A5 has
been changed to meet the calling code's needs, and is wrong for your needs.

If this is the case, you should either 1) not refer to globals in your
callback, or 2) pass your A5 value to the callback and use SysSetA5() to
temporarily set A5 for your use.

This is all best accomplished by creating a structure containing everything
needed by the callback, and then passing the address of the structure to the
callback as a userdata pointer. The structure could contain your own A5
value, giving you full access to your normal globals, or it could contain
everything needed without globals, or some combination.

You already do the structure bit with "struct PeckAudioType". You could
either add your A5 value to the structure, or add a reference to the global
in the structure. Whatever works best for you.

If you'd like info on a (32x32).L, that's another email.

Sorry so long winded.

--------------------
Jeff Loucks
Work 425-284-1128 [EMAIL PROTECTED]
Home 253-851-8908 [EMAIL PROTECTED]
Mobile 253-691-8812


-----Original Message-----
From: Greg Sepesi [mailto:[EMAIL PROTECTED] 
Sent: Tuesday, April 05, 2005 12:10 PM
To: Palm Developer Forum
Subject: fatal exception from multiplication in gcc compiled callback


I'd like to implement a UInt32 x UInt32 multiply (discarding the most
significant 32 bits of result) in a callback for a sound stream, but the
multiplication is causing a fatal exception (on a Zire 31).  From 
looking at the assembly language produced by gcc, the reason for the 
exception appears to be the attempted use of a global (not available in 
callback). 

Here's the applicable data structure and code:

typedef struct PeckAudioType {
   SndStreamRef streamRef;
   UInt32 fileSize;
   UInt32 fileOffset;
   FileRef fileRef;
   UInt32 bufferCount;

   UInt32 s;
   UInt32 a;
   UInt32 b;
} PeckAudioType;

Err CallbackPeckAudio(void *pUserData, 
   SndStreamRef stream, 
   void *bufferP, 
   UInt32 frameCount) 
{
   PeckAudioType *pPeckAudio = (PeckAudioType *)pUserData;
   Err err;

   /* Read next sound stream buffer from file. */
   err = VFSFileRead(pPeckAudio->fileRef, frameCount*2, bufferP, NULL);

   pPeckAudio->a *= pPeckAudio->b;          /* LINE 8 */

- - -

The assembly language for Line 8 is:

.globl CallbackPeckAudio
CallbackPeckAudio:
...
        .ln     8
        move.l [EMAIL PROTECTED](%a5),%a0
        add.l #__mulsi3,%a0 /*JANE2*/
        move.l 28(%a2),-(%sp)
        move.l 24(%a2),-(%sp)
        jsr (%a0)
        addq.l #8,%sp
        move.l %d0,24(%a2)

- - -

Noting that changing the multiplication to addition causes an in-line
calculation and allows the sound stream callback to work properly, I
tried gcc's inline assembly.

Err CallbackPeckAudio(void *pUserData, 
   SndStreamRef stream, 
   void *bufferP, 
   UInt32 frameCount) 
{
   PeckAudioType *pPeckAudio = (PeckAudioType *)pUserData;
   Err err;

   /* Read next sound stream buffer from file. */
   err = VFSFileRead(pPeckAudio->fileRef, frameCount*2, bufferP, NULL);

//   pPeckAudio->a *= pPeckAudio->b;
   __asm__("
      move.l   28(%a2),%d0; 
      mulu.l   24(%a2),%d0; 
      move.l   %d0,24(%a2);
   ");

- - -

However, that results in the compiler error: "invalid instruction for
this architecture; needs 68020 or 68030 or 68040 or 68060 or cpu32 or
5200 or 5206e or 5307 or 5407 -- statement `mulu.l 24(%a2),%d0'
ignored".  That's a bit confusing because the MC68EZ328 User Manual
lists a mulu instruction in its EC000 instruction set.  I've never had
to mess much with the prc-tools.  Do I need to somewhere specify that I
want gcc to produce MC68EZ328 instructions?

Before I get into this any deeper, I'd like to ask how others have
implemented multiplications from within callbacks.

Thanks,
Greg

-- 
For information on using the Palm Developer Forums, or to unsubscribe, please 
see http://www.palmos.com/dev/support/forums/

Reply via email to