mirror of
https://github.com/ziglang/zig.git
synced 2026-01-01 02:53:23 +00:00
fix invalid const bitcast of f80
LLVM bitcast wants integers that match the number of bits. So the const bitcast has to use an i80, not an i128. This commit makes the behavior tests fail for me, so it seems I did not correctly construct the type. But it gets rid of the LLVM segfault. I noticed that the strategy of memcpy the buf worked if I simply did an LLVMConstTrunc() on the i128 to make it into an i80 before the LLVMConstBitCast(). But is that correct in the face of different endianness? I'm not sure.
This commit is contained in:
parent
4411f9c019
commit
3c827be876
@ -8094,10 +8094,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *n
|
||||
case 64:
|
||||
return LLVMConstReal(get_llvm_type(g, type_entry), const_val->data.x_f64);
|
||||
case 80: {
|
||||
uint64_t buf[2];
|
||||
memcpy(&buf, &const_val->data.x_f80, 16);
|
||||
LLVMValueRef as_int = LLVMConstIntOfArbitraryPrecision(LLVMInt128Type(), 2, buf);
|
||||
return LLVMConstBitCast(as_int, get_llvm_type(g, type_entry));
|
||||
LLVMTypeRef llvm_i80 = LLVMIntType(80);
|
||||
LLVMValueRef x;
|
||||
if (g->is_big_endian) {
|
||||
x = LLVMConstInt(llvm_i80, const_val->data.x_f80.signExp, false);
|
||||
x = LLVMConstShl(x, LLVMConstInt(llvm_i80, 64, false));
|
||||
x = LLVMConstOr(x, LLVMConstInt(llvm_i80, const_val->data.x_f80.signif, false));
|
||||
} else {
|
||||
x = LLVMConstInt(llvm_i80, const_val->data.x_f80.signif, false);
|
||||
x = LLVMConstShl(x, LLVMConstInt(llvm_i80, 16, false));
|
||||
x = LLVMConstOr(x, LLVMConstInt(llvm_i80, const_val->data.x_f80.signExp, false));
|
||||
}
|
||||
return LLVMConstBitCast(x, get_llvm_type(g, type_entry));
|
||||
}
|
||||
case 128:
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user