git: 45f92b1e834c - stable/13 - Split out the arm64 ID field comparison function

Andrew Turner andrew at FreeBSD.org
Mon Aug 30 12:43:09 UTC 2021


The branch stable/13 has been updated by andrew:

URL: https://cgit.FreeBSD.org/src/commit/?id=45f92b1e834c11093d8c1fd4fb7654a14e0b2de1

commit 45f92b1e834c11093d8c1fd4fb7654a14e0b2de1
Author:     Andrew Turner <andrew at FreeBSD.org>
AuthorDate: 2021-07-16 12:46:59 +0000
Commit:     Andrew Turner <andrew at FreeBSD.org>
CommitDate: 2021-08-30 11:22:21 +0000

    Split out the arm64 ID field comparison function
    
    This will be useful in an update for finding which HWCAPS to set.
    
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D31200
    
    (cherry picked from commit 04f6015706f73c90ba78699953d0d4d0b0237298)
---
 sys/arm64/arm64/identcpu.c | 48 ++++++++++++++++++++++++++++++----------------
 1 file changed, 32 insertions(+), 16 deletions(-)

diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c
index 522526b92307..233b036f4499 100644
--- a/sys/arm64/arm64/identcpu.c
+++ b/sys/arm64/arm64/identcpu.c
@@ -1348,22 +1348,26 @@ get_kernel_reg(u_int reg, uint64_t *val)
 	return (false);
 }
 
-static uint64_t
-update_lower_register(uint64_t val, uint64_t new_val, u_int shift,
-    int width, bool sign)
+/*
+ * Compares two field values that may be signed or unsigned.
+ * Returns:
+ *  < 0 when a is less than b
+ *  = 0 when a equals b
+ *  > 0 when a is greater than b
+ */
+static int
+mrs_field_cmp(uint64_t a, uint64_t b, u_int shift, int width, bool sign)
 {
 	uint64_t mask;
-	uint64_t new_field, old_field;
-	bool update;
 
 	KASSERT(width > 0 && width < 64, ("%s: Invalid width %d", __func__,
 	    width));
 
 	mask = (1ul << width) - 1;
-	new_field = (new_val >> shift) & mask;
-	old_field = (val >> shift) & mask;
+	/* Move the field to the lower bits */
+	a = (a >> shift) & mask;
+	b = (b >> shift) & mask;
 
-	update = false;
 	if (sign) {
 		/*
 		 * The field is signed. Toggle the upper bit so the comparison
@@ -1371,17 +1375,29 @@ update_lower_register(uint64_t val, uint64_t new_val, u_int shift,
 		 * i.e. those with a 0 bit, larger than negative numbers,
 		 * i.e. those with a 1 bit, in an unsigned comparison.
 		 */
-		if ((new_field ^ (1ul << (width - 1))) <
-		    (old_field ^ (1ul << (width - 1))))
-			update = true;
-	} else {
-		if (new_field < old_field)
-			update = true;
+		a ^= 1ul << (width - 1);
+		b ^= 1ul << (width - 1);
 	}
 
-	if (update) {
+	return (a - b);
+}
+
+static uint64_t
+update_lower_register(uint64_t val, uint64_t new_val, u_int shift,
+    int width, bool sign)
+{
+	uint64_t mask;
+
+	KASSERT(width > 0 && width < 64, ("%s: Invalid width %d", __func__,
+	    width));
+
+	/*
+	 * If the new value is less than the existing value update it.
+	 */
+	if (mrs_field_cmp(new_val, val, shift, width, sign) < 0) {
+		mask = (1ul << width) - 1;
 		val &= ~(mask << shift);
-		val |= new_field << shift;
+		val |= new_val & (mask << shift);
 	}
 
 	return (val);


More information about the dev-commits-src-all mailing list