// File: /workspace/github_c_makefile_star2_O1/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 0xea9a
movq 0x60(%rsi), %r10
movl 0x50(%r8), %eax
movl 0x50(%rsi), %r9d
movq 0x60(%r10), %r10
cmpq 0x52493(%rip), %r10     # 0x60f40
je 0xeae8
cmpb $0x3, (%r8)
movq %r8, %r10
jne 0xeabc
movq 0x60(%r8), %r10
movq 0x60(%r10), %r10
cmpq 0x52479(%rip), %r10     # 0x60f40
je 0xeae8
movb $0x1, (%rdi)
movl 0x28(%rdx), %ecx
movl %ecx, 0x28(%rdi)
cmpl %r9d, %eax
jne 0xeba1
movq 0x20(%rdx), %rax
movq %rax, 0x20(%rdi)
jmp 0xed14
movq %rsi, %r10
cmpl $0x3, %ecx
jne 0xeaf4
movq 0x60(%rsi), %r10
movq 0x60(%r10), %rcx
cmpq 0x52441(%rip), %rcx     # 0x60f40
je 0xeb38
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 0xebe2
cmpb $0x3, (%r8)
movq %r8, %rcx
jne 0xeb45
movq 0x60(%r8), %rcx
movq 0x60(%rcx), %rcx
cmpq 0x523f0(%rip), %rcx     # 0x60f40
je 0xecc5
leal -0x1(%rax), %r9d
negb %al
movq $-0x1, %r10
movl %eax, %ecx
shrq %cl, %r10
movq 0x68(%r8), %rax
movq 0x20(%rdx), %rcx
movq %r10, %rdx
notq %rdx
xorl %r8d, %r8d
btl $0xe, %eax
cmovbq %r8, %rdx
movzbl %r9b, %eax
btq %rax, %rcx
cmovaeq %r8, %rdx
andq %rcx, %r10
orq %rdx, %r10
movq %r10, -0x10(%rsp)
fildll -0x10(%rsp)
jmp 0xecc8
movq 0x10(%rdx), %rcx
movq 0x20(%rdx), %r10
movq 0x68(%rcx), %r11
movb 0x50(%rcx), %cl
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 0xebef
movq 0x60(%rsi), %rsi
cmpq 0x523ea(%rip), %rsi     # 0x60fe0
je 0xec92
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 0x52967(%rip), %rcx     # 0x61590
cmpl $0x0, (%rcx)
je 0xed18
testb $0x1, 0x57847(%rip)     # 0x66480
jne 0xed18
movl %eax, %ecx
negb %cl
movq $-0x1, %rdi
shrq %cl, %rdi
notq %r10
andq %rdi, %r10
testq %r10, %r8
je 0xed18
decl %eax
btsq %rax, %rsi
orq %r10, %rsi
movq %r8, %rax
notq %rax
testq %rax, %rsi
je 0xed18
andq %rdi, %r8
movq 0x8(%rdx), %rdi
leaq 0x3253b(%rip), %rsi     # 0x411bd
movq %r8, %rdx
movq %r9, %rcx
xorl %eax, %eax
popq %rbx
popq %r14
jmp 0x118b4
xorl %eax, %eax
testq %r8, %r8
setne %al
movq %rax, 0x20(%rdi)
cmpb $0x0, 0x577db(%rip)     # 0x66480
jne 0xed18
cmpq $0x2, %r8
jb 0xed18
movq 0x8(%rdx), %rdi
leaq 0x324dc(%rip), %rsi     # 0x41194
movq %r8, %rdx
xorl %eax, %eax
popq %rbx
popq %r14
jmp 0x118b4
fldt 0x20(%rdx)
fstpt 0x20(%rdi)
movl 0x54(%rsi), %eax
shll $0x6, %eax
cmpl $0x1fffffff, %eax       # imm = 0x1FFFFFFF
jg 0xed11
cmpl $0x20000000, %eax       # imm = 0x20000000
fldt 0x20(%rdi)
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)
movb $0x1c, (%rdi)
movq %rsi, 0x10(%rdi)
popq %rbx
popq %r14
retq