github.com/Rookout/GoSDK@v0.1.48/pkg/services/assembler/internal/obj/arm64/asm7.go (about) 1 // cmd/7l/asm.c, cmd/7l/asmout.c, cmd/7l/optab.c, cmd/7l/span.c, cmd/ld/sub.c, cmd/ld/mod.c, from Vita Nuova. 2 // https://code.google.com/p/ken-cc/source/browse/ 3 // 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 6 // Portions Copyright © 1997-1999 Vita Nuova Limited 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 8 // Portions Copyright © 2004,2006 Bruce Ellis 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 11 // Portions Copyright © 2009 The Go Authors. All rights reserved. 12 // 13 // Permission is hereby granted, free of charge, to any person obtaining a copy 14 // of this software and associated documentation files (the "Software"), to deal 15 // in the Software without restriction, including without limitation the rights 16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 // copies of the Software, and to permit persons to whom the Software is 18 // furnished to do so, subject to the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be included in 21 // all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 // THE SOFTWARE. 30 31 package arm64 32 33 import ( 34 "github.com/Rookout/GoSDK/pkg/services/assembler/internal/obj" 35 "github.com/Rookout/GoSDK/pkg/services/assembler/internal/objabi" 36 "fmt" 37 "log" 38 "math" 39 "sort" 40 "strings" 41 ) 42 43 44 45 46 type ctxt7 struct { 47 ctxt *obj.Link 48 newprog obj.ProgAlloc 49 cursym *obj.LSym 50 blitrl *obj.Prog 51 elitrl *obj.Prog 52 autosize int32 53 extrasize int32 54 instoffset int64 55 pc int64 56 pool struct { 57 start uint32 58 size uint32 59 } 60 } 61 62 const ( 63 funcAlign = 16 64 ) 65 66 const ( 67 REGFROM = 1 68 ) 69 70 type Optab struct { 71 as obj.As 72 a1 uint8 73 a2 uint8 74 a3 uint8 75 a4 uint8 76 type_ int8 77 size_ int8 78 param int16 79 flag int8 80 scond uint16 81 } 82 83 func IsAtomicInstruction(as obj.As) bool { 84 if _, ok := atomicLDADD[as]; ok { 85 return true 86 } 87 if _, ok := atomicSWP[as]; ok { 88 return true 89 } 90 return false 91 } 92 93 94 var atomicLDADD = map[obj.As]uint32{ 95 ALDADDAD: 3<<30 | 0x1c5<<21 | 0x00<<10, 96 ALDADDAW: 2<<30 | 0x1c5<<21 | 0x00<<10, 97 ALDADDAH: 1<<30 | 0x1c5<<21 | 0x00<<10, 98 ALDADDAB: 0<<30 | 0x1c5<<21 | 0x00<<10, 99 ALDADDALD: 3<<30 | 0x1c7<<21 | 0x00<<10, 100 ALDADDALW: 2<<30 | 0x1c7<<21 | 0x00<<10, 101 ALDADDALH: 1<<30 | 0x1c7<<21 | 0x00<<10, 102 ALDADDALB: 0<<30 | 0x1c7<<21 | 0x00<<10, 103 ALDADDD: 3<<30 | 0x1c1<<21 | 0x00<<10, 104 ALDADDW: 2<<30 | 0x1c1<<21 | 0x00<<10, 105 ALDADDH: 1<<30 | 0x1c1<<21 | 0x00<<10, 106 ALDADDB: 0<<30 | 0x1c1<<21 | 0x00<<10, 107 ALDADDLD: 3<<30 | 0x1c3<<21 | 0x00<<10, 108 ALDADDLW: 2<<30 | 0x1c3<<21 | 0x00<<10, 109 ALDADDLH: 1<<30 | 0x1c3<<21 | 0x00<<10, 110 ALDADDLB: 0<<30 | 0x1c3<<21 | 0x00<<10, 111 ALDCLRAD: 3<<30 | 0x1c5<<21 | 0x04<<10, 112 ALDCLRAW: 2<<30 | 0x1c5<<21 | 0x04<<10, 113 ALDCLRAH: 1<<30 | 0x1c5<<21 | 0x04<<10, 114 ALDCLRAB: 0<<30 | 0x1c5<<21 | 0x04<<10, 115 ALDCLRALD: 3<<30 | 0x1c7<<21 | 0x04<<10, 116 ALDCLRALW: 2<<30 | 0x1c7<<21 | 0x04<<10, 117 ALDCLRALH: 1<<30 | 0x1c7<<21 | 0x04<<10, 118 ALDCLRALB: 0<<30 | 0x1c7<<21 | 0x04<<10, 119 ALDCLRD: 3<<30 | 0x1c1<<21 | 0x04<<10, 120 ALDCLRW: 2<<30 | 0x1c1<<21 | 0x04<<10, 121 ALDCLRH: 1<<30 | 0x1c1<<21 | 0x04<<10, 122 ALDCLRB: 0<<30 | 0x1c1<<21 | 0x04<<10, 123 ALDCLRLD: 3<<30 | 0x1c3<<21 | 0x04<<10, 124 ALDCLRLW: 2<<30 | 0x1c3<<21 | 0x04<<10, 125 ALDCLRLH: 1<<30 | 0x1c3<<21 | 0x04<<10, 126 ALDCLRLB: 0<<30 | 0x1c3<<21 | 0x04<<10, 127 ALDEORAD: 3<<30 | 0x1c5<<21 | 0x08<<10, 128 ALDEORAW: 2<<30 | 0x1c5<<21 | 0x08<<10, 129 ALDEORAH: 1<<30 | 0x1c5<<21 | 0x08<<10, 130 ALDEORAB: 0<<30 | 0x1c5<<21 | 0x08<<10, 131 ALDEORALD: 3<<30 | 0x1c7<<21 | 0x08<<10, 132 ALDEORALW: 2<<30 | 0x1c7<<21 | 0x08<<10, 133 ALDEORALH: 1<<30 | 0x1c7<<21 | 0x08<<10, 134 ALDEORALB: 0<<30 | 0x1c7<<21 | 0x08<<10, 135 ALDEORD: 3<<30 | 0x1c1<<21 | 0x08<<10, 136 ALDEORW: 2<<30 | 0x1c1<<21 | 0x08<<10, 137 ALDEORH: 1<<30 | 0x1c1<<21 | 0x08<<10, 138 ALDEORB: 0<<30 | 0x1c1<<21 | 0x08<<10, 139 ALDEORLD: 3<<30 | 0x1c3<<21 | 0x08<<10, 140 ALDEORLW: 2<<30 | 0x1c3<<21 | 0x08<<10, 141 ALDEORLH: 1<<30 | 0x1c3<<21 | 0x08<<10, 142 ALDEORLB: 0<<30 | 0x1c3<<21 | 0x08<<10, 143 ALDORAD: 3<<30 | 0x1c5<<21 | 0x0c<<10, 144 ALDORAW: 2<<30 | 0x1c5<<21 | 0x0c<<10, 145 ALDORAH: 1<<30 | 0x1c5<<21 | 0x0c<<10, 146 ALDORAB: 0<<30 | 0x1c5<<21 | 0x0c<<10, 147 ALDORALD: 3<<30 | 0x1c7<<21 | 0x0c<<10, 148 ALDORALW: 2<<30 | 0x1c7<<21 | 0x0c<<10, 149 ALDORALH: 1<<30 | 0x1c7<<21 | 0x0c<<10, 150 ALDORALB: 0<<30 | 0x1c7<<21 | 0x0c<<10, 151 ALDORD: 3<<30 | 0x1c1<<21 | 0x0c<<10, 152 ALDORW: 2<<30 | 0x1c1<<21 | 0x0c<<10, 153 ALDORH: 1<<30 | 0x1c1<<21 | 0x0c<<10, 154 ALDORB: 0<<30 | 0x1c1<<21 | 0x0c<<10, 155 ALDORLD: 3<<30 | 0x1c3<<21 | 0x0c<<10, 156 ALDORLW: 2<<30 | 0x1c3<<21 | 0x0c<<10, 157 ALDORLH: 1<<30 | 0x1c3<<21 | 0x0c<<10, 158 ALDORLB: 0<<30 | 0x1c3<<21 | 0x0c<<10, 159 } 160 161 var atomicSWP = map[obj.As]uint32{ 162 ASWPAD: 3<<30 | 0x1c5<<21 | 0x20<<10, 163 ASWPAW: 2<<30 | 0x1c5<<21 | 0x20<<10, 164 ASWPAH: 1<<30 | 0x1c5<<21 | 0x20<<10, 165 ASWPAB: 0<<30 | 0x1c5<<21 | 0x20<<10, 166 ASWPALD: 3<<30 | 0x1c7<<21 | 0x20<<10, 167 ASWPALW: 2<<30 | 0x1c7<<21 | 0x20<<10, 168 ASWPALH: 1<<30 | 0x1c7<<21 | 0x20<<10, 169 ASWPALB: 0<<30 | 0x1c7<<21 | 0x20<<10, 170 ASWPD: 3<<30 | 0x1c1<<21 | 0x20<<10, 171 ASWPW: 2<<30 | 0x1c1<<21 | 0x20<<10, 172 ASWPH: 1<<30 | 0x1c1<<21 | 0x20<<10, 173 ASWPB: 0<<30 | 0x1c1<<21 | 0x20<<10, 174 ASWPLD: 3<<30 | 0x1c3<<21 | 0x20<<10, 175 ASWPLW: 2<<30 | 0x1c3<<21 | 0x20<<10, 176 ASWPLH: 1<<30 | 0x1c3<<21 | 0x20<<10, 177 ASWPLB: 0<<30 | 0x1c3<<21 | 0x20<<10, 178 ACASD: 3<<30 | 0x45<<21 | 0x1f<<10, 179 ACASW: 2<<30 | 0x45<<21 | 0x1f<<10, 180 ACASH: 1<<30 | 0x45<<21 | 0x1f<<10, 181 ACASB: 0<<30 | 0x45<<21 | 0x1f<<10, 182 ACASAD: 3<<30 | 0x47<<21 | 0x1f<<10, 183 ACASAW: 2<<30 | 0x47<<21 | 0x1f<<10, 184 ACASLD: 3<<30 | 0x45<<21 | 0x3f<<10, 185 ACASLW: 2<<30 | 0x45<<21 | 0x3f<<10, 186 ACASALD: 3<<30 | 0x47<<21 | 0x3f<<10, 187 ACASALW: 2<<30 | 0x47<<21 | 0x3f<<10, 188 ACASALH: 1<<30 | 0x47<<21 | 0x3f<<10, 189 ACASALB: 0<<30 | 0x47<<21 | 0x3f<<10, 190 } 191 var atomicCASP = map[obj.As]uint32{ 192 ACASPD: 1<<30 | 0x41<<21 | 0x1f<<10, 193 ACASPW: 0<<30 | 0x41<<21 | 0x1f<<10, 194 } 195 196 var oprange [ALAST & obj.AMask][]Optab 197 198 var xcmp [C_NCLASS][C_NCLASS]bool 199 200 const ( 201 S32 = 0 << 31 202 S64 = 1 << 31 203 Sbit = 1 << 29 204 LSL0_32 = 2 << 13 205 LSL0_64 = 3 << 13 206 ) 207 208 func OPDP2(x uint32) uint32 { 209 return 0<<30 | 0<<29 | 0xd6<<21 | x<<10 210 } 211 212 func OPDP3(sf uint32, op54 uint32, op31 uint32, o0 uint32) uint32 { 213 return sf<<31 | op54<<29 | 0x1B<<24 | op31<<21 | o0<<15 214 } 215 216 func OPBcc(x uint32) uint32 { 217 return 0x2A<<25 | 0<<24 | 0<<4 | x&15 218 } 219 220 func OPBLR(x uint32) uint32 { 221 222 return 0x6B<<25 | 0<<23 | x<<21 | 0x1F<<16 | 0<<10 223 } 224 225 func SYSOP(l uint32, op0 uint32, op1 uint32, crn uint32, crm uint32, op2 uint32, rt uint32) uint32 { 226 return 0x354<<22 | l<<21 | op0<<19 | op1<<16 | crn&15<<12 | crm&15<<8 | op2<<5 | rt 227 } 228 229 func SYSHINT(x uint32) uint32 { 230 return SYSOP(0, 0, 3, 2, 0, x, 0x1F) 231 } 232 233 func LDSTR(sz uint32, v uint32, opc uint32) uint32 { 234 return sz<<30 | 7<<27 | v<<26 | opc<<22 235 } 236 237 func LD2STR(o uint32) uint32 { 238 return o &^ (3 << 22) 239 } 240 241 func LDSTX(sz uint32, o2 uint32, l uint32, o1 uint32, o0 uint32) uint32 { 242 return sz<<30 | 0x8<<24 | o2<<23 | l<<22 | o1<<21 | o0<<15 243 } 244 245 func FPCMP(m uint32, s uint32, type_ uint32, op uint32, op2 uint32) uint32 { 246 return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<14 | 8<<10 | op2 247 } 248 249 func FPCCMP(m uint32, s uint32, type_ uint32, op uint32) uint32 { 250 return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | 1<<10 | op<<4 251 } 252 253 func FPOP1S(m uint32, s uint32, type_ uint32, op uint32) uint32 { 254 return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<15 | 0x10<<10 255 } 256 257 func FPOP2S(m uint32, s uint32, type_ uint32, op uint32) uint32 { 258 return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<12 | 2<<10 259 } 260 261 func FPOP3S(m uint32, s uint32, type_ uint32, op uint32, op2 uint32) uint32 { 262 return m<<31 | s<<29 | 0x1F<<24 | type_<<22 | op<<21 | op2<<15 263 } 264 265 func FPCVTI(sf uint32, s uint32, type_ uint32, rmode uint32, op uint32) uint32 { 266 return sf<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | rmode<<19 | op<<16 | 0<<10 267 } 268 269 func ADR(p uint32, o uint32, rt uint32) uint32 { 270 return p<<31 | (o&3)<<29 | 0x10<<24 | ((o>>2)&0x7FFFF)<<5 | rt&31 271 } 272 273 func OPBIT(x uint32) uint32 { 274 return 1<<30 | 0<<29 | 0xD6<<21 | 0<<16 | x<<10 275 } 276 277 func MOVCONST(d int64, s int, rt int) uint32 { 278 return uint32(((d>>uint(s*16))&0xFFFF)<<5) | uint32(s)&3<<21 | uint32(rt&31) 279 } 280 281 const ( 282 283 LFROM = 1 << iota 284 LFROM128 285 LTO 286 NOTUSETMP 287 BRANCH14BITS 288 BRANCH19BITS 289 ) 290 291 var optab = []Optab{ 292 293 {obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0, 0, 0}, 294 295 296 {AADD, C_ZREG, C_ZREG, C_NONE, C_ZREG, 1, 4, 0, 0, 0}, 297 {AADD, C_ZREG, C_NONE, C_NONE, C_ZREG, 1, 4, 0, 0, 0}, 298 {AADC, C_ZREG, C_ZREG, C_NONE, C_ZREG, 1, 4, 0, 0, 0}, 299 {AADC, C_ZREG, C_NONE, C_NONE, C_ZREG, 1, 4, 0, 0, 0}, 300 {ANEG, C_ZREG, C_NONE, C_NONE, C_ZREG, 25, 4, 0, 0, 0}, 301 {ANEG, C_NONE, C_NONE, C_NONE, C_ZREG, 25, 4, 0, 0, 0}, 302 {ANGC, C_ZREG, C_NONE, C_NONE, C_ZREG, 17, 4, 0, 0, 0}, 303 {ACMP, C_ZREG, C_ZREG, C_NONE, C_NONE, 1, 4, 0, 0, 0}, 304 {AADD, C_ADDCON, C_RSP, C_NONE, C_RSP, 2, 4, 0, 0, 0}, 305 {AADD, C_ADDCON, C_NONE, C_NONE, C_RSP, 2, 4, 0, 0, 0}, 306 {ACMP, C_ADDCON, C_RSP, C_NONE, C_NONE, 2, 4, 0, 0, 0}, 307 {AADD, C_MOVCON, C_RSP, C_NONE, C_RSP, 62, 8, 0, 0, 0}, 308 {AADD, C_MOVCON, C_NONE, C_NONE, C_RSP, 62, 8, 0, 0, 0}, 309 {ACMP, C_MOVCON, C_RSP, C_NONE, C_NONE, 62, 8, 0, 0, 0}, 310 {AADD, C_BITCON, C_RSP, C_NONE, C_RSP, 62, 8, 0, 0, 0}, 311 {AADD, C_BITCON, C_NONE, C_NONE, C_RSP, 62, 8, 0, 0, 0}, 312 {ACMP, C_BITCON, C_RSP, C_NONE, C_NONE, 62, 8, 0, 0, 0}, 313 {AADD, C_ADDCON2, C_RSP, C_NONE, C_RSP, 48, 8, 0, NOTUSETMP, 0}, 314 {AADD, C_ADDCON2, C_NONE, C_NONE, C_RSP, 48, 8, 0, NOTUSETMP, 0}, 315 {AADD, C_MOVCON2, C_RSP, C_NONE, C_RSP, 13, 12, 0, 0, 0}, 316 {AADD, C_MOVCON2, C_NONE, C_NONE, C_RSP, 13, 12, 0, 0, 0}, 317 {AADD, C_MOVCON3, C_RSP, C_NONE, C_RSP, 13, 16, 0, 0, 0}, 318 {AADD, C_MOVCON3, C_NONE, C_NONE, C_RSP, 13, 16, 0, 0, 0}, 319 {AADD, C_VCON, C_RSP, C_NONE, C_RSP, 13, 20, 0, 0, 0}, 320 {AADD, C_VCON, C_NONE, C_NONE, C_RSP, 13, 20, 0, 0, 0}, 321 {ACMP, C_MOVCON2, C_ZREG, C_NONE, C_NONE, 13, 12, 0, 0, 0}, 322 {ACMP, C_MOVCON3, C_ZREG, C_NONE, C_NONE, 13, 16, 0, 0, 0}, 323 {ACMP, C_VCON, C_ZREG, C_NONE, C_NONE, 13, 20, 0, 0, 0}, 324 {AADD, C_SHIFT, C_ZREG, C_NONE, C_ZREG, 3, 4, 0, 0, 0}, 325 {AADD, C_SHIFT, C_NONE, C_NONE, C_ZREG, 3, 4, 0, 0, 0}, 326 {AMVN, C_SHIFT, C_NONE, C_NONE, C_ZREG, 3, 4, 0, 0, 0}, 327 {ACMP, C_SHIFT, C_ZREG, C_NONE, C_NONE, 3, 4, 0, 0, 0}, 328 {ANEG, C_SHIFT, C_NONE, C_NONE, C_ZREG, 3, 4, 0, 0, 0}, 329 {AADD, C_ZREG, C_RSP, C_NONE, C_RSP, 27, 4, 0, 0, 0}, 330 {AADD, C_ZREG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0}, 331 {ACMP, C_ZREG, C_RSP, C_NONE, C_NONE, 27, 4, 0, 0, 0}, 332 {AADD, C_EXTREG, C_RSP, C_NONE, C_RSP, 27, 4, 0, 0, 0}, 333 {AADD, C_EXTREG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0}, 334 {ACMP, C_EXTREG, C_RSP, C_NONE, C_NONE, 27, 4, 0, 0, 0}, 335 {AADD, C_ZREG, C_ZREG, C_NONE, C_ZREG, 1, 4, 0, 0, 0}, 336 {AADD, C_ZREG, C_NONE, C_NONE, C_ZREG, 1, 4, 0, 0, 0}, 337 {AMUL, C_ZREG, C_ZREG, C_NONE, C_ZREG, 15, 4, 0, 0, 0}, 338 {AMUL, C_ZREG, C_NONE, C_NONE, C_ZREG, 15, 4, 0, 0, 0}, 339 {AMADD, C_ZREG, C_ZREG, C_ZREG, C_ZREG, 15, 4, 0, 0, 0}, 340 {AREM, C_ZREG, C_ZREG, C_NONE, C_ZREG, 16, 8, 0, 0, 0}, 341 {AREM, C_ZREG, C_NONE, C_NONE, C_ZREG, 16, 8, 0, 0, 0}, 342 {ASDIV, C_ZREG, C_NONE, C_NONE, C_ZREG, 1, 4, 0, 0, 0}, 343 {ASDIV, C_ZREG, C_ZREG, C_NONE, C_ZREG, 1, 4, 0, 0, 0}, 344 345 {AFADDS, C_FREG, C_NONE, C_NONE, C_FREG, 54, 4, 0, 0, 0}, 346 {AFADDS, C_FREG, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0}, 347 {AFMSUBD, C_FREG, C_FREG, C_FREG, C_FREG, 15, 4, 0, 0, 0}, 348 {AFCMPS, C_FREG, C_FREG, C_NONE, C_NONE, 56, 4, 0, 0, 0}, 349 {AFCMPS, C_FCON, C_FREG, C_NONE, C_NONE, 56, 4, 0, 0, 0}, 350 {AVADDP, C_ARNG, C_ARNG, C_NONE, C_ARNG, 72, 4, 0, 0, 0}, 351 {AVADD, C_ARNG, C_ARNG, C_NONE, C_ARNG, 72, 4, 0, 0, 0}, 352 {AVADD, C_VREG, C_VREG, C_NONE, C_VREG, 89, 4, 0, 0, 0}, 353 {AVADD, C_VREG, C_NONE, C_NONE, C_VREG, 89, 4, 0, 0, 0}, 354 {AVADDV, C_ARNG, C_NONE, C_NONE, C_VREG, 85, 4, 0, 0, 0}, 355 356 357 {AAND, C_ZREG, C_ZREG, C_NONE, C_ZREG, 1, 4, 0, 0, 0}, 358 {AAND, C_ZREG, C_NONE, C_NONE, C_ZREG, 1, 4, 0, 0, 0}, 359 {AANDS, C_ZREG, C_ZREG, C_NONE, C_ZREG, 1, 4, 0, 0, 0}, 360 {AANDS, C_ZREG, C_NONE, C_NONE, C_ZREG, 1, 4, 0, 0, 0}, 361 {ATST, C_ZREG, C_ZREG, C_NONE, C_NONE, 1, 4, 0, 0, 0}, 362 {AAND, C_MBCON, C_ZREG, C_NONE, C_RSP, 53, 4, 0, 0, 0}, 363 {AAND, C_MBCON, C_NONE, C_NONE, C_RSP, 53, 4, 0, 0, 0}, 364 {AANDS, C_MBCON, C_ZREG, C_NONE, C_ZREG, 53, 4, 0, 0, 0}, 365 {AANDS, C_MBCON, C_NONE, C_NONE, C_ZREG, 53, 4, 0, 0, 0}, 366 {ATST, C_MBCON, C_ZREG, C_NONE, C_NONE, 53, 4, 0, 0, 0}, 367 {AAND, C_BITCON, C_ZREG, C_NONE, C_RSP, 53, 4, 0, 0, 0}, 368 {AAND, C_BITCON, C_NONE, C_NONE, C_RSP, 53, 4, 0, 0, 0}, 369 {AANDS, C_BITCON, C_ZREG, C_NONE, C_ZREG, 53, 4, 0, 0, 0}, 370 {AANDS, C_BITCON, C_NONE, C_NONE, C_ZREG, 53, 4, 0, 0, 0}, 371 {ATST, C_BITCON, C_ZREG, C_NONE, C_NONE, 53, 4, 0, 0, 0}, 372 {AAND, C_MOVCON, C_ZREG, C_NONE, C_ZREG, 62, 8, 0, 0, 0}, 373 {AAND, C_MOVCON, C_NONE, C_NONE, C_ZREG, 62, 8, 0, 0, 0}, 374 {AANDS, C_MOVCON, C_ZREG, C_NONE, C_ZREG, 62, 8, 0, 0, 0}, 375 {AANDS, C_MOVCON, C_NONE, C_NONE, C_ZREG, 62, 8, 0, 0, 0}, 376 {ATST, C_MOVCON, C_ZREG, C_NONE, C_NONE, 62, 8, 0, 0, 0}, 377 {AAND, C_MOVCON2, C_ZREG, C_NONE, C_ZREG, 28, 12, 0, 0, 0}, 378 {AAND, C_MOVCON2, C_NONE, C_NONE, C_ZREG, 28, 12, 0, 0, 0}, 379 {AAND, C_MOVCON3, C_ZREG, C_NONE, C_ZREG, 28, 16, 0, 0, 0}, 380 {AAND, C_MOVCON3, C_NONE, C_NONE, C_ZREG, 28, 16, 0, 0, 0}, 381 {AAND, C_VCON, C_ZREG, C_NONE, C_ZREG, 28, 20, 0, 0, 0}, 382 {AAND, C_VCON, C_NONE, C_NONE, C_ZREG, 28, 20, 0, 0, 0}, 383 {AANDS, C_MOVCON2, C_ZREG, C_NONE, C_ZREG, 28, 12, 0, 0, 0}, 384 {AANDS, C_MOVCON2, C_NONE, C_NONE, C_ZREG, 28, 12, 0, 0, 0}, 385 {AANDS, C_MOVCON3, C_ZREG, C_NONE, C_ZREG, 28, 16, 0, 0, 0}, 386 {AANDS, C_MOVCON3, C_NONE, C_NONE, C_ZREG, 28, 16, 0, 0, 0}, 387 {AANDS, C_VCON, C_ZREG, C_NONE, C_ZREG, 28, 20, 0, 0, 0}, 388 {AANDS, C_VCON, C_NONE, C_NONE, C_ZREG, 28, 20, 0, 0, 0}, 389 {ATST, C_MOVCON2, C_ZREG, C_NONE, C_NONE, 28, 12, 0, 0, 0}, 390 {ATST, C_MOVCON3, C_ZREG, C_NONE, C_NONE, 28, 16, 0, 0, 0}, 391 {ATST, C_VCON, C_ZREG, C_NONE, C_NONE, 28, 20, 0, 0, 0}, 392 {AAND, C_SHIFT, C_ZREG, C_NONE, C_ZREG, 3, 4, 0, 0, 0}, 393 {AAND, C_SHIFT, C_NONE, C_NONE, C_ZREG, 3, 4, 0, 0, 0}, 394 {AANDS, C_SHIFT, C_ZREG, C_NONE, C_ZREG, 3, 4, 0, 0, 0}, 395 {AANDS, C_SHIFT, C_NONE, C_NONE, C_ZREG, 3, 4, 0, 0, 0}, 396 {ATST, C_SHIFT, C_ZREG, C_NONE, C_NONE, 3, 4, 0, 0, 0}, 397 {AMOVD, C_RSP, C_NONE, C_NONE, C_RSP, 24, 4, 0, 0, 0}, 398 {AMOVD, C_ZREG, C_NONE, C_NONE, C_ZREG, 24, 4, 0, 0, 0}, 399 {AMVN, C_ZREG, C_NONE, C_NONE, C_ZREG, 24, 4, 0, 0, 0}, 400 {AMOVB, C_ZREG, C_NONE, C_NONE, C_ZREG, 45, 4, 0, 0, 0}, 401 {AMOVH, C_ZREG, C_NONE, C_NONE, C_ZREG, 45, 4, 0, 0, 0}, 402 {AMOVW, C_ZREG, C_NONE, C_NONE, C_ZREG, 45, 4, 0, 0, 0}, 403 404 405 406 {AMOVW, C_MBCON, C_NONE, C_NONE, C_ZREG, 32, 4, 0, 0, 0}, 407 {AMOVD, C_MBCON, C_NONE, C_NONE, C_ZREG, 32, 4, 0, 0, 0}, 408 {AMOVW, C_MOVCON, C_NONE, C_NONE, C_ZREG, 32, 4, 0, 0, 0}, 409 {AMOVD, C_MOVCON, C_NONE, C_NONE, C_ZREG, 32, 4, 0, 0, 0}, 410 {AMOVW, C_BITCON, C_NONE, C_NONE, C_RSP, 32, 4, 0, 0, 0}, 411 {AMOVD, C_BITCON, C_NONE, C_NONE, C_RSP, 32, 4, 0, 0, 0}, 412 {AMOVW, C_MOVCON2, C_NONE, C_NONE, C_ZREG, 12, 8, 0, NOTUSETMP, 0}, 413 {AMOVD, C_MOVCON2, C_NONE, C_NONE, C_ZREG, 12, 8, 0, NOTUSETMP, 0}, 414 {AMOVD, C_MOVCON3, C_NONE, C_NONE, C_ZREG, 12, 12, 0, NOTUSETMP, 0}, 415 {AMOVD, C_VCON, C_NONE, C_NONE, C_ZREG, 12, 16, 0, NOTUSETMP, 0}, 416 417 {AMOVK, C_VCON, C_NONE, C_NONE, C_ZREG, 33, 4, 0, 0, 0}, 418 {AMOVD, C_AACON, C_NONE, C_NONE, C_RSP, 4, 4, REGFROM, 0, 0}, 419 {AMOVD, C_AACON2, C_NONE, C_NONE, C_RSP, 4, 8, REGFROM, NOTUSETMP, 0}, 420 421 422 {AMOVD, C_LACON, C_NONE, C_NONE, C_RSP, 34, 8, REGSP, LFROM, 0}, 423 424 425 {AVMOVQ, C_VCON, C_NONE, C_VCON, C_VREG, 101, 4, 0, LFROM128, 0}, 426 {AVMOVD, C_VCON, C_NONE, C_NONE, C_VREG, 101, 4, 0, LFROM, 0}, 427 {AVMOVS, C_LCON, C_NONE, C_NONE, C_VREG, 101, 4, 0, LFROM, 0}, 428 429 430 {AB, C_NONE, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, 431 {ABL, C_NONE, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, 432 {AB, C_NONE, C_NONE, C_NONE, C_ZOREG, 6, 4, 0, 0, 0}, 433 {ABL, C_NONE, C_NONE, C_NONE, C_ZREG, 6, 4, 0, 0, 0}, 434 {ABL, C_NONE, C_NONE, C_NONE, C_ZOREG, 6, 4, 0, 0, 0}, 435 {obj.ARET, C_NONE, C_NONE, C_NONE, C_ZREG, 6, 4, 0, 0, 0}, 436 {obj.ARET, C_NONE, C_NONE, C_NONE, C_ZOREG, 6, 4, 0, 0, 0}, 437 {ABEQ, C_NONE, C_NONE, C_NONE, C_SBRA, 7, 4, 0, BRANCH19BITS, 0}, 438 {ACBZ, C_ZREG, C_NONE, C_NONE, C_SBRA, 39, 4, 0, BRANCH19BITS, 0}, 439 {ATBZ, C_VCON, C_ZREG, C_NONE, C_SBRA, 40, 4, 0, BRANCH14BITS, 0}, 440 {AERET, C_NONE, C_NONE, C_NONE, C_NONE, 41, 4, 0, 0, 0}, 441 442 443 {AADRP, C_SBRA, C_NONE, C_NONE, C_ZREG, 60, 4, 0, 0, 0}, 444 {AADR, C_SBRA, C_NONE, C_NONE, C_ZREG, 61, 4, 0, 0, 0}, 445 446 {ACLREX, C_NONE, C_NONE, C_NONE, C_VCON, 38, 4, 0, 0, 0}, 447 {ACLREX, C_NONE, C_NONE, C_NONE, C_NONE, 38, 4, 0, 0, 0}, 448 {ABFM, C_VCON, C_ZREG, C_VCON, C_ZREG, 42, 4, 0, 0, 0}, 449 {ABFI, C_VCON, C_ZREG, C_VCON, C_ZREG, 43, 4, 0, 0, 0}, 450 {AEXTR, C_VCON, C_ZREG, C_ZREG, C_ZREG, 44, 4, 0, 0, 0}, 451 {ASXTB, C_ZREG, C_NONE, C_NONE, C_ZREG, 45, 4, 0, 0, 0}, 452 {ACLS, C_ZREG, C_NONE, C_NONE, C_ZREG, 46, 4, 0, 0, 0}, 453 {ALSL, C_VCON, C_ZREG, C_NONE, C_ZREG, 8, 4, 0, 0, 0}, 454 {ALSL, C_VCON, C_NONE, C_NONE, C_ZREG, 8, 4, 0, 0, 0}, 455 {ALSL, C_ZREG, C_NONE, C_NONE, C_ZREG, 9, 4, 0, 0, 0}, 456 {ALSL, C_ZREG, C_ZREG, C_NONE, C_ZREG, 9, 4, 0, 0, 0}, 457 {ASVC, C_VCON, C_NONE, C_NONE, C_NONE, 10, 4, 0, 0, 0}, 458 {ASVC, C_NONE, C_NONE, C_NONE, C_NONE, 10, 4, 0, 0, 0}, 459 {ADWORD, C_NONE, C_NONE, C_NONE, C_VCON, 11, 8, 0, NOTUSETMP, 0}, 460 {ADWORD, C_NONE, C_NONE, C_NONE, C_LEXT, 11, 8, 0, NOTUSETMP, 0}, 461 {ADWORD, C_NONE, C_NONE, C_NONE, C_ADDR, 11, 8, 0, NOTUSETMP, 0}, 462 {ADWORD, C_NONE, C_NONE, C_NONE, C_LACON, 11, 8, 0, NOTUSETMP, 0}, 463 {AWORD, C_NONE, C_NONE, C_NONE, C_LCON, 14, 4, 0, 0, 0}, 464 {AWORD, C_NONE, C_NONE, C_NONE, C_LEXT, 14, 4, 0, 0, 0}, 465 {AWORD, C_NONE, C_NONE, C_NONE, C_ADDR, 14, 4, 0, 0, 0}, 466 {AMOVW, C_VCONADDR, C_NONE, C_NONE, C_ZREG, 68, 8, 0, NOTUSETMP, 0}, 467 {AMOVD, C_VCONADDR, C_NONE, C_NONE, C_ZREG, 68, 8, 0, NOTUSETMP, 0}, 468 {AMOVB, C_ZREG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0}, 469 {AMOVH, C_ZREG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0}, 470 {AMOVW, C_ZREG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0}, 471 {AMOVD, C_ZREG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0}, 472 {AMOVB, C_ADDR, C_NONE, C_NONE, C_ZREG, 65, 12, 0, 0, 0}, 473 {AMOVH, C_ADDR, C_NONE, C_NONE, C_ZREG, 65, 12, 0, 0, 0}, 474 {AMOVW, C_ADDR, C_NONE, C_NONE, C_ZREG, 65, 12, 0, 0, 0}, 475 {AMOVD, C_ADDR, C_NONE, C_NONE, C_ZREG, 65, 12, 0, 0, 0}, 476 {AMOVD, C_GOTADDR, C_NONE, C_NONE, C_ZREG, 71, 8, 0, 0, 0}, 477 {AMOVD, C_TLS_LE, C_NONE, C_NONE, C_ZREG, 69, 4, 0, 0, 0}, 478 {AMOVD, C_TLS_IE, C_NONE, C_NONE, C_ZREG, 70, 8, 0, 0, 0}, 479 480 {AFMOVS, C_FREG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0}, 481 {AFMOVS, C_ADDR, C_NONE, C_NONE, C_FREG, 65, 12, 0, 0, 0}, 482 {AFMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0}, 483 {AFMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, 65, 12, 0, 0, 0}, 484 {AFMOVS, C_FCON, C_NONE, C_NONE, C_FREG, 55, 4, 0, 0, 0}, 485 {AFMOVS, C_FREG, C_NONE, C_NONE, C_FREG, 54, 4, 0, 0, 0}, 486 {AFMOVD, C_FCON, C_NONE, C_NONE, C_FREG, 55, 4, 0, 0, 0}, 487 {AFMOVD, C_FREG, C_NONE, C_NONE, C_FREG, 54, 4, 0, 0, 0}, 488 {AFMOVS, C_ZREG, C_NONE, C_NONE, C_FREG, 29, 4, 0, 0, 0}, 489 {AFMOVS, C_FREG, C_NONE, C_NONE, C_ZREG, 29, 4, 0, 0, 0}, 490 {AFMOVD, C_ZREG, C_NONE, C_NONE, C_FREG, 29, 4, 0, 0, 0}, 491 {AFMOVD, C_FREG, C_NONE, C_NONE, C_ZREG, 29, 4, 0, 0, 0}, 492 {AFCVTZSD, C_FREG, C_NONE, C_NONE, C_ZREG, 29, 4, 0, 0, 0}, 493 {ASCVTFD, C_ZREG, C_NONE, C_NONE, C_FREG, 29, 4, 0, 0, 0}, 494 {AFCVTSD, C_FREG, C_NONE, C_NONE, C_FREG, 29, 4, 0, 0, 0}, 495 {AVMOV, C_ELEM, C_NONE, C_NONE, C_ZREG, 73, 4, 0, 0, 0}, 496 {AVMOV, C_ELEM, C_NONE, C_NONE, C_ELEM, 92, 4, 0, 0, 0}, 497 {AVMOV, C_ELEM, C_NONE, C_NONE, C_VREG, 80, 4, 0, 0, 0}, 498 {AVMOV, C_ZREG, C_NONE, C_NONE, C_ARNG, 82, 4, 0, 0, 0}, 499 {AVMOV, C_ZREG, C_NONE, C_NONE, C_ELEM, 78, 4, 0, 0, 0}, 500 {AVMOV, C_ARNG, C_NONE, C_NONE, C_ARNG, 83, 4, 0, 0, 0}, 501 {AVDUP, C_ELEM, C_NONE, C_NONE, C_ARNG, 79, 4, 0, 0, 0}, 502 {AVDUP, C_ELEM, C_NONE, C_NONE, C_VREG, 80, 4, 0, 0, 0}, 503 {AVDUP, C_ZREG, C_NONE, C_NONE, C_ARNG, 82, 4, 0, 0, 0}, 504 {AVMOVI, C_ADDCON, C_NONE, C_NONE, C_ARNG, 86, 4, 0, 0, 0}, 505 {AVFMLA, C_ARNG, C_ARNG, C_NONE, C_ARNG, 72, 4, 0, 0, 0}, 506 {AVEXT, C_VCON, C_ARNG, C_ARNG, C_ARNG, 94, 4, 0, 0, 0}, 507 {AVTBL, C_ARNG, C_NONE, C_LIST, C_ARNG, 100, 4, 0, 0, 0}, 508 {AVUSHR, C_VCON, C_ARNG, C_NONE, C_ARNG, 95, 4, 0, 0, 0}, 509 {AVZIP1, C_ARNG, C_ARNG, C_NONE, C_ARNG, 72, 4, 0, 0, 0}, 510 {AVUSHLL, C_VCON, C_ARNG, C_NONE, C_ARNG, 102, 4, 0, 0, 0}, 511 {AVUXTL, C_ARNG, C_NONE, C_NONE, C_ARNG, 102, 4, 0, 0, 0}, 512 {AVUADDW, C_ARNG, C_ARNG, C_NONE, C_ARNG, 105, 4, 0, 0, 0}, 513 514 515 {ACSEL, C_COND, C_ZREG, C_ZREG, C_ZREG, 18, 4, 0, 0, 0}, 516 {ACINC, C_COND, C_ZREG, C_NONE, C_ZREG, 18, 4, 0, 0, 0}, 517 {ACSET, C_COND, C_NONE, C_NONE, C_ZREG, 18, 4, 0, 0, 0}, 518 {AFCSELD, C_COND, C_FREG, C_FREG, C_FREG, 18, 4, 0, 0, 0}, 519 {ACCMN, C_COND, C_ZREG, C_ZREG, C_VCON, 19, 4, 0, 0, 0}, 520 {ACCMN, C_COND, C_ZREG, C_VCON, C_VCON, 19, 4, 0, 0, 0}, 521 {AFCCMPS, C_COND, C_FREG, C_FREG, C_VCON, 57, 4, 0, 0, 0}, 522 523 524 {AMOVB, C_ZREG, C_NONE, C_NONE, C_UAUTO4K, 20, 4, REGSP, 0, 0}, 525 {AMOVB, C_ZREG, C_NONE, C_NONE, C_UOREG4K, 20, 4, 0, 0, 0}, 526 {AMOVH, C_ZREG, C_NONE, C_NONE, C_UAUTO8K, 20, 4, REGSP, 0, 0}, 527 {AMOVH, C_ZREG, C_NONE, C_NONE, C_UOREG8K, 20, 4, 0, 0, 0}, 528 {AMOVW, C_ZREG, C_NONE, C_NONE, C_UAUTO16K, 20, 4, REGSP, 0, 0}, 529 {AMOVW, C_ZREG, C_NONE, C_NONE, C_UOREG16K, 20, 4, 0, 0, 0}, 530 {AMOVD, C_ZREG, C_NONE, C_NONE, C_UAUTO32K, 20, 4, REGSP, 0, 0}, 531 {AMOVD, C_ZREG, C_NONE, C_NONE, C_UOREG32K, 20, 4, 0, 0, 0}, 532 533 {AFMOVS, C_FREG, C_NONE, C_NONE, C_UAUTO16K, 20, 4, REGSP, 0, 0}, 534 {AFMOVS, C_FREG, C_NONE, C_NONE, C_UOREG16K, 20, 4, 0, 0, 0}, 535 {AFMOVD, C_FREG, C_NONE, C_NONE, C_UAUTO32K, 20, 4, REGSP, 0, 0}, 536 {AFMOVD, C_FREG, C_NONE, C_NONE, C_UOREG32K, 20, 4, 0, 0, 0}, 537 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_UAUTO64K, 20, 4, REGSP, 0, 0}, 538 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_UOREG64K, 20, 4, 0, 0, 0}, 539 540 541 {AMOVB, C_ZREG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0}, 542 {AMOVB, C_ZREG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0}, 543 {AMOVH, C_ZREG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0}, 544 {AMOVH, C_ZREG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0}, 545 {AMOVW, C_ZREG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0}, 546 {AMOVW, C_ZREG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0}, 547 {AMOVD, C_ZREG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0}, 548 {AMOVD, C_ZREG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0}, 549 550 {AFMOVS, C_FREG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0}, 551 {AFMOVS, C_FREG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0}, 552 {AFMOVD, C_FREG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0}, 553 {AFMOVD, C_FREG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0}, 554 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0}, 555 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0}, 556 557 558 {AMOVB, C_UAUTO4K, C_NONE, C_NONE, C_ZREG, 21, 4, REGSP, 0, 0}, 559 {AMOVB, C_UOREG4K, C_NONE, C_NONE, C_ZREG, 21, 4, 0, 0, 0}, 560 {AMOVH, C_UAUTO8K, C_NONE, C_NONE, C_ZREG, 21, 4, REGSP, 0, 0}, 561 {AMOVH, C_UOREG8K, C_NONE, C_NONE, C_ZREG, 21, 4, 0, 0, 0}, 562 {AMOVW, C_UAUTO16K, C_NONE, C_NONE, C_ZREG, 21, 4, REGSP, 0, 0}, 563 {AMOVW, C_UOREG16K, C_NONE, C_NONE, C_ZREG, 21, 4, 0, 0, 0}, 564 {AMOVD, C_UAUTO32K, C_NONE, C_NONE, C_ZREG, 21, 4, REGSP, 0, 0}, 565 {AMOVD, C_UOREG32K, C_NONE, C_NONE, C_ZREG, 21, 4, 0, 0, 0}, 566 567 {AFMOVS, C_UAUTO16K, C_NONE, C_NONE, C_FREG, 21, 4, REGSP, 0, 0}, 568 {AFMOVS, C_UOREG16K, C_NONE, C_NONE, C_FREG, 21, 4, 0, 0, 0}, 569 {AFMOVD, C_UAUTO32K, C_NONE, C_NONE, C_FREG, 21, 4, REGSP, 0, 0}, 570 {AFMOVD, C_UOREG32K, C_NONE, C_NONE, C_FREG, 21, 4, 0, 0, 0}, 571 {AFMOVQ, C_UAUTO64K, C_NONE, C_NONE, C_FREG, 21, 4, REGSP, 0, 0}, 572 {AFMOVQ, C_UOREG64K, C_NONE, C_NONE, C_FREG, 21, 4, 0, 0, 0}, 573 574 575 {AMOVB, C_NSAUTO, C_NONE, C_NONE, C_ZREG, 21, 4, REGSP, 0, 0}, 576 {AMOVB, C_NSOREG, C_NONE, C_NONE, C_ZREG, 21, 4, 0, 0, 0}, 577 {AMOVH, C_NSAUTO, C_NONE, C_NONE, C_ZREG, 21, 4, REGSP, 0, 0}, 578 {AMOVH, C_NSOREG, C_NONE, C_NONE, C_ZREG, 21, 4, 0, 0, 0}, 579 {AMOVW, C_NSAUTO, C_NONE, C_NONE, C_ZREG, 21, 4, REGSP, 0, 0}, 580 {AMOVW, C_NSOREG, C_NONE, C_NONE, C_ZREG, 21, 4, 0, 0, 0}, 581 {AMOVD, C_NSAUTO, C_NONE, C_NONE, C_ZREG, 21, 4, REGSP, 0, 0}, 582 {AMOVD, C_NSOREG, C_NONE, C_NONE, C_ZREG, 21, 4, 0, 0, 0}, 583 584 {AFMOVS, C_NSAUTO, C_NONE, C_NONE, C_FREG, 21, 4, REGSP, 0, 0}, 585 {AFMOVS, C_NSOREG, C_NONE, C_NONE, C_FREG, 21, 4, 0, 0, 0}, 586 {AFMOVD, C_NSAUTO, C_NONE, C_NONE, C_FREG, 21, 4, REGSP, 0, 0}, 587 {AFMOVD, C_NSOREG, C_NONE, C_NONE, C_FREG, 21, 4, 0, 0, 0}, 588 {AFMOVQ, C_NSAUTO, C_NONE, C_NONE, C_FREG, 21, 4, REGSP, 0, 0}, 589 {AFMOVQ, C_NSOREG, C_NONE, C_NONE, C_FREG, 21, 4, 0, 0, 0}, 590 591 592 {AMOVB, C_ZREG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, 593 {AMOVB, C_ZREG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, 594 {AMOVH, C_ZREG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, 595 {AMOVH, C_ZREG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, 596 {AMOVW, C_ZREG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, 597 {AMOVW, C_ZREG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, 598 {AMOVD, C_ZREG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, 599 {AMOVD, C_ZREG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, 600 601 {AFMOVS, C_FREG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, 602 {AFMOVS, C_FREG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, 603 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, 604 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, 605 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, 606 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, 607 608 609 {AMOVB, C_LAUTO, C_NONE, C_NONE, C_ZREG, 31, 8, REGSP, LFROM, 0}, 610 {AMOVB, C_LOREG, C_NONE, C_NONE, C_ZREG, 31, 8, 0, LFROM, 0}, 611 {AMOVH, C_LAUTO, C_NONE, C_NONE, C_ZREG, 31, 8, REGSP, LFROM, 0}, 612 {AMOVH, C_LOREG, C_NONE, C_NONE, C_ZREG, 31, 8, 0, LFROM, 0}, 613 {AMOVW, C_LAUTO, C_NONE, C_NONE, C_ZREG, 31, 8, REGSP, LFROM, 0}, 614 {AMOVW, C_LOREG, C_NONE, C_NONE, C_ZREG, 31, 8, 0, LFROM, 0}, 615 {AMOVD, C_LAUTO, C_NONE, C_NONE, C_ZREG, 31, 8, REGSP, LFROM, 0}, 616 {AMOVD, C_LOREG, C_NONE, C_NONE, C_ZREG, 31, 8, 0, LFROM, 0}, 617 618 {AFMOVS, C_LAUTO, C_NONE, C_NONE, C_FREG, 31, 8, REGSP, LFROM, 0}, 619 {AFMOVS, C_LOREG, C_NONE, C_NONE, C_FREG, 31, 8, 0, LFROM, 0}, 620 {AFMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, 31, 8, REGSP, LFROM, 0}, 621 {AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 31, 8, 0, LFROM, 0}, 622 {AFMOVQ, C_LAUTO, C_NONE, C_NONE, C_FREG, 31, 8, REGSP, LFROM, 0}, 623 {AFMOVQ, C_LOREG, C_NONE, C_NONE, C_FREG, 31, 8, 0, LFROM, 0}, 624 625 626 {AMOVD, C_LOREG, C_NONE, C_NONE, C_ZREG, 22, 4, 0, 0, C_XPOST}, 627 {AMOVW, C_LOREG, C_NONE, C_NONE, C_ZREG, 22, 4, 0, 0, C_XPOST}, 628 {AMOVH, C_LOREG, C_NONE, C_NONE, C_ZREG, 22, 4, 0, 0, C_XPOST}, 629 {AMOVB, C_LOREG, C_NONE, C_NONE, C_ZREG, 22, 4, 0, 0, C_XPOST}, 630 {AFMOVS, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPOST}, 631 {AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPOST}, 632 {AFMOVQ, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPOST}, 633 634 {AMOVD, C_LOREG, C_NONE, C_NONE, C_ZREG, 22, 4, 0, 0, C_XPRE}, 635 {AMOVW, C_LOREG, C_NONE, C_NONE, C_ZREG, 22, 4, 0, 0, C_XPRE}, 636 {AMOVH, C_LOREG, C_NONE, C_NONE, C_ZREG, 22, 4, 0, 0, C_XPRE}, 637 {AMOVB, C_LOREG, C_NONE, C_NONE, C_ZREG, 22, 4, 0, 0, C_XPRE}, 638 {AFMOVS, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPRE}, 639 {AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPRE}, 640 {AFMOVQ, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPRE}, 641 642 643 {AMOVD, C_ZREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, 644 {AMOVW, C_ZREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, 645 {AMOVH, C_ZREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, 646 {AMOVB, C_ZREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, 647 {AFMOVS, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, 648 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, 649 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, 650 651 {AMOVD, C_ZREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, 652 {AMOVW, C_ZREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, 653 {AMOVH, C_ZREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, 654 {AMOVB, C_ZREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, 655 {AFMOVS, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, 656 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, 657 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, 658 659 660 {AMOVD, C_ROFF, C_NONE, C_NONE, C_ZREG, 98, 4, 0, 0, 0}, 661 {AMOVW, C_ROFF, C_NONE, C_NONE, C_ZREG, 98, 4, 0, 0, 0}, 662 {AMOVH, C_ROFF, C_NONE, C_NONE, C_ZREG, 98, 4, 0, 0, 0}, 663 {AMOVB, C_ROFF, C_NONE, C_NONE, C_ZREG, 98, 4, 0, 0, 0}, 664 {AFMOVS, C_ROFF, C_NONE, C_NONE, C_FREG, 98, 4, 0, 0, 0}, 665 {AFMOVD, C_ROFF, C_NONE, C_NONE, C_FREG, 98, 4, 0, 0, 0}, 666 667 668 {AMOVD, C_ZREG, C_NONE, C_NONE, C_ROFF, 99, 4, 0, 0, 0}, 669 {AMOVW, C_ZREG, C_NONE, C_NONE, C_ROFF, 99, 4, 0, 0, 0}, 670 {AMOVH, C_ZREG, C_NONE, C_NONE, C_ROFF, 99, 4, 0, 0, 0}, 671 {AMOVB, C_ZREG, C_NONE, C_NONE, C_ROFF, 99, 4, 0, 0, 0}, 672 {AFMOVS, C_FREG, C_NONE, C_NONE, C_ROFF, 99, 4, 0, 0, 0}, 673 {AFMOVD, C_FREG, C_NONE, C_NONE, C_ROFF, 99, 4, 0, 0, 0}, 674 675 676 {AFLDPQ, C_NQAUTO_16, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, 0}, 677 {AFLDPQ, C_PQAUTO_16, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, 0}, 678 {AFLDPQ, C_UAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, 0}, 679 {AFLDPQ, C_NAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, 0}, 680 {AFLDPQ, C_LAUTO, C_NONE, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, 0}, 681 {AFLDPQ, C_NQOREG_16, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, 0}, 682 {AFLDPQ, C_NQOREG_16, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE}, 683 {AFLDPQ, C_NQOREG_16, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST}, 684 {AFLDPQ, C_PQOREG_16, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, 0}, 685 {AFLDPQ, C_PQOREG_16, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE}, 686 {AFLDPQ, C_PQOREG_16, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST}, 687 {AFLDPQ, C_UOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, 0}, 688 {AFLDPQ, C_NOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, 0}, 689 {AFLDPQ, C_LOREG, C_NONE, C_NONE, C_PAIR, 75, 12, 0, LFROM, 0}, 690 {AFLDPQ, C_ADDR, C_NONE, C_NONE, C_PAIR, 88, 12, 0, 0, 0}, 691 692 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQAUTO_16, 67, 4, REGSP, 0, 0}, 693 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQAUTO_16, 67, 4, REGSP, 0, 0}, 694 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, 0}, 695 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, 76, 8, REGSP, 0, 0}, 696 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, 0}, 697 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQOREG_16, 67, 4, 0, 0, 0}, 698 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQOREG_16, 67, 4, 0, 0, C_XPRE}, 699 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQOREG_16, 67, 4, 0, 0, C_XPOST}, 700 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQOREG_16, 67, 4, 0, 0, 0}, 701 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQOREG_16, 67, 4, 0, 0, C_XPRE}, 702 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQOREG_16, 67, 4, 0, 0, C_XPOST}, 703 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_UOREG4K, 76, 8, 0, 0, 0}, 704 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NOREG4K, 76, 8, 0, 0, 0}, 705 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_LOREG, 77, 12, 0, LTO, 0}, 706 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_ADDR, 87, 12, 0, 0, 0}, 707 708 {ALDP, C_NPAUTO, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, 0}, 709 {ALDP, C_PPAUTO, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, 0}, 710 {ALDP, C_UAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, 0}, 711 {ALDP, C_NAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, 0}, 712 {ALDP, C_LAUTO, C_NONE, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, 0}, 713 {ALDP, C_NPOREG, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, 0}, 714 {ALDP, C_NPOREG, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE}, 715 {ALDP, C_NPOREG, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST}, 716 {ALDP, C_PPOREG, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, 0}, 717 {ALDP, C_PPOREG, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE}, 718 {ALDP, C_PPOREG, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST}, 719 {ALDP, C_UOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, 0}, 720 {ALDP, C_NOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, 0}, 721 {ALDP, C_LOREG, C_NONE, C_NONE, C_PAIR, 75, 12, 0, LFROM, 0}, 722 {ALDP, C_ADDR, C_NONE, C_NONE, C_PAIR, 88, 12, 0, 0, 0}, 723 724 {ASTP, C_PAIR, C_NONE, C_NONE, C_NPAUTO, 67, 4, REGSP, 0, 0}, 725 {ASTP, C_PAIR, C_NONE, C_NONE, C_PPAUTO, 67, 4, REGSP, 0, 0}, 726 {ASTP, C_PAIR, C_NONE, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, 0}, 727 {ASTP, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, 76, 8, REGSP, 0, 0}, 728 {ASTP, C_PAIR, C_NONE, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, 0}, 729 {ASTP, C_PAIR, C_NONE, C_NONE, C_NPOREG, 67, 4, 0, 0, 0}, 730 {ASTP, C_PAIR, C_NONE, C_NONE, C_NPOREG, 67, 4, 0, 0, C_XPRE}, 731 {ASTP, C_PAIR, C_NONE, C_NONE, C_NPOREG, 67, 4, 0, 0, C_XPOST}, 732 {ASTP, C_PAIR, C_NONE, C_NONE, C_PPOREG, 67, 4, 0, 0, 0}, 733 {ASTP, C_PAIR, C_NONE, C_NONE, C_PPOREG, 67, 4, 0, 0, C_XPRE}, 734 {ASTP, C_PAIR, C_NONE, C_NONE, C_PPOREG, 67, 4, 0, 0, C_XPOST}, 735 {ASTP, C_PAIR, C_NONE, C_NONE, C_UOREG4K, 76, 8, 0, 0, 0}, 736 {ASTP, C_PAIR, C_NONE, C_NONE, C_NOREG4K, 76, 8, 0, 0, 0}, 737 {ASTP, C_PAIR, C_NONE, C_NONE, C_LOREG, 77, 12, 0, LTO, 0}, 738 {ASTP, C_PAIR, C_NONE, C_NONE, C_ADDR, 87, 12, 0, 0, 0}, 739 740 741 {ALDPW, C_NSAUTO_4, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, 0}, 742 {ALDPW, C_PSAUTO_4, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, 0}, 743 {ALDPW, C_UAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, 0}, 744 {ALDPW, C_NAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, 0}, 745 {ALDPW, C_LAUTO, C_NONE, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, 0}, 746 {ALDPW, C_NSOREG_4, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, 0}, 747 {ALDPW, C_NSOREG_4, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE}, 748 {ALDPW, C_NSOREG_4, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST}, 749 {ALDPW, C_PSOREG_4, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, 0}, 750 {ALDPW, C_PSOREG_4, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE}, 751 {ALDPW, C_PSOREG_4, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST}, 752 {ALDPW, C_UOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, 0}, 753 {ALDPW, C_NOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, 0}, 754 {ALDPW, C_LOREG, C_NONE, C_NONE, C_PAIR, 75, 12, 0, LFROM, 0}, 755 {ALDPW, C_ADDR, C_NONE, C_NONE, C_PAIR, 88, 12, 0, 0, 0}, 756 757 {ASTPW, C_PAIR, C_NONE, C_NONE, C_NSAUTO_4, 67, 4, REGSP, 0, 0}, 758 {ASTPW, C_PAIR, C_NONE, C_NONE, C_PSAUTO_4, 67, 4, REGSP, 0, 0}, 759 {ASTPW, C_PAIR, C_NONE, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, 0}, 760 {ASTPW, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, 76, 8, REGSP, 0, 0}, 761 {ASTPW, C_PAIR, C_NONE, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, 0}, 762 {ASTPW, C_PAIR, C_NONE, C_NONE, C_NSOREG_4, 67, 4, 0, 0, 0}, 763 {ASTPW, C_PAIR, C_NONE, C_NONE, C_NSOREG_4, 67, 4, 0, 0, C_XPRE}, 764 {ASTPW, C_PAIR, C_NONE, C_NONE, C_NSOREG_4, 67, 4, 0, 0, C_XPOST}, 765 {ASTPW, C_PAIR, C_NONE, C_NONE, C_PSOREG_4, 67, 4, 0, 0, 0}, 766 {ASTPW, C_PAIR, C_NONE, C_NONE, C_PSOREG_4, 67, 4, 0, 0, C_XPRE}, 767 {ASTPW, C_PAIR, C_NONE, C_NONE, C_PSOREG_4, 67, 4, 0, 0, C_XPOST}, 768 {ASTPW, C_PAIR, C_NONE, C_NONE, C_UOREG4K, 76, 8, 0, 0, 0}, 769 {ASTPW, C_PAIR, C_NONE, C_NONE, C_NOREG4K, 76, 8, 0, 0, 0}, 770 {ASTPW, C_PAIR, C_NONE, C_NONE, C_LOREG, 77, 12, 0, LTO, 0}, 771 {ASTPW, C_PAIR, C_NONE, C_NONE, C_ADDR, 87, 12, 0, 0, 0}, 772 773 {ASWPD, C_ZREG, C_NONE, C_NONE, C_ZOREG, 47, 4, 0, 0, 0}, 774 {ASWPD, C_ZREG, C_NONE, C_NONE, C_ZAUTO, 47, 4, REGSP, 0, 0}, 775 {ACASPD, C_PAIR, C_NONE, C_NONE, C_ZOREG, 106, 4, 0, 0, 0}, 776 {ACASPD, C_PAIR, C_NONE, C_NONE, C_ZAUTO, 106, 4, REGSP, 0, 0}, 777 {ALDAR, C_ZOREG, C_NONE, C_NONE, C_ZREG, 58, 4, 0, 0, 0}, 778 {ALDXR, C_ZOREG, C_NONE, C_NONE, C_ZREG, 58, 4, 0, 0, 0}, 779 {ALDAXR, C_ZOREG, C_NONE, C_NONE, C_ZREG, 58, 4, 0, 0, 0}, 780 {ALDXP, C_ZOREG, C_NONE, C_NONE, C_PAIR, 58, 4, 0, 0, 0}, 781 {ASTLR, C_ZREG, C_NONE, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, 782 {ASTXR, C_ZREG, C_NONE, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, 783 {ASTLXR, C_ZREG, C_NONE, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, 784 {ASTXP, C_PAIR, C_NONE, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, 785 786 787 {AVLD1, C_ZOREG, C_NONE, C_NONE, C_LIST, 81, 4, 0, 0, 0}, 788 {AVLD1, C_LOREG, C_NONE, C_NONE, C_LIST, 81, 4, 0, 0, C_XPOST}, 789 {AVLD1, C_ROFF, C_NONE, C_NONE, C_LIST, 81, 4, 0, 0, C_XPOST}, 790 {AVLD1R, C_ZOREG, C_NONE, C_NONE, C_LIST, 81, 4, 0, 0, 0}, 791 {AVLD1R, C_LOREG, C_NONE, C_NONE, C_LIST, 81, 4, 0, 0, C_XPOST}, 792 {AVLD1R, C_ROFF, C_NONE, C_NONE, C_LIST, 81, 4, 0, 0, C_XPOST}, 793 {AVLD1, C_LOREG, C_NONE, C_NONE, C_ELEM, 97, 4, 0, 0, C_XPOST}, 794 {AVLD1, C_ROFF, C_NONE, C_NONE, C_ELEM, 97, 4, 0, 0, C_XPOST}, 795 {AVLD1, C_LOREG, C_NONE, C_NONE, C_ELEM, 97, 4, 0, 0, 0}, 796 {AVST1, C_LIST, C_NONE, C_NONE, C_ZOREG, 84, 4, 0, 0, 0}, 797 {AVST1, C_LIST, C_NONE, C_NONE, C_LOREG, 84, 4, 0, 0, C_XPOST}, 798 {AVST1, C_LIST, C_NONE, C_NONE, C_ROFF, 84, 4, 0, 0, C_XPOST}, 799 {AVST2, C_LIST, C_NONE, C_NONE, C_ZOREG, 84, 4, 0, 0, 0}, 800 {AVST2, C_LIST, C_NONE, C_NONE, C_LOREG, 84, 4, 0, 0, C_XPOST}, 801 {AVST2, C_LIST, C_NONE, C_NONE, C_ROFF, 84, 4, 0, 0, C_XPOST}, 802 {AVST3, C_LIST, C_NONE, C_NONE, C_ZOREG, 84, 4, 0, 0, 0}, 803 {AVST3, C_LIST, C_NONE, C_NONE, C_LOREG, 84, 4, 0, 0, C_XPOST}, 804 {AVST3, C_LIST, C_NONE, C_NONE, C_ROFF, 84, 4, 0, 0, C_XPOST}, 805 {AVST4, C_LIST, C_NONE, C_NONE, C_ZOREG, 84, 4, 0, 0, 0}, 806 {AVST4, C_LIST, C_NONE, C_NONE, C_LOREG, 84, 4, 0, 0, C_XPOST}, 807 {AVST4, C_LIST, C_NONE, C_NONE, C_ROFF, 84, 4, 0, 0, C_XPOST}, 808 {AVST1, C_ELEM, C_NONE, C_NONE, C_LOREG, 96, 4, 0, 0, C_XPOST}, 809 {AVST1, C_ELEM, C_NONE, C_NONE, C_ROFF, 96, 4, 0, 0, C_XPOST}, 810 {AVST1, C_ELEM, C_NONE, C_NONE, C_LOREG, 96, 4, 0, 0, 0}, 811 812 813 {AMOVD, C_SPR, C_NONE, C_NONE, C_ZREG, 35, 4, 0, 0, 0}, 814 {AMRS, C_SPR, C_NONE, C_NONE, C_ZREG, 35, 4, 0, 0, 0}, 815 {AMOVD, C_ZREG, C_NONE, C_NONE, C_SPR, 36, 4, 0, 0, 0}, 816 {AMSR, C_ZREG, C_NONE, C_NONE, C_SPR, 36, 4, 0, 0, 0}, 817 {AMOVD, C_VCON, C_NONE, C_NONE, C_SPR, 37, 4, 0, 0, 0}, 818 {AMSR, C_VCON, C_NONE, C_NONE, C_SPR, 37, 4, 0, 0, 0}, 819 {AMSR, C_VCON, C_NONE, C_NONE, C_SPOP, 37, 4, 0, 0, 0}, 820 {APRFM, C_UOREG32K, C_NONE, C_NONE, C_SPOP, 91, 4, 0, 0, 0}, 821 {APRFM, C_UOREG32K, C_NONE, C_NONE, C_LCON, 91, 4, 0, 0, 0}, 822 {ADMB, C_VCON, C_NONE, C_NONE, C_NONE, 51, 4, 0, 0, 0}, 823 {AHINT, C_VCON, C_NONE, C_NONE, C_NONE, 52, 4, 0, 0, 0}, 824 {ASYS, C_VCON, C_NONE, C_NONE, C_NONE, 50, 4, 0, 0, 0}, 825 {ASYS, C_VCON, C_NONE, C_NONE, C_ZREG, 50, 4, 0, 0, 0}, 826 {ASYSL, C_VCON, C_NONE, C_NONE, C_ZREG, 50, 4, 0, 0, 0}, 827 {ATLBI, C_SPOP, C_NONE, C_NONE, C_NONE, 107, 4, 0, 0, 0}, 828 {ATLBI, C_SPOP, C_NONE, C_NONE, C_ZREG, 107, 4, 0, 0, 0}, 829 830 831 {AAESD, C_VREG, C_NONE, C_NONE, C_VREG, 29, 4, 0, 0, 0}, 832 {AAESD, C_ARNG, C_NONE, C_NONE, C_ARNG, 29, 4, 0, 0, 0}, 833 {ASHA1C, C_VREG, C_ZREG, C_NONE, C_VREG, 1, 4, 0, 0, 0}, 834 {ASHA1C, C_ARNG, C_VREG, C_NONE, C_VREG, 1, 4, 0, 0, 0}, 835 {ASHA1H, C_VREG, C_NONE, C_NONE, C_VREG, 29, 4, 0, 0, 0}, 836 {ASHA1SU0, C_ARNG, C_ARNG, C_NONE, C_ARNG, 1, 4, 0, 0, 0}, 837 {ASHA256H, C_ARNG, C_VREG, C_NONE, C_VREG, 1, 4, 0, 0, 0}, 838 {AVREV32, C_ARNG, C_NONE, C_NONE, C_ARNG, 83, 4, 0, 0, 0}, 839 {AVPMULL, C_ARNG, C_ARNG, C_NONE, C_ARNG, 93, 4, 0, 0, 0}, 840 {AVEOR3, C_ARNG, C_ARNG, C_ARNG, C_ARNG, 103, 4, 0, 0, 0}, 841 {AVXAR, C_VCON, C_ARNG, C_ARNG, C_ARNG, 104, 4, 0, 0, 0}, 842 843 {obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 90, 4, 0, 0, 0}, 844 {obj.APCDATA, C_VCON, C_NONE, C_NONE, C_VCON, 0, 0, 0, 0, 0}, 845 {obj.AFUNCDATA, C_VCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0, 0, 0}, 846 {obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0}, 847 {obj.ANOP, C_LCON, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0}, 848 {obj.ANOP, C_ZREG, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0}, 849 {obj.ANOP, C_VREG, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0}, 850 {obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, 851 {obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, 852 {obj.APCALIGN, C_LCON, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0}, 853 854 {obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0, 0}, 855 } 856 857 858 859 var pstatefield = []struct { 860 opd SpecialOperand 861 enc uint32 862 }{ 863 {SPOP_DAIFSet, 3<<16 | 4<<12 | 6<<5}, 864 {SPOP_DAIFClr, 3<<16 | 4<<12 | 7<<5}, 865 } 866 867 var prfopfield = map[SpecialOperand]uint32{ 868 SPOP_PLDL1KEEP: 0, 869 SPOP_PLDL1STRM: 1, 870 SPOP_PLDL2KEEP: 2, 871 SPOP_PLDL2STRM: 3, 872 SPOP_PLDL3KEEP: 4, 873 SPOP_PLDL3STRM: 5, 874 SPOP_PLIL1KEEP: 8, 875 SPOP_PLIL1STRM: 9, 876 SPOP_PLIL2KEEP: 10, 877 SPOP_PLIL2STRM: 11, 878 SPOP_PLIL3KEEP: 12, 879 SPOP_PLIL3STRM: 13, 880 SPOP_PSTL1KEEP: 16, 881 SPOP_PSTL1STRM: 17, 882 SPOP_PSTL2KEEP: 18, 883 SPOP_PSTL2STRM: 19, 884 SPOP_PSTL3KEEP: 20, 885 SPOP_PSTL3STRM: 21, 886 } 887 888 889 890 891 892 893 var sysInstFields = map[SpecialOperand]struct { 894 op1 uint8 895 cn uint8 896 cm uint8 897 op2 uint8 898 hasOperand2 bool 899 }{ 900 901 SPOP_VMALLE1IS: {0, 8, 3, 0, false}, 902 SPOP_VAE1IS: {0, 8, 3, 1, true}, 903 SPOP_ASIDE1IS: {0, 8, 3, 2, true}, 904 SPOP_VAAE1IS: {0, 8, 3, 3, true}, 905 SPOP_VALE1IS: {0, 8, 3, 5, true}, 906 SPOP_VAALE1IS: {0, 8, 3, 7, true}, 907 SPOP_VMALLE1: {0, 8, 7, 0, false}, 908 SPOP_VAE1: {0, 8, 7, 1, true}, 909 SPOP_ASIDE1: {0, 8, 7, 2, true}, 910 SPOP_VAAE1: {0, 8, 7, 3, true}, 911 SPOP_VALE1: {0, 8, 7, 5, true}, 912 SPOP_VAALE1: {0, 8, 7, 7, true}, 913 SPOP_IPAS2E1IS: {4, 8, 0, 1, true}, 914 SPOP_IPAS2LE1IS: {4, 8, 0, 5, true}, 915 SPOP_ALLE2IS: {4, 8, 3, 0, false}, 916 SPOP_VAE2IS: {4, 8, 3, 1, true}, 917 SPOP_ALLE1IS: {4, 8, 3, 4, false}, 918 SPOP_VALE2IS: {4, 8, 3, 5, true}, 919 SPOP_VMALLS12E1IS: {4, 8, 3, 6, false}, 920 SPOP_IPAS2E1: {4, 8, 4, 1, true}, 921 SPOP_IPAS2LE1: {4, 8, 4, 5, true}, 922 SPOP_ALLE2: {4, 8, 7, 0, false}, 923 SPOP_VAE2: {4, 8, 7, 1, true}, 924 SPOP_ALLE1: {4, 8, 7, 4, false}, 925 SPOP_VALE2: {4, 8, 7, 5, true}, 926 SPOP_VMALLS12E1: {4, 8, 7, 6, false}, 927 SPOP_ALLE3IS: {6, 8, 3, 0, false}, 928 SPOP_VAE3IS: {6, 8, 3, 1, true}, 929 SPOP_VALE3IS: {6, 8, 3, 5, true}, 930 SPOP_ALLE3: {6, 8, 7, 0, false}, 931 SPOP_VAE3: {6, 8, 7, 1, true}, 932 SPOP_VALE3: {6, 8, 7, 5, true}, 933 SPOP_VMALLE1OS: {0, 8, 1, 0, false}, 934 SPOP_VAE1OS: {0, 8, 1, 1, true}, 935 SPOP_ASIDE1OS: {0, 8, 1, 2, true}, 936 SPOP_VAAE1OS: {0, 8, 1, 3, true}, 937 SPOP_VALE1OS: {0, 8, 1, 5, true}, 938 SPOP_VAALE1OS: {0, 8, 1, 7, true}, 939 SPOP_RVAE1IS: {0, 8, 2, 1, true}, 940 SPOP_RVAAE1IS: {0, 8, 2, 3, true}, 941 SPOP_RVALE1IS: {0, 8, 2, 5, true}, 942 SPOP_RVAALE1IS: {0, 8, 2, 7, true}, 943 SPOP_RVAE1OS: {0, 8, 5, 1, true}, 944 SPOP_RVAAE1OS: {0, 8, 5, 3, true}, 945 SPOP_RVALE1OS: {0, 8, 5, 5, true}, 946 SPOP_RVAALE1OS: {0, 8, 5, 7, true}, 947 SPOP_RVAE1: {0, 8, 6, 1, true}, 948 SPOP_RVAAE1: {0, 8, 6, 3, true}, 949 SPOP_RVALE1: {0, 8, 6, 5, true}, 950 SPOP_RVAALE1: {0, 8, 6, 7, true}, 951 SPOP_RIPAS2E1IS: {4, 8, 0, 2, true}, 952 SPOP_RIPAS2LE1IS: {4, 8, 0, 6, true}, 953 SPOP_ALLE2OS: {4, 8, 1, 0, false}, 954 SPOP_VAE2OS: {4, 8, 1, 1, true}, 955 SPOP_ALLE1OS: {4, 8, 1, 4, false}, 956 SPOP_VALE2OS: {4, 8, 1, 5, true}, 957 SPOP_VMALLS12E1OS: {4, 8, 1, 6, false}, 958 SPOP_RVAE2IS: {4, 8, 2, 1, true}, 959 SPOP_RVALE2IS: {4, 8, 2, 5, true}, 960 SPOP_IPAS2E1OS: {4, 8, 4, 0, true}, 961 SPOP_RIPAS2E1: {4, 8, 4, 2, true}, 962 SPOP_RIPAS2E1OS: {4, 8, 4, 3, true}, 963 SPOP_IPAS2LE1OS: {4, 8, 4, 4, true}, 964 SPOP_RIPAS2LE1: {4, 8, 4, 6, true}, 965 SPOP_RIPAS2LE1OS: {4, 8, 4, 7, true}, 966 SPOP_RVAE2OS: {4, 8, 5, 1, true}, 967 SPOP_RVALE2OS: {4, 8, 5, 5, true}, 968 SPOP_RVAE2: {4, 8, 6, 1, true}, 969 SPOP_RVALE2: {4, 8, 6, 5, true}, 970 SPOP_ALLE3OS: {6, 8, 1, 0, false}, 971 SPOP_VAE3OS: {6, 8, 1, 1, true}, 972 SPOP_VALE3OS: {6, 8, 1, 5, true}, 973 SPOP_RVAE3IS: {6, 8, 2, 1, true}, 974 SPOP_RVALE3IS: {6, 8, 2, 5, true}, 975 SPOP_RVAE3OS: {6, 8, 5, 1, true}, 976 SPOP_RVALE3OS: {6, 8, 5, 5, true}, 977 SPOP_RVAE3: {6, 8, 6, 1, true}, 978 SPOP_RVALE3: {6, 8, 6, 5, true}, 979 980 SPOP_IVAC: {0, 7, 6, 1, true}, 981 SPOP_ISW: {0, 7, 6, 2, true}, 982 SPOP_CSW: {0, 7, 10, 2, true}, 983 SPOP_CISW: {0, 7, 14, 2, true}, 984 SPOP_ZVA: {3, 7, 4, 1, true}, 985 SPOP_CVAC: {3, 7, 10, 1, true}, 986 SPOP_CVAU: {3, 7, 11, 1, true}, 987 SPOP_CIVAC: {3, 7, 14, 1, true}, 988 SPOP_IGVAC: {0, 7, 6, 3, true}, 989 SPOP_IGSW: {0, 7, 6, 4, true}, 990 SPOP_IGDVAC: {0, 7, 6, 5, true}, 991 SPOP_IGDSW: {0, 7, 6, 6, true}, 992 SPOP_CGSW: {0, 7, 10, 4, true}, 993 SPOP_CGDSW: {0, 7, 10, 6, true}, 994 SPOP_CIGSW: {0, 7, 14, 4, true}, 995 SPOP_CIGDSW: {0, 7, 14, 6, true}, 996 SPOP_GVA: {3, 7, 4, 3, true}, 997 SPOP_GZVA: {3, 7, 4, 4, true}, 998 SPOP_CGVAC: {3, 7, 10, 3, true}, 999 SPOP_CGDVAC: {3, 7, 10, 5, true}, 1000 SPOP_CGVAP: {3, 7, 12, 3, true}, 1001 SPOP_CGDVAP: {3, 7, 12, 5, true}, 1002 SPOP_CGVADP: {3, 7, 13, 3, true}, 1003 SPOP_CGDVADP: {3, 7, 13, 5, true}, 1004 SPOP_CIGVAC: {3, 7, 14, 3, true}, 1005 SPOP_CIGDVAC: {3, 7, 14, 5, true}, 1006 SPOP_CVAP: {3, 7, 12, 1, true}, 1007 SPOP_CVADP: {3, 7, 13, 1, true}, 1008 } 1009 1010 1011 const OP_NOOP = 0xd503201f 1012 1013 1014 1015 func pcAlignPadLength(ctxt *obj.Link, pc int64, alignedValue int64) int { 1016 if !((alignedValue&(alignedValue-1) == 0) && 8 <= alignedValue && alignedValue <= 2048) { 1017 ctxt.Diag("alignment value of an instruction must be a power of two and in the range [8, 2048], got %d\n", alignedValue) 1018 } 1019 return int(-pc & (alignedValue - 1)) 1020 } 1021 1022 1023 1024 1025 1026 func (o *Optab) size(ctxt *obj.Link, p *obj.Prog) int { 1027 1028 sz := movesize(p.As) 1029 if sz != -1 { 1030 1031 1032 1033 1034 align := int64(1 << sz) 1035 if o.a1 == C_ADDR && p.From.Offset%align == 0 && !strings.HasPrefix(p.From.Sym.Name, "go:string.") || 1036 o.a4 == C_ADDR && p.To.Offset%align == 0 && !strings.HasPrefix(p.To.Sym.Name, "go:string.") { 1037 return 8 1038 } 1039 } 1040 return int(o.size_) 1041 } 1042 1043 func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { 1044 if ctxt.Retpoline { 1045 ctxt.Diag("-spectre=ret not supported on arm64") 1046 ctxt.Retpoline = false 1047 } 1048 1049 p := cursym.Func().Text 1050 if p == nil || p.Link == nil { 1051 return 1052 } 1053 1054 if oprange[AAND&obj.AMask] == nil { 1055 ctxt.Diag("arm64 ops not initialized, call arm64.buildop first") 1056 } 1057 1058 c := ctxt7{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: int32(p.To.Offset & 0xffffffff), extrasize: int32(p.To.Offset >> 32)} 1059 p.To.Offset &= 0xffffffff 1060 1061 bflag := 1 1062 pc := int64(0) 1063 p.Pc = pc 1064 var m int 1065 var o *Optab 1066 for p = p.Link; p != nil; p = p.Link { 1067 p.Pc = pc 1068 o = c.oplook(p) 1069 m = o.size(c.ctxt, p) 1070 if m == 0 { 1071 switch p.As { 1072 case obj.APCALIGN: 1073 alignedValue := p.From.Offset 1074 m = pcAlignPadLength(ctxt, pc, alignedValue) 1075 1076 if int32(alignedValue) > cursym.Func().Align { 1077 cursym.Func().Align = int32(alignedValue) 1078 } 1079 break 1080 case obj.ANOP, obj.AFUNCDATA, obj.APCDATA: 1081 continue 1082 default: 1083 c.ctxt.Diag("zero-width instruction\n%v", p) 1084 } 1085 } 1086 pc += int64(m) 1087 1088 if o.flag&LFROM != 0 { 1089 c.addpool(p, &p.From) 1090 } 1091 if o.flag&LFROM128 != 0 { 1092 c.addpool128(p, &p.From, p.GetFrom3()) 1093 } 1094 if o.flag<O != 0 { 1095 c.addpool(p, &p.To) 1096 } 1097 if c.blitrl != nil { 1098 c.checkpool(p) 1099 } 1100 } 1101 1102 c.cursym.Size = pc 1103 1104 1105 for bflag != 0 { 1106 bflag = 0 1107 pc = 0 1108 for p = c.cursym.Func().Text.Link; p != nil; p = p.Link { 1109 p.Pc = pc 1110 o = c.oplook(p) 1111 1112 1113 if (o.flag&BRANCH14BITS != 0 || o.flag&BRANCH19BITS != 0) && p.To.Target() != nil { 1114 otxt := p.To.Target().Pc - pc 1115 var toofar bool 1116 if o.flag&BRANCH14BITS != 0 { 1117 toofar = otxt <= -(1<<15)+10 || otxt >= (1<<15)-10 1118 } else if o.flag&BRANCH19BITS != 0 { 1119 toofar = otxt <= -(1<<20)+10 || otxt >= (1<<20)-10 1120 } 1121 if toofar { 1122 q := c.newprog() 1123 q.Link = p.Link 1124 p.Link = q 1125 q.As = AB 1126 q.To.Type = obj.TYPE_BRANCH 1127 q.To.SetTarget(p.To.Target()) 1128 p.To.SetTarget(q) 1129 q = c.newprog() 1130 q.Link = p.Link 1131 p.Link = q 1132 q.As = AB 1133 q.To.Type = obj.TYPE_BRANCH 1134 q.To.SetTarget(q.Link.Link) 1135 bflag = 1 1136 } 1137 } 1138 m = o.size(c.ctxt, p) 1139 1140 if m == 0 { 1141 switch p.As { 1142 case obj.APCALIGN: 1143 alignedValue := p.From.Offset 1144 m = pcAlignPadLength(ctxt, pc, alignedValue) 1145 break 1146 case obj.ANOP, obj.AFUNCDATA, obj.APCDATA: 1147 continue 1148 default: 1149 c.ctxt.Diag("zero-width instruction\n%v", p) 1150 } 1151 } 1152 1153 pc += int64(m) 1154 } 1155 } 1156 1157 pc += -pc & (funcAlign - 1) 1158 c.cursym.Size = pc 1159 1160 1161 c.cursym.Grow(c.cursym.Size) 1162 bp := c.cursym.P 1163 psz := int32(0) 1164 var i int 1165 var out [6]uint32 1166 for p := c.cursym.Func().Text.Link; p != nil; p = p.Link { 1167 c.pc = p.Pc 1168 o = c.oplook(p) 1169 sz := o.size(c.ctxt, p) 1170 if sz > 4*len(out) { 1171 log.Fatalf("out array in span7 is too small, need at least %d for %v", sz/4, p) 1172 } 1173 if p.As == obj.APCALIGN { 1174 alignedValue := p.From.Offset 1175 v := pcAlignPadLength(c.ctxt, p.Pc, alignedValue) 1176 for i = 0; i < int(v/4); i++ { 1177 1178 c.ctxt.Arch.ByteOrder.PutUint32(bp, OP_NOOP) 1179 bp = bp[4:] 1180 psz += 4 1181 } 1182 } else { 1183 c.asmout(p, o, out[:]) 1184 for i = 0; i < sz/4; i++ { 1185 c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i]) 1186 bp = bp[4:] 1187 psz += 4 1188 } 1189 } 1190 } 1191 1192 1193 1194 1195 1196 obj.MarkUnsafePoints(c.ctxt, c.cursym.Func().Text, c.newprog, c.isUnsafePoint, c.isRestartable) 1197 1198 1199 for _, jt := range cursym.Func().JumpTables { 1200 for i, p := range jt.Targets { 1201 1202 1203 1204 jt.Sym.WriteAddr(ctxt, int64(i)*8, 8, cursym, p.Pc) 1205 } 1206 } 1207 } 1208 1209 1210 func (c *ctxt7) isUnsafePoint(p *obj.Prog) bool { 1211 1212 1213 return p.From.Reg == REGTMP || p.To.Reg == REGTMP || p.Reg == REGTMP || 1214 p.From.Type == obj.TYPE_REGREG && p.From.Offset == REGTMP || 1215 p.To.Type == obj.TYPE_REGREG && p.To.Offset == REGTMP 1216 } 1217 1218 1219 1220 func (c *ctxt7) isRestartable(p *obj.Prog) bool { 1221 if c.isUnsafePoint(p) { 1222 return false 1223 } 1224 1225 1226 1227 1228 1229 1230 1231 o := c.oplook(p) 1232 return o.size(c.ctxt, p) > 4 && o.flag&NOTUSETMP == 0 1233 } 1234 1235 1236 func (c *ctxt7) checkpool(p *obj.Prog) { 1237 1238 1239 if c.pool.size >= 0xffff0 || !ispcdisp(int32(p.Pc+4+int64(c.pool.size)-int64(c.pool.start)+8)) || p.Link == nil { 1240 c.flushpool(p) 1241 } 1242 } 1243 1244 func (c *ctxt7) flushpool(p *obj.Prog) { 1245 1246 1247 1248 if !(p.As == AB || p.As == obj.ARET || p.As == AERET) { 1249 if c.ctxt.Debugvlog { 1250 fmt.Printf("note: flush literal pool at %#x: len=%d ref=%x\n", uint64(p.Pc+4), c.pool.size, c.pool.start) 1251 } 1252 q := c.newprog() 1253 if p.Link == nil { 1254 1255 1256 q.As = obj.AUNDEF 1257 } else { 1258 1259 q.As = AB 1260 q.To.Type = obj.TYPE_BRANCH 1261 q.To.SetTarget(p.Link) 1262 } 1263 q.Link = c.blitrl 1264 q.Pos = p.Pos 1265 c.blitrl = q 1266 } 1267 1268 1269 1270 1271 for q := c.blitrl; q != nil; q = q.Link { 1272 q.Pos = p.Pos 1273 } 1274 1275 c.elitrl.Link = p.Link 1276 p.Link = c.blitrl 1277 1278 c.blitrl = nil 1279 c.elitrl = nil 1280 c.pool.size = 0 1281 c.pool.start = 0 1282 } 1283 1284 1285 1286 func (c *ctxt7) addpool128(p *obj.Prog, al, ah *obj.Addr) { 1287 q := c.newprog() 1288 q.As = ADWORD 1289 q.To.Type = obj.TYPE_CONST 1290 q.To.Offset = al.Offset 1291 1292 t := c.newprog() 1293 t.As = ADWORD 1294 t.To.Type = obj.TYPE_CONST 1295 t.To.Offset = ah.Offset 1296 1297 q.Link = t 1298 1299 if c.blitrl == nil { 1300 c.blitrl = q 1301 c.pool.start = uint32(p.Pc) 1302 } else { 1303 c.elitrl.Link = q 1304 } 1305 1306 c.elitrl = t 1307 c.pool.size = roundUp(c.pool.size, 16) 1308 c.pool.size += 16 1309 p.Pool = q 1310 } 1311 1312 1313 func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) { 1314 cls := c.aclass(a) 1315 lit := c.instoffset 1316 t := c.newprog() 1317 t.As = AWORD 1318 sz := 4 1319 1320 if a.Type == obj.TYPE_CONST { 1321 if (lit != int64(int32(lit)) && uint64(lit) != uint64(uint32(lit))) || p.As == AVMOVQ || p.As == AVMOVD { 1322 1323 t.As = ADWORD 1324 sz = 8 1325 } 1326 } else if p.As == AMOVD && a.Type != obj.TYPE_MEM || cls == C_ADDR || cls == C_VCON || lit != int64(int32(lit)) || uint64(lit) != uint64(uint32(lit)) { 1327 1328 1329 t.As = ADWORD 1330 sz = 8 1331 } 1332 1333 t.To.Type = obj.TYPE_CONST 1334 t.To.Offset = lit 1335 1336 for q := c.blitrl; q != nil; q = q.Link { 1337 if q.To == t.To { 1338 p.Pool = q 1339 return 1340 } 1341 } 1342 1343 if c.blitrl == nil { 1344 c.blitrl = t 1345 c.pool.start = uint32(p.Pc) 1346 } else { 1347 c.elitrl.Link = t 1348 } 1349 c.elitrl = t 1350 if t.As == ADWORD { 1351 1352 1353 1354 c.pool.size = roundUp(c.pool.size, 8) 1355 } 1356 c.pool.size += uint32(sz) 1357 p.Pool = t 1358 } 1359 1360 1361 func roundUp(x, to uint32) uint32 { 1362 if to == 0 || to&(to-1) != 0 { 1363 log.Fatalf("rounded up to a value that is not a power of 2: %d\n", to) 1364 } 1365 return (x + to - 1) &^ (to - 1) 1366 } 1367 1368 func (c *ctxt7) regoff(a *obj.Addr) int32 { 1369 c.instoffset = 0 1370 c.aclass(a) 1371 return int32(c.instoffset) 1372 } 1373 1374 func isSTLXRop(op obj.As) bool { 1375 switch op { 1376 case ASTLXR, ASTLXRW, ASTLXRB, ASTLXRH, 1377 ASTXR, ASTXRW, ASTXRB, ASTXRH: 1378 return true 1379 } 1380 return false 1381 } 1382 1383 func isSTXPop(op obj.As) bool { 1384 switch op { 1385 case ASTXP, ASTLXP, ASTXPW, ASTLXPW: 1386 return true 1387 } 1388 return false 1389 } 1390 1391 func isANDop(op obj.As) bool { 1392 switch op { 1393 case AAND, AORR, AEOR, AANDS, ATST, 1394 ABIC, AEON, AORN, ABICS: 1395 return true 1396 } 1397 return false 1398 } 1399 1400 func isANDWop(op obj.As) bool { 1401 switch op { 1402 case AANDW, AORRW, AEORW, AANDSW, ATSTW, 1403 ABICW, AEONW, AORNW, ABICSW: 1404 return true 1405 } 1406 return false 1407 } 1408 1409 func isADDop(op obj.As) bool { 1410 switch op { 1411 case AADD, AADDS, ASUB, ASUBS, ACMN, ACMP: 1412 return true 1413 } 1414 return false 1415 } 1416 1417 func isADDWop(op obj.As) bool { 1418 switch op { 1419 case AADDW, AADDSW, ASUBW, ASUBSW, ACMNW, ACMPW: 1420 return true 1421 } 1422 return false 1423 } 1424 1425 func isADDSop(op obj.As) bool { 1426 switch op { 1427 case AADDS, AADDSW, ASUBS, ASUBSW: 1428 return true 1429 } 1430 return false 1431 } 1432 1433 func isNEGop(op obj.As) bool { 1434 switch op { 1435 case ANEG, ANEGW, ANEGS, ANEGSW: 1436 return true 1437 } 1438 return false 1439 } 1440 1441 func isRegShiftOrExt(a *obj.Addr) bool { 1442 return (a.Index-obj.RBaseARM64)®_EXT != 0 || (a.Index-obj.RBaseARM64)®_LSL != 0 1443 } 1444 1445 1446 1447 1448 1449 const maxPCDisp = 512 * 1024 1450 1451 1452 func ispcdisp(v int32) bool { 1453 return -maxPCDisp < v && v < maxPCDisp && v&3 == 0 1454 } 1455 1456 func isaddcon(v int64) bool { 1457 1458 if v < 0 { 1459 return false 1460 } 1461 if (v & 0xFFF) == 0 { 1462 v >>= 12 1463 } 1464 return v <= 0xFFF 1465 } 1466 1467 func isaddcon2(v int64) bool { 1468 return 0 <= v && v <= 0xFFFFFF 1469 } 1470 1471 1472 1473 1474 1475 1476 1477 func isbitcon(x uint64) bool { 1478 if x == 1<<64-1 || x == 0 { 1479 return false 1480 } 1481 1482 switch { 1483 case x != x>>32|x<<32: 1484 1485 1486 case x != x>>16|x<<48: 1487 1488 x = uint64(int64(int32(x))) 1489 case x != x>>8|x<<56: 1490 1491 x = uint64(int64(int16(x))) 1492 case x != x>>4|x<<60: 1493 1494 x = uint64(int64(int8(x))) 1495 default: 1496 1497 1498 1499 1500 1501 return true 1502 } 1503 return sequenceOfOnes(x) || sequenceOfOnes(^x) 1504 } 1505 1506 1507 func sequenceOfOnes(x uint64) bool { 1508 y := x & -x 1509 y += x 1510 return (y-1)&y == 0 1511 } 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 func bitconEncode(x uint64, mode int) uint32 { 1527 if mode == 32 { 1528 x &= 0xffffffff 1529 x = x<<32 | x 1530 } 1531 var period uint32 1532 1533 switch { 1534 case x != x>>32|x<<32: 1535 period = 64 1536 case x != x>>16|x<<48: 1537 period = 32 1538 x = uint64(int64(int32(x))) 1539 case x != x>>8|x<<56: 1540 period = 16 1541 x = uint64(int64(int16(x))) 1542 case x != x>>4|x<<60: 1543 period = 8 1544 x = uint64(int64(int8(x))) 1545 case x != x>>2|x<<62: 1546 period = 4 1547 x = uint64(int64(x<<60) >> 60) 1548 default: 1549 period = 2 1550 x = uint64(int64(x<<62) >> 62) 1551 } 1552 neg := false 1553 if int64(x) < 0 { 1554 x = ^x 1555 neg = true 1556 } 1557 y := x & -x 1558 s := log2(y) 1559 n := log2(x+y) - s 1560 if neg { 1561 1562 1563 s = n + s 1564 n = period - n 1565 } 1566 1567 N := uint32(0) 1568 if mode == 64 && period == 64 { 1569 N = 1 1570 } 1571 R := (period - s) & (period - 1) & uint32(mode-1) 1572 S := (n - 1) | 63&^(period<<1-1) 1573 return N<<22 | R<<16 | S<<10 1574 } 1575 1576 func log2(x uint64) uint32 { 1577 if x == 0 { 1578 panic("log2 of 0") 1579 } 1580 n := uint32(0) 1581 if x >= 1<<32 { 1582 x >>= 32 1583 n += 32 1584 } 1585 if x >= 1<<16 { 1586 x >>= 16 1587 n += 16 1588 } 1589 if x >= 1<<8 { 1590 x >>= 8 1591 n += 8 1592 } 1593 if x >= 1<<4 { 1594 x >>= 4 1595 n += 4 1596 } 1597 if x >= 1<<2 { 1598 x >>= 2 1599 n += 2 1600 } 1601 if x >= 1<<1 { 1602 x >>= 1 1603 n += 1 1604 } 1605 return n 1606 } 1607 1608 func autoclass(l int64) int { 1609 if l == 0 { 1610 return C_ZAUTO 1611 } 1612 1613 if l < 0 { 1614 if l >= -256 && (l&15) == 0 { 1615 return C_NSAUTO_16 1616 } 1617 if l >= -256 && (l&7) == 0 { 1618 return C_NSAUTO_8 1619 } 1620 if l >= -256 && (l&3) == 0 { 1621 return C_NSAUTO_4 1622 } 1623 if l >= -256 { 1624 return C_NSAUTO 1625 } 1626 if l >= -512 && (l&15) == 0 { 1627 return C_NPAUTO_16 1628 } 1629 if l >= -512 && (l&7) == 0 { 1630 return C_NPAUTO 1631 } 1632 if l >= -1024 && (l&15) == 0 { 1633 return C_NQAUTO_16 1634 } 1635 if l >= -4095 { 1636 return C_NAUTO4K 1637 } 1638 return C_LAUTO 1639 } 1640 1641 if l <= 255 { 1642 if (l & 15) == 0 { 1643 return C_PSAUTO_16 1644 } 1645 if (l & 7) == 0 { 1646 return C_PSAUTO_8 1647 } 1648 if (l & 3) == 0 { 1649 return C_PSAUTO_4 1650 } 1651 return C_PSAUTO 1652 } 1653 if l <= 504 { 1654 if l&15 == 0 { 1655 return C_PPAUTO_16 1656 } 1657 if l&7 == 0 { 1658 return C_PPAUTO 1659 } 1660 } 1661 if l <= 1008 { 1662 if l&15 == 0 { 1663 return C_PQAUTO_16 1664 } 1665 } 1666 if l <= 4095 { 1667 if l&15 == 0 { 1668 return C_UAUTO4K_16 1669 } 1670 if l&7 == 0 { 1671 return C_UAUTO4K_8 1672 } 1673 if l&3 == 0 { 1674 return C_UAUTO4K_4 1675 } 1676 if l&1 == 0 { 1677 return C_UAUTO4K_2 1678 } 1679 return C_UAUTO4K 1680 } 1681 if l <= 8190 { 1682 if l&15 == 0 { 1683 return C_UAUTO8K_16 1684 } 1685 if l&7 == 0 { 1686 return C_UAUTO8K_8 1687 } 1688 if l&3 == 0 { 1689 return C_UAUTO8K_4 1690 } 1691 if l&1 == 0 { 1692 return C_UAUTO8K 1693 } 1694 } 1695 if l <= 16380 { 1696 if l&15 == 0 { 1697 return C_UAUTO16K_16 1698 } 1699 if l&7 == 0 { 1700 return C_UAUTO16K_8 1701 } 1702 if l&3 == 0 { 1703 return C_UAUTO16K 1704 } 1705 } 1706 if l <= 32760 { 1707 if l&15 == 0 { 1708 return C_UAUTO32K_16 1709 } 1710 if l&7 == 0 { 1711 return C_UAUTO32K 1712 } 1713 } 1714 if l <= 65520 && (l&15) == 0 { 1715 return C_UAUTO64K 1716 } 1717 return C_LAUTO 1718 } 1719 1720 func oregclass(l int64) int { 1721 return autoclass(l) - C_ZAUTO + C_ZOREG 1722 } 1723 1724 1725 func (c *ctxt7) offsetshift(p *obj.Prog, v int64, cls int) int64 { 1726 s := 0 1727 if cls >= C_SEXT1 && cls <= C_SEXT16 { 1728 s = cls - C_SEXT1 1729 } else { 1730 switch cls { 1731 case C_UAUTO4K, C_UOREG4K, C_ZOREG: 1732 s = 0 1733 case C_UAUTO8K, C_UOREG8K: 1734 s = 1 1735 case C_UAUTO16K, C_UOREG16K: 1736 s = 2 1737 case C_UAUTO32K, C_UOREG32K: 1738 s = 3 1739 case C_UAUTO64K, C_UOREG64K: 1740 s = 4 1741 default: 1742 c.ctxt.Diag("bad class: %v\n%v", DRconv(cls), p) 1743 } 1744 } 1745 vs := v >> uint(s) 1746 if vs<<uint(s) != v { 1747 c.ctxt.Diag("odd offset: %d\n%v", v, p) 1748 } 1749 return vs 1750 } 1751 1752 1753 func movcon(v int64) int { 1754 for s := 0; s < 64; s += 16 { 1755 if (uint64(v) &^ (uint64(0xFFFF) << uint(s))) == 0 { 1756 return s / 16 1757 } 1758 } 1759 return -1 1760 } 1761 1762 func rclass(r int16) int { 1763 switch { 1764 case REG_R0 <= r && r <= REG_R30: 1765 return C_REG 1766 case r == REGZERO: 1767 return C_ZREG 1768 case REG_F0 <= r && r <= REG_F31: 1769 return C_FREG 1770 case REG_V0 <= r && r <= REG_V31: 1771 return C_VREG 1772 case r == REGSP: 1773 return C_RSP 1774 case r >= REG_ARNG && r < REG_ELEM: 1775 return C_ARNG 1776 case r >= REG_ELEM && r < REG_ELEM_END: 1777 return C_ELEM 1778 case r >= REG_UXTB && r < REG_SPECIAL, 1779 r >= REG_LSL && r < REG_ARNG: 1780 return C_EXTREG 1781 case r >= REG_SPECIAL: 1782 return C_SPR 1783 } 1784 return C_GOK 1785 } 1786 1787 1788 1789 func (c *ctxt7) con32class(a *obj.Addr) int { 1790 v := uint32(a.Offset) 1791 1792 1793 1794 1795 1796 1797 vbitcon := uint64(v)<<32 | uint64(v) 1798 if v == 0 { 1799 return C_ZCON 1800 } 1801 if isaddcon(int64(v)) { 1802 if v <= 0xFFF { 1803 if isbitcon(vbitcon) { 1804 return C_ABCON0 1805 } 1806 return C_ADDCON0 1807 } 1808 if isbitcon(vbitcon) { 1809 return C_ABCON 1810 } 1811 if movcon(int64(v)) >= 0 { 1812 return C_AMCON 1813 } 1814 if movcon(int64(^v)) >= 0 { 1815 return C_AMCON 1816 } 1817 return C_ADDCON 1818 } 1819 1820 t := movcon(int64(v)) 1821 if t >= 0 { 1822 if isbitcon(vbitcon) { 1823 return C_MBCON 1824 } 1825 return C_MOVCON 1826 } 1827 1828 t = movcon(int64(^v)) 1829 if t >= 0 { 1830 if isbitcon(vbitcon) { 1831 return C_MBCON 1832 } 1833 return C_MOVCON 1834 } 1835 1836 if isbitcon(vbitcon) { 1837 return C_BITCON 1838 } 1839 1840 if 0 <= v && v <= 0xffffff { 1841 return C_ADDCON2 1842 } 1843 return C_LCON 1844 } 1845 1846 1847 func (c *ctxt7) con64class(a *obj.Addr) int { 1848 zeroCount := 0 1849 negCount := 0 1850 for i := uint(0); i < 4; i++ { 1851 immh := uint32(a.Offset >> (i * 16) & 0xffff) 1852 if immh == 0 { 1853 zeroCount++ 1854 } else if immh == 0xffff { 1855 negCount++ 1856 } 1857 } 1858 if zeroCount >= 3 || negCount >= 3 { 1859 return C_MOVCON 1860 } else if zeroCount == 2 || negCount == 2 { 1861 return C_MOVCON2 1862 } else if zeroCount == 1 || negCount == 1 { 1863 return C_MOVCON3 1864 } else { 1865 return C_VCON 1866 } 1867 } 1868 1869 func (c *ctxt7) aclass(a *obj.Addr) int { 1870 switch a.Type { 1871 case obj.TYPE_NONE: 1872 return C_NONE 1873 1874 case obj.TYPE_REG: 1875 return rclass(a.Reg) 1876 1877 case obj.TYPE_REGREG: 1878 return C_PAIR 1879 1880 case obj.TYPE_SHIFT: 1881 return C_SHIFT 1882 1883 case obj.TYPE_REGLIST: 1884 return C_LIST 1885 1886 case obj.TYPE_MEM: 1887 1888 if int16(REG_F0) <= a.Reg && a.Reg <= int16(REG_V31) { 1889 break 1890 } 1891 switch a.Name { 1892 case obj.NAME_EXTERN, obj.NAME_STATIC: 1893 if a.Sym == nil { 1894 break 1895 } 1896 c.instoffset = a.Offset 1897 if a.Sym != nil { 1898 if a.Sym.Type == objabi.STLSBSS { 1899 if c.ctxt.Flag_shared { 1900 return C_TLS_IE 1901 } else { 1902 return C_TLS_LE 1903 } 1904 } 1905 return C_ADDR 1906 } 1907 return C_LEXT 1908 1909 case obj.NAME_GOTREF: 1910 return C_GOTADDR 1911 1912 case obj.NAME_AUTO: 1913 if a.Reg == REGSP { 1914 1915 1916 a.Reg = obj.REG_NONE 1917 } 1918 1919 c.instoffset = int64(c.autosize) + a.Offset - int64(c.extrasize) 1920 return autoclass(c.instoffset) 1921 1922 case obj.NAME_PARAM: 1923 if a.Reg == REGSP { 1924 1925 1926 a.Reg = obj.REG_NONE 1927 } 1928 c.instoffset = int64(c.autosize) + a.Offset + 8 1929 return autoclass(c.instoffset) 1930 1931 case obj.NAME_NONE: 1932 if a.Index != 0 { 1933 if a.Offset != 0 { 1934 if isRegShiftOrExt(a) { 1935 1936 return C_ROFF 1937 } 1938 return C_GOK 1939 } 1940 1941 return C_ROFF 1942 } 1943 c.instoffset = a.Offset 1944 return oregclass(c.instoffset) 1945 } 1946 return C_GOK 1947 1948 case obj.TYPE_FCONST: 1949 return C_FCON 1950 1951 case obj.TYPE_TEXTSIZE: 1952 return C_TEXTSIZE 1953 1954 case obj.TYPE_CONST, obj.TYPE_ADDR: 1955 switch a.Name { 1956 case obj.NAME_NONE: 1957 c.instoffset = a.Offset 1958 if a.Reg != 0 && a.Reg != REGZERO { 1959 break 1960 } 1961 v := c.instoffset 1962 if v == 0 { 1963 return C_ZCON 1964 } 1965 if isaddcon(v) { 1966 if v <= 0xFFF { 1967 if isbitcon(uint64(v)) { 1968 return C_ABCON0 1969 } 1970 return C_ADDCON0 1971 } 1972 if isbitcon(uint64(v)) { 1973 return C_ABCON 1974 } 1975 if movcon(v) >= 0 { 1976 return C_AMCON 1977 } 1978 if movcon(^v) >= 0 { 1979 return C_AMCON 1980 } 1981 return C_ADDCON 1982 } 1983 1984 t := movcon(v) 1985 if t >= 0 { 1986 if isbitcon(uint64(v)) { 1987 return C_MBCON 1988 } 1989 return C_MOVCON 1990 } 1991 1992 t = movcon(^v) 1993 if t >= 0 { 1994 if isbitcon(uint64(v)) { 1995 return C_MBCON 1996 } 1997 return C_MOVCON 1998 } 1999 2000 if isbitcon(uint64(v)) { 2001 return C_BITCON 2002 } 2003 2004 if 0 <= v && v <= 0xffffff { 2005 return C_ADDCON2 2006 } 2007 2008 if uint64(v) == uint64(uint32(v)) || v == int64(int32(v)) { 2009 return C_LCON 2010 } 2011 return C_VCON 2012 2013 case obj.NAME_EXTERN, obj.NAME_STATIC: 2014 if a.Sym == nil { 2015 return C_GOK 2016 } 2017 if a.Sym.Type == objabi.STLSBSS { 2018 c.ctxt.Diag("taking address of TLS variable is not supported") 2019 } 2020 c.instoffset = a.Offset 2021 return C_VCONADDR 2022 2023 case obj.NAME_AUTO: 2024 if a.Reg == REGSP { 2025 2026 2027 a.Reg = obj.REG_NONE 2028 } 2029 2030 c.instoffset = int64(c.autosize) + a.Offset - int64(c.extrasize) 2031 2032 case obj.NAME_PARAM: 2033 if a.Reg == REGSP { 2034 2035 2036 a.Reg = obj.REG_NONE 2037 } 2038 c.instoffset = int64(c.autosize) + a.Offset + 8 2039 default: 2040 return C_GOK 2041 } 2042 cf := c.instoffset 2043 if isaddcon(cf) || isaddcon(-cf) { 2044 return C_AACON 2045 } 2046 if isaddcon2(cf) { 2047 return C_AACON2 2048 } 2049 2050 return C_LACON 2051 2052 case obj.TYPE_BRANCH: 2053 return C_SBRA 2054 2055 case obj.TYPE_SPECIAL: 2056 opd := SpecialOperand(a.Offset) 2057 if SPOP_EQ <= opd && opd <= SPOP_NV { 2058 return C_COND 2059 } 2060 return C_SPOP 2061 } 2062 return C_GOK 2063 } 2064 2065 func oclass(a *obj.Addr) int { 2066 return int(a.Class) - 1 2067 } 2068 2069 func (c *ctxt7) oplook(p *obj.Prog) *Optab { 2070 a1 := int(p.Optab) 2071 if a1 != 0 { 2072 return &optab[a1-1] 2073 } 2074 a1 = int(p.From.Class) 2075 if a1 == 0 { 2076 a0 := c.aclass(&p.From) 2077 2078 if (p.As == AADDS || p.As == AADDSW || p.As == ASUBS || p.As == ASUBSW) && a0 == C_ADDCON2 { 2079 a0 = C_LCON 2080 } 2081 a1 = a0 + 1 2082 p.From.Class = int8(a1) 2083 if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE { 2084 if p.As == AMOVW || isADDWop(p.As) || isANDWop(p.As) { 2085 2086 2087 ra0 := c.con32class(&p.From) 2088 2089 if (p.As == AADDSW || p.As == ASUBSW) && ra0 == C_ADDCON2 { 2090 ra0 = C_LCON 2091 } 2092 a1 = ra0 + 1 2093 p.From.Class = int8(a1) 2094 } 2095 if ((p.As == AMOVD) || isANDop(p.As) || isADDop(p.As)) && (a0 == C_LCON || a0 == C_VCON) { 2096 2097 a1 = c.con64class(&p.From) + 1 2098 p.From.Class = int8(a1) 2099 } 2100 } 2101 } 2102 2103 a1-- 2104 a3 := C_NONE + 1 2105 if p.GetFrom3() != nil && p.RestArgs[0].Pos == 0 { 2106 a3 = int(p.GetFrom3().Class) 2107 if a3 == 0 { 2108 a3 = c.aclass(p.GetFrom3()) + 1 2109 p.GetFrom3().Class = int8(a3) 2110 } 2111 } 2112 2113 a3-- 2114 a4 := int(p.To.Class) 2115 if a4 == 0 { 2116 a4 = c.aclass(&p.To) + 1 2117 p.To.Class = int8(a4) 2118 } 2119 2120 a4-- 2121 a2 := C_NONE 2122 if p.Reg != 0 { 2123 a2 = rclass(p.Reg) 2124 } 2125 2126 if false { 2127 fmt.Printf("oplook %v %d %d %d %d\n", p.As, a1, a2, a3, a4) 2128 fmt.Printf("\t\t%d %d\n", p.From.Type, p.To.Type) 2129 } 2130 2131 ops := oprange[p.As&obj.AMask] 2132 c1 := &xcmp[a1] 2133 c2 := &xcmp[a2] 2134 c3 := &xcmp[a3] 2135 c4 := &xcmp[a4] 2136 c5 := &xcmp[p.Scond>>5] 2137 for i := range ops { 2138 op := &ops[i] 2139 if (int(op.a2) == a2 || c2[op.a2]) && c5[op.scond>>5] && c1[op.a1] && c3[op.a3] && c4[op.a4] { 2140 p.Optab = uint16(cap(optab) - cap(ops) + i + 1) 2141 return op 2142 } 2143 } 2144 2145 c.ctxt.Diag("illegal combination: %v %v %v %v %v, %d %d", p, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4), p.From.Type, p.To.Type) 2146 2147 return &Optab{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 90, 4, 0, 0, 0} 2148 } 2149 2150 func cmp(a int, b int) bool { 2151 if a == b { 2152 return true 2153 } 2154 switch a { 2155 case C_RSP: 2156 if b == C_REG { 2157 return true 2158 } 2159 2160 case C_ZREG: 2161 if b == C_REG { 2162 return true 2163 } 2164 2165 case C_ADDCON0: 2166 if b == C_ZCON || b == C_ABCON0 { 2167 return true 2168 } 2169 2170 case C_ADDCON: 2171 if b == C_ZCON || b == C_ABCON0 || b == C_ADDCON0 || b == C_ABCON || b == C_AMCON { 2172 return true 2173 } 2174 2175 case C_MBCON: 2176 if b == C_ABCON0 { 2177 return true 2178 } 2179 2180 case C_BITCON: 2181 if b == C_ABCON0 || b == C_ABCON || b == C_MBCON { 2182 return true 2183 } 2184 2185 case C_MOVCON: 2186 if b == C_MBCON || b == C_ZCON || b == C_ADDCON0 || b == C_ABCON0 || b == C_AMCON { 2187 return true 2188 } 2189 2190 case C_ADDCON2: 2191 if b == C_ZCON || b == C_ADDCON || b == C_ADDCON0 { 2192 return true 2193 } 2194 2195 case C_LCON: 2196 if b == C_ZCON || b == C_BITCON || b == C_ADDCON || b == C_ADDCON0 || b == C_ABCON || b == C_ABCON0 || b == C_MBCON || b == C_MOVCON || b == C_ADDCON2 || b == C_AMCON { 2197 return true 2198 } 2199 2200 case C_MOVCON2: 2201 return cmp(C_LCON, b) 2202 2203 case C_VCON: 2204 return cmp(C_LCON, b) 2205 2206 case C_LACON: 2207 if b == C_AACON || b == C_AACON2 { 2208 return true 2209 } 2210 2211 case C_SEXT2: 2212 if b == C_SEXT1 { 2213 return true 2214 } 2215 2216 case C_SEXT4: 2217 if b == C_SEXT1 || b == C_SEXT2 { 2218 return true 2219 } 2220 2221 case C_SEXT8: 2222 if b >= C_SEXT1 && b <= C_SEXT4 { 2223 return true 2224 } 2225 2226 case C_SEXT16: 2227 if b >= C_SEXT1 && b <= C_SEXT8 { 2228 return true 2229 } 2230 2231 case C_LEXT: 2232 if b >= C_SEXT1 && b <= C_SEXT16 { 2233 return true 2234 } 2235 2236 case C_NSAUTO_8: 2237 if b == C_NSAUTO_16 { 2238 return true 2239 } 2240 2241 case C_NSAUTO_4: 2242 if b == C_NSAUTO_16 || b == C_NSAUTO_8 { 2243 return true 2244 } 2245 2246 case C_NSAUTO: 2247 switch b { 2248 case C_NSAUTO_4, C_NSAUTO_8, C_NSAUTO_16: 2249 return true 2250 } 2251 2252 case C_NPAUTO_16: 2253 switch b { 2254 case C_NSAUTO_16: 2255 return true 2256 } 2257 2258 case C_NPAUTO: 2259 switch b { 2260 case C_NSAUTO_16, C_NSAUTO_8, C_NPAUTO_16: 2261 return true 2262 } 2263 2264 case C_NQAUTO_16: 2265 switch b { 2266 case C_NSAUTO_16, C_NPAUTO_16: 2267 return true 2268 } 2269 2270 case C_NAUTO4K: 2271 switch b { 2272 case C_NSAUTO_16, C_NSAUTO_8, C_NSAUTO_4, C_NSAUTO, C_NPAUTO_16, 2273 C_NPAUTO, C_NQAUTO_16: 2274 return true 2275 } 2276 2277 case C_PSAUTO_16: 2278 if b == C_ZAUTO { 2279 return true 2280 } 2281 2282 case C_PSAUTO_8: 2283 if b == C_ZAUTO || b == C_PSAUTO_16 { 2284 return true 2285 } 2286 2287 case C_PSAUTO_4: 2288 switch b { 2289 case C_ZAUTO, C_PSAUTO_16, C_PSAUTO_8: 2290 return true 2291 } 2292 2293 case C_PSAUTO: 2294 switch b { 2295 case C_ZAUTO, C_PSAUTO_16, C_PSAUTO_8, C_PSAUTO_4: 2296 return true 2297 } 2298 2299 case C_PPAUTO_16: 2300 switch b { 2301 case C_ZAUTO, C_PSAUTO_16: 2302 return true 2303 } 2304 2305 case C_PPAUTO: 2306 switch b { 2307 case C_ZAUTO, C_PSAUTO_16, C_PSAUTO_8, C_PPAUTO_16: 2308 return true 2309 } 2310 2311 case C_PQAUTO_16: 2312 switch b { 2313 case C_ZAUTO, C_PSAUTO_16, C_PPAUTO_16: 2314 return true 2315 } 2316 2317 case C_UAUTO4K: 2318 switch b { 2319 case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16, 2320 C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16, 2321 C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16: 2322 return true 2323 } 2324 2325 case C_UAUTO8K: 2326 switch b { 2327 case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16, 2328 C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16, 2329 C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16, 2330 C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO8K_16: 2331 return true 2332 } 2333 2334 case C_UAUTO16K: 2335 switch b { 2336 case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16, 2337 C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16, 2338 C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16, 2339 C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO8K_16, 2340 C_UAUTO16K_8, C_UAUTO16K_16: 2341 return true 2342 } 2343 2344 case C_UAUTO32K: 2345 switch b { 2346 case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16, 2347 C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16, 2348 C_UAUTO4K_8, C_UAUTO4K_16, 2349 C_UAUTO8K_8, C_UAUTO8K_16, 2350 C_UAUTO16K_8, C_UAUTO16K_16, 2351 C_UAUTO32K_16: 2352 return true 2353 } 2354 2355 case C_UAUTO64K: 2356 switch b { 2357 case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16, 2358 C_PPAUTO_16, C_PQAUTO_16, C_UAUTO4K_16, C_UAUTO8K_16, C_UAUTO16K_16, 2359 C_UAUTO32K_16: 2360 return true 2361 } 2362 2363 case C_LAUTO: 2364 switch b { 2365 case C_ZAUTO, C_NSAUTO, C_NSAUTO_4, C_NSAUTO_8, C_NSAUTO_16, C_NPAUTO_16, C_NPAUTO, C_NQAUTO_16, C_NAUTO4K, 2366 C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16, 2367 C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16, 2368 C_UAUTO4K, C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16, 2369 C_UAUTO8K, C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO8K_16, 2370 C_UAUTO16K, C_UAUTO16K_8, C_UAUTO16K_16, 2371 C_UAUTO32K, C_UAUTO32K_16, 2372 C_UAUTO64K: 2373 return true 2374 } 2375 2376 case C_NSOREG_8: 2377 if b == C_NSOREG_16 { 2378 return true 2379 } 2380 2381 case C_NSOREG_4: 2382 if b == C_NSOREG_8 || b == C_NSOREG_16 { 2383 return true 2384 } 2385 2386 case C_NSOREG: 2387 switch b { 2388 case C_NSOREG_4, C_NSOREG_8, C_NSOREG_16: 2389 return true 2390 } 2391 2392 case C_NPOREG_16: 2393 switch b { 2394 case C_NSOREG_16: 2395 return true 2396 } 2397 2398 case C_NPOREG: 2399 switch b { 2400 case C_NSOREG_16, C_NSOREG_8, C_NPOREG_16: 2401 return true 2402 } 2403 2404 case C_NQOREG_16: 2405 switch b { 2406 case C_NSOREG_16, C_NPOREG_16: 2407 return true 2408 } 2409 2410 case C_NOREG4K: 2411 switch b { 2412 case C_NSOREG_16, C_NSOREG_8, C_NSOREG_4, C_NSOREG, C_NPOREG_16, C_NPOREG, C_NQOREG_16: 2413 return true 2414 } 2415 2416 case C_PSOREG_16: 2417 if b == C_ZOREG { 2418 return true 2419 } 2420 2421 case C_PSOREG_8: 2422 if b == C_ZOREG || b == C_PSOREG_16 { 2423 return true 2424 } 2425 2426 case C_PSOREG_4: 2427 switch b { 2428 case C_ZOREG, C_PSOREG_16, C_PSOREG_8: 2429 return true 2430 } 2431 2432 case C_PSOREG: 2433 switch b { 2434 case C_ZOREG, C_PSOREG_16, C_PSOREG_8, C_PSOREG_4: 2435 return true 2436 } 2437 2438 case C_PPOREG_16: 2439 switch b { 2440 case C_ZOREG, C_PSOREG_16: 2441 return true 2442 } 2443 2444 case C_PPOREG: 2445 switch b { 2446 case C_ZOREG, C_PSOREG_16, C_PSOREG_8, C_PPOREG_16: 2447 return true 2448 } 2449 2450 case C_PQOREG_16: 2451 switch b { 2452 case C_ZOREG, C_PSOREG_16, C_PPOREG_16: 2453 return true 2454 } 2455 2456 case C_UOREG4K: 2457 switch b { 2458 case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16, 2459 C_PPOREG, C_PPOREG_16, C_PQOREG_16, 2460 C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16: 2461 return true 2462 } 2463 2464 case C_UOREG8K: 2465 switch b { 2466 case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16, 2467 C_PPOREG, C_PPOREG_16, C_PQOREG_16, 2468 C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16, 2469 C_UOREG8K_4, C_UOREG8K_8, C_UOREG8K_16: 2470 return true 2471 } 2472 2473 case C_UOREG16K: 2474 switch b { 2475 case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16, 2476 C_PPOREG, C_PPOREG_16, C_PQOREG_16, 2477 C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16, 2478 C_UOREG8K_4, C_UOREG8K_8, C_UOREG8K_16, 2479 C_UOREG16K_8, C_UOREG16K_16: 2480 return true 2481 } 2482 2483 case C_UOREG32K: 2484 switch b { 2485 case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16, 2486 C_PPOREG, C_PPOREG_16, C_PQOREG_16, 2487 C_UOREG4K_8, C_UOREG4K_16, 2488 C_UOREG8K_8, C_UOREG8K_16, 2489 C_UOREG16K_8, C_UOREG16K_16, 2490 C_UOREG32K_16: 2491 return true 2492 } 2493 2494 case C_UOREG64K: 2495 switch b { 2496 case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16, 2497 C_PPOREG_16, C_PQOREG_16, C_UOREG4K_16, C_UOREG8K_16, C_UOREG16K_16, 2498 C_UOREG32K_16: 2499 return true 2500 } 2501 2502 case C_LOREG: 2503 switch b { 2504 case C_ZOREG, C_NSOREG, C_NSOREG_4, C_NSOREG_8, C_NSOREG_16, C_NPOREG, C_NPOREG_16, C_NQOREG_16, C_NOREG4K, 2505 C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16, 2506 C_PPOREG, C_PPOREG_16, C_PQOREG_16, 2507 C_UOREG4K, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16, 2508 C_UOREG8K, C_UOREG8K_4, C_UOREG8K_8, C_UOREG8K_16, 2509 C_UOREG16K, C_UOREG16K_8, C_UOREG16K_16, 2510 C_UOREG32K, C_UOREG32K_16, 2511 C_UOREG64K: 2512 return true 2513 } 2514 2515 case C_LBRA: 2516 if b == C_SBRA { 2517 return true 2518 } 2519 } 2520 2521 return false 2522 } 2523 2524 type ocmp []Optab 2525 2526 func (x ocmp) Len() int { 2527 return len(x) 2528 } 2529 2530 func (x ocmp) Swap(i, j int) { 2531 x[i], x[j] = x[j], x[i] 2532 } 2533 2534 func (x ocmp) Less(i, j int) bool { 2535 p1 := &x[i] 2536 p2 := &x[j] 2537 if p1.as != p2.as { 2538 return p1.as < p2.as 2539 } 2540 if p1.a1 != p2.a1 { 2541 return p1.a1 < p2.a1 2542 } 2543 if p1.a2 != p2.a2 { 2544 return p1.a2 < p2.a2 2545 } 2546 if p1.a3 != p2.a3 { 2547 return p1.a3 < p2.a3 2548 } 2549 if p1.a4 != p2.a4 { 2550 return p1.a4 < p2.a4 2551 } 2552 if p1.scond != p2.scond { 2553 return p1.scond < p2.scond 2554 } 2555 return false 2556 } 2557 2558 func oprangeset(a obj.As, t []Optab) { 2559 oprange[a&obj.AMask] = t 2560 } 2561 2562 func buildop(ctxt *obj.Link) { 2563 if oprange[AAND&obj.AMask] != nil { 2564 2565 2566 2567 return 2568 } 2569 2570 var n int 2571 for i := 0; i < C_GOK; i++ { 2572 for n = 0; n < C_GOK; n++ { 2573 if cmp(n, i) { 2574 xcmp[i][n] = true 2575 } 2576 } 2577 } 2578 for n = 0; optab[n].as != obj.AXXX; n++ { 2579 } 2580 sort.Sort(ocmp(optab[:n])) 2581 for i := 0; i < n; i++ { 2582 r := optab[i].as 2583 start := i 2584 for optab[i].as == r { 2585 i++ 2586 } 2587 t := optab[start:i] 2588 i-- 2589 oprangeset(r, t) 2590 switch r { 2591 default: 2592 ctxt.Diag("unknown op in build: %v", r) 2593 ctxt.DiagFlush() 2594 log.Fatalf("bad code") 2595 2596 case AADD: 2597 oprangeset(AADDS, t) 2598 oprangeset(ASUB, t) 2599 oprangeset(ASUBS, t) 2600 oprangeset(AADDW, t) 2601 oprangeset(AADDSW, t) 2602 oprangeset(ASUBW, t) 2603 oprangeset(ASUBSW, t) 2604 2605 case AAND: 2606 oprangeset(AANDW, t) 2607 oprangeset(AEOR, t) 2608 oprangeset(AEORW, t) 2609 oprangeset(AORR, t) 2610 oprangeset(AORRW, t) 2611 oprangeset(ABIC, t) 2612 oprangeset(ABICW, t) 2613 oprangeset(AEON, t) 2614 oprangeset(AEONW, t) 2615 oprangeset(AORN, t) 2616 oprangeset(AORNW, t) 2617 2618 case AANDS: 2619 oprangeset(AANDSW, t) 2620 oprangeset(ABICS, t) 2621 oprangeset(ABICSW, t) 2622 2623 case ANEG: 2624 oprangeset(ANEGS, t) 2625 oprangeset(ANEGSW, t) 2626 oprangeset(ANEGW, t) 2627 2628 case AADC: 2629 oprangeset(AADCW, t) 2630 2631 oprangeset(AADCS, t) 2632 oprangeset(AADCSW, t) 2633 oprangeset(ASBC, t) 2634 oprangeset(ASBCW, t) 2635 oprangeset(ASBCS, t) 2636 oprangeset(ASBCSW, t) 2637 2638 case ANGC: 2639 oprangeset(ANGCW, t) 2640 2641 oprangeset(ANGCS, t) 2642 oprangeset(ANGCSW, t) 2643 2644 case ACMP: 2645 oprangeset(ACMPW, t) 2646 oprangeset(ACMN, t) 2647 oprangeset(ACMNW, t) 2648 2649 case ATST: 2650 oprangeset(ATSTW, t) 2651 2652 2653 case AMVN: 2654 oprangeset(AMVNW, t) 2655 2656 case AMOVK: 2657 oprangeset(AMOVKW, t) 2658 oprangeset(AMOVN, t) 2659 oprangeset(AMOVNW, t) 2660 oprangeset(AMOVZ, t) 2661 oprangeset(AMOVZW, t) 2662 2663 case ASWPD: 2664 for i := range atomicLDADD { 2665 oprangeset(i, t) 2666 } 2667 for i := range atomicSWP { 2668 if i == ASWPD { 2669 continue 2670 } 2671 oprangeset(i, t) 2672 } 2673 2674 case ACASPD: 2675 oprangeset(ACASPW, t) 2676 case ABEQ: 2677 oprangeset(ABNE, t) 2678 oprangeset(ABCS, t) 2679 oprangeset(ABHS, t) 2680 oprangeset(ABCC, t) 2681 oprangeset(ABLO, t) 2682 oprangeset(ABMI, t) 2683 oprangeset(ABPL, t) 2684 oprangeset(ABVS, t) 2685 oprangeset(ABVC, t) 2686 oprangeset(ABHI, t) 2687 oprangeset(ABLS, t) 2688 oprangeset(ABGE, t) 2689 oprangeset(ABLT, t) 2690 oprangeset(ABGT, t) 2691 oprangeset(ABLE, t) 2692 2693 case ALSL: 2694 oprangeset(ALSLW, t) 2695 oprangeset(ALSR, t) 2696 oprangeset(ALSRW, t) 2697 oprangeset(AASR, t) 2698 oprangeset(AASRW, t) 2699 oprangeset(AROR, t) 2700 oprangeset(ARORW, t) 2701 2702 case ACLS: 2703 oprangeset(ACLSW, t) 2704 oprangeset(ACLZ, t) 2705 oprangeset(ACLZW, t) 2706 oprangeset(ARBIT, t) 2707 oprangeset(ARBITW, t) 2708 oprangeset(AREV, t) 2709 oprangeset(AREVW, t) 2710 oprangeset(AREV16, t) 2711 oprangeset(AREV16W, t) 2712 oprangeset(AREV32, t) 2713 2714 case ASDIV: 2715 oprangeset(ASDIVW, t) 2716 oprangeset(AUDIV, t) 2717 oprangeset(AUDIVW, t) 2718 oprangeset(ACRC32B, t) 2719 oprangeset(ACRC32CB, t) 2720 oprangeset(ACRC32CH, t) 2721 oprangeset(ACRC32CW, t) 2722 oprangeset(ACRC32CX, t) 2723 oprangeset(ACRC32H, t) 2724 oprangeset(ACRC32W, t) 2725 oprangeset(ACRC32X, t) 2726 2727 case AMADD: 2728 oprangeset(AMADDW, t) 2729 oprangeset(AMSUB, t) 2730 oprangeset(AMSUBW, t) 2731 oprangeset(ASMADDL, t) 2732 oprangeset(ASMSUBL, t) 2733 oprangeset(AUMADDL, t) 2734 oprangeset(AUMSUBL, t) 2735 2736 case AREM: 2737 oprangeset(AREMW, t) 2738 oprangeset(AUREM, t) 2739 oprangeset(AUREMW, t) 2740 2741 case AMUL: 2742 oprangeset(AMULW, t) 2743 oprangeset(AMNEG, t) 2744 oprangeset(AMNEGW, t) 2745 oprangeset(ASMNEGL, t) 2746 oprangeset(ASMULL, t) 2747 oprangeset(ASMULH, t) 2748 oprangeset(AUMNEGL, t) 2749 oprangeset(AUMULH, t) 2750 oprangeset(AUMULL, t) 2751 2752 case AMOVB: 2753 oprangeset(AMOVBU, t) 2754 2755 case AMOVH: 2756 oprangeset(AMOVHU, t) 2757 2758 case AMOVW: 2759 oprangeset(AMOVWU, t) 2760 2761 case ABFM: 2762 oprangeset(ABFMW, t) 2763 oprangeset(ASBFM, t) 2764 oprangeset(ASBFMW, t) 2765 oprangeset(AUBFM, t) 2766 oprangeset(AUBFMW, t) 2767 2768 case ABFI: 2769 oprangeset(ABFIW, t) 2770 oprangeset(ABFXIL, t) 2771 oprangeset(ABFXILW, t) 2772 oprangeset(ASBFIZ, t) 2773 oprangeset(ASBFIZW, t) 2774 oprangeset(ASBFX, t) 2775 oprangeset(ASBFXW, t) 2776 oprangeset(AUBFIZ, t) 2777 oprangeset(AUBFIZW, t) 2778 oprangeset(AUBFX, t) 2779 oprangeset(AUBFXW, t) 2780 2781 case AEXTR: 2782 oprangeset(AEXTRW, t) 2783 2784 case ASXTB: 2785 oprangeset(ASXTBW, t) 2786 oprangeset(ASXTH, t) 2787 oprangeset(ASXTHW, t) 2788 oprangeset(ASXTW, t) 2789 oprangeset(AUXTB, t) 2790 oprangeset(AUXTH, t) 2791 oprangeset(AUXTW, t) 2792 oprangeset(AUXTBW, t) 2793 oprangeset(AUXTHW, t) 2794 2795 case ACCMN: 2796 oprangeset(ACCMNW, t) 2797 oprangeset(ACCMP, t) 2798 oprangeset(ACCMPW, t) 2799 2800 case ACSEL: 2801 oprangeset(ACSELW, t) 2802 oprangeset(ACSINC, t) 2803 oprangeset(ACSINCW, t) 2804 oprangeset(ACSINV, t) 2805 oprangeset(ACSINVW, t) 2806 oprangeset(ACSNEG, t) 2807 oprangeset(ACSNEGW, t) 2808 2809 case ACINC: 2810 2811 oprangeset(ACINCW, t) 2812 oprangeset(ACINV, t) 2813 oprangeset(ACINVW, t) 2814 oprangeset(ACNEG, t) 2815 oprangeset(ACNEGW, t) 2816 2817 2818 case ACSET: 2819 oprangeset(ACSETW, t) 2820 2821 oprangeset(ACSETM, t) 2822 oprangeset(ACSETMW, t) 2823 2824 case AMOVD, 2825 AB, 2826 ABL, 2827 AWORD, 2828 ADWORD, 2829 obj.ARET, 2830 obj.ATEXT: 2831 break 2832 2833 case AFLDPQ: 2834 break 2835 case AFSTPQ: 2836 break 2837 case ALDP: 2838 oprangeset(AFLDPD, t) 2839 2840 case ASTP: 2841 oprangeset(AFSTPD, t) 2842 2843 case ASTPW: 2844 oprangeset(AFSTPS, t) 2845 2846 case ALDPW: 2847 oprangeset(ALDPSW, t) 2848 oprangeset(AFLDPS, t) 2849 2850 case AERET: 2851 oprangeset(AWFE, t) 2852 oprangeset(AWFI, t) 2853 oprangeset(AYIELD, t) 2854 oprangeset(ASEV, t) 2855 oprangeset(ASEVL, t) 2856 oprangeset(ANOOP, t) 2857 oprangeset(ADRPS, t) 2858 2859 case ACBZ: 2860 oprangeset(ACBZW, t) 2861 oprangeset(ACBNZ, t) 2862 oprangeset(ACBNZW, t) 2863 2864 case ATBZ: 2865 oprangeset(ATBNZ, t) 2866 2867 case AADR, AADRP: 2868 break 2869 2870 case ACLREX: 2871 break 2872 2873 case ASVC: 2874 oprangeset(AHVC, t) 2875 oprangeset(AHLT, t) 2876 oprangeset(ASMC, t) 2877 oprangeset(ABRK, t) 2878 oprangeset(ADCPS1, t) 2879 oprangeset(ADCPS2, t) 2880 oprangeset(ADCPS3, t) 2881 2882 case AFADDS: 2883 oprangeset(AFADDD, t) 2884 oprangeset(AFSUBS, t) 2885 oprangeset(AFSUBD, t) 2886 oprangeset(AFMULS, t) 2887 oprangeset(AFMULD, t) 2888 oprangeset(AFNMULS, t) 2889 oprangeset(AFNMULD, t) 2890 oprangeset(AFDIVS, t) 2891 oprangeset(AFMAXD, t) 2892 oprangeset(AFMAXS, t) 2893 oprangeset(AFMIND, t) 2894 oprangeset(AFMINS, t) 2895 oprangeset(AFMAXNMD, t) 2896 oprangeset(AFMAXNMS, t) 2897 oprangeset(AFMINNMD, t) 2898 oprangeset(AFMINNMS, t) 2899 oprangeset(AFDIVD, t) 2900 2901 case AFMSUBD: 2902 oprangeset(AFMSUBS, t) 2903 oprangeset(AFMADDS, t) 2904 oprangeset(AFMADDD, t) 2905 oprangeset(AFNMSUBS, t) 2906 oprangeset(AFNMSUBD, t) 2907 oprangeset(AFNMADDS, t) 2908 oprangeset(AFNMADDD, t) 2909 2910 case AFCVTSD: 2911 oprangeset(AFCVTDS, t) 2912 oprangeset(AFABSD, t) 2913 oprangeset(AFABSS, t) 2914 oprangeset(AFNEGD, t) 2915 oprangeset(AFNEGS, t) 2916 oprangeset(AFSQRTD, t) 2917 oprangeset(AFSQRTS, t) 2918 oprangeset(AFRINTNS, t) 2919 oprangeset(AFRINTND, t) 2920 oprangeset(AFRINTPS, t) 2921 oprangeset(AFRINTPD, t) 2922 oprangeset(AFRINTMS, t) 2923 oprangeset(AFRINTMD, t) 2924 oprangeset(AFRINTZS, t) 2925 oprangeset(AFRINTZD, t) 2926 oprangeset(AFRINTAS, t) 2927 oprangeset(AFRINTAD, t) 2928 oprangeset(AFRINTXS, t) 2929 oprangeset(AFRINTXD, t) 2930 oprangeset(AFRINTIS, t) 2931 oprangeset(AFRINTID, t) 2932 oprangeset(AFCVTDH, t) 2933 oprangeset(AFCVTHS, t) 2934 oprangeset(AFCVTHD, t) 2935 oprangeset(AFCVTSH, t) 2936 2937 case AFCMPS: 2938 oprangeset(AFCMPD, t) 2939 oprangeset(AFCMPES, t) 2940 oprangeset(AFCMPED, t) 2941 2942 case AFCCMPS: 2943 oprangeset(AFCCMPD, t) 2944 oprangeset(AFCCMPES, t) 2945 oprangeset(AFCCMPED, t) 2946 2947 case AFCSELD: 2948 oprangeset(AFCSELS, t) 2949 2950 case AFMOVQ, AFMOVD, AFMOVS, 2951 AVMOVQ, AVMOVD, AVMOVS: 2952 break 2953 2954 case AFCVTZSD: 2955 oprangeset(AFCVTZSDW, t) 2956 oprangeset(AFCVTZSS, t) 2957 oprangeset(AFCVTZSSW, t) 2958 oprangeset(AFCVTZUD, t) 2959 oprangeset(AFCVTZUDW, t) 2960 oprangeset(AFCVTZUS, t) 2961 oprangeset(AFCVTZUSW, t) 2962 2963 case ASCVTFD: 2964 oprangeset(ASCVTFS, t) 2965 oprangeset(ASCVTFWD, t) 2966 oprangeset(ASCVTFWS, t) 2967 oprangeset(AUCVTFD, t) 2968 oprangeset(AUCVTFS, t) 2969 oprangeset(AUCVTFWD, t) 2970 oprangeset(AUCVTFWS, t) 2971 2972 case ASYS: 2973 oprangeset(AAT, t) 2974 oprangeset(AIC, t) 2975 2976 case ATLBI: 2977 oprangeset(ADC, t) 2978 2979 case ASYSL, AHINT: 2980 break 2981 2982 case ADMB: 2983 oprangeset(ADSB, t) 2984 oprangeset(AISB, t) 2985 2986 case AMRS, AMSR: 2987 break 2988 2989 case ALDAR: 2990 oprangeset(ALDARW, t) 2991 oprangeset(ALDARB, t) 2992 oprangeset(ALDARH, t) 2993 fallthrough 2994 2995 case ALDXR: 2996 oprangeset(ALDXRB, t) 2997 oprangeset(ALDXRH, t) 2998 oprangeset(ALDXRW, t) 2999 3000 case ALDAXR: 3001 oprangeset(ALDAXRB, t) 3002 oprangeset(ALDAXRH, t) 3003 oprangeset(ALDAXRW, t) 3004 3005 case ALDXP: 3006 oprangeset(ALDXPW, t) 3007 oprangeset(ALDAXP, t) 3008 oprangeset(ALDAXPW, t) 3009 3010 case ASTLR: 3011 oprangeset(ASTLRB, t) 3012 oprangeset(ASTLRH, t) 3013 oprangeset(ASTLRW, t) 3014 3015 case ASTXR: 3016 oprangeset(ASTXRB, t) 3017 oprangeset(ASTXRH, t) 3018 oprangeset(ASTXRW, t) 3019 3020 case ASTLXR: 3021 oprangeset(ASTLXRB, t) 3022 oprangeset(ASTLXRH, t) 3023 oprangeset(ASTLXRW, t) 3024 3025 case ASTXP: 3026 oprangeset(ASTLXP, t) 3027 oprangeset(ASTLXPW, t) 3028 oprangeset(ASTXPW, t) 3029 3030 case AVADDP: 3031 oprangeset(AVAND, t) 3032 oprangeset(AVCMEQ, t) 3033 oprangeset(AVORR, t) 3034 oprangeset(AVEOR, t) 3035 oprangeset(AVBSL, t) 3036 oprangeset(AVBIT, t) 3037 oprangeset(AVCMTST, t) 3038 oprangeset(AVUMAX, t) 3039 oprangeset(AVUMIN, t) 3040 oprangeset(AVUZP1, t) 3041 oprangeset(AVUZP2, t) 3042 oprangeset(AVBIF, t) 3043 3044 case AVADD: 3045 oprangeset(AVSUB, t) 3046 oprangeset(AVRAX1, t) 3047 3048 case AAESD: 3049 oprangeset(AAESE, t) 3050 oprangeset(AAESMC, t) 3051 oprangeset(AAESIMC, t) 3052 oprangeset(ASHA1SU1, t) 3053 oprangeset(ASHA256SU0, t) 3054 oprangeset(ASHA512SU0, t) 3055 3056 case ASHA1C: 3057 oprangeset(ASHA1P, t) 3058 oprangeset(ASHA1M, t) 3059 3060 case ASHA256H: 3061 oprangeset(ASHA256H2, t) 3062 oprangeset(ASHA512H, t) 3063 oprangeset(ASHA512H2, t) 3064 3065 case ASHA1SU0: 3066 oprangeset(ASHA256SU1, t) 3067 oprangeset(ASHA512SU1, t) 3068 3069 case AVADDV: 3070 oprangeset(AVUADDLV, t) 3071 3072 case AVFMLA: 3073 oprangeset(AVFMLS, t) 3074 3075 case AVPMULL: 3076 oprangeset(AVPMULL2, t) 3077 3078 case AVUSHR: 3079 oprangeset(AVSHL, t) 3080 oprangeset(AVSRI, t) 3081 oprangeset(AVSLI, t) 3082 oprangeset(AVUSRA, t) 3083 3084 case AVREV32: 3085 oprangeset(AVCNT, t) 3086 oprangeset(AVRBIT, t) 3087 oprangeset(AVREV64, t) 3088 oprangeset(AVREV16, t) 3089 3090 case AVZIP1: 3091 oprangeset(AVZIP2, t) 3092 oprangeset(AVTRN1, t) 3093 oprangeset(AVTRN2, t) 3094 3095 case AVUXTL: 3096 oprangeset(AVUXTL2, t) 3097 3098 case AVUSHLL: 3099 oprangeset(AVUSHLL2, t) 3100 3101 case AVLD1R: 3102 oprangeset(AVLD2, t) 3103 oprangeset(AVLD2R, t) 3104 oprangeset(AVLD3, t) 3105 oprangeset(AVLD3R, t) 3106 oprangeset(AVLD4, t) 3107 oprangeset(AVLD4R, t) 3108 3109 case AVEOR3: 3110 oprangeset(AVBCAX, t) 3111 3112 case AVUADDW: 3113 oprangeset(AVUADDW2, t) 3114 3115 case AVTBL: 3116 oprangeset(AVTBX, t) 3117 3118 case ASHA1H, 3119 AVCNT, 3120 AVMOV, 3121 AVLD1, 3122 AVST1, 3123 AVST2, 3124 AVST3, 3125 AVST4, 3126 AVDUP, 3127 AVMOVI, 3128 APRFM, 3129 AVEXT, 3130 AVXAR: 3131 break 3132 3133 case obj.ANOP, 3134 obj.AUNDEF, 3135 obj.AFUNCDATA, 3136 obj.APCALIGN, 3137 obj.APCDATA, 3138 obj.ADUFFZERO, 3139 obj.ADUFFCOPY: 3140 break 3141 } 3142 } 3143 } 3144 3145 3146 3147 3148 func (c *ctxt7) chipfloat7(e float64) int { 3149 ei := math.Float64bits(e) 3150 l := uint32(int32(ei)) 3151 h := uint32(int32(ei >> 32)) 3152 3153 if l != 0 || h&0xffff != 0 { 3154 return -1 3155 } 3156 h1 := h & 0x7fc00000 3157 if h1 != 0x40000000 && h1 != 0x3fc00000 { 3158 return -1 3159 } 3160 n := 0 3161 3162 3163 if h&0x80000000 != 0 { 3164 n |= 1 << 7 3165 } 3166 3167 3168 if h1 == 0x3fc00000 { 3169 n |= 1 << 6 3170 } 3171 3172 3173 n |= int((h >> 16) & 0x3f) 3174 3175 3176 return n 3177 } 3178 3179 3180 func SYSARG5(op0 int, op1 int, Cn int, Cm int, op2 int) int { 3181 return op0<<19 | op1<<16 | Cn<<12 | Cm<<8 | op2<<5 3182 } 3183 3184 func SYSARG4(op1 int, Cn int, Cm int, op2 int) int { 3185 return SYSARG5(0, op1, Cn, Cm, op2) 3186 } 3187 3188 3189 3190 func (c *ctxt7) checkUnpredictable(p *obj.Prog, isload bool, wback bool, rn int16, rt1 int16, rt2 int16) { 3191 if wback && rn != REGSP && (rn == rt1 || rn == rt2) { 3192 c.ctxt.Diag("constrained unpredictable behavior: %v", p) 3193 } 3194 if isload && rt1 == rt2 { 3195 c.ctxt.Diag("constrained unpredictable behavior: %v", p) 3196 } 3197 } 3198 3199 3200 func (c *ctxt7) checkindex(p *obj.Prog, index, maxindex int) { 3201 if index < 0 || index > maxindex { 3202 c.ctxt.Diag("register element index out of range 0 to %d: %v", maxindex, p) 3203 } 3204 } 3205 3206 3207 func (c *ctxt7) checkoffset(p *obj.Prog, as obj.As) { 3208 var offset, list, n, expect int64 3209 switch as { 3210 case AVLD1, AVLD2, AVLD3, AVLD4, AVLD1R, AVLD2R, AVLD3R, AVLD4R: 3211 offset = p.From.Offset 3212 list = p.To.Offset 3213 case AVST1, AVST2, AVST3, AVST4: 3214 offset = p.To.Offset 3215 list = p.From.Offset 3216 default: 3217 c.ctxt.Diag("invalid operation on op %v", p.As) 3218 } 3219 opcode := (list >> 12) & 15 3220 q := (list >> 30) & 1 3221 size := (list >> 10) & 3 3222 if offset == 0 { 3223 return 3224 } 3225 switch opcode { 3226 case 0x7: 3227 n = 1 3228 case 0xa: 3229 n = 2 3230 case 0x6: 3231 n = 3 3232 case 0x2: 3233 n = 4 3234 default: 3235 c.ctxt.Diag("invalid register numbers in ARM64 register list: %v", p) 3236 } 3237 3238 switch as { 3239 case AVLD1R, AVLD2R, AVLD3R, AVLD4R: 3240 if offset != n*(1<<uint(size)) { 3241 c.ctxt.Diag("invalid post-increment offset: %v", p) 3242 } 3243 default: 3244 if !(q == 0 && offset == n*8) && !(q == 1 && offset == n*16) { 3245 c.ctxt.Diag("invalid post-increment offset: %v", p) 3246 } 3247 } 3248 3249 switch as { 3250 case AVLD1, AVST1: 3251 return 3252 case AVLD1R: 3253 expect = 1 3254 case AVLD2, AVST2, AVLD2R: 3255 expect = 2 3256 case AVLD3, AVST3, AVLD3R: 3257 expect = 3 3258 case AVLD4, AVST4, AVLD4R: 3259 expect = 4 3260 } 3261 3262 if expect != n { 3263 c.ctxt.Diag("expected %d registers, got %d: %v.", expect, n, p) 3264 } 3265 } 3266 3267 3268 3269 func (c *ctxt7) checkShiftAmount(p *obj.Prog, a *obj.Addr) { 3270 var amount int16 3271 amount = (a.Index >> 5) & 7 3272 switch p.As { 3273 case AMOVB, AMOVBU: 3274 if amount != 0 { 3275 c.ctxt.Diag("invalid index shift amount: %v", p) 3276 } 3277 case AMOVH, AMOVHU: 3278 if amount != 1 && amount != 0 { 3279 c.ctxt.Diag("invalid index shift amount: %v", p) 3280 } 3281 case AMOVW, AMOVWU, AFMOVS: 3282 if amount != 2 && amount != 0 { 3283 c.ctxt.Diag("invalid index shift amount: %v", p) 3284 } 3285 case AMOVD, AFMOVD: 3286 if amount != 3 && amount != 0 { 3287 c.ctxt.Diag("invalid index shift amount: %v", p) 3288 } 3289 default: 3290 panic("invalid operation") 3291 } 3292 } 3293 3294 func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { 3295 var os [5]uint32 3296 o1 := uint32(0) 3297 o2 := uint32(0) 3298 o3 := uint32(0) 3299 o4 := uint32(0) 3300 o5 := uint32(0) 3301 if false { 3302 fmt.Printf("%x: %v\ttype %d\n", uint32(p.Pc), p, o.type_) 3303 } 3304 switch o.type_ { 3305 default: 3306 c.ctxt.Diag("%v: unknown asm %d", p, o.type_) 3307 3308 case 0: 3309 break 3310 3311 case 1: 3312 o1 = c.oprrr(p, p.As) 3313 3314 rf := int(p.From.Reg) 3315 rt := int(p.To.Reg) 3316 r := int(p.Reg) 3317 if p.To.Type == obj.TYPE_NONE { 3318 rt = REGZERO 3319 } 3320 if r == obj.REG_NONE { 3321 r = rt 3322 } 3323 o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31) 3324 3325 case 2: 3326 if p.To.Reg == REG_RSP && isADDSop(p.As) { 3327 c.ctxt.Diag("illegal destination register: %v\n", p) 3328 } 3329 o1 = c.opirr(p, p.As) 3330 3331 rt, r := p.To.Reg, p.Reg 3332 if p.To.Type == obj.TYPE_NONE { 3333 if (o1 & Sbit) == 0 { 3334 c.ctxt.Diag("ineffective ZR destination\n%v", p) 3335 } 3336 rt = REGZERO 3337 } 3338 if r == obj.REG_NONE { 3339 r = rt 3340 } 3341 v := c.regoff(&p.From) 3342 o1 = c.oaddi(p, p.As, v, rt, r) 3343 3344 case 3: 3345 o1 = c.oprrr(p, p.As) 3346 3347 amount := (p.From.Offset >> 10) & 63 3348 is64bit := o1 & (1 << 31) 3349 if is64bit == 0 && amount >= 32 { 3350 c.ctxt.Diag("shift amount out of range 0 to 31: %v", p) 3351 } 3352 shift := (p.From.Offset >> 22) & 3 3353 if (shift > 2 || shift < 0) && (isADDop(p.As) || isADDWop(p.As) || isNEGop(p.As)) { 3354 c.ctxt.Diag("unsupported shift operator: %v", p) 3355 } 3356 o1 |= uint32(p.From.Offset) 3357 rt := int(p.To.Reg) 3358 if p.To.Type == obj.TYPE_NONE { 3359 rt = REGZERO 3360 } 3361 r := int(p.Reg) 3362 if p.As == AMVN || p.As == AMVNW || isNEGop(p.As) { 3363 r = REGZERO 3364 } else if r == obj.REG_NONE { 3365 r = rt 3366 } 3367 o1 |= (uint32(r&31) << 5) | uint32(rt&31) 3368 3369 case 4: 3370 rt, r := p.To.Reg, o.param 3371 if r == obj.REG_NONE { 3372 r = REGZERO 3373 } else if r == REGFROM { 3374 r = p.From.Reg 3375 } 3376 if r == obj.REG_NONE { 3377 r = REGSP 3378 } 3379 3380 v := c.regoff(&p.From) 3381 a := AADD 3382 if v < 0 { 3383 a = ASUB 3384 v = -v 3385 } 3386 3387 if o.size(c.ctxt, p) == 8 { 3388 3389 3390 o1 = c.oaddi(p, a, v&0xfff000, rt, r) 3391 o2 = c.oaddi(p, a, v&0x000fff, rt, rt) 3392 break 3393 } 3394 3395 o1 = c.oaddi(p, a, v, rt, r) 3396 3397 case 5: 3398 o1 = c.opbra(p, p.As) 3399 3400 if p.To.Sym == nil { 3401 o1 |= uint32(c.brdist(p, 0, 26, 2)) 3402 break 3403 } 3404 3405 rel := obj.Addrel(c.cursym) 3406 rel.Off = int32(c.pc) 3407 rel.Siz = 4 3408 rel.Sym = p.To.Sym 3409 rel.Add = p.To.Offset 3410 rel.Type = objabi.R_CALLARM64 3411 3412 case 6: 3413 o1 = c.opbrr(p, p.As) 3414 o1 |= uint32(p.To.Reg&31) << 5 3415 if p.As == obj.ACALL { 3416 rel := obj.Addrel(c.cursym) 3417 rel.Off = int32(c.pc) 3418 rel.Siz = 0 3419 rel.Type = objabi.R_CALLIND 3420 } 3421 3422 case 7: 3423 o1 = c.opbra(p, p.As) 3424 3425 o1 |= uint32(c.brdist(p, 0, 19, 2) << 5) 3426 3427 case 8: 3428 rt, rf := p.To.Reg, p.Reg 3429 if rf == obj.REG_NONE { 3430 rf = rt 3431 } 3432 v := p.From.Offset 3433 switch p.As { 3434 case AASR: 3435 o1 = c.opbfm(p, ASBFM, v, 63, rf, rt) 3436 3437 case AASRW: 3438 o1 = c.opbfm(p, ASBFMW, v, 31, rf, rt) 3439 3440 case ALSL: 3441 o1 = c.opbfm(p, AUBFM, (64-v)&63, 63-v, rf, rt) 3442 3443 case ALSLW: 3444 o1 = c.opbfm(p, AUBFMW, (32-v)&31, 31-v, rf, rt) 3445 3446 case ALSR: 3447 o1 = c.opbfm(p, AUBFM, v, 63, rf, rt) 3448 3449 case ALSRW: 3450 o1 = c.opbfm(p, AUBFMW, v, 31, rf, rt) 3451 3452 case AROR: 3453 o1 = c.opextr(p, AEXTR, v, rf, rf, rt) 3454 3455 case ARORW: 3456 o1 = c.opextr(p, AEXTRW, v, rf, rf, rt) 3457 3458 default: 3459 c.ctxt.Diag("bad shift $con\n%v", p) 3460 break 3461 } 3462 3463 case 9: 3464 o1 = c.oprrr(p, p.As) 3465 3466 r := int(p.Reg) 3467 if r == obj.REG_NONE { 3468 r = int(p.To.Reg) 3469 } 3470 o1 |= (uint32(p.From.Reg&31) << 16) | (uint32(r&31) << 5) | uint32(p.To.Reg&31) 3471 3472 case 10: 3473 o1 = c.opimm(p, p.As) 3474 3475 if p.From.Type != obj.TYPE_NONE { 3476 o1 |= uint32((p.From.Offset & 0xffff) << 5) 3477 } 3478 3479 case 11: 3480 c.aclass(&p.To) 3481 3482 o1 = uint32(c.instoffset) 3483 o2 = uint32(c.instoffset >> 32) 3484 if p.To.Sym != nil { 3485 rel := obj.Addrel(c.cursym) 3486 rel.Off = int32(c.pc) 3487 rel.Siz = 8 3488 rel.Sym = p.To.Sym 3489 rel.Add = p.To.Offset 3490 rel.Type = objabi.R_ADDR 3491 o2 = 0 3492 o1 = o2 3493 } 3494 3495 case 12: 3496 3497 3498 num := c.omovlconst(p.As, p, &p.From, int(p.To.Reg), os[:]) 3499 if num == 0 { 3500 c.ctxt.Diag("invalid constant: %v", p) 3501 } 3502 o1 = os[0] 3503 o2 = os[1] 3504 o3 = os[2] 3505 o4 = os[3] 3506 3507 case 13: 3508 if p.Reg == REGTMP { 3509 c.ctxt.Diag("cannot use REGTMP as source: %v\n", p) 3510 } 3511 if p.To.Reg == REG_RSP && isADDSop(p.As) { 3512 c.ctxt.Diag("illegal destination register: %v\n", p) 3513 } 3514 o := uint32(0) 3515 num := uint8(0) 3516 cls := oclass(&p.From) 3517 if isADDWop(p.As) { 3518 if !cmp(C_LCON, cls) { 3519 c.ctxt.Diag("illegal combination: %v", p) 3520 } 3521 num = c.omovlconst(AMOVW, p, &p.From, REGTMP, os[:]) 3522 } else { 3523 num = c.omovlconst(AMOVD, p, &p.From, REGTMP, os[:]) 3524 } 3525 if num == 0 { 3526 c.ctxt.Diag("invalid constant: %v", p) 3527 } 3528 rt := int(p.To.Reg) 3529 if p.To.Type == obj.TYPE_NONE { 3530 rt = REGZERO 3531 } 3532 r := int(p.Reg) 3533 if r == obj.REG_NONE { 3534 r = rt 3535 } 3536 if p.To.Type != obj.TYPE_NONE && (p.To.Reg == REGSP || r == REGSP) { 3537 o = c.opxrrr(p, p.As, false) 3538 o |= REGTMP & 31 << 16 3539 o |= LSL0_64 3540 } else { 3541 o = c.oprrr(p, p.As) 3542 o |= REGTMP & 31 << 16 3543 } 3544 3545 o |= uint32(r&31) << 5 3546 o |= uint32(rt & 31) 3547 3548 os[num] = o 3549 o1 = os[0] 3550 o2 = os[1] 3551 o3 = os[2] 3552 o4 = os[3] 3553 o5 = os[4] 3554 3555 case 14: 3556 if c.aclass(&p.To) == C_ADDR { 3557 c.ctxt.Diag("address constant needs DWORD\n%v", p) 3558 } 3559 o1 = uint32(c.instoffset) 3560 if p.To.Sym != nil { 3561 3562 3563 rel := obj.Addrel(c.cursym) 3564 3565 rel.Off = int32(c.pc) 3566 rel.Siz = 4 3567 rel.Sym = p.To.Sym 3568 rel.Add = p.To.Offset 3569 rel.Type = objabi.R_ADDR 3570 o1 = 0 3571 } 3572 3573 case 15: 3574 o1 = c.oprrr(p, p.As) 3575 3576 rf := int(p.From.Reg) 3577 rt := int(p.To.Reg) 3578 var r int 3579 var ra int 3580 if p.From3Type() == obj.TYPE_REG { 3581 r = int(p.GetFrom3().Reg) 3582 ra = int(p.Reg) 3583 if ra == obj.REG_NONE { 3584 ra = REGZERO 3585 } 3586 } else { 3587 r = int(p.Reg) 3588 if r == obj.REG_NONE { 3589 r = rt 3590 } 3591 ra = REGZERO 3592 } 3593 3594 o1 |= (uint32(rf&31) << 16) | (uint32(ra&31) << 10) | (uint32(r&31) << 5) | uint32(rt&31) 3595 3596 case 16: 3597 o1 = c.oprrr(p, p.As) 3598 3599 rf := int(p.From.Reg) 3600 rt := int(p.To.Reg) 3601 r := int(p.Reg) 3602 if r == obj.REG_NONE { 3603 r = rt 3604 } 3605 o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | REGTMP&31 3606 o2 = c.oprrr(p, AMSUBW) 3607 o2 |= o1 & (1 << 31) 3608 o2 |= (uint32(rf&31) << 16) | (uint32(r&31) << 10) | (REGTMP & 31 << 5) | uint32(rt&31) 3609 3610 case 17: 3611 o1 = c.oprrr(p, p.As) 3612 3613 rf := int(p.From.Reg) 3614 rt := int(p.To.Reg) 3615 r := int(p.Reg) 3616 if p.To.Type == obj.TYPE_NONE { 3617 rt = REGZERO 3618 } 3619 if r == obj.REG_NONE { 3620 r = REGZERO 3621 } 3622 o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31) 3623 3624 case 18: 3625 o1 = c.oprrr(p, p.As) 3626 3627 cond := SpecialOperand(p.From.Offset) 3628 if cond < SPOP_EQ || cond > SPOP_NV || (cond == SPOP_AL || cond == SPOP_NV) && p.From3Type() == obj.TYPE_NONE { 3629 c.ctxt.Diag("invalid condition: %v", p) 3630 } else { 3631 cond -= SPOP_EQ 3632 } 3633 3634 r := int(p.Reg) 3635 var rf int = r 3636 if p.From3Type() == obj.TYPE_NONE { 3637 3638 if r == obj.REG_NONE { 3639 3640 rf = REGZERO 3641 r = rf 3642 } 3643 cond ^= 1 3644 } else { 3645 rf = int(p.GetFrom3().Reg) 3646 } 3647 3648 rt := int(p.To.Reg) 3649 o1 |= (uint32(rf&31) << 16) | (uint32(cond&15) << 12) | (uint32(r&31) << 5) | uint32(rt&31) 3650 3651 case 19: 3652 nzcv := int(p.To.Offset) 3653 3654 cond := SpecialOperand(p.From.Offset) 3655 if cond < SPOP_EQ || cond > SPOP_NV { 3656 c.ctxt.Diag("invalid condition\n%v", p) 3657 } else { 3658 cond -= SPOP_EQ 3659 } 3660 var rf int 3661 if p.GetFrom3().Type == obj.TYPE_REG { 3662 o1 = c.oprrr(p, p.As) 3663 rf = int(p.GetFrom3().Reg) 3664 } else { 3665 o1 = c.opirr(p, p.As) 3666 rf = int(p.GetFrom3().Offset & 0x1F) 3667 } 3668 3669 o1 |= (uint32(rf&31) << 16) | (uint32(cond&15) << 12) | (uint32(p.Reg&31) << 5) | uint32(nzcv) 3670 3671 case 20: 3672 v := c.regoff(&p.To) 3673 sz := int32(1 << uint(movesize(p.As))) 3674 3675 rt, rf := p.To.Reg, p.From.Reg 3676 if rt == obj.REG_NONE { 3677 rt = o.param 3678 } 3679 if v < 0 || v%sz != 0 { 3680 o1 = c.olsr9s(p, c.opstr(p, p.As), v, rt, rf) 3681 } else { 3682 v = int32(c.offsetshift(p, int64(v), int(o.a4))) 3683 o1 = c.olsr12u(p, c.opstr(p, p.As), v, rt, rf) 3684 } 3685 3686 case 21: 3687 v := c.regoff(&p.From) 3688 sz := int32(1 << uint(movesize(p.As))) 3689 3690 rt, rf := p.To.Reg, p.From.Reg 3691 if rf == obj.REG_NONE { 3692 rf = o.param 3693 } 3694 if v < 0 || v%sz != 0 { 3695 o1 = c.olsr9s(p, c.opldr(p, p.As), v, rf, rt) 3696 } else { 3697 v = int32(c.offsetshift(p, int64(v), int(o.a1))) 3698 o1 = c.olsr12u(p, c.opldr(p, p.As), v, rf, rt) 3699 } 3700 3701 case 22: 3702 if p.From.Reg != REGSP && p.From.Reg == p.To.Reg { 3703 c.ctxt.Diag("constrained unpredictable behavior: %v", p) 3704 } 3705 3706 v := int32(p.From.Offset) 3707 3708 if v < -256 || v > 255 { 3709 c.ctxt.Diag("offset out of range [-256,255]: %v", p) 3710 } 3711 o1 = c.opldr(p, p.As) 3712 if o.scond == C_XPOST { 3713 o1 |= 1 << 10 3714 } else { 3715 o1 |= 3 << 10 3716 } 3717 o1 |= ((uint32(v) & 0x1FF) << 12) | (uint32(p.From.Reg&31) << 5) | uint32(p.To.Reg&31) 3718 3719 case 23: 3720 if p.To.Reg != REGSP && p.From.Reg == p.To.Reg { 3721 c.ctxt.Diag("constrained unpredictable behavior: %v", p) 3722 } 3723 3724 v := int32(p.To.Offset) 3725 3726 if v < -256 || v > 255 { 3727 c.ctxt.Diag("offset out of range [-256,255]: %v", p) 3728 } 3729 o1 = c.opstr(p, p.As) 3730 if o.scond == C_XPOST { 3731 o1 |= 1 << 10 3732 } else { 3733 o1 |= 3 << 10 3734 } 3735 o1 |= ((uint32(v) & 0x1FF) << 12) | (uint32(p.To.Reg&31) << 5) | uint32(p.From.Reg&31) 3736 3737 case 24: 3738 rf := int(p.From.Reg) 3739 rt := int(p.To.Reg) 3740 if rf == REGSP || rt == REGSP { 3741 if p.As == AMVN || p.As == AMVNW { 3742 c.ctxt.Diag("illegal SP reference\n%v", p) 3743 } 3744 o1 = c.opirr(p, p.As) 3745 o1 |= (uint32(rf&31) << 5) | uint32(rt&31) 3746 } else { 3747 o1 = c.oprrr(p, p.As) 3748 o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31) 3749 } 3750 3751 case 25: 3752 o1 = c.oprrr(p, p.As) 3753 3754 rf := int(p.From.Reg) 3755 if rf == C_NONE { 3756 rf = int(p.To.Reg) 3757 } 3758 rt := int(p.To.Reg) 3759 o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31) 3760 3761 case 27: 3762 if p.To.Reg == REG_RSP && isADDSop(p.As) { 3763 c.ctxt.Diag("illegal destination register: %v\n", p) 3764 } 3765 if (p.From.Reg-obj.RBaseARM64)®_EXT != 0 || 3766 (p.From.Reg >= REG_LSL && p.From.Reg < REG_ARNG) { 3767 amount := (p.From.Reg >> 5) & 7 3768 if amount > 4 { 3769 c.ctxt.Diag("shift amount out of range 0 to 4: %v", p) 3770 } 3771 o1 = c.opxrrr(p, p.As, true) 3772 o1 |= c.encRegShiftOrExt(p, &p.From, p.From.Reg) 3773 } else { 3774 o1 = c.opxrrr(p, p.As, false) 3775 o1 |= uint32(p.From.Reg&31) << 16 3776 } 3777 rt := int(p.To.Reg) 3778 if p.To.Type == obj.TYPE_NONE { 3779 rt = REGZERO 3780 } 3781 r := int(p.Reg) 3782 if r == obj.REG_NONE { 3783 r = rt 3784 } 3785 o1 |= (uint32(r&31) << 5) | uint32(rt&31) 3786 3787 case 28: 3788 if p.Reg == REGTMP { 3789 c.ctxt.Diag("cannot use REGTMP as source: %v\n", p) 3790 } 3791 o := uint32(0) 3792 num := uint8(0) 3793 cls := oclass(&p.From) 3794 if isANDWop(p.As) { 3795 if !cmp(C_LCON, cls) { 3796 c.ctxt.Diag("illegal combination: %v", p) 3797 } 3798 num = c.omovlconst(AMOVW, p, &p.From, REGTMP, os[:]) 3799 } else { 3800 num = c.omovlconst(AMOVD, p, &p.From, REGTMP, os[:]) 3801 } 3802 3803 if num == 0 { 3804 c.ctxt.Diag("invalid constant: %v", p) 3805 } 3806 rt := int(p.To.Reg) 3807 if p.To.Type == obj.TYPE_NONE { 3808 rt = REGZERO 3809 } 3810 r := int(p.Reg) 3811 if r == obj.REG_NONE { 3812 r = rt 3813 } 3814 o = c.oprrr(p, p.As) 3815 o |= REGTMP & 31 << 16 3816 o |= uint32(r&31) << 5 3817 o |= uint32(rt & 31) 3818 3819 os[num] = o 3820 o1 = os[0] 3821 o2 = os[1] 3822 o3 = os[2] 3823 o4 = os[3] 3824 o5 = os[4] 3825 3826 case 29: 3827 fc := c.aclass(&p.From) 3828 tc := c.aclass(&p.To) 3829 if (p.As == AFMOVD || p.As == AFMOVS) && (fc == C_REG || fc == C_ZREG || tc == C_REG) { 3830 3831 o1 = FPCVTI(0, 0, 0, 0, 6) 3832 if p.As == AFMOVD { 3833 o1 |= 1<<31 | 1<<22 3834 } 3835 if fc == C_REG || fc == C_ZREG { 3836 o1 |= 1 << 16 3837 } 3838 } else { 3839 o1 = c.oprrr(p, p.As) 3840 } 3841 o1 |= uint32(p.From.Reg&31)<<5 | uint32(p.To.Reg&31) 3842 3843 case 30: 3844 3845 3846 3847 3848 3849 3850 s := movesize(o.as) 3851 if s < 0 { 3852 c.ctxt.Diag("unexpected long move, op %v tab %v\n%v", p.As, o.as, p) 3853 } 3854 3855 r := p.To.Reg 3856 if r == obj.REG_NONE { 3857 r = o.param 3858 } 3859 3860 v := c.regoff(&p.To) 3861 var hi int32 3862 if v < 0 || (v&((1<<uint(s))-1)) != 0 { 3863 3864 goto storeusepool 3865 } 3866 3867 hi = v - (v & (0xFFF << uint(s))) 3868 if hi&0xFFF != 0 { 3869 c.ctxt.Diag("internal: miscalculated offset %d [%d]\n%v", v, s, p) 3870 } 3871 if hi&^0xFFF000 != 0 { 3872 3873 goto storeusepool 3874 } 3875 3876 o1 = c.oaddi(p, AADD, hi, REGTMP, r) 3877 o2 = c.olsr12u(p, c.opstr(p, p.As), ((v-hi)>>uint(s))&0xFFF, REGTMP, p.From.Reg) 3878 break 3879 3880 storeusepool: 3881 if r == REGTMP || p.From.Reg == REGTMP { 3882 c.ctxt.Diag("REGTMP used in large offset store: %v", p) 3883 } 3884 o1 = c.omovlit(AMOVD, p, &p.To, REGTMP) 3885 o2 = c.olsxrr(p, int32(c.opstrr(p, p.As, false)), int(p.From.Reg), int(r), REGTMP) 3886 3887 case 31: 3888 3889 3890 3891 3892 3893 3894 s := movesize(o.as) 3895 if s < 0 { 3896 c.ctxt.Diag("unexpected long move, op %v tab %v\n%v", p.As, o.as, p) 3897 } 3898 3899 r := p.From.Reg 3900 if r == obj.REG_NONE { 3901 r = o.param 3902 } 3903 3904 v := c.regoff(&p.From) 3905 var hi int32 3906 if v < 0 || (v&((1<<uint(s))-1)) != 0 { 3907 3908 goto loadusepool 3909 } 3910 3911 hi = v - (v & (0xFFF << uint(s))) 3912 if (hi & 0xFFF) != 0 { 3913 c.ctxt.Diag("internal: miscalculated offset %d [%d]\n%v", v, s, p) 3914 } 3915 if hi&^0xFFF000 != 0 { 3916 3917 goto loadusepool 3918 } 3919 3920 o1 = c.oaddi(p, AADD, hi, REGTMP, r) 3921 o2 = c.olsr12u(p, c.opldr(p, p.As), ((v-hi)>>uint(s))&0xFFF, REGTMP, p.To.Reg) 3922 break 3923 3924 loadusepool: 3925 if r == REGTMP || p.From.Reg == REGTMP { 3926 c.ctxt.Diag("REGTMP used in large offset load: %v", p) 3927 } 3928 o1 = c.omovlit(AMOVD, p, &p.From, REGTMP) 3929 o2 = c.olsxrr(p, int32(c.opldrr(p, p.As, false)), int(p.To.Reg), int(r), REGTMP) 3930 3931 case 32: 3932 o1 = c.omovconst(p.As, p, &p.From, int(p.To.Reg)) 3933 3934 case 33: 3935 o1 = c.opirr(p, p.As) 3936 3937 d := p.From.Offset 3938 if d == 0 { 3939 c.ctxt.Diag("zero shifts cannot be handled correctly: %v", p) 3940 } 3941 s := movcon(d) 3942 if s < 0 || s >= 4 { 3943 c.ctxt.Diag("bad constant for MOVK: %#x\n%v", uint64(d), p) 3944 } 3945 if (o1&S64) == 0 && s >= 2 { 3946 c.ctxt.Diag("illegal bit position\n%v", p) 3947 } 3948 if ((uint64(d) >> uint(s*16)) >> 16) != 0 { 3949 c.ctxt.Diag("requires uimm16\n%v", p) 3950 } 3951 rt := int(p.To.Reg) 3952 3953 o1 |= uint32((((d >> uint(s*16)) & 0xFFFF) << 5) | int64((uint32(s)&3)<<21) | int64(rt&31)) 3954 3955 case 34: 3956 o1 = c.omovlit(AMOVD, p, &p.From, REGTMP) 3957 o2 = c.opxrrr(p, AADD, false) 3958 o2 |= REGTMP & 31 << 16 3959 o2 |= LSL0_64 3960 r := int(p.From.Reg) 3961 if r == obj.REG_NONE { 3962 r = int(o.param) 3963 } 3964 o2 |= uint32(r&31) << 5 3965 o2 |= uint32(p.To.Reg & 31) 3966 3967 case 35: 3968 o1 = c.oprrr(p, AMRS) 3969 3970 3971 _, v, accessFlags := SysRegEnc(p.From.Reg) 3972 if v == 0 { 3973 c.ctxt.Diag("illegal system register:\n%v", p) 3974 } 3975 if (o1 & (v &^ (3 << 19))) != 0 { 3976 c.ctxt.Diag("MRS register value overlap\n%v", p) 3977 } 3978 if accessFlags&SR_READ == 0 { 3979 c.ctxt.Diag("system register is not readable: %v", p) 3980 } 3981 3982 o1 |= v 3983 o1 |= uint32(p.To.Reg & 31) 3984 3985 case 36: 3986 o1 = c.oprrr(p, AMSR) 3987 3988 3989 _, v, accessFlags := SysRegEnc(p.To.Reg) 3990 if v == 0 { 3991 c.ctxt.Diag("illegal system register:\n%v", p) 3992 } 3993 if (o1 & (v &^ (3 << 19))) != 0 { 3994 c.ctxt.Diag("MSR register value overlap\n%v", p) 3995 } 3996 if accessFlags&SR_WRITE == 0 { 3997 c.ctxt.Diag("system register is not writable: %v", p) 3998 } 3999 4000 o1 |= v 4001 o1 |= uint32(p.From.Reg & 31) 4002 4003 case 37: 4004 if (uint64(p.From.Offset) &^ uint64(0xF)) != 0 { 4005 c.ctxt.Diag("illegal immediate for PSTATE field\n%v", p) 4006 } 4007 o1 = c.opirr(p, AMSR) 4008 o1 |= uint32((p.From.Offset & 0xF) << 8) 4009 v := uint32(0) 4010 4011 if p.To.Type == obj.TYPE_REG && p.To.Reg == REG_SPSel { 4012 v = 0<<16 | 4<<12 | 5<<5 4013 } else if p.To.Type == obj.TYPE_SPECIAL { 4014 opd := SpecialOperand(p.To.Offset) 4015 for _, pf := range pstatefield { 4016 if pf.opd == opd { 4017 v = pf.enc 4018 break 4019 } 4020 } 4021 } 4022 4023 if v == 0 { 4024 c.ctxt.Diag("illegal PSTATE field for immediate move\n%v", p) 4025 } 4026 o1 |= v 4027 4028 case 38: 4029 o1 = c.opimm(p, p.As) 4030 4031 if p.To.Type == obj.TYPE_NONE { 4032 o1 |= 0xF << 8 4033 } else { 4034 o1 |= uint32((p.To.Offset & 0xF) << 8) 4035 } 4036 4037 case 39: 4038 o1 = c.opirr(p, p.As) 4039 4040 o1 |= uint32(p.From.Reg & 31) 4041 o1 |= uint32(c.brdist(p, 0, 19, 2) << 5) 4042 4043 case 40: 4044 o1 = c.opirr(p, p.As) 4045 4046 v := int32(p.From.Offset) 4047 if v < 0 || v > 63 { 4048 c.ctxt.Diag("illegal bit number\n%v", p) 4049 } 4050 o1 |= ((uint32(v) & 0x20) << (31 - 5)) | ((uint32(v) & 0x1F) << 19) 4051 o1 |= uint32(c.brdist(p, 0, 14, 2) << 5) 4052 o1 |= uint32(p.Reg & 31) 4053 4054 case 41: 4055 o1 = c.op0(p, p.As) 4056 4057 case 42: 4058 o1 = c.opbfm(p, p.As, p.From.Offset, p.GetFrom3().Offset, p.Reg, p.To.Reg) 4059 4060 case 43: 4061 rt, rf := p.To.Reg, p.Reg 4062 if rf == obj.REG_NONE { 4063 rf = rt 4064 } 4065 r, s := p.From.Offset, p.GetFrom3().Offset 4066 switch p.As { 4067 case ABFI: 4068 if r != 0 { 4069 r = 64 - r 4070 } 4071 o1 = c.opbfm(p, ABFM, r, s-1, rf, rt) 4072 4073 case ABFIW: 4074 if r != 0 { 4075 r = 32 - r 4076 } 4077 o1 = c.opbfm(p, ABFMW, r, s-1, rf, rt) 4078 4079 case ABFXIL: 4080 o1 = c.opbfm(p, ABFM, r, r+s-1, rf, rt) 4081 4082 case ABFXILW: 4083 o1 = c.opbfm(p, ABFMW, r, r+s-1, rf, rt) 4084 4085 case ASBFIZ: 4086 if r != 0 { 4087 r = 64 - r 4088 } 4089 o1 = c.opbfm(p, ASBFM, r, s-1, rf, rt) 4090 4091 case ASBFIZW: 4092 if r != 0 { 4093 r = 32 - r 4094 } 4095 o1 = c.opbfm(p, ASBFMW, r, s-1, rf, rt) 4096 4097 case ASBFX: 4098 o1 = c.opbfm(p, ASBFM, r, r+s-1, rf, rt) 4099 4100 case ASBFXW: 4101 o1 = c.opbfm(p, ASBFMW, r, r+s-1, rf, rt) 4102 4103 case AUBFIZ: 4104 if r != 0 { 4105 r = 64 - r 4106 } 4107 o1 = c.opbfm(p, AUBFM, r, s-1, rf, rt) 4108 4109 case AUBFIZW: 4110 if r != 0 { 4111 r = 32 - r 4112 } 4113 o1 = c.opbfm(p, AUBFMW, r, s-1, rf, rt) 4114 4115 case AUBFX: 4116 o1 = c.opbfm(p, AUBFM, r, r+s-1, rf, rt) 4117 4118 case AUBFXW: 4119 o1 = c.opbfm(p, AUBFMW, r, r+s-1, rf, rt) 4120 4121 default: 4122 c.ctxt.Diag("bad bfm alias\n%v", p) 4123 break 4124 } 4125 4126 case 44: 4127 o1 = c.opextr(p, p.As, p.From.Offset, p.GetFrom3().Reg, p.Reg, p.To.Reg) 4128 4129 case 45: 4130 as := p.As 4131 rt, rf := p.To.Reg, p.From.Reg 4132 if rf == REGZERO { 4133 as = AMOVWU 4134 } 4135 switch as { 4136 case AMOVB, ASXTB: 4137 o1 = c.opbfm(p, ASBFM, 0, 7, rf, rt) 4138 4139 case AMOVH, ASXTH: 4140 o1 = c.opbfm(p, ASBFM, 0, 15, rf, rt) 4141 4142 case AMOVW, ASXTW: 4143 o1 = c.opbfm(p, ASBFM, 0, 31, rf, rt) 4144 4145 case AMOVBU, AUXTB: 4146 o1 = c.opbfm(p, AUBFM, 0, 7, rf, rt) 4147 4148 case AMOVHU, AUXTH: 4149 o1 = c.opbfm(p, AUBFM, 0, 15, rf, rt) 4150 4151 case AMOVWU: 4152 o1 = c.oprrr(p, as) | (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31) 4153 4154 case AUXTW: 4155 o1 = c.opbfm(p, AUBFM, 0, 31, rf, rt) 4156 4157 case ASXTBW: 4158 o1 = c.opbfm(p, ASBFMW, 0, 7, rf, rt) 4159 4160 case ASXTHW: 4161 o1 = c.opbfm(p, ASBFMW, 0, 15, rf, rt) 4162 4163 case AUXTBW: 4164 o1 = c.opbfm(p, AUBFMW, 0, 7, rf, rt) 4165 4166 case AUXTHW: 4167 o1 = c.opbfm(p, AUBFMW, 0, 15, rf, rt) 4168 4169 default: 4170 c.ctxt.Diag("bad sxt %v", as) 4171 break 4172 } 4173 4174 case 46: 4175 o1 = c.opbit(p, p.As) 4176 4177 o1 |= uint32(p.From.Reg&31) << 5 4178 o1 |= uint32(p.To.Reg & 31) 4179 4180 case 47: 4181 rs := p.From.Reg 4182 rt := p.RegTo2 4183 rb := p.To.Reg 4184 4185 4186 if rt == REG_RSP { 4187 c.ctxt.Diag("illegal destination register: %v\n", p) 4188 } 4189 4190 o1 = atomicLDADD[p.As] | atomicSWP[p.As] 4191 o1 |= uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31) 4192 4193 case 48: 4194 4195 4196 op := c.opirr(p, p.As) 4197 if op&Sbit != 0 { 4198 c.ctxt.Diag("can not break addition/subtraction when S bit is set", p) 4199 } 4200 rt, r := p.To.Reg, p.Reg 4201 if r == obj.REG_NONE { 4202 r = rt 4203 } 4204 o1 = c.oaddi(p, p.As, c.regoff(&p.From)&0x000fff, rt, r) 4205 o2 = c.oaddi(p, p.As, c.regoff(&p.From)&0xfff000, rt, rt) 4206 4207 case 50: 4208 o1 = c.opirr(p, p.As) 4209 4210 if (p.From.Offset &^ int64(SYSARG4(0x7, 0xF, 0xF, 0x7))) != 0 { 4211 c.ctxt.Diag("illegal SYS argument\n%v", p) 4212 } 4213 o1 |= uint32(p.From.Offset) 4214 if p.To.Type == obj.TYPE_REG { 4215 o1 |= uint32(p.To.Reg & 31) 4216 } else { 4217 o1 |= 0x1F 4218 } 4219 4220 case 51: 4221 o1 = c.opirr(p, p.As) 4222 4223 if p.From.Type == obj.TYPE_CONST { 4224 o1 |= uint32((p.From.Offset & 0xF) << 8) 4225 } 4226 4227 case 52: 4228 o1 = c.opirr(p, p.As) 4229 4230 o1 |= uint32((p.From.Offset & 0x7F) << 5) 4231 4232 case 53: 4233 a := p.As 4234 rt := int(p.To.Reg) 4235 if p.To.Type == obj.TYPE_NONE { 4236 rt = REGZERO 4237 } 4238 r := int(p.Reg) 4239 if r == obj.REG_NONE { 4240 r = rt 4241 } 4242 if r == REG_RSP { 4243 c.ctxt.Diag("illegal source register: %v", p) 4244 break 4245 } 4246 mode := 64 4247 v := uint64(p.From.Offset) 4248 switch p.As { 4249 case AANDW, AORRW, AEORW, AANDSW, ATSTW: 4250 mode = 32 4251 case ABIC, AORN, AEON, ABICS: 4252 v = ^v 4253 case ABICW, AORNW, AEONW, ABICSW: 4254 v = ^v 4255 mode = 32 4256 } 4257 o1 = c.opirr(p, a) 4258 o1 |= bitconEncode(v, mode) | uint32(r&31)<<5 | uint32(rt&31) 4259 4260 case 54: 4261 o1 = c.oprrr(p, p.As) 4262 rf := int(p.From.Reg) 4263 rt := int(p.To.Reg) 4264 r := int(p.Reg) 4265 if (o1&(0x1F<<24)) == (0x1E<<24) && (o1&(1<<11)) == 0 { 4266 r = rf 4267 rf = 0 4268 } else if r == obj.REG_NONE { 4269 r = rt 4270 } 4271 o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31) 4272 4273 case 55: 4274 var rf int 4275 o1 = 0xf<<25 | 1<<21 | 1<<12 4276 rf = c.chipfloat7(p.From.Val.(float64)) 4277 if rf < 0 { 4278 c.ctxt.Diag("invalid floating-point immediate\n%v", p) 4279 } 4280 if p.As == AFMOVD { 4281 o1 |= 1 << 22 4282 } 4283 o1 |= (uint32(rf&0xff) << 13) | uint32(p.To.Reg&31) 4284 4285 case 56: 4286 o1 = c.oprrr(p, p.As) 4287 4288 var rf int 4289 if p.From.Type == obj.TYPE_FCONST { 4290 o1 |= 8 4291 rf = 0 4292 } else { 4293 rf = int(p.From.Reg) 4294 } 4295 rt := int(p.Reg) 4296 o1 |= uint32(rf&31)<<16 | uint32(rt&31)<<5 4297 4298 case 57: 4299 o1 = c.oprrr(p, p.As) 4300 4301 cond := SpecialOperand(p.From.Offset) 4302 if cond < SPOP_EQ || cond > SPOP_NV { 4303 c.ctxt.Diag("invalid condition\n%v", p) 4304 } else { 4305 cond -= SPOP_EQ 4306 } 4307 4308 nzcv := int(p.To.Offset) 4309 if nzcv&^0xF != 0 { 4310 c.ctxt.Diag("implausible condition\n%v", p) 4311 } 4312 rf := int(p.Reg) 4313 if p.GetFrom3() == nil || p.GetFrom3().Reg < REG_F0 || p.GetFrom3().Reg > REG_F31 { 4314 c.ctxt.Diag("illegal FCCMP\n%v", p) 4315 break 4316 } 4317 rt := int(p.GetFrom3().Reg) 4318 o1 |= uint32(rf&31)<<16 | uint32(cond&15)<<12 | uint32(rt&31)<<5 | uint32(nzcv) 4319 4320 case 58: 4321 o1 = c.opload(p, p.As) 4322 4323 o1 |= 0x1F << 16 4324 o1 |= uint32(p.From.Reg&31) << 5 4325 if p.As == ALDXP || p.As == ALDXPW || p.As == ALDAXP || p.As == ALDAXPW { 4326 if int(p.To.Reg) == int(p.To.Offset) { 4327 c.ctxt.Diag("constrained unpredictable behavior: %v", p) 4328 } 4329 o1 |= uint32(p.To.Offset&31) << 10 4330 } else { 4331 o1 |= 0x1F << 10 4332 } 4333 o1 |= uint32(p.To.Reg & 31) 4334 4335 case 59: 4336 s := p.RegTo2 4337 n := p.To.Reg 4338 t := p.From.Reg 4339 if isSTLXRop(p.As) { 4340 if s == t || (s == n && n != REGSP) { 4341 c.ctxt.Diag("constrained unpredictable behavior: %v", p) 4342 } 4343 } else if isSTXPop(p.As) { 4344 t2 := int16(p.From.Offset) 4345 if (s == t || s == t2) || (s == n && n != REGSP) { 4346 c.ctxt.Diag("constrained unpredictable behavior: %v", p) 4347 } 4348 } 4349 if s == REG_RSP { 4350 c.ctxt.Diag("illegal destination register: %v\n", p) 4351 } 4352 o1 = c.opstore(p, p.As) 4353 4354 if p.RegTo2 != obj.REG_NONE { 4355 o1 |= uint32(p.RegTo2&31) << 16 4356 } else { 4357 o1 |= 0x1F << 16 4358 } 4359 if isSTXPop(p.As) { 4360 o1 |= uint32(p.From.Offset&31) << 10 4361 } 4362 o1 |= uint32(p.To.Reg&31)<<5 | uint32(p.From.Reg&31) 4363 4364 case 60: 4365 d := c.brdist(p, 12, 21, 0) 4366 4367 o1 = ADR(1, uint32(d), uint32(p.To.Reg)) 4368 4369 case 61: 4370 d := c.brdist(p, 0, 21, 0) 4371 4372 o1 = ADR(0, uint32(d), uint32(p.To.Reg)) 4373 4374 case 62: 4375 if p.Reg == REGTMP { 4376 c.ctxt.Diag("cannot use REGTMP as source: %v\n", p) 4377 } 4378 if p.To.Reg == REG_RSP && isADDSop(p.As) { 4379 c.ctxt.Diag("illegal destination register: %v\n", p) 4380 } 4381 lsl0 := LSL0_64 4382 if isADDWop(p.As) || isANDWop(p.As) { 4383 o1 = c.omovconst(AMOVW, p, &p.From, REGTMP) 4384 lsl0 = LSL0_32 4385 } else { 4386 o1 = c.omovconst(AMOVD, p, &p.From, REGTMP) 4387 } 4388 4389 rt := int(p.To.Reg) 4390 if p.To.Type == obj.TYPE_NONE { 4391 rt = REGZERO 4392 } 4393 r := int(p.Reg) 4394 if r == obj.REG_NONE { 4395 r = rt 4396 } 4397 if p.To.Reg == REGSP || r == REGSP { 4398 o2 = c.opxrrr(p, p.As, false) 4399 o2 |= REGTMP & 31 << 16 4400 o2 |= uint32(lsl0) 4401 } else { 4402 o2 = c.oprrr(p, p.As) 4403 o2 |= REGTMP & 31 << 16 4404 } 4405 o2 |= uint32(r&31) << 5 4406 o2 |= uint32(rt & 31) 4407 4408 4409 case 64: 4410 if p.From.Reg == REGTMP { 4411 c.ctxt.Diag("cannot use REGTMP as source: %v\n", p) 4412 } 4413 o1 = ADR(1, 0, REGTMP) 4414 rel := obj.Addrel(c.cursym) 4415 rel.Off = int32(c.pc) 4416 rel.Siz = 8 4417 rel.Sym = p.To.Sym 4418 rel.Add = p.To.Offset 4419 4420 if o.size(c.ctxt, p) != 8 { 4421 o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31 4422 o3 = c.olsr12u(p, c.opstr(p, p.As), 0, REGTMP, p.From.Reg) 4423 rel.Type = objabi.R_ADDRARM64 4424 break 4425 } 4426 o2 = c.olsr12u(p, c.opstr(p, p.As), 0, REGTMP, p.From.Reg) 4427 rel.Type = c.addrRelocType(p) 4428 4429 case 65: 4430 o1 = ADR(1, 0, REGTMP) 4431 rel := obj.Addrel(c.cursym) 4432 rel.Off = int32(c.pc) 4433 rel.Siz = 8 4434 rel.Sym = p.From.Sym 4435 rel.Add = p.From.Offset 4436 4437 if o.size(c.ctxt, p) != 8 { 4438 o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31 4439 o3 = c.olsr12u(p, c.opldr(p, p.As), 0, REGTMP, p.To.Reg) 4440 rel.Type = objabi.R_ADDRARM64 4441 break 4442 } 4443 o2 = c.olsr12u(p, c.opldr(p, p.As), 0, REGTMP, p.To.Reg) 4444 rel.Type = c.addrRelocType(p) 4445 4446 case 66: 4447 rf, rt1, rt2 := p.From.Reg, p.To.Reg, int16(p.To.Offset) 4448 if rf == obj.REG_NONE { 4449 rf = o.param 4450 } 4451 if rf == obj.REG_NONE { 4452 c.ctxt.Diag("invalid ldp source: %v\n", p) 4453 } 4454 v := c.regoff(&p.From) 4455 o1 = c.opldpstp(p, o, v, rf, rt1, rt2, 1) 4456 4457 case 67: 4458 rt, rf1, rf2 := p.To.Reg, p.From.Reg, int16(p.From.Offset) 4459 if rt == obj.REG_NONE { 4460 rt = o.param 4461 } 4462 if rt == obj.REG_NONE { 4463 c.ctxt.Diag("invalid stp destination: %v\n", p) 4464 } 4465 v := c.regoff(&p.To) 4466 o1 = c.opldpstp(p, o, v, rt, rf1, rf2, 0) 4467 4468 case 68: 4469 4470 4471 if p.As == AMOVW { 4472 c.ctxt.Diag("invalid load of 32-bit address: %v", p) 4473 } 4474 o1 = ADR(1, 0, uint32(p.To.Reg)) 4475 o2 = c.opirr(p, AADD) | uint32(p.To.Reg&31)<<5 | uint32(p.To.Reg&31) 4476 rel := obj.Addrel(c.cursym) 4477 rel.Off = int32(c.pc) 4478 rel.Siz = 8 4479 rel.Sym = p.From.Sym 4480 rel.Add = p.From.Offset 4481 rel.Type = objabi.R_ADDRARM64 4482 4483 case 69: 4484 o1 = c.opirr(p, AMOVZ) 4485 o1 |= uint32(p.To.Reg & 31) 4486 rel := obj.Addrel(c.cursym) 4487 rel.Off = int32(c.pc) 4488 rel.Siz = 4 4489 rel.Sym = p.From.Sym 4490 rel.Type = objabi.R_ARM64_TLS_LE 4491 if p.From.Offset != 0 { 4492 c.ctxt.Diag("invalid offset on MOVW $tlsvar") 4493 } 4494 4495 case 70: 4496 o1 = ADR(1, 0, REGTMP) 4497 o2 = c.olsr12u(p, c.opldr(p, AMOVD), 0, REGTMP, p.To.Reg) 4498 rel := obj.Addrel(c.cursym) 4499 rel.Off = int32(c.pc) 4500 rel.Siz = 8 4501 rel.Sym = p.From.Sym 4502 rel.Add = 0 4503 rel.Type = objabi.R_ARM64_TLS_IE 4504 if p.From.Offset != 0 { 4505 c.ctxt.Diag("invalid offset on MOVW $tlsvar") 4506 } 4507 4508 case 71: 4509 o1 = ADR(1, 0, REGTMP) 4510 o2 = c.olsr12u(p, c.opldr(p, AMOVD), 0, REGTMP, p.To.Reg) 4511 rel := obj.Addrel(c.cursym) 4512 rel.Off = int32(c.pc) 4513 rel.Siz = 8 4514 rel.Sym = p.From.Sym 4515 rel.Add = 0 4516 rel.Type = objabi.R_ARM64_GOTPCREL 4517 4518 case 72: 4519 af := int((p.From.Reg >> 5) & 15) 4520 af3 := int((p.Reg >> 5) & 15) 4521 at := int((p.To.Reg >> 5) & 15) 4522 if af != af3 || af != at { 4523 c.ctxt.Diag("operand mismatch: %v", p) 4524 break 4525 } 4526 o1 = c.oprrr(p, p.As) 4527 rf := int((p.From.Reg) & 31) 4528 rt := int((p.To.Reg) & 31) 4529 r := int((p.Reg) & 31) 4530 4531 Q := 0 4532 size := 0 4533 switch af { 4534 case ARNG_16B: 4535 Q = 1 4536 size = 0 4537 case ARNG_2D: 4538 Q = 1 4539 size = 3 4540 case ARNG_2S: 4541 Q = 0 4542 size = 2 4543 case ARNG_4H: 4544 Q = 0 4545 size = 1 4546 case ARNG_4S: 4547 Q = 1 4548 size = 2 4549 case ARNG_8B: 4550 Q = 0 4551 size = 0 4552 case ARNG_8H: 4553 Q = 1 4554 size = 1 4555 default: 4556 c.ctxt.Diag("invalid arrangement: %v", p) 4557 } 4558 4559 switch p.As { 4560 case AVORR, AVAND, AVEOR, AVBIT, AVBSL, AVBIF: 4561 if af != ARNG_16B && af != ARNG_8B { 4562 c.ctxt.Diag("invalid arrangement: %v", p) 4563 } 4564 case AVFMLA, AVFMLS: 4565 if af != ARNG_2D && af != ARNG_2S && af != ARNG_4S { 4566 c.ctxt.Diag("invalid arrangement: %v", p) 4567 } 4568 case AVUMAX, AVUMIN: 4569 if af == ARNG_2D { 4570 c.ctxt.Diag("invalid arrangement: %v", p) 4571 } 4572 } 4573 switch p.As { 4574 case AVAND, AVEOR: 4575 size = 0 4576 case AVBSL: 4577 size = 1 4578 case AVORR, AVBIT, AVBIF: 4579 size = 2 4580 case AVFMLA, AVFMLS: 4581 if af == ARNG_2D { 4582 size = 1 4583 } else { 4584 size = 0 4585 } 4586 case AVRAX1: 4587 if af != ARNG_2D { 4588 c.ctxt.Diag("invalid arrangement: %v", p) 4589 } 4590 size = 0 4591 Q = 0 4592 } 4593 4594 o1 |= (uint32(Q&1) << 30) | (uint32(size&3) << 22) | (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31) 4595 4596 case 73: 4597 rf := int(p.From.Reg) 4598 rt := int(p.To.Reg) 4599 imm5 := 0 4600 o1 = 7<<25 | 0xf<<10 4601 index := int(p.From.Index) 4602 switch (p.From.Reg >> 5) & 15 { 4603 case ARNG_B: 4604 c.checkindex(p, index, 15) 4605 imm5 |= 1 4606 imm5 |= index << 1 4607 case ARNG_H: 4608 c.checkindex(p, index, 7) 4609 imm5 |= 2 4610 imm5 |= index << 2 4611 case ARNG_S: 4612 c.checkindex(p, index, 3) 4613 imm5 |= 4 4614 imm5 |= index << 3 4615 case ARNG_D: 4616 c.checkindex(p, index, 1) 4617 imm5 |= 8 4618 imm5 |= index << 4 4619 o1 |= 1 << 30 4620 default: 4621 c.ctxt.Diag("invalid arrangement: %v", p) 4622 } 4623 o1 |= (uint32(imm5&0x1f) << 16) | (uint32(rf&31) << 5) | uint32(rt&31) 4624 4625 case 74: 4626 4627 4628 rf, rt1, rt2 := p.From.Reg, p.To.Reg, int16(p.To.Offset) 4629 if rf == obj.REG_NONE { 4630 rf = o.param 4631 } 4632 if rf == obj.REG_NONE { 4633 c.ctxt.Diag("invalid ldp source: %v", p) 4634 } 4635 v := c.regoff(&p.From) 4636 o1 = c.oaddi12(p, v, REGTMP, rf) 4637 o2 = c.opldpstp(p, o, 0, REGTMP, rt1, rt2, 1) 4638 4639 case 75: 4640 4641 4642 4643 rf, rt1, rt2 := int(p.From.Reg), p.To.Reg, int16(p.To.Offset) 4644 if rf == REGTMP { 4645 c.ctxt.Diag("REGTMP used in large offset load: %v", p) 4646 } 4647 if rf == obj.REG_NONE { 4648 rf = int(o.param) 4649 } 4650 if rf == obj.REG_NONE { 4651 c.ctxt.Diag("invalid ldp source: %v", p) 4652 } 4653 o1 = c.omovlit(AMOVD, p, &p.From, REGTMP) 4654 o2 = c.opxrrr(p, AADD, false) 4655 o2 |= (REGTMP & 31) << 16 4656 o2 |= uint32(rf&31) << 5 4657 o2 |= uint32(REGTMP & 31) 4658 o3 = c.opldpstp(p, o, 0, REGTMP, rt1, rt2, 1) 4659 4660 case 76: 4661 4662 4663 rt, rf1, rf2 := p.To.Reg, p.From.Reg, int16(p.From.Offset) 4664 if rf1 == REGTMP || rf2 == REGTMP { 4665 c.ctxt.Diag("cannot use REGTMP as source: %v", p) 4666 } 4667 if rt == obj.REG_NONE { 4668 rt = o.param 4669 } 4670 if rt == obj.REG_NONE { 4671 c.ctxt.Diag("invalid stp destination: %v", p) 4672 } 4673 v := c.regoff(&p.To) 4674 o1 = c.oaddi12(p, v, REGTMP, rt) 4675 o2 = c.opldpstp(p, o, 0, REGTMP, rf1, rf2, 0) 4676 4677 case 77: 4678 4679 4680 4681 rt, rf1, rf2 := int(p.To.Reg), p.From.Reg, int16(p.From.Offset) 4682 if rt == REGTMP || rf1 == REGTMP || rf2 == REGTMP { 4683 c.ctxt.Diag("REGTMP used in large offset store: %v", p) 4684 } 4685 if rt == obj.REG_NONE { 4686 rt = int(o.param) 4687 } 4688 if rt == obj.REG_NONE { 4689 c.ctxt.Diag("invalid stp destination: %v", p) 4690 } 4691 o1 = c.omovlit(AMOVD, p, &p.To, REGTMP) 4692 o2 = c.opxrrr(p, AADD, false) 4693 o2 |= REGTMP & 31 << 16 4694 o2 |= uint32(rt&31) << 5 4695 o2 |= uint32(REGTMP & 31) 4696 o3 = c.opldpstp(p, o, 0, REGTMP, rf1, rf2, 0) 4697 4698 case 78: 4699 rf := int(p.From.Reg) 4700 rt := int(p.To.Reg) 4701 imm5 := 0 4702 o1 = 1<<30 | 7<<25 | 7<<10 4703 index := int(p.To.Index) 4704 switch (p.To.Reg >> 5) & 15 { 4705 case ARNG_B: 4706 c.checkindex(p, index, 15) 4707 imm5 |= 1 4708 imm5 |= index << 1 4709 case ARNG_H: 4710 c.checkindex(p, index, 7) 4711 imm5 |= 2 4712 imm5 |= index << 2 4713 case ARNG_S: 4714 c.checkindex(p, index, 3) 4715 imm5 |= 4 4716 imm5 |= index << 3 4717 case ARNG_D: 4718 c.checkindex(p, index, 1) 4719 imm5 |= 8 4720 imm5 |= index << 4 4721 default: 4722 c.ctxt.Diag("invalid arrangement: %v", p) 4723 } 4724 o1 |= (uint32(imm5&0x1f) << 16) | (uint32(rf&31) << 5) | uint32(rt&31) 4725 4726 case 79: 4727 rf := int(p.From.Reg) 4728 rt := int(p.To.Reg) 4729 o1 = 7<<25 | 1<<10 4730 var imm5, Q int 4731 index := int(p.From.Index) 4732 switch (p.To.Reg >> 5) & 15 { 4733 case ARNG_16B: 4734 c.checkindex(p, index, 15) 4735 Q = 1 4736 imm5 = 1 4737 imm5 |= index << 1 4738 case ARNG_2D: 4739 c.checkindex(p, index, 1) 4740 Q = 1 4741 imm5 = 8 4742 imm5 |= index << 4 4743 case ARNG_2S: 4744 c.checkindex(p, index, 3) 4745 Q = 0 4746 imm5 = 4 4747 imm5 |= index << 3 4748 case ARNG_4H: 4749 c.checkindex(p, index, 7) 4750 Q = 0 4751 imm5 = 2 4752 imm5 |= index << 2 4753 case ARNG_4S: 4754 c.checkindex(p, index, 3) 4755 Q = 1 4756 imm5 = 4 4757 imm5 |= index << 3 4758 case ARNG_8B: 4759 c.checkindex(p, index, 15) 4760 Q = 0 4761 imm5 = 1 4762 imm5 |= index << 1 4763 case ARNG_8H: 4764 c.checkindex(p, index, 7) 4765 Q = 1 4766 imm5 = 2 4767 imm5 |= index << 2 4768 default: 4769 c.ctxt.Diag("invalid arrangement: %v", p) 4770 } 4771 o1 |= (uint32(Q&1) << 30) | (uint32(imm5&0x1f) << 16) 4772 o1 |= (uint32(rf&31) << 5) | uint32(rt&31) 4773 4774 case 80: 4775 rf := int(p.From.Reg) 4776 rt := int(p.To.Reg) 4777 imm5 := 0 4778 index := int(p.From.Index) 4779 switch p.As { 4780 case AVMOV, AVDUP: 4781 o1 = 1<<30 | 15<<25 | 1<<10 4782 switch (p.From.Reg >> 5) & 15 { 4783 case ARNG_B: 4784 c.checkindex(p, index, 15) 4785 imm5 |= 1 4786 imm5 |= index << 1 4787 case ARNG_H: 4788 c.checkindex(p, index, 7) 4789 imm5 |= 2 4790 imm5 |= index << 2 4791 case ARNG_S: 4792 c.checkindex(p, index, 3) 4793 imm5 |= 4 4794 imm5 |= index << 3 4795 case ARNG_D: 4796 c.checkindex(p, index, 1) 4797 imm5 |= 8 4798 imm5 |= index << 4 4799 default: 4800 c.ctxt.Diag("invalid arrangement: %v", p) 4801 } 4802 default: 4803 c.ctxt.Diag("unsupported op %v", p.As) 4804 } 4805 o1 |= (uint32(imm5&0x1f) << 16) | (uint32(rf&31) << 5) | uint32(rt&31) 4806 4807 case 81: 4808 c.checkoffset(p, p.As) 4809 r := int(p.From.Reg) 4810 o1 = c.oprrr(p, p.As) 4811 if o.scond == C_XPOST { 4812 o1 |= 1 << 23 4813 if p.From.Index == 0 { 4814 4815 o1 |= 0x1f << 16 4816 } else { 4817 4818 if isRegShiftOrExt(&p.From) { 4819 c.ctxt.Diag("invalid extended register op: %v\n", p) 4820 } 4821 o1 |= uint32(p.From.Index&0x1f) << 16 4822 } 4823 } 4824 o1 |= uint32(p.To.Offset) 4825 4826 4827 o1 = c.maskOpvldvst(p, o1) 4828 o1 |= uint32(r&31) << 5 4829 4830 case 82: 4831 rf := int(p.From.Reg) 4832 rt := int(p.To.Reg) 4833 o1 = 7<<25 | 3<<10 4834 var imm5, Q uint32 4835 switch (p.To.Reg >> 5) & 15 { 4836 case ARNG_16B: 4837 Q = 1 4838 imm5 = 1 4839 case ARNG_2D: 4840 Q = 1 4841 imm5 = 8 4842 case ARNG_2S: 4843 Q = 0 4844 imm5 = 4 4845 case ARNG_4H: 4846 Q = 0 4847 imm5 = 2 4848 case ARNG_4S: 4849 Q = 1 4850 imm5 = 4 4851 case ARNG_8B: 4852 Q = 0 4853 imm5 = 1 4854 case ARNG_8H: 4855 Q = 1 4856 imm5 = 2 4857 default: 4858 c.ctxt.Diag("invalid arrangement: %v\n", p) 4859 } 4860 o1 |= (Q & 1 << 30) | (imm5 & 0x1f << 16) 4861 o1 |= (uint32(rf&31) << 5) | uint32(rt&31) 4862 4863 case 83: 4864 af := int((p.From.Reg >> 5) & 15) 4865 at := int((p.To.Reg >> 5) & 15) 4866 if af != at { 4867 c.ctxt.Diag("invalid arrangement: %v\n", p) 4868 } 4869 o1 = c.oprrr(p, p.As) 4870 rf := int((p.From.Reg) & 31) 4871 rt := int((p.To.Reg) & 31) 4872 4873 var Q, size uint32 4874 switch af { 4875 case ARNG_8B: 4876 Q = 0 4877 size = 0 4878 case ARNG_16B: 4879 Q = 1 4880 size = 0 4881 case ARNG_4H: 4882 Q = 0 4883 size = 1 4884 case ARNG_8H: 4885 Q = 1 4886 size = 1 4887 case ARNG_2S: 4888 Q = 0 4889 size = 2 4890 case ARNG_4S: 4891 Q = 1 4892 size = 2 4893 default: 4894 c.ctxt.Diag("invalid arrangement: %v\n", p) 4895 } 4896 4897 if (p.As == AVMOV || p.As == AVRBIT || p.As == AVCNT) && (af != ARNG_16B && af != ARNG_8B) { 4898 c.ctxt.Diag("invalid arrangement: %v", p) 4899 } 4900 4901 if p.As == AVREV32 && (af == ARNG_2S || af == ARNG_4S) { 4902 c.ctxt.Diag("invalid arrangement: %v", p) 4903 } 4904 4905 if p.As == AVREV16 && af != ARNG_8B && af != ARNG_16B { 4906 c.ctxt.Diag("invalid arrangement: %v", p) 4907 } 4908 4909 if p.As == AVMOV { 4910 o1 |= uint32(rf&31) << 16 4911 } 4912 4913 if p.As == AVRBIT { 4914 size = 1 4915 } 4916 4917 o1 |= (Q&1)<<30 | (size&3)<<22 | uint32(rf&31)<<5 | uint32(rt&31) 4918 4919 case 84: 4920 c.checkoffset(p, p.As) 4921 r := int(p.To.Reg) 4922 o1 = 3 << 26 4923 if o.scond == C_XPOST { 4924 o1 |= 1 << 23 4925 if p.To.Index == 0 { 4926 4927 o1 |= 0x1f << 16 4928 } else { 4929 4930 if isRegShiftOrExt(&p.To) { 4931 c.ctxt.Diag("invalid extended register: %v\n", p) 4932 } 4933 o1 |= uint32(p.To.Index&31) << 16 4934 } 4935 } 4936 o1 |= uint32(p.From.Offset) 4937 4938 4939 o1 = c.maskOpvldvst(p, o1) 4940 o1 |= uint32(r&31) << 5 4941 4942 case 85: 4943 af := int((p.From.Reg >> 5) & 15) 4944 o1 = c.oprrr(p, p.As) 4945 rf := int((p.From.Reg) & 31) 4946 rt := int((p.To.Reg) & 31) 4947 Q := 0 4948 size := 0 4949 switch af { 4950 case ARNG_8B: 4951 Q = 0 4952 size = 0 4953 case ARNG_16B: 4954 Q = 1 4955 size = 0 4956 case ARNG_4H: 4957 Q = 0 4958 size = 1 4959 case ARNG_8H: 4960 Q = 1 4961 size = 1 4962 case ARNG_4S: 4963 Q = 1 4964 size = 2 4965 default: 4966 c.ctxt.Diag("invalid arrangement: %v\n", p) 4967 } 4968 o1 |= (uint32(Q&1) << 30) | (uint32(size&3) << 22) | (uint32(rf&31) << 5) | uint32(rt&31) 4969 4970 case 86: 4971 at := int((p.To.Reg >> 5) & 15) 4972 r := int(p.From.Offset) 4973 if r > 255 || r < 0 { 4974 c.ctxt.Diag("immediate constant out of range: %v\n", p) 4975 } 4976 rt := int((p.To.Reg) & 31) 4977 Q := 0 4978 switch at { 4979 case ARNG_8B: 4980 Q = 0 4981 case ARNG_16B: 4982 Q = 1 4983 default: 4984 c.ctxt.Diag("invalid arrangement: %v\n", p) 4985 } 4986 o1 = 0xf<<24 | 0xe<<12 | 1<<10 4987 o1 |= (uint32(Q&1) << 30) | (uint32((r>>5)&7) << 16) | (uint32(r&0x1f) << 5) | uint32(rt&31) 4988 4989 case 87: 4990 rf1, rf2 := p.From.Reg, int16(p.From.Offset) 4991 if rf1 == REGTMP || rf2 == REGTMP { 4992 c.ctxt.Diag("cannot use REGTMP as source: %v", p) 4993 } 4994 o1 = ADR(1, 0, REGTMP) 4995 o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31 4996 rel := obj.Addrel(c.cursym) 4997 rel.Off = int32(c.pc) 4998 rel.Siz = 8 4999 rel.Sym = p.To.Sym 5000 rel.Add = p.To.Offset 5001 rel.Type = objabi.R_ADDRARM64 5002 o3 = c.opldpstp(p, o, 0, REGTMP, rf1, rf2, 0) 5003 5004 case 88: 5005 rt1, rt2 := p.To.Reg, int16(p.To.Offset) 5006 o1 = ADR(1, 0, REGTMP) 5007 o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31 5008 rel := obj.Addrel(c.cursym) 5009 rel.Off = int32(c.pc) 5010 rel.Siz = 8 5011 rel.Sym = p.From.Sym 5012 rel.Add = p.From.Offset 5013 rel.Type = objabi.R_ADDRARM64 5014 o3 = c.opldpstp(p, o, 0, REGTMP, rt1, rt2, 1) 5015 5016 case 89: 5017 switch p.As { 5018 case AVADD: 5019 o1 = 5<<28 | 7<<25 | 7<<21 | 1<<15 | 1<<10 5020 5021 case AVSUB: 5022 o1 = 7<<28 | 7<<25 | 7<<21 | 1<<15 | 1<<10 5023 5024 default: 5025 c.ctxt.Diag("bad opcode: %v\n", p) 5026 break 5027 } 5028 5029 rf := int(p.From.Reg) 5030 rt := int(p.To.Reg) 5031 r := int(p.Reg) 5032 if r == obj.REG_NONE { 5033 r = rt 5034 } 5035 o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31) 5036 5037 5038 5039 5040 5041 5042 case 90: 5043 o1 = 0xbea71700 5044 5045 case 91: 5046 imm := uint32(p.From.Offset) 5047 r := p.From.Reg 5048 var v uint32 5049 var ok bool 5050 if p.To.Type == obj.TYPE_CONST { 5051 v = uint32(p.To.Offset) 5052 ok = v <= 31 5053 } else { 5054 v, ok = prfopfield[SpecialOperand(p.To.Offset)] 5055 } 5056 if !ok { 5057 c.ctxt.Diag("illegal prefetch operation:\n%v", p) 5058 } 5059 5060 o1 = c.opirr(p, p.As) 5061 o1 |= (uint32(r&31) << 5) | (uint32((imm>>3)&0xfff) << 10) | (uint32(v & 31)) 5062 5063 case 92: 5064 rf := int(p.From.Reg) 5065 rt := int(p.To.Reg) 5066 imm4 := 0 5067 imm5 := 0 5068 o1 = 3<<29 | 7<<25 | 1<<10 5069 index1 := int(p.To.Index) 5070 index2 := int(p.From.Index) 5071 if ((p.To.Reg >> 5) & 15) != ((p.From.Reg >> 5) & 15) { 5072 c.ctxt.Diag("operand mismatch: %v", p) 5073 } 5074 switch (p.To.Reg >> 5) & 15 { 5075 case ARNG_B: 5076 c.checkindex(p, index1, 15) 5077 c.checkindex(p, index2, 15) 5078 imm5 |= 1 5079 imm5 |= index1 << 1 5080 imm4 |= index2 5081 case ARNG_H: 5082 c.checkindex(p, index1, 7) 5083 c.checkindex(p, index2, 7) 5084 imm5 |= 2 5085 imm5 |= index1 << 2 5086 imm4 |= index2 << 1 5087 case ARNG_S: 5088 c.checkindex(p, index1, 3) 5089 c.checkindex(p, index2, 3) 5090 imm5 |= 4 5091 imm5 |= index1 << 3 5092 imm4 |= index2 << 2 5093 case ARNG_D: 5094 c.checkindex(p, index1, 1) 5095 c.checkindex(p, index2, 1) 5096 imm5 |= 8 5097 imm5 |= index1 << 4 5098 imm4 |= index2 << 3 5099 default: 5100 c.ctxt.Diag("invalid arrangement: %v", p) 5101 } 5102 o1 |= (uint32(imm5&0x1f) << 16) | (uint32(imm4&0xf) << 11) | (uint32(rf&31) << 5) | uint32(rt&31) 5103 5104 case 93: 5105 af := uint8((p.From.Reg >> 5) & 15) 5106 at := uint8((p.To.Reg >> 5) & 15) 5107 a := uint8((p.Reg >> 5) & 15) 5108 if af != a { 5109 c.ctxt.Diag("invalid arrangement: %v", p) 5110 } 5111 5112 var Q, size uint32 5113 if p.As == AVPMULL2 { 5114 Q = 1 5115 } 5116 switch pack(Q, at, af) { 5117 case pack(0, ARNG_8H, ARNG_8B), pack(1, ARNG_8H, ARNG_16B): 5118 size = 0 5119 case pack(0, ARNG_1Q, ARNG_1D), pack(1, ARNG_1Q, ARNG_2D): 5120 size = 3 5121 default: 5122 c.ctxt.Diag("operand mismatch: %v\n", p) 5123 } 5124 5125 o1 = c.oprrr(p, p.As) 5126 rf := int((p.From.Reg) & 31) 5127 rt := int((p.To.Reg) & 31) 5128 r := int((p.Reg) & 31) 5129 o1 |= ((Q & 1) << 30) | ((size & 3) << 22) | (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31) 5130 5131 case 94: 5132 af := int(((p.GetFrom3().Reg) >> 5) & 15) 5133 at := int((p.To.Reg >> 5) & 15) 5134 a := int((p.Reg >> 5) & 15) 5135 index := int(p.From.Offset) 5136 5137 if af != a || af != at { 5138 c.ctxt.Diag("invalid arrangement: %v", p) 5139 break 5140 } 5141 5142 var Q uint32 5143 var b int 5144 if af == ARNG_8B { 5145 Q = 0 5146 b = 7 5147 } else if af == ARNG_16B { 5148 Q = 1 5149 b = 15 5150 } else { 5151 c.ctxt.Diag("invalid arrangement, should be B8 or B16: %v", p) 5152 break 5153 } 5154 5155 if index < 0 || index > b { 5156 c.ctxt.Diag("illegal offset: %v", p) 5157 } 5158 5159 o1 = c.opirr(p, p.As) 5160 rf := int((p.GetFrom3().Reg) & 31) 5161 rt := int((p.To.Reg) & 31) 5162 r := int((p.Reg) & 31) 5163 5164 o1 |= ((Q & 1) << 30) | (uint32(r&31) << 16) | (uint32(index&15) << 11) | (uint32(rf&31) << 5) | uint32(rt&31) 5165 5166 case 95: 5167 at := int((p.To.Reg >> 5) & 15) 5168 af := int((p.Reg >> 5) & 15) 5169 shift := int(p.From.Offset) 5170 5171 if af != at { 5172 c.ctxt.Diag("invalid arrangement on op Vn.<T>, Vd.<T>: %v", p) 5173 } 5174 5175 var Q uint32 5176 var imax, esize int 5177 5178 switch af { 5179 case ARNG_8B, ARNG_4H, ARNG_2S: 5180 Q = 0 5181 case ARNG_16B, ARNG_8H, ARNG_4S, ARNG_2D: 5182 Q = 1 5183 default: 5184 c.ctxt.Diag("invalid arrangement on op Vn.<T>, Vd.<T>: %v", p) 5185 } 5186 5187 switch af { 5188 case ARNG_8B, ARNG_16B: 5189 imax = 15 5190 esize = 8 5191 case ARNG_4H, ARNG_8H: 5192 imax = 31 5193 esize = 16 5194 case ARNG_2S, ARNG_4S: 5195 imax = 63 5196 esize = 32 5197 case ARNG_2D: 5198 imax = 127 5199 esize = 64 5200 } 5201 5202 imm := 0 5203 switch p.As { 5204 case AVUSHR, AVSRI, AVUSRA: 5205 imm = esize*2 - shift 5206 if imm < esize || imm > imax { 5207 c.ctxt.Diag("shift out of range: %v", p) 5208 } 5209 case AVSHL, AVSLI: 5210 imm = esize + shift 5211 if imm > imax { 5212 c.ctxt.Diag("shift out of range: %v", p) 5213 } 5214 default: 5215 c.ctxt.Diag("invalid instruction %v\n", p) 5216 } 5217 5218 o1 = c.opirr(p, p.As) 5219 rt := int((p.To.Reg) & 31) 5220 rf := int((p.Reg) & 31) 5221 5222 o1 |= ((Q & 1) << 30) | (uint32(imm&0x7f) << 16) | (uint32(rf&31) << 5) | uint32(rt&31) 5223 5224 case 96: 5225 af := int((p.From.Reg >> 5) & 15) 5226 rt := int((p.From.Reg) & 31) 5227 rf := int((p.To.Reg) & 31) 5228 r := int(p.To.Index & 31) 5229 index := int(p.From.Index) 5230 offset := c.regoff(&p.To) 5231 5232 if o.scond == C_XPOST { 5233 if (p.To.Index != 0) && (offset != 0) { 5234 c.ctxt.Diag("invalid offset: %v", p) 5235 } 5236 if p.To.Index == 0 && offset == 0 { 5237 c.ctxt.Diag("invalid offset: %v", p) 5238 } 5239 } 5240 5241 if offset != 0 { 5242 r = 31 5243 } 5244 5245 var Q, S, size int 5246 var opcode uint32 5247 switch af { 5248 case ARNG_B: 5249 c.checkindex(p, index, 15) 5250 if o.scond == C_XPOST && offset != 0 && offset != 1 { 5251 c.ctxt.Diag("invalid offset: %v", p) 5252 } 5253 Q = index >> 3 5254 S = (index >> 2) & 1 5255 size = index & 3 5256 opcode = 0 5257 case ARNG_H: 5258 c.checkindex(p, index, 7) 5259 if o.scond == C_XPOST && offset != 0 && offset != 2 { 5260 c.ctxt.Diag("invalid offset: %v", p) 5261 } 5262 Q = index >> 2 5263 S = (index >> 1) & 1 5264 size = (index & 1) << 1 5265 opcode = 2 5266 case ARNG_S: 5267 c.checkindex(p, index, 3) 5268 if o.scond == C_XPOST && offset != 0 && offset != 4 { 5269 c.ctxt.Diag("invalid offset: %v", p) 5270 } 5271 Q = index >> 1 5272 S = index & 1 5273 size = 0 5274 opcode = 4 5275 case ARNG_D: 5276 c.checkindex(p, index, 1) 5277 if o.scond == C_XPOST && offset != 0 && offset != 8 { 5278 c.ctxt.Diag("invalid offset: %v", p) 5279 } 5280 Q = index 5281 S = 0 5282 size = 1 5283 opcode = 4 5284 default: 5285 c.ctxt.Diag("invalid arrangement: %v", p) 5286 } 5287 5288 if o.scond == C_XPOST { 5289 o1 |= 27 << 23 5290 } else { 5291 o1 |= 26 << 23 5292 } 5293 5294 o1 |= (uint32(Q&1) << 30) | (uint32(r&31) << 16) | ((opcode & 7) << 13) | (uint32(S&1) << 12) | (uint32(size&3) << 10) | (uint32(rf&31) << 5) | uint32(rt&31) 5295 5296 case 97: 5297 at := int((p.To.Reg >> 5) & 15) 5298 rt := int((p.To.Reg) & 31) 5299 rf := int((p.From.Reg) & 31) 5300 r := int(p.From.Index & 31) 5301 index := int(p.To.Index) 5302 offset := c.regoff(&p.From) 5303 5304 if o.scond == C_XPOST { 5305 if (p.From.Index != 0) && (offset != 0) { 5306 c.ctxt.Diag("invalid offset: %v", p) 5307 } 5308 if p.From.Index == 0 && offset == 0 { 5309 c.ctxt.Diag("invalid offset: %v", p) 5310 } 5311 } 5312 5313 if offset != 0 { 5314 r = 31 5315 } 5316 5317 Q := 0 5318 S := 0 5319 size := 0 5320 var opcode uint32 5321 switch at { 5322 case ARNG_B: 5323 c.checkindex(p, index, 15) 5324 if o.scond == C_XPOST && offset != 0 && offset != 1 { 5325 c.ctxt.Diag("invalid offset: %v", p) 5326 } 5327 Q = index >> 3 5328 S = (index >> 2) & 1 5329 size = index & 3 5330 opcode = 0 5331 case ARNG_H: 5332 c.checkindex(p, index, 7) 5333 if o.scond == C_XPOST && offset != 0 && offset != 2 { 5334 c.ctxt.Diag("invalid offset: %v", p) 5335 } 5336 Q = index >> 2 5337 S = (index >> 1) & 1 5338 size = (index & 1) << 1 5339 opcode = 2 5340 case ARNG_S: 5341 c.checkindex(p, index, 3) 5342 if o.scond == C_XPOST && offset != 0 && offset != 4 { 5343 c.ctxt.Diag("invalid offset: %v", p) 5344 } 5345 Q = index >> 1 5346 S = index & 1 5347 size = 0 5348 opcode = 4 5349 case ARNG_D: 5350 c.checkindex(p, index, 1) 5351 if o.scond == C_XPOST && offset != 0 && offset != 8 { 5352 c.ctxt.Diag("invalid offset: %v", p) 5353 } 5354 Q = index 5355 S = 0 5356 size = 1 5357 opcode = 4 5358 default: 5359 c.ctxt.Diag("invalid arrangement: %v", p) 5360 } 5361 5362 if o.scond == C_XPOST { 5363 o1 |= 110 << 21 5364 } else { 5365 o1 |= 106 << 21 5366 } 5367 5368 o1 |= (uint32(Q&1) << 30) | (uint32(r&31) << 16) | ((opcode & 7) << 13) | (uint32(S&1) << 12) | (uint32(size&3) << 10) | (uint32(rf&31) << 5) | uint32(rt&31) 5369 5370 case 98: 5371 if isRegShiftOrExt(&p.From) { 5372 5373 c.checkShiftAmount(p, &p.From) 5374 5375 o1 = c.opldrr(p, p.As, true) 5376 o1 |= c.encRegShiftOrExt(p, &p.From, p.From.Index) 5377 } else { 5378 5379 o1 = c.opldrr(p, p.As, false) 5380 o1 |= uint32(p.From.Index&31) << 16 5381 } 5382 o1 |= uint32(p.From.Reg&31) << 5 5383 rt := int(p.To.Reg) 5384 o1 |= uint32(rt & 31) 5385 5386 case 99: 5387 if isRegShiftOrExt(&p.To) { 5388 5389 c.checkShiftAmount(p, &p.To) 5390 5391 o1 = c.opstrr(p, p.As, true) 5392 o1 |= c.encRegShiftOrExt(p, &p.To, p.To.Index) 5393 } else { 5394 5395 o1 = c.opstrr(p, p.As, false) 5396 o1 |= uint32(p.To.Index&31) << 16 5397 } 5398 o1 |= uint32(p.To.Reg&31) << 5 5399 rf := int(p.From.Reg) 5400 o1 |= uint32(rf & 31) 5401 5402 case 100: 5403 af := int((p.From.Reg >> 5) & 15) 5404 at := int((p.To.Reg >> 5) & 15) 5405 if af != at { 5406 c.ctxt.Diag("invalid arrangement: %v\n", p) 5407 } 5408 var q, len uint32 5409 switch af { 5410 case ARNG_8B: 5411 q = 0 5412 case ARNG_16B: 5413 q = 1 5414 default: 5415 c.ctxt.Diag("invalid arrangement: %v", p) 5416 } 5417 rf := int(p.From.Reg) 5418 rt := int(p.To.Reg) 5419 offset := int(p.GetFrom3().Offset) 5420 opcode := (offset >> 12) & 15 5421 switch opcode { 5422 case 0x7: 5423 len = 0 5424 case 0xa: 5425 len = 1 5426 case 0x6: 5427 len = 2 5428 case 0x2: 5429 len = 3 5430 default: 5431 c.ctxt.Diag("invalid register numbers in ARM64 register list: %v", p) 5432 } 5433 var op uint32 5434 switch p.As { 5435 case AVTBL: 5436 op = 0 5437 case AVTBX: 5438 op = 1 5439 } 5440 o1 = q<<30 | 0xe<<24 | len<<13 | op<<12 5441 o1 |= (uint32(rf&31) << 16) | uint32(offset&31)<<5 | uint32(rt&31) 5442 5443 case 101: 5444 o1 = c.omovlit(p.As, p, &p.From, int(p.To.Reg)) 5445 5446 case 102: 5447 o1 = c.opirr(p, p.As) 5448 rf := p.Reg 5449 af := uint8((p.Reg >> 5) & 15) 5450 at := uint8((p.To.Reg >> 5) & 15) 5451 shift := int(p.From.Offset) 5452 if p.As == AVUXTL || p.As == AVUXTL2 { 5453 rf = p.From.Reg 5454 af = uint8((p.From.Reg >> 5) & 15) 5455 shift = 0 5456 } 5457 5458 Q := (o1 >> 30) & 1 5459 var immh, width uint8 5460 switch pack(Q, af, at) { 5461 case pack(0, ARNG_8B, ARNG_8H): 5462 immh, width = 1, 8 5463 case pack(1, ARNG_16B, ARNG_8H): 5464 immh, width = 1, 8 5465 case pack(0, ARNG_4H, ARNG_4S): 5466 immh, width = 2, 16 5467 case pack(1, ARNG_8H, ARNG_4S): 5468 immh, width = 2, 16 5469 case pack(0, ARNG_2S, ARNG_2D): 5470 immh, width = 4, 32 5471 case pack(1, ARNG_4S, ARNG_2D): 5472 immh, width = 4, 32 5473 default: 5474 c.ctxt.Diag("operand mismatch: %v\n", p) 5475 } 5476 if !(0 <= shift && shift <= int(width-1)) { 5477 c.ctxt.Diag("shift amount out of range: %v\n", p) 5478 } 5479 o1 |= uint32(immh)<<19 | uint32(shift)<<16 | uint32(rf&31)<<5 | uint32(p.To.Reg&31) 5480 5481 case 103: 5482 ta := (p.From.Reg >> 5) & 15 5483 tm := (p.Reg >> 5) & 15 5484 td := (p.To.Reg >> 5) & 15 5485 tn := ((p.GetFrom3().Reg) >> 5) & 15 5486 5487 if ta != tm || ta != tn || ta != td || ta != ARNG_16B { 5488 c.ctxt.Diag("invalid arrangement: %v", p) 5489 break 5490 } 5491 5492 o1 = c.oprrr(p, p.As) 5493 ra := int(p.From.Reg) 5494 rm := int(p.Reg) 5495 rn := int(p.GetFrom3().Reg) 5496 rd := int(p.To.Reg) 5497 o1 |= uint32(rm&31)<<16 | uint32(ra&31)<<10 | uint32(rn&31)<<5 | uint32(rd)&31 5498 5499 case 104: 5500 af := ((p.GetFrom3().Reg) >> 5) & 15 5501 at := (p.To.Reg >> 5) & 15 5502 a := (p.Reg >> 5) & 15 5503 index := int(p.From.Offset) 5504 5505 if af != a || af != at { 5506 c.ctxt.Diag("invalid arrangement: %v", p) 5507 break 5508 } 5509 5510 if af != ARNG_2D { 5511 c.ctxt.Diag("invalid arrangement, should be D2: %v", p) 5512 break 5513 } 5514 5515 if index < 0 || index > 63 { 5516 c.ctxt.Diag("illegal offset: %v", p) 5517 } 5518 5519 o1 = c.opirr(p, p.As) 5520 rf := (p.GetFrom3().Reg) & 31 5521 rt := (p.To.Reg) & 31 5522 r := (p.Reg) & 31 5523 5524 o1 |= (uint32(r&31) << 16) | (uint32(index&63) << 10) | (uint32(rf&31) << 5) | uint32(rt&31) 5525 5526 case 105: 5527 af := uint8((p.From.Reg >> 5) & 15) 5528 at := uint8((p.To.Reg >> 5) & 15) 5529 a := uint8((p.Reg >> 5) & 15) 5530 if at != a { 5531 c.ctxt.Diag("invalid arrangement: %v", p) 5532 break 5533 } 5534 5535 var Q, size uint32 5536 if p.As == AVUADDW2 { 5537 Q = 1 5538 } 5539 switch pack(Q, at, af) { 5540 case pack(0, ARNG_8H, ARNG_8B), pack(1, ARNG_8H, ARNG_16B): 5541 size = 0 5542 case pack(0, ARNG_4S, ARNG_4H), pack(1, ARNG_4S, ARNG_8H): 5543 size = 1 5544 case pack(0, ARNG_2D, ARNG_2S), pack(1, ARNG_2D, ARNG_4S): 5545 size = 2 5546 default: 5547 c.ctxt.Diag("operand mismatch: %v\n", p) 5548 } 5549 5550 o1 = c.oprrr(p, p.As) 5551 rf := int((p.From.Reg) & 31) 5552 rt := int((p.To.Reg) & 31) 5553 r := int((p.Reg) & 31) 5554 o1 |= ((Q & 1) << 30) | ((size & 3) << 22) | (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31) 5555 5556 case 106: 5557 rs := p.From.Reg 5558 rt := p.GetTo2().Reg 5559 rb := p.To.Reg 5560 rs1 := int16(p.From.Offset) 5561 rt1 := int16(p.GetTo2().Offset) 5562 5563 enc, ok := atomicCASP[p.As] 5564 if !ok { 5565 c.ctxt.Diag("invalid CASP-like atomic instructions: %v\n", p) 5566 } 5567 5568 switch { 5569 case rs&1 != 0: 5570 c.ctxt.Diag("source register pair must start from even register: %v\n", p) 5571 break 5572 case rt&1 != 0: 5573 c.ctxt.Diag("destination register pair must start from even register: %v\n", p) 5574 break 5575 case rs != rs1-1: 5576 c.ctxt.Diag("source register pair must be contiguous: %v\n", p) 5577 break 5578 case rt != rt1-1: 5579 c.ctxt.Diag("destination register pair must be contiguous: %v\n", p) 5580 break 5581 } 5582 5583 if rt == REG_RSP { 5584 c.ctxt.Diag("illegal destination register: %v\n", p) 5585 } 5586 o1 |= enc | uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31) 5587 5588 case 107: 5589 op, ok := sysInstFields[SpecialOperand(p.From.Offset)] 5590 if !ok || (p.As == ATLBI && op.cn != 8) || (p.As == ADC && op.cn != 7) { 5591 c.ctxt.Diag("illegal argument: %v\n", p) 5592 break 5593 } 5594 o1 = c.opirr(p, p.As) 5595 if op.hasOperand2 { 5596 if p.To.Reg == obj.REG_NONE { 5597 c.ctxt.Diag("missing register at operand 2: %v\n", p) 5598 } 5599 o1 |= uint32(p.To.Reg & 0x1F) 5600 } else { 5601 if p.To.Reg != obj.REG_NONE || p.Reg != obj.REG_NONE { 5602 c.ctxt.Diag("extraneous register at operand 2: %v\n", p) 5603 } 5604 o1 |= uint32(0x1F) 5605 } 5606 o1 |= uint32(SYSARG4(int(op.op1), int(op.cn), int(op.cm), int(op.op2))) 5607 } 5608 out[0] = o1 5609 out[1] = o2 5610 out[2] = o3 5611 out[3] = o4 5612 out[4] = o5 5613 } 5614 5615 func (c *ctxt7) addrRelocType(p *obj.Prog) objabi.RelocType { 5616 switch movesize(p.As) { 5617 case 0: 5618 return objabi.R_ARM64_PCREL_LDST8 5619 case 1: 5620 return objabi.R_ARM64_PCREL_LDST16 5621 case 2: 5622 return objabi.R_ARM64_PCREL_LDST32 5623 case 3: 5624 return objabi.R_ARM64_PCREL_LDST64 5625 default: 5626 c.ctxt.Diag("use R_ADDRARM64 relocation type for: %v\n", p) 5627 } 5628 return -1 5629 } 5630 5631 5632 func (c *ctxt7) oprrr(p *obj.Prog, a obj.As) uint32 { 5633 switch a { 5634 case AADC: 5635 return S64 | 0<<30 | 0<<29 | 0xd0<<21 | 0<<10 5636 5637 case AADCW: 5638 return S32 | 0<<30 | 0<<29 | 0xd0<<21 | 0<<10 5639 5640 case AADCS: 5641 return S64 | 0<<30 | 1<<29 | 0xd0<<21 | 0<<10 5642 5643 case AADCSW: 5644 return S32 | 0<<30 | 1<<29 | 0xd0<<21 | 0<<10 5645 5646 case ANGC, ASBC: 5647 return S64 | 1<<30 | 0<<29 | 0xd0<<21 | 0<<10 5648 5649 case ANGCS, ASBCS: 5650 return S64 | 1<<30 | 1<<29 | 0xd0<<21 | 0<<10 5651 5652 case ANGCW, ASBCW: 5653 return S32 | 1<<30 | 0<<29 | 0xd0<<21 | 0<<10 5654 5655 case ANGCSW, ASBCSW: 5656 return S32 | 1<<30 | 1<<29 | 0xd0<<21 | 0<<10 5657 5658 case AADD: 5659 return S64 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10 5660 5661 case AADDW: 5662 return S32 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10 5663 5664 case ACMN, AADDS: 5665 return S64 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10 5666 5667 case ACMNW, AADDSW: 5668 return S32 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10 5669 5670 case ASUB: 5671 return S64 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10 5672 5673 case ASUBW: 5674 return S32 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10 5675 5676 case ACMP, ASUBS: 5677 return S64 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10 5678 5679 case ACMPW, ASUBSW: 5680 return S32 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10 5681 5682 case AAND: 5683 return S64 | 0<<29 | 0xA<<24 5684 5685 case AANDW: 5686 return S32 | 0<<29 | 0xA<<24 5687 5688 case AMOVD, AORR: 5689 return S64 | 1<<29 | 0xA<<24 5690 5691 5692 case AMOVWU, AORRW: 5693 return S32 | 1<<29 | 0xA<<24 5694 5695 case AEOR: 5696 return S64 | 2<<29 | 0xA<<24 5697 5698 case AEORW: 5699 return S32 | 2<<29 | 0xA<<24 5700 5701 case AANDS, ATST: 5702 return S64 | 3<<29 | 0xA<<24 5703 5704 case AANDSW, ATSTW: 5705 return S32 | 3<<29 | 0xA<<24 5706 5707 case ABIC: 5708 return S64 | 0<<29 | 0xA<<24 | 1<<21 5709 5710 case ABICW: 5711 return S32 | 0<<29 | 0xA<<24 | 1<<21 5712 5713 case ABICS: 5714 return S64 | 3<<29 | 0xA<<24 | 1<<21 5715 5716 case ABICSW: 5717 return S32 | 3<<29 | 0xA<<24 | 1<<21 5718 5719 case AEON: 5720 return S64 | 2<<29 | 0xA<<24 | 1<<21 5721 5722 case AEONW: 5723 return S32 | 2<<29 | 0xA<<24 | 1<<21 5724 5725 case AMVN, AORN: 5726 return S64 | 1<<29 | 0xA<<24 | 1<<21 5727 5728 case AMVNW, AORNW: 5729 return S32 | 1<<29 | 0xA<<24 | 1<<21 5730 5731 case AASR: 5732 return S64 | OPDP2(10) 5733 5734 case AASRW: 5735 return S32 | OPDP2(10) 5736 5737 case ALSL: 5738 return S64 | OPDP2(8) 5739 5740 case ALSLW: 5741 return S32 | OPDP2(8) 5742 5743 case ALSR: 5744 return S64 | OPDP2(9) 5745 5746 case ALSRW: 5747 return S32 | OPDP2(9) 5748 5749 case AROR: 5750 return S64 | OPDP2(11) 5751 5752 case ARORW: 5753 return S32 | OPDP2(11) 5754 5755 case ACCMN: 5756 return S64 | 0<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4 5757 5758 case ACCMNW: 5759 return S32 | 0<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4 5760 5761 case ACCMP: 5762 return S64 | 1<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4 5763 5764 case ACCMPW: 5765 return S32 | 1<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4 5766 5767 case ACRC32B: 5768 return S32 | OPDP2(16) 5769 5770 case ACRC32H: 5771 return S32 | OPDP2(17) 5772 5773 case ACRC32W: 5774 return S32 | OPDP2(18) 5775 5776 case ACRC32X: 5777 return S64 | OPDP2(19) 5778 5779 case ACRC32CB: 5780 return S32 | OPDP2(20) 5781 5782 case ACRC32CH: 5783 return S32 | OPDP2(21) 5784 5785 case ACRC32CW: 5786 return S32 | OPDP2(22) 5787 5788 case ACRC32CX: 5789 return S64 | OPDP2(23) 5790 5791 case ACSEL: 5792 return S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10 5793 5794 case ACSELW: 5795 return S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10 5796 5797 case ACSET: 5798 return S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10 5799 5800 case ACSETW: 5801 return S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10 5802 5803 case ACSETM: 5804 return S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10 5805 5806 case ACSETMW: 5807 return S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10 5808 5809 case ACINC, ACSINC: 5810 return S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10 5811 5812 case ACINCW, ACSINCW: 5813 return S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10 5814 5815 case ACINV, ACSINV: 5816 return S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10 5817 5818 case ACINVW, ACSINVW: 5819 return S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10 5820 5821 case ACNEG, ACSNEG: 5822 return S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10 5823 5824 case ACNEGW, ACSNEGW: 5825 return S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10 5826 5827 case AMUL, AMADD: 5828 return S64 | 0<<29 | 0x1B<<24 | 0<<21 | 0<<15 5829 5830 case AMULW, AMADDW: 5831 return S32 | 0<<29 | 0x1B<<24 | 0<<21 | 0<<15 5832 5833 case AMNEG, AMSUB: 5834 return S64 | 0<<29 | 0x1B<<24 | 0<<21 | 1<<15 5835 5836 case AMNEGW, AMSUBW: 5837 return S32 | 0<<29 | 0x1B<<24 | 0<<21 | 1<<15 5838 5839 case AMRS: 5840 return SYSOP(1, 2, 0, 0, 0, 0, 0) 5841 5842 case AMSR: 5843 return SYSOP(0, 2, 0, 0, 0, 0, 0) 5844 5845 case ANEG: 5846 return S64 | 1<<30 | 0<<29 | 0xB<<24 | 0<<21 5847 5848 case ANEGW: 5849 return S32 | 1<<30 | 0<<29 | 0xB<<24 | 0<<21 5850 5851 case ANEGS: 5852 return S64 | 1<<30 | 1<<29 | 0xB<<24 | 0<<21 5853 5854 case ANEGSW: 5855 return S32 | 1<<30 | 1<<29 | 0xB<<24 | 0<<21 5856 5857 case AREM, ASDIV: 5858 return S64 | OPDP2(3) 5859 5860 case AREMW, ASDIVW: 5861 return S32 | OPDP2(3) 5862 5863 case ASMULL, ASMADDL: 5864 return OPDP3(1, 0, 1, 0) 5865 5866 case ASMNEGL, ASMSUBL: 5867 return OPDP3(1, 0, 1, 1) 5868 5869 case ASMULH: 5870 return OPDP3(1, 0, 2, 0) 5871 5872 case AUMULL, AUMADDL: 5873 return OPDP3(1, 0, 5, 0) 5874 5875 case AUMNEGL, AUMSUBL: 5876 return OPDP3(1, 0, 5, 1) 5877 5878 case AUMULH: 5879 return OPDP3(1, 0, 6, 0) 5880 5881 case AUREM, AUDIV: 5882 return S64 | OPDP2(2) 5883 5884 case AUREMW, AUDIVW: 5885 return S32 | OPDP2(2) 5886 5887 case AAESE: 5888 return 0x4E<<24 | 2<<20 | 8<<16 | 4<<12 | 2<<10 5889 5890 case AAESD: 5891 return 0x4E<<24 | 2<<20 | 8<<16 | 5<<12 | 2<<10 5892 5893 case AAESMC: 5894 return 0x4E<<24 | 2<<20 | 8<<16 | 6<<12 | 2<<10 5895 5896 case AAESIMC: 5897 return 0x4E<<24 | 2<<20 | 8<<16 | 7<<12 | 2<<10 5898 5899 case ASHA1C: 5900 return 0x5E<<24 | 0<<12 5901 5902 case ASHA1P: 5903 return 0x5E<<24 | 1<<12 5904 5905 case ASHA1M: 5906 return 0x5E<<24 | 2<<12 5907 5908 case ASHA1SU0: 5909 return 0x5E<<24 | 3<<12 5910 5911 case ASHA256H: 5912 return 0x5E<<24 | 4<<12 5913 5914 case ASHA256H2: 5915 return 0x5E<<24 | 5<<12 5916 5917 case ASHA256SU1: 5918 return 0x5E<<24 | 6<<12 5919 5920 case ASHA1H: 5921 return 0x5E<<24 | 2<<20 | 8<<16 | 0<<12 | 2<<10 5922 5923 case ASHA1SU1: 5924 return 0x5E<<24 | 2<<20 | 8<<16 | 1<<12 | 2<<10 5925 5926 case ASHA256SU0: 5927 return 0x5E<<24 | 2<<20 | 8<<16 | 2<<12 | 2<<10 5928 5929 case ASHA512H: 5930 return 0xCE<<24 | 3<<21 | 8<<12 5931 5932 case ASHA512H2: 5933 return 0xCE<<24 | 3<<21 | 8<<12 | 4<<8 5934 5935 case ASHA512SU1: 5936 return 0xCE<<24 | 3<<21 | 8<<12 | 8<<8 5937 5938 case ASHA512SU0: 5939 return 0xCE<<24 | 3<<22 | 8<<12 5940 5941 case AFCVTZSD: 5942 return FPCVTI(1, 0, 1, 3, 0) 5943 5944 case AFCVTZSDW: 5945 return FPCVTI(0, 0, 1, 3, 0) 5946 5947 case AFCVTZSS: 5948 return FPCVTI(1, 0, 0, 3, 0) 5949 5950 case AFCVTZSSW: 5951 return FPCVTI(0, 0, 0, 3, 0) 5952 5953 case AFCVTZUD: 5954 return FPCVTI(1, 0, 1, 3, 1) 5955 5956 case AFCVTZUDW: 5957 return FPCVTI(0, 0, 1, 3, 1) 5958 5959 case AFCVTZUS: 5960 return FPCVTI(1, 0, 0, 3, 1) 5961 5962 case AFCVTZUSW: 5963 return FPCVTI(0, 0, 0, 3, 1) 5964 5965 case ASCVTFD: 5966 return FPCVTI(1, 0, 1, 0, 2) 5967 5968 case ASCVTFS: 5969 return FPCVTI(1, 0, 0, 0, 2) 5970 5971 case ASCVTFWD: 5972 return FPCVTI(0, 0, 1, 0, 2) 5973 5974 case ASCVTFWS: 5975 return FPCVTI(0, 0, 0, 0, 2) 5976 5977 case AUCVTFD: 5978 return FPCVTI(1, 0, 1, 0, 3) 5979 5980 case AUCVTFS: 5981 return FPCVTI(1, 0, 0, 0, 3) 5982 5983 case AUCVTFWD: 5984 return FPCVTI(0, 0, 1, 0, 3) 5985 5986 case AUCVTFWS: 5987 return FPCVTI(0, 0, 0, 0, 3) 5988 5989 case AFADDS: 5990 return FPOP2S(0, 0, 0, 2) 5991 5992 case AFADDD: 5993 return FPOP2S(0, 0, 1, 2) 5994 5995 case AFSUBS: 5996 return FPOP2S(0, 0, 0, 3) 5997 5998 case AFSUBD: 5999 return FPOP2S(0, 0, 1, 3) 6000 6001 case AFMADDD: 6002 return FPOP3S(0, 0, 1, 0, 0) 6003 6004 case AFMADDS: 6005 return FPOP3S(0, 0, 0, 0, 0) 6006 6007 case AFMSUBD: 6008 return FPOP3S(0, 0, 1, 0, 1) 6009 6010 case AFMSUBS: 6011 return FPOP3S(0, 0, 0, 0, 1) 6012 6013 case AFNMADDD: 6014 return FPOP3S(0, 0, 1, 1, 0) 6015 6016 case AFNMADDS: 6017 return FPOP3S(0, 0, 0, 1, 0) 6018 6019 case AFNMSUBD: 6020 return FPOP3S(0, 0, 1, 1, 1) 6021 6022 case AFNMSUBS: 6023 return FPOP3S(0, 0, 0, 1, 1) 6024 6025 case AFMULS: 6026 return FPOP2S(0, 0, 0, 0) 6027 6028 case AFMULD: 6029 return FPOP2S(0, 0, 1, 0) 6030 6031 case AFDIVS: 6032 return FPOP2S(0, 0, 0, 1) 6033 6034 case AFDIVD: 6035 return FPOP2S(0, 0, 1, 1) 6036 6037 case AFMAXS: 6038 return FPOP2S(0, 0, 0, 4) 6039 6040 case AFMINS: 6041 return FPOP2S(0, 0, 0, 5) 6042 6043 case AFMAXD: 6044 return FPOP2S(0, 0, 1, 4) 6045 6046 case AFMIND: 6047 return FPOP2S(0, 0, 1, 5) 6048 6049 case AFMAXNMS: 6050 return FPOP2S(0, 0, 0, 6) 6051 6052 case AFMAXNMD: 6053 return FPOP2S(0, 0, 1, 6) 6054 6055 case AFMINNMS: 6056 return FPOP2S(0, 0, 0, 7) 6057 6058 case AFMINNMD: 6059 return FPOP2S(0, 0, 1, 7) 6060 6061 case AFNMULS: 6062 return FPOP2S(0, 0, 0, 8) 6063 6064 case AFNMULD: 6065 return FPOP2S(0, 0, 1, 8) 6066 6067 case AFCMPS: 6068 return FPCMP(0, 0, 0, 0, 0) 6069 6070 case AFCMPD: 6071 return FPCMP(0, 0, 1, 0, 0) 6072 6073 case AFCMPES: 6074 return FPCMP(0, 0, 0, 0, 16) 6075 6076 case AFCMPED: 6077 return FPCMP(0, 0, 1, 0, 16) 6078 6079 case AFCCMPS: 6080 return FPCCMP(0, 0, 0, 0) 6081 6082 case AFCCMPD: 6083 return FPCCMP(0, 0, 1, 0) 6084 6085 case AFCCMPES: 6086 return FPCCMP(0, 0, 0, 1) 6087 6088 case AFCCMPED: 6089 return FPCCMP(0, 0, 1, 1) 6090 6091 case AFCSELS: 6092 return 0x1E<<24 | 0<<22 | 1<<21 | 3<<10 6093 6094 case AFCSELD: 6095 return 0x1E<<24 | 1<<22 | 1<<21 | 3<<10 6096 6097 case AFMOVS: 6098 return FPOP1S(0, 0, 0, 0) 6099 6100 case AFABSS: 6101 return FPOP1S(0, 0, 0, 1) 6102 6103 case AFNEGS: 6104 return FPOP1S(0, 0, 0, 2) 6105 6106 case AFSQRTS: 6107 return FPOP1S(0, 0, 0, 3) 6108 6109 case AFCVTSD: 6110 return FPOP1S(0, 0, 0, 5) 6111 6112 case AFCVTSH: 6113 return FPOP1S(0, 0, 0, 7) 6114 6115 case AFRINTNS: 6116 return FPOP1S(0, 0, 0, 8) 6117 6118 case AFRINTPS: 6119 return FPOP1S(0, 0, 0, 9) 6120 6121 case AFRINTMS: 6122 return FPOP1S(0, 0, 0, 10) 6123 6124 case AFRINTZS: 6125 return FPOP1S(0, 0, 0, 11) 6126 6127 case AFRINTAS: 6128 return FPOP1S(0, 0, 0, 12) 6129 6130 case AFRINTXS: 6131 return FPOP1S(0, 0, 0, 14) 6132 6133 case AFRINTIS: 6134 return FPOP1S(0, 0, 0, 15) 6135 6136 case AFMOVD: 6137 return FPOP1S(0, 0, 1, 0) 6138 6139 case AFABSD: 6140 return FPOP1S(0, 0, 1, 1) 6141 6142 case AFNEGD: 6143 return FPOP1S(0, 0, 1, 2) 6144 6145 case AFSQRTD: 6146 return FPOP1S(0, 0, 1, 3) 6147 6148 case AFCVTDS: 6149 return FPOP1S(0, 0, 1, 4) 6150 6151 case AFCVTDH: 6152 return FPOP1S(0, 0, 1, 7) 6153 6154 case AFRINTND: 6155 return FPOP1S(0, 0, 1, 8) 6156 6157 case AFRINTPD: 6158 return FPOP1S(0, 0, 1, 9) 6159 6160 case AFRINTMD: 6161 return FPOP1S(0, 0, 1, 10) 6162 6163 case AFRINTZD: 6164 return FPOP1S(0, 0, 1, 11) 6165 6166 case AFRINTAD: 6167 return FPOP1S(0, 0, 1, 12) 6168 6169 case AFRINTXD: 6170 return FPOP1S(0, 0, 1, 14) 6171 6172 case AFRINTID: 6173 return FPOP1S(0, 0, 1, 15) 6174 6175 case AFCVTHS: 6176 return FPOP1S(0, 0, 3, 4) 6177 6178 case AFCVTHD: 6179 return FPOP1S(0, 0, 3, 5) 6180 6181 case AVADD: 6182 return 7<<25 | 1<<21 | 1<<15 | 1<<10 6183 6184 case AVSUB: 6185 return 0x17<<25 | 1<<21 | 1<<15 | 1<<10 6186 6187 case AVADDP: 6188 return 7<<25 | 1<<21 | 1<<15 | 15<<10 6189 6190 case AVAND: 6191 return 7<<25 | 1<<21 | 7<<10 6192 6193 case AVBCAX: 6194 return 0xCE<<24 | 1<<21 6195 6196 case AVCMEQ: 6197 return 1<<29 | 0x71<<21 | 0x23<<10 6198 6199 case AVCNT: 6200 return 0xE<<24 | 0x10<<17 | 5<<12 | 2<<10 6201 6202 case AVZIP1: 6203 return 0xE<<24 | 3<<12 | 2<<10 6204 6205 case AVZIP2: 6206 return 0xE<<24 | 1<<14 | 3<<12 | 2<<10 6207 6208 case AVEOR: 6209 return 1<<29 | 0x71<<21 | 7<<10 6210 6211 case AVEOR3: 6212 return 0xCE << 24 6213 6214 case AVORR: 6215 return 7<<25 | 5<<21 | 7<<10 6216 6217 case AVREV16: 6218 return 3<<26 | 2<<24 | 1<<21 | 3<<11 6219 6220 case AVRAX1: 6221 return 0xCE<<24 | 3<<21 | 1<<15 | 3<<10 6222 6223 case AVREV32: 6224 return 11<<26 | 2<<24 | 1<<21 | 1<<11 6225 6226 case AVREV64: 6227 return 3<<26 | 2<<24 | 1<<21 | 1<<11 6228 6229 case AVMOV: 6230 return 7<<25 | 5<<21 | 7<<10 6231 6232 case AVADDV: 6233 return 7<<25 | 3<<20 | 3<<15 | 7<<11 6234 6235 case AVUADDLV: 6236 return 1<<29 | 7<<25 | 3<<20 | 7<<11 6237 6238 case AVFMLA: 6239 return 7<<25 | 0<<23 | 1<<21 | 3<<14 | 3<<10 6240 6241 case AVFMLS: 6242 return 7<<25 | 1<<23 | 1<<21 | 3<<14 | 3<<10 6243 6244 case AVPMULL, AVPMULL2: 6245 return 0xE<<24 | 1<<21 | 0x38<<10 6246 6247 case AVRBIT: 6248 return 0x2E<<24 | 1<<22 | 0x10<<17 | 5<<12 | 2<<10 6249 6250 case AVLD1, AVLD2, AVLD3, AVLD4: 6251 return 3<<26 | 1<<22 6252 6253 case AVLD1R, AVLD3R: 6254 return 0xD<<24 | 1<<22 6255 6256 case AVLD2R, AVLD4R: 6257 return 0xD<<24 | 3<<21 6258 6259 case AVBIF: 6260 return 1<<29 | 7<<25 | 7<<21 | 7<<10 6261 6262 case AVBIT: 6263 return 1<<29 | 0x75<<21 | 7<<10 6264 6265 case AVBSL: 6266 return 1<<29 | 0x73<<21 | 7<<10 6267 6268 case AVCMTST: 6269 return 0xE<<24 | 1<<21 | 0x23<<10 6270 6271 case AVUMAX: 6272 return 1<<29 | 7<<25 | 1<<21 | 0x19<<10 6273 6274 case AVUMIN: 6275 return 1<<29 | 7<<25 | 1<<21 | 0x1b<<10 6276 6277 case AVUZP1: 6278 return 7<<25 | 3<<11 6279 6280 case AVUZP2: 6281 return 7<<25 | 1<<14 | 3<<11 6282 6283 case AVUADDW, AVUADDW2: 6284 return 0x17<<25 | 1<<21 | 1<<12 6285 6286 case AVTRN1: 6287 return 7<<25 | 5<<11 6288 6289 case AVTRN2: 6290 return 7<<25 | 1<<14 | 5<<11 6291 } 6292 6293 c.ctxt.Diag("%v: bad rrr %d %v", p, a, a) 6294 return 0 6295 } 6296 6297 6298 func (c *ctxt7) opirr(p *obj.Prog, a obj.As) uint32 { 6299 switch a { 6300 6301 case AMOVD, AADD: 6302 return S64 | 0<<30 | 0<<29 | 0x11<<24 6303 6304 case ACMN, AADDS: 6305 return S64 | 0<<30 | 1<<29 | 0x11<<24 6306 6307 case AMOVW, AADDW: 6308 return S32 | 0<<30 | 0<<29 | 0x11<<24 6309 6310 case ACMNW, AADDSW: 6311 return S32 | 0<<30 | 1<<29 | 0x11<<24 6312 6313 case ASUB: 6314 return S64 | 1<<30 | 0<<29 | 0x11<<24 6315 6316 case ACMP, ASUBS: 6317 return S64 | 1<<30 | 1<<29 | 0x11<<24 6318 6319 case ASUBW: 6320 return S32 | 1<<30 | 0<<29 | 0x11<<24 6321 6322 case ACMPW, ASUBSW: 6323 return S32 | 1<<30 | 1<<29 | 0x11<<24 6324 6325 6326 case AADR: 6327 return 0<<31 | 0x10<<24 6328 6329 case AADRP: 6330 return 1<<31 | 0x10<<24 6331 6332 6333 case AAND, ABIC: 6334 return S64 | 0<<29 | 0x24<<23 6335 6336 case AANDW, ABICW: 6337 return S32 | 0<<29 | 0x24<<23 | 0<<22 6338 6339 case AORR, AORN: 6340 return S64 | 1<<29 | 0x24<<23 6341 6342 case AORRW, AORNW: 6343 return S32 | 1<<29 | 0x24<<23 | 0<<22 6344 6345 case AEOR, AEON: 6346 return S64 | 2<<29 | 0x24<<23 6347 6348 case AEORW, AEONW: 6349 return S32 | 2<<29 | 0x24<<23 | 0<<22 6350 6351 case AANDS, ABICS, ATST: 6352 return S64 | 3<<29 | 0x24<<23 6353 6354 case AANDSW, ABICSW, ATSTW: 6355 return S32 | 3<<29 | 0x24<<23 | 0<<22 6356 6357 case AASR: 6358 return S64 | 0<<29 | 0x26<<23 6359 6360 case AASRW: 6361 return S32 | 0<<29 | 0x26<<23 | 0<<22 6362 6363 6364 case ABFI: 6365 return S64 | 2<<29 | 0x26<<23 | 1<<22 6366 6367 6368 case ABFIW: 6369 return S32 | 2<<29 | 0x26<<23 | 0<<22 6370 6371 6372 case ABFM: 6373 return S64 | 1<<29 | 0x26<<23 | 1<<22 6374 6375 case ABFMW: 6376 return S32 | 1<<29 | 0x26<<23 | 0<<22 6377 6378 case ASBFM: 6379 return S64 | 0<<29 | 0x26<<23 | 1<<22 6380 6381 case ASBFMW: 6382 return S32 | 0<<29 | 0x26<<23 | 0<<22 6383 6384 case AUBFM: 6385 return S64 | 2<<29 | 0x26<<23 | 1<<22 6386 6387 case AUBFMW: 6388 return S32 | 2<<29 | 0x26<<23 | 0<<22 6389 6390 case ABFXIL: 6391 return S64 | 1<<29 | 0x26<<23 | 1<<22 6392 6393 case ABFXILW: 6394 return S32 | 1<<29 | 0x26<<23 | 0<<22 6395 6396 case AEXTR: 6397 return S64 | 0<<29 | 0x27<<23 | 1<<22 | 0<<21 6398 6399 case AEXTRW: 6400 return S32 | 0<<29 | 0x27<<23 | 0<<22 | 0<<21 6401 6402 case ACBNZ: 6403 return S64 | 0x1A<<25 | 1<<24 6404 6405 case ACBNZW: 6406 return S32 | 0x1A<<25 | 1<<24 6407 6408 case ACBZ: 6409 return S64 | 0x1A<<25 | 0<<24 6410 6411 case ACBZW: 6412 return S32 | 0x1A<<25 | 0<<24 6413 6414 case ACCMN: 6415 return S64 | 0<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4 6416 6417 case ACCMNW: 6418 return S32 | 0<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4 6419 6420 case ACCMP: 6421 return S64 | 1<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4 6422 6423 case ACCMPW: 6424 return S32 | 1<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4 6425 6426 case AMOVK: 6427 return S64 | 3<<29 | 0x25<<23 6428 6429 case AMOVKW: 6430 return S32 | 3<<29 | 0x25<<23 6431 6432 case AMOVN: 6433 return S64 | 0<<29 | 0x25<<23 6434 6435 case AMOVNW: 6436 return S32 | 0<<29 | 0x25<<23 6437 6438 case AMOVZ: 6439 return S64 | 2<<29 | 0x25<<23 6440 6441 case AMOVZW: 6442 return S32 | 2<<29 | 0x25<<23 6443 6444 case AMSR: 6445 return SYSOP(0, 0, 0, 4, 0, 0, 0x1F) 6446 6447 case AAT, 6448 ADC, 6449 AIC, 6450 ATLBI, 6451 ASYS: 6452 return SYSOP(0, 1, 0, 0, 0, 0, 0) 6453 6454 case ASYSL: 6455 return SYSOP(1, 1, 0, 0, 0, 0, 0) 6456 6457 case ATBZ: 6458 return 0x36 << 24 6459 6460 case ATBNZ: 6461 return 0x37 << 24 6462 6463 case ADSB: 6464 return SYSOP(0, 0, 3, 3, 0, 4, 0x1F) 6465 6466 case ADMB: 6467 return SYSOP(0, 0, 3, 3, 0, 5, 0x1F) 6468 6469 case AISB: 6470 return SYSOP(0, 0, 3, 3, 0, 6, 0x1F) 6471 6472 case AHINT: 6473 return SYSOP(0, 0, 3, 2, 0, 0, 0x1F) 6474 6475 case AVEXT: 6476 return 0x2E<<24 | 0<<23 | 0<<21 | 0<<15 6477 6478 case AVUSHR: 6479 return 0x5E<<23 | 1<<10 6480 6481 case AVSHL: 6482 return 0x1E<<23 | 21<<10 6483 6484 case AVSRI: 6485 return 0x5E<<23 | 17<<10 6486 6487 case AVSLI: 6488 return 0x5E<<23 | 21<<10 6489 6490 case AVUSHLL, AVUXTL: 6491 return 1<<29 | 15<<24 | 0x29<<10 6492 6493 case AVUSHLL2, AVUXTL2: 6494 return 3<<29 | 15<<24 | 0x29<<10 6495 6496 case AVXAR: 6497 return 0xCE<<24 | 1<<23 6498 6499 case AVUSRA: 6500 return 1<<29 | 15<<24 | 5<<10 6501 6502 case APRFM: 6503 return 0xf9<<24 | 2<<22 6504 } 6505 6506 c.ctxt.Diag("%v: bad irr %v", p, a) 6507 return 0 6508 } 6509 6510 func (c *ctxt7) opbit(p *obj.Prog, a obj.As) uint32 { 6511 switch a { 6512 case ACLS: 6513 return S64 | OPBIT(5) 6514 6515 case ACLSW: 6516 return S32 | OPBIT(5) 6517 6518 case ACLZ: 6519 return S64 | OPBIT(4) 6520 6521 case ACLZW: 6522 return S32 | OPBIT(4) 6523 6524 case ARBIT: 6525 return S64 | OPBIT(0) 6526 6527 case ARBITW: 6528 return S32 | OPBIT(0) 6529 6530 case AREV: 6531 return S64 | OPBIT(3) 6532 6533 case AREVW: 6534 return S32 | OPBIT(2) 6535 6536 case AREV16: 6537 return S64 | OPBIT(1) 6538 6539 case AREV16W: 6540 return S32 | OPBIT(1) 6541 6542 case AREV32: 6543 return S64 | OPBIT(2) 6544 6545 default: 6546 c.ctxt.Diag("bad bit op\n%v", p) 6547 return 0 6548 } 6549 } 6550 6551 6552 func (c *ctxt7) opxrrr(p *obj.Prog, a obj.As, extend bool) uint32 { 6553 extension := uint32(0) 6554 if !extend { 6555 if isADDop(a) { 6556 extension = LSL0_64 6557 } 6558 if isADDWop(a) { 6559 extension = LSL0_32 6560 } 6561 } 6562 6563 switch a { 6564 case AADD: 6565 return S64 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension 6566 6567 case AADDW: 6568 return S32 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension 6569 6570 case ACMN, AADDS: 6571 return S64 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension 6572 6573 case ACMNW, AADDSW: 6574 return S32 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension 6575 6576 case ASUB: 6577 return S64 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension 6578 6579 case ASUBW: 6580 return S32 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension 6581 6582 case ACMP, ASUBS: 6583 return S64 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension 6584 6585 case ACMPW, ASUBSW: 6586 return S32 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension 6587 } 6588 6589 c.ctxt.Diag("bad opxrrr %v\n%v", a, p) 6590 return 0 6591 } 6592 6593 func (c *ctxt7) opimm(p *obj.Prog, a obj.As) uint32 { 6594 switch a { 6595 case ASVC: 6596 return 0xD4<<24 | 0<<21 | 1 6597 6598 case AHVC: 6599 return 0xD4<<24 | 0<<21 | 2 6600 6601 case ASMC: 6602 return 0xD4<<24 | 0<<21 | 3 6603 6604 case ABRK: 6605 return 0xD4<<24 | 1<<21 | 0 6606 6607 case AHLT: 6608 return 0xD4<<24 | 2<<21 | 0 6609 6610 case ADCPS1: 6611 return 0xD4<<24 | 5<<21 | 1 6612 6613 case ADCPS2: 6614 return 0xD4<<24 | 5<<21 | 2 6615 6616 case ADCPS3: 6617 return 0xD4<<24 | 5<<21 | 3 6618 6619 case ACLREX: 6620 return SYSOP(0, 0, 3, 3, 0, 2, 0x1F) 6621 } 6622 6623 c.ctxt.Diag("%v: bad imm %v", p, a) 6624 return 0 6625 } 6626 6627 func (c *ctxt7) brdist(p *obj.Prog, preshift int, flen int, shift int) int64 { 6628 v := int64(0) 6629 t := int64(0) 6630 var q *obj.Prog 6631 if p.To.Type == obj.TYPE_BRANCH { 6632 q = p.To.Target() 6633 } else if p.From.Type == obj.TYPE_BRANCH { 6634 q = p.From.Target() 6635 } 6636 if q == nil { 6637 6638 6639 q = p.Pool 6640 } 6641 if q != nil { 6642 v = (q.Pc >> uint(preshift)) - (c.pc >> uint(preshift)) 6643 if (v & ((1 << uint(shift)) - 1)) != 0 { 6644 c.ctxt.Diag("misaligned label\n%v", p) 6645 } 6646 v >>= uint(shift) 6647 t = int64(1) << uint(flen-1) 6648 if v < -t || v >= t { 6649 c.ctxt.Diag("branch too far %#x vs %#x [%p]\n%v\n%v", v, t, c.blitrl, p, q) 6650 panic("branch too far") 6651 } 6652 } 6653 6654 return v & ((t << 1) - 1) 6655 } 6656 6657 6658 func (c *ctxt7) opbra(p *obj.Prog, a obj.As) uint32 { 6659 switch a { 6660 case ABEQ: 6661 return OPBcc(0x0) 6662 6663 case ABNE: 6664 return OPBcc(0x1) 6665 6666 case ABCS: 6667 return OPBcc(0x2) 6668 6669 case ABHS: 6670 return OPBcc(0x2) 6671 6672 case ABCC: 6673 return OPBcc(0x3) 6674 6675 case ABLO: 6676 return OPBcc(0x3) 6677 6678 case ABMI: 6679 return OPBcc(0x4) 6680 6681 case ABPL: 6682 return OPBcc(0x5) 6683 6684 case ABVS: 6685 return OPBcc(0x6) 6686 6687 case ABVC: 6688 return OPBcc(0x7) 6689 6690 case ABHI: 6691 return OPBcc(0x8) 6692 6693 case ABLS: 6694 return OPBcc(0x9) 6695 6696 case ABGE: 6697 return OPBcc(0xa) 6698 6699 case ABLT: 6700 return OPBcc(0xb) 6701 6702 case ABGT: 6703 return OPBcc(0xc) 6704 6705 case ABLE: 6706 return OPBcc(0xd) 6707 6708 case AB: 6709 return 0<<31 | 5<<26 6710 6711 case obj.ADUFFZERO, obj.ADUFFCOPY, ABL: 6712 return 1<<31 | 5<<26 6713 } 6714 6715 c.ctxt.Diag("%v: bad bra %v", p, a) 6716 return 0 6717 } 6718 6719 func (c *ctxt7) opbrr(p *obj.Prog, a obj.As) uint32 { 6720 switch a { 6721 case ABL: 6722 return OPBLR(1) 6723 6724 case AB: 6725 return OPBLR(0) 6726 6727 case obj.ARET: 6728 return OPBLR(2) 6729 } 6730 6731 c.ctxt.Diag("%v: bad brr %v", p, a) 6732 return 0 6733 } 6734 6735 func (c *ctxt7) op0(p *obj.Prog, a obj.As) uint32 { 6736 switch a { 6737 case ADRPS: 6738 return 0x6B<<25 | 5<<21 | 0x1F<<16 | 0x1F<<5 6739 6740 case AERET: 6741 return 0x6B<<25 | 4<<21 | 0x1F<<16 | 0<<10 | 0x1F<<5 6742 6743 case ANOOP: 6744 return SYSHINT(0) 6745 6746 case AYIELD: 6747 return SYSHINT(1) 6748 6749 case AWFE: 6750 return SYSHINT(2) 6751 6752 case AWFI: 6753 return SYSHINT(3) 6754 6755 case ASEV: 6756 return SYSHINT(4) 6757 6758 case ASEVL: 6759 return SYSHINT(5) 6760 } 6761 6762 c.ctxt.Diag("%v: bad op0 %v", p, a) 6763 return 0 6764 } 6765 6766 6767 func (c *ctxt7) opload(p *obj.Prog, a obj.As) uint32 { 6768 switch a { 6769 case ALDAR: 6770 return LDSTX(3, 1, 1, 0, 1) | 0x1F<<10 6771 6772 case ALDARW: 6773 return LDSTX(2, 1, 1, 0, 1) | 0x1F<<10 6774 6775 case ALDARB: 6776 return LDSTX(0, 1, 1, 0, 1) | 0x1F<<10 6777 6778 case ALDARH: 6779 return LDSTX(1, 1, 1, 0, 1) | 0x1F<<10 6780 6781 case ALDAXP: 6782 return LDSTX(3, 0, 1, 1, 1) 6783 6784 case ALDAXPW: 6785 return LDSTX(2, 0, 1, 1, 1) 6786 6787 case ALDAXR: 6788 return LDSTX(3, 0, 1, 0, 1) | 0x1F<<10 6789 6790 case ALDAXRW: 6791 return LDSTX(2, 0, 1, 0, 1) | 0x1F<<10 6792 6793 case ALDAXRB: 6794 return LDSTX(0, 0, 1, 0, 1) | 0x1F<<10 6795 6796 case ALDAXRH: 6797 return LDSTX(1, 0, 1, 0, 1) | 0x1F<<10 6798 6799 case ALDXR: 6800 return LDSTX(3, 0, 1, 0, 0) | 0x1F<<10 6801 6802 case ALDXRB: 6803 return LDSTX(0, 0, 1, 0, 0) | 0x1F<<10 6804 6805 case ALDXRH: 6806 return LDSTX(1, 0, 1, 0, 0) | 0x1F<<10 6807 6808 case ALDXRW: 6809 return LDSTX(2, 0, 1, 0, 0) | 0x1F<<10 6810 6811 case ALDXP: 6812 return LDSTX(3, 0, 1, 1, 0) 6813 6814 case ALDXPW: 6815 return LDSTX(2, 0, 1, 1, 0) 6816 } 6817 6818 c.ctxt.Diag("bad opload %v\n%v", a, p) 6819 return 0 6820 } 6821 6822 func (c *ctxt7) opstore(p *obj.Prog, a obj.As) uint32 { 6823 switch a { 6824 case ASTLR: 6825 return LDSTX(3, 1, 0, 0, 1) | 0x1F<<10 6826 6827 case ASTLRB: 6828 return LDSTX(0, 1, 0, 0, 1) | 0x1F<<10 6829 6830 case ASTLRH: 6831 return LDSTX(1, 1, 0, 0, 1) | 0x1F<<10 6832 6833 case ASTLRW: 6834 return LDSTX(2, 1, 0, 0, 1) | 0x1F<<10 6835 6836 case ASTLXP: 6837 return LDSTX(3, 0, 0, 1, 1) 6838 6839 case ASTLXPW: 6840 return LDSTX(2, 0, 0, 1, 1) 6841 6842 case ASTLXR: 6843 return LDSTX(3, 0, 0, 0, 1) | 0x1F<<10 6844 6845 case ASTLXRB: 6846 return LDSTX(0, 0, 0, 0, 1) | 0x1F<<10 6847 6848 case ASTLXRH: 6849 return LDSTX(1, 0, 0, 0, 1) | 0x1F<<10 6850 6851 case ASTLXRW: 6852 return LDSTX(2, 0, 0, 0, 1) | 0x1F<<10 6853 6854 case ASTXR: 6855 return LDSTX(3, 0, 0, 0, 0) | 0x1F<<10 6856 6857 case ASTXRB: 6858 return LDSTX(0, 0, 0, 0, 0) | 0x1F<<10 6859 6860 case ASTXRH: 6861 return LDSTX(1, 0, 0, 0, 0) | 0x1F<<10 6862 6863 case ASTXP: 6864 return LDSTX(3, 0, 0, 1, 0) 6865 6866 case ASTXPW: 6867 return LDSTX(2, 0, 0, 1, 0) 6868 6869 case ASTXRW: 6870 return LDSTX(2, 0, 0, 0, 0) | 0x1F<<10 6871 } 6872 6873 c.ctxt.Diag("bad opstore %v\n%v", a, p) 6874 return 0 6875 } 6876 6877 6878 func (c *ctxt7) olsr12u(p *obj.Prog, o uint32, v int32, rn, rt int16) uint32 { 6879 if v < 0 || v >= (1<<12) { 6880 c.ctxt.Diag("offset out of range: %d\n%v", v, p) 6881 } 6882 o |= uint32(v&0xFFF) << 10 6883 o |= uint32(rn&31) << 5 6884 o |= uint32(rt & 31) 6885 o |= 1 << 24 6886 return o 6887 } 6888 6889 6890 func (c *ctxt7) olsr9s(p *obj.Prog, o uint32, v int32, rn, rt int16) uint32 { 6891 if v < -256 || v > 255 { 6892 c.ctxt.Diag("offset out of range: %d\n%v", v, p) 6893 } 6894 o |= uint32((v & 0x1FF) << 12) 6895 o |= uint32(rn&31) << 5 6896 o |= uint32(rt & 31) 6897 return o 6898 } 6899 6900 6901 6902 6903 6904 6905 func (c *ctxt7) opstr(p *obj.Prog, a obj.As) uint32 { 6906 enc := c.opldr(p, a) 6907 switch p.As { 6908 case AFMOVQ: 6909 enc = enc &^ (1 << 22) 6910 default: 6911 enc = LD2STR(enc) 6912 } 6913 return enc 6914 } 6915 6916 6917 6918 6919 6920 6921 func (c *ctxt7) opldr(p *obj.Prog, a obj.As) uint32 { 6922 switch a { 6923 case AMOVD: 6924 return LDSTR(3, 0, 1) 6925 6926 case AMOVW: 6927 return LDSTR(2, 0, 2) 6928 6929 case AMOVWU: 6930 return LDSTR(2, 0, 1) 6931 6932 case AMOVH: 6933 return LDSTR(1, 0, 2) 6934 6935 case AMOVHU: 6936 return LDSTR(1, 0, 1) 6937 6938 case AMOVB: 6939 return LDSTR(0, 0, 2) 6940 6941 case AMOVBU: 6942 return LDSTR(0, 0, 1) 6943 6944 case AFMOVS: 6945 return LDSTR(2, 1, 1) 6946 6947 case AFMOVD: 6948 return LDSTR(3, 1, 1) 6949 6950 case AFMOVQ: 6951 return LDSTR(0, 1, 3) 6952 } 6953 6954 c.ctxt.Diag("bad opldr %v\n%v", a, p) 6955 return 0 6956 } 6957 6958 6959 6960 func (c *ctxt7) olsxrr(p *obj.Prog, o int32, r int, r1 int, r2 int) uint32 { 6961 o |= int32(r1&31) << 5 6962 o |= int32(r2&31) << 16 6963 o |= int32(r & 31) 6964 return uint32(o) 6965 } 6966 6967 6968 6969 6970 func (c *ctxt7) opldrr(p *obj.Prog, a obj.As, extension bool) uint32 { 6971 OptionS := uint32(0x1a) 6972 if extension { 6973 OptionS = uint32(0) 6974 } 6975 switch a { 6976 case AMOVD: 6977 return OptionS<<10 | 0x3<<21 | 0x1f<<27 6978 case AMOVW: 6979 return OptionS<<10 | 0x5<<21 | 0x17<<27 6980 case AMOVWU: 6981 return OptionS<<10 | 0x3<<21 | 0x17<<27 6982 case AMOVH: 6983 return OptionS<<10 | 0x5<<21 | 0x0f<<27 6984 case AMOVHU: 6985 return OptionS<<10 | 0x3<<21 | 0x0f<<27 6986 case AMOVB: 6987 return OptionS<<10 | 0x5<<21 | 0x07<<27 6988 case AMOVBU: 6989 return OptionS<<10 | 0x3<<21 | 0x07<<27 6990 case AFMOVS: 6991 return OptionS<<10 | 0x3<<21 | 0x17<<27 | 1<<26 6992 case AFMOVD: 6993 return OptionS<<10 | 0x3<<21 | 0x1f<<27 | 1<<26 6994 } 6995 c.ctxt.Diag("bad opldrr %v\n%v", a, p) 6996 return 0 6997 } 6998 6999 7000 7001 7002 func (c *ctxt7) opstrr(p *obj.Prog, a obj.As, extension bool) uint32 { 7003 OptionS := uint32(0x1a) 7004 if extension { 7005 OptionS = uint32(0) 7006 } 7007 switch a { 7008 case AMOVD: 7009 return OptionS<<10 | 0x1<<21 | 0x1f<<27 7010 case AMOVW, AMOVWU: 7011 return OptionS<<10 | 0x1<<21 | 0x17<<27 7012 case AMOVH, AMOVHU: 7013 return OptionS<<10 | 0x1<<21 | 0x0f<<27 7014 case AMOVB, AMOVBU: 7015 return OptionS<<10 | 0x1<<21 | 0x07<<27 7016 case AFMOVS: 7017 return OptionS<<10 | 0x1<<21 | 0x17<<27 | 1<<26 7018 case AFMOVD: 7019 return OptionS<<10 | 0x1<<21 | 0x1f<<27 | 1<<26 7020 } 7021 c.ctxt.Diag("bad opstrr %v\n%v", a, p) 7022 return 0 7023 } 7024 7025 func (c *ctxt7) oaddi(p *obj.Prog, a obj.As, v int32, rd, rn int16) uint32 { 7026 op := c.opirr(p, a) 7027 7028 if (v & 0xFFF000) != 0 { 7029 if v&0xFFF != 0 { 7030 c.ctxt.Diag("%v misuses oaddi", p) 7031 } 7032 v >>= 12 7033 op |= 1 << 22 7034 } 7035 7036 op |= (uint32(v&0xFFF) << 10) | (uint32(rn&31) << 5) | uint32(rd&31) 7037 7038 return op 7039 } 7040 7041 func (c *ctxt7) oaddi12(p *obj.Prog, v int32, rd, rn int16) uint32 { 7042 if v < -4095 || v > 4095 { 7043 c.ctxt.Diag("%v is not a 12 bit immediate: %v", v, p) 7044 return 0 7045 } 7046 a := AADD 7047 if v < 0 { 7048 a = ASUB 7049 v = -v 7050 } 7051 return c.oaddi(p, a, v, rd, rn) 7052 } 7053 7054 7055 func (c *ctxt7) omovlit(as obj.As, p *obj.Prog, a *obj.Addr, dr int) uint32 { 7056 var o1 int32 7057 if p.Pool == nil { 7058 c.aclass(a) 7059 c.ctxt.Logf("omovlit add %d (%#x)\n", c.instoffset, uint64(c.instoffset)) 7060 7061 7062 o1 = int32(c.opirr(p, AADD)) 7063 7064 v := int32(c.instoffset) 7065 if v != 0 && (v&0xFFF) == 0 { 7066 v >>= 12 7067 o1 |= 1 << 22 7068 } 7069 7070 o1 |= ((v & 0xFFF) << 10) | (REGZERO & 31 << 5) | int32(dr&31) 7071 } else { 7072 fp, w := 0, 0 7073 switch as { 7074 case AFMOVS, AVMOVS: 7075 fp = 1 7076 w = 0 7077 7078 case AFMOVD, AVMOVD: 7079 fp = 1 7080 w = 1 7081 7082 case AVMOVQ: 7083 fp = 1 7084 w = 2 7085 7086 case AMOVD: 7087 if p.Pool.As == ADWORD { 7088 w = 1 7089 } else if p.Pool.To.Offset < 0 { 7090 w = 2 7091 } else if p.Pool.To.Offset >= 0 { 7092 w = 0 7093 } else { 7094 c.ctxt.Diag("invalid operand %v in %v", a, p) 7095 } 7096 7097 case AMOVBU, AMOVHU, AMOVWU: 7098 w = 0 7099 7100 case AMOVB, AMOVH, AMOVW: 7101 w = 2 7102 7103 default: 7104 c.ctxt.Diag("invalid operation %v in %v", as, p) 7105 } 7106 7107 v := int32(c.brdist(p, 0, 19, 2)) 7108 o1 = (int32(w) << 30) | (int32(fp) << 26) | (3 << 27) 7109 o1 |= (v & 0x7FFFF) << 5 7110 o1 |= int32(dr & 31) 7111 } 7112 7113 return uint32(o1) 7114 } 7115 7116 7117 func (c *ctxt7) omovconst(as obj.As, p *obj.Prog, a *obj.Addr, rt int) (o1 uint32) { 7118 if cls := oclass(a); (cls == C_BITCON || cls == C_ABCON || cls == C_ABCON0) && rt != REGZERO { 7119 7120 mode := 64 7121 var as1 obj.As 7122 switch as { 7123 case AMOVW: 7124 as1 = AORRW 7125 mode = 32 7126 case AMOVD: 7127 as1 = AORR 7128 } 7129 o1 = c.opirr(p, as1) 7130 o1 |= bitconEncode(uint64(a.Offset), mode) | uint32(REGZERO&31)<<5 | uint32(rt&31) 7131 return o1 7132 } 7133 7134 if as == AMOVW { 7135 d := uint32(a.Offset) 7136 s := movcon(int64(d)) 7137 if s < 0 || 16*s >= 32 { 7138 d = ^d 7139 s = movcon(int64(d)) 7140 if s < 0 || 16*s >= 32 { 7141 c.ctxt.Diag("impossible 32-bit move wide: %#x\n%v", uint32(a.Offset), p) 7142 } 7143 o1 = c.opirr(p, AMOVNW) 7144 } else { 7145 o1 = c.opirr(p, AMOVZW) 7146 } 7147 o1 |= MOVCONST(int64(d), s, rt) 7148 } 7149 if as == AMOVD { 7150 d := a.Offset 7151 s := movcon(d) 7152 if s < 0 || 16*s >= 64 { 7153 d = ^d 7154 s = movcon(d) 7155 if s < 0 || 16*s >= 64 { 7156 c.ctxt.Diag("impossible 64-bit move wide: %#x\n%v", uint64(a.Offset), p) 7157 } 7158 o1 = c.opirr(p, AMOVN) 7159 } else { 7160 o1 = c.opirr(p, AMOVZ) 7161 } 7162 o1 |= MOVCONST(d, s, rt) 7163 } 7164 return o1 7165 } 7166 7167 7168 7169 func (c *ctxt7) omovlconst(as obj.As, p *obj.Prog, a *obj.Addr, rt int, os []uint32) (num uint8) { 7170 switch as { 7171 case AMOVW: 7172 d := uint32(a.Offset) 7173 7174 os[0] = c.opirr(p, AMOVZW) 7175 os[0] |= MOVCONST(int64(d), 0, rt) 7176 os[1] = c.opirr(p, AMOVKW) 7177 os[1] |= MOVCONST(int64(d), 1, rt) 7178 return 2 7179 7180 case AMOVD: 7181 d := a.Offset 7182 dn := ^d 7183 var immh [4]uint64 7184 var i int 7185 zeroCount := int(0) 7186 negCount := int(0) 7187 for i = 0; i < 4; i++ { 7188 immh[i] = uint64((d >> uint(i*16)) & 0xffff) 7189 if immh[i] == 0 { 7190 zeroCount++ 7191 } else if immh[i] == 0xffff { 7192 negCount++ 7193 } 7194 } 7195 7196 if zeroCount == 4 || negCount == 4 { 7197 c.ctxt.Diag("the immediate should be MOVCON: %v", p) 7198 } 7199 switch { 7200 case zeroCount == 3: 7201 7202 for i = 0; i < 4; i++ { 7203 if immh[i] != 0 { 7204 os[0] = c.opirr(p, AMOVZ) 7205 os[0] |= MOVCONST(d, i, rt) 7206 break 7207 } 7208 } 7209 return 1 7210 7211 case negCount == 3: 7212 7213 for i = 0; i < 4; i++ { 7214 if immh[i] != 0xffff { 7215 os[0] = c.opirr(p, AMOVN) 7216 os[0] |= MOVCONST(dn, i, rt) 7217 break 7218 } 7219 } 7220 return 1 7221 7222 case zeroCount == 2: 7223 7224 for i = 0; i < 4; i++ { 7225 if immh[i] != 0 { 7226 os[0] = c.opirr(p, AMOVZ) 7227 os[0] |= MOVCONST(d, i, rt) 7228 i++ 7229 break 7230 } 7231 } 7232 for ; i < 4; i++ { 7233 if immh[i] != 0 { 7234 os[1] = c.opirr(p, AMOVK) 7235 os[1] |= MOVCONST(d, i, rt) 7236 } 7237 } 7238 return 2 7239 7240 case negCount == 2: 7241 7242 for i = 0; i < 4; i++ { 7243 if immh[i] != 0xffff { 7244 os[0] = c.opirr(p, AMOVN) 7245 os[0] |= MOVCONST(dn, i, rt) 7246 i++ 7247 break 7248 } 7249 } 7250 for ; i < 4; i++ { 7251 if immh[i] != 0xffff { 7252 os[1] = c.opirr(p, AMOVK) 7253 os[1] |= MOVCONST(d, i, rt) 7254 } 7255 } 7256 return 2 7257 7258 case zeroCount == 1: 7259 7260 for i = 0; i < 4; i++ { 7261 if immh[i] != 0 { 7262 os[0] = c.opirr(p, AMOVZ) 7263 os[0] |= MOVCONST(d, i, rt) 7264 i++ 7265 break 7266 } 7267 } 7268 7269 for j := 1; i < 4; i++ { 7270 if immh[i] != 0 { 7271 os[j] = c.opirr(p, AMOVK) 7272 os[j] |= MOVCONST(d, i, rt) 7273 j++ 7274 } 7275 } 7276 return 3 7277 7278 case negCount == 1: 7279 7280 for i = 0; i < 4; i++ { 7281 if immh[i] != 0xffff { 7282 os[0] = c.opirr(p, AMOVN) 7283 os[0] |= MOVCONST(dn, i, rt) 7284 i++ 7285 break 7286 } 7287 } 7288 7289 for j := 1; i < 4; i++ { 7290 if immh[i] != 0xffff { 7291 os[j] = c.opirr(p, AMOVK) 7292 os[j] |= MOVCONST(d, i, rt) 7293 j++ 7294 } 7295 } 7296 return 3 7297 7298 default: 7299 7300 os[0] = c.opirr(p, AMOVZ) 7301 os[0] |= MOVCONST(d, 0, rt) 7302 for i = 1; i < 4; i++ { 7303 os[i] = c.opirr(p, AMOVK) 7304 os[i] |= MOVCONST(d, i, rt) 7305 } 7306 return 4 7307 } 7308 default: 7309 return 0 7310 } 7311 } 7312 7313 func (c *ctxt7) opbfm(p *obj.Prog, a obj.As, r, s int64, rf, rt int16) uint32 { 7314 var b uint32 7315 o := c.opirr(p, a) 7316 if (o & (1 << 31)) == 0 { 7317 b = 32 7318 } else { 7319 b = 64 7320 } 7321 if r < 0 || uint32(r) >= b { 7322 c.ctxt.Diag("illegal bit number\n%v", p) 7323 } 7324 o |= (uint32(r) & 0x3F) << 16 7325 if s < 0 || uint32(s) >= b { 7326 c.ctxt.Diag("illegal bit number\n%v", p) 7327 } 7328 o |= (uint32(s) & 0x3F) << 10 7329 o |= (uint32(rf&31) << 5) | uint32(rt&31) 7330 return o 7331 } 7332 7333 func (c *ctxt7) opextr(p *obj.Prog, a obj.As, v int64, rn, rm, rt int16) uint32 { 7334 var b uint32 7335 o := c.opirr(p, a) 7336 if (o & (1 << 31)) != 0 { 7337 b = 63 7338 } else { 7339 b = 31 7340 } 7341 if v < 0 || uint32(v) > b { 7342 c.ctxt.Diag("illegal bit number\n%v", p) 7343 } 7344 o |= uint32(v) << 10 7345 o |= uint32(rn&31) << 5 7346 o |= uint32(rm&31) << 16 7347 o |= uint32(rt & 31) 7348 return o 7349 } 7350 7351 7352 func (c *ctxt7) opldpstp(p *obj.Prog, o *Optab, vo int32, rbase, rl, rh int16, ldp uint32) uint32 { 7353 wback := false 7354 if o.scond == C_XPOST || o.scond == C_XPRE { 7355 wback = true 7356 } 7357 switch p.As { 7358 case ALDP, ALDPW, ALDPSW: 7359 c.checkUnpredictable(p, true, wback, p.From.Reg, p.To.Reg, int16(p.To.Offset)) 7360 case ASTP, ASTPW: 7361 if wback { 7362 c.checkUnpredictable(p, false, true, p.To.Reg, p.From.Reg, int16(p.From.Offset)) 7363 } 7364 case AFLDPD, AFLDPQ, AFLDPS: 7365 c.checkUnpredictable(p, true, false, p.From.Reg, p.To.Reg, int16(p.To.Offset)) 7366 } 7367 var ret uint32 7368 7369 switch p.As { 7370 case AFLDPQ, AFSTPQ: 7371 if vo < -1024 || vo > 1008 || vo%16 != 0 { 7372 c.ctxt.Diag("invalid offset %v\n", p) 7373 } 7374 vo /= 16 7375 ret = 2<<30 | 1<<26 7376 case AFLDPD, AFSTPD: 7377 if vo < -512 || vo > 504 || vo%8 != 0 { 7378 c.ctxt.Diag("invalid offset %v\n", p) 7379 } 7380 vo /= 8 7381 ret = 1<<30 | 1<<26 7382 case AFLDPS, AFSTPS: 7383 if vo < -256 || vo > 252 || vo%4 != 0 { 7384 c.ctxt.Diag("invalid offset %v\n", p) 7385 } 7386 vo /= 4 7387 ret = 1 << 26 7388 case ALDP, ASTP: 7389 if vo < -512 || vo > 504 || vo%8 != 0 { 7390 c.ctxt.Diag("invalid offset %v\n", p) 7391 } 7392 vo /= 8 7393 ret = 2 << 30 7394 case ALDPW, ASTPW: 7395 if vo < -256 || vo > 252 || vo%4 != 0 { 7396 c.ctxt.Diag("invalid offset %v\n", p) 7397 } 7398 vo /= 4 7399 ret = 0 7400 case ALDPSW: 7401 if vo < -256 || vo > 252 || vo%4 != 0 { 7402 c.ctxt.Diag("invalid offset %v\n", p) 7403 } 7404 vo /= 4 7405 ret = 1 << 30 7406 default: 7407 c.ctxt.Diag("invalid instruction %v\n", p) 7408 } 7409 7410 switch p.As { 7411 case AFLDPQ, AFLDPD, AFLDPS, AFSTPQ, AFSTPD, AFSTPS: 7412 if rl < REG_F0 || REG_F31 < rl || rh < REG_F0 || REG_F31 < rh { 7413 c.ctxt.Diag("invalid register pair %v\n", p) 7414 } 7415 case ALDP, ALDPW, ALDPSW: 7416 if rl < REG_R0 || REG_R30 < rl || rh < REG_R0 || REG_R30 < rh { 7417 c.ctxt.Diag("invalid register pair %v\n", p) 7418 } 7419 case ASTP, ASTPW: 7420 if rl < REG_R0 || REG_R31 < rl || rh < REG_R0 || REG_R31 < rh { 7421 c.ctxt.Diag("invalid register pair %v\n", p) 7422 } 7423 } 7424 7425 switch o.scond { 7426 case C_XPOST: 7427 ret |= 1 << 23 7428 case C_XPRE: 7429 ret |= 3 << 23 7430 default: 7431 ret |= 2 << 23 7432 } 7433 ret |= 5<<27 | (ldp&1)<<22 | uint32(vo&0x7f)<<15 | uint32(rh&31)<<10 | uint32(rbase&31)<<5 | uint32(rl&31) 7434 return ret 7435 } 7436 7437 func (c *ctxt7) maskOpvldvst(p *obj.Prog, o1 uint32) uint32 { 7438 if p.As == AVLD1 || p.As == AVST1 { 7439 return o1 7440 } 7441 7442 o1 &^= 0xf000 7443 switch p.As { 7444 case AVLD1R, AVLD2R: 7445 o1 |= 0xC << 12 7446 case AVLD3R, AVLD4R: 7447 o1 |= 0xE << 12 7448 case AVLD2, AVST2: 7449 o1 |= 8 << 12 7450 case AVLD3, AVST3: 7451 o1 |= 4 << 12 7452 case AVLD4, AVST4: 7453 default: 7454 c.ctxt.Diag("unsupported instruction:%v\n", p.As) 7455 } 7456 return o1 7457 } 7458 7459 7460 func movesize(a obj.As) int { 7461 switch a { 7462 case AFMOVQ: 7463 return 4 7464 7465 case AMOVD, AFMOVD: 7466 return 3 7467 7468 case AMOVW, AMOVWU, AFMOVS: 7469 return 2 7470 7471 case AMOVH, AMOVHU: 7472 return 1 7473 7474 case AMOVB, AMOVBU: 7475 return 0 7476 7477 default: 7478 return -1 7479 } 7480 } 7481 7482 7483 func roff(rm int16, o uint32, amount int16) uint32 { 7484 return uint32(rm&31)<<16 | o<<13 | uint32(amount)<<10 7485 } 7486 7487 7488 func (c *ctxt7) encRegShiftOrExt(p *obj.Prog, a *obj.Addr, r int16) uint32 { 7489 var num, rm int16 7490 num = (r >> 5) & 7 7491 rm = r & 31 7492 switch { 7493 case REG_UXTB <= r && r < REG_UXTH: 7494 return roff(rm, 0, num) 7495 case REG_UXTH <= r && r < REG_UXTW: 7496 return roff(rm, 1, num) 7497 case REG_UXTW <= r && r < REG_UXTX: 7498 if a.Type == obj.TYPE_MEM { 7499 if num == 0 { 7500 return roff(rm, 2, 2) 7501 } else { 7502 return roff(rm, 2, 6) 7503 } 7504 } else { 7505 return roff(rm, 2, num) 7506 } 7507 case REG_UXTX <= r && r < REG_SXTB: 7508 return roff(rm, 3, num) 7509 case REG_SXTB <= r && r < REG_SXTH: 7510 return roff(rm, 4, num) 7511 case REG_SXTH <= r && r < REG_SXTW: 7512 return roff(rm, 5, num) 7513 case REG_SXTW <= r && r < REG_SXTX: 7514 if a.Type == obj.TYPE_MEM { 7515 if num == 0 { 7516 return roff(rm, 6, 2) 7517 } else { 7518 return roff(rm, 6, 6) 7519 } 7520 } else { 7521 return roff(rm, 6, num) 7522 } 7523 case REG_SXTX <= r && r < REG_SPECIAL: 7524 if a.Type == obj.TYPE_MEM { 7525 if num == 0 { 7526 return roff(rm, 7, 2) 7527 } else { 7528 return roff(rm, 7, 6) 7529 } 7530 } else { 7531 return roff(rm, 7, num) 7532 } 7533 case REG_LSL <= r && r < REG_ARNG: 7534 if a.Type == obj.TYPE_MEM { 7535 return roff(rm, 3, 6) 7536 } else if isADDWop(p.As) { 7537 return roff(rm, 2, num) 7538 } 7539 return roff(rm, 3, num) 7540 default: 7541 c.ctxt.Diag("unsupported register extension type.") 7542 } 7543 7544 return 0 7545 } 7546 7547 7548 func pack(q uint32, arngA, arngB uint8) uint32 { 7549 return uint32(q)<<16 | uint32(arngA)<<8 | uint32(arngB) 7550 }