<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://sdcc.sourceforge.net/mediawiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://sdcc.sourceforge.net/mediawiki/index.php?title=Combined_i186/Z80_backend_design&amp;feed=atom&amp;action=history</id>
		<title>Combined i186/Z80 backend design - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://sdcc.sourceforge.net/mediawiki/index.php?title=Combined_i186/Z80_backend_design&amp;feed=atom&amp;action=history"/>
		<link rel="alternate" type="text/html" href="http://sdcc.sourceforge.net/mediawiki/index.php?title=Combined_i186/Z80_backend_design&amp;action=history"/>
		<updated>2013-05-26T05:45:35Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.20.2</generator>

	<entry>
		<id>http://sdcc.sourceforge.net/mediawiki/index.php?title=Combined_i186/Z80_backend_design&amp;diff=73&amp;oldid=prev</id>
		<title>Borutr: Created page with &quot;= Combined i186/Z80 backend design =  &lt;div class=&quot;author_info&quot;&gt;  '''Michael Hope michaelh@earthling.net.nz'''  &lt;/div&gt;  === Abstract: ===  &lt;div class=&quot;ABSTRACT&quot;&gt; There is much ...&quot;</title>
		<link rel="alternate" type="text/html" href="http://sdcc.sourceforge.net/mediawiki/index.php?title=Combined_i186/Z80_backend_design&amp;diff=73&amp;oldid=prev"/>
				<updated>2012-12-04T20:18:14Z</updated>
		
		<summary type="html">&lt;p&gt;Created page with &amp;quot;= Combined i186/Z80 backend design =  &amp;lt;div class=&amp;quot;author_info&amp;quot;&amp;gt;  &amp;#039;&amp;#039;&amp;#039;Michael Hope michaelh@earthling.net.nz&amp;#039;&amp;#039;&amp;#039;  &amp;lt;/div&amp;gt;  === Abstract: ===  &amp;lt;div class=&amp;quot;ABSTRACT&amp;quot;&amp;gt; There is much ...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Combined i186/Z80 backend design =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;author_info&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Michael Hope michaelh@earthling.net.nz'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Abstract: ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;ABSTRACT&amp;quot;&amp;gt; There is much similarity between the Zilog Z80, Nintendo GBZ80, Intel i186, and Toshiba TLCS-900Hprocessors. This document describes the design of a backend consisting of a register allocator and set of extendable code generators for SDCC which can target all of these processors. &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= &amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;1&amp;lt;/span&amp;gt; Motivation =&lt;br /&gt;
