// File: exrd[P]neteruhsp/neteruhsp/neteruhsp.cc
// Function: neteruhsp::variable_add(neteruhsp::variable_t*, neteruhsp::value_t const&, int)
void variable_add( variable_t* var, const value_t& v, int idx )
{
	assert( var != nullptr );
	if ( var->type_ != v.type_ )
	{
		raise_error( "型の異なる変数への加算代入（+=）操作@@ %s(%d)", var->name_, idx );
		return;
	}

	assert( var->type_ == v.type_ );
	auto* data_ptr = variable_data_ptr( *var, idx );
	switch( var->type_ )
	{
	case VALUE_INT:
	{
		reinterpret_cast<int*>( data_ptr )[0] += v.ivalue_;
		break;
	}
	case VALUE_DOUBLE:
	{
		reinterpret_cast<double*>( data_ptr )[0] += v.dvalue_;
		break;
	}
	case VALUE_STRING:
	{
		auto* varstr = reinterpret_cast<char*>( data_ptr );
		const auto varstrlen = static_cast<int>( strlen( varstr ) );
		const auto vstrlen = static_cast<int>( strlen( v.svalue_ ) );
		// 再確保必要？
		if ( ( varstrlen + vstrlen ) > var->granule_size_ )
		{
			if ( idx > 0 )
			{
				raise_error( "文字列変数への加算代入操作：バッファオーバーフロー@@ %s(%d)", var->name_, idx );
				return;
			}
			// 再確保してコピー
			auto* pstr = create_string( varstr );
			prepare_variable( var, VALUE_STRING, varstrlen + vstrlen + 4, 1 );
			varstr = reinterpret_cast<char*>( data_ptr );
			strcpy( varstr, pstr );
			destroy_string( pstr );
		}
		strcpy( varstr + varstrlen, v.svalue_ );
		break;
	}
	default:
		assert( false );
		break;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
cmpq $0x0, -0x8(%rbp)
je 0x97fc
jmp 0x981b
leaq 0xaed7(%rip), %rdi      # 0x146da
leaq 0x9247(%rip), %rsi      # 0x12a51
movl $0xf92, %edx            # imm = 0xF92
leaq 0xafab(%rip), %rcx      # 0x147c1
callq 0x30f0
movq -0x8(%rbp), %rax
movl 0x8(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl (%rcx), %eax
je 0x9847
movq -0x8(%rbp), %rax
movq (%rax), %rsi
movl -0x14(%rbp), %edx
leaq 0xafc7(%rip), %rdi      # 0x14802
movb $0x0, %al
callq 0x4cd0
jmp 0x99b3
movq -0x8(%rbp), %rax
movl 0x8(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl (%rcx), %eax
jne 0x9858
jmp 0x9877
leaq 0xaf4c(%rip), %rdi      # 0x147ab
leaq 0x91eb(%rip), %rsi      # 0x12a51
movl $0xf99, %edx            # imm = 0xF99
leaq 0xaf4f(%rip), %rcx      # 0x147c1
callq 0x30f0
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x9700
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0x3c(%rbp)
subl $0x1, %eax
je 0x98af
jmp 0x9898
movl -0x3c(%rbp), %eax
subl $0x2, %eax
je 0x98c3
jmp 0x98a2
movl -0x3c(%rbp), %eax
subl $0x3, %eax
je 0x98dd
jmp 0x9994
movq -0x10(%rbp), %rax
movl 0x8(%rax), %ecx
movq -0x20(%rbp), %rax
addl (%rax), %ecx
movl %ecx, (%rax)
jmp 0x99b3
movq -0x10(%rbp), %rax
movsd 0x8(%rax), %xmm0
movq -0x20(%rbp), %rax
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
jmp 0x99b3
movq -0x20(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x30b0
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x30b0
movl %eax, -0x30(%rbp)
movl -0x2c(%rbp), %eax
addl -0x30(%rbp), %eax
movq -0x8(%rbp), %rcx
cmpl 0xc(%rcx), %eax
jle 0x997a
cmpl $0x0, -0x14(%rbp)
jle 0x9933
movq -0x8(%rbp), %rax
movq (%rax), %rsi
movl -0x14(%rbp), %edx
leaq 0xaf1a(%rip), %rdi      # 0x14841
movb $0x0, %al
callq 0x4cd0
jmp 0x99b3
movq -0x28(%rbp), %rdi
callq 0x57d0
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rdi
movl -0x2c(%rbp), %edx
addl -0x30(%rbp), %edx
addl $0x4, %edx
movl $0x3, %esi
movl $0x1, %ecx
callq 0x9220
movq -0x20(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x3140
movq -0x38(%rbp), %rdi
callq 0x5030
movq -0x28(%rbp), %rdi
movslq -0x2c(%rbp), %rax
addq %rax, %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x3140
jmp 0x99b3
leaq 0x9fd4(%rip), %rdi      # 0x1396f
leaq 0x90af(%rip), %rsi      # 0x12a51
movl $0xfbf, %edx            # imm = 0xFBF
leaq 0xae13(%rip), %rcx      # 0x147c1
callq 0x30f0
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax)