Archives
 
 
 
  Special
 
 
 
  About Us
 
 
 

Newsletter
Free E-mail Newsletter from BYTE.com

 
    
           
Visit the home page Browse the four-year online archive Download platform-neutral CPU/FPU benchmarks Find information for advertisers, authors, vendors, subscribers Request free information on products written about or advertised in BYTE Submit a press release, or scan recent announcements Talk with BYTE's staff and readers about products and technologies

ArticlesPort Mac Applications to the PowerPC


June 1994 / Core Technologies / Port Mac Applications to the PowerPC

Apple's Mixed Mode Manager and Universal Procedure Pointer greatly ease the transition

Rick Grehan

Longtime readers will remember that the IBM PC started out as an 8088 machine. Over time, it and the countless clones that followed grew to be 286 machines, then 386 machines, then 486 machines, then Pentium machines. With the arrival of NT, the notion of a PC clone has blurred. Machines have appeared that look to the casual observer like a high-end PC clone, but inside beats the heart of an Alpha, a Mips processor, a PowerPC, or possibly even an Intel processor.

The incursion of non-Intel CPUs into what had been a virtually all-Intel world continues to assault applications developers with a series of p roblems--which are, happily, closely pursued by solutions. A similar production is unfolding on the Macintosh stage, heralded by the advent of the PowerPC-toting Power Macs. Up to now, the Macintosh was a 680x0 (abbreviated as 68K hereafter) platform, and the installed base of applications software--never mind the Mac OS and Toolbox code--is a gigantic body of 68K-based code that no sane person would simply discard as a casualty necessarily incurred on the road to RISC.

ANSI C Is King

The name of the game is C. When the first edition of Inside Macintosh appeared, the language that was used to describe data structures and call sequences was Pascal. This is no longer the case, however; C is the lingua franca when working with Power Macs.

To be accurate, ANSI C is the language to use with Power Macs. To non-Mac programmers, this may seem to be a given: If you say "C," you really mean "ANSI C." Not so among Mac programmers; nonstandard constructs not only were encouraged to flourish, but in some cases were required. For example, some Toolbox routines expect--and return--parameters in registers; others use a Pascal calling convention, which places parameters atop the stack and the return address beneath.

While compiler designers can provide "wrapper" code to insulate the C program from these peculiar calling conventions, if a programmer wanted to hook a Toolbox call (i.e., provide his or her own code to replace the Toolbox routine), he or she was frequently forced into assembly language. Consequently, Mac C compilers often allowed in-line assembly code. For example, Symantec's Think C provides a non-ANSI asm{ ... } construct that permits the programmer to commingle C and assembly.

The requirement for ANSI compliance not only provides a framework by which the Mac's API can be rigorously defined, but it can also produce some performance gains. For instance, a lazy programmer might be tempted to ignore placing a return type on a function declaration for a routine that returns no value:

sillyFunc(long *x)

{ *x=*x+12;

}

In this case, the C compiler--assuming it's lax enough to permit this--will assume that noValFunction() returns an argument of type int so the compiler will emit code to return an int derived from the value of the last statement executed in the function. It's better to define the function's return type:

void sillyFunc(long *x) ...

so the compiler won't generate the unneeded code.

Finally, if you want to lessen the programming work you'll have to do to verify that your application runs on all Macs, you should remove any explicit dependence on the size of the int data type. On 68K Macs, depending on the compiler, an int could be 2 or 4 bytes (some compilers provide switches that let you toggle between the two). On the PowerPC, an int is always 4 bytes.

Preliminary Apple documentation relating to the porting process recommends you use variables of type int only to access the "natural word size" of the machine, such as the declar ation of a variable used only as the index in a for loop. Use short for 2-byte integers and long for 4-byte integers.

Floating Point

Programmers familiar with SANE (Standard Apple Numeric Environment) will be saddened to know that the 64-bit comp (short for computational) data type and the 80-bit extended floating-point type are not supported on Power Macs. (The comp data type was basically a 64-bit signed integer, with the added advantage that it could return a NaN [not a number] value, useful in indicating arithmetic exceptions. The comp data type performed exact arithmetic, such as is required in accounting.) This "out with the old, in with the new" campaign is necessary because the PowerPC chip's integrated FPU handles single- and double-precision numbers (32 and 64 bits, respectively) as native data types.

What made the 80-bit extended format useful was the fact that single-precision, double-precision, and comp types could be converted to the 80-bit extended type with no loss of precisio n. This simplified the mixing of operands of different types. In fact, the SANE package used the extended type for all its internal calculations. Ironically, the Apple Numerics Manual referred to the single-precision, double-precision, and comp types as "application types" rather than as arithmetic types; they were deemed to have value as space-saving data structures rather than as data structures to be used during calculations.

Fortunately, if you need the precision, Power Macs do support a 128-bit long double. You will, however, pay a speed penalty; operations performed on long doubles are handled in emulation fashion rather than by the PowerPC's FPU.

Code Fragments

If you set your Wayback Machine to a little over 10 years ago, when the Macintosh was first introduced, you'll recall that the machine was delivered to the world with 128 KB of RAM. Although that was a respectable amount of RAM at that time, Mac engineers realized that an application would require more RAM than might be left fre e after the operating system had taken what it needed. They therefore designed the system so that applications consisted of relocatable chunks of code called segments. And, because of the limitation on the relative jump instruction within the 68000 CPU, the size of a segment was fixed at 32 KB. Although the operating system handled the headaches of loading and unloading segments, it was nonetheless left to the programmer to tell the Mac OS when a particular segment was free to be discarded (using the UnloadSeg trap).

