assembler_aarch64.hpp (8210:2a6c4bd248cf) assembler_aarch64.hpp (8462:5b8b5731ca2d)
1/*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.

--- 452 unchanged lines hidden (view full) ---

461 void encode(Instruction_aarch64 *i) const {
462 i->f(0b111, 29, 27);
463 i->srf(_base, 5);
464
465 switch(_mode) {
466 case base_plus_offset:
467 {
468 unsigned size = i->get(31, 30);
1/*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.

--- 452 unchanged lines hidden (view full) ---

461 void encode(Instruction_aarch64 *i) const {
462 i->f(0b111, 29, 27);
463 i->srf(_base, 5);
464
465 switch(_mode) {
466 case base_plus_offset:
467 {
468 unsigned size = i->get(31, 30);
469 if (i->get(26, 26) && i->get(23, 23)) {
470 // SIMD Q Type - Size = 128 bits
471 assert(size == 0, "bad size");
472 size = 0b100;
473 }
469 unsigned mask = (1 << size) - 1;
470 if (_offset < 0 || _offset & mask)
471 {
472 i->f(0b00, 25, 24);
473 i->f(0, 21), i->f(0b00, 11, 10);
474 i->sf(_offset, 20, 12);
475 } else {
476 i->f(0b01, 25, 24);

--- 1406 unchanged lines hidden (view full) ---

1883 */
1884 public:
1885
1886 enum SIMD_Arrangement {
1887 T8B, T16B, T4H, T8H, T2S, T4S, T1D, T2D
1888 };
1889
1890 enum SIMD_RegVariant {
474 unsigned mask = (1 << size) - 1;
475 if (_offset < 0 || _offset & mask)
476 {
477 i->f(0b00, 25, 24);
478 i->f(0, 21), i->f(0b00, 11, 10);
479 i->sf(_offset, 20, 12);
480 } else {
481 i->f(0b01, 25, 24);

--- 1406 unchanged lines hidden (view full) ---

1888 */
1889 public:
1890
1891 enum SIMD_Arrangement {
1892 T8B, T16B, T4H, T8H, T2S, T4S, T1D, T2D
1893 };
1894
1895 enum SIMD_RegVariant {
1891 S32, D64, Q128
1896 B, H, S, D, Q
1892 };
1893
1897 };
1898
1899#define INSN(NAME, op) \
1900 void NAME(FloatRegister Rt, SIMD_RegVariant T, const Address &adr) { \
1901 ld_st2((Register)Rt, adr, (int)T & 3, op + ((T==Q) ? 0b10:0b00), 1); \
1902 } \
1894
1903
1904 INSN(ldr, 1);
1905 INSN(str, 0);
1906
1907#undef INSN
1908
1895 private:
1896
1897 void ld_st(FloatRegister Vt, SIMD_Arrangement T, Register Xn, int op1, int op2) {
1898 starti;
1899 f(0,31), f((int)T & 1, 30);
1900 f(op1, 29, 21), f(0, 20, 16), f(op2, 15, 12);
1901 f((int)T >> 1, 11, 10), rf(Xn, 5), rf(Vt, 0);
1902 }

--- 89 unchanged lines hidden (view full) ---

1992#define INSN(NAME, opc) \
1993 void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm) { \
1994 starti; \
1995 assert(T == T8B || T == T16B, "must be T8B or T16B"); \
1996 f(0, 31), f((int)T & 1, 30), f(opc, 29, 21); \
1997 rf(Vm, 16), f(0b000111, 15, 10), rf(Vn, 5), rf(Vd, 0); \
1998 }
1999
1909 private:
1910
1911 void ld_st(FloatRegister Vt, SIMD_Arrangement T, Register Xn, int op1, int op2) {
1912 starti;
1913 f(0,31), f((int)T & 1, 30);
1914 f(op1, 29, 21), f(0, 20, 16), f(op2, 15, 12);
1915 f((int)T >> 1, 11, 10), rf(Xn, 5), rf(Vt, 0);
1916 }

--- 89 unchanged lines hidden (view full) ---

