// File: attractivechaos[P]udb2/stb/./stb.h
// Function: stb_ps_add
stb_ps *  stb_ps_add   (stb_ps *ps, void *value)
{
   #ifdef STB_DEBUG
   assert(!stb_ps_find(ps,value));
   #endif
   if (value == NULL) return ps; // ignore NULL adds to avoid bad breakage
   assert((3 & (int) value) == STB_ps_direct);
   assert(stb_ps_fastlist_valid(value));
   assert(value != STB_DEL);     // STB_DEL is less likely

   switch (3 & (int) ps) {
      case STB_ps_direct:
         if (ps == NULL) return (stb_ps *) value;
         return EncodeBucket(stb_bucket_create2(ps,value));

      case STB_ps_bucket: {
         stb_ps_bucket *b = GetBucket(ps);
         stb_ps_array  *a;
         assert(STB_BUCKET_SIZE == 4);
         if (b->p[0] == NULL) { b->p[0] = value; return ps; }
         if (b->p[1] == NULL) { b->p[1] = value; return ps; }
         if (b->p[2] == NULL) { b->p[2] = value; return ps; }
         if (b->p[3] == NULL) { b->p[3] = value; return ps; }
         a = (stb_ps_array *) malloc(sizeof(*a) + 7 * sizeof(a->p[0])); // 8 slots, must be 2^k
         memcpy(a->p, b, sizeof(*b));
         a->p[4] = value;
         a->count = 5;
         stb_bucket_free(b);
         return EncodeArray(a);
      }

      case STB_ps_array: {
         stb_ps_array *a = GetArray(ps);
         if (a->count == stb_ps_array_max) {
            // promote from array to hash
            stb_ps_hash *h = stb_ps_makehash(2 << stb_log2_ceil(a->count), a->count, a->p);
            free(a);
            return stb_ps_add(EncodeHash(h), value);
         }
         // do we need to resize the array? the array doubles in size when it
         // crosses a power-of-two
         if ((a->count & (a->count-1))==0) {
            int newsize = a->count*2;
            // clamp newsize to max if:
            //    1. it's larger than max
            //    2. newsize*1.5 is larger than max (to avoid extra resizing)
            if (newsize + a->count > stb_ps_array_max)
               newsize = stb_ps_array_max;
            a = (stb_ps_array *) realloc(a, sizeof(*a) + (newsize-1) * sizeof(a->p[0]));
         }
         a->p[a->count++] = value;
         return EncodeArray(a);
      }
      case STB_ps_hash: {
         stb_ps_hash *h = GetHash(ps);
         stb_uint32 hash = stb_hashptr(value);
         stb_uint32 n = hash & h->mask;
         void **t = h->table;
         // find first NULL or STB_DEL entry
         if (!stb_ps_empty(t[n])) {
            stb_uint32 s = stb_rehash(hash) | 1;
            do {
               n = (n + s) & h->mask;
            } while (!stb_ps_empty(t[n]));
         }
         if (t[n] == STB_DEL)
            -- h->count_deletes;
         t[n] = value;
         ++ h->count;
         if (h->count == h->grow_threshhold) {
            stb_ps_hash *h2 = stb_ps_makehash(h->size*2, h->size, t);
            free(h);
            return EncodeHash(h2);
         }
         if (h->count + h->count_deletes == h->rehash_threshhold) {
            stb_ps_hash *h2 = stb_ps_makehash(h->size, h->size, t);
            free(h);
            return EncodeHash(h2);
         }
         return ps;
      }
   }
   return NULL; /* NOTREACHED */
}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x68(%rsp)
movq %rsi, 0x60(%rsp)
cmpq $0x0, 0x60(%rsp)
jne 0x12fa5
movq 0x68(%rsp), %rax
movq %rax, 0x70(%rsp)
jmp 0x1343c
movq 0x60(%rsp), %rax
andl $0x3, %eax
cmpl $0x0, %eax
jne 0x12fb4
jmp 0x12fd3
leaq 0xca59(%rip), %rdi      # 0x1fa14
leaq 0xc3c7(%rip), %rsi      # 0x1f389
movl $0x1e2a, %edx           # imm = 0x1E2A
leaq 0xcaa8(%rip), %rcx      # 0x1fa76
callq 0x2140
movq 0x60(%rsp), %rax
cmpq $0x1, %rax
jbe 0x12fe0
jmp 0x12fff
leaq 0xca72(%rip), %rdi      # 0x1fa59
leaq 0xc39b(%rip), %rsi      # 0x1f389
movl $0x1e2b, %edx           # imm = 0x1E2B
leaq 0xca7c(%rip), %rcx      # 0x1fa76
callq 0x2140
movl $0x1, %eax
cmpq %rax, 0x60(%rsp)
je 0x1300d
jmp 0x1302c
leaq 0xca87(%rip), %rdi      # 0x1fa9b
leaq 0xc36e(%rip), %rsi      # 0x1f389
movl $0x1e2c, %edx           # imm = 0x1E2C
leaq 0xca4f(%rip), %rcx      # 0x1fa76
callq 0x2140
movl 0x68(%rsp), %eax
andl $0x3, %eax
movl %eax, %ecx
movq %rcx, (%rsp)
subl $0x3, %eax
ja 0x13433
movq (%rsp), %rax
leaq 0xc0a7(%rip), %rcx      # 0x1f0f4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
cmpq $0x0, 0x68(%rsp)
jne 0x1306d
movq 0x60(%rsp), %rax
movq %rax, 0x70(%rsp)
jmp 0x1343c
movq 0x68(%rsp), %rdi
movq 0x60(%rsp), %rsi
callq 0x13450
addq $0x1, %rax
movq %rax, 0x70(%rsp)
jmp 0x1343c
movq 0x68(%rsp), %rax
addq $-0x1, %rax
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rax
cmpq $0x0, (%rax)
jne 0x130bf
movq 0x60(%rsp), %rcx
movq 0x58(%rsp), %rax
movq %rcx, (%rax)
movq 0x68(%rsp), %rax
movq %rax, 0x70(%rsp)
jmp 0x1343c
movq 0x58(%rsp), %rax
cmpq $0x0, 0x8(%rax)
jne 0x130e8
movq 0x60(%rsp), %rcx
movq 0x58(%rsp), %rax
movq %rcx, 0x8(%rax)
movq 0x68(%rsp), %rax
movq %rax, 0x70(%rsp)
jmp 0x1343c
movq 0x58(%rsp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x13111
movq 0x60(%rsp), %rcx
movq 0x58(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0x68(%rsp), %rax
movq %rax, 0x70(%rsp)
jmp 0x1343c
movq 0x58(%rsp), %rax
cmpq $0x0, 0x18(%rax)
jne 0x1313a
movq 0x60(%rsp), %rcx
movq 0x58(%rsp), %rax
movq %rcx, 0x18(%rax)
movq 0x68(%rsp), %rax
movq %rax, 0x70(%rsp)
jmp 0x1343c
movl $0x48, %edi
callq 0x2260
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rax
movq 0x58(%rsp), %rcx
movq (%rcx), %rdx
movq %rdx, 0x8(%rax)
movq 0x8(%rcx), %rdx
movq %rdx, 0x10(%rax)
movq 0x10(%rcx), %rdx
movq %rdx, 0x18(%rax)
movq 0x18(%rcx), %rcx
movq %rcx, 0x20(%rax)
movq 0x60(%rsp), %rcx
movq 0x50(%rsp), %rax
movq %rcx, 0x28(%rax)
movq 0x50(%rsp), %rax
movl $0x5, (%rax)
movq 0x58(%rsp), %rdi
callq 0x12a20
movq 0x50(%rsp), %rax
addq $0x2, %rax
movq %rax, 0x70(%rsp)
jmp 0x1343c
movq 0x68(%rsp), %rax
addq $-0x2, %rax
movq %rax, 0x48(%rsp)
movq 0x48(%rsp), %rax
movl (%rax), %eax
cmpl 0x131bd(%rip), %eax     # 0x26380
jne 0x1321b
movq 0x48(%rsp), %rax
movl (%rax), %edi
callq 0x47c0
movl %eax, %ecx
movl $0x2, %edi
shll %cl, %edi
movq 0x48(%rsp), %rax
movl (%rax), %esi
movq 0x48(%rsp), %rdx
addq $0x8, %rdx
callq 0x12bb0
movq %rax, 0x40(%rsp)
movq 0x48(%rsp), %rdi
callq 0x23c0
movq 0x40(%rsp), %rdi
addq $0x3, %rdi
movq 0x60(%rsp), %rsi
callq 0x12f80
movq %rax, 0x70(%rsp)
jmp 0x1343c
movq 0x48(%rsp), %rax
movl (%rax), %eax
movq 0x48(%rsp), %rcx
movl (%rcx), %ecx
subl $0x1, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
jne 0x1327e
movq 0x48(%rsp), %rax
movl (%rax), %eax
shll %eax
movl %eax, 0x3c(%rsp)
movl 0x3c(%rsp), %eax
movq 0x48(%rsp), %rcx
addl (%rcx), %eax
cmpl 0x1312f(%rip), %eax     # 0x26380
jle 0x1325d
movl 0x13127(%rip), %eax     # 0x26380
movl %eax, 0x3c(%rsp)
movq 0x48(%rsp), %rdi
movl 0x3c(%rsp), %eax
subl $0x1, %eax
movslq %eax, %rsi
shlq $0x3, %rsi
addq $0x10, %rsi
callq 0x22b0
movq %rax, 0x48(%rsp)
movq 0x60(%rsp), %rdx
movq 0x48(%rsp), %rax
movq 0x48(%rsp), %rsi
movl (%rsi), %ecx
movl %ecx, %edi
addl $0x1, %edi
movl %edi, (%rsi)
movslq %ecx, %rcx
movq %rdx, 0x8(%rax,%rcx,8)
movq 0x48(%rsp), %rax
addq $0x2, %rax
movq %rax, 0x70(%rsp)
jmp 0x1343c
movq 0x68(%rsp), %rax
addq $-0x3, %rax
movq %rax, 0x30(%rsp)
movq 0x60(%rsp), %rdi
callq 0x8340
movl %eax, 0x2c(%rsp)
movl 0x2c(%rsp), %eax
movq 0x30(%rsp), %rcx
andl 0x4(%rcx), %eax
movl %eax, 0x28(%rsp)
movq 0x30(%rsp), %rax
addq $0x20, %rax
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rax
movl 0x28(%rsp), %ecx
movq (%rax,%rcx,8), %rax
cmpl $0x1, %eax
jbe 0x13349
movl 0x2c(%rsp), %eax
movl 0x2c(%rsp), %ecx
shrl $0x6, %ecx
addl %ecx, %eax
movl 0x2c(%rsp), %ecx
shrl $0x13, %ecx
addl %ecx, %eax
orl $0x1, %eax
movl %eax, 0x1c(%rsp)
movl 0x28(%rsp), %eax
addl 0x1c(%rsp), %eax
movq 0x30(%rsp), %rcx
andl 0x4(%rcx), %eax
movl %eax, 0x28(%rsp)
movq 0x20(%rsp), %rax
movl 0x28(%rsp), %ecx
movq (%rax,%rcx,8), %rax
cmpl $0x1, %eax
setbe %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x1331a
jmp 0x13349
movq 0x20(%rsp), %rax
movl 0x28(%rsp), %ecx
movl $0x1, %edx
cmpq %rdx, (%rax,%rcx,8)
jne 0x1336b
movq 0x30(%rsp), %rax
movl 0xc(%rax), %ecx
addl $-0x1, %ecx
movl %ecx, 0xc(%rax)
movq 0x60(%rsp), %rdx
movq 0x20(%rsp), %rax
movl 0x28(%rsp), %ecx
movq %rdx, (%rax,%rcx,8)
movq 0x30(%rsp), %rax
movl 0x8(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x8(%rax)
movq 0x30(%rsp), %rax
movl 0x8(%rax), %eax
movq 0x30(%rsp), %rcx
cmpl 0x10(%rcx), %eax
jne 0x133d6
movq 0x30(%rsp), %rax
movl (%rax), %edi
shll %edi
movq 0x30(%rsp), %rax
movl (%rax), %esi
movq 0x20(%rsp), %rdx
callq 0x12bb0
movq %rax, 0x10(%rsp)
movq 0x30(%rsp), %rdi
callq 0x23c0
movq 0x10(%rsp), %rax
addq $0x3, %rax
movq %rax, 0x70(%rsp)
jmp 0x1343c
movq 0x30(%rsp), %rax
movl 0x8(%rax), %eax
movq 0x30(%rsp), %rcx
addl 0xc(%rcx), %eax
movq 0x30(%rsp), %rcx
cmpl 0x18(%rcx), %eax
jne 0x13427
movq 0x30(%rsp), %rax
movl (%rax), %edi
movq 0x30(%rsp), %rax
movl (%rax), %esi
movq 0x20(%rsp), %rdx
callq 0x12bb0
movq %rax, 0x8(%rsp)
movq 0x30(%rsp), %rdi
callq 0x23c0
movq 0x8(%rsp), %rax
addq $0x3, %rax
movq %rax, 0x70(%rsp)
jmp 0x1343c
movq 0x68(%rsp), %rax
movq %rax, 0x70(%rsp)
jmp 0x1343c
movq $0x0, 0x70(%rsp)
movq 0x70(%rsp), %rax
addq $0x78, %rsp
retq
nopw %cs:(%rax,%rax)