diff --git a/doc/asm.html b/doc/asm.html index b283efde61..76aecad54c 100644 --- a/doc/asm.html +++ b/doc/asm.html @@ -514,42 +514,61 @@ even pointers to stack data must not be kept in local variables.

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

-enum	as
-{
-	AXXX,
-	AAAA,
-	AAAD,
-	AAAM,
-	AAAS,
-	AADCB,
+const (
+	AAND = obj.ABaseARM + obj.A_ARCHSPECIFIC + iota
+	AEOR
+	ASUB
+	ARSB
+	AADD
 	...
 

-Each instruction begins with a initial capital A in this list, so AADCB -represents the ADCB (add carry byte) instruction. -The enumeration is in alphabetical order, plus some late additions (AXXX occupies -the zero slot as an invalid instruction). -The sequence has nothing to do with the actual encoding of the machine instructions. -Again, the linker takes care of that detail. +This is the list of instructions and their spellings as known to the assembler and linker for that architecture. +Each instruction begins with an initial capital A in this list, so AAND +represents the bitwise and instruction, +AND (without the leading A), +and is written in assembly source as AND. +The enumeration is mostly in alphabetical order. +(The architecture-independent AXXX, defined in the +cmd/internal/obj package, +represents an invalid instruction). +The sequence of the A names has nothing to do with the actual +encoding of the machine instructions. +The cmd/internal/obj package takes care of that detail. +

+ +

+The instructions for both the 386 and AMD64 architectures are listed in +cmd/internal/obj/x86/a.out.go. +

+ +

+The architectures share syntax for common addressing modes such as +(R1) (register indirect), +4(R1) (register indirect with offset), and +$foo(SB) (absolute address). +The assembler also supports some (not necessarily all) addressing modes +specific to each architecture. +The sections below list these.

One detail evident in the examples from the previous sections is that data in the instructions flows from left to right: MOVQ $0, CX clears CX. -This convention applies even on architectures where the usual mode is the opposite direction. +This rule applies even on architectures where the conventional notation uses the opposite direction.

-Here follows some descriptions of key Go-specific details for the supported architectures. +Here follow some descriptions of key Go-specific details for the supported architectures.

32-bit Intel 386

@@ -558,11 +577,11 @@ Here follows some descriptions of key Go-specific details for the supported arch The runtime pointer to the g structure is maintained through the value of an otherwise unused (as far as Go is concerned) register in the MMU. A OS-dependent macro get_tls is defined for the assembler if the source includes -an architecture-dependent header file, like this: +a special header, go_asm.h:

-#include "zasm_GOOS_GOARCH.h"
+#include "go_asm.h"
 

@@ -575,21 +594,39 @@ The sequence to load g and m using CX loo

 get_tls(CX)
 MOVL	g(CX), AX     // Move g into AX.
-MOVL	g_m(AX), BX   // Move g->m into BX.
+MOVL	g_m(AX), BX   // Move g.m into BX.
 
+

+Addressing modes: +

+ + +

64-bit Intel 386 (a.k.a. amd64)

-The assembly code to access the m and g -pointers is the same as on the 386, except it uses MOVQ rather than -MOVL: +The two architectures behave largely the same at the assembler level. +Assembly code to access the m and g +pointers on the 64-bit version is the same as on the 32-bit 386, +except it uses MOVQ rather than MOVL:

 get_tls(CX)
 MOVQ	g(CX), AX     // Move g into AX.
-MOVQ	g_m(AX), BX   // Move g->m into BX.
+MOVQ	g_m(AX), BX   // Move g.m into BX.
 

ARM

@@ -626,6 +663,85 @@ The name SP always refers to the virtual stack pointer described ea For the hardware register, use R13.

+

+Addressing modes: +

+ + + +

ARM64

+ +

+TODO +

+ +

+Addressing modes: +

+ + + +

Power64, a.k.a. ppc64

+ +

+TODO +

+ +

+Addressing modes: +

+ + +

Unsupported opcodes

@@ -644,11 +760,17 @@ Here's how the 386 runtime defines the 64-bit atomic load function. // uint64 atomicload64(uint64 volatile* addr); // so actually // void atomicload64(uint64 *res, uint64 volatile *addr); -TEXT runtime·atomicload64(SB), NOSPLIT, $0-8 +TEXT runtime·atomicload64(SB), NOSPLIT, $0-12 MOVL ptr+0(FP), AX + TESTL $7, AX + JZ 2(PC) + MOVL 0, AX // crash with nil ptr deref LEAL ret_lo+4(FP), BX - BYTE $0x0f; BYTE $0x6f; BYTE $0x00 // MOVQ (%EAX), %MM0 - BYTE $0x0f; BYTE $0x7f; BYTE $0x03 // MOVQ %MM0, 0(%EBX) - BYTE $0x0F; BYTE $0x77 // EMMS + // MOVQ (%EAX), %MM0 + BYTE $0x0f; BYTE $0x6f; BYTE $0x00 + // MOVQ %MM0, 0(%EBX) + BYTE $0x0f; BYTE $0x7f; BYTE $0x03 + // EMMS + BYTE $0x0F; BYTE $0x77 RET