mixed mode magic

mixed mode magic

Post by meero » Wed, 29 Mar 2000 04:00:00





>I'm working on a plug-in architecture.  A 68k plugin needs to call
>some code in the host app, which is PowerPC.  It seems that I can do
>this by directly invoking the function pointer given to me by the host
>app.  I think there is some mixed-mode magic going on behind the
>scenes which makes this possible.  (I didn't write this code, I'm just
>trying to update it!)

>But today, a weird thing is going on.  I'm calling a PowerPC function
>which returns a constant (12345 -- just for testing).  In MacsBug, I
>can see that as this function exits, the value is in r3, where it
>should be.  Then we go briefly into some bowels of the system,
>presumably doing the mode switch.  Then we exit back out to the 68k
>code which called this function.  12345 is not in D0, as you'd expect
>(the function was declared to return an unsigned long), nor in any
>other register at all.  It's on the stack.

>According to the Metrowerks docs, PowerPC functions return integer
>values in r3 (which matches my observations), and 68k functions return
>them in D0 (which does not).  It appears that the mixed-mode magic is
>failing me here, but I don't understand what it's doing or how I'm
>supposed to be using it properly.

>Here's the really weird thing, for the real experts: all this worked
>fine before today.  Today, I added pragmas to my host app which force
>it to compile with Think C calling conventions (#pragma
>pointers_in_D0).  But AIUI, this only affects the 68k target; it
>shouldn't affect my PowerPC target at all.  But it's in the PowerPC
>(host app) target where this problem has cropped up.

Well, no, it's not in the PowerPC app that the problem has cropped up.
As you say yourself, the PPC app is still just as well-behaved as it was
before.

When you call PPC code from 68K code, the 68K code doesn't know anything
about this. What happens is that the 68K code calls what ends up being a
universal procedure pointer, which contains the MixedModeMagic trap at
the beginning. That causes the emulator get invoked, at which point the
arguments get put in the appropriate places in the registers and on the
stack, and the PPC code is invoked. On return, the PPC code leaves the
results in the appropriate places, and then control is returned to the
MixedModeMagic trap. The trap finds those return values, and puts them
into the places where the 68K code expects them. Finally, you return to
the 68K code which now find the results where it wants them.

So, there are basically two things that affect where the arguments are
taken from and where the results are stored:

1. the procInfo field of the UPP for PPC code. This is inspected by the
Mixed Mode Manager to determine both where the arguments will be passed
into the PPC code and where the result will be returned from

2. the calling convention with which the 68K code is compiled. This
determined where the arguments will be put and where the result will be
taken from.

So, now the question becomes: how is the UPP for the PPC code created?
Does it match what the code is compiled with? What conventions is the
68K code compiled with? The 68K code calling PPC code via UPPs has to
use the pointers in D0 convention.

I need more details, but the two things to check are that the 68K code
uses D0 conventions, and that the procInfo is correct -- in particular
that the result part of it is correct.

If you post the function prototype and the procInfo, I can look at
them...

Hth,

meeroh
--
To get random signatures put text files into a folder called 3Random Signatures2 into your Preferences folder.

 
 
 

mixed mode magic

Post by meero » Wed, 29 Mar 2000 04:00:00




>> So, now the question becomes: how is the UPP for the PPC code created?

>It's created by the host app, with NewRoutineDescriptor...

>Doh!  I found the problem: where my UPP info is created, I'm using a
>constant to define the calling convention... and I'd done an overly
>promiscuous search & replace which had munged the constant.  A stupid
>editing mistake, but I'd been poring through this code and stepping
>through assembly in MacsBug for hours, and never found this until I
>want to answer your specific question.

Cool.

Quote:>Meeroh, you're an angel.  This is at least twice you've pulled my
>chestnuts out of the fire (and I bet DejaNews would turn up several
>more).  You have my eternal gratitude!

:-)  Thanks

meeroh
--
To get random signatures put text files into a folder called 3Random Signatures2 into your Preferences folder.

 
 
 

mixed mode magic

Post by Joe Strou » Thu, 30 Mar 2000 04:00:00


