progs/perftest.c: Use from Glibc syscall numbers.
[catacomb] / base / regdump.h
index 3ada7ea..4934f5c 100644 (file)
@@ -135,6 +135,7 @@ union gp64 { uint64 u64; int64 i64; PTR64 };
 #define   REGSRC_SIMD  0x04000000      /* SIMD vector register */
 #define   REGSRC_STMMX 0x05000000      /* x86-specific: x87/MMX register */
 #define   REGSRC_SEG   0x06000000      /* x86-specific: segment register */
+#define   REGSRC_NONE  0x0f000000      /* just a message */
 /* Where to find the values. */
 
 #define REGF_WDMASK    0xf0000000
@@ -186,10 +187,10 @@ union gp64 { uint64 u64; int64 i64; PTR64 };
 #if !__ASSEMBLER__
 
 #if CPUFAM_X86
-typedef union gp32 gpreg;
+  typedef union gp32 gpreg;
 #endif
 #if CPUFAM_AMD64
-typedef union gp64 gpreg;
+  typedef union gp64 gpreg;
 #endif
 
 struct gpsave {
@@ -202,7 +203,7 @@ union stmmx {
 #if FLT_RADIX == 2 && LDBL_MANT_DIG == 64
   long double f80;
 #endif
-unsigned char _pad[16];
+  unsigned char _pad[16];
 };
 
 union xmm { SIMD_COMMON(128); };
@@ -262,9 +263,23 @@ struct regmap {
 #else
 
        .extern regdump_gpsave
+         // Save general-purpose registers at r/esp; flags, r/eax, and, on
+         // x86, ebx, should have been filled in already, together with the
+         // focus address, in `REGIX_ADDR', if relevant.  Return required
+         // extended save area size in ecx, and leave r/ebp pointing to the
+         // save area.
+
        .extern regdump_xtsave
+         // Save extended registers at r/esp, leaving r/ebp pointing to the
+         // register map.
+
        .extern regdump_xtrstr
+         // Restore extended registers from register map in r/ebp, leaving
+         // r/ebp pointing to general-purpose save area.
+
        .extern regdump_gprstr
+         // Restore general-purpose registers, except r/esp, from save area
+         // at r/ebp.
 
        regmap_gp = 0*WORDSZ
        regmap_fx = 1*WORDSZ
@@ -384,8 +399,8 @@ DO8(REGDEF_SIMD)
        mov     [SP - REGDUMP_SPADJ + (REGIX_AX - 1)*WORDSZ], AX
 
   .ifnes "\addr", "nil"
-       // Collect the effective address for the following dump, leaving it
-       // in the `addr' slot of the dump.
+       // Collect the focus address for the following dump, leaving it in
+       // the `addr' slot of the dump.
        lea     AX, \addr
        mov     [SP - REGDUMP_SPADJ + (REGIX_ADDR - 1)*WORDSZ], AX
   .endif
@@ -432,6 +447,17 @@ DO8(REGDEF_SIMD)
        lea     SP, [SP + REGDUMP_SPADJ]
 .endm
 
+.macro _nilbase
+#  if CPUFAM_X86
+       xor     eax, eax
+       mov     [SP + 0], eax
+#  elif ABI_SYSV
+       xor     edi, edi
+#  elif ABI_WIN
+       xor     ecx, ecx
+#  endif
+.endm
+
 .macro _regbase
 #  if CPUFAM_X86
        mov     [SP + 0], BP
@@ -534,9 +560,22 @@ struct regmap {
 #else
 
        .extern regdump_gpsave
+         // Save general-purpose registers at r13; r12 and r14 should have
+         // been filled in already, along with the focus address in
+         // `REGIX_ADDR', if relevant.  Return required extended save area
+         // size in r0, leave r4 pointing to the save area, and set r6 to
+         // the focus address.
+
        .extern regdump_xtsave
+         // Save extended registers at r13, leaving r5 pointing to the
+         // register map.
+
        .extern regdump_xtrstr
+         // Restore extended registers from register map at r5.
+
        .extern regdump_gprstr
+         // Restore general-purpose registers, except r13 and r14, from save
+         // area at r4.
 
        regmap_gp = 0
        regmap_fp = 4
@@ -586,8 +625,8 @@ DO16(REGDEF_NEONQ)
        str     r14, [r13, #-REGDUMP_GPSIZE + 14*4]
 
   .ifnes "\base,\off", "nil,#0"
-       // Collect the effective address for the following dump, leaving it
-       // in the `addr' slot of the dump.
+       // Collect the focus address for the following dump, leaving it in
+       // the `addr' slot of the dump.
     .ifeqs "\base", "nil"
        adrl    r14, \off
     .else
@@ -600,6 +639,8 @@ DO16(REGDEF_NEONQ)
        sub     r13, r13, #REGDUMP_GPSIZE
 
        // Save flags and general-purpose registers.
+       mrs     r14, cpsr
+       str     r14, [r13, #4*REGIX_CPSR]
        str     r12, [r13, #4*12]
        bl      regdump_gpsave
 
@@ -625,6 +666,10 @@ DO16(REGDEF_NEONQ)
        add     r13, r13, #REGDUMP_GPSIZE
 .endm
 
+.macro _nilbase
+       mov     r0, #0
+.endm
+
 .macro _regbase
        mov     r0, r5
 .endm
@@ -681,9 +726,22 @@ struct regmap {
 #else
 
        .extern regdump_gpsave
+         // Save general-purpose registers at sp; x16, x17, and x30, should
+         // have been filled in already, along with the focus address in
+         // `REGIX_ADDR', if relevant.  Return required extended save area
+         // size in x0, leave x20 pointing to the save area, and set x22 to
+         // the focus address.
+
        .extern regdump_xtsave
+         // Save extended registers at sp, leaving x21 pointing to the
+         // register map.
+
        .extern regdump_xtrstr
+         // Restore extended registers from register map at x21.
+
        .extern regdump_gprstr
+         // Restore general-purpose registers, except sp and x30, from save
+         // area at x20.
 
        regmap_gp = 0
        regmap_fp = 8
@@ -743,8 +801,8 @@ DO32(REGDEF_FP)
        str     x30, [sp, #-REGDUMP_GPSIZE + 30*8]
 
   .ifnes "\base,\off", "nil,#0"
-       // Collect the effective address for the following dump, leaving it
-       // in the `addr' slot of the dump.
+       // Collect the focus address for the following dump, leaving it in
+       // the `addr' slot of the dump.
     .ifeqs "\base", "nil"
        adr     x30, \off
     .else
@@ -756,8 +814,15 @@ DO32(REGDEF_FP)
        // Make space for the register save area.
        sub     sp, sp, #REGDUMP_GPSIZE
 
-       // Save flags and general-purpose registers.
-       stp     x16, x17, [sp, #8*16]
+       // Save flags and general-purpose registers.  The PLT linkage code
+       // makes free with x8--x17, so we must save those here.
+       mrs     x30, nzcv
+       str     x30, [sp, #8*REGIX_NZCV]
+       stp     x8, x9, [sp, #64]
+       stp     x10, x11, [sp, #80]
+       stp     x12, x13, [sp, #96]
+       stp     x14, x15, [sp, #112]
+       stp     x16, x17, [sp, #128]
        bl      regdump_gpsave
 
        // Make space for the extended registers.
@@ -776,6 +841,10 @@ DO32(REGDEF_FP)
        add     sp, sp, #REGDUMP_GPSIZE
 .endm
 
+.macro _nilbase
+       mov     x0, #0
+.endm
+
 .macro _regbase
        mov     x0, x21
 .endm
@@ -889,6 +958,15 @@ extern void regdump_freshline(void);
        _rstrregs
 .endm
 
+.macro msg     lbl
+       _saveregs
+       _nilbase
+       _reglbl "\lbl"
+       _regfmt REGSRC_NONE | (1 << REGF_WDSHIFT)
+       callext F(regdump)
+       _rstrregs
+.endm
+
 .macro reg     lbl, rn, fmt=0
        _saveregs
        _regbase