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