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);
}
}
-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
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;
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
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:
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:
}
} 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;
/* 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;
}
+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, ...)
{