authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-28 11:40:19-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-28 11:45:04-07:00
loga0a71709bc2104c708f045fbb42c6247aff136ac
treebaf9979d27276b6765ba55f1251d5f3f99cf96ea
parent3c827be876a39cbe199e5cd7c6e90edef3a090b5

stage1: lower const f80 a different way

this way passes the behavior tests

1 files changed, 21 insertions(+), 22 deletions(-)

src/stage1/codegen.cpp+21-22
......@@ -8094,33 +8094,32 @@ static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *n
80948094 case 64:
80958095 return LLVMConstReal(get_llvm_type(g, type_entry), const_val->data.x_f64);
80968096 case 80: {
8097 LLVMTypeRef llvm_i80 = LLVMIntType(80);
8098 LLVMValueRef x;
8099 if (g->is_big_endian) {
8100 x = LLVMConstInt(llvm_i80, const_val->data.x_f80.signExp, false);
8101 x = LLVMConstShl(x, LLVMConstInt(llvm_i80, 64, false));
8102 x = LLVMConstOr(x, LLVMConstInt(llvm_i80, const_val->data.x_f80.signif, false));
8103 } else {
8104 x = LLVMConstInt(llvm_i80, const_val->data.x_f80.signif, false);
8105 x = LLVMConstShl(x, LLVMConstInt(llvm_i80, 16, false));
8106 x = LLVMConstOr(x, LLVMConstInt(llvm_i80, const_val->data.x_f80.signExp, false));
8107 }
8108 return LLVMConstBitCast(x, get_llvm_type(g, type_entry));
8097 uint64_t buf[2];
8098 memcpy(&buf, &const_val->data.x_f80, 16);
8099#if ZIG_BYTE_ORDER == ZIG_BIG_ENDIAN
8100 uint64_t tmp = buf[0];
8101 buf[0] = buf[1];
8102 buf[1] = tmp;
8103#endif
8104 LLVMValueRef as_i128 = LLVMConstIntOfArbitraryPrecision(LLVMInt128Type(), 2, buf);
8105 LLVMValueRef as_int = LLVMConstTrunc(as_i128, LLVMIntType(80));
8106 return LLVMConstBitCast(as_int, get_llvm_type(g, type_entry));
81098107 }
81108108 case 128:
81118109 {
81128110 uint64_t buf[2];
81138111
8114 // LLVM seems to require that the lower half of the f128 be placed first in the buffer.
8115 #if defined(ZIG_BYTE_ORDER) && ZIG_BYTE_ORDER == ZIG_LITTLE_ENDIAN
8116 buf[0] = const_val->data.x_f128.v[0];
8117 buf[1] = const_val->data.x_f128.v[1];
8118 #elif defined(ZIG_BYTE_ORDER) && ZIG_BYTE_ORDER == ZIG_BIG_ENDIAN
8119 buf[0] = const_val->data.x_f128.v[1];
8120 buf[1] = const_val->data.x_f128.v[0];
8121 #else
8122 #error Unsupported endian
8123 #endif
8112 // LLVM seems to require that the lower half of the f128 be
8113 // placed first in the buffer.
8114#if ZIG_BYTE_ORDER == ZIG_LITTLE_ENDIAN
8115 buf[0] = const_val->data.x_f128.v[0];
8116 buf[1] = const_val->data.x_f128.v[1];
8117#elif ZIG_BYTE_ORDER == ZIG_BIG_ENDIAN
8118 buf[0] = const_val->data.x_f128.v[1];
8119 buf[1] = const_val->data.x_f128.v[0];
8120#else
8121#error Unsupported endian
8122#endif
81248123
81258124 LLVMValueRef as_int = LLVMConstIntOfArbitraryPrecision(LLVMInt128Type(), 2, buf);
81268125 return LLVMConstBitCast(as_int, get_llvm_type(g, type_entry));