arm64: Add support for CCmp
Also add a test for SUBS/ADDS with XZR, as CMP/CMN are aliases. Copyright (c) 2020, Arm Limited.
This commit is contained in:
committed by
Benjamin Bouvier
parent
9364eb1d98
commit
3638f8a764
@@ -257,6 +257,15 @@ fn enc_cset(rd: Writable<Reg>, cond: Cond) -> u32 {
|
||||
| (cond.invert().bits() << 12)
|
||||
}
|
||||
|
||||
fn enc_ccmp_imm(size: InstSize, rn: Reg, imm: UImm5, nzcv: NZCV, cond: Cond) -> u32 {
|
||||
0b0_1_1_11010010_00000_0000_10_00000_0_0000
|
||||
| size.sf_bit() << 31
|
||||
| imm.bits() << 16
|
||||
| cond.bits() << 12
|
||||
| machreg_to_gpr(rn) << 5
|
||||
| nzcv.bits()
|
||||
}
|
||||
|
||||
fn enc_vecmov(is_16b: bool, rd: Writable<Reg>, rn: Reg) -> u32 {
|
||||
debug_assert!(!is_16b); // to be supported later.
|
||||
0b00001110_101_00000_00011_1_00000_00000
|
||||
@@ -831,6 +840,15 @@ impl<O: MachSectionOutput> MachInstEmit<O> for Inst {
|
||||
&Inst::CSet { rd, cond } => {
|
||||
sink.put4(enc_cset(rd, cond));
|
||||
}
|
||||
&Inst::CCmpImm {
|
||||
size,
|
||||
rn,
|
||||
imm,
|
||||
nzcv,
|
||||
cond,
|
||||
} => {
|
||||
sink.put4(enc_ccmp_imm(size, rn, imm, nzcv, cond));
|
||||
}
|
||||
&Inst::FpuMove64 { rd, rn } => {
|
||||
sink.put4(enc_vecmov(/* 16b = */ false, rd, rn));
|
||||
}
|
||||
@@ -1419,6 +1437,17 @@ mod test {
|
||||
"A400068A",
|
||||
"and x4, x5, x6",
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::SubS32,
|
||||
rd: writable_zero_reg(),
|
||||
rn: xreg(2),
|
||||
rm: xreg(3),
|
||||
},
|
||||
"5F00036B",
|
||||
// TODO: Display as cmp
|
||||
"subs wzr, w2, w3",
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::SubS32,
|
||||
@@ -1459,6 +1488,17 @@ mod test {
|
||||
"A40006AB",
|
||||
"adds x4, x5, x6",
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRImm12 {
|
||||
alu_op: ALUOp::AddS64,
|
||||
rd: writable_zero_reg(),
|
||||
rn: xreg(5),
|
||||
imm12: Imm12::maybe_from_u64(1).unwrap(),
|
||||
},
|
||||
"BF0400B1",
|
||||
// TODO: Display as cmn.
|
||||
"adds xzr, x5, #1",
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::SDiv64,
|
||||
@@ -3053,6 +3093,28 @@ mod test {
|
||||
"EFB79F9A",
|
||||
"cset x15, ge",
|
||||
));
|
||||
insns.push((
|
||||
Inst::CCmpImm {
|
||||
size: InstSize::Size64,
|
||||
rn: xreg(22),
|
||||
imm: UImm5::maybe_from_u8(5).unwrap(),
|
||||
nzcv: NZCV::new(false, false, true, true),
|
||||
cond: Cond::Eq,
|
||||
},
|
||||
"C30A45FA",
|
||||
"ccmp x22, #5, #nzCV, eq",
|
||||
));
|
||||
insns.push((
|
||||
Inst::CCmpImm {
|
||||
size: InstSize::Size32,
|
||||
rn: xreg(3),
|
||||
imm: UImm5::maybe_from_u8(30).unwrap(),
|
||||
nzcv: NZCV::new(true, true, true, true),
|
||||
cond: Cond::Gt,
|
||||
},
|
||||
"6FC85E7A",
|
||||
"ccmp w3, #30, #NZCV, gt",
|
||||
));
|
||||
insns.push((
|
||||
Inst::MovToVec64 {
|
||||
rd: writable_vreg(20),
|
||||
|
||||
Reference in New Issue
Block a user