I'm working on a plug-in architecture.  A 68k plugin needs to call some
code in the host app, which is PowerPC.  It seems that I can do this by
directly invoking the function pointer given to me by the host app.  I
think there is some mixed-mode magic going on behind the scenes which
makes this possible.  (I didn't write this code, I'm just trying to
update it!)

But today, a weird thing is going on.  I'm calling a PowerPC function
which returns a constant (12345 -- just for testing).  In MacsBug, I
can see that as this function exits, the value is in r3, where it
should be.  Then we go briefly into some bowels of the system,
presumably doing the mode switch.  Then we exit back out to the 68k
code which called this function.  12345 is not in D0, as you'd expect
(the function was declared to return an unsigned long), nor in any
other register at all.  It's on the stack.

According to the Metrowerks docs, PowerPC functions return integer
values in r3 (which matches my observations), and 68k functions return
them in D0 (which does not).  It appears that the mixed-mode magic is
failing me here, but I don't understand what it's doing or how I'm
supposed to be using it properly.

Here's the really weird thing, for the real experts: all this worked
fine before today.  Today, I added pragmas to my host app which force
it to compile with Think C calling conventions (#pragma
pointers_in_D0).  But AIUI, this only affects the 68k target; it
shouldn't affect my PowerPC target at all.  But it's in the PowerPC
(host app) target where this problem has cropped up.

I'm completely baffled by this one; any advice will be greatly
appreciated!

Thanks,
-- Joe

--
,------------------------------------------------------------------.
|    Joseph J. Strout         Check out the Mac Web Directory:     |

`------------------------------------------------------------------'

 
 
 

mixed mode magic

Post by Joe Strou » Thu, 30 Mar 2000 04:00:00




> When you call PPC code from 68K code, the 68K code doesn't know anything
> about this. What happens is that the 68K code calls what ends up being a
> universal procedure pointer, which contains the MixedModeMagic trap at
> the beginning.

OK, I'd thought something like this was going on.  Thank you for the
very helpful explanation (now snipped) of how all this Mixed Mode magic
works!

Quote:> So, now the question becomes: how is the UPP for the PPC code created?

It's created by the host app, with NewRoutineDescriptor...

Doh!  I found the problem: where my UPP info is created, I'm using a
constant to define the calling convention... and I'd done an overly
promiscuous search & replace which had munged the constant.  A stupid
editing mistake, but I'd been poring through this code and stepping
through assembly in MacsBug for hours, and never found this until I
want to answer your specific question.

Meeroh, you're an angel.  This is at least twice you've pulled my
chestnuts out of the fire (and I bet DejaNews would turn up several
more).  You have my eternal gratitude!

--
,------------------------------------------------------------------.
|    Joseph J. Strout         Check out the Mac Web Directory:     |

`------------------------------------------------------------------'

 
 
 

mixed mode magic

Post by Hoshi Takano » Thu, 30 Mar 2000 04:00:00



> It's on the stack.

Don't you remember the good old pascal calling convention?

hoshi

 
 
 

mixed mode magic

Post by Eric Gran » Mon, 03 Apr 2000 05:00:00



> So, now the question becomes: how is the UPP for the PPC code created?
> Does it match what the code is compiled with? What conventions is the
> 68K code compiled with? The 68K code calling PPC code via UPPs has to
> use the pointers in D0 convention.

> I need more details, but the two things to check are that the 68K code
> uses D0 conventions, and that the procInfo is correct -- in particular
> that the result part of it is correct.

I was curious as to what you meant by "68K code calling PPC code via UPPs has
to use the pointers in D0 convention."  Obviously, if the UPPs return pointers
in D0, the 68K calling code had better use that convention if it wants valid
return values.  But then again, UPPs *need not* return pointers in D0.
Indeed, the Toolbox UPPs that implement Memory Manager traps on more recent
versions of the OS typically (perhaps even always?) return pointers in A0
(e.g., NewPtr, NewHandle).

