s390x: clean up lower.rs (#4355)
Now that lowering is fully done in ISLE, clean up some code remnants in lower.rs. In particular, move code to lower/isle.rs where possible, and inline lower_insn_to_regs into its caller and simplify.
This commit is contained in:
@@ -1,329 +1,15 @@
|
|||||||
//! Lowering rules for S390x.
|
//! Lowering rules for S390x.
|
||||||
|
|
||||||
use crate::ir::condcodes::IntCC;
|
|
||||||
use crate::ir::Inst as IRInst;
|
use crate::ir::Inst as IRInst;
|
||||||
use crate::ir::{MemFlags, Opcode};
|
use crate::ir::Opcode;
|
||||||
use crate::isa::s390x::abi::*;
|
use crate::isa::s390x::inst::Inst;
|
||||||
use crate::isa::s390x::inst::*;
|
|
||||||
use crate::isa::s390x::settings as s390x_settings;
|
|
||||||
use crate::isa::s390x::S390xBackend;
|
use crate::isa::s390x::S390xBackend;
|
||||||
use crate::machinst::lower::*;
|
use crate::machinst::{InsnOutput, LowerBackend, LowerCtx, MachLabel};
|
||||||
use crate::machinst::*;
|
|
||||||
use crate::settings::Flags;
|
|
||||||
use crate::CodegenResult;
|
use crate::CodegenResult;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
pub mod isle;
|
pub mod isle;
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
// Lowering: force instruction input into a register
|
|
||||||
|
|
||||||
/// Sign-extend the low `from_bits` bits of `value` to a full u64.
|
|
||||||
fn sign_extend_to_u64(value: u64, from_bits: u8) -> u64 {
|
|
||||||
assert!(from_bits <= 64);
|
|
||||||
if from_bits >= 64 {
|
|
||||||
value
|
|
||||||
} else {
|
|
||||||
(((value << (64 - from_bits)) as i64) >> (64 - from_bits)) as u64
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
// Lowering: comparisons
|
|
||||||
|
|
||||||
/// Determines whether this condcode interprets inputs as signed or
|
|
||||||
/// unsigned. See the documentation for the `icmp` instruction in
|
|
||||||
/// cranelift-codegen/meta/src/shared/instructions.rs for further insights
|
|
||||||
/// into this.
|
|
||||||
pub fn condcode_is_signed(cc: IntCC) -> bool {
|
|
||||||
match cc {
|
|
||||||
IntCC::Equal => false,
|
|
||||||
IntCC::NotEqual => false,
|
|
||||||
IntCC::SignedGreaterThanOrEqual => true,
|
|
||||||
IntCC::SignedGreaterThan => true,
|
|
||||||
IntCC::SignedLessThanOrEqual => true,
|
|
||||||
IntCC::SignedLessThan => true,
|
|
||||||
IntCC::UnsignedGreaterThanOrEqual => false,
|
|
||||||
IntCC::UnsignedGreaterThan => false,
|
|
||||||
IntCC::UnsignedLessThanOrEqual => false,
|
|
||||||
IntCC::UnsignedLessThan => false,
|
|
||||||
IntCC::Overflow => true,
|
|
||||||
IntCC::NotOverflow => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
// Lowering: main entry point for lowering a instruction
|
|
||||||
|
|
||||||
fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
|
||||||
ctx: &mut C,
|
|
||||||
insn: IRInst,
|
|
||||||
flags: &Flags,
|
|
||||||
isa_flags: &s390x_settings::Flags,
|
|
||||||
) -> CodegenResult<()> {
|
|
||||||
let op = ctx.data(insn).opcode();
|
|
||||||
let outputs: SmallVec<[InsnOutput; 2]> = (0..ctx.num_outputs(insn))
|
|
||||||
.map(|i| InsnOutput { insn, output: i })
|
|
||||||
.collect();
|
|
||||||
let ty = if outputs.len() > 0 {
|
|
||||||
Some(ctx.output_ty(insn, 0))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Ok(()) = super::lower::isle::lower(ctx, flags, isa_flags, &outputs, insn) {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let implemented_in_isle = || {
|
|
||||||
unreachable!(
|
|
||||||
"implemented in ISLE: inst = `{}`, type = `{:?}`",
|
|
||||||
ctx.dfg().display_inst(insn),
|
|
||||||
ty
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
match op {
|
|
||||||
Opcode::Nop
|
|
||||||
| Opcode::Copy
|
|
||||||
| Opcode::Iconst
|
|
||||||
| Opcode::Bconst
|
|
||||||
| Opcode::F32const
|
|
||||||
| Opcode::F64const
|
|
||||||
| Opcode::Null
|
|
||||||
| Opcode::Iadd
|
|
||||||
| Opcode::IaddIfcout
|
|
||||||
| Opcode::Isub
|
|
||||||
| Opcode::Iabs
|
|
||||||
| Opcode::Ineg
|
|
||||||
| Opcode::Imul
|
|
||||||
| Opcode::Umulhi
|
|
||||||
| Opcode::Smulhi
|
|
||||||
| Opcode::Udiv
|
|
||||||
| Opcode::Urem
|
|
||||||
| Opcode::Sdiv
|
|
||||||
| Opcode::Srem
|
|
||||||
| Opcode::Ishl
|
|
||||||
| Opcode::Ushr
|
|
||||||
| Opcode::Sshr
|
|
||||||
| Opcode::Rotr
|
|
||||||
| Opcode::Rotl
|
|
||||||
| Opcode::Ireduce
|
|
||||||
| Opcode::Uextend
|
|
||||||
| Opcode::Sextend
|
|
||||||
| Opcode::Bnot
|
|
||||||
| Opcode::Band
|
|
||||||
| Opcode::Bor
|
|
||||||
| Opcode::Bxor
|
|
||||||
| Opcode::BandNot
|
|
||||||
| Opcode::BorNot
|
|
||||||
| Opcode::BxorNot
|
|
||||||
| Opcode::Bitselect
|
|
||||||
| Opcode::Breduce
|
|
||||||
| Opcode::Bextend
|
|
||||||
| Opcode::Bmask
|
|
||||||
| Opcode::Bint
|
|
||||||
| Opcode::Clz
|
|
||||||
| Opcode::Cls
|
|
||||||
| Opcode::Ctz
|
|
||||||
| Opcode::Popcnt
|
|
||||||
| Opcode::Fadd
|
|
||||||
| Opcode::Fsub
|
|
||||||
| Opcode::Fmul
|
|
||||||
| Opcode::Fdiv
|
|
||||||
| Opcode::Fmin
|
|
||||||
| Opcode::Fmax
|
|
||||||
| Opcode::Sqrt
|
|
||||||
| Opcode::Fneg
|
|
||||||
| Opcode::Fabs
|
|
||||||
| Opcode::Fpromote
|
|
||||||
| Opcode::Fdemote
|
|
||||||
| Opcode::Ceil
|
|
||||||
| Opcode::Floor
|
|
||||||
| Opcode::Trunc
|
|
||||||
| Opcode::Nearest
|
|
||||||
| Opcode::Fma
|
|
||||||
| Opcode::Fcopysign
|
|
||||||
| Opcode::FcvtFromUint
|
|
||||||
| Opcode::FcvtFromSint
|
|
||||||
| Opcode::FcvtToUint
|
|
||||||
| Opcode::FcvtToSint
|
|
||||||
| Opcode::FcvtToUintSat
|
|
||||||
| Opcode::FcvtToSintSat
|
|
||||||
| Opcode::Bitcast
|
|
||||||
| Opcode::Load
|
|
||||||
| Opcode::Uload8
|
|
||||||
| Opcode::Sload8
|
|
||||||
| Opcode::Uload16
|
|
||||||
| Opcode::Sload16
|
|
||||||
| Opcode::Uload32
|
|
||||||
| Opcode::Sload32
|
|
||||||
| Opcode::Store
|
|
||||||
| Opcode::Istore8
|
|
||||||
| Opcode::Istore16
|
|
||||||
| Opcode::Istore32
|
|
||||||
| Opcode::AtomicRmw
|
|
||||||
| Opcode::AtomicCas
|
|
||||||
| Opcode::AtomicLoad
|
|
||||||
| Opcode::AtomicStore
|
|
||||||
| Opcode::Fence
|
|
||||||
| Opcode::Icmp
|
|
||||||
| Opcode::Fcmp
|
|
||||||
| Opcode::IsNull
|
|
||||||
| Opcode::IsInvalid
|
|
||||||
| Opcode::Select
|
|
||||||
| Opcode::SelectifSpectreGuard
|
|
||||||
| Opcode::Trap
|
|
||||||
| Opcode::ResumableTrap
|
|
||||||
| Opcode::Trapz
|
|
||||||
| Opcode::Trapnz
|
|
||||||
| Opcode::ResumableTrapnz
|
|
||||||
| Opcode::Trapif
|
|
||||||
| Opcode::Debugtrap
|
|
||||||
| Opcode::Call
|
|
||||||
| Opcode::CallIndirect
|
|
||||||
| Opcode::FallthroughReturn
|
|
||||||
| Opcode::Return
|
|
||||||
| Opcode::StackAddr
|
|
||||||
| Opcode::FuncAddr
|
|
||||||
| Opcode::SymbolValue => implemented_in_isle(),
|
|
||||||
|
|
||||||
Opcode::UaddSat | Opcode::SaddSat => unimplemented!(),
|
|
||||||
Opcode::UsubSat | Opcode::SsubSat => unimplemented!(),
|
|
||||||
|
|
||||||
Opcode::Bitrev => unimplemented!(),
|
|
||||||
|
|
||||||
Opcode::FcvtLowFromSint => unimplemented!("FcvtLowFromSint"),
|
|
||||||
|
|
||||||
Opcode::StackLoad | Opcode::StackStore => {
|
|
||||||
panic!("Direct stack memory access not supported; should not be used by Wasm");
|
|
||||||
}
|
|
||||||
|
|
||||||
Opcode::ConstAddr => unimplemented!(),
|
|
||||||
|
|
||||||
Opcode::HeapAddr => {
|
|
||||||
panic!("heap_addr should have been removed by legalization!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Opcode::TableAddr => {
|
|
||||||
panic!("table_addr should have been removed by legalization!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Opcode::GlobalValue => {
|
|
||||||
panic!("global_value should have been removed by legalization!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Opcode::TlsValue => {
|
|
||||||
unimplemented!("Thread-local storage support not implemented!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Opcode::GetPinnedReg | Opcode::SetPinnedReg => {
|
|
||||||
unimplemented!("Pinned register support not implemented!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Opcode::RawBitcast
|
|
||||||
| Opcode::Splat
|
|
||||||
| Opcode::Swizzle
|
|
||||||
| Opcode::Insertlane
|
|
||||||
| Opcode::Extractlane
|
|
||||||
| Opcode::Imin
|
|
||||||
| Opcode::Umin
|
|
||||||
| Opcode::Imax
|
|
||||||
| Opcode::Umax
|
|
||||||
| Opcode::AvgRound
|
|
||||||
| Opcode::FminPseudo
|
|
||||||
| Opcode::FmaxPseudo
|
|
||||||
| Opcode::Uload8x8
|
|
||||||
| Opcode::Sload8x8
|
|
||||||
| Opcode::Uload16x4
|
|
||||||
| Opcode::Sload16x4
|
|
||||||
| Opcode::Uload32x2
|
|
||||||
| Opcode::Sload32x2
|
|
||||||
| Opcode::Vconst
|
|
||||||
| Opcode::Shuffle
|
|
||||||
| Opcode::Vsplit
|
|
||||||
| Opcode::Vconcat
|
|
||||||
| Opcode::Vselect
|
|
||||||
| Opcode::VanyTrue
|
|
||||||
| Opcode::VallTrue
|
|
||||||
| Opcode::VhighBits
|
|
||||||
| Opcode::ScalarToVector
|
|
||||||
| Opcode::Snarrow
|
|
||||||
| Opcode::Unarrow
|
|
||||||
| Opcode::Uunarrow
|
|
||||||
| Opcode::SwidenLow
|
|
||||||
| Opcode::SwidenHigh
|
|
||||||
| Opcode::UwidenLow
|
|
||||||
| Opcode::UwidenHigh
|
|
||||||
| Opcode::WideningPairwiseDotProductS
|
|
||||||
| Opcode::SqmulRoundSat
|
|
||||||
| Opcode::FvpromoteLow
|
|
||||||
| Opcode::Fvdemote
|
|
||||||
| Opcode::IaddPairwise => {
|
|
||||||
// TODO
|
|
||||||
unimplemented!("Vector ops not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Opcode::Isplit | Opcode::Iconcat => unimplemented!("Wide integer ops not implemented."),
|
|
||||||
|
|
||||||
Opcode::IfcmpSp => {
|
|
||||||
panic!("Unused opcode should not be encountered.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Opcode::Ifcmp
|
|
||||||
| Opcode::Ffcmp
|
|
||||||
| Opcode::Trapff
|
|
||||||
| Opcode::Trueif
|
|
||||||
| Opcode::Trueff
|
|
||||||
| Opcode::Selectif => {
|
|
||||||
panic!("Flags opcode should not be encountered.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Opcode::Jump
|
|
||||||
| Opcode::Brz
|
|
||||||
| Opcode::Brnz
|
|
||||||
| Opcode::BrIcmp
|
|
||||||
| Opcode::Brif
|
|
||||||
| Opcode::Brff
|
|
||||||
| Opcode::BrTable => {
|
|
||||||
panic!("Branch opcode reached non-branch lowering logic!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Opcode::IaddImm
|
|
||||||
| Opcode::ImulImm
|
|
||||||
| Opcode::UdivImm
|
|
||||||
| Opcode::SdivImm
|
|
||||||
| Opcode::UremImm
|
|
||||||
| Opcode::SremImm
|
|
||||||
| Opcode::IrsubImm
|
|
||||||
| Opcode::IaddCin
|
|
||||||
| Opcode::IaddIfcin
|
|
||||||
| Opcode::IaddCout
|
|
||||||
| Opcode::IaddCarry
|
|
||||||
| Opcode::IaddIfcarry
|
|
||||||
| Opcode::IsubBin
|
|
||||||
| Opcode::IsubIfbin
|
|
||||||
| Opcode::IsubBout
|
|
||||||
| Opcode::IsubIfbout
|
|
||||||
| Opcode::IsubBorrow
|
|
||||||
| Opcode::IsubIfborrow
|
|
||||||
| Opcode::BandImm
|
|
||||||
| Opcode::BorImm
|
|
||||||
| Opcode::BxorImm
|
|
||||||
| Opcode::RotlImm
|
|
||||||
| Opcode::RotrImm
|
|
||||||
| Opcode::IshlImm
|
|
||||||
| Opcode::UshrImm
|
|
||||||
| Opcode::SshrImm
|
|
||||||
| Opcode::IcmpImm
|
|
||||||
| Opcode::IfcmpImm => {
|
|
||||||
panic!("ALU+imm and ALU+carry ops should not appear here!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Lowering-backend trait implementation.
|
// Lowering-backend trait implementation.
|
||||||
|
|
||||||
@@ -331,7 +17,255 @@ impl LowerBackend for S390xBackend {
|
|||||||
type MInst = Inst;
|
type MInst = Inst;
|
||||||
|
|
||||||
fn lower<C: LowerCtx<I = Inst>>(&self, ctx: &mut C, ir_inst: IRInst) -> CodegenResult<()> {
|
fn lower<C: LowerCtx<I = Inst>>(&self, ctx: &mut C, ir_inst: IRInst) -> CodegenResult<()> {
|
||||||
lower_insn_to_regs(ctx, ir_inst, &self.flags, &self.isa_flags)
|
let op = ctx.data(ir_inst).opcode();
|
||||||
|
let outputs: SmallVec<[InsnOutput; 2]> = (0..ctx.num_outputs(ir_inst))
|
||||||
|
.map(|i| InsnOutput {
|
||||||
|
insn: ir_inst,
|
||||||
|
output: i,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let ty = if outputs.len() > 0 {
|
||||||
|
Some(ctx.output_ty(ir_inst, 0))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Ok(()) =
|
||||||
|
super::lower::isle::lower(ctx, &self.flags, &self.isa_flags, &outputs, ir_inst)
|
||||||
|
{
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
match op {
|
||||||
|
Opcode::Nop
|
||||||
|
| Opcode::Copy
|
||||||
|
| Opcode::Iconst
|
||||||
|
| Opcode::Bconst
|
||||||
|
| Opcode::F32const
|
||||||
|
| Opcode::F64const
|
||||||
|
| Opcode::Null
|
||||||
|
| Opcode::Iadd
|
||||||
|
| Opcode::IaddIfcout
|
||||||
|
| Opcode::Isub
|
||||||
|
| Opcode::Iabs
|
||||||
|
| Opcode::Ineg
|
||||||
|
| Opcode::Imul
|
||||||
|
| Opcode::Umulhi
|
||||||
|
| Opcode::Smulhi
|
||||||
|
| Opcode::Udiv
|
||||||
|
| Opcode::Urem
|
||||||
|
| Opcode::Sdiv
|
||||||
|
| Opcode::Srem
|
||||||
|
| Opcode::Ishl
|
||||||
|
| Opcode::Ushr
|
||||||
|
| Opcode::Sshr
|
||||||
|
| Opcode::Rotr
|
||||||
|
| Opcode::Rotl
|
||||||
|
| Opcode::Ireduce
|
||||||
|
| Opcode::Uextend
|
||||||
|
| Opcode::Sextend
|
||||||
|
| Opcode::Bnot
|
||||||
|
| Opcode::Band
|
||||||
|
| Opcode::Bor
|
||||||
|
| Opcode::Bxor
|
||||||
|
| Opcode::BandNot
|
||||||
|
| Opcode::BorNot
|
||||||
|
| Opcode::BxorNot
|
||||||
|
| Opcode::Bitselect
|
||||||
|
| Opcode::Breduce
|
||||||
|
| Opcode::Bextend
|
||||||
|
| Opcode::Bmask
|
||||||
|
| Opcode::Bint
|
||||||
|
| Opcode::Clz
|
||||||
|
| Opcode::Cls
|
||||||
|
| Opcode::Ctz
|
||||||
|
| Opcode::Popcnt
|
||||||
|
| Opcode::Fadd
|
||||||
|
| Opcode::Fsub
|
||||||
|
| Opcode::Fmul
|
||||||
|
| Opcode::Fdiv
|
||||||
|
| Opcode::Fmin
|
||||||
|
| Opcode::Fmax
|
||||||
|
| Opcode::Sqrt
|
||||||
|
| Opcode::Fneg
|
||||||
|
| Opcode::Fabs
|
||||||
|
| Opcode::Fpromote
|
||||||
|
| Opcode::Fdemote
|
||||||
|
| Opcode::Ceil
|
||||||
|
| Opcode::Floor
|
||||||
|
| Opcode::Trunc
|
||||||
|
| Opcode::Nearest
|
||||||
|
| Opcode::Fma
|
||||||
|
| Opcode::Fcopysign
|
||||||
|
| Opcode::FcvtFromUint
|
||||||
|
| Opcode::FcvtFromSint
|
||||||
|
| Opcode::FcvtToUint
|
||||||
|
| Opcode::FcvtToSint
|
||||||
|
| Opcode::FcvtToUintSat
|
||||||
|
| Opcode::FcvtToSintSat
|
||||||
|
| Opcode::Bitcast
|
||||||
|
| Opcode::Load
|
||||||
|
| Opcode::Uload8
|
||||||
|
| Opcode::Sload8
|
||||||
|
| Opcode::Uload16
|
||||||
|
| Opcode::Sload16
|
||||||
|
| Opcode::Uload32
|
||||||
|
| Opcode::Sload32
|
||||||
|
| Opcode::Store
|
||||||
|
| Opcode::Istore8
|
||||||
|
| Opcode::Istore16
|
||||||
|
| Opcode::Istore32
|
||||||
|
| Opcode::AtomicRmw
|
||||||
|
| Opcode::AtomicCas
|
||||||
|
| Opcode::AtomicLoad
|
||||||
|
| Opcode::AtomicStore
|
||||||
|
| Opcode::Fence
|
||||||
|
| Opcode::Icmp
|
||||||
|
| Opcode::Fcmp
|
||||||
|
| Opcode::IsNull
|
||||||
|
| Opcode::IsInvalid
|
||||||
|
| Opcode::Select
|
||||||
|
| Opcode::SelectifSpectreGuard
|
||||||
|
| Opcode::Trap
|
||||||
|
| Opcode::ResumableTrap
|
||||||
|
| Opcode::Trapz
|
||||||
|
| Opcode::Trapnz
|
||||||
|
| Opcode::ResumableTrapnz
|
||||||
|
| Opcode::Trapif
|
||||||
|
| Opcode::Debugtrap
|
||||||
|
| Opcode::Call
|
||||||
|
| Opcode::CallIndirect
|
||||||
|
| Opcode::FallthroughReturn
|
||||||
|
| Opcode::Return
|
||||||
|
| Opcode::StackAddr
|
||||||
|
| Opcode::FuncAddr
|
||||||
|
| Opcode::SymbolValue => {
|
||||||
|
unreachable!(
|
||||||
|
"implemented in ISLE: inst = `{}`, type = `{:?}`",
|
||||||
|
ctx.dfg().display_inst(ir_inst),
|
||||||
|
ty
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Opcode::UaddSat
|
||||||
|
| Opcode::SaddSat
|
||||||
|
| Opcode::UsubSat
|
||||||
|
| Opcode::SsubSat
|
||||||
|
| Opcode::Bitrev
|
||||||
|
| Opcode::FcvtLowFromSint
|
||||||
|
| Opcode::ConstAddr
|
||||||
|
| Opcode::TlsValue
|
||||||
|
| Opcode::GetPinnedReg
|
||||||
|
| Opcode::SetPinnedReg
|
||||||
|
| Opcode::Isplit
|
||||||
|
| Opcode::Iconcat
|
||||||
|
| Opcode::RawBitcast
|
||||||
|
| Opcode::Splat
|
||||||
|
| Opcode::Swizzle
|
||||||
|
| Opcode::Insertlane
|
||||||
|
| Opcode::Extractlane
|
||||||
|
| Opcode::Imin
|
||||||
|
| Opcode::Umin
|
||||||
|
| Opcode::Imax
|
||||||
|
| Opcode::Umax
|
||||||
|
| Opcode::AvgRound
|
||||||
|
| Opcode::FminPseudo
|
||||||
|
| Opcode::FmaxPseudo
|
||||||
|
| Opcode::Uload8x8
|
||||||
|
| Opcode::Sload8x8
|
||||||
|
| Opcode::Uload16x4
|
||||||
|
| Opcode::Sload16x4
|
||||||
|
| Opcode::Uload32x2
|
||||||
|
| Opcode::Sload32x2
|
||||||
|
| Opcode::Vconst
|
||||||
|
| Opcode::Shuffle
|
||||||
|
| Opcode::Vsplit
|
||||||
|
| Opcode::Vconcat
|
||||||
|
| Opcode::Vselect
|
||||||
|
| Opcode::VanyTrue
|
||||||
|
| Opcode::VallTrue
|
||||||
|
| Opcode::VhighBits
|
||||||
|
| Opcode::ScalarToVector
|
||||||
|
| Opcode::Snarrow
|
||||||
|
| Opcode::Unarrow
|
||||||
|
| Opcode::Uunarrow
|
||||||
|
| Opcode::SwidenLow
|
||||||
|
| Opcode::SwidenHigh
|
||||||
|
| Opcode::UwidenLow
|
||||||
|
| Opcode::UwidenHigh
|
||||||
|
| Opcode::WideningPairwiseDotProductS
|
||||||
|
| Opcode::SqmulRoundSat
|
||||||
|
| Opcode::FvpromoteLow
|
||||||
|
| Opcode::Fvdemote
|
||||||
|
| Opcode::IaddPairwise => {
|
||||||
|
unreachable!(
|
||||||
|
"TODO: not yet implemented in ISLE: inst = `{}`, type = `{:?}`",
|
||||||
|
ctx.dfg().display_inst(ir_inst),
|
||||||
|
ty
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Opcode::StackLoad | Opcode::StackStore => {
|
||||||
|
panic!("Direct stack memory access not supported; should not be used by Wasm");
|
||||||
|
}
|
||||||
|
Opcode::HeapAddr => {
|
||||||
|
panic!("heap_addr should have been removed by legalization!");
|
||||||
|
}
|
||||||
|
Opcode::TableAddr => {
|
||||||
|
panic!("table_addr should have been removed by legalization!");
|
||||||
|
}
|
||||||
|
Opcode::GlobalValue => {
|
||||||
|
panic!("global_value should have been removed by legalization!");
|
||||||
|
}
|
||||||
|
Opcode::Ifcmp
|
||||||
|
| Opcode::IfcmpSp
|
||||||
|
| Opcode::Ffcmp
|
||||||
|
| Opcode::Trapff
|
||||||
|
| Opcode::Trueif
|
||||||
|
| Opcode::Trueff
|
||||||
|
| Opcode::Selectif => {
|
||||||
|
panic!("Flags opcode should not be encountered.");
|
||||||
|
}
|
||||||
|
Opcode::Jump
|
||||||
|
| Opcode::Brz
|
||||||
|
| Opcode::Brnz
|
||||||
|
| Opcode::BrIcmp
|
||||||
|
| Opcode::Brif
|
||||||
|
| Opcode::Brff
|
||||||
|
| Opcode::BrTable => {
|
||||||
|
panic!("Branch opcode reached non-branch lowering logic!");
|
||||||
|
}
|
||||||
|
Opcode::IaddImm
|
||||||
|
| Opcode::ImulImm
|
||||||
|
| Opcode::UdivImm
|
||||||
|
| Opcode::SdivImm
|
||||||
|
| Opcode::UremImm
|
||||||
|
| Opcode::SremImm
|
||||||
|
| Opcode::IrsubImm
|
||||||
|
| Opcode::IaddCin
|
||||||
|
| Opcode::IaddIfcin
|
||||||
|
| Opcode::IaddCout
|
||||||
|
| Opcode::IaddCarry
|
||||||
|
| Opcode::IaddIfcarry
|
||||||
|
| Opcode::IsubBin
|
||||||
|
| Opcode::IsubIfbin
|
||||||
|
| Opcode::IsubBout
|
||||||
|
| Opcode::IsubIfbout
|
||||||
|
| Opcode::IsubBorrow
|
||||||
|
| Opcode::IsubIfborrow
|
||||||
|
| Opcode::BandImm
|
||||||
|
| Opcode::BorImm
|
||||||
|
| Opcode::BxorImm
|
||||||
|
| Opcode::RotlImm
|
||||||
|
| Opcode::RotrImm
|
||||||
|
| Opcode::IshlImm
|
||||||
|
| Opcode::UshrImm
|
||||||
|
| Opcode::SshrImm
|
||||||
|
| Opcode::IcmpImm
|
||||||
|
| Opcode::IfcmpImm => {
|
||||||
|
panic!("ALU+imm and ALU+carry ops should not appear here!");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_branch_group<C: LowerCtx<I = Inst>>(
|
fn lower_branch_group<C: LowerCtx<I = Inst>>(
|
||||||
|
|||||||
@@ -4,17 +4,19 @@
|
|||||||
pub mod generated_code;
|
pub mod generated_code;
|
||||||
|
|
||||||
// Types that the generated ISLE code uses via `use super::*`.
|
// Types that the generated ISLE code uses via `use super::*`.
|
||||||
use super::{
|
use crate::isa::s390x::abi::S390xMachineDeps;
|
||||||
CallIndInfo, CallInfo, Cond, Inst as MInst, MachLabel, MemArg, MemFlags, Opcode, Reg,
|
use crate::isa::s390x::inst::{
|
||||||
S390xMachineDeps, UImm16Shifted, UImm32Shifted,
|
stack_reg, writable_gpr, zero_reg, CallIndInfo, CallInfo, Cond, Inst as MInst, MemArg,
|
||||||
|
UImm16Shifted, UImm32Shifted,
|
||||||
};
|
};
|
||||||
use crate::isa::s390x::settings::Flags as IsaFlags;
|
use crate::isa::s390x::settings::Flags as IsaFlags;
|
||||||
use crate::machinst::isle::*;
|
use crate::machinst::isle::*;
|
||||||
|
use crate::machinst::{MachLabel, Reg};
|
||||||
use crate::settings::Flags;
|
use crate::settings::Flags;
|
||||||
use crate::{
|
use crate::{
|
||||||
ir::{
|
ir::{
|
||||||
condcodes::*, immediates::*, types::*, AtomicRmwOp, Endianness, Inst, InstructionData,
|
condcodes::*, immediates::*, types::*, AtomicRmwOp, Endianness, Inst, InstructionData,
|
||||||
StackSlot, TrapCode, Value, ValueList,
|
MemFlags, Opcode, StackSlot, TrapCode, Value, ValueList,
|
||||||
},
|
},
|
||||||
isa::unwind::UnwindInst,
|
isa::unwind::UnwindInst,
|
||||||
machinst::{InsnOutput, LowerCtx, VCodeConstant, VCodeConstantData},
|
machinst::{InsnOutput, LowerCtx, VCodeConstant, VCodeConstantData},
|
||||||
@@ -150,12 +152,12 @@ where
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn writable_gpr(&mut self, regno: u8) -> WritableReg {
|
fn writable_gpr(&mut self, regno: u8) -> WritableReg {
|
||||||
super::writable_gpr(regno)
|
writable_gpr(regno)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn zero_reg(&mut self) -> Reg {
|
fn zero_reg(&mut self) -> Reg {
|
||||||
super::zero_reg()
|
zero_reg()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -282,10 +284,7 @@ where
|
|||||||
let inst = self.lower_ctx.dfg().value_def(val).inst()?;
|
let inst = self.lower_ctx.dfg().value_def(val).inst()?;
|
||||||
let constant = self.lower_ctx.get_constant(inst)?;
|
let constant = self.lower_ctx.get_constant(inst)?;
|
||||||
let ty = self.lower_ctx.output_ty(inst, 0);
|
let ty = self.lower_ctx.output_ty(inst, 0);
|
||||||
Some(super::sign_extend_to_u64(
|
Some(sign_extend_to_u64(constant, self.ty_bits(ty).unwrap()))
|
||||||
constant,
|
|
||||||
self.ty_bits(ty).unwrap(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -390,7 +389,7 @@ where
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn signed(&mut self, cc: &IntCC) -> Option<()> {
|
fn signed(&mut self, cc: &IntCC) -> Option<()> {
|
||||||
if super::condcode_is_signed(*cc) {
|
if condcode_is_signed(*cc) {
|
||||||
Some(())
|
Some(())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -399,7 +398,7 @@ where
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn unsigned(&mut self, cc: &IntCC) -> Option<()> {
|
fn unsigned(&mut self, cc: &IntCC) -> Option<()> {
|
||||||
if !super::condcode_is_signed(*cc) {
|
if !condcode_is_signed(*cc) {
|
||||||
Some(())
|
Some(())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -468,7 +467,7 @@ where
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn memarg_stack_off(&mut self, base: i64, off: i64) -> MemArg {
|
fn memarg_stack_off(&mut self, base: i64, off: i64) -> MemArg {
|
||||||
MemArg::reg_plus_off(super::stack_reg(), base + off, MemFlags::trusted())
|
MemArg::reg_plus_off(stack_reg(), base + off, MemFlags::trusted())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -555,3 +554,36 @@ where
|
|||||||
self.lower_ctx.emit(inst.clone());
|
self.lower_ctx.emit(inst.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sign-extend the low `from_bits` bits of `value` to a full u64.
|
||||||
|
#[inline]
|
||||||
|
fn sign_extend_to_u64(value: u64, from_bits: u8) -> u64 {
|
||||||
|
assert!(from_bits <= 64);
|
||||||
|
if from_bits >= 64 {
|
||||||
|
value
|
||||||
|
} else {
|
||||||
|
(((value << (64 - from_bits)) as i64) >> (64 - from_bits)) as u64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determines whether this condcode interprets inputs as signed or
|
||||||
|
/// unsigned. See the documentation for the `icmp` instruction in
|
||||||
|
/// cranelift-codegen/meta/src/shared/instructions.rs for further insights
|
||||||
|
/// into this.
|
||||||
|
#[inline]
|
||||||
|
fn condcode_is_signed(cc: IntCC) -> bool {
|
||||||
|
match cc {
|
||||||
|
IntCC::Equal => false,
|
||||||
|
IntCC::NotEqual => false,
|
||||||
|
IntCC::SignedGreaterThanOrEqual => true,
|
||||||
|
IntCC::SignedGreaterThan => true,
|
||||||
|
IntCC::SignedLessThanOrEqual => true,
|
||||||
|
IntCC::SignedLessThan => true,
|
||||||
|
IntCC::UnsignedGreaterThanOrEqual => false,
|
||||||
|
IntCC::UnsignedGreaterThan => false,
|
||||||
|
IntCC::UnsignedLessThanOrEqual => false,
|
||||||
|
IntCC::UnsignedLessThan => false,
|
||||||
|
IntCC::Overflow => true,
|
||||||
|
IntCC::NotOverflow => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user