2264 2265 INSN(sha1h, 0b000010); 2266 INSN(sha1su1, 0b000110); 2267 INSN(sha256su0, 0b001010); 2268 2269 #undef INSN 2270 2271 #define INSN(NAME, opc) \ 2272 void NAME(FloatRegister Vd, FloatRegister Vn) { \ 2273 starti; \ 2274 f(opc, 31, 10), rf(Vn, 5), rf(Vd, 0); \ 2275 } 2276 2277 INSN(aese, 0b0100111000101000010010); 2278 INSN(aesd, 0b0100111000101000010110); 2279 INSN(aesmc, 0b0100111000101000011010); 2280 INSN(aesimc, 0b0100111000101000011110); 2281 2282 #undef INSN 2283 2284 void ins(FloatRegister Vd, SIMD_RegVariant T, FloatRegister Vn, int didx, int sidx) { 2285 starti; 2286 assert(T != Q, "invalid register variant"); 2287 f(0b01101110000, 31, 21), f(((didx<<1)|1)<<(int)T, 20, 16), f(0, 15); 2288 f(sidx<<(int)T, 14, 11), f(1, 10), rf(Vn, 5), rf(Vd, 0); 2289 } 2290 2291 void umov(Register Rd, FloatRegister Vn, SIMD_RegVariant T, int idx) { 2292 starti; 2293 f(0, 31), f(T==D ? 1:0, 30), f(0b001110000, 29, 21); 2294 f(((idx<<1)|1)<<(int)T, 20, 16), f(0b001111, 15, 10); 2295 rf(Vn, 5), rf(Rd, 0); 2296 } 2297 2298 #define INSN(NAME, opc, opc2, isSHR) \ 2299 void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, int shift){ \ 2300 starti; \ 2301 /* The encodings for the immh:immb fields (bits 22:16) in *SHR are \ 2302 * 0001 xxx 8B/16B, shift = 16 - UInt(immh:immb) \ 2303 * 001x xxx 4H/8H, shift = 32 - UInt(immh:immb) \ | 2264 2265 INSN(sha1h, 0b000010); 2266 INSN(sha1su1, 0b000110); 2267 INSN(sha256su0, 0b001010); 2268 2269 #undef INSN 2270 2271 #define INSN(NAME, opc) \ 2272 void NAME(FloatRegister Vd, FloatRegister Vn) { \ 2273 starti; \ 2274 f(opc, 31, 10), rf(Vn, 5), rf(Vd, 0); \ 2275 } 2276 2277 INSN(aese, 0b0100111000101000010010); 2278 INSN(aesd, 0b0100111000101000010110); 2279 INSN(aesmc, 0b0100111000101000011010); 2280 INSN(aesimc, 0b0100111000101000011110); 2281 2282 #undef INSN 2283 2284 // vect1 += vect2*scalar. FMLA-Vector-Scalar-Double 2285 void fmlavsd(FloatRegister Vd, FloatRegister Vn, FloatRegister Vm, int index) { 2286 assert(index == 0 || index == 1, "Incorrect index"); 2287 starti; 2288 f(0b01001111110, 31, 21); 2289 rf(Vm, 16); 2290 f(0b0001, 15, 12); 2291 f(index, 11); 2292 f(0, 10); 2293 rf(Vn, 5); 2294 rf(Vd, 0); 2295 } 2296 2297 // vect1 += vect2*vect3. FMLA-Vector-Vector-Double 2298 void fmlavvd(FloatRegister Vd, FloatRegister Vn, FloatRegister Vm) { 2299 starti; 2300 // 01001110011 Rm 110011 Rn Rd 2301 f(0b01001110011, 31, 21); 2302 rf(Vm, 16); 2303 f(0b110011, 15, 10); 2304 rf(Vn, 5); 2305 rf(Vd, 0); 2306 } 2307 2308 // Floating-point Reciprocal Estimate for single precision 2309 void frecpe(FloatRegister Vd, FloatRegister Vn, SIMD_RegVariant type) { 2310 assert(type == D || type == S, "Wrong type for frecpe"); 2311 starti; 2312 f(0b010111101, 31, 23); 2313 f(type == D ? 1 : 0, 22); 2314 f(0b100001110110, 21, 10); 2315 rf(Vn, 5), rf(Vd, 0); 2316 } 2317 2318 // (double) {a, b} -> (a + b) 2319 void faddpd(FloatRegister Vd, FloatRegister Vn) { 2320 starti; 2321 f(0b0111111001110000110110, 31, 10); 2322 rf(Vn, 5), rf(Vd, 0); 2323 } 2324 2325 // fmulxvd is vect(Vn)*Vm[index]. FMULX-Vector-Scalar-Double 2326 void fmulxvsd(FloatRegister Vd, FloatRegister Vn, FloatRegister Vm, int index) { 2327 assert(index == 0 || index == 1, "Incorrect index"); 2328 //Q=1, sz=1,L=0, M:Rm = Vm, H=index for T2D 2329 starti; 2330 f(0b01101111110, 31, 21); 2331 rf(Vm, 16); 2332 f(0b1001, 15, 12); 2333 f(index, 11); 2334 f(0, 10); 2335 rf(Vn, 5); 2336 rf(Vd, 0); 2337 } 2338 2339 // fmulxsd is LO64(Vn)*Vm[index]. FULX-Scalar-Double 2340 void fmulxssd(FloatRegister Vd, FloatRegister Vn, FloatRegister Vm, int index) { 2341 // sz = 1, L = 0, H = index, M:Rm = Vm 2342 starti; 2343 f(0b01111111110, 31, 21); 2344 rf(Vm, 16); 2345 f(0b1001, 15, 12); 2346 f(index, 11); 2347 f(0, 10); 2348 rf(Vn, 5); 2349 rf(Vd, 0); 2350 } 2351 2352 void ins(FloatRegister Vd, SIMD_RegVariant T, FloatRegister Vn, int didx, int sidx) { 2353 starti; 2354 assert(T != Q, "invalid register variant"); 2355 f(0b01101110000, 31, 21), f(((didx<<1)|1)<<(int)T, 20, 16), f(0, 15); 2356 f(sidx<<(int)T, 14, 11), f(1, 10), rf(Vn, 5), rf(Vd, 0); 2357 } 2358 2359 void umov(Register Rd, FloatRegister Vn, SIMD_RegVariant T, int idx) { 2360 starti; 2361 f(0, 31), f(T==D ? 1:0, 30), f(0b001110000, 29, 21); 2362 f(((idx<<1)|1)<<(int)T, 20, 16), f(0b001111, 15, 10); 2363 rf(Vn, 5), rf(Rd, 0); 2364 } 2365 2366 #define INSN(NAME, opc, opc2, isSHR) \ 2367 void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, int shift){ \ 2368 starti; \ 2369 /* The encodings for the immh:immb fields (bits 22:16) in *SHR are \ 2370 * 0001 xxx 8B/16B, shift = 16 - UInt(immh:immb) \ 2371 * 001x xxx 4H/8H, shift = 32 - UInt(immh:immb) \ |