79072884

Date: 2024-10-10 05:56:39
Score: 2.5
Natty:
Report link

Thanks, everyone! For future reference: I have successfully optimized memory scanning. I hope my code is clear: (For now I assume every brainfuck code is well-written):

                TokenType::MemoryScan(n) => { 
                        let loop_label = format!("loop_scan{}", label_counter);
                        label_counter += 1;
                        let found_label = format!("loop_scan{}", label_counter);
                        label_counter += 1;
                        let not_found_label = format!("loop_scan{}", label_counter);
                        label_counter += 1;
                        
                        assembly.push_str(&format!("{}:\n", loop_label));  
                        assembly.push_str("    ld1.16b {v0}, [x19]\n"); // Load 16 bytes to registers             
                        assembly.push_str("    cmeq.16b v0, v0, #0\n"); // Compare with zeros  
                        // Keep the zeros only poisitions for [>>] [>>>>] [>>>>>>>>] (Just mask the certain positions)
                        if *n == 2 {
                            assembly.push_str("    movi.8h  v1, #1\n");
                        } else if *n == 4 {
                            assembly.push_str("    movi.4s  v1, #1\n");
                        } else if *n == 8 {
                            assembly.push_str("    movi.2d  v1, #0x000000000000ff\n");
                        }
                        if *n == 2 || *n == 4 || *n == 8 {
                            assembly.push_str("    and.16b  v0, v0, v1\n");
                            assembly.push_str("    shl.16b  v0, v0, #7\n");
                            assembly.push_str("    sshr.16b v0, v0, #7\n");
                        }          
                        // Find the first matching zero
                        assembly.push_str("    shrn.8b v0, v0, #4\n"); // Do shrn: make it 64 bits value             
                        assembly.push_str("    fmov x8, d0\n");  // Move the 64 bit value to general purpose reg
                        assembly.push_str("    rbit x9, x8\n"); // rotate the bits (We do not have ctz so we do rbit then clz which is ctz)
                        assembly.push_str("    clz x9, x9\n"); // Count leading zeros
                        assembly.push_str("    ubfx x9, x9, #2, #30\n"); // Do shifting
                        // Compare x9 with 16 (indicating 64 bits of zeros, since 64 >> 2 = 16)
                        assembly.push_str("    cmp    x9, #16\n"); 
                        // If x9 equals 16, jump to the 'not_found_label'
                        assembly.push_str(&format!("    b.eq    {}\n", not_found_label));
                        // Else jump to the found label
                        assembly.push_str(&format!("    b {}\n", found_label)); 
                        assembly.push_str(&format!("{}:\n", not_found_label)); // Not found label
                        // Increment pointer +16 to load the next 16 bytes
                        assembly.push_str("    add x19, x19, #16\n"); 
                        // Jump back for the next 16 bytes
                        assembly.push_str(&format!("    b {}\n", loop_label)); 
                        // If found adjust the pointer +x9 and continue
                        assembly.push_str(&format!("{}:\n", found_label));
                        assembly.push_str("    add x19, x19, x9\n");            
                },  
Reasons:
  • Blacklisted phrase (0.5): Thanks
  • Blacklisted phrase (2): fuck
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (1):
Posted by: user27680699