diff --git a/src/libhexfloat/lib.rs b/src/libhexfloat/lib.rs index 4897924c55b..72528e96917 100644 --- a/src/libhexfloat/lib.rs +++ b/src/libhexfloat/lib.rs @@ -105,6 +105,7 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> Some(Ident{ident, span}) => match token::get_ident(ident).get() { "f32" => Some(ast::TyF32), "f64" => Some(ast::TyF64), + "f128" => Some(ast::TyF128), _ => { cx.span_err(span, "invalid floating point type in hexfloat!"); None diff --git a/src/librustc/front/feature_gate.rs b/src/librustc/front/feature_gate.rs index 5bca018c3ee..50018feff2d 100644 --- a/src/librustc/front/feature_gate.rs +++ b/src/librustc/front/feature_gate.rs @@ -57,6 +57,8 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[ ("linkage", Active), ("struct_inherit", Active), + ("quad_precision_float", Active), + // These are used to test this portion of the compiler, they don't actually // mean anything ("test_accepted_feature", Accepted), @@ -77,13 +79,15 @@ enum Status { /// A set of features to be used by later passes. pub struct Features { - pub default_type_params: Cell + pub default_type_params: Cell, + pub quad_precision_float: Cell } impl Features { pub fn new() -> Features { Features { - default_type_params: Cell::new(false) + default_type_params: Cell::new(false), + quad_precision_float: Cell::new(false) } } } @@ -364,4 +368,5 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) { sess.abort_if_errors(); sess.features.default_type_params.set(cx.has_feature("default_type_params")); + sess.features.quad_precision_float.set(cx.has_feature("quad_precision_float")); } diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 3ba8dd3b30f..3fdf3053451 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -317,6 +317,7 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t { 'D' => return ty::mk_mach_int(ast::TyI64), 'f' => return ty::mk_mach_float(ast::TyF32), 'F' => return ty::mk_mach_float(ast::TyF64), + 'Q' => return ty::mk_mach_float(ast::TyF128), _ => fail!("parse_ty: bad numeric type") } } diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 13d24e7a1d0..192a9591658 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -236,6 +236,7 @@ fn enc_sty(w: &mut MemWriter, cx: &ctxt, st: &ty::sty) { match t { TyF32 => mywrite!(w, "Mf"), TyF64 => mywrite!(w, "MF"), + TyF128 => mywrite!(w, "MQ") } } ty::ty_enum(def, ref substs) => { diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index d645b628aff..b20c434729a 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -772,6 +772,7 @@ fn PrimitiveTypeTable() -> PrimitiveTypeTable { table.intern("char", TyChar); table.intern("f32", TyFloat(TyF32)); table.intern("f64", TyFloat(TyF64)); + table.intern("f128", TyFloat(TyF128)); table.intern("int", TyInt(TyI)); table.intern("i8", TyInt(TyI8)); table.intern("i16", TyInt(TyI16)); diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 4dd929e16f7..27a97af6108 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -1170,7 +1170,8 @@ fn basic_type_metadata(cx: &CrateContext, t: ty::t) -> DIType { }, ty::ty_float(float_ty) => match float_ty { ast::TyF32 => ("f32".to_owned(), DW_ATE_float), - ast::TyF64 => ("f64".to_owned(), DW_ATE_float) + ast::TyF64 => ("f64".to_owned(), DW_ATE_float), + ast::TyF128 => ("f128".to_owned(), DW_ATE_float) }, _ => cx.sess().bug("debuginfo::basic_type_metadata - t is invalid type") }; diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index a1752862715..fffc13fe36b 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -163,6 +163,7 @@ impl<'a, 'b> Reflector<'a, 'b> { ty::ty_uint(ast::TyU64) => self.leaf("u64"), ty::ty_float(ast::TyF32) => self.leaf("f32"), ty::ty_float(ast::TyF64) => self.leaf("f64"), + ty::ty_float(ast::TyF128) => self.leaf("f128"), // Should rename to str_*/vec_*. ty::ty_str(vst) => { diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 6f91ec53419..e49e9539980 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -88,6 +88,10 @@ impl Type { ty!(llvm::LLVMDoubleTypeInContext(ccx.llcx)) } + pub fn f128(ccx: &CrateContext) -> Type { + ty!(llvm::LLVMFP128TypeInContext(ccx.llcx)) + } + pub fn bool(ccx: &CrateContext) -> Type { Type::i8(ccx) } @@ -130,7 +134,8 @@ impl Type { pub fn float_from_ty(ccx: &CrateContext, t: ast::FloatTy) -> Type { match t { ast::TyF32 => Type::f32(ccx), - ast::TyF64 => Type::f64(ccx) + ast::TyF64 => Type::f64(ccx), + ast::TyF128 => Type::f128(ccx) } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 9a3bdcc1e15..cc4f3d9dd93 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -706,6 +706,7 @@ mod primitives { def_prim_ty!(TY_U64, super::ty_uint(ast::TyU64), 12) def_prim_ty!(TY_F32, super::ty_float(ast::TyF32), 14) def_prim_ty!(TY_F64, super::ty_float(ast::TyF64), 15) + def_prim_ty!(TY_F128, super::ty_float(ast::TyF128), 16) pub static TY_BOT: t_box_ = t_box_ { sty: super::ty_bot, @@ -1305,6 +1306,9 @@ pub fn mk_f32() -> t { mk_prim_t(&primitives::TY_F32) } #[inline] pub fn mk_f64() -> t { mk_prim_t(&primitives::TY_F64) } +#[inline] +pub fn mk_f128() -> t { mk_prim_t(&primitives::TY_F128) } + #[inline] pub fn mk_uint() -> t { mk_prim_t(&primitives::TY_UINT) } @@ -1344,6 +1348,7 @@ pub fn mk_mach_float(tm: ast::FloatTy) -> t { match tm { ast::TyF32 => mk_f32(), ast::TyF64 => mk_f64(), + ast::TyF128 => mk_f128() } } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 6ae68bdbad1..33f833a2594 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -341,6 +341,13 @@ pub fn ast_ty_to_prim_ty(tcx: &ty::ctxt, ast_ty: &ast::Ty) -> Option { Some(ty::mk_mach_uint(uit)) } ast::TyFloat(ft) => { + if ft == ast::TyF128 && !tcx.sess.features.quad_precision_float.get() { + tcx.sess.span_err(path.span, "quadruple precision floats are \ + missing complete runtime support"); + tcx.sess.span_note(path.span, "add \ + #[feature(quad_precision_float)] \ + to the crate attributes to enable"); + } check_path_args(tcx, path, NO_TPS | NO_REGIONS); Some(ty::mk_mach_float(ft)) } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 2819a70de92..1e2f89659cd 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -332,6 +332,7 @@ impl fmt::Show for clean::Type { ast::TyUint(ast::TyU64) => "u64", ast::TyFloat(ast::TyF32) => "f32", ast::TyFloat(ast::TyF64) => "f64", + ast::TyFloat(ast::TyF128) => "f128", ast::TyStr => "str", ast::TyBool => "bool", ast::TyChar => "char", diff --git a/src/libstd/intrinsics.rs b/src/libstd/intrinsics.rs index 7f02ab28342..43b5f42163e 100644 --- a/src/libstd/intrinsics.rs +++ b/src/libstd/intrinsics.rs @@ -95,6 +95,8 @@ pub trait TyVisitor { fn visit_f32(&mut self) -> bool; fn visit_f64(&mut self) -> bool; + #[cfg(not(stage0))] + fn visit_f128(&mut self) -> bool; fn visit_char(&mut self) -> bool; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 9325a0ad112..7cb07e8e551 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -52,11 +52,13 @@ html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://static.rust-lang.org/doc/master")] #![feature(macro_rules, globs, asm, managed_boxes, thread_local, link_args, - simd, linkage, default_type_params, phase, concat_idents)] + simd, linkage, default_type_params, phase, concat_idents, quad_precision_float)] // Don't link to std. We are std. #![no_std] +// NOTE: remove after snapshot +#![allow(unknown_features)] #![deny(missing_doc)] // When testing libstd, bring in libuv as the I/O backend so tests can print diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs index e64a6b86d02..45f214e26fb 100644 --- a/src/libstd/reflect.rs +++ b/src/libstd/reflect.rs @@ -176,6 +176,14 @@ impl TyVisitor for MovePtrAdaptor { true } + #[cfg(not(stage0))] + fn visit_f128(&mut self) -> bool { + self.align_to::(); + if ! self.inner.visit_f128() { return false; } + self.bump_past::(); + true + } + fn visit_char(&mut self) -> bool { self.align_to::(); if ! self.inner.visit_char() { return false; } diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index 668edbcc42f..61154502445 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -280,6 +280,8 @@ impl<'a> TyVisitor for ReprVisitor<'a> { fn visit_f32(&mut self) -> bool { self.write::() } fn visit_f64(&mut self) -> bool { self.write::() } + #[cfg(not(stage0))] + fn visit_f128(&mut self) -> bool { fail!("not implemented") } fn visit_char(&mut self) -> bool { self.get::(|this, &ch| { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 2b6f94e6bf5..a6146e0eaea 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -730,6 +730,7 @@ impl fmt::Show for UintTy { pub enum FloatTy { TyF32, TyF64, + TyF128 } impl fmt::Show for FloatTy { diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 437f865b449..adb97af7490 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -187,7 +187,7 @@ pub fn uint_ty_max(t: UintTy) -> u64 { } pub fn float_ty_to_str(t: FloatTy) -> ~str { - match t { TyF32 => "f32".to_owned(), TyF64 => "f64".to_owned() } + match t { TyF32 => "f32".to_owned(), TyF64 => "f64".to_owned(), TyF128 => "f128".to_owned() } } pub fn is_call_expr(e: @Expr) -> bool { diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 7d86b988077..68b0ef40b16 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -436,7 +436,8 @@ fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> @ast::Expr { LIT_FLOAT(fident, fty) => { let s_fty = match fty { ast::TyF32 => "TyF32".to_owned(), - ast::TyF64 => "TyF64".to_owned() + ast::TyF64 => "TyF64".to_owned(), + ast::TyF128 => "TyF128".to_owned() }; let e_fty = cx.expr_ident(sp, id_ext(s_fty)); diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index ff087d95e50..992d289b4e9 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -593,10 +593,15 @@ fn scan_number(c: char, rdr: &mut StringReader) -> token::Token { /* FIXME (#2252): if this is out of range for either a 32-bit or 64-bit float, it won't be noticed till the back-end. */ - } else { - fatal_span(rdr, start_bpos, rdr.last_pos, - "expected `f32` or `f64` suffix".to_owned()); + } else if c == '1' && n == '2' && nextnextch(rdr).unwrap_or('\x00') == '8' { + bump(rdr); + bump(rdr); + bump(rdr); + check_float_base(rdr, start_bpos, rdr.last_pos, base); + return token::LIT_FLOAT(str_to_ident(num_str.as_slice()), ast::TyF128); } + fatal_span(rdr, start_bpos, rdr.last_pos, + "expected `f32`, `f64` or `f128` suffix".to_owned()); } if is_float { check_float_base(rdr, start_bpos, rdr.last_pos, base); diff --git a/src/test/run-pass/quad-precision-float.rs b/src/test/run-pass/quad-precision-float.rs new file mode 100644 index 00000000000..d6827666eeb --- /dev/null +++ b/src/test/run-pass/quad-precision-float.rs @@ -0,0 +1,20 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(quad_precision_float)] + +static x: f128 = 1.0 + 2.0; + +fn foo(a: f128) -> f128 { a } + +pub fn main() { + let y = x; + foo(y); +} diff --git a/src/test/run-pass/reflect-visit-type.rs b/src/test/run-pass/reflect-visit-type.rs index 5c28307ea49..e3ad5f1e40f 100644 --- a/src/test/run-pass/reflect-visit-type.rs +++ b/src/test/run-pass/reflect-visit-type.rs @@ -58,6 +58,7 @@ impl TyVisitor for MyVisitor { fn visit_f32(&mut self) -> bool { true } fn visit_f64(&mut self) -> bool { true } + fn visit_f128(&mut self) -> bool { true } fn visit_char(&mut self) -> bool { true }