// File: /workspace/github_c_makefile_star2_O3/lucvoo[P]sparse-dev/expand.c
// Function: cast_value
void cast_value(struct expression *expr, struct symbol *newtype, struct expression *old)
{
	struct symbol *oldtype = old->ctype;
	int old_size = oldtype->bit_size;
	int new_size = newtype->bit_size;
	long long value, mask, signmask;
	long long oldmask, oldsignmask, dropped;

	if (is_float_type(newtype) || is_float_type(oldtype))
		goto Float;

	// For pointers and integers, we can just move the value around
	expr->type = EXPR_VALUE;
	expr->taint = old->taint;
	if (old_size == new_size) {
		expr->value = old->value;
		expr->ctype = newtype;
		return;
	}

	// expand it to the full "long long" value
	value = get_longlong(old);
	expr->ctype = newtype;

Int:
	// _Bool requires a zero test rather than truncation.
	if (is_bool_type(newtype)) {
		expr->value = !!value;
		if (!conservative && value != 0 && value != 1)
			warning(old->pos, "odd constant _Bool cast (%llx becomes 1)", value);
		return;
	}

	// Truncate it to the new size
	signmask = 1ULL << (new_size-1);
	mask = signmask | (signmask-1);
	expr->value = value & mask;

	// Stop here unless checking for truncation
	if (!Wcast_truncate || conservative)
		return;
	
	// Check if we dropped any bits..
	oldsignmask = 1ULL << (old_size-1);
	oldmask = oldsignmask | (oldsignmask-1);
	dropped = oldmask & ~mask;

	// OK if the bits were (and still are) purely sign bits
	if (value & dropped) {
		if (!(value & oldsignmask) || !(value & signmask) || (value & dropped) != dropped)
			warning(old->pos, "cast truncates bits from constant value (%llx becomes %llx)",
				value & oldmask,
				value & mask);
	}
	return;

Float:
	if (!is_float_type(newtype)) {
		value = (long long)old->fvalue;
		expr->type = EXPR_VALUE;
		expr->taint = 0;
		expr->ctype = newtype;
		goto Int;
	}

	if (!is_float_type(oldtype))
		expr->fvalue = (long double)get_longlong(old);
	else
		expr->fvalue = old->fvalue;

	if (newtype->rank <= 0) {
		if (newtype->rank == 0)
			expr->fvalue = (double)expr->fvalue;
		else
			expr->fvalue = (float)expr->fvalue;
	}
	expr->type = EXPR_FVALUE;
	expr->ctype = newtype;
}

