]> git.sur5r.net Git - cc65/blobdiff - doc/cc65-intern.sgml
Minor clarification.
[cc65] / doc / cc65-intern.sgml
index f3aef939a910c68276e755a9606d8e8717e1b1d7..ec6c48ca31da9e0e4d4bdc04660da79f765ea63a 100644 (file)
@@ -2,8 +2,7 @@
 
 <article>
 <title>cc65 internals
-<author><url url="mailto:brad@rainwarrior.ca" name="Brad Smith">
-<date>2016-02-27
+<author><url url="mailto:bbbradsmith@users.noreply.github.com" name="Brad Smith">
 
 <abstract>
 Internal details of cc65 code generation,
@@ -27,7 +26,7 @@ There are two calling conventions used in cc65:
   <item><tt/cdecl/ - passes all parameters on the C-stack.
   <p>
   <item><tt/fastcall/ - passes the rightmost parameter in
-  registers <tt>A/X/sreg</tt> an all others on the C-stack.
+  registers <tt>A/X/sreg</tt> and all others on the C-stack.
   <p>
 </itemize>
 
@@ -40,7 +39,11 @@ If the <tt/--standard/ command line option is used,
 the <tt/cdecl/ and <tt/fastcall/ keywords will not be available.
 The standard compliant variations <tt/__cdecl__/ and <tt/__fastcall__/ are always available.
 
-K &amp; R style function prototypes may be used, but they do not alter the calling conventions in any way.
+If a function has a prototype, parameters are pushed to the C-stack as their respective types
+(i.e. a <tt/char/ parameter will push 1 byte), but if a function has no prototype, default
+promotions will apply. This means that with no prototype, <tt/char/ will be promoted
+to <tt/int/ and be pushed as 2 bytes. K &amp; R style function prototypes may be used,
+but they will function the same as if no prototype was used.
 
 <sect1>Prologue, before the function call<p>
 
@@ -48,7 +51,7 @@ If the function is declared as fastcall, the rightmost argument will be loaded i
 the <tt>A/X/sreg</tt> registers:
 
 <itemize>
-  <item><tt/A/ - 8-bit parameter, or low byte of larger tyes<p>
+  <item><tt/A/ - 8-bit parameter, or low byte of larger types<p>
   <item><tt/X/ - 16-bit high byte, or second byte of 32-bits<p>
   <item><tt/sreg/ - Zeropage pseudo-register including high 2 bytes of 32-bit parameter<p>
 </itemize>
@@ -57,13 +60,14 @@ All other parameters will be pushed to the C-stack from left to right.
 The rightmost parameter will have the lowest address on the stack,
 and multi-byte parameters will have their least significant byte at the lower address.
 
-The <tt/Y/ register will contain the number of bytes pushed to the stack for this function,
-and the <tt/sp/ pseudo-register is a zeropage pointer to the base of the C-stack.
+The <tt/sp/ pseudo-register is a zeropage pointer to the base of the C-stack.
+If the function has no prototype or is variadic
+the <tt/Y/ register will contain the number of bytes pushed to the stack for this function.
 
 Example:
 <tscreen><verb>
 // C prototype
-void foo(unsigned bar, unsigned char baz);
+void cdecl foo(unsigned bar, unsigned char baz);
 
 ; C-stack layout within the function:
 ;
@@ -84,13 +88,9 @@ void foo(unsigned bar, unsigned char baz);
     lda     (sp),y  ; Low byte now in A
 </verb></tscreen>
 
-Variadic functions push all parameters exactly as other <tt/cdecl/ convention functions,
-but the value of <tt/Y/ should be used to determine how many bytes of parameters
-were placed onto the stack.
+<sect1>Epilogue, after the function call<p>
 
-<sect1>Epilogue, after the functiona call<p>
-
-<sect2>Return requirements</p>
+<sect2>Return requirements<p>
 
 If the function has a return value, it will appear in the <tt>A/X/sreg</tt> registers.
 
@@ -106,14 +106,14 @@ of <tt>A/X/sreg</tt>, so these may be clobbered by the function.
 
 The C-stack pointer <tt/sp/ must be restored by the function to its value before the
 function call prologue. It may pop all of its parameters from the C-stack
-(e.g. using the <tt/runtime/ function <tt/popa/.),
+(e.g. using the <tt/runtime/ function <tt/popa/),
 or it could adjust <tt/sp/ directly.
-On entry to the function the <tt/Y/ register contains the number of bytes
-pushed to the stack, which may be added to <tt/sp/ to restore its original state.
+If the function has no prototype, or is variadic the <tt/Y/ register contains the
+number of bytes pushed to the stack on entry, which may be added to <tt/sp/ to restore its original state.
 
 The internal pseudo-register <tt/regbank/ must not be changed by the function.
 
-<sect2>Clobbered state</p>
+<sect2>Clobbered state<p>
 
 The <tt/Y/ register may be clobbered by the function.
 The compiler will not depend on its state after a function call.
@@ -125,6 +125,7 @@ Many of the internal pseudo-registers used by cc65 are available for
 free use by any function called by C, and do not need to be preserved.
 Note that if another C function is called from your assembly function,
 it may clobber any of these itself:
+
 <itemize>
   <item><tt>tmp1 .. tmp4</tt><p>
   <item><tt>ptr1 .. ptr4</tt><p>