base/regdump.c: Print matching condition codes along with CPU flags.
[catacomb] / base / regdump.c
index d4f5fde..0fa76df 100644 (file)
@@ -213,6 +213,7 @@ static const char *regname(char *buf, uint32 f)
 
   switch (src) {
 
+    case REGSRC_NONE:
     case REGSRC_ABS:
       return (0);
 
@@ -374,6 +375,14 @@ static const char *regname(char *buf, uint32 f)
 #  define GP(gp) (gp).u64
 #endif
 
+#define CF (1 <<  0)
+#define PF (1 <<  2)
+#define AF (1 <<  4)
+#define ZF (1 <<  6)
+#define SF (1 <<  7)
+#define DF (1 << 10)
+#define OF (1 << 11)
+
 void regdump_init(void) { ; }
 
 static void dump_flags(const char *lbl, const char *reg, gpreg f)
@@ -390,6 +399,17 @@ static void dump_flags(const char *lbl, const char *reg, gpreg f)
         (GP(f) >>  7)&1u ? '+' : '-',
         (GP(f) >> 10)&1u ? '+' : '-',
         (GP(f) >> 11)&1u ? '+' : '-');
+  printf(";;\t\tcond:");
+  if (GP(f)&CF) printf(" c/b/nae"); else printf(" nc/ae/nb");
+  if (GP(f)&ZF) printf(" e/z"); else printf(" ne/nz");
+  if (GP(f)&SF) printf(" s"); else printf(" ns");
+  if (GP(f)&OF) printf(" o"); else printf(" no");
+  if (GP(f)&PF) printf(" p"); else printf(" np");
+  if ((GP(f)&CF) || (GP(f)&ZF)) printf(" be/na"); else printf(" a/nbe");
+  if (!(GP(f)&OF) == !(GP(f)&SF)) printf(" ge/nl"); else printf(" l/nge");
+  if (!(GP(f)&OF) == !(GP(f)&SF) && !(GP(f)&ZF))
+    printf(" g/nle"); else printf(" le/ng");
+  putchar('\n');
   printf(";;\t\tsystem: %ctf %cif iopl=%d %cnt "
                        "%crf %cvm %cac %cvif %cvip %cid\n",
         (GP(f) >>  8)&1u ? '+' : '-',
@@ -548,6 +568,11 @@ void regdump_simd(const struct regmap *map)
 
 #if CPUFAM_ARMEL
 
+#define NF (1u << 31)
+#define ZF (1u << 30)
+#define CF (1u << 29)
+#define VF (1u << 28)
+
 unsigned regdump__flags = 0;
 
 void regdump_init(void)
@@ -556,6 +581,17 @@ void regdump_init(void)
   if (cpu_feature_p(CPUFEAT_ARM_D32)) regdump__flags |= REGF_D32;
 }
 
