On 2005-04-05, Greg Sepesi <[EMAIL PROTECTED]> wrote:
> 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
>

The assembler in the m68k-palmos-gcc backend defaults to the bare-bones 
m68000 instruction set. You can see this if you do 'm68k-palmos-gcc 
-dumpspecs'.
As a workaround use the '-Wa,-m68020' option to force the assembler to 
recognize the mulu.l instruction.

HTH
Ton van Overbeek

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

Reply via email to