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