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