fn inject_double_builtin(declaration: &mut FunctionDeclaration, module: &mut Module, name: &str) {
    let width = 8;
    match name {
        "abs" | "sign" => {
            // bits layout
            // bit 0 trough 1 - dims
            for bits in 0..(0b100) {
                let size = match bits {
                    0b00 => None,
                    0b01 => Some(VectorSize::Bi),
                    0b10 => Some(VectorSize::Tri),
                    _ => Some(VectorSize::Quad),
                };
                let kind = Sk::Float;

                let args = vec![match size {
                    Some(size) => TypeInner::Vector { size, kind, width },
                    None => TypeInner::Scalar { kind, width },
                }];

                declaration.overloads.push(module.add_builtin(
                    args,
                    MacroCall::MathFunction(match name {
                        "abs" => MathFunction::Abs,
                        "sign" => MathFunction::Sign,
                        _ => unreachable!(),
                    }),
                ))
            }
        }
        "min" | "max" => {
            // bits layout
            // bit 0 trough 2 - dims
            for bits in 0..(0b111) {
                let (size, second_size) = match bits {
                    0b000 => (None, None),
                    0b001 => (Some(VectorSize::Bi), None),
                    0b010 => (Some(VectorSize::Tri), None),
                    0b011 => (Some(VectorSize::Quad), None),
                    0b100 => (Some(VectorSize::Bi), Some(VectorSize::Bi)),
                    0b101 => (Some(VectorSize::Tri), Some(VectorSize::Tri)),
                    _ => (Some(VectorSize::Quad), Some(VectorSize::Quad)),
                };
                let kind = Sk::Float;

                let args = vec![
                    match size {
                        Some(size) => TypeInner::Vector { size, kind, width },
                        None => TypeInner::Scalar { kind, width },
                    },
                    match second_size {
                        Some(size) => TypeInner::Vector { size, kind, width },
                        None => TypeInner::Scalar { kind, width },
                    },
                ];

                let fun = match name {
                    "max" => MacroCall::Splatted(MathFunction::Max, size, 1),
                    "min" => MacroCall::Splatted(MathFunction::Min, size, 1),
                    _ => unreachable!(),
                };

                declaration.overloads.push(module.add_builtin(args, fun))
            }
        }
        "mix" => {
            // bits layout
            // bit 0 trough 1 - dims
            // bit 2 trough 3 - splatted/boolean
            //
            // 0b1010 is the last element since splatted with single elements
            // is equal to normal single elements
            for bits in 0..(0b1011) {
                let size = match bits & 0b11 {
                    0b00 => Some(VectorSize::Quad),
                    0b01 => Some(VectorSize::Bi),
                    0b10 => Some(VectorSize::Tri),
                    _ => None,
                };
                let kind = Sk::Float;
                let (splatted, boolean) = match bits >> 2 {
                    0b00 => (false, false),
                    0b01 => (false, true),
                    _ => (true, false),
                };

                let ty = |kind, width| match size {
                    Some(size) => TypeInner::Vector { size, kind, width },
                    None => TypeInner::Scalar { kind, width },
                };
                let args = vec![
                    ty(kind, width),
                    ty(kind, width),
                    match (boolean, splatted) {
                        (true, _) => ty(Sk::Bool, crate::BOOL_WIDTH),
                        (_, false) => TypeInner::Scalar { kind, width },
                        _ => ty(kind, width),
                    },
                ];

                declaration.overloads.push(module.add_builtin(
                    args,
                    match boolean {
                        true => MacroCall::MixBoolean,
                        false => MacroCall::Splatted(MathFunction::Mix, size, 2),
                    },
                ))
            }
        }
        "clamp" => {
            // bits layout
            // bit 0 trough 1 - dims
            // bit 2 - splatted
            //
            // 0b110 is the last element since splatted with single elements
            // is equal to normal single elements
            for bits in 0..(0b111) {
                let kind = Sk::Float;
                let size = match bits & 0b11 {
                    0b00 => Some(VectorSize::Bi),
                    0b01 => Some(VectorSize::Tri),
                    0b10 => Some(VectorSize::Quad),
                    _ => None,
                };
                let splatted = bits & 0b100 == 0b100;

                let base_ty = || match size {
                    Some(size) => TypeInner::Vector { size, kind, width },
                    None => TypeInner::Scalar { kind, width },
                };
                let limit_ty = || match splatted {
                    true => TypeInner::Scalar { kind, width },
                    false => base_ty(),
                };

                let args = vec![base_ty(), limit_ty(), limit_ty()];

                declaration
                    .overloads
                    .push(module.add_builtin(args, MacroCall::Clamp(size)))
            }
        }
        // Add common builtins with doubles
        _ => inject_common_builtin(declaration, module, name, 8),
    }
}
/// Injects the builtins into declaration that need doubles
Injects the builtins into declaration that need doubles
Injects the builtins into declaration that need doubles
fn inject_double_builtin(declaration: &mut FunctionDeclaration, module: &mut Module, name: &str) {
    let width = 8;
    match name {
        "abs" | "sign" => {
            // bits layout
            // bit 0 trough 1 - dims
            for bits in 0..(0b100) {
                let size = match bits {
                    0b00 => None,
                    0b01 => Some(VectorSize::Bi),
                    0b10 => Some(VectorSize::Tri),
                    _ => Some(VectorSize::Quad),
                };
                let kind = Sk::Float;
                let args = vec![match size {
                    Some(size) => TypeInner::Vector { size, kind, width },
                    None => TypeInner::Scalar { kind, width },
                }];
                declaration.overloads.push(module.add_builtin(
                    args,
                    MacroCall::MathFunction(match name {
                        "abs" => MathFunction::Abs,
                        "sign" => MathFunction::Sign,
                        _ => unreachable!(),
                    }),
                ))
            }
        }
        "min" | "max" => {
            // bits layout
            // bit 0 trough 2 - dims
            for bits in 0..(0b111) {
                let (size, second_size) = match bits {
                    0b000 => (None, None),
                    0b001 => (Some(VectorSize::Bi), None),
                    0b010 => (Some(VectorSize::Tri), None),
                    0b011 => (Some(VectorSize::Quad), None),
                    0b100 => (Some(VectorSize::Bi), Some(VectorSize::Bi)),
                    0b101 => (Some(VectorSize::Tri), Some(VectorSize::Tri)),
                    _ => (Some(VectorSize::Quad), Some(VectorSize::Quad)),
                };
                let kind = Sk::Float;
                let args = vec![
                    match size {
                        Some(size) => TypeInner::Vector { size, kind, width },
                        None => TypeInner::Scalar { kind, width },
                    },
                    match second_size {
                        Some(size) => TypeInner::Vector { size, kind, width },
                        None => TypeInner::Scalar { kind, width },
                    },
                ];
                let fun = match name {
                    "max" => MacroCall::Splatted(MathFunction::Max, size, 1),
                    "min" => MacroCall::Splatted(MathFunction::Min, size, 1),
                    _ => unreachable!(),
                };
                declaration.overloads.push(module.add_builtin(args, fun))
            }
        }
        "mix" => {
            // bits layout
            // bit 0 trough 1 - dims
            // bit 2 trough 3 - splatted/boolean
            //
            // 0b1010 is the last element since splatted with single elements
            // is equal to normal single elements
            for bits in 0..(0b1011) {
                let size = match bits & 0b11 {
                    0b00 => Some(VectorSize::Quad),
                    0b01 => Some(VectorSize::Bi),
                    0b10 => Some(VectorSize::Tri),
                    _ => None,
                };
                let kind = Sk::Float;
                let (splatted, boolean) = match bits >> 2 {
                    0b00 => (false, false),
                    0b01 => (false, true),
                    _ => (true, false),
                };
                let ty = |kind, width| match size {
                    Some(size) => TypeInner::Vector { size, kind, width },
                    None => TypeInner::Scalar { kind, width },
                };
                let args = vec![
                    ty(kind, width),
                    ty(kind, width),
                    match (boolean, splatted) {
                        (true, _) => ty(Sk::Bool, crate::BOOL_WIDTH),
                        (_, false) => TypeInner::Scalar { kind, width },
                        _ => ty(kind, width),
                    },
                ];
                declaration.overloads.push(module.add_builtin(
                    args,
                    match boolean {
                        true => MacroCall::MixBoolean,
                        false => MacroCall::Splatted(MathFunction::Mix, size, 2),
                    },
                ))
            }
        }
        "clamp" => {
            // bits layout
            // bit 0 trough 1 - dims
            // bit 2 - splatted
            //
            // 0b110 is the last element since splatted with single elements
            // is equal to normal single elements
            for bits in 0..(0b111) {
                let kind = Sk::Float;
                let size = match bits & 0b11 {
                    0b00 => Some(VectorSize::Bi),
                    0b01 => Some(VectorSize::Tri),
                    0b10 => Some(VectorSize::Quad),
                    _ => None,
                };
                let splatted = bits & 0b100 == 0b100;
                let base_ty = || match size {
                    Some(size) => TypeInner::Vector { size, kind, width },
                    None => TypeInner::Scalar { kind, width },
                };
                let limit_ty = || match splatted {
                    true => TypeInner::Scalar { kind, width },
                    false => base_ty(),
                };
                let args = vec![base_ty(), limit_ty(), limit_ty()];
                declaration
                    .overloads
                    .push(module.add_builtin(args, MacroCall::Clamp(size)))
            }
        }
        // Add common builtins with doubles
        _ => inject_common_builtin(declaration, module, name, 8),
    }
}
fn inject_double_builtin ( declaration : & mut FunctionDeclaration , module : & mut Module , name : & str ) { let width = 8 ; match name { " " | " " => { // bits layout // bit 0 trough 1 - dims for bits in 0 .. ( 0b100 ) { let size = match bits { 0b00 => None , 0b01 => Some ( VectorSize :: Bi ) , 0b10 => Some ( VectorSize :: Tri ) , _ => Some ( VectorSize :: Quad ) , } ; let kind = Sk :: Float ; let args = vec ! [ match size { Some ( size ) TypeInner Vector { size kind width } None TypeInner Scalar { kind width } } ] ; declaration . overloads . push ( module . add_builtin ( args , MacroCall :: MathFunction ( match name { " " => MathFunction :: Abs , " " => MathFunction :: Sign , _ => unreachable ! ( ) , } ) , ) ) } } " " | " " => { // bits layout // bit 0 trough 2 - dims for bits in 0 .. ( 0b111 ) { let ( size , second_size ) = match bits { 0b000 => ( None , None ) , 0b001 => ( Some ( VectorSize :: Bi ) , None ) , 0b010 => ( Some ( VectorSize :: Tri ) , None ) , 0b011 => ( Some ( VectorSize :: Quad ) , None ) , 0b100 => ( Some ( VectorSize :: Bi ) , Some ( VectorSize :: Bi ) ) , 0b101 => ( Some ( VectorSize :: Tri ) , Some ( VectorSize :: Tri ) ) , _ => ( Some ( VectorSize :: Quad ) , Some ( VectorSize :: Quad ) ) , } ; let kind = Sk :: Float ; let args = vec ! [ match size { Some ( size ) TypeInner Vector { size kind width } None TypeInner Scalar { kind width } } match second_size { Some ( size ) TypeInner Vector { size kind width } None TypeInner Scalar { kind width } } ] ; let fun = match name { " " => MacroCall :: Splatted ( MathFunction :: Max , size , 1 ) , " " => MacroCall :: Splatted ( MathFunction :: Min , size , 1 ) , _ => unreachable ! ( ) , } ; declaration . overloads . push ( module . add_builtin ( args , fun ) ) } } " " => { // bits layout // bit 0 trough 1 - dims // bit 2 trough 3 - splatted/boolean // // 0b1010 is the last element since splatted with single elements // is equal to normal single elements for bits in 0 .. ( 0b1011 ) { let size = match bits & 0b11 { 0b00 => Some ( VectorSize :: Quad ) , 0b01 => Some ( VectorSize :: Bi ) , 0b10 => Some ( VectorSize :: Tri ) , _ => None , } ; let kind = Sk :: Float ; let ( splatted , boolean ) = match bits >> 2 { 0b00 => ( false , false ) , 0b01 => ( false , true ) , _ => ( true , false ) , } ; let ty = | kind , width | match size { Some ( size ) => TypeInner :: Vector { size , kind , width } , None => TypeInner :: Scalar { kind , width } , } ; let args = vec ! [ ty ( kind width ) ty ( kind width ) match ( boolean splatted ) { ( true ) ty ( Sk Bool crate BOOL_WIDTH ) ( false ) TypeInner Scalar { kind width } ty ( kind width ) } ] ; declaration . overloads . push ( module . add_builtin ( args , match boolean { true => MacroCall :: MixBoolean , false => MacroCall :: Splatted ( MathFunction :: Mix , size , 2 ) , } , ) ) } } " " => { // bits layout // bit 0 trough 1 - dims // bit 2 - splatted // // 0b110 is the last element since splatted with single elements // is equal to normal single elements for bits in 0 .. ( 0b111 ) { let kind = Sk :: Float ; let size = match bits & 0b11 { 0b00 => Some ( VectorSize :: Bi ) , 0b01 => Some ( VectorSize :: Tri ) , 0b10 => Some ( VectorSize :: Quad ) , _ => None , } ; let splatted = bits & 0b100 == 0b100 ; let base_ty = | | match size { Some ( size ) => TypeInner :: Vector { size , kind , width } , None => TypeInner :: Scalar { kind , width } , } ; let limit_ty = | | match splatted { true => TypeInner :: Scalar { kind , width } , false => base_ty ( ) , } ; let args = vec ! [ base_ty ( ) limit_ty ( ) limit_ty ( ) ] ; declaration . overloads . push ( module . add_builtin ( args , MacroCall :: Clamp ( size ) ) ) } } // Add common builtins with doubles _ => inject_common_builtin ( declaration , module , name , 8 ) , } }
Injects the builtins into declaration that need doubles
Injects the builtins into declaration that need doubles
declaration
&mut FunctionDeclaration
module
&mut Module
name
&str
declaration
&mut FunctionDeclaration
module
&mut Module
name
&str