&lt;br /&gt;
The primary motivation is to add a i186 backend to SDCC, and in the process come to understand register allocation. The secondary goal is to attempt to combine the common parts from the Z80 and i186 backends to make both easier to maintain. In the 'would be nice' category is adding support for the Toshiba TLCS-900H.&lt;br /&gt;
&lt;br /&gt;
= &amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;2&amp;lt;/span&amp;gt; Processor descriptions =&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;2&amp;lt;/span&amp;gt;.&amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;1&amp;lt;/span&amp;gt; Zilog Z80 ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Name&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Parts&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Notes&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | AF&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | A&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Accumulator and flags. Unusable as a pair.&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | BC&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | B, C&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | DE&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | D, E&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | HL&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | H, L&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | IX&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | None&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Index register.&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | IY&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | None&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Index register.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The Z80 also has a switchable alternate register set AF', BC', DE', and HL' which are not accessible directly. It is assumed that it is too hard to track these to make it worthwhile. IX and IY can be split at the byte level by using undocumented instructions. While this would make them more usable as general purpose registers, it is ignored for compatibility.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;2&amp;lt;/span&amp;gt;.&amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;2&amp;lt;/span&amp;gt; Nintendo GBZ80 ==&lt;br /&gt;
&lt;br /&gt;
The GBZ80 is basically a Z80 less the index registers and the alternate register set. &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Name&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Parts&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Notes&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | AF&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | A&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Accumulator and flags. Unusable as a pair.&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | BC&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | B, C&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | DE&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | D, E&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | HL&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | H, L&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; |&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;2&amp;lt;/span&amp;gt;.&amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;3&amp;lt;/span&amp;gt; Intel i186 ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Name&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Parts&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Notes&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | AX&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | AH, AL&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Accumulator.&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | BX&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | BH, BL&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | CX&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | CH, CL&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | DX&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | DH, DL&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | DI&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | None&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Destination Index.&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | SI&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | None&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Source Index.&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | BP&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | None&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Base pointer.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that the segment registers CS, DS, ES, and SS are not listed. For simplicity only tiny mode is supported. Tiny mode is where both the data and code exist in one segment, such that CS = DS. This allows constant data stored in the code segment to be accessed in the same method as data. This may cause trouble later if far mode is needed.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;2&amp;lt;/span&amp;gt;.&amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;4&amp;lt;/span&amp;gt; Toshiba TLCS-900H ==&lt;br /&gt;
&lt;br /&gt;
The 900H seems to be inspired by the Z80. It is listed as a 16 bit device, but most of the registers are 32 bits wide. &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Name&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Parts&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Notes&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | XWA&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | WA, W, A&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Accumulator&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | XBC&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | BC, B, C&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | XDE&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | DE, D, E&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | XHL&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | HL, H, L&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | XIX&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | IX&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | XIY&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | IY&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | XIZ&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | IZ&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; |&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
All registers can act as either an index base or an index offset. The offset is limited to sixteen bits. Apparently XIX, XIY, and XIZ can be split at the byte level. For simplicity this is ignored.&lt;br /&gt;
&lt;br /&gt;
= &amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;3&amp;lt;/span&amp;gt; Common features =&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;3&amp;lt;/span&amp;gt;.&amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;1&amp;lt;/span&amp;gt; Stack ==&lt;br /&gt;
&lt;br /&gt;
The stack grows downwards. All push operations are pre-decrement. All but the GBZ80 have a base pointer register that can be used along with an offset to access local variables and parameters. The GBZ80 and Z80 both have problems with more than 127 bytes of local variables due to their offset being a INT8.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;3&amp;lt;/span&amp;gt;.&amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;2&amp;lt;/span&amp;gt; Registers ==&lt;br /&gt;
&lt;br /&gt;
All contain a reasonable but small number of registers. All have some special purpose registers which can either be handled separately or ignored. All general purpose registers can be split at the byte and word level, but doing so may make the rest of the register unavailable.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;3&amp;lt;/span&amp;gt;.&amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;3&amp;lt;/span&amp;gt; Memory ==&lt;br /&gt;
&lt;br /&gt;
All have a 64k address space. However this should not be assumed to make far support easier later.&lt;br /&gt;
&lt;br /&gt;
= &amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;4&amp;lt;/span&amp;gt; Design =&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;4&amp;lt;/span&amp;gt;.&amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;1&amp;lt;/span&amp;gt; Basics ==&lt;br /&gt;
&lt;br /&gt;
The design is mainly stack based, such that all local variables and parameters go onto the stack. Compare with the mcs51 backend which overlays variables onto a shared static area.&lt;br /&gt;
&lt;br /&gt;
All stack access goes through the base pointer register (BP). The stack frame consists of the parameters pushed right to left, the return context, and then local variables. SP points to the base of the local variables. BP points to the bottom of the return context and hence to just above the top of the local variables. Note that as the stack grows down the parameters appear with the left most parameter at the lowest address.&lt;br /&gt;
&lt;br /&gt;
A scratch register will be available for any sub operation to use and will be valid only within that sub operation. The accumulator is also unavailable. Return values are normally returned in the scratch register and accumulator.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Name&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | i186&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Z80&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | GBZ80&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | 900H&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Base pointer&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | BP&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | IX&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | HL&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | XIX&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Scratch&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | BX&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | HL&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | DE&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | XHL&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Return&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | BX, AX&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | HL, IY&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | DE, HL&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | XHL&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Available&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | CX, DX&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | BC, DE&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | BC&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | XBC, XDE&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | Ignored&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | SI, DI&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | IY&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | None&lt;br /&gt;
| align=&amp;quot;LEFT&amp;quot; | XIY, XIZ&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;4&amp;lt;/span&amp;gt;.&amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;2&amp;lt;/span&amp;gt; Register allocator ==&lt;br /&gt;
&lt;br /&gt;
The current Z80 and mcs51 register allocators perform these steps:&lt;br /&gt;
&lt;br /&gt;
# Pack each basic block by removing straight assignments and marking remat. iTemps.&lt;br /&gt;
# Set the number of registers required for each live range based on the type and size of the live range.&lt;br /&gt;
# Assign registers to each segment by deassigning registers and stack locations for any just expired iTemps, skipping any instructions which don't need registers, and spilling and assigning registers to the result of this tuple.&lt;br /&gt;
# Create the register mask for this segment.&lt;br /&gt;
&lt;br /&gt;
Optimisations include assigning into the accumulator or the scratch register where possible. This requires knowledge of what the code generator touches for a given instruction.&lt;br /&gt;
&lt;br /&gt;
The first generation register allocator will only pack assignments and mark remat. variables. Only the register management is processor specific. The allocator may ask for a given size register or if a given size register is available. Note that only whole registers may be returned. For example, allocation will fail if a sixteen bit register is requested and no pair is available, even two eight bit registers are available. Note that on the Z80, GBZ80, and i186 a request for a 32 bit register will always fail.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;4&amp;lt;/span&amp;gt;.&amp;lt;span class=&amp;quot;arabic&amp;quot;&amp;gt;3&amp;lt;/span&amp;gt; Code generator ==&lt;br /&gt;
&lt;br /&gt;
The possible operations are:&lt;br /&gt;
&lt;br /&gt;
* NOT - Logical not. 0 -&amp;amp;gt; 1, others -&amp;amp;gt; 0.&lt;br /&gt;
* CPL - Bitwise complement.&lt;br /&gt;
* UMINUS - Unary minus. result = 0 - left.&lt;br /&gt;
* IPUSH - Push immediate onto the stack.&lt;br /&gt;
* CALL - Call a function.&lt;br /&gt;
* PCALL - Call via pointer.&lt;br /&gt;
* FUNCTION - Emit the function prelude.&lt;br /&gt;
* ENDFUNCTION - Emit the function prologue.&lt;br /&gt;
* RET - Load the return value and jump to end of function.&lt;br /&gt;
* LABEL - Generate a local label.&lt;br /&gt;
* GOTO - Jump to a local label.&lt;br /&gt;
* Arithmitic - , -, *, /, %.&lt;br /&gt;
* Comparison - LT, GT, LEQ, GEQ, !=, =.&lt;br /&gt;
* Logical - &amp;amp;amp;&amp;amp;amp;, ||&lt;br /&gt;
* Binary - AND, OR, XOR.&lt;br /&gt;
* Shift - RRC, RLC, LSR, LSL.&lt;br /&gt;
* Pointer - Set and Get.&lt;br /&gt;
* Assign.&lt;br /&gt;
* IF jump.&lt;br /&gt;
* Misc - Jump table, cast, address of.&lt;/div&gt;</summary>
		<author><name>Borutr</name></author>	</entry>

	</feed>