aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Khimenko <khim@google.com>2024-02-26 17:43:53 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2024-02-26 17:43:53 +0000
commit071b44000419f84375562b8c2d4c84ad4638fdbe (patch)
treeb2472721da4291511da642a84543c79bf267d788
parent21333e8f6f8c4fb56d78d2c865a8c45396c891c7 (diff)
parent42638c1568774aeacb53719568699256eb4cdc2d (diff)
downloadbinary_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.h125
-rw-r--r--decoder/include/berberis/decoder/riscv64/semantics_player.h9
-rw-r--r--interpreter/riscv64/interpreter.cc60
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>;