Commit a31a749c42

Veikka Tuominen <git@vexu.eu>
2022-01-19 11:26:30
stage1: add f80 type
1 parent 0e6d218
src/stage1/all_types.hpp
@@ -516,6 +516,7 @@ struct ZigValue {
         float16_t x_f16;
         float x_f32;
         double x_f64;
+        extFloat80_t x_f80;
         float128_t x_f128;
         bool x_bool;
         ConstBoundFnValue x_bound_fn;
@@ -2089,6 +2090,7 @@ struct CodeGen {
         ZigType *entry_f16;
         ZigType *entry_f32;
         ZigType *entry_f64;
+        ZigType *entry_f80;
         ZigType *entry_f128;
         ZigType *entry_void;
         ZigType *entry_unreachable;
src/stage1/analyze.cpp
@@ -5647,6 +5647,9 @@ static uint32_t hash_combine_const_val(uint32_t hash_val, ZigValue *const_val) {
                 case 16:  return hash_combine(hash_val, &const_val->data.x_f16);
                 case 32:  return hash_combine(hash_val, &const_val->data.x_f32);
                 case 64:  return hash_combine(hash_val, &const_val->data.x_f64);
+                case 80:
+                    hash_val = hash_combine(hash_val, &const_val->data.x_f80.signExp);
+                    return hash_combine(hash_val, &const_val->data.x_f80.signif);
                 case 128: return hash_combine(hash_val, &const_val->data.x_f128);
                 default:  zig_unreachable();
             }
@@ -6325,6 +6328,7 @@ void init_const_float(ZigValue *const_val, ZigType *type, double value) {
             case 64:
                 const_val->data.x_f64 = value;
                 break;
+            case 80:
             case 128:
                 // if we need this, we should add a function that accepts a float128_t param
                 zig_unreachable();
@@ -7218,6 +7222,8 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) {
                     return a->data.x_f32 == b->data.x_f32;
                 case 64:
                     return a->data.x_f64 == b->data.x_f64;
+                case 80:
+                    return extF80M_eq(&a->data.x_f80, &b->data.x_f80);
                 case 128:
                     return f128M_eq(&a->data.x_f128, &b->data.x_f128);
                 default:
@@ -7470,6 +7476,13 @@ void render_const_value(CodeGen *g, Buf *buf, ZigValue *const_val) {
                 case 64:
                     buf_appendf(buf, "%f", const_val->data.x_f64);
                     return;
+                case 80: {
+                    float64_t f64_value = extF80M_to_f64(&const_val->data.x_f80);
+                    double double_value;
+                    memcpy(&double_value, &f64_value, sizeof(double));
+                    buf_appendf(buf, "%f", double_value);
+                    return;
+                }
                 case 128:
                     {
                         const size_t extra_len = 100;
src/stage1/codegen.cpp
@@ -7692,6 +7692,12 @@ static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *n
                     return LLVMConstReal(get_llvm_type(g, type_entry), const_val->data.x_f32);
                 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));
+                }
                 case 128:
                     {
                         uint64_t buf[2];
@@ -8911,6 +8917,13 @@ static void define_builtin_types(CodeGen *g) {
     add_fp_entry(g, "f64", 64, LLVMDoubleType(), &g->builtin_types.entry_f64);
     add_fp_entry(g, "f128", 128, LLVMFP128Type(), &g->builtin_types.entry_f128);
 
+    if (target_has_f80(g->zig_target)) {
+        add_fp_entry(g, "f80", 80, LLVMX86FP80Type(), &g->builtin_types.entry_f80);
+    } else {
+        // use f128 for correct size and alignment
+        add_fp_entry(g, "f80", 128, LLVMFP128Type(), &g->builtin_types.entry_f80);
+    }
+
     switch (g->zig_target->arch) {
         case ZigLLVM_x86:
         case ZigLLVM_x86_64:
src/stage1/ir.cpp
@@ -2688,6 +2688,12 @@ static bool float_has_fraction(ZigValue *const_val) {
                 return floorf(const_val->data.x_f32) != const_val->data.x_f32;
             case 64:
                 return floor(const_val->data.x_f64) != const_val->data.x_f64;
+            case 80:
+                {
+                    extFloat80_t floored;
+                    extF80M_roundToInt(&const_val->data.x_f80, softfloat_round_minMag, false, &floored);
+                    return !extF80M_eq(&floored, &const_val->data.x_f80);
+                }
             case 128:
                 {
                     float128_t floored;
@@ -2716,6 +2722,15 @@ static void float_append_buf(Buf *buf, ZigValue *const_val) {
             case 64:
                 buf_appendf(buf, "%f", const_val->data.x_f64);
                 break;
+            case 80:
+                {
+                    float64_t f64_value = extF80M_to_f64(&const_val->data.x_f80);
+                    double double_value;
+                    memcpy(&double_value, &f64_value, sizeof(double));
+
+                    buf_appendf(buf, "%f", const_val->data.x_f64);
+                    break;
+                }
             case 128:
                 {
                     // TODO actual implementation
@@ -2772,6 +2787,15 @@ static void float_init_bigint(BigInt *bigint, ZigValue *const_val) {
                     bigint->is_negative = true;
                 }
                 break;
+            case 80:
+                {
+                    float128_t f128_value;
+                    extF80M_to_f128M(&const_val->data.x_f80, &f128_value);
+                    BigFloat tmp_float;
+                    bigfloat_init_128(&tmp_float, f128_value);
+                    bigint_init_bigfloat(bigint, &tmp_float);
+                }
+                break;
             case 128:
                 {
                     BigFloat tmp_float;
@@ -2801,8 +2825,11 @@ static void float_init_bigfloat(ZigValue *dest_val, BigFloat *bigfloat) {
             case 64:
                 dest_val->data.x_f64 = bigfloat_to_f64(bigfloat);
                 break;
-            case 80:
-                zig_panic("TODO: float_init_bigfloat c_longdouble");
+            case 80: {
+                float128_t f128_value = bigfloat_to_f128(bigfloat);
+                f128M_to_extF80M(&f128_value, &dest_val->data.x_f80);
+                break;
+            }
             case 128:
                 dest_val->data.x_f128 = bigfloat_to_f128(bigfloat);
                 break;
@@ -2828,6 +2855,9 @@ static void float_init_f16(ZigValue *dest_val, float16_t x) {
             case 64:
                 dest_val->data.x_f64 = zig_f16_to_double(x);
                 break;
+            case 80:
+                f16_to_extF80M(x, &dest_val->data.x_f80);
+                break;
             case 128:
                 f16_to_f128M(x, &dest_val->data.x_f128);
                 break;
@@ -2853,6 +2883,12 @@ static void float_init_f32(ZigValue *dest_val, float x) {
             case 64:
                 dest_val->data.x_f64 = x;
                 break;
+            case 80: {
+                float32_t x_f32;
+                memcpy(&x_f32, &x, sizeof(float));
+                f32_to_extF80M(x_f32, &dest_val->data.x_f80);
+                break;
+            }
             case 128:
                 {
                     float32_t x_f32;
@@ -2882,6 +2918,12 @@ static void float_init_f64(ZigValue *dest_val, double x) {
             case 64:
                 dest_val->data.x_f64 = x;
                 break;
+            case 80: {
+                float64_t x_f64;
+                memcpy(&x_f64, &x, sizeof(double));
+                f64_to_extF80M(x_f64, &dest_val->data.x_f80);
+                break;
+            }
             case 128:
                 {
                     float64_t x_f64;
@@ -2917,6 +2959,9 @@ static void float_init_f128(ZigValue *dest_val, float128_t x) {
                     memcpy(&dest_val->data.x_f64, &f64_val, sizeof(double));
                     break;
                 }
+            case 80:
+                f128M_to_extF80M(&x, &dest_val->data.x_f80);
+                break;
             case 128:
                 {
                     memcpy(&dest_val->data.x_f128, &x, sizeof(float128_t));
@@ -2944,6 +2989,12 @@ static void float_init_float(ZigValue *dest_val, ZigValue *src_val) {
             case 64:
                 float_init_f64(dest_val, src_val->data.x_f64);
                 break;
+            case 80: {
+                float128_t f128_value;
+                extF80M_to_f128M(&src_val->data.x_f80, &f128_value);
+                float_init_f128(dest_val, f128_value);
+                break;
+            }
             case 128:
                 float_init_f128(dest_val, src_val->data.x_f128);
                 break;
@@ -2966,6 +3017,8 @@ static bool float_is_nan(ZigValue *op) {
                 return op->data.x_f32 != op->data.x_f32;
             case 64:
                 return op->data.x_f64 != op->data.x_f64;
+            case 80:
+                return zig_extF80_isNaN(&op->data.x_f80);
             case 128:
                 return zig_f128_isNaN(&op->data.x_f128);
             default:
@@ -3006,6 +3059,14 @@ static Cmp float_cmp(ZigValue *op1, ZigValue *op2) {
                     } else {
                         return CmpEQ;
                     }
+                case 80:
+                    if (extF80M_lt(&op1->data.x_f80, &op2->data.x_f80)) {
+                        return CmpLT;
+                    } else if (extF80M_eq(&op1->data.x_f80, &op2->data.x_f80)) {
+                        return CmpEQ;
+                    } else {
+                        return CmpGT;
+                    }
                 case 128:
                     if (f128M_lt(&op1->data.x_f128, &op2->data.x_f128)) {
                         return CmpLT;
@@ -3061,7 +3122,18 @@ static Cmp float_cmp_zero(ZigValue *op) {
                 } else {
                     return CmpEQ;
                 }
-            case 128:
+            case 80: {
+                extFloat80_t zero_float;
+                ui32_to_extF80M(0, &zero_float);
+                if (extF80M_lt(&op->data.x_f80, &zero_float)) {
+                    return CmpLT;
+                } else if (extF80M_eq(&op->data.x_f80, &zero_float)) {
+                    return CmpEQ;
+                } else {
+                    return CmpGT;
+                }
+            }
+            case 128: {
                 float128_t zero_float;
                 ui32_to_f128M(0, &zero_float);
                 if (f128M_lt(&op->data.x_f128, &zero_float)) {
@@ -3071,6 +3143,7 @@ static Cmp float_cmp_zero(ZigValue *op) {
                 } else {
                     return CmpGT;
                 }
+            }
             default:
                 zig_unreachable();
         }
@@ -3095,6 +3168,9 @@ static void float_add(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
             case 64:
                 out_val->data.x_f64 =  op1->data.x_f64 + op2->data.x_f64;
                 return;
+            case 80:
+                extF80M_add(&op1->data.x_f80, &op2->data.x_f80, &out_val->data.x_f80);
+                return;
             case 128:
                 f128M_add(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
                 return;
@@ -3122,6 +3198,9 @@ static void float_sub(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
             case 64:
                 out_val->data.x_f64 = op1->data.x_f64 - op2->data.x_f64;
                 return;
+            case 80:
+                extF80M_sub(&op1->data.x_f80, &op2->data.x_f80, &out_val->data.x_f80);
+                return;
             case 128:
                 f128M_sub(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
                 return;
@@ -3149,6 +3228,9 @@ static void float_mul(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
             case 64:
                 out_val->data.x_f64 = op1->data.x_f64 * op2->data.x_f64;
                 return;
+            case 80:
+                extF80M_mul(&op1->data.x_f80, &op2->data.x_f80, &out_val->data.x_f80);
+                return;
             case 128:
                 f128M_mul(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
                 return;
@@ -3176,6 +3258,9 @@ static void float_div(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
             case 64:
                 out_val->data.x_f64 = op1->data.x_f64 / op2->data.x_f64;
                 return;
+            case 80:
+                extF80M_div(&op1->data.x_f80, &op2->data.x_f80, &out_val->data.x_f80);
+                return;
             case 128:
                 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
                 return;
@@ -3204,6 +3289,10 @@ static void float_div_trunc(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
             case 64:
                 out_val->data.x_f64 = trunc(op1->data.x_f64 / op2->data.x_f64);
                 return;
+            case 80:
+                extF80M_div(&op1->data.x_f80, &op2->data.x_f80, &out_val->data.x_f80);
+                extF80M_roundToInt(&out_val->data.x_f80, softfloat_round_minMag, false, &out_val->data.x_f80);
+                return;
             case 128:
                 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
                 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_minMag, false, &out_val->data.x_f128);
@@ -3233,6 +3322,10 @@ static void float_div_floor(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
             case 64:
                 out_val->data.x_f64 = floor(op1->data.x_f64 / op2->data.x_f64);
                 return;
+            case 80:
+                extF80M_div(&op1->data.x_f80, &op2->data.x_f80, &out_val->data.x_f80);
+                extF80M_roundToInt(&out_val->data.x_f80, softfloat_round_min, false, &out_val->data.x_f80);
+                return;
             case 128:
                 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
                 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_min, false, &out_val->data.x_f128);
@@ -3261,6 +3354,9 @@ static void float_rem(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
             case 64:
                 out_val->data.x_f64 = fmod(op1->data.x_f64, op2->data.x_f64);
                 return;
+            case 80:
+                extF80M_rem(&op1->data.x_f80, &op2->data.x_f80, &out_val->data.x_f80);
+                return;
             case 128:
                 f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
                 return;
@@ -3290,6 +3386,14 @@ static void zig_f128M_mod(const float128_t* a, const float128_t* b, float128_t*
     f128M_sub(a, c, c);
 }
 
+// c = a - b * trunc(a / b)
+static void zig_extF80M_mod(const extFloat80_t* a, const extFloat80_t* b, extFloat80_t* c) {
+    extF80M_div(a, b, c);
+    extF80M_roundToInt(c, softfloat_round_min, true, c);
+    extF80M_mul(b, c, c);
+    extF80M_sub(a, c, c);
+}
+
 static void float_mod(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
     assert(op1->type == op2->type);
     out_val->type = op1->type;
@@ -3306,6 +3410,9 @@ static void float_mod(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
             case 64:
                 out_val->data.x_f64 = fmod(fmod(op1->data.x_f64, op2->data.x_f64) + op2->data.x_f64, op2->data.x_f64);
                 return;
+            case 80:
+                zig_extF80M_mod(&op1->data.x_f80, &op2->data.x_f80, &out_val->data.x_f80);
+                return;
             case 128:
                 zig_f128M_mod(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
                 return;
@@ -3351,6 +3458,15 @@ static void float_max(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
                     out_val->data.x_f64 = op1->data.x_f64 > op2->data.x_f64 ? op1->data.x_f64 : op2->data.x_f64;
                 }
                 return;
+            case 80:
+                if (zig_extF80_isNaN(&op1->data.x_f80)) {
+                    out_val->data.x_f80 = op2->data.x_f80;
+                } else if (zig_extF80_isNaN(&op2->data.x_f80)) {
+                    out_val->data.x_f80 = op1->data.x_f80;
+                } else {
+                    out_val->data.x_f80 = extF80M_lt(&op1->data.x_f80, &op2->data.x_f80) ? op2->data.x_f80 : op1->data.x_f80;
+                }
+                return;
             case 128:
                 if (zig_f128_isNaN(&op1->data.x_f128)) {
                     out_val->data.x_f128 = op2->data.x_f128;
@@ -3402,6 +3518,15 @@ static void float_min(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
                     out_val->data.x_f64 = op1->data.x_f32 < op2->data.x_f64 ? op1->data.x_f64 : op2->data.x_f64;
                 }
                 return;
+            case 80:
+                if (zig_extF80_isNaN(&op1->data.x_f80)) {
+                    out_val->data.x_f80 = op2->data.x_f80;
+                } else if (zig_extF80_isNaN(&op2->data.x_f80)) {
+                    out_val->data.x_f80 = op1->data.x_f80;
+                } else {
+                    out_val->data.x_f80 = extF80M_lt(&op1->data.x_f80, &op2->data.x_f80) ? op1->data.x_f80 : op2->data.x_f80;
+                }
+                return;
             case 128:
                 if (zig_f128_isNaN(&op1->data.x_f128)) {
                     out_val->data.x_f128 = op2->data.x_f128;
@@ -3434,6 +3559,9 @@ static void float_negate(ZigValue *out_val, ZigValue *op) {
             case 64:
                 out_val->data.x_f64 = -op->data.x_f64;
                 return;
+            case 80:
+                extF80M_neg(&op->data.x_f80, &out_val->data.x_f80);
+                return;
             case 128:
                 f128M_neg(&op->data.x_f128, &out_val->data.x_f128);
                 return;
@@ -3462,6 +3590,9 @@ void float_write_ieee597(ZigValue *op, uint8_t *buf, bool target_is_big_endian)
         case 64:
             memcpy(buf, &op->data.x_f64, 8);
             break;
+        case 80:
+            memcpy(buf, &op->data.x_f80, 16);
+            break;
         case 128:
             memcpy(buf, &op->data.x_f128, 16);
             break;
@@ -3511,6 +3642,9 @@ void float_read_ieee597(ZigValue *val, uint8_t *buf, bool target_is_big_endian)
         case 64:
             memcpy(&val->data.x_f64, ptr, 8);
             return;
+        case 80:
+            memcpy(&val->data.x_f80, ptr, 16);
+            return;
         case 128:
             memcpy(&val->data.x_f128, ptr, 16);
             return;
@@ -3538,8 +3672,12 @@ static void value_to_bigfloat(BigFloat *out, ZigValue *val) {
             case 64:
                 bigfloat_init_64(out, val->data.x_f64);
                 return;
-            case 80:
-                zig_panic("TODO: value_to_bigfloat c_longdouble");
+            case 80: {
+                float128_t f128_value;
+                extF80M_to_f128M(&val->data.x_f80, &f128_value);
+                bigfloat_init_128(out, f128_value);
+                return;
+            }
             case 128:
                 bigfloat_init_128(out, val->data.x_f128);
                 return;
@@ -3628,8 +3766,14 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, Stage1AirInst *instruc
                     bigfloat_init_64(&orig_bf, tmp);
                     break;
                 }
-                case 80:
-                    zig_panic("TODO: ir_num_lit_fits_in_other_type c_longdouble");
+                case 80: {
+                    float128_t tmp = bigfloat_to_f128(&tmp_bf);
+                    extFloat80_t tmp80;
+                    f128M_to_extF80M(&tmp, &tmp80);
+                    extF80M_to_f128M(&tmp80, &tmp);
+                    bigfloat_init_128(&orig_bf, tmp);
+                    break;
+                }
                 case 128: {
                     float128_t tmp = bigfloat_to_f128(&tmp_bf);
                     bigfloat_init_128(&orig_bf, tmp);
@@ -3673,8 +3817,15 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, Stage1AirInst *instruc
                         }
                         break;
                     }
-                    case 80:
-                        zig_panic("TODO: ir_num_lit_fits_in_other_type c_longdouble");
+                    case 80: {
+                        float16_t tmp = extF80M_to_f16(&const_val->data.x_f80);
+                        extFloat80_t orig;
+                        f16_to_extF80M(tmp, &orig);
+                        if (extF80M_eq(&orig, &const_val->data.x_f80)) {
+                            return true;
+                        }
+                        break;
+                    }
                     case 128: {
                         float16_t tmp = f128M_to_f16(&const_val->data.x_f128);
                         float128_t orig;
@@ -3698,8 +3849,15 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, Stage1AirInst *instruc
                         }
                         break;
                     }
-                    case 80:
-                        zig_panic("TODO: ir_num_lit_fits_in_other_type c_longdouble");
+                    case 80: {
+                        float32_t tmp = extF80M_to_f32(&const_val->data.x_f80);
+                        extFloat80_t orig;
+                        f32_to_extF80M(tmp, &orig);
+                        if (extF80M_eq(&orig, &const_val->data.x_f80)) {
+                            return true;
+                        }
+                        break;
+                    }
                     case 128: {
                         float32_t tmp = f128M_to_f32(&const_val->data.x_f128);
                         float128_t orig;
@@ -3715,8 +3873,15 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, Stage1AirInst *instruc
                 break;
             case 64:
                 switch (const_val->type->data.floating.bit_count) {
-                    case 80:
-                        zig_panic("TODO: ir_num_lit_fits_in_other_type c_longdouble");
+                    case 80: {
+                        float64_t tmp = extF80M_to_f64(&const_val->data.x_f80);
+                        extFloat80_t orig;
+                        f64_to_extF80M(tmp, &orig);
+                        if (extF80M_eq(&orig, &const_val->data.x_f80)) {
+                            return true;
+                        }
+                        break;
+                    }
                     case 128: {
                         float64_t tmp = f128M_to_f64(&const_val->data.x_f128);
                         float128_t orig;
@@ -3730,9 +3895,17 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, Stage1AirInst *instruc
                         zig_unreachable();
                 }
                 break;
-            case 80:
+            case 80: {
                 assert(const_val->type->data.floating.bit_count == 128);
-                zig_panic("TODO: ir_num_lit_fits_in_other_type c_longdouble");
+                extFloat80_t tmp;
+                f128M_to_extF80M(&const_val->data.x_f128, &tmp);
+                float128_t orig;
+                extF80M_to_f128M(&tmp, &orig);
+                if (f128M_eq(&orig, &const_val->data.x_f128)) {
+                    return true;
+                }
+                break;
+            }
             case 128:
                 return true;
             default:
@@ -5143,8 +5316,11 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, Scope *scope, AstNode
                     case 64:
                         const_val->data.x_f64 = bigfloat_to_f64(&other_val->data.x_bigfloat);
                         break;
-                    case 80:
-                        zig_panic("TODO: eval_const_expr_implicit_cast c_longdouble");
+                    case 80: {
+                        float128_t tmp = bigfloat_to_f128(&other_val->data.x_bigfloat);
+                        f128M_to_extF80M(&tmp, &const_val->data.x_f80);
+                        break;
+                    }
                     case 128:
                         const_val->data.x_f128 = bigfloat_to_f128(&other_val->data.x_bigfloat);
                         break;
@@ -5172,8 +5348,11 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, Scope *scope, AstNode
                     case 64:
                         const_val->data.x_f64 = bigfloat_to_f64(&bigfloat);
                         break;
-                    case 80:
-                        zig_panic("TODO: eval_const_expr_implicit_cast c_longdouble");
+                    case 80: {
+                        float128_t tmp = bigfloat_to_f128(&other_val->data.x_bigfloat);
+                        f128M_to_extF80M(&tmp, &const_val->data.x_f80);
+                        break;
+                    }
                     case 128:
                         const_val->data.x_f128 = bigfloat_to_f128(&bigfloat);
                         break;
@@ -18960,6 +19139,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_
                     case  16: return ira->codegen->builtin_types.entry_f16;
                     case  32: return ira->codegen->builtin_types.entry_f32;
                     case  64: return ira->codegen->builtin_types.entry_f64;
+                    case  80: return ira->codegen->builtin_types.entry_f80;
                     case 128: return ira->codegen->builtin_types.entry_f128;
                 }
                 ir_add_error_node(ira, source_node, buf_sprintf("%d-bit float unsupported", bits));
@@ -21943,6 +22123,8 @@ static void ir_eval_mul_add(IrAnalyze *ira, ZigType *float_type,
             case 64:
                 out_val->data.x_f64 = fma(op1->data.x_f64, op2->data.x_f64, op3->data.x_f64);
                 break;
+            case 80:
+                zig_panic("compiler bug: TODO: implement 'mulAdd' for type 'f80'. See https://github.com/ziglang/zig/issues/4026");
             case 128:
                 f128M_mulAdd(&op1->data.x_f128, &op2->data.x_f128, &op3->data.x_f128, &out_val->data.x_f128);
                 break;
@@ -24156,10 +24338,44 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, Scope *scope, AstNode *source_
         }
         break;
     }
-    case 80:
-        return ir_add_error_node(ira, source_node,
-            buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026",
-                float_op_to_name(fop), buf_ptr(&float_type->name)));
+    case 80: {
+        extFloat80_t *out = &out_val->data.x_f80;
+        extFloat80_t *in = &op->data.x_f80;
+        switch (fop) {
+        case BuiltinFnIdSqrt:
+            extF80M_sqrt(in, out);
+            break;
+        case BuiltinFnIdFabs:
+            extF80M_abs(in, out);
+            break;
+        case BuiltinFnIdFloor:
+            extF80M_roundToInt(in, softfloat_round_min, false, out);
+            break;
+        case BuiltinFnIdCeil:
+            extF80M_roundToInt(in, softfloat_round_max, false, out);
+        break;
+        case BuiltinFnIdTrunc:
+            extF80M_trunc(in, out);
+            break;
+        case BuiltinFnIdRound:
+            extF80M_roundToInt(in, softfloat_round_near_maxMag, false, out);
+            break;
+        case BuiltinFnIdNearbyInt:
+        case BuiltinFnIdSin:
+        case BuiltinFnIdCos:
+        case BuiltinFnIdExp:
+        case BuiltinFnIdExp2:
+        case BuiltinFnIdLog:
+        case BuiltinFnIdLog10:
+        case BuiltinFnIdLog2:
+            return ir_add_error_node(ira, source_node,
+                buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026",
+                    float_op_to_name(fop), buf_ptr(&float_type->name)));
+        default:
+            zig_unreachable();
+        }
+        break;
+    }
     case 128: {
         float128_t *out, *in;
         if (float_type->id == ZigTypeIdComptimeFloat) {
src/stage1/softfloat.hpp
@@ -56,4 +56,8 @@ static inline bool zig_f128_isNaN(float128_t *aPtr) {
             || ((absA64 == UINT64_C(0x7FFF000000000000)) && lo);
 }
 
+static inline bool zig_extF80_isNaN(extFloat80_t *aPtr) {
+    return aPtr->signExp & 0x7FFF && aPtr->signif;
+}
+
 #endif
src/stage1/softfloat_ext.cpp
@@ -28,13 +28,6 @@ void f128M_trunc(const float128_t *aPtr, float128_t *zPtr) {
     } 
 }
 
-float16_t f16_neg(const float16_t a) {
-    union { uint16_t ui; float16_t f; } uA;
-    // Toggle the sign bit.
-    uA.ui = a.v ^ (UINT16_C(1) << 15);
-    return uA.f;
-}
-
 void f128M_neg(const float128_t *aPtr, float128_t *zPtr) {
     // Toggle the sign bit.
 #if ZIG_BYTE_ORDER == ZIG_LITTLE_ENDIAN
@@ -46,4 +39,33 @@ void f128M_neg(const float128_t *aPtr, float128_t *zPtr) {
 #else
 #error Unsupported endian
 #endif
-}
\ No newline at end of file
+}
+
+void extF80M_abs(const extFloat80_t *aPtr, extFloat80_t *zPtr) {
+    // Clear the sign bit.
+    zPtr->signExp = aPtr->signExp & UINT16_C(0x7FFF);
+    zPtr->signif = aPtr->signif;
+}
+
+void extF80M_trunc(const extFloat80_t *aPtr, extFloat80_t *zPtr) {
+    extFloat80_t zero_float;
+    ui32_to_extF80M(0, &zero_float);
+    if (extF80M_lt(aPtr, &zero_float)) {
+        extF80M_roundToInt(aPtr, softfloat_round_max, false, zPtr);
+    } else {
+        extF80M_roundToInt(aPtr, softfloat_round_min, false, zPtr);
+    } 
+}
+
+void extF80M_neg(const extFloat80_t *aPtr, extFloat80_t *zPtr) {
+    // Toggle the sign bit.
+    zPtr->signExp = aPtr->signExp ^ UINT16_C(0x8000);
+    zPtr->signif = aPtr->signif;
+}
+
+float16_t f16_neg(const float16_t a) {
+    union { uint16_t ui; float16_t f; } uA;
+    // Toggle the sign bit.
+    uA.ui = a.v ^ (UINT16_C(1) << 15);
+    return uA.f;
+}
src/stage1/softfloat_ext.hpp
@@ -7,6 +7,10 @@ void f128M_abs(const float128_t *aPtr, float128_t *zPtr);
 void f128M_trunc(const float128_t *aPtr, float128_t *zPtr);
 void f128M_neg(const float128_t *aPtr, float128_t *zPtr);
 
+void extF80M_abs(const extFloat80_t *aPtr, extFloat80_t *zPtr);
+void extF80M_trunc(const extFloat80_t *aPtr, extFloat80_t *zPtr);
+void extF80M_neg(const extFloat80_t *aPtr, extFloat80_t *zPtr);
+
 float16_t f16_neg(const float16_t a);
 
 #endif
\ No newline at end of file
src/stage1/target.cpp
@@ -1019,6 +1019,17 @@ bool target_long_double_is_f128(const ZigTarget *target) {
     }
 }
 
+bool target_has_f80(const ZigTarget *target) {
+    switch (target->arch) {
+        case ZigLLVM_x86:
+        case ZigLLVM_x86_64:
+            return true;
+
+        default:
+            return false;
+    }
+}
+
 bool target_is_riscv(const ZigTarget *target) {
     return target->arch == ZigLLVM_riscv32 || target->arch == ZigLLVM_riscv64;
 }
src/stage1/target.hpp
@@ -81,6 +81,7 @@ bool target_is_sparc(const ZigTarget *target);
 bool target_is_android(const ZigTarget *target);
 bool target_has_debug_info(const ZigTarget *target);
 bool target_long_double_is_f128(const ZigTarget *target);
+bool target_has_f80(const ZigTarget *target);
 
 uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch);
 uint32_t target_arch_largest_atomic_bits(ZigLLVM_ArchType arch);
src/AstGen.zig
@@ -7723,6 +7723,7 @@ const primitives = std.ComptimeStringMap(Zir.Inst.Ref, .{
     .{ "f16", .f16_type },
     .{ "f32", .f32_type },
     .{ "f64", .f64_type },
+    .{ "f80", .f80_type },
     .{ "false", .bool_false },
     .{ "i16", .i16_type },
     .{ "i32", .i32_type },
@@ -8732,6 +8733,7 @@ fn rvalue(
                 as_ty | @enumToInt(Zir.Inst.Ref.f16_type),
                 as_ty | @enumToInt(Zir.Inst.Ref.f32_type),
                 as_ty | @enumToInt(Zir.Inst.Ref.f64_type),
+                as_ty | @enumToInt(Zir.Inst.Ref.f80_type),
                 as_ty | @enumToInt(Zir.Inst.Ref.f128_type),
                 as_ty | @enumToInt(Zir.Inst.Ref.anyopaque_type),
                 as_ty | @enumToInt(Zir.Inst.Ref.bool_type),
src/Sema.zig
@@ -16950,6 +16950,7 @@ pub fn typeHasOnePossibleValue(
         .f16,
         .f32,
         .f64,
+        .f80,
         .f128,
         .c_longdouble,
         .comptime_int,
@@ -17227,6 +17228,7 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
         .f16 => return .f16_type,
         .f32 => return .f32_type,
         .f64 => return .f64_type,
+        .f80 => return .f80_type,
         .f128 => return .f128_type,
         .anyopaque => return .anyopaque_type,
         .bool => return .bool_type,
@@ -17572,6 +17574,7 @@ fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) C
         .f16,
         .f32,
         .f64,
+        .f80,
         .f128,
         .anyopaque,
         .bool,
src/type.zig
@@ -58,6 +58,7 @@ pub const Type = extern union {
             .f16,
             .f32,
             .f64,
+            .f80,
             .f128,
             .c_longdouble,
             => return .Float,
@@ -833,6 +834,7 @@ pub const Type = extern union {
             .f16,
             .f32,
             .f64,
+            .f80,
             .f128,
             .bool,
             .void,
@@ -1053,6 +1055,7 @@ pub const Type = extern union {
                 .f16,
                 .f32,
                 .f64,
+                .f80,
                 .f128,
                 .bool,
                 .void,
@@ -1371,6 +1374,7 @@ pub const Type = extern union {
             .f16,
             .f32,
             .f64,
+            .f80,
             .f128,
             .bool,
             .void,
@@ -1473,6 +1477,7 @@ pub const Type = extern union {
             .f16 => return Value.initTag(.f16_type),
             .f32 => return Value.initTag(.f32_type),
             .f64 => return Value.initTag(.f64_type),
+            .f80 => return Value.initTag(.f80_type),
             .f128 => return Value.initTag(.f128_type),
             .bool => return Value.initTag(.bool_type),
             .void => return Value.initTag(.void_type),
@@ -1543,6 +1548,7 @@ pub const Type = extern union {
             .f16,
             .f32,
             .f64,
+            .f80,
             .f128,
             .bool,
             .anyerror,
@@ -1858,6 +1864,7 @@ pub const Type = extern union {
             .f16 => return 2,
             .f32 => return 4,
             .f64 => return 8,
+            .f80 => return 16,
             .f128 => return 16,
             .c_longdouble => return 16,
 
@@ -2138,6 +2145,7 @@ pub const Type = extern union {
             .f16 => return 2,
             .f32 => return 4,
             .f64 => return 8,
+            .f80 => return 16,
             .f128 => return 16,
             .c_longdouble => return 16,
 
@@ -2277,6 +2285,7 @@ pub const Type = extern union {
             .i16, .u16, .f16 => 16,
             .i32, .u32, .f32 => 32,
             .i64, .u64, .f64 => 64,
+            .f80 => 80,
             .u128, .i128, .f128 => 128,
 
             .isize,
@@ -3170,6 +3179,7 @@ pub const Type = extern union {
             .f16,
             .f32,
             .f64,
+            .f80,
             .f128,
             .c_longdouble,
             => true,
@@ -3184,6 +3194,7 @@ pub const Type = extern union {
             .f16,
             .f32,
             .f64,
+            .f80,
             .f128,
             .c_longdouble,
             .comptime_float,
@@ -3200,6 +3211,7 @@ pub const Type = extern union {
             .f16 => 16,
             .f32 => 32,
             .f64 => 64,
+            .f80 => 80,
             .f128, .comptime_float => 128,
             .c_longdouble => CType.longdouble.sizeInBits(target),
 
@@ -3340,6 +3352,7 @@ pub const Type = extern union {
             .f16,
             .f32,
             .f64,
+            .f80,
             .f128,
             .c_longdouble,
             .comptime_int,
@@ -3381,6 +3394,7 @@ pub const Type = extern union {
             .f16,
             .f32,
             .f64,
+            .f80,
             .f128,
             .c_longdouble,
             .comptime_int,
@@ -3579,6 +3593,7 @@ pub const Type = extern union {
             .f16,
             .f32,
             .f64,
+            .f80,
             .f128,
             .anyopaque,
             .bool,
@@ -4334,6 +4349,7 @@ pub const Type = extern union {
         f16,
         f32,
         f64,
+        f80,
         f128,
         anyopaque,
         bool,
@@ -4453,6 +4469,7 @@ pub const Type = extern union {
                 .f16,
                 .f32,
                 .f64,
+                .f80,
                 .f128,
                 .anyopaque,
                 .bool,
src/value.zig
@@ -47,6 +47,7 @@ pub const Value = extern union {
         f16_type,
         f32_type,
         f64_type,
+        f80_type,
         f128_type,
         anyopaque_type,
         bool_type,
@@ -205,6 +206,7 @@ pub const Value = extern union {
                 .f16_type,
                 .f32_type,
                 .f64_type,
+                .f80_type,
                 .f128_type,
                 .anyopaque_type,
                 .bool_type,
@@ -398,6 +400,7 @@ pub const Value = extern union {
             .f16_type,
             .f32_type,
             .f64_type,
+            .f80_type,
             .f128_type,
             .anyopaque_type,
             .bool_type,
@@ -630,6 +633,7 @@ pub const Value = extern union {
             .f16_type => return out_stream.writeAll("f16"),
             .f32_type => return out_stream.writeAll("f32"),
             .f64_type => return out_stream.writeAll("f64"),
+            .f80_type => return out_stream.writeAll("f80"),
             .f128_type => return out_stream.writeAll("f128"),
             .anyopaque_type => return out_stream.writeAll("anyopaque"),
             .bool_type => return out_stream.writeAll("bool"),
@@ -824,6 +828,7 @@ pub const Value = extern union {
             .f16_type => Type.initTag(.f16),
             .f32_type => Type.initTag(.f32),
             .f64_type => Type.initTag(.f64),
+            .f80_type => Type.initTag(.f80),
             .f128_type => Type.initTag(.f128),
             .anyopaque_type => Type.initTag(.anyopaque),
             .bool_type => Type.initTag(.bool),
src/Zir.zig
@@ -1639,6 +1639,7 @@ pub const Inst = struct {
         f16_type,
         f32_type,
         f64_type,
+        f80_type,
         f128_type,
         anyopaque_type,
         bool_type,
@@ -1809,6 +1810,10 @@ pub const Inst = struct {
                 .ty = Type.initTag(.type),
                 .val = Value.initTag(.f64_type),
             },
+            .f80_type = .{
+                .ty = Type.initTag(.type),
+                .val = Value.initTag(.f80_type),
+            },
             .f128_type = .{
                 .ty = Type.initTag(.type),
                 .val = Value.initTag(.f128_type),
CMakeLists.txt
@@ -142,15 +142,19 @@ include_directories(${CLANG_INCLUDE_DIRS})
 # No patches have been applied to SoftFloat-3e
 set(EMBEDDED_SOFTFLOAT_SOURCES
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/8086/f128M_isSignalingNaN.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/8086/extF80M_isSignalingNaN.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/8086/s_commonNaNToF128M.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/8086/s_commonNaNToExtF80M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/8086/s_commonNaNToF16UI.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/8086/s_commonNaNToF32UI.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/8086/s_commonNaNToF64UI.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/8086/s_f128MToCommonNaN.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/8086/s_extF80MToCommonNaN.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/8086/s_f16UIToCommonNaN.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/8086/s_f32UIToCommonNaN.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/8086/s_f64UIToCommonNaN.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/8086/s_propagateNaNF128M.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/8086/s_propagateNaNExtF80M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/8086/s_propagateNaNF16UI.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/8086/softfloat_raiseFlags.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f128M_add.c"
@@ -170,6 +174,7 @@ set(EMBEDDED_SOFTFLOAT_SOURCES
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f128M_to_f16.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f128M_to_f32.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f128M_to_f64.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f128M_to_extF80M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f128M_to_i32.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f128M_to_i32_r_minMag.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f128M_to_i64.c"
@@ -178,6 +183,20 @@ set(EMBEDDED_SOFTFLOAT_SOURCES
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f128M_to_ui32_r_minMag.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f128M_to_ui64.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f128M_to_ui64_r_minMag.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/extF80M_add.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/extF80M_div.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/extF80M_eq.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/extF80M_le.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/extF80M_lt.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/extF80M_mul.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/extF80M_rem.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/extF80M_roundToInt.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/extF80M_sqrt.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/extF80M_sub.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/extF80M_to_f16.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/extF80M_to_f32.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/extF80M_to_f64.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/extF80M_to_f128M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f16_add.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f16_div.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f16_eq.c"
@@ -188,9 +207,12 @@ set(EMBEDDED_SOFTFLOAT_SOURCES
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f16_roundToInt.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f16_sqrt.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f16_sub.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f16_to_extF80M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f16_to_f128M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f16_to_f64.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f32_to_extF80M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f32_to_f128M.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f64_to_extF80M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f64_to_f128M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f64_to_f16.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/i32_to_f128M.c"
@@ -198,6 +220,7 @@ set(EMBEDDED_SOFTFLOAT_SOURCES
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_addCarryM.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_addComplCarryM.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_addF128M.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_addExtF80M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_addM.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_addMagsF16.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_addMagsF32.c"
@@ -208,12 +231,14 @@ set(EMBEDDED_SOFTFLOAT_SOURCES
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_approxRecip_1Ks.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_compare128M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_compare96M.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_compareNonnormExtF80M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_countLeadingZeros16.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_countLeadingZeros32.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_countLeadingZeros64.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_countLeadingZeros8.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_eq128.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_invalidF128M.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_invalidExtF80M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_isNaNF128M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_le128.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_lt128.c"
@@ -224,7 +249,9 @@ set(EMBEDDED_SOFTFLOAT_SOURCES
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_mulAddF32.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_mulAddF64.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_negXM.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_normExtF80SigM.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_normRoundPackMToF128M.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_normRoundPackMToExtF80M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_normRoundPackToF16.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_normRoundPackToF32.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_normRoundPackToF64.c"
@@ -235,6 +262,7 @@ set(EMBEDDED_SOFTFLOAT_SOURCES
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_remStepMBy32.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_roundMToI64.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_roundMToUI64.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_roundPackMToExtF80M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_roundPackMToF128M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_roundPackToF16.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_roundPackToF32.c"
@@ -263,11 +291,14 @@ set(EMBEDDED_SOFTFLOAT_SOURCES
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_subMagsF32.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_subMagsF64.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_tryPropagateNaNF128M.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_tryPropagateNaNExtF80M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f16_mulAdd.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f128M_mulAdd.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/softfloat_state.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/ui32_to_f128M.c"
     "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/ui64_to_f128M.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/ui32_to_extF80M.c"
+    "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/ui64_to_extF80M.c"
 )
 add_library(embedded_softfloat STATIC ${EMBEDDED_SOFTFLOAT_SOURCES})
 if(MSVC)