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