2223 f(0, 31), f((T >= T1D) ? 1:0, 30), f(0b001110000, 29, 21); |
2223 f(0, 31), f((T >= T1D) ? 1:0, 30), f(0b001110000, 29, 21); |
2224 f(((1 << (T >> 1)) | (index << ((T >> 1) + 1))), 20, 16); |
2224 f(((1 << (T >> 1)) | (index << ((T >> 1) + 1))), 20, 16); |
2225 f(0b001111, 15, 10), rf(Vn, 5), rf(Xd, 0); |
2225 f(0b001111, 15, 10), rf(Vn, 5), rf(Xd, 0); |
2226 } |
2226 } |
2227 |
2227 |
2228 // We do not handle the 1Q arrangement. |
|
2229 void pmull(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, FloatRegister Vm, SIMD_Arrangement Tb) { |
2228 void pmull(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, FloatRegister Vm, SIMD_Arrangement Tb) { |
2230 starti; |
2229 starti; |
2231 assert(Ta == T8H && (Tb == T8B || Tb == T16B), "Invalid Size specifier"); |
2230 assert((Ta == T1Q && (Tb == T1D || Tb == T2D)) || |
2232 f(0, 31), f(Tb & 1, 30), f(0b001110001, 29, 21), rf(Vm, 16), f(0b111000, 15, 10); |
2231 (Ta == T8H && (Tb == T8B || Tb == T16B)), "Invalid Size specifier"); |
2233 rf(Vn, 5), rf(Vd, 0); |
2232 int size = (Ta == T1Q) ? 0b11 : 0b00; |
|
2233 f(0, 31), f(Tb & 1, 30), f(0b001110, 29, 24), f(size, 23, 22); |
|
2234 f(1, 21), rf(Vm, 16), f(0b111000, 15, 10), rf(Vn, 5), rf(Vd, 0); |
2234 } |
2235 } |
2235 void pmull2(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, FloatRegister Vm, SIMD_Arrangement Tb) { |
2236 void pmull2(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, FloatRegister Vm, SIMD_Arrangement Tb) { |
|
2237 assert(Tb == T2D || Tb == T16B, "pmull2 assumes T2D or T16B as the second size specifier"); |
2236 pmull(Vd, Ta, Vn, Vm, Tb); |
2238 pmull(Vd, Ta, Vn, Vm, Tb); |
2237 } |
2239 } |
2238 |
2240 |
2239 void uqxtn(FloatRegister Vd, SIMD_Arrangement Tb, FloatRegister Vn, SIMD_Arrangement Ta) { |
2241 void uqxtn(FloatRegister Vd, SIMD_Arrangement Tb, FloatRegister Vn, SIMD_Arrangement Ta) { |
2240 starti; |
2242 starti; |
2241 int size_b = (int)Tb >> 1; |
2243 int size_b = (int)Tb >> 1; |
2242 int size_a = (int)Ta >> 1; |
2244 int size_a = (int)Ta >> 1; |
2243 assert(size_b < 3 && size_b == size_a - 1, "Invalid size specifier"); |
2245 assert(size_b < 3 && size_b == size_a - 1, "Invalid size specifier"); |
2244 f(0, 31), f(Tb & 1, 30), f(0b101110, 29, 24), f(size_b, 23, 22); |
2246 f(0, 31), f(Tb & 1, 30), f(0b101110, 29, 24), f(size_b, 23, 22); |
2245 f(0b100001010010, 21, 10), rf(Vn, 5), rf(Vd, 0); |
2247 f(0b100001010010, 21, 10), rf(Vn, 5), rf(Vd, 0); |
2246 } |
|
2247 |
|
2248 void rev32(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn) |
|
2249 { |
|
2250 starti; |
|
2251 assert(T <= T8H, "must be one of T8B, T16B, T4H, T8H"); |
|
2252 f(0, 31), f((int)T & 1, 30), f(0b101110, 29, 24); |
|
2253 f(T <= T16B ? 0b00 : 0b01, 23, 22), f(0b100000000010, 21, 10); |
|
2254 rf(Vn, 5), rf(Vd, 0); |
|
2255 } |
2248 } |
2256 |
2249 |
2257 void dup(FloatRegister Vd, SIMD_Arrangement T, Register Xs) |
2250 void dup(FloatRegister Vd, SIMD_Arrangement T, Register Xs) |
2258 { |
2251 { |
2259 starti; |
2252 starti; |
2288 INSN(crc32cw, 1, 0, 0b10); |
2281 INSN(crc32cw, 1, 0, 0b10); |
2289 INSN(crc32cx, 1, 1, 0b11); |
2282 INSN(crc32cx, 1, 1, 0b11); |
2290 |
2283 |
2291 #undef INSN |
2284 #undef INSN |
2292 |
2285 |
|
2286 // Table vector lookup |
|
2287 #define INSN(NAME, op) \ |
|
2288 void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, unsigned registers, FloatRegister Vm) { \ |
|
2289 starti; \ |
|
2290 assert(T == T8B || T == T16B, "invalid arrangement"); \ |
|
2291 assert(0 < registers && registers <= 4, "invalid number of registers"); \ |
|
2292 f(0, 31), f((int)T & 1, 30), f(0b001110000, 29, 21), rf(Vm, 16), f(0, 15); \ |
|
2293 f(registers - 1, 14, 13), f(op, 12),f(0b00, 11, 10), rf(Vn, 5), rf(Vd, 0); \ |
|
2294 } |
|
2295 |
|
2296 INSN(tbl, 0); |
|
2297 INSN(tbx, 1); |
|
2298 |
|
2299 #undef INSN |
|
2300 |
|
2301 #define INSN(NAME, U, opcode) \ |
|
2302 void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn) { \ |
|
2303 starti; \ |
|
2304 assert((ASSERTION), MSG); \ |
|
2305 f(0, 31), f((int)T & 1, 30), f(U, 29), f(0b01110, 28, 24); \ |
|
2306 f((int)(T >> 1), 23, 22), f(0b10000, 21, 17), f(opcode, 16, 12); \ |
|
2307 f(0b10, 11, 10), rf(Vn, 5), rf(Vd, 0); \ |
|
2308 } |
|
2309 |
|
2310 #define MSG "invalid arrangement" |
|
2311 |
|
2312 #define ASSERTION (T == T8B || T == T16B || T == T4H || T == T8H || T == T2S || T == T4S) |
|
2313 INSN(rev64, 0, 0b00000); |
|
2314 #undef ASSERTION |
|
2315 |
|
2316 #define ASSERTION (T == T8B || T == T16B || T == T4H || T == T8H) |
|
2317 INSN(rev32, 1, 0b00000); |
|
2318 #undef ASSERTION |
|
2319 |
|
2320 #define ASSERTION (T == T8B || T == T16B) |
|
2321 INSN(rev16, 0, 0b00001); |
|
2322 #undef ASSERTION |
|
2323 |
|
2324 #undef MSG |
|
2325 |
|
2326 #undef INSN |
|
2327 |
|
2328 void ext(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm, int index) |
|
2329 { |
|
2330 starti; |
|
2331 assert(T == T8B || T == T16B, "invalid arrangement"); |
|
2332 assert((T == T8B && index <= 0b0111) || (T == T16B && index <= 0b1111), "Invalid index value"); |
|
2333 f(0, 31), f((int)T & 1, 30), f(0b101110000, 29, 21); |
|
2334 rf(Vm, 16), f(0, 15), f(index, 14, 11); |
|
2335 f(0, 10), rf(Vn, 5), rf(Vd, 0); |
|
2336 } |
2293 |
2337 |
2294 /* Simulator extensions to the ISA |
2338 /* Simulator extensions to the ISA |
2295 |
2339 |
2296 haltsim |
2340 haltsim |
2297 |
2341 |