Changes between Version 15 and Version 16 of Commentary/Compiler/CmmType


Ignore:
Timestamp:
Jan 15, 2007 5:54:14 PM (9 years ago)
Author:
p_tanski
Comment:

finish color; typo; clarification (primitive operation equivalent quasi-operator)

Legend:

Unmodified
Added
Removed
Modified
  • Commentary/Compiler/CmmType

    v15 v16  
    149149#!html
    150150<pre>
    151 <u><font color=Magenta>newtype</font></u> <font color=Green>GenCmm</font> <font color=Black>d</font> <font color=Black>i</font> <font color=Blue>=</font> <font color=Green>Cmm</font> <font color=Blue>[</font><font color=Green>GenCmmTop</font> <font color=Black>d</font> <font color=Black>i</font><font color=Blue>]</font>
    152 
    153 <u><font color=Magenta>type</font></u> <font color=Green>Cmm</font> <font color=Blue>=</font> <font color=Green>GenCmm</font> <font color=Green>CmmStatic</font> <font color=Green>CmmStmt</font>
    154 
    155 
    156 <u><font color=Magenta>data</font></u> <font color=Green>GenCmmTop</font> <font color=Black>d</font> <font color=Black>i</font>
     151<font color=DarkOrchid>newtype</font> <font color=Green>GenCmm</font> <font color=Black>d</font> <font color=Black>i</font> <font color=Blue>=</font> <font color=Green>Cmm</font> <font color=Blue>[</font><font color=Green>GenCmmTop</font> <font color=Black>d</font> <font color=Black>i</font><font color=Blue>]</font>
     152
     153<font color=DarkOrchid>type</font> <font color=Green>Cmm</font> <font color=Blue>=</font> <font color=Green>GenCmm</font> <font color=Green>CmmStatic</font> <font color=Green>CmmStmt</font>
     154
     155
     156<font color=DarkOrchid>data</font> <font color=Green>GenCmmTop</font> <font color=Black>d</font> <font color=Black>i</font>
    157157  <font color=Blue>=</font> <font color=Green>CmmProc</font>
    158      <font color=Blue>[</font><font color=Black>d</font><font color=Blue>]</font>              <font color=Red>-- Info table, may be empty</font>
    159      <font color=Green>CLabel</font>            <font color=Red>-- Used to generate both info &amp; entry labels</font>
    160      <font color=Blue>[</font><font color=Green>LocalReg</font><font color=Blue>]</font>        <font color=Red>-- Argument locals live on entry (C-- procedure params)</font>
    161      <font color=Blue>[</font><font color=Green>GenBasicBlock</font> <font color=Black>i</font><font color=Blue>]</font> <font color=Red>-- Code, may be empty.  The first block is</font>
    162                        <font color=Red>-- the entry point.  The order is otherwise initially </font>
    163                        <font color=Red>-- unimportant, but at some point the code gen will</font>
    164                        <font color=Red>-- fix the order.</font>
    165 
    166                        <font color=Red>-- the BlockId of the first block does not give rise</font>
    167                        <font color=Red>-- to a label.  To jump to the first block in a Proc,</font>
    168                        <font color=Red>-- use the appropriate CLabel.</font>
    169 
    170   <font color=Red>-- some static data.</font>
    171   <font color=Blue>|</font> <font color=Green>CmmData</font> <font color=Green>Section</font> <font color=Blue>[</font><font color=Black>d</font><font color=Blue>]</font>      <font color=Red>-- constant values only</font>
    172 
    173 <u><font color=Magenta>type</font></u> <font color=Green>CmmTop</font> <font color=Blue>=</font> <font color=Green>GenCmmTop</font> <font color=Green>CmmStatic</font> <font color=Green>CmmStmt</font>
     158     <font color=Blue>[</font><font color=Black>d</font><font color=Blue>]</font>              <font color=Crimson>-- Info table, may be empty</font>
     159     <font color=Green>CLabel</font>            <font color=Crimson>-- Used to generate both info &amp; entry labels</font>
     160     <font color=Blue>[</font><font color=Green>LocalReg</font><font color=Blue>]</font>        <font color=Crimson>-- Argument locals live on entry (C-- procedure params)</font>
     161     <font color=Blue>[</font><font color=Green>GenBasicBlock</font> <font color=Black>i</font><font color=Blue>]</font> <font color=Crimson>-- Code, may be empty.  The first block is</font>
     162                       <font color=Crimson>-- the entry point.  The order is otherwise initially </font>
     163                       <font color=Crimson>-- unimportant, but at some point the code gen will</font>
     164                       <font color=Crimson>-- fix the order.</font>
     165
     166                       <font color=Crimson>-- the BlockId of the first block does not give rise</font>
     167                       <font color=Crimson>-- to a label.  To jump to the first block in a Proc,</font>
     168                       <font color=Crimson>-- use the appropriate CLabel.</font>
     169
     170  <font color=Crimson>-- some static data.</font>
     171  <font color=Blue>|</font> <font color=Green>CmmData</font> <font color=Green>Section</font> <font color=Blue>[</font><font color=Black>d</font><font color=Blue>]</font>      <font color=Crimson>-- constant values only</font>
     172
     173<font color=DarkOrchid>type</font> <font color=Green>CmmTop</font> <font color=Blue>=</font> <font color=Green>GenCmmTop</font> <font color=Green>CmmStatic</font> <font color=Green>CmmStmt</font>
    174174</pre>
    175175}}}
     
    194194#!html
    195195<pre>
    196 <u><font color=Magenta>data</font></u> <font color=Green>GenBasicBlock</font> <font color=Black>i</font> <font color=Blue>=</font> <font color=Green>BasicBlock</font> <font color=Green>BlockId</font> <font color=Blue>[</font><font color=Black>i</font><font color=Blue>]</font>
    197 
    198 <u><font color=Magenta>type</font></u> <font color=Green>CmmBasicBlock</font> <font color=Blue>=</font> <font color=Green>GenBasicBlock</font> <font color=Green>CmmStmt</font>
    199 
    200 <u><font color=Magenta>newtype</font></u> <font color=Green>BlockId</font> <font color=Blue>=</font> <font color=Green>BlockId</font> <font color=Green>Unique</font>
    201   <u><font color=Magenta>deriving</font></u> <font color=Blue>(</font><font color=Green>Eq</font><font color=Blue>,</font><font color=Green>Ord</font><font color=Blue>)</font>
    202 
    203 <u><font color=Magenta>instance</font></u> <font color=Green>Uniquable</font> <font color=Green>BlockId</font> <u><font color=Magenta>where</font></u>
     196<font color=DarkOrchid>data</font> <font color=Green>GenBasicBlock</font> <font color=Black>i</font> <font color=Blue>=</font> <font color=Green>BasicBlock</font> <font color=Green>BlockId</font> <font color=Blue>[</font><font color=Black>i</font><font color=Blue>]</font>
     197
     198<font color=DarkOrchid>type</font> <font color=Green>CmmBasicBlock</font> <font color=Blue>=</font> <font color=Green>GenBasicBlock</font> <font color=Green>CmmStmt</font>
     199
     200<font color=DarkOrchid>newtype</font> <font color=Green>BlockId</font> <font color=Blue>=</font> <font color=Green>BlockId</font> <font color=Green>Unique</font>
     201  <font color=DarkOrchid>deriving</font> <font color=Blue>(</font><font color=Green>Eq</font><font color=Blue>,</font><font color=Green>Ord</font><font color=Blue>)</font>
     202
     203<font color=DarkOrchid>instance</font> <font color=Green>Uniquable</font> <font color=Green>BlockId</font> <font color=DarkOrchid>where</font>
    204204  <font color=Orange>getUnique</font> <font color=Blue>(</font><font color=Green>BlockId</font> <font color=Black>u</font><font color=Blue>)</font> <font color=Blue>=</font> <font color=Black>u</font>
    205205</pre>
     
    217217#!html
    218218<pre>
    219 <u><font color=Magenta>data</font></u> <font color=Green>CmmReg</font>
     219<font color=DarkOrchid>data</font> <font color=Green>CmmReg</font>
    220220  <font color=Blue>=</font> <font color=Green>CmmLocal</font>  <font color=Green>LocalReg</font>
    221221  <font color=Blue>|</font> <font color=Green>CmmGlobal</font> <font color=Green>GlobalReg</font>
    222   <u><font color=Magenta>deriving</font></u><font color=Blue>(</font> <font color=Green>Eq</font> <font color=Blue>)</font>
     222  <font color=DarkOrchid>deriving</font><font color=Blue>(</font> <font color=Green>Eq</font> <font color=Blue>)</font>
    223223</pre>
    224224}}}
     
    229229#!html
    230230<pre>
    231 <u><font color=Magenta>data</font></u> <font color=Green>LocalReg</font>
     231<font color=DarkOrchid>data</font> <font color=Green>LocalReg</font>
    232232  <font color=Blue>=</font> <font color=Green>LocalReg</font> <font color=Blue>!</font><font color=Green>Unique</font> <font color=Green>MachRep</font>
    233233</pre>
     
    239239#!html
    240240<pre>
    241 <u><font color=Magenta>data</font></u> <font color=Green>MachRep</font>
    242   <font color=Blue>=</font> <font color=Green>I8</font>         <font color=Red>-- integral type, 8 bits wide (a byte)</font>
    243   <font color=Blue>|</font> <font color=Green>I16</font>                <font color=Red>-- integral type, 16 bits wide</font>
    244   <font color=Blue>|</font> <font color=Green>I32</font>                <font color=Red>-- integral type, 32 bits wide</font>
    245   <font color=Blue>|</font> <font color=Green>I64</font>                <font color=Red>-- integral type, 64 bits wide</font>
    246   <font color=Blue>|</font> <font color=Green>I128</font>       <font color=Red>-- integral type, 128 bits wide (an integral vector register)</font>
    247   <font color=Blue>|</font> <font color=Green>F32</font>                <font color=Red>-- floating point type, 32 bits wide (float)</font>
    248   <font color=Blue>|</font> <font color=Green>F64</font>                <font color=Red>-- floating point type, 64 bits wide (double)</font>
    249   <font color=Blue>|</font> <font color=Green>F80</font>                <font color=Red>-- extended double-precision, used in x86 native codegen only.</font>
    250   <u><font color=Magenta>deriving</font></u> <font color=Blue>(</font><font color=Green>Eq</font><font color=Blue>,</font> <font color=Green>Ord</font><font color=Blue>,</font> <font color=Green>Show</font><font color=Blue>)</font>
     241<font color=DarkOrchid>data</font> <font color=Green>MachRep</font>
     242  <font color=Blue>=</font> <font color=Green>I8</font>         <font color=Crimson>-- integral type, 8 bits wide (a byte)</font>
     243  <font color=Blue>|</font> <font color=Green>I16</font>                <font color=Crimson>-- integral type, 16 bits wide</font>
     244  <font color=Blue>|</font> <font color=Green>I32</font>                <font color=Crimson>-- integral type, 32 bits wide</font>
     245  <font color=Blue>|</font> <font color=Green>I64</font>                <font color=Crimson>-- integral type, 64 bits wide</font>
     246  <font color=Blue>|</font> <font color=Green>I128</font>       <font color=Crimson>-- integral type, 128 bits wide (an integral vector register)</font>
     247  <font color=Blue>|</font> <font color=Green>F32</font>                <font color=Crimson>-- floating point type, 32 bits wide (float)</font>
     248  <font color=Blue>|</font> <font color=Green>F64</font>                <font color=Crimson>-- floating point type, 64 bits wide (double)</font>
     249  <font color=Blue>|</font> <font color=Green>F80</font>                <font color=Crimson>-- extended double-precision, used in x86 native codegen only.</font>
     250  <font color=DarkOrchid>deriving</font> <font color=Blue>(</font><font color=Green>Eq</font><font color=Blue>,</font> <font color=Green>Ord</font><font color=Blue>,</font> <font color=Green>Show</font><font color=Blue>)</font>
    251251</pre>
    252252}}}
     
    271271#!html
    272272<pre>
    273 <u><font color=Magenta>data</font></u> <font color=Green>GlobalReg</font>
    274   <font color=Red>-- Argument and return registers</font>
    275   <font color=Blue>=</font> <font color=Green>VanillaReg</font>                 <font color=Red>-- pointers, unboxed ints and chars</font>
    276         <font color=Red>{-# UNPACK #-}</font> <font color=Green>!</font><font color=Green>Int</font>    <font color=Red>-- register number, such as R3, R11</font>
    277 
    278   <font color=Blue>|</font> <font color=Green>FloatReg</font>           <font color=Red>-- single-precision floating-point registers</font>
    279         <font color=Red>{-# UNPACK #-}</font> <font color=Green>!</font><font color=Green>Int</font>    <font color=Red>-- register number</font>
    280 
    281   <font color=Blue>|</font> <font color=Green>DoubleReg</font>          <font color=Red>-- double-precision floating-point registers</font>
    282         <font color=Red>{-# UNPACK #-}</font> <font color=Green>!</font><font color=Green>Int</font>    <font color=Red>-- register number</font>
    283 
    284   <font color=Blue>|</font> <font color=Green>LongReg</font>            <font color=Red>-- long int registers (64-bit, really)</font>
    285         <font color=Red>{-# UNPACK #-}</font> <font color=Green>!</font><font color=Green>Int</font>    <font color=Red>-- register number</font>
    286 
    287   <font color=Red>-- STG registers</font>
    288   <font color=Blue>|</font> <font color=Green>Sp</font>                 <font color=Red>-- Stack ptr; points to last occupied stack location.</font>
    289   <font color=Blue>|</font> <font color=Green>SpLim</font>              <font color=Red>-- Stack limit</font>
    290   <font color=Blue>|</font> <font color=Green>Hp</font>                 <font color=Red>-- Heap ptr; points to last occupied heap location.</font>
    291   <font color=Blue>|</font> <font color=Green>HpLim</font>              <font color=Red>-- Heap limit register</font>
    292   <font color=Blue>|</font> <font color=Green>CurrentTSO</font>         <font color=Red>-- pointer to current thread's TSO</font>
    293   <font color=Blue>|</font> <font color=Green>CurrentNursery</font>     <font color=Red>-- pointer to allocation area</font>
    294   <font color=Blue>|</font> <font color=Green>HpAlloc</font>            <font color=Red>-- allocation count for heap check failure</font>
    295 
    296                 <font color=Red>-- We keep the address of some commonly-called </font>
    297                 <font color=Red>-- functions in the register table, to keep code</font>
    298                 <font color=Red>-- size down:</font>
    299   <font color=Blue>|</font> <font color=Green>GCEnter1</font>           <font color=Red>-- stg_gc_enter_1</font>
    300   <font color=Blue>|</font> <font color=Green>GCFun</font>              <font color=Red>-- stg_gc_fun</font>
    301 
    302   <font color=Red>-- Base offset for the register table, used for accessing registers</font>
    303   <font color=Red>-- which do not have real registers assigned to them.  This register</font>
    304   <font color=Red>-- will only appear after we have expanded GlobalReg into memory accesses</font>
    305   <font color=Red>-- (where necessary) in the native code generator.</font>
     273<font color=DarkOrchid>data</font> <font color=Green>GlobalReg</font>
     274  <font color=Crimson>-- Argument and return registers</font>
     275  <font color=Blue>=</font> <font color=Green>VanillaReg</font>                 <font color=Crimson>-- pointers, unboxed ints and chars</font>
     276        <font color=Crimson>{-# UNPACK #-}</font> <font color=Blue>!</font><font color=Green>Int</font> <font color=Crimson>-- register number, such as R3, R11</font>
     277
     278  <font color=Blue>|</font> <font color=Green>FloatReg</font>                   <font color=Crimson>-- single-precision floating-point registers</font>
     279        <font color=Crimson>{-# UNPACK #-}</font> <font color=Blue>!</font><font color=Green>Int</font> <font color=Crimson>-- register number</font>
     280
     281  <font color=Blue>|</font> <font color=Green>DoubleReg</font>                  <font color=Crimson>-- double-precision floating-point registers</font>
     282        <font color=Crimson>{-# UNPACK #-}</font> <font color=Blue>!</font><font color=Green>Int</font> <font color=Crimson>-- register number</font>
     283
     284  <font color=Blue>|</font> <font color=Green>LongReg</font>                    <font color=Crimson>-- long int registers (64-bit, really)</font>
     285        <font color=Crimson>{-# UNPACK #-}</font> <font color=Blue>!</font><font color=Green>Int</font> <font color=Crimson>-- register number</font>
     286
     287  <font color=Crimson>-- STG registers</font>
     288  <font color=Blue>|</font> <font color=Green>Sp</font>                 <font color=Crimson>-- Stack ptr; points to last occupied stack location.</font>
     289  <font color=Blue>|</font> <font color=Green>SpLim</font>              <font color=Crimson>-- Stack limit</font>
     290  <font color=Blue>|</font> <font color=Green>Hp</font>                 <font color=Crimson>-- Heap ptr; points to last occupied heap location.</font>
     291  <font color=Blue>|</font> <font color=Green>HpLim</font>              <font color=Crimson>-- Heap limit register</font>
     292  <font color=Blue>|</font> <font color=Green>CurrentTSO</font>         <font color=Crimson>-- pointer to current thread's TSO</font>
     293  <font color=Blue>|</font> <font color=Green>CurrentNursery</font>     <font color=Crimson>-- pointer to allocation area</font>
     294  <font color=Blue>|</font> <font color=Green>HpAlloc</font>            <font color=Crimson>-- allocation count for heap check failure</font>
     295
     296  <font color=Crimson>-- We keep the address of some commonly-called </font>
     297  <font color=Crimson>-- functions in the register table, to keep code</font>
     298  <font color=Crimson>-- size down:</font>
     299  <font color=Blue>|</font> <font color=Green>GCEnter1</font>           <font color=Crimson>-- stg_gc_enter_1</font>
     300  <font color=Blue>|</font> <font color=Green>GCFun</font>              <font color=Crimson>-- stg_gc_fun</font>
     301
     302  <font color=Crimson>-- Base offset for the register table, used for accessing registers</font>
     303  <font color=Crimson>-- which do not have real registers assigned to them.  This register</font>
     304  <font color=Crimson>-- will only appear after we have expanded GlobalReg into memory accesses</font>
     305  <font color=Crimson>-- (where necessary) in the native code generator.</font>
    306306  <font color=Blue>|</font> <font color=Green>BaseReg</font>
    307307
    308   <font color=Red>-- Base Register for PIC (position-independent code) calculations</font>
    309   <font color=Red>-- Only used inside the native code generator. It's exact meaning differs</font>
    310   <font color=Red>-- from platform to platform  (see compiler/nativeGen/PositionIndependentCode.hs).</font>
     308  <font color=Crimson>-- Base Register for PIC (position-independent code) calculations</font>
     309  <font color=Crimson>-- Only used inside the native code generator. It's exact meaning differs</font>
     310  <font color=Crimson>-- from platform to platform  (see compiler/nativeGen/PositionIndependentCode.hs).</font>
    311311  <font color=Blue>|</font> <font color=Green>PicBaseReg</font>
    312312</pre>
     
    340340#!html
    341341<pre>
    342 <u><font color=Magenta>data</font></u> <font color=Green>MachHint</font>
    343   <font color=Blue>=</font> <font color=Green>NoHint</font>     <font color=Red>-- string: "NoHint"     Cmm syntax: [empty]</font>
    344   <font color=Blue>|</font> <font color=Green>PtrHint</font>    <font color=Red>-- string: "PtrHint"    Cmm syntax: "ptr"    (C-- uses "address")</font>
    345   <font color=Blue>|</font> <font color=Green>SignedHint</font> <font color=Red>-- string: "SignedHint" Cmm syntax: "signed"</font>
    346   <font color=Blue>|</font> <font color=Green>FloatHint</font>  <font color=Red>-- string: "FloatHint"  Cmm syntax: "float" </font>
     342<font color=DarkOrchid>data</font> <font color=Green>MachHint</font>
     343  <font color=Blue>=</font> <font color=Green>NoHint</font>     <font color=Crimson>-- string: "NoHint" Cmm syntax: [empty]</font>
     344  <font color=Blue>|</font> <font color=Green>PtrHint</font>    <font color=Crimson>-- string: "PtrHint"    Cmm syntax: "ptr"    (C-- uses "address")</font>
     345  <font color=Blue>|</font> <font color=Green>SignedHint</font> <font color=Crimson>-- string: "SignedHint"     Cmm syntax: "signed"</font>
     346  <font color=Blue>|</font> <font color=Green>FloatHint</font>  <font color=Crimson>-- string: "FloatHint"      Cmm syntax: "float" </font>
    347347</pre>
    348348}}}
     
    440440#!html
    441441<pre>
    442 <u><font color=Magenta>data</font></u> <font color=Green>CmmLit</font>
     442<font color=DarkOrchid>data</font> <font color=Green>CmmLit</font>
    443443  <font color=Blue>=</font> <font color=Green>CmmInt</font> <font color=Green>Integer</font>  <font color=Green>MachRep</font>
    444         <font color=Red>-- Interpretation: the 2's complement representation of the value</font>
    445         <font color=Red>-- is truncated to the specified size.  This is easier than trying</font>
    446         <font color=Red>-- to keep the value within range, because we don't know whether</font>
    447         <font color=Red>-- it will be used as a signed or unsigned value (the MachRep doesn't</font>
    448         <font color=Red>-- distinguish between signed &amp; unsigned).</font>
     444        <font color=Crimson>-- Interpretation: the 2's complement representation of the value</font>
     445        <font color=Crimson>-- is truncated to the specified size.  This is easier than trying</font>
     446        <font color=Crimson>-- to keep the value within range, because we don't know whether</font>
     447        <font color=Crimson>-- it will be used as a signed or unsigned value (the MachRep doesn't</font>
     448        <font color=Crimson>-- distinguish between signed &amp; unsigned).</font>
    449449  <font color=Blue>|</font> <font color=Green>CmmFloat</font>  <font color=Green>Rational</font> <font color=Green>MachRep</font>
    450   <font color=Blue>|</font> <font color=Green>CmmLabel</font>    <font color=Green>CLabel</font>                        <font color=Red>-- Address of label</font>
    451   <font color=Blue>|</font> <font color=Green>CmmLabelOff</font> <font color=Green>CLabel</font> <font color=Green>Int</font>           <font color=Red>-- Address of label + byte offset</font>
     450  <font color=Blue>|</font> <font color=Green>CmmLabel</font>    <font color=Green>CLabel</font>                        <font color=Crimson>-- Address of label</font>
     451  <font color=Blue>|</font> <font color=Green>CmmLabelOff</font> <font color=Green>CLabel</font> <font color=Green>Int</font>           <font color=Crimson>-- Address of label + byte offset</font>
    452452 
    453         <font color=Red>-- Due to limitations in the C backend, the following</font>
    454         <font color=Red>-- MUST ONLY be used inside the info table indicated by label2</font>
    455         <font color=Red>-- (label2 must be the info label), and label1 must be an</font>
    456         <font color=Red>-- SRT, a slow entrypoint or a large bitmap (see the Mangler)</font>
    457         <font color=Red>-- Don't use it at all unless tablesNextToCode.</font>
    458         <font color=Red>-- It is also used inside the NCG during when generating</font>
    459         <font color=Red>-- position-independent code. </font>
    460   <font color=Blue>|</font> <font color=Green>CmmLabelDiffOff</font> <font color=Green>CLabel</font> <font color=Green>CLabel</font> <font color=Green>Int</font>   <font color=Red>-- label1 - label2 + offset</font>
     453        <font color=Crimson>-- Due to limitations in the C backend, the following</font>
     454        <font color=Crimson>-- MUST ONLY be used inside the info table indicated by label2</font>
     455        <font color=Crimson>-- (label2 must be the info label), and label1 must be an</font>
     456        <font color=Crimson>-- SRT, a slow entrypoint or a large bitmap (see the Mangler)</font>
     457        <font color=Crimson>-- Don't use it at all unless tablesNextToCode.</font>
     458        <font color=Crimson>-- It is also used inside the NCG during when generating</font>
     459        <font color=Crimson>-- position-independent code. </font>
     460  <font color=Blue>|</font> <font color=Green>CmmLabelDiffOff</font> <font color=Green>CLabel</font> <font color=Green>CLabel</font> <font color=Green>Int</font>   <font color=Crimson>-- label1 - label2 + offset</font>
    461461</pre>
    462462}}}
    463463Note how the `CmmLit` constructor `CmmInt Integer MachRep` contains sign information in the `Integer`, the representation of the literal itself: this conforms to the C-- specification, where integral literals contain sign information. For an example of a function using `CmmInt` sign information, see `cmmMachOpFold` in [[GhcFile(compiler/cmm/CmmOpt.hs)]], where sign-operations are performed on the `Integer`.
    464464
    465 The `MachRep` of a literal, such as `CmmInt Integer MachRep` or `CmmFloat Rational MachRep` may not always require the size defined by `MachRep`.  The NCG optimiser, [[GhcFile(compiler/nativeGen/MachCodeGen.hs)]], will test a literal such as `1::bits32` (in Haskell, `CmmInt (1::Integer) I32`) for whether it would fit into the bit-size of Assembler instruction literals on that particular architecture with a function defined in [[GhcFile(compiler/nativeGen/MachRegs.lhs)]], such as `fits16Bits` on the PPC.  If the Integer literal fits, the function `makeImmediate` will truncate it to the specified size if possible and store it in a NCG data type, `Imm`, specifically `Maybe Imm`.  (These are also defined in [[GhcFile(compiler/nativeGen/MachRegs.lhs)]]).
     465The `MachRep` of a literal, such as `CmmInt Integer MachRep` or `CmmFloat Rational MachRep` may not always require the size defined by `MachRep`.  The NCG optimiser, [[GhcFile(compiler/nativeGen/MachCodeGen.hs)]], will test a literal such as `1::bits32` (in Haskell, `CmmInt (1::Integer) I32`) for whether it would fit into the bit-size of Assembler instruction literals on that particular architecture with a function defined in [[GhcFile(compiler/nativeGen/MachRegs.lhs)]], such as `fits16Bits` on the PPC.  If the Integer literal fits, the function `makeImmediate` will truncate it to the specified size if possible and store it in a NCG data type, `Imm`, specifically `Maybe Imm`.  (These are also defined in [[GhcFile(compiler/nativeGen/MachRegs.lhs)]].)
    466466
    467467The Haskell representation of Cmm separates unchangeable Cmm values into a separate data type, `CmmStatic`, defined in [[GhcFile(compiler/cmm/Cmm.hs)]]:
    468468{{{
    469 data CmmStatic
    470   = CmmStaticLit CmmLit
    471         -- a literal value, size given by cmmLitRep of the literal.
    472   | CmmUninitialised Int
    473         -- uninitialised data, N bytes long
    474   | CmmAlign Int
    475         -- align to next N-byte boundary (N must be a power of 2).
    476   | CmmDataLabel CLabel
    477         -- label the current position in this section.
    478   | CmmString [Word8]
    479         -- string of 8-bit values only, not zero terminated.
     469#!html
     470<pre>
     471<font color=DarkOrchid>data</font> <font color=Green>CmmStatic</font>
     472  <font color=Blue>=</font> <font color=Green>CmmStaticLit</font> <font color=Green>CmmLit</font>       
     473        <font color=Crimson>-- a literal value, size given by cmmLitRep of the literal.</font>
     474  <font color=Blue>|</font> <font color=Green>CmmUninitialised</font> <font color=Green>Int</font>
     475        <font color=Crimson>-- uninitialised data, N bytes long</font>
     476  <font color=Blue>|</font> <font color=Green>CmmAlign</font> <font color=Green>Int</font>
     477        <font color=Crimson>-- align to next N-byte boundary (N must be a power of 2).</font>
     478  <font color=Blue>|</font> <font color=Green>CmmDataLabel</font> <font color=Green>CLabel</font>
     479        <font color=Crimson>-- label the current position in this section.</font>
     480  <font color=Blue>|</font> <font color=Green>CmmString</font> <font color=Blue>[</font><font color=Green>Word8</font><font color=Blue>]</font>
     481        <font color=Crimson>-- string of 8-bit values only, not zero terminated.</font>
     482</pre>
    480483}}}
    481484Note the `CmmAlign` constructor: this maps to the assembler directive `.align N` to set alignment for a data item (hopefully one you remembered to label).  This is the same as the `align` directive noted in Section 4.5 of the [http://cminusminus.org/extern/man2.pdf C-- specification (PDF)].  In the current implementation of Cmm the `align` directive seems superfluous because [[GhcFile(compiler/nativeGen/PprMach.hs)]] translates `Section`s to assembler with alignment directives corresponding to the target architecture (see [wiki:Commentary/Compiler/CmmType#SectionsandDirectives Sections and Directives], below).
     
    491494Cmm labels conform to the C-- specification.  C--/Cmm uses labels to refer to memory locations in code--if you use a data directive but do not give it a label, you will have no means of referring to the memory!  For `GlobalReg`s (transformed to assembler `.globl`), labels serve as both symbols and labels (in the assembler meaning of the terms).  The Haskell representation of Cmm Labels is contained in the `CmmLit` data type, see [wiki:Commentary/Compiler/CmmType#Literals Literals] section, above.  Note how Cmm Labels are `CLabel`s with address information.  The `Clabel` data type, defined in [[GhcFile(compiler/cmm/CLabel.hs)]], is used throughout the Compiler for symbol information in binary files.  Here it is:
    492495{{{
    493 data CLabel
    494   = IdLabel                     -- A family of labels related to the
    495         Name                    -- definition of a particular Id or Con
    496         IdLabelInfo
    497 
    498   | DynIdLabel                  -- like IdLabel, but in a separate package,
    499         Name                    -- and might therefore need a dynamic
    500         IdLabelInfo             -- reference.
    501 
    502   | CaseLabel                   -- A family of labels related to a particular
    503                                 -- case expression.
    504         {-# UNPACK #-} !Unique  -- Unique says which case expression
    505         CaseLabelInfo
    506 
    507   | AsmTempLabel
    508         {-# UNPACK #-} !Unique
    509 
    510   | StringLitLabel
    511         {-# UNPACK #-} !Unique
    512 
    513   | ModuleInitLabel
    514         Module                  -- the module name
    515         String                  -- its "way"
    516         Bool                    -- True <=> is in a different package
    517         -- at some point we might want some kind of version number in
    518         -- the module init label, to guard against compiling modules in
    519         -- the wrong order.  We can't use the interface file version however,
    520         -- because we don't always recompile modules which depend on a module
    521         -- whose version has changed.
    522 
    523   | PlainModuleInitLabel        -- without the vesrion & way info
    524         Module
    525         Bool                    -- True <=> is in a different package
    526 
    527   | ModuleRegdLabel
    528 
    529   | RtsLabel RtsLabelInfo
    530 
    531   | ForeignLabel FastString     -- a 'C' (or otherwise foreign) label
    532         (Maybe Int)             -- possible '@n' suffix for stdcall functions
    533                 -- When generating C, the '@n' suffix is omitted, but when
    534                 -- generating assembler we must add it to the label.
    535         Bool                    -- True <=> is dynamic
    536 
    537   | CC_Label  CostCentre
    538   | CCS_Label CostCentreStack
    539 
    540       -- Dynamic Linking in the NCG:
    541       -- generated and used inside the NCG only,
    542       -- see compiler/nativeGen/PositionIndependentCode.hs for details.
     496#!html
     497<pre>
     498<font color=DarkOrchid>data</font> <font color=Green>CLabel</font>
     499  <font color=Blue>=</font> <font color=Green>IdLabel</font>                    <font color=Crimson>-- A family of labels related to the</font>
     500        <font color=Green>Name</font>                   <font color=Crimson>-- definition of a particular Id or Con</font>
     501        <font color=Green>IdLabelInfo</font>
     502
     503  <font color=Blue>|</font> <font color=Green>DynIdLabel</font>                 <font color=Crimson>-- like IdLabel, but in a separate package,</font>
     504        <font color=Green>Name</font>                   <font color=Crimson>-- and might therefore need a dynamic</font>
     505        <font color=Green>IdLabelInfo</font>            <font color=Crimson>-- reference.</font>
     506
     507  <font color=Blue>|</font> <font color=Green>CaseLabel</font>                  <font color=Crimson>-- A family of labels related to a particular</font>
     508                                <font color=Crimson>-- case expression.</font>
     509        <font color=Crimson>{-# UNPACK #-}</font> <font color=Blue>!</font><font color=Green>Unique</font>      <font color=Crimson>-- Unique says which case expression</font>
     510        <font color=Green>CaseLabelInfo</font>
     511
     512  <font color=Blue>|</font> <font color=Green>AsmTempLabel</font>
     513        <font color=Crimson>{-# UNPACK #-}</font> <font color=Blue>!</font><font color=Green>Unique</font>
     514
     515  <font color=Blue>|</font> <font color=Green>StringLitLabel</font>
     516        <font color=Crimson>{-# UNPACK #-}</font> <font color=Blue>!</font><font color=Green>Unique</font>
     517
     518  <font color=Blue>|</font> <font color=Green>ModuleInitLabel</font>
     519        <font color=Green>Module</font>                 <font color=Crimson>-- the module name</font>
     520        <font color=Green>String</font>                 <font color=Crimson>-- its "way"</font>
     521        <font color=Green>Bool</font>                   <font color=Crimson>-- True &lt;=&gt; is in a different package</font>
     522        <font color=Crimson>-- at some point we might want some kind of version number in</font>
     523        <font color=Crimson>-- the module init label, to guard against compiling modules in</font>
     524        <font color=Crimson>-- the wrong order.  We can't use the interface file version however,</font>
     525        <font color=Crimson>-- because we don't always recompile modules which depend on a module</font>
     526        <font color=Crimson>-- whose version has changed.</font>
     527
     528  <font color=Blue>|</font> <font color=Green>PlainModuleInitLabel</font>       <font color=Crimson>-- without the vesrion &amp; way info</font>
     529        <font color=Green>Module</font>
     530        <font color=Green>Bool</font>                   <font color=Crimson>-- True &lt;=&gt; is in a different package</font>
     531
     532  <font color=Blue>|</font> <font color=Green>ModuleRegdLabel</font>
     533
     534  <font color=Blue>|</font> <font color=Green>RtsLabel</font> <font color=Green>RtsLabelInfo</font>
     535
     536  <font color=Blue>|</font> <font color=Green>ForeignLabel</font> <font color=Green>FastString</font>   <font color=Crimson>-- a 'C' (or otherwise foreign) label</font>
     537        <font color=Blue>(</font><font color=Green>Maybe</font> <font color=Green>Int</font><font color=Blue>)</font>           <font color=Crimson>-- possible '@n' suffix for stdcall functions</font>
     538                <font color=Crimson>-- When generating C, the '@n' suffix is omitted, but when</font>
     539                <font color=Crimson>-- generating assembler we must add it to the label.</font>
     540        <font color=Green>Bool</font>                   <font color=Crimson>-- True &lt;=&gt; is dynamic</font>
     541
     542  <font color=Blue>|</font> <font color=Green>CC_Label</font>  <font color=Green>CostCentre</font>
     543  <font color=Blue>|</font> <font color=Green>CCS_Label</font> <font color=Green>CostCentreStack</font>
     544
     545      <font color=Crimson>-- Dynamic Linking in the NCG:</font>
     546      <font color=Crimson>-- generated and used inside the NCG only,</font>
     547      <font color=Crimson>-- see module PositionIndependentCode for details.</font>
    543548     
    544   | DynamicLinkerLabel DynamicLinkerLabelInfo CLabel
    545         -- special variants of a label used for dynamic linking
    546 
    547   | PicBaseLabel                -- a label used as a base for PIC calculations
    548                                 -- on some platforms.
    549                                 -- It takes the form of a local numeric
    550                                 -- assembler label '1'; it is pretty-printed
    551                                 -- as 1b, referring to the previous definition
    552                                 -- of 1: in the assembler source file.
    553 
    554   | DeadStripPreventer CLabel
    555     -- label before an info table to prevent excessive dead-stripping on darwin
    556 
    557   | HpcTicksLabel Module       -- Per-module table of tick locations
    558   | HpcModuleNameLabel         -- Per-module name of the module for Hpc
    559 
    560   deriving (Eq, Ord)
     549  <font color=Blue>|</font> <font color=Green>DynamicLinkerLabel</font> <font color=Green>DynamicLinkerLabelInfo</font> <font color=Green>CLabel</font>
     550        <font color=Crimson>-- special variants of a label used for dynamic linking</font>
     551
     552  <font color=Blue>|</font> <font color=Green>PicBaseLabel</font>                <font color=Crimson>-- a label used as a base for PIC calculations</font>
     553                                <font color=Crimson>-- on some platforms.</font>
     554                                <font color=Crimson>-- It takes the form of a local numeric</font>
     555                                <font color=Crimson>-- assembler label '1'; it is pretty-printed</font>
     556                                <font color=Crimson>-- as 1b, referring to the previous definition</font>
     557                                <font color=Crimson>-- of 1: in the assembler source file.</font>
     558
     559  <font color=Blue>|</font> <font color=Green>DeadStripPreventer</font> <font color=Green>CLabel</font>
     560    <font color=Crimson>-- label before an info table to prevent excessive dead-stripping on darwin</font>
     561
     562  <font color=Blue>|</font> <font color=Green>HpcTicksLabel</font> <font color=Green>Module</font>       <font color=Crimson>-- Per-module table of tick locations</font>
     563  <font color=Blue>|</font> <font color=Green>HpcModuleNameLabel</font>         <font color=Crimson>-- Per-module name of the module for Hpc</font>
     564  <font color=Blue>|</font> <font color=Green>HpcModuleOffsetLabel</font> <font color=Green>Module</font><font color=Crimson>-- Per-module offset of the module for Hpc (dynamically generated)</font>
     565
     566  <font color=DarkOrchid>deriving</font> <font color=Blue>(</font><font color=Green>Eq</font><font color=Blue>,</font> <font color=Green>Ord</font><font color=Blue>)</font>
     567</pre>
    561568}}}
    562569
     
    564571The Haskell representation of Cmm Section directives, in [[GhcFile(compiler/cmm/Cmm.hs)]] as the first part of the "Static Data" section, is:
    565572{{{
    566 data Section
    567   = Text               
    568   | Data               
    569   | ReadOnlyData       
    570   | RelocatableReadOnlyData
    571   | UninitialisedData
    572   | ReadOnlyData16      -- .rodata.cst16 on x86_64, 16-byte aligned
    573   | OtherSection String
     573#!html
     574<pre>
     575<font color=DarkOrchid>data</font> <font color=Green>Section</font>
     576  <font color=Blue>=</font> <font color=Green>Text</font>
     577  <font color=Blue>|</font> <font color=Green>Data</font>
     578  <font color=Blue>|</font> <font color=Green>ReadOnlyData</font>
     579  <font color=Blue>|</font> <font color=Green>RelocatableReadOnlyData</font>
     580  <font color=Blue>|</font> <font color=Green>UninitialisedData</font>
     581  <font color=Blue>|</font> <font color=Green>ReadOnlyData16</font>     <font color=Crimson>-- .rodata.cst16 on x86_64, 16-byte aligned</font>
     582  <font color=Blue>|</font> <font color=Green>OtherSection</font> <font color=Green>String</font>
     583</pre>
    574584}}}
    575585Cmm supports the following directives, corresponding to the assembler directives pretty-printed by the `pprSectionHeader` function in [[GhcFile(compiler/nativeGen/PprMach.hs)]]:
     
    634644These are all included as constructors in the `CmmExpr` data type, defined in [[GhcFile(compiler/cmm/Cmm.hs)]]:
    635645{{{
    636 data CmmExpr
    637   = CmmLit CmmLit               -- Literal or Label (name)
    638   | CmmLoad CmmExpr MachRep     -- Read memory location (memory reference)
    639   | CmmReg CmmReg               -- Contents of register
    640   | CmmMachOp MachOp [CmmExpr]  -- operation (+, -, *, `lt`, etc.)
    641   | CmmRegOff CmmReg Int       
     646#!html
     647<pre>
     648<font color=DarkOrchid>data</font> <font color=Green>CmmExpr</font>
     649  <font color=Blue>=</font> <font color=Green>CmmLit</font> <font color=Green>CmmLit</font>               <font color=Crimson>-- Literal or Label (name)</font>
     650  <font color=Blue>|</font> <font color=Green>CmmLoad</font> <font color=Green>CmmExpr</font> <font color=Green>MachRep</font>     <font color=Crimson>-- Read memory location (memory reference)</font>
     651  <font color=Blue>|</font> <font color=Green>CmmReg</font> <font color=Green>CmmReg</font>             <font color=Crimson>-- Contents of register</font>
     652  <font color=Blue>|</font> <font color=Green>CmmMachOp</font> <font color=Green>MachOp</font> <font color=Blue>[</font><font color=Green>CmmExpr</font><font color=Blue>]</font>  <font color=Crimson>-- operation (+, -, *, etc.)</font>
     653  <font color=Blue>|</font> <font color=Green>CmmRegOff</font> <font color=Green>CmmReg</font> <font color=Green>Int</font>
     654</pre>
    642655}}}
    643656Note that `CmmRegOff reg i` is only shorthand for a specific `CmmMachOp` application:
    644657{{{
    645 CmmMachOp (MO_Add rep) [(CmmReg reg),(CmmLit (CmmInt i rep))]
    646         where rep = cmmRegRep reg
     658#!html
     659<pre>
     660<font color=Green>CmmMachOp</font> <font color=Blue>(</font><font color=Green>MO_Add</font> rep<font color=Blue>) [(</font><font color=Green>CmmReg</font> reg<font color=Blue>)</font>,<font color=Blue>(</font><font color=Green>CmmLit</font> <font color=Blue>(</font><font color=Green>CmmInt</font> i rep<font color=Blue>))]</font>
     661        <font color=DarkOrchid>where</font> rep <font color=Blue>=</font> <font color=Orange>cmmRegRep</font> reg
     662</pre>
    647663}}}
    648664The function `cmmRegRep` is described below.  Note: the original comment following `CmmExpr` in [[GhcFile(compiler/cmm/Cmm.hs)]] is erroneous (cf., `mangleIndexTree` in [[GhcFile(compiler/nativeGen/MachCodeGen.hs)]]) but makes the same point described here.  The offset, `(CmmLit (CmmInt i rep))`, is a literal (`CmmLit`), not a name (`CLabel`).  A `CmmExpr` for an offset must be reducible to a `CmmInt` ''in Haskell''; in other words, offsets in Cmm expressions may not be external symbols whose addresses are not resolvable in the current context.
     
    657673Boolean conditions include: `&&`, `||`, `!` and parenthetical combinations of boolean conditions.  The `if expr { }` and `if expr { } else { }` statements contain boolean conditions.  The C-- type produced by conditional expressions is `bool`, in Cmm, type `BoolExpr` in [[GhcFile(compiler/cmm/CmmParse.y)]]:
    658674{{{
    659 data BoolExpr
    660   = BoolExpr `BoolAnd` BoolExpr
    661   | BoolExpr `BoolOr`  BoolExpr
    662   | BoolNot BoolExpr
    663   | BoolTest CmmExpr
     675#!html
     676<pre>
     677<font color=DarkOrchid>data</font> <font color=Green>BoolExpr</font>
     678  <font color=Blue>=</font> <font color=Green>BoolExpr</font> <font color=Blue>`</font><font color=Green>BoolAnd</font><font color=Blue>`</font> <font color=Green>BoolExpr</font>
     679  <font color=Blue>|</font> <font color=Green>BoolExpr</font> <font color=Blue>`</font><font color=Green>BoolOr</font><font color=Blue>`</font>  <font color=Green>BoolExpr</font>
     680  <font color=Blue>|</font> <font color=Green>BoolNot</font> <font color=Green>BoolExpr</font>
     681  <font color=Blue>|</font> <font color=Green>BoolTest</font> <font color=Green>CmmExpr</font></pre>
    664682}}}
    665683The type `BoolExpr` maps to the `CmmCondBranch` or `CmmBranch` constructors of type `CmmStmt`, defined in [[GhcFile(compiler/cmm/Cmm.hs)]], see [wiki:Commentary/Compiler/CmmType#StatementsandCalls Statements and Calls].
     
    667685The `CmmExpr` constructor `CmmMachOp MachOp [CmmExpr]` is the core of every operator-based expression; the key here is `MachOp`, which in turn depends on the type of `MachRep` for each operand.  See [wiki:Commentary/Compiler/CmmType#FundamentalandPrimitiveOperators Fundamental and PrimitiveOperators].  In order to process `CmmExpr`s, the data type comes with a deconstructor function to obtain the relevant `MachRep`s, defined in [[GhcFile(compiler/cmm/Cmm.hs)]]:
    668686{{{
    669 cmmExprRep :: CmmExpr -> MachRep
    670 cmmExprRep (CmmLit lit)      = cmmLitRep lit
    671 cmmExprRep (CmmLoad _ rep)   = rep
    672 cmmExprRep (CmmReg reg)      = cmmRegRep reg
    673 cmmExprRep (CmmMachOp op _)  = resultRepOfMachOp op
    674 cmmExprRep (CmmRegOff reg _) = cmmRegRep reg
     687#!html
     688<pre>
     689<font color=Orange>cmmExprRep</font> <font color=Blue>::</font> <font color=Green>CmmExpr</font> <font color=Blue>-&gt;</font> <font color=Green>MachRep</font>
     690<font color=Orange>cmmExprRep</font> <font color=Blue>(</font><font color=Green>CmmLit</font> <font color=Black>lit</font><font color=Blue>)</font>      <font color=Blue>=</font> <font color=Orange>cmmLitRep</font> <font color=Black>lit</font>
     691<font color=Orange>cmmExprRep</font> <font color=Blue>(</font><font color=Green>CmmLoad</font> <font color=Magenta>_</font> <font color=Black>rep</font><font color=Blue>)</font>   <font color=Blue>=</font> <font color=Black>rep</font>
     692<font color=Orange>cmmExprRep</font> <font color=Blue>(</font><font color=Green>CmmReg</font> <font color=Black>reg</font><font color=Blue>)</font>      <font color=Blue>=</font> <font color=Orange>cmmRegRep</font> <font color=Black>reg</font>
     693<font color=Orange>cmmExprRep</font> <font color=Blue>(</font><font color=Green>CmmMachOp</font> <font color=Black>op</font> <font color=Magenta>_</font><font color=Blue>)</font>  <font color=Blue>=</font> <font color=Black>resultRepOfMachOp</font> <font color=Black>op</font>
     694<font color=Orange>cmmExprRep</font> <font color=Blue>(</font><font color=Green>CmmRegOff</font> <font color=Black>reg</font> <font color=Magenta>_</font><font color=Blue>)</font> <font color=Blue>=</font> <font color=Orange>cmmRegRep</font> <font color=Black>reg</font>
     695</pre>
    675696}}}
    676697The deconstructors `cmmLitRep` and `cmmRegRep` (with its supporting deconstructor `localRegRep`) are also defined in [[GhcFile(compiler/cmm/Cmm.hs)]].
     
    686707Remember that the assignment operator, `=`, is a statement since it has the "side effect" of modifying the value in `res`.  The `+` expression in the above statement, for a 32-bit architecture, would be represented in Haskell as:
    687708{{{
    688 CmmMachOp (MO_Add I32) [CmmReg (CmmLocal uniq I32), CmmReg (CmmLocal uniq I32)]
     709#!html
     710<pre>
     711<font color=Green>CmmMachOp</font> <font color=Blue>(</font><font color=Green>MO_Add</font> <font color=Green>I32</font><font color=Blue>)</font> <font color=Blue>[</font><font color=Green>CmmReg</font> <font color=Blue>(</font><font color=Green>CmmLocal</font> <font color=Black>uniq</font> <font color=Green>I32</font><font color=Blue>)</font><font color=Blue>,</font> <font color=Green>CmmReg</font> <font color=Blue>(</font><font color=Green>CmmLocal</font> <font color=Black>uniq</font> <font color=Green>I32</font><font color=Blue>)</font><font color=Blue>]</font>
     712</pre>
    689713}}}
    690714The `expr` production rule in the Cmm Parser [[GhcFile(compiler/cmm/CmmParse.y)]] maps tokens to "values", such as `+` to an addition operation, `MO_Add`.  The `mkMachOp` function in the Parser determines the `MachOp` type in `CmmMachOp MachOp [CmmExpr]` from the token value and the `MachRep` type of the `head` variable.  Notice that the simple `+` operator did not contain sign information, only the `MachRep`.  For `expr`, signed and other `MachOps`, see the `machOps` function in [[GhcFile(compiler/cmm/CmmParse.y)]].  Here is a table of operators and the corresponding `MachOp`s recognised by Cmm (listed in order of precedence):
     
    771795The Haskell representation of Cmm Statements is the data type `CmmStmt`, defined in [[GhcFile(compiler/cmm/Cmm.hs)]]:
    772796{{{
    773 data CmmStmt
    774   = CmmNop
    775   | CmmComment FastString
    776 
    777   | CmmAssign CmmReg CmmExpr     -- Assign to register
    778 
    779   | CmmStore CmmExpr CmmExpr     -- Assign to memory location.  Size is
    780                                  -- given by cmmExprRep of the rhs.
    781 
    782   | CmmCall                      -- A foreign call, with
    783      CmmCallTarget
    784      [(CmmReg,MachHint)]         -- zero or more results
    785      [(CmmExpr,MachHint)]        -- zero or more arguments
    786      (Maybe [GlobalReg])         -- Global regs that may need to be saved
    787                                  -- if they will be clobbered by the call.
    788                                  -- Nothing <=> save *all* globals that
    789                                  -- might be clobbered.
    790 
    791   | CmmBranch BlockId             -- branch to another BB in this fn
    792 
    793   | CmmCondBranch CmmExpr BlockId -- conditional branch
    794 
    795   | CmmSwitch CmmExpr [Maybe BlockId]   -- Table branch
    796         -- The scrutinee is zero-based;
    797         --      zero -> first block
    798         --      one  -> second block etc
    799         -- Undefined outside range, and when there's a Nothing
    800 
    801   | CmmJump CmmExpr [LocalReg]    -- Jump to another function, with these
    802                                   -- parameters.
     797#!html
     798<pre>
     799<font color=DarkOrchid>data</font> <font color=Green>CmmStmt</font>
     800  <font color=Blue>=</font> <font color=Green>CmmNop</font>
     801  <font color=Blue>|</font> <font color=Green>CmmComment</font> <font color=Green>FastString</font>
     802
     803  <font color=Blue>|</font> <font color=Green>CmmAssign</font> <font color=Green>CmmReg</font> <font color=Green>CmmExpr</font>  <font color=Crimson>-- Assign to register</font>
     804
     805  <font color=Blue>|</font> <font color=Green>CmmStore</font> <font color=Green>CmmExpr</font> <font color=Green>CmmExpr</font>     <font color=Crimson>-- Assign to memory location.  Size is</font>
     806                                 <font color=Crimson>-- given by cmmExprRep of the rhs.</font>
     807
     808  <font color=Blue>|</font> <font color=Green>CmmCall</font>                     <font color=Crimson>-- A foreign call, with </font>
     809     <font color=Green>CmmCallTarget</font>
     810     <font color=Blue>[</font><font color=Blue>(</font><font color=Green>CmmReg</font><font color=Blue>,</font><font color=Green>MachHint</font><font color=Blue>)</font><font color=Blue>]</font>       <font color=Crimson>-- zero or more results</font>
     811     <font color=Blue>[</font><font color=Blue>(</font><font color=Green>CmmExpr</font><font color=Blue>,</font><font color=Green>MachHint</font><font color=Blue>)</font><font color=Blue>]</font>      <font color=Crimson>-- zero or more arguments</font>
     812     <font color=Blue>(</font><font color=Green>Maybe</font> <font color=Blue>[</font><font color=Green>GlobalReg</font><font color=Blue>]</font><font color=Blue>)</font>       <font color=Crimson>-- Global regs that may need to be saved</font>
     813                                 <font color=Crimson>-- if they will be clobbered by the call.</font>
     814                                 <font color=Crimson>-- Nothing &lt;=&gt; save *all* globals that</font>
     815                                 <font color=Crimson>-- might be clobbered.</font>
     816
     817  <font color=Blue>|</font> <font color=Green>CmmBranch</font> <font color=Green>BlockId</font>             <font color=Crimson>-- branch to another BB in this fn</font>
     818
     819  <font color=Blue>|</font> <font color=Green>CmmCondBranch</font> <font color=Green>CmmExpr</font> <font color=Green>BlockId</font> <font color=Crimson>-- conditional branch</font>
     820
     821  <font color=Blue>|</font> <font color=Green>CmmSwitch</font> <font color=Green>CmmExpr</font> <font color=Blue>[</font><font color=Green>Maybe</font> <font color=Green>BlockId</font><font color=Blue>]</font>   <font color=Crimson>-- Table branch</font>
     822        <font color=Crimson>-- The scrutinee is zero-based; </font>
     823        <font color=Crimson>--  zero -&gt; first block</font>
     824        <font color=Crimson>--  one  -&gt; second block etc</font>
     825        <font color=Crimson>-- Undefined outside range, and when there's a Nothing</font>
     826
     827  <font color=Blue>|</font> <font color=Green>CmmJump</font> <font color=Green>CmmExpr</font> <font color=Blue>[</font><font color=Green>LocalReg</font><font color=Blue>]</font>    <font color=Crimson>-- Jump to another function, with these </font>
     828                                  <font color=Crimson>-- parameters.</font>
     829</pre>
    803830}}}
    804831Note how the constructor `CmmJump` contains `[LocalReg]`: this is the Cmm implementation of the C-- `jump` statement for calling another procedure where the parameters are the arguments passed to the other procedure. None of the parameters contain the address--in assembler, a label--of the caller, to return control to the caller.  The `CmmCall` constructor also lacks a parameter to store the caller's address.  Cmm implements C-- jump nesting and matching returns by ''tail calls'', as described in section 6.8 of the C-- specification.  Tail calls are managed through the [wiki:Commentary/Compiler/CodeGen CodeGen], see [[GhcFile(compiler/codeGen/CgTailCall.lhs)]].  You may have already noticed that the call target of the `CmmJump` is a `CmmExpr`: this is the Cmm implementation of computed procedure addresses, for example:
     
    826853The data type, `CmmCallTarget` is defined in [[GhcFile(compiler/cmm/Cmm.hs)]] as:
    827854{{{
    828 data CmmCallTarget
    829   = CmmForeignCall              -- Call to a foreign function
    830         CmmExpr                 -- literal label <=> static call
    831                                 -- other expression <=> dynamic call
    832         CCallConv               -- The calling convention
    833 
    834   | CmmPrim                     -- Call to a "primitive" (eg. sin, cos)
    835         CallishMachOp           -- These might be implemented as inline
    836                                 -- code by the backend.
     855#!html
     856<pre>
     857<font color=DarkOrchid>data</font> <font color=Green>CmmCallTarget</font>
     858  <font color=Blue>=</font> <font color=Green>CmmForeignCall</font>             <font color=Crimson>-- Call to a foreign function</font>
     859        <font color=Green>CmmExpr</font>                <font color=Crimson>-- literal label &lt;=&gt; static call</font>
     860                                <font color=Crimson>-- other expression &lt;=&gt; dynamic call</font>
     861        <font color=Green>CCallConv</font>              <font color=Crimson>-- The calling convention</font>
     862
     863  <font color=Blue>|</font> <font color=Green>CmmPrim</font>                    <font color=Crimson>-- Call to a "primitive" (eg. sin, cos)</font>
     864        <font color=Green>CallishMachOp</font>          <font color=Crimson>-- These might be implemented as inline</font>
     865                                <font color=Crimson>-- code by the backend.</font>
     866</pre>
    837867}}}
    838868`CCallConv` is defined in [[GhcFile(compiler/prelude/ForeignCall.lhs)]]; for information on register assignments, see comments in [[GhcFile(compiler/codeGen/CgCallConv.hs)]].
     
    851881   * have no side effects; and,
    852882   * are represented in Haskell using the `MachOp` data type;
    853  * ''primitive operations'' are special, usually inlined, procedures, represented in Haskell using the `CallishMachOp` data type; primitive operations may have side effects.
     883 * ''primitive operations'' (Cmm ''quasi-operators'') are special, usually inlined, procedures, represented in Haskell using the `CallishMachOp` data type; primitive operations may have side effects.
    854884The `MachOp` and `CallishMachOp` data types are defined in [[GhcFile(compiler/cmm/MachOp.hs)]].
    855885
     
    858888==== Operators ====
    859889{{{
    860 data MachOp
    861 
    862   -- Integer operations
    863   = MO_Add    MachRep
    864   | MO_Sub    MachRep
    865   | MO_Eq     MachRep
    866   | MO_Ne     MachRep
    867   | MO_Mul    MachRep           -- low word of multiply
    868   | MO_S_MulMayOflo MachRep     -- nonzero if signed multiply overflows
    869   | MO_S_Quot MachRep           -- signed / (same semantics as IntQuotOp)
    870   | MO_S_Rem  MachRep           -- signed % (same semantics as IntRemOp)
    871   | MO_S_Neg  MachRep           -- unary -
    872   | MO_U_MulMayOflo MachRep     -- nonzero if unsigned multiply overflows
    873   | MO_U_Quot MachRep           -- unsigned / (same semantics as WordQuotOp)
    874   | MO_U_Rem  MachRep           -- unsigned % (same semantics as WordRemOp)
    875 
    876   -- Signed comparisons (floating-point comparisons also use these)
    877   | MO_S_Ge MachRep
    878   | MO_S_Le MachRep
    879   | MO_S_Gt MachRep
    880   | MO_S_Lt MachRep
    881 
    882   -- Unsigned comparisons
    883   | MO_U_Ge MachRep
    884   | MO_U_Le MachRep
    885   | MO_U_Gt MachRep
    886   | MO_U_Lt MachRep
    887 
    888   -- Bitwise operations.  Not all of these may be supported at all sizes,
    889   -- and only integral MachReps are valid.
    890   | MO_And   MachRep
    891   | MO_Or    MachRep
    892   | MO_Xor   MachRep
    893   | MO_Not   MachRep
    894   | MO_Shl   MachRep
    895   | MO_U_Shr MachRep    -- unsigned shift right
    896   | MO_S_Shr MachRep    -- signed shift right
    897 
    898   -- Conversions.  Some of these will be NOPs.
    899   -- Floating-point conversions use the signed variant.
    900   | MO_S_Conv MachRep{-from-} MachRep{-to-}     -- signed conversion
    901   | MO_U_Conv MachRep{-from-} MachRep{-to-}     -- unsigned conversion
     890#!html
     891<pre>
     892<font color=DarkOrchid>data</font> <font color=Green>MachOp</font>
     893
     894  <font color=Crimson>-- Integer operations</font>
     895  <font color=Blue>=</font> <font color=Green>MO_Add</font>    <font color=Green>MachRep</font>
     896  <font color=Blue>|</font> <font color=Green>MO_Sub</font>    <font color=Green>MachRep</font>
     897  <font color=Blue>|</font> <font color=Green>MO_Eq</font>     <font color=Green>MachRep</font>
     898  <font color=Blue>|</font> <font color=Green>MO_Ne</font>     <font color=Green>MachRep</font>
     899  <font color=Blue>|</font> <font color=Green>MO_Mul</font>    <font color=Green>MachRep</font>         <font color=Crimson>-- low word of multiply</font>
     900  <font color=Blue>|</font> <font color=Green>MO_S_MulMayOflo</font> <font color=Green>MachRep</font>   <font color=Crimson>-- nonzero if signed multiply overflows</font>
     901  <font color=Blue>|</font> <font color=Green>MO_S_Quot</font> <font color=Green>MachRep</font>         <font color=Crimson>-- signed / (same semantics as IntQuotOp)</font>
     902  <font color=Blue>|</font> <font color=Green>MO_S_Rem</font>  <font color=Green>MachRep</font>         <font color=Crimson>-- signed % (same semantics as IntRemOp)</font>
     903  <font color=Blue>|</font> <font color=Green>MO_S_Neg</font>  <font color=Green>MachRep</font>         <font color=Crimson>-- unary -</font>
     904  <font color=Blue>|</font> <font color=Green>MO_U_MulMayOflo</font> <font color=Green>MachRep</font>   <font color=Crimson>-- nonzero if unsigned multiply overflows</font>
     905  <font color=Blue>|</font> <font color=Green>MO_U_Quot</font> <font color=Green>MachRep</font>         <font color=Crimson>-- unsigned / (same semantics as WordQuotOp)</font>
     906  <font color=Blue>|</font> <font color=Green>MO_U_Rem</font>  <font color=Green>MachRep</font>         <font color=Crimson>-- unsigned % (same semantics as WordRemOp)</font>
     907
     908  <font color=Crimson>-- Signed comparisons (floating-point comparisons also use these)</font>
     909  <font color=Blue>|</font> <font color=Green>MO_S_Ge</font> <font color=Green>MachRep</font>
     910  <font color=Blue>|</font> <font color=Green>MO_S_Le</font> <font color=Green>MachRep</font>
     911  <font color=Blue>|</font> <font color=Green>MO_S_Gt</font> <font color=Green>MachRep</font>
     912  <font color=Blue>|</font> <font color=Green>MO_S_Lt</font> <font color=Green>MachRep</font>
     913
     914  <font color=Crimson>-- Unsigned comparisons</font>
     915  <font color=Blue>|</font> <font color=Green>MO_U_Ge</font> <font color=Green>MachRep</font>
     916  <font color=Blue>|</font> <font color=Green>MO_U_Le</font> <font color=Green>MachRep</font>
     917  <font color=Blue>|</font> <font color=Green>MO_U_Gt</font> <font color=Green>MachRep</font>
     918  <font color=Blue>|</font> <font color=Green>MO_U_Lt</font> <font color=Green>MachRep</font>
     919
     920  <font color=Crimson>-- Bitwise operations.  Not all of these may be supported at all sizes,</font>
     921  <font color=Crimson>-- and only integral MachReps are valid.</font>
     922  <font color=Blue>|</font> <font color=Green>MO_And</font>   <font color=Green>MachRep</font>
     923  <font color=Blue>|</font> <font color=Green>MO_Or</font>    <font color=Green>MachRep</font>
     924  <font color=Blue>|</font> <font color=Green>MO_Xor</font>   <font color=Green>MachRep</font>
     925  <font color=Blue>|</font> <font color=Green>MO_Not</font>   <font color=Green>MachRep</font>
     926  <font color=Blue>|</font> <font color=Green>MO_Shl</font>   <font color=Green>MachRep</font>
     927  <font color=Blue>|</font> <font color=Green>MO_U_Shr</font> <font color=Green>MachRep</font>  <font color=Crimson>-- unsigned shift right</font>
     928  <font color=Blue>|</font> <font color=Green>MO_S_Shr</font> <font color=Green>MachRep</font>  <font color=Crimson>-- signed shift right</font>
     929
     930  <font color=Crimson>-- Conversions.  Some of these will be NOPs.</font>
     931  <font color=Crimson>-- Floating-point conversions use the signed variant.</font>
     932  <font color=Blue>|</font> <font color=Green>MO_S_Conv</font> <font color=Green>MachRep</font><font color=Crimson>{-from-}</font> <font color=Green>MachRep</font><font color=Crimson>{-to-}</font>    <font color=Crimson>-- signed conversion</font>
     933  <font color=Blue>|</font> <font color=Green>MO_U_Conv</font> <font color=Green>MachRep</font><font color=Crimson>{-from-}</font> <font color=Green>MachRep</font><font color=Crimson>{-to-}</font>    <font color=Crimson>-- unsigned conversion</font>
     934</pre>
    902935}}}
    903936Each `MachOp` generally corresponds to a machine instruction but may have its value precomputed in the Cmm, NCG or HC optimisers. 
     
    907940
    908941{{{
    909 -- These MachOps tend to be implemented by foreign calls in some backends,
    910 -- so we separate them out.  In Cmm, these can only occur in a
    911 -- statement position, in contrast to an ordinary MachOp which can occur
    912 -- anywhere in an expression.
    913 data CallishMachOp
    914   = MO_F64_Pwr
    915   | MO_F64_Sin
    916   | MO_F64_Cos
    917   | MO_F64_Tan
    918   | MO_F64_Sinh
    919   | MO_F64_Cosh
    920   | MO_F64_Tanh
    921   | MO_F64_Asin
    922   | MO_F64_Acos
    923   | MO_F64_Atan
    924   | MO_F64_Log
    925   | MO_F64_Exp
    926   | MO_F64_Sqrt
    927   | MO_F32_Pwr
    928   | MO_F32_Sin
    929   | MO_F32_Cos
    930   | MO_F32_Tan
    931   | MO_F32_Sinh
    932   | MO_F32_Cosh
    933   | MO_F32_Tanh
    934   | MO_F32_Asin
    935   | MO_F32_Acos
    936   | MO_F32_Atan
    937   | MO_F32_Log
    938   | MO_F32_Exp
    939   | MO_F32_Sqrt
    940   | MO_WriteBarrier
     942#!html
     943<pre>
     944<font color=Crimson>-- These MachOps tend to be implemented by foreign calls in some backends,</font>
     945<font color=Crimson>-- so we separate them out.  In Cmm, these can only occur in a</font>
     946<font color=Crimson>-- statement position, in contrast to an ordinary MachOp which can occur</font>
     947<font color=Crimson>-- anywhere in an expression.</font>
     948<font color=DarkOrchid>data</font> <font color=Green>CallishMachOp</font>
     949  <font color=Blue>=</font> <font color=Green>MO_F64_Pwr</font>
     950  <font color=Blue>|</font> <font color=Green>MO_F64_Sin</font>
     951  <font color=Blue>|</font> <font color=Green>MO_F64_Cos</font>
     952  <font color=Blue>|</font> <font color=Green>MO_F64_Tan</font>
     953  <font color=Blue>|</font> <font color=Green>MO_F64_Sinh</font>
     954  <font color=Blue>|</font> <font color=Green>MO_F64_Cosh</font>
     955  <font color=Blue>|</font> <font color=Green>MO_F64_Tanh</font>
     956  <font color=Blue>|</font> <font color=Green>MO_F64_Asin</font>
     957  <font color=Blue>|</font> <font color=Green>MO_F64_Acos</font>
     958  <font color=Blue>|</font> <font color=Green>MO_F64_Atan</font>
     959  <font color=Blue>|</font> <font color=Green>MO_F64_Log</font>
     960  <font color=Blue>|</font> <font color=Green>MO_F64_Exp</font>
     961  <font color=Blue>|</font> <font color=Green>MO_F64_Sqrt</font>
     962  <font color=Blue>|</font> <font color=Green>MO_F32_Pwr</font>
     963  <font color=Blue>|</font> <font color=Green>MO_F32_Sin</font>
     964  <font color=Blue>|</font> <font color=Green>MO_F32_Cos</font>
     965  <font color=Blue>|</font> <font color=Green>MO_F32_Tan</font>
     966  <font color=Blue>|</font> <font color=Green>MO_F32_Sinh</font>
     967  <font color=Blue>|</font> <font color=Green>MO_F32_Cosh</font>
     968  <font color=Blue>|</font> <font color=Green>MO_F32_Tanh</font>
     969  <font color=Blue>|</font> <font color=Green>MO_F32_Asin</font>
     970  <font color=Blue>|</font> <font color=Green>MO_F32_Acos</font>
     971  <font color=Blue>|</font> <font color=Green>MO_F32_Atan</font>
     972  <font color=Blue>|</font> <font color=Green>MO_F32_Log</font>
     973  <font color=Blue>|</font> <font color=Green>MO_F32_Exp</font>
     974  <font color=Blue>|</font> <font color=Green>MO_F32_Sqrt</font>
     975  <font color=Blue>|</font> <font color=Green>MO_WriteBarrier</font>
     976</pre>
    941977}}}
    942978For an example, the floating point sine function, `sinFloat#` in [[GhcFile(compiler/prelude/primops.txt.pp)]] is piped through the `callishOp` function in [[GhcFile(compiler/codegen/CgPrimOp.hs)]] to become `Just MO_F32_Sin`.  The `CallishMachOp` constructor `MO_F32_Sin` is piped through [[GhcFile(compiler/nativeGen/MachCodeGen.hs)]], where the function `genCCall` will (for most architectures) call `outOfLineFloatOp` to issue a call to a C function such as `sin`.