Add instructions using CPU flags.

Add integer and floating comparison instructions that return CPU flags:
ifcmp, ifcmp_imm, and ffcmp.

Add conditional branch instructions that check CPU flags: brif, brff

Add instructions that check a condition in the CPU flags and return a
b1: trueif, trueff.
This commit is contained in:
Jakob Stoklund Olesen
2017-10-12 15:21:40 -07:00
parent 15461c1e4b
commit 1f98fc491c
8 changed files with 262 additions and 28 deletions

View File

@@ -141,11 +141,21 @@ pub enum InstructionData {
arg: Value,
imm: Imm64,
},
IntCond {
opcode: Opcode,
cond: IntCC,
arg: Value,
},
FloatCompare {
opcode: Opcode,
cond: FloatCC,
args: [Value; 2],
},
FloatCond {
opcode: Opcode,
cond: FloatCC,
arg: Value,
},
Jump {
opcode: Opcode,
destination: Ebb,
@@ -162,6 +172,18 @@ pub enum InstructionData {
destination: Ebb,
args: ValueList,
},
BranchInt {
opcode: Opcode,
cond: IntCC,
destination: Ebb,
args: ValueList,
},
BranchFloat {
opcode: Opcode,
cond: FloatCC,
destination: Ebb,
args: ValueList,
},
BranchTable {
opcode: Opcode,
arg: Value,

View File

@@ -288,6 +288,16 @@ impl<'a> Verifier<'a> {
ref args,
..
} |
BranchInt {
destination,
ref args,
..
} |
BranchFloat {
destination,
ref args,
..
} |
BranchIcmp {
destination,
ref args,
@@ -340,7 +350,9 @@ impl<'a> Verifier<'a> {
ExtractLane { .. } |
IntCompare { .. } |
IntCompareImm { .. } |
IntCond { .. } |
FloatCompare { .. } |
FloatCond { .. } |
Load { .. } |
Store { .. } |
RegMove { .. } |

View File

@@ -299,22 +299,16 @@ pub fn write_operands(
ExtractLane { lane, arg, .. } => write!(w, " {}, {}", arg, lane),
IntCompare { cond, args, .. } => write!(w, " {} {}, {}", cond, args[0], args[1]),
IntCompareImm { cond, arg, imm, .. } => write!(w, " {} {}, {}", cond, arg, imm),
IntCond { cond, arg, .. } => write!(w, " {} {}", cond, arg),
FloatCompare { cond, args, .. } => write!(w, " {} {}, {}", cond, args[0], args[1]),
FloatCond { cond, arg, .. } => write!(w, " {} {}", cond, arg),
Jump {
destination,
ref args,
..
} => {
if args.is_empty() {
write!(w, " {}", destination)
} else {
write!(
w,
" {}({})",
destination,
DisplayValues(args.as_slice(pool))
)
}
write!(w, " {}", destination)?;
write_ebb_args(w, args.as_slice(pool))
}
Branch {
destination,
@@ -323,10 +317,27 @@ pub fn write_operands(
} => {
let args = args.as_slice(pool);
write!(w, " {}, {}", args[0], destination)?;
if args.len() > 1 {
write!(w, "({})", DisplayValues(&args[1..]))?;
}
Ok(())
write_ebb_args(w, &args[1..])
}
BranchInt {
cond,
destination,
ref args,
..
} => {
let args = args.as_slice(pool);
write!(w, " {} {}, {}", cond, args[0], destination)?;
write_ebb_args(w, &args[1..])
}
BranchFloat {
cond,
destination,
ref args,
..
} => {
let args = args.as_slice(pool);
write!(w, " {} {}, {}", cond, args[0], destination)?;
write_ebb_args(w, &args[1..])
}
BranchIcmp {
cond,
@@ -336,10 +347,7 @@ pub fn write_operands(
} => {
let args = args.as_slice(pool);
write!(w, " {} {}, {}, {}", cond, args[0], args[1], destination)?;
if args.len() > 2 {
write!(w, "({})", DisplayValues(&args[2..]))?;
}
Ok(())
write_ebb_args(w, &args[2..])
}
BranchTable { arg, table, .. } => write!(w, " {}, {}", arg, table),
Call { func_ref, ref args, .. } => {
@@ -406,6 +414,15 @@ pub fn write_operands(
}
}
/// Write EBB args using optional parantheses.
fn write_ebb_args(w: &mut Write, args: &[Value]) -> Result {
if args.is_empty() {
Ok(())
} else {
write!(w, "({})", DisplayValues(args))
}
}
/// Displayable slice of values.
struct DisplayValues<'a>(&'a [Value]);