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