Add an icmp_imm instruction.
Compare a scalar integer to an immediate constant. Both Intel and RISC-V ISAs have this operation. This requires the addition of a new IntCompareImm instruction format.
This commit is contained in:
@@ -678,6 +678,7 @@ Integer operations
|
|||||||
------------------
|
------------------
|
||||||
|
|
||||||
.. autoinst:: icmp
|
.. autoinst:: icmp
|
||||||
|
.. autoinst:: icmp_imm
|
||||||
.. autoinst:: iadd
|
.. autoinst:: iadd
|
||||||
.. autoinst:: iadd_imm
|
.. autoinst:: iadd_imm
|
||||||
.. autoinst:: iadd_cin
|
.. autoinst:: iadd_cin
|
||||||
|
|||||||
@@ -54,14 +54,14 @@ function icmp(i32, i32) {
|
|||||||
ebb0(vx0: i32, vx1: i32):
|
ebb0(vx0: i32, vx1: i32):
|
||||||
v0 = icmp eq, vx0, vx1
|
v0 = icmp eq, vx0, vx1
|
||||||
v1 = icmp ult, vx0, vx1
|
v1 = icmp ult, vx0, vx1
|
||||||
v2 = icmp sge, vx0, vx1
|
v2 = icmp_imm sge, vx0, -12
|
||||||
v3 = irsub_imm vx1, 45
|
v3 = irsub_imm vx1, 45
|
||||||
}
|
}
|
||||||
; sameln: function icmp(i32, i32) {
|
; sameln: function icmp(i32, i32) {
|
||||||
; nextln: ebb0(vx0: i32, vx1: i32):
|
; nextln: ebb0(vx0: i32, vx1: i32):
|
||||||
; nextln: v0 = icmp eq, vx0, vx1
|
; nextln: v0 = icmp eq, vx0, vx1
|
||||||
; nextln: v1 = icmp ult, vx0, vx1
|
; nextln: v1 = icmp ult, vx0, vx1
|
||||||
; nextln: v2 = icmp sge, vx0, vx1
|
; nextln: v2 = icmp_imm sge, vx0, -12
|
||||||
; nextln: v3 = irsub_imm vx1, 45
|
; nextln: v3 = irsub_imm vx1, 45
|
||||||
; nextln: }
|
; nextln: }
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ InsertLane = InstructionFormat(VALUE, ('lane', uimm8), VALUE)
|
|||||||
ExtractLane = InstructionFormat(VALUE, ('lane', uimm8))
|
ExtractLane = InstructionFormat(VALUE, ('lane', uimm8))
|
||||||
|
|
||||||
IntCompare = InstructionFormat(intcc, VALUE, VALUE)
|
IntCompare = InstructionFormat(intcc, VALUE, VALUE)
|
||||||
|
IntCompareImm = InstructionFormat(intcc, VALUE, imm64)
|
||||||
FloatCompare = InstructionFormat(floatcc, VALUE, VALUE)
|
FloatCompare = InstructionFormat(floatcc, VALUE, VALUE)
|
||||||
|
|
||||||
Jump = InstructionFormat(ebb, VARIABLE_ARGS)
|
Jump = InstructionFormat(ebb, VARIABLE_ARGS)
|
||||||
|
|||||||
@@ -367,6 +367,22 @@ icmp = Instruction(
|
|||||||
""",
|
""",
|
||||||
ins=(Cond, x, y), outs=a)
|
ins=(Cond, x, y), outs=a)
|
||||||
|
|
||||||
|
a = Operand('a', b1)
|
||||||
|
x = Operand('x', iB)
|
||||||
|
Y = Operand('Y', imm64)
|
||||||
|
|
||||||
|
icmp_imm = Instruction(
|
||||||
|
'icmp_imm', r"""
|
||||||
|
Compare scalar integer to a constant.
|
||||||
|
|
||||||
|
This is the same as the :inst:`icmp` instruction, except one operand is
|
||||||
|
an immediate constant.
|
||||||
|
|
||||||
|
This instruction can only compare scalars. Use :inst:`icmp` for
|
||||||
|
lane-wise vector comparisons.
|
||||||
|
""",
|
||||||
|
ins=(Cond, x, Y), outs=a)
|
||||||
|
|
||||||
a = Operand('a', Int)
|
a = Operand('a', Int)
|
||||||
x = Operand('x', Int)
|
x = Operand('x', Int)
|
||||||
y = Operand('y', Int)
|
y = Operand('y', Int)
|
||||||
|
|||||||
@@ -175,6 +175,13 @@ pub enum InstructionData {
|
|||||||
cond: IntCC,
|
cond: IntCC,
|
||||||
args: [Value; 2],
|
args: [Value; 2],
|
||||||
},
|
},
|
||||||
|
IntCompareImm {
|
||||||
|
opcode: Opcode,
|
||||||
|
ty: Type,
|
||||||
|
cond: IntCC,
|
||||||
|
arg: Value,
|
||||||
|
imm: Imm64,
|
||||||
|
},
|
||||||
FloatCompare {
|
FloatCompare {
|
||||||
opcode: Opcode,
|
opcode: Opcode,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
|
|||||||
@@ -251,6 +251,7 @@ impl<'a> Verifier<'a> {
|
|||||||
&InsertLane { .. } |
|
&InsertLane { .. } |
|
||||||
&ExtractLane { .. } |
|
&ExtractLane { .. } |
|
||||||
&IntCompare { .. } |
|
&IntCompare { .. } |
|
||||||
|
&IntCompareImm { .. } |
|
||||||
&FloatCompare { .. } => {}
|
&FloatCompare { .. } => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,4 +683,4 @@ mod tests {
|
|||||||
let verifier = Verifier::new(&func);
|
let verifier = Verifier::new(&func);
|
||||||
assert_err_with_msg!(verifier.run(), "instruction format");
|
assert_err_with_msg!(verifier.run(), "instruction format");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -260,6 +260,7 @@ pub fn write_operands(w: &mut Write, dfg: &DataFlowGraph, inst: Inst) -> Result
|
|||||||
InsertLane { lane, args, .. } => write!(w, " {}, {}, {}", args[0], lane, args[1]),
|
InsertLane { lane, args, .. } => write!(w, " {}, {}, {}", args[0], lane, args[1]),
|
||||||
ExtractLane { lane, arg, .. } => write!(w, " {}, {}", arg, lane),
|
ExtractLane { lane, arg, .. } => write!(w, " {}, {}", arg, lane),
|
||||||
IntCompare { cond, args, .. } => write!(w, " {}, {}, {}", cond, args[0], args[1]),
|
IntCompare { cond, args, .. } => write!(w, " {}, {}, {}", cond, args[0], args[1]),
|
||||||
|
IntCompareImm { cond, arg, imm, .. } => write!(w, " {}, {}, {}", cond, arg, imm),
|
||||||
FloatCompare { cond, args, .. } => write!(w, " {}, {}, {}", cond, args[0], args[1]),
|
FloatCompare { cond, args, .. } => write!(w, " {}, {}, {}", cond, args[0], args[1]),
|
||||||
Jump { destination, ref args, .. } => {
|
Jump { destination, ref args, .. } => {
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
|
|||||||
@@ -216,11 +216,12 @@ impl<'a> Context<'a> {
|
|||||||
InstructionData::UnaryIeee32 { .. } |
|
InstructionData::UnaryIeee32 { .. } |
|
||||||
InstructionData::UnaryIeee64 { .. } => {}
|
InstructionData::UnaryIeee64 { .. } => {}
|
||||||
|
|
||||||
InstructionData::Unary { ref mut arg, .. } |
|
|
||||||
InstructionData::UnarySplit { ref mut arg, .. } |
|
|
||||||
InstructionData::BinaryImm { ref mut arg, .. } |
|
InstructionData::BinaryImm { ref mut arg, .. } |
|
||||||
|
InstructionData::BranchTable { ref mut arg, .. } |
|
||||||
InstructionData::ExtractLane { ref mut arg, .. } |
|
InstructionData::ExtractLane { ref mut arg, .. } |
|
||||||
InstructionData::BranchTable { ref mut arg, .. } => {
|
InstructionData::IntCompareImm { ref mut arg, .. } |
|
||||||
|
InstructionData::Unary { ref mut arg, .. } |
|
||||||
|
InstructionData::UnarySplit { ref mut arg, .. } => {
|
||||||
self.map.rewrite_value(arg, loc)?;
|
self.map.rewrite_value(arg, loc)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1557,6 +1558,20 @@ impl<'a> Parser<'a> {
|
|||||||
args: [lhs, rhs],
|
args: [lhs, rhs],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
InstructionFormat::IntCompareImm => {
|
||||||
|
let cond = self.match_enum("expected intcc condition code")?;
|
||||||
|
self.match_token(Token::Comma, "expected ',' between operands")?;
|
||||||
|
let lhs = self.match_value("expected SSA value first operand")?;
|
||||||
|
self.match_token(Token::Comma, "expected ',' between operands")?;
|
||||||
|
let rhs = self.match_imm64("expected immediate second operand")?;
|
||||||
|
InstructionData::IntCompareImm {
|
||||||
|
opcode: opcode,
|
||||||
|
ty: VOID,
|
||||||
|
cond: cond,
|
||||||
|
arg: lhs,
|
||||||
|
imm: rhs,
|
||||||
|
}
|
||||||
|
}
|
||||||
InstructionFormat::FloatCompare => {
|
InstructionFormat::FloatCompare => {
|
||||||
let cond = self.match_enum("expected floatcc condition code")?;
|
let cond = self.match_enum("expected floatcc condition code")?;
|
||||||
self.match_token(Token::Comma, "expected ',' between operands")?;
|
self.match_token(Token::Comma, "expected ',' between operands")?;
|
||||||
|
|||||||
Reference in New Issue
Block a user