Skip to content

Commit 3c5eb96

Browse files
committed
doc: update the architecture-specific information in asm.html
Still to do: ARM64 and PPC64. These architectures are woefully underdocumented. Change-Id: Iedcf767a7e0e1c931812351940bc08f0c3821212 Reviewed-on: https://go-review.googlesource.com/12110 Reviewed-by: Russ Cox <[email protected]>
1 parent 1bd1880 commit 3c5eb96

File tree

1 file changed

+154
-32
lines changed

1 file changed

+154
-32
lines changed

doc/asm.html

Lines changed: 154 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -514,42 +514,61 @@ <h2 id="architectures">Architecture-specific details</h2>
514514

515515
<p>
516516
It is impractical to list all the instructions and other details for each machine.
517-
To see what instructions are defined for a given machine, say 32-bit Intel x86,
518-
look in the top-level header file for the corresponding linker, in this case <code>8l</code>.
519-
That is, the file <code>$GOROOT/src/cmd/8l/8.out.h</code> contains a C enumeration, called <code>as</code>,
520-
of the instructions and their spellings as known to the assembler and linker for that architecture.
521-
In that file you'll find a declaration that begins
517+
To see what instructions are defined for a given machine, say ARM,
518+
look in the source for the <code>obj</code> support library for
519+
that architecture, located in the directory <code>src/cmd/internal/obj/arm</code>.
520+
In that directory is a file <code>a.out.go</code>; it contains
521+
a long list of constants starting with <code>A</code>, like this:
522522
</p>
523523

