Move second_result outside boxed storage.
In instruction formats that have multiple results AND boxed storage, place the second_result field outside the boxed storage. The 16-byte instruction format has room for opcode, type, second_result in the first 8 bytes, and the boxed pointer in the last 8 bytes. This provides a simpler implementation of the second_result() and second_result_mut() InstructionData methods.
This commit is contained in:
@@ -158,6 +158,7 @@ pub enum InstructionData {
|
||||
TernaryOverflow {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
second_result: Value,
|
||||
data: Box<TernaryOverflowData>,
|
||||
},
|
||||
InsertLane {
|
||||
@@ -203,6 +204,7 @@ pub enum InstructionData {
|
||||
Call {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
second_result: Value,
|
||||
data: Box<CallData>,
|
||||
},
|
||||
Return {
|
||||
@@ -284,7 +286,6 @@ impl Display for UnaryImmVectorData {
|
||||
/// Payload data for ternary instructions with multiple results, such as `iadd_carry`.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TernaryOverflowData {
|
||||
pub second_result: Value,
|
||||
pub args: [Value; 3],
|
||||
}
|
||||
|
||||
@@ -334,9 +335,6 @@ impl Display for BranchData {
|
||||
/// Payload of a call instruction.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CallData {
|
||||
/// Second result value for a call producing multiple return values.
|
||||
second_result: Value,
|
||||
|
||||
/// Callee function.
|
||||
pub func_ref: FuncRef,
|
||||
|
||||
|
||||
@@ -1089,10 +1089,8 @@ impl<'a> Parser<'a> {
|
||||
InstructionData::TernaryOverflow {
|
||||
opcode: opcode,
|
||||
ty: VOID,
|
||||
data: Box::new(TernaryOverflowData {
|
||||
second_result: NO_VALUE,
|
||||
args: [lhs, rhs, cin],
|
||||
}),
|
||||
data: Box::new(TernaryOverflowData { args: [lhs, rhs, cin] }),
|
||||
}
|
||||
}
|
||||
InstructionFormat::Jump => {
|
||||
|
||||
@@ -87,23 +87,16 @@ def gen_instruction_data_impl(fmt):
|
||||
'pub fn second_result(&self) -> Option<Value> {', '}'):
|
||||
with fmt.indented('match *self {', '}'):
|
||||
for f in cretonne.InstructionFormat.all_formats:
|
||||
if not f.multiple_results:
|
||||
# Single or no results.
|
||||
fmt.line(
|
||||
'InstructionData::{} {{ .. }} => None,'
|
||||
.format(f.name))
|
||||
elif f.boxed_storage:
|
||||
# Multiple results, boxed storage.
|
||||
fmt.line(
|
||||
'InstructionData::' + f.name +
|
||||
' { ref data, .. }' +
|
||||
' => Some(data.second_result),')
|
||||
else:
|
||||
# Multiple results, inline storage.
|
||||
if f.multiple_results:
|
||||
fmt.line(
|
||||
'InstructionData::' + f.name +
|
||||
' { second_result, .. }' +
|
||||
' => Some(second_result),')
|
||||
else:
|
||||
# Single or no results.
|
||||
fmt.line(
|
||||
'InstructionData::{} {{ .. }} => None,'
|
||||
.format(f.name))
|
||||
|
||||
fmt.doc_comment('Mutable reference to second result value, if any.')
|
||||
with fmt.indented(
|
||||
@@ -111,23 +104,16 @@ def gen_instruction_data_impl(fmt):
|
||||
" -> Option<&'a mut Value> {", '}'):
|
||||
with fmt.indented('match *self {', '}'):
|
||||
for f in cretonne.InstructionFormat.all_formats:
|
||||
if not f.multiple_results:
|
||||
# Single or no results.
|
||||
fmt.line(
|
||||
'InstructionData::{} {{ .. }} => None,'
|
||||
.format(f.name))
|
||||
elif f.boxed_storage:
|
||||
# Multiple results, boxed storage.
|
||||
fmt.line(
|
||||
'InstructionData::' + f.name +
|
||||
' { ref mut data, .. }' +
|
||||
' => Some(&mut data.second_result),')
|
||||
else:
|
||||
# Multiple results, inline storage.
|
||||
if f.multiple_results:
|
||||
fmt.line(
|
||||
'InstructionData::' + f.name +
|
||||
' { ref mut second_result, .. }' +
|
||||
' => Some(second_result),')
|
||||
else:
|
||||
# Single or no results.
|
||||
fmt.line(
|
||||
'InstructionData::{} {{ .. }} => None,'
|
||||
.format(f.name))
|
||||
|
||||
fmt.doc_comment('Get the controlling type variable operand.')
|
||||
with fmt.indented(
|
||||
|
||||
Reference in New Issue
Block a user