My suggestions for Rust: More Operators and easy API

I think that the operators in Rust is too less! I think we can add more trait for Rust.Such as INC(increase),DEC(decrease),PUSH(push into stack,unsafe),POP(pop from stack,unsafe).I hope the Rust can provide more easy API for the programmers of the Rust.This is my code that design the DEC operator.It is verry useful when subtruct 1. my email is "ora_in_py@hotmail.com" and my URL of this crate in the Cargo is " ooo - crates.io: Rust Package Registry".

pub trait DecAssign{
    fn dec_assign(&mut self);
}


impl DecAssign for u8{
    fn dec_assign(&mut self) {
        unsafe{
            std::arch::asm!("DEC BYTE PTR [{}];", in(reg) self, options(nostack, nomem));
        };
    }
}


impl DecAssign for u16{
    fn dec_assign(&mut self) {
        unsafe{
            std::arch::asm!("DEC WORD PTR [{}];", in(reg) self, options(nostack, nomem));
        };
    }
}


impl DecAssign for u32{
    fn dec_assign(&mut self) {
        unsafe{
            std::arch::asm!("DEC DWORD PTR [{}];", in(reg) self, options(nostack, nomem));
        };
    }
}


impl DecAssign for u64{
    fn dec_assign(&mut self) {
        unsafe{
            std::arch::asm!("DEC QWORD PTR [{}];", in(reg) self, options(nostack, nomem));
        };
    }
}


impl DecAssign for usize{
    fn dec_assign(&mut self) {
        unsafe{
            std::arch::asm!("DEC QWORD PTR [{}];", in(reg) self, options(nostack, nomem));
        };
    }
}


impl DecAssign for i8{
    fn dec_assign(&mut self) {
        unsafe{
            std::arch::asm!("DEC BYTE PTR [{}];", in(reg) self, options(nostack, nomem));
        };
    }
}


impl DecAssign for i16{
    fn dec_assign(&mut self) {
        unsafe{
            std::arch::asm!("DEC WORD PTR [{}];", in(reg) self, options(nostack, nomem));
        };
    }
}


impl DecAssign for i32{
    fn dec_assign(&mut self) {
        unsafe{
            std::arch::asm!("DEC DWORD PTR [{}];", in(reg) self, options(nostack, nomem));
        };
    }
}


impl DecAssign for i64{
    fn dec_assign(&mut self) {
        unsafe{
            std::arch::asm!("DEC QWORD PTR [{}];", in(reg) self, options(nostack, nomem));
        };
    }
}


impl DecAssign for isize{
    fn dec_assign(&mut self) {
        unsafe{
            std::arch::asm!("DEC QWORD PTR [{}];", in(reg) self, options(nostack, nomem));
        };
    }
}

Please explain what you want to do with these that you cannot easily do today.

Please also understand that LLVM (like all modern optimizing compilers) is not a macro assembler. It wants certain things to be completely under its control. One of those things is the stack pointer. Therefore, we cannot give you the ability to shove x86 PUSH and POP instructions into the generated machine code wherever you want. But if you explain your larger goals there might be some other way to achieve them.

4 Likes

hello,nice to meet you. you are right,the push command as the pop command is invalid in x86-64 mode.but I can try to belive another instructions.such as "MOV","MOVZX","MOVSX","INC","DEC","INT" instruction.My aim is Beliving provide API in Rust with Any Instruct.

Well, we already have std::arch::asm!, so I need you to take another step backward in your thinking.

What do you want to DO with this API that you're asking for?

2 Likes

Rust already provides access to those instructions via higher-level operations. For example, if INC is the best way to implement it, you can generate an INC instruction on x86-64 CPUs with:

x += 1;

Similar applies to all the MOV variants, DEC, and other instructions. If you need to force specific x86-64 instruction sequences, you can use inline assembly, or intrinsics directly.

Note, too, that one advantage of using the higher-level operations is that Rust will automatically change the instructions in use if you change CPU; for example, there is no INC or DEC instruction on an Arm CPU core, but that's OK because Rust knows this, and if you target an Arm CPU core (such as the Cortex-M0), it'll generate Arm instructions instead that have the same effect.

Additionally, the higher-level operations are understood by the optimizer; if I write:

x += 1;
x *= 2;

The Rust compiler knows enough about x86-64 to know whether this is best implemented as INC and a left shift, or a single LEA instruction, or indeed any other instruction sequence with the same effect. Further, the Rust compiler can eliminate operations trivially:

x += 1;
x -= 1;

does not compile to INC followed by DEC, but to nothing in release mode, since the compiler can see that there's no side effect here.

9 Likes

I've already programmed a part of the module for this problem, brother, you can't spoil my fun like this, you let my hard work all day go to waste? I hope you can say it sooner or don't make me feel so bad next time. Thank you!