This commit is contained in:
mlokr 2024-09-17 15:14:24 +02:00
parent da69b705f1
commit 0ae0cae825
No known key found for this signature in database
GPG key ID: DEA147DDEE644993
8 changed files with 77 additions and 244 deletions

120
Cargo.lock generated
View file

@ -34,24 +34,21 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cranelift-bforest"
version = "0.111.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b80c3a50b9c4c7e5b5f73c0ed746687774fc9e36ef652b110da8daebf0c6e0e6"
version = "0.113.0"
source = "git+https://github.com/jakubDoka/wasmtime.git#969c85a481985be2fa2d555cdb338454f77213c6"
dependencies = [
"cranelift-entity",
]
[[package]]
name = "cranelift-bitset"
version = "0.111.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38778758c2ca918b05acb2199134e0c561fb577c50574259b26190b6c2d95ded"
version = "0.113.0"
source = "git+https://github.com/jakubDoka/wasmtime.git#969c85a481985be2fa2d555cdb338454f77213c6"
[[package]]
name = "cranelift-codegen"
version = "0.111.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58258667ad10e468bfc13a8d620f50dfcd4bb35d668123e97defa2549b9ad397"
version = "0.113.0"
source = "git+https://github.com/jakubDoka/wasmtime.git#969c85a481985be2fa2d555cdb338454f77213c6"
dependencies = [
"bumpalo",
"cranelift-bforest",
@ -61,85 +58,47 @@ dependencies = [
"cranelift-control",
"cranelift-entity",
"cranelift-isle",
"gimli",
"hashbrown 0.14.5",
"hashbrown",
"log",
"regalloc2 0.9.3",
"rustc-hash 1.1.0",
"regalloc2",
"rustc-hash",
"smallvec",
"target-lexicon",
]
[[package]]
name = "cranelift-codegen-meta"
version = "0.111.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "043f0b702e529dcb07ff92bd7d40e7d5317b5493595172c5eb0983343751ee06"
version = "0.113.0"
source = "git+https://github.com/jakubDoka/wasmtime.git#969c85a481985be2fa2d555cdb338454f77213c6"
dependencies = [
"cranelift-codegen-shared",
]
[[package]]
name = "cranelift-codegen-shared"
version = "0.111.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7763578888ab53eca5ce7da141953f828e82c2bfadcffc106d10d1866094ffbb"
version = "0.113.0"
source = "git+https://github.com/jakubDoka/wasmtime.git#969c85a481985be2fa2d555cdb338454f77213c6"
[[package]]
name = "cranelift-control"
version = "0.111.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32db15f08c05df570f11e8ab33cb1ec449a64b37c8a3498377b77650bef33d8b"
version = "0.113.0"
source = "git+https://github.com/jakubDoka/wasmtime.git#969c85a481985be2fa2d555cdb338454f77213c6"
dependencies = [
"arbitrary",
]
[[package]]
name = "cranelift-entity"
version = "0.111.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5289cdb399381a27e7bbfa1b42185916007c3d49aeef70b1d01cb4caa8010130"
version = "0.113.0"
source = "git+https://github.com/jakubDoka/wasmtime.git#969c85a481985be2fa2d555cdb338454f77213c6"
dependencies = [
"cranelift-bitset",
]
[[package]]
name = "cranelift-isle"
version = "0.111.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b72a3c5c166a70426dcb209bdd0bb71a787c1ea76023dc0974fbabca770e8f9"
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "fallible-iterator"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
[[package]]
name = "gimli"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
dependencies = [
"fallible-iterator",
"indexmap",
"stable_deref_trait",
]
[[package]]
name = "hashbrown"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
dependencies = [
"ahash",
]
version = "0.113.0"
source = "git+https://github.com/jakubDoka/wasmtime.git#969c85a481985be2fa2d555cdb338454f77213c6"
[[package]]
name = "hashbrown"
@ -163,7 +122,7 @@ dependencies = [
"cranelift-control",
"cranelift-isle",
"log",
"regalloc2 0.10.2",
"regalloc2",
"smallvec",
"target-lexicon",
]
@ -194,16 +153,6 @@ dependencies = [
"memmap2",
]
[[package]]
name = "indexmap"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
dependencies = [
"equivalent",
"hashbrown 0.14.5",
]
[[package]]
name = "libc"
version = "0.2.158"
@ -249,38 +198,19 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "regalloc2"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6"
dependencies = [
"hashbrown 0.13.2",
"log",
"rustc-hash 1.1.0",
"slice-group-by",
"smallvec",
]
[[package]]
name = "regalloc2"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12908dbeb234370af84d0579b9f68258a0f67e201412dd9a2814e6f45b2fc0f0"
dependencies = [
"hashbrown 0.14.5",
"hashbrown",
"log",
"rustc-hash 2.0.0",
"rustc-hash",
"slice-group-by",
"smallvec",
]
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc-hash"
version = "2.0.0"
@ -299,12 +229,6 @@ version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "syn"
version = "2.0.77"

View file

@ -4,8 +4,8 @@ version = "0.1.0"
edition = "2021"
[dependencies]
cranelift-codegen = "0.111.0"
cranelift-control = "0.111.0"
cranelift-codegen = { git = "https://github.com/jakubDoka/wasmtime.git", default-features = false }
cranelift-control = { git = "https://github.com/jakubDoka/wasmtime.git", default-features = false }
log = "0.4.22"
regalloc2 = "0.10.2"
smallvec = "1.13.2"
@ -18,5 +18,5 @@ isle-in-source-tree = []
isle-errors = []
[build-dependencies]
cranelift-codegen-meta = "0.111.0"
cranelift-isle = "0.111.0"
cranelift-codegen-meta = { git = "https://github.com/jakubDoka/wasmtime.git" }
cranelift-isle = { git = "https://github.com/jakubDoka/wasmtime.git" }

View file

@ -15,6 +15,7 @@
// current directory is used to find the sources.
use {
core::panic,
cranelift_codegen_meta::{self as meta, isle::IsleCompilations},
cranelift_isle::error::Errors,
meta::isle::IsleCompilation,

View file

@ -1,9 +1,9 @@
//! Implementation of a standard Riscv64 ABI.
use {
crate::inst::*,
alloc::{boxed::Box, vec::Vec},
cranelift_codegen::{
inst::*,
ir::{self, types::*, LibCall, Signature},
isa::{self, unwind::UnwindInst, CallConv},
machinst::*,

View file

@ -1,14 +1,17 @@
//! Riscv64 ISA definitions: instruction arguments.
use super::*;
use crate::ir::condcodes::CondCode;
use crate::lower::isle::generated_code::{
COpcodeSpace, CaOp, CbOp, CiOp, CiwOp, ClOp, CrOp, CsOp, CssOp, CsznOp, FpuOPWidth, ZcbMemOp,
use {
super::*,
crate::{
ir::condcodes::CondCode,
lower::isle::generated_code::{
COpcodeSpace, CaOp, CbOp, CiOp, CiwOp, ClOp, CrOp, CsOp, CssOp, CsznOp, FpuOPWidth,
ZcbMemOp,
},
},
cranelift_codegen::machinst::isle::WritableReg,
std::fmt::Result,
};
use crate::machinst::isle::WritableReg;
use std::fmt::Result;
/// A macro for defining a newtype of `Reg` that enforces some invariant about
/// the wrapped `Reg` (such as that it is of a particular register class).
@ -292,11 +295,7 @@ impl IntegerCompare {
pub(crate) fn emit(self) -> u32 {
let (funct3, reverse) = self.funct3();
let (rs1, rs2) = if reverse {
(self.rs2, self.rs1)
} else {
(self.rs1, self.rs2)
};
let (rs1, rs2) = if reverse { (self.rs2, self.rs1) } else { (self.rs1, self.rs2) };
self.op_code()
| funct3.funct3() << 12
@ -305,10 +304,7 @@ impl IntegerCompare {
}
pub(crate) fn inverse(self) -> Self {
Self {
kind: self.kind.complement(),
..self
}
Self { kind: self.kind.complement(), ..self }
}
pub(crate) fn regs(&self) -> [Reg; 2] {
@ -610,16 +606,12 @@ impl FpuOPRRR {
impl Display for FpuOPWidth {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
write!(
f,
"{}",
match self {
FpuOPWidth::H => "h",
FpuOPWidth::S => "s",
FpuOPWidth::D => "d",
FpuOPWidth::Q => "q",
}
)
write!(f, "{}", match self {
FpuOPWidth::H => "h",
FpuOPWidth::S => "s",
FpuOPWidth::D => "d",
FpuOPWidth::Q => "q",
})
}
}
@ -1141,6 +1133,7 @@ impl FRM {
FRM::Fcsr => 0b111,
}
}
pub(crate) fn as_u32(self) -> u32 {
self.bits() as u32
}
@ -1206,6 +1199,7 @@ impl LoadOP {
Self::Flh | Self::Flw | Self::Fld => 0b0000111,
}
}
pub(crate) fn funct3(self) -> u32 {
match self {
Self::Lb => 0b000,
@ -1234,6 +1228,7 @@ impl StoreOP {
Self::Fsd => "fsd",
}
}
pub(crate) fn from_type(ty: Type) -> Self {
match ty {
F16 => Self::Fsh,
@ -1262,6 +1257,7 @@ impl StoreOP {
Self::Fsh | Self::Fsw | Self::Fsd => 0b0100111,
}
}
pub(crate) fn funct3(self) -> u32 {
match self {
Self::Sb => 0b000,
@ -1296,6 +1292,7 @@ impl FClassResult {
pub(crate) const fn is_nan_bits() -> u32 {
Self::SNaN.bit() | Self::QNaN.bit()
}
#[inline]
pub(crate) fn is_zero_bits() -> u32 {
Self::NegZero.bit() | Self::PosZero.bit()
@ -1345,6 +1342,7 @@ impl AtomicOP {
};
format!("{}{}", s, amo.to_static_str())
}
#[inline]
pub(crate) fn op_code(self) -> u32 {
0b0101111
@ -1381,6 +1379,7 @@ impl AtomicOP {
| AtomicOP::AmomaxuD => 0b011,
}
}
pub(crate) fn funct5(self) -> u32 {
match self {
AtomicOP::LrW => 0b00010,
@ -1415,6 +1414,7 @@ impl AtomicOP {
Self::LrD
}
}
pub(crate) fn store_op(t: Type) -> Self {
if t.bits() <= 32 {
Self::ScW
@ -1426,15 +1426,10 @@ impl AtomicOP {
/// extract
pub(crate) fn extract(rd: WritableReg, offset: Reg, rs: Reg, ty: Type) -> SmallInstVec<Inst> {
let mut insts = SmallInstVec::new();
insts.push(Inst::AluRRR {
alu_op: AluOPRRR::Srl,
rd: rd,
rs1: rs,
rs2: offset,
});
insts.push(Inst::AluRRR { alu_op: AluOPRRR::Srl, rd, rs1: rs, rs2: offset });
//
insts.push(Inst::Extend {
rd: rd,
rd,
rn: rd.to_reg(),
signed: false,
from_bits: ty.bits() as u8,
@ -1452,15 +1447,10 @@ impl AtomicOP {
ty: Type,
) -> SmallInstVec<Inst> {
let mut insts = SmallInstVec::new();
insts.push(Inst::AluRRR {
alu_op: AluOPRRR::Srl,
rd: rd,
rs1: rs,
rs2: offset,
});
insts.push(Inst::AluRRR { alu_op: AluOPRRR::Srl, rd, rs1: rs, rs2: offset });
//
insts.push(Inst::Extend {
rd: rd,
rd,
rn: rd.to_reg(),
signed: true,
from_bits: ty.bits() as u8,
@ -1478,19 +1468,9 @@ impl AtomicOP {
assert!(rd != tmp);
let mut insts = SmallInstVec::new();
insts.extend(Inst::load_int_mask(tmp, ty));
insts.push(Inst::AluRRR {
alu_op: AluOPRRR::Sll,
rd: tmp,
rs1: tmp.to_reg(),
rs2: offset,
});
insts.push(Inst::AluRRR { alu_op: AluOPRRR::Sll, rd: tmp, rs1: tmp.to_reg(), rs2: offset });
insts.push(Inst::construct_bit_not(tmp, tmp.to_reg()));
insts.push(Inst::AluRRR {
alu_op: AluOPRRR::And,
rd: rd,
rs1: rd.to_reg(),
rs2: tmp.to_reg(),
});
insts.push(Inst::AluRRR { alu_op: AluOPRRR::And, rd, rs1: rd.to_reg(), rs2: tmp.to_reg() });
insts
}
@ -1511,18 +1491,8 @@ impl AtomicOP {
from_bits: ty.bits() as u8,
to_bits: 64,
});
insts.push(Inst::AluRRR {
alu_op: AluOPRRR::Sll,
rd: tmp,
rs1: tmp.to_reg(),
rs2: offset,
});
insts.push(Inst::AluRRR {
alu_op: AluOPRRR::Or,
rd: rd,
rs1: rd.to_reg(),
rs2: tmp.to_reg(),
});
insts.push(Inst::AluRRR { alu_op: AluOPRRR::Sll, rd: tmp, rs1: tmp.to_reg(), rs2: offset });
insts.push(Inst::AluRRR { alu_op: AluOPRRR::Or, rd, rs1: rd.to_reg(), rs2: tmp.to_reg() });
insts
}
@ -1559,6 +1529,7 @@ impl AMO {
AMO::SeqCst => ".aqrl",
}
}
pub(crate) fn as_u32(self) -> u32 {
self as u32
}
@ -1570,6 +1541,7 @@ impl Inst {
pub(crate) const FENCE_REQ_O: u8 = 1 << 2;
pub(crate) const FENCE_REQ_R: u8 = 1 << 1;
pub(crate) const FENCE_REQ_W: u8 = 1 << 0;
pub(crate) fn fence_req_to_string(x: u8) -> String {
let mut s = String::default();
if x & Self::FENCE_REQ_I != 0 {

View file

@ -16,9 +16,8 @@ use {
compile, CompiledCode, CompiledCodeStencil, MachInst, MachTextSectionBuilder, Reg,
SigSet, TextSectionBuilder, VCode,
},
result::CodegenResult,
settings::{self as shared_settings, Flags},
CodegenError,
CodegenError, CodegenResult,
},
cranelift_control::ControlPlane,
target_lexicon::{Architecture, Triple},
@ -28,8 +27,6 @@ pub(crate) mod inst;
mod lower;
mod settings;
use self::inst::EmitInfo;
#[cfg(feature = "unwind")]
use crate::isa::unwind::systemv;
/// An riscv64 backend.
pub struct Riscv64Backend {
@ -117,43 +114,10 @@ impl TargetIsa for Riscv64Backend {
self.isa_flags.iter().collect()
}
#[cfg(feature = "unwind")]
fn emit_unwind_info(
&self,
result: &CompiledCode,
kind: crate::isa::unwind::UnwindInfoKind,
) -> CodegenResult<Option<crate::isa::unwind::UnwindInfo>> {
use crate::isa::unwind::{UnwindInfo, UnwindInfoKind};
Ok(match kind {
UnwindInfoKind::SystemV => {
let mapper = self::inst::unwind::systemv::RegisterMapper;
Some(UnwindInfo::SystemV(
crate::isa::unwind::systemv::create_unwind_info_from_insts(
&result.buffer.unwind_info[..],
result.buffer.data().len(),
&mapper,
)?,
))
}
UnwindInfoKind::Windows => None,
_ => None,
})
}
#[cfg(feature = "unwind")]
fn create_systemv_cie(&self) -> Option<gimli::write::CommonInformationEntry> {
Some(inst::unwind::systemv::create_cie())
}
fn text_section_builder(&self, num_funcs: usize) -> Box<dyn TextSectionBuilder> {
Box::new(MachTextSectionBuilder::<inst::Inst>::new(num_funcs))
}
#[cfg(feature = "unwind")]
fn map_regalloc_reg_to_dwarf(&self, reg: Reg) -> Result<u16, systemv::RegisterMappingError> {
inst::unwind::systemv::map_reg(reg).map(|reg| reg.0)
}
fn function_alignment(&self) -> FunctionAlignment {
inst::Inst::function_alignment()
}
@ -163,37 +127,6 @@ impl TargetIsa for Riscv64Backend {
12
}
#[cfg(feature = "disas")]
fn to_capstone(&self) -> Result<capstone::Capstone, capstone::Error> {
use capstone::prelude::*;
let mut cs_builder = Capstone::new().riscv().mode(arch::riscv::ArchMode::RiscV64);
// Enable C instruction decoding if we have compressed instructions enabled.
//
// We can't enable this unconditionally because it will cause Capstone to
// emit weird instructions and generally mess up when it encounters unknown
// instructions, such as any Zba,Zbb,Zbc or Vector instructions.
//
// This causes the default disassembly to be quite unreadable, so enable
// it only when we are actually going to be using them.
let uses_compressed = self
.isa_flags()
.iter()
.filter(|f| ["has_zca", "has_zcb", "has_zcd"].contains(&f.name))
.any(|f| f.as_bool().unwrap_or(false));
if uses_compressed {
cs_builder = cs_builder.extra_mode([arch::riscv::ArchExtraMode::RiscVC].into_iter());
}
let mut cs = cs_builder.build()?;
// Similar to AArch64, RISC-V uses inline constants rather than a separate
// constant pool. We want to skip disassembly over inline constants instead
// of stopping on invalid bytes.
cs.set_skipdata(true)?;
Ok(cs)
}
fn has_native_fma(&self) -> bool {
true
}
@ -231,7 +164,7 @@ pub fn isa_builder(triple: Triple) -> IsaBuilder {
Architecture::Riscv64(..) => {}
_ => unreachable!(),
}
IsaBuilder { triple, setup: riscv_settings::builder(), constructor: isa_constructor }
IsaBuilder::new(triple, riscv_settings::builder(), isa_constructor)
}
fn isa_constructor(

View file

@ -6,17 +6,20 @@ pub mod generated_code;
// Types that the generated ISLE code uses via `use super::*`.
use {
self::generated_code::{FpuOPWidth, VecAluOpRR, VecLmul},
crate::{inst::*, Riscv64Backend},
cranelift_codegen::{
crate::{
abi::Riscv64ABICallSite,
inst::*,
lower::args::{FReg, VReg, WritableFReg, WritableVReg, WritableXReg, XReg},
Riscv64Backend,
},
cranelift_codegen::{
ir::{
immediates::*, types::*, AtomicRmwOp, BlockCall, ExternalName, Inst, InstructionData,
MemFlags, Opcode, TrapCode, Value, ValueList,
},
isa::{self},
lower::args::{FReg, VReg, WritableFReg, WritableVReg, WritableXReg, XReg},
machinst::{
isle::*, ArgPair, CallInfo, InstOutput, IsTailCall, MachInst, Reg, VCodeConstant,
self, isle::*, ArgPair, CallInfo, InstOutput, IsTailCall, MachInst, Reg, VCodeConstant,
VCodeConstantData,
},
},
@ -52,9 +55,9 @@ impl<'a, 'b> RV64IsleContext<'a, 'b, MInst, Riscv64Backend> {
}
impl generated_code::Context for RV64IsleContext<'_, '_, MInst, Riscv64Backend> {
isle_lower_prelude_methods!();
cranelift_codegen::isle_lower_prelude_methods!();
isle_prelude_caller_methods!(Riscv64MachineDeps, Riscv64ABICallSite);
cranelift_codegen::isle_prelude_caller_methods!(Riscv64MachineDeps, Riscv64ABICallSite);
fn gen_return_call(
&mut self,

View file

@ -2,7 +2,7 @@
use {
core::fmt,
cranelift_codegen::settings::{self, detail, Builder, Value},
cranelift_codegen::settings::{self, detail, Builder, PredicateView, Value},
};
// Include code generated by `cranelift-codegen/meta/src/gen_settings.rs:`. This file contains a