library/stdarch/crates/intrinsic-test/src/arm/types.rs RUST 240 lines View on github.com → Search inside
1use super::intrinsic::ArmIntrinsicType;2use crate::common::cli::Language;3use crate::common::indentation::Indentation;4use crate::common::intrinsic_helpers::{IntrinsicType, IntrinsicTypeDefinition, Sign, TypeKind};56impl IntrinsicTypeDefinition for ArmIntrinsicType {7    /// Gets a string containing the typename for this type in C format.8    fn c_type(&self) -> String {9        let prefix = self.kind.c_prefix();10        let const_prefix = if self.constant { "const " } else { "" };1112        if let (Some(bit_len), simd_len, vec_len) = (self.bit_len, self.simd_len, self.vec_len) {13            match (simd_len, vec_len) {14                (None, None) => format!("{const_prefix}{prefix}{bit_len}_t"),15                (Some(simd), None) => format!("{prefix}{bit_len}x{simd}_t"),16                (Some(simd), Some(vec)) => format!("{prefix}{bit_len}x{simd}x{vec}_t"),17                (None, Some(_)) => todo!("{self:#?}"), // Likely an invalid case18            }19        } else {20            todo!("{self:#?}")21        }22    }2324    fn c_single_vector_type(&self) -> String {25        if let (Some(bit_len), Some(simd_len)) = (self.bit_len, self.simd_len) {26            format!(27                "{prefix}{bit_len}x{simd_len}_t",28                prefix = self.kind.c_prefix()29            )30        } else {31            unreachable!("Shouldn't be called on this type")32        }33    }3435    /// Determines the load function for this type.36    fn get_load_function(&self, language: Language) -> String {37        if let IntrinsicType {38            kind: k,39            bit_len: Some(bl),40            simd_len,41            vec_len,42            ..43        } = &self.data44        {45            let quad = if simd_len.unwrap_or(1) * bl > 64 {46                "q"47            } else {48                ""49            };5051            let choose_workaround = language == Language::C && self.target.contains("v7");52            format!(53                "vld{len}{quad}_{type}{size}",54                type = match k {55                    TypeKind::Int(Sign::Unsigned) => "u",56                    TypeKind::Int(Sign::Signed) => "s",57                    TypeKind::Float => "f",58                    // The ACLE doesn't support 64-bit polynomial loads on Armv759                    // if armv7 and bl == 64, use "s", else "p"60                    TypeKind::Poly => if choose_workaround && *bl == 64 {"s"} else {"p"},61                    x => todo!("get_load_function TypeKind: {x:#?}"),62                },63                size = bl,64                quad = quad,65                len = vec_len.unwrap_or(1),66            )67        } else {68            todo!("get_load_function IntrinsicType: {self:#?}")69        }70    }7172    /// Determines the get lane function for this type.73    fn get_lane_function(&self) -> String {74        if let IntrinsicType {75            kind: k,76            bit_len: Some(bl),77            simd_len,78            ..79        } = &self.data80        {81            let quad = if (simd_len.unwrap_or(1) * bl) > 64 {82                "q"83            } else {84                ""85            };86            format!(87                "vget{quad}_lane_{type}{size}",88                type = match k {89                    TypeKind::Int(Sign::Unsigned) => "u",90                    TypeKind::Int(Sign::Signed) => "s",91                    TypeKind::Float => "f",92                    TypeKind::Poly => "p",93                    x => todo!("get_load_function TypeKind: {x:#?}"),94                },95                size = bl,96                quad = quad,97            )98        } else {99            todo!("get_lane_function IntrinsicType: {self:#?}")100        }101    }102103    /// Generates a std::cout for the intrinsics results that will match the104    /// rust debug output format for the return type. The generated line assumes105    /// there is an int i in scope which is the current pass number.106    fn print_result_c(&self, indentation: Indentation, additional: &str) -> String {107        let lanes = if self.num_vectors() > 1 {108            (0..self.num_vectors())109                .map(|vector| {110                    format!(111                        r#""{ty}(" << {lanes} << ")""#,112                        ty = self.c_single_vector_type(),113                        lanes = (0..self.num_lanes())114                            .map(move |idx| -> std::string::String {115                                let lane_fn = self.get_lane_function();116                                let final_cast = self.generate_final_type_cast();117                                format!(118                                    "{final_cast}{lane_fn}(__return_value.val[{vector}], {idx})"119                                )120                            })121                            .collect::<Vec<_>>()122                            .join(r#" << ", " << "#)123                    )124                })125                .collect::<Vec<_>>()126                .join(r#" << ", " << "#)127        } else if self.num_lanes() > 1 {128            (0..self.num_lanes())129                .map(|idx| -> std::string::String {130                    let lane_fn = self.get_lane_function();131                    let final_cast = self.generate_final_type_cast();132                    format!("{final_cast}{lane_fn}(__return_value, {idx})")133                })134                .collect::<Vec<_>>()135                .join(r#" << ", " << "#)136        } else {137            format!(138                "{promote}cast<{cast}>(__return_value)",139                cast = match self.kind() {140                    TypeKind::Float if self.inner_size() == 16 => "float16_t".to_string(),141                    TypeKind::Float if self.inner_size() == 32 => "float".to_string(),142                    TypeKind::Float if self.inner_size() == 64 => "double".to_string(),143                    TypeKind::Int(Sign::Signed) => format!("int{}_t", self.inner_size()),144                    TypeKind::Int(Sign::Unsigned) => format!("uint{}_t", self.inner_size()),145                    TypeKind::Poly => format!("poly{}_t", self.inner_size()),146                    ty => todo!("print_result_c - Unknown type: {ty:#?}"),147                },148                promote = self.generate_final_type_cast(),149            )150        };151152        format!(153            r#"{indentation}std::cout << "Result {additional}-" << i+1 << ": {ty}" << std::fixed << std::setprecision(150) <<  {lanes} << "{close}" << std::endl;"#,154            ty = if self.is_simd() {155                format!("{}(", self.c_type())156            } else {157                String::from("")158            },159            close = if self.is_simd() { ")" } else { "" },160        )161    }162}163164impl ArmIntrinsicType {165    pub fn from_c(s: &str, target: &str) -> Result<Self, String> {166        const CONST_STR: &str = "const";167        if let Some(s) = s.strip_suffix('*') {168            let (s, constant) = match s.trim().strip_suffix(CONST_STR) {169                Some(stripped) => (stripped, true),170                None => (s, false),171            };172            let s = s.trim_end();173            let temp_return = ArmIntrinsicType::from_c(s, target);174            temp_return.map(|mut op| {175                op.ptr = true;176                op.ptr_constant = constant;177                op178            })179        } else {180            // [const ]TYPE[{bitlen}[x{simdlen}[x{vec_len}]]][_t]181            let (mut s, constant) = match s.strip_prefix(CONST_STR) {182                Some(stripped) => (stripped.trim(), true),183                None => (s, false),184            };185            s = s.strip_suffix("_t").unwrap_or(s);186            let mut parts = s.split('x'); // [[{bitlen}], [{simdlen}], [{vec_len}] ]187            let start = parts.next().ok_or("Impossible to parse type")?;188            if let Some(digit_start) = start.find(|c: char| c.is_ascii_digit()) {189                let (arg_kind, bit_len) = start.split_at(digit_start);190                let arg_kind = arg_kind.parse::<TypeKind>()?;191                let bit_len = bit_len.parse::<u32>().map_err(|err| err.to_string())?;192                let simd_len = match parts.next() {193                    Some(part) => Some(194                        part.parse::<u32>()195                            .map_err(|_| "Couldn't parse simd_len: {part}")?,196                    ),197                    None => None,198                };199                let vec_len = match parts.next() {200                    Some(part) => Some(201                        part.parse::<u32>()202                            .map_err(|_| "Couldn't parse vec_len: {part}")?,203                    ),204                    None => None,205                };206                Ok(ArmIntrinsicType {207                    data: IntrinsicType {208                        ptr: false,209                        ptr_constant: false,210                        constant,211                        kind: arg_kind,212                        bit_len: Some(bit_len),213                        simd_len,214                        vec_len,215                    },216                    target: target.to_string(),217                })218            } else {219                let kind = start.parse::<TypeKind>()?;220                let bit_len = match kind {221                    TypeKind::Int(_) => Some(32),222                    _ => None,223                };224                Ok(ArmIntrinsicType {225                    data: IntrinsicType {226                        ptr: false,227                        ptr_constant: false,228                        constant,229                        kind: start.parse::<TypeKind>()?,230                        bit_len,231                        simd_len: None,232                        vec_len: None,233                    },234                    target: target.to_string(),235                })236            }237        }238    }239}

Code quality findings 12

Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
"{final_cast}{lane_fn}(__return_value.val[{vector}], {idx})"
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
// [const ]TYPE[{bitlen}[x{simdlen}[x{vec_len}]]][_t]
Maintainability Info: `todo!()` or `unimplemented!()` macros indicate incomplete code paths that will panic at runtime if reached. Ensure these are replaced with actual logic before production use.
info correctness todo-unimplemented
(None, Some(_)) => todo!("{self:#?}"), // Likely an invalid case
Maintainability Info: `todo!()` or `unimplemented!()` macros indicate incomplete code paths that will panic at runtime if reached. Ensure these are replaced with actual logic before production use.
info correctness todo-unimplemented
todo!("{self:#?}")
Maintainability Info: `todo!()` or `unimplemented!()` macros indicate incomplete code paths that will panic at runtime if reached. Ensure these are replaced with actual logic before production use.
info correctness todo-unimplemented
x => todo!("get_load_function TypeKind: {x:#?}"),
Maintainability Info: `todo!()` or `unimplemented!()` macros indicate incomplete code paths that will panic at runtime if reached. Ensure these are replaced with actual logic before production use.
info correctness todo-unimplemented
todo!("get_load_function IntrinsicType: {self:#?}")
Maintainability Info: `todo!()` or `unimplemented!()` macros indicate incomplete code paths that will panic at runtime if reached. Ensure these are replaced with actual logic before production use.
info correctness todo-unimplemented
x => todo!("get_load_function TypeKind: {x:#?}"),
Maintainability Info: `todo!()` or `unimplemented!()` macros indicate incomplete code paths that will panic at runtime if reached. Ensure these are replaced with actual logic before production use.
info correctness todo-unimplemented
todo!("get_lane_function IntrinsicType: {self:#?}")
Maintainability Info: `todo!()` or `unimplemented!()` macros indicate incomplete code paths that will panic at runtime if reached. Ensure these are replaced with actual logic before production use.
info correctness todo-unimplemented
ty => todo!("print_result_c - Unknown type: {ty:#?}"),
Info: This standard library function returns a Result. Ensure the Result is handled properly (e.g., using '?', match, if let) rather than potentially panicking with .unwrap() or .expect().
info correctness unhandled-result
part.parse::<u32>()
Info: This standard library function returns a Result. Ensure the Result is handled properly (e.g., using '?', match, if let) rather than potentially panicking with .unwrap() or .expect().
info correctness unhandled-result
part.parse::<u32>()
Info: Ensure 'match' statements are exhaustive. If matching on enums, consider adding a wildcard arm `_ => {}` only if necessary and intentional, as it suppresses warnings about unhandled variants.
info correctness match-wildcard
let bit_len = match kind {

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.