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