github.com/riscv/riscv-go@v0.0.0-20200123204226-124ebd6fcc8e/src/cmd/compile/internal/ppc64/prog.go (about) 1 // Copyright 2014 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 ppc64 6 7 import ( 8 "cmd/compile/internal/gc" 9 "cmd/internal/obj" 10 "cmd/internal/obj/ppc64" 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 = [ppc64.ALAST & obj.AMask]gc.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.AVARDEF: {Flags: gc.Pseudo | gc.RightWrite}, 35 obj.AVARKILL: {Flags: gc.Pseudo | gc.RightWrite}, 36 obj.AVARLIVE: {Flags: gc.Pseudo | gc.LeftRead}, 37 38 // NOP is an internal no-op that also stands 39 // for USED and SET annotations, not the Power opcode. 40 obj.ANOP: {Flags: gc.LeftRead | gc.RightWrite}, 41 42 // Integer 43 ppc64.AADD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 44 ppc64.AADDC & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 45 ppc64.ASUB & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 46 ppc64.AADDME & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 47 ppc64.ANEG & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 48 ppc64.AAND & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 49 ppc64.AANDN & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 50 ppc64.AOR & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 51 ppc64.AORN & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 52 ppc64.AXOR & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 53 ppc64.AEQV & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 54 ppc64.AMULLD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 55 ppc64.AMULLW & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite}, 56 ppc64.AMULHD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 57 ppc64.AMULHDU & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 58 ppc64.AMULHW & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite}, 59 ppc64.AMULHWU & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite}, 60 ppc64.ADIVD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 61 ppc64.ADIVDU & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 62 ppc64.ADIVW & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite}, 63 ppc64.ADIVWU & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite}, 64 ppc64.ASLD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 65 ppc64.ASRD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 66 ppc64.ASRAD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 67 ppc64.ASLW & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite}, 68 ppc64.ASRW & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite}, 69 ppc64.ASRAW & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite}, 70 ppc64.ACMP & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RightRead}, 71 ppc64.ACMPU & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RightRead}, 72 ppc64.ACMPW & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RightRead}, 73 ppc64.ACMPWU & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RightRead}, 74 ppc64.ATD & obj.AMask: {Flags: gc.SizeQ | gc.RightRead}, 75 76 // Floating point. 77 ppc64.AFADD & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RegRead | gc.RightWrite}, 78 ppc64.AFADDS & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RegRead | gc.RightWrite}, 79 ppc64.AFSUB & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RegRead | gc.RightWrite}, 80 ppc64.AFSUBS & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RegRead | gc.RightWrite}, 81 ppc64.AFMUL & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RegRead | gc.RightWrite}, 82 ppc64.AFMULS & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RegRead | gc.RightWrite}, 83 ppc64.AFDIV & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RegRead | gc.RightWrite}, 84 ppc64.AFDIVS & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RegRead | gc.RightWrite}, 85 ppc64.AFCTIDZ & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RegRead | gc.RightWrite}, 86 ppc64.AFCTIWZ & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RegRead | gc.RightWrite}, 87 ppc64.AFCFID & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RegRead | gc.RightWrite}, 88 ppc64.AFCFIDU & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RegRead | gc.RightWrite}, 89 ppc64.AFCMPU & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RightRead}, 90 ppc64.AFRSP & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Conv}, 91 ppc64.AFSQRT & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite}, 92 ppc64.AFNEG & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite}, 93 94 // Moves 95 ppc64.AMOVB & obj.AMask: {Flags: gc.SizeB | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv}, 96 ppc64.AMOVBU & obj.AMask: {Flags: gc.SizeB | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv | gc.PostInc}, 97 ppc64.AMOVBZ & obj.AMask: {Flags: gc.SizeB | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv}, 98 ppc64.AMOVH & obj.AMask: {Flags: gc.SizeW | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv}, 99 ppc64.AMOVHU & obj.AMask: {Flags: gc.SizeW | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv | gc.PostInc}, 100 ppc64.AMOVHZ & obj.AMask: {Flags: gc.SizeW | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv}, 101 ppc64.AMOVW & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv}, 102 103 ppc64.AISEL & obj.AMask: {Flags: gc.SizeQ | gc.RegRead | gc.From3Read | gc.RightWrite}, 104 105 // there is no AMOVWU. 106 ppc64.AMOVWZU & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv | gc.PostInc}, 107 ppc64.AMOVWZ & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv}, 108 ppc64.AMOVD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Move}, 109 ppc64.AMOVDU & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Move | gc.PostInc}, 110 ppc64.AFMOVS & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv}, 111 ppc64.AFMOVSX & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv}, 112 ppc64.AFMOVSZ & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv}, 113 ppc64.AFMOVD & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Move}, 114 115 // Jumps 116 ppc64.ABR & obj.AMask: {Flags: gc.Jump | gc.Break}, 117 ppc64.ABL & obj.AMask: {Flags: gc.Call}, 118 ppc64.ABVS & obj.AMask: {Flags: gc.Cjmp}, 119 ppc64.ABVC & obj.AMask: {Flags: gc.Cjmp}, 120 ppc64.ABEQ & obj.AMask: {Flags: gc.Cjmp}, 121 ppc64.ABNE & obj.AMask: {Flags: gc.Cjmp}, 122 ppc64.ABGE & obj.AMask: {Flags: gc.Cjmp}, 123 ppc64.ABLT & obj.AMask: {Flags: gc.Cjmp}, 124 ppc64.ABGT & obj.AMask: {Flags: gc.Cjmp}, 125 ppc64.ABLE & obj.AMask: {Flags: gc.Cjmp}, 126 obj.ARET: {Flags: gc.Break}, 127 obj.ADUFFZERO: {Flags: gc.Call}, 128 obj.ADUFFCOPY: {Flags: gc.Call}, 129 } 130 131 func initproginfo() { 132 var addvariant = []int{V_CC, V_V, V_CC | V_V} 133 134 // Perform one-time expansion of instructions in progtable to 135 // their CC, V, and VCC variants 136 for i := range progtable { 137 as := obj.As(i) 138 if progtable[as].Flags == 0 { 139 continue 140 } 141 variant := as2variant(as) 142 for i := range addvariant { 143 as2 := variant2as(as, variant|addvariant[i]) 144 if as2 != 0 && progtable[as2&obj.AMask].Flags == 0 { 145 progtable[as2&obj.AMask] = progtable[as] 146 } 147 } 148 } 149 } 150 151 func proginfo(p *obj.Prog) gc.ProgInfo { 152 info := progtable[p.As&obj.AMask] 153 if info.Flags == 0 { 154 gc.Fatalf("proginfo: unknown instruction %v", p) 155 } 156 157 if (info.Flags&gc.RegRead != 0) && p.Reg == 0 { 158 info.Flags &^= gc.RegRead 159 info.Flags |= gc.RightRead /*CanRegRead |*/ 160 } 161 162 if p.From.Type == obj.TYPE_ADDR && p.From.Sym != nil && (info.Flags&gc.LeftRead != 0) { 163 info.Flags &^= gc.LeftRead 164 info.Flags |= gc.LeftAddr 165 } 166 167 return info 168 } 169 170 // Instruction variants table, populated by initvariants via Main. 171 // The index is the base form of the instruction, masked by obj.AMask. 172 // The 4 values are the unmasked base form, then the unmasked CC, V, 173 // and VCC variants, respectively. 174 var varianttable = [ppc64.ALAST & obj.AMask][4]obj.As{} 175 176 func initvariant(as obj.As, variants ...obj.As) { 177 vv := &varianttable[as&obj.AMask] 178 vv[0] = as 179 for i, v := range variants { 180 vv[i+1] = v 181 } 182 } 183 184 func initvariants() { 185 initvariant(ppc64.AADD, ppc64.AADDCC, ppc64.AADDV, ppc64.AADDVCC) 186 initvariant(ppc64.AADDC, ppc64.AADDCCC, ppc64.AADDCV, ppc64.AADDCVCC) 187 initvariant(ppc64.AADDE, ppc64.AADDECC, ppc64.AADDEV, ppc64.AADDEVCC) 188 initvariant(ppc64.AADDME, ppc64.AADDMECC, ppc64.AADDMEV, ppc64.AADDMEVCC) 189 initvariant(ppc64.AADDZE, ppc64.AADDZECC, ppc64.AADDZEV, ppc64.AADDZEVCC) 190 initvariant(ppc64.AAND, ppc64.AANDCC) 191 initvariant(ppc64.AANDN, ppc64.AANDNCC) 192 initvariant(ppc64.ACNTLZD, ppc64.ACNTLZDCC) 193 initvariant(ppc64.ACNTLZW, ppc64.ACNTLZWCC) 194 initvariant(ppc64.ADIVD, ppc64.ADIVDCC, ppc64.ADIVDV, ppc64.ADIVDVCC) 195 initvariant(ppc64.ADIVDU, ppc64.ADIVDUCC, ppc64.ADIVDUV, ppc64.ADIVDUVCC) 196 initvariant(ppc64.ADIVW, ppc64.ADIVWCC, ppc64.ADIVWV, ppc64.ADIVWVCC) 197 initvariant(ppc64.ADIVWU, ppc64.ADIVWUCC, ppc64.ADIVWUV, ppc64.ADIVWUVCC) 198 initvariant(ppc64.AEQV, ppc64.AEQVCC) 199 initvariant(ppc64.AEXTSB, ppc64.AEXTSBCC) 200 initvariant(ppc64.AEXTSH, ppc64.AEXTSHCC) 201 initvariant(ppc64.AEXTSW, ppc64.AEXTSWCC) 202 initvariant(ppc64.AFABS, ppc64.AFABSCC) 203 initvariant(ppc64.AFADD, ppc64.AFADDCC) 204 initvariant(ppc64.AFADDS, ppc64.AFADDSCC) 205 initvariant(ppc64.AFCFID, ppc64.AFCFIDCC) 206 initvariant(ppc64.AFCFIDU, ppc64.AFCFIDUCC) 207 initvariant(ppc64.AFCTID, ppc64.AFCTIDCC) 208 initvariant(ppc64.AFCTIDZ, ppc64.AFCTIDZCC) 209 initvariant(ppc64.AFCTIW, ppc64.AFCTIWCC) 210 initvariant(ppc64.AFCTIWZ, ppc64.AFCTIWZCC) 211 initvariant(ppc64.AFDIV, ppc64.AFDIVCC) 212 initvariant(ppc64.AFDIVS, ppc64.AFDIVSCC) 213 initvariant(ppc64.AFMADD, ppc64.AFMADDCC) 214 initvariant(ppc64.AFMADDS, ppc64.AFMADDSCC) 215 initvariant(ppc64.AFMOVD, ppc64.AFMOVDCC) 216 initvariant(ppc64.AFMSUB, ppc64.AFMSUBCC) 217 initvariant(ppc64.AFMSUBS, ppc64.AFMSUBSCC) 218 initvariant(ppc64.AFMUL, ppc64.AFMULCC) 219 initvariant(ppc64.AFMULS, ppc64.AFMULSCC) 220 initvariant(ppc64.AFNABS, ppc64.AFNABSCC) 221 initvariant(ppc64.AFNEG, ppc64.AFNEGCC) 222 initvariant(ppc64.AFNMADD, ppc64.AFNMADDCC) 223 initvariant(ppc64.AFNMADDS, ppc64.AFNMADDSCC) 224 initvariant(ppc64.AFNMSUB, ppc64.AFNMSUBCC) 225 initvariant(ppc64.AFNMSUBS, ppc64.AFNMSUBSCC) 226 initvariant(ppc64.AFRES, ppc64.AFRESCC) 227 initvariant(ppc64.AFRSP, ppc64.AFRSPCC) 228 initvariant(ppc64.AFRSQRTE, ppc64.AFRSQRTECC) 229 initvariant(ppc64.AFSEL, ppc64.AFSELCC) 230 initvariant(ppc64.AFSQRT, ppc64.AFSQRTCC) 231 initvariant(ppc64.AFSQRTS, ppc64.AFSQRTSCC) 232 initvariant(ppc64.AFSUB, ppc64.AFSUBCC) 233 initvariant(ppc64.AFSUBS, ppc64.AFSUBSCC) 234 initvariant(ppc64.AMTFSB0, ppc64.AMTFSB0CC) 235 initvariant(ppc64.AMTFSB1, ppc64.AMTFSB1CC) 236 initvariant(ppc64.AMULHD, ppc64.AMULHDCC) 237 initvariant(ppc64.AMULHDU, ppc64.AMULHDUCC) 238 initvariant(ppc64.AMULHW, ppc64.AMULHWCC) 239 initvariant(ppc64.AMULHWU, ppc64.AMULHWUCC) 240 initvariant(ppc64.AMULLD, ppc64.AMULLDCC, ppc64.AMULLDV, ppc64.AMULLDVCC) 241 initvariant(ppc64.AMULLW, ppc64.AMULLWCC, ppc64.AMULLWV, ppc64.AMULLWVCC) 242 initvariant(ppc64.ANAND, ppc64.ANANDCC) 243 initvariant(ppc64.ANEG, ppc64.ANEGCC, ppc64.ANEGV, ppc64.ANEGVCC) 244 initvariant(ppc64.ANOR, ppc64.ANORCC) 245 initvariant(ppc64.AOR, ppc64.AORCC) 246 initvariant(ppc64.AORN, ppc64.AORNCC) 247 initvariant(ppc64.AREM, ppc64.AREMCC, ppc64.AREMV, ppc64.AREMVCC) 248 initvariant(ppc64.AREMD, ppc64.AREMDCC, ppc64.AREMDV, ppc64.AREMDVCC) 249 initvariant(ppc64.AREMDU, ppc64.AREMDUCC, ppc64.AREMDUV, ppc64.AREMDUVCC) 250 initvariant(ppc64.AREMU, ppc64.AREMUCC, ppc64.AREMUV, ppc64.AREMUVCC) 251 initvariant(ppc64.ARLDC, ppc64.ARLDCCC) 252 initvariant(ppc64.ARLDCL, ppc64.ARLDCLCC) 253 initvariant(ppc64.ARLDCR, ppc64.ARLDCRCC) 254 initvariant(ppc64.ARLDMI, ppc64.ARLDMICC) 255 initvariant(ppc64.ARLWMI, ppc64.ARLWMICC) 256 initvariant(ppc64.ARLWNM, ppc64.ARLWNMCC) 257 initvariant(ppc64.ASLD, ppc64.ASLDCC) 258 initvariant(ppc64.ASLW, ppc64.ASLWCC) 259 initvariant(ppc64.ASRAD, ppc64.ASRADCC) 260 initvariant(ppc64.ASRAW, ppc64.ASRAWCC) 261 initvariant(ppc64.ASRD, ppc64.ASRDCC) 262 initvariant(ppc64.ASRW, ppc64.ASRWCC) 263 initvariant(ppc64.ASUB, ppc64.ASUBCC, ppc64.ASUBV, ppc64.ASUBVCC) 264 initvariant(ppc64.ASUBC, ppc64.ASUBCCC, ppc64.ASUBCV, ppc64.ASUBCVCC) 265 initvariant(ppc64.ASUBE, ppc64.ASUBECC, ppc64.ASUBEV, ppc64.ASUBEVCC) 266 initvariant(ppc64.ASUBME, ppc64.ASUBMECC, ppc64.ASUBMEV, ppc64.ASUBMEVCC) 267 initvariant(ppc64.ASUBZE, ppc64.ASUBZECC, ppc64.ASUBZEV, ppc64.ASUBZEVCC) 268 initvariant(ppc64.AXOR, ppc64.AXORCC) 269 270 for i := range varianttable { 271 vv := &varianttable[i] 272 if vv[0] == 0 { 273 // Instruction has no variants 274 varianttable[i][0] = obj.As(i) 275 continue 276 } 277 278 // Copy base form to other variants 279 if vv[0]&obj.AMask == obj.As(i) { 280 for _, v := range vv { 281 if v != 0 { 282 varianttable[v&obj.AMask] = varianttable[i] 283 } 284 } 285 } 286 } 287 } 288 289 // as2variant returns the variant (V_*) flags of instruction as. 290 func as2variant(as obj.As) int { 291 for i, v := range varianttable[as&obj.AMask] { 292 if v&obj.AMask == as&obj.AMask { 293 return i 294 } 295 } 296 gc.Fatalf("as2variant: instruction %v is not a variant of itself", as&obj.AMask) 297 return 0 298 } 299 300 // variant2as returns the instruction as with the given variant (V_*) flags. 301 // If no such variant exists, this returns 0. 302 func variant2as(as obj.As, flags int) obj.As { 303 return varianttable[as&obj.AMask][flags] 304 }