2006#define INSN(NAME, opc) \
2007 void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm) { \
2008 starti; \
2009 assert(T == T8B || T == T16B, "must be T8B or T16B"); \
2010 f(0, 31), f((int)T & 1, 30), f(opc, 29, 21); \
2011 rf(Vm, 16), f(0b000111, 15, 10), rf(Vn, 5), rf(Vd, 0); \
2012 }
2013
2000 INSN(eor, 0b101110001);
2001 INSN(orr, 0b001110101);
2014 INSN(eor, 0b101110001);
2015 INSN(orr, 0b001110101);
2002 INSN(andr, 0b001110001);
2016 INSN(andr, 0b001110001);
2003 INSN(bic, 0b001110011);
2004 INSN(bif, 0b101110111);
2005 INSN(bit, 0b101110101);
2006 INSN(bsl, 0b101110011);
2007 INSN(orn, 0b001110111);
2017 INSN(bic, 0b001110011);
2018 INSN(bif, 0b101110111);
2019 INSN(bit, 0b101110101);
2020 INSN(bsl, 0b101110011);
2021 INSN(orn, 0b001110111);
2008
2009#undef INSN
2010
2022
2023#undef INSN
2024
2011#define INSN(NAME, opc) \
2025#define INSN(NAME, opc, opc2) \
2012 void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm) { \
2013 starti; \
2014 f(0, 31), f((int)T & 1, 30), f(opc, 29), f(0b01110, 28, 24); \
2026 void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm) { \
2027 starti; \
2028 f(0, 31), f((int)T & 1, 30), f(opc, 29), f(0b01110, 28, 24); \
2015 f((int)T >> 1, 23, 22), f(1, 21), rf(Vm, 16), f(0b100001, 15, 10); \
2029 f((int)T >> 1, 23, 22), f(1, 21), rf(Vm, 16), f(opc2, 15, 10); \
2016 rf(Vn, 5), rf(Vd, 0); \
2017 }
2018
2030 rf(Vn, 5), rf(Vd, 0); \
2031 }
2032
2019 INSN(addv, 0);
2020 INSN(subv, 1);
2033 INSN(addv, 0, 0b100001);
2034 INSN(subv, 1, 0b100001);
2035 INSN(mulv, 0, 0b100111);
2036 INSN(sshl, 0, 0b010001);
2037 INSN(ushl, 1, 0b010001);
2021
2022#undef INSN
2023
2038
2039#undef INSN
2040
2041#define INSN(NAME, opc, opc2) \
2042 void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn) { \
2043 starti; \
2044 f(0, 31), f((int)T & 1, 30), f(opc, 29), f(0b01110, 28, 24); \
2045 f((int)T >> 1, 23, 22), f(opc2, 21, 10); \
2046 rf(Vn, 5), rf(Vd, 0); \
2047 }
2048
2049 INSN(absr, 0, 0b100000101110);
2050 INSN(negr, 1, 0b100000101110);
2051 INSN(notr, 1, 0b100000010110);
2052 INSN(addv, 0, 0b110001101110);
2053
2054#undef INSN
2055
2056#define INSN(NAME, op0, cmode0) \
2057 void NAME(FloatRegister Vd, SIMD_Arrangement T, unsigned imm8, unsigned lsl = 0) { \
2058 unsigned cmode = cmode0; \
2059 unsigned op = op0; \
2060 starti; \
2061 assert(lsl == 0 || \
2062 ((T == T4H || T == T8H) && lsl == 8) || \
2063 ((T == T2S || T == T4S) && ((lsl >> 3) < 4)), "invalid shift"); \
2064 cmode |= lsl >> 2; \
2065 if (T == T4H || T == T8H) cmode |= 0b1000; \
2066 if (!(T == T4H || T == T8H || T == T2S || T == T4S)) { \
2067 assert(op == 0 && cmode0 == 0, "must be MOVI"); \
2068 cmode = 0b1110; \
2069 if (T == T1D || T == T2D) op = 1; \
2070 } \
2071 f(0, 31), f((int)T & 1, 30), f(op, 29), f(0b0111100000, 28, 19); \
2072 f(imm8 >> 5, 18, 16), f(cmode, 15, 12), f(0x01, 11, 10), f(imm8 & 0b11111, 9, 5); \
2073 rf(Vd, 0); \
2074 }
2075
2076 INSN(movi, 0, 0);
2077 INSN(orri, 0, 1);
2078 INSN(mvni, 1, 0);
2079 INSN(bici, 1, 1);
2080
2081#undef INSN
2082
2083#define INSN(NAME, op1, op2, op3) \
2084 void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm) { \
2085 starti; \
2086 assert(T == T2S || T == T4S || T == T2D, "invalid arrangement"); \
2087 f(0, 31), f((int)T & 1, 30), f(op1, 29), f(0b01110, 28, 24), f(op2, 23); \
2088 f(T==T2D ? 1:0, 22); f(1, 21), rf(Vm, 16), f(op3, 15, 10), rf(Vn, 5), rf(Vd, 0); \
2089 }
2090
2091 INSN(fadd, 0, 0, 0b110101);
2092 INSN(fdiv, 1, 0, 0b111111);
2093 INSN(fmul, 1, 0, 0b110111);
2094 INSN(fsub, 0, 1, 0b110101);
2095
2096#undef INSN
2097
2024#define INSN(NAME, opc) \
2025 void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm) { \
2026 starti; \
2027 assert(T == T4S, "arrangement must be T4S"); \
2028 f(0b01011110000, 31, 21), rf(Vm, 16), f(opc, 15, 10), rf(Vn, 5), rf(Vd, 0); \
2029 }
2030
2031 INSN(sha1c, 0b000000);

