fn funccall(&mut self, fn_name: &str, num_params: usize) -> usize {
        let r = self.alloc_register();

        self.gen_unary_op("call", Operand::Func(fn_name.to_string()));

        if num_params > PARAM_REGS.len() {
            for _ in 0..(num_params - PARAM_REGS.len()) {
                // Temporarily use this register to pop out args
                self.gen_unary_op("popq", Operand::Reg(self.reg_name(r)));
            }
        }

        // TODO: Unpop registers we spilled earlier
        for r in PARAM_REGS.iter().rev() {
            self.gen_unary_op("popq", Operand::Reg(r.to_string()));
        }

        self.gen_binary_op(
            "movq",
            Operand::Reg("rax".into()),
            Operand::Reg(self.reg_name(r)),
        );
        return r;
    }
// TODO: Do we need to copy return val to a register if no one intends
// use it? Especially in the case of void functions.
Do we need to copy return val to a register if no one intends
use it. Especially in the case of void functions.
Do we need to copy return val to a register if no one intends use it . Especially in the case of void functions .
fn funccall(&mut self, fn_name: &str, num_params: usize) -> usize {
        let r = self.alloc_register();
        self.gen_unary_op("call", Operand::Func(fn_name.to_string()));
        if num_params > PARAM_REGS.len() {
            for _ in 0..(num_params - PARAM_REGS.len()) {
                // Temporarily use this register to pop out args
                self.gen_unary_op("popq", Operand::Reg(self.reg_name(r)));
            }
        }
        // TODO: Unpop registers we spilled earlier
        for r in PARAM_REGS.iter().rev() {
            self.gen_unary_op("popq", Operand::Reg(r.to_string()));
        }
        self.gen_binary_op(
            "movq",
            Operand::Reg("rax".into()),
            Operand::Reg(self.reg_name(r)),
        );
        return r;
    }
fn funccall ( & mut self , fn_name : & str , num_params : usize ) -> usize { let r = self . alloc_register ( ) ; self . gen_unary_op ( " " , Operand :: Func ( fn_name . to_string ( ) ) ) ; if num_params > PARAM_REGS . len ( ) { for _ in 0 .. ( num_params - PARAM_REGS . len ( ) ) { // Temporarily use this register to pop out args self . gen_unary_op ( " " , Operand :: Reg ( self . reg_name ( r ) ) ) ; } } // TODO: Unpop registers we spilled earlier for r in PARAM_REGS . iter ( ) . rev ( ) { self . gen_unary_op ( " " , Operand :: Reg ( r . to_string ( ) ) ) ; } self . gen_binary_op ( " " , Operand :: Reg ( " " . into ( ) ) , Operand :: Reg ( self . reg_name ( r ) ) , ) ; return r ; }
TODO: Do we need to copy return val to a register if no one intends
use it?
TODO : Do we need to copy return val to a register if no one intends use it?
&mut self
fn_name
&str
num_params
usize