pass: ensure frame pointer register is saved (#174)

Currently `avo` uses `BP` as a standard general-purpose register. However, `BP` is used for the frame pointer and should be callee-save. Under some circumstances, the Go assembler will do this automatically, but not always. At the moment `avo` can produce code that clobbers the `BP` register. Since Go 1.16 this code will also fail a new `go vet` check.

This PR provides a (currently sub-optimal) fix for the issue. It introduces an `EnsureBasePointerCalleeSaved` pass which will check if the base pointer is written to by a function, and if so will artificially ensure that the function has a non-zero frame size. This will trigger the Go assembler to automatically save and restore the BP register.

In addition, we update the `asmdecl` tool to `asmvet`, which includes the `framepointer` vet check.

Updates #156
This commit is contained in:
Michael McLoughlin
2021-04-18 18:37:56 -07:00
committed by GitHub
parent 4592e16ebb
commit f295bde84c
16 changed files with 154 additions and 28 deletions

View File

@@ -3,7 +3,7 @@
#include "textflag.h"
// func GP8() uint8
TEXT ·GP8(SB), NOSPLIT, $0-1
TEXT ·GP8(SB), NOSPLIT, $8-1
MOVB $0x01, AL
MOVB $0x02, CL
MOVB $0x03, DL

View File

@@ -3,7 +3,7 @@
#include "textflag.h"
// func Masks() (uint16, uint64)
TEXT ·Masks(SB), NOSPLIT, $0-16
TEXT ·Masks(SB), NOSPLIT, $8-16
MOVQ $0x0001002a, AX
MOVQ $0x0002002a, CX
MOVQ $0x0003002a, DX

View File

@@ -3,7 +3,7 @@
#include "textflag.h"
// func Upper32() uint64
TEXT ·Upper32(SB), NOSPLIT, $0-8
TEXT ·Upper32(SB), NOSPLIT, $8-8
// Initialize sum.
XORQ AX, AX

View File

@@ -8978,7 +8978,7 @@ emit_literal_skip_emit_remainder_encodeBlockAsm12BAvx:
// func emitLiteral(dst []byte, lit []byte) int
// Requires: SSE2
TEXT ·emitLiteral(SB), NOSPLIT, $0-56
TEXT ·emitLiteral(SB), NOSPLIT, $8-56
MOVQ dst_base+0(FP), AX
MOVQ lit_base+24(FP), CX
MOVQ lit_len+32(FP), DX
@@ -9212,7 +9212,7 @@ emit_literal_end_standalone:
// func emitLiteralAvx(dst []byte, lit []byte) int
// Requires: AVX, SSE2
TEXT ·emitLiteralAvx(SB), NOSPLIT, $0-56
TEXT ·emitLiteralAvx(SB), NOSPLIT, $8-56
MOVQ dst_base+0(FP), AX
MOVQ lit_base+24(FP), CX
MOVQ lit_len+32(FP), DX
@@ -9492,7 +9492,7 @@ emit_literal_end_avx_standalone:
RET
// func emitRepeat(dst []byte, offset int, length int) int
TEXT ·emitRepeat(SB), NOSPLIT, $0-48
TEXT ·emitRepeat(SB), NOSPLIT, $8-48
XORQ BX, BX
MOVQ dst_base+0(FP), AX
MOVQ offset+24(FP), CX
@@ -9574,7 +9574,7 @@ gen_emit_repeat_end:
RET
// func emitCopy(dst []byte, offset int, length int) int
TEXT ·emitCopy(SB), NOSPLIT, $0-48
TEXT ·emitCopy(SB), NOSPLIT, $8-48
XORQ BX, BX
MOVQ dst_base+0(FP), AX
MOVQ offset+24(FP), CX
@@ -9784,7 +9784,7 @@ gen_emit_copy_end:
RET
// func matchLen(a []byte, b []byte) int
TEXT ·matchLen(SB), NOSPLIT, $0-56
TEXT ·matchLen(SB), NOSPLIT, $8-56
MOVQ a_base+0(FP), AX
MOVQ b_base+24(FP), CX
MOVQ a_len+8(FP), DX