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