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