Convert return formats to value lists.
With the Return and ReturnReg formats converted to using value lists for storing their arguments, thee are no remaining instruction formats with variable argument lists in boxed storage. The Return and ReturnReg formats are also going to be merged since they are identical now.
This commit is contained in:
@@ -51,8 +51,8 @@ Call = InstructionFormat(
|
|||||||
IndirectCall = InstructionFormat(
|
IndirectCall = InstructionFormat(
|
||||||
sig_ref, VALUE, VARIABLE_ARGS,
|
sig_ref, VALUE, VARIABLE_ARGS,
|
||||||
multiple_results=True, value_list=True)
|
multiple_results=True, value_list=True)
|
||||||
Return = InstructionFormat(VARIABLE_ARGS, boxed_storage=True)
|
Return = InstructionFormat(VARIABLE_ARGS, value_list=True)
|
||||||
ReturnReg = InstructionFormat(VALUE, VARIABLE_ARGS, boxed_storage=True)
|
ReturnReg = InstructionFormat(VALUE, VARIABLE_ARGS, value_list=True)
|
||||||
|
|
||||||
# Finally extract the names of global variables in this module.
|
# Finally extract the names of global variables in this module.
|
||||||
InstructionFormat.extract_names(globals())
|
InstructionFormat.extract_names(globals())
|
||||||
|
|||||||
@@ -63,6 +63,10 @@ class InstructionFormat(object):
|
|||||||
self.value_operands = tuple(
|
self.value_operands = tuple(
|
||||||
i for i, k in enumerate(self.kinds) if k is VALUE)
|
i for i, k in enumerate(self.kinds) if k is VALUE)
|
||||||
|
|
||||||
|
# We require a value list for storage of variable arguments.
|
||||||
|
if VARIABLE_ARGS in self.kinds:
|
||||||
|
assert self.has_value_list, "Need a value list for variable args"
|
||||||
|
|
||||||
# The typevar_operand argument must point to a 'value' operand.
|
# The typevar_operand argument must point to a 'value' operand.
|
||||||
self.typevar_operand = kwargs.get('typevar_operand', None) # type: int
|
self.typevar_operand = kwargs.get('typevar_operand', None) # type: int
|
||||||
if self.typevar_operand is not None:
|
if self.typevar_operand is not None:
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
use ir::{types, instructions};
|
use ir::{types, instructions};
|
||||||
use ir::{InstructionData, DataFlowGraph, Cursor};
|
use ir::{InstructionData, DataFlowGraph, Cursor};
|
||||||
use ir::{Opcode, Type, Inst, Value, Ebb, JumpTable, VariableArgs, SigRef, FuncRef, ValueList};
|
use ir::{Opcode, Type, Inst, Value, Ebb, JumpTable, SigRef, FuncRef, ValueList};
|
||||||
use ir::immediates::{Imm64, Uimm8, Ieee32, Ieee64, ImmVector};
|
use ir::immediates::{Imm64, Uimm8, Ieee32, Ieee64, ImmVector};
|
||||||
use ir::condcodes::{IntCC, FloatCC};
|
use ir::condcodes::{IntCC, FloatCC};
|
||||||
|
|
||||||
|
|||||||
@@ -228,12 +228,12 @@ pub enum InstructionData {
|
|||||||
Return {
|
Return {
|
||||||
opcode: Opcode,
|
opcode: Opcode,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
data: Box<ReturnData>,
|
args: ValueList,
|
||||||
},
|
},
|
||||||
ReturnReg {
|
ReturnReg {
|
||||||
opcode: Opcode,
|
opcode: Opcode,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
data: Box<ReturnRegData>,
|
args: ValueList,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,34 +331,6 @@ impl Display for TernaryOverflowData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Payload of a return instruction.
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct ReturnData {
|
|
||||||
/// Dynamically sized array containing return values.
|
|
||||||
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.
|
/// Analyzing an instruction.
|
||||||
///
|
///
|
||||||
/// Avoid large matches on instruction formats by using the methods defined here to examine
|
/// Avoid large matches on instruction formats by using the methods defined here to examine
|
||||||
|
|||||||
@@ -282,19 +282,19 @@ fn write_instruction(w: &mut Write,
|
|||||||
args[0],
|
args[0],
|
||||||
DisplayValues(&args[1..]))
|
DisplayValues(&args[1..]))
|
||||||
}
|
}
|
||||||
Return { ref data, .. } => {
|
Return { ref args, .. } => {
|
||||||
if data.varargs.is_empty() {
|
if args.is_empty() {
|
||||||
writeln!(w, "")
|
writeln!(w, "")
|
||||||
} else {
|
} else {
|
||||||
writeln!(w, " {}", data.varargs)
|
writeln!(w,
|
||||||
|
" {}",
|
||||||
|
DisplayValues(args.as_slice(&func.dfg.value_lists)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ReturnReg { ref data, .. } => {
|
ReturnReg { ref args, .. } => {
|
||||||
if data.varargs.is_empty() {
|
writeln!(w,
|
||||||
writeln!(w, " {}", data.arg)
|
" {}",
|
||||||
} else {
|
DisplayValues(args.as_slice(&func.dfg.value_lists)))
|
||||||
writeln!(w, " {}, {}", data.arg, data.varargs)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use cretonne::ir::types::VOID;
|
|||||||
use cretonne::ir::immediates::{Imm64, Ieee32, Ieee64};
|
use cretonne::ir::immediates::{Imm64, Ieee32, Ieee64};
|
||||||
use cretonne::ir::entities::AnyEntity;
|
use cretonne::ir::entities::AnyEntity;
|
||||||
use cretonne::ir::instructions::{InstructionFormat, InstructionData, VariableArgs,
|
use cretonne::ir::instructions::{InstructionFormat, InstructionData, VariableArgs,
|
||||||
TernaryOverflowData, ReturnData, ReturnRegData};
|
TernaryOverflowData};
|
||||||
use cretonne::isa::{self, TargetIsa, Encoding};
|
use cretonne::isa::{self, TargetIsa, Encoding};
|
||||||
use cretonne::settings;
|
use cretonne::settings;
|
||||||
use testfile::{TestFile, Details, Comment};
|
use testfile::{TestFile, Details, Comment};
|
||||||
@@ -217,13 +217,12 @@ impl<'a> Context<'a> {
|
|||||||
self.map.rewrite_values(args.as_mut_slice(value_lists), loc)?;
|
self.map.rewrite_values(args.as_mut_slice(value_lists), loc)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
InstructionData::Return { ref mut data, .. } => {
|
InstructionData::Return { ref mut args, .. } => {
|
||||||
self.map.rewrite_values(&mut data.varargs, loc)?;
|
self.map.rewrite_values(args.as_mut_slice(value_lists), loc)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
InstructionData::ReturnReg { ref mut data, .. } => {
|
InstructionData::ReturnReg { ref mut args, .. } => {
|
||||||
self.map.rewrite_value(&mut data.arg, loc)?;
|
self.map.rewrite_values(args.as_mut_slice(value_lists), loc)?;
|
||||||
self.map.rewrite_values(&mut data.varargs, loc)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1527,7 +1526,7 @@ impl<'a> Parser<'a> {
|
|||||||
InstructionData::Return {
|
InstructionData::Return {
|
||||||
opcode: opcode,
|
opcode: opcode,
|
||||||
ty: VOID,
|
ty: VOID,
|
||||||
data: Box::new(ReturnData { varargs: args }),
|
args: args.into_value_list(&[], &mut ctx.function.dfg.value_lists),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InstructionFormat::ReturnReg => {
|
InstructionFormat::ReturnReg => {
|
||||||
@@ -1540,10 +1539,7 @@ impl<'a> Parser<'a> {
|
|||||||
InstructionData::ReturnReg {
|
InstructionData::ReturnReg {
|
||||||
opcode: opcode,
|
opcode: opcode,
|
||||||
ty: VOID,
|
ty: VOID,
|
||||||
data: Box::new(ReturnRegData {
|
args: args.into_value_list(&[raddr], &mut ctx.function.dfg.value_lists),
|
||||||
arg: raddr,
|
|
||||||
varargs: args,
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InstructionFormat::BranchTable => {
|
InstructionFormat::BranchTable => {
|
||||||
|
|||||||
Reference in New Issue
Block a user