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