[sve2] Implement floating point multiply add long (vector)
Include fmlalb, fmlalt, fmlslb and fmlslt.
Also, add a feature to the test donkey for generating normal floating-point
numbers rather than random numbers.
Change-Id: I8cb6aa8fd277c6627a8a84067550c0854997c6b1
diff --git a/test/test-donkey.cc b/test/test-donkey.cc
index c391323..858ddd6 100644
--- a/test/test-donkey.cc
+++ b/test/test-donkey.cc
@@ -73,18 +73,22 @@
}
#else
int main(int argc, char **argv) {
- if ((argc != 3) && (argc != 4)) {
+ if ((argc < 3) || (argc > 5)) {
printf(
"Usage: test-donkey <instruction form regex> <number of instructions "
- "to emit in test> "
- "[random_only|initial encoding as hex]\n"
+ "to emit in test> <encoding generation manner> <input data type>\n"
" regex - ECMAScript (C++11) regular expression to match instruction "
"form\n"
- " random_only - use rng only to select new instructions\n"
+ " encoding=random - use rng only to select new instructions\n"
" (can take longer, but gives better coverage for disparate "
"encodings)\n"
- " initial encoding - encoding of first instruction in test, eg. "
- "1234abcd\n");
+ " encoding=`initial hex` - hex encoding of first instruction in test, "
+ "eg. 1234abcd\n"
+ " input data type - used to specify the data type of generating "
+ "input, e.g. input=fp, default set to integer type\n"
+ " command examples :\n"
+ " ./test-donkey \"fml[as]l[bt]\" 50 encoding=random input=fp\n"
+ " ./test-donkey \"fml[as]l[bt]\" 30 input=int\n");
exit(1);
}
@@ -94,12 +98,39 @@
std::string target_re = argv[1];
uint32_t count = static_cast<uint32_t>(strtoul(argv[2], NULL, 10));
uint32_t cmdline_encoding = 0;
- if (argc == 4) {
- if (strcmp(argv[3], "random_only") == 0) {
- random_only = true;
- } else {
- cmdline_encoding = static_cast<uint32_t>(strtoul(argv[3], NULL, 16));
+ InputSet input_set = kIntInputSet;
+ if (argc > 3) {
+ // The arguments of instruction pattern and the number of generating
+ // instructions are processed.
+ int32_t i = 3;
+ std::string argv_s(argv[i]);
+ if (argv_s.find("encoding=") != std::string::npos) {
+ char *c = argv[i];
+ c += 9;
+ if (strcmp(c, "random") == 0) {
+ random_only = true;
+ } else {
+ cmdline_encoding = static_cast<uint32_t>(strtoul(c, NULL, 16));
+ }
+ i++;
}
+
+ if ((argc > 4) || (i == 3)) {
+ argv_s = std::string(argv[i]);
+ if (argv_s.find("input=") != std::string::npos) {
+ char *c = argv[i];
+ c += 6;
+ if (strcmp(c, "fp") == 0) {
+ input_set = kFpInputSet;
+ } else {
+ VIXL_ASSERT(strcmp(c, "int") == 0);
+ }
+ i++;
+ }
+ }
+
+ // Ensure all arguments have been processed.
+ VIXL_ASSERT(argc == i);
}
srand48(42);
@@ -139,7 +170,7 @@
Label test;
masm.Bind(&test);
masm.PushCalleeSavedRegisters();
- SetInitialMachineState(&masm);
+ SetInitialMachineState(&masm, input_set);
ComputeMachineStateHash(&masm, &state_hash);
masm.PopCalleeSavedRegisters();
masm.Ret();
@@ -195,7 +226,7 @@
// Initialise the machine to a known state.
masm.PushCalleeSavedRegisters();
- SetInitialMachineState(&masm);
+ SetInitialMachineState(&masm, input_set);
{
ExactAssemblyScope scope(&masm,
@@ -261,7 +292,9 @@
"CPUFeatures::kNEON, "
"CPUFeatures::kCRC32);\n");
printf(" START();\n\n");
- printf(" SetInitialMachineState(&masm);\n");
+ printf((input_set == kFpInputSet)
+ ? " SetInitialMachineState(&masm, kFpInputSet);\n"
+ : " SetInitialMachineState(&masm);\n");
printf(" // state = 0x%08x\n\n", initial_state_vl[128]);
printf(" {\n");