github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/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 mips 31 32 import ( 33 "cmd/internal/obj" 34 "fmt" 35 "log" 36 "sort" 37 ) 38 39 // Instruction layout. 40 41 const ( 42 FuncAlign = 8 43 ) 44 45 const ( 46 r0iszero = 1 47 ) 48 49 type Optab struct { 50 as obj.As 51 a1 uint8 52 a2 uint8 53 a3 uint8 54 type_ int8 55 size int8 56 param int16 57 } 58 59 var optab = []Optab{ 60 {obj.ATEXT, C_LEXT, C_NONE, C_TEXTSIZE, 0, 0, 0}, 61 {obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0}, 62 63 {AMOVW, C_REG, C_NONE, C_REG, 1, 4, 0}, 64 {AMOVV, C_REG, C_NONE, C_REG, 1, 4, 0}, 65 {AMOVB, C_REG, C_NONE, C_REG, 12, 8, 0}, 66 {AMOVBU, C_REG, C_NONE, C_REG, 13, 4, 0}, 67 {AMOVWU, C_REG, C_NONE, C_REG, 14, 8, 0}, 68 69 {ASUB, C_REG, C_REG, C_REG, 2, 4, 0}, 70 {AADD, C_REG, C_REG, C_REG, 2, 4, 0}, 71 {AAND, C_REG, C_REG, C_REG, 2, 4, 0}, 72 {ASUB, C_REG, C_NONE, C_REG, 2, 4, 0}, 73 {AADD, C_REG, C_NONE, C_REG, 2, 4, 0}, 74 {AAND, C_REG, C_NONE, C_REG, 2, 4, 0}, 75 76 {ASLL, C_REG, C_NONE, C_REG, 9, 4, 0}, 77 {ASLL, C_REG, C_REG, C_REG, 9, 4, 0}, 78 79 {AADDF, C_FREG, C_NONE, C_FREG, 32, 4, 0}, 80 {AADDF, C_FREG, C_REG, C_FREG, 32, 4, 0}, 81 {ACMPEQF, C_FREG, C_REG, C_NONE, 32, 4, 0}, 82 {AABSF, C_FREG, C_NONE, C_FREG, 33, 4, 0}, 83 {AMOVF, C_FREG, C_NONE, C_FREG, 33, 4, 0}, 84 {AMOVD, C_FREG, C_NONE, C_FREG, 33, 4, 0}, 85 86 {AMOVW, C_REG, C_NONE, C_SEXT, 7, 4, REGSB}, 87 {AMOVWU, C_REG, C_NONE, C_SEXT, 7, 4, REGSB}, 88 {AMOVV, C_REG, C_NONE, C_SEXT, 7, 4, REGSB}, 89 {AMOVB, C_REG, C_NONE, C_SEXT, 7, 4, REGSB}, 90 {AMOVBU, C_REG, C_NONE, C_SEXT, 7, 4, REGSB}, 91 {AMOVWL, C_REG, C_NONE, C_SEXT, 7, 4, REGSB}, 92 {AMOVW, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP}, 93 {AMOVWU, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP}, 94 {AMOVV, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP}, 95 {AMOVB, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP}, 96 {AMOVBU, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP}, 97 {AMOVWL, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP}, 98 {AMOVW, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO}, 99 {AMOVWU, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO}, 100 {AMOVV, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO}, 101 {AMOVB, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO}, 102 {AMOVBU, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO}, 103 {AMOVWL, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO}, 104 105 {AMOVW, C_SEXT, C_NONE, C_REG, 8, 4, REGSB}, 106 {AMOVWU, C_SEXT, C_NONE, C_REG, 8, 4, REGSB}, 107 {AMOVV, C_SEXT, C_NONE, C_REG, 8, 4, REGSB}, 108 {AMOVB, C_SEXT, C_NONE, C_REG, 8, 4, REGSB}, 109 {AMOVBU, C_SEXT, C_NONE, C_REG, 8, 4, REGSB}, 110 {AMOVWL, C_SEXT, C_NONE, C_REG, 8, 4, REGSB}, 111 {AMOVW, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP}, 112 {AMOVWU, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP}, 113 {AMOVV, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP}, 114 {AMOVB, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP}, 115 {AMOVBU, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP}, 116 {AMOVWL, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP}, 117 {AMOVW, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO}, 118 {AMOVWU, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO}, 119 {AMOVV, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO}, 120 {AMOVB, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO}, 121 {AMOVBU, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO}, 122 {AMOVWL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO}, 123 124 {AMOVW, C_REG, C_NONE, C_LEXT, 35, 12, REGSB}, 125 {AMOVWU, C_REG, C_NONE, C_LEXT, 35, 12, REGSB}, 126 {AMOVV, C_REG, C_NONE, C_LEXT, 35, 12, REGSB}, 127 {AMOVB, C_REG, C_NONE, C_LEXT, 35, 12, REGSB}, 128 {AMOVBU, C_REG, C_NONE, C_LEXT, 35, 12, REGSB}, 129 {AMOVW, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP}, 130 {AMOVWU, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP}, 131 {AMOVV, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP}, 132 {AMOVB, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP}, 133 {AMOVBU, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP}, 134 {AMOVW, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO}, 135 {AMOVWU, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO}, 136 {AMOVV, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO}, 137 {AMOVB, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO}, 138 {AMOVBU, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO}, 139 {AMOVW, C_REG, C_NONE, C_ADDR, 50, 12, 0}, 140 {AMOVWU, C_REG, C_NONE, C_ADDR, 50, 12, 0}, 141 {AMOVV, C_REG, C_NONE, C_ADDR, 50, 12, 0}, 142 {AMOVB, C_REG, C_NONE, C_ADDR, 50, 12, 0}, 143 {AMOVBU, C_REG, C_NONE, C_ADDR, 50, 12, 0}, 144 {AMOVW, C_REG, C_NONE, C_TLS, 53, 8, 0}, 145 {AMOVWU, C_REG, C_NONE, C_TLS, 53, 8, 0}, 146 {AMOVV, C_REG, C_NONE, C_TLS, 53, 8, 0}, 147 {AMOVB, C_REG, C_NONE, C_TLS, 53, 8, 0}, 148 {AMOVBU, C_REG, C_NONE, C_TLS, 53, 8, 0}, 149 150 {AMOVW, C_LEXT, C_NONE, C_REG, 36, 12, REGSB}, 151 {AMOVWU, C_LEXT, C_NONE, C_REG, 36, 12, REGSB}, 152 {AMOVV, C_LEXT, C_NONE, C_REG, 36, 12, REGSB}, 153 {AMOVB, C_LEXT, C_NONE, C_REG, 36, 12, REGSB}, 154 {AMOVBU, C_LEXT, C_NONE, C_REG, 36, 12, REGSB}, 155 {AMOVW, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP}, 156 {AMOVWU, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP}, 157 {AMOVV, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP}, 158 {AMOVB, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP}, 159 {AMOVBU, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP}, 160 {AMOVW, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO}, 161 {AMOVWU, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO}, 162 {AMOVV, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO}, 163 {AMOVB, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO}, 164 {AMOVBU, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO}, 165 {AMOVW, C_ADDR, C_NONE, C_REG, 51, 12, 0}, 166 {AMOVWU, C_ADDR, C_NONE, C_REG, 51, 12, 0}, 167 {AMOVV, C_ADDR, C_NONE, C_REG, 51, 12, 0}, 168 {AMOVB, C_ADDR, C_NONE, C_REG, 51, 12, 0}, 169 {AMOVBU, C_ADDR, C_NONE, C_REG, 51, 12, 0}, 170 {AMOVW, C_TLS, C_NONE, C_REG, 54, 8, 0}, 171 {AMOVWU, C_TLS, C_NONE, C_REG, 54, 8, 0}, 172 {AMOVV, C_TLS, C_NONE, C_REG, 54, 8, 0}, 173 {AMOVB, C_TLS, C_NONE, C_REG, 54, 8, 0}, 174 {AMOVBU, C_TLS, C_NONE, C_REG, 54, 8, 0}, 175 176 {AMOVW, C_SECON, C_NONE, C_REG, 3, 4, REGSB}, 177 {AMOVV, C_SECON, C_NONE, C_REG, 3, 4, REGSB}, 178 {AMOVW, C_SACON, C_NONE, C_REG, 3, 4, REGSP}, 179 {AMOVV, C_SACON, C_NONE, C_REG, 3, 4, REGSP}, 180 {AMOVW, C_LECON, C_NONE, C_REG, 52, 12, REGSB}, 181 {AMOVV, C_LECON, C_NONE, C_REG, 52, 12, REGSB}, 182 {AMOVW, C_LACON, C_NONE, C_REG, 26, 12, REGSP}, 183 {AMOVV, C_LACON, C_NONE, C_REG, 26, 12, REGSP}, 184 {AMOVW, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO}, 185 {AMOVV, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO}, 186 {AMOVW, C_ANDCON, C_NONE, C_REG, 3, 4, REGZERO}, 187 {AMOVV, C_ANDCON, C_NONE, C_REG, 3, 4, REGZERO}, 188 {AMOVW, C_STCON, C_NONE, C_REG, 55, 8, 0}, 189 {AMOVV, C_STCON, C_NONE, C_REG, 55, 8, 0}, 190 191 {AMOVW, C_UCON, C_NONE, C_REG, 24, 4, 0}, 192 {AMOVV, C_UCON, C_NONE, C_REG, 24, 4, 0}, 193 {AMOVW, C_LCON, C_NONE, C_REG, 19, 8, 0}, 194 {AMOVV, C_LCON, C_NONE, C_REG, 19, 8, 0}, 195 196 {AMOVW, C_HI, C_NONE, C_REG, 20, 4, 0}, 197 {AMOVV, C_HI, C_NONE, C_REG, 20, 4, 0}, 198 {AMOVW, C_LO, C_NONE, C_REG, 20, 4, 0}, 199 {AMOVV, C_LO, C_NONE, C_REG, 20, 4, 0}, 200 {AMOVW, C_REG, C_NONE, C_HI, 21, 4, 0}, 201 {AMOVV, C_REG, C_NONE, C_HI, 21, 4, 0}, 202 {AMOVW, C_REG, C_NONE, C_LO, 21, 4, 0}, 203 {AMOVV, C_REG, C_NONE, C_LO, 21, 4, 0}, 204 205 {AMUL, C_REG, C_REG, C_NONE, 22, 4, 0}, 206 207 {AADD, C_ADD0CON, C_REG, C_REG, 4, 4, 0}, 208 {AADD, C_ADD0CON, C_NONE, C_REG, 4, 4, 0}, 209 {AADD, C_ANDCON, C_REG, C_REG, 10, 8, 0}, 210 {AADD, C_ANDCON, C_NONE, C_REG, 10, 8, 0}, 211 212 {AAND, C_AND0CON, C_REG, C_REG, 4, 4, 0}, 213 {AAND, C_AND0CON, C_NONE, C_REG, 4, 4, 0}, 214 {AAND, C_ADDCON, C_REG, C_REG, 10, 8, 0}, 215 {AAND, C_ADDCON, C_NONE, C_REG, 10, 8, 0}, 216 217 {AADD, C_UCON, C_REG, C_REG, 25, 8, 0}, 218 {AADD, C_UCON, C_NONE, C_REG, 25, 8, 0}, 219 {AAND, C_UCON, C_REG, C_REG, 25, 8, 0}, 220 {AAND, C_UCON, C_NONE, C_REG, 25, 8, 0}, 221 222 {AADD, C_LCON, C_NONE, C_REG, 23, 12, 0}, 223 {AAND, C_LCON, C_NONE, C_REG, 23, 12, 0}, 224 {AADD, C_LCON, C_REG, C_REG, 23, 12, 0}, 225 {AAND, C_LCON, C_REG, C_REG, 23, 12, 0}, 226 227 {ASLL, C_SCON, C_REG, C_REG, 16, 4, 0}, 228 {ASLL, C_SCON, C_NONE, C_REG, 16, 4, 0}, 229 230 {ASYSCALL, C_NONE, C_NONE, C_NONE, 5, 4, 0}, 231 232 {ABEQ, C_REG, C_REG, C_SBRA, 6, 4, 0}, 233 {ABEQ, C_REG, C_NONE, C_SBRA, 6, 4, 0}, 234 {ABLEZ, C_REG, C_NONE, C_SBRA, 6, 4, 0}, 235 {ABFPT, C_NONE, C_NONE, C_SBRA, 6, 8, 0}, 236 237 {AJMP, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, 238 {AJAL, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, 239 240 {AJMP, C_NONE, C_NONE, C_ZOREG, 18, 4, REGZERO}, 241 {AJAL, C_NONE, C_NONE, C_ZOREG, 18, 4, REGLINK}, 242 243 {AMOVW, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB}, 244 {AMOVF, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB}, 245 {AMOVD, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB}, 246 {AMOVW, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP}, 247 {AMOVF, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP}, 248 {AMOVD, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP}, 249 {AMOVW, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO}, 250 {AMOVF, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO}, 251 {AMOVD, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO}, 252 253 {AMOVW, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB}, 254 {AMOVF, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB}, 255 {AMOVD, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB}, 256 {AMOVW, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP}, 257 {AMOVF, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP}, 258 {AMOVD, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP}, 259 {AMOVW, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO}, 260 {AMOVF, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO}, 261 {AMOVD, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO}, 262 {AMOVF, C_ADDR, C_NONE, C_FREG, 51, 12, 0}, 263 {AMOVD, C_ADDR, C_NONE, C_FREG, 51, 12, 0}, 264 265 {AMOVW, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB}, 266 {AMOVF, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB}, 267 {AMOVD, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB}, 268 {AMOVW, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP}, 269 {AMOVF, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP}, 270 {AMOVD, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP}, 271 {AMOVW, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO}, 272 {AMOVF, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO}, 273 {AMOVD, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO}, 274 275 {AMOVW, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB}, 276 {AMOVF, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB}, 277 {AMOVD, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB}, 278 {AMOVW, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP}, 279 {AMOVF, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP}, 280 {AMOVD, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP}, 281 {AMOVW, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO}, 282 {AMOVF, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO}, 283 {AMOVD, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO}, 284 {AMOVF, C_FREG, C_NONE, C_ADDR, 50, 12, 0}, 285 {AMOVD, C_FREG, C_NONE, C_ADDR, 50, 12, 0}, 286 287 {AMOVW, C_REG, C_NONE, C_FREG, 30, 4, 0}, 288 {AMOVW, C_FREG, C_NONE, C_REG, 31, 4, 0}, 289 {AMOVV, C_REG, C_NONE, C_FREG, 47, 4, 0}, 290 {AMOVV, C_FREG, C_NONE, C_REG, 48, 4, 0}, 291 292 {AMOVW, C_ADDCON, C_NONE, C_FREG, 34, 8, 0}, 293 {AMOVW, C_ANDCON, C_NONE, C_FREG, 34, 8, 0}, 294 295 {AMOVW, C_REG, C_NONE, C_MREG, 37, 4, 0}, 296 {AMOVV, C_REG, C_NONE, C_MREG, 37, 4, 0}, 297 {AMOVW, C_MREG, C_NONE, C_REG, 38, 4, 0}, 298 {AMOVV, C_MREG, C_NONE, C_REG, 38, 4, 0}, 299 300 {AWORD, C_LCON, C_NONE, C_NONE, 40, 4, 0}, 301 302 {AMOVW, C_REG, C_NONE, C_FCREG, 41, 8, 0}, 303 {AMOVV, C_REG, C_NONE, C_FCREG, 41, 8, 0}, 304 {AMOVW, C_FCREG, C_NONE, C_REG, 42, 4, 0}, 305 {AMOVV, C_FCREG, C_NONE, C_REG, 42, 4, 0}, 306 307 {ABREAK, C_REG, C_NONE, C_SEXT, 7, 4, REGSB}, /* really CACHE instruction */ 308 {ABREAK, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP}, 309 {ABREAK, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO}, 310 {ABREAK, C_NONE, C_NONE, C_NONE, 5, 4, 0}, 311 312 {obj.AUNDEF, C_NONE, C_NONE, C_NONE, 49, 4, 0}, 313 {obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, 0, 0, 0}, 314 {obj.APCDATA, C_LCON, C_NONE, C_LCON, 0, 0, 0}, 315 {obj.AFUNCDATA, C_SCON, C_NONE, C_ADDR, 0, 0, 0}, 316 {obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0}, 317 {obj.ADUFFZERO, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as AJMP 318 {obj.ADUFFCOPY, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as AJMP 319 320 {obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0}, 321 } 322 323 var oprange [ALAST & obj.AMask][]Optab 324 325 var xcmp [C_NCLASS][C_NCLASS]bool 326 327 func span0(ctxt *obj.Link, cursym *obj.LSym) { 328 p := cursym.Text 329 if p == nil || p.Link == nil { // handle external functions and ELF section symbols 330 return 331 } 332 ctxt.Cursym = cursym 333 ctxt.Autosize = int32(p.To.Offset + 8) 334 335 if oprange[AOR&obj.AMask] == nil { 336 buildop(ctxt) 337 } 338 339 c := int64(0) 340 p.Pc = c 341 342 var m int 343 var o *Optab 344 for p = p.Link; p != nil; p = p.Link { 345 ctxt.Curp = p 346 p.Pc = c 347 o = oplook(ctxt, p) 348 m = int(o.size) 349 if m == 0 { 350 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD { 351 ctxt.Diag("zero-width instruction\n%v", p) 352 } 353 continue 354 } 355 356 c += int64(m) 357 } 358 359 cursym.Size = c 360 361 /* 362 * if any procedure is large enough to 363 * generate a large SBRA branch, then 364 * generate extra passes putting branches 365 * around jmps to fix. this is rare. 366 */ 367 bflag := 1 368 369 var otxt int64 370 var q *obj.Prog 371 for bflag != 0 { 372 if ctxt.Debugvlog != 0 { 373 fmt.Fprintf(ctxt.Bso, "%5.2f span1\n", obj.Cputime()) 374 } 375 bflag = 0 376 c = 0 377 for p = cursym.Text.Link; p != nil; p = p.Link { 378 p.Pc = c 379 o = oplook(ctxt, p) 380 381 // very large conditional branches 382 if o.type_ == 6 && p.Pcond != nil { 383 otxt = p.Pcond.Pc - c 384 if otxt < -(1<<17)+10 || otxt >= (1<<17)-10 { 385 q = ctxt.NewProg() 386 q.Link = p.Link 387 p.Link = q 388 q.As = AJMP 389 q.Lineno = p.Lineno 390 q.To.Type = obj.TYPE_BRANCH 391 q.Pcond = p.Pcond 392 p.Pcond = q 393 q = ctxt.NewProg() 394 q.Link = p.Link 395 p.Link = q 396 q.As = AJMP 397 q.Lineno = p.Lineno 398 q.To.Type = obj.TYPE_BRANCH 399 q.Pcond = q.Link.Link 400 401 addnop(ctxt, p.Link) 402 addnop(ctxt, p) 403 bflag = 1 404 } 405 } 406 407 m = int(o.size) 408 if m == 0 { 409 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD { 410 ctxt.Diag("zero-width instruction\n%v", p) 411 } 412 continue 413 } 414 415 c += int64(m) 416 } 417 418 cursym.Size = c 419 } 420 421 c += -c & (FuncAlign - 1) 422 cursym.Size = c 423 424 /* 425 * lay out the code, emitting code and data relocations. 426 */ 427 428 cursym.Grow(cursym.Size) 429 430 bp := cursym.P 431 var i int32 432 var out [4]uint32 433 for p := cursym.Text.Link; p != nil; p = p.Link { 434 ctxt.Pc = p.Pc 435 ctxt.Curp = p 436 o = oplook(ctxt, p) 437 if int(o.size) > 4*len(out) { 438 log.Fatalf("out array in span0 is too small, need at least %d for %v", o.size/4, p) 439 } 440 asmout(ctxt, p, o, out[:]) 441 for i = 0; i < int32(o.size/4); i++ { 442 ctxt.Arch.ByteOrder.PutUint32(bp, out[i]) 443 bp = bp[4:] 444 } 445 } 446 } 447 448 func isint32(v int64) bool { 449 return int64(int32(v)) == v 450 } 451 452 func isuint32(v uint64) bool { 453 return uint64(uint32(v)) == v 454 } 455 456 func aclass(ctxt *obj.Link, a *obj.Addr) int { 457 switch a.Type { 458 case obj.TYPE_NONE: 459 return C_NONE 460 461 case obj.TYPE_REG: 462 if REG_R0 <= a.Reg && a.Reg <= REG_R31 { 463 return C_REG 464 } 465 if REG_F0 <= a.Reg && a.Reg <= REG_F31 { 466 return C_FREG 467 } 468 if REG_M0 <= a.Reg && a.Reg <= REG_M31 { 469 return C_MREG 470 } 471 if REG_FCR0 <= a.Reg && a.Reg <= REG_FCR31 { 472 return C_FCREG 473 } 474 if a.Reg == REG_LO { 475 return C_LO 476 } 477 if a.Reg == REG_HI { 478 return C_HI 479 } 480 return C_GOK 481 482 case obj.TYPE_MEM: 483 switch a.Name { 484 case obj.NAME_EXTERN, 485 obj.NAME_STATIC: 486 if a.Sym == nil { 487 break 488 } 489 ctxt.Instoffset = a.Offset 490 if a.Sym != nil { // use relocation 491 if a.Sym.Type == obj.STLSBSS { 492 return C_TLS 493 } 494 return C_ADDR 495 } 496 return C_LEXT 497 498 case obj.NAME_AUTO: 499 ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset 500 if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { 501 return C_SAUTO 502 } 503 return C_LAUTO 504 505 case obj.NAME_PARAM: 506 ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8 507 if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { 508 return C_SAUTO 509 } 510 return C_LAUTO 511 512 case obj.NAME_NONE: 513 ctxt.Instoffset = a.Offset 514 if ctxt.Instoffset == 0 { 515 return C_ZOREG 516 } 517 if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { 518 return C_SOREG 519 } 520 return C_LOREG 521 } 522 523 return C_GOK 524 525 case obj.TYPE_TEXTSIZE: 526 return C_TEXTSIZE 527 528 case obj.TYPE_CONST, 529 obj.TYPE_ADDR: 530 switch a.Name { 531 case obj.NAME_NONE: 532 ctxt.Instoffset = a.Offset 533 if a.Reg != 0 { 534 if -BIG <= ctxt.Instoffset && ctxt.Instoffset <= BIG { 535 return C_SACON 536 } 537 if isint32(ctxt.Instoffset) { 538 return C_LACON 539 } 540 return C_DACON 541 } 542 543 goto consize 544 545 case obj.NAME_EXTERN, 546 obj.NAME_STATIC: 547 s := a.Sym 548 if s == nil { 549 break 550 } 551 if s.Type == obj.SCONST { 552 ctxt.Instoffset = a.Offset 553 goto consize 554 } 555 556 ctxt.Instoffset = a.Offset 557 if s.Type == obj.STLSBSS { 558 return C_STCON // address of TLS variable 559 } 560 return C_LECON 561 562 case obj.NAME_AUTO: 563 ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset 564 if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { 565 return C_SACON 566 } 567 return C_LACON 568 569 case obj.NAME_PARAM: 570 ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8 571 if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { 572 return C_SACON 573 } 574 return C_LACON 575 } 576 577 return C_GOK 578 579 consize: 580 if ctxt.Instoffset >= 0 { 581 if ctxt.Instoffset == 0 { 582 return C_ZCON 583 } 584 if ctxt.Instoffset <= 0x7fff { 585 return C_SCON 586 } 587 if ctxt.Instoffset <= 0xffff { 588 return C_ANDCON 589 } 590 if ctxt.Instoffset&0xffff == 0 && isuint32(uint64(ctxt.Instoffset)) { /* && (instoffset & (1<<31)) == 0) */ 591 return C_UCON 592 } 593 if isint32(ctxt.Instoffset) || isuint32(uint64(ctxt.Instoffset)) { 594 return C_LCON 595 } 596 return C_LCON // C_DCON 597 } 598 599 if ctxt.Instoffset >= -0x8000 { 600 return C_ADDCON 601 } 602 if ctxt.Instoffset&0xffff == 0 && isint32(ctxt.Instoffset) { 603 return C_UCON 604 } 605 if isint32(ctxt.Instoffset) { 606 return C_LCON 607 } 608 return C_LCON // C_DCON 609 610 case obj.TYPE_BRANCH: 611 return C_SBRA 612 } 613 614 return C_GOK 615 } 616 617 func prasm(p *obj.Prog) { 618 fmt.Printf("%v\n", p) 619 } 620 621 func oplook(ctxt *obj.Link, p *obj.Prog) *Optab { 622 if oprange[AOR&obj.AMask] == nil { 623 buildop(ctxt) 624 } 625 626 a1 := int(p.Optab) 627 if a1 != 0 { 628 return &optab[a1-1] 629 } 630 a1 = int(p.From.Class) 631 if a1 == 0 { 632 a1 = aclass(ctxt, &p.From) + 1 633 p.From.Class = int8(a1) 634 } 635 636 a1-- 637 a3 := int(p.To.Class) 638 if a3 == 0 { 639 a3 = aclass(ctxt, &p.To) + 1 640 p.To.Class = int8(a3) 641 } 642 643 a3-- 644 a2 := C_NONE 645 if p.Reg != 0 { 646 a2 = C_REG 647 } 648 649 //print("oplook %P %d %d %d\n", p, a1, a2, a3); 650 651 ops := oprange[p.As&obj.AMask] 652 c1 := &xcmp[a1] 653 c3 := &xcmp[a3] 654 for i := range ops { 655 op := &ops[i] 656 if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] { 657 p.Optab = uint16(cap(optab) - cap(ops) + i + 1) 658 return op 659 } 660 } 661 662 ctxt.Diag("illegal combination %v %v %v %v", obj.Aconv(p.As), DRconv(a1), DRconv(a2), DRconv(a3)) 663 prasm(p) 664 if ops == nil { 665 ops = optab 666 } 667 return &ops[0] 668 } 669 670 func cmp(a int, b int) bool { 671 if a == b { 672 return true 673 } 674 switch a { 675 case C_LCON: 676 if b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON { 677 return true 678 } 679 680 case C_ADD0CON: 681 if b == C_ADDCON { 682 return true 683 } 684 fallthrough 685 686 case C_ADDCON: 687 if b == C_ZCON || b == C_SCON { 688 return true 689 } 690 691 case C_AND0CON: 692 if b == C_ANDCON { 693 return true 694 } 695 fallthrough 696 697 case C_ANDCON: 698 if b == C_ZCON || b == C_SCON { 699 return true 700 } 701 702 case C_UCON: 703 if b == C_ZCON { 704 return true 705 } 706 707 case C_SCON: 708 if b == C_ZCON { 709 return true 710 } 711 712 case C_LACON: 713 if b == C_SACON { 714 return true 715 } 716 717 case C_LBRA: 718 if b == C_SBRA { 719 return true 720 } 721 722 case C_LEXT: 723 if b == C_SEXT { 724 return true 725 } 726 727 case C_LAUTO: 728 if b == C_SAUTO { 729 return true 730 } 731 732 case C_REG: 733 if b == C_ZCON { 734 return r0iszero != 0 /*TypeKind(100016)*/ 735 } 736 737 case C_LOREG: 738 if b == C_ZOREG || b == C_SOREG { 739 return true 740 } 741 742 case C_SOREG: 743 if b == C_ZOREG { 744 return true 745 } 746 } 747 748 return false 749 } 750 751 type ocmp []Optab 752 753 func (x ocmp) Len() int { 754 return len(x) 755 } 756 757 func (x ocmp) Swap(i, j int) { 758 x[i], x[j] = x[j], x[i] 759 } 760 761 func (x ocmp) Less(i, j int) bool { 762 p1 := &x[i] 763 p2 := &x[j] 764 n := int(p1.as) - int(p2.as) 765 if n != 0 { 766 return n < 0 767 } 768 n = int(p1.a1) - int(p2.a1) 769 if n != 0 { 770 return n < 0 771 } 772 n = int(p1.a2) - int(p2.a2) 773 if n != 0 { 774 return n < 0 775 } 776 n = int(p1.a3) - int(p2.a3) 777 if n != 0 { 778 return n < 0 779 } 780 return false 781 } 782 783 func opset(a, b0 obj.As) { 784 oprange[a&obj.AMask] = oprange[b0] 785 } 786 787 func buildop(ctxt *obj.Link) { 788 var n int 789 790 for i := 0; i < C_NCLASS; i++ { 791 for n = 0; n < C_NCLASS; n++ { 792 if cmp(n, i) { 793 xcmp[i][n] = true 794 } 795 } 796 } 797 for n = 0; optab[n].as != obj.AXXX; n++ { 798 } 799 sort.Sort(ocmp(optab[:n])) 800 for i := 0; i < n; i++ { 801 r := optab[i].as 802 r0 := r & obj.AMask 803 start := i 804 for optab[i].as == r { 805 i++ 806 } 807 oprange[r0] = optab[start:i] 808 i-- 809 810 switch r { 811 default: 812 ctxt.Diag("unknown op in build: %v", obj.Aconv(r)) 813 log.Fatalf("bad code") 814 815 case AABSF: 816 opset(AMOVFD, r0) 817 opset(AMOVDF, r0) 818 opset(AMOVWF, r0) 819 opset(AMOVFW, r0) 820 opset(AMOVWD, r0) 821 opset(AMOVDW, r0) 822 opset(ANEGF, r0) 823 opset(ANEGD, r0) 824 opset(AABSD, r0) 825 opset(ATRUNCDW, r0) 826 opset(ATRUNCFW, r0) 827 opset(ATRUNCDV, r0) 828 opset(ATRUNCFV, r0) 829 opset(AMOVVF, r0) 830 opset(AMOVFV, r0) 831 opset(AMOVVD, r0) 832 opset(AMOVDV, r0) 833 834 case AADD: 835 opset(ASGT, r0) 836 opset(ASGTU, r0) 837 opset(AADDU, r0) 838 opset(AADDV, r0) 839 opset(AADDVU, r0) 840 841 case AADDF: 842 opset(ADIVF, r0) 843 opset(ADIVD, r0) 844 opset(AMULF, r0) 845 opset(AMULD, r0) 846 opset(ASUBF, r0) 847 opset(ASUBD, r0) 848 opset(AADDD, r0) 849 850 case AAND: 851 opset(AOR, r0) 852 opset(AXOR, r0) 853 854 case ABEQ: 855 opset(ABNE, r0) 856 857 case ABLEZ: 858 opset(ABGEZ, r0) 859 opset(ABGEZAL, r0) 860 opset(ABLTZ, r0) 861 opset(ABLTZAL, r0) 862 opset(ABGTZ, r0) 863 864 case AMOVB: 865 opset(AMOVH, r0) 866 867 case AMOVBU: 868 opset(AMOVHU, r0) 869 870 case AMUL: 871 opset(AREM, r0) 872 opset(AREMU, r0) 873 opset(ADIVU, r0) 874 opset(AMULU, r0) 875 opset(ADIV, r0) 876 opset(ADIVV, r0) 877 opset(ADIVVU, r0) 878 opset(AMULV, r0) 879 opset(AMULVU, r0) 880 opset(AREMV, r0) 881 opset(AREMVU, r0) 882 883 case ASLL: 884 opset(ASRL, r0) 885 opset(ASRA, r0) 886 opset(ASLLV, r0) 887 opset(ASRAV, r0) 888 opset(ASRLV, r0) 889 890 case ASUB: 891 opset(ASUBU, r0) 892 opset(ASUBV, r0) 893 opset(ASUBVU, r0) 894 opset(ANOR, r0) 895 896 case ASYSCALL: 897 opset(ATLBP, r0) 898 opset(ATLBR, r0) 899 opset(ATLBWI, r0) 900 opset(ATLBWR, r0) 901 902 case ACMPEQF: 903 opset(ACMPGTF, r0) 904 opset(ACMPGTD, r0) 905 opset(ACMPGEF, r0) 906 opset(ACMPGED, r0) 907 opset(ACMPEQD, r0) 908 909 case ABFPT: 910 opset(ABFPF, r0) 911 912 case AMOVWL: 913 opset(AMOVWR, r0) 914 opset(AMOVVR, r0) 915 opset(AMOVVL, r0) 916 917 case AMOVW, 918 AMOVD, 919 AMOVF, 920 AMOVV, 921 ABREAK, 922 ARFE, 923 AJAL, 924 AJMP, 925 AMOVWU, 926 AWORD, 927 obj.ANOP, 928 obj.ATEXT, 929 obj.AUNDEF, 930 obj.AUSEFIELD, 931 obj.AFUNCDATA, 932 obj.APCDATA, 933 obj.ADUFFZERO, 934 obj.ADUFFCOPY: 935 break 936 } 937 } 938 } 939 940 func OP(x uint32, y uint32) uint32 { 941 return x<<3 | y<<0 942 } 943 944 func SP(x uint32, y uint32) uint32 { 945 return x<<29 | y<<26 946 } 947 948 func BCOND(x uint32, y uint32) uint32 { 949 return x<<19 | y<<16 950 } 951 952 func MMU(x uint32, y uint32) uint32 { 953 return SP(2, 0) | 16<<21 | x<<3 | y<<0 954 } 955 956 func FPF(x uint32, y uint32) uint32 { 957 return SP(2, 1) | 16<<21 | x<<3 | y<<0 958 } 959 960 func FPD(x uint32, y uint32) uint32 { 961 return SP(2, 1) | 17<<21 | x<<3 | y<<0 962 } 963 964 func FPW(x uint32, y uint32) uint32 { 965 return SP(2, 1) | 20<<21 | x<<3 | y<<0 966 } 967 968 func FPV(x uint32, y uint32) uint32 { 969 return SP(2, 1) | 21<<21 | x<<3 | y<<0 970 } 971 972 func OP_RRR(op uint32, r1 uint32, r2 uint32, r3 uint32) uint32 { 973 return op | (r1&31)<<16 | (r2&31)<<21 | (r3&31)<<11 974 } 975 976 func OP_IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 { 977 return op | i&0xFFFF | (r2&31)<<21 | (r3&31)<<16 978 } 979 980 func OP_SRR(op uint32, s uint32, r2 uint32, r3 uint32) uint32 { 981 return op | (s&31)<<6 | (r2&31)<<16 | (r3&31)<<11 982 } 983 984 func OP_FRRR(op uint32, r1 uint32, r2 uint32, r3 uint32) uint32 { 985 return op | (r1&31)<<16 | (r2&31)<<11 | (r3&31)<<6 986 } 987 988 func OP_JMP(op uint32, i uint32) uint32 { 989 return op | i&0x3FFFFFF 990 } 991 992 func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { 993 o1 := uint32(0) 994 o2 := uint32(0) 995 o3 := uint32(0) 996 o4 := uint32(0) 997 998 switch o.type_ { 999 default: 1000 ctxt.Diag("unknown type %d %v", o.type_) 1001 prasm(p) 1002 1003 case 0: /* pseudo ops */ 1004 break 1005 1006 case 1: /* mov r1,r2 ==> OR r1,r0,r2 */ 1007 a := AOR 1008 if p.As == AMOVW { 1009 a = AADDU // sign-extended to high 32 bits 1010 } 1011 o1 = OP_RRR(oprrr(ctxt, a), uint32(p.From.Reg), uint32(REGZERO), uint32(p.To.Reg)) 1012 1013 case 2: /* add/sub r1,[r2],r3 */ 1014 r := int(p.Reg) 1015 1016 if r == 0 { 1017 r = int(p.To.Reg) 1018 } 1019 o1 = OP_RRR(oprrr(ctxt, p.As), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg)) 1020 1021 case 3: /* mov $soreg, r ==> or/add $i,o,r */ 1022 v := regoff(ctxt, &p.From) 1023 1024 r := int(p.From.Reg) 1025 if r == 0 { 1026 r = int(o.param) 1027 } 1028 a := AADDVU 1029 if o.a1 == C_ANDCON { 1030 a = AOR 1031 } 1032 1033 o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(r), uint32(p.To.Reg)) 1034 1035 case 4: /* add $scon,[r1],r2 */ 1036 v := regoff(ctxt, &p.From) 1037 1038 r := int(p.Reg) 1039 if r == 0 { 1040 r = int(p.To.Reg) 1041 } 1042 1043 o1 = OP_IRR(opirr(ctxt, p.As), uint32(v), uint32(r), uint32(p.To.Reg)) 1044 1045 case 5: /* syscall */ 1046 o1 = oprrr(ctxt, p.As) 1047 1048 case 6: /* beq r1,[r2],sbra */ 1049 v := int32(0) 1050 if p.Pcond == nil { 1051 v = int32(-4) >> 2 1052 } else { 1053 v = int32(p.Pcond.Pc-p.Pc-4) >> 2 1054 } 1055 if (v<<16)>>16 != v { 1056 ctxt.Diag("short branch too far\n%v", p) 1057 } 1058 o1 = OP_IRR(opirr(ctxt, p.As), uint32(v), uint32(p.From.Reg), uint32(p.Reg)) 1059 // for ABFPT and ABFPF only: always fill delay slot with 0 1060 // see comments in func preprocess for details. 1061 o2 = 0 1062 1063 case 7: /* mov r, soreg ==> sw o(r) */ 1064 r := int(p.To.Reg) 1065 if r == 0 { 1066 r = int(o.param) 1067 } 1068 v := regoff(ctxt, &p.To) 1069 o1 = OP_IRR(opirr(ctxt, p.As), uint32(v), uint32(r), uint32(p.From.Reg)) 1070 1071 case 8: /* mov soreg, r ==> lw o(r) */ 1072 r := int(p.From.Reg) 1073 if r == 0 { 1074 r = int(o.param) 1075 } 1076 v := regoff(ctxt, &p.From) 1077 o1 = OP_IRR(opirr(ctxt, -p.As), uint32(v), uint32(r), uint32(p.To.Reg)) 1078 1079 case 9: /* sll r1,[r2],r3 */ 1080 r := int(p.Reg) 1081 1082 if r == 0 { 1083 r = int(p.To.Reg) 1084 } 1085 o1 = OP_RRR(oprrr(ctxt, p.As), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg)) 1086 1087 case 10: /* add $con,[r1],r2 ==> mov $con, t; add t,[r1],r2 */ 1088 v := regoff(ctxt, &p.From) 1089 a := AOR 1090 if v < 0 { 1091 a = AADDU 1092 } 1093 o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(0), uint32(REGTMP)) 1094 r := int(p.Reg) 1095 if r == 0 { 1096 r = int(p.To.Reg) 1097 } 1098 o2 = OP_RRR(oprrr(ctxt, p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg)) 1099 1100 case 11: /* jmp lbra */ 1101 v := int32(0) 1102 if aclass(ctxt, &p.To) == C_SBRA && p.To.Sym == nil && p.As == AJMP { 1103 // use PC-relative branch for short branches 1104 // BEQ R0, R0, sbra 1105 if p.Pcond == nil { 1106 v = int32(-4) >> 2 1107 } else { 1108 v = int32(p.Pcond.Pc-p.Pc-4) >> 2 1109 } 1110 if (v<<16)>>16 == v { 1111 o1 = OP_IRR(opirr(ctxt, ABEQ), uint32(v), uint32(REGZERO), uint32(REGZERO)) 1112 break 1113 } 1114 } 1115 if p.Pcond == nil { 1116 v = int32(p.Pc) >> 2 1117 } else { 1118 v = int32(p.Pcond.Pc) >> 2 1119 } 1120 o1 = OP_JMP(opirr(ctxt, p.As), uint32(v)) 1121 if p.To.Sym == nil { 1122 p.To.Sym = ctxt.Cursym.Text.From.Sym 1123 p.To.Offset = p.Pcond.Pc 1124 } 1125 rel := obj.Addrel(ctxt.Cursym) 1126 rel.Off = int32(ctxt.Pc) 1127 rel.Siz = 4 1128 rel.Sym = p.To.Sym 1129 rel.Add = p.To.Offset 1130 if p.As == AJAL { 1131 rel.Type = obj.R_CALLMIPS 1132 } else { 1133 rel.Type = obj.R_JMPMIPS 1134 } 1135 1136 case 12: /* movbs r,r */ 1137 v := 16 1138 if p.As == AMOVB { 1139 v = 24 1140 } 1141 o1 = OP_SRR(opirr(ctxt, ASLL), uint32(v), uint32(p.From.Reg), uint32(p.To.Reg)) 1142 o2 = OP_SRR(opirr(ctxt, ASRA), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg)) 1143 1144 case 13: /* movbu r,r */ 1145 if p.As == AMOVBU { 1146 o1 = OP_IRR(opirr(ctxt, AAND), uint32(0xff), uint32(p.From.Reg), uint32(p.To.Reg)) 1147 } else { 1148 o1 = OP_IRR(opirr(ctxt, AAND), uint32(0xffff), uint32(p.From.Reg), uint32(p.To.Reg)) 1149 } 1150 1151 case 14: /* movwu r,r */ 1152 o1 = OP_SRR(opirr(ctxt, -ASLLV), uint32(0), uint32(p.From.Reg), uint32(p.To.Reg)) 1153 o2 = OP_SRR(opirr(ctxt, -ASRLV), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg)) 1154 1155 case 16: /* sll $c,[r1],r2 */ 1156 v := regoff(ctxt, &p.From) 1157 r := int(p.Reg) 1158 if r == 0 { 1159 r = int(p.To.Reg) 1160 } 1161 1162 /* OP_SRR will use only the low 5 bits of the shift value */ 1163 if v >= 32 && vshift(p.As) { 1164 o1 = OP_SRR(opirr(ctxt, -p.As), uint32(v-32), uint32(r), uint32(p.To.Reg)) 1165 } else { 1166 o1 = OP_SRR(opirr(ctxt, p.As), uint32(v), uint32(r), uint32(p.To.Reg)) 1167 } 1168 1169 case 18: /* jmp [r1],0(r2) */ 1170 r := int(p.Reg) 1171 if r == 0 { 1172 r = int(o.param) 1173 } 1174 o1 = OP_RRR(oprrr(ctxt, p.As), uint32(0), uint32(p.To.Reg), uint32(r)) 1175 rel := obj.Addrel(ctxt.Cursym) 1176 rel.Off = int32(ctxt.Pc) 1177 rel.Siz = 0 1178 rel.Type = obj.R_CALLIND 1179 1180 case 19: /* mov $lcon,r ==> lu+or */ 1181 v := regoff(ctxt, &p.From) 1182 o1 = OP_IRR(opirr(ctxt, ALUI), uint32(v>>16), uint32(REGZERO), uint32(p.To.Reg)) 1183 o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg)) 1184 1185 case 20: /* mov lo/hi,r */ 1186 a := OP(2, 0) /* mfhi */ 1187 if p.From.Reg == REG_LO { 1188 a = OP(2, 2) /* mflo */ 1189 } 1190 o1 = OP_RRR(a, uint32(REGZERO), uint32(REGZERO), uint32(p.To.Reg)) 1191 1192 case 21: /* mov r,lo/hi */ 1193 a := OP(2, 1) /* mthi */ 1194 if p.To.Reg == REG_LO { 1195 a = OP(2, 3) /* mtlo */ 1196 } 1197 o1 = OP_RRR(a, uint32(REGZERO), uint32(p.From.Reg), uint32(REGZERO)) 1198 1199 case 22: /* mul r1,r2 */ 1200 o1 = OP_RRR(oprrr(ctxt, p.As), uint32(p.From.Reg), uint32(p.Reg), uint32(REGZERO)) 1201 1202 case 23: /* add $lcon,r1,r2 ==> lu+or+add */ 1203 v := regoff(ctxt, &p.From) 1204 o1 = OP_IRR(opirr(ctxt, ALUI), uint32(v>>16), uint32(REGZERO), uint32(REGTMP)) 1205 o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(REGTMP), uint32(REGTMP)) 1206 r := int(p.Reg) 1207 if r == 0 { 1208 r = int(p.To.Reg) 1209 } 1210 o3 = OP_RRR(oprrr(ctxt, p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg)) 1211 1212 case 24: /* mov $ucon,r ==> lu r */ 1213 v := regoff(ctxt, &p.From) 1214 o1 = OP_IRR(opirr(ctxt, ALUI), uint32(v>>16), uint32(REGZERO), uint32(p.To.Reg)) 1215 1216 case 25: /* add/and $ucon,[r1],r2 ==> lu $con,t; add t,[r1],r2 */ 1217 v := regoff(ctxt, &p.From) 1218 o1 = OP_IRR(opirr(ctxt, ALUI), uint32(v>>16), uint32(REGZERO), uint32(REGTMP)) 1219 r := int(p.Reg) 1220 if r == 0 { 1221 r = int(p.To.Reg) 1222 } 1223 o2 = OP_RRR(oprrr(ctxt, p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg)) 1224 1225 case 26: /* mov $lsext/auto/oreg,r ==> lu+or+add */ 1226 v := regoff(ctxt, &p.From) 1227 o1 = OP_IRR(opirr(ctxt, ALUI), uint32(v>>16), uint32(REGZERO), uint32(REGTMP)) 1228 o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(REGTMP), uint32(REGTMP)) 1229 r := int(p.From.Reg) 1230 if r == 0 { 1231 r = int(o.param) 1232 } 1233 o3 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGTMP), uint32(r), uint32(p.To.Reg)) 1234 1235 case 27: /* mov [sl]ext/auto/oreg,fr ==> lwc1 o(r) */ 1236 v := regoff(ctxt, &p.From) 1237 r := int(p.From.Reg) 1238 if r == 0 { 1239 r = int(o.param) 1240 } 1241 a := -AMOVF 1242 if p.As == AMOVD { 1243 a = -AMOVD 1244 } 1245 switch o.size { 1246 case 12: 1247 o1 = OP_IRR(opirr(ctxt, ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP)) 1248 o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP)) 1249 o3 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(REGTMP), uint32(p.To.Reg)) 1250 1251 case 4: 1252 o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(r), uint32(p.To.Reg)) 1253 } 1254 1255 case 28: /* mov fr,[sl]ext/auto/oreg ==> swc1 o(r) */ 1256 v := regoff(ctxt, &p.To) 1257 r := int(p.To.Reg) 1258 if r == 0 { 1259 r = int(o.param) 1260 } 1261 a := AMOVF 1262 if p.As == AMOVD { 1263 a = AMOVD 1264 } 1265 switch o.size { 1266 case 12: 1267 o1 = OP_IRR(opirr(ctxt, ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP)) 1268 o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP)) 1269 o3 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(REGTMP), uint32(p.From.Reg)) 1270 1271 case 4: 1272 o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(r), uint32(p.From.Reg)) 1273 } 1274 1275 case 30: /* movw r,fr */ 1276 a := SP(2, 1) | (4 << 21) /* mtc1 */ 1277 o1 = OP_RRR(a, uint32(p.From.Reg), uint32(0), uint32(p.To.Reg)) 1278 1279 case 31: /* movw fr,r */ 1280 a := SP(2, 1) | (0 << 21) /* mtc1 */ 1281 o1 = OP_RRR(a, uint32(p.To.Reg), uint32(0), uint32(p.From.Reg)) 1282 1283 case 32: /* fadd fr1,[fr2],fr3 */ 1284 r := int(p.Reg) 1285 if r == 0 { 1286 r = int(p.To.Reg) 1287 } 1288 o1 = OP_FRRR(oprrr(ctxt, p.As), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg)) 1289 1290 case 33: /* fabs fr1, fr3 */ 1291 o1 = OP_FRRR(oprrr(ctxt, p.As), uint32(0), uint32(p.From.Reg), uint32(p.To.Reg)) 1292 1293 case 34: /* mov $con,fr ==> or/add $i,t; mov t,fr */ 1294 v := regoff(ctxt, &p.From) 1295 a := AADDU 1296 if o.a1 == C_ANDCON { 1297 a = AOR 1298 } 1299 o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(0), uint32(REGTMP)) 1300 o2 = OP_RRR(SP(2, 1)|(4<<21), uint32(REGTMP), uint32(0), uint32(p.To.Reg)) /* mtc1 */ 1301 1302 case 35: /* mov r,lext/auto/oreg ==> sw o(REGTMP) */ 1303 v := regoff(ctxt, &p.To) 1304 r := int(p.To.Reg) 1305 if r == 0 { 1306 r = int(o.param) 1307 } 1308 o1 = OP_IRR(opirr(ctxt, ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP)) 1309 o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP)) 1310 o3 = OP_IRR(opirr(ctxt, p.As), uint32(v), uint32(REGTMP), uint32(p.From.Reg)) 1311 1312 case 36: /* mov lext/auto/oreg,r ==> lw o(REGTMP) */ 1313 v := regoff(ctxt, &p.From) 1314 r := int(p.From.Reg) 1315 if r == 0 { 1316 r = int(o.param) 1317 } 1318 o1 = OP_IRR(opirr(ctxt, ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP)) 1319 o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP)) 1320 o3 = OP_IRR(opirr(ctxt, -p.As), uint32(v), uint32(REGTMP), uint32(p.To.Reg)) 1321 1322 case 37: /* movw r,mr */ 1323 a := SP(2, 0) | (4 << 21) /* mtc0 */ 1324 if p.As == AMOVV { 1325 a = SP(2, 0) | (5 << 21) /* dmtc0 */ 1326 } 1327 o1 = OP_RRR(a, uint32(p.From.Reg), uint32(0), uint32(p.To.Reg)) 1328 1329 case 38: /* movw mr,r */ 1330 a := SP(2, 0) | (0 << 21) /* mfc0 */ 1331 if p.As == AMOVV { 1332 a = SP(2, 0) | (1 << 21) /* dmfc0 */ 1333 } 1334 o1 = OP_RRR(a, uint32(p.To.Reg), uint32(0), uint32(p.From.Reg)) 1335 1336 case 40: /* word */ 1337 o1 = uint32(regoff(ctxt, &p.From)) 1338 1339 case 41: /* movw f,fcr */ 1340 o1 = OP_RRR(SP(2, 1)|(2<<21), uint32(REGZERO), uint32(0), uint32(p.To.Reg)) /* mfcc1 */ 1341 o2 = OP_RRR(SP(2, 1)|(6<<21), uint32(p.From.Reg), uint32(0), uint32(p.To.Reg)) /* mtcc1 */ 1342 1343 case 42: /* movw fcr,r */ 1344 o1 = OP_RRR(SP(2, 1)|(2<<21), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg)) /* mfcc1 */ 1345 1346 case 47: /* movv r,fr */ 1347 a := SP(2, 1) | (5 << 21) /* dmtc1 */ 1348 o1 = OP_RRR(a, uint32(p.From.Reg), uint32(0), uint32(p.To.Reg)) 1349 1350 case 48: /* movv fr,r */ 1351 a := SP(2, 1) | (1 << 21) /* dmtc1 */ 1352 o1 = OP_RRR(a, uint32(p.To.Reg), uint32(0), uint32(p.From.Reg)) 1353 1354 case 49: /* undef */ 1355 o1 = 52 /* trap -- teq r0, r0 */ 1356 1357 /* relocation operations */ 1358 case 50: /* mov r,addr ==> lu + add REGSB, REGTMP + sw o(REGTMP) */ 1359 o1 = OP_IRR(opirr(ctxt, ALUI), uint32(0), uint32(REGZERO), uint32(REGTMP)) 1360 rel := obj.Addrel(ctxt.Cursym) 1361 rel.Off = int32(ctxt.Pc) 1362 rel.Siz = 4 1363 rel.Sym = p.To.Sym 1364 rel.Add = p.To.Offset 1365 rel.Type = obj.R_ADDRMIPSU 1366 o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGSB), uint32(REGTMP), uint32(REGTMP)) 1367 o3 = OP_IRR(opirr(ctxt, p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg)) 1368 rel2 := obj.Addrel(ctxt.Cursym) 1369 rel2.Off = int32(ctxt.Pc + 8) 1370 rel2.Siz = 4 1371 rel2.Sym = p.To.Sym 1372 rel2.Add = p.To.Offset 1373 rel2.Type = obj.R_ADDRMIPS 1374 1375 case 51: /* mov addr,r ==> lu + add REGSB, REGTMP + lw o(REGTMP) */ 1376 o1 = OP_IRR(opirr(ctxt, ALUI), uint32(0), uint32(REGZERO), uint32(REGTMP)) 1377 rel := obj.Addrel(ctxt.Cursym) 1378 rel.Off = int32(ctxt.Pc) 1379 rel.Siz = 4 1380 rel.Sym = p.From.Sym 1381 rel.Add = p.From.Offset 1382 rel.Type = obj.R_ADDRMIPSU 1383 o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGSB), uint32(REGTMP), uint32(REGTMP)) 1384 o3 = OP_IRR(opirr(ctxt, -p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg)) 1385 rel2 := obj.Addrel(ctxt.Cursym) 1386 rel2.Off = int32(ctxt.Pc + 8) 1387 rel2.Siz = 4 1388 rel2.Sym = p.From.Sym 1389 rel2.Add = p.From.Offset 1390 rel2.Type = obj.R_ADDRMIPS 1391 1392 case 52: /* mov $lext, r ==> lu + add REGSB, r + add */ 1393 o1 = OP_IRR(opirr(ctxt, ALUI), uint32(0), uint32(REGZERO), uint32(p.To.Reg)) 1394 rel := obj.Addrel(ctxt.Cursym) 1395 rel.Off = int32(ctxt.Pc) 1396 rel.Siz = 4 1397 rel.Sym = p.From.Sym 1398 rel.Add = p.From.Offset 1399 rel.Type = obj.R_ADDRMIPSU 1400 o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGSB), uint32(p.To.Reg), uint32(p.To.Reg)) 1401 o3 = OP_IRR(opirr(ctxt, AADDVU), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg)) 1402 rel2 := obj.Addrel(ctxt.Cursym) 1403 rel2.Off = int32(ctxt.Pc + 8) 1404 rel2.Siz = 4 1405 rel2.Sym = p.From.Sym 1406 rel2.Add = p.From.Offset 1407 rel2.Type = obj.R_ADDRMIPS 1408 1409 case 53: /* mov r, tlsvar ==> rdhwr + sw o(r3) */ 1410 // clobbers R3 ! 1411 // load thread pointer with RDHWR, R3 is used for fast kernel emulation on Linux 1412 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16) // rdhwr $29, r3 1413 o2 = OP_IRR(opirr(ctxt, p.As), uint32(0), uint32(REG_R3), uint32(p.From.Reg)) 1414 rel := obj.Addrel(ctxt.Cursym) 1415 rel.Off = int32(ctxt.Pc + 4) 1416 rel.Siz = 4 1417 rel.Sym = p.To.Sym 1418 rel.Add = p.To.Offset 1419 rel.Type = obj.R_ADDRMIPSTLS 1420 1421 case 54: /* mov tlsvar, r ==> rdhwr + lw o(r3) */ 1422 // clobbers R3 ! 1423 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16) // rdhwr $29, r3 1424 o2 = OP_IRR(opirr(ctxt, -p.As), uint32(0), uint32(REG_R3), uint32(p.To.Reg)) 1425 rel := obj.Addrel(ctxt.Cursym) 1426 rel.Off = int32(ctxt.Pc + 4) 1427 rel.Siz = 4 1428 rel.Sym = p.From.Sym 1429 rel.Add = p.From.Offset 1430 rel.Type = obj.R_ADDRMIPSTLS 1431 1432 case 55: /* mov $tlsvar, r ==> rdhwr + add */ 1433 // clobbers R3 ! 1434 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16) // rdhwr $29, r3 1435 o2 = OP_IRR(opirr(ctxt, AADDVU), uint32(0), uint32(REG_R3), uint32(p.To.Reg)) 1436 rel := obj.Addrel(ctxt.Cursym) 1437 rel.Off = int32(ctxt.Pc + 4) 1438 rel.Siz = 4 1439 rel.Sym = p.From.Sym 1440 rel.Add = p.From.Offset 1441 rel.Type = obj.R_ADDRMIPSTLS 1442 } 1443 1444 out[0] = o1 1445 out[1] = o2 1446 out[2] = o3 1447 out[3] = o4 1448 return 1449 } 1450 1451 func vregoff(ctxt *obj.Link, a *obj.Addr) int64 { 1452 ctxt.Instoffset = 0 1453 aclass(ctxt, a) 1454 return ctxt.Instoffset 1455 } 1456 1457 func regoff(ctxt *obj.Link, a *obj.Addr) int32 { 1458 return int32(vregoff(ctxt, a)) 1459 } 1460 1461 func oprrr(ctxt *obj.Link, a obj.As) uint32 { 1462 switch a { 1463 case AADD: 1464 return OP(4, 0) 1465 case AADDU: 1466 return OP(4, 1) 1467 case ASGT: 1468 return OP(5, 2) 1469 case ASGTU: 1470 return OP(5, 3) 1471 case AAND: 1472 return OP(4, 4) 1473 case AOR: 1474 return OP(4, 5) 1475 case AXOR: 1476 return OP(4, 6) 1477 case ASUB: 1478 return OP(4, 2) 1479 case ASUBU: 1480 return OP(4, 3) 1481 case ANOR: 1482 return OP(4, 7) 1483 case ASLL: 1484 return OP(0, 4) 1485 case ASRL: 1486 return OP(0, 6) 1487 case ASRA: 1488 return OP(0, 7) 1489 case ASLLV: 1490 return OP(2, 4) 1491 case ASRLV: 1492 return OP(2, 6) 1493 case ASRAV: 1494 return OP(2, 7) 1495 case AADDV: 1496 return OP(5, 4) 1497 case AADDVU: 1498 return OP(5, 5) 1499 case ASUBV: 1500 return OP(5, 6) 1501 case ASUBVU: 1502 return OP(5, 7) 1503 case AREM, 1504 ADIV: 1505 return OP(3, 2) 1506 case AREMU, 1507 ADIVU: 1508 return OP(3, 3) 1509 case AMUL: 1510 return OP(3, 0) 1511 case AMULU: 1512 return OP(3, 1) 1513 case AREMV, 1514 ADIVV: 1515 return OP(3, 6) 1516 case AREMVU, 1517 ADIVVU: 1518 return OP(3, 7) 1519 case AMULV: 1520 return OP(3, 4) 1521 case AMULVU: 1522 return OP(3, 5) 1523 1524 case AJMP: 1525 return OP(1, 0) 1526 case AJAL: 1527 return OP(1, 1) 1528 1529 case ABREAK: 1530 return OP(1, 5) 1531 case ASYSCALL: 1532 return OP(1, 4) 1533 case ATLBP: 1534 return MMU(1, 0) 1535 case ATLBR: 1536 return MMU(0, 1) 1537 case ATLBWI: 1538 return MMU(0, 2) 1539 case ATLBWR: 1540 return MMU(0, 6) 1541 case ARFE: 1542 return MMU(2, 0) 1543 1544 case ADIVF: 1545 return FPF(0, 3) 1546 case ADIVD: 1547 return FPD(0, 3) 1548 case AMULF: 1549 return FPF(0, 2) 1550 case AMULD: 1551 return FPD(0, 2) 1552 case ASUBF: 1553 return FPF(0, 1) 1554 case ASUBD: 1555 return FPD(0, 1) 1556 case AADDF: 1557 return FPF(0, 0) 1558 case AADDD: 1559 return FPD(0, 0) 1560 case ATRUNCFV: 1561 return FPF(1, 1) 1562 case ATRUNCDV: 1563 return FPD(1, 1) 1564 case ATRUNCFW: 1565 return FPF(1, 5) 1566 case ATRUNCDW: 1567 return FPD(1, 5) 1568 case AMOVFV: 1569 return FPF(4, 5) 1570 case AMOVDV: 1571 return FPD(4, 5) 1572 case AMOVVF: 1573 return FPV(4, 0) 1574 case AMOVVD: 1575 return FPV(4, 1) 1576 case AMOVFW: 1577 return FPF(4, 4) 1578 case AMOVDW: 1579 return FPD(4, 4) 1580 case AMOVWF: 1581 return FPW(4, 0) 1582 case AMOVDF: 1583 return FPD(4, 0) 1584 case AMOVWD: 1585 return FPW(4, 1) 1586 case AMOVFD: 1587 return FPF(4, 1) 1588 case AABSF: 1589 return FPF(0, 5) 1590 case AABSD: 1591 return FPD(0, 5) 1592 case AMOVF: 1593 return FPF(0, 6) 1594 case AMOVD: 1595 return FPD(0, 6) 1596 case ANEGF: 1597 return FPF(0, 7) 1598 case ANEGD: 1599 return FPD(0, 7) 1600 case ACMPEQF: 1601 return FPF(6, 2) 1602 case ACMPEQD: 1603 return FPD(6, 2) 1604 case ACMPGTF: 1605 return FPF(7, 4) 1606 case ACMPGTD: 1607 return FPD(7, 4) 1608 case ACMPGEF: 1609 return FPF(7, 6) 1610 case ACMPGED: 1611 return FPD(7, 6) 1612 } 1613 1614 if a < 0 { 1615 ctxt.Diag("bad rrr opcode -%v", obj.Aconv(-a)) 1616 } else { 1617 ctxt.Diag("bad rrr opcode %v", obj.Aconv(a)) 1618 } 1619 return 0 1620 } 1621 1622 func opirr(ctxt *obj.Link, a obj.As) uint32 { 1623 switch a { 1624 case AADD: 1625 return SP(1, 0) 1626 case AADDU: 1627 return SP(1, 1) 1628 case ASGT: 1629 return SP(1, 2) 1630 case ASGTU: 1631 return SP(1, 3) 1632 case AAND: 1633 return SP(1, 4) 1634 case AOR: 1635 return SP(1, 5) 1636 case AXOR: 1637 return SP(1, 6) 1638 case ALUI: 1639 return SP(1, 7) 1640 case ASLL: 1641 return OP(0, 0) 1642 case ASRL: 1643 return OP(0, 2) 1644 case ASRA: 1645 return OP(0, 3) 1646 case AADDV: 1647 return SP(3, 0) 1648 case AADDVU: 1649 return SP(3, 1) 1650 1651 case AJMP: 1652 return SP(0, 2) 1653 case AJAL, 1654 obj.ADUFFZERO, 1655 obj.ADUFFCOPY: 1656 return SP(0, 3) 1657 case ABEQ: 1658 return SP(0, 4) 1659 case -ABEQ: 1660 return SP(2, 4) /* likely */ 1661 case ABNE: 1662 return SP(0, 5) 1663 case -ABNE: 1664 return SP(2, 5) /* likely */ 1665 case ABGEZ: 1666 return SP(0, 1) | BCOND(0, 1) 1667 case -ABGEZ: 1668 return SP(0, 1) | BCOND(0, 3) /* likely */ 1669 case ABGEZAL: 1670 return SP(0, 1) | BCOND(2, 1) 1671 case -ABGEZAL: 1672 return SP(0, 1) | BCOND(2, 3) /* likely */ 1673 case ABGTZ: 1674 return SP(0, 7) 1675 case -ABGTZ: 1676 return SP(2, 7) /* likely */ 1677 case ABLEZ: 1678 return SP(0, 6) 1679 case -ABLEZ: 1680 return SP(2, 6) /* likely */ 1681 case ABLTZ: 1682 return SP(0, 1) | BCOND(0, 0) 1683 case -ABLTZ: 1684 return SP(0, 1) | BCOND(0, 2) /* likely */ 1685 case ABLTZAL: 1686 return SP(0, 1) | BCOND(2, 0) 1687 case -ABLTZAL: 1688 return SP(0, 1) | BCOND(2, 2) /* likely */ 1689 case ABFPT: 1690 return SP(2, 1) | (257 << 16) 1691 case -ABFPT: 1692 return SP(2, 1) | (259 << 16) /* likely */ 1693 case ABFPF: 1694 return SP(2, 1) | (256 << 16) 1695 case -ABFPF: 1696 return SP(2, 1) | (258 << 16) /* likely */ 1697 1698 case AMOVB, 1699 AMOVBU: 1700 return SP(5, 0) 1701 case AMOVH, 1702 AMOVHU: 1703 return SP(5, 1) 1704 case AMOVW, 1705 AMOVWU: 1706 return SP(5, 3) 1707 case AMOVV: 1708 return SP(7, 7) 1709 case AMOVF: 1710 return SP(7, 1) 1711 case AMOVD: 1712 return SP(7, 5) 1713 case AMOVWL: 1714 return SP(5, 2) 1715 case AMOVWR: 1716 return SP(5, 6) 1717 case AMOVVL: 1718 return SP(5, 4) 1719 case AMOVVR: 1720 return SP(5, 5) 1721 1722 case ABREAK: 1723 return SP(5, 7) 1724 1725 case -AMOVWL: 1726 return SP(4, 2) 1727 case -AMOVWR: 1728 return SP(4, 6) 1729 case -AMOVVL: 1730 return SP(3, 2) 1731 case -AMOVVR: 1732 return SP(3, 3) 1733 case -AMOVB: 1734 return SP(4, 0) 1735 case -AMOVBU: 1736 return SP(4, 4) 1737 case -AMOVH: 1738 return SP(4, 1) 1739 case -AMOVHU: 1740 return SP(4, 5) 1741 case -AMOVW: 1742 return SP(4, 3) 1743 case -AMOVWU: 1744 return SP(4, 7) 1745 case -AMOVV: 1746 return SP(6, 7) 1747 case -AMOVF: 1748 return SP(6, 1) 1749 case -AMOVD: 1750 return SP(6, 5) 1751 1752 case ASLLV: 1753 return OP(7, 0) 1754 case ASRLV: 1755 return OP(7, 2) 1756 case ASRAV: 1757 return OP(7, 3) 1758 case -ASLLV: 1759 return OP(7, 4) 1760 case -ASRLV: 1761 return OP(7, 6) 1762 case -ASRAV: 1763 return OP(7, 7) 1764 } 1765 1766 if a < 0 { 1767 ctxt.Diag("bad irr opcode -%v", obj.Aconv(-a)) 1768 } else { 1769 ctxt.Diag("bad irr opcode %v", obj.Aconv(a)) 1770 } 1771 return 0 1772 } 1773 1774 func vshift(a obj.As) bool { 1775 switch a { 1776 case ASLLV, 1777 ASRLV, 1778 ASRAV: 1779 return true 1780 } 1781 return false 1782 }