[chore] Update gin to v1.9.0 (#1553)

This commit is contained in:
Daenney
2023-02-25 13:12:40 +01:00
committed by GitHub
parent 689a10fe17
commit ecdc8379fa
347 changed files with 166814 additions and 3671 deletions

View File

@ -0,0 +1,423 @@
// Inferno utils/6c/6.out.h
// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6c/6.out.h
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package x86
import "github.com/twitchyliquid64/golang-asm/obj"
const (
REG_NONE = 0
)
const (
REG_AL = obj.RBaseAMD64 + iota
REG_CL
REG_DL
REG_BL
REG_SPB
REG_BPB
REG_SIB
REG_DIB
REG_R8B
REG_R9B
REG_R10B
REG_R11B
REG_R12B
REG_R13B
REG_R14B
REG_R15B
REG_AX
REG_CX
REG_DX
REG_BX
REG_SP
REG_BP
REG_SI
REG_DI
REG_R8
REG_R9
REG_R10
REG_R11
REG_R12
REG_R13
REG_R14
REG_R15
REG_AH
REG_CH
REG_DH
REG_BH
REG_F0
REG_F1
REG_F2
REG_F3
REG_F4
REG_F5
REG_F6
REG_F7
REG_M0
REG_M1
REG_M2
REG_M3
REG_M4
REG_M5
REG_M6
REG_M7
REG_K0
REG_K1
REG_K2
REG_K3
REG_K4
REG_K5
REG_K6
REG_K7
REG_X0
REG_X1
REG_X2
REG_X3
REG_X4
REG_X5
REG_X6
REG_X7
REG_X8
REG_X9
REG_X10
REG_X11
REG_X12
REG_X13
REG_X14
REG_X15
REG_X16
REG_X17
REG_X18
REG_X19
REG_X20
REG_X21
REG_X22
REG_X23
REG_X24
REG_X25
REG_X26
REG_X27
REG_X28
REG_X29
REG_X30
REG_X31
REG_Y0
REG_Y1
REG_Y2
REG_Y3
REG_Y4
REG_Y5
REG_Y6
REG_Y7
REG_Y8
REG_Y9
REG_Y10
REG_Y11
REG_Y12
REG_Y13
REG_Y14
REG_Y15
REG_Y16
REG_Y17
REG_Y18
REG_Y19
REG_Y20
REG_Y21
REG_Y22
REG_Y23
REG_Y24
REG_Y25
REG_Y26
REG_Y27
REG_Y28
REG_Y29
REG_Y30
REG_Y31
REG_Z0
REG_Z1
REG_Z2
REG_Z3
REG_Z4
REG_Z5
REG_Z6
REG_Z7
REG_Z8
REG_Z9
REG_Z10
REG_Z11
REG_Z12
REG_Z13
REG_Z14
REG_Z15
REG_Z16
REG_Z17
REG_Z18
REG_Z19
REG_Z20
REG_Z21
REG_Z22
REG_Z23
REG_Z24
REG_Z25
REG_Z26
REG_Z27
REG_Z28
REG_Z29
REG_Z30
REG_Z31
REG_CS
REG_SS
REG_DS
REG_ES
REG_FS
REG_GS
REG_GDTR // global descriptor table register
REG_IDTR // interrupt descriptor table register
REG_LDTR // local descriptor table register
REG_MSW // machine status word
REG_TASK // task register
REG_CR0
REG_CR1
REG_CR2
REG_CR3
REG_CR4
REG_CR5
REG_CR6
REG_CR7
REG_CR8
REG_CR9
REG_CR10
REG_CR11
REG_CR12
REG_CR13
REG_CR14
REG_CR15
REG_DR0
REG_DR1
REG_DR2
REG_DR3
REG_DR4
REG_DR5
REG_DR6
REG_DR7
REG_TR0
REG_TR1
REG_TR2
REG_TR3
REG_TR4
REG_TR5
REG_TR6
REG_TR7
REG_TLS
MAXREG
REG_CR = REG_CR0
REG_DR = REG_DR0
REG_TR = REG_TR0
REGARG = -1
REGRET = REG_AX
FREGRET = REG_X0
REGSP = REG_SP
REGCTXT = REG_DX
REGEXT = REG_R15 // compiler allocates external registers R15 down
FREGMIN = REG_X0 + 5 // first register variable
FREGEXT = REG_X0 + 15 // first external register
T_TYPE = 1 << 0
T_INDEX = 1 << 1
T_OFFSET = 1 << 2
T_FCONST = 1 << 3
T_SYM = 1 << 4
T_SCONST = 1 << 5
T_64 = 1 << 6
T_GOTYPE = 1 << 7
)
// https://www.uclibc.org/docs/psABI-x86_64.pdf, figure 3.36
var AMD64DWARFRegisters = map[int16]int16{
REG_AX: 0,
REG_DX: 1,
REG_CX: 2,
REG_BX: 3,
REG_SI: 4,
REG_DI: 5,
REG_BP: 6,
REG_SP: 7,
REG_R8: 8,
REG_R9: 9,
REG_R10: 10,
REG_R11: 11,
REG_R12: 12,
REG_R13: 13,
REG_R14: 14,
REG_R15: 15,
// 16 is "Return Address RA", whatever that is.
// 17-24 vector registers (X/Y/Z).
REG_X0: 17,
REG_X1: 18,
REG_X2: 19,
REG_X3: 20,
REG_X4: 21,
REG_X5: 22,
REG_X6: 23,
REG_X7: 24,
// 25-32 extended vector registers (X/Y/Z).
REG_X8: 25,
REG_X9: 26,
REG_X10: 27,
REG_X11: 28,
REG_X12: 29,
REG_X13: 30,
REG_X14: 31,
REG_X15: 32,
// ST registers. %stN => FN.
REG_F0: 33,
REG_F1: 34,
REG_F2: 35,
REG_F3: 36,
REG_F4: 37,
REG_F5: 38,
REG_F6: 39,
REG_F7: 40,
// MMX registers. %mmN => MN.
REG_M0: 41,
REG_M1: 42,
REG_M2: 43,
REG_M3: 44,
REG_M4: 45,
REG_M5: 46,
REG_M6: 47,
REG_M7: 48,
// 48 is flags, which doesn't have a name.
REG_ES: 50,
REG_CS: 51,
REG_SS: 52,
REG_DS: 53,
REG_FS: 54,
REG_GS: 55,
// 58 and 59 are {fs,gs}base, which don't have names.
REG_TR: 62,
REG_LDTR: 63,
// 64-66 are mxcsr, fcw, fsw, which don't have names.
// 67-82 upper vector registers (X/Y/Z).
REG_X16: 67,
REG_X17: 68,
REG_X18: 69,
REG_X19: 70,
REG_X20: 71,
REG_X21: 72,
REG_X22: 73,
REG_X23: 74,
REG_X24: 75,
REG_X25: 76,
REG_X26: 77,
REG_X27: 78,
REG_X28: 79,
REG_X29: 80,
REG_X30: 81,
REG_X31: 82,
// 118-125 vector mask registers. %kN => KN.
REG_K0: 118,
REG_K1: 119,
REG_K2: 120,
REG_K3: 121,
REG_K4: 122,
REG_K5: 123,
REG_K6: 124,
REG_K7: 125,
}
// https://www.uclibc.org/docs/psABI-i386.pdf, table 2.14
var X86DWARFRegisters = map[int16]int16{
REG_AX: 0,
REG_CX: 1,
REG_DX: 2,
REG_BX: 3,
REG_SP: 4,
REG_BP: 5,
REG_SI: 6,
REG_DI: 7,
// 8 is "Return Address RA", whatever that is.
// 9 is flags, which doesn't have a name.
// ST registers. %stN => FN.
REG_F0: 11,
REG_F1: 12,
REG_F2: 13,
REG_F3: 14,
REG_F4: 15,
REG_F5: 16,
REG_F6: 17,
REG_F7: 18,
// XMM registers. %xmmN => XN.
REG_X0: 21,
REG_X1: 22,
REG_X2: 23,
REG_X3: 24,
REG_X4: 25,
REG_X5: 26,
REG_X6: 27,
REG_X7: 28,
// MMX registers. %mmN => MN.
REG_M0: 29,
REG_M1: 30,
REG_M2: 31,
REG_M3: 32,
REG_M4: 33,
REG_M5: 34,
REG_M6: 35,
REG_M7: 36,
// 39 is mxcsr, which doesn't have a name.
REG_ES: 40,
REG_CS: 41,
REG_SS: 42,
REG_DS: 43,
REG_FS: 44,
REG_GS: 45,
REG_TR: 48,
REG_LDTR: 49,
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,382 @@
// 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.
package x86
import (
"github.com/twitchyliquid64/golang-asm/obj"
"errors"
"fmt"
"strings"
)
// evexBits stores EVEX prefix info that is used during instruction encoding.
type evexBits struct {
b1 byte // [W1mmLLpp]
b2 byte // [NNNbbZRS]
// Associated instruction opcode.
opcode byte
}
// newEVEXBits creates evexBits object from enc bytes at z position.
func newEVEXBits(z int, enc *opBytes) evexBits {
return evexBits{
b1: enc[z+0],
b2: enc[z+1],
opcode: enc[z+2],
}
}
// P returns EVEX.pp value.
func (evex evexBits) P() byte { return (evex.b1 & evexP) >> 0 }
// L returns EVEX.L'L value.
func (evex evexBits) L() byte { return (evex.b1 & evexL) >> 2 }
// M returns EVEX.mm value.
func (evex evexBits) M() byte { return (evex.b1 & evexM) >> 4 }
// W returns EVEX.W value.
func (evex evexBits) W() byte { return (evex.b1 & evexW) >> 7 }
// BroadcastEnabled reports whether BCST suffix is permitted.
func (evex evexBits) BroadcastEnabled() bool {
return evex.b2&evexBcst != 0
}
// ZeroingEnabled reports whether Z suffix is permitted.
func (evex evexBits) ZeroingEnabled() bool {
return (evex.b2&evexZeroing)>>2 != 0
}
// RoundingEnabled reports whether RN_SAE, RZ_SAE, RD_SAE and RU_SAE suffixes
// are permitted.
func (evex evexBits) RoundingEnabled() bool {
return (evex.b2&evexRounding)>>1 != 0
}
// SaeEnabled reports whether SAE suffix is permitted.
func (evex evexBits) SaeEnabled() bool {
return (evex.b2&evexSae)>>0 != 0
}
// DispMultiplier returns displacement multiplier that is calculated
// based on tuple type, EVEX.W and input size.
// If embedded broadcast is used, bcst should be true.
func (evex evexBits) DispMultiplier(bcst bool) int32 {
if bcst {
switch evex.b2 & evexBcst {
case evexBcstN4:
return 4
case evexBcstN8:
return 8
}
return 1
}
switch evex.b2 & evexN {
case evexN1:
return 1
case evexN2:
return 2
case evexN4:
return 4
case evexN8:
return 8
case evexN16:
return 16
case evexN32:
return 32
case evexN64:
return 64
case evexN128:
return 128
}
return 1
}
// EVEX is described by using 2-byte sequence.
// See evexBits for more details.
const (
evexW = 0x80 // b1[W... ....]
evexWIG = 0 << 7
evexW0 = 0 << 7
evexW1 = 1 << 7
evexM = 0x30 // b2[..mm ...]
evex0F = 1 << 4
evex0F38 = 2 << 4
evex0F3A = 3 << 4
evexL = 0x0C // b1[.... LL..]
evexLIG = 0 << 2
evex128 = 0 << 2
evex256 = 1 << 2
evex512 = 2 << 2
evexP = 0x03 // b1[.... ..pp]
evex66 = 1 << 0
evexF3 = 2 << 0
evexF2 = 3 << 0
// Precalculated Disp8 N value.
// N acts like a multiplier for 8bit displacement.
// Note that some N are not used, but their bits are reserved.
evexN = 0xE0 // b2[NNN. ....]
evexN1 = 0 << 5
evexN2 = 1 << 5
evexN4 = 2 << 5
evexN8 = 3 << 5
evexN16 = 4 << 5
evexN32 = 5 << 5
evexN64 = 6 << 5
evexN128 = 7 << 5
// Disp8 for broadcasts.
evexBcst = 0x18 // b2[...b b...]
evexBcstN4 = 1 << 3
evexBcstN8 = 2 << 3
// Flags that permit certain AVX512 features.
// It's semantically illegal to combine evexZeroing and evexSae.
evexZeroing = 0x4 // b2[.... .Z..]
evexZeroingEnabled = 1 << 2
evexRounding = 0x2 // b2[.... ..R.]
evexRoundingEnabled = 1 << 1
evexSae = 0x1 // b2[.... ...S]
evexSaeEnabled = 1 << 0
)
// compressedDisp8 calculates EVEX compressed displacement, if applicable.
func compressedDisp8(disp, elemSize int32) (disp8 byte, ok bool) {
if disp%elemSize == 0 {
v := disp / elemSize
if v >= -128 && v <= 127 {
return byte(v), true
}
}
return 0, false
}
// evexZcase reports whether given Z-case belongs to EVEX group.
func evexZcase(zcase uint8) bool {
return zcase > Zevex_first && zcase < Zevex_last
}
// evexSuffixBits carries instruction EVEX suffix set flags.
//
// Examples:
// "RU_SAE.Z" => {rounding: 3, zeroing: true}
// "Z" => {zeroing: true}
// "BCST" => {broadcast: true}
// "SAE.Z" => {sae: true, zeroing: true}
type evexSuffix struct {
rounding byte
sae bool
zeroing bool
broadcast bool
}
// Rounding control values.
// Match exact value for EVEX.L'L field (with exception of rcUnset).
const (
rcRNSAE = 0 // Round towards nearest
rcRDSAE = 1 // Round towards -Inf
rcRUSAE = 2 // Round towards +Inf
rcRZSAE = 3 // Round towards zero
rcUnset = 4
)
// newEVEXSuffix returns proper zero value for evexSuffix.
func newEVEXSuffix() evexSuffix {
return evexSuffix{rounding: rcUnset}
}
// evexSuffixMap maps obj.X86suffix to its decoded version.
// Filled during init().
var evexSuffixMap [255]evexSuffix
func init() {
// Decode all valid suffixes for later use.
for i := range opSuffixTable {
suffix := newEVEXSuffix()
parts := strings.Split(opSuffixTable[i], ".")
for j := range parts {
switch parts[j] {
case "Z":
suffix.zeroing = true
case "BCST":
suffix.broadcast = true
case "SAE":
suffix.sae = true
case "RN_SAE":
suffix.rounding = rcRNSAE
case "RD_SAE":
suffix.rounding = rcRDSAE
case "RU_SAE":
suffix.rounding = rcRUSAE
case "RZ_SAE":
suffix.rounding = rcRZSAE
}
}
evexSuffixMap[i] = suffix
}
}
// toDisp8 tries to convert disp to proper 8-bit displacement value.
func toDisp8(disp int32, p *obj.Prog, asmbuf *AsmBuf) (disp8 byte, ok bool) {
if asmbuf.evexflag {
bcst := evexSuffixMap[p.Scond].broadcast
elemSize := asmbuf.evex.DispMultiplier(bcst)
return compressedDisp8(disp, elemSize)
}
return byte(disp), disp >= -128 && disp < 128
}
// EncodeRegisterRange packs [reg0-reg1] list into 64-bit value that
// is intended to be stored inside obj.Addr.Offset with TYPE_REGLIST.
func EncodeRegisterRange(reg0, reg1 int16) int64 {
return (int64(reg0) << 0) |
(int64(reg1) << 16) |
obj.RegListX86Lo
}
// decodeRegisterRange unpacks [reg0-reg1] list from 64-bit value created by EncodeRegisterRange.
func decodeRegisterRange(list int64) (reg0, reg1 int) {
return int((list >> 0) & 0xFFFF),
int((list >> 16) & 0xFFFF)
}
// ParseSuffix handles the special suffix for the 386/AMD64.
// Suffix bits are stored into p.Scond.
//
// Leading "." in cond is ignored.
func ParseSuffix(p *obj.Prog, cond string) error {
cond = strings.TrimPrefix(cond, ".")
suffix := newOpSuffix(cond)
if !suffix.IsValid() {
return inferSuffixError(cond)
}
p.Scond = uint8(suffix)
return nil
}
// inferSuffixError returns non-nil error that describes what could be
// the cause of suffix parse failure.
//
// At the point this function is executed there is already assembly error,
// so we can burn some clocks to construct good error message.
//
// Reported issues:
// - duplicated suffixes
// - illegal rounding/SAE+broadcast combinations
// - unknown suffixes
// - misplaced suffix (e.g. wrong Z suffix position)
func inferSuffixError(cond string) error {
suffixSet := make(map[string]bool) // Set for duplicates detection.
unknownSet := make(map[string]bool) // Set of unknown suffixes.
hasBcst := false
hasRoundSae := false
var msg []string // Error message parts
suffixes := strings.Split(cond, ".")
for i, suffix := range suffixes {
switch suffix {
case "Z":
if i != len(suffixes)-1 {
msg = append(msg, "Z suffix should be the last")
}
case "BCST":
hasBcst = true
case "SAE", "RN_SAE", "RZ_SAE", "RD_SAE", "RU_SAE":
hasRoundSae = true
default:
if !unknownSet[suffix] {
msg = append(msg, fmt.Sprintf("unknown suffix %q", suffix))
}
unknownSet[suffix] = true
}
if suffixSet[suffix] {
msg = append(msg, fmt.Sprintf("duplicate suffix %q", suffix))
}
suffixSet[suffix] = true
}
if hasBcst && hasRoundSae {
msg = append(msg, "can't combine rounding/SAE and broadcast")
}
if len(msg) == 0 {
return errors.New("bad suffix combination")
}
return errors.New(strings.Join(msg, "; "))
}
// opSuffixTable is a complete list of possible opcode suffix combinations.
// It "maps" uint8 suffix bits to their string representation.
// With the exception of first and last elements, order is not important.
var opSuffixTable = [...]string{
"", // Map empty suffix to empty string.
"Z",
"SAE",
"SAE.Z",
"RN_SAE",
"RZ_SAE",
"RD_SAE",
"RU_SAE",
"RN_SAE.Z",
"RZ_SAE.Z",
"RD_SAE.Z",
"RU_SAE.Z",
"BCST",
"BCST.Z",
"<bad suffix>",
}
// opSuffix represents instruction opcode suffix.
// Compound (multi-part) suffixes expressed with single opSuffix value.
//
// uint8 type is used to fit obj.Prog.Scond.
type opSuffix uint8
// badOpSuffix is used to represent all invalid suffix combinations.
const badOpSuffix = opSuffix(len(opSuffixTable) - 1)
// newOpSuffix returns opSuffix object that matches suffixes string.
//
// If no matching suffix is found, special "invalid" suffix is returned.
// Use IsValid method to check against this case.
func newOpSuffix(suffixes string) opSuffix {
for i := range opSuffixTable {
if opSuffixTable[i] == suffixes {
return opSuffix(i)
}
}
return badOpSuffix
}
// IsValid reports whether suffix is valid.
// Empty suffixes are valid.
func (suffix opSuffix) IsValid() bool {
return suffix != badOpSuffix
}
// String returns suffix printed representation.
//
// It matches the string that was used to create suffix with NewX86Suffix()
// for valid suffixes.
// For all invalid suffixes, special marker is returned.
func (suffix opSuffix) String() string {
return opSuffixTable[suffix]
}

View File

@ -0,0 +1,264 @@
// Inferno utils/6c/list.c
// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6c/list.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package x86
import (
"github.com/twitchyliquid64/golang-asm/obj"
"fmt"
)
var Register = []string{
"AL", // [D_AL]
"CL",
"DL",
"BL",
"SPB",
"BPB",
"SIB",
"DIB",
"R8B",
"R9B",
"R10B",
"R11B",
"R12B",
"R13B",
"R14B",
"R15B",
"AX", // [D_AX]
"CX",
"DX",
"BX",
"SP",
"BP",
"SI",
"DI",
"R8",
"R9",
"R10",
"R11",
"R12",
"R13",
"R14",
"R15",
"AH",
"CH",
"DH",
"BH",
"F0", // [D_F0]
"F1",
"F2",
"F3",
"F4",
"F5",
"F6",
"F7",
"M0",
"M1",
"M2",
"M3",
"M4",
"M5",
"M6",
"M7",
"K0",
"K1",
"K2",
"K3",
"K4",
"K5",
"K6",
"K7",
"X0",
"X1",
"X2",
"X3",
"X4",
"X5",
"X6",
"X7",
"X8",
"X9",
"X10",
"X11",
"X12",
"X13",
"X14",
"X15",
"X16",
"X17",
"X18",
"X19",
"X20",
"X21",
"X22",
"X23",
"X24",
"X25",
"X26",
"X27",
"X28",
"X29",
"X30",
"X31",
"Y0",
"Y1",
"Y2",
"Y3",
"Y4",
"Y5",
"Y6",
"Y7",
"Y8",
"Y9",
"Y10",
"Y11",
"Y12",
"Y13",
"Y14",
"Y15",
"Y16",
"Y17",
"Y18",
"Y19",
"Y20",
"Y21",
"Y22",
"Y23",
"Y24",
"Y25",
"Y26",
"Y27",
"Y28",
"Y29",
"Y30",
"Y31",
"Z0",
"Z1",
"Z2",
"Z3",
"Z4",
"Z5",
"Z6",
"Z7",
"Z8",
"Z9",
"Z10",
"Z11",
"Z12",
"Z13",
"Z14",
"Z15",
"Z16",
"Z17",
"Z18",
"Z19",
"Z20",
"Z21",
"Z22",
"Z23",
"Z24",
"Z25",
"Z26",
"Z27",
"Z28",
"Z29",
"Z30",
"Z31",
"CS", // [D_CS]
"SS",
"DS",
"ES",
"FS",
"GS",
"GDTR", // [D_GDTR]
"IDTR", // [D_IDTR]
"LDTR", // [D_LDTR]
"MSW", // [D_MSW]
"TASK", // [D_TASK]
"CR0", // [D_CR]
"CR1",
"CR2",
"CR3",
"CR4",
"CR5",
"CR6",
"CR7",
"CR8",
"CR9",
"CR10",
"CR11",
"CR12",
"CR13",
"CR14",
"CR15",
"DR0", // [D_DR]
"DR1",
"DR2",
"DR3",
"DR4",
"DR5",
"DR6",
"DR7",
"TR0", // [D_TR]
"TR1",
"TR2",
"TR3",
"TR4",
"TR5",
"TR6",
"TR7",
"TLS", // [D_TLS]
"MAXREG", // [MAXREG]
}
func init() {
obj.RegisterRegister(REG_AL, REG_AL+len(Register), rconv)
obj.RegisterOpcode(obj.ABaseAMD64, Anames)
obj.RegisterRegisterList(obj.RegListX86Lo, obj.RegListX86Hi, rlconv)
obj.RegisterOpSuffix("386", opSuffixString)
obj.RegisterOpSuffix("amd64", opSuffixString)
}
func rconv(r int) string {
if REG_AL <= r && r-REG_AL < len(Register) {
return Register[r-REG_AL]
}
return fmt.Sprintf("Rgok(%d)", r-obj.RBaseAMD64)
}
func rlconv(bits int64) string {
reg0, reg1 := decodeRegisterRange(bits)
return fmt.Sprintf("[%s-%s]", rconv(reg0), rconv(reg1))
}
func opSuffixString(s uint8) string {
return "." + opSuffix(s).String()
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,44 @@
// Copyright 2017 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.
package x86
// argListMax specifies upper arg count limit expected to be carried by obj.Prog.
// Max len(obj.Prog.RestArgs) can be inferred from this to be 4.
const argListMax int = 6
type argList [argListMax]uint8
type ytab struct {
zcase uint8
zoffset uint8
// Last arg is usually destination.
// For unary instructions unaryDst is used to determine
// if single argument is a source or destination.
args argList
}
// Returns true if yt is compatible with args.
//
// Elements from args and yt.args are used
// to index ycover table like `ycover[args[i]+yt.args[i]]`.
// This means that args should contain values that already
// multiplied by Ymax.
func (yt *ytab) match(args []int) bool {
// Trailing Yxxx check is required to avoid a case
// where shorter arg list is matched.
// If we had exact yt.args length, it could be `yt.argc != len(args)`.
if len(args) < len(yt.args) && yt.args[len(args)] != Yxxx {
return false
}
for i := range args {
if ycover[args[i]+int(yt.args[i])] == 0 {
return false
}
}
return true
}