|
1 | 1 | /*
|
2 |
| - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * Copyright (c) 2014, 2024, Red Hat Inc. All rights reserved.
|
4 | 4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
5 | 5 | *
|
@@ -287,6 +287,11 @@ class Instruction_aarch64 {
|
287 | 287 | f(r->raw_encoding(), lsb + 4, lsb);
|
288 | 288 | }
|
289 | 289 |
|
| 290 | + //<0-15>reg: As `rf(FloatRegister)`, but only the lower 16 FloatRegisters are allowed. |
| 291 | + void lrf(FloatRegister r, int lsb) { |
| 292 | + f(r->raw_encoding(), lsb + 3, lsb); |
| 293 | + } |
| 294 | + |
290 | 295 | void prf(PRegister r, int lsb) {
|
291 | 296 | f(r->raw_encoding(), lsb + 3, lsb);
|
292 | 297 | }
|
@@ -765,6 +770,7 @@ class Assembler : public AbstractAssembler {
|
765 | 770 | #define f current_insn.f
|
766 | 771 | #define sf current_insn.sf
|
767 | 772 | #define rf current_insn.rf
|
| 773 | +#define lrf current_insn.lrf |
768 | 774 | #define srf current_insn.srf
|
769 | 775 | #define zrf current_insn.zrf
|
770 | 776 | #define prf current_insn.prf
|
@@ -1590,6 +1596,16 @@ class Assembler : public AbstractAssembler {
|
1590 | 1596 |
|
1591 | 1597 | #undef INSN
|
1592 | 1598 |
|
| 1599 | + // Load/store a register, but with a BasicType parameter. Loaded signed integer values are |
| 1600 | + // extended to 64 bits. |
| 1601 | + void load(Register Rt, const Address &adr, BasicType bt) { |
| 1602 | + int op = (is_signed_subword_type(bt) || bt == T_INT) ? 0b10 : 0b01; |
| 1603 | + ld_st2(Rt, adr, exact_log2(type2aelembytes(bt)), op); |
| 1604 | + } |
| 1605 | + void store(Register Rt, const Address &adr, BasicType bt) { |
| 1606 | + ld_st2(Rt, adr, exact_log2(type2aelembytes(bt)), 0b00); |
| 1607 | + } |
| 1608 | + |
1593 | 1609 | /* SIMD extensions
|
1594 | 1610 | *
|
1595 | 1611 | * We just use FloatRegister in the following. They are exactly the same
|
@@ -2587,6 +2603,7 @@ template<typename R, typename... Rx>
|
2587 | 2603 | INSN(addpv, 0, 0b101111, true); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S, T2D
|
2588 | 2604 | INSN(smullv, 0, 0b110000, false); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S
|
2589 | 2605 | INSN(umullv, 1, 0b110000, false); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S
|
| 2606 | + INSN(smlalv, 0, 0b100000, false); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S |
2590 | 2607 | INSN(umlalv, 1, 0b100000, false); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S
|
2591 | 2608 | INSN(maxv, 0, 0b011001, false); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S
|
2592 | 2609 | INSN(minv, 0, 0b011011, false); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S
|
@@ -2860,6 +2877,28 @@ template<typename R, typename... Rx>
|
2860 | 2877 | // FMULX - Vector - Scalar
|
2861 | 2878 | INSN(fmulxvs, 1, 0b1001);
|
2862 | 2879 |
|
| 2880 | +#undef INSN |
| 2881 | + |
| 2882 | +#define INSN(NAME, op1, op2) \ |
| 2883 | + void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm, int index) { \ |
| 2884 | + starti; \ |
| 2885 | + assert(T == T4H || T == T8H || T == T2S || T == T4S, "invalid arrangement"); \ |
| 2886 | + assert(index >= 0 && \ |
| 2887 | + ((T == T2S && index <= 1) || (T != T2S && index <= 3) || (T == T8H && index <= 7)), \ |
| 2888 | + "invalid index"); \ |
| 2889 | + assert((T != T4H && T != T8H) || Vm->encoding() < 16, "invalid source SIMD&FP register"); \ |
| 2890 | + f(0, 31), f((int)T & 1, 30), f(op1, 29), f(0b01111, 28, 24); \ |
| 2891 | + if (T == T4H || T == T8H) { \ |
| 2892 | + f(0b01, 23, 22), f(index & 0b11, 21, 20), lrf(Vm, 16), f(index >> 2 & 1, 11); \ |
| 2893 | + } else { \ |
| 2894 | + f(0b10, 23, 22), f(index & 1, 21), rf(Vm, 16), f(index >> 1, 11); \ |
| 2895 | + } \ |
| 2896 | + f(op2, 15, 12), f(0, 10), rf(Vn, 5), rf(Vd, 0); \ |
| 2897 | + } |
| 2898 | + |
| 2899 | + // MUL - Vector - Scalar |
| 2900 | + INSN(mulvs, 0, 0b1000); |
| 2901 | + |
2863 | 2902 | #undef INSN
|
2864 | 2903 |
|
2865 | 2904 | // Floating-point Reciprocal Estimate
|
@@ -3023,6 +3062,33 @@ template<typename R, typename... Rx>
|
3023 | 3062 | umov(Xd, Vn, T, index);
|
3024 | 3063 | }
|
3025 | 3064 |
|
| 3065 | + protected: |
| 3066 | + void _xaddwv(bool is_unsigned, FloatRegister Vd, FloatRegister Vn, SIMD_Arrangement Ta, |
| 3067 | + FloatRegister Vm, SIMD_Arrangement Tb) { |
| 3068 | + starti; |
| 3069 | + assert((Tb >> 1) + 1 == (Ta >> 1), "Incompatible arrangement"); |
| 3070 | + f(0, 31), f((int)Tb & 1, 30), f(is_unsigned ? 1 : 0, 29), f(0b01110, 28, 24); |
| 3071 | + f((int)(Ta >> 1) - 1, 23, 22), f(1, 21), rf(Vm, 16), f(0b000100, 15, 10), rf(Vn, 5), rf(Vd, 0); |
| 3072 | + } |
| 3073 | + |
| 3074 | + public: |
| 3075 | +#define INSN(NAME, assertion, is_unsigned) \ |
| 3076 | + void NAME(FloatRegister Vd, FloatRegister Vn, SIMD_Arrangement Ta, FloatRegister Vm, \ |
| 3077 | + SIMD_Arrangement Tb) { \ |
| 3078 | + assert((assertion), "invalid arrangement"); \ |
| 3079 | + _xaddwv(is_unsigned, Vd, Vn, Ta, Vm, Tb); \ |
| 3080 | + } |
| 3081 | + |
| 3082 | +public: |
| 3083 | + |
| 3084 | + INSN(uaddwv, Tb == T8B || Tb == T4H || Tb == T2S, /*is_unsigned*/true) |
| 3085 | + INSN(uaddwv2, Tb == T16B || Tb == T8H || Tb == T4S, /*is_unsigned*/true) |
| 3086 | + INSN(saddwv, Tb == T8B || Tb == T4H || Tb == T2S, /*is_unsigned*/false) |
| 3087 | + INSN(saddwv2, Tb == T16B || Tb == T8H || Tb == T4S, /*is_unsigned*/false) |
| 3088 | + |
| 3089 | +#undef INSN |
| 3090 | + |
| 3091 | + |
3026 | 3092 | private:
|
3027 | 3093 | void _pmull(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, FloatRegister Vm, SIMD_Arrangement Tb) {
|
3028 | 3094 | starti;
|
|
1 commit comments
openjdk-notifier[bot] commentedon Nov 5, 2024
Review
Issues