github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/src/cmd/internal/obj/ppc64/asm9.go (about) 1 // cmd/9l/optab.c, cmd/9l/asmout.c from Vita Nuova. 2 // 3 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 4 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 5 // Portions Copyright © 1997-1999 Vita Nuova Limited 6 // Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) 7 // Portions Copyright © 2004,2006 Bruce Ellis 8 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 9 // Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others 10 // Portions Copyright © 2009 The Go Authors. All rights reserved. 11 // 12 // Permission is hereby granted, free of charge, to any person obtaining a copy 13 // of this software and associated documentation files (the "Software"), to deal 14 // in the Software without restriction, including without limitation the rights 15 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 // copies of the Software, and to permit persons to whom the Software is 17 // furnished to do so, subject to the following conditions: 18 // 19 // The above copyright notice and this permission notice shall be included in 20 // all copies or substantial portions of the Software. 21 // 22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 // THE SOFTWARE. 29 30 package ppc64 31 32 import ( 33 "cmd/internal/obj" 34 "encoding/binary" 35 "fmt" 36 "log" 37 "sort" 38 ) 39 40 // Instruction layout. 41 42 const ( 43 FuncAlign = 8 44 ) 45 46 const ( 47 r0iszero = 1 48 ) 49 50 type Optab struct { 51 as obj.As 52 a1 uint8 53 a2 uint8 54 a3 uint8 55 a4 uint8 56 type_ int8 57 size int8 58 param int16 59 } 60 61 var optab = []Optab{ 62 {obj.ATEXT, C_LEXT, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0}, 63 {obj.ATEXT, C_LEXT, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0}, 64 {obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0}, 65 {obj.ATEXT, C_ADDR, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0}, 66 /* move register */ 67 {AMOVD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0}, 68 {AMOVB, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0}, 69 {AMOVBZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0}, 70 {AMOVW, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0}, 71 {AMOVWZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0}, 72 {AADD, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, 73 {AADD, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0}, 74 {AADD, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0}, 75 {AADD, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0}, 76 {AADD, C_UCON, C_REG, C_NONE, C_REG, 20, 4, 0}, 77 {AADD, C_UCON, C_NONE, C_NONE, C_REG, 20, 4, 0}, 78 {AADD, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0}, 79 {AADD, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0}, 80 {AADDC, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, 81 {AADDC, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0}, 82 {AADDC, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0}, 83 {AADDC, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0}, 84 {AADDC, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0}, 85 {AADDC, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0}, 86 {AAND, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, no literal */ 87 {AAND, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0}, 88 {AANDCC, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, 89 {AANDCC, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0}, 90 {AANDCC, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0}, 91 {AANDCC, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0}, 92 {AANDCC, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0}, 93 {AANDCC, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0}, 94 {AANDCC, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0}, 95 {AANDCC, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0}, 96 {AMULLW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, 97 {AMULLW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0}, 98 {AMULLW, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0}, 99 {AMULLW, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0}, 100 {AMULLW, C_ANDCON, C_REG, C_NONE, C_REG, 4, 4, 0}, 101 {AMULLW, C_ANDCON, C_NONE, C_NONE, C_REG, 4, 4, 0}, 102 {AMULLW, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0}, 103 {AMULLW, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0}, 104 {ASUBC, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0}, 105 {ASUBC, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0}, 106 {ASUBC, C_REG, C_NONE, C_ADDCON, C_REG, 27, 4, 0}, 107 {ASUBC, C_REG, C_NONE, C_LCON, C_REG, 28, 12, 0}, 108 {AOR, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, literal not cc (or/xor) */ 109 {AOR, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0}, 110 {AOR, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0}, 111 {AOR, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0}, 112 {AOR, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0}, 113 {AOR, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0}, 114 {AOR, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0}, 115 {AOR, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0}, 116 {ADIVW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, /* op r1[,r2],r3 */ 117 {ADIVW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0}, 118 {ASUB, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0}, /* op r2[,r1],r3 */ 119 {ASUB, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0}, 120 {ASLW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0}, 121 {ASLW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, 122 {ASLD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0}, 123 {ASLD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, 124 {ASLD, C_SCON, C_REG, C_NONE, C_REG, 25, 4, 0}, 125 {ASLD, C_SCON, C_NONE, C_NONE, C_REG, 25, 4, 0}, 126 {ASLW, C_SCON, C_REG, C_NONE, C_REG, 57, 4, 0}, 127 {ASLW, C_SCON, C_NONE, C_NONE, C_REG, 57, 4, 0}, 128 {ASRAW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0}, 129 {ASRAW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, 130 {ASRAW, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0}, 131 {ASRAW, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0}, 132 {ASRAD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0}, 133 {ASRAD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, 134 {ASRAD, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0}, 135 {ASRAD, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0}, 136 {ARLWMI, C_SCON, C_REG, C_LCON, C_REG, 62, 4, 0}, 137 {ARLWMI, C_REG, C_REG, C_LCON, C_REG, 63, 4, 0}, 138 {ARLDMI, C_SCON, C_REG, C_LCON, C_REG, 30, 4, 0}, 139 {ARLDC, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0}, 140 {ARLDCL, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0}, 141 {ARLDCL, C_REG, C_REG, C_LCON, C_REG, 14, 4, 0}, 142 {ARLDCL, C_REG, C_NONE, C_LCON, C_REG, 14, 4, 0}, 143 {AFADD, C_FREG, C_NONE, C_NONE, C_FREG, 2, 4, 0}, 144 {AFADD, C_FREG, C_REG, C_NONE, C_FREG, 2, 4, 0}, 145 {AFABS, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0}, 146 {AFABS, C_NONE, C_NONE, C_NONE, C_FREG, 33, 4, 0}, 147 {AFMOVD, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0}, 148 {AFMADD, C_FREG, C_REG, C_FREG, C_FREG, 34, 4, 0}, 149 {AFMUL, C_FREG, C_NONE, C_NONE, C_FREG, 32, 4, 0}, 150 {AFMUL, C_FREG, C_REG, C_NONE, C_FREG, 32, 4, 0}, 151 152 /* store, short offset */ 153 {AMOVD, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO}, 154 {AMOVW, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO}, 155 {AMOVWZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO}, 156 {AMOVBZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO}, 157 {AMOVBZU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO}, 158 {AMOVB, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO}, 159 {AMOVBU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO}, 160 {AMOVD, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB}, 161 {AMOVW, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB}, 162 {AMOVWZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB}, 163 {AMOVBZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB}, 164 {AMOVB, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB}, 165 {AMOVD, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP}, 166 {AMOVW, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP}, 167 {AMOVWZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP}, 168 {AMOVBZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP}, 169 {AMOVB, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP}, 170 {AMOVD, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO}, 171 {AMOVW, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO}, 172 {AMOVWZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO}, 173 {AMOVBZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO}, 174 {AMOVBZU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO}, 175 {AMOVB, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO}, 176 {AMOVBU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO}, 177 178 /* load, short offset */ 179 {AMOVD, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO}, 180 {AMOVW, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO}, 181 {AMOVWZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO}, 182 {AMOVBZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO}, 183 {AMOVBZU, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO}, 184 {AMOVB, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO}, 185 {AMOVBU, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO}, 186 {AMOVD, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB}, 187 {AMOVW, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB}, 188 {AMOVWZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB}, 189 {AMOVBZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB}, 190 {AMOVB, C_SEXT, C_NONE, C_NONE, C_REG, 9, 8, REGSB}, 191 {AMOVD, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP}, 192 {AMOVW, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP}, 193 {AMOVWZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP}, 194 {AMOVBZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP}, 195 {AMOVB, C_SAUTO, C_NONE, C_NONE, C_REG, 9, 8, REGSP}, 196 {AMOVD, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO}, 197 {AMOVW, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO}, 198 {AMOVWZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO}, 199 {AMOVBZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO}, 200 {AMOVBZU, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO}, 201 {AMOVB, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO}, 202 {AMOVBU, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO}, 203 204 /* store, long offset */ 205 {AMOVD, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB}, 206 {AMOVW, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB}, 207 {AMOVWZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB}, 208 {AMOVBZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB}, 209 {AMOVB, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB}, 210 {AMOVD, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP}, 211 {AMOVW, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP}, 212 {AMOVWZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP}, 213 {AMOVBZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP}, 214 {AMOVB, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP}, 215 {AMOVD, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO}, 216 {AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO}, 217 {AMOVWZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO}, 218 {AMOVBZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO}, 219 {AMOVB, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO}, 220 {AMOVD, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0}, 221 {AMOVW, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0}, 222 {AMOVWZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0}, 223 {AMOVBZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0}, 224 {AMOVB, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0}, 225 226 /* load, long offset */ 227 {AMOVD, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB}, 228 {AMOVW, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB}, 229 {AMOVWZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB}, 230 {AMOVBZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB}, 231 {AMOVB, C_LEXT, C_NONE, C_NONE, C_REG, 37, 12, REGSB}, 232 {AMOVD, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP}, 233 {AMOVW, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP}, 234 {AMOVWZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP}, 235 {AMOVBZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP}, 236 {AMOVB, C_LAUTO, C_NONE, C_NONE, C_REG, 37, 12, REGSP}, 237 {AMOVD, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO}, 238 {AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO}, 239 {AMOVWZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO}, 240 {AMOVBZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO}, 241 {AMOVB, C_LOREG, C_NONE, C_NONE, C_REG, 37, 12, REGZERO}, 242 {AMOVD, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0}, 243 {AMOVW, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0}, 244 {AMOVWZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0}, 245 {AMOVBZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0}, 246 {AMOVB, C_ADDR, C_NONE, C_NONE, C_REG, 76, 12, 0}, 247 248 {AMOVD, C_TLS_LE, C_NONE, C_NONE, C_REG, 79, 4, 0}, 249 {AMOVD, C_TLS_IE, C_NONE, C_NONE, C_REG, 80, 8, 0}, 250 251 {AMOVD, C_GOTADDR, C_NONE, C_NONE, C_REG, 81, 8, 0}, 252 253 /* load constant */ 254 {AMOVD, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, 255 {AMOVD, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP}, 256 {AMOVD, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB}, 257 {AMOVD, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP}, 258 {AMOVD, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO}, 259 {AMOVW, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */ 260 {AMOVW, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP}, 261 {AMOVW, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB}, 262 {AMOVW, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP}, 263 {AMOVW, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO}, 264 {AMOVWZ, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */ 265 {AMOVWZ, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP}, 266 {AMOVWZ, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB}, 267 {AMOVWZ, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP}, 268 {AMOVWZ, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO}, 269 270 /* load unsigned/long constants (TO DO: check) */ 271 {AMOVD, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO}, 272 {AMOVD, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0}, 273 {AMOVW, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO}, 274 {AMOVW, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0}, 275 {AMOVWZ, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO}, 276 {AMOVWZ, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0}, 277 {AMOVHBR, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0}, 278 {AMOVHBR, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0}, 279 {AMOVHBR, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0}, 280 {AMOVHBR, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0}, 281 {ASYSCALL, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0}, 282 {ASYSCALL, C_REG, C_NONE, C_NONE, C_NONE, 77, 12, 0}, 283 {ASYSCALL, C_SCON, C_NONE, C_NONE, C_NONE, 77, 12, 0}, 284 {ABEQ, C_NONE, C_NONE, C_NONE, C_SBRA, 16, 4, 0}, 285 {ABEQ, C_CREG, C_NONE, C_NONE, C_SBRA, 16, 4, 0}, 286 {ABR, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, 287 {ABR, C_NONE, C_NONE, C_NONE, C_LBRAPIC, 11, 8, 0}, 288 {ABC, C_SCON, C_REG, C_NONE, C_SBRA, 16, 4, 0}, 289 {ABC, C_SCON, C_REG, C_NONE, C_LBRA, 17, 4, 0}, 290 {ABR, C_NONE, C_NONE, C_NONE, C_LR, 18, 4, 0}, 291 {ABR, C_NONE, C_NONE, C_NONE, C_CTR, 18, 4, 0}, 292 {ABR, C_REG, C_NONE, C_NONE, C_CTR, 18, 4, 0}, 293 {ABR, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0}, 294 {ABC, C_NONE, C_REG, C_NONE, C_LR, 18, 4, 0}, 295 {ABC, C_NONE, C_REG, C_NONE, C_CTR, 18, 4, 0}, 296 {ABC, C_SCON, C_REG, C_NONE, C_LR, 18, 4, 0}, 297 {ABC, C_SCON, C_REG, C_NONE, C_CTR, 18, 4, 0}, 298 {ABC, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0}, 299 {AFMOVD, C_SEXT, C_NONE, C_NONE, C_FREG, 8, 4, REGSB}, 300 {AFMOVD, C_SAUTO, C_NONE, C_NONE, C_FREG, 8, 4, REGSP}, 301 {AFMOVD, C_SOREG, C_NONE, C_NONE, C_FREG, 8, 4, REGZERO}, 302 {AFMOVD, C_LEXT, C_NONE, C_NONE, C_FREG, 36, 8, REGSB}, 303 {AFMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, 36, 8, REGSP}, 304 {AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 36, 8, REGZERO}, 305 {AFMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, 75, 8, 0}, 306 {AFMOVD, C_FREG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB}, 307 {AFMOVD, C_FREG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP}, 308 {AFMOVD, C_FREG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO}, 309 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB}, 310 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP}, 311 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO}, 312 {AFMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, 74, 8, 0}, 313 {ASYNC, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0}, 314 {AWORD, C_LCON, C_NONE, C_NONE, C_NONE, 40, 4, 0}, 315 {ADWORD, C_LCON, C_NONE, C_NONE, C_NONE, 31, 8, 0}, 316 {ADWORD, C_DCON, C_NONE, C_NONE, C_NONE, 31, 8, 0}, 317 {AADDME, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0}, 318 {AEXTSB, C_REG, C_NONE, C_NONE, C_REG, 48, 4, 0}, 319 {AEXTSB, C_NONE, C_NONE, C_NONE, C_REG, 48, 4, 0}, 320 {ANEG, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0}, 321 {ANEG, C_NONE, C_NONE, C_NONE, C_REG, 47, 4, 0}, 322 {AREM, C_REG, C_NONE, C_NONE, C_REG, 50, 12, 0}, 323 {AREM, C_REG, C_REG, C_NONE, C_REG, 50, 12, 0}, 324 {AREMU, C_REG, C_NONE, C_NONE, C_REG, 50, 16, 0}, 325 {AREMU, C_REG, C_REG, C_NONE, C_REG, 50, 16, 0}, 326 {AREMD, C_REG, C_NONE, C_NONE, C_REG, 51, 12, 0}, 327 {AREMD, C_REG, C_REG, C_NONE, C_REG, 51, 12, 0}, 328 {AREMDU, C_REG, C_NONE, C_NONE, C_REG, 51, 12, 0}, 329 {AREMDU, C_REG, C_REG, C_NONE, C_REG, 51, 12, 0}, 330 {AMTFSB0, C_SCON, C_NONE, C_NONE, C_NONE, 52, 4, 0}, 331 {AMOVFL, C_FPSCR, C_NONE, C_NONE, C_FREG, 53, 4, 0}, 332 {AMOVFL, C_FREG, C_NONE, C_NONE, C_FPSCR, 64, 4, 0}, 333 {AMOVFL, C_FREG, C_NONE, C_LCON, C_FPSCR, 64, 4, 0}, 334 {AMOVFL, C_LCON, C_NONE, C_NONE, C_FPSCR, 65, 4, 0}, 335 {AMOVD, C_MSR, C_NONE, C_NONE, C_REG, 54, 4, 0}, /* mfmsr */ 336 {AMOVD, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0}, /* mtmsrd */ 337 {AMOVWZ, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0}, /* mtmsr */ 338 339 /* 64-bit special registers */ 340 {AMOVD, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0}, 341 {AMOVD, C_REG, C_NONE, C_NONE, C_LR, 66, 4, 0}, 342 {AMOVD, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0}, 343 {AMOVD, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0}, 344 {AMOVD, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0}, 345 {AMOVD, C_LR, C_NONE, C_NONE, C_REG, 66, 4, 0}, 346 {AMOVD, C_CTR, C_NONE, C_NONE, C_REG, 66, 4, 0}, 347 {AMOVD, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0}, 348 349 /* 32-bit special registers (gloss over sign-extension or not?) */ 350 {AMOVW, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0}, 351 {AMOVW, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0}, 352 {AMOVW, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0}, 353 {AMOVW, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0}, 354 {AMOVW, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0}, 355 {AMOVWZ, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0}, 356 {AMOVWZ, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0}, 357 {AMOVWZ, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0}, 358 {AMOVWZ, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0}, 359 {AMOVWZ, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0}, 360 {AMOVFL, C_FPSCR, C_NONE, C_NONE, C_CREG, 73, 4, 0}, 361 {AMOVFL, C_CREG, C_NONE, C_NONE, C_CREG, 67, 4, 0}, 362 {AMOVW, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0}, 363 {AMOVWZ, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0}, 364 {AMOVFL, C_REG, C_NONE, C_LCON, C_CREG, 69, 4, 0}, 365 {AMOVFL, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0}, 366 {AMOVW, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0}, 367 {AMOVWZ, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0}, 368 {ACMP, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0}, 369 {ACMP, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0}, 370 {ACMP, C_REG, C_NONE, C_NONE, C_ADDCON, 71, 4, 0}, 371 {ACMP, C_REG, C_REG, C_NONE, C_ADDCON, 71, 4, 0}, 372 {ACMPU, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0}, 373 {ACMPU, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0}, 374 {ACMPU, C_REG, C_NONE, C_NONE, C_ANDCON, 71, 4, 0}, 375 {ACMPU, C_REG, C_REG, C_NONE, C_ANDCON, 71, 4, 0}, 376 {AFCMPO, C_FREG, C_NONE, C_NONE, C_FREG, 70, 4, 0}, 377 {AFCMPO, C_FREG, C_REG, C_NONE, C_FREG, 70, 4, 0}, 378 {ATW, C_LCON, C_REG, C_NONE, C_REG, 60, 4, 0}, 379 {ATW, C_LCON, C_REG, C_NONE, C_ADDCON, 61, 4, 0}, 380 {ADCBF, C_ZOREG, C_NONE, C_NONE, C_NONE, 43, 4, 0}, 381 {ADCBF, C_ZOREG, C_REG, C_NONE, C_NONE, 43, 4, 0}, 382 {AECOWX, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0}, 383 {AECIWX, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0}, 384 {AECOWX, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0}, 385 {AECIWX, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0}, 386 {AEIEIO, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0}, 387 {ATLBIE, C_REG, C_NONE, C_NONE, C_NONE, 49, 4, 0}, 388 {ATLBIE, C_SCON, C_NONE, C_NONE, C_REG, 49, 4, 0}, 389 {ASLBMFEE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0}, 390 {ASLBMTE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0}, 391 {ASTSW, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0}, 392 {ASTSW, C_REG, C_NONE, C_LCON, C_ZOREG, 41, 4, 0}, 393 {ALSW, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0}, 394 {ALSW, C_ZOREG, C_NONE, C_LCON, C_REG, 42, 4, 0}, 395 {obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0}, 396 {obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, C_NONE, 0, 0, 0}, 397 {obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0}, 398 {obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0}, 399 {obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0}, 400 {obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL 401 {obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL 402 403 {obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0}, 404 } 405 406 var oprange [ALAST & obj.AMask][]Optab 407 408 var xcmp [C_NCLASS][C_NCLASS]bool 409 410 func span9(ctxt *obj.Link, cursym *obj.LSym) { 411 p := cursym.Text 412 if p == nil || p.Link == nil { // handle external functions and ELF section symbols 413 return 414 } 415 ctxt.Cursym = cursym 416 ctxt.Autosize = int32(p.To.Offset) 417 418 if oprange[AANDN&obj.AMask] == nil { 419 buildop(ctxt) 420 } 421 422 c := int64(0) 423 p.Pc = c 424 425 var m int 426 var o *Optab 427 for p = p.Link; p != nil; p = p.Link { 428 ctxt.Curp = p 429 p.Pc = c 430 o = oplook(ctxt, p) 431 m = int(o.size) 432 if m == 0 { 433 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD { 434 ctxt.Diag("zero-width instruction\n%v", p) 435 } 436 continue 437 } 438 439 c += int64(m) 440 } 441 442 cursym.Size = c 443 444 /* 445 * if any procedure is large enough to 446 * generate a large SBRA branch, then 447 * generate extra passes putting branches 448 * around jmps to fix. this is rare. 449 */ 450 bflag := 1 451 452 var otxt int64 453 var q *obj.Prog 454 for bflag != 0 { 455 if ctxt.Debugvlog != 0 { 456 fmt.Fprintf(ctxt.Bso, "%5.2f span1\n", obj.Cputime()) 457 } 458 bflag = 0 459 c = 0 460 for p = cursym.Text.Link; p != nil; p = p.Link { 461 p.Pc = c 462 o = oplook(ctxt, p) 463 464 // very large conditional branches 465 if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil { 466 otxt = p.Pcond.Pc - c 467 if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 { 468 q = ctxt.NewProg() 469 q.Link = p.Link 470 p.Link = q 471 q.As = ABR 472 q.To.Type = obj.TYPE_BRANCH 473 q.Pcond = p.Pcond 474 p.Pcond = q 475 q = ctxt.NewProg() 476 q.Link = p.Link 477 p.Link = q 478 q.As = ABR 479 q.To.Type = obj.TYPE_BRANCH 480 q.Pcond = q.Link.Link 481 482 //addnop(p->link); 483 //addnop(p); 484 bflag = 1 485 } 486 } 487 488 m = int(o.size) 489 if m == 0 { 490 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD { 491 ctxt.Diag("zero-width instruction\n%v", p) 492 } 493 continue 494 } 495 496 c += int64(m) 497 } 498 499 cursym.Size = c 500 } 501 502 c += -c & (FuncAlign - 1) 503 cursym.Size = c 504 505 /* 506 * lay out the code, emitting code and data relocations. 507 */ 508 509 cursym.Grow(cursym.Size) 510 511 bp := cursym.P 512 var i int32 513 var out [6]uint32 514 for p := cursym.Text.Link; p != nil; p = p.Link { 515 ctxt.Pc = p.Pc 516 ctxt.Curp = p 517 o = oplook(ctxt, p) 518 if int(o.size) > 4*len(out) { 519 log.Fatalf("out array in span9 is too small, need at least %d for %v", o.size/4, p) 520 } 521 asmout(ctxt, p, o, out[:]) 522 for i = 0; i < int32(o.size/4); i++ { 523 ctxt.Arch.ByteOrder.PutUint32(bp, out[i]) 524 bp = bp[4:] 525 } 526 } 527 } 528 529 func isint32(v int64) bool { 530 return int64(int32(v)) == v 531 } 532 533 func isuint32(v uint64) bool { 534 return uint64(uint32(v)) == v 535 } 536 537 func aclass(ctxt *obj.Link, a *obj.Addr) int { 538 switch a.Type { 539 case obj.TYPE_NONE: 540 return C_NONE 541 542 case obj.TYPE_REG: 543 if REG_R0 <= a.Reg && a.Reg <= REG_R31 { 544 return C_REG 545 } 546 if REG_F0 <= a.Reg && a.Reg <= REG_F31 { 547 return C_FREG 548 } 549 if REG_CR0 <= a.Reg && a.Reg <= REG_CR7 || a.Reg == REG_CR { 550 return C_CREG 551 } 552 if REG_SPR0 <= a.Reg && a.Reg <= REG_SPR0+1023 { 553 switch a.Reg { 554 case REG_LR: 555 return C_LR 556 557 case REG_XER: 558 return C_XER 559 560 case REG_CTR: 561 return C_CTR 562 } 563 564 return C_SPR 565 } 566 567 if REG_DCR0 <= a.Reg && a.Reg <= REG_DCR0+1023 { 568 return C_SPR 569 } 570 if a.Reg == REG_FPSCR { 571 return C_FPSCR 572 } 573 if a.Reg == REG_MSR { 574 return C_MSR 575 } 576 return C_GOK 577 578 case obj.TYPE_MEM: 579 switch a.Name { 580 case obj.NAME_EXTERN, 581 obj.NAME_STATIC: 582 if a.Sym == nil { 583 break 584 } 585 ctxt.Instoffset = a.Offset 586 if a.Sym != nil { // use relocation 587 if a.Sym.Type == obj.STLSBSS { 588 if ctxt.Flag_shared != 0 { 589 return C_TLS_IE 590 } else { 591 return C_TLS_LE 592 } 593 } 594 return C_ADDR 595 } 596 return C_LEXT 597 598 case obj.NAME_GOTREF: 599 return C_GOTADDR 600 601 case obj.NAME_AUTO: 602 ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset 603 if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { 604 return C_SAUTO 605 } 606 return C_LAUTO 607 608 case obj.NAME_PARAM: 609 ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + ctxt.FixedFrameSize() 610 if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { 611 return C_SAUTO 612 } 613 return C_LAUTO 614 615 case obj.NAME_NONE: 616 ctxt.Instoffset = a.Offset 617 if ctxt.Instoffset == 0 { 618 return C_ZOREG 619 } 620 if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { 621 return C_SOREG 622 } 623 return C_LOREG 624 } 625 626 return C_GOK 627 628 case obj.TYPE_TEXTSIZE: 629 return C_TEXTSIZE 630 631 case obj.TYPE_CONST, 632 obj.TYPE_ADDR: 633 switch a.Name { 634 case obj.NAME_NONE: 635 ctxt.Instoffset = a.Offset 636 if a.Reg != 0 { 637 if -BIG <= ctxt.Instoffset && ctxt.Instoffset <= BIG { 638 return C_SACON 639 } 640 if isint32(ctxt.Instoffset) { 641 return C_LACON 642 } 643 return C_DACON 644 } 645 646 goto consize 647 648 case obj.NAME_EXTERN, 649 obj.NAME_STATIC: 650 s := a.Sym 651 if s == nil { 652 break 653 } 654 if s.Type == obj.SCONST { 655 ctxt.Instoffset = a.Offset 656 goto consize 657 } 658 659 ctxt.Instoffset = a.Offset 660 661 /* not sure why this barfs */ 662 return C_LCON 663 664 case obj.NAME_AUTO: 665 ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset 666 if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { 667 return C_SACON 668 } 669 return C_LACON 670 671 case obj.NAME_PARAM: 672 ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + ctxt.FixedFrameSize() 673 if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { 674 return C_SACON 675 } 676 return C_LACON 677 } 678 679 return C_GOK 680 681 consize: 682 if ctxt.Instoffset >= 0 { 683 if ctxt.Instoffset == 0 { 684 return C_ZCON 685 } 686 if ctxt.Instoffset <= 0x7fff { 687 return C_SCON 688 } 689 if ctxt.Instoffset <= 0xffff { 690 return C_ANDCON 691 } 692 if ctxt.Instoffset&0xffff == 0 && isuint32(uint64(ctxt.Instoffset)) { /* && (instoffset & (1<<31)) == 0) */ 693 return C_UCON 694 } 695 if isint32(ctxt.Instoffset) || isuint32(uint64(ctxt.Instoffset)) { 696 return C_LCON 697 } 698 return C_DCON 699 } 700 701 if ctxt.Instoffset >= -0x8000 { 702 return C_ADDCON 703 } 704 if ctxt.Instoffset&0xffff == 0 && isint32(ctxt.Instoffset) { 705 return C_UCON 706 } 707 if isint32(ctxt.Instoffset) { 708 return C_LCON 709 } 710 return C_DCON 711 712 case obj.TYPE_BRANCH: 713 if a.Sym != nil && ctxt.Flag_dynlink { 714 return C_LBRAPIC 715 } 716 return C_SBRA 717 } 718 719 return C_GOK 720 } 721 722 func prasm(p *obj.Prog) { 723 fmt.Printf("%v\n", p) 724 } 725 726 func oplook(ctxt *obj.Link, p *obj.Prog) *Optab { 727 a1 := int(p.Optab) 728 if a1 != 0 { 729 return &optab[a1-1] 730 } 731 a1 = int(p.From.Class) 732 if a1 == 0 { 733 a1 = aclass(ctxt, &p.From) + 1 734 p.From.Class = int8(a1) 735 } 736 737 a1-- 738 a3 := C_NONE + 1 739 if p.From3 != nil { 740 a3 = int(p.From3.Class) 741 if a3 == 0 { 742 a3 = aclass(ctxt, p.From3) + 1 743 p.From3.Class = int8(a3) 744 } 745 } 746 747 a3-- 748 a4 := int(p.To.Class) 749 if a4 == 0 { 750 a4 = aclass(ctxt, &p.To) + 1 751 p.To.Class = int8(a4) 752 } 753 754 a4-- 755 a2 := C_NONE 756 if p.Reg != 0 { 757 a2 = C_REG 758 } 759 760 //print("oplook %v %d %d %d %d\n", p, a1, a2, a3, a4); 761 ops := oprange[p.As&obj.AMask] 762 c1 := &xcmp[a1] 763 c3 := &xcmp[a3] 764 c4 := &xcmp[a4] 765 for i := range ops { 766 op := &ops[i] 767 if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] && c4[op.a4] { 768 p.Optab = uint16(cap(optab) - cap(ops) + i + 1) 769 return op 770 } 771 } 772 773 ctxt.Diag("illegal combination %v %v %v %v %v", obj.Aconv(p.As), DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4)) 774 prasm(p) 775 if ops == nil { 776 ops = optab 777 } 778 return &ops[0] 779 } 780 781 func cmp(a int, b int) bool { 782 if a == b { 783 return true 784 } 785 switch a { 786 case C_LCON: 787 if b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON { 788 return true 789 } 790 791 case C_ADDCON: 792 if b == C_ZCON || b == C_SCON { 793 return true 794 } 795 796 case C_ANDCON: 797 if b == C_ZCON || b == C_SCON { 798 return true 799 } 800 801 case C_SPR: 802 if b == C_LR || b == C_XER || b == C_CTR { 803 return true 804 } 805 806 case C_UCON: 807 if b == C_ZCON { 808 return true 809 } 810 811 case C_SCON: 812 if b == C_ZCON { 813 return true 814 } 815 816 case C_LACON: 817 if b == C_SACON { 818 return true 819 } 820 821 case C_LBRA: 822 if b == C_SBRA { 823 return true 824 } 825 826 case C_LEXT: 827 if b == C_SEXT { 828 return true 829 } 830 831 case C_LAUTO: 832 if b == C_SAUTO { 833 return true 834 } 835 836 case C_REG: 837 if b == C_ZCON { 838 return r0iszero != 0 /*TypeKind(100016)*/ 839 } 840 841 case C_LOREG: 842 if b == C_ZOREG || b == C_SOREG { 843 return true 844 } 845 846 case C_SOREG: 847 if b == C_ZOREG { 848 return true 849 } 850 851 case C_ANY: 852 return true 853 } 854 855 return false 856 } 857 858 type ocmp []Optab 859 860 func (x ocmp) Len() int { 861 return len(x) 862 } 863 864 func (x ocmp) Swap(i, j int) { 865 x[i], x[j] = x[j], x[i] 866 } 867 868 func (x ocmp) Less(i, j int) bool { 869 p1 := &x[i] 870 p2 := &x[j] 871 n := int(p1.as) - int(p2.as) 872 if n != 0 { 873 return n < 0 874 } 875 n = int(p1.a1) - int(p2.a1) 876 if n != 0 { 877 return n < 0 878 } 879 n = int(p1.a2) - int(p2.a2) 880 if n != 0 { 881 return n < 0 882 } 883 n = int(p1.a3) - int(p2.a3) 884 if n != 0 { 885 return n < 0 886 } 887 n = int(p1.a4) - int(p2.a4) 888 if n != 0 { 889 return n < 0 890 } 891 return false 892 } 893 func opset(a, b0 obj.As) { 894 oprange[a&obj.AMask] = oprange[b0] 895 } 896 897 func buildop(ctxt *obj.Link) { 898 var n int 899 900 for i := 0; i < C_NCLASS; i++ { 901 for n = 0; n < C_NCLASS; n++ { 902 if cmp(n, i) { 903 xcmp[i][n] = true 904 } 905 } 906 } 907 for n = 0; optab[n].as != obj.AXXX; n++ { 908 } 909 sort.Sort(ocmp(optab[:n])) 910 for i := 0; i < n; i++ { 911 r := optab[i].as 912 r0 := r & obj.AMask 913 start := i 914 for optab[i].as == r { 915 i++ 916 } 917 oprange[r0] = optab[start:i] 918 i-- 919 920 switch r { 921 default: 922 ctxt.Diag("unknown op in build: %v", obj.Aconv(r)) 923 log.Fatalf("bad code") 924 925 case ADCBF: /* unary indexed: op (b+a); op (b) */ 926 opset(ADCBI, r0) 927 928 opset(ADCBST, r0) 929 opset(ADCBT, r0) 930 opset(ADCBTST, r0) 931 opset(ADCBZ, r0) 932 opset(AICBI, r0) 933 934 case AECOWX: /* indexed store: op s,(b+a); op s,(b) */ 935 opset(ASTWCCC, r0) 936 937 opset(ASTDCCC, r0) 938 939 case AREM: /* macro */ 940 opset(AREMCC, r0) 941 942 opset(AREMV, r0) 943 opset(AREMVCC, r0) 944 945 case AREMU: 946 opset(AREMU, r0) 947 opset(AREMUCC, r0) 948 opset(AREMUV, r0) 949 opset(AREMUVCC, r0) 950 951 case AREMD: 952 opset(AREMDCC, r0) 953 opset(AREMDV, r0) 954 opset(AREMDVCC, r0) 955 956 case AREMDU: 957 opset(AREMDU, r0) 958 opset(AREMDUCC, r0) 959 opset(AREMDUV, r0) 960 opset(AREMDUVCC, r0) 961 962 case ADIVW: /* op Rb[,Ra],Rd */ 963 opset(AMULHW, r0) 964 965 opset(AMULHWCC, r0) 966 opset(AMULHWU, r0) 967 opset(AMULHWUCC, r0) 968 opset(AMULLWCC, r0) 969 opset(AMULLWVCC, r0) 970 opset(AMULLWV, r0) 971 opset(ADIVWCC, r0) 972 opset(ADIVWV, r0) 973 opset(ADIVWVCC, r0) 974 opset(ADIVWU, r0) 975 opset(ADIVWUCC, r0) 976 opset(ADIVWUV, r0) 977 opset(ADIVWUVCC, r0) 978 opset(AADDCC, r0) 979 opset(AADDCV, r0) 980 opset(AADDCVCC, r0) 981 opset(AADDV, r0) 982 opset(AADDVCC, r0) 983 opset(AADDE, r0) 984 opset(AADDECC, r0) 985 opset(AADDEV, r0) 986 opset(AADDEVCC, r0) 987 opset(ACRAND, r0) 988 opset(ACRANDN, r0) 989 opset(ACREQV, r0) 990 opset(ACRNAND, r0) 991 opset(ACRNOR, r0) 992 opset(ACROR, r0) 993 opset(ACRORN, r0) 994 opset(ACRXOR, r0) 995 opset(AMULHD, r0) 996 opset(AMULHDCC, r0) 997 opset(AMULHDU, r0) 998 opset(AMULHDUCC, r0) 999 opset(AMULLD, r0) 1000 opset(AMULLDCC, r0) 1001 opset(AMULLDVCC, r0) 1002 opset(AMULLDV, r0) 1003 opset(ADIVD, r0) 1004 opset(ADIVDCC, r0) 1005 opset(ADIVDVCC, r0) 1006 opset(ADIVDV, r0) 1007 opset(ADIVDU, r0) 1008 opset(ADIVDUCC, r0) 1009 opset(ADIVDUVCC, r0) 1010 opset(ADIVDUCC, r0) 1011 1012 case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */ 1013 opset(AMOVH, r0) 1014 1015 opset(AMOVHZ, r0) 1016 1017 case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */ 1018 opset(AMOVHU, r0) 1019 1020 opset(AMOVHZU, r0) 1021 opset(AMOVWU, r0) 1022 opset(AMOVWZU, r0) 1023 opset(AMOVDU, r0) 1024 opset(AMOVMW, r0) 1025 1026 case AAND: /* logical op Rb,Rs,Ra; no literal */ 1027 opset(AANDN, r0) 1028 1029 opset(AANDNCC, r0) 1030 opset(AEQV, r0) 1031 opset(AEQVCC, r0) 1032 opset(ANAND, r0) 1033 opset(ANANDCC, r0) 1034 opset(ANOR, r0) 1035 opset(ANORCC, r0) 1036 opset(AORCC, r0) 1037 opset(AORN, r0) 1038 opset(AORNCC, r0) 1039 opset(AXORCC, r0) 1040 1041 case AADDME: /* op Ra, Rd */ 1042 opset(AADDMECC, r0) 1043 1044 opset(AADDMEV, r0) 1045 opset(AADDMEVCC, r0) 1046 opset(AADDZE, r0) 1047 opset(AADDZECC, r0) 1048 opset(AADDZEV, r0) 1049 opset(AADDZEVCC, r0) 1050 opset(ASUBME, r0) 1051 opset(ASUBMECC, r0) 1052 opset(ASUBMEV, r0) 1053 opset(ASUBMEVCC, r0) 1054 opset(ASUBZE, r0) 1055 opset(ASUBZECC, r0) 1056 opset(ASUBZEV, r0) 1057 opset(ASUBZEVCC, r0) 1058 1059 case AADDC: 1060 opset(AADDCCC, r0) 1061 1062 case ABEQ: 1063 opset(ABGE, r0) 1064 opset(ABGT, r0) 1065 opset(ABLE, r0) 1066 opset(ABLT, r0) 1067 opset(ABNE, r0) 1068 opset(ABVC, r0) 1069 opset(ABVS, r0) 1070 1071 case ABR: 1072 opset(ABL, r0) 1073 1074 case ABC: 1075 opset(ABCL, r0) 1076 1077 case AEXTSB: /* op Rs, Ra */ 1078 opset(AEXTSBCC, r0) 1079 1080 opset(AEXTSH, r0) 1081 opset(AEXTSHCC, r0) 1082 opset(ACNTLZW, r0) 1083 opset(ACNTLZWCC, r0) 1084 opset(ACNTLZD, r0) 1085 opset(AEXTSW, r0) 1086 opset(AEXTSWCC, r0) 1087 opset(ACNTLZDCC, r0) 1088 1089 case AFABS: /* fop [s,]d */ 1090 opset(AFABSCC, r0) 1091 1092 opset(AFNABS, r0) 1093 opset(AFNABSCC, r0) 1094 opset(AFNEG, r0) 1095 opset(AFNEGCC, r0) 1096 opset(AFRSP, r0) 1097 opset(AFRSPCC, r0) 1098 opset(AFCTIW, r0) 1099 opset(AFCTIWCC, r0) 1100 opset(AFCTIWZ, r0) 1101 opset(AFCTIWZCC, r0) 1102 opset(AFCTID, r0) 1103 opset(AFCTIDCC, r0) 1104 opset(AFCTIDZ, r0) 1105 opset(AFCTIDZCC, r0) 1106 opset(AFCFID, r0) 1107 opset(AFCFIDCC, r0) 1108 opset(AFRES, r0) 1109 opset(AFRESCC, r0) 1110 opset(AFRSQRTE, r0) 1111 opset(AFRSQRTECC, r0) 1112 opset(AFSQRT, r0) 1113 opset(AFSQRTCC, r0) 1114 opset(AFSQRTS, r0) 1115 opset(AFSQRTSCC, r0) 1116 1117 case AFADD: 1118 opset(AFADDS, r0) 1119 opset(AFADDCC, r0) 1120 opset(AFADDSCC, r0) 1121 opset(AFDIV, r0) 1122 opset(AFDIVS, r0) 1123 opset(AFDIVCC, r0) 1124 opset(AFDIVSCC, r0) 1125 opset(AFSUB, r0) 1126 opset(AFSUBS, r0) 1127 opset(AFSUBCC, r0) 1128 opset(AFSUBSCC, r0) 1129 1130 case AFMADD: 1131 opset(AFMADDCC, r0) 1132 opset(AFMADDS, r0) 1133 opset(AFMADDSCC, r0) 1134 opset(AFMSUB, r0) 1135 opset(AFMSUBCC, r0) 1136 opset(AFMSUBS, r0) 1137 opset(AFMSUBSCC, r0) 1138 opset(AFNMADD, r0) 1139 opset(AFNMADDCC, r0) 1140 opset(AFNMADDS, r0) 1141 opset(AFNMADDSCC, r0) 1142 opset(AFNMSUB, r0) 1143 opset(AFNMSUBCC, r0) 1144 opset(AFNMSUBS, r0) 1145 opset(AFNMSUBSCC, r0) 1146 opset(AFSEL, r0) 1147 opset(AFSELCC, r0) 1148 1149 case AFMUL: 1150 opset(AFMULS, r0) 1151 opset(AFMULCC, r0) 1152 opset(AFMULSCC, r0) 1153 1154 case AFCMPO: 1155 opset(AFCMPU, r0) 1156 1157 case AMTFSB0: 1158 opset(AMTFSB0CC, r0) 1159 opset(AMTFSB1, r0) 1160 opset(AMTFSB1CC, r0) 1161 1162 case ANEG: /* op [Ra,] Rd */ 1163 opset(ANEGCC, r0) 1164 1165 opset(ANEGV, r0) 1166 opset(ANEGVCC, r0) 1167 1168 case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */ 1169 opset(AXOR, r0) 1170 1171 case ASLW: 1172 opset(ASLWCC, r0) 1173 opset(ASRW, r0) 1174 opset(ASRWCC, r0) 1175 1176 case ASLD: 1177 opset(ASLDCC, r0) 1178 opset(ASRD, r0) 1179 opset(ASRDCC, r0) 1180 1181 case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */ 1182 opset(ASRAWCC, r0) 1183 1184 case ASRAD: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */ 1185 opset(ASRADCC, r0) 1186 1187 case ASUB: /* SUB Ra,Rb,Rd => subf Rd,ra,rb */ 1188 opset(ASUB, r0) 1189 1190 opset(ASUBCC, r0) 1191 opset(ASUBV, r0) 1192 opset(ASUBVCC, r0) 1193 opset(ASUBCCC, r0) 1194 opset(ASUBCV, r0) 1195 opset(ASUBCVCC, r0) 1196 opset(ASUBE, r0) 1197 opset(ASUBECC, r0) 1198 opset(ASUBEV, r0) 1199 opset(ASUBEVCC, r0) 1200 1201 case ASYNC: 1202 opset(AISYNC, r0) 1203 opset(APTESYNC, r0) 1204 opset(ATLBSYNC, r0) 1205 1206 case ARLWMI: 1207 opset(ARLWMICC, r0) 1208 opset(ARLWNM, r0) 1209 opset(ARLWNMCC, r0) 1210 1211 case ARLDMI: 1212 opset(ARLDMICC, r0) 1213 1214 case ARLDC: 1215 opset(ARLDCCC, r0) 1216 1217 case ARLDCL: 1218 opset(ARLDCR, r0) 1219 opset(ARLDCLCC, r0) 1220 opset(ARLDCRCC, r0) 1221 1222 case AFMOVD: 1223 opset(AFMOVDCC, r0) 1224 opset(AFMOVDU, r0) 1225 opset(AFMOVS, r0) 1226 opset(AFMOVSU, r0) 1227 1228 case AECIWX: 1229 opset(ALWAR, r0) 1230 opset(ALDAR, r0) 1231 1232 case ASYSCALL: /* just the op; flow of control */ 1233 opset(ARFI, r0) 1234 1235 opset(ARFCI, r0) 1236 opset(ARFID, r0) 1237 opset(AHRFID, r0) 1238 1239 case AMOVHBR: 1240 opset(AMOVWBR, r0) 1241 1242 case ASLBMFEE: 1243 opset(ASLBMFEV, r0) 1244 1245 case ATW: 1246 opset(ATD, r0) 1247 1248 case ATLBIE: 1249 opset(ASLBIE, r0) 1250 opset(ATLBIEL, r0) 1251 1252 case AEIEIO: 1253 opset(ASLBIA, r0) 1254 1255 case ACMP: 1256 opset(ACMPW, r0) 1257 1258 case ACMPU: 1259 opset(ACMPWU, r0) 1260 1261 case AADD, 1262 AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */ 1263 ALSW, 1264 AMOVW, 1265 /* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */ 1266 AMOVWZ, /* load/store/move word with zero extension; move 32-bit literals */ 1267 AMOVD, /* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */ 1268 AMOVB, /* macro: move byte with sign extension */ 1269 AMOVBU, /* macro: move byte with sign extension & update */ 1270 AMOVFL, 1271 AMULLW, 1272 /* op $s[,r2],r3; op r1[,r2],r3; no cc/v */ 1273 ASUBC, /* op r1,$s,r3; op r1[,r2],r3 */ 1274 ASTSW, 1275 ASLBMTE, 1276 AWORD, 1277 ADWORD, 1278 obj.ANOP, 1279 obj.ATEXT, 1280 obj.AUNDEF, 1281 obj.AUSEFIELD, 1282 obj.AFUNCDATA, 1283 obj.APCDATA, 1284 obj.ADUFFZERO, 1285 obj.ADUFFCOPY: 1286 break 1287 } 1288 } 1289 } 1290 1291 func OPVCC(o uint32, xo uint32, oe uint32, rc uint32) uint32 { 1292 return o<<26 | xo<<1 | oe<<10 | rc&1 1293 } 1294 1295 func OPCC(o uint32, xo uint32, rc uint32) uint32 { 1296 return OPVCC(o, xo, 0, rc) 1297 } 1298 1299 func OP(o uint32, xo uint32) uint32 { 1300 return OPVCC(o, xo, 0, 0) 1301 } 1302 1303 /* the order is dest, a/s, b/imm for both arithmetic and logical operations */ 1304 func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 { 1305 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 1306 } 1307 1308 func AOP_IRR(op uint32, d uint32, a uint32, simm uint32) uint32 { 1309 return op | (d&31)<<21 | (a&31)<<16 | simm&0xFFFF 1310 } 1311 1312 func LOP_RRR(op uint32, a uint32, s uint32, b uint32) uint32 { 1313 return op | (s&31)<<21 | (a&31)<<16 | (b&31)<<11 1314 } 1315 1316 func LOP_IRR(op uint32, a uint32, s uint32, uimm uint32) uint32 { 1317 return op | (s&31)<<21 | (a&31)<<16 | uimm&0xFFFF 1318 } 1319 1320 func OP_BR(op uint32, li uint32, aa uint32) uint32 { 1321 return op | li&0x03FFFFFC | aa<<1 1322 } 1323 1324 func OP_BC(op uint32, bo uint32, bi uint32, bd uint32, aa uint32) uint32 { 1325 return op | (bo&0x1F)<<21 | (bi&0x1F)<<16 | bd&0xFFFC | aa<<1 1326 } 1327 1328 func OP_BCR(op uint32, bo uint32, bi uint32) uint32 { 1329 return op | (bo&0x1F)<<21 | (bi&0x1F)<<16 1330 } 1331 1332 func OP_RLW(op uint32, a uint32, s uint32, sh uint32, mb uint32, me uint32) uint32 { 1333 return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | (mb&31)<<6 | (me&31)<<1 1334 } 1335 1336 const ( 1337 /* each rhs is OPVCC(_, _, _, _) */ 1338 OP_ADD = 31<<26 | 266<<1 | 0<<10 | 0 1339 OP_ADDI = 14<<26 | 0<<1 | 0<<10 | 0 1340 OP_ADDIS = 15<<26 | 0<<1 | 0<<10 | 0 1341 OP_ANDI = 28<<26 | 0<<1 | 0<<10 | 0 1342 OP_EXTSB = 31<<26 | 954<<1 | 0<<10 | 0 1343 OP_EXTSH = 31<<26 | 922<<1 | 0<<10 | 0 1344 OP_EXTSW = 31<<26 | 986<<1 | 0<<10 | 0 1345 OP_MCRF = 19<<26 | 0<<1 | 0<<10 | 0 1346 OP_MCRFS = 63<<26 | 64<<1 | 0<<10 | 0 1347 OP_MCRXR = 31<<26 | 512<<1 | 0<<10 | 0 1348 OP_MFCR = 31<<26 | 19<<1 | 0<<10 | 0 1349 OP_MFFS = 63<<26 | 583<<1 | 0<<10 | 0 1350 OP_MFMSR = 31<<26 | 83<<1 | 0<<10 | 0 1351 OP_MFSPR = 31<<26 | 339<<1 | 0<<10 | 0 1352 OP_MFSR = 31<<26 | 595<<1 | 0<<10 | 0 1353 OP_MFSRIN = 31<<26 | 659<<1 | 0<<10 | 0 1354 OP_MTCRF = 31<<26 | 144<<1 | 0<<10 | 0 1355 OP_MTFSF = 63<<26 | 711<<1 | 0<<10 | 0 1356 OP_MTFSFI = 63<<26 | 134<<1 | 0<<10 | 0 1357 OP_MTMSR = 31<<26 | 146<<1 | 0<<10 | 0 1358 OP_MTMSRD = 31<<26 | 178<<1 | 0<<10 | 0 1359 OP_MTSPR = 31<<26 | 467<<1 | 0<<10 | 0 1360 OP_MTSR = 31<<26 | 210<<1 | 0<<10 | 0 1361 OP_MTSRIN = 31<<26 | 242<<1 | 0<<10 | 0 1362 OP_MULLW = 31<<26 | 235<<1 | 0<<10 | 0 1363 OP_MULLD = 31<<26 | 233<<1 | 0<<10 | 0 1364 OP_OR = 31<<26 | 444<<1 | 0<<10 | 0 1365 OP_ORI = 24<<26 | 0<<1 | 0<<10 | 0 1366 OP_ORIS = 25<<26 | 0<<1 | 0<<10 | 0 1367 OP_RLWINM = 21<<26 | 0<<1 | 0<<10 | 0 1368 OP_SUBF = 31<<26 | 40<<1 | 0<<10 | 0 1369 OP_RLDIC = 30<<26 | 4<<1 | 0<<10 | 0 1370 OP_RLDICR = 30<<26 | 2<<1 | 0<<10 | 0 1371 OP_RLDICL = 30<<26 | 0<<1 | 0<<10 | 0 1372 ) 1373 1374 func oclass(a *obj.Addr) int { 1375 return int(a.Class) - 1 1376 } 1377 1378 const ( 1379 D_FORM = iota 1380 DS_FORM 1381 ) 1382 1383 // opform returns the form (D_FORM or DS_FORM) of an instruction. Used to decide on 1384 // which relocation to use with a load or store and only supports the needed 1385 // instructions. 1386 func opform(ctxt *obj.Link, insn uint32) int { 1387 switch uint32(insn) { 1388 default: 1389 ctxt.Diag("bad insn in loadform: %x", insn) 1390 case OPVCC(58, 0, 0, 0), // ld 1391 OPVCC(58, 0, 0, 0) | 1<<1, // lwa 1392 OPVCC(62, 0, 0, 0): // std 1393 return DS_FORM 1394 case OP_ADDI, // add 1395 OPVCC(32, 0, 0, 0), // lwz 1396 OPVCC(42, 0, 0, 0), // lha 1397 OPVCC(40, 0, 0, 0), // lhz 1398 OPVCC(34, 0, 0, 0), // lbz 1399 OPVCC(50, 0, 0, 0), // lfd 1400 OPVCC(48, 0, 0, 0), // lfs 1401 OPVCC(36, 0, 0, 0), // stw 1402 OPVCC(44, 0, 0, 0), // sth 1403 OPVCC(38, 0, 0, 0), // stb 1404 OPVCC(54, 0, 0, 0), // stfd 1405 OPVCC(52, 0, 0, 0): // stfs 1406 return D_FORM 1407 } 1408 return 0 1409 } 1410 1411 // Encode instructions and create relocation for accessing s+d according to the 1412 // instruction op with source or destination (as appropriate) register reg. 1413 func symbolAccess(ctxt *obj.Link, s *obj.LSym, d int64, reg int16, op uint32) (o1, o2 uint32) { 1414 var base uint32 1415 form := opform(ctxt, op) 1416 if ctxt.Flag_shared != 0 { 1417 base = REG_R2 1418 } else { 1419 base = REG_R0 1420 } 1421 o1 = AOP_IRR(OP_ADDIS, REGTMP, base, 0) 1422 o2 = AOP_IRR(op, uint32(reg), REGTMP, 0) 1423 rel := obj.Addrel(ctxt.Cursym) 1424 rel.Off = int32(ctxt.Pc) 1425 rel.Siz = 8 1426 rel.Sym = s 1427 rel.Add = d 1428 if ctxt.Flag_shared != 0 { 1429 switch form { 1430 case D_FORM: 1431 rel.Type = obj.R_ADDRPOWER_TOCREL 1432 case DS_FORM: 1433 rel.Type = obj.R_ADDRPOWER_TOCREL_DS 1434 } 1435 1436 } else { 1437 switch form { 1438 case D_FORM: 1439 rel.Type = obj.R_ADDRPOWER 1440 case DS_FORM: 1441 rel.Type = obj.R_ADDRPOWER_DS 1442 } 1443 } 1444 return 1445 } 1446 1447 /* 1448 * 32-bit masks 1449 */ 1450 func getmask(m []byte, v uint32) bool { 1451 m[1] = 0 1452 m[0] = m[1] 1453 if v != ^uint32(0) && v&(1<<31) != 0 && v&1 != 0 { /* MB > ME */ 1454 if getmask(m, ^v) { 1455 i := int(m[0]) 1456 m[0] = m[1] + 1 1457 m[1] = byte(i - 1) 1458 return true 1459 } 1460 1461 return false 1462 } 1463 1464 for i := 0; i < 32; i++ { 1465 if v&(1<<uint(31-i)) != 0 { 1466 m[0] = byte(i) 1467 for { 1468 m[1] = byte(i) 1469 i++ 1470 if i >= 32 || v&(1<<uint(31-i)) == 0 { 1471 break 1472 } 1473 } 1474 1475 for ; i < 32; i++ { 1476 if v&(1<<uint(31-i)) != 0 { 1477 return false 1478 } 1479 } 1480 return true 1481 } 1482 } 1483 1484 return false 1485 } 1486 1487 func maskgen(ctxt *obj.Link, p *obj.Prog, m []byte, v uint32) { 1488 if !getmask(m, v) { 1489 ctxt.Diag("cannot generate mask #%x\n%v", v, p) 1490 } 1491 } 1492 1493 /* 1494 * 64-bit masks (rldic etc) 1495 */ 1496 func getmask64(m []byte, v uint64) bool { 1497 m[1] = 0 1498 m[0] = m[1] 1499 for i := 0; i < 64; i++ { 1500 if v&(uint64(1)<<uint(63-i)) != 0 { 1501 m[0] = byte(i) 1502 for { 1503 m[1] = byte(i) 1504 i++ 1505 if i >= 64 || v&(uint64(1)<<uint(63-i)) == 0 { 1506 break 1507 } 1508 } 1509 1510 for ; i < 64; i++ { 1511 if v&(uint64(1)<<uint(63-i)) != 0 { 1512 return false 1513 } 1514 } 1515 return true 1516 } 1517 } 1518 1519 return false 1520 } 1521 1522 func maskgen64(ctxt *obj.Link, p *obj.Prog, m []byte, v uint64) { 1523 if !getmask64(m, v) { 1524 ctxt.Diag("cannot generate mask #%x\n%v", v, p) 1525 } 1526 } 1527 1528 func loadu32(r int, d int64) uint32 { 1529 v := int32(d >> 16) 1530 if isuint32(uint64(d)) { 1531 return LOP_IRR(OP_ORIS, uint32(r), REGZERO, uint32(v)) 1532 } 1533 return AOP_IRR(OP_ADDIS, uint32(r), REGZERO, uint32(v)) 1534 } 1535 1536 func high16adjusted(d int32) uint16 { 1537 if d&0x8000 != 0 { 1538 return uint16((d >> 16) + 1) 1539 } 1540 return uint16(d >> 16) 1541 } 1542 1543 func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { 1544 o1 := uint32(0) 1545 o2 := uint32(0) 1546 o3 := uint32(0) 1547 o4 := uint32(0) 1548 o5 := uint32(0) 1549 1550 //print("%v => case %d\n", p, o->type); 1551 switch o.type_ { 1552 default: 1553 ctxt.Diag("unknown type %d", o.type_) 1554 prasm(p) 1555 1556 case 0: /* pseudo ops */ 1557 break 1558 1559 case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */ 1560 if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST { 1561 v := regoff(ctxt, &p.From) 1562 if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 { 1563 //nerrors--; 1564 ctxt.Diag("literal operation on R0\n%v", p) 1565 } 1566 1567 o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v)) 1568 break 1569 } 1570 1571 o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg)) 1572 1573 case 2: /* int/cr/fp op Rb,[Ra],Rd */ 1574 r := int(p.Reg) 1575 1576 if r == 0 { 1577 r = int(p.To.Reg) 1578 } 1579 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg)) 1580 1581 case 3: /* mov $soreg/addcon/ucon, r ==> addis/addi $i,reg',r */ 1582 d := vregoff(ctxt, &p.From) 1583 1584 v := int32(d) 1585 r := int(p.From.Reg) 1586 if r == 0 { 1587 r = int(o.param) 1588 } 1589 if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) { 1590 ctxt.Diag("literal operation on R0\n%v", p) 1591 } 1592 a := OP_ADDI 1593 if o.a1 == C_UCON { 1594 if d&0xffff != 0 { 1595 log.Fatalf("invalid handling of %v", p) 1596 } 1597 v >>= 16 1598 if r == REGZERO && isuint32(uint64(d)) { 1599 o1 = LOP_IRR(OP_ORIS, uint32(p.To.Reg), REGZERO, uint32(v)) 1600 break 1601 } 1602 1603 a = OP_ADDIS 1604 } else { 1605 if int64(int16(d)) != d { 1606 log.Fatalf("invalid handling of %v", p) 1607 } 1608 } 1609 1610 o1 = AOP_IRR(uint32(a), uint32(p.To.Reg), uint32(r), uint32(v)) 1611 1612 case 4: /* add/mul $scon,[r1],r2 */ 1613 v := regoff(ctxt, &p.From) 1614 1615 r := int(p.Reg) 1616 if r == 0 { 1617 r = int(p.To.Reg) 1618 } 1619 if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 { 1620 ctxt.Diag("literal operation on R0\n%v", p) 1621 } 1622 if int32(int16(v)) != v { 1623 log.Fatalf("mishandled instruction %v", p) 1624 } 1625 o1 = AOP_IRR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v)) 1626 1627 case 5: /* syscall */ 1628 o1 = oprrr(ctxt, p.As) 1629 1630 case 6: /* logical op Rb,[Rs,]Ra; no literal */ 1631 r := int(p.Reg) 1632 1633 if r == 0 { 1634 r = int(p.To.Reg) 1635 } 1636 o1 = LOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg)) 1637 1638 case 7: /* mov r, soreg ==> stw o(r) */ 1639 r := int(p.To.Reg) 1640 1641 if r == 0 { 1642 r = int(o.param) 1643 } 1644 v := regoff(ctxt, &p.To) 1645 if p.To.Type == obj.TYPE_MEM && p.To.Index != 0 { 1646 if v != 0 { 1647 ctxt.Diag("illegal indexed instruction\n%v", p) 1648 } 1649 if ctxt.Flag_shared != 0 && r == REG_R13 { 1650 rel := obj.Addrel(ctxt.Cursym) 1651 rel.Off = int32(ctxt.Pc) 1652 rel.Siz = 4 1653 // This (and the matching part in the load case 1654 // below) are the only places in the ppc64 toolchain 1655 // that knows the name of the tls variable. Possibly 1656 // we could add some assembly syntax so that the name 1657 // of the variable does not have to be assumed. 1658 rel.Sym = obj.Linklookup(ctxt, "runtime.tls_g", 0) 1659 rel.Type = obj.R_POWER_TLS 1660 } 1661 o1 = AOP_RRR(opstorex(ctxt, p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r)) 1662 } else { 1663 if int32(int16(v)) != v { 1664 log.Fatalf("mishandled instruction %v", p) 1665 } 1666 o1 = AOP_IRR(opstore(ctxt, p.As), uint32(p.From.Reg), uint32(r), uint32(v)) 1667 } 1668 1669 case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */ 1670 r := int(p.From.Reg) 1671 1672 if r == 0 { 1673 r = int(o.param) 1674 } 1675 v := regoff(ctxt, &p.From) 1676 if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 { 1677 if v != 0 { 1678 ctxt.Diag("illegal indexed instruction\n%v", p) 1679 } 1680 if ctxt.Flag_shared != 0 && r == REG_R13 { 1681 rel := obj.Addrel(ctxt.Cursym) 1682 rel.Off = int32(ctxt.Pc) 1683 rel.Siz = 4 1684 rel.Sym = obj.Linklookup(ctxt, "runtime.tls_g", 0) 1685 rel.Type = obj.R_POWER_TLS 1686 } 1687 o1 = AOP_RRR(oploadx(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r)) 1688 } else { 1689 if int32(int16(v)) != v { 1690 log.Fatalf("mishandled instruction %v", p) 1691 } 1692 o1 = AOP_IRR(opload(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v)) 1693 } 1694 1695 case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */ 1696 r := int(p.From.Reg) 1697 1698 if r == 0 { 1699 r = int(o.param) 1700 } 1701 v := regoff(ctxt, &p.From) 1702 if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 { 1703 if v != 0 { 1704 ctxt.Diag("illegal indexed instruction\n%v", p) 1705 } 1706 o1 = AOP_RRR(oploadx(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r)) 1707 } else { 1708 o1 = AOP_IRR(opload(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v)) 1709 } 1710 o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0) 1711 1712 case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */ 1713 r := int(p.Reg) 1714 1715 if r == 0 { 1716 r = int(p.To.Reg) 1717 } 1718 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r)) 1719 1720 case 11: /* br/bl lbra */ 1721 v := int32(0) 1722 1723 if p.Pcond != nil { 1724 v = int32(p.Pcond.Pc - p.Pc) 1725 if v&03 != 0 { 1726 ctxt.Diag("odd branch target address\n%v", p) 1727 v &^= 03 1728 } 1729 1730 if v < -(1<<25) || v >= 1<<24 { 1731 ctxt.Diag("branch too far\n%v", p) 1732 } 1733 } 1734 1735 o1 = OP_BR(opirr(ctxt, p.As), uint32(v), 0) 1736 if p.To.Sym != nil { 1737 rel := obj.Addrel(ctxt.Cursym) 1738 rel.Off = int32(ctxt.Pc) 1739 rel.Siz = 4 1740 rel.Sym = p.To.Sym 1741 v += int32(p.To.Offset) 1742 if v&03 != 0 { 1743 ctxt.Diag("odd branch target address\n%v", p) 1744 v &^= 03 1745 } 1746 1747 rel.Add = int64(v) 1748 rel.Type = obj.R_CALLPOWER 1749 } 1750 o2 = 0x60000000 // nop, sometimes overwritten by ld r2, 24(r1) when dynamic linking 1751 1752 case 12: /* movb r,r (extsb); movw r,r (extsw) */ 1753 if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST { 1754 v := regoff(ctxt, &p.From) 1755 if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 { 1756 ctxt.Diag("literal operation on R0\n%v", p) 1757 } 1758 1759 o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v)) 1760 break 1761 } 1762 1763 if p.As == AMOVW { 1764 o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0) 1765 } else { 1766 o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0) 1767 } 1768 1769 case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */ 1770 if p.As == AMOVBZ { 1771 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31) 1772 } else if p.As == AMOVH { 1773 o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0) 1774 } else if p.As == AMOVHZ { 1775 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 16, 31) 1776 } else if p.As == AMOVWZ { 1777 o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */ 1778 } else { 1779 ctxt.Diag("internal: bad mov[bhw]z\n%v", p) 1780 } 1781 1782 case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */ 1783 r := int(p.Reg) 1784 1785 if r == 0 { 1786 r = int(p.To.Reg) 1787 } 1788 d := vregoff(ctxt, p.From3) 1789 var mask [2]uint8 1790 maskgen64(ctxt, p, mask[:], uint64(d)) 1791 var a int 1792 switch p.As { 1793 case ARLDCL, ARLDCLCC: 1794 a = int(mask[0]) /* MB */ 1795 if mask[1] != 63 { 1796 ctxt.Diag("invalid mask for rotate: %x (end != bit 63)\n%v", uint64(d), p) 1797 } 1798 1799 case ARLDCR, ARLDCRCC: 1800 a = int(mask[1]) /* ME */ 1801 if mask[0] != 0 { 1802 ctxt.Diag("invalid mask for rotate: %x (start != 0)\n%v", uint64(d), p) 1803 } 1804 1805 default: 1806 ctxt.Diag("unexpected op in rldc case\n%v", p) 1807 a = 0 1808 } 1809 1810 o1 = LOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg)) 1811 o1 |= (uint32(a) & 31) << 6 1812 if a&0x20 != 0 { 1813 o1 |= 1 << 5 /* mb[5] is top bit */ 1814 } 1815 1816 case 17, /* bc bo,bi,lbra (same for now) */ 1817 16: /* bc bo,bi,sbra */ 1818 a := 0 1819 1820 if p.From.Type == obj.TYPE_CONST { 1821 a = int(regoff(ctxt, &p.From)) 1822 } 1823 r := int(p.Reg) 1824 if r == 0 { 1825 r = 0 1826 } 1827 v := int32(0) 1828 if p.Pcond != nil { 1829 v = int32(p.Pcond.Pc - p.Pc) 1830 } 1831 if v&03 != 0 { 1832 ctxt.Diag("odd branch target address\n%v", p) 1833 v &^= 03 1834 } 1835 1836 if v < -(1<<16) || v >= 1<<15 { 1837 ctxt.Diag("branch too far\n%v", p) 1838 } 1839 o1 = OP_BC(opirr(ctxt, p.As), uint32(a), uint32(r), uint32(v), 0) 1840 1841 case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */ 1842 var v int32 1843 if p.As == ABC || p.As == ABCL { 1844 v = regoff(ctxt, &p.To) & 31 1845 } else { 1846 v = 20 /* unconditional */ 1847 } 1848 o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (REG_LR&0x1f)<<16 | ((REG_LR>>5)&0x1f)<<11 1849 o2 = OPVCC(19, 16, 0, 0) 1850 if p.As == ABL || p.As == ABCL { 1851 o2 |= 1 1852 } 1853 o2 = OP_BCR(o2, uint32(v), uint32(p.To.Index)) 1854 1855 case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */ 1856 var v int32 1857 if p.As == ABC || p.As == ABCL { 1858 v = regoff(ctxt, &p.From) & 31 1859 } else { 1860 v = 20 /* unconditional */ 1861 } 1862 r := int(p.Reg) 1863 if r == 0 { 1864 r = 0 1865 } 1866 switch oclass(&p.To) { 1867 case C_CTR: 1868 o1 = OPVCC(19, 528, 0, 0) 1869 1870 case C_LR: 1871 o1 = OPVCC(19, 16, 0, 0) 1872 1873 default: 1874 ctxt.Diag("bad optab entry (18): %d\n%v", p.To.Class, p) 1875 v = 0 1876 } 1877 1878 if p.As == ABL || p.As == ABCL { 1879 o1 |= 1 1880 } 1881 o1 = OP_BCR(o1, uint32(v), uint32(r)) 1882 1883 case 19: /* mov $lcon,r ==> cau+or */ 1884 d := vregoff(ctxt, &p.From) 1885 1886 if p.From.Sym == nil { 1887 o1 = loadu32(int(p.To.Reg), d) 1888 o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d))) 1889 } else { 1890 o1, o2 = symbolAccess(ctxt, p.From.Sym, d, p.To.Reg, OP_ADDI) 1891 } 1892 1893 //if(dlm) reloc(&p->from, p->pc, 0); 1894 1895 case 20: /* add $ucon,,r */ 1896 v := regoff(ctxt, &p.From) 1897 1898 r := int(p.Reg) 1899 if r == 0 { 1900 r = int(p.To.Reg) 1901 } 1902 if p.As == AADD && (r0iszero == 0 /*TypeKind(100016)*/ && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) { 1903 ctxt.Diag("literal operation on R0\n%v", p) 1904 } 1905 o1 = AOP_IRR(opirr(ctxt, -p.As), uint32(p.To.Reg), uint32(r), uint32(v)>>16) 1906 1907 case 22: /* add $lcon,r1,r2 ==> cau+or+add */ /* could do add/sub more efficiently */ 1908 if p.To.Reg == REGTMP || p.Reg == REGTMP { 1909 ctxt.Diag("can't synthesize large constant\n%v", p) 1910 } 1911 d := vregoff(ctxt, &p.From) 1912 o1 = loadu32(REGTMP, d) 1913 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d))) 1914 r := int(p.Reg) 1915 if r == 0 { 1916 r = int(p.To.Reg) 1917 } 1918 o3 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), REGTMP, uint32(r)) 1919 if p.From.Sym != nil { 1920 ctxt.Diag("%v is not supported", p) 1921 } 1922 1923 //if(dlm) reloc(&p->from, p->pc, 0); 1924 1925 case 23: /* and $lcon,r1,r2 ==> cau+or+and */ /* masks could be done using rlnm etc. */ 1926 if p.To.Reg == REGTMP || p.Reg == REGTMP { 1927 ctxt.Diag("can't synthesize large constant\n%v", p) 1928 } 1929 d := vregoff(ctxt, &p.From) 1930 o1 = loadu32(REGTMP, d) 1931 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d))) 1932 r := int(p.Reg) 1933 if r == 0 { 1934 r = int(p.To.Reg) 1935 } 1936 o3 = LOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), REGTMP, uint32(r)) 1937 if p.From.Sym != nil { 1938 ctxt.Diag("%v is not supported", p) 1939 } 1940 1941 //if(dlm) reloc(&p->from, p->pc, 0); 1942 1943 /*24*/ 1944 case 25: 1945 /* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */ 1946 v := regoff(ctxt, &p.From) 1947 1948 if v < 0 { 1949 v = 0 1950 } else if v > 63 { 1951 v = 63 1952 } 1953 r := int(p.Reg) 1954 if r == 0 { 1955 r = int(p.To.Reg) 1956 } 1957 var a int 1958 switch p.As { 1959 case ASLD, ASLDCC: 1960 a = int(63 - v) 1961 o1 = OP_RLDICR 1962 1963 case ASRD, ASRDCC: 1964 a = int(v) 1965 v = 64 - v 1966 o1 = OP_RLDICL 1967 1968 default: 1969 ctxt.Diag("unexpected op in sldi case\n%v", p) 1970 a = 0 1971 o1 = 0 1972 } 1973 1974 o1 = AOP_RRR(o1, uint32(r), uint32(p.To.Reg), (uint32(v) & 0x1F)) 1975 o1 |= (uint32(a) & 31) << 6 1976 if v&0x20 != 0 { 1977 o1 |= 1 << 1 1978 } 1979 if a&0x20 != 0 { 1980 o1 |= 1 << 5 /* mb[5] is top bit */ 1981 } 1982 if p.As == ASLDCC || p.As == ASRDCC { 1983 o1 |= 1 /* Rc */ 1984 } 1985 1986 case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */ 1987 if p.To.Reg == REGTMP { 1988 ctxt.Diag("can't synthesize large constant\n%v", p) 1989 } 1990 v := regoff(ctxt, &p.From) 1991 r := int(p.From.Reg) 1992 if r == 0 { 1993 r = int(o.param) 1994 } 1995 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v))) 1996 o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(v)) 1997 1998 case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */ 1999 v := regoff(ctxt, p.From3) 2000 2001 r := int(p.From.Reg) 2002 o1 = AOP_IRR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v)) 2003 2004 case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */ 2005 if p.To.Reg == REGTMP || p.From.Reg == REGTMP { 2006 ctxt.Diag("can't synthesize large constant\n%v", p) 2007 } 2008 v := regoff(ctxt, p.From3) 2009 o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(v)>>16) 2010 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(v)) 2011 o3 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), REGTMP) 2012 if p.From.Sym != nil { 2013 ctxt.Diag("%v is not supported", p) 2014 } 2015 2016 //if(dlm) reloc(&p->from3, p->pc, 0); 2017 2018 case 29: /* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */ 2019 v := regoff(ctxt, &p.From) 2020 2021 d := vregoff(ctxt, p.From3) 2022 var mask [2]uint8 2023 maskgen64(ctxt, p, mask[:], uint64(d)) 2024 var a int 2025 switch p.As { 2026 case ARLDC, ARLDCCC: 2027 a = int(mask[0]) /* MB */ 2028 if int32(mask[1]) != (63 - v) { 2029 ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p) 2030 } 2031 2032 case ARLDCL, ARLDCLCC: 2033 a = int(mask[0]) /* MB */ 2034 if mask[1] != 63 { 2035 ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p) 2036 } 2037 2038 case ARLDCR, ARLDCRCC: 2039 a = int(mask[1]) /* ME */ 2040 if mask[0] != 0 { 2041 ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p) 2042 } 2043 2044 default: 2045 ctxt.Diag("unexpected op in rldic case\n%v", p) 2046 a = 0 2047 } 2048 2049 o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F)) 2050 o1 |= (uint32(a) & 31) << 6 2051 if v&0x20 != 0 { 2052 o1 |= 1 << 1 2053 } 2054 if a&0x20 != 0 { 2055 o1 |= 1 << 5 /* mb[5] is top bit */ 2056 } 2057 2058 case 30: /* rldimi $sh,s,$mask,a */ 2059 v := regoff(ctxt, &p.From) 2060 2061 d := vregoff(ctxt, p.From3) 2062 var mask [2]uint8 2063 maskgen64(ctxt, p, mask[:], uint64(d)) 2064 if int32(mask[1]) != (63 - v) { 2065 ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p) 2066 } 2067 o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F)) 2068 o1 |= (uint32(mask[0]) & 31) << 6 2069 if v&0x20 != 0 { 2070 o1 |= 1 << 1 2071 } 2072 if mask[0]&0x20 != 0 { 2073 o1 |= 1 << 5 /* mb[5] is top bit */ 2074 } 2075 2076 case 31: /* dword */ 2077 d := vregoff(ctxt, &p.From) 2078 2079 if ctxt.Arch.ByteOrder == binary.BigEndian { 2080 o1 = uint32(d >> 32) 2081 o2 = uint32(d) 2082 } else { 2083 o1 = uint32(d) 2084 o2 = uint32(d >> 32) 2085 } 2086 2087 if p.From.Sym != nil { 2088 rel := obj.Addrel(ctxt.Cursym) 2089 rel.Off = int32(ctxt.Pc) 2090 rel.Siz = 8 2091 rel.Sym = p.From.Sym 2092 rel.Add = p.From.Offset 2093 rel.Type = obj.R_ADDR 2094 o2 = 0 2095 o1 = o2 2096 } 2097 2098 case 32: /* fmul frc,fra,frd */ 2099 r := int(p.Reg) 2100 2101 if r == 0 { 2102 r = int(p.To.Reg) 2103 } 2104 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6 2105 2106 case 33: /* fabs [frb,]frd; fmr. frb,frd */ 2107 r := int(p.From.Reg) 2108 2109 if oclass(&p.From) == C_NONE { 2110 r = int(p.To.Reg) 2111 } 2112 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), 0, uint32(r)) 2113 2114 case 34: /* FMADDx fra,frb,frc,frd (d=a*b+c); FSELx a<0? (d=b): (d=c) */ 2115 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) | (uint32(p.From3.Reg)&31)<<6 2116 2117 case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */ 2118 v := regoff(ctxt, &p.To) 2119 2120 r := int(p.To.Reg) 2121 if r == 0 { 2122 r = int(o.param) 2123 } 2124 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v))) 2125 o2 = AOP_IRR(opstore(ctxt, p.As), uint32(p.From.Reg), REGTMP, uint32(v)) 2126 2127 case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */ 2128 v := regoff(ctxt, &p.From) 2129 2130 r := int(p.From.Reg) 2131 if r == 0 { 2132 r = int(o.param) 2133 } 2134 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v))) 2135 o2 = AOP_IRR(opload(ctxt, p.As), uint32(p.To.Reg), REGTMP, uint32(v)) 2136 2137 case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */ 2138 v := regoff(ctxt, &p.From) 2139 2140 r := int(p.From.Reg) 2141 if r == 0 { 2142 r = int(o.param) 2143 } 2144 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v))) 2145 o2 = AOP_IRR(opload(ctxt, p.As), uint32(p.To.Reg), REGTMP, uint32(v)) 2146 o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0) 2147 2148 case 40: /* word */ 2149 o1 = uint32(regoff(ctxt, &p.From)) 2150 2151 case 41: /* stswi */ 2152 o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(regoff(ctxt, p.From3))&0x7F)<<11 2153 2154 case 42: /* lswi */ 2155 o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(regoff(ctxt, p.From3))&0x7F)<<11 2156 2157 case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */ 2158 o1 = AOP_RRR(oprrr(ctxt, p.As), 0, uint32(p.From.Index), uint32(p.From.Reg)) 2159 2160 case 44: /* indexed store */ 2161 o1 = AOP_RRR(opstorex(ctxt, p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg)) 2162 2163 case 45: /* indexed load */ 2164 o1 = AOP_RRR(oploadx(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg)) 2165 2166 case 46: /* plain op */ 2167 o1 = oprrr(ctxt, p.As) 2168 2169 case 47: /* op Ra, Rd; also op [Ra,] Rd */ 2170 r := int(p.From.Reg) 2171 2172 if r == 0 { 2173 r = int(p.To.Reg) 2174 } 2175 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), 0) 2176 2177 case 48: /* op Rs, Ra */ 2178 r := int(p.From.Reg) 2179 2180 if r == 0 { 2181 r = int(p.To.Reg) 2182 } 2183 o1 = LOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), 0) 2184 2185 case 49: /* op Rb; op $n, Rb */ 2186 if p.From.Type != obj.TYPE_REG { /* tlbie $L, rB */ 2187 v := regoff(ctxt, &p.From) & 1 2188 o1 = AOP_RRR(oprrr(ctxt, p.As), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21 2189 } else { 2190 o1 = AOP_RRR(oprrr(ctxt, p.As), 0, 0, uint32(p.From.Reg)) 2191 } 2192 2193 case 50: /* rem[u] r1[,r2],r3 */ 2194 r := int(p.Reg) 2195 2196 if r == 0 { 2197 r = int(p.To.Reg) 2198 } 2199 v := oprrr(ctxt, p.As) 2200 t := v & (1<<10 | 1) /* OE|Rc */ 2201 o1 = AOP_RRR(uint32(v)&^uint32(t), REGTMP, uint32(r), uint32(p.From.Reg)) 2202 o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, uint32(p.From.Reg)) 2203 o3 = AOP_RRR(OP_SUBF|uint32(t), uint32(p.To.Reg), REGTMP, uint32(r)) 2204 if p.As == AREMU { 2205 o4 = o3 2206 2207 /* Clear top 32 bits */ 2208 o3 = OP_RLW(OP_RLDIC, REGTMP, REGTMP, 0, 0, 0) | 1<<5 2209 } 2210 2211 case 51: /* remd[u] r1[,r2],r3 */ 2212 r := int(p.Reg) 2213 2214 if r == 0 { 2215 r = int(p.To.Reg) 2216 } 2217 v := oprrr(ctxt, p.As) 2218 t := v & (1<<10 | 1) /* OE|Rc */ 2219 o1 = AOP_RRR(uint32(v)&^uint32(t), REGTMP, uint32(r), uint32(p.From.Reg)) 2220 o2 = AOP_RRR(OP_MULLD, REGTMP, REGTMP, uint32(p.From.Reg)) 2221 o3 = AOP_RRR(OP_SUBF|uint32(t), uint32(p.To.Reg), REGTMP, uint32(r)) 2222 2223 case 52: /* mtfsbNx cr(n) */ 2224 v := regoff(ctxt, &p.From) & 31 2225 2226 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(v), 0, 0) 2227 2228 case 53: /* mffsX ,fr1 */ 2229 o1 = AOP_RRR(OP_MFFS, uint32(p.To.Reg), 0, 0) 2230 2231 case 54: /* mov msr,r1; mov r1, msr*/ 2232 if oclass(&p.From) == C_REG { 2233 if p.As == AMOVD { 2234 o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0) 2235 } else { 2236 o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0) 2237 } 2238 } else { 2239 o1 = AOP_RRR(OP_MFMSR, uint32(p.To.Reg), 0, 0) 2240 } 2241 2242 case 55: /* op Rb, Rd */ 2243 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), 0, uint32(p.From.Reg)) 2244 2245 case 56: /* sra $sh,[s,]a; srd $sh,[s,]a */ 2246 v := regoff(ctxt, &p.From) 2247 2248 r := int(p.Reg) 2249 if r == 0 { 2250 r = int(p.To.Reg) 2251 } 2252 o1 = AOP_RRR(opirr(ctxt, p.As), uint32(r), uint32(p.To.Reg), uint32(v)&31) 2253 if (p.As == ASRAD || p.As == ASRADCC) && (v&0x20 != 0) { 2254 o1 |= 1 << 1 /* mb[5] */ 2255 } 2256 2257 case 57: /* slw $sh,[s,]a -> rlwinm ... */ 2258 v := regoff(ctxt, &p.From) 2259 2260 r := int(p.Reg) 2261 if r == 0 { 2262 r = int(p.To.Reg) 2263 } 2264 2265 /* 2266 * Let user (gs) shoot himself in the foot. 2267 * qc has already complained. 2268 * 2269 if(v < 0 || v > 31) 2270 ctxt->diag("illegal shift %ld\n%v", v, p); 2271 */ 2272 if v < 0 { 2273 v = 0 2274 } else if v > 32 { 2275 v = 32 2276 } 2277 var mask [2]uint8 2278 if p.As == ASRW || p.As == ASRWCC { /* shift right */ 2279 mask[0] = uint8(v) 2280 mask[1] = 31 2281 v = 32 - v 2282 } else { 2283 mask[0] = 0 2284 mask[1] = uint8(31 - v) 2285 } 2286 2287 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(r), uint32(v), uint32(mask[0]), uint32(mask[1])) 2288 if p.As == ASLWCC || p.As == ASRWCC { 2289 o1 |= 1 /* Rc */ 2290 } 2291 2292 case 58: /* logical $andcon,[s],a */ 2293 v := regoff(ctxt, &p.From) 2294 2295 r := int(p.Reg) 2296 if r == 0 { 2297 r = int(p.To.Reg) 2298 } 2299 o1 = LOP_IRR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v)) 2300 2301 case 59: /* or/and $ucon,,r */ 2302 v := regoff(ctxt, &p.From) 2303 2304 r := int(p.Reg) 2305 if r == 0 { 2306 r = int(p.To.Reg) 2307 } 2308 o1 = LOP_IRR(opirr(ctxt, -p.As), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis */ 2309 2310 case 60: /* tw to,a,b */ 2311 r := int(regoff(ctxt, &p.From) & 31) 2312 2313 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(r), uint32(p.Reg), uint32(p.To.Reg)) 2314 2315 case 61: /* tw to,a,$simm */ 2316 r := int(regoff(ctxt, &p.From) & 31) 2317 2318 v := regoff(ctxt, &p.To) 2319 o1 = AOP_IRR(opirr(ctxt, p.As), uint32(r), uint32(p.Reg), uint32(v)) 2320 2321 case 62: /* rlwmi $sh,s,$mask,a */ 2322 v := regoff(ctxt, &p.From) 2323 2324 var mask [2]uint8 2325 maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, p.From3))) 2326 o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(v)) 2327 o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1 2328 2329 case 63: /* rlwmi b,s,$mask,a */ 2330 var mask [2]uint8 2331 maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, p.From3))) 2332 2333 o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg)) 2334 o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1 2335 2336 case 64: /* mtfsf fr[, $m] {,fpcsr} */ 2337 var v int32 2338 if p.From3Type() != obj.TYPE_NONE { 2339 v = regoff(ctxt, p.From3) & 255 2340 } else { 2341 v = 255 2342 } 2343 o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<11 2344 2345 case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */ 2346 if p.To.Reg == 0 { 2347 ctxt.Diag("must specify FPSCR(n)\n%v", p) 2348 } 2349 o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(regoff(ctxt, &p.From))&31)<<12 2350 2351 case 66: /* mov spr,r1; mov r1,spr, also dcr */ 2352 var r int 2353 var v int32 2354 if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 { 2355 r = int(p.From.Reg) 2356 v = int32(p.To.Reg) 2357 if REG_DCR0 <= v && v <= REG_DCR0+1023 { 2358 o1 = OPVCC(31, 451, 0, 0) /* mtdcr */ 2359 } else { 2360 o1 = OPVCC(31, 467, 0, 0) /* mtspr */ 2361 } 2362 } else { 2363 r = int(p.To.Reg) 2364 v = int32(p.From.Reg) 2365 if REG_DCR0 <= v && v <= REG_DCR0+1023 { 2366 o1 = OPVCC(31, 323, 0, 0) /* mfdcr */ 2367 } else { 2368 o1 = OPVCC(31, 339, 0, 0) /* mfspr */ 2369 } 2370 } 2371 2372 o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11 2373 2374 case 67: /* mcrf crfD,crfS */ 2375 if p.From.Type != obj.TYPE_REG || p.From.Reg < REG_CR0 || REG_CR7 < p.From.Reg || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_CR0 || REG_CR7 < p.To.Reg { 2376 ctxt.Diag("illegal CR field number\n%v", p) 2377 } 2378 o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0) 2379 2380 case 68: /* mfcr rD; mfocrf CRM,rD */ 2381 if p.From.Type == obj.TYPE_REG && REG_CR0 <= p.From.Reg && p.From.Reg <= REG_CR7 { 2382 v := int32(1 << uint(7-(p.To.Reg&7))) /* CR(n) */ 2383 o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */ 2384 } else { 2385 o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */ 2386 } 2387 2388 case 69: /* mtcrf CRM,rS */ 2389 var v int32 2390 if p.From3Type() != obj.TYPE_NONE { 2391 if p.To.Reg != 0 { 2392 ctxt.Diag("can't use both mask and CR(n)\n%v", p) 2393 } 2394 v = regoff(ctxt, p.From3) & 0xff 2395 } else { 2396 if p.To.Reg == 0 { 2397 v = 0xff /* CR */ 2398 } else { 2399 v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */ 2400 } 2401 } 2402 2403 o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12 2404 2405 case 70: /* [f]cmp r,r,cr*/ 2406 var r int 2407 if p.Reg == 0 { 2408 r = 0 2409 } else { 2410 r = (int(p.Reg) & 7) << 2 2411 } 2412 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg)) 2413 2414 case 71: /* cmp[l] r,i,cr*/ 2415 var r int 2416 if p.Reg == 0 { 2417 r = 0 2418 } else { 2419 r = (int(p.Reg) & 7) << 2 2420 } 2421 o1 = AOP_RRR(opirr(ctxt, p.As), uint32(r), uint32(p.From.Reg), 0) | uint32(regoff(ctxt, &p.To))&0xffff 2422 2423 case 72: /* slbmte (Rb+Rs -> slb[Rb]) -> Rs, Rb */ 2424 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.From.Reg), 0, uint32(p.To.Reg)) 2425 2426 case 73: /* mcrfs crfD,crfS */ 2427 if p.From.Type != obj.TYPE_REG || p.From.Reg != REG_FPSCR || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_CR0 || REG_CR7 < p.To.Reg { 2428 ctxt.Diag("illegal FPSCR/CR field number\n%v", p) 2429 } 2430 o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((0 & 7) << 2), 0) 2431 2432 case 77: /* syscall $scon, syscall Rx */ 2433 if p.From.Type == obj.TYPE_CONST { 2434 if p.From.Offset > BIG || p.From.Offset < -BIG { 2435 ctxt.Diag("illegal syscall, sysnum too large: %v", p) 2436 } 2437 o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(p.From.Offset)) 2438 } else if p.From.Type == obj.TYPE_REG { 2439 o1 = LOP_RRR(OP_OR, REGZERO, uint32(p.From.Reg), uint32(p.From.Reg)) 2440 } else { 2441 ctxt.Diag("illegal syscall: %v", p) 2442 o1 = 0x7fe00008 // trap always 2443 } 2444 2445 o2 = oprrr(ctxt, p.As) 2446 o3 = AOP_RRR(oprrr(ctxt, AXOR), REGZERO, REGZERO, REGZERO) // XOR R0, R0 2447 2448 case 78: /* undef */ 2449 o1 = 0 /* "An instruction consisting entirely of binary 0s is guaranteed 2450 always to be an illegal instruction." */ 2451 2452 /* relocation operations */ 2453 case 74: 2454 v := vregoff(ctxt, &p.To) 2455 o1, o2 = symbolAccess(ctxt, p.To.Sym, v, p.From.Reg, opstore(ctxt, p.As)) 2456 2457 //if(dlm) reloc(&p->to, p->pc, 1); 2458 2459 case 75: 2460 v := vregoff(ctxt, &p.From) 2461 o1, o2 = symbolAccess(ctxt, p.From.Sym, v, p.To.Reg, opload(ctxt, p.As)) 2462 2463 //if(dlm) reloc(&p->from, p->pc, 1); 2464 2465 case 76: 2466 v := vregoff(ctxt, &p.From) 2467 o1, o2 = symbolAccess(ctxt, p.From.Sym, v, p.To.Reg, opload(ctxt, p.As)) 2468 o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0) 2469 2470 //if(dlm) reloc(&p->from, p->pc, 1); 2471 2472 case 79: 2473 if p.From.Offset != 0 { 2474 ctxt.Diag("invalid offset against tls var %v", p) 2475 } 2476 o1 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGZERO, 0) 2477 rel := obj.Addrel(ctxt.Cursym) 2478 rel.Off = int32(ctxt.Pc) 2479 rel.Siz = 4 2480 rel.Sym = p.From.Sym 2481 rel.Type = obj.R_POWER_TLS_LE 2482 2483 case 80: 2484 if p.From.Offset != 0 { 2485 ctxt.Diag("invalid offset against tls var %v", p) 2486 } 2487 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0) 2488 o2 = AOP_IRR(uint32(opload(ctxt, AMOVD)), uint32(p.To.Reg), uint32(p.To.Reg), 0) 2489 rel := obj.Addrel(ctxt.Cursym) 2490 rel.Off = int32(ctxt.Pc) 2491 rel.Siz = 8 2492 rel.Sym = p.From.Sym 2493 rel.Type = obj.R_POWER_TLS_IE 2494 2495 case 81: 2496 v := vregoff(ctxt, &p.To) 2497 if v != 0 { 2498 ctxt.Diag("invalid offset against GOT slot %v", p) 2499 } 2500 2501 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0) 2502 o2 = AOP_IRR(uint32(opload(ctxt, AMOVD)), uint32(p.To.Reg), uint32(p.To.Reg), 0) 2503 rel := obj.Addrel(ctxt.Cursym) 2504 rel.Off = int32(ctxt.Pc) 2505 rel.Siz = 8 2506 rel.Sym = p.From.Sym 2507 rel.Type = obj.R_ADDRPOWER_GOT 2508 } 2509 2510 out[0] = o1 2511 out[1] = o2 2512 out[2] = o3 2513 out[3] = o4 2514 out[4] = o5 2515 return 2516 } 2517 2518 func vregoff(ctxt *obj.Link, a *obj.Addr) int64 { 2519 ctxt.Instoffset = 0 2520 if a != nil { 2521 aclass(ctxt, a) 2522 } 2523 return ctxt.Instoffset 2524 } 2525 2526 func regoff(ctxt *obj.Link, a *obj.Addr) int32 { 2527 return int32(vregoff(ctxt, a)) 2528 } 2529 2530 func oprrr(ctxt *obj.Link, a obj.As) uint32 { 2531 switch a { 2532 case AADD: 2533 return OPVCC(31, 266, 0, 0) 2534 case AADDCC: 2535 return OPVCC(31, 266, 0, 1) 2536 case AADDV: 2537 return OPVCC(31, 266, 1, 0) 2538 case AADDVCC: 2539 return OPVCC(31, 266, 1, 1) 2540 case AADDC: 2541 return OPVCC(31, 10, 0, 0) 2542 case AADDCCC: 2543 return OPVCC(31, 10, 0, 1) 2544 case AADDCV: 2545 return OPVCC(31, 10, 1, 0) 2546 case AADDCVCC: 2547 return OPVCC(31, 10, 1, 1) 2548 case AADDE: 2549 return OPVCC(31, 138, 0, 0) 2550 case AADDECC: 2551 return OPVCC(31, 138, 0, 1) 2552 case AADDEV: 2553 return OPVCC(31, 138, 1, 0) 2554 case AADDEVCC: 2555 return OPVCC(31, 138, 1, 1) 2556 case AADDME: 2557 return OPVCC(31, 234, 0, 0) 2558 case AADDMECC: 2559 return OPVCC(31, 234, 0, 1) 2560 case AADDMEV: 2561 return OPVCC(31, 234, 1, 0) 2562 case AADDMEVCC: 2563 return OPVCC(31, 234, 1, 1) 2564 case AADDZE: 2565 return OPVCC(31, 202, 0, 0) 2566 case AADDZECC: 2567 return OPVCC(31, 202, 0, 1) 2568 case AADDZEV: 2569 return OPVCC(31, 202, 1, 0) 2570 case AADDZEVCC: 2571 return OPVCC(31, 202, 1, 1) 2572 2573 case AAND: 2574 return OPVCC(31, 28, 0, 0) 2575 case AANDCC: 2576 return OPVCC(31, 28, 0, 1) 2577 case AANDN: 2578 return OPVCC(31, 60, 0, 0) 2579 case AANDNCC: 2580 return OPVCC(31, 60, 0, 1) 2581 2582 case ACMP: 2583 return OPVCC(31, 0, 0, 0) | 1<<21 /* L=1 */ 2584 case ACMPU: 2585 return OPVCC(31, 32, 0, 0) | 1<<21 2586 case ACMPW: 2587 return OPVCC(31, 0, 0, 0) /* L=0 */ 2588 case ACMPWU: 2589 return OPVCC(31, 32, 0, 0) 2590 2591 case ACNTLZW: 2592 return OPVCC(31, 26, 0, 0) 2593 case ACNTLZWCC: 2594 return OPVCC(31, 26, 0, 1) 2595 case ACNTLZD: 2596 return OPVCC(31, 58, 0, 0) 2597 case ACNTLZDCC: 2598 return OPVCC(31, 58, 0, 1) 2599 2600 case ACRAND: 2601 return OPVCC(19, 257, 0, 0) 2602 case ACRANDN: 2603 return OPVCC(19, 129, 0, 0) 2604 case ACREQV: 2605 return OPVCC(19, 289, 0, 0) 2606 case ACRNAND: 2607 return OPVCC(19, 225, 0, 0) 2608 case ACRNOR: 2609 return OPVCC(19, 33, 0, 0) 2610 case ACROR: 2611 return OPVCC(19, 449, 0, 0) 2612 case ACRORN: 2613 return OPVCC(19, 417, 0, 0) 2614 case ACRXOR: 2615 return OPVCC(19, 193, 0, 0) 2616 2617 case ADCBF: 2618 return OPVCC(31, 86, 0, 0) 2619 case ADCBI: 2620 return OPVCC(31, 470, 0, 0) 2621 case ADCBST: 2622 return OPVCC(31, 54, 0, 0) 2623 case ADCBT: 2624 return OPVCC(31, 278, 0, 0) 2625 case ADCBTST: 2626 return OPVCC(31, 246, 0, 0) 2627 case ADCBZ: 2628 return OPVCC(31, 1014, 0, 0) 2629 2630 case AREM, ADIVW: 2631 return OPVCC(31, 491, 0, 0) 2632 2633 case AREMCC, ADIVWCC: 2634 return OPVCC(31, 491, 0, 1) 2635 2636 case AREMV, ADIVWV: 2637 return OPVCC(31, 491, 1, 0) 2638 2639 case AREMVCC, ADIVWVCC: 2640 return OPVCC(31, 491, 1, 1) 2641 2642 case AREMU, ADIVWU: 2643 return OPVCC(31, 459, 0, 0) 2644 2645 case AREMUCC, ADIVWUCC: 2646 return OPVCC(31, 459, 0, 1) 2647 2648 case AREMUV, ADIVWUV: 2649 return OPVCC(31, 459, 1, 0) 2650 2651 case AREMUVCC, ADIVWUVCC: 2652 return OPVCC(31, 459, 1, 1) 2653 2654 case AREMD, ADIVD: 2655 return OPVCC(31, 489, 0, 0) 2656 2657 case AREMDCC, ADIVDCC: 2658 return OPVCC(31, 489, 0, 1) 2659 2660 case AREMDV, ADIVDV: 2661 return OPVCC(31, 489, 1, 0) 2662 2663 case AREMDVCC, ADIVDVCC: 2664 return OPVCC(31, 489, 1, 1) 2665 2666 case AREMDU, ADIVDU: 2667 return OPVCC(31, 457, 0, 0) 2668 2669 case AREMDUCC, ADIVDUCC: 2670 return OPVCC(31, 457, 0, 1) 2671 2672 case AREMDUV, ADIVDUV: 2673 return OPVCC(31, 457, 1, 0) 2674 2675 case AREMDUVCC, ADIVDUVCC: 2676 return OPVCC(31, 457, 1, 1) 2677 2678 case AEIEIO: 2679 return OPVCC(31, 854, 0, 0) 2680 2681 case AEQV: 2682 return OPVCC(31, 284, 0, 0) 2683 case AEQVCC: 2684 return OPVCC(31, 284, 0, 1) 2685 2686 case AEXTSB: 2687 return OPVCC(31, 954, 0, 0) 2688 case AEXTSBCC: 2689 return OPVCC(31, 954, 0, 1) 2690 case AEXTSH: 2691 return OPVCC(31, 922, 0, 0) 2692 case AEXTSHCC: 2693 return OPVCC(31, 922, 0, 1) 2694 case AEXTSW: 2695 return OPVCC(31, 986, 0, 0) 2696 case AEXTSWCC: 2697 return OPVCC(31, 986, 0, 1) 2698 2699 case AFABS: 2700 return OPVCC(63, 264, 0, 0) 2701 case AFABSCC: 2702 return OPVCC(63, 264, 0, 1) 2703 case AFADD: 2704 return OPVCC(63, 21, 0, 0) 2705 case AFADDCC: 2706 return OPVCC(63, 21, 0, 1) 2707 case AFADDS: 2708 return OPVCC(59, 21, 0, 0) 2709 case AFADDSCC: 2710 return OPVCC(59, 21, 0, 1) 2711 case AFCMPO: 2712 return OPVCC(63, 32, 0, 0) 2713 case AFCMPU: 2714 return OPVCC(63, 0, 0, 0) 2715 case AFCFID: 2716 return OPVCC(63, 846, 0, 0) 2717 case AFCFIDCC: 2718 return OPVCC(63, 846, 0, 1) 2719 case AFCTIW: 2720 return OPVCC(63, 14, 0, 0) 2721 case AFCTIWCC: 2722 return OPVCC(63, 14, 0, 1) 2723 case AFCTIWZ: 2724 return OPVCC(63, 15, 0, 0) 2725 case AFCTIWZCC: 2726 return OPVCC(63, 15, 0, 1) 2727 case AFCTID: 2728 return OPVCC(63, 814, 0, 0) 2729 case AFCTIDCC: 2730 return OPVCC(63, 814, 0, 1) 2731 case AFCTIDZ: 2732 return OPVCC(63, 815, 0, 0) 2733 case AFCTIDZCC: 2734 return OPVCC(63, 815, 0, 1) 2735 case AFDIV: 2736 return OPVCC(63, 18, 0, 0) 2737 case AFDIVCC: 2738 return OPVCC(63, 18, 0, 1) 2739 case AFDIVS: 2740 return OPVCC(59, 18, 0, 0) 2741 case AFDIVSCC: 2742 return OPVCC(59, 18, 0, 1) 2743 case AFMADD: 2744 return OPVCC(63, 29, 0, 0) 2745 case AFMADDCC: 2746 return OPVCC(63, 29, 0, 1) 2747 case AFMADDS: 2748 return OPVCC(59, 29, 0, 0) 2749 case AFMADDSCC: 2750 return OPVCC(59, 29, 0, 1) 2751 2752 case AFMOVS, AFMOVD: 2753 return OPVCC(63, 72, 0, 0) /* load */ 2754 case AFMOVDCC: 2755 return OPVCC(63, 72, 0, 1) 2756 case AFMSUB: 2757 return OPVCC(63, 28, 0, 0) 2758 case AFMSUBCC: 2759 return OPVCC(63, 28, 0, 1) 2760 case AFMSUBS: 2761 return OPVCC(59, 28, 0, 0) 2762 case AFMSUBSCC: 2763 return OPVCC(59, 28, 0, 1) 2764 case AFMUL: 2765 return OPVCC(63, 25, 0, 0) 2766 case AFMULCC: 2767 return OPVCC(63, 25, 0, 1) 2768 case AFMULS: 2769 return OPVCC(59, 25, 0, 0) 2770 case AFMULSCC: 2771 return OPVCC(59, 25, 0, 1) 2772 case AFNABS: 2773 return OPVCC(63, 136, 0, 0) 2774 case AFNABSCC: 2775 return OPVCC(63, 136, 0, 1) 2776 case AFNEG: 2777 return OPVCC(63, 40, 0, 0) 2778 case AFNEGCC: 2779 return OPVCC(63, 40, 0, 1) 2780 case AFNMADD: 2781 return OPVCC(63, 31, 0, 0) 2782 case AFNMADDCC: 2783 return OPVCC(63, 31, 0, 1) 2784 case AFNMADDS: 2785 return OPVCC(59, 31, 0, 0) 2786 case AFNMADDSCC: 2787 return OPVCC(59, 31, 0, 1) 2788 case AFNMSUB: 2789 return OPVCC(63, 30, 0, 0) 2790 case AFNMSUBCC: 2791 return OPVCC(63, 30, 0, 1) 2792 case AFNMSUBS: 2793 return OPVCC(59, 30, 0, 0) 2794 case AFNMSUBSCC: 2795 return OPVCC(59, 30, 0, 1) 2796 case AFRES: 2797 return OPVCC(59, 24, 0, 0) 2798 case AFRESCC: 2799 return OPVCC(59, 24, 0, 1) 2800 case AFRSP: 2801 return OPVCC(63, 12, 0, 0) 2802 case AFRSPCC: 2803 return OPVCC(63, 12, 0, 1) 2804 case AFRSQRTE: 2805 return OPVCC(63, 26, 0, 0) 2806 case AFRSQRTECC: 2807 return OPVCC(63, 26, 0, 1) 2808 case AFSEL: 2809 return OPVCC(63, 23, 0, 0) 2810 case AFSELCC: 2811 return OPVCC(63, 23, 0, 1) 2812 case AFSQRT: 2813 return OPVCC(63, 22, 0, 0) 2814 case AFSQRTCC: 2815 return OPVCC(63, 22, 0, 1) 2816 case AFSQRTS: 2817 return OPVCC(59, 22, 0, 0) 2818 case AFSQRTSCC: 2819 return OPVCC(59, 22, 0, 1) 2820 case AFSUB: 2821 return OPVCC(63, 20, 0, 0) 2822 case AFSUBCC: 2823 return OPVCC(63, 20, 0, 1) 2824 case AFSUBS: 2825 return OPVCC(59, 20, 0, 0) 2826 case AFSUBSCC: 2827 return OPVCC(59, 20, 0, 1) 2828 2829 case AICBI: 2830 return OPVCC(31, 982, 0, 0) 2831 case AISYNC: 2832 return OPVCC(19, 150, 0, 0) 2833 2834 case AMTFSB0: 2835 return OPVCC(63, 70, 0, 0) 2836 case AMTFSB0CC: 2837 return OPVCC(63, 70, 0, 1) 2838 case AMTFSB1: 2839 return OPVCC(63, 38, 0, 0) 2840 case AMTFSB1CC: 2841 return OPVCC(63, 38, 0, 1) 2842 2843 case AMULHW: 2844 return OPVCC(31, 75, 0, 0) 2845 case AMULHWCC: 2846 return OPVCC(31, 75, 0, 1) 2847 case AMULHWU: 2848 return OPVCC(31, 11, 0, 0) 2849 case AMULHWUCC: 2850 return OPVCC(31, 11, 0, 1) 2851 case AMULLW: 2852 return OPVCC(31, 235, 0, 0) 2853 case AMULLWCC: 2854 return OPVCC(31, 235, 0, 1) 2855 case AMULLWV: 2856 return OPVCC(31, 235, 1, 0) 2857 case AMULLWVCC: 2858 return OPVCC(31, 235, 1, 1) 2859 2860 case AMULHD: 2861 return OPVCC(31, 73, 0, 0) 2862 case AMULHDCC: 2863 return OPVCC(31, 73, 0, 1) 2864 case AMULHDU: 2865 return OPVCC(31, 9, 0, 0) 2866 case AMULHDUCC: 2867 return OPVCC(31, 9, 0, 1) 2868 case AMULLD: 2869 return OPVCC(31, 233, 0, 0) 2870 case AMULLDCC: 2871 return OPVCC(31, 233, 0, 1) 2872 case AMULLDV: 2873 return OPVCC(31, 233, 1, 0) 2874 case AMULLDVCC: 2875 return OPVCC(31, 233, 1, 1) 2876 2877 case ANAND: 2878 return OPVCC(31, 476, 0, 0) 2879 case ANANDCC: 2880 return OPVCC(31, 476, 0, 1) 2881 case ANEG: 2882 return OPVCC(31, 104, 0, 0) 2883 case ANEGCC: 2884 return OPVCC(31, 104, 0, 1) 2885 case ANEGV: 2886 return OPVCC(31, 104, 1, 0) 2887 case ANEGVCC: 2888 return OPVCC(31, 104, 1, 1) 2889 case ANOR: 2890 return OPVCC(31, 124, 0, 0) 2891 case ANORCC: 2892 return OPVCC(31, 124, 0, 1) 2893 case AOR: 2894 return OPVCC(31, 444, 0, 0) 2895 case AORCC: 2896 return OPVCC(31, 444, 0, 1) 2897 case AORN: 2898 return OPVCC(31, 412, 0, 0) 2899 case AORNCC: 2900 return OPVCC(31, 412, 0, 1) 2901 2902 case ARFI: 2903 return OPVCC(19, 50, 0, 0) 2904 case ARFCI: 2905 return OPVCC(19, 51, 0, 0) 2906 case ARFID: 2907 return OPVCC(19, 18, 0, 0) 2908 case AHRFID: 2909 return OPVCC(19, 274, 0, 0) 2910 2911 case ARLWMI: 2912 return OPVCC(20, 0, 0, 0) 2913 case ARLWMICC: 2914 return OPVCC(20, 0, 0, 1) 2915 case ARLWNM: 2916 return OPVCC(23, 0, 0, 0) 2917 case ARLWNMCC: 2918 return OPVCC(23, 0, 0, 1) 2919 2920 case ARLDCL: 2921 return OPVCC(30, 8, 0, 0) 2922 case ARLDCR: 2923 return OPVCC(30, 9, 0, 0) 2924 2925 case ASYSCALL: 2926 return OPVCC(17, 1, 0, 0) 2927 2928 case ASLW: 2929 return OPVCC(31, 24, 0, 0) 2930 case ASLWCC: 2931 return OPVCC(31, 24, 0, 1) 2932 case ASLD: 2933 return OPVCC(31, 27, 0, 0) 2934 case ASLDCC: 2935 return OPVCC(31, 27, 0, 1) 2936 2937 case ASRAW: 2938 return OPVCC(31, 792, 0, 0) 2939 case ASRAWCC: 2940 return OPVCC(31, 792, 0, 1) 2941 case ASRAD: 2942 return OPVCC(31, 794, 0, 0) 2943 case ASRADCC: 2944 return OPVCC(31, 794, 0, 1) 2945 2946 case ASRW: 2947 return OPVCC(31, 536, 0, 0) 2948 case ASRWCC: 2949 return OPVCC(31, 536, 0, 1) 2950 case ASRD: 2951 return OPVCC(31, 539, 0, 0) 2952 case ASRDCC: 2953 return OPVCC(31, 539, 0, 1) 2954 2955 case ASUB: 2956 return OPVCC(31, 40, 0, 0) 2957 case ASUBCC: 2958 return OPVCC(31, 40, 0, 1) 2959 case ASUBV: 2960 return OPVCC(31, 40, 1, 0) 2961 case ASUBVCC: 2962 return OPVCC(31, 40, 1, 1) 2963 case ASUBC: 2964 return OPVCC(31, 8, 0, 0) 2965 case ASUBCCC: 2966 return OPVCC(31, 8, 0, 1) 2967 case ASUBCV: 2968 return OPVCC(31, 8, 1, 0) 2969 case ASUBCVCC: 2970 return OPVCC(31, 8, 1, 1) 2971 case ASUBE: 2972 return OPVCC(31, 136, 0, 0) 2973 case ASUBECC: 2974 return OPVCC(31, 136, 0, 1) 2975 case ASUBEV: 2976 return OPVCC(31, 136, 1, 0) 2977 case ASUBEVCC: 2978 return OPVCC(31, 136, 1, 1) 2979 case ASUBME: 2980 return OPVCC(31, 232, 0, 0) 2981 case ASUBMECC: 2982 return OPVCC(31, 232, 0, 1) 2983 case ASUBMEV: 2984 return OPVCC(31, 232, 1, 0) 2985 case ASUBMEVCC: 2986 return OPVCC(31, 232, 1, 1) 2987 case ASUBZE: 2988 return OPVCC(31, 200, 0, 0) 2989 case ASUBZECC: 2990 return OPVCC(31, 200, 0, 1) 2991 case ASUBZEV: 2992 return OPVCC(31, 200, 1, 0) 2993 case ASUBZEVCC: 2994 return OPVCC(31, 200, 1, 1) 2995 2996 case ASYNC: 2997 return OPVCC(31, 598, 0, 0) 2998 case APTESYNC: 2999 return OPVCC(31, 598, 0, 0) | 2<<21 3000 3001 case ATLBIE: 3002 return OPVCC(31, 306, 0, 0) 3003 case ATLBIEL: 3004 return OPVCC(31, 274, 0, 0) 3005 case ATLBSYNC: 3006 return OPVCC(31, 566, 0, 0) 3007 case ASLBIA: 3008 return OPVCC(31, 498, 0, 0) 3009 case ASLBIE: 3010 return OPVCC(31, 434, 0, 0) 3011 case ASLBMFEE: 3012 return OPVCC(31, 915, 0, 0) 3013 case ASLBMFEV: 3014 return OPVCC(31, 851, 0, 0) 3015 case ASLBMTE: 3016 return OPVCC(31, 402, 0, 0) 3017 3018 case ATW: 3019 return OPVCC(31, 4, 0, 0) 3020 case ATD: 3021 return OPVCC(31, 68, 0, 0) 3022 3023 case AXOR: 3024 return OPVCC(31, 316, 0, 0) 3025 case AXORCC: 3026 return OPVCC(31, 316, 0, 1) 3027 } 3028 3029 ctxt.Diag("bad r/r opcode %v", obj.Aconv(a)) 3030 return 0 3031 } 3032 3033 func opirr(ctxt *obj.Link, a obj.As) uint32 { 3034 switch a { 3035 case AADD: 3036 return OPVCC(14, 0, 0, 0) 3037 case AADDC: 3038 return OPVCC(12, 0, 0, 0) 3039 case AADDCCC: 3040 return OPVCC(13, 0, 0, 0) 3041 case -AADD: 3042 return OPVCC(15, 0, 0, 0) /* ADDIS/CAU */ 3043 3044 case AANDCC: 3045 return OPVCC(28, 0, 0, 0) 3046 case -AANDCC: 3047 return OPVCC(29, 0, 0, 0) /* ANDIS./ANDIU. */ 3048 3049 case ABR: 3050 return OPVCC(18, 0, 0, 0) 3051 case ABL: 3052 return OPVCC(18, 0, 0, 0) | 1 3053 case obj.ADUFFZERO: 3054 return OPVCC(18, 0, 0, 0) | 1 3055 case obj.ADUFFCOPY: 3056 return OPVCC(18, 0, 0, 0) | 1 3057 case ABC: 3058 return OPVCC(16, 0, 0, 0) 3059 case ABCL: 3060 return OPVCC(16, 0, 0, 0) | 1 3061 3062 case ABEQ: 3063 return AOP_RRR(16<<26, 12, 2, 0) 3064 case ABGE: 3065 return AOP_RRR(16<<26, 4, 0, 0) 3066 case ABGT: 3067 return AOP_RRR(16<<26, 12, 1, 0) 3068 case ABLE: 3069 return AOP_RRR(16<<26, 4, 1, 0) 3070 case ABLT: 3071 return AOP_RRR(16<<26, 12, 0, 0) 3072 case ABNE: 3073 return AOP_RRR(16<<26, 4, 2, 0) 3074 case ABVC: 3075 return AOP_RRR(16<<26, 4, 3, 0) 3076 case ABVS: 3077 return AOP_RRR(16<<26, 12, 3, 0) 3078 3079 case ACMP: 3080 return OPVCC(11, 0, 0, 0) | 1<<21 /* L=1 */ 3081 case ACMPU: 3082 return OPVCC(10, 0, 0, 0) | 1<<21 3083 case ACMPW: 3084 return OPVCC(11, 0, 0, 0) /* L=0 */ 3085 case ACMPWU: 3086 return OPVCC(10, 0, 0, 0) 3087 case ALSW: 3088 return OPVCC(31, 597, 0, 0) 3089 3090 case AMULLW: 3091 return OPVCC(7, 0, 0, 0) 3092 3093 case AOR: 3094 return OPVCC(24, 0, 0, 0) 3095 case -AOR: 3096 return OPVCC(25, 0, 0, 0) /* ORIS/ORIU */ 3097 3098 case ARLWMI: 3099 return OPVCC(20, 0, 0, 0) /* rlwimi */ 3100 case ARLWMICC: 3101 return OPVCC(20, 0, 0, 1) 3102 case ARLDMI: 3103 return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */ 3104 case ARLDMICC: 3105 return OPVCC(30, 0, 0, 1) | 3<<2 3106 3107 case ARLWNM: 3108 return OPVCC(21, 0, 0, 0) /* rlwinm */ 3109 case ARLWNMCC: 3110 return OPVCC(21, 0, 0, 1) 3111 3112 case ARLDCL: 3113 return OPVCC(30, 0, 0, 0) /* rldicl */ 3114 case ARLDCLCC: 3115 return OPVCC(30, 0, 0, 1) 3116 case ARLDCR: 3117 return OPVCC(30, 1, 0, 0) /* rldicr */ 3118 case ARLDCRCC: 3119 return OPVCC(30, 1, 0, 1) 3120 case ARLDC: 3121 return OPVCC(30, 0, 0, 0) | 2<<2 3122 case ARLDCCC: 3123 return OPVCC(30, 0, 0, 1) | 2<<2 3124 3125 case ASRAW: 3126 return OPVCC(31, 824, 0, 0) 3127 case ASRAWCC: 3128 return OPVCC(31, 824, 0, 1) 3129 case ASRAD: 3130 return OPVCC(31, (413 << 1), 0, 0) 3131 case ASRADCC: 3132 return OPVCC(31, (413 << 1), 0, 1) 3133 3134 case ASTSW: 3135 return OPVCC(31, 725, 0, 0) 3136 3137 case ASUBC: 3138 return OPVCC(8, 0, 0, 0) 3139 3140 case ATW: 3141 return OPVCC(3, 0, 0, 0) 3142 case ATD: 3143 return OPVCC(2, 0, 0, 0) 3144 3145 case AXOR: 3146 return OPVCC(26, 0, 0, 0) /* XORIL */ 3147 case -AXOR: 3148 return OPVCC(27, 0, 0, 0) /* XORIU */ 3149 } 3150 3151 ctxt.Diag("bad opcode i/r %v", obj.Aconv(a)) 3152 return 0 3153 } 3154 3155 /* 3156 * load o(a),d 3157 */ 3158 func opload(ctxt *obj.Link, a obj.As) uint32 { 3159 switch a { 3160 case AMOVD: 3161 return OPVCC(58, 0, 0, 0) /* ld */ 3162 case AMOVDU: 3163 return OPVCC(58, 0, 0, 1) /* ldu */ 3164 case AMOVWZ: 3165 return OPVCC(32, 0, 0, 0) /* lwz */ 3166 case AMOVWZU: 3167 return OPVCC(33, 0, 0, 0) /* lwzu */ 3168 case AMOVW: 3169 return OPVCC(58, 0, 0, 0) | 1<<1 /* lwa */ 3170 3171 /* no AMOVWU */ 3172 case AMOVB, AMOVBZ: 3173 return OPVCC(34, 0, 0, 0) 3174 /* load */ 3175 3176 case AMOVBU, AMOVBZU: 3177 return OPVCC(35, 0, 0, 0) 3178 case AFMOVD: 3179 return OPVCC(50, 0, 0, 0) 3180 case AFMOVDU: 3181 return OPVCC(51, 0, 0, 0) 3182 case AFMOVS: 3183 return OPVCC(48, 0, 0, 0) 3184 case AFMOVSU: 3185 return OPVCC(49, 0, 0, 0) 3186 case AMOVH: 3187 return OPVCC(42, 0, 0, 0) 3188 case AMOVHU: 3189 return OPVCC(43, 0, 0, 0) 3190 case AMOVHZ: 3191 return OPVCC(40, 0, 0, 0) 3192 case AMOVHZU: 3193 return OPVCC(41, 0, 0, 0) 3194 case AMOVMW: 3195 return OPVCC(46, 0, 0, 0) /* lmw */ 3196 } 3197 3198 ctxt.Diag("bad load opcode %v", obj.Aconv(a)) 3199 return 0 3200 } 3201 3202 /* 3203 * indexed load a(b),d 3204 */ 3205 func oploadx(ctxt *obj.Link, a obj.As) uint32 { 3206 switch a { 3207 case AMOVWZ: 3208 return OPVCC(31, 23, 0, 0) /* lwzx */ 3209 case AMOVWZU: 3210 return OPVCC(31, 55, 0, 0) /* lwzux */ 3211 case AMOVW: 3212 return OPVCC(31, 341, 0, 0) /* lwax */ 3213 case AMOVWU: 3214 return OPVCC(31, 373, 0, 0) /* lwaux */ 3215 3216 case AMOVB, AMOVBZ: 3217 return OPVCC(31, 87, 0, 0) /* lbzx */ 3218 3219 case AMOVBU, AMOVBZU: 3220 return OPVCC(31, 119, 0, 0) /* lbzux */ 3221 case AFMOVD: 3222 return OPVCC(31, 599, 0, 0) /* lfdx */ 3223 case AFMOVDU: 3224 return OPVCC(31, 631, 0, 0) /* lfdux */ 3225 case AFMOVS: 3226 return OPVCC(31, 535, 0, 0) /* lfsx */ 3227 case AFMOVSU: 3228 return OPVCC(31, 567, 0, 0) /* lfsux */ 3229 case AMOVH: 3230 return OPVCC(31, 343, 0, 0) /* lhax */ 3231 case AMOVHU: 3232 return OPVCC(31, 375, 0, 0) /* lhaux */ 3233 case AMOVHBR: 3234 return OPVCC(31, 790, 0, 0) /* lhbrx */ 3235 case AMOVWBR: 3236 return OPVCC(31, 534, 0, 0) /* lwbrx */ 3237 case AMOVHZ: 3238 return OPVCC(31, 279, 0, 0) /* lhzx */ 3239 case AMOVHZU: 3240 return OPVCC(31, 311, 0, 0) /* lhzux */ 3241 case AECIWX: 3242 return OPVCC(31, 310, 0, 0) /* eciwx */ 3243 case ALWAR: 3244 return OPVCC(31, 20, 0, 0) /* lwarx */ 3245 case ALDAR: 3246 return OPVCC(31, 84, 0, 0) 3247 case ALSW: 3248 return OPVCC(31, 533, 0, 0) /* lswx */ 3249 case AMOVD: 3250 return OPVCC(31, 21, 0, 0) /* ldx */ 3251 case AMOVDU: 3252 return OPVCC(31, 53, 0, 0) /* ldux */ 3253 } 3254 3255 ctxt.Diag("bad loadx opcode %v", obj.Aconv(a)) 3256 return 0 3257 } 3258 3259 /* 3260 * store s,o(d) 3261 */ 3262 func opstore(ctxt *obj.Link, a obj.As) uint32 { 3263 switch a { 3264 case AMOVB, AMOVBZ: 3265 return OPVCC(38, 0, 0, 0) /* stb */ 3266 3267 case AMOVBU, AMOVBZU: 3268 return OPVCC(39, 0, 0, 0) /* stbu */ 3269 case AFMOVD: 3270 return OPVCC(54, 0, 0, 0) /* stfd */ 3271 case AFMOVDU: 3272 return OPVCC(55, 0, 0, 0) /* stfdu */ 3273 case AFMOVS: 3274 return OPVCC(52, 0, 0, 0) /* stfs */ 3275 case AFMOVSU: 3276 return OPVCC(53, 0, 0, 0) /* stfsu */ 3277 3278 case AMOVHZ, AMOVH: 3279 return OPVCC(44, 0, 0, 0) /* sth */ 3280 3281 case AMOVHZU, AMOVHU: 3282 return OPVCC(45, 0, 0, 0) /* sthu */ 3283 case AMOVMW: 3284 return OPVCC(47, 0, 0, 0) /* stmw */ 3285 case ASTSW: 3286 return OPVCC(31, 725, 0, 0) /* stswi */ 3287 3288 case AMOVWZ, AMOVW: 3289 return OPVCC(36, 0, 0, 0) /* stw */ 3290 3291 case AMOVWZU, AMOVWU: 3292 return OPVCC(37, 0, 0, 0) /* stwu */ 3293 case AMOVD: 3294 return OPVCC(62, 0, 0, 0) /* std */ 3295 case AMOVDU: 3296 return OPVCC(62, 0, 0, 1) /* stdu */ 3297 } 3298 3299 ctxt.Diag("unknown store opcode %v", obj.Aconv(a)) 3300 return 0 3301 } 3302 3303 /* 3304 * indexed store s,a(b) 3305 */ 3306 func opstorex(ctxt *obj.Link, a obj.As) uint32 { 3307 switch a { 3308 case AMOVB, AMOVBZ: 3309 return OPVCC(31, 215, 0, 0) /* stbx */ 3310 3311 case AMOVBU, AMOVBZU: 3312 return OPVCC(31, 247, 0, 0) /* stbux */ 3313 case AFMOVD: 3314 return OPVCC(31, 727, 0, 0) /* stfdx */ 3315 case AFMOVDU: 3316 return OPVCC(31, 759, 0, 0) /* stfdux */ 3317 case AFMOVS: 3318 return OPVCC(31, 663, 0, 0) /* stfsx */ 3319 case AFMOVSU: 3320 return OPVCC(31, 695, 0, 0) /* stfsux */ 3321 3322 case AMOVHZ, AMOVH: 3323 return OPVCC(31, 407, 0, 0) /* sthx */ 3324 case AMOVHBR: 3325 return OPVCC(31, 918, 0, 0) /* sthbrx */ 3326 3327 case AMOVHZU, AMOVHU: 3328 return OPVCC(31, 439, 0, 0) /* sthux */ 3329 3330 case AMOVWZ, AMOVW: 3331 return OPVCC(31, 151, 0, 0) /* stwx */ 3332 3333 case AMOVWZU, AMOVWU: 3334 return OPVCC(31, 183, 0, 0) /* stwux */ 3335 case ASTSW: 3336 return OPVCC(31, 661, 0, 0) /* stswx */ 3337 case AMOVWBR: 3338 return OPVCC(31, 662, 0, 0) /* stwbrx */ 3339 case ASTWCCC: 3340 return OPVCC(31, 150, 0, 1) /* stwcx. */ 3341 case ASTDCCC: 3342 return OPVCC(31, 214, 0, 1) /* stwdx. */ 3343 case AECOWX: 3344 return OPVCC(31, 438, 0, 0) /* ecowx */ 3345 case AMOVD: 3346 return OPVCC(31, 149, 0, 0) /* stdx */ 3347 case AMOVDU: 3348 return OPVCC(31, 181, 0, 0) /* stdux */ 3349 } 3350 3351 ctxt.Diag("unknown storex opcode %v", obj.Aconv(a)) 3352 return 0 3353 }