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