The crucial point to remember (as meeroh surely knows) is that the procInfo
and the calling convention must match.  If the UPP procInfo is fixed, you must
change your 68K calling convention to match; if the 68K calling convention is
fixed, you must change the UPP procInfo to match; if both are fixed (and are
different), you must write wrapper functions.

Cheers,
Eric

 
 
 

mixed mode magic

Post by meero » Mon, 03 Apr 2000 05:00:00





>> So, now the question becomes: how is the UPP for the PPC code
>> created? Does it match what the code is compiled with? What
>> conventions is the 68K code compiled with? The 68K code calling PPC
>> code via UPPs has to use the pointers in D0 convention.

>> I need more details, but the two things to check are that the 68K
>> code uses D0 conventions, and that the procInfo is correct -- in
>> particular that the result part of it is correct.

>I was curious as to what you meant by "68K code calling PPC code via
>UPPs has to use the pointers in D0 convention."  Obviously, if the
>UPPs return pointers in D0, the 68K calling code had better use that
>convention if it wants valid return values.  But then again, UPPs
>*need not* return pointers in D0. Indeed, the Toolbox UPPs that
>implement Memory Manager traps on more recent versions of the OS
>typically (perhaps even always?) return pointers in A0 (e.g., NewPtr,
>NewHandle).

Yes, that is exactly what I meant.

If
   you build a piece of 68K code with pointers in A0 convention and
   that code uses a UPP to call a function that returns a pointer and
   the function is PPC or CFM68K and
   the proc info in the UPP does not indicate that the result is
returned in A0

then
   the 68K code will get a garbage result from the UPP call.

The reason that this works for the memory manager is that the procinfo
for UPPs that point to the memory manager calls which return pointers in
A0 are setup differently. Indeed, look at NewPtr UPP (you can get to it
in Macsbug with "atb NewPtr ';s;drd pc'"), you see that its procinfo is
0x00033312, which is:

kRegisterBased
| RESULT_SIZE (SIZE_CODE (4))
| REGISTER_RESULT_LOCATION (kRegisterA0)
| REGISTER_ROUTINE_PARAMETER (1, kRegisterD1, SIZE_CODE (2))
| REGISTER_ROUTINE_PARAMETER (2, kRegisterD0, SIZE_CODE (4))

as you would expect.

Quote:>The crucial point to remember (as meeroh surely knows) is that the
>procInfo and the calling convention must match.  If the UPP procInfo
>is fixed, you must change your 68K calling convention to match; if the
>68K calling convention is fixed, you must change the UPP procInfo to
>match; if both are fixed (and are different), you must write wrapper
>functions.

No, you are misstating things slightly. There are three things here:

1. calling convention of the caller
2. procinfo in the UPP
3. calling convention of the callee

and they _all_ have to match.

You can't just change the UPP procinfo to match the caller, because the
UPP procinfo does not describe the caller, just the callee. The caller
has to be changed to match, unless (of course), you can recompile the
callee.

meeroh
--
To get random signatures put text files into a folder called "Random Signatures" into your Preferences folder.

 
 
 

1. 68k to ppc mixed mode

I'm trying to call a shared library fragment, compiled with CodeWarrior
(ppc),
from Forth, written in 68k. I'm able to load the fragment, get a
connection ID
to the library routine, get a routine descriptor. But when I jump to the
descriptor (containing the Mixed Mode Magic trap), I always crash. I've
set
a breakpoint at the library routine, but never get there.

Does anyone have any experience with this sort of thing?

2. networked HP 710C

3. Mixed mode/calling PPC code resources question

4. bulk-e-mail.com

5. blank full-screen tv-out when VMR is in mixing mode

6. Service down!

7. mixed video problem using video mixed render 9

8. conflict between MSI - GNB Max (MS 6565) and RADEON 8500 LE

9. changing directdraw exclusive mode in VMR9 renderless mode

10. ANNOUNCE: CC Mode 5.14, Emacs mode for C, C++, Java, ObjC, IDL

11. Announce: cc-mode 4.322, an Emacs mode for C,C++,Objective-C,Java

12. push mode or pull mode

13. How can I switch between Retail mode and Debug mode of DX8.1???