executor/docs/MacHack_96.htm

1 line
200 KiB
HTML

<html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta name=Title content="Executor Internals">
<meta name=Keywords content="">
<meta http-equiv=Content-Type content="text/html; charset=macintosh">
<meta name=ProgId content=Word.Document>
<meta name=Generator content="Microsoft Word 9">
<meta name=Originator content="Microsoft Word 9">
<link rel=File-List href="MacHack_96_files/filelist.xml">
<title>Executor Internals</title>
<!--[if gte mso 9]><xml>
<o:DocumentProperties>
<o:Subject>How to efficiently run Mac Programs on PCs</o:Subject>
<o:Author>ctm + mat</o:Author>
<o:Template>Normal</o:Template>
<o:LastAuthor>ctm</o:LastAuthor>
<o:Revision>2</o:Revision>
<o:TotalTime>1</o:TotalTime>
<o:Created>2002-02-27T23:21:00Z</o:Created>
<o:LastSaved>2002-02-27T23:21:00Z</o:LastSaved>
<o:Pages>3</o:Pages>
<o:Words>7412</o:Words>
<o:Characters>42250</o:Characters>
<o:Company>ardi</o:Company>
<o:Lines>352</o:Lines>
<o:Paragraphs>84</o:Paragraphs>
<o:CharactersWithSpaces>51885</o:CharactersWithSpaces>
<o:Version>9.2511</o:Version>
</o:DocumentProperties>
<o:OfficeDocumentSettings>
<o:PixelsPerInch>800x600</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:PrintFractionalCharacterWidth/>
<w:HyphenationZone>0</w:HyphenationZone>
<w:DoNotHyphenateCaps/>
<w:DrawingGridHorizontalSpacing>6 pt</w:DrawingGridHorizontalSpacing>
<w:DrawingGridVerticalSpacing>6 pt</w:DrawingGridVerticalSpacing>
<w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery>
<w:DisplayVerticalDrawingGridEvery>0</w:DisplayVerticalDrawingGridEvery>
<w:UseMarginsForDrawingGridOrigin/>
<w:DoNotShadeFormData/>
<w:Compatibility>
<w:OrigWordTableRules/>
<w:NoLeading/>
<w:SpaceForUL/>
<w:BalanceSingleByteDoubleByteWidth/>
<w:DoNotLeaveBackslashAlone/>
<w:ULTrailSpace/>
<w:DoNotExpandShiftReturn/>
<w:SpacingInWholePoints/>
<w:ShowBreaksInFrames/>
<w:SuppressTopSpacing/>
<w:SuppressTopSpacingMac5/>
<w:MWSmallCaps/>
<w:UsePrinterMetrics/>
<w:WW6BorderRules/>
<w:FootnoteLayoutLikeWW8/>
<w:ShapeLayoutLikeWW8/>
<w:AlignTablesRowByRow/>
<w:ForgetLastTabAlignment/>
<w:DoNotUseHTMLParagraphAutoSpacing/>
<w:LayoutRawTableWidth/>
<w:LayoutTableRowsApart/>
<w:UseWord97LineBreakingRules/>
</w:Compatibility>
</w:WordDocument>
</xml><![endif]-->
<style>
<!--
/* Font Definitions */
@font-face
{font-family:"Times New Roman";
panose-1:0 2 2 6 3 5 4 5 2 3;
mso-font-charset:0;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:50331648 0 0 0 1 0;}
@font-face
{font-family:Arial;
panose-1:0 2 11 6 4 2 2 2 2 2;
mso-font-charset:0;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:50331648 0 0 0 1 0;}
@font-face
{font-family:"Courier New";
panose-1:0 2 7 3 9 2 2 5 2 4;
mso-font-charset:77;
mso-generic-font-family:modern;
mso-font-format:other;
mso-font-pitch:fixed;
mso-font-signature:50331648 0 0 0 1 0;}
@font-face
{font-family:Geneva;
panose-1:0 2 11 5 3 3 4 4 4 2;
mso-font-charset:77;
mso-generic-font-family:swiss;
mso-font-format:other;
mso-font-pitch:variable;
mso-font-signature:50331648 0 0 0 1 0;}
@font-face
{font-family:"Tms Rmn";
panose-1:0 0 0 0 0 0 0 0 0 0;
mso-font-charset:77;
mso-generic-font-family:roman;
mso-font-format:other;
mso-font-pitch:variable;
mso-font-signature:50331648 0 0 0 1 0;}
@font-face
{font-family:Helv;
panose-1:0 0 0 0 0 0 0 0 0 0;
mso-font-charset:77;
mso-generic-font-family:swiss;
mso-font-format:other;
mso-font-pitch:variable;
mso-font-signature:50331648 0 0 0 1 0;}
@font-face
{font-family:"MS Serif";
panose-1:0 0 0 0 0 0 0 0 0 0;
mso-font-charset:77;
mso-generic-font-family:roman;
mso-font-format:other;
mso-font-pitch:variable;
mso-font-signature:50331648 0 0 0 1 0;}
@font-face
{font-family:"MS Sans Serif";
panose-1:0 0 0 0 0 0 0 0 0 0;
mso-font-charset:77;
mso-generic-font-family:swiss;
mso-font-format:other;
mso-font-pitch:variable;
mso-font-signature:50331648 0 0 0 1 0;}
@font-face
{font-family:"New York";
panose-1:0 2 2 5 2 6 3 5 6 2;
mso-font-charset:77;
mso-generic-font-family:roman;
mso-font-format:other;
mso-font-pitch:variable;
mso-font-signature:50331648 0 0 0 1 0;}
@font-face
{font-family:System;
panose-1:0 0 0 0 0 0 0 0 0 0;
mso-font-charset:77;
mso-generic-font-family:swiss;
mso-font-format:other;
mso-font-pitch:variable;
mso-font-signature:50331648 0 0 0 1 0;}
@font-face
{font-family:Wingdings;
panose-1:0 5 2 1 2 1 8 4 8 7;
mso-font-charset:2;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:0 16 0 0 -2147483648 0;}
@font-face
{font-family:"FE Roman font face";
panose-1:0 0 0 0 0 0 0 0 0 0;
mso-font-charset:0;
mso-generic-font-family:roman;
mso-font-format:other;
mso-font-pitch:fixed;
mso-font-signature:50331648 0 0 0 1 0;}
@font-face
{font-family:"FE Modern font face";
panose-1:0 0 0 0 0 0 0 0 0 0;
mso-font-charset:0;
mso-generic-font-family:modern;
mso-font-format:other;
mso-font-pitch:fixed;
mso-font-signature:50331648 0 0 0 1 0;}
@font-face
{font-family:"FE Truetype Roman font face";
panose-1:0 0 0 0 0 0 0 0 0 0;
mso-font-charset:0;
mso-generic-font-family:roman;
mso-font-format:other;
mso-font-pitch:fixed;
mso-font-signature:50331648 0 0 0 1 0;}
@font-face
{font-family:"FE Truetype Modern font face";
panose-1:0 0 0 0 0 0 0 0 0 0;
mso-font-charset:0;
mso-generic-font-family:modern;
mso-font-format:other;
mso-font-pitch:fixed;
mso-font-signature:50331648 0 0 0 1 0;}
@font-face
{font-family:Century;
panose-1:0 0 0 0 0 0 0 0 0 0;
mso-font-charset:77;
mso-generic-font-family:roman;
mso-font-format:other;
mso-font-pitch:variable;
mso-font-signature:50331648 0 0 0 1 0;}
@font-face
{font-family:Chicago;
panose-1:0 2 11 8 6 8 6 4 4 2;
mso-font-charset:0;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:50331648 0 0 0 1 0;}
@font-face
{font-family:Monaco;
panose-1:0 2 0 5 0 0 0 0 0 0;
mso-font-charset:0;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:50331648 0 0 0 1 0;}
@font-face
{font-family:Palatino;
panose-1:0 2 0 5 0 0 0 0 0 0;
mso-font-charset:0;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:50331648 0 0 0 1 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:Palatino;}
h1
{mso-style-next:Normal;
margin-top:12.0pt;
margin-right:0in;
margin-bottom:0in;
margin-left:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
mso-outline-level:1;
font-size:12.0pt;
font-family:Helvetica;
mso-font-kerning:0pt;
text-decoration:underline;
text-underline:single;}
h2
{mso-style-next:Normal;
margin-top:6.0pt;
margin-right:0in;
margin-bottom:0in;
margin-left:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
mso-outline-level:2;
font-size:12.0pt;
font-family:Helvetica;}
h3
{mso-style-next:Normal;
margin-top:6.0pt;
margin-right:0in;
margin-bottom:0in;
margin-left:.25in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
mso-outline-level:3;
font-size:12.0pt;
font-family:Palatino;}
h4
{mso-style-next:Normal;
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:.25in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
mso-outline-level:4;
font-size:12.0pt;
font-family:Palatino;
text-decoration:underline;
text-underline:single;
font-weight:normal;}
h5
{mso-style-next:Normal;
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:.5in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
mso-outline-level:5;
font-size:10.0pt;
font-family:Palatino;}
h6
{mso-style-next:Normal;
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:.5in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
mso-outline-level:6;
font-size:10.0pt;
font-family:Palatino;
text-decoration:underline;
text-underline:single;
font-weight:normal;}
p.MsoFootnoteText, li.MsoFootnoteText, div.MsoFootnoteText
{margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:Palatino;}
p.MsoFooter, li.MsoFooter, div.MsoFooter
{margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
tab-stops:center 3.0in right 6.0in;
font-size:10.0pt;
font-family:Palatino;}
span.MsoFootnoteReference
{font-size:8.0pt;
mso-text-raise:3.0pt;}
span.MsoEndnoteReference
{vertical-align:super;}
/* Page Definitions */
@page
{mso-mirror-margins:yes;
mso-page-border-surround-header:no;
mso-page-border-surround-footer:no;}
@page Section1
{size:8.5in 11.0in;
margin:-1.0in .5in -1.0in .5in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-gutter-margin:.75in;
mso-footer:url(":MacHack_96_files:header.htm") f1;
mso-paper-source:0;}
div.Section1
{page:Section1;}
@page Section2
{size:8.5in 11.0in;
margin:-1.0in .5in -1.0in .5in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-gutter-margin:.75in;
mso-columns:2 even .5in;
mso-footer:url(":MacHack_96_files:header.htm") f1;
mso-paper-source:0;}
div.Section2
{page:Section2;}
@page Section3
{size:8.5in 11.0in;
margin:-1.0in .5in -1.0in .5in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-gutter-margin:.75in;
mso-footer:url(":MacHack_96_files:header.htm") f1;
mso-paper-source:0;}
div.Section3
{page:Section3;}
@page Section4
{size:8.5in 11.0in;
margin:-1.0in .5in -1.0in .5in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-gutter-margin:.75in;
mso-columns:2 even .5in;
mso-footer:url(":MacHack_96_files:header.htm") f1;
mso-paper-source:0;}
div.Section4
{page:Section4;}
@page Section5
{size:8.5in 11.0in;
margin:-1.0in .5in -1.0in .5in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-gutter-margin:.75in;
mso-footer:url(":MacHack_96_files:header.htm") f1;
mso-paper-source:0;}
div.Section5
{page:Section5;}
@page Section6
{size:8.5in 11.0in;
margin:-1.0in .5in -1.0in .5in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-gutter-margin:.75in;
mso-columns:2 even .5in;
mso-footer:url(":MacHack_96_files:header.htm") f1;
mso-paper-source:0;}
div.Section6
{page:Section6;}
@page Section7
{size:8.5in 11.0in;
margin:-1.0in .5in -1.0in .5in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-gutter-margin:.75in;
mso-footer:url(":MacHack_96_files:header.htm") f1;
mso-paper-source:0;}
div.Section7
{page:Section7;}
@page Section8
{size:8.5in 11.0in;
margin:-1.0in .5in -1.0in .5in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-gutter-margin:.75in;
mso-columns:2 even .5in;
mso-footer:url(":MacHack_96_files:header.htm") f1;
mso-paper-source:0;}
div.Section8
{page:Section8;}
@page Section9
{size:8.5in 11.0in;
margin:-1.0in .5in -1.0in .5in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-gutter-margin:.75in;
mso-footer:url(":MacHack_96_files:header.htm") f1;
mso-paper-source:0;}
div.Section9
{page:Section9;}
@page Section10
{size:8.5in 11.0in;
margin:-1.0in .5in -1.0in .5in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-gutter-margin:.75in;
mso-columns:2 even .5in;
mso-footer:url(":MacHack_96_files:header.htm") f1;
mso-paper-source:0;}
div.Section10
{page:Section10;}
@page Section11
{size:8.5in 11.0in;
margin:-1.0in .5in -1.0in .5in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-gutter-margin:.75in;
mso-footer:url(":MacHack_96_files:header.htm") f1;
mso-paper-source:0;}
div.Section11
{page:Section11;}
@page Section12
{size:8.5in 11.0in;
margin:-1.0in .5in -1.0in .5in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-gutter-margin:.75in;
mso-columns:2 even .5in;
mso-footer:url(":MacHack_96_files:header.htm") f1;
mso-paper-source:0;}
div.Section12
{page:Section12;}
@page Section13
{size:8.5in 11.0in;
margin:-1.0in .5in -1.0in .5in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-gutter-margin:.75in;
mso-footer:url(":MacHack_96_files:header.htm") f1;
mso-paper-source:0;}
div.Section13
{page:Section13;}
@page Section14
{size:8.5in 11.0in;
margin:-1.0in .5in -1.0in .5in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-gutter-margin:.75in;
mso-columns:2 even .5in;
mso-footer:url(":MacHack_96_files:header.htm") f1;
mso-paper-source:0;}
div.Section14
{page:Section14;}
@page Section15
{size:8.5in 11.0in;
margin:-1.0in .5in -1.0in .5in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-gutter-margin:.75in;
mso-footer:url(":MacHack_96_files:header.htm") f1;
mso-paper-source:0;}
div.Section15
{page:Section15;}
-->
</style>
</head>
<body bgcolor=white lang=EN-US style='tab-interval:.5in'>
<div class=Section1>
<p class=MsoNormal align=center style='text-align:center'><span
style='font-size:18.0pt'>Executor Internals:<o:p></o:p></span></p>
<p class=MsoNormal align=center style='text-align:center'><span
style='font-size:18.0pt'>How to Efficiently Run Mac Programs on PCs<o:p></o:p></span></p>
<p class=MsoNormal align=center style='text-align:center'><span
style='font-size:18.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
<p class=MsoNormal align=center style='text-align:center'><span
style='font-size:12.0pt'>Mathew J. Hostetter </span><span style='font-size:
12.0pt;font-family:Courier'>&lt;mat@ardi.com&gt;</span><span style='font-size:
12.0pt'><o:p></o:p></span></p>
<p class=MsoNormal align=center style='text-align:center'><span
style='font-size:12.0pt'>Clifford T. Matthews </span><span style='font-size:
12.0pt;font-family:Courier'>&lt;ctm@ardi.com&gt;<o:p></o:p></span></p>
<p class=MsoNormal align=center style='text-align:center'><span
style='font-size:9.0pt'>After MacHack '96, this paper will be available from</span><span
style='font-size:9.0pt;font-family:Courier'> http://www.ardi.com</span><span
style='font-size:9.0pt'><o:p></o:p></span></p>
<p class=MsoNormal align=center style='text-align:center'><span
style='font-size:12.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
<p class=MsoNormal>Executor is a commercial Macintosh emulator that uses no
software from Apple, but is still able to run much 680x0 based Macintosh
software faster on Pentiums than the same software runs on 680x0 based
Macs.<span style="mso-spacerun: yes">&nbsp; </span>This paper contains some
implementation details, including descriptions of Executor's synthetic CPU,
graphics subsystem and debugging environment.<span style="mso-spacerun:
yes">&nbsp; </span>Portability issues, current limitations and future plans are
also presented.<span style='font-size:18.0pt'><o:p></o:p></span></p>
</div>
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
</span>
<div class=Section2>
<h1>Executor Overview</h1>
<h2>What Executor is</h2>
<p class=MsoNormal>Executor is a commercial emulator that allows PCs to run
many Macintosh applications.<span style="mso-spacerun: yes">&nbsp;
</span>Executor does not require Macintosh ROMs or a Macintosh System file and
contains no Appple code itself.<span style="mso-spacerun: yes">&nbsp;
</span>Executor was written entiredly by engineers without Macintosh
backgrounds who have not disassembled any of Apple's ROMs or System file.</p>
<h2>Limitations</h2>
<p class=MsoNormal>Because Executor was written strictly from publicly
available documentation (Inside Macintosh, Tech. Notes, etc.), programs which
make use of undocumented features of MacOS may fail under Executor.<span
style="mso-spacerun: yes">&nbsp; </span>Furthermore,<span style="mso-spacerun:
yes">&nbsp; </span>there are some portions of MacOS that we haven't implemented
yet.<span style="mso-spacerun: yes">&nbsp; </span>Executor is sufficiently
large that there are probably bugs in some of our code as well.<span
style="mso-spacerun: yes">&nbsp; </span>We realize these are major limitations,
but this paper is primarily concerned with implementation details that are
interesting to our fellow programmers as opposed to feature sets and limitations
which are of more concern to end users and our marketing department.</p>
<h1>Design Goals</h1>
<p class=MsoNormal>Our goal is for Executor to be accurate, fast and
portable.<span style="mso-spacerun: yes">&nbsp; </span>Beyond that,
completeness is a secondary issue.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Accuracy means that each subsystem that we implement should
behave exactly according to the functional specs for the subsystem that we've
derived from a combination of reading documentation, writing test cases and
running programs under Executor.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Fast is harder to qualify.<span style="mso-spacerun:
yes">&nbsp; </span>As programmers we like to use advanced techniques that will
result in programs running under Executor as quickly as possible.<span
style="mso-spacerun: yes">&nbsp; </span>Unfortunately, we have a limited number
of engineer hours in a week and most engineering time is spent implementing new
subsystems or finding and fixing subtle incompatibilities.<span
style="mso-spacerun: yes">&nbsp; </span>We're proud of the speed that we've
obtained so far, but we know that we can do better in the future.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Portability is the ability to support multiple platforms
from the same source base.<span style="mso-spacerun: yes">&nbsp; </span>A
platform is a combination of CPU, operating system and graphics device or
windowing system.<span style="mso-spacerun: yes">&nbsp; </span>Executor
currently supports Intel 80[3456]86 and compatible CPUs, Motorola m680[34]0
CPUs, the operating systems DOS, Linux and NEXTSTEP and can interact with VGA,
SVGA,<span style="mso-spacerun: yes">&nbsp; </span>Display PostScript and
X-Windows.<span style="mso-spacerun: yes">&nbsp; </span>To get the best
performance on some architectures we do use architecture specific code,
but<span style="mso-spacerun: yes">&nbsp; </span>we also write portable
versions to be used where the platform specific versions can't be.<span
style="mso-spacerun: yes">&nbsp; </span>Although not supported as a product,
Executor was ported to DEC's Alpha, but since ARDI has no Alpha and DEC lost
interest, the Alpha port is no longer current.<span style="mso-spacerun:
yes">&nbsp; </span>Although not recently, ROMlib, ARDI's rewrite of the MacOS
OS and Toolbox routines, has been ported to a wide variety of platforms,
including MIPS , m88k , Clipper, IBM RT, SPARC and even VAX based systems.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Those three design goals have led us in the direction of
dynamic code generation for both the 680x0 emulation and for our blitter.<span
style="mso-spacerun: yes">&nbsp; </span>In both cases we use high level
descriptions of what we want accomplished and then use special purpose tools at
compile time to translate these high level descriptions into constructs that we
can then use at run time.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>High level descriptions are less error prone, allowing us to
document the semantics that we wish to see in our synthetic CPU or blitter
using a special purpose language that is directly suited to the task at hand,
rather than a general purpose language like C or the traditional language of
speed freaks -- assembler.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>High level descriptions also lend themselves to
portability.<span style="mso-spacerun: yes">&nbsp; </span>We have our tools
generate portable constructs for the general case and, with a little more
programming effort, faster architecture specific constructs for the architectures
that we consider most important.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Since the conversion from high level description to useful
construct takes place at compile time, there is no need to worry about the CPU
cycles spent doing the mapping.<span style="mso-spacerun: yes">&nbsp;
</span>This allows us to design our code by thinking:<span style="mso-spacerun:
yes">&nbsp; </span>&quot;At <i>runtime</i><span style='font-style:normal'>,
what would be the optimal instruction sequence to perform a specific
task?&quot;<span style="mso-spacerun: yes">&nbsp; </span>Once we know the
answer to that question we can ask:<span style="mso-spacerun: yes">&nbsp;
</span>&quot;How can we represent at a high level, the task is being
accomplished by that optimal set of instructions?&quot;. <span
style="mso-spacerun: yes">&nbsp;</span>Then, the final question is &quot;Given
what we want to generate and how we want to represent it, what does the compile
time mapping look like?&quot;.<span style="mso-spacerun: yes">&nbsp;&nbsp;
</span>The entire time we're pondering those three questions, we're keeping
accuracy, portability and efficiency in mind.</span></p>
<h1>Executor Subsystems</h1>
<h2>Synthetic CPU</h2>
<h3>Overview</h3>
<p class=MsoNormal>Syn68k is the name of the synthetic CPU that Executor 2
uses.<span style="mso-spacerun: yes">&nbsp; </span>Syn68k is both highly
portable and fast.<span style="mso-spacerun: yes">&nbsp; </span>The portable
core of Syn68k, which works by dynamically compiling 680x0 code into an
efficient interpreted form, was designed to run on all major CPU's.<span
style="mso-spacerun: yes">&nbsp; </span>On supported architectures, Syn68k can
also translate 680x0 code into native code that the host processor can run
directly.</p>
<h3>Syngen</h3>
<p class=MsoNormal>Syngen analyzes a lisp-like file describing the bit patterns
and semantics of the 680x0 instruction set and produces lookup tables and C code
for the runtime system to use.<span style="mso-spacerun: yes">&nbsp; </span>The
code and tables generated by syngen depend somewhat on the characteristics of
the host processor; for example, on a little endian machine it is advantageous
to byte swap some extracted 680x0 operands at translation time instead of at
runtime.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The 680x0 description file can describe multiple ways to
emulate any particular 680x0 opcode.<span style="mso-spacerun: yes">&nbsp;
</span>The runtime system looks at what CC bits are live after the instruction
and chooses the fastest variant it can legally use.<span style="mso-spacerun:
yes">&nbsp; </span>In Figure 1, we have two CC variants of lsrw; one computes
no CC bits, and the other computes all of them.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The 680x0 description file can also specify which 680x0
operands should be &quot;expanded&quot; to become implicitly known by the
corresponding synthetic opcode.<span style="mso-spacerun: yes">&nbsp;
</span>For example, fully expanding out &quot;addl dx,dy&quot; would result in
64 synthetic opcodes, one </p>
<p class=MsoNormal>for each combination of data register operands.<span
style="mso-spacerun: yes">&nbsp; </span>This results in smaller and faster
synthetic opcodes at the expense of increasing the total number of synthetic
opcodes.<span style="mso-spacerun: yes">&nbsp; </span>To conserve space, we
only &quot;expand out &quot; common 680x0 opcodes. On host architectures where
we can compile to native code, we don't waste space by &quot;expanding
out&quot; common synthetic opcodes.</p>
<h3>Interpreted Code</h3>
<p class=MsoNormal>Our interpreted code consists of contiguous sequences of
&quot;synthetic opcodes&quot; and their operands.<span style="mso-spacerun:
yes">&nbsp; </span>Syngen can generate ANSI C, but when </p>
</div>
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
</span>
<div class=Section3>
<div style='mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-element-top:bottom;mso-height-rule:exactly'>
<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=center>
<tr>
<td valign=top align=left style='padding-top:9.0pt;padding-right:9.0pt;
padding-bottom:9.0pt;padding-left:9.0pt'>
<div style='border:solid windowtext .75pt;padding:0in 0in 0in 0in;background:
#E5E5E5;mso-shading:windowtext;mso-pattern:gray-10 auto'>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'>(defopcode lsrw_ea<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun: yes">&nbsp;
</span>(list 68000 amode_alterable_memory () (list
&quot;1110001011mmmmmm&quot;))<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun: yes">&nbsp;
</span>(list &quot;-----&quot; &quot;-----&quot; dont_expand<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(assign
$1.muw (&gt;&gt; $1.muw 1)))<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun: yes">&nbsp;
</span>(list &quot;CN0XZ&quot; &quot;-----&quot; dont_expand<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(list<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span
style="mso-spacerun: yes">&nbsp;</span>(assign ccx (assign ccc (&amp; $1.muw
1)))<o:p></o:p></span></p>
<p class=MsoNormal align=center style='text-align:center;border:none;
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span
style="mso-spacerun: yes">&nbsp;</span>(ASSIGN_NNZ_WORD (assign $1.muw
(&gt;&gt; $1.muw 1))))))<o:p></o:p></span></p>
<p class=MsoNormal align=center style='text-align:center;border:none;
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
<p class=MsoNormal align=center style='text-align:center;border:none;
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-size:12.0pt'>Figure 1.<span style="mso-spacerun: yes">&nbsp;
</span>Syn68k description of lsrw</span><span style='font-family:Courier'><o:p></o:p></span></p>
</div>
</td>
</tr>
</table>
</div>
</div>
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
</span>
<div class=Section4>
<p class=MsoNormal>compiled with GCC it uses C language extensions that make
synthetic opcodes be pointers to the C code responsible for interpreting that
opcode.<span style="mso-spacerun: yes">&nbsp; </span>This &quot;threaded
interpreting&quot; entirely eliminates switch dispatch and loop overhead.</p>
<h3>Native Code</h3>
<p class=MsoNormal>For the 80x86 architecture, Syn68k supports an optional
architecture-specific native code extension that tries to generate native code
whenever possible.<span style="mso-spacerun: yes">&nbsp; </span>In those rare
cases when it cannot, it reverts to our interpreted code.<span
style="mso-spacerun: yes">&nbsp; </span>Since Syn68k supports both native and
synthetic code, the runtime system automatically inserts gateways between the
two whenever there is a transition. </p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Three major problems make translating 680x0 code to 80x86
code difficult:</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>&#8226; The
80x86 has only 8 registers, while the 680x0 has 16.</p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>&#8226; The
80x86 is little endian, while the 680x0 is big endian.</p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>&#8226; The
80x86 does not have general-purpose postincrement and predecrement<span
style="mso-spacerun: yes">&nbsp; </span>operators, which are used frequently in
680x0 code.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>On the other hand, several factors make the job easier than
it would be for RISC machines:</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>&#8226; The
80x86 has all of the CISC addressing modes commonly used in 680x0 code.</p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>&#8226; The
80x86 has CC bits that map directly to their 680x0 counterparts (except for the
680x0's X bit).</p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>&#8226; The
80x86 supports 8-, 16- and 32-bit operations, (although it can only support 8
bit operations on four of its registers).</p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>&#8226; The
80x86 and 680x0 have analogous conditional branch instructions.</p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>&#8226; The
80x86 allows unaligned memory accesses without substantial overhead.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The toughest problem is the lack of registers.<span
style="mso-spacerun: yes">&nbsp; </span>On 32-register RISC architectures it's
easy to allocate one RISC register for each 680x0 register, but on the 80x86 a
different approach is needed. The obvious solution is to perform full-blown
inter-block register allocation, but we fear that using traditional compiler
techniques would be unacceptably slow.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>For now, we have adopted a simple constraint: between basic
blocks, all registers and live CC bits must reside in their canonical home in
memory.<span style="mso-spacerun: yes">&nbsp; </span>Within a block, anything
goes.<span style="mso-spacerun: yes">&nbsp; </span>So what liberties does Syn68k
take within a block?</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The 80x86 register set is treated as a cache for recently
used 680x0 registers, and the 80x86 CC bits are used as a cache for the 680x0
CC bits.<span style="mso-spacerun: yes">&nbsp; </span>At any particular point
within a block, each 680x0 register is either sitting in its memory home or is
cached in an 80x86 register, and each live 680x0 CC bit is either cached in its
80x86 equivalent or stored in its memory home.<span style="mso-spacerun:
yes">&nbsp; </span>Cached registers may be in canonical form, may be byte
swapped, may have only their low two bytes swapped, or may be offset by a known
constant from their actual value.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Each 680x0 instruction can require that 680x0 registers be
cached in particular ways.<span style="mso-spacerun: yes">&nbsp; </span>For
example, <span style='font-family:Courier'>movel d0, mem</span> requires d0 to
be cached in big endian byte order.<span style="mso-spacerun: yes">&nbsp;
</span>The compilation engine generates the minimal code needed to satisfy
those constraints and then calls a sequence of routines to generate the native
code.<span style="mso-spacerun: yes">&nbsp; </span>As each 680x0 instruction is
processed, each 680x0 register's cache status is updated.<span
style="mso-spacerun: yes">&nbsp; </span>Dirty registers are canonicalized and
spilled back to memory at the end of each block (or when we run out of 80x86
registers and we need to make room).</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>We allow 680x0 registers to be cached with varying byte
orders and offsets so that we can perform the optimizations of lazy byte
swapping and lazy constant offsetting.<span style="mso-spacerun: yes">&nbsp;
</span>If the 680x0 program loads a register from memory and then ends up
writing it out later, we avoid unnecessary byte swaps by not canonicalizing the
value immediately.<span style="mso-spacerun: yes">&nbsp; </span>Lazy constant
offsetting mitigates </p>
</div>
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
</span>
<div class=Section5>
<div style='mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-element-top:top;mso-height-rule:exactly'>
<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=center>
<tr>
<td valign=top align=left style='padding-top:9.0pt;padding-right:9.0pt;
padding-bottom:9.0pt;padding-left:9.0pt'>
<div style='border:solid windowtext .75pt;padding:0in 0in 0in 0in;background:
#E5E5E5;mso-shading:windowtext;mso-pattern:gray-10 auto'>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pea<span
style='mso-tab-count:2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>0x1<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pea<span
style='mso-tab-count:2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>0x2<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pea<span
style='mso-tab-count:2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>0x3<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pea<span
style='mso-tab-count:2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>0x4<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>...</p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'>becomes
this 80x86 code:</p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>_a7,%edi<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>$0x01000000,-4(%edi)<span
style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp; </span>; &quot;push&quot;
big-endian constant<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>$0x02000000,-8(%edi)<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>$0x03000000,-12(%edi)<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>$0x04000000,-16(%edi)<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>...
&lt;more uses of a7 may follow, and they'll use %edi&gt;<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>subl<span
style='mso-tab-count:1'>&nbsp; </span>$16,%edi<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>$edi,_a7<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>...</p>
<p class=MsoNormal align=center style='text-align:center;border:none;
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-element-top:top;mso-height-rule:exactly'><span style='font-size:
12.0pt'>Figure 2.<span style="mso-spacerun: yes">&nbsp; </span>Lazy Constant
Offsetting<o:p></o:p></span></p>
</div>
</td>
</tr>
</table>
</div>
</div>
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
</span>
<div class=Section6>
<p class=MsoNormal>the overhead of postincrement and predecrement side
effects.<span style="mso-spacerun: yes">&nbsp; </span>Figure 2 is an example of
lazy constant offsetting.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>As mentioned above, we use the 80x86 condition code bits as
a cache for the real 680x0 CC bits.<span style="mso-spacerun: yes">&nbsp;
</span>Although live cached CC bits are occasionally spilled back to memory
because some 80x86 instruction is about to clobber them, this trick almost
always works.<span style="mso-spacerun: yes">&nbsp; </span>Using 80x86 CC bits,
we can frequently get away with extremely concise code sequences; for example,
a 680x0 compare and conditional branch becomes an 80x86 compare and conditional
branch.</p>
<h3>Self-modifying Code</h3>
<p class=MsoNormal>Like most dynamically compiling emulators, Syn68k doesn't
detect self-modifying code; the overhead is too high.<span style="mso-spacerun:
yes">&nbsp; </span>Fortunately, self-modifying programs don't work on the real
68040 either.<span style="mso-spacerun: yes">&nbsp; </span>We rely on the
program making explicit system calls to flush the caches whenever 680x0 code
may have been modified or created.<span style="mso-spacerun: yes">&nbsp;
</span>Some programs (like HyperCard) flush the caches very often, which can
cause real performance headaches if code is continuously recompiled.<span
style="mso-spacerun: yes">&nbsp; </span>We have solved this problem by
checksumming 680x0 blocks as they are compiled and only decompiling blocks
which fail their checksums.<span style="mso-spacerun: yes">&nbsp; </span>This
optimization alone sped up some HyperCard stacks by a factor of three or so.</p>
<h3>Examples</h3>
<p class=MsoNormal>Figure 3 contains two sample 680x0 code sequences from real
applications, and the 80x86 code that Syn68k generates for them.<span
style="mso-spacerun: yes">&nbsp; </span>We chose these code sequences
specifically to showcase several of the techniques we use, so you shouldn't use
them as a substitute for benchmarks. Not all 680x0 code translates as well as
these examples do, but these examples are far from exotic.</p>
</div>
<span style='font-size:12.0pt;font-family:Helvetica;mso-ansi-language:EN-US'><b><br
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
</b></span>
<div class=Section7>
<div style='mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-height-rule:exactly'>
<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=center>
<tr>
<td valign=top align=left style='padding-top:9.0pt;padding-right:9.0pt;
padding-bottom:9.0pt;padding-left:9.0pt'>
<div style='border:solid windowtext .75pt;padding:0in 0in 0in 0in;background:
#E5E5E5;mso-shading:windowtext;mso-pattern:gray-10 auto'>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'>Example 1 (Solarian):</p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'>680x0 code:</p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>addqb<span
style='mso-tab-count:1'> </span>#1,a4@(1)<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movel<span
style='mso-tab-count:1'> </span>#0,d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>moveb<span
style='mso-tab-count:1'> </span>a4@,d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>swap<span
style='mso-tab-count:1'>&nbsp; </span>d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>clrw<span
style='mso-tab-count:1'>&nbsp; </span>d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>swap<span
style='mso-tab-count:1'>&nbsp; </span>d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>asll<span
style='mso-tab-count:1'>&nbsp; </span>#2,d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lea<span
style='mso-tab-count:1'>&nbsp;&nbsp; </span>a5@(-13462),a0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>addal<span
style='mso-tab-count:1'> </span>d0,a0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>moveal<span
style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>a0@,a0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movel<span
style='mso-tab-count:1'> </span>#0,d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>moveb<span
style='mso-tab-count:1'> </span>a4@(1),d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>cmpw<span
style='mso-tab-count:1'>&nbsp; </span>a0@,d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>bcs<span
style='mso-tab-count:1'>&nbsp;&nbsp; </span>0x3fffee2</span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'>80x86 code:</p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>_a4,%edi<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; addqb
#1,a4@(1)<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>addb<span
style='mso-tab-count:1'>&nbsp; </span>$0x1,0x1(%edi)<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>xorl<span
style='mso-tab-count:1'>&nbsp; </span>%ebx,%ebx<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; movel #0,d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movb<span
style='mso-tab-count:1'>&nbsp; </span>(%edi),%bl<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; moveb a4@,d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>rorl<span
style='mso-tab-count:1'>&nbsp; </span>$0x10,%ebx<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; swap d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>xorw<span
style='mso-tab-count:1'>&nbsp; </span>%bx,%bx<span style='mso-tab-count:2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;
clrw d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>rorl<span
style='mso-tab-count:1'>&nbsp; </span>$0x10,%ebx<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; swap d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>shll<span
style='mso-tab-count:1'>&nbsp; </span>$0x2,%ebx<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; asll #2,d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>_a5,%esi<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; lea
a5@(-13462),a0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>leal<span
style='mso-tab-count:1'>&nbsp; </span>0xffffcb6a(%esi),%edx<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>addl<span
style='mso-tab-count:1'>&nbsp; </span>%ebx,%edx<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; addal d0,a0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>(%edx),%edx<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; moveal a0@,a0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>xorl<span
style='mso-tab-count:1'>&nbsp; </span>%ebx,%ebx<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; movel #0,d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movb<span
style='mso-tab-count:1'>&nbsp; </span>0x1(%edi),%bl<span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp; </span>; moveb a4@(1),d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>bswap<span
style='mso-tab-count:1'> </span>%edx<span style='mso-tab-count:3'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;
cmpw a0@,d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movw<span
style='mso-tab-count:1'>&nbsp; </span>(%edx),%cx<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>rorw<span
style='mso-tab-count:1'>&nbsp; </span>$0x8,%cx<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>cmpw<span
style='mso-tab-count:1'>&nbsp; </span>%cx,%bx<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>%edx,_a0<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; &lt;spill
dirty 68k<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>%ebx,_d0<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;<span
style="mso-spacerun: yes">&nbsp; </span>registers back to memory&gt;<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>jb<span
style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp; </span>0x6fae0c<span
style='mso-tab-count:2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;
bcs 0x3fffee2<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>jmp<span
style='mso-tab-count:1'>&nbsp;&nbsp; </span>0x6faf0c<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; &lt;go to
&quot;fall through&quot; code&gt;</span></p>
</div>
</td>
</tr>
</table>
</div>
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
clear=ALL style='page-break-before:always'>
</span>
<div style='mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-element-top:top;mso-height-rule:exactly'>
<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=center>
<tr>
<td valign=top align=left style='padding-top:9.0pt;padding-right:9.0pt;
padding-bottom:9.0pt;padding-left:9.0pt'>
<div style='border:solid windowtext .75pt;padding:0in 0in 0in 0in;background:
#E5E5E5;mso-shading:windowtext;mso-pattern:gray-10 auto'>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'>Example
2 (PageMaker):</p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'>680x0
code:</p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movel<span
style='mso-tab-count:1'> </span>#0,d2<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>moveb<span
style='mso-tab-count:1'> </span>d0,d2<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lslw<span
style='mso-tab-count:1'>&nbsp; </span>#8,d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>orw<span
style='mso-tab-count:1'>&nbsp;&nbsp; </span>d0,d2<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movel<span
style='mso-tab-count:1'> </span>d2,d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>swap<span
style='mso-tab-count:1'>&nbsp; </span>d2<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>orl<span
style='mso-tab-count:1'>&nbsp;&nbsp; </span>d2,d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movel<span
style='mso-tab-count:1'> </span>a0,d2<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lsrb<span
style='mso-tab-count:1'>&nbsp; </span>#1,d2<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>bcc<span
style='mso-tab-count:1'>&nbsp;&nbsp; </span>0x3fffed4</span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'>80x86
code:</p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>xorl<span
style='mso-tab-count:1'>&nbsp; </span>%ebx,%ebx<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; movel #0,d2<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>_d0,%edx<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; moveb
d0,d2<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movb<span
style='mso-tab-count:1'>&nbsp; </span>%dl,%bl<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>shlw<span
style='mso-tab-count:1'>&nbsp; </span>$0x8,%dx<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; lslw #8,d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>orw<span
style='mso-tab-count:1'>&nbsp;&nbsp; </span>%dx,%bx<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; orw
d0,d2<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>%ebx,%edx<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; movel d2,d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>rorl<span
style='mso-tab-count:1'>&nbsp; </span>$0x10,%ebx<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; swap d2<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>orl<span
style='mso-tab-count:1'>&nbsp;&nbsp; </span>%ebx,%edx<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; orl d2,d0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>_a0,%ecx<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; movel
a0,d2<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>%ecx,%ebx<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>shrb<span
style='mso-tab-count:1'>&nbsp; </span>%bl<span style='mso-tab-count:3'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;
lsrb #1,d2<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>%ebx,_d2<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; &lt;spill dirty
68k<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>%edx,_d0<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;<span
style="mso-spacerun: yes">&nbsp; </span>registers back to memory&gt;<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>jae<span
style='mso-tab-count:1'>&nbsp;&nbsp; </span>0x3b734c<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; bcc
0x3fffed4<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>jmp<span
style='mso-tab-count:1'>&nbsp;&nbsp; </span>0x43d48c<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; &lt;go to
&quot;fall through&quot; 68k code&gt;<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
style='font-family:Courier'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
<p class=MsoNormal align=center style='text-align:center;border:none;
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-element-top:top;mso-height-rule:exactly'><span style='font-size:
12.0pt'>Figure 3.<span style="mso-spacerun: yes">&nbsp; </span>680x0 -&gt; 80x86
examples<o:p></o:p></span></p>
</div>
</td>
</tr>
</table>
</div>
</div>
<span style='font-size:12.0pt;font-family:Helvetica;mso-ansi-language:EN-US'><b><br
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
</b></span>
<div class=Section8>
<h2>Graphics</h2>
<h3>SVGA Graphics</h3>
<p class=MsoNormal>The DOS world is one of standards.<span style="mso-spacerun:
yes">&nbsp; </span><i>Many</i><span style='font-style:normal'> standards.<span
style="mso-spacerun: yes">&nbsp; </span>Standards made by engineers who were
even more short-sighted than the folks who brought you ROM85, only to be
replaced by SysEnvirons which was then replaced by Gestalt.<span
style="mso-spacerun: yes">&nbsp; </span>The first color graphics adapter for
the PC (CGA) was replaced with EGA, which was then replaced by VGA, which
eventually gave way to several different Super Video Graphics Array (SVGA)
cards.</span></p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>SVGA cards have a couple of properties that make them less
than perfect targets for the output of Macintosh emulators.<span
style="mso-spacerun: yes">&nbsp; </span>First, the default is for SVGA's video
memory to only be mapped into the PC address space through a 64k window (or
bank).<span style="mso-spacerun: yes">&nbsp; </span>If you want to display
640x480x8 bits you need to write 64k of information to the 64k screen address
range, then tell the video card that you want that same address to represent a
different 64k chunk of the screen, then you write to that address range again,
then you switch banks again, and so forth.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The second major complication is that under DPMI, the
address space that contains the SVGA video memory is not in the same address space
that a 32-bit application uses.<span style="mso-spacerun: yes">&nbsp;
</span>For those of you used to programming in a flat address space, it might
be hard to believe that you need special machine language address space
overriding prefixes to access screen memory, but under DPMI 0.9 (which is the
version of DPMI that Microsoft supports; we wouldn't have to do this under 1.0)
&quot;selector&quot; overrides really are necessary.</p>
<span style='font-size:12.0pt;font-family:Palatino;mso-ansi-language:EN-US'><b><br
clear=ALL style='mso-column-break-before:always'>
</b></span>
<h3>Blitter Overview</h3>
<p class=MsoNormal>A Region is a data structure that describes a set of
pixels.<span style="mso-spacerun: yes">&nbsp; </span>Regions can be created by
the application by calling various MacOS toolbox routines.<span
style="mso-spacerun: yes">&nbsp; </span>In addition the toolbox routines
themselves sometimes create Regions for their own purposes.<span
style="mso-spacerun: yes">&nbsp; </span></p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>A blitter is a set of software or hardware which takes sets
of bits, representing pixels, and combines them with other sets of bits in a
variety of different ways.<span style="mso-spacerun: yes">&nbsp; </span>A
Region blitter is a blitter that processes pixels by Regions (rather than by
rectangles or rectangle lists).</p>
<h3>A Simple Blitter </h3>
<p class=MsoNormal>One way to write a simple Region blitter is to start with a
subroutine that parses the start/stop pairs of a Region scanline and draws the
corresponding pixels.<span style="mso-spacerun: yes">&nbsp; </span>This
subroutine is then called once for each row of pixels to be displayed.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Unfortunately, this approach is slow since each scanline
gets re-parsed every time it is drawn.<span style="mso-spacerun: yes">&nbsp;
</span>The Region for a 300 pixel tall rectangle consists of a single scanline
with a repeat count of &quot;300&quot;; this &quot;simple Region blitter&quot;
will parse that scanline 300 times! That's a lot of redundant work.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>There are many possible ways to get away with parsing each
scanline only once.<span style="mso-spacerun: yes">&nbsp; </span>One approach
is to convert the start/stop pairs into a bit mask where the bits in the mask
correspond to the bits in the target bitmap that are to be changed.<span
style="mso-spacerun: yes">&nbsp; </span>The inner blitting loop then becomes an
exercise in bitwise arithmetic.<span style="mso-spacerun: yes">&nbsp; </span>In
C, such a loop might look something like this:<span style='font-family:Courier'><o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>for (x = left; x &lt;
right; x++)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>dst[x] = (dst[x] &amp; ~mask[x]) <o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>| (pattern_value &amp; mask[x]);<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
<p class=MsoNormal>That's not bad, but we can do better.</p>
<h3>A Dynamically Recompiling Blitter </h3>
<p class=MsoNormal>Using an explicit bit mask array is unnecessarily slow in
the common case of filling a rectangle.<span style="mso-spacerun: yes">&nbsp;
</span>For a rectangular Region, mask[x] is usually all one bits, making the
bit munging a waste of time.<span style="mso-spacerun: yes">&nbsp; </span>And
even when the masks are never solid (e.g. when drawing a thin vertical line),
this technique is still unnecessarily slow.<span style="mso-spacerun:
yes">&nbsp; </span>As it turns out, even the cycles the CPU spends loading mask
bits from memory are unnecessary.<span style="mso-spacerun: yes">&nbsp;
</span>Furthermore, even if we were satisfied with the level of performance
that C code like the above provides, we couldn't use it on a stock SVGA system
because it wouldn't know how to access the SVGA portion of memory.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Executor's blitter uses the techniques of partial evaluation
and dynamic code generation to eliminate redundant work and also give us access
to SVGA memory.<span style="mso-spacerun: yes">&nbsp; </span>On the 80x86 each
scanline is quickly translated into executable code, and that code gets
executed once each time the scanline needs to be drawn.<span
style="mso-spacerun: yes">&nbsp; </span>On non-80x86 platforms, each scanline
is compiled into threaded code which is executed by a machine-generated interpreter
to draw the scanlines.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Before describing how the dynamic compilation process works,
let's take a look at an example.<span style="mso-spacerun: yes">&nbsp;
</span>Consider the case where a 401x300 rectangle is to be filled with white
pixels (pixel value zero on the Macintosh).<span style="mso-spacerun:
yes">&nbsp; </span>This might happen, for example, when erasing a window.
Furthermore, let's assume that the target bitmap has four bits per pixel, since
that's somewhat tricker to handle than 8 bits per pixel.<span
style="mso-spacerun: yes">&nbsp; </span>Figure 4 shows the subroutine that
Executor dynamically generates to draw this rectangle on a Pentium.</p>
</div>
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
</span>
<div class=Section9>
<div style='mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-element-top:bottom;mso-height-rule:exactly'>
<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=center>
<tr>
<td valign=top align=left style='padding-top:9.0pt;padding-right:9.0pt;
padding-bottom:9.0pt;padding-left:9.0pt'>
<div style='border:solid windowtext .75pt;padding:0in 0in 0in 0in;background:
#E5E5E5;mso-shading:windowtext;mso-pattern:gray-10 auto'>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'>loop:<span style='mso-tab-count:1'> </span>andl<span
style='mso-tab-count:1'>&nbsp; </span>$0xff,0x50(%edi)<span style='mso-tab-count:
1'>&nbsp; </span><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;
clear leftmost 6 boundary pixels<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>addl<span
style='mso-tab-count:1'>&nbsp; </span>$0x54,%edi<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; set up pointer for loop<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span
style='mso-tab-count:1'>&nbsp; </span>$0x31,%ecx<span style='mso-tab-count:
2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; set up loop counter<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>rep<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>stosl<span
style='mso-tab-count:3'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span
style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span
style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; slam out 49
aligned longs<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>andl<span
style='mso-tab-count:1'>&nbsp; </span>$0xffff0f00,0x0(%edi)<span
style='mso-tab-count:1'>&nbsp;&nbsp; </span>; clear 3 right boundary pixels<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>addl<span
style='mso-tab-count:1'>&nbsp; </span>$0x28,%edi<span style='mso-tab-count:
3'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;
move to next row<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>decl<span
style='mso-tab-count:1'>&nbsp; </span>%edx<span style='mso-tab-count:4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;
decrement # of rows left<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>jne<span
style='mso-tab-count:1'>&nbsp;&nbsp; </span>loop<span style='mso-tab-count:
4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;
continue looping if appropriate<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ret<span
style='mso-tab-count:5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;
we're done!<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
<p class=MsoNormal align=center style='text-align:center;border:none;
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-size:12.0pt'>Figure 4.<span style="mso-spacerun: yes">&nbsp;
</span>Dynamically generated blitting code</span></p>
</div>
</td>
</tr>
</table>
</div>
</div>
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
</span>
<div class=Section10>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
clear=ALL style='mso-column-break-before:always'>
<br clear=ALL style='mso-column-break-before:always'>
</span>
<p class=MsoNormal>This code, when called with the proper values in its input
registers, will draw the entire rectangle.<span style="mso-spacerun:
yes">&nbsp; </span>Note how the inner loop is merely a</p>
<p class=MsoNormal>&quot;<span style='font-family:Courier'>rep ; stosl</span>&quot;...it
doesn't get much more concise than that!<span style="mso-spacerun: yes">&nbsp;
</span>The astute reader will know that on certain 80x86 processors &quot;rep ;
stosl&quot; is not the fastest possible way to set a range of memory.<span
style="mso-spacerun: yes">&nbsp; </span>This is true, but because our code
generation is dynamic, in the future we can tailor the specific code sequence
generated to the processor on which Executor is currently running.<span
style="mso-spacerun: yes">&nbsp; </span>The blitter already does this when it
needs to emit a byte swap; on the 80486 and up we use the &quot;bswap&quot;
instruction, and on the 80386 (which doesn't support &quot;bswap&quot;) we use
a sequence of rotates.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>One thing you may notice in this example is that the bit
masks used to clear the boundary pixels look strange.<span style="mso-spacerun:
yes">&nbsp; </span>They are actually correct, since 80x86 processors are little
endian.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Unlike some processors, such as the 68040, the 80x86
instruction and data caches are always coherent.<span style="mso-spacerun:
yes">&nbsp; </span>Consequently, no cache flushes need to be performed before
the dynamically created code can be executed.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Figure 5 contains another example, this time drawn from a
real application.<span style="mso-spacerun: yes">&nbsp; </span>The program
&quot;Globe&quot;, by Paul Mercer, draws a spinning globe </p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>on the screen as fast as it can.<span style="mso-spacerun:
yes">&nbsp; </span>Each &quot;globe frame&quot; is a 128x128 Pixmap.<span
style="mso-spacerun: yes">&nbsp; </span>Here is the code that Executor
generates and runs when Globe uses CopyBits to transfer one frame to the screen
at 8 bits per pixel.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Again the inner loop is very tight, just a &quot;rep ;
movsl&quot; this time.</p>
<span style='font-size:12.0pt;font-family:Palatino;mso-ansi-language:EN-US'><b><br
clear=ALL style='mso-column-break-before:always'>
</b></span>
<h3>Meta-Assembler </h3>
<p class=MsoNormal>No matter how fast the generated code, if Executor spends
too much time generating that code then any speedup will be negated by the
increased time required for dynamic compilation.<span style="mso-spacerun:
yes">&nbsp; </span>Consequently, the dynamic compilation from Region to 80x86
code needs to be fast. We solved this problem with a &quot;meta-assembler&quot;
written in Perl.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Whereas an assembler tells a computer how to translate
assembly instructions into machine code, our meta-assembler tells the computer
how to generate tiny translators.<span style="mso-spacerun: yes">&nbsp;
</span>These translators will then be used to translate pixel manipulation requests
into machine code.<span style="mso-spacerun: yes">&nbsp; </span>Another way of
looking at it is that the meta-assembler generates code that generates code.<span
style="mso-spacerun: yes">&nbsp; </span>This meta-assembly process is done only
once:<span style="mso-spacerun: yes">&nbsp; </span>when Executor is compiled.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The blitter operates on aligned longs in the destination
bitmap.<span style="mso-spacerun: yes">&nbsp; </span>As the compilation engine
strides through the scanline's start/stop pairs from left to right, it identifies
which bits in each long are part of the Region and determines which of several pixel
manipulation requests to issue to the tiny translators that were created by the
meta-assembler.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>&#8226; Some
but not all bits in the current long are in the Region.</p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>&#8226; All
bits in the current long are in the Region.</p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>&#8226; All
bits in this long and the next long are in the Region.</p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>&#8226; All
bits in this long and the next two longs are in the Region.</p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>&#8226; All
bits in this long and the next three longs are in the Region.</p>
</div>
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
</span>
<div class=Section11>
<div style='mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-element-top:bottom;mso-height-rule:exactly'>
<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=center>
<tr>
<td valign=top align=left style='padding-top:9.0pt;padding-right:9.0pt;
padding-bottom:9.0pt;padding-left:9.0pt'>
<div style='border:solid windowtext .75pt;padding:0in 0in 0in 0in;background:
#E5E5E5;mso-shading:windowtext;mso-pattern:gray-10 auto'>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'>loop:<span style='mso-tab-count:1'> </span>movl<span
style="mso-spacerun: yes">&nbsp;&nbsp; </span>$0x20,%ecx<span
style='mso-tab-count:2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; set up
loop counter for 32 longs<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>rep<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movsl<span
style='mso-tab-count:2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span
style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span
style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; copy one row
(128 bytes)<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>addl<span
style="mso-spacerun: yes">&nbsp;&nbsp; </span>$0xffffff00,%esi<span
style='mso-tab-count:1'> </span>; advance to previous src row<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>addl<span
style="mso-spacerun: yes">&nbsp;&nbsp; </span>$0xfffffd00,%edi<span
style='mso-tab-count:1'> </span>; advance to previous dst row<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>decl<span
style="mso-spacerun: yes">&nbsp;&nbsp; </span>%edx<span style='mso-tab-count:
3'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;
decrement # of rows remaining<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>jne<span
style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>loop<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ret<o:p></o:p></span></p>
<p class=MsoNormal align=center style='text-align:center;border:none;
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-element-top:bottom;mso-height-rule:exactly'><span
style='font-size:12.0pt'>Figure 5.<span style="mso-spacerun: yes">&nbsp;
</span>Blitting code from Globe</span></p>
</div>
</td>
</tr>
</table>
</div>
</div>
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
</span>
<div class=Section12><br clear=ALL style='mso-column-break-before:always'>
<br clear=ALL style='mso-column-break-before:always'>
<p class=MsoNormal style='margin-left:.25in;text-indent:-9.0pt'>&#8226; More
than four contiguous longs are</p>
<p class=MsoNormal style='margin-left:27.0pt'>completely in the Region, and the
number of longs equals 0 mod 4.</p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>&#8226; More
than four contiguous longs are completely in the Region, and the number of
longs equals 1 mod 4.</p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>&#8226; More
than four contiguous longs are completely in the Region, and the number of
longs equals 2 mod 4.</p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>&#8226; More
than four contiguous longs are completely in the Region, and the number of
longs equals 3 mod 4.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The particular case encountered determines which function
pointer to load from a lookup table corresponding to the current drawing mode.
For example, the &quot;patCopy&quot; drawing mode has one table of function
pointers, &quot;patXor&quot; another.<span style="mso-spacerun: yes">&nbsp;
</span>There are also some special case tables for drawing patterns that are
either all zero bits or all one bits.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The main blitter doesn't care what drawing mode is being
used, since it does all mode-specific work through the supplied function
pointer table.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Each function pointer points to a function that generates
80x86 code for the appropriate case.<span style="mso-spacerun: yes">&nbsp;
</span>For example, one function generates code for a &quot;patCopy&quot; to
three contiguous longs, one generates code for &quot;patXor&quot; only to
certain specified bits within one long, etc.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The blitter compilation engine marches through the Region
scanline from left to right, calling code generation functions as it goes.<span
style="mso-spacerun: yes">&nbsp; </span>The generated code is accrued into a
32-byte aligned buffer on the stack. In this way, the blitter constructs a
subroutine to draw the Region.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The compilation engine isn't very complicated.<span
style="mso-spacerun: yes">&nbsp; </span>The tricky part is the numerous
generation subroutines, which need to be fast since they are called so often
and need to be easy to write since there are so many of them. For each drawing
mode there's one for each case the compilation engine cares about.<span
style="mso-spacerun: yes">&nbsp; </span>For pattern drawing modes, there are
separate specialized subroutines for cases like patterns that can be entirely
expressed in one 32-bit value (&quot;short/narrow&quot;) patterns, patterns
which can be expressed as one 32-bit value for each row, but which vary per row
(&quot;tall/narrow&quot;), as well as &quot;wide&quot; variants of both. Beyond
that, there are some versions specialized for 80486 and higher processors (which
have the &quot;bswap&quot; instruction).</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Generating fast and robust code generators is where the Perl
meta-assembler comes into play.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The meta-assembler takes as input an assembly language
template, and generates as output Pentium-scheduled assembly code that outputs
an 80x86 binary for the input template.<span style="mso-spacerun: yes">&nbsp;
</span>This process only takes place when Executor is compiled.<span
style="mso-spacerun: yes">&nbsp; </span>Got it?<span style="mso-spacerun:
yes">&nbsp; </span>This can be a little confusing, so a few examples are in
order.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Here is perhaps the simplest template:</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>@meta copy_short_narrow_1<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span style='mso-tab-count:1'>&nbsp; </span>%eax,@param_offset@(%edi)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>@endmeta<o:p></o:p></span></p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>This template describes what should be done when the blitter
wants to write one long to memory.<span style="mso-spacerun: yes">&nbsp;
</span>The meta-assembler processes that into this 80x86 assembly code which is
to be called by the blitter compilation engine:</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.align<span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>4,0x90<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>_xdblt_copy_short_narrow_1:<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movw<span style='mso-tab-count:1'>&nbsp; </span>$0x8789,(%edi)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span style='mso-tab-count:1'>&nbsp; </span>%eax,2(%edi)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>addl<span style='mso-tab-count:1'>&nbsp; </span>$6,%edi<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ret<o:p></o:p></span></p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The subroutine that the meta-assembler has produced above,
when executed, will generate the movl instruction (i.e. the movl instruction in
the template) followed by its argument. <span style="mso-spacerun:
yes">&nbsp;&nbsp;</span>The meta-assembler has deduced that &quot;movl&quot; in
the example template is 80x86 opcode 0x8789. <span style="mso-spacerun:
yes">&nbsp;&nbsp;</span></p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
clear=ALL style='mso-column-break-before:always'>
</span>
<p class=MsoNormal>Let's take a look at a more complicated template.<span
style="mso-spacerun: yes">&nbsp; </span>This template handles the case where we
want to bitwise OR a pattern to the destination bitmap, and the number of longs
to transfer equals zero mod 4 (e.g. if the blitter wants to OR 36 longs to
memory):</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal><span style='font-family:Courier'>@meta
or_short_narrow_many_mod_0<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>addl<span style='mso-tab-count:1'>&nbsp; </span>$@param_offset@,%edi<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span style='mso-tab-count:1'>&nbsp; </span>$@param_l_cnt_div_4@,%ecx<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>1:<span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp; </span>orl<span style='mso-tab-count:1'>&nbsp;&nbsp; </span>%eax,(%edi)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>orl<span style='mso-tab-count:1'>&nbsp;&nbsp; </span>%eax,4(%edi)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>orl<span style='mso-tab-count:1'>&nbsp;&nbsp; </span>%eax,8(%edi)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>orl<span style='mso-tab-count:1'>&nbsp;&nbsp; </span>%eax,12(%edi)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>addl<span style='mso-tab-count:1'>&nbsp; </span>$16,%edi<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>decl<span style='mso-tab-count:1'>&nbsp; </span>%ecx<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>jnz<span style='mso-tab-count:1'>&nbsp;&nbsp; </span>1b<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>@lit<span
style='mso-tab-count:1'>&nbsp; </span>leal<span style='mso-tab-count:1'>&nbsp; </span>(%eax,%edx,4),%ecx<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>@lit<span
style='mso-tab-count:1'>&nbsp; </span>addl<span style='mso-tab-count:1'>&nbsp; </span>%ecx,edi_offset<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>@endmeta<o:p></o:p></span></p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The meta-assembler compiles that to this:</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.align<span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>4,0x90<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>_xdblt_or_short_narrow_many_mod_0:<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movw<span style='mso-tab-count:1'>&nbsp; </span>$0xC781,(%edi)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span style='mso-tab-count:1'>&nbsp; </span>%eax,2(%edi)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span style='mso-tab-count:1'>&nbsp; </span>$0x47090709,11(%edi)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movb<span style='mso-tab-count:1'>&nbsp; </span>$0xB9,6(%edi)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span style='mso-tab-count:1'>&nbsp; </span>$0x8470904,15(%edi)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span style='mso-tab-count:1'>&nbsp; </span>$0x754910C7,23(%edi)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span style='mso-tab-count:1'>&nbsp; </span>$0x830C4709,19(%edi)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movb<span style='mso-tab-count:1'>&nbsp; </span>$0xEF,27(%edi)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span style='mso-tab-count:1'>&nbsp; </span>%edx,%ecx<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>shrl<span style='mso-tab-count:1'>&nbsp; </span>$2,%ecx<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>movl<span style='mso-tab-count:1'>&nbsp; </span>%ecx,7(%edi)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>addl<span style='mso-tab-count:1'>&nbsp; </span>$28,%edi<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>leal<span style='mso-tab-count:1'>&nbsp; </span>(%eax,%edx,4),%ecx<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>addl<span style='mso-tab-count:1'>&nbsp; </span>%ecx,edi_offset<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ret<o:p></o:p></span></p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>This mechanically generated subroutine generates the
executable 80x86 binary for the &quot;or_short_narrow_many_mod_0&quot;
template.<span style="mso-spacerun: yes">&nbsp; </span>It gets called by the
blitter compilation engine when it needs code to OR a bunch of longs to memory.<span
style="mso-spacerun: yes">&nbsp; </span></p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The output of the meta-assembler isn't meant for human
consumption.<span style="mso-spacerun: yes">&nbsp; </span>As such, the output
contains a hodge-podge of magic numbers (<span style='font-family:Courier'>0x47090709,
0xB9, 0x8470904,</span> etc.).<span style="mso-spacerun: yes">&nbsp;
</span>These numbers are fixed machine code values corresponding to opcodes, constant
operands, and other values.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Even though this subroutine is longer than the previous
example, it still doesn't take very long to execute.<span style="mso-spacerun:
yes">&nbsp; </span>Furthermore, it only gets called when the blitter has
determined that many longs are to be ORed to memory, so the time taken actually
blitting to memory will typically dwarf the time taken to execute these 15 code
generation instructions.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The meta-assembler is a Perl script that works by running
numerous syntactically modified versions of the assembly template through
&quot;gas&quot;, the GNU assembler, and examining the output bytes to discover
which bits are fixed opcode bits and which bits correspond to operands.<span
style="mso-spacerun: yes">&nbsp; </span>Once it has figured out what goes
where, it generates 80x86 assembly code which writes out the constant bytes and
computes and writes out the operand bytes.<span style="mso-spacerun:
yes">&nbsp; </span>That code is run through a simple Pentium instruction
scheduler and the meta-assembler is done.<span style="mso-spacerun: yes">&nbsp;
</span>This entire process is, of course, done only once, when Executor is
compiled.</p>
<h3>A Portable Dynamically Recompiling Blitter</h3>
<p class=MsoNormal>Although the meta-assembler-based blitter works only on
80x86 processors, Executor itself can run on non-Intel processors.<span
style="mso-spacerun: yes">&nbsp; </span>On other CPUs (such as the 68040 used
in the NeXTstation) Executor's blitter works somewhat differently.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The basic idea is still the same: translate Region scanlines
into an efficient form once and then use that efficient form each time the
scanline gets drawn.<span style="mso-spacerun: yes">&nbsp; </span>This time,
however, the &quot;efficient form&quot; is processor independent, and the
blitter is written entirely in C.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>As is the case with the 80x86-specific blitter, the portable
blitter compilation engine examines scanline start/stop pairs and identifies
which of several cases is appropriate.<span style="mso-spacerun: yes">&nbsp;
</span>One case is &quot;output three longs&quot;, another is &quot;output only
certain pixels within the current long&quot;, and so on.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Like the 80x86-specific blitter, the particular case
encountered determines which entry in a lookup table will be used.<span
style="mso-spacerun: yes">&nbsp; </span>But there the similarity ends.<span
style="mso-spacerun: yes">&nbsp; </span>The lookup tables contain pointers to C
code labels<a style='mso-footnote-id:ftn1' href="#_ftn1" name="_ftnref1"
title=""><span class=MsoFootnoteReference><span style='mso-special-character:
footnote'><![if !supportFootnotes]>[1]<![endif]></span></span></a> rather than
to routines that generates 80x86 code on the fly.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Each scanline gets translated into an array of opcodes for
the &quot;blitter opcode interpreter&quot; (which will be described
below).<span style="mso-spacerun: yes">&nbsp; </span>Each opcode is stored in
one of these C structs:</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal><span style='font-family:Courier'>struct<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>{<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>/* Pointer to C code to handle<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp;&nbsp; </span>this opcode. */<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>const void *label;<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>/* Offset into scanline */<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>int32 offset;<span style='mso-tab-count:2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>/* Extra operand with<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp;&nbsp; </span>different uses. */<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>int32 arg;<span style='mso-tab-count:2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>};<o:p></o:p></span></p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>For example, consider the case where the blitter wants to
write out five contiguous longs from a &quot;simple&quot; pattern starting 64
bytes into the current row.<span style="mso-spacerun: yes">&nbsp; </span>In
this case, &quot;label&quot; would equal
&quot;&amp;&amp;copy_short_narrow_many_5&quot;, &quot;offset&quot; would equal
64, and &quot;arg&quot; would equal 5.</p>
<h3>The Blitter Opcode Interpreter</h3>
<p class=MsoNormal>The blitter opcode interpreter is machine generated C code
created by a Perl script when Executor is compiled.<span style="mso-spacerun:
yes">&nbsp; </span>That Perl script takes as input C code snippets that tell it
how to handle particular drawing modes, and produces as output C code for an
interpreter.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Here is the template taken as input by the Perl script for
the &quot;copy_short_narrow&quot; case.<span style="mso-spacerun: yes">&nbsp;
</span>This is the simple case where the pixels for the pattern being displayed
can be stored entirely within one 32-bit long (for example, solid white or
solid black).</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal><span style='font-family:Courier'>begin_mode cpy_shrt_narrow
max_unwrap<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;</span>repeat<span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp; </span>@dst@
= v;<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;</span>mask<span style='mso-tab-count:1'> </span><span
style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>@dst@ = (@dst@
&amp; ~arg)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
3'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|
(v &amp; arg);<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>end_mode<o:p></o:p></span></p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The &quot;<span style='font-family:Courier'>repeat</span>&quot;
field tells the Perl script what C code to generate for the simple case where
all pixels in the destination long are to be affected.<span
style="mso-spacerun: yes">&nbsp; </span>The &quot;mask&quot; case tells it what
to do when it must only modify certain bits in the target long and must leave
others alone.<span style="mso-spacerun: yes">&nbsp; </span>Max_unwrap tells the
Perl script to unroll the new blitting loop.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The generated interpreter takes as input an array of blitter
opcode structs, which it then proceeds to interpret once for each row to be
drawn.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Here is the section of the (machine-generated) interpreter
that handles the copy_short_narrow cases.<span style="mso-spacerun: yes">&nbsp;
</span>Remember that each &quot;blitter opcode&quot; is really just a pointer
to one of these C labels.<span style="mso-spacerun: yes">&nbsp; </span>This
code would get used when filling a rectangle with a solid color.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_mask:<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>*dst = (*dst &amp; ~arg) | (v &amp; arg);<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>JUMP_TO_NEXT;<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_loop:<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>dst += 8;<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_8:<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>dst[0] = v;<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_7:<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>dst[1] = v;<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_6:<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>dst[2] = v;<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_5:<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>dst[3] = v;<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_4:<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>dst[4] = v;<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_3:<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>dst[5] = v;<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_2:<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>dst[6] = v;<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_1:<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>dst[7] = v;<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>if ((arg -= 8) &gt; 0)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>goto copy_short_narrow_many_loop;<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp; </span>JUMP_TO_NEXT;<o:p></o:p></span></p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Note how the inner blitting loop is &quot;unwrapped&quot;
for speed.<span style="mso-spacerun: yes">&nbsp; </span>A blitter opcode would
specify that 39 longs are to be output by making its &quot;arg&quot; field be
39 and the &quot;label&quot; field point to &quot;copy_short_narrow_many_7&quot;,
in the middle of the unwrapped loop (39 mod 8 equals 7).<span
style="mso-spacerun: yes">&nbsp; </span>The interpreter would jump there and
loop until all of the pixels had been written out, at 32 bytes per loop
iteration.<span style="mso-spacerun: yes">&nbsp; </span>This is very fast,
especially for portable code.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Of course, if any other pixels needed to be drawn, there
would be additional blitter opcode structs telling the interpreter what to do.
The interpreter dispatches to the next opcode by executing the
&quot;JUMP_TO_NEXT&quot; macro, which automatically uses GCC's &quot;goto void
*&quot; extension to &quot;goto&quot; the C label that handles the next opcode.</p>
<h1>Development Tools</h1>
<h2>Free Software</h2>
<p class=MsoNormal>It is true that ARDI has a very tight R&amp;D budget, but we
really don't skimp on the tools that we use to build Executor.<span
style="mso-spacerun: yes">&nbsp; </span>We use free software to develop
Executor because we like to push the tools that we use very hard and the only
way we can do that and still sleep at night is when we know that if we find
bugs in our tools that they can be fixed quickly.<span style="mso-spacerun:
yes">&nbsp; </span>With free software the worst case is to fix bugs ourselves,
and that worst case is actually much better than the average case with non-free
software where you report a bug and pray for a patch.<span style="mso-spacerun:
yes">&nbsp; </span>In reality it's rare that we even have to resort to the
worst case since bugs reported are often fixed in less than a day.</p>
<h3>GCC</h3>
<p class=MsoNormal>GCC is the Free Software Foundation's C compiler.<span
style="mso-spacerun: yes">&nbsp; </span>It produces good code and has a
powerful inline assembly syntax that allows optimization to be done on the
expressions in the inline assembly without the optimization ruining the
assembly you've written.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Another handy GCC extension is &quot;<span style='font-family:
Courier'>typeof</span>&quot; which can be used in macros to cast a value to the
type of a different value.<span style="mso-spacerun: yes">&nbsp; </span>The
combination of powerful inline assembly and typeof allows us to have efficient
macros that swap bytes in a 16 bit or 32 bit quantity.<span
style="mso-spacerun: yes">&nbsp; </span>Since the Mac and PC are of different
endianness, quick byte swapping routines are very important.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>As mentioned above in our synthetic CPU and portable blitter
descriptions, we also use GCC's ability to take the address of a label and
store it in a variable so that we can produce our own threaded code on the fly.</p>
<h3>Hacked GCC</h3>
<p class=MsoNormal>Because the source to GCC is available, it is possible,
although not necessarily advisable, to hack in custom extensions.<span
style="mso-spacerun: yes">&nbsp; </span>At ARDI we've done this twice in the
past.<span style="mso-spacerun: yes">&nbsp; </span>At one time we used a set of
locally written modifications to support the pascal keyword so that we could
automatically call functions using Pascal calling conventions.<span
style="mso-spacerun: yes">&nbsp; </span>At the same time we also supported '<span
style='font-family:Courier'>1234'</span> (i.e. the ability to construct a
32-bit quantity out of four character constants inside apostrophes).<span
style="mso-spacerun: yes">&nbsp; </span><span style="mso-spacerun:
yes">&nbsp;&nbsp;</span>Eventually we decided that we didn't get enough benefit
from these extensions to make it worth patching new versions of GCC as they
came out.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The other time we modified GCC was when we were porting
Executor to DEC's Alpha processor.<span style="mso-spacerun: yes">&nbsp;
</span>We were doing this under OSF/1 which uses 64-bit pointers.<span
style="mso-spacerun: yes">&nbsp; </span>Since Executor needs to use the same
internal representation that Macs use, we wanted a way to easily write 32-bit
pointers to memory in such a way that they would be extended to 64-bits when
they were read into a register for use.<span style="mso-spacerun: yes">&nbsp;
</span>To do this we made GCC support &quot;pointer bit fields&quot;, a logical
extension that allowed bit-field notation to be used when specifying
pointers.<span style="mso-spacerun: yes">&nbsp; </span>At that time we didn't
have a resident GCC expert, so we were lucky that such modifications basically
consisted in taking out a few checks that disallowed such constructs.<span
style="mso-spacerun: yes">&nbsp; </span>Once those checks were removed, pointer
bit-fields, &quot;just worked&quot;.</p>
<h3>DJGPP</h3>
<p class=MsoNormal>DJGPP is DJ Delorie's (see <span style='font-family:Courier'>http://www.delorie.com</span>)
port of GCC to MSDOS.<span style="mso-spacerun: yes">&nbsp; </span>It allows
DOS users to compile UNIX programs under DOS and to run them with little or no
modification.<span style="mso-spacerun: yes">&nbsp; </span>DJGPP is GCC and
associated development tools with a special UNIX like C-library and a &quot;DOS
Extender&quot;.<span style="mso-spacerun: yes">&nbsp; </span>DOS extenders are
used to combat OS inferiority.<span style="mso-spacerun: yes">&nbsp; </span>DOS
is a 16-bit OS, whereas most relatively modern OSes are 32-bit.<span
style="mso-spacerun: yes">&nbsp; </span>DOS extenders allow 32-bit programs to
run under DOS.<span style="mso-spacerun: yes">&nbsp; </span>Executor is one
such program.<span style="mso-spacerun: yes">&nbsp; </span>In fact, we use the
djgpp libraries and DOS extender but we don't actually use the DOS port of GCC,
because we don't like DOS.<span style="mso-spacerun: yes">&nbsp; </span>We like
Linux and GCC is well structured so we can do cross-compilation and
cross-linking with the djgpp libraries and build our DOS product under
Linux.<span style="mso-spacerun: yes">&nbsp; </span>We completely compile the DOS
version of Executor under Linux.<span style="mso-spacerun: yes">&nbsp;
</span>We then copy the new Executor binary to a DOS partition, reboot to DOS,
test Executor and then get the heck out of DOS.<span style="mso-spacerun:
yes">&nbsp; </span>Time spent using Executor is more like a Mac than it is like
DOS.</p>
<span style='font-size:12.0pt;font-family:Helvetica;mso-ansi-language:EN-US'><b><u><br
clear=ALL style='mso-column-break-before:always'>
</u></b></span>
<h1>Debugging Tools</h1>
<p class=MsoNormal>Internally we have many debugging tools to help us figure
out why an application may die or misbehave under Executor.</p>
<h2>More Free Software</h2>
<h3>GDB in General</h3>
<p class=MsoNormal>Almost all of our debugging is done under the GDB
debugger.<span style="mso-spacerun: yes">&nbsp; </span>As with GCC, we're not
using GDB because it's the free debugger; we're using the free debugger because
it's GDB.<span style="mso-spacerun: yes">&nbsp; </span>GDB is quite powerful.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Whenever we find that a given application fails under
Executor, we try to reproduce the failure under Linux.<span
style="mso-spacerun: yes">&nbsp; </span>Debugging on a system that has complete
memory protection and pre-emptive multi-tasking means that your system stays up
even when your application crashes.<span style="mso-spacerun: yes">&nbsp;
</span>There's also no need to worry that when a program is misbehaving that
it's subtly corrupting other programs on the system.</p>
<h4>hardware watch points</h4>
<p class=MsoNormal>Beyond the features that are handed to us due to the
underlying robustness of the OS, GDB also supports hardware watch points, at
least on 80x86 based PCs.<span style="mso-spacerun: yes">&nbsp; </span>&quot;80x86&quot;s
have the ability to use hardware to watch a small set of memory locations to
see when they change.<span style="mso-spacerun: yes">&nbsp; </span>Since the
checking is done by hardware, the program runs at full speed until the memory
location is modified, at which point the debugger stops, tells us which
instruction modified which memory address and what the old and new values are
for that address.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>As an example, assume we want to know when the low-memory
global <span style='font-family:Courier'>TheMenu</span> is changing, here is
how it might look under GDB:</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal><span style='font-family:Courier'>(gdb) watch TheMenu<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>Hardware watchpoint 1:
TheMenu<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>(gdb) c<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>Continuing.<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>Hardware watchpoint 1:
TheMenu<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>Old value = 0<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>New value = 768<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>C_HiliteMenu (mid=3) at
menu.c:877<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>(gdb) swap16 768<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>$2 = 0x3<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>(gdb) c<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>Continuing.<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>Hardware watchpoint 1:
TheMenu<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>Old value = 768<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>New value = 0<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>C_HiliteMenu (mid=0) at
menu.c:877<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>(gdb) delete 3<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>(gdb) c<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>Continuing.<o:p></o:p></span></p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>At the first <span style='font-family:Courier'>(gdb) </span>prompt
above, we tell GDB that we want to be alerted whenever the expression
&quot;TheMenu&quot; changes.<span style="mso-spacerun: yes">&nbsp; </span>GDB
is clever enough to realize that it can watch that expression with a hardware
watchpoint, so it assigns watchpoint 1 to the task.<span style="mso-spacerun:
yes">&nbsp; </span>We then continue, which allows Executor to continue running whatever
program it was already running.<a style='mso-footnote-id:ftn2' href="#_ftn2"
name="_ftnref2" title=""><span class=MsoFootnoteReference><span
style='mso-special-character:footnote'><![if !supportFootnotes]>[2]<![endif]></span></span></a></p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Eventually, when the menu bar was accessed, GDB told us that
TheMenu had changed from 0 to 768.<span style="mso-spacerun: yes">&nbsp;
</span>768 may sound like a weird value for TheMenu to take, but this is on a
byte swapped machine, so we need to swap that 16-bit value to see what the
TheMenu would look like to a Mac program and we find that it's 3, a sane value
for TheMenu, after all.<span style="mso-spacerun: yes">&nbsp; </span>We let the
program continue and later TheMenu is changed back to zero.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>You can't see it, but in another window the source to
Executor is displayed so that we are automatically shown the 877th line of
menu.c when GDB's watch point triggers there.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>The argument to the watch command is an arbitrary
expression, so it is possible to watch for much more complex changes than our
example demonstrated.<span style="mso-spacerun: yes">&nbsp; </span>Although
only relatively simple watchpoints will be handled by hardware watchpoints, the
others will be handled by software watchpoints which are much slower.</p>
<span style='font-size:12.0pt;font-family:Palatino;mso-ansi-language:EN-US'><b><br
clear=ALL style='mso-column-break-before:always'>
</b></span>
<h3>Hacked GDB</h3>
<p class=MsoNormal>Unlike GCC, where we made local modifications and then, upon
reflection, threw them out, we have made a slight change to GDB that is a big
win for debugging Executor (and Mac programs running under Executor) on
PCs.<span style="mso-spacerun: yes">&nbsp; </span>GDB always knows how to
disassemble the object code that it's running, and GDB is available for many
architectures, so we modified GDB so that on the 80x86 we can do both 80x86
disassembly and 680x0 disassembly.<span style="mso-spacerun: yes">&nbsp;
</span>That allows us to look at sections of memory within our emulator and see
what 680x0 code is there.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>In the example below, Executor is running the game Risk,
when we interrupt Executor and then tell GDB to break in the routine
alinehandler.<span style="mso-spacerun: yes">&nbsp; </span>We then continue
until alinehandler is hit.<span style="mso-spacerun: yes">&nbsp; </span>We then
disassemble, in 680x0 format, the first nine instructions at the location from
which alinehandler was dispatched.<span style="mso-spacerun: yes">&nbsp;
</span>After doing that we disassemble in 80x86 format the first nine
instructions of alinehandler itself.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal><span style='font-family:Courier'>(gdb) b alinehandler<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>Breakpoint 6 at 0x17ce2d:
file executor.c, line 369.<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>(gdb) c<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>Continuing.<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>Breakpoint 6, alinehandler
(pc=3652006, ignored=0x0) at executor.c:369<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>(gdb) set m68k<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>(gdb) x/9i pc<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>0x37b9a6 :<span
style='mso-tab-count:1'>&nbsp; </span>_SystemTask<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>0x37b9a8 :<span
style='mso-tab-count:1'>&nbsp; </span>clrw sp@-<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>0x37b9aa :<span
style='mso-tab-count:1'>&nbsp; </span>movew #-1,sp@-<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>0x37b9ae :<span
style='mso-tab-count:1'>&nbsp; </span>pea a5@(-27598)<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>0x37b9b2 :<span
style='mso-tab-count:1'>&nbsp; </span>_GetNextEvent<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>0x37b9b4 :<span
style='mso-tab-count:1'>&nbsp; </span>moveb sp@+,d0<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>0x37b9b6 :<span
style='mso-tab-count:1'>&nbsp; </span>tstb d0<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>0x37b9b8 :<span
style='mso-tab-count:1'>&nbsp; </span>beqw 0x37ba0e &lt;end+667542&gt;<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>0x37b9bc :<span
style='mso-tab-count:1'>&nbsp; </span>movew a5@(-27598),d0<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>(gdb) set m68k off<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>(gdb) x/9i alinehandler<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>&lt;alinehandler&gt;:<span
style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>pushl<span style="mso-spacerun: yes">&nbsp; </span>%ebp<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>&lt;alinehandler+1&gt;:<span
style='mso-tab-count:1'> </span>movl<span style="mso-spacerun:
yes">&nbsp;&nbsp; </span>%esp,%ebp<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>&lt;alinehandler+3&gt;:<span
style='mso-tab-count:1'> </span>subl<span style="mso-spacerun:
yes">&nbsp;&nbsp; </span>$0x28,%esp<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>&lt;alinehandler+6&gt;:<span
style='mso-tab-count:1'> </span>pushl<span style="mso-spacerun: yes">&nbsp;
</span>%esi<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>&lt;alinehandler+7&gt;:<span
style='mso-tab-count:1'> </span>pushl<span style="mso-spacerun: yes">&nbsp;
</span>%ebx<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>&lt;alinehandler+8&gt;:<span
style='mso-tab-count:1'> </span>jmp<span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>0x17ce10 &lt;alinehandler+48&gt;<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>&lt;alinehandler+10&gt;:<span
style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>nop<span
style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>&lt;alinehandler+11&gt;:<span
style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>nop<span
style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:Courier'>&lt;alinehandler+12&gt;:<span
style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>nop</span><span
style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span></p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Being able to disassemble 680x0 code on the 80x86 required
us to change approximately 50 source lines of GDB (remember, the 680x0
disassembly code was already present for use in GDB on 680x0 machines).<span
style="mso-spacerun: yes">&nbsp; </span>We also added a set of tables so that
a-line traps and low-memory globals are displayed by name, rather than by
number.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Although our special circumstances led us to modify the GDB
source code, GDB is customizable out of the box.<span style="mso-spacerun:
yes">&nbsp; </span>We've defined a handful of macros that automate debugging
tasks.<span style="mso-spacerun: yes">&nbsp; </span>Figure 6 is a macro that
crawls through the stack in mac space.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>For comparison, Figure 7 is what GDB produces when
backtracking code that is compiled with GDB debugging symbols.</p>
</div>
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
</span>
<div class=Section13>
<div style='mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-height-rule:exactly'>
<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=center>
<tr>
<td valign=top align=left style='padding-top:9.0pt;padding-right:9.0pt;
padding-bottom:9.0pt;padding-left:9.0pt'>
<div style='border:solid windowtext .75pt;padding:0in 0in 0in 0in;background:
#E5E5E5;mso-shading:windowtext;mso-pattern:gray-10 auto'>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>define macktrace<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun: yes">&nbsp; </span>set
$_fp = cpu_state.regs[14].ul.n + 0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun: yes">&nbsp;
</span>silentswap32 (((uint32*)$_fp)[1]+0)<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun: yes">&nbsp; </span>set
$_pc = $_val + 0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun: yes">&nbsp;
</span>silentswap32 (((uint32*)$_fp)[0]+0)<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun: yes">&nbsp; </span>set
$_fp = $_val + 0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun: yes">&nbsp;
</span>while $_fp &gt; 100 &amp;&amp; $_fp &lt; 30000000<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>set $_start = (long) $_pc + 0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>while $_start &gt; (long)&amp;end &amp;&amp;
*(uint16 *)$_start != 0x564E<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>set
$_start = $_start - 2<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>end<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>printf &quot;func=0x%lX, ret=0x%lX, fp=0x%lX,
args=0x%02X%02X%02X%02X 0x%02X%02X%02X%02X 0x%02X%02X%02X%02X\n&quot;,\<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>$_start,
$_pc, $_fp,\<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>((uint8
*)$_fp)[8], ((uint8 *)$_fp)[9], ((uint8 *)$_fp)[10],\<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>((uint8
*)$_fp)[11], ((uint8 *)$_fp)[12], ((uint8 *)$_fp)[13],\<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>((uint8
*)$_fp)[14], ((uint8 *)$_fp)[15], ((uint8 *)$_fp)[16],\<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>((uint8
*)$_fp)[17], ((uint8 *)$_fp)[18], ((uint8 *)$_fp)[19]<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>silentswap32 ((uint32*)$_fp)[1]+0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>set $_pc = $_val + 0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>silentswap32 ((uint32*)$_fp)[0]+0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>set $_fp = $_val + 0<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun: yes">&nbsp; </span>end<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>end<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>(gdb) macktrace<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>func=0x3824F8, ret=0x38250E, fp=0xB28E3C,
args=0x00B2E852 0x000300B2 0x8E580037<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>func=0x37A2BE, ret=0x37A3A6, fp=0xB28E4A,
args=0x0037BA12 0x000000B2 0x8F840037<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>func=0x37AECE, ret=0x37AFF0, fp=0xB28E58,
args=0x0001002E 0xE0BC0000 0x00010035<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>func=0x379D58, ret=0x379E0C, fp=0xB28F84,
args=0x000100B2 0x8F9200B2 0x8F9A0000<o:p></o:p></span></p>
<p class=MsoNormal align=center style='text-align:center;border:none;
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-height-rule:exactly'><span style='font-size:12.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
<p class=MsoNormal align=center style='text-align:center;border:none;
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-height-rule:exactly'><span style='font-size:12.0pt'>Figure 6.<span
style="mso-spacerun: yes">&nbsp; </span>Macktrace Definition and Example<o:p></o:p></span></p>
<p class=MsoNormal align=center style='text-align:center;border:none;
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-height-rule:exactly'><span style='font-family:Courier'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>(gdb) backtrace<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>#0<span style="mso-spacerun: yes">&nbsp;
</span>C_SysBeep (i=10) at osutil.c:837<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>#1<span style="mso-spacerun: yes">&nbsp;
</span>0x18934d in PascalToCCall (ignoreme=2271560241, infop=0x29faa4)<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>at emutrap.c:94<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>#2<span style="mso-spacerun: yes">&nbsp;
</span>0x17d0c9 in alinehandler (pc=3661160, ignored=0x0)<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>at executor.c:399<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>#3<span style="mso-spacerun: yes">&nbsp;
</span>0x1c1b85 in trap_direct (trap_number=10, exception_pc=3661160, <o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>exception_address=0) at trap.c:201<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>#4<span style="mso-spacerun: yes">&nbsp;
</span>0x197cfc in S68K_HANDLE_0x00B5 () at syn68k.c:1038<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>#5<span style="mso-spacerun: yes">&nbsp;
</span>0x196067 in interpret_code (start_code=0x2df6c4) at syn68k.c:587<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>#6<span style="mso-spacerun: yes">&nbsp;
</span>0x12d476 in beginexecutingat (startpc=11730018)<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>at launch.c:328<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>#7<span style="mso-spacerun: yes">&nbsp;
</span>0x12e1ce in launchchain (fName=0x2b53f8 &quot;\004Risk&quot;,
vRefNum=-32717, <o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>resetmemory=1 '\001') at launch.c:575<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>#8<span style="mso-spacerun: yes">&nbsp;
</span>0x12f6e0 in Launch (<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>fName_arg=0x910 &quot;\004Riskutor&quot;,
'&#711;' &lt;repeats 27 times&gt;, vRefNum_arg=-32717)<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>at launch.c:1142<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>#9<span style="mso-spacerun: yes">&nbsp;
</span>0x17e1f7 in executor_main ()<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>at executor.c:589<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'>#10 0x13371a in main (argc=2, argv=0xbffffa04)<o:p></o:p></span></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
margin;mso-element-left:center;mso-height-rule:exactly'><span
style='font-family:Courier'><span style="mso-spacerun:
yes">&nbsp;&nbsp;&nbsp; </span>at main.c:2112</span></p>
<p class=MsoNormal align=center style='text-align:center;border:none;
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
center;mso-height-rule:exactly'><span style='font-size:12.0pt'>Figure 7.<span
style="mso-spacerun: yes">&nbsp; </span>GDB backtrace</span></p>
</div>
</td>
</tr>
</table>
</div>
</div>
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
</span>
<div class=Section14><br clear=ALL style='mso-column-break-before:always'>
<br clear=ALL style='mso-column-break-before:always'>
<p class=MsoNormal>As you might guess, this disparity of information makes it
much easier for for us to track down bugs in our own code then finding bizarre
incompatibilities in the code that is being run under the emulator.</p>
<h2>Disassembler</h2>
<p class=MsoNormal>Since GDB already knows how to disassemble 680x0 code it was
possible to write a driver for GDB so that it can disassemble Mac
programs.<span style="mso-spacerun: yes">&nbsp; </span>The driver is about
1,000 lines of C code, with another 500 lines describing the low-memory
globals.<span style="mso-spacerun: yes">&nbsp; </span>Basically the driver knows
about CODE resources and how intersegment jumps work.<span style="mso-spacerun:
yes">&nbsp; </span>GDB normally doesn't produce labels for jump targets or the
beginning of subroutines, so the driver adds those too, to make the output that
much easier to read.&#19;</p>
<h2>Run-time Aids</h2>
<p class=MsoNormal>Because we're using our own set of OS and Toolbox routines,
we can add code that is conditionally compiled into debug versions of Executor
that can provide still more information than GDB or GDB macros can.</p>
<h3>Debugtable, Debugnumber</h3>
<p class=MsoNormal>Our A-line trap handler has a table, known as debugtable, of
4096 32-bit ints that it updates each time a trap is taken.<span
style="mso-spacerun: yes">&nbsp; </span>Each time alinehandler is called, a
variable known as &quot;debugnumber&quot; is incremented and then the value of
debugnumber is stored in the slot in debugtable corresponding to the aline trap
that was called.<span style="mso-spacerun: yes">&nbsp; </span>This allows us to
see both what traps were recently executed and a complete list of every trap
that an application makes, no matter how long the application has run.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>This scheme has its drawbacks.<span style="mso-spacerun:
yes">&nbsp; </span>Traps that are dispatched via selectors are all lumped
together.<span style="mso-spacerun: yes">&nbsp; </span>Traps whose addresses
are taken and then are called by jumps through the address don't show up in
debugtable.<span style="mso-spacerun: yes">&nbsp; </span>Although debugtable
and debugnumber are perhaps the least sophisticated portion of Executor,
they're still quite handy, since a visual inspection of the last 100 traps made
before an application died often gives a good idea of where to start looking
for the source of the incompatibility.</p>
<h3>XX_slam</h3>
<p class=MsoNormal>In the course of developing Executor, we did a major rewrite
of our memory manager and our TextEdit replacement.<span style="mso-spacerun:
yes">&nbsp; </span>In both cases it's not enough to just implement the APIs
that are defined in Inside Macintosh, we also have to duplicate the in-memory
data structures so that programs which count on them will run properly.<span
style="mso-spacerun: yes">&nbsp; </span>To help us verify that we weren't
adding new bugs when we rewrote those subsystems we added routines that would
consistency check the data structures that each of those subsystems support.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Because these consistency checks are thorough but time
consuming, we call them &quot;slams&quot;, and by default they are not enabled,
even in debugging versions of Executor.<span style="mso-spacerun: yes">&nbsp;
</span>When they are enabled, the data structures for each subsystem are
slammed at the entry to a call that might modify one of the data structures and
the data structure is slammed once again on exit of the routine.<span
style="mso-spacerun: yes">&nbsp; </span>We can turn them on at run-time either
by using a command line option when Executor is started or by using GDB to
enable the slamming.<span style="mso-spacerun: yes">&nbsp; </span>This is
something we should have done for all of Executor's subsystems from day one,
since it's ever so helpful to be told that going into routine XXX, the heap was
fine, but coming out the heap was corrupted.</p>
<h3>Image Viewer</h3>
<p class=MsoNormal>Reading disassembled code is much easier than staring at hex
numbers.<span style="mso-spacerun: yes">&nbsp; </span>Similarly, being able to
view a portion of memory as some sort of PixMap (assuming that the memory
really is a bit image) is also better than staring at a bunch of hex
numbers.<span style="mso-spacerun: yes">&nbsp; </span>When we build Executor
for X-Windows, we also build an image server that uses UNIX interprocess
communication to communicate with the process being debugged under GDB.<span
style="mso-spacerun: yes">&nbsp; </span>This allows us to monitor offscreen
graphics, which can be very important when an application makes many graphics
calls and eventually an abomination is drawn on the screen instead of what
should have been drawn.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Our debugging arsenal includes other, more prosaic,
tools.<span style="mso-spacerun: yes">&nbsp; </span>In fact, our debugging
environment encourages the development of new tools, because it's so easy to
leverage existing tools into new tools and even write new tools from scratch.</p>
<span style='font-size:12.0pt;font-family:Helvetica;mso-ansi-language:EN-US'><b><u><br
clear=ALL style='mso-column-break-before:always'>
</u></b></span>
<h1>Future Plans</h1>
<p class=MsoNormal>Much of VCPU, a successor to Syn68k, has already been
written.<span style="mso-spacerun: yes">&nbsp; </span>VCPU performs many
optimizations that Syn68k does not, including improved register allocation,
dead subregister elimination, opcode &quot;widening&quot;, and moving work
outside of loops.<span style="mso-spacerun: yes">&nbsp; </span>VCPU has a clean
high-level syntax for specifying both front ends and back ends, allowing it to
dynamically compile both PowerPC and m68k binaries on any architecture we
decide to support.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Although we don't explicitly mention it, the graphic
subsystem one layer above the blitter already has hooks in it to allow use of
graphics accelerators, where present.<span style="mso-spacerun: yes">&nbsp;
</span>We plan a native port to Win32 and OS/2 and those ports should be able
to use fancier graphic subsystems and also make use of the underlying network
APIs.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Currently INITs and CDEVs do not run under Executor, but the
same mechanisms that allow applications to run can also allow INITs and CDEVs
to run.<span style="mso-spacerun: yes">&nbsp; </span>QuickTime and ATM will
both be high priorities after Executor 2 ships.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>We will also be developing compiler tools that will allow ISVs
to natively compile CPU specific routines to be used when their applications
are run under Executor.<span style="mso-spacerun: yes">&nbsp; </span>Executor
already uses such gateways internally.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>Already, multiple simultaneous instances of Executor can be
run under NEXTSTEP and Linux (and to a lesser extent under Windows '95).<span
style="mso-spacerun: yes">&nbsp; </span>Currently only Executor/NEXTSTEP
handles PICT pasteboard cutting and pasting from one instantiation of Executor
to another, and no versions of Executor do enough file locking to allow
concurrent access of the same HFS volumes at once.<span style="mso-spacerun:
yes">&nbsp; </span>This needs to be fixed, since either through shared text
segments under UNIX and UNIX like operating systems or through DLLs under Microsoft
operating systems, it can be made fairly efficient to run multiple instances of
Executor simultaneously.<span style="mso-spacerun: yes">&nbsp; </span>When that
is done, each instance of Executor has its own address space and is
automatically scheduled by the underlying operating system scheduler.<span
style="mso-spacerun: yes">&nbsp; </span>That means that Executor
&quot;inherits&quot; memory-protection and pre-emptive multi-tasking from the
underlying core operating system.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>By properly exploiting this inheritance it should be
possible to provide an environment that allows well-behaved Mac applications to
run efficiently under a variety of PC operating systems with automatic
protection from non-well-behaved applications.</p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=MsoNormal>One interesting variant on this theme would be to use Linux
as the core OS, but to hide it from the end-user, for a net result of an 80x86
box that boots an efficient, robust MacOS-like environment.<span
style="mso-spacerun: yes">&nbsp; </span></p>
</div>
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
</span>
<div class=Section15>
<p class=MsoNormal><span style='font-size:12.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
</div>
<div style='mso-element:footnote-list'><![if !supportFootnotes]><br clear=all>
<hr align=left size=1 width="33%">
<![endif]>
<div style='mso-element:footnote' id=ftn1>
<p class=MsoFootnoteText><a style='mso-footnote-id:ftn1' href="#_ftnref1"
name="_ftn1" title=""><span class=MsoFootnoteReference><span style='mso-special-character:
footnote'><![if !supportFootnotes]>[1]<![endif]></span></span></a>&quot;What
the heck is a pointer to a C code label?&quot;, you ask?<span
style="mso-spacerun: yes">&nbsp; </span>gcc (the GNU C compiler) has a
&quot;pointer to label&quot; extension to the C language which makes the
statement &quot;<span style='font-family:Courier'>&amp;&amp;my_label&quot;</span>
evaluate to a</p>
<p class=MsoFootnoteText>&quot;<span style='font-family:Courier'>void *</span>&quot;
that points to the compiled code for &quot;<span style='font-family:Courier'>my_label:</span>&quot;
within a C function. This, combined with gcc's &quot;<span style='font-family:
Courier'>goto void *</span>&quot; extension, allows C programs to execute goto
statements whose destinations are not known at compile time.</p>
</div>
<div style='mso-element:footnote' id=ftn2>
<p class=MsoFootnoteText><a style='mso-footnote-id:ftn2' href="#_ftnref2"
name="_ftn2" title=""><span class=MsoFootnoteReference><span style='mso-special-character:
footnote'><![if !supportFootnotes]>[2]<![endif]></span></span></a>I actually
set this watchpoint in the session of Executor that I am using to run Word 5.1
for the Macintosh to compose this document (Executor/Linux on a 90 MHz Pentium).</p>
</div>
</div>
</body>
</html>