github.com/peggyl/go@v0.0.0-20151008231540-ae315999c2d5/src/cmd/compile/internal/amd64/prog.go (about) 1 // Copyright 2013 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 amd64 6 7 import ( 8 "cmd/compile/internal/gc" 9 "cmd/internal/obj" 10 "cmd/internal/obj/x86" 11 ) 12 13 const ( 14 LeftRdwr uint32 = gc.LeftRead | gc.LeftWrite 15 RightRdwr uint32 = gc.RightRead | gc.RightWrite 16 ) 17 18 // This table gives the basic information about instruction 19 // generated by the compiler and processed in the optimizer. 20 // See opt.h for bit definitions. 21 // 22 // Instructions not generated need not be listed. 23 // As an exception to that rule, we typically write down all the 24 // size variants of an operation even if we just use a subset. 25 // 26 // The table is formatted for 8-space tabs. 27 var progtable = [x86.ALAST]obj.ProgInfo{ 28 obj.ATYPE: {Flags: gc.Pseudo | gc.Skip}, 29 obj.ATEXT: {Flags: gc.Pseudo}, 30 obj.AFUNCDATA: {Flags: gc.Pseudo}, 31 obj.APCDATA: {Flags: gc.Pseudo}, 32 obj.AUNDEF: {Flags: gc.Break}, 33 obj.AUSEFIELD: {Flags: gc.OK}, 34 obj.ACHECKNIL: {Flags: gc.LeftRead}, 35 obj.AVARDEF: {Flags: gc.Pseudo | gc.RightWrite}, 36 obj.AVARKILL: {Flags: gc.Pseudo | gc.RightWrite}, 37 38 // NOP is an internal no-op that also stands 39 // for USED and SET annotations, not the Intel opcode. 40 obj.ANOP: {Flags: gc.LeftRead | gc.RightWrite}, 41 x86.AADCL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.SetCarry | gc.UseCarry}, 42 x86.AADCQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.SetCarry | gc.UseCarry}, 43 x86.AADCW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry | gc.UseCarry}, 44 x86.AADDB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.SetCarry}, 45 x86.AADDL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.SetCarry}, 46 x86.AADDW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry}, 47 x86.AADDQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.SetCarry}, 48 x86.AADDSD: {Flags: gc.SizeD | gc.LeftRead | RightRdwr}, 49 x86.AADDSS: {Flags: gc.SizeF | gc.LeftRead | RightRdwr}, 50 x86.AANDB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.SetCarry}, 51 x86.AANDL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.SetCarry}, 52 x86.AANDQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.SetCarry}, 53 x86.AANDW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry}, 54 obj.ACALL: {Flags: gc.RightAddr | gc.Call | gc.KillCarry}, 55 x86.ACDQ: {Flags: gc.OK, Reguse: AX, Regset: AX | DX}, 56 x86.ACQO: {Flags: gc.OK, Reguse: AX, Regset: AX | DX}, 57 x86.ACWD: {Flags: gc.OK, Reguse: AX, Regset: AX | DX}, 58 x86.ACLD: {Flags: gc.OK}, 59 x86.ASTD: {Flags: gc.OK}, 60 x86.ACMPB: {Flags: gc.SizeB | gc.LeftRead | gc.RightRead | gc.SetCarry}, 61 x86.ACMPL: {Flags: gc.SizeL | gc.LeftRead | gc.RightRead | gc.SetCarry}, 62 x86.ACMPQ: {Flags: gc.SizeQ | gc.LeftRead | gc.RightRead | gc.SetCarry}, 63 x86.ACMPW: {Flags: gc.SizeW | gc.LeftRead | gc.RightRead | gc.SetCarry}, 64 x86.ACOMISD: {Flags: gc.SizeD | gc.LeftRead | gc.RightRead | gc.SetCarry}, 65 x86.ACOMISS: {Flags: gc.SizeF | gc.LeftRead | gc.RightRead | gc.SetCarry}, 66 x86.ACVTSD2SL: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv}, 67 x86.ACVTSD2SQ: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv}, 68 x86.ACVTSD2SS: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Conv}, 69 x86.ACVTSL2SD: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Conv}, 70 x86.ACVTSL2SS: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Conv}, 71 x86.ACVTSQ2SD: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Conv}, 72 x86.ACVTSQ2SS: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Conv}, 73 x86.ACVTSS2SD: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Conv}, 74 x86.ACVTSS2SL: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv}, 75 x86.ACVTSS2SQ: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv}, 76 x86.ACVTTSD2SL: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv}, 77 x86.ACVTTSD2SQ: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv}, 78 x86.ACVTTSS2SL: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv}, 79 x86.ACVTTSS2SQ: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv}, 80 x86.ADECB: {Flags: gc.SizeB | RightRdwr}, 81 x86.ADECL: {Flags: gc.SizeL | RightRdwr}, 82 x86.ADECQ: {Flags: gc.SizeQ | RightRdwr}, 83 x86.ADECW: {Flags: gc.SizeW | RightRdwr}, 84 x86.ADIVB: {Flags: gc.SizeB | gc.LeftRead | gc.SetCarry, Reguse: AX, Regset: AX}, 85 x86.ADIVL: {Flags: gc.SizeL | gc.LeftRead | gc.SetCarry, Reguse: AX | DX, Regset: AX | DX}, 86 x86.ADIVQ: {Flags: gc.SizeQ | gc.LeftRead | gc.SetCarry, Reguse: AX | DX, Regset: AX | DX}, 87 x86.ADIVW: {Flags: gc.SizeW | gc.LeftRead | gc.SetCarry, Reguse: AX | DX, Regset: AX | DX}, 88 x86.ADIVSD: {Flags: gc.SizeD | gc.LeftRead | RightRdwr}, 89 x86.ADIVSS: {Flags: gc.SizeF | gc.LeftRead | RightRdwr}, 90 x86.AIDIVB: {Flags: gc.SizeB | gc.LeftRead | gc.SetCarry, Reguse: AX, Regset: AX}, 91 x86.AIDIVL: {Flags: gc.SizeL | gc.LeftRead | gc.SetCarry, Reguse: AX | DX, Regset: AX | DX}, 92 x86.AIDIVQ: {Flags: gc.SizeQ | gc.LeftRead | gc.SetCarry, Reguse: AX | DX, Regset: AX | DX}, 93 x86.AIDIVW: {Flags: gc.SizeW | gc.LeftRead | gc.SetCarry, Reguse: AX | DX, Regset: AX | DX}, 94 x86.AIMULB: {Flags: gc.SizeB | gc.LeftRead | gc.SetCarry, Reguse: AX, Regset: AX}, 95 x86.AIMULL: {Flags: gc.SizeL | gc.LeftRead | gc.ImulAXDX | gc.SetCarry}, 96 x86.AIMULQ: {Flags: gc.SizeQ | gc.LeftRead | gc.ImulAXDX | gc.SetCarry}, 97 x86.AIMULW: {Flags: gc.SizeW | gc.LeftRead | gc.ImulAXDX | gc.SetCarry}, 98 x86.AINCB: {Flags: gc.SizeB | RightRdwr}, 99 x86.AINCL: {Flags: gc.SizeL | RightRdwr}, 100 x86.AINCQ: {Flags: gc.SizeQ | RightRdwr}, 101 x86.AINCW: {Flags: gc.SizeW | RightRdwr}, 102 x86.AJCC: {Flags: gc.Cjmp | gc.UseCarry}, 103 x86.AJCS: {Flags: gc.Cjmp | gc.UseCarry}, 104 x86.AJEQ: {Flags: gc.Cjmp | gc.UseCarry}, 105 x86.AJGE: {Flags: gc.Cjmp | gc.UseCarry}, 106 x86.AJGT: {Flags: gc.Cjmp | gc.UseCarry}, 107 x86.AJHI: {Flags: gc.Cjmp | gc.UseCarry}, 108 x86.AJLE: {Flags: gc.Cjmp | gc.UseCarry}, 109 x86.AJLS: {Flags: gc.Cjmp | gc.UseCarry}, 110 x86.AJLT: {Flags: gc.Cjmp | gc.UseCarry}, 111 x86.AJMI: {Flags: gc.Cjmp | gc.UseCarry}, 112 x86.AJNE: {Flags: gc.Cjmp | gc.UseCarry}, 113 x86.AJOC: {Flags: gc.Cjmp | gc.UseCarry}, 114 x86.AJOS: {Flags: gc.Cjmp | gc.UseCarry}, 115 x86.AJPC: {Flags: gc.Cjmp | gc.UseCarry}, 116 x86.AJPL: {Flags: gc.Cjmp | gc.UseCarry}, 117 x86.AJPS: {Flags: gc.Cjmp | gc.UseCarry}, 118 obj.AJMP: {Flags: gc.Jump | gc.Break | gc.KillCarry}, 119 x86.ALEAL: {Flags: gc.LeftAddr | gc.RightWrite}, 120 x86.ALEAQ: {Flags: gc.LeftAddr | gc.RightWrite}, 121 x86.AMOVBLSX: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv}, 122 x86.AMOVBLZX: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv}, 123 x86.AMOVBQSX: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv}, 124 x86.AMOVBQZX: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv}, 125 x86.AMOVBWSX: {Flags: gc.SizeW | gc.LeftRead | gc.RightWrite | gc.Conv}, 126 x86.AMOVBWZX: {Flags: gc.SizeW | gc.LeftRead | gc.RightWrite | gc.Conv}, 127 x86.AMOVLQSX: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv}, 128 x86.AMOVLQZX: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv}, 129 x86.AMOVWLSX: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv}, 130 x86.AMOVWLZX: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv}, 131 x86.AMOVWQSX: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv}, 132 x86.AMOVWQZX: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv}, 133 x86.AMOVQL: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv}, 134 x86.AMOVB: {Flags: gc.SizeB | gc.LeftRead | gc.RightWrite | gc.Move}, 135 x86.AMOVL: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Move}, 136 x86.AMOVQ: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Move}, 137 x86.AMOVW: {Flags: gc.SizeW | gc.LeftRead | gc.RightWrite | gc.Move}, 138 x86.AMOVUPS: {Flags: gc.LeftRead | gc.RightWrite | gc.Move}, 139 x86.AMOVSB: {Flags: gc.OK, Reguse: DI | SI, Regset: DI | SI}, 140 x86.AMOVSL: {Flags: gc.OK, Reguse: DI | SI, Regset: DI | SI}, 141 x86.AMOVSQ: {Flags: gc.OK, Reguse: DI | SI, Regset: DI | SI}, 142 x86.AMOVSW: {Flags: gc.OK, Reguse: DI | SI, Regset: DI | SI}, 143 obj.ADUFFCOPY: {Flags: gc.OK, Reguse: DI | SI, Regset: DI | SI | CX}, 144 x86.AMOVSD: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Move}, 145 x86.AMOVSS: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Move}, 146 147 // We use MOVAPD as a faster synonym for MOVSD. 148 x86.AMOVAPD: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Move}, 149 x86.AMULB: {Flags: gc.SizeB | gc.LeftRead | gc.SetCarry, Reguse: AX, Regset: AX}, 150 x86.AMULL: {Flags: gc.SizeL | gc.LeftRead | gc.SetCarry, Reguse: AX, Regset: AX | DX}, 151 x86.AMULQ: {Flags: gc.SizeQ | gc.LeftRead | gc.SetCarry, Reguse: AX, Regset: AX | DX}, 152 x86.AMULW: {Flags: gc.SizeW | gc.LeftRead | gc.SetCarry, Reguse: AX, Regset: AX | DX}, 153 x86.AMULSD: {Flags: gc.SizeD | gc.LeftRead | RightRdwr}, 154 x86.AMULSS: {Flags: gc.SizeF | gc.LeftRead | RightRdwr}, 155 x86.ANEGB: {Flags: gc.SizeB | RightRdwr | gc.SetCarry}, 156 x86.ANEGL: {Flags: gc.SizeL | RightRdwr | gc.SetCarry}, 157 x86.ANEGQ: {Flags: gc.SizeQ | RightRdwr | gc.SetCarry}, 158 x86.ANEGW: {Flags: gc.SizeW | RightRdwr | gc.SetCarry}, 159 x86.ANOTB: {Flags: gc.SizeB | RightRdwr}, 160 x86.ANOTL: {Flags: gc.SizeL | RightRdwr}, 161 x86.ANOTQ: {Flags: gc.SizeQ | RightRdwr}, 162 x86.ANOTW: {Flags: gc.SizeW | RightRdwr}, 163 x86.AORB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.SetCarry}, 164 x86.AORL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.SetCarry}, 165 x86.AORQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.SetCarry}, 166 x86.AORW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry}, 167 x86.APOPQ: {Flags: gc.SizeQ | gc.RightWrite}, 168 x86.APUSHQ: {Flags: gc.SizeQ | gc.LeftRead}, 169 x86.ARCLB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry}, 170 x86.ARCLL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry}, 171 x86.ARCLQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry}, 172 x86.ARCLW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry}, 173 x86.ARCRB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry}, 174 x86.ARCRL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry}, 175 x86.ARCRQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry}, 176 x86.ARCRW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry}, 177 x86.AREP: {Flags: gc.OK, Reguse: CX, Regset: CX}, 178 x86.AREPN: {Flags: gc.OK, Reguse: CX, Regset: CX}, 179 obj.ARET: {Flags: gc.Break | gc.KillCarry}, 180 x86.AROLB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 181 x86.AROLL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 182 x86.AROLQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 183 x86.AROLW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 184 x86.ARORB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 185 x86.ARORL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 186 x86.ARORQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 187 x86.ARORW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 188 x86.ASALB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 189 x86.ASALL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 190 x86.ASALQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 191 x86.ASALW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 192 x86.ASARB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 193 x86.ASARL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 194 x86.ASARQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 195 x86.ASARW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 196 x86.ASBBB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.SetCarry | gc.UseCarry}, 197 x86.ASBBL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.SetCarry | gc.UseCarry}, 198 x86.ASBBQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.SetCarry | gc.UseCarry}, 199 x86.ASBBW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry | gc.UseCarry}, 200 x86.ASETCC: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry}, 201 x86.ASETCS: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry}, 202 x86.ASETEQ: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry}, 203 x86.ASETGE: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry}, 204 x86.ASETGT: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry}, 205 x86.ASETHI: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry}, 206 x86.ASETLE: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry}, 207 x86.ASETLS: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry}, 208 x86.ASETLT: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry}, 209 x86.ASETMI: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry}, 210 x86.ASETNE: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry}, 211 x86.ASETOC: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry}, 212 x86.ASETOS: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry}, 213 x86.ASETPC: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry}, 214 x86.ASETPL: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry}, 215 x86.ASETPS: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry}, 216 x86.ASHLB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 217 x86.ASHLL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 218 x86.ASHLQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 219 x86.ASHLW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 220 x86.ASHRB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 221 x86.ASHRL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 222 x86.ASHRQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 223 x86.ASHRW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry}, 224 x86.ASQRTSD: {Flags: gc.SizeD | gc.LeftRead | RightRdwr}, 225 x86.ASTOSB: {Flags: gc.OK, Reguse: AX | DI, Regset: DI}, 226 x86.ASTOSL: {Flags: gc.OK, Reguse: AX | DI, Regset: DI}, 227 x86.ASTOSQ: {Flags: gc.OK, Reguse: AX | DI, Regset: DI}, 228 x86.ASTOSW: {Flags: gc.OK, Reguse: AX | DI, Regset: DI}, 229 obj.ADUFFZERO: {Flags: gc.OK, Reguse: AX | DI, Regset: DI}, 230 x86.ASUBB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.SetCarry}, 231 x86.ASUBL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.SetCarry}, 232 x86.ASUBQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.SetCarry}, 233 x86.ASUBW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry}, 234 x86.ASUBSD: {Flags: gc.SizeD | gc.LeftRead | RightRdwr}, 235 x86.ASUBSS: {Flags: gc.SizeF | gc.LeftRead | RightRdwr}, 236 x86.ATESTB: {Flags: gc.SizeB | gc.LeftRead | gc.RightRead | gc.SetCarry}, 237 x86.ATESTL: {Flags: gc.SizeL | gc.LeftRead | gc.RightRead | gc.SetCarry}, 238 x86.ATESTQ: {Flags: gc.SizeQ | gc.LeftRead | gc.RightRead | gc.SetCarry}, 239 x86.ATESTW: {Flags: gc.SizeW | gc.LeftRead | gc.RightRead | gc.SetCarry}, 240 x86.AUCOMISD: {Flags: gc.SizeD | gc.LeftRead | gc.RightRead}, 241 x86.AUCOMISS: {Flags: gc.SizeF | gc.LeftRead | gc.RightRead}, 242 x86.AXCHGB: {Flags: gc.SizeB | LeftRdwr | RightRdwr}, 243 x86.AXCHGL: {Flags: gc.SizeL | LeftRdwr | RightRdwr}, 244 x86.AXCHGQ: {Flags: gc.SizeQ | LeftRdwr | RightRdwr}, 245 x86.AXCHGW: {Flags: gc.SizeW | LeftRdwr | RightRdwr}, 246 x86.AXORB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.SetCarry}, 247 x86.AXORL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.SetCarry}, 248 x86.AXORQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.SetCarry}, 249 x86.AXORW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry}, 250 x86.AXORPS: {Flags: gc.LeftRead | RightRdwr}, 251 } 252 253 func progflags(p *obj.Prog) uint32 { 254 flags := progtable[p.As].Flags 255 if flags&gc.ImulAXDX != 0 && p.To.Type != obj.TYPE_NONE { 256 flags |= RightRdwr 257 } 258 return flags 259 } 260 261 func progcarryflags(p *obj.Prog) uint32 { 262 return progtable[p.As].Flags 263 } 264 265 func proginfo(p *obj.Prog) { 266 info := &p.Info 267 *info = progtable[p.As] 268 if info.Flags == 0 { 269 gc.Fatalf("unknown instruction %v", p) 270 } 271 272 if (info.Flags&gc.ShiftCX != 0) && p.From.Type != obj.TYPE_CONST { 273 info.Reguse |= CX 274 } 275 276 if info.Flags&gc.ImulAXDX != 0 { 277 if p.To.Type == obj.TYPE_NONE { 278 info.Reguse |= AX 279 info.Regset |= AX | DX 280 } else { 281 info.Flags |= RightRdwr 282 } 283 } 284 285 // Addressing makes some registers used. 286 if p.From.Type == obj.TYPE_MEM && p.From.Name == obj.NAME_NONE { 287 info.Regindex |= RtoB(int(p.From.Reg)) 288 } 289 if p.From.Index != x86.REG_NONE { 290 info.Regindex |= RtoB(int(p.From.Index)) 291 } 292 if p.To.Type == obj.TYPE_MEM && p.To.Name == obj.NAME_NONE { 293 info.Regindex |= RtoB(int(p.To.Reg)) 294 } 295 if p.To.Index != x86.REG_NONE { 296 info.Regindex |= RtoB(int(p.To.Index)) 297 } 298 if gc.Ctxt.Flag_dynlink { 299 // When -dynlink is passed, many operations on external names (and 300 // also calling duffzero/duffcopy) use R15 as a scratch register. 301 if p.As == x86.ALEAQ || info.Flags == gc.Pseudo || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP { 302 return 303 } 304 if p.As == obj.ADUFFZERO || p.As == obj.ADUFFCOPY || (p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local) || (p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local) { 305 info.Reguse |= R15 306 info.Regset |= R15 307 return 308 } 309 } 310 }