< prev index next >

src/cpu/aarch64/vm/assembler_aarch64.hpp

Print this page
rev 8393 : 8079565: aarch64: Add vectorization support for aarch64
Summary: Add vectorization support
Reviewed-by: duke

*** 464,473 **** --- 464,478 ---- switch(_mode) { case base_plus_offset: { unsigned size = i->get(31, 30); + if (i->get(26, 26) && i->get(23, 23)) { + // SIMD Q Type - Size = 128 bits + assert(size == 0, "bad size"); + size = 0b100; + } unsigned mask = (1 << size) - 1; if (_offset < 0 || _offset & mask) { i->f(0b00, 25, 24); i->f(0, 21), i->f(0b00, 11, 10);
*** 1886,1898 **** enum SIMD_Arrangement { T8B, T16B, T4H, T8H, T2S, T4S, T1D, T2D }; enum SIMD_RegVariant { ! S32, D64, Q128 }; private: void ld_st(FloatRegister Vt, SIMD_Arrangement T, Register Xn, int op1, int op2) { starti; --- 1891,1912 ---- enum SIMD_Arrangement { T8B, T16B, T4H, T8H, T2S, T4S, T1D, T2D }; enum SIMD_RegVariant { ! B, H, S, D, Q }; + #define INSN(NAME, op) \ + void NAME(FloatRegister Rt, SIMD_RegVariant T, const Address &adr) { \ + ld_st2((Register)Rt, adr, (int)T & 3, op + ((T==Q) ? 0b10:0b00), 1); \ + } \ + + INSN(ldr, 1); + INSN(str, 0); + + #undef INSN private: void ld_st(FloatRegister Vt, SIMD_Arrangement T, Register Xn, int op1, int op2) { starti;
*** 2006,2025 **** INSN(bsl, 0b101110011); INSN(orn, 0b001110111); #undef INSN ! #define INSN(NAME, opc) \ void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm) { \ starti; \ f(0, 31), f((int)T & 1, 30), f(opc, 29), f(0b01110, 28, 24); \ ! f((int)T >> 1, 23, 22), f(1, 21), rf(Vm, 16), f(0b100001, 15, 10); \ rf(Vn, 5), rf(Vd, 0); \ } ! INSN(addv, 0); ! INSN(subv, 1); #undef INSN #define INSN(NAME, opc) \ void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm) { \ --- 2020,2099 ---- INSN(bsl, 0b101110011); INSN(orn, 0b001110111); #undef INSN ! #define INSN(NAME, opc, opc2) \ void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm) { \ starti; \ f(0, 31), f((int)T & 1, 30), f(opc, 29), f(0b01110, 28, 24); \ ! f((int)T >> 1, 23, 22), f(1, 21), rf(Vm, 16), f(opc2, 15, 10); \ rf(Vn, 5), rf(Vd, 0); \ } ! INSN(addv, 0, 0b100001); ! INSN(subv, 1, 0b100001); ! INSN(mulv, 0, 0b100111); ! INSN(sshl, 0, 0b010001); ! INSN(ushl, 1, 0b010001); ! ! #undef INSN ! ! #define INSN(NAME, opc, opc2) \ ! void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn) { \ ! starti; \ ! f(0, 31), f((int)T & 1, 30), f(opc, 29), f(0b01110, 28, 24); \ ! f((int)T >> 1, 23, 22), f(opc2, 21, 10); \ ! rf(Vn, 5), rf(Vd, 0); \ ! } ! ! INSN(absr, 0, 0b100000101110); ! INSN(negr, 1, 0b100000101110); ! INSN(notr, 1, 0b100000010110); ! INSN(addv, 0, 0b110001101110); ! ! #undef INSN ! ! #define INSN(NAME, op0, cmode0) \ ! void NAME(FloatRegister Vd, SIMD_Arrangement T, unsigned imm8, unsigned lsl = 0) { \ ! unsigned cmode = cmode0; \ ! unsigned op = op0; \ ! starti; \ ! assert(lsl == 0 || \ ! ((T == T4H || T == T8H) && lsl == 8) || \ ! ((T == T2S || T == T4S) && ((lsl >> 3) < 4)), "invalid shift"); \ ! cmode |= lsl >> 2; \ ! if (T == T4H || T == T8H) cmode |= 0b1000; \ ! if (!(T == T4H || T == T8H || T == T2S || T == T4S)) { \ ! assert(op == 0 && cmode0 == 0, "must be MOVI"); \ ! cmode = 0b1110; \ ! if (T == T1D || T == T2D) op = 1; \ ! } \ ! f(0, 31), f((int)T & 1, 30), f(op, 29), f(0b0111100000, 28, 19); \ ! f(imm8 >> 5, 18, 16), f(cmode, 15, 12), f(0x01, 11, 10), f(imm8 & 0b11111, 9, 5); \ ! rf(Vd, 0); \ ! } ! ! INSN(movi, 0, 0); ! INSN(orri, 0, 1); ! INSN(mvni, 1, 0); ! INSN(bici, 1, 1); ! ! #undef INSN ! ! #define INSN(NAME, op1, op2, op3) \ ! void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm) { \ ! starti; \ ! assert(T == T2S || T == T4S || T == T2D, "invalid arrangement"); \ ! f(0, 31), f((int)T & 1, 30), f(op1, 29), f(0b01110, 28, 24), f(op2, 23); \ ! f(T==T2D ? 1:0, 22); f(1, 21), rf(Vm, 16), f(op3, 15, 10), rf(Vn, 5), rf(Vd, 0); \ ! } ! ! INSN(fadd, 0, 0, 0b110101); ! INSN(fdiv, 1, 0, 0b111111); ! INSN(fmul, 1, 0, 0b110111); ! INSN(fsub, 0, 1, 0b110101); #undef INSN #define INSN(NAME, opc) \ void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm) { \
*** 2062,2084 **** INSN(aesmc, 0b0100111000101000011010); INSN(aesimc, 0b0100111000101000011110); #undef INSN ! void shl(FloatRegister Vd, FloatRegister Vn, SIMD_Arrangement T, int shift){ starti; ! /* The encodings for the immh:immb fields (bits 22:16) are ! * 0001 xxx 8B/16B, shift = xxx ! * 001x xxx 4H/8H, shift = xxxx ! * 01xx xxx 2S/4S, shift = xxxxx ! * 1xxx xxx 1D/2D, shift = xxxxxx (1D is RESERVED) ! */ ! assert((1 << ((T>>1)+3)) > shift, "Invalid Shift value"); ! f(0, 31), f(T & 1, 30), f(0b0011110, 29, 23), f((1 << ((T>>1)+3))|shift, 22, 16); ! f(0b010101, 15, 10), rf(Vn, 5), rf(Vd, 0); } void ushll(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb, int shift) { starti; /* The encodings for the immh:immb fields (bits 22:16) are * 0001 xxx 8H, 8B/16b shift = xxx * 001x xxx 4S, 4H/8H shift = xxxx --- 2136,2179 ---- INSN(aesmc, 0b0100111000101000011010); INSN(aesimc, 0b0100111000101000011110); #undef INSN ! void ins(FloatRegister Vd, SIMD_RegVariant T, FloatRegister Vn, int didx, int sidx) { starti; ! assert(T != Q, "invalid register variant"); ! f(0b01101110000, 31, 21), f(((didx<<1)|1)<<(int)T, 20, 16), f(0, 15); ! f(sidx<<(int)T, 14, 11), f(1, 10), rf(Vn, 5), rf(Vd, 0); ! } ! ! void umov(Register Rd, FloatRegister Vn, SIMD_RegVariant T, int idx) { ! starti; ! f(0, 31), f(T==D ? 1:0, 30), f(0b001110000, 29, 21); ! f(((idx<<1)|1)<<(int)T, 20, 16), f(0b001111, 15, 10); ! rf(Vn, 5), rf(Rd, 0); ! } ! ! #define INSN(NAME, opc, opc2) \ ! void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, int shift){ \ ! starti; \ ! /* The encodings for the immh:immb fields (bits 22:16) are \ ! * 0001 xxx 8B/16B, shift = xxx \ ! * 001x xxx 4H/8H, shift = xxxx \ ! * 01xx xxx 2S/4S, shift = xxxxx \ ! * 1xxx xxx 1D/2D, shift = xxxxxx (1D is RESERVED) \ ! */ \ ! assert((1 << ((T>>1)+3)) > shift, "Invalid Shift value"); \ ! f(0, 31), f(T & 1, 30), f(opc, 29), f(0b011110, 28, 23), \ ! f((1 << ((T>>1)+3))|shift, 22, 16); f(opc2, 15, 10), rf(Vn, 5), rf(Vd, 0); \ } + INSN(shl, 0, 0b010101); + INSN(sshr, 0, 0b000001); + INSN(ushr, 1, 0b000001); + + #undef INSN + void ushll(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb, int shift) { starti; /* The encodings for the immh:immb fields (bits 22:16) are * 0001 xxx 8H, 8B/16b shift = xxx * 001x xxx 4S, 4H/8H shift = xxxx
*** 2147,2156 **** --- 2242,2268 ---- f(0, 31), f((int)T & 1, 30), f(0b101110, 29, 24); f(T <= T16B ? 0b00 : 0b01, 23, 22), f(0b100000000010, 21, 10); rf(Vn, 5), rf(Vd, 0); } + void dup(FloatRegister Vd, SIMD_Arrangement T, Register Xs) + { + starti; + assert(T != T1D, "reserved encoding"); + f(0,31), f((int)T & 1, 30), f(0b001110000, 29, 21); + f((1 << (T >> 1)), 20, 16), f(0b000011, 15, 10), rf(Xs, 5), rf(Vd, 0); + } + + void dup(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, int index = 0) + { + starti; + assert(T != T1D, "reserved encoding"); + f(0, 31), f((int)T & 1, 30), f(0b001110000, 29, 21); + f(((1 << (T >> 1)) | (index << ((T >> 1) + 1))), 20, 16); + f(0b000001, 15, 10), rf(Vn, 5), rf(Vd, 0); + } + // CRC32 instructions #define INSN(NAME, sf, sz) \ void NAME(Register Rd, Register Rn, Register Rm) { \ starti; \ f(sf, 31), f(0b0011010110, 30, 21), f(0b0100, 15, 12), f(sz, 11, 10); \
< prev index next >