RAA: add function to compare if two RAAs are identical

Add raa_equal() to compare two RAAs, accounting for the fact that any
not-present entries in an RAA is zero.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin 2022-11-21 10:52:32 -08:00
parent b018ba0f45
commit cb3ed55e38
2 changed files with 70 additions and 2 deletions

View File

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2020 The NASM Authors - All Rights Reserved
* Copyright 1996-2022 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
@ -54,6 +54,14 @@ union intorptr {
};
typedef union intorptr intorptr;
static inline bool intorptr_bool(intorptr iop)
{
if (sizeof(int64_t) >= sizeof(void *))
return !!iop.i;
else
return !!iop.p;
}
/*
* Wrappers around malloc, realloc, free and a few more. nasm_malloc
* will fatal-error and die rather than return NULL; nasm_realloc will

View File

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
* Copyright 1996-2022 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
@ -196,3 +196,63 @@ struct RAA *raa_write_ptr(struct RAA *r, raaindex posn, void *value)
ip.p = value;
return real_raa_write(r, posn, ip);
}
/* Test to see if an entire RAA (level) is all zero */
static bool raa_is_zero(const struct RAA *top)
{
size_t i;
if (!top)
return true;
if (!top->layers) {
for (i = 0; i < RAA_LAYERSIZE; i++) {
if (intorptr_bool(top->u.l.data[i]))
return false;
}
} else {
for (i = 0; i < RAA_LAYERSIZE; i++) {
if (!raa_is_zero(top->u.b.data[i]))
return false;
}
}
return true;
}
/* Return true if and only if both RAAs (which may be NULL) are identical */
bool raa_equal(const struct RAA *r1, const struct RAA *r2)
{
size_t i;
if (!r1)
return raa_is_zero(r2);
if (!r2)
return raa_is_zero(r1);
if (r1->layers < r2->layers) {
/* Swap so r1 is the "larger" RAA if necessary */
const struct RAA *rtmp = r2;
r2 = r1;
r1 = rtmp;
}
while (r1->layers > r2->layers) {
for (i = 1; i < RAA_LAYERSIZE; i++) {
if (!raa_is_zero(r1->u.b.data[i]))
return false;
}
r1 = r1->u.b.data[0];
if (!r1)
return raa_is_zero(r2);
}
if (!r1->layers) {
return !memcmp(&r1->u.l, &r2->u.l, sizeof r1->u.l);
} else {
for (i = 0; i < RAA_LAYERSIZE; i++) {
if (!raa_equal(r1->u.b.data[i], r2->u.b.data[i]))
return false;
}
return true;
}
}