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