diff --git a/src/Compilation.zig b/src/Compilation.zig index 64548a96..8c2f16ef 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -751,6 +751,10 @@ fn generateExactWidthType(comp: *const Compilation, w: anytype, mapper: StringIn try comp.generateSuffixMacro(prefix.constSlice(), w, ty); } +pub fn hasFloat128(comp: *const Compilation) bool { + return target_util.hasFloat128(comp.target); +} + pub fn hasHalfPrecisionFloatABI(comp: *const Compilation) bool { return comp.langopts.allow_half_args_and_returns or target_util.hasHalfPrecisionFloatABI(comp.target); } diff --git a/src/Parser.zig b/src/Parser.zig index 16748b4e..422c655c 100644 --- a/src/Parser.zig +++ b/src/Parser.zig @@ -1852,7 +1852,12 @@ fn typeSpec(p: *Parser, ty: *Type.Builder) Error!bool { .keyword_double => try ty.combine(p, .double, p.tok_i), .keyword_complex => try ty.combine(p, .complex, p.tok_i), .keyword_float80 => try ty.combine(p, .float80, p.tok_i), - .keyword_float128 => try ty.combine(p, .float128, p.tok_i), + .keyword_float128_1, .keyword_float128_2 => { + if (!p.comp.hasFloat128()) { + try p.errStr(.type_not_supported_on_target, p.tok_i, p.tok_ids[p.tok_i].lexeme().?); + } + try ty.combine(p, .float128, p.tok_i); + }, .keyword_atomic => { const atomic_tok = p.tok_i; p.tok_i += 1; diff --git a/src/Tokenizer.zig b/src/Tokenizer.zig index d6bd7079..e20f76d9 100644 --- a/src/Tokenizer.zig +++ b/src/Tokenizer.zig @@ -259,7 +259,10 @@ pub const Token = struct { keyword_asm1, keyword_asm2, keyword_float80, - keyword_float128, + /// _Float128 + keyword_float128_1, + /// __float128 + keyword_float128_2, keyword_int128, keyword_imag1, keyword_imag2, @@ -415,7 +418,8 @@ pub const Token = struct { .keyword_asm1, .keyword_asm2, .keyword_float80, - .keyword_float128, + .keyword_float128_1, + .keyword_float128_2, .keyword_int128, .keyword_imag1, .keyword_imag2, @@ -698,7 +702,8 @@ pub const Token = struct { .keyword_asm1 => "__asm", .keyword_asm2 => "__asm__", .keyword_float80 => "__float80", - .keyword_float128 => "__float18", + .keyword_float128_1 => "_Float128", + .keyword_float128_2 => "__float128", .keyword_int128 => "__int128", .keyword_imag1 => "__imag", .keyword_imag2 => "__imag__", @@ -974,7 +979,8 @@ pub const Token = struct { .{ "__asm", .keyword_asm1 }, .{ "__asm__", .keyword_asm2 }, .{ "__float80", .keyword_float80 }, - .{ "__float128", .keyword_float128 }, + .{ "_Float128", .keyword_float128_1 }, + .{ "__float128", .keyword_float128_2 }, .{ "__int128", .keyword_int128 }, .{ "__imag", .keyword_imag1 }, .{ "__imag__", .keyword_imag2 }, diff --git a/src/target.zig b/src/target.zig index 526fce33..7bc22f4a 100644 --- a/src/target.zig +++ b/src/target.zig @@ -258,6 +258,21 @@ pub fn systemCompiler(target: std.Target) LangOpts.Compiler { return .clang; } +pub fn hasFloat128(target: std.Target) bool { + if (target.cpu.arch.isWasm()) return true; + if (target.isDarwin()) return false; + if (target.cpu.arch.isPPC() or target.cpu.arch.isPPC64()) return std.Target.powerpc.featureSetHas(target.cpu.features, .float128); + return switch (target.os.tag) { + .dragonfly, + .haiku, + .linux, + .openbsd, + .solaris, + => target.cpu.arch.isX86(), + else => false, + }; +} + pub fn hasInt128(target: std.Target) bool { if (target.cpu.arch == .wasm32) return true; if (target.cpu.arch == .x86_64) return true; diff --git a/test/cases/darwin __float128.c b/test/cases/darwin __float128.c new file mode 100644 index 00000000..41f8b622 --- /dev/null +++ b/test/cases/darwin __float128.c @@ -0,0 +1,5 @@ +//aro-args --target=x86_64-macos +__float128 q = 0.0; + +#define EXPECTED_ERRORS "darwin __float128.c:2:1: error: __float128 is not supported on this target" \ + diff --git a/test/cases/linux __float128.c b/test/cases/linux __float128.c new file mode 100644 index 00000000..1859b454 --- /dev/null +++ b/test/cases/linux __float128.c @@ -0,0 +1,10 @@ +//aro-args --target=x86_64-linux-gnu +void foo(void) { + __float128 q = 0.0; + _Float128 q2 = 0.0; + + // q = 1.0q; + // q = 1.0f128; +} + +#define TESTS_SKIPPED 2