diff options
author | 2025-03-09 17:47:56 +0100 | |
---|---|---|
committer | 2025-03-10 01:59:49 +0100 | |
commit | 3ac1ee16f377d31a0fb80c8dae28b6239ac4229e (patch) | |
tree | f61faa581feaaeaba2542b9f2b8234a590684413 /vendor/github.com/twitchyliquid64/golang-asm/obj/x86/evex.go | |
parent | [chore] update URLs to forked source (diff) | |
download | gotosocial-3ac1ee16f377d31a0fb80c8dae28b6239ac4229e.tar.xz |
[chore] remove vendor
Diffstat (limited to 'vendor/github.com/twitchyliquid64/golang-asm/obj/x86/evex.go')
-rw-r--r-- | vendor/github.com/twitchyliquid64/golang-asm/obj/x86/evex.go | 382 |
1 files changed, 0 insertions, 382 deletions
diff --git a/vendor/github.com/twitchyliquid64/golang-asm/obj/x86/evex.go b/vendor/github.com/twitchyliquid64/golang-asm/obj/x86/evex.go deleted file mode 100644 index 47932684d..000000000 --- a/vendor/github.com/twitchyliquid64/golang-asm/obj/x86/evex.go +++ /dev/null @@ -1,382 +0,0 @@ -// 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] -} |