Integer add with carry instructions.
Integer addition with carry in/out/both.
This commit is contained in:
@@ -149,6 +149,11 @@ pub enum InstructionData {
|
||||
ty: Type,
|
||||
args: [Value; 3],
|
||||
},
|
||||
TernaryOverflow {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
data: Box<TernaryOverflowData>,
|
||||
},
|
||||
InsertLane {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
@@ -254,6 +259,19 @@ impl Default for VariableArgs {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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],
|
||||
}
|
||||
|
||||
impl Display for TernaryOverflowData {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
write!(f, "{}, {}, {}", self.args[0], self.args[1], self.args[2])
|
||||
}
|
||||
}
|
||||
|
||||
/// Payload data for jump instructions. These need to carry lists of EBB arguments that won't fit
|
||||
/// in the allowed InstructionData size.
|
||||
#[derive(Clone, Debug)]
|
||||
|
||||
@@ -190,6 +190,7 @@ fn write_instruction(w: &mut Write,
|
||||
BinaryImmRev { imm, arg, .. } => writeln!(w, " {}, {}", imm, arg),
|
||||
BinaryOverflow { args, .. } => writeln!(w, " {}, {}", args[0], args[1]),
|
||||
Ternary { args, .. } => writeln!(w, " {}, {}, {}", args[0], args[1], args[2]),
|
||||
TernaryOverflow { ref data, .. } => writeln!(w, " {}", data),
|
||||
InsertLane { lane, args, .. } => writeln!(w, " {}, {}, {}", args[0], lane, args[1]),
|
||||
ExtractLane { lane, arg, .. } => writeln!(w, " {}, {}", arg, lane),
|
||||
IntCompare { cond, args, .. } => writeln!(w, " {}, {}, {}", cond, args[0], args[1]),
|
||||
|
||||
@@ -13,8 +13,8 @@ use cretonne::ir::{Function, Ebb, Opcode, Value, Type, FunctionName, StackSlotDa
|
||||
use cretonne::ir::types::{VOID, Signature, ArgumentType, ArgumentExtension};
|
||||
use cretonne::ir::immediates::{Imm64, Ieee32, Ieee64};
|
||||
use cretonne::ir::entities::{AnyEntity, NO_EBB, NO_INST, NO_VALUE};
|
||||
use cretonne::ir::instructions::{InstructionFormat, InstructionData, VariableArgs, JumpData,
|
||||
BranchData, ReturnData};
|
||||
use cretonne::ir::instructions::{InstructionFormat, InstructionData, VariableArgs,
|
||||
TernaryOverflowData, JumpData, BranchData, ReturnData};
|
||||
use cretonne::isa;
|
||||
use cretonne::settings;
|
||||
use testfile::{TestFile, Details, Comment};
|
||||
@@ -138,6 +138,10 @@ impl Context {
|
||||
try!(self.map.rewrite_values(args, loc));
|
||||
}
|
||||
|
||||
InstructionData::TernaryOverflow { ref mut data, .. } => {
|
||||
try!(self.map.rewrite_values(&mut data.args, loc));
|
||||
}
|
||||
|
||||
InstructionData::Jump { ref mut data, .. } => {
|
||||
try!(self.map.rewrite_ebb(&mut data.destination, loc));
|
||||
try!(self.map.rewrite_values(&mut data.arguments, loc));
|
||||
@@ -1066,6 +1070,22 @@ impl<'a> Parser<'a> {
|
||||
args: [ctrl_arg, true_arg, false_arg],
|
||||
}
|
||||
}
|
||||
InstructionFormat::TernaryOverflow => {
|
||||
// Names here refer to the `iadd_carry` instruction.
|
||||
let lhs = try!(self.match_value("expected SSA value first operand"));
|
||||
try!(self.match_token(Token::Comma, "expected ',' between operands"));
|
||||
let rhs = try!(self.match_value("expected SSA value second operand"));
|
||||
try!(self.match_token(Token::Comma, "expected ',' between operands"));
|
||||
let cin = try!(self.match_value("expected SSA value third operand"));
|
||||
InstructionData::TernaryOverflow {
|
||||
opcode: opcode,
|
||||
ty: VOID,
|
||||
data: Box::new(TernaryOverflowData {
|
||||
second_result: NO_VALUE,
|
||||
args: [lhs, rhs, cin],
|
||||
}),
|
||||
}
|
||||
}
|
||||
InstructionFormat::Jump => {
|
||||
// Parse the destination EBB number. Don't translate source to local numbers yet.
|
||||
let ebb_num = try!(self.match_ebb("expected jump destination EBB"));
|
||||
|
||||
Reference in New Issue
Block a user