< 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 >