// Assembly:
pushq %r14
pushq %rbx
movq 0x10(%rdx), %r8
movzbl (%rsi), %ecx
movq %rsi, %r10
cmpl $0x3, %ecx
jne 0xeab2
movq 0x60(%rsi), %r10
movl 0x50(%r8), %eax
movl 0x50(%rsi), %r9d
movq 0x60(%r10), %r10
cmpq 0x5148b(%rip), %r10     # 0x5ff50
je 0xeb00
cmpb $0x3, (%r8)
movq %r8, %r10
jne 0xead4
movq 0x60(%r8), %r10
movq 0x60(%r10), %r10
cmpq 0x51471(%rip), %r10     # 0x5ff50
je 0xeb00
movb $0x1, (%rdi)
movl 0x28(%rdx), %ecx
movl %ecx, 0x28(%rdi)
movq 0x20(%rdx), %r10
cmpl %r9d, %eax
jne 0xebb9
movq %r10, 0x20(%rdi)
jmp 0xed2c
movq %rsi, %r10
cmpl $0x3, %ecx
jne 0xeb0c
movq 0x60(%rsi), %r10
movq 0x60(%r10), %rcx
cmpq 0x51439(%rip), %rcx     # 0x5ff50
je 0xeb50
fldt 0x20(%rdx)
fnstcw -0x2c(%rsp)
movzwl -0x2c(%rsp), %ecx
orl $0xc00, %ecx            # imm = 0xC00
movw %cx, -0x2a(%rsp)
fldcw -0x2a(%rsp)
fistpll -0x8(%rsp)
fldcw -0x2c(%rsp)
movq -0x8(%rsp), %r8
movb $0x1, (%rdi)
movl $0x0, 0x28(%rdi)
jmp 0xebf7
cmpb $0x3, (%r8)
movq %r8, %rcx
jne 0xeb5d
movq 0x60(%r8), %rcx
movq 0x60(%rcx), %rcx
cmpq 0x513e8(%rip), %rcx     # 0x5ff50
je 0xecda
leal -0x1(%rax), %r9d
negb %al
movq $-0x1, %r10
movl %eax, %ecx
shrq %cl, %r10
movq 0x20(%rdx), %rax
movq 0x68(%r8), %rcx
movq %r10, %rdx
notq %rdx
xorl %r8d, %r8d
btl $0xe, %ecx
cmovbq %r8, %rdx
movzbl %r9b, %ecx
btq %rcx, %rax
cmovaeq %r8, %rdx
andq %rax, %r10
orq %rdx, %r10
movq %r10, -0x10(%rsp)
fildll -0x10(%rsp)
jmp 0xecdd
movq 0x10(%rdx), %r8
movb 0x50(%r8), %cl
movq 0x68(%r8), %r11
leal -0x1(%rcx), %ebx
negb %cl
movq $-0x1, %r8
shrq %cl, %r8
movzbl %bl, %ecx
movq %r8, %rbx
notq %rbx
xorl %r14d, %r14d
btl $0xe, %r11d
cmovbq %r14, %rbx
btq %rcx, %r10
cmovaeq %r14, %rbx
andq %r10, %r8
orq %rbx, %r8
movq %rsi, 0x10(%rdi)
cmpb $0x3, (%rsi)
jne 0xec04
movq 0x60(%rsi), %rsi
cmpq 0x513dd(%rip), %rsi     # 0x5ffe8
je 0xeca7
leal -0x1(%r9), %ecx
movl $0x1, %esi
shlq %cl, %rsi
negb %r9b
movq $-0x1, %r10
movl %r9d, %ecx
shrq %cl, %r10
movq %r8, %r9
andq %r10, %r9
movq %r9, 0x20(%rdi)
leaq 0x51952(%rip), %rcx     # 0x60590
cmpl $0x0, (%rcx)
je 0xed30
testb $0x1, 0x56832(%rip)     # 0x65480
jne 0xed30
movl %eax, %ecx
negb %cl
movq $-0x1, %rdi
shrq %cl, %rdi
notq %r10
andq %rdi, %r10
testq %r10, %r8
je 0xed30
decl %eax
btsq %rax, %rsi
orq %r10, %rsi
movq %r8, %rax
notq %rax
testq %rax, %rsi
je 0xed30
andq %rdi, %r8
movq 0x8(%rdx), %rdi
leaq 0x31526(%rip), %rsi     # 0x401bd
movq %r8, %rdx
movq %r9, %rcx
xorl %eax, %eax
popq %rbx
popq %r14
jmp 0x118fc
xorl %eax, %eax
testq %r8, %r8
setne %al
movq %rax, 0x20(%rdi)
cmpb $0x0, 0x567c6(%rip)     # 0x65480
jne 0xed30
cmpq $0x2, %r8
jb 0xed30
movq 0x8(%rdx), %rdi
leaq 0x314c7(%rip), %rsi     # 0x40194
movq %r8, %rdx
xorl %eax, %eax
popq %rbx
popq %r14
jmp 0x118fc
fldt 0x20(%rdx)
fld %st(0)
fstpt 0x20(%rdi)
movl 0x54(%rsi), %eax
shll $0x6, %eax
cmpl $0x1fffffff, %eax       # imm = 0x1FFFFFFF
jg 0xed27
cmpl $0x20000000, %eax       # imm = 0x20000000
fstl -0x18(%rsp)
movsd -0x18(%rsp), %xmm0
movsd %xmm0, -0x20(%rsp)
fldl -0x20(%rsp)
fxch %st(1)
fstps -0x24(%rsp)
movss -0x24(%rsp), %xmm0
movss %xmm0, -0x28(%rsp)
flds -0x28(%rsp)
fcmovb %st(1), %st
fstp %st(1)
fstpt 0x20(%rdi)
fldz
fstp %st(0)
movb $0x1c, (%rdi)
movq %rsi, 0x10(%rdi)
popq %rbx
popq %r14
retq