Commit ff5cf43d authored by isharipo's avatar isharipo Committed by Ilya Tocar

runtime,sync/atomic: replace asm BYTEs with insts for x86

For each replacement, test case is added to new 386enc.s file
with exception of EMMS, SYSENTER, MFENCE and LFENCE as they
are already covered in amd64enc.s (same on amd64 and 386).

The replacement became less obvious after go vet suggested changes
Before:
	BYTE $0x0f; BYTE $0x7f; BYTE $0x44; BYTE $0x24; BYTE $0x08
Changed to MOVQ (this form is being tested):
	MOVQ M0, 8(SP)
Refactored to FP-relative access (go vet advice):
	MOVQ M0, val+4(FP)

Change-Id: I56b87cf3371b6ad81ad0cd9db2033aee407b5818
Reviewed-on: https://go-review.googlesource.com/101475
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarIlya Tocar <ilya.tocar@intel.com>
parent 65727ab5
...@@ -393,6 +393,10 @@ func TestAMD64EndToEnd(t *testing.T) { ...@@ -393,6 +393,10 @@ func TestAMD64EndToEnd(t *testing.T) {
testEndToEnd(t, "amd64", "amd64") testEndToEnd(t, "amd64", "amd64")
} }
func Test386Encoder(t *testing.T) {
testEndToEnd(t, "386", "386enc")
}
func TestAMD64Encoder(t *testing.T) { func TestAMD64Encoder(t *testing.T) {
testEndToEnd(t, "amd64", "amd64enc") testEndToEnd(t, "amd64", "amd64enc")
testEndToEnd(t, "amd64", "amd64enc_extra") testEndToEnd(t, "amd64", "amd64enc_extra")
......
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "../../../../../runtime/textflag.h"
TEXT asmtest(SB),DUPOK|NOSPLIT,$0
// Instructions that were encoded with BYTE sequences.
// Included to simplify validation of CL that fixed that.
MOVQ (AX), M0 // 0f6f00
MOVQ M0, 8(SP) // 0f7f442408
MOVQ 8(SP), M0 // 0f6f442408
MOVQ M0, (AX) // 0f7f00
MOVQ M0, (BX) // 0f7f03
// End of tests.
RET
...@@ -930,10 +930,10 @@ TEXT runtime·cputicks(SB),NOSPLIT,$0-8 ...@@ -930,10 +930,10 @@ TEXT runtime·cputicks(SB),NOSPLIT,$0-8
JNE done JNE done
CMPB runtime·lfenceBeforeRdtsc(SB), $1 CMPB runtime·lfenceBeforeRdtsc(SB), $1
JNE mfence JNE mfence
BYTE $0x0f; BYTE $0xae; BYTE $0xe8 // LFENCE LFENCE
JMP done JMP done
mfence: mfence:
BYTE $0x0f; BYTE $0xae; BYTE $0xf0 // MFENCE MFENCE
done: done:
RDTSC RDTSC
MOVL AX, ret_lo+0(FP) MOVL AX, ret_lo+0(FP)
......
...@@ -124,12 +124,9 @@ TEXT runtime∕internal∕atomic·Load64(SB), NOSPLIT, $0-12 ...@@ -124,12 +124,9 @@ TEXT runtime∕internal∕atomic·Load64(SB), NOSPLIT, $0-12
JZ 2(PC) JZ 2(PC)
MOVL 0, AX // crash with nil ptr deref MOVL 0, AX // crash with nil ptr deref
LEAL ret_lo+4(FP), BX LEAL ret_lo+4(FP), BX
// MOVQ (%EAX), %MM0 MOVQ (AX), M0
BYTE $0x0f; BYTE $0x6f; BYTE $0x00 MOVQ M0, (BX)
// MOVQ %MM0, 0(%EBX) EMMS
BYTE $0x0f; BYTE $0x7f; BYTE $0x03
// EMMS
BYTE $0x0F; BYTE $0x77
RET RET
// void runtime∕internal∕atomic·Store64(uint64 volatile* addr, uint64 v); // void runtime∕internal∕atomic·Store64(uint64 volatile* addr, uint64 v);
...@@ -139,12 +136,9 @@ TEXT runtime∕internal∕atomic·Store64(SB), NOSPLIT, $0-12 ...@@ -139,12 +136,9 @@ TEXT runtime∕internal∕atomic·Store64(SB), NOSPLIT, $0-12
JZ 2(PC) JZ 2(PC)
MOVL 0, AX // crash with nil ptr deref MOVL 0, AX // crash with nil ptr deref
// MOVQ and EMMS were introduced on the Pentium MMX. // MOVQ and EMMS were introduced on the Pentium MMX.
// MOVQ 0x8(%ESP), %MM0 MOVQ val+4(FP), M0
BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08 MOVQ M0, (AX)
// MOVQ %MM0, (%EAX) EMMS
BYTE $0x0f; BYTE $0x7f; BYTE $0x00
// EMMS
BYTE $0x0F; BYTE $0x77
// This is essentially a no-op, but it provides required memory fencing. // This is essentially a no-op, but it provides required memory fencing.
// It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2). // It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2).
MOVL $0, AX MOVL $0, AX
......
...@@ -464,7 +464,7 @@ TEXT runtime·bsdthread_register(SB),NOSPLIT,$40 ...@@ -464,7 +464,7 @@ TEXT runtime·bsdthread_register(SB),NOSPLIT,$40
TEXT runtime·sysenter(SB),NOSPLIT,$0 TEXT runtime·sysenter(SB),NOSPLIT,$0
POPL DX POPL DX
MOVL SP, CX MOVL SP, CX
BYTE $0x0F; BYTE $0x34; // SYSENTER SYSENTER
// returns to DX with SP set to CX // returns to DX with SP set to CX
TEXT runtime·mach_msg_trap(SB),NOSPLIT,$0 TEXT runtime·mach_msg_trap(SB),NOSPLIT,$0
......
...@@ -158,10 +158,8 @@ TEXT ·LoadUint64(SB),NOSPLIT,$0-12 ...@@ -158,10 +158,8 @@ TEXT ·LoadUint64(SB),NOSPLIT,$0-12
JZ 2(PC) JZ 2(PC)
MOVL 0, AX // crash with nil ptr deref MOVL 0, AX // crash with nil ptr deref
// MOVQ and EMMS were introduced on the Pentium MMX. // MOVQ and EMMS were introduced on the Pentium MMX.
// MOVQ (%EAX), %MM0 MOVQ (AX), M0
BYTE $0x0f; BYTE $0x6f; BYTE $0x00 MOVQ M0, val+4(FP)
// MOVQ %MM0, 0x8(%ESP)
BYTE $0x0f; BYTE $0x7f; BYTE $0x44; BYTE $0x24; BYTE $0x08
EMMS EMMS
RET RET
...@@ -189,10 +187,8 @@ TEXT ·StoreUint64(SB),NOSPLIT,$0-12 ...@@ -189,10 +187,8 @@ TEXT ·StoreUint64(SB),NOSPLIT,$0-12
JZ 2(PC) JZ 2(PC)
MOVL 0, AX // crash with nil ptr deref MOVL 0, AX // crash with nil ptr deref
// MOVQ and EMMS were introduced on the Pentium MMX. // MOVQ and EMMS were introduced on the Pentium MMX.
// MOVQ 0x8(%ESP), %MM0 MOVQ val+4(FP), M0
BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08 MOVQ M0, (AX)
// MOVQ %MM0, (%EAX)
BYTE $0x0f; BYTE $0x7f; BYTE $0x00
EMMS EMMS
// This is essentially a no-op, but it provides required memory fencing. // This is essentially a no-op, but it provides required memory fencing.
// It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2). // It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2).
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment