]> Cypherpunks.ru repositories - gostls13.git/blobdiff - doc/asm.html
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / doc / asm.html
index d89072e319654e17ab9790c1b0288db2f5d5b247..f7787a4076ce600dbce55eef8b1dbdccdf2898c5 100644 (file)
@@ -125,8 +125,8 @@ it is a distinct program, so there are some differences.
 One is in constant evaluation.
 Constant expressions in the assembler are parsed using Go's operator
 precedence, not the C-like precedence of the original.
-Thus <code>3&amp;1<<2</code> is 4, not 0—it parses as <code>(3&amp;1)<<2</code>
-not <code>3&amp;(1<<2)</code>.
+Thus <code>3&amp;1&lt;&lt;2</code> is 4, not 0—it parses as <code>(3&amp;1)&lt;&lt;2</code>
+not <code>3&amp;(1&lt;&lt;2)</code>.
 Also, constants are always evaluated as 64-bit unsigned integers.
 Thus <code>-2</code> is not the integer value minus two,
 but the unsigned 64-bit integer with the same bit pattern.
@@ -166,7 +166,7 @@ jumps and branches.
 </li>
 
 <li>
-<code>SP</code>: Stack pointer: top of stack.
+<code>SP</code>: Stack pointer: the highest address within the local stack frame.
 </li>
 
 </ul>
@@ -216,7 +216,7 @@ If a Go prototype does not name its result, the expected assembly name is <code>
 The <code>SP</code> pseudo-register is a virtual stack pointer
 used to refer to frame-local variables and the arguments being
 prepared for function calls.
-It points to the top of the local stack frame, so references should use negative offsets
+It points to the highest address within the local stack frame, so references should use negative offsets
 in the range [−framesize, 0):
 <code>x-8(SP)</code>, <code>y-4(SP)</code>, and so on.
 </p>
@@ -409,7 +409,7 @@ The linker will choose one of the duplicates to use.
 (For <code>TEXT</code> items.)
 Don't insert the preamble to check if the stack must be split.
 The frame for the routine, plus anything it calls, must fit in the
-spare space at the top of the stack segment.
+spare space remaining in the current stack segment.
 Used to protect routines such as the stack splitting code itself.
 </li>
 <li>
@@ -437,8 +437,84 @@ This is a wrapper function and should not count as disabling <code>recover</code
 (For <code>TEXT</code> items.)
 This function is a closure so it uses its incoming context register.
 </li>
+<li>
+<code>LOCAL</code> = 128
+<br>
+This symbol is local to the dynamic shared object.
+</li>
+<li>
+<code>TLSBSS</code> = 256
+<br>
+(For <code>DATA</code> and <code>GLOBL</code> items.)
+Put this data in thread local storage.
+</li>
+<li>
+<code>NOFRAME</code> = 512
+<br>
+(For <code>TEXT</code> items.)
+Do not insert instructions to allocate a stack frame and save/restore the return
+address, even if this is not a leaf function.
+Only valid on functions that declare a frame size of 0.
+</li>
+<li>
+<code>TOPFRAME</code> = 2048
+<br>
+(For <code>TEXT</code> items.)
+Function is the outermost frame of the call stack. Traceback should stop at this function.
+</li>
 </ul>
 
