github.com/zxy12/go_duplicate_1_12@v0.0.0-20200217043740-b1636fc0368b/src/cmd/asm/internal/arch/arch.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package arch defines architecture-specific information and support functions. 6 package arch 7 8 import ( 9 "cmd/internal/obj" 10 //"cmd/internal/obj/arm" 11 //"cmd/internal/obj/arm64" 12 //"cmd/internal/obj/mips" 13 //"cmd/internal/obj/ppc64" 14 //"cmd/internal/obj/s390x" 15 //"cmd/internal/obj/wasm" 16 "cmd/internal/obj/x86" 17 //"fmt" 18 "log" 19 "strings" 20 ) 21 22 // Pseudo-registers whose names are the constant name without the leading R. 23 const ( 24 RFP = -(iota + 1) 25 RSB 26 RSP 27 RPC 28 ) 29 30 // Arch wraps the link architecture object with more architecture-specific information. 31 type Arch struct { 32 *obj.LinkArch 33 // Map of instruction names to enumeration. 34 Instructions map[string]obj.As 35 // Map of register names to enumeration. 36 Register map[string]int16 37 // Table of register prefix names. These are things like R for R(0) and SPR for SPR(268). 38 RegisterPrefix map[string]bool 39 // RegisterNumber converts R(10) into arm.REG_R10. 40 RegisterNumber func(string, int16) (int16, bool) 41 // Instruction is a jump. 42 IsJump func(word string) bool 43 } 44 45 // nilRegisterNumber is the register number function for architectures 46 // that do not accept the R(N) notation. It always returns failure. 47 func nilRegisterNumber(name string, n int16) (int16, bool) { 48 return 0, false 49 } 50 51 func jumpX86(word string) bool { 52 return word[0] == 'J' || word == "CALL" || strings.HasPrefix(word, "LOOP") || word == "XBEGIN" 53 } 54 55 // Set configures the architecture specified by GOARCH and returns its representation. 56 // It returns nil if GOARCH is not recognized. 57 func Set(GOARCH string) *Arch { 58 log.Printf("Arch set GOARCH[%s]\n", GOARCH) 59 switch GOARCH { 60 case "amd64": 61 return archX86(&x86.Linkamd64) 62 } 63 64 return nil 65 } 66 67 func archX86(linkArch *obj.LinkArch) *Arch { 68 register := make(map[string]int16) 69 // Create maps for easy lookup of instruction names etc. 70 for i, s := range x86.Register { 71 register[s] = int16(i + x86.REG_AL) 72 } 73 // Pseudo-registers. 74 register["SB"] = RSB 75 register["FP"] = RFP 76 register["PC"] = RPC 77 // Register prefix not used on this architecture. 78 79 instructions := make(map[string]obj.As) 80 for i, s := range obj.Anames { 81 instructions[s] = obj.As(i) 82 } 83 for i, s := range x86.Anames { 84 if obj.As(i) >= obj.A_ARCHSPECIFIC { 85 instructions[s] = obj.As(i) + obj.ABaseAMD64 86 } 87 } 88 // Annoying aliases. 89 instructions["JA"] = x86.AJHI /* alternate */ 90 instructions["JAE"] = x86.AJCC /* alternate */ 91 instructions["JB"] = x86.AJCS /* alternate */ 92 instructions["JBE"] = x86.AJLS /* alternate */ 93 instructions["JC"] = x86.AJCS /* alternate */ 94 instructions["JCC"] = x86.AJCC /* carry clear (CF = 0) */ 95 instructions["JCS"] = x86.AJCS /* carry set (CF = 1) */ 96 instructions["JE"] = x86.AJEQ /* alternate */ 97 instructions["JEQ"] = x86.AJEQ /* equal (ZF = 1) */ 98 instructions["JG"] = x86.AJGT /* alternate */ 99 instructions["JGE"] = x86.AJGE /* greater than or equal (signed) (SF = OF) */ 100 instructions["JGT"] = x86.AJGT /* greater than (signed) (ZF = 0 && SF = OF) */ 101 instructions["JHI"] = x86.AJHI /* higher (unsigned) (CF = 0 && ZF = 0) */ 102 instructions["JHS"] = x86.AJCC /* alternate */ 103 instructions["JL"] = x86.AJLT /* alternate */ 104 instructions["JLE"] = x86.AJLE /* less than or equal (signed) (ZF = 1 || SF != OF) */ 105 instructions["JLO"] = x86.AJCS /* alternate */ 106 instructions["JLS"] = x86.AJLS /* lower or same (unsigned) (CF = 1 || ZF = 1) */ 107 instructions["JLT"] = x86.AJLT /* less than (signed) (SF != OF) */ 108 instructions["JMI"] = x86.AJMI /* negative (minus) (SF = 1) */ 109 instructions["JNA"] = x86.AJLS /* alternate */ 110 instructions["JNAE"] = x86.AJCS /* alternate */ 111 instructions["JNB"] = x86.AJCC /* alternate */ 112 instructions["JNBE"] = x86.AJHI /* alternate */ 113 instructions["JNC"] = x86.AJCC /* alternate */ 114 instructions["JNE"] = x86.AJNE /* not equal (ZF = 0) */ 115 instructions["JNG"] = x86.AJLE /* alternate */ 116 instructions["JNGE"] = x86.AJLT /* alternate */ 117 instructions["JNL"] = x86.AJGE /* alternate */ 118 instructions["JNLE"] = x86.AJGT /* alternate */ 119 instructions["JNO"] = x86.AJOC /* alternate */ 120 instructions["JNP"] = x86.AJPC /* alternate */ 121 instructions["JNS"] = x86.AJPL /* alternate */ 122 instructions["JNZ"] = x86.AJNE /* alternate */ 123 instructions["JO"] = x86.AJOS /* alternate */ 124 instructions["JOC"] = x86.AJOC /* overflow clear (OF = 0) */ 125 instructions["JOS"] = x86.AJOS /* overflow set (OF = 1) */ 126 instructions["JP"] = x86.AJPS /* alternate */ 127 instructions["JPC"] = x86.AJPC /* parity clear (PF = 0) */ 128 instructions["JPE"] = x86.AJPS /* alternate */ 129 instructions["JPL"] = x86.AJPL /* non-negative (plus) (SF = 0) */ 130 instructions["JPO"] = x86.AJPC /* alternate */ 131 instructions["JPS"] = x86.AJPS /* parity set (PF = 1) */ 132 instructions["JS"] = x86.AJMI /* alternate */ 133 instructions["JZ"] = x86.AJEQ /* alternate */ 134 instructions["MASKMOVDQU"] = x86.AMASKMOVOU 135 instructions["MOVD"] = x86.AMOVQ 136 instructions["MOVDQ2Q"] = x86.AMOVQ 137 instructions["MOVNTDQ"] = x86.AMOVNTO 138 instructions["MOVOA"] = x86.AMOVO 139 instructions["PSLLDQ"] = x86.APSLLO 140 instructions["PSRLDQ"] = x86.APSRLO 141 instructions["PADDD"] = x86.APADDL 142 143 return &Arch{ 144 LinkArch: linkArch, 145 Instructions: instructions, 146 Register: register, 147 RegisterPrefix: nil, 148 RegisterNumber: nilRegisterNumber, 149 IsJump: jumpX86, 150 } 151 }