cranelift_codegen/isa/aarch64/
lower.rs1use crate::ir::condcodes::{FloatCC, IntCC};
11use crate::ir::pcc::{FactContext, PccResult};
12use crate::ir::Inst as IRInst;
13use crate::ir::{Opcode, Value};
14use crate::isa::aarch64::inst::*;
15use crate::isa::aarch64::pcc;
16use crate::isa::aarch64::AArch64Backend;
17use crate::machinst::lower::*;
18use crate::machinst::*;
19
20pub mod isle;
21
22fn get_as_extended_value(ctx: &mut Lower<Inst>, val: Value) -> Option<(Value, ExtendOp)> {
26 let inputs = ctx.get_value_as_source_or_const(val);
27 let (insn, n) = inputs.inst.as_inst()?;
28 if n != 0 {
29 return None;
30 }
31 let op = ctx.data(insn).opcode();
32 let out_ty = ctx.output_ty(insn, 0);
33 let out_bits = ty_bits(out_ty);
34
35 if op == Opcode::Uextend || op == Opcode::Sextend {
37 let sign_extend = op == Opcode::Sextend;
38 let inner_ty = ctx.input_ty(insn, 0);
39 let inner_bits = ty_bits(inner_ty);
40 assert!(inner_bits < out_bits);
41 let extendop = match (sign_extend, inner_bits) {
42 (true, 8) => ExtendOp::SXTB,
43 (false, 8) => ExtendOp::UXTB,
44 (true, 16) => ExtendOp::SXTH,
45 (false, 16) => ExtendOp::UXTH,
46 (true, 32) => ExtendOp::SXTW,
47 (false, 32) => ExtendOp::UXTW,
48 _ => unreachable!(),
49 };
50 return Some((ctx.input_as_value(insn, 0), extendop));
51 }
52
53 None
54}
55
56pub(crate) fn lower_condcode(cc: IntCC) -> Cond {
57 match cc {
58 IntCC::Equal => Cond::Eq,
59 IntCC::NotEqual => Cond::Ne,
60 IntCC::SignedGreaterThanOrEqual => Cond::Ge,
61 IntCC::SignedGreaterThan => Cond::Gt,
62 IntCC::SignedLessThanOrEqual => Cond::Le,
63 IntCC::SignedLessThan => Cond::Lt,
64 IntCC::UnsignedGreaterThanOrEqual => Cond::Hs,
65 IntCC::UnsignedGreaterThan => Cond::Hi,
66 IntCC::UnsignedLessThanOrEqual => Cond::Ls,
67 IntCC::UnsignedLessThan => Cond::Lo,
68 }
69}
70
71pub(crate) fn lower_fp_condcode(cc: FloatCC) -> Cond {
72 match cc {
80 FloatCC::Ordered => Cond::Vc,
82 FloatCC::Unordered => Cond::Vs,
84 FloatCC::Equal => Cond::Eq,
86 FloatCC::NotEqual => Cond::Ne,
88 FloatCC::OrderedNotEqual => unimplemented!(),
90 FloatCC::UnorderedOrEqual => unimplemented!(),
92 FloatCC::LessThan => Cond::Mi,
94 FloatCC::LessThanOrEqual => Cond::Ls,
96 FloatCC::GreaterThan => Cond::Gt,
98 FloatCC::GreaterThanOrEqual => Cond::Ge,
100 FloatCC::UnorderedOrLessThan => unimplemented!(),
102 FloatCC::UnorderedOrLessThanOrEqual => unimplemented!(),
104 FloatCC::UnorderedOrGreaterThan => unimplemented!(),
106 FloatCC::UnorderedOrGreaterThanOrEqual => unimplemented!(),
108 }
109}
110
111impl LowerBackend for AArch64Backend {
115 type MInst = Inst;
116
117 fn lower(&self, ctx: &mut Lower<Inst>, ir_inst: IRInst) -> Option<InstOutput> {
118 isle::lower(ctx, self, ir_inst)
119 }
120
121 fn lower_branch(
122 &self,
123 ctx: &mut Lower<Inst>,
124 ir_inst: IRInst,
125 targets: &[MachLabel],
126 ) -> Option<()> {
127 isle::lower_branch(ctx, self, ir_inst, targets)
128 }
129
130 fn maybe_pinned_reg(&self) -> Option<Reg> {
131 Some(regs::pinned_reg())
132 }
133
134 fn check_fact(
135 &self,
136 ctx: &FactContext<'_>,
137 vcode: &mut VCode<Self::MInst>,
138 inst: InsnIndex,
139 state: &mut pcc::FactFlowState,
140 ) -> PccResult<()> {
141 pcc::check(ctx, vcode, inst, state)
142 }
143
144 type FactFlowState = pcc::FactFlowState;
145}