diff options
author | Victor Khimenko <khim@google.com> | 2024-02-26 17:43:53 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2024-02-26 17:43:53 +0000 |
commit | 071b44000419f84375562b8c2d4c84ad4638fdbe (patch) | |
tree | b2472721da4291511da642a84543c79bf267d788 | |
parent | 21333e8f6f8c4fb56d78d2c865a8c45396c891c7 (diff) | |
parent | 42638c1568774aeacb53719568699256eb4cdc2d (diff) | |
download | binary_translation-071b44000419f84375562b8c2d4c84ad4638fdbe.tar.gz |
Merge "Add boilerplate to decode and process vector FP instructions." into main am: 42638c1568
Original change: https://android-review.googlesource.com/c/platform/frameworks/libs/binary_translation/+/2973380
Change-Id: Ie82563afd32e6802db4af3ada5e2a3831fbfe7db
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | decoder/include/berberis/decoder/riscv64/decoder.h | 125 | ||||
-rw-r--r-- | decoder/include/berberis/decoder/riscv64/semantics_player.h | 9 | ||||
-rw-r--r-- | interpreter/riscv64/interpreter.cc | 60 |
3 files changed, 178 insertions, 16 deletions
diff --git a/decoder/include/berberis/decoder/riscv64/decoder.h b/decoder/include/berberis/decoder/riscv64/decoder.h index 7343987a..39c1ad55 100644 --- a/decoder/include/berberis/decoder/riscv64/decoder.h +++ b/decoder/include/berberis/decoder/riscv64/decoder.h @@ -241,6 +241,89 @@ class Decoder { kVlm = 0b01011, }; + enum class VOpFVfOpcode : uint8_t { + kVfaddvf = 0b000000, + kVfsubvf = 0b000010, + kVfminvf = 0b000100, + kVfmaxvf = 0b000110, + kVfsgnjvf = 0b001000, + kVfsgnjnvf = 0b001001, + kVfsgnjxvf = 0b001010, + kVfslide1upvf = 0b001110, + kVfslide1downvf = 0b001111, + kVfmvsf = 0b010000, + kVfmergevf = 0b010111, // Also kVfmv.vf + kVmfeqvf = 0b011000, + kVmflevf = 0b011001, + kVmfltvf = 0b011011, + kVmfnevf = 0b011100, + kVmfgtvf = 0b011101, + kVmfgevf = 0b011111, + kVfdivvf = 0b100000, + kVfrdivvf = 0b100001, + kVfmulvf = 0b100100, + kVfrsubvf = 0b100111, + kVfmaddvf = 0b101000, + kVfnmaddvf = 0b101001, + kVfmsubvf = 0b101010, + kVfnmsubvf = 0b101011, + kVfmaccvf = 0b101100, + kVfnmaccvf = 0b101101, + kVfmsacvf = 0b101110, + kVfnmsacvf = 0b101111, + kVfwaddvf = 0b110000, + kVfwsubvf = 0b110010, + kVfwaddwf = 0b110100, + kVfwsubwf = 0b110110, + kVfwmulvf = 0b111000, + kVfwmaccvf = 0b111100, + kVfwnmaccvf = 0b111100, + kVfwmsacvf = 0b111100, + kVfwnmsacvf = 0b111111, + }; + + enum class VOpFVvOpcode : uint8_t { + kVfaddvv = 0b000000, + kVfredusumvv = 0b000001, + kVfsubvv = 0b000010, + kVfredosumvv = 0b000011, + kVfminvv = 0b000100, + kVfredminvv = 0b000101, + kVfmaxvv = 0b000110, + kVfredmaxvv = 0b000111, + kVfsgnjvv = 0b001000, + kVfsgnjnvv = 0b001001, + kVfsgnjxvv = 0b001010, + kVfmvfs = 0b010000, + kVfcvtXX = 0b010010, + kVXXXv = 010011, // Vfsqrt.v/Vfrsqrt7.v/Vfrec7.v/Vfclass.v + kVmfeqvv = 0b011000, + kVmflevv = 0b011001, + kVmfltvv = 0b011011, + kVmfnevv = 0b011100, + kVfdivvv = 0b100000, + kVfmulvv = 0b100100, + kVfmaddvv = 0b101000, + kVfnmaddvv = 0b101001, + kVfmsubvv = 0b101010, + kVfnmsubvv = 0b101011, + kVfmaccvv = 0b101100, + kVfnmaccvv = 0b101101, + kVfmsacvv = 0b101110, + kVfnmsacvv = 0b101111, + kVfwaddvv = 0b110000, + kVfwredusumvv = 0b110001, + kVfwsubvv = 0b110010, + kVfwredosumvv = 0b110011, + kVfwaddwv = 0b110100, + kVfwsubwv = 0b110110, + kVfwmulvv = 0b111000, + kVfwmaccvv = 0b111100, + kVfwnmaccvv = 0b111100, + kVfwmsacvv = 0b111100, + kVfwnmsacvv = 0b111111, + }; + enum class VOpIViOpcode : uint8_t { kVaddvi = 0b000000, kVrsubvi = 0b000011, @@ -252,7 +335,7 @@ class Decoder { kVslidedownvi = 0b001111, kVadcvi = 0b010000, kVmadcvi = 0b010001, - kVmergevi = 0b010111, + kVmergevi = 0b010111, // Also kVmv.vi kVmseqvi = 0b011000, kVmsnevi = 0b011001, kVmsleuvi = 0b011100, @@ -289,7 +372,7 @@ class Decoder { kVmadcvv = 0b010001, kVsbcvv = 0b010010, kVmsbcvv = 0b010011, - kVmergevv = 0b010111, + kVmergevv = 0b010111, // Also kVmv.vv kVmseqvv = 0b011000, kVmsnevv = 0b011001, kVmsltuvv = 0b011010, @@ -366,7 +449,7 @@ class Decoder { kVmadcvx = 0b010001, kVsbcvx = 0b010010, kVmsbcvx = 0b010011, - kVmergevx = 0b010111, + kVmergevx = 0b010111, // Also Vmv.vx kVmseqvx = 0b011000, kVmsnevx = 0b011001, kVmsltuvx = 0b011010, @@ -699,6 +782,22 @@ class Decoder { uint8_t src; }; + struct VOpFVfArgs { + VOpFVfOpcode opcode; + bool vm; + uint8_t dst; + uint8_t src1; + uint8_t src2; + }; + + struct VOpFVvArgs { + VOpFVvOpcode opcode; + bool vm; + uint8_t dst; + uint8_t src1; + uint8_t src2; + }; + struct VOpIViArgs { VOpIViOpcode opcode; bool vm; @@ -1940,6 +2039,16 @@ class Decoder { }; return insn_consumer_->OpVector(args); } + case 0b001: { + const VOpFVvArgs args = { + .opcode = VOpFVvOpcode{opcode}, + .vm = vm, + .dst = dst, + .src1 = src1, + .src2 = src2, + }; + return insn_consumer_->OpVector(args); + } case 0b010: { const VOpMVvArgs args = { .opcode = VOpMVvOpcode{opcode}, @@ -1970,6 +2079,16 @@ class Decoder { }; return insn_consumer_->OpVector(args); } + case 0b101: { + const VOpFVfArgs args = { + .opcode = VOpFVfOpcode{opcode}, + .vm = vm, + .dst = dst, + .src1 = src1, + .src2 = src2, + }; + return insn_consumer_->OpVector(args); + } case 0b110: { const VOpMVxArgs args = { .opcode = VOpMVxOpcode{opcode}, diff --git a/decoder/include/berberis/decoder/riscv64/semantics_player.h b/decoder/include/berberis/decoder/riscv64/semantics_player.h index 44a6a659..2e948f69 100644 --- a/decoder/include/berberis/decoder/riscv64/semantics_player.h +++ b/decoder/include/berberis/decoder/riscv64/semantics_player.h @@ -809,6 +809,15 @@ class SemanticsPlayer { listener_->OpVector(args, arg2); } + void OpVector(const typename Decoder::VOpFVfArgs& args) { + // Note: we don't have information here to chosee between GetFRegAndUnboxNan<Float32> and + // GetFRegAndUnboxNan<Float64> because that depends on vtype. + FpRegister arg2 = GetFpReg(args.src2); + listener_->OpVector(args, arg2); + } + + void OpVector(const typename Decoder::VOpFVvArgs& args) { listener_->OpVector(args); } + void OpVector(const typename Decoder::VOpIViArgs& args) { listener_->OpVector(args); } void OpVector(const typename Decoder::VOpIVvArgs& args) { listener_->OpVector(args); } diff --git a/interpreter/riscv64/interpreter.cc b/interpreter/riscv64/interpreter.cc index 83a22716..0325e0e6 100644 --- a/interpreter/riscv64/interpreter.cc +++ b/interpreter/riscv64/interpreter.cc @@ -559,19 +559,37 @@ class Interpreter { default: return Unimplemented(); } - } - VectorRegisterGroupMultiplier vlmul = static_cast<VectorRegisterGroupMultiplier>(vtype & 0b111); - switch (static_cast<VectorSelectElementWidth>((vtype >> 3) & 0b111)) { - case VectorSelectElementWidth::k8bit: - return OpVector<UInt8>(args, vlmul, vtype, extra_args...); - case VectorSelectElementWidth::k16bit: - return OpVector<UInt16>(args, vlmul, vtype, extra_args...); - case VectorSelectElementWidth::k32bit: - return OpVector<UInt32>(args, vlmul, vtype, extra_args...); - case VectorSelectElementWidth::k64bit: - return OpVector<UInt64>(args, vlmul, vtype, extra_args...); - default: - return Unimplemented(); + } else { + VectorRegisterGroupMultiplier vlmul = static_cast<VectorRegisterGroupMultiplier>(vtype & 0x7); + if constexpr (std::is_same_v<VOpArgs, Decoder::VOpFVfArgs> || + std::is_same_v<VOpArgs, Decoder::VOpFVvArgs>) { + switch (static_cast<VectorSelectElementWidth>((vtype >> 3) & 0b111)) { + case VectorSelectElementWidth::k32bit: + return OpVector<Float32>( + args, + vlmul, + vtype, + std::get<0>(intrinsics::UnboxNan<Float32>(bit_cast<Float64>(extra_args)))...); + case VectorSelectElementWidth::k64bit: + // Note: if arguments are 64bit floats then we don't need to do any unboxing. + return OpVector<Float64>(args, vlmul, vtype, bit_cast<Float64>(extra_args)...); + default: + return Unimplemented(); + } + } else { + switch (static_cast<VectorSelectElementWidth>((vtype >> 3) & 0b111)) { + case VectorSelectElementWidth::k8bit: + return OpVector<UInt8>(args, vlmul, vtype, extra_args...); + case VectorSelectElementWidth::k16bit: + return OpVector<UInt16>(args, vlmul, vtype, extra_args...); + case VectorSelectElementWidth::k32bit: + return OpVector<UInt32>(args, vlmul, vtype, extra_args...); + case VectorSelectElementWidth::k64bit: + return OpVector<UInt64>(args, vlmul, vtype, extra_args...); + default: + return Unimplemented(); + } + } } } @@ -1155,6 +1173,22 @@ class Interpreter { } template <typename ElementType, VectorRegisterGroupMultiplier vlmul, TailProcessing vta, auto vma> + void OpVector(const Decoder::VOpFVfArgs& args, ElementType /*arg2*/) { + switch (args.opcode) { + default: + Unimplemented(); + } + } + + template <typename ElementType, VectorRegisterGroupMultiplier vlmul, TailProcessing vta, auto vma> + void OpVector(const Decoder::VOpFVvArgs& args) { + switch (args.opcode) { + default: + Unimplemented(); + } + } + + template <typename ElementType, VectorRegisterGroupMultiplier vlmul, TailProcessing vta, auto vma> void OpVector(const Decoder::VOpIViArgs& args) { using SignedType = berberis::SignedType<ElementType>; using UnsignedType = berberis::UnsignedType<ElementType>; |