With the introduction of Power Macs, what had been a code segment now becomes a code fragment. This is not, however, a simple change in nomenclature. Code fragments can extend beyond 32 KB, they can possess local data, and they carry named entry points. An application is really just a code fragment; when an application loads on a Power Mac, the Mac OS also loads all code fragments holding routines referenced by the application and binds the references (this is done by a new Toolbox service , the Code Fragment Manager). Code fragments are therefore very similar to dynamically linked libraries.

Note that the programmer no longer needs to get involved with memory management issues (i.e., which fragments are free to be unloaded). The reason for this, of course, is that the PowerPC has its own virtual MMU (memory management unit), so the entire mechanism for memory management moves into the operating system, where it belongs.

Mixed-Mode Programming

As I mentioned at the outset, Apple has done much work to make the transition to the PowerPC world as easy as possible. Specifically, Power Macs provide a 68K emulator that can make the machine look to the outside world like a 68020-based Mac. Actually, it looks sort of like a 68040 minus the 68040's integrated MMU and FPU. However, Apple discourages developers from presuming any instructions beyond those supported by the 68020.

This protects all the work that's been done to create the existing 68K code base. However, it would be c razy if the system ran only in emulated fashion. Not only would that guarantee less-than-optimum performance, but no smooth transition to native PowerPC applications would be possible.

Apple engineers, looking at the Mac's Toolbox code, were staring at the same porting problems that any other Mac developer would be faced with during the transition. Not only would rewriting all that code take lots of time, programmers, and money, but the process would likely introduce bugs in routines that had long since been cleansed. So, Apple programmers rewrote only critical, often-called Toolbox routines in PowerPC code, leaving the rest in 68K code. These latter routines are executed by the Power Macs' 68K emulator.

Consequently, a given Toolbox routine might be written in PowerPC code, or it might be in 68K code (and therefore require the emulator). Since it would be unimaginable to place upon the programmer the job of determining--at run time--the machine-code type of a particular routine, Apple designed the Mixed Mode Manager and armed programmers with the UPP (Universal Procedure Pointer). It works as follows.

Any exported routine in a code fragment (i.e., a routine that can be called from outside the fragment) is accessed via a UPP. Setting up the UPP is the job of the caller (i.e., the caller calls the exported routine through the UPP). If the exported routine is composed of 68K code, then the UPP consists of just a typical pointer to the address of the routine's entry point. However, if the exported routine is composed of PowerPC code, the UPP is a data structure (called a routine descriptor), typically about 32 bytes in size, headed by a trap word that leads into the Mixed Mode Manager.

Consequently, calling the UPP either leads your program directly to the 68K code or transfers control to the Mixed Mode Manager. It is the Mixed Mode Manager's job to deduce where the application is coming from and where it's going to and to determine if a switch from native PowerPC code to the 68K emulator (or back) is needed. Note that this also requires moving arguments around (e.g., from registers to the stack) so that the called routine finds data where it expects it.

Happily, C/C++ compilers for PowerPC Macs already provide functions and macros that automate the process of building UPPs. Apple guidelines suggest that, wherever your code uses a ProcPtr, you replace it with a UniversalProcPtr.

A Stroke of Genius

Faced with the admittedly daunting task of shepherding a well-established system into an entirely new processor architecture, Apple appears to be doing a remarkable job of accommodating developers during the transition. Admittedly, the transition isn't trouble-free; I have my own pile of C code that I'll have to sift through via search-and-replace and turn every int into short.

On the bright side, my opinion is that the Mixed Mode Manager (with its accompanying UPPs) is something of a stroke of genius. What it provides is a way for Apple to continue to move more of the Toolbo x to native code, and programmers will see the benefits without having to make any alterations of their own.

Of course, it also means that as you target those routines that will yield the greatest performance if converted to PowerPC code, you'll be doing some code-tweaking for a while. But you're used to that, right?


Illustration: Mixed-Mode Magic By examining the UPP, the Mixed Mode Manager handles switching between native PowerPC routines and routines executed by the 68K emulator.
Rick Grehan is technical director of the BYTE Lab. Before coming to BYTE, he worked as a programmer. He has a B.S. in physics and applied mathematics and an M.S. in mathematics/computer science. He can be reached on the Internet or BIX at rick_g@bix.com .

Up to the Core Technologies section contentsGo to previous article: From Here to ThereSearchSend a comment on this articleSubscribe to BYTE or BYTE on CD-ROM   Copy
Flexible C++
Matthew Wilson
My approach to software engineering is far more pragmatic than it is theoretical--and no language better exemplifies this than C++.

more...

BYTE Digest

BYTE Digest editors every month analyze and evaluate the best articles from Information Week, EE Times, Dr. Dobb's Journal, Network Computing, Sys Admin, and dozens of other CMP publications—bringing you critical news and information about wireless communication, computer security, software development, embedded systems, and more!

Find out more

BYTE.com Store

BYTE CD-ROM
NOW, on one CD-ROM, you can instantly access more than 8 years of BYTE.
 
The Best of BYTE Volume 1: Programming Languages
The Best of BYTE
Volume 1: Programming Languages
In this issue of Best of BYTE, we bring together some of the leading programming language designers and implementors...

Copyright © 2005 CMP Media LLC, Privacy Policy, Your California Privacy rights, Terms of Service
Site comments: webmaster@byte.com
SDMG Web Sites: BYTE.com, C/C++ Users Journal, Dr. Dobb's Journal, MSDN Magazine, New Architect, SD Expo, SD Magazine, Sys Admin, The Perl Journal, UnixReview.com, Windows Developer Network