diff --git a/Cargo.toml b/Cargo.toml index 59f6b404..e23c6660 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ name = "compiler_builtins" version = "0.1.0" [build-dependencies] -cast = { version = "0.2.0", optional = true } +cast = { version = "0.2.2", features = ["x128"], optional = true } rand = { version = "0.3.15", optional = true } [build-dependencies.gcc] diff --git a/README.md b/README.md index 0810edf5..5f59b44b 100644 --- a/README.md +++ b/README.md @@ -141,22 +141,22 @@ features = ["c"] - [x] divsi3.c - [ ] extendhfsf2.c - [ ] extendsfdf2.c -- [ ] fixdfdi.c -- [ ] fixdfsi.c -- [ ] fixsfdi.c -- [ ] fixsfsi.c -- [ ] fixunsdfdi.c -- [ ] fixunsdfsi.c -- [ ] fixunssfdi.c -- [ ] fixunssfsi.c -- [ ] floatdidf.c +- [x] fixdfdi.c +- [x] fixdfsi.c +- [x] fixsfdi.c +- [x] fixsfsi.c +- [x] fixunsdfdi.c +- [x] fixunsdfsi.c +- [x] fixunssfdi.c +- [x] fixunssfsi.c +- [x] floatdidf.c - [ ] floatdisf.c -- [ ] floatsidf.c -- [ ] floatsisf.c -- [ ] floatundidf.c +- [x] floatsidf.c +- [x] floatsisf.c +- [x] floatundidf.c - [ ] floatundisf.c -- [ ] floatunsidf.c -- [ ] floatunsisf.c +- [x] floatunsidf.c +- [x] floatunsisf.c - [ ] i386/ashldi3.S - [ ] i386/ashrdi3.S - [ ] i386/chkstk.S @@ -196,14 +196,14 @@ These builtins are needed to support 128-bit integers, which are in the process - [x] ashlti3.c - [x] ashrti3.c - [x] divti3.c -- [ ] fixdfti.c -- [ ] fixsfti.c -- [ ] fixunsdfti.c -- [ ] fixunssfti.c -- [ ] floattidf.c -- [ ] floattisf.c -- [ ] floatuntidf.c -- [ ] floatuntisf.c +- [x] fixdfti.c +- [x] fixsfti.c +- [x] fixunsdfti.c +- [x] fixunssfti.c +- [x] floattidf.c +- [x] floattisf.c +- [x] floatuntidf.c +- [x] floatuntisf.c - [x] lshrti3.c - [x] modti3.c - [x] muloti4.c diff --git a/build.rs b/build.rs index ac75e6ed..1ae8b41e 100644 --- a/build.rs +++ b/build.rs @@ -49,7 +49,7 @@ mod tests { use std::path::PathBuf; use std::{env, mem}; - use self::cast::{f32, f64, u32, u64, i32, i64}; + use self::cast::{f32, f64, u32, u64, u128, i32, i64, i128}; use self::rand::Rng; const NTESTS: usize = 10_000; @@ -74,16 +74,24 @@ mod tests { Fixdfsi, Fixsfdi, Fixsfsi, + Fixsfti, + Fixdfti, Fixunsdfdi, Fixunsdfsi, Fixunssfdi, Fixunssfsi, + Fixunssfti, + Fixunsdfti, Floatdidf, Floatsidf, Floatsisf, + Floattisf, + Floattidf, Floatundidf, Floatunsidf, Floatunsisf, + Floatuntisf, + Floatuntidf, // float/pow.rs Powidf2, @@ -1084,7 +1092,7 @@ static TEST_CASES: &[((u32,), i32)] = &[ ]; #[test] -fn fixsfdi() { +fn fixsfsi() { for &((a,), b) in TEST_CASES { let b_ = __fixsfsi(mk_f32(a)); assert_eq!(((a,), b), ((a,), b_)); @@ -1094,6 +1102,128 @@ fn fixsfdi() { } } + #[derive(Eq, Hash, PartialEq)] + pub struct Fixsfti { + a: u32, // f32 + b: i128, + } + + impl TestCase for Fixsfti { + fn name() -> &'static str { + "fixsfti" + } + + fn generate(rng: &mut R) -> Option + where + R: Rng, + Self: Sized, + { + let a = gen_f32(rng); + i128(a).ok().map(|b| Fixsfti { a: to_u32(a), b }) + } + + fn to_string(&self, buffer: &mut String) { + writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap(); + } + + fn prologue() -> &'static str { + r#" +#[cfg(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test))] +use core::mem; +#[cfg(not(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test)))] +use std::mem; +use compiler_builtins::float::conv::__fixsfti; + +fn mk_f32(x: u32) -> f32 { + unsafe { mem::transmute(x) } +} + +static TEST_CASES: &[((u32,), i128)] = &[ +"# + } + + fn epilogue() -> &'static str { + " +]; + +#[test] +fn fixsfti() { + for &((a,), b) in TEST_CASES { + let b_ = __fixsfti(mk_f32(a)); + assert_eq!(((a,), b), ((a,), b_)); + } +} +" + } + } + + #[derive(Eq, Hash, PartialEq)] + pub struct Fixdfti { + a: u64, // f64 + b: i128, + } + + impl TestCase for Fixdfti { + fn name() -> &'static str { + "fixdfti" + } + + fn generate(rng: &mut R) -> Option + where + R: Rng, + Self: Sized, + { + let a = gen_f64(rng); + i128(a).ok().map(|b| Fixdfti { a: to_u64(a), b }) + } + + fn to_string(&self, buffer: &mut String) { + writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap(); + } + + fn prologue() -> &'static str { + r#" +#[cfg(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test))] +use core::mem; +#[cfg(not(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test)))] +use std::mem; +use compiler_builtins::float::conv::__fixdfti; + +fn mk_f64(x: u64) -> f64 { + unsafe { mem::transmute(x) } +} + +static TEST_CASES: &[((u64,), i128)] = &[ +"# + } + + fn epilogue() -> &'static str { + " +]; + +#[test] +fn fixdfti() { + for &((a,), b) in TEST_CASES { + let b_ = __fixdfti(mk_f64(a)); + assert_eq!(((a,), b), ((a,), b_)); + } +} +" + } + } + #[derive(Eq, Hash, PartialEq)] pub struct Fixunsdfdi { a: u64, // f64 @@ -1338,6 +1468,128 @@ fn fixunssfsi() { } } + #[derive(Eq, Hash, PartialEq)] + pub struct Fixunssfti { + a: u32, // f32 + b: u128, + } + + impl TestCase for Fixunssfti { + fn name() -> &'static str { + "fixunssfti" + } + + fn generate(rng: &mut R) -> Option + where + R: Rng, + Self: Sized, + { + let a = gen_f32(rng); + u128(a).ok().map(|b| Fixunssfti { a: to_u32(a), b }) + } + + fn to_string(&self, buffer: &mut String) { + writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap(); + } + + fn prologue() -> &'static str { + r#" +#[cfg(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test))] +use core::mem; +#[cfg(not(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test)))] +use std::mem; +use compiler_builtins::float::conv::__fixunssfti; + +fn mk_f32(x: u32) -> f32 { + unsafe { mem::transmute(x) } +} + +static TEST_CASES: &[((u32,), u128)] = &[ +"# + } + + fn epilogue() -> &'static str { + " +]; + +#[test] +fn fixunssfti() { + for &((a,), b) in TEST_CASES { + let b_ = __fixunssfti(mk_f32(a)); + assert_eq!(((a,), b), ((a,), b_)); + } +} +" + } + } + + #[derive(Eq, Hash, PartialEq)] + pub struct Fixunsdfti { + a: u64, // f64 + b: u128, + } + + impl TestCase for Fixunsdfti { + fn name() -> &'static str { + "fixunsdfti" + } + + fn generate(rng: &mut R) -> Option + where + R: Rng, + Self: Sized, + { + let a = gen_f64(rng); + u128(a).ok().map(|b| Fixunsdfti { a: to_u64(a), b }) + } + + fn to_string(&self, buffer: &mut String) { + writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap(); + } + + fn prologue() -> &'static str { + r#" +#[cfg(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test))] +use core::mem; +#[cfg(not(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test)))] +use std::mem; +use compiler_builtins::float::conv::__fixunsdfti; + +fn mk_f64(x: u64) -> f64 { + unsafe { mem::transmute(x) } +} + +static TEST_CASES: &[((u64,), u128)] = &[ +"# + } + + fn epilogue() -> &'static str { + " +]; + +#[test] +fn fixunsdfti() { + for &((a,), b) in TEST_CASES { + let b_ = __fixunsdfti(mk_f64(a)); + assert_eq!(((a,), b), ((a,), b_)); + } +} +" + } + } + #[derive(Eq, Hash, PartialEq)] pub struct Floatdidf { a: i64, @@ -1536,6 +1788,138 @@ fn floatsisf() { } } + #[derive(Eq, Hash, PartialEq)] + pub struct Floattisf { + a: i128, + b: u32, // f32 + } + + impl TestCase for Floattisf { + fn name() -> &'static str { + "floattisf" + } + + fn generate(rng: &mut R) -> Option + where + R: Rng, + Self: Sized, + { + let a = gen_i128(rng); + Some( + Floattisf { + a, + b: to_u32(f32(a)), + }, + ) + } + + fn to_string(&self, buffer: &mut String) { + writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap(); + } + + fn prologue() -> &'static str { + r#" +#[cfg(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test))] +use core::mem; +#[cfg(not(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test)))] +use std::mem; +use compiler_builtins::float::conv::__floattisf; + +fn to_u32(x: f32) -> u32 { + unsafe { mem::transmute(x) } +} + +static TEST_CASES: &[((i128,), u32)] = &[ +"# + } + + fn epilogue() -> &'static str { + " +]; + +#[test] +fn floattisf() { + for &((a,), b) in TEST_CASES { + let b_ = __floattisf(a); + assert_eq!(((a,), b), ((a,), to_u32(b_))); + } +} +" + } + } + + #[derive(Eq, Hash, PartialEq)] + pub struct Floattidf { + a: i128, + b: u64, // f64 + } + + impl TestCase for Floattidf { + fn name() -> &'static str { + "floattidf" + } + + fn generate(rng: &mut R) -> Option + where + R: Rng, + Self: Sized, + { + let a = gen_i128(rng); + Some( + Floattidf { + a, + b: to_u64(f64(a)), + }, + ) + } + + fn to_string(&self, buffer: &mut String) { + writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap(); + } + + fn prologue() -> &'static str { + r#" +#[cfg(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test))] +use core::mem; +#[cfg(not(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test)))] +use std::mem; +use compiler_builtins::float::conv::__floattidf; + +fn to_u64(x: f64) -> u64 { + unsafe { mem::transmute(x) } +} + +static TEST_CASES: &[((i128,), u64)] = &[ +"# + } + + fn epilogue() -> &'static str { + " +]; + +#[test] +fn floattidf() { + for &((a,), b) in TEST_CASES { + let b_ = __floattidf(a); + assert_eq!(((a,), b), ((a,), to_u64(b_))); + } +} +" + } + } + #[derive(Eq, Hash, PartialEq)] pub struct Floatundidf { a: u64, @@ -1734,6 +2118,139 @@ fn floatunsisf() { } } + #[derive(Eq, Hash, PartialEq)] + pub struct Floatuntisf { + a: u128, + b: u32, // f32 + } + + impl TestCase for Floatuntisf { + fn name() -> &'static str { + "floatuntisf" + } + + fn generate(rng: &mut R) -> Option + where + R: Rng, + Self: Sized, + { + let a = gen_u128(rng); + let f_a = f32(a); + f_a.ok().map(|f| { + Floatuntisf { + a, + b: to_u32(f), + } + }) + } + + fn to_string(&self, buffer: &mut String) { + writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap(); + } + + fn prologue() -> &'static str { + r#" +#[cfg(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test))] +use core::mem; +#[cfg(not(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test)))] +use std::mem; +use compiler_builtins::float::conv::__floatuntisf; + +fn to_u32(x: f32) -> u32 { + unsafe { mem::transmute(x) } +} + +static TEST_CASES: &[((u128,), u32)] = &[ +"# + } + + fn epilogue() -> &'static str { + " +]; + +#[test] +fn floatuntisf() { + for &((a,), b) in TEST_CASES { + let b_ = __floatuntisf(a); + assert_eq!(((a,), b), ((a,), to_u32(b_))); + } +} +" + } + } + + #[derive(Eq, Hash, PartialEq)] + pub struct Floatuntidf { + a: u128, + b: u64, // f64 + } + + impl TestCase for Floatuntidf { + fn name() -> &'static str { + "floatuntidf" + } + + fn generate(rng: &mut R) -> Option + where + R: Rng, + Self: Sized, + { + let a = gen_u128(rng); + Some( + Floatuntidf { + a, + b: to_u64(f64(a)), + }, + ) + } + + fn to_string(&self, buffer: &mut String) { + writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap(); + } + + fn prologue() -> &'static str { + r#" +#[cfg(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test))] +use core::mem; +#[cfg(not(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test)))] +use std::mem; +use compiler_builtins::float::conv::__floatuntidf; + +fn to_u64(x: f64) -> u64 { + unsafe { mem::transmute(x) } +} + +static TEST_CASES: &[((u128,), u64)] = &[ +"# + } + + fn epilogue() -> &'static str { + " +]; + +#[test] +fn floatuntidf() { + for &((a,), b) in TEST_CASES { + let b_ = __floatuntidf(a); + assert_eq!(((a,), b), ((a,), to_u64(b_))); + } +} +" + } + } + #[derive(Eq, Hash, PartialEq)] pub struct Moddi3 { a: i64, @@ -3417,7 +3934,9 @@ macro_rules! panic { let rng = &mut rand::thread_rng(); let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); - let out_file = out_dir.join(format!("{}.rs", T::name())); + let out_file_name = format!("{}.rs", T::name()); + let out_file = out_dir.join(&out_file_name); + println!("Generating {}", out_file_name); let contents = mk_tests::(NTESTS, rng); File::create(out_file) diff --git a/src/float/conv.rs b/src/float/conv.rs index efe590ab..3413812a 100755 --- a/src/float/conv.rs +++ b/src/float/conv.rs @@ -12,10 +12,13 @@ macro_rules! fp_overflow { } } -macro_rules! fp_convert { +macro_rules! int_to_float { ($intrinsic:ident: $ity:ty, $fty:ty) => { + int_to_float!($intrinsic: $ity, $fty, "C"); + }; + ($intrinsic:ident: $ity:ty, $fty:ty, $abi:tt) => { - pub extern "C" fn $intrinsic(i: $ity) -> $fty { + pub extern $abi fn $intrinsic(i: $ity) -> $fty { if i == 0 { return 0.0 } @@ -82,12 +85,25 @@ macro_rules! fp_convert { } } -fp_convert!(__floatsisf: i32, f32); -fp_convert!(__floatsidf: i32, f64); -fp_convert!(__floatdidf: i64, f64); -fp_convert!(__floatunsisf: u32, f32); -fp_convert!(__floatunsidf: u32, f64); -fp_convert!(__floatundidf: u64, f64); +macro_rules! int_to_float_unadj_on_win { + ($intrinsic:ident: $ity:ty, $fty:ty) => { + #[cfg(all(windows, target_pointer_width="64"))] + int_to_float!($intrinsic: $ity, $fty, "unadjusted"); + #[cfg(not(all(windows, target_pointer_width="64")))] + int_to_float!($intrinsic: $ity, $fty, "C"); + }; +} + +int_to_float!(__floatsisf: i32, f32); +int_to_float!(__floatsidf: i32, f64); +int_to_float!(__floatdidf: i64, f64); +int_to_float_unadj_on_win!(__floattisf: i128, f32); +int_to_float_unadj_on_win!(__floattidf: i128, f64); +int_to_float!(__floatunsisf: u32, f32); +int_to_float!(__floatunsidf: u32, f64); +int_to_float!(__floatundidf: u64, f64); +int_to_float_unadj_on_win!(__floatuntisf: u128, f32); +int_to_float_unadj_on_win!(__floatuntidf: u128, f64); #[derive(PartialEq, Debug)] enum Sign { @@ -95,9 +111,12 @@ enum Sign { Negative } -macro_rules! fp_fix { +macro_rules! float_to_int { ($intrinsic:ident: $fty:ty, $ity:ty) => { - pub extern "C" fn $intrinsic(f: $fty) -> $ity { + float_to_int!($intrinsic: $fty, $ity, "C"); + }; + ($intrinsic:ident: $fty:ty, $ity:ty, $abi:tt) => { + pub extern $abi fn $intrinsic(f: $fty) -> $ity { let fixint_min = <$ity>::min_value(); let fixint_max = <$ity>::max_value(); let fixint_bits = <$ity>::bits() as usize; @@ -147,12 +166,25 @@ macro_rules! fp_fix { } } -fp_fix!(__fixsfsi: f32, i32); -fp_fix!(__fixsfdi: f32, i64); -fp_fix!(__fixdfsi: f64, i32); -fp_fix!(__fixdfdi: f64, i64); +macro_rules! float_to_int_unadj_on_win { + ($intrinsic:ident: $fty:ty, $ity:ty) => { + #[cfg(all(windows, target_pointer_width="64"))] + float_to_int!($intrinsic: $fty, $ity, "unadjusted"); + #[cfg(not(all(windows, target_pointer_width="64")))] + float_to_int!($intrinsic: $fty, $ity, "C"); + }; +} -fp_fix!(__fixunssfsi: f32, u32); -fp_fix!(__fixunssfdi: f32, u64); -fp_fix!(__fixunsdfsi: f64, u32); -fp_fix!(__fixunsdfdi: f64, u64); +float_to_int!(__fixsfsi: f32, i32); +float_to_int!(__fixsfdi: f32, i64); +float_to_int_unadj_on_win!(__fixsfti: f32, i128); +float_to_int!(__fixdfsi: f64, i32); +float_to_int!(__fixdfdi: f64, i64); +float_to_int_unadj_on_win!(__fixdfti: f64, i128); + +float_to_int!(__fixunssfsi: f32, u32); +float_to_int!(__fixunssfdi: f32, u64); +float_to_int_unadj_on_win!(__fixunssfti: f32, u128); +float_to_int!(__fixunsdfsi: f64, u32); +float_to_int!(__fixunsdfdi: f64, u64); +float_to_int_unadj_on_win!(__fixunsdfti: f64, u128); diff --git a/tests/fixdfti.rs b/tests/fixdfti.rs new file mode 100644 index 00000000..5bae55e9 --- /dev/null +++ b/tests/fixdfti.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/fixdfti.rs")); diff --git a/tests/fixsfti.rs b/tests/fixsfti.rs new file mode 100644 index 00000000..653157df --- /dev/null +++ b/tests/fixsfti.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/fixsfti.rs")); diff --git a/tests/fixunsdfti.rs b/tests/fixunsdfti.rs new file mode 100644 index 00000000..615e7b33 --- /dev/null +++ b/tests/fixunsdfti.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/fixunsdfti.rs")); diff --git a/tests/fixunssfti.rs b/tests/fixunssfti.rs new file mode 100644 index 00000000..d67f9e79 --- /dev/null +++ b/tests/fixunssfti.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/fixunssfti.rs")); diff --git a/tests/floattidf.rs b/tests/floattidf.rs new file mode 100644 index 00000000..4e4f84dd --- /dev/null +++ b/tests/floattidf.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/floattidf.rs")); diff --git a/tests/floattisf.rs b/tests/floattisf.rs new file mode 100644 index 00000000..2a0657d3 --- /dev/null +++ b/tests/floattisf.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/floattisf.rs")); diff --git a/tests/floatuntidf.rs b/tests/floatuntidf.rs new file mode 100644 index 00000000..4ea272e9 --- /dev/null +++ b/tests/floatuntidf.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/floatuntidf.rs")); diff --git a/tests/floatuntisf.rs b/tests/floatuntisf.rs new file mode 100644 index 00000000..74cd853e --- /dev/null +++ b/tests/floatuntisf.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/floatuntisf.rs"));