#else
 #define cpu_is_pj4()   0
 #endif
+
+static inline int __attribute_const__ cpuid_feature_extract_field(u32 features,
+                                                                 int field)
+{
+       int feature = (features >> field) & 15;
+
+       /* feature registers are signed values */
+       if (feature > 8)
+               feature -= 16;
+
+       return feature;
+}
+
+#define cpuid_feature_extract(reg, field) \
+       cpuid_feature_extract_field(read_cpuid_ext(reg), field)
+
 #endif
 
 
 static void __init cpuid_init_hwcaps(void)
 {
-       unsigned int divide_instrs, vmsa;
+       int block;
 
        if (cpu_architecture() < CPU_ARCH_ARMv7)
                return;
 
-       divide_instrs = (read_cpuid_ext(CPUID_EXT_ISAR0) & 0x0f000000) >> 24;
-
-       switch (divide_instrs) {
-       case 2:
+       block = cpuid_feature_extract(CPUID_EXT_ISAR0, 24);
+       if (block >= 2)
                elf_hwcap |= HWCAP_IDIVA;
-       case 1:
+       if (block >= 1)
                elf_hwcap |= HWCAP_IDIVT;
-       }
 
        /* LPAE implies atomic ldrd/strd instructions */
-       vmsa = (read_cpuid_ext(CPUID_EXT_MMFR0) & 0xf) >> 0;
-       if (vmsa >= 5)
+       block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0);
+       if (block >= 5)
                elf_hwcap |= HWCAP_LPAE;
 }
 
 static void __init elf_hwcap_fixup(void)
 {
        unsigned id = read_cpuid_id();
-       unsigned sync_prim;
 
        /*
         * HWCAP_TLS is available only on 1136 r1p0 and later,
         * avoid advertising SWP; it may not be atomic with
         * multiprocessing cores.
         */
-       sync_prim = ((read_cpuid_ext(CPUID_EXT_ISAR3) >> 8) & 0xf0) |
-                   ((read_cpuid_ext(CPUID_EXT_ISAR4) >> 20) & 0x0f);
-       if (sync_prim >= 0x13)
+       if (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) > 1 ||
+           (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) == 1 &&
+            cpuid_feature_extract(CPUID_EXT_ISAR3, 20) >= 3))
                elf_hwcap &= ~HWCAP_SWP;
 }