]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390x: disasm-test: prepare for AR and FPR register support
authorFlorian Krohm <flo2030@eich-krohm.de>
Mon, 24 Mar 2025 21:53:11 +0000 (21:53 +0000)
committerFlorian Krohm <flo2030@eich-krohm.de>
Mon, 24 Mar 2025 21:53:11 +0000 (21:53 +0000)
- New function random_reg to replace random_gpr, random_vr.
- New function unique_reg to replace unique_gpr, unique_vr.
- New function choose_reg_and_iterate to handle register operands whose
  values are constrained, e.g. only even registers.
- Do not call unique_reg for a register operand whose values are constrained.

none/tests/s390x/disasm-test/generate.c

index 7e69085e384ff53b0b116e7c1fee9b5fd598eadc..25d160704735875afe4dead3a74495d8be4ecc41 100644 (file)
@@ -67,15 +67,16 @@ vr_operand(unsigned regno)
 
 
 static unsigned
-random_gpr(int allow_r0)
+random_reg(opnd_t reg_kind, int r0_allowed)
 {
+   unsigned num_regs = reg_kind == OPND_VR ? 32 : 16;
    unsigned regno;
 
-   if (allow_r0) {
-      regno = rand() % 16;
+   if (r0_allowed) {
+      regno = rand() % num_regs;
    } else {
       do {
-         regno = rand() % 16;
+         regno = rand() % num_regs;
       } while (regno == 0);
    }
 
@@ -83,13 +84,6 @@ random_gpr(int allow_r0)
 }
 
 
-static unsigned
-random_vr(void)
-{
-   return rand() % 32;
-}
-
-
 #if 0
 /* These functions are currently unused. But may become useful in
    alternate test generation strategies that use random values instead
@@ -159,31 +153,15 @@ sint_value(unsigned num_bits)
    function returns a register number which has not been used and
    adjusts the bitvector. */
 static unsigned
-unique_gpr(unsigned regno, unsigned *mask)
-{
-   assert(regno < 16);
-   assert(*mask != ~0U);   // Paranoia: avoid infinite loop
-
-   unsigned bit = 1 << regno;
-   while (*mask & bit) {
-      regno = random_gpr(/* allow_r0 */1);
-      bit = 1 << regno;
-   }
-   *mask |= bit;
-   return regno;
-}
-
-
-/* Like unique_gpr */
-static unsigned
-unique_vr(unsigned regno, unsigned *mask)
+unique_reg(opnd_t reg_kind, unsigned regno, unsigned *mask)
 {
-   assert(regno < 32);
+   unsigned num_regs = reg_kind == OPND_VR ? 32 : 16;
+   assert(regno < num_regs);
    assert(*mask != ~0U);   // Paranoia: avoid infinite loop
 
    unsigned bit = 1 << regno;
    while (*mask & bit) {
-      regno = random_vr();
+      regno = random_reg(reg_kind, /* r0_allowed */1);
       bit = 1 << regno;
    }
    *mask |= bit;
@@ -200,6 +178,8 @@ typedef struct {
    long long assigned_value;
 } field;
 
+static void choose_reg_and_iterate(FILE *, const opcode *, const opnd *,
+                                   field [], unsigned);
 
 /* Write out a single ASM statement for OPC. */
 static void
@@ -221,11 +201,15 @@ write_asm_stmt(FILE *fp, const opcode *opc, const field fields[])
          fputc(',', fp);
       switch (operand->kind) {
       case OPND_GPR:
-         regno = unique_gpr(fields[i].assigned_value, &gpr_mask);
+         regno = fields[i].assigned_value;
+         if (! operand->allowed_values)
+            regno = unique_reg(operand->kind, regno, &gpr_mask);
          fprintf(fp, "%s", gpr_operand(regno));
          break;
       case OPND_VR:
-         regno = unique_vr(fields[i].assigned_value, &vr_mask);
+         regno = fields[i].assigned_value;
+         if (! operand->allowed_values)
+            regno = unique_reg(operand->kind, regno, &vr_mask);
          fprintf(fp, "%s", vr_operand(regno));
          break;
       case OPND_D12XB:
@@ -300,18 +284,15 @@ iterate(FILE *fp, const opcode *opc, field fields[], unsigned ix)
          f->assigned_value = 0;
          iterate(fp, opc, fields, ix + 1);
          /* Choose any GPR other than r0 */
-         f->assigned_value = random_gpr(/* r0_allowed */ 0);
+         f->assigned_value = random_reg(operand->kind, /* r0_allowed */ 0);
          iterate(fp, opc, fields, ix + 1);
       } else {
-         /* Choose any GPR */
-         f->assigned_value = random_gpr(/* r0_allowed */ 1);
-         iterate(fp, opc, fields, ix + 1);
+         choose_reg_and_iterate(fp, opc, operand, fields, ix);
       }
       break;
 
    case OPND_VR:
-      f->assigned_value = random_vr();   // Choose any VR
-      iterate(fp, opc, fields, ix + 1);
+      choose_reg_and_iterate(fp, opc, operand, fields, ix);
       break;
 
    case OPND_D12B:
@@ -341,13 +322,15 @@ iterate(FILE *fp, const opcode *opc, field fields[], unsigned ix)
          }
       } else if (f->is_vr) {
          /* v0 is not special AFAICT */
-         f->assigned_value = random_vr();
+         f->assigned_value = random_reg(OPND_VR, /* r0_allowed */ 11);
          iterate(fp, opc, fields, ix + 1);
       } else {
          /* Base or index register */
+         /* Choose r0 */
          f->assigned_value = 0;
          iterate(fp, opc, fields, ix + 1);
-         f->assigned_value = random_gpr(/* r0_allowed */ 0);
+         /* Choose any GPR other than r0 */
+         f->assigned_value = random_reg(OPND_GPR, /* r0_allowed */ 0);
          iterate(fp, opc, fields, ix + 1);
       }
       break;
@@ -373,7 +356,7 @@ iterate(FILE *fp, const opcode *opc, field fields[], unsigned ix)
          /* base or index register */
          f->assigned_value = 0;
          iterate(fp, opc, fields, ix + 1);
-         f->assigned_value = random_gpr(/* r0_allowed */ 0);
+         f->assigned_value = random_reg(OPND_GPR, /* r0_allowed */ 0);
          iterate(fp, opc, fields, ix + 1);
       }
       break;
@@ -572,6 +555,27 @@ generate_tests(const opcode *opc)
 }
 
 
+static void
+choose_reg_and_iterate(FILE *fp, const opcode *opc, const opnd *operand,
+                       field fields[], unsigned ix)
+{
+   field *f = fields + ix;
+
+   if (operand->allowed_values == NULL) {
+      /* No constraint. Pick register at random. */
+      f->assigned_value = random_reg(operand->kind, /* r0_allowed */ 1);
+      iterate(fp, opc, fields, ix + 1);
+   } else {
+      /* Constraint. Choose only allowed values */
+      unsigned num_val = operand->allowed_values[0];
+      for (int i = 1; i <= num_val; ++i) {
+         f->assigned_value = operand->allowed_values[i];
+         iterate(fp, opc, fields, ix + 1);
+      }
+   }
+}
+
+
 static void
 run_cmd(const char *fmt, ...)
 {