Add a return_reg instruction to the base instruction set.

Register-style return is used by all RISC architectures, so it is
natural to have a shared instruction representation.
This commit is contained in:
Jakob Stoklund Olesen
2017-02-21 13:05:17 -08:00
parent 22bc33fa05
commit b6fa40d6a3
6 changed files with 75 additions and 4 deletions

View File

@@ -222,6 +222,11 @@ pub enum InstructionData {
ty: Type,
data: Box<ReturnData>,
},
ReturnReg {
opcode: Opcode,
ty: Type,
data: Box<ReturnRegData>,
},
}
/// A variable list of `Value` operands used for function call arguments and passing arguments to
@@ -406,6 +411,27 @@ pub struct ReturnData {
pub varargs: VariableArgs,
}
/// Payload of a return instruction.
#[derive(Clone, Debug)]
pub struct ReturnRegData {
/// Return address.
pub arg: Value,
/// Dynamically sized array containing return values.
pub varargs: VariableArgs,
}
impl ReturnRegData {
/// Get references to the arguments.
pub fn arguments(&self) -> [&[Value]; 2] {
[ref_slice(&self.arg), &self.varargs]
}
/// Get mutable references to the arguments.
pub fn arguments_mut(&mut self) -> [&mut [Value]; 2] {
[ref_slice_mut(&mut self.arg), &mut self.varargs]
}
}
/// Analyzing an instruction.
///
/// Avoid large matches on instruction formats by using the methods defined here to examine

View File

@@ -239,6 +239,13 @@ fn write_instruction(w: &mut Write,
writeln!(w, " {}", data.varargs)
}
}
ReturnReg { ref data, .. } => {
if data.varargs.is_empty() {
writeln!(w, "{}", data.arg)
} else {
writeln!(w, "{}, {}", data.arg, data.varargs)
}
}
}
}