--- 27 unchanged lines hidden (view full) ---

2059
2060 INSN(aese, 0b0100111000101000010010);
2061 INSN(aesd, 0b0100111000101000010110);
2062 INSN(aesmc, 0b0100111000101000011010);
2063 INSN(aesimc, 0b0100111000101000011110);
2064
2065#undef INSN
2066
2098#define INSN(NAME, opc) \
2099 void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm) { \
2100 starti; \
2101 assert(T == T4S, "arrangement must be T4S"); \
2102 f(0b01011110000, 31, 21), rf(Vm, 16), f(opc, 15, 10), rf(Vn, 5), rf(Vd, 0); \
2103 }
2104
2105 INSN(sha1c, 0b000000);

--- 27 unchanged lines hidden (view full) ---

2133
2134 INSN(aese, 0b0100111000101000010010);
2135 INSN(aesd, 0b0100111000101000010110);
2136 INSN(aesmc, 0b0100111000101000011010);
2137 INSN(aesimc, 0b0100111000101000011110);
2138
2139#undef INSN
2140
2067 void shl(FloatRegister Vd, FloatRegister Vn, SIMD_Arrangement T, int shift){
2141 void ins(FloatRegister Vd, SIMD_RegVariant T, FloatRegister Vn, int didx, int sidx) {
2068 starti;
2142 starti;
2069 /* The encodings for the immh:immb fields (bits 22:16) are
2070 * 0001 xxx 8B/16B, shift = xxx
2071 * 001x xxx 4H/8H, shift = xxxx
2072 * 01xx xxx 2S/4S, shift = xxxxx
2073 * 1xxx xxx 1D/2D, shift = xxxxxx (1D is RESERVED)
2074 */
2075 assert((1 << ((T>>1)+3)) > shift, "Invalid Shift value");
2076 f(0, 31), f(T & 1, 30), f(0b0011110, 29, 23), f((1 << ((T>>1)+3))|shift, 22, 16);
2077 f(0b010101, 15, 10), rf(Vn, 5), rf(Vd, 0);
2143 assert(T != Q, "invalid register variant");
2144 f(0b01101110000, 31, 21), f(((didx<<1)|1)<<(int)T, 20, 16), f(0, 15);
2145 f(sidx<<(int)T, 14, 11), f(1, 10), rf(Vn, 5), rf(Vd, 0);
2078 }
2079
2146 }
2147
2148 void umov(Register Rd, FloatRegister Vn, SIMD_RegVariant T, int idx) {
2149 starti;
2150 f(0, 31), f(T==D ? 1:0, 30), f(0b001110000, 29, 21);
2151 f(((idx<<1)|1)<<(int)T, 20, 16), f(0b001111, 15, 10);
2152 rf(Vn, 5), rf(Rd, 0);
2153 }
2154
2155#define INSN(NAME, opc, opc2) \
2156 void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, int shift){ \
2157 starti; \
2158 /* The encodings for the immh:immb fields (bits 22:16) are \
2159 * 0001 xxx 8B/16B, shift = xxx \
2160 * 001x xxx 4H/8H, shift = xxxx \
2161 * 01xx xxx 2S/4S, shift = xxxxx \
2162 * 1xxx xxx 1D/2D, shift = xxxxxx (1D is RESERVED) \
2163 */ \
2164 assert((1 << ((T>>1)+3)) > shift, "Invalid Shift value"); \
2165 f(0, 31), f(T & 1, 30), f(opc, 29), f(0b011110, 28, 23), \
2166 f((1 << ((T>>1)+3))|shift, 22, 16); f(opc2, 15, 10), rf(Vn, 5), rf(Vd, 0); \
2167 }
2168
2169 INSN(shl, 0, 0b010101);
2170 INSN(sshr, 0, 0b000001);
2171 INSN(ushr, 1, 0b000001);
2172
2173#undef INSN
2174
2080 void ushll(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb, int shift) {
2081 starti;
2082 /* The encodings for the immh:immb fields (bits 22:16) are
2083 * 0001 xxx 8H, 8B/16b shift = xxx
2084 * 001x xxx 4S, 4H/8H shift = xxxx
2085 * 01xx xxx 2D, 2S/4S shift = xxxxx
2086 * 1xxx xxx RESERVED
2087 */

--- 56 unchanged lines hidden (view full) ---

2144 {
2145 starti;
2146 assert(T <= T8H, "must be one of T8B, T16B, T4H, T8H");
2147 f(0, 31), f((int)T & 1, 30), f(0b101110, 29, 24);
2148 f(T <= T16B ? 0b00 : 0b01, 23, 22), f(0b100000000010, 21, 10);
2149 rf(Vn, 5), rf(Vd, 0);
2150 }
2151
2175 void ushll(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb, int shift) {
2176 starti;
2177 /* The encodings for the immh:immb fields (bits 22:16) are
2178 * 0001 xxx 8H, 8B/16b shift = xxx
2179 * 001x xxx 4S, 4H/8H shift = xxxx
2180 * 01xx xxx 2D, 2S/4S shift = xxxxx
2181 * 1xxx xxx RESERVED
2182 */

--- 56 unchanged lines hidden (view full) ---

2239 {
2240 starti;
2241 assert(T <= T8H, "must be one of T8B, T16B, T4H, T8H");
2242 f(0, 31), f((int)T & 1, 30), f(0b101110, 29, 24);
2243 f(T <= T16B ? 0b00 : 0b01, 23, 22), f(0b100000000010, 21, 10);
2244 rf(Vn, 5), rf(Vd, 0);
2245 }
2246
2247 void dup(FloatRegister Vd, SIMD_Arrangement T, Register Xs)
2248 {
2249 starti;
2250 assert(T != T1D, "reserved encoding");
2251 f(0,31), f((int)T & 1, 30), f(0b001110000, 29, 21);
2252 f((1 << (T >> 1)), 20, 16), f(0b000011, 15, 10), rf(Xs, 5), rf(Vd, 0);
2253 }
2254
2255 void dup(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, int index = 0)
2256 {
2257 starti;
2258 assert(T != T1D, "reserved encoding");
2259 f(0, 31), f((int)T & 1, 30), f(0b001110000, 29, 21);
2260 f(((1 << (T >> 1)) | (index << ((T >> 1) + 1))), 20, 16);
2261 f(0b000001, 15, 10), rf(Vn, 5), rf(Vd, 0);
2262 }
2263
2152 // CRC32 instructions
2153#define INSN(NAME, sf, sz) \
2154 void NAME(Register Rd, Register Rn, Register Rm) { \
2155 starti; \
2156 f(sf, 31), f(0b0011010110, 30, 21), f(0b0100, 15, 12), f(sz, 11, 10); \
2157 rf(Rm, 16), rf(Rn, 5), rf(Rd, 0); \
2158 }
2159

--- 181 unchanged lines hidden ---
2264 // CRC32 instructions
2265#define INSN(NAME, sf, sz) \
2266 void NAME(Register Rd, Register Rn, Register Rm) { \
2267 starti; \
2268 f(sf, 31), f(0b0011010110, 30, 21), f(0b0100, 15, 12), f(sz, 11, 10); \
2269 rf(Rm, 16), rf(Rn, 5), rf(Rd, 0); \
2270 }
2271

--- 181 unchanged lines hidden ---