524524
<pre>
525-
enum as
526-
{
527-
AXXX,
528-
AAAA,
529-
AAAD,
530-
AAAM,
531-
AAAS,
532-
AADCB,
525+
const (
526+
AAND = obj.ABaseARM + obj.A_ARCHSPECIFIC + iota
527+
AEOR
528+
ASUB
529+
ARSB
530+
AADD
533531
...
534532
</pre>
535533

536534
<p>
537-
Each instruction begins with a initial capital <code>A</code> in this list, so <code>AADCB</code>
538-
represents the <code>ADCB</code> (add carry byte) instruction.
539-
The enumeration is in alphabetical order, plus some late additions (<code>AXXX</code> occupies
540-
the zero slot as an invalid instruction).
541-
The sequence has nothing to do with the actual encoding of the machine instructions.
542-
Again, the linker takes care of that detail.
535+
This is the list of instructions and their spellings as known to the assembler and linker for that architecture.
536+
Each instruction begins with an initial capital <code>A</code> in this list, so <code>AAND</code>
537+
represents the bitwise and instruction,
538+
<code>AND</code> (without the leading <code>A</code>),
539+
and is written in assembly source as <code>AND</code>.
540+
The enumeration is mostly in alphabetical order.
541+
(The architecture-independent <code>AXXX</code>, defined in the
542+
<code>cmd/internal/obj</code> package,
543+
represents an invalid instruction).
544+
The sequence of the <code>A</code> names has nothing to do with the actual
545+
encoding of the machine instructions.
546+
The <code>cmd/internal/obj</code> package takes care of that detail.
547+
</p>
548+
549+
<p>
550+
The instructions for both the 386 and AMD64 architectures are listed in
551+
<code>cmd/internal/obj/x86/a.out.go</code>.
552+
</p>
553+
554+
<p>
555+
The architectures share syntax for common addressing modes such as
556+
<code>(R1)</code> (register indirect),
557+
<code>4(R1)</code> (register indirect with offset), and
558+
<code>$foo(SB)</code> (absolute address).
559+
The assembler also supports some (not necessarily all) addressing modes
560+
specific to each architecture.
561+
The sections below list these.
543562
</p>
544563

545564
<p>
546565
One detail evident in the examples from the previous sections is that data in the instructions flows from left to right:
547566
<code>MOVQ</code> <code>$0,</code> <code>CX</code> clears <code>CX</code>.
548-
This convention applies even on architectures where the usual mode is the opposite direction.
567+
This rule applies even on architectures where the conventional notation uses the opposite direction.
549568
</p>
550569

551570
<p>
552-
Here follows some descriptions of key Go-specific details for the supported architectures.
571+
Here follow some descriptions of key Go-specific details for the supported architectures.
553572
</p>
554573

555574
<h3 id="x86">32-bit Intel 386</h3>
@@ -558,11 +577,11 @@ <h3 id="x86">32-bit Intel 386</h3>
558577
The runtime pointer to the <code>g</code> structure is maintained
559578
through the value of an otherwise unused (as far as Go is concerned) register in the MMU.
560579
A OS-dependent macro <code>get_tls</code> is defined for the assembler if the source includes
561-
an architecture-dependent header file, like this:
580+
a special header, <code>go_asm.h</code>:
562581
</p>
563582

564583
<pre>
565-
#include "zasm_GOOS_GOARCH.h"
584+
#include "go_asm.h"
566585
</pre>
567586

568587
<p>
@@ -575,21 +594,39 @@ <h3 id="x86">32-bit Intel 386</h3>
575594
<pre>
576595
get_tls(CX)
577596
MOVL g(CX), AX // Move g into AX.
578-
MOVL g_m(AX), BX // Move g->m into BX.
597+
MOVL g_m(AX), BX // Move g.m into BX.
579598
</pre>
580599

600+
<p>
601+
Addressing modes:
602+
</p>
603+
604+
<ul>
605+
606+
<li>
607+
<code>(DI)(BX*2)</code>: The location at address <code>DI</code> plus <code>BX*2</code>.
608+
</li>
609+
610+
<li>
611+
<code>64(DI)(BX*2)</code>: The location at address <code>DI</code> plus <code>BX*2</code> plus 64.
612+
These modes accept only 1, 2, 4, and 8 as scale factors.
613+
</li>
614+
615+
</ul>
616+
581617
<h3 id="amd64">64-bit Intel 386 (a.k.a. amd64)</h3>
582618

583619
<p>
584-
The assembly code to access the <code>m</code> and <code>g</code>
585-
pointers is the same as on the 386, except it uses <code>MOVQ</code> rather than
586-
<code>MOVL</code>:
620+
The two architectures behave largely the same at the assembler level.
621+
Assembly code to access the <code>m</code> and <code>g</code>
622+
pointers on the 64-bit version is the same as on the 32-bit 386,
623+
except it uses <code>MOVQ</code> rather than <code>MOVL</code>:
587624
</p>
588625

589626
<pre>
590627
get_tls(CX)
591628
MOVQ g(CX), AX // Move g into AX.
592-
MOVQ g_m(AX), BX // Move g->m into BX.
629+
MOVQ g_m(AX), BX // Move g.m into BX.
593630
</pre>
594631

595632
<h3 id="arm">ARM</h3>
@@ -626,6 +663,85 @@ <h3 id="arm">ARM</h3>
626663
For the hardware register, use <code>R13</code>.
627664
</p>
628665

666+
<p>
667+
Addressing modes:
668+
</p>
669+
670+
<ul>
671+
672+
<li>
673+
<code>R0-&gt;16</code>
674+
<br>
675+
<code>R0&gt;&gt;16</code>
676+
<br>
677+
<code>R0&lt;&lt;16</code>
678+
<br>
679+
<code>R0@&gt;16</code>:
680+
For <code>&lt;&lt;</code>, left shift <code>R0</code> by 16 bits.
681+
The other codes are <code>-&gt;</code> (arithmetic right shift),
682+
<code>&gt;&gt;</code> (logical right shift), and
683+
<code>@&gt;</code> (rotate right).
684+
</li>
685+
686+
<li>
687+
<code>R0-&gt;R1</code>
688+
<br>
689+
<code>R0&gt;&gt;R1</code>
690+
<br>
691+
<code>R0&lt;&lt;R1</code>
692+
<br>
693+
<code>R0@&gt;R1</code>:
694+
For <code>&lt;&lt;</code>, left shift <code>R0</code> by the count in <code>R1</code>.
695+
The other codes are <code>-&gt;</code> (arithmetic right shift),
696+
<code>&gt;&gt;</code> (logical right shift), and
697+
<code>@&gt;</code> (rotate right).
698+
699+
</li>
700+
701+
<li>
702+
<code>[R0,g,R12-R15]</code>: For multi-register instructions, the set comprising
703+
<code>R0</code>, <code>g</code>, and <code>R12</code> through <code>R15</code> inclusive.
704+
</li>
705+
706+
</ul>
707+
708+
<h3 id="arm64">ARM64</h3>
709+
710+
<p>
711+
TODO
712+
</p>
713+
714+
<p>
715+
Addressing modes:
716+
</p>
717+
718+
<ul>
719+
720+
<li>
721+
TODO
722+
</li>
723+
724+
</ul>
725+
726+
<h3 id="ppc64">Power64, a.k.a. ppc64</h3>
727+
728+
<p>
729+
TODO
730+
</p>
731+
732+
<p>
733+
Addressing modes:
734+
</p>
735+
736+
<ul>
737+
738+
<li>
739+
<code>(R5)(R6*1)</code>: The location at <code>R5</code> plus <code>R6</code>. It is a scaled
740+
mode like on the x86, but the only scale allowed is <code>1</code>.
741+
</li>
742+
743+
</ul>
744+
629745
<h3 id="unsupported_opcodes">Unsupported opcodes</h3>
630746

631747
<p>
@@ -644,11 +760,17 @@ <h3 id="unsupported_opcodes">Unsupported opcodes</h3>
644760
// uint64 atomicload64(uint64 volatile* addr);
645761
// so actually
646762
// void atomicload64(uint64 *res, uint64 volatile *addr);
647-
TEXT runtime·atomicload64(SB), NOSPLIT, $0-8
763+
TEXT runtime·atomicload64(SB), NOSPLIT, $0-12
648764
MOVL ptr+0(FP), AX
765+
TESTL $7, AX
766+
JZ 2(PC)
767+
MOVL 0, AX // crash with nil ptr deref
649768
LEAL ret_lo+4(FP), BX
650-
BYTE $0x0f; BYTE $0x6f; BYTE $0x00 // MOVQ (%EAX), %MM0
651-
BYTE $0x0f; BYTE $0x7f; BYTE $0x03 // MOVQ %MM0, 0(%EBX)
652-
BYTE $0x0F; BYTE $0x77 // EMMS
769+
// MOVQ (%EAX), %MM0
770+
BYTE $0x0f; BYTE $0x6f; BYTE $0x00
771+
// MOVQ %MM0, 0(%EBX)
772+
BYTE $0x0f; BYTE $0x7f; BYTE $0x03
773+
// EMMS
774+
BYTE $0x0F; BYTE $0x77
653775
RET
654776
</pre>

0 commit comments

Comments
 (0)