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