+static void dump_conditions(unsigned f)
+{
+  if (f&NF) printf(" mi"); else printf(" pl");
+  if (f&ZF) printf(" eq"); else printf(" ne");
+  if (f&CF) printf(" cs/hs"); else printf(" cc/lo");
+  if (f&VF) printf(" vs"); else printf(" vc");
+  if ((f&CF) && !(f&ZF)) printf(" hi"); else printf(" ls");
+  if (!(f&VF) == !(f&NF)) printf(" ge"); else printf(" lt");
+  if (!(f&VF) == !(f&NF) && !(f&ZF)) printf(" gt"); else printf(" le");
+}
+
 static void dump_flags(const char *lbl, unsigned f)
 {
   static const char
@@ -569,7 +605,7 @@ static void dump_flags(const char *lbl, unsigned f)
   printf(";; ");
   if (lbl) printf("%s: ", lbl);
   printf("   cpsr = 0x%08x\n", f);
-  printf(";;\t\tuser: %cn %cz %cc %cv %cq ge=%c%c%c%c\n",
+  printf(";;\t\tuser: %cn %cz %cc %cv %cq ge=%c%c%c%c;",
         (f >> 31)&1u ? '+' : '-',
         (f >> 30)&1u ? '+' : '-',
         (f >> 29)&1u ? '+' : '-',
@@ -579,6 +615,7 @@ static void dump_flags(const char *lbl, unsigned f)
         (f >> 18)&1u ? '1' : '0',
         (f >> 17)&1u ? '1' : '0',
         (f >> 16)&1u ? '1' : '0');
+  dump_conditions(f); putchar('\n');
   printf(";;\t\tsystem: %cj it=%s:%c%c%c%c %ce %ca %ci %cf %ct m=%s\n",
         (f >> 24)&1u ? '+' : '-',
         condtab[(f >> 12)&15u],
@@ -601,12 +638,13 @@ static void dump_fpflags(const char *lbl, unsigned f)
   printf(";; ");
   if (lbl) printf("%s: ", lbl);
   printf("  fpscr = 0x%08x\n", f);
-  printf(";;\t\tcond: %cn %cz %cc %cv %cqc\n",
+  printf(";;\t\tcond: %cn %cz %cc %cv %cqc;",
         (f >> 31)&1u ? '+' : '-',
         (f >> 30)&1u ? '+' : '-',
         (f >> 29)&1u ? '+' : '-',
         (f >> 28)&1u ? '+' : '-',
         (f >> 27)&1u ? '+' : '-');
+  dump_conditions(f); putchar('\n');
   printf(";;\t\ttrap: %cide %cixe %cufe %cofe %cdze %cioe\n",
         (f >> 15)&1u ? '+' : '-',
         (f >> 12)&1u ? '+' : '-',
@@ -659,7 +697,7 @@ void regdump_fp(const struct regmap *map)
     regdump(map, 0,
            REGF_HEX | REGF_UNSGN | REGF_SGN | REGF_FLT | REGF_CHR |
            REGF_64 | REGF_32 | REGF_16 | REGF_8 |
-           REGSRC_SIMD | i | (6 << REGF_WDSHIFT));
+           REGSRC_FP | i | (6 << REGF_WDSHIFT));
 
   printf(";; Floating-point state:\n");
   dump_fpflags(0, map->fp->fpscr);
@@ -673,18 +711,35 @@ void regdump_simd(const struct regmap *map) { ; }
 
 #if CPUFAM_ARM64
 
+#define NF (1u << 31)
+#define ZF (1u << 30)
+#define CF (1u << 29)
+#define VF (1u << 28)
+
 void regdump_init(void) { ; }
 
+static void dump_conditions(unsigned f)
+{
+  if (f&NF) printf(" mi"); else printf(" pl");
+  if (f&ZF) printf(" eq"); else printf(" ne");
+  if (f&CF) printf(" cs/hs"); else printf(" cc/lo");
+  if (f&VF) printf(" vs"); else printf(" vc");
+  if ((f&CF) && !(f&ZF)) printf(" hi"); else printf(" ls");
+  if (!(f&VF) == !(f&NF)) printf(" ge"); else printf(" lt");
+  if (!(f&VF) == !(f&NF) && !(f&ZF)) printf(" gt"); else printf(" le");
+}
+
 static void dump_flags(const char *lbl, unsigned f)
 {
   printf(";; ");
   if (lbl) printf("%s: ", lbl);
   printf("   nzcv = 0x%08x\n", f);
-  printf(";;\t\tuser: %cn %cz %cc %cv\n",
+  printf(";;\t\tuser: %cn %cz %cc %cv;",
         (f >> 31)&1u ? '+' : '-',
         (f >> 30)&1u ? '+' : '-',
         (f >> 29)&1u ? '+' : '-',
         (f >> 28)&1u ? '+' : '-');
+  dump_conditions(f); putchar('\n');
 }
 
 static void dump_fpflags(const char *lbl, const struct fpsave *fp)
@@ -695,12 +750,13 @@ static void dump_fpflags(const char *lbl, const struct fpsave *fp)
   printf(";; ");
   if (lbl) printf("%s: ", lbl);
   printf("   fpsr = 0x%08x\n", fp->fpsr);
-  printf(";;\t\tcond: %cn %cz %cc %cv %cqc\n",
+  printf(";;\t\tcond_a32: %cn %cz %cc %cv %cqc;",
         (fp->fpsr >> 31)&1u ? '+' : '-',
         (fp->fpsr >> 30)&1u ? '+' : '-',
         (fp->fpsr >> 29)&1u ? '+' : '-',
         (fp->fpsr >> 28)&1u ? '+' : '-',
         (fp->fpsr >> 27)&1u ? '+' : '-');
+  dump_conditions(fp->fpsr); putchar('\n');
   printf(";;\t\terror:  %cidc %cixc %cufc %cofc %cdzc %cioc\n",
         (fp->fpsr >>  7)&1u ? '+' : '-',
         (fp->fpsr >>  4)&1u ? '+' : '-',
@@ -803,6 +859,11 @@ void regdump(const void *base, const char *lbl, uint32 f)
   }
 
   switch (f&REGF_SRCMASK) {
+
+    case REGSRC_NONE:
+      printf(";; %s\n", lbl);
+      return;
+
     case REGSRC_ABS:
       p = base;
       break;
@@ -857,6 +918,13 @@ void regdump(const void *base, const char *lbl, uint32 f)
     case REGSRC_FP:
     case REGSRC_SIMD:
       map = (const struct regmap *)base;
+      if (!map->fp) {
+       printf(";;");
+       if (lbl) printf(" %s:", lbl);
+       if (reg) printf(" %s =", reg);
+       printf(" #<not available -- regdump_init?>\n");
+       return;
+      }
       if (ix == REGIX_FPSCR) {
        assert(!(f&REGF_FMTMASK));
        dump_fpflags(lbl, map->fp->fpscr);