// File: jliesch[P]ofxget/pugixml/pugixml.cpp
// Function: pugi::impl::(anonymous namespace)::xml_allocator::allocate_string(unsigned long)
char_t* allocate_string(size_t length)
		{
			static const size_t max_encoded_offset = (1 << 16) * xml_memory_block_alignment;

			PUGI__STATIC_ASSERT(xml_memory_page_size <= max_encoded_offset);

			// allocate memory for string and header block
			size_t size = sizeof(xml_memory_string_header) + length * sizeof(char_t);

			// round size up to block alignment boundary
			size_t full_size = (size + (xml_memory_block_alignment - 1)) & ~(xml_memory_block_alignment - 1);

			xml_memory_page* page;
			xml_memory_string_header* header = static_cast<xml_memory_string_header*>(allocate_memory(full_size, page));

			if (!header) return 0;

			// setup header
			ptrdiff_t page_offset = reinterpret_cast<char*>(header) - reinterpret_cast<char*>(page) - sizeof(xml_memory_page);

			assert(page_offset % xml_memory_block_alignment == 0);
			assert(page_offset >= 0 && static_cast<size_t>(page_offset) < max_encoded_offset);
			header->page_offset = static_cast<uint16_t>(static_cast<size_t>(page_offset) / xml_memory_block_alignment);

			// full_size == 0 for large strings that occupy the whole page
			assert(full_size % xml_memory_block_alignment == 0);
			assert(full_size < max_encoded_offset || (page->busy_size == full_size && page_offset == 0));
			header->full_size = static_cast<uint16_t>(full_size < max_encoded_offset ? full_size / xml_memory_block_alignment : 0);

			// round-trip through void* to avoid 'cast increases required alignment of target type' warning
			// header is guaranteed a pointer-sized alignment, which should be enough for char_t
			return static_cast<char_t*>(static_cast<void*>(header + 1));
		}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
shlq $0x0, %rax
addq $0x4, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
addq $0x7, %rax
andq $-0x8, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rsi
leaq -0x30(%rbp), %rdx
callq 0x44e50
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jne 0x67279
movq $0x0, -0x8(%rbp)
jmp 0x673d8
movq -0x38(%rbp), %rax
movq -0x30(%rbp), %rcx
subq %rcx, %rax
subq $0x28, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
andq $0x7, %rax
cmpq $0x0, %rax
jne 0x6729c
jmp 0x672bb
leaq 0x7a83(%rip), %rdi      # 0x6ed26
leaq 0x40ab(%rip), %rsi      # 0x6b355
movl $0x291, %edx            # imm = 0x291
leaq 0x7a9e(%rip), %rcx      # 0x6ed54
callq 0x7180
xorl %eax, %eax
cmpq $0x0, -0x40(%rbp)
movb %al, -0x41(%rbp)
jl 0x672d5
cmpq $0x80000, -0x40(%rbp)   # imm = 0x80000
setb %al
movb %al, -0x41(%rbp)
movb -0x41(%rbp), %al
testb $0x1, %al
jne 0x672de
jmp 0x672e0
jmp 0x672ff
leaq 0x7abf(%rip), %rdi      # 0x6eda6
leaq 0x4067(%rip), %rsi      # 0x6b355
movl $0x292, %edx            # imm = 0x292
leaq 0x7a5a(%rip), %rcx      # 0x6ed54
callq 0x7180
movq -0x40(%rbp), %rax
shrq $0x3, %rax
movw %ax, %cx
movq -0x38(%rbp), %rax
movw %cx, (%rax)
movq -0x28(%rbp), %rax
andq $0x7, %rax
cmpq $0x0, %rax
jne 0x67321
jmp 0x67340
leaq 0x7ac8(%rip), %rdi      # 0x6edf0
leaq 0x4026(%rip), %rsi      # 0x6b355
movl $0x296, %edx            # imm = 0x296
leaq 0x7a19(%rip), %rcx      # 0x6ed54
callq 0x7180
movb $0x1, %al
cmpq $0x80000, -0x28(%rbp)   # imm = 0x80000
movb %al, -0x42(%rbp)
jb 0x67373
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rcx
xorl %eax, %eax
cmpq -0x28(%rbp), %rcx
movb %al, -0x43(%rbp)
jne 0x6736d
cmpq $0x0, -0x40(%rbp)
sete %al
movb %al, -0x43(%rbp)
movb -0x43(%rbp), %al
movb %al, -0x42(%rbp)
movb -0x42(%rbp), %al
testb $0x1, %al
jne 0x6737c
jmp 0x6737e
jmp 0x6739d
leaq 0x7a97(%rip), %rdi      # 0x6ee1c
leaq 0x3fc9(%rip), %rsi      # 0x6b355
movl $0x297, %edx            # imm = 0x297
leaq 0x79bc(%rip), %rcx      # 0x6ed54
callq 0x7180
cmpq $0x80000, -0x28(%rbp)   # imm = 0x80000
jae 0x673b5
movq -0x28(%rbp), %rax
shrq $0x3, %rax
movq %rax, -0x50(%rbp)
jmp 0x673bd
xorl %eax, %eax
movq %rax, -0x50(%rbp)
jmp 0x673bd
movq -0x50(%rbp), %rax
movw %ax, %cx
movq -0x38(%rbp), %rax
movw %cx, 0x2(%rax)
movq -0x38(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)