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