arm64: Use FPU instrctions for Fcopysign
Copyright (c) 2020, Arm Limited.
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use crate::binemit::CodeOffset;
|
||||
use crate::ir::types::{B1, B16, B32, B64, B8, F32, F64, FFLAGS, I16, I32, I64, I8, IFLAGS};
|
||||
use crate::ir::types::{B1, B16, B32, B64, B8, F32, F32X2, F64, FFLAGS, I16, I32, I64, I8, IFLAGS};
|
||||
use crate::ir::{ExternalName, Opcode, SourceLoc, TrapCode, Type};
|
||||
use crate::machinst::*;
|
||||
use crate::{settings, CodegenError, CodegenResult};
|
||||
@@ -124,6 +124,19 @@ pub enum FPUOp2 {
|
||||
Min64,
|
||||
}
|
||||
|
||||
/// A floating-point unit (FPU) operation with two args, a register and an immediate.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum FPUOpRI {
|
||||
/// Unsigned right shift. Rd = Rn << #imm
|
||||
UShr32(FPURightShiftImm),
|
||||
/// Unsigned right shift. Rd = Rn << #imm
|
||||
UShr64(FPURightShiftImm),
|
||||
/// Shift left and insert. Rd |= Rn << #imm
|
||||
Sli32(FPULeftShiftImm),
|
||||
/// Shift left and insert. Rd |= Rn << #imm
|
||||
Sli64(FPULeftShiftImm),
|
||||
}
|
||||
|
||||
/// A floating-point unit (FPU) operation with three args.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum FPUOp3 {
|
||||
@@ -472,6 +485,12 @@ pub enum Inst {
|
||||
rm: Reg,
|
||||
},
|
||||
|
||||
FpuRRI {
|
||||
fpu_op: FPUOpRI,
|
||||
rd: Writable<Reg>,
|
||||
rn: Reg,
|
||||
},
|
||||
|
||||
/// 3-op FPU instruction.
|
||||
FpuRRRR {
|
||||
fpu_op: FPUOp3,
|
||||
@@ -1034,6 +1053,13 @@ fn aarch64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
|
||||
collector.add_use(rn);
|
||||
collector.add_use(rm);
|
||||
}
|
||||
&Inst::FpuRRI { fpu_op, rd, rn, .. } => {
|
||||
match fpu_op {
|
||||
FPUOpRI::UShr32(..) | FPUOpRI::UShr64(..) => collector.add_def(rd),
|
||||
FPUOpRI::Sli32(..) | FPUOpRI::Sli64(..) => collector.add_mod(rd),
|
||||
}
|
||||
collector.add_use(rn);
|
||||
}
|
||||
&Inst::FpuRRRR { rd, rn, rm, ra, .. } => {
|
||||
collector.add_def(rd);
|
||||
collector.add_use(rn);
|
||||
@@ -1482,6 +1508,14 @@ fn aarch64_map_regs(inst: &mut Inst, mapper: &RegUsageMapper) {
|
||||
map_use(mapper, rn);
|
||||
map_use(mapper, rm);
|
||||
}
|
||||
&mut Inst::FpuRRI {
|
||||
ref mut rd,
|
||||
ref mut rn,
|
||||
..
|
||||
} => {
|
||||
map_def(mapper, rd);
|
||||
map_use(mapper, rn);
|
||||
}
|
||||
&mut Inst::FpuRRRR {
|
||||
ref mut rd,
|
||||
ref mut rn,
|
||||
@@ -2236,6 +2270,23 @@ impl ShowWithRRU for Inst {
|
||||
let rm = show_freg_sized(rm, mb_rru, size);
|
||||
format!("{} {}, {}, {}", op, rd, rn, rm)
|
||||
}
|
||||
&Inst::FpuRRI { fpu_op, rd, rn } => {
|
||||
let (op, imm, vector) = match fpu_op {
|
||||
FPUOpRI::UShr32(imm) => ("ushr", imm.show_rru(mb_rru), true),
|
||||
FPUOpRI::UShr64(imm) => ("ushr", imm.show_rru(mb_rru), false),
|
||||
FPUOpRI::Sli32(imm) => ("sli", imm.show_rru(mb_rru), true),
|
||||
FPUOpRI::Sli64(imm) => ("sli", imm.show_rru(mb_rru), false),
|
||||
};
|
||||
|
||||
let show_vreg_fn: fn(Reg, Option<&RealRegUniverse>) -> String = if vector {
|
||||
|reg, mb_rru| show_vreg_vector(reg, mb_rru, F32X2)
|
||||
} else {
|
||||
show_vreg_scalar
|
||||
};
|
||||
let rd = show_vreg_fn(rd.to_reg(), mb_rru);
|
||||
let rn = show_vreg_fn(rn, mb_rru);
|
||||
format!("{} {}, {}, {}", op, rd, rn, imm)
|
||||
}
|
||||
&Inst::FpuRRRR {
|
||||
fpu_op,
|
||||
rd,
|
||||
|
||||
Reference in New Issue
Block a user