+<h3 id="data-offsets">Interacting with Go types and constants</h3>
+
+<p>
+If a package has any .s files, then <code>go build</code> will direct
+the compiler to emit a special header called <code>go_asm.h</code>,
+which the .s files can then <code>#include</code>.
+The file contains symbolic <code>#define</code> constants for the
+offsets of Go struct fields, the sizes of Go struct types, and most
+Go <code>const</code> declarations defined in the current package.
+Go assembly should avoid making assumptions about the layout of Go
+types and instead use these constants.
+This improves the readability of assembly code, and keeps it robust to
+changes in data layout either in the Go type definitions or in the
+layout rules used by the Go compiler.
+</p>
+
+<p>
+Constants are of the form <code>const_<i>name</i></code>.
+For example, given the Go declaration <code>const bufSize =
+1024</code>, assembly code can refer to the value of this constant
+as <code>const_bufSize</code>.
+</p>
+
+<p>
+Field offsets are of the form <code><i>type</i>_<i>field</i></code>.
+Struct sizes are of the form <code><i>type</i>__size</code>.
+For example, consider the following Go definition:
+</p>
+
+<pre>
+type reader struct {
+       buf [bufSize]byte
+       r   int
+}
+</pre>
+
+<p>
+Assembly can refer to the size of this struct
+as <code>reader__size</code> and the offsets of the two fields
+as <code>reader_buf</code> and <code>reader_r</code>.
+Hence, if register <code>R1</code> contains a pointer to
+a <code>reader</code>, assembly can reference the <code>r</code> field
+as <code>reader_r(R1)</code>.
+</p>
+
+<p>
+If any of these <code>#define</code> names are ambiguous (for example,
+a struct with a <code>_size</code> field), <code>#include
+"go_asm.h"</code> will fail with a "redefinition of macro" error.
+</p>
+
 <h3 id="runtime">Runtime Coordination</h3>
 
 <p>
@@ -590,21 +666,15 @@ Here follow some descriptions of key Go-specific details for the supported archi
 <p>
 The runtime pointer to the <code>g</code> structure is maintained
 through the value of an otherwise unused (as far as Go is concerned) register in the MMU.
-An OS-dependent macro <code>get_tls</code> is defined for the assembler if the source is
-in the <code>runtime</code> package and includes a special header, <code>go_tls.h</code>:
+In the runtime package, assembly code can include <code>go_tls.h</code>, which defines
+an OS- and architecture-dependent macro <code>get_tls</code> for accessing this register.
+The <code>get_tls</code> macro takes one argument, which is the register to load the
+<code>g</code> pointer into.
 </p>
 
-<pre>
-#include "go_tls.h"
-</pre>
-
 <p>
-Within the runtime, the <code>get_tls</code> macro loads its argument register
-with a pointer to the <code>g</code> pointer, and the <code>g</code> struct
-contains the <code>m</code> pointer.
-There's another special header containing the offsets for each
-element of <code>g</code>, called <code>go_asm.h</code>.
-The sequence to load <code>g</code> and <code>m</code> using <code>CX</code> looks like this:
+For example, the sequence to load <code>g</code> and <code>m</code>
+using <code>CX</code> looks like this:
 </p>
 
 <pre>
@@ -617,8 +687,7 @@ MOVL        g_m(AX), BX   // Move g.m into BX.
 </pre>
 
 <p>
-Note: The code above works only in the <code>runtime</code> package, while <code>go_tls.h</code> also
-applies to <a href="#arm">arm</a>, <a href="#amd64">amd64</a> and amd64p32, and <code>go_asm.h</code> applies to all architectures.
+The <code>get_tls</code> macro is also defined on <a href="#amd64">amd64</a>.
 </p>
 
 <p>
@@ -662,6 +731,13 @@ MOVQ       g(CX), AX     // Move g into AX.
 MOVQ   g_m(AX), BX   // Move g.m into BX.
 </pre>
 
+<p>
+Register <code>BP</code> is callee-save.
+The assembler automatically inserts <code>BP</code> save/restore when frame size is larger than zero.
+Using <code>BP</code> as a general purpose register is allowed,
+however it can interfere with sampling-based profiling.
+</p>
+
 <h3 id="arm">ARM</h3>
 
 <p>
@@ -751,10 +827,6 @@ The other codes are <code>-&gt;</code> (arithmetic right shift),
 
 <h3 id="arm64">ARM64</h3>
 
-<p>
-The ARM64 port is in an experimental state.
-</p>
-
 <p>
 <code>R18</code> is the "platform register", reserved on the Apple platform.
 To prevent accidental misuse, the register is named <code>R18_PLATFORM</code>.
@@ -842,8 +914,6 @@ This assembler is used by GOARCH values ppc64 and ppc64le.
 Reference: <a href="/pkg/cmd/internal/obj/ppc64">Go PPC64 Assembly Instructions Reference Manual</a>
 </p>
 
-</ul>
-
 <h3 id="s390x">IBM z/Architecture, a.k.a. s390x</